@@ -1165,17 +1165,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
11651165 ///
11661166 /// This is really an internal helper. From outside the coercion
11671167 /// module, you should instantiate a `CoerceMany` instance.
1168- fn try_find_coercion_lub < E > (
1168+ fn try_find_coercion_lub (
11691169 & self ,
11701170 cause : & ObligationCause < ' tcx > ,
1171- exprs : & [ E ] ,
1171+ exprs : & [ & ' tcx hir :: Expr < ' tcx > ] ,
11721172 prev_ty : Ty < ' tcx > ,
11731173 new : & hir:: Expr < ' _ > ,
11741174 new_ty : Ty < ' tcx > ,
1175- ) -> RelateResult < ' tcx , Ty < ' tcx > >
1176- where
1177- E : AsCoercionSite ,
1178- {
1175+ ) -> RelateResult < ' tcx , Ty < ' tcx > > {
11791176 let prev_ty = self . try_structurally_resolve_type ( cause. span , prev_ty) ;
11801177 let new_ty = self . try_structurally_resolve_type ( new. span , new_ty) ;
11811178 debug ! (
@@ -1269,7 +1266,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
12691266 ty:: FnDef ( ..) => Adjust :: Pointer ( PointerCoercion :: ReifyFnPointer ( sig. safety ( ) ) ) ,
12701267 _ => span_bug ! ( new. span, "should not try to coerce a {new_ty} to a fn pointer" ) ,
12711268 } ;
1272- for expr in exprs. iter ( ) . map ( |e| e . as_coercion_site ( ) ) {
1269+ for expr in exprs. iter ( ) {
12731270 self . apply_adjustments (
12741271 expr,
12751272 vec ! [ Adjustment { kind: prev_adjustment. clone( ) , target: fn_ptr } ] ,
@@ -1316,7 +1313,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13161313
13171314 let ( adjustments, target) = self . register_infer_ok_obligations ( ok) ;
13181315 for expr in exprs {
1319- let expr = expr. as_coercion_site ( ) ;
13201316 self . apply_adjustments ( expr, adjustments. clone ( ) ) ;
13211317 }
13221318 debug ! (
@@ -1382,40 +1378,35 @@ pub fn can_coerce<'tcx>(
13821378/// }
13831379/// let final_ty = coerce.complete(fcx);
13841380/// ```
1385- pub ( crate ) struct CoerceMany < ' tcx , ' exprs , E : AsCoercionSite > {
1381+ pub ( crate ) struct CoerceMany < ' tcx > {
13861382 expected_ty : Ty < ' tcx > ,
13871383 final_ty : Option < Ty < ' tcx > > ,
1388- expressions : Expressions < ' tcx , ' exprs , E > ,
1384+ expressions : Vec < & ' tcx hir :: Expr < ' tcx > > ,
13891385 pushed : usize ,
13901386}
13911387
13921388/// The type of a `CoerceMany` that is storing up the expressions into
13931389/// a buffer. We use this in `check/mod.rs` for things like `break`.
1394- pub ( crate ) type DynamicCoerceMany < ' tcx > = CoerceMany < ' tcx , ' tcx , & ' tcx hir:: Expr < ' tcx > > ;
1395-
1396- enum Expressions < ' tcx , ' exprs , E : AsCoercionSite > {
1397- Dynamic ( Vec < & ' tcx hir:: Expr < ' tcx > > ) ,
1398- UpFront ( & ' exprs [ E ] ) ,
1399- }
1390+ pub ( crate ) type DynamicCoerceMany < ' tcx > = CoerceMany < ' tcx > ;
14001391
1401- impl < ' tcx , ' exprs , E : AsCoercionSite > CoerceMany < ' tcx , ' exprs , E > {
1392+ impl < ' tcx > CoerceMany < ' tcx > {
14021393 /// The usual case; collect the set of expressions dynamically.
14031394 /// If the full set of coercion sites is known before hand,
14041395 /// consider `with_coercion_sites()` instead to avoid allocation.
14051396 pub ( crate ) fn new ( expected_ty : Ty < ' tcx > ) -> Self {
1406- Self :: make ( expected_ty, Expressions :: Dynamic ( vec ! [ ] ) )
1397+ Self :: make ( expected_ty, Vec :: with_capacity ( 1 ) )
14071398 }
14081399
14091400 /// As an optimization, you can create a `CoerceMany` with a
14101401 /// preexisting slice of expressions. In this case, you are
14111402 /// expected to pass each element in the slice to `coerce(...)` in
14121403 /// order. This is used with arrays in particular to avoid
14131404 /// needlessly cloning the slice.
1414- pub ( crate ) fn with_coercion_sites ( expected_ty : Ty < ' tcx > , coercion_sites : & ' exprs [ E ] ) -> Self {
1415- Self :: make ( expected_ty, Expressions :: UpFront ( coercion_sites) )
1405+ pub ( crate ) fn with_coercion_sites ( expected_ty : Ty < ' tcx > , coercion_sites : usize ) -> Self {
1406+ Self :: make ( expected_ty, Vec :: with_capacity ( coercion_sites) )
14161407 }
14171408
1418- fn make ( expected_ty : Ty < ' tcx > , expressions : Expressions < ' tcx , ' exprs , E > ) -> Self {
1409+ fn make ( expected_ty : Ty < ' tcx > , expressions : Vec < & ' tcx hir :: Expr < ' tcx > > ) -> Self {
14191410 CoerceMany { expected_ty, final_ty : None , expressions, pushed : 0 }
14201411 }
14211412
@@ -1541,22 +1532,13 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
15411532 Some ( cause. clone ( ) ) ,
15421533 )
15431534 } else {
1544- match self . expressions {
1545- Expressions :: Dynamic ( ref exprs) => fcx. try_find_coercion_lub (
1546- cause,
1547- exprs,
1548- self . merged_ty ( ) ,
1549- expression,
1550- expression_ty,
1551- ) ,
1552- Expressions :: UpFront ( coercion_sites) => fcx. try_find_coercion_lub (
1553- cause,
1554- & coercion_sites[ 0 ..self . pushed ] ,
1555- self . merged_ty ( ) ,
1556- expression,
1557- expression_ty,
1558- ) ,
1559- }
1535+ fcx. try_find_coercion_lub (
1536+ cause,
1537+ & self . expressions ,
1538+ self . merged_ty ( ) ,
1539+ expression,
1540+ expression_ty,
1541+ )
15601542 }
15611543 } else {
15621544 // this is a hack for cases where we default to `()` because
@@ -1591,17 +1573,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
15911573 Ok ( v) => {
15921574 self . final_ty = Some ( v) ;
15931575 if let Some ( e) = expression {
1594- match self . expressions {
1595- Expressions :: Dynamic ( ref mut buffer) => buffer. push ( e) ,
1596- Expressions :: UpFront ( coercion_sites) => {
1597- // if the user gave us an array to validate, check that we got
1598- // the next expression in the list, as expected
1599- assert_eq ! (
1600- coercion_sites[ self . pushed] . as_coercion_site( ) . hir_id,
1601- e. hir_id
1602- ) ;
1603- }
1604- }
1576+ self . expressions . push ( e) ;
16051577 self . pushed += 1 ;
16061578 }
16071579 }
@@ -1961,39 +1933,6 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
19611933 }
19621934}
19631935
1964- /// Something that can be converted into an expression to which we can
1965- /// apply a coercion.
1966- pub ( crate ) trait AsCoercionSite {
1967- fn as_coercion_site ( & self ) -> & hir:: Expr < ' _ > ;
1968- }
1969-
1970- impl AsCoercionSite for hir:: Expr < ' _ > {
1971- fn as_coercion_site ( & self ) -> & hir:: Expr < ' _ > {
1972- self
1973- }
1974- }
1975-
1976- impl < ' a , T > AsCoercionSite for & ' a T
1977- where
1978- T : AsCoercionSite ,
1979- {
1980- fn as_coercion_site ( & self ) -> & hir:: Expr < ' _ > {
1981- ( * * self ) . as_coercion_site ( )
1982- }
1983- }
1984-
1985- impl AsCoercionSite for ! {
1986- fn as_coercion_site ( & self ) -> & hir:: Expr < ' _ > {
1987- * self
1988- }
1989- }
1990-
1991- impl AsCoercionSite for hir:: Arm < ' _ > {
1992- fn as_coercion_site ( & self ) -> & hir:: Expr < ' _ > {
1993- self . body
1994- }
1995- }
1996-
19971936/// Recursively visit goals to decide whether an unsizing is possible.
19981937/// `Break`s when it isn't, and an error should be raised.
19991938/// `Continue`s when an unsizing ok based on an implementation of the `Unsize` trait / lang item.
0 commit comments