Auto merge of #14120 - Veykril:castable, r=Veykril
internal: Revert castable expectation and simplify Unfixes https://github.com/rust-lang/rust-analyzer/issues/11571, the PR for that introduced some regressions (tried fixing them but doing what rustc does there specifically does not help, probably because something else affects it as well there)
This commit is contained in:
commit
d9c020d426
@ -219,6 +219,7 @@ struct InternedStandardTypes {
|
|||||||
unknown: Ty,
|
unknown: Ty,
|
||||||
bool_: Ty,
|
bool_: Ty,
|
||||||
unit: Ty,
|
unit: Ty,
|
||||||
|
never: Ty,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for InternedStandardTypes {
|
impl Default for InternedStandardTypes {
|
||||||
@ -227,6 +228,7 @@ impl Default for InternedStandardTypes {
|
|||||||
unknown: TyKind::Error.intern(Interner),
|
unknown: TyKind::Error.intern(Interner),
|
||||||
bool_: TyKind::Scalar(Scalar::Bool).intern(Interner),
|
bool_: TyKind::Scalar(Scalar::Bool).intern(Interner),
|
||||||
unit: TyKind::Tuple(0, Substitution::empty(Interner)).intern(Interner),
|
unit: TyKind::Tuple(0, Substitution::empty(Interner)).intern(Interner),
|
||||||
|
never: TyKind::Never.intern(Interner),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1024,6 +1026,7 @@ impl<'a> InferenceContext<'a> {
|
|||||||
pub(crate) enum Expectation {
|
pub(crate) enum Expectation {
|
||||||
None,
|
None,
|
||||||
HasType(Ty),
|
HasType(Ty),
|
||||||
|
#[allow(dead_code)]
|
||||||
Castable(Ty),
|
Castable(Ty),
|
||||||
RValueLikeUnsized(Ty),
|
RValueLikeUnsized(Ty),
|
||||||
}
|
}
|
||||||
@ -1102,6 +1105,10 @@ impl Expectation {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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:
|
/// Comment copied from rustc:
|
||||||
/// Disregard "castable to" expectations because they
|
/// Disregard "castable to" expectations because they
|
||||||
/// can lead us astray. Consider for example `if cond
|
/// can lead us astray. Consider for example `if cond
|
||||||
|
@ -51,7 +51,7 @@ impl InferenceContext<'_> {
|
|||||||
.map(to_chalk_trait_id)
|
.map(to_chalk_trait_id)
|
||||||
.collect();
|
.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)]);
|
let bounds = dyn_ty.bounds.clone().substitute(Interner, &[self_ty.cast(Interner)]);
|
||||||
for bound in bounds.iter(Interner) {
|
for bound in bounds.iter(Interner) {
|
||||||
// NOTE(skip_binders): the extracted types are rebound by the returned `FnPointer`
|
// NOTE(skip_binders): the extracted types are rebound by the returned `FnPointer`
|
||||||
@ -67,7 +67,7 @@ impl InferenceContext<'_> {
|
|||||||
let arg = projection.substitution.as_slice(Interner).get(1)?;
|
let arg = projection.substitution.as_slice(Interner).get(1)?;
|
||||||
if let Some(subst) = arg.ty(Interner)?.as_tuple() {
|
if let Some(subst) = arg.ty(Interner)?.as_tuple() {
|
||||||
let generic_args = subst.as_slice(Interner);
|
let generic_args = subst.as_slice(Interner);
|
||||||
let mut sig_tys = Vec::new();
|
let mut sig_tys = Vec::with_capacity(generic_args.len() + 1);
|
||||||
for arg in generic_args {
|
for arg in generic_args {
|
||||||
sig_tys.push(arg.ty(Interner)?.clone());
|
sig_tys.push(arg.ty(Interner)?.clone());
|
||||||
}
|
}
|
||||||
|
@ -87,16 +87,15 @@ impl<'a> InferenceContext<'a> {
|
|||||||
let expected = &expected.adjust_for_branches(&mut self.table);
|
let expected = &expected.adjust_for_branches(&mut self.table);
|
||||||
self.infer_expr(
|
self.infer_expr(
|
||||||
condition,
|
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 condition_diverges = mem::replace(&mut self.diverges, Diverges::Maybe);
|
||||||
let mut both_arms_diverge = Diverges::Always;
|
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);
|
let then_ty = self.infer_expr_inner(then_branch, expected);
|
||||||
both_arms_diverge &= mem::replace(&mut self.diverges, Diverges::Maybe);
|
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);
|
coerce.coerce(self, Some(then_branch), &then_ty);
|
||||||
let else_ty = match else_branch {
|
let else_ty = match else_branch {
|
||||||
Some(else_branch) => self.infer_expr_inner(else_branch, expected),
|
Some(else_branch) => self.infer_expr_inner(else_branch, expected),
|
||||||
@ -113,7 +112,7 @@ impl<'a> InferenceContext<'a> {
|
|||||||
&Expr::Let { pat, expr } => {
|
&Expr::Let { pat, expr } => {
|
||||||
let input_ty = self.infer_expr(expr, &Expectation::none());
|
let input_ty = self.infer_expr(expr, &Expectation::none());
|
||||||
self.infer_pat(pat, &input_ty, BindingMode::default());
|
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: _ } => {
|
Expr::Block { statements, tail, label, id: _ } => {
|
||||||
let old_resolver = mem::replace(
|
let old_resolver = mem::replace(
|
||||||
@ -188,10 +187,12 @@ impl<'a> InferenceContext<'a> {
|
|||||||
.intern(Interner)
|
.intern(Interner)
|
||||||
}
|
}
|
||||||
&Expr::Loop { body, label } => {
|
&Expr::Loop { body, label } => {
|
||||||
|
// FIXME: should be:
|
||||||
|
// let ty = expected.coercion_target_type(&mut self.table);
|
||||||
let ty = self.table.new_type_var();
|
let ty = self.table.new_type_var();
|
||||||
let (breaks, ()) =
|
let (breaks, ()) =
|
||||||
self.with_breakable_ctx(BreakableKind::Loop, ty, label, |this| {
|
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 {
|
match breaks {
|
||||||
@ -199,16 +200,16 @@ impl<'a> InferenceContext<'a> {
|
|||||||
self.diverges = Diverges::Maybe;
|
self.diverges = Diverges::Maybe;
|
||||||
breaks
|
breaks
|
||||||
}
|
}
|
||||||
None => TyKind::Never.intern(Interner),
|
None => self.result.standard_types.never.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&Expr::While { condition, body, label } => {
|
&Expr::While { condition, body, label } => {
|
||||||
self.with_breakable_ctx(BreakableKind::Loop, self.err_ty(), label, |this| {
|
self.with_breakable_ctx(BreakableKind::Loop, self.err_ty(), label, |this| {
|
||||||
this.infer_expr(
|
this.infer_expr(
|
||||||
condition,
|
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
|
// the body may not run, so it diverging doesn't mean we diverge
|
||||||
@ -224,7 +225,7 @@ impl<'a> InferenceContext<'a> {
|
|||||||
|
|
||||||
self.infer_pat(pat, &pat_ty, BindingMode::default());
|
self.infer_pat(pat, &pat_ty, BindingMode::default());
|
||||||
self.with_breakable_ctx(BreakableKind::Loop, self.err_ty(), label, |this| {
|
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
|
// the body may not run, so it diverging doesn't mean we diverge
|
||||||
@ -234,7 +235,7 @@ impl<'a> InferenceContext<'a> {
|
|||||||
Expr::Closure { body, args, ret_type, arg_types, closure_kind } => {
|
Expr::Closure { body, args, ret_type, arg_types, closure_kind } => {
|
||||||
assert_eq!(args.len(), arg_types.len());
|
assert_eq!(args.len(), arg_types.len());
|
||||||
|
|
||||||
let mut sig_tys = Vec::new();
|
let mut sig_tys = Vec::with_capacity(arg_types.len() + 1);
|
||||||
|
|
||||||
// collect explicitly written argument types
|
// collect explicitly written argument types
|
||||||
for arg_type in arg_types.iter() {
|
for arg_type in arg_types.iter() {
|
||||||
@ -255,7 +256,8 @@ impl<'a> InferenceContext<'a> {
|
|||||||
num_binders: 0,
|
num_binders: 0,
|
||||||
sig: FnSig { abi: (), safety: chalk_ir::Safety::Safe, variadic: false },
|
sig: FnSig { abi: (), safety: chalk_ir::Safety::Safe, variadic: false },
|
||||||
substitution: FnSubst(
|
substitution: FnSubst(
|
||||||
Substitution::from_iter(Interner, sig_tys.clone()).shifted_in(Interner),
|
Substitution::from_iter(Interner, sig_tys.iter().cloned())
|
||||||
|
.shifted_in(Interner),
|
||||||
),
|
),
|
||||||
})
|
})
|
||||||
.intern(Interner);
|
.intern(Interner);
|
||||||
@ -317,16 +319,16 @@ impl<'a> InferenceContext<'a> {
|
|||||||
Expr::Call { callee, args, .. } => {
|
Expr::Call { callee, args, .. } => {
|
||||||
let callee_ty = self.infer_expr(*callee, &Expectation::none());
|
let callee_ty = self.infer_expr(*callee, &Expectation::none());
|
||||||
let mut derefs = Autoderef::new(&mut self.table, callee_ty.clone());
|
let mut derefs = Autoderef::new(&mut self.table, callee_ty.clone());
|
||||||
let mut res = None;
|
let (res, derefed_callee) = 'b: {
|
||||||
let mut derefed_callee = callee_ty.clone();
|
// manual loop to be able to access `derefs.table`
|
||||||
// manual loop to be able to access `derefs.table`
|
while let Some((callee_deref_ty, _)) = derefs.next() {
|
||||||
while let Some((callee_deref_ty, _)) = derefs.next() {
|
let res = derefs.table.callable_sig(&callee_deref_ty, args.len());
|
||||||
res = derefs.table.callable_sig(&callee_deref_ty, args.len());
|
if res.is_some() {
|
||||||
if res.is_some() {
|
break 'b (res, callee_deref_ty);
|
||||||
derefed_callee = callee_deref_ty;
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
(None, callee_ty.clone())
|
||||||
|
};
|
||||||
// if the function is unresolved, we use is_varargs=true to
|
// if the function is unresolved, we use is_varargs=true to
|
||||||
// suppress the arg count diagnostic here
|
// suppress the arg count diagnostic here
|
||||||
let is_varargs =
|
let is_varargs =
|
||||||
@ -382,12 +384,9 @@ impl<'a> InferenceContext<'a> {
|
|||||||
let expected = expected.adjust_for_branches(&mut self.table);
|
let expected = expected.adjust_for_branches(&mut self.table);
|
||||||
|
|
||||||
let result_ty = if arms.is_empty() {
|
let result_ty = if arms.is_empty() {
|
||||||
TyKind::Never.intern(Interner)
|
self.result.standard_types.never.clone()
|
||||||
} else {
|
} else {
|
||||||
match &expected {
|
expected.coercion_target_type(&mut self.table)
|
||||||
Expectation::HasType(ty) => ty.clone(),
|
|
||||||
_ => self.table.new_type_var(),
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
let mut coerce = CoerceMany::new(result_ty);
|
let mut coerce = CoerceMany::new(result_ty);
|
||||||
|
|
||||||
@ -400,7 +399,7 @@ impl<'a> InferenceContext<'a> {
|
|||||||
if let Some(guard_expr) = arm.guard {
|
if let Some(guard_expr) = arm.guard {
|
||||||
self.infer_expr(
|
self.infer_expr(
|
||||||
guard_expr,
|
guard_expr,
|
||||||
&Expectation::has_type(TyKind::Scalar(Scalar::Bool).intern(Interner)),
|
&Expectation::HasType(self.result.standard_types.bool_.clone()),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -425,7 +424,7 @@ impl<'a> InferenceContext<'a> {
|
|||||||
is_break: false,
|
is_break: false,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
TyKind::Never.intern(Interner)
|
self.result.standard_types.never.clone()
|
||||||
}
|
}
|
||||||
Expr::Break { expr, label } => {
|
Expr::Break { expr, label } => {
|
||||||
let val_ty = if let Some(expr) = *expr {
|
let val_ty = if let Some(expr) = *expr {
|
||||||
@ -439,7 +438,7 @@ impl<'a> InferenceContext<'a> {
|
|||||||
// avoiding the borrowck
|
// avoiding the borrowck
|
||||||
let mut coerce = mem::replace(
|
let mut coerce = mem::replace(
|
||||||
&mut ctxt.coerce,
|
&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?
|
// FIXME: create a synthetic `()` during lowering so we have something to refer to here?
|
||||||
@ -457,7 +456,7 @@ impl<'a> InferenceContext<'a> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TyKind::Never.intern(Interner)
|
self.result.standard_types.never.clone()
|
||||||
}
|
}
|
||||||
Expr::Return { expr } => {
|
Expr::Return { expr } => {
|
||||||
if let Some(expr) = expr {
|
if let Some(expr) = expr {
|
||||||
@ -466,7 +465,7 @@ impl<'a> InferenceContext<'a> {
|
|||||||
let unit = TyBuilder::unit();
|
let unit = TyBuilder::unit();
|
||||||
let _ = self.coerce(Some(tgt_expr), &unit, &self.return_ty.clone());
|
let _ = self.coerce(Some(tgt_expr), &unit, &self.return_ty.clone());
|
||||||
}
|
}
|
||||||
TyKind::Never.intern(Interner)
|
self.result.standard_types.never.clone()
|
||||||
}
|
}
|
||||||
Expr::Yield { expr } => {
|
Expr::Yield { expr } => {
|
||||||
if let Some((resume_ty, yield_ty)) = self.resume_yield_tys.clone() {
|
if let Some((resume_ty, yield_ty)) = self.resume_yield_tys.clone() {
|
||||||
@ -479,14 +478,14 @@ impl<'a> InferenceContext<'a> {
|
|||||||
resume_ty
|
resume_ty
|
||||||
} else {
|
} else {
|
||||||
// FIXME: report error (yield expr in non-generator)
|
// FIXME: report error (yield expr in non-generator)
|
||||||
TyKind::Error.intern(Interner)
|
self.result.standard_types.unknown.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Expr::Yeet { expr } => {
|
Expr::Yeet { expr } => {
|
||||||
if let &Some(expr) = expr {
|
if let &Some(expr) = expr {
|
||||||
self.infer_expr_inner(expr, &Expectation::None);
|
self.infer_expr_inner(expr, &Expectation::None);
|
||||||
}
|
}
|
||||||
TyKind::Never.intern(Interner)
|
self.result.standard_types.never.clone()
|
||||||
}
|
}
|
||||||
Expr::RecordLit { path, fields, spread, .. } => {
|
Expr::RecordLit { path, fields, spread, .. } => {
|
||||||
let (ty, def_id) = self.resolve_variant(path.as_deref(), false);
|
let (ty, def_id) = self.resolve_variant(path.as_deref(), false);
|
||||||
@ -611,8 +610,8 @@ impl<'a> InferenceContext<'a> {
|
|||||||
}
|
}
|
||||||
Expr::Cast { expr, type_ref } => {
|
Expr::Cast { expr, type_ref } => {
|
||||||
let cast_ty = self.make_ty(type_ref);
|
let cast_ty = self.make_ty(type_ref);
|
||||||
let _inner_ty =
|
// FIXME: propagate the "castable to" expectation
|
||||||
self.infer_expr_inner(*expr, &Expectation::Castable(cast_ty.clone()));
|
let _inner_ty = self.infer_expr_inner(*expr, &Expectation::None);
|
||||||
// FIXME check the cast...
|
// FIXME check the cast...
|
||||||
cast_ty
|
cast_ty
|
||||||
}
|
}
|
||||||
@ -829,7 +828,7 @@ impl<'a> InferenceContext<'a> {
|
|||||||
self.infer_expr_coerce(initializer, &Expectation::has_type(elem_ty));
|
self.infer_expr_coerce(initializer, &Expectation::has_type(elem_ty));
|
||||||
self.infer_expr(
|
self.infer_expr(
|
||||||
repeat,
|
repeat,
|
||||||
&Expectation::has_type(
|
&Expectation::HasType(
|
||||||
TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(Interner),
|
TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(Interner),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@ -852,7 +851,7 @@ impl<'a> InferenceContext<'a> {
|
|||||||
TyKind::Array(coerce.complete(), len).intern(Interner)
|
TyKind::Array(coerce.complete(), len).intern(Interner)
|
||||||
}
|
}
|
||||||
Expr::Literal(lit) => match lit {
|
Expr::Literal(lit) => match lit {
|
||||||
Literal::Bool(..) => TyKind::Scalar(Scalar::Bool).intern(Interner),
|
Literal::Bool(..) => self.result.standard_types.bool_.clone(),
|
||||||
Literal::String(..) => {
|
Literal::String(..) => {
|
||||||
TyKind::Ref(Mutability::Not, static_lifetime(), TyKind::Str.intern(Interner))
|
TyKind::Ref(Mutability::Not, static_lifetime(), TyKind::Str.intern(Interner))
|
||||||
.intern(Interner)
|
.intern(Interner)
|
||||||
@ -1148,7 +1147,7 @@ impl<'a> InferenceContext<'a> {
|
|||||||
if let Some(expr) = else_branch {
|
if let Some(expr) = else_branch {
|
||||||
self.infer_expr_coerce(
|
self.infer_expr_coerce(
|
||||||
*expr,
|
*expr,
|
||||||
&Expectation::has_type(Ty::new(Interner, TyKind::Never)),
|
&Expectation::HasType(self.result.standard_types.never.clone()),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,7 +112,7 @@ impl<'a> InferenceContext<'a> {
|
|||||||
let ty = TyBuilder::value_ty(self.db, typable, parent_substs)
|
let ty = TyBuilder::value_ty(self.db, typable, parent_substs)
|
||||||
.fill(|x| {
|
.fill(|x| {
|
||||||
it.next().unwrap_or_else(|| match 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()),
|
ParamKind::Const(ty) => consteval::unknown_const_as_generic(ty.clone()),
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -3200,6 +3200,8 @@ fn func() {
|
|||||||
"#,
|
"#,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME
|
||||||
#[test]
|
#[test]
|
||||||
fn castable_to() {
|
fn castable_to() {
|
||||||
check_infer(
|
check_infer(
|
||||||
@ -3224,10 +3226,60 @@ fn func() {
|
|||||||
120..122 '{}': ()
|
120..122 '{}': ()
|
||||||
138..184 '{ ...0]>; }': ()
|
138..184 '{ ...0]>; }': ()
|
||||||
148..149 'x': Box<[i32; 0]>
|
148..149 'x': Box<[i32; 0]>
|
||||||
152..160 'Box::new': fn new<[i32; 0]>([i32; 0]) -> Box<[i32; 0]>
|
152..160 'Box::new': fn new<[{unknown}; 0]>([{unknown}; 0]) -> Box<[{unknown}; 0]>
|
||||||
152..164 'Box::new([])': Box<[i32; 0]>
|
152..164 'Box::new([])': Box<[{unknown}; 0]>
|
||||||
152..181 'Box::n...2; 0]>': Box<[i32; 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…
x
Reference in New Issue
Block a user