Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 283c81f

Browse filesBrowse files
committed
wf: emit projection goal for aliases
To check that their normalization succeeds in the current environment. This eagerly detects ambiguous and diverging aliases.
1 parent 0e517d3 commit 283c81f
Copy full SHA for 283c81f

File tree

Expand file treeCollapse file tree

33 files changed

+340
-100
lines changed
Filter options
Expand file treeCollapse file tree

33 files changed

+340
-100
lines changed

‎compiler/rustc_hir_analysis/src/check/compare_impl_item.rs

Copy file name to clipboardExpand all lines: compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,7 @@ fn compare_method_predicate_entailment<'tcx>(
393393
for obligation in obligations {
394394
debug!(?obligation);
395395
match obligation.predicate.kind().skip_binder() {
396-
// We need to register Projection oblgiations too, because we may end up with
396+
// We need to register Projection obligations too, because we may end up with
397397
// an implied `X::Item: 'a`, which gets desugared into `X::Item = ?0`, `?0: 'a`.
398398
// If we only register the region outlives obligation, this leads to an unconstrained var.
399399
// See `implied_bounds_entailment_alias_var.rs` test.

‎compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs

Copy file name to clipboardExpand all lines: compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs
-2Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -381,8 +381,6 @@ fn check_predicates<'tcx>(
381381
let obligations =
382382
wf::obligations(infcx, tcx.param_env(impl1_def_id), impl1_def_id, 0, term, span)
383383
.unwrap();
384-
385-
assert!(!obligations.has_infer());
386384
impl2_predicates
387385
.extend(traits::elaborate(tcx, obligations).map(|obligation| obligation.predicate))
388386
}

‎compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs

Copy file name to clipboardExpand all lines: compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs
+9-1Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
3939
self.type_matches_expected_vid(expected_vid, data.self_ty())
4040
}
4141
ty::PredicateKind::Clause(ty::ClauseKind::Projection(data)) => {
42-
self.type_matches_expected_vid(expected_vid, data.projection_term.self_ty())
42+
match data.projection_term.kind(self.tcx) {
43+
ty::AliasTermKind::ProjectionTy | ty::AliasTermKind::ProjectionConst => {
44+
self.type_matches_expected_vid(expected_vid, data.projection_term.self_ty())
45+
}
46+
ty::AliasTermKind::InherentTy
47+
| ty::AliasTermKind::OpaqueTy
48+
| ty::AliasTermKind::FreeTy
49+
| ty::AliasTermKind::UnevaluatedConst => false,
50+
}
4351
}
4452
ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..))
4553
| ty::PredicateKind::Subtype(..)

‎compiler/rustc_trait_selection/src/traits/wf.rs

Copy file name to clipboardExpand all lines: compiler/rustc_trait_selection/src/traits/wf.rs
+28-9Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -509,8 +509,6 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
509509
let obligations = self.nominal_obligations(data.def_id, args);
510510
self.out.extend(obligations);
511511
}
512-
513-
data.args.visit_with(self);
514512
}
515513

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

