Skip to content

Commit

Permalink
Deny capturing late-bound ty/ct params in nested opaques
Browse files Browse the repository at this point in the history
  • Loading branch information
compiler-errors committed Nov 10, 2024
1 parent 58abbaf commit 8d871b7
Show file tree
Hide file tree
Showing 8 changed files with 48 additions and 35 deletions.
37 changes: 27 additions & 10 deletions compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ enum Scope<'a> {
LateBoundary {
s: ScopeRef<'a>,
what: &'static str,
deny_late_regions: bool,
},

Root {
Expand Down Expand Up @@ -234,9 +235,11 @@ impl<'a> fmt::Debug for TruncatedScopeDebug<'a> {
.field("s", &"..")
.finish(),
Scope::TraitRefBoundary { s: _ } => f.debug_struct("TraitRefBoundary").finish(),
Scope::LateBoundary { s: _, what } => {
f.debug_struct("LateBoundary").field("what", what).finish()
}
Scope::LateBoundary { s: _, what, deny_late_regions } => f
.debug_struct("LateBoundary")
.field("what", what)
.field("deny_late_regions", deny_late_regions)
.finish(),
Scope::Root { opt_parent_item } => {
f.debug_struct("Root").field("opt_parent_item", &opt_parent_item).finish()
}
Expand Down Expand Up @@ -630,7 +633,16 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
let scope = Scope::Opaque { captures: &captures, def_id: opaque.def_id, s: self.scope };
self.with(scope, |this| {
let scope = Scope::TraitRefBoundary { s: this.scope };
this.with(scope, |this| intravisit::walk_opaque_ty(this, opaque))
this.with(scope, |this| {
let scope = Scope::LateBoundary {
s: this.scope,
what: "nested `impl Trait`",
// We can capture late-bound regions; we just don't duplicate
// lifetime or const params, so we can't allow those.
deny_late_regions: false,
};
this.with(scope, |this| intravisit::walk_opaque_ty(this, opaque))
})
});

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

fn visit_anon_const(&mut self, c: &'tcx hir::AnonConst) {
self.with(Scope::LateBoundary { s: self.scope, what: "constant" }, |this| {
intravisit::walk_anon_const(this, c);
});
self.with(
Scope::LateBoundary { s: self.scope, what: "constant", deny_late_regions: true },
|this| {
intravisit::walk_anon_const(this, c);
},
);
}

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

Scope::LateBoundary { s, what } => {
crossed_late_boundary = Some(what);
Scope::LateBoundary { s, what, deny_late_regions } => {
if deny_late_regions {
crossed_late_boundary = Some(what);
}
scope = s;
}
}
Expand Down Expand Up @@ -1498,7 +1515,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
scope = s;
}

Scope::LateBoundary { s, what } => {
Scope::LateBoundary { s, what, deny_late_regions: _ } => {
crossed_late_boundary = Some(what);
scope = s;
}
Expand Down
4 changes: 0 additions & 4 deletions tests/crashes/131535.rs

This file was deleted.

7 changes: 0 additions & 7 deletions tests/crashes/131637.rs

This file was deleted.

9 changes: 0 additions & 9 deletions tests/crashes/132530.rs

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ fn produce() -> impl for<T> Trait<(), Assoc = impl Trait<T>> {
//~^ ERROR associated type `Assoc` not found for `Trait`
//~| ERROR associated type `Assoc` not found for `Trait`
//~| the trait bound `{integer}: Trait<()>` is not satisfied
//~| ERROR cannot capture late-bound type parameter in nested `impl Trait`
16
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
error: cannot capture late-bound type parameter in nested `impl Trait`
--> $DIR/non-lifetime-binder-in-constraint.rs:6:58
|
LL | fn produce() -> impl for<T> Trait<(), Assoc = impl Trait<T>> {
| - parameter defined here ^

error[E0220]: associated type `Assoc` not found for `Trait`
--> $DIR/non-lifetime-binder-in-constraint.rs:6:39
|
Expand Down Expand Up @@ -27,7 +33,7 @@ help: this trait has no implementations, consider adding one
LL | trait Trait<T: ?Sized> {}
| ^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to 3 previous errors
error: aborting due to 4 previous errors

Some errors have detailed explanations: E0220, E0277.
For more information about an error, try `rustc --explain E0220`.
3 changes: 2 additions & 1 deletion tests/ui/type-alias-impl-trait/non-lifetime-binder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ trait Trait<T> {}

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

fn main() {}
14 changes: 11 additions & 3 deletions tests/ui/type-alias-impl-trait/non-lifetime-binder.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,27 @@ LL | fn f() -> impl for<T> Trait<impl Trait<T>> {}
| | nested `impl Trait` here
| outer `impl Trait`

error[E0277]: the trait bound `(): Trait<impl Trait<T>>` is not satisfied
error: cannot capture late-bound type parameter in nested `impl Trait`
--> $DIR/non-lifetime-binder.rs:6:40
|
LL | fn f() -> impl for<T> Trait<impl Trait<T>> {}
| - ^
| |
| parameter defined here

error[E0277]: the trait bound `(): Trait<impl Trait<{type error}>>` is not satisfied
--> $DIR/non-lifetime-binder.rs:6:11
|
LL | fn f() -> impl for<T> Trait<impl Trait<T>> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait<impl Trait<T>>` is not implemented for `()`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait<impl Trait<{type error}>>` is not implemented for `()`
|
help: this trait has no implementations, consider adding one
--> $DIR/non-lifetime-binder.rs:4:1
|
LL | trait Trait<T> {}
| ^^^^^^^^^^^^^^

error: aborting due to 2 previous errors
error: aborting due to 3 previous errors

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

0 comments on commit 8d871b7

Please sign in to comment.