8
8
//! https://rustc-dev-guide.rust-lang.org/traits/resolution.html#confirmation
9
9
use rustc_data_structures:: stack:: ensure_sufficient_stack;
10
10
use rustc_hir:: lang_items:: LangItem ;
11
- use rustc_hir:: Constness ;
12
11
use rustc_index:: bit_set:: GrowableBitSet ;
13
12
use rustc_infer:: infer:: InferOk ;
14
13
use rustc_infer:: infer:: LateBoundRegionConversionTime :: HigherRankedType ;
@@ -29,9 +28,9 @@ use crate::traits::TraitNotObjectSafe;
29
28
use crate :: traits:: VtblSegment ;
30
29
use crate :: traits:: { BuiltinDerivedObligation , ImplDerivedObligation } ;
31
30
use crate :: traits:: {
32
- ImplSourceAutoImplData , ImplSourceBuiltinData , ImplSourceClosureData , ImplSourceConstDropData ,
33
- ImplSourceDiscriminantKindData , ImplSourceFnPointerData , ImplSourceGeneratorData ,
34
- ImplSourceObjectData , ImplSourcePointeeData , ImplSourceTraitAliasData ,
31
+ ImplSourceAutoImplData , ImplSourceBuiltinData , ImplSourceClosureData ,
32
+ ImplSourceConstDestructData , ImplSourceDiscriminantKindData , ImplSourceFnPointerData ,
33
+ ImplSourceGeneratorData , ImplSourceObjectData , ImplSourcePointeeData , ImplSourceTraitAliasData ,
35
34
ImplSourceTraitUpcastingData , ImplSourceUserDefinedData ,
36
35
} ;
37
36
use crate :: traits:: { ObjectCastObligation , PredicateObligation , TraitObligation } ;
@@ -156,9 +155,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
156
155
Ok ( ImplSource :: TraitUpcasting ( data) )
157
156
}
158
157
159
- ConstDropCandidate ( def_id) => {
160
- let data = self . confirm_const_drop_candidate ( obligation, def_id) ?;
161
- Ok ( ImplSource :: ConstDrop ( data) )
158
+ ConstDestructCandidate ( def_id) => {
159
+ let data = self . confirm_const_destruct_candidate ( obligation, def_id) ?;
160
+ Ok ( ImplSource :: ConstDestruct ( data) )
162
161
}
163
162
}
164
163
}
@@ -1037,14 +1036,24 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1037
1036
Ok ( ImplSourceBuiltinData { nested } )
1038
1037
}
1039
1038
1040
- fn confirm_const_drop_candidate (
1039
+ fn confirm_const_destruct_candidate (
1041
1040
& mut self ,
1042
1041
obligation : & TraitObligation < ' tcx > ,
1043
1042
impl_def_id : Option < DefId > ,
1044
- ) -> Result < ImplSourceConstDropData < PredicateObligation < ' tcx > > , SelectionError < ' tcx > > {
1045
- // `~const Drop` in a non-const environment is always trivially true, since our type is `Drop`
1046
- if obligation. param_env . constness ( ) == Constness :: NotConst {
1047
- return Ok ( ImplSourceConstDropData { nested : vec ! [ ] } ) ;
1043
+ ) -> Result < ImplSourceConstDestructData < PredicateObligation < ' tcx > > , SelectionError < ' tcx > > {
1044
+ // `~const Destruct` in a non-const environment is always trivially true, since our type is `Drop`
1045
+ if !obligation. is_const ( ) {
1046
+ return Ok ( ImplSourceConstDestructData { nested : vec ! [ ] } ) ;
1047
+ }
1048
+
1049
+ let drop_trait = self . tcx ( ) . require_lang_item ( LangItem :: Drop , None ) ;
1050
+ // FIXME: remove if statement below when beta is bumped
1051
+ #[ cfg( bootstrap) ]
1052
+ { }
1053
+
1054
+ if obligation. predicate . skip_binder ( ) . def_id ( ) == drop_trait
1055
+ {
1056
+ return Ok ( ImplSourceConstDestructData { nested : vec ! [ ] } ) ;
1048
1057
}
1049
1058
1050
1059
let tcx = self . tcx ( ) ;
@@ -1054,9 +1063,26 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1054
1063
let cause = obligation. derived_cause ( BuiltinDerivedObligation ) ;
1055
1064
1056
1065
// If we have a custom `impl const Drop`, then
1057
- // first check it like a regular impl candidate
1066
+ // first check it like a regular impl candidate.
1067
+ // This is copied from confirm_impl_candidate but remaps the predicate to `~const Drop` beforehand.
1058
1068
if let Some ( impl_def_id) = impl_def_id {
1059
- nested. extend ( self . confirm_impl_candidate ( obligation, impl_def_id) . nested ) ;
1069
+ let obligations = self . infcx . commit_unconditionally ( |_| {
1070
+ let mut new_obligation = obligation. clone ( ) ;
1071
+ new_obligation. predicate = new_obligation. predicate . map_bound ( |mut trait_pred| { trait_pred. trait_ref . def_id = drop_trait; trait_pred } ) ;
1072
+ let substs = self . rematch_impl ( impl_def_id, & new_obligation) ;
1073
+ debug ! ( ?substs, "impl substs" ) ;
1074
+ let cause = obligation. derived_cause ( ImplDerivedObligation ) ;
1075
+ ensure_sufficient_stack ( || {
1076
+ self . vtable_impl (
1077
+ impl_def_id,
1078
+ substs,
1079
+ cause,
1080
+ new_obligation. recursion_depth + 1 ,
1081
+ new_obligation. param_env ,
1082
+ )
1083
+ } )
1084
+ } ) ;
1085
+ nested. extend ( obligations. nested ) ;
1060
1086
}
1061
1087
1062
1088
// We want to confirm the ADT's fields if we have an ADT
@@ -1114,7 +1140,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1114
1140
self_ty
1115
1141
. rebind ( ty:: TraitPredicate {
1116
1142
trait_ref : ty:: TraitRef {
1117
- def_id : self . tcx ( ) . require_lang_item ( LangItem :: Drop , None ) ,
1143
+ def_id : self . tcx ( ) . require_lang_item ( LangItem :: Destruct , None ) ,
1118
1144
substs : self . tcx ( ) . mk_substs_trait ( nested_ty, & [ ] ) ,
1119
1145
} ,
1120
1146
constness : ty:: BoundConstness :: ConstIfConst ,
@@ -1140,7 +1166,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1140
1166
let predicate = self_ty
1141
1167
. rebind ( ty:: TraitPredicate {
1142
1168
trait_ref : ty:: TraitRef {
1143
- def_id : self . tcx ( ) . require_lang_item ( LangItem :: Drop , None ) ,
1169
+ def_id : self . tcx ( ) . require_lang_item ( LangItem :: Destruct , None ) ,
1144
1170
substs : self . tcx ( ) . mk_substs_trait ( nested_ty, & [ ] ) ,
1145
1171
} ,
1146
1172
constness : ty:: BoundConstness :: ConstIfConst ,
@@ -1158,6 +1184,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1158
1184
}
1159
1185
}
1160
1186
1161
- Ok ( ImplSourceConstDropData { nested } )
1187
+ Ok ( ImplSourceConstDestructData { nested } )
1162
1188
}
1163
1189
}
0 commit comments