@@ -52,13 +52,17 @@ use middle::const_val::ConstVal;
5252use rustc_const_eval:: { eval_const_expr_partial, ConstEvalErr } ;
5353use rustc_const_eval:: EvalHint :: UncheckedExprHint ;
5454use rustc_const_eval:: ErrKind :: ErroneousReferencedConstant ;
55+ use hir:: { self , SelfKind } ;
5556use hir:: def:: { self , Def } ;
5657use hir:: def_id:: DefId ;
58+ use hir:: print as pprust;
5759use middle:: resolve_lifetime as rl;
60+ use rustc:: lint;
5861use rustc:: ty:: subst:: { FnSpace , TypeSpace , SelfSpace , Subst , Substs , ParamSpace } ;
5962use rustc:: traits;
6063use rustc:: ty:: { self , Ty , TyCtxt , ToPredicate , TypeFoldable } ;
6164use rustc:: ty:: wf:: object_region_bounds;
65+ use rustc_back:: slice;
6266use require_c_abi_if_variadic;
6367use rscope:: { self , UnelidableRscope , RegionScope , ElidableRscope ,
6468 ObjectLifetimeDefaultRscope , ShiftedRscope , BindingRscope ,
@@ -74,10 +78,6 @@ use syntax::errors::DiagnosticBuilder;
7478use syntax:: feature_gate:: { GateIssue , emit_feature_err} ;
7579use syntax:: parse:: token:: { self , keywords} ;
7680
77- use rustc:: hir:: print as pprust;
78- use rustc:: hir:: { self , SelfKind } ;
79- use rustc_back:: slice;
80-
8181pub trait AstConv < ' gcx , ' tcx > {
8282 fn tcx < ' a > ( & ' a self ) -> TyCtxt < ' a , ' gcx , ' tcx > ;
8383
@@ -679,6 +679,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
679679 PathParamMode :: Explicit ,
680680 trait_def_id,
681681 self_ty,
682+ trait_ref. ref_id ,
682683 trait_ref. path . segments . last ( ) . unwrap ( ) ,
683684 poly_projections)
684685 }
@@ -723,6 +724,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
723724 span : Span ,
724725 param_mode : PathParamMode ,
725726 trait_def_id : DefId ,
727+ trait_path_ref_id : ast:: NodeId ,
726728 trait_segment : & hir:: PathSegment ,
727729 mut projections : & mut Vec < ty:: PolyProjectionPredicate < ' tcx > > )
728730 -> ty:: PolyTraitRef < ' tcx >
@@ -732,6 +734,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
732734 param_mode,
733735 trait_def_id,
734736 None ,
737+ trait_path_ref_id,
735738 trait_segment,
736739 projections)
737740 }
@@ -742,6 +745,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
742745 param_mode : PathParamMode ,
743746 trait_def_id : DefId ,
744747 self_ty : Option < Ty < ' tcx > > ,
748+ path_id : ast:: NodeId ,
745749 trait_segment : & hir:: PathSegment ,
746750 poly_projections : & mut Vec < ty:: PolyProjectionPredicate < ' tcx > > )
747751 -> ty:: PolyTraitRef < ' tcx >
@@ -770,7 +774,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
770774 . filter_map ( |binding| {
771775 // specify type to assert that error was already reported in Err case:
772776 let predicate: Result < _ , ErrorReported > =
773- self . ast_type_binding_to_poly_projection_predicate ( poly_trait_ref. clone ( ) ,
777+ self . ast_type_binding_to_poly_projection_predicate ( path_id,
778+ poly_trait_ref. clone ( ) ,
774779 self_ty,
775780 binding) ;
776781 predicate. ok ( ) // ok to ignore Err() because ErrorReported (see above)
@@ -863,7 +868,9 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
863868 ( self . tcx ( ) . mk_substs ( substs) , assoc_bindings)
864869 }
865870
866- fn ast_type_binding_to_poly_projection_predicate ( & self ,
871+ fn ast_type_binding_to_poly_projection_predicate (
872+ & self ,
873+ path_id : ast:: NodeId ,
867874 mut trait_ref : ty:: PolyTraitRef < ' tcx > ,
868875 self_ty : Option < Ty < ' tcx > > ,
869876 binding : & ConvertedBinding < ' tcx > )
@@ -887,6 +894,36 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
887894 //
888895 // We want to produce `<B as SuperTrait<int>>::T == foo`.
889896
897+ // Find any late-bound regions declared in `ty` that are not
898+ // declared in the trait-ref. These are not wellformed.
899+ //
900+ // Example:
901+ //
902+ // for<'a> <T as Iterator>::Item = &'a str // <-- 'a is bad
903+ // for<'a> <T as FnMut<(&'a u32,)>>::Output = &'a str // <-- 'a is ok
904+ let late_bound_in_trait_ref = tcx. collect_constrained_late_bound_regions ( & trait_ref) ;
905+ let late_bound_in_ty = tcx. collect_referenced_late_bound_regions ( & ty:: Binder ( binding. ty ) ) ;
906+ debug ! ( "late_bound_in_trait_ref = {:?}" , late_bound_in_trait_ref) ;
907+ debug ! ( "late_bound_in_ty = {:?}" , late_bound_in_ty) ;
908+ for br in late_bound_in_ty. difference ( & late_bound_in_trait_ref) {
909+ let br_name = match * br {
910+ ty:: BrNamed ( _, name) => name,
911+ _ => {
912+ span_bug ! (
913+ binding. span,
914+ "anonymous bound region {:?} in binding but not trait ref" ,
915+ br) ;
916+ }
917+ } ;
918+ tcx. sess . add_lint (
919+ lint:: builtin:: HR_LIFETIME_IN_ASSOC_TYPE ,
920+ path_id,
921+ binding. span ,
922+ format ! ( "binding for associated type `{}` references lifetime `{}`, \
923+ which does not appear in the trait input types",
924+ binding. item_name, br_name) ) ;
925+ }
926+
890927 // Simple case: X is defined in the current trait.
891928 if self . trait_defines_associated_type_named ( trait_ref. def_id ( ) , binding. item_name ) {
892929 return Ok ( ty:: Binder ( ty:: ProjectionPredicate { // <-------------------+
@@ -1012,6 +1049,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
10121049 path. span ,
10131050 PathParamMode :: Explicit ,
10141051 trait_def_id,
1052+ ty. id ,
10151053 path. segments . last ( ) . unwrap ( ) ,
10161054 & mut projection_bounds) ;
10171055 Ok ( ( trait_ref, projection_bounds) )
@@ -1416,6 +1454,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
14161454 param_mode : PathParamMode ,
14171455 def : Def ,
14181456 opt_self_ty : Option < Ty < ' tcx > > ,
1457+ base_path_ref_id : ast:: NodeId ,
14191458 base_segments : & [ hir:: PathSegment ] )
14201459 -> Ty < ' tcx > {
14211460 let tcx = self . tcx ( ) ;
@@ -1434,6 +1473,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
14341473 span,
14351474 param_mode,
14361475 trait_def_id,
1476+ base_path_ref_id,
14371477 base_segments. last ( ) . unwrap ( ) ,
14381478 & mut projection_bounds) ;
14391479
@@ -1518,6 +1558,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
15181558 param_mode : PathParamMode ,
15191559 mut def : Def ,
15201560 opt_self_ty : Option < Ty < ' tcx > > ,
1561+ base_path_ref_id : ast:: NodeId ,
15211562 base_segments : & [ hir:: PathSegment ] ,
15221563 assoc_segments : & [ hir:: PathSegment ] )
15231564 -> ( Ty < ' tcx > , Def ) {
@@ -1532,6 +1573,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
15321573 param_mode,
15331574 def,
15341575 opt_self_ty,
1576+ base_path_ref_id,
15351577 base_segments) ;
15361578 debug ! ( "finish_resolving_def_to_ty: base_def_to_ty returned {:?}" , ty) ;
15371579 // If any associated type segments remain, attempt to resolve them.
@@ -1607,7 +1649,45 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
16071649 }
16081650 hir:: TyBareFn ( ref bf) => {
16091651 require_c_abi_if_variadic ( tcx, & bf. decl , bf. abi , ast_ty. span ) ;
1610- tcx. mk_fn_ptr ( self . ty_of_bare_fn ( bf. unsafety , bf. abi , & bf. decl ) )
1652+ let bare_fn_ty = self . ty_of_bare_fn ( bf. unsafety , bf. abi , & bf. decl ) ;
1653+
1654+ // Find any late-bound regions declared in return type that do
1655+ // not appear in the arguments. These are not wellformed.
1656+ //
1657+ // Example:
1658+ //
1659+ // for<'a> fn() -> &'a str <-- 'a is bad
1660+ // for<'a> fn(&'a String) -> &'a str <-- 'a is ok
1661+ //
1662+ // Note that we do this check **here** and not in
1663+ // `ty_of_bare_fn` because the latter is also used to make
1664+ // the types for fn items, and we do not want to issue a
1665+ // warning then. (Once we fix #32330, the regions we are
1666+ // checking for here would be considered early bound
1667+ // anyway.)
1668+ let inputs = bare_fn_ty. sig . inputs ( ) ;
1669+ let late_bound_in_args = tcx. collect_constrained_late_bound_regions ( & inputs) ;
1670+ let output = bare_fn_ty. sig . output ( ) ;
1671+ let late_bound_in_ret = tcx. collect_referenced_late_bound_regions ( & output) ;
1672+ for br in late_bound_in_ret. difference ( & late_bound_in_args) {
1673+ let br_name = match * br {
1674+ ty:: BrNamed ( _, name) => name,
1675+ _ => {
1676+ span_bug ! (
1677+ bf. decl. output. span( ) ,
1678+ "anonymous bound region {:?} in return but not args" ,
1679+ br) ;
1680+ }
1681+ } ;
1682+ tcx. sess . add_lint (
1683+ lint:: builtin:: HR_LIFETIME_IN_ASSOC_TYPE ,
1684+ ast_ty. id ,
1685+ ast_ty. span ,
1686+ format ! ( "return type references lifetime `{}`, \
1687+ which does not appear in the trait input types",
1688+ br_name) ) ;
1689+ }
1690+ tcx. mk_fn_ptr ( bare_fn_ty)
16111691 }
16121692 hir:: TyPolyTraitRef ( ref bounds) => {
16131693 self . conv_ty_poly_trait_ref ( rscope, ast_ty. span , bounds)
@@ -1635,6 +1715,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
16351715 PathParamMode :: Explicit ,
16361716 def,
16371717 opt_self_ty,
1718+ ast_ty. id ,
16381719 & path. segments [ ..base_ty_end] ,
16391720 & path. segments [ base_ty_end..] ) ;
16401721
0 commit comments