mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-04 11:04:03 +00:00
Abort analysis on type error
This commit is contained in:
parent
07d5f19426
commit
4b2e8bc841
@ -77,7 +77,7 @@ pub trait TypeCx: Sized + fmt::Debug {
|
||||
/// The set of all the constructors for `ty`.
|
||||
///
|
||||
/// This must follow the invariants of `ConstructorSet`
|
||||
fn ctors_for_ty(&self, ty: Self::Ty) -> ConstructorSet<Self>;
|
||||
fn ctors_for_ty(&self, ty: Self::Ty) -> Result<ConstructorSet<Self>, Self::Error>;
|
||||
|
||||
/// Best-effort `Debug` implementation.
|
||||
fn debug_pat(f: &mut fmt::Formatter<'_>, pat: &DeconstructedPat<'_, Self>) -> fmt::Result;
|
||||
|
@ -52,9 +52,13 @@ impl<'p, 'tcx> PatternColumn<'p, 'tcx> {
|
||||
}
|
||||
|
||||
/// Do constructor splitting on the constructors of the column.
|
||||
fn analyze_ctors(&self, pcx: &PlaceCtxt<'_, 'p, 'tcx>) -> SplitConstructorSet<'p, 'tcx> {
|
||||
fn analyze_ctors(
|
||||
&self,
|
||||
pcx: &PlaceCtxt<'_, 'p, 'tcx>,
|
||||
) -> Result<SplitConstructorSet<'p, 'tcx>, ErrorGuaranteed> {
|
||||
let column_ctors = self.patterns.iter().map(|p| p.ctor());
|
||||
pcx.ctors_for_ty().split(pcx, column_ctors)
|
||||
let ctors_for_ty = &pcx.ctors_for_ty()?;
|
||||
Ok(ctors_for_ty.split(pcx, column_ctors))
|
||||
}
|
||||
|
||||
fn iter(&self) -> impl Iterator<Item = &'p DeconstructedPat<'p, 'tcx>> + Captures<'_> {
|
||||
@ -116,7 +120,7 @@ fn collect_nonexhaustive_missing_variants<'a, 'p, 'tcx>(
|
||||
};
|
||||
let pcx = &PlaceCtxt::new_dummy(cx, ty);
|
||||
|
||||
let set = column.analyze_ctors(pcx);
|
||||
let set = column.analyze_ctors(pcx)?;
|
||||
if set.present.is_empty() {
|
||||
// We can't consistently handle the case where no constructors are present (since this would
|
||||
// require digging deep through any type in case there's a non_exhaustive enum somewhere),
|
||||
@ -219,7 +223,7 @@ pub(crate) fn lint_overlapping_range_endpoints<'a, 'p, 'tcx>(
|
||||
let pcx = &PlaceCtxt::new_dummy(cx, ty);
|
||||
let rcx: &RustcMatchCheckCtxt<'_, '_> = cx.tycx;
|
||||
|
||||
let set = column.analyze_ctors(pcx);
|
||||
let set = column.analyze_ctors(pcx)?;
|
||||
|
||||
if matches!(ty.kind(), ty::Char | ty::Int(_) | ty::Uint(_)) {
|
||||
let emit_lint = |overlap: &IntRange, this_span: Span, overlapped_spans: &[Span]| {
|
||||
|
@ -12,6 +12,7 @@ use rustc_middle::mir::interpret::Scalar;
|
||||
use rustc_middle::mir::{self, Const};
|
||||
use rustc_middle::thir::{FieldPat, Pat, PatKind, PatRange, PatRangeBoundary};
|
||||
use rustc_middle::ty::layout::IntegerExt;
|
||||
use rustc_middle::ty::TypeVisitableExt;
|
||||
use rustc_middle::ty::{self, OpaqueTypeKey, Ty, TyCtxt, VariantDef};
|
||||
use rustc_span::ErrorGuaranteed;
|
||||
use rustc_span::{Span, DUMMY_SP};
|
||||
@ -303,7 +304,10 @@ impl<'p, 'tcx> RustcMatchCheckCtxt<'p, 'tcx> {
|
||||
///
|
||||
/// See [`crate::constructor`] for considerations of emptiness.
|
||||
#[instrument(level = "debug", skip(self), ret)]
|
||||
pub fn ctors_for_ty(&self, ty: RevealedTy<'tcx>) -> ConstructorSet<'p, 'tcx> {
|
||||
pub fn ctors_for_ty(
|
||||
&self,
|
||||
ty: RevealedTy<'tcx>,
|
||||
) -> Result<ConstructorSet<'p, 'tcx>, ErrorGuaranteed> {
|
||||
let cx = self;
|
||||
let make_uint_range = |start, end| {
|
||||
IntRange::from_range(
|
||||
@ -312,9 +316,11 @@ impl<'p, 'tcx> RustcMatchCheckCtxt<'p, 'tcx> {
|
||||
RangeEnd::Included,
|
||||
)
|
||||
};
|
||||
// Abort on type error.
|
||||
ty.error_reported()?;
|
||||
// This determines the set of all possible constructors for the type `ty`. For numbers,
|
||||
// arrays and slices we use ranges and variable-length slices when appropriate.
|
||||
match ty.kind() {
|
||||
Ok(match ty.kind() {
|
||||
ty::Bool => ConstructorSet::Bool,
|
||||
ty::Char => {
|
||||
// The valid Unicode Scalar Value ranges.
|
||||
@ -424,7 +430,7 @@ impl<'p, 'tcx> RustcMatchCheckCtxt<'p, 'tcx> {
|
||||
ty::CoroutineWitness(_, _) | ty::Bound(_, _) | ty::Placeholder(_) | ty::Infer(_) => {
|
||||
bug!("Encountered unexpected type in `ConstructorSet::for_ty`: {ty:?}")
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn lower_pat_range_bdy(
|
||||
@ -965,7 +971,10 @@ impl<'p, 'tcx> TypeCx for RustcMatchCheckCtxt<'p, 'tcx> {
|
||||
) -> &[Self::Ty] {
|
||||
self.ctor_sub_tys(ctor, ty)
|
||||
}
|
||||
fn ctors_for_ty(&self, ty: Self::Ty) -> crate::constructor::ConstructorSet<Self> {
|
||||
fn ctors_for_ty(
|
||||
&self,
|
||||
ty: Self::Ty,
|
||||
) -> Result<crate::constructor::ConstructorSet<Self>, Self::Error> {
|
||||
self.ctors_for_ty(ty)
|
||||
}
|
||||
|
||||
|
@ -753,7 +753,7 @@ impl<'a, 'p, Cx: TypeCx> PlaceCtxt<'a, 'p, Cx> {
|
||||
pub(crate) fn ctor_sub_tys(&self, ctor: &Constructor<Cx>) -> &[Cx::Ty] {
|
||||
self.mcx.tycx.ctor_sub_tys(ctor, self.ty)
|
||||
}
|
||||
pub(crate) fn ctors_for_ty(&self) -> ConstructorSet<Cx> {
|
||||
pub(crate) fn ctors_for_ty(&self) -> Result<ConstructorSet<Cx>, Cx::Error> {
|
||||
self.mcx.tycx.ctors_for_ty(self.ty)
|
||||
}
|
||||
}
|
||||
@ -1383,7 +1383,7 @@ fn compute_exhaustiveness_and_usefulness<'a, 'p, Cx: TypeCx>(
|
||||
|
||||
// Analyze the constructors present in this column.
|
||||
let ctors = matrix.heads().map(|p| p.ctor());
|
||||
let ctors_for_ty = pcx.ctors_for_ty();
|
||||
let ctors_for_ty = pcx.ctors_for_ty()?;
|
||||
let is_integers = matches!(ctors_for_ty, ConstructorSet::Integers { .. }); // For diagnostics.
|
||||
let split_set = ctors_for_ty.split(pcx, ctors);
|
||||
let all_missing = split_set.present.is_empty();
|
||||
|
13
tests/ui/pattern/usefulness/issue-119493-type-error-ice.rs
Normal file
13
tests/ui/pattern/usefulness/issue-119493-type-error-ice.rs
Normal file
@ -0,0 +1,13 @@
|
||||
fn main() {}
|
||||
|
||||
fn foo() {
|
||||
#[derive(Copy, Clone)]
|
||||
struct Foo(NonExistent);
|
||||
//~^ ERROR cannot find type
|
||||
//~| ERROR cannot find type
|
||||
|
||||
type U = impl Copy;
|
||||
//~^ ERROR `impl Trait` in type aliases is unstable
|
||||
let foo: U = Foo(());
|
||||
let Foo(()) = foo;
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
error[E0412]: cannot find type `NonExistent` in this scope
|
||||
--> $DIR/issue-119493-type-error-ice.rs:5:16
|
||||
|
|
||||
LL | struct Foo(NonExistent);
|
||||
| ^^^^^^^^^^^ not found in this scope
|
||||
|
||||
error[E0412]: cannot find type `NonExistent` in this scope
|
||||
--> $DIR/issue-119493-type-error-ice.rs:5:16
|
||||
|
|
||||
LL | struct Foo(NonExistent);
|
||||
| ^^^^^^^^^^^ not found in this scope
|
||||
|
|
||||
help: you might be missing a type parameter
|
||||
|
|
||||
LL | struct Foo<NonExistent>(NonExistent);
|
||||
| +++++++++++++
|
||||
|
||||
error[E0658]: `impl Trait` in type aliases is unstable
|
||||
--> $DIR/issue-119493-type-error-ice.rs:9:14
|
||||
|
|
||||
LL | type U = impl Copy;
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
|
||||
= help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0412, E0658.
|
||||
For more information about an error, try `rustc --explain E0412`.
|
Loading…
Reference in New Issue
Block a user