mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-28 12:54:58 +00:00
Allow ambiguous autoderef with defininte guidance.
This enables autoderefing types with inference variables inside.
This commit is contained in:
parent
14898729f4
commit
e89ad9f345
2 changed files with 28 additions and 10 deletions
|
@ -14,8 +14,8 @@ use log::{info, warn};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
db::HirDatabase, static_lifetime, AliasEq, AliasTy, BoundVar, Canonical, CanonicalVarKinds,
|
db::HirDatabase, static_lifetime, AliasEq, AliasTy, BoundVar, Canonical, CanonicalVarKinds,
|
||||||
DebruijnIndex, Environment, InEnvironment, Interner, ProjectionTyExt, Solution, Substitution,
|
ConstrainedSubst, DebruijnIndex, Environment, Guidance, InEnvironment, Interner,
|
||||||
Ty, TyBuilder, TyKind,
|
ProjectionTyExt, Solution, Substitution, Ty, TyBuilder, TyKind,
|
||||||
};
|
};
|
||||||
|
|
||||||
const AUTODEREF_RECURSION_LIMIT: Limit = Limit::new(10);
|
const AUTODEREF_RECURSION_LIMIT: Limit = Limit::new(10);
|
||||||
|
@ -187,7 +187,8 @@ fn deref_by_trait(
|
||||||
let solution = db.trait_solve(krate, canonical)?;
|
let solution = db.trait_solve(krate, canonical)?;
|
||||||
|
|
||||||
match &solution {
|
match &solution {
|
||||||
Solution::Unique(vars) => {
|
Solution::Unique(Canonical { value: ConstrainedSubst { subst, .. }, binders })
|
||||||
|
| Solution::Ambig(Guidance::Definite(Canonical { value: subst, binders })) => {
|
||||||
// FIXME: vars may contain solutions for any inference variables
|
// FIXME: vars may contain solutions for any inference variables
|
||||||
// that happened to be inside ty. To correctly handle these, we
|
// that happened to be inside ty. To correctly handle these, we
|
||||||
// would have to pass the solution up to the inference context, but
|
// would have to pass the solution up to the inference context, but
|
||||||
|
@ -203,8 +204,8 @@ fn deref_by_trait(
|
||||||
// assumptions will be broken. We would need to properly introduce
|
// assumptions will be broken. We would need to properly introduce
|
||||||
// new variables in that case
|
// new variables in that case
|
||||||
|
|
||||||
for i in 1..vars.binders.len(&Interner) {
|
for i in 1..binders.len(&Interner) {
|
||||||
if vars.value.subst.at(&Interner, i - 1).assert_ty_ref(&Interner).kind(&Interner)
|
if subst.at(&Interner, i - 1).assert_ty_ref(&Interner).kind(&Interner)
|
||||||
!= &TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, i - 1))
|
!= &TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, i - 1))
|
||||||
{
|
{
|
||||||
warn!("complex solution for derefing {:?}: {:?}, ignoring", ty.goal, solution);
|
warn!("complex solution for derefing {:?}: {:?}, ignoring", ty.goal, solution);
|
||||||
|
@ -214,13 +215,11 @@ fn deref_by_trait(
|
||||||
// FIXME: we remove lifetime variables here since they can confuse
|
// FIXME: we remove lifetime variables here since they can confuse
|
||||||
// the method resolution code later
|
// the method resolution code later
|
||||||
Some(fixup_lifetime_variables(Canonical {
|
Some(fixup_lifetime_variables(Canonical {
|
||||||
value: vars
|
value: subst
|
||||||
.value
|
.at(&Interner, subst.len(&Interner) - 1)
|
||||||
.subst
|
|
||||||
.at(&Interner, vars.value.subst.len(&Interner) - 1)
|
|
||||||
.assert_ty_ref(&Interner)
|
.assert_ty_ref(&Interner)
|
||||||
.clone(),
|
.clone(),
|
||||||
binders: vars.binders.clone(),
|
binders: binders.clone(),
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
Solution::Ambig(_) => {
|
Solution::Ambig(_) => {
|
||||||
|
|
|
@ -648,6 +648,25 @@ fn test(s: Arc<S>) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn deref_trait_with_implicit_sized_requirement_on_inference_var() {
|
||||||
|
check_types(
|
||||||
|
r#"
|
||||||
|
//- minicore: deref
|
||||||
|
struct Foo<T>;
|
||||||
|
impl<T> core::ops::Deref for Foo<T> {
|
||||||
|
type Target = ();
|
||||||
|
}
|
||||||
|
fn test() {
|
||||||
|
let foo = Foo;
|
||||||
|
*foo;
|
||||||
|
//^^^^ ()
|
||||||
|
let _: Foo<u8> = foo;
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn obligation_from_function_clause() {
|
fn obligation_from_function_clause() {
|
||||||
check_types(
|
check_types(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue