Skip to content

Commit 8d871b7

Browse files
Deny capturing late-bound ty/ct params in nested opaques
1 parent 58abbaf commit 8d871b7

File tree

8 files changed

+48
-35
lines changed

8 files changed

+48
-35
lines changed

compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs

+27-10
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ enum Scope<'a> {
177177
LateBoundary {
178178
s: ScopeRef<'a>,
179179
what: &'static str,
180+
deny_late_regions: bool,
180181
},
181182

182183
Root {
@@ -234,9 +235,11 @@ impl<'a> fmt::Debug for TruncatedScopeDebug<'a> {
234235
.field("s", &"..")
235236
.finish(),
236237
Scope::TraitRefBoundary { s: _ } => f.debug_struct("TraitRefBoundary").finish(),
237-
Scope::LateBoundary { s: _, what } => {
238-
f.debug_struct("LateBoundary").field("what", what).finish()
239-
}
238+
Scope::LateBoundary { s: _, what, deny_late_regions } => f
239+
.debug_struct("LateBoundary")
240+
.field("what", what)
241+
.field("deny_late_regions", deny_late_regions)
242+
.finish(),
240243
Scope::Root { opt_parent_item } => {
241244
f.debug_struct("Root").field("opt_parent_item", &opt_parent_item).finish()
242245
}
@@ -630,7 +633,16 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
630633
let scope = Scope::Opaque { captures: &captures, def_id: opaque.def_id, s: self.scope };
631634
self.with(scope, |this| {
632635
let scope = Scope::TraitRefBoundary { s: this.scope };
633-
this.with(scope, |this| intravisit::walk_opaque_ty(this, opaque))
636+
this.with(scope, |this| {
637+
let scope = Scope::LateBoundary {
638+
s: this.scope,
639+
what: "nested `impl Trait`",
640+
// We can capture late-bound regions; we just don't duplicate
641+
// lifetime or const params, so we can't allow those.
642+
deny_late_regions: false,
643+
};
644+
this.with(scope, |this| intravisit::walk_opaque_ty(this, opaque))
645+
})
634646
});
635647

636648
let captures = captures.into_inner().into_iter().collect();
@@ -987,9 +999,12 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
987999
}
9881000

9891001
fn visit_anon_const(&mut self, c: &'tcx hir::AnonConst) {
990-
self.with(Scope::LateBoundary { s: self.scope, what: "constant" }, |this| {
991-
intravisit::walk_anon_const(this, c);
992-
});
1002+
self.with(
1003+
Scope::LateBoundary { s: self.scope, what: "constant", deny_late_regions: true },
1004+
|this| {
1005+
intravisit::walk_anon_const(this, c);
1006+
},
1007+
);
9931008
}
9941009

9951010
fn visit_generic_param(&mut self, p: &'tcx GenericParam<'tcx>) {
@@ -1281,8 +1296,10 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
12811296
scope = s;
12821297
}
12831298

1284-
Scope::LateBoundary { s, what } => {
1285-
crossed_late_boundary = Some(what);
1299+
Scope::LateBoundary { s, what, deny_late_regions } => {
1300+
if deny_late_regions {
1301+
crossed_late_boundary = Some(what);
1302+
}
12861303
scope = s;
12871304
}
12881305
}
@@ -1498,7 +1515,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
14981515
scope = s;
14991516
}
15001517

1501-
Scope::LateBoundary { s, what } => {
1518+
Scope::LateBoundary { s, what, deny_late_regions: _ } => {
15021519
crossed_late_boundary = Some(what);
15031520
scope = s;
15041521
}

tests/crashes/131535.rs

-4
This file was deleted.

tests/crashes/131637.rs

-7
This file was deleted.

tests/crashes/132530.rs

-9
This file was deleted.

tests/ui/type-alias-impl-trait/non-lifetime-binder-in-constraint.rs

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ fn produce() -> impl for<T> Trait<(), Assoc = impl Trait<T>> {
77
//~^ ERROR associated type `Assoc` not found for `Trait`
88
//~| ERROR associated type `Assoc` not found for `Trait`
99
//~| the trait bound `{integer}: Trait<()>` is not satisfied
10+
//~| ERROR cannot capture late-bound type parameter in nested `impl Trait`
1011
16
1112
}
1213

tests/ui/type-alias-impl-trait/non-lifetime-binder-in-constraint.stderr

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
error: cannot capture late-bound type parameter in nested `impl Trait`
2+
--> $DIR/non-lifetime-binder-in-constraint.rs:6:58
3+
|
4+
LL | fn produce() -> impl for<T> Trait<(), Assoc = impl Trait<T>> {
5+
| - parameter defined here ^
6+
17
error[E0220]: associated type `Assoc` not found for `Trait`
28
--> $DIR/non-lifetime-binder-in-constraint.rs:6:39
39
|
@@ -27,7 +33,7 @@ help: this trait has no implementations, consider adding one
2733
LL | trait Trait<T: ?Sized> {}
2834
| ^^^^^^^^^^^^^^^^^^^^^^
2935

30-
error: aborting due to 3 previous errors
36+
error: aborting due to 4 previous errors
3137

3238
Some errors have detailed explanations: E0220, E0277.
3339
For more information about an error, try `rustc --explain E0220`.

tests/ui/type-alias-impl-trait/non-lifetime-binder.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ trait Trait<T> {}
55

66
fn f() -> impl for<T> Trait<impl Trait<T>> {}
77
//~^ ERROR nested `impl Trait` is not allowed
8-
//~| ERROR the trait bound `(): Trait<impl Trait<T>>` is not satisfied
8+
//~| ERROR the trait bound `(): Trait<impl Trait<{type error}>>` is not satisfied
9+
//~| ERROR cannot capture late-bound type parameter in nested `impl Trait`
910

1011
fn main() {}

tests/ui/type-alias-impl-trait/non-lifetime-binder.stderr

+11-3
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,27 @@ LL | fn f() -> impl for<T> Trait<impl Trait<T>> {}
77
| | nested `impl Trait` here
88
| outer `impl Trait`
99

10-
error[E0277]: the trait bound `(): Trait<impl Trait<T>>` is not satisfied
10+
error: cannot capture late-bound type parameter in nested `impl Trait`
11+
--> $DIR/non-lifetime-binder.rs:6:40
12+
|
13+
LL | fn f() -> impl for<T> Trait<impl Trait<T>> {}
14+
| - ^
15+
| |
16+
| parameter defined here
17+
18+
error[E0277]: the trait bound `(): Trait<impl Trait<{type error}>>` is not satisfied
1119
--> $DIR/non-lifetime-binder.rs:6:11
1220
|
1321
LL | fn f() -> impl for<T> Trait<impl Trait<T>> {}
14-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait<impl Trait<T>>` is not implemented for `()`
22+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait<impl Trait<{type error}>>` is not implemented for `()`
1523
|
1624
help: this trait has no implementations, consider adding one
1725
--> $DIR/non-lifetime-binder.rs:4:1
1826
|
1927
LL | trait Trait<T> {}
2028
| ^^^^^^^^^^^^^^
2129

22-
error: aborting due to 2 previous errors
30+
error: aborting due to 3 previous errors
2331

2432
Some errors have detailed explanations: E0277, E0666.
2533
For more information about an error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)