mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-26 13:01:27 +03:00
Reject implementing const Drop for types that are not const Destruct already
This commit is contained in:
@@ -11,7 +11,7 @@
|
|||||||
use rustc_infer::traits::{ObligationCause, ObligationCauseCode};
|
use rustc_infer::traits::{ObligationCause, ObligationCauseCode};
|
||||||
use rustc_middle::span_bug;
|
use rustc_middle::span_bug;
|
||||||
use rustc_middle::ty::util::CheckRegions;
|
use rustc_middle::ty::util::CheckRegions;
|
||||||
use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt, TypingMode};
|
use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt, TypeVisitableExt, TypingMode};
|
||||||
use rustc_trait_selection::regions::InferCtxtRegionExt;
|
use rustc_trait_selection::regions::InferCtxtRegionExt;
|
||||||
use rustc_trait_selection::traits::{self, ObligationCtxt};
|
use rustc_trait_selection::traits::{self, ObligationCtxt};
|
||||||
|
|
||||||
@@ -65,6 +65,8 @@ pub(crate) fn check_drop_impl(
|
|||||||
adt_to_impl_args,
|
adt_to_impl_args,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
ensure_all_fields_are_const_destruct(tcx, drop_impl_did, adt_def.did())?;
|
||||||
|
|
||||||
ensure_impl_predicates_are_implied_by_item_defn(
|
ensure_impl_predicates_are_implied_by_item_defn(
|
||||||
tcx,
|
tcx,
|
||||||
drop_impl_did,
|
drop_impl_did,
|
||||||
@@ -173,6 +175,64 @@ fn ensure_impl_params_and_item_params_correspond<'tcx>(
|
|||||||
Err(err.emit())
|
Err(err.emit())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn ensure_all_fields_are_const_destruct<'tcx>(
|
||||||
|
tcx: TyCtxt<'tcx>,
|
||||||
|
impl_def_id: LocalDefId,
|
||||||
|
adt_def_id: DefId,
|
||||||
|
) -> Result<(), ErrorGuaranteed> {
|
||||||
|
if !tcx.is_conditionally_const(impl_def_id) {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
let infcx = tcx.infer_ctxt().build(TypingMode::non_body_analysis());
|
||||||
|
let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
|
||||||
|
|
||||||
|
let impl_span = tcx.def_span(impl_def_id.to_def_id());
|
||||||
|
let env =
|
||||||
|
ty::EarlyBinder::bind(tcx.param_env(impl_def_id)).instantiate_identity().skip_norm_wip();
|
||||||
|
let args = ty::GenericArgs::identity_for_item(tcx, impl_def_id);
|
||||||
|
let destruct_trait = tcx.lang_items().destruct_trait().unwrap();
|
||||||
|
for field in tcx.adt_def(adt_def_id).all_fields() {
|
||||||
|
let field_ty = field.ty(tcx, args);
|
||||||
|
let cause = traits::ObligationCause::new(
|
||||||
|
tcx.def_span(field.did),
|
||||||
|
impl_def_id,
|
||||||
|
ObligationCauseCode::Misc,
|
||||||
|
);
|
||||||
|
ocx.register_obligation(traits::Obligation::new(
|
||||||
|
tcx,
|
||||||
|
cause,
|
||||||
|
env,
|
||||||
|
ty::ClauseKind::HostEffect(ty::HostEffectPredicate {
|
||||||
|
trait_ref: ty::TraitRef::new(tcx, destruct_trait, [field_ty]),
|
||||||
|
constness: ty::BoundConstness::Maybe,
|
||||||
|
}),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
ocx.evaluate_obligations_error_on_ambiguity()
|
||||||
|
.into_iter()
|
||||||
|
.map(|error| {
|
||||||
|
let ty::ClauseKind::HostEffect(eff) =
|
||||||
|
error.root_obligation.predicate.expect_clause().kind().no_bound_vars().unwrap()
|
||||||
|
else {
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
|
let field_ty = eff.trait_ref.self_ty();
|
||||||
|
let diag = struct_span_code_err!(
|
||||||
|
tcx.dcx(),
|
||||||
|
error.root_obligation.cause.span,
|
||||||
|
E0367,
|
||||||
|
"`{field_ty}` does not implement `[const] Destruct`",
|
||||||
|
)
|
||||||
|
.with_span_note(impl_span, "required for this `Drop` impl");
|
||||||
|
if field_ty.has_param() {
|
||||||
|
// FIXME: suggest adding `[const] Destruct` by teaching
|
||||||
|
// `suggest_restricting_param_bound` about const traits.
|
||||||
|
}
|
||||||
|
Err(diag.emit())
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
/// Confirms that all predicates defined on the `Drop` impl (`drop_impl_def_id`) are able to be
|
/// Confirms that all predicates defined on the `Drop` impl (`drop_impl_def_id`) are able to be
|
||||||
/// proven from within `adt_def_id`'s environment. I.e. all the predicates on the impl are
|
/// proven from within `adt_def_id`'s environment. I.e. all the predicates on the impl are
|
||||||
/// implied by the ADT being well formed.
|
/// implied by the ADT being well formed.
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
#![feature(const_trait_impl)]
|
#![feature(const_trait_impl)]
|
||||||
#![feature(const_destruct)]
|
#![feature(const_destruct)]
|
||||||
//@ check-pass
|
|
||||||
|
|
||||||
use std::marker::Destruct;
|
use std::marker::Destruct;
|
||||||
|
|
||||||
@@ -11,12 +10,14 @@ fn drop(&mut self) {}
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct ConstDrop(NotConstDrop);
|
struct ConstDrop(NotConstDrop);
|
||||||
|
//~^ ERROR: `NotConstDrop` does not implement `[const] Destruct`
|
||||||
|
|
||||||
impl const Drop for ConstDrop {
|
impl const Drop for ConstDrop {
|
||||||
fn drop(&mut self) {}
|
fn drop(&mut self) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ConstDrop2<T>(T);
|
struct ConstDrop2<T>(T);
|
||||||
|
//~^ ERROR: `T` does not implement `[const] Destruct`
|
||||||
|
|
||||||
impl<T> const Drop for ConstDrop2<T> {
|
impl<T> const Drop for ConstDrop2<T> {
|
||||||
fn drop(&mut self) {}
|
fn drop(&mut self) {}
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
error[E0367]: `NotConstDrop` does not implement `[const] Destruct`
|
||||||
|
--> $DIR/drop-impl-nonconst-drop-field.rs:12:18
|
||||||
|
|
|
||||||
|
LL | struct ConstDrop(NotConstDrop);
|
||||||
|
| ^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
note: required for this `Drop` impl
|
||||||
|
--> $DIR/drop-impl-nonconst-drop-field.rs:15:1
|
||||||
|
|
|
||||||
|
LL | impl const Drop for ConstDrop {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0367]: `T` does not implement `[const] Destruct`
|
||||||
|
--> $DIR/drop-impl-nonconst-drop-field.rs:19:22
|
||||||
|
|
|
||||||
|
LL | struct ConstDrop2<T>(T);
|
||||||
|
| ^
|
||||||
|
|
|
||||||
|
note: required for this `Drop` impl
|
||||||
|
--> $DIR/drop-impl-nonconst-drop-field.rs:22:1
|
||||||
|
|
|
||||||
|
LL | impl<T> const Drop for ConstDrop2<T> {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0367`.
|
||||||
@@ -1,5 +1,17 @@
|
|||||||
|
error[E0367]: `NonTrivialDrop` does not implement `[const] Destruct`
|
||||||
|
--> $DIR/const-drop-fail.rs:19:30
|
||||||
|
|
|
||||||
|
LL | struct ConstImplWithDropGlue(NonTrivialDrop);
|
||||||
|
| ^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
note: required for this `Drop` impl
|
||||||
|
--> $DIR/const-drop-fail.rs:22:1
|
||||||
|
|
|
||||||
|
LL | impl const Drop for ConstImplWithDropGlue {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error[E0277]: the trait bound `NonTrivialDrop: const Destruct` is not satisfied
|
error[E0277]: the trait bound `NonTrivialDrop: const Destruct` is not satisfied
|
||||||
--> $DIR/const-drop-fail.rs:34:5
|
--> $DIR/const-drop-fail.rs:35:5
|
||||||
|
|
|
|
||||||
LL | const _: () = check($exp);
|
LL | const _: () = check($exp);
|
||||||
| ----- required by a bound introduced by this call
|
| ----- required by a bound introduced by this call
|
||||||
@@ -8,13 +20,13 @@ LL | NonTrivialDrop,
|
|||||||
| ^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
note: required by a bound in `check`
|
note: required by a bound in `check`
|
||||||
--> $DIR/const-drop-fail.rs:25:19
|
--> $DIR/const-drop-fail.rs:26:19
|
||||||
|
|
|
|
||||||
LL | const fn check<T: [const] Destruct>(_: T) {}
|
LL | const fn check<T: [const] Destruct>(_: T) {}
|
||||||
| ^^^^^^^^^^^^^^^^ required by this bound in `check`
|
| ^^^^^^^^^^^^^^^^ required by this bound in `check`
|
||||||
|
|
||||||
error[E0277]: the trait bound `NonTrivialDrop: const Destruct` is not satisfied
|
error[E0277]: the trait bound `NonTrivialDrop: const Destruct` is not satisfied
|
||||||
--> $DIR/const-drop-fail.rs:36:5
|
--> $DIR/const-drop-fail.rs:37:5
|
||||||
|
|
|
|
||||||
LL | const _: () = check($exp);
|
LL | const _: () = check($exp);
|
||||||
| ----- required by a bound introduced by this call
|
| ----- required by a bound introduced by this call
|
||||||
@@ -23,11 +35,12 @@ LL | ConstImplWithDropGlue(NonTrivialDrop),
|
|||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
note: required by a bound in `check`
|
note: required by a bound in `check`
|
||||||
--> $DIR/const-drop-fail.rs:25:19
|
--> $DIR/const-drop-fail.rs:26:19
|
||||||
|
|
|
|
||||||
LL | const fn check<T: [const] Destruct>(_: T) {}
|
LL | const fn check<T: [const] Destruct>(_: T) {}
|
||||||
| ^^^^^^^^^^^^^^^^ required by this bound in `check`
|
| ^^^^^^^^^^^^^^^^ required by this bound in `check`
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0277`.
|
Some errors have detailed explanations: E0277, E0367.
|
||||||
|
For more information about an error, try `rustc --explain E0277`.
|
||||||
|
|||||||
@@ -1,5 +1,17 @@
|
|||||||
|
error[E0367]: `NonTrivialDrop` does not implement `[const] Destruct`
|
||||||
|
--> $DIR/const-drop-fail.rs:19:30
|
||||||
|
|
|
||||||
|
LL | struct ConstImplWithDropGlue(NonTrivialDrop);
|
||||||
|
| ^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
note: required for this `Drop` impl
|
||||||
|
--> $DIR/const-drop-fail.rs:22:1
|
||||||
|
|
|
||||||
|
LL | impl const Drop for ConstImplWithDropGlue {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error[E0277]: the trait bound `NonTrivialDrop: const Destruct` is not satisfied
|
error[E0277]: the trait bound `NonTrivialDrop: const Destruct` is not satisfied
|
||||||
--> $DIR/const-drop-fail.rs:34:5
|
--> $DIR/const-drop-fail.rs:35:5
|
||||||
|
|
|
|
||||||
LL | const _: () = check($exp);
|
LL | const _: () = check($exp);
|
||||||
| ----- required by a bound introduced by this call
|
| ----- required by a bound introduced by this call
|
||||||
@@ -8,13 +20,13 @@ LL | NonTrivialDrop,
|
|||||||
| ^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
note: required by a bound in `check`
|
note: required by a bound in `check`
|
||||||
--> $DIR/const-drop-fail.rs:25:19
|
--> $DIR/const-drop-fail.rs:26:19
|
||||||
|
|
|
|
||||||
LL | const fn check<T: [const] Destruct>(_: T) {}
|
LL | const fn check<T: [const] Destruct>(_: T) {}
|
||||||
| ^^^^^^^^^^^^^^^^ required by this bound in `check`
|
| ^^^^^^^^^^^^^^^^ required by this bound in `check`
|
||||||
|
|
||||||
error[E0277]: the trait bound `NonTrivialDrop: const Destruct` is not satisfied
|
error[E0277]: the trait bound `NonTrivialDrop: const Destruct` is not satisfied
|
||||||
--> $DIR/const-drop-fail.rs:36:5
|
--> $DIR/const-drop-fail.rs:37:5
|
||||||
|
|
|
|
||||||
LL | const _: () = check($exp);
|
LL | const _: () = check($exp);
|
||||||
| ----- required by a bound introduced by this call
|
| ----- required by a bound introduced by this call
|
||||||
@@ -23,11 +35,12 @@ LL | ConstImplWithDropGlue(NonTrivialDrop),
|
|||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
note: required by a bound in `check`
|
note: required by a bound in `check`
|
||||||
--> $DIR/const-drop-fail.rs:25:19
|
--> $DIR/const-drop-fail.rs:26:19
|
||||||
|
|
|
|
||||||
LL | const fn check<T: [const] Destruct>(_: T) {}
|
LL | const fn check<T: [const] Destruct>(_: T) {}
|
||||||
| ^^^^^^^^^^^^^^^^ required by this bound in `check`
|
| ^^^^^^^^^^^^^^^^ required by this bound in `check`
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0277`.
|
Some errors have detailed explanations: E0277, E0367.
|
||||||
|
For more information about an error, try `rustc --explain E0277`.
|
||||||
|
|||||||
@@ -1,5 +1,17 @@
|
|||||||
|
error[E0367]: `NonTrivialDrop` does not implement `[const] Destruct`
|
||||||
|
--> $DIR/const-drop-fail.rs:19:30
|
||||||
|
|
|
||||||
|
LL | struct ConstImplWithDropGlue(NonTrivialDrop);
|
||||||
|
| ^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
note: required for this `Drop` impl
|
||||||
|
--> $DIR/const-drop-fail.rs:22:1
|
||||||
|
|
|
||||||
|
LL | impl const Drop for ConstImplWithDropGlue {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error[E0277]: the trait bound `NonTrivialDrop: const Destruct` is not satisfied
|
error[E0277]: the trait bound `NonTrivialDrop: const Destruct` is not satisfied
|
||||||
--> $DIR/const-drop-fail.rs:34:5
|
--> $DIR/const-drop-fail.rs:35:5
|
||||||
|
|
|
|
||||||
LL | const _: () = check($exp);
|
LL | const _: () = check($exp);
|
||||||
| ----- required by a bound introduced by this call
|
| ----- required by a bound introduced by this call
|
||||||
@@ -8,13 +20,13 @@ LL | NonTrivialDrop,
|
|||||||
| ^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
note: required by a bound in `check`
|
note: required by a bound in `check`
|
||||||
--> $DIR/const-drop-fail.rs:25:19
|
--> $DIR/const-drop-fail.rs:26:19
|
||||||
|
|
|
|
||||||
LL | const fn check<T: [const] Destruct>(_: T) {}
|
LL | const fn check<T: [const] Destruct>(_: T) {}
|
||||||
| ^^^^^^^^^^^^^^^^ required by this bound in `check`
|
| ^^^^^^^^^^^^^^^^ required by this bound in `check`
|
||||||
|
|
||||||
error[E0277]: the trait bound `NonTrivialDrop: const Destruct` is not satisfied
|
error[E0277]: the trait bound `NonTrivialDrop: const Destruct` is not satisfied
|
||||||
--> $DIR/const-drop-fail.rs:36:5
|
--> $DIR/const-drop-fail.rs:37:5
|
||||||
|
|
|
|
||||||
LL | const _: () = check($exp);
|
LL | const _: () = check($exp);
|
||||||
| ----- required by a bound introduced by this call
|
| ----- required by a bound introduced by this call
|
||||||
@@ -23,11 +35,12 @@ LL | ConstImplWithDropGlue(NonTrivialDrop),
|
|||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
note: required by a bound in `check`
|
note: required by a bound in `check`
|
||||||
--> $DIR/const-drop-fail.rs:25:19
|
--> $DIR/const-drop-fail.rs:26:19
|
||||||
|
|
|
|
||||||
LL | const fn check<T: [const] Destruct>(_: T) {}
|
LL | const fn check<T: [const] Destruct>(_: T) {}
|
||||||
| ^^^^^^^^^^^^^^^^ required by this bound in `check`
|
| ^^^^^^^^^^^^^^^^ required by this bound in `check`
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0277`.
|
Some errors have detailed explanations: E0277, E0367.
|
||||||
|
For more information about an error, try `rustc --explain E0277`.
|
||||||
|
|||||||
@@ -1,5 +1,17 @@
|
|||||||
|
error[E0367]: `NonTrivialDrop` does not implement `[const] Destruct`
|
||||||
|
--> $DIR/const-drop-fail.rs:19:30
|
||||||
|
|
|
||||||
|
LL | struct ConstImplWithDropGlue(NonTrivialDrop);
|
||||||
|
| ^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
note: required for this `Drop` impl
|
||||||
|
--> $DIR/const-drop-fail.rs:22:1
|
||||||
|
|
|
||||||
|
LL | impl const Drop for ConstImplWithDropGlue {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error[E0277]: the trait bound `NonTrivialDrop: const Destruct` is not satisfied
|
error[E0277]: the trait bound `NonTrivialDrop: const Destruct` is not satisfied
|
||||||
--> $DIR/const-drop-fail.rs:34:5
|
--> $DIR/const-drop-fail.rs:35:5
|
||||||
|
|
|
|
||||||
LL | const _: () = check($exp);
|
LL | const _: () = check($exp);
|
||||||
| ----- required by a bound introduced by this call
|
| ----- required by a bound introduced by this call
|
||||||
@@ -8,13 +20,13 @@ LL | NonTrivialDrop,
|
|||||||
| ^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
note: required by a bound in `check`
|
note: required by a bound in `check`
|
||||||
--> $DIR/const-drop-fail.rs:25:19
|
--> $DIR/const-drop-fail.rs:26:19
|
||||||
|
|
|
|
||||||
LL | const fn check<T: [const] Destruct>(_: T) {}
|
LL | const fn check<T: [const] Destruct>(_: T) {}
|
||||||
| ^^^^^^^^^^^^^^^^ required by this bound in `check`
|
| ^^^^^^^^^^^^^^^^ required by this bound in `check`
|
||||||
|
|
||||||
error[E0277]: the trait bound `NonTrivialDrop: const Destruct` is not satisfied
|
error[E0277]: the trait bound `NonTrivialDrop: const Destruct` is not satisfied
|
||||||
--> $DIR/const-drop-fail.rs:36:5
|
--> $DIR/const-drop-fail.rs:37:5
|
||||||
|
|
|
|
||||||
LL | const _: () = check($exp);
|
LL | const _: () = check($exp);
|
||||||
| ----- required by a bound introduced by this call
|
| ----- required by a bound introduced by this call
|
||||||
@@ -23,11 +35,12 @@ LL | ConstImplWithDropGlue(NonTrivialDrop),
|
|||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
note: required by a bound in `check`
|
note: required by a bound in `check`
|
||||||
--> $DIR/const-drop-fail.rs:25:19
|
--> $DIR/const-drop-fail.rs:26:19
|
||||||
|
|
|
|
||||||
LL | const fn check<T: [const] Destruct>(_: T) {}
|
LL | const fn check<T: [const] Destruct>(_: T) {}
|
||||||
| ^^^^^^^^^^^^^^^^ required by this bound in `check`
|
| ^^^^^^^^^^^^^^^^ required by this bound in `check`
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0277`.
|
Some errors have detailed explanations: E0277, E0367.
|
||||||
|
For more information about an error, try `rustc --explain E0277`.
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ fn drop(&mut self) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct ConstImplWithDropGlue(NonTrivialDrop);
|
struct ConstImplWithDropGlue(NonTrivialDrop);
|
||||||
|
//~^ ERROR: `NonTrivialDrop` does not implement `[const] Destruct`
|
||||||
|
|
||||||
impl const Drop for ConstImplWithDropGlue {
|
impl const Drop for ConstImplWithDropGlue {
|
||||||
fn drop(&mut self) {}
|
fn drop(&mut self) {}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ const trait Foo {}
|
|||||||
impl Foo for () {}
|
impl Foo for () {}
|
||||||
|
|
||||||
struct Conditional<T: Foo>(T);
|
struct Conditional<T: Foo>(T);
|
||||||
impl<T> const Drop for Conditional<T> where T: [const] Foo {
|
impl<T> const Drop for Conditional<T> where T: [const] Foo + [const] Destruct {
|
||||||
fn drop(&mut self) {}
|
fn drop(&mut self) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user