@@ -171,7 +171,7 @@ fn with_appropriate_checker(cx: Context, id: node_id,
171
171
// check that only immutable variables are implicitly copied in
172
172
check_imm_free_var ( cx, fv. def , fv. span ) ;
173
173
174
- check_freevar_bounds ( cx, fv. span , var_t, bounds) ;
174
+ check_freevar_bounds ( cx, fv. span , var_t, bounds, None ) ;
175
175
}
176
176
177
177
fn check_for_box ( cx : Context , fv : & freevar_entry , bounds : ty:: BuiltinBounds ) {
@@ -182,13 +182,18 @@ fn with_appropriate_checker(cx: Context, id: node_id,
182
182
// check that only immutable variables are implicitly copied in
183
183
check_imm_free_var ( cx, fv. def , fv. span ) ;
184
184
185
- check_freevar_bounds ( cx, fv. span , var_t, bounds) ;
185
+ check_freevar_bounds ( cx, fv. span , var_t, bounds, None ) ;
186
186
}
187
187
188
- fn check_for_block ( cx : Context , fv : & freevar_entry , bounds : ty:: BuiltinBounds ) {
188
+ fn check_for_block ( cx : Context , fv : & freevar_entry ,
189
+ bounds : ty:: BuiltinBounds , region : ty:: Region ) {
189
190
let id = ast_util:: def_id_of_def ( fv. def ) . node ;
190
191
let var_t = ty:: node_id_to_type ( cx. tcx , id) ;
191
- check_freevar_bounds ( cx, fv. span , var_t, bounds) ;
192
+ // FIXME(#3569): Figure out whether the implicit borrow is actually
193
+ // mutable. Currently we assume all upvars are referenced mutably.
194
+ let implicit_borrowed_type = ty:: mk_mut_rptr ( cx. tcx , region, var_t) ;
195
+ check_freevar_bounds ( cx, fv. span , implicit_borrowed_type,
196
+ bounds, Some ( var_t) ) ;
192
197
}
193
198
194
199
fn check_for_bare ( cx : Context , fv : @freevar_entry ) {
@@ -205,8 +210,9 @@ fn with_appropriate_checker(cx: Context, id: node_id,
205
210
ty:: ty_closure( ty:: ClosureTy { sigil : ManagedSigil , bounds : bounds, _} ) => {
206
211
b ( |cx, fv| check_for_box ( cx, fv, bounds) )
207
212
}
208
- ty:: ty_closure( ty:: ClosureTy { sigil : BorrowedSigil , bounds : bounds, _} ) => {
209
- b ( |cx, fv| check_for_block ( cx, fv, bounds) )
213
+ ty:: ty_closure( ty:: ClosureTy { sigil : BorrowedSigil , bounds : bounds,
214
+ region : region, _} ) => {
215
+ b ( |cx, fv| check_for_block ( cx, fv, bounds, region) )
210
216
}
211
217
ty:: ty_bare_fn( _) => {
212
218
b ( check_for_bare)
@@ -366,14 +372,21 @@ pub fn check_typaram_bounds(cx: Context,
366
372
}
367
373
368
374
pub fn check_freevar_bounds( cx: Context , sp: span, ty: ty:: t,
369
- bounds: ty:: BuiltinBounds )
375
+ bounds: ty:: BuiltinBounds , referenced_ty : Option <ty :: t> )
370
376
{
371
377
do check_builtin_bounds( cx, ty, bounds) |missing| {
372
- cx. tcx. sess. span_err(
373
- sp,
374
- fmt ! ( "cannot capture variable of type `%s`, which does not fulfill \
375
- `%s`, in a bounded closure",
376
- ty_to_str( cx. tcx, ty) , missing. user_string( cx. tcx) ) ) ;
378
+ // Will be Some if the freevar is implicitly borrowed (stack closure).
379
+ // Emit a less mysterious error message in this case.
380
+ match referenced_ty {
381
+ Some ( rty) => cx. tcx. sess. span_err( sp,
382
+ fmt ! ( "cannot implicitly borrow variable of type `%s` in a bounded \
383
+ stack closure (implicit reference does not fulfill `%s`)",
384
+ ty_to_str( cx. tcx, rty) , missing. user_string( cx. tcx) ) ) ,
385
+ None => cx. tcx. sess. span_err( sp,
386
+ fmt ! ( "cannot capture variable of type `%s`, which does \
387
+ not fulfill `%s`, in a bounded closure",
388
+ ty_to_str( cx. tcx, ty) , missing. user_string( cx. tcx) ) ) ,
389
+ }
377
390
cx. tcx. sess. span_note(
378
391
sp,
379
392
fmt ! ( "this closure's environment must satisfy `%s`" ,
0 commit comments