From a2254d5d7c57be00cc640c0f7a8e21b320e947aa Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Mon, 13 Jun 2022 07:36:45 +0200 Subject: [PATCH 01/10] Do not produce extra lifetime parameters when not needed. --- compiler/rustc_resolve/src/late.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 9b5fd4ea6d133..bc5668bcec00f 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -1632,6 +1632,9 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { | PathSource::Struct | PathSource::TupleStruct(..) => false, }; + if !missing && !segment.has_generic_args { + continue; + } let elided_lifetime_span = if segment.has_generic_args { // If there are brackets, but not generic arguments, then use the opening bracket From ab63591f00cb985fe95e1226a2ab3898f1b9e471 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 22 May 2022 10:22:20 +0200 Subject: [PATCH 02/10] Remove the distinction between LifetimeName::Implicit and LifetimeName::Underscore. --- compiler/rustc_ast_lowering/src/lib.rs | 8 +-- .../src/diagnostics/region_name.rs | 1 - compiler/rustc_hir/src/def.rs | 2 - compiler/rustc_hir/src/hir.rs | 14 ++---- compiler/rustc_hir/src/intravisit.rs | 1 - compiler/rustc_resolve/src/late.rs | 50 +++++-------------- compiler/rustc_resolve/src/late/lifetimes.rs | 8 +-- 7 files changed, 21 insertions(+), 63 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index d4b41aad08ca4..a031480611641 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -1883,7 +1883,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } hir::LifetimeName::Param(param, ParamName::Fresh) } - LifetimeRes::Anonymous { binder, elided } => { + LifetimeRes::Anonymous { binder } => { let mut l_name = None; if let Some(mut captured_lifetimes) = self.captured_lifetimes.take() { if !captured_lifetimes.binders_to_ignore.contains(&binder) { @@ -1900,11 +1900,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } self.captured_lifetimes = Some(captured_lifetimes); }; - l_name.unwrap_or(if elided { - hir::LifetimeName::Implicit - } else { - hir::LifetimeName::Underscore - }) + l_name.unwrap_or(hir::LifetimeName::Underscore) } LifetimeRes::Static => hir::LifetimeName::Static, LifetimeRes::Error => hir::LifetimeName::Error, diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs index 4cf1ac4d7abc0..8ba76979c39c6 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs @@ -589,7 +589,6 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { hir::LifetimeName::Param(_, hir::ParamName::Fresh) | hir::LifetimeName::ImplicitObjectLifetimeDefault - | hir::LifetimeName::Implicit | hir::LifetimeName::Underscore => { // In this case, the user left off the lifetime; so // they wrote something like: diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs index c0d5d2bc46d0d..2003d70835c6f 100644 --- a/compiler/rustc_hir/src/def.rs +++ b/compiler/rustc_hir/src/def.rs @@ -742,8 +742,6 @@ pub enum LifetimeRes { Anonymous { /// Id of the introducing place. See `Param`. binder: NodeId, - /// Whether this lifetime was spelled or elided. - elided: bool, }, /// Explicit `'static` lifetime. Static, diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 18ffc227fed86..7a0bf265fafdb 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -90,9 +90,6 @@ pub enum LifetimeName { /// User-given names or fresh (synthetic) names. Param(LocalDefId, ParamName), - /// User wrote nothing (e.g., the lifetime in `&u32`). - Implicit, - /// Implicit lifetime in a context like `dyn Foo`. This is /// distinguished from implicit lifetimes elsewhere because the /// lifetime that they default to must appear elsewhere within the @@ -110,7 +107,7 @@ pub enum LifetimeName { /// that was already reported. Error, - /// User wrote specifies `'_`. + /// User wrote an anonymous lifetime, either `'_` or nothing. Underscore, /// User wrote `'static`. @@ -120,9 +117,7 @@ pub enum LifetimeName { impl LifetimeName { pub fn ident(&self) -> Ident { match *self { - LifetimeName::ImplicitObjectLifetimeDefault - | LifetimeName::Implicit - | LifetimeName::Error => Ident::empty(), + LifetimeName::ImplicitObjectLifetimeDefault | LifetimeName::Error => Ident::empty(), LifetimeName::Underscore => Ident::with_dummy_span(kw::UnderscoreLifetime), LifetimeName::Static => Ident::with_dummy_span(kw::StaticLifetime), LifetimeName::Param(_, param_name) => param_name.ident(), @@ -132,7 +127,6 @@ impl LifetimeName { pub fn is_anonymous(&self) -> bool { match *self { LifetimeName::ImplicitObjectLifetimeDefault - | LifetimeName::Implicit | LifetimeName::Underscore | LifetimeName::Param(_, ParamName::Fresh) | LifetimeName::Error => true, @@ -142,9 +136,7 @@ impl LifetimeName { pub fn is_elided(&self) -> bool { match self { - LifetimeName::ImplicitObjectLifetimeDefault - | LifetimeName::Implicit - | LifetimeName::Underscore => true, + LifetimeName::ImplicitObjectLifetimeDefault | LifetimeName::Underscore => true, // It might seem surprising that `Fresh` counts as // *not* elided -- but this is because, as far as the code diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index d00b65da7e6a5..b1d8c616fb81d 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -496,7 +496,6 @@ pub fn walk_lifetime<'v, V: Visitor<'v>>(visitor: &mut V, lifetime: &'v Lifetime | LifetimeName::Param(_, ParamName::Error) | LifetimeName::Static | LifetimeName::Error - | LifetimeName::Implicit | LifetimeName::ImplicitObjectLifetimeDefault | LifetimeName::Underscore => {} } diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index bc5668bcec00f..a12495c51ad7c 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -262,9 +262,6 @@ enum LifetimeRibKind { /// error on default object bounds (e.g., `Box`). AnonymousReportError, - /// Pass responsibility to `resolve_lifetime` code for all cases. - AnonymousPassThrough(NodeId), - /// Replace all anonymous lifetimes by provided lifetime. Elided(LifetimeRes), @@ -868,7 +865,7 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> { let previous_state = replace(&mut this.in_func_body, true); // Resolve the function body, potentially inside the body of an async closure this.with_lifetime_rib( - LifetimeRibKind::AnonymousPassThrough(fn_id), + LifetimeRibKind::Elided(LifetimeRes::Anonymous { binder: fn_id }), |this| this.visit_block(body), ); @@ -896,7 +893,9 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> { this.with_lifetime_rib( match binder { ClosureBinder::NotPresent => { - LifetimeRibKind::AnonymousPassThrough(fn_id) + LifetimeRibKind::Elided(LifetimeRes::Anonymous { + binder: fn_id, + }) } ClosureBinder::For { .. } => LifetimeRibKind::AnonymousReportError, }, @@ -908,7 +907,7 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> { let previous_state = replace(&mut this.in_func_body, true); // Resolve the function body, potentially inside the body of an async closure this.with_lifetime_rib( - LifetimeRibKind::AnonymousPassThrough(fn_id), + LifetimeRibKind::Elided(LifetimeRes::Anonymous { binder: fn_id }), |this| this.visit_expr(body), ); @@ -1053,8 +1052,7 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> { visit::walk_generic_args(self, path_span, args); break; } - LifetimeRibKind::AnonymousPassThrough(..) - | LifetimeRibKind::AnonymousCreateParameter { .. } + LifetimeRibKind::AnonymousCreateParameter { .. } | LifetimeRibKind::AnonymousReportError | LifetimeRibKind::Elided(_) | LifetimeRibKind::ElisionFailure @@ -1415,8 +1413,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { | LifetimeRibKind::AnonymousReportError | LifetimeRibKind::ElisionFailure => Some(LifetimeUseSet::Many), // An anonymous lifetime is legal here, go ahead. - LifetimeRibKind::AnonymousPassThrough(_) - | LifetimeRibKind::AnonymousCreateParameter { .. } => { + LifetimeRibKind::AnonymousCreateParameter { .. } => { Some(LifetimeUseSet::One { use_span: ident.span, use_ctxt }) } // Only report if eliding the lifetime would have the same @@ -1527,14 +1524,6 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { self.record_lifetime_res(lifetime.id, LifetimeRes::Error, elision_candidate); return; } - LifetimeRibKind::AnonymousPassThrough(node_id) => { - self.record_lifetime_res( - lifetime.id, - LifetimeRes::Anonymous { binder: node_id, elided }, - elision_candidate, - ); - return; - } LifetimeRibKind::Elided(res) => { self.record_lifetime_res(lifetime.id, res, elision_candidate); return; @@ -1658,8 +1647,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { // Do not create a parameter for patterns and expressions. for rib in self.lifetime_ribs.iter().rev() { match rib.kind { - LifetimeRibKind::AnonymousPassThrough(binder) => { - let res = LifetimeRes::Anonymous { binder, elided: true }; + LifetimeRibKind::Elided(res @ LifetimeRes::Anonymous { .. }) => { for id in node_ids { self.record_lifetime_res(id, res, LifetimeElisionCandidate::Named); } @@ -1673,8 +1661,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { // FIXME(cjgillot) This resolution is wrong, but this does not matter // since these cases are erroneous anyway. Lifetime resolution should // emit a "missing lifetime specifier" diagnostic. - let res = - LifetimeRes::Anonymous { binder: DUMMY_NODE_ID, elided: true }; + let res = LifetimeRes::Anonymous { binder: DUMMY_NODE_ID }; for id in node_ids { self.record_lifetime_res(id, res, LifetimeElisionCandidate::Named); } @@ -1753,19 +1740,6 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { } break; } - // `PassThrough` is the normal case. - LifetimeRibKind::AnonymousPassThrough(binder) => { - let res = LifetimeRes::Anonymous { binder, elided: true }; - let mut candidate = LifetimeElisionCandidate::Missing(missing_lifetime); - for id in node_ids { - self.record_lifetime_res( - id, - res, - replace(&mut candidate, LifetimeElisionCandidate::Ignore), - ); - } - break; - } LifetimeRibKind::Elided(res) => { let mut candidate = LifetimeElisionCandidate::Missing(missing_lifetime); for id in node_ids { @@ -2272,7 +2246,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { this.visit_ty(ty); }); this.with_lifetime_rib( - LifetimeRibKind::AnonymousPassThrough(item.id), + LifetimeRibKind::Elided(LifetimeRes::Anonymous { binder: item.id }), |this| { if let Some(expr) = expr { let constant_item_kind = match item.kind { @@ -2547,7 +2521,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { // Type parameters can already be used and as associated consts are // not used as part of the type system, this is far less surprising. self.with_lifetime_rib( - LifetimeRibKind::AnonymousPassThrough(item.id), + LifetimeRibKind::Elided(LifetimeRes::Anonymous { binder: item.id }), |this| { this.with_constant_rib( IsRepeatExpr::No, @@ -2721,7 +2695,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { // Type parameters can already be used and as associated consts are // not used as part of the type system, this is far less surprising. self.with_lifetime_rib( - LifetimeRibKind::AnonymousPassThrough(item.id), + LifetimeRibKind::Elided(LifetimeRes::Anonymous { binder: item.id }), |this| { this.with_constant_rib( IsRepeatExpr::No, diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs index a7fd7c427c759..e9cbbedc7b0b2 100644 --- a/compiler/rustc_resolve/src/late/lifetimes.rs +++ b/compiler/rustc_resolve/src/late/lifetimes.rs @@ -819,7 +819,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { // `Box`. self.resolve_object_lifetime_default(lifetime) } - LifetimeName::Implicit | LifetimeName::Underscore => { + LifetimeName::Underscore => { // If the user writes `'_`, we use the *ordinary* elision // rules. So the `'_` in e.g., `Box` will be // resolved the same as the `'_` in `&'_ Foo`. @@ -1135,9 +1135,9 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { #[tracing::instrument(level = "debug", skip(self))] fn visit_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime) { match lifetime_ref.name { - hir::LifetimeName::ImplicitObjectLifetimeDefault - | hir::LifetimeName::Implicit - | hir::LifetimeName::Underscore => self.resolve_elided_lifetimes(&[lifetime_ref]), + hir::LifetimeName::ImplicitObjectLifetimeDefault | hir::LifetimeName::Underscore => { + self.resolve_elided_lifetimes(&[lifetime_ref]) + } hir::LifetimeName::Static => self.insert_lifetime(lifetime_ref, Region::Static), hir::LifetimeName::Param(param_def_id, _) => { self.resolve_lifetime_ref(param_def_id, lifetime_ref) From 10be0dd8dfc46eda4dc4d1555df31de2e8b7551a Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Mon, 13 Jun 2022 08:22:06 +0200 Subject: [PATCH 03/10] Replace LifetimeRes::Anonymous by LifetimeRes::Infer. --- compiler/rustc_ast_lowering/src/lib.rs | 20 +--- .../src/diagnostics/region_name.rs | 2 +- compiler/rustc_hir/src/def.rs | 7 +- compiler/rustc_hir/src/hir.rs | 9 +- compiler/rustc_hir/src/intravisit.rs | 2 +- compiler/rustc_resolve/src/late.rs | 108 ++++++------------ compiler/rustc_resolve/src/late/lifetimes.rs | 4 +- .../clippy_lints/src/manual_async_fn.rs | 2 +- src/tools/clippy/clippy_lints/src/ptr.rs | 2 +- 9 files changed, 51 insertions(+), 105 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index a031480611641..a1bf0f94964bb 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -1883,25 +1883,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } hir::LifetimeName::Param(param, ParamName::Fresh) } - LifetimeRes::Anonymous { binder } => { - let mut l_name = None; - if let Some(mut captured_lifetimes) = self.captured_lifetimes.take() { - if !captured_lifetimes.binders_to_ignore.contains(&binder) { - let p_id = self.next_node_id(); - let p_def_id = self.create_def( - captured_lifetimes.parent_def_id, - p_id, - DefPathData::LifetimeNs(kw::UnderscoreLifetime), - ); - captured_lifetimes - .captures - .insert(p_def_id, (span, p_id, ParamName::Fresh, res)); - l_name = Some(hir::LifetimeName::Param(p_def_id, ParamName::Fresh)); - } - self.captured_lifetimes = Some(captured_lifetimes); - }; - l_name.unwrap_or(hir::LifetimeName::Underscore) - } + LifetimeRes::Infer => hir::LifetimeName::Infer, LifetimeRes::Static => hir::LifetimeName::Static, LifetimeRes::Error => hir::LifetimeName::Error, res => panic!("Unexpected lifetime resolution {:?} for {:?} at {:?}", res, ident, span), diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs index 8ba76979c39c6..0662d4d882f6a 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs @@ -589,7 +589,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { hir::LifetimeName::Param(_, hir::ParamName::Fresh) | hir::LifetimeName::ImplicitObjectLifetimeDefault - | hir::LifetimeName::Underscore => { + | hir::LifetimeName::Infer => { // In this case, the user left off the lifetime; so // they wrote something like: // diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs index 2003d70835c6f..be5b7eccbafb2 100644 --- a/compiler/rustc_hir/src/def.rs +++ b/compiler/rustc_hir/src/def.rs @@ -738,11 +738,8 @@ pub enum LifetimeRes { binder: NodeId, }, /// This variant is used for anonymous lifetimes that we did not resolve during - /// late resolution. Shifting the work to the HIR lifetime resolver. - Anonymous { - /// Id of the introducing place. See `Param`. - binder: NodeId, - }, + /// late resolution. Those lifetimes will be inferred by typechecking. + Infer, /// Explicit `'static` lifetime. Static, /// Resolution failure. diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 7a0bf265fafdb..f71400898e60b 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -108,7 +108,8 @@ pub enum LifetimeName { Error, /// User wrote an anonymous lifetime, either `'_` or nothing. - Underscore, + /// The semantics of this lifetime should be inferred by typechecking code. + Infer, /// User wrote `'static`. Static, @@ -118,7 +119,7 @@ impl LifetimeName { pub fn ident(&self) -> Ident { match *self { LifetimeName::ImplicitObjectLifetimeDefault | LifetimeName::Error => Ident::empty(), - LifetimeName::Underscore => Ident::with_dummy_span(kw::UnderscoreLifetime), + LifetimeName::Infer => Ident::with_dummy_span(kw::UnderscoreLifetime), LifetimeName::Static => Ident::with_dummy_span(kw::StaticLifetime), LifetimeName::Param(_, param_name) => param_name.ident(), } @@ -127,7 +128,7 @@ impl LifetimeName { pub fn is_anonymous(&self) -> bool { match *self { LifetimeName::ImplicitObjectLifetimeDefault - | LifetimeName::Underscore + | LifetimeName::Infer | LifetimeName::Param(_, ParamName::Fresh) | LifetimeName::Error => true, LifetimeName::Static | LifetimeName::Param(..) => false, @@ -136,7 +137,7 @@ impl LifetimeName { pub fn is_elided(&self) -> bool { match self { - LifetimeName::ImplicitObjectLifetimeDefault | LifetimeName::Underscore => true, + LifetimeName::ImplicitObjectLifetimeDefault | LifetimeName::Infer => true, // It might seem surprising that `Fresh` counts as // *not* elided -- but this is because, as far as the code diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index b1d8c616fb81d..640974115b926 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -497,7 +497,7 @@ pub fn walk_lifetime<'v, V: Visitor<'v>>(visitor: &mut V, lifetime: &'v Lifetime | LifetimeName::Static | LifetimeName::Error | LifetimeName::ImplicitObjectLifetimeDefault - | LifetimeName::Underscore => {} + | LifetimeName::Infer => {} } } diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index a12495c51ad7c..f5fb2585c748e 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -865,7 +865,7 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> { let previous_state = replace(&mut this.in_func_body, true); // Resolve the function body, potentially inside the body of an async closure this.with_lifetime_rib( - LifetimeRibKind::Elided(LifetimeRes::Anonymous { binder: fn_id }), + LifetimeRibKind::Elided(LifetimeRes::Infer), |this| this.visit_block(body), ); @@ -893,9 +893,7 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> { this.with_lifetime_rib( match binder { ClosureBinder::NotPresent => { - LifetimeRibKind::Elided(LifetimeRes::Anonymous { - binder: fn_id, - }) + LifetimeRibKind::Elided(LifetimeRes::Infer) } ClosureBinder::For { .. } => LifetimeRibKind::AnonymousReportError, }, @@ -907,7 +905,7 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> { let previous_state = replace(&mut this.in_func_body, true); // Resolve the function body, potentially inside the body of an async closure this.with_lifetime_rib( - LifetimeRibKind::Elided(LifetimeRes::Anonymous { binder: fn_id }), + LifetimeRibKind::Elided(LifetimeRes::Infer), |this| this.visit_expr(body), ); @@ -1645,35 +1643,12 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { if !missing { // Do not create a parameter for patterns and expressions. - for rib in self.lifetime_ribs.iter().rev() { - match rib.kind { - LifetimeRibKind::Elided(res @ LifetimeRes::Anonymous { .. }) => { - for id in node_ids { - self.record_lifetime_res(id, res, LifetimeElisionCandidate::Named); - } - break; - } - // `LifetimeRes::Error`, which would usually be used in the case of - // `ReportError`, is unsuitable here, as we don't emit an error yet. Instead, - // we simply resolve to an implicit lifetime, which will be checked later, at - // which point a suitable error will be emitted. - LifetimeRibKind::AnonymousReportError | LifetimeRibKind::Item => { - // FIXME(cjgillot) This resolution is wrong, but this does not matter - // since these cases are erroneous anyway. Lifetime resolution should - // emit a "missing lifetime specifier" diagnostic. - let res = LifetimeRes::Anonymous { binder: DUMMY_NODE_ID }; - for id in node_ids { - self.record_lifetime_res(id, res, LifetimeElisionCandidate::Named); - } - break; - } - LifetimeRibKind::AnonymousCreateParameter { .. } - | LifetimeRibKind::Elided(_) - | LifetimeRibKind::ElisionFailure - | LifetimeRibKind::Generics { .. } - | LifetimeRibKind::ConstGeneric - | LifetimeRibKind::AnonConst => {} - } + for id in node_ids { + self.record_lifetime_res( + id, + LifetimeRes::Infer, + LifetimeElisionCandidate::Named, + ); } continue; } @@ -1814,15 +1789,12 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { ) } match res { - LifetimeRes::Param { .. } - | LifetimeRes::Fresh { .. } - | LifetimeRes::Anonymous { .. } - | LifetimeRes::Static => { + LifetimeRes::Param { .. } | LifetimeRes::Fresh { .. } | LifetimeRes::Static => { if let Some(ref mut candidates) = self.lifetime_elision_candidates { candidates.insert(res, candidate); } } - LifetimeRes::Error | LifetimeRes::ElidedAnchor { .. } => {} + LifetimeRes::Infer | LifetimeRes::Error | LifetimeRes::ElidedAnchor { .. } => {} } } @@ -2245,26 +2217,23 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { this.with_lifetime_rib(LifetimeRibKind::Elided(LifetimeRes::Static), |this| { this.visit_ty(ty); }); - this.with_lifetime_rib( - LifetimeRibKind::Elided(LifetimeRes::Anonymous { binder: item.id }), - |this| { - if let Some(expr) = expr { - let constant_item_kind = match item.kind { - ItemKind::Const(..) => ConstantItemKind::Const, - ItemKind::Static(..) => ConstantItemKind::Static, - _ => unreachable!(), - }; - // We already forbid generic params because of the above item rib, - // so it doesn't matter whether this is a trivial constant. - this.with_constant_rib( - IsRepeatExpr::No, - HasGenericParams::Yes, - Some((item.ident, constant_item_kind)), - |this| this.visit_expr(expr), - ); - } - }, - ); + this.with_lifetime_rib(LifetimeRibKind::Elided(LifetimeRes::Infer), |this| { + if let Some(expr) = expr { + let constant_item_kind = match item.kind { + ItemKind::Const(..) => ConstantItemKind::Const, + ItemKind::Static(..) => ConstantItemKind::Static, + _ => unreachable!(), + }; + // We already forbid generic params because of the above item rib, + // so it doesn't matter whether this is a trivial constant. + this.with_constant_rib( + IsRepeatExpr::No, + HasGenericParams::Yes, + Some((item.ident, constant_item_kind)), + |this| this.visit_expr(expr), + ); + } + }); }); } @@ -2521,7 +2490,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { // Type parameters can already be used and as associated consts are // not used as part of the type system, this is far less surprising. self.with_lifetime_rib( - LifetimeRibKind::Elided(LifetimeRes::Anonymous { binder: item.id }), + LifetimeRibKind::Elided(LifetimeRes::Infer), |this| { this.with_constant_rib( IsRepeatExpr::No, @@ -2694,17 +2663,14 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { // // Type parameters can already be used and as associated consts are // not used as part of the type system, this is far less surprising. - self.with_lifetime_rib( - LifetimeRibKind::Elided(LifetimeRes::Anonymous { binder: item.id }), - |this| { - this.with_constant_rib( - IsRepeatExpr::No, - HasGenericParams::Yes, - None, - |this| this.visit_expr(expr), - ) - }, - ); + self.with_lifetime_rib(LifetimeRibKind::Elided(LifetimeRes::Infer), |this| { + this.with_constant_rib( + IsRepeatExpr::No, + HasGenericParams::Yes, + None, + |this| this.visit_expr(expr), + ) + }); } } AssocItemKind::Fn(box Fn { generics, .. }) => { diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs index e9cbbedc7b0b2..51aea02cb7a62 100644 --- a/compiler/rustc_resolve/src/late/lifetimes.rs +++ b/compiler/rustc_resolve/src/late/lifetimes.rs @@ -819,7 +819,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { // `Box`. self.resolve_object_lifetime_default(lifetime) } - LifetimeName::Underscore => { + LifetimeName::Infer => { // If the user writes `'_`, we use the *ordinary* elision // rules. So the `'_` in e.g., `Box` will be // resolved the same as the `'_` in `&'_ Foo`. @@ -1135,7 +1135,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { #[tracing::instrument(level = "debug", skip(self))] fn visit_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime) { match lifetime_ref.name { - hir::LifetimeName::ImplicitObjectLifetimeDefault | hir::LifetimeName::Underscore => { + hir::LifetimeName::ImplicitObjectLifetimeDefault | hir::LifetimeName::Infer => { self.resolve_elided_lifetimes(&[lifetime_ref]) } hir::LifetimeName::Static => self.insert_lifetime(lifetime_ref, Region::Static), diff --git a/src/tools/clippy/clippy_lints/src/manual_async_fn.rs b/src/tools/clippy/clippy_lints/src/manual_async_fn.rs index 945880d21471b..a0ca7e6ff1e22 100644 --- a/src/tools/clippy/clippy_lints/src/manual_async_fn.rs +++ b/src/tools/clippy/clippy_lints/src/manual_async_fn.rs @@ -166,7 +166,7 @@ fn captures_all_lifetimes(inputs: &[Ty<'_>], output_lifetimes: &[LifetimeName]) // - There's only one output lifetime bound using `+ '_` // - All input lifetimes are explicitly bound to the output input_lifetimes.is_empty() - || (output_lifetimes.len() == 1 && matches!(output_lifetimes[0], LifetimeName::Underscore)) + || (output_lifetimes.len() == 1 && matches!(output_lifetimes[0], LifetimeName::Infer)) || input_lifetimes .iter() .all(|in_lt| output_lifetimes.iter().any(|out_lt| in_lt == out_lt)) diff --git a/src/tools/clippy/clippy_lints/src/ptr.rs b/src/tools/clippy/clippy_lints/src/ptr.rs index 8534d8a29f10d..3c5ea2d94144f 100644 --- a/src/tools/clippy/clippy_lints/src/ptr.rs +++ b/src/tools/clippy/clippy_lints/src/ptr.rs @@ -351,7 +351,7 @@ impl fmt::Display for RefPrefix { name.fmt(f)?; f.write_char(' ')?; }, - LifetimeName::Underscore => f.write_str("'_ ")?, + LifetimeName::Infer => f.write_str("'_ ")?, LifetimeName::Static => f.write_str("'static ")?, _ => (), } From ae70e366f3b77c127f6cb799fcaab4de96974d5c Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 6 Jul 2022 18:27:43 +0200 Subject: [PATCH 04/10] Check that we do not ICE when anonymous lifetimes appear in AnonConst. Fixes #98932. --- .../constant-used-as-arraylen.rs | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 src/test/ui/impl-header-lifetime-elision/constant-used-as-arraylen.rs diff --git a/src/test/ui/impl-header-lifetime-elision/constant-used-as-arraylen.rs b/src/test/ui/impl-header-lifetime-elision/constant-used-as-arraylen.rs new file mode 100644 index 0000000000000..929b82bfc432e --- /dev/null +++ b/src/test/ui/impl-header-lifetime-elision/constant-used-as-arraylen.rs @@ -0,0 +1,24 @@ +// check-pass +// Verify that we do not ICE when anonymous lifetimes appear inside an AnonConst. + +pub struct EntriesBuffer(Box<[[u8; HashesEntry::LEN]; 5]>); + +impl EntriesBuffer { + pub fn iter_child_buffers(&mut self) -> impl Iterator { + self.0.iter_mut() + } + + pub fn iter_child_buffers_explicit( + &mut self, + ) -> impl Iterator::LEN]> { + self.0.iter_mut() + } +} + +pub struct HashesEntry<'a>(&'a [u8]); + +impl HashesEntry<'_> { + pub const LEN: usize = 1; +} + +fn main() {} From 267d3620a59c66a58d4d53f77d3f31e44f0f07fe Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 22 May 2022 23:31:39 +0200 Subject: [PATCH 05/10] Move fn parameter ribs outwards. --- compiler/rustc_resolve/src/late.rs | 98 +++++++++++++++++++----------- 1 file changed, 62 insertions(+), 36 deletions(-) diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index f5fb2585c748e..ed65100ae7751 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -695,14 +695,25 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> { }, |this| { this.visit_generic_params(&bare_fn.generic_params, false); - this.resolve_fn_signature( - ty.id, - None, - false, - // We don't need to deal with patterns in parameters, because - // they are not possible for foreign or bodiless functions. - bare_fn.decl.inputs.iter().map(|Param { ty, .. }| (None, &**ty)), - &bare_fn.decl.output, + this.with_lifetime_rib( + LifetimeRibKind::AnonymousCreateParameter { + binder: ty.id, + report_in_path: false, + }, + |this| { + this.resolve_fn_signature( + ty.id, + false, + // We don't need to deal with patterns in parameters, because + // they are not possible for foreign or bodiless functions. + bare_fn + .decl + .inputs + .iter() + .map(|Param { ty, .. }| (None, &**ty)), + &bare_fn.decl.output, + ) + }, ); }, ) @@ -782,12 +793,19 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> { | FnKind::Fn(_, _, sig, _, generics, None) => { self.visit_fn_header(&sig.header); self.visit_generics(generics); - self.resolve_fn_signature( - fn_id, - None, - sig.decl.has_self(), - sig.decl.inputs.iter().map(|Param { ty, .. }| (None, &**ty)), - &sig.decl.output, + self.with_lifetime_rib( + LifetimeRibKind::AnonymousCreateParameter { + binder: fn_id, + report_in_path: false, + }, + |this| { + this.resolve_fn_signature( + fn_id, + sig.decl.has_self(), + sig.decl.inputs.iter().map(|Param { ty, .. }| (None, &**ty)), + &sig.decl.output, + ) + }, ); return; } @@ -812,15 +830,22 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> { let declaration = &sig.decl; let async_node_id = sig.header.asyncness.opt_return_id(); - this.resolve_fn_signature( - fn_id, - async_node_id, - declaration.has_self(), - declaration - .inputs - .iter() - .map(|Param { pat, ty, .. }| (Some(&**pat), &**ty)), - &declaration.output, + this.with_lifetime_rib( + LifetimeRibKind::AnonymousCreateParameter { + binder: fn_id, + report_in_path: async_node_id.is_some(), + }, + |this| { + this.resolve_fn_signature( + fn_id, + declaration.has_self(), + declaration + .inputs + .iter() + .map(|Param { pat, ty, .. }| (Some(&**pat), &**ty)), + &declaration.output, + ) + }, ); // Construct the list of in-scope lifetime parameters for async lowering. @@ -1035,12 +1060,19 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> { kind: LifetimeBinderKind::PolyTrait, .. } => { - self.resolve_fn_signature( - binder, - None, - false, - p_args.inputs.iter().map(|ty| (None, &**ty)), - &p_args.output, + self.with_lifetime_rib( + LifetimeRibKind::AnonymousCreateParameter { + binder, + report_in_path: false, + }, + |this| { + this.resolve_fn_signature( + binder, + false, + p_args.inputs.iter().map(|ty| (None, &**ty)), + &p_args.output, + ) + }, ); break; } @@ -1813,18 +1845,12 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { fn resolve_fn_signature( &mut self, fn_id: NodeId, - async_node_id: Option, has_self: bool, inputs: impl Iterator, &'ast Ty)> + Clone, output_ty: &'ast FnRetTy, ) { // Add each argument to the rib. - let parameter_rib = LifetimeRibKind::AnonymousCreateParameter { - binder: fn_id, - report_in_path: async_node_id.is_some(), - }; - let elision_lifetime = - self.with_lifetime_rib(parameter_rib, |this| this.resolve_fn_params(has_self, inputs)); + let elision_lifetime = self.resolve_fn_params(has_self, inputs); debug!(?elision_lifetime); let outer_failures = take(&mut self.diagnostic_metadata.current_elision_failures); From 30565e5871ce59e1277879bcd391adf9f544b39e Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Mon, 23 May 2022 16:27:52 +0200 Subject: [PATCH 06/10] Stop resolving lifetime elision on HIR. --- compiler/rustc_resolve/src/late/lifetimes.rs | 477 ++----------------- 1 file changed, 52 insertions(+), 425 deletions(-) diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs index 51aea02cb7a62..c6af81ed507ce 100644 --- a/compiler/rustc_resolve/src/late/lifetimes.rs +++ b/compiler/rustc_resolve/src/late/lifetimes.rs @@ -21,7 +21,7 @@ use rustc_middle::hir::nested_filter; use rustc_middle::middle::resolve_lifetime::*; use rustc_middle::ty::{self, GenericParamDefKind, TyCtxt}; use rustc_span::def_id::DefId; -use rustc_span::symbol::{kw, sym, Ident}; +use rustc_span::symbol::{sym, Ident}; use rustc_span::Span; use std::borrow::Cow; use std::cell::Cell; @@ -215,9 +215,8 @@ enum Scope<'a> { }, /// A scope which either determines unspecified lifetimes or errors - /// on them (e.g., due to ambiguity). For more details, see `Elide`. + /// on them (e.g., due to ambiguity). Elision { - elide: Elide, s: ScopeRef<'a>, }, @@ -290,9 +289,7 @@ impl<'a> fmt::Debug for TruncatedScopeDebug<'a> { Scope::Body { id, s: _ } => { f.debug_struct("Body").field("id", id).field("s", &"..").finish() } - Scope::Elision { elide, s: _ } => { - f.debug_struct("Elision").field("elide", elide).field("s", &"..").finish() - } + Scope::Elision { s: _ } => f.debug_struct("Elision").field("s", &"..").finish(), Scope::ObjectLifetimeDefault { lifetime, s: _ } => f .debug_struct("ObjectLifetimeDefault") .field("lifetime", lifetime) @@ -309,21 +306,6 @@ impl<'a> fmt::Debug for TruncatedScopeDebug<'a> { } } -#[derive(Clone, Debug)] -enum Elide { - /// Use a fresh anonymous late-bound lifetime each time, by - /// incrementing the counter to generate sequential indices. All - /// anonymous lifetimes must start *after* named bound vars. - FreshLateAnon(u32, Cell), - /// Always use this one lifetime. - Exact(Region), - /// Less or more than one lifetime were found, error on unspecified. - Error, - /// Forbid lifetime elision inside of a larger scope where it would be - /// permitted. For example, in let position impl trait. - Forbid, -} - type ScopeRef<'a> = &'a Scope<'a>; const ROOT_SCOPE: ScopeRef<'static> = &Scope::Root; @@ -664,8 +646,9 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { } hir::ItemKind::Static(..) | hir::ItemKind::Const(..) => { // No lifetime parameters, but implied 'static. - let scope = Scope::Elision { elide: Elide::Exact(Region::Static), s: ROOT_SCOPE }; - self.with(scope, |this| intravisit::walk_item(this, item)); + self.with(Scope::Elision { s: self.scope }, |this| { + intravisit::walk_item(this, item) + }); } hir::ItemKind::OpaqueTy(hir::OpaqueTy { .. }) => { // Opaque types are visited when we visit the @@ -860,7 +843,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { // position impl Trait let scope = Scope::TraitRefBoundary { s: self.scope }; self.with(scope, |this| { - let scope = Scope::Elision { elide: Elide::Forbid, s: this.scope }; + let scope = Scope::Elision { s: this.scope }; this.with(scope, |this| { intravisit::walk_item(this, opaque_ty); }) @@ -936,7 +919,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { let mut index = self.next_early_index_for_opaque_type(); debug!(?index); - let mut elision = None; let mut lifetimes = FxIndexMap::default(); let mut non_lifetime_count = 0; debug!(?generics.params); @@ -945,15 +927,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { GenericParamKind::Lifetime { .. } => { let (def_id, reg) = Region::early(self.tcx.hir(), &mut index, ¶m); lifetimes.insert(def_id, reg); - if let hir::ParamName::Plain(Ident { - name: kw::UnderscoreLifetime, - .. - }) = param.name - { - // Pick the elided lifetime "definition" if one exists - // and use it to make an elision scope. - elision = Some(reg); - } } GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => { non_lifetime_count += 1; @@ -963,51 +936,25 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { let next_early_index = index + non_lifetime_count; self.map.late_bound_vars.insert(ty.hir_id, vec![]); - if let Some(elision_region) = elision { - let scope = - Scope::Elision { elide: Elide::Exact(elision_region), s: self.scope }; - self.with(scope, |this| { - let scope = Scope::Binder { - hir_id: ty.hir_id, - lifetimes, - next_early_index, - s: this.scope, - opaque_type_parent: false, - scope_type: BinderScopeType::Normal, - allow_late_bound: false, - where_bound_origin: None, - }; - this.with(scope, |this| { - this.visit_generics(generics); - let scope = Scope::TraitRefBoundary { s: this.scope }; - this.with(scope, |this| { - for bound in bounds { - this.visit_param_bound(bound); - } - }) - }); - }); - } else { - let scope = Scope::Binder { - hir_id: ty.hir_id, - lifetimes, - next_early_index, - s: self.scope, - opaque_type_parent: false, - scope_type: BinderScopeType::Normal, - allow_late_bound: false, - where_bound_origin: None, - }; - self.with(scope, |this| { - let scope = Scope::TraitRefBoundary { s: this.scope }; - this.with(scope, |this| { - this.visit_generics(generics); - for bound in bounds { - this.visit_param_bound(bound); - } - }) - }); - } + let scope = Scope::Binder { + hir_id: ty.hir_id, + lifetimes, + next_early_index, + s: self.scope, + opaque_type_parent: false, + scope_type: BinderScopeType::Normal, + allow_late_bound: false, + where_bound_origin: None, + }; + self.with(scope, |this| { + let scope = Scope::TraitRefBoundary { s: this.scope }; + this.with(scope, |this| { + this.visit_generics(generics); + for bound in bounds { + this.visit_param_bound(bound); + } + }) + }); } _ => intravisit::walk_ty(self, ty), } @@ -1156,12 +1103,21 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { } } - fn visit_fn_decl(&mut self, fd: &'tcx hir::FnDecl<'tcx>) { + fn visit_fn( + &mut self, + fk: intravisit::FnKind<'tcx>, + fd: &'tcx hir::FnDecl<'tcx>, + body_id: hir::BodyId, + _: Span, + _: hir::HirId, + ) { let output = match fd.output { hir::FnRetTy::DefaultReturn(_) => None, hir::FnRetTy::Return(ref ty) => Some(&**ty), }; - self.visit_fn_like_elision(&fd.inputs, output); + self.visit_fn_like_elision(&fd.inputs, output, matches!(fk, intravisit::FnKind::Closure)); + intravisit::walk_fn_kind(self, fk); + self.visit_nested_body(body_id) } fn visit_generics(&mut self, generics: &'tcx hir::Generics<'tcx>) { @@ -1773,7 +1729,11 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { ); if generic_args.parenthesized { - self.visit_fn_like_elision(generic_args.inputs(), Some(generic_args.bindings[0].ty())); + self.visit_fn_like_elision( + generic_args.inputs(), + Some(generic_args.bindings[0].ty()), + false, + ); return; } @@ -2052,319 +2012,18 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { &mut self, inputs: &'tcx [hir::Ty<'tcx>], output: Option<&'tcx hir::Ty<'tcx>>, + in_closure: bool, ) { - debug!("visit_fn_like_elision: enter"); - let mut scope = &*self.scope; - let hir_id = loop { - match scope { - Scope::Binder { hir_id, allow_late_bound: true, .. } => { - break *hir_id; - } - Scope::ObjectLifetimeDefault { ref s, .. } - | Scope::Elision { ref s, .. } - | Scope::Supertrait { ref s, .. } - | Scope::TraitRefBoundary { ref s, .. } => { - scope = *s; - } - Scope::Root - | Scope::Body { .. } - | Scope::Binder { allow_late_bound: false, .. } => { - // See issues #83907 and #83693. Just bail out from looking inside. - // See the issue #95023 for not allowing late bound - self.tcx.sess.delay_span_bug( - rustc_span::DUMMY_SP, - "In fn_like_elision without appropriate scope above", - ); - return; - } - } - }; - // While not strictly necessary, we gather anon lifetimes *before* actually - // visiting the argument types. - let mut gather = GatherAnonLifetimes { anon_count: 0 }; - for input in inputs { - gather.visit_ty(input); - } - trace!(?gather.anon_count); - let late_bound_vars = self.map.late_bound_vars.entry(hir_id).or_default(); - let named_late_bound_vars = late_bound_vars.len() as u32; - late_bound_vars.extend( - (0..gather.anon_count).map(|var| ty::BoundVariableKind::Region(ty::BrAnon(var))), - ); - let arg_scope = Scope::Elision { - elide: Elide::FreshLateAnon(named_late_bound_vars, Cell::new(0)), - s: self.scope, - }; - self.with(arg_scope, |this| { + self.with(Scope::Elision { s: self.scope }, |this| { for input in inputs { this.visit_ty(input); } - }); - - let Some(output) = output else { return }; - - debug!("determine output"); - - // Figure out if there's a body we can get argument names from, - // and whether there's a `self` argument (treated specially). - let mut assoc_item_kind = None; - let mut impl_self = None; - let parent = self.tcx.hir().get_parent_node(output.hir_id); - match self.tcx.hir().get(parent) { - // `fn` definitions and methods. - Node::Item(&hir::Item { kind: hir::ItemKind::Fn(..), .. }) => {} - - Node::TraitItem(&hir::TraitItem { kind: hir::TraitItemKind::Fn(..), .. }) => { - if let hir::ItemKind::Trait(.., ref trait_items) = - self.tcx.hir().expect_item(self.tcx.hir().get_parent_item(parent)).kind - { - assoc_item_kind = - trait_items.iter().find(|ti| ti.id.hir_id() == parent).map(|ti| ti.kind); - } - } - - Node::ImplItem(&hir::ImplItem { kind: hir::ImplItemKind::Fn(_, _), .. }) => { - if let hir::ItemKind::Impl(hir::Impl { ref self_ty, ref items, .. }) = - self.tcx.hir().expect_item(self.tcx.hir().get_parent_item(parent)).kind - { - impl_self = Some(self_ty); - assoc_item_kind = - items.iter().find(|ii| ii.id.hir_id() == parent).map(|ii| ii.kind); - } - } - - // Foreign functions, `fn(...) -> R` and `Trait(...) -> R` (both types and bounds). - Node::ForeignItem(_) | Node::Ty(_) | Node::TraitRef(_) => {}, - - Node::TypeBinding(_) if let Node::TraitRef(_) = self.tcx.hir().get(self.tcx.hir().get_parent_node(parent)) => {}, - - // Everything else (only closures?) doesn't - // actually enjoy elision in return types. - _ => { - self.visit_ty(output); - return; - } - }; - - let has_self = match assoc_item_kind { - Some(hir::AssocItemKind::Fn { has_self }) => has_self, - _ => false, - }; - - // In accordance with the rules for lifetime elision, we can determine - // what region to use for elision in the output type in two ways. - // First (determined here), if `self` is by-reference, then the - // implied output region is the region of the self parameter. - if has_self { - struct SelfVisitor<'a> { - map: &'a NamedRegionMap, - impl_self: Option<&'a hir::TyKind<'a>>, - lifetime: Set1, - } - - impl SelfVisitor<'_> { - // Look for `self: &'a Self` - also desugared from `&'a self`, - // and if that matches, use it for elision and return early. - fn is_self_ty(&self, res: Res) -> bool { - if let Res::SelfTy { .. } = res { - return true; - } - - // Can't always rely on literal (or implied) `Self` due - // to the way elision rules were originally specified. - if let Some(&hir::TyKind::Path(hir::QPath::Resolved(None, ref path))) = - self.impl_self - { - match path.res { - // Permit the types that unambiguously always - // result in the same type constructor being used - // (it can't differ between `Self` and `self`). - Res::Def(DefKind::Struct | DefKind::Union | DefKind::Enum, _) - | Res::PrimTy(_) => return res == path.res, - _ => {} - } - } - - false - } - } - - impl<'a> Visitor<'a> for SelfVisitor<'a> { - fn visit_ty(&mut self, ty: &'a hir::Ty<'a>) { - if let hir::TyKind::Rptr(lifetime_ref, ref mt) = ty.kind { - if let hir::TyKind::Path(hir::QPath::Resolved(None, ref path)) = mt.ty.kind - { - if self.is_self_ty(path.res) { - if let Some(lifetime) = self.map.defs.get(&lifetime_ref.hir_id) { - self.lifetime.insert(*lifetime); - } - } - } - } - intravisit::walk_ty(self, ty) - } - } - - let mut visitor = SelfVisitor { - map: self.map, - impl_self: impl_self.map(|ty| &ty.kind), - lifetime: Set1::Empty, - }; - visitor.visit_ty(&inputs[0]); - if let Set1::One(lifetime) = visitor.lifetime { - let scope = Scope::Elision { elide: Elide::Exact(lifetime), s: self.scope }; - self.with(scope, |this| this.visit_ty(output)); - return; - } - } - - // Second, if there was exactly one lifetime (either a substitution or a - // reference) in the arguments, then any anonymous regions in the output - // have that lifetime. - let mut possible_implied_output_region = None; - let mut lifetime_count = 0; - for input in inputs.iter().skip(has_self as usize) { - let mut gather = GatherLifetimes { - map: self.map, - outer_index: ty::INNERMOST, - have_bound_regions: false, - lifetimes: Default::default(), - }; - gather.visit_ty(input); - - lifetime_count += gather.lifetimes.len(); - - if lifetime_count == 1 && gather.lifetimes.len() == 1 { - // there's a chance that the unique lifetime of this - // iteration will be the appropriate lifetime for output - // parameters, so lets store it. - possible_implied_output_region = gather.lifetimes.iter().cloned().next(); - } - } - - let elide = if lifetime_count == 1 { - Elide::Exact(possible_implied_output_region.unwrap()) - } else { - Elide::Error - }; - - debug!(?elide); - - let scope = Scope::Elision { elide, s: self.scope }; - self.with(scope, |this| this.visit_ty(output)); - - struct GatherLifetimes<'a> { - map: &'a NamedRegionMap, - outer_index: ty::DebruijnIndex, - have_bound_regions: bool, - lifetimes: FxHashSet, - } - - impl<'v, 'a> Visitor<'v> for GatherLifetimes<'a> { - fn visit_ty(&mut self, ty: &hir::Ty<'_>) { - if let hir::TyKind::BareFn(_) = ty.kind { - self.outer_index.shift_in(1); - } - match ty.kind { - hir::TyKind::TraitObject(bounds, ref lifetime, _) => { - for bound in bounds { - self.visit_poly_trait_ref(bound, hir::TraitBoundModifier::None); - } - - // Stay on the safe side and don't include the object - // lifetime default (which may not end up being used). - if !lifetime.is_elided() { - self.visit_lifetime(lifetime); - } - } - _ => { - intravisit::walk_ty(self, ty); - } - } - if let hir::TyKind::BareFn(_) = ty.kind { - self.outer_index.shift_out(1); - } - } - - fn visit_generic_param(&mut self, param: &hir::GenericParam<'_>) { - if let hir::GenericParamKind::Lifetime { .. } = param.kind { - // FIXME(eddyb) Do we want this? It only makes a difference - // if this `for<'a>` lifetime parameter is never used. - self.have_bound_regions = true; - } - - intravisit::walk_generic_param(self, param); - } - - fn visit_poly_trait_ref( - &mut self, - trait_ref: &hir::PolyTraitRef<'_>, - modifier: hir::TraitBoundModifier, - ) { - self.outer_index.shift_in(1); - intravisit::walk_poly_trait_ref(self, trait_ref, modifier); - self.outer_index.shift_out(1); - } - - fn visit_param_bound(&mut self, bound: &hir::GenericBound<'_>) { - if let hir::GenericBound::LangItemTrait { .. } = bound { - self.outer_index.shift_in(1); - intravisit::walk_param_bound(self, bound); - self.outer_index.shift_out(1); - } else { - intravisit::walk_param_bound(self, bound); - } - } - - fn visit_lifetime(&mut self, lifetime_ref: &hir::Lifetime) { - if let Some(&lifetime) = self.map.defs.get(&lifetime_ref.hir_id) { - match lifetime { - Region::LateBound(debruijn, _, _) - | Region::LateBoundAnon(debruijn, _, _) - if debruijn < self.outer_index => - { - self.have_bound_regions = true; - } - _ => { - // FIXME(jackh726): nested trait refs? - self.lifetimes.insert(lifetime.shifted_out_to_binder(self.outer_index)); - } - } - } - } - } - - struct GatherAnonLifetimes { - anon_count: u32, - } - impl<'v> Visitor<'v> for GatherAnonLifetimes { - #[instrument(skip(self), level = "trace")] - fn visit_ty(&mut self, ty: &hir::Ty<'_>) { - // If we enter a `BareFn`, then we enter a *new* binding scope - if let hir::TyKind::BareFn(_) = ty.kind { - return; - } - intravisit::walk_ty(self, ty); - } - - fn visit_generic_args( - &mut self, - path_span: Span, - generic_args: &'v hir::GenericArgs<'v>, - ) { - // parenthesized args enter a new elision scope - if generic_args.parenthesized { - return; - } - intravisit::walk_generic_args(self, path_span, generic_args) - } - - #[instrument(skip(self), level = "trace")] - fn visit_lifetime(&mut self, lifetime_ref: &hir::Lifetime) { - if lifetime_ref.is_elided() { - self.anon_count += 1; - } + if !in_closure && let Some(output) = output { + this.visit_ty(output); } + }); + if in_closure && let Some(output) = output { + self.visit_ty(output); } } @@ -2375,48 +2034,16 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { return; } - let mut late_depth = 0; let mut scope = self.scope; loop { match *scope { // Do not assign any resolution, it will be inferred. Scope::Body { .. } => return, - Scope::Root => break, - - Scope::Binder { s, scope_type, .. } => { - match scope_type { - BinderScopeType::Normal => late_depth += 1, - BinderScopeType::Concatenating => {} - } - scope = s; - } - - Scope::Elision { - elide: Elide::FreshLateAnon(named_late_bound_vars, ref counter), - .. - } => { - for lifetime_ref in lifetime_refs { - let lifetime = - Region::late_anon(named_late_bound_vars, counter).shifted(late_depth); + Scope::Root | Scope::Elision { .. } => break, - self.insert_lifetime(lifetime_ref, lifetime); - } - return; - } - - Scope::Elision { elide: Elide::Exact(l), .. } => { - let lifetime = l.shifted(late_depth); - for lifetime_ref in lifetime_refs { - self.insert_lifetime(lifetime_ref, lifetime); - } - return; - } - - Scope::Elision { elide: Elide::Error, .. } - | Scope::Elision { elide: Elide::Forbid, .. } => break, - - Scope::ObjectLifetimeDefault { s, .. } + Scope::Binder { s, .. } + | Scope::ObjectLifetimeDefault { s, .. } | Scope::Supertrait { s, .. } | Scope::TraitRefBoundary { s, .. } => { scope = s; From ad1b1819eb65e30b8351e14b93bfac8740077242 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Mon, 23 May 2022 17:03:14 +0200 Subject: [PATCH 07/10] Remove resolve_elided_lifetimes. --- compiler/rustc_resolve/src/late/lifetimes.rs | 59 ++------------------ 1 file changed, 6 insertions(+), 53 deletions(-) diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs index c6af81ed507ce..7b751c663d24b 100644 --- a/compiler/rustc_resolve/src/late/lifetimes.rs +++ b/compiler/rustc_resolve/src/late/lifetimes.rs @@ -808,7 +808,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { // resolved the same as the `'_` in `&'_ Foo`. // // cc #48468 - self.resolve_elided_lifetimes(&[lifetime]) } LifetimeName::Param(..) | LifetimeName::Static => { // If the user wrote an explicit name, use that. @@ -1082,15 +1081,14 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { #[tracing::instrument(level = "debug", skip(self))] fn visit_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime) { match lifetime_ref.name { - hir::LifetimeName::ImplicitObjectLifetimeDefault | hir::LifetimeName::Infer => { - self.resolve_elided_lifetimes(&[lifetime_ref]) - } hir::LifetimeName::Static => self.insert_lifetime(lifetime_ref, Region::Static), hir::LifetimeName::Param(param_def_id, _) => { self.resolve_lifetime_ref(param_def_id, lifetime_ref) } // If we've already reported an error, just ignore `lifetime_ref`. hir::LifetimeName::Error => {} + // Those will be resolved by typechecking. + hir::LifetimeName::ImplicitObjectLifetimeDefault | hir::LifetimeName::Infer => {} } } @@ -1737,26 +1735,10 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { return; } - let mut elide_lifetimes = true; - let lifetimes: Vec<_> = generic_args - .args - .iter() - .filter_map(|arg| match arg { - hir::GenericArg::Lifetime(lt) => { - if !lt.is_elided() { - elide_lifetimes = false; - } - Some(lt) - } - _ => None, - }) - .collect(); - // We short-circuit here if all are elided in order to pluralize - // possible errors - if elide_lifetimes { - self.resolve_elided_lifetimes(&lifetimes); - } else { - lifetimes.iter().for_each(|lt| self.visit_lifetime(lt)); + for arg in generic_args.args { + if let hir::GenericArg::Lifetime(lt) = arg { + self.visit_lifetime(lt); + } } // Figure out if this is a type/trait segment, @@ -2027,35 +2009,6 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } } - fn resolve_elided_lifetimes(&mut self, lifetime_refs: &[&'tcx hir::Lifetime]) { - debug!("resolve_elided_lifetimes(lifetime_refs={:?})", lifetime_refs); - - if lifetime_refs.is_empty() { - return; - } - - let mut scope = self.scope; - loop { - match *scope { - // Do not assign any resolution, it will be inferred. - Scope::Body { .. } => return, - - Scope::Root | Scope::Elision { .. } => break, - - Scope::Binder { s, .. } - | Scope::ObjectLifetimeDefault { s, .. } - | Scope::Supertrait { s, .. } - | Scope::TraitRefBoundary { s, .. } => { - scope = s; - } - } - } - - for lt in lifetime_refs { - self.tcx.sess.delay_span_bug(lt.span, "Missing lifetime specifier"); - } - } - fn resolve_object_lifetime_default(&mut self, lifetime_ref: &'tcx hir::Lifetime) { debug!("resolve_object_lifetime_default(lifetime_ref={:?})", lifetime_ref); let mut late_depth = 0; From 556b02704f338e121d5129c714d774bff67bf35c Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 24 May 2022 08:23:24 +0200 Subject: [PATCH 08/10] Stop creating anonymous late lifetimes. --- .../nice_region_error/find_anon_type.rs | 31 +--------------- .../src/middle/resolve_lifetime.rs | 1 - compiler/rustc_resolve/src/late/lifetimes.rs | 37 +------------------ compiler/rustc_typeck/src/astconv/mod.rs | 8 ---- compiler/rustc_typeck/src/collect.rs | 12 +----- 5 files changed, 4 insertions(+), 85 deletions(-) diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs index e5ae835e81349..c1b201da69121 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs @@ -100,23 +100,6 @@ impl<'tcx> Visitor<'tcx> for FindNestedTypeVisitor<'tcx> { // the lifetime of the TyRptr let hir_id = lifetime.hir_id; match (self.tcx.named_region(hir_id), self.bound_region) { - // Find the index of the anonymous region that was part of the - // error. We will then search the function parameters for a bound - // region at the right depth with the same index - ( - Some(rl::Region::LateBoundAnon(debruijn_index, _, anon_index)), - ty::BrAnon(br_index), - ) => { - debug!( - "LateBoundAnon depth = {:?} anon_index = {:?} br_index={:?}", - debruijn_index, anon_index, br_index - ); - if debruijn_index == self.current_index && anon_index == br_index { - self.found_type = Some(arg); - return; // we can stop visiting now - } - } - // Find the index of the named region that was part of the // error. We will then search the function parameters for a bound // region at the right depth with the same index @@ -151,8 +134,7 @@ impl<'tcx> Visitor<'tcx> for FindNestedTypeVisitor<'tcx> { rl::Region::Static | rl::Region::Free(_, _) | rl::Region::EarlyBound(_, _) - | rl::Region::LateBound(_, _, _) - | rl::Region::LateBoundAnon(_, _, _), + | rl::Region::LateBound(_, _, _), ) | None, _, @@ -206,16 +188,6 @@ impl<'tcx> Visitor<'tcx> for TyPathVisitor<'tcx> { fn visit_lifetime(&mut self, lifetime: &hir::Lifetime) { match (self.tcx.named_region(lifetime.hir_id), self.bound_region) { // the lifetime of the TyPath! - ( - Some(rl::Region::LateBoundAnon(debruijn_index, _, anon_index)), - ty::BrAnon(br_index), - ) => { - if debruijn_index == self.current_index && anon_index == br_index { - self.found_it = true; - return; - } - } - (Some(rl::Region::EarlyBound(_, id)), ty::BrNamed(def_id, _)) => { debug!("EarlyBound id={:?} def_id={:?}", id, def_id); if id == def_id { @@ -239,7 +211,6 @@ impl<'tcx> Visitor<'tcx> for TyPathVisitor<'tcx> { rl::Region::Static | rl::Region::EarlyBound(_, _) | rl::Region::LateBound(_, _, _) - | rl::Region::LateBoundAnon(_, _, _) | rl::Region::Free(_, _), ) | None, diff --git a/compiler/rustc_middle/src/middle/resolve_lifetime.rs b/compiler/rustc_middle/src/middle/resolve_lifetime.rs index c71ba7b175313..9b2f445670532 100644 --- a/compiler/rustc_middle/src/middle/resolve_lifetime.rs +++ b/compiler/rustc_middle/src/middle/resolve_lifetime.rs @@ -12,7 +12,6 @@ pub enum Region { Static, EarlyBound(/* index */ u32, /* lifetime decl */ DefId), LateBound(ty::DebruijnIndex, /* late-bound index */ u32, /* lifetime decl */ DefId), - LateBoundAnon(ty::DebruijnIndex, /* late-bound index */ u32, /* anon index */ u32), Free(DefId, /* lifetime decl */ DefId), } diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs index 7b751c663d24b..1d83d57fe383c 100644 --- a/compiler/rustc_resolve/src/late/lifetimes.rs +++ b/compiler/rustc_resolve/src/late/lifetimes.rs @@ -24,7 +24,6 @@ use rustc_span::def_id::DefId; use rustc_span::symbol::{sym, Ident}; use rustc_span::Span; use std::borrow::Cow; -use std::cell::Cell; use std::fmt; use std::mem::take; @@ -33,8 +32,6 @@ trait RegionExt { fn late(index: u32, hir_map: Map<'_>, param: &GenericParam<'_>) -> (LocalDefId, Region); - fn late_anon(named_late_bound_vars: u32, index: &Cell) -> Region; - fn id(&self) -> Option; fn shifted(self, amount: u32) -> Region; @@ -65,16 +62,9 @@ impl RegionExt for Region { (def_id, Region::LateBound(depth, idx, def_id.to_def_id())) } - fn late_anon(named_late_bound_vars: u32, index: &Cell) -> Region { - let i = index.get(); - index.set(i + 1); - let depth = ty::INNERMOST; - Region::LateBoundAnon(depth, named_late_bound_vars + i, i) - } - fn id(&self) -> Option { match *self { - Region::Static | Region::LateBoundAnon(..) => None, + Region::Static => None, Region::EarlyBound(_, id) | Region::LateBound(_, _, id) | Region::Free(_, id) => { Some(id) @@ -87,9 +77,6 @@ impl RegionExt for Region { Region::LateBound(debruijn, idx, id) => { Region::LateBound(debruijn.shifted_in(amount), idx, id) } - Region::LateBoundAnon(debruijn, index, anon_index) => { - Region::LateBoundAnon(debruijn.shifted_in(amount), index, anon_index) - } _ => self, } } @@ -99,9 +86,6 @@ impl RegionExt for Region { Region::LateBound(debruijn, index, id) => { Region::LateBound(debruijn.shifted_out_to_binder(binder), index, id) } - Region::LateBoundAnon(debruijn, index, anon_index) => { - Region::LateBoundAnon(debruijn.shifted_out_to_binder(binder), index, anon_index) - } _ => self, } } @@ -193,10 +177,6 @@ enum Scope<'a> { s: ScopeRef<'a>, - /// In some cases not allowing late bounds allows us to avoid ICEs. - /// This is almost ways set to true. - allow_late_bound: bool, - /// If this binder comes from a where clause, specify how it was created. /// This is used to diagnose inaccessible lifetimes in APIT: /// ```ignore (illustrative) @@ -272,7 +252,6 @@ impl<'a> fmt::Debug for TruncatedScopeDebug<'a> { opaque_type_parent, scope_type, hir_id, - allow_late_bound, where_bound_origin, s: _, } => f @@ -282,7 +261,6 @@ impl<'a> fmt::Debug for TruncatedScopeDebug<'a> { .field("opaque_type_parent", opaque_type_parent) .field("scope_type", scope_type) .field("hir_id", hir_id) - .field("allow_late_bound", allow_late_bound) .field("where_bound_origin", where_bound_origin) .field("s", &"..") .finish(), @@ -468,9 +446,6 @@ fn late_region_as_bound_region<'tcx>(tcx: TyCtxt<'tcx>, region: &Region) -> ty:: let name = tcx.hir().name(tcx.hir().local_def_id_to_hir_id(def_id.expect_local())); ty::BoundVariableKind::Region(ty::BrNamed(*def_id, name)) } - Region::LateBoundAnon(_, _, anon_idx) => { - ty::BoundVariableKind::Region(ty::BrAnon(*anon_idx)) - } _ => bug!("{:?} is not a late region", region), } } @@ -605,7 +580,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { next_early_index, opaque_type_parent: false, scope_type: BinderScopeType::Normal, - allow_late_bound: true, where_bound_origin: None, }; @@ -724,7 +698,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { opaque_type_parent: true, scope_type: BinderScopeType::Normal, s: ROOT_SCOPE, - allow_late_bound: false, where_bound_origin: None, }; self.with(scope, |this| { @@ -777,7 +750,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { next_early_index, opaque_type_parent: false, scope_type: BinderScopeType::Normal, - allow_late_bound: true, where_bound_origin: None, }; self.with(scope, |this| { @@ -942,7 +914,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { s: self.scope, opaque_type_parent: false, scope_type: BinderScopeType::Normal, - allow_late_bound: false, where_bound_origin: None, }; self.with(scope, |this| { @@ -997,7 +968,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { s: self.scope, opaque_type_parent: true, scope_type: BinderScopeType::Normal, - allow_late_bound: false, where_bound_origin: None, }; self.with(scope, |this| { @@ -1059,7 +1029,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { s: self.scope, opaque_type_parent: true, scope_type: BinderScopeType::Normal, - allow_late_bound: true, where_bound_origin: None, }; self.with(scope, |this| { @@ -1173,7 +1142,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { next_early_index, opaque_type_parent: false, scope_type: BinderScopeType::Normal, - allow_late_bound: true, where_bound_origin: Some(origin), }; this.with(scope, |this| { @@ -1246,7 +1214,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { next_early_index: self.next_early_index(), opaque_type_parent: false, scope_type, - allow_late_bound: true, where_bound_origin: None, }; self.with(scope, |this| { @@ -1297,7 +1264,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { next_early_index, opaque_type_parent: false, scope_type, - allow_late_bound: true, where_bound_origin: None, }; self.with(scope, |this| { @@ -1551,7 +1517,6 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { s: self.scope, opaque_type_parent: true, scope_type: BinderScopeType::Normal, - allow_late_bound: true, where_bound_origin: None, }; self.with(scope, walk); diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index 58f4f02052f8b..08e8e6f7d0f40 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -221,14 +221,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { tcx.mk_region(ty::ReLateBound(debruijn, br)) } - Some(rl::Region::LateBoundAnon(debruijn, index, anon_index)) => { - let br = ty::BoundRegion { - var: ty::BoundVar::from_u32(index), - kind: ty::BrAnon(anon_index), - }; - tcx.mk_region(ty::ReLateBound(debruijn, br)) - } - Some(rl::Region::EarlyBound(index, id)) => { let name = lifetime_name(id.expect_local()); tcx.mk_region(ty::ReEarlyBound(ty::EarlyBoundRegion { def_id: id, index, name })) diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 0fcbfa734f8fe..d725c9d28ac1a 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -1346,16 +1346,8 @@ fn has_late_bound_regions<'tcx>(tcx: TyCtxt<'tcx>, node: Node<'tcx>) -> Option {} - Some( - rl::Region::LateBound(debruijn, _, _) - | rl::Region::LateBoundAnon(debruijn, _, _), - ) if debruijn < self.outer_index => {} - Some( - rl::Region::LateBound(..) - | rl::Region::LateBoundAnon(..) - | rl::Region::Free(..), - ) - | None => { + Some(rl::Region::LateBound(debruijn, _, _)) if debruijn < self.outer_index => {} + Some(rl::Region::LateBound(..) | rl::Region::Free(..)) | None => { self.has_late_bound_regions = Some(lt.span); } } From e2b8f0d55c3594b3bc1797131421f63edcfbe81d Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Mon, 13 Jun 2022 11:53:31 +0200 Subject: [PATCH 09/10] Clippy fallout. --- src/tools/clippy/clippy_lints/src/lifetimes.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/clippy/clippy_lints/src/lifetimes.rs b/src/tools/clippy/clippy_lints/src/lifetimes.rs index 826353aafc069..3f69cc2038839 100644 --- a/src/tools/clippy/clippy_lints/src/lifetimes.rs +++ b/src/tools/clippy/clippy_lints/src/lifetimes.rs @@ -615,7 +615,7 @@ struct BodyLifetimeChecker { impl<'tcx> Visitor<'tcx> for BodyLifetimeChecker { // for lifetimes as parameters of generics fn visit_lifetime(&mut self, lifetime: &'tcx Lifetime) { - if lifetime.name.ident().name != kw::Empty && lifetime.name.ident().name != kw::StaticLifetime { + if lifetime.name.ident().name != kw::UnderscoreLifetime && lifetime.name.ident().name != kw::StaticLifetime { self.lifetimes_used_in_body = true; } } From 4b2f06b8a91fde63a744c4b297030893d4a92c92 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 19 Jun 2022 16:35:16 +0200 Subject: [PATCH 10/10] Pacify tidy. --- compiler/rustc_resolve/src/late/lifetimes.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs index 1d83d57fe383c..94460e33d8b01 100644 --- a/compiler/rustc_resolve/src/late/lifetimes.rs +++ b/compiler/rustc_resolve/src/late/lifetimes.rs @@ -1,4 +1,3 @@ -// ignore-tidy-filelength //! Resolution of early vs late bound lifetimes. //! //! Name resolution for lifetimes is performed on the AST and embedded into HIR. From this