Skip to content

Commit 5f5e7a8

Browse files
committed
Record in HIR whether lifetime elision was succesful.
1 parent fb7d25e commit 5f5e7a8

File tree

7 files changed

+50
-34
lines changed

7 files changed

+50
-34
lines changed

compiler/rustc_ast_lowering/src/expr.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
603603
output,
604604
c_variadic: false,
605605
implicit_self: hir::ImplicitSelfKind::None,
606+
lifetime_elision_allowed: false,
606607
});
607608

608609
// Lower the argument pattern/ident. The ident is used again in the `.await` lowering.
@@ -907,7 +908,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
907908

908909
let bound_generic_params = self.lower_lifetime_binder(closure_id, generic_params);
909910
// Lower outside new scope to preserve `is_in_loop_condition`.
910-
let fn_decl = self.lower_fn_decl(decl, None, fn_decl_span, FnDeclKind::Closure, None);
911+
let fn_decl = self.lower_fn_decl(decl, closure_id, fn_decl_span, FnDeclKind::Closure, None);
911912

912913
let c = self.arena.alloc(hir::Closure {
913914
def_id: self.local_def_id(closure_id),
@@ -1017,7 +1018,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
10171018
// have to conserve the state of being inside a loop condition for the
10181019
// closure argument types.
10191020
let fn_decl =
1020-
self.lower_fn_decl(&outer_decl, None, fn_decl_span, FnDeclKind::Closure, None);
1021+
self.lower_fn_decl(&outer_decl, closure_id, fn_decl_span, FnDeclKind::Closure, None);
10211022

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

compiler/rustc_ast_lowering/src/item.rs

+3-3
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
}

compiler/rustc_ast_lowering/src/lib.rs

+34-29
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,
@@ -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
}
@@ -1671,7 +1678,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
16711678
fn lower_fn_decl(
16721679
&mut self,
16731680
decl: &FnDecl,
1674-
fn_node_id: Option<NodeId>,
1681+
fn_node_id: NodeId,
16751682
fn_span: Span,
16761683
kind: FnDeclKind,
16771684
make_ret_async: Option<(NodeId, Span)>,
@@ -1686,23 +1693,21 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
16861693
inputs = &inputs[..inputs.len() - 1];
16871694
}
16881695
let inputs = self.arena.alloc_from_iter(inputs.iter().map(|param| {
1689-
if fn_node_id.is_some() {
1690-
self.lower_ty_direct(&param.ty, &ImplTraitContext::Universal)
1696+
let itctx = if kind.param_impl_trait_allowed() {
1697+
ImplTraitContext::Universal
16911698
} else {
1692-
self.lower_ty_direct(
1693-
&param.ty,
1694-
&ImplTraitContext::Disallowed(match kind {
1695-
FnDeclKind::Fn | FnDeclKind::Inherent => {
1696-
unreachable!("fn should allow in-band lifetimes")
1697-
}
1698-
FnDeclKind::ExternFn => ImplTraitPosition::ExternFnParam,
1699-
FnDeclKind::Closure => ImplTraitPosition::ClosureParam,
1700-
FnDeclKind::Pointer => ImplTraitPosition::PointerParam,
1701-
FnDeclKind::Trait => ImplTraitPosition::TraitParam,
1702-
FnDeclKind::Impl => ImplTraitPosition::ImplParam,
1703-
}),
1704-
)
1705-
}
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)
17061711
}));
17071712

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

