Add support for unions in inference and lowering

This commit is contained in:
Paul Daniel Faria 2020-08-07 09:24:20 -04:00
parent a39d503ef3
commit 3bf033e548
4 changed files with 17 additions and 11 deletions

View file

@ -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)
}

View file

@ -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),

View file

@ -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)

View file

@ -50,13 +50,13 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
<span class="keyword">fn</span> <span class="function declaration">main</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span>
<span class="keyword">let</span> <span class="variable declaration">x</span> <span class="operator">=</span> <span class="operator">&</span><span class="numeric_literal">5</span> <span class="keyword">as</span> <span class="keyword">*</span><span class="keyword">const</span> <span class="builtin_type">usize</span><span class="punctuation">;</span>
<span class="keyword">let</span> <span class="variable declaration">u</span> <span class="operator">=</span> <span class="union">Union</span> <span class="punctuation">{</span> <span class="unresolved_reference">b</span><span class="punctuation">:</span> <span class="numeric_literal">0</span> <span class="punctuation">}</span><span class="punctuation">;</span>
<span class="keyword">let</span> <span class="variable declaration">u</span> <span class="operator">=</span> <span class="union">Union</span> <span class="punctuation">{</span> <span class="field">b</span><span class="punctuation">:</span> <span class="numeric_literal">0</span> <span class="punctuation">}</span><span class="punctuation">;</span>
<span class="keyword unsafe">unsafe</span> <span class="punctuation">{</span>
<span class="function unsafe">unsafe_fn</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span>
<span class="keyword">let</span> <span class="variable declaration">b</span> <span class="operator">=</span> <span class="variable">u</span><span class="punctuation">.</span><span class="unresolved_reference">b</span><span class="punctuation">;</span>
<span class="keyword">let</span> <span class="variable declaration">b</span> <span class="operator">=</span> <span class="variable">u</span><span class="punctuation">.</span><span class="field">b</span><span class="punctuation">;</span>
<span class="keyword control">match</span> <span class="variable">u</span> <span class="punctuation">{</span>
<span class="union">Union</span> <span class="punctuation">{</span> <span class="unresolved_reference">b</span><span class="punctuation">:</span> <span class="numeric_literal">0</span> <span class="punctuation">}</span> <span class="operator">=&gt;</span> <span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">,</span>
<span class="union">Union</span> <span class="punctuation">{</span> <span class="variable declaration">a</span> <span class="punctuation">}</span> <span class="operator">=&gt;</span> <span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">,</span>
<span class="union">Union</span> <span class="punctuation">{</span> <span class="field">b</span><span class="punctuation">:</span> <span class="numeric_literal">0</span> <span class="punctuation">}</span> <span class="operator">=&gt;</span> <span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">,</span>
<span class="union">Union</span> <span class="punctuation">{</span> <span class="field">a</span> <span class="punctuation">}</span> <span class="operator">=&gt;</span> <span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">,</span>
<span class="punctuation">}</span>
<span class="struct">HasUnsafeFn</span><span class="punctuation">.</span><span class="function unsafe">unsafe_method</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span>
<span class="keyword">let</span> <span class="variable declaration">y</span> <span class="operator">=</span> <span class="operator unsafe">*</span><span class="punctuation">(</span><span class="variable">x</span><span class="punctuation">)</span><span class="punctuation">;</span>