@@ -116,6 +116,7 @@ use syntax::ast;
116116use syntax:: attr;
117117use syntax:: attr:: AttrMetaMethods ;
118118use syntax:: codemap:: { self , Spanned } ;
119+ use syntax:: feature_gate:: { GateIssue , emit_feature_err} ;
119120use syntax:: parse:: token:: { self , InternedString , keywords} ;
120121use syntax:: ptr:: P ;
121122use syntax:: util:: lev_distance:: find_best_match_for_name;
@@ -1700,7 +1701,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
17001701 node_id : ast:: NodeId )
17011702 -> Ty < ' tcx > {
17021703 debug ! ( "instantiate_type_path(did={:?}, path={:?})" , did, path) ;
1703- let type_scheme = self . tcx . lookup_item_type ( did) ;
1704+ let mut type_scheme = self . tcx . lookup_item_type ( did) ;
1705+ if type_scheme. ty . is_fn ( ) {
1706+ // Tuple variants have fn type even in type namespace, extract true variant type from it
1707+ let fn_ret = self . tcx . no_late_bound_regions ( & type_scheme. ty . fn_ret ( ) ) . unwrap ( ) . unwrap ( ) ;
1708+ type_scheme = ty:: TypeScheme { ty : fn_ret, generics : type_scheme. generics }
1709+ }
17041710 let type_predicates = self . tcx . lookup_predicates ( did) ;
17051711 let substs = AstConv :: ast_path_substs_for_ty ( self , self ,
17061712 path. span ,
@@ -3244,19 +3250,24 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
32443250 }
32453251 _ => None
32463252 } ;
3247- if variant. is_none ( ) || variant. unwrap ( ) . kind == ty:: VariantKind :: Tuple {
3248- // Reject tuple structs for now, braced and unit structs are allowed.
3253+
3254+ if let Some ( variant) = variant {
3255+ if variant. kind == ty:: VariantKind :: Tuple &&
3256+ !self . tcx . sess . features . borrow ( ) . relaxed_adts {
3257+ emit_feature_err ( & self . tcx . sess . parse_sess . span_diagnostic ,
3258+ "relaxed_adts" , span, GateIssue :: Language ,
3259+ "tuple structs and variants in struct patterns are unstable" ) ;
3260+ }
3261+ let ty = self . instantiate_type_path ( def. def_id ( ) , path, node_id) ;
3262+ Some ( ( variant, ty) )
3263+ } else {
32493264 struct_span_err ! ( self . tcx. sess, path. span, E0071 ,
32503265 "`{}` does not name a struct or a struct variant" ,
32513266 pprust:: path_to_string( path) )
32523267 . span_label ( path. span , & format ! ( "not a struct" ) )
32533268 . emit ( ) ;
3254-
3255- return None ;
3269+ None
32563270 }
3257-
3258- let ty = self . instantiate_type_path ( def. def_id ( ) , path, node_id) ;
3259- Some ( ( variant. unwrap ( ) , ty) )
32603271 }
32613272
32623273 fn check_expr_struct ( & self ,
0 commit comments