@@ -1061,7 +1061,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10611061 & self ,
10621062 blk : & ' tcx hir:: Block < ' tcx > ,
10631063 expected_ty : Ty < ' tcx > ,
1064- ) -> Option < Span > {
1064+ ) -> Option < ( Span , bool ) > {
10651065 // Be helpful when the user wrote `{... expr;}` and
10661066 // taking the `;` off is enough to fix the error.
10671067 let last_stmt = blk. stmts . last ( ) ?;
@@ -1070,13 +1070,62 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10701070 _ => return None ,
10711071 } ;
10721072 let last_expr_ty = self . node_ty ( last_expr. hir_id ) ;
1073- if matches ! ( last_expr_ty. kind( ) , ty:: Error ( _) )
1074- || self . can_sub ( self . param_env , last_expr_ty, expected_ty) . is_err ( )
1073+ let needs_box = match ( last_expr_ty. kind ( ) , expected_ty. kind ( ) ) {
1074+ ( ty:: Opaque ( last_def_id, last_bounds) , ty:: Opaque ( exp_def_id, exp_bounds) ) => {
1075+ debug ! (
1076+ "both opaque, likely future {:?} {:?} {:?} {:?}" ,
1077+ last_def_id, last_bounds, exp_def_id, exp_bounds
1078+ ) ;
1079+ let last_hir_id = self . tcx . hir ( ) . local_def_id_to_hir_id ( last_def_id. expect_local ( ) ) ;
1080+ let exp_hir_id = self . tcx . hir ( ) . local_def_id_to_hir_id ( exp_def_id. expect_local ( ) ) ;
1081+ if let (
1082+ hir:: ItemKind :: OpaqueTy ( hir:: OpaqueTy { bounds : last_bounds, .. } ) ,
1083+ hir:: ItemKind :: OpaqueTy ( hir:: OpaqueTy { bounds : exp_bounds, .. } ) ,
1084+ ) = (
1085+ & self . tcx . hir ( ) . expect_item ( last_hir_id) . kind ,
1086+ & self . tcx . hir ( ) . expect_item ( exp_hir_id) . kind ,
1087+ ) {
1088+ debug ! ( "{:?} {:?}" , last_bounds, exp_bounds) ;
1089+ last_bounds. iter ( ) . zip ( exp_bounds. iter ( ) ) . all ( |( left, right) | {
1090+ match ( left, right) {
1091+ (
1092+ hir:: GenericBound :: Trait ( tl, ml) ,
1093+ hir:: GenericBound :: Trait ( tr, mr) ,
1094+ ) => {
1095+ tl. trait_ref . trait_def_id ( ) == tr. trait_ref . trait_def_id ( )
1096+ && ml == mr
1097+ }
1098+ (
1099+ hir:: GenericBound :: LangItemTrait ( langl, _, _, argsl) ,
1100+ hir:: GenericBound :: LangItemTrait ( langr, _, _, argsr) ,
1101+ ) => {
1102+ // FIXME: consider the bounds!
1103+ debug ! ( "{:?} {:?}" , argsl, argsr) ;
1104+ langl == langr
1105+ }
1106+ _ => false ,
1107+ }
1108+ } )
1109+ } else {
1110+ false
1111+ }
1112+ }
1113+ _ => false ,
1114+ } ;
1115+ debug ! (
1116+ "needs_box {:?} {:?} {:?}" ,
1117+ needs_box,
1118+ last_expr_ty. kind( ) ,
1119+ self . can_sub( self . param_env, last_expr_ty, expected_ty)
1120+ ) ;
1121+ if ( matches ! ( last_expr_ty. kind( ) , ty:: Error ( _) )
1122+ || self . can_sub ( self . param_env , last_expr_ty, expected_ty) . is_err ( ) )
1123+ && !needs_box
10751124 {
10761125 return None ;
10771126 }
10781127 let original_span = original_sp ( last_stmt. span , blk. span ) ;
1079- Some ( original_span. with_lo ( original_span. hi ( ) - BytePos ( 1 ) ) )
1128+ Some ( ( original_span. with_lo ( original_span. hi ( ) - BytePos ( 1 ) ) , needs_box ) )
10801129 }
10811130
10821131 // Instantiates the given path, which must refer to an item with the given
0 commit comments