Skip to content

Commit

Permalink
Fixed type inference for tuple struct variants.
Browse files Browse the repository at this point in the history
  • Loading branch information
Alexander Regueiro committed Dec 26, 2018
1 parent fa07e62 commit 6a3f96d
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 21 deletions.
2 changes: 1 addition & 1 deletion src/librustc_typeck/astconv.rs
Expand Up @@ -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)
Expand Down
17 changes: 11 additions & 6 deletions src/librustc_typeck/check/mod.rs
Expand Up @@ -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;
Expand Down Expand Up @@ -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 {
Expand Down
15 changes: 1 addition & 14 deletions src/test/run-pass/enum-variant-generic-args.rs
Expand Up @@ -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<()>;
Expand All @@ -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

Expand All @@ -38,8 +29,6 @@ fn main() {

is_variant!(TSVariant, AliasFixed::TSVariant(()));

Enum::<()>::ts_variant();

// Struct variant

is_variant!(SVariant, Enum::SVariant { v: () });
Expand All @@ -50,6 +39,4 @@ fn main() {
is_variant!(SVariant, Alias::<()>::SVariant { v: () });

is_variant!(SVariant, AliasFixed::SVariant { v: () });

Enum::<()>::s_variant();
}
4 changes: 4 additions & 0 deletions src/test/ui/enum-variant-generic-args.rs
Expand Up @@ -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(());
Expand All @@ -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]
Expand Down

0 comments on commit 6a3f96d

Please sign in to comment.