Make const trait aliases work in the old solver

This commit is contained in:
Oli Scherer
2025-07-22 07:23:33 +00:00
committed by Oli Scherer
parent bc4d612d46
commit b9e7cf61be
5 changed files with 44 additions and 35 deletions

View File

@@ -69,6 +69,12 @@ pub fn evaluate_host_effect_obligation<'tcx>(
Err(EvaluationFailure::NoSolution) => {}
}
match evaluate_host_effect_from_trait_alias(selcx, obligation) {
Ok(result) => return Ok(result),
Err(EvaluationFailure::Ambiguous) => return Err(EvaluationFailure::Ambiguous),
Err(EvaluationFailure::NoSolution) => {}
}
Err(EvaluationFailure::NoSolution)
}
@@ -496,3 +502,37 @@ fn evaluate_host_effect_from_selection_candidate<'tcx>(
}
})
}
fn evaluate_host_effect_from_trait_alias<'tcx>(
selcx: &mut SelectionContext<'_, 'tcx>,
obligation: &HostEffectObligation<'tcx>,
) -> Result<ThinVec<PredicateObligation<'tcx>>, EvaluationFailure> {
let tcx = selcx.tcx();
let def_id = obligation.predicate.def_id();
if !tcx.trait_is_alias(def_id) {
return Err(EvaluationFailure::NoSolution);
}
Ok(tcx
.const_conditions(def_id)
.instantiate(tcx, obligation.predicate.trait_ref.args)
.into_iter()
.map(|(trait_ref, span)| {
Obligation::new(
tcx,
obligation.cause.clone().derived_host_cause(
ty::Binder::dummy(obligation.predicate),
|derived| {
ObligationCauseCode::ImplDerivedHost(Box::new(ImplDerivedHostCause {
derived,
impl_def_id: def_id,
span,
}))
},
),
obligation.param_env,
trait_ref.to_host_effect_clause(tcx, obligation.predicate.constness),
)
})
.collect())
}

View File

@@ -1,23 +1,9 @@
error[E0277]: the trait bound `T: [const] Baz` is not satisfied
--> $DIR/trait_alias.rs:23:11
--> $DIR/trait_alias.rs:24:11
|
LL | x.baz();
| ^^^
error[E0277]: the trait bound `(): const Foo` is not satisfied
--> $DIR/trait_alias.rs:28:19
|
LL | const _: () = foo(&());
| --- ^^^
| |
| required by a bound introduced by this call
|
note: required by a bound in `foo`
--> $DIR/trait_alias.rs:19:17
|
LL | const fn foo<T: [const] Foo>(x: &T) {
| ^^^^^^^^^^^ required by this bound in `foo`
error: aborting due to 2 previous errors
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0277`.

View File

@@ -1,5 +1,5 @@
error[E0277]: the trait bound `T: [const] Baz` is not satisfied
--> $DIR/trait_alias.rs:23:11
--> $DIR/trait_alias.rs:24:11
|
LL | x.baz();
| ^^^

View File

@@ -1,17 +0,0 @@
error[E0277]: the trait bound `(): const Foo` is not satisfied
--> $DIR/trait_alias.rs:28:19
|
LL | const _: () = foo(&());
| --- ^^^
| |
| required by a bound introduced by this call
|
note: required by a bound in `foo`
--> $DIR/trait_alias.rs:19:17
|
LL | const fn foo<T: [const] Foo>(x: &T) {
| ^^^^^^^^^^^ required by this bound in `foo`
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0277`.

View File

@@ -3,6 +3,7 @@
//@[next_pass] compile-flags: -Znext-solver
//@[next_fail] compile-flags: -Znext-solver
//@[next_pass] check-pass
//@[pass] check-pass
const trait Bar {
fn bar(&self) {}
@@ -26,6 +27,5 @@ const fn foo<T: [const] Foo>(x: &T) {
}
const _: () = foo(&());
//[fail,pass]~^ ERROR: `(): const Foo` is not satisfied
fn main() {}