Skip to content

Only use normalize_param_env when normalizing predicate in check_item_bounds #117542

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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 <https://github.com/rust-lang/rust/pull/117542#issue-1976337685>.
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;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// check-pass
// known-bug: #117606

#![feature(associated_type_defaults)]

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
error[E0277]: the trait bound `<Self as Foo>::Bar<()>: Eq<i32>` is not satisfied
--> $DIR/assume-gat-normalization-for-nested-goals.rs:6:30
|
LL | type Bar<T>: Baz<Self> = i32;
| ^^^ the trait `Eq<i32>` is not implemented for `<Self as Foo>::Bar<()>`
|
note: required for `i32` to implement `Baz<Self>`
--> $DIR/assume-gat-normalization-for-nested-goals.rs:13:23
|
LL | impl<T: Foo + ?Sized> Baz<T> for i32 where T::Bar<()>: Eq<i32> {}
| ^^^^^^ ^^^ ------- 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<T>: Baz<Self> = i32;
| ^^^^^^^^^ required by this bound in `Foo::Bar`
help: consider further restricting the associated type
|
LL | trait Foo where <Self as Foo>::Bar<()>: Eq<i32> {
| +++++++++++++++++++++++++++++++++++++

error: aborting due to previous error

For more information about this error, try `rustc --explain E0277`.
Original file line number Diff line number Diff line change
@@ -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
// `<Any as HasValue<'r>>::Database = Any` isn't universally
// parameterized over `'r`.
type Database = Any;
}

fn main() {}
2 changes: 1 addition & 1 deletion tests/ui/traits/new-solver/specialization-transmute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ trait Default {
}

impl<T> 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
Expand Down
11 changes: 9 additions & 2 deletions tests/ui/traits/new-solver/specialization-transmute.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@ LL | fn intu(&self) -> &Self::Id {
|
= note: cannot satisfy `<T as Default>::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 `<T as Default>::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`.
2 changes: 1 addition & 1 deletion tests/ui/traits/new-solver/specialization-unconstrained.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ trait Default {
}

impl<T> Default for T {
default type Id = T;
default type Id = T; //~ ERROR type annotations needed
}

fn test<T: Default<Id = U>, U>() {}
Expand Down
11 changes: 9 additions & 2 deletions tests/ui/traits/new-solver/specialization-unconstrained.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,13 @@ note: required by a bound in `test`
LL | fn test<T: Default<Id = U>, 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 `<T as Default>::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`.