Rollup merge of #116715 - Nadrieril:patkind-error, r=oli-obk
Prevent more spurious unreachable pattern lints Continues the work of https://github.com/rust-lang/rust/pull/115937 by introducing `PatKind::Error`, to be used instead of `PatKind::Wild` when an error was raised during pattern lowering. Most of match checking lints are skipped when a `PatKind::Error` is encountered. This avoids confusing extra warnings when a pattern is malformed. Now `PatKind::Wild` should indicate an actual wildcard pattern. r? `@oli-obk`
This commit is contained in:
commit
7d1b24f4bc
@ -19,11 +19,12 @@
|
||||
use rustc_middle::mir::interpret::AllocId;
|
||||
use rustc_middle::mir::{self, BinOp, BorrowKind, FakeReadCause, Mutability, UnOp};
|
||||
use rustc_middle::ty::adjustment::PointerCoercion;
|
||||
use rustc_middle::ty::GenericArgsRef;
|
||||
use rustc_middle::ty::{self, AdtDef, FnSig, List, Ty, UpvarArgs};
|
||||
use rustc_middle::ty::{CanonicalUserType, CanonicalUserTypeAnnotation};
|
||||
use rustc_middle::ty::{
|
||||
self, AdtDef, CanonicalUserType, CanonicalUserTypeAnnotation, FnSig, GenericArgsRef, List, Ty,
|
||||
UpvarArgs,
|
||||
};
|
||||
use rustc_span::def_id::LocalDefId;
|
||||
use rustc_span::{sym, Span, Symbol, DUMMY_SP};
|
||||
use rustc_span::{sym, ErrorGuaranteed, Span, Symbol, DUMMY_SP};
|
||||
use rustc_target::abi::{FieldIdx, VariantIdx};
|
||||
use rustc_target::asm::InlineAsmRegOrRegClass;
|
||||
use std::fmt;
|
||||
@ -632,7 +633,7 @@ fn walk_(&self, it: &mut impl FnMut(&Pat<'tcx>) -> bool) {
|
||||
|
||||
use PatKind::*;
|
||||
match &self.kind {
|
||||
Wild | Range(..) | Binding { subpattern: None, .. } | Constant { .. } => {}
|
||||
Wild | Range(..) | Binding { subpattern: None, .. } | Constant { .. } | Error(_) => {}
|
||||
AscribeUserType { subpattern, .. }
|
||||
| Binding { subpattern: Some(subpattern), .. }
|
||||
| Deref { subpattern } => subpattern.walk_(it),
|
||||
@ -647,6 +648,21 @@ fn walk_(&self, it: &mut impl FnMut(&Pat<'tcx>) -> bool) {
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether the pattern has a `PatKind::Error` nested within.
|
||||
pub fn pat_error_reported(&self) -> Result<(), ErrorGuaranteed> {
|
||||
let mut error = None;
|
||||
self.walk(|pat| {
|
||||
if let PatKind::Error(e) = pat.kind && error.is_none() {
|
||||
error = Some(e);
|
||||
}
|
||||
error.is_none()
|
||||
});
|
||||
match error {
|
||||
None => Ok(()),
|
||||
Some(e) => Err(e),
|
||||
}
|
||||
}
|
||||
|
||||
/// Walk the pattern in left-to-right order.
|
||||
///
|
||||
/// If you always want to recurse, prefer this method over `walk`.
|
||||
@ -771,6 +787,10 @@ pub enum PatKind<'tcx> {
|
||||
Or {
|
||||
pats: Box<[Box<Pat<'tcx>>]>,
|
||||
},
|
||||
|
||||
/// An error has been encountered during lowering. We probably shouldn't report more lints
|
||||
/// related to this pattern.
|
||||
Error(ErrorGuaranteed),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, HashStable, TypeVisitable)]
|
||||
@ -934,6 +954,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
PatKind::Error(_) => write!(f, "<error>"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -226,7 +226,7 @@ pub fn walk_pat<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, pat: &Pat<'
|
||||
is_primary: _,
|
||||
name: _,
|
||||
} => visitor.visit_pat(&subpattern),
|
||||
Binding { .. } | Wild => {}
|
||||
Binding { .. } | Wild | Error(_) => {}
|
||||
Variant { subpatterns, adt_def: _, args: _, variant_index: _ } | Leaf { subpatterns } => {
|
||||
for subpattern in subpatterns {
|
||||
visitor.visit_pat(&subpattern.pattern);
|
||||
|
@ -814,7 +814,10 @@ pub(super) fn visit_primary_bindings(
|
||||
}
|
||||
}
|
||||
|
||||
PatKind::Constant { .. } | PatKind::Range { .. } | PatKind::Wild => {}
|
||||
PatKind::Constant { .. }
|
||||
| PatKind::Range { .. }
|
||||
| PatKind::Wild
|
||||
| PatKind::Error(_) => {}
|
||||
|
||||
PatKind::Deref { ref subpattern } => {
|
||||
self.visit_primary_bindings(subpattern, pattern_user_ty.deref(), f);
|
||||
|
@ -168,7 +168,7 @@ fn simplify_match_pair<'pat>(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
PatKind::Wild => {
|
||||
PatKind::Wild | PatKind::Error(_) => {
|
||||
// nothing left to do
|
||||
Ok(())
|
||||
}
|
||||
|
@ -77,7 +77,8 @@ pub(super) fn test<'pat>(&mut self, match_pair: &MatchPair<'pat, 'tcx>) -> Test<
|
||||
| PatKind::Wild
|
||||
| PatKind::Binding { .. }
|
||||
| PatKind::Leaf { .. }
|
||||
| PatKind::Deref { .. } => self.error_simplifiable(match_pair),
|
||||
| PatKind::Deref { .. }
|
||||
| PatKind::Error(_) => self.error_simplifiable(match_pair),
|
||||
}
|
||||
}
|
||||
|
||||
@ -111,7 +112,8 @@ pub(super) fn add_cases_to_switch<'pat>(
|
||||
| PatKind::Binding { .. }
|
||||
| PatKind::AscribeUserType { .. }
|
||||
| PatKind::Leaf { .. }
|
||||
| PatKind::Deref { .. } => {
|
||||
| PatKind::Deref { .. }
|
||||
| PatKind::Error(_) => {
|
||||
// don't know how to add these patterns to a switch
|
||||
false
|
||||
}
|
||||
|
@ -224,7 +224,8 @@ fn visit_pat(&mut self, pat: &Pat<'tcx>) {
|
||||
PatKind::Wild |
|
||||
// these just wrap other patterns
|
||||
PatKind::Or { .. } |
|
||||
PatKind::AscribeUserType { .. } => {}
|
||||
PatKind::AscribeUserType { .. } |
|
||||
PatKind::Error(_) => {}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -19,7 +19,7 @@
|
||||
use rustc_middle::thir::visit::{self, Visitor};
|
||||
use rustc_middle::thir::*;
|
||||
use rustc_middle::ty::print::with_no_trimmed_paths;
|
||||
use rustc_middle::ty::{self, AdtDef, Ty, TyCtxt, TypeVisitableExt};
|
||||
use rustc_middle::ty::{self, AdtDef, Ty, TyCtxt};
|
||||
use rustc_session::lint::builtin::{
|
||||
BINDINGS_WITH_VARIANT_NAME, IRREFUTABLE_LET_PATTERNS, UNREACHABLE_PATTERNS,
|
||||
};
|
||||
@ -231,6 +231,10 @@ fn check_let(&mut self, pat: &Pat<'tcx>, scrutinee: ExprId, source: LetSource, s
|
||||
if let LetSource::None = source {
|
||||
return;
|
||||
}
|
||||
if let Err(err) = pat.pat_error_reported() {
|
||||
self.error = Err(err);
|
||||
return;
|
||||
}
|
||||
self.check_patterns(pat, Refutable);
|
||||
let mut cx = self.new_cx(self.lint_level, true);
|
||||
let tpat = self.lower_pattern(&mut cx, pat);
|
||||
@ -252,6 +256,10 @@ fn check_match(
|
||||
self.with_lint_level(arm.lint_level, |this| {
|
||||
this.check_patterns(&arm.pattern, Refutable);
|
||||
});
|
||||
if let Err(err) = arm.pattern.pat_error_reported() {
|
||||
self.error = Err(err);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
let tarms: Vec<_> = arms
|
||||
@ -334,7 +342,8 @@ fn check_let_chain(
|
||||
// and record chain members that aren't let exprs.
|
||||
let mut chain_refutabilities = Vec::new();
|
||||
|
||||
let add = |expr: ExprId, mut local_lint_level| {
|
||||
let mut error = Ok(());
|
||||
let mut add = |expr: ExprId, mut local_lint_level| {
|
||||
// `local_lint_level` is the lint level enclosing the pattern inside `expr`.
|
||||
let mut expr = &self.thir[expr];
|
||||
debug!(?expr, ?local_lint_level, "add");
|
||||
@ -348,6 +357,10 @@ fn check_let_chain(
|
||||
debug!(?expr, ?local_lint_level, "after scopes");
|
||||
match expr.kind {
|
||||
ExprKind::Let { box ref pat, expr: _ } => {
|
||||
if let Err(err) = pat.pat_error_reported() {
|
||||
error = Err(err);
|
||||
return None;
|
||||
}
|
||||
let mut ncx = self.new_cx(local_lint_level, true);
|
||||
let tpat = self.lower_pattern(&mut ncx, pat);
|
||||
let refutable = !is_let_irrefutable(&mut ncx, local_lint_level, tpat);
|
||||
@ -380,6 +393,11 @@ fn check_let_chain(
|
||||
debug!(?chain_refutabilities);
|
||||
chain_refutabilities.reverse();
|
||||
|
||||
if error.is_err() {
|
||||
self.error = error;
|
||||
return;
|
||||
}
|
||||
|
||||
// Third, emit the actual warnings.
|
||||
if chain_refutabilities.iter().all(|r| matches!(*r, Some((_, false)))) {
|
||||
// The entire chain is made up of irrefutable `let` statements
|
||||
@ -426,6 +444,12 @@ fn check_let_chain(
|
||||
|
||||
#[instrument(level = "trace", skip(self))]
|
||||
fn check_irrefutable(&mut self, pat: &Pat<'tcx>, origin: &str, sp: Option<Span>) {
|
||||
// If we got errors while lowering, don't emit anything more.
|
||||
if let Err(err) = pat.pat_error_reported() {
|
||||
self.error = Err(err);
|
||||
return;
|
||||
}
|
||||
|
||||
let mut cx = self.new_cx(self.lint_level, false);
|
||||
|
||||
let pattern = self.lower_pattern(&mut cx, pat);
|
||||
@ -682,12 +706,6 @@ fn non_exhaustive_match<'p, 'tcx>(
|
||||
arms: &[ArmId],
|
||||
expr_span: Span,
|
||||
) -> ErrorGuaranteed {
|
||||
for &arm in arms {
|
||||
if let Err(err) = thir[arm].pattern.error_reported() {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
let is_empty_match = arms.is_empty();
|
||||
let non_empty_enum = match scrut_ty.kind() {
|
||||
ty::Adt(def, _) => def.is_enum() && !def.variants().is_empty(),
|
||||
|
@ -196,9 +196,7 @@ fn to_pat(
|
||||
};
|
||||
// All branches above emitted an error. Don't print any more lints.
|
||||
// We errored. Signal that in the pattern, so that follow up errors can be silenced.
|
||||
let kind = PatKind::Constant {
|
||||
value: mir::Const::Ty(ty::Const::new_error(self.tcx(), e, cv.ty())),
|
||||
};
|
||||
let kind = PatKind::Error(e);
|
||||
return Box::new(Pat { span: self.span, ty: cv.ty(), kind });
|
||||
} else if !self.saw_const_match_lint.get() {
|
||||
if let Some(mir_structural_match_violation) = mir_structural_match_violation {
|
||||
@ -351,7 +349,7 @@ fn recur(
|
||||
let e = tcx.sess.emit_err(InvalidPattern { span, non_sm_ty: ty });
|
||||
self.saw_const_match_error.set(Some(e));
|
||||
// We errored. Signal that in the pattern, so that follow up errors can be silenced.
|
||||
PatKind::Constant { value: mir::Const::Ty(ty::Const::new_error(tcx, e, ty)) }
|
||||
PatKind::Error(e)
|
||||
}
|
||||
ty::Adt(adt_def, _) if !self.type_marked_structural(ty) => {
|
||||
debug!("adt_def {:?} has !type_marked_structural for cv.ty: {:?}", adt_def, ty,);
|
||||
@ -359,7 +357,7 @@ fn recur(
|
||||
let e = tcx.sess.emit_err(err);
|
||||
self.saw_const_match_error.set(Some(e));
|
||||
// We errored. Signal that in the pattern, so that follow up errors can be silenced.
|
||||
PatKind::Constant { value: mir::Const::Ty(ty::Const::new_error(tcx, e, ty)) }
|
||||
PatKind::Error(e)
|
||||
}
|
||||
ty::Adt(adt_def, args) if adt_def.is_enum() => {
|
||||
let (&variant_index, fields) = cv.unwrap_branch().split_first().unwrap();
|
||||
@ -434,17 +432,13 @@ fn recur(
|
||||
} else {
|
||||
if let Some(e) = self.saw_const_match_error.get() {
|
||||
// We already errored. Signal that in the pattern, so that follow up errors can be silenced.
|
||||
PatKind::Constant {
|
||||
value: mir::Const::Ty(ty::Const::new_error(tcx, e, ty)),
|
||||
}
|
||||
PatKind::Error(e)
|
||||
} else {
|
||||
let err = TypeNotStructural { span, non_sm_ty: *pointee_ty };
|
||||
let e = tcx.sess.emit_err(err);
|
||||
self.saw_const_match_error.set(Some(e));
|
||||
// We errored. Signal that in the pattern, so that follow up errors can be silenced.
|
||||
PatKind::Constant {
|
||||
value: mir::Const::Ty(ty::Const::new_error(tcx, e, ty)),
|
||||
}
|
||||
PatKind::Error(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -456,9 +450,7 @@ fn recur(
|
||||
let err = UnsizedPattern { span, non_sm_ty: *pointee_ty };
|
||||
let e = tcx.sess.emit_err(err);
|
||||
// We errored. Signal that in the pattern, so that follow up errors can be silenced.
|
||||
PatKind::Constant {
|
||||
value: mir::Const::Ty(ty::Const::new_error(tcx, e, ty)),
|
||||
}
|
||||
PatKind::Error(e)
|
||||
} else {
|
||||
let old = self.behind_reference.replace(true);
|
||||
// `b"foo"` produces a `&[u8; 3]`, but you can't use constants of array type when
|
||||
@ -489,7 +481,7 @@ fn recur(
|
||||
let e = tcx.sess.emit_err(err);
|
||||
self.saw_const_match_error.set(Some(e));
|
||||
// We errored. Signal that in the pattern, so that follow up errors can be silenced.
|
||||
PatKind::Constant { value: mir::Const::Ty(ty::Const::new_error(tcx, e, ty)) }
|
||||
PatKind::Error(e)
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1525,6 +1525,10 @@ pub(crate) fn from_pat(cx: &MatchCheckCtxt<'p, 'tcx>, pat: &Pat<'tcx>) -> Self {
|
||||
let pats = expand_or_pat(pat);
|
||||
fields = Fields::from_iter(cx, pats.into_iter().map(mkpat));
|
||||
}
|
||||
PatKind::Error(_) => {
|
||||
ctor = Opaque;
|
||||
fields = Fields::empty();
|
||||
}
|
||||
}
|
||||
DeconstructedPat::new(ctor, fields, pat.ty, pat.span)
|
||||
}
|
||||
|
@ -252,10 +252,8 @@ fn lower_pattern_unadjusted(&mut self, pat: &'tcx hir::Pat<'tcx>) -> Box<Pat<'tc
|
||||
|
||||
hir::PatKind::Range(ref lo_expr, ref hi_expr, end) => {
|
||||
let (lo_expr, hi_expr) = (lo_expr.as_deref(), hi_expr.as_deref());
|
||||
// FIXME?: returning `_` can cause inaccurate "unreachable" warnings. This can be
|
||||
// fixed by returning `PatKind::Const(ConstKind::Error(...))` if #115937 gets
|
||||
// merged.
|
||||
self.lower_pattern_range(lo_expr, hi_expr, end, ty, span).unwrap_or(PatKind::Wild)
|
||||
self.lower_pattern_range(lo_expr, hi_expr, end, ty, span)
|
||||
.unwrap_or_else(PatKind::Error)
|
||||
}
|
||||
|
||||
hir::PatKind::Path(ref qpath) => {
|
||||
@ -423,9 +421,9 @@ fn lower_variant_or_leaf(
|
||||
if adt_def.is_enum() {
|
||||
let args = match ty.kind() {
|
||||
ty::Adt(_, args) | ty::FnDef(_, args) => args,
|
||||
ty::Error(_) => {
|
||||
ty::Error(e) => {
|
||||
// Avoid ICE (#50585)
|
||||
return PatKind::Wild;
|
||||
return PatKind::Error(*e);
|
||||
}
|
||||
_ => bug!("inappropriate type for def: {:?}", ty),
|
||||
};
|
||||
@ -452,7 +450,7 @@ fn lower_variant_or_leaf(
|
||||
| Res::SelfTyAlias { .. }
|
||||
| Res::SelfCtor(..) => PatKind::Leaf { subpatterns },
|
||||
_ => {
|
||||
match res {
|
||||
let e = match res {
|
||||
Res::Def(DefKind::ConstParam, _) => {
|
||||
self.tcx.sess.emit_err(ConstParamInPattern { span })
|
||||
}
|
||||
@ -461,7 +459,7 @@ fn lower_variant_or_leaf(
|
||||
}
|
||||
_ => self.tcx.sess.emit_err(NonConstPath { span }),
|
||||
};
|
||||
PatKind::Wild
|
||||
PatKind::Error(e)
|
||||
}
|
||||
};
|
||||
|
||||
@ -513,14 +511,13 @@ fn lower_path(&mut self, qpath: &hir::QPath<'_>, id: hir::HirId, span: Span) ->
|
||||
// It should be assoc consts if there's no error but we cannot resolve it.
|
||||
debug_assert!(is_associated_const);
|
||||
|
||||
self.tcx.sess.emit_err(AssocConstInPattern { span });
|
||||
|
||||
return pat_from_kind(PatKind::Wild);
|
||||
let e = self.tcx.sess.emit_err(AssocConstInPattern { span });
|
||||
return pat_from_kind(PatKind::Error(e));
|
||||
}
|
||||
|
||||
Err(_) => {
|
||||
self.tcx.sess.emit_err(CouldNotEvalConstPattern { span });
|
||||
return pat_from_kind(PatKind::Wild);
|
||||
let e = self.tcx.sess.emit_err(CouldNotEvalConstPattern { span });
|
||||
return pat_from_kind(PatKind::Error(e));
|
||||
}
|
||||
};
|
||||
|
||||
@ -574,12 +571,12 @@ fn lower_path(&mut self, qpath: &hir::QPath<'_>, id: hir::HirId, span: Span) ->
|
||||
Err(ErrorHandled::TooGeneric(_)) => {
|
||||
// While `Reported | Linted` cases will have diagnostics emitted already
|
||||
// it is not true for TooGeneric case, so we need to give user more information.
|
||||
self.tcx.sess.emit_err(ConstPatternDependsOnGenericParameter { span });
|
||||
pat_from_kind(PatKind::Wild)
|
||||
let e = self.tcx.sess.emit_err(ConstPatternDependsOnGenericParameter { span });
|
||||
pat_from_kind(PatKind::Error(e))
|
||||
}
|
||||
Err(_) => {
|
||||
self.tcx.sess.emit_err(CouldNotEvalConstPattern { span });
|
||||
pat_from_kind(PatKind::Wild)
|
||||
let e = self.tcx.sess.emit_err(CouldNotEvalConstPattern { span });
|
||||
pat_from_kind(PatKind::Error(e))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -629,7 +626,7 @@ fn lower_inline_const(
|
||||
let uneval = mir::UnevaluatedConst { def: def_id.to_def_id(), args, promoted: None };
|
||||
debug_assert!(!args.has_free_regions());
|
||||
|
||||
let ct = ty::UnevaluatedConst { def: def_id.to_def_id(), args: args };
|
||||
let ct = ty::UnevaluatedConst { def: def_id.to_def_id(), args };
|
||||
// First try using a valtree in order to destructure the constant into a pattern.
|
||||
// FIXME: replace "try to do a thing, then fall back to another thing"
|
||||
// but something more principled, like a trait query checking whether this can be turned into a valtree.
|
||||
@ -649,10 +646,10 @@ fn lower_inline_const(
|
||||
Ok(val) => self.const_to_pat(mir::Const::Val(val, ty), id, span, None).kind,
|
||||
Err(ErrorHandled::TooGeneric(_)) => {
|
||||
// If we land here it means the const can't be evaluated because it's `TooGeneric`.
|
||||
self.tcx.sess.emit_err(ConstPatternDependsOnGenericParameter { span });
|
||||
PatKind::Wild
|
||||
let e = self.tcx.sess.emit_err(ConstPatternDependsOnGenericParameter { span });
|
||||
PatKind::Error(e)
|
||||
}
|
||||
Err(ErrorHandled::Reported(..)) => PatKind::Wild,
|
||||
Err(ErrorHandled::Reported(err, ..)) => PatKind::Error(err.into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -685,7 +682,7 @@ fn lower_lit(&mut self, expr: &'tcx hir::Expr<'tcx>) -> PatKind<'tcx> {
|
||||
Ok(constant) => {
|
||||
self.const_to_pat(Const::Ty(constant), expr.hir_id, lit.span, None).kind
|
||||
}
|
||||
Err(LitToConstError::Reported(_)) => PatKind::Wild,
|
||||
Err(LitToConstError::Reported(e)) => PatKind::Error(e),
|
||||
Err(LitToConstError::TypeError) => bug!("lower_lit: had type error"),
|
||||
}
|
||||
}
|
||||
@ -791,6 +788,7 @@ fn fold_with<F: PatternFolder<'tcx>>(&self, folder: &mut F) -> Self {
|
||||
fn super_fold_with<F: PatternFolder<'tcx>>(&self, folder: &mut F) -> Self {
|
||||
match *self {
|
||||
PatKind::Wild => PatKind::Wild,
|
||||
PatKind::Error(e) => PatKind::Error(e),
|
||||
PatKind::AscribeUserType {
|
||||
ref subpattern,
|
||||
ascription: Ascription { ref annotation, variance },
|
||||
|
@ -757,6 +757,9 @@ fn print_pat_kind(&mut self, pat_kind: &PatKind<'tcx>, depth_lvl: usize) {
|
||||
print_indented!(self, "]", depth_lvl + 2);
|
||||
print_indented!(self, "}", depth_lvl + 1);
|
||||
}
|
||||
PatKind::Error(_) => {
|
||||
print_indented!(self, "Error", depth_lvl + 1);
|
||||
}
|
||||
}
|
||||
|
||||
print_indented!(self, "}", depth_lvl);
|
||||
|
@ -7,17 +7,5 @@ LL | WHAT_A_TYPE => 0,
|
||||
= note: the traits must be derived, manual `impl`s are not sufficient
|
||||
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details
|
||||
|
||||
error[E0015]: cannot match on `TypeId` in constant functions
|
||||
--> $DIR/typeid-equality-by-subtyping.rs:18:9
|
||||
|
|
||||
LL | WHAT_A_TYPE => 0,
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
= note: `TypeId` cannot be compared in compile-time, and therefore cannot be used in `match`es
|
||||
note: impl defined here, but it is not `const`
|
||||
--> $SRC_DIR/core/src/any.rs:LL:COL
|
||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||
error: aborting due to previous error
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0015`.
|
||||
|
@ -52,7 +52,6 @@ fn main() {
|
||||
BAR => {}
|
||||
//~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]`
|
||||
_ => {}
|
||||
//~^ ERROR unreachable pattern
|
||||
}
|
||||
|
||||
match BAR {
|
||||
@ -60,7 +59,6 @@ fn main() {
|
||||
//~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]`
|
||||
Bar => {}
|
||||
_ => {}
|
||||
//~^ ERROR unreachable pattern
|
||||
}
|
||||
|
||||
match BAR {
|
||||
|
@ -38,7 +38,16 @@ LL | BAR => {}
|
||||
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details
|
||||
|
||||
error: to use a constant of type `Bar` in a pattern, `Bar` must be annotated with `#[derive(PartialEq, Eq)]`
|
||||
--> $DIR/consts-opaque.rs:59:9
|
||||
--> $DIR/consts-opaque.rs:58:9
|
||||
|
|
||||
LL | BAR => {}
|
||||
| ^^^
|
||||
|
|
||||
= note: the traits must be derived, manual `impl`s are not sufficient
|
||||
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details
|
||||
|
||||
error: to use a constant of type `Bar` in a pattern, `Bar` must be annotated with `#[derive(PartialEq, Eq)]`
|
||||
--> $DIR/consts-opaque.rs:65:9
|
||||
|
|
||||
LL | BAR => {}
|
||||
| ^^^
|
||||
@ -55,17 +64,8 @@ LL | BAR => {}
|
||||
= note: the traits must be derived, manual `impl`s are not sufficient
|
||||
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details
|
||||
|
||||
error: to use a constant of type `Bar` in a pattern, `Bar` must be annotated with `#[derive(PartialEq, Eq)]`
|
||||
--> $DIR/consts-opaque.rs:69:9
|
||||
|
|
||||
LL | BAR => {}
|
||||
| ^^^
|
||||
|
|
||||
= note: the traits must be derived, manual `impl`s are not sufficient
|
||||
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details
|
||||
|
||||
error: to use a constant of type `Baz` in a pattern, `Baz` must be annotated with `#[derive(PartialEq, Eq)]`
|
||||
--> $DIR/consts-opaque.rs:75:9
|
||||
--> $DIR/consts-opaque.rs:73:9
|
||||
|
|
||||
LL | BAZ => {}
|
||||
| ^^^
|
||||
@ -74,7 +74,7 @@ LL | BAZ => {}
|
||||
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details
|
||||
|
||||
error: to use a constant of type `Baz` in a pattern, `Baz` must be annotated with `#[derive(PartialEq, Eq)]`
|
||||
--> $DIR/consts-opaque.rs:83:9
|
||||
--> $DIR/consts-opaque.rs:81:9
|
||||
|
|
||||
LL | BAZ => {}
|
||||
| ^^^
|
||||
@ -83,7 +83,7 @@ LL | BAZ => {}
|
||||
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details
|
||||
|
||||
error: to use a constant of type `Baz` in a pattern, `Baz` must be annotated with `#[derive(PartialEq, Eq)]`
|
||||
--> $DIR/consts-opaque.rs:89:9
|
||||
--> $DIR/consts-opaque.rs:87:9
|
||||
|
|
||||
LL | BAZ => {}
|
||||
| ^^^
|
||||
@ -91,37 +91,14 @@ LL | BAZ => {}
|
||||
= note: the traits must be derived, manual `impl`s are not sufficient
|
||||
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/consts-opaque.rs:54:9
|
||||
|
|
||||
LL | Bar => {}
|
||||
| --- matches any value
|
||||
...
|
||||
LL | _ => {}
|
||||
| ^ unreachable pattern
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/consts-opaque.rs:6:9
|
||||
|
|
||||
LL | #![deny(unreachable_patterns)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/consts-opaque.rs:62:9
|
||||
|
|
||||
LL | Bar => {}
|
||||
| --- matches any value
|
||||
LL | _ => {}
|
||||
| ^ unreachable pattern
|
||||
|
||||
error[E0004]: non-exhaustive patterns: `Wrap(_)` not covered
|
||||
--> $DIR/consts-opaque.rs:124:11
|
||||
--> $DIR/consts-opaque.rs:122:11
|
||||
|
|
||||
LL | match WRAPQUUX {
|
||||
| ^^^^^^^^ pattern `Wrap(_)` not covered
|
||||
|
|
||||
note: `Wrap<fn(usize, usize) -> usize>` defined here
|
||||
--> $DIR/consts-opaque.rs:106:12
|
||||
--> $DIR/consts-opaque.rs:104:12
|
||||
|
|
||||
LL | struct Wrap<T>(T);
|
||||
| ^^^^
|
||||
@ -132,6 +109,6 @@ LL ~ WRAPQUUX => {},
|
||||
LL + Wrap(_) => todo!()
|
||||
|
|
||||
|
||||
error: aborting due to 12 previous errors; 1 warning emitted
|
||||
error: aborting due to 10 previous errors; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0004`.
|
||||
|
Loading…
Reference in New Issue
Block a user