@@ -283,6 +283,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
283283 if self . is_in_const_context {
284284 self . assemble_const_drop_candidates ( obligation, & mut candidates) ?;
285285 } else {
286+ debug ! ( "passing ~const Drop bound; in non-const context" ) ;
286287 // `~const Drop` when we are not in a const context has no effect.
287288 candidates. vec . push ( ConstDropCandidate )
288289 }
@@ -821,6 +822,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
821822 let mut stack: Vec < ( Ty < ' tcx > , usize ) > = vec ! [ ( obligation. self_ty( ) . skip_binder( ) , 0 ) ] ;
822823
823824 while let Some ( ( ty, depth) ) = stack. pop ( ) {
825+ let mut noreturn = false ;
826+
824827 self . check_recursion_depth ( depth, obligation) ?;
825828 let mut copy_candidates = SelectionCandidateSet { vec : Vec :: new ( ) , ambiguous : false } ;
826829 let mut copy_obligation =
@@ -836,8 +839,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
836839 let copy_conditions = self . copy_clone_conditions ( & copy_obligation) ;
837840 self . assemble_builtin_bound_candidates ( copy_conditions, & mut copy_candidates) ;
838841 if !copy_candidates. vec . is_empty ( ) {
839- continue ;
842+ noreturn = true ;
840843 }
844+ debug ! ( ?copy_candidates. vec, "assemble_const_drop_candidates - copy" ) ;
841845
842846 match ty. kind ( ) {
843847 ty:: Int ( _)
@@ -857,22 +861,28 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
857861
858862 ty:: Adt ( def, subst) => {
859863 let mut set = SelectionCandidateSet { vec : Vec :: new ( ) , ambiguous : false } ;
860- self . assemble_candidates_from_impls ( obligation, & mut set) ;
861- if set
862- . vec
863- . into_iter ( )
864- . find ( |candidate| {
865- if let SelectionCandidate :: ImplCandidate ( did) = candidate {
866- matches ! ( self . tcx( ) . impl_constness( * did) , hir:: Constness :: NotConst )
867- } else {
868- false
869- }
870- } )
871- . is_none ( )
872- {
873- // could not find a const impl for Drop, iterate over its fields.
874- stack
875- . extend ( def. all_fields ( ) . map ( |f| ( f. ty ( self . tcx ( ) , subst) , depth + 1 ) ) ) ;
864+ self . assemble_candidates_from_impls (
865+ & obligation. with ( obligation. predicate . map_bound ( |mut pred| {
866+ pred. trait_ref . substs = self . tcx ( ) . mk_substs_trait ( ty, & [ ] ) ;
867+ pred
868+ } ) ) ,
869+ & mut set,
870+ ) ;
871+ stack. extend ( def. all_fields ( ) . map ( |f| ( f. ty ( self . tcx ( ) , subst) , depth + 1 ) ) ) ;
872+
873+ debug ! ( ?set. vec, "assemble_const_drop_candidates - ty::Adt" ) ;
874+ if set. vec . into_iter ( ) . any ( |candidate| {
875+ if let SelectionCandidate :: ImplCandidate ( did) = candidate {
876+ matches ! ( self . tcx( ) . impl_constness( did) , hir:: Constness :: NotConst )
877+ } else {
878+ false
879+ }
880+ } ) {
881+ if !noreturn {
882+ // has non-const Drop
883+ return Ok ( ( ) ) ;
884+ }
885+ debug ! ( "not returning" ) ;
876886 }
877887 }
878888
@@ -903,8 +913,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
903913 | ty:: Infer ( _)
904914 | ty:: Placeholder ( _)
905915 | ty:: Projection ( ..)
906- | ty:: Param ( ..) => return Ok ( ( ) ) ,
916+ | ty:: Param ( ..) => {
917+ if !noreturn {
918+ return Ok ( ( ) ) ;
919+ }
920+ debug ! ( "not returning" ) ;
921+ }
907922 }
923+ debug ! ( ?stack, "assemble_const_drop_candidates - in loop" ) ;
908924 }
909925 // all types have passed.
910926 candidates. vec . push ( ConstDropCandidate ) ;
0 commit comments