Fixed type inference for tuple struct variants.

This commit is contained in:
Alexander Regueiro 2018-12-20 03:26:07 +00:00
parent fa07e62389
commit 6a3f96d302
4 changed files with 17 additions and 21 deletions

View file

@ -1551,7 +1551,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
// Case 2. Reference to a variant constructor.
Def::Variant(def_id) |
Def::VariantCtor(def_id, ..) => {
let adt_def = self_ty.and_then(|t| t.ty_adt_def());
let adt_def = self_ty.map(|t| t.ty_adt_def().unwrap());
let (generics_def_id, index) = if let Some(adt_def) = adt_def {
debug_assert!(adt_def.is_enum());
(adt_def.did, last)

View file

@ -5079,7 +5079,18 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
let path_segs = AstConv::def_ids_for_path_segments(self, segments, self_ty, def);
let mut user_self_ty = None;
let mut is_alias_variant_ctor = false;
match def {
Def::VariantCtor(_, _) => {
if let Some(self_ty) = self_ty {
let adt_def = self_ty.ty_adt_def().unwrap();
user_self_ty = Some(UserSelfTy {
impl_def_id: adt_def.did,
self_ty,
});
is_alias_variant_ctor = true;
}
}
Def::Method(def_id) |
Def::AssociatedConst(def_id) => {
let container = tcx.associated_item(def_id).container;
@ -5111,12 +5122,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
// provided (if any) into their appropriate spaces. We'll also report
// errors if type parameters are provided in an inappropriate place.
let is_alias_variant_ctor =
match def {
Def::VariantCtor(_, _) if self_ty.is_some() => true,
_ => false,
};
let generic_segs: FxHashSet<_> = path_segs.iter().map(|PathSeg(_, index)| index).collect();
AstConv::prohibit_generics(self, segments.iter().enumerate().filter_map(|(index, seg)| {
if !generic_segs.contains(&index) || is_alias_variant_ctor {

View file

@ -3,6 +3,7 @@
#![allow(irrefutable_let_patterns)]
#[allow(dead_code)]
enum Enum<T> { TSVariant(T), SVariant { v: T } }
type Alias<T> = Enum<T>;
type AliasFixed = Enum<()>;
@ -16,16 +17,6 @@ macro_rules! is_variant {
);
}
impl<T> Enum<T> {
fn ts_variant() {
is_variant!(TSVariant, Self::TSVariant(()));
}
fn s_variant() {
is_variant!(SVariant, Self::SVariant { v: () });
}
}
fn main() {
// Tuple struct variant
@ -38,8 +29,6 @@ fn main() {
is_variant!(TSVariant, AliasFixed::TSVariant(()));
Enum::<()>::ts_variant();
// Struct variant
is_variant!(SVariant, Enum::SVariant { v: () });
@ -50,6 +39,4 @@ fn main() {
is_variant!(SVariant, Alias::<()>::SVariant { v: () });
is_variant!(SVariant, AliasFixed::SVariant { v: () });
Enum::<()>::s_variant();
}

View file

@ -6,6 +6,8 @@ type AliasFixed = Enum<()>;
impl<T> Enum<T> {
fn ts_variant() {
Self::TSVariant(());
//~^ ERROR type parameters are not allowed on this name [E0109]
Self::TSVariant::<()>(());
//~^ ERROR type arguments are not allowed on this entity [E0109]
Self::<()>::TSVariant(());
@ -16,6 +18,8 @@ impl<T> Enum<T> {
}
fn s_variant() {
Self::SVariant { v: () };
//~^ ERROR type parameters are not allowed on this name [E0109]
Self::SVariant::<()> { v: () };
//~^ ERROR type arguments are not allowed on this entity [E0109]
//~^^ ERROR mismatched types [E0308]