Skip to content

Commit eaed19c

Browse files
committed
Auto merge of rust-lang#14104 - Veykril:castable-expect, r=Veykril
fix: Implement Expactation::Castable and add a test case for it Fixes rust-lang/rust-analyzer#11571
2 parents 5341a6f + f8f1cb9 commit eaed19c

File tree

3 files changed

+41
-8
lines changed

3 files changed

+41
-8
lines changed

crates/hir-ty/src/infer.rs

+8-6
Original file line numberDiff line numberDiff line change
@@ -1024,7 +1024,7 @@ impl<'a> InferenceContext<'a> {
10241024
pub(crate) enum Expectation {
10251025
None,
10261026
HasType(Ty),
1027-
// Castable(Ty), // rustc has this, we currently just don't propagate an expectation for casts
1027+
Castable(Ty),
10281028
RValueLikeUnsized(Ty),
10291029
}
10301030

@@ -1077,6 +1077,7 @@ impl Expectation {
10771077
match self {
10781078
Expectation::None => Expectation::None,
10791079
Expectation::HasType(t) => Expectation::HasType(table.resolve_ty_shallow(t)),
1080+
Expectation::Castable(t) => Expectation::Castable(table.resolve_ty_shallow(t)),
10801081
Expectation::RValueLikeUnsized(t) => {
10811082
Expectation::RValueLikeUnsized(table.resolve_ty_shallow(t))
10821083
}
@@ -1086,17 +1087,18 @@ impl Expectation {
10861087
fn to_option(&self, table: &mut unify::InferenceTable<'_>) -> Option<Ty> {
10871088
match self.resolve(table) {
10881089
Expectation::None => None,
1089-
Expectation::HasType(t) |
1090-
// Expectation::Castable(t) |
1091-
Expectation::RValueLikeUnsized(t) => Some(t),
1090+
Expectation::HasType(t)
1091+
| Expectation::Castable(t)
1092+
| Expectation::RValueLikeUnsized(t) => Some(t),
10921093
}
10931094
}
10941095

10951096
fn only_has_type(&self, table: &mut unify::InferenceTable<'_>) -> Option<Ty> {
10961097
match self {
10971098
Expectation::HasType(t) => Some(table.resolve_ty_shallow(t)),
1098-
// Expectation::Castable(_) |
1099-
Expectation::RValueLikeUnsized(_) | Expectation::None => None,
1099+
Expectation::Castable(_) | Expectation::RValueLikeUnsized(_) | Expectation::None => {
1100+
None
1101+
}
11001102
}
11011103
}
11021104

crates/hir-ty/src/infer/expr.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -610,9 +610,9 @@ impl<'a> InferenceContext<'a> {
610610
}
611611
}
612612
Expr::Cast { expr, type_ref } => {
613-
// FIXME: propagate the "castable to" expectation (and find a test case that shows this is necessary)
614-
let _inner_ty = self.infer_expr_inner(*expr, &Expectation::none());
615613
let cast_ty = self.make_ty(type_ref);
614+
let _inner_ty =
615+
self.infer_expr_inner(*expr, &Expectation::Castable(cast_ty.clone()));
616616
// FIXME check the cast...
617617
cast_ty
618618
}

crates/hir-ty/src/tests/simple.rs

+31
Original file line numberDiff line numberDiff line change
@@ -3200,3 +3200,34 @@ fn func() {
32003200
"#,
32013201
);
32023202
}
3203+
#[test]
3204+
fn castable_to() {
3205+
check_infer(
3206+
r#"
3207+
//- minicore: sized
3208+
#[lang = "owned_box"]
3209+
pub struct Box<T: ?Sized> {
3210+
inner: *mut T,
3211+
}
3212+
impl<T> Box<T> {
3213+
fn new(t: T) -> Self { loop {} }
3214+
}
3215+
3216+
fn func() {
3217+
let x = Box::new([]) as Box<[i32; 0]>;
3218+
}
3219+
"#,
3220+
expect![[r#"
3221+
99..100 't': T
3222+
113..124 '{ loop {} }': Box<T>
3223+
115..122 'loop {}': !
3224+
120..122 '{}': ()
3225+
138..184 '{ ...0]>; }': ()
3226+
148..149 'x': Box<[i32; 0]>
3227+
152..160 'Box::new': fn new<[i32; 0]>([i32; 0]) -> Box<[i32; 0]>
3228+
152..164 'Box::new([])': Box<[i32; 0]>
3229+
152..181 'Box::n...2; 0]>': Box<[i32; 0]>
3230+
161..163 '[]': [i32; 0]
3231+
"#]],
3232+
);
3233+
}

0 commit comments

Comments
 (0)