Skip to content

Commit c4ce33c

Browse files
committed
Auto merge of #115887 - RalfJung:pat, r=oli-obk
thir::pattern: update some comments and error type names Follow-up to [these comments](#105750 (review)). Please carefully fact-check, I'm new to this area of the compiler!
2 parents 92009f2 + 12a1b55 commit c4ce33c

File tree

2 files changed

+27
-17
lines changed

2 files changed

+27
-17
lines changed

compiler/rustc_middle/src/thir.rs

+10-6
Original file line numberDiff line numberDiff line change
@@ -732,12 +732,16 @@ pub enum PatKind<'tcx> {
732732
},
733733

734734
/// One of the following:
735-
/// * `&str`, which will be handled as a string pattern and thus exhaustiveness
736-
/// checking will detect if you use the same string twice in different patterns.
737-
/// * integer, bool, char or float, which will be handled by exhaustiveness to cover exactly
738-
/// its own value, similar to `&str`, but these values are much simpler.
739-
/// * Opaque constants, that must not be matched structurally. So anything that does not derive
740-
/// `PartialEq` and `Eq`.
735+
/// * `&str` (represented as a valtree), which will be handled as a string pattern and thus
736+
/// exhaustiveness checking will detect if you use the same string twice in different
737+
/// patterns.
738+
/// * integer, bool, char or float (represented as a valtree), which will be handled by
739+
/// exhaustiveness to cover exactly its own value, similar to `&str`, but these values are
740+
/// much simpler.
741+
/// * Opaque constants (represented as `mir::ConstValue`), that must not be matched
742+
/// structurally. So anything that does not derive `PartialEq` and `Eq`.
743+
///
744+
/// These are always compared with the matched place using (the semantics of) `PartialEq`.
741745
Constant {
742746
value: mir::Const<'tcx>,
743747
},

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

+17-11
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
2424
/// Converts an evaluated constant to a pattern (if possible).
2525
/// This means aggregate values (like structs and enums) are converted
2626
/// to a pattern that matches the value (as if you'd compared via structural equality).
27+
///
28+
/// `cv` must be a valtree or a `mir::ConstValue`.
2729
#[instrument(level = "debug", skip(self), ret)]
2830
pub(super) fn const_to_pat(
2931
&self,
@@ -64,12 +66,10 @@ struct ConstToPat<'tcx> {
6466
}
6567

6668
/// This error type signals that we encountered a non-struct-eq situation.
67-
/// We bubble this up in order to get back to the reference destructuring and make that emit
68-
/// a const pattern instead of a deref pattern. This allows us to simply call `PartialEq::eq`
69-
/// on such patterns (since that function takes a reference) and not have to jump through any
70-
/// hoops to get a reference to the value.
69+
/// We will fall back to calling `PartialEq::eq` on such patterns,
70+
/// and exhaustiveness checking will consider them as matching nothing.
7171
#[derive(Debug)]
72-
struct FallbackToConstRef;
72+
struct FallbackToOpaqueConst;
7373

7474
impl<'tcx> ConstToPat<'tcx> {
7575
fn new(
@@ -136,7 +136,7 @@ impl<'tcx> ConstToPat<'tcx> {
136136
}
137137
ty::ConstKind::Value(valtree) => self
138138
.recur(valtree, cv.ty(), mir_structural_match_violation.unwrap_or(false))
139-
.unwrap_or_else(|_| {
139+
.unwrap_or_else(|_: FallbackToOpaqueConst| {
140140
Box::new(Pat {
141141
span: self.span,
142142
ty: cv.ty(),
@@ -285,7 +285,7 @@ impl<'tcx> ConstToPat<'tcx> {
285285
fn field_pats(
286286
&self,
287287
vals: impl Iterator<Item = (ValTree<'tcx>, Ty<'tcx>)>,
288-
) -> Result<Vec<FieldPat<'tcx>>, FallbackToConstRef> {
288+
) -> Result<Vec<FieldPat<'tcx>>, FallbackToOpaqueConst> {
289289
vals.enumerate()
290290
.map(|(idx, (val, ty))| {
291291
let field = FieldIdx::new(idx);
@@ -303,7 +303,7 @@ impl<'tcx> ConstToPat<'tcx> {
303303
cv: ValTree<'tcx>,
304304
ty: Ty<'tcx>,
305305
mir_structural_match_violation: bool,
306-
) -> Result<Box<Pat<'tcx>>, FallbackToConstRef> {
306+
) -> Result<Box<Pat<'tcx>>, FallbackToOpaqueConst> {
307307
let id = self.id;
308308
let span = self.span;
309309
let tcx = self.tcx();
@@ -318,7 +318,7 @@ impl<'tcx> ConstToPat<'tcx> {
318318
span,
319319
FloatPattern,
320320
);
321-
return Err(FallbackToConstRef);
321+
return Err(FallbackToOpaqueConst);
322322
}
323323
// If the type is not structurally comparable, just emit the constant directly,
324324
// causing the pattern match code to treat it opaquely.
@@ -342,18 +342,20 @@ impl<'tcx> ConstToPat<'tcx> {
342342
// Since we are behind a reference, we can just bubble the error up so we get a
343343
// constant at reference type, making it easy to let the fallback call
344344
// `PartialEq::eq` on it.
345-
return Err(FallbackToConstRef);
345+
return Err(FallbackToOpaqueConst);
346346
}
347347
ty::FnDef(..) => {
348348
self.saw_const_match_error.set(true);
349349
tcx.sess.emit_err(InvalidPattern { span, non_sm_ty: ty });
350+
// We errored, so the pattern we generate is irrelevant.
350351
PatKind::Wild
351352
}
352353
ty::Adt(adt_def, _) if !self.type_marked_structural(ty) => {
353354
debug!("adt_def {:?} has !type_marked_structural for cv.ty: {:?}", adt_def, ty,);
354355
self.saw_const_match_error.set(true);
355356
let err = TypeNotStructural { span, non_sm_ty: ty };
356357
tcx.sess.emit_err(err);
358+
// We errored, so the pattern we generate is irrelevant.
357359
PatKind::Wild
358360
}
359361
ty::Adt(adt_def, args) if adt_def.is_enum() => {
@@ -423,13 +425,15 @@ impl<'tcx> ConstToPat<'tcx> {
423425
IndirectStructuralMatch { non_sm_ty: *pointee_ty },
424426
);
425427
}
426-
return Err(FallbackToConstRef);
428+
return Err(FallbackToOpaqueConst);
427429
} else {
428430
if !self.saw_const_match_error.get() {
429431
self.saw_const_match_error.set(true);
430432
let err = TypeNotStructural { span, non_sm_ty: *pointee_ty };
431433
tcx.sess.emit_err(err);
432434
}
435+
tcx.sess.delay_span_bug(span, "`saw_const_match_error` set but no error?");
436+
// We errored, so the pattern we generate is irrelevant.
433437
PatKind::Wild
434438
}
435439
}
@@ -442,6 +446,7 @@ impl<'tcx> ConstToPat<'tcx> {
442446
tcx.sess.emit_err(err);
443447

444448
// FIXME: introduce PatKind::Error to silence follow up diagnostics due to unreachable patterns.
449+
// We errored, so the pattern we generate is irrelevant.
445450
PatKind::Wild
446451
} else {
447452
let old = self.behind_reference.replace(true);
@@ -472,6 +477,7 @@ impl<'tcx> ConstToPat<'tcx> {
472477
self.saw_const_match_error.set(true);
473478
let err = InvalidPattern { span, non_sm_ty: ty };
474479
tcx.sess.emit_err(err);
480+
// We errored, so the pattern we generate is irrelevant.
475481
PatKind::Wild
476482
}
477483
};

0 commit comments

Comments
 (0)