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

Sign up
Appearance settings

Commit 747075d

Browse files
committed
Auto merge of #98462 - cjgillot:no-apit-hrtb-beta, r=Mark-Simulacrum
[beta] Fail gracefully when encountering an HRTB in APIT. Backport of #97683 The diagnostic is a bit worse, but still better than an ICE. r? `@ehuss`
2 parents d8ffc1f + a081507 commit 747075d

File tree

4 files changed

+82
-8
lines changed

4 files changed

+82
-8
lines changed

‎compiler/rustc_hir/src/hir.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -721,7 +721,7 @@ impl<'hir> WherePredicate<'hir> {
721721
}
722722
}
723723

724-
#[derive(Debug, HashStable_Generic, PartialEq, Eq)]
724+
#[derive(Copy,Clone,Debug, HashStable_Generic, PartialEq, Eq)]
725725
pub enum PredicateOrigin {
726726
WhereClause,
727727
GenericParam,

‎compiler/rustc_resolve/src/late/lifetimes.rs

Lines changed: 65 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,13 @@ enum Scope<'a> {
230230
/// In some cases not allowing late bounds allows us to avoid ICEs.
231231
/// This is almost ways set to true.
232232
allow_late_bound: bool,
233+
234+
/// If this binder comes from a where clause, specify how it was created.
235+
/// This is used to diagnose inaccessible lifetimes in APIT:
236+
/// ```ignore (illustrative)
237+
/// fn foo(x: impl for<'a> Trait<'a, Assoc = impl Copy + 'a>) {}
238+
/// ```
239+
where_bound_origin: Option<hir::PredicateOrigin>,
233240
},
234241

235242
/// Lifetimes introduced by a fn are scoped to the call-site for that fn,
@@ -301,8 +308,9 @@ impl<'a> fmt::Debug for TruncatedScopeDebug<'a> {
301308
opaque_type_parent,
302309
scope_type,
303310
hir_id,
304-
s: _,
305311
allow_late_bound,
312+
where_bound_origin,
313+
s: _,
306314
} => f
307315
.debug_struct("Binder")
308316
.field("lifetimes", lifetimes)
@@ -311,8 +319,9 @@ impl<'a> fmt::Debug for TruncatedScopeDebug<'a> {
311319
.field("opaque_type_parent", opaque_type_parent)
312320
.field("scope_type", scope_type)
313321
.field("hir_id", hir_id)
314-
.field("s", &"..")
315322
.field("allow_late_bound", allow_late_bound)
323+
.field("where_bound_origin", where_bound_origin)
324+
.field("s", &"..")
316325
.finish(),
317326
Scope::Body { id, s: _ } => {
318327
f.debug_struct("Body").field("id", id).field("s", &"..").finish()
@@ -701,6 +710,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
701710
opaque_type_parent: false,
702711
scope_type: BinderScopeType::Normal,
703712
allow_late_bound: true,
713+
where_bound_origin: None,
704714
};
705715
self.with(scope, move |_old_scope, this| {
706716
intravisit::walk_fn(this, fk, fd, b, s, hir_id)
@@ -829,6 +839,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
829839
scope_type: BinderScopeType::Normal,
830840
s: ROOT_SCOPE,
831841
allow_late_bound: false,
842+
where_bound_origin: None,
832843
};
833844
self.with(scope, |old_scope, this| {
834845
this.check_lifetime_params(old_scope, &generics.params);
@@ -896,6 +907,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
896907
opaque_type_parent: false,
897908
scope_type: BinderScopeType::Normal,
898909
allow_late_bound: true,
910+
where_bound_origin: None,
899911
};
900912
self.with(scope, |old_scope, this| {
901913
// a bare fn has no bounds, so everything
@@ -1091,6 +1103,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
10911103
opaque_type_parent: false,
10921104
scope_type: BinderScopeType::Normal,
10931105
allow_late_bound: false,
1106+
where_bound_origin: None,
10941107
};
10951108
this.with(scope, |_old_scope, this| {
10961109
this.visit_generics(generics);
@@ -1112,6 +1125,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
11121125
opaque_type_parent: false,
11131126
scope_type: BinderScopeType::Normal,
11141127
allow_late_bound: false,
1128+
where_bound_origin: None,
11151129
};
11161130
self.with(scope, |_old_scope, this| {
11171131
let scope = Scope::TraitRefBoundary { s: this.scope };
@@ -1172,6 +1186,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
11721186
opaque_type_parent: true,
11731187
scope_type: BinderScopeType::Normal,
11741188
allow_late_bound: false,
1189+
where_bound_origin: None,
11751190
};
11761191
self.with(scope, |old_scope, this| {
11771192
this.check_lifetime_params(old_scope, &generics.params);
@@ -1242,6 +1257,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
12421257
opaque_type_parent: true,
12431258
scope_type: BinderScopeType::Normal,
12441259
allow_late_bound: true,
1260+
where_bound_origin: None,
12451261
};
12461262
self.with(scope, |old_scope, this| {
12471263
this.check_lifetime_params(old_scope, &generics.params);
@@ -1356,6 +1372,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
13561372
ref bounded_ty,
13571373
bounds,
13581374
ref bound_generic_params,
1375+
origin,
13591376
..
13601377
}) => {
13611378
let (lifetimes, binders): (FxIndexMap<hir::ParamName, Region>, Vec<_>) =
@@ -1387,6 +1404,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
13871404
opaque_type_parent: false,
13881405
scope_type: BinderScopeType::Normal,
13891406
allow_late_bound: true,
1407+
where_bound_origin: Some(origin),
13901408
};
13911409
this.with(scope, |old_scope, this| {
13921410
this.check_lifetime_params(old_scope, &bound_generic_params);
@@ -1461,6 +1479,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
14611479
opaque_type_parent: false,
14621480
scope_type,
14631481
allow_late_bound: true,
1482+
where_bound_origin: None,
14641483
};
14651484
self.with(scope, |_, this| {
14661485
intravisit::walk_param_bound(this, bound);
@@ -1514,6 +1533,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
15141533
opaque_type_parent: false,
15151534
scope_type,
15161535
allow_late_bound: true,
1536+
where_bound_origin: None,
15171537
};
15181538
self.with(scope, |old_scope, this| {
15191539
this.check_lifetime_params(old_scope, &trait_ref.bound_generic_params);
@@ -2207,6 +2227,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
22072227
track_lifetime_uses: false,
22082228
scope_type: BinderScopeType::Normal,
22092229
allow_late_bound: true,
2230+
where_bound_origin: None,
22102231
};
22112232
self.with(scope, move |old_scope, this| {
22122233
this.check_lifetime_params(old_scope, &generics.params);
@@ -2321,12 +2342,49 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
23212342
}
23222343

23232344
self.insert_lifetime(lifetime_ref, def);
2324-
} else {
2325-
self.tcx.sess.delay_span_bug(
2326-
lifetime_ref.span,
2327-
&format!("Could not resolve {:?} in scope {:#?}", lifetime_ref, self.scope,),
2328-
);
2345+
return;
2346+
}
2347+
2348+
// We may fail to resolve higher-ranked lifetimes that are mentionned by APIT.
2349+
// AST-based resolution does not care for impl-trait desugaring, which are the
2350+
// responibility of lowering. This may create a mismatch between the resolution
2351+
// AST found (`region_def_id`) which points to HRTB, and what HIR allows.
2352+
// ```
2353+
// fn foo(x: impl for<'a> Trait<'a, Assoc = impl Copy + 'a>) {}
2354+
// ```
2355+
//
2356+
// In such case, walk back the binders to diagnose it properly.
2357+
let mut scope = self.scope;
2358+
loop {
2359+
match *scope {
2360+
Scope::Binder {
2361+
where_bound_origin: Some(hir::PredicateOrigin::ImplTrait), ..
2362+
} => {
2363+
self.tcx
2364+
.sess
2365+
.struct_span_err(
2366+
lifetime_ref.span,
2367+
"`impl Trait` can only mention lifetimes bound at the fn or impl level",
2368+
)
2369+
.emit();
2370+
return;
2371+
}
2372+
Scope::Root => break,
2373+
Scope::Binder { s, .. }
2374+
| Scope::Body { s, .. }
2375+
| Scope::Elision { s, .. }
2376+
| Scope::ObjectLifetimeDefault { s, .. }
2377+
| Scope::Supertrait { s, .. }
2378+
| Scope::TraitRefBoundary { s, .. } => {
2379+
scope = s;
2380+
}
2381+
}
23292382
}
2383+
2384+
self.tcx.sess.delay_span_bug(
2385+
lifetime_ref.span,
2386+
&format!("Could not resolve {:?} in scope {:#?}", lifetime_ref, self.scope,),
2387+
);
23302388
}
23312389

23322390
fn visit_segment_args(
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
trait Trait<'a> {
2+
type Assoc;
3+
}
4+
5+
fn test_argument_position(x: impl for<'a> Trait<'a, Assoc = impl Copy + 'a>) {}
6+
//~^ ERROR `impl Trait` can only mention lifetimes bound at the fn or impl level
7+
8+
fn main() {}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: `impl Trait` can only mention lifetimes bound at the fn or impl level
2+
--> $DIR/universal_wrong_hrtb.rs:5:73
3+
|
4+
LL | fn test_argument_position(x: impl for<'a> Trait<'a, Assoc = impl Copy + 'a>) {}
5+
| ^^
6+
7+
error: aborting due to previous error
8+

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /