diff --git a/compiler/rustc_trait_selection/src/traits/effects.rs b/compiler/rustc_trait_selection/src/traits/effects.rs index 7f2a9999d646..d2094046ed44 100644 --- a/compiler/rustc_trait_selection/src/traits/effects.rs +++ b/compiler/rustc_trait_selection/src/traits/effects.rs @@ -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>, 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()) +} diff --git a/tests/ui/consts/trait_alias.fail.stderr b/tests/ui/consts/trait_alias.fail.stderr index 8cf9a7c87770..16675206a7a4 100644 --- a/tests/ui/consts/trait_alias.fail.stderr +++ b/tests/ui/consts/trait_alias.fail.stderr @@ -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(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`. diff --git a/tests/ui/consts/trait_alias.next_fail.stderr b/tests/ui/consts/trait_alias.next_fail.stderr index 1a72b9c70de7..16675206a7a4 100644 --- a/tests/ui/consts/trait_alias.next_fail.stderr +++ b/tests/ui/consts/trait_alias.next_fail.stderr @@ -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(); | ^^^ diff --git a/tests/ui/consts/trait_alias.pass.stderr b/tests/ui/consts/trait_alias.pass.stderr deleted file mode 100644 index bbd598e80785..000000000000 --- a/tests/ui/consts/trait_alias.pass.stderr +++ /dev/null @@ -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(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`. diff --git a/tests/ui/consts/trait_alias.rs b/tests/ui/consts/trait_alias.rs index 4062c19f52d2..3d9a60cefc7c 100644 --- a/tests/ui/consts/trait_alias.rs +++ b/tests/ui/consts/trait_alias.rs @@ -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(x: &T) { } const _: () = foo(&()); -//[fail,pass]~^ ERROR: `(): const Foo` is not satisfied fn main() {}