Skip to content

Commit 22d5e6f

Browse files
committed
Keep an ErrorGuaranteed around for LifetimeRes::Error
This will later be used to taint things
1 parent 76e7a08 commit 22d5e6f

File tree

5 files changed

+114
-75
lines changed

5 files changed

+114
-75
lines changed

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -814,7 +814,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
814814

815815
(hir::ParamName::Fresh, hir::LifetimeParamKind::Elided(kind))
816816
}
817-
LifetimeRes::Static | LifetimeRes::Error => return None,
817+
LifetimeRes::Static | LifetimeRes::Error(_) => return None,
818818
res => panic!(
819819
"Unexpected lifetime resolution {:?} for {:?} at {:?}",
820820
res, ident, ident.span
@@ -1629,14 +1629,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
16291629
let mut synthesized_lifetime_args = vec![];
16301630

16311631
for lifetime in captured_lifetimes_to_duplicate {
1632-
let res = self.resolver.get_lifetime_res(lifetime.id).unwrap_or(LifetimeRes::Error);
1633-
let (old_def_id, missing_kind) = match res {
1634-
LifetimeRes::Param { param: old_def_id, binder: _ } => (old_def_id, None),
1632+
let res = self.resolver.get_lifetime_res(lifetime.id);
1633+
let (old_def_id, missing_kind, res) = match res {
1634+
Some(res @ LifetimeRes::Param { param: old_def_id, binder: _ }) => {
1635+
(old_def_id, None, res)
1636+
}
16351637

1636-
LifetimeRes::Fresh { param, kind, .. } => {
1638+
Some(res @ LifetimeRes::Fresh { param, kind, .. }) => {
16371639
debug_assert_eq!(lifetime.ident.name, kw::UnderscoreLifetime);
16381640
if let Some(old_def_id) = self.orig_opt_local_def_id(param) {
1639-
(old_def_id, Some(kind))
1641+
(old_def_id, Some(kind), res)
16401642
} else {
16411643
self.dcx()
16421644
.span_delayed_bug(lifetime.ident.span, "no def-id for fresh lifetime");
@@ -1645,7 +1647,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
16451647
}
16461648

16471649
// Opaques do not capture `'static`
1648-
LifetimeRes::Static | LifetimeRes::Error => {
1650+
Some(LifetimeRes::Static | LifetimeRes::Error(_)) | None => {
16491651
continue;
16501652
}
16511653

@@ -2067,7 +2069,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
20672069
}
20682070
LifetimeRes::Infer => hir::LifetimeName::Infer,
20692071
LifetimeRes::Static => hir::LifetimeName::Static,
2070-
LifetimeRes::Error => hir::LifetimeName::Error,
2072+
LifetimeRes::Error(_guar) => hir::LifetimeName::Error,
20712073
res => panic!(
20722074
"Unexpected lifetime resolution {:?} for {:?} at {:?}",
20732075
res, ident, ident.span
@@ -2089,7 +2091,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
20892091
new_id: NodeId,
20902092
ident: Ident,
20912093
) -> &'hir hir::Lifetime {
2092-
let res = self.resolver.get_lifetime_res(id).unwrap_or(LifetimeRes::Error);
2094+
let res = self.resolver.get_lifetime_res(id).unwrap_or_else(|| {
2095+
LifetimeRes::Error(self.dcx().has_errors().expect(
2096+
"if resolution can't find a lifetime here, \
2097+
then the ast must be broken (e.g. `&self` in a free function",
2098+
))
2099+
});
20932100
self.new_named_lifetime_with_res(new_id, ident, res)
20942101
}
20952102

@@ -2140,13 +2147,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
21402147
GenericParamKind::Lifetime => {
21412148
// AST resolution emitted an error on those parameters, so we lower them using
21422149
// `ParamName::Error`.
2143-
let param_name =
2144-
if let Some(LifetimeRes::Error) = self.resolver.get_lifetime_res(param.id) {
2145-
ParamName::Error
2146-
} else {
2147-
let ident = self.lower_ident(param.ident);
2148-
ParamName::Plain(ident)
2149-
};
2150+
let param_name = if let Some(LifetimeRes::Error(_guar)) =
2151+
self.resolver.get_lifetime_res(param.id)
2152+
{
2153+
ParamName::Error
2154+
} else {
2155+
let ident = self.lower_ident(param.ident);
2156+
ParamName::Plain(ident)
2157+
};
21502158
let kind =
21512159
hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Explicit };
21522160

compiler/rustc_ast_lowering/src/lifetime_collector.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,16 @@ impl<'ast> LifetimeCollectVisitor<'ast> {
2020
}
2121

2222
fn record_lifetime_use(&mut self, lifetime: Lifetime) {
23-
match self.resolver.get_lifetime_res(lifetime.id).unwrap_or(LifetimeRes::Error) {
24-
LifetimeRes::Param { binder, .. } | LifetimeRes::Fresh { binder, .. } => {
23+
match self.resolver.get_lifetime_res(lifetime.id) {
24+
Some(LifetimeRes::Param { binder, .. } | LifetimeRes::Fresh { binder, .. }) => {
2525
if !self.current_binders.contains(&binder) {
2626
self.collected_lifetimes.insert(lifetime);
2727
}
2828
}
29-
LifetimeRes::Static | LifetimeRes::Error => {
29+
Some(LifetimeRes::Static | LifetimeRes::Error(_)) => {
3030
self.collected_lifetimes.insert(lifetime);
3131
}
32-
LifetimeRes::Infer => {}
32+
Some(LifetimeRes::Infer) => {}
3333
res => {
3434
let bug_msg = format!(
3535
"Unexpected lifetime resolution {:?} for {:?} at {:?}",

compiler/rustc_hir/src/def.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use rustc_macros::{Decodable, Encodable, HashStable_Generic};
99
use rustc_span::def_id::{DefId, LocalDefId};
1010
use rustc_span::hygiene::MacroKind;
1111
use rustc_span::symbol::kw;
12-
use rustc_span::Symbol;
12+
use rustc_span::{ErrorGuaranteed, Symbol};
1313

1414
use std::array::IntoIter;
1515
use std::fmt::Debug;
@@ -824,7 +824,7 @@ pub enum LifetimeRes {
824824
/// Explicit `'static` lifetime.
825825
Static,
826826
/// Resolution failure.
827-
Error,
827+
Error(ErrorGuaranteed),
828828
/// HACK: This is used to recover the NodeId of an elided lifetime.
829829
ElidedAnchor { start: NodeId, end: NodeId },
830830
}

compiler/rustc_resolve/src/late.rs

Lines changed: 60 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use rustc_session::lint::{self, BuiltinLintDiag};
2828
use rustc_session::parse::feature_err;
2929
use rustc_span::source_map::{respan, Spanned};
3030
use rustc_span::symbol::{kw, sym, Ident, Symbol};
31-
use rustc_span::{BytePos, Span, SyntaxContext};
31+
use rustc_span::{BytePos, ErrorGuaranteed, Span, SyntaxContext};
3232
use smallvec::{smallvec, SmallVec};
3333
use tracing::{debug, instrument, trace};
3434

@@ -1621,19 +1621,19 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
16211621
match rib.kind {
16221622
LifetimeRibKind::Item => break,
16231623
LifetimeRibKind::ConstParamTy => {
1624-
self.emit_non_static_lt_in_const_param_ty_error(lifetime);
1624+
let guar = self.emit_non_static_lt_in_const_param_ty_error(lifetime);
16251625
self.record_lifetime_res(
16261626
lifetime.id,
1627-
LifetimeRes::Error,
1627+
LifetimeRes::Error(guar),
16281628
LifetimeElisionCandidate::Ignore,
16291629
);
16301630
return;
16311631
}
16321632
LifetimeRibKind::ConcreteAnonConst(cause) => {
1633-
self.emit_forbidden_non_static_lifetime_error(cause, lifetime);
1633+
let guar = self.emit_forbidden_non_static_lifetime_error(cause, lifetime);
16341634
self.record_lifetime_res(
16351635
lifetime.id,
1636-
LifetimeRes::Error,
1636+
LifetimeRes::Error(guar),
16371637
LifetimeElisionCandidate::Ignore,
16381638
);
16391639
return;
@@ -1656,8 +1656,12 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
16561656
}
16571657
}
16581658

1659-
self.emit_undeclared_lifetime_error(lifetime, outer_res);
1660-
self.record_lifetime_res(lifetime.id, LifetimeRes::Error, LifetimeElisionCandidate::Named);
1659+
let guar = self.emit_undeclared_lifetime_error(lifetime, outer_res);
1660+
self.record_lifetime_res(
1661+
lifetime.id,
1662+
LifetimeRes::Error(guar),
1663+
LifetimeElisionCandidate::Named,
1664+
);
16611665
}
16621666

16631667
#[instrument(level = "debug", skip(self))]
@@ -1689,7 +1693,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
16891693
);
16901694
}
16911695
LifetimeRibKind::AnonymousReportError => {
1692-
if elided {
1696+
let guar = if elided {
16931697
let mut suggestion = None;
16941698
for rib in self.lifetime_ribs[i..].iter().rev() {
16951699
if let LifetimeRibKind::Generics {
@@ -1723,24 +1727,28 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
17231727
self.r.dcx().emit_err(errors::LendingIteratorReportError {
17241728
lifetime: lifetime.ident.span,
17251729
ty: ty.span(),
1726-
});
1730+
})
17271731
} else {
17281732
self.r.dcx().emit_err(errors::AnonymousLivetimeNonGatReportError {
17291733
lifetime: lifetime.ident.span,
1730-
});
1734+
})
17311735
}
17321736
} else {
17331737
self.r.dcx().emit_err(errors::ElidedAnonymousLivetimeReportError {
17341738
span: lifetime.ident.span,
17351739
suggestion,
1736-
});
1740+
})
17371741
}
17381742
} else {
17391743
self.r.dcx().emit_err(errors::ExplicitAnonymousLivetimeReportError {
17401744
span: lifetime.ident.span,
1741-
});
1745+
})
17421746
};
1743-
self.record_lifetime_res(lifetime.id, LifetimeRes::Error, elision_candidate);
1747+
self.record_lifetime_res(
1748+
lifetime.id,
1749+
LifetimeRes::Error(guar),
1750+
elision_candidate,
1751+
);
17441752
return;
17451753
}
17461754
LifetimeRibKind::Elided(res) => {
@@ -1749,7 +1757,11 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
17491757
}
17501758
LifetimeRibKind::ElisionFailure => {
17511759
self.diag_metadata.current_elision_failures.push(missing_lifetime);
1752-
self.record_lifetime_res(lifetime.id, LifetimeRes::Error, elision_candidate);
1760+
self.record_lifetime_res(
1761+
lifetime.id,
1762+
LifetimeRes::Error(self.r.dcx().delayed_bug("elision failure")),
1763+
elision_candidate,
1764+
);
17531765
return;
17541766
}
17551767
LifetimeRibKind::Item => break,
@@ -1760,8 +1772,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
17601772
}
17611773
}
17621774
}
1763-
self.record_lifetime_res(lifetime.id, LifetimeRes::Error, elision_candidate);
1764-
self.report_missing_lifetime_specifiers(vec![missing_lifetime], None);
1775+
let guar = self.report_missing_lifetime_specifiers(vec![missing_lifetime], None);
1776+
self.record_lifetime_res(lifetime.id, LifetimeRes::Error(guar), elision_candidate);
17651777
}
17661778

