84
84
*
85
85
*/
86
86
87
- import syntax:: { ast, ast_util, visit} ;
87
+ import syntax:: { ast, ast_util, visit, codemap } ;
88
88
import std:: { vec, option, str} ;
89
89
import ast:: { kind, kind_unique, kind_shared, kind_pinned} ;
90
90
@@ -122,12 +122,18 @@ fn need_expr_kind(tcx: ty::ctxt, e: @ast::expr, k_need: ast::kind,
122
122
kind_to_str ( k_need) , kind_to_str ( tk. kind ) ,
123
123
util:: ppaux:: ty_to_str ( tcx, tk. ty ) ] ;
124
124
125
- if !kind_lteq ( k_need, tk. kind ) {
125
+ demand_kind ( tcx, e. span , tk. ty , k_need, descr) ;
126
+ }
127
+
128
+ fn demand_kind ( tcx : ty:: ctxt , sp : codemap:: span , t : ty:: t ,
129
+ k_need : ast:: kind , descr : str ) {
130
+ let k = ty:: type_kind ( tcx, t) ;
131
+ if !kind_lteq ( k_need, k) {
126
132
let s =
127
133
#fmt[ "mismatched kinds for %s: needed %s type, got %s type %s" ,
128
- descr, kind_to_str ( k_need) , kind_to_str ( tk . kind ) ,
129
- util:: ppaux:: ty_to_str ( tcx, tk . ty ) ] ;
130
- tcx. sess . span_err ( e . span , s) ;
134
+ descr, kind_to_str ( k_need) , kind_to_str ( k ) ,
135
+ util:: ppaux:: ty_to_str ( tcx, t ) ] ;
136
+ tcx. sess . span_err ( sp , s) ;
131
137
}
132
138
}
133
139
@@ -136,16 +142,30 @@ fn need_shared_lhs_rhs(tcx: ty::ctxt, a: @ast::expr, b: @ast::expr, op: str) {
136
142
need_expr_kind ( tcx, b, ast:: kind_shared, op + " rhs" ) ;
137
143
}
138
144
145
+ // Additional checks for copyability that require a little more nuance
146
+ fn check_copy ( tcx : ty:: ctxt , e : @ast:: expr ) {
147
+ alt ty:: struct ( tcx, ty:: expr_ty ( tcx, e) ) {
148
+ // Unique boxes most not contain pinned kinds
149
+ ty:: ty_uniq ( mt) {
150
+ demand_kind ( tcx, e. span , mt. ty , ast:: kind_shared,
151
+ "unique box interior" ) ;
152
+ }
153
+ _ { }
154
+ }
155
+ }
156
+
139
157
fn check_expr ( tcx : ty:: ctxt , e : @ast:: expr ) {
140
158
alt e. node {
141
159
142
- // FIXME: These rules do not implement the copy type-constructor
143
- // discrimination described by the block comment at the top of
144
- // this file. This code is wrong; it lets you copy anything
145
- // shared-kind.
160
+ // FIXME: These rules do not fully implement the copy type-constructor
161
+ // discrimination described by the block comment at the top of this
162
+ // file. This code is wrong; it lets you copy anything shared-kind.
146
163
147
164
ast:: expr_move ( a, b) { need_shared_lhs_rhs ( tcx, a, b, "<-" ) ; }
148
- ast:: expr_assign ( a, b) { need_shared_lhs_rhs ( tcx, a, b, "=" ) ; }
165
+ ast:: expr_assign ( a, b) {
166
+ need_shared_lhs_rhs ( tcx, a, b, "=" ) ;
167
+ check_copy ( tcx, b) ;
168
+ }
149
169
ast:: expr_assign_op ( _, a, b) { need_shared_lhs_rhs ( tcx, a, b, "op=" ) ; }
150
170
ast:: expr_swap ( a, b) { need_shared_lhs_rhs ( tcx, a, b, "<->" ) ; }
151
171
ast:: expr_copy ( a) {
@@ -174,15 +194,8 @@ fn check_expr(tcx: ty::ctxt, e: @ast::expr) {
174
194
assert ( vec:: len ( item_tk. kinds ) == vec:: len ( tpt. params ) ) ;
175
195
for k_need: ast:: kind in item_tk. kinds {
176
196
let t = tpt. params [ i] ;
177
- let k = ty:: type_kind ( tcx, t) ;
178
- if !kind_lteq ( k_need, k) {
179
- let s =
180
- #fmt[ "mismatched kinds for typaram %d: \
181
- needed %s type, got %s type %s",
182
- i, kind_to_str ( k_need) , kind_to_str ( k) ,
183
- util:: ppaux:: ty_to_str ( tcx, t) ] ;
184
- tcx. sess . span_err ( e. span , s) ;
185
- }
197
+ demand_kind ( tcx, e. span , t, k_need,
198
+ #fmt ( "typaram %d" , i) ) ;
186
199
i += 1 ;
187
200
}
188
201
}
0 commit comments