thir::pattern: update some comments and error type names
This commit is contained in:
parent
635c4a5e61
commit
d34e15e740
2 changed files with 24 additions and 17 deletions
|
@ -732,12 +732,16 @@ pub enum PatKind<'tcx> {
|
||||||
},
|
},
|
||||||
|
|
||||||
/// One of the following:
|
/// One of the following:
|
||||||
/// * `&str`, which will be handled as a string pattern and thus exhaustiveness
|
/// * `&str` (represented as a valtree), which will be handled as a string pattern and thus
|
||||||
/// checking will detect if you use the same string twice in different patterns.
|
/// exhaustiveness checking will detect if you use the same string twice in different
|
||||||
/// * integer, bool, char or float, which will be handled by exhaustiveness to cover exactly
|
/// patterns.
|
||||||
/// its own value, similar to `&str`, but these values are much simpler.
|
/// * integer, bool, char or float (represented as a valtree), which will be handled by
|
||||||
/// * Opaque constants, that must not be matched structurally. So anything that does not derive
|
/// exhaustiveness to cover exactly its own value, similar to `&str`, but these values are
|
||||||
/// `PartialEq` and `Eq`.
|
/// much simpler.
|
||||||
|
/// * Opaque constants (represented as `mir::ConstValue`), that must not be matched
|
||||||
|
/// structurally. So anything that does not derive `PartialEq` and `Eq`.
|
||||||
|
///
|
||||||
|
/// These are always compared with the matched place using (the semantics of) `PartialEq`.
|
||||||
Constant {
|
Constant {
|
||||||
value: mir::ConstantKind<'tcx>,
|
value: mir::ConstantKind<'tcx>,
|
||||||
},
|
},
|
||||||
|
|
|
@ -24,6 +24,8 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
||||||
/// Converts an evaluated constant to a pattern (if possible).
|
/// Converts an evaluated constant to a pattern (if possible).
|
||||||
/// This means aggregate values (like structs and enums) are converted
|
/// This means aggregate values (like structs and enums) are converted
|
||||||
/// to a pattern that matches the value (as if you'd compared via structural equality).
|
/// to a pattern that matches the value (as if you'd compared via structural equality).
|
||||||
|
///
|
||||||
|
/// `cv` must be a valtree or a `mir::ConstValue`.
|
||||||
#[instrument(level = "debug", skip(self), ret)]
|
#[instrument(level = "debug", skip(self), ret)]
|
||||||
pub(super) fn const_to_pat(
|
pub(super) fn const_to_pat(
|
||||||
&self,
|
&self,
|
||||||
|
@ -64,12 +66,8 @@ struct ConstToPat<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This error type signals that we encountered a non-struct-eq situation.
|
/// This error type signals that we encountered a non-struct-eq situation.
|
||||||
/// We bubble this up in order to get back to the reference destructuring and make that emit
|
|
||||||
/// a const pattern instead of a deref pattern. This allows us to simply call `PartialEq::eq`
|
|
||||||
/// on such patterns (since that function takes a reference) and not have to jump through any
|
|
||||||
/// hoops to get a reference to the value.
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct FallbackToConstRef;
|
struct FallbackToOpaqueConst;
|
||||||
|
|
||||||
impl<'tcx> ConstToPat<'tcx> {
|
impl<'tcx> ConstToPat<'tcx> {
|
||||||
fn new(
|
fn new(
|
||||||
|
@ -136,7 +134,7 @@ impl<'tcx> ConstToPat<'tcx> {
|
||||||
}
|
}
|
||||||
ty::ConstKind::Value(valtree) => self
|
ty::ConstKind::Value(valtree) => self
|
||||||
.recur(valtree, cv.ty(), mir_structural_match_violation.unwrap_or(false))
|
.recur(valtree, cv.ty(), mir_structural_match_violation.unwrap_or(false))
|
||||||
.unwrap_or_else(|_| {
|
.unwrap_or_else(|_: FallbackToOpaqueConst| {
|
||||||
Box::new(Pat {
|
Box::new(Pat {
|
||||||
span: self.span,
|
span: self.span,
|
||||||
ty: cv.ty(),
|
ty: cv.ty(),
|
||||||
|
@ -266,7 +264,7 @@ impl<'tcx> ConstToPat<'tcx> {
|
||||||
fn field_pats(
|
fn field_pats(
|
||||||
&self,
|
&self,
|
||||||
vals: impl Iterator<Item = (ValTree<'tcx>, Ty<'tcx>)>,
|
vals: impl Iterator<Item = (ValTree<'tcx>, Ty<'tcx>)>,
|
||||||
) -> Result<Vec<FieldPat<'tcx>>, FallbackToConstRef> {
|
) -> Result<Vec<FieldPat<'tcx>>, FallbackToOpaqueConst> {
|
||||||
vals.enumerate()
|
vals.enumerate()
|
||||||
.map(|(idx, (val, ty))| {
|
.map(|(idx, (val, ty))| {
|
||||||
let field = FieldIdx::new(idx);
|
let field = FieldIdx::new(idx);
|
||||||
|
@ -284,7 +282,7 @@ impl<'tcx> ConstToPat<'tcx> {
|
||||||
cv: ValTree<'tcx>,
|
cv: ValTree<'tcx>,
|
||||||
ty: Ty<'tcx>,
|
ty: Ty<'tcx>,
|
||||||
mir_structural_match_violation: bool,
|
mir_structural_match_violation: bool,
|
||||||
) -> Result<Box<Pat<'tcx>>, FallbackToConstRef> {
|
) -> Result<Box<Pat<'tcx>>, FallbackToOpaqueConst> {
|
||||||
let id = self.id;
|
let id = self.id;
|
||||||
let span = self.span;
|
let span = self.span;
|
||||||
let tcx = self.tcx();
|
let tcx = self.tcx();
|
||||||
|
@ -299,7 +297,7 @@ impl<'tcx> ConstToPat<'tcx> {
|
||||||
span,
|
span,
|
||||||
FloatPattern,
|
FloatPattern,
|
||||||
);
|
);
|
||||||
return Err(FallbackToConstRef);
|
return Err(FallbackToOpaqueConst);
|
||||||
}
|
}
|
||||||
// If the type is not structurally comparable, just emit the constant directly,
|
// If the type is not structurally comparable, just emit the constant directly,
|
||||||
// causing the pattern match code to treat it opaquely.
|
// causing the pattern match code to treat it opaquely.
|
||||||
|
@ -323,11 +321,12 @@ impl<'tcx> ConstToPat<'tcx> {
|
||||||
// Since we are behind a reference, we can just bubble the error up so we get a
|
// Since we are behind a reference, we can just bubble the error up so we get a
|
||||||
// constant at reference type, making it easy to let the fallback call
|
// constant at reference type, making it easy to let the fallback call
|
||||||
// `PartialEq::eq` on it.
|
// `PartialEq::eq` on it.
|
||||||
return Err(FallbackToConstRef);
|
return Err(FallbackToOpaqueConst);
|
||||||
}
|
}
|
||||||
ty::FnDef(..) => {
|
ty::FnDef(..) => {
|
||||||
self.saw_const_match_error.set(true);
|
self.saw_const_match_error.set(true);
|
||||||
tcx.sess.emit_err(InvalidPattern { span, non_sm_ty: ty });
|
tcx.sess.emit_err(InvalidPattern { span, non_sm_ty: ty });
|
||||||
|
// We errored, so the pattern we generate is irrelevant.
|
||||||
PatKind::Wild
|
PatKind::Wild
|
||||||
}
|
}
|
||||||
ty::Adt(adt_def, _) if !self.type_marked_structural(ty) => {
|
ty::Adt(adt_def, _) if !self.type_marked_structural(ty) => {
|
||||||
|
@ -335,6 +334,7 @@ impl<'tcx> ConstToPat<'tcx> {
|
||||||
self.saw_const_match_error.set(true);
|
self.saw_const_match_error.set(true);
|
||||||
let err = TypeNotStructural { span, non_sm_ty: ty };
|
let err = TypeNotStructural { span, non_sm_ty: ty };
|
||||||
tcx.sess.emit_err(err);
|
tcx.sess.emit_err(err);
|
||||||
|
// We errored, so the pattern we generate is irrelevant.
|
||||||
PatKind::Wild
|
PatKind::Wild
|
||||||
}
|
}
|
||||||
ty::Adt(adt_def, args) if adt_def.is_enum() => {
|
ty::Adt(adt_def, args) if adt_def.is_enum() => {
|
||||||
|
@ -404,13 +404,14 @@ impl<'tcx> ConstToPat<'tcx> {
|
||||||
IndirectStructuralMatch { non_sm_ty: *pointee_ty },
|
IndirectStructuralMatch { non_sm_ty: *pointee_ty },
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return Err(FallbackToConstRef);
|
return Err(FallbackToOpaqueConst);
|
||||||
} else {
|
} else {
|
||||||
if !self.saw_const_match_error.get() {
|
if !self.saw_const_match_error.get() {
|
||||||
self.saw_const_match_error.set(true);
|
self.saw_const_match_error.set(true);
|
||||||
let err = TypeNotStructural { span, non_sm_ty: *pointee_ty };
|
let err = TypeNotStructural { span, non_sm_ty: *pointee_ty };
|
||||||
tcx.sess.emit_err(err);
|
tcx.sess.emit_err(err);
|
||||||
}
|
}
|
||||||
|
// We errored, so the pattern we generate is irrelevant.
|
||||||
PatKind::Wild
|
PatKind::Wild
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -423,6 +424,7 @@ impl<'tcx> ConstToPat<'tcx> {
|
||||||
tcx.sess.emit_err(err);
|
tcx.sess.emit_err(err);
|
||||||
|
|
||||||
// FIXME: introduce PatKind::Error to silence follow up diagnostics due to unreachable patterns.
|
// FIXME: introduce PatKind::Error to silence follow up diagnostics due to unreachable patterns.
|
||||||
|
// We errored, so the pattern we generate is irrelevant.
|
||||||
PatKind::Wild
|
PatKind::Wild
|
||||||
} else {
|
} else {
|
||||||
let old = self.behind_reference.replace(true);
|
let old = self.behind_reference.replace(true);
|
||||||
|
@ -453,6 +455,7 @@ impl<'tcx> ConstToPat<'tcx> {
|
||||||
self.saw_const_match_error.set(true);
|
self.saw_const_match_error.set(true);
|
||||||
let err = InvalidPattern { span, non_sm_ty: ty };
|
let err = InvalidPattern { span, non_sm_ty: ty };
|
||||||
tcx.sess.emit_err(err);
|
tcx.sess.emit_err(err);
|
||||||
|
// We errored, so the pattern we generate is irrelevant.
|
||||||
PatKind::Wild
|
PatKind::Wild
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue