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,23 @@ 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
+ return Ok ( ImplSourceConstDestructData { nested : vec ! [ ] } ) ;
1048
1056
}
1049
1057
1050
1058
let tcx = self . tcx ( ) ;
@@ -1054,9 +1062,29 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1054
1062
let cause = obligation. derived_cause ( BuiltinDerivedObligation ) ;
1055
1063
1056
1064
// If we have a custom `impl const Drop`, then
1057
- // first check it like a regular impl candidate
1065
+ // first check it like a regular impl candidate.
1066
+ // This is copied from confirm_impl_candidate but remaps the predicate to `~const Drop` beforehand.
1058
1067
if let Some ( impl_def_id) = impl_def_id {
1059
- nested. extend ( self . confirm_impl_candidate ( obligation, impl_def_id) . nested ) ;
1068
+ let obligations = self . infcx . commit_unconditionally ( |_| {
1069
+ let mut new_obligation = obligation. clone ( ) ;
1070
+ new_obligation. predicate = new_obligation. predicate . map_bound ( |mut trait_pred| {
1071
+ trait_pred. trait_ref . def_id = drop_trait;
1072
+ trait_pred
1073
+ } ) ;
1074
+ let substs = self . rematch_impl ( impl_def_id, & new_obligation) ;
1075
+ debug ! ( ?substs, "impl substs" ) ;
1076
+ let cause = obligation. derived_cause ( ImplDerivedObligation ) ;
1077
+ ensure_sufficient_stack ( || {
1078
+ self . vtable_impl (
1079
+ impl_def_id,
1080
+ substs,
1081
+ cause,
1082
+ new_obligation. recursion_depth + 1 ,
1083
+ new_obligation. param_env ,
1084
+ )
1085
+ } )
1086
+ } ) ;
1087
+ nested. extend ( obligations. nested ) ;
1060
1088
}
1061
1089
1062
1090
// We want to confirm the ADT's fields if we have an ADT
@@ -1114,7 +1142,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1114
1142
self_ty
1115
1143
. rebind ( ty:: TraitPredicate {
1116
1144
trait_ref : ty:: TraitRef {
1117
- def_id : self . tcx ( ) . require_lang_item ( LangItem :: Drop , None ) ,
1145
+ def_id : self
1146
+ . tcx ( )
1147
+ . require_lang_item ( LangItem :: Destruct , None ) ,
1118
1148
substs : self . tcx ( ) . mk_substs_trait ( nested_ty, & [ ] ) ,
1119
1149
} ,
1120
1150
constness : ty:: BoundConstness :: ConstIfConst ,
@@ -1140,7 +1170,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1140
1170
let predicate = self_ty
1141
1171
. rebind ( ty:: TraitPredicate {
1142
1172
trait_ref : ty:: TraitRef {
1143
- def_id : self . tcx ( ) . require_lang_item ( LangItem :: Drop , None ) ,
1173
+ def_id : self . tcx ( ) . require_lang_item ( LangItem :: Destruct , None ) ,
1144
1174
substs : self . tcx ( ) . mk_substs_trait ( nested_ty, & [ ] ) ,
1145
1175
} ,
1146
1176
constness : ty:: BoundConstness :: ConstIfConst ,
@@ -1158,6 +1188,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1158
1188
}
1159
1189
}
1160
1190
1161
- Ok ( ImplSourceConstDropData { nested } )
1191
+ Ok ( ImplSourceConstDestructData { nested } )
1162
1192
}
1163
1193
}
0 commit comments