@@ -962,7 +962,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
962
962
ty. id ,
963
963
path. segments . last ( ) . unwrap ( ) ,
964
964
span,
965
- partition_bounds ( tcx , span , bounds) )
965
+ partition_bounds ( bounds) )
966
966
} else {
967
967
struct_span_err ! ( tcx. sess, ty. span, E0172 ,
968
968
"expected a reference to a trait" )
@@ -1045,11 +1045,12 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
1045
1045
trait_segment,
1046
1046
& mut projection_bounds) ;
1047
1047
1048
- let PartitionedBounds { auto_traits,
1049
- trait_bounds,
1048
+ let PartitionedBounds { trait_bounds,
1050
1049
region_bounds } =
1051
1050
partitioned_bounds;
1052
1051
1052
+ let ( auto_traits, trait_bounds) = split_auto_traits ( tcx, trait_bounds) ;
1053
+
1053
1054
if !trait_bounds. is_empty ( ) {
1054
1055
let b = & trait_bounds[ 0 ] ;
1055
1056
let span = b. trait_ref . path . span ;
@@ -1443,7 +1444,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
1443
1444
path_id,
1444
1445
path. segments . last ( ) . unwrap ( ) ,
1445
1446
span,
1446
- partition_bounds ( tcx , span , & [ ] ) )
1447
+ partition_bounds ( & [ ] ) )
1447
1448
}
1448
1449
Def :: Enum ( did) | Def :: TyAlias ( did) | Def :: Struct ( did) | Def :: Union ( did) => {
1449
1450
assert_eq ! ( opt_self_ty, None ) ;
@@ -1897,7 +1898,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
1897
1898
ast_bounds : & [ hir:: TyParamBound ] )
1898
1899
-> Ty < ' tcx >
1899
1900
{
1900
- let mut partitioned_bounds = partition_bounds ( self . tcx ( ) , span , & ast_bounds[ .. ] ) ;
1901
+ let mut partitioned_bounds = partition_bounds ( ast_bounds) ;
1901
1902
1902
1903
let trait_bound = if !partitioned_bounds. trait_bounds . is_empty ( ) {
1903
1904
partitioned_bounds. trait_bounds . remove ( 0 )
@@ -1982,49 +1983,62 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
1982
1983
}
1983
1984
1984
1985
pub struct PartitionedBounds < ' a > {
1985
- pub auto_traits : Vec < DefId > ,
1986
1986
pub trait_bounds : Vec < & ' a hir:: PolyTraitRef > ,
1987
1987
pub region_bounds : Vec < & ' a hir:: Lifetime > ,
1988
1988
}
1989
1989
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 >
1996
2036
{
1997
- let mut auto_traits = Vec :: new ( ) ;
1998
2037
let mut region_bounds = Vec :: new ( ) ;
1999
2038
let mut trait_bounds = Vec :: new ( ) ;
2000
2039
for ast_bound in ast_bounds {
2001
2040
match * ast_bound {
2002
2041
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
- }
2028
2042
trait_bounds. push ( b) ;
2029
2043
}
2030
2044
hir:: TraitTyParamBound ( _, hir:: TraitBoundModifier :: Maybe ) => { }
@@ -2035,7 +2049,6 @@ pub fn partition_bounds<'a, 'b, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
2035
2049
}
2036
2050
2037
2051
PartitionedBounds {
2038
- auto_traits : auto_traits,
2039
2052
trait_bounds : trait_bounds,
2040
2053
region_bounds : region_bounds,
2041
2054
}
@@ -2110,7 +2123,7 @@ fn report_lifetime_number_error(tcx: TyCtxt, span: Span, number: usize, expected
2110
2123
#[ derive( PartialEq , Eq , Clone , Debug ) ]
2111
2124
pub struct Bounds < ' tcx > {
2112
2125
pub region_bounds : Vec < & ' tcx ty:: Region > ,
2113
- pub auto_traits : Vec < DefId > ,
2126
+ pub implicitly_sized : bool ,
2114
2127
pub trait_bounds : Vec < ty:: PolyTraitRef < ' tcx > > ,
2115
2128
pub projection_bounds : Vec < ty:: PolyProjectionPredicate < ' tcx > > ,
2116
2129
}
0 commit comments