17261731
self.lower_async_fn_ret_ty(
17271732
&decl.output,
1728-
fn_node_id.expect("`make_ret_async` but no `fn_def_id`"),
1733+
fn_node_id,
17291734
ret_id,
17301735
matches!(kind, FnDeclKind::Trait),
17311736
)
17321737
} else {
17331738
match &decl.output {
17341739
FnRetTy::Ty(ty) => {
1735-
let mut context = match fn_node_id {
1736-
Some(fn_node_id) if kind.impl_trait_allowed(self.tcx) => {
1737-
let fn_def_id = self.local_def_id(fn_node_id);
1738-
ImplTraitContext::ReturnPositionOpaqueTy {
1739-
origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id),
1740-
in_trait: matches!(kind, FnDeclKind::Trait),
1741-
}
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),
17421745
}
1743-
_ => ImplTraitContext::Disallowed(match kind {
1746+
} else {
1747+
ImplTraitContext::Disallowed(match kind {
17441748
FnDeclKind::Fn | FnDeclKind::Inherent => {
17451749
unreachable!("fn should allow in-band lifetimes")
17461750
}
@@ -1749,7 +1753,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
17491753
FnDeclKind::Pointer => ImplTraitPosition::PointerReturn,
17501754
FnDeclKind::Trait => ImplTraitPosition::TraitReturn,
17511755
FnDeclKind::Impl => ImplTraitPosition::ImplReturn,
1752-
}),
1756+
})
17531757
};
17541758
hir::FnRetTy::Return(self.lower_ty(ty, &mut context))
17551759
}
@@ -1761,6 +1765,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
17611765
inputs,
17621766
output,
17631767
c_variadic,
1768+
lifetime_elision_allowed: self.resolver.lifetime_elision_allowed.contains(&fn_node_id),
17641769
implicit_self: decl.inputs.get(0).map_or(hir::ImplicitSelfKind::None, |arg| {
17651770
let is_mutable_pat = matches!(
17661771
arg.pat.kind,

compiler/rustc_hir/src/hir.rs

+2
Original file line numberDiff line numberDiff line change
@@ -2670,6 +2670,8 @@ pub struct FnDecl<'hir> {
26702670
pub c_variadic: bool,
26712671
/// Does the function have an implicit self?
26722672
pub implicit_self: ImplicitSelfKind,
2673+
/// Is lifetime elision allowed.
2674+
pub lifetime_elision_allowed: bool,
26732675
}
26742676

26752677
/// Represents what type of implicit self a function has, if any.

compiler/rustc_middle/src/ty/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,8 @@ pub struct ResolverAstLowering {
207207
/// A small map keeping true kinds of built-in macros that appear to be fn-like on
208208
/// the surface (`macro` items in libcore), but are actually attributes or derives.
209209
pub builtin_macro_kinds: FxHashMap<LocalDefId, MacroKind>,
210+
/// List functions and methods for which lifetime elision was successful.
211+
pub lifetime_elision_allowed: FxHashSet<ast::NodeId>,
210212
}
211213

212214
#[derive(Clone, Copy, Debug)]

compiler/rustc_resolve/src/late.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1838,6 +1838,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
18381838

18391839
let outer_failures = take(&mut self.diagnostic_metadata.current_elision_failures);
18401840
let output_rib = if let Ok(res) = elision_lifetime.as_ref() {
1841+
self.r.lifetime_elision_allowed.insert(fn_id);
18411842
LifetimeRibKind::Elided(*res)
18421843
} else {
18431844
LifetimeRibKind::ElisionFailure

compiler/rustc_resolve/src/lib.rs

+5
Original file line numberDiff line numberDiff line change
@@ -1036,6 +1036,8 @@ pub struct Resolver<'a> {
10361036
/// they are declared in the static array generated by proc_macro_harness.
10371037
proc_macros: Vec<NodeId>,
10381038
confused_type_with_std_module: FxHashMap<Span, Span>,
1039+
/// Whether lifetime elision was successful.
1040+
lifetime_elision_allowed: FxHashSet<NodeId>,
10391041

10401042
effective_visibilities: EffectiveVisibilities,
10411043
}
@@ -1354,6 +1356,7 @@ impl<'a> Resolver<'a> {
13541356
trait_impls: Default::default(),
13551357
proc_macros: Default::default(),
13561358
confused_type_with_std_module: Default::default(),
1359+
lifetime_elision_allowed: Default::default(),
13571360
effective_visibilities: Default::default(),
13581361
};
13591362

@@ -1448,6 +1451,7 @@ impl<'a> Resolver<'a> {
14481451
def_id_to_node_id: self.def_id_to_node_id,
14491452
trait_map: self.trait_map,
14501453
builtin_macro_kinds: self.builtin_macro_kinds,
1454+
lifetime_elision_allowed: self.lifetime_elision_allowed,
14511455
};
14521456
ResolverOutputs { definitions, global_ctxt, ast_lowering }
14531457
}
@@ -1491,6 +1495,7 @@ impl<'a> Resolver<'a> {
14911495
def_id_to_node_id: self.def_id_to_node_id.clone(),
14921496
trait_map: self.trait_map.clone(),
14931497
builtin_macro_kinds: self.builtin_macro_kinds.clone(),
1498+
lifetime_elision_allowed: self.lifetime_elision_allowed.clone(),
14941499
};
14951500
ResolverOutputs { definitions, global_ctxt, ast_lowering }
14961501
}

0 commit comments

Comments
 (0)