Skip to content

Commit e89ad9f

Browse files
committed
Allow ambiguous autoderef with defininte guidance.
This enables autoderefing types with inference variables inside.
1 parent 1489872 commit e89ad9f

File tree

2 files changed

+28
-10
lines changed

2 files changed

+28
-10
lines changed

crates/hir_ty/src/autoderef.rs

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ use log::{info, warn};
1414

1515
use crate::{
1616
db::HirDatabase, static_lifetime, AliasEq, AliasTy, BoundVar, Canonical, CanonicalVarKinds,
17-
DebruijnIndex, Environment, InEnvironment, Interner, ProjectionTyExt, Solution, Substitution,
18-
Ty, TyBuilder, TyKind,
17+
ConstrainedSubst, DebruijnIndex, Environment, Guidance, InEnvironment, Interner,
18+
ProjectionTyExt, Solution, Substitution, Ty, TyBuilder, TyKind,
1919
};
2020

2121
const AUTODEREF_RECURSION_LIMIT: Limit = Limit::new(10);
@@ -187,7 +187,8 @@ fn deref_by_trait(
187187
let solution = db.trait_solve(krate, canonical)?;
188188

189189
match &solution {
190-
Solution::Unique(vars) => {
190+
Solution::Unique(Canonical { value: ConstrainedSubst { subst, .. }, binders })
191+
| Solution::Ambig(Guidance::Definite(Canonical { value: subst, binders })) => {
191192
// FIXME: vars may contain solutions for any inference variables
192193
// that happened to be inside ty. To correctly handle these, we
193194
// would have to pass the solution up to the inference context, but
@@ -203,8 +204,8 @@ fn deref_by_trait(
203204
// assumptions will be broken. We would need to properly introduce
204205
// new variables in that case
205206

206-
for i in 1..vars.binders.len(&Interner) {
207-
if vars.value.subst.at(&Interner, i - 1).assert_ty_ref(&Interner).kind(&Interner)
207+
for i in 1..binders.len(&Interner) {
208+
if subst.at(&Interner, i - 1).assert_ty_ref(&Interner).kind(&Interner)
208209
!= &TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, i - 1))
209210
{
210211
warn!("complex solution for derefing {:?}: {:?}, ignoring", ty.goal, solution);
@@ -214,13 +215,11 @@ fn deref_by_trait(
214215
// FIXME: we remove lifetime variables here since they can confuse
215216
// the method resolution code later
216217
Some(fixup_lifetime_variables(Canonical {
217-
value: vars
218-
.value
219-
.subst
220-
.at(&Interner, vars.value.subst.len(&Interner) - 1)
218+
value: subst
219+
.at(&Interner, subst.len(&Interner) - 1)
221220
.assert_ty_ref(&Interner)
222221
.clone(),
223-
binders: vars.binders.clone(),
222+
binders: binders.clone(),
224223
}))
225224
}
226225
Solution::Ambig(_) => {

crates/hir_ty/src/tests/traits.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -648,6 +648,25 @@ fn test(s: Arc<S>) {
648648
);
649649
}
650650

651+
#[test]
652+
fn deref_trait_with_implicit_sized_requirement_on_inference_var() {
653+
check_types(
654+
r#"
655+
//- minicore: deref
656+
struct Foo<T>;
657+
impl<T> core::ops::Deref for Foo<T> {
658+
type Target = ();
659+
}
660+
fn test() {
661+
let foo = Foo;
662+
*foo;
663+
//^^^^ ()
664+
let _: Foo<u8> = foo;
665+
}
666+
"#,
667+
)
668+
}
669+
651670
#[test]
652671
fn obligation_from_function_clause() {
653672
check_types(

0 commit comments

Comments
 (0)