diff options
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_hir_analysis/messages.ftl | 4 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/src/check/dropck.rs | 17 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/src/errors.rs | 14 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/util.rs | 10 |
4 files changed, 39 insertions, 6 deletions
diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index 5d45d09797b..4c4af9b6908 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -276,3 +276,7 @@ hir_analysis_const_specialize = cannot specialize on const impl with non-const i hir_analysis_static_specialize = cannot specialize on `'static` lifetime hir_analysis_missing_tilde_const = missing `~const` qualifier for specialization + +hir_analysis_drop_impl_negative = negative `Drop` impls are not supported + +hir_analysis_drop_impl_reservation = reservation `Drop` impls are not supported diff --git a/compiler/rustc_hir_analysis/src/check/dropck.rs b/compiler/rustc_hir_analysis/src/check/dropck.rs index 111bf5e5455..703e389a838 100644 --- a/compiler/rustc_hir_analysis/src/check/dropck.rs +++ b/compiler/rustc_hir_analysis/src/check/dropck.rs @@ -1,7 +1,6 @@ // FIXME(@lcnr): Move this module out of `rustc_hir_analysis`. // // We don't do any drop checking during hir typeck. -use crate::hir::def_id::{DefId, LocalDefId}; use rustc_errors::{struct_span_err, ErrorGuaranteed}; use rustc_middle::ty::error::TypeError; use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation}; @@ -9,6 +8,9 @@ use rustc_middle::ty::subst::SubstsRef; use rustc_middle::ty::util::IgnoreRegions; use rustc_middle::ty::{self, Predicate, Ty, TyCtxt}; +use crate::errors; +use crate::hir::def_id::{DefId, LocalDefId}; + /// This function confirms that the `Drop` implementation identified by /// `drop_impl_did` is not any more specialized than the type it is /// attached to (Issue #8142). @@ -27,6 +29,19 @@ use rustc_middle::ty::{self, Predicate, Ty, TyCtxt}; /// cannot do `struct S<T>; impl<T:Clone> Drop for S<T> { ... }`). /// pub fn check_drop_impl(tcx: TyCtxt<'_>, drop_impl_did: DefId) -> Result<(), ErrorGuaranteed> { + match tcx.impl_polarity(drop_impl_did) { + ty::ImplPolarity::Positive => {} + ty::ImplPolarity::Negative => { + return Err(tcx.sess.emit_err(errors::DropImplPolarity::Negative { + span: tcx.def_span(drop_impl_did), + })); + } + ty::ImplPolarity::Reservation => { + return Err(tcx.sess.emit_err(errors::DropImplPolarity::Reservation { + span: tcx.def_span(drop_impl_did), + })); + } + } let dtor_self_type = tcx.type_of(drop_impl_did).subst_identity(); let dtor_predicates = tcx.predicates_of(drop_impl_did); match dtor_self_type.kind() { diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index f82169dee98..ba3039272f5 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -815,3 +815,17 @@ pub(crate) struct MissingTildeConst { #[primary_span] pub span: Span, } + +#[derive(Diagnostic)] +pub(crate) enum DropImplPolarity { + #[diag(hir_analysis_drop_impl_negative)] + Negative { + #[primary_span] + span: Span, + }, + #[diag(hir_analysis_drop_impl_reservation)] + Reservation { + #[primary_span] + span: Span, + }, +} diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index c77985c6bd6..e5b2d342452 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -360,16 +360,16 @@ impl<'tcx> TyCtxt<'tcx> { let ty = self.type_of(adt_did).subst_identity(); let mut dtor_candidate = None; self.for_each_relevant_impl(drop_trait, ty, |impl_did| { - let Some(item_id) = self.associated_item_def_ids(impl_did).first() else { - self.sess.delay_span_bug(self.def_span(impl_did), "Drop impl without drop function"); - return; - }; - if validate(self, impl_did).is_err() { // Already `ErrorGuaranteed`, no need to delay a span bug here. return; } + let Some(item_id) = self.associated_item_def_ids(impl_did).first() else { + self.sess.delay_span_bug(self.def_span(impl_did), "Drop impl without drop function"); + return; + }; + if let Some((old_item_id, _)) = dtor_candidate { self.sess .struct_span_err(self.def_span(item_id), "multiple drop impls found") |