17671779
#[instrument(level = "debug", skip(self))]
@@ -1913,16 +1925,17 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
19131925
!segment.has_generic_args,
19141926
elided_lifetime_span,
19151927
);
1916-
self.r.dcx().emit_err(errors::ImplicitElidedLifetimeNotAllowedHere {
1917-
span: path_span,
1918-
subdiag,
1919-
});
1928+
let guar =
1929+
self.r.dcx().emit_err(errors::ImplicitElidedLifetimeNotAllowedHere {
1930+
span: path_span,
1931+
subdiag,
1932+
});
19201933
should_lint = false;
19211934

19221935
for id in node_ids {
19231936
self.record_lifetime_res(
19241937
id,
1925-
LifetimeRes::Error,
1938+
LifetimeRes::Error(guar),
19261939
LifetimeElisionCandidate::Named,
19271940
);
19281941
}
@@ -1958,7 +1971,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
19581971
for id in node_ids {
19591972
self.record_lifetime_res(
19601973
id,
1961-
LifetimeRes::Error,
1974+
LifetimeRes::Error(self.r.dcx().delayed_bug("missing lifetime")),
19621975
LifetimeElisionCandidate::Ignore,
19631976
);
19641977
}
@@ -1969,14 +1982,15 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
19691982
// we simply resolve to an implicit lifetime, which will be checked later, at
19701983
// which point a suitable error will be emitted.
19711984
LifetimeRibKind::AnonymousReportError | LifetimeRibKind::Item => {
1985+
let guar =
1986+
self.report_missing_lifetime_specifiers(vec![missing_lifetime], None);
19721987
for id in node_ids {
19731988
self.record_lifetime_res(
19741989
id,
1975-
LifetimeRes::Error,
1990+
LifetimeRes::Error(guar),
19761991
LifetimeElisionCandidate::Ignore,
19771992
);
19781993
}
1979-
self.report_missing_lifetime_specifiers(vec![missing_lifetime], None);
19801994
break;
19811995
}
19821996
LifetimeRibKind::Generics { .. } | LifetimeRibKind::ConstParamTy => {}
@@ -2011,6 +2025,9 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
20112025
candidate: LifetimeElisionCandidate,
20122026
) {
20132027
if let Some(prev_res) = self.r.lifetimes_res_map.insert(id, res) {
2028+
if let LifetimeRes::Error(_) = res {
2029+
return;
2030+
}
20142031
panic!("lifetime {id:?} resolved multiple times ({prev_res:?} before, {res:?} now)")
20152032
}
20162033
match res {
@@ -2019,7 +2036,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
20192036
candidates.push((res, candidate));
20202037
}
20212038
}
2022-
LifetimeRes::Infer | LifetimeRes::Error | LifetimeRes::ElidedAnchor { .. } => {}
2039+
LifetimeRes::Infer | LifetimeRes::Error(_) | LifetimeRes::ElidedAnchor { .. } => {}
20232040
}
20242041
}
20252042

