diff --git a/Cargo.lock b/Cargo.lock index f35d63df2f2..72ec6862460 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -162,9 +162,9 @@ checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" [[package]] name = "chalk-derive" -version = "0.25.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624e14d3f029186e6ffd97081ffa082f98ddd5df20655b6f0e8efb83dd8ac8b4" +checksum = "d5444ff2a211fe2a863e44d16a368c3d8a314d489de21b8eeb6879f14dd5d4a8" dependencies = [ "proc-macro2", "quote", @@ -174,9 +174,9 @@ dependencies = [ [[package]] name = "chalk-ir" -version = "0.25.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "118c68eccdda5604af50bbef84c94550f3854f76989cb03c36ffd36cc2ffe958" +checksum = "e39c3db1dd4abfaa7658faaa62e5fe998a982a592b710bd971fad5b6adfcfdef" dependencies = [ "chalk-derive", "lazy_static", @@ -184,9 +184,9 @@ dependencies = [ [[package]] name = "chalk-recursive" -version = "0.25.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5130de3065e3cdfd2ab6d7d70b02b917bafbc096f270c9a643c23da249053606" +checksum = "3bfae328eff80ca54dcd0d731725bbb56136ac21c59261b68f1e5498e056b306" dependencies = [ "chalk-derive", "chalk-ir", @@ -197,9 +197,9 @@ dependencies = [ [[package]] name = "chalk-solve" -version = "0.25.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45b235a1f568b28707f117b2d30eabbee9cbcfccaa0d6e9697300400c8ca0996" +checksum = "a673abe3077adc25f8ee0894198aed494a5bb0ce50ee993900d0ee1a44e1948a" dependencies = [ "chalk-derive", "chalk-ir", diff --git a/crates/hir_def/src/item_tree.rs b/crates/hir_def/src/item_tree.rs index e14722caebb..52abb8e7f16 100644 --- a/crates/hir_def/src/item_tree.rs +++ b/crates/hir_def/src/item_tree.rs @@ -592,6 +592,7 @@ pub struct TypeAlias { pub bounds: Box<[TypeBound]>, pub generic_params: GenericParamsId, pub type_ref: Option, + pub is_extern: bool, pub ast_id: FileAstId, } diff --git a/crates/hir_def/src/item_tree/lower.rs b/crates/hir_def/src/item_tree/lower.rs index 6a503d7853e..d93377c3bd4 100644 --- a/crates/hir_def/src/item_tree/lower.rs +++ b/crates/hir_def/src/item_tree/lower.rs @@ -364,6 +364,7 @@ fn lower_type_alias( generic_params, type_ref, ast_id, + is_extern: false, }; Some(id(self.data().type_aliases.alloc(res))) } @@ -558,8 +559,9 @@ fn lower_extern_block(&mut self, block: &ast::ExternBlock) -> Vec { statik.into() } ast::ExternItem::TypeAlias(ty) => { - let id = self.lower_type_alias(&ty)?; - id.into() + let foreign_ty = self.lower_type_alias(&ty)?; + self.data().type_aliases[foreign_ty.index].is_extern = true; + foreign_ty.into() } ast::ExternItem::MacroCall(_) => return None, }; diff --git a/crates/hir_def/src/item_tree/tests.rs b/crates/hir_def/src/item_tree/tests.rs index 620e697d4a1..eed3d0d6ff4 100644 --- a/crates/hir_def/src/item_tree/tests.rs +++ b/crates/hir_def/src/item_tree/tests.rs @@ -236,7 +236,7 @@ union Un { #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("on_trait"))] }, input: None }]) }] Trait { name: Name(Text("Tr")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(0), auto: false, items: [TypeAlias(Idx::(0)), Const(Idx::(0)), Function(Idx::(0)), Function(Idx::(1))], ast_id: FileAstId::(2) } > #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("assoc_ty"))] }, input: None }]) }] - > TypeAlias { name: Name(Text("AssocTy")), visibility: RawVisibilityId("pub(self)"), bounds: [Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("Tr"))] }, generic_args: [Some(GenericArgs { args: [Type(Tuple([]))], has_self_type: false, bindings: [] })] })], generic_params: GenericParamsId(4294967295), type_ref: None, ast_id: FileAstId::(8) } + > TypeAlias { name: Name(Text("AssocTy")), visibility: RawVisibilityId("pub(self)"), bounds: [Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("Tr"))] }, generic_args: [Some(GenericArgs { args: [Type(Tuple([]))], has_self_type: false, bindings: [] })] })], generic_params: GenericParamsId(4294967295), type_ref: None, is_extern: false, ast_id: FileAstId::(8) } > #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("assoc_const"))] }, input: None }]) }] > Const { name: Some(Name(Text("CONST"))), visibility: RawVisibilityId("pub(self)"), type_ref: Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("u8"))] }, generic_args: [None] }), ast_id: FileAstId::(9) } > #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("assoc_method"))] }, input: None }]) }] diff --git a/crates/hir_ty/Cargo.toml b/crates/hir_ty/Cargo.toml index 7d02aaf9554..bc86df2b168 100644 --- a/crates/hir_ty/Cargo.toml +++ b/crates/hir_ty/Cargo.toml @@ -17,9 +17,9 @@ ena = "0.14.0" log = "0.4.8" rustc-hash = "1.1.0" scoped-tls = "1" -chalk-solve = { version = "0.25.0" } -chalk-ir = { version = "0.25.0" } -chalk-recursive = { version = "0.25.0" } +chalk-solve = { version = "0.27.0" } +chalk-ir = { version = "0.27.0" } +chalk-recursive = { version = "0.27.0" } stdx = { path = "../stdx", version = "0.0.0" } hir_def = { path = "../hir_def", version = "0.0.0" } diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs index efb48c7ee4b..f389c5a4b34 100644 --- a/crates/hir_ty/src/display.rs +++ b/crates/hir_ty/src/display.rs @@ -380,6 +380,15 @@ fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { write!(f, ">")?; } } + TypeCtor::ForeignType(type_alias) => { + let type_alias = f.db.type_alias_data(type_alias); + write!(f, "{}", type_alias.name)?; + if self.parameters.len() > 0 { + write!(f, "<")?; + f.write_joined(&*self.parameters.0, ", ")?; + write!(f, ">")?; + } + } TypeCtor::OpaqueType(opaque_ty_id) => { match opaque_ty_id { OpaqueTyId::ReturnTypeImplTrait(func, idx) => { diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs index f16d1fc979f..768d95effa2 100644 --- a/crates/hir_ty/src/lib.rs +++ b/crates/hir_ty/src/lib.rs @@ -134,6 +134,9 @@ pub enum TypeCtor { /// representing the Future::Output type. OpaqueType(OpaqueTyId), + /// Represents a foreign type declared in external blocks. + ForeignType(TypeAliasId), + /// The type of a specific closure. /// /// The closure signature is stored in a `FnPtr` type in the first type @@ -168,6 +171,10 @@ pub fn num_ty_params(self, db: &dyn HirDatabase) -> usize { let generic_params = generics(db.upcast(), type_alias.into()); generic_params.len() } + TypeCtor::ForeignType(type_alias) => { + let generic_params = generics(db.upcast(), type_alias.into()); + generic_params.len() + } TypeCtor::OpaqueType(opaque_ty_id) => { match opaque_ty_id { OpaqueTyId::ReturnTypeImplTrait(func, _) => { @@ -204,6 +211,9 @@ pub fn krate(self, db: &dyn HirDatabase) -> Option { TypeCtor::AssociatedType(type_alias) => { Some(type_alias.lookup(db.upcast()).module(db.upcast()).krate) } + TypeCtor::ForeignType(type_alias) => { + Some(type_alias.lookup(db.upcast()).module(db.upcast()).krate) + } TypeCtor::OpaqueType(opaque_ty_id) => match opaque_ty_id { OpaqueTyId::ReturnTypeImplTrait(func, _) => { Some(func.lookup(db.upcast()).module(db.upcast()).krate) @@ -231,6 +241,7 @@ pub fn as_generic_def(self) -> Option { TypeCtor::Adt(adt) => Some(adt.into()), TypeCtor::FnDef(callable) => Some(callable.into()), TypeCtor::AssociatedType(type_alias) => Some(type_alias.into()), + TypeCtor::ForeignType(type_alias) => Some(type_alias.into()), TypeCtor::OpaqueType(_impl_trait_id) => None, } } diff --git a/crates/hir_ty/src/traits/chalk.rs b/crates/hir_ty/src/traits/chalk.rs index 57d0a32df02..27f0ed628fe 100644 --- a/crates/hir_ty/src/traits/chalk.rs +++ b/crates/hir_ty/src/traits/chalk.rs @@ -23,7 +23,8 @@ ProjectionTy, Substs, TraitRef, Ty, TypeCtor, }; use mapping::{ - convert_where_clauses, generic_predicate_to_inline_bound, make_binders, TypeAliasAsValue, + convert_where_clauses, generic_predicate_to_inline_bound, make_binders, TypeAliasAsAssocType, + TypeAliasAsValue, }; pub use self::interner::*; @@ -340,7 +341,7 @@ pub(crate) fn associated_ty_data_query( id: AssocTypeId, ) -> Arc { debug!("associated_ty_data {:?}", id); - let type_alias: TypeAliasId = from_chalk(db, id); + let type_alias: TypeAliasId = from_chalk::(db, id).0; let trait_ = match type_alias.lookup(db.upcast()).container { AssocContainerId::TraitId(t) => t, _ => panic!("associated type not in trait"), @@ -394,8 +395,10 @@ pub(crate) fn trait_datum_query( fundamental: false, }; let where_clauses = convert_where_clauses(db, trait_.into(), &bound_vars); - let associated_ty_ids = - trait_data.associated_types().map(|type_alias| type_alias.to_chalk(db)).collect(); + let associated_ty_ids = trait_data + .associated_types() + .map(|type_alias| TypeAliasAsAssocType(type_alias).to_chalk(db)) + .collect(); let trait_datum_bound = rust_ir::TraitDatumBound { where_clauses }; let well_known = lang_attr(db.upcast(), trait_).and_then(|name| well_known_trait_from_lang_attr(&name)); @@ -433,6 +436,7 @@ fn lang_attr_from_well_known_trait(attr: WellKnownTrait) -> &'static str { WellKnownTrait::FnMut => "fn_mut", WellKnownTrait::Fn => "fn", WellKnownTrait::Unsize => "unsize", + WellKnownTrait::Unpin => "unpin", } } @@ -576,7 +580,7 @@ fn type_alias_associated_ty_value( let value_bound = rust_ir::AssociatedTyValueBound { ty: ty.value.to_chalk(db) }; let value = rust_ir::AssociatedTyValue { impl_id: impl_id.to_chalk(db), - associated_ty_id: assoc_ty.to_chalk(db), + associated_ty_id: TypeAliasAsAssocType(assoc_ty).to_chalk(db), value: make_binders(value_bound, ty.num_binders), }; Arc::new(value) @@ -611,9 +615,11 @@ pub(crate) fn fn_def_datum_query( }; let datum = FnDefDatum { id: fn_def_id, - abi: (), - safety: chalk_ir::Safety::Safe, - variadic: sig.value.is_varargs, + sig: chalk_ir::FnSig { + abi: (), + safety: chalk_ir::Safety::Safe, + variadic: sig.value.is_varargs, + }, binders: make_binders(bound, sig.num_binders), }; Arc::new(datum) diff --git a/crates/hir_ty/src/traits/chalk/interner.rs b/crates/hir_ty/src/traits/chalk/interner.rs index eb35db3ffc1..f9304b7d0c8 100644 --- a/crates/hir_ty/src/traits/chalk/interner.rs +++ b/crates/hir_ty/src/traits/chalk/interner.rs @@ -12,6 +12,7 @@ pub type AssocTypeId = chalk_ir::AssocTypeId; pub type AssociatedTyDatum = chalk_solve::rust_ir::AssociatedTyDatum; +pub type ForeignDefId = chalk_ir::ForeignDefId; pub type TraitId = chalk_ir::TraitId; pub type TraitDatum = chalk_solve::rust_ir::TraitDatum; pub type AdtId = chalk_ir::AdtId; diff --git a/crates/hir_ty/src/traits/chalk/mapping.rs b/crates/hir_ty/src/traits/chalk/mapping.rs index d6bacba1d3d..d42f4bba9e5 100644 --- a/crates/hir_ty/src/traits/chalk/mapping.rs +++ b/crates/hir_ty/src/traits/chalk/mapping.rs @@ -34,9 +34,11 @@ fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Ty { let substitution = apply_ty.parameters.to_chalk(db).shifted_in(&Interner); chalk_ir::TyData::Function(chalk_ir::FnPointer { num_binders: 0, - abi: (), - safety: chalk_ir::Safety::Safe, - variadic: is_varargs, + sig: chalk_ir::FnSig { + abi: (), + safety: chalk_ir::Safety::Safe, + variadic: is_varargs, + }, substitution, }) .intern(&Interner) @@ -48,7 +50,7 @@ fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Ty { } }, Ty::Projection(proj_ty) => { - let associated_ty_id = proj_ty.associated_ty.to_chalk(db); + let associated_ty_id = TypeAliasAsAssocType(proj_ty.associated_ty).to_chalk(db); let substitution = proj_ty.parameters.to_chalk(db); chalk_ir::AliasTy::Projection(chalk_ir::ProjectionTy { associated_ty_id, @@ -114,7 +116,8 @@ fn from_chalk(db: &dyn HirDatabase, chalk: chalk_ir::Ty) -> Self { Ty::Placeholder(db.lookup_intern_type_param_id(interned_id)) } chalk_ir::TyData::Alias(chalk_ir::AliasTy::Projection(proj)) => { - let associated_ty = from_chalk(db, proj.associated_ty_id); + let associated_ty = + from_chalk::(db, proj.associated_ty_id).0; let parameters = from_chalk(db, proj.substitution); Ty::Projection(ProjectionTy { associated_ty, parameters }) } @@ -125,7 +128,7 @@ fn from_chalk(db: &dyn HirDatabase, chalk: chalk_ir::Ty) -> Self { } chalk_ir::TyData::Function(chalk_ir::FnPointer { num_binders, - variadic, + sig: chalk_ir::FnSig { variadic, .. }, substitution, .. }) => { @@ -290,8 +293,9 @@ impl ToChalk for TypeCtor { fn to_chalk(self, db: &dyn HirDatabase) -> TypeName { match self { TypeCtor::AssociatedType(type_alias) => { - let type_id = type_alias.to_chalk(db); - TypeName::AssociatedType(type_id) + let assoc_type = TypeAliasAsAssocType(type_alias); + let assoc_type_id = assoc_type.to_chalk(db); + TypeName::AssociatedType(assoc_type_id) } TypeCtor::OpaqueType(impl_trait_id) => { @@ -299,6 +303,12 @@ fn to_chalk(self, db: &dyn HirDatabase) -> TypeName { TypeName::OpaqueType(id) } + TypeCtor::ForeignType(type_alias) => { + let foreign_type = TypeAliasAsForeignType(type_alias); + let foreign_type_id = foreign_type.to_chalk(db); + TypeName::Foreign(foreign_type_id) + } + TypeCtor::Bool => TypeName::Scalar(Scalar::Bool), TypeCtor::Char => TypeName::Scalar(Scalar::Char), TypeCtor::Int(int_ty) => TypeName::Scalar(int_ty_to_chalk(int_ty)), @@ -339,7 +349,9 @@ fn to_chalk(self, db: &dyn HirDatabase) -> TypeName { fn from_chalk(db: &dyn HirDatabase, type_name: TypeName) -> TypeCtor { match type_name { TypeName::Adt(struct_id) => TypeCtor::Adt(struct_id.0), - TypeName::AssociatedType(type_id) => TypeCtor::AssociatedType(from_chalk(db, type_id)), + TypeName::AssociatedType(type_id) => { + TypeCtor::AssociatedType(from_chalk::(db, type_id).0) + } TypeName::OpaqueType(opaque_type_id) => { TypeCtor::OpaqueType(from_chalk(db, opaque_type_id)) } @@ -379,6 +391,10 @@ fn from_chalk(db: &dyn HirDatabase, type_name: TypeName) -> TypeCtor { TypeCtor::Closure { def, expr } } + TypeName::Foreign(foreign_def_id) => { + TypeCtor::ForeignType(from_chalk::(db, foreign_def_id).0) + } + TypeName::Error => { // this should not be reached, since we don't represent TypeName::Error with TypeCtor unreachable!() @@ -488,15 +504,31 @@ fn from_chalk(db: &dyn HirDatabase, fn_def_id: FnDefId) -> CallableDefId { } } -impl ToChalk for TypeAliasId { +pub struct TypeAliasAsAssocType(pub TypeAliasId); + +impl ToChalk for TypeAliasAsAssocType { type Chalk = AssocTypeId; fn to_chalk(self, _db: &dyn HirDatabase) -> AssocTypeId { - chalk_ir::AssocTypeId(self.as_intern_id()) + chalk_ir::AssocTypeId(self.0.as_intern_id()) } - fn from_chalk(_db: &dyn HirDatabase, type_alias_id: AssocTypeId) -> TypeAliasId { - InternKey::from_intern_id(type_alias_id.0) + fn from_chalk(_db: &dyn HirDatabase, assoc_type_id: AssocTypeId) -> TypeAliasAsAssocType { + TypeAliasAsAssocType(InternKey::from_intern_id(assoc_type_id.0)) + } +} + +pub struct TypeAliasAsForeignType(pub TypeAliasId); + +impl ToChalk for TypeAliasAsForeignType { + type Chalk = ForeignDefId; + + fn to_chalk(self, _db: &dyn HirDatabase) -> ForeignDefId { + chalk_ir::ForeignDefId(self.0.as_intern_id()) + } + + fn from_chalk(_db: &dyn HirDatabase, foreign_def_id: ForeignDefId) -> TypeAliasAsForeignType { + TypeAliasAsForeignType(InternKey::from_intern_id(foreign_def_id.0)) } } @@ -580,7 +612,7 @@ impl ToChalk for ProjectionTy { fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::ProjectionTy { chalk_ir::ProjectionTy { - associated_ty_id: self.associated_ty.to_chalk(db), + associated_ty_id: TypeAliasAsAssocType(self.associated_ty).to_chalk(db), substitution: self.parameters.to_chalk(db), } } @@ -590,7 +622,11 @@ fn from_chalk( projection_ty: chalk_ir::ProjectionTy, ) -> ProjectionTy { ProjectionTy { - associated_ty: from_chalk(db, projection_ty.associated_ty_id), + associated_ty: from_chalk::( + db, + projection_ty.associated_ty_id, + ) + .0, parameters: from_chalk(db, projection_ty.substitution), } } @@ -789,7 +825,8 @@ pub(super) fn generic_predicate_to_inline_bound( let alias_eq_bound = rust_ir::AliasEqBound { value: proj.ty.clone().to_chalk(db), trait_bound: rust_ir::TraitBound { trait_id: trait_.to_chalk(db), args_no_self }, - associated_ty_id: proj.projection_ty.associated_ty.to_chalk(db), + associated_ty_id: TypeAliasAsAssocType(proj.projection_ty.associated_ty) + .to_chalk(db), parameters: Vec::new(), // FIXME we don't support generic associated types yet }; Some(rust_ir::InlineBound::AliasEqBound(alias_eq_bound)) diff --git a/crates/hir_ty/src/traits/chalk/tls.rs b/crates/hir_ty/src/traits/chalk/tls.rs index cb6b0fe81fd..b4568cff643 100644 --- a/crates/hir_ty/src/traits/chalk/tls.rs +++ b/crates/hir_ty/src/traits/chalk/tls.rs @@ -4,7 +4,7 @@ use chalk_ir::{AliasTy, GenericArg, Goal, Goals, Lifetime, ProgramClauseImplication, TypeName}; use itertools::Itertools; -use super::{from_chalk, Interner}; +use super::{from_chalk, Interner, TypeAliasAsAssocType}; use crate::{db::HirDatabase, CallableDefId, TypeCtor}; use hir_def::{AdtId, AssocContainerId, DefWithBodyId, Lookup, TypeAliasId}; @@ -77,6 +77,10 @@ pub fn debug_struct_id( write!(f, "{{impl trait of async block {} of {:?}}}", idx.into_raw(), def)?; } }, + TypeCtor::ForeignType(type_alias) => { + let name = self.0.type_alias_data(type_alias).name.clone(); + write!(f, "{}", name)?; + } TypeCtor::Closure { def, expr } => { write!(f, "{{closure {:?} in ", expr.into_raw())?; match def { @@ -119,7 +123,7 @@ pub fn debug_assoc_type_id( id: super::AssocTypeId, fmt: &mut fmt::Formatter<'_>, ) -> Result<(), fmt::Error> { - let type_alias: TypeAliasId = from_chalk(self.0, id); + let type_alias: TypeAliasId = from_chalk::(self.0, id).0; let type_alias_data = self.0.type_alias_data(type_alias); let trait_ = match type_alias.lookup(self.0.upcast()).container { AssocContainerId::TraitId(t) => t, @@ -153,7 +157,8 @@ pub fn debug_projection_ty( projection_ty: &chalk_ir::ProjectionTy, fmt: &mut fmt::Formatter<'_>, ) -> Result<(), fmt::Error> { - let type_alias: TypeAliasId = from_chalk(self.0, projection_ty.associated_ty_id); + let type_alias: TypeAliasId = + from_chalk::(self.0, projection_ty.associated_ty_id).0; let type_alias_data = self.0.type_alias_data(type_alias); let trait_ = match type_alias.lookup(self.0.upcast()).container { AssocContainerId::TraitId(t) => t,