@@ -58,7 +58,7 @@ use middle::const_eval;
5858use middle:: ty:: { arg, field, substs} ;
5959use middle:: ty:: { ty_param_substs_and_ty} ;
6060use middle:: ty;
61- use middle:: typeck:: rscope:: { in_binding_rscope, in_binding_rscope_ext } ;
61+ use middle:: typeck:: rscope:: { in_binding_rscope} ;
6262use middle:: typeck:: rscope:: { region_scope, type_rscope, RegionError } ;
6363use middle:: typeck:: rscope:: { RegionParamNames } ;
6464
@@ -67,6 +67,7 @@ use core::vec;
6767use syntax:: { ast, ast_util} ;
6868use syntax:: codemap:: span;
6969use syntax:: opt_vec:: OptVec ;
70+ use syntax:: opt_vec;
7071use syntax:: print:: pprust:: { lifetime_to_str, path_to_str} ;
7172use syntax:: parse:: token:: special_idents;
7273use util:: common:: indenter;
@@ -347,7 +348,7 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:region_scope + Copy + Durable>(
347348 }
348349 ast:: ty_bare_fn ( ref bf) => {
349350 ty:: mk_bare_fn ( tcx, ty_of_bare_fn ( self , rscope, bf. purity ,
350- bf. abi , & bf. decl ) )
351+ bf. abi , & bf. lifetimes , & bf . decl ) )
351352 }
352353 ast:: ty_closure( ref f) => {
353354 let fn_decl = ty_of_closure ( self ,
@@ -508,45 +509,50 @@ pub fn ty_of_arg<AC:AstConv,RS:region_scope + Copy + Durable>(
508509 arg { mode : mode, ty : ty}
509510}
510511
511- pub fn ty_of_bare_fn < AC : AstConv , RS : region_scope + Copy + Durable > (
512- self : & AC ,
513- rscope : & RS ,
514- purity : ast:: purity ,
515- abi : ast:: Abi ,
516- decl : & ast:: fn_decl )
517- -> ty:: BareFnTy {
518- debug ! ( "ty_of_bare_fn" ) ;
519-
520- // new region names that appear inside of the fn decl are bound to
521- // that function type
522- let rb = in_binding_rscope ( rscope) ;
523-
524- let input_tys = decl. inputs . map ( |a| ty_of_arg ( self , & rb, * a, None ) ) ;
525- let output_ty = match decl. output . node {
526- ast:: ty_infer => self . ty_infer ( decl. output . span ) ,
527- _ => ast_ty_to_ty ( self , & rb, decl. output )
528- } ;
529-
530- ty:: BareFnTy {
531- purity : purity,
532- abi : abi,
533- sig : ty:: FnSig { inputs : input_tys, output : output_ty}
534- }
512+ pub fn bound_lifetimes < AC : AstConv > (
513+ self : & AC ,
514+ ast_lifetimes : & OptVec < ast:: Lifetime > ) -> OptVec < ast:: ident >
515+ {
516+ /*!
517+ *
518+ * Converts a list of lifetimes into a list of bound identifier
519+ * names. Does not permit special names like 'static or 'self to
520+ * be bound. Note that this function is for use in closures,
521+ * methods, and fn definitions. It is legal to bind 'self in a
522+ * type. Eventually this distinction should go away and the same
523+ * rules should apply everywhere ('self would not be a special name
524+ * at that point).
525+ */
526+
527+ let special_idents = [ special_idents:: static, special_idents:: self_] ;
528+ let mut bound_lifetime_names = opt_vec:: Empty ;
529+ ast_lifetimes. map_to_vec ( |ast_lifetime| {
530+ if special_idents. any ( |& i| i == ast_lifetime. ident ) {
531+ self . tcx ( ) . sess . span_err (
532+ ast_lifetime. span ,
533+ fmt ! ( "illegal lifetime parameter name: `%s`" ,
534+ lifetime_to_str( ast_lifetime, self . tcx( ) . sess. intr( ) ) ) ) ;
535+ } else {
536+ bound_lifetime_names. push ( ast_lifetime. ident ) ;
537+ }
538+ } ) ;
539+ bound_lifetime_names
535540}
536541
537- pub fn ty_of_bare_fn_ext < AC : AstConv , RS : region_scope + Copy + Durable > (
538- self : & AC ,
539- rscope : & RS ,
540- purity : ast:: purity ,
541- abi : ast:: Abi ,
542- decl : & ast:: fn_decl ,
543- + region_param_names : RegionParamNames )
544- -> ty :: BareFnTy {
545- debug ! ( "ty_of_bare_fn_ext " ) ;
542+ pub fn ty_of_bare_fn < AC : AstConv , RS : region_scope + Copy + Durable > (
543+ self : & AC ,
544+ rscope : & RS ,
545+ purity : ast:: purity ,
546+ abi : ast:: Abi ,
547+ lifetimes : & OptVec < ast:: Lifetime > ,
548+ decl : & ast :: fn_decl ) -> ty :: BareFnTy
549+ {
550+ debug ! ( "ty_of_bare_fn " ) ;
546551
547552 // new region names that appear inside of the fn decl are bound to
548553 // that function type
549- let rb = in_binding_rscope_ext ( rscope, region_param_names) ;
554+ let bound_lifetime_names = bound_lifetimes ( self , lifetimes) ;
555+ let rb = in_binding_rscope ( rscope, RegionParamNames ( copy bound_lifetime_names) ) ;
550556
551557 let input_tys = decl. inputs . map ( |a| ty_of_arg ( self , & rb, * a, None ) ) ;
552558 let output_ty = match decl. output . node {
@@ -557,7 +563,9 @@ pub fn ty_of_bare_fn_ext<AC:AstConv,RS:region_scope + Copy + Durable>(
557563 ty:: BareFnTy {
558564 purity : purity,
559565 abi : abi,
560- sig : ty:: FnSig { inputs : input_tys, output : output_ty}
566+ sig : ty:: FnSig { bound_lifetime_names : bound_lifetime_names,
567+ inputs : input_tys,
568+ output : output_ty}
561569 }
562570}
563571
@@ -569,10 +577,16 @@ pub fn ty_of_closure<AC:AstConv,RS:region_scope + Copy + Durable>(
569577 onceness : ast:: Onceness ,
570578 opt_lifetime : Option < @ast:: Lifetime > ,
571579 decl : & ast:: fn_decl ,
572- expected_tys : Option < ty:: FnSig > ,
580+ expected_sig : Option < ty:: FnSig > ,
573581 lifetimes : & OptVec < ast:: Lifetime > ,
574582 span : span )
575- -> ty:: ClosureTy {
583+ -> ty:: ClosureTy
584+ {
585+ // The caller should not both provide explicit bound lifetime
586+ // names and expected types. Either we infer the bound lifetime
587+ // names or they are provided, but not both.
588+ fail_unless ! ( lifetimes. is_empty( ) || expected_sig. is_none( ) ) ;
589+
576590 debug ! ( "ty_of_fn_decl" ) ;
577591 let _i = indenter ( ) ;
578592
@@ -599,19 +613,19 @@ pub fn ty_of_closure<AC:AstConv,RS:region_scope + Copy + Durable>(
599613
600614 // new region names that appear inside of the fn decl are bound to
601615 // that function type
602- let region_param_names = RegionParamNames :: from_lifetimes ( lifetimes) ;
603- let rb = in_binding_rscope_ext ( rscope, region_param_names ) ;
616+ let bound_lifetime_names = bound_lifetimes ( self , lifetimes) ;
617+ let rb = in_binding_rscope ( rscope, RegionParamNames ( copy bound_lifetime_names ) ) ;
604618
605619 let input_tys = do decl. inputs . mapi |i, a| {
606- let expected_arg_ty = do expected_tys . chain_ref |e| {
620+ let expected_arg_ty = do expected_sig . chain_ref |e| {
607621 // no guarantee that the correct number of expected args
608622 // were supplied
609623 if i < e. inputs . len ( ) { Some ( e. inputs [ i] ) } else { None }
610624 } ;
611625 ty_of_arg ( self , & rb, * a, expected_arg_ty)
612626 } ;
613627
614- let expected_ret_ty = expected_tys . map ( |e| e. output ) ;
628+ let expected_ret_ty = expected_sig . map ( |e| e. output ) ;
615629 let output_ty = match decl. output . node {
616630 ast:: ty_infer if expected_ret_ty. is_some ( ) => expected_ret_ty. get ( ) ,
617631 ast:: ty_infer => self . ty_infer ( decl. output . span ) ,
@@ -623,7 +637,8 @@ pub fn ty_of_closure<AC:AstConv,RS:region_scope + Copy + Durable>(
623637 sigil : sigil,
624638 onceness : onceness,
625639 region : bound_region,
626- sig : ty:: FnSig { inputs : input_tys,
640+ sig : ty:: FnSig { bound_lifetime_names : bound_lifetime_names,
641+ inputs : input_tys,
627642 output : output_ty}
628643 }
629644}
0 commit comments