From 127ab2c1671693c5dd85ca3efb49b1534b0fe9fe Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 20 Oct 2024 19:49:11 +0000 Subject: [PATCH] Implement const effect predicate in new solver --- compiler/rustc_hir_analysis/src/bounds.rs | 11 + .../src/check/compare_impl_item.rs | 139 +++++++-- .../rustc_hir_analysis/src/check/wfcheck.rs | 37 ++- compiler/rustc_hir_analysis/src/collect.rs | 2 + .../src/collect/item_bounds.rs | 38 ++- .../src/collect/predicates_of.rs | 201 +++++++++++- .../src/hir_ty_lowering/bounds.rs | 44 ++- .../src/hir_ty_lowering/dyn_compatibility.rs | 3 +- .../src/hir_ty_lowering/mod.rs | 47 ++- .../src/impl_wf_check/min_specialization.rs | 3 +- .../src/outlives/explicit.rs | 3 +- compiler/rustc_hir_typeck/src/callee.rs | 45 ++- .../src/fn_ctxt/inspect_obligations.rs | 1 + compiler/rustc_hir_typeck/src/method/probe.rs | 3 +- .../rustc_infer/src/infer/outlives/mod.rs | 14 +- compiler/rustc_lint/src/builtin.rs | 4 +- .../src/rmeta/decoder/cstore_impl.rs | 2 + compiler/rustc_metadata/src/rmeta/encoder.rs | 8 +- compiler/rustc_metadata/src/rmeta/mod.rs | 2 + compiler/rustc_middle/src/query/erase.rs | 1 + compiler/rustc_middle/src/query/mod.rs | 18 ++ compiler/rustc_middle/src/ty/codec.rs | 11 + compiler/rustc_middle/src/ty/context.rs | 32 +- compiler/rustc_middle/src/ty/flags.rs | 6 + compiler/rustc_middle/src/ty/generics.rs | 67 ++++ compiler/rustc_middle/src/ty/mod.rs | 13 +- compiler/rustc_middle/src/ty/parameterized.rs | 1 + compiler/rustc_middle/src/ty/predicate.rs | 4 + compiler/rustc_middle/src/ty/print/pretty.rs | 12 + .../src/solve/effect_goals.rs | 295 ++++++++++++++++++ .../src/solve/eval_ctxt/mod.rs | 3 + .../rustc_next_trait_solver/src/solve/mod.rs | 1 + compiler/rustc_privacy/src/lib.rs | 4 + .../rustc_smir/src/rustc_smir/convert/ty.rs | 3 + .../traits/fulfillment_errors.rs | 23 ++ .../src/traits/auto_trait.rs | 3 +- .../src/traits/dyn_compatibility.rs | 4 +- .../src/traits/fulfill.rs | 10 +- .../query/type_op/implied_outlives_bounds.rs | 2 + .../src/traits/select/mod.rs | 7 + .../rustc_trait_selection/src/traits/wf.rs | 5 + .../src/normalize_erasing_regions.rs | 1 + compiler/rustc_ty_utils/src/ty.rs | 7 + compiler/rustc_type_ir/src/elaborate.rs | 10 + compiler/rustc_type_ir/src/inherent.rs | 8 + compiler/rustc_type_ir/src/interner.rs | 11 + compiler/rustc_type_ir/src/ir_print.rs | 5 +- compiler/rustc_type_ir/src/predicate.rs | 55 ++++ compiler/rustc_type_ir/src/predicate_kind.rs | 4 + src/librustdoc/clean/mod.rs | 4 +- .../const-generics/issues/issue-88119.stderr | 18 -- .../ui/consts/const-block-const-bound.stderr | 10 +- ...constifconst-call-in-const-position.stderr | 20 +- tests/ui/consts/fn_trait_refs.stderr | 74 ++++- .../unstable-const-fn-in-libcore.stderr | 10 +- tests/ui/delegation/ice-issue-124347.rs | 2 +- tests/ui/delegation/ice-issue-124347.stderr | 12 +- tests/ui/delegation/unsupported.rs | 2 +- tests/ui/delegation/unsupported.stderr | 12 +- .../impl-trait/normalize-tait-in-const.stderr | 18 +- .../assoc-type-const-bound-usage-0.stderr | 41 +-- .../assoc-type-const-bound-usage-1.stderr | 41 +-- .../call-const-trait-method-fail.stderr | 15 +- .../call-const-trait-method-pass.stderr | 14 +- .../call-generic-in-impl.stderr | 16 +- .../call-generic-method-chain.stderr | 18 +- .../call-generic-method-dup-bound.stderr | 18 +- .../call-generic-method-nonconst.stderr | 16 +- .../call-generic-method-pass.stderr | 10 +- .../const-bounds-non-const-trait.rs | 1 + .../const-bounds-non-const-trait.stderr | 12 +- .../const-closure-trait-method-fail.stderr | 18 +- .../const-closure-trait-method.stderr | 18 +- .../const-closures.stderr | 34 +- .../const-default-method-bodies.stderr | 17 +- .../const-drop-bound.stderr | 26 +- .../const-drop-fail-2.stderr | 10 +- .../const-drop-fail.precise.stderr | 10 +- .../const-drop-fail.stock.stderr | 10 +- .../const-drop.precise.stderr | 24 +- .../const-drop.stock.stderr | 24 +- .../const-fns-are-early-bound.rs | 1 + .../const-fns-are-early-bound.stderr | 222 +++++++++++-- .../const-impl-trait.stderr | 42 ++- .../cross-crate.gatednc.stderr | 17 +- ...-method-body-is-const-same-trait-ck.stderr | 17 +- .../effects/minicore.stderr | 8 +- ...o-explicit-const-params-cross-crate.stderr | 16 +- .../effects/no-explicit-const-params.rs | 1 - .../effects/no-explicit-const-params.stderr | 30 +- .../effects/spec-effectvar-ice.rs | 2 +- .../effects/spec-effectvar-ice.stderr | 22 +- .../ice-123664-unexpected-bound-var.rs | 1 + .../ice-123664-unexpected-bound-var.stderr | 10 +- .../issue-92111.stderr | 10 +- .../non-const-op-in-closure-in-const.stderr | 16 +- ...t-bound-non-const-specialized-bound.stderr | 32 +- .../const-default-const-specialized.stderr | 25 +- .../specialization/default-keyword.rs | 3 +- .../specialization/default-keyword.stderr | 12 - .../issue-95186-specialize-on-tilde-const.rs | 3 +- ...sue-95186-specialize-on-tilde-const.stderr | 43 --- ...87-same-trait-bound-different-constness.rs | 3 +- ...ame-trait-bound-different-constness.stderr | 43 --- ...non-const-default-const-specialized.stderr | 25 +- .../specializing-constness-2.stderr | 25 +- .../specializing-constness.rs | 2 - .../specializing-constness.stderr | 14 +- .../super-traits-fail-2.ny.stderr | 18 +- .../super-traits-fail-2.rs | 4 +- .../super-traits-fail-2.yn.stderr | 17 +- .../super-traits-fail-2.yy.stderr | 17 +- .../super-traits-fail-3.nn.stderr | 12 +- .../super-traits-fail-3.ny.stderr | 18 +- .../super-traits-fail-3.rs | 5 +- .../super-traits-fail-3.yn.stderr | 29 +- .../super-traits-fail.rs | 1 - .../super-traits-fail.stderr | 23 +- .../tilde-const-and-const-params.rs | 2 - .../tilde-const-and-const-params.stderr | 25 +- .../trait-where-clause-const.rs | 6 +- .../trait-where-clause-const.stderr | 51 +-- .../unsatisfied-const-trait-bound.stderr | 25 +- .../ui/specialization/const_trait_impl.stderr | 62 +--- 124 files changed, 1882 insertions(+), 886 deletions(-) create mode 100644 compiler/rustc_next_trait_solver/src/solve/effect_goals.rs delete mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/default-keyword.stderr delete mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.stderr delete mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.stderr diff --git a/compiler/rustc_hir_analysis/src/bounds.rs b/compiler/rustc_hir_analysis/src/bounds.rs index d0c45a7c04c73..334353891fd89 100644 --- a/compiler/rustc_hir_analysis/src/bounds.rs +++ b/compiler/rustc_hir_analysis/src/bounds.rs @@ -81,6 +81,17 @@ impl<'tcx> Bounds<'tcx> { self.clauses.insert(0, (trait_ref.upcast(tcx), span)); } + /// Push a `const` or `~const` bound as a `HostEffect` predicate. + pub(crate) fn push_const_bound( + &mut self, + tcx: TyCtxt<'tcx>, + bound_trait_ref: ty::PolyTraitRef<'tcx>, + host: ty::HostPolarity, + span: Span, + ) { + self.clauses.push((bound_trait_ref.to_host_effect(tcx, host), span)); + } + pub(crate) fn clauses( &self, // FIXME(effects): remove tcx diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index 75956165e8737..50b447cd2adbb 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -187,23 +187,14 @@ fn compare_method_predicate_entailment<'tcx>( let impl_to_placeholder_args = GenericArgs::identity_for_item(tcx, impl_m.def_id); // Create mapping from trait to placeholder. + let impl_def_id = impl_m.container_id(tcx); let trait_to_placeholder_args = - impl_to_placeholder_args.rebase_onto(tcx, impl_m.container_id(tcx), trait_to_impl_args); + impl_to_placeholder_args.rebase_onto(tcx, impl_def_id, trait_to_impl_args); debug!("compare_impl_method: trait_to_placeholder_args={:?}", trait_to_placeholder_args); let impl_m_predicates = tcx.predicates_of(impl_m.def_id); let trait_m_predicates = tcx.predicates_of(trait_m.def_id); - // Create obligations for each predicate declared by the impl - // definition in the context of the trait's parameter - // environment. We can't just use `impl_env.caller_bounds`, - // however, because we want to replace all late-bound regions with - // region variables. - let impl_predicates = tcx.predicates_of(impl_m_predicates.parent.unwrap()); - let mut hybrid_preds = impl_predicates.instantiate_identity(tcx); - - debug!("compare_impl_method: impl_bounds={:?}", hybrid_preds); - // This is the only tricky bit of the new way we check implementation methods // We need to build a set of predicates where only the method-level bounds // are from the trait and we assume all other bounds from the implementation @@ -211,17 +202,35 @@ fn compare_method_predicate_entailment<'tcx>( // // We then register the obligations from the impl_m and check to see // if all constraints hold. - hybrid_preds.predicates.extend( + let impl_predicates = tcx.predicates_of(impl_m_predicates.parent.unwrap()); + let mut hybrid_preds = impl_predicates.instantiate_identity(tcx).predicates; + hybrid_preds.extend( trait_m_predicates .instantiate_own(tcx, trait_to_placeholder_args) .map(|(predicate, _)| predicate), ); + // FIXME(effects): This should be replaced with a more dedicated method. + let check_const_if_const = tcx.constness(impl_def_id) == hir::Constness::Const; + if check_const_if_const { + // Augment the hybrid param-env with the const conditions. + hybrid_preds.extend( + tcx.const_conditions(impl_def_id) + .instantiate_identity(tcx) + .into_iter() + .chain( + tcx.const_conditions(trait_m.def_id) + .instantiate_own(tcx, trait_to_placeholder_args), + ) + .map(|(trait_ref, _)| trait_ref.to_host_effect(tcx, ty::HostPolarity::Maybe)), + ); + } + // Construct trait parameter environment and then shift it into the placeholder viewpoint. // The key step here is to update the caller_bounds's predicates to be // the new hybrid bounds we computed. let normalize_cause = traits::ObligationCause::misc(impl_m_span, impl_m_def_id); - let param_env = ty::ParamEnv::new(tcx.mk_clauses(&hybrid_preds.predicates), Reveal::UserFacing); + let param_env = ty::ParamEnv::new(tcx.mk_clauses(&hybrid_preds), Reveal::UserFacing); let param_env = traits::normalize_param_env_or_error(tcx, param_env, normalize_cause); let infcx = &tcx.infer_ctxt().build(); @@ -229,6 +238,10 @@ fn compare_method_predicate_entailment<'tcx>( debug!("compare_impl_method: caller_bounds={:?}", param_env.caller_bounds()); + // Create obligations for each predicate declared by the impl + // definition in the context of the hybrid param-env. This makes + // sure that the impl's method's where clauses are not more + // restrictive than the trait's method (and the impl itself). let impl_m_own_bounds = impl_m_predicates.instantiate_own(tcx, impl_to_placeholder_args); for (predicate, span) in impl_m_own_bounds { let normalize_cause = traits::ObligationCause::misc(span, impl_m_def_id); @@ -243,6 +256,34 @@ fn compare_method_predicate_entailment<'tcx>( ocx.register_obligation(traits::Obligation::new(tcx, cause, param_env, predicate)); } + // If we're within a const implementation, we need to make sure that the method + // does not assume stronger `~const` bounds than the trait definition. + // + // This registers the `~const` bounds of the impl method, which we will prove + // using the hybrid param-env that we earlier augmented with the const conditions + // from the impl header and trait method declaration. + if check_const_if_const { + for (const_condition, span) in + tcx.const_conditions(impl_m.def_id).instantiate_own(tcx, impl_to_placeholder_args) + { + let normalize_cause = traits::ObligationCause::misc(span, impl_m_def_id); + let const_condition = ocx.normalize(&normalize_cause, param_env, const_condition); + + let cause = + ObligationCause::new(span, impl_m_def_id, ObligationCauseCode::CompareImplItem { + impl_item_def_id: impl_m_def_id, + trait_item_def_id: trait_m.def_id, + kind: impl_m.kind, + }); + ocx.register_obligation(traits::Obligation::new( + tcx, + cause, + param_env, + const_condition.to_host_effect(tcx, ty::HostPolarity::Maybe), + )); + } + } + // We now need to check that the signature of the impl method is // compatible with that of the trait method. We do this by // checking that `impl_fty <: trait_fty`. @@ -1759,14 +1800,14 @@ fn compare_const_predicate_entailment<'tcx>( // The predicates declared by the impl definition, the trait and the // associated const in the trait are assumed. let impl_predicates = tcx.predicates_of(impl_ct_predicates.parent.unwrap()); - let mut hybrid_preds = impl_predicates.instantiate_identity(tcx); - hybrid_preds.predicates.extend( + let mut hybrid_preds = impl_predicates.instantiate_identity(tcx).predicates; + hybrid_preds.extend( trait_ct_predicates .instantiate_own(tcx, trait_to_impl_args) .map(|(predicate, _)| predicate), ); - let param_env = ty::ParamEnv::new(tcx.mk_clauses(&hybrid_preds.predicates), Reveal::UserFacing); + let param_env = ty::ParamEnv::new(tcx.mk_clauses(&hybrid_preds), Reveal::UserFacing); let param_env = traits::normalize_param_env_or_error( tcx, param_env, @@ -1871,14 +1912,16 @@ fn compare_type_predicate_entailment<'tcx>( impl_trait_ref: ty::TraitRef<'tcx>, ) -> Result<(), ErrorGuaranteed> { let impl_args = GenericArgs::identity_for_item(tcx, impl_ty.def_id); - let trait_to_impl_args = - impl_args.rebase_onto(tcx, impl_ty.container_id(tcx), impl_trait_ref.args); + let impl_def_id = impl_ty.container_id(tcx); + let trait_to_impl_args = impl_args.rebase_onto(tcx, impl_def_id, impl_trait_ref.args); let impl_ty_predicates = tcx.predicates_of(impl_ty.def_id); let trait_ty_predicates = tcx.predicates_of(trait_ty.def_id); let impl_ty_own_bounds = impl_ty_predicates.instantiate_own(tcx, impl_args); - if impl_ty_own_bounds.len() == 0 { + let impl_ty_own_const_conditions = + tcx.const_conditions(impl_ty.def_id).instantiate_own(tcx, impl_args); + if impl_ty_own_bounds.len() == 0 && impl_ty_own_const_conditions.len() == 0 { // Nothing to check. return Ok(()); } @@ -1892,18 +1935,31 @@ fn compare_type_predicate_entailment<'tcx>( // The predicates declared by the impl definition, the trait and the // associated type in the trait are assumed. let impl_predicates = tcx.predicates_of(impl_ty_predicates.parent.unwrap()); - let mut hybrid_preds = impl_predicates.instantiate_identity(tcx); - hybrid_preds.predicates.extend( + let mut hybrid_preds = impl_predicates.instantiate_identity(tcx).predicates; + hybrid_preds.extend( trait_ty_predicates .instantiate_own(tcx, trait_to_impl_args) .map(|(predicate, _)| predicate), ); + let check_const_if_const = tcx.constness(impl_def_id) == hir::Constness::Const; + if check_const_if_const { + hybrid_preds.extend( + tcx.const_conditions(impl_ty_predicates.parent.unwrap()) + .instantiate_identity(tcx) + .into_iter() + .chain( + tcx.const_conditions(trait_ty.def_id).instantiate_own(tcx, trait_to_impl_args), + ) + .map(|(trait_ref, _)| trait_ref.to_host_effect(tcx, ty::HostPolarity::Maybe)), + ); + } + debug!("compare_type_predicate_entailment: bounds={:?}", hybrid_preds); let impl_ty_span = tcx.def_span(impl_ty_def_id); let normalize_cause = ObligationCause::misc(impl_ty_span, impl_ty_def_id); - let param_env = ty::ParamEnv::new(tcx.mk_clauses(&hybrid_preds.predicates), Reveal::UserFacing); + let param_env = ty::ParamEnv::new(tcx.mk_clauses(&hybrid_preds), Reveal::UserFacing); let param_env = traits::normalize_param_env_or_error(tcx, param_env, normalize_cause); let infcx = tcx.infer_ctxt().build(); let ocx = ObligationCtxt::new_with_diagnostics(&infcx); @@ -1923,6 +1979,27 @@ fn compare_type_predicate_entailment<'tcx>( ocx.register_obligation(traits::Obligation::new(tcx, cause, param_env, predicate)); } + if check_const_if_const { + // Validate the const conditions of the impl method. + for (const_condition, span) in impl_ty_own_const_conditions { + let normalize_cause = traits::ObligationCause::misc(span, impl_ty_def_id); + let const_condition = ocx.normalize(&normalize_cause, param_env, const_condition); + + let cause = + ObligationCause::new(span, impl_ty_def_id, ObligationCauseCode::CompareImplItem { + impl_item_def_id: impl_ty_def_id, + trait_item_def_id: trait_ty.def_id, + kind: impl_ty.kind, + }); + ocx.register_obligation(traits::Obligation::new( + tcx, + cause, + param_env, + const_condition.to_host_effect(tcx, ty::HostPolarity::Maybe), + )); + } + } + // Check that all obligations are satisfied by the implementation's // version. let errors = ocx.select_all_or_error(); @@ -2005,7 +2082,7 @@ pub(super) fn check_type_bounds<'tcx>( ObligationCause::new(impl_ty_span, impl_ty_def_id, code) }; - let obligations: Vec<_> = tcx + let mut obligations: Vec<_> = tcx .explicit_item_bounds(trait_ty.def_id) .iter_instantiated_copied(tcx, rebased_args) .map(|(concrete_ty_bound, span)| { @@ -2013,6 +2090,22 @@ pub(super) fn check_type_bounds<'tcx>( traits::Obligation::new(tcx, mk_cause(span), param_env, concrete_ty_bound) }) .collect(); + + // Only in a const implementation do we need to check that the `~const` item bounds hold. + if tcx.constness(container_id) == hir::Constness::Const { + obligations.extend( + tcx.implied_const_bounds(trait_ty.def_id) + .iter_instantiated_copied(tcx, rebased_args) + .map(|(c, span)| { + traits::Obligation::new( + tcx, + mk_cause(span), + param_env, + c.to_host_effect(tcx, ty::HostPolarity::Maybe), + ) + }), + ); + } debug!("check_type_bounds: item_bounds={:?}", obligations); // Normalize predicates with the assumption that the GAT may always normalize diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 85514cd88c76d..fc524ac6cc83f 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -32,7 +32,8 @@ use rustc_trait_selection::traits::misc::{ use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _; use rustc_trait_selection::traits::{ - self, FulfillmentError, ObligationCause, ObligationCauseCode, ObligationCtxt, WellFormedLoc, + self, FulfillmentError, Obligation, ObligationCause, ObligationCauseCode, ObligationCtxt, + WellFormedLoc, }; use rustc_type_ir::TypeFlags; use rustc_type_ir::solve::NoSolution; @@ -86,7 +87,7 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> { self.body_def_id, ObligationCauseCode::WellFormed(loc), ); - self.ocx.register_obligation(traits::Obligation::new( + self.ocx.register_obligation(Obligation::new( self.tcx(), cause, self.param_env, @@ -1173,7 +1174,7 @@ fn check_type_defn<'tcx>( wfcx.body_def_id, ObligationCauseCode::Misc, ); - wfcx.register_obligation(traits::Obligation::new( + wfcx.register_obligation(Obligation::new( tcx, cause, wfcx.param_env, @@ -1369,6 +1370,30 @@ fn check_impl<'tcx>( obligation.cause.span = hir_self_ty.span; } } + + // Ensure that the `~const` where clauses of the trait hold for the impl. + if tcx.constness(item.owner_id.def_id) == hir::Constness::Const { + for (bound, _) in + tcx.const_conditions(trait_ref.def_id).instantiate(tcx, trait_ref.args) + { + let bound = wfcx.normalize( + item.span, + Some(WellFormedLoc::Ty(item.hir_id().expect_owner().def_id)), + bound, + ); + wfcx.register_obligation(Obligation::new( + tcx, + ObligationCause::new( + hir_self_ty.span, + wfcx.body_def_id, + ObligationCauseCode::WellFormed(None), + ), + wfcx.param_env, + bound.to_host_effect(tcx, ty::HostPolarity::Maybe), + )) + } + } + debug!(?obligations); wfcx.register_obligations(obligations); } @@ -1561,7 +1586,7 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id wfcx.body_def_id, ObligationCauseCode::WhereClause(def_id.to_def_id(), DUMMY_SP), ); - traits::Obligation::new(tcx, cause, wfcx.param_env, pred) + Obligation::new(tcx, cause, wfcx.param_env, pred) }); let predicates = predicates.instantiate_identity(tcx); @@ -1852,7 +1877,7 @@ fn receiver_is_implemented<'tcx>( let tcx = wfcx.tcx(); let trait_ref = ty::TraitRef::new(tcx, receiver_trait_def_id, [receiver_ty]); - let obligation = traits::Obligation::new(tcx, cause, wfcx.param_env, trait_ref); + let obligation = Obligation::new(tcx, cause, wfcx.param_env, trait_ref); if wfcx.infcx.predicate_must_hold_modulo_regions(&obligation) { true @@ -2188,7 +2213,7 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> { .unwrap_or(obligation_span); } - let obligation = traits::Obligation::new( + let obligation = Obligation::new( tcx, traits::ObligationCause::new( span, diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index f63e2d40e3906..0cceca89da1a7 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -77,6 +77,8 @@ pub fn provide(providers: &mut Providers) { explicit_supertraits_containing_assoc_item: predicates_of::explicit_supertraits_containing_assoc_item, trait_explicit_predicates_and_bounds: predicates_of::trait_explicit_predicates_and_bounds, + const_conditions: predicates_of::const_conditions, + implied_const_bounds: predicates_of::implied_const_bounds, type_param_predicates: predicates_of::type_param_predicates, trait_def, adt_def, diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs index 4346504450d0b..64194b779a1c4 100644 --- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs +++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs @@ -37,8 +37,18 @@ fn associated_type_bounds<'tcx>( let icx = ItemCtxt::new(tcx, assoc_item_def_id); let mut bounds = icx.lowerer().lower_mono_bounds(item_ty, hir_bounds, filter); + // Associated types are implicitly sized unless a `?Sized` bound is found - icx.lowerer().add_sized_bound(&mut bounds, item_ty, hir_bounds, None, span); + match filter { + PredicateFilter::All + | PredicateFilter::SelfOnly + | PredicateFilter::SelfThatDefines(_) + | PredicateFilter::SelfAndAssociatedTypeBounds => { + icx.lowerer().add_sized_bound(&mut bounds, item_ty, hir_bounds, None, span); + } + // We don't lower any bounds except for `~const` for `ConstIfConst` filtering. + PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst => {} + } let trait_def_id = tcx.local_parent(assoc_item_def_id); let trait_predicates = tcx.trait_explicit_predicates_and_bounds(trait_def_id); @@ -107,10 +117,19 @@ fn remap_gat_vars_and_recurse_into_nested_projections<'tcx>( } else { // Only collect *self* type bounds if the filter is for self. match filter { - PredicateFilter::SelfOnly | PredicateFilter::SelfThatDefines(_) => { + PredicateFilter::All => {} + PredicateFilter::SelfOnly => { return None; } - PredicateFilter::All | PredicateFilter::SelfAndAssociatedTypeBounds => {} + PredicateFilter::SelfThatDefines(_) + | PredicateFilter::SelfConstIfConst + | PredicateFilter::SelfAndAssociatedTypeBounds + | PredicateFilter::ConstIfConst => { + unreachable!( + "invalid predicate filter for \ + `remap_gat_vars_and_recurse_into_nested_projections`" + ) + } } clause_ty = alias_ty.self_ty(); @@ -304,8 +323,19 @@ fn opaque_type_bounds<'tcx>( ty::print::with_reduced_queries!({ let icx = ItemCtxt::new(tcx, opaque_def_id); let mut bounds = icx.lowerer().lower_mono_bounds(item_ty, hir_bounds, filter); + // Opaque types are implicitly sized unless a `?Sized` bound is found - icx.lowerer().add_sized_bound(&mut bounds, item_ty, hir_bounds, None, span); + match filter { + PredicateFilter::All + | PredicateFilter::SelfOnly + | PredicateFilter::SelfThatDefines(_) + | PredicateFilter::SelfAndAssociatedTypeBounds => { + // Associated types are implicitly sized unless a `?Sized` bound is found + icx.lowerer().add_sized_bound(&mut bounds, item_ty, hir_bounds, None, span); + } + // We don't lower any bounds except for `~const` for `ConstIfConst` filtering. + PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst => {} + } debug!(?bounds); tcx.arena.alloc_from_iter(bounds.clauses(tcx)) diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index c45a8b2dfa111..eb593d01086dd 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -12,6 +12,7 @@ use rustc_span::symbol::Ident; use rustc_span::{DUMMY_SP, Span}; use tracing::{debug, instrument, trace}; +use super::item_bounds::explicit_item_bounds_with_filter; use crate::bounds::Bounds; use crate::collect::ItemCtxt; use crate::constrained_generic_params as cgp; @@ -701,7 +702,8 @@ pub(super) fn assert_only_contains_predicates_from<'tcx>( ty::ClauseKind::RegionOutlives(_) | ty::ClauseKind::ConstArgHasType(_, _) | ty::ClauseKind::WellFormed(_) - | ty::ClauseKind::ConstEvaluatable(_) => { + | ty::ClauseKind::ConstEvaluatable(_) + | ty::ClauseKind::HostEffect(..) => { bug!( "unexpected non-`Self` predicate when computing `{filter:?}` implied bounds: {clause:?}" ); @@ -709,6 +711,36 @@ pub(super) fn assert_only_contains_predicates_from<'tcx>( } } } + PredicateFilter::ConstIfConst => { + for (clause, _) in bounds { + match clause.kind().skip_binder() { + ty::ClauseKind::HostEffect(_) => {} + _ => { + bug!( + "unexpected non-`HostEffect` predicate when computing `{filter:?}` implied bounds: {clause:?}" + ); + } + } + } + } + PredicateFilter::SelfConstIfConst => { + for (clause, _) in bounds { + match clause.kind().skip_binder() { + ty::ClauseKind::HostEffect(pred) => { + assert_eq!( + pred.trait_ref.self_ty(), + ty, + "expected `Self` predicate when computing `{filter:?}` implied bounds: {clause:?}" + ); + } + _ => { + bug!( + "unexpected non-`HostEffect` predicate when computing `{filter:?}` implied bounds: {clause:?}" + ); + } + } + } + } PredicateFilter::All | PredicateFilter::SelfAndAssociatedTypeBounds => {} } } @@ -825,3 +857,170 @@ impl<'tcx> ItemCtxt<'tcx> { bounds.clauses(self.tcx).collect() } } + +/// Compute the conditions that need to hold for a conditionally-const item to be const. +/// That is, compute the set of `~const` where clauses for a given item. +/// +/// This query also computes the `~const` where clauses for associated types, which are +/// not "const", but which have item bounds which may be `~const`. These must hold for +/// the `~const` item bound to hold. +pub(super) fn const_conditions<'tcx>( + tcx: TyCtxt<'tcx>, + def_id: LocalDefId, +) -> ty::ConstConditions<'tcx> { + // This logic is spaghetti, and should be cleaned up. The current methods that are + // defined to deal with constness are very unintuitive. + if tcx.is_const_fn_raw(def_id.to_def_id()) { + // Ok, const fn or method in const trait. + } else { + match tcx.def_kind(def_id) { + DefKind::Trait => { + if !tcx.is_const_trait(def_id.to_def_id()) { + return Default::default(); + } + } + DefKind::Impl { .. } => { + if !tcx + .trait_id_of_impl(def_id.to_def_id()) + .is_some_and(|def_id| tcx.is_const_trait(def_id)) + { + return Default::default(); + } + } + DefKind::AssocTy | DefKind::AssocFn => { + let parent_def_id = tcx.local_parent(def_id).to_def_id(); + match tcx.associated_item(def_id).container { + ty::AssocItemContainer::TraitContainer => { + if !tcx.is_const_trait(parent_def_id) { + return Default::default(); + } + } + ty::AssocItemContainer::ImplContainer => { + if !tcx + .trait_id_of_impl(parent_def_id) + .is_some_and(|def_id| tcx.is_const_trait(def_id)) + { + return Default::default(); + } + } + } + } + _ => return Default::default(), + } + } + + let (generics, is_trait, has_parent) = match tcx.hir_node_by_def_id(def_id) { + Node::Item(item) => match item.kind { + hir::ItemKind::Impl(impl_) => (impl_.generics, None, false), + hir::ItemKind::Fn(_, generics, _) => (generics, None, false), + hir::ItemKind::Trait(_, _, generics, supertraits, _) => { + (generics, Some((item.owner_id.def_id, supertraits)), false) + } + _ => return Default::default(), + }, + Node::TraitItem(item) => match item.kind { + hir::TraitItemKind::Fn(_, _) => (item.generics, None, true), + _ => return Default::default(), + }, + Node::ImplItem(item) => match item.kind { + hir::ImplItemKind::Fn(_, _) => (item.generics, None, true), + _ => return Default::default(), + }, + _ => return Default::default(), + }; + + let icx = ItemCtxt::new(tcx, def_id); + let mut bounds = Bounds::default(); + + for pred in generics.predicates { + match pred { + hir::WherePredicate::BoundPredicate(bound_pred) => { + let ty = icx.lowerer().lower_ty_maybe_return_type_notation(bound_pred.bounded_ty); + let bound_vars = tcx.late_bound_vars(bound_pred.hir_id); + icx.lowerer().lower_poly_bounds( + ty, + bound_pred.bounds.iter(), + &mut bounds, + bound_vars, + PredicateFilter::ConstIfConst, + ); + } + _ => {} + } + } + + if let Some((def_id, supertraits)) = is_trait { + bounds.push_const_bound( + tcx, + ty::Binder::dummy(ty::TraitRef::identity(tcx, def_id.to_def_id())), + ty::HostPolarity::Maybe, + DUMMY_SP, + ); + + icx.lowerer().lower_poly_bounds( + tcx.types.self_param, + supertraits.into_iter(), + &mut bounds, + ty::List::empty(), + PredicateFilter::ConstIfConst, + ); + } + + ty::ConstConditions { + parent: has_parent.then(|| tcx.local_parent(def_id).to_def_id()), + predicates: tcx.arena.alloc_from_iter(bounds.clauses(tcx).map(|(clause, span)| { + ( + clause.kind().map_bound(|clause| match clause { + ty::ClauseKind::HostEffect(ty::HostEffectPredicate { + trait_ref, + host: ty::HostPolarity::Maybe, + }) => trait_ref, + _ => bug!("converted {clause:?}"), + }), + span, + ) + })), + } +} + +pub(super) fn implied_const_bounds<'tcx>( + tcx: TyCtxt<'tcx>, + def_id: LocalDefId, +) -> ty::EarlyBinder<'tcx, &'tcx [(ty::PolyTraitRef<'tcx>, Span)]> { + let bounds = match tcx.hir_node_by_def_id(def_id) { + Node::Item(hir::Item { kind: hir::ItemKind::Trait(..), .. }) => { + if !tcx.is_const_trait(def_id.to_def_id()) { + return ty::EarlyBinder::bind(&[]); + } + + implied_predicates_with_filter( + tcx, + def_id.to_def_id(), + PredicateFilter::SelfConstIfConst, + ) + } + Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Type(..), .. }) => { + if !tcx.is_const_trait(tcx.local_parent(def_id).to_def_id()) { + return ty::EarlyBinder::bind(&[]); + } + + explicit_item_bounds_with_filter(tcx, def_id, PredicateFilter::ConstIfConst) + } + _ => return ty::EarlyBinder::bind(&[]), + }; + + bounds.map_bound(|bounds| { + &*tcx.arena.alloc_from_iter(bounds.iter().copied().map(|(clause, span)| { + ( + clause.kind().map_bound(|clause| match clause { + ty::ClauseKind::HostEffect(ty::HostEffectPredicate { + trait_ref, + host: ty::HostPolarity::Maybe, + }) => trait_ref, + _ => bug!("converted {clause:?}"), + }), + span, + ) + })) + }) +} diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs index 310f648b980e6..a3c6ec99fd9f9 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs @@ -155,7 +155,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { for hir_bound in hir_bounds { // In order to avoid cycles, when we're lowering `SelfThatDefines`, // we skip over any traits that don't define the given associated type. - if let PredicateFilter::SelfThatDefines(assoc_name) = predicate_filter { if let Some(trait_ref) = hir_bound.trait_ref() && let Some(trait_did) = trait_ref.trait_def_id() @@ -195,6 +194,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { ); } hir::GenericBound::Outlives(lifetime) => { + // We don't lower any bounds except for `~const` for `ConstIfConst` + // filtering. + if matches!( + predicate_filter, + PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst + ) { + continue; + } + let region = self.lower_lifetime(lifetime, RegionInferReason::OutlivesBound); bounds.push_region_bound( self.tcx(), @@ -423,21 +431,32 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { }, ); - bounds.push_projection_bound( - tcx, - projection_term.map_bound(|projection_term| ty::ProjectionPredicate { - projection_term, - term, - }), - constraint.span, - ); + match predicate_filter { + PredicateFilter::All + | PredicateFilter::SelfOnly + | PredicateFilter::SelfThatDefines(_) + | PredicateFilter::SelfAndAssociatedTypeBounds => { + bounds.push_projection_bound( + tcx, + projection_term.map_bound(|projection_term| ty::ProjectionPredicate { + projection_term, + term, + }), + constraint.span, + ); + } + // We don't lower any bounds except for `~const` for `ConstIfConst` + // filtering. + PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst => {} + } } // Lower a constraint like `Item: Debug` as found in HIR bound `T: Iterator` // to a bound involving a projection: `::Item: Debug`. hir::AssocItemConstraintKind::Bound { bounds: hir_bounds } => { match predicate_filter { - PredicateFilter::SelfOnly | PredicateFilter::SelfThatDefines(_) => {} - PredicateFilter::All | PredicateFilter::SelfAndAssociatedTypeBounds => { + PredicateFilter::All + | PredicateFilter::SelfAndAssociatedTypeBounds + | PredicateFilter::ConstIfConst => { let projection_ty = projection_term .map_bound(|projection_term| projection_term.expect_ty(self.tcx())); // Calling `skip_binder` is okay, because `lower_bounds` expects the `param_ty` @@ -452,6 +471,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { predicate_filter, ); } + PredicateFilter::SelfOnly + | PredicateFilter::SelfThatDefines(_) + | PredicateFilter::SelfConstIfConst => {} } } } diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs index 2cf97e290605b..e10b6e6fe1704 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs @@ -79,7 +79,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { ty::ClauseKind::RegionOutlives(_) | ty::ClauseKind::ConstArgHasType(..) | ty::ClauseKind::WellFormed(_) - | ty::ClauseKind::ConstEvaluatable(_) => { + | ty::ClauseKind::ConstEvaluatable(_) + | ty::ClauseKind::HostEffect(..) => { span_bug!(span, "did not expect {pred} clause in object bounds"); } } diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 8f5358e26f708..3aaafd6aec8fe 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -81,6 +81,12 @@ pub enum PredicateFilter { /// For example, given `Self: Tr`, this would expand to `Self: Tr` /// and `::A: B`. SelfAndAssociatedTypeBounds, + + /// Filter only the `~const` bounds, which are lowered into `HostEffect` clauses. + ConstIfConst, + + /// Filter only the `~const` bounds which are *also* in the supertrait position. + SelfConstIfConst, } #[derive(Debug)] @@ -693,8 +699,45 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { bound_vars, ); - debug!(?poly_trait_ref); - bounds.push_trait_bound(tcx, poly_trait_ref, span, polarity); + match predicate_filter { + PredicateFilter::All + | PredicateFilter::SelfOnly + | PredicateFilter::SelfThatDefines(..) + | PredicateFilter::SelfAndAssociatedTypeBounds => { + debug!(?poly_trait_ref); + bounds.push_trait_bound(tcx, poly_trait_ref, span, polarity); + + match constness { + ty::BoundConstness::Const => { + if polarity == ty::PredicatePolarity::Positive { + bounds.push_const_bound( + tcx, + poly_trait_ref, + ty::HostPolarity::Const, + span, + ); + } + } + ty::BoundConstness::NotConst => {} + ty::BoundConstness::ConstIfConst => { + // We don't emit a const bound here, since that would mean that we + // unconditionally need to prove a `HostEffect` predicate, even when + // the predicates are being instantiated in a non-const context. This + // is instead handled in the `const_conditions` query. + } + } + } + // On the flip side, when filtering `ConstIfConst` bounds, we only need to convert + // `~const` bounds. All other predicates are handled in their respective queries. + PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst => match constness { + ty::BoundConstness::ConstIfConst => { + if polarity == ty::PredicatePolarity::Positive { + bounds.push_const_bound(tcx, poly_trait_ref, ty::HostPolarity::Maybe, span); + } + } + ty::BoundConstness::NotConst | ty::BoundConstness::Const => {} + }, + } let mut dup_constraints = FxIndexMap::default(); for constraint in trait_segment.args().constraints { diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs index 0355adfcb11e1..a394fc2fbb199 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs @@ -530,6 +530,7 @@ fn trait_specialization_kind<'tcx>( | ty::ClauseKind::Projection(_) | ty::ClauseKind::ConstArgHasType(..) | ty::ClauseKind::WellFormed(_) - | ty::ClauseKind::ConstEvaluatable(..) => None, + | ty::ClauseKind::ConstEvaluatable(..) + | ty::ClauseKind::HostEffect(..) => None, } } diff --git a/compiler/rustc_hir_analysis/src/outlives/explicit.rs b/compiler/rustc_hir_analysis/src/outlives/explicit.rs index f576499ecac38..2c1d443f9512f 100644 --- a/compiler/rustc_hir_analysis/src/outlives/explicit.rs +++ b/compiler/rustc_hir_analysis/src/outlives/explicit.rs @@ -53,7 +53,8 @@ impl<'tcx> ExplicitPredicatesMap<'tcx> { | ty::ClauseKind::Projection(_) | ty::ClauseKind::ConstArgHasType(_, _) | ty::ClauseKind::WellFormed(_) - | ty::ClauseKind::ConstEvaluatable(_) => {} + | ty::ClauseKind::ConstEvaluatable(_) + | ty::ClauseKind::HostEffect(..) => {} } } diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index b642ba03aee2e..8899b2d5d6f35 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -836,14 +836,49 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn_sig.output() } - #[tracing::instrument(level = "debug", skip(self, _span))] + #[tracing::instrument(level = "debug", skip(self, span))] pub(super) fn enforce_context_effects( &self, - _span: Span, - _callee_did: DefId, - _callee_args: GenericArgsRef<'tcx>, + span: Span, + callee_did: DefId, + callee_args: GenericArgsRef<'tcx>, ) { - todo!() + // FIXME(effects): We should be enforcing these effects unconditionally. + // This can be done as soon as we convert the standard library back to + // using const traits, since if we were to enforce these conditions now, + // we'd fail on basically every builtin trait call (i.e. `1 + 2`). + if !self.tcx.features().effects { + return; + } + + let host = match self.tcx.hir().body_const_context(self.body_id) { + Some(hir::ConstContext::Const { .. } | hir::ConstContext::Static(_)) => { + ty::HostPolarity::Const + } + Some(hir::ConstContext::ConstFn) => ty::HostPolarity::Maybe, + None => return, + }; + + if self.tcx.is_const_fn(callee_did) + || self + .tcx + .trait_of_item(callee_did) + .is_some_and(|def_id| self.tcx.is_const_trait(def_id)) + { + let q = self.tcx.const_conditions(callee_did); + // FIXME(effects): Use this span with a better cause code. + for (cond, _) in q.instantiate(self.tcx, callee_args) { + self.register_predicate(Obligation::new( + self.tcx, + self.misc(span), + self.param_env, + cond.to_host_effect(self.tcx, host), + )); + } + } else { + // FIXME(effects): This should eventually be caught here. + // For now, though, we defer some const checking to MIR. + } } fn confirm_overloaded_call( diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs index 693cb4465cc15..eb5fe3a86e4c5 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs @@ -52,6 +52,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { | ty::PredicateKind::AliasRelate(..) | ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..)) | ty::PredicateKind::ConstEquate(..) + | ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(..)) | ty::PredicateKind::Ambiguous => false, } } diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 1be711887d9fa..848e28de3891c 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -813,7 +813,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { | ty::ClauseKind::Projection(_) | ty::ClauseKind::ConstArgHasType(_, _) | ty::ClauseKind::WellFormed(_) - | ty::ClauseKind::ConstEvaluatable(_) => None, + | ty::ClauseKind::ConstEvaluatable(_) + | ty::ClauseKind::HostEffect(..) => None, } }); diff --git a/compiler/rustc_infer/src/infer/outlives/mod.rs b/compiler/rustc_infer/src/infer/outlives/mod.rs index e23bb1aaa5631..1afe50e336da2 100644 --- a/compiler/rustc_infer/src/infer/outlives/mod.rs +++ b/compiler/rustc_infer/src/infer/outlives/mod.rs @@ -24,19 +24,9 @@ pub fn explicit_outlives_bounds<'tcx>( param_env .caller_bounds() .into_iter() - .map(ty::Clause::kind) + .filter_map(ty::Clause::as_region_outlives_clause) .filter_map(ty::Binder::no_bound_vars) - .filter_map(move |kind| match kind { - ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(r_a, r_b)) => { - Some(OutlivesBound::RegionSubRegion(r_b, r_a)) - } - ty::ClauseKind::Trait(_) - | ty::ClauseKind::TypeOutlives(_) - | ty::ClauseKind::Projection(_) - | ty::ClauseKind::ConstArgHasType(_, _) - | ty::ClauseKind::WellFormed(_) - | ty::ClauseKind::ConstEvaluatable(_) => None, - }) + .map(|ty::OutlivesPredicate(r_a, r_b)| OutlivesBound::RegionSubRegion(r_b, r_a)) } impl<'tcx> InferCtxt<'tcx> { diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 8bd9c899a6286..c8d5aa4c35ab1 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -1554,7 +1554,9 @@ impl<'tcx> LateLintPass<'tcx> for TrivialConstraints { // Ignore bounds that a user can't type | ClauseKind::WellFormed(..) // FIXME(generic_const_exprs): `ConstEvaluatable` can be written - | ClauseKind::ConstEvaluatable(..) => continue, + | ClauseKind::ConstEvaluatable(..) + // Users don't write this directly, only via another trait ref. + | ty::ClauseKind::HostEffect(..) => continue, }; if predicate.is_global() { cx.emit_span_lint(TRIVIAL_BOUNDS, span, BuiltinTrivialBounds { diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index d4cbf6e13afbc..71c7231a78826 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -275,6 +275,8 @@ provide! { tcx, def_id, other, cdata, impl_parent => { table } defaultness => { table_direct } constness => { table_direct } + const_conditions => { table } + implied_const_bounds => { table_defaulted_array } coerce_unsized_info => { Ok(cdata .root diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 812cdbd1fcaa0..2f6342866d7bc 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1423,6 +1423,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let g = tcx.generics_of(def_id); record!(self.tables.generics_of[def_id] <- g); record!(self.tables.explicit_predicates_of[def_id] <- self.tcx.explicit_predicates_of(def_id)); + record!(self.tables.const_conditions[def_id] <- self.tcx.const_conditions(def_id)); let inferred_outlives = self.tcx.inferred_outlives_of(def_id); record_defaulted_array!(self.tables.inferred_outlives_of[def_id] <- inferred_outlives); @@ -1456,7 +1457,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { self.tcx.explicit_super_predicates_of(def_id).skip_binder()); record_defaulted_array!(self.tables.explicit_implied_predicates_of[def_id] <- self.tcx.explicit_implied_predicates_of(def_id).skip_binder()); - + record_defaulted_array!(self.tables.implied_const_bounds[def_id] + <- self.tcx.implied_const_bounds(def_id).skip_binder()); let module_children = self.tcx.module_children_local(local_id); record_array!(self.tables.module_children_non_reexports[def_id] <- module_children.iter().map(|child| child.res.def_id().index)); @@ -1467,6 +1469,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { self.tcx.explicit_super_predicates_of(def_id).skip_binder()); record_defaulted_array!(self.tables.explicit_implied_predicates_of[def_id] <- self.tcx.explicit_implied_predicates_of(def_id).skip_binder()); + record_defaulted_array!(self.tables.implied_const_bounds[def_id] + <- self.tcx.implied_const_bounds(def_id).skip_binder()); } if let DefKind::Trait | DefKind::Impl { .. } = def_kind { let associated_item_def_ids = self.tcx.associated_item_def_ids(def_id); @@ -1649,6 +1653,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { if let ty::AssocKind::Type = item.kind { self.encode_explicit_item_bounds(def_id); self.encode_explicit_item_super_predicates(def_id); + record_defaulted_array!(self.tables.implied_const_bounds[def_id] + <- self.tcx.implied_const_bounds(def_id).skip_binder()); } } AssocItemContainer::ImplContainer => { diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 8da1be8054460..a00ca27aacc0c 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -392,6 +392,7 @@ define_tables! { inferred_outlives_of: Table, Span)>>, explicit_super_predicates_of: Table, Span)>>, explicit_implied_predicates_of: Table, Span)>>, + implied_const_bounds: Table, Span)>>, inherent_impls: Table>, associated_types_for_impl_traits_in_associated_fn: Table>, opt_rpitit_info: Table>>, @@ -435,6 +436,7 @@ define_tables! { thir_abstract_const: Table>>>, impl_parent: Table, constness: Table, + const_conditions: Table>>, defaultness: Table, // FIXME(eddyb) perhaps compute this on the fly if cheap enough? coerce_unsized_info: Table>, diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs index 48bf4ffced0ce..5f8427bd707aa 100644 --- a/compiler/rustc_middle/src/query/erase.rs +++ b/compiler/rustc_middle/src/query/erase.rs @@ -370,6 +370,7 @@ tcx_lifetime! { rustc_middle::ty::FnSig, rustc_middle::ty::GenericArg, rustc_middle::ty::GenericPredicates, + rustc_middle::ty::ConstConditions, rustc_middle::ty::inhabitedness::InhabitedPredicate, rustc_middle::ty::Instance, rustc_middle::ty::InstanceKind, diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 0b751779501d9..d03fc39c9ade1 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -683,6 +683,24 @@ rustc_queries! { } } + query const_conditions( + key: DefId + ) -> ty::ConstConditions<'tcx> { + desc { |tcx| "computing the conditions for `{}` to be considered const", + tcx.def_path_str(key) + } + separate_provide_extern + } + + query implied_const_bounds( + key: DefId + ) -> ty::EarlyBinder<'tcx, &'tcx [(ty::PolyTraitRef<'tcx>, Span)]> { + desc { |tcx| "computing the implied `~const` bounds for `{}`", + tcx.def_path_str(key) + } + separate_provide_extern + } + /// To avoid cycles within the predicates of a single item we compute /// per-type-parameter predicates for resolving `T::AssocTy`. query type_param_predicates( diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs index 7e533bc4291a1..ef9dfdd2f9624 100644 --- a/compiler/rustc_middle/src/ty/codec.rs +++ b/compiler/rustc_middle/src/ty/codec.rs @@ -386,6 +386,17 @@ impl<'tcx, D: TyDecoder>> RefDecodable<'tcx, D> for [(ty::Claus } } +impl<'tcx, D: TyDecoder>> RefDecodable<'tcx, D> + for [(ty::PolyTraitRef<'tcx>, Span)] +{ + fn decode(decoder: &mut D) -> &'tcx Self { + decoder + .interner() + .arena + .alloc_from_iter((0..decoder.read_usize()).map(|_| Decodable::decode(decoder))) + } +} + impl<'tcx, D: TyDecoder>> RefDecodable<'tcx, D> for ty::List { diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 46d3149564f5e..b906e07ad2737 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -78,10 +78,10 @@ use crate::traits::solve::{ use crate::ty::predicate::ExistentialPredicateStableCmpExt as _; use crate::ty::{ self, AdtDef, AdtDefData, AdtKind, Binder, Clause, Clauses, Const, GenericArg, GenericArgs, - GenericArgsRef, GenericParamDefKind, ImplPolarity, List, ListWithCachedTypeInfo, ParamConst, - ParamTy, Pattern, PatternKind, PolyExistentialPredicate, PolyFnSig, Predicate, PredicateKind, - PredicatePolarity, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyVid, - Visibility, + GenericArgsRef, GenericParamDefKind, HostPolarity, ImplPolarity, List, ListWithCachedTypeInfo, + ParamConst, ParamTy, Pattern, PatternKind, PolyExistentialPredicate, PolyFnSig, Predicate, + PredicateKind, PredicatePolarity, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, + TyKind, TyVid, Visibility, }; #[allow(rustc::usage_of_ty_tykind)] @@ -363,6 +363,28 @@ impl<'tcx> Interner for TyCtxt<'tcx> { self.explicit_implied_predicates_of(def_id).map_bound(|preds| preds.into_iter().copied()) } + fn is_const_impl(self, def_id: DefId) -> bool { + self.constness(def_id) == hir::Constness::Const + } + + fn const_conditions( + self, + def_id: DefId, + ) -> ty::EarlyBinder<'tcx, impl IntoIterator>>> { + ty::EarlyBinder::bind( + self.const_conditions(def_id).instantiate_identity(self).into_iter().map(|(c, _)| c), + ) + } + + fn implied_const_bounds( + self, + def_id: DefId, + ) -> ty::EarlyBinder<'tcx, impl IntoIterator>>> { + ty::EarlyBinder::bind( + self.implied_const_bounds(def_id).iter_identity_copied().map(|(c, _)| c), + ) + } + fn has_target_features(self, def_id: DefId) -> bool { !self.codegen_fn_attrs(def_id).target_features.is_empty() } @@ -2169,7 +2191,7 @@ macro_rules! nop_slice_lift { nop_slice_lift! {ty::ValTree<'a> => ty::ValTree<'tcx>} TrivialLiftImpls! { - ImplPolarity, PredicatePolarity, Promoted + ImplPolarity, PredicatePolarity, Promoted, HostPolarity, } macro_rules! sty_debug_print { diff --git a/compiler/rustc_middle/src/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs index 39899f1d32be6..704a197aa49d0 100644 --- a/compiler/rustc_middle/src/ty/flags.rs +++ b/compiler/rustc_middle/src/ty/flags.rs @@ -265,6 +265,12 @@ impl FlagComputation { ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_pred)) => { self.add_args(trait_pred.trait_ref.args); } + ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(ty::HostEffectPredicate { + trait_ref, + host: _, + })) => { + self.add_args(trait_ref.args); + } ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate( a, b, diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs index 7c83888b834d2..27e29763b5935 100644 --- a/compiler/rustc_middle/src/ty/generics.rs +++ b/compiler/rustc_middle/src/ty/generics.rs @@ -420,3 +420,70 @@ impl<'tcx> GenericPredicates<'tcx> { instantiated.spans.extend(self.predicates.iter().map(|(_, s)| s)); } } + +/// `~const` bounds for a given item. This is represented using a struct much like +/// `GenericPredicates`, where you can either choose to only instantiate the "own" +/// bounds or all of the bounds including those from the parent. This distinction +/// is necessary for code like `compare_method_predicate_entailment`. +#[derive(Copy, Clone, Default, Debug, TyEncodable, TyDecodable, HashStable)] +pub struct ConstConditions<'tcx> { + pub parent: Option, + pub predicates: &'tcx [(ty::PolyTraitRef<'tcx>, Span)], +} + +impl<'tcx> ConstConditions<'tcx> { + pub fn instantiate( + self, + tcx: TyCtxt<'tcx>, + args: GenericArgsRef<'tcx>, + ) -> Vec<(ty::PolyTraitRef<'tcx>, Span)> { + let mut instantiated = vec![]; + self.instantiate_into(tcx, &mut instantiated, args); + instantiated + } + + pub fn instantiate_own( + self, + tcx: TyCtxt<'tcx>, + args: GenericArgsRef<'tcx>, + ) -> impl Iterator, Span)> + DoubleEndedIterator + ExactSizeIterator + { + EarlyBinder::bind(self.predicates).iter_instantiated_copied(tcx, args) + } + + pub fn instantiate_own_identity(self) -> impl Iterator, Span)> { + EarlyBinder::bind(self.predicates).iter_identity_copied() + } + + #[instrument(level = "debug", skip(self, tcx))] + fn instantiate_into( + self, + tcx: TyCtxt<'tcx>, + instantiated: &mut Vec<(ty::PolyTraitRef<'tcx>, Span)>, + args: GenericArgsRef<'tcx>, + ) { + if let Some(def_id) = self.parent { + tcx.const_conditions(def_id).instantiate_into(tcx, instantiated, args); + } + instantiated.extend( + self.predicates.iter().map(|&(p, s)| (EarlyBinder::bind(p).instantiate(tcx, args), s)), + ); + } + + pub fn instantiate_identity(self, tcx: TyCtxt<'tcx>) -> Vec<(ty::PolyTraitRef<'tcx>, Span)> { + let mut instantiated = vec![]; + self.instantiate_identity_into(tcx, &mut instantiated); + instantiated + } + + fn instantiate_identity_into( + self, + tcx: TyCtxt<'tcx>, + instantiated: &mut Vec<(ty::PolyTraitRef<'tcx>, Span)>, + ) { + if let Some(def_id) = self.parent { + tcx.const_conditions(def_id).instantiate_identity_into(tcx, instantiated); + } + instantiated.extend(self.predicates.iter().copied()); + } +} diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index ed24fcc7eb88a..84e1897019e7e 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -84,12 +84,13 @@ pub use self::parameterized::ParameterizedOverTcx; pub use self::pattern::{Pattern, PatternKind}; pub use self::predicate::{ AliasTerm, Clause, ClauseKind, CoercePredicate, ExistentialPredicate, - ExistentialPredicateStableCmpExt, ExistentialProjection, ExistentialTraitRef, NormalizesTo, - OutlivesPredicate, PolyCoercePredicate, PolyExistentialPredicate, PolyExistentialProjection, - PolyExistentialTraitRef, PolyProjectionPredicate, PolyRegionOutlivesPredicate, - PolySubtypePredicate, PolyTraitPredicate, PolyTraitRef, PolyTypeOutlivesPredicate, Predicate, - PredicateKind, ProjectionPredicate, RegionOutlivesPredicate, SubtypePredicate, ToPolyTraitRef, - TraitPredicate, TraitRef, TypeOutlivesPredicate, + ExistentialPredicateStableCmpExt, ExistentialProjection, ExistentialTraitRef, + HostEffectPredicate, NormalizesTo, OutlivesPredicate, PolyCoercePredicate, + PolyExistentialPredicate, PolyExistentialProjection, PolyExistentialTraitRef, + PolyProjectionPredicate, PolyRegionOutlivesPredicate, PolySubtypePredicate, PolyTraitPredicate, + PolyTraitRef, PolyTypeOutlivesPredicate, Predicate, PredicateKind, ProjectionPredicate, + RegionOutlivesPredicate, SubtypePredicate, ToPolyTraitRef, TraitPredicate, TraitRef, + TypeOutlivesPredicate, }; pub use self::region::BoundRegionKind::*; pub use self::region::{ diff --git a/compiler/rustc_middle/src/ty/parameterized.rs b/compiler/rustc_middle/src/ty/parameterized.rs index 7e1255f606c35..43bdce5b576dd 100644 --- a/compiler/rustc_middle/src/ty/parameterized.rs +++ b/compiler/rustc_middle/src/ty/parameterized.rs @@ -132,6 +132,7 @@ parameterized_over_tcx! { ty::Ty, ty::FnSig, ty::GenericPredicates, + ty::ConstConditions, ty::TraitRef, ty::Const, ty::Predicate, diff --git a/compiler/rustc_middle/src/ty/predicate.rs b/compiler/rustc_middle/src/ty/predicate.rs index d20cb368278b3..3ecaa3e22d39c 100644 --- a/compiler/rustc_middle/src/ty/predicate.rs +++ b/compiler/rustc_middle/src/ty/predicate.rs @@ -19,6 +19,7 @@ pub type ExistentialPredicate<'tcx> = ir::ExistentialPredicate>; pub type ExistentialTraitRef<'tcx> = ir::ExistentialTraitRef>; pub type ExistentialProjection<'tcx> = ir::ExistentialProjection>; pub type TraitPredicate<'tcx> = ir::TraitPredicate>; +pub type HostEffectPredicate<'tcx> = ir::HostEffectPredicate>; pub type ClauseKind<'tcx> = ir::ClauseKind>; pub type PredicateKind<'tcx> = ir::PredicateKind>; pub type NormalizesTo<'tcx> = ir::NormalizesTo>; @@ -143,6 +144,7 @@ impl<'tcx> Predicate<'tcx> { | PredicateKind::AliasRelate(..) | PredicateKind::NormalizesTo(..) => false, PredicateKind::Clause(ClauseKind::Trait(_)) + | PredicateKind::Clause(ClauseKind::HostEffect(..)) | PredicateKind::Clause(ClauseKind::RegionOutlives(_)) | PredicateKind::Clause(ClauseKind::TypeOutlives(_)) | PredicateKind::Clause(ClauseKind::Projection(_)) @@ -644,6 +646,7 @@ impl<'tcx> Predicate<'tcx> { match predicate.skip_binder() { PredicateKind::Clause(ClauseKind::Trait(t)) => Some(predicate.rebind(t)), PredicateKind::Clause(ClauseKind::Projection(..)) + | PredicateKind::Clause(ClauseKind::HostEffect(..)) | PredicateKind::Clause(ClauseKind::ConstArgHasType(..)) | PredicateKind::NormalizesTo(..) | PredicateKind::AliasRelate(..) @@ -664,6 +667,7 @@ impl<'tcx> Predicate<'tcx> { match predicate.skip_binder() { PredicateKind::Clause(ClauseKind::Projection(t)) => Some(predicate.rebind(t)), PredicateKind::Clause(ClauseKind::Trait(..)) + | PredicateKind::Clause(ClauseKind::HostEffect(..)) | PredicateKind::Clause(ClauseKind::ConstArgHasType(..)) | PredicateKind::NormalizesTo(..) | PredicateKind::AliasRelate(..) diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 7ada5fd93ba7d..7e8414592c19e 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -3073,6 +3073,15 @@ define_print! { p!(print(self.trait_ref.print_trait_sugared())) } + ty::HostEffectPredicate<'tcx> { + let constness = match self.host { + ty::HostPolarity::Const => { "const" } + ty::HostPolarity::Maybe => { "~const" } + }; + p!(print(self.trait_ref.self_ty()), ": {constness}"); + p!(print(self.trait_ref.print_trait_sugared())) + } + ty::TypeAndMut<'tcx> { p!(write("{}", self.mutbl.prefix_str()), print(self.ty)) } @@ -3092,6 +3101,9 @@ define_print! { ty::ClauseKind::ConstEvaluatable(ct) => { p!("the constant `", print(ct), "` can be evaluated") } + ty::ClauseKind::HostEffect(predicate) => { + p!("the trait `", print(predicate.trait_ref), "` is const") + } } } diff --git a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs new file mode 100644 index 0000000000000..226a3c0cf433e --- /dev/null +++ b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs @@ -0,0 +1,295 @@ +//! Dealing with trait goals, i.e. `T: Trait<'a, U>`. + +use rustc_type_ir::fast_reject::DeepRejectCtxt; +use rustc_type_ir::inherent::*; +use rustc_type_ir::{self as ty, Interner}; +use tracing::instrument; + +use super::assembly::Candidate; +use crate::delegate::SolverDelegate; +use crate::solve::assembly::{self}; +use crate::solve::{ + BuiltinImplSource, CandidateSource, Certainty, EvalCtxt, Goal, GoalSource, NoSolution, + QueryResult, +}; + +impl assembly::GoalKind for ty::HostEffectPredicate +where + D: SolverDelegate, + I: Interner, +{ + fn self_ty(self) -> I::Ty { + self.self_ty() + } + + fn trait_ref(self, _: I) -> ty::TraitRef { + self.trait_ref + } + + fn with_self_ty(self, cx: I, self_ty: I::Ty) -> Self { + self.with_self_ty(cx, self_ty) + } + + fn trait_def_id(self, _: I) -> I::DefId { + self.def_id() + } + + fn probe_and_match_goal_against_assumption( + ecx: &mut EvalCtxt<'_, D>, + source: rustc_type_ir::solve::CandidateSource, + goal: Goal, + assumption: ::Clause, + then: impl FnOnce(&mut EvalCtxt<'_, D>) -> QueryResult, + ) -> Result, NoSolution> { + if let Some(host_clause) = assumption.as_host_effect_clause() { + if host_clause.def_id() == goal.predicate.def_id() + && host_clause.host() >= goal.predicate.host + { + if !DeepRejectCtxt::relate_rigid_rigid(ecx.cx()).args_may_unify( + goal.predicate.trait_ref.args, + host_clause.skip_binder().trait_ref.args, + ) { + return Err(NoSolution); + } + + ecx.probe_trait_candidate(source).enter(|ecx| { + let assumption_trait_pred = ecx.instantiate_binder_with_infer(host_clause); + ecx.eq( + goal.param_env, + goal.predicate.trait_ref, + assumption_trait_pred.trait_ref, + )?; + then(ecx) + }) + } else { + Err(NoSolution) + } + } else { + Err(NoSolution) + } + } + + fn consider_impl_candidate( + ecx: &mut EvalCtxt<'_, D>, + goal: Goal, + impl_def_id: ::DefId, + ) -> Result, NoSolution> { + let cx = ecx.cx(); + + let impl_trait_ref = cx.impl_trait_ref(impl_def_id); + if !DeepRejectCtxt::relate_rigid_infer(ecx.cx()) + .args_may_unify(goal.predicate.trait_ref.args, impl_trait_ref.skip_binder().args) + { + return Err(NoSolution); + } + + let impl_polarity = cx.impl_polarity(impl_def_id); + match impl_polarity { + ty::ImplPolarity::Negative => return Err(NoSolution), + ty::ImplPolarity::Reservation => { + unimplemented!("reservation impl for trait with assoc item: {:?}", goal) + } + ty::ImplPolarity::Positive => {} + }; + + if !cx.is_const_impl(impl_def_id) { + return Err(NoSolution); + } + + ecx.probe_trait_candidate(CandidateSource::Impl(impl_def_id)).enter(|ecx| { + let impl_args = ecx.fresh_args_for_item(impl_def_id); + ecx.record_impl_args(impl_args); + let impl_trait_ref = impl_trait_ref.instantiate(cx, impl_args); + + ecx.eq(goal.param_env, goal.predicate.trait_ref, impl_trait_ref)?; + let where_clause_bounds = cx + .predicates_of(impl_def_id) + .iter_instantiated(cx, impl_args) + .map(|pred| goal.with(cx, pred)); + ecx.add_goals(GoalSource::ImplWhereBound, where_clause_bounds); + + // For this impl to be `const`, we need to check its `~const` bounds too. + let const_conditions = cx + .const_conditions(impl_def_id) + .iter_instantiated(cx, impl_args) + .map(|bound_trait_ref| { + goal.with(cx, bound_trait_ref.to_host_effect(cx, goal.predicate.host)) + }); + ecx.add_goals(GoalSource::ImplWhereBound, const_conditions); + + ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + }) + } + + fn consider_error_guaranteed_candidate( + ecx: &mut EvalCtxt<'_, D>, + _guar: ::ErrorGuaranteed, + ) -> Result, NoSolution> { + ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc) + .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)) + } + + fn consider_auto_trait_candidate( + _ecx: &mut EvalCtxt<'_, D>, + _goal: Goal, + ) -> Result, NoSolution> { + unreachable!("auto traits are never const") + } + + fn consider_trait_alias_candidate( + _ecx: &mut EvalCtxt<'_, D>, + _goal: Goal, + ) -> Result, NoSolution> { + unreachable!("trait aliases are never const") + } + + fn consider_builtin_sized_candidate( + _ecx: &mut EvalCtxt<'_, D>, + _goal: Goal, + ) -> Result, NoSolution> { + unreachable!("Sized is never const") + } + + fn consider_builtin_copy_clone_candidate( + _ecx: &mut EvalCtxt<'_, D>, + _goal: Goal, + ) -> Result, NoSolution> { + todo!("Copy/Clone is not yet const") + } + + fn consider_builtin_pointer_like_candidate( + _ecx: &mut EvalCtxt<'_, D>, + _goal: Goal, + ) -> Result, NoSolution> { + unreachable!("PointerLike is not const") + } + + fn consider_builtin_fn_ptr_trait_candidate( + _ecx: &mut EvalCtxt<'_, D>, + _goal: Goal, + ) -> Result, NoSolution> { + todo!("Fn* are not yet const") + } + + fn consider_builtin_fn_trait_candidates( + _ecx: &mut EvalCtxt<'_, D>, + _goal: Goal, + _kind: rustc_type_ir::ClosureKind, + ) -> Result, NoSolution> { + todo!("Fn* are not yet const") + } + + fn consider_builtin_async_fn_trait_candidates( + _ecx: &mut EvalCtxt<'_, D>, + _goal: Goal, + _kind: rustc_type_ir::ClosureKind, + ) -> Result, NoSolution> { + todo!("AsyncFn* are not yet const") + } + + fn consider_builtin_async_fn_kind_helper_candidate( + _ecx: &mut EvalCtxt<'_, D>, + _goal: Goal, + ) -> Result, NoSolution> { + unreachable!("AsyncFnKindHelper is not const") + } + + fn consider_builtin_tuple_candidate( + _ecx: &mut EvalCtxt<'_, D>, + _goal: Goal, + ) -> Result, NoSolution> { + unreachable!("Tuple trait is not const") + } + + fn consider_builtin_pointee_candidate( + _ecx: &mut EvalCtxt<'_, D>, + _goal: Goal, + ) -> Result, NoSolution> { + unreachable!("Pointee is not const") + } + + fn consider_builtin_future_candidate( + _ecx: &mut EvalCtxt<'_, D>, + _goal: Goal, + ) -> Result, NoSolution> { + unreachable!("Future is not const") + } + + fn consider_builtin_iterator_candidate( + _ecx: &mut EvalCtxt<'_, D>, + _goal: Goal, + ) -> Result, NoSolution> { + todo!("Iterator is not yet const") + } + + fn consider_builtin_fused_iterator_candidate( + _ecx: &mut EvalCtxt<'_, D>, + _goal: Goal, + ) -> Result, NoSolution> { + unreachable!("FusedIterator is not const") + } + + fn consider_builtin_async_iterator_candidate( + _ecx: &mut EvalCtxt<'_, D>, + _goal: Goal, + ) -> Result, NoSolution> { + unreachable!("AsyncIterator is not const") + } + + fn consider_builtin_coroutine_candidate( + _ecx: &mut EvalCtxt<'_, D>, + _goal: Goal, + ) -> Result, NoSolution> { + unreachable!("Coroutine is not const") + } + + fn consider_builtin_discriminant_kind_candidate( + _ecx: &mut EvalCtxt<'_, D>, + _goal: Goal, + ) -> Result, NoSolution> { + unreachable!("DiscriminantKind is not const") + } + + fn consider_builtin_async_destruct_candidate( + _ecx: &mut EvalCtxt<'_, D>, + _goal: Goal, + ) -> Result, NoSolution> { + unreachable!("AsyncDestruct is not const") + } + + fn consider_builtin_destruct_candidate( + _ecx: &mut EvalCtxt<'_, D>, + _goal: Goal, + ) -> Result, NoSolution> { + unreachable!("Destruct is not const") + } + + fn consider_builtin_transmute_candidate( + _ecx: &mut EvalCtxt<'_, D>, + _goal: Goal, + ) -> Result, NoSolution> { + unreachable!("TransmuteFrom is not const") + } + + fn consider_structural_builtin_unsize_candidates( + _ecx: &mut EvalCtxt<'_, D>, + _goal: Goal, + ) -> Vec> { + unreachable!("Unsize is not const") + } +} + +impl EvalCtxt<'_, D> +where + D: SolverDelegate, + I: Interner, +{ + #[instrument(level = "trace", skip(self))] + pub(super) fn compute_host_effect_goal( + &mut self, + goal: Goal>, + ) -> QueryResult { + let candidates = self.assemble_and_evaluate_candidates(goal); + self.merge_candidates(candidates) + } +} diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs index cbefc826fb7d8..1d30b2eb3f53e 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs @@ -443,6 +443,9 @@ where ty::PredicateKind::Clause(ty::ClauseKind::Trait(predicate)) => { self.compute_trait_goal(Goal { param_env, predicate }) } + ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(predicate)) => { + self.compute_host_effect_goal(Goal { param_env, predicate }) + } ty::PredicateKind::Clause(ty::ClauseKind::Projection(predicate)) => { self.compute_projection_goal(Goal { param_env, predicate }) } diff --git a/compiler/rustc_next_trait_solver/src/solve/mod.rs b/compiler/rustc_next_trait_solver/src/solve/mod.rs index 5a799ff8e749e..bc65e5b264acd 100644 --- a/compiler/rustc_next_trait_solver/src/solve/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/mod.rs @@ -13,6 +13,7 @@ mod alias_relate; mod assembly; +mod effect_goals; mod eval_ctxt; pub mod inspect; mod normalizes_to; diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index f67c4cb922cee..f427928fdb3fc 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -137,6 +137,10 @@ where ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref, polarity: _ }) => { self.visit_trait(trait_ref) } + ty::ClauseKind::HostEffect(pred) => { + try_visit!(self.visit_trait(pred.trait_ref)); + pred.host.visit_with(self) + } ty::ClauseKind::Projection(ty::ProjectionPredicate { projection_term: projection_ty, term, diff --git a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs index 134d444a9ae30..b6352fd390a59 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs @@ -689,6 +689,9 @@ impl<'tcx> Stable<'tcx> for ty::ClauseKind<'tcx> { ClauseKind::ConstEvaluatable(const_) => { stable_mir::ty::ClauseKind::ConstEvaluatable(const_.stable(tables)) } + ClauseKind::HostEffect(..) => { + todo!() + } } } } diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index 9538f6e07ad17..ef58fc6930531 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -541,6 +541,29 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { err } + ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(predicate)) => { + // FIXME(effects): We should recompute the predicate with `~const` + // if it's `const`, and if it holds, explain that this bound only + // *conditionally* holds. If that fails, we should also do selection + // to drill this down to an impl or built-in source, so we can + // point at it and explain that while the trait *is* implemented, + // that implementation is not const. + let err_msg = self.get_standard_error_message( + bound_predicate.rebind(ty::TraitPredicate { + trait_ref: predicate.trait_ref, + polarity: ty::PredicatePolarity::Positive, + }), + None, + match predicate.host { + ty::HostPolarity::Maybe => ty::BoundConstness::ConstIfConst, + ty::HostPolarity::Const => ty::BoundConstness::Const, + }, + None, + String::new(), + ); + struct_span_code_err!(self.dcx(), span, E0277, "{}", err_msg) + } + ty::PredicateKind::Subtype(predicate) => { // Errors for Subtype predicates show up as // `FulfillmentErrorCode::SubtypeError`, diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index 12aeee0d02fe7..934fe9ec47c0e 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -806,7 +806,8 @@ impl<'tcx> AutoTraitFinder<'tcx> { | ty::PredicateKind::Subtype(..) // FIXME(generic_const_exprs): you can absolutely add this as a where clauses | ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..)) - | ty::PredicateKind::Coerce(..) => {} + | ty::PredicateKind::Coerce(..) + | ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(..)) => {} ty::PredicateKind::Ambiguous => return false, }; } diff --git a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs index 364a13b3a7599..7a1a3116b3821 100644 --- a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs +++ b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs @@ -245,6 +245,7 @@ fn predicate_references_self<'tcx>( | ty::ClauseKind::RegionOutlives(..) // FIXME(generic_const_exprs): this can mention `Self` | ty::ClauseKind::ConstEvaluatable(..) + | ty::ClauseKind::HostEffect(..) => None, } } @@ -284,7 +285,8 @@ fn generics_require_sized_self(tcx: TyCtxt<'_>, def_id: DefId) -> bool { | ty::ClauseKind::Projection(_) | ty::ClauseKind::ConstArgHasType(_, _) | ty::ClauseKind::WellFormed(_) - | ty::ClauseKind::ConstEvaluatable(_) => false, + | ty::ClauseKind::ConstEvaluatable(_) + | ty::ClauseKind::HostEffect(..) => false, }) } diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index b6c9549428335..5a3eb1d3f1c6b 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -372,7 +372,11 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { | ty::PredicateKind::Subtype(_) | ty::PredicateKind::Coerce(_) | ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..)) - | ty::PredicateKind::ConstEquate(..) => { + | ty::PredicateKind::ConstEquate(..) + // FIXME(effects): We may need to do this using the higher-ranked + // pred instead of just instantiating it with placeholders b/c of + // higher-ranked implied bound issues in the old solver. + | ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(..)) => { let pred = ty::Binder::dummy(infcx.enter_forall_and_leak_universe(binder)); let mut obligations = PredicateObligations::with_capacity(1); obligations.push(obligation.with(infcx.tcx, pred)); @@ -398,6 +402,10 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { ) } + ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(..)) => { + ProcessResult::Changed(Default::default()) + } + ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(data)) => { if infcx.considering_regions { infcx.region_outlives_predicate(&obligation.cause, Binder::dummy(data)); diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs index dfd0cab69058b..c6e41e57f0cec 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs @@ -96,6 +96,7 @@ pub fn compute_implied_outlives_bounds_inner<'tcx>( // FIXME(const_generics): Make sure that `<'a, 'b, const N: &'a &'b u32>` is sound // if we ever support that ty::PredicateKind::Clause(ty::ClauseKind::Trait(..)) + | ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(..)) | ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..)) | ty::PredicateKind::Subtype(..) | ty::PredicateKind::Coerce(..) @@ -200,6 +201,7 @@ pub fn compute_implied_outlives_bounds_compat_inner<'tcx>( // FIXME(const_generics): Make sure that `<'a, 'b, const N: &'a &'b u32>` is sound // if we ever support that ty::PredicateKind::Clause(ty::ClauseKind::Trait(..)) + | ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(..)) | ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..)) | ty::PredicateKind::Subtype(..) | ty::PredicateKind::Coerce(..) diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index a7bb9829f8c76..719ce4aa20897 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -645,6 +645,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { self.evaluate_trait_predicate_recursively(previous_stack, obligation) } + ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(..)) => { + // FIXME(effects): It should be relatively straightforward to implement + // old trait solver support for `HostEffect` bounds; or at least basic + // support for them. + todo!() + } + ty::PredicateKind::Subtype(p) => { let p = bound_predicate.rebind(p); // Does this code ever run? diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 07e68e5a3e81b..cfd6c8aacae2d 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -170,6 +170,10 @@ pub fn clause_obligations<'tcx>( ty::ClauseKind::Trait(t) => { wf.compute_trait_pred(t, Elaborate::None); } + ty::ClauseKind::HostEffect(..) => { + // Technically the well-formedness of this predicate is implied by + // the corresponding trait predicate it should've been generated beside. + } ty::ClauseKind::RegionOutlives(..) => {} ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(ty, _reg)) => { wf.compute(ty.into()); @@ -1021,6 +1025,7 @@ pub(crate) fn required_region_bounds<'tcx>( } } ty::ClauseKind::Trait(_) + | ty::ClauseKind::HostEffect(..) | ty::ClauseKind::RegionOutlives(_) | ty::ClauseKind::Projection(_) | ty::ClauseKind::ConstArgHasType(_, _) diff --git a/compiler/rustc_traits/src/normalize_erasing_regions.rs b/compiler/rustc_traits/src/normalize_erasing_regions.rs index f01a12b0a00c9..3e2794f6489f8 100644 --- a/compiler/rustc_traits/src/normalize_erasing_regions.rs +++ b/compiler/rustc_traits/src/normalize_erasing_regions.rs @@ -55,6 +55,7 @@ fn not_outlives_predicate(p: ty::Predicate<'_>) -> bool { | ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(..)) => false, ty::PredicateKind::Clause(ty::ClauseKind::Trait(..)) | ty::PredicateKind::Clause(ty::ClauseKind::Projection(..)) + | ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(..)) | ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..)) | ty::PredicateKind::NormalizesTo(..) | ty::PredicateKind::AliasRelate(..) diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 28a81b1b06217..1e1b77e39e24a 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -150,6 +150,13 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> { }); } + predicates.extend( + tcx.const_conditions(def_id) + .instantiate_identity(tcx) + .into_iter() + .map(|(trait_ref, _)| trait_ref.to_host_effect(tcx, ty::HostPolarity::Maybe)), + ); + let local_did = def_id.as_local(); let unnormalized_env = diff --git a/compiler/rustc_type_ir/src/elaborate.rs b/compiler/rustc_type_ir/src/elaborate.rs index 56a72f943ab4e..227a5d66124bb 100644 --- a/compiler/rustc_type_ir/src/elaborate.rs +++ b/compiler/rustc_type_ir/src/elaborate.rs @@ -155,6 +155,16 @@ impl> Elaborator { ), }; } + // `T: ~const Trait` implies `T: ~const Supertrait`. + ty::ClauseKind::HostEffect(data) => self.extend_deduped( + cx.implied_const_bounds(data.def_id()).iter_identity().map(|trait_ref| { + elaboratable.child( + trait_ref + .to_host_effect(cx, data.host) + .instantiate_supertrait(cx, bound_clause.rebind(data.trait_ref)), + ) + }), + ), ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(ty_max, r_min)) => { // We know that `T: 'a` for some type `T`. We can // often elaborate this. For example, if we know that diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs index f7875bb515270..d5d911ccc743f 100644 --- a/compiler/rustc_type_ir/src/inherent.rs +++ b/compiler/rustc_type_ir/src/inherent.rs @@ -468,6 +468,14 @@ pub trait Clause>: .transpose() } + fn as_host_effect_clause(self) -> Option>> { + self.kind() + .map_bound( + |clause| if let ty::ClauseKind::HostEffect(t) = clause { Some(t) } else { None }, + ) + .transpose() + } + fn as_projection_clause(self) -> Option>> { self.kind() .map_bound( diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index f06017d7e5c35..b6715e333a4bb 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -26,6 +26,7 @@ pub trait Interner: + IrPrint> + IrPrint> + IrPrint> + + IrPrint> + IrPrint> + IrPrint> + IrPrint> @@ -226,6 +227,16 @@ pub trait Interner: def_id: Self::DefId, ) -> ty::EarlyBinder>; + fn is_const_impl(self, def_id: Self::DefId) -> bool; + fn const_conditions( + self, + def_id: Self::DefId, + ) -> ty::EarlyBinder>>>; + fn implied_const_bounds( + self, + def_id: Self::DefId, + ) -> ty::EarlyBinder>>>; + fn has_target_features(self, def_id: Self::DefId) -> bool; fn require_lang_item(self, lang_item: TraitSolverLangItem) -> Self::DefId; diff --git a/compiler/rustc_type_ir/src/ir_print.rs b/compiler/rustc_type_ir/src/ir_print.rs index d57d0816680bf..0c71f3a3df2a2 100644 --- a/compiler/rustc_type_ir/src/ir_print.rs +++ b/compiler/rustc_type_ir/src/ir_print.rs @@ -2,8 +2,8 @@ use std::fmt; use crate::{ AliasTerm, AliasTy, Binder, CoercePredicate, ExistentialProjection, ExistentialTraitRef, FnSig, - Interner, NormalizesTo, OutlivesPredicate, ProjectionPredicate, SubtypePredicate, - TraitPredicate, TraitRef, + HostEffectPredicate, Interner, NormalizesTo, OutlivesPredicate, ProjectionPredicate, + SubtypePredicate, TraitPredicate, TraitRef, }; pub trait IrPrint { @@ -53,6 +53,7 @@ define_display_via_print!( NormalizesTo, SubtypePredicate, CoercePredicate, + HostEffectPredicate, AliasTy, AliasTerm, FnSig, diff --git a/compiler/rustc_type_ir/src/predicate.rs b/compiler/rustc_type_ir/src/predicate.rs index 8146181df6c17..24d8ce1f0c053 100644 --- a/compiler/rustc_type_ir/src/predicate.rs +++ b/compiler/rustc_type_ir/src/predicate.rs @@ -111,6 +111,13 @@ impl ty::Binder> { pub fn def_id(&self) -> I::DefId { self.skip_binder().def_id } + + pub fn to_host_effect(self, cx: I, host: HostPolarity) -> I::Clause { + self.map_bound(|trait_ref| { + ty::ClauseKind::HostEffect(HostEffectPredicate { trait_ref, host }) + }) + .upcast(cx) + } } #[derive_where(Clone, Copy, Hash, PartialEq, Eq; I: Interner)] @@ -702,6 +709,54 @@ impl fmt::Debug for NormalizesTo { } } +#[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)] +#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))] +pub struct HostEffectPredicate { + pub trait_ref: ty::TraitRef, + pub host: HostPolarity, +} + +impl HostEffectPredicate { + pub fn self_ty(self) -> I::Ty { + self.trait_ref.self_ty() + } + + pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> Self { + Self { trait_ref: self.trait_ref.with_self_ty(interner, self_ty), ..self } + } + + pub fn def_id(self) -> I::DefId { + self.trait_ref.def_id + } +} + +impl ty::Binder> { + pub fn def_id(self) -> I::DefId { + // Ok to skip binder since trait `DefId` does not care about regions. + self.skip_binder().def_id() + } + + pub fn self_ty(self) -> ty::Binder { + self.map_bound(|trait_ref| trait_ref.self_ty()) + } + + #[inline] + pub fn host(self) -> HostPolarity { + self.skip_binder().host + } +} + +#[derive(Clone, Copy, Hash, PartialEq, Eq, Debug, PartialOrd, Ord)] +#[derive(TypeVisitable_Generic, TypeFoldable_Generic)] +#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))] +pub enum HostPolarity { + /// May be called in const environments if the callee is const. + Maybe, + /// Always allowed to be called in const environments. + Const, +} + /// Encodes that `a` must be a subtype of `b`. The `a_is_expected` flag indicates /// whether the `a` type is the type that we should label as "expected" when /// presenting user diagnostics. diff --git a/compiler/rustc_type_ir/src/predicate_kind.rs b/compiler/rustc_type_ir/src/predicate_kind.rs index 46202dbb0f276..39e012022dc9e 100644 --- a/compiler/rustc_type_ir/src/predicate_kind.rs +++ b/compiler/rustc_type_ir/src/predicate_kind.rs @@ -37,6 +37,9 @@ pub enum ClauseKind { /// Constant initializer must evaluate successfully. ConstEvaluatable(I::Const), + + /// Whether `T: Trait`'s host effect is `true`/`false`. + HostEffect(ty::HostEffectPredicate), } #[derive_where(Clone, Copy, Hash, PartialEq, Eq; I: Interner)] @@ -110,6 +113,7 @@ impl fmt::Debug for ClauseKind { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { ClauseKind::ConstArgHasType(ct, ty) => write!(f, "ConstArgHasType({ct:?}, {ty:?})"), + ClauseKind::HostEffect(data) => data.fmt(f), ClauseKind::Trait(a) => a.fmt(f), ClauseKind::RegionOutlives(pair) => pair.fmt(f), ClauseKind::TypeOutlives(pair) => pair.fmt(f), diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 5867c78cc4a1f..a3fd82b1086e4 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -368,7 +368,9 @@ pub(crate) fn clean_predicate<'tcx>( // FIXME(generic_const_exprs): should this do something? ty::ClauseKind::ConstEvaluatable(..) | ty::ClauseKind::WellFormed(..) - | ty::ClauseKind::ConstArgHasType(..) => None, + | ty::ClauseKind::ConstArgHasType(..) + // FIXME(effects): We can probably use this `HostEffect` pred to render `~const`. + | ty::ClauseKind::HostEffect(_) => None, } } diff --git a/tests/ui/const-generics/issues/issue-88119.stderr b/tests/ui/const-generics/issues/issue-88119.stderr index 98bb81968100b..a0ca33e38ef83 100644 --- a/tests/ui/const-generics/issues/issue-88119.stderr +++ b/tests/ui/const-generics/issues/issue-88119.stderr @@ -11,30 +11,12 @@ error[E0284]: type annotations needed: cannot normalize `<&T as ConstName>::{con | LL | impl const ConstName for &T | ^^ cannot normalize `<&T as ConstName>::{constant#0}` - | -note: required for `&T` to implement `ConstName` - --> $DIR/issue-88119.rs:19:35 - | -LL | impl const ConstName for &T - | ^^^^^^^^^ ^^ -LL | where -LL | [(); name_len::()]:, - | --------------------- unsatisfied trait bound introduced here error[E0284]: type annotations needed: cannot normalize `<&mut T as ConstName>::{constant#0}` --> $DIR/issue-88119.rs:26:49 | LL | impl const ConstName for &mut T | ^^^^^^ cannot normalize `<&mut T as ConstName>::{constant#0}` - | -note: required for `&mut T` to implement `ConstName` - --> $DIR/issue-88119.rs:26:35 - | -LL | impl const ConstName for &mut T - | ^^^^^^^^^ ^^^^^^ -LL | where -LL | [(); name_len::()]:, - | --------------------- unsatisfied trait bound introduced here error: aborting due to 3 previous errors diff --git a/tests/ui/consts/const-block-const-bound.stderr b/tests/ui/consts/const-block-const-bound.stderr index 42a42ae3938b7..8cb91d78f6cac 100644 --- a/tests/ui/consts/const-block-const-bound.stderr +++ b/tests/ui/consts/const-block-const-bound.stderr @@ -4,6 +4,14 @@ error: `~const` can only be applied to `#[const_trait]` traits LL | const fn f(x: T) {} | ^^^^^^^^ +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/const-block-const-bound.rs:8:22 + | +LL | const fn f(x: T) {} + | ^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + error[E0493]: destructor of `T` cannot be evaluated at compile-time --> $DIR/const-block-const-bound.rs:8:32 | @@ -12,6 +20,6 @@ LL | const fn f(x: T) {} | | | the destructor for this type cannot be evaluated in constant functions -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0493`. diff --git a/tests/ui/consts/constifconst-call-in-const-position.stderr b/tests/ui/consts/constifconst-call-in-const-position.stderr index 7de10f0287b4b..2195cab3f4d03 100644 --- a/tests/ui/consts/constifconst-call-in-const-position.stderr +++ b/tests/ui/consts/constifconst-call-in-const-position.stderr @@ -3,24 +3,12 @@ error: using `#![feature(effects)]` without enabling next trait solver globally = note: the next trait solver must be enabled globally for the effects feature to work correctly = help: use `-Znext-solver` to enable -error[E0308]: mismatched types +error[E0080]: evaluation of `foo::<()>::{constant#0}` failed --> $DIR/constifconst-call-in-const-position.rs:17:38 | LL | const fn foo() -> [u8; T::a()] { - | ^^^^^^ expected `false`, found `host` - | - = note: expected constant `false` - found constant `host` - -error[E0308]: mismatched types - --> $DIR/constifconst-call-in-const-position.rs:18:9 - | -LL | [0; T::a()] - | ^^^^^^ expected `false`, found `host` - | - = note: expected constant `false` - found constant `host` + | ^^^^^^ calling non-const function `<() as Tr>::a` -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0308`. +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/fn_trait_refs.stderr b/tests/ui/consts/fn_trait_refs.stderr index 218c90f89a9e2..2b012432afd41 100644 --- a/tests/ui/consts/fn_trait_refs.stderr +++ b/tests/ui/consts/fn_trait_refs.stderr @@ -30,6 +30,22 @@ LL | T: ~const Fn<()> + ~const Destruct, | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/fn_trait_refs.rs:13:15 + | +LL | T: ~const Fn<()> + ~const Destruct, + | ^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/fn_trait_refs.rs:13:31 + | +LL | T: ~const Fn<()> + ~const Destruct, + | ^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/fn_trait_refs.rs:20:15 | @@ -50,11 +66,35 @@ LL | T: ~const FnMut<()> + ~const Destruct, | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/fn_trait_refs.rs:20:15 + | +LL | T: ~const FnMut<()> + ~const Destruct, + | ^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/fn_trait_refs.rs:20:34 + | +LL | T: ~const FnMut<()> + ~const Destruct, + | ^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/fn_trait_refs.rs:27:15 + | +LL | T: ~const FnOnce<()>, + | ^^^^^^^^^^ + error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/fn_trait_refs.rs:27:15 | LL | T: ~const FnOnce<()>, | ^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/fn_trait_refs.rs:27:15 @@ -84,6 +124,22 @@ LL | T: ~const Fn<()> + ~const Destruct, | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/fn_trait_refs.rs:34:15 + | +LL | T: ~const Fn<()> + ~const Destruct, + | ^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/fn_trait_refs.rs:34:31 + | +LL | T: ~const Fn<()> + ~const Destruct, + | ^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/fn_trait_refs.rs:48:15 | @@ -104,6 +160,22 @@ LL | T: ~const FnMut<()> + ~const Destruct, | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/fn_trait_refs.rs:48:15 + | +LL | T: ~const FnMut<()> + ~const Destruct, + | ^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/fn_trait_refs.rs:48:34 + | +LL | T: ~const FnMut<()> + ~const Destruct, + | ^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + error[E0015]: cannot call non-const operator in constants --> $DIR/fn_trait_refs.rs:70:17 | @@ -212,7 +284,7 @@ LL | const fn test_fn_mut(mut f: T) -> (T::Output, T::Output) LL | } | - value is dropped here -error: aborting due to 25 previous errors +error: aborting due to 34 previous errors Some errors have detailed explanations: E0015, E0493, E0635. For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/consts/unstable-const-fn-in-libcore.stderr b/tests/ui/consts/unstable-const-fn-in-libcore.stderr index 6c83eff4de013..59476f9860321 100644 --- a/tests/ui/consts/unstable-const-fn-in-libcore.stderr +++ b/tests/ui/consts/unstable-const-fn-in-libcore.stderr @@ -4,6 +4,14 @@ error: `~const` can only be applied to `#[const_trait]` traits LL | const fn unwrap_or_else T>(self, f: F) -> T { | ^^^^^^^^^^^^^ +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/unstable-const-fn-in-libcore.rs:19:39 + | +LL | const fn unwrap_or_else T>(self, f: F) -> T { + | ^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + error[E0015]: cannot call non-const closure in constant functions --> $DIR/unstable-const-fn-in-libcore.rs:24:26 | @@ -38,7 +46,7 @@ LL | const fn unwrap_or_else T>(self, f: F) -> T { LL | } | - value is dropped here -error: aborting due to 4 previous errors +error: aborting due to 5 previous errors Some errors have detailed explanations: E0015, E0493. For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/delegation/ice-issue-124347.rs b/tests/ui/delegation/ice-issue-124347.rs index ee2bf9e33eb89..b2b3c61a722b3 100644 --- a/tests/ui/delegation/ice-issue-124347.rs +++ b/tests/ui/delegation/ice-issue-124347.rs @@ -4,7 +4,7 @@ // FIXME(fn_delegation): `recursive delegation` error should be emitted here trait Trait { reuse Trait::foo { &self.0 } - //~^ ERROR cycle detected when computing generics of `Trait::foo` + //~^ ERROR recursive delegation is not supported yet } reuse foo; diff --git a/tests/ui/delegation/ice-issue-124347.stderr b/tests/ui/delegation/ice-issue-124347.stderr index bd0bc970b94c2..74c4b5cd949a3 100644 --- a/tests/ui/delegation/ice-issue-124347.stderr +++ b/tests/ui/delegation/ice-issue-124347.stderr @@ -1,16 +1,8 @@ -error[E0391]: cycle detected when computing generics of `Trait::foo` +error: recursive delegation is not supported yet --> $DIR/ice-issue-124347.rs:6:18 | LL | reuse Trait::foo { &self.0 } - | ^^^ - | - = note: ...which immediately requires computing generics of `Trait::foo` again -note: cycle used when inheriting delegation signature - --> $DIR/ice-issue-124347.rs:6:18 - | -LL | reuse Trait::foo { &self.0 } - | ^^^ - = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information + | ^^^ callee defined here error[E0391]: cycle detected when computing generics of `foo` --> $DIR/ice-issue-124347.rs:10:7 diff --git a/tests/ui/delegation/unsupported.rs b/tests/ui/delegation/unsupported.rs index e57effff48d81..56296db85a3fa 100644 --- a/tests/ui/delegation/unsupported.rs +++ b/tests/ui/delegation/unsupported.rs @@ -51,7 +51,7 @@ mod effects { } reuse Trait::foo; - //~^ ERROR delegation to a function with effect parameter is not supported yet + //~^ ERROR type annotations needed } fn main() {} diff --git a/tests/ui/delegation/unsupported.stderr b/tests/ui/delegation/unsupported.stderr index 6a627be3b64e7..1c79a603503f6 100644 --- a/tests/ui/delegation/unsupported.stderr +++ b/tests/ui/delegation/unsupported.stderr @@ -81,15 +81,15 @@ LL | pub reuse to_reuse2::foo; LL | reuse to_reuse1::foo; | ^^^ -error: delegation to a function with effect parameter is not supported yet +error[E0283]: type annotations needed --> $DIR/unsupported.rs:53:18 | -LL | fn foo(); - | --------- callee defined here -... LL | reuse Trait::foo; - | ^^^ + | ^^^ cannot infer type + | + = note: cannot satisfy `_: effects::Trait` error: aborting due to 5 previous errors; 2 warnings emitted -For more information about this error, try `rustc --explain E0391`. +Some errors have detailed explanations: E0283, E0391. +For more information about an error, try `rustc --explain E0283`. diff --git a/tests/ui/impl-trait/normalize-tait-in-const.stderr b/tests/ui/impl-trait/normalize-tait-in-const.stderr index e0d193b5d4027..f1e6207ed817d 100644 --- a/tests/ui/impl-trait/normalize-tait-in-const.stderr +++ b/tests/ui/impl-trait/normalize-tait-in-const.stderr @@ -10,6 +10,22 @@ error: `~const` can only be applied to `#[const_trait]` traits LL | const fn with_positive ~const Fn(&'a Alias<'a>) + ~const Destruct>(fun: F) { | ^^^^^^^^ +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/normalize-tait-in-const.rs:26:42 + | +LL | const fn with_positive ~const Fn(&'a Alias<'a>) + ~const Destruct>(fun: F) { + | ^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/normalize-tait-in-const.rs:26:69 + | +LL | const fn with_positive ~const Fn(&'a Alias<'a>) + ~const Destruct>(fun: F) { + | ^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + error[E0015]: cannot call non-const closure in constant functions --> $DIR/normalize-tait-in-const.rs:27:5 | @@ -35,7 +51,7 @@ LL | fun(filter_positive()); LL | } | - value is dropped here -error: aborting due to 4 previous errors +error: aborting due to 6 previous errors Some errors have detailed explanations: E0015, E0493. For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.stderr index 8288c660ce7c8..20448f51de22c 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.stderr @@ -3,44 +3,5 @@ error: using `#![feature(effects)]` without enabling next trait solver globally = note: the next trait solver must be enabled globally for the effects feature to work correctly = help: use `-Znext-solver` to enable -error[E0277]: the trait bound `::Assoc: Trait` is not satisfied - --> $DIR/assoc-type-const-bound-usage-0.rs:13:5 - | -LL | T::Assoc::func() - | ^^^^^^^^ the trait `Trait` is not implemented for `::Assoc` - | -note: required by a bound in `Trait::func` - --> $DIR/assoc-type-const-bound-usage-0.rs:6:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ required by this bound in `Trait::func` -... -LL | fn func() -> i32; - | ---- required by a bound in this associated function -help: consider further restricting the associated type - | -LL | const fn unqualified() -> i32 where ::Assoc: Trait { - | ++++++++++++++++++++++++++++++++ - -error[E0277]: the trait bound `::Assoc: Trait` is not satisfied - --> $DIR/assoc-type-const-bound-usage-0.rs:17:5 - | -LL | ::Assoc::func() - | ^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `::Assoc` - | -note: required by a bound in `Trait::func` - --> $DIR/assoc-type-const-bound-usage-0.rs:6:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ required by this bound in `Trait::func` -... -LL | fn func() -> i32; - | ---- required by a bound in this associated function -help: consider further restricting the associated type - | -LL | const fn qualified() -> i32 where ::Assoc: Trait { - | ++++++++++++++++++++++++++++++++ - -error: aborting due to 3 previous errors +error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.stderr index 0792d090321d3..20448f51de22c 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.stderr @@ -3,44 +3,5 @@ error: using `#![feature(effects)]` without enabling next trait solver globally = note: the next trait solver must be enabled globally for the effects feature to work correctly = help: use `-Znext-solver` to enable -error[E0277]: the trait bound `::Assoc: Trait` is not satisfied - --> $DIR/assoc-type-const-bound-usage-1.rs:15:44 - | -LL | fn unqualified() -> Type<{ T::Assoc::func() }> { - | ^^^^^^^^ the trait `Trait` is not implemented for `::Assoc` - | -note: required by a bound in `Trait::func` - --> $DIR/assoc-type-const-bound-usage-1.rs:7:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ required by this bound in `Trait::func` -... -LL | fn func() -> i32; - | ---- required by a bound in this associated function -help: consider further restricting the associated type - | -LL | fn unqualified() -> Type<{ T::Assoc::func() }> where ::Assoc: Trait { - | ++++++++++++++++++++++++++++++++ - -error[E0277]: the trait bound `::Assoc: Trait` is not satisfied - --> $DIR/assoc-type-const-bound-usage-1.rs:19:42 - | -LL | fn qualified() -> Type<{ ::Assoc::func() }> { - | ^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `::Assoc` - | -note: required by a bound in `Trait::func` - --> $DIR/assoc-type-const-bound-usage-1.rs:7:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ required by this bound in `Trait::func` -... -LL | fn func() -> i32; - | ---- required by a bound in this associated function -help: consider further restricting the associated type - | -LL | fn qualified() -> Type<{ ::Assoc::func() }> where ::Assoc: Trait { - | ++++++++++++++++++++++++++++++++ - -error: aborting due to 3 previous errors +error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr index 5d2333d94fe89..40a06af85edca 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr @@ -2,20 +2,7 @@ error[E0277]: the trait bound `u32: ~const Plus` is not satisfied --> $DIR/call-const-trait-method-fail.rs:27:5 | LL | a.plus(b) - | ^ the trait `Plus` is not implemented for `u32` - | -note: required by a bound in `Plus::plus` - --> $DIR/call-const-trait-method-fail.rs:5:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ required by this bound in `Plus::plus` -LL | pub trait Plus { -LL | fn plus(self, rhs: Self) -> Self; - | ---- required by a bound in this associated function -help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement - | -LL | pub const fn add_u32(a: u32, b: u32) -> u32 where u32: Plus { - | +++++++++++++++ + | ^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-pass.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-pass.stderr index bf455a714a343..c1cead542163e 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-pass.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-pass.stderr @@ -16,15 +16,6 @@ LL | impl const PartialEq for Int { = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` = note: adding a non-const method body in the future would be a breaking change -error[E0049]: method `plus` has 1 const parameter but its trait declaration has 0 const parameters - --> $DIR/call-const-trait-method-pass.rs:24:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | pub trait Plus { -LL | fn plus(self, rhs: Self) -> Self; - | - expected 0 const parameters - error[E0015]: cannot call non-const operator in constants --> $DIR/call-const-trait-method-pass.rs:39:22 | @@ -73,7 +64,6 @@ help: add `#![feature(effects)]` to the crate attributes to enable LL + #![feature(effects)] | -error: aborting due to 7 previous errors +error: aborting due to 6 previous errors -Some errors have detailed explanations: E0015, E0049. -For more information about an error, try `rustc --explain E0015`. +For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-in-impl.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-in-impl.stderr index 5cd274c6c5a22..368c22675e7f6 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-in-impl.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-in-impl.stderr @@ -4,14 +4,13 @@ error: `~const` can only be applied to `#[const_trait]` traits LL | impl const MyPartialEq for T { | ^^^^^^^^^ -error[E0049]: method `eq` has 1 const parameter but its trait declaration has 0 const parameters - --> $DIR/call-generic-in-impl.rs:5:1 +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/call-generic-in-impl.rs:10:16 + | +LL | impl const MyPartialEq for T { + | ^^^^^^^^^ | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | trait MyPartialEq { -LL | fn eq(&self, other: &Self) -> bool; - | - expected 0 const parameters + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0015]: cannot call non-const fn `::eq` in constant functions --> $DIR/call-generic-in-impl.rs:12:9 @@ -27,5 +26,4 @@ LL + #![feature(effects)] error: aborting due to 3 previous errors -Some errors have detailed explanations: E0015, E0049. -For more information about an error, try `rustc --explain E0015`. +For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-chain.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-chain.stderr index 57d57dfd5b935..dce9f0853904d 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-chain.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-chain.stderr @@ -27,11 +27,27 @@ error: `~const` can only be applied to `#[const_trait]` traits LL | const fn equals_self(t: &T) -> bool { | ^^^^^^^^^ +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/call-generic-method-chain.rs:19:32 + | +LL | const fn equals_self(t: &T) -> bool { + | ^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/call-generic-method-chain.rs:23:40 | LL | const fn equals_self_wrapper(t: &T) -> bool { | ^^^^^^^^^ -error: aborting due to 4 previous errors; 1 warning emitted +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/call-generic-method-chain.rs:23:40 + | +LL | const fn equals_self_wrapper(t: &T) -> bool { + | ^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 6 previous errors; 1 warning emitted diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-dup-bound.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-dup-bound.stderr index 0088ed2eb13db..5da511a580e21 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-dup-bound.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-dup-bound.stderr @@ -27,11 +27,27 @@ error: `~const` can only be applied to `#[const_trait]` traits LL | const fn equals_self(t: &T) -> bool { | ^^^^^^^^^ +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/call-generic-method-dup-bound.rs:19:44 + | +LL | const fn equals_self(t: &T) -> bool { + | ^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/call-generic-method-dup-bound.rs:26:37 | LL | const fn equals_self2(t: &T) -> bool { | ^^^^^^^^^ -error: aborting due to 4 previous errors; 1 warning emitted +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/call-generic-method-dup-bound.rs:26:37 + | +LL | const fn equals_self2(t: &T) -> bool { + | ^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 6 previous errors; 1 warning emitted diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr index 68c9fc400104e..06b99375cdaa7 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr @@ -1,20 +1,8 @@ error[E0277]: the trait bound `S: const Foo` is not satisfied - --> $DIR/call-generic-method-nonconst.rs:25:34 + --> $DIR/call-generic-method-nonconst.rs:25:22 | LL | pub const EQ: bool = equals_self(&S); - | ----------- ^^ the trait `Foo` is not implemented for `S` - | | - | required by a bound introduced by this call - | -note: required by a bound in `equals_self` - --> $DIR/call-generic-method-nonconst.rs:18:25 - | -LL | const fn equals_self(t: &T) -> bool { - | ^^^^^^^^^^ required by this bound in `equals_self` -help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement - | -LL | pub const EQ: bool where S: Foo = equals_self(&S); - | ++++++++++++ + | ^^^^^^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-pass.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-pass.stderr index 4a6100c3c1aac..52579813b691b 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-pass.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-pass.stderr @@ -27,5 +27,13 @@ error: `~const` can only be applied to `#[const_trait]` traits LL | const fn equals_self(t: &T) -> bool { | ^^^^^^^^^ -error: aborting due to 3 previous errors; 1 warning emitted +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/call-generic-method-pass.rs:19:32 + | +LL | const fn equals_self(t: &T) -> bool { + | ^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 4 previous errors; 1 warning emitted diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-bounds-non-const-trait.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-bounds-non-const-trait.rs index db446f8bc2eab..d51d231b8a977 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-bounds-non-const-trait.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-bounds-non-const-trait.rs @@ -5,6 +5,7 @@ trait NonConst {} const fn perform() {} //~^ ERROR `~const` can only be applied to `#[const_trait]` traits +//~| ERROR `~const` can only be applied to `#[const_trait]` traits fn operate() {} //~^ ERROR `const` can only be applied to `#[const_trait]` traits diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-bounds-non-const-trait.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-bounds-non-const-trait.stderr index e1a85fc54144b..6c3c11c6a4756 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-bounds-non-const-trait.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-bounds-non-const-trait.stderr @@ -18,11 +18,19 @@ error: `~const` can only be applied to `#[const_trait]` traits LL | const fn perform() {} | ^^^^^^^^ +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/const-bounds-non-const-trait.rs:6:28 + | +LL | const fn perform() {} + | ^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + error: `const` can only be applied to `#[const_trait]` traits - --> $DIR/const-bounds-non-const-trait.rs:9:21 + --> $DIR/const-bounds-non-const-trait.rs:10:21 | LL | fn operate() {} | ^^^^^^^^ -error: aborting due to 3 previous errors; 1 warning emitted +error: aborting due to 4 previous errors; 1 warning emitted diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-trait-method-fail.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-trait-method-fail.stderr index 507ceaae2eab3..4e6707bba51ce 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-trait-method-fail.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-trait-method-fail.stderr @@ -1,17 +1,16 @@ -error[E0049]: method `a` has 1 const parameter but its trait declaration has 0 const parameters - --> $DIR/const-closure-trait-method-fail.rs:5:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | trait Tr { -LL | fn a(self) -> i32; - | - expected 0 const parameters +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/const-closure-trait-method-fail.rs:14:39 + | +LL | const fn need_const_closure i32>(x: T) -> i32 { + | ^^^^^^^^^^^^^^^^^ error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/const-closure-trait-method-fail.rs:14:39 | LL | const fn need_const_closure i32>(x: T) -> i32 { | ^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0015]: cannot call non-const closure in constant functions --> $DIR/const-closure-trait-method-fail.rs:15:5 @@ -31,5 +30,4 @@ LL + #![feature(effects)] error: aborting due to 3 previous errors -Some errors have detailed explanations: E0015, E0049. -For more information about an error, try `rustc --explain E0015`. +For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-trait-method.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-trait-method.stderr index 2a54cd5d7f6e5..0f0cd73cc102c 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-trait-method.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-trait-method.stderr @@ -1,17 +1,16 @@ -error[E0049]: method `a` has 1 const parameter but its trait declaration has 0 const parameters - --> $DIR/const-closure-trait-method.rs:5:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | trait Tr { -LL | fn a(self) -> i32; - | - expected 0 const parameters +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/const-closure-trait-method.rs:14:39 + | +LL | const fn need_const_closure i32>(x: T) -> i32 { + | ^^^^^^^^^^^^^^^^^ error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/const-closure-trait-method.rs:14:39 | LL | const fn need_const_closure i32>(x: T) -> i32 { | ^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0015]: cannot call non-const closure in constant functions --> $DIR/const-closure-trait-method.rs:15:5 @@ -31,5 +30,4 @@ LL + #![feature(effects)] error: aborting due to 3 previous errors -Some errors have detailed explanations: E0015, E0049. -For more information about an error, try `rustc --explain E0015`. +For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closures.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closures.stderr index a0f053253892f..4d354cb281fea 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closures.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closures.stderr @@ -16,12 +16,44 @@ error: `~const` can only be applied to `#[const_trait]` traits LL | F: ~const Fn() -> u8, | ^^^^^^^^^^ +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/const-closures.rs:8:19 + | +LL | F: ~const FnOnce() -> u8, + | ^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/const-closures.rs:9:19 + | +LL | F: ~const FnMut() -> u8, + | ^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/const-closures.rs:10:19 + | +LL | F: ~const Fn() -> u8, + | ^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/const-closures.rs:23:27 | LL | const fn answer u8>(f: &F) -> u8 { | ^^^^^^^^^^ +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/const-closures.rs:23:27 + | +LL | const fn answer u8>(f: &F) -> u8 { + | ^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + error[E0015]: cannot call non-const closure in constant functions --> $DIR/const-closures.rs:24:5 | @@ -70,6 +102,6 @@ help: add `#![feature(effects)]` to the crate attributes to enable LL + #![feature(effects)] | -error: aborting due to 7 previous errors +error: aborting due to 11 previous errors For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.stderr index 0809d9c1e1d32..071eaf495418a 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.stderr @@ -1,21 +1,8 @@ error[E0277]: the trait bound `NonConstImpl: ~const ConstDefaultFn` is not satisfied - --> $DIR/const-default-method-bodies.rs:26:18 + --> $DIR/const-default-method-bodies.rs:26:5 | LL | NonConstImpl.a(); - | ^ the trait `ConstDefaultFn` is not implemented for `NonConstImpl` - | -note: required by a bound in `ConstDefaultFn::a` - --> $DIR/const-default-method-bodies.rs:5:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ required by this bound in `ConstDefaultFn::a` -... -LL | fn a(self) { - | - required by a bound in this associated function -help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement - | -LL | const fn test() where NonConstImpl: ConstDefaultFn { - | ++++++++++++++++++++++++++++++++++ + | ^^^^^^^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-bound.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-bound.stderr index be197006f021a..d94b0542324f6 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-bound.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-bound.stderr @@ -4,6 +4,14 @@ error: `~const` can only be applied to `#[const_trait]` traits LL | const fn foo(res: Result) -> Option where E: ~const Destruct { | ^^^^^^^^ +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/const-drop-bound.rs:9:68 + | +LL | const fn foo(res: Result) -> Option where E: ~const Destruct { + | ^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/const-drop-bound.rs:20:15 | @@ -16,12 +24,28 @@ error: `~const` can only be applied to `#[const_trait]` traits LL | E: ~const Destruct, | ^^^^^^^^ +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/const-drop-bound.rs:20:15 + | +LL | T: ~const Destruct, + | ^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/const-drop-bound.rs:21:15 + | +LL | E: ~const Destruct, + | ^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + error[E0493]: destructor of `E` cannot be evaluated at compile-time --> $DIR/const-drop-bound.rs:12:13 | LL | Err(_e) => None, | ^^ the destructor for this type cannot be evaluated in constant functions -error: aborting due to 4 previous errors +error: aborting due to 7 previous errors For more information about this error, try `rustc --explain E0493`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.stderr index faf24c6d91145..27e8053c9690a 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.stderr @@ -13,6 +13,14 @@ error: `~const` can only be applied to `#[const_trait]` traits LL | const fn check(_: T) {} | ^^^^^^^^ +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/const-drop-fail-2.rs:20:26 + | +LL | const fn check(_: T) {} + | ^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + error[E0493]: destructor of `T` cannot be evaluated at compile-time --> $DIR/const-drop-fail-2.rs:20:36 | @@ -33,7 +41,7 @@ help: add `#![feature(effects)]` to the crate attributes to enable LL + #![feature(effects)] | -error: aborting due to 4 previous errors +error: aborting due to 5 previous errors Some errors have detailed explanations: E0015, E0493. For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr index 3d400bf015871..bde13b4d6cfa8 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr @@ -13,6 +13,14 @@ error: `~const` can only be applied to `#[const_trait]` traits LL | const fn check(_: T) {} | ^^^^^^^^ +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/const-drop-fail.rs:23:26 + | +LL | const fn check(_: T) {} + | ^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + error[E0493]: destructor of `T` cannot be evaluated at compile-time --> $DIR/const-drop-fail.rs:23:36 | @@ -71,7 +79,7 @@ LL | | } | |_- in this macro invocation = note: this error originates in the macro `check_all` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 5 previous errors +error: aborting due to 6 previous errors Some errors have detailed explanations: E0080, E0493. For more information about an error, try `rustc --explain E0080`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr index fd0f6d02684a6..064ffacca4274 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr @@ -13,6 +13,14 @@ error: `~const` can only be applied to `#[const_trait]` traits LL | const fn check(_: T) {} | ^^^^^^^^ +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/const-drop-fail.rs:23:26 + | +LL | const fn check(_: T) {} + | ^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + error[E0493]: destructor of `T` cannot be evaluated at compile-time --> $DIR/const-drop-fail.rs:23:36 | @@ -21,6 +29,6 @@ LL | const fn check(_: T) {} | | | the destructor for this type cannot be evaluated in constant functions -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0493`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.precise.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.precise.stderr index dd3ea5d241d76..7b6d185c7cc8b 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.precise.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.precise.stderr @@ -40,23 +40,11 @@ error: `~const` can only be applied to `#[const_trait]` traits LL | const fn a(_: T) {} | ^^^^^^^^ -error[E0049]: associated function `foo` has 1 const parameter but its trait declaration has 0 const parameters - --> $DIR/const-drop.rs:53:5 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | pub trait SomeTrait { -LL | fn foo(); - | - expected 0 const parameters - -error[E0049]: associated function `foo` has 1 const parameter but its trait declaration has 0 const parameters - --> $DIR/const-drop.rs:53:5 +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/const-drop.rs:18:22 | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | pub trait SomeTrait { -LL | fn foo(); - | - expected 0 const parameters +LL | const fn a(_: T) {} + | ^^^^^^^^ | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` @@ -78,7 +66,7 @@ help: add `#![feature(effects)]` to the crate attributes to enable LL + #![feature(effects)] | -error: aborting due to 9 previous errors +error: aborting due to 8 previous errors -Some errors have detailed explanations: E0015, E0049, E0493. +Some errors have detailed explanations: E0015, E0493. For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.stock.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.stock.stderr index aa59e1c8dc492..b497c39b08aaf 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.stock.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.stock.stderr @@ -40,23 +40,11 @@ error: `~const` can only be applied to `#[const_trait]` traits LL | const fn a(_: T) {} | ^^^^^^^^ -error[E0049]: associated function `foo` has 1 const parameter but its trait declaration has 0 const parameters - --> $DIR/const-drop.rs:53:5 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | pub trait SomeTrait { -LL | fn foo(); - | - expected 0 const parameters - -error[E0049]: associated function `foo` has 1 const parameter but its trait declaration has 0 const parameters - --> $DIR/const-drop.rs:53:5 +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/const-drop.rs:18:22 | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | pub trait SomeTrait { -LL | fn foo(); - | - expected 0 const parameters +LL | const fn a(_: T) {} + | ^^^^^^^^ | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` @@ -80,7 +68,7 @@ help: add `#![feature(effects)]` to the crate attributes to enable LL + #![feature(effects)] | -error: aborting due to 9 previous errors +error: aborting due to 8 previous errors -Some errors have detailed explanations: E0015, E0049, E0493. +Some errors have detailed explanations: E0015, E0493. For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-fns-are-early-bound.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-fns-are-early-bound.rs index e85c034e80a39..28a5c181566ac 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-fns-are-early-bound.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-fns-are-early-bound.rs @@ -1,4 +1,5 @@ //@ known-bug: #110395 +//@ failure-status: 101 // FIXME(effects) check-pass //@ compile-flags: -Znext-solver diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-fns-are-early-bound.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-fns-are-early-bound.stderr index 9eda9d98ec552..365f1f387fbc8 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-fns-are-early-bound.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-fns-are-early-bound.stderr @@ -1,20 +1,206 @@ -error[E0277]: the trait bound `fn() {foo}: const FnOnce()` is not satisfied - --> $DIR/const-fns-are-early-bound.rs:31:17 - | -LL | is_const_fn(foo); - | ----------- ^^^ the trait `FnOnce()` is not implemented for fn item `fn() {foo}` - | | - | required by a bound introduced by this call - | -note: required by a bound in `is_const_fn` - --> $DIR/const-fns-are-early-bound.rs:25:12 - | -LL | fn is_const_fn(_: F) - | ----------- required by a bound in this function -LL | where -LL | F: const FnOnce<()>, - | ^^^^^^^^^^^^^^^^ required by this bound in `is_const_fn` +thread 'rustc' panicked at /home/mgx/rust/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs:179:9: +not yet implemented: Fn* are not yet const +stack backtrace: + 0: begin_panic_handler + at ./library/std/src/panicking.rs:665:5 + 1: panic_fmt + at ./library/core/src/panicking.rs:74:14 + 2: consider_builtin_fn_trait_candidates + at ./compiler/rustc_next_trait_solver/src/solve/effect_goals.rs:179:9 + 3: assemble_builtin_impl_candidates> + at ./compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs:420:21 + 4: assemble_and_evaluate_candidates> + at ./compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs:329:9 + 5: compute_host_effect_goal + at ./compiler/rustc_next_trait_solver/src/solve/effect_goals.rs:292:26 + 6: compute_goal + at ./compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs:447:21 + 7: {closure#0} + at ./compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs:353:42 + 8: enter_canonical>, rustc_type_ir::solve::NoSolution>, rustc_next_trait_solver::solve::eval_ctxt::{impl#2}::evaluate_canonical_goal::{closure#0}::{closure#0}::{closure#0}::{closure_env#0}> + at ./compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs:305:22 + 9: {closure#0} + at ./compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs:347:21 + 10: call_mut<(&mut rustc_type_ir::search_graph::SearchGraph, rustc_middle::ty::context::TyCtxt>, &mut rustc_next_trait_solver::solve::inspect::build::ProofTreeBuilder), rustc_next_trait_solver::solve::eval_ctxt::{impl#2}::evaluate_canonical_goal::{closure#0}::{closure#0}::{closure_env#0}> + at ./library/core/src/ops/function.rs:294:13 + 11: evaluate_goal_in_task, rustc_middle::ty::context::TyCtxt, &mut rustc_next_trait_solver::solve::eval_ctxt::{impl#2}::evaluate_canonical_goal::{closure#0}::{closure#0}::{closure_env#0}> + at ./compiler/rustc_type_ir/src/search_graph/mod.rs:955:26 + 12: {closure#2}, rustc_middle::ty::context::TyCtxt, rustc_next_trait_solver::solve::eval_ctxt::{impl#2}::evaluate_canonical_goal::{closure#0}::{closure#0}::{closure_env#0}> + at ./compiler/rustc_type_ir/src/search_graph/mod.rs:530:13 + 13: with_anon_task, rustc_middle::ty::context::TyCtxt, rustc_next_trait_solver::solve::eval_ctxt::{impl#2}::evaluate_canonical_goal::{closure#0}::{closure#0}::{closure_env#0}>, (rustc_type_ir::search_graph::StackEntry, core::result::Result>, rustc_type_ir::solve::NoSolution>)> + at ./compiler/rustc_query_system/src/dep_graph/graph.rs:306:22 + 14: with_cached_task<(rustc_type_ir::search_graph::StackEntry, core::result::Result>, rustc_type_ir::solve::NoSolution>), rustc_type_ir::search_graph::{impl#4}::with_new_goal::{closure_env#2}, rustc_middle::ty::context::TyCtxt, rustc_next_trait_solver::solve::eval_ctxt::{impl#2}::evaluate_canonical_goal::{closure#0}::{closure#0}::{closure_env#0}>> + at ./compiler/rustc_middle/src/ty/context.rs:124:9 + 15: with_cached_task, core::result::Result>, rustc_type_ir::solve::NoSolution>), rustc_type_ir::search_graph::{impl#4}::with_new_goal::{closure_env#2}, rustc_middle::ty::context::TyCtxt, rustc_next_trait_solver::solve::eval_ctxt::{impl#2}::evaluate_canonical_goal::{closure#0}::{closure#0}::{closure_env#0}>> + at ./compiler/rustc_type_ir/src/interner.rs:413:9 + 16: with_new_goal, rustc_middle::ty::context::TyCtxt, rustc_next_trait_solver::solve::eval_ctxt::{impl#2}::evaluate_canonical_goal::{closure#0}::{closure#0}::{closure_env#0}> + at ./compiler/rustc_type_ir/src/search_graph/mod.rs:529:49 + 17: {closure#0} + at ./compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs:342:13 + 18: maybe_grow>, rustc_type_ir::solve::NoSolution>, rustc_next_trait_solver::solve::eval_ctxt::{impl#2}::evaluate_canonical_goal::{closure#0}::{closure_env#0}> + at /home/mgx/.cargo/registry/src/index.crates.io-6f17d22bba15001f/stacker-0.1.17/src/lib.rs:55:9 + 19: ensure_sufficient_stack>, rustc_type_ir::solve::NoSolution>, rustc_next_trait_solver::solve::eval_ctxt::{impl#2}::evaluate_canonical_goal::{closure#0}::{closure_env#0}> + at ./compiler/rustc_data_structures/src/stack.rs:21:5 + 20: {closure#0} + at ./compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs:341:22 + 21: evaluate_canonical_goal + at ./compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs:328:5 + 22: evaluate_goal_raw + at ./compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs:399:34 + 23: evaluate_goal + at ./compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs:376:13 + 24: {closure#0} + at ./compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs:180:13 + 25: enter_root, rustc_next_trait_solver::solve::eval_ctxt::{impl#1}::evaluate_root_goal::{closure_env#0}> + at ./compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs:254:22 + 26: evaluate_root_goal + at ./compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs:179:9 + 27: select_where_possible + at ./compiler/rustc_trait_selection/src/solve/fulfill.rs:169:30 + 28: select_obligations_where_possible> + at ./compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs:644:26 + 29: check_argument_types + at ./compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs:374:17 + 30: confirm_builtin_call + at ./compiler/rustc_hir_typeck/src/callee.rs:500:9 + 31: check_call + 32: check_expr_kind + at ./compiler/rustc_hir_typeck/src/expr.rs:498:45 + 33: {closure#0} + at ./compiler/rustc_hir_typeck/src/expr.rs:221:18 + 34: maybe_grow + at /home/mgx/.cargo/registry/src/index.crates.io-6f17d22bba15001f/stacker-0.1.17/src/lib.rs:55:9 + 35: ensure_sufficient_stack + at ./compiler/rustc_data_structures/src/stack.rs:21:5 + 36: check_expr_with_expectation_and_args + at ./compiler/rustc_hir_typeck/src/expr.rs:217:18 + 37: check_expr_with_expectation + at ./compiler/rustc_hir_typeck/src/expr.rs:163:9 + 38: check_expr + at ./compiler/rustc_hir_typeck/src/expr.rs:136:9 + 39: check_stmt + at ./compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs:1775:17 + 40: {closure#0} + at ./compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs:1827:17 + 41: with_breakable_ctxt + at ./compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs:1522:22 + 42: check_block_with_expected + at ./compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs:1825:26 + 43: check_expr_kind + at ./compiler/rustc_hir_typeck/src/expr.rs:497:41 + 44: {closure#0} + at ./compiler/rustc_hir_typeck/src/expr.rs:221:18 + 45: maybe_grow + at /home/mgx/.cargo/registry/src/index.crates.io-6f17d22bba15001f/stacker-0.1.17/src/lib.rs:55:9 + 46: ensure_sufficient_stack + at ./compiler/rustc_data_structures/src/stack.rs:21:5 + 47: check_expr_with_expectation_and_args + at ./compiler/rustc_hir_typeck/src/expr.rs:217:18 + 48: check_expr_with_expectation + at ./compiler/rustc_hir_typeck/src/expr.rs:163:9 + 49: check_expr_with_hint + at ./compiler/rustc_hir_typeck/src/expr.rs:115:9 + 50: check_return_expr + at ./compiler/rustc_hir_typeck/src/expr.rs:1027:30 + 51: check_fn + at ./compiler/rustc_hir_typeck/src/check.rs:140:5 + 52: {closure#0} + at ./compiler/rustc_hir_typeck/src/lib.rs:164:9 + 53: typeck_with_fallback + at ./compiler/rustc_hir_typeck/src/lib.rs:119:1 + 54: {closure#0} + at ./compiler/rustc_query_impl/src/plumbing.rs:283:9 + [... omitted 22 frames ...] + 55: query_ensure>> + at ./compiler/rustc_middle/src/query/plumbing.rs:159:9 + 56: typeck + at ./compiler/rustc_middle/src/query/plumbing.rs:194:9 + 57: {closure#4} + at ./compiler/rustc_hir_analysis/src/lib.rs:206:13 + 58: {closure#0} + at ./compiler/rustc_middle/src/hir/map/mod.rs:352:82 + 59: {closure#0}<&rustc_span::def_id::LocalDefId, &[rustc_span::def_id::LocalDefId], rustc_middle::hir::map::{impl#4}::par_body_owners::{closure_env#0}> + at ./compiler/rustc_data_structures/src/sync/parallel.rs:183:34 + 60: call_once<(), rustc_data_structures::sync::parallel::enabled::par_for_each_in::{closure#0}::{closure#0}::{closure_env#0}<&rustc_span::def_id::LocalDefId, &[rustc_span::def_id::LocalDefId], rustc_middle::hir::map::{impl#4}::par_body_owners::{closure_env#0}>> + at ./library/core/src/panic/unwind_safe.rs:272:9 + 61: do_call>>, ()> + at ./library/std/src/panicking.rs:557:40 + 62: try<(), core::panic::unwind_safe::AssertUnwindSafe>>> + at ./library/std/src/panicking.rs:520:19 + 63: catch_unwind>>, ()> + at ./library/std/src/panic.rs:358:14 + 64: run<(), rustc_data_structures::sync::parallel::enabled::par_for_each_in::{closure#0}::{closure#1}::{closure_env#0}<&rustc_span::def_id::LocalDefId, &[rustc_span::def_id::LocalDefId], rustc_middle::hir::map::{impl#4}::par_body_owners::{closure_env#0}>> + at ./compiler/rustc_data_structures/src/sync/parallel.rs:29:9 + 65: {closure#1}<&rustc_span::def_id::LocalDefId, &[rustc_span::def_id::LocalDefId], rustc_middle::hir::map::{impl#4}::par_body_owners::{closure_env#0}> + at ./compiler/rustc_data_structures/src/sync/parallel.rs:187:21 + 66: for_each>> + at ./library/core/src/slice/iter/macros.rs:254:21 + 67: {closure#0}<&rustc_span::def_id::LocalDefId, &[rustc_span::def_id::LocalDefId], rustc_middle::hir::map::{impl#4}::par_body_owners::{closure_env#0}> + at ./compiler/rustc_data_structures/src/sync/parallel.rs:186:17 + 68: parallel_guard<(), rustc_data_structures::sync::parallel::enabled::par_for_each_in::{closure_env#0}<&rustc_span::def_id::LocalDefId, &[rustc_span::def_id::LocalDefId], rustc_middle::hir::map::{impl#4}::par_body_owners::{closure_env#0}>> + at ./compiler/rustc_data_structures/src/sync/parallel.rs:45:15 + 69: par_for_each_in<&rustc_span::def_id::LocalDefId, &[rustc_span::def_id::LocalDefId], rustc_middle::hir::map::{impl#4}::par_body_owners::{closure_env#0}> + at ./compiler/rustc_data_structures/src/sync/parallel.rs:179:9 + 70: par_body_owners + at ./compiler/rustc_middle/src/hir/map/mod.rs:352:9 + 71: check_crate + at ./compiler/rustc_hir_analysis/src/lib.rs:203:5 + 72: run_required_analyses + at ./compiler/rustc_interface/src/passes.rs:865:5 + 73: analysis + at ./compiler/rustc_interface/src/passes.rs:930:5 + 74: {closure#0} + at ./compiler/rustc_query_impl/src/plumbing.rs:283:9 + [... omitted 22 frames ...] + 75: query_get_at>> + at ./compiler/rustc_middle/src/query/plumbing.rs:143:17 + 76: analysis + at ./compiler/rustc_middle/src/query/plumbing.rs:422:31 + 77: analysis + at ./compiler/rustc_middle/src/query/plumbing.rs:413:17 + 78: {closure#5} + at ./compiler/rustc_driver_impl/src/lib.rs:449:48 + 79: {closure#1}> + at ./compiler/rustc_middle/src/ty/context.rs:1351:37 + 80: {closure#0}>, core::result::Result<(), rustc_span::ErrorGuaranteed>> + at ./compiler/rustc_middle/src/ty/context/tls.rs:82:9 + 81: try_with, rustc_middle::ty::context::tls::enter_context::{closure_env#0}>, core::result::Result<(), rustc_span::ErrorGuaranteed>>, core::result::Result<(), rustc_span::ErrorGuaranteed>> + at ./library/std/src/thread/local.rs:283:12 + 82: with, rustc_middle::ty::context::tls::enter_context::{closure_env#0}>, core::result::Result<(), rustc_span::ErrorGuaranteed>>, core::result::Result<(), rustc_span::ErrorGuaranteed>> + at ./library/std/src/thread/local.rs:260:9 + 83: enter_context>, core::result::Result<(), rustc_span::ErrorGuaranteed>> + at ./compiler/rustc_middle/src/ty/context/tls.rs:79:5 + 84: enter> + at ./compiler/rustc_middle/src/ty/context.rs:1351:9 + 85: {closure#1} + at ./compiler/rustc_driver_impl/src/lib.rs:449:13 + 86: enter, rustc_span::ErrorGuaranteed>> + at ./compiler/rustc_interface/src/queries.rs:210:19 + 87: {closure#0} + at ./compiler/rustc_driver_impl/src/lib.rs:391:22 + 88: {closure#1}, rustc_driver_impl::run_compiler::{closure_env#0}> + at ./compiler/rustc_interface/src/interface.rs:505:27 + 89: {closure#0}, rustc_driver_impl::run_compiler::{closure_env#0}>, core::result::Result<(), rustc_span::ErrorGuaranteed>> + at ./compiler/rustc_interface/src/util.rs:157:13 + 90: {closure#0}, rustc_driver_impl::run_compiler::{closure_env#0}>, core::result::Result<(), rustc_span::ErrorGuaranteed>>, core::result::Result<(), rustc_span::ErrorGuaranteed>> + at ./compiler/rustc_interface/src/util.rs:107:21 + 91: set, rustc_driver_impl::run_compiler::{closure_env#0}>, core::result::Result<(), rustc_span::ErrorGuaranteed>>, core::result::Result<(), rustc_span::ErrorGuaranteed>>, core::result::Result<(), rustc_span::ErrorGuaranteed>> + at /home/mgx/.cargo/registry/src/index.crates.io-6f17d22bba15001f/scoped-tls-1.0.1/src/lib.rs:137:9 + 92: create_session_globals_then, rustc_interface::util::run_in_thread_with_globals::{closure#0}::{closure#0}::{closure_env#0}, rustc_driver_impl::run_compiler::{closure_env#0}>, core::result::Result<(), rustc_span::ErrorGuaranteed>>, core::result::Result<(), rustc_span::ErrorGuaranteed>>> + at ./compiler/rustc_span/src/lib.rs:137:5 + 93: {closure#0}, rustc_driver_impl::run_compiler::{closure_env#0}>, core::result::Result<(), rustc_span::ErrorGuaranteed>>, core::result::Result<(), rustc_span::ErrorGuaranteed>> + at ./compiler/rustc_interface/src/util.rs:106:17 +note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace. -error: aborting due to 1 previous error +error: the compiler unexpectedly panicked. this is a bug. -For more information about this error, try `rustc --explain E0277`. +note: using internal features is not supported and expected to cause internal compiler errors when used incorrectly + +note: rustc 1.84.0-dev running on x86_64-unknown-linux-gnu + +note: compiler flags: -Z threads=1 -Z simulate-remapped-rust-src-base=/rustc/FAKE_PREFIX -Z translate-remapped-path-to-local-path=no -Z ignore-directory-in-diagnostics-source-blocks=/home/mgx/.cargo -Z ignore-directory-in-diagnostics-source-blocks=/home/mgx/rust/vendor -C codegen-units=1 -Z ui-testing -Z deduplicate-diagnostics=no -Z write-long-types-to-disk=no -C strip=debuginfo -C prefer-dynamic -C rpath -C debuginfo=0 -Z next-solver + +query stack during panic: +#0 [typeck] type-checking `test` +#1 [analysis] running analysis passes on this crate +end of query stack diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-trait.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-trait.stderr index 1040af7541c08..3baebb5faa7f3 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-trait.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-trait.stderr @@ -15,6 +15,14 @@ error: `~const` can only be applied to `#[const_trait]` traits LL | const fn cmp(a: &impl ~const PartialEq) -> bool { | ^^^^^^^^^ +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/const-impl-trait.rs:13:30 + | +LL | const fn cmp(a: &impl ~const PartialEq) -> bool { + | ^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/const-impl-trait.rs:17:30 | @@ -55,6 +63,22 @@ LL | -> impl ~const PartialEq + ~const Destruct | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/const-impl-trait.rs:17:30 + | +LL | const fn wrap(x: impl ~const PartialEq + ~const Destruct) + | ^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/const-impl-trait.rs:17:49 + | +LL | const fn wrap(x: impl ~const PartialEq + ~const Destruct) + | ^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/const-impl-trait.rs:25:29 | @@ -101,11 +125,27 @@ error: `~const` can only be applied to `#[const_trait]` traits LL | const fn apit(_: impl ~const T + ~const Destruct) {} | ^^^^^^^^ +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/const-impl-trait.rs:50:41 + | +LL | const fn apit(_: impl ~const T + ~const Destruct) {} + | ^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/const-impl-trait.rs:54:73 + | +LL | const fn apit_assoc_bound(_: impl IntoIterator + ~const Destruct) {} + | ^^^^^^^^ + error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/const-impl-trait.rs:54:73 | LL | const fn apit_assoc_bound(_: impl IntoIterator + ~const Destruct) {} | ^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/const-impl-trait.rs:25:29 @@ -243,7 +283,7 @@ LL | const fn apit_assoc_bound(_: impl IntoIterator + ~const Des | | | the destructor for this type cannot be evaluated in constant functions -error: aborting due to 33 previous errors +error: aborting due to 38 previous errors Some errors have detailed explanations: E0493, E0635. For more information about an error, try `rustc --explain E0493`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.gatednc.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.gatednc.stderr index a34bae843c816..b6f2434140d6a 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.gatednc.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.gatednc.stderr @@ -1,21 +1,8 @@ error[E0277]: the trait bound `cross_crate::NonConst: ~const cross_crate::MyTrait` is not satisfied - --> $DIR/cross-crate.rs:19:14 + --> $DIR/cross-crate.rs:19:5 | LL | NonConst.func(); - | ^^^^ the trait `cross_crate::MyTrait` is not implemented for `cross_crate::NonConst` - | -note: required by a bound in `func` - --> $DIR/auxiliary/cross-crate.rs:5:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ required by this bound in `MyTrait::func` -... -LL | fn func(self); - | ---- required by a bound in this associated function -help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement - | -LL | const fn const_context() where cross_crate::NonConst: cross_crate::MyTrait { - | +++++++++++++++++++++++++++++++++++++++++++++++++ + | ^^^^^^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr index d0f22c0b9b62b..7b4d512e39180 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr @@ -1,21 +1,8 @@ error[E0277]: the trait bound `(): ~const Tr` is not satisfied - --> $DIR/default-method-body-is-const-same-trait-ck.rs:10:12 + --> $DIR/default-method-body-is-const-same-trait-ck.rs:10:9 | LL | ().a() - | ^ the trait `Tr` is not implemented for `()` - | -note: required by a bound in `Tr::a` - --> $DIR/default-method-body-is-const-same-trait-ck.rs:5:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ required by this bound in `Tr::a` -LL | pub trait Tr { -LL | fn a(&self) {} - | - required by a bound in this associated function -help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement - | -LL | pub trait Tr where (): Tr { - | ++++++++++++ + | ^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.stderr index 823ab69df9cb5..568d98cfe8715 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.stderr @@ -1,13 +1,13 @@ error: the compiler unexpectedly panicked. this is a bug. query stack during panic: -#0 [check_well_formed] checking that `` is well-formed -#1 [check_mod_type_wf] checking that types are well-formed in top-level module +#0 [typeck] type-checking `Clone::clone_from` +#1 [analysis] running analysis passes on this crate end of query stack error: the compiler unexpectedly panicked. this is a bug. query stack during panic: -#0 [check_well_formed] checking that `drop` is well-formed -#1 [check_mod_type_wf] checking that types are well-formed in top-level module +#0 [typeck] type-checking `test_const_eval_select` +#1 [analysis] running analysis passes on this crate end of query stack diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params-cross-crate.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params-cross-crate.stderr index 8c591edac5404..eea6a06c1c818 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params-cross-crate.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params-cross-crate.stderr @@ -16,17 +16,15 @@ error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplie --> $DIR/no-explicit-const-params-cross-crate.rs:16:12 | LL | <() as Bar>::bar(); - | ^^^ expected 0 generic arguments + | ^^^------- help: remove the unnecessary generics + | | + | expected 0 generic arguments | note: trait defined here, with 0 generic parameters --> $DIR/auxiliary/cross-crate.rs:8:11 | LL | pub trait Bar { | ^^^ -help: replace the generic bound with the associated type - | -LL | <() as Bar< = false>>::bar(); - | + error[E0107]: function takes 0 generic arguments but 1 generic argument was supplied --> $DIR/no-explicit-const-params-cross-crate.rs:7:5 @@ -46,17 +44,15 @@ error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplie --> $DIR/no-explicit-const-params-cross-crate.rs:9:12 | LL | <() as Bar>::bar(); - | ^^^ expected 0 generic arguments + | ^^^------ help: remove the unnecessary generics + | | + | expected 0 generic arguments | note: trait defined here, with 0 generic parameters --> $DIR/auxiliary/cross-crate.rs:8:11 | LL | pub trait Bar { | ^^^ -help: replace the generic bound with the associated type - | -LL | <() as Bar< = true>>::bar(); - | + error: aborting due to 4 previous errors diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params.rs index 84f5f2803e156..b08aba9acbcd3 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params.rs @@ -23,5 +23,4 @@ const FOO: () = { //~^ ERROR: function takes 0 generic arguments but 1 generic argument was supplied <() as Bar>::bar(); //~^ ERROR: trait takes 0 generic arguments but 1 generic argument was supplied - //~| ERROR: mismatched types }; diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params.stderr index cc08114ddb565..a3aa970e94d24 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params.stderr @@ -30,26 +30,15 @@ error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplie --> $DIR/no-explicit-const-params.rs:24:12 | LL | <() as Bar>::bar(); - | ^^^ expected 0 generic arguments + | ^^^------- help: remove the unnecessary generics + | | + | expected 0 generic arguments | note: trait defined here, with 0 generic parameters --> $DIR/no-explicit-const-params.rs:6:7 | LL | trait Bar { | ^^^ -help: replace the generic bound with the associated type - | -LL | <() as Bar< = false>>::bar(); - | + - -error[E0308]: mismatched types - --> $DIR/no-explicit-const-params.rs:24:5 - | -LL | <() as Bar>::bar(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `false`, found `true` - | - = note: expected constant `false` - found constant `true` error[E0107]: function takes 0 generic arguments but 1 generic argument was supplied --> $DIR/no-explicit-const-params.rs:15:5 @@ -69,19 +58,16 @@ error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplie --> $DIR/no-explicit-const-params.rs:17:12 | LL | <() as Bar>::bar(); - | ^^^ expected 0 generic arguments + | ^^^------ help: remove the unnecessary generics + | | + | expected 0 generic arguments | note: trait defined here, with 0 generic parameters --> $DIR/no-explicit-const-params.rs:6:7 | LL | trait Bar { | ^^^ -help: replace the generic bound with the associated type - | -LL | <() as Bar< = true>>::bar(); - | + -error: aborting due to 6 previous errors; 1 warning emitted +error: aborting due to 5 previous errors; 1 warning emitted -Some errors have detailed explanations: E0107, E0308. -For more information about an error, try `rustc --explain E0107`. +For more information about this error, try `rustc --explain E0107`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.rs index 0508b1c5e26b6..32a2898bba810 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.rs @@ -1,4 +1,3 @@ -//@ check-fail // Fixes #119830 #![feature(effects)] //~ WARN the feature `effects` is incomplete @@ -17,5 +16,6 @@ impl const Foo for T where T: const Specialize {} //~| error: `const` can only be applied to `#[const_trait]` traits //~| error: specialization impl does not specialize any associated items //~| error: cannot specialize on trait `Specialize` +//~| ERROR cannot specialize on predicate fn main() {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.stderr index e97a9615ae1a0..bd1392ede87cc 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.stderr @@ -1,5 +1,5 @@ warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/spec-effectvar-ice.rs:4:12 + --> $DIR/spec-effectvar-ice.rs:3:12 | LL | #![feature(effects)] | ^^^^^^^ @@ -13,7 +13,7 @@ error: using `#![feature(effects)]` without enabling next trait solver globally = help: use `-Znext-solver` to enable error: const `impl` for trait `Foo` which is not marked with `#[const_trait]` - --> $DIR/spec-effectvar-ice.rs:12:15 + --> $DIR/spec-effectvar-ice.rs:11:15 | LL | trait Foo {} | - help: mark `Foo` as const: `#[const_trait]` @@ -25,7 +25,7 @@ LL | impl const Foo for T {} = note: adding a non-const method body in the future would be a breaking change error: const `impl` for trait `Foo` which is not marked with `#[const_trait]` - --> $DIR/spec-effectvar-ice.rs:15:15 + --> $DIR/spec-effectvar-ice.rs:14:15 | LL | trait Foo {} | - help: mark `Foo` as const: `#[const_trait]` @@ -37,28 +37,34 @@ LL | impl const Foo for T where T: const Specialize {} = note: adding a non-const method body in the future would be a breaking change error: `const` can only be applied to `#[const_trait]` traits - --> $DIR/spec-effectvar-ice.rs:15:40 + --> $DIR/spec-effectvar-ice.rs:14:40 | LL | impl const Foo for T where T: const Specialize {} | ^^^^^^^^^^ error: specialization impl does not specialize any associated items - --> $DIR/spec-effectvar-ice.rs:15:1 + --> $DIR/spec-effectvar-ice.rs:14:1 | LL | impl const Foo for T where T: const Specialize {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: impl is a specialization of this impl - --> $DIR/spec-effectvar-ice.rs:12:1 + --> $DIR/spec-effectvar-ice.rs:11:1 | LL | impl const Foo for T {} | ^^^^^^^^^^^^^^^^^^^^^^^ +error: cannot specialize on predicate `the trait `` is const` + --> $DIR/spec-effectvar-ice.rs:14:34 + | +LL | impl const Foo for T where T: const Specialize {} + | ^^^^^^^^^^^^^^^^ + error: cannot specialize on trait `Specialize` - --> $DIR/spec-effectvar-ice.rs:15:34 + --> $DIR/spec-effectvar-ice.rs:14:34 | LL | impl const Foo for T where T: const Specialize {} | ^^^^^^^^^^^^^^^^ -error: aborting due to 6 previous errors; 1 warning emitted +error: aborting due to 7 previous errors; 1 warning emitted diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-123664-unexpected-bound-var.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-123664-unexpected-bound-var.rs index 64634e7b7ac30..29f40604747b2 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-123664-unexpected-bound-var.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-123664-unexpected-bound-var.rs @@ -3,5 +3,6 @@ const fn with_positive() {} //~^ ERROR `~const` can only be applied to `#[const_trait]` traits +//~| ERROR `~const` can only be applied to `#[const_trait]` traits pub fn main() {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-123664-unexpected-bound-var.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-123664-unexpected-bound-var.stderr index c937430a1ca19..03f88be009364 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-123664-unexpected-bound-var.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-123664-unexpected-bound-var.stderr @@ -9,5 +9,13 @@ error: `~const` can only be applied to `#[const_trait]` traits LL | const fn with_positive() {} | ^^^^ -error: aborting due to 2 previous errors +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/ice-123664-unexpected-bound-var.rs:4:34 + | +LL | const fn with_positive() {} + | ^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 3 previous errors diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-92111.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-92111.stderr index ecc994a3fe658..805cc5370149b 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-92111.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-92111.stderr @@ -4,6 +4,14 @@ error: `~const` can only be applied to `#[const_trait]` traits LL | const fn a(t: T) {} | ^^^^^^^^ +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/issue-92111.rs:20:22 + | +LL | const fn a(t: T) {} + | ^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + error[E0493]: destructor of `T` cannot be evaluated at compile-time --> $DIR/issue-92111.rs:20:32 | @@ -12,6 +20,6 @@ LL | const fn a(t: T) {} | | | the destructor for this type cannot be evaluated in constant functions -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0493`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/non-const-op-in-closure-in-const.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/non-const-op-in-closure-in-const.stderr index de4783bdb3fe6..2803c37646b14 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/non-const-op-in-closure-in-const.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/non-const-op-in-closure-in-const.stderr @@ -4,14 +4,13 @@ error: `~const` can only be applied to `#[const_trait]` traits LL | impl const Convert for A where B: ~const From { | ^^^^^^^ -error[E0049]: method `to` has 1 const parameter but its trait declaration has 0 const parameters - --> $DIR/non-const-op-in-closure-in-const.rs:5:1 +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/non-const-op-in-closure-in-const.rs:10:51 + | +LL | impl const Convert for A where B: ~const From { + | ^^^^^^^ | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | trait Convert { -LL | fn to(self) -> T; - | - expected 0 const parameters + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0015]: cannot call non-const fn `>::from` in constant functions --> $DIR/non-const-op-in-closure-in-const.rs:12:9 @@ -27,5 +26,4 @@ LL + #![feature(effects)] error: aborting due to 3 previous errors -Some errors have detailed explanations: E0015, E0049. -For more information about an error, try `rustc --explain E0015`. +For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.stderr index 7643697874f25..bffc60c65fcea 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.stderr @@ -1,12 +1,3 @@ -error[E0049]: associated function `bar` has 1 const parameter but its trait declaration has 0 const parameters - --> $DIR/const-default-bound-non-const-specialized-bound.rs:16:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | trait Bar { -LL | fn bar(); - | - expected 0 const parameters - error: cannot specialize on const impl with non-const impl --> $DIR/const-default-bound-non-const-specialized-bound.rs:28:1 | @@ -16,26 +7,5 @@ LL | | T: Foo, //FIXME ~ ERROR missing `~const` qualifier LL | | T: Specialize, | |__________________^ -error[E0049]: associated function `baz` has 1 const parameter but its trait declaration has 0 const parameters - --> $DIR/const-default-bound-non-const-specialized-bound.rs:36:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | trait Baz { -LL | fn baz(); - | - expected 0 const parameters - -error[E0049]: associated function `baz` has 1 const parameter but its trait declaration has 0 const parameters - --> $DIR/const-default-bound-non-const-specialized-bound.rs:36:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | trait Baz { -LL | fn baz(); - | - expected 0 const parameters - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: aborting due to 4 previous errors +error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0049`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-const-specialized.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-const-specialized.stderr index 9b2ae8d739c88..f127268d2a1c9 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-const-specialized.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-const-specialized.stderr @@ -1,23 +1,3 @@ -error[E0049]: associated function `value` has 1 const parameter but its trait declaration has 0 const parameters - --> $DIR/const-default-const-specialized.rs:10:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | trait Value { -LL | fn value() -> u32; - | - expected 0 const parameters - -error[E0049]: associated function `value` has 1 const parameter but its trait declaration has 0 const parameters - --> $DIR/const-default-const-specialized.rs:10:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | trait Value { -LL | fn value() -> u32; - | - expected 0 const parameters - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - error[E0015]: cannot call non-const fn `::value` in constant functions --> $DIR/const-default-const-specialized.rs:16:5 | @@ -30,7 +10,6 @@ help: add `#![feature(effects)]` to the crate attributes to enable LL + #![feature(effects)] | -error: aborting due to 3 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0015, E0049. -For more information about an error, try `rustc --explain E0015`. +For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/default-keyword.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/default-keyword.rs index d9ffd237dcefd..bc45a70777ca5 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/default-keyword.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/default-keyword.rs @@ -1,5 +1,4 @@ -//@ known-bug: #110395 -// FIXME check-pass +//@ check-pass #![feature(const_trait_impl)] #![feature(min_specialization)] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/default-keyword.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/default-keyword.stderr deleted file mode 100644 index 18a25045f4b08..0000000000000 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/default-keyword.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0049]: associated function `foo` has 1 const parameter but its trait declaration has 0 const parameters - --> $DIR/default-keyword.rs:7:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | trait Foo { -LL | fn foo(); - | - expected 0 const parameters - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0049`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.rs index 219e5f3a600c1..d80370aee8209 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.rs @@ -1,7 +1,6 @@ // Tests that `~const` trait bounds can be used to specialize const trait impls. -//@ known-bug: #110395 -// FIXME check-pass +//@ check-pass #![feature(const_trait_impl)] #![feature(rustc_attrs)] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.stderr deleted file mode 100644 index ecdc7b930e609..0000000000000 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.stderr +++ /dev/null @@ -1,43 +0,0 @@ -error[E0049]: associated function `foo` has 1 const parameter but its trait declaration has 0 const parameters - --> $DIR/issue-95186-specialize-on-tilde-const.rs:14:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | trait Foo { -LL | fn foo(); - | - expected 0 const parameters - -error[E0049]: associated function `foo` has 1 const parameter but its trait declaration has 0 const parameters - --> $DIR/issue-95186-specialize-on-tilde-const.rs:14:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | trait Foo { -LL | fn foo(); - | - expected 0 const parameters - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0049]: associated function `bar` has 1 const parameter but its trait declaration has 0 const parameters - --> $DIR/issue-95186-specialize-on-tilde-const.rs:30:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | trait Bar { -LL | fn bar() {} - | - expected 0 const parameters - -error[E0049]: associated function `bar` has 1 const parameter but its trait declaration has 0 const parameters - --> $DIR/issue-95186-specialize-on-tilde-const.rs:30:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | trait Bar { -LL | fn bar() {} - | - expected 0 const parameters - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: aborting due to 4 previous errors - -For more information about this error, try `rustc --explain E0049`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.rs index 7514baa2fd554..d97469edaf97f 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.rs @@ -2,8 +2,7 @@ // `T: Foo` in the default impl for the purposes of specialization (i.e., it // does not think that the user is attempting to specialize on trait `Foo`). -//@ known-bug: #110395 -// FIXME check-pass +//@ check-pass #![feature(rustc_attrs)] #![feature(min_specialization)] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.stderr deleted file mode 100644 index 6679bb4653788..0000000000000 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.stderr +++ /dev/null @@ -1,43 +0,0 @@ -error[E0049]: associated function `bar` has 1 const parameter but its trait declaration has 0 const parameters - --> $DIR/issue-95187-same-trait-bound-different-constness.rs:18:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | trait Bar { -LL | fn bar(); - | - expected 0 const parameters - -error[E0049]: associated function `bar` has 1 const parameter but its trait declaration has 0 const parameters - --> $DIR/issue-95187-same-trait-bound-different-constness.rs:18:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | trait Bar { -LL | fn bar(); - | - expected 0 const parameters - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0049]: associated function `baz` has 1 const parameter but its trait declaration has 0 const parameters - --> $DIR/issue-95187-same-trait-bound-different-constness.rs:38:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | trait Baz { -LL | fn baz(); - | - expected 0 const parameters - -error[E0049]: associated function `baz` has 1 const parameter but its trait declaration has 0 const parameters - --> $DIR/issue-95187-same-trait-bound-different-constness.rs:38:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | trait Baz { -LL | fn baz(); - | - expected 0 const parameters - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: aborting due to 4 previous errors - -For more information about this error, try `rustc --explain E0049`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.stderr index 7f363922947fe..a4095d7e8ce56 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.stderr @@ -1,23 +1,3 @@ -error[E0049]: associated function `value` has 1 const parameter but its trait declaration has 0 const parameters - --> $DIR/non-const-default-const-specialized.rs:9:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | trait Value { -LL | fn value() -> u32; - | - expected 0 const parameters - -error[E0049]: associated function `value` has 1 const parameter but its trait declaration has 0 const parameters - --> $DIR/non-const-default-const-specialized.rs:9:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | trait Value { -LL | fn value() -> u32; - | - expected 0 const parameters - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - error[E0015]: cannot call non-const fn `::value` in constant functions --> $DIR/non-const-default-const-specialized.rs:15:5 | @@ -30,7 +10,6 @@ help: add `#![feature(effects)]` to the crate attributes to enable LL + #![feature(effects)] | -error: aborting due to 3 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0015, E0049. -For more information about an error, try `rustc --explain E0015`. +For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness-2.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness-2.stderr index bf273f349b4bc..8e6f6945a1b85 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness-2.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness-2.stderr @@ -1,23 +1,3 @@ -error[E0049]: associated function `a` has 1 const parameter but its trait declaration has 0 const parameters - --> $DIR/specializing-constness-2.rs:9:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | pub trait A { -LL | fn a() -> u32; - | - expected 0 const parameters - -error[E0049]: associated function `a` has 1 const parameter but its trait declaration has 0 const parameters - --> $DIR/specializing-constness-2.rs:9:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | pub trait A { -LL | fn a() -> u32; - | - expected 0 const parameters - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - error[E0015]: cannot call non-const fn `::a` in constant functions --> $DIR/specializing-constness-2.rs:27:5 | @@ -30,7 +10,6 @@ help: add `#![feature(effects)]` to the crate attributes to enable LL + #![feature(effects)] | -error: aborting due to 3 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0015, E0049. -For more information about an error, try `rustc --explain E0015`. +For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness.rs index 4501a218ad723..3aabaf137d54c 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness.rs @@ -22,8 +22,6 @@ impl const A for T { impl A for T { //~^ ERROR: cannot specialize -//~| ERROR: cannot specialize -//~| ERROR: cannot specialize //FIXME(effects) ~| ERROR: missing `~const` qualifier fn a() -> u32 { 3 diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness.stderr index 90721af8e5aab..e8c4fb0f0c723 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness.stderr @@ -18,17 +18,5 @@ error: cannot specialize on const impl with non-const impl LL | impl A for T { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: cannot specialize on trait `Compat` - --> $DIR/specializing-constness.rs:23:16 - | -LL | impl A for T { - | ^^^ - -error: cannot specialize on trait `Compat` - --> $DIR/specializing-constness.rs:23:9 - | -LL | impl A for T { - | ^^^^ - -error: aborting due to 4 previous errors; 1 warning emitted +error: aborting due to 2 previous errors; 1 warning emitted diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.ny.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.ny.stderr index 029c3b4bde3ec..a0848fe520e85 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.ny.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.ny.stderr @@ -20,5 +20,21 @@ LL | trait Bar: ~const Foo {} | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: aborting due to 3 previous errors +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/super-traits-fail-2.rs:12:19 + | +LL | trait Bar: ~const Foo {} + | ^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/super-traits-fail-2.rs:12:19 + | +LL | trait Bar: ~const Foo {} + | ^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 5 previous errors diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.rs index 93a6f385e47db..0ea61f4ae2001 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.rs @@ -13,7 +13,9 @@ trait Bar: ~const Foo {} //[ny,nn]~^ ERROR: `~const` can only be applied to `#[const_trait]` //[ny,nn]~| ERROR: `~const` can only be applied to `#[const_trait]` //[ny,nn]~| ERROR: `~const` can only be applied to `#[const_trait]` -//[yn,nn]~^^^^ ERROR: `~const` is not allowed here +//[ny]~| ERROR: `~const` can only be applied to `#[const_trait]` +//[ny]~| ERROR: `~const` can only be applied to `#[const_trait]` +//[yn,nn]~^^^^^^ ERROR: `~const` is not allowed here const fn foo(x: &T) { x.a(); diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yn.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yn.stderr index 873c57ec71ffe..ec6ca1072890e 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yn.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yn.stderr @@ -11,23 +11,10 @@ LL | trait Bar: ~const Foo {} | ^^^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `T: ~const Foo` is not satisfied - --> $DIR/super-traits-fail-2.rs:19:7 + --> $DIR/super-traits-fail-2.rs:21:5 | LL | x.a(); - | ^ the trait `Foo` is not implemented for `T` - | -note: required by a bound in `Foo::a` - --> $DIR/super-traits-fail-2.rs:6:25 - | -LL | #[cfg_attr(any(yy, yn), const_trait)] - | ^^^^^^^^^^^ required by this bound in `Foo::a` -LL | trait Foo { -LL | fn a(&self); - | - required by a bound in this associated function -help: consider further restricting this bound - | -LL | const fn foo(x: &T) { - | +++++ + | ^^^^^ error: aborting due to 2 previous errors diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yy.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yy.stderr index bea3aea2f3afb..3fa6256abc349 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yy.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yy.stderr @@ -1,21 +1,8 @@ error[E0277]: the trait bound `T: ~const Foo` is not satisfied - --> $DIR/super-traits-fail-2.rs:19:7 + --> $DIR/super-traits-fail-2.rs:21:5 | LL | x.a(); - | ^ the trait `Foo` is not implemented for `T` - | -note: required by a bound in `Foo::a` - --> $DIR/super-traits-fail-2.rs:6:25 - | -LL | #[cfg_attr(any(yy, yn), const_trait)] - | ^^^^^^^^^^^ required by this bound in `Foo::a` -LL | trait Foo { -LL | fn a(&self); - | - required by a bound in this associated function -help: consider further restricting this bound - | -LL | const fn foo(x: &T) { - | +++++ + | ^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr index f40583f0ca57f..294545014bf5e 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr @@ -33,10 +33,18 @@ LL | trait Bar: ~const Foo {} = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/super-traits-fail-3.rs:20:24 + --> $DIR/super-traits-fail-3.rs:22:24 | LL | const fn foo(x: &T) { | ^^^ -error: aborting due to 5 previous errors +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/super-traits-fail-3.rs:22:24 + | +LL | const fn foo(x: &T) { + | ^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 6 previous errors diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.ny.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.ny.stderr index 3f6dfa7b00896..54bb6c5ca4418 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.ny.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.ny.stderr @@ -20,5 +20,21 @@ LL | trait Bar: ~const Foo {} | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: aborting due to 3 previous errors +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/super-traits-fail-3.rs:14:19 + | +LL | trait Bar: ~const Foo {} + | ^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/super-traits-fail-3.rs:14:19 + | +LL | trait Bar: ~const Foo {} + | ^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 5 previous errors diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.rs index b5643b1170000..a9b08e6edcdc6 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.rs @@ -15,10 +15,13 @@ trait Bar: ~const Foo {} //[ny,nn]~^ ERROR: `~const` can only be applied to `#[const_trait]` //[ny,nn]~| ERROR: `~const` can only be applied to `#[const_trait]` //[ny,nn]~| ERROR: `~const` can only be applied to `#[const_trait]` -//[yn,nn]~^^^^ ERROR: `~const` is not allowed here +//[ny]~| ERROR: `~const` can only be applied to `#[const_trait]` +//[ny]~| ERROR: `~const` can only be applied to `#[const_trait]` +//[yn,nn]~^^^^^^ ERROR: `~const` is not allowed here const fn foo(x: &T) { //[yn,nn]~^ ERROR: `~const` can only be applied to `#[const_trait]` + //[yn,nn]~| ERROR: `~const` can only be applied to `#[const_trait]` x.a(); //[yn]~^ ERROR: the trait bound `T: ~const Foo` is not satisfied } diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.yn.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.yn.stderr index bbc95948a59db..b6747d10e83c9 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.yn.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.yn.stderr @@ -11,30 +11,25 @@ LL | trait Bar: ~const Foo {} | ^^^^^^^^^^^^^^^^^^^^^^^^ error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/super-traits-fail-3.rs:20:24 + --> $DIR/super-traits-fail-3.rs:22:24 | LL | const fn foo(x: &T) { | ^^^ -error[E0277]: the trait bound `T: ~const Foo` is not satisfied - --> $DIR/super-traits-fail-3.rs:22:7 - | -LL | x.a(); - | ^ the trait `Foo` is not implemented for `T` +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/super-traits-fail-3.rs:22:24 | -note: required by a bound in `Foo::a` - --> $DIR/super-traits-fail-3.rs:8:25 +LL | const fn foo(x: &T) { + | ^^^ | -LL | #[cfg_attr(any(yy, yn), const_trait)] - | ^^^^^^^^^^^ required by this bound in `Foo::a` -LL | trait Foo { -LL | fn a(&self); - | - required by a bound in this associated function -help: consider further restricting this bound + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0277]: the trait bound `T: ~const Foo` is not satisfied + --> $DIR/super-traits-fail-3.rs:25:5 | -LL | const fn foo(x: &T) { - | +++++ +LL | x.a(); + | ^^^^^ -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail.rs index da41d7fcc723a..c07619fbf621c 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail.rs @@ -1,4 +1,3 @@ -//~ ERROR the trait bound //@ compile-flags: -Znext-solver #![allow(incomplete_features)] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail.stderr index 3870f0f722f99..7a734a6c9f1ca 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail.stderr @@ -1,24 +1,9 @@ -error[E0277]: the trait bound `Bar::{synthetic#0}: TyCompat` is not satisfied - --> $DIR/super-traits-fail.rs:19:12 +error[E0277]: the trait bound `S: ~const Foo` is not satisfied + --> $DIR/super-traits-fail.rs:18:20 | LL | impl const Bar for S {} - | ^^^ the trait `TyCompat` is not implemented for `Bar::{synthetic#0}`, which is required by `S: Bar` - | - = help: the trait `Bar` is implemented for `S` -note: required for `S` to implement `Bar` - --> $DIR/super-traits-fail.rs:12:7 - | -LL | trait Bar: ~const Foo {} - | ^^^ - -error[E0277]: the trait bound `Maybe: TyCompat` is not satisfied - | -note: required by a bound in `Bar::{synthetic#0}` - --> $DIR/super-traits-fail.rs:12:12 - | -LL | trait Bar: ~const Foo {} - | ^^^^^^^^^^ required by this bound in `Bar::{synthetic#0}` + | ^ -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-and-const-params.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-and-const-params.rs index 4b720b534a49e..f6a7c7c174612 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-and-const-params.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-and-const-params.rs @@ -8,7 +8,6 @@ struct Foo; impl Foo { fn add(self) -> Foo<{ A::add(N) }> { //~^ ERROR `~const` is not allowed here - //~| ERROR mismatched types Foo } } @@ -26,7 +25,6 @@ impl const Add42 for () { fn bar(_: Foo) -> Foo<{ A::add(N) }> { //~^ ERROR `~const` is not allowed here - //~| ERROR mismatched types Foo } diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-and-const-params.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-and-const-params.stderr index 73526a26e081e..84a425f6791bd 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-and-const-params.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-and-const-params.stderr @@ -11,13 +11,13 @@ LL | fn add(self) -> Foo<{ A::add(N) }> { | ^^^ error: `~const` is not allowed here - --> $DIR/tilde-const-and-const-params.rs:27:11 + --> $DIR/tilde-const-and-const-params.rs:26:11 | LL | fn bar(_: Foo) -> Foo<{ A::add(N) }> { | ^^^^^^ | note: this function is not `const`, so it cannot have `~const` trait bounds - --> $DIR/tilde-const-and-const-params.rs:27:4 + --> $DIR/tilde-const-and-const-params.rs:26:4 | LL | fn bar(_: Foo) -> Foo<{ A::add(N) }> { | ^^^ @@ -27,24 +27,5 @@ error: using `#![feature(effects)]` without enabling next trait solver globally = note: the next trait solver must be enabled globally for the effects feature to work correctly = help: use `-Znext-solver` to enable -error[E0308]: mismatched types - --> $DIR/tilde-const-and-const-params.rs:27:61 - | -LL | fn bar(_: Foo) -> Foo<{ A::add(N) }> { - | ^^^^^^^^^ expected `false`, found `true` - | - = note: expected constant `false` - found constant `true` - -error[E0308]: mismatched types - --> $DIR/tilde-const-and-const-params.rs:9:44 - | -LL | fn add(self) -> Foo<{ A::add(N) }> { - | ^^^^^^^^^ expected `false`, found `true` - | - = note: expected constant `false` - found constant `true` - -error: aborting due to 5 previous errors +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.rs index 8ca9b7cc7aa0a..61e2bc384268a 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.rs @@ -20,11 +20,9 @@ trait Foo { const fn test1() { T::a(); T::b(); - //~^ ERROR mismatched types - //~| ERROR the trait bound + //~^ ERROR the trait bound T::c::(); - //~^ ERROR mismatched types - //~| ERROR the trait bound + //~^ ERROR the trait bound } const fn test2() { diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.stderr index eaa981ec74444..30a7ef1fd0d3f 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.stderr @@ -1,52 +1,15 @@ -error[E0277]: the trait bound `T: Foo` is not satisfied +error[E0277]: the trait bound `T: ~const Bar` is not satisfied --> $DIR/trait-where-clause-const.rs:22:5 | LL | T::b(); - | ^ the trait `Foo` is not implemented for `T` - | -note: required by a bound in `Foo::b` - --> $DIR/trait-where-clause-const.rs:13:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ required by this bound in `Foo::b` -... -LL | fn b() where Self: ~const Bar; - | - required by a bound in this associated function - -error[E0308]: mismatched types - --> $DIR/trait-where-clause-const.rs:22:5 - | -LL | T::b(); - | ^^^^^^ expected `host`, found `true` - | - = note: expected constant `host` - found constant `true` + | ^^^^^^ -error[E0277]: the trait bound `T: Foo` is not satisfied - --> $DIR/trait-where-clause-const.rs:25:5 +error[E0277]: the trait bound `T: ~const Bar` is not satisfied + --> $DIR/trait-where-clause-const.rs:24:5 | LL | T::c::(); - | ^ the trait `Foo` is not implemented for `T` - | -note: required by a bound in `Foo::c` - --> $DIR/trait-where-clause-const.rs:13:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ required by this bound in `Foo::c` -... -LL | fn c(); - | - required by a bound in this associated function - -error[E0308]: mismatched types - --> $DIR/trait-where-clause-const.rs:25:5 - | -LL | T::c::(); - | ^^^^^^^^^^^ expected `host`, found `true` - | - = note: expected constant `host` - found constant `true` + | ^^^^^^^^^^^ -error: aborting due to 4 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0277, E0308. -For more information about an error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.stderr index 848aa68689b48..e0cf062ad95e8 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.stderr @@ -6,41 +6,30 @@ LL | #![feature(const_trait_impl, effects, generic_const_exprs)] | = help: remove one of these features -error[E0308]: mismatched types +error[E0277]: the trait bound `T: const Trait` is not satisfied --> $DIR/unsatisfied-const-trait-bound.rs:29:37 | LL | fn accept0(_: Container<{ T::make() }>) {} - | ^^^^^^^^^ expected `false`, found `true` - | - = note: expected constant `false` - found constant `true` + | ^^^^^^^^^ -error[E0308]: mismatched types +error[E0277]: the trait bound `T: const Trait` is not satisfied --> $DIR/unsatisfied-const-trait-bound.rs:33:50 | LL | const fn accept1(_: Container<{ T::make() }>) {} - | ^^^^^^^^^ expected `false`, found `host` - | - = note: expected constant `false` - found constant `host` + | ^^^^^^^^^ error[E0277]: the trait bound `Ty: const Trait` is not satisfied - --> $DIR/unsatisfied-const-trait-bound.rs:22:15 + --> $DIR/unsatisfied-const-trait-bound.rs:22:5 | LL | require::(); - | ^^ the trait `Trait` is not implemented for `Ty` + | ^^^^^^^^^^^^^^^ | note: required by a bound in `require` --> $DIR/unsatisfied-const-trait-bound.rs:8:15 | LL | fn require() {} | ^^^^^^^^^^^ required by this bound in `require` -help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement - | -LL | fn main() where Ty: Trait { - | +++++++++++++++ error: aborting due to 4 previous errors -Some errors have detailed explanations: E0277, E0308. -For more information about an error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/specialization/const_trait_impl.stderr b/tests/ui/specialization/const_trait_impl.stderr index 643f1de3e8d79..746b08fa71058 100644 --- a/tests/ui/specialization/const_trait_impl.stderr +++ b/tests/ui/specialization/const_trait_impl.stderr @@ -1,23 +1,3 @@ -error[E0049]: associated function `foo` has 1 const parameter but its trait declaration has 0 const parameters - --> $DIR/const_trait_impl.rs:6:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | pub unsafe trait Sup { -LL | fn foo() -> u32; - | - expected 0 const parameters - -error[E0049]: associated function `foo` has 1 const parameter but its trait declaration has 0 const parameters - --> $DIR/const_trait_impl.rs:6:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | pub unsafe trait Sup { -LL | fn foo() -> u32; - | - expected 0 const parameters - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/const_trait_impl.rs:34:16 | @@ -36,34 +16,27 @@ error: `~const` can only be applied to `#[const_trait]` traits LL | impl const A for T { | ^^^^^^^ -error[E0049]: associated function `a` has 1 const parameter but its trait declaration has 0 const parameters - --> $DIR/const_trait_impl.rs:29:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | pub trait A { -LL | fn a() -> u32; - | - expected 0 const parameters +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/const_trait_impl.rs:40:16 + | +LL | impl const A for T { + | ^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error[E0049]: associated function `a` has 1 const parameter but its trait declaration has 0 const parameters - --> $DIR/const_trait_impl.rs:29:1 +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/const_trait_impl.rs:34:16 | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | pub trait A { -LL | fn a() -> u32; - | - expected 0 const parameters +LL | impl const A for T { + | ^^^^^^^ | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error[E0049]: associated function `a` has 1 const parameter but its trait declaration has 0 const parameters - --> $DIR/const_trait_impl.rs:29:1 +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/const_trait_impl.rs:46:16 | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | pub trait A { -LL | fn a() -> u32; - | - expected 0 const parameters +LL | impl const A for T { + | ^^^^^^^ | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` @@ -115,7 +88,6 @@ help: add `#![feature(effects)]` to the crate attributes to enable LL + #![feature(effects)] | -error: aborting due to 12 previous errors +error: aborting due to 10 previous errors -Some errors have detailed explanations: E0015, E0049. -For more information about an error, try `rustc --explain E0015`. +For more information about this error, try `rustc --explain E0015`.