mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-28 22:13:39 +00:00
Auto merge of #14104 - Veykril:castable-expect, r=Veykril
fix: Implement Expactation::Castable and add a test case for it Fixes https://github.com/rust-lang/rust-analyzer/issues/11571
This commit is contained in:
commit
eaed19c539
3 changed files with 41 additions and 8 deletions
|
@ -1024,7 +1024,7 @@ impl<'a> InferenceContext<'a> {
|
|||
pub(crate) enum Expectation {
|
||||
None,
|
||||
HasType(Ty),
|
||||
// Castable(Ty), // rustc has this, we currently just don't propagate an expectation for casts
|
||||
Castable(Ty),
|
||||
RValueLikeUnsized(Ty),
|
||||
}
|
||||
|
||||
|
@ -1077,6 +1077,7 @@ impl Expectation {
|
|||
match self {
|
||||
Expectation::None => Expectation::None,
|
||||
Expectation::HasType(t) => Expectation::HasType(table.resolve_ty_shallow(t)),
|
||||
Expectation::Castable(t) => Expectation::Castable(table.resolve_ty_shallow(t)),
|
||||
Expectation::RValueLikeUnsized(t) => {
|
||||
Expectation::RValueLikeUnsized(table.resolve_ty_shallow(t))
|
||||
}
|
||||
|
@ -1086,17 +1087,18 @@ impl Expectation {
|
|||
fn to_option(&self, table: &mut unify::InferenceTable<'_>) -> Option<Ty> {
|
||||
match self.resolve(table) {
|
||||
Expectation::None => None,
|
||||
Expectation::HasType(t) |
|
||||
// Expectation::Castable(t) |
|
||||
Expectation::RValueLikeUnsized(t) => Some(t),
|
||||
Expectation::HasType(t)
|
||||
| Expectation::Castable(t)
|
||||
| Expectation::RValueLikeUnsized(t) => Some(t),
|
||||
}
|
||||
}
|
||||
|
||||
fn only_has_type(&self, table: &mut unify::InferenceTable<'_>) -> Option<Ty> {
|
||||
match self {
|
||||
Expectation::HasType(t) => Some(table.resolve_ty_shallow(t)),
|
||||
// Expectation::Castable(_) |
|
||||
Expectation::RValueLikeUnsized(_) | Expectation::None => None,
|
||||
Expectation::Castable(_) | Expectation::RValueLikeUnsized(_) | Expectation::None => {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -610,9 +610,9 @@ impl<'a> InferenceContext<'a> {
|
|||
}
|
||||
}
|
||||
Expr::Cast { expr, type_ref } => {
|
||||
// FIXME: propagate the "castable to" expectation (and find a test case that shows this is necessary)
|
||||
let _inner_ty = self.infer_expr_inner(*expr, &Expectation::none());
|
||||
let cast_ty = self.make_ty(type_ref);
|
||||
let _inner_ty =
|
||||
self.infer_expr_inner(*expr, &Expectation::Castable(cast_ty.clone()));
|
||||
// FIXME check the cast...
|
||||
cast_ty
|
||||
}
|
||||
|
|
|
@ -3200,3 +3200,34 @@ fn func() {
|
|||
"#,
|
||||
);
|
||||
}
|
||||
#[test]
|
||||
fn castable_to() {
|
||||
check_infer(
|
||||
r#"
|
||||
//- minicore: sized
|
||||
#[lang = "owned_box"]
|
||||
pub struct Box<T: ?Sized> {
|
||||
inner: *mut T,
|
||||
}
|
||||
impl<T> Box<T> {
|
||||
fn new(t: T) -> Self { loop {} }
|
||||
}
|
||||
|
||||
fn func() {
|
||||
let x = Box::new([]) as Box<[i32; 0]>;
|
||||
}
|
||||
"#,
|
||||
expect![[r#"
|
||||
99..100 't': T
|
||||
113..124 '{ loop {} }': Box<T>
|
||||
115..122 'loop {}': !
|
||||
120..122 '{}': ()
|
||||
138..184 '{ ...0]>; }': ()
|
||||
148..149 'x': Box<[i32; 0]>
|
||||
152..160 'Box::new': fn new<[i32; 0]>([i32; 0]) -> Box<[i32; 0]>
|
||||
152..164 'Box::new([])': Box<[i32; 0]>
|
||||
152..181 'Box::n...2; 0]>': Box<[i32; 0]>
|
||||
161..163 '[]': [i32; 0]
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue