mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-01 14:21:44 +00:00
Support all coercion places
This commit is contained in:
parent
5807e261c2
commit
29e56b8ee4
3 changed files with 216 additions and 96 deletions
|
@ -14,7 +14,7 @@
|
||||||
//! the `ena` crate, which is extracted from rustc.
|
//! the `ena` crate, which is extracted from rustc.
|
||||||
|
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::iter::repeat;
|
use std::iter::{repeat, repeat_with};
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ops::Index;
|
use std::ops::Index;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
@ -876,10 +876,23 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Infer type of expression with possibly implicit coerce to the expected type.
|
/// Infer type of expression with possibly implicit coerce to the expected type.
|
||||||
|
/// Return the type after possible coercion.
|
||||||
fn infer_expr_coerce(&mut self, expr: ExprId, expected: &Expectation) -> Ty {
|
fn infer_expr_coerce(&mut self, expr: ExprId, expected: &Expectation) -> Ty {
|
||||||
let ty = self.infer_expr_inner(expr, &expected);
|
let ty = self.infer_expr_inner(expr, &expected);
|
||||||
self.coerce(&ty, &expected.ty);
|
let ty = if !self.coerce(&ty, &expected.ty) {
|
||||||
|
self.result
|
||||||
|
.type_mismatches
|
||||||
|
.insert(expr, TypeMismatch { expected: expected.ty.clone(), actual: ty.clone() });
|
||||||
|
// Return actual type when type mismatch.
|
||||||
|
// This is needed for diagnostic when return type mismatch.
|
||||||
ty
|
ty
|
||||||
|
} else if expected.ty == Ty::Unknown {
|
||||||
|
ty
|
||||||
|
} else {
|
||||||
|
expected.ty.clone()
|
||||||
|
};
|
||||||
|
|
||||||
|
self.resolve_ty_as_possible(&mut vec![], ty)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Merge two types from different branches, with possible implicit coerce.
|
/// Merge two types from different branches, with possible implicit coerce.
|
||||||
|
@ -1328,6 +1341,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
|
||||||
self.write_variant_resolution(tgt_expr.into(), variant);
|
self.write_variant_resolution(tgt_expr.into(), variant);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.unify(&ty, &expected.ty);
|
||||||
|
|
||||||
let substs = ty.substs().unwrap_or_else(Substs::empty);
|
let substs = ty.substs().unwrap_or_else(Substs::empty);
|
||||||
for (field_idx, field) in fields.iter().enumerate() {
|
for (field_idx, field) in fields.iter().enumerate() {
|
||||||
let field_ty = def_id
|
let field_ty = def_id
|
||||||
|
@ -1343,7 +1358,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
|
||||||
})
|
})
|
||||||
.map_or(Ty::Unknown, |field| field.ty(self.db))
|
.map_or(Ty::Unknown, |field| field.ty(self.db))
|
||||||
.subst(&substs);
|
.subst(&substs);
|
||||||
self.infer_expr(field.expr, &Expectation::has_type(field_ty));
|
self.infer_expr_coerce(field.expr, &Expectation::has_type(field_ty));
|
||||||
}
|
}
|
||||||
if let Some(expr) = spread {
|
if let Some(expr) = spread {
|
||||||
self.infer_expr(*expr, &Expectation::has_type(ty.clone()));
|
self.infer_expr(*expr, &Expectation::has_type(ty.clone()));
|
||||||
|
@ -1513,35 +1528,41 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
|
||||||
Ty::Unknown
|
Ty::Unknown
|
||||||
}
|
}
|
||||||
Expr::Tuple { exprs } => {
|
Expr::Tuple { exprs } => {
|
||||||
let mut ty_vec = Vec::with_capacity(exprs.len());
|
let mut tys = match &expected.ty {
|
||||||
for arg in exprs.iter() {
|
ty_app!(TypeCtor::Tuple { .. }, st) => st
|
||||||
ty_vec.push(self.infer_expr(*arg, &Expectation::none()));
|
.iter()
|
||||||
|
.cloned()
|
||||||
|
.chain(repeat_with(|| self.new_type_var()))
|
||||||
|
.take(exprs.len())
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
_ => (0..exprs.len()).map(|_| self.new_type_var()).collect(),
|
||||||
|
};
|
||||||
|
|
||||||
|
for (expr, ty) in exprs.iter().zip(tys.iter_mut()) {
|
||||||
|
self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone()));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ty::apply(
|
Ty::apply(TypeCtor::Tuple { cardinality: tys.len() as u16 }, Substs(tys.into()))
|
||||||
TypeCtor::Tuple { cardinality: ty_vec.len() as u16 },
|
|
||||||
Substs(ty_vec.into()),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
Expr::Array(array) => {
|
Expr::Array(array) => {
|
||||||
let elem_ty = match &expected.ty {
|
let elem_ty = match &expected.ty {
|
||||||
Ty::Apply(a_ty) => match a_ty.ctor {
|
ty_app!(TypeCtor::Array, st) | ty_app!(TypeCtor::Slice, st) => {
|
||||||
TypeCtor::Slice | TypeCtor::Array => {
|
st.as_single().clone()
|
||||||
Ty::clone(&a_ty.parameters.as_single())
|
|
||||||
}
|
}
|
||||||
_ => self.new_type_var(),
|
_ => self.new_type_var(),
|
||||||
},
|
|
||||||
_ => self.new_type_var(),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
match array {
|
match array {
|
||||||
Array::ElementList(items) => {
|
Array::ElementList(items) => {
|
||||||
for expr in items.iter() {
|
for expr in items.iter() {
|
||||||
self.infer_expr(*expr, &Expectation::has_type(elem_ty.clone()));
|
self.infer_expr_coerce(*expr, &Expectation::has_type(elem_ty.clone()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Array::Repeat { initializer, repeat } => {
|
Array::Repeat { initializer, repeat } => {
|
||||||
self.infer_expr(*initializer, &Expectation::has_type(elem_ty.clone()));
|
self.infer_expr_coerce(
|
||||||
|
*initializer,
|
||||||
|
&Expectation::has_type(elem_ty.clone()),
|
||||||
|
);
|
||||||
self.infer_expr(
|
self.infer_expr(
|
||||||
*repeat,
|
*repeat,
|
||||||
&Expectation::has_type(Ty::simple(TypeCtor::Int(
|
&Expectation::has_type(Ty::simple(TypeCtor::Int(
|
||||||
|
@ -1588,12 +1609,19 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
|
||||||
Statement::Let { pat, type_ref, initializer } => {
|
Statement::Let { pat, type_ref, initializer } => {
|
||||||
let decl_ty =
|
let decl_ty =
|
||||||
type_ref.as_ref().map(|tr| self.make_ty(tr)).unwrap_or(Ty::Unknown);
|
type_ref.as_ref().map(|tr| self.make_ty(tr)).unwrap_or(Ty::Unknown);
|
||||||
let decl_ty = self.insert_type_vars(decl_ty);
|
|
||||||
|
// Always use the declared type when specified
|
||||||
|
let mut ty = decl_ty.clone();
|
||||||
|
|
||||||
if let Some(expr) = initializer {
|
if let Some(expr) = initializer {
|
||||||
|
let actual_ty =
|
||||||
self.infer_expr_coerce(*expr, &Expectation::has_type(decl_ty.clone()));
|
self.infer_expr_coerce(*expr, &Expectation::has_type(decl_ty.clone()));
|
||||||
|
if decl_ty == Ty::Unknown {
|
||||||
|
ty = actual_ty;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let ty = self.resolve_ty_as_possible(&mut vec![], decl_ty);
|
let ty = self.resolve_ty_as_possible(&mut vec![], ty);
|
||||||
self.infer_pat(*pat, &ty, BindingMode::default());
|
self.infer_pat(*pat, &ty, BindingMode::default());
|
||||||
}
|
}
|
||||||
Statement::Expr(expr) => {
|
Statement::Expr(expr) => {
|
||||||
|
@ -1601,9 +1629,13 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let ty =
|
|
||||||
if let Some(expr) = tail { self.infer_expr_inner(expr, expected) } else { Ty::unit() };
|
if let Some(expr) = tail {
|
||||||
ty
|
self.infer_expr_coerce(expr, expected)
|
||||||
|
} else {
|
||||||
|
self.coerce(&Ty::unit(), &expected.ty);
|
||||||
|
Ty::unit()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_call_arguments(&mut self, args: &[ExprId], param_tys: &[Ty]) {
|
fn check_call_arguments(&mut self, args: &[ExprId], param_tys: &[Ty]) {
|
||||||
|
|
|
@ -239,17 +239,23 @@ fn test() {
|
||||||
let a = 1isize;
|
let a = 1isize;
|
||||||
let b: usize = 1;
|
let b: usize = 1;
|
||||||
let c = b;
|
let c = b;
|
||||||
|
let d: u32;
|
||||||
|
let e;
|
||||||
|
let f: i32 = e;
|
||||||
}
|
}
|
||||||
"#),
|
"#),
|
||||||
@r###"
|
@r###"
|
||||||
|
[11; 118) '{ ...= e; }': ()
|
||||||
[11; 71) '{ ...= b; }': ()
|
|
||||||
[21; 22) 'a': isize
|
[21; 22) 'a': isize
|
||||||
[25; 31) '1isize': isize
|
[25; 31) '1isize': isize
|
||||||
[41; 42) 'b': usize
|
[41; 42) 'b': usize
|
||||||
[52; 53) '1': usize
|
[52; 53) '1': usize
|
||||||
[63; 64) 'c': usize
|
[63; 64) 'c': usize
|
||||||
[67; 68) 'b': usize
|
[67; 68) 'b': usize
|
||||||
|
[78; 79) 'd': u32
|
||||||
|
[94; 95) 'e': i32
|
||||||
|
[105; 106) 'f': i32
|
||||||
|
[114; 115) 'e': i32
|
||||||
"###
|
"###
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -331,7 +337,7 @@ fn test() {
|
||||||
"#),
|
"#),
|
||||||
@r###"
|
@r###"
|
||||||
[45; 49) 'self': &[T]
|
[45; 49) 'self': &[T]
|
||||||
[56; 79) '{ ... }': !
|
[56; 79) '{ ... }': T
|
||||||
[66; 73) 'loop {}': !
|
[66; 73) 'loop {}': !
|
||||||
[71; 73) '{}': ()
|
[71; 73) '{}': ()
|
||||||
[133; 160) '{ ...o"); }': ()
|
[133; 160) '{ ...o"); }': ()
|
||||||
|
@ -817,7 +823,7 @@ struct A<T>(T);
|
||||||
|
|
||||||
impl<T> A<T> {
|
impl<T> A<T> {
|
||||||
fn foo(&self) -> &T {
|
fn foo(&self) -> &T {
|
||||||
self.0
|
&self.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -837,27 +843,28 @@ fn test() {
|
||||||
@r###"
|
@r###"
|
||||||
[68; 72) 'self': &Self
|
[68; 72) 'self': &Self
|
||||||
[139; 143) 'self': &A<T>
|
[139; 143) 'self': &A<T>
|
||||||
[151; 173) '{ ... }': T
|
[151; 174) '{ ... }': &T
|
||||||
[161; 165) 'self': &A<T>
|
[161; 168) '&self.0': &T
|
||||||
[161; 167) 'self.0': T
|
[162; 166) 'self': &A<T>
|
||||||
[254; 258) 'self': &B<T>
|
[162; 168) 'self.0': T
|
||||||
[277; 300) '{ ... }': &T
|
[255; 259) 'self': &B<T>
|
||||||
[287; 294) '&self.0': &T
|
[278; 301) '{ ... }': &T
|
||||||
[288; 292) 'self': &B<T>
|
[288; 295) '&self.0': &T
|
||||||
[288; 294) 'self.0': T
|
[289; 293) 'self': &B<T>
|
||||||
[314; 352) '{ ...))); }': ()
|
[289; 295) 'self.0': T
|
||||||
[324; 325) 't': &i32
|
[315; 353) '{ ...))); }': ()
|
||||||
[328; 334) 'A::foo': fn foo<i32>(&A<T>) -> &T
|
[325; 326) 't': &i32
|
||||||
[328; 349) 'A::foo...42))))': &i32
|
[329; 335) 'A::foo': fn foo<i32>(&A<T>) -> &T
|
||||||
[335; 348) '&&B(B(A(42)))': &&B<B<A<i32>>>
|
[329; 350) 'A::foo...42))))': &i32
|
||||||
[336; 348) '&B(B(A(42)))': &B<B<A<i32>>>
|
[336; 349) '&&B(B(A(42)))': &&B<B<A<i32>>>
|
||||||
[337; 338) 'B': B<B<A<i32>>>(T) -> B<T>
|
[337; 349) '&B(B(A(42)))': &B<B<A<i32>>>
|
||||||
[337; 348) 'B(B(A(42)))': B<B<A<i32>>>
|
[338; 339) 'B': B<B<A<i32>>>(T) -> B<T>
|
||||||
[339; 340) 'B': B<A<i32>>(T) -> B<T>
|
[338; 349) 'B(B(A(42)))': B<B<A<i32>>>
|
||||||
[339; 347) 'B(A(42))': B<A<i32>>
|
[340; 341) 'B': B<A<i32>>(T) -> B<T>
|
||||||
[341; 342) 'A': A<i32>(T) -> A<T>
|
[340; 348) 'B(A(42))': B<A<i32>>
|
||||||
[341; 346) 'A(42)': A<i32>
|
[342; 343) 'A': A<i32>(T) -> A<T>
|
||||||
[343; 345) '42': i32
|
[342; 347) 'A(42)': A<i32>
|
||||||
|
[344; 346) '42': i32
|
||||||
"###
|
"###
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1109,13 +1116,12 @@ fn test(x: &str, y: isize) {
|
||||||
|
|
||||||
let b = [a, ["b"]];
|
let b = [a, ["b"]];
|
||||||
let x: [u8; 0] = [];
|
let x: [u8; 0] = [];
|
||||||
let z: &[u8] = &[1, 2, 3];
|
|
||||||
}
|
}
|
||||||
"#),
|
"#),
|
||||||
@r###"
|
@r###"
|
||||||
[9; 10) 'x': &str
|
[9; 10) 'x': &str
|
||||||
[18; 19) 'y': isize
|
[18; 19) 'y': isize
|
||||||
[28; 324) '{ ... 3]; }': ()
|
[28; 293) '{ ... []; }': ()
|
||||||
[38; 39) 'a': [&str;_]
|
[38; 39) 'a': [&str;_]
|
||||||
[42; 45) '[x]': [&str;_]
|
[42; 45) '[x]': [&str;_]
|
||||||
[43; 44) 'x': &str
|
[43; 44) 'x': &str
|
||||||
|
@ -1165,12 +1171,6 @@ fn test(x: &str, y: isize) {
|
||||||
[260; 263) '"b"': &str
|
[260; 263) '"b"': &str
|
||||||
[275; 276) 'x': [u8;_]
|
[275; 276) 'x': [u8;_]
|
||||||
[288; 290) '[]': [u8;_]
|
[288; 290) '[]': [u8;_]
|
||||||
[300; 301) 'z': &[u8]
|
|
||||||
[311; 321) '&[1, 2, 3]': &[u8;_]
|
|
||||||
[312; 321) '[1, 2, 3]': [u8;_]
|
|
||||||
[313; 314) '1': u8
|
|
||||||
[316; 317) '2': u8
|
|
||||||
[319; 320) '3': u8
|
|
||||||
"###
|
"###
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1892,8 +1892,7 @@ fn test() {
|
||||||
}
|
}
|
||||||
"#),
|
"#),
|
||||||
@r###"
|
@r###"
|
||||||
|
[80; 104) '{ ... }': Gen<T>
|
||||||
[80; 104) '{ ... }': !
|
|
||||||
[90; 98) 'loop { }': !
|
[90; 98) 'loop { }': !
|
||||||
[95; 98) '{ }': ()
|
[95; 98) '{ }': ()
|
||||||
[118; 146) '{ ...e(); }': ()
|
[118; 146) '{ ...e(); }': ()
|
||||||
|
@ -1923,8 +1922,7 @@ fn test() {
|
||||||
}
|
}
|
||||||
"#),
|
"#),
|
||||||
@r###"
|
@r###"
|
||||||
|
[76; 100) '{ ... }': Gen<T>
|
||||||
[76; 100) '{ ... }': !
|
|
||||||
[86; 94) 'loop { }': !
|
[86; 94) 'loop { }': !
|
||||||
[91; 94) '{ }': ()
|
[91; 94) '{ }': ()
|
||||||
[114; 149) '{ ...e(); }': ()
|
[114; 149) '{ ...e(); }': ()
|
||||||
|
@ -1955,8 +1953,7 @@ fn test() {
|
||||||
}
|
}
|
||||||
"#),
|
"#),
|
||||||
@r###"
|
@r###"
|
||||||
|
[102; 126) '{ ... }': Gen<u32, T>
|
||||||
[102; 126) '{ ... }': !
|
|
||||||
[112; 120) 'loop { }': !
|
[112; 120) 'loop { }': !
|
||||||
[117; 120) '{ }': ()
|
[117; 120) '{ }': ()
|
||||||
[140; 180) '{ ...e(); }': ()
|
[140; 180) '{ ...e(); }': ()
|
||||||
|
@ -2100,7 +2097,7 @@ fn test() {
|
||||||
@r###"
|
@r###"
|
||||||
[11; 48) '{ ...&y]; }': ()
|
[11; 48) '{ ...&y]; }': ()
|
||||||
[21; 22) 'y': &{unknown}
|
[21; 22) 'y': &{unknown}
|
||||||
[25; 32) 'unknown': &&{unknown}
|
[25; 32) 'unknown': &{unknown}
|
||||||
[38; 45) '[y, &y]': [&&{unknown};_]
|
[38; 45) '[y, &y]': [&&{unknown};_]
|
||||||
[39; 40) 'y': &{unknown}
|
[39; 40) 'y': &{unknown}
|
||||||
[42; 44) '&y': &&{unknown}
|
[42; 44) '&y': &&{unknown}
|
||||||
|
@ -2124,11 +2121,11 @@ fn test() {
|
||||||
@r###"
|
@r###"
|
||||||
[11; 80) '{ ...x)]; }': ()
|
[11; 80) '{ ...x)]; }': ()
|
||||||
[21; 22) 'x': &&{unknown}
|
[21; 22) 'x': &&{unknown}
|
||||||
[25; 32) 'unknown': &&&{unknown}
|
[25; 32) 'unknown': &&{unknown}
|
||||||
[42; 43) 'y': &&{unknown}
|
[42; 43) 'y': &&{unknown}
|
||||||
[46; 53) 'unknown': &&&{unknown}
|
[46; 53) 'unknown': &&{unknown}
|
||||||
[59; 77) '[(x, y..., &x)]': [(&&{unknown}, &&{unknown});_]
|
[59; 77) '[(x, y..., &x)]': [(&&&{unknown}, &&&{unknown});_]
|
||||||
[60; 66) '(x, y)': (&&{unknown}, &&{unknown})
|
[60; 66) '(x, y)': (&&&{unknown}, &&&{unknown})
|
||||||
[61; 62) 'x': &&{unknown}
|
[61; 62) 'x': &&{unknown}
|
||||||
[64; 65) 'y': &&{unknown}
|
[64; 65) 'y': &&{unknown}
|
||||||
[68; 76) '(&y, &x)': (&&&{unknown}, &&&{unknown})
|
[68; 76) '(&y, &x)': (&&&{unknown}, &&&{unknown})
|
||||||
|
@ -2149,7 +2146,7 @@ fn id<T>(x: T) -> T {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clone<T>(x: &T) -> T {
|
fn clone<T>(x: &T) -> T {
|
||||||
x
|
*x
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test() {
|
fn test() {
|
||||||
|
@ -2160,26 +2157,26 @@ fn test() {
|
||||||
}
|
}
|
||||||
"#),
|
"#),
|
||||||
@r###"
|
@r###"
|
||||||
|
|
||||||
[10; 11) 'x': T
|
[10; 11) 'x': T
|
||||||
[21; 30) '{ x }': T
|
[21; 30) '{ x }': T
|
||||||
[27; 28) 'x': T
|
[27; 28) 'x': T
|
||||||
[44; 45) 'x': &T
|
[44; 45) 'x': &T
|
||||||
[56; 65) '{ x }': &T
|
[56; 66) '{ *x }': T
|
||||||
[62; 63) 'x': &T
|
[62; 64) '*x': T
|
||||||
[77; 157) '{ ...(1); }': ()
|
[63; 64) 'x': &T
|
||||||
[87; 88) 'y': u32
|
[78; 158) '{ ...(1); }': ()
|
||||||
[91; 96) '10u32': u32
|
[88; 89) 'y': u32
|
||||||
[102; 104) 'id': fn id<u32>(T) -> T
|
[92; 97) '10u32': u32
|
||||||
[102; 107) 'id(y)': u32
|
[103; 105) 'id': fn id<u32>(T) -> T
|
||||||
[105; 106) 'y': u32
|
[103; 108) 'id(y)': u32
|
||||||
[117; 118) 'x': bool
|
[106; 107) 'y': u32
|
||||||
[127; 132) 'clone': fn clone<bool>(&T) -> T
|
[118; 119) 'x': bool
|
||||||
[127; 135) 'clone(z)': bool
|
[128; 133) 'clone': fn clone<bool>(&T) -> T
|
||||||
[133; 134) 'z': &bool
|
[128; 136) 'clone(z)': bool
|
||||||
[141; 151) 'id::<i128>': fn id<i128>(T) -> T
|
[134; 135) 'z': &bool
|
||||||
[141; 154) 'id::<i128>(1)': i128
|
[142; 152) 'id::<i128>': fn id<i128>(T) -> T
|
||||||
[152; 153) '1': i128
|
[142; 155) 'id::<i128>(1)': i128
|
||||||
|
[153; 154) '1': i128
|
||||||
"###
|
"###
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -3404,7 +3401,7 @@ impl S {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test(s: Arc<S>) {
|
fn test(s: Arc<S>) {
|
||||||
(*s, s.foo())<|>
|
(*s, s.foo())<|>;
|
||||||
}
|
}
|
||||||
"#,
|
"#,
|
||||||
);
|
);
|
||||||
|
@ -3488,7 +3485,7 @@ impl S {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test(s: Arc<S>) {
|
fn test(s: Arc<S>) {
|
||||||
(*s, s.foo())<|>
|
(*s, s.foo())<|>;
|
||||||
}
|
}
|
||||||
"#,
|
"#,
|
||||||
);
|
);
|
||||||
|
|
|
@ -19,6 +19,97 @@ fn infer(source: &str) -> String {
|
||||||
super::infer(&format!("{}{}", source, defs))
|
super::infer(&format!("{}{}", source, defs))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn infer_block_expr_type_mismatch() {
|
||||||
|
assert_snapshot!(
|
||||||
|
infer(r#"
|
||||||
|
fn test() {
|
||||||
|
let a: i32 = { 1i64 };
|
||||||
|
}
|
||||||
|
"#),
|
||||||
|
@r###"
|
||||||
|
[11; 41) '{ ...4 }; }': ()
|
||||||
|
[21; 22) 'a': i32
|
||||||
|
[30; 38) '{ 1i64 }': i64
|
||||||
|
[32; 36) '1i64': i64
|
||||||
|
"###);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn coerce_places() {
|
||||||
|
assert_snapshot!(
|
||||||
|
infer(r#"
|
||||||
|
struct S<T> { a: T }
|
||||||
|
|
||||||
|
fn f<T>(_: &[T]) -> T { loop {} }
|
||||||
|
fn g<T>(_: S<&[T]>) -> T { loop {} }
|
||||||
|
|
||||||
|
fn gen<T>() -> *mut [T; 2] { loop {} }
|
||||||
|
fn test1<U>() -> *mut [U] {
|
||||||
|
gen()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test2() {
|
||||||
|
let arr: &[u8; 1] = &[1];
|
||||||
|
|
||||||
|
let a: &[_] = arr;
|
||||||
|
let b = f(arr);
|
||||||
|
let c: &[_] = { arr };
|
||||||
|
let d = g(S { a: arr });
|
||||||
|
let e: [&[_]; 1] = [arr];
|
||||||
|
let f: [&[_]; 2] = [arr; 2];
|
||||||
|
let g: (&[_], &[_]) = (arr, arr);
|
||||||
|
}
|
||||||
|
"#),
|
||||||
|
@r###"
|
||||||
|
[31; 32) '_': &[T]
|
||||||
|
[45; 56) '{ loop {} }': T
|
||||||
|
[47; 54) 'loop {}': !
|
||||||
|
[52; 54) '{}': ()
|
||||||
|
[65; 66) '_': S<&[T]>
|
||||||
|
[82; 93) '{ loop {} }': T
|
||||||
|
[84; 91) 'loop {}': !
|
||||||
|
[89; 91) '{}': ()
|
||||||
|
[122; 133) '{ loop {} }': *mut [T;_]
|
||||||
|
[124; 131) 'loop {}': !
|
||||||
|
[129; 131) '{}': ()
|
||||||
|
[160; 173) '{ gen() }': *mut [U]
|
||||||
|
[166; 169) 'gen': fn gen<U>() -> *mut [T;_]
|
||||||
|
[166; 171) 'gen()': *mut [U;_]
|
||||||
|
[186; 420) '{ ...rr); }': ()
|
||||||
|
[196; 199) 'arr': &[u8;_]
|
||||||
|
[212; 216) '&[1]': &[u8;_]
|
||||||
|
[213; 216) '[1]': [u8;_]
|
||||||
|
[214; 215) '1': u8
|
||||||
|
[227; 228) 'a': &[u8]
|
||||||
|
[237; 240) 'arr': &[u8;_]
|
||||||
|
[250; 251) 'b': u8
|
||||||
|
[254; 255) 'f': fn f<u8>(&[T]) -> T
|
||||||
|
[254; 260) 'f(arr)': u8
|
||||||
|
[256; 259) 'arr': &[u8;_]
|
||||||
|
[270; 271) 'c': &[u8]
|
||||||
|
[280; 287) '{ arr }': &[u8]
|
||||||
|
[282; 285) 'arr': &[u8;_]
|
||||||
|
[297; 298) 'd': u8
|
||||||
|
[301; 302) 'g': fn g<u8>(S<&[T]>) -> T
|
||||||
|
[301; 316) 'g(S { a: arr })': u8
|
||||||
|
[303; 315) 'S { a: arr }': S<&[u8]>
|
||||||
|
[310; 313) 'arr': &[u8;_]
|
||||||
|
[326; 327) 'e': [&[u8];_]
|
||||||
|
[341; 346) '[arr]': [&[u8];_]
|
||||||
|
[342; 345) 'arr': &[u8;_]
|
||||||
|
[356; 357) 'f': [&[u8];_]
|
||||||
|
[371; 379) '[arr; 2]': [&[u8];_]
|
||||||
|
[372; 375) 'arr': &[u8;_]
|
||||||
|
[377; 378) '2': usize
|
||||||
|
[389; 390) 'g': (&[u8], &[u8])
|
||||||
|
[407; 417) '(arr, arr)': (&[u8], &[u8])
|
||||||
|
[408; 411) 'arr': &[u8;_]
|
||||||
|
[413; 416) 'arr': &[u8;_]
|
||||||
|
"###
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn infer_let_stmt_coerce() {
|
fn infer_let_stmt_coerce() {
|
||||||
assert_snapshot!(
|
assert_snapshot!(
|
||||||
|
@ -102,7 +193,7 @@ fn test() {
|
||||||
"#),
|
"#),
|
||||||
@r###"
|
@r###"
|
||||||
[11; 12) 'x': &[T]
|
[11; 12) 'x': &[T]
|
||||||
[28; 39) '{ loop {} }': !
|
[28; 39) '{ loop {} }': &[T]
|
||||||
[30; 37) 'loop {}': !
|
[30; 37) 'loop {}': !
|
||||||
[35; 37) '{}': ()
|
[35; 37) '{}': ()
|
||||||
[50; 126) '{ ... }; }': ()
|
[50; 126) '{ ... }; }': ()
|
||||||
|
@ -138,7 +229,7 @@ fn test() {
|
||||||
"#),
|
"#),
|
||||||
@r###"
|
@r###"
|
||||||
[11; 12) 'x': &[T]
|
[11; 12) 'x': &[T]
|
||||||
[28; 39) '{ loop {} }': !
|
[28; 39) '{ loop {} }': &[T]
|
||||||
[30; 37) 'loop {}': !
|
[30; 37) 'loop {}': !
|
||||||
[35; 37) '{}': ()
|
[35; 37) '{}': ()
|
||||||
[50; 126) '{ ... }; }': ()
|
[50; 126) '{ ... }; }': ()
|
||||||
|
@ -174,7 +265,7 @@ fn test(i: i32) {
|
||||||
"#),
|
"#),
|
||||||
@r###"
|
@r###"
|
||||||
[11; 12) 'x': &[T]
|
[11; 12) 'x': &[T]
|
||||||
[28; 39) '{ loop {} }': !
|
[28; 39) '{ loop {} }': &[T]
|
||||||
[30; 37) 'loop {}': !
|
[30; 37) 'loop {}': !
|
||||||
[35; 37) '{}': ()
|
[35; 37) '{}': ()
|
||||||
[48; 49) 'i': i32
|
[48; 49) 'i': i32
|
||||||
|
@ -215,7 +306,7 @@ fn test(i: i32) {
|
||||||
"#),
|
"#),
|
||||||
@r###"
|
@r###"
|
||||||
[11; 12) 'x': &[T]
|
[11; 12) 'x': &[T]
|
||||||
[28; 39) '{ loop {} }': !
|
[28; 39) '{ loop {} }': &[T]
|
||||||
[30; 37) 'loop {}': !
|
[30; 37) 'loop {}': !
|
||||||
[35; 37) '{}': ()
|
[35; 37) '{}': ()
|
||||||
[48; 49) 'i': i32
|
[48; 49) 'i': i32
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue