@@ -3,15 +3,18 @@ use rustc_index::bit_set::DenseBitSet;
3
3
use rustc_index:: interval:: IntervalSet ;
4
4
use rustc_infer:: infer:: canonical:: QueryRegionConstraints ;
5
5
use rustc_infer:: infer:: outlives:: for_liveness;
6
- use rustc_middle:: mir:: { BasicBlock , Body , ConstraintCategory , Local , Location } ;
6
+ use rustc_middle:: mir:: { BasicBlock , Body , ConstraintCategory , HasLocalDecls , Local , Location } ;
7
7
use rustc_middle:: traits:: query:: DropckOutlivesResult ;
8
8
use rustc_middle:: ty:: relate:: Relate ;
9
9
use rustc_middle:: ty:: { Ty , TyCtxt , TypeVisitable , TypeVisitableExt } ;
10
10
use rustc_mir_dataflow:: ResultsCursor ;
11
11
use rustc_mir_dataflow:: impls:: MaybeInitializedPlaces ;
12
12
use rustc_mir_dataflow:: move_paths:: { HasMoveData , MoveData , MovePathIndex } ;
13
13
use rustc_mir_dataflow:: points:: { DenseLocationMap , PointIndex } ;
14
- use rustc_span:: DUMMY_SP ;
14
+ use rustc_span:: { DUMMY_SP , Span } ;
15
+ use rustc_trait_selection:: error_reporting:: InferCtxtErrorExt ;
16
+ use rustc_trait_selection:: traits:: ObligationCtxt ;
17
+ use rustc_trait_selection:: traits:: query:: dropck_outlives;
15
18
use rustc_trait_selection:: traits:: query:: type_op:: { DropckOutlives , TypeOp , TypeOpOutput } ;
16
19
use tracing:: debug;
17
20
@@ -162,9 +165,10 @@ impl<'a, 'typeck, 'b, 'tcx> LivenessResults<'a, 'typeck, 'b, 'tcx> {
162
165
fn dropck_boring_locals ( & mut self , boring_locals : Vec < Local > ) {
163
166
for local in boring_locals {
164
167
let local_ty = self . cx . body . local_decls [ local] . ty ;
168
+ let local_span = self . cx . body . local_decls [ local] . source_info . span ;
165
169
let drop_data = self . cx . drop_data . entry ( local_ty) . or_insert_with ( {
166
170
let typeck = & self . cx . typeck ;
167
- move || LivenessContext :: compute_drop_data ( typeck, local_ty)
171
+ move || LivenessContext :: compute_drop_data ( typeck, local_ty, local_span )
168
172
} ) ;
169
173
170
174
drop_data. dropck_result . report_overflows (
@@ -522,9 +526,10 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> {
522
526
values:: pretty_print_points( self . location_map, live_at. iter( ) ) ,
523
527
) ;
524
528
529
+ let local_span = self . body . local_decls ( ) [ dropped_local] . source_info . span ;
525
530
let drop_data = self . drop_data . entry ( dropped_ty) . or_insert_with ( {
526
531
let typeck = & self . typeck ;
527
- move || Self :: compute_drop_data ( typeck, dropped_ty)
532
+ move || Self :: compute_drop_data ( typeck, dropped_ty, local_span )
528
533
} ) ;
529
534
530
535
if let Some ( data) = & drop_data. region_constraint_data {
@@ -589,19 +594,45 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> {
589
594
}
590
595
}
591
596
592
- fn compute_drop_data ( typeck : & TypeChecker < ' _ , ' tcx > , dropped_ty : Ty < ' tcx > ) -> DropData < ' tcx > {
593
- debug ! ( "compute_drop_data(dropped_ty={:?})" , dropped_ty, ) ;
597
+ fn compute_drop_data (
598
+ typeck : & TypeChecker < ' _ , ' tcx > ,
599
+ dropped_ty : Ty < ' tcx > ,
600
+ span : Span ,
601
+ ) -> DropData < ' tcx > {
602
+ debug ! ( "compute_drop_data(dropped_ty={:?})" , dropped_ty) ;
603
+
604
+ let op = typeck. infcx . param_env . and ( DropckOutlives { dropped_ty } ) ;
594
605
595
- match typeck
596
- . infcx
597
- . param_env
598
- . and ( DropckOutlives { dropped_ty } )
599
- . fully_perform ( typeck. infcx , DUMMY_SP )
600
- {
606
+ match op. fully_perform ( typeck. infcx , DUMMY_SP ) {
601
607
Ok ( TypeOpOutput { output, constraints, .. } ) => {
602
608
DropData { dropck_result : output, region_constraint_data : constraints }
603
609
}
604
- Err ( _) => DropData { dropck_result : Default :: default ( ) , region_constraint_data : None } ,
610
+ Err ( _) => {
611
+ // We don't run dropck on HIR, and dropck looks inside fields of
612
+ // types, so there's no guarantee that it succeeds. We also
613
+ // can't rely on the the `ErrorGuaranteed` from `fully_perform` here
614
+ // because it comes from delay_span_bug.
615
+ let ocx = ObligationCtxt :: new_with_diagnostics ( & typeck. infcx ) ;
616
+ let errors = match dropck_outlives:: compute_dropck_outlives_with_errors (
617
+ & ocx, op, span, true ,
618
+ ) {
619
+ Ok ( _) => ocx. select_all_or_error ( ) ,
620
+ Err ( e) => {
621
+ if e. is_empty ( ) {
622
+ ocx. select_all_or_error ( )
623
+ } else {
624
+ e
625
+ }
626
+ }
627
+ } ;
628
+
629
+ if !errors. is_empty ( ) {
630
+ typeck. infcx . err_ctxt ( ) . report_fulfillment_errors ( errors) ;
631
+ } else {
632
+ rustc_middle:: span_bug!( span, "Rerunning drop data query produced no error." ) ;
633
+ }
634
+ DropData { dropck_result : Default :: default ( ) , region_constraint_data : None }
635
+ }
605
636
}
606
637
}
607
638
}
0 commit comments