summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_mir_build/src/thir/pattern
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_mir_build/src/thir/pattern')
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/check_match.rs40
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs3
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs30
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/mod.rs14
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/usefulness.rs2
5 files changed, 46 insertions, 43 deletions
diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
index 858129c74..e369dba55 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
@@ -79,7 +79,10 @@ impl<'tcx> Visitor<'tcx> for MatchVisitor<'_, '_, 'tcx> {
intravisit::walk_local(self, loc);
let els = loc.els;
if let Some(init) = loc.init && els.is_some() {
- self.check_let(&loc.pat, init, loc.span);
+ // Build a span without the else { ... } as we don't want to underline
+ // the entire else block in the IDE setting.
+ let span = loc.span.with_hi(init.span.hi());
+ self.check_let(&loc.pat, init, span);
}
let (msg, sp) = match loc.source {
@@ -507,7 +510,7 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
_ => "aren't",
},
),
- " else { todo!() }".to_string(),
+ " else { todo!() }",
Applicability::HasPlaceholders,
);
}
@@ -561,7 +564,7 @@ fn check_for_bindings_named_same_as_variants(
&& let ty::Adt(edef, _) = pat_ty.kind()
&& edef.is_enum()
&& edef.variants().iter().any(|variant| {
- variant.ident(cx.tcx) == ident && variant.ctor_kind == CtorKind::Const
+ variant.ident(cx.tcx) == ident && variant.ctor_kind() == Some(CtorKind::Const)
})
{
let variant_count = edef.variants().len();
@@ -630,11 +633,6 @@ fn irrefutable_let_patterns(
count: usize,
span: Span,
) {
- let span = match source {
- LetSource::LetElse(span) => span,
- _ => span,
- };
-
macro_rules! emit_diag {
(
$lint:expr,
@@ -680,7 +678,7 @@ fn irrefutable_let_patterns(
"removing the guard and adding a `let` inside the match arm"
);
}
- LetSource::LetElse(..) => {
+ LetSource::LetElse => {
emit_diag!(
lint,
"`let...else`",
@@ -820,7 +818,7 @@ fn non_exhaustive_match<'p, 'tcx>(
}
}
if let ty::Ref(_, sub_ty, _) = scrut_ty.kind() {
- if cx.tcx.is_ty_uninhabited_from(cx.module, *sub_ty, cx.param_env) {
+ if !sub_ty.is_inhabited_from(cx.tcx, cx.module, cx.param_env) {
err.note("references are always considered inhabited");
}
}
@@ -1046,11 +1044,19 @@ fn check_borrow_conflicts_in_at_patterns(cx: &MatchVisitor<'_, '_, '_>, pat: &Pa
name,
typeck_results.node_type(pat.hir_id),
);
- sess.struct_span_err(pat.span, "borrow of moved value")
- .span_label(binding_span, format!("value moved into `{}` here", name))
+ let mut err = sess.struct_span_err(pat.span, "borrow of moved value");
+ err.span_label(binding_span, format!("value moved into `{}` here", name))
.span_label(binding_span, occurs_because)
- .span_labels(conflicts_ref, "value borrowed here after move")
- .emit();
+ .span_labels(conflicts_ref, "value borrowed here after move");
+ if pat.span.contains(binding_span) {
+ err.span_suggestion_verbose(
+ binding_span.shrink_to_lo(),
+ "borrow this binding in the pattern to avoid moving the value",
+ "ref ".to_string(),
+ Applicability::MachineApplicable,
+ );
+ }
+ err.emit();
}
return;
}
@@ -1127,7 +1133,7 @@ pub enum LetSource {
GenericLet,
IfLet,
IfLetGuard,
- LetElse(Span),
+ LetElse,
WhileLet,
}
@@ -1156,8 +1162,8 @@ fn let_source_parent(tcx: TyCtxt<'_>, parent: HirId, pat_id: Option<HirId>) -> L
let parent_parent = hir.get_parent_node(parent);
let parent_parent_node = hir.get(parent_parent);
match parent_parent_node {
- hir::Node::Stmt(hir::Stmt { kind: hir::StmtKind::Local(_), span, .. }) => {
- return LetSource::LetElse(*span);
+ hir::Node::Stmt(hir::Stmt { kind: hir::StmtKind::Local(_), .. }) => {
+ return LetSource::LetElse;
}
hir::Node::Arm(hir::Arm { guard: Some(hir::Guard::If(_)), .. }) => {
return LetSource::IfLetGuard;
diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
index ad12e0116..a21f6cd39 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
@@ -232,8 +232,7 @@ impl<'tcx> ConstToPat<'tcx> {
ObligationCause::misc(self.span, self.id),
partial_eq_trait_id,
0,
- ty,
- &[],
+ [ty, ty],
);
// FIXME: should this call a `predicate_must_hold` variant instead?
diff --git a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs
index 595abc8f6..d60e8722c 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs
@@ -42,16 +42,17 @@
//! wildcards, see [`SplitWildcard`]; for integer ranges, see [`SplitIntRange`]; for slices, see
//! [`SplitVarLenSlice`].
-use self::Constructor::*;
-use self::SliceKind::*;
+use std::cell::Cell;
+use std::cmp::{self, max, min, Ordering};
+use std::fmt;
+use std::iter::{once, IntoIterator};
+use std::ops::RangeInclusive;
-use super::compare_const_vals;
-use super::usefulness::{MatchCheckCtxt, PatCtxt};
+use smallvec::{smallvec, SmallVec};
use rustc_data_structures::captures::Captures;
-use rustc_index::vec::Idx;
-
use rustc_hir::{HirId, RangeEnd};
+use rustc_index::vec::Idx;
use rustc_middle::mir::{self, Field};
use rustc_middle::thir::{FieldPat, Pat, PatKind, PatRange};
use rustc_middle::ty::layout::IntegerExt;
@@ -61,12 +62,11 @@ use rustc_session::lint;
use rustc_span::{Span, DUMMY_SP};
use rustc_target::abi::{Integer, Size, VariantIdx};
-use smallvec::{smallvec, SmallVec};
-use std::cell::Cell;
-use std::cmp::{self, max, min, Ordering};
-use std::fmt;
-use std::iter::{once, IntoIterator};
-use std::ops::RangeInclusive;
+use self::Constructor::*;
+use self::SliceKind::*;
+
+use super::compare_const_vals;
+use super::usefulness::{MatchCheckCtxt, PatCtxt};
/// Recursively expand this pattern into its subpatterns. Only useful for or-patterns.
fn expand_or_pat<'p, 'tcx>(pat: &'p Pat<'tcx>) -> Vec<&'p Pat<'tcx>> {
@@ -147,11 +147,7 @@ impl IntRange {
// straight to the result, after doing a bit of checking. (We
// could remove this branch and just fall through, which
// is more general but much slower.)
- if let Ok(Ok(bits)) = scalar.to_bits_or_ptr_internal(target_size) {
- return Some(bits);
- } else {
- return None;
- }
+ return scalar.to_bits_or_ptr_internal(target_size).unwrap().left();
}
mir::ConstantKind::Ty(c) => match c.kind() {
ty::ConstKind::Value(_) => bug!(
diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
index 2526522a2..48a231a6c 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
@@ -216,7 +216,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
let lo = lo_expr.map(|e| self.lower_range_expr(e));
let hi = hi_expr.map(|e| self.lower_range_expr(e));
- let (lp, hp) = (lo.as_ref().map(|x| &x.0), hi.as_ref().map(|x| &x.0));
+ let (lp, hp) = (lo.as_ref().map(|(x, _)| x), hi.as_ref().map(|(x, _)| x));
let mut kind = match self.normalize_range_pattern_ends(ty, lp, hp) {
Some((lc, hc)) => self.lower_pattern_range(ty, lc, hc, end, lo_span),
None => {
@@ -321,7 +321,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
let subpatterns = fields
.iter()
.map(|field| FieldPat {
- field: Field::new(self.tcx.field_index(field.hir_id, self.typeck_results)),
+ field: Field::new(self.typeck_results.field_index(field.hir_id)),
pattern: self.lower_pattern(&field.pat),
})
.collect();
@@ -358,7 +358,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
&mut self,
pat: &'tcx Option<&'tcx hir::Pat<'tcx>>,
) -> Option<Box<Pat<'tcx>>> {
- pat.as_ref().map(|p| self.lower_pattern(p))
+ pat.map(|p| self.lower_pattern(p))
}
fn slice_or_array_pattern(
@@ -565,8 +565,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
id: hir::HirId,
span: Span,
) -> PatKind<'tcx> {
- let anon_const_def_id = self.tcx.hir().local_def_id(anon_const.hir_id);
- let value = mir::ConstantKind::from_inline_const(self.tcx, anon_const_def_id);
+ let value = mir::ConstantKind::from_inline_const(self.tcx, anon_const.def_id);
// Evaluate early like we do in `lower_path`.
let value = value.eval(self.tcx, self.param_env);
@@ -577,6 +576,9 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
self.errors.push(PatternError::ConstParamInPattern(span));
return PatKind::Wild;
}
+ ConstKind::Error(_) => {
+ return PatKind::Wild;
+ }
_ => bug!("Expected ConstKind::Param"),
},
mir::ConstantKind::Val(_, _) => self.const_to_pat(value, id, span, false).kind,
@@ -614,7 +616,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
LitToConstInput { lit: &lit.node, ty: self.typeck_results.expr_ty(expr), neg };
match self.tcx.at(expr.span).lit_to_mir_constant(lit_input) {
Ok(constant) => self.const_to_pat(constant, expr.hir_id, lit.span, false).kind,
- Err(LitToConstError::Reported) => PatKind::Wild,
+ Err(LitToConstError::Reported(_)) => PatKind::Wild,
Err(LitToConstError::TypeError) => bug!("lower_lit: had type error"),
}
}
diff --git a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs
index 8dc9976ea..3e370a053 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs
@@ -324,7 +324,7 @@ pub(crate) struct MatchCheckCtxt<'p, 'tcx> {
impl<'a, 'tcx> MatchCheckCtxt<'a, 'tcx> {
pub(super) fn is_uninhabited(&self, ty: Ty<'tcx>) -> bool {
if self.tcx.features().exhaustive_patterns {
- self.tcx.is_ty_uninhabited_from(self.module, ty, self.param_env)
+ !ty.is_inhabited_from(self.tcx, self.module, self.param_env)
} else {
false
}