mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-28 04:45:05 +00:00
insert type vars in function arguments
This commit is contained in:
parent
615aaa4751
commit
c21d09f3cc
3 changed files with 45 additions and 4 deletions
|
@ -1025,7 +1025,8 @@ impl<'a> InferenceContext<'a> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
// Try to evaluate unevaluated constant, and insert variable if is not possible.
|
||||||
|
let len = self.table.insert_const_vars_shallow(len);
|
||||||
TyKind::Array(elem_ty, len).intern(Interner)
|
TyKind::Array(elem_ty, len).intern(Interner)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1681,9 +1682,10 @@ impl<'a> InferenceContext<'a> {
|
||||||
} else {
|
} else {
|
||||||
param_ty
|
param_ty
|
||||||
};
|
};
|
||||||
if !coercion_target.is_unknown()
|
// The function signature may contain some unknown types, so we need to insert
|
||||||
&& self.coerce(Some(arg), &ty, &coercion_target).is_err()
|
// type vars here to avoid type mismatch false positive.
|
||||||
{
|
let coercion_target = self.insert_type_vars(coercion_target);
|
||||||
|
if self.coerce(Some(arg), &ty, &coercion_target).is_err() {
|
||||||
self.result.type_mismatches.insert(
|
self.result.type_mismatches.insert(
|
||||||
arg.into(),
|
arg.into(),
|
||||||
TypeMismatch { expected: coercion_target, actual: ty.clone() },
|
TypeMismatch { expected: coercion_target, actual: ty.clone() },
|
||||||
|
|
|
@ -1888,6 +1888,26 @@ fn main() {
|
||||||
_ = Outer {
|
_ = Outer {
|
||||||
inner: Inner::<1>(),
|
inner: Inner::<1>(),
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
check_no_mismatches(
|
||||||
|
r#"
|
||||||
|
pub const N: usize = 2 + 2;
|
||||||
|
|
||||||
|
fn f(t: [u8; N]) {}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let a = [1, 2, 3, 4];
|
||||||
|
f(a);
|
||||||
|
let b = [1; 4];
|
||||||
|
let c: [u8; N] = b;
|
||||||
|
let d = [1; N];
|
||||||
|
let e: [u8; N] = d;
|
||||||
|
let f = [1; N];
|
||||||
|
let g = match f {
|
||||||
|
[a, b, c, d] => a + b + c + d,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
"#,
|
"#,
|
||||||
);
|
);
|
||||||
|
|
|
@ -644,6 +644,25 @@ fn h() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn unknown_type_in_function_signature() {
|
||||||
|
check_diagnostics(
|
||||||
|
r#"
|
||||||
|
struct X<T>(T);
|
||||||
|
|
||||||
|
fn foo(x: X<Unknown>) {}
|
||||||
|
fn test1() {
|
||||||
|
// Unknown might be `i32`, so we should not emit type mismatch here.
|
||||||
|
foo(X(42));
|
||||||
|
}
|
||||||
|
fn test2() {
|
||||||
|
foo(42);
|
||||||
|
//^^ error: expected X<{unknown}>, found i32
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn evaluate_const_generics_in_types() {
|
fn evaluate_const_generics_in_types() {
|
||||||
check_diagnostics(
|
check_diagnostics(
|
||||||
|
|
Loading…
Reference in a new issue