Skip to content

Add a new mismatched-lifetime-syntaxes lint #138677

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions compiler/rustc_ast_lowering/src/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use rustc_ast::*;
use rustc_errors::ErrorGuaranteed;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId};
use rustc_hir::{self as hir, HirId, IsAnonInPath, PredicateOrigin};
use rustc_hir::{self as hir, HirId, LifetimeSource, PredicateOrigin};
use rustc_index::{IndexSlice, IndexVec};
use rustc_middle::ty::{ResolverAstLowering, TyCtxt};
use rustc_span::edit_distance::find_best_match_for_name;
Expand Down Expand Up @@ -1861,7 +1861,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
GenericParamKind::Lifetime => {
let lt_id = self.next_node_id();
let lifetime = self.new_named_lifetime(id, lt_id, ident, IsAnonInPath::No);
let lifetime =
self.new_named_lifetime(id, lt_id, ident, LifetimeSource::Other, ident.into());
hir::WherePredicateKind::RegionPredicate(hir::WhereRegionPredicate {
lifetime,
bounds,
Expand Down Expand Up @@ -1894,7 +1895,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
}),
WherePredicateKind::RegionPredicate(WhereRegionPredicate { lifetime, bounds }) => {
hir::WherePredicateKind::RegionPredicate(hir::WhereRegionPredicate {
lifetime: self.lower_lifetime(lifetime),
lifetime: self.lower_lifetime(
lifetime,
LifetimeSource::Other,
lifetime.ident.into(),
),
bounds: self.lower_param_bounds(
bounds,
ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
Expand Down
121 changes: 73 additions & 48 deletions compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ use rustc_errors::{DiagArgFromDisplay, DiagCtxtHandle, StashKey};
use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res};
use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE, LocalDefId};
use rustc_hir::{
self as hir, ConstArg, GenericArg, HirId, IsAnonInPath, ItemLocalMap, LangItem, ParamName,
TraitCandidate,
self as hir, ConstArg, GenericArg, HirId, ItemLocalMap, LangItem, LifetimeSource,
LifetimeSyntax, ParamName, TraitCandidate,
};
use rustc_index::{Idx, IndexSlice, IndexVec};
use rustc_macros::extension;
Expand Down Expand Up @@ -1080,7 +1080,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
itctx: ImplTraitContext,
) -> hir::GenericArg<'hir> {
match arg {
ast::GenericArg::Lifetime(lt) => GenericArg::Lifetime(self.lower_lifetime(lt)),
ast::GenericArg::Lifetime(lt) => GenericArg::Lifetime(self.lower_lifetime(
lt,
LifetimeSource::Path { with_angle_brackets: true },
lt.ident.into(),
)),
ast::GenericArg::Type(ty) => {
// We cannot just match on `TyKind::Infer` as `(_)` is represented as
// `TyKind::Paren(TyKind::Infer)` and should also be lowered to `GenericArg::Infer`
Expand Down Expand Up @@ -1199,35 +1203,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
TyKind::Slice(ty) => hir::TyKind::Slice(self.lower_ty(ty, itctx)),
TyKind::Ptr(mt) => hir::TyKind::Ptr(self.lower_mt(mt, itctx)),
TyKind::Ref(region, mt) => {
let region = region.unwrap_or_else(|| {
let id = if let Some(LifetimeRes::ElidedAnchor { start, end }) =
self.resolver.get_lifetime_res(t.id)
{
debug_assert_eq!(start.plus(1), end);
start
} else {
self.next_node_id()
};
let span = self.tcx.sess.source_map().start_point(t.span).shrink_to_hi();
Lifetime { ident: Ident::new(kw::UnderscoreLifetime, span), id }
});
let lifetime = self.lower_lifetime(&region);
let lifetime = self.lower_ty_direct_lifetime(t, *region);
hir::TyKind::Ref(lifetime, self.lower_mt(mt, itctx))
}
TyKind::PinnedRef(region, mt) => {
let region = region.unwrap_or_else(|| {
let id = if let Some(LifetimeRes::ElidedAnchor { start, end }) =
self.resolver.get_lifetime_res(t.id)
{
debug_assert_eq!(start.plus(1), end);
start
} else {
self.next_node_id()
};
let span = self.tcx.sess.source_map().start_point(t.span).shrink_to_hi();
Lifetime { ident: Ident::new(kw::UnderscoreLifetime, span), id }
});
let lifetime = self.lower_lifetime(&region);
let lifetime = self.lower_ty_direct_lifetime(t, *region);
let kind = hir::TyKind::Ref(lifetime, self.lower_mt(mt, itctx));
let span = self.lower_span(t.span);
let arg = hir::Ty { kind, span, hir_id: self.next_id() };
Expand Down Expand Up @@ -1303,7 +1283,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}
GenericBound::Outlives(lifetime) => {
if lifetime_bound.is_none() {
lifetime_bound = Some(this.lower_lifetime(lifetime));
lifetime_bound = Some(this.lower_lifetime(
lifetime,
LifetimeSource::Other,
lifetime.ident.into(),
));
}
None
}
Expand Down Expand Up @@ -1394,6 +1378,31 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
hir::Ty { kind, span: self.lower_span(t.span), hir_id: self.lower_node_id(t.id) }
}

fn lower_ty_direct_lifetime(
&mut self,
t: &Ty,
region: Option<Lifetime>,
) -> &'hir hir::Lifetime {
let (region, syntax) = match region {
Some(region) => (region, region.ident.into()),

None => {
let id = if let Some(LifetimeRes::ElidedAnchor { start, end }) =
self.resolver.get_lifetime_res(t.id)
{
debug_assert_eq!(start.plus(1), end);
start
} else {
self.next_node_id()
};
let span = self.tcx.sess.source_map().start_point(t.span).shrink_to_hi();
let region = Lifetime { ident: Ident::new(kw::UnderscoreLifetime, span), id };
(region, LifetimeSyntax::Hidden)
}
};
self.lower_lifetime(&region, LifetimeSource::Reference, syntax)
}

/// Lowers a `ReturnPositionOpaqueTy` (`-> impl Trait`) or a `TypeAliasesOpaqueTy` (`type F =
/// impl Trait`): this creates the associated Opaque Type (TAIT) definition and then returns a
/// HIR type that references the TAIT.
Expand Down Expand Up @@ -1475,9 +1484,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
precise_capturing_args: &[PreciseCapturingArg],
) -> &'hir [hir::PreciseCapturingArg<'hir>] {
self.arena.alloc_from_iter(precise_capturing_args.iter().map(|arg| match arg {
PreciseCapturingArg::Lifetime(lt) => {
hir::PreciseCapturingArg::Lifetime(self.lower_lifetime(lt))
}
PreciseCapturingArg::Lifetime(lt) => hir::PreciseCapturingArg::Lifetime(
self.lower_lifetime(lt, LifetimeSource::PreciseCapturing, lt.ident.into()),
),
PreciseCapturingArg::Arg(path, id) => {
let [segment] = path.segments.as_slice() else {
panic!();
Expand Down Expand Up @@ -1740,22 +1749,40 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
) -> hir::GenericBound<'hir> {
match tpb {
GenericBound::Trait(p) => hir::GenericBound::Trait(self.lower_poly_trait_ref(p, itctx)),
GenericBound::Outlives(lifetime) => {
hir::GenericBound::Outlives(self.lower_lifetime(lifetime))
}
GenericBound::Outlives(lifetime) => hir::GenericBound::Outlives(self.lower_lifetime(
lifetime,
LifetimeSource::OutlivesBound,
lifetime.ident.into(),
)),
GenericBound::Use(args, span) => hir::GenericBound::Use(
self.lower_precise_capturing_args(args),
self.lower_span(*span),
),
}
}

fn lower_lifetime(&mut self, l: &Lifetime) -> &'hir hir::Lifetime {
self.new_named_lifetime(l.id, l.id, l.ident, IsAnonInPath::No)
fn lower_lifetime(
&mut self,
l: &Lifetime,
source: LifetimeSource,
syntax: LifetimeSyntax,
) -> &'hir hir::Lifetime {
self.new_named_lifetime(l.id, l.id, l.ident, source, syntax)
}

fn lower_lifetime_anon_in_path(&mut self, id: NodeId, span: Span) -> &'hir hir::Lifetime {
self.new_named_lifetime(id, id, Ident::new(kw::UnderscoreLifetime, span), IsAnonInPath::Yes)
fn lower_lifetime_hidden_in_path(
&mut self,
id: NodeId,
span: Span,
with_angle_brackets: bool,
) -> &'hir hir::Lifetime {
self.new_named_lifetime(
id,
id,
Ident::new(kw::UnderscoreLifetime, span),
LifetimeSource::Path { with_angle_brackets },
LifetimeSyntax::Hidden,
)
}

#[instrument(level = "debug", skip(self))]
Expand All @@ -1764,7 +1791,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
id: NodeId,
new_id: NodeId,
ident: Ident,
is_anon_in_path: IsAnonInPath,
source: LifetimeSource,
syntax: LifetimeSyntax,
) -> &'hir hir::Lifetime {
debug_assert_ne!(ident.name, kw::Empty);
let res = self.resolver.get_lifetime_res(id).unwrap_or(LifetimeRes::Error);
Expand All @@ -1789,17 +1817,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}
};

