@@ -303,7 +303,7 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:region_scope + Copy + 'static>(
303
303
ty:: BoxTraitStore
304
304
}
305
305
} ;
306
- let bounds = conv_builtin_bounds ( this. tcx ( ) , bounds) ;
306
+ let bounds = conv_builtin_bounds ( this. tcx ( ) , bounds, trait_store ) ;
307
307
return ty:: mk_trait ( tcx,
308
308
result. def_id ,
309
309
copy result. substs ,
@@ -386,7 +386,13 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:region_scope + Copy + 'static>(
386
386
bf. abis , & bf. lifetimes , & bf. decl ) )
387
387
}
388
388
ast:: ty_closure( ref f) => {
389
- let bounds = conv_builtin_bounds ( this. tcx ( ) , & f. bounds ) ;
389
+ let bounds = conv_builtin_bounds ( this. tcx ( ) , & f. bounds , match f. sigil {
390
+ // Use corresponding trait store to figure out default bounds
391
+ // if none were specified.
392
+ ast:: BorrowedSigil => ty:: RegionTraitStore ( ty:: re_empty) , // dummy region
393
+ ast:: OwnedSigil => ty:: UniqTraitStore ,
394
+ ast:: ManagedSigil => ty:: BoxTraitStore ,
395
+ } ) ;
390
396
let fn_decl = ty_of_closure ( this,
391
397
rscope,
392
398
f. sigil ,
@@ -411,7 +417,7 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:region_scope + Copy + 'static>(
411
417
match a_def {
412
418
// But don't emit the error if the user meant to do a trait anyway.
413
419
ast:: def_trait( * ) => { } ,
414
- _ if ! bounds. is_empty ( ) =>
420
+ _ if bounds. is_some ( ) =>
415
421
tcx. sess . span_err ( ast_ty. span ,
416
422
"kind bounds can only be used on trait types" ) ,
417
423
_ => { } ,
@@ -741,41 +747,60 @@ pub fn ty_of_closure<AC:AstConv,RS:region_scope + Copy + 'static>(
741
747
}
742
748
}
743
749
744
- fn conv_builtin_bounds ( tcx : ty:: ctxt ,
745
- ast_bounds : & OptVec < ast :: TyParamBound > )
750
+ fn conv_builtin_bounds ( tcx : ty:: ctxt , ast_bounds : & Option < OptVec < ast :: TyParamBound > > ,
751
+ store : ty :: TraitStore )
746
752
-> ty:: BuiltinBounds {
747
753
//! Converts a list of bounds from the AST into a `BuiltinBounds`
748
754
//! struct. Reports an error if any of the bounds that appear
749
755
//! in the AST refer to general traits and not the built-in traits
750
756
//! like `Copy` or `Owned`. Used to translate the bounds that
751
757
//! appear in closure and trait types, where only builtin bounds are
752
758
//! legal.
753
-
754
- let mut builtin_bounds = ty:: EmptyBuiltinBounds ( ) ;
755
- for ast_bounds. iter( ) . advance |ast_bound| {
756
- match * ast_bound {
757
- ast : : TraitTyParamBound ( b) => {
758
- match lookup_def_tcx ( tcx, b. path . span , b. ref_id ) {
759
- ast:: def_trait( trait_did) => {
760
- if try_add_builtin_trait ( tcx,
761
- trait_did,
762
- & mut builtin_bounds) {
763
- loop ; // success
759
+ //! If no bounds were specified, we choose a "default" bound based on
760
+ //! the allocation type of the fn/trait, as per issue #7264. The user can
761
+ //! override this with an empty bounds list, e.g. "~fn:()" or "~Trait:".
762
+
763
+ match ( ast_bounds, store) {
764
+ ( & Some ( ref bound_vec) , _) => {
765
+ let mut builtin_bounds = ty:: EmptyBuiltinBounds ( ) ;
766
+ for bound_vec. iter( ) . advance |ast_bound| {
767
+ match * ast_bound {
768
+ ast : : TraitTyParamBound ( b) => {
769
+ match lookup_def_tcx ( tcx, b. path . span , b. ref_id ) {
770
+ ast:: def_trait( trait_did) => {
771
+ if try_add_builtin_trait ( tcx,
772
+ trait_did,
773
+ & mut builtin_bounds) {
774
+ loop ; // success
775
+ }
776
+ }
777
+ _ => { }
764
778
}
779
+ tcx. sess . span_fatal (
780
+ b. path . span ,
781
+ fmt ! ( "only the builtin traits can be used \
782
+ as closure or object bounds") ) ;
783
+ }
784
+ ast:: RegionTyParamBound => {
785
+ builtin_bounds. add ( ty:: BoundStatic ) ;
765
786
}
766
- _ => { }
767
787
}
768
- tcx. sess . span_fatal (
769
- b. path . span ,
770
- fmt ! ( "only the builtin traits can be used \
771
- as closure or object bounds") ) ;
772
- }
773
- ast:: RegionTyParamBound => {
774
- builtin_bounds. add ( ty:: BoundStatic ) ;
775
788
}
789
+ builtin_bounds
790
+ } ,
791
+ // ~Trait is sugar for ~Trait:Owned.
792
+ ( & None , ty:: UniqTraitStore ) => {
793
+ let mut set = ty:: EmptyBuiltinBounds ( ) ; set. add ( ty:: BoundOwned ) ; set
794
+ }
795
+ // @Trait is sugar for @Trait:'static.
796
+ // &'static Trait is sugar for &'static Trait:'static.
797
+ ( & None , ty:: BoxTraitStore ) |
798
+ ( & None , ty:: RegionTraitStore ( ty:: re_static) ) => {
799
+ let mut set = ty:: EmptyBuiltinBounds ( ) ; set. add ( ty:: BoundStatic ) ; set
776
800
}
801
+ // &'r Trait is sugar for &'r Trait:<no-bounds>.
802
+ ( & None , ty:: RegionTraitStore ( * ) ) => ty:: EmptyBuiltinBounds ( ) ,
777
803
}
778
- builtin_bounds
779
804
}
780
805
781
806
pub fn try_add_builtin_trait ( tcx : ty:: ctxt ,
0 commit comments