From 97c9d8f405e1b93bf69334b239f89d92d28847a0 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 3 Nov 2023 14:34:08 +0000 Subject: [PATCH] Only use normalize_param_env when normalizing predicate in check_item_bounds --- .../src/check/compare_impl_item.rs | 10 ++++++-- ...sume-gat-normalization-for-nested-goals.rs | 2 +- ...-gat-normalization-for-nested-goals.stderr | 24 +++++++++++++++++++ .../higher-ranked-self-impl-requirement.rs | 20 ++++++++++++++++ .../new-solver/specialization-transmute.rs | 2 +- .../specialization-transmute.stderr | 11 +++++++-- .../specialization-unconstrained.rs | 2 +- .../specialization-unconstrained.stderr | 11 +++++++-- 8 files changed, 73 insertions(+), 9 deletions(-) create mode 100644 tests/ui/generic-associated-types/assume-gat-normalization-for-nested-goals.stderr create mode 100644 tests/ui/generic-associated-types/higher-ranked-self-impl-requirement.rs diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index 90babbb63a000..857515f971a85 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -2162,7 +2162,7 @@ pub(super) fn check_type_bounds<'tcx>( impl_ty: ty::AssocItem, impl_trait_ref: ty::TraitRef<'tcx>, ) -> Result<(), ErrorGuaranteed> { - let param_env = param_env_with_gat_bounds(tcx, impl_ty, impl_trait_ref); + let param_env = tcx.param_env(impl_ty.def_id); debug!(?param_env); let container_id = impl_ty.container_id(tcx); @@ -2217,8 +2217,14 @@ pub(super) fn check_type_bounds<'tcx>( .collect(); debug!("check_type_bounds: item_bounds={:?}", obligations); + // Normalize predicates with the assumption that the GAT may always normalize + // to its definition type. This should be the param-env we use to *prove* the + // predicate too, but we don't do that because of performance issues. + // See . + let normalize_param_env = param_env_with_gat_bounds(tcx, impl_ty, impl_trait_ref); for mut obligation in util::elaborate(tcx, obligations) { - let normalized_predicate = ocx.normalize(&normalize_cause, param_env, obligation.predicate); + let normalized_predicate = + ocx.normalize(&normalize_cause, normalize_param_env, obligation.predicate); debug!("compare_projection_bounds: normalized predicate = {:?}", normalized_predicate); obligation.predicate = normalized_predicate; diff --git a/tests/ui/generic-associated-types/assume-gat-normalization-for-nested-goals.rs b/tests/ui/generic-associated-types/assume-gat-normalization-for-nested-goals.rs index 7b16870723976..e2d51c6649ab9 100644 --- a/tests/ui/generic-associated-types/assume-gat-normalization-for-nested-goals.rs +++ b/tests/ui/generic-associated-types/assume-gat-normalization-for-nested-goals.rs @@ -1,4 +1,4 @@ -// check-pass +// known-bug: #117606 #![feature(associated_type_defaults)] diff --git a/tests/ui/generic-associated-types/assume-gat-normalization-for-nested-goals.stderr b/tests/ui/generic-associated-types/assume-gat-normalization-for-nested-goals.stderr new file mode 100644 index 0000000000000..abad0f25c0f43 --- /dev/null +++ b/tests/ui/generic-associated-types/assume-gat-normalization-for-nested-goals.stderr @@ -0,0 +1,24 @@ +error[E0277]: the trait bound `::Bar<()>: Eq` is not satisfied + --> $DIR/assume-gat-normalization-for-nested-goals.rs:6:30 + | +LL | type Bar: Baz = i32; + | ^^^ the trait `Eq` is not implemented for `::Bar<()>` + | +note: required for `i32` to implement `Baz` + --> $DIR/assume-gat-normalization-for-nested-goals.rs:13:23 + | +LL | impl Baz for i32 where T::Bar<()>: Eq {} + | ^^^^^^ ^^^ ------- unsatisfied trait bound introduced here +note: required by a bound in `Foo::Bar` + --> $DIR/assume-gat-normalization-for-nested-goals.rs:6:18 + | +LL | type Bar: Baz = i32; + | ^^^^^^^^^ required by this bound in `Foo::Bar` +help: consider further restricting the associated type + | +LL | trait Foo where ::Bar<()>: Eq { + | +++++++++++++++++++++++++++++++++++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/generic-associated-types/higher-ranked-self-impl-requirement.rs b/tests/ui/generic-associated-types/higher-ranked-self-impl-requirement.rs new file mode 100644 index 0000000000000..5ef9437c96875 --- /dev/null +++ b/tests/ui/generic-associated-types/higher-ranked-self-impl-requirement.rs @@ -0,0 +1,20 @@ +// check-pass + +trait Database: for<'r> HasValueRef<'r, Database = Self> {} + +trait HasValueRef<'r> { + type Database: Database; +} + +struct Any; + +impl Database for Any {} + +impl<'r> HasValueRef<'r> for Any { + // Make sure we don't have issues when the GAT assumption + // `>::Database = Any` isn't universally + // parameterized over `'r`. + type Database = Any; +} + +fn main() {} diff --git a/tests/ui/traits/new-solver/specialization-transmute.rs b/tests/ui/traits/new-solver/specialization-transmute.rs index f6b19e7adf512..fac7d76f8cf5f 100644 --- a/tests/ui/traits/new-solver/specialization-transmute.rs +++ b/tests/ui/traits/new-solver/specialization-transmute.rs @@ -10,7 +10,7 @@ trait Default { } impl Default for T { - default type Id = T; + default type Id = T; //~ ERROR type annotations needed // This will be fixed by #111994 fn intu(&self) -> &Self::Id { //~ ERROR type annotations needed self diff --git a/tests/ui/traits/new-solver/specialization-transmute.stderr b/tests/ui/traits/new-solver/specialization-transmute.stderr index 09b1405fefbf3..18965a465b3fa 100644 --- a/tests/ui/traits/new-solver/specialization-transmute.stderr +++ b/tests/ui/traits/new-solver/specialization-transmute.stderr @@ -16,6 +16,13 @@ LL | fn intu(&self) -> &Self::Id { | = note: cannot satisfy `::Id == _` -error: aborting due to previous error; 1 warning emitted +error[E0282]: type annotations needed + --> $DIR/specialization-transmute.rs:13:23 + | +LL | default type Id = T; + | ^ cannot infer type for associated type `::Id` + +error: aborting due to 2 previous errors; 1 warning emitted -For more information about this error, try `rustc --explain E0284`. +Some errors have detailed explanations: E0282, E0284. +For more information about an error, try `rustc --explain E0282`. diff --git a/tests/ui/traits/new-solver/specialization-unconstrained.rs b/tests/ui/traits/new-solver/specialization-unconstrained.rs index 02150689ee5c3..7fd753109be2d 100644 --- a/tests/ui/traits/new-solver/specialization-unconstrained.rs +++ b/tests/ui/traits/new-solver/specialization-unconstrained.rs @@ -11,7 +11,7 @@ trait Default { } impl Default for T { - default type Id = T; + default type Id = T; //~ ERROR type annotations needed } fn test, U>() {} diff --git a/tests/ui/traits/new-solver/specialization-unconstrained.stderr b/tests/ui/traits/new-solver/specialization-unconstrained.stderr index 910925cbaeb0d..ed4dafa1484c2 100644 --- a/tests/ui/traits/new-solver/specialization-unconstrained.stderr +++ b/tests/ui/traits/new-solver/specialization-unconstrained.stderr @@ -20,6 +20,13 @@ note: required by a bound in `test` LL | fn test, U>() {} | ^^^^^^ required by this bound in `test` -error: aborting due to previous error; 1 warning emitted +error[E0282]: type annotations needed + --> $DIR/specialization-unconstrained.rs:14:22 + | +LL | default type Id = T; + | ^ cannot infer type for associated type `::Id` + +error: aborting due to 2 previous errors; 1 warning emitted -For more information about this error, try `rustc --explain E0284`. +Some errors have detailed explanations: E0282, E0284. +For more information about an error, try `rustc --explain E0282`.