5151
5252use middle:: const_eval;
5353use middle:: def;
54- use middle:: subst ;
54+ use middle:: lang_items :: FnMutTraitLangItem ;
5555use middle:: subst:: { Subst , Substs } ;
56- use middle:: ty:: { ty_param_substs_and_ty} ;
56+ use middle:: subst;
57+ use middle:: ty:: ty_param_substs_and_ty;
5758use middle:: ty;
58- use middle:: typeck:: rscope;
59- use middle:: typeck:: rscope:: { RegionScope } ;
6059use middle:: typeck:: lookup_def_tcx;
60+ use middle:: typeck:: rscope:: RegionScope ;
61+ use middle:: typeck:: rscope;
6162use util:: ppaux:: Repr ;
6263
6364use std:: rc:: Rc ;
@@ -469,6 +470,38 @@ fn ast_ty_to_mt<AC:AstConv, RS:RegionScope>(this: &AC,
469470 ty:: mt { ty : ast_ty_to_ty ( this, rscope, ty) , mutbl : ast:: MutImmutable }
470471}
471472
473+ pub fn trait_ref_for_unboxed_function < AC : AstConv ,
474+ RS : RegionScope > (
475+ this : & AC ,
476+ rscope : & RS ,
477+ unboxed_function : & ast:: UnboxedFnTy )
478+ -> ty:: TraitRef {
479+ let fn_mut_trait_did = this. tcx ( )
480+ . lang_items
481+ . require ( FnMutTraitLangItem )
482+ . unwrap ( ) ;
483+ let input_types =
484+ unboxed_function. decl
485+ . inputs
486+ . iter ( )
487+ . map ( |input| {
488+ ast_ty_to_ty ( this, rscope, input. ty )
489+ } ) . collect :: < Vec < _ > > ( ) ;
490+ let input_tuple = ty:: mk_tup ( this. tcx ( ) , input_types) ;
491+ let output_type = ast_ty_to_ty ( this,
492+ rscope,
493+ unboxed_function. decl . output ) ;
494+ let substs = subst:: Substs {
495+ self_ty : None ,
496+ tps : vec ! ( input_tuple, output_type) ,
497+ regions : subst:: NonerasedRegions ( Vec :: new ( ) ) ,
498+ } ;
499+ ty:: TraitRef {
500+ def_id : fn_mut_trait_did,
501+ substs : substs,
502+ }
503+ }
504+
472505// Handle `~`, `Box`, and `&` being able to mean strs and vecs.
473506// If a_seq_ty is a str or a vec, make it a str/vec.
474507// Also handle first-class trait types.
@@ -491,6 +524,32 @@ fn mk_pointer<AC:AstConv,
491524 }
492525 return constr ( ty:: mk_vec ( tcx, mt, None ) ) ;
493526 }
527+ ast:: TyUnboxedFn ( ref unboxed_function) => {
528+ let trait_store = match ptr_ty {
529+ Uniq => ty:: UniqTraitStore ,
530+ RPtr ( r) => {
531+ ty:: RegionTraitStore ( r, a_seq_ty. mutbl )
532+ }
533+ _ => {
534+ tcx. sess . span_err (
535+ a_seq_ty. ty . span ,
536+ "~trait or &trait are the only supported \
537+ forms of casting-to-trait") ;
538+ return ty:: mk_err ( ) ;
539+ }
540+ } ;
541+ let ty:: TraitRef {
542+ def_id,
543+ substs
544+ } = trait_ref_for_unboxed_function ( this,
545+ rscope,
546+ * unboxed_function) ;
547+ return ty:: mk_trait ( this. tcx ( ) ,
548+ def_id,
549+ substs,
550+ trait_store,
551+ ty:: empty_builtin_bounds ( ) ) ;
552+ }
494553 ast:: TyPath ( ref path, ref bounds, id) => {
495554 // Note that the "bounds must be empty if path is not a trait"
496555 // restriction is enforced in the below case for ty_path, which
@@ -528,7 +587,10 @@ fn mk_pointer<AC:AstConv,
528587 return ty:: mk_err ( ) ;
529588 }
530589 } ;
531- let bounds = conv_builtin_bounds ( this. tcx ( ) , bounds, trait_store) ;
590+ let bounds = conv_builtin_bounds ( this. tcx ( ) ,
591+ path. span ,
592+ bounds,
593+ trait_store) ;
532594 return ty:: mk_trait ( tcx,
533595 result. def_id ,
534596 result. substs . clone ( ) ,
@@ -621,7 +683,10 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:RegionScope>(
621683
622684 // Use corresponding trait store to figure out default bounds
623685 // if none were specified.
624- let bounds = conv_builtin_bounds ( this. tcx ( ) , & f. bounds , store) ;
686+ let bounds = conv_builtin_bounds ( this. tcx ( ) ,
687+ ast_ty. span ,
688+ & f. bounds ,
689+ store) ;
625690
626691 let fn_decl = ty_of_closure ( this,
627692 ast_ty. id ,
@@ -636,7 +701,10 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:RegionScope>(
636701 ast:: TyProc ( ref f) => {
637702 // Use corresponding trait store to figure out default bounds
638703 // if none were specified.
639- let bounds = conv_builtin_bounds ( this. tcx ( ) , & f. bounds , ty:: UniqTraitStore ) ;
704+ let bounds = conv_builtin_bounds ( this. tcx ( ) ,
705+ ast_ty. span ,
706+ & f. bounds ,
707+ ty:: UniqTraitStore ) ;
640708
641709 let fn_decl = ty_of_closure ( this,
642710 ast_ty. id ,
@@ -648,6 +716,11 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:RegionScope>(
648716 None ) ;
649717 ty:: mk_closure ( tcx, fn_decl)
650718 }
719+ ast:: TyUnboxedFn ( _) => {
720+ tcx. sess . span_err ( ast_ty. span ,
721+ "cannot use unboxed functions here" ) ;
722+ ty:: mk_err ( )
723+ }
651724 ast:: TyPath ( ref path, ref bounds, id) => {
652725 let a_def = match tcx. def_map . borrow ( ) . find ( & id) {
653726 None => {
@@ -891,7 +964,9 @@ pub fn ty_of_closure<AC:AstConv>(
891964 }
892965}
893966
894- fn conv_builtin_bounds ( tcx : & ty:: ctxt , ast_bounds : & Option < OwnedSlice < ast:: TyParamBound > > ,
967+ fn conv_builtin_bounds ( tcx : & ty:: ctxt ,
968+ span : Span ,
969+ ast_bounds : & Option < OwnedSlice < ast:: TyParamBound > > ,
895970 store : ty:: TraitStore )
896971 -> ty:: BuiltinBounds {
897972 //! Converts a list of bounds from the AST into a `BuiltinBounds`
@@ -928,6 +1003,11 @@ fn conv_builtin_bounds(tcx: &ty::ctxt, ast_bounds: &Option<OwnedSlice<ast::TyPar
9281003 ast:: StaticRegionTyParamBound => {
9291004 builtin_bounds. add ( ty:: BoundStatic ) ;
9301005 }
1006+ ast:: UnboxedFnTyParamBound ( _) => {
1007+ tcx. sess . span_err ( span,
1008+ "unboxed functions are not allowed \
1009+ here") ;
1010+ }
9311011 ast:: OtherRegionTyParamBound ( span) => {
9321012 if !tcx. sess . features . issue_5723_bootstrap . get ( ) {
9331013 tcx. sess . span_err (
0 commit comments