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.
This commit is contained in:
parent
8547f5732c
commit
b7e4433974
6 changed files with 31 additions and 17 deletions
|
@ -148,7 +148,7 @@ impl Qualif for NeedsNonConstDrop {
|
||||||
|
|
||||||
fn in_any_value_of_ty<'tcx>(cx: &ConstCx<'_, 'tcx>, ty: Ty<'tcx>) -> bool {
|
fn in_any_value_of_ty<'tcx>(cx: &ConstCx<'_, 'tcx>, ty: Ty<'tcx>) -> bool {
|
||||||
// Avoid selecting for simple cases, such as builtin types.
|
// Avoid selecting for simple cases, such as builtin types.
|
||||||
if ty::util::trivial_const_drop(ty) {
|
if ty::util::is_trivially_const_drop(ty) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1041,7 +1041,7 @@ pub fn needs_drop_components<'tcx>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn trivial_const_drop<'tcx>(ty: Ty<'tcx>) -> bool {
|
pub fn is_trivially_const_drop<'tcx>(ty: Ty<'tcx>) -> bool {
|
||||||
match *ty.kind() {
|
match *ty.kind() {
|
||||||
ty::Bool
|
ty::Bool
|
||||||
| ty::Char
|
| ty::Char
|
||||||
|
@ -1055,7 +1055,8 @@ pub fn trivial_const_drop<'tcx>(ty: Ty<'tcx>) -> bool {
|
||||||
| ty::Ref(..)
|
| ty::Ref(..)
|
||||||
| ty::FnDef(..)
|
| ty::FnDef(..)
|
||||||
| ty::FnPtr(_)
|
| ty::FnPtr(_)
|
||||||
| ty::Never => true,
|
| ty::Never
|
||||||
|
| ty::Foreign(_) => true,
|
||||||
|
|
||||||
ty::Opaque(..)
|
ty::Opaque(..)
|
||||||
| ty::Dynamic(..)
|
| ty::Dynamic(..)
|
||||||
|
@ -1063,7 +1064,6 @@ pub fn trivial_const_drop<'tcx>(ty: Ty<'tcx>) -> bool {
|
||||||
| ty::Bound(..)
|
| ty::Bound(..)
|
||||||
| ty::Param(_)
|
| ty::Param(_)
|
||||||
| ty::Placeholder(_)
|
| ty::Placeholder(_)
|
||||||
| ty::Foreign(_)
|
|
||||||
| ty::Projection(_)
|
| ty::Projection(_)
|
||||||
| ty::Infer(_) => false,
|
| ty::Infer(_) => false,
|
||||||
|
|
||||||
|
@ -1071,9 +1071,9 @@ pub fn trivial_const_drop<'tcx>(ty: Ty<'tcx>) -> bool {
|
||||||
// we'll just perform trait selection.
|
// we'll just perform trait selection.
|
||||||
ty::Closure(..) | ty::Generator(..) | ty::GeneratorWitness(_) | ty::Adt(..) => false,
|
ty::Closure(..) | ty::Generator(..) | ty::GeneratorWitness(_) | ty::Adt(..) => false,
|
||||||
|
|
||||||
ty::Array(ty, _) | ty::Slice(ty) => trivial_const_drop(ty),
|
ty::Array(ty, _) | ty::Slice(ty) => is_trivially_const_drop(ty),
|
||||||
|
|
||||||
ty::Tuple(tys) => tys.iter().all(|ty| trivial_const_drop(ty.expect_ty())),
|
ty::Tuple(tys) => tys.iter().all(|ty| is_trivially_const_drop(ty.expect_ty())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -932,7 +932,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
| ty::Bound(..)
|
| ty::Bound(..)
|
||||||
| ty::Param(_)
|
| ty::Param(_)
|
||||||
| ty::Placeholder(_)
|
| ty::Placeholder(_)
|
||||||
| ty::Foreign(_)
|
|
||||||
| ty::Projection(_) => {
|
| ty::Projection(_) => {
|
||||||
// We don't know if these are `~const Drop`, at least
|
// We don't know if these are `~const Drop`, at least
|
||||||
// not structurally... so don't push a candidate.
|
// not structurally... so don't push a candidate.
|
||||||
|
@ -951,6 +950,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
| ty::FnDef(..)
|
| ty::FnDef(..)
|
||||||
| ty::FnPtr(_)
|
| ty::FnPtr(_)
|
||||||
| ty::Never
|
| ty::Never
|
||||||
|
| ty::Foreign(_)
|
||||||
| ty::Array(..)
|
| ty::Array(..)
|
||||||
| ty::Slice(_)
|
| ty::Slice(_)
|
||||||
| ty::Closure(..)
|
| ty::Closure(..)
|
||||||
|
|
|
@ -1133,7 +1133,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
| ty::Ref(..)
|
| ty::Ref(..)
|
||||||
| ty::FnDef(..)
|
| ty::FnDef(..)
|
||||||
| ty::FnPtr(_)
|
| ty::FnPtr(_)
|
||||||
| ty::Never => {}
|
| ty::Never
|
||||||
|
| ty::Foreign(_) => {}
|
||||||
|
|
||||||
// These types are built-in, so we can fast-track by registering
|
// These types are built-in, so we can fast-track by registering
|
||||||
// nested predicates for their constituient type(s)
|
// nested predicates for their constituient type(s)
|
||||||
|
|
|
@ -228,15 +228,15 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
|
||||||
let predicate = predicate.kind();
|
let predicate = predicate.kind();
|
||||||
let p = p.kind();
|
let p = p.kind();
|
||||||
match (predicate.skip_binder(), p.skip_binder()) {
|
match (predicate.skip_binder(), p.skip_binder()) {
|
||||||
(ty::PredicateKind::Trait(a), ty::PredicateKind::Trait(b)) => relator
|
(ty::PredicateKind::Trait(a), ty::PredicateKind::Trait(b)) => {
|
||||||
.relate(
|
// Since struct predicates cannot have ~const, project the impl predicate
|
||||||
predicate.rebind(ty::TraitPredicate {
|
// onto one that ignores the constness. This is equivalent to saying that
|
||||||
constness: ty::BoundConstness::NotConst,
|
// we match a `Trait` bound on the struct with a `Trait` or `~const Trait`
|
||||||
..a
|
// in the impl.
|
||||||
}),
|
let non_const_a =
|
||||||
p.rebind(b),
|
ty::TraitPredicate { constness: ty::BoundConstness::NotConst, ..a };
|
||||||
)
|
relator.relate(predicate.rebind(non_const_a), p.rebind(b)).is_ok()
|
||||||
.is_ok(),
|
}
|
||||||
(ty::PredicateKind::Projection(a), ty::PredicateKind::Projection(b)) => {
|
(ty::PredicateKind::Projection(a), ty::PredicateKind::Projection(b)) => {
|
||||||
relator.relate(predicate.rebind(a), p.rebind(b)).is_ok()
|
relator.relate(predicate.rebind(a), p.rebind(b)).is_ok()
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,6 +53,10 @@ mod t {
|
||||||
impl const SomeTrait for () {
|
impl const SomeTrait for () {
|
||||||
fn foo() {}
|
fn foo() {}
|
||||||
}
|
}
|
||||||
|
// non-const impl
|
||||||
|
impl SomeTrait for i32 {
|
||||||
|
fn foo() {}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct ConstDropWithBound<T: SomeTrait>(pub core::marker::PhantomData<T>);
|
pub struct ConstDropWithBound<T: SomeTrait>(pub core::marker::PhantomData<T>);
|
||||||
|
|
||||||
|
@ -61,6 +65,14 @@ mod t {
|
||||||
T::foo();
|
T::foo();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct ConstDropWithNonconstBound<T: SomeTrait>(pub core::marker::PhantomData<T>);
|
||||||
|
|
||||||
|
impl<T: SomeTrait> const Drop for ConstDropWithNonconstBound<T> {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
// Note: we DON'T use the `T: SomeTrait` bound
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
use t::*;
|
use t::*;
|
||||||
|
@ -78,6 +90,7 @@ implements_const_drop! {
|
||||||
&1,
|
&1,
|
||||||
&1 as *const i32,
|
&1 as *const i32,
|
||||||
ConstDropWithBound::<()>,
|
ConstDropWithBound::<()>,
|
||||||
|
ConstDropWithNonconstBound::<i32>,
|
||||||
Result::<i32, !>::Ok(1),
|
Result::<i32, !>::Ok(1),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue