Skip to content

Commit 79492cb

Browse files
committed
internal: Revert castable expectation and simplify
1 parent 8f5deb4 commit 79492cb

File tree

5 files changed

+88
-31
lines changed

5 files changed

+88
-31
lines changed

crates/hir-ty/src/infer.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,7 @@ struct InternedStandardTypes {
219219
unknown: Ty,
220220
bool_: Ty,
221221
unit: Ty,
222+
never: Ty,
222223
}
223224

224225
impl Default for InternedStandardTypes {
@@ -227,6 +228,7 @@ impl Default for InternedStandardTypes {
227228
unknown: TyKind::Error.intern(Interner),
228229
bool_: TyKind::Scalar(Scalar::Bool).intern(Interner),
229230
unit: TyKind::Tuple(0, Substitution::empty(Interner)).intern(Interner),
231+
never: TyKind::Never.intern(Interner),
230232
}
231233
}
232234
}
@@ -1024,6 +1026,7 @@ impl<'a> InferenceContext<'a> {
10241026
pub(crate) enum Expectation {
10251027
None,
10261028
HasType(Ty),
1029+
#[allow(dead_code)]
10271030
Castable(Ty),
10281031
RValueLikeUnsized(Ty),
10291032
}
@@ -1102,6 +1105,10 @@ impl Expectation {
11021105
}
11031106
}
11041107

1108+
fn coercion_target_type(&self, table: &mut unify::InferenceTable<'_>) -> Ty {
1109+
self.only_has_type(table).unwrap_or_else(|| table.new_type_var())
1110+
}
1111+
11051112
/// Comment copied from rustc:
11061113
/// Disregard "castable to" expectations because they
11071114
/// can lead us astray. Consider for example `if cond

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ impl InferenceContext<'_> {
5151
.map(to_chalk_trait_id)
5252
.collect();
5353

