Skip to content

Commit 3819154

Browse files
committed
elided_named_lifetimes: try to work around the issues with NodeIds for lint buffering
1 parent a055fad commit 3819154

File tree

2 files changed

+40
-15
lines changed

2 files changed

+40
-15
lines changed

compiler/rustc_resolve/src/late.rs

+23-15
Original file line numberDiff line numberDiff line change
@@ -699,6 +699,11 @@ struct LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
699699

700700
/// Count the number of places a lifetime is used.
701701
lifetime_uses: FxHashMap<LocalDefId, LifetimeUseSet>,
702+
703+
/// We need some "real" `NodeId` to emit
704+
/// [`elided_named_lifetimes`](lint::builtin::ELIDED_NAMED_LIFETIMES).
705+
/// See comments in [`MissingLifetime::id_if_not_fake_or`].
706+
crate_node_id: NodeId,
702707
}
703708

704709
/// Walks the whole crate in DFS order, visiting each item, resolving names as it goes.
@@ -1317,7 +1322,10 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
13171322
}
13181323

13191324
impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
1320-
fn new(resolver: &'b mut Resolver<'a, 'tcx>) -> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
1325+
fn new(
1326+
resolver: &'b mut Resolver<'a, 'tcx>,
1327+
krate: &Crate,
1328+
) -> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
13211329
// During late resolution we only track the module component of the parent scope,
13221330
// although it may be useful to track other components as well for diagnostics.
13231331
let graph_root = resolver.graph_root;
@@ -1340,6 +1348,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
13401348
// errors at module scope should always be reported
13411349
in_func_body: false,
13421350
lifetime_uses: Default::default(),
1351+
crate_node_id: krate.id,
13431352
}
13441353
}
13451354

@@ -2045,23 +2054,22 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
20452054
debug_assert_eq!(id, missing.id);
20462055
match res {
20472056
LifetimeRes::Static => {
2048-
// FIXME: ICEs otherwise
2049-
if missing.kind != MissingLifetimeKind::Ampersand {
2050-
self.r.lint_buffer.buffer_lint(
2051-
lint::builtin::ELIDED_NAMED_LIFETIMES,
2052-
missing.id,
2053-
missing.span,
2054-
BuiltinLintDiag::ElidedIsStatic { elided: missing.span },
2055-
);
2056-
}
2057+
self.r.lint_buffer.buffer_lint(
2058+
lint::builtin::ELIDED_NAMED_LIFETIMES,
2059+
missing.id_if_not_fake_or(self.crate_node_id),
2060+
missing.span,
2061+
BuiltinLintDiag::ElidedIsStatic { elided: missing.span },
2062+
);
20572063
}
20582064
LifetimeRes::Param { param, binder } => {
20592065
self.r.lint_buffer.buffer_lint(
20602066
lint::builtin::ELIDED_NAMED_LIFETIMES,
2061-
// HACK: we can't use `missing.id` instead of `binder` here,
2062-
// because for `missing.kind == Ampersand` it is a "fake" node that gets overlooked and its lints do not end up emitted.
2063-
// Alternatively, it might be possible to convert `param` to `NodeId` and use that instead.
2064-
binder,
2067+
// It should be possible to use `self.crate_node_id`
2068+
// or `param`'s `NodeId` here as a fallback instead of the `binder`,
2069+
// but `binder` sounds like a more appropriate place than the crate,
2070+
// and to convert `param` from `LocalDefId` to `NodeId`,
2071+
// we would have to do some additional work.
2072+
missing.id_if_not_fake_or(binder),
20652073
missing.span,
20662074
BuiltinLintDiag::ElidedIsParam {
20672075
elided: missing.span,
@@ -4971,7 +4979,7 @@ impl<'ast> Visitor<'ast> for ItemInfoCollector<'_, '_, '_> {
49714979
impl<'a, 'tcx> Resolver<'a, 'tcx> {
49724980
pub(crate) fn late_resolve_crate(&mut self, krate: &Crate) {
49734981
visit::walk_crate(&mut ItemInfoCollector { r: self }, krate);
4974-
let mut late_resolution_visitor = LateResolutionVisitor::new(self);
4982+
let mut late_resolution_visitor = LateResolutionVisitor::new(self, krate);
49754983
late_resolution_visitor.resolve_doc_links(&krate.attrs, MaybeExported::Ok(CRATE_NODE_ID));
49764984
visit::walk_crate(&mut late_resolution_visitor, krate);
49774985
for (id, span) in late_resolution_visitor.diag_metadata.unused_labels.iter() {

compiler/rustc_resolve/src/late/diagnostics.rs

+17
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,23 @@ pub(super) struct MissingLifetime {
110110
pub count: usize,
111111
}
112112

113+
impl MissingLifetime {
114+
/// As we cannot yet emit lints in this crate and have to buffer them instead,
115+
/// we need to associate each lint with some `NodeId`,
116+
/// however for some `MissingLifetime`s their `NodeId`s are "fake",
117+
/// in a sense that they are temporary and not get preserved down the line,
118+
/// which means that the lints for those nodes will not get emitted.
119+
/// To combat this, we can try to use some other `NodeId`s as a fallback option.
120+
pub(super) fn id_if_not_fake_or(self, fallback: NodeId) -> NodeId {
121+
match self.kind {
122+
MissingLifetimeKind::Underscore
123+
| MissingLifetimeKind::Comma
124+
| MissingLifetimeKind::Brackets => self.id,
125+
MissingLifetimeKind::Ampersand => fallback,
126+
}
127+
}
128+
}
129+
113130
/// Description of the lifetimes appearing in a function parameter.
114131
/// This is used to provide a literal explanation to the elision failure.
115132
#[derive(Clone, Debug)]

0 commit comments

Comments
 (0)