Skip to content

Commit b7e4433

Browse files
Foreign types are trivially drop
- Also rename a trivial_const_drop to match style of other functions in the util module. - Also add a test for `const Drop` that doesn't depend on a `~const` bound. - Also comment a bit why we remove the const bound during dropck impl check.
1 parent 8547f57 commit b7e4433

File tree

6 files changed

+31
-17
lines changed

6 files changed

+31
-17
lines changed

Diff for: compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ impl Qualif for NeedsNonConstDrop {
148148

149149
fn in_any_value_of_ty<'tcx>(cx: &ConstCx<'_, 'tcx>, ty: Ty<'tcx>) -> bool {
150150
// Avoid selecting for simple cases, such as builtin types.
151-
if ty::util::trivial_const_drop(ty) {
151+
if ty::util::is_trivially_const_drop(ty) {
152152
return false;
153153
}
154154

Diff for: compiler/rustc_middle/src/ty/util.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -1041,7 +1041,7 @@ pub fn needs_drop_components<'tcx>(
10411041
}
10421042
}
10431043

1044-
pub fn trivial_const_drop<'tcx>(ty: Ty<'tcx>) -> bool {
1044+
pub fn is_trivially_const_drop<'tcx>(ty: Ty<'tcx>) -> bool {
10451045
match *ty.kind() {
10461046
ty::Bool
10471047
| ty::Char
@@ -1055,25 +1055,25 @@ pub fn trivial_const_drop<'tcx>(ty: Ty<'tcx>) -> bool {
10551055
| ty::Ref(..)
10561056
| ty::FnDef(..)
10571057
| ty::FnPtr(_)
1058-
| ty::Never => true,
1058+
| ty::Never
1059+
| ty::Foreign(_) => true,
10591060

10601061
ty::Opaque(..)
10611062
| ty::Dynamic(..)
10621063
| ty::Error(_)
10631064
| ty::Bound(..)
10641065
| ty::Param(_)
10651066
| ty::Placeholder(_)
1066-
| ty::Foreign(_)
10671067
| ty::Projection(_)
10681068
| ty::Infer(_) => false,
10691069

10701070
// Not trivial because they have components, and instead of looking inside,
10711071
// we'll just perform trait selection.
10721072
ty::Closure(..) | ty::Generator(..) | ty::GeneratorWitness(_) | ty::Adt(..) => false,
10731073

1074-
ty::Array(ty, _) | ty::Slice(ty) => trivial_const_drop(ty),
1074+
ty::Array(ty, _) | ty::Slice(ty) => is_trivially_const_drop(ty),
10751075

1076-
ty::Tuple(tys) => tys.iter().all(|ty| trivial_const_drop(ty.expect_ty())),
1076+
ty::Tuple(tys) => tys.iter().all(|ty| is_trivially_const_drop(ty.expect_ty())),
10771077
}
10781078
}
10791079

Diff for: compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -932,7 +932,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
932932
| ty::Bound(..)
933933
| ty::Param(_)
934934
| ty::Placeholder(_)
935-
| ty::Foreign(_)
936935
| ty::Projection(_) => {
937936
// We don't know if these are `~const Drop`, at least
938937
// not structurally... so don't push a candidate.
@@ -951,6 +950,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
951950
| ty::FnDef(..)
952951
| ty::FnPtr(_)
953952
| ty::Never
953+
| ty::Foreign(_)
954954
| ty::Array(..)
955955
| ty::Slice(_)
956956
| ty::Closure(..)

Diff for: compiler/rustc_trait_selection/src/traits/select/confirmation.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1133,7 +1133,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
11331133
| ty::Ref(..)
11341134
| ty::FnDef(..)
11351135
| ty::FnPtr(_)
1136-
| ty::Never => {}
1136+
| ty::Never
1137+
| ty::Foreign(_) => {}
11371138

11381139
// These types are built-in, so we can fast-track by registering
11391140
// nested predicates for their constituient type(s)

Diff for: compiler/rustc_typeck/src/check/dropck.rs

+9-9
Original file line numberDiff line numberDiff line change
@@ -228,15 +228,15 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
228228
let predicate = predicate.kind();
229229
let p = p.kind();
230230
match (predicate.skip_binder(), p.skip_binder()) {
231-
(ty::PredicateKind::Trait(a), ty::PredicateKind::Trait(b)) => relator
232-
.relate(
233-
predicate.rebind(ty::TraitPredicate {
234-
constness: ty::BoundConstness::NotConst,
235-
..a
236-
}),
237-
p.rebind(b),
238-
)
239-
.is_ok(),
231+
(ty::PredicateKind::Trait(a), ty::PredicateKind::Trait(b)) => {
232+
// Since struct predicates cannot have ~const, project the impl predicate
233+
// onto one that ignores the constness. This is equivalent to saying that
234+
// we match a `Trait` bound on the struct with a `Trait` or `~const Trait`
235+
// in the impl.
236+
let non_const_a =
237+
ty::TraitPredicate { constness: ty::BoundConstness::NotConst, ..a };
238+
relator.relate(predicate.rebind(non_const_a), p.rebind(b)).is_ok()
239+
}
240240
(ty::PredicateKind::Projection(a), ty::PredicateKind::Projection(b)) => {
241241
relator.relate(predicate.rebind(a), p.rebind(b)).is_ok()
242242
}

Diff for: src/test/ui/rfc-2632-const-trait-impl/const-drop.rs

+13
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ mod t {
5353
impl const SomeTrait for () {
5454
fn foo() {}
5555
}
56+
// non-const impl
57+
impl SomeTrait for i32 {
58+
fn foo() {}
59+
}
5660

5761
pub struct ConstDropWithBound<T: SomeTrait>(pub core::marker::PhantomData<T>);
5862

@@ -61,6 +65,14 @@ mod t {
6165
T::foo();
6266
}
6367
}
68+
69+
pub struct ConstDropWithNonconstBound<T: SomeTrait>(pub core::marker::PhantomData<T>);
70+
71+
impl<T: SomeTrait> const Drop for ConstDropWithNonconstBound<T> {
72+
fn drop(&mut self) {
73+
// Note: we DON'T use the `T: SomeTrait` bound
74+
}
75+
}
6476
}
6577

6678
use t::*;
@@ -78,6 +90,7 @@ implements_const_drop! {
7890
&1,
7991
&1 as *const i32,
8092
ConstDropWithBound::<()>,
93+
ConstDropWithNonconstBound::<i32>,
8194
Result::<i32, !>::Ok(1),
8295
}
8396

0 commit comments

Comments
 (0)