mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-25 11:17:13 +00:00
Revert tests::patterns::infer_pattern
And apply requested changes
This commit is contained in:
parent
dd461203a6
commit
135fca9efe
@ -334,7 +334,11 @@ impl InferenceContext<'_> {
|
||||
ExprIsRead::No
|
||||
};
|
||||
let input_ty = self.infer_expr(expr, &Expectation::none(), child_is_read);
|
||||
self.infer_top_pat(pat, &input_ty, None);
|
||||
self.infer_top_pat(
|
||||
pat,
|
||||
&input_ty,
|
||||
Some(DeclContext { origin: DeclOrigin::LetExpr }),
|
||||
);
|
||||
self.result.standard_types.bool_.clone()
|
||||
}
|
||||
Expr::Block { statements, tail, label, id } => {
|
||||
@ -1633,8 +1637,7 @@ impl InferenceContext<'_> {
|
||||
};
|
||||
|
||||
let decl = DeclContext {
|
||||
has_else: else_branch.is_some(),
|
||||
origin: DeclOrigin::LocalDecl,
|
||||
origin: DeclOrigin::LocalDecl { has_else: else_branch.is_some() },
|
||||
};
|
||||
|
||||
this.infer_top_pat(*pat, &ty, Some(decl));
|
||||
|
@ -498,7 +498,7 @@ impl InferenceContext<'_> {
|
||||
|
||||
// If `expected` is an infer ty, we try to equate it to an array if the given pattern
|
||||
// allows it. See issue #16609
|
||||
if self.decl_allows_array_type_infer(decl) && expected.is_ty_var() {
|
||||
if self.pat_is_irrefutable(decl) && expected.is_ty_var() {
|
||||
if let Some(resolved_array_ty) =
|
||||
self.try_resolve_slice_ty_to_array_ty(prefix, suffix, slice)
|
||||
{
|
||||
@ -601,42 +601,38 @@ impl InferenceContext<'_> {
|
||||
Some(array_ty)
|
||||
}
|
||||
|
||||
/// Determines whether we can infer the expected type in the slice pattern to be of type array.
|
||||
/// Used to determine whether we can infer the expected type in the slice pattern to be of type array.
|
||||
/// This is only possible if we're in an irrefutable pattern. If we were to allow this in refutable
|
||||
/// patterns we wouldn't e.g. report ambiguity in the following situation:
|
||||
///
|
||||
/// ```ignore(rust)
|
||||
/// struct Zeroes;
|
||||
/// const ARR: [usize; 2] = [0; 2];
|
||||
/// const ARR2: [usize; 2] = [2; 2];
|
||||
/// struct Zeroes;
|
||||
/// const ARR: [usize; 2] = [0; 2];
|
||||
/// const ARR2: [usize; 2] = [2; 2];
|
||||
///
|
||||
/// impl Into<&'static [usize; 2]> for Zeroes {
|
||||
/// fn into(self) -> &'static [usize; 2] {
|
||||
/// impl Into<&'static [usize; 2]> for Zeroes {
|
||||
/// fn into(self) -> &'static [usize; 2] {
|
||||
/// &ARR
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// impl Into<&'static [usize]> for Zeroes {
|
||||
/// fn into(self) -> &'static [usize] {
|
||||
/// &ARR2
|
||||
/// }
|
||||
/// }
|
||||
/// impl Into<&'static [usize]> for Zeroes {
|
||||
/// fn into(self) -> &'static [usize] {
|
||||
/// &ARR2
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// fn main() {
|
||||
/// let &[a, b]: &[usize] = Zeroes.into() else {
|
||||
/// ..
|
||||
/// };
|
||||
/// }
|
||||
/// fn main() {
|
||||
/// let &[a, b]: &[usize] = Zeroes.into() else {
|
||||
/// ..
|
||||
/// };
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// 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).
|
||||
fn decl_allows_array_type_infer(&self, decl_ctxt: Option<DeclContext>) -> bool {
|
||||
if let Some(decl_ctxt) = decl_ctxt {
|
||||
!decl_ctxt.has_else && matches!(decl_ctxt.origin, DeclOrigin::LocalDecl)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
/// the slice impl candidate would be rejected anyway (if no ambiguity existed).
|
||||
fn pat_is_irrefutable(&self, decl_ctxt: Option<DeclContext>) -> bool {
|
||||
matches!(decl_ctxt, Some(DeclContext { origin: DeclOrigin::LocalDecl { has_else: false } }))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1052,18 +1052,17 @@ pub fn known_const_to_ast(
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub(crate) enum DeclOrigin {
|
||||
// from an `if let` expression
|
||||
LetExpr,
|
||||
// from `let x = ..`
|
||||
LocalDecl,
|
||||
/// from `let x = ..`
|
||||
LocalDecl {
|
||||
has_else: bool,
|
||||
},
|
||||
}
|
||||
|
||||
/// Provides context for checking patterns in declarations. More specifically this
|
||||
/// allows us to infer array types if the pattern is irrefutable and allows us to infer
|
||||
/// the size of the array. See issue #76342.
|
||||
/// the size of the array. See issue rust-lang/rust#76342.
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub(crate) struct DeclContext {
|
||||
// whether we're in a let-else context
|
||||
pub(crate) has_else: bool,
|
||||
pub(crate) origin: DeclOrigin,
|
||||
}
|
||||
|
@ -67,9 +67,9 @@ fn infer_pattern() {
|
||||
143..144 'e': {unknown}
|
||||
157..204 'if let... }': ()
|
||||
160..175 'let [val] = opt': bool
|
||||
164..169 '[val]': [{unknown}; 1]
|
||||
164..169 '[val]': [{unknown}]
|
||||
165..168 'val': {unknown}
|
||||
172..175 'opt': [{unknown}; 1]
|
||||
172..175 'opt': [{unknown}]
|
||||
176..204 '{ ... }': ()
|
||||
190..191 'h': {unknown}
|
||||
194..197 'val': {unknown}
|
||||
|
Loading…
x
Reference in New Issue
Block a user