mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-26 13:54:06 +00:00
Use environment for associated type normalization as well
This commit is contained in:
parent
b1b12072ed
commit
15862fc041
@ -224,7 +224,7 @@ pub trait HirDatabase: DefDatabase + AstDatabase {
|
||||
fn normalize(
|
||||
&self,
|
||||
krate: Crate,
|
||||
goal: crate::ty::Canonical<crate::ty::ProjectionPredicate>,
|
||||
goal: crate::ty::Canonical<crate::ty::InEnvironment<crate::ty::ProjectionPredicate>>,
|
||||
) -> Option<crate::ty::traits::Solution>;
|
||||
}
|
||||
|
||||
|
@ -52,6 +52,8 @@ fn deref_by_trait(
|
||||
|
||||
// FIXME make the Canonical handling nicer
|
||||
|
||||
let env = super::lower::trait_env(db, resolver);
|
||||
|
||||
let projection = super::traits::ProjectionPredicate {
|
||||
ty: Ty::Bound(0),
|
||||
projection_ty: super::ProjectionTy {
|
||||
@ -60,7 +62,9 @@ fn deref_by_trait(
|
||||
},
|
||||
};
|
||||
|
||||
let canonical = super::Canonical { num_vars: 1 + ty.num_vars, value: projection };
|
||||
let in_env = super::traits::InEnvironment { value: projection, environment: env };
|
||||
|
||||
let canonical = super::Canonical { num_vars: 1 + ty.num_vars, value: in_env };
|
||||
|
||||
let solution = db.normalize(krate, canonical)?;
|
||||
|
||||
|
@ -356,7 +356,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
|
||||
};
|
||||
}
|
||||
Obligation::Projection(pr) => {
|
||||
let canonicalized = self.canonicalizer().canonicalize_projection(pr.clone());
|
||||
let in_env = InEnvironment::new(self.trait_env.clone(), pr.clone());
|
||||
let canonicalized = self.canonicalizer().canonicalize_projection(in_env);
|
||||
let solution = self
|
||||
.db
|
||||
.normalize(self.resolver.krate().unwrap(), canonicalized.value.clone());
|
||||
|
@ -129,10 +129,14 @@ where
|
||||
|
||||
pub fn canonicalize_projection(
|
||||
mut self,
|
||||
projection: ProjectionPredicate,
|
||||
) -> Canonicalized<ProjectionPredicate> {
|
||||
let result = self.do_canonicalize_projection_predicate(projection);
|
||||
self.into_canonicalized(result)
|
||||
projection: InEnvironment<ProjectionPredicate>,
|
||||
) -> Canonicalized<InEnvironment<ProjectionPredicate>> {
|
||||
let result = self.do_canonicalize_projection_predicate(projection.value);
|
||||
// FIXME canonicalize env
|
||||
self.into_canonicalized(InEnvironment {
|
||||
value: result,
|
||||
environment: projection.environment,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3010,6 +3010,25 @@ fn test<T>(t: T) { t.foo()<|>; }
|
||||
assert_eq!(t, "{unknown}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn generic_param_env_deref() {
|
||||
let t = type_at(
|
||||
r#"
|
||||
//- /main.rs
|
||||
#[lang = "deref"]
|
||||
trait Deref {
|
||||
type Target;
|
||||
}
|
||||
trait Trait {}
|
||||
impl<T> Deref for T where T: Trait {
|
||||
type Target = i128;
|
||||
}
|
||||
fn test<T: Trait>(t: T) { (*t)<|>; }
|
||||
"#,
|
||||
);
|
||||
assert_eq!(t, "i128");
|
||||
}
|
||||
|
||||
fn type_at_pos(db: &MockDatabase, pos: FilePosition) -> String {
|
||||
let file = db.parse(pos.file_id).ok().unwrap();
|
||||
let expr = algo::find_node_at_offset::<ast::Expr>(file.syntax(), pos.offset).unwrap();
|
||||
|
@ -134,20 +134,9 @@ pub(crate) fn implements_query(
|
||||
pub(crate) fn normalize_query(
|
||||
db: &impl HirDatabase,
|
||||
krate: Crate,
|
||||
projection: Canonical<ProjectionPredicate>,
|
||||
projection: Canonical<InEnvironment<ProjectionPredicate>>,
|
||||
) -> Option<Solution> {
|
||||
let goal: chalk_ir::Goal = chalk_ir::Normalize {
|
||||
projection: projection.value.projection_ty.to_chalk(db),
|
||||
ty: projection.value.ty.to_chalk(db),
|
||||
}
|
||||
.cast();
|
||||
debug!("goal: {:?}", goal);
|
||||
// FIXME unify with `implements`
|
||||
let env = chalk_ir::Environment::new();
|
||||
let in_env = chalk_ir::InEnvironment::new(&env, goal);
|
||||
let parameter = chalk_ir::ParameterKind::Ty(chalk_ir::UniverseIndex::ROOT);
|
||||
let canonical =
|
||||
chalk_ir::Canonical { value: in_env, binders: vec![parameter; projection.num_vars] };
|
||||
let canonical = projection.to_chalk(db).cast();
|
||||
// We currently don't deal with universes (I think / hope they're not yet
|
||||
// relevant for our use cases?)
|
||||
let u_canonical = chalk_ir::UCanonical { canonical, universes: 1 };
|
||||
|
@ -218,6 +218,21 @@ impl ToChalk for ProjectionTy {
|
||||
}
|
||||
}
|
||||
|
||||
impl ToChalk for super::ProjectionPredicate {
|
||||
type Chalk = chalk_ir::Normalize;
|
||||
|
||||
fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::Normalize {
|
||||
chalk_ir::Normalize {
|
||||
projection: self.projection_ty.to_chalk(db),
|
||||
ty: self.ty.to_chalk(db),
|
||||
}
|
||||
}
|
||||
|
||||
fn from_chalk(_db: &impl HirDatabase, _normalize: chalk_ir::Normalize) -> Self {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> ToChalk for Canonical<T>
|
||||
where
|
||||
T: ToChalk,
|
||||
|
Loading…
Reference in New Issue
Block a user