Skip to content

wf: emit projection goal for aliases #140558

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

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
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
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ fn compare_method_predicate_entailment<'tcx>(
for obligation in obligations {
debug!(?obligation);
match obligation.predicate.kind().skip_binder() {
// We need to register Projection oblgiations too, because we may end up with
// We need to register Projection obligations too, because we may end up with
// an implied `X::Item: 'a`, which gets desugared into `X::Item = ?0`, `?0: 'a`.
// If we only register the region outlives obligation, this leads to an unconstrained var.
// See `implied_bounds_entailment_alias_var.rs` test.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -381,8 +381,6 @@ fn check_predicates<'tcx>(
let obligations =
wf::obligations(infcx, tcx.param_env(impl1_def_id), impl1_def_id, 0, term, span)
.unwrap();

assert!(!obligations.has_infer());
impl2_predicates
.extend(traits::elaborate(tcx, obligations).map(|obligation| obligation.predicate))
}
Expand Down
10 changes: 9 additions & 1 deletion compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.type_matches_expected_vid(expected_vid, data.self_ty())
}
ty::PredicateKind::Clause(ty::ClauseKind::Projection(data)) => {
self.type_matches_expected_vid(expected_vid, data.projection_term.self_ty())
match data.projection_term.kind(self.tcx) {
ty::AliasTermKind::ProjectionTy | ty::AliasTermKind::ProjectionConst => {
self.type_matches_expected_vid(expected_vid, data.projection_term.self_ty())
}
ty::AliasTermKind::InherentTy
| ty::AliasTermKind::OpaqueTy
| ty::AliasTermKind::FreeTy
| ty::AliasTermKind::UnevaluatedConst => false,
}
}
ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..))
| ty::PredicateKind::Subtype(..)
Expand Down
37 changes: 28 additions & 9 deletions compiler/rustc_trait_selection/src/traits/wf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -509,8 +509,6 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
let obligations = self.nominal_obligations(data.def_id, args);
self.out.extend(obligations);
}

data.args.visit_with(self);
}

fn add_wf_preds_for_projection_args(&mut self, args: GenericArgsRef<'tcx>) {
Expand Down Expand Up @@ -771,13 +769,34 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
// Simple cases that are WF if their type args are WF.
}

