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 ;
61use rustc_middle:: ty:: { self , Ty , TyCtxt } ;
72
83pub use rustc_middle:: traits:: query:: { DropckConstraint , DropckOutlivesResult } ;
94
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-
715/// This returns true if the type `ty` is "trivial" for
726/// dropck-outlives -- that is, if it doesn't require any types to
737/// outlive. This is similar but not *quite* the same as the
@@ -79,6 +13,8 @@ impl<'cx, 'tcx> AtExt<'tcx> for At<'cx, 'tcx> {
7913///
8014/// Note also that `needs_drop` requires a "global" type (i.e., one
8115/// with erased regions), but this function does not.
16+ ///
17+ // FIXME(@lcnr): remove this module and move this function somewhere else.
8218pub fn trivial_dropck_outlives < ' tcx > ( tcx : TyCtxt < ' tcx > , ty : Ty < ' tcx > ) -> bool {
8319 match ty. kind ( ) {
8420 // 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 {
10541 ty:: Array ( ty, _) | ty:: Slice ( ty) => trivial_dropck_outlives ( tcx, * ty) ,
10642
10743 // (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.
10945 ty:: Tuple ( tys) => tys. iter ( ) . all ( |t| trivial_dropck_outlives ( tcx, t) ) ,
11046 ty:: Closure ( _, ref substs) => {
11147 trivial_dropck_outlives ( tcx, substs. as_closure ( ) . tupled_upvars_ty ( ) )
0 commit comments