@@ -171,7 +171,7 @@ fn with_appropriate_checker(cx: Context, id: node_id,
171171 // check that only immutable variables are implicitly copied in
172172 check_imm_free_var ( cx, fv. def , fv. span ) ;
173173
174- check_freevar_bounds ( cx, fv. span , var_t, bounds) ;
174+ check_freevar_bounds ( cx, fv. span , var_t, bounds, None ) ;
175175 }
176176
177177 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,
182182 // check that only immutable variables are implicitly copied in
183183 check_imm_free_var ( cx, fv. def , fv. span ) ;
184184
185- check_freevar_bounds ( cx, fv. span , var_t, bounds) ;
185+ check_freevar_bounds ( cx, fv. span , var_t, bounds, None ) ;
186186 }
187187
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 ) {
189190 let id = ast_util:: def_id_of_def ( fv. def ) . node ;
190191 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) ) ;
192197 }
193198
194199 fn check_for_bare ( cx : Context , fv : @freevar_entry ) {
@@ -205,8 +210,9 @@ fn with_appropriate_checker(cx: Context, id: node_id,
205210 ty:: ty_closure( ty:: ClosureTy { sigil : ManagedSigil , bounds : bounds, _} ) => {
206211 b ( |cx, fv| check_for_box ( cx, fv, bounds) )
207212 }
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) )
210216 }
211217 ty:: ty_bare_fn( _) => {
212218 b ( check_for_bare)
@@ -366,14 +372,21 @@ pub fn check_typaram_bounds(cx: Context,
366372}
367373
368374pub fn check_freevar_bounds( cx: Context , sp: span, ty: ty:: t,
369- bounds: ty:: BuiltinBounds )
375+ bounds: ty:: BuiltinBounds , referenced_ty : Option <ty :: t> )
370376{
371377 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+ }
377390 cx. tcx. sess. span_note(
378391 sp,
379392 fmt ! ( "this closure's environment must satisfy `%s`" ,
0 commit comments