@@ -116,6 +116,7 @@ use syntax::ast;
116
116
use syntax:: attr;
117
117
use syntax:: attr:: AttrMetaMethods ;
118
118
use syntax:: codemap:: { self , Spanned } ;
119
+ use syntax:: feature_gate:: { GateIssue , emit_feature_err} ;
119
120
use syntax:: parse:: token:: { self , InternedString , keywords} ;
120
121
use syntax:: ptr:: P ;
121
122
use syntax:: util:: lev_distance:: find_best_match_for_name;
@@ -1700,7 +1701,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
1700
1701
node_id : ast:: NodeId )
1701
1702
-> Ty < ' tcx > {
1702
1703
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
+ }
1704
1710
let type_predicates = self . tcx . lookup_predicates ( did) ;
1705
1711
let substs = AstConv :: ast_path_substs_for_ty ( self , self ,
1706
1712
path. span ,
@@ -3244,19 +3250,24 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
3244
3250
}
3245
3251
_ => None
3246
3252
} ;
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 {
3249
3264
struct_span_err ! ( self . tcx. sess, path. span, E0071 ,
3250
3265
"`{}` does not name a struct or a struct variant" ,
3251
3266
pprust:: path_to_string( path) )
3252
3267
. span_label ( path. span , & format ! ( "not a struct" ) )
3253
3268
. emit ( ) ;
3254
-
3255
- return None ;
3269
+ None
3256
3270
}
3257
-
3258
- let ty = self . instantiate_type_path ( def. def_id ( ) , path, node_id) ;
3259
- Some ( ( variant. unwrap ( ) , ty) )
3260
3271
}
3261
3272
3262
3273
fn check_expr_struct ( & self ,
0 commit comments