Skip to content

Commit 454784a

Browse files
committed
Auto merge of #104048 - cjgillot:split-lifetime, r=compiler-errors
Separate lifetime ident from lifetime resolution in HIR Drive-by: change how suggested generic args are computed. Fixes #103815 I recommend reviewing commit-by-commit.
2 parents df04d28 + 5de9c84 commit 454784a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+583
-437
lines changed

compiler/rustc_ast_lowering/src/expr.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -605,6 +605,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
605605
output,
606606
c_variadic: false,
607607
implicit_self: hir::ImplicitSelfKind::None,
608+
lifetime_elision_allowed: false,
608609
});
609610

610611
// Lower the argument pattern/ident. The ident is used again in the `.await` lowering.
@@ -917,7 +918,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
917918

918919
let bound_generic_params = self.lower_lifetime_binder(closure_id, generic_params);
919920
// Lower outside new scope to preserve `is_in_loop_condition`.
920-
let fn_decl = self.lower_fn_decl(decl, None, fn_decl_span, FnDeclKind::Closure, None);
921+
let fn_decl = self.lower_fn_decl(decl, closure_id, fn_decl_span, FnDeclKind::Closure, None);
921922

922923
let c = self.arena.alloc(hir::Closure {
923924
def_id: self.local_def_id(closure_id),
@@ -1027,7 +1028,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
10271028
// have to conserve the state of being inside a loop condition for the
10281029
// closure argument types.
10291030
let fn_decl =
1030-
self.lower_fn_decl(&outer_decl, None, fn_decl_span, FnDeclKind::Closure, None);
1031+
self.lower_fn_decl(&outer_decl, closure_id, fn_decl_span, FnDeclKind::Closure, None);
10311032

10321033
let c = self.arena.alloc(hir::Closure {
10331034
def_id: self.local_def_id(closure_id),

compiler/rustc_ast_lowering/src/index.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
303303
}
304304

305305
fn visit_lifetime(&mut self, lifetime: &'hir Lifetime) {
306-
self.insert(lifetime.span, lifetime.hir_id, Node::Lifetime(lifetime));
306+
self.insert(lifetime.ident.span, lifetime.hir_id, Node::Lifetime(lifetime));
307307
}
308308

309309
fn visit_variant(&mut self, v: &'hir Variant<'hir>) {

compiler/rustc_ast_lowering/src/item.rs

+4-5
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
274274
let mut itctx = ImplTraitContext::Universal;
275275
let (generics, decl) = this.lower_generics(generics, id, &mut itctx, |this| {
276276
let ret_id = asyncness.opt_return_id();
277-
this.lower_fn_decl(&decl, Some(id), *fn_sig_span, FnDeclKind::Fn, ret_id)
277+
this.lower_fn_decl(&decl, id, *fn_sig_span, FnDeclKind::Fn, ret_id)
278278
});
279279
let sig = hir::FnSig {
280280
decl,
@@ -659,7 +659,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
659659
// Disallow `impl Trait` in foreign items.
660660
this.lower_fn_decl(
661661
fdec,
662-
None,
662+
i.id,
663663
sig.span,
664664
FnDeclKind::ExternFn,
665665
None,
@@ -1247,7 +1247,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
12471247
let header = self.lower_fn_header(sig.header);
12481248
let mut itctx = ImplTraitContext::Universal;
12491249
let (generics, decl) = self.lower_generics(generics, id, &mut itctx, |this| {
1250-
this.lower_fn_decl(&sig.decl, Some(id), sig.span, kind, is_async)
1250+
this.lower_fn_decl(&sig.decl, id, sig.span, kind, is_async)
12511251
});
12521252
(generics, hir::FnSig { header, decl, span: self.lower_span(sig.span) })
12531253
}
@@ -1479,10 +1479,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
14791479
}))
14801480
}
14811481
GenericParamKind::Lifetime => {
1482-
let ident_span = self.lower_span(ident.span);
14831482
let ident = self.lower_ident(ident);
14841483
let lt_id = self.next_node_id();
1485-
let lifetime = self.new_named_lifetime(id, lt_id, ident_span, ident);
1484+
let lifetime = self.new_named_lifetime(id, lt_id, ident);
14861485
Some(hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate {
14871486
lifetime,
14881487
span,

compiler/rustc_ast_lowering/src/lib.rs

+51-66
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,14 @@ enum FnDeclKind {
327327
}
328328

329329
impl FnDeclKind {
330-
fn impl_trait_allowed(&self, tcx: TyCtxt<'_>) -> bool {
330+
fn param_impl_trait_allowed(&self) -> bool {
331+
match self {
332+
FnDeclKind::Fn | FnDeclKind::Inherent | FnDeclKind::Impl | FnDeclKind::Trait => true,
333+
_ => false,
334+
}
335+
}
336+
337+
fn return_impl_trait_allowed(&self, tcx: TyCtxt<'_>) -> bool {
331338
match self {
332339
FnDeclKind::Fn | FnDeclKind::Inherent => true,
333340
FnDeclKind::Impl if tcx.features().return_position_impl_trait_in_trait => true,
@@ -1255,7 +1262,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
12551262
} else {
12561263
self.next_node_id()
12571264
};
1258-
let span = self.tcx.sess.source_map().start_point(t.span);
1265+
let span = self.tcx.sess.source_map().start_point(t.span).shrink_to_hi();
12591266
Lifetime { ident: Ident::new(kw::UnderscoreLifetime, span), id }
12601267
});
12611268
let lifetime = self.lower_lifetime(&region);
@@ -1267,7 +1274,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
12671274
generic_params,
12681275
unsafety: self.lower_unsafety(f.unsafety),
12691276
abi: self.lower_extern(f.ext),
1270-
decl: self.lower_fn_decl(&f.decl, None, t.span, FnDeclKind::Pointer, None),
1277+
decl: self.lower_fn_decl(&f.decl, t.id, t.span, FnDeclKind::Pointer, None),
12711278
param_names: self.lower_fn_params_to_names(&f.decl),
12721279
}))
12731280
}
@@ -1546,15 +1553,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
15461553
let lifetimes =
15471554
self.arena.alloc_from_iter(collected_lifetimes.into_iter().map(|(_, lifetime)| {
15481555
let id = self.next_node_id();
1549-
let span = lifetime.ident.span;
1550-
1551-
let ident = if lifetime.ident.name == kw::UnderscoreLifetime {
1552-
Ident::with_dummy_span(kw::UnderscoreLifetime)
1553-
} else {
1554-
lifetime.ident
1555-
};
1556-
1557-
let l = self.new_named_lifetime(lifetime.id, id, span, ident);
1556+
let l = self.new_named_lifetime(lifetime.id, id, lifetime.ident);
15581557
hir::GenericArg::Lifetime(l)
15591558
}));
15601559
debug!(?lifetimes);
@@ -1679,7 +1678,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
16791678
fn lower_fn_decl(
16801679
&mut self,
16811680
decl: &FnDecl,
1682-
fn_node_id: Option<NodeId>,
1681+
fn_node_id: NodeId,
16831682
fn_span: Span,
16841683
kind: FnDeclKind,
16851684
make_ret_async: Option<(NodeId, Span)>,
@@ -1694,23 +1693,21 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
16941693
inputs = &inputs[..inputs.len() - 1];
16951694
}
16961695
let inputs = self.arena.alloc_from_iter(inputs.iter().map(|param| {
1697-
if fn_node_id.is_some() {
1698-
self.lower_ty_direct(&param.ty, &ImplTraitContext::Universal)
1696+
let itctx = if kind.param_impl_trait_allowed() {
1697+
ImplTraitContext::Universal
16991698
} else {
1700-
self.lower_ty_direct(
1701-
&param.ty,
1702-
&ImplTraitContext::Disallowed(match kind {
1703-
FnDeclKind::Fn | FnDeclKind::Inherent => {
1704-
unreachable!("fn should allow in-band lifetimes")
1705-
}
1706-
FnDeclKind::ExternFn => ImplTraitPosition::ExternFnParam,
1707-
FnDeclKind::Closure => ImplTraitPosition::ClosureParam,
1708-
FnDeclKind::Pointer => ImplTraitPosition::PointerParam,
1709-
FnDeclKind::Trait => ImplTraitPosition::TraitParam,
1710-
FnDeclKind::Impl => ImplTraitPosition::ImplParam,
1711-
}),
1712-
)
1713-
}
1699+
ImplTraitContext::Disallowed(match kind {
1700+
FnDeclKind::Fn | FnDeclKind::Inherent => {
1701+
unreachable!("fn should allow APIT")
1702+
}
1703+
FnDeclKind::ExternFn => ImplTraitPosition::ExternFnParam,
1704+
FnDeclKind::Closure => ImplTraitPosition::ClosureParam,
1705+
FnDeclKind::Pointer => ImplTraitPosition::PointerParam,
1706+
FnDeclKind::Trait => ImplTraitPosition::TraitParam,
1707+
FnDeclKind::Impl => ImplTraitPosition::ImplParam,
1708+
})
1709+
};
1710+
self.lower_ty_direct(&param.ty, &itctx)
17141711
}));
17151712

17161713
let output = if let Some((ret_id, span)) = make_ret_async {
@@ -1733,22 +1730,21 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
17331730

17341731
self.lower_async_fn_ret_ty(
17351732
&decl.output,
1736-
fn_node_id.expect("`make_ret_async` but no `fn_def_id`"),
1733+
fn_node_id,
17371734
ret_id,
17381735
matches!(kind, FnDeclKind::Trait),
17391736
)
17401737
} else {
17411738
match &decl.output {
17421739
FnRetTy::Ty(ty) => {
1743-
let mut context = match fn_node_id {
1744-
Some(fn_node_id) if kind.impl_trait_allowed(self.tcx) => {
1745-
let fn_def_id = self.local_def_id(fn_node_id);
1746-
ImplTraitContext::ReturnPositionOpaqueTy {
1747-
origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id),
1748-
in_trait: matches!(kind, FnDeclKind::Trait),
1749-
}
1740+
let mut context = if kind.return_impl_trait_allowed(self.tcx) {
1741+
let fn_def_id = self.local_def_id(fn_node_id);
1742+
ImplTraitContext::ReturnPositionOpaqueTy {
1743+
origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id),
1744+
in_trait: matches!(kind, FnDeclKind::Trait),
17501745
}
1751-
_ => ImplTraitContext::Disallowed(match kind {
1746+
} else {
1747+
ImplTraitContext::Disallowed(match kind {
17521748
FnDeclKind::Fn | FnDeclKind::Inherent => {
17531749
unreachable!("fn should allow in-band lifetimes")
17541750
}
@@ -1757,7 +1753,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
17571753
FnDeclKind::Pointer => ImplTraitPosition::PointerReturn,
17581754
FnDeclKind::Trait => ImplTraitPosition::TraitReturn,
17591755
FnDeclKind::Impl => ImplTraitPosition::ImplReturn,
1760-
}),
1756+
})
17611757
};
17621758
hir::FnRetTy::Return(self.lower_ty(ty, &mut context))
17631759
}
@@ -1769,6 +1765,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
17691765
inputs,
17701766
output,
17711767
c_variadic,
1768+
lifetime_elision_allowed: self.resolver.lifetime_elision_allowed.contains(&fn_node_id),
17721769
implicit_self: decl.inputs.get(0).map_or(hir::ImplicitSelfKind::None, |arg| {
17731770
let is_mutable_pat = matches!(
17741771
arg.pat.kind,
@@ -2010,18 +2007,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
20102007
let generic_args = self.arena.alloc_from_iter(collected_lifetimes.into_iter().map(
20112008
|(_, lifetime, res)| {
20122009
let id = self.next_node_id();
2013-
let span = lifetime.ident.span;
2014-
2015-
let ident = if lifetime.ident.name == kw::UnderscoreLifetime {
2016-
Ident::with_dummy_span(kw::UnderscoreLifetime)
2017-
} else {
2018-
lifetime.ident
2019-
};
2020-
20212010
let res = res.unwrap_or(
20222011
self.resolver.get_lifetime_res(lifetime.id).unwrap_or(LifetimeRes::Error),
20232012
);
2024-
hir::GenericArg::Lifetime(self.new_named_lifetime_with_res(id, span, ident, res))
2013+
hir::GenericArg::Lifetime(self.new_named_lifetime_with_res(id, lifetime.ident, res))
20252014
},
20262015
));
20272016

@@ -2091,43 +2080,40 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
20912080
}
20922081

20932082
fn lower_lifetime(&mut self, l: &Lifetime) -> &'hir hir::Lifetime {
2094-
let span = self.lower_span(l.ident.span);
20952083
let ident = self.lower_ident(l.ident);
2096-
self.new_named_lifetime(l.id, l.id, span, ident)
2084+
self.new_named_lifetime(l.id, l.id, ident)
20972085
}
20982086

20992087
#[instrument(level = "debug", skip(self))]
21002088
fn new_named_lifetime_with_res(
21012089
&mut self,
21022090
id: NodeId,
2103-
span: Span,
21042091
ident: Ident,
21052092
res: LifetimeRes,
21062093
) -> &'hir hir::Lifetime {
2107-
let name = match res {
2094+
let res = match res {
21082095
LifetimeRes::Param { param, .. } => {
2109-
let p_name = ParamName::Plain(ident);
21102096
let param = self.get_remapped_def_id(param);
2111-
2112-
hir::LifetimeName::Param(param, p_name)
2097+
hir::LifetimeName::Param(param)
21132098
}
21142099
LifetimeRes::Fresh { param, .. } => {
2115-
debug_assert_eq!(ident.name, kw::UnderscoreLifetime);
21162100
let param = self.local_def_id(param);
2117-
2118-
hir::LifetimeName::Param(param, ParamName::Fresh)
2101+
hir::LifetimeName::Param(param)
21192102
}
21202103
LifetimeRes::Infer => hir::LifetimeName::Infer,
21212104
LifetimeRes::Static => hir::LifetimeName::Static,
21222105
LifetimeRes::Error => hir::LifetimeName::Error,
2123-
res => panic!("Unexpected lifetime resolution {:?} for {:?} at {:?}", res, ident, span),
2106+
res => panic!(
2107+
"Unexpected lifetime resolution {:?} for {:?} at {:?}",
2108+
res, ident, ident.span
2109+
),
21242110
};
21252111

2126-
debug!(?name);
2112+
debug!(?res);
21272113
self.arena.alloc(hir::Lifetime {
21282114
hir_id: self.lower_node_id(id),
2129-
span: self.lower_span(span),
2130-
name,
2115+
ident: self.lower_ident(ident),
2116+
res,
21312117
})
21322118
}
21332119

@@ -2136,11 +2122,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
21362122
&mut self,
21372123
id: NodeId,
21382124
new_id: NodeId,
2139-
span: Span,
21402125
ident: Ident,
21412126
) -> &'hir hir::Lifetime {
21422127
let res = self.resolver.get_lifetime_res(id).unwrap_or(LifetimeRes::Error);
2143-
self.new_named_lifetime_with_res(new_id, span, ident, res)
2128+
self.new_named_lifetime_with_res(new_id, ident, res)
21442129
}
21452130

21462131
fn lower_generic_params_mut<'s>(
@@ -2552,8 +2537,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
25522537
fn elided_dyn_bound(&mut self, span: Span) -> &'hir hir::Lifetime {
25532538
let r = hir::Lifetime {
25542539
hir_id: self.next_id(),
2555-
span: self.lower_span(span),
2556-
name: hir::LifetimeName::ImplicitObjectLifetimeDefault,
2540+
ident: Ident::new(kw::Empty, self.lower_span(span)),
2541+
res: hir::LifetimeName::ImplicitObjectLifetimeDefault,
25572542
};
25582543
debug!("elided_dyn_bound: r={:?}", r);
25592544
self.arena.alloc(r)

compiler/rustc_ast_lowering/src/path.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
309309
let id = NodeId::from_u32(i);
310310
let l = self.lower_lifetime(&Lifetime {
311311
id,
312-
ident: Ident::new(kw::UnderscoreLifetime, elided_lifetime_span),
312+
ident: Ident::new(kw::Empty, elided_lifetime_span),
313313
});
314314
GenericArg::Lifetime(l)
315315
}),

compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -2670,7 +2670,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
26702670
if let hir::TyKind::Rptr(lifetime, _) = &fn_decl.inputs[index].kind {
26712671
// With access to the lifetime, we can get
26722672
// the span of it.
2673-
arguments.push((*argument, lifetime.span));
2673+
arguments.push((*argument, lifetime.ident.span));
26742674
} else {
26752675
bug!("ty type is a ref but hir type is not");
26762676
}
@@ -2689,7 +2689,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
26892689
let mut return_span = fn_decl.output.span();
26902690
if let hir::FnRetTy::Return(ty) = &fn_decl.output {
26912691
if let hir::TyKind::Rptr(lifetime, _) = ty.kind {
2692-
return_span = lifetime.span;
2692+
return_span = lifetime.ident.span;
26932693
}
26942694
}
26952695

compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1211,7 +1211,7 @@ fn get_mut_span_in_struct_field<'tcx>(
12111211
&& let hir::Node::Field(field) = node
12121212
&& let hir::TyKind::Rptr(lt, hir::MutTy { mutbl: hir::Mutability::Not, ty }) = field.ty.kind
12131213
{
1214-
return Some(lt.span.between(ty.span));
1214+
return Some(lt.ident.span.between(ty.span));
12151215
}
12161216

12171217
None