54-
let self_ty = TyKind::Error.intern(Interner);
54+
let self_ty = self.result.standard_types.unknown.clone();
5555
let bounds = dyn_ty.bounds.clone().substitute(Interner, &[self_ty.cast(Interner)]);
5656
for bound in bounds.iter(Interner) {
5757
// NOTE(skip_binders): the extracted types are rebound by the returned `FnPointer`

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

Lines changed: 24 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -87,16 +87,15 @@ impl<'a> InferenceContext<'a> {
8787
let expected = &expected.adjust_for_branches(&mut self.table);
8888
self.infer_expr(
8989
condition,
90-
&Expectation::has_type(TyKind::Scalar(Scalar::Bool).intern(Interner)),
90+
&Expectation::HasType(self.result.standard_types.bool_.clone()),
9191
);
9292

9393
let condition_diverges = mem::replace(&mut self.diverges, Diverges::Maybe);
9494
let mut both_arms_diverge = Diverges::Always;
9595

96-
let result_ty = self.table.new_type_var();
9796
let then_ty = self.infer_expr_inner(then_branch, expected);
9897
both_arms_diverge &= mem::replace(&mut self.diverges, Diverges::Maybe);
99-
let mut coerce = CoerceMany::new(result_ty);
98+
let mut coerce = CoerceMany::new(expected.coercion_target_type(&mut self.table));
10099
coerce.coerce(self, Some(then_branch), &then_ty);
101100
let else_ty = match else_branch {
102101
Some(else_branch) => self.infer_expr_inner(else_branch, expected),
@@ -113,7 +112,7 @@ impl<'a> InferenceContext<'a> {
113112
&Expr::Let { pat, expr } => {
114113
let input_ty = self.infer_expr(expr, &Expectation::none());
115114
self.infer_pat(pat, &input_ty, BindingMode::default());
116-
TyKind::Scalar(Scalar::Bool).intern(Interner)
115+
self.result.standard_types.bool_.clone()
117116
}
118117
Expr::Block { statements, tail, label, id: _ } => {
119118
let old_resolver = mem::replace(
@@ -188,27 +187,29 @@ impl<'a> InferenceContext<'a> {
188187
.intern(Interner)
189188
}
190189
&Expr::Loop { body, label } => {
190+
// FIXME: should be:
191+
// let ty = expected.coercion_target_type(&mut self.table);
191192
let ty = self.table.new_type_var();
192193
let (breaks, ()) =
193194
self.with_breakable_ctx(BreakableKind::Loop, ty, label, |this| {
194-
this.infer_expr(body, &Expectation::has_type(TyBuilder::unit()));
195+
this.infer_expr(body, &Expectation::HasType(TyBuilder::unit()));
195196
});
196197

197198
match breaks {
198199
Some(breaks) => {
199200
self.diverges = Diverges::Maybe;
200201
breaks
201202
}
202-
None => TyKind::Never.intern(Interner),
203+
None => self.result.standard_types.never.clone(),
203204
}
204205
}
205206
&Expr::While { condition, body, label } => {
206207
self.with_breakable_ctx(BreakableKind::Loop, self.err_ty(), label, |this| {
207208
this.infer_expr(
208209
condition,
209-
&Expectation::has_type(TyKind::Scalar(Scalar::Bool).intern(Interner)),
210+
&Expectation::HasType(this.result.standard_types.bool_.clone()),
210211
);
211-
this.infer_expr(body, &Expectation::has_type(TyBuilder::unit()));
212+
this.infer_expr(body, &Expectation::HasType(TyBuilder::unit()));
212213
});
213214

214215
// the body may not run, so it diverging doesn't mean we diverge
@@ -224,7 +225,7 @@ impl<'a> InferenceContext<'a> {
224225

225226
self.infer_pat(pat, &pat_ty, BindingMode::default());
226227
self.with_breakable_ctx(BreakableKind::Loop, self.err_ty(), label, |this| {
227-
this.infer_expr(body, &Expectation::has_type(TyBuilder::unit()));
228+
this.infer_expr(body, &Expectation::HasType(TyBuilder::unit()));
228229
});
229230

230231
// the body may not run, so it diverging doesn't mean we diverge
@@ -382,12 +383,9 @@ impl<'a> InferenceContext<'a> {
382383
let expected = expected.adjust_for_branches(&mut self.table);
383384

384385
let result_ty = if arms.is_empty() {
385-
TyKind::Never.intern(Interner)
386+
self.result.standard_types.never.clone()
386387
} else {
387-
match &expected {
388-
Expectation::HasType(ty) => ty.clone(),
389-
_ => self.table.new_type_var(),
390-
}
388+
expected.coercion_target_type(&mut self.table)
391389
};
392390
let mut coerce = CoerceMany::new(result_ty);
393391

@@ -400,7 +398,7 @@ impl<'a> InferenceContext<'a> {
400398
if let Some(guard_expr) = arm.guard {
401399
self.infer_expr(
402400
guard_expr,
403-
&Expectation::has_type(TyKind::Scalar(Scalar::Bool).intern(Interner)),
401+
&Expectation::HasType(self.result.standard_types.bool_.clone()),
404402
);
405403
}
406404

@@ -425,7 +423,7 @@ impl<'a> InferenceContext<'a> {
425423
is_break: false,
426424
});
427425
};
428-
TyKind::Never.intern(Interner)
426+
self.result.standard_types.never.clone()
429427
}
430428
Expr::Break { expr, label } => {
431429
let val_ty = if let Some(expr) = *expr {
@@ -439,7 +437,7 @@ impl<'a> InferenceContext<'a> {
439437
// avoiding the borrowck
440438
let mut coerce = mem::replace(
441439
&mut ctxt.coerce,
442-
CoerceMany::new(self.result.standard_types.unknown.clone()),
440+
CoerceMany::new(expected.coercion_target_type(&mut self.table)),
443441
);
444442

445443
// FIXME: create a synthetic `()` during lowering so we have something to refer to here?
@@ -457,7 +455,7 @@ impl<'a> InferenceContext<'a> {
457455
});
458456
}
459457
}
460-
TyKind::Never.intern(Interner)
458+
self.result.standard_types.never.clone()
461459
}
462460
Expr::Return { expr } => {
463461
if let Some(expr) = expr {
@@ -466,7 +464,7 @@ impl<'a> InferenceContext<'a> {
466464
let unit = TyBuilder::unit();
467465
let _ = self.coerce(Some(tgt_expr), &unit, &self.return_ty.clone());
468466
}
469-
TyKind::Never.intern(Interner)
467+
self.result.standard_types.never.clone()
470468
}
471469
Expr::Yield { expr } => {
472470
if let Some((resume_ty, yield_ty)) = self.resume_yield_tys.clone() {
@@ -479,14 +477,14 @@ impl<'a> InferenceContext<'a> {
479477
resume_ty
480478
} else {
481479
// FIXME: report error (yield expr in non-generator)
482-
TyKind::Error.intern(Interner)
480+
self.result.standard_types.unknown.clone()
483481
}
484482
}
485483
Expr::Yeet { expr } => {
486484
if let &Some(expr) = expr {
487485
self.infer_expr_inner(expr, &Expectation::None);
488486
}
489-
TyKind::Never.intern(Interner)
487+
self.result.standard_types.never.clone()
490488
}
491489
Expr::RecordLit { path, fields, spread, .. } => {
492490
let (ty, def_id) = self.resolve_variant(path.as_deref(), false);
@@ -611,8 +609,8 @@ impl<'a> InferenceContext<'a> {
611609
}
612610
Expr::Cast { expr, type_ref } => {
613611
let cast_ty = self.make_ty(type_ref);
614-
let _inner_ty =
615-
self.infer_expr_inner(*expr, &Expectation::Castable(cast_ty.clone()));
612+
// FIXME: propagate the "castable to" expectation
613+
let _inner_ty = self.infer_expr_inner(*expr, &Expectation::None);
616614
// FIXME check the cast...
617615
cast_ty
618616
}
@@ -829,7 +827,7 @@ impl<'a> InferenceContext<'a> {
829827
self.infer_expr_coerce(initializer, &Expectation::has_type(elem_ty));
830828
self.infer_expr(
831829
repeat,
832-
&Expectation::has_type(
830+
&Expectation::HasType(
833831
TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(Interner),
834832
),
835833
);
@@ -852,7 +850,7 @@ impl<'a> InferenceContext<'a> {
852850
TyKind::Array(coerce.complete(), len).intern(Interner)
853851
}
854852
Expr::Literal(lit) => match lit {
855-
Literal::Bool(..) => TyKind::Scalar(Scalar::Bool).intern(Interner),
853+
Literal::Bool(..) => self.result.standard_types.bool_.clone(),
856854
Literal::String(..) => {
857855
TyKind::Ref(Mutability::Not, static_lifetime(), TyKind::Str.intern(Interner))
858856
.intern(Interner)
@@ -1148,7 +1146,7 @@ impl<'a> InferenceContext<'a> {
11481146
if let Some(expr) = else_branch {
11491147
self.infer_expr_coerce(
11501148
*expr,
1151-
&Expectation::has_type(Ty::new(Interner, TyKind::Never)),
1149+
&Expectation::HasType(self.result.standard_types.never.clone()),
11521150
);
11531151
}
11541152

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ impl<'a> InferenceContext<'a> {
112112
let ty = TyBuilder::value_ty(self.db, typable, parent_substs)
113113
.fill(|x| {
114114
it.next().unwrap_or_else(|| match x {
115-
ParamKind::Type => TyKind::Error.intern(Interner).cast(Interner),
115+
ParamKind::Type => self.result.standard_types.unknown.clone().cast(Interner),
116116
ParamKind::Const(ty) => consteval::unknown_const_as_generic(ty.clone()),
117117
})
118118
})

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

Lines changed: 55 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3200,6 +3200,8 @@ fn func() {
32003200
"#,
32013201
);
32023202
}
3203+
3204+
// FIXME
32033205
#[test]
32043206
fn castable_to() {
32053207
check_infer(
@@ -3224,10 +3226,60 @@ fn func() {
32243226
120..122 '{}': ()
32253227
138..184 '{ ...0]>; }': ()
32263228
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..160 'Box::new': fn new<[{unknown}; 0]>([{unknown}; 0]) -> Box<[{unknown}; 0]>
3230+
152..164 'Box::new([])': Box<[{unknown}; 0]>
32293231
152..181 'Box::n...2; 0]>': Box<[i32; 0]>
3230-
161..163 '[]': [i32; 0]
3232+
161..163 '[]': [{unknown}; 0]
3233+
"#]],
3234+
);
3235+
}
3236+
3237+
#[test]
3238+
fn castable_to1() {
3239+
check_infer(
3240+
r#"
3241+
struct Ark<T>(T);
3242+
impl<T> Ark<T> {
3243+
fn foo(&self) -> *const T {
3244+
&self.0
3245+
}
3246+
}
3247+
fn f<T>(t: Ark<T>) {
3248+
Ark::foo(&t) as *const ();
3249+
}
3250+
"#,
3251+
expect![[r#"
3252+
47..51 'self': &Ark<T>
3253+
65..88 '{ ... }': *const T
3254+
75..82 '&self.0': &T
3255+
76..80 'self': &Ark<T>
3256+
76..82 'self.0': T
3257+
99..100 't': Ark<T>
3258+
110..144 '{ ... (); }': ()
3259+
116..124 'Ark::foo': fn foo<T>(&Ark<T>) -> *const T
3260+
116..128 'Ark::foo(&t)': *const T
3261+
116..141 'Ark::f...nst ()': *const ()
3262+
125..127 '&t': &Ark<T>
3263+
126..127 't': Ark<T>
3264+
"#]],
3265+
);
3266+
}
3267+
3268+
// FIXME
3269+
#[test]
3270+
fn castable_to2() {
3271+
check_infer(
3272+
r#"
3273+
fn func() {
3274+
let x = &0u32 as *const _;
3275+
}
3276+
"#,
3277+
expect![[r#"
3278+
10..44 '{ ...t _; }': ()
3279+
20..21 'x': *const {unknown}
3280+
24..29 '&0u32': &u32
3281+
24..41 '&0u32 ...onst _': *const {unknown}
3282+
25..29 '0u32': u32
32313283
"#]],
32323284
);
32333285
}

0 commit comments

Comments
 (0)