Skip to content

Commit 4b2e8bc

Browse files
committed
Abort analysis on type error
1 parent 07d5f19 commit 4b2e8bc

File tree

6 files changed

+67
-11
lines changed

6 files changed

+67
-11
lines changed

compiler/rustc_pattern_analysis/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ pub trait TypeCx: Sized + fmt::Debug {
7777
/// The set of all the constructors for `ty`.
7878
///
7979
/// This must follow the invariants of `ConstructorSet`
80-
fn ctors_for_ty(&self, ty: Self::Ty) -> ConstructorSet<Self>;
80+
fn ctors_for_ty(&self, ty: Self::Ty) -> Result<ConstructorSet<Self>, Self::Error>;
8181

8282
/// Best-effort `Debug` implementation.
8383
fn debug_pat(f: &mut fmt::Formatter<'_>, pat: &DeconstructedPat<'_, Self>) -> fmt::Result;

compiler/rustc_pattern_analysis/src/lints.rs

+8-4
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,13 @@ impl<'p, 'tcx> PatternColumn<'p, 'tcx> {
5252
}
5353

5454
/// Do constructor splitting on the constructors of the column.
55-
fn analyze_ctors(&self, pcx: &PlaceCtxt<'_, 'p, 'tcx>) -> SplitConstructorSet<'p, 'tcx> {
55+
fn analyze_ctors(
56+
&self,
57+
pcx: &PlaceCtxt<'_, 'p, 'tcx>,
58+
) -> Result<SplitConstructorSet<'p, 'tcx>, ErrorGuaranteed> {
5659
let column_ctors = self.patterns.iter().map(|p| p.ctor());
57-
pcx.ctors_for_ty().split(pcx, column_ctors)
60+
let ctors_for_ty = &pcx.ctors_for_ty()?;
61+
Ok(ctors_for_ty.split(pcx, column_ctors))
5862
}
5963

6064
fn iter(&self) -> impl Iterator<Item = &'p DeconstructedPat<'p, 'tcx>> + Captures<'_> {
@@ -116,7 +120,7 @@ fn collect_nonexhaustive_missing_variants<'a, 'p, 'tcx>(
116120
};
117121
let pcx = &PlaceCtxt::new_dummy(cx, ty);
118122

119-
let set = column.analyze_ctors(pcx);
123+
let set = column.analyze_ctors(pcx)?;
120124
if set.present.is_empty() {
121125
// We can't consistently handle the case where no constructors are present (since this would
122126
// 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>(
219223
let pcx = &PlaceCtxt::new_dummy(cx, ty);
220224
let rcx: &RustcMatchCheckCtxt<'_, '_> = cx.tycx;
221225

222-
let set = column.analyze_ctors(pcx);
226+
let set = column.analyze_ctors(pcx)?;
223227

224228
if matches!(ty.kind(), ty::Char | ty::Int(_) | ty::Uint(_)) {
225229
let emit_lint = |overlap: &IntRange, this_span: Span, overlapped_spans: &[Span]| {

compiler/rustc_pattern_analysis/src/rustc.rs

+13-4
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use rustc_middle::mir::interpret::Scalar;
1212
use rustc_middle::mir::{self, Const};
1313
use rustc_middle::thir::{FieldPat, Pat, PatKind, PatRange, PatRangeBoundary};
1414
use rustc_middle::ty::layout::IntegerExt;
15+
use rustc_middle::ty::TypeVisitableExt;
1516
use rustc_middle::ty::{self, OpaqueTypeKey, Ty, TyCtxt, VariantDef};
1617
use rustc_span::ErrorGuaranteed;
1718
use rustc_span::{Span, DUMMY_SP};
@@ -303,7 +304,10 @@ impl<'p, 'tcx> RustcMatchCheckCtxt<'p, 'tcx> {
303304
///
304305
/// See [`crate::constructor`] for considerations of emptiness.
305306
#[instrument(level = "debug", skip(self), ret)]
306-
pub fn ctors_for_ty(&self, ty: RevealedTy<'tcx>) -> ConstructorSet<'p, 'tcx> {
307+
pub fn ctors_for_ty(
308+
&self,
309+
ty: RevealedTy<'tcx>,
310+
) -> Result<ConstructorSet<'p, 'tcx>, ErrorGuaranteed> {
307311
let cx = self;
308312
let make_uint_range = |start, end| {
309313
IntRange::from_range(
@@ -312,9 +316,11 @@ impl<'p, 'tcx> RustcMatchCheckCtxt<'p, 'tcx> {
312316
RangeEnd::Included,
313317
)
314318
};
319+
// Abort on type error.
320+
ty.error_reported()?;
315321
// This determines the set of all possible constructors for the type `ty`. For numbers,
316322
// arrays and slices we use ranges and variable-length slices when appropriate.
317-
match ty.kind() {
323+
Ok(match ty.kind() {
318324
ty::Bool => ConstructorSet::Bool,
319325
ty::Char => {
320326
// The valid Unicode Scalar Value ranges.
@@ -424,7 +430,7 @@ impl<'p, 'tcx> RustcMatchCheckCtxt<'p, 'tcx> {
424430
ty::CoroutineWitness(_, _) | ty::Bound(_, _) | ty::Placeholder(_) | ty::Infer(_) => {
425431
bug!("Encountered unexpected type in `ConstructorSet::for_ty`: {ty:?}")
426432
}
427-
}
433+
})
428434
}
429435

430436
pub(crate) fn lower_pat_range_bdy(
@@ -965,7 +971,10 @@ impl<'p, 'tcx> TypeCx for RustcMatchCheckCtxt<'p, 'tcx> {
965971
) -> &[Self::Ty] {
966972
self.ctor_sub_tys(ctor, ty)
967973
}
968-
fn ctors_for_ty(&self, ty: Self::Ty) -> crate::constructor::ConstructorSet<Self> {
974+
fn ctors_for_ty(
975+
&self,
976+
ty: Self::Ty,
977+
) -> Result<crate::constructor::ConstructorSet<Self>, Self::Error> {
969978
self.ctors_for_ty(ty)
970979
}
971980

compiler/rustc_pattern_analysis/src/usefulness.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -753,7 +753,7 @@ impl<'a, 'p, Cx: TypeCx> PlaceCtxt<'a, 'p, Cx> {
753753
pub(crate) fn ctor_sub_tys(&self, ctor: &Constructor<Cx>) -> &[Cx::Ty] {
754754
self.mcx.tycx.ctor_sub_tys(ctor, self.ty)
755755
}
756-
pub(crate) fn ctors_for_ty(&self) -> ConstructorSet<Cx> {
756+
pub(crate) fn ctors_for_ty(&self) -> Result<ConstructorSet<Cx>, Cx::Error> {
757757
self.mcx.tycx.ctors_for_ty(self.ty)
758758
}
759759
}
@@ -1383,7 +1383,7 @@ fn compute_exhaustiveness_and_usefulness<'a, 'p, Cx: TypeCx>(
13831383

13841384
// Analyze the constructors present in this column.
13851385
let ctors = matrix.heads().map(|p| p.ctor());
1386-
let ctors_for_ty = pcx.ctors_for_ty();
1386+
let ctors_for_ty = pcx.ctors_for_ty()?;
13871387
let is_integers = matches!(ctors_for_ty, ConstructorSet::Integers { .. }); // For diagnostics.
13881388
let split_set = ctors_for_ty.split(pcx, ctors);
13891389
let all_missing = split_set.present.is_empty();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
fn main() {}
2+
3+
fn foo() {
4+
#[derive(Copy, Clone)]
5+
struct Foo(NonExistent);
6+
//~^ ERROR cannot find type
7+
//~| ERROR cannot find type
8+
9+
type U = impl Copy;
10+
//~^ ERROR `impl Trait` in type aliases is unstable
11+
let foo: U = Foo(());
12+
let Foo(()) = foo;
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
error[E0412]: cannot find type `NonExistent` in this scope
2+
--> $DIR/issue-119493-type-error-ice.rs:5:16
3+
|
4+
LL | struct Foo(NonExistent);
5+
| ^^^^^^^^^^^ not found in this scope
6+
7+
error[E0412]: cannot find type `NonExistent` in this scope
8+
--> $DIR/issue-119493-type-error-ice.rs:5:16
9+
|
10+
LL | struct Foo(NonExistent);
11+
| ^^^^^^^^^^^ not found in this scope
12+
|
13+
help: you might be missing a type parameter
14+
|
15+
LL | struct Foo<NonExistent>(NonExistent);
16+
| +++++++++++++
17+
18+
error[E0658]: `impl Trait` in type aliases is unstable
19+
--> $DIR/issue-119493-type-error-ice.rs:9:14
20+
|
21+
LL | type U = impl Copy;
22+
| ^^^^^^^^^
23+
|
24+
= note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
25+
= help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
26+
27+
error: aborting due to 3 previous errors
28+
29+
Some errors have detailed explanations: E0412, E0658.
30+
For more information about an error, try `rustc --explain E0412`.

0 commit comments

Comments
 (0)