774-
ty::Alias(ty::Projection | ty::Opaque | ty::Free, data) => {
775-
let obligations = self.nominal_obligations(data.def_id, data.args);
776-
self.out.extend(obligations);
777-
}
778-
ty::Alias(ty::Inherent, data) => {
779-
self.add_wf_preds_for_inherent_projection(data);
780-
return; // Subtree handled by compute_inherent_projection.
772+
ty::Alias(kind, data) => {
773+
let code = ObligationCauseCode::Misc;
774+
let cause = self.cause(code);
775+
let inf = self.infcx.next_ty_var(rustc_span::DUMMY_SP);
776+
let projection_goal_supported =
777+
matches!(kind, ty::Projection) || self.infcx.next_trait_solver();
778+
if projection_goal_supported && !data.has_escaping_bound_vars() {
779+
let obligation: traits::PredicateObligation<'tcx> =
780+
traits::Obligation::with_depth(
781+
self.tcx(),
782+
cause,
783+
self.recursion_depth,
784+
self.param_env,
785+
ty::ProjectionPredicate {
786+
projection_term: data.into(),
787+
term: inf.into(),
788+
},
789+
);
790+
self.out.push(obligation);
791+
}
792+
793+
match kind {
794+
ty::Projection | ty::Opaque | ty::Free => {
795+
let obligations = self.nominal_obligations(data.def_id, data.args);
796+
self.out.extend(obligations);
797+
}
798+
ty::Inherent => self.add_wf_preds_for_inherent_projection(data),
799+
}
781800
}
782801

783802
ty::Adt(def, args) => {

‎tests/ui/associated-inherent-types/normalization-overflow.stderr renamed to ‎tests/ui/associated-inherent-types/normalization-overflow.current.stderr

Copy file name to clipboardExpand all lines: tests/ui/associated-inherent-types/normalization-overflow.current.stderr
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: overflow evaluating associated type `T::This`
2-
--> $DIR/normalization-overflow.rs:9:17
2+
--> $DIR/normalization-overflow.rs:12:17
33
|
44
LL | type This = Self::This;
55
| ^^^^^^^^^^
+9Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0271]: type mismatch resolving `T::This normalizes-to _`
2+
--> $DIR/normalization-overflow.rs:12:17
3+
|
4+
LL | type This = Self::This;
5+
| ^^^^^^^^^^ types differ
6+
7+
error: aborting due to 1 previous error
8+
9+
For more information about this error, try `rustc --explain E0271`.
+6-1Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
//@ revisions: current next
2+
//@[next] compile-flags: -Znext-solver
3+
//@ ignore-compare-mode-next-solver (explicit revisions)
14
#![feature(inherent_associated_types)]
25
#![allow(incomplete_features)]
36

@@ -6,7 +9,9 @@
69
struct T;
710

811
impl T {
9-
type This = Self::This; //~ ERROR overflow evaluating associated type `T::This`
12+
type This = Self::This;
13+
//[current]~^ ERROR overflow evaluating associated type `T::This`
14+
//[next]~^^ ERROR type mismatch resolving `T::This normalizes-to _`
1015
}
1116

1217
fn main() {}

‎tests/ui/auto-traits/assoc-ty.next.stderr

Copy file name to clipboardExpand all lines: tests/ui/auto-traits/assoc-ty.next.stderr
+9-1Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,15 @@ LL | let _: <() as Trait>::Output = ();
3535
|
3636
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
3737

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

4048
Some errors have detailed explanations: E0271, E0380, E0658.
4149
For more information about an error, try `rustc --explain E0271`.

‎tests/ui/auto-traits/assoc-ty.rs

Copy file name to clipboardExpand all lines: tests/ui/auto-traits/assoc-ty.rs
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,5 @@ fn main() {
1616
//[current]~^ ERROR mismatched types
1717
//[next]~^^ ERROR type mismatch resolving `<() as Trait>::Output normalizes-to _`
1818
//[next]~| ERROR type mismatch resolving `<() as Trait>::Output normalizes-to _`
19+
//[next]~| ERROR type mismatch resolving `<() as Trait>::Output normalizes-to _`
1920
}

‎tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.stderr

Copy file name to clipboardExpand all lines: tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.stderr
-5Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,6 @@ help: this trait has no implementations, consider adding one
1818
|
1919
LL | trait Foo {}
2020
| ^^^^^^^^^
21-
note: required by a bound in `A`
22-
--> $DIR/alias-bounds-when-not-wf.rs:8:11
23-
|
24-
LL | type A<T: Foo> = T;
25-
| ^^^ required by this bound in `A`
2621

2722
error[E0277]: the trait bound `usize: Foo` is not satisfied
2823
--> $DIR/alias-bounds-when-not-wf.rs:16:10

‎tests/ui/impl-trait/recursive-in-exhaustiveness.current.stderr

Copy file name to clipboardExpand all lines: tests/ui/impl-trait/recursive-in-exhaustiveness.current.stderr
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ LL | (build2(x),)
3131
| ------------ returning here with type `(impl Sized,)`
3232

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

4444
error[E0792]: expected generic type parameter, found `(T,)`
45-
--> $DIR/recursive-in-exhaustiveness.rs:49:5
45+
--> $DIR/recursive-in-exhaustiveness.rs:51:5
4646
|
4747
LL | fn build3<T>(x: T) -> impl Sized {
4848
| - this generic parameter must be used with a generic type parameter

‎tests/ui/impl-trait/recursive-in-exhaustiveness.next.stderr

Copy file name to clipboardExpand all lines: tests/ui/impl-trait/recursive-in-exhaustiveness.next.stderr
+23-7Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,14 @@ error[E0271]: type mismatch resolving `build2<(_,)>::{opaque#0} normalizes-to _`
1010
LL | (build2(x),)
1111
| ^^^^^^^^^ types differ
1212

13+
error[E0271]: type mismatch resolving `build2<(_,)>::{opaque#0} normalizes-to _`
14+
--> $DIR/recursive-in-exhaustiveness.rs:31:6
15+
|
16+
LL | (build2(x),)
17+
| ^^^^^^^^^ types differ
18+
|
19+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
20+
1321
error[E0271]: type mismatch resolving `build2<(_,)>::{opaque#0} normalizes-to _`
1422
--> $DIR/recursive-in-exhaustiveness.rs:31:5
1523
|
@@ -26,13 +34,21 @@ LL | (build2(x),)
2634
= note: tuples must have a statically known size to be initialized
2735

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

42+
error[E0271]: type mismatch resolving `build3<(T,)>::{opaque#0} normalizes-to _`
43+
--> $DIR/recursive-in-exhaustiveness.rs:43:17
44+
|
45+
LL | let (x,) = (build3((x,)),);
46+
| ^^^^^^^^^^^^ types differ
47+
|
48+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
49+
3450
error[E0277]: the size for values of type `(impl Sized,)` cannot be known at compilation time
35-
--> $DIR/recursive-in-exhaustiveness.rs:42:16
51+
--> $DIR/recursive-in-exhaustiveness.rs:43:16
3652
|
3753
LL | let (x,) = (build3((x,)),);
3854
| ^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
@@ -41,7 +57,7 @@ LL | let (x,) = (build3((x,)),);
4157
= note: tuples must have a statically known size to be initialized
4258

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

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

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

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

77-
error: aborting due to 10 previous errors
93+
error: aborting due to 12 previous errors
7894

7995
Some errors have detailed explanations: E0271, E0277, E0284, E0308.
8096
For more information about an error, try `rustc --explain E0271`.

‎tests/ui/impl-trait/recursive-in-exhaustiveness.rs

Copy file name to clipboardExpand all lines: tests/ui/impl-trait/recursive-in-exhaustiveness.rs
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ fn build2<T>(x: T) -> impl Sized {
3232
//[next]~^ ERROR type mismatch resolving
3333
//[next]~| ERROR type mismatch resolving
3434
//[next]~| ERROR the size for values of type
35+
//[next]~| ERROR type mismatch resolving `build2<(_,)>::{opaque#0} normalizes-to _`
3536
}
3637

3738
// Opaque<T> = Opaque<(T,)>
@@ -44,6 +45,7 @@ fn build3<T>(x: T) -> impl Sized {
4445
//[next]~| ERROR type mismatch resolving
4546
//[next]~| ERROR type mismatch resolving
4647
//[next]~| ERROR type mismatch resolving
48+
//[next]~| ERROR type mismatch resolving
4749
//[next]~| ERROR the size for values of type
4850
//[next]~| ERROR mismatched types
4951
build3(x)
+27Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
error[E0275]: overflow normalizing the type alias `X2`
2+
--> $DIR/infinite-type-alias-mutual-recursion.rs:9:11
3+
|
4+
LL | type X1 = X2;
5+
| ^^
6+
|
7+
= note: in case this is a recursive type alias, consider using a struct, enum, or union instead
8+
9+
error[E0275]: overflow normalizing the type alias `X3`
10+
--> $DIR/infinite-type-alias-mutual-recursion.rs:14:11
11+
|
12+
LL | type X2 = X3;
13+
| ^^
14+
|
15+
= note: in case this is a recursive type alias, consider using a struct, enum, or union instead
16+
17+
error[E0275]: overflow normalizing the type alias `X1`
18+
--> $DIR/infinite-type-alias-mutual-recursion.rs:18:11
19+
|
20+
LL | type X3 = X1;
21+
| ^^
22+
|
23+
= note: in case this is a recursive type alias, consider using a struct, enum, or union instead
24+
25+
error: aborting due to 3 previous errors
26+
27+
For more information about this error, try `rustc --explain E0275`.
+30Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
error[E0391]: cycle detected when expanding type alias `X1`
2+
--> $DIR/infinite-type-alias-mutual-recursion.rs:9:11
3+
|
4+
LL | type X1 = X2;
5+
| ^^
6+
|
7+
note: ...which requires expanding type alias `X2`...
8+
--> $DIR/infinite-type-alias-mutual-recursion.rs:14:11
9+
|
10+
LL | type X2 = X3;
11+
| ^^
12+
note: ...which requires expanding type alias `X3`...
13+
--> $DIR/infinite-type-alias-mutual-recursion.rs:18:11
14+
|
15+
LL | type X3 = X1;
16+
| ^^
17+
= note: ...which again requires expanding type alias `X1`, completing the cycle
18+
= note: type aliases cannot be recursive
19+
= help: consider using a struct, enum, or union instead to break the cycle
20+
= help: see <https://doc.rust-lang.org/reference/types.html#recursive-types> for more information
21+
note: cycle used when checking that `X1` is well-formed
22+
--> $DIR/infinite-type-alias-mutual-recursion.rs:9:1
23+
|
24+
LL | type X1 = X2;
25+
| ^^^^^^^
26+
= 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
27+
28+
error: aborting due to 1 previous error
29+
30+
For more information about this error, try `rustc --explain E0391`.
+21Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
error[E0271]: type mismatch resolving `X2 normalizes-to _`
2+
--> $DIR/infinite-type-alias-mutual-recursion.rs:9:11
3+
|
4+
LL | type X1 = X2;
5+
| ^^ types differ
6+
7+
error[E0271]: type mismatch resolving `X3 normalizes-to _`
8+
--> $DIR/infinite-type-alias-mutual-recursion.rs:14:11
9+
|
10+
LL | type X2 = X3;
11+
| ^^ types differ
12+
13+
error[E0271]: type mismatch resolving `X1 normalizes-to _`
14+
--> $DIR/infinite-type-alias-mutual-recursion.rs:18:11
15+
|
16+
LL | type X3 = X1;
17+
| ^^ types differ
18+
19+
error: aborting due to 3 previous errors
20+
21+
For more information about this error, try `rustc --explain E0271`.
+30Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
error[E0391]: cycle detected when expanding type alias `X1`
2+
--> $DIR/infinite-type-alias-mutual-recursion.rs:9:11
3+
|
4+
LL | type X1 = X2;
5+
| ^^
6+
|
7+
note: ...which requires expanding type alias `X2`...
8+
--> $DIR/infinite-type-alias-mutual-recursion.rs:14:11
9+
|
10+
LL | type X2 = X3;
11+
| ^^
12+
note: ...which requires expanding type alias `X3`...
13+
--> $DIR/infinite-type-alias-mutual-recursion.rs:18:11
14+
|
15+
LL | type X3 = X1;
16+
| ^^
17+
= note: ...which again requires expanding type alias `X1`, completing the cycle
18+
= note: type aliases cannot be recursive
19+
= help: consider using a struct, enum, or union instead to break the cycle
20+
= help: see <https://doc.rust-lang.org/reference/types.html#recursive-types> for more information
21+
note: cycle used when checking that `X1` is well-formed
22+
--> $DIR/infinite-type-alias-mutual-recursion.rs:9:1
23+
|
24+
LL | type X1 = X2;
25+
| ^^^^^^^
26+
= 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
27+
28+
error: aborting due to 1 previous error
29+
30+
For more information about this error, try `rustc --explain E0391`.

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.