From cf3b4f1e208247c9d171273dabff9c6b3c98a240 Mon Sep 17 00:00:00 2001 From: cynecx Date: Sat, 10 Apr 2021 17:49:12 +0200 Subject: hir_ty: Expand macros at type position --- crates/hir_ty/src/display.rs | 2 +- crates/hir_ty/src/lower.rs | 12 ++- crates/hir_ty/src/tests/macros.rs | 169 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 181 insertions(+), 2 deletions(-) (limited to 'crates/hir_ty/src') diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs index e7c9dabc2..63bcb0640 100644 --- a/crates/hir_ty/src/display.rs +++ b/crates/hir_ty/src/display.rs @@ -997,7 +997,7 @@ impl HirDisplay for TypeRef { write!(f, "dyn ")?; f.write_joined(bounds, " + ")?; } - TypeRef::Error => write!(f, "{{error}}")?, + TypeRef::Error | TypeRef::Macro(_) => write!(f, "{{error}}")?, } Ok(()) } diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs index a035686bc..95ca5bdb0 100644 --- a/crates/hir_ty/src/lower.rs +++ b/crates/hir_ty/src/lower.rs @@ -15,7 +15,7 @@ use hir_def::{ generics::{TypeParamProvenance, WherePredicate, WherePredicateTypeTarget}, path::{GenericArg, Path, PathSegment, PathSegments}, resolver::{HasResolver, Resolver, TypeNs}, - type_ref::{TraitRef as HirTraitRef, TypeBound, TypeRef}, + type_ref::{expand_type_ref, TraitRef as HirTraitRef, TypeBound, TypeRef}, AdtId, AssocContainerId, AssocItemId, ConstId, ConstParamId, EnumId, EnumVariantId, FunctionId, GenericDefId, HasModule, ImplId, LocalFieldId, Lookup, StaticId, StructId, TraitId, TypeAliasId, TypeParamId, UnionId, VariantId, @@ -287,6 +287,16 @@ impl<'a> TyLoweringContext<'a> { } } } + mt @ TypeRef::Macro(_) => { + if let Some(module_id) = self.resolver.module() { + match expand_type_ref(self.db.upcast(), module_id, mt) { + Some(type_ref) => self.lower_ty(type_ref.as_ref()), + None => TyKind::Error.intern(&Interner), + } + } else { + TyKind::Error.intern(&Interner) + } + } TypeRef::Error => TyKind::Error.intern(&Interner), }; (ty, res) diff --git a/crates/hir_ty/src/tests/macros.rs b/crates/hir_ty/src/tests/macros.rs index b8e373ed8..cbe05a5c1 100644 --- a/crates/hir_ty/src/tests/macros.rs +++ b/crates/hir_ty/src/tests/macros.rs @@ -1074,3 +1074,172 @@ fn macro_in_arm() { "#]], ); } + +#[test] +fn macro_in_type_alias_position() { + check_infer( + r#" + macro_rules! U32 { + () => { u32 }; + } + + trait Foo { + type Ty; + } + + impl Foo for T { + type Ty = U32!(); + } + + type TayTo = U32!(); + + fn testy() { + let a: <() as Foo>::Ty; + let b: TayTo; + } + "#, + expect![[r#" + 147..196 '{ ...yTo; }': () + 157..158 'a': u32 + 185..186 'b': u32 + "#]], + ); +} + +#[test] +fn nested_macro_in_type_alias_position() { + check_infer( + r#" + macro_rules! U32Inner2 { + () => { u32 }; + } + + macro_rules! U32Inner1 { + () => { U32Inner2!() }; + } + + macro_rules! U32 { + () => { U32Inner1!() }; + } + + trait Foo { + type Ty; + } + + impl Foo for T { + type Ty = U32!(); + } + + type TayTo = U32!(); + + fn testy() { + let a: <() as Foo>::Ty; + let b: TayTo; + } + "#, + expect![[r#" + 259..308 '{ ...yTo; }': () + 269..270 'a': u32 + 297..298 'b': u32 + "#]], + ); +} + +#[test] +fn macros_in_type_alias_position_generics() { + check_infer( + r#" + struct Foo(A, B); + + macro_rules! U32 { + () => { u32 }; + } + + macro_rules! Bar { + () => { Foo }; + } + + trait Moo { + type Ty; + } + + impl Moo for T { + type Ty = Bar!(); + } + + type TayTo = Bar!(); + + fn main() { + let a: <() as Moo>::Ty; + let b: TayTo; + } + "#, + expect![[r#" + 228..277 '{ ...yTo; }': () + 238..239 'a': Foo + 266..267 'b': Foo + "#]], + ); +} + +#[test] +fn macros_in_type_position() { + check_infer( + r#" + struct Foo(A, B); + + macro_rules! U32 { + () => { u32 }; + } + + macro_rules! Bar { + () => { Foo }; + } + + fn main() { + let a: Bar!(); + } + "#, + expect![[r#" + 133..155 '{ ...!(); }': () + 143..144 'a': Foo + "#]], + ); +} + +#[test] +fn macros_in_type_generics() { + check_infer( + r#" + struct Foo(A, B); + + macro_rules! U32 { + () => { u32 }; + } + + macro_rules! Bar { + () => { Foo }; + } + + trait Moo { + type Ty; + } + + impl Moo for T { + type Ty = Foo; + } + + type TayTo = Foo; + + fn main() { + let a: <() as Moo>::Ty; + let b: TayTo; + } + "#, + expect![[r#" + 254..303 '{ ...yTo; }': () + 264..265 'a': Foo, Foo> + 292..293 'b': Foo, u32> + "#]], + ); +} -- cgit v1.2.3