address review
This commit is contained in:
parent
1c217b6d8a
commit
65f92a52bf
@ -1478,7 +1478,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
let pat_ty = self.node_ty(decl.pat.hir_id);
|
let pat_ty = self.node_ty(decl.pat.hir_id);
|
||||||
self.overwrite_local_ty_if_err(decl.hir_id, decl.pat, pat_ty);
|
self.overwrite_local_ty_if_err(decl.hir_id, decl.pat, pat_ty);
|
||||||
|
|
||||||
if let Some(blk) = decl.origin.try_get_els() {
|
if let Some(blk) = decl.origin.try_get_else() {
|
||||||
let previous_diverges = self.diverges.get();
|
let previous_diverges = self.diverges.get();
|
||||||
let else_ty = self.check_block_with_expected(blk, NoExpectation);
|
let else_ty = self.check_block_with_expected(blk, NoExpectation);
|
||||||
let cause = self.cause(blk.span, ObligationCauseCode::LetElse);
|
let cause = self.cause(blk.span, ObligationCauseCode::LetElse);
|
||||||
|
@ -21,7 +21,7 @@ pub(super) enum DeclOrigin<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> DeclOrigin<'a> {
|
impl<'a> DeclOrigin<'a> {
|
||||||
pub(super) fn try_get_els(&self) -> Option<&'a hir::Block<'a>> {
|
pub(super) fn try_get_else(&self) -> Option<&'a hir::Block<'a>> {
|
||||||
match self {
|
match self {
|
||||||
Self::LocalDecl { els } => *els,
|
Self::LocalDecl { els } => *els,
|
||||||
Self::LetExpr => None,
|
Self::LetExpr => None,
|
||||||
|
@ -163,7 +163,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
/// Conversely, inside this module, `check_pat_top` should never be used.
|
/// Conversely, inside this module, `check_pat_top` should never be used.
|
||||||
#[instrument(level = "debug", skip(self, pat_info))]
|
#[instrument(level = "debug", skip(self, pat_info))]
|
||||||
fn check_pat(&self, pat: &'tcx Pat<'tcx>, expected: Ty<'tcx>, pat_info: PatInfo<'tcx, '_>) {
|
fn check_pat(&self, pat: &'tcx Pat<'tcx>, expected: Ty<'tcx>, pat_info: PatInfo<'tcx, '_>) {
|
||||||
let PatInfo { binding_mode: def_bm, top_info: ti, decl_origin } = pat_info;
|
let PatInfo { binding_mode: def_bm, top_info: ti, .. } = pat_info;
|
||||||
let path_res = match &pat.kind {
|
let path_res = match &pat.kind {
|
||||||
PatKind::Path(qpath) => {
|
PatKind::Path(qpath) => {
|
||||||
Some(self.resolve_ty_and_res_fully_qualified_call(qpath, pat.hir_id, pat.span))
|
Some(self.resolve_ty_and_res_fully_qualified_call(qpath, pat.hir_id, pat.span))
|
||||||
@ -172,76 +172,39 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
};
|
};
|
||||||
let adjust_mode = self.calc_adjust_mode(pat, path_res.map(|(res, ..)| res));
|
let adjust_mode = self.calc_adjust_mode(pat, path_res.map(|(res, ..)| res));
|
||||||
let (expected, def_bm) = self.calc_default_binding_mode(pat, expected, def_bm, adjust_mode);
|
let (expected, def_bm) = self.calc_default_binding_mode(pat, expected, def_bm, adjust_mode);
|
||||||
|
let pat_info =
|
||||||
|
PatInfo { binding_mode: def_bm, top_info: ti, decl_origin: pat_info.decl_origin };
|
||||||
|
|
||||||
let ty = match pat.kind {
|
let ty = match pat.kind {
|
||||||
PatKind::Wild => expected,
|
PatKind::Wild => expected,
|
||||||
PatKind::Lit(lt) => self.check_pat_lit(pat.span, lt, expected, ti),
|
PatKind::Lit(lt) => self.check_pat_lit(pat.span, lt, expected, ti),
|
||||||
PatKind::Range(lhs, rhs, _) => self.check_pat_range(pat.span, lhs, rhs, expected, ti),
|
PatKind::Range(lhs, rhs, _) => self.check_pat_range(pat.span, lhs, rhs, expected, ti),
|
||||||
PatKind::Binding(ba, var_id, _, sub) => self.check_pat_ident(
|
PatKind::Binding(ba, var_id, _, sub) => {
|
||||||
pat,
|
self.check_pat_ident(pat, ba, var_id, sub, expected, pat_info)
|
||||||
ba,
|
}
|
||||||
var_id,
|
PatKind::TupleStruct(ref qpath, subpats, ddpos) => {
|
||||||
sub,
|
self.check_pat_tuple_struct(pat, qpath, subpats, ddpos, expected, pat_info)
|
||||||
expected,
|
}
|
||||||
PatInfo { binding_mode: def_bm, top_info: ti, decl_origin },
|
|
||||||
),
|
|
||||||
PatKind::TupleStruct(ref qpath, subpats, ddpos) => self.check_pat_tuple_struct(
|
|
||||||
pat,
|
|
||||||
qpath,
|
|
||||||
subpats,
|
|
||||||
ddpos,
|
|
||||||
expected,
|
|
||||||
PatInfo { binding_mode: def_bm, top_info: ti, decl_origin },
|
|
||||||
),
|
|
||||||
PatKind::Path(ref qpath) => {
|
PatKind::Path(ref qpath) => {
|
||||||
self.check_pat_path(pat, qpath, path_res.unwrap(), expected, ti)
|
self.check_pat_path(pat, qpath, path_res.unwrap(), expected, ti)
|
||||||
}
|
}
|
||||||
PatKind::Struct(ref qpath, fields, has_rest_pat) => self.check_pat_struct(
|
PatKind::Struct(ref qpath, fields, has_rest_pat) => {
|
||||||
pat,
|
self.check_pat_struct(pat, qpath, fields, has_rest_pat, expected, pat_info)
|
||||||
qpath,
|
}
|
||||||
fields,
|
|
||||||
has_rest_pat,
|
|
||||||
expected,
|
|
||||||
PatInfo { binding_mode: def_bm, top_info: ti, decl_origin },
|
|
||||||
),
|
|
||||||
PatKind::Or(pats) => {
|
PatKind::Or(pats) => {
|
||||||
for pat in pats {
|
for pat in pats {
|
||||||
self.check_pat(
|
self.check_pat(pat, expected, pat_info);
|
||||||
pat,
|
|
||||||
expected,
|
|
||||||
PatInfo { binding_mode: def_bm, top_info: ti, decl_origin },
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
expected
|
expected
|
||||||
}
|
}
|
||||||
PatKind::Tuple(elements, ddpos) => self.check_pat_tuple(
|
PatKind::Tuple(elements, ddpos) => {
|
||||||
pat.span,
|
self.check_pat_tuple(pat.span, elements, ddpos, expected, pat_info)
|
||||||
elements,
|
}
|
||||||
ddpos,
|
PatKind::Box(inner) => self.check_pat_box(pat.span, inner, expected, pat_info),
|
||||||
expected,
|
PatKind::Ref(inner, mutbl) => self.check_pat_ref(pat, inner, mutbl, expected, pat_info),
|
||||||
PatInfo { binding_mode: def_bm, top_info: ti, decl_origin },
|
PatKind::Slice(before, slice, after) => {
|
||||||
),
|
self.check_pat_slice(pat.span, before, slice, after, expected, pat_info)
|
||||||
PatKind::Box(inner) => self.check_pat_box(
|
}
|
||||||
pat.span,
|
|
||||||
inner,
|
|
||||||
expected,
|
|
||||||
PatInfo { binding_mode: def_bm, top_info: ti, decl_origin },
|
|
||||||
),
|
|
||||||
PatKind::Ref(inner, mutbl) => self.check_pat_ref(
|
|
||||||
pat,
|
|
||||||
inner,
|
|
||||||
mutbl,
|
|
||||||
expected,
|
|
||||||
PatInfo { binding_mode: def_bm, top_info: ti, decl_origin },
|
|
||||||
),
|
|
||||||
PatKind::Slice(before, slice, after) => self.check_pat_slice(
|
|
||||||
pat.span,
|
|
||||||
before,
|
|
||||||
slice,
|
|
||||||
after,
|
|
||||||
expected,
|
|
||||||
PatInfo { binding_mode: def_bm, top_info: ti, decl_origin },
|
|
||||||
),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
self.write_ty(pat.hir_id, ty);
|
self.write_ty(pat.hir_id, ty);
|
||||||
@ -624,7 +587,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
expected: Ty<'tcx>,
|
expected: Ty<'tcx>,
|
||||||
pat_info: PatInfo<'tcx, '_>,
|
pat_info: PatInfo<'tcx, '_>,
|
||||||
) -> Ty<'tcx> {
|
) -> Ty<'tcx> {
|
||||||
let PatInfo { binding_mode: def_bm, top_info: ti, decl_origin } = pat_info;
|
let PatInfo { binding_mode: def_bm, top_info: ti, .. } = pat_info;
|
||||||
|
|
||||||
// Determine the binding mode...
|
// Determine the binding mode...
|
||||||
let bm = match ba {
|
let bm = match ba {
|
||||||
@ -663,11 +626,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(p) = sub {
|
if let Some(p) = sub {
|
||||||
self.check_pat(
|
self.check_pat(p, expected, pat_info);
|
||||||
p,
|
|
||||||
expected,
|
|
||||||
PatInfo { binding_mode: def_bm, top_info: ti, decl_origin },
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
local_ty
|
local_ty
|
||||||
@ -892,37 +851,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
expected: Ty<'tcx>,
|
expected: Ty<'tcx>,
|
||||||
pat_info: PatInfo<'tcx, '_>,
|
pat_info: PatInfo<'tcx, '_>,
|
||||||
) -> Ty<'tcx> {
|
) -> Ty<'tcx> {
|
||||||
let PatInfo { binding_mode: def_bm, top_info: ti, decl_origin } = pat_info;
|
|
||||||
|
|
||||||
// Resolve the path and check the definition for errors.
|
// Resolve the path and check the definition for errors.
|
||||||
let (variant, pat_ty) = match self.check_struct_path(qpath, pat.hir_id) {
|
let (variant, pat_ty) = match self.check_struct_path(qpath, pat.hir_id) {
|
||||||
Ok(data) => data,
|
Ok(data) => data,
|
||||||
Err(guar) => {
|
Err(guar) => {
|
||||||
let err = Ty::new_error(self.tcx, guar);
|
let err = Ty::new_error(self.tcx, guar);
|
||||||
for field in fields {
|
for field in fields {
|
||||||
let ti = ti;
|
self.check_pat(field.pat, err, pat_info);
|
||||||
self.check_pat(
|
|
||||||
field.pat,
|
|
||||||
err,
|
|
||||||
PatInfo { binding_mode: def_bm, top_info: ti, decl_origin },
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Type-check the path.
|
// Type-check the path.
|
||||||
self.demand_eqtype_pat(pat.span, expected, pat_ty, ti);
|
self.demand_eqtype_pat(pat.span, expected, pat_ty, pat_info.top_info);
|
||||||
|
|
||||||
// Type-check subpatterns.
|
// Type-check subpatterns.
|
||||||
if self.check_struct_pat_fields(
|
if self.check_struct_pat_fields(pat_ty, &pat, variant, fields, has_rest_pat, pat_info) {
|
||||||
pat_ty,
|
|
||||||
&pat,
|
|
||||||
variant,
|
|
||||||
fields,
|
|
||||||
has_rest_pat,
|
|
||||||
PatInfo { binding_mode: def_bm, top_info: ti, decl_origin },
|
|
||||||
) {
|
|
||||||
pat_ty
|
pat_ty
|
||||||
} else {
|
} else {
|
||||||
Ty::new_misc_error(self.tcx)
|
Ty::new_misc_error(self.tcx)
|
||||||
@ -2144,11 +2089,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
/// If we're in an irrefutable pattern we prefer the array impl candidate given that
|
/// If we're in an irrefutable pattern we prefer the array impl candidate given that
|
||||||
/// the slice impl candidate would be be rejected anyway (if no ambiguity existed).
|
/// the slice impl candidate would be be rejected anyway (if no ambiguity existed).
|
||||||
fn pat_is_irrefutable(&self, decl_origin: Option<DeclOrigin<'_>>) -> bool {
|
fn pat_is_irrefutable(&self, decl_origin: Option<DeclOrigin<'_>>) -> bool {
|
||||||
if let Some(decl_origin) = decl_origin {
|
match decl_origin {
|
||||||
decl_origin.try_get_els().is_none()
|
Some(DeclOrigin::LocalDecl { els: None }) => true,
|
||||||
&& matches!(decl_origin, DeclOrigin::LocalDecl { .. })
|
Some(DeclOrigin::LocalDecl { els: Some(_) } | DeclOrigin::LetExpr) | None => false,
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2183,6 +2126,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let expected = self.structurally_resolve_type(span, expected);
|
let expected = self.structurally_resolve_type(span, expected);
|
||||||
|
debug!(?expected);
|
||||||
|
|
||||||
let (element_ty, opt_slice_ty, inferred) = match *expected.kind() {
|
let (element_ty, opt_slice_ty, inferred) = match *expected.kind() {
|
||||||
// An array, so we might have something like `let [a, b, c] = [0, 1, 2];`.
|
// An array, so we might have something like `let [a, b, c] = [0, 1, 2];`.
|
||||||
ty::Array(element_ty, len) => {
|
ty::Array(element_ty, len) => {
|
||||||
|
@ -30,9 +30,8 @@ fn main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn another_fn_to_avoid_suppression() {
|
fn another_fn_to_avoid_suppression() {
|
||||||
match Default
|
match Default::default() {
|
||||||
//~^ ERROR expected value, found trait
|
|
||||||
{
|
|
||||||
[] => {}
|
[] => {}
|
||||||
|
//~^ ERROR type annotations needed
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -4,12 +4,6 @@ error[E0425]: cannot find value `does_not_exist` in this scope
|
|||||||
LL | match does_not_exist {
|
LL | match does_not_exist {
|
||||||
| ^^^^^^^^^^^^^^ not found in this scope
|
| ^^^^^^^^^^^^^^ not found in this scope
|
||||||
|
|
||||||
error[E0423]: expected value, found trait `Default`
|
|
||||||
--> $DIR/slice-pat-type-mismatches.rs:33:11
|
|
||||||
|
|
|
||||||
LL | match Default
|
|
||||||
| ^^^^^^^ not a value
|
|
||||||
|
|
||||||
error[E0529]: expected an array or slice, found `String`
|
error[E0529]: expected an array or slice, found `String`
|
||||||
--> $DIR/slice-pat-type-mismatches.rs:3:9
|
--> $DIR/slice-pat-type-mismatches.rs:3:9
|
||||||
|
|
|
|
||||||
@ -28,7 +22,13 @@ error[E0528]: pattern requires at least 4 elements but array has 3
|
|||||||
LL | [0, 1, 2, 3, x @ ..] => {}
|
LL | [0, 1, 2, 3, x @ ..] => {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^ pattern cannot match array of 3 elements
|
| ^^^^^^^^^^^^^^^^^^^^ pattern cannot match array of 3 elements
|
||||||
|
|
||||||
|
error[E0282]: type annotations needed
|
||||||
|
--> $DIR/slice-pat-type-mismatches.rs:34:9
|
||||||
|
|
|
||||||
|
LL | [] => {}
|
||||||
|
| ^^ cannot infer type
|
||||||
|
|
||||||
error: aborting due to 5 previous errors
|
error: aborting due to 5 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0423, E0425, E0527, E0528, E0529.
|
Some errors have detailed explanations: E0282, E0425, E0527, E0528, E0529.
|
||||||
For more information about an error, try `rustc --explain E0423`.
|
For more information about an error, try `rustc --explain E0282`.
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
// check-pass
|
// check-pass
|
||||||
|
|
||||||
|
// Test that we infer the expected type of a pattern to an array of the given length.
|
||||||
|
|
||||||
#![allow(unused_variables)]
|
#![allow(unused_variables)]
|
||||||
struct Zeroes;
|
struct Zeroes;
|
||||||
impl Into<[usize; 2]> for Zeroes {
|
impl Into<[usize; 2]> for Zeroes {
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
// Test that we do not infer the expected types of patterns to an array
|
||||||
|
// if we're in a refutable pattern.
|
||||||
#![allow(unused_variables)]
|
#![allow(unused_variables)]
|
||||||
|
|
||||||
struct Zeroes;
|
struct Zeroes;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
error[E0282]: type annotations needed
|
error[E0282]: type annotations needed
|
||||||
--> $DIR/slice-pattern-refutable.rs:12:9
|
--> $DIR/slice-pattern-refutable.rs:14:9
|
||||||
|
|
|
|
||||||
LL | let [a, b, c] = Zeroes.into() else {
|
LL | let [a, b, c] = Zeroes.into() else {
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
@ -10,7 +10,7 @@ LL | let [a, b, c]: /* Type */ = Zeroes.into() else {
|
|||||||
| ++++++++++++
|
| ++++++++++++
|
||||||
|
|
||||||
error[E0282]: type annotations needed
|
error[E0282]: type annotations needed
|
||||||
--> $DIR/slice-pattern-refutable.rs:19:31
|
--> $DIR/slice-pattern-refutable.rs:21:31
|
||||||
|
|
|
|
||||||
LL | if let [a, b, c] = Zeroes.into() {
|
LL | if let [a, b, c] = Zeroes.into() {
|
||||||
| --------- ^^^^
|
| --------- ^^^^
|
||||||
@ -23,7 +23,7 @@ LL | if let [a, b, c] = <Zeroes as Into<T>>::into(Zeroes) {
|
|||||||
| ++++++++++++++++++++++++++ ~
|
| ++++++++++++++++++++++++++ ~
|
||||||
|
|
||||||
error[E0282]: type annotations needed
|
error[E0282]: type annotations needed
|
||||||
--> $DIR/slice-pattern-refutable.rs:26:31
|
--> $DIR/slice-pattern-refutable.rs:28:31
|
||||||
|
|
|
|
||||||
LL | if let [a, b, c] = Zeroes.into() {
|
LL | if let [a, b, c] = Zeroes.into() {
|
||||||
| --------- ^^^^
|
| --------- ^^^^
|
||||||
|
Loading…
x
Reference in New Issue
Block a user