#[cfg(debug_assertions)]
if is_anon_in_path == IsAnonInPath::Yes {
debug_assert_eq!(ident.name, kw::UnderscoreLifetime);
}

debug!(?res);
self.arena.alloc(hir::Lifetime::new(
self.lower_node_id(new_id),
self.lower_ident(ident),
res,
is_anon_in_path,
source,
syntax,
))
}

Expand Down Expand Up @@ -2389,7 +2413,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
self.next_id(),
Ident::new(kw::UnderscoreLifetime, self.lower_span(span)),
hir::LifetimeName::ImplicitObjectLifetimeDefault,
IsAnonInPath::No,
LifetimeSource::Other,
LifetimeSyntax::Hidden,
);
debug!("elided_dyn_bound: r={:?}", r);
self.arena.alloc(r)
Expand Down
18 changes: 11 additions & 7 deletions compiler/rustc_ast_lowering/src/path.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
use std::sync::Arc;

use rustc_ast::{self as ast, *};
use rustc_hir as hir;
use rustc_hir::GenericArg;
use rustc_hir::def::{DefKind, PartialRes, Res};
use rustc_hir::def_id::DefId;
use rustc_hir::{self as hir, GenericArg};
use rustc_middle::span_bug;
use rustc_session::parse::add_feature_diagnostics;
use rustc_span::{BytePos, DUMMY_SP, DesugaringKind, Ident, Span, Symbol, sym};
Expand Down Expand Up @@ -433,24 +432,29 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {

// Note: these spans are used for diagnostics when they can't be inferred.
// See rustc_resolve::late::lifetimes::LifetimeContext::add_missing_lifetime_specifiers_label
let elided_lifetime_span = if generic_args.span.is_empty() {
let (elided_lifetime_span, with_angle_brackets) = if generic_args.span.is_empty() {
// If there are no brackets, use the identifier span.
// HACK: we use find_ancestor_inside to properly suggest elided spans in paths
// originating from macros, since the segment's span might be from a macro arg.
segment_ident_span.find_ancestor_inside(path_span).unwrap_or(path_span)
(segment_ident_span.find_ancestor_inside(path_span).unwrap_or(path_span), false)
} else if generic_args.is_empty() {
// If there are brackets, but not generic arguments, then use the opening bracket
generic_args.span.with_hi(generic_args.span.lo() + BytePos(1))
(generic_args.span.with_hi(generic_args.span.lo() + BytePos(1)), true)
} else {
// Else use an empty span right after the opening bracket.
generic_args.span.with_lo(generic_args.span.lo() + BytePos(1)).shrink_to_lo()
(generic_args.span.with_lo(generic_args.span.lo() + BytePos(1)).shrink_to_lo(), true)
};

generic_args.args.insert_many(
0,
(start.as_u32()..end.as_u32()).map(|i| {
let id = NodeId::from_u32(i);
let l = self.lower_lifetime_anon_in_path(id, elided_lifetime_span);

let l = self.lower_lifetime_hidden_in_path(
id,
elided_lifetime_span,
with_angle_brackets,
);
GenericArg::Lifetime(l)
}),
);
Expand Down
14 changes: 3 additions & 11 deletions compiler/rustc_ast_passes/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

use rustc_ast::ParamKindOrd;
use rustc_errors::codes::*;
use rustc_errors::{Applicability, Diag, EmissionGuarantee, SubdiagMessageOp, Subdiagnostic};
use rustc_errors::{Applicability, Diag, EmissionGuarantee, Subdiagnostic};
use rustc_macros::{Diagnostic, Subdiagnostic};
use rustc_span::{Ident, Span, Symbol};

Expand Down Expand Up @@ -394,11 +394,7 @@ pub(crate) struct EmptyLabelManySpans(pub Vec<Span>);

// The derive for `Vec<Span>` does multiple calls to `span_label`, adding commas between each
impl Subdiagnostic for EmptyLabelManySpans {
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
self,
diag: &mut Diag<'_, G>,
_: &F,
) {
fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
diag.span_labels(self.0, "");
}
}
Expand Down Expand Up @@ -749,11 +745,7 @@ pub(crate) struct StableFeature {
}

impl Subdiagnostic for StableFeature {
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
self,
diag: &mut Diag<'_, G>,
_: &F,
) {
fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
diag.arg("name", self.name);
diag.arg("since", self.since);
diag.help(fluent::ast_passes_stable_since);
Expand Down
10 changes: 3 additions & 7 deletions compiler/rustc_builtin_macros/src/errors.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use rustc_errors::codes::*;
use rustc_errors::{
Diag, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level, MultiSpan, SingleLabelManySpans,
SubdiagMessageOp, Subdiagnostic,
Subdiagnostic,
};
use rustc_macros::{Diagnostic, Subdiagnostic};
use rustc_span::{Ident, Span, Symbol};
Expand Down Expand Up @@ -691,13 +691,9 @@ pub(crate) struct FormatUnusedArg {
// Allow the singular form to be a subdiagnostic of the multiple-unused
// form of diagnostic.
impl Subdiagnostic for FormatUnusedArg {
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
self,
diag: &mut Diag<'_, G>,
f: &F,
) {
fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
diag.arg("named", self.named);
let msg = f(diag, crate::fluent_generated::builtin_macros_format_unused_arg.into());
let msg = diag.eagerly_translate(crate::fluent_generated::builtin_macros_format_unused_arg);
diag.span_label(self.span, msg);
}
}
Expand Down
10 changes: 3 additions & 7 deletions compiler/rustc_const_eval/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use rustc_abi::WrappingRange;
use rustc_errors::codes::*;
use rustc_errors::{
Diag, DiagArgValue, DiagCtxtHandle, DiagMessage, Diagnostic, EmissionGuarantee, Level,
MultiSpan, SubdiagMessageOp, Subdiagnostic,
MultiSpan, Subdiagnostic,
};
use rustc_hir::ConstContext;
use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
Expand Down Expand Up @@ -290,19 +290,15 @@ pub struct FrameNote {
}

impl Subdiagnostic for FrameNote {
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
self,
diag: &mut Diag<'_, G>,
f: &F,
) {
fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
diag.arg("times", self.times);
diag.arg("where_", self.where_);
diag.arg("instance", self.instance);
let mut span: MultiSpan = self.span.into();
if self.has_label && !self.span.is_dummy() {
span.push_span_label(self.span, fluent::const_eval_frame_note_last);
}
let msg = f(diag, fluent::const_eval_frame_note.into());
let msg = diag.eagerly_translate(fluent::const_eval_frame_note);
diag.span_note(span, msg);
}
}
Expand Down
Loading
Loading