mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-01 14:21:44 +00:00
More TyBuilder use
This commit is contained in:
parent
cd227f581e
commit
66fec39aa0
1 changed files with 15 additions and 23 deletions
|
@ -13,11 +13,9 @@ use log::{info, warn};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
db::HirDatabase,
|
db::HirDatabase,
|
||||||
to_assoc_type_id, to_chalk_trait_id,
|
|
||||||
traits::{InEnvironment, Solution},
|
traits::{InEnvironment, Solution},
|
||||||
utils::generics,
|
AliasEq, AliasTy, BoundVar, Canonical, CanonicalVarKinds, DebruijnIndex, Interner, Ty,
|
||||||
AliasEq, AliasTy, BoundVar, Canonical, CanonicalVarKinds, DebruijnIndex, Interner,
|
TyBuilder, TyKind,
|
||||||
ProjectionTy, Substitution, TraitRef, Ty, TyKind,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const AUTODEREF_RECURSION_LIMIT: usize = 10;
|
const AUTODEREF_RECURSION_LIMIT: usize = 10;
|
||||||
|
@ -57,21 +55,20 @@ fn deref_by_trait(
|
||||||
};
|
};
|
||||||
let target = db.trait_data(deref_trait).associated_type_by_name(&name![Target])?;
|
let target = db.trait_data(deref_trait).associated_type_by_name(&name![Target])?;
|
||||||
|
|
||||||
let generic_params = generics(db.upcast(), target.into());
|
let projection = {
|
||||||
if generic_params.len() != 1 {
|
let b = TyBuilder::assoc_type_projection(db, target);
|
||||||
// the Target type + Deref trait should only have one generic parameter,
|
if b.remaining() != 1 {
|
||||||
// namely Deref's Self type
|
// the Target type + Deref trait should only have one generic parameter,
|
||||||
return None;
|
// namely Deref's Self type
|
||||||
}
|
return None;
|
||||||
|
}
|
||||||
|
b.push(ty.goal.value.clone()).build()
|
||||||
|
};
|
||||||
|
|
||||||
// FIXME make the Canonical / bound var handling nicer
|
// FIXME make the Canonical / bound var handling nicer
|
||||||
|
|
||||||
let parameters =
|
|
||||||
Substitution::build_for_generics(&generic_params).push(ty.goal.value.clone()).build();
|
|
||||||
|
|
||||||
// Check that the type implements Deref at all
|
// Check that the type implements Deref at all
|
||||||
let trait_ref =
|
let trait_ref = projection.trait_ref(db);
|
||||||
TraitRef { trait_id: to_chalk_trait_id(deref_trait), substitution: parameters.clone() };
|
|
||||||
let implements_goal = Canonical {
|
let implements_goal = Canonical {
|
||||||
binders: ty.goal.binders.clone(),
|
binders: ty.goal.binders.clone(),
|
||||||
value: InEnvironment {
|
value: InEnvironment {
|
||||||
|
@ -84,11 +81,8 @@ fn deref_by_trait(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now do the assoc type projection
|
// Now do the assoc type projection
|
||||||
let projection = AliasEq {
|
let alias_eq = AliasEq {
|
||||||
alias: AliasTy::Projection(ProjectionTy {
|
alias: AliasTy::Projection(projection),
|
||||||
associated_ty_id: to_assoc_type_id(target),
|
|
||||||
substitution: parameters,
|
|
||||||
}),
|
|
||||||
ty: TyKind::BoundVar(BoundVar::new(
|
ty: TyKind::BoundVar(BoundVar::new(
|
||||||
DebruijnIndex::INNERMOST,
|
DebruijnIndex::INNERMOST,
|
||||||
ty.goal.binders.len(&Interner),
|
ty.goal.binders.len(&Interner),
|
||||||
|
@ -96,9 +90,7 @@ fn deref_by_trait(
|
||||||
.intern(&Interner),
|
.intern(&Interner),
|
||||||
};
|
};
|
||||||
|
|
||||||
let obligation = projection.cast(&Interner);
|
let in_env = InEnvironment { goal: alias_eq.cast(&Interner), environment: ty.environment };
|
||||||
|
|
||||||
let in_env = InEnvironment { goal: obligation, environment: ty.environment };
|
|
||||||
|
|
||||||
let canonical = Canonical {
|
let canonical = Canonical {
|
||||||
value: in_env,
|
value: in_env,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue