Skip to content

Commit c352720

Browse files
committed
Statically enforce revealing of opaques
1 parent e51e98d commit c352720

File tree

5 files changed

+132
-94
lines changed

5 files changed

+132
-94
lines changed

compiler/rustc_mir_build/src/thir/pattern/check_match.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -554,7 +554,7 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
554554
let cx = self.new_cx(refutability, None, scrut, pat.span);
555555
let pat = self.lower_pattern(&cx, pat)?;
556556
let arms = [MatchArm { pat, arm_data: self.lint_level, has_guard: false }];
557-
let report = analyze_match(&cx, &arms, pat.ty());
557+
let report = analyze_match(&cx, &arms, pat.ty().inner());
558558
Ok((cx, report))
559559
}
560560

@@ -972,7 +972,7 @@ fn report_non_exhaustive_match<'p, 'tcx>(
972972
}
973973
} else if ty == cx.tcx.types.str_ {
974974
err.note("`&str` cannot be matched exhaustively, so a wildcard `_` is necessary");
975-
} else if cx.is_foreign_non_exhaustive_enum(ty) {
975+
} else if cx.is_foreign_non_exhaustive_enum(cx.reveal_opaque_ty(ty)) {
976976
err.note(format!("`{ty}` is marked as non-exhaustive, so a wildcard `_` is necessary to match exhaustively"));
977977
}
978978
}
@@ -1112,12 +1112,12 @@ fn collect_non_exhaustive_tys<'tcx>(
11121112
non_exhaustive_tys: &mut FxIndexSet<Ty<'tcx>>,
11131113
) {
11141114
if matches!(pat.ctor(), Constructor::NonExhaustive) {
1115-
non_exhaustive_tys.insert(pat.ty());
1115+
non_exhaustive_tys.insert(pat.ty().inner());
11161116
}
11171117
if let Constructor::IntRange(range) = pat.ctor() {
11181118
if cx.is_range_beyond_boundaries(range, pat.ty()) {
11191119
// The range denotes the values before `isize::MIN` or the values after `usize::MAX`/`isize::MAX`.
1120-
non_exhaustive_tys.insert(pat.ty());
1120+
non_exhaustive_tys.insert(pat.ty().inner());
11211121
}
11221122
}
11231123
pat.iter_fields()

compiler/rustc_pattern_analysis/src/lib.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,6 @@ pub trait TypeCx: Sized + fmt::Debug {
6161
/// Extra data to store in a pattern.
6262
type PatData: Clone;
6363

64-
/// FIXME(Nadrieril): `Cx` should only give us revealed types.
65-
fn reveal_opaque_ty(&self, ty: Self::Ty) -> Self::Ty;
6664
fn is_exhaustive_patterns_feature_on(&self) -> bool;
6765

6866
/// The number of fields for this constructor.
@@ -114,6 +112,7 @@ pub fn analyze_match<'p, 'tcx>(
114112
) -> rustc::UsefulnessReport<'p, 'tcx> {
115113
// Arena to store the extra wildcards we construct during analysis.
116114
let wildcard_arena = tycx.pattern_arena;
115+
let scrut_ty = tycx.reveal_opaque_ty(scrut_ty);
117116
let scrut_validity = ValidityConstraint::from_bool(tycx.known_valid_scrutinee);
118117
let cx = MatchCtxt { tycx, wildcard_arena };
119118

compiler/rustc_pattern_analysis/src/lints.rs

+8-15
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use smallvec::SmallVec;
22

33
use rustc_data_structures::captures::Captures;
4-
use rustc_middle::ty::{self, Ty};
4+
use rustc_middle::ty;
55
use rustc_session::lint;
66
use rustc_session::lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS;
77
use rustc_span::Span;
@@ -12,10 +12,9 @@ use crate::errors::{
1212
OverlappingRangeEndpoints, Uncovered,
1313
};
1414
use crate::rustc::{
15-
Constructor, DeconstructedPat, MatchArm, MatchCtxt, PlaceCtxt, RustcMatchCheckCtxt,
15+
Constructor, DeconstructedPat, MatchArm, MatchCtxt, PlaceCtxt, RevealedTy, RustcMatchCheckCtxt,
1616
SplitConstructorSet, WitnessPat,
1717
};
18-
use crate::TypeCx;
1918

2019
/// A column of patterns in the matrix, where a column is the intuitive notion of "subpatterns that
2120
/// inspect the same subvalue/place".
@@ -48,14 +47,8 @@ impl<'p, 'tcx> PatternColumn<'p, 'tcx> {
4847
fn is_empty(&self) -> bool {
4948
self.patterns.is_empty()
5049
}
51-
fn head_ty(&self, cx: MatchCtxt<'_, 'p, 'tcx>) -> Option<Ty<'tcx>> {
52-
if self.patterns.len() == 0 {
53-
return None;
54-
}
55-
56-
let ty = self.patterns[0].ty();
57-
// FIXME(Nadrieril): `Cx` should only give us revealed types.
58-
Some(cx.tycx.reveal_opaque_ty(ty))
50+
fn head_ty(&self) -> Option<RevealedTy<'tcx>> {
51+
self.patterns.first().map(|pat| pat.ty())
5952
}
6053

6154
/// Do constructor splitting on the constructors of the column.
@@ -117,7 +110,7 @@ fn collect_nonexhaustive_missing_variants<'a, 'p, 'tcx>(
117110
cx: MatchCtxt<'a, 'p, 'tcx>,
118111
column: &PatternColumn<'p, 'tcx>,
119112
) -> Vec<WitnessPat<'p, 'tcx>> {
120-
let Some(ty) = column.head_ty(cx) else {
113+
let Some(ty) = column.head_ty() else {
121114
return Vec::new();
122115
};
123116
let pcx = &PlaceCtxt::new_dummy(cx, ty);
@@ -164,7 +157,7 @@ pub(crate) fn lint_nonexhaustive_missing_variants<'a, 'p, 'tcx>(
164157
cx: MatchCtxt<'a, 'p, 'tcx>,
165158
arms: &[MatchArm<'p, 'tcx>],
166159
pat_column: &PatternColumn<'p, 'tcx>,
167-
scrut_ty: Ty<'tcx>,
160+
scrut_ty: RevealedTy<'tcx>,
168161
) {
169162
let rcx: &RustcMatchCheckCtxt<'_, '_> = cx.tycx;
170163
if !matches!(
@@ -182,7 +175,7 @@ pub(crate) fn lint_nonexhaustive_missing_variants<'a, 'p, 'tcx>(
182175
rcx.match_lint_level,
183176
rcx.scrut_span,
184177
NonExhaustiveOmittedPattern {
185-
scrut_ty,
178+
scrut_ty: scrut_ty.inner(),
186179
uncovered: Uncovered::new(rcx.scrut_span, rcx, witnesses),
187180
},
188181
);
@@ -218,7 +211,7 @@ pub(crate) fn lint_overlapping_range_endpoints<'a, 'p, 'tcx>(
218211
cx: MatchCtxt<'a, 'p, 'tcx>,
219212
column: &PatternColumn<'p, 'tcx>,
220213
) {
221-
let Some(ty) = column.head_ty(cx) else {
214+
let Some(ty) = column.head_ty() else {
222215
return;
223216
};
224217
let pcx = &PlaceCtxt::new_dummy(cx, ty);

0 commit comments

Comments
 (0)