Make const trait aliases work in the old solver
This commit is contained in:
@@ -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())
|
||||
}
|
||||
|
||||
@@ -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`.
|
||||
|
||||
@@ -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();
|
||||
| ^^^
|
||||
|
||||
@@ -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`.
|
||||
@@ -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() {}
|
||||
|
||||
Reference in New Issue
Block a user