Skip to content

Commit d356232

Browse files
committed
Auto merge of #155020 - fmease:no-obj-lt-def-in-bodies, r=<try>
[IGNORE] Abolish trait object lifetime defaults in bodies
2 parents 9004856 + c973925 commit d356232

5 files changed

Lines changed: 112 additions & 53 deletions

File tree

compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs

Lines changed: 59 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,29 @@ enum Scope<'a, 'tcx> {
168168
}
169169

170170
impl<'a, 'tcx> Scope<'a, 'tcx> {
171+
// FIXME(fmease): This is called in a bunch of places that are probably relatively hot.
172+
// Consider tracking this flag as a field in `BoundVarContext` (to be
173+
// updated in `visit_nested_body` but that's a bit ewww)
174+
fn in_body(&self) -> bool {
175+
let mut scope = self;
176+
loop {
177+
match *scope {
178+
Scope::Root { .. } => return false,
179+
180+
Scope::Body { .. } => return true,
181+
182+
Scope::Binder { s, .. }
183+
| Scope::ObjectLifetimeDefault { s, .. }
184+
| Scope::Opaque { s, .. }
185+
| Scope::Supertrait { s, .. }
186+
| Scope::TraitRefBoundary { s, .. }
187+
| Scope::LateBoundary { s, .. } => {
188+
scope = s;
189+
}
190+
}
191+
}
192+
}
193+
171194
// A helper for debugging scopes without printing parent scopes
172195
fn debug_truncated(&self) -> impl fmt::Debug {
173196
fmt::from_fn(move |f| match self {
@@ -809,11 +832,12 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
809832
}
810833
hir::TyKind::Ref(lifetime_ref, ref mt) => {
811834
self.visit_lifetime(lifetime_ref);
812-
let scope = Scope::ObjectLifetimeDefault {
813-
lifetime: self.rbv.defs.get(&lifetime_ref.hir_id.local_id).cloned(),
814-
s: self.scope,
815-
};
816-
self.with(scope, |this| this.visit_ty_unambig(mt.ty));
835+
836+
// NOTE(fmease): Likely hot.
837+
self.maybe_with_object_lifetime_default(
838+
|this| this.rbv.defs.get(&lifetime_ref.hir_id.local_id).cloned(),
839+
|this| this.visit_ty_unambig(mt.ty),
840+
);
817841
}
818842
hir::TyKind::TraitAscription(bounds) => {
819843
let scope = Scope::TraitRefBoundary { s: self.scope };
@@ -1121,6 +1145,21 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
11211145
*self.opaque_capture_errors.borrow_mut() = this.opaque_capture_errors.into_inner();
11221146
}
11231147

1148+
// FIXME(fmease): Temporary.
1149+
fn maybe_with_object_lifetime_default<L, F>(&mut self, lifetime: L, f: F)
1150+
where
1151+
L: FnOnce(&mut Self) -> Option<ResolvedArg>,
1152+
F: for<'b> FnOnce(&mut BoundVarContext<'b, 'tcx>),
1153+
{
1154+
if !self.scope.in_body() {
1155+
let lifetime = lifetime(self);
1156+
let scope = Scope::ObjectLifetimeDefault { lifetime, s: self.scope };
1157+
self.with(scope, f)
1158+
} else {
1159+
f(self);
1160+
}
1161+
}
1162+
11241163
fn record_late_bound_vars(&mut self, hir_id: HirId, binder: Vec<ty::BoundVariableKind<'tcx>>) {
11251164
if let Some(old) = self.rbv.late_bound_vars.insert(hir_id.local_id, binder) {
11261165
bug!(
@@ -1722,25 +1761,9 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
17221761
// vector like `['x, 'static]`. Note that the vector only
17231762
// includes type parameters.
17241763
let object_lifetime_defaults = type_def_id.map_or_else(Vec::new, |def_id| {
1725-
let in_body = {
1726-
let mut scope = self.scope;
1727-
loop {
1728-
match *scope {
1729-
Scope::Root { .. } => break false,
1730-
1731-
Scope::Body { .. } => break true,
1732-
1733-
Scope::Binder { s, .. }
1734-
| Scope::ObjectLifetimeDefault { s, .. }
1735-
| Scope::Opaque { s, .. }
1736-
| Scope::Supertrait { s, .. }
1737-
| Scope::TraitRefBoundary { s, .. }
1738-
| Scope::LateBoundary { s, .. } => {
1739-
scope = s;
1740-
}
1741-
}
1742-
}
1743-
};
1764+
if self.scope.in_body() {
1765+
return Vec::new();
1766+
}
17441767

17451768
let rbv = &self.rbv;
17461769
let generics = self.tcx.generics_of(def_id);
@@ -1749,14 +1772,9 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
17491772
debug_assert_eq!(generics.parent_count, 0);
17501773

17511774
let set_to_region = |set: ObjectLifetimeDefault| match set {
1752-
ObjectLifetimeDefault::Empty => {
1753-
if in_body {
1754-
None
1755-
} else {
1756-
Some(ResolvedArg::StaticLifetime)
1757-
}
1775+
ObjectLifetimeDefault::Empty | ObjectLifetimeDefault::Static => {
1776+
Some(ResolvedArg::StaticLifetime)
17581777
}
1759-
ObjectLifetimeDefault::Static => Some(ResolvedArg::StaticLifetime),
17601778
ObjectLifetimeDefault::Param(param_def_id) => {
17611779
// This index can be used with `generic_args` since `parent_count == 0`.
17621780
let index = generics.param_def_id_to_index[&param_def_id] as usize;
@@ -1844,13 +1862,8 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
18441862
// Resolve lifetimes found in the bindings, so either in the type `XX` in `Item = XX` or
18451863
// in the trait ref `YY<...>` in `Item: YY<...>`.
18461864
for constraint in generic_args.constraints {
1847-
let scope = Scope::ObjectLifetimeDefault {
1848-
lifetime: if has_lifetime_parameter {
1849-
None
1850-
} else {
1851-
Some(ResolvedArg::StaticLifetime)
1852-
},
1853-
s: self.scope,
1865+
let lifetime = |_: &mut _| {
1866+
if has_lifetime_parameter { None } else { Some(ResolvedArg::StaticLifetime) }
18541867
};
18551868
// If the args are parenthesized, then this must be `feature(return_type_notation)`.
18561869
// In that case, introduce a binder over all of the function's early and late bound vars.
@@ -1892,7 +1905,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
18921905
.span_delayed_bug(constraint.ident.span, "bad return type notation here");
18931906
vec![]
18941907
};
1895-
self.with(scope, |this| {
1908+
self.maybe_with_object_lifetime_default(lifetime, |this| {
18961909
let scope = Scope::Supertrait { bound_vars, s: this.scope };
18971910
this.with(scope, |this| {
18981911
let (bound_vars, _) = this.poly_trait_ref_binder_info();
@@ -1908,15 +1921,17 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
19081921
ty::AssocTag::Type,
19091922
)
19101923
.map(|(bound_vars, _)| bound_vars);
1911-
self.with(scope, |this| {
1924+
self.maybe_with_object_lifetime_default(lifetime, |this| {
19121925
let scope = Scope::Supertrait {
19131926
bound_vars: bound_vars.unwrap_or_default(),
19141927
s: this.scope,
19151928
};
19161929
this.with(scope, |this| this.visit_assoc_item_constraint(constraint));
19171930
});
19181931
} else {
1919-
self.with(scope, |this| this.visit_assoc_item_constraint(constraint));
1932+
self.maybe_with_object_lifetime_default(lifetime, |this| {
1933+
this.visit_assoc_item_constraint(constraint)
1934+
});
19201935
}
19211936
}
19221937
}
@@ -1995,11 +2010,8 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
19952010
output: Option<&'tcx hir::Ty<'tcx>>,
19962011
in_closure: bool,
19972012
) {
1998-
self.with(
1999-
Scope::ObjectLifetimeDefault {
2000-
lifetime: Some(ResolvedArg::StaticLifetime),
2001-
s: self.scope,
2002-
},
2013+
self.maybe_with_object_lifetime_default(
2014+
|_| Some(ResolvedArg::StaticLifetime),
20032015
|this| {
20042016
for input in inputs {
20052017
this.visit_ty_unambig(input);
@@ -2009,6 +2021,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
20092021
}
20102022
},
20112023
);
2024+
20122025
if in_closure && let Some(output) = output {
20132026
self.visit_ty_unambig(output);
20142027
}

compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -443,20 +443,23 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
443443
let existential_predicates = tcx.mk_poly_existential_predicates(&v);
444444

445445
// Use explicitly-specified region bound, unless the bound is missing.
446+
// FIXME(fmease): Simplify logic
446447
let region_bound = if !lifetime.is_elided() {
447448
self.lower_lifetime(lifetime, RegionInferReason::ExplicitObjectLifetime)
449+
} else if self.infcx().is_some() {
450+
self.re_infer(span, RegionInferReason::ExplicitObjectLifetime)
448451
} else {
449452
self.compute_object_lifetime_bound(span, existential_predicates).unwrap_or_else(|| {
453+
let reason = match lifetime.kind {
454+
hir::LifetimeKind::ImplicitObjectLifetimeDefault => {
455+
RegionInferReason::ObjectLifetimeDefault(span.shrink_to_hi())
456+
}
457+
_ => RegionInferReason::ExplicitObjectLifetime,
458+
};
450459
// Curiously, we prefer object lifetime default for `+ '_`...
451460
if tcx.named_bound_var(lifetime.hir_id).is_some() {
452-
self.lower_lifetime(lifetime, RegionInferReason::ExplicitObjectLifetime)
461+
self.lower_lifetime(lifetime, reason)
453462
} else {
454-
let reason =
455-
if let hir::LifetimeKind::ImplicitObjectLifetimeDefault = lifetime.kind {
456-
RegionInferReason::ObjectLifetimeDefault(span.shrink_to_hi())
457-
} else {
458-
RegionInferReason::ExplicitObjectLifetime
459-
};
460463
self.re_infer(span, reason)
461464
}
462465
})
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//@ check-pass
2+
3+
trait Trait {}
4+
impl Trait for () {}
5+
6+
fn scope<'a>(arg: &'a ()) {
7+
// NOTE: Use to be elab'ed to `&'a (dyn Trait + 'a)`.
8+
// Now elabs to `&'a (dyn Trait + '_)`.
9+
let dt: &'a dyn Trait = arg;
10+
let _: &(dyn Trait + 'static) = dt;
11+
}
12+
13+
fn main() {}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
//@ check-pass
2+
3+
trait Double<'a, 'b>: 'a + 'b {}
4+
impl Double<'_, '_> for () {}
5+
6+
fn scope<'a, 'b>() {
7+
// NOTE: These used to get rejected due to "ambiguity".
8+
let _: Box<dyn Double<'a, 'b>> = Box::new(());
9+
let _: Box<dyn Double<'a, 'b> + '_> = Box::new(());
10+
}
11+
12+
fn main() {}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//@ check-pass
2+
3+
trait Trait<'a>: 'a {}
4+
impl Trait<'_> for () {}
5+
6+
fn scope0<'a>() {
7+
// NOTE: Used to be elab'ed to `dyn Trait<'a> + 'a`, now it's `dyn Trait<'a> + '_`.
8+
let bx: Box<dyn Trait<'a>> = Box::new(());
9+
let _: Box<dyn Trait<'a> + 'static> = bx;
10+
}
11+
12+
fn scope1<'a>() {
13+
// NOTE: Used to be elab'ed to `dyn Trait<'a> + 'a`, now it's `dyn Trait<'a> + '_`.
14+
let bx: Box<dyn Trait<'a> + '_> = Box::new(());
15+
let _: Box<dyn Trait<'a> + 'static> = bx;
16+
}
17+
18+
fn main() {}

0 commit comments

Comments
 (0)