155
155
//!
156
156
//! ```{.text}
157
157
//! EnumNonMatchingCollapsed(
158
- //! vec![<ident of self>, <ident of __arg_1>],
158
+ //! vec![<ast::Expr for self>, <ast::Expr for __arg_1>],
159
159
//! &[<ast::Variant for C0>, <ast::Variant for C1>],
160
160
//! &[<ident for self index value>, <ident of __arg_1 index value>])
161
161
//! ```
@@ -203,7 +203,6 @@ use ext::build::AstBuilder;
203
203
use codemap:: { self , DUMMY_SP } ;
204
204
use codemap:: Span ;
205
205
use diagnostic:: SpanHandler ;
206
- use fold:: MoveMap ;
207
206
use owned_slice:: OwnedSlice ;
208
207
use parse:: token:: InternedString ;
209
208
use parse:: token:: special_idents;
@@ -267,7 +266,7 @@ pub struct Substructure<'a> {
267
266
/// ident of the method
268
267
pub method_ident : Ident ,
269
268
/// dereferenced access to any `Self_` or `Ptr(Self_, _)` arguments
270
- pub self_args : & ' a [ P < Expr > ] ,
269
+ pub self_args : & ' a [ ( P < Expr > , ast :: Mutability ) ] ,
271
270
/// verbatim access to any other arguments
272
271
pub nonself_args : & ' a [ P < Expr > ] ,
273
272
pub fields : & ' a SubstructureFields < ' a >
@@ -311,7 +310,7 @@ pub enum SubstructureFields<'a> {
311
310
/// variants for the enum itself, and the third component is a list of
312
311
/// `Ident`s bound to the variant index values for each of the actual
313
312
/// input `Self` arguments.
314
- EnumNonMatchingCollapsed ( Vec < Ident > , & ' a [ P < ast:: Variant > ] , & ' a [ Ident ] ) ,
313
+ EnumNonMatchingCollapsed ( Vec < P < ast :: Expr > > , & ' a [ P < ast:: Variant > ] , & ' a [ Ident ] ) ,
315
314
316
315
/// A static method where `Self` is a struct.
317
316
StaticStruct ( & ' a ast:: StructDef , StaticFields ) ,
@@ -332,7 +331,7 @@ pub type CombineSubstructureFunc<'a> =
332
331
/// holding the variant index value for each of the `Self` arguments. The
333
332
/// last argument is all the non-`Self` args of the method being derived.
334
333
pub type EnumNonMatchCollapsedFunc < ' a > =
335
- Box < FnMut ( & mut ExtCtxt , Span , ( & [ Ident ] , & [ Ident ] ) , & [ P < Expr > ] ) -> P < Expr > + ' a > ;
334
+ Box < FnMut ( & mut ExtCtxt , Span , ( & [ P < Expr > ] , & [ Ident ] ) , & [ P < Expr > ] ) -> P < Expr > + ' a > ;
336
335
337
336
pub fn combine_substructure < ' a > ( f : CombineSubstructureFunc < ' a > )
338
337
-> RefCell < CombineSubstructureFunc < ' a > > {
@@ -764,7 +763,7 @@ impl<'a> MethodDef<'a> {
764
763
cx : & mut ExtCtxt ,
765
764
trait_ : & TraitDef ,
766
765
type_ident : Ident ,
767
- self_args : & [ P < Expr > ] ,
766
+ self_args : & [ ( P < Expr > , ast :: Mutability ) ] ,
768
767
nonself_args : & [ P < Expr > ] ,
769
768
fields : & SubstructureFields )
770
769
-> P < Expr > {
@@ -798,7 +797,7 @@ impl<'a> MethodDef<'a> {
798
797
trait_ : & TraitDef ,
799
798
type_ident : Ident ,
800
799
generics : & Generics )
801
- -> ( ast:: ExplicitSelf , Vec < P < Expr > > , Vec < P < Expr > > , Vec < ( Ident , P < ast:: Ty > ) > ) {
800
+ -> ( ast:: ExplicitSelf , Vec < ( P < Expr > , ast :: Mutability ) > , Vec < P < Expr > > , Vec < ( Ident , P < ast:: Ty > ) > ) {
802
801
803
802
let mut self_args = Vec :: new ( ) ;
804
803
let mut nonself_args = Vec :: new ( ) ;
@@ -807,10 +806,10 @@ impl<'a> MethodDef<'a> {
807
806
808
807
let ast_explicit_self = match self . explicit_self {
809
808
Some ( ref self_ptr) => {
810
- let ( self_expr, explicit_self) =
809
+ let ( self_expr, mutability , explicit_self) =
811
810
ty:: get_explicit_self ( cx, trait_. span , self_ptr) ;
812
811
813
- self_args. push ( self_expr) ;
812
+ self_args. push ( ( self_expr, mutability ) ) ;
814
813
nonstatic = true ;
815
814
816
815
explicit_self
@@ -829,10 +828,13 @@ impl<'a> MethodDef<'a> {
829
828
// for static methods, just treat any Self
830
829
// arguments as a normal arg
831
830
Self_ if nonstatic => {
832
- self_args. push ( arg_expr) ;
831
+ self_args. push ( ( arg_expr, ast :: MutImmutable ) ) ;
833
832
}
834
- Ptr ( ref ty, _) if * * ty == Self_ && nonstatic => {
835
- self_args. push ( cx. expr_deref ( trait_. span , arg_expr) )
833
+ Ptr ( ref ty, ref ty_ptr) if * * ty == Self_ && nonstatic => {
834
+ let mutability = match ty_ptr {
835
+ & ty:: Borrowed ( _, m) | & ty:: Raw ( m) => m
836
+ } ;
837
+ self_args. push ( ( cx. expr_deref ( trait_. span , arg_expr) , mutability) )
836
838
}
837
839
_ => {
838
840
nonself_args. push ( arg_expr) ;
@@ -921,7 +923,7 @@ impl<'a> MethodDef<'a> {
921
923
trait_ : & TraitDef < ' b > ,
922
924
struct_def : & ' b StructDef ,
923
925
type_ident : Ident ,
924
- self_args : & [ P < Expr > ] ,
926
+ self_args : & [ ( P < Expr > , ast :: Mutability ) ] ,
925
927
nonself_args : & [ P < Expr > ] )
926
928
-> P < Expr > {
927
929
@@ -936,7 +938,7 @@ impl<'a> MethodDef<'a> {
936
938
struct_def,
937
939
& format ! ( "__self_{}" ,
938
940
i) ,
939
- ast :: MutImmutable ) ;
941
+ self_args [ i ] . 1 ) ;
940
942
patterns. push ( pat) ;
941
943
raw_fields. push ( ident_expr) ;
942
944
}
@@ -978,7 +980,7 @@ impl<'a> MethodDef<'a> {
978
980
// make a series of nested matches, to destructure the
979
981
// structs. This is actually right-to-left, but it shouldn't
980
982
// matter.
981
- for ( arg_expr, pat) in self_args. iter ( ) . zip ( patterns) {
983
+ for ( & ( ref arg_expr, _ ) , ref pat) in self_args. iter ( ) . zip ( patterns) {
982
984
body = cx. expr_match ( trait_. span , arg_expr. clone ( ) ,
983
985
vec ! ( cx. arm( trait_. span, vec!( pat. clone( ) ) , body) ) )
984
986
}
@@ -990,7 +992,7 @@ impl<'a> MethodDef<'a> {
990
992
trait_ : & TraitDef ,
991
993
struct_def : & StructDef ,
992
994
type_ident : Ident ,
993
- self_args : & [ P < Expr > ] ,
995
+ self_args : & [ ( P < Expr > , ast :: Mutability ) ] ,
994
996
nonself_args : & [ P < Expr > ] )
995
997
-> P < Expr > {
996
998
let summary = trait_. summarise_struct ( cx, struct_def) ;
@@ -1037,7 +1039,7 @@ impl<'a> MethodDef<'a> {
1037
1039
enum_def : & ' b EnumDef ,
1038
1040
type_attrs : & [ ast:: Attribute ] ,
1039
1041
type_ident : Ident ,
1040
- self_args : Vec < P < Expr > > ,
1042
+ self_args : Vec < ( P < Expr > , ast :: Mutability ) > ,
1041
1043
nonself_args : & [ P < Expr > ] )
1042
1044
-> P < Expr > {
1043
1045
self . build_enum_match_tuple (
@@ -1087,39 +1089,35 @@ impl<'a> MethodDef<'a> {
1087
1089
enum_def : & ' b EnumDef ,
1088
1090
type_attrs : & [ ast:: Attribute ] ,
1089
1091
type_ident : Ident ,
1090
- self_args : Vec < P < Expr > > ,
1092
+ self_args : Vec < ( P < Expr > , ast :: Mutability ) > ,
1091
1093
nonself_args : & [ P < Expr > ] ) -> P < Expr > {
1092
1094
1093
1095
let sp = trait_. span ;
1094
1096
let variants = & enum_def. variants ;
1095
1097
1096
1098
let self_arg_names = self_args. iter ( ) . enumerate ( )
1097
- . map ( |( arg_count, _self_arg ) | {
1099
+ . map ( |( arg_count, & ( _ , mutability ) ) | {
1098
1100
if arg_count == 0 {
1099
- "__self" . to_string ( )
1101
+ ( "__self" . to_string ( ) , mutability )
1100
1102
} else {
1101
- format ! ( "__arg_{}" , arg_count)
1103
+ ( format ! ( "__arg_{}" , arg_count- 1 ) , mutability )
1102
1104
}
1103
1105
} )
1104
- . collect :: < Vec < String > > ( ) ;
1105
-
1106
- let self_arg_idents = self_arg_names. iter ( )
1107
- . map ( |name|cx. ident_of ( & name[ ..] ) )
1108
- . collect :: < Vec < ast:: Ident > > ( ) ;
1106
+ . collect :: < Vec < ( String , ast:: Mutability ) > > ( ) ;
1109
1107
1110
1108
// The `vi_idents` will be bound, solely in the catch-all, to
1111
1109
// a series of let statements mapping each self_arg to an int
1112
1110
// value corresponding to its discriminant.
1113
1111
let vi_idents: Vec < ast:: Ident > = self_arg_names. iter ( )
1114
- . map ( |name| { let vi_suffix = format ! ( "{}_vi" , & name[ ..] ) ;
1112
+ . map ( |& ( ref name, _ ) | { let vi_suffix = format ! ( "{}_vi" , & name[ ..] ) ;
1115
1113
cx. ident_of ( & vi_suffix[ ..] ) } )
1116
1114
. collect :: < Vec < ast:: Ident > > ( ) ;
1117
1115
1118
1116
// Builds, via callback to call_substructure_method, the
1119
1117
// delegated expression that handles the catch-all case,
1120
1118
// using `__variants_tuple` to drive logic if necessary.
1121
1119
let catch_all_substructure = EnumNonMatchingCollapsed (
1122
- self_arg_idents , & variants[ ..] , & vi_idents[ ..] ) ;
1120
+ self_args . iter ( ) . map ( | & ( ref expr , _ ) | expr . clone ( ) ) . collect ( ) , & variants[ ..] , & vi_idents[ ..] ) ;
1123
1121
1124
1122
// These arms are of the form:
1125
1123
// (Variant1, Variant1, ...) => Body1
@@ -1128,12 +1126,12 @@ impl<'a> MethodDef<'a> {
1128
1126
// where each tuple has length = self_args.len()
1129
1127
let mut match_arms: Vec < ast:: Arm > = variants. iter ( ) . enumerate ( )
1130
1128
. map ( |( index, variant) | {
1131
- let mk_self_pat = |cx : & mut ExtCtxt , self_arg_name : & str | {
1129
+ let mk_self_pat = |cx : & mut ExtCtxt , self_arg_name : & ( String , ast :: Mutability ) | {
1132
1130
let ( p, idents) = trait_. create_enum_variant_pattern ( cx, type_ident,
1133
1131
& * * variant,
1134
- self_arg_name,
1135
- ast :: MutImmutable ) ;
1136
- ( cx. pat ( sp, ast:: PatRegion ( p, ast :: MutImmutable ) ) , idents)
1132
+ & self_arg_name. 0 [ .. ] ,
1133
+ self_arg_name . 1 ) ;
1134
+ ( cx. pat ( sp, ast:: PatRegion ( p, self_arg_name . 1 ) ) , idents)
1137
1135
} ;
1138
1136
1139
1137
// A single arm has form (&VariantK, &VariantK, ...) => BodyK
@@ -1146,7 +1144,7 @@ impl<'a> MethodDef<'a> {
1146
1144
idents
1147
1145
} ;
1148
1146
for self_arg_name in & self_arg_names[ 1 ..] {
1149
- let ( p, idents) = mk_self_pat ( cx, & self_arg_name[ .. ] ) ;
1147
+ let ( p, idents) = mk_self_pat ( cx, self_arg_name) ;
1150
1148
subpats. push ( p) ;
1151
1149
self_pats_idents. push ( idents) ;
1152
1150
}
@@ -1251,7 +1249,7 @@ impl<'a> MethodDef<'a> {
1251
1249
find_repr_type_name ( & cx. parse_sess . span_diagnostic , type_attrs) ;
1252
1250
1253
1251
let mut first_ident = None ;
1254
- for ( & ident, self_arg) in vi_idents. iter ( ) . zip ( & self_args) {
1252
+ for ( & ident, & ( ref self_arg, _ ) ) in vi_idents. iter ( ) . zip ( & self_args) {
1255
1253
let path = cx. std_path ( & [ "intrinsics" , "discriminant_value" ] ) ;
1256
1254
let call = cx. expr_call_global (
1257
1255
sp, path, vec ! [ cx. expr_addr_of( sp, self_arg. clone( ) ) ] ) ;
@@ -1303,7 +1301,12 @@ impl<'a> MethodDef<'a> {
1303
1301
// them when they are fed as r-values into a tuple
1304
1302
// expression; here add a layer of borrowing, turning
1305
1303
// `(*self, *__arg_0, ...)` into `(&*self, &*__arg_0, ...)`.
1306
- let borrowed_self_args = self_args. move_map ( |self_arg| cx. expr_addr_of ( sp, self_arg) ) ;
1304
+ let borrowed_self_args = self_args. into_iter ( ) . map ( |( self_arg, mutability) | {
1305
+ match mutability {
1306
+ ast:: MutImmutable => cx. expr_addr_of ( sp, self_arg) ,
1307
+ ast:: MutMutable => cx. expr_mut_addr_of ( sp, self_arg) ,
1308
+ }
1309
+ } ) . collect ( ) ;
1307
1310
let match_arg = cx. expr ( sp, ast:: ExprTup ( borrowed_self_args) ) ;
1308
1311
1309
1312
//Lastly we create an expression which branches on all discriminants being equal
@@ -1381,7 +1384,12 @@ impl<'a> MethodDef<'a> {
1381
1384
// them when they are fed as r-values into a tuple
1382
1385
// expression; here add a layer of borrowing, turning
1383
1386
// `(*self, *__arg_0, ...)` into `(&*self, &*__arg_0, ...)`.
1384
- let borrowed_self_args = self_args. move_map ( |self_arg| cx. expr_addr_of ( sp, self_arg) ) ;
1387
+ let borrowed_self_args = self_args. into_iter ( ) . map ( |( self_arg, mutability) | {
1388
+ match mutability {
1389
+ ast:: MutImmutable => cx. expr_addr_of ( sp, self_arg) ,
1390
+ ast:: MutMutable => cx. expr_mut_addr_of ( sp, self_arg) ,
1391
+ }
1392
+ } ) . collect ( ) ;
1385
1393
let match_arg = cx. expr ( sp, ast:: ExprTup ( borrowed_self_args) ) ;
1386
1394
cx. expr_match ( sp, match_arg, match_arms)
1387
1395
}
@@ -1392,7 +1400,7 @@ impl<'a> MethodDef<'a> {
1392
1400
trait_ : & TraitDef ,
1393
1401
enum_def : & EnumDef ,
1394
1402
type_ident : Ident ,
1395
- self_args : & [ P < Expr > ] ,
1403
+ self_args : & [ ( P < Expr > , ast :: Mutability ) ] ,
1396
1404
nonself_args : & [ P < Expr > ] )
1397
1405
-> P < Expr > {
1398
1406
let summary = enum_def. variants . iter ( ) . map ( |v| {
0 commit comments