mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-29 13:25:09 +00:00
Handle where clauses in trait solving
This commit is contained in:
parent
940c538ecf
commit
50bbf9eb09
6 changed files with 188 additions and 29 deletions
|
@ -11,7 +11,7 @@ use crate::{
|
||||||
DefWithBody, Trait,
|
DefWithBody, Trait,
|
||||||
ids,
|
ids,
|
||||||
nameres::{Namespace, ImportSourceMap, RawItems, CrateDefMap},
|
nameres::{Namespace, ImportSourceMap, RawItems, CrateDefMap},
|
||||||
ty::{InferenceResult, Ty, method_resolution::CrateImplBlocks, TypableDef, CallableDef, FnSig, TypeCtor},
|
ty::{InferenceResult, Ty, method_resolution::CrateImplBlocks, TypableDef, CallableDef, FnSig, TypeCtor, GenericPredicate},
|
||||||
adt::{StructData, EnumData},
|
adt::{StructData, EnumData},
|
||||||
impl_block::{ModuleImplBlocks, ImplSourceMap, ImplBlock},
|
impl_block::{ModuleImplBlocks, ImplSourceMap, ImplBlock},
|
||||||
generics::{GenericParams, GenericDef},
|
generics::{GenericParams, GenericDef},
|
||||||
|
@ -138,6 +138,9 @@ pub trait HirDatabase: DefDatabase {
|
||||||
#[salsa::invoke(crate::ty::callable_item_sig)]
|
#[salsa::invoke(crate::ty::callable_item_sig)]
|
||||||
fn callable_item_signature(&self, def: CallableDef) -> FnSig;
|
fn callable_item_signature(&self, def: CallableDef) -> FnSig;
|
||||||
|
|
||||||
|
#[salsa::invoke(crate::ty::generic_predicates)]
|
||||||
|
fn generic_predicates(&self, def: GenericDef) -> Arc<[GenericPredicate]>;
|
||||||
|
|
||||||
#[salsa::invoke(crate::expr::body_with_source_map_query)]
|
#[salsa::invoke(crate::expr::body_with_source_map_query)]
|
||||||
fn body_with_source_map(
|
fn body_with_source_map(
|
||||||
&self,
|
&self,
|
||||||
|
|
|
@ -8,7 +8,7 @@ use std::sync::Arc;
|
||||||
use ra_syntax::ast::{self, NameOwner, TypeParamsOwner, TypeBoundsOwner};
|
use ra_syntax::ast::{self, NameOwner, TypeParamsOwner, TypeBoundsOwner};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
db::DefDatabase,
|
db::{ HirDatabase, DefDatabase},
|
||||||
Name, AsName, Function, Struct, Enum, Trait, TypeAlias, ImplBlock, Container, path::Path, type_ref::TypeRef, AdtDef
|
Name, AsName, Function, Struct, Enum, Trait, TypeAlias, ImplBlock, Container, path::Path, type_ref::TypeRef, AdtDef
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -32,8 +32,8 @@ pub struct GenericParams {
|
||||||
/// where clauses like `where T: Foo + Bar` are turned into multiple of these.
|
/// where clauses like `where T: Foo + Bar` are turned into multiple of these.
|
||||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||||
pub struct WherePredicate {
|
pub struct WherePredicate {
|
||||||
type_ref: TypeRef,
|
pub(crate) type_ref: TypeRef,
|
||||||
trait_ref: Path,
|
pub(crate) trait_ref: Path,
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: consts can have type parameters from their parents (i.e. associated consts of traits)
|
// FIXME: consts can have type parameters from their parents (i.e. associated consts of traits)
|
||||||
|
@ -148,6 +148,19 @@ impl GenericParams {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl GenericDef {
|
||||||
|
pub(crate) fn resolver(&self, db: &impl HirDatabase) -> crate::Resolver {
|
||||||
|
match self {
|
||||||
|
GenericDef::Function(inner) => inner.resolver(db),
|
||||||
|
GenericDef::Struct(inner) => inner.resolver(db),
|
||||||
|
GenericDef::Enum(inner) => inner.resolver(db),
|
||||||
|
GenericDef::Trait(inner) => inner.resolver(db),
|
||||||
|
GenericDef::TypeAlias(inner) => inner.resolver(db),
|
||||||
|
GenericDef::ImplBlock(inner) => inner.resolver(db),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<Container> for GenericDef {
|
impl From<Container> for GenericDef {
|
||||||
fn from(c: Container) -> Self {
|
fn from(c: Container) -> Self {
|
||||||
match c {
|
match c {
|
||||||
|
|
|
@ -19,7 +19,7 @@ use std::{fmt, mem};
|
||||||
use crate::{Name, AdtDef, type_ref::Mutability, db::HirDatabase, Trait, GenericParams};
|
use crate::{Name, AdtDef, type_ref::Mutability, db::HirDatabase, Trait, GenericParams};
|
||||||
use display::{HirDisplay, HirFormatter};
|
use display::{HirDisplay, HirFormatter};
|
||||||
|
|
||||||
pub(crate) use lower::{TypableDef, type_for_def, type_for_field, callable_item_sig};
|
pub(crate) use lower::{TypableDef, type_for_def, type_for_field, callable_item_sig, generic_predicates};
|
||||||
pub(crate) use infer::{infer, InferenceResult, InferTy};
|
pub(crate) use infer::{infer, InferenceResult, InferTy};
|
||||||
pub use lower::CallableDef;
|
pub use lower::CallableDef;
|
||||||
|
|
||||||
|
@ -234,6 +234,35 @@ impl TraitRef {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Like `generics::WherePredicate`, but with resolved types: A condition on the
|
||||||
|
/// parameters of a generic item.
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
|
pub enum GenericPredicate {
|
||||||
|
/// The given trait needs to be implemented for its type parameters.
|
||||||
|
Implemented(TraitRef),
|
||||||
|
/// We couldn't resolve the trait reference. (If some type parameters can't
|
||||||
|
/// be resolved, they will just be Unknown).
|
||||||
|
Error,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GenericPredicate {
|
||||||
|
pub fn is_error(&self) -> bool {
|
||||||
|
match self {
|
||||||
|
GenericPredicate::Error => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn subst(self, substs: &Substs) -> GenericPredicate {
|
||||||
|
match self {
|
||||||
|
GenericPredicate::Implemented(trait_ref) => {
|
||||||
|
GenericPredicate::Implemented(trait_ref.subst(substs))
|
||||||
|
}
|
||||||
|
GenericPredicate::Error => self,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Basically a claim (currently not validated / checked) that the contained
|
/// Basically a claim (currently not validated / checked) that the contained
|
||||||
/// type / trait ref contains no inference variables; any inference variables it
|
/// type / trait ref contains no inference variables; any inference variables it
|
||||||
/// contained have been replaced by bound variables, and `num_vars` tells us how
|
/// contained have been replaced by bound variables, and `num_vars` tells us how
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
//! - Building the type for an item: This happens through the `type_for_def` query.
|
//! - Building the type for an item: This happens through the `type_for_def` query.
|
||||||
//!
|
//!
|
||||||
//! This usually involves resolving names, collecting generic arguments etc.
|
//! This usually involves resolving names, collecting generic arguments etc.
|
||||||
|
use std::sync::Arc;
|
||||||
use std::iter;
|
use std::iter;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -18,9 +19,9 @@ use crate::{
|
||||||
resolve::{Resolver, Resolution},
|
resolve::{Resolver, Resolution},
|
||||||
path::{PathSegment, GenericArg},
|
path::{PathSegment, GenericArg},
|
||||||
generics::{GenericParams, HasGenericParams},
|
generics::{GenericParams, HasGenericParams},
|
||||||
adt::VariantDef, Trait
|
adt::VariantDef, Trait, generics::{ WherePredicate, GenericDef}
|
||||||
};
|
};
|
||||||
use super::{Ty, primitive, FnSig, Substs, TypeCtor, TraitRef};
|
use super::{Ty, primitive, FnSig, Substs, TypeCtor, TraitRef, GenericPredicate};
|
||||||
|
|
||||||
impl Ty {
|
impl Ty {
|
||||||
pub(crate) fn from_hir(db: &impl HirDatabase, resolver: &Resolver, type_ref: &TypeRef) -> Self {
|
pub(crate) fn from_hir(db: &impl HirDatabase, resolver: &Resolver, type_ref: &TypeRef) -> Self {
|
||||||
|
@ -208,16 +209,12 @@ pub(super) fn substs_from_path_segment(
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TraitRef {
|
impl TraitRef {
|
||||||
pub(crate) fn from_hir(
|
pub(crate) fn from_path(
|
||||||
db: &impl HirDatabase,
|
db: &impl HirDatabase,
|
||||||
resolver: &Resolver,
|
resolver: &Resolver,
|
||||||
type_ref: &TypeRef,
|
path: &Path,
|
||||||
explicit_self_ty: Option<Ty>,
|
explicit_self_ty: Option<Ty>,
|
||||||
) -> Option<Self> {
|
) -> Option<Self> {
|
||||||
let path = match type_ref {
|
|
||||||
TypeRef::Path(path) => path,
|
|
||||||
_ => return None,
|
|
||||||
};
|
|
||||||
let resolved = match resolver.resolve_path(db, &path).take_types()? {
|
let resolved = match resolver.resolve_path(db, &path).take_types()? {
|
||||||
Resolution::Def(ModuleDef::Trait(tr)) => tr,
|
Resolution::Def(ModuleDef::Trait(tr)) => tr,
|
||||||
_ => return None,
|
_ => return None,
|
||||||
|
@ -232,6 +229,19 @@ impl TraitRef {
|
||||||
Some(TraitRef { trait_: resolved, substs })
|
Some(TraitRef { trait_: resolved, substs })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn from_hir(
|
||||||
|
db: &impl HirDatabase,
|
||||||
|
resolver: &Resolver,
|
||||||
|
type_ref: &TypeRef,
|
||||||
|
explicit_self_ty: Option<Ty>,
|
||||||
|
) -> Option<Self> {
|
||||||
|
let path = match type_ref {
|
||||||
|
TypeRef::Path(path) => path,
|
||||||
|
_ => return None,
|
||||||
|
};
|
||||||
|
TraitRef::from_path(db, resolver, path, explicit_self_ty)
|
||||||
|
}
|
||||||
|
|
||||||
fn substs_from_path(
|
fn substs_from_path(
|
||||||
db: &impl HirDatabase,
|
db: &impl HirDatabase,
|
||||||
resolver: &Resolver,
|
resolver: &Resolver,
|
||||||
|
@ -246,6 +256,15 @@ impl TraitRef {
|
||||||
let substs = Substs::identity(&trait_.generic_params(db));
|
let substs = Substs::identity(&trait_.generic_params(db));
|
||||||
TraitRef { trait_, substs }
|
TraitRef { trait_, substs }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn for_where_predicate(
|
||||||
|
db: &impl HirDatabase,
|
||||||
|
resolver: &Resolver,
|
||||||
|
pred: &WherePredicate,
|
||||||
|
) -> Option<TraitRef> {
|
||||||
|
let self_ty = Ty::from_hir(db, resolver, &pred.type_ref);
|
||||||
|
TraitRef::from_path(db, resolver, &pred.trait_ref, Some(self_ty))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Build the declared type of an item. This depends on the namespace; e.g. for
|
/// Build the declared type of an item. This depends on the namespace; e.g. for
|
||||||
|
@ -294,6 +313,24 @@ pub(crate) fn type_for_field(db: &impl HirDatabase, field: StructField) -> Ty {
|
||||||
Ty::from_hir(db, &resolver, type_ref)
|
Ty::from_hir(db, &resolver, type_ref)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Resolve the where clause(s) of an item with generics.
|
||||||
|
pub(crate) fn generic_predicates(
|
||||||
|
db: &impl HirDatabase,
|
||||||
|
def: GenericDef,
|
||||||
|
) -> Arc<[GenericPredicate]> {
|
||||||
|
let resolver = def.resolver(db);
|
||||||
|
let generic_params = def.generic_params(db);
|
||||||
|
let predicates = generic_params
|
||||||
|
.where_predicates
|
||||||
|
.iter()
|
||||||
|
.map(|pred| {
|
||||||
|
TraitRef::for_where_predicate(db, &resolver, pred)
|
||||||
|
.map_or(GenericPredicate::Error, GenericPredicate::Implemented)
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
predicates.into()
|
||||||
|
}
|
||||||
|
|
||||||
fn fn_sig_for_fn(db: &impl HirDatabase, def: Function) -> FnSig {
|
fn fn_sig_for_fn(db: &impl HirDatabase, def: Function) -> FnSig {
|
||||||
let signature = def.signature(db);
|
let signature = def.signature(db);
|
||||||
let resolver = def.resolver(db);
|
let resolver = def.resolver(db);
|
||||||
|
|
|
@ -2510,12 +2510,47 @@ fn method_resolution_where_clause_not_met() {
|
||||||
trait Clone {}
|
trait Clone {}
|
||||||
trait Trait { fn foo(self) -> u128; }
|
trait Trait { fn foo(self) -> u128; }
|
||||||
struct S;
|
struct S;
|
||||||
impl S { fn foo(self) -> i8 { 0 } }
|
impl<T> Trait for T where T: Clone {}
|
||||||
impl<T> Trait for T where T: Clone { fn foo(self) -> u128 { 0 } }
|
|
||||||
fn test() { (&S).foo()<|>; }
|
fn test() { (&S).foo()<|>; }
|
||||||
"#,
|
"#,
|
||||||
);
|
);
|
||||||
assert_eq!(t, "i8");
|
// This is also to make sure that we don't resolve to the foo method just
|
||||||
|
// because that's the only method named foo we can find, which would make
|
||||||
|
// the below tests not work
|
||||||
|
assert_eq!(t, "{unknown}");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn method_resolution_where_clause_1() {
|
||||||
|
let t = type_at(
|
||||||
|
r#"
|
||||||
|
//- /main.rs
|
||||||
|
trait Clone {}
|
||||||
|
trait Trait { fn foo(self) -> u128; }
|
||||||
|
struct S;
|
||||||
|
impl Clone for S {};
|
||||||
|
impl<T> Trait for T where T: Clone {}
|
||||||
|
fn test() { S.foo()<|>; }
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
assert_eq!(t, "u128");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn method_resolution_where_clause_2() {
|
||||||
|
let t = type_at(
|
||||||
|
r#"
|
||||||
|
//- /main.rs
|
||||||
|
trait Into<T> { fn into(self) -> T; }
|
||||||
|
trait From<T> { fn from(other: T) -> Self; }
|
||||||
|
struct S1;
|
||||||
|
struct S2;
|
||||||
|
impl From<S2> for S1 {};
|
||||||
|
impl<T, U> Into<U> for T where U: From<T> {}
|
||||||
|
fn test() { S2.into()<|>; }
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
assert_eq!(t, "S1");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn type_at_pos(db: &MockDatabase, pos: FilePosition) -> String {
|
fn type_at_pos(db: &MockDatabase, pos: FilePosition) -> String {
|
||||||
|
|
|
@ -11,7 +11,7 @@ use ra_db::salsa::{InternId, InternKey};
|
||||||
use crate::{
|
use crate::{
|
||||||
Trait, HasGenericParams, ImplBlock,
|
Trait, HasGenericParams, ImplBlock,
|
||||||
db::HirDatabase,
|
db::HirDatabase,
|
||||||
ty::{TraitRef, Ty, ApplicationTy, TypeCtor, Substs},
|
ty::{TraitRef, Ty, ApplicationTy, TypeCtor, Substs, GenericPredicate}, generics::GenericDef,
|
||||||
};
|
};
|
||||||
use super::ChalkContext;
|
use super::ChalkContext;
|
||||||
|
|
||||||
|
@ -146,6 +146,27 @@ impl ToChalk for ImplBlock {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ToChalk for GenericPredicate {
|
||||||
|
type Chalk = chalk_ir::QuantifiedWhereClause;
|
||||||
|
|
||||||
|
fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::QuantifiedWhereClause {
|
||||||
|
match self {
|
||||||
|
GenericPredicate::Implemented(trait_ref) => {
|
||||||
|
make_binders(chalk_ir::WhereClause::Implemented(trait_ref.to_chalk(db)), 0)
|
||||||
|
}
|
||||||
|
GenericPredicate::Error => panic!("Trying to pass errored where clause to Chalk"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn from_chalk(
|
||||||
|
_db: &impl HirDatabase,
|
||||||
|
_where_clause: chalk_ir::QuantifiedWhereClause,
|
||||||
|
) -> GenericPredicate {
|
||||||
|
// This should never need to be called
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn make_binders<T>(value: T, num_vars: usize) -> chalk_ir::Binders<T> {
|
fn make_binders<T>(value: T, num_vars: usize) -> chalk_ir::Binders<T> {
|
||||||
chalk_ir::Binders {
|
chalk_ir::Binders {
|
||||||
value,
|
value,
|
||||||
|
@ -153,6 +174,25 @@ fn make_binders<T>(value: T, num_vars: usize) -> chalk_ir::Binders<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn convert_where_clauses(
|
||||||
|
db: &impl HirDatabase,
|
||||||
|
def: GenericDef,
|
||||||
|
substs: &Substs,
|
||||||
|
) -> (Vec<chalk_ir::QuantifiedWhereClause>, bool) {
|
||||||
|
let generic_predicates = db.generic_predicates(def);
|
||||||
|
let mut result = Vec::with_capacity(generic_predicates.len());
|
||||||
|
let mut has_error = false;
|
||||||
|
for pred in generic_predicates.iter() {
|
||||||
|
// FIXME: it would probably be nicer if we could just convert errored predicates to a where clause that is never true...
|
||||||
|
if pred.is_error() {
|
||||||
|
has_error = true;
|
||||||
|
} else {
|
||||||
|
result.push(pred.clone().subst(substs).to_chalk(db));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(result, has_error)
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a, DB> chalk_solve::RustIrDatabase for ChalkContext<'a, DB>
|
impl<'a, DB> chalk_solve::RustIrDatabase for ChalkContext<'a, DB>
|
||||||
where
|
where
|
||||||
DB: HirDatabase,
|
DB: HirDatabase,
|
||||||
|
@ -173,7 +213,7 @@ where
|
||||||
upstream: trait_.module(self.db).krate(self.db) != Some(self.krate),
|
upstream: trait_.module(self.db).krate(self.db) != Some(self.krate),
|
||||||
fundamental: false,
|
fundamental: false,
|
||||||
};
|
};
|
||||||
let where_clauses = Vec::new(); // FIXME add where clauses
|
let (where_clauses, _) = convert_where_clauses(self.db, trait_.into(), &bound_vars);
|
||||||
let associated_ty_ids = Vec::new(); // FIXME add associated tys
|
let associated_ty_ids = Vec::new(); // FIXME add associated tys
|
||||||
let trait_datum_bound =
|
let trait_datum_bound =
|
||||||
chalk_rust_ir::TraitDatumBound { trait_ref, where_clauses, flags, associated_ty_ids };
|
chalk_rust_ir::TraitDatumBound { trait_ref, where_clauses, flags, associated_ty_ids };
|
||||||
|
@ -185,21 +225,26 @@ where
|
||||||
let type_ctor = from_chalk(self.db, struct_id);
|
let type_ctor = from_chalk(self.db, struct_id);
|
||||||
// FIXME might be nicer if we can create a fake GenericParams for the TypeCtor
|
// FIXME might be nicer if we can create a fake GenericParams for the TypeCtor
|
||||||
// FIXME extract this to a method on Ty
|
// FIXME extract this to a method on Ty
|
||||||
let (num_params, upstream) = match type_ctor {
|
let (num_params, where_clauses, upstream) = match type_ctor {
|
||||||
TypeCtor::Bool
|
TypeCtor::Bool
|
||||||
| TypeCtor::Char
|
| TypeCtor::Char
|
||||||
| TypeCtor::Int(_)
|
| TypeCtor::Int(_)
|
||||||
| TypeCtor::Float(_)
|
| TypeCtor::Float(_)
|
||||||
| TypeCtor::Never
|
| TypeCtor::Never
|
||||||
| TypeCtor::Str => (0, true),
|
| TypeCtor::Str => (0, vec![], true),
|
||||||
TypeCtor::Slice | TypeCtor::Array | TypeCtor::RawPtr(_) | TypeCtor::Ref(_) => (1, true),
|
TypeCtor::Slice | TypeCtor::Array | TypeCtor::RawPtr(_) | TypeCtor::Ref(_) => {
|
||||||
TypeCtor::FnPtr { num_args } => (num_args as usize + 1, true),
|
(1, vec![], true)
|
||||||
TypeCtor::Tuple { cardinality } => (cardinality as usize, true),
|
}
|
||||||
|
TypeCtor::FnPtr { num_args } => (num_args as usize + 1, vec![], true),
|
||||||
|
TypeCtor::Tuple { cardinality } => (cardinality as usize, vec![], true),
|
||||||
TypeCtor::FnDef(_) => unimplemented!(),
|
TypeCtor::FnDef(_) => unimplemented!(),
|
||||||
TypeCtor::Adt(adt) => {
|
TypeCtor::Adt(adt) => {
|
||||||
let generic_params = adt.generic_params(self.db);
|
let generic_params = adt.generic_params(self.db);
|
||||||
|
let bound_vars = Substs::bound_vars(&generic_params);
|
||||||
|
let (where_clauses, _) = convert_where_clauses(self.db, adt.into(), &bound_vars);
|
||||||
(
|
(
|
||||||
generic_params.count_params_including_parent(),
|
generic_params.count_params_including_parent(),
|
||||||
|
where_clauses,
|
||||||
adt.krate(self.db) != Some(self.krate),
|
adt.krate(self.db) != Some(self.krate),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -209,7 +254,6 @@ where
|
||||||
// FIXME set fundamental flag correctly
|
// FIXME set fundamental flag correctly
|
||||||
fundamental: false,
|
fundamental: false,
|
||||||
};
|
};
|
||||||
let where_clauses = Vec::new(); // FIXME add where clauses
|
|
||||||
let self_ty = chalk_ir::ApplicationTy {
|
let self_ty = chalk_ir::ApplicationTy {
|
||||||
name: TypeName::TypeKindId(type_ctor.to_chalk(self.db).into()),
|
name: TypeName::TypeKindId(type_ctor.to_chalk(self.db).into()),
|
||||||
parameters: (0..num_params).map(|i| chalk_ir::Ty::BoundVar(i).cast()).collect(),
|
parameters: (0..num_params).map(|i| chalk_ir::Ty::BoundVar(i).cast()).collect(),
|
||||||
|
@ -237,10 +281,12 @@ where
|
||||||
} else {
|
} else {
|
||||||
chalk_rust_ir::ImplType::External
|
chalk_rust_ir::ImplType::External
|
||||||
};
|
};
|
||||||
|
let (where_clauses, where_clause_error) =
|
||||||
|
convert_where_clauses(self.db, impl_block.into(), &bound_vars);
|
||||||
let impl_datum_bound = chalk_rust_ir::ImplDatumBound {
|
let impl_datum_bound = chalk_rust_ir::ImplDatumBound {
|
||||||
// FIXME handle negative impls (impl !Sync for Foo)
|
// FIXME handle negative impls (impl !Sync for Foo)
|
||||||
trait_ref: chalk_rust_ir::PolarizedTraitRef::Positive(trait_ref.to_chalk(self.db)),
|
trait_ref: chalk_rust_ir::PolarizedTraitRef::Positive(trait_ref.to_chalk(self.db)),
|
||||||
where_clauses: Vec::new(), // FIXME add where clauses
|
where_clauses,
|
||||||
associated_ty_values: Vec::new(), // FIXME add associated type values
|
associated_ty_values: Vec::new(), // FIXME add associated type values
|
||||||
impl_type,
|
impl_type,
|
||||||
};
|
};
|
||||||
|
@ -253,10 +299,6 @@ where
|
||||||
self.db
|
self.db
|
||||||
.impls_for_trait(self.krate, trait_)
|
.impls_for_trait(self.krate, trait_)
|
||||||
.iter()
|
.iter()
|
||||||
// FIXME temporary hack -- as long as we're not lowering where clauses
|
|
||||||
// correctly, ignore impls with them completely so as to not treat
|
|
||||||
// impl<T> Trait for T where T: ... as a blanket impl on all types
|
|
||||||
.filter(|impl_block| impl_block.generic_params(self.db).where_predicates.is_empty())
|
|
||||||
.map(|impl_block| impl_block.to_chalk(self.db))
|
.map(|impl_block| impl_block.to_chalk(self.db))
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue