2608: Support for nested traits r=matklad a=matklad



Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
bors[bot] 2019-12-20 11:43:19 +00:00 committed by GitHub
commit 6537762024
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 131 additions and 73 deletions

View file

@ -269,7 +269,7 @@ pub struct Struct {
impl Struct {
pub fn module(self, db: &impl DefDatabase) -> Module {
Module { id: self.id.lookup(db).container }
Module { id: self.id.lookup(db).container.module(db) }
}
pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> {
@ -290,7 +290,7 @@ impl Struct {
}
pub fn ty(self, db: &impl HirDatabase) -> Type {
Type::from_def(db, self.id.lookup(db).container.krate, self.id)
Type::from_def(db, self.id.lookup(db).container.module(db).krate, self.id)
}
fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> {
@ -309,11 +309,11 @@ impl Union {
}
pub fn module(self, db: &impl DefDatabase) -> Module {
Module { id: self.id.lookup(db).container }
Module { id: self.id.lookup(db).container.module(db) }
}
pub fn ty(self, db: &impl HirDatabase) -> Type {
Type::from_def(db, self.id.lookup(db).container.krate, self.id)
Type::from_def(db, self.id.lookup(db).container.module(db).krate, self.id)
}
pub fn fields(self, db: &impl HirDatabase) -> Vec<StructField> {
@ -337,7 +337,7 @@ pub struct Enum {
impl Enum {
pub fn module(self, db: &impl DefDatabase) -> Module {
Module { id: self.id.lookup(db).container }
Module { id: self.id.lookup(db).container.module(db) }
}
pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> {
@ -357,7 +357,7 @@ impl Enum {
}
pub fn ty(self, db: &impl HirDatabase) -> Type {
Type::from_def(db, self.id.lookup(db).container.krate, self.id)
Type::from_def(db, self.id.lookup(db).container.module(db).krate, self.id)
}
}
@ -553,7 +553,7 @@ pub struct Trait {
impl Trait {
pub fn module(self, db: &impl DefDatabase) -> Module {
Module { id: self.id.lookup(db).container }
Module { id: self.id.lookup(db).container.module(db) }
}
pub fn name(self, db: &impl DefDatabase) -> Name {

View file

@ -25,7 +25,8 @@ use crate::{
path::GenericArgs,
path::Path,
type_ref::{Mutability, TypeRef},
ContainerId, DefWithBodyId, FunctionLoc, Intern,
ConstLoc, ContainerId, DefWithBodyId, EnumLoc, FunctionLoc, Intern, ModuleDefId, StaticLoc,
StructLoc, TraitLoc, TypeAliasLoc, UnionLoc,
};
pub(super) fn lower(
@ -492,14 +493,45 @@ where
fn collect_block_items(&mut self, block: &ast::Block) {
let container = ContainerId::DefWithBodyId(self.def);
for item in block.items() {
match item {
let def: ModuleDefId = match item {
ast::ModuleItem::FnDef(def) => {
let ast_id = self.expander.ast_id(&def);
self.body.defs.push(FunctionLoc { container, ast_id }.intern(self.db).into())
FunctionLoc { container: container.into(), ast_id }.intern(self.db).into()
}
// FIXME: handle other items
_ => (),
}
ast::ModuleItem::TypeAliasDef(def) => {
let ast_id = self.expander.ast_id(&def);
TypeAliasLoc { container: container.into(), ast_id }.intern(self.db).into()
}
ast::ModuleItem::ConstDef(def) => {
let ast_id = self.expander.ast_id(&def);
ConstLoc { container: container.into(), ast_id }.intern(self.db).into()
}
ast::ModuleItem::StaticDef(def) => {
let ast_id = self.expander.ast_id(&def);
StaticLoc { container, ast_id }.intern(self.db).into()
}
ast::ModuleItem::StructDef(def) => {
let ast_id = self.expander.ast_id(&def);
StructLoc { container, ast_id }.intern(self.db).into()
}
ast::ModuleItem::EnumDef(def) => {
let ast_id = self.expander.ast_id(&def);
EnumLoc { container, ast_id }.intern(self.db).into()
}
ast::ModuleItem::UnionDef(def) => {
let ast_id = self.expander.ast_id(&def);
UnionLoc { container, ast_id }.intern(self.db).into()
}
ast::ModuleItem::TraitDef(def) => {
let ast_id = self.expander.ast_id(&def);
TraitLoc { container, ast_id }.intern(self.db).into()
}
ast::ModuleItem::ImplBlock(_)
| ast::ModuleItem::UseItem(_)
| ast::ModuleItem::ExternCrateItem(_)
| ast::ModuleItem::Module(_) => continue,
};
self.body.defs.push(def)
}
}

View file

@ -12,8 +12,8 @@ use crate::{
db::DefDatabase,
src::HasSource,
type_ref::{Mutability, TypeRef},
AssocItemId, ConstId, ConstLoc, ContainerId, FunctionId, FunctionLoc, ImplId, Intern, Lookup,
StaticId, TraitId, TypeAliasId, TypeAliasLoc,
AssocContainerId, AssocItemId, ConstId, ConstLoc, FunctionId, FunctionLoc, ImplId, Intern,
Lookup, StaticId, TraitId, TypeAliasId, TypeAliasLoc,
};
#[derive(Debug, Clone, PartialEq, Eq)]
@ -99,7 +99,7 @@ impl TraitData {
let auto = src.value.is_auto();
let ast_id_map = db.ast_id_map(src.file_id);
let container = ContainerId::TraitId(tr);
let container = AssocContainerId::TraitId(tr);
let items = if let Some(item_list) = src.value.item_list() {
item_list
.impl_items()
@ -180,7 +180,7 @@ impl ImplData {
.map(|item_node| match item_node {
ast::ImplItem::FnDef(it) => {
let def = FunctionLoc {
container: ContainerId::ImplId(id),
container: AssocContainerId::ImplId(id),
ast_id: AstId::new(src.file_id, items.ast_id(&it)),
}
.intern(db);
@ -188,7 +188,7 @@ impl ImplData {
}
ast::ImplItem::ConstDef(it) => {
let def = ConstLoc {
container: ContainerId::ImplId(id),
container: AssocContainerId::ImplId(id),
ast_id: AstId::new(src.file_id, items.ast_id(&it)),
}
.intern(db);
@ -196,7 +196,7 @@ impl ImplData {
}
ast::ImplItem::TypeAliasDef(it) => {
let def = TypeAliasLoc {
container: ContainerId::ImplId(id),
container: AssocContainerId::ImplId(id),
ast_id: AstId::new(src.file_id, items.ast_id(&it)),
}
.intern(db);

View file

@ -71,7 +71,7 @@ impl_intern_key!(FunctionId);
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct FunctionLoc {
pub container: ContainerId,
pub container: AssocContainerId,
pub ast_id: AstId<ast::FnDef>,
}
@ -95,7 +95,7 @@ impl_intern_key!(StructId);
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct StructLoc {
pub container: ModuleId,
pub container: ContainerId,
pub ast_id: AstId<ast::StructDef>,
}
@ -119,7 +119,7 @@ impl_intern_key!(UnionId);
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct UnionLoc {
pub container: ModuleId,
pub container: ContainerId,
pub ast_id: AstId<ast::UnionDef>,
}
@ -143,7 +143,7 @@ impl_intern_key!(EnumId);
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct EnumLoc {
pub container: ModuleId,
pub container: ContainerId,
pub ast_id: AstId<ast::EnumDef>,
}
@ -187,7 +187,7 @@ pub struct ConstId(salsa::InternId);
impl_intern_key!(ConstId);
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct ConstLoc {
pub container: ContainerId,
pub container: AssocContainerId,
pub ast_id: AstId<ast::ConstDef>,
}
@ -211,7 +211,7 @@ impl_intern_key!(StaticId);
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct StaticLoc {
pub container: ModuleId,
pub container: ContainerId,
pub ast_id: AstId<ast::StaticDef>,
}
@ -235,7 +235,7 @@ impl_intern_key!(TraitId);
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct TraitLoc {
pub container: ModuleId,
pub container: ContainerId,
pub ast_id: AstId<ast::TraitDef>,
}
@ -259,7 +259,7 @@ impl_intern_key!(TypeAliasId);
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct TypeAliasLoc {
pub container: ContainerId,
pub container: AssocContainerId,
pub ast_id: AstId<ast::TypeAliasDef>,
}
@ -333,11 +333,17 @@ impl_arena_id!(LocalTypeParamId);
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum ContainerId {
ModuleId(ModuleId),
ImplId(ImplId),
TraitId(TraitId),
DefWithBodyId(DefWithBodyId),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum AssocContainerId {
ContainerId(ContainerId),
ImplId(ImplId),
TraitId(TraitId),
}
impl_froms!(AssocContainerId: ContainerId);
/// A Data Type
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum AdtId {
@ -483,13 +489,21 @@ impl HasModule for ContainerId {
fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
match *self {
ContainerId::ModuleId(it) => it,
ContainerId::ImplId(it) => it.lookup(db).container,
ContainerId::TraitId(it) => it.lookup(db).container,
ContainerId::DefWithBodyId(it) => it.module(db),
}
}
}
impl HasModule for AssocContainerId {
fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
match *self {
AssocContainerId::ContainerId(it) => it.module(db),
AssocContainerId::ImplId(it) => it.lookup(db).container,
AssocContainerId::TraitId(it) => it.lookup(db).container.module(db),
}
}
}
impl HasModule for FunctionLoc {
fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
self.container.module(db)
@ -515,6 +529,7 @@ impl HasModule for AdtId {
AdtId::UnionId(it) => it.lookup(db).container,
AdtId::EnumId(it) => it.lookup(db).container,
}
.module(db)
}
}
@ -533,17 +548,17 @@ impl HasModule for GenericDefId {
match self {
GenericDefId::FunctionId(it) => it.lookup(db).module(db),
GenericDefId::AdtId(it) => it.module(db),
GenericDefId::TraitId(it) => it.lookup(db).container,
GenericDefId::TraitId(it) => it.lookup(db).container.module(db),
GenericDefId::TypeAliasId(it) => it.lookup(db).module(db),
GenericDefId::ImplId(it) => it.lookup(db).container,
GenericDefId::EnumVariantId(it) => it.parent.lookup(db).container,
GenericDefId::EnumVariantId(it) => it.parent.lookup(db).container.module(db),
GenericDefId::ConstId(it) => it.lookup(db).module(db),
}
}
}
impl HasModule for StaticLoc {
fn module(&self, _db: &impl db::DefDatabase) -> ModuleId {
self.container
fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
self.container.module(db)
}
}

View file

@ -760,10 +760,11 @@ where
self.collect_derives(attrs, def);
let name = def.name.clone();
let container = ContainerId::ModuleId(module);
let def: PerNs = match def.kind {
raw::DefKind::Function(ast_id) => {
let def = FunctionLoc {
container: ContainerId::ModuleId(module),
container: container.into(),
ast_id: AstId::new(self.file_id, ast_id),
}
.intern(self.def_collector.db);
@ -771,23 +772,23 @@ where
PerNs::values(def.into())
}
raw::DefKind::Struct(ast_id) => {
let def = StructLoc { container: module, ast_id: AstId::new(self.file_id, ast_id) }
let def = StructLoc { container, ast_id: AstId::new(self.file_id, ast_id) }
.intern(self.def_collector.db);
PerNs::both(def.into(), def.into())
}
raw::DefKind::Union(ast_id) => {
let def = UnionLoc { container: module, ast_id: AstId::new(self.file_id, ast_id) }
let def = UnionLoc { container, ast_id: AstId::new(self.file_id, ast_id) }
.intern(self.def_collector.db);
PerNs::both(def.into(), def.into())
}
raw::DefKind::Enum(ast_id) => {
let def = EnumLoc { container: module, ast_id: AstId::new(self.file_id, ast_id) }
let def = EnumLoc { container, ast_id: AstId::new(self.file_id, ast_id) }
.intern(self.def_collector.db);
PerNs::types(def.into())
}
raw::DefKind::Const(ast_id) => {
let def = ConstLoc {
container: ContainerId::ModuleId(module),
container: container.into(),
ast_id: AstId::new(self.file_id, ast_id),
}
.intern(self.def_collector.db);
@ -795,20 +796,20 @@ where
PerNs::values(def.into())
}
raw::DefKind::Static(ast_id) => {
let def = StaticLoc { container: module, ast_id: AstId::new(self.file_id, ast_id) }
let def = StaticLoc { container, ast_id: AstId::new(self.file_id, ast_id) }
.intern(self.def_collector.db);
PerNs::values(def.into())
}
raw::DefKind::Trait(ast_id) => {
let def = TraitLoc { container: module, ast_id: AstId::new(self.file_id, ast_id) }
let def = TraitLoc { container, ast_id: AstId::new(self.file_id, ast_id) }
.intern(self.def_collector.db);
PerNs::types(def.into())
}
raw::DefKind::TypeAlias(ast_id) => {
let def = TypeAliasLoc {
container: ContainerId::ModuleId(module),
container: container.into(),
ast_id: AstId::new(self.file_id, ast_id),
}
.intern(self.def_collector.db);

View file

@ -17,9 +17,9 @@ use crate::{
nameres::{BuiltinShadowMode, CrateDefMap},
path::{ModPath, PathKind},
per_ns::PerNs,
AdtId, ConstId, ContainerId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, GenericDefId,
HasModule, ImplId, LocalModuleId, Lookup, ModuleDefId, ModuleId, StaticId, StructId, TraitId,
TypeAliasId, TypeParamId, VariantId,
AdtId, AssocContainerId, ConstId, ContainerId, DefWithBodyId, EnumId, EnumVariantId,
FunctionId, GenericDefId, HasModule, ImplId, LocalModuleId, Lookup, ModuleDefId, ModuleId,
StaticId, StructId, TraitId, TypeAliasId, TypeParamId, VariantId,
};
#[derive(Debug, Clone, Default)]
@ -583,14 +583,22 @@ impl HasResolver for DefWithBodyId {
impl HasResolver for ContainerId {
fn resolver(self, db: &impl DefDatabase) -> Resolver {
match self {
ContainerId::TraitId(it) => it.resolver(db),
ContainerId::ImplId(it) => it.resolver(db),
ContainerId::ModuleId(it) => it.resolver(db),
ContainerId::DefWithBodyId(it) => it.resolver(db),
}
}
}
impl HasResolver for AssocContainerId {
fn resolver(self, db: &impl DefDatabase) -> Resolver {
match self {
AssocContainerId::ContainerId(it) => it.resolver(db),
AssocContainerId::TraitId(it) => it.resolver(db),
AssocContainerId::ImplId(it) => it.resolver(db),
}
}
}
impl HasResolver for GenericDefId {
fn resolver(self, db: &impl DefDatabase) -> Resolver {
match self {

View file

@ -8,7 +8,7 @@ use hir_def::{
expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp},
path::{GenericArg, GenericArgs},
resolver::resolver_for_expr,
AdtId, ContainerId, Lookup, StructFieldId,
AdtId, AssocContainerId, Lookup, StructFieldId,
};
use hir_expand::name::{name, Name};
use ra_syntax::ast::RangeOp;
@ -672,7 +672,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
// add obligation for trait implementation, if this is a trait method
match def {
CallableDef::FunctionId(f) => {
if let ContainerId::TraitId(trait_) = f.lookup(self.db).container {
if let AssocContainerId::TraitId(trait_) = f.lookup(self.db).container {
// construct a TraitDef
let substs =
a_ty.parameters.prefix(generics(self.db, trait_.into()).len());

View file

@ -5,7 +5,7 @@ use std::iter;
use hir_def::{
path::{Path, PathSegment},
resolver::{ResolveValueResult, Resolver, TypeNs, ValueNs},
AssocItemId, ContainerId, Lookup,
AssocContainerId, AssocItemId, Lookup,
};
use hir_expand::name::Name;
@ -209,7 +209,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
AssocItemId::TypeAliasId(_) => unreachable!(),
};
let substs = match container {
ContainerId::ImplId(impl_id) => {
AssocContainerId::ImplId(impl_id) => {
let impl_substs = Substs::build_for_def(self.db, impl_id)
.fill(iter::repeat_with(|| self.table.new_type_var()))
.build();
@ -221,7 +221,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
self.unify(&impl_self_ty, &ty);
Some(substs)
}
ContainerId::TraitId(trait_) => {
AssocContainerId::TraitId(trait_) => {
// we're picking this method
let trait_substs = Substs::build_for_def(self.db, trait_)
.push(ty.clone())
@ -237,7 +237,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
}));
Some(substs)
}
ContainerId::ModuleId(_) | ContainerId::DefWithBodyId(_) => None,
AssocContainerId::ContainerId(_) => None,
};
self.write_assoc_resolution(id, item.into());

View file

@ -44,8 +44,8 @@ use std::sync::Arc;
use std::{fmt, iter, mem};
use hir_def::{
expr::ExprId, type_ref::Mutability, AdtId, ContainerId, DefWithBodyId, GenericDefId, HasModule,
Lookup, TraitId, TypeAliasId,
expr::ExprId, type_ref::Mutability, AdtId, AssocContainerId, DefWithBodyId, GenericDefId,
HasModule, Lookup, TraitId, TypeAliasId,
};
use hir_expand::name::Name;
use ra_db::{impl_intern_key, salsa, CrateId};
@ -251,7 +251,7 @@ impl ProjectionTy {
fn trait_(&self, db: &impl HirDatabase) -> TraitId {
match self.associated_ty.lookup(db).container {
ContainerId::TraitId(it) => it,
AssocContainerId::TraitId(it) => it,
_ => panic!("projection ty without parent trait"),
}
}
@ -943,7 +943,7 @@ impl HirDisplay for ApplicationTy {
}
TypeCtor::AssociatedType(type_alias) => {
let trait_ = match type_alias.lookup(f.db).container {
ContainerId::TraitId(it) => it,
AssocContainerId::TraitId(it) => it,
_ => panic!("not an associated type"),
};
let trait_name = f.db.trait_data(trait_).name.clone();

View file

@ -697,8 +697,8 @@ impl CallableDef {
pub fn krate(self, db: &impl HirDatabase) -> CrateId {
match self {
CallableDef::FunctionId(f) => f.lookup(db).module(db),
CallableDef::StructId(s) => s.lookup(db).container,
CallableDef::EnumVariantId(e) => e.parent.lookup(db).container,
CallableDef::StructId(s) => s.lookup(db).container.module(db),
CallableDef::EnumVariantId(e) => e.parent.lookup(db).container.module(db),
}
.krate
}

View file

@ -6,8 +6,8 @@ use std::sync::Arc;
use arrayvec::ArrayVec;
use hir_def::{
lang_item::LangItemTarget, resolver::Resolver, type_ref::Mutability, AssocItemId, ContainerId,
FunctionId, HasModule, ImplId, Lookup, TraitId,
lang_item::LangItemTarget, resolver::Resolver, type_ref::Mutability, AssocContainerId,
AssocItemId, FunctionId, HasModule, ImplId, Lookup, TraitId,
};
use hir_expand::name::Name;
use ra_db::CrateId;
@ -451,12 +451,12 @@ fn transform_receiver_ty(
self_ty: &Canonical<Ty>,
) -> Option<Ty> {
let substs = match function_id.lookup(db).container {
ContainerId::TraitId(_) => Substs::build_for_def(db, function_id)
AssocContainerId::TraitId(_) => Substs::build_for_def(db, function_id)
.push(self_ty.value.clone())
.fill_with_unknown()
.build(),
ContainerId::ImplId(impl_id) => inherent_impl_substs(db, impl_id, &self_ty)?,
ContainerId::ModuleId(_) | ContainerId::DefWithBodyId(_) => unreachable!(),
AssocContainerId::ImplId(impl_id) => inherent_impl_substs(db, impl_id, &self_ty)?,
AssocContainerId::ContainerId(_) => unreachable!(),
};
let sig = db.callable_item_signature(function_id.into());
Some(sig.params()[0].clone().subst(&substs))

View file

@ -9,7 +9,9 @@ use chalk_ir::{
};
use chalk_rust_ir::{AssociatedTyDatum, AssociatedTyValue, ImplDatum, StructDatum, TraitDatum};
use hir_def::{AssocItemId, ContainerId, GenericDefId, ImplId, Lookup, TraitId, TypeAliasId};
use hir_def::{
AssocContainerId, AssocItemId, GenericDefId, HasModule, ImplId, Lookup, TraitId, TypeAliasId,
};
use ra_db::{
salsa::{InternId, InternKey},
CrateId,
@ -542,7 +544,7 @@ pub(crate) fn associated_ty_data_query(
debug!("associated_ty_data {:?}", id);
let type_alias: TypeAliasId = from_chalk(db, id);
let trait_ = match type_alias.lookup(db).container {
ContainerId::TraitId(t) => t,
AssocContainerId::TraitId(t) => t,
_ => panic!("associated type not in trait"),
};
let generic_params = generics(db, type_alias.into());
@ -591,7 +593,7 @@ pub(crate) fn trait_datum_query(
let bound_vars = Substs::bound_vars(&generic_params);
let flags = chalk_rust_ir::TraitFlags {
auto: trait_data.auto,
upstream: trait_.lookup(db).container.krate != krate,
upstream: trait_.lookup(db).container.module(db).krate != krate,
non_enumerable: true,
coinductive: false, // only relevant for Chalk testing
// FIXME set these flags correctly
@ -755,7 +757,7 @@ fn type_alias_associated_ty_value(
) -> Arc<AssociatedTyValue<ChalkIr>> {
let type_alias_data = db.type_alias_data(type_alias);
let impl_id = match type_alias.lookup(db).container {
ContainerId::ImplId(it) => it,
AssocContainerId::ImplId(it) => it,
_ => panic!("assoc ty value should be in impl"),
};

View file

@ -9,7 +9,7 @@ use hir_def::{
path::Path,
resolver::{HasResolver, TypeNs},
type_ref::TypeRef,
ContainerId, GenericDefId, Lookup, TraitId, TypeAliasId, TypeParamId, VariantId,
AssocContainerId, GenericDefId, Lookup, TraitId, TypeAliasId, TypeParamId, VariantId,
};
use hir_expand::name::{name, Name};
@ -155,8 +155,8 @@ fn parent_generic_def(db: &impl DefDatabase, def: GenericDefId) -> Option<Generi
};
match container {
ContainerId::ImplId(it) => Some(it.into()),
ContainerId::TraitId(it) => Some(it.into()),
ContainerId::ModuleId(_) | ContainerId::DefWithBodyId(_) => None,
AssocContainerId::ImplId(it) => Some(it.into()),
AssocContainerId::TraitId(it) => Some(it.into()),
AssocContainerId::ContainerId(_) => None,
}
}