compiler/rustc_borrowck/src/diagnostics/region_name.rs

+4-24
Original file line numberDiff line numberDiff line change
@@ -576,30 +576,10 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
576576
let args = last_segment.args.as_ref()?;
577577
let lifetime =
578578
self.try_match_adt_and_generic_args(substs, needle_fr, args, search_stack)?;
579-
match lifetime.name {
580-
hir::LifetimeName::Param(_, hir::ParamName::Plain(_) | hir::ParamName::Error)
581-
| hir::LifetimeName::Error
582-
| hir::LifetimeName::Static => {
583-
let lifetime_span = lifetime.span;
584-
Some(RegionNameHighlight::MatchedAdtAndSegment(lifetime_span))
585-
}
586-
587-
hir::LifetimeName::Param(_, hir::ParamName::Fresh)
588-
| hir::LifetimeName::ImplicitObjectLifetimeDefault
589-
| hir::LifetimeName::Infer => {
590-
// In this case, the user left off the lifetime; so
591-
// they wrote something like:
592-
//
593-
// ```
594-
// x: Foo<T>
595-
// ```
596-
//
597-
// where the fully elaborated form is `Foo<'_, '1,
598-
// T>`. We don't consider this a match; instead we let
599-
// the "fully elaborated" type fallback above handle
600-
// it.
601-
None
602-
}
579+
if lifetime.is_anonymous() {
580+
None
581+
} else {
582+
Some(RegionNameHighlight::MatchedAdtAndSegment(lifetime.ident.span))
603583
}
604584
}
605585

0 commit comments

Comments
 (0)