mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-25 19:39:50 +00:00
Add method resolution deref inference var test
This commit is contained in:
parent
d21f88883b
commit
c679482d7e
3 changed files with 30 additions and 16 deletions
|
@ -312,15 +312,13 @@ impl InferenceContext<'_> {
|
||||||
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(), false);
|
let mut derefs = Autoderef::new(&mut self.table, callee_ty.clone(), false);
|
||||||
let (res, derefed_callee) = 'b: {
|
let (res, derefed_callee) = loop {
|
||||||
// manual loop to be able to access `derefs.table`
|
let Some((callee_deref_ty, _)) = derefs.next() else {
|
||||||
while let Some((callee_deref_ty, _)) = derefs.next() {
|
break (None, callee_ty.clone());
|
||||||
let res = derefs.table.callable_sig(&callee_deref_ty, args.len());
|
};
|
||||||
if res.is_some() {
|
if let Some(res) = derefs.table.callable_sig(&callee_deref_ty, args.len()) {
|
||||||
break 'b (res, callee_deref_ty);
|
break (Some(res), callee_deref_ty);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
(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
|
||||||
|
|
|
@ -289,14 +289,14 @@ impl<'a> InferenceTable<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fallback_value(&self, iv: InferenceVar, kind: TyVariableKind) -> Ty {
|
fn fallback_value(&self, iv: InferenceVar, kind: TyVariableKind) -> Ty {
|
||||||
match kind {
|
let is_diverging = self
|
||||||
_ if self
|
|
||||||
.type_variable_table
|
.type_variable_table
|
||||||
.get(iv.index() as usize)
|
.get(iv.index() as usize)
|
||||||
.map_or(false, |data| data.contains(TypeVariableFlags::DIVERGING)) =>
|
.map_or(false, |data| data.contains(TypeVariableFlags::DIVERGING));
|
||||||
{
|
if is_diverging {
|
||||||
TyKind::Never
|
return TyKind::Never.intern(Interner);
|
||||||
}
|
}
|
||||||
|
match kind {
|
||||||
TyVariableKind::General => TyKind::Error,
|
TyVariableKind::General => TyKind::Error,
|
||||||
TyVariableKind::Integer => TyKind::Scalar(Scalar::Int(IntTy::I32)),
|
TyVariableKind::Integer => TyKind::Scalar(Scalar::Int(IntTy::I32)),
|
||||||
TyVariableKind::Float => TyKind::Scalar(Scalar::Float(FloatTy::F64)),
|
TyVariableKind::Float => TyKind::Scalar(Scalar::Float(FloatTy::F64)),
|
||||||
|
@ -438,6 +438,7 @@ impl<'a> InferenceTable<'a> {
|
||||||
where
|
where
|
||||||
T: HasInterner<Interner = Interner> + TypeFoldable<Interner>,
|
T: HasInterner<Interner = Interner> + TypeFoldable<Interner>,
|
||||||
{
|
{
|
||||||
|
// TODO check this vec here
|
||||||
self.resolve_with_fallback_inner(&mut Vec::new(), t, &fallback)
|
self.resolve_with_fallback_inner(&mut Vec::new(), t, &fallback)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -798,7 +799,7 @@ impl<'a> InferenceTable<'a> {
|
||||||
let trait_data = self.db.trait_data(fn_once_trait);
|
let trait_data = self.db.trait_data(fn_once_trait);
|
||||||
let output_assoc_type = trait_data.associated_type_by_name(&name![Output])?;
|
let output_assoc_type = trait_data.associated_type_by_name(&name![Output])?;
|
||||||
|
|
||||||
let mut arg_tys = vec![];
|
let mut arg_tys = Vec::with_capacity(num_args);
|
||||||
let arg_ty = TyBuilder::tuple(num_args)
|
let arg_ty = TyBuilder::tuple(num_args)
|
||||||
.fill(|it| {
|
.fill(|it| {
|
||||||
let arg = match it {
|
let arg = match it {
|
||||||
|
|
|
@ -1795,6 +1795,21 @@ fn test() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn deref_into_inference_var() {
|
||||||
|
check_types(
|
||||||
|
r#"
|
||||||
|
//- minicore:deref
|
||||||
|
struct A<T>(T);
|
||||||
|
impl core::ops::Deref for A<u32> {}
|
||||||
|
impl A<i32> { fn foo(&self) {} }
|
||||||
|
fn main() {
|
||||||
|
A(0).foo();
|
||||||
|
//^^^^^^^^^^ ()
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn receiver_adjustment_autoref() {
|
fn receiver_adjustment_autoref() {
|
||||||
check(
|
check(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue