Skip to content

Introduce ReError #107652

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

Merged
merged 6 commits into from
Feb 10, 2023
Merged
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
10 changes: 7 additions & 3 deletions compiler/rustc_borrowck/src/diagnostics/region_name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -343,11 +343,11 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
let note = match closure_kind_ty.to_opt_closure_kind() {
Some(ty::ClosureKind::Fn) => {
"closure implements `Fn`, so references to captured variables \
can't escape the closure"
can't escape the closure"
}
Some(ty::ClosureKind::FnMut) => {
"closure implements `FnMut`, so references to captured variables \
can't escape the closure"
can't escape the closure"
}
Some(ty::ClosureKind::FnOnce) => {
bug!("BrEnv in a `FnOnce` closure");
Expand All @@ -364,7 +364,11 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
ty::BoundRegionKind::BrAnon(..) => None,
},

ty::ReLateBound(..) | ty::ReVar(..) | ty::RePlaceholder(..) | ty::ReErased => None,
ty::ReLateBound(..)
| ty::ReVar(..)
| ty::RePlaceholder(..)
| ty::ReErased
| ty::ReError(_) => None,
}
}

Expand Down
5 changes: 2 additions & 3 deletions compiler/rustc_borrowck/src/region_infer/opaque_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,11 +91,10 @@ impl<'tcx> RegionInferenceContext<'tcx> {
}
None => {
subst_regions.push(vid);
infcx.tcx.sess.delay_span_bug(
infcx.tcx.re_error_with_message(
concrete_type.span,
"opaque type with non-universal region substs",
);
infcx.tcx.lifetimes.re_static
)
}
}
};
Expand Down
10 changes: 9 additions & 1 deletion compiler/rustc_borrowck/src/universal_regions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,9 @@ struct UniversalRegionIndices<'tcx> {
/// contains an entry for `ReStatic` -- it might be nice to just
/// use a substs, and then handle `ReStatic` another way.
indices: FxHashMap<ty::Region<'tcx>, RegionVid>,

/// The vid assigned to `'static`. Used only for diagnostics.
pub fr_static: RegionVid,
}

#[derive(Debug, PartialEq)]
Expand Down Expand Up @@ -609,7 +612,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
let subst_mapping =
iter::zip(identity_substs.regions(), fr_substs.regions().map(|r| r.to_region_vid()));

UniversalRegionIndices { indices: global_mapping.chain(subst_mapping).collect() }
UniversalRegionIndices { indices: global_mapping.chain(subst_mapping).collect(), fr_static }
}

fn compute_inputs_and_output(
Expand Down Expand Up @@ -821,6 +824,11 @@ impl<'tcx> UniversalRegionIndices<'tcx> {
pub fn to_region_vid(&self, r: ty::Region<'tcx>) -> RegionVid {
if let ty::ReVar(..) = *r {
r.to_region_vid()
} else if r.is_error() {
// We use the `'static` `RegionVid` because `ReError` doesn't actually exist in the
// `UniversalRegionIndices`. This is fine because 1) it is a fallback only used if
// errors are being emitted and 2) it leaves the happy path unaffected.
self.fr_static
} else {
*self
.indices
Expand Down
22 changes: 7 additions & 15 deletions compiler/rustc_hir_analysis/src/astconv/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -263,11 +263,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
// elision. `resolve_lifetime` should have
// reported an error in this case -- but if
// not, let's error out.
tcx.sess.delay_span_bug(lifetime.ident.span, "unelided lifetime in signature");

// Supply some dummy value. We don't have an
// `re_error`, annoyingly, so use `'static`.
tcx.lifetimes.re_static
tcx.re_error_with_message(lifetime.ident.span, "unelided lifetime in signature")
})
}
}
Expand Down Expand Up @@ -481,11 +477,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
debug!(?param, "unelided lifetime in signature");

// This indicates an illegal lifetime in a non-assoc-trait position
tcx.sess.delay_span_bug(self.span, "unelided lifetime in signature");

// Supply some dummy value. We don't have an
// `re_error`, annoyingly, so use `'static`.
tcx.lifetimes.re_static
tcx.re_error_with_message(self.span, "unelided lifetime in signature")
})
.into(),
GenericParamDefKind::Type { has_default, .. } => {
Expand Down Expand Up @@ -1622,14 +1614,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
"the lifetime bound for this object type cannot be deduced \
from context; please supply an explicit bound"
);
if borrowed {
let e = if borrowed {
// We will have already emitted an error E0106 complaining about a
// missing named lifetime in `&dyn Trait`, so we elide this one.
err.delay_as_bug();
err.delay_as_bug()
} else {
err.emit();
}
tcx.lifetimes.re_static
err.emit()
};
tcx.re_error(e)
})
}
})
Expand Down
8 changes: 1 addition & 7 deletions compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -786,13 +786,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
}
let Some(ty::ReEarlyBound(e)) = map.get(&region.into()).map(|r| r.expect_region().kind())
else {
tcx
.sess
.delay_span_bug(
return_span,
"expected ReFree to map to ReEarlyBound"
);
return tcx.lifetimes.re_static;
return tcx.re_error_with_message(return_span, "expected ReFree to map to ReEarlyBound")
};
tcx.mk_region(ty::ReEarlyBound(ty::EarlyBoundRegion {
def_id: e.def_id,
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_hir_analysis/src/outlives/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,8 @@ fn is_free_region(region: Region<'_>) -> bool {
// ignore it. We can't put it on the struct header anyway.
ty::ReLateBound(..) => false,

ty::ReError(_) => false,

// These regions don't appear in types from type declarations:
ty::ReErased | ty::ReVar(..) | ty::RePlaceholder(..) | ty::ReFree(..) => {
bug!("unexpected region in outlives inference: {:?}", region);
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_hir_analysis/src/variance/constraints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,8 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
// way early-bound regions do, so we skip them here.
}

ty::ReError(_) => {}

ty::ReFree(..) | ty::ReVar(..) | ty::RePlaceholder(..) | ty::ReErased => {
// We don't expect to see anything but 'static or bound
// regions when visiting member types or method types.
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_infer/src/errors/note_and_explain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ impl<'a> DescriptionCtx<'a> {

ty::RePlaceholder(_) => return None,

ty::ReError(_) => return None,

// FIXME(#13998) RePlaceholder should probably print like
// ReFree rather than dumping Debug output on the user.
//
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> {

ty::ReStatic
| ty::ReEarlyBound(..)
| ty::ReError(_)
| ty::ReFree(_)
| ty::RePlaceholder(..)
| ty::ReErased => self.canonicalize_mode.canonicalize_free_region(self, r),
Expand Down
6 changes: 5 additions & 1 deletion compiler/rustc_infer/src/infer/combine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -705,6 +705,10 @@ impl<'tcx> TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
return Ok(r);
}

ty::ReError(_) => {
return Ok(r);
}

ty::RePlaceholder(..)
| ty::ReVar(..)
| ty::ReStatic
Expand Down Expand Up @@ -861,7 +865,7 @@ impl<'tcx> FallibleTypeFolder<'tcx> for ConstInferUnifier<'_, 'tcx> {
match *r {
// Never make variables for regions bound within the type itself,
// nor for erased regions.
ty::ReLateBound(..) | ty::ReErased => {
ty::ReLateBound(..) | ty::ReErased | ty::ReError(_) => {
return Ok(r);
}

Expand Down
17 changes: 15 additions & 2 deletions compiler/rustc_infer/src/infer/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@ pub(super) fn note_and_explain_region<'tcx>(

ty::RePlaceholder(_) => return,

ty::ReError(_) => return,

// FIXME(#13998) RePlaceholder should probably print like
// ReFree rather than dumping Debug output on the user.
//
Expand Down Expand Up @@ -313,6 +315,9 @@ pub fn unexpected_hidden_region_diagnostic<'tcx>(
)
}
}
ty::ReError(_) => {
err.delay_as_bug();
}
_ => {
// Ugh. This is a painful case: the hidden region is not one
// that we can easily summarize or explain. This can happen
Expand Down Expand Up @@ -2546,7 +2551,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
);

err.note_expected_found(&"", sup_expected, &"", sup_found);
err.emit();
if sub_region.is_error() | sup_region.is_error() {
err.delay_as_bug();
} else {
err.emit();
}
return;
}

Expand All @@ -2562,7 +2571,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
);

self.note_region_origin(&mut err, &sub_origin);
err.emit();
if sub_region.is_error() | sup_region.is_error() {
err.delay_as_bug();
} else {
err.emit();
}
}

/// Determine whether an error associated with the given span and definition
Expand Down
6 changes: 5 additions & 1 deletion compiler/rustc_infer/src/infer/error_reporting/note.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
sub: Region<'tcx>,
sup: Region<'tcx>,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
match origin {
let mut err = match origin {
infer::Subtype(box trace) => {
let terr = TypeError::RegionsDoesNotOutlive(sup, sub);
let mut err = self.report_and_explain_type_error(trace, terr);
Expand Down Expand Up @@ -299,7 +299,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
);
err
}
};
if sub.is_error() || sup.is_error() {
err.delay_as_bug();
}
err
}

pub fn suggest_copy_trait_method_bounds(
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_infer/src/infer/freshen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
| ty::ReFree(_)
| ty::ReVar(_)
| ty::RePlaceholder(..)
| ty::ReError(_)
| ty::ReErased => {
// replace all free regions with 'erased
self.tcx().lifetimes.re_erased
Expand Down
14 changes: 10 additions & 4 deletions compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use rustc_index::vec::{Idx, IndexVec};
use rustc_middle::ty::fold::TypeFoldable;
use rustc_middle::ty::PlaceholderRegion;
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_middle::ty::{ReEarlyBound, ReErased, ReFree, ReStatic};
use rustc_middle::ty::{ReEarlyBound, ReErased, ReError, ReFree, ReStatic};
use rustc_middle::ty::{ReLateBound, RePlaceholder, ReVar};
use rustc_middle::ty::{Region, RegionVid};
use rustc_span::Span;
Expand Down Expand Up @@ -216,6 +216,8 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
Ok(self.tcx().lifetimes.re_static)
}

ReError(_) => Ok(a_region),

ReEarlyBound(_) | ReFree(_) => {
// All empty regions are less than early-bound, free,
// and scope regions.
Expand Down Expand Up @@ -436,7 +438,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
}
(VarValue::Value(a), VarValue::Empty(_)) => {
match *a {
ReLateBound(..) | ReErased => {
ReLateBound(..) | ReErased | ReError(_) => {
bug!("cannot relate region: {:?}", a);
}

Expand Down Expand Up @@ -465,7 +467,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
}
(VarValue::Empty(a_ui), VarValue::Value(b)) => {
match *b {
ReLateBound(..) | ReErased => {
ReLateBound(..) | ReErased | ReError(_) => {
bug!("cannot relate region: {:?}", b);
}

Expand Down Expand Up @@ -546,6 +548,10 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
);
}

(ReError(_), _) => a,

(_, ReError(_)) => b,

(ReStatic, _) | (_, ReStatic) => {
// nothing lives longer than `'static`
self.tcx().lifetimes.re_static
Expand Down Expand Up @@ -1040,7 +1046,7 @@ impl<'tcx> LexicalRegionResolutions<'tcx> {
ty::ReVar(rid) => match self.values[rid] {
VarValue::Empty(_) => r,
VarValue::Value(r) => r,
VarValue::ErrorValue => tcx.lifetimes.re_static,
VarValue::ErrorValue => tcx.re_error_misc(),
},
_ => r,
};
Expand Down
8 changes: 5 additions & 3 deletions compiler/rustc_infer/src/infer/region_constraints/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -696,9 +696,11 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {

pub fn universe(&self, region: Region<'tcx>) -> ty::UniverseIndex {
match *region {
ty::ReStatic | ty::ReErased | ty::ReFree(..) | ty::ReEarlyBound(..) => {
ty::UniverseIndex::ROOT
}
ty::ReStatic
| ty::ReErased
| ty::ReFree(..)
| ty::ReEarlyBound(..)
| ty::ReError(_) => ty::UniverseIndex::ROOT,
ty::RePlaceholder(placeholder) => placeholder.universe,
ty::ReVar(vid) => self.var_universe(vid),
ty::ReLateBound(..) => bug!("universe(): encountered bound region {:?}", region),
Expand Down
24 changes: 24 additions & 0 deletions compiler/rustc_middle/src/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -649,6 +649,30 @@ impl<'tcx> TyCtxt<'tcx> {
self.mk_ty(Error(reported))
}

/// Constructs a `RegionKind::ReError` lifetime.
#[track_caller]
pub fn re_error(self, reported: ErrorGuaranteed) -> Region<'tcx> {
self.mk_region(ty::ReError(reported))
}

/// Constructs a `RegionKind::ReError` lifetime and registers a `delay_span_bug` to ensure it
/// gets used.
#[track_caller]
pub fn re_error_misc(self) -> Region<'tcx> {
self.re_error_with_message(
DUMMY_SP,
"RegionKind::ReError constructed but no error reported",
)
}

/// Constructs a `RegionKind::ReError` lifetime and registers a `delay_span_bug` with the given
/// `msg` to ensure it gets used.
#[track_caller]
pub fn re_error_with_message<S: Into<MultiSpan>>(self, span: S, msg: &str) -> Region<'tcx> {
let reported = self.sess.delay_span_bug(span, msg);
self.re_error(reported)
}

/// Like [TyCtxt::ty_error] but for constants, with current `ErrorGuaranteed`
#[track_caller]
pub fn const_error_with_guaranteed(
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/generics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ impl GenericParamDef {
preceding_substs: &[ty::GenericArg<'tcx>],
) -> ty::GenericArg<'tcx> {
match &self.kind {
ty::GenericParamDefKind::Lifetime => tcx.lifetimes.re_static.into(),
ty::GenericParamDefKind::Lifetime => tcx.re_error_misc().into(),
ty::GenericParamDefKind::Type { .. } => tcx.ty_error().into(),
ty::GenericParamDefKind::Const { .. } => {
tcx.const_error(tcx.bound_type_of(self.def_id).subst(tcx, preceding_substs)).into()
Expand Down
Loading