8
8
// option. This file may not be copied, modified, or distributed
9
9
// except according to those terms.
10
10
11
- use borrow_check:: nll:: constraints:: OutlivesConstraint ;
11
+ use borrow_check:: nll:: constraints:: { OutlivesConstraint , ConstraintCategory } ;
12
12
use borrow_check:: nll:: region_infer:: RegionInferenceContext ;
13
- use borrow_check:: nll:: type_check:: Locations ;
14
13
use rustc:: hir:: def_id:: DefId ;
15
14
use rustc:: infer:: error_reporting:: nice_region_error:: NiceRegionError ;
16
15
use rustc:: infer:: InferCtxt ;
17
- use rustc:: mir:: { self , Location , Mir , Place , Rvalue , StatementKind , TerminatorKind } ;
18
- use rustc:: ty:: { self , TyCtxt , RegionVid } ;
16
+ use rustc:: mir:: { Location , Mir } ;
17
+ use rustc:: ty:: { self , RegionVid } ;
19
18
use rustc_data_structures:: indexed_vec:: IndexVec ;
20
19
use rustc_errors:: { Diagnostic , DiagnosticBuilder } ;
21
20
use std:: collections:: VecDeque ;
@@ -28,19 +27,6 @@ mod var_name;
28
27
29
28
use self :: region_name:: RegionName ;
30
29
31
- /// Constraints that are considered interesting can be categorized to
32
- /// determine why they are interesting. Order of variants indicates
33
- /// sort order of the category, thereby influencing diagnostic output.
34
- #[ derive( Copy , Clone , Debug , Eq , PartialEq , PartialOrd , Ord ) ]
35
- enum ConstraintCategory {
36
- Cast ,
37
- Assignment ,
38
- Return ,
39
- CallArgument ,
40
- Other ,
41
- Boring ,
42
- }
43
-
44
30
impl fmt:: Display for ConstraintCategory {
45
31
fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
46
32
// Must end with a space. Allows for empty names to be provided.
@@ -49,7 +35,14 @@ impl fmt::Display for ConstraintCategory {
49
35
ConstraintCategory :: Return => write ! ( f, "returning this value " ) ,
50
36
ConstraintCategory :: Cast => write ! ( f, "cast " ) ,
51
37
ConstraintCategory :: CallArgument => write ! ( f, "argument " ) ,
52
- _ => write ! ( f, "" ) ,
38
+ ConstraintCategory :: TypeAnnotation => write ! ( f, "type annotation " ) ,
39
+ ConstraintCategory :: ClosureBounds => write ! ( f, "closure body " ) ,
40
+ ConstraintCategory :: SizedBound => write ! ( f, "proving this value is `Sized` " ) ,
41
+ ConstraintCategory :: CopyBound => write ! ( f, "copying this value " ) ,
42
+ ConstraintCategory :: OpaqueType => write ! ( f, "opaque type " ) ,
43
+ ConstraintCategory :: Boring
44
+ | ConstraintCategory :: BoringNoLocation
45
+ | ConstraintCategory :: Internal => write ! ( f, "" ) ,
53
46
}
54
47
}
55
48
}
@@ -71,7 +64,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
71
64
fn best_blame_constraint (
72
65
& self ,
73
66
mir : & Mir < ' tcx > ,
74
- tcx : TyCtxt < ' _ , ' _ , ' tcx > ,
75
67
from_region : RegionVid ,
76
68
target_test : impl Fn ( RegionVid ) -> bool ,
77
69
) -> ( ConstraintCategory , Span , RegionVid ) {
@@ -96,7 +88,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
96
88
// Classify each of the constraints along the path.
97
89
let mut categorized_path: Vec < ( ConstraintCategory , Span ) > = path
98
90
. iter ( )
99
- . map ( |& index| self . classify_constraint ( index , mir, tcx ) )
91
+ . map ( |constraint| ( constraint . category , constraint . locations . span ( mir) ) )
100
92
. collect ( ) ;
101
93
debug ! (
102
94
"best_blame_constraint: categorized_path={:#?}" ,
@@ -129,12 +121,10 @@ impl<'tcx> RegionInferenceContext<'tcx> {
129
121
let constraint_sup_scc = self . constraint_sccs . scc ( constraint. sup ) ;
130
122
131
123
match categorized_path[ i] . 0 {
132
- ConstraintCategory :: Boring => false ,
133
- ConstraintCategory :: Other => {
134
- // other isn't interesting when the two lifetimes
135
- // are unified.
136
- constraint_sup_scc != self . constraint_sccs . scc ( constraint. sub )
137
- }
124
+ ConstraintCategory :: OpaqueType
125
+ | ConstraintCategory :: Boring
126
+ | ConstraintCategory :: BoringNoLocation
127
+ | ConstraintCategory :: Internal => false ,
138
128
_ => constraint_sup_scc != target_scc,
139
129
}
140
130
} ) ;
@@ -220,106 +210,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
220
210
None
221
211
}
222
212
223
- /// This function will return true if a constraint is interesting and false if a constraint
224
- /// is not. It is useful in filtering constraint paths to only interesting points.
225
- fn constraint_is_interesting ( & self , constraint : OutlivesConstraint ) -> bool {
226
- debug ! (
227
- "constraint_is_interesting: locations={:?} constraint={:?}" ,
228
- constraint. locations, constraint
229
- ) ;
230
-
231
- match constraint. locations {
232
- Locations :: Interesting ( _) | Locations :: All => true ,
233
- _ => false ,
234
- }
235
- }
236
-
237
- /// This function classifies a constraint from a location.
238
- fn classify_constraint (
239
- & self ,
240
- constraint : OutlivesConstraint ,
241
- mir : & Mir < ' tcx > ,
242
- tcx : TyCtxt < ' _ , ' _ , ' tcx > ,
243
- ) -> ( ConstraintCategory , Span ) {
244
- debug ! ( "classify_constraint: constraint={:?}" , constraint) ;
245
- let span = constraint. locations . span ( mir) ;
246
- let location = constraint
247
- . locations
248
- . from_location ( )
249
- . unwrap_or ( Location :: START ) ;
250
-
251
- if !self . constraint_is_interesting ( constraint) {
252
- return ( ConstraintCategory :: Boring , span) ;
253
- }
254
-
255
- let data = & mir[ location. block ] ;
256
- debug ! (
257
- "classify_constraint: location={:?} data={:?}" ,
258
- location, data
259
- ) ;
260
- let category = if location. statement_index == data. statements . len ( ) {
261
- if let Some ( ref terminator) = data. terminator {
262
- debug ! ( "classify_constraint: terminator.kind={:?}" , terminator. kind) ;
263
- match terminator. kind {
264
- TerminatorKind :: DropAndReplace { .. } => ConstraintCategory :: Assignment ,
265
- // Classify calls differently depending on whether or not
266
- // the sub region appears in the destination type (so the
267
- // sup region is in the return type). If the return type
268
- // contains the sub-region, then this is either an
269
- // assignment or a return, depending on whether we are
270
- // writing to the RETURN_PLACE or not.
271
- //
272
- // The idea here is that the region is being propagated
273
- // from an input into the output place, so it's a kind of
274
- // assignment. Otherwise, if the sub-region only appears in
275
- // the argument types, then use the CallArgument
276
- // classification.
277
- TerminatorKind :: Call { destination : Some ( ( ref place, _) ) , .. } => {
278
- if tcx. any_free_region_meets (
279
- & place. ty ( mir, tcx) . to_ty ( tcx) ,
280
- |region| self . to_region_vid ( region) == constraint. sub ,
281
- ) {
282
- match place {
283
- Place :: Local ( mir:: RETURN_PLACE ) => ConstraintCategory :: Return ,
284
- _ => ConstraintCategory :: Assignment ,
285
- }
286
- } else {
287
- ConstraintCategory :: CallArgument
288
- }
289
- }
290
- TerminatorKind :: Call { destination : None , .. } => {
291
- ConstraintCategory :: CallArgument
292
- }
293
- _ => ConstraintCategory :: Other ,
294
- }
295
- } else {
296
- ConstraintCategory :: Other
297
- }
298
- } else {
299
- let statement = & data. statements [ location. statement_index ] ;
300
- debug ! ( "classify_constraint: statement.kind={:?}" , statement. kind) ;
301
- match statement. kind {
302
- StatementKind :: Assign ( ref place, ref rvalue) => {
303
- debug ! ( "classify_constraint: place={:?} rvalue={:?}" , place, rvalue) ;
304
- if * place == Place :: Local ( mir:: RETURN_PLACE ) {
305
- ConstraintCategory :: Return
306
- } else {
307
- match rvalue {
308
- Rvalue :: Cast ( ..) => ConstraintCategory :: Cast ,
309
- Rvalue :: Use ( ..) | Rvalue :: Aggregate ( ..) => {
310
- ConstraintCategory :: Assignment
311
- }
312
- _ => ConstraintCategory :: Other ,
313
- }
314
- }
315
- }
316
- _ => ConstraintCategory :: Other ,
317
- }
318
- } ;
319
-
320
- ( category, span)
321
- }
322
-
323
213
/// Report an error because the universal region `fr` was required to outlive
324
214
/// `outlived_fr` but it is not known to do so. For example:
325
215
///
@@ -341,7 +231,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
341
231
342
232
let ( category, span, _) = self . best_blame_constraint (
343
233
mir,
344
- infcx. tcx ,
345
234
fr,
346
235
|r| r == outlived_fr
347
236
) ;
@@ -574,11 +463,10 @@ impl<'tcx> RegionInferenceContext<'tcx> {
574
463
crate fn find_outlives_blame_span (
575
464
& self ,
576
465
mir : & Mir < ' tcx > ,
577
- tcx : TyCtxt < ' _ , ' _ , ' tcx > ,
578
466
fr1 : RegionVid ,
579
467
fr2 : RegionVid ,
580
468
) -> Span {
581
- let ( _, span, _) = self . best_blame_constraint ( mir, tcx , fr1, |r| r == fr2) ;
469
+ let ( _, span, _) = self . best_blame_constraint ( mir, fr1, |r| r == fr2) ;
582
470
span
583
471
}
584
472
}
0 commit comments