@@ -2640,21 +2657,22 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
26402657
if let GenericParamKind::Lifetime = param.kind
26412658
&& let Some(&original) = seen_lifetimes.get(&ident)
26422659
{
2643-
diagnostics::signal_lifetime_shadowing(self.r.tcx.sess, original, param.ident);
2660+
let guar =
2661+
diagnostics::signal_lifetime_shadowing(self.r.tcx.sess, original, param.ident);
26442662
// Record lifetime res, so lowering knows there is something fishy.
2645-
self.record_lifetime_param(param.id, LifetimeRes::Error);
2663+
self.record_lifetime_param(param.id, LifetimeRes::Error(guar));
26462664
continue;
26472665
}
26482666

26492667
match seen_bindings.entry(ident) {
26502668
Entry::Occupied(entry) => {
26512669
let span = *entry.get();
26522670
let err = ResolutionError::NameAlreadyUsedInParameterList(ident.name, span);
2653-
self.report_error(param.ident.span, err);
2671+
let guar = self.report_error(param.ident.span, err);
26542672
let rib = match param.kind {
26552673
GenericParamKind::Lifetime => {
26562674
// Record lifetime res, so lowering knows there is something fishy.
2657-
self.record_lifetime_param(param.id, LifetimeRes::Error);
2675+
self.record_lifetime_param(param.id, LifetimeRes::Error(guar));
26582676
continue;
26592677
}
26602678
GenericParamKind::Type { .. } => &mut function_type_rib,
@@ -2672,21 +2690,22 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
26722690
}
26732691

26742692
if param.ident.name == kw::UnderscoreLifetime {
2675-
self.r
2693+
let guar = self
2694+
.r
26762695
.dcx()
26772696
.emit_err(errors::UnderscoreLifetimeIsReserved { span: param.ident.span });
26782697
// Record lifetime res, so lowering knows there is something fishy.
2679-
self.record_lifetime_param(param.id, LifetimeRes::Error);
2698+
self.record_lifetime_param(param.id, LifetimeRes::Error(guar));
26802699
continue;
26812700
}
26822701

26832702
if param.ident.name == kw::StaticLifetime {
2684-
self.r.dcx().emit_err(errors::StaticLifetimeIsReserved {
2703+
let guar = self.r.dcx().emit_err(errors::StaticLifetimeIsReserved {
26852704
span: param.ident.span,
26862705
lifetime: param.ident,
26872706
});
26882707
// Record lifetime res, so lowering knows there is something fishy.
2689-
self.record_lifetime_param(param.id, LifetimeRes::Error);
2708+
self.record_lifetime_param(param.id, LifetimeRes::Error(guar));
26902709
continue;
26912710
}
26922711

@@ -4056,9 +4075,15 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
40564075
/// A wrapper around [`Resolver::report_error`].
40574076
///
40584077
/// This doesn't emit errors for function bodies if this is rustdoc.
4059-
fn report_error(&mut self, span: Span, resolution_error: ResolutionError<'a>) {
4078+
fn report_error(
4079+
&mut self,
4080+
span: Span,
4081+
resolution_error: ResolutionError<'a>,
4082+
) -> ErrorGuaranteed {
40604083
if self.should_report_errs() {
4061-
self.r.report_error(span, resolution_error);
4084+
self.r.report_error(span, resolution_error)
4085+
} else {
4086+
self.r.tcx.dcx().has_errors().unwrap()
40624087
}
40634088
}
40644089

0 commit comments

Comments
 (0)