@@ -962,7 +962,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
962962 ty. id ,
963963 path. segments . last ( ) . unwrap ( ) ,
964964 span,
965- partition_bounds ( tcx , span , bounds) )
965+ partition_bounds ( bounds) )
966966 } else {
967967 struct_span_err ! ( tcx. sess, ty. span, E0172 ,
968968 "expected a reference to a trait" )
@@ -1045,11 +1045,12 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
10451045 trait_segment,
10461046 & mut projection_bounds) ;
10471047
1048- let PartitionedBounds { auto_traits,
1049- trait_bounds,
1048+ let PartitionedBounds { trait_bounds,
10501049 region_bounds } =
10511050 partitioned_bounds;
10521051
1052+ let ( auto_traits, trait_bounds) = split_auto_traits ( tcx, trait_bounds) ;
1053+
10531054 if !trait_bounds. is_empty ( ) {
10541055 let b = & trait_bounds[ 0 ] ;
10551056 let span = b. trait_ref . path . span ;
@@ -1443,7 +1444,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
14431444 path_id,
14441445 path. segments . last ( ) . unwrap ( ) ,
14451446 span,
1446- partition_bounds ( tcx , span , & [ ] ) )
1447+ partition_bounds ( & [ ] ) )
14471448 }
14481449 Def :: Enum ( did) | Def :: TyAlias ( did) | Def :: Struct ( did) | Def :: Union ( did) => {
14491450 assert_eq ! ( opt_self_ty, None ) ;
@@ -1897,7 +1898,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
18971898 ast_bounds : & [ hir:: TyParamBound ] )
18981899 -> Ty < ' tcx >
18991900 {
1900- let mut partitioned_bounds = partition_bounds ( self . tcx ( ) , span , & ast_bounds[ .. ] ) ;
1901+ let mut partitioned_bounds = partition_bounds ( ast_bounds) ;
19011902
19021903 let trait_bound = if !partitioned_bounds. trait_bounds . is_empty ( ) {
19031904 partitioned_bounds. trait_bounds . remove ( 0 )
@@ -1982,49 +1983,62 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
19821983}
19831984
19841985pub struct PartitionedBounds < ' a > {
1985- pub auto_traits : Vec < DefId > ,
19861986 pub trait_bounds : Vec < & ' a hir:: PolyTraitRef > ,
19871987 pub region_bounds : Vec < & ' a hir:: Lifetime > ,
19881988}
19891989
1990- /// Divides a list of bounds from the AST into three groups: builtin bounds (Copy, Sized etc),
1991- /// general trait bounds, and region bounds.
1992- pub fn partition_bounds < ' a , ' b , ' gcx , ' tcx > ( tcx : TyCtxt < ' a , ' gcx , ' tcx > ,
1993- _span : Span ,
1994- ast_bounds : & ' b [ hir:: TyParamBound ] )
1995- -> PartitionedBounds < ' b >
1990+ /// Divides a list of general trait bounds into two groups: builtin bounds (Sync/Send) and the
1991+ /// remaining general trait bounds.
1992+ fn split_auto_traits < ' a , ' b , ' gcx , ' tcx > ( tcx : TyCtxt < ' a , ' gcx , ' tcx > ,
1993+ trait_bounds : Vec < & ' b hir:: PolyTraitRef > )
1994+ -> ( Vec < DefId > , Vec < & ' b hir:: PolyTraitRef > )
1995+ {
1996+ let ( auto_traits, trait_bounds) : ( Vec < _ > , _ ) = trait_bounds. into_iter ( ) . partition ( |bound| {
1997+ match bound. trait_ref . path . def {
1998+ Def :: Trait ( trait_did) => {
1999+ // Checks whether `trait_did` refers to one of the builtin
2000+ // traits, like `Send`, and adds it to `auto_traits` if so.
2001+ if Some ( trait_did) == tcx. lang_items . send_trait ( ) ||
2002+ Some ( trait_did) == tcx. lang_items . sync_trait ( ) {
2003+ let segments = & bound. trait_ref . path . segments ;
2004+ let parameters = & segments[ segments. len ( ) - 1 ] . parameters ;
2005+ if !parameters. types ( ) . is_empty ( ) {
2006+ check_type_argument_count ( tcx, bound. trait_ref . path . span ,
2007+ parameters. types ( ) . len ( ) , & [ ] ) ;
2008+ }
2009+ if !parameters. lifetimes ( ) . is_empty ( ) {
2010+ report_lifetime_number_error ( tcx, bound. trait_ref . path . span ,
2011+ parameters. lifetimes ( ) . len ( ) , 0 ) ;
2012+ }
2013+ true
2014+ } else {
2015+ false
2016+ }
2017+ }
2018+ _ => false
2019+ }
2020+ } ) ;
2021+
2022+ let auto_traits = auto_traits. into_iter ( ) . map ( |tr| {
2023+ if let Def :: Trait ( trait_did) = tr. trait_ref . path . def {
2024+ trait_did
2025+ } else {
2026+ unreachable ! ( )
2027+ }
2028+ } ) . collect :: < Vec < _ > > ( ) ;
2029+
2030+ ( auto_traits, trait_bounds)
2031+ }
2032+
2033+ /// Divides a list of bounds from the AST into two groups: general trait bounds and region bounds
2034+ pub fn partition_bounds < ' a , ' b , ' gcx , ' tcx > ( ast_bounds : & ' b [ hir:: TyParamBound ] )
2035+ -> PartitionedBounds < ' b >
19962036{
1997- let mut auto_traits = Vec :: new ( ) ;
19982037 let mut region_bounds = Vec :: new ( ) ;
19992038 let mut trait_bounds = Vec :: new ( ) ;
20002039 for ast_bound in ast_bounds {
20012040 match * ast_bound {
20022041 hir:: TraitTyParamBound ( ref b, hir:: TraitBoundModifier :: None ) => {
2003- match b. trait_ref . path . def {
2004- Def :: Trait ( trait_did) => {
2005- // Checks whether `trait_did` refers to one of the builtin
2006- // traits, like `Send`, and adds it to `auto_traits` if so.
2007- if Some ( trait_did) == tcx. lang_items . send_trait ( ) ||
2008- Some ( trait_did) == tcx. lang_items . sync_trait ( ) {
2009- auto_traits. push ( trait_did) ;
2010- let segments = & b. trait_ref . path . segments ;
2011- let parameters = & segments[ segments. len ( ) - 1 ] . parameters ;
2012- if !parameters. types ( ) . is_empty ( ) {
2013- check_type_argument_count ( tcx, b. trait_ref . path . span ,
2014- parameters. types ( ) . len ( ) , & [ ] ) ;
2015- }
2016- if !parameters. lifetimes ( ) . is_empty ( ) {
2017- report_lifetime_number_error ( tcx, b. trait_ref . path . span ,
2018- parameters. lifetimes ( ) . len ( ) , 0 ) ;
2019- }
2020- continue ; // success
2021- }
2022- }
2023- _ => {
2024- // Not a trait? that's an error, but it'll get
2025- // reported later.
2026- }
2027- }
20282042 trait_bounds. push ( b) ;
20292043 }
20302044 hir:: TraitTyParamBound ( _, hir:: TraitBoundModifier :: Maybe ) => { }
@@ -2035,7 +2049,6 @@ pub fn partition_bounds<'a, 'b, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
20352049 }
20362050
20372051 PartitionedBounds {
2038- auto_traits : auto_traits,
20392052 trait_bounds : trait_bounds,
20402053 region_bounds : region_bounds,
20412054 }
@@ -2110,7 +2123,7 @@ fn report_lifetime_number_error(tcx: TyCtxt, span: Span, number: usize, expected
21102123#[ derive( PartialEq , Eq , Clone , Debug ) ]
21112124pub struct Bounds < ' tcx > {
21122125 pub region_bounds : Vec < & ' tcx ty:: Region > ,
2113- pub auto_traits : Vec < DefId > ,
2126+ pub implicitly_sized : bool ,
21142127 pub trait_bounds : Vec < ty:: PolyTraitRef < ' tcx > > ,
21152128 pub projection_bounds : Vec < ty:: PolyProjectionPredicate < ' tcx > > ,
21162129}
0 commit comments