internal: Revert castable expectation and simplify
This commit is contained in:
parent
8f5deb4ff2
commit
79492cb8ae
@ -219,6 +219,7 @@ struct InternedStandardTypes {
|
||||
unknown: Ty,
|
||||
bool_: Ty,
|
||||
unit: Ty,
|
||||
never: Ty,
|
||||
}
|
||||
|
||||
impl Default for InternedStandardTypes {
|
||||
@ -227,6 +228,7 @@ fn default() -> Self {
|
||||
unknown: TyKind::Error.intern(Interner),
|
||||
bool_: TyKind::Scalar(Scalar::Bool).intern(Interner),
|
||||
unit: TyKind::Tuple(0, Substitution::empty(Interner)).intern(Interner),
|
||||
never: TyKind::Never.intern(Interner),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1024,6 +1026,7 @@ fn resolve_va_list(&self) -> Option<AdtId> {
|
||||
pub(crate) enum Expectation {
|
||||
None,
|
||||
HasType(Ty),
|
||||
#[allow(dead_code)]
|
||||
Castable(Ty),
|
||||
RValueLikeUnsized(Ty),
|
||||
}
|
||||
@ -1102,6 +1105,10 @@ fn only_has_type(&self, table: &mut unify::InferenceTable<'_>) -> Option<Ty> {
|
||||
}
|
||||
}
|
||||
|
||||
fn coercion_target_type(&self, table: &mut unify::InferenceTable<'_>) -> Ty {
|
||||
self.only_has_type(table).unwrap_or_else(|| table.new_type_var())
|
||||
}
|
||||
|
||||
/// Comment copied from rustc:
|
||||
/// Disregard "castable to" expectations because they
|
||||
/// can lead us astray. Consider for example `if cond
|
||||
|
@ -51,7 +51,7 @@ fn deduce_sig_from_dyn_ty(&self, dyn_ty: &DynTy) -> Option<FnPointer> {
|
||||
.map(to_chalk_trait_id)
|
||||
.collect();
|
||||
|
||||
let self_ty = TyKind::Error.intern(Interner);
|
||||
let self_ty = self.result.standard_types.unknown.clone();
|
||||
let bounds = dyn_ty.bounds.clone().substitute(Interner, &[self_ty.cast(Interner)]);
|
||||
for bound in bounds.iter(Interner) {
|
||||
// NOTE(skip_binders): the extracted types are rebound by the returned `FnPointer`
|
||||
|
@ -87,16 +87,15 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
|
||||
let expected = &expected.adjust_for_branches(&mut self.table);
|
||||
self.infer_expr(
|
||||
condition,
|
||||
&Expectation::has_type(TyKind::Scalar(Scalar::Bool).intern(Interner)),
|
||||
&Expectation::HasType(self.result.standard_types.bool_.clone()),
|
||||
);
|
||||
|
||||
let condition_diverges = mem::replace(&mut self.diverges, Diverges::Maybe);
|
||||
let mut both_arms_diverge = Diverges::Always;
|
||||
|
||||
let result_ty = self.table.new_type_var();
|
||||
let then_ty = self.infer_expr_inner(then_branch, expected);
|
||||
both_arms_diverge &= mem::replace(&mut self.diverges, Diverges::Maybe);
|
||||
let mut coerce = CoerceMany::new(result_ty);
|
||||
let mut coerce = CoerceMany::new(expected.coercion_target_type(&mut self.table));
|
||||
coerce.coerce(self, Some(then_branch), &then_ty);
|
||||
let else_ty = match else_branch {
|
||||
Some(else_branch) => self.infer_expr_inner(else_branch, expected),
|
||||
@ -113,7 +112,7 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
|
||||
&Expr::Let { pat, expr } => {
|
||||
let input_ty = self.infer_expr(expr, &Expectation::none());
|
||||
self.infer_pat(pat, &input_ty, BindingMode::default());
|
||||
TyKind::Scalar(Scalar::Bool).intern(Interner)
|
||||
self.result.standard_types.bool_.clone()
|
||||
}
|
||||
Expr::Block { statements, tail, label, id: _ } => {
|
||||
let old_resolver = mem::replace(
|
||||
@ -188,10 +187,12 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
|
||||
.intern(Interner)
|
||||
}
|
||||
&Expr::Loop { body, label } => {
|
||||
// FIXME: should be:
|
||||
// let ty = expected.coercion_target_type(&mut self.table);
|
||||
let ty = self.table.new_type_var();
|
||||
let (breaks, ()) =
|
||||
self.with_breakable_ctx(BreakableKind::Loop, ty, label, |this| {
|
||||
this.infer_expr(body, &Expectation::has_type(TyBuilder::unit()));
|
||||
this.infer_expr(body, &Expectation::HasType(TyBuilder::unit()));
|
||||
});
|
||||
|
||||
match breaks {
|
||||
@ -199,16 +200,16 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
|
||||
self.diverges = Diverges::Maybe;
|
||||
breaks
|
||||
}
|
||||
None => TyKind::Never.intern(Interner),
|
||||
None => self.result.standard_types.never.clone(),
|
||||
}
|
||||
}
|
||||
&Expr::While { condition, body, label } => {
|
||||
self.with_breakable_ctx(BreakableKind::Loop, self.err_ty(), label, |this| {
|
||||
this.infer_expr(
|
||||
condition,
|
||||
&Expectation::has_type(TyKind::Scalar(Scalar::Bool).intern(Interner)),
|
||||
&Expectation::HasType(this.result.standard_types.bool_.clone()),
|
||||
);
|
||||
this.infer_expr(body, &Expectation::has_type(TyBuilder::unit()));
|
||||
this.infer_expr(body, &Expectation::HasType(TyBuilder::unit()));
|
||||
});
|
||||
|
||||
// the body may not run, so it diverging doesn't mean we diverge
|
||||
@ -224,7 +225,7 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
|
||||
|
||||
self.infer_pat(pat, &pat_ty, BindingMode::default());
|
||||
self.with_breakable_ctx(BreakableKind::Loop, self.err_ty(), label, |this| {
|
||||
this.infer_expr(body, &Expectation::has_type(TyBuilder::unit()));
|
||||
this.infer_expr(body, &Expectation::HasType(TyBuilder::unit()));
|
||||
});
|
||||
|
||||
// the body may not run, so it diverging doesn't mean we diverge
|
||||
@ -382,12 +383,9 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
|
||||
let expected = expected.adjust_for_branches(&mut self.table);
|
||||
|
||||
let result_ty = if arms.is_empty() {
|
||||
TyKind::Never.intern(Interner)
|
||||
self.result.standard_types.never.clone()
|
||||
} else {
|
||||
match &expected {
|
||||
Expectation::HasType(ty) => ty.clone(),
|
||||
_ => self.table.new_type_var(),
|
||||
}
|
||||
expected.coercion_target_type(&mut self.table)
|
||||
};
|
||||
let mut coerce = CoerceMany::new(result_ty);
|
||||
|
||||
@ -400,7 +398,7 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
|
||||
if let Some(guard_expr) = arm.guard {
|
||||
self.infer_expr(
|
||||
guard_expr,
|
||||
&Expectation::has_type(TyKind::Scalar(Scalar::Bool).intern(Interner)),
|
||||
&Expectation::HasType(self.result.standard_types.bool_.clone()),
|
||||
);
|
||||
}
|
||||
|
||||
@ -425,7 +423,7 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
|
||||
is_break: false,
|
||||
});
|
||||
};
|
||||
TyKind::Never.intern(Interner)
|
||||
self.result.standard_types.never.clone()
|
||||
}
|
||||
Expr::Break { expr, label } => {
|
||||
let val_ty = if let Some(expr) = *expr {
|
||||
@ -439,7 +437,7 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
|
||||
// avoiding the borrowck
|
||||
let mut coerce = mem::replace(
|
||||
&mut ctxt.coerce,
|
||||
CoerceMany::new(self.result.standard_types.unknown.clone()),
|
||||
CoerceMany::new(expected.coercion_target_type(&mut self.table)),
|
||||
);
|
||||
|
||||
// FIXME: create a synthetic `()` during lowering so we have something to refer to here?
|
||||
@ -457,7 +455,7 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
|
||||
});
|
||||
}
|
||||
}
|
||||
TyKind::Never.intern(Interner)
|
||||
self.result.standard_types.never.clone()
|
||||
}
|
||||
Expr::Return { expr } => {
|
||||
if let Some(expr) = expr {
|
||||
@ -466,7 +464,7 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
|
||||
let unit = TyBuilder::unit();
|
||||
let _ = self.coerce(Some(tgt_expr), &unit, &self.return_ty.clone());
|
||||
}
|
||||
TyKind::Never.intern(Interner)
|
||||
self.result.standard_types.never.clone()
|
||||
}
|
||||
Expr::Yield { expr } => {
|
||||
if let Some((resume_ty, yield_ty)) = self.resume_yield_tys.clone() {
|
||||
@ -479,14 +477,14 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
|
||||
resume_ty
|
||||
} else {
|
||||
// FIXME: report error (yield expr in non-generator)
|
||||
TyKind::Error.intern(Interner)
|
||||
self.result.standard_types.unknown.clone()
|
||||
}
|
||||
}
|
||||
Expr::Yeet { expr } => {
|
||||
if let &Some(expr) = expr {
|
||||
self.infer_expr_inner(expr, &Expectation::None);
|
||||
}
|
||||
TyKind::Never.intern(Interner)
|
||||
self.result.standard_types.never.clone()
|
||||
}
|
||||
Expr::RecordLit { path, fields, spread, .. } => {
|
||||
let (ty, def_id) = self.resolve_variant(path.as_deref(), false);
|
||||
@ -611,8 +609,8 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
|
||||
}
|
||||
Expr::Cast { expr, type_ref } => {
|
||||
let cast_ty = self.make_ty(type_ref);
|
||||
let _inner_ty =
|
||||
self.infer_expr_inner(*expr, &Expectation::Castable(cast_ty.clone()));
|
||||
// FIXME: propagate the "castable to" expectation
|
||||
let _inner_ty = self.infer_expr_inner(*expr, &Expectation::None);
|
||||
// FIXME check the cast...
|
||||
cast_ty
|
||||
}
|
||||
@ -829,7 +827,7 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
|
||||
self.infer_expr_coerce(initializer, &Expectation::has_type(elem_ty));
|
||||
self.infer_expr(
|
||||
repeat,
|
||||
&Expectation::has_type(
|
||||
&Expectation::HasType(
|
||||
TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(Interner),
|
||||
),
|
||||
);
|
||||
@ -852,7 +850,7 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
|
||||
TyKind::Array(coerce.complete(), len).intern(Interner)
|
||||
}
|
||||
Expr::Literal(lit) => match lit {
|
||||
Literal::Bool(..) => TyKind::Scalar(Scalar::Bool).intern(Interner),
|
||||
Literal::Bool(..) => self.result.standard_types.bool_.clone(),
|
||||
Literal::String(..) => {
|
||||
TyKind::Ref(Mutability::Not, static_lifetime(), TyKind::Str.intern(Interner))
|
||||
.intern(Interner)
|
||||
@ -1148,7 +1146,7 @@ fn infer_block(
|
||||
if let Some(expr) = else_branch {
|
||||
self.infer_expr_coerce(
|
||||
*expr,
|
||||
&Expectation::has_type(Ty::new(Interner, TyKind::Never)),
|
||||
&Expectation::HasType(self.result.standard_types.never.clone()),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -112,7 +112,7 @@ fn resolve_value_path(
|
||||
let ty = TyBuilder::value_ty(self.db, typable, parent_substs)
|
||||
.fill(|x| {
|
||||
it.next().unwrap_or_else(|| match x {
|
||||
ParamKind::Type => TyKind::Error.intern(Interner).cast(Interner),
|
||||
ParamKind::Type => self.result.standard_types.unknown.clone().cast(Interner),
|
||||
ParamKind::Const(ty) => consteval::unknown_const_as_generic(ty.clone()),
|
||||
})
|
||||
})
|
||||
|
@ -3200,6 +3200,8 @@ fn func() {
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
||||
// FIXME
|
||||
#[test]
|
||||
fn castable_to() {
|
||||
check_infer(
|
||||
@ -3224,10 +3226,60 @@ fn func() {
|
||||
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..160 'Box::new': fn new<[{unknown}; 0]>([{unknown}; 0]) -> Box<[{unknown}; 0]>
|
||||
152..164 'Box::new([])': Box<[{unknown}; 0]>
|
||||
152..181 'Box::n...2; 0]>': Box<[i32; 0]>
|
||||
161..163 '[]': [i32; 0]
|
||||
161..163 '[]': [{unknown}; 0]
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn castable_to1() {
|
||||
check_infer(
|
||||
r#"
|
||||
struct Ark<T>(T);
|
||||
impl<T> Ark<T> {
|
||||
fn foo(&self) -> *const T {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
fn f<T>(t: Ark<T>) {
|
||||
Ark::foo(&t) as *const ();
|
||||
}
|
||||
"#,
|
||||
expect![[r#"
|
||||
47..51 'self': &Ark<T>
|
||||
65..88 '{ ... }': *const T
|
||||
75..82 '&self.0': &T
|
||||
76..80 'self': &Ark<T>
|
||||
76..82 'self.0': T
|
||||
99..100 't': Ark<T>
|
||||
110..144 '{ ... (); }': ()
|
||||
116..124 'Ark::foo': fn foo<T>(&Ark<T>) -> *const T
|
||||
116..128 'Ark::foo(&t)': *const T
|
||||
116..141 'Ark::f...nst ()': *const ()
|
||||
125..127 '&t': &Ark<T>
|
||||
126..127 't': Ark<T>
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
||||
// FIXME
|
||||
#[test]
|
||||
fn castable_to2() {
|
||||
check_infer(
|
||||
r#"
|
||||
fn func() {
|
||||
let x = &0u32 as *const _;
|
||||
}
|
||||
"#,
|
||||
expect![[r#"
|
||||
10..44 '{ ...t _; }': ()
|
||||
20..21 'x': *const {unknown}
|
||||
24..29 '&0u32': &u32
|
||||
24..41 '&0u32 ...onst _': *const {unknown}
|
||||
25..29 '0u32': u32
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user