mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-15 22:54:00 +00:00
Auto merge of #18101 - ChayimFriedman2:inference-fix, r=Veykril
fix: Fix inference of literals when the expectation is Castable
I followed the compiler: 5bce6d48ff/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs (L1560-L1579)
.
Fixes #18095.
This commit is contained in:
commit
fdda41897f
4 changed files with 51 additions and 9 deletions
|
@ -895,21 +895,52 @@ impl InferenceContext<'_> {
|
||||||
TyKind::Scalar(Scalar::Int(primitive::int_ty_from_builtin(*int_ty)))
|
TyKind::Scalar(Scalar::Int(primitive::int_ty_from_builtin(*int_ty)))
|
||||||
.intern(Interner)
|
.intern(Interner)
|
||||||
}
|
}
|
||||||
None => self.table.new_integer_var(),
|
None => {
|
||||||
|
let expected_ty = expected.to_option(&mut self.table);
|
||||||
|
let opt_ty = match expected_ty.as_ref().map(|it| it.kind(Interner)) {
|
||||||
|
Some(TyKind::Scalar(Scalar::Int(_) | Scalar::Uint(_))) => expected_ty,
|
||||||
|
Some(TyKind::Scalar(Scalar::Char)) => {
|
||||||
|
Some(TyKind::Scalar(Scalar::Uint(UintTy::U8)).intern(Interner))
|
||||||
|
}
|
||||||
|
Some(TyKind::Raw(..) | TyKind::FnDef(..) | TyKind::Function(..)) => {
|
||||||
|
Some(TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(Interner))
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
opt_ty.unwrap_or_else(|| self.table.new_integer_var())
|
||||||
|
}
|
||||||
},
|
},
|
||||||
Literal::Uint(_v, ty) => match ty {
|
Literal::Uint(_v, ty) => match ty {
|
||||||
Some(int_ty) => {
|
Some(int_ty) => {
|
||||||
TyKind::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(*int_ty)))
|
TyKind::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(*int_ty)))
|
||||||
.intern(Interner)
|
.intern(Interner)
|
||||||
}
|
}
|
||||||
None => self.table.new_integer_var(),
|
None => {
|
||||||
|
let expected_ty = expected.to_option(&mut self.table);
|
||||||
|
let opt_ty = match expected_ty.as_ref().map(|it| it.kind(Interner)) {
|
||||||
|
Some(TyKind::Scalar(Scalar::Int(_) | Scalar::Uint(_))) => expected_ty,
|
||||||
|
Some(TyKind::Scalar(Scalar::Char)) => {
|
||||||
|
Some(TyKind::Scalar(Scalar::Uint(UintTy::U8)).intern(Interner))
|
||||||
|
}
|
||||||
|
Some(TyKind::Raw(..) | TyKind::FnDef(..) | TyKind::Function(..)) => {
|
||||||
|
Some(TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(Interner))
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
opt_ty.unwrap_or_else(|| self.table.new_integer_var())
|
||||||
|
}
|
||||||
},
|
},
|
||||||
Literal::Float(_v, ty) => match ty {
|
Literal::Float(_v, ty) => match ty {
|
||||||
Some(float_ty) => {
|
Some(float_ty) => {
|
||||||
TyKind::Scalar(Scalar::Float(primitive::float_ty_from_builtin(*float_ty)))
|
TyKind::Scalar(Scalar::Float(primitive::float_ty_from_builtin(*float_ty)))
|
||||||
.intern(Interner)
|
.intern(Interner)
|
||||||
}
|
}
|
||||||
None => self.table.new_float_var(),
|
None => {
|
||||||
|
let opt_ty = expected.to_option(&mut self.table).filter(|ty| {
|
||||||
|
matches!(ty.kind(Interner), TyKind::Scalar(Scalar::Float(_)))
|
||||||
|
});
|
||||||
|
opt_ty.unwrap_or_else(|| self.table.new_float_var())
|
||||||
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Expr::Underscore => {
|
Expr::Underscore => {
|
||||||
|
|
|
@ -49,7 +49,7 @@ fn let_stmt_coerce() {
|
||||||
//- minicore: coerce_unsized
|
//- minicore: coerce_unsized
|
||||||
fn test() {
|
fn test() {
|
||||||
let x: &[isize] = &[1];
|
let x: &[isize] = &[1];
|
||||||
// ^^^^ adjustments: Deref(None), Borrow(Ref('?3, Not)), Pointer(Unsize)
|
// ^^^^ adjustments: Deref(None), Borrow(Ref('?2, Not)), Pointer(Unsize)
|
||||||
let x: *const [isize] = &[1];
|
let x: *const [isize] = &[1];
|
||||||
// ^^^^ adjustments: Deref(None), Borrow(RawPtr(Not)), Pointer(Unsize)
|
// ^^^^ adjustments: Deref(None), Borrow(RawPtr(Not)), Pointer(Unsize)
|
||||||
}
|
}
|
||||||
|
@ -148,7 +148,7 @@ fn foo<T>(x: &[T]) -> &[T] { x }
|
||||||
fn test(i: i32) {
|
fn test(i: i32) {
|
||||||
let x = match i {
|
let x = match i {
|
||||||
2 => foo(&[2]),
|
2 => foo(&[2]),
|
||||||
// ^^^^ adjustments: Deref(None), Borrow(Ref('?10, Not)), Pointer(Unsize)
|
// ^^^^ adjustments: Deref(None), Borrow(Ref('?8, Not)), Pointer(Unsize)
|
||||||
1 => &[1],
|
1 => &[1],
|
||||||
_ => &[3],
|
_ => &[3],
|
||||||
};
|
};
|
||||||
|
|
|
@ -917,7 +917,7 @@ fn test(a: A<i32>) {
|
||||||
278..279 'A': extern "rust-call" A<i32>(*mut i32) -> A<i32>
|
278..279 'A': extern "rust-call" A<i32>(*mut i32) -> A<i32>
|
||||||
278..292 'A(0 as *mut _)': A<i32>
|
278..292 'A(0 as *mut _)': A<i32>
|
||||||
278..307 'A(0 as...B(a)))': &'? i32
|
278..307 'A(0 as...B(a)))': &'? i32
|
||||||
280..281 '0': i32
|
280..281 '0': usize
|
||||||
280..291 '0 as *mut _': *mut i32
|
280..291 '0 as *mut _': *mut i32
|
||||||
297..306 '&&B(B(a))': &'? &'? B<B<A<i32>>>
|
297..306 '&&B(B(a))': &'? &'? B<B<A<i32>>>
|
||||||
298..306 '&B(B(a))': &'? B<B<A<i32>>>
|
298..306 '&B(B(a))': &'? B<B<A<i32>>>
|
||||||
|
|
|
@ -441,16 +441,16 @@ fn main() {
|
||||||
//^^^^^^^^^^^^^^^^^ error: cannot cast thin pointer `*const i32` to fat pointer `*const [i32]`
|
//^^^^^^^^^^^^^^^^^ error: cannot cast thin pointer `*const i32` to fat pointer `*const [i32]`
|
||||||
|
|
||||||
let t: *mut (dyn Trait + 'static) = 0 as *mut _;
|
let t: *mut (dyn Trait + 'static) = 0 as *mut _;
|
||||||
//^^^^^^^^^^^ error: cannot cast `i32` to a fat pointer `*mut _`
|
//^^^^^^^^^^^ error: cannot cast `usize` to a fat pointer `*mut _`
|
||||||
let mut fail: *const str = 0 as *const str;
|
let mut fail: *const str = 0 as *const str;
|
||||||
//^^^^^^^^^^^^^^^ error: cannot cast `i32` to a fat pointer `*const str`
|
//^^^^^^^^^^^^^^^ error: cannot cast `usize` to a fat pointer `*const str`
|
||||||
let mut fail2: *const str = 0isize as *const str;
|
let mut fail2: *const str = 0isize as *const str;
|
||||||
//^^^^^^^^^^^^^^^^^^^^ error: cannot cast `isize` to a fat pointer `*const str`
|
//^^^^^^^^^^^^^^^^^^^^ error: cannot cast `isize` to a fat pointer `*const str`
|
||||||
}
|
}
|
||||||
|
|
||||||
fn foo<T: ?Sized>() {
|
fn foo<T: ?Sized>() {
|
||||||
let s = 0 as *const T;
|
let s = 0 as *const T;
|
||||||
//^^^^^^^^^^^^^ error: cannot cast `i32` to a fat pointer `*const T`
|
//^^^^^^^^^^^^^ error: cannot cast `usize` to a fat pointer `*const T`
|
||||||
}
|
}
|
||||||
"#,
|
"#,
|
||||||
&["E0308", "unused_variables"],
|
&["E0308", "unused_variables"],
|
||||||
|
@ -1100,4 +1100,15 @@ where
|
||||||
"#,
|
"#,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn cast_literal_to_char() {
|
||||||
|
check_diagnostics(
|
||||||
|
r#"
|
||||||
|
fn foo() {
|
||||||
|
0 as char;
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue