1
- use crate :: infer:: at:: At ;
2
- use crate :: infer:: canonical:: OriginalQueryValues ;
3
- use crate :: infer:: InferOk ;
4
-
5
- use rustc_middle:: ty:: subst:: GenericArg ;
6
1
use rustc_middle:: ty:: { self , Ty , TyCtxt } ;
7
2
8
3
pub use rustc_middle:: traits:: query:: { DropckConstraint , DropckOutlivesResult } ;
9
4
10
- pub trait AtExt < ' tcx > {
11
- fn dropck_outlives ( & self , ty : Ty < ' tcx > ) -> InferOk < ' tcx , Vec < GenericArg < ' tcx > > > ;
12
- }
13
-
14
- impl < ' cx , ' tcx > AtExt < ' tcx > for At < ' cx , ' tcx > {
15
- /// Given a type `ty` of some value being dropped, computes a set
16
- /// of "kinds" (types, regions) that must be outlive the execution
17
- /// of the destructor. These basically correspond to data that the
18
- /// destructor might access. This is used during regionck to
19
- /// impose "outlives" constraints on any lifetimes referenced
20
- /// within.
21
- ///
22
- /// The rules here are given by the "dropck" RFCs, notably [#1238]
23
- /// and [#1327]. This is a fixed-point computation, where we
24
- /// explore all the data that will be dropped (transitively) when
25
- /// a value of type `ty` is dropped. For each type T that will be
26
- /// dropped and which has a destructor, we must assume that all
27
- /// the types/regions of T are live during the destructor, unless
28
- /// they are marked with a special attribute (`#[may_dangle]`).
29
- ///
30
- /// [#1238]: https://github.com/rust-lang/rfcs/blob/master/text/1238-nonparametric-dropck.md
31
- /// [#1327]: https://github.com/rust-lang/rfcs/blob/master/text/1327-dropck-param-eyepatch.md
32
- fn dropck_outlives ( & self , ty : Ty < ' tcx > ) -> InferOk < ' tcx , Vec < GenericArg < ' tcx > > > {
33
- debug ! ( "dropck_outlives(ty={:?}, param_env={:?})" , ty, self . param_env, ) ;
34
-
35
- // Quick check: there are a number of cases that we know do not require
36
- // any destructor.
37
- let tcx = self . infcx . tcx ;
38
- if trivial_dropck_outlives ( tcx, ty) {
39
- return InferOk { value : vec ! [ ] , obligations : vec ! [ ] } ;
40
- }
41
-
42
- let mut orig_values = OriginalQueryValues :: default ( ) ;
43
- let c_ty = self . infcx . canonicalize_query ( self . param_env . and ( ty) , & mut orig_values) ;
44
- let span = self . cause . span ;
45
- debug ! ( "c_ty = {:?}" , c_ty) ;
46
- if let Ok ( result) = tcx. dropck_outlives ( c_ty)
47
- && result. is_proven ( )
48
- && let Ok ( InferOk { value, obligations } ) =
49
- self . infcx . instantiate_query_response_and_region_obligations (
50
- self . cause ,
51
- self . param_env ,
52
- & orig_values,
53
- result,
54
- )
55
- {
56
- let ty = self . infcx . resolve_vars_if_possible ( ty) ;
57
- let kinds = value. into_kinds_reporting_overflows ( tcx, span, ty) ;
58
- return InferOk { value : kinds, obligations } ;
59
- }
60
-
61
- // Errors and ambiguity in dropck occur in two cases:
62
- // - unresolved inference variables at the end of typeck
63
- // - non well-formed types where projections cannot be resolved
64
- // Either of these should have created an error before.
65
- tcx. sess . delay_span_bug ( span, "dtorck encountered internal error" ) ;
66
-
67
- InferOk { value : vec ! [ ] , obligations : vec ! [ ] }
68
- }
69
- }
70
-
71
5
/// This returns true if the type `ty` is "trivial" for
72
6
/// dropck-outlives -- that is, if it doesn't require any types to
73
7
/// outlive. This is similar but not *quite* the same as the
@@ -79,6 +13,8 @@ impl<'cx, 'tcx> AtExt<'tcx> for At<'cx, 'tcx> {
79
13
///
80
14
/// Note also that `needs_drop` requires a "global" type (i.e., one
81
15
/// with erased regions), but this function does not.
16
+ ///
17
+ // FIXME(@lcnr): remove this module and move this function somewhere else.
82
18
pub fn trivial_dropck_outlives < ' tcx > ( tcx : TyCtxt < ' tcx > , ty : Ty < ' tcx > ) -> bool {
83
19
match ty. kind ( ) {
84
20
// None of these types have a destructor and hence they do not
@@ -105,7 +41,7 @@ pub fn trivial_dropck_outlives<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool {
105
41
ty:: Array ( ty, _) | ty:: Slice ( ty) => trivial_dropck_outlives ( tcx, * ty) ,
106
42
107
43
// (T1..Tn) and closures have same properties as T1..Tn --
108
- // check if *any * of those are trivial.
44
+ // check if *all * of them are trivial.
109
45
ty:: Tuple ( tys) => tys. iter ( ) . all ( |t| trivial_dropck_outlives ( tcx, t) ) ,
110
46
ty:: Closure ( _, ref substs) => {
111
47
trivial_dropck_outlives ( tcx, substs. as_closure ( ) . tupled_upvars_ty ( ) )
0 commit comments