diff --git a/compiler/rustc_hir_analysis/src/bounds.rs b/compiler/rustc_hir_analysis/src/bounds.rs index d0c45a7c04c7..7a919bb25005 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_clause(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 7a56b3784f8b..439e6d784283 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -181,6 +181,7 @@ fn compare_method_predicate_entailment<'tcx>( }); // Create mapping from trait method to impl method. + let impl_def_id = impl_m.container_id(tcx); let trait_to_impl_args = GenericArgs::identity_for_item(tcx, impl_m.def_id).rebase_onto( tcx, impl_m.container_id(tcx), @@ -204,6 +205,24 @@ fn compare_method_predicate_entailment<'tcx>( trait_m_predicates.instantiate_own(tcx, trait_to_impl_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 + // of the impl header and the trait method. + 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_impl_args), + ) + .map(|(trait_ref, _)| { + trait_ref.to_host_effect_clause(tcx, ty::HostPolarity::Maybe) + }), + ); + } + let normalize_cause = traits::ObligationCause::misc(impl_m_span, impl_m_def_id); 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); @@ -230,6 +249,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_identity() + { + 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_clause(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`. @@ -1846,9 +1893,10 @@ fn compare_type_predicate_entailment<'tcx>( trait_ty: ty::AssocItem, impl_trait_ref: ty::TraitRef<'tcx>, ) -> Result<(), ErrorGuaranteed> { + let impl_def_id = impl_ty.container_id(tcx); let trait_to_impl_args = GenericArgs::identity_for_item(tcx, impl_ty.def_id).rebase_onto( tcx, - impl_ty.container_id(tcx), + impl_def_id, impl_trait_ref.args, ); @@ -1856,7 +1904,9 @@ fn compare_type_predicate_entailment<'tcx>( let trait_ty_predicates = tcx.predicates_of(trait_ty.def_id); let impl_ty_own_bounds = impl_ty_predicates.instantiate_own_identity(); - if impl_ty_own_bounds.len() == 0 { + let impl_ty_own_const_conditions = + tcx.const_conditions(impl_ty.def_id).instantiate_own_identity(); + if impl_ty_own_bounds.len() == 0 && impl_ty_own_const_conditions.len() == 0 { // Nothing to check. return Ok(()); } @@ -1881,6 +1931,23 @@ fn compare_type_predicate_entailment<'tcx>( let impl_ty_span = tcx.def_span(impl_ty_def_id); let normalize_cause = ObligationCause::misc(impl_ty_span, impl_ty_def_id); + 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 + // of the impl header and the trait assoc type. + 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_clause(tcx, ty::HostPolarity::Maybe) + }), + ); + } + 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); debug!(caller_bounds=?param_env.caller_bounds()); @@ -1901,6 +1968,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 associated type. + 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_clause(tcx, ty::HostPolarity::Maybe), + )); + } + } + // Check that all obligations are satisfied by the implementation's // version. let errors = ocx.select_all_or_error(); @@ -1983,7 +2071,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)| { @@ -1991,6 +2079,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_clause(tcx, ty::HostPolarity::Maybe), + ) + }), + ); + } debug!(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 79e579841746..f0041a577424 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_clause(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 acc21d0994bf..f46b7a8bc9cc 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 69ebd3a928a3..075faea3d2aa 100644 --- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs +++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs @@ -40,7 +40,16 @@ fn associated_type_bounds<'tcx>( let mut bounds = Bounds::default(); icx.lowerer().lower_bounds(item_ty, hir_bounds, &mut bounds, ty::List::empty(), 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); + } + // `ConstIfConst` is only interested in `~const` bounds. + 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); @@ -109,10 +118,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(); @@ -308,7 +326,17 @@ fn opaque_type_bounds<'tcx>( let mut bounds = Bounds::default(); icx.lowerer().lower_bounds(item_ty, hir_bounds, &mut bounds, ty::List::empty(), 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); + } + //`ConstIfConst` is only interested in `~const` bounds. + 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 f9460ed5b473..ec5773d174f8 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; @@ -685,29 +686,76 @@ pub(super) fn assert_only_contains_predicates_from<'tcx>( assert_eq!( trait_predicate.self_ty(), ty, - "expected `Self` predicate when computing `{filter:?}` implied bounds: {clause:?}" + "expected `Self` predicate when computing \ + `{filter:?}` implied bounds: {clause:?}" ); } ty::ClauseKind::Projection(projection_predicate) => { assert_eq!( projection_predicate.self_ty(), ty, - "expected `Self` predicate when computing `{filter:?}` implied bounds: {clause:?}" + "expected `Self` predicate when computing \ + `{filter:?}` implied bounds: {clause:?}" ); } ty::ClauseKind::TypeOutlives(outlives_predicate) => { assert_eq!( outlives_predicate.0, ty, - "expected `Self` predicate when computing `{filter:?}` implied bounds: {clause:?}" + "expected `Self` predicate when computing \ + `{filter:?}` implied bounds: {clause:?}" ); } 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:?}" + "unexpected non-`Self` predicate when computing \ + `{filter:?}` implied bounds: {clause:?}" + ); + } + } + } + } + PredicateFilter::ConstIfConst => { + for (clause, _) in bounds { + match clause.kind().skip_binder() { + ty::ClauseKind::HostEffect(ty::HostEffectPredicate { + trait_ref: _, + host: ty::HostPolarity::Maybe, + }) => {} + _ => { + 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.host, + ty::HostPolarity::Maybe, + "expected `~const` predicate when computing `{filter:?}` \ + implied bounds: {clause:?}", + ); + 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:?}" ); } } @@ -829,3 +877,184 @@ 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 { .. } => { + // FIXME(effects): Should be using a dedicated function to + // test if this is a const trait impl. + if tcx.constness(def_id) != hir::Constness::Const { + 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 => { + // FIXME(effects): Should be using a dedicated function to + // test if this is a const trait impl. + if tcx.constness(parent_def_id) != hir::Constness::Const { + return Default::default(); + } + } + } + } + DefKind::Closure | DefKind::OpaqueTy => { + // Closures and RPITs will eventually have const conditions + // for `~const` bounds. + return Default::default(); + } + _ => return Default::default(), + } + } + + let (generics, trait_def_id_and_supertraits, 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(), + }, + // While associated types are not really const, we do allow them to have `~const` + // bounds and where clauses. `const_conditions` is responsible for gathering + // these up so we can check them in `compare_type_predicate_entailment`, and + // in `HostEffect` goal computation. + Node::TraitItem(item) => match item.kind { + hir::TraitItemKind::Fn(_, _) | hir::TraitItemKind::Type(_, _) => { + (item.generics, None, true) + } + _ => return Default::default(), + }, + Node::ImplItem(item) => match item.kind { + hir::ImplItemKind::Fn(_, _) | hir::ImplItemKind::Type(_) => (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_bounds( + ty, + bound_pred.bounds.iter(), + &mut bounds, + bound_vars, + PredicateFilter::ConstIfConst, + ); + } + _ => {} + } + } + + if let Some((def_id, supertraits)) = trait_def_id_and_supertraits { + 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_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) + } + Node::OpaqueTy(..) => { + // We should eventually collect the `~const` bounds on opaques. + return ty::EarlyBinder::bind(&[]); + } + _ => 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 2b0e1350108f..c902e85c2673 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs @@ -154,7 +154,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() @@ -193,6 +192,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { ); } hir::GenericBound::Outlives(lifetime) => { + // `ConstIfConst` is only interested in `~const` bounds. + if matches!( + predicate_filter, + PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst + ) { + continue; + } + let region = self.lower_lifetime(lifetime, RegionInferReason::OutlivesBound); bounds.push_region_bound( self.tcx(), @@ -392,21 +399,31 @@ 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, + ); + } + // `ConstIfConst` is only interested in `~const` bounds. + 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` @@ -421,6 +438,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 2cee7c77aa53..3449270564a7 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 @@ -78,7 +78,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 d2636c1573e0..863c077a9e03 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,49 @@ 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 { + Some(ty::BoundConstness::Const) => { + if polarity == ty::PredicatePolarity::Positive { + bounds.push_const_bound( + tcx, + poly_trait_ref, + ty::HostPolarity::Const, + span, + ); + } + } + Some(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. + } + None => {} + } + } + // On the flip side, when filtering `ConstIfConst` bounds, we only need to convert + // `~const` bounds. All other predicates are handled in their respective queries. + // + // Note that like `PredicateFilter::SelfOnly`, we don't need to do any filtering + // here because we only call this on self bounds, and deal with the recursive case + // in `lower_assoc_item_constraint`. + PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst => match constness { + Some(ty::BoundConstness::ConstIfConst) => { + if polarity == ty::PredicatePolarity::Positive { + bounds.push_const_bound(tcx, poly_trait_ref, ty::HostPolarity::Maybe, span); + } + } + None | Some(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 0355adfcb11e..a394fc2fbb19 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 f576499ecac3..2c1d443f9512 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 b642ba03aee2..081cb8c18e65 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -836,14 +836,51 @@ 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, + }; + + // FIXME(effects): Should this be `is_const_fn_raw`? It depends on if we move + // const stability checking here too, I guess. + 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_clause(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 693cb4465cc1..eb5fe3a86e4c 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 b60fa8bbfa14..569fdea11ce7 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 e23bb1aaa563..1afe50e336da 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 71c667b2cd6b..cf889e958a9d 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 d4cbf6e13afb..71c7231a7882 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 80b979fe088f..a71d1993c6c1 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 8da1be805446..a00ca27aacc0 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 48bf4ffced0c..5f8427bd707a 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 0b751779501d..d03fc39c9ade 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 7e533bc4291a..ef9dfdd2f962 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 281899647efb..c8fe6cbf4c65 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)] @@ -383,6 +383,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() } @@ -2189,7 +2211,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 39899f1d32be..704a197aa49d 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 e24a3f281fc5..ab1b8fa6a732 100644 --- a/compiler/rustc_middle/src/ty/generics.rs +++ b/compiler/rustc_middle/src/ty/generics.rs @@ -422,3 +422,73 @@ 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)> + DoubleEndedIterator + ExactSizeIterator + { + 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 ed24fcc7eb88..84e1897019e7 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 7e1255f606c3..43bdce5b576d 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 d20cb368278b..3ecaa3e22d39 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 10c3522eb0e9..0248aad53e24 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -3075,6 +3075,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)) } @@ -3087,6 +3096,7 @@ define_print! { ty::ClauseKind::RegionOutlives(predicate) => p!(print(predicate)), ty::ClauseKind::TypeOutlives(predicate) => p!(print(predicate)), ty::ClauseKind::Projection(predicate) => p!(print(predicate)), + ty::ClauseKind::HostEffect(predicate) => p!(print(predicate)), ty::ClauseKind::ConstArgHasType(ct, ty) => { p!("the constant `", print(ct), "` has type `", print(ty), "`") }, 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 000000000000..62b4bb0004ca --- /dev/null +++ b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs @@ -0,0 +1,296 @@ +//! Dealing with host effect goals, i.e. enforcing the constness in +//! `T: const Trait` or `T: ~const Trait`. + +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().satisfies(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 const trait: {:?}", 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_clause(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 250174e033e3..7608253882a2 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 b7fdc339be5c..6793779b205d 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 7827975d3caf..05954143aee0 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 0abc89ddb81a..8f05f859c077 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 b0175fff8a7f..b7e2ed391cd4 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 @@ -156,8 +156,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { (leaf_trait_predicate, &obligation) }; - let (main_trait_predicate, leaf_trait_predicate, predicate_constness) = self.get_effects_trait_pred_override(main_trait_predicate, leaf_trait_predicate, span); - let main_trait_ref = main_trait_predicate.to_poly_trait_ref(); let leaf_trait_ref = leaf_trait_predicate.to_poly_trait_ref(); @@ -228,7 +226,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let err_msg = self.get_standard_error_message( main_trait_predicate, message, - predicate_constness, + None, append_const_msg, post_message, ); @@ -289,13 +287,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { ); } - if tcx.is_lang_item(leaf_trait_ref.def_id(), LangItem::Drop) - && matches!(predicate_constness, Some(ty::BoundConstness::ConstIfConst | ty::BoundConstness::Const)) - { - err.note("`~const Drop` was renamed to `~const Destruct`"); - err.note("See for more details"); - } - let explanation = get_explanation_based_on_obligation( self.tcx, &obligation, @@ -541,6 +532,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, + Some(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`, @@ -2374,16 +2388,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { }) } - // FIXME(effects): Remove this. - fn get_effects_trait_pred_override( - &self, - p: ty::PolyTraitPredicate<'tcx>, - leaf: ty::PolyTraitPredicate<'tcx>, - _span: Span, - ) -> (ty::PolyTraitPredicate<'tcx>, ty::PolyTraitPredicate<'tcx>, ty::BoundConstness) { - (p, leaf, ty::BoundConstness::NotConst) - } - fn add_tuple_trait_message( &self, obligation_cause_code: &ObligationCauseCode<'tcx>, diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index 12aeee0d02fe..934fe9ec47c0 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 cc0450e0b057..a068f25fe35e 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 ca9e6cd662d9..1754418156d9 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 dfd0cab69058..c6e41e57f0ce 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 4d7e2769af5f..ec4114fd9d72 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 8904a9a68580..437343b569c4 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 f01a12b0a00c..3e2794f6489f 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 28a81b1b0621..ac2708a29f4a 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -150,6 +150,15 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> { }); } + // We extend the param-env of our item with the const conditions of the item, + // since we're allowed to assume `~const` bounds hold within the item itself. + predicates.extend( + tcx.const_conditions(def_id) + .instantiate_identity(tcx) + .into_iter() + .map(|(trait_ref, _)| trait_ref.to_host_effect_clause(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 56a72f943ab4..72d392ecd7bd 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_clause(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 02ec29a7f3d5..5af1aa2f8faa 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 4184e9e313ff..6a8113b38b7b 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -24,6 +24,7 @@ pub trait Interner: + IrPrint> + IrPrint> + IrPrint> + + IrPrint> + IrPrint> + IrPrint> + IrPrint> @@ -228,6 +229,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 d57d0816680b..0c71f3a3df2a 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 e8ce39be3e50..c31645503487 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_clause(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)] @@ -745,6 +752,64 @@ 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)] +#[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, +} + +impl HostPolarity { + pub fn satisfies(self, goal: HostPolarity) -> bool { + match (self, goal) { + (HostPolarity::Const, HostPolarity::Const | HostPolarity::Maybe) => true, + (HostPolarity::Maybe, HostPolarity::Maybe) => true, + (HostPolarity::Maybe, HostPolarity::Const) => false, + } + } +} + /// 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 46202dbb0f27..21f4456abd11 100644 --- a/compiler/rustc_type_ir/src/predicate_kind.rs +++ b/compiler/rustc_type_ir/src/predicate_kind.rs @@ -37,6 +37,12 @@ pub enum ClauseKind { /// Constant initializer must evaluate successfully. ConstEvaluatable(I::Const), + + /// Enforces the constness of the predicate we're calling. Like a projection + /// goal from a where clause, it's always going to be paired with a + /// corresponding trait clause; this just enforces the *constness* of that + /// implementation. + HostEffect(ty::HostEffectPredicate), } #[derive_where(Clone, Copy, Hash, PartialEq, Eq; I: Interner)] @@ -110,6 +116,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 861ca70cd83d..81264b49dfd0 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/crashes/118320.rs b/tests/crashes/118320.rs deleted file mode 100644 index 093c58e1c05f..000000000000 --- a/tests/crashes/118320.rs +++ /dev/null @@ -1,14 +0,0 @@ -//@ known-bug: #118320 -//@ edition:2021 -#![feature(const_trait_impl, effects, const_closures)] - -#[const_trait] -trait Bar { - fn foo(&self); -} - -impl Bar for () {} - -const FOO: () = { - (const || (()).foo())(); -}; diff --git a/tests/crashes/119924-6.rs b/tests/crashes/119924-6.rs deleted file mode 100644 index f1cc9d291591..000000000000 --- a/tests/crashes/119924-6.rs +++ /dev/null @@ -1,15 +0,0 @@ -//@ known-bug: #119924 -//@ compile-flags: -Znext-solver -#![feature(const_trait_impl, effects)] - -struct S; -#[const_trait] -trait Trait {} - -const fn f>(U); // should've gotten rejected during AST validation - //~^ ICE no host param id for call in const yet no errors reported - 0 -}>>() {} - -pub fn main() {} diff --git a/tests/ui/const-generics/issues/issue-88119.stderr b/tests/ui/const-generics/issues/issue-88119.stderr index 98bb81968100..a0ca33e38ef8 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 42a42ae3938b..8cb91d78f6ca 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 7de10f0287b4..2195cab3f4d0 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` + | ^^^^^^ calling non-const function `<() as Tr>::a` -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` +error: aborting due to 2 previous errors -error: aborting due to 3 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 218c90f89a9e..2b012432afd4 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,6 +66,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: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 | @@ -64,6 +96,14 @@ 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 + | +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:34: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 6c83eff4de01..59476f986032 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 ee2bf9e33eb8..b2b3c61a722b 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 bd0bc970b94c..74c4b5cd949a 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 e57effff48d8..56296db85a3f 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 6a627be3b64e..1c79a603503f 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 e0d193b5d402..f1e6207ed817 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/specialization/const_trait_impl.stderr b/tests/ui/specialization/const_trait_impl.stderr index 643f1de3e8d7..746b08fa7105 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 +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/const_trait_impl.rs:40:16 | -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/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 +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: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/const_trait_impl.rs:46:16 + | +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`. diff --git a/tests/ui/traits/const-traits/assoc-type-const-bound-usage-0.stderr b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-0.stderr index 8288c660ce7c..20448f51de22 100644 --- a/tests/ui/traits/const-traits/assoc-type-const-bound-usage-0.stderr +++ b/tests/ui/traits/const-traits/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: aborting due to 1 previous error -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 - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/const-traits/assoc-type-const-bound-usage-1.stderr b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-1.stderr index 0792d090321d..20448f51de22 100644 --- a/tests/ui/traits/const-traits/assoc-type-const-bound-usage-1.stderr +++ b/tests/ui/traits/const-traits/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: aborting due to 1 previous error -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 - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/const-traits/call-const-trait-method-fail.stderr b/tests/ui/traits/const-traits/call-const-trait-method-fail.stderr index 5d2333d94fe8..40a06af85edc 100644 --- a/tests/ui/traits/const-traits/call-const-trait-method-fail.stderr +++ b/tests/ui/traits/const-traits/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/traits/const-traits/call-const-trait-method-pass.stderr b/tests/ui/traits/const-traits/call-const-trait-method-pass.stderr index bf455a714a34..c1cead542163 100644 --- a/tests/ui/traits/const-traits/call-const-trait-method-pass.stderr +++ b/tests/ui/traits/const-traits/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/traits/const-traits/call-generic-in-impl.stderr b/tests/ui/traits/const-traits/call-generic-in-impl.stderr index 5cd274c6c5a2..368c22675e7f 100644 --- a/tests/ui/traits/const-traits/call-generic-in-impl.stderr +++ b/tests/ui/traits/const-traits/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 | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | trait MyPartialEq { -LL | fn eq(&self, other: &Self) -> bool; - | - expected 0 const parameters +LL | impl const MyPartialEq for T { + | ^^^^^^^^^ + | + = 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/traits/const-traits/call-generic-method-chain.stderr b/tests/ui/traits/const-traits/call-generic-method-chain.stderr index 57d57dfd5b93..dce9f0853904 100644 --- a/tests/ui/traits/const-traits/call-generic-method-chain.stderr +++ b/tests/ui/traits/const-traits/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/traits/const-traits/call-generic-method-dup-bound.stderr b/tests/ui/traits/const-traits/call-generic-method-dup-bound.stderr index 0088ed2eb13d..5da511a580e2 100644 --- a/tests/ui/traits/const-traits/call-generic-method-dup-bound.stderr +++ b/tests/ui/traits/const-traits/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/traits/const-traits/call-generic-method-nonconst.stderr b/tests/ui/traits/const-traits/call-generic-method-nonconst.stderr index 68c9fc400104..06b99375cdaa 100644 --- a/tests/ui/traits/const-traits/call-generic-method-nonconst.stderr +++ b/tests/ui/traits/const-traits/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/traits/const-traits/call-generic-method-pass.stderr b/tests/ui/traits/const-traits/call-generic-method-pass.stderr index 4a6100c3c1aa..52579813b691 100644 --- a/tests/ui/traits/const-traits/call-generic-method-pass.stderr +++ b/tests/ui/traits/const-traits/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/traits/const-traits/const-bounds-non-const-trait.rs b/tests/ui/traits/const-traits/const-bounds-non-const-trait.rs index db446f8bc2ea..d51d231b8a97 100644 --- a/tests/ui/traits/const-traits/const-bounds-non-const-trait.rs +++ b/tests/ui/traits/const-traits/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/traits/const-traits/const-bounds-non-const-trait.stderr b/tests/ui/traits/const-traits/const-bounds-non-const-trait.stderr index e1a85fc54144..6c3c11c6a475 100644 --- a/tests/ui/traits/const-traits/const-bounds-non-const-trait.stderr +++ b/tests/ui/traits/const-traits/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/traits/const-traits/const-closure-trait-method-fail.stderr b/tests/ui/traits/const-traits/const-closure-trait-method-fail.stderr index 507ceaae2eab..4e6707bba51c 100644 --- a/tests/ui/traits/const-traits/const-closure-trait-method-fail.stderr +++ b/tests/ui/traits/const-traits/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 +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/const-closure-trait-method-fail.rs:14:39 | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | trait Tr { -LL | fn a(self) -> i32; - | - expected 0 const parameters +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/traits/const-traits/const-closure-trait-method.stderr b/tests/ui/traits/const-traits/const-closure-trait-method.stderr index 2a54cd5d7f6e..0f0cd73cc102 100644 --- a/tests/ui/traits/const-traits/const-closure-trait-method.stderr +++ b/tests/ui/traits/const-traits/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 +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/const-closure-trait-method.rs:14:39 | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | trait Tr { -LL | fn a(self) -> i32; - | - expected 0 const parameters +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/traits/const-traits/const-closures.stderr b/tests/ui/traits/const-traits/const-closures.stderr index a0f053253892..4d354cb281fe 100644 --- a/tests/ui/traits/const-traits/const-closures.stderr +++ b/tests/ui/traits/const-traits/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/traits/const-traits/const-default-method-bodies.stderr b/tests/ui/traits/const-traits/const-default-method-bodies.stderr index 0809d9c1e1d3..071eaf495418 100644 --- a/tests/ui/traits/const-traits/const-default-method-bodies.stderr +++ b/tests/ui/traits/const-traits/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/traits/const-traits/const-drop-bound.stderr b/tests/ui/traits/const-traits/const-drop-bound.stderr index be197006f021..d94b0542324f 100644 --- a/tests/ui/traits/const-traits/const-drop-bound.stderr +++ b/tests/ui/traits/const-traits/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/traits/const-traits/const-drop-fail-2.stderr b/tests/ui/traits/const-traits/const-drop-fail-2.stderr index faf24c6d9114..27e8053c9690 100644 --- a/tests/ui/traits/const-traits/const-drop-fail-2.stderr +++ b/tests/ui/traits/const-traits/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/traits/const-traits/const-drop-fail.precise.stderr b/tests/ui/traits/const-traits/const-drop-fail.precise.stderr index 3d400bf01587..bde13b4d6cfa 100644 --- a/tests/ui/traits/const-traits/const-drop-fail.precise.stderr +++ b/tests/ui/traits/const-traits/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/traits/const-traits/const-drop-fail.stock.stderr b/tests/ui/traits/const-traits/const-drop-fail.stock.stderr index fd0f6d02684a..064ffacca427 100644 --- a/tests/ui/traits/const-traits/const-drop-fail.stock.stderr +++ b/tests/ui/traits/const-traits/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/traits/const-traits/const-drop.precise.stderr b/tests/ui/traits/const-traits/const-drop.precise.stderr index dd3ea5d241d7..7b6d185c7cc8 100644 --- a/tests/ui/traits/const-traits/const-drop.precise.stderr +++ b/tests/ui/traits/const-traits/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 +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 - -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 +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/traits/const-traits/const-drop.stock.stderr b/tests/ui/traits/const-traits/const-drop.stock.stderr index aa59e1c8dc49..b497c39b08aa 100644 --- a/tests/ui/traits/const-traits/const-drop.stock.stderr +++ b/tests/ui/traits/const-traits/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 +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 - -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 +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/traits/const-traits/const-fns-are-early-bound.rs b/tests/ui/traits/const-traits/const-fns-are-early-bound.rs index 59a61e4f954d..6d08d8bdd919 100644 --- a/tests/ui/traits/const-traits/const-fns-are-early-bound.rs +++ b/tests/ui/traits/const-traits/const-fns-are-early-bound.rs @@ -1,4 +1,6 @@ //@ known-bug: #110395 +//@ failure-status: 101 +//@ dont-check-compiler-stderr // FIXME(effects) check-pass //@ compile-flags: -Znext-solver diff --git a/tests/ui/traits/const-traits/const-fns-are-early-bound.stderr b/tests/ui/traits/const-traits/const-fns-are-early-bound.stderr deleted file mode 100644 index 9eda9d98ec55..000000000000 --- a/tests/ui/traits/const-traits/const-fns-are-early-bound.stderr +++ /dev/null @@ -1,20 +0,0 @@ -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` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/const-traits/const-impl-trait.stderr b/tests/ui/traits/const-traits/const-impl-trait.stderr deleted file mode 100644 index 1040af7541c0..000000000000 --- a/tests/ui/traits/const-traits/const-impl-trait.stderr +++ /dev/null @@ -1,249 +0,0 @@ -error[E0635]: unknown feature `const_cmp` - --> $DIR/const-impl-trait.rs:8:5 - | -LL | const_cmp, - | ^^^^^^^^^ - -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: `~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 { - | ^^^^^^^^^ - -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) - | ^^^^^^^^^ - -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) - | ^^^^^^^^ - -error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/const-impl-trait.rs:18:20 - | -LL | -> impl ~const PartialEq + ~const Destruct - | ^^^^^^^^^ - -error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/const-impl-trait.rs:18:39 - | -LL | -> impl ~const PartialEq + ~const Destruct - | ^^^^^^^^ - -error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/const-impl-trait.rs:18:20 - | -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:18:39 - | -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:25:29 - | -LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy; - | ^^^^^^^^^ - -error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/const-impl-trait.rs:25:48 - | -LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy; - | ^^^^^^^^ - -error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/const-impl-trait.rs:29:29 - | -LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy { - | ^^^^^^^^^ - -error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/const-impl-trait.rs:29:48 - | -LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy { - | ^^^^^^^^ - -error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/const-impl-trait.rs:29:29 - | -LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy { - | ^^^^^^^^^ - | - = 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:29:48 - | -LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy { - | ^^^^^^^^ - | - = 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:50:41 - | -LL | const fn apit(_: impl ~const T + ~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) {} - | ^^^^^^^^ - -error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/const-impl-trait.rs:25:29 - | -LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy; - | ^^^^^^^^^ - | - = 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:48 - | -LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy; - | ^^^^^^^^ - | - = 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 - | -LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy; - | ^^^^^^^^^ - | - = 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:48 - | -LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy; - | ^^^^^^^^ - | - = 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 - | -LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy; - | ^^^^^^^^^ - | - = 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:48 - | -LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy; - | ^^^^^^^^ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0493]: destructor of `impl PartialEq + Destruct` cannot be evaluated at compile-time - --> $DIR/const-impl-trait.rs:37:26 - | -LL | assert!(wrap(123) == wrap(123)); - | ^^^^^^^^^- value is dropped here - | | - | the destructor for this type cannot be evaluated in constants - -error[E0493]: destructor of `impl PartialEq + Destruct` cannot be evaluated at compile-time - --> $DIR/const-impl-trait.rs:37:26 - | -LL | assert!(wrap(123) == wrap(123)); - | ^^^^^^^^^- value is dropped here - | | - | the destructor for this type cannot be evaluated in constants - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0493]: destructor of `impl PartialEq + Destruct` cannot be evaluated at compile-time - --> $DIR/const-impl-trait.rs:37:13 - | -LL | assert!(wrap(123) == wrap(123)); - | ^^^^^^^^^ - value is dropped here - | | - | the destructor for this type cannot be evaluated in constants - -error[E0493]: destructor of `impl PartialEq + Destruct` cannot be evaluated at compile-time - --> $DIR/const-impl-trait.rs:37:13 - | -LL | assert!(wrap(123) == wrap(123)); - | ^^^^^^^^^ - value is dropped here - | | - | the destructor for this type cannot be evaluated in constants - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0493]: destructor of `impl PartialEq + Destruct` cannot be evaluated at compile-time - --> $DIR/const-impl-trait.rs:38:26 - | -LL | assert!(wrap(123) != wrap(456)); - | ^^^^^^^^^- value is dropped here - | | - | the destructor for this type cannot be evaluated in constants - -error[E0493]: destructor of `impl PartialEq + Destruct` cannot be evaluated at compile-time - --> $DIR/const-impl-trait.rs:38:26 - | -LL | assert!(wrap(123) != wrap(456)); - | ^^^^^^^^^- value is dropped here - | | - | the destructor for this type cannot be evaluated in constants - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0493]: destructor of `impl PartialEq + Destruct` cannot be evaluated at compile-time - --> $DIR/const-impl-trait.rs:38:13 - | -LL | assert!(wrap(123) != wrap(456)); - | ^^^^^^^^^ - value is dropped here - | | - | the destructor for this type cannot be evaluated in constants - -error[E0493]: destructor of `impl PartialEq + Destruct` cannot be evaluated at compile-time - --> $DIR/const-impl-trait.rs:38:13 - | -LL | assert!(wrap(123) != wrap(456)); - | ^^^^^^^^^ - value is dropped here - | | - | the destructor for this type cannot be evaluated in constants - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0493]: destructor of `impl ~const T + ~const Destruct` cannot be evaluated at compile-time - --> $DIR/const-impl-trait.rs:50:15 - | -LL | const fn apit(_: impl ~const T + ~const Destruct) {} - | ^ - value is dropped here - | | - | the destructor for this type cannot be evaluated in constant functions - -error[E0493]: destructor of `impl IntoIterator + ~const Destruct` cannot be evaluated at compile-time - --> $DIR/const-impl-trait.rs:54:27 - | -LL | const fn apit_assoc_bound(_: impl IntoIterator + ~const Destruct) {} - | ^ - value is dropped here - | | - | the destructor for this type cannot be evaluated in constant functions - -error: aborting due to 33 previous errors - -Some errors have detailed explanations: E0493, E0635. -For more information about an error, try `rustc --explain E0493`. diff --git a/tests/ui/traits/const-traits/const_derives/derive-const-with-params.stderr b/tests/ui/traits/const-traits/const_derives/derive-const-with-params.stderr index addce8dcd6c7..3388ee30a5d3 100644 --- a/tests/ui/traits/const-traits/const_derives/derive-const-with-params.stderr +++ b/tests/ui/traits/const-traits/const_derives/derive-const-with-params.stderr @@ -30,5 +30,14 @@ LL | #[derive_const(PartialEq)] | = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 3 previous errors; 1 warning emitted +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/derive-const-with-params.rs:7:16 + | +LL | #[derive_const(PartialEq)] + | ^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 4 previous errors; 1 warning emitted diff --git a/tests/ui/traits/const-traits/cross-crate.gatednc.stderr b/tests/ui/traits/const-traits/cross-crate.gatednc.stderr index a34bae843c81..b6f2434140d6 100644 --- a/tests/ui/traits/const-traits/cross-crate.gatednc.stderr +++ b/tests/ui/traits/const-traits/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/traits/const-traits/default-method-body-is-const-same-trait-ck.stderr b/tests/ui/traits/const-traits/default-method-body-is-const-same-trait-ck.stderr index d0f22c0b9b62..7b4d512e3918 100644 --- a/tests/ui/traits/const-traits/default-method-body-is-const-same-trait-ck.stderr +++ b/tests/ui/traits/const-traits/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/traits/const-traits/effects/minicore.stderr b/tests/ui/traits/const-traits/effects/minicore.stderr index 823ab69df9cb..568d98cfe871 100644 --- a/tests/ui/traits/const-traits/effects/minicore.stderr +++ b/tests/ui/traits/const-traits/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/traits/const-traits/effects/no-explicit-const-params-cross-crate.stderr b/tests/ui/traits/const-traits/effects/no-explicit-const-params-cross-crate.stderr index 8c591edac540..eea6a06c1c81 100644 --- a/tests/ui/traits/const-traits/effects/no-explicit-const-params-cross-crate.stderr +++ b/tests/ui/traits/const-traits/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/traits/const-traits/effects/no-explicit-const-params.rs b/tests/ui/traits/const-traits/effects/no-explicit-const-params.rs index 84f5f2803e15..b08aba9acbcd 100644 --- a/tests/ui/traits/const-traits/effects/no-explicit-const-params.rs +++ b/tests/ui/traits/const-traits/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/traits/const-traits/effects/no-explicit-const-params.stderr b/tests/ui/traits/const-traits/effects/no-explicit-const-params.stderr index cc08114ddb56..a3aa970e94d2 100644 --- a/tests/ui/traits/const-traits/effects/no-explicit-const-params.stderr +++ b/tests/ui/traits/const-traits/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/traits/const-traits/effects/spec-effectvar-ice.rs b/tests/ui/traits/const-traits/effects/spec-effectvar-ice.rs index 0508b1c5e26b..73d3e883aad9 100644 --- a/tests/ui/traits/const-traits/effects/spec-effectvar-ice.rs +++ b/tests/ui/traits/const-traits/effects/spec-effectvar-ice.rs @@ -1,4 +1,3 @@ -//@ check-fail // Fixes #119830 #![feature(effects)] //~ WARN the feature `effects` is incomplete @@ -15,7 +14,9 @@ impl const Foo for T {} impl const Foo for T where T: const Specialize {} //~^ error: const `impl` for trait `Foo` which is not marked with `#[const_trait]` //~| error: `const` can only be applied to `#[const_trait]` traits +//~| 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/traits/const-traits/effects/spec-effectvar-ice.stderr b/tests/ui/traits/const-traits/effects/spec-effectvar-ice.stderr index e97a9615ae1a..2556903150b4 100644 --- a/tests/ui/traits/const-traits/effects/spec-effectvar-ice.stderr +++ b/tests/ui/traits/const-traits/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,42 @@ 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: `const` can only be applied to `#[const_trait]` traits + --> $DIR/spec-effectvar-ice.rs:14:40 + | +LL | impl const Foo for T where T: const Specialize {} + | ^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + 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 trait `Specialize` - --> $DIR/spec-effectvar-ice.rs:15:34 +error: cannot specialize on predicate `T: const Specialize` + --> $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: cannot specialize on trait `Specialize` + --> $DIR/spec-effectvar-ice.rs:14:34 + | +LL | impl const Foo for T where T: const Specialize {} + | ^^^^^^^^^^^^^^^^ + +error: aborting due to 8 previous errors; 1 warning emitted diff --git a/tests/ui/traits/const-traits/ice-123664-unexpected-bound-var.rs b/tests/ui/traits/const-traits/ice-123664-unexpected-bound-var.rs index 64634e7b7ac3..29f40604747b 100644 --- a/tests/ui/traits/const-traits/ice-123664-unexpected-bound-var.rs +++ b/tests/ui/traits/const-traits/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/traits/const-traits/ice-123664-unexpected-bound-var.stderr b/tests/ui/traits/const-traits/ice-123664-unexpected-bound-var.stderr index c937430a1ca1..03f88be00936 100644 --- a/tests/ui/traits/const-traits/ice-123664-unexpected-bound-var.stderr +++ b/tests/ui/traits/const-traits/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/traits/const-traits/issue-92111.stderr b/tests/ui/traits/const-traits/issue-92111.stderr index ecc994a3fe65..805cc5370149 100644 --- a/tests/ui/traits/const-traits/issue-92111.stderr +++ b/tests/ui/traits/const-traits/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/traits/const-traits/non-const-op-in-closure-in-const.stderr b/tests/ui/traits/const-traits/non-const-op-in-closure-in-const.stderr index de4783bdb3fe..2803c37646b1 100644 --- a/tests/ui/traits/const-traits/non-const-op-in-closure-in-const.stderr +++ b/tests/ui/traits/const-traits/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 | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | trait Convert { -LL | fn to(self) -> T; - | - expected 0 const parameters +LL | impl const Convert for A where B: ~const From { + | ^^^^^^^ + | + = 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/traits/const-traits/specialization/const-default-bound-non-const-specialized-bound.stderr b/tests/ui/traits/const-traits/specialization/const-default-bound-non-const-specialized-bound.stderr index 7643697874f2..bffc60c65fce 100644 --- a/tests/ui/traits/const-traits/specialization/const-default-bound-non-const-specialized-bound.stderr +++ b/tests/ui/traits/const-traits/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: aborting due to 1 previous error -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 - -For more information about this error, try `rustc --explain E0049`. diff --git a/tests/ui/traits/const-traits/specialization/const-default-const-specialized.stderr b/tests/ui/traits/const-traits/specialization/const-default-const-specialized.stderr index 9b2ae8d739c8..f127268d2a1c 100644 --- a/tests/ui/traits/const-traits/specialization/const-default-const-specialized.stderr +++ b/tests/ui/traits/const-traits/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/traits/const-traits/specialization/default-keyword.rs b/tests/ui/traits/const-traits/specialization/default-keyword.rs index d9ffd237dcef..bc45a70777ca 100644 --- a/tests/ui/traits/const-traits/specialization/default-keyword.rs +++ b/tests/ui/traits/const-traits/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/traits/const-traits/specialization/default-keyword.stderr b/tests/ui/traits/const-traits/specialization/default-keyword.stderr deleted file mode 100644 index 18a25045f4b0..000000000000 --- a/tests/ui/traits/const-traits/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/traits/const-traits/specialization/issue-95186-specialize-on-tilde-const.rs b/tests/ui/traits/const-traits/specialization/issue-95186-specialize-on-tilde-const.rs index 219e5f3a600c..d80370aee820 100644 --- a/tests/ui/traits/const-traits/specialization/issue-95186-specialize-on-tilde-const.rs +++ b/tests/ui/traits/const-traits/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/traits/const-traits/specialization/issue-95186-specialize-on-tilde-const.stderr b/tests/ui/traits/const-traits/specialization/issue-95186-specialize-on-tilde-const.stderr deleted file mode 100644 index ecdc7b930e60..000000000000 --- a/tests/ui/traits/const-traits/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/traits/const-traits/specialization/issue-95187-same-trait-bound-different-constness.rs b/tests/ui/traits/const-traits/specialization/issue-95187-same-trait-bound-different-constness.rs index 7514baa2fd55..d97469edaf97 100644 --- a/tests/ui/traits/const-traits/specialization/issue-95187-same-trait-bound-different-constness.rs +++ b/tests/ui/traits/const-traits/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/traits/const-traits/specialization/issue-95187-same-trait-bound-different-constness.stderr b/tests/ui/traits/const-traits/specialization/issue-95187-same-trait-bound-different-constness.stderr deleted file mode 100644 index 6679bb465378..000000000000 --- a/tests/ui/traits/const-traits/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/traits/const-traits/specialization/non-const-default-const-specialized.stderr b/tests/ui/traits/const-traits/specialization/non-const-default-const-specialized.stderr index 7f363922947f..a4095d7e8ce5 100644 --- a/tests/ui/traits/const-traits/specialization/non-const-default-const-specialized.stderr +++ b/tests/ui/traits/const-traits/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/traits/const-traits/specializing-constness-2.stderr b/tests/ui/traits/const-traits/specializing-constness-2.stderr index bf273f349b4b..8e6f6945a1b8 100644 --- a/tests/ui/traits/const-traits/specializing-constness-2.stderr +++ b/tests/ui/traits/const-traits/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/traits/const-traits/specializing-constness.rs b/tests/ui/traits/const-traits/specializing-constness.rs index 4501a218ad72..3aabaf137d54 100644 --- a/tests/ui/traits/const-traits/specializing-constness.rs +++ b/tests/ui/traits/const-traits/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/traits/const-traits/specializing-constness.stderr b/tests/ui/traits/const-traits/specializing-constness.stderr index 90721af8e5aa..e8c4fb0f0c72 100644 --- a/tests/ui/traits/const-traits/specializing-constness.stderr +++ b/tests/ui/traits/const-traits/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/traits/const-traits/super-traits-fail-2.ny.stderr b/tests/ui/traits/const-traits/super-traits-fail-2.ny.stderr index 029c3b4bde3e..a0848fe520e8 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-2.ny.stderr +++ b/tests/ui/traits/const-traits/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/traits/const-traits/super-traits-fail-2.rs b/tests/ui/traits/const-traits/super-traits-fail-2.rs index 93a6f385e47d..0ea61f4ae200 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-2.rs +++ b/tests/ui/traits/const-traits/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/traits/const-traits/super-traits-fail-2.yn.stderr b/tests/ui/traits/const-traits/super-traits-fail-2.yn.stderr index 873c57ec71ff..ec6ca1072890 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-2.yn.stderr +++ b/tests/ui/traits/const-traits/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/traits/const-traits/super-traits-fail-2.yy.stderr b/tests/ui/traits/const-traits/super-traits-fail-2.yy.stderr index bea3aea2f3af..3fa6256abc34 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-2.yy.stderr +++ b/tests/ui/traits/const-traits/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/traits/const-traits/super-traits-fail-3.nn.stderr b/tests/ui/traits/const-traits/super-traits-fail-3.nn.stderr index f40583f0ca57..294545014bf5 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-3.nn.stderr +++ b/tests/ui/traits/const-traits/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/traits/const-traits/super-traits-fail-3.ny.stderr b/tests/ui/traits/const-traits/super-traits-fail-3.ny.stderr index 3f6dfa7b0089..54bb6c5ca441 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-3.ny.stderr +++ b/tests/ui/traits/const-traits/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/traits/const-traits/super-traits-fail-3.rs b/tests/ui/traits/const-traits/super-traits-fail-3.rs index b5643b117000..a9b08e6edcdc 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-3.rs +++ b/tests/ui/traits/const-traits/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/traits/const-traits/super-traits-fail-3.yn.stderr b/tests/ui/traits/const-traits/super-traits-fail-3.yn.stderr index bbc95948a59d..b6747d10e83c 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-3.yn.stderr +++ b/tests/ui/traits/const-traits/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: `~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[E0277]: the trait bound `T: ~const Foo` is not satisfied - --> $DIR/super-traits-fail-3.rs:22:7 + --> $DIR/super-traits-fail-3.rs:25:5 | LL | x.a(); - | ^ the trait `Foo` is not implemented for `T` - | -note: required by a bound in `Foo::a` - --> $DIR/super-traits-fail-3.rs:8: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 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/traits/const-traits/super-traits-fail.rs b/tests/ui/traits/const-traits/super-traits-fail.rs index da41d7fcc723..c07619fbf621 100644 --- a/tests/ui/traits/const-traits/super-traits-fail.rs +++ b/tests/ui/traits/const-traits/super-traits-fail.rs @@ -1,4 +1,3 @@ -//~ ERROR the trait bound //@ compile-flags: -Znext-solver #![allow(incomplete_features)] diff --git a/tests/ui/traits/const-traits/super-traits-fail.stderr b/tests/ui/traits/const-traits/super-traits-fail.stderr index 3870f0f722f9..7a734a6c9f1c 100644 --- a/tests/ui/traits/const-traits/super-traits-fail.stderr +++ b/tests/ui/traits/const-traits/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/traits/const-traits/tilde-const-and-const-params.rs b/tests/ui/traits/const-traits/tilde-const-and-const-params.rs index 4b720b534a49..f6a7c7c17461 100644 --- a/tests/ui/traits/const-traits/tilde-const-and-const-params.rs +++ b/tests/ui/traits/const-traits/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/traits/const-traits/tilde-const-and-const-params.stderr b/tests/ui/traits/const-traits/tilde-const-and-const-params.stderr index 73526a26e081..84a425f6791b 100644 --- a/tests/ui/traits/const-traits/tilde-const-and-const-params.stderr +++ b/tests/ui/traits/const-traits/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: aborting due to 3 previous errors -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 - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/traits/const-traits/trait-where-clause-const.rs b/tests/ui/traits/const-traits/trait-where-clause-const.rs index 8ca9b7cc7aa0..61e2bc384268 100644 --- a/tests/ui/traits/const-traits/trait-where-clause-const.rs +++ b/tests/ui/traits/const-traits/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/traits/const-traits/trait-where-clause-const.stderr b/tests/ui/traits/const-traits/trait-where-clause-const.stderr index eaa981ec7444..30a7ef1fd0d3 100644 --- a/tests/ui/traits/const-traits/trait-where-clause-const.stderr +++ b/tests/ui/traits/const-traits/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 2 previous errors -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/traits/const-traits/unsatisfied-const-trait-bound.stderr b/tests/ui/traits/const-traits/unsatisfied-const-trait-bound.stderr index 848aa68689b4..e0cf062ad95e 100644 --- a/tests/ui/traits/const-traits/unsatisfied-const-trait-bound.stderr +++ b/tests/ui/traits/const-traits/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`.