ty::Alias(ty::Projection | ty::Opaque | ty::Free, data) => {
let obligations = self.nominal_obligations(data.def_id, data.args);
self.out.extend(obligations);
}
ty::Alias(ty::Inherent, data) => {
self.add_wf_preds_for_inherent_projection(data);
return; // Subtree handled by compute_inherent_projection.
ty::Alias(kind, data) => {
let code = ObligationCauseCode::Misc;
let cause = self.cause(code);
let inf = self.infcx.next_ty_var(rustc_span::DUMMY_SP);
let projection_goal_supported =
matches!(kind, ty::Projection) || self.infcx.next_trait_solver();
if projection_goal_supported && !data.has_escaping_bound_vars() {
let obligation: traits::PredicateObligation<'tcx> =
traits::Obligation::with_depth(
self.tcx(),
cause,
self.recursion_depth,
self.param_env,
ty::ProjectionPredicate {
projection_term: data.into(),
term: inf.into(),
},
);
self.out.push(obligation);
}

match kind {
ty::Projection | ty::Opaque | ty::Free => {
let obligations = self.nominal_obligations(data.def_id, data.args);
self.out.extend(obligations);
}
ty::Inherent => self.add_wf_preds_for_inherent_projection(data),
}
}

ty::Adt(def, args) => {
Expand Down
14 changes: 0 additions & 14 deletions tests/crashes/102252.rs

This file was deleted.

18 changes: 0 additions & 18 deletions tests/crashes/126268.rs

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error: overflow evaluating associated type `T::This`
--> $DIR/normalization-overflow.rs:9:17
--> $DIR/normalization-overflow.rs:12:17
|
LL | type This = Self::This;
| ^^^^^^^^^^
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
error[E0271]: type mismatch resolving `T::This normalizes-to _`
--> $DIR/normalization-overflow.rs:12:17
|
LL | type This = Self::This;
| ^^^^^^^^^^ types differ

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0271`.
7 changes: 6 additions & 1 deletion tests/ui/associated-inherent-types/normalization-overflow.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
//@ revisions: current next
//@[next] compile-flags: -Znext-solver
//@ ignore-compare-mode-next-solver (explicit revisions)
#![feature(inherent_associated_types)]
#![allow(incomplete_features)]

Expand All @@ -6,7 +9,9 @@
struct T;

impl T {
type This = Self::This; //~ ERROR overflow evaluating associated type `T::This`
type This = Self::This;
//[current]~^ ERROR overflow evaluating associated type `T::This`
//[next]~^^ ERROR type mismatch resolving `T::This normalizes-to _`
}

fn main() {}
10 changes: 9 additions & 1 deletion tests/ui/auto-traits/assoc-ty.next.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,15 @@ LL | let _: <() as Trait>::Output = ();
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

error: aborting due to 4 previous errors
error[E0271]: type mismatch resolving `<() as Trait>::Output normalizes-to _`
--> $DIR/assoc-ty.rs:15:12
|
LL | let _: <() as Trait>::Output = ();
| ^^^^^^^^^^^^^^^^^^^^^ types differ
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

error: aborting due to 5 previous errors

Some errors have detailed explanations: E0271, E0380, E0658.
For more information about an error, try `rustc --explain E0271`.
1 change: 1 addition & 0 deletions tests/ui/auto-traits/assoc-ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ fn main() {
//[current]~^ ERROR mismatched types
//[next]~^^ ERROR type mismatch resolving `<() as Trait>::Output normalizes-to _`
//[next]~| ERROR type mismatch resolving `<() as Trait>::Output normalizes-to _`
//[next]~| ERROR type mismatch resolving `<() as Trait>::Output normalizes-to _`
}
5 changes: 0 additions & 5 deletions tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,6 @@ help: this trait has no implementations, consider adding one
|
LL | trait Foo {}
| ^^^^^^^^^
note: required by a bound in `A`
--> $DIR/alias-bounds-when-not-wf.rs:8:11
|
LL | type A<T: Foo> = T;
| ^^^ required by this bound in `A`

error[E0277]: the trait bound `usize: Foo` is not satisfied
--> $DIR/alias-bounds-when-not-wf.rs:16:10
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ LL | (build2(x),)
| ------------ returning here with type `(impl Sized,)`

warning: function cannot return without recursing
--> $DIR/recursive-in-exhaustiveness.rs:40:1
--> $DIR/recursive-in-exhaustiveness.rs:41:1
|
LL | fn build3<T>(x: T) -> impl Sized {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
Expand All @@ -42,7 +42,7 @@ LL | let (x,) = (build3((x,)),);
= help: a `loop` may express intention better if this is on purpose

error[E0792]: expected generic type parameter, found `(T,)`
--> $DIR/recursive-in-exhaustiveness.rs:49:5
--> $DIR/recursive-in-exhaustiveness.rs:51:5
|
LL | fn build3<T>(x: T) -> impl Sized {
| - this generic parameter must be used with a generic type parameter
Expand Down
30 changes: 23 additions & 7 deletions tests/ui/impl-trait/recursive-in-exhaustiveness.next.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,14 @@ error[E0271]: type mismatch resolving `build2<(_,)>::{opaque#0} normalizes-to _`
LL | (build2(x),)
| ^^^^^^^^^ types differ

error[E0271]: type mismatch resolving `build2<(_,)>::{opaque#0} normalizes-to _`
--> $DIR/recursive-in-exhaustiveness.rs:31:6
|
LL | (build2(x),)
| ^^^^^^^^^ types differ
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

error[E0271]: type mismatch resolving `build2<(_,)>::{opaque#0} normalizes-to _`
--> $DIR/recursive-in-exhaustiveness.rs:31:5
|
Expand All @@ -26,13 +34,21 @@ LL | (build2(x),)
= note: tuples must have a statically known size to be initialized

error[E0271]: type mismatch resolving `build3<(T,)>::{opaque#0} normalizes-to _`
--> $DIR/recursive-in-exhaustiveness.rs:42:17
--> $DIR/recursive-in-exhaustiveness.rs:43:17
|
LL | let (x,) = (build3((x,)),);
| ^^^^^^^^^^^^ types differ

error[E0271]: type mismatch resolving `build3<(T,)>::{opaque#0} normalizes-to _`
--> $DIR/recursive-in-exhaustiveness.rs:43:17
|
LL | let (x,) = (build3((x,)),);
| ^^^^^^^^^^^^ types differ
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

error[E0277]: the size for values of type `(impl Sized,)` cannot be known at compilation time
--> $DIR/recursive-in-exhaustiveness.rs:42:16
--> $DIR/recursive-in-exhaustiveness.rs:43:16
|
LL | let (x,) = (build3((x,)),);
| ^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
Expand All @@ -41,7 +57,7 @@ LL | let (x,) = (build3((x,)),);
= note: tuples must have a statically known size to be initialized

error[E0308]: mismatched types
--> $DIR/recursive-in-exhaustiveness.rs:42:16
--> $DIR/recursive-in-exhaustiveness.rs:43:16
|
LL | fn build3<T>(x: T) -> impl Sized {
| ---------- the found opaque type
Expand All @@ -53,28 +69,28 @@ LL | let (x,) = (build3((x,)),);
found tuple `(impl Sized,)`

error[E0271]: type mismatch resolving `build3<(T,)>::{opaque#0} normalizes-to _`
--> $DIR/recursive-in-exhaustiveness.rs:42:17
--> $DIR/recursive-in-exhaustiveness.rs:43:17
|
LL | let (x,) = (build3((x,)),);
| ^^^^^^^^^^^^ types differ
|
= note: the return type of a function must have a statically known size

error[E0271]: type mismatch resolving `build3<(T,)>::{opaque#0} normalizes-to _`
--> $DIR/recursive-in-exhaustiveness.rs:42:16
--> $DIR/recursive-in-exhaustiveness.rs:43:16
|
LL | let (x,) = (build3((x,)),);
| ^^^^^^^^^^^^^^^ types differ

error[E0271]: type mismatch resolving `build3<(T,)>::{opaque#0} normalizes-to _`
--> $DIR/recursive-in-exhaustiveness.rs:42:17
--> $DIR/recursive-in-exhaustiveness.rs:43:17
|
LL | let (x,) = (build3((x,)),);
| ^^^^^^^^^^^^ types differ
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

error: aborting due to 10 previous errors
error: aborting due to 12 previous errors

Some errors have detailed explanations: E0271, E0277, E0284, E0308.
For more information about an error, try `rustc --explain E0271`.
2 changes: 2 additions & 0 deletions tests/ui/impl-trait/recursive-in-exhaustiveness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ fn build2<T>(x: T) -> impl Sized {
//[next]~^ ERROR type mismatch resolving
//[next]~| ERROR type mismatch resolving
//[next]~| ERROR the size for values of type
//[next]~| ERROR type mismatch resolving `build2<(_,)>::{opaque#0} normalizes-to _`
}

// Opaque<T> = Opaque<(T,)>
Expand All @@ -44,6 +45,7 @@ fn build3<T>(x: T) -> impl Sized {
//[next]~| ERROR type mismatch resolving
//[next]~| ERROR type mismatch resolving
//[next]~| ERROR type mismatch resolving
//[next]~| ERROR type mismatch resolving
//[next]~| ERROR the size for values of type
//[next]~| ERROR mismatched types
build3(x)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
error[E0275]: overflow normalizing the type alias `X2`
--> $DIR/infinite-type-alias-mutual-recursion.rs:9:11
|
LL | type X1 = X2;
| ^^
|
= note: in case this is a recursive type alias, consider using a struct, enum, or union instead

error[E0275]: overflow normalizing the type alias `X3`
--> $DIR/infinite-type-alias-mutual-recursion.rs:14:11
|
LL | type X2 = X3;
| ^^
|
= note: in case this is a recursive type alias, consider using a struct, enum, or union instead

error[E0275]: overflow normalizing the type alias `X1`
--> $DIR/infinite-type-alias-mutual-recursion.rs:18:11
|
LL | type X3 = X1;
| ^^
|
= note: in case this is a recursive type alias, consider using a struct, enum, or union instead

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0275`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
error[E0391]: cycle detected when expanding type alias `X1`
--> $DIR/infinite-type-alias-mutual-recursion.rs:9:11
|
LL | type X1 = X2;
| ^^
|
note: ...which requires expanding type alias `X2`...
--> $DIR/infinite-type-alias-mutual-recursion.rs:14:11
|
LL | type X2 = X3;
| ^^
note: ...which requires expanding type alias `X3`...
--> $DIR/infinite-type-alias-mutual-recursion.rs:18:11
|
LL | type X3 = X1;
| ^^
= note: ...which again requires expanding type alias `X1`, completing the cycle
= note: type aliases cannot be recursive
= help: consider using a struct, enum, or union instead to break the cycle
= help: see <https://doc.rust-lang.org/reference/types.html#recursive-types> for more information
note: cycle used when checking that `X1` is well-formed
--> $DIR/infinite-type-alias-mutual-recursion.rs:9:1
|
LL | type X1 = X2;
| ^^^^^^^
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0391`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
error[E0271]: type mismatch resolving `X2 normalizes-to _`
--> $DIR/infinite-type-alias-mutual-recursion.rs:9:11
|
LL | type X1 = X2;
| ^^ types differ

error[E0271]: type mismatch resolving `X3 normalizes-to _`
--> $DIR/infinite-type-alias-mutual-recursion.rs:14:11
|
LL | type X2 = X3;
| ^^ types differ

error[E0271]: type mismatch resolving `X1 normalizes-to _`
--> $DIR/infinite-type-alias-mutual-recursion.rs:18:11
|
LL | type X3 = X1;
| ^^ types differ

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0271`.
Loading
Loading