Skip to content

Commit cb50cae

Browse files
Recurse into args in WF even if they have escaping bound vars
1 parent 1419cf4 commit cb50cae

File tree

8 files changed

+69
-155
lines changed

8 files changed

+69
-155
lines changed

compiler/rustc_trait_selection/src/traits/wf.rs

+15-58
Original file line numberDiff line numberDiff line change
@@ -396,36 +396,17 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
396396
self.out.extend(obligations);
397397
}
398398

399-
self.out.extend(
400-
trait_ref
401-
.args
402-
.iter()
403-
.enumerate()
404-
.filter(|(_, arg)| {
405-
matches!(arg.unpack(), GenericArgKind::Type(..) | GenericArgKind::Const(..))
406-
})
407-
.filter(|(_, arg)| !arg.has_escaping_bound_vars())
408-
.map(|(i, arg)| {
409-
let mut cause = traits::ObligationCause::misc(self.span, self.body_id);
410-
// The first arg is the self ty - use the correct span for it.
411-
if i == 0 {
412-
if let Some(hir::ItemKind::Impl(hir::Impl { self_ty, .. })) =
413-
item.map(|i| &i.kind)
414-
{
415-
cause.span = self_ty.span;
416-
}
417-
}
418-
traits::Obligation::with_depth(
419-
tcx,
420-
cause,
421-
depth,
422-
param_env,
423-
ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(
424-
arg,
425-
))),
426-
)
427-
}),
428-
);
399+
if let Some(hir::ItemKind::Impl(hir::Impl { self_ty, .. })) = item.map(|i| &i.kind) {
400+
// FIXME: Could generalize this hack.
401+
let span = std::mem::replace(&mut self.span, self_ty.span);
402+
// make sure that the trait ref is WF.
403+
trait_ref.args[0].visit_with(self);
404+
self.span = span;
405+
(&trait_ref.args[1..]).visit_with(self);
406+
} else {
407+
// make sure that the trait ref is WF.
408+
trait_ref.visit_with(self);
409+
}
429410
}
430411

431412
// Compute the obligations that are required for `trait_ref` to be WF,
@@ -463,7 +444,8 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
463444
let obligations = self.nominal_obligations(data.def_id, data.args);
464445
self.out.extend(obligations);
465446

466-
self.compute_projection_args(data.args);
447+
// Make sure that projection args are WF.
448+
data.visit_with(self);
467449
}
468450

469451
/// Pushes the obligations required for an inherent alias to be WF
@@ -493,33 +475,8 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
493475
self.out.extend(obligations);
494476
}
495477

496-
self.compute_projection_args(data.args);
497-
}
498-
499-
fn compute_projection_args(&mut self, args: GenericArgsRef<'tcx>) {
500-
let tcx = self.tcx();
501-
let cause = self.cause(traits::WellFormed(None));
502-
let param_env = self.param_env;
503-
let depth = self.recursion_depth;
504-
505-
self.out.extend(
506-
args.iter()
507-
.filter(|arg| {
508-
matches!(arg.unpack(), GenericArgKind::Type(..) | GenericArgKind::Const(..))
509-
})
510-
.filter(|arg| !arg.has_escaping_bound_vars())
511-
.map(|arg| {
512-
traits::Obligation::with_depth(
513-
tcx,
514-
cause.clone(),
515-
depth,
516-
param_env,
517-
ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(
518-
arg,
519-
))),
520-
)
521-
}),
522-
);
478+
// Make sure that projection args are WF.
479+
data.visit_with(self);
523480
}
524481

525482
fn require_sized(&mut self, subty: Ty<'tcx>, cause: traits::ObligationCauseCode<'tcx>) {

tests/ui/implied-bounds/from-trait-impl.stderr

+5-5
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@ LL | fn func1(foo: Foo<(&str,)>) {
77
= note: type must satisfy the static lifetime
88

99
error[E0310]: the parameter type `X` may not live long enough
10-
--> $DIR/from-trait-impl.rs:20:23
10+
--> $DIR/from-trait-impl.rs:20:9
1111
|
1212
LL | impl<X> TestTrait for [Foo<(X,)>; 1] {}
13-
| ^^^^^^^^^^^^^^
14-
| |
15-
| the parameter type `X` must be valid for the static lifetime...
16-
| ...so that the type `X` will meet its required lifetime bounds
13+
| ^^^^^^^^^
14+
| |
15+
| the parameter type `X` must be valid for the static lifetime...
16+
| ...so that the type `X` will meet its required lifetime bounds
1717
|
1818
help: consider adding an explicit lifetime bound
1919
|

tests/ui/inference/issue-80409.no-compat.stderr

-14
This file was deleted.

tests/ui/inference/issue-80409.rs

+1-16
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,3 @@
1-
// This should not pass, because `usize: Fsm` does not hold. However, it currently ICEs.
2-
3-
// ignore-tidy-linelength
4-
5-
//@ revisions: compat no-compat
6-
//@[compat] check-pass
7-
//@[no-compat] compile-flags: -Zno-implied-bounds-compat
8-
//@[no-compat] check-fail
9-
//@[no-compat] known-bug: #80409
10-
//@[no-compat] failure-status: 101
11-
//@[no-compat] normalize-stderr-test "delayed at.*" -> ""
12-
//@[no-compat] normalize-stderr-test "note: .*\n\n" -> ""
13-
//@[no-compat] normalize-stderr-test "thread 'rustc' panicked.*\n" -> ""
14-
//@[no-compat] normalize-stderr-test "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: "
15-
//@[no-compat] rustc-env:RUST_BACKTRACE=0
16-
171
#![allow(unreachable_code, unused)]
182

193
use std::marker::PhantomData;
@@ -34,6 +18,7 @@ struct FsmStateBuilder<TFsm> {
3418

3519
impl<TFsm> FsmStateBuilder<TFsm> {
3620
fn on_entry<TAction: Fn(&mut StateContext<'_, TFsm>)>(&self, _action: TAction) {}
21+
//~^ ERROR the trait bound `TFsm: Fsm` is not satisfied
3722
}
3823

3924
trait Fsm {

tests/ui/trait-bounds/unsized-bound.stderr

+40-40
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,18 @@
1+
error[E0277]: the size for values of type `A` cannot be known at compilation time
2+
--> $DIR/unsized-bound.rs:2:30
3+
|
4+
LL | impl<A, B> Trait<(A, B)> for (A, B) where A: ?Sized, B: ?Sized, {}
5+
| - ^^^^^^ doesn't have a size known at compile-time
6+
| |
7+
| this type parameter needs to be `Sized`
8+
|
9+
= note: only the last element of a tuple may have a dynamically sized type
10+
help: consider removing the `?Sized` bound to make the type parameter `Sized`
11+
|
12+
LL - impl<A, B> Trait<(A, B)> for (A, B) where A: ?Sized, B: ?Sized, {}
13+
LL + impl<A, B> Trait<(A, B)> for (A, B) where B: ?Sized, {}
14+
|
15+
116
error[E0277]: the size for values of type `B` cannot be known at compilation time
217
--> $DIR/unsized-bound.rs:2:30
318
|
@@ -23,18 +38,29 @@ LL | trait Trait<A: ?Sized> {}
2338
| ++++++++
2439

2540
error[E0277]: the size for values of type `A` cannot be known at compilation time
26-
--> $DIR/unsized-bound.rs:2:30
41+
--> $DIR/unsized-bound.rs:5:52
2742
|
28-
LL | impl<A, B> Trait<(A, B)> for (A, B) where A: ?Sized, B: ?Sized, {}
29-
| - ^^^^^^ doesn't have a size known at compile-time
30-
| |
31-
| this type parameter needs to be `Sized`
43+
LL | impl<A, B: ?Sized, C: ?Sized> Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {}
44+
| - this type parameter needs to be `Sized` ^^^^^^^^^ doesn't have a size known at compile-time
3245
|
3346
= note: only the last element of a tuple may have a dynamically sized type
3447
help: consider removing the `?Sized` bound to make the type parameter `Sized`
3548
|
36-
LL - impl<A, B> Trait<(A, B)> for (A, B) where A: ?Sized, B: ?Sized, {}
37-
LL + impl<A, B> Trait<(A, B)> for (A, B) where B: ?Sized, {}
49+
LL - impl<A, B: ?Sized, C: ?Sized> Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {}
50+
LL + impl<A, B: ?Sized, C: ?Sized> Trait<(A, B, C)> for (A, B, C) {}
51+
|
52+
53+
error[E0277]: the size for values of type `B` cannot be known at compilation time
54+
--> $DIR/unsized-bound.rs:5:52
55+
|
56+
LL | impl<A, B: ?Sized, C: ?Sized> Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {}
57+
| - this type parameter needs to be `Sized` ^^^^^^^^^ doesn't have a size known at compile-time
58+
|
59+
= note: only the last element of a tuple may have a dynamically sized type
60+
help: consider removing the `?Sized` bound to make the type parameter `Sized`
61+
|
62+
LL - impl<A, B: ?Sized, C: ?Sized> Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {}
63+
LL + impl<A, B, C: ?Sized> Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {}
3864
|
3965

4066
error[E0277]: the size for values of type `C` cannot be known at compilation time
@@ -62,29 +88,18 @@ LL | trait Trait<A: ?Sized> {}
6288
| ++++++++
6389

6490
error[E0277]: the size for values of type `A` cannot be known at compilation time
65-
--> $DIR/unsized-bound.rs:5:52
66-
|
67-
LL | impl<A, B: ?Sized, C: ?Sized> Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {}
68-
| - this type parameter needs to be `Sized` ^^^^^^^^^ doesn't have a size known at compile-time
69-
|
70-
= note: only the last element of a tuple may have a dynamically sized type
71-
help: consider removing the `?Sized` bound to make the type parameter `Sized`
72-
|
73-
LL - impl<A, B: ?Sized, C: ?Sized> Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {}
74-
LL + impl<A, B: ?Sized, C: ?Sized> Trait<(A, B, C)> for (A, B, C) {}
75-
|
76-
77-
error[E0277]: the size for values of type `B` cannot be known at compilation time
78-
--> $DIR/unsized-bound.rs:5:52
91+
--> $DIR/unsized-bound.rs:10:47
7992
|
80-
LL | impl<A, B: ?Sized, C: ?Sized> Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {}
81-
| - this type parameter needs to be `Sized` ^^^^^^^^^ doesn't have a size known at compile-time
93+
LL | impl<A: ?Sized, B: ?Sized> Trait2<(A, B)> for (A, B) {}
94+
| - ^^^^^^ doesn't have a size known at compile-time
95+
| |
96+
| this type parameter needs to be `Sized`
8297
|
8398
= note: only the last element of a tuple may have a dynamically sized type
8499
help: consider removing the `?Sized` bound to make the type parameter `Sized`
85100
|
86-
LL - impl<A, B: ?Sized, C: ?Sized> Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {}
87-
LL + impl<A, B, C: ?Sized> Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {}
101+
LL - impl<A: ?Sized, B: ?Sized> Trait2<(A, B)> for (A, B) {}
102+
LL + impl<A, B: ?Sized> Trait2<(A, B)> for (A, B) {}
88103
|
89104

90105
error[E0277]: the size for values of type `B` cannot be known at compilation time
@@ -111,21 +126,6 @@ help: consider relaxing the implicit `Sized` restriction
111126
LL | trait Trait2<A: ?Sized> {}
112127
| ++++++++
113128

114-
error[E0277]: the size for values of type `A` cannot be known at compilation time
115-
--> $DIR/unsized-bound.rs:10:47
116-
|
117-
LL | impl<A: ?Sized, B: ?Sized> Trait2<(A, B)> for (A, B) {}
118-
| - ^^^^^^ doesn't have a size known at compile-time
119-
| |
120-
| this type parameter needs to be `Sized`
121-
|
122-
= note: only the last element of a tuple may have a dynamically sized type
123-
help: consider removing the `?Sized` bound to make the type parameter `Sized`
124-
|
125-
LL - impl<A: ?Sized, B: ?Sized> Trait2<(A, B)> for (A, B) {}
126-
LL + impl<A, B: ?Sized> Trait2<(A, B)> for (A, B) {}
127-
|
128-
129129
error[E0277]: the size for values of type `A` cannot be known at compilation time
130130
--> $DIR/unsized-bound.rs:14:23
131131
|

tests/ui/traits/copy-impl-cannot-normalize.stderr

+6-8
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,16 @@ error[E0277]: the trait bound `T: TraitFoo` is not satisfied
22
--> $DIR/copy-impl-cannot-normalize.rs:22:18
33
|
44
LL | impl<T> Copy for Foo<T> {}
5-
| ^^^^^^ the trait `TraitFoo` is not implemented for `T`, which is required by `Foo<T>: Clone`
5+
| ^^^^^^ the trait `TraitFoo` is not implemented for `T`
66
|
7-
note: required for `Foo<T>` to implement `Clone`
8-
--> $DIR/copy-impl-cannot-normalize.rs:12:9
7+
note: required by a bound in `Foo`
8+
--> $DIR/copy-impl-cannot-normalize.rs:7:8
99
|
10-
LL | impl<T> Clone for Foo<T>
11-
| ^^^^^ ^^^^^^
10+
LL | struct Foo<T>
11+
| --- required by a bound in this struct
1212
LL | where
1313
LL | T: TraitFoo,
14-
| -------- unsatisfied trait bound introduced here
15-
note: required by a bound in `Copy`
16-
--> $SRC_DIR/core/src/marker.rs:LL:COL
14+
| ^^^^^^^^ required by this bound in `Foo`
1715
help: consider restricting type parameter `T`
1816
|
1917
LL | impl<T: TraitFoo> Copy for Foo<T> {}

tests/ui/traits/next-solver/normalize/normalize-param-env-2.stderr

+1-7
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,6 @@ error[E0275]: overflow evaluating the requirement `<() as A<T>>::Assoc: A<T>`
1919
LL | Self::Assoc: A<T>,
2020
| ^^^^
2121

22-
error[E0275]: overflow evaluating the requirement `<() as A<T>>::Assoc well-formed`
23-
--> $DIR/normalize-param-env-2.rs:24:22
24-
|
25-
LL | Self::Assoc: A<T>,
26-
| ^^^^
27-
2822
error[E0275]: overflow evaluating the requirement `(): A<T>`
2923
--> $DIR/normalize-param-env-2.rs:27:10
3024
|
@@ -46,6 +40,6 @@ LL | where
4640
LL | Self::Assoc: A<T>,
4741
| ^^^^ required by this bound in `A::f`
4842

49-
error: aborting due to 5 previous errors
43+
error: aborting due to 4 previous errors
5044

5145
For more information about this error, try `rustc --explain E0275`.

tests/ui/traits/next-solver/normalize/normalize-param-env-4.next.stderr

+1-7
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,6 @@ error[E0275]: overflow evaluating the requirement `<T as Trait>::Assoc: Trait`
44
LL | <T as Trait>::Assoc: Trait,
55
| ^^^^^
66

7-
error[E0275]: overflow evaluating the requirement `<T as Trait>::Assoc well-formed`
8-
--> $DIR/normalize-param-env-4.rs:19:26
9-
|
10-
LL | <T as Trait>::Assoc: Trait,
11-
| ^^^^^
12-
137
error[E0275]: overflow evaluating the requirement `T: Trait`
148
--> $DIR/normalize-param-env-4.rs:32:19
159
|
@@ -22,6 +16,6 @@ note: required by a bound in `impls_trait`
2216
LL | fn impls_trait<T: Trait>() {}
2317
| ^^^^^ required by this bound in `impls_trait`
2418

25-
error: aborting due to 3 previous errors
19+
error: aborting due to 2 previous errors
2620

2721
For more information about this error, try `rustc --explain E0275`.

0 commit comments

Comments
 (0)