From 3bf033e54814919f2214ca4e9b73cebc5ba7d86d Mon Sep 17 00:00:00 2001 From: Paul Daniel Faria Date: Fri, 7 Aug 2020 09:24:20 -0400 Subject: [PATCH] Add support for unions in inference and lowering --- crates/ra_hir_ty/src/infer.rs | 11 +++++++---- crates/ra_hir_ty/src/lower.rs | 5 ++++- crates/ra_hir_ty/src/tests/simple.rs | 4 ++-- crates/ra_ide/test_data/highlight_unsafe.html | 8 ++++---- 4 files changed, 17 insertions(+), 11 deletions(-) diff --git a/crates/ra_hir_ty/src/infer.rs b/crates/ra_hir_ty/src/infer.rs index 28f32a0a4de..3d12039a6d2 100644 --- a/crates/ra_hir_ty/src/infer.rs +++ b/crates/ra_hir_ty/src/infer.rs @@ -440,6 +440,12 @@ impl<'a> InferenceContext<'a> { let ty = self.insert_type_vars(ty.subst(&substs)); forbid_unresolved_segments((ty, Some(strukt.into())), unresolved) } + TypeNs::AdtId(AdtId::UnionId(u)) => { + let substs = Ty::substs_from_path(&ctx, path, u.into(), true); + let ty = self.db.ty(u.into()); + let ty = self.insert_type_vars(ty.subst(&substs)); + forbid_unresolved_segments((ty, Some(u.into())), unresolved) + } TypeNs::EnumVariantId(var) => { let substs = Ty::substs_from_path(&ctx, path, var.into(), true); let ty = self.db.ty(var.parent.into()); @@ -490,10 +496,7 @@ impl<'a> InferenceContext<'a> { // FIXME potentially resolve assoc type (Ty::Unknown, None) } - TypeNs::AdtId(AdtId::EnumId(_)) - | TypeNs::AdtId(AdtId::UnionId(_)) - | TypeNs::BuiltinType(_) - | TypeNs::TraitId(_) => { + TypeNs::AdtId(AdtId::EnumId(_)) | TypeNs::BuiltinType(_) | TypeNs::TraitId(_) => { // FIXME diagnostic (Ty::Unknown, None) } diff --git a/crates/ra_hir_ty/src/lower.rs b/crates/ra_hir_ty/src/lower.rs index 1eacc6f95ed..7638f167b5b 100644 --- a/crates/ra_hir_ty/src/lower.rs +++ b/crates/ra_hir_ty/src/lower.rs @@ -518,6 +518,7 @@ impl Ty { let (segment, generic_def) = match resolved { ValueTyDefId::FunctionId(it) => (last, Some(it.into())), ValueTyDefId::StructId(it) => (last, Some(it.into())), + ValueTyDefId::UnionId(it) => (last, Some(it.into())), ValueTyDefId::ConstId(it) => (last, Some(it.into())), ValueTyDefId::StaticId(_) => (last, None), ValueTyDefId::EnumVariantId(var) => { @@ -1148,11 +1149,12 @@ impl_from!(BuiltinType, AdtId(StructId, EnumId, UnionId), TypeAliasId for TyDefI pub enum ValueTyDefId { FunctionId(FunctionId), StructId(StructId), + UnionId(UnionId), EnumVariantId(EnumVariantId), ConstId(ConstId), StaticId(StaticId), } -impl_from!(FunctionId, StructId, EnumVariantId, ConstId, StaticId for ValueTyDefId); +impl_from!(FunctionId, StructId, UnionId, EnumVariantId, ConstId, StaticId for ValueTyDefId); /// Build the declared type of an item. This depends on the namespace; e.g. for /// `struct Foo(usize)`, we have two types: The type of the struct itself, and @@ -1179,6 +1181,7 @@ pub(crate) fn value_ty_query(db: &dyn HirDatabase, def: ValueTyDefId) -> Binders match def { ValueTyDefId::FunctionId(it) => type_for_fn(db, it), ValueTyDefId::StructId(it) => type_for_struct_constructor(db, it), + ValueTyDefId::UnionId(it) => type_for_adt(db, it.into()), ValueTyDefId::EnumVariantId(it) => type_for_enum_variant_constructor(db, it), ValueTyDefId::ConstId(it) => type_for_const(db, it), ValueTyDefId::StaticId(it) => type_for_static(db, it), diff --git a/crates/ra_hir_ty/src/tests/simple.rs b/crates/ra_hir_ty/src/tests/simple.rs index a2db6944df2..5a7cf9455b5 100644 --- a/crates/ra_hir_ty/src/tests/simple.rs +++ b/crates/ra_hir_ty/src/tests/simple.rs @@ -350,7 +350,7 @@ fn infer_union() { 57..172 '{ ...); } }': () 67..68 'u': MyUnion 71..89 'MyUnio...o: 0 }': MyUnion - 86..87 '0': i32 + 86..87 '0': u32 95..113 'unsafe...(u); }': () 102..113 '{ baz(u); }': () 104..107 'baz': fn baz(MyUnion) @@ -358,7 +358,7 @@ fn infer_union() { 108..109 'u': MyUnion 122..123 'u': MyUnion 126..146 'MyUnio... 0.0 }': MyUnion - 141..144 '0.0': f64 + 141..144 '0.0': f32 152..170 'unsafe...(u); }': () 159..170 '{ baz(u); }': () 161..164 'baz': fn baz(MyUnion) diff --git a/crates/ra_ide/test_data/highlight_unsafe.html b/crates/ra_ide/test_data/highlight_unsafe.html index 39582b5bb47..de70363da27 100644 --- a/crates/ra_ide/test_data/highlight_unsafe.html +++ b/crates/ra_ide/test_data/highlight_unsafe.html @@ -50,13 +50,13 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd fn main() { let x = &5 as *const usize; - let u = Union { b: 0 }; + let u = Union { b: 0 }; unsafe { unsafe_fn(); - let b = u.b; + let b = u.b; match u { - Union { b: 0 } => (), - Union { a } => (), + Union { b: 0 } => (), + Union { a } => (), } HasUnsafeFn.unsafe_method(); let y = *(x);