diff --git a/compiler/rustc_attr_ir/src/data_structures.rs b/compiler/rustc_attr_ir/src/data_structures.rs index 81887e0176ee7..f52548ab047f6 100644 --- a/compiler/rustc_attr_ir/src/data_structures.rs +++ b/compiler/rustc_attr_ir/src/data_structures.rs @@ -1615,9 +1615,6 @@ pub enum AttributeKind { /// Represents `#[rustc_regions]` RustcRegions, - /// Represents `#[rustc_reservation_impl]` - RustcReservationImpl(Symbol), - /// Represents `#[rustc_scalable_vector(N)]` RustcScalableVector { /// The base multiple of lanes that are in a scalable vector, if provided. `element_count` diff --git a/compiler/rustc_attr_ir/src/encode_cross_crate.rs b/compiler/rustc_attr_ir/src/encode_cross_crate.rs index 6a9f37f80868a..1ddc9c61c02b2 100644 --- a/compiler/rustc_attr_ir/src/encode_cross_crate.rs +++ b/compiler/rustc_attr_ir/src/encode_cross_crate.rs @@ -185,7 +185,6 @@ impl AttributeKind { RustcPubTransparent(..) => Yes, RustcReallocator => No, RustcRegions => No, - RustcReservationImpl(..) => Yes, RustcScalableVector { .. } => Yes, RustcShouldNotBeCalledOnConstItems => Yes, RustcSimdMonomorphizeLaneLimit(..) => Yes, // Affects layout computation, which needs to work cross-crate diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs index 94d7d70d07afc..683aad14cf615 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs @@ -1102,23 +1102,6 @@ impl NoArgsAttributeParser for RustcStrictCoherenceParser { const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcStrictCoherence; } -pub(crate) struct RustcReservationImplParser; - -impl SingleAttributeParser for RustcReservationImplParser { - const PATH: &[Symbol] = &[sym::rustc_reservation_impl]; - const ALLOWED_TARGETS: AllowedTargets<'_> = - AllowedTargets::AllowList(&[Allow(Target::Impl { of_trait: true })]); - const TEMPLATE: AttributeTemplate = template!(NameValueStr: "reservation message"); - const STABILITY: AttributeStability = unstable!(rustc_attrs); - - fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option { - let nv = cx.expect_name_value(args, cx.attr_span, None)?; - let value_str = cx.expect_string_literal(nv)?; - - Some(AttributeKind::RustcReservationImpl(value_str)) - } -} - pub(crate) struct PreludeImportParser; impl NoArgsAttributeParser for PreludeImportParser { diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 73195c7b77b10..41271bf404878 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -248,7 +248,6 @@ attribute_parsers!( Single, Single, Single, - Single, Single, Single, Single, diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index bc6f87a2a7f17..e22ff7e7d6a7d 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -364,7 +364,6 @@ pub static BUILTIN_ATTRIBUTES: &[Symbol] = &[ sym::prelude_import, sym::rustc_paren_sugar, sym::rustc_inherit_overflow_checks, - sym::rustc_reservation_impl, sym::rustc_test_entrypoint_marker, sym::rustc_test_marker, sym::rustc_allow_lifetime_dependent_specialization, diff --git a/compiler/rustc_hir_analysis/src/check/always_applicable.rs b/compiler/rustc_hir_analysis/src/check/always_applicable.rs index 6a30ff40eedc6..60636a1164926 100644 --- a/compiler/rustc_hir_analysis/src/check/always_applicable.rs +++ b/compiler/rustc_hir_analysis/src/check/always_applicable.rs @@ -43,12 +43,7 @@ pub(crate) fn check_drop_impl( match tcx.impl_polarity(drop_impl_did) { ty::ImplPolarity::Positive => {} ty::ImplPolarity::Negative => { - return Err(tcx.dcx().emit_err(diagnostics::DropImplPolarity::Negative { - span: tcx.def_span(drop_impl_did), - })); - } - ty::ImplPolarity::Reservation => { - return Err(tcx.dcx().emit_err(diagnostics::DropImplPolarity::Reservation { + return Err(tcx.dcx().emit_err(diagnostics::NegativeDropImplPolarity { span: tcx.def_span(drop_impl_did), })); } @@ -153,7 +148,7 @@ fn ensure_impl_params_and_item_params_correspond<'tcx>( let item_span = tcx.def_span(adt_def_id); let self_descr = tcx.def_descr(adt_def_id); let polarity = match tcx.impl_polarity(impl_def_id) { - ty::ImplPolarity::Positive | ty::ImplPolarity::Reservation => "", + ty::ImplPolarity::Positive => "", ty::ImplPolarity::Negative => "!", }; let trait_name = tcx.item_name(tcx.impl_trait_id(impl_def_id.to_def_id())); @@ -265,7 +260,7 @@ fn ensure_impl_predicates_are_implied_by_item_defn<'tcx>( let impl_span = tcx.def_span(impl_def_id.to_def_id()); let trait_name = tcx.item_name(tcx.impl_trait_id(impl_def_id.to_def_id())); let polarity = match tcx.impl_polarity(impl_def_id) { - ty::ImplPolarity::Positive | ty::ImplPolarity::Reservation => "", + ty::ImplPolarity::Positive => "", ty::ImplPolarity::Negative => "!", }; // Take the param-env of the adt and instantiate the args that show up in diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 01df2e199a5ac..4f7d059bf18d2 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -1274,7 +1274,7 @@ fn check_impl_items_against_trait<'tcx>( // Negative impls are not expected to have any items match impl_trait_header.polarity { - ty::ImplPolarity::Reservation | ty::ImplPolarity::Positive => {} + ty::ImplPolarity::Positive => {} ty::ImplPolarity::Negative => { if let [first_item_ref, ..] = *impl_item_refs { let first_item_span = tcx.def_span(first_item_ref); diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 9a498837b1f4d..e76a7863add25 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -316,9 +316,6 @@ pub(super) fn check_item<'tcx>( .emit()); } } - ty::ImplPolarity::Reservation => { - // FIXME: what amount of WF checking do we need for reservation impls? - } } } else { res = res.and(check_impl(tcx, item, impl_)); @@ -1309,9 +1306,6 @@ fn check_impl<'tcx>( enter_wf_checking_ctxt(tcx, item.owner_id.def_id, |wfcx| { match impl_.of_trait { Some(of_trait) => { - // `#[rustc_reservation_impl]` impls are not real impls and - // therefore don't need to be WF (the trait's `Self: Trait` predicate - // won't hold). let trait_ref = tcx.impl_trait_ref(item.owner_id).instantiate_identity(); // Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in // case other `Foo` impls are incoherent. diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index 3b57f45e684f7..99e6be5329f40 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -170,7 +170,7 @@ fn visit_implementation_of_const_param_ty(checker: &Checker<'_>) -> Result<(), E let param_env = tcx.param_env(impl_did); - if let ty::ImplPolarity::Negative | ty::ImplPolarity::Reservation = header.polarity { + if let ty::ImplPolarity::Negative = header.polarity { return Ok(()); } diff --git a/compiler/rustc_hir_analysis/src/coherence/unsafety.rs b/compiler/rustc_hir_analysis/src/coherence/unsafety.rs index 7fcf8ddceea5c..ce0171a4d2d7d 100644 --- a/compiler/rustc_hir_analysis/src/coherence/unsafety.rs +++ b/compiler/rustc_hir_analysis/src/coherence/unsafety.rs @@ -34,7 +34,7 @@ pub(super) fn check_item( }; match (trait_def_safety, unsafe_attr, trait_header.safety, trait_header.polarity) { - (Safety::Safe, None, Safety::Unsafe, Positive | Reservation) => { + (Safety::Safe, None, Safety::Unsafe, Positive) => { let span = tcx.def_span(def_id); return Err(struct_span_code_err!( tcx.dcx(), @@ -52,7 +52,7 @@ pub(super) fn check_item( .emit()); } - (Safety::Unsafe, _, Safety::Safe, Positive | Reservation) => { + (Safety::Unsafe, _, Safety::Safe, Positive) => { let span = tcx.def_span(def_id); return Err(struct_span_code_err!( tcx.dcx(), @@ -86,7 +86,7 @@ pub(super) fn check_item( .emit()); } - (Safety::Safe, Some(attr_name), Safety::Safe, Positive | Reservation) => { + (Safety::Safe, Some(attr_name), Safety::Safe, Positive) => { let span = tcx.def_span(def_id); return Err(struct_span_code_err!( tcx.dcx(), @@ -116,8 +116,8 @@ pub(super) fn check_item( Ok(()) } (_, _, Safety::Safe, Negative) - | (Safety::Unsafe, _, Safety::Unsafe, Positive | Reservation) - | (Safety::Safe, Some(_), Safety::Unsafe, Positive | Reservation) + | (Safety::Unsafe, _, Safety::Unsafe, Positive) + | (Safety::Safe, Some(_), Safety::Unsafe, Positive) | (Safety::Safe, None, Safety::Safe, _) => Ok(()), } } diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 25ba0c810489e..db0d7e4bbac1a 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -1410,7 +1410,6 @@ fn impl_trait_header(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::ImplTraitHeader .of_trait .unwrap_or_else(|| panic!("expected impl trait, found inherent impl on {def_id:?}")); let selfty = tcx.type_of(def_id).instantiate_identity().skip_norm_wip(); - let is_rustc_reservation = find_attr!(tcx, def_id, RustcReservationImpl(..)); check_impl_constness(tcx, impl_.constness, &of_trait.trait_ref); @@ -1419,7 +1418,7 @@ fn impl_trait_header(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::ImplTraitHeader ty::ImplTraitHeader { trait_ref: ty::EarlyBinder::bind(tcx, trait_ref), safety: of_trait.safety, - polarity: polarity_of_impl(tcx, of_trait, is_rustc_reservation), + polarity: polarity_of_impl(of_trait), constness: impl_.constness, } } @@ -1466,26 +1465,10 @@ fn check_impl_constness( }); } -fn polarity_of_impl( - tcx: TyCtxt<'_>, - of_trait: &hir::TraitImplHeader<'_>, - is_rustc_reservation: bool, -) -> ty::ImplPolarity { +fn polarity_of_impl(of_trait: &hir::TraitImplHeader<'_>) -> ty::ImplPolarity { match of_trait.polarity { - hir::ImplPolarity::Negative(span) => { - if is_rustc_reservation { - let span = span.to(of_trait.trait_ref.path.span); - tcx.dcx().span_err(span, "reservation impls can't be negative"); - } - ty::ImplPolarity::Negative - } - hir::ImplPolarity::Positive => { - if is_rustc_reservation { - ty::ImplPolarity::Reservation - } else { - ty::ImplPolarity::Positive - } - } + hir::ImplPolarity::Negative(_) => ty::ImplPolarity::Negative, + hir::ImplPolarity::Positive => ty::ImplPolarity::Positive, } } diff --git a/compiler/rustc_hir_analysis/src/diagnostics.rs b/compiler/rustc_hir_analysis/src/diagnostics.rs index 890d25f14b264..e966992ae9294 100644 --- a/compiler/rustc_hir_analysis/src/diagnostics.rs +++ b/compiler/rustc_hir_analysis/src/diagnostics.rs @@ -1074,17 +1074,10 @@ pub(crate) struct StaticSpecialize { } #[derive(Diagnostic)] -pub(crate) enum DropImplPolarity { - #[diag("negative `Drop` impls are not supported")] - Negative { - #[primary_span] - span: Span, - }, - #[diag("reservation `Drop` impls are not supported")] - Reservation { - #[primary_span] - span: Span, - }, +#[diag("negative `Drop` impls are not supported")] +pub(crate) struct NegativeDropImplPolarity { + #[primary_span] + pub span: Span, } #[derive(Diagnostic)] diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index cd9e5f6903478..29b3ab47bcf87 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1904,10 +1904,6 @@ impl<'tcx> TyCtxt<'tcx> { } match (impl1.polarity, impl2.polarity) { - (ImplPolarity::Reservation, _) | (_, ImplPolarity::Reservation) => { - // `#[rustc_reservation_impl]` impls don't overlap with anything - return Some(ImplOverlapKind::Permitted { marker: false }); - } (ImplPolarity::Positive, ImplPolarity::Negative) | (ImplPolarity::Negative, ImplPolarity::Positive) => { // `impl AutoTrait for Type` + `impl !AutoTrait for Type` diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs index 836b552f5129c..a597230b8fe4d 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs @@ -219,7 +219,7 @@ where goal: Goal, goal_trait_ref: ty::TraitRef, impl_def_id: I::ImplId, - then: impl FnOnce(&mut EvalCtxt<'_, D>, Certainty) -> QueryResultOrRerunNonErased, + then: impl FnOnce(&mut EvalCtxt<'_, D>) -> QueryResultOrRerunNonErased, ) -> Result, NoSolutionOrRerunNonErased>; /// If the predicate contained an error, we want to avoid emitting unnecessary trait @@ -553,13 +553,9 @@ where let cx = self.cx(); let goal_trait_ref = goal.predicate.trait_ref(cx); cx.for_each_relevant_impl(goal_trait_ref, |impl_def_id| -> Result<_, _> { - match G::consider_impl_candidate( - self, - goal, - goal_trait_ref, - impl_def_id, - |ecx, certainty| ecx.evaluate_added_goals_and_make_canonical_response(certainty), - ) + match G::consider_impl_candidate(self, goal, goal_trait_ref, impl_def_id, |ecx| { + ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + }) .map_err_to_rerun()? { Ok(candidate) => { @@ -1186,26 +1182,19 @@ where return Ok(()); } - match G::consider_impl_candidate( - self, - goal, - goal_trait_ref, - impl_def_id, - |ecx, certainty| { - if ecx.shallow_resolve(self_ty).is_ty_var() { - // We force the certainty of impl candidates to be `Maybe`. - let certainty = certainty.and(Certainty::AMBIGUOUS); - ecx.evaluate_added_goals_and_make_canonical_response(certainty) - } else { - // We don't want to use impls if they constrain the opaque. - // - // FIXME(trait-system-refactor-initiative#229): This isn't - // perfect yet as it still allows us to incorrectly constrain - // other inference variables. - Err(NoSolution.into()) - } - }, - ) + match G::consider_impl_candidate(self, goal, goal_trait_ref, impl_def_id, |ecx| { + if ecx.shallow_resolve(self_ty).is_ty_var() { + // We force the certainty of impl candidates to be `Maybe`. + ecx.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS) + } else { + // We don't want to use impls if they constrain the opaque. + // + // FIXME(trait-system-refactor-initiative#229): This isn't + // perfect yet as it still allows us to incorrectly constrain + // other inference variables. + Err(NoSolution.into()) + } + }) .map_err_to_rerun()? { Ok(candidate) => candidates.push(candidate), diff --git a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs index 488d1b9215016..6354fd6b5146a 100644 --- a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs @@ -138,7 +138,7 @@ where goal: Goal, goal_trait_ref: ty::TraitRef, impl_def_id: I::ImplId, - then: impl FnOnce(&mut EvalCtxt<'_, D>, Certainty) -> QueryResultOrRerunNonErased, + then: impl FnOnce(&mut EvalCtxt<'_, D>) -> QueryResultOrRerunNonErased, ) -> Result, NoSolutionOrRerunNonErased> { let cx = ecx.cx(); @@ -149,17 +149,9 @@ where return Err(NoSolution.into()); } - let impl_polarity = cx.impl_polarity(impl_def_id); - let certainty = match impl_polarity { + match cx.impl_polarity(impl_def_id) { ty::ImplPolarity::Negative => return Err(NoSolution.into()), - ty::ImplPolarity::Reservation => { - if ecx.typing_mode().is_coherence() { - Certainty::AMBIGUOUS - } else { - return Err(NoSolution.into()); - } - } - ty::ImplPolarity::Positive => Certainty::Yes, + ty::ImplPolarity::Positive => (), }; if !cx.impl_is_const(impl_def_id) { @@ -193,7 +185,7 @@ where }); ecx.add_goals(GoalSource::ImplWhereBound, const_conditions)?; - then(ecx, certainty) + then(ecx) }) } diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to.rs index 08c634620300a..7ec62a37b2d30 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to.rs @@ -255,7 +255,7 @@ where goal: Goal>, goal_trait_ref: ty::TraitRef, impl_def_id: I::ImplId, - then: impl FnOnce(&mut EvalCtxt<'_, D>, Certainty) -> QueryResultOrRerunNonErased, + then: impl FnOnce(&mut EvalCtxt<'_, D>) -> QueryResultOrRerunNonErased, ) -> Result, NoSolutionOrRerunNonErased> { let cx = ecx.cx(); @@ -271,9 +271,6 @@ where let impl_polarity = cx.impl_polarity(impl_def_id); match impl_polarity { ty::ImplPolarity::Negative => return Err(NoSolution.into()), - ty::ImplPolarity::Reservation => { - unimplemented!("reservation impl for trait with assoc item: {:?}", goal) - } ty::ImplPolarity::Positive => {} }; @@ -382,10 +379,10 @@ where // This is not the case here and we only prefer adding an ambiguous // nested goal for consistency. ecx.add_goal(GoalSource::Misc, goal.with(cx, PredicateKind::Ambiguous))?; - return then(ecx, Certainty::Yes); + return then(ecx); } else { ecx.instantiate_normalizes_to_as_rigid(goal)?; - return then(ecx, Certainty::Yes); + return then(ecx); } } else { return error_response(ecx, cx.delay_bug("missing item")); diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs index bff406e72919c..690a15dd669c0 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -62,7 +62,7 @@ where goal: Goal>, goal_trait_ref: TraitRef, impl_def_id: I::ImplId, - then: impl FnOnce(&mut EvalCtxt<'_, D>, Certainty) -> QueryResultOrRerunNonErased, + then: impl FnOnce(&mut EvalCtxt<'_, D>) -> QueryResultOrRerunNonErased, ) -> Result, NoSolutionOrRerunNonErased> { let cx = ecx.cx(); @@ -73,37 +73,18 @@ where return Err(NoSolution.into()); } - // An upper bound of the certainty of this goal, used to lower the certainty - // of reservation impl to ambiguous during coherence. - let impl_polarity = cx.impl_polarity(impl_def_id); - let maximal_certainty = match (impl_polarity, goal.predicate.polarity) { - // In coherence mode, this is ambiguous. But outside of coherence, it's not a real impl. - (ty::ImplPolarity::Reservation, _) => { - if ecx.typing_mode().is_coherence() { - Certainty::AMBIGUOUS - } else { - return Err(NoSolution.into()); - } - } - - // Impl matches polarity - (ty::ImplPolarity::Positive, ty::PredicatePolarity::Positive) - | (ty::ImplPolarity::Negative, ty::PredicatePolarity::Negative) => { - if ecx.typing_mode().is_reflection() - && !cx.is_fully_generic_for_reflection(impl_def_id) - { - return Err(NoSolution.into()); - } else { - Certainty::Yes - } - } - + match (cx.impl_polarity(impl_def_id), goal.predicate.polarity) { // Impl doesn't match polarity (ty::ImplPolarity::Positive, ty::PredicatePolarity::Negative) | (ty::ImplPolarity::Negative, ty::PredicatePolarity::Positive) => { return Err(NoSolution.into()); } - }; + _ => {} + } + + if ecx.typing_mode().is_reflection() && !cx.is_fully_generic_for_reflection(impl_def_id) { + return Err(NoSolution.into()); + } ecx.probe_trait_candidate(CandidateSource::Impl(impl_def_id)).enter(|ecx| { let impl_args = ecx.fresh_args_for_item(impl_def_id.into()); @@ -129,7 +110,7 @@ where .map(|pred| goal.with(cx, pred)), )?; - then(ecx, maximal_certainty) + then(ecx) }) } diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index e035e16cabb91..aa92a6d56c136 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -381,7 +381,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { AttributeKind::RustcPubTransparent(..) => (), AttributeKind::RustcReallocator => (), AttributeKind::RustcRegions => (), - AttributeKind::RustcReservationImpl(..) => (), AttributeKind::RustcScalableVector { .. } => (), AttributeKind::RustcShouldNotBeCalledOnConstItems => (), AttributeKind::RustcSimdMonomorphizeLaneLimit(..) => (), diff --git a/compiler/rustc_public/src/unstable/convert/stable/ty.rs b/compiler/rustc_public/src/unstable/convert/stable/ty.rs index 160487400c38c..0f95d8f7a9885 100644 --- a/compiler/rustc_public/src/unstable/convert/stable/ty.rs +++ b/compiler/rustc_public/src/unstable/convert/stable/ty.rs @@ -896,7 +896,6 @@ impl<'tcx> Stable<'tcx> for ty::ImplPolarity { match self { Positive => crate::ty::ImplPolarity::Positive, Negative => crate::ty::ImplPolarity::Negative, - Reservation => crate::ty::ImplPolarity::Reservation, } } } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 45df107bf7469..c8bed7a1f70a7 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1863,7 +1863,6 @@ symbols! { rustc_pub_transparent, rustc_reallocator, rustc_regions, - rustc_reservation_impl, rustc_scalable_vector, rustc_should_not_be_called_on_const_items, rustc_simd_monomorphize_lane_limit, diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 78ccf04d456a3..2cb4bc130dcf5 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -9,7 +9,6 @@ use std::fmt::Debug; use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; use rustc_errors::{Diag, EmissionGuarantee}; use rustc_hir::def_id::{CRATE_DEF_ID, DefId}; -use rustc_hir::find_attr; use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, TyCtxtInferExt}; use rustc_infer::traits::{PredicateObligations, TraitErrors}; use rustc_macros::{TypeFoldable, TypeVisitable}; @@ -772,20 +771,6 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for AmbiguityCausesVisitor<'a, 'tcx> { } let mut candidates = goal.candidates(); - for cand in goal.candidates() { - if let inspect::ProbeKind::TraitCandidate { - source: CandidateSource::Impl(def_id), - result: Ok(_), - } = cand.kind() - && let ty::ImplPolarity::Reservation = infcx.tcx.impl_polarity(def_id) - { - if let Some(message) = - find_attr!(infcx.tcx, def_id, RustcReservationImpl(message) => *message) - { - self.causes.insert(IntercrateAmbiguityCause::ReservationImpl { message }); - } - } - } // We also look for unknowable candidates. In case a goal is unknowable, there's // always exactly 1 candidate. diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 9b4ee13bf1b63..cd998d6c6e85a 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -10,9 +10,9 @@ use std::ops::ControlFlow; use hir::def::DefKind; use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_errors::{Diag, EmissionGuarantee}; +use rustc_hir as hir; use rustc_hir::attrs::lang_items::LangItem; use rustc_hir::def_id::DefId; -use rustc_hir::{self as hir, find_attr}; use rustc_infer::infer::BoundRegionConversionTime::{self, HigherRankedType}; use rustc_infer::infer::DefineOpaqueTypes; use rustc_infer::infer::at::ToTrace; @@ -31,7 +31,6 @@ use rustc_middle::ty::{ TypingMode, Unnormalized, Upcast, elaborate, may_use_unstable_feature, }; use rustc_next_trait_solver::solve::AliasBoundKind; -use rustc_span::Symbol; use tracing::{debug, instrument, trace}; use self::EvaluationResult::*; @@ -59,7 +58,6 @@ mod confirmation; pub enum IntercrateAmbiguityCause<'tcx> { DownstreamCrate { trait_ref: ty::TraitRef<'tcx>, self_ty: Option> }, UpstreamCrateUpdate { trait_ref: ty::TraitRef<'tcx>, self_ty: Option> }, - ReservationImpl { message: Symbol }, } impl<'tcx> IntercrateAmbiguityCause<'tcx> { @@ -94,7 +92,6 @@ impl<'tcx> IntercrateAmbiguityCause<'tcx> { } ) } - IntercrateAmbiguityCause::ReservationImpl { message } => message.to_string(), }) } } @@ -441,7 +438,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // Instead, we select the right impl now but report "`Bar` does // not implement `Clone`". if candidates.len() == 1 { - return self.filter_reservation_impls(candidates.pop().unwrap()); + return Ok(candidates.pop()); } // Winnow, but record the exact outcome of evaluation, which @@ -488,13 +485,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let has_non_region_infer = stack.obligation.predicate.has_non_region_infer(); let candidate_preference_mode = CandidatePreferenceMode::compute(self.tcx(), stack.obligation.predicate.def_id()); - if let Some(candidate) = - self.winnow_candidates(has_non_region_infer, candidate_preference_mode, candidates) - { - self.filter_reservation_impls(candidate) - } else { - Ok(None) - } + Ok(self.winnow_candidates(has_non_region_infer, candidate_preference_mode, candidates)) } } @@ -1414,58 +1405,28 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { #[instrument(level = "debug", skip(self, candidates))] fn filter_impls( &mut self, - candidates: Vec>, + mut candidates: Vec>, obligation: &PolyTraitObligation<'tcx>, ) -> Vec> { trace!("{candidates:#?}"); let tcx = self.tcx(); - let mut result = Vec::with_capacity(candidates.len()); - for candidate in candidates { - if let ImplCandidate(def_id) = candidate { + candidates.retain(|candidate| { + if let &ImplCandidate(def_id) = candidate { match (tcx.impl_polarity(def_id), obligation.polarity()) { - (ty::ImplPolarity::Reservation, _) - | (ty::ImplPolarity::Positive, ty::PredicatePolarity::Positive) - | (ty::ImplPolarity::Negative, ty::PredicatePolarity::Negative) => { - result.push(candidate); - } - _ => {} + (ty::ImplPolarity::Positive, ty::PredicatePolarity::Positive) + | (ty::ImplPolarity::Negative, ty::PredicatePolarity::Negative) => true, + + // remove impl candidates with mismatched polarity to the obligation + _ => false, } } else { - result.push(candidate); + true } - } - - trace!("{result:#?}"); - result - } + }); - /// filter_reservation_impls filter reservation impl for any goal as ambiguous - #[instrument(level = "debug", skip(self))] - fn filter_reservation_impls( - &mut self, - candidate: SelectionCandidate<'tcx>, - ) -> SelectionResult<'tcx, SelectionCandidate<'tcx>> { - let tcx = self.tcx(); - // Treat reservation impls as ambiguity. - if let ImplCandidate(def_id) = candidate - && let ty::ImplPolarity::Reservation = tcx.impl_polarity(def_id) - { - if let Some(intercrate_ambiguity_clauses) = &mut self.intercrate_ambiguity_causes { - let message = find_attr!(tcx, def_id, RustcReservationImpl(message) => *message); - if let Some(message) = message { - debug!( - "filter_reservation_impls: \ - reservation impl ambiguity on {:?}", - def_id - ); - intercrate_ambiguity_clauses - .insert(IntercrateAmbiguityCause::ReservationImpl { message }); - } - } - return Ok(None); - } - Ok(Some(candidate)) + trace!("{candidates:#?}"); + candidates } fn is_knowable<'o>(&mut self, stack: &TraitObligationStack<'o, 'tcx>) -> Result<(), Conflict> { @@ -2555,7 +2516,6 @@ impl<'tcx> SelectionContext<'_, 'tcx> { nested_obligations.extend(obligations); match self.typing_mode() { - TypingMode::Coherence => {} TypingMode::Reflection if !self.tcx().impl_is_fully_generic_for_reflection(impl_def_id) => { @@ -2563,18 +2523,14 @@ impl<'tcx> SelectionContext<'_, 'tcx> { return Err(()); } - TypingMode::Typeck { .. } + TypingMode::Coherence + | TypingMode::Typeck { .. } | TypingMode::PostTypeckUntilBorrowck { .. } | TypingMode::PostBorrowck { .. } | TypingMode::Codegen | TypingMode::ErasedNotCoherence(_) | TypingMode::Reflection - | TypingMode::PostAnalysis => { - if impl_trait_header.polarity == ty::ImplPolarity::Reservation { - debug!("reservation impls only apply in intercrate mode"); - return Err(()); - } - } + | TypingMode::PostAnalysis => {} } Ok(Normalized { value: impl_args, obligations: nested_obligations }) diff --git a/compiler/rustc_type_ir/src/predicate.rs b/compiler/rustc_type_ir/src/predicate.rs index 7907149e25fef..9ad4690b2fa09 100644 --- a/compiler/rustc_type_ir/src/predicate.rs +++ b/compiler/rustc_type_ir/src/predicate.rs @@ -268,11 +268,6 @@ pub enum ImplPolarity { Positive, /// `impl !Trait for Type` Negative, - /// `#[rustc_reservation_impl] impl Trait for Type` - /// - /// This is a "stability hack", not a real Rust feature. - /// See #64631 for details. - Reservation, } impl fmt::Display for ImplPolarity { @@ -280,7 +275,6 @@ impl fmt::Display for ImplPolarity { match self { Self::Positive => f.write_str("positive"), Self::Negative => f.write_str("negative"), - Self::Reservation => f.write_str("reservation"), } } } @@ -291,7 +285,6 @@ impl ImplPolarity { match self { Self::Positive => "", Self::Negative => "!", - Self::Reservation => "", } } } diff --git a/library/core/src/convert/mod.rs b/library/core/src/convert/mod.rs index 912623b73050e..8bd2ea302b605 100644 --- a/library/core/src/convert/mod.rs +++ b/library/core/src/convert/mod.rs @@ -793,21 +793,6 @@ const impl From for T { } } -/// **Stability note:** This impl does not yet exist, but we are -/// "reserving space" to add it in the future. See -/// [rust-lang/rust#64715][#64715] for details. -/// -/// [#64715]: https://github.com/rust-lang/rust/issues/64715 -#[stable(feature = "convert_infallible", since = "1.34.0")] -#[rustc_reservation_impl = "permitting this impl would forbid us from adding \ - `impl From for T` later; see rust-lang/rust#64715 for details"] -#[rustc_const_unstable(feature = "const_convert", issue = "143773")] -const impl From for T { - fn from(t: !) -> T { - t - } -} - // TryFrom implies TryInto #[stable(feature = "try_from", since = "1.34.0")] #[rustc_const_unstable(feature = "const_convert", issue = "143773")] diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 152a61beef405..dbffff503d564 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -948,7 +948,7 @@ fn short_item_info( fn impl_trait_key(cx: &Context<'_>, i: &Impl) -> Option { let trait_ = i.inner_impl().trait_.as_ref()?; let prefix = match i.inner_impl().polarity { - ty::ImplPolarity::Positive | ty::ImplPolarity::Reservation => "", + ty::ImplPolarity::Positive => "", ty::ImplPolarity::Negative => "!", }; Some(format!("{prefix}{:#}", print_path(trait_, cx))) @@ -964,7 +964,7 @@ fn render_impls<'a, 'cx>( ) -> impl fmt::Display + use<'a, 'cx> { impls.sort_by_cached_key(|imp| { let prefix = match imp.inner_impl().polarity { - ty::ImplPolarity::Positive | ty::ImplPolarity::Reservation => Ordering::Greater, + ty::ImplPolarity::Positive => Ordering::Greater, ty::ImplPolarity::Negative => Ordering::Less, }; (prefix, ImplString::new_path(imp, cx)) diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index b19ed533d4953..5a0e9d9e810e7 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -829,7 +829,7 @@ impl FromClean for Impl { clean::ImplKind::Blanket(ty) => (false, Some(ty)), }; let is_negative = match polarity { - ty::ImplPolarity::Positive | ty::ImplPolarity::Reservation => false, + ty::ImplPolarity::Positive => false, ty::ImplPolarity::Negative => true, }; Impl { diff --git a/tests/ui/dropck/reservation.rs b/tests/ui/dropck/reservation.rs deleted file mode 100644 index f7199d4ec4407..0000000000000 --- a/tests/ui/dropck/reservation.rs +++ /dev/null @@ -1,10 +0,0 @@ -#![feature(rustc_attrs)] - -struct ReservedDrop; -#[rustc_reservation_impl = "message"] -impl Drop for ReservedDrop { -//~^ ERROR reservation `Drop` impls are not supported - fn drop(&mut self) {} -} - -fn main() {} diff --git a/tests/ui/dropck/reservation.stderr b/tests/ui/dropck/reservation.stderr deleted file mode 100644 index a6ebf158a075d..0000000000000 --- a/tests/ui/dropck/reservation.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: reservation `Drop` impls are not supported - --> $DIR/reservation.rs:5:1 - | -LL | impl Drop for ReservedDrop { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 1 previous error - diff --git a/tests/ui/never_type/never-from-impl-is-reserved.rs b/tests/ui/never_type/never-from-impl-is-not-reserved.rs similarity index 53% rename from tests/ui/never_type/never-from-impl-is-reserved.rs rename to tests/ui/never_type/never-from-impl-is-not-reserved.rs index c673462f2962a..22b1c14db0bdf 100644 --- a/tests/ui/never_type/never-from-impl-is-reserved.rs +++ b/tests/ui/never_type/never-from-impl-is-not-reserved.rs @@ -1,5 +1,7 @@ -// check that the `for T: From` impl is reserved +// check that the `for T: From` impl is not reserved anymore +//@ check-pass +// //@ revisions: current next //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver=coherence @@ -10,7 +12,6 @@ pub struct MyFoo; pub trait MyTrait {} impl MyTrait for MyFoo {} -// This will conflict with the first impl if we impl `for T: From`. -impl MyTrait for T where T: From {} //~ ERROR conflicting implementation +impl MyTrait for T where T: From {} fn main() {} diff --git a/tests/ui/never_type/never-from-impl-is-reserved.current.stderr b/tests/ui/never_type/never-from-impl-is-reserved.current.stderr deleted file mode 100644 index 7868206950c34..0000000000000 --- a/tests/ui/never_type/never-from-impl-is-reserved.current.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error[E0119]: conflicting implementations of trait `MyTrait` for type `MyFoo` - --> $DIR/never-from-impl-is-reserved.rs:14:1 - | -LL | impl MyTrait for MyFoo {} - | ---------------------- first implementation here -LL | // This will conflict with the first impl if we impl `for T: From`. -LL | impl MyTrait for T where T: From {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `MyFoo` - | - = note: permitting this impl would forbid us from adding `impl From for T` later; see rust-lang/rust#64715 for details - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/never_type/never-from-impl-is-reserved.next.stderr b/tests/ui/never_type/never-from-impl-is-reserved.next.stderr deleted file mode 100644 index 7868206950c34..0000000000000 --- a/tests/ui/never_type/never-from-impl-is-reserved.next.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error[E0119]: conflicting implementations of trait `MyTrait` for type `MyFoo` - --> $DIR/never-from-impl-is-reserved.rs:14:1 - | -LL | impl MyTrait for MyFoo {} - | ---------------------- first implementation here -LL | // This will conflict with the first impl if we impl `for T: From`. -LL | impl MyTrait for T where T: From {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `MyFoo` - | - = note: permitting this impl would forbid us from adding `impl From for T` later; see rust-lang/rust#64715 for details - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/traits/reservation-impl/coherence-conflict.next.stderr b/tests/ui/traits/reservation-impl/coherence-conflict.next.stderr deleted file mode 100644 index 2b5277f933289..0000000000000 --- a/tests/ui/traits/reservation-impl/coherence-conflict.next.stderr +++ /dev/null @@ -1,13 +0,0 @@ -error[E0119]: conflicting implementations of trait `OtherTrait` for type `()` - --> $DIR/coherence-conflict.rs:12:1 - | -LL | impl OtherTrait for () {} - | ---------------------- first implementation here -LL | impl OtherTrait for T {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `()` - | - = note: this impl is reserved - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/traits/reservation-impl/coherence-conflict.old.stderr b/tests/ui/traits/reservation-impl/coherence-conflict.old.stderr deleted file mode 100644 index 2b5277f933289..0000000000000 --- a/tests/ui/traits/reservation-impl/coherence-conflict.old.stderr +++ /dev/null @@ -1,13 +0,0 @@ -error[E0119]: conflicting implementations of trait `OtherTrait` for type `()` - --> $DIR/coherence-conflict.rs:12:1 - | -LL | impl OtherTrait for () {} - | ---------------------- first implementation here -LL | impl OtherTrait for T {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `()` - | - = note: this impl is reserved - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/traits/reservation-impl/coherence-conflict.rs b/tests/ui/traits/reservation-impl/coherence-conflict.rs deleted file mode 100644 index 558793c25f3c4..0000000000000 --- a/tests/ui/traits/reservation-impl/coherence-conflict.rs +++ /dev/null @@ -1,15 +0,0 @@ -// check that reservation impls are accounted for in negative reasoning. -//@ revisions: old next -//@[next] compile-flags: -Znext-solver -#![feature(rustc_attrs)] - -trait MyTrait {} -#[rustc_reservation_impl="this impl is reserved"] -impl MyTrait for () {} - -trait OtherTrait {} -impl OtherTrait for () {} -impl OtherTrait for T {} -//~^ ERROR conflicting implementations - -fn main() {} diff --git a/tests/ui/traits/reservation-impl/no-use.next.stderr b/tests/ui/traits/reservation-impl/no-use.next.stderr deleted file mode 100644 index 772e360eade44..0000000000000 --- a/tests/ui/traits/reservation-impl/no-use.next.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0277]: the trait bound `(): MyTrait` is not satisfied - --> $DIR/no-use.rs:11:6 - | -LL | <() as MyTrait>::foo(&()); - | ^^ the trait `MyTrait` is not implemented for `()` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/reservation-impl/no-use.old.stderr b/tests/ui/traits/reservation-impl/no-use.old.stderr deleted file mode 100644 index 772e360eade44..0000000000000 --- a/tests/ui/traits/reservation-impl/no-use.old.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0277]: the trait bound `(): MyTrait` is not satisfied - --> $DIR/no-use.rs:11:6 - | -LL | <() as MyTrait>::foo(&()); - | ^^ the trait `MyTrait` is not implemented for `()` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/reservation-impl/no-use.rs b/tests/ui/traits/reservation-impl/no-use.rs deleted file mode 100644 index b470a2815c0c7..0000000000000 --- a/tests/ui/traits/reservation-impl/no-use.rs +++ /dev/null @@ -1,13 +0,0 @@ -// check that reservation impls can't be used as normal impls in positive reasoning. -//@ revisions: old next -//@[next] compile-flags: -Znext-solver -#![feature(rustc_attrs)] - -trait MyTrait { fn foo(&self); } -#[rustc_reservation_impl = "foo"] -impl MyTrait for () { fn foo(&self) {} } - -fn main() { - <() as MyTrait>::foo(&()); - //~^ ERROR the trait bound `(): MyTrait` is not satisfied -} diff --git a/tests/ui/traits/reservation-impl/non-lattice-ok.rs b/tests/ui/traits/reservation-impl/non-lattice-ok.rs deleted file mode 100644 index 32d610bf915aa..0000000000000 --- a/tests/ui/traits/reservation-impl/non-lattice-ok.rs +++ /dev/null @@ -1,65 +0,0 @@ -//@ build-pass - -// Check that a reservation impl does not force other impls to follow -// a lattice discipline. - -// Why did we ever want to do this? -// -// We want to eventually add an `impl From for T` impl. That impl conflicts -// with existing impls - at least the `impl From for T` impl. There are -// 2 ways we thought of for dealing with that conflict: -// -// 1. Using specialization and doing some handling for the -// overlap. The current thought is to require ["intersection -// impls"][ii], specialization", which means providing an -// (higher-priority) impl for the intersection of every 2 conflicting -// impls that determines what happens in the intersection case. That's -// the first thing we thought about - see e.g. -// https://github.com/rust-lang/rust/issues/57012#issuecomment-452150775 -// -// 2. The other way is to notice that `impl From for T` is basically a -// marker trait since its only method is uninhabited, and allow for "marker -// trait overlap", where the conflict "doesn't matter" because it can't -// actually cause any ambiguity. -// -// Now it turned out lattice specialization doesn't work it, because an -// `impl From for Smaht` would require an `impl From for Smaht`, -// breaking backwards-compatibility in a fairly painful way. So if we want to -// go with a known approach, we should go with a "marker trait overlap"-style -// approach. -// -// [ii]: https://smallcultfollowing.com/babysteps/blog/2016/09/24/intersection-impls/ - - -// check that reservation impls can't be used as normal impls in positive reasoning. - -//@ revisions: old next -//@[next] compile-flags: -Znext-solver - -#![feature(rustc_attrs, never_type)] - -trait MyTrait {} - -impl MyTrait for ! {} - -trait MyFrom { - fn my_from(x: T) -> Self; -} - -// Given the "normal" impls for From -#[rustc_reservation_impl="this impl is reserved"] -impl MyFrom for T { - fn my_from(x: !) -> Self { match x {} } -} - -impl MyFrom for T { - fn my_from(x: T) -> Self { x } -} - -// ... we *do* want to allow this common pattern, of `From for MySmaht` -struct MySmaht(T); -impl MyFrom for MySmaht { - fn my_from(x: T) -> Self { MySmaht(x) } -} - -fn main() {} diff --git a/tests/ui/traits/reservation-impl/ok.rs b/tests/ui/traits/reservation-impl/ok.rs deleted file mode 100644 index cf68c1b2e96dc..0000000000000 --- a/tests/ui/traits/reservation-impl/ok.rs +++ /dev/null @@ -1,31 +0,0 @@ -//@ run-pass - -// rpass test for reservation impls. Not 100% required because `From` uses them, -// but still. - -//@ revisions: old next -//@[next] compile-flags: -Znext-solver - -#![feature(rustc_attrs)] - -use std::mem; - -trait MyTrait { - fn foo(&self, s: S) -> usize; -} - -#[rustc_reservation_impl = "foo"] -impl MyTrait for T { - fn foo(&self, _x: u64) -> usize { 0 } -} - -// reservation impls don't create coherence conflicts, even with -// non-chain overlap. -impl MyTrait for u32 { - fn foo(&self, _x: S) -> usize { mem::size_of::() } -} - -fn main() { - // ...and the non-reservation impl gets picked.XS - assert_eq!(0u32.foo(0u64), mem::size_of::()); -}