Skip to content

Commit

Permalink
Auto merge of #107652 - estebank:re_error, r=oli-obk
Browse files Browse the repository at this point in the history
Introduce `ReError`

CC #69314

r? `@nagisa`
  • Loading branch information
bors committed Feb 10, 2023
2 parents 9b8dbd5 + 3689295 commit d1ac43a
Show file tree
Hide file tree
Showing 50 changed files with 248 additions and 227 deletions.
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 @@ -369,6 +369,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 @@ -661,6 +661,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

0 comments on commit d1ac43a

Please sign in to comment.