@@ -303,7 +303,7 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:region_scope + Copy + 'static>(
303303 ty:: BoxTraitStore
304304 }
305305 } ;
306- let bounds = conv_builtin_bounds ( this. tcx ( ) , bounds) ;
306+ let bounds = conv_builtin_bounds ( this. tcx ( ) , bounds, trait_store ) ;
307307 return ty:: mk_trait ( tcx,
308308 result. def_id ,
309309 copy result. substs ,
@@ -386,7 +386,13 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:region_scope + Copy + 'static>(
386386 bf. abis , & bf. lifetimes , & bf. decl ) )
387387 }
388388 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+ } ) ;
390396 let fn_decl = ty_of_closure ( this,
391397 rscope,
392398 f. sigil ,
@@ -411,7 +417,7 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:region_scope + Copy + 'static>(
411417 match a_def {
412418 // But don't emit the error if the user meant to do a trait anyway.
413419 ast:: def_trait( * ) => { } ,
414- _ if ! bounds. is_empty ( ) =>
420+ _ if bounds. is_some ( ) =>
415421 tcx. sess . span_err ( ast_ty. span ,
416422 "kind bounds can only be used on trait types" ) ,
417423 _ => { } ,
@@ -741,41 +747,60 @@ pub fn ty_of_closure<AC:AstConv,RS:region_scope + Copy + 'static>(
741747 }
742748}
743749
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 )
746752 -> ty:: BuiltinBounds {
747753 //! Converts a list of bounds from the AST into a `BuiltinBounds`
748754 //! struct. Reports an error if any of the bounds that appear
749755 //! in the AST refer to general traits and not the built-in traits
750756 //! like `Copy` or `Owned`. Used to translate the bounds that
751757 //! appear in closure and trait types, where only builtin bounds are
752758 //! 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+ _ => { }
764778 }
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 ) ;
765786 }
766- _ => { }
767787 }
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 ) ;
775788 }
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
776800 }
801+ // &'r Trait is sugar for &'r Trait:<no-bounds>.
802+ ( & None , ty:: RegionTraitStore ( * ) ) => ty:: EmptyBuiltinBounds ( ) ,
777803 }
778- builtin_bounds
779804}
780805
781806pub fn try_add_builtin_trait ( tcx : ty:: ctxt ,
0 commit comments