diff --git a/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs index 4004e354dc18..26ba1511b540 100644 --- a/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs +++ b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs @@ -6,8 +6,7 @@ use rustc_span::{DUMMY_SP, Span}; use tracing::{debug, instrument}; use crate::traits::query::NoSolution; -use crate::traits::query::normalize::QueryNormalizeExt; -use crate::traits::{Normalized, ObligationCause, ObligationCtxt}; +use crate::traits::{ObligationCause, ObligationCtxt}; /// This returns true if the type `ty` is "trivial" for /// dropck-outlives -- that is, if it doesn't require any types to @@ -172,13 +171,18 @@ pub fn compute_dropck_outlives_inner<'tcx>( // do not themselves define a destructor", more or less. We have // to push them onto the stack to be expanded. for ty in constraints.dtorck_types.drain(..) { - let Normalized { value: ty, obligations } = - ocx.infcx.at(&cause, param_env).query_normalize(ty)?; - ocx.register_obligations(obligations); + let normalized_ty = ocx.normalize(&cause, param_env, ty); - debug!("dropck_outlives: ty from dtorck_types = {:?}", ty); + let errors = ocx.select_where_possible(); + if !errors.is_empty() { + debug!("failed to normalize dtorck type: {ty} ~> {errors:#?}"); + return Err(NoSolution); + } + + let normalized_ty = ocx.infcx.resolve_vars_if_possible(normalized_ty); + debug!("dropck_outlives: ty from dtorck_types = {:?}", normalized_ty); - match ty.kind() { + match normalized_ty.kind() { // All parameters live for the duration of the // function. ty::Param(..) => {} @@ -186,12 +190,12 @@ pub fn compute_dropck_outlives_inner<'tcx>( // A projection that we couldn't resolve - it // might have a destructor. ty::Alias(..) => { - result.kinds.push(ty.into()); + result.kinds.push(normalized_ty.into()); } _ => { - if ty_set.insert(ty) { - ty_stack.push((ty, depth + 1)); + if ty_set.insert(normalized_ty) { + ty_stack.push((normalized_ty, depth + 1)); } } } diff --git a/compiler/rustc_traits/src/type_op.rs b/compiler/rustc_traits/src/type_op.rs index 71088a598bb9..5d041c2623aa 100644 --- a/compiler/rustc_traits/src/type_op.rs +++ b/compiler/rustc_traits/src/type_op.rs @@ -6,13 +6,12 @@ use rustc_middle::query::Providers; use rustc_middle::traits::query::NoSolution; use rustc_middle::ty::{Clause, FnSig, ParamEnvAnd, PolyFnSig, Ty, TyCtxt, TypeFoldable}; use rustc_trait_selection::infer::InferCtxtBuilderExt; -use rustc_trait_selection::traits::query::normalize::QueryNormalizeExt; use rustc_trait_selection::traits::query::type_op::ascribe_user_type::{ AscribeUserType, type_op_ascribe_user_type_with_span, }; use rustc_trait_selection::traits::query::type_op::normalize::Normalize; use rustc_trait_selection::traits::query::type_op::prove_predicate::ProvePredicate; -use rustc_trait_selection::traits::{Normalized, Obligation, ObligationCause, ObligationCtxt}; +use rustc_trait_selection::traits::{Obligation, ObligationCause, ObligationCtxt}; pub(crate) fn provide(p: &mut Providers) { *p = Providers { @@ -43,10 +42,7 @@ where T: fmt::Debug + TypeFoldable>, { let (param_env, Normalize { value }) = key.into_parts(); - let Normalized { value, obligations } = - ocx.infcx.at(&ObligationCause::dummy(), param_env).query_normalize(value)?; - ocx.register_obligations(obligations); - Ok(value) + Ok(ocx.normalize(&ObligationCause::dummy(), param_env, value)) } fn type_op_normalize_ty<'tcx>( diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-71955.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-71955.rs index a44ed9e5ef59..34548e2487e0 100644 --- a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-71955.rs +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-71955.rs @@ -43,9 +43,9 @@ fn main() { } foo(bar, "string", |s| s.len() == 5); - //~^ ERROR implementation of `FnOnce` is not general enough - //~| ERROR implementation of `FnOnce` is not general enough + //~^ ERROR implementation of `Parser` is not general enough + //~| ERROR implementation of `Parser` is not general enough foo(baz, "string", |s| s.0.len() == 5); - //~^ ERROR implementation of `FnOnce` is not general enough - //~| ERROR implementation of `FnOnce` is not general enough + //~^ ERROR implementation of `Parser` is not general enough + //~| ERROR implementation of `Parser` is not general enough } diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-71955.stderr b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-71955.stderr index b2bb417a8f01..23fc6e2f7f40 100644 --- a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-71955.stderr +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-71955.stderr @@ -1,39 +1,39 @@ -error: implementation of `FnOnce` is not general enough +error: implementation of `Parser` is not general enough --> $DIR/issue-71955.rs:45:5 | LL | foo(bar, "string", |s| s.len() == 5); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Parser` is not general enough | - = note: closure with signature `for<'a> fn(&'a &'2 str) -> bool` must implement `FnOnce<(&&'1 str,)>`, for any lifetime `'1`... - = note: ...but it actually implements `FnOnce<(&&'2 str,)>`, for some specific lifetime `'2` + = note: `for<'a> fn(&'a str) -> (&'a str, &'a str) {bar}` must implement `Parser<'0>`, for any lifetime `'0`... + = note: ...but it actually implements `Parser<'1>`, for some specific lifetime `'1` -error: implementation of `FnOnce` is not general enough +error: implementation of `Parser` is not general enough --> $DIR/issue-71955.rs:45:5 | LL | foo(bar, "string", |s| s.len() == 5); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Parser` is not general enough | - = note: closure with signature `for<'a> fn(&'a &'2 str) -> bool` must implement `FnOnce<(&&'1 str,)>`, for any lifetime `'1`... - = note: ...but it actually implements `FnOnce<(&&'2 str,)>`, for some specific lifetime `'2` + = note: `for<'a> fn(&'a str) -> (&'a str, &'a str) {bar}` must implement `Parser<'0>`, for any lifetime `'0`... + = note: ...but it actually implements `Parser<'1>`, for some specific lifetime `'1` = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: implementation of `FnOnce` is not general enough +error: implementation of `Parser` is not general enough --> $DIR/issue-71955.rs:48:5 | LL | foo(baz, "string", |s| s.0.len() == 5); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Parser` is not general enough | - = note: closure with signature `for<'a> fn(&'a Wrapper<'2>) -> bool` must implement `FnOnce<(&Wrapper<'1>,)>`, for any lifetime `'1`... - = note: ...but it actually implements `FnOnce<(&Wrapper<'2>,)>`, for some specific lifetime `'2` + = note: `for<'a> fn(&'a str) -> (&'a str, Wrapper<'a>) {baz}` must implement `Parser<'0>`, for any lifetime `'0`... + = note: ...but it actually implements `Parser<'1>`, for some specific lifetime `'1` -error: implementation of `FnOnce` is not general enough +error: implementation of `Parser` is not general enough --> $DIR/issue-71955.rs:48:5 | LL | foo(baz, "string", |s| s.0.len() == 5); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Parser` is not general enough | - = note: closure with signature `for<'a> fn(&'a Wrapper<'2>) -> bool` must implement `FnOnce<(&Wrapper<'1>,)>`, for any lifetime `'1`... - = note: ...but it actually implements `FnOnce<(&Wrapper<'2>,)>`, for some specific lifetime `'2` + = note: `for<'a> fn(&'a str) -> (&'a str, Wrapper<'a>) {baz}` must implement `Parser<'0>`, for any lifetime `'0`... + = note: ...but it actually implements `Parser<'1>`, for some specific lifetime `'1` = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 4 previous errors