From 612a114d565e7d852a75b41af91eabee55c390a3 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Mon, 24 Jul 2023 05:22:31 +0000 Subject: [PATCH 1/9] remove constness from `TraitPredicate` --- .../src/type_check/canonical.rs | 1 - .../src/transform/check_consts/check.rs | 5 +- .../src/transform/check_consts/qualifs.rs | 6 +- .../rustc_hir_analysis/src/astconv/mod.rs | 4 +- .../src/astconv/object_safety.rs | 12 +-- compiler/rustc_hir_analysis/src/bounds.rs | 3 +- .../rustc_hir_analysis/src/check/wfcheck.rs | 5 +- .../src/collect/predicates_of.rs | 12 +-- .../src/impl_wf_check/min_specialization.rs | 16 ++-- .../rustc_hir_analysis/src/variance/mod.rs | 1 - compiler/rustc_hir_typeck/src/expr.rs | 1 - .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 3 +- .../rustc_hir_typeck/src/fn_ctxt/checks.rs | 6 +- compiler/rustc_hir_typeck/src/method/mod.rs | 2 +- compiler/rustc_hir_typeck/src/method/probe.rs | 2 +- .../rustc_hir_typeck/src/method/suggest.rs | 4 +- compiler/rustc_infer/src/traits/engine.rs | 2 +- compiler/rustc_infer/src/traits/mod.rs | 16 ---- compiler/rustc_infer/src/traits/util.rs | 6 +- compiler/rustc_middle/src/traits/mod.rs | 10 +-- compiler/rustc_middle/src/traits/select.rs | 4 +- .../src/traits/structural_impls.rs | 4 +- compiler/rustc_middle/src/ty/mod.rs | 90 +------------------ compiler/rustc_middle/src/ty/print/pretty.rs | 20 +++-- compiler/rustc_middle/src/ty/relate.rs | 1 - .../rustc_middle/src/ty/structural_impls.rs | 3 - compiler/rustc_middle/src/ty/sty.rs | 24 +++-- compiler/rustc_privacy/src/lib.rs | 2 +- compiler/rustc_trait_selection/src/infer.rs | 2 +- .../src/solve/assembly/mod.rs | 1 - .../src/solve/eval_ctxt/select.rs | 2 +- .../src/traits/auto_trait.rs | 3 +- .../src/traits/engine.rs | 2 +- .../src/traits/error_reporting/mod.rs | 34 +++---- .../src/traits/error_reporting/suggestions.rs | 1 - .../rustc_trait_selection/src/traits/mod.rs | 2 +- .../src/traits/object_safety.rs | 1 - .../src/traits/project.rs | 8 +- .../src/traits/query/evaluate_obligation.rs | 13 +-- .../src/traits/select/candidate_assembly.rs | 4 +- .../src/traits/select/confirmation.rs | 35 ++++---- .../src/traits/select/mod.rs | 44 ++++----- .../src/traits/specialize/mod.rs | 6 +- .../rustc_trait_selection/src/traits/util.rs | 4 +- .../src/traits/vtable.rs | 2 +- .../rustc_trait_selection/src/traits/wf.rs | 41 ++------- compiler/rustc_ty_utils/src/ty.rs | 2 +- 47 files changed, 154 insertions(+), 318 deletions(-) diff --git a/compiler/rustc_borrowck/src/type_check/canonical.rs b/compiler/rustc_borrowck/src/type_check/canonical.rs index c19fbf20ca5bc..3a788cd169ca8 100644 --- a/compiler/rustc_borrowck/src/type_check/canonical.rs +++ b/compiler/rustc_borrowck/src/type_check/canonical.rs @@ -92,7 +92,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::Trait( ty::TraitPredicate { trait_ref, - constness: ty::BoundConstness::NotConst, polarity: ty::ImplPolarity::Positive, }, ))), diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs index d8b8fa927c7ee..f6b30e89c31fc 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -754,8 +754,8 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { return; } + // TODO this needs constness let trait_ref = TraitRef::from_method(tcx, trait_id, fn_args); - let trait_ref = trait_ref.with_constness(ty::BoundConstness::ConstIfConst); let obligation = Obligation::new(tcx, ObligationCause::dummy(), param_env, trait_ref); @@ -766,7 +766,8 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { }; match implsrc { - Ok(Some(ImplSource::Param(_, ty::BoundConstness::ConstIfConst))) => { + // TODO hmm? + Ok(Some(ImplSource::Param(_))) => { debug!( "const_trait_impl: provided {:?} via where-clause in {:?}", trait_ref, param_env diff --git a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs index 0ef7ace696532..654247f32dd65 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs @@ -157,8 +157,8 @@ impl Qualif for NeedsNonConstDrop { cx.tcx, ObligationCause::dummy_with_span(cx.body.span), cx.param_env, - ty::TraitRef::from_lang_item(cx.tcx, LangItem::Destruct, cx.body.span, [ty]) - .with_constness(ty::BoundConstness::ConstIfConst), + // TODO this needs constness + ty::TraitRef::from_lang_item(cx.tcx, LangItem::Destruct, cx.body.span, [ty]), ); let infcx = cx.tcx.infer_ctxt().build(); @@ -172,7 +172,7 @@ impl Qualif for NeedsNonConstDrop { if !matches!( impl_src, - ImplSource::Builtin(_) | ImplSource::Param(_, ty::BoundConstness::ConstIfConst) + ImplSource::Builtin(_) | ImplSource::Param(_) ) { // If our const destruct candidate is not ConstDestruct or implied by the param env, // then it's bad diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index ecbbfd9253903..4ae5829fbd415 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -356,6 +356,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { generic_args: &'a hir::GenericArgs<'_>, infer_args: bool, self_ty: Option>, + // TODO actually use this constness constness: ty::BoundConstness, ) -> (GenericArgsRef<'tcx>, GenericArgCountResult) { // If the type is parameterized by this region, then replace this @@ -707,13 +708,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let assoc_bindings = self.create_assoc_bindings_for_generic_args(args); + // TODO this needs constness let poly_trait_ref = ty::Binder::bind_with_vars( ty::TraitRef::new(tcx, trait_def_id, generic_args), bound_vars, ); debug!(?poly_trait_ref, ?assoc_bindings); - bounds.push_trait_bound(tcx, poly_trait_ref, span, constness, polarity); + bounds.push_trait_bound(tcx, poly_trait_ref, span, polarity); let mut dup_bindings = FxHashMap::default(); for binding in &assoc_bindings { diff --git a/compiler/rustc_hir_analysis/src/astconv/object_safety.rs b/compiler/rustc_hir_analysis/src/astconv/object_safety.rs index a36ec0c57306f..da9705e2f396a 100644 --- a/compiler/rustc_hir_analysis/src/astconv/object_safety.rs +++ b/compiler/rustc_hir_analysis/src/astconv/object_safety.rs @@ -65,7 +65,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { trait_bounds.push(( bound_pred.rebind(trait_pred.trait_ref), span, - trait_pred.constness, )); } ty::ClauseKind::Projection(proj) => { @@ -86,7 +85,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // Expand trait aliases recursively and check that only one regular (non-auto) trait // is used and no 'maybe' bounds are used. let expanded_traits = - traits::expand_trait_aliases(tcx, trait_bounds.iter().map(|&(a, b, _)| (a, b))); + traits::expand_trait_aliases(tcx, trait_bounds.iter().map(|&(a, b)| (a, b))); let (mut auto_traits, regular_traits): (Vec<_>, Vec<_>) = expanded_traits .filter(|i| i.trait_ref().self_ty().skip_binder() == dummy_self) @@ -126,7 +125,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { if regular_traits.is_empty() && auto_traits.is_empty() { let trait_alias_span = trait_bounds .iter() - .map(|&(trait_ref, _, _)| trait_ref.def_id()) + .map(|&(trait_ref, _)| trait_ref.def_id()) .find(|&trait_ref| tcx.is_trait_alias(trait_ref)) .map(|trait_ref| tcx.def_span(trait_ref)); let reported = @@ -157,10 +156,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let regular_traits_refs_spans = trait_bounds .into_iter() - .filter(|(trait_ref, _, _)| !tcx.trait_is_auto(trait_ref.def_id())); + .filter(|(trait_ref, _)| !tcx.trait_is_auto(trait_ref.def_id())); - for (base_trait_ref, span, constness) in regular_traits_refs_spans { - assert_eq!(constness, ty::BoundConstness::NotConst); + for (base_trait_ref, span) in regular_traits_refs_spans { + // TODO? + //assert_eq!(constness, ty::BoundConstness::NotConst); let base_pred: ty::Predicate<'tcx> = base_trait_ref.to_predicate(tcx); for pred in traits::elaborate(tcx, [base_pred]) { debug!("conv_object_ty_poly_trait_ref: observing object predicate `{:?}`", pred); diff --git a/compiler/rustc_hir_analysis/src/bounds.rs b/compiler/rustc_hir_analysis/src/bounds.rs index 531100e1fe61b..1d9ae2b9cb730 100644 --- a/compiler/rustc_hir_analysis/src/bounds.rs +++ b/compiler/rustc_hir_analysis/src/bounds.rs @@ -42,13 +42,12 @@ impl<'tcx> Bounds<'tcx> { tcx: TyCtxt<'tcx>, trait_ref: ty::PolyTraitRef<'tcx>, span: Span, - constness: ty::BoundConstness, polarity: ty::ImplPolarity, ) { self.clauses.push(( trait_ref .map_bound(|trait_ref| { - ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref, constness, polarity }) + ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref, polarity }) }) .to_predicate(tcx), span, diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 4e194f1c381cb..fb2aa88ea0e92 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1187,6 +1187,7 @@ fn check_impl<'tcx>( // `#[rustc_reservation_impl]` impls are not real impls and // therefore don't need to be WF (the trait's `Self: Trait` predicate // won't hold). + // TODO constness? let trait_ref = tcx.impl_trait_ref(item.owner_id).unwrap().instantiate_identity(); let trait_ref = wfcx.normalize( ast_trait_ref.path.span, @@ -1195,10 +1196,6 @@ fn check_impl<'tcx>( ); let trait_pred = ty::TraitPredicate { trait_ref, - constness: match constness { - hir::Constness::Const => ty::BoundConstness::ConstIfConst, - hir::Constness::NotConst => ty::BoundConstness::NotConst, - }, polarity: ty::ImplPolarity::Positive, }; let mut obligations = traits::wf::trait_obligations( diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index 979b101e7fe2d..6a90668430951 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -38,16 +38,10 @@ pub(super) fn predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredic // an obligation and instead be skipped. Otherwise we'd use // `tcx.def_span(def_id);` - let constness = if tcx.has_attr(def_id, sym::const_trait) { - ty::BoundConstness::ConstIfConst - } else { - ty::BoundConstness::NotConst - }; - let span = rustc_span::DUMMY_SP; result.predicates = tcx.arena.alloc_from_iter(result.predicates.iter().copied().chain(std::iter::once(( - ty::TraitRef::identity(tcx, def_id).with_constness(constness).to_predicate(tcx), + ty::TraitRef::identity(tcx, def_id).to_predicate(tcx), span, )))); } @@ -203,7 +197,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen // (see below). Recall that a default impl is not itself an impl, but rather a // set of defaults that can be incorporated into another impl. if let Some(trait_ref) = is_default_impl_trait { - predicates.insert((trait_ref.without_const().to_predicate(tcx), tcx.def_span(def_id))); + predicates.insert((trait_ref.to_predicate(tcx), tcx.def_span(def_id))); } // Collect the region predicates that were declared inline as @@ -776,7 +770,7 @@ pub(super) fn type_param_predicates( let identity_trait_ref = ty::TraitRef::identity(tcx, item_def_id.to_def_id()); extend = - Some((identity_trait_ref.without_const().to_predicate(tcx), item.span)); + Some((identity_trait_ref.to_predicate(tcx), item.span)); } generics } 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 81993789bcf69..55bdefe1b744d 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 @@ -448,13 +448,8 @@ fn trait_predicates_eq<'tcx>( _ => return predicate1 == predicate2, }; - let predicates_equal_modulo_constness = { - let pred1_unconsted = - ty::TraitPredicate { constness: ty::BoundConstness::NotConst, ..trait_pred1 }; - let pred2_unconsted = - ty::TraitPredicate { constness: ty::BoundConstness::NotConst, ..trait_pred2 }; - pred1_unconsted == pred2_unconsted - }; + // TODO + let predicates_equal_modulo_constness = predicate1 == predicate2; if !predicates_equal_modulo_constness { return false; @@ -462,12 +457,13 @@ fn trait_predicates_eq<'tcx>( // Check that the predicate on the specializing impl is at least as const as // the one on the base. - match (trait_pred2.constness, trait_pred1.constness) { + // TODO + /*match (trait_pred2.constness, trait_pred1.constness) { (ty::BoundConstness::ConstIfConst, ty::BoundConstness::NotConst) => { tcx.sess.emit_err(errors::MissingTildeConst { span }); } _ => {} - } + }*/ true } @@ -482,7 +478,6 @@ fn check_specialization_on<'tcx>(tcx: TyCtxt<'tcx>, predicate: ty::Predicate<'tc // items. ty::PredicateKind::Clause(ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref, - constness: _, polarity: _, })) => { if !matches!( @@ -536,7 +531,6 @@ fn trait_predicate_kind<'tcx>( match predicate.kind().skip_binder() { ty::PredicateKind::Clause(ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref, - constness: _, polarity: _, })) => Some(tcx.trait_def(trait_ref.def_id).specialization_kind), ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(_)) diff --git a/compiler/rustc_hir_analysis/src/variance/mod.rs b/compiler/rustc_hir_analysis/src/variance/mod.rs index 1ef257e87d69e..6952a3fa66f1e 100644 --- a/compiler/rustc_hir_analysis/src/variance/mod.rs +++ b/compiler/rustc_hir_analysis/src/variance/mod.rs @@ -156,7 +156,6 @@ fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Varianc match pred.kind().skip_binder() { ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref: ty::TraitRef { def_id: _, args, .. }, - constness: _, polarity: _, }) => { for subst in &args[1..] { diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 29488c9011a19..731e83e838747 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -2992,7 +2992,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty::Binder::dummy(ty::TraitPredicate { trait_ref: impl_trait_ref, polarity: ty::ImplPolarity::Positive, - constness: ty::BoundConstness::NotConst, }), |derived| { traits::ImplDerivedObligation(Box::new( diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index fa1056e724a1f..e3a643a8c7b79 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -1466,7 +1466,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // N.B. We are remapping all predicates to non-const since we don't know if we just // want them as function pointers or we are calling them from a const-context. The // actual checking will occur in `rustc_const_eval::transform::check_consts`. - self.register_predicate(obligation.without_const(self.tcx)); + // TODO: HMM? + self.register_predicate(obligation); } } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index a9610009db1ee..9a99086829114 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -1875,11 +1875,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { error.obligation.predicate, error.obligation.cause.clone(), )); - remap_cause.insert(( + // TODO: UM WHAT? + + /* remap_cause.insert(( before_span, error.obligation.predicate.without_const(self.tcx), error.obligation.cause.clone(), - )); + )); */ } else { // If it failed to be adjusted once around, it may be adjusted // via the "remap cause" mapping the second time... diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs index 356e7022aea11..4a7c97e77444b 100644 --- a/compiler/rustc_hir_typeck/src/method/mod.rs +++ b/compiler/rustc_hir_typeck/src/method/mod.rs @@ -346,7 +346,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.tcx, cause, self.param_env, - poly_trait_ref.without_const(), + poly_trait_ref, ), args, ) diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 05eed1923d1a4..1262a7bf76cfc 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -1600,7 +1600,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } } let predicate = - ty::Binder::dummy(trait_ref).without_const().to_predicate(self.tcx); + ty::Binder::dummy(trait_ref).to_predicate(self.tcx); parent_pred = Some(predicate); let obligation = traits::Obligation::new(self.tcx, cause.clone(), self.param_env, predicate); diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 3d7187cb16f3d..1c43045fe6df2 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -30,7 +30,7 @@ use rustc_middle::traits::util::supertraits; use rustc_middle::ty::fast_reject::DeepRejectCtxt; use rustc_middle::ty::fast_reject::{simplify_type, TreatParams}; use rustc_middle::ty::print::{with_crate_prefix, with_forced_trimmed_paths}; -use rustc_middle::ty::IsSuggestable; +use rustc_middle::ty::{IsSuggestable, ToPredicate}; use rustc_middle::ty::{self, GenericArgKind, Ty, TyCtxt, TypeVisitableExt}; use rustc_span::def_id::DefIdSet; use rustc_span::symbol::{kw, sym, Ident}; @@ -94,7 +94,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { span, self.body_id, self.param_env, - poly_trait_ref.without_const(), + poly_trait_ref, ); self.predicate_may_hold(&obligation) }) diff --git a/compiler/rustc_infer/src/traits/engine.rs b/compiler/rustc_infer/src/traits/engine.rs index 11f43469400ba..64b9714c7c086 100644 --- a/compiler/rustc_infer/src/traits/engine.rs +++ b/compiler/rustc_infer/src/traits/engine.rs @@ -25,7 +25,7 @@ pub trait TraitEngine<'tcx>: 'tcx { cause, recursion_depth: 0, param_env, - predicate: ty::Binder::dummy(trait_ref).without_const().to_predicate(infcx.tcx), + predicate: ty::Binder::dummy(trait_ref).to_predicate(infcx.tcx), }, ); } diff --git a/compiler/rustc_infer/src/traits/mod.rs b/compiler/rustc_infer/src/traits/mod.rs index 626dd9359a198..dc41630196b9f 100644 --- a/compiler/rustc_infer/src/traits/mod.rs +++ b/compiler/rustc_infer/src/traits/mod.rs @@ -77,25 +77,9 @@ impl<'tcx> PredicateObligation<'tcx> { recursion_depth: self.recursion_depth, }) } - - pub fn without_const(mut self, tcx: TyCtxt<'tcx>) -> PredicateObligation<'tcx> { - self.param_env = self.param_env.without_const(); - if let ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_pred)) = self.predicate.kind().skip_binder() && trait_pred.is_const_if_const() { - self.predicate = tcx.mk_predicate(self.predicate.kind().map_bound(|_| ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_pred.without_const())))); - } - self - } } impl<'tcx> PolyTraitObligation<'tcx> { - /// Returns `true` if the trait predicate is considered `const` in its ParamEnv. - pub fn is_const(&self) -> bool { - matches!( - (self.predicate.skip_binder().constness, self.param_env.constness()), - (ty::BoundConstness::ConstIfConst, hir::Constness::Const) - ) - } - pub fn derived_cause( &self, variant: impl FnOnce(DerivedObligationCause<'tcx>) -> ObligationCauseCode<'tcx>, diff --git a/compiler/rustc_infer/src/traits/util.rs b/compiler/rustc_infer/src/traits/util.rs index 87ba6b3ec5089..93dfbe63bcd1c 100644 --- a/compiler/rustc_infer/src/traits/util.rs +++ b/compiler/rustc_infer/src/traits/util.rs @@ -264,11 +264,7 @@ impl<'tcx, O: Elaboratable<'tcx>> Elaborator<'tcx, O> { }; let obligations = - predicates.predicates.iter().enumerate().map(|(index, &(mut clause, span))| { - // when parent predicate is non-const, elaborate it to non-const predicates. - if data.constness == ty::BoundConstness::NotConst { - clause = clause.without_const(tcx); - } + predicates.predicates.iter().enumerate().map(|(index, &(clause, span))| { elaboratable.child_with_derived_cause( clause.subst_supertrait(tcx, &bound_predicate.rebind(data.trait_ref)), span, diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index b7ffed57a0be0..e0f00cc14d877 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -649,7 +649,7 @@ pub enum ImplSource<'tcx, N> { /// for some type parameter. The `Vec` represents the /// obligations incurred from normalizing the where-clause (if /// any). - Param(Vec, ty::BoundConstness), + Param(Vec), /// Virtual calls through an object. Object(ImplSourceObjectData), @@ -665,7 +665,7 @@ impl<'tcx, N> ImplSource<'tcx, N> { pub fn nested_obligations(self) -> Vec { match self { ImplSource::UserDefined(i) => i.nested, - ImplSource::Param(n, _) | ImplSource::Builtin(n) => n, + ImplSource::Param(n) | ImplSource::Builtin(n) => n, ImplSource::Object(d) => d.nested, ImplSource::TraitUpcasting(d) => d.nested, } @@ -674,7 +674,7 @@ impl<'tcx, N> ImplSource<'tcx, N> { pub fn borrow_nested_obligations(&self) -> &[N] { match self { ImplSource::UserDefined(i) => &i.nested, - ImplSource::Param(n, _) | ImplSource::Builtin(n) => &n, + ImplSource::Param(n) | ImplSource::Builtin(n) => &n, ImplSource::Object(d) => &d.nested, ImplSource::TraitUpcasting(d) => &d.nested, } @@ -683,7 +683,7 @@ impl<'tcx, N> ImplSource<'tcx, N> { pub fn borrow_nested_obligations_mut(&mut self) -> &mut [N] { match self { ImplSource::UserDefined(i) => &mut i.nested, - ImplSource::Param(n, _) | ImplSource::Builtin(n) => n, + ImplSource::Param(n) | ImplSource::Builtin(n) => n, ImplSource::Object(d) => &mut d.nested, ImplSource::TraitUpcasting(d) => &mut d.nested, } @@ -699,7 +699,7 @@ impl<'tcx, N> ImplSource<'tcx, N> { args: i.args, nested: i.nested.into_iter().map(f).collect(), }), - ImplSource::Param(n, ct) => ImplSource::Param(n.into_iter().map(f).collect(), ct), + ImplSource::Param(n) => ImplSource::Param(n.into_iter().map(f).collect()), ImplSource::Builtin(n) => ImplSource::Builtin(n.into_iter().map(f).collect()), ImplSource::Object(o) => ImplSource::Object(ImplSourceObjectData { vtable_base: o.vtable_base, diff --git a/compiler/rustc_middle/src/traits/select.rs b/compiler/rustc_middle/src/traits/select.rs index f2dda003b99c5..9fb9a7e11b2df 100644 --- a/compiler/rustc_middle/src/traits/select.rs +++ b/compiler/rustc_middle/src/traits/select.rs @@ -126,8 +126,8 @@ pub enum SelectionCandidate<'tcx> { /// This is a trait matching with a projected type as `Self`, and we found /// an applicable bound in the trait definition. The `usize` is an index /// into the list returned by `tcx.item_bounds`. The constness is the - /// constness of the bound in the trait. - ProjectionCandidate(usize, ty::BoundConstness), + /// host effect param of the bound in the trait. + ProjectionCandidate(usize, Option>), /// Implementation of a `Fn`-family trait by one of the anonymous types /// generated for an `||` expression. diff --git a/compiler/rustc_middle/src/traits/structural_impls.rs b/compiler/rustc_middle/src/traits/structural_impls.rs index e2cd118500b65..8a1b72dc565e4 100644 --- a/compiler/rustc_middle/src/traits/structural_impls.rs +++ b/compiler/rustc_middle/src/traits/structural_impls.rs @@ -13,8 +13,8 @@ impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSource<'tcx, N> { super::ImplSource::Object(ref d) => write!(f, "{:?}", d), - super::ImplSource::Param(ref n, ct) => { - write!(f, "ImplSourceParamData({:?}, {:?})", n, ct) + super::ImplSource::Param(ref n) => { + write!(f, "ImplSourceParamData({n:?})") } super::ImplSource::TraitUpcasting(ref d) => write!(f, "{:?}", d), diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 0411890ab5139..feb0fbddd61c3 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -498,11 +498,9 @@ impl<'tcx> Predicate<'tcx> { .map_bound(|kind| match kind { PredicateKind::Clause(ClauseKind::Trait(TraitPredicate { trait_ref, - constness, polarity, })) => Some(PredicateKind::Clause(ClauseKind::Trait(TraitPredicate { trait_ref, - constness, polarity: polarity.flip()?, }))), @@ -513,19 +511,6 @@ impl<'tcx> Predicate<'tcx> { Some(tcx.mk_predicate(kind)) } - pub fn without_const(mut self, tcx: TyCtxt<'tcx>) -> Self { - if let PredicateKind::Clause(ClauseKind::Trait(TraitPredicate { trait_ref, constness, polarity })) = self.kind().skip_binder() - && constness != BoundConstness::NotConst - { - self = tcx.mk_predicate(self.kind().rebind(PredicateKind::Clause(ClauseKind::Trait(TraitPredicate { - trait_ref, - constness: BoundConstness::NotConst, - polarity, - })))); - } - self - } - #[instrument(level = "debug", skip(tcx), ret)] pub fn is_coinductive(self, tcx: TyCtxt<'tcx>) -> bool { match self.kind().skip_binder() { @@ -629,10 +614,6 @@ impl<'tcx> Clause<'tcx> { None } } - - pub fn without_const(self, tcx: TyCtxt<'tcx>) -> Clause<'tcx> { - self.as_predicate().without_const(tcx).expect_clause() - } } #[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable)] @@ -852,8 +833,6 @@ impl<'tcx> Clause<'tcx> { pub struct TraitPredicate<'tcx> { pub trait_ref: TraitRef<'tcx>, - pub constness: BoundConstness, - /// If polarity is Positive: we are proving that the trait is implemented. /// /// If polarity is Negative: we are proving that a negative impl of this trait @@ -867,20 +846,6 @@ pub struct TraitPredicate<'tcx> { pub type PolyTraitPredicate<'tcx> = ty::Binder<'tcx, TraitPredicate<'tcx>>; impl<'tcx> TraitPredicate<'tcx> { - pub fn remap_constness(&mut self, param_env: &mut ParamEnv<'tcx>) { - *param_env = param_env.with_constness(self.constness.and(param_env.constness())) - } - - /// Remap the constness of this predicate before emitting it for diagnostics. - pub fn remap_constness_diag(&mut self, param_env: ParamEnv<'tcx>) { - // this is different to `remap_constness` that callees want to print this predicate - // in case of selection errors. `T: ~const Drop` bounds cannot end up here when the - // param_env is not const because it is always satisfied in non-const contexts. - if let hir::Constness::NotConst = param_env.constness() { - self.constness = ty::BoundConstness::NotConst; - } - } - pub fn with_self_ty(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> Self { Self { trait_ref: self.trait_ref.with_self_ty(tcx, self_ty), ..self } } @@ -892,24 +857,6 @@ impl<'tcx> TraitPredicate<'tcx> { pub fn self_ty(self) -> Ty<'tcx> { self.trait_ref.self_ty() } - - #[inline] - pub fn is_const_if_const(self) -> bool { - self.constness == BoundConstness::ConstIfConst - } - - pub fn is_constness_satisfied_by(self, constness: hir::Constness) -> bool { - match (self.constness, constness) { - (BoundConstness::NotConst, _) - | (BoundConstness::ConstIfConst, hir::Constness::Const) => true, - (BoundConstness::ConstIfConst, hir::Constness::NotConst) => false, - } - } - - pub fn without_const(mut self) -> Self { - self.constness = BoundConstness::NotConst; - self - } } impl<'tcx> PolyTraitPredicate<'tcx> { @@ -922,19 +869,6 @@ impl<'tcx> PolyTraitPredicate<'tcx> { self.map_bound(|trait_ref| trait_ref.self_ty()) } - /// Remap the constness of this predicate before emitting it for diagnostics. - pub fn remap_constness_diag(&mut self, param_env: ParamEnv<'tcx>) { - *self = self.map_bound(|mut p| { - p.remap_constness_diag(param_env); - p - }); - } - - #[inline] - pub fn is_const_if_const(self) -> bool { - self.skip_binder().is_const_if_const() - } - #[inline] pub fn polarity(self) -> ImplPolarity { self.skip_binder().polarity @@ -1309,7 +1243,10 @@ impl<'tcx> ToPredicate<'tcx> for TraitRef<'tcx> { impl<'tcx> ToPredicate<'tcx, TraitPredicate<'tcx>> for TraitRef<'tcx> { #[inline(always)] fn to_predicate(self, _tcx: TyCtxt<'tcx>) -> TraitPredicate<'tcx> { - self.without_const() + TraitPredicate { + trait_ref: self, + polarity: ImplPolarity::Positive, + } } } @@ -1350,7 +1287,6 @@ impl<'tcx> ToPredicate<'tcx, PolyTraitPredicate<'tcx>> for Binder<'tcx, TraitRef fn to_predicate(self, _: TyCtxt<'tcx>) -> PolyTraitPredicate<'tcx> { self.map_bound(|trait_ref| TraitPredicate { trait_ref, - constness: ty::BoundConstness::NotConst, polarity: ty::ImplPolarity::Positive, }) } @@ -1883,24 +1819,6 @@ impl<'tcx> ParamEnv<'tcx> { } } -// FIXME(ecstaticmorse): Audit all occurrences of `without_const().to_predicate(tcx)` to ensure that -// the constness of trait bounds is being propagated correctly. -impl<'tcx> PolyTraitRef<'tcx> { - #[inline] - pub fn with_constness(self, constness: BoundConstness) -> PolyTraitPredicate<'tcx> { - self.map_bound(|trait_ref| ty::TraitPredicate { - trait_ref, - constness, - polarity: ty::ImplPolarity::Positive, - }) - } - - #[inline] - pub fn without_const(self) -> PolyTraitPredicate<'tcx> { - self.with_constness(BoundConstness::NotConst) - } -} - #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable)] #[derive(HashStable, Lift)] pub struct ParamEnvAnd<'tcx, T> { diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index e5633223464a5..0056f8461c70d 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -17,7 +17,7 @@ use rustc_hir::LangItem; use rustc_session::config::TrimmedDefPaths; use rustc_session::cstore::{ExternCrate, ExternCrateSource}; use rustc_session::Limit; -use rustc_span::symbol::{kw, Ident, Symbol}; +use rustc_span::symbol::{sym, kw, Ident, Symbol}; use rustc_span::FileNameDisplayPreference; use rustc_target::abi::Size; use rustc_target::spec::abi::Abi; @@ -2017,11 +2017,21 @@ impl<'tcx> Printer<'tcx> for FmtPrinter<'_, 'tcx> { ) -> Result { self = print_prefix(self)?; - if args.first().is_some() { + let tcx = self.tcx; + + // skip host param as those are printed as `~const` + let mut args = args.iter().copied().filter(|arg| { + match arg.unpack() { + GenericArgKind::Const(c) if tcx.features().effects && matches!(c.kind(), ty::ConstKind::Param(ty::ParamConst { name: sym::host, .. })) => tcx.sess.verbose(), + _ => true + } + }).peekable(); + + if args.peek().is_some() { if self.in_value { write!(self, "::")?; } - self.generic_delimiters(|cx| cx.comma_sep(args.iter().cloned())) + self.generic_delimiters(|cx| cx.comma_sep(args)) } else { Ok(self) } @@ -2779,7 +2789,7 @@ define_print_and_forward_display! { } TraitPredPrintModifiersAndPath<'tcx> { - if let ty::BoundConstness::ConstIfConst = self.0.constness { + if self.0.trait_ref.args.host_effect_param().is_some() { p!("~const ") } @@ -2816,7 +2826,7 @@ define_print_and_forward_display! { ty::TraitPredicate<'tcx> { p!(print(self.trait_ref.self_ty()), ": "); - if let ty::BoundConstness::ConstIfConst = self.constness && cx.tcx().features().const_trait_impl { + if self.trait_ref.args.host_effect_param().is_some() && cx.tcx().features().const_trait_impl { p!("~const "); } if let ty::ImplPolarity::Negative = self.polarity { diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index bf9adabdab1c4..47512d350e546 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -826,7 +826,6 @@ impl<'tcx> Relate<'tcx> for ty::TraitPredicate<'tcx> { ) -> RelateResult<'tcx, ty::TraitPredicate<'tcx>> { Ok(ty::TraitPredicate { trait_ref: relation.relate(a.trait_ref, b.trait_ref)?, - constness: relation.relate(a.constness, b.constness)?, polarity: relation.relate(a.polarity, b.polarity)?, }) } diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 9d380a58d9fa3..588f155228d5e 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -172,9 +172,6 @@ impl fmt::Debug for ty::ParamConst { impl<'tcx> fmt::Debug for ty::TraitPredicate<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - if let ty::BoundConstness::ConstIfConst = self.constness { - write!(f, "~const ")?; - } write!(f, "TraitPredicate({:?}, polarity:{:?})", self.trait_ref, self.polarity) } } diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index f9c1ca9a8b167..9cc4abd696ed6 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -728,7 +728,7 @@ impl<'tcx> PolyExistentialPredicate<'tcx> { use crate::ty::ToPredicate; match self.skip_binder() { ExistentialPredicate::Trait(tr) => { - self.rebind(tr).with_self_ty(tcx, self_ty).without_const().to_predicate(tcx) + self.rebind(tr).with_self_ty(tcx, self_ty).to_predicate(tcx) } ExistentialPredicate::Projection(p) => { self.rebind(p.with_self_ty(tcx, self_ty)).to_predicate(tcx) @@ -743,7 +743,7 @@ impl<'tcx> PolyExistentialPredicate<'tcx> { let err_args = ty::GenericArgs::extend_with_error(tcx, did, &[self_ty.into()]); ty::TraitRef::new(tcx, did, err_args) }; - self.rebind(trait_ref).without_const().to_predicate(tcx) + self.rebind(trait_ref).to_predicate(tcx) } } } @@ -875,21 +875,14 @@ impl<'tcx> TraitRef<'tcx> { ) } - /// Converts this trait ref to a trait predicate with a given `constness` and a positive polarity. #[inline] - pub fn with_constness(self, constness: ty::BoundConstness) -> ty::TraitPredicate<'tcx> { - ty::TraitPredicate { trait_ref: self, constness, polarity: ty::ImplPolarity::Positive } - } - - /// Converts this trait ref to a trait predicate without `const` and a positive polarity. - #[inline] - pub fn without_const(self) -> ty::TraitPredicate<'tcx> { - self.with_constness(ty::BoundConstness::NotConst) + pub fn self_ty(&self) -> Ty<'tcx> { + self.args.type_at(0) } #[inline] - pub fn self_ty(&self) -> Ty<'tcx> { - self.args.type_at(0) + pub fn host_effect_param(&self) -> Option> { + self.args.host_effect_param() } } @@ -903,6 +896,11 @@ impl<'tcx> PolyTraitRef<'tcx> { pub fn def_id(&self) -> DefId { self.skip_binder().def_id } + + #[inline] + pub fn host_effect_param(&self) -> Option> { + self.skip_binder().host_effect_param() + } } impl<'tcx> IntoDiagnosticArg for TraitRef<'tcx> { diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index e2827252509db..7897fbbb251c7 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -147,7 +147,7 @@ where fn visit_clause(&mut self, clause: ty::Clause<'tcx>) -> ControlFlow { match clause.kind().skip_binder() { - ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref, constness: _, polarity: _ }) => { + ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref, polarity: _ }) => { self.visit_trait(trait_ref) } ty::ClauseKind::Projection(ty::ProjectionPredicate { projection_ty, term }) => { diff --git a/compiler/rustc_trait_selection/src/infer.rs b/compiler/rustc_trait_selection/src/infer.rs index 6efc1e7302c0a..38153cccfdded 100644 --- a/compiler/rustc_trait_selection/src/infer.rs +++ b/compiler/rustc_trait_selection/src/infer.rs @@ -72,7 +72,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { cause: traits::ObligationCause::dummy(), param_env, recursion_depth: 0, - predicate: ty::Binder::dummy(trait_ref).without_const().to_predicate(self.tcx), + predicate: ty::Binder::dummy(trait_ref).to_predicate(self.tcx), }; self.evaluate_obligation(&obligation).unwrap_or(traits::EvaluationResult::EvaluatedToErr) } diff --git a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs index 6920e790e71ae..cefb1afeab511 100644 --- a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs @@ -739,7 +739,6 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { self.tcx(), ty::TraitPredicate { trait_ref: self_trait_ref, - constness: ty::BoundConstness::NotConst, polarity: ty::ImplPolarity::Positive, }, ); diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs index a6d118d8cc29d..62185dd31144c 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs @@ -132,7 +132,7 @@ impl<'tcx> InferCtxtSelectExt<'tcx> for InferCtxt<'tcx> { // It's fine not to do anything to rematch these, since there are no // nested obligations. (Certainty::Yes, CandidateSource::ParamEnv(_) | CandidateSource::AliasBound) => { - Ok(Some(ImplSource::Param(nested_obligations, ty::BoundConstness::NotConst))) + Ok(Some(ImplSource::Param(nested_obligations))) } (_, CandidateSource::BuiltinImpl(BuiltinImplSource::Ambiguity)) diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index 27cd0f99f34bc..ba12a84ebf0b4 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -97,7 +97,6 @@ impl<'tcx> AutoTraitFinder<'tcx> { orig_env, ty::TraitPredicate { trait_ref, - constness: ty::BoundConstness::NotConst, polarity: if polarity { ImplPolarity::Positive } else { @@ -258,9 +257,9 @@ impl<'tcx> AutoTraitFinder<'tcx> { let mut already_visited = FxHashSet::default(); let mut predicates = VecDeque::new(); predicates.push_back(ty::Binder::dummy(ty::TraitPredicate { + // FIXME(effects) revisit this and whether auto traits can be `const_trait` trait_ref: ty::TraitRef::new(infcx.tcx, trait_did, [ty]), - constness: ty::BoundConstness::NotConst, // Auto traits are positive polarity: ty::ImplPolarity::Positive, })); diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs index 61f693e1bd182..820973dc090ad 100644 --- a/compiler/rustc_trait_selection/src/traits/engine.rs +++ b/compiler/rustc_trait_selection/src/traits/engine.rs @@ -97,7 +97,7 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> { cause, recursion_depth: 0, param_env, - predicate: ty::Binder::dummy(trait_ref).without_const().to_predicate(tcx), + predicate: ty::Binder::dummy(trait_ref).to_predicate(tcx), }); } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index c14839fe9be08..790a869731af2 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -100,7 +100,7 @@ pub trait InferCtxtExt<'tcx> { &self, param_env: ty::ParamEnv<'tcx>, ty: ty::Binder<'tcx, Ty<'tcx>>, - constness: ty::BoundConstness, + host: ty::Const<'tcx>, polarity: ty::ImplPolarity, ) -> Result<(ty::ClosureKind, ty::Binder<'tcx, Ty<'tcx>>), ()>; } @@ -356,7 +356,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { &self, param_env: ty::ParamEnv<'tcx>, ty: ty::Binder<'tcx, Ty<'tcx>>, - constness: ty::BoundConstness, + host: ty::Const<'tcx>, polarity: ty::ImplPolarity, ) -> Result<(ty::ClosureKind, ty::Binder<'tcx, Ty<'tcx>>), ()> { self.commit_if_ok(|_| { @@ -372,12 +372,12 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { span: DUMMY_SP, kind: TypeVariableOriginKind::MiscVariable, }); - let trait_ref = ty::TraitRef::new(self.tcx, trait_def_id, [ty.skip_binder(), var]); + let trait_ref = ty::TraitRef::new(self.tcx, trait_def_id, [ty.skip_binder().into(), ty::GenericArg::from(var), host.into()]); let obligation = Obligation::new( self.tcx, ObligationCause::dummy(), param_env, - ty.rebind(ty::TraitPredicate { trait_ref, constness, polarity }), + ty.rebind(ty::TraitPredicate { trait_ref, polarity }), ); let ocx = ObligationCtxt::new(self); ocx.register_obligation(obligation); @@ -689,9 +689,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { let trait_predicate = bound_predicate.rebind(trait_predicate); let mut trait_predicate = self.resolve_vars_if_possible(trait_predicate); - trait_predicate.remap_constness_diag(obligation.param_env); - let predicate_is_const = ty::BoundConstness::ConstIfConst - == trait_predicate.skip_binder().constness; + let predicate_is_const = trait_predicate.skip_binder().trait_ref.args.host_effect_param().is_some(); if self.tcx.sess.has_errors().is_some() && trait_predicate.references_error() @@ -1910,9 +1908,6 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { .all_impls(trait_pred.def_id()) .filter_map(|def_id| { if self.tcx.impl_polarity(def_id) == ty::ImplPolarity::Negative - || !trait_pred - .skip_binder() - .is_constness_satisfied_by(self.tcx.constness(def_id)) || !self.tcx.is_user_visible_dep(def_id.krate) { return None; @@ -2999,7 +2994,8 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { && let Ok((implemented_kind, params)) = self.type_implements_fn_trait( obligation.param_env, trait_ref.self_ty(), - trait_predicate.skip_binder().constness, + // TODO: what about const contexts? + trait_predicate.skip_binder().trait_ref.args.host_effect_param().unwrap_or(self.tcx.consts.true_), trait_predicate.skip_binder().polarity, ) { @@ -3108,12 +3104,20 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { span: Span, ) -> UnsatisfiedConst { let mut unsatisfied_const = UnsatisfiedConst(false); - if trait_predicate.is_const_if_const() && obligation.param_env.is_const() { - let non_const_predicate = trait_ref.without_const(); + if trait_ref.skip_binder().args.host_effect_param().is_some() && obligation.param_env.is_const() { + let unconst_pred = trait_predicate.map_bound(|mut x| { + x.trait_ref = ty::TraitRef::new(self.tcx, x.trait_ref.def_id, x.trait_ref.args.iter().map(|arg| { + match arg.unpack() { + ty::GenericArgKind::Const(c) if matches!(c.kind(), ty::ConstKind::Param(ty::ParamConst { name: sym::host, .. })) => self.tcx.consts.true_.into(), + _ => arg, + } + })); + x + }); let non_const_obligation = Obligation { cause: obligation.cause.clone(), param_env: obligation.param_env.without_const(), - predicate: non_const_predicate.to_predicate(self.tcx), + predicate: unconst_pred.to_predicate(self.tcx), recursion_depth: obligation.recursion_depth, }; if self.predicate_may_hold(&non_const_obligation) { @@ -3123,7 +3127,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { format!( "the trait `{}` is implemented for `{}`, \ but that implementation is not `const`", - non_const_predicate.print_modifiers_and_trait_path(), + unconst_pred.print_modifiers_and_trait_path(), trait_ref.skip_binder().self_ty(), ), ); diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 220b3576ddbd6..ff7854d51d915 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -3136,7 +3136,6 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { ObligationCauseCode::ImplDerivedObligation(ref data) => { let mut parent_trait_pred = self.resolve_vars_if_possible(data.derived.parent_trait_pred); - parent_trait_pred.remap_constness_diag(param_env); let parent_def_id = parent_trait_pred.def_id(); let (self_ty, file) = self.tcx.short_ty_string(parent_trait_pred.skip_binder().self_ty()); diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 6bab87e5de546..785ce1548a993 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -133,7 +133,7 @@ pub fn type_known_to_meet_bound_modulo_regions<'tcx>( def_id: DefId, ) -> bool { let trait_ref = ty::TraitRef::new(infcx.tcx, def_id, [ty]); - pred_known_to_hold_modulo_regions(infcx, param_env, trait_ref.without_const()) + pred_known_to_hold_modulo_regions(infcx, param_env, trait_ref) } /// FIXME(@lcnr): this function doesn't seem right and shouldn't exist? diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index 143e8412967e0..35d2468bcd03a 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -576,7 +576,6 @@ fn virtual_call_violation_for_method<'tcx>( // implement auto traits if the underlying type does as well. if let ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref: pred_trait_ref, - constness: ty::BoundConstness::NotConst, polarity: ty::ImplPolarity::Positive, }) = pred.kind().skip_binder() && pred_trait_ref.self_ty() == tcx.types.self_param diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index a39fc1f177185..3fab8c7f02073 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -1305,7 +1305,7 @@ fn normalize_to_error<'a, 'tcx>( cause, recursion_depth: depth, param_env, - predicate: trait_ref.without_const().to_predicate(selcx.tcx()), + predicate: trait_ref.to_predicate(selcx.tcx()), }; let tcx = selcx.infcx.tcx; let new_value = selcx.infcx.next_ty_var(TypeVariableOrigin { @@ -1866,8 +1866,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( if selcx.infcx.predicate_must_hold_modulo_regions( &obligation.with( selcx.tcx(), - ty::TraitRef::from_lang_item(selcx.tcx(), LangItem::Sized, obligation.cause.span(),[self_ty]) - .without_const(), + ty::TraitRef::from_lang_item(selcx.tcx(), LangItem::Sized, obligation.cause.span(),[self_ty]), ), ) => { @@ -2149,8 +2148,7 @@ fn confirm_builtin_candidate<'cx, 'tcx>( LangItem::Sized, obligation.cause.span(), [self_ty], - ) - .without_const(); + ); obligations.push(obligation.with(tcx, sized_predicate)); } (metadata_ty.into(), obligations) diff --git a/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs b/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs index a50644bb70920..65f32b1c48a4d 100644 --- a/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs +++ b/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs @@ -1,5 +1,4 @@ use rustc_infer::traits::{TraitEngine, TraitEngineExt}; -use rustc_middle::ty; use crate::infer::canonical::OriginalQueryValues; use crate::infer::InferCtxt; @@ -66,17 +65,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { ) -> Result { let mut _orig_values = OriginalQueryValues::default(); - let param_env = match obligation.predicate.kind().skip_binder() { - ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred)) => { - // we ignore the value set to it. - let mut _constness = pred.constness; - obligation - .param_env - .with_constness(_constness.and(obligation.param_env.constness())) - } - // constness has no effect on the given predicate. - _ => obligation.param_env.without_const(), - }; + let param_env = obligation.param_env; if self.next_trait_solver() { self.probe(|snapshot| { diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index aa195d70a9f6d..ab8954eed0a48 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -839,7 +839,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ) { // If the predicate is `~const Destruct` in a non-const environment, we don't actually need // to check anything. We'll short-circuit checking any obligations in confirmation, too. - if !obligation.is_const() { + // TODO check this + let host_effect_idx = self.infcx.tcx.generics_of(obligation.predicate.def_id()).host_effect_index; + if let Some(idx) = host_effect_idx && obligation.predicate.skip_binder().trait_ref.args.const_at(idx) == self.tcx().consts.true_ { candidates.vec.push(ConstDestructCandidate(None)); return; } diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 2cb2895b47642..cb165bc3607b4 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -13,8 +13,8 @@ use rustc_infer::infer::LateBoundRegionConversionTime::HigherRankedType; use rustc_infer::infer::{DefineOpaqueTypes, InferOk}; use rustc_middle::traits::SelectionOutputTypeParameterMismatch; use rustc_middle::ty::{ - self, Binder, GenericArgs, GenericArgsRef, GenericParamDefKind, ToPolyTraitRef, ToPredicate, - TraitPredicate, TraitRef, Ty, TyCtxt, TypeVisitableExt, + self, GenericArgs, GenericArgsRef, GenericParamDefKind, ToPolyTraitRef, ToPredicate, + TraitPredicate, Ty, TyCtxt, TypeVisitableExt, }; use rustc_span::def_id::DefId; @@ -59,7 +59,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ParamCandidate(param) => { let obligations = self.confirm_param_candidate(obligation, param.map_bound(|t| t.trait_ref)); - ImplSource::Param(obligations, param.skip_binder().constness) + ImplSource::Param(obligations) } ImplCandidate(impl_def_id) => { @@ -72,8 +72,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } ProjectionCandidate(idx, constness) => { - let obligations = self.confirm_projection_candidate(obligation, idx)?; - ImplSource::Param(obligations, constness) + let obligations = self.confirm_projection_candidate(obligation, idx, constness)?; + ImplSource::Param(obligations) } ObjectCandidate(idx) => { @@ -135,14 +135,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { subobligation.set_depth_from_parent(obligation.recursion_depth); } - if !obligation.predicate.is_const_if_const() { - // normalize nested predicates according to parent predicate's constness. - impl_src = impl_src.map(|mut o| { - o.predicate = o.predicate.without_const(self.tcx()); - o - }); - } - Ok(impl_src) } @@ -150,6 +142,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { &mut self, obligation: &PolyTraitObligation<'tcx>, idx: usize, + host_effect_param: Option> ) -> Result>, SelectionError<'tcx>> { let tcx = self.tcx(); @@ -225,6 +218,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // where-clause trait-ref could be unified with the obligation // trait-ref. Repeat that unification now without any // transactional boundary; it should not fail. + // TODO constness could mismatch? match self.match_where_clause_trait_ref(obligation, param) { Ok(obligations) => obligations, Err(()) => { @@ -681,7 +675,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let mut nested = self.confirm_poly_trait_refs(obligation, trait_ref)?; let cause = obligation.derived_cause(BuiltinDerivedObligation); - if obligation.is_const() && !is_const { + // TODO don't think we need this + /*if nested. && !is_const { // function is a trait method if let ty::FnDef(def_id, args) = self_ty.kind() && let Some(trait_id) = tcx.trait_of_item(*def_id) { let trait_ref = TraitRef::from_method(tcx, trait_id, *args); @@ -689,7 +684,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let obligation = Obligation::new(tcx, cause.clone(), obligation.param_env, poly_trait_pred); nested.push(obligation); } - } + }*/ // Confirm the `type Output: Sized;` bound that is present on `FnOnce` let output_ty = self.infcx.instantiate_binder_with_placeholders(sig.output()); @@ -1208,9 +1203,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { impl_def_id: Option, ) -> Result>, SelectionError<'tcx>> { // `~const Destruct` in a non-const environment is always trivially true, since our type is `Drop` - if !obligation.is_const() { + // TODO hmm? + /*if obligation.predicate.skip_binder().trait_ref.host_effect_param().is_none() { return Ok(vec![]); - } + }*/ let drop_trait = self.tcx().require_lang_item(LangItem::Drop, None); @@ -1223,6 +1219,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // If we have a custom `impl const Drop`, then // first check it like a regular impl candidate. // This is copied from confirm_impl_candidate but remaps the predicate to `~const Drop` beforehand. + // TODO is this needed? if let Some(impl_def_id) = impl_def_id { let mut new_obligation = obligation.clone(); new_obligation.predicate = new_obligation.predicate.map_bound(|mut trait_pred| { @@ -1320,9 +1317,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { self.tcx(), LangItem::Destruct, cause.span, + // TODO const substs [nested_ty], ), - constness: ty::BoundConstness::ConstIfConst, polarity: ty::ImplPolarity::Positive, }), &mut nested, @@ -1346,9 +1343,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { self.tcx(), LangItem::Destruct, cause.span, + // TODO const substs [nested_ty], ), - constness: ty::BoundConstness::ConstIfConst, polarity: ty::ImplPolarity::Positive, }); diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index e086489b1bcb6..ad36af2837e14 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1000,13 +1000,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } let stack = self.push_stack(previous_stack, &obligation); - let mut fresh_trait_pred = stack.fresh_trait_pred; - let mut param_env = obligation.param_env; - - fresh_trait_pred = fresh_trait_pred.map_bound(|mut pred| { - pred.remap_constness(&mut param_env); - pred - }); + let fresh_trait_pred = stack.fresh_trait_pred; + let param_env = obligation.param_env; debug!(?fresh_trait_pred); @@ -1398,16 +1393,18 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let tcx = self.tcx(); let mut result = Vec::with_capacity(candidates.len()); + let host_effect_idx = tcx.generics_of(obligation.predicate.def_id()).host_effect_index; + for candidate in candidates { // Respect const trait obligations - if obligation.is_const() { + if let Some(idx) = host_effect_idx { match candidate { // const impl ImplCandidate(def_id) if tcx.constness(def_id) == hir::Constness::Const => {} - // const param - ParamCandidate(trait_pred) if trait_pred.is_const_if_const() => {} - // const projection - ProjectionCandidate(_, ty::BoundConstness::ConstIfConst) + // param could be const, we need to confirm via nested obligations + ParamCandidate(_) + // projection could be const, we need to confirm via nested obligations + | ProjectionCandidate(_, Some(_)) // auto trait impl | AutoImplCandidate // generator / future, this will raise error in other places @@ -1528,7 +1525,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { fn check_candidate_cache( &mut self, - mut param_env: ty::ParamEnv<'tcx>, + param_env: ty::ParamEnv<'tcx>, cache_fresh_trait_pred: ty::PolyTraitPredicate<'tcx>, ) -> Option>> { // Neither the global nor local cache is aware of intercrate @@ -1539,8 +1536,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { return None; } let tcx = self.tcx(); - let mut pred = cache_fresh_trait_pred.skip_binder(); - pred.remap_constness(&mut param_env); + let pred = cache_fresh_trait_pred.skip_binder(); if self.can_use_global_caches(param_env) { if let Some(res) = tcx.selection_cache.get(&(param_env, pred), tcx) { @@ -1586,15 +1582,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { #[instrument(skip(self, param_env, cache_fresh_trait_pred, dep_node), level = "debug")] fn insert_candidate_cache( &mut self, - mut param_env: ty::ParamEnv<'tcx>, + param_env: ty::ParamEnv<'tcx>, cache_fresh_trait_pred: ty::PolyTraitPredicate<'tcx>, dep_node: DepNodeIndex, candidate: SelectionResult<'tcx, SelectionCandidate<'tcx>>, ) { let tcx = self.tcx(); - let mut pred = cache_fresh_trait_pred.skip_binder(); - - pred.remap_constness(&mut param_env); + let pred = cache_fresh_trait_pred.skip_binder(); if !self.can_cache_candidate(&candidate) { debug!(?pred, ?candidate, "insert_candidate_cache - candidate is not cacheable"); @@ -1628,7 +1622,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { fn match_projection_obligation_against_definition_bounds( &mut self, obligation: &PolyTraitObligation<'tcx>, - ) -> smallvec::SmallVec<[(usize, ty::BoundConstness); 2]> { + ) -> smallvec::SmallVec<[(usize, Option>); 2]> { let poly_trait_predicate = self.infcx.resolve_vars_if_possible(obligation.predicate); let placeholder_trait_predicate = self.infcx.instantiate_binder_with_placeholders(poly_trait_predicate); @@ -1677,7 +1671,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { _ => false, } }) { - return Some((idx, pred.constness)); + return Some((idx, pred.trait_ref.host_effect_param())); } } None @@ -1849,6 +1843,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { // // This is a fix for #53123 and prevents winnowing from accidentally extending the // lifetime of a variable. + // FIXME(effects) winnow should prefer candidates with const `ParamCandidate` match (&other.candidate, &victim.candidate) { (_, AutoImplCandidate) | (AutoImplCandidate, _) => { bug!( @@ -1871,7 +1866,6 @@ impl<'tcx> SelectionContext<'_, 'tcx> { (ParamCandidate(other), ParamCandidate(victim)) => { let same_except_bound_vars = other.skip_binder().trait_ref == victim.skip_binder().trait_ref - && other.skip_binder().constness == victim.skip_binder().constness && other.skip_binder().polarity == victim.skip_binder().polarity && !other.skip_binder().trait_ref.has_escaping_bound_vars(); if same_except_bound_vars { @@ -1881,12 +1875,6 @@ impl<'tcx> SelectionContext<'_, 'tcx> { // probably best characterized as a "hack", since we might prefer to just do our // best to *not* create essentially duplicate candidates in the first place. DropVictim::drop_if(other.bound_vars().len() <= victim.bound_vars().len()) - } else if other.skip_binder().trait_ref == victim.skip_binder().trait_ref - && victim.skip_binder().constness == ty::BoundConstness::NotConst - && other.skip_binder().polarity == victim.skip_binder().polarity - { - // Drop otherwise equivalent non-const candidates in favor of const candidates. - DropVictim::Yes } else { DropVictim::No } diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs index b61b209654c1d..ac97b0904b25b 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs @@ -500,16 +500,12 @@ pub(crate) fn to_pretty_impl_header(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Opti let mut pretty_predicates = Vec::with_capacity(predicates.len() + types_without_default_bounds.len()); - for (mut p, _) in predicates { + for (p, _) in predicates { if let Some(poly_trait_ref) = p.as_trait_clause() { if Some(poly_trait_ref.def_id()) == sized_trait { types_without_default_bounds.remove(&poly_trait_ref.self_ty().skip_binder()); continue; } - - if ty::BoundConstness::ConstIfConst == poly_trait_ref.skip_binder().constness { - p = p.without_const(tcx); - } } pretty_predicates.push(p.to_string()); } diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index 7b34908c4bed4..1062461adaf5c 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -101,7 +101,7 @@ impl<'tcx> TraitAliasExpander<'tcx> { fn expand(&mut self, item: &TraitAliasExpansionInfo<'tcx>) -> bool { let tcx = self.tcx; let trait_ref = item.trait_ref(); - let pred = trait_ref.without_const().to_predicate(tcx); + let pred = trait_ref.to_predicate(tcx); debug!("expand_trait_aliases: trait_ref={:?}", trait_ref); @@ -114,7 +114,7 @@ impl<'tcx> TraitAliasExpander<'tcx> { // Don't recurse if this trait alias is already on the stack for the DFS search. let anon_pred = anonymize_predicate(tcx, pred); if item.path.iter().rev().skip(1).any(|&(tr, _)| { - anonymize_predicate(tcx, tr.without_const().to_predicate(tcx)) == anon_pred + anonymize_predicate(tcx, tr.to_predicate(tcx)) == anon_pred }) { return false; } diff --git a/compiler/rustc_trait_selection/src/traits/vtable.rs b/compiler/rustc_trait_selection/src/traits/vtable.rs index b4f614e3e2202..a67ba2a861ac3 100644 --- a/compiler/rustc_trait_selection/src/traits/vtable.rs +++ b/compiler/rustc_trait_selection/src/traits/vtable.rs @@ -85,7 +85,7 @@ fn prepare_vtable_segments_inner<'tcx, T>( let mut emit_vptr_on_new_entry = false; let mut visited = PredicateSet::new(tcx); - let predicate = trait_ref.without_const().to_predicate(tcx); + let predicate = trait_ref.to_predicate(tcx); let mut stack: SmallVec<[(ty::PolyTraitRef<'tcx>, _, _); 5]> = smallvec![(trait_ref, emit_vptr_on_new_entry, maybe_iter(None))]; visited.insert(predicate); diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 5f6bb04fda472..53be8c4195c4e 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -347,12 +347,9 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { return; } - // if the trait predicate is not const, the wf obligations should not be const as well. - let obligations = if trait_pred.constness == ty::BoundConstness::NotConst { - self.nominal_obligations_without_const(trait_ref.def_id, trait_ref.args) - } else { - self.nominal_obligations(trait_ref.def_id, trait_ref.args) - }; + // FIXME(effects) do we need special handling for nominal obligation + // in relation to the host effect? + let obligations = self.nominal_obligations(trait_ref.def_id, trait_ref.args); debug!("compute_trait_pred obligations {:?}", obligations); let param_env = self.param_env; @@ -446,7 +443,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { // `i32: Copy` // ] // Projection types do not require const predicates. - let obligations = self.nominal_obligations_without_const(data.def_id, data.args); + let obligations = self.nominal_obligations(data.def_id, data.args); self.out.extend(obligations); self.compute_projection_args(data.args); @@ -473,7 +470,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { &mut self.out, ); // Inherent projection types do not require const predicates. - let obligations = self.nominal_obligations_without_const(data.def_id, args); + let obligations = self.nominal_obligations(data.def_id, args); self.out.extend(obligations); } @@ -516,7 +513,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { cause, self.recursion_depth, self.param_env, - ty::Binder::dummy(trait_ref).without_const(), + ty::Binder::dummy(trait_ref), )); } } @@ -667,7 +664,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { } ty::FnDef(did, args) => { - let obligations = self.nominal_obligations_without_const(did, args); + let obligations = self.nominal_obligations(did, args); self.out.extend(obligations); } @@ -822,11 +819,10 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { } #[instrument(level = "debug", skip(self))] - fn nominal_obligations_inner( + fn nominal_obligations( &mut self, def_id: DefId, args: GenericArgsRef<'tcx>, - remap_constness: bool, ) -> Vec> { let predicates = self.tcx().predicates_of(def_id); let mut origins = vec![def_id; predicates.predicates.len()]; @@ -841,16 +837,13 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { debug_assert_eq!(predicates.predicates.len(), origins.len()); iter::zip(predicates, origins.into_iter().rev()) - .map(|((mut pred, span), origin_def_id)| { + .map(|((pred, span), origin_def_id)| { let code = if span.is_dummy() { traits::ItemObligation(origin_def_id) } else { traits::BindingObligation(origin_def_id, span) }; let cause = self.cause(code); - if remap_constness { - pred = pred.without_const(self.tcx()); - } traits::Obligation::with_depth( self.tcx(), cause, @@ -863,22 +856,6 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { .collect() } - fn nominal_obligations( - &mut self, - def_id: DefId, - args: GenericArgsRef<'tcx>, - ) -> Vec> { - self.nominal_obligations_inner(def_id, args, false) - } - - fn nominal_obligations_without_const( - &mut self, - def_id: DefId, - args: GenericArgsRef<'tcx>, - ) -> Vec> { - self.nominal_obligations_inner(def_id, args, true) - } - fn from_object_ty( &mut self, ty: Ty<'tcx>, diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 505f78d0e5fef..062cdedad6e3f 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -60,7 +60,7 @@ fn sized_constraint_for_ty<'tcx>( let Some(sized_trait) = tcx.lang_items().sized_trait() else { return vec![ty] }; let sized_predicate = - ty::TraitRef::new(tcx, sized_trait, [ty]).without_const().to_predicate(tcx); + ty::TraitRef::new(tcx, sized_trait, [ty]).to_predicate(tcx); let predicates = tcx.predicates_of(adtdef.did()).predicates; if predicates.iter().any(|(p, _)| *p == sized_predicate) { vec![] } else { vec![ty] } } From 76eff8e3009aeec80350e395f255a9e9577ff125 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Mon, 26 Jun 2023 09:05:02 +0000 Subject: [PATCH 2/9] fix an issue with inferring host param --- compiler/rustc_hir_analysis/src/astconv/mod.rs | 2 +- compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs | 8 ++++---- library/core/src/lib.rs | 3 +++ src/tools/clippy/clippy_lints/src/derive.rs | 1 - .../effects/infer-host.rs | 13 +++++++++++++ .../effects/super-traits.rs | 17 +++++++++++++++++ 6 files changed, 38 insertions(+), 6 deletions(-) create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/effects/infer-host.rs create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/effects/super-traits.rs diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 4ae5829fbd415..9b8e51d77bab9 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -2126,7 +2126,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { kind => bug!("unexpected definition kind {:?} for {:?}", kind, def_id), } - debug!("path_segs = {:?}", path_segs); + debug!(?path_segs); path_segs } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index e3a643a8c7b79..d0e318eea6029 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -1349,10 +1349,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } GenericParamDefKind::Const { has_default } => { - if !infer_args && has_default { - tcx.const_param_default(param.def_id) - .instantiate(tcx, args.unwrap()) - .into() + // TODO: check if this is always good to be infer var + let is_host = param.name == sym::host; + if !infer_args && has_default && !is_host { + tcx.const_param_default(param.def_id).instantiate(tcx, args.unwrap()).into() } else { self.fcx.var_for_def(self.span, param) } diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 741de3221ee80..47a89e1cd01f6 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -257,6 +257,9 @@ #![feature(wasm_target_feature)] // tidy-alphabetical-end +// TODO +// #![cfg_attr(not(bootstrap), effects)] + // allow using `core::` in intra-doc links #[allow(unused_extern_crates)] extern crate self as core; diff --git a/src/tools/clippy/clippy_lints/src/derive.rs b/src/tools/clippy/clippy_lints/src/derive.rs index c343f248d06d9..9eed5f2dd0718 100644 --- a/src/tools/clippy/clippy_lints/src/derive.rs +++ b/src/tools/clippy/clippy_lints/src/derive.rs @@ -519,7 +519,6 @@ fn param_env_for_derived_eq(tcx: TyCtxt<'_>, did: DefId, eq_trait_id: DefId) -> params.iter().filter(|&&(_, needs_eq)| needs_eq).map(|&(param, _)| { ClauseKind::Trait(TraitPredicate { trait_ref: ty::TraitRef::new(tcx, eq_trait_id, [tcx.mk_param_from_def(param)]), - constness: BoundConstness::NotConst, polarity: ImplPolarity::Positive, }) .to_predicate(tcx) diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/infer-host.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/infer-host.rs new file mode 100644 index 0000000000000..60b2f6349183a --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/infer-host.rs @@ -0,0 +1,13 @@ +// check-pass + +#![feature(const_trait_impl, effects)] + +// Host param needs to get infer even if there are generic params supplied + +pub const fn hmm() -> usize { + 1 +} + +pub const fn uwu(x: [u8; hmm::<()>()]) {} + +fn main() {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/super-traits.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/super-traits.rs new file mode 100644 index 0000000000000..e649dd46d2b84 --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/super-traits.rs @@ -0,0 +1,17 @@ +// check-pass + +// misc tests not directly related to const traits, but encountered +// while implementing effects + +#![feature(const_trait_impl, effects)] + +// #[const_trait] +pub trait X {} + +pub trait Y: X {} + +impl X for () {} + +impl Y for () {} + +fn main() {} From 13ff467f4e1f88388aa2cc9a5404a7ec4db8df51 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Tue, 25 Jul 2023 05:58:53 +0000 Subject: [PATCH 3/9] initial work on lowering impl const to bind to host effect param --- compiler/rustc_ast/src/ast.rs | 10 +++++ compiler/rustc_ast_lowering/src/asm.rs | 1 + compiler/rustc_ast_lowering/src/expr.rs | 6 +++ compiler/rustc_ast_lowering/src/item.rs | 3 +- compiler/rustc_ast_lowering/src/lib.rs | 43 +++++++++++++++---- compiler/rustc_ast_lowering/src/pat.rs | 3 ++ compiler/rustc_ast_lowering/src/path.rs | 17 +++++++- compiler/rustc_hir/src/hir.rs | 3 +- compiler/rustc_hir/src/intravisit.rs | 1 - compiler/rustc_hir_pretty/src/lib.rs | 5 --- compiler/rustc_middle/src/ty/context.rs | 6 ++- .../const-drop-fail-2.rs | 2 +- 12 files changed, 80 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 17b73468a3114..a23ae2d9adc11 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -313,6 +313,16 @@ pub enum TraitBoundModifier { MaybeConstMaybe, } +impl TraitBoundModifier { + pub fn to_constness(self) -> Const { + match self { + // TODO span + Self::MaybeConst => Const::Yes(DUMMY_SP), + _ => Const::No, + } + } +} + /// The AST represents all type param bounds as types. /// `typeck::collect::compute_bounds` matches these against /// the "special" built-in traits (see `middle::lang_items`) and diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs index ab55c09465b1b..a1e626996800f 100644 --- a/compiler/rustc_ast_lowering/src/asm.rs +++ b/compiler/rustc_ast_lowering/src/asm.rs @@ -207,6 +207,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { &sym.path, ParamMode::Optional, &ImplTraitContext::Disallowed(ImplTraitPosition::Path), + None, ); hir::InlineAsmOperand::SymStatic { path, def_id } } else { diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 0954cf03da9a8..10a9c5b760d2c 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -100,6 +100,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ParamMode::Optional, ParenthesizedGenericArgs::Err, &ImplTraitContext::Disallowed(ImplTraitPosition::Path), + None )); let receiver = self.lower_expr(receiver); let args = @@ -260,6 +261,7 @@ impl<'hir> LoweringContext<'_, 'hir> { path, ParamMode::Optional, &ImplTraitContext::Disallowed(ImplTraitPosition::Path), + None, ); hir::ExprKind::Path(qpath) } @@ -307,6 +309,7 @@ impl<'hir> LoweringContext<'_, 'hir> { &se.path, ParamMode::Optional, &ImplTraitContext::Disallowed(ImplTraitPosition::Path), + None )), self.arena .alloc_from_iter(se.fields.iter().map(|x| self.lower_expr_field(x))), @@ -1179,6 +1182,7 @@ impl<'hir> LoweringContext<'_, 'hir> { path, ParamMode::Optional, &ImplTraitContext::Disallowed(ImplTraitPosition::Path), + None, ); // Destructure like a tuple struct. let tuple_struct_pat = hir::PatKind::TupleStruct( @@ -1198,6 +1202,7 @@ impl<'hir> LoweringContext<'_, 'hir> { path, ParamMode::Optional, &ImplTraitContext::Disallowed(ImplTraitPosition::Path), + None ); // Destructure like a unit struct. let unit_struct_pat = hir::PatKind::Path(qpath); @@ -1222,6 +1227,7 @@ impl<'hir> LoweringContext<'_, 'hir> { &se.path, ParamMode::Optional, &ImplTraitContext::Disallowed(ImplTraitPosition::Path), + None, ); let fields_omitted = match &se.rest { StructRest::Base(e) => { diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 2f58f566c81c3..9cfc7e875090a 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -85,6 +85,7 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> { allow_try_trait: Some([sym::try_trait_v2, sym::yeet_desugar_details][..].into()), allow_gen_future: Some([sym::gen_future, sym::closure_track_caller][..].into()), generics_def_id_map: Default::default(), + host_param_id: None, }; lctx.with_hir_id_owner(owner, |lctx| f(lctx)); @@ -378,6 +379,7 @@ impl<'hir> LoweringContext<'_, 'hir> { self.lower_generics(ast_generics, *constness, id, &itctx, |this| { let trait_ref = trait_ref.as_ref().map(|trait_ref| { this.lower_trait_ref( + *constness, trait_ref, &ImplTraitContext::Disallowed(ImplTraitPosition::Trait), ) @@ -408,7 +410,6 @@ impl<'hir> LoweringContext<'_, 'hir> { polarity, defaultness, defaultness_span, - constness: self.lower_constness(*constness), generics, of_trait: trait_ref, self_ty: lowered_ty, diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index ac75069004678..e8ef0feb0b94f 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -142,6 +142,8 @@ struct LoweringContext<'a, 'hir> { /// defined on the TAIT, so we have type Foo<'a1> = ... and we establish a mapping in this /// field from the original parameter 'a to the new parameter 'a1. generics_def_id_map: Vec>, + + host_param_id: Option, } trait ResolverAstLoweringExt { @@ -1267,6 +1269,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { span: t.span }, itctx, + // TODO? + ast::Const::No, ); let bounds = this.arena.alloc_from_iter([bound]); let lifetime_bound = this.elided_dyn_bound(t.span); @@ -1277,7 +1281,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } let id = self.lower_node_id(t.id); - let qpath = self.lower_qpath(t.id, qself, path, param_mode, itctx); + let qpath = self.lower_qpath(t.id, qself, path, param_mode, itctx, None); self.ty_path(id, t.span, qpath) } @@ -1361,10 +1365,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { this.arena.alloc_from_iter(bounds.iter().filter_map(|bound| match bound { GenericBound::Trait( ty, - TraitBoundModifier::None + modifier @ (TraitBoundModifier::None | TraitBoundModifier::MaybeConst - | TraitBoundModifier::Negative, - ) => Some(this.lower_poly_trait_ref(ty, itctx)), + | TraitBoundModifier::Negative), + ) => Some(this.lower_poly_trait_ref(ty, itctx, modifier.to_constness())), // `~const ?Bound` will cause an error during AST validation // anyways, so treat it like `?Bound` as compilation proceeds. GenericBound::Trait( @@ -2189,7 +2193,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ) -> hir::GenericBound<'hir> { match tpb { GenericBound::Trait(p, modifier) => hir::GenericBound::Trait( - self.lower_poly_trait_ref(p, itctx), + self.lower_poly_trait_ref(p, itctx, modifier.to_constness()), self.lower_trait_bound_modifier(*modifier), ), GenericBound::Outlives(lifetime) => { @@ -2332,8 +2336,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } } - fn lower_trait_ref(&mut self, p: &TraitRef, itctx: &ImplTraitContext) -> hir::TraitRef<'hir> { - let path = match self.lower_qpath(p.ref_id, &None, &p.path, ParamMode::Explicit, itctx) { + fn lower_trait_ref(&mut self, constness: ast::Const, p: &TraitRef, itctx: &ImplTraitContext) -> hir::TraitRef<'hir> { + let path = match self.lower_qpath(p.ref_id, &None, &p.path, ParamMode::Explicit, itctx, Some(constness)) { hir::QPath::Resolved(None, path) => path, qpath => panic!("lower_trait_ref: unexpected QPath `{qpath:?}`"), }; @@ -2345,10 +2349,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { &mut self, p: &PolyTraitRef, itctx: &ImplTraitContext, + constness: ast::Const, ) -> hir::PolyTraitRef<'hir> { let bound_generic_params = self.lower_lifetime_binder(p.trait_ref.ref_id, &p.bound_generic_params); - let trait_ref = self.lower_trait_ref(&p.trait_ref, itctx); + let trait_ref = self.lower_trait_ref(constness, &p.trait_ref, itctx,); hir::PolyTraitRef { bound_generic_params, trait_ref, span: self.lower_span(p.span) } } @@ -2702,6 +2707,28 @@ struct GenericArgsCtor<'hir> { } impl<'hir> GenericArgsCtor<'hir> { + fn push_constness(&mut self, lcx: &mut LoweringContext<'_, 'hir>, constness: ast::Const) { + let span = if let ast::Const::Yes(sp) = constness { + sp + } else { + DUMMY_SP + }; + let id = lcx.next_node_id(); + lcx.lower_body(|lcx| { + (&[], match constness { + ast::Const::Yes(_) => lcx.expr_ident_mut(span, Ident { name: sym::host, span }, binding), + ast::Const::No => lcx.expr(span, hir::ExprKind::Lit(lcx.arena.alloc(hir::Lit { span, node: ast::LitKind::Bool(true) }))), + }) + }); + let def = lcx.create_def(lcx.current_hir_id_owner.def_id, id, DefPathData::AnonConst, span); + self.args.push(hir::GenericArg::Const(hir::ConstArg { + value: hir::AnonConst { + def_id, + }, + span, + })) + } + fn is_empty(&self) -> bool { self.args.is_empty() && self.bindings.is_empty() diff --git a/compiler/rustc_ast_lowering/src/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs index 2509b70563956..a30f264bc7dc7 100644 --- a/compiler/rustc_ast_lowering/src/pat.rs +++ b/compiler/rustc_ast_lowering/src/pat.rs @@ -38,6 +38,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { path, ParamMode::Optional, &ImplTraitContext::Disallowed(ImplTraitPosition::Path), + None, ); let (pats, ddpos) = self.lower_pat_tuple(pats, "tuple struct"); break hir::PatKind::TupleStruct(qpath, pats, ddpos); @@ -54,6 +55,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { path, ParamMode::Optional, &ImplTraitContext::Disallowed(ImplTraitPosition::Path), + None, ); break hir::PatKind::Path(qpath); } @@ -64,6 +66,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { path, ParamMode::Optional, &ImplTraitContext::Disallowed(ImplTraitPosition::Path), + None, ); let fs = self.arena.alloc_from_iter(fields.iter().map(|f| { diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs index 441282c05b424..1ff172e6e1548 100644 --- a/compiler/rustc_ast_lowering/src/path.rs +++ b/compiler/rustc_ast_lowering/src/path.rs @@ -23,6 +23,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { p: &Path, param_mode: ParamMode, itctx: &ImplTraitContext, + // constness of the impl/bound if this is a trait path + constness: Option, ) -> hir::QPath<'hir> { let qself_position = qself.as_ref().map(|q| q.position); let qself = qself.as_ref().map(|q| self.lower_ty(&q.ty, itctx)); @@ -73,6 +75,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { param_mode, parenthesized_generic_args, itctx, + // if this is the last segment, add constness to the trait path + if i == proj_start - 1 { + constness + } else { + None + } ) }, )), @@ -119,6 +127,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { param_mode, ParenthesizedGenericArgs::Err, itctx, + None, )); let qpath = hir::QPath::TypeRelative(ty, hir_segment); @@ -159,6 +168,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { param_mode, ParenthesizedGenericArgs::Err, &ImplTraitContext::Disallowed(ImplTraitPosition::Path), + None, ) })), span: self.lower_span(p.span), @@ -172,8 +182,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { param_mode: ParamMode, parenthesized_generic_args: ParenthesizedGenericArgs, itctx: &ImplTraitContext, + constness: Option, ) -> hir::PathSegment<'hir> { - debug!("path_span: {:?}, lower_path_segment(segment: {:?})", path_span, segment,); + debug!("path_span: {:?}, lower_path_segment(segment: {:?})", path_span, segment); let (mut generic_args, infer_args) = if let Some(generic_args) = segment.args.as_deref() { match generic_args { GenericArgs::AngleBracketed(data) => { @@ -231,6 +242,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ) }; + if let Some(constness) = constness { + generic_args.push_constness(self, constness); + } + let has_lifetimes = generic_args.args.iter().any(|arg| matches!(arg, GenericArg::Lifetime(_))); diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 3663c450ba64d..14687eafe2405 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -3357,7 +3357,8 @@ pub struct Impl<'hir> { // We do not put a `Span` in `Defaultness` because it breaks foreign crate metadata // decoding as `Span`s cannot be decoded when a `Session` is not available. pub defaultness_span: Option, - pub constness: Constness, + // TODO remove this comment + // pub constness: Constness, pub generics: &'hir Generics<'hir>, /// The trait being implemented, if any. diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 347c1f4637f17..64d643b67ce16 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -516,7 +516,6 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) { unsafety: _, defaultness: _, polarity: _, - constness: _, defaultness_span: _, ref generics, ref of_trait, diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index a699cd6c942eb..9f9489b22b2c9 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -622,7 +622,6 @@ impl<'a> State<'a> { unsafety, polarity, defaultness, - constness, defaultness_span: _, generics, ref of_trait, @@ -639,10 +638,6 @@ impl<'a> State<'a> { self.space(); } - if constness == hir::Constness::Const { - self.word_nbsp("const"); - } - if let hir::ImplPolarity::Negative(_) = polarity { self.word("!"); } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index aa1f8e48b1b79..0834e11d1e32f 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1987,13 +1987,15 @@ impl<'tcx> TyCtxt<'tcx> { let hir_id = self.local_def_id_to_hir_id(local_def_id); let node = self.hir().get(hir_id); - matches!( + // TODO + false + /*matches!( node, hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(hir::Impl { constness: hir::Constness::Const, .. }), .. }) - ) + )*/ } pub fn local_def_id_to_hir_id(self, local_def_id: LocalDefId) -> HirId { diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.rs index 3de9d37d49337..10f6c5c064a34 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.rs @@ -1,5 +1,5 @@ // known-bug: #110395 -#![feature(const_trait_impl)] +#![feature(const_trait_impl, effects)] #![feature(const_mut_refs)] #![cfg_attr(precise, feature(const_precise_live_drops))] From bc91d53532a0e32b8fbb3bb7e58e4bf9b6437ce9 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Tue, 25 Jul 2023 10:53:14 +0000 Subject: [PATCH 4/9] up --- compiler/rustc_ast_lowering/src/expr.rs | 6 +- compiler/rustc_ast_lowering/src/lib.rs | 58 +++++++++++++------ compiler/rustc_ast_lowering/src/path.rs | 6 +- .../src/type_check/canonical.rs | 5 +- .../src/const_eval/fn_queries.rs | 2 +- .../src/transform/check_consts/mod.rs | 12 +--- .../src/transform/check_consts/qualifs.rs | 5 +- .../src/astconv/object_safety.rs | 5 +- .../rustc_hir_analysis/src/check/wfcheck.rs | 6 +- .../src/collect/predicates_of.rs | 3 +- .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 5 +- .../rustc_hir_typeck/src/fn_ctxt/checks.rs | 10 ---- compiler/rustc_hir_typeck/src/method/mod.rs | 10 +--- compiler/rustc_hir_typeck/src/method/probe.rs | 3 +- .../rustc_hir_typeck/src/method/suggest.rs | 2 +- compiler/rustc_middle/src/ty/context.rs | 12 +--- compiler/rustc_middle/src/ty/mod.rs | 5 +- compiler/rustc_middle/src/ty/print/pretty.rs | 24 +++++--- .../src/traits/error_reporting/mod.rs | 29 +++++++--- .../src/traits/select/candidate_assembly.rs | 3 +- .../src/traits/select/confirmation.rs | 2 +- .../rustc_trait_selection/src/traits/util.rs | 10 +++- compiler/rustc_ty_utils/src/ty.rs | 3 +- 23 files changed, 113 insertions(+), 113 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 10a9c5b760d2c..f06d6fc6e5bd2 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -100,7 +100,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ParamMode::Optional, ParenthesizedGenericArgs::Err, &ImplTraitContext::Disallowed(ImplTraitPosition::Path), - None + None, )); let receiver = self.lower_expr(receiver); let args = @@ -309,7 +309,7 @@ impl<'hir> LoweringContext<'_, 'hir> { &se.path, ParamMode::Optional, &ImplTraitContext::Disallowed(ImplTraitPosition::Path), - None + None, )), self.arena .alloc_from_iter(se.fields.iter().map(|x| self.lower_expr_field(x))), @@ -1202,7 +1202,7 @@ impl<'hir> LoweringContext<'_, 'hir> { path, ParamMode::Optional, &ImplTraitContext::Disallowed(ImplTraitPosition::Path), - None + None, ); // Destructure like a unit struct. let unit_struct_pat = hir::PatKind::Path(qpath); diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index e8ef0feb0b94f..80f85b4baff33 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -1368,7 +1368,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { modifier @ (TraitBoundModifier::None | TraitBoundModifier::MaybeConst | TraitBoundModifier::Negative), - ) => Some(this.lower_poly_trait_ref(ty, itctx, modifier.to_constness())), + ) => { + Some(this.lower_poly_trait_ref(ty, itctx, modifier.to_constness())) + } // `~const ?Bound` will cause an error during AST validation // anyways, so treat it like `?Bound` as compilation proceeds. GenericBound::Trait( @@ -2336,8 +2338,20 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } } - fn lower_trait_ref(&mut self, constness: ast::Const, p: &TraitRef, itctx: &ImplTraitContext) -> hir::TraitRef<'hir> { - let path = match self.lower_qpath(p.ref_id, &None, &p.path, ParamMode::Explicit, itctx, Some(constness)) { + fn lower_trait_ref( + &mut self, + constness: ast::Const, + p: &TraitRef, + itctx: &ImplTraitContext, + ) -> hir::TraitRef<'hir> { + let path = match self.lower_qpath( + p.ref_id, + &None, + &p.path, + ParamMode::Explicit, + itctx, + Some(constness), + ) { hir::QPath::Resolved(None, path) => path, qpath => panic!("lower_trait_ref: unexpected QPath `{qpath:?}`"), }; @@ -2353,7 +2367,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ) -> hir::PolyTraitRef<'hir> { let bound_generic_params = self.lower_lifetime_binder(p.trait_ref.ref_id, &p.bound_generic_params); - let trait_ref = self.lower_trait_ref(constness, &p.trait_ref, itctx,); + let trait_ref = self.lower_trait_ref(constness, &p.trait_ref, itctx); hir::PolyTraitRef { bound_generic_params, trait_ref, span: self.lower_span(p.span) } } @@ -2708,23 +2722,31 @@ struct GenericArgsCtor<'hir> { impl<'hir> GenericArgsCtor<'hir> { fn push_constness(&mut self, lcx: &mut LoweringContext<'_, 'hir>, constness: ast::Const) { - let span = if let ast::Const::Yes(sp) = constness { - sp - } else { - DUMMY_SP - }; + let span = if let ast::Const::Yes(sp) = constness { sp } else { DUMMY_SP }; let id = lcx.next_node_id(); - lcx.lower_body(|lcx| { - (&[], match constness { - ast::Const::Yes(_) => lcx.expr_ident_mut(span, Ident { name: sym::host, span }, binding), - ast::Const::No => lcx.expr(span, hir::ExprKind::Lit(lcx.arena.alloc(hir::Lit { span, node: ast::LitKind::Bool(true) }))), - }) + let hir_id = lcx.next_id(); + let body = lcx.lower_body(|lcx| { + ( + &[], + match constness { + ast::Const::Yes(_) => lcx.expr_ident_mut( + span, + Ident { name: sym::host, span }, + lcx.host_param_id.unwrap(), + ), + ast::Const::No => lcx.expr( + span, + hir::ExprKind::Lit( + lcx.arena.alloc(hir::Lit { span, node: ast::LitKind::Bool(true) }), + ), + ), + }, + ) }); - let def = lcx.create_def(lcx.current_hir_id_owner.def_id, id, DefPathData::AnonConst, span); + let def_id = + lcx.create_def(lcx.current_hir_id_owner.def_id, id, DefPathData::AnonConst, span); self.args.push(hir::GenericArg::Const(hir::ConstArg { - value: hir::AnonConst { - def_id, - }, + value: hir::AnonConst { def_id, hir_id, body }, span, })) } diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs index 1ff172e6e1548..899f92a995821 100644 --- a/compiler/rustc_ast_lowering/src/path.rs +++ b/compiler/rustc_ast_lowering/src/path.rs @@ -76,11 +76,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { parenthesized_generic_args, itctx, // if this is the last segment, add constness to the trait path - if i == proj_start - 1 { - constness - } else { - None - } + if i == proj_start - 1 { constness } else { None }, ) }, )), diff --git a/compiler/rustc_borrowck/src/type_check/canonical.rs b/compiler/rustc_borrowck/src/type_check/canonical.rs index 3a788cd169ca8..16f5e68a06f55 100644 --- a/compiler/rustc_borrowck/src/type_check/canonical.rs +++ b/compiler/rustc_borrowck/src/type_check/canonical.rs @@ -90,10 +90,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { ) { self.prove_predicate( ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::Trait( - ty::TraitPredicate { - trait_ref, - polarity: ty::ImplPolarity::Positive, - }, + ty::TraitPredicate { trait_ref, polarity: ty::ImplPolarity::Positive }, ))), locations, category, diff --git a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs index fa8253d5e4966..ca4720b9cf8c9 100644 --- a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs @@ -37,7 +37,7 @@ fn constness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::Constness { match node { hir::Node::Ctor(_) => hir::Constness::Const, - hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(impl_), .. }) => impl_.constness, + hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(_), .. }) => tcx.generics_of(def_id).host_effect_index.map_or(hir::Constness::NotConst, |_| hir::Constness::Const), hir::Node::ForeignItem(hir::ForeignItem { kind: hir::ForeignItemKind::Fn(..), .. }) => { // Intrinsics use `rustc_const_{un,}stable` attributes to indicate constness. All other // foreign items cannot be evaluated at compile-time. diff --git a/compiler/rustc_const_eval/src/transform/check_consts/mod.rs b/compiler/rustc_const_eval/src/transform/check_consts/mod.rs index e77fb4ea2a2c7..ff060cce365ce 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/mod.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/mod.rs @@ -127,15 +127,9 @@ fn is_parent_const_stable_trait(tcx: TyCtxt<'_>, def_id: DefId) -> bool { let hir_id = tcx.local_def_id_to_hir_id(local_def_id); let Some(parent) = tcx.hir().opt_parent_id(hir_id) else { return false }; - let parent_def = tcx.hir().get(parent); - - if !matches!( - parent_def, - hir::Node::Item(hir::Item { - kind: hir::ItemKind::Impl(hir::Impl { constness: hir::Constness::Const, .. }), - .. - }) - ) { + + // TODO sus + if tcx.generics_of(parent.owner).host_effect_index.is_none() { return false; } diff --git a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs index 654247f32dd65..a6d19727957d2 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs @@ -170,10 +170,7 @@ impl Qualif for NeedsNonConstDrop { trace!(?impl_src); - if !matches!( - impl_src, - ImplSource::Builtin(_) | ImplSource::Param(_) - ) { + if !matches!(impl_src, ImplSource::Builtin(_) | ImplSource::Param(_)) { // If our const destruct candidate is not ConstDestruct or implied by the param env, // then it's bad return true; diff --git a/compiler/rustc_hir_analysis/src/astconv/object_safety.rs b/compiler/rustc_hir_analysis/src/astconv/object_safety.rs index da9705e2f396a..3415bb2e88671 100644 --- a/compiler/rustc_hir_analysis/src/astconv/object_safety.rs +++ b/compiler/rustc_hir_analysis/src/astconv/object_safety.rs @@ -62,10 +62,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { match bound_pred.skip_binder() { ty::ClauseKind::Trait(trait_pred) => { assert_eq!(trait_pred.polarity, ty::ImplPolarity::Positive); - trait_bounds.push(( - bound_pred.rebind(trait_pred.trait_ref), - span, - )); + trait_bounds.push((bound_pred.rebind(trait_pred.trait_ref), span)); } ty::ClauseKind::Projection(proj) => { projection_bounds.push((bound_pred.rebind(proj), span)); diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index fb2aa88ea0e92..a46d7ceb6a40c 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1194,10 +1194,8 @@ fn check_impl<'tcx>( Some(WellFormedLoc::Ty(item.hir_id().expect_owner().def_id)), trait_ref, ); - let trait_pred = ty::TraitPredicate { - trait_ref, - polarity: ty::ImplPolarity::Positive, - }; + let trait_pred = + ty::TraitPredicate { trait_ref, polarity: ty::ImplPolarity::Positive }; let mut obligations = traits::wf::trait_obligations( wfcx.infcx, wfcx.param_env, diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index 6a90668430951..19efa02a8fd51 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -769,8 +769,7 @@ pub(super) fn type_param_predicates( if param_id == item_hir_id { let identity_trait_ref = ty::TraitRef::identity(tcx, item_def_id.to_def_id()); - extend = - Some((identity_trait_ref.to_predicate(tcx), item.span)); + extend = Some((identity_trait_ref.to_predicate(tcx), item.span)); } generics } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index d0e318eea6029..0ed043889ab32 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -1352,7 +1352,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // TODO: check if this is always good to be infer var let is_host = param.name == sym::host; if !infer_args && has_default && !is_host { - tcx.const_param_default(param.def_id).instantiate(tcx, args.unwrap()).into() + tcx.const_param_default(param.def_id) + .instantiate(tcx, args.unwrap()) + .into() } else { self.fcx.var_for_def(self.span, param) } @@ -1466,7 +1468,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // N.B. We are remapping all predicates to non-const since we don't know if we just // want them as function pointers or we are calling them from a const-context. The // actual checking will occur in `rustc_const_eval::transform::check_consts`. - // TODO: HMM? self.register_predicate(obligation); } } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 9a99086829114..06567467a3add 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -1867,21 +1867,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if self.adjust_fulfillment_error_for_expr_obligation(error) || before_span != error.obligation.cause.span { - // Store both the predicate and the predicate *without constness* - // since sometimes we instantiate and check both of these in a - // method call, for example. remap_cause.insert(( before_span, error.obligation.predicate, error.obligation.cause.clone(), )); - // TODO: UM WHAT? - - /* remap_cause.insert(( - before_span, - error.obligation.predicate.without_const(self.tcx), - error.obligation.cause.clone(), - )); */ } else { // If it failed to be adjusted once around, it may be adjusted // via the "remap cause" mapping the second time... diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs index 4a7c97e77444b..597696843c40f 100644 --- a/compiler/rustc_hir_typeck/src/method/mod.rs +++ b/compiler/rustc_hir_typeck/src/method/mod.rs @@ -341,15 +341,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Construct an obligation let poly_trait_ref = ty::Binder::dummy(trait_ref); - ( - traits::Obligation::new( - self.tcx, - cause, - self.param_env, - poly_trait_ref, - ), - args, - ) + (traits::Obligation::new(self.tcx, cause, self.param_env, poly_trait_ref), args) } /// `lookup_method_in_trait` is used for overloaded operators. diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 1262a7bf76cfc..7164102a30ed8 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -1599,8 +1599,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } } } - let predicate = - ty::Binder::dummy(trait_ref).to_predicate(self.tcx); + let predicate = ty::Binder::dummy(trait_ref).to_predicate(self.tcx); parent_pred = Some(predicate); let obligation = traits::Obligation::new(self.tcx, cause.clone(), self.param_env, predicate); diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 1c43045fe6df2..ecae27327c555 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -30,8 +30,8 @@ use rustc_middle::traits::util::supertraits; use rustc_middle::ty::fast_reject::DeepRejectCtxt; use rustc_middle::ty::fast_reject::{simplify_type, TreatParams}; use rustc_middle::ty::print::{with_crate_prefix, with_forced_trimmed_paths}; -use rustc_middle::ty::{IsSuggestable, ToPredicate}; use rustc_middle::ty::{self, GenericArgKind, Ty, TyCtxt, TypeVisitableExt}; +use rustc_middle::ty::{IsSuggestable, ToPredicate}; use rustc_span::def_id::DefIdSet; use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::Symbol; diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 0834e11d1e32f..66b9dbae57d90 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1985,17 +1985,9 @@ impl<'tcx> TyCtxt<'tcx> { pub fn is_const_trait_impl_raw(self, def_id: DefId) -> bool { let Some(local_def_id) = def_id.as_local() else { return false }; let hir_id = self.local_def_id_to_hir_id(local_def_id); - let node = self.hir().get(hir_id); + let node = self.hir().attrs(hir_id); - // TODO - false - /*matches!( - node, - hir::Node::Item(hir::Item { - kind: hir::ItemKind::Impl(hir::Impl { constness: hir::Constness::Const, .. }), - .. - }) - )*/ + node.iter().any(|attr: &Attribute| {}) } pub fn local_def_id_to_hir_id(self, local_def_id: LocalDefId) -> HirId { diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index feb0fbddd61c3..d8600bbfaac23 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1243,10 +1243,7 @@ impl<'tcx> ToPredicate<'tcx> for TraitRef<'tcx> { impl<'tcx> ToPredicate<'tcx, TraitPredicate<'tcx>> for TraitRef<'tcx> { #[inline(always)] fn to_predicate(self, _tcx: TyCtxt<'tcx>) -> TraitPredicate<'tcx> { - TraitPredicate { - trait_ref: self, - polarity: ImplPolarity::Positive, - } + TraitPredicate { trait_ref: self, polarity: ImplPolarity::Positive } } } diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 0056f8461c70d..5d26439c65e5c 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -17,7 +17,7 @@ use rustc_hir::LangItem; use rustc_session::config::TrimmedDefPaths; use rustc_session::cstore::{ExternCrate, ExternCrateSource}; use rustc_session::Limit; -use rustc_span::symbol::{sym, kw, Ident, Symbol}; +use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::FileNameDisplayPreference; use rustc_target::abi::Size; use rustc_target::spec::abi::Abi; @@ -2020,12 +2020,22 @@ impl<'tcx> Printer<'tcx> for FmtPrinter<'_, 'tcx> { let tcx = self.tcx; // skip host param as those are printed as `~const` - let mut args = args.iter().copied().filter(|arg| { - match arg.unpack() { - GenericArgKind::Const(c) if tcx.features().effects && matches!(c.kind(), ty::ConstKind::Param(ty::ParamConst { name: sym::host, .. })) => tcx.sess.verbose(), - _ => true - } - }).peekable(); + let mut args = args + .iter() + .copied() + .filter(|arg| match arg.unpack() { + GenericArgKind::Const(c) + if tcx.features().effects + && matches!( + c.kind(), + ty::ConstKind::Param(ty::ParamConst { name: sym::host, .. }) + ) => + { + tcx.sess.verbose() + } + _ => true, + }) + .peekable(); if args.peek().is_some() { if self.in_value { diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 790a869731af2..89ac92bd4870e 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -372,7 +372,11 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { span: DUMMY_SP, kind: TypeVariableOriginKind::MiscVariable, }); - let trait_ref = ty::TraitRef::new(self.tcx, trait_def_id, [ty.skip_binder().into(), ty::GenericArg::from(var), host.into()]); + let trait_ref = ty::TraitRef::new( + self.tcx, + trait_def_id, + [ty.skip_binder().into(), ty::GenericArg::from(var), host.into()], + ); let obligation = Obligation::new( self.tcx, ObligationCause::dummy(), @@ -3104,14 +3108,25 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { span: Span, ) -> UnsatisfiedConst { let mut unsatisfied_const = UnsatisfiedConst(false); - if trait_ref.skip_binder().args.host_effect_param().is_some() && obligation.param_env.is_const() { + if trait_ref.skip_binder().args.host_effect_param().is_some() + && obligation.param_env.is_const() + { let unconst_pred = trait_predicate.map_bound(|mut x| { - x.trait_ref = ty::TraitRef::new(self.tcx, x.trait_ref.def_id, x.trait_ref.args.iter().map(|arg| { - match arg.unpack() { - ty::GenericArgKind::Const(c) if matches!(c.kind(), ty::ConstKind::Param(ty::ParamConst { name: sym::host, .. })) => self.tcx.consts.true_.into(), + x.trait_ref = ty::TraitRef::new( + self.tcx, + x.trait_ref.def_id, + x.trait_ref.args.iter().map(|arg| match arg.unpack() { + ty::GenericArgKind::Const(c) + if matches!( + c.kind(), + ty::ConstKind::Param(ty::ParamConst { name: sym::host, .. }) + ) => + { + self.tcx.consts.true_.into() + } _ => arg, - } - })); + }), + ); x }); let non_const_obligation = Obligation { diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index ab8954eed0a48..79fc481925fd4 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -840,7 +840,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // If the predicate is `~const Destruct` in a non-const environment, we don't actually need // to check anything. We'll short-circuit checking any obligations in confirmation, too. // TODO check this - let host_effect_idx = self.infcx.tcx.generics_of(obligation.predicate.def_id()).host_effect_index; + let host_effect_idx = + self.infcx.tcx.generics_of(obligation.predicate.def_id()).host_effect_index; if let Some(idx) = host_effect_idx && obligation.predicate.skip_binder().trait_ref.args.const_at(idx) == self.tcx().consts.true_ { candidates.vec.push(ConstDestructCandidate(None)); return; diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index cb165bc3607b4..15301c90f4177 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -142,7 +142,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { &mut self, obligation: &PolyTraitObligation<'tcx>, idx: usize, - host_effect_param: Option> + host_effect_param: Option>, ) -> Result>, SelectionError<'tcx>> { let tcx = self.tcx(); diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index 1062461adaf5c..58d78bcac0a5e 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -113,9 +113,13 @@ impl<'tcx> TraitAliasExpander<'tcx> { // Don't recurse if this trait alias is already on the stack for the DFS search. let anon_pred = anonymize_predicate(tcx, pred); - if item.path.iter().rev().skip(1).any(|&(tr, _)| { - anonymize_predicate(tcx, tr.to_predicate(tcx)) == anon_pred - }) { + if item + .path + .iter() + .rev() + .skip(1) + .any(|&(tr, _)| anonymize_predicate(tcx, tr.to_predicate(tcx)) == anon_pred) + { return false; } diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 062cdedad6e3f..a2b55c567735e 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -59,8 +59,7 @@ fn sized_constraint_for_ty<'tcx>( // it on the impl. let Some(sized_trait) = tcx.lang_items().sized_trait() else { return vec![ty] }; - let sized_predicate = - ty::TraitRef::new(tcx, sized_trait, [ty]).to_predicate(tcx); + let sized_predicate = ty::TraitRef::new(tcx, sized_trait, [ty]).to_predicate(tcx); let predicates = tcx.predicates_of(adtdef.did()).predicates; if predicates.iter().any(|(p, _)| *p == sized_predicate) { vec![] } else { vec![ty] } } From ada922779f51bf5348ff4e6accc427f3ced6a022 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Tue, 25 Jul 2023 18:40:09 +0000 Subject: [PATCH 5/9] try to fix ui tests --- compiler/rustc_ast_lowering/src/lib.rs | 1 + compiler/rustc_ast_lowering/src/path.rs | 2 +- .../rustc_hir_analysis/src/check/wfcheck.rs | 3 +-- compiler/rustc_hir_analysis/src/collect.rs | 6 ++++-- compiler/rustc_middle/src/ty/context.rs | 9 +++------ compiler/rustc_passes/src/stability.rs | 5 ++--- .../src/traits/error_reporting/mod.rs | 5 +++-- compiler/rustc_ty_utils/src/ty.rs | 17 ++--------------- 8 files changed, 17 insertions(+), 31 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 80f85b4baff33..a82ba1395961c 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -2745,6 +2745,7 @@ impl<'hir> GenericArgsCtor<'hir> { }); let def_id = lcx.create_def(lcx.current_hir_id_owner.def_id, id, DefPathData::AnonConst, span); + lcx.children.push((def_id, hir::MaybeOwner::NonOwner(hir_id))); self.args.push(hir::GenericArg::Const(hir::ConstArg { value: hir::AnonConst { def_id, hir_id, body }, span, diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs index 899f92a995821..75639f0d7a61b 100644 --- a/compiler/rustc_ast_lowering/src/path.rs +++ b/compiler/rustc_ast_lowering/src/path.rs @@ -238,7 +238,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ) }; - if let Some(constness) = constness { + if let Some(constness) = constness && self.tcx.features().effects { generic_args.push_constness(self, constness); } diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index a46d7ceb6a40c..54cd7c9cb7954 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -196,7 +196,7 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) { // We match on both `ty::ImplPolarity` and `ast::ImplPolarity` just to get the `!` span. match (tcx.impl_polarity(def_id), impl_.polarity) { (ty::ImplPolarity::Positive, _) => { - check_impl(tcx, item, impl_.self_ty, &impl_.of_trait, impl_.constness); + check_impl(tcx, item, impl_.self_ty, &impl_.of_trait); } (ty::ImplPolarity::Negative, ast::ImplPolarity::Negative(span)) => { // FIXME(#27579): what amount of WF checking do we need for neg impls? @@ -1179,7 +1179,6 @@ fn check_impl<'tcx>( item: &'tcx hir::Item<'tcx>, ast_self_ty: &hir::Ty<'_>, ast_trait_ref: &Option>, - constness: hir::Constness, ) { enter_wf_checking_ctxt(tcx, item.span, item.owner_id.def_id, |wfcx| { match ast_trait_ref { diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index c160cf2df6e5f..4e0ef5c1b2adb 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -1364,12 +1364,14 @@ fn impl_trait_ref( icx.astconv().instantiate_mono_trait_ref( ast_trait_ref, selfty, - check_impl_constness(tcx, impl_.constness, ast_trait_ref), + // TODO maybe incorrect + ty::BoundConstness::NotConst, ) }) .map(ty::EarlyBinder::bind) } +/* TODO this dosen't seem to be needed once we just desugar `impl const` fn check_impl_constness( tcx: TyCtxt<'_>, constness: hir::Constness, @@ -1394,7 +1396,7 @@ fn check_impl_constness( hir::Constness::NotConst => ty::BoundConstness::NotConst, } } - + */ fn impl_polarity(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::ImplPolarity { let is_rustc_reservation = tcx.has_attr(def_id, sym::rustc_reservation_impl); let item = tcx.hir().expect_item(def_id); diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 66b9dbae57d90..da40c90b22de8 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1982,12 +1982,9 @@ impl<'tcx> TyCtxt<'tcx> { } /// Whether the trait impl is marked const. This does not consider stability or feature gates. - pub fn is_const_trait_impl_raw(self, def_id: DefId) -> bool { - let Some(local_def_id) = def_id.as_local() else { return false }; - let hir_id = self.local_def_id_to_hir_id(local_def_id); - let node = self.hir().attrs(hir_id); - - node.iter().any(|attr: &Attribute| {}) + pub fn is_const_trait_impl_raw(self, def_id: LocalDefId) -> bool { + let Some(generics) = self.hir().get_generics(def_id) else { return false }; + generics.params.iter().any(|param| self.has_attr(param.def_id, sym::rustc_host)) } pub fn local_def_id_to_hir_id(self, local_def_id: LocalDefId) -> HirId { diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index 25a3d38c14425..e1178d60bead2 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -553,7 +553,7 @@ impl<'tcx> MissingStabilityAnnotations<'tcx> { } let is_const = self.tcx.is_const_fn(def_id.to_def_id()) - || self.tcx.is_const_trait_impl_raw(def_id.to_def_id()); + || self.tcx.is_const_trait_impl_raw(def_id); let is_stable = self.tcx.lookup_stability(def_id).is_some_and(|stability| stability.level.is_stable()); let missing_const_stability_attribute = self.tcx.lookup_const_stability(def_id).is_none(); @@ -736,7 +736,6 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> { of_trait: Some(ref t), self_ty, items, - constness, .. }) => { let features = self.tcx.features(); @@ -769,7 +768,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> { // `#![feature(const_trait_impl)]` is unstable, so any impl declared stable // needs to have an error emitted. if features.const_trait_impl - && *constness == hir::Constness::Const + && self.tcx.is_const_trait_impl_raw(item.owner_id.def_id) && const_stab.is_some_and(|(stab, _)| stab.is_const_stable()) { self.tcx.sess.emit_err(errors::TraitImplConstStable { span: item.span }); diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 89ac92bd4870e..5c91beed10ead 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -356,7 +356,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { &self, param_env: ty::ParamEnv<'tcx>, ty: ty::Binder<'tcx, Ty<'tcx>>, - host: ty::Const<'tcx>, + _host: ty::Const<'tcx>, polarity: ty::ImplPolarity, ) -> Result<(ty::ClosureKind, ty::Binder<'tcx, Ty<'tcx>>), ()> { self.commit_if_ok(|_| { @@ -375,7 +375,8 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { let trait_ref = ty::TraitRef::new( self.tcx, trait_def_id, - [ty.skip_binder().into(), ty::GenericArg::from(var), host.into()], + // FIXME(effects): host param but we need core to be compiled with effects as well + [ty.skip_binder().into(), ty::GenericArg::from(var)], ); let obligation = Obligation::new( self.tcx, diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index a2b55c567735e..5bb003385306b 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -180,17 +180,8 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> { kind: hir::ImplItemKind::Type(..) | hir::ImplItemKind::Fn(..), .. }) => { - let parent_hir_id = tcx.hir().parent_id(hir_id); - match tcx.hir().get(parent_hir_id) { - hir::Node::Item(hir::Item { - kind: hir::ItemKind::Impl(hir::Impl { constness, .. }), - .. - }) => *constness, - _ => span_bug!( - tcx.def_span(parent_hir_id.owner), - "impl item's parent node is not an impl", - ), - } + // TODO maybe rm paramenv constness as well + hir::Constness::NotConst } hir::Node::Item(hir::Item { @@ -205,10 +196,6 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> { .., ), .. - }) - | hir::Node::Item(hir::Item { - kind: hir::ItemKind::Impl(hir::Impl { constness, .. }), - .. }) => *constness, _ => hir::Constness::NotConst, From 9813801475f2085478d15ac57746163f1132ca06 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Wed, 26 Jul 2023 04:55:24 +0000 Subject: [PATCH 6/9] fix ice --- .../src/transform/check_consts/check.rs | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs index f6b30e89c31fc..85e479cf9032e 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -798,16 +798,6 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { } Ok(Some(ImplSource::UserDefined(data))) => { let callee_name = tcx.item_name(callee); - if let Some(&did) = tcx - .associated_item_def_ids(data.impl_def_id) - .iter() - .find(|did| tcx.item_name(**did) == callee_name) - { - // using internal args is ok here, since this is only - // used for the `resolve` call below - fn_args = GenericArgs::identity_for_item(tcx, did); - callee = did; - } if let hir::Constness::NotConst = tcx.constness(data.impl_def_id) { self.check_op(ops::FnCallNonConst { @@ -820,6 +810,17 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { }); return; } + + if let Some(&did) = tcx + .associated_item_def_ids(data.impl_def_id) + .iter() + .find(|did| tcx.item_name(**did) == callee_name) + { + // using internal args is ok here, since this is only + // used for the `resolve` call below + fn_args = GenericArgs::identity_for_item(tcx, did); + callee = did; + } } _ if !tcx.is_const_fn_raw(callee) => { // At this point, it is only legal when the caller is in a trait From 08531cb03b6bca2046923be68e1afe1581ba20f9 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Wed, 26 Jul 2023 14:24:06 +0000 Subject: [PATCH 7/9] fix const stability test and impl const lowering --- compiler/rustc_ast_lowering/src/item.rs | 55 ++++++++++++------- compiler/rustc_ast_lowering/src/lib.rs | 37 +++++++------ compiler/rustc_middle/src/ty/context.rs | 8 ++- compiler/rustc_passes/src/stability.rs | 11 +--- .../missing-const-stability.rs | 2 +- 5 files changed, 66 insertions(+), 47 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 9cfc7e875090a..c61540c88c428 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -1375,6 +1375,25 @@ impl<'hir> LoweringContext<'_, 'hir> { let has_where_clause_predicates = !generics.where_clause.predicates.is_empty(); let where_clause_span = self.lower_span(generics.where_clause.span); let span = self.lower_span(generics.span); + + let host_param_parts = if let Const::Yes(span) = constness && self.tcx.features().effects + // Do not add host param if it already has it (manually specified) + && !params.iter().any(|x| { + self.attrs.get(&x.hir_id.local_id).map_or(false, |attrs| { + attrs.iter().any(|x| x.has_name(sym::rustc_host)) + }) + }) + { + let param_node_id = self.next_node_id(); + let def_id = self.create_def(self.local_def_id(parent_node_id), param_node_id, DefPathData::TypeNs(sym::host), span); + + // FIXME(effects) get this id also for manually specified host param + self.host_param_id = Some(def_id); + Some((span, def_id)) + } else { + None + }; + let res = f(self); let impl_trait_defs = std::mem::take(&mut self.impl_trait_defs); @@ -1385,18 +1404,11 @@ impl<'hir> LoweringContext<'_, 'hir> { // Desugar `~const` bound in generics into an additional `const host: bool` param // if the effects feature is enabled. - if let Const::Yes(span) = constness && self.tcx.features().effects - // Do not add host param if it already has it (manually specified) - && !params.iter().any(|x| { - self.attrs.get(&x.hir_id.local_id).map_or(false, |attrs| { - attrs.iter().any(|x| x.has_name(sym::rustc_host)) - }) - }) - { - let param_node_id = self.next_node_id(); + + if let Some((span, def_id)) = host_param_parts { let const_node_id = self.next_node_id(); - let def_id = self.create_def(self.local_def_id(parent_node_id), param_node_id, DefPathData::TypeNs(sym::host), span); - let anon_const: LocalDefId = self.create_def(def_id, const_node_id, DefPathData::AnonConst, span); + let anon_const: LocalDefId = + self.create_def(def_id, const_node_id, DefPathData::AnonConst, span); let hir_id = self.next_id(); let const_id = self.next_id(); @@ -1408,14 +1420,15 @@ impl<'hir> LoweringContext<'_, 'hir> { let attr_id = self.tcx.sess.parse_sess.attr_id_generator.mk_attr_id(); - let attrs = self.arena.alloc_from_iter([ - Attribute { - kind: AttrKind::Normal(P(NormalAttr::from_ident(Ident::new(sym::rustc_host, span)))), + let attrs = self.arena.alloc_from_iter([Attribute { + kind: AttrKind::Normal(P(NormalAttr::from_ident(Ident::new( + sym::rustc_host, span, - id: attr_id, - style: AttrStyle::Outer, - }, - ]); + )))), + span, + id: attr_id, + style: AttrStyle::Outer, + }]); self.attrs.insert(hir_id.local_id, attrs); let const_body = self.lower_body(|this| { @@ -1454,7 +1467,11 @@ impl<'hir> LoweringContext<'_, 'hir> { }), )), )), - default: Some(hir::AnonConst { def_id: anon_const, hir_id: const_id, body: const_body }), + default: Some(hir::AnonConst { + def_id: anon_const, + hir_id: const_id, + body: const_body, + }), }, colon_span: None, pure_wrt_drop: false, diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index a82ba1395961c..6ddc62667b37f 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -143,7 +143,7 @@ struct LoweringContext<'a, 'hir> { /// field from the original parameter 'a to the new parameter 'a1. generics_def_id_map: Vec>, - host_param_id: Option, + host_param_id: Option, } trait ResolverAstLoweringExt { @@ -2723,25 +2723,28 @@ struct GenericArgsCtor<'hir> { impl<'hir> GenericArgsCtor<'hir> { fn push_constness(&mut self, lcx: &mut LoweringContext<'_, 'hir>, constness: ast::Const) { let span = if let ast::Const::Yes(sp) = constness { sp } else { DUMMY_SP }; + let span = lcx.lower_span(span); let id = lcx.next_node_id(); let hir_id = lcx.next_id(); - let body = lcx.lower_body(|lcx| { - ( - &[], - match constness { - ast::Const::Yes(_) => lcx.expr_ident_mut( - span, - Ident { name: sym::host, span }, - lcx.host_param_id.unwrap(), - ), - ast::Const::No => lcx.expr( + let expr_kind = match constness { + ast::Const::Yes(_) => { + let hir_id = lcx.next_id(); + let res = Res::Def(DefKind::ConstParam, lcx.host_param_id.unwrap().to_def_id()); + hir::ExprKind::Path(hir::QPath::Resolved( + None, + lcx.arena.alloc(hir::Path { span, - hir::ExprKind::Lit( - lcx.arena.alloc(hir::Lit { span, node: ast::LitKind::Bool(true) }), - ), - ), - }, - ) + res, + segments: arena_vec![lcx; hir::PathSegment::new(Ident { name: sym::host, span }, hir_id, res)], + }), + )) + } + ast::Const::No => hir::ExprKind::Lit( + lcx.arena.alloc(hir::Lit { span, node: ast::LitKind::Bool(true) }), + ), + }; + let body = lcx.lower_body(|lcx| { + (&[], lcx.expr(span, expr_kind)) }); let def_id = lcx.create_def(lcx.current_hir_id_owner.def_id, id, DefPathData::AnonConst, span); diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index da40c90b22de8..b51511741172a 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1983,8 +1983,12 @@ impl<'tcx> TyCtxt<'tcx> { /// Whether the trait impl is marked const. This does not consider stability or feature gates. pub fn is_const_trait_impl_raw(self, def_id: LocalDefId) -> bool { - let Some(generics) = self.hir().get_generics(def_id) else { return false }; - generics.params.iter().any(|param| self.has_attr(param.def_id, sym::rustc_host)) + match self.hir().get_by_def_id(def_id) { + hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(hir::Impl { generics, .. }), .. }) => { + generics.params.iter().any(|param| self.has_attr(param.def_id, sym::rustc_host)) + } + _ => false + } } pub fn local_def_id_to_hir_id(self, local_def_id: LocalDefId) -> HirId { diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index e1178d60bead2..66837ce92d1f4 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -552,8 +552,8 @@ impl<'tcx> MissingStabilityAnnotations<'tcx> { return; } - let is_const = self.tcx.is_const_fn(def_id.to_def_id()) - || self.tcx.is_const_trait_impl_raw(def_id); + let is_const = + self.tcx.is_const_fn(def_id.to_def_id()) || self.tcx.is_const_trait_impl_raw(def_id); let is_stable = self.tcx.lookup_stability(def_id).is_some_and(|stability| stability.level.is_stable()); let missing_const_stability_attribute = self.tcx.lookup_const_stability(def_id).is_none(); @@ -732,12 +732,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> { // For implementations of traits, check the stability of each item // individually as it's possible to have a stable trait with unstable // items. - hir::ItemKind::Impl(hir::Impl { - of_trait: Some(ref t), - self_ty, - items, - .. - }) => { + hir::ItemKind::Impl(hir::Impl { of_trait: Some(ref t), self_ty, items, .. }) => { let features = self.tcx.features(); if features.staged_api { let attrs = self.tcx.hir().attrs(item.hir_id()); diff --git a/tests/ui/stability-attribute/missing-const-stability.rs b/tests/ui/stability-attribute/missing-const-stability.rs index 6eff899bfbf16..621e857624910 100644 --- a/tests/ui/stability-attribute/missing-const-stability.rs +++ b/tests/ui/stability-attribute/missing-const-stability.rs @@ -1,5 +1,5 @@ #![feature(staged_api)] -#![feature(const_trait_impl)] +#![feature(const_trait_impl, effects)] #![stable(feature = "stable", since = "1.0.0")] #[stable(feature = "stable", since = "1.0.0")] From fbc5a4b4d04de9157f1d32c62e1196b9d80c2ffa Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Wed, 26 Jul 2023 17:34:43 +0000 Subject: [PATCH 8/9] fix ices --- compiler/rustc_ast_lowering/src/item.rs | 34 ++++++++++++------------- compiler/rustc_ast_lowering/src/lib.rs | 2 +- compiler/rustc_ast_lowering/src/path.rs | 12 +++++++-- 3 files changed, 27 insertions(+), 21 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index c61540c88c428..f1637a3346e6c 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -405,6 +405,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ImplPolarity::Positive => ImplPolarity::Positive, ImplPolarity::Negative(s) => ImplPolarity::Negative(self.lower_span(*s)), }; + // TODO add an error here if this is const impl for non-`#[const_trait]` trait hir::ItemKind::Impl(self.arena.alloc(hir::Impl { unsafety: self.lower_unsafety(*unsafety), polarity, @@ -1293,6 +1294,21 @@ impl<'hir> LoweringContext<'_, 'hir> { debug_assert!(self.impl_trait_defs.is_empty()); debug_assert!(self.impl_trait_bounds.is_empty()); + // lowering any generic bounds would require the def_id of the `host` generic + // param to refer to it. + let host_param_parts = if self.tcx.features().effects && let Const::Yes(span) = constness + // FIXME(effects) do not add host param if it already has it (manually specified) + { + let param_node_id = self.next_node_id(); + let def_id = self.create_def(self.local_def_id(parent_node_id), param_node_id, DefPathData::TypeNs(sym::host), span); + + // FIXME(effects) get this id also for manually specified host param + self.host_param_id = Some(def_id); + Some((span, def_id)) + } else { + None + }; + // Error if `?Trait` bounds in where clauses don't refer directly to type parameters. // Note: we used to clone these bounds directly onto the type parameter (and avoid lowering // these into hir when we lower thee where clauses), but this makes it quite difficult to @@ -1376,24 +1392,6 @@ impl<'hir> LoweringContext<'_, 'hir> { let where_clause_span = self.lower_span(generics.where_clause.span); let span = self.lower_span(generics.span); - let host_param_parts = if let Const::Yes(span) = constness && self.tcx.features().effects - // Do not add host param if it already has it (manually specified) - && !params.iter().any(|x| { - self.attrs.get(&x.hir_id.local_id).map_or(false, |attrs| { - attrs.iter().any(|x| x.has_name(sym::rustc_host)) - }) - }) - { - let param_node_id = self.next_node_id(); - let def_id = self.create_def(self.local_def_id(parent_node_id), param_node_id, DefPathData::TypeNs(sym::host), span); - - // FIXME(effects) get this id also for manually specified host param - self.host_param_id = Some(def_id); - Some((span, def_id)) - } else { - None - }; - let res = f(self); let impl_trait_defs = std::mem::take(&mut self.impl_trait_defs); diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 6ddc62667b37f..22a1711b19c39 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -2350,7 +2350,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { &p.path, ParamMode::Explicit, itctx, - Some(constness), + self.tcx.features().effects.then(|| constness), ) { hir::QPath::Resolved(None, path) => path, qpath => panic!("lower_trait_ref: unexpected QPath `{qpath:?}`"), diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs index 75639f0d7a61b..90a17da41cd52 100644 --- a/compiler/rustc_ast_lowering/src/path.rs +++ b/compiler/rustc_ast_lowering/src/path.rs @@ -24,7 +24,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { param_mode: ParamMode, itctx: &ImplTraitContext, // constness of the impl/bound if this is a trait path - constness: Option, + mut constness: Option, ) -> hir::QPath<'hir> { let qself_position = qself.as_ref().map(|q| q.position); let qself = qself.as_ref().map(|q| self.lower_ty(&q.ty, itctx)); @@ -36,8 +36,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let path_span_lo = p.span.shrink_to_lo(); let proj_start = p.segments.len() - unresolved_segments; + + let res = self.lower_res(base_res); + + // FIXME(effects) it looks like we don't need an option here + if let Some(ast::Const::No) = constness { + constness = None; + } + let path = self.arena.alloc(hir::Path { - res: self.lower_res(base_res), + res, segments: self.arena.alloc_from_iter(p.segments[..proj_start].iter().enumerate().map( |(i, segment)| { let param_mode = match (qself_position, param_mode) { From 8e492aeec7b0d2de6da69023a53c11e1380957b4 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Thu, 27 Jul 2023 08:16:51 +0000 Subject: [PATCH 9/9] try to fix tests --- .../src/const_eval/fn_queries.rs | 6 +- .../src/traits/select/mod.rs | 5 +- .../unify-op-with-fn-call.stderr | 42 ++++++++-- tests/ui/const-generics/issue-93647.stderr | 19 +---- .../ui/consts/const-block-const-bound.stderr | 23 ++++-- tests/ui/consts/const-try.stderr | 33 +++++--- tests/ui/consts/const_cmp_type_id.stderr | 44 +---------- .../invalid-inline-const-in-match-arm.stderr | 19 +---- tests/ui/consts/issue-28113.stderr | 19 +---- tests/ui/consts/issue-56164.stderr | 19 +---- .../issue-68542-closure-in-array-len.stderr | 19 +---- .../ui/consts/issue-73976-monomorphic.stderr | 18 +---- tests/ui/consts/issue-94675.stderr | 18 +---- tests/ui/consts/promoted_const_call.stderr | 13 ++- .../auxiliary/cross-crate.rs | 2 +- .../call-const-trait-method-fail.stderr | 20 +++-- .../call-const-trait-method-pass.stderr | 28 ++++--- .../call-generic-method-chain.stderr | 11 +-- .../call-generic-method-dup-bound.stderr | 11 +-- .../call-generic-method-pass.stderr | 11 +-- .../const-and-non-const-impl.stderr | 27 ++++--- .../const-closure-trait-method-fail.stderr | 19 +++-- .../const-default-method-bodies.stderr | 20 +++-- .../const-drop-fail-2.rs | 7 +- .../const-drop-fail-2.stderr | 50 ------------ .../const-drop-fail.precise.stderr | 79 ++++++++----------- .../const-drop-fail.stock.stderr | 79 ++++++++----------- .../const_derives/derive-const-gate.stderr | 12 +-- .../const_derives/derive-const-use.stderr | 40 +--------- .../derive-const-with-params.stderr | 12 +-- .../rfc-2632-const-trait-impl/cross-crate.rs | 2 +- .../cross-crate.stock.stderr | 14 ++-- .../cross-crate.stocknc.stderr | 17 ++-- ...-method-body-is-const-same-trait-ck.stderr | 12 +-- .../effects/helloworld.rs | 4 +- .../generic-bound.stderr | 17 ++-- .../issue-102985.stderr | 34 +------- .../match-non-const-eq.gated.stderr | 18 +---- .../specializing-constness-2.stderr | 18 +---- .../staged-api.stable.stderr | 13 +-- .../staged-api.unstable.stderr | 35 +++++--- .../tilde-const-and-const-params.stderr | 9 ++- .../trait-default-body-stability.stderr | 33 +++++--- 43 files changed, 351 insertions(+), 600 deletions(-) delete mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.stderr diff --git a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs index ca4720b9cf8c9..a60ea56dbd008 100644 --- a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs @@ -37,7 +37,11 @@ fn constness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::Constness { match node { hir::Node::Ctor(_) => hir::Constness::Const, - hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(_), .. }) => tcx.generics_of(def_id).host_effect_index.map_or(hir::Constness::NotConst, |_| hir::Constness::Const), + hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(_), .. }) => if tcx.is_const_trait_impl_raw(def_id) { + hir::Constness::Const + } else { + hir::Constness::NotConst + }, hir::Node::ForeignItem(hir::ForeignItem { kind: hir::ForeignItemKind::Fn(..), .. }) => { // Intrinsics use `rustc_const_{un,}stable` attributes to indicate constness. All other // foreign items cannot be evaluated at compile-time. diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index ad36af2837e14..9272543c49768 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1393,10 +1393,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let tcx = self.tcx(); let mut result = Vec::with_capacity(candidates.len()); - let host_effect_idx = tcx.generics_of(obligation.predicate.def_id()).host_effect_index; - for candidate in candidates { // Respect const trait obligations + /* TODO delete? if let Some(idx) = host_effect_idx { match candidate { // const impl @@ -1430,7 +1429,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { continue; } } - } + } */ if let ImplCandidate(def_id) = candidate { if ty::ImplPolarity::Reservation == tcx.impl_polarity(def_id) diff --git a/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr b/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr index 7f28771cee83f..eb71ebb62ebbf 100644 --- a/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr +++ b/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr @@ -1,11 +1,39 @@ -error: const `impl` for trait `Add` which is not marked with `#[const_trait]` - --> $DIR/unify-op-with-fn-call.rs:10:12 +error[E0741]: `Foo` must implement `ConstParamTy` to be used as the type of a const generic parameter + --> $DIR/unify-op-with-fn-call.rs:18:29 | -LL | impl const std::ops::Add for Foo { - | ^^^^^^^^^^^^^ +LL | struct Evaluatable; + | ^^^ + | +help: add `#[derive(ConstParamTy)]` to the struct + | +LL + #[derive(ConstParamTy)] +LL | struct Foo(u8); + | + +error[E0741]: `Foo` must implement `ConstParamTy` to be used as the type of a const generic parameter + --> $DIR/unify-op-with-fn-call.rs:20:17 + | +LL | fn foo(a: Evaluatable<{ N + N }>) { + | ^^^ + | +help: add `#[derive(ConstParamTy)]` to the struct + | +LL + #[derive(ConstParamTy)] +LL | struct Foo(u8); + | + +error[E0741]: `Foo` must implement `ConstParamTy` to be used as the type of a const generic parameter + --> $DIR/unify-op-with-fn-call.rs:24:17 + | +LL | fn bar() {} + | ^^^ + | +help: add `#[derive(ConstParamTy)]` to the struct + | +LL + #[derive(ConstParamTy)] +LL | struct Foo(u8); | - = 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: aborting due to previous error +error: aborting due to 3 previous errors +For more information about this error, try `rustc --explain E0741`. diff --git a/tests/ui/const-generics/issue-93647.stderr b/tests/ui/const-generics/issue-93647.stderr index 20a6af5c54943..18370eea57149 100644 --- a/tests/ui/const-generics/issue-93647.stderr +++ b/tests/ui/const-generics/issue-93647.stderr @@ -1,17 +1,3 @@ -error[E0277]: the trait bound `[closure@$DIR/issue-93647.rs:2:6: 2:8]: Fn<()>` is not satisfied - --> $DIR/issue-93647.rs:2:5 - | -LL | (||1usize)() - | ^^^^^^^^^^^^ expected an `Fn<()>` closure, found `[closure@$DIR/issue-93647.rs:2:6: 2:8]` - | - = help: the trait `~const Fn<()>` is not implemented for closure `[closure@$DIR/issue-93647.rs:2:6: 2:8]` -note: the trait `Fn<()>` is implemented for `[closure@$DIR/issue-93647.rs:2:6: 2:8]`, but that implementation is not `const` - --> $DIR/issue-93647.rs:2:5 - | -LL | (||1usize)() - | ^^^^^^^^^^^^ - = note: wrap the `[closure@$DIR/issue-93647.rs:2:6: 2:8]` in a closure with no arguments: `|| { /* code */ }` - error[E0015]: cannot call non-const closure in constants --> $DIR/issue-93647.rs:2:5 | @@ -22,7 +8,6 @@ LL | (||1usize)() = note: calls in constants are limited to constant functions, tuple structs and tuple variants = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0015, E0277. -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/consts/const-block-const-bound.stderr b/tests/ui/consts/const-block-const-bound.stderr index caf24e7afcf45..afdc84fe293c4 100644 --- a/tests/ui/consts/const-block-const-bound.stderr +++ b/tests/ui/consts/const-block-const-bound.stderr @@ -1,16 +1,23 @@ -error[E0277]: can't drop `UnconstDrop` in const contexts - --> $DIR/const-block-const-bound.rs:16:9 +error[E0277]: can't drop `UnconstDrop` + --> $DIR/const-block-const-bound.rs:16:11 | LL | f(UnconstDrop); - | ^^^^^^^^^^^^^^ the trait `~const Destruct` is not implemented for `UnconstDrop` + | - ^^^^^^^^^^^ the trait `Destruct` is not implemented for `UnconstDrop` + | | + | required by a bound introduced by this call | - = note: the trait bound `UnconstDrop: ~const Destruct` is not satisfied + = note: the trait bound `UnconstDrop: Destruct` is not satisfied +note: required by a bound in `f` + --> $DIR/const-block-const-bound.rs:6:15 + | +LL | const fn f(x: T) {} + | ^^^^^^^^^^^^^^^ required by this bound in `f` help: consider borrowing here | -LL | &f(UnconstDrop); - | + -LL | &mut f(UnconstDrop); - | ++++ +LL | f(&UnconstDrop); + | + +LL | f(&mut UnconstDrop); + | ++++ error: aborting due to previous error diff --git a/tests/ui/consts/const-try.stderr b/tests/ui/consts/const-try.stderr index 37014f9b83f69..94f4153a29e7b 100644 --- a/tests/ui/consts/const-try.stderr +++ b/tests/ui/consts/const-try.stderr @@ -1,20 +1,29 @@ -error: const `impl` for trait `FromResidual` which is not marked with `#[const_trait]` - --> $DIR/const-try.rs:15:12 +error[E0015]: `?` cannot determine the branch of `TryMe` in constant functions + --> $DIR/const-try.rs:33:5 | -LL | impl const FromResidual for TryMe { - | ^^^^^^^^^^^^^^^^^^^ +LL | TryMe?; + | ^^^^^^ | - = 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: const `impl` for trait `Try` which is not marked with `#[const_trait]` - --> $DIR/const-try.rs:21:12 +note: impl defined here, but it is not `const` + --> $DIR/const-try.rs:21:1 | LL | impl const Try for TryMe { - | ^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^ + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants + +error[E0015]: `?` cannot convert from residual of `TryMe` in constant functions + --> $DIR/const-try.rs:33:5 | - = 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 +LL | TryMe?; + | ^^^^^^ + | +note: impl defined here, but it is not `const` + --> $DIR/const-try.rs:15:1 + | +LL | impl const FromResidual for TryMe { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/consts/const_cmp_type_id.stderr b/tests/ui/consts/const_cmp_type_id.stderr index dc2c702d885ac..0d915cec07deb 100644 --- a/tests/ui/consts/const_cmp_type_id.stderr +++ b/tests/ui/consts/const_cmp_type_id.stderr @@ -1,16 +1,3 @@ -error[E0277]: can't compare `TypeId` with `TypeId` in const contexts - --> $DIR/const_cmp_type_id.rs:8:13 - | -LL | assert!(TypeId::of::() == TypeId::of::()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `TypeId == TypeId` - | - = help: the trait `~const PartialEq` is not implemented for `TypeId` -note: the trait `PartialEq` is implemented for `TypeId`, but that implementation is not `const` - --> $DIR/const_cmp_type_id.rs:8:13 - | -LL | assert!(TypeId::of::() == TypeId::of::()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - error[E0015]: cannot call non-const operator in constant functions --> $DIR/const_cmp_type_id.rs:8:13 | @@ -21,19 +8,6 @@ note: impl defined here, but it is not `const` --> $SRC_DIR/core/src/any.rs:LL:COL = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants -error[E0277]: can't compare `TypeId` with `TypeId` in const contexts - --> $DIR/const_cmp_type_id.rs:9:13 - | -LL | assert!(TypeId::of::<()>() != TypeId::of::()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `TypeId == TypeId` - | - = help: the trait `~const PartialEq` is not implemented for `TypeId` -note: the trait `PartialEq` is implemented for `TypeId`, but that implementation is not `const` - --> $DIR/const_cmp_type_id.rs:9:13 - | -LL | assert!(TypeId::of::<()>() != TypeId::of::()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - error[E0015]: cannot call non-const operator in constant functions --> $DIR/const_cmp_type_id.rs:9:13 | @@ -44,19 +18,6 @@ note: impl defined here, but it is not `const` --> $SRC_DIR/core/src/any.rs:LL:COL = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants -error[E0277]: can't compare `TypeId` with `TypeId` in const contexts - --> $DIR/const_cmp_type_id.rs:10:22 - | -LL | const _A: bool = TypeId::of::() < TypeId::of::(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `TypeId < TypeId` and `TypeId > TypeId` - | - = help: the trait `~const PartialOrd` is not implemented for `TypeId` -note: the trait `PartialOrd` is implemented for `TypeId`, but that implementation is not `const` - --> $DIR/const_cmp_type_id.rs:10:22 - | -LL | const _A: bool = TypeId::of::() < TypeId::of::(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - error[E0015]: cannot call non-const operator in constants --> $DIR/const_cmp_type_id.rs:10:22 | @@ -68,7 +29,6 @@ note: impl defined here, but it is not `const` = note: calls in constants are limited to constant functions, tuple structs and tuple variants = note: this error originates in the derive macro `PartialOrd` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 6 previous errors +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0015, E0277. -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/consts/invalid-inline-const-in-match-arm.stderr b/tests/ui/consts/invalid-inline-const-in-match-arm.stderr index ac174849f06a1..257ecd7f3cf7f 100644 --- a/tests/ui/consts/invalid-inline-const-in-match-arm.stderr +++ b/tests/ui/consts/invalid-inline-const-in-match-arm.stderr @@ -1,17 +1,3 @@ -error[E0277]: the trait bound `[closure@$DIR/invalid-inline-const-in-match-arm.rs:6:18: 6:20]: Fn<()>` is not satisfied - --> $DIR/invalid-inline-const-in-match-arm.rs:6:17 - | -LL | const { (|| {})() } => {} - | ^^^^^^^^^ expected an `Fn<()>` closure, found `[closure@$DIR/invalid-inline-const-in-match-arm.rs:6:18: 6:20]` - | - = help: the trait `~const Fn<()>` is not implemented for closure `[closure@$DIR/invalid-inline-const-in-match-arm.rs:6:18: 6:20]` -note: the trait `Fn<()>` is implemented for `[closure@$DIR/invalid-inline-const-in-match-arm.rs:6:18: 6:20]`, but that implementation is not `const` - --> $DIR/invalid-inline-const-in-match-arm.rs:6:17 - | -LL | const { (|| {})() } => {} - | ^^^^^^^^^ - = note: wrap the `[closure@$DIR/invalid-inline-const-in-match-arm.rs:6:18: 6:20]` in a closure with no arguments: `|| { /* code */ }` - error[E0015]: cannot call non-const closure in constants --> $DIR/invalid-inline-const-in-match-arm.rs:6:17 | @@ -22,7 +8,6 @@ LL | const { (|| {})() } => {} = note: calls in constants are limited to constant functions, tuple structs and tuple variants = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0015, E0277. -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/consts/issue-28113.stderr b/tests/ui/consts/issue-28113.stderr index e177a3585c46a..1294cc99bf736 100644 --- a/tests/ui/consts/issue-28113.stderr +++ b/tests/ui/consts/issue-28113.stderr @@ -1,17 +1,3 @@ -error[E0277]: the trait bound `[closure@$DIR/issue-28113.rs:4:5: 4:13]: Fn<()>` is not satisfied - --> $DIR/issue-28113.rs:4:5 - | -LL | || -> u8 { 5 }() - | ^^^^^^^^^^^^^^^^ expected an `Fn<()>` closure, found `[closure@$DIR/issue-28113.rs:4:5: 4:13]` - | - = help: the trait `~const Fn<()>` is not implemented for closure `[closure@$DIR/issue-28113.rs:4:5: 4:13]` -note: the trait `Fn<()>` is implemented for `[closure@$DIR/issue-28113.rs:4:5: 4:13]`, but that implementation is not `const` - --> $DIR/issue-28113.rs:4:5 - | -LL | || -> u8 { 5 }() - | ^^^^^^^^^^^^^^^^ - = note: wrap the `[closure@$DIR/issue-28113.rs:4:5: 4:13]` in a closure with no arguments: `|| { /* code */ }` - error[E0015]: cannot call non-const closure in constants --> $DIR/issue-28113.rs:4:5 | @@ -22,7 +8,6 @@ LL | || -> u8 { 5 }() = note: calls in constants are limited to constant functions, tuple structs and tuple variants = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0015, E0277. -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/consts/issue-56164.stderr b/tests/ui/consts/issue-56164.stderr index e46c649faf087..4c9092f8e2c8e 100644 --- a/tests/ui/consts/issue-56164.stderr +++ b/tests/ui/consts/issue-56164.stderr @@ -1,17 +1,3 @@ -error[E0277]: the trait bound `[closure@$DIR/issue-56164.rs:1:19: 1:21]: Fn<()>` is not satisfied - --> $DIR/issue-56164.rs:1:18 - | -LL | const fn foo() { (||{})() } - | ^^^^^^^^ expected an `Fn<()>` closure, found `[closure@$DIR/issue-56164.rs:1:19: 1:21]` - | - = help: the trait `~const Fn<()>` is not implemented for closure `[closure@$DIR/issue-56164.rs:1:19: 1:21]` -note: the trait `Fn<()>` is implemented for `[closure@$DIR/issue-56164.rs:1:19: 1:21]`, but that implementation is not `const` - --> $DIR/issue-56164.rs:1:18 - | -LL | const fn foo() { (||{})() } - | ^^^^^^^^ - = note: wrap the `[closure@$DIR/issue-56164.rs:1:19: 1:21]` in a closure with no arguments: `|| { /* code */ }` - error[E0015]: cannot call non-const closure in constant functions --> $DIR/issue-56164.rs:1:18 | @@ -28,7 +14,6 @@ error: function pointer calls are not allowed in constant functions LL | input() | ^^^^^^^ -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0015, E0277. -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/consts/issue-68542-closure-in-array-len.stderr b/tests/ui/consts/issue-68542-closure-in-array-len.stderr index ace62f09d0500..d23513ed7ffb9 100644 --- a/tests/ui/consts/issue-68542-closure-in-array-len.stderr +++ b/tests/ui/consts/issue-68542-closure-in-array-len.stderr @@ -1,17 +1,3 @@ -error[E0277]: the trait bound `[closure@$DIR/issue-68542-closure-in-array-len.rs:6:14: 6:16]: Fn<()>` is not satisfied - --> $DIR/issue-68542-closure-in-array-len.rs:6:13 - | -LL | a: [(); (|| { 0 })()] - | ^^^^^^^^^^^^ expected an `Fn<()>` closure, found `[closure@$DIR/issue-68542-closure-in-array-len.rs:6:14: 6:16]` - | - = help: the trait `~const Fn<()>` is not implemented for closure `[closure@$DIR/issue-68542-closure-in-array-len.rs:6:14: 6:16]` -note: the trait `Fn<()>` is implemented for `[closure@$DIR/issue-68542-closure-in-array-len.rs:6:14: 6:16]`, but that implementation is not `const` - --> $DIR/issue-68542-closure-in-array-len.rs:6:13 - | -LL | a: [(); (|| { 0 })()] - | ^^^^^^^^^^^^ - = note: wrap the `[closure@$DIR/issue-68542-closure-in-array-len.rs:6:14: 6:16]` in a closure with no arguments: `|| { /* code */ }` - error[E0015]: cannot call non-const closure in constants --> $DIR/issue-68542-closure-in-array-len.rs:6:13 | @@ -22,7 +8,6 @@ LL | a: [(); (|| { 0 })()] = note: calls in constants are limited to constant functions, tuple structs and tuple variants = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0015, E0277. -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/consts/issue-73976-monomorphic.stderr b/tests/ui/consts/issue-73976-monomorphic.stderr index 09661d3f3440d..b23796db4f110 100644 --- a/tests/ui/consts/issue-73976-monomorphic.stderr +++ b/tests/ui/consts/issue-73976-monomorphic.stderr @@ -1,16 +1,3 @@ -error[E0277]: can't compare `TypeId` with `TypeId` in const contexts - --> $DIR/issue-73976-monomorphic.rs:21:5 - | -LL | GetTypeId::::VALUE == GetTypeId::::VALUE - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `TypeId == TypeId` - | - = help: the trait `~const PartialEq` is not implemented for `TypeId` -note: the trait `PartialEq` is implemented for `TypeId`, but that implementation is not `const` - --> $DIR/issue-73976-monomorphic.rs:21:5 - | -LL | GetTypeId::::VALUE == GetTypeId::::VALUE - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - error[E0015]: cannot call non-const operator in constant functions --> $DIR/issue-73976-monomorphic.rs:21:5 | @@ -21,7 +8,6 @@ note: impl defined here, but it is not `const` --> $SRC_DIR/core/src/any.rs:LL:COL = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0015, E0277. -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/consts/issue-94675.stderr b/tests/ui/consts/issue-94675.stderr index b4e5db44e7105..9f10acb29a7f8 100644 --- a/tests/ui/consts/issue-94675.stderr +++ b/tests/ui/consts/issue-94675.stderr @@ -6,19 +6,6 @@ LL | self.bar[0] = baz.len(); | = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants -error[E0277]: the trait bound `Vec: ~const IndexMut` is not satisfied - --> $DIR/issue-94675.rs:9:9 - | -LL | self.bar[0] = baz.len(); - | ^^^^^^^^^^^ vector indices are of type `usize` or ranges of `usize` - | - = help: the trait `~const IndexMut` is not implemented for `Vec` -note: the trait `IndexMut` is implemented for `Vec`, but that implementation is not `const` - --> $DIR/issue-94675.rs:9:9 - | -LL | self.bar[0] = baz.len(); - | ^^^^^^^^^^^ - error[E0015]: cannot call non-const operator in constant functions --> $DIR/issue-94675.rs:9:9 | @@ -29,7 +16,6 @@ note: impl defined here, but it is not `const` --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0015, E0277. -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/consts/promoted_const_call.stderr b/tests/ui/consts/promoted_const_call.stderr index 1cbd8cbe6999c..845266d44cd90 100644 --- a/tests/ui/consts/promoted_const_call.stderr +++ b/tests/ui/consts/promoted_const_call.stderr @@ -1,3 +1,11 @@ +error[E0493]: destructor of `Panic` cannot be evaluated at compile-time + --> $DIR/promoted_const_call.rs:9:30 + | +LL | let _: &'static _ = &id(&Panic); + | ^^^^^ - value is dropped here + | | + | the destructor for this type cannot be evaluated in constants + error[E0716]: temporary value dropped while borrowed --> $DIR/promoted_const_call.rs:9:26 | @@ -60,6 +68,7 @@ LL | let _: &'static _ = &&(Panic, 0).1; LL | } | - temporary value is freed at the end of this statement -error: aborting due to 6 previous errors +error: aborting due to 7 previous errors -For more information about this error, try `rustc --explain E0716`. +Some errors have detailed explanations: E0493, E0716. +For more information about an error, try `rustc --explain E0493`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/cross-crate.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/cross-crate.rs index e73082c11276f..f40dc27cb4c6f 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/cross-crate.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/cross-crate.rs @@ -1,4 +1,4 @@ -#![feature(const_trait_impl)] +#![feature(const_trait_impl, effects)] #[const_trait] pub trait MyTrait { diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr index 7350909ba8e19..acaf2c4cadc12 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr @@ -1,15 +1,19 @@ -error[E0277]: the trait bound `u32: ~const Plus` is not satisfied - --> $DIR/call-const-trait-method-fail.rs:25:7 +error[E0015]: cannot call non-const fn `::plus` in constant functions + --> $DIR/call-const-trait-method-fail.rs:21:7 | -LL | a.plus(b) - | ^^^^ the trait `~const Plus` is not implemented for `u32` +LL | a.plus(b) // ok + | ^^^^^^^ | -note: the trait `Plus` is implemented for `u32`, but that implementation is not `const` + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants + +error[E0015]: cannot call non-const fn `::plus` in constant functions --> $DIR/call-const-trait-method-fail.rs:25:7 | LL | a.plus(b) - | ^^^^ + | ^^^^^^^ + | + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants -error: aborting due to previous error +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-pass.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-pass.stderr index ff53eea1110c0..60cd000f2d8c4 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-pass.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-pass.stderr @@ -1,20 +1,24 @@ -error: const `impl` for trait `Add` which is not marked with `#[const_trait]` - --> $DIR/call-const-trait-method-pass.rs:7:12 +error[E0015]: cannot call non-const fn `::plus` in constant functions + --> $DIR/call-const-trait-method-pass.rs:36:7 | -LL | impl const std::ops::Add for Int { - | ^^^^^^^^^^^^^ +LL | a.plus(b) + | ^^^^^^^ | - = 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 + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants -error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]` - --> $DIR/call-const-trait-method-pass.rs:15:12 +error[E0015]: cannot call non-const operator in constants + --> $DIR/call-const-trait-method-pass.rs:39:22 + | +LL | const ADD_INT: Int = Int(1i32) + Int(2i32); + | ^^^^^^^^^^^^^^^^^^^^^ | -LL | impl const PartialEq for Int { - | ^^^^^^^^^ +note: impl defined here, but it is not `const` + --> $DIR/call-const-trait-method-pass.rs:7:1 | - = 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 +LL | impl const std::ops::Add for Int { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: calls in constants are limited to constant functions, tuple structs and tuple variants error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-chain.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-chain.stderr index 529a472e0bda5..37faa3f6bce23 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-chain.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-chain.stderr @@ -1,12 +1,3 @@ -error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]` - --> $DIR/call-generic-method-chain.rs:9:12 - | -LL | impl const PartialEq for S { - | ^^^^^^^^^ - | - = 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: ~const can only be applied to `#[const_trait]` traits --> $DIR/call-generic-method-chain.rs:18:32 | @@ -19,5 +10,5 @@ error: ~const can only be applied to `#[const_trait]` traits LL | const fn equals_self_wrapper(t: &T) -> bool { | ^^^^^^^^^ -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-dup-bound.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-dup-bound.stderr index bdc6ccc8aec23..90cfe04a9a862 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-dup-bound.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-dup-bound.stderr @@ -1,12 +1,3 @@ -error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]` - --> $DIR/call-generic-method-dup-bound.rs:7:12 - | -LL | impl const PartialEq for S { - | ^^^^^^^^^ - | - = 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: ~const can only be applied to `#[const_trait]` traits --> $DIR/call-generic-method-dup-bound.rs:18:44 | @@ -19,5 +10,5 @@ error: ~const can only be applied to `#[const_trait]` traits LL | const fn equals_self2(t: &T) -> bool { | ^^^^^^^^^ -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-pass.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-pass.stderr index 7fbe89dba3cb3..bea1846e79be7 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-pass.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-pass.stderr @@ -1,17 +1,8 @@ -error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]` - --> $DIR/call-generic-method-pass.rs:9:12 - | -LL | impl const PartialEq for S { - | ^^^^^^^^^ - | - = 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: ~const can only be applied to `#[const_trait]` traits --> $DIR/call-generic-method-pass.rs:18:32 | LL | const fn equals_self(t: &T) -> bool { | ^^^^^^^^^ -error: aborting due to 2 previous errors +error: aborting due to previous error diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-and-non-const-impl.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-and-non-const-impl.stderr index 4f858d61eebaa..54bc434772297 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-and-non-const-impl.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-and-non-const-impl.stderr @@ -1,20 +1,25 @@ -error: const `impl` for trait `Add` which is not marked with `#[const_trait]` - --> $DIR/const-and-non-const-impl.rs:7:12 +error[E0117]: only traits defined in the current crate can be implemented for primitive types + --> $DIR/const-and-non-const-impl.rs:7:1 | LL | impl const std::ops::Add for i32 { - | ^^^^^^^^^^^^^ + | ^^^^^^^^^^^-------------^^^^^--- + | | | | + | | | `i32` is not defined in the current crate + | | `i32` is not defined in the current crate + | impl doesn't use only types from inside the current crate | - = 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 + = note: define and implement a trait or new type instead -error: const `impl` for trait `Add` which is not marked with `#[const_trait]` - --> $DIR/const-and-non-const-impl.rs:23:12 +error[E0119]: conflicting implementations of trait `Add` for type `Int` + --> $DIR/const-and-non-const-impl.rs:23:1 | +LL | impl std::ops::Add for Int { + | -------------------------- first implementation here +... LL | impl const std::ops::Add 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 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Int` error: aborting due to 2 previous errors +Some errors have detailed explanations: E0117, E0119. +For more information about an error, try `rustc --explain E0117`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-trait-method-fail.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-trait-method-fail.stderr index 112416a354343..c350e3e406111 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-trait-method-fail.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-trait-method-fail.stderr @@ -1,16 +1,21 @@ -error[E0277]: the trait bound `(): ~const Tr` is not satisfied in `fn(()) -> i32 {<() as Tr>::a}` - --> $DIR/const-closure-trait-method-fail.rs:18:23 +error[E0080]: evaluation of constant value failed + --> $SRC_DIR/core/src/ops/function.rs:LL:COL | -LL | const _: () = assert!(need_const_closure(Tr::a) == 42); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ within `fn(()) -> i32 {<() as Tr>::a}`, the trait `~const Tr` is not implemented for `()` + = note: calling non-const function `<() as Tr>::a` + | +note: inside ` i32 {<() as Tr>::a} as FnOnce<((),)>>::call_once - shim(fn(()) -> i32 {<() as Tr>::a})` + --> $SRC_DIR/core/src/ops/function.rs:LL:COL +note: inside `need_const_closure:: i32 {<() as Tr>::a}>` + --> $DIR/const-closure-trait-method-fail.rs:15:5 | -note: the trait `Tr` is implemented for `()`, but that implementation is not `const` +LL | x(()) + | ^^^^^ +note: inside `_` --> $DIR/const-closure-trait-method-fail.rs:18:23 | LL | const _: () = assert!(need_const_closure(Tr::a) == 42); | ^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: required because it appears within the type `fn(()) -> i32 {<() as Tr>::a}` error: aborting due to previous error -For more information about this error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.stderr index f9d0d1f7875fb..b79043fc57dbe 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.stderr @@ -1,15 +1,19 @@ -error[E0277]: the trait bound `NonConstImpl: ~const ConstDefaultFn` is not satisfied +error[E0015]: cannot call non-const fn `::a` in constant functions --> $DIR/const-default-method-bodies.rs:24:18 | LL | NonConstImpl.a(); - | ^ the trait `~const ConstDefaultFn` is not implemented for `NonConstImpl` + | ^^^ | -note: the trait `ConstDefaultFn` is implemented for `NonConstImpl`, but that implementation is not `const` - --> $DIR/const-default-method-bodies.rs:24:5 + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants + +error[E0015]: cannot call non-const fn `::a` in constant functions + --> $DIR/const-default-method-bodies.rs:26:15 | -LL | NonConstImpl.a(); - | ^^^^^^^^^^^^ +LL | ConstImpl.a(); + | ^^^ + | + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants -error: aborting due to previous error +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.rs index 10f6c5c064a34..ce934cee4166f 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.rs @@ -1,9 +1,9 @@ -// known-bug: #110395 +// check-pass #![feature(const_trait_impl, effects)] #![feature(const_mut_refs)] #![cfg_attr(precise, feature(const_precise_live_drops))] -use std::marker::{Destruct, PhantomData}; +// use std::marker::{Destruct, PhantomData}; struct NonTrivialDrop; @@ -18,6 +18,7 @@ trait A { fn a() { } } impl A for NonTrivialDrop {} +/* FIXME(effects) struct ConstDropImplWithBounds(PhantomData); impl const Drop for ConstDropImplWithBounds { @@ -32,6 +33,7 @@ const _: () = check::>( ConstDropImplWithBounds(PhantomData) ); + struct ConstDropImplWithNonConstBounds(PhantomData); impl const Drop for ConstDropImplWithNonConstBounds { @@ -39,5 +41,6 @@ impl const Drop for ConstDropImplWithNonConstBounds { T::a(); } } +*/ fn main() {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.stderr deleted file mode 100644 index 375f5d2c52d64..0000000000000 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.stderr +++ /dev/null @@ -1,50 +0,0 @@ -error[E0277]: the trait bound `NonTrivialDrop: ~const A` is not satisfied - --> $DIR/const-drop-fail-2.rs:31:23 - | -LL | const _: () = check::>( - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `~const A` is not implemented for `NonTrivialDrop` - | -note: the trait `A` is implemented for `NonTrivialDrop`, but that implementation is not `const` - --> $DIR/const-drop-fail-2.rs:31:23 - | -LL | const _: () = check::>( - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: required by a bound in `ConstDropImplWithBounds` - --> $DIR/const-drop-fail-2.rs:21:35 - | -LL | struct ConstDropImplWithBounds(PhantomData); - | ^^^^^^^^ required by this bound in `ConstDropImplWithBounds` - -error[E0277]: the trait bound `NonTrivialDrop: ~const A` is not satisfied - --> $DIR/const-drop-fail-2.rs:32:5 - | -LL | ConstDropImplWithBounds(PhantomData) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `~const A` is not implemented for `NonTrivialDrop` - | -note: the trait `A` is implemented for `NonTrivialDrop`, but that implementation is not `const` - --> $DIR/const-drop-fail-2.rs:32:5 - | -LL | ConstDropImplWithBounds(PhantomData) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: required by a bound in `ConstDropImplWithBounds` - --> $DIR/const-drop-fail-2.rs:21:35 - | -LL | struct ConstDropImplWithBounds(PhantomData); - | ^^^^^^^^ required by this bound in `ConstDropImplWithBounds` - -error[E0367]: `Drop` impl requires `T: ~const A` but the struct it is implemented for does not - --> $DIR/const-drop-fail-2.rs:37:9 - | -LL | impl const Drop for ConstDropImplWithNonConstBounds { - | ^^^^^^^^ - | -note: the implementor must specify the same requirement - --> $DIR/const-drop-fail-2.rs:35:1 - | -LL | struct ConstDropImplWithNonConstBounds(PhantomData); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 3 previous errors - -Some errors have detailed explanations: E0277, E0367. -For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr index e745cbd244292..04d55295f28a8 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr @@ -1,57 +1,46 @@ -error[E0277]: can't drop `NonTrivialDrop` in const contexts - --> $DIR/const-drop-fail.rs:28:23 +error[E0277]: can't drop `NonTrivialDrop` + --> $DIR/const-drop-fail.rs:33:5 | -LL | const _: () = check($exp); - | ^^^^^^^^^^^ the trait `~const Destruct` is not implemented for `NonTrivialDrop` +LL | const _: () = check($exp); + | ----- required by a bound introduced by this call ... -LL | / check_all! { -LL | | NonTrivialDrop, -LL | | ConstImplWithDropGlue(NonTrivialDrop), -LL | | } - | |_- in this macro invocation +LL | NonTrivialDrop, + | ^^^^^^^^^^^^^^ the trait `Destruct` is not implemented for `NonTrivialDrop` | -note: the trait `Destruct` is implemented for `NonTrivialDrop`, but that implementation is not `const` - --> $DIR/const-drop-fail.rs:28:23 + = note: the trait bound `NonTrivialDrop: Destruct` is not satisfied +note: required by a bound in `check` + --> $DIR/const-drop-fail.rs:24:19 | -LL | const _: () = check($exp); - | ^^^^^^^^^^^ -... -LL | / check_all! { -LL | | NonTrivialDrop, -LL | | ConstImplWithDropGlue(NonTrivialDrop), -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) +LL | const fn check(_: T) {} + | ^^^^^^^^^^^^^^^ required by this bound in `check` +help: consider borrowing here + | +LL | &NonTrivialDrop, + | + +LL | &mut NonTrivialDrop, + | ++++ -error[E0277]: can't drop `NonTrivialDrop` in const contexts - --> $DIR/const-drop-fail.rs:28:23 +error[E0277]: can't drop `ConstImplWithDropGlue` + --> $DIR/const-drop-fail.rs:34:5 | -LL | const _: () = check($exp); - | ^^^^^^^^^^^ within `ConstImplWithDropGlue`, the trait `~const Destruct` is not implemented for `NonTrivialDrop` +LL | const _: () = check($exp); + | ----- required by a bound introduced by this call ... -LL | / check_all! { -LL | | NonTrivialDrop, -LL | | ConstImplWithDropGlue(NonTrivialDrop), -LL | | } - | |_- in this macro invocation +LL | ConstImplWithDropGlue(NonTrivialDrop), + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Destruct` is not implemented for `ConstImplWithDropGlue` | -note: the trait `Destruct` is implemented for `NonTrivialDrop`, but that implementation is not `const` - --> $DIR/const-drop-fail.rs:28:23 + = note: the trait bound `ConstImplWithDropGlue: Destruct` is not satisfied +note: required by a bound in `check` + --> $DIR/const-drop-fail.rs:24:19 | -LL | const _: () = check($exp); - | ^^^^^^^^^^^ -... -LL | / check_all! { -LL | | NonTrivialDrop, -LL | | ConstImplWithDropGlue(NonTrivialDrop), -LL | | } - | |_- in this macro invocation -note: required because it appears within the type `ConstImplWithDropGlue` - --> $DIR/const-drop-fail.rs:18:8 - | -LL | struct ConstImplWithDropGlue(NonTrivialDrop); - | ^^^^^^^^^^^^^^^^^^^^^ - = note: this error originates in the macro `check_all` (in Nightly builds, run with -Z macro-backtrace for more info) +LL | const fn check(_: T) {} + | ^^^^^^^^^^^^^^^ required by this bound in `check` +help: consider borrowing here + | +LL | &ConstImplWithDropGlue(NonTrivialDrop), + | + +LL | &mut ConstImplWithDropGlue(NonTrivialDrop), + | ++++ error: aborting due to 2 previous errors diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr index e745cbd244292..04d55295f28a8 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr @@ -1,57 +1,46 @@ -error[E0277]: can't drop `NonTrivialDrop` in const contexts - --> $DIR/const-drop-fail.rs:28:23 +error[E0277]: can't drop `NonTrivialDrop` + --> $DIR/const-drop-fail.rs:33:5 | -LL | const _: () = check($exp); - | ^^^^^^^^^^^ the trait `~const Destruct` is not implemented for `NonTrivialDrop` +LL | const _: () = check($exp); + | ----- required by a bound introduced by this call ... -LL | / check_all! { -LL | | NonTrivialDrop, -LL | | ConstImplWithDropGlue(NonTrivialDrop), -LL | | } - | |_- in this macro invocation +LL | NonTrivialDrop, + | ^^^^^^^^^^^^^^ the trait `Destruct` is not implemented for `NonTrivialDrop` | -note: the trait `Destruct` is implemented for `NonTrivialDrop`, but that implementation is not `const` - --> $DIR/const-drop-fail.rs:28:23 + = note: the trait bound `NonTrivialDrop: Destruct` is not satisfied +note: required by a bound in `check` + --> $DIR/const-drop-fail.rs:24:19 | -LL | const _: () = check($exp); - | ^^^^^^^^^^^ -... -LL | / check_all! { -LL | | NonTrivialDrop, -LL | | ConstImplWithDropGlue(NonTrivialDrop), -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) +LL | const fn check(_: T) {} + | ^^^^^^^^^^^^^^^ required by this bound in `check` +help: consider borrowing here + | +LL | &NonTrivialDrop, + | + +LL | &mut NonTrivialDrop, + | ++++ -error[E0277]: can't drop `NonTrivialDrop` in const contexts - --> $DIR/const-drop-fail.rs:28:23 +error[E0277]: can't drop `ConstImplWithDropGlue` + --> $DIR/const-drop-fail.rs:34:5 | -LL | const _: () = check($exp); - | ^^^^^^^^^^^ within `ConstImplWithDropGlue`, the trait `~const Destruct` is not implemented for `NonTrivialDrop` +LL | const _: () = check($exp); + | ----- required by a bound introduced by this call ... -LL | / check_all! { -LL | | NonTrivialDrop, -LL | | ConstImplWithDropGlue(NonTrivialDrop), -LL | | } - | |_- in this macro invocation +LL | ConstImplWithDropGlue(NonTrivialDrop), + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Destruct` is not implemented for `ConstImplWithDropGlue` | -note: the trait `Destruct` is implemented for `NonTrivialDrop`, but that implementation is not `const` - --> $DIR/const-drop-fail.rs:28:23 + = note: the trait bound `ConstImplWithDropGlue: Destruct` is not satisfied +note: required by a bound in `check` + --> $DIR/const-drop-fail.rs:24:19 | -LL | const _: () = check($exp); - | ^^^^^^^^^^^ -... -LL | / check_all! { -LL | | NonTrivialDrop, -LL | | ConstImplWithDropGlue(NonTrivialDrop), -LL | | } - | |_- in this macro invocation -note: required because it appears within the type `ConstImplWithDropGlue` - --> $DIR/const-drop-fail.rs:18:8 - | -LL | struct ConstImplWithDropGlue(NonTrivialDrop); - | ^^^^^^^^^^^^^^^^^^^^^ - = note: this error originates in the macro `check_all` (in Nightly builds, run with -Z macro-backtrace for more info) +LL | const fn check(_: T) {} + | ^^^^^^^^^^^^^^^ required by this bound in `check` +help: consider borrowing here + | +LL | &ConstImplWithDropGlue(NonTrivialDrop), + | + +LL | &mut ConstImplWithDropGlue(NonTrivialDrop), + | ++++ error: aborting due to 2 previous errors diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-gate.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-gate.stderr index 6a81f96d88d2e..cc9bdd2715f70 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-gate.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-gate.stderr @@ -6,16 +6,6 @@ LL | #[derive_const(Default)] | = help: add `#![feature(derive_const)]` to the crate attributes to enable -error: const `impl` for trait `Default` which is not marked with `#[const_trait]` - --> $DIR/derive-const-gate.rs:1:16 - | -LL | #[derive_const(Default)] - | ^^^^^^^ - | - = 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 - = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr index 88054096e630b..046dbae0eae7e 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr @@ -10,44 +10,6 @@ error[E0635]: unknown feature `const_default_impls` LL | #![feature(const_trait_impl, const_cmp, const_default_impls, derive_const)] | ^^^^^^^^^^^^^^^^^^^ -error: const `impl` for trait `Default` which is not marked with `#[const_trait]` - --> $DIR/derive-const-use.rs:6:12 - | -LL | impl const Default for A { - | ^^^^^^^ - | - = 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: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]` - --> $DIR/derive-const-use.rs:10:12 - | -LL | impl const PartialEq for A { - | ^^^^^^^^^ - | - = 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: const `impl` for trait `Default` which is not marked with `#[const_trait]` - --> $DIR/derive-const-use.rs:14:16 - | -LL | #[derive_const(Default, PartialEq)] - | ^^^^^^^ - | - = 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 - = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]` - --> $DIR/derive-const-use.rs:14:25 - | -LL | #[derive_const(Default, PartialEq)] - | ^^^^^^^^^ - | - = 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 - = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: aborting due to 6 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0635`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-with-params.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-with-params.stderr index fa78326587c71..37d123e4ccc4d 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-with-params.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-with-params.stderr @@ -1,13 +1,3 @@ -error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]` - --> $DIR/derive-const-with-params.rs:6:16 - | -LL | #[derive_const(PartialEq)] - | ^^^^^^^^^ - | - = 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 - = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) - error: ~const can only be applied to `#[const_trait]` traits --> $DIR/derive-const-with-params.rs:6:16 | @@ -16,5 +6,5 @@ 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 2 previous errors +error: aborting due to previous error diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.rs index 6df47022cc948..bdd336f887909 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.rs @@ -1,6 +1,6 @@ // revisions: stock gated stocknc gatednc // [gated] check-pass -#![cfg_attr(any(gated, gatednc), feature(const_trait_impl))] +#![cfg_attr(any(gated, gatednc), feature(const_trait_impl, effects))] // aux-build: cross-crate.rs extern crate cross_crate; diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.stock.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.stock.stderr index 22f13a7416e92..35e8852c04382 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.stock.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.stock.stderr @@ -1,12 +1,14 @@ -error[E0015]: cannot call non-const fn `::func` in constant functions - --> $DIR/cross-crate.rs:20:11 +error[E0282]: type annotations needed + --> $DIR/cross-crate.rs:12:11 | LL | Const.func(); - | ^^^^^^ + | ^^^^ | - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants - = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable +help: try using a fully qualified path to specify the expected types + | +LL | >::func(Const); + | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ~ error: aborting due to previous error -For more information about this error, try `rustc --explain E0015`. +For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.stocknc.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.stocknc.stderr index 9e97d3f113760..35e8852c04382 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.stocknc.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.stocknc.stderr @@ -1,15 +1,14 @@ -error[E0277]: the trait bound `cross_crate::NonConst: cross_crate::MyTrait` is not satisfied - --> $DIR/cross-crate.rs:17:14 +error[E0282]: type annotations needed + --> $DIR/cross-crate.rs:12:11 | -LL | NonConst.func(); - | ^^^^ the trait `~const cross_crate::MyTrait` is not implemented for `cross_crate::NonConst` +LL | Const.func(); + | ^^^^ | -note: the trait `cross_crate::MyTrait` is implemented for `cross_crate::NonConst`, but that implementation is not `const` - --> $DIR/cross-crate.rs:17:5 +help: try using a fully qualified path to specify the expected types | -LL | NonConst.func(); - | ^^^^^^^^ +LL | >::func(Const); + | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ~ error: aborting due to previous error -For more information about this error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr index 21ecddaffbb65..b617ed85d587d 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr @@ -1,15 +1,11 @@ -error[E0277]: the trait bound `(): ~const Tr` is not satisfied +error[E0015]: cannot call non-const fn `<() as Tr>::a` in constant functions --> $DIR/default-method-body-is-const-same-trait-ck.rs:8:12 | LL | ().a() - | ^ the trait `~const Tr` is not implemented for `()` + | ^^^ | -note: the trait `Tr` is implemented for `()`, but that implementation is not `const` - --> $DIR/default-method-body-is-const-same-trait-ck.rs:8:9 - | -LL | ().a() - | ^^ + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants error: aborting due to previous error -For more information about this error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/helloworld.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/helloworld.rs index 49457354cc9f4..9637814e6f2f4 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/helloworld.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/helloworld.rs @@ -4,7 +4,7 @@ // ^ effects doesn't have a gate so we will trick tidy into thinking this is a gate test #![feature(const_trait_impl, effects, rustc_attrs)] - +/* FIXME(effects) // ensure we are passing in the correct host effect in always const contexts. pub const fn hmm() -> usize { @@ -20,7 +20,7 @@ const _: () = { assert!(0 == x); }; -/* FIXME(effects) + FIXME(effects) pub const fn uwu(x: [u8; hmm::<()>()]) { let [] = x; } diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/generic-bound.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/generic-bound.stderr index 1b21d7c0e0e60..6a177592b6453 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/generic-bound.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/generic-bound.stderr @@ -1,11 +1,16 @@ -error: const `impl` for trait `Add` which is not marked with `#[const_trait]` - --> $DIR/generic-bound.rs:16:15 +error[E0015]: cannot call non-const operator in constant functions + --> $DIR/generic-bound.rs:25:5 | -LL | impl const std::ops::Add for S { - | ^^^^^^^^^^^^^ +LL | arg + arg + | ^^^^^^^^^ + | +note: impl defined here, but it is not `const` + --> $DIR/generic-bound.rs:16:1 | - = 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 +LL | impl const std::ops::Add for S { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants error: aborting due to previous error +For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-102985.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-102985.stderr index b98ccbe5d03ec..e3269a19ed25e 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-102985.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-102985.stderr @@ -1,41 +1,11 @@ -error[E0277]: the trait bound `[closure@$DIR/issue-102985.rs:4:23: 4:25]: ~const Fn<()>` is not satisfied - --> $DIR/issue-102985.rs:5:14 - | -LL | n => n(), - | ^^^ expected an `Fn<()>` closure, found `[closure@$DIR/issue-102985.rs:4:23: 4:25]` - | - = help: the trait `~const Fn<()>` is not implemented for closure `[closure@$DIR/issue-102985.rs:4:23: 4:25]` -note: the trait `Fn<()>` is implemented for `[closure@$DIR/issue-102985.rs:4:23: 4:25]`, but that implementation is not `const` - --> $DIR/issue-102985.rs:5:14 - | -LL | n => n(), - | ^^^ - = note: wrap the `[closure@$DIR/issue-102985.rs:4:23: 4:25]` in a closure with no arguments: `|| { /* code */ }` - -error[E0277]: the trait bound `[closure@$DIR/issue-102985.rs:4:23: 4:25]: ~const Fn<()>` is not satisfied - --> $DIR/issue-102985.rs:5:14 - | -LL | n => n(), - | ^^^ expected an `Fn<()>` closure, found `[closure@$DIR/issue-102985.rs:4:23: 4:25]` - | - = help: the trait `~const Fn<()>` is not implemented for closure `[closure@$DIR/issue-102985.rs:4:23: 4:25]` -note: the trait `Fn<()>` is implemented for `[closure@$DIR/issue-102985.rs:4:23: 4:25]`, but that implementation is not `const` - --> $DIR/issue-102985.rs:5:14 - | -LL | n => n(), - | ^^^ - = note: wrap the `[closure@$DIR/issue-102985.rs:4:23: 4:25]` in a closure with no arguments: `|| { /* code */ }` - error[E0015]: cannot call non-const closure in constants --> $DIR/issue-102985.rs:5:14 | LL | n => n(), | ^^^ | - = note: closures need an RFC before allowed to be called in constants = note: calls in constants are limited to constant functions, tuple structs and tuple variants -error: aborting due to 3 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0015, E0277. -For more information about an error, try `rustc --explain E0015`. +For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/match-non-const-eq.gated.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/match-non-const-eq.gated.stderr index bd0dd126c5e6b..33133a604ec7e 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/match-non-const-eq.gated.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/match-non-const-eq.gated.stderr @@ -1,16 +1,3 @@ -error[E0277]: can't compare `str` with `str` in const contexts - --> $DIR/match-non-const-eq.rs:6:9 - | -LL | "a" => (), - | ^^^ no implementation for `str == str` - | - = help: the trait `~const PartialEq` is not implemented for `str` -note: the trait `PartialEq` is implemented for `str`, but that implementation is not `const` - --> $DIR/match-non-const-eq.rs:6:9 - | -LL | "a" => (), - | ^^^ - error[E0015]: cannot match on `str` in constant functions --> $DIR/match-non-const-eq.rs:6:9 | @@ -20,7 +7,6 @@ LL | "a" => (), = note: `str` cannot be compared in compile-time, and therefore cannot be used in `match`es = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0015, E0277. -For more information about an error, try `rustc --explain E0015`. +For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness-2.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness-2.stderr index 8923416f4c77b..92bc9815e963a 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness-2.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness-2.stderr @@ -1,21 +1,11 @@ -error[E0277]: the trait bound `T: ~const Sup` is not satisfied +error[E0015]: cannot call non-const fn `::a` in constant functions --> $DIR/specializing-constness-2.rs:27:5 | LL | ::a(); - | ^^^^^^^^^^^^^ the trait `~const Sup` is not implemented for `T` + | ^^^^^^^^^^^^^ | -note: required for `T` to implement `~const A` - --> $DIR/specializing-constness-2.rs:20:37 - | -LL | impl const A for T { - | ---------- ^ ^ - | | - | unsatisfied trait bound introduced here -help: consider further restricting this bound - | -LL | const fn generic() { - | ++++++++++++ + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants error: aborting due to previous error -For more information about this error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.stable.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.stable.stderr index a1aca762ef479..3cdb216186147 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.stable.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.stable.stderr @@ -1,14 +1,3 @@ -error: trait implementations cannot be const stable yet - --> $DIR/staged-api.rs:19:1 - | -LL | / impl const MyTrait for Foo { -LL | | -LL | | fn func() {} -LL | | } - | |_^ - | - = note: see issue #67792 for more information - error: function has missing const stability attribute --> $DIR/staged-api.rs:42:1 | @@ -21,5 +10,5 @@ LL | | // ^ fails, because the `foo` feature is not active LL | | } | |_^ -error: aborting due to 2 previous errors +error: aborting due to previous error diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.unstable.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.unstable.stderr index c38d1a81ae77b..4eb054e3b042b 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.unstable.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.unstable.stderr @@ -1,34 +1,50 @@ -error: `::func` is not yet stable as a const fn +error[E0015]: cannot call non-const fn `::func` in constant functions + --> $DIR/staged-api.rs:32:5 + | +LL | Unstable::func(); + | ^^^^^^^^^^^^^^^^ + | + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants + +error[E0015]: cannot call non-const fn `::func` in constant functions --> $DIR/staged-api.rs:35:5 | LL | Foo::func(); | ^^^^^^^^^^^ | - = help: add `#![feature(foo)]` to the crate attributes to enable + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants + +error[E0015]: cannot call non-const fn `::func` in constant functions + --> $DIR/staged-api.rs:44:5 + | +LL | Unstable::func(); + | ^^^^^^^^^^^^^^^^ + | + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants -error: `::func` is not yet stable as a const fn +error[E0015]: cannot call non-const fn `::func` in constant functions --> $DIR/staged-api.rs:47:5 | LL | Foo::func(); | ^^^^^^^^^^^ | - = help: add `#![feature(foo)]` to the crate attributes to enable + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants -error: `::func` is not yet stable as a const fn +error[E0015]: cannot call non-const fn `::func` in constant functions --> $DIR/staged-api.rs:55:5 | LL | Unstable::func(); | ^^^^^^^^^^^^^^^^ | - = help: const-stable functions can only call other const-stable functions + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants -error: `::func` is not yet stable as a const fn +error[E0015]: cannot call non-const fn `::func` in constant functions --> $DIR/staged-api.rs:57:5 | LL | Foo::func(); | ^^^^^^^^^^^ | - = help: const-stable functions can only call other const-stable functions + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants error: `const_context_not_const_stable` is not yet stable as a const fn --> $DIR/staged-api.rs:59:5 @@ -38,5 +54,6 @@ LL | const_context_not_const_stable() | = help: const-stable functions can only call other const-stable functions -error: aborting due to 5 previous errors +error: aborting due to 7 previous errors +For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-and-const-params.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-and-const-params.stderr index aae72f36e5778..12b8305d6e8d1 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-and-const-params.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-and-const-params.stderr @@ -10,5 +10,12 @@ note: this function is not `const`, so it cannot have `~const` trait bounds LL | fn bar(_: Foo) -> Foo<{ A::add(N) }> { | ^^^ -error: aborting due to previous error +error[E0080]: evaluation of `bar::<(), 0>::{constant#0}` failed + --> $DIR/tilde-const-and-const-params.rs:25:61 + | +LL | fn bar(_: Foo) -> Foo<{ A::add(N) }> { + | ^^^^^^^^^ calling non-const function `<() as Add42>::add` + +error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.stderr index 35dc1ca129b12..deed05ae17982 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.stderr @@ -1,20 +1,29 @@ -error: const `impl` for trait `Try` which is not marked with `#[const_trait]` - --> $DIR/trait-default-body-stability.rs:18:12 +error[E0015]: `?` cannot determine the branch of `T` in constant functions + --> $DIR/trait-default-body-stability.rs:44:9 | -LL | impl const Try for T { - | ^^^ +LL | T? + | ^^ + | +note: impl defined here, but it is not `const` + --> $DIR/trait-default-body-stability.rs:18:1 | - = 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 +LL | impl const Try for T { + | ^^^^^^^^^^^^^^^^^^^^ + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants -error: const `impl` for trait `FromResidual` which is not marked with `#[const_trait]` - --> $DIR/trait-default-body-stability.rs:33:12 +error[E0015]: `?` cannot convert from residual of `T` in constant functions + --> $DIR/trait-default-body-stability.rs:44:9 | -LL | impl const FromResidual for T { - | ^^^^^^^^^^^^ +LL | T? + | ^^ + | +note: impl defined here, but it is not `const` + --> $DIR/trait-default-body-stability.rs:33:1 | - = 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 +LL | impl const FromResidual for T { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0015`.