From cc5960c16db0337dac43993123d8c8762b3ea43a Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Wed, 13 Apr 2022 13:03:46 +1000 Subject: [PATCH 01/51] Add new generic param --- .../src/infer/canonical/query_response.rs | 4 + .../infer/error_reporting/need_type_info.rs | 2 + compiler/rustc_infer/src/infer/mod.rs | 2 +- .../rustc_infer/src/infer/opaque_types.rs | 4 +- .../src/infer/outlives/components.rs | 4 + .../src/infer/outlives/obligations.rs | 2 + .../rustc_infer/src/infer/outlives/verify.rs | 4 + compiler/rustc_infer/src/traits/engine.rs | 9 +- compiler/rustc_infer/src/traits/mod.rs | 8 - compiler/rustc_infer/src/traits/util.rs | 8 +- compiler/rustc_macros/src/query.rs | 20 -- compiler/rustc_middle/src/infer/canonical.rs | 9 +- .../rustc_middle/src/mir/interpret/queries.rs | 2 - compiler/rustc_middle/src/query/mod.rs | 36 +--- compiler/rustc_middle/src/traits/mod.rs | 2 +- compiler/rustc_middle/src/ty/adjustment.rs | 2 +- compiler/rustc_middle/src/ty/context.rs | 15 +- compiler/rustc_middle/src/ty/error.rs | 21 +- compiler/rustc_middle/src/ty/flags.rs | 2 + compiler/rustc_middle/src/ty/generics.rs | 1 + compiler/rustc_middle/src/ty/impls_ty.rs | 5 + compiler/rustc_middle/src/ty/instance.rs | 2 +- compiler/rustc_middle/src/ty/mod.rs | 185 ++++++------------ compiler/rustc_middle/src/ty/print/pretty.rs | 8 +- compiler/rustc_middle/src/ty/query.rs | 12 -- compiler/rustc_middle/src/ty/relate.rs | 21 +- .../rustc_middle/src/ty/structural_impls.rs | 14 +- compiler/rustc_middle/src/ty/sty.rs | 21 +- compiler/rustc_middle/src/ty/subst.rs | 29 ++- compiler/rustc_middle/src/ty/util.rs | 2 + compiler/rustc_middle/src/ty/walk.rs | 1 + .../rustc_mir_dataflow/src/elaborate_drops.rs | 2 +- compiler/rustc_monomorphize/src/collector.rs | 2 +- compiler/rustc_monomorphize/src/lib.rs | 2 +- compiler/rustc_query_impl/src/plumbing.rs | 12 -- compiler/rustc_symbol_mangling/src/v0.rs | 1 + .../rustc_trait_selection/src/traits/mod.rs | 38 ++-- .../src/traits/object_safety.rs | 6 +- .../src/traits/query/evaluate_obligation.rs | 18 +- .../src/traits/select/confirmation.rs | 14 +- .../src/traits/select/mod.rs | 24 +-- compiler/rustc_ty_utils/src/ty.rs | 74 +------ compiler/rustc_typeck/src/collect.rs | 1 + 43 files changed, 251 insertions(+), 400 deletions(-) diff --git a/compiler/rustc_infer/src/infer/canonical/query_response.rs b/compiler/rustc_infer/src/infer/canonical/query_response.rs index 7120d5ad93455..61df4637f19ed 100644 --- a/compiler/rustc_infer/src/infer/canonical/query_response.rs +++ b/compiler/rustc_infer/src/infer/canonical/query_response.rs @@ -466,6 +466,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { opt_values[b] = Some(*original_value); } } + GenericArgKind::Constness(_) => {} } } @@ -571,6 +572,9 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { // encounter this branch. span_bug!(cause.span, "unexpected const outlives {:?}", predicate); } + GenericArgKind::Constness(_) => { + span_bug!(cause.span, "unexpected constness outlives {:?}", predicate); + } }; let predicate = predicate.rebind(atom).to_predicate(self.tcx); diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs index 4d29fc469462c..b4e1399824ba2 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs @@ -292,6 +292,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } } GenericArgKind::Lifetime(_) => bug!("unexpected lifetime"), + // TODO ? + GenericArgKind::Constness(_) => bug!("unexpected constness arg"), } } diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 28f037cc61a76..fc4a01f2cac54 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -1752,7 +1752,7 @@ impl<'tcx> TyOrConstInferVar<'tcx> { match arg.unpack() { GenericArgKind::Type(ty) => Self::maybe_from_ty(ty), GenericArgKind::Const(ct) => Self::maybe_from_const(ct), - GenericArgKind::Lifetime(_) => None, + GenericArgKind::Lifetime(_) | GenericArgKind::Constness(_) => None, } } diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs index f11701bba6f43..c7821422c245b 100644 --- a/compiler/rustc_infer/src/infer/opaque_types.rs +++ b/compiler/rustc_infer/src/infer/opaque_types.rs @@ -379,7 +379,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { .iter() .filter_map(|arg| match arg.unpack() { GenericArgKind::Lifetime(r) => Some(r), - GenericArgKind::Type(_) | GenericArgKind::Const(_) => None, + GenericArgKind::Type(_) + | GenericArgKind::Const(_) + | GenericArgKind::Constness(_) => None, }) .chain(std::iter::once(self.tcx.lifetimes.re_static)) .collect(), diff --git a/compiler/rustc_infer/src/infer/outlives/components.rs b/compiler/rustc_infer/src/infer/outlives/components.rs index 7234660dbcd32..b4734cc931478 100644 --- a/compiler/rustc_infer/src/infer/outlives/components.rs +++ b/compiler/rustc_infer/src/infer/outlives/components.rs @@ -88,6 +88,8 @@ fn compute_components<'tcx>( GenericArgKind::Const(_) => { compute_components_recursive(tcx, child, out, visited); } + // TODO ? + GenericArgKind::Constness(_) => {} } } } @@ -210,6 +212,8 @@ fn compute_components_recursive<'tcx>( GenericArgKind::Const(_) => { compute_components_recursive(tcx, child, out, visited); } + // TODO ? + GenericArgKind::Constness(_) => {} } } } diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs index 59cf39abe6440..70b585ecaa542 100644 --- a/compiler/rustc_infer/src/infer/outlives/obligations.rs +++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs @@ -391,6 +391,8 @@ where GenericArgKind::Const(_) => { // Const parameters don't impose constraints. } + // TODO ? + GenericArgKind::Constness(_) => {} } } diff --git a/compiler/rustc_infer/src/infer/outlives/verify.rs b/compiler/rustc_infer/src/infer/outlives/verify.rs index 86b025dce5eda..7a099d27ecd8b 100644 --- a/compiler/rustc_infer/src/infer/outlives/verify.rs +++ b/compiler/rustc_infer/src/infer/outlives/verify.rs @@ -67,6 +67,8 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> { GenericArgKind::Type(ty) => Some(self.type_bound(ty, visited)), GenericArgKind::Lifetime(_) => None, GenericArgKind::Const(_) => Some(self.recursive_bound(child, visited)), + // TODO ? + GenericArgKind::Constness(_) => None, }) .filter(|bound| { // Remove bounds that must hold, since they are not interesting. @@ -208,6 +210,8 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> { if !lt.is_late_bound() { Some(VerifyBound::OutlivedBy(lt)) } else { None } } GenericArgKind::Const(_) => Some(self.recursive_bound(child, visited)), + // TODO ? + GenericArgKind::Constness(_) => None, }) .filter(|bound| { // Remove bounds that must hold, since they are not interesting. diff --git a/compiler/rustc_infer/src/traits/engine.rs b/compiler/rustc_infer/src/traits/engine.rs index 736278ba0d346..00ef13f57eb31 100644 --- a/compiler/rustc_infer/src/traits/engine.rs +++ b/compiler/rustc_infer/src/traits/engine.rs @@ -27,14 +27,19 @@ pub trait TraitEngine<'tcx>: 'tcx { def_id: DefId, cause: ObligationCause<'tcx>, ) { - let trait_ref = ty::TraitRef { def_id, substs: infcx.tcx.mk_substs_trait(ty, &[]) }; + let trait_ref = ty::TraitRef { + def_id, + substs: infcx.tcx.mk_substs_trait(ty, &[], ty::ConstnessArg::Param), + }; self.register_predicate_obligation( infcx, Obligation { 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_poly_trait_predicate() + .to_predicate(infcx.tcx), }, ); } diff --git a/compiler/rustc_infer/src/traits/mod.rs b/compiler/rustc_infer/src/traits/mod.rs index 4df4de21a0f07..a2bcb8ff1e363 100644 --- a/compiler/rustc_infer/src/traits/mod.rs +++ b/compiler/rustc_infer/src/traits/mod.rs @@ -70,14 +70,6 @@ impl<'tcx> PredicateObligation<'tcx> { } impl<'tcx> TraitObligation<'tcx> { - /// Returns `true` if the trait predicate is considered `const` in its ParamEnv. - pub fn is_const(&self) -> bool { - match (self.predicate.skip_binder().constness, self.param_env.constness()) { - (ty::BoundConstness::ConstIfConst, hir::Constness::Const) => true, - _ => false, - } - } - 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 674c75fdee561..39dc456f79376 100644 --- a/compiler/rustc_infer/src/traits/util.rs +++ b/compiler/rustc_infer/src/traits/util.rs @@ -75,14 +75,18 @@ pub fn elaborate_trait_ref<'tcx>( tcx: TyCtxt<'tcx>, trait_ref: ty::PolyTraitRef<'tcx>, ) -> Elaborator<'tcx> { - elaborate_predicates(tcx, std::iter::once(trait_ref.without_const().to_predicate(tcx))) + elaborate_predicates( + tcx, + std::iter::once(trait_ref.to_poly_trait_predicate().to_predicate(tcx)), + ) } pub fn elaborate_trait_refs<'tcx>( tcx: TyCtxt<'tcx>, trait_refs: impl Iterator>, ) -> Elaborator<'tcx> { - let predicates = trait_refs.map(|trait_ref| trait_ref.without_const().to_predicate(tcx)); + let predicates = + trait_refs.map(|trait_ref| trait_ref.to_poly_trait_predicate().to_predicate(tcx)); elaborate_predicates(tcx, predicates) } diff --git a/compiler/rustc_macros/src/query.rs b/compiler/rustc_macros/src/query.rs index a6912653368b5..4144959b61eff 100644 --- a/compiler/rustc_macros/src/query.rs +++ b/compiler/rustc_macros/src/query.rs @@ -58,9 +58,6 @@ enum QueryModifier { /// Use a separate query provider for local and extern crates SeparateProvideExtern(Ident), - - /// Always remap the ParamEnv's constness before hashing and passing to the query provider - RemapEnvConstness(Ident), } impl Parse for QueryModifier { @@ -126,8 +123,6 @@ impl Parse for QueryModifier { Ok(QueryModifier::EvalAlways(modifier)) } else if modifier == "separate_provide_extern" { Ok(QueryModifier::SeparateProvideExtern(modifier)) - } else if modifier == "remap_env_constness" { - Ok(QueryModifier::RemapEnvConstness(modifier)) } else { Err(Error::new(modifier.span(), "unknown query modifier")) } @@ -227,9 +222,6 @@ struct QueryModifiers { /// Use a separate query provider for local and extern crates separate_provide_extern: Option, - - /// Always remap the ParamEnv's constness before hashing. - remap_env_constness: Option, } /// Process query modifiers into a struct, erroring on duplicates @@ -244,7 +236,6 @@ fn process_modifiers(query: &mut Query) -> QueryModifiers { let mut anon = None; let mut eval_always = None; let mut separate_provide_extern = None; - let mut remap_env_constness = None; for modifier in query.modifiers.0.drain(..) { match modifier { QueryModifier::LoadCached(tcx, id, block) => { @@ -344,12 +335,6 @@ fn process_modifiers(query: &mut Query) -> QueryModifiers { } separate_provide_extern = Some(ident); } - QueryModifier::RemapEnvConstness(ident) => { - if remap_env_constness.is_some() { - panic!("duplicate modifier `remap_env_constness` for query `{}`", query.name); - } - remap_env_constness = Some(ident) - } } } let desc = desc.unwrap_or_else(|| { @@ -366,7 +351,6 @@ fn process_modifiers(query: &mut Query) -> QueryModifiers { anon, eval_always, separate_provide_extern, - remap_env_constness, } } @@ -503,10 +487,6 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream { if let Some(separate_provide_extern) = &modifiers.separate_provide_extern { attributes.push(quote! { (#separate_provide_extern) }); } - // Pass on the remap_env_constness modifier - if let Some(remap_env_constness) = &modifiers.remap_env_constness { - attributes.push(quote! { (#remap_env_constness) }); - } // This uses the span of the query definition for the commas, // which can be important if we later encounter any ambiguity diff --git a/compiler/rustc_middle/src/infer/canonical.rs b/compiler/rustc_middle/src/infer/canonical.rs index c6fe3e721032f..f090588061844 100644 --- a/compiler/rustc_middle/src/infer/canonical.rs +++ b/compiler/rustc_middle/src/infer/canonical.rs @@ -252,14 +252,6 @@ impl<'tcx, R> Canonical<'tcx, QueryResponse<'tcx, R>> { } } -impl<'tcx, R> Canonical<'tcx, ty::ParamEnvAnd<'tcx, R>> { - #[inline] - pub fn without_const(mut self) -> Self { - self.value = self.value.without_const(); - self - } -} - impl<'tcx, V> Canonical<'tcx, V> { /// Allows you to map the `value` of a canonical while keeping the /// same set of bound variables. @@ -339,6 +331,7 @@ impl<'tcx> CanonicalVarValues<'tcx> { kind: ty::ConstKind::Bound(ty::INNERMOST, ty::BoundVar::from_u32(i)), }) .into(), + GenericArgKind::Constness(_) => *kind, }) .collect(), } diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs index 786927e2dad70..e7148d20f9b77 100644 --- a/compiler/rustc_middle/src/mir/interpret/queries.rs +++ b/compiler/rustc_middle/src/mir/interpret/queries.rs @@ -103,7 +103,6 @@ impl<'tcx> TyCtxt<'tcx> { cid: GlobalId<'tcx>, span: Option, ) -> EvalToConstValueResult<'tcx> { - let param_env = param_env.with_const(); // Const-eval shouldn't depend on lifetimes at all, so we can erase them, which should // improve caching of queries. let inputs = self.erase_regions(param_env.and(cid)); @@ -164,7 +163,6 @@ impl<'tcx> TyCtxtAt<'tcx> { gid: GlobalId<'tcx>, param_env: ty::ParamEnv<'tcx>, ) -> Result, ErrorHandled> { - let param_env = param_env.with_const(); trace!("eval_to_allocation: Need to compute {:?}", gid); let raw_const = self.eval_to_allocation_raw(param_env.and(gid))?; Ok(self.global_alloc(raw_const.alloc_id).unwrap_memory()) diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index cbc45526e89fb..4645d12d1fd46 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -995,7 +995,14 @@ rustc_queries! { /// and its field values. query try_destructure_mir_constant(key: ty::ParamEnvAnd<'tcx, mir::ConstantKind<'tcx>>) -> Option> { desc { "destructuring mir constant"} - remap_env_constness + } + + /// Dereference a constant reference or raw pointer and turn the result into a constant + /// again. + query deref_const( + key: ty::ParamEnvAnd<'tcx, ty::Const<'tcx>> + ) -> ty::Const<'tcx> { + desc { "deref constant" } } /// Dereference a constant reference or raw pointer and turn the result into a constant @@ -1004,7 +1011,6 @@ rustc_queries! { key: ty::ParamEnvAnd<'tcx, mir::ConstantKind<'tcx>> ) -> mir::ConstantKind<'tcx> { desc { "dereferencing mir constant" } - remap_env_constness } query const_caller_location(key: (rustc_span::Symbol, u32, u32)) -> ConstValue<'tcx> { @@ -1240,32 +1246,26 @@ rustc_queries! { /// `ty.is_copy()`, etc, since that will prune the environment where possible. query is_copy_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool { desc { "computing whether `{}` is `Copy`", env.value } - remap_env_constness } /// Query backing `Ty::is_sized`. query is_sized_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool { desc { "computing whether `{}` is `Sized`", env.value } - remap_env_constness } /// Query backing `Ty::is_freeze`. query is_freeze_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool { desc { "computing whether `{}` is freeze", env.value } - remap_env_constness } /// Query backing `Ty::is_unpin`. query is_unpin_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool { desc { "computing whether `{}` is `Unpin`", env.value } - remap_env_constness } /// Query backing `Ty::needs_drop`. query needs_drop_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool { desc { "computing whether `{}` needs drop", env.value } - remap_env_constness } /// Query backing `Ty::has_significant_drop_raw`. query has_significant_drop_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool { desc { "computing whether `{}` has a significant drop", env.value } - remap_env_constness } /// Query backing `Ty::is_structural_eq_shallow`. @@ -1304,7 +1304,6 @@ rustc_queries! { key: ty::ParamEnvAnd<'tcx, Ty<'tcx>> ) -> Result, ty::layout::LayoutError<'tcx>> { desc { "computing layout of `{}`", key.value } - remap_env_constness } /// Compute a `FnAbi` suitable for indirect calls, i.e. to `fn` pointers. @@ -1315,7 +1314,6 @@ rustc_queries! { key: ty::ParamEnvAnd<'tcx, (ty::PolyFnSig<'tcx>, &'tcx ty::List>)> ) -> Result<&'tcx abi::call::FnAbi<'tcx, Ty<'tcx>>, ty::layout::FnAbiError<'tcx>> { desc { "computing call ABI of `{}` function pointers", key.value.0 } - remap_env_constness } /// Compute a `FnAbi` suitable for declaring/defining an `fn` instance, and for @@ -1327,7 +1325,6 @@ rustc_queries! { key: ty::ParamEnvAnd<'tcx, (ty::Instance<'tcx>, &'tcx ty::List>)> ) -> Result<&'tcx abi::call::FnAbi<'tcx, Ty<'tcx>>, ty::layout::FnAbiError<'tcx>> { desc { "computing call ABI of `{}`", key.value.0 } - remap_env_constness } query dylib_dependency_formats(_: CrateNum) @@ -1607,7 +1604,6 @@ rustc_queries! { key: ty::ParamEnvAnd<'tcx, Ty<'tcx>> ) -> ty::inhabitedness::DefIdForest<'tcx> { desc { "computing the inhabitedness of `{:?}`", key } - remap_env_constness } query dep_kind(_: CrateNum) -> CrateDepKind { @@ -1803,7 +1799,6 @@ rustc_queries! { NoSolution, > { desc { "normalizing `{:?}`", goal } - remap_env_constness } /// Do not call this query directly: invoke `try_normalize_erasing_regions` instead. @@ -1811,7 +1806,6 @@ rustc_queries! { goal: ParamEnvAnd<'tcx, GenericArg<'tcx>> ) -> Result, NoSolution> { desc { "normalizing `{}`", goal.value } - remap_env_constness } /// Do not call this query directly: invoke `try_normalize_erasing_regions` instead. @@ -1819,7 +1813,6 @@ rustc_queries! { goal: ParamEnvAnd<'tcx, mir::ConstantKind<'tcx>> ) -> Result, NoSolution> { desc { "normalizing `{}`", goal.value } - remap_env_constness } query implied_outlives_bounds( @@ -1829,7 +1822,6 @@ rustc_queries! { NoSolution, > { desc { "computing implied outlives bounds for `{:?}`", goal } - remap_env_constness } /// Do not call this query directly: @@ -1841,7 +1833,6 @@ rustc_queries! { NoSolution, > { desc { "computing dropck types for `{:?}`", goal } - remap_env_constness } /// Do not call this query directly: invoke `infcx.predicate_may_hold()` or @@ -1869,7 +1860,6 @@ rustc_queries! { NoSolution, > { desc { "evaluating `type_op_ascribe_user_type` `{:?}`", goal } - remap_env_constness } /// Do not call this query directly: part of the `Eq` type-op @@ -1880,7 +1870,6 @@ rustc_queries! { NoSolution, > { desc { "evaluating `type_op_eq` `{:?}`", goal } - remap_env_constness } /// Do not call this query directly: part of the `Subtype` type-op @@ -1891,7 +1880,6 @@ rustc_queries! { NoSolution, > { desc { "evaluating `type_op_subtype` `{:?}`", goal } - remap_env_constness } /// Do not call this query directly: part of the `ProvePredicate` type-op @@ -1912,7 +1900,6 @@ rustc_queries! { NoSolution, > { desc { "normalizing `{:?}`", goal } - remap_env_constness } /// Do not call this query directly: part of the `Normalize` type-op @@ -1923,7 +1910,6 @@ rustc_queries! { NoSolution, > { desc { "normalizing `{:?}`", goal } - remap_env_constness } /// Do not call this query directly: part of the `Normalize` type-op @@ -1934,7 +1920,6 @@ rustc_queries! { NoSolution, > { desc { "normalizing `{:?}`", goal } - remap_env_constness } /// Do not call this query directly: part of the `Normalize` type-op @@ -1945,7 +1930,6 @@ rustc_queries! { NoSolution, > { desc { "normalizing `{:?}`", goal } - remap_env_constness } query subst_and_check_impossible_predicates(key: (DefId, SubstsRef<'tcx>)) -> bool { @@ -1959,7 +1943,6 @@ rustc_queries! { goal: CanonicalTyGoal<'tcx> ) -> MethodAutoderefStepsResult<'tcx> { desc { "computing autoderef types for `{:?}`", goal } - remap_env_constness } query supported_target_features(_: CrateNum) -> FxHashMap> { @@ -1992,7 +1975,6 @@ rustc_queries! { key: ty::ParamEnvAnd<'tcx, (DefId, SubstsRef<'tcx>)> ) -> Result>, ErrorGuaranteed> { desc { "resolving instance `{}`", ty::Instance::new(key.value.0, key.value.1) } - remap_env_constness } query resolve_instance_of_const_arg( @@ -2002,7 +1984,6 @@ rustc_queries! { "resolving instance of the const argument `{}`", ty::Instance::new(key.value.0.to_def_id(), key.value.2), } - remap_env_constness } query normalize_opaque_types(key: &'tcx ty::List>) -> &'tcx ty::List> { @@ -2017,7 +1998,6 @@ rustc_queries! { /// size, to account for partial initialisation. See #49298 for details.) query conservative_is_privately_uninhabited(key: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool { desc { "conservatively checking if {:?} is privately uninhabited", key } - remap_env_constness } query limits(key: ()) -> Limits { diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index fe7f72024d358..0b128fbfe3e45 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -616,7 +616,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, ty::ConstnessArg), /// Virtual calls through an object. Object(ImplSourceObjectData<'tcx, N>), diff --git a/compiler/rustc_middle/src/ty/adjustment.rs b/compiler/rustc_middle/src/ty/adjustment.rs index d36cf2fe3f8d0..76afca6226034 100644 --- a/compiler/rustc_middle/src/ty/adjustment.rs +++ b/compiler/rustc_middle/src/ty/adjustment.rs @@ -129,7 +129,7 @@ impl<'tcx> OverloadedDeref<'tcx> { .find(|m| m.kind == ty::AssocKind::Fn) .unwrap() .def_id; - (method_def_id, tcx.mk_substs_trait(source, &[])) + (method_def_id, tcx.mk_substs_trait(source, &[], ty::ConstnessArg::Not)) } } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index a594dab2e20a3..346ef72c44e06 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -921,6 +921,8 @@ impl<'tcx> CanonicalUserType<'tcx> { } _ => false, }, + + GenericArgKind::Constness(_) => false, } }) } @@ -2798,8 +2800,17 @@ impl<'tcx> TyCtxt<'tcx> { iter.intern_with(|xs| self.intern_place_elems(xs)) } - pub fn mk_substs_trait(self, self_ty: Ty<'tcx>, rest: &[GenericArg<'tcx>]) -> SubstsRef<'tcx> { - self.mk_substs(iter::once(self_ty.into()).chain(rest.iter().cloned())) + pub fn mk_substs_trait( + self, + self_ty: Ty<'tcx>, + rest: &[GenericArg<'tcx>], + constness: ty::ConstnessArg, + ) -> SubstsRef<'tcx> { + self.mk_substs( + iter::once(self_ty.into()) + .chain(rest.iter().cloned()) + .chain(iter::once(constness.into())), + ) } pub fn mk_bound_variable_kinds< diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs index 49a518b101dd1..96e6ae4349c16 100644 --- a/compiler/rustc_middle/src/ty/error.rs +++ b/compiler/rustc_middle/src/ty/error.rs @@ -34,6 +34,7 @@ impl ExpectedFound { pub enum TypeError<'tcx> { Mismatch, ConstnessMismatch(ExpectedFound), + ConstnessArgMismatch(ExpectedFound), PolarityMismatch(ExpectedFound), UnsafetyMismatch(ExpectedFound), AbiMismatch(ExpectedFound), @@ -103,6 +104,7 @@ impl<'tcx> fmt::Display for TypeError<'tcx> { CyclicTy(_) => write!(f, "cyclic type of infinite size"), CyclicConst(_) => write!(f, "encountered a self-referencing constant"), Mismatch => write!(f, "types differ"), + ConstnessArgMismatch(_) => write!(f, "constness arguments differ"), ConstnessMismatch(values) => { write!(f, "expected {} bound, found {} bound", values.expected, values.found) } @@ -214,10 +216,21 @@ impl<'tcx> TypeError<'tcx> { pub fn must_include_note(&self) -> bool { use self::TypeError::*; match self { - CyclicTy(_) | CyclicConst(_) | UnsafetyMismatch(_) | ConstnessMismatch(_) - | PolarityMismatch(_) | Mismatch | AbiMismatch(_) | FixedArraySize(_) - | ArgumentSorts(..) | Sorts(_) | IntMismatch(_) | FloatMismatch(_) - | VariadicMismatch(_) | TargetFeatureCast(_) => false, + CyclicTy(_) + | CyclicConst(_) + | UnsafetyMismatch(_) + | ConstnessMismatch(_) + | PolarityMismatch(_) + | Mismatch + | AbiMismatch(_) + | FixedArraySize(_) + | ArgumentSorts(..) + | Sorts(_) + | IntMismatch(_) + | FloatMismatch(_) + | VariadicMismatch(_) + | TargetFeatureCast(_) + | ConstnessArgMismatch(_) => false, Mutability | ArgumentMutability(_) diff --git a/compiler/rustc_middle/src/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs index ea6bb8a7abd4b..ddd13fbfc3a4f 100644 --- a/compiler/rustc_middle/src/ty/flags.rs +++ b/compiler/rustc_middle/src/ty/flags.rs @@ -336,6 +336,8 @@ impl FlagComputation { GenericArgKind::Type(ty) => self.add_ty(ty), GenericArgKind::Lifetime(lt) => self.add_region(lt), GenericArgKind::Const(ct) => self.add_const(ct), + // TODO ? + GenericArgKind::Constness(_) => {} } } } diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs index add2df25884e3..ffe956d325492 100644 --- a/compiler/rustc_middle/src/ty/generics.rs +++ b/compiler/rustc_middle/src/ty/generics.rs @@ -118,6 +118,7 @@ pub struct Generics { pub param_def_id_to_index: FxHashMap, pub has_self: bool, + pub has_constness: bool, pub has_late_bound_regions: Option, } diff --git a/compiler/rustc_middle/src/ty/impls_ty.rs b/compiler/rustc_middle/src/ty/impls_ty.rs index 88397a2bb56ba..a76578b09d765 100644 --- a/compiler/rustc_middle/src/ty/impls_ty.rs +++ b/compiler/rustc_middle/src/ty/impls_ty.rs @@ -97,6 +97,11 @@ impl<'a, 'tcx> HashStable> for ty::subst::GenericArgKin 0xF5u8.hash_stable(hcx, hasher); lt.hash_stable(hcx, hasher); } + ty::subst::GenericArgKind::Constness(constness) => { + 0xFFu8.hash_stable(hcx, hasher); + mem::discriminant(self).hash_stable(hcx, hasher); + constness.hash_stable(hcx, hasher); + } } } } diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index 391abdbe84c5a..be4f2b7f4f0e7 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -536,7 +536,7 @@ impl<'tcx> Instance<'tcx> { let sig = tcx.try_normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), sig).ok()?; assert_eq!(sig.inputs().len(), 1); - let substs = tcx.mk_substs_trait(self_ty, &[sig.inputs()[0].into()]); + let substs = tcx.mk_substs_trait(self_ty, &[sig.inputs()[0].into()], ty::ConstnessArg::Not); debug!("fn_once_adapter_shim: self_ty={:?} sig={:?}", self_ty, sig); Some(Instance { def, substs }) diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index c2c7b3df844ad..e5a6cbc574bb7 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -297,8 +297,45 @@ impl fmt::Display for BoundConstness { } } +/// Whether we should select const impls only or not, or whether this is variable. +#[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + HashStable, + TyEncodable, + TyDecodable, + PartialOrd, + Ord +)] +pub enum ConstnessArg { + Required, + Not, + Param, +} + +impl ConstnessArg { + pub fn is_const(self) -> bool { + matches!(self, ConstnessArg::Required) + } +} + +impl fmt::Display for ConstnessArg { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(match self { + Self::Required => "(constness: required)", + Self::Not => "(constness: not)", + Self::Param => "(constness: parameterized)", + }) + } +} + #[derive(Clone, Debug, PartialEq, Eq, Copy, Hash, TyEncodable, TyDecodable, HashStable)] #[derive(TypeFoldable, TypeVisitable)] +>>>>>>> Add new generic param pub struct ClosureSizeProfileData<'tcx> { /// Tuple containing the types of closure captures before the feature `capture_disjoint_fields` pub before_feature_tys: Ty<'tcx>, @@ -309,7 +346,6 @@ pub struct ClosureSizeProfileData<'tcx> { pub trait DefIdTree: Copy { fn opt_parent(self, id: DefId) -> Option; - #[inline] #[track_caller] fn parent(self, id: DefId) -> DefId { match self.opt_parent(id) { @@ -560,10 +596,9 @@ impl<'tcx> Predicate<'tcx> { let kind = self .kind() .map_bound(|kind| match kind { - PredicateKind::Trait(TraitPredicate { trait_ref, constness, polarity }) => { + PredicateKind::Trait(TraitPredicate { trait_ref, polarity }) => { Some(PredicateKind::Trait(TraitPredicate { trait_ref, - constness, polarity: polarity.flip()?, })) } @@ -774,8 +809,6 @@ impl<'tcx> Predicate<'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 @@ -789,27 +822,6 @@ pub struct TraitPredicate<'tcx> { pub type PolyTraitPredicate<'tcx> = ty::Binder<'tcx, TraitPredicate<'tcx>>; impl<'tcx> TraitPredicate<'tcx> { - pub fn remap_constness(&mut self, tcx: TyCtxt<'tcx>, param_env: &mut ParamEnv<'tcx>) { - if std::intrinsics::unlikely(Some(self.trait_ref.def_id) == tcx.lang_items().drop_trait()) { - // remap without changing constness of this predicate. - // this is because `T: ~const Drop` has a different meaning to `T: Drop` - // FIXME(fee1-dead): remove this logic after beta bump - param_env.remap_constness_with(self.constness) - } else { - *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 we it is always satisfied in non-const contexts. - if let hir::Constness::NotConst = param_env.constness() { - self.constness = ty::BoundConstness::NotConst; - } - } - pub fn def_id(self) -> DefId { self.trait_ref.def_id } @@ -818,9 +830,12 @@ impl<'tcx> TraitPredicate<'tcx> { self.trait_ref.self_ty() } - #[inline] - pub fn is_const_if_const(self) -> bool { - self.constness == BoundConstness::ConstIfConst + pub fn constness(self) -> ty::ConstnessArg { + // TODO remove panic + match self.trait_ref.substs.last().expect("constness").unpack() { + ty::subst::GenericArgKind::Constness(constness) => constness, + _ => panic!("?"), + } } } @@ -834,17 +849,9 @@ 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() + pub fn constness(self) -> ty::ConstnessArg { + // TODO remove panic + self.skip_binder().constness() } } @@ -1331,27 +1338,22 @@ pub struct ParamEnv<'tcx> { #[derive(Copy, Clone)] struct ParamTag { reveal: traits::Reveal, - constness: hir::Constness, } unsafe impl rustc_data_structures::tagged_ptr::Tag for ParamTag { - const BITS: usize = 2; + const BITS: usize = 1; #[inline] fn into_usize(self) -> usize { match self { - Self { reveal: traits::Reveal::UserFacing, constness: hir::Constness::NotConst } => 0, - Self { reveal: traits::Reveal::All, constness: hir::Constness::NotConst } => 1, - Self { reveal: traits::Reveal::UserFacing, constness: hir::Constness::Const } => 2, - Self { reveal: traits::Reveal::All, constness: hir::Constness::Const } => 3, + Self { reveal: traits::Reveal::UserFacing } => 0, + Self { reveal: traits::Reveal::All } => 1, } } #[inline] unsafe fn from_usize(ptr: usize) -> Self { match ptr { - 0 => Self { reveal: traits::Reveal::UserFacing, constness: hir::Constness::NotConst }, - 1 => Self { reveal: traits::Reveal::All, constness: hir::Constness::NotConst }, - 2 => Self { reveal: traits::Reveal::UserFacing, constness: hir::Constness::Const }, - 3 => Self { reveal: traits::Reveal::All, constness: hir::Constness::Const }, + 0 => Self { reveal: traits::Reveal::UserFacing }, + 1 => Self { reveal: traits::Reveal::All }, _ => std::hint::unreachable_unchecked(), } } @@ -1362,7 +1364,6 @@ impl<'tcx> fmt::Debug for ParamEnv<'tcx> { f.debug_struct("ParamEnv") .field("caller_bounds", &self.caller_bounds()) .field("reveal", &self.reveal()) - .field("constness", &self.constness()) .finish() } } @@ -1371,7 +1372,6 @@ impl<'a, 'tcx> HashStable> for ParamEnv<'tcx> { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { self.caller_bounds().hash_stable(hcx, hasher); self.reveal().hash_stable(hcx, hasher); - self.constness().hash_stable(hcx, hasher); } } @@ -1383,7 +1383,6 @@ impl<'tcx> TypeFoldable<'tcx> for ParamEnv<'tcx> { Ok(ParamEnv::new( self.caller_bounds().try_fold_with(folder)?, self.reveal().try_fold_with(folder)?, - self.constness().try_fold_with(folder)?, )) } } @@ -1391,8 +1390,7 @@ impl<'tcx> TypeFoldable<'tcx> for ParamEnv<'tcx> { impl<'tcx> TypeVisitable<'tcx> for ParamEnv<'tcx> { fn visit_with>(&self, visitor: &mut V) -> ControlFlow { self.caller_bounds().visit_with(visitor)?; - self.reveal().visit_with(visitor)?; - self.constness().visit_with(visitor) + self.reveal().visit_with(visitor) } } @@ -1403,7 +1401,7 @@ impl<'tcx> ParamEnv<'tcx> { /// type-checking. #[inline] pub fn empty() -> Self { - Self::new(List::empty(), Reveal::UserFacing, hir::Constness::NotConst) + Self::new(List::empty(), Reveal::UserFacing) } #[inline] @@ -1416,16 +1414,6 @@ impl<'tcx> ParamEnv<'tcx> { self.packed.tag().reveal } - #[inline] - pub fn constness(self) -> hir::Constness { - self.packed.tag().constness - } - - #[inline] - pub fn is_const(self) -> bool { - self.packed.tag().constness == hir::Constness::Const - } - /// Construct a trait environment with no where-clauses in scope /// where the values of all `impl Trait` and other hidden types /// are revealed. This is suitable for monomorphized, post-typeck @@ -1435,17 +1423,13 @@ impl<'tcx> ParamEnv<'tcx> { /// or invoke `param_env.with_reveal_all()`. #[inline] pub fn reveal_all() -> Self { - Self::new(List::empty(), Reveal::All, hir::Constness::NotConst) + Self::new(List::empty(), Reveal::All) } /// Construct a trait environment with the given set of predicates. #[inline] - pub fn new( - caller_bounds: &'tcx List>, - reveal: Reveal, - constness: hir::Constness, - ) -> Self { - ty::ParamEnv { packed: CopyTaggedPtr::new(caller_bounds, ParamTag { reveal, constness }) } + pub fn new(caller_bounds: &'tcx List>, reveal: Reveal) -> Self { + ty::ParamEnv { packed: CopyTaggedPtr::new(caller_bounds, ParamTag { reveal }) } } pub fn with_user_facing(mut self) -> Self { @@ -1453,29 +1437,6 @@ impl<'tcx> ParamEnv<'tcx> { self } - #[inline] - pub fn with_constness(mut self, constness: hir::Constness) -> Self { - self.packed.set_tag(ParamTag { constness, ..self.packed.tag() }); - self - } - - #[inline] - pub fn with_const(mut self) -> Self { - self.packed.set_tag(ParamTag { constness: hir::Constness::Const, ..self.packed.tag() }); - self - } - - #[inline] - pub fn without_const(mut self) -> Self { - self.packed.set_tag(ParamTag { constness: hir::Constness::NotConst, ..self.packed.tag() }); - self - } - - #[inline] - pub fn remap_constness_with(&mut self, mut constness: ty::BoundConstness) { - *self = self.with_constness(constness.and(self.constness())) - } - /// Returns a new parameter environment with the same clauses, but /// which "reveals" the true results of projections in all cases /// (even for associated types that are specializable). This is @@ -1490,17 +1451,13 @@ impl<'tcx> ParamEnv<'tcx> { return self; } - ParamEnv::new( - tcx.normalize_opaque_types(self.caller_bounds()), - Reveal::All, - self.constness(), - ) + ParamEnv::new(tcx.normalize_opaque_types(self.caller_bounds()), Reveal::All) } /// Returns this same environment but with no caller bounds. #[inline] pub fn without_caller_bounds(self) -> Self { - Self::new(List::empty(), self.reveal(), self.constness()) + Self::new(List::empty(), self.reveal()) } /// Creates a suitable environment in which to perform trait @@ -1530,24 +1487,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)] pub struct ParamEnvAnd<'tcx, T> { pub param_env: ParamEnv<'tcx>, @@ -1558,12 +1497,6 @@ impl<'tcx, T> ParamEnvAnd<'tcx, T> { pub fn into_parts(self) -> (ParamEnv<'tcx>, T) { (self.param_env, self.value) } - - #[inline] - pub fn without_const(mut self) -> Self { - self.param_env = self.param_env.without_const(); - self - } } impl<'a, 'tcx, T> HashStable> for ParamEnvAnd<'tcx, T> diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index f721a175c9834..e0f9af1ccb92b 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -2525,10 +2525,6 @@ define_print_and_forward_display! { } TraitPredPrintModifiersAndPath<'tcx> { - if let ty::BoundConstness::ConstIfConst = self.0.constness { - p!("~const ") - } - if let ty::ImplPolarity::Negative = self.0.polarity { p!("!") } @@ -2554,9 +2550,6 @@ define_print_and_forward_display! { ty::TraitPredicate<'tcx> { p!(print(self.trait_ref.self_ty()), ": "); - if let ty::BoundConstness::ConstIfConst = self.constness { - p!("~const "); - } p!(print(self.trait_ref.print_only_trait_path())) } @@ -2624,6 +2617,7 @@ define_print_and_forward_display! { GenericArgKind::Lifetime(lt) => p!(print(lt)), GenericArgKind::Type(ty) => p!(print(ty)), GenericArgKind::Const(ct) => p!(print(ct)), + GenericArgKind::Constness(_) => {}, } } } diff --git a/compiler/rustc_middle/src/ty/query.rs b/compiler/rustc_middle/src/ty/query.rs index 3d662ed5de4ba..5f84ef9e075ab 100644 --- a/compiler/rustc_middle/src/ty/query.rs +++ b/compiler/rustc_middle/src/ty/query.rs @@ -161,16 +161,6 @@ macro_rules! separate_provide_extern_default { }; } -macro_rules! opt_remap_env_constness { - ([][$name:ident]) => {}; - ([(remap_env_constness) $($rest:tt)*][$name:ident]) => { - let $name = $name.without_const(); - }; - ([$other:tt $($modifiers:tt)*][$name:ident]) => { - opt_remap_env_constness!([$($modifiers)*][$name]) - }; -} - macro_rules! define_callbacks { (<$tcx:tt> $($(#[$attr:meta])* @@ -217,7 +207,6 @@ macro_rules! define_callbacks { #[inline(always)] pub fn $name(self, key: query_helper_param_ty!($($K)*)) { let key = key.into_query_param(); - opt_remap_env_constness!([$($modifiers)*][key]); let cached = try_get_cached(self.tcx, &self.tcx.query_caches.$name, &key, noop); @@ -246,7 +235,6 @@ macro_rules! define_callbacks { pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> query_stored::$name<$tcx> { let key = key.into_query_param(); - opt_remap_env_constness!([$($modifiers)*][key]); let cached = try_get_cached(self.tcx, &self.tcx.query_caches.$name, &key, copy); diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index 818affa7113a1..d7afde01a96e4 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -226,6 +226,20 @@ impl<'tcx> Relate<'tcx> for ty::FnSig<'tcx> { } } +impl<'tcx> Relate<'tcx> for ty::ConstnessArg { + fn relate>( + relation: &mut R, + a: ty::ConstnessArg, + b: ty::ConstnessArg, + ) -> RelateResult<'tcx, ty::ConstnessArg> { + if a == b { + Ok(a) + } else { + Err(TypeError::ConstnessArgMismatch(expected_found(relation, a, b))) + } + } +} + impl<'tcx> Relate<'tcx> for ty::BoundConstness { fn relate>( relation: &mut R, @@ -762,6 +776,9 @@ impl<'tcx> Relate<'tcx> for GenericArg<'tcx> { (GenericArgKind::Const(a_ct), GenericArgKind::Const(b_ct)) => { Ok(relation.relate(a_ct, b_ct)?.into()) } + (GenericArgKind::Constness(a_ca), GenericArgKind::Constness(b_ca)) => { + Ok(relation.relate(a_ca, b_ca)?.into()) + } (GenericArgKind::Lifetime(unpacked), x) => { bug!("impossible case reached: can't relate: {:?} with {:?}", unpacked, x) } @@ -771,6 +788,9 @@ impl<'tcx> Relate<'tcx> for GenericArg<'tcx> { (GenericArgKind::Const(unpacked), x) => { bug!("impossible case reached: can't relate: {:?} with {:?}", unpacked, x) } + (GenericArgKind::Constness(unpacked), x) => { + bug!("impossible case reached: can't relate: {:?} with {:?}", unpacked, x) + } } } } @@ -797,7 +817,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 391a0a20c9662..e668acd0d5d93 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -132,9 +132,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) } } @@ -218,6 +215,7 @@ TrivialTypeTraversalAndLiftImpls! { crate::ty::adjustment::AutoBorrowMutability, crate::ty::AdtKind, crate::ty::BoundConstness, + crate::ty::ConstnessArg, // Including `BoundRegionKind` is a *bit* dubious, but direct // references to bound region appear in `ty::Error`, and aren't // really meant to be folded. In general, we can only fold a fully @@ -353,11 +351,8 @@ impl<'a, 'tcx> Lift<'tcx> for Term<'a> { impl<'a, 'tcx> Lift<'tcx> for ty::TraitPredicate<'a> { type Lifted = ty::TraitPredicate<'tcx>; fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option> { - tcx.lift(self.trait_ref).map(|trait_ref| ty::TraitPredicate { - trait_ref, - constness: self.constness, - polarity: self.polarity, - }) + tcx.lift(self.trait_ref) + .map(|trait_ref| ty::TraitPredicate { trait_ref, polarity: self.polarity }) } } @@ -468,7 +463,7 @@ impl<'a, 'tcx> Lift<'tcx> for ty::ParamEnv<'a> { type Lifted = ty::ParamEnv<'tcx>; fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option { tcx.lift(self.caller_bounds()) - .map(|caller_bounds| ty::ParamEnv::new(caller_bounds, self.reveal(), self.constness())) + .map(|caller_bounds| ty::ParamEnv::new(caller_bounds, self.reveal())) } } @@ -581,6 +576,7 @@ impl<'a, 'tcx> Lift<'tcx> for ty::error::TypeError<'a> { Some(match self { Mismatch => Mismatch, + ConstnessArgMismatch(x) => ConstnessArgMismatch(x), ConstnessMismatch(x) => ConstnessMismatch(x), PolarityMismatch(x) => PolarityMismatch(x), UnsafetyMismatch(x) => UnsafetyMismatch(x), diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index d663f1a3ec6e7..8345fcd0f9849 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -690,18 +690,20 @@ impl<'tcx> Binder<'tcx, ExistentialPredicate<'tcx>> { pub fn with_self_ty(&self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> ty::Predicate<'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) - } + ExistentialPredicate::Trait(tr) => self + .rebind(tr) + .with_self_ty(tcx, self_ty) + .to_poly_trait_predicate() + .to_predicate(tcx), ExistentialPredicate::Projection(p) => { self.rebind(p.with_self_ty(tcx, self_ty)).to_predicate(tcx) } ExistentialPredicate::AutoTrait(did) => { let trait_ref = self.rebind(ty::TraitRef { def_id: did, - substs: tcx.mk_substs_trait(self_ty, &[]), + substs: tcx.mk_substs_trait(self_ty, &[], ty::ConstnessArg::Not), }); - trait_ref.without_const().to_predicate(tcx) + trait_ref.to_poly_trait_predicate().to_predicate(tcx) } } } @@ -830,7 +832,6 @@ impl<'tcx> PolyTraitRef<'tcx> { pub fn to_poly_trait_predicate(&self) -> ty::PolyTraitPredicate<'tcx> { self.map_bound(|trait_ref| ty::TraitPredicate { trait_ref, - constness: ty::BoundConstness::NotConst, polarity: ty::ImplPolarity::Positive, }) } @@ -839,7 +840,6 @@ impl<'tcx> PolyTraitRef<'tcx> { pub fn to_poly_trait_predicate_negative_polarity(&self) -> ty::PolyTraitPredicate<'tcx> { self.map_bound(|trait_ref| ty::TraitPredicate { trait_ref, - constness: ty::BoundConstness::NotConst, polarity: ty::ImplPolarity::Negative, }) } @@ -881,7 +881,10 @@ impl<'tcx> ExistentialTraitRef<'tcx> { // otherwise the escaping vars would be captured by the binder // debug_assert!(!self_ty.has_escaping_bound_vars()); - ty::TraitRef { def_id: self.def_id, substs: tcx.mk_substs_trait(self_ty, self.substs) } + ty::TraitRef { + def_id: self.def_id, + substs: tcx.mk_substs_trait(self_ty, self.substs, ty::ConstnessArg::Not), + } } } @@ -1422,7 +1425,7 @@ impl<'tcx> ExistentialProjection<'tcx> { ty::ProjectionPredicate { projection_ty: ty::ProjectionTy { item_def_id: self.item_def_id, - substs: tcx.mk_substs_trait(self_ty, self.substs), + substs: tcx.mk_substs_trait(self_ty, self.substs, ty::ConstnessArg::Not), }, term: self.term, } diff --git a/compiler/rustc_middle/src/ty/subst.rs b/compiler/rustc_middle/src/ty/subst.rs index 3a524d7b0f307..8560799bd7ec7 100644 --- a/compiler/rustc_middle/src/ty/subst.rs +++ b/compiler/rustc_middle/src/ty/subst.rs @@ -34,19 +34,21 @@ use std::slice; #[derive(Copy, Clone, PartialEq, Eq, Hash)] pub struct GenericArg<'tcx> { ptr: NonZeroUsize, - marker: PhantomData<(Ty<'tcx>, ty::Region<'tcx>, ty::Const<'tcx>)>, + marker: PhantomData<(Ty<'tcx>, ty::Region<'tcx>, ty::Const<'tcx>, ty::ConstnessArg)>, } const TAG_MASK: usize = 0b11; const TYPE_TAG: usize = 0b00; const REGION_TAG: usize = 0b01; const CONST_TAG: usize = 0b10; +const CONSTNESS_TAG: usize = 0b11; #[derive(Debug, TyEncodable, TyDecodable, PartialEq, Eq, PartialOrd, Ord)] pub enum GenericArgKind<'tcx> { Lifetime(ty::Region<'tcx>), Type(Ty<'tcx>), Const(ty::Const<'tcx>), + Constness(ty::ConstnessArg), } /// This function goes from `&'a [Ty<'tcx>]` to `&'a [GenericArg<'tcx>]` @@ -93,6 +95,14 @@ impl<'tcx> GenericArgKind<'tcx> { assert_eq!(mem::align_of_val(&*ct.0.0) & TAG_MASK, 0); (CONST_TAG, ct.0.0 as *const ty::ConstS<'tcx> as usize) } + GenericArgKind::Constness(carg) => ( + CONSTNESS_TAG, + match carg { + ty::ConstnessArg::Not => 0, + ty::ConstnessArg::Required => 0b100, + ty::ConstnessArg::Param => 0b1000, + }, + ), }; GenericArg { ptr: unsafe { NonZeroUsize::new_unchecked(ptr | tag) }, marker: PhantomData } @@ -105,6 +115,7 @@ impl<'tcx> fmt::Debug for GenericArg<'tcx> { GenericArgKind::Lifetime(lt) => lt.fmt(f), GenericArgKind::Type(ty) => ty.fmt(f), GenericArgKind::Const(ct) => ct.fmt(f), + GenericArgKind::Constness(ca) => ca.fmt(f), } } } @@ -142,6 +153,13 @@ impl<'tcx> From> for GenericArg<'tcx> { } } +impl<'tcx> From for GenericArg<'tcx> { + #[inline] + fn from(c: ty::ConstnessArg) -> GenericArg<'tcx> { + GenericArgKind::Constness(c).pack() + } +} + impl<'tcx> GenericArg<'tcx> { #[inline] pub fn unpack(self) -> GenericArgKind<'tcx> { @@ -160,6 +178,12 @@ impl<'tcx> GenericArg<'tcx> { CONST_TAG => GenericArgKind::Const(ty::Const(Interned::new_unchecked( &*((ptr & !TAG_MASK) as *const ty::ConstS<'tcx>), ))), + CONSTNESS_TAG => GenericArgKind::Constness(match ptr & (!TAG_MASK) { + 0 => ty::ConstnessArg::Not, + 0b100 => ty::ConstnessArg::Required, + 0b1000 => ty::ConstnessArg::Param, + _ => intrinsics::unreachable(), + }), _ => intrinsics::unreachable(), } } @@ -192,6 +216,7 @@ impl<'a, 'tcx> Lift<'tcx> for GenericArg<'a> { GenericArgKind::Lifetime(lt) => tcx.lift(lt).map(|lt| lt.into()), GenericArgKind::Type(ty) => tcx.lift(ty).map(|ty| ty.into()), GenericArgKind::Const(ct) => tcx.lift(ct).map(|ct| ct.into()), + GenericArgKind::Constness(ca) => Some(ca.into()), } } } @@ -202,6 +227,7 @@ impl<'tcx> TypeFoldable<'tcx> for GenericArg<'tcx> { GenericArgKind::Lifetime(lt) => lt.try_fold_with(folder).map(Into::into), GenericArgKind::Type(ty) => ty.try_fold_with(folder).map(Into::into), GenericArgKind::Const(ct) => ct.try_fold_with(folder).map(Into::into), + GenericArgKind::Constness(_) => Ok(self), } } } @@ -212,6 +238,7 @@ impl<'tcx> TypeVisitable<'tcx> for GenericArg<'tcx> { GenericArgKind::Lifetime(lt) => lt.visit_with(visitor), GenericArgKind::Type(ty) => ty.visit_with(visitor), GenericArgKind::Const(ct) => ct.visit_with(visitor), + GenericArgKind::Constness(_) => ControlFlow::CONTINUE, } } } diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 4d2f69b23fa09..09d70d0b01acf 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -458,6 +458,7 @@ impl<'tcx> TyCtxt<'tcx> { // Error: not a const param _ => false, }, + GenericArgKind::Constness(_) => false, } }) .map(|(item_param, _)| item_param) @@ -501,6 +502,7 @@ impl<'tcx> TyCtxt<'tcx> { } _ => return Err(NotUniqueParam::NotParam(c.into())), }, + GenericArgKind::Constness(_) => {} } } diff --git a/compiler/rustc_middle/src/ty/walk.rs b/compiler/rustc_middle/src/ty/walk.rs index 02fe1f3a7bded..6b39e7fb51beb 100644 --- a/compiler/rustc_middle/src/ty/walk.rs +++ b/compiler/rustc_middle/src/ty/walk.rs @@ -203,5 +203,6 @@ fn push_inner<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent: GenericArg<'tcx>) } } } + GenericArgKind::Constness(_) => {} } } diff --git a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs index c0b0cc3c591b0..3833a6dde4f9e 100644 --- a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs +++ b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs @@ -616,7 +616,7 @@ where let drop_trait = tcx.require_lang_item(LangItem::Drop, None); let drop_fn = tcx.associated_item_def_ids(drop_trait)[0]; let ty = self.place_ty(self.place); - let substs = tcx.mk_substs_trait(ty, &[]); + let substs = tcx.mk_substs_trait(ty, &[], ty::ConstnessArg::Not); let ref_ty = tcx.mk_ref(tcx.lifetimes.re_erased, ty::TypeAndMut { ty, mutbl: hir::Mutability::Mut }); diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index b3ac0f4cbeaa4..39d873c3c1ea1 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -629,7 +629,7 @@ fn check_type_length_limit<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) { .flat_map(|arg| arg.walk()) .filter(|arg| match arg.unpack() { GenericArgKind::Type(_) | GenericArgKind::Const(_) => true, - GenericArgKind::Lifetime(_) => false, + GenericArgKind::Lifetime(_) | GenericArgKind::Constness(_) => false, }) .count(); debug!(" => type length={}", type_length); diff --git a/compiler/rustc_monomorphize/src/lib.rs b/compiler/rustc_monomorphize/src/lib.rs index ef4560b5ec48e..bb525ce3284bb 100644 --- a/compiler/rustc_monomorphize/src/lib.rs +++ b/compiler/rustc_monomorphize/src/lib.rs @@ -29,7 +29,7 @@ fn custom_coerce_unsize_info<'tcx>( let trait_ref = ty::Binder::dummy(ty::TraitRef { def_id, - substs: tcx.mk_substs_trait(source_ty, &[target_ty.into()]), + substs: tcx.mk_substs_trait(source_ty, &[target_ty.into()], ty::ConstnessArg::Not), }); match tcx.codegen_fulfill_obligation((ty::ParamEnv::reveal_all(), trait_ref)) { diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index 333dc5aa668b0..20e0011428f64 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -233,16 +233,6 @@ macro_rules! get_provider { }; } -macro_rules! opt_remap_env_constness { - ([][$name:ident]) => {}; - ([(remap_env_constness) $($rest:tt)*][$name:ident]) => { - let $name = $name.without_const(); - }; - ([$other:tt $($modifiers:tt)*][$name:ident]) => { - opt_remap_env_constness!([$($modifiers)*][$name]) - }; -} - macro_rules! define_queries { (<$tcx:tt> $($(#[$attr:meta])* @@ -259,7 +249,6 @@ macro_rules! define_queries { // Create an eponymous constructor for each query. $(#[allow(nonstandard_style)] $(#[$attr])* pub fn $name<$tcx>(tcx: QueryCtxt<$tcx>, key: query_keys::$name<$tcx>) -> QueryStackFrame { - opt_remap_env_constness!([$($modifiers)*][key]); let kind = dep_graph::DepKind::$name; let name = stringify!($name); // Disable visible paths printing for performance reasons. @@ -549,7 +538,6 @@ macro_rules! define_queries_struct { key: query_keys::$name<$tcx>, mode: QueryMode, ) -> Option> { - opt_remap_env_constness!([$($modifiers)*][key]); let qcx = QueryCtxt { tcx, queries: self }; get_query::, _>(qcx, span, key, mode) })* diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index 13229a3995c22..591a43378de02 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -871,6 +871,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> { self.push("K"); self = c.print(self)?; } + GenericArgKind::Constness(_) => {} } } self.push("E"); diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 74d2eb17b6b30..1760bc8070a8c 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -137,13 +137,15 @@ pub fn type_known_to_meet_bound_modulo_regions<'a, 'tcx>( infcx.tcx.def_path_str(def_id) ); - let trait_ref = - ty::Binder::dummy(ty::TraitRef { def_id, substs: infcx.tcx.mk_substs_trait(ty, &[]) }); + let trait_ref = ty::Binder::dummy(ty::TraitRef { + def_id, + substs: infcx.tcx.mk_substs_trait(ty, &[], ty::ConstnessArg::Not), + }); let obligation = Obligation { param_env, cause: ObligationCause::misc(span, hir::CRATE_HIR_ID), recursion_depth: 0, - predicate: trait_ref.without_const().to_predicate(infcx.tcx), + predicate: trait_ref.to_predicate(infcx.tcx), }; let result = infcx.predicate_must_hold_modulo_regions(&obligation); @@ -293,11 +295,8 @@ pub fn normalize_param_env_or_error<'tcx>( debug!("normalize_param_env_or_error: elaborated-predicates={:?}", predicates); - let elaborated_env = ty::ParamEnv::new( - tcx.intern_predicates(&predicates), - unnormalized_env.reveal(), - unnormalized_env.constness(), - ); + let elaborated_env = + ty::ParamEnv::new(tcx.intern_predicates(&predicates), unnormalized_env.reveal()); // HACK: we are trying to normalize the param-env inside *itself*. The problem is that // normalization expects its param-env to be already normalized, which means we have @@ -345,11 +344,8 @@ pub fn normalize_param_env_or_error<'tcx>( // predicates here anyway. Keeping them here anyway because it seems safer. let outlives_env: Vec<_> = non_outlives_predicates.iter().chain(&outlives_predicates).cloned().collect(); - let outlives_env = ty::ParamEnv::new( - tcx.intern_predicates(&outlives_env), - unnormalized_env.reveal(), - unnormalized_env.constness(), - ); + let outlives_env = + ty::ParamEnv::new(tcx.intern_predicates(&outlives_env), unnormalized_env.reveal()); let Ok(outlives_predicates) = do_normalize_predicates( tcx, cause, @@ -365,11 +361,7 @@ pub fn normalize_param_env_or_error<'tcx>( let mut predicates = non_outlives_predicates; predicates.extend(outlives_predicates); debug!("normalize_param_env_or_error: final predicates={:?}", predicates); - ty::ParamEnv::new( - tcx.intern_predicates(&predicates), - unnormalized_env.reveal(), - unnormalized_env.constness(), - ) + ty::ParamEnv::new(tcx.intern_predicates(&predicates), unnormalized_env.reveal()) } pub fn fully_normalize<'a, 'tcx, T>( @@ -528,7 +520,7 @@ fn prepare_vtable_segments<'tcx, T>( let mut emit_vptr_on_new_entry = false; let mut visited = util::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, None)]; visited.insert(predicate); @@ -810,16 +802,12 @@ pub fn vtable_trait_upcasting_coercion_new_vptr_slot<'tcx>( let trait_ref = ty::TraitRef { def_id: unsize_trait_did, - substs: tcx.mk_substs_trait(source, &[target.into()]), + substs: tcx.mk_substs_trait(source, &[target.into()], ty::ConstnessArg::Not), }; let obligation = Obligation::new( ObligationCause::dummy(), ty::ParamEnv::reveal_all(), - ty::Binder::dummy(ty::TraitPredicate { - trait_ref, - constness: ty::BoundConstness::NotConst, - polarity: ty::ImplPolarity::Positive, - }), + ty::Binder::dummy(ty::TraitPredicate { trait_ref, polarity: ty::ImplPolarity::Positive }), ); let implsrc = tcx.infer_ctxt().enter(|infcx| { diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index ac1811244ca5e..0370a158b683e 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -706,11 +706,7 @@ fn receiver_is_dispatchable<'tcx>( let caller_bounds: Vec> = param_env.caller_bounds().iter().chain([unsize_predicate, trait_predicate]).collect(); - ty::ParamEnv::new( - tcx.intern_predicates(&caller_bounds), - param_env.reveal(), - param_env.constness(), - ) + ty::ParamEnv::new(tcx.intern_predicates(&caller_bounds), param_env.reveal()) }; // Receiver: DispatchFromDyn U]> 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 db45ee3fed7db..6511942da4010 100644 --- a/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs +++ b/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs @@ -67,20 +67,10 @@ impl<'cx, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'cx, 'tcx> { ) -> Result { let mut _orig_values = OriginalQueryValues::default(); - let param_env = match obligation.predicate.kind().skip_binder() { - ty::PredicateKind::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 c_pred = self - .canonicalize_query_keep_static(param_env.and(obligation.predicate), &mut _orig_values); + let c_pred = self.canonicalize_query_keep_static( + obligation.param_env.and(obligation.predicate), + &mut _orig_values, + ); // Run canonical query. If overflow occurs, rerun from scratch but this time // in standard trait query mode so that overflow is handled appropriately // within `SelectionContext`. diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 4862631980e36..1816f5c9ef970 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -43,7 +43,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { candidate: SelectionCandidate<'tcx>, ) -> Result, SelectionError<'tcx>> { let mut obligation = obligation; - let new_obligation; + // let new_obligation; // HACK(const_trait_impl): the surrounding environment is remapped to a non-const context // because nested obligations might be actually `~const` then (incorrectly) requiring @@ -62,14 +62,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // CheckPredicate(&A: Super) // CheckPredicate(A: ~const Super) // <- still const env, failure // ``` - if obligation.param_env.is_const() && !obligation.predicate.is_const_if_const() { + /*if obligation.param_env.is_const() && !obligation.predicate.constness().is_const() { new_obligation = TraitObligation { cause: obligation.cause.clone(), - param_env: obligation.param_env.without_const(), + param_env: obligation.param_env, ..*obligation }; obligation = &new_obligation; - } + }*/ match candidate { BuiltinCandidate { has_nested } => { @@ -80,7 +80,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ParamCandidate(param) => { let obligations = self.confirm_param_candidate(obligation, param.map_bound(|t| t.trait_ref)); - Ok(ImplSource::Param(obligations, param.skip_binder().constness)) + Ok(ImplSource::Param(obligations, param.skip_binder().constness())) } ImplCandidate(impl_def_id) => { @@ -95,7 +95,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ProjectionCandidate(idx) => { let obligations = self.confirm_projection_candidate(obligation, idx)?; // FIXME(jschievink): constness - Ok(ImplSource::Param(obligations, ty::BoundConstness::NotConst)) + Ok(ImplSource::Param(obligations, ty::ConstnessArg::Not)) } ObjectCandidate(idx) => { @@ -133,7 +133,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // This indicates something like `Trait + Send: Send`. In this case, we know that // this holds because that's what the object type is telling us, and there's really // no additional obligations to prove and no types in particular to unify, etc. - Ok(ImplSource::Param(Vec::new(), ty::BoundConstness::NotConst)) + Ok(ImplSource::Param(Vec::new(), ty::ConstnessArg::Not)) } BuiltinUnsizeCandidate => { diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 2bb53a466caa4..0321123c141a5 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -785,13 +785,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(self.tcx(), &mut param_env); - pred - }); + let fresh_trait_pred = stack.fresh_trait_pred; + let param_env = obligation.param_env; debug!(?fresh_trait_pred); @@ -1196,12 +1191,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { for candidate in candidates { // Respect const trait obligations - if obligation.is_const() { + if obligation.predicate.constness().is_const() { 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() => {} + ParamCandidate(trait_pred) if trait_pred.constness().is_const() => {} // auto trait impl AutoImplCandidate(..) => {} // generator, this will raise error in other places @@ -1309,7 +1304,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 @@ -1320,8 +1315,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(tcx, &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) { @@ -1367,15 +1361,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(tcx, &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"); diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 1d345caf69971..2c473c51faed0 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -134,78 +134,8 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> { let local_did = def_id.as_local(); let hir_id = local_did.map(|def_id| tcx.hir().local_def_id_to_hir_id(def_id)); - let constness = match hir_id { - Some(hir_id) => match tcx.hir().get(hir_id) { - hir::Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Fn(..), .. }) - if tcx.is_const_default_method(def_id) => - { - hir::Constness::Const - } - - hir::Node::Item(hir::Item { kind: hir::ItemKind::Const(..), .. }) - | hir::Node::Item(hir::Item { kind: hir::ItemKind::Static(..), .. }) - | hir::Node::TraitItem(hir::TraitItem { - kind: hir::TraitItemKind::Const(..), .. - }) - | hir::Node::AnonConst(_) - | hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Const(..), .. }) - | hir::Node::ImplItem(hir::ImplItem { - kind: - hir::ImplItemKind::Fn( - hir::FnSig { - header: hir::FnHeader { constness: hir::Constness::Const, .. }, - .. - }, - .., - ), - .. - }) => hir::Constness::Const, - - hir::Node::ImplItem(hir::ImplItem { - kind: hir::ImplItemKind::TyAlias(..) | hir::ImplItemKind::Fn(..), - .. - }) => { - let parent_hir_id = tcx.hir().get_parent_node(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", - ), - } - } - - hir::Node::Item(hir::Item { - kind: - hir::ItemKind::Fn(hir::FnSig { header: hir::FnHeader { constness, .. }, .. }, ..), - .. - }) - | hir::Node::TraitItem(hir::TraitItem { - kind: - hir::TraitItemKind::Fn( - hir::FnSig { header: hir::FnHeader { constness, .. }, .. }, - .., - ), - .. - }) - | hir::Node::Item(hir::Item { - kind: hir::ItemKind::Impl(hir::Impl { constness, .. }), - .. - }) => *constness, - - _ => hir::Constness::NotConst, - }, - None => hir::Constness::NotConst, - }; - - let unnormalized_env = ty::ParamEnv::new( - tcx.intern_predicates(&predicates), - traits::Reveal::UserFacing, - constness, - ); + let unnormalized_env = + ty::ParamEnv::new(tcx.intern_predicates(&predicates), traits::Reveal::UserFacing); let body_id = hir_id.map_or(hir::CRATE_HIR_ID, |id| { tcx.hir().maybe_body_owned_by(id).map_or(id, |body| body.hir_id) diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 9795be1a912ad..91a94b2220ea6 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -1519,6 +1519,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics { params, param_def_id_to_index, has_self: generics.has_self, + has_constness: false, has_late_bound_regions: generics.has_late_bound_regions, }; } From 1933ba7c18615d398cf1d4657c9af7385b1617db Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Wed, 13 Apr 2022 14:20:25 +1000 Subject: [PATCH 02/51] Add GenericArgDefKind::Constness and tweak generics_of --- compiler/rustc_infer/src/infer/mod.rs | 1 + compiler/rustc_infer/src/traits/engine.rs | 4 +- compiler/rustc_infer/src/traits/util.rs | 5 +-- compiler/rustc_middle/src/ty/context.rs | 22 ++++++++++- compiler/rustc_middle/src/ty/generics.rs | 17 +++++++-- compiler/rustc_middle/src/ty/instance.rs | 1 + compiler/rustc_middle/src/ty/mod.rs | 12 +++--- compiler/rustc_middle/src/ty/print/pretty.rs | 2 + compiler/rustc_middle/src/ty/sty.rs | 37 +++++++++++++++---- compiler/rustc_monomorphize/src/collector.rs | 1 + .../rustc_trait_selection/src/autoderef.rs | 4 +- compiler/rustc_trait_selection/src/infer.rs | 8 ++-- .../src/traits/auto_trait.rs | 13 ++----- .../src/traits/error_reporting/mod.rs | 28 +++++++------- .../src/traits/error_reporting/suggestions.rs | 7 ++-- .../rustc_trait_selection/src/traits/mod.rs | 3 +- .../src/traits/object_safety.rs | 8 ++-- .../src/traits/project.rs | 6 +-- .../traits/query/type_op/prove_predicate.rs | 8 +--- .../src/traits/relationships.rs | 3 +- .../src/traits/select/candidate_assembly.rs | 6 +-- .../src/traits/select/confirmation.rs | 23 ++++++++---- .../src/traits/select/mod.rs | 4 +- .../src/traits/specialize/mod.rs | 4 +- .../rustc_trait_selection/src/traits/util.rs | 24 +++++++----- .../rustc_trait_selection/src/traits/wf.rs | 11 ++++-- compiler/rustc_traits/src/chalk/lowering.rs | 6 +-- compiler/rustc_ty_utils/src/ty.rs | 5 ++- .../rustc_typeck/src/check/compare_method.rs | 6 +-- compiler/rustc_typeck/src/collect.rs | 16 +++++++- 30 files changed, 182 insertions(+), 113 deletions(-) diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index fc4a01f2cac54..e65700ee27409 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -1199,6 +1199,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { }); self.tcx.mk_const_var(const_var_id, self.tcx.type_of(param.def_id)).into() } + GenericParamDefKind::Constness => ty::ConstnessArg::Param.into(), } } diff --git a/compiler/rustc_infer/src/traits/engine.rs b/compiler/rustc_infer/src/traits/engine.rs index 00ef13f57eb31..034f790c86af1 100644 --- a/compiler/rustc_infer/src/traits/engine.rs +++ b/compiler/rustc_infer/src/traits/engine.rs @@ -37,9 +37,7 @@ pub trait TraitEngine<'tcx>: 'tcx { cause, recursion_depth: 0, param_env, - predicate: ty::Binder::dummy(trait_ref) - .to_poly_trait_predicate() - .to_predicate(infcx.tcx), + predicate: ty::Binder::dummy(trait_ref).to_predicate(infcx.tcx), }, ); } diff --git a/compiler/rustc_infer/src/traits/util.rs b/compiler/rustc_infer/src/traits/util.rs index 39dc456f79376..985517e9575dd 100644 --- a/compiler/rustc_infer/src/traits/util.rs +++ b/compiler/rustc_infer/src/traits/util.rs @@ -75,10 +75,7 @@ pub fn elaborate_trait_ref<'tcx>( tcx: TyCtxt<'tcx>, trait_ref: ty::PolyTraitRef<'tcx>, ) -> Elaborator<'tcx> { - elaborate_predicates( - tcx, - std::iter::once(trait_ref.to_poly_trait_predicate().to_predicate(tcx)), - ) + elaborate_predicates(tcx, std::iter::once(trait_ref.to_predicate(tcx))) } pub fn elaborate_trait_refs<'tcx>( diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 346ef72c44e06..fbe61a6c9258f 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2438,7 +2438,9 @@ impl<'tcx> TyCtxt<'tcx> { let adt_def = self.adt_def(wrapper_def_id); let substs = InternalSubsts::for_item(self, wrapper_def_id, |param, substs| match param.kind { - GenericParamDefKind::Lifetime | GenericParamDefKind::Const { .. } => bug!(), + GenericParamDefKind::Lifetime + | GenericParamDefKind::Const { .. } + | GenericParamDefKind::Constness => bug!(), GenericParamDefKind::Type { has_default, .. } => { if param.index == 0 { ty_param.into() @@ -2627,6 +2629,7 @@ impl<'tcx> TyCtxt<'tcx> { GenericParamDefKind::Const { .. } => { self.mk_const_param(param.index, param.name, self.type_of(param.def_id)).into() } + GenericParamDefKind::Constness => ty::ConstnessArg::Param.into(), } } @@ -2800,6 +2803,23 @@ impl<'tcx> TyCtxt<'tcx> { iter.intern_with(|xs| self.intern_place_elems(xs)) } + pub fn mk_substs_trait_no_append( + self, + self_ty: Ty<'tcx>, + rest: &[GenericArg<'tcx>], + ) -> SubstsRef<'tcx> { + assert!(matches!(rest.last().unwrap().unpack(), GenericArgKind::Constness(_))); + self.mk_substs(iter::once(self_ty.into()).chain(rest.iter().cloned())) + } + + pub fn mk_substs_trait_non_const( + self, + self_ty: Ty<'tcx>, + rest: &[GenericArg<'tcx>], + ) -> SubstsRef<'tcx> { + self.mk_substs_trait(self_ty, rest, ty::ConstnessArg::Not) + } + pub fn mk_substs_trait( self, self_ty: Ty<'tcx>, diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs index ffe956d325492..2026505189393 100644 --- a/compiler/rustc_middle/src/ty/generics.rs +++ b/compiler/rustc_middle/src/ty/generics.rs @@ -15,6 +15,7 @@ pub enum GenericParamDefKind { Lifetime, Type { has_default: bool, object_lifetime_default: ObjectLifetimeDefault, synthetic: bool }, Const { has_default: bool }, + Constness, } impl GenericParamDefKind { @@ -23,6 +24,7 @@ impl GenericParamDefKind { GenericParamDefKind::Lifetime => "lifetime", GenericParamDefKind::Type { .. } => "type", GenericParamDefKind::Const { .. } => "constant", + GenericParamDefKind::Constness => "constness", } } pub fn to_ord(&self) -> ast::ParamKindOrd { @@ -30,12 +32,13 @@ impl GenericParamDefKind { GenericParamDefKind::Lifetime => ast::ParamKindOrd::Lifetime, GenericParamDefKind::Type { .. } => ast::ParamKindOrd::Type, GenericParamDefKind::Const { .. } => ast::ParamKindOrd::Const, + GenericParamDefKind::Constness => ast::ParamKindOrd::Infer, } } pub fn is_ty_or_const(&self) -> bool { match self { - GenericParamDefKind::Lifetime => false, + GenericParamDefKind::Lifetime | GenericParamDefKind::Constness => false, GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. } => true, } } @@ -100,6 +103,7 @@ pub struct GenericParamCount { pub lifetimes: usize, pub types: usize, pub consts: usize, + pub has_constness: bool, } /// Information about the formal type/lifetime parameters associated @@ -118,7 +122,6 @@ pub struct Generics { pub param_def_id_to_index: FxHashMap, pub has_self: bool, - pub has_constness: bool, pub has_late_bound_regions: Option, } @@ -139,6 +142,12 @@ impl<'tcx> Generics { GenericParamDefKind::Lifetime => own_counts.lifetimes += 1, GenericParamDefKind::Type { .. } => own_counts.types += 1, GenericParamDefKind::Const { .. } => own_counts.consts += 1, + GenericParamDefKind::Constness => { + if own_counts.has_constness { + bug!("more than one constness parameter"); + } + own_counts.has_constness = true; + } } } @@ -150,7 +159,7 @@ impl<'tcx> Generics { for param in &self.params { match param.kind { - GenericParamDefKind::Lifetime => (), + GenericParamDefKind::Lifetime | GenericParamDefKind::Constness => (), GenericParamDefKind::Type { has_default, .. } => { own_defaults.types += has_default as usize; } @@ -182,7 +191,7 @@ impl<'tcx> Generics { GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. } => { return true; } - GenericParamDefKind::Lifetime => {} + GenericParamDefKind::Lifetime | GenericParamDefKind::Constness => {} } } false diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index be4f2b7f4f0e7..cc635c18ccbfa 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -323,6 +323,7 @@ impl<'tcx> Instance<'tcx> { ty::GenericParamDefKind::Const { .. } => { bug!("Instance::mono: {:?} has const parameters", def_id) } + ty::GenericParamDefKind::Constness => ty::ConstnessArg::Not.into(), }); Instance::new(def_id, substs) diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index e5a6cbc574bb7..120811f6dfee2 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -831,11 +831,7 @@ impl<'tcx> TraitPredicate<'tcx> { } pub fn constness(self) -> ty::ConstnessArg { - // TODO remove panic - match self.trait_ref.substs.last().expect("constness").unpack() { - ty::subst::GenericArgKind::Constness(constness) => constness, - _ => panic!("?"), - } + self.trait_ref.constness() } } @@ -996,6 +992,12 @@ impl<'tcx> ToPredicate<'tcx> for Binder<'tcx, PredicateKind<'tcx>> { } } +impl<'tcx> ToPredicate<'tcx> for PolyTraitRef<'tcx> { + fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { + self.to_poly_trait_predicate().to_predicate(tcx) + } +} + impl<'tcx> ToPredicate<'tcx> for PolyTraitPredicate<'tcx> { fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { self.map_bound(PredicateKind::Trait).to_predicate(tcx) diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index e0f9af1ccb92b..d1fe922ac77b9 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -2381,6 +2381,8 @@ macro_rules! define_print_and_forward_display { }; } +// TODO fix printing + /// Wrapper type for `ty::TraitRef` which opts-in to pretty printing only /// the trait path. That is, it will print `Trait` instead of /// `>`. diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 8345fcd0f9849..2262e6083c855 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -690,20 +690,18 @@ impl<'tcx> Binder<'tcx, ExistentialPredicate<'tcx>> { pub fn with_self_ty(&self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> ty::Predicate<'tcx> { use crate::ty::ToPredicate; match self.skip_binder() { - ExistentialPredicate::Trait(tr) => self - .rebind(tr) - .with_self_ty(tcx, self_ty) - .to_poly_trait_predicate() - .to_predicate(tcx), + ExistentialPredicate::Trait(tr) => { + 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) } ExistentialPredicate::AutoTrait(did) => { let trait_ref = self.rebind(ty::TraitRef { def_id: did, - substs: tcx.mk_substs_trait(self_ty, &[], ty::ConstnessArg::Not), + substs: tcx.mk_substs_trait_non_const(self_ty, &[]), }); - trait_ref.to_poly_trait_predicate().to_predicate(tcx) + trait_ref.to_predicate(tcx) } } } @@ -816,6 +814,27 @@ impl<'tcx> TraitRef<'tcx> { let defs = tcx.generics_of(trait_id); ty::TraitRef { def_id: trait_id, substs: tcx.intern_substs(&substs[..defs.params.len()]) } } + + pub fn constness(self) -> ty::ConstnessArg { + // TODO remove panic + match self.substs.last().expect("constness").unpack() { + ty::subst::GenericArgKind::Constness(constness) => constness, + _ => panic!("?"), + } + } + + pub fn without_const(mut self, tcx: TyCtxt<'tcx>) -> Self { + if self.constness().is_const() { + self.substs = tcx.mk_substs( + self.substs + .iter() + .take(self.substs.len() - 1) + .chain(Some(ty::ConstnessArg::Not.into())), + ); + } + + self + } } pub type PolyTraitRef<'tcx> = Binder<'tcx, TraitRef<'tcx>>; @@ -843,6 +862,10 @@ impl<'tcx> PolyTraitRef<'tcx> { polarity: ty::ImplPolarity::Negative, }) } + + pub fn without_const(self, tcx: TyCtxt<'tcx>) -> Self { + self.map_bound(|tr| tr.without_const(tcx)) + } } /// An existential reference to a trait, where `Self` is erased. diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 39d873c3c1ea1..a7dc821b879d1 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -1382,6 +1382,7 @@ fn create_mono_items_for_default_impls<'tcx>( let substs = InternalSubsts::for_item(tcx, method.def_id, |param, _| match param.kind { GenericParamDefKind::Lifetime => tcx.lifetimes.re_erased.into(), + GenericParamDefKind::Constness => ty::ConstnessArg::Not.into(), GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. } => { trait_ref.substs[param.index as usize] diff --git a/compiler/rustc_trait_selection/src/autoderef.rs b/compiler/rustc_trait_selection/src/autoderef.rs index 8b7e8984a8adb..4ff47301ef1f5 100644 --- a/compiler/rustc_trait_selection/src/autoderef.rs +++ b/compiler/rustc_trait_selection/src/autoderef.rs @@ -127,7 +127,7 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> { // let trait_ref = TraitRef { def_id: tcx.lang_items().deref_trait()?, - substs: tcx.mk_substs_trait(ty, &[]), + substs: tcx.mk_substs_trait_non_const(ty, &[]), }; let cause = traits::ObligationCause::misc(self.span, self.body_id); @@ -135,7 +135,7 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> { let obligation = traits::Obligation::new( cause.clone(), self.param_env, - ty::Binder::dummy(trait_ref).without_const().to_predicate(tcx), + ty::Binder::dummy(trait_ref).to_predicate(tcx), ); if !self.infcx.predicate_may_hold(&obligation) { debug!("overloaded_deref_ty: cannot match obligation"); diff --git a/compiler/rustc_trait_selection/src/infer.rs b/compiler/rustc_trait_selection/src/infer.rs index 9d30374f8b8ae..7c3e138eca732 100644 --- a/compiler/rustc_trait_selection/src/infer.rs +++ b/compiler/rustc_trait_selection/src/infer.rs @@ -108,14 +108,16 @@ impl<'cx, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'cx, 'tcx> { trait_def_id, ty, params, param_env ); - let trait_ref = - ty::TraitRef { def_id: trait_def_id, substs: self.tcx.mk_substs_trait(ty, params) }; + let trait_ref = ty::TraitRef { + def_id: trait_def_id, + substs: self.tcx.mk_substs_trait_non_const(ty, params), + }; let obligation = traits::Obligation { 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/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index 65ff9ceb67ecb..6d5516eb8856d 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -85,7 +85,8 @@ impl<'tcx> AutoTraitFinder<'tcx> { ) -> AutoTraitResult { let tcx = self.tcx; - let trait_ref = ty::TraitRef { def_id: trait_did, substs: tcx.mk_substs_trait(ty, &[]) }; + let trait_ref = + ty::TraitRef { def_id: trait_did, substs: tcx.mk_substs_trait_non_const(ty, &[]) }; let trait_pred = ty::Binder::dummy(trait_ref); @@ -297,9 +298,8 @@ impl<'tcx> AutoTraitFinder<'tcx> { predicates.push_back(ty::Binder::dummy(ty::TraitPredicate { trait_ref: ty::TraitRef { def_id: trait_did, - substs: infcx.tcx.mk_substs_trait(ty, &[]), + substs: infcx.tcx.mk_substs_trait_non_const(ty, &[]), }, - constness: ty::BoundConstness::NotConst, // Auto traits are positive polarity: ty::ImplPolarity::Positive, })); @@ -382,17 +382,12 @@ impl<'tcx> AutoTraitFinder<'tcx> { computed_preds.clone().chain(user_computed_preds.iter().cloned()), ) .map(|o| o.predicate); - new_env = ty::ParamEnv::new( - tcx.mk_predicates(normalized_preds), - param_env.reveal(), - param_env.constness(), - ); + new_env = ty::ParamEnv::new(tcx.mk_predicates(normalized_preds), param_env.reveal()); } let final_user_env = ty::ParamEnv::new( tcx.mk_predicates(user_computed_preds.into_iter()), user_env.reveal(), - user_env.constness(), ); debug!( "evaluate_nested_obligations(ty={:?}, trait_did={:?}): succeeded with '{:?}' \ 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 8d7c6b26ba152..767788adcdf03 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -116,7 +116,7 @@ pub trait InferCtxtExt<'tcx> { &self, param_env: ty::ParamEnv<'tcx>, ty: ty::Binder<'tcx, Ty<'tcx>>, - constness: ty::BoundConstness, + constness: ty::ConstnessArg, polarity: ty::ImplPolarity, ) -> Result<(ty::ClosureKind, ty::Binder<'tcx, Ty<'tcx>>), ()>; } @@ -327,9 +327,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, '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 = + ty::ConstnessArg::Required == trait_predicate.skip_binder().constness(); if self.tcx.sess.has_errors().is_some() && trait_predicate.references_error() @@ -490,11 +489,11 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { self.suggest_borrowing_for_object_cast(&mut err, &root_obligation, *concrete_ty, *obj_ty); } - if trait_predicate.is_const_if_const() && obligation.param_env.is_const() { - let non_const_predicate = trait_ref.without_const(); + if trait_predicate.constness().is_const() { + let non_const_predicate = trait_ref.without_const(self.tcx); let non_const_obligation = Obligation { cause: obligation.cause.clone(), - param_env: obligation.param_env.without_const(), + param_env: obligation.param_env, predicate: non_const_predicate.to_predicate(tcx), recursion_depth: obligation.recursion_depth, }; @@ -504,7 +503,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { &format!( "the trait `{}` is implemented for `{}`, \ but that implementation is not `const`", - non_const_predicate.print_modifiers_and_trait_path(), + non_const_predicate.print_only_trait_path(), trait_ref.skip_binder().self_ty(), ), ); @@ -599,7 +598,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { && let Ok((implemented_kind, params)) = self.type_implements_fn_trait( obligation.param_env, trait_ref.self_ty(), - trait_predicate.skip_binder().constness, + trait_predicate.skip_binder().constness(), trait_predicate.skip_binder().polarity, ) { @@ -729,7 +728,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { && fallback_has_occurred { let predicate = trait_predicate.map_bound(|mut trait_pred| { - trait_pred.trait_ref.substs = self.tcx.mk_substs_trait( + trait_pred.trait_ref.substs = self.tcx.mk_substs_trait_no_append( self.tcx.mk_unit(), &trait_pred.trait_ref.substs[1..], ); @@ -1276,7 +1275,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { &self, param_env: ty::ParamEnv<'tcx>, ty: ty::Binder<'tcx, Ty<'tcx>>, - constness: ty::BoundConstness, + constness: ty::ConstnessArg, polarity: ty::ImplPolarity, ) -> Result<(ty::ClosureKind, ty::Binder<'tcx, Ty<'tcx>>), ()> { self.commit_if_ok(|_| { @@ -1292,13 +1291,12 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { span: DUMMY_SP, kind: TypeVariableOriginKind::MiscVariable, }); - let substs = self.tcx.mk_substs_trait(ty.skip_binder(), &[var.into()]); + let substs = self.tcx.mk_substs_trait(ty.skip_binder(), &[var.into()], constness); let obligation = Obligation::new( ObligationCause::dummy(), param_env, ty.rebind(ty::TraitPredicate { trait_ref: ty::TraitRef::new(trait_def_id, substs), - constness, polarity, }) .to_predicate(self.tcx), @@ -1935,7 +1933,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> { ) -> PredicateObligation<'tcx> { let trait_pred = trait_ref_and_ty.map_bound_ref(|(tr, new_self_ty)| ty::TraitPredicate { trait_ref: ty::TraitRef { - substs: self.tcx.mk_substs_trait(*new_self_ty, &tr.trait_ref.substs[1..]), + substs: self.tcx.mk_substs_trait_no_append(*new_self_ty, &tr.trait_ref.substs[1..]), ..tr.trait_ref }, ..*tr @@ -2351,7 +2349,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> { let obligation = Obligation::new( ObligationCause::dummy(), param_env, - cleaned_pred.without_const().to_predicate(selcx.tcx()), + cleaned_pred.to_predicate(selcx.tcx()), ); self.predicate_may_hold(&obligation) 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 b08fc48218602..efbb6cf56f5a7 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -2501,7 +2501,6 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, '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 msg = format!( "required because of the requirements on the impl of `{}` for `{}`", @@ -2785,7 +2784,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { self.tcx.mk_projection( item_def_id, // Future::Output has no substs - self.tcx.mk_substs_trait(trait_pred.self_ty(), &[]), + self.tcx.mk_substs_trait(trait_pred.self_ty(), &[], ty::ConstnessArg::Not), ) }); let projection_ty = normalize_to( @@ -2874,9 +2873,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { let field_ty = field.ty(self.tcx, substs); let trait_substs = match diagnostic_name { sym::PartialEq | sym::PartialOrd => { - self.tcx.mk_substs_trait(field_ty, &[field_ty.into()]) + self.tcx.mk_substs_trait_non_const(field_ty, &[field_ty.into()]) } - _ => self.tcx.mk_substs_trait(field_ty, &[]), + _ => self.tcx.mk_substs_trait_non_const(field_ty, &[]), }; let trait_pred = trait_pred.map_bound_ref(|tr| ty::TraitPredicate { trait_ref: ty::TraitRef { diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 1760bc8070a8c..00be2c3a69c68 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -688,7 +688,8 @@ fn vtable_entries<'tcx>( InternalSubsts::for_item(tcx, def_id, |param, _| match param.kind { GenericParamDefKind::Lifetime => tcx.lifetimes.re_erased.into(), GenericParamDefKind::Type { .. } - | GenericParamDefKind::Const { .. } => { + | GenericParamDefKind::Const { .. } + | GenericParamDefKind::Constness => { trait_ref.substs[param.index as usize] } }) diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index 0370a158b683e..5fdfb9833d980 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -682,9 +682,8 @@ fn receiver_is_dispatchable<'tcx>( // Self: Unsize let unsize_predicate = ty::Binder::dummy(ty::TraitRef { def_id: unsize_did, - substs: tcx.mk_substs_trait(tcx.types.self_param, &[unsized_self_ty.into()]), + substs: tcx.mk_substs_trait_non_const(tcx.types.self_param, &[unsized_self_ty.into()]), }) - .without_const() .to_predicate(tcx); // U: Trait @@ -699,7 +698,7 @@ fn receiver_is_dispatchable<'tcx>( }); ty::Binder::dummy(ty::TraitRef { def_id: unsize_did, substs }) - .without_const() + .without_const(tcx) .to_predicate(tcx) }; @@ -713,9 +712,8 @@ fn receiver_is_dispatchable<'tcx>( let obligation = { let predicate = ty::Binder::dummy(ty::TraitRef { def_id: dispatch_from_dyn_did, - substs: tcx.mk_substs_trait(receiver_ty, &[unsized_receiver_ty.into()]), + substs: tcx.mk_substs_trait_non_const(receiver_ty, &[unsized_receiver_ty.into()]), }) - .without_const() .to_predicate(tcx); Obligation::new(ObligationCause::dummy(), param_env, predicate) diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index b3e7fbb357828..cf1a7cb7b10ee 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -1136,7 +1136,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 def_id = projection_ty.item_def_id; @@ -1808,9 +1808,9 @@ fn confirm_pointee_candidate<'cx, 'tcx>( if check_is_sized { let sized_predicate = ty::Binder::dummy(ty::TraitRef::new( tcx.require_lang_item(LangItem::Sized, None), - tcx.mk_substs_trait(self_ty, &[]), + tcx.mk_substs_trait_non_const(self_ty, &[]), )) - .without_const() + .to_poly_trait_predicate() .to_predicate(tcx); obligations.push(Obligation::new( obligation.cause.clone(), diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs index 081308ac73e05..02e9b4d0f0e72 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs @@ -30,14 +30,8 @@ impl<'tcx> super::QueryTypeOp<'tcx> for ProvePredicate<'tcx> { fn perform_query( tcx: TyCtxt<'tcx>, - mut canonicalized: Canonicalized<'tcx, ParamEnvAnd<'tcx, Self>>, + canonicalized: Canonicalized<'tcx, ParamEnvAnd<'tcx, Self>>, ) -> Fallible> { - match canonicalized.value.value.predicate.kind().skip_binder() { - ty::PredicateKind::Trait(pred) => { - canonicalized.value.param_env.remap_constness_with(pred.constness); - } - _ => canonicalized.value.param_env = canonicalized.value.param_env.without_const(), - } tcx.type_op_prove_predicate(canonicalized) } } diff --git a/compiler/rustc_trait_selection/src/traits/relationships.rs b/compiler/rustc_trait_selection/src/traits/relationships.rs index 56bdeafeecae4..99853e0d98102 100644 --- a/compiler/rustc_trait_selection/src/traits/relationships.rs +++ b/compiler/rustc_trait_selection/src/traits/relationships.rs @@ -19,7 +19,7 @@ pub(crate) fn update<'tcx, T>( let new_self_ty = infcx.tcx.types.unit; let trait_ref = ty::TraitRef { - substs: infcx.tcx.mk_substs_trait(new_self_ty, &tpred.trait_ref.substs[1..]), + substs: infcx.tcx.mk_substs_trait_no_append(new_self_ty, &tpred.trait_ref.substs[1..]), ..tpred.trait_ref }; @@ -35,7 +35,6 @@ pub(crate) fn update<'tcx, T>( // (*) binder moved here ty::PredicateKind::Trait(ty::TraitPredicate { trait_ref, - constness: tpred.constness, polarity: tpred.polarity, }) }) 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 96d83deeeb7ab..1a309221deb4d 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -752,13 +752,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // let trait_ref = ty::TraitRef { def_id: tcx.lang_items().deref_trait()?, - substs: tcx.mk_substs_trait(ty, &[]), + substs: tcx.mk_substs_trait_non_const(ty, &[]), }; let obligation = traits::Obligation::new( cause.clone(), param_env, - ty::Binder::dummy(trait_ref).without_const().to_predicate(tcx), + ty::Binder::dummy(trait_ref).to_predicate(tcx), ); if !self.infcx.predicate_may_hold(&obligation) { return None; @@ -957,7 +957,7 @@ 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() { + if !obligation.predicate.constness().is_const() { 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 1816f5c9ef970..75729cc8c84f0 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -958,9 +958,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // We can only make objects from sized types. let tr = ty::Binder::dummy(ty::TraitRef::new( tcx.require_lang_item(LangItem::Sized, None), - tcx.mk_substs_trait(source, &[]), + tcx.mk_substs_trait_non_const(source, &[]), )); - nested.push(predicate_to_obligation(tr.without_const().to_predicate(tcx))); + nested.push(predicate_to_obligation(tr.to_predicate(tcx))); // If the type is `Foo + 'a`, ensure that the type // being cast to `Foo + 'a` outlives `'a`: @@ -993,6 +993,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ty::ConstKind::Param(p) => Some(p.index), _ => None, }, + + // TODO confirm that this is correct + GenericArgKind::Constness(_) => None, }; // FIXME(eddyb) cache this (including computing `unsizing_params`) @@ -1098,7 +1101,7 @@ 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() { + if !obligation.predicate.constness().is_const() { return Ok(ImplSourceConstDestructData { nested: vec![] }); } @@ -1202,9 +1205,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { def_id: self .tcx() .require_lang_item(LangItem::Destruct, None), - substs: self.tcx().mk_substs_trait(nested_ty, &[]), + substs: self.tcx().mk_substs_trait( + nested_ty, + &[], + ty::ConstnessArg::Required, + ), }, - constness: ty::BoundConstness::ConstIfConst, polarity: ty::ImplPolarity::Positive, }) .to_predicate(tcx), @@ -1228,9 +1234,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { .rebind(ty::TraitPredicate { trait_ref: ty::TraitRef { def_id: self.tcx().require_lang_item(LangItem::Destruct, None), - substs: self.tcx().mk_substs_trait(nested_ty, &[]), + substs: self.tcx().mk_substs_trait( + nested_ty, + &[], + ty::ConstnessArg::Required, + ), }, - constness: ty::BoundConstness::ConstIfConst, polarity: ty::ImplPolarity::Positive, }) .to_predicate(tcx); diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 0321123c141a5..1d68c1a6f940b 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1641,7 +1641,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, '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().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 { @@ -1652,7 +1652,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // best to *not* create essentially duplicate candidates in the first place. 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 + && victim.skip_binder().constness() == ty::ConstnessArg::Not && other.skip_binder().polarity == victim.skip_binder().polarity { // Drop otherwise equivalent non-const candidates in favor of const candidates. diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs index 2c4a453aefc34..e167650df109c 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs @@ -514,6 +514,8 @@ pub(crate) fn to_pretty_impl_header(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Opti continue; } + // TODO FIX this + /* if ty::BoundConstness::ConstIfConst == poly_trait_ref.skip_binder().constness { let new_trait_pred = poly_trait_ref.map_bound(|mut trait_pred| { trait_pred.constness = ty::BoundConstness::NotConst; @@ -521,7 +523,7 @@ pub(crate) fn to_pretty_impl_header(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Opti }); p = tcx.mk_predicate(new_trait_pred.map_bound(ty::PredicateKind::Trait)) - } + }*/ } 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 3170b29ee6973..6c3efa35fb0bb 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -98,7 +98,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); @@ -110,9 +110,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.without_const().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; } @@ -251,7 +255,7 @@ pub fn predicate_for_trait_ref<'tcx>( cause, param_env, recursion_depth, - predicate: ty::Binder::dummy(trait_ref).without_const().to_predicate(tcx), + predicate: ty::Binder::dummy(trait_ref).to_predicate(tcx), } } @@ -264,8 +268,10 @@ pub fn predicate_for_trait_def<'tcx>( self_ty: Ty<'tcx>, params: &[GenericArg<'tcx>], ) -> PredicateObligation<'tcx> { - let trait_ref = - ty::TraitRef { def_id: trait_def_id, substs: tcx.mk_substs_trait(self_ty, params) }; + let trait_ref = ty::TraitRef { + def_id: trait_def_id, + substs: tcx.mk_substs_trait(self_ty, params, ty::ConstnessArg::Not), + }; predicate_for_trait_ref(tcx, cause, param_env, trait_ref, recursion_depth) } @@ -338,7 +344,7 @@ pub fn closure_trait_ref_and_return_type<'tcx>( debug_assert!(!self_ty.has_escaping_bound_vars()); let trait_ref = ty::TraitRef { def_id: fn_trait_def_id, - substs: tcx.mk_substs_trait(self_ty, &[arguments_tuple.into()]), + substs: tcx.mk_substs_trait_non_const(self_ty, &[arguments_tuple.into()]), }; sig.map_bound(|sig| (trait_ref, sig.output())) } @@ -352,7 +358,7 @@ pub fn generator_trait_ref_and_outputs<'tcx>( debug_assert!(!self_ty.has_escaping_bound_vars()); let trait_ref = ty::TraitRef { def_id: fn_trait_def_id, - substs: tcx.mk_substs_trait(self_ty, &[sig.skip_binder().resume_ty.into()]), + substs: tcx.mk_substs_trait_non_const(self_ty, &[sig.skip_binder().resume_ty.into()]), }; sig.map_bound(|sig| (trait_ref, sig.yield_ty, sig.return_ty)) } diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 7b5e1498f2695..8804e7ce9bf61 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -56,8 +56,8 @@ pub fn obligations<'a, 'tcx>( } .into() } - // There is nothing we have to do for lifetimes. - GenericArgKind::Lifetime(..) => return Some(Vec::new()), + // There is nothing we have to do for lifetimes and constness arguments. + GenericArgKind::Lifetime(..) | GenericArgKind::Constness(_) => return Some(Vec::new()), }; let mut wf = @@ -411,13 +411,13 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { let cause = self.cause(cause); let trait_ref = ty::TraitRef { def_id: self.infcx.tcx.require_lang_item(LangItem::Sized, None), - substs: self.infcx.tcx.mk_substs_trait(subty, &[]), + substs: self.infcx.tcx.mk_substs_trait_non_const(subty, &[]), }; self.out.push(traits::Obligation::with_depth( cause, self.recursion_depth, self.param_env, - ty::Binder::dummy(trait_ref).without_const().to_predicate(self.infcx.tcx), + ty::Binder::dummy(trait_ref).to_predicate(self.infcx.tcx), )); } } @@ -435,6 +435,9 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { // obligations are handled by the parent (e.g. `ty::Ref`). GenericArgKind::Lifetime(_) => continue, + // No WF for constness argument + GenericArgKind::Constness(_) => continue, + GenericArgKind::Const(constant) => { match constant.kind() { ty::ConstKind::Unevaluated(uv) => { diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs index c7c604e14e3ee..0c01d4973a018 100644 --- a/compiler/rustc_traits/src/chalk/lowering.rs +++ b/compiler/rustc_traits/src/chalk/lowering.rs @@ -670,7 +670,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Binders LowerInto<'tcx, chalk_ir::Binders LowerInto<'tcx, chalk_ir::Binders( let Some(sized_trait) = tcx.lang_items().sized_trait() else { return vec![ty] }; let sized_predicate = ty::Binder::dummy(ty::TraitRef { def_id: sized_trait, - substs: tcx.mk_substs_trait(ty, &[]), + substs: tcx.mk_substs_trait_non_const(ty, &[]), }) - .without_const() .to_predicate(tcx); let predicates = tcx.predicates_of(adtdef.did()).predicates; if predicates.iter().any(|(p, _)| *p == sized_predicate) { vec![] } else { vec![ty] } @@ -253,6 +252,8 @@ fn well_formed_types_in_env<'tcx>( // FIXME(eddyb) support const generics in Chalk GenericArgKind::Const(_) => None, + + GenericArgKind::Constness(_) => None, } }); diff --git a/compiler/rustc_typeck/src/check/compare_method.rs b/compiler/rustc_typeck/src/check/compare_method.rs index 2bfb9343877a4..7c604b5c8cb1d 100644 --- a/compiler/rustc_typeck/src/check/compare_method.rs +++ b/compiler/rustc_typeck/src/check/compare_method.rs @@ -1423,11 +1423,7 @@ pub fn check_type_bounds<'tcx>( .to_predicate(tcx), ), }; - ty::ParamEnv::new( - tcx.intern_predicates(&predicates), - Reveal::UserFacing, - param_env.constness(), - ) + ty::ParamEnv::new(tcx.intern_predicates(&predicates), Reveal::UserFacing) }; debug!(?normalize_param_env); diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 91a94b2220ea6..82628d185dc47 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -1519,7 +1519,6 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics { params, param_def_id_to_index, has_self: generics.has_self, - has_constness: false, has_late_bound_regions: generics.has_late_bound_regions, }; } @@ -1632,7 +1631,10 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics { assert!(!has_self); parent_has_self = generics.has_self; own_start = generics.count() as u32; - generics.parent_count + generics.params.len() + // if parent has constness param, we do not inherit it from the parent, and we + // get it in the end instead of the middle. + let parent_constness = parent_has_self as u32; + generics.parent_count + generics.params.len() - parent_constness }); let mut params: Vec<_> = Vec::with_capacity(ast_generics.params.len() + has_self as usize); @@ -1758,6 +1760,16 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics { } } + if has_self || parent_has_self { + params.push(ty::GenericParamDef { + name: Symbol::intern(""), + index: type_start + i, + def_id, + pure_wrt_drop: false, + kind: ty::GenericParamDefKind::Constness, + }); + } + let param_def_id_to_index = params.iter().map(|param| (param.def_id, param.index)).collect(); ty::Generics { From 0f0f9171b13dcda6ce5ecccd31b1195f8432f269 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 31 May 2022 10:25:13 +0000 Subject: [PATCH 03/51] Small fixups --- compiler/rustc_middle/src/mir/interpret/queries.rs | 2 -- compiler/rustc_resolve/src/late/lifetimes.rs | 1 + compiler/rustc_trait_selection/src/traits/project.rs | 4 ++-- .../src/traits/query/evaluate_obligation.rs | 2 -- 4 files changed, 3 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs index e7148d20f9b77..8f6be48e563a7 100644 --- a/compiler/rustc_middle/src/mir/interpret/queries.rs +++ b/compiler/rustc_middle/src/mir/interpret/queries.rs @@ -121,8 +121,6 @@ impl<'tcx> TyCtxt<'tcx> { cid: GlobalId<'tcx>, span: Option, ) -> EvalToValTreeResult<'tcx> { - let param_env = param_env.with_const(); - debug!(?param_env); // Const-eval shouldn't depend on lifetimes at all, so we can erase them, which should // improve caching of queries. let inputs = self.erase_regions(param_env.and(cid)); diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs index 557dbecfabe09..8a23812181dfe 100644 --- a/compiler/rustc_resolve/src/late/lifetimes.rs +++ b/compiler/rustc_resolve/src/late/lifetimes.rs @@ -1894,6 +1894,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { Some(object_lifetime_default) } GenericParamDefKind::Const { .. } => Some(Set1::Empty), + GenericParamDefKind::Constness => None, GenericParamDefKind::Lifetime => None, }) .collect() diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index cf1a7cb7b10ee..e6e157feb0dfc 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -1563,9 +1563,9 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( &obligation.with( ty::Binder::dummy(ty::TraitRef::new( selcx.tcx().require_lang_item(LangItem::Sized, None), - selcx.tcx().mk_substs_trait(self_ty, &[]), + selcx.tcx().mk_substs_trait(self_ty, &[], ty::ConstnessArg::Not), )) - .without_const() + .without_const(selcx.tcx()) .to_predicate(selcx.tcx()), ), ) => 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 6511942da4010..e3150e8e1aabd 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,3 @@ -use rustc_middle::ty; - use crate::infer::canonical::OriginalQueryValues; use crate::infer::InferCtxt; use crate::traits::{ From 7014e402126650546869b8dad2ab79670d079314 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Fri, 15 Apr 2022 23:24:49 +1000 Subject: [PATCH 04/51] Update rustc_{infer,resolve,typeck,trait_selection} --- compiler/rustc_resolve/src/late/lifetimes.rs | 5 +++-- .../src/traits/error_reporting/on_unimplemented.rs | 2 +- .../src/traits/on_unimplemented.rs | 2 +- compiler/rustc_trait_selection/src/traits/project.rs | 3 +-- .../src/traits/select/confirmation.rs | 1 + compiler/rustc_typeck/src/check/closure.rs | 2 +- compiler/rustc_typeck/src/check/wfcheck.rs | 10 +++------- compiler/rustc_typeck/src/collect.rs | 9 ++++----- .../src/impl_wf_check/min_specialization.rs | 6 ++---- 9 files changed, 17 insertions(+), 23 deletions(-) diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs index 8a23812181dfe..259d5361affb8 100644 --- a/compiler/rustc_resolve/src/late/lifetimes.rs +++ b/compiler/rustc_resolve/src/late/lifetimes.rs @@ -1894,8 +1894,9 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { Some(object_lifetime_default) } GenericParamDefKind::Const { .. } => Some(Set1::Empty), - GenericParamDefKind::Constness => None, - GenericParamDefKind::Lifetime => None, + GenericParamDefKind::Lifetime | GenericParamDefKind::Constness => { + None + } }) .collect() }) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs index 7c9ee64a0c2b0..78bd643d9653b 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs @@ -180,7 +180,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. } => { substs[param.index as usize].to_string() } - GenericParamDefKind::Lifetime => continue, + GenericParamDefKind::Lifetime | GenericParamDefKind::Constness => continue, }; let name = param.name; flags.push((name, Some(value))); diff --git a/compiler/rustc_trait_selection/src/traits/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/on_unimplemented.rs index ed7d16f7a5419..0b0066636a365 100644 --- a/compiler/rustc_trait_selection/src/traits/on_unimplemented.rs +++ b/compiler/rustc_trait_selection/src/traits/on_unimplemented.rs @@ -371,7 +371,7 @@ impl<'tcx> OnUnimplementedFormatString { GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. } => { trait_ref.substs[param.index as usize].to_string() } - GenericParamDefKind::Lifetime => return None, + GenericParamDefKind::Lifetime | GenericParamDefKind::Constness => return None, }; let name = param.name; Some((name, value)) diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index e6e157feb0dfc..5daffd6898d59 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -1563,9 +1563,8 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( &obligation.with( ty::Binder::dummy(ty::TraitRef::new( selcx.tcx().require_lang_item(LangItem::Sized, None), - selcx.tcx().mk_substs_trait(self_ty, &[], ty::ConstnessArg::Not), + selcx.tcx().mk_substs_trait_non_const(self_ty, &[]), )) - .without_const(selcx.tcx()) .to_predicate(selcx.tcx()), ), ) => diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 75729cc8c84f0..40836bb5d54e6 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -549,6 +549,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { }) .into() } + GenericParamDefKind::Constness => ty::ConstnessArg::Not.into(), }); let bound_vars = tcx.mk_bound_variable_kinds(bound_vars.into_iter()); let assoc_ty_substs = tcx.intern_substs(&substs); diff --git a/compiler/rustc_typeck/src/check/closure.rs b/compiler/rustc_typeck/src/check/closure.rs index 1681e6af81239..1e7f0b8cc61cd 100644 --- a/compiler/rustc_typeck/src/check/closure.rs +++ b/compiler/rustc_typeck/src/check/closure.rs @@ -81,7 +81,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let generator_types = check_fn( self, - self.param_env.without_const(), + self.param_env, liberated_sig, decl, expr.hir_id, diff --git a/compiler/rustc_typeck/src/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs index 5621cf2e1a4b5..0e1cd1c3cb022 100644 --- a/compiler/rustc_typeck/src/check/wfcheck.rs +++ b/compiler/rustc_typeck/src/check/wfcheck.rs @@ -486,7 +486,7 @@ fn augment_param_env<'tcx>( tcx.mk_predicates(param_env.caller_bounds().iter().chain(new_predicates.iter().cloned())); // FIXME(compiler-errors): Perhaps there is a case where we need to normalize this // i.e. traits::normalize_param_env_or_error - ty::ParamEnv::new(bounds, param_env.reveal(), param_env.constness()) + ty::ParamEnv::new(bounds, param_env.reveal()) } /// We use the following trait as an example throughout this function. @@ -1698,14 +1698,10 @@ fn receiver_is_implemented<'tcx>( ) -> bool { let trait_ref = ty::Binder::dummy(ty::TraitRef { def_id: receiver_trait_def_id, - substs: fcx.tcx.mk_substs_trait(receiver_ty, &[]), + substs: fcx.tcx.mk_substs_trait(receiver_ty, &[], ty::ConstnessArg::Not), }); - let obligation = traits::Obligation::new( - cause, - fcx.param_env, - trait_ref.without_const().to_predicate(fcx.tcx), - ); + let obligation = traits::Obligation::new(cause, fcx.param_env, trait_ref.to_predicate(fcx.tcx)); if fcx.predicate_must_hold_modulo_regions(&obligation) { true diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 82628d185dc47..8ec887ab45362 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -607,8 +607,7 @@ fn type_param_predicates( // Implied `Self: Trait` and supertrait bounds. if param_id == item_hir_id { let identity_trait_ref = ty::TraitRef::identity(tcx, item_def_id); - extend = - Some((identity_trait_ref.without_const().to_predicate(tcx), item.span)); + extend = Some((identity_trait_ref.to_predicate(tcx), item.span)); } generics } @@ -1634,7 +1633,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics { // if parent has constness param, we do not inherit it from the parent, and we // get it in the end instead of the middle. let parent_constness = parent_has_self as u32; - generics.parent_count + generics.params.len() - parent_constness + generics.parent_count as u32 + generics.params.len() as u32 - parent_constness }); let mut params: Vec<_> = Vec::with_capacity(ast_generics.params.len() + has_self as usize); @@ -2099,7 +2098,7 @@ fn predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicates<'_> { 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).without_const().to_predicate(tcx), + ty::TraitRef::identity(tcx, def_id).to_predicate(tcx), span, )))); } @@ -2218,7 +2217,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP // (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 diff --git a/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs b/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs index c46b825f4578d..d2d2e2a1961f6 100644 --- a/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs +++ b/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs @@ -371,9 +371,8 @@ fn check_specialization_on<'tcx>(tcx: TyCtxt<'tcx>, predicate: ty::Predicate<'tc // items. ty::PredicateKind::Trait(ty::TraitPredicate { trait_ref, - constness: ty::BoundConstness::NotConst, polarity: _, - }) => { + }) if !trait_ref.constness().is_const() => { // TODO fix this if !matches!( trait_predicate_kind(tcx, predicate), Some(TraitSpecializationKind::Marker) @@ -411,8 +410,7 @@ fn trait_predicate_kind<'tcx>( ) -> Option { match predicate.kind().skip_binder() { ty::PredicateKind::Trait(ty::TraitPredicate { - trait_ref, - constness: ty::BoundConstness::NotConst, + trait_ref, // TODO review specialization check polarity: _, }) => Some(tcx.trait_def(trait_ref.def_id).specialization_kind), ty::PredicateKind::Trait(_) From 1bafdc277e038c212f8ef13bffc8d723b921b03d Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Sat, 7 May 2022 23:31:33 +1000 Subject: [PATCH 05/51] Fix more trivial errors --- .../src/const_eval/eval_queries.rs | 2 -- .../src/interpret/eval_context.rs | 1 - .../src/transform/check_consts/check.rs | 5 ++- .../src/transform/check_consts/ops.rs | 3 +- .../src/transform/check_consts/qualifs.rs | 5 ++- compiler/rustc_middle/src/ty/mod.rs | 5 +++ compiler/rustc_middle/src/ty/sty.rs | 13 +++++++ compiler/rustc_traits/src/chalk/db.rs | 3 ++ compiler/rustc_typeck/src/astconv/generics.rs | 3 ++ compiler/rustc_typeck/src/astconv/mod.rs | 35 ++++++++++++------- compiler/rustc_typeck/src/bounds.rs | 15 ++++---- compiler/rustc_typeck/src/check/_match.rs | 3 +- compiler/rustc_typeck/src/check/cast.rs | 2 +- .../rustc_typeck/src/check/compare_method.rs | 14 +++----- compiler/rustc_typeck/src/check/dropck.rs | 3 +- compiler/rustc_typeck/src/check/expr.rs | 2 +- .../rustc_typeck/src/check/fn_ctxt/_impl.rs | 1 + .../src/check/fn_ctxt/suggestions.rs | 3 +- .../rustc_typeck/src/check/method/confirm.rs | 1 + compiler/rustc_typeck/src/check/method/mod.rs | 4 +-- .../rustc_typeck/src/check/method/probe.rs | 3 +- .../rustc_typeck/src/check/method/suggest.rs | 3 +- compiler/rustc_typeck/src/check/upvar.rs | 6 ++-- compiler/rustc_typeck/src/collect.rs | 6 ++-- compiler/rustc_typeck/src/lib.rs | 2 +- 25 files changed, 81 insertions(+), 62 deletions(-) diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs index b18976302b4ff..fc74f66c48c8f 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -226,7 +226,6 @@ pub fn eval_to_const_value_raw_provider<'tcx>( tcx: TyCtxt<'tcx>, key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>, ) -> ::rustc_middle::mir::interpret::EvalToConstValueResult<'tcx> { - assert!(key.param_env.is_const()); // see comment in eval_to_allocation_raw_provider for what we're doing here if key.param_env.reveal() == Reveal::All { let mut key = key; @@ -261,7 +260,6 @@ pub fn eval_to_allocation_raw_provider<'tcx>( tcx: TyCtxt<'tcx>, key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>, ) -> ::rustc_middle::mir::interpret::EvalToAllocationRawResult<'tcx> { - assert!(key.param_env.is_const()); // Because the constant is computed twice (once per value of `Reveal`), we are at risk of // reporting the same error twice here. To resolve this, we check whether we can evaluate the // constant in the more restrictive `Reveal::UserFacing`, which most likely already was diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index 2e47cf8921073..8854da8b2df66 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -924,7 +924,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } else { self.param_env }; - let param_env = param_env.with_const(); // Use a precise span for better cycle errors. let val = self.tcx.at(self.cur_span()).eval_to_allocation_raw(param_env.and(gid))?; self.raw_const_to_mplace(val) 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 39fabd17c5271..d940c63fa14de 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -720,10 +720,9 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { return; } - let trait_ref = TraitRef::from_method(tcx, trait_id, substs); + let trait_ref = TraitRef::from_method(tcx, trait_id, substs).with_const(tcx); let poly_trait_pred = Binder::dummy(TraitPredicate { trait_ref, - constness: ty::BoundConstness::ConstIfConst, polarity: ty::ImplPolarity::Positive, }); let obligation = @@ -735,7 +734,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { }); match implsrc { - Ok(Some(ImplSource::Param(_, ty::BoundConstness::ConstIfConst))) => { + Ok(Some(ImplSource::Param(_, ty::ConstnessArg::Required))) => { debug!( "const_trait_impl: provided {:?} via where-clause in {:?}", trait_ref, param_env diff --git a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs index 1d083b0bf8268..29ac0a76b398e 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs @@ -149,8 +149,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> { ObligationCause::dummy(), param_env, Binder::dummy(TraitPredicate { - trait_ref, - constness: BoundConstness::NotConst, + trait_ref: trait_ref.without_const(), polarity: ImplPolarity::Positive, }), ); 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 29464cf8c4e4f..1a6f34f5bd26b 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs @@ -161,9 +161,8 @@ impl Qualif for NeedsNonConstDrop { ty::Binder::dummy(ty::TraitPredicate { trait_ref: ty::TraitRef { def_id: destruct, - substs: cx.tcx.mk_substs_trait(ty, &[]), + substs: cx.tcx.mk_substs_trait(ty, &[], ty::ConstnessArg::Required), }, - constness: ty::BoundConstness::ConstIfConst, polarity: ty::ImplPolarity::Positive, }), ); @@ -178,7 +177,7 @@ impl Qualif for NeedsNonConstDrop { if !matches!( impl_src, ImplSource::ConstDestruct(_) - | ImplSource::Param(_, ty::BoundConstness::ConstIfConst) + | ImplSource::Param(_, ty::ConstnessArg::Requried) ) { // If our const destruct candidate is not ConstDestruct or implied by the param env, // then it's bad diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 120811f6dfee2..80ea92e8766ba 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -833,6 +833,11 @@ impl<'tcx> TraitPredicate<'tcx> { pub fn constness(self) -> ty::ConstnessArg { self.trait_ref.constness() } + + pub fn without_const(mut self, tcx: TyCtxt<'tcx>) -> Self { + self.trait_ref = self.trait_ref.without_const(tcx); + self + } } impl<'tcx> PolyTraitPredicate<'tcx> { diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 2262e6083c855..1fe480d8d8493 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -835,6 +835,19 @@ impl<'tcx> TraitRef<'tcx> { self } + + pub fn with_const(mut self, tcx: TyCtxt<'tcx>) -> Self { + if !self.constness().is_const() { + self.substs = tcx.mk_substs( + self.substs + .iter() + .take(self.substs.len() - 1) + .chain(Some(ty::ConstnessArg::Required.into())), + ); + } + + self + } } pub type PolyTraitRef<'tcx> = Binder<'tcx, TraitRef<'tcx>>; diff --git a/compiler/rustc_traits/src/chalk/db.rs b/compiler/rustc_traits/src/chalk/db.rs index 497819ce5c567..7b87d0f2374b0 100644 --- a/compiler/rustc_traits/src/chalk/db.rs +++ b/compiler/rustc_traits/src/chalk/db.rs @@ -740,6 +740,9 @@ fn bound_vars_for_item<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> SubstsRef<'tcx ty: tcx.type_of(param.def_id), }) .into(), + ty::GenericParamDefKind::Constness => { + ty::GenericArg::Param.into() // TODO Confirm + } }) } diff --git a/compiler/rustc_typeck/src/astconv/generics.rs b/compiler/rustc_typeck/src/astconv/generics.rs index 612dc38452188..4eece40b1203f 100644 --- a/compiler/rustc_typeck/src/astconv/generics.rs +++ b/compiler/rustc_typeck/src/astconv/generics.rs @@ -189,6 +189,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { self_ty: Option>, arg_count: &GenericArgCountResult, ctx: &mut impl CreateSubstsForGenericArgsCtxt<'a, 'tcx>, + constness: Option, ) -> SubstsRef<'tcx> { // Collect the segments of the path; we need to substitute arguments // for parameters throughout the entire path (wherever there are @@ -383,6 +384,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } } + substs.extend(constness.map(Into::into)); + tcx.intern_substs(&substs) } diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index 1d4e64b6bfc30..1aa43a4475a08 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -282,6 +282,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { item_segment.args(), item_segment.infer_args, None, + None, ); let assoc_bindings = self.create_assoc_bindings_for_generic_args(item_segment.args()); @@ -333,6 +334,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { generic_args: &'a hir::GenericArgs<'_>, infer_args: bool, self_ty: Option>, + constness: Option, ) -> (SubstsRef<'tcx>, GenericArgCountResult) { // If the type is parameterized by this region, then replace this // region with the current anon region binding (in other words, @@ -372,7 +374,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // here and so associated type bindings will be handled regardless of whether there are any // non-`Self` generic parameters. if generics.params.is_empty() { - return (tcx.intern_substs(&[]), arg_count); + return ( + tcx.intern_substs(&constness.map(Into::into).into_iter().collect::>()), + arg_count, + ); } let is_object = self_ty.map_or(false, |ty| ty == self.tcx().types.trait_object_dummy_self); @@ -584,6 +589,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { self_ty, &arg_count, &mut substs_ctx, + constness, ); self.complain_about_missing_type_params( @@ -671,6 +677,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { item_segment.args(), item_segment.infer_args, None, + None, ) .0 } @@ -703,7 +710,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { hir_id: hir::HirId, span: Span, binding_span: Option, - constness: ty::BoundConstness, + constness: ty::ConstnessArg, bounds: &mut Bounds<'tcx>, speculative: bool, trait_ref_span: Span, @@ -721,6 +728,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { args, infer_args, Some(self_ty), + Some(constness), ); let tcx = self.tcx(); @@ -733,7 +741,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { ty::Binder::bind_with_vars(ty::TraitRef::new(trait_def_id, substs), bound_vars); debug!(?poly_trait_ref, ?assoc_bindings); - bounds.trait_bounds.push((poly_trait_ref, span, constness)); + bounds.trait_bounds.push((poly_trait_ref, span)); let mut dup_bindings = FxHashMap::default(); for binding in &assoc_bindings { @@ -777,7 +785,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { &self, trait_ref: &hir::TraitRef<'_>, span: Span, - constness: ty::BoundConstness, + constness: ty::ConstnessArg, self_ty: Ty<'tcx>, bounds: &mut Bounds<'tcx>, speculative: bool, @@ -819,7 +827,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { bounds: &mut Bounds<'tcx>, ) { let binding_span = Some(span); - let constness = ty::BoundConstness::NotConst; + let constness = ty::ConstnessArg::Not; let speculative = false; let trait_ref_span = span; let trait_def_id = self.tcx().require_lang_item(lang_item, Some(span)); @@ -883,6 +891,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { trait_segment.args(), trait_segment.infer_args, Some(self_ty), + Some(ty::ConstnessArg::Not), ) } @@ -990,8 +999,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { match ast_bound { hir::GenericBound::Trait(poly_trait_ref, modifier) => { let constness = match modifier { - hir::TraitBoundModifier::MaybeConst => ty::BoundConstness::ConstIfConst, - hir::TraitBoundModifier::None => ty::BoundConstness::NotConst, + hir::TraitBoundModifier::MaybeConst => ty::ConstnessArg::Param, + hir::TraitBoundModifier::None => ty::ConstnessArg::Not, hir::TraitBoundModifier::Maybe => continue, }; @@ -1327,7 +1336,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } = self.instantiate_poly_trait_ref( &trait_bound.trait_ref, trait_bound.span, - ty::BoundConstness::NotConst, + ty::ConstnessArg::Not, dummy_self, &mut bounds, false, @@ -1338,8 +1347,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, bounds.trait_bounds.iter().map(|&(a, b, _)| (a, b))); + let expanded_traits = traits::expand_trait_aliases(tcx, bounds.trait_bounds.iter()); let (mut auto_traits, regular_traits): (Vec<_>, Vec<_>) = expanded_traits .filter(|i| i.trait_ref().self_ty().skip_binder() == dummy_self) .partition(|i| tcx.trait_is_auto(i.trait_ref().def_id())); @@ -1410,10 +1418,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let regular_traits_refs_spans = bounds .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 { + assert_eq!(base_trait_ref.skip_binder().constness(), ty::ConstnessArg::Not); for obligation in traits::elaborate_trait_ref(tcx, base_trait_ref) { debug!( @@ -2656,6 +2664,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { &GenericArgs::none(), true, None, + None, ); EarlyBinder(self.normalize_ty(span, tcx.at(span).type_of(def_id))) .subst(tcx, substs) diff --git a/compiler/rustc_typeck/src/bounds.rs b/compiler/rustc_typeck/src/bounds.rs index 6a28bb16a20ac..d7aac484de9a7 100644 --- a/compiler/rustc_typeck/src/bounds.rs +++ b/compiler/rustc_typeck/src/bounds.rs @@ -29,7 +29,7 @@ pub struct Bounds<'tcx> { /// A list of trait bounds. So if you had `T: Debug` this would be /// `T: Debug`. Note that the self-type is explicit here. - pub trait_bounds: Vec<(ty::PolyTraitRef<'tcx>, Span, ty::BoundConstness)>, + pub trait_bounds: Vec<(ty::PolyTraitRef<'tcx>, Span)>, /// A list of projection equality bounds. So if you had `T: /// Iterator` this would include ` Bounds<'tcx> { tcx.lang_items().sized_trait().map(move |sized| { let trait_ref = ty::Binder::dummy(ty::TraitRef { def_id: sized, - substs: tcx.mk_substs_trait(param_ty, &[]), + substs: tcx.mk_substs_trait_non_const(param_ty, &[]), }); - (trait_ref.without_const().to_predicate(tcx), span) + (trait_ref.to_predicate(tcx), span) }) }); @@ -75,11 +75,10 @@ impl<'tcx> Bounds<'tcx> { .to_predicate(tcx); (pred, span) }); - let trait_bounds = - self.trait_bounds.iter().map(move |&(bound_trait_ref, span, constness)| { - let predicate = bound_trait_ref.with_constness(constness).to_predicate(tcx); - (predicate, span) - }); + let trait_bounds = self.trait_bounds.iter().map(move |&(bound_trait_ref, span)| { + let predicate = bound_trait_ref.to_predicate(tcx); + (predicate, span) + }); let projection_bounds = self .projection_bounds .iter() diff --git a/compiler/rustc_typeck/src/check/_match.rs b/compiler/rustc_typeck/src/check/_match.rs index 79e402b542a60..c615b4bab8d22 100644 --- a/compiler/rustc_typeck/src/check/_match.rs +++ b/compiler/rustc_typeck/src/check/_match.rs @@ -521,9 +521,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty::Binder::dummy(ty::PredicateKind::Trait(ty::TraitPredicate { trait_ref: ty::TraitRef { def_id: t.def_id(), - substs: self.infcx.tcx.mk_substs_trait(outer_ty, &[]), + substs: self.infcx.tcx.mk_substs_trait(outer_ty, &[], t.constness()), }, - constness: t.constness, polarity: t.polarity, })); let obl = Obligation::new( diff --git a/compiler/rustc_typeck/src/check/cast.rs b/compiler/rustc_typeck/src/check/cast.rs index 66dd558249052..dfb3effe20df2 100644 --- a/compiler/rustc_typeck/src/check/cast.rs +++ b/compiler/rustc_typeck/src/check/cast.rs @@ -495,7 +495,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { let ty = fcx.tcx.erase_regions(ty); let expr_ty = fcx.resolve_vars_if_possible(self.expr_ty); let expr_ty = fcx.tcx.erase_regions(expr_ty); - let ty_params = fcx.tcx.mk_substs_trait(expr_ty, &[]); + let ty_params = fcx.tcx.mk_substs_trait(expr_ty, &[], ty::ConstnessArg::Not); if fcx .infcx .type_implements_trait(from_trait, ty, ty_params, fcx.param_env) diff --git a/compiler/rustc_typeck/src/check/compare_method.rs b/compiler/rustc_typeck/src/check/compare_method.rs index 7c604b5c8cb1d..ec85fe55c4a2d 100644 --- a/compiler/rustc_typeck/src/check/compare_method.rs +++ b/compiler/rustc_typeck/src/check/compare_method.rs @@ -205,11 +205,8 @@ fn compare_predicate_entailment<'tcx>( // The key step here is to update the caller_bounds's predicates to be // the new hybrid bounds we computed. let normalize_cause = traits::ObligationCause::misc(impl_m_span, impl_m_hir_id); - let param_env = ty::ParamEnv::new( - tcx.intern_predicates(&hybrid_preds.predicates), - Reveal::UserFacing, - hir::Constness::NotConst, - ); + let param_env = + ty::ParamEnv::new(tcx.intern_predicates(&hybrid_preds.predicates), Reveal::UserFacing); let param_env = traits::normalize_param_env_or_error(tcx, param_env, normalize_cause); tcx.infer_ctxt().enter(|infcx| { @@ -1239,11 +1236,8 @@ fn compare_type_predicate_entailment<'tcx>( debug!("compare_type_predicate_entailment: bounds={:?}", hybrid_preds); let normalize_cause = traits::ObligationCause::misc(impl_ty_span, impl_ty_hir_id); - let param_env = ty::ParamEnv::new( - tcx.intern_predicates(&hybrid_preds.predicates), - Reveal::UserFacing, - hir::Constness::NotConst, - ); + let param_env = + ty::ParamEnv::new(tcx.intern_predicates(&hybrid_preds.predicates), Reveal::UserFacing); let param_env = traits::normalize_param_env_or_error(tcx, param_env, normalize_cause.clone()); tcx.infer_ctxt().enter(|infcx| { let inh = Inherited::new(infcx, impl_ty.def_id.expect_local()); diff --git a/compiler/rustc_typeck/src/check/dropck.rs b/compiler/rustc_typeck/src/check/dropck.rs index 72095c408075c..5381e309adb24 100644 --- a/compiler/rustc_typeck/src/check/dropck.rs +++ b/compiler/rustc_typeck/src/check/dropck.rs @@ -186,8 +186,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>( // onto one that ignores the constness. This is equivalent to saying that // we match a `Trait` bound on the struct with a `Trait` or `~const Trait` // in the impl. - let non_const_a = - ty::TraitPredicate { constness: ty::BoundConstness::NotConst, ..a }; + let non_const_a = a.without_const(tcx); relator.relate(predicate.rebind(non_const_a), p.rebind(b)).is_ok() } (ty::PredicateKind::Projection(a), ty::PredicateKind::Projection(b)) => { diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs index 30b76b922c77a..d07995535b3a3 100644 --- a/compiler/rustc_typeck/src/check/expr.rs +++ b/compiler/rustc_typeck/src/check/expr.rs @@ -1312,7 +1312,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let body = self.tcx.hir().body(anon_const.body); // Create a new function context. - let fcx = FnCtxt::new(self, self.param_env.with_const(), body.value.hir_id); + let fcx = FnCtxt::new(self, self.param_env, body.value.hir_id); crate::check::GatherLocalsVisitor::new(&fcx).visit_body(body); let ty = fcx.check_expr_with_expectation(&body.value, expected); diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs index d15d40bc24756..c3d2b12c2ec9c 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs @@ -1452,6 +1452,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { infer_args_for_err: &infer_args_for_err, segments, }, + None, ) }); assert!(!substs.has_escaping_bound_vars()); diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs index 863a981134f24..765be5bf243b3 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs @@ -851,9 +851,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { recursion_depth: 0, predicate: ty::Binder::dummy(ty::TraitRef { def_id: clone_trait_did, - substs: self.tcx.mk_substs([expected_ty.into()].iter()), + substs: self.tcx.mk_substs_trait_non_const(expected_ty.into(), &[]), }) - .without_const() .to_predicate(self.tcx), }) { diff --git a/compiler/rustc_typeck/src/check/method/confirm.rs b/compiler/rustc_typeck/src/check/method/confirm.rs index b14f3d6de4ef1..f2ebea68956c3 100644 --- a/compiler/rustc_typeck/src/check/method/confirm.rs +++ b/compiler/rustc_typeck/src/check/method/confirm.rs @@ -409,6 +409,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { None, &arg_count_correct, &mut MethodSubstsCtxt { cfcx: self, pick, seg }, + None, ) } diff --git a/compiler/rustc_typeck/src/check/method/mod.rs b/compiler/rustc_typeck/src/check/method/mod.rs index c0b3a23fde437..6821d85d600c3 100644 --- a/compiler/rustc_typeck/src/check/method/mod.rs +++ b/compiler/rustc_typeck/src/check/method/mod.rs @@ -305,7 +305,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { span, self.body_id, self.param_env, - poly_trait_ref.without_const().to_predicate(self.tcx), + poly_trait_ref.to_predicate(self.tcx), ), substs, ) @@ -351,7 +351,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }, ), self.param_env, - poly_trait_ref.without_const().to_predicate(self.tcx), + poly_trait_ref.to_predicate(self.tcx), ), substs, ) diff --git a/compiler/rustc_typeck/src/check/method/probe.rs b/compiler/rustc_typeck/src/check/method/probe.rs index 2de225303560c..0964f876d79f6 100644 --- a/compiler/rustc_typeck/src/check/method/probe.rs +++ b/compiler/rustc_typeck/src/check/method/probe.rs @@ -1546,8 +1546,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } } } - let predicate = - ty::Binder::dummy(trait_ref).without_const().to_predicate(self.tcx); + let predicate = ty::Binder::dummy(trait_ref).to_predicate(self.tcx); parent_pred = Some(predicate); let obligation = traits::Obligation::new(cause, self.param_env, predicate); if !self.predicate_may_hold(&obligation) { diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs index 7bf167426f748..88acf77a1b7f9 100644 --- a/compiler/rustc_typeck/src/check/method/suggest.rs +++ b/compiler/rustc_typeck/src/check/method/suggest.rs @@ -67,6 +67,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { span, }) .into()], + ty::ConstnessArg::Not, ); let trait_ref = ty::TraitRef::new(fn_once, fn_once_substs); let poly_trait_ref = ty::Binder::dummy(trait_ref); @@ -74,7 +75,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { span, self.body_id, self.param_env, - poly_trait_ref.without_const().to_predicate(tcx), + poly_trait_ref.to_predicate(tcx), ); self.predicate_may_hold(&obligation) }) diff --git a/compiler/rustc_typeck/src/check/upvar.rs b/compiler/rustc_typeck/src/check/upvar.rs index 74546ed908085..efa1682170c07 100644 --- a/compiler/rustc_typeck/src/check/upvar.rs +++ b/compiler/rustc_typeck/src/check/upvar.rs @@ -980,7 +980,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .type_implements_trait( check_trait, ty, - self.tcx.mk_substs_trait(ty, &[]), + self.tcx.mk_substs_trait(ty, &[], ty::ConstnessArg::Not), self.param_env, ) .must_apply_modulo_regions() @@ -1009,7 +1009,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .type_implements_trait( check_trait, ty, - self.tcx.mk_substs_trait(ty, &[]), + self.tcx.mk_substs_trait(ty, &[], ty::ConstnessArg::Not), self.param_env, ) .must_apply_modulo_regions() @@ -1355,7 +1355,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let is_drop_defined_for_ty = |ty: Ty<'tcx>| { let drop_trait = self.tcx.require_lang_item(hir::LangItem::Drop, Some(closure_span)); - let ty_params = self.tcx.mk_substs_trait(base_path_ty, &[]); + let ty_params = self.tcx.mk_substs_trait(base_path_ty, &[], ty::ConstnessArg::Not); self.infcx .type_implements_trait( drop_trait, diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 8ec887ab45362..66163c9f49f46 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -1632,8 +1632,8 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics { own_start = generics.count() as u32; // if parent has constness param, we do not inherit it from the parent, and we // get it in the end instead of the middle. - let parent_constness = parent_has_self as u32; - generics.parent_count as u32 + generics.params.len() as u32 - parent_constness + let parent_constness = parent_has_self as usize; + generics.parent_count + generics.params.len() - parent_constness }); let mut params: Vec<_> = Vec::with_capacity(ast_generics.params.len() + has_self as usize); @@ -1762,7 +1762,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics { if has_self || parent_has_self { params.push(ty::GenericParamDef { name: Symbol::intern(""), - index: type_start + i, + index: type_start + i as u32, def_id, pure_wrt_drop: false, kind: ty::GenericParamDefKind::Constness, diff --git a/compiler/rustc_typeck/src/lib.rs b/compiler/rustc_typeck/src/lib.rs index f98ae46c58730..93a125c575323 100644 --- a/compiler/rustc_typeck/src/lib.rs +++ b/compiler/rustc_typeck/src/lib.rs @@ -569,7 +569,7 @@ pub fn hir_trait_to_predicates<'tcx>( &item_cx, hir_trait, DUMMY_SP, - ty::BoundConstness::NotConst, + ty::ConstnessArg::Not, // TODO Or Param? self_ty, &mut bounds, true, From ab19ef392362b3b95722ea88095b5d0b08bcfbe4 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 9 May 2022 14:08:20 +0000 Subject: [PATCH 06/51] Address trivial lints --- .../rustc_trait_selection/src/traits/error_reporting/mod.rs | 2 +- .../rustc_trait_selection/src/traits/select/confirmation.rs | 1 - compiler/rustc_trait_selection/src/traits/specialize/mod.rs | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) 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 767788adcdf03..8453c460476c1 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -325,7 +325,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { match bound_predicate.skip_binder() { ty::PredicateKind::Trait(trait_predicate) => { let trait_predicate = bound_predicate.rebind(trait_predicate); - let mut trait_predicate = self.resolve_vars_if_possible(trait_predicate); + let trait_predicate = self.resolve_vars_if_possible(trait_predicate); let predicate_is_const = ty::ConstnessArg::Required == trait_predicate.skip_binder().constness(); diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 40836bb5d54e6..92ffd415c8e9f 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -42,7 +42,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { obligation: &TraitObligation<'tcx>, candidate: SelectionCandidate<'tcx>, ) -> Result, SelectionError<'tcx>> { - let mut obligation = obligation; // let new_obligation; // HACK(const_trait_impl): the surrounding environment is remapped to a non-const context diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs index e167650df109c..66a89bcd1ce6a 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs @@ -507,7 +507,7 @@ 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.to_opt_poly_trait_pred() { if Some(poly_trait_ref.def_id()) == sized_trait { types_without_default_bounds.remove(&poly_trait_ref.self_ty().skip_binder()); From 429f9e1a6396cb1aa2557970c00c61da934bd77d Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 9 May 2022 14:08:52 +0000 Subject: [PATCH 07/51] rustc_const_eval --- compiler/rustc_const_eval/src/transform/check_consts/ops.rs | 2 +- .../rustc_const_eval/src/transform/check_consts/qualifs.rs | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs index 29ac0a76b398e..dd6de864d7717 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs @@ -149,7 +149,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> { ObligationCause::dummy(), param_env, Binder::dummy(TraitPredicate { - trait_ref: trait_ref.without_const(), + trait_ref, polarity: ImplPolarity::Positive, }), ); 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 1a6f34f5bd26b..718a863b1c70b 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs @@ -176,8 +176,7 @@ impl Qualif for NeedsNonConstDrop { if !matches!( impl_src, - ImplSource::ConstDestruct(_) - | ImplSource::Param(_, ty::ConstnessArg::Requried) + ImplSource::ConstDestruct(_) | ImplSource::Param(_, ty::ConstnessArg::Required) ) { // If our const destruct candidate is not ConstDestruct or implied by the param env, // then it's bad From d9b6e5042169b7ff62284f0ff469602837714f3b Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 9 May 2022 14:09:44 +0000 Subject: [PATCH 08/51] runtime matches fall back to non-const PartialEq. Will need to fix in the future to allow in const fn --- compiler/rustc_mir_build/src/build/matches/test.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_mir_build/src/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs index 598da80c574af..70983c79ac6e7 100644 --- a/compiler/rustc_mir_build/src/build/matches/test.rs +++ b/compiler/rustc_mir_build/src/build/matches/test.rs @@ -820,7 +820,7 @@ fn trait_method<'tcx>( self_ty: Ty<'tcx>, params: &[GenericArg<'tcx>], ) -> ConstantKind<'tcx> { - let substs = tcx.mk_substs_trait(self_ty, params); + let substs = tcx.mk_substs_trait(self_ty, params, ty::ConstnessArg::Not); // The unhygienic comparison here is acceptable because this is only // used on known traits. From 821bb1fa6aa397cea28eec53757b6a445f157c4b Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 31 May 2022 10:37:23 +0000 Subject: [PATCH 09/51] Small fixups --- compiler/rustc_borrowck/src/region_infer/opaque_types.rs | 1 + .../rustc_const_eval/src/transform/check_consts/check.rs | 4 +++- compiler/rustc_const_eval/src/transform/check_consts/ops.rs | 2 +- compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs | 1 + compiler/rustc_traits/src/chalk/db.rs | 3 ++- compiler/rustc_traits/src/chalk/lowering.rs | 2 ++ compiler/rustc_typeck/src/astconv/mod.rs | 5 +++-- 7 files changed, 13 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index 7c1fa28b8dfcc..768a54f4772f3 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -381,6 +381,7 @@ fn check_opaque_type_parameter_valid( matches!(*lt, ty::ReEarlyBound(_) | ty::ReFree(_)) } GenericArgKind::Const(ct) => matches!(ct.kind(), ty::ConstKind::Param(_)), + GenericArgKind::Constness(ct) => matches!(ct, ty::ConstnessArg::Param), }; if arg_is_param { 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 d940c63fa14de..f5225f03b47e6 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -346,7 +346,9 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> { // No constraints on lifetimes or constants, except potentially // constants' types, but `walk` will get to them as well. - GenericArgKind::Lifetime(_) | GenericArgKind::Const(_) => continue, + GenericArgKind::Constness(_) + | GenericArgKind::Lifetime(_) + | GenericArgKind::Const(_) => continue, }; match *ty.kind() { diff --git a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs index dd6de864d7717..8c90974d50e4a 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs @@ -15,7 +15,7 @@ use rustc_middle::ty::{ suggest_constraining_type_param, Adt, Closure, DefIdTree, FnDef, FnPtr, Param, TraitPredicate, Ty, }; -use rustc_middle::ty::{Binder, BoundConstness, ImplPolarity, TraitRef}; +use rustc_middle::ty::{Binder, ImplPolarity, TraitRef}; use rustc_session::parse::feature_err; use rustc_span::symbol::sym; use rustc_span::{BytePos, Pos, Span, Symbol}; diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index e32e0b11ba497..bf0d459e26fb4 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -250,6 +250,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { ty::subst::GenericArgKind::Lifetime(_) => false, ty::subst::GenericArgKind::Type(t) => t.is_fn_ptr(), ty::subst::GenericArgKind::Const(_) => false, + ty::subst::GenericArgKind::Constness(_) => false, }) } diff --git a/compiler/rustc_traits/src/chalk/db.rs b/compiler/rustc_traits/src/chalk/db.rs index 7b87d0f2374b0..eeeea52ef5f7b 100644 --- a/compiler/rustc_traits/src/chalk/db.rs +++ b/compiler/rustc_traits/src/chalk/db.rs @@ -741,7 +741,7 @@ fn bound_vars_for_item<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> SubstsRef<'tcx }) .into(), ty::GenericParamDefKind::Constness => { - ty::GenericArg::Param.into() // TODO Confirm + ty::ConstnessArg::Param.into() // TODO Confirm } }) } @@ -760,6 +760,7 @@ fn binders_for<'tcx>( ty::subst::GenericArgKind::Const(c) => { chalk_ir::VariableKind::Const(c.ty().lower_into(interner)) } + ty::subst::GenericArgKind::Constness(_) => unimplemented!(), }), ) } diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs index 0c01d4973a018..1fc587395fd36 100644 --- a/compiler/rustc_traits/src/chalk/lowering.rs +++ b/compiler/rustc_traits/src/chalk/lowering.rs @@ -191,6 +191,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::GoalData>> for ty::Predi GenericArgKind::Const(..) => { chalk_ir::GoalData::All(chalk_ir::Goals::empty(interner)) } + GenericArgKind::Constness(..) => unimplemented!(), GenericArgKind::Lifetime(lt) => bug!("unexpect well formed predicate: {:?}", lt), }, @@ -565,6 +566,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::GenericArg>> for Generic ty::subst::GenericArgKind::Const(c) => { chalk_ir::GenericArgData::Const(c.lower_into(interner)) } + ty::subst::GenericArgKind::Constness(_) => unimplemented!(), } .intern(interner) } diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index 1aa43a4475a08..b43fe3c8bb0a2 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -1347,7 +1347,8 @@ 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, bounds.trait_bounds.iter()); + let expanded_traits = + traits::expand_trait_aliases(tcx, bounds.trait_bounds.iter().copied()); let (mut auto_traits, regular_traits): (Vec<_>, Vec<_>) = expanded_traits .filter(|i| i.trait_ref().self_ty().skip_binder() == dummy_self) .partition(|i| tcx.trait_is_auto(i.trait_ref().def_id())); @@ -1387,7 +1388,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let trait_alias_span = bounds .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)); tcx.sess.emit_err(TraitObjectDeclaredWithNoTraits { span, trait_alias_span }); From 67e3eb37ae816a1e14b2153f89dbbb75d0307eaf Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 9 May 2022 14:30:37 +0000 Subject: [PATCH 10/51] Infer constness params from context if missing --- compiler/rustc_typeck/src/astconv/mod.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index b43fe3c8bb0a2..9dbaae464ef98 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -567,6 +567,21 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } } } + GenericParamDefKind::Constness => { + match self.astconv.item_def_id() { + // no information available + // TODO: fall back to `Not`? + None => ty::ConstnessArg::Param, + Some(context) => { + if tcx.hir().body_const_context(context.expect_local()).is_some() { + ty::ConstnessArg::Required + } else { + ty::ConstnessArg::Not + } + } + } + .into() + } } } } From 1b7063864ba9ae365f5cbd8f7d3b735b19d416a7 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 9 May 2022 14:31:49 +0000 Subject: [PATCH 11/51] Port some more crates --- compiler/rustc_typeck/src/check/compare_method.rs | 8 ++++++-- compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs | 1 + compiler/rustc_typeck/src/check/method/mod.rs | 8 ++++++-- compiler/rustc_typeck/src/check/method/probe.rs | 7 ++++--- compiler/rustc_typeck/src/check/wfcheck.rs | 8 ++++---- compiler/rustc_typeck/src/impl_wf_check.rs | 3 +++ compiler/rustc_typeck/src/outlives/implicit_infer.rs | 6 +++++- compiler/rustc_typeck/src/outlives/mod.rs | 4 ++++ compiler/rustc_typeck/src/outlives/utils.rs | 3 +++ compiler/rustc_typeck/src/variance/constraints.rs | 3 +++ 10 files changed, 39 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_typeck/src/check/compare_method.rs b/compiler/rustc_typeck/src/check/compare_method.rs index ec85fe55c4a2d..b6e00f870a9a0 100644 --- a/compiler/rustc_typeck/src/check/compare_method.rs +++ b/compiler/rustc_typeck/src/check/compare_method.rs @@ -834,11 +834,15 @@ fn compare_synthetic_generics<'tcx>( let trait_m_generics = tcx.generics_of(trait_m.def_id); let impl_m_type_params = impl_m_generics.params.iter().filter_map(|param| match param.kind { GenericParamDefKind::Type { synthetic, .. } => Some((param.def_id, synthetic)), - GenericParamDefKind::Lifetime | GenericParamDefKind::Const { .. } => None, + GenericParamDefKind::Constness + | GenericParamDefKind::Lifetime + | GenericParamDefKind::Const { .. } => None, }); let trait_m_type_params = trait_m_generics.params.iter().filter_map(|param| match param.kind { GenericParamDefKind::Type { synthetic, .. } => Some((param.def_id, synthetic)), - GenericParamDefKind::Lifetime | GenericParamDefKind::Const { .. } => None, + GenericParamDefKind::Constness + | GenericParamDefKind::Lifetime + | GenericParamDefKind::Const { .. } => None, }); for ((impl_def_id, impl_synthetic), (trait_def_id, trait_synthetic)) in iter::zip(impl_m_type_params, trait_m_type_params) diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs index c3d2b12c2ec9c..5110eba5caa3d 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs @@ -1433,6 +1433,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.fcx.var_for_def(self.span, param) } } + GenericParamDefKind::Constness => self.fcx.var_for_def(self.span, param), } } } diff --git a/compiler/rustc_typeck/src/check/method/mod.rs b/compiler/rustc_typeck/src/check/method/mod.rs index 6821d85d600c3..d62466fff9b45 100644 --- a/compiler/rustc_typeck/src/check/method/mod.rs +++ b/compiler/rustc_typeck/src/check/method/mod.rs @@ -284,7 +284,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Construct a trait-reference `self_ty : Trait` let substs = InternalSubsts::for_item(self.tcx, trait_def_id, |param, _| { match param.kind { - GenericParamDefKind::Lifetime | GenericParamDefKind::Const { .. } => {} + GenericParamDefKind::Constness + | GenericParamDefKind::Lifetime + | GenericParamDefKind::Const { .. } => {} GenericParamDefKind::Type { .. } => { if param.index == 0 { return self_ty.into(); @@ -323,7 +325,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Construct a trait-reference `self_ty : Trait` let substs = InternalSubsts::for_item(self.tcx, trait_def_id, |param, _| { match param.kind { - GenericParamDefKind::Lifetime | GenericParamDefKind::Const { .. } => {} + GenericParamDefKind::Constness + | GenericParamDefKind::Lifetime + | GenericParamDefKind::Const { .. } => {} GenericParamDefKind::Type { .. } => { if param.index == 0 { return self_ty.into(); diff --git a/compiler/rustc_typeck/src/check/method/probe.rs b/compiler/rustc_typeck/src/check/method/probe.rs index 0964f876d79f6..3a7dce4ab64cf 100644 --- a/compiler/rustc_typeck/src/check/method/probe.rs +++ b/compiler/rustc_typeck/src/check/method/probe.rs @@ -1796,9 +1796,9 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { // In general, during probe we erase regions. self.tcx.lifetimes.re_erased.into() } - GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. } => { - self.var_for_def(self.span, param) - } + GenericParamDefKind::Constness + | GenericParamDefKind::Type { .. } + | GenericParamDefKind::Const { .. } => self.var_for_def(self.span, param), } } }); @@ -1833,6 +1833,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { }; self.next_const_var(self.tcx.type_of(param.def_id), origin).into() } + GenericParamDefKind::Constness => ty::ConstnessArg::Param.into(), }) } diff --git a/compiler/rustc_typeck/src/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs index 0e1cd1c3cb022..26a57a271a76a 100644 --- a/compiler/rustc_typeck/src/check/wfcheck.rs +++ b/compiler/rustc_typeck/src/check/wfcheck.rs @@ -1281,7 +1281,7 @@ fn check_where_clauses<'tcx, 'fcx>( | GenericParamDefKind::Const { has_default } => { has_default && def.index >= generics.parent_count as u32 } - GenericParamDefKind::Lifetime => unreachable!(), + GenericParamDefKind::Constness | GenericParamDefKind::Lifetime => unreachable!(), }; // Check that concrete defaults are well-formed. See test `type-check-defaults.rs`. @@ -1323,8 +1323,8 @@ fn check_where_clauses<'tcx, 'fcx>( } } } - // Doesn't have defaults. - GenericParamDefKind::Lifetime => {} + // Don't have defaults. + GenericParamDefKind::Constness | GenericParamDefKind::Lifetime => {} } } @@ -1338,7 +1338,7 @@ fn check_where_clauses<'tcx, 'fcx>( // First we build the defaulted substitution. let substs = InternalSubsts::for_item(tcx, def_id.to_def_id(), |param, _| { match param.kind { - GenericParamDefKind::Lifetime => { + GenericParamDefKind::Constness | GenericParamDefKind::Lifetime => { // All regions are identity. tcx.mk_param_from_def(param) } diff --git a/compiler/rustc_typeck/src/impl_wf_check.rs b/compiler/rustc_typeck/src/impl_wf_check.rs index e7ca70de4ba71..c8ea68d304646 100644 --- a/compiler/rustc_typeck/src/impl_wf_check.rs +++ b/compiler/rustc_typeck/src/impl_wf_check.rs @@ -155,6 +155,9 @@ fn enforce_impl_params_are_constrained(tcx: TyCtxt<'_>, impl_def_id: LocalDefId) ); } } + ty::GenericParamDefKind::Constness => { + // TODO: users can't write these, do we have to do anything here? + } } } diff --git a/compiler/rustc_typeck/src/outlives/implicit_infer.rs b/compiler/rustc_typeck/src/outlives/implicit_infer.rs index 257a9520eeb25..04649f82131f5 100644 --- a/compiler/rustc_typeck/src/outlives/implicit_infer.rs +++ b/compiler/rustc_typeck/src/outlives/implicit_infer.rs @@ -99,7 +99,11 @@ fn insert_required_predicates_to_be_wf<'tcx>( // No predicates from lifetimes or constants, except potentially // constants' types, but `walk` will get to them as well. - GenericArgKind::Lifetime(_) | GenericArgKind::Const(_) => continue, + GenericArgKind::Constness(_) + | GenericArgKind::Lifetime(_) + | GenericArgKind::Const(_) => { + continue; + } }; match *ty.kind() { diff --git a/compiler/rustc_typeck/src/outlives/mod.rs b/compiler/rustc_typeck/src/outlives/mod.rs index 8fa65d51e3ba1..d25d45b0039e7 100644 --- a/compiler/rustc_typeck/src/outlives/mod.rs +++ b/compiler/rustc_typeck/src/outlives/mod.rs @@ -119,6 +119,10 @@ fn inferred_outlives_crate(tcx: TyCtxt<'_>, (): ()) -> CratePredicatesMap<'_> { // Generic consts don't impose any constraints. None } + GenericArgKind::Constness(_) => { + // Constness effect doesn't impose any constraints. + None + } } }, )); diff --git a/compiler/rustc_typeck/src/outlives/utils.rs b/compiler/rustc_typeck/src/outlives/utils.rs index b718ca9421336..922854c69f96c 100644 --- a/compiler/rustc_typeck/src/outlives/utils.rs +++ b/compiler/rustc_typeck/src/outlives/utils.rs @@ -128,6 +128,9 @@ pub(crate) fn insert_outlives_predicate<'tcx>( GenericArgKind::Const(_) => { // Generic consts don't impose any constraints. } + GenericArgKind::Constness(_) => { + // Constness effect doesn't impose any constraints. + } } } diff --git a/compiler/rustc_typeck/src/variance/constraints.rs b/compiler/rustc_typeck/src/variance/constraints.rs index d79450e1ae707..6f703362c6869 100644 --- a/compiler/rustc_typeck/src/variance/constraints.rs +++ b/compiler/rustc_typeck/src/variance/constraints.rs @@ -189,6 +189,8 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { GenericArgKind::Const(val) => { self.add_constraints_from_const(current, val, variance_i) } + // Does not contain anything with constraints + GenericArgKind::Constness(_) => {} } } } @@ -354,6 +356,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { GenericArgKind::Const(val) => { self.add_constraints_from_const(current, val, variance) } + GenericArgKind::Constness(_) => {} } } } From 11026ec17c65877bc21f0198fd3ce42a68ee7136 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 9 May 2022 14:35:42 +0000 Subject: [PATCH 12/51] Update mir typeck --- .../rustc_borrowck/src/type_check/canonical.rs | 1 - compiler/rustc_borrowck/src/type_check/mod.rs | 17 +++++++++++------ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_borrowck/src/type_check/canonical.rs b/compiler/rustc_borrowck/src/type_check/canonical.rs index 55c0bf05b4873..30c77a935c062 100644 --- a/compiler/rustc_borrowck/src/type_check/canonical.rs +++ b/compiler/rustc_borrowck/src/type_check/canonical.rs @@ -93,7 +93,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { self.prove_predicates( Some(ty::Binder::dummy(ty::PredicateKind::Trait(ty::TraitPredicate { trait_ref, - constness: ty::BoundConstness::NotConst, polarity: ty::ImplPolarity::Positive, }))), locations, diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index cf2140097e6da..7eaa4bc556bb6 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -572,7 +572,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { let tcx = self.tcx(); let trait_ref = ty::TraitRef { def_id: tcx.require_lang_item(LangItem::Copy, Some(self.last_span)), - substs: tcx.mk_substs_trait(place_ty.ty, &[]), + substs: tcx.mk_substs_trait(place_ty.ty, &[], ty::ConstnessArg::Not), }; // To have a `Copy` operand, the type `T` of the @@ -1304,7 +1304,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { if !self.unsized_feature_enabled() { let trait_ref = ty::TraitRef { def_id: tcx.require_lang_item(LangItem::Sized, Some(self.last_span)), - substs: tcx.mk_substs_trait(place_ty, &[]), + substs: tcx.mk_substs_trait(place_ty, &[], ty::ConstnessArg::Not), }; self.prove_trait_ref( trait_ref, @@ -1894,7 +1894,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { let ty = place.ty(body, tcx).ty; let trait_ref = ty::TraitRef::new( tcx.require_lang_item(LangItem::Copy, Some(span)), - tcx.mk_substs_trait(ty, &[]), + tcx.mk_substs_trait(ty, &[], ty::ConstnessArg::Not), ); self.prove_trait_ref( @@ -1910,7 +1910,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { &Rvalue::NullaryOp(_, ty) => { let trait_ref = ty::TraitRef { def_id: tcx.require_lang_item(LangItem::Sized, Some(self.last_span)), - substs: tcx.mk_substs_trait(ty, &[]), + substs: tcx.mk_substs_trait(ty, &[], ty::ConstnessArg::Not), }; self.prove_trait_ref( @@ -1925,7 +1925,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { let trait_ref = ty::TraitRef { def_id: tcx.require_lang_item(LangItem::Sized, Some(self.last_span)), - substs: tcx.mk_substs_trait(*ty, &[]), + substs: tcx.mk_substs_trait(*ty, &[], ty::ConstnessArg::Not), }; self.prove_trait_ref( @@ -2026,7 +2026,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { let trait_ref = ty::TraitRef { def_id: tcx .require_lang_item(LangItem::CoerceUnsized, Some(self.last_span)), - substs: tcx.mk_substs_trait(op.ty(body, tcx), &[ty.into()]), + // TODO: pick constness arg from context + substs: tcx.mk_substs_trait( + op.ty(body, tcx), + &[ty.into()], + ty::ConstnessArg::Not, + ), }; self.prove_trait_ref( From 6ce510980604c1253f1ef18442c23f191fe96ce9 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 9 May 2022 17:40:27 +0000 Subject: [PATCH 13/51] typeck and borrowck compile --- compiler/rustc_borrowck/src/diagnostics/region_name.rs | 1 + .../src/type_check/constraint_conversion.rs | 2 +- compiler/rustc_borrowck/src/type_check/mod.rs | 4 +++- compiler/rustc_mir_transform/src/shim.rs | 7 ++++--- compiler/rustc_privacy/src/lib.rs | 10 ++++------ compiler/rustc_typeck/src/check/compare_method.rs | 7 +++++-- .../src/impl_wf_check/min_specialization.rs | 3 +-- 7 files changed, 19 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs index e60e11f11df9f..9686729ad6eb7 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs @@ -642,6 +642,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { ( GenericArgKind::Lifetime(_) | GenericArgKind::Type(_) + | GenericArgKind::Constness(_) | GenericArgKind::Const(_), _, ) => { diff --git a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs index 3f9c0cecccc68..5afea31c047e7 100644 --- a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs +++ b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs @@ -126,7 +126,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> { .type_must_outlive(origin, t1, r2); } - GenericArgKind::Const(_) => { + GenericArgKind::Constness(_) | GenericArgKind::Const(_) => { // Consts cannot outlive one another, so we // don't need to handle any relations here. } diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 7eaa4bc556bb6..6a8c340371ac3 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -2608,7 +2608,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { (outlives_requirements.category, outlives_requirements.blame_span), )) } - GenericArgKind::Type(_) | GenericArgKind::Const(_) => None, + GenericArgKind::Type(_) + | GenericArgKind::Const(_) + | GenericArgKind::Constness(_) => None, } }) .collect(); diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index f3153a6482048..36192c6a2528d 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -342,7 +342,7 @@ impl<'tcx> CloneShimBuilder<'tcx> { // we must subst the self_ty because it's // otherwise going to be TySelf and we can't index // or access fields of a Place of type TySelf. - let substs = tcx.mk_substs_trait(self_ty, &[]); + let substs = tcx.mk_substs_trait(self_ty, &[], ty::ConstnessArg::Not); let sig = tcx.bound_fn_sig(def_id).subst(tcx, substs); let sig = tcx.erase_late_bound_regions(sig); let span = tcx.def_span(def_id); @@ -423,7 +423,7 @@ impl<'tcx> CloneShimBuilder<'tcx> { ) { let tcx = self.tcx; - let substs = tcx.mk_substs_trait(ty, &[]); + let substs = tcx.mk_substs_trait(ty, &[], ty::ConstnessArg::Not); // `func == Clone::clone(&ty) -> ty` let func_ty = tcx.mk_fn_def(self.def_id, substs); @@ -529,7 +529,8 @@ fn build_call_shim<'tcx>( // Create substitutions for the `Self` and `Args` generic parameters of the shim body. let arg_tup = tcx.mk_tup(untuple_args.iter()); - let sig_substs = tcx.mk_substs_trait(ty, &[ty::subst::GenericArg::from(arg_tup)]); + let sig_substs = + tcx.mk_substs_trait(ty, &[ty::subst::GenericArg::from(arg_tup)], ty::ConstnessArg::Not); (Some(sig_substs), Some(untuple_args)) } else { diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 5560d44aa0d52..0b973ea657562 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -132,11 +132,9 @@ where fn visit_predicate(&mut self, predicate: ty::Predicate<'tcx>) -> ControlFlow { match predicate.kind().skip_binder() { - ty::PredicateKind::Trait(ty::TraitPredicate { - trait_ref, - constness: _, - polarity: _, - }) => self.visit_trait(trait_ref), + ty::PredicateKind::Trait(ty::TraitPredicate { trait_ref, polarity: _ }) => { + self.visit_trait(trait_ref) + } ty::PredicateKind::Projection(ty::ProjectionPredicate { projection_ty, term }) => { term.visit_with(self)?; self.visit_projection_ty(projection_ty) @@ -1167,7 +1165,7 @@ impl<'tcx> Visitor<'tcx> for TypePrivacyVisitor<'tcx> { self.tcx.types.never, ); - for (trait_predicate, _, _) in bounds.trait_bounds { + for (trait_predicate, _) in bounds.trait_bounds { if self.visit_trait(trait_predicate.skip_binder()).is_break() { return; } diff --git a/compiler/rustc_typeck/src/check/compare_method.rs b/compiler/rustc_typeck/src/check/compare_method.rs index b6e00f870a9a0..299f473042cee 100644 --- a/compiler/rustc_typeck/src/check/compare_method.rs +++ b/compiler/rustc_typeck/src/check/compare_method.rs @@ -1013,7 +1013,9 @@ fn compare_generic_param_kinds<'tcx>( // this is exhaustive so that anyone adding new generic param kinds knows // to make sure this error is reported for them. (Const { .. }, Const { .. }) | (Type { .. }, Type { .. }) => false, - (Lifetime { .. }, _) | (_, Lifetime { .. }) => unreachable!(), + (Constness, _) | (_, Constness) | (Lifetime { .. }, _) | (_, Lifetime { .. }) => { + unreachable!() + } } { let param_impl_span = tcx.def_span(param_impl.def_id); let param_trait_span = tcx.def_span(param_trait.def_id); @@ -1033,7 +1035,7 @@ fn compare_generic_param_kinds<'tcx>( format!("{} const parameter of type `{}`", prefix, tcx.type_of(param.def_id)) } Type { .. } => format!("{} type parameter", prefix), - Lifetime { .. } => unreachable!(), + Constness | Lifetime { .. } => unreachable!(), }; let trait_header_span = tcx.def_ident_span(tcx.parent(trait_item.def_id)).unwrap(); @@ -1376,6 +1378,7 @@ pub fn check_type_bounds<'tcx>( }) .into() } + GenericParamDefKind::Constness => ty::ConstnessArg::Param.into(), }); let bound_vars = tcx.mk_bound_variable_kinds(bound_vars.into_iter()); let impl_ty_substs = tcx.intern_substs(&substs); diff --git a/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs b/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs index d2d2e2a1961f6..04742518cd0d7 100644 --- a/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs +++ b/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs @@ -413,8 +413,7 @@ fn trait_predicate_kind<'tcx>( trait_ref, // TODO review specialization check polarity: _, }) => Some(tcx.trait_def(trait_ref.def_id).specialization_kind), - ty::PredicateKind::Trait(_) - | ty::PredicateKind::RegionOutlives(_) + ty::PredicateKind::RegionOutlives(_) | ty::PredicateKind::TypeOutlives(_) | ty::PredicateKind::Projection(_) | ty::PredicateKind::WellFormed(_) From 7d3ee998240cdca70806b84e0d0f3d88548a8756 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 9 May 2022 17:41:59 +0000 Subject: [PATCH 14/51] Get rustc_privacy to compile --- compiler/rustc_privacy/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 0b973ea657562..2a5fd8c1419ec 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -846,7 +846,7 @@ impl ReachEverythingInTheInterfaceVisitor<'_, '_> { fn generics(&mut self) -> &mut Self { for param in &self.ev.tcx.generics_of(self.item_def_id).params { match param.kind { - GenericParamDefKind::Lifetime => {} + GenericParamDefKind::Constness | GenericParamDefKind::Lifetime => {} GenericParamDefKind::Type { has_default, .. } => { if has_default { self.visit(self.ev.tcx.type_of(param.def_id)); @@ -1674,7 +1674,7 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> { fn generics(&mut self) -> &mut Self { for param in &self.tcx.generics_of(self.item_def_id).params { match param.kind { - GenericParamDefKind::Lifetime => {} + GenericParamDefKind::Constness | GenericParamDefKind::Lifetime => {} GenericParamDefKind::Type { has_default, .. } => { if has_default { self.visit(self.tcx.type_of(param.def_id)); From 537b869fb43ad3be2de8e020039254f3e50a2fca Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 9 May 2022 17:49:58 +0000 Subject: [PATCH 15/51] rustdoc --- src/librustdoc/clean/auto_trait.rs | 6 +++++- src/librustdoc/clean/mod.rs | 6 +++++- src/librustdoc/clean/types.rs | 5 ++++- src/librustdoc/clean/utils.rs | 1 + src/librustdoc/html/format.rs | 1 + src/librustdoc/json/conversions.rs | 1 + src/rustdoc-json-types/lib.rs | 1 + 7 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index e6f006135e29a..c031e4c4e5e9e 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -40,7 +40,10 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { discard_positive_impl: bool, ) -> Option { let tcx = self.cx.tcx; - let trait_ref = ty::TraitRef { def_id: trait_def_id, substs: tcx.mk_substs_trait(ty, &[]) }; + let trait_ref = ty::TraitRef { + def_id: trait_def_id, + substs: tcx.mk_substs_trait(ty, &[], ty::ConstnessArg::Not), + }; if !self.cx.generated_synthetics.insert((ty, trait_def_id)) { debug!("get_auto_trait_impl_for({:?}): already generated, aborting", trait_ref); return None; @@ -625,6 +628,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { } } GenericParamDefKind::Lifetime { .. } => {} + GenericParamDefKind::Constness => {} GenericParamDefKind::Const { ref mut default, .. } => { // We never want something like `impl` default.take(); diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index fa2efb0041621..b70ad5e82c4bb 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -308,7 +308,7 @@ impl<'tcx> Clean<'tcx, Option> for ty::Predicate<'tcx> { impl<'tcx> Clean<'tcx, Option> for ty::PolyTraitPredicate<'tcx> { fn clean(&self, cx: &mut DocContext<'tcx>) -> Option { // `T: ~const Destruct` is hidden because `T: Destruct` is a no-op. - if self.skip_binder().constness == ty::BoundConstness::ConstIfConst + if self.skip_binder().constness() != ty::ConstnessArg::Not && Some(self.skip_binder().def_id()) == cx.tcx.lang_items().destruct_trait() { return None; @@ -439,6 +439,7 @@ fn projection_to_path_segment<'tcx>( impl<'tcx> Clean<'tcx, GenericParamDef> for ty::GenericParamDef { fn clean(&self, cx: &mut DocContext<'tcx>) -> GenericParamDef { let (name, kind) = match self.kind { + ty::GenericParamDefKind::Constness => (self.name, GenericParamDefKind::Constness), ty::GenericParamDefKind::Lifetime => { (self.name, GenericParamDefKind::Lifetime { outlives: vec![] }) } @@ -561,6 +562,7 @@ impl<'tcx> Clean<'tcx, Generics> for hir::Generics<'tcx> { .map(|param| { let param = clean_generic_param(cx, Some(self), param); match param.kind { + GenericParamDefKind::Constness => unreachable!(), GenericParamDefKind::Lifetime { .. } => unreachable!(), GenericParamDefKind::Type { did, ref bounds, .. } => { cx.impl_trait_bounds.insert(did.into(), bounds.clone()); @@ -594,6 +596,7 @@ impl<'tcx> Clean<'tcx, Generics> for hir::Generics<'tcx> { if bounds.is_empty() { for param in &mut generics.params { match param.kind { + GenericParamDefKind::Constness => {} GenericParamDefKind::Lifetime { .. } => {} GenericParamDefKind::Type { bounds: ref mut ty_bounds, .. } => { if ¶m.name == name { @@ -642,6 +645,7 @@ fn clean_ty_generics<'tcx>( } Some(param.clean(cx)) } + ty::GenericParamDefKind::Constness => None, ty::GenericParamDefKind::Const { .. } => Some(param.clean(cx)), }) .collect::>(); diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index d29ba2dedaf71..5160c1b96c204 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -1362,6 +1362,7 @@ impl WherePredicate { #[derive(Clone, PartialEq, Eq, Debug, Hash)] pub(crate) enum GenericParamDefKind { + Constness, Lifetime { outlives: Vec }, Type { did: DefId, bounds: Vec, default: Option>, synthetic: bool }, Const { did: DefId, ty: Box, default: Option> }, @@ -1386,7 +1387,9 @@ rustc_data_structures::static_assert_size!(GenericParamDef, 56); impl GenericParamDef { pub(crate) fn is_synthetic_type_param(&self) -> bool { match self.kind { - GenericParamDefKind::Lifetime { .. } | GenericParamDefKind::Const { .. } => false, + GenericParamDefKind::Constness + | GenericParamDefKind::Lifetime { .. } + | GenericParamDefKind::Const { .. } => false, GenericParamDefKind::Type { synthetic, .. } => synthetic, } } diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 22b1e2335fd84..0161951b04bff 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -84,6 +84,7 @@ pub(crate) fn substs_to_args<'tcx>( let mut ret_val = Vec::with_capacity(substs.len().saturating_sub(if skip_first { 1 } else { 0 })); ret_val.extend(substs.iter().filter_map(|kind| match kind.unpack() { + GenericArgKind::Constness(_) => None, GenericArgKind::Lifetime(lt) => { Some(GenericArg::Lifetime(lt.clean(cx).unwrap_or(Lifetime::elided()))) } diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 9f46ab54d3ece..46487a4b5ebf3 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -190,6 +190,7 @@ impl clean::GenericParamDef { cx: &'a Context<'tcx>, ) -> impl fmt::Display + 'a + Captures<'tcx> { display_fn(move |f| match &self.kind { + clean::GenericParamDefKind::Constness => Ok(()), clean::GenericParamDefKind::Lifetime { outlives } => { write!(f, "{}", self.name)?; diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index db2ad953f6aa0..999b686c3652e 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -363,6 +363,7 @@ impl FromWithTcx for GenericParamDefKind { type_: (*ty).into_tcx(tcx), default: default.map(|x| *x), }, + Constness => GenericParamDefKind::Constness, } } } diff --git a/src/rustdoc-json-types/lib.rs b/src/rustdoc-json-types/lib.rs index 1168a89a8b2bf..e9355447b2524 100644 --- a/src/rustdoc-json-types/lib.rs +++ b/src/rustdoc-json-types/lib.rs @@ -382,6 +382,7 @@ pub enum GenericParamDefKind { type_: Type, default: Option, }, + Constness, } #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] From 69e6e6308b5de85bffd3502b01e2fd7d1e0cad94 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 9 May 2022 17:53:09 +0000 Subject: [PATCH 16/51] clippy --- src/tools/clippy/clippy_lints/src/bool_assert_comparison.rs | 2 +- src/tools/clippy/clippy_lints/src/let_underscore.rs | 1 + .../clippy/clippy_lints/src/non_send_fields_in_send_ty.rs | 1 + src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs | 1 + src/tools/clippy/clippy_utils/src/ty.rs | 6 +++--- 5 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/tools/clippy/clippy_lints/src/bool_assert_comparison.rs b/src/tools/clippy/clippy_lints/src/bool_assert_comparison.rs index 95abe8aa59fbe..1dc5afebd9e87 100644 --- a/src/tools/clippy/clippy_lints/src/bool_assert_comparison.rs +++ b/src/tools/clippy/clippy_lints/src/bool_assert_comparison.rs @@ -59,7 +59,7 @@ fn is_impl_not_trait_with_bool_out(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { ) }) .map_or(false, |assoc_item| { - let proj = cx.tcx.mk_projection(assoc_item.def_id, cx.tcx.mk_substs_trait(ty, &[])); + let proj = cx.tcx.mk_projection(assoc_item.def_id, cx.tcx.mk_substs_trait(ty, &[], ty::ConstnessArg::Not)); let nty = cx.tcx.normalize_erasing_regions(cx.param_env, proj); nty.is_bool() diff --git a/src/tools/clippy/clippy_lints/src/let_underscore.rs b/src/tools/clippy/clippy_lints/src/let_underscore.rs index 176787497ebf2..23d5e353efa33 100644 --- a/src/tools/clippy/clippy_lints/src/let_underscore.rs +++ b/src/tools/clippy/clippy_lints/src/let_underscore.rs @@ -124,6 +124,7 @@ impl<'tcx> LateLintPass<'tcx> for LetUnderscore { SYNC_GUARD_PATHS.iter().any(|path| match_type(cx, inner_ty, path)) }, + GenericArgKind::Constness(_) | GenericArgKind::Lifetime(_) | GenericArgKind::Const(_) => false, }); if contains_sync_guard { diff --git a/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs b/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs index ddef7352de889..6c4b261ec0579 100644 --- a/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs +++ b/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs @@ -212,6 +212,7 @@ fn ty_allowed_with_raw_pointer_heuristic<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'t substs.iter().all(|generic_arg| match generic_arg.unpack() { GenericArgKind::Type(ty) => ty_allowed_with_raw_pointer_heuristic(cx, ty, send_trait), // Lifetimes and const generics are not solid part of ADT and ignored + GenericArgKind::Constness(_) | GenericArgKind::Lifetime(_) | GenericArgKind::Const(_) => true, }) } else { diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs index f3283588c7320..2ff130a011b47 100644 --- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs +++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs @@ -71,6 +71,7 @@ fn check_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, span: Span) -> McfResult { // No constraints on lifetimes or constants, except potentially // constants' types, but `walk` will get to them as well. + GenericArgKind::Constness(_) | GenericArgKind::Lifetime(_) | GenericArgKind::Const(_) => continue, }; diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs index a426fa1b0ffcf..a02c406f8d79e 100644 --- a/src/tools/clippy/clippy_utils/src/ty.rs +++ b/src/tools/clippy/clippy_utils/src/ty.rs @@ -47,7 +47,7 @@ pub fn can_partially_move_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool pub fn contains_ty<'tcx>(ty: Ty<'tcx>, other_ty: Ty<'tcx>) -> bool { ty.walk().any(|inner| match inner.unpack() { GenericArgKind::Type(inner_ty) => other_ty == inner_ty, - GenericArgKind::Lifetime(_) | GenericArgKind::Const(_) => false, + GenericArgKind::Lifetime(_) | GenericArgKind::Constness(_) | GenericArgKind::Const(_) => false, }) } @@ -56,7 +56,7 @@ pub fn contains_ty<'tcx>(ty: Ty<'tcx>, other_ty: Ty<'tcx>) -> bool { pub fn contains_adt_constructor<'tcx>(ty: Ty<'tcx>, adt: AdtDef<'tcx>) -> bool { ty.walk().any(|inner| match inner.unpack() { GenericArgKind::Type(inner_ty) => inner_ty.ty_adt_def() == Some(adt), - GenericArgKind::Lifetime(_) | GenericArgKind::Const(_) => false, + GenericArgKind::Lifetime(_) | GenericArgKind::Constness(_) | GenericArgKind::Const(_) => false, }) } @@ -80,7 +80,7 @@ pub fn get_associated_type<'tcx>( .associated_items(trait_id) .find_by_name_and_kind(cx.tcx, Ident::from_str(name), ty::AssocKind::Type, trait_id) .and_then(|assoc| { - let proj = cx.tcx.mk_projection(assoc.def_id, cx.tcx.mk_substs_trait(ty, &[])); + let proj = cx.tcx.mk_projection(assoc.def_id, cx.tcx.mk_substs_trait(ty, &[], ty::ConstnessArg::Not)); cx.tcx.try_normalize_erasing_regions(cx.param_env, proj).ok() }) } From dd7ec3784585c44b8aeecc47b3fc0a22971809d1 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 9 May 2022 18:20:22 +0000 Subject: [PATCH 17/51] Start poking ICEs until they melt --- compiler/rustc_middle/src/ty/fast_reject.rs | 18 ++++++++++++++++++ compiler/rustc_middle/src/ty/generics.rs | 5 +++++ compiler/rustc_typeck/src/astconv/mod.rs | 6 ++++-- 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_middle/src/ty/fast_reject.rs b/compiler/rustc_middle/src/ty/fast_reject.rs index 8d019a3bad8cc..3e9bd0437cd50 100644 --- a/compiler/rustc_middle/src/ty/fast_reject.rs +++ b/compiler/rustc_middle/src/ty/fast_reject.rs @@ -221,6 +221,9 @@ impl DeepRejectCtxt { (GenericArgKind::Const(obl), GenericArgKind::Const(imp)) => { self.consts_may_unify(obl, imp) } + (GenericArgKind::Constness(obl), GenericArgKind::Constness(imp)) => { + self.constness_may_unify(obl, imp) + } _ => bug!("kind mismatch: {obligation_arg} {impl_arg}"), } } @@ -402,4 +405,19 @@ impl DeepRejectCtxt { } } } + + pub fn constness_may_unify( + self, + obligation_ct: ty::ConstnessArg, + impl_ct: ty::ConstnessArg, + ) -> bool { + match (obligation_ct, impl_ct) { + (_, ty::ConstnessArg::Param) => true, + (ty::ConstnessArg::Param, _) => match self.treat_obligation_params { + TreatParams::AsPlaceholder => false, + TreatParams::AsInfer => true, + }, + _ => obligation_ct == impl_ct, + } + } } diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs index 2026505189393..58b82b208cf95 100644 --- a/compiler/rustc_middle/src/ty/generics.rs +++ b/compiler/rustc_middle/src/ty/generics.rs @@ -238,6 +238,11 @@ impl<'tcx> Generics { } } + /// Returns the `ConstnessArg` + pub fn has_constness_param(&'tcx self) -> bool { + self.params.iter().any(|param| matches!(param.kind, ty::GenericParamDefKind::Constness)) + } + /// Returns `true` if `params` has `impl Trait`. pub fn has_impl_trait(&'tcx self) -> bool { self.params.iter().any(|param| { diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index 9dbaae464ef98..5f4980fdf0443 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -573,9 +573,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // TODO: fall back to `Not`? None => ty::ConstnessArg::Param, Some(context) => { - if tcx.hir().body_const_context(context.expect_local()).is_some() { - ty::ConstnessArg::Required + if tcx.generics_of(context).has_constness_param() { + ty::ConstnessArg::Param } else { + // TODO: should use `Required` if we're in a const context + // like `const`/`static` item initializers. ty::ConstnessArg::Not } } From 77b4af3f1e809aab00908a6b93e002967d8a0e5b Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Wed, 11 May 2022 09:09:28 +1000 Subject: [PATCH 18/51] Fix assertion ICE --- compiler/rustc_typeck/src/check/method/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_typeck/src/check/method/mod.rs b/compiler/rustc_typeck/src/check/method/mod.rs index d62466fff9b45..22ded2e8457af 100644 --- a/compiler/rustc_typeck/src/check/method/mod.rs +++ b/compiler/rustc_typeck/src/check/method/mod.rs @@ -454,7 +454,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; let def_id = method_item.def_id; let generics = tcx.generics_of(def_id); - assert_eq!(generics.params.len(), 0); + assert_eq!(generics.params.len(), 1); // no generics except for constness debug!("lookup_in_trait_adjusted: method_item={:?}", method_item); let mut obligations = vec![]; From 17339ca81a045ba1f5a35c530110e0712554565e Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 11 May 2022 07:24:21 +0000 Subject: [PATCH 19/51] Add more information to substitution failure --- compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs index 5110eba5caa3d..712895fc24fa0 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs @@ -195,7 +195,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if i < method_generics.parent_count { self.infcx.var_for_def(DUMMY_SP, param) } else { - method.substs[i] + *method.substs.get(i).unwrap_or_else(|| { + span_bug!( + self.tcx.hir().span(hir_id), + "{:#?}\n{:#?}\ni: {}", + method, + method_generics, + i + ) + }) } }), user_self_ty: None, // not relevant here From 826f29dfbf3c192ec39ff3a636f1ffafc6644ac0 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 11 May 2022 07:49:56 +0000 Subject: [PATCH 20/51] Only add constness arg for const_trait traits --- compiler/rustc_typeck/src/collect.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 66163c9f49f46..ba23e2f1c7fb8 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -1759,7 +1759,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics { } } - if has_self || parent_has_self { + if (has_self || parent_has_self) && tcx.has_attr(def_id, sym::const_trait) { params.push(ty::GenericParamDef { name: Symbol::intern(""), index: type_start + i as u32, From 0d5b724b3d171191b7c5bda53dc58b94493633e8 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Wed, 11 May 2022 18:22:18 +1000 Subject: [PATCH 21/51] Print GenericArg --- compiler/rustc_middle/src/ty/print/pretty.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index d1fe922ac77b9..21cd417708918 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -2619,7 +2619,7 @@ define_print_and_forward_display! { GenericArgKind::Lifetime(lt) => p!(print(lt)), GenericArgKind::Type(ty) => p!(print(ty)), GenericArgKind::Const(ct) => p!(print(ct)), - GenericArgKind::Constness(_) => {}, + GenericArgKind::Constness(ca) => p!("{ca:?}"), } } } From e70e92ec791eecc52fcc778687116207c6c9637b Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 11 May 2022 09:18:39 +0000 Subject: [PATCH 22/51] Explicitly handle constness from parents --- compiler/rustc_middle/src/ty/generics.rs | 7 +++++-- compiler/rustc_typeck/src/collect.rs | 10 +++++++--- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs index 58b82b208cf95..33b7189a0ce25 100644 --- a/compiler/rustc_middle/src/ty/generics.rs +++ b/compiler/rustc_middle/src/ty/generics.rs @@ -110,7 +110,7 @@ pub struct GenericParamCount { /// with an item or method. Analogous to `hir::Generics`. /// /// The ordering of parameters is the same as in `Subst` (excluding child generics): -/// `Self` (optionally), `Lifetime` params..., `Type` params... +/// `Self` (optionally), `Lifetime` params..., `Type` params..., `constness` (optional) #[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable)] pub struct Generics { pub parent: Option, @@ -122,6 +122,7 @@ pub struct Generics { pub param_def_id_to_index: FxHashMap, pub has_self: bool, + pub has_constness: bool, pub has_late_bound_regions: Option, } @@ -240,7 +241,9 @@ impl<'tcx> Generics { /// Returns the `ConstnessArg` pub fn has_constness_param(&'tcx self) -> bool { - self.params.iter().any(|param| matches!(param.kind, ty::GenericParamDefKind::Constness)) + self.params + .last() + .map_or(false, |param| matches!(param.kind, ty::GenericParamDefKind::Constness)) } /// Returns `true` if `params` has `impl Trait`. diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index ba23e2f1c7fb8..56343dad0cd9c 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -1518,6 +1518,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics { params, param_def_id_to_index, has_self: generics.has_self, + has_constness: generics.has_constness, has_late_bound_regions: generics.has_late_bound_regions, }; } @@ -1623,7 +1624,9 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics { }; let has_self = opt_self.is_some(); + let has_constness = tcx.has_attr(def_id, sym::const_trait); let mut parent_has_self = false; + let mut parent_has_constness = false; let mut own_start = has_self as u32; let parent_count = parent_def_id.map_or(0, |def_id| { let generics = tcx.generics_of(def_id); @@ -1632,8 +1635,8 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics { own_start = generics.count() as u32; // if parent has constness param, we do not inherit it from the parent, and we // get it in the end instead of the middle. - let parent_constness = parent_has_self as usize; - generics.parent_count + generics.params.len() - parent_constness + parent_has_constness = generics.has_constness; + generics.parent_count + generics.params.len() - parent_has_constness as usize }); let mut params: Vec<_> = Vec::with_capacity(ast_generics.params.len() + has_self as usize); @@ -1759,7 +1762,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics { } } - if (has_self || parent_has_self) && tcx.has_attr(def_id, sym::const_trait) { + if has_constness || parent_has_constness { params.push(ty::GenericParamDef { name: Symbol::intern(""), index: type_start + i as u32, @@ -1777,6 +1780,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics { params, param_def_id_to_index, has_self: has_self || parent_has_self, + has_constness: has_constness || parent_has_constness, has_late_bound_regions: has_late_bound_regions(tcx, node), } } From 7c5527d3493291a963d4d8aff339ae566473b9b8 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 11 May 2022 09:22:35 +0000 Subject: [PATCH 23/51] Now that constness is optional, we default to not-const if it isn't there --- compiler/rustc_middle/src/ty/sty.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 1fe480d8d8493..c9c3b973d4fbd 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -816,10 +816,9 @@ impl<'tcx> TraitRef<'tcx> { } pub fn constness(self) -> ty::ConstnessArg { - // TODO remove panic match self.substs.last().expect("constness").unpack() { ty::subst::GenericArgKind::Constness(constness) => constness, - _ => panic!("?"), + _ => ty::ConstnessArg::Not, } } From 0fe3432828a12c8426fcefb1aa0be5e68d02fa2d Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 11 May 2022 09:24:59 +0000 Subject: [PATCH 24/51] Constness is optional now --- compiler/rustc_typeck/src/check/method/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_typeck/src/check/method/mod.rs b/compiler/rustc_typeck/src/check/method/mod.rs index 22ded2e8457af..ba7ef85879069 100644 --- a/compiler/rustc_typeck/src/check/method/mod.rs +++ b/compiler/rustc_typeck/src/check/method/mod.rs @@ -454,7 +454,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; let def_id = method_item.def_id; let generics = tcx.generics_of(def_id); - assert_eq!(generics.params.len(), 1); // no generics except for constness + assert_eq!(generics.params.len(), generics.has_constness as usize); // no generics except for constness debug!("lookup_in_trait_adjusted: method_item={:?}", method_item); let mut obligations = vec![]; From 56a16f8f7f997b4109748f3241aed3d7083f7ba6 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 11 May 2022 10:24:00 +0000 Subject: [PATCH 25/51] Remove constness arg from `mk_substs_trait` this is now handled in compiler/rustc_typeck/src/astconv/mod.rs --- compiler/rustc_borrowck/src/type_check/mod.rs | 16 ++++++---------- .../src/transform/check_consts/qualifs.rs | 2 +- compiler/rustc_infer/src/traits/engine.rs | 5 +---- compiler/rustc_middle/src/ty/adjustment.rs | 2 +- compiler/rustc_middle/src/ty/context.rs | 15 +++------------ compiler/rustc_middle/src/ty/instance.rs | 2 +- compiler/rustc_middle/src/ty/sty.rs | 7 ++----- .../rustc_mir_build/src/build/matches/test.rs | 2 +- .../rustc_mir_dataflow/src/elaborate_drops.rs | 2 +- compiler/rustc_mir_transform/src/shim.rs | 7 +++---- compiler/rustc_monomorphize/src/lib.rs | 2 +- .../src/traits/error_reporting/mod.rs | 5 +++-- compiler/rustc_trait_selection/src/traits/mod.rs | 8 +++----- .../src/traits/select/confirmation.rs | 6 ++---- .../rustc_trait_selection/src/traits/util.rs | 6 ++---- compiler/rustc_typeck/src/check/_match.rs | 2 +- compiler/rustc_typeck/src/check/cast.rs | 2 +- compiler/rustc_typeck/src/check/method/probe.rs | 8 +++++++- .../rustc_typeck/src/check/method/suggest.rs | 1 - compiler/rustc_typeck/src/check/upvar.rs | 6 +++--- compiler/rustc_typeck/src/check/wfcheck.rs | 2 +- src/librustdoc/clean/auto_trait.rs | 5 +---- .../clippy_lints/src/bool_assert_comparison.rs | 2 +- src/tools/clippy/clippy_utils/src/ty.rs | 2 +- 24 files changed, 47 insertions(+), 70 deletions(-) diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 6a8c340371ac3..7d5d1d02c040f 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -572,7 +572,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { let tcx = self.tcx(); let trait_ref = ty::TraitRef { def_id: tcx.require_lang_item(LangItem::Copy, Some(self.last_span)), - substs: tcx.mk_substs_trait(place_ty.ty, &[], ty::ConstnessArg::Not), + substs: tcx.mk_substs_trait(place_ty.ty, &[]), }; // To have a `Copy` operand, the type `T` of the @@ -1304,7 +1304,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { if !self.unsized_feature_enabled() { let trait_ref = ty::TraitRef { def_id: tcx.require_lang_item(LangItem::Sized, Some(self.last_span)), - substs: tcx.mk_substs_trait(place_ty, &[], ty::ConstnessArg::Not), + substs: tcx.mk_substs_trait(place_ty, &[]), }; self.prove_trait_ref( trait_ref, @@ -1894,7 +1894,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { let ty = place.ty(body, tcx).ty; let trait_ref = ty::TraitRef::new( tcx.require_lang_item(LangItem::Copy, Some(span)), - tcx.mk_substs_trait(ty, &[], ty::ConstnessArg::Not), + tcx.mk_substs_trait(ty, &[]), ); self.prove_trait_ref( @@ -1910,7 +1910,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { &Rvalue::NullaryOp(_, ty) => { let trait_ref = ty::TraitRef { def_id: tcx.require_lang_item(LangItem::Sized, Some(self.last_span)), - substs: tcx.mk_substs_trait(ty, &[], ty::ConstnessArg::Not), + substs: tcx.mk_substs_trait(ty, &[]), }; self.prove_trait_ref( @@ -1925,7 +1925,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { let trait_ref = ty::TraitRef { def_id: tcx.require_lang_item(LangItem::Sized, Some(self.last_span)), - substs: tcx.mk_substs_trait(*ty, &[], ty::ConstnessArg::Not), + substs: tcx.mk_substs_trait(*ty, &[]), }; self.prove_trait_ref( @@ -2027,11 +2027,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { def_id: tcx .require_lang_item(LangItem::CoerceUnsized, Some(self.last_span)), // TODO: pick constness arg from context - substs: tcx.mk_substs_trait( - op.ty(body, tcx), - &[ty.into()], - ty::ConstnessArg::Not, - ), + substs: tcx.mk_substs_trait(op.ty(body, tcx), &[ty.into()]), }; self.prove_trait_ref( 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 718a863b1c70b..b1aa8448678a3 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs @@ -161,7 +161,7 @@ impl Qualif for NeedsNonConstDrop { ty::Binder::dummy(ty::TraitPredicate { trait_ref: ty::TraitRef { def_id: destruct, - substs: cx.tcx.mk_substs_trait(ty, &[], ty::ConstnessArg::Required), + substs: cx.tcx.mk_substs_trait(ty, &[ty::ConstnessArg::Required.into()]), }, polarity: ty::ImplPolarity::Positive, }), diff --git a/compiler/rustc_infer/src/traits/engine.rs b/compiler/rustc_infer/src/traits/engine.rs index 034f790c86af1..fafedf4603d23 100644 --- a/compiler/rustc_infer/src/traits/engine.rs +++ b/compiler/rustc_infer/src/traits/engine.rs @@ -27,10 +27,7 @@ pub trait TraitEngine<'tcx>: 'tcx { def_id: DefId, cause: ObligationCause<'tcx>, ) { - let trait_ref = ty::TraitRef { - def_id, - substs: infcx.tcx.mk_substs_trait(ty, &[], ty::ConstnessArg::Param), - }; + let trait_ref = ty::TraitRef { def_id, substs: infcx.tcx.mk_substs_trait(ty, &[]) }; self.register_predicate_obligation( infcx, Obligation { diff --git a/compiler/rustc_middle/src/ty/adjustment.rs b/compiler/rustc_middle/src/ty/adjustment.rs index 76afca6226034..d36cf2fe3f8d0 100644 --- a/compiler/rustc_middle/src/ty/adjustment.rs +++ b/compiler/rustc_middle/src/ty/adjustment.rs @@ -129,7 +129,7 @@ impl<'tcx> OverloadedDeref<'tcx> { .find(|m| m.kind == ty::AssocKind::Fn) .unwrap() .def_id; - (method_def_id, tcx.mk_substs_trait(source, &[], ty::ConstnessArg::Not)) + (method_def_id, tcx.mk_substs_trait(source, &[])) } } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index fbe61a6c9258f..09ec2a95674f1 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2817,20 +2817,11 @@ impl<'tcx> TyCtxt<'tcx> { self_ty: Ty<'tcx>, rest: &[GenericArg<'tcx>], ) -> SubstsRef<'tcx> { - self.mk_substs_trait(self_ty, rest, ty::ConstnessArg::Not) + self.mk_substs_trait(self_ty, rest) } - pub fn mk_substs_trait( - self, - self_ty: Ty<'tcx>, - rest: &[GenericArg<'tcx>], - constness: ty::ConstnessArg, - ) -> SubstsRef<'tcx> { - self.mk_substs( - iter::once(self_ty.into()) - .chain(rest.iter().cloned()) - .chain(iter::once(constness.into())), - ) + pub fn mk_substs_trait(self, self_ty: Ty<'tcx>, rest: &[GenericArg<'tcx>]) -> SubstsRef<'tcx> { + self.mk_substs(iter::once(self_ty.into()).chain(rest.iter().cloned())) } pub fn mk_bound_variable_kinds< diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index cc635c18ccbfa..2c257c330a4ec 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -537,7 +537,7 @@ impl<'tcx> Instance<'tcx> { let sig = tcx.try_normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), sig).ok()?; assert_eq!(sig.inputs().len(), 1); - let substs = tcx.mk_substs_trait(self_ty, &[sig.inputs()[0].into()], ty::ConstnessArg::Not); + let substs = tcx.mk_substs_trait(self_ty, &[sig.inputs()[0].into()]); debug!("fn_once_adapter_shim: self_ty={:?} sig={:?}", self_ty, sig); Some(Instance { def, substs }) diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index c9c3b973d4fbd..aae22c911b824 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -916,10 +916,7 @@ impl<'tcx> ExistentialTraitRef<'tcx> { // otherwise the escaping vars would be captured by the binder // debug_assert!(!self_ty.has_escaping_bound_vars()); - ty::TraitRef { - def_id: self.def_id, - substs: tcx.mk_substs_trait(self_ty, self.substs, ty::ConstnessArg::Not), - } + ty::TraitRef { def_id: self.def_id, substs: tcx.mk_substs_trait(self_ty, self.substs) } } } @@ -1460,7 +1457,7 @@ impl<'tcx> ExistentialProjection<'tcx> { ty::ProjectionPredicate { projection_ty: ty::ProjectionTy { item_def_id: self.item_def_id, - substs: tcx.mk_substs_trait(self_ty, self.substs, ty::ConstnessArg::Not), + substs: tcx.mk_substs_trait(self_ty, self.substs), }, term: self.term, } diff --git a/compiler/rustc_mir_build/src/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs index 70983c79ac6e7..598da80c574af 100644 --- a/compiler/rustc_mir_build/src/build/matches/test.rs +++ b/compiler/rustc_mir_build/src/build/matches/test.rs @@ -820,7 +820,7 @@ fn trait_method<'tcx>( self_ty: Ty<'tcx>, params: &[GenericArg<'tcx>], ) -> ConstantKind<'tcx> { - let substs = tcx.mk_substs_trait(self_ty, params, ty::ConstnessArg::Not); + let substs = tcx.mk_substs_trait(self_ty, params); // The unhygienic comparison here is acceptable because this is only // used on known traits. diff --git a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs index 3833a6dde4f9e..c0b0cc3c591b0 100644 --- a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs +++ b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs @@ -616,7 +616,7 @@ where let drop_trait = tcx.require_lang_item(LangItem::Drop, None); let drop_fn = tcx.associated_item_def_ids(drop_trait)[0]; let ty = self.place_ty(self.place); - let substs = tcx.mk_substs_trait(ty, &[], ty::ConstnessArg::Not); + let substs = tcx.mk_substs_trait(ty, &[]); let ref_ty = tcx.mk_ref(tcx.lifetimes.re_erased, ty::TypeAndMut { ty, mutbl: hir::Mutability::Mut }); diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index 36192c6a2528d..f3153a6482048 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -342,7 +342,7 @@ impl<'tcx> CloneShimBuilder<'tcx> { // we must subst the self_ty because it's // otherwise going to be TySelf and we can't index // or access fields of a Place of type TySelf. - let substs = tcx.mk_substs_trait(self_ty, &[], ty::ConstnessArg::Not); + let substs = tcx.mk_substs_trait(self_ty, &[]); let sig = tcx.bound_fn_sig(def_id).subst(tcx, substs); let sig = tcx.erase_late_bound_regions(sig); let span = tcx.def_span(def_id); @@ -423,7 +423,7 @@ impl<'tcx> CloneShimBuilder<'tcx> { ) { let tcx = self.tcx; - let substs = tcx.mk_substs_trait(ty, &[], ty::ConstnessArg::Not); + let substs = tcx.mk_substs_trait(ty, &[]); // `func == Clone::clone(&ty) -> ty` let func_ty = tcx.mk_fn_def(self.def_id, substs); @@ -529,8 +529,7 @@ fn build_call_shim<'tcx>( // Create substitutions for the `Self` and `Args` generic parameters of the shim body. let arg_tup = tcx.mk_tup(untuple_args.iter()); - let sig_substs = - tcx.mk_substs_trait(ty, &[ty::subst::GenericArg::from(arg_tup)], ty::ConstnessArg::Not); + let sig_substs = tcx.mk_substs_trait(ty, &[ty::subst::GenericArg::from(arg_tup)]); (Some(sig_substs), Some(untuple_args)) } else { diff --git a/compiler/rustc_monomorphize/src/lib.rs b/compiler/rustc_monomorphize/src/lib.rs index bb525ce3284bb..ef4560b5ec48e 100644 --- a/compiler/rustc_monomorphize/src/lib.rs +++ b/compiler/rustc_monomorphize/src/lib.rs @@ -29,7 +29,7 @@ fn custom_coerce_unsize_info<'tcx>( let trait_ref = ty::Binder::dummy(ty::TraitRef { def_id, - substs: tcx.mk_substs_trait(source_ty, &[target_ty.into()], ty::ConstnessArg::Not), + substs: tcx.mk_substs_trait(source_ty, &[target_ty.into()]), }); match tcx.codegen_fulfill_obligation((ty::ParamEnv::reveal_all(), trait_ref)) { 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 8453c460476c1..d9ae26adc18f3 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -1275,9 +1275,10 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { &self, param_env: ty::ParamEnv<'tcx>, ty: ty::Binder<'tcx, Ty<'tcx>>, - constness: ty::ConstnessArg, + _constness: ty::ConstnessArg, polarity: ty::ImplPolarity, ) -> Result<(ty::ClosureKind, ty::Binder<'tcx, Ty<'tcx>>), ()> { + // TODO: handle constness once the fn traits are const_trait self.commit_if_ok(|_| { for trait_def_id in [ self.tcx.lang_items().fn_trait(), @@ -1291,7 +1292,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { span: DUMMY_SP, kind: TypeVariableOriginKind::MiscVariable, }); - let substs = self.tcx.mk_substs_trait(ty.skip_binder(), &[var.into()], constness); + let substs = self.tcx.mk_substs_trait(ty.skip_binder(), &[var.into()]); let obligation = Obligation::new( ObligationCause::dummy(), param_env, diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 00be2c3a69c68..7678e2dbf13cb 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -137,10 +137,8 @@ pub fn type_known_to_meet_bound_modulo_regions<'a, 'tcx>( infcx.tcx.def_path_str(def_id) ); - let trait_ref = ty::Binder::dummy(ty::TraitRef { - def_id, - substs: infcx.tcx.mk_substs_trait(ty, &[], ty::ConstnessArg::Not), - }); + let trait_ref = + ty::Binder::dummy(ty::TraitRef { def_id, substs: infcx.tcx.mk_substs_trait(ty, &[]) }); let obligation = Obligation { param_env, cause: ObligationCause::misc(span, hir::CRATE_HIR_ID), @@ -803,7 +801,7 @@ pub fn vtable_trait_upcasting_coercion_new_vptr_slot<'tcx>( let trait_ref = ty::TraitRef { def_id: unsize_trait_did, - substs: tcx.mk_substs_trait(source, &[target.into()], ty::ConstnessArg::Not), + substs: tcx.mk_substs_trait(source, &[target.into()]), }; let obligation = Obligation::new( ObligationCause::dummy(), diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 92ffd415c8e9f..4e556c99d9aae 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -1207,8 +1207,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { .require_lang_item(LangItem::Destruct, None), substs: self.tcx().mk_substs_trait( nested_ty, - &[], - ty::ConstnessArg::Required, + &[ty::ConstnessArg::Required.into()], ), }, polarity: ty::ImplPolarity::Positive, @@ -1236,8 +1235,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { def_id: self.tcx().require_lang_item(LangItem::Destruct, None), substs: self.tcx().mk_substs_trait( nested_ty, - &[], - ty::ConstnessArg::Required, + &[ty::ConstnessArg::Required.into()], ), }, polarity: ty::ImplPolarity::Positive, diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index 6c3efa35fb0bb..c874e34a24e5e 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -268,10 +268,8 @@ pub fn predicate_for_trait_def<'tcx>( self_ty: Ty<'tcx>, params: &[GenericArg<'tcx>], ) -> PredicateObligation<'tcx> { - let trait_ref = ty::TraitRef { - def_id: trait_def_id, - substs: tcx.mk_substs_trait(self_ty, params, ty::ConstnessArg::Not), - }; + let trait_ref = + ty::TraitRef { def_id: trait_def_id, substs: tcx.mk_substs_trait(self_ty, params) }; predicate_for_trait_ref(tcx, cause, param_env, trait_ref, recursion_depth) } diff --git a/compiler/rustc_typeck/src/check/_match.rs b/compiler/rustc_typeck/src/check/_match.rs index c615b4bab8d22..82e2fe237cd07 100644 --- a/compiler/rustc_typeck/src/check/_match.rs +++ b/compiler/rustc_typeck/src/check/_match.rs @@ -521,7 +521,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty::Binder::dummy(ty::PredicateKind::Trait(ty::TraitPredicate { trait_ref: ty::TraitRef { def_id: t.def_id(), - substs: self.infcx.tcx.mk_substs_trait(outer_ty, &[], t.constness()), + substs: self.infcx.tcx.mk_substs_trait(outer_ty, &[]), }, polarity: t.polarity, })); diff --git a/compiler/rustc_typeck/src/check/cast.rs b/compiler/rustc_typeck/src/check/cast.rs index dfb3effe20df2..66dd558249052 100644 --- a/compiler/rustc_typeck/src/check/cast.rs +++ b/compiler/rustc_typeck/src/check/cast.rs @@ -495,7 +495,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { let ty = fcx.tcx.erase_regions(ty); let expr_ty = fcx.resolve_vars_if_possible(self.expr_ty); let expr_ty = fcx.tcx.erase_regions(expr_ty); - let ty_params = fcx.tcx.mk_substs_trait(expr_ty, &[], ty::ConstnessArg::Not); + let ty_params = fcx.tcx.mk_substs_trait(expr_ty, &[]); if fcx .infcx .type_implements_trait(from_trait, ty, ty_params, fcx.param_env) diff --git a/compiler/rustc_typeck/src/check/method/probe.rs b/compiler/rustc_typeck/src/check/method/probe.rs index 3a7dce4ab64cf..232d7ebf8ba35 100644 --- a/compiler/rustc_typeck/src/check/method/probe.rs +++ b/compiler/rustc_typeck/src/check/method/probe.rs @@ -1781,7 +1781,13 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { // method yet. So create fresh variables here for those too, // if there are any. let generics = self.tcx.generics_of(method); - assert_eq!(substs.len(), generics.parent_count as usize); + assert_eq!( + substs.len(), + generics.parent_count as usize, + "{:#?} vs {:#?}", + substs, + generics.params + ); let xform_fn_sig = if generics.params.is_empty() { fn_sig.subst(self.tcx, substs) diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs index 88acf77a1b7f9..345cdef2a31b3 100644 --- a/compiler/rustc_typeck/src/check/method/suggest.rs +++ b/compiler/rustc_typeck/src/check/method/suggest.rs @@ -67,7 +67,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { span, }) .into()], - ty::ConstnessArg::Not, ); let trait_ref = ty::TraitRef::new(fn_once, fn_once_substs); let poly_trait_ref = ty::Binder::dummy(trait_ref); diff --git a/compiler/rustc_typeck/src/check/upvar.rs b/compiler/rustc_typeck/src/check/upvar.rs index efa1682170c07..74546ed908085 100644 --- a/compiler/rustc_typeck/src/check/upvar.rs +++ b/compiler/rustc_typeck/src/check/upvar.rs @@ -980,7 +980,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .type_implements_trait( check_trait, ty, - self.tcx.mk_substs_trait(ty, &[], ty::ConstnessArg::Not), + self.tcx.mk_substs_trait(ty, &[]), self.param_env, ) .must_apply_modulo_regions() @@ -1009,7 +1009,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .type_implements_trait( check_trait, ty, - self.tcx.mk_substs_trait(ty, &[], ty::ConstnessArg::Not), + self.tcx.mk_substs_trait(ty, &[]), self.param_env, ) .must_apply_modulo_regions() @@ -1355,7 +1355,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let is_drop_defined_for_ty = |ty: Ty<'tcx>| { let drop_trait = self.tcx.require_lang_item(hir::LangItem::Drop, Some(closure_span)); - let ty_params = self.tcx.mk_substs_trait(base_path_ty, &[], ty::ConstnessArg::Not); + let ty_params = self.tcx.mk_substs_trait(base_path_ty, &[]); self.infcx .type_implements_trait( drop_trait, diff --git a/compiler/rustc_typeck/src/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs index 26a57a271a76a..5ee52981856b7 100644 --- a/compiler/rustc_typeck/src/check/wfcheck.rs +++ b/compiler/rustc_typeck/src/check/wfcheck.rs @@ -1698,7 +1698,7 @@ fn receiver_is_implemented<'tcx>( ) -> bool { let trait_ref = ty::Binder::dummy(ty::TraitRef { def_id: receiver_trait_def_id, - substs: fcx.tcx.mk_substs_trait(receiver_ty, &[], ty::ConstnessArg::Not), + substs: fcx.tcx.mk_substs_trait(receiver_ty, &[]), }); let obligation = traits::Obligation::new(cause, fcx.param_env, trait_ref.to_predicate(fcx.tcx)); diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index c031e4c4e5e9e..9c02e4d9aeca8 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -40,10 +40,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { discard_positive_impl: bool, ) -> Option { let tcx = self.cx.tcx; - let trait_ref = ty::TraitRef { - def_id: trait_def_id, - substs: tcx.mk_substs_trait(ty, &[], ty::ConstnessArg::Not), - }; + let trait_ref = ty::TraitRef { def_id: trait_def_id, substs: tcx.mk_substs_trait(ty, &[]) }; if !self.cx.generated_synthetics.insert((ty, trait_def_id)) { debug!("get_auto_trait_impl_for({:?}): already generated, aborting", trait_ref); return None; diff --git a/src/tools/clippy/clippy_lints/src/bool_assert_comparison.rs b/src/tools/clippy/clippy_lints/src/bool_assert_comparison.rs index 1dc5afebd9e87..95abe8aa59fbe 100644 --- a/src/tools/clippy/clippy_lints/src/bool_assert_comparison.rs +++ b/src/tools/clippy/clippy_lints/src/bool_assert_comparison.rs @@ -59,7 +59,7 @@ fn is_impl_not_trait_with_bool_out(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { ) }) .map_or(false, |assoc_item| { - let proj = cx.tcx.mk_projection(assoc_item.def_id, cx.tcx.mk_substs_trait(ty, &[], ty::ConstnessArg::Not)); + let proj = cx.tcx.mk_projection(assoc_item.def_id, cx.tcx.mk_substs_trait(ty, &[])); let nty = cx.tcx.normalize_erasing_regions(cx.param_env, proj); nty.is_bool() diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs index a02c406f8d79e..673da988393f1 100644 --- a/src/tools/clippy/clippy_utils/src/ty.rs +++ b/src/tools/clippy/clippy_utils/src/ty.rs @@ -80,7 +80,7 @@ pub fn get_associated_type<'tcx>( .associated_items(trait_id) .find_by_name_and_kind(cx.tcx, Ident::from_str(name), ty::AssocKind::Type, trait_id) .and_then(|assoc| { - let proj = cx.tcx.mk_projection(assoc.def_id, cx.tcx.mk_substs_trait(ty, &[], ty::ConstnessArg::Not)); + let proj = cx.tcx.mk_projection(assoc.def_id, cx.tcx.mk_substs_trait(ty, &[])); cx.tcx.try_normalize_erasing_regions(cx.param_env, proj).ok() }) } From 1727172847c54a484cd50aa5c22fbbb4daa8d842 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 11 May 2022 10:50:26 +0000 Subject: [PATCH 26/51] Remove the helper-methods for mk_substs_trait --- compiler/rustc_middle/src/ty/context.rs | 17 ----------------- compiler/rustc_middle/src/ty/sty.rs | 2 +- compiler/rustc_trait_selection/src/autoderef.rs | 2 +- compiler/rustc_trait_selection/src/infer.rs | 6 ++---- .../src/traits/auto_trait.rs | 5 ++--- .../src/traits/error_reporting/mod.rs | 4 ++-- .../src/traits/error_reporting/suggestions.rs | 6 +++--- .../src/traits/object_safety.rs | 4 ++-- .../rustc_trait_selection/src/traits/project.rs | 4 ++-- .../src/traits/relationships.rs | 2 +- .../src/traits/select/candidate_assembly.rs | 2 +- .../src/traits/select/confirmation.rs | 2 +- .../rustc_trait_selection/src/traits/util.rs | 4 ++-- compiler/rustc_trait_selection/src/traits/wf.rs | 2 +- compiler/rustc_traits/src/chalk/lowering.rs | 6 +++--- compiler/rustc_ty_utils/src/ty.rs | 2 +- compiler/rustc_typeck/src/bounds.rs | 2 +- .../src/check/fn_ctxt/suggestions.rs | 2 +- compiler/rustc_typeck/src/collect.rs | 7 +++++-- 19 files changed, 32 insertions(+), 49 deletions(-) diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 09ec2a95674f1..1b6ae3cb55813 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2803,23 +2803,6 @@ impl<'tcx> TyCtxt<'tcx> { iter.intern_with(|xs| self.intern_place_elems(xs)) } - pub fn mk_substs_trait_no_append( - self, - self_ty: Ty<'tcx>, - rest: &[GenericArg<'tcx>], - ) -> SubstsRef<'tcx> { - assert!(matches!(rest.last().unwrap().unpack(), GenericArgKind::Constness(_))); - self.mk_substs(iter::once(self_ty.into()).chain(rest.iter().cloned())) - } - - pub fn mk_substs_trait_non_const( - self, - self_ty: Ty<'tcx>, - rest: &[GenericArg<'tcx>], - ) -> SubstsRef<'tcx> { - self.mk_substs_trait(self_ty, rest) - } - pub fn mk_substs_trait(self, self_ty: Ty<'tcx>, rest: &[GenericArg<'tcx>]) -> SubstsRef<'tcx> { self.mk_substs(iter::once(self_ty.into()).chain(rest.iter().cloned())) } diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index aae22c911b824..ea73d71bd4764 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -699,7 +699,7 @@ impl<'tcx> Binder<'tcx, ExistentialPredicate<'tcx>> { ExistentialPredicate::AutoTrait(did) => { let trait_ref = self.rebind(ty::TraitRef { def_id: did, - substs: tcx.mk_substs_trait_non_const(self_ty, &[]), + substs: tcx.mk_substs_trait(self_ty, &[]), }); trait_ref.to_predicate(tcx) } diff --git a/compiler/rustc_trait_selection/src/autoderef.rs b/compiler/rustc_trait_selection/src/autoderef.rs index 4ff47301ef1f5..b6feecef33e2e 100644 --- a/compiler/rustc_trait_selection/src/autoderef.rs +++ b/compiler/rustc_trait_selection/src/autoderef.rs @@ -127,7 +127,7 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> { // let trait_ref = TraitRef { def_id: tcx.lang_items().deref_trait()?, - substs: tcx.mk_substs_trait_non_const(ty, &[]), + substs: tcx.mk_substs_trait(ty, &[]), }; let cause = traits::ObligationCause::misc(self.span, self.body_id); diff --git a/compiler/rustc_trait_selection/src/infer.rs b/compiler/rustc_trait_selection/src/infer.rs index 7c3e138eca732..c154f81c5775b 100644 --- a/compiler/rustc_trait_selection/src/infer.rs +++ b/compiler/rustc_trait_selection/src/infer.rs @@ -108,10 +108,8 @@ impl<'cx, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'cx, 'tcx> { trait_def_id, ty, params, param_env ); - let trait_ref = ty::TraitRef { - def_id: trait_def_id, - substs: self.tcx.mk_substs_trait_non_const(ty, params), - }; + let trait_ref = + ty::TraitRef { def_id: trait_def_id, substs: self.tcx.mk_substs_trait(ty, params) }; let obligation = traits::Obligation { cause: traits::ObligationCause::dummy(), diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index 6d5516eb8856d..ca3ba46cd0f50 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -85,8 +85,7 @@ impl<'tcx> AutoTraitFinder<'tcx> { ) -> AutoTraitResult { let tcx = self.tcx; - let trait_ref = - ty::TraitRef { def_id: trait_did, substs: tcx.mk_substs_trait_non_const(ty, &[]) }; + let trait_ref = ty::TraitRef { def_id: trait_did, substs: tcx.mk_substs_trait(ty, &[]) }; let trait_pred = ty::Binder::dummy(trait_ref); @@ -298,7 +297,7 @@ impl<'tcx> AutoTraitFinder<'tcx> { predicates.push_back(ty::Binder::dummy(ty::TraitPredicate { trait_ref: ty::TraitRef { def_id: trait_did, - substs: infcx.tcx.mk_substs_trait_non_const(ty, &[]), + substs: infcx.tcx.mk_substs_trait(ty, &[]), }, // Auto traits are positive polarity: ty::ImplPolarity::Positive, 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 d9ae26adc18f3..b914135543b47 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -728,7 +728,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { && fallback_has_occurred { let predicate = trait_predicate.map_bound(|mut trait_pred| { - trait_pred.trait_ref.substs = self.tcx.mk_substs_trait_no_append( + trait_pred.trait_ref.substs = self.tcx.mk_substs_trait( self.tcx.mk_unit(), &trait_pred.trait_ref.substs[1..], ); @@ -1934,7 +1934,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> { ) -> PredicateObligation<'tcx> { let trait_pred = trait_ref_and_ty.map_bound_ref(|(tr, new_self_ty)| ty::TraitPredicate { trait_ref: ty::TraitRef { - substs: self.tcx.mk_substs_trait_no_append(*new_self_ty, &tr.trait_ref.substs[1..]), + substs: self.tcx.mk_substs_trait(*new_self_ty, &tr.trait_ref.substs[1..]), ..tr.trait_ref }, ..*tr 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 efbb6cf56f5a7..6a70109aae932 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -2784,7 +2784,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { self.tcx.mk_projection( item_def_id, // Future::Output has no substs - self.tcx.mk_substs_trait(trait_pred.self_ty(), &[], ty::ConstnessArg::Not), + self.tcx.mk_substs_trait(trait_pred.self_ty(), &[]), ) }); let projection_ty = normalize_to( @@ -2873,9 +2873,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { let field_ty = field.ty(self.tcx, substs); let trait_substs = match diagnostic_name { sym::PartialEq | sym::PartialOrd => { - self.tcx.mk_substs_trait_non_const(field_ty, &[field_ty.into()]) + self.tcx.mk_substs_trait(field_ty, &[field_ty.into()]) } - _ => self.tcx.mk_substs_trait_non_const(field_ty, &[]), + _ => self.tcx.mk_substs_trait(field_ty, &[]), }; let trait_pred = trait_pred.map_bound_ref(|tr| ty::TraitPredicate { trait_ref: ty::TraitRef { diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index 5fdfb9833d980..c14cc27aded41 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -682,7 +682,7 @@ fn receiver_is_dispatchable<'tcx>( // Self: Unsize let unsize_predicate = ty::Binder::dummy(ty::TraitRef { def_id: unsize_did, - substs: tcx.mk_substs_trait_non_const(tcx.types.self_param, &[unsized_self_ty.into()]), + substs: tcx.mk_substs_trait(tcx.types.self_param, &[unsized_self_ty.into()]), }) .to_predicate(tcx); @@ -712,7 +712,7 @@ fn receiver_is_dispatchable<'tcx>( let obligation = { let predicate = ty::Binder::dummy(ty::TraitRef { def_id: dispatch_from_dyn_did, - substs: tcx.mk_substs_trait_non_const(receiver_ty, &[unsized_receiver_ty.into()]), + substs: tcx.mk_substs_trait(receiver_ty, &[unsized_receiver_ty.into()]), }) .to_predicate(tcx); diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 5daffd6898d59..39e4be063980f 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -1563,7 +1563,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( &obligation.with( ty::Binder::dummy(ty::TraitRef::new( selcx.tcx().require_lang_item(LangItem::Sized, None), - selcx.tcx().mk_substs_trait_non_const(self_ty, &[]), + selcx.tcx().mk_substs_trait(self_ty, &[]), )) .to_predicate(selcx.tcx()), ), @@ -1807,7 +1807,7 @@ fn confirm_pointee_candidate<'cx, 'tcx>( if check_is_sized { let sized_predicate = ty::Binder::dummy(ty::TraitRef::new( tcx.require_lang_item(LangItem::Sized, None), - tcx.mk_substs_trait_non_const(self_ty, &[]), + tcx.mk_substs_trait(self_ty, &[]), )) .to_poly_trait_predicate() .to_predicate(tcx); diff --git a/compiler/rustc_trait_selection/src/traits/relationships.rs b/compiler/rustc_trait_selection/src/traits/relationships.rs index 99853e0d98102..7e956786404df 100644 --- a/compiler/rustc_trait_selection/src/traits/relationships.rs +++ b/compiler/rustc_trait_selection/src/traits/relationships.rs @@ -19,7 +19,7 @@ pub(crate) fn update<'tcx, T>( let new_self_ty = infcx.tcx.types.unit; let trait_ref = ty::TraitRef { - substs: infcx.tcx.mk_substs_trait_no_append(new_self_ty, &tpred.trait_ref.substs[1..]), + substs: infcx.tcx.mk_substs_trait(new_self_ty, &tpred.trait_ref.substs[1..]), ..tpred.trait_ref }; 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 1a309221deb4d..b5eaaea885156 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -752,7 +752,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // let trait_ref = ty::TraitRef { def_id: tcx.lang_items().deref_trait()?, - substs: tcx.mk_substs_trait_non_const(ty, &[]), + substs: tcx.mk_substs_trait(ty, &[]), }; let obligation = traits::Obligation::new( diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 4e556c99d9aae..49dc01eb22861 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -958,7 +958,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // We can only make objects from sized types. let tr = ty::Binder::dummy(ty::TraitRef::new( tcx.require_lang_item(LangItem::Sized, None), - tcx.mk_substs_trait_non_const(source, &[]), + tcx.mk_substs_trait(source, &[]), )); nested.push(predicate_to_obligation(tr.to_predicate(tcx))); diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index c874e34a24e5e..24f9d56593bfb 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -342,7 +342,7 @@ pub fn closure_trait_ref_and_return_type<'tcx>( debug_assert!(!self_ty.has_escaping_bound_vars()); let trait_ref = ty::TraitRef { def_id: fn_trait_def_id, - substs: tcx.mk_substs_trait_non_const(self_ty, &[arguments_tuple.into()]), + substs: tcx.mk_substs_trait(self_ty, &[arguments_tuple.into()]), }; sig.map_bound(|sig| (trait_ref, sig.output())) } @@ -356,7 +356,7 @@ pub fn generator_trait_ref_and_outputs<'tcx>( debug_assert!(!self_ty.has_escaping_bound_vars()); let trait_ref = ty::TraitRef { def_id: fn_trait_def_id, - substs: tcx.mk_substs_trait_non_const(self_ty, &[sig.skip_binder().resume_ty.into()]), + substs: tcx.mk_substs_trait(self_ty, &[sig.skip_binder().resume_ty.into()]), }; sig.map_bound(|sig| (trait_ref, sig.yield_ty, sig.return_ty)) } diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 8804e7ce9bf61..392ff2ccad4aa 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -411,7 +411,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { let cause = self.cause(cause); let trait_ref = ty::TraitRef { def_id: self.infcx.tcx.require_lang_item(LangItem::Sized, None), - substs: self.infcx.tcx.mk_substs_trait_non_const(subty, &[]), + substs: self.infcx.tcx.mk_substs_trait(subty, &[]), }; self.out.push(traits::Obligation::with_depth( cause, diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs index 1fc587395fd36..94add86c1f097 100644 --- a/compiler/rustc_traits/src/chalk/lowering.rs +++ b/compiler/rustc_traits/src/chalk/lowering.rs @@ -672,7 +672,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Binders LowerInto<'tcx, chalk_ir::Binders LowerInto<'tcx, chalk_ir::Binders( let Some(sized_trait) = tcx.lang_items().sized_trait() else { return vec![ty] }; let sized_predicate = ty::Binder::dummy(ty::TraitRef { def_id: sized_trait, - substs: tcx.mk_substs_trait_non_const(ty, &[]), + substs: tcx.mk_substs_trait(ty, &[]), }) .to_predicate(tcx); let predicates = tcx.predicates_of(adtdef.did()).predicates; diff --git a/compiler/rustc_typeck/src/bounds.rs b/compiler/rustc_typeck/src/bounds.rs index d7aac484de9a7..8a21c39ee462f 100644 --- a/compiler/rustc_typeck/src/bounds.rs +++ b/compiler/rustc_typeck/src/bounds.rs @@ -63,7 +63,7 @@ impl<'tcx> Bounds<'tcx> { tcx.lang_items().sized_trait().map(move |sized| { let trait_ref = ty::Binder::dummy(ty::TraitRef { def_id: sized, - substs: tcx.mk_substs_trait_non_const(param_ty, &[]), + substs: tcx.mk_substs_trait(param_ty, &[]), }); (trait_ref.to_predicate(tcx), span) }) diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs index 765be5bf243b3..b0e6c542f07bd 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs @@ -851,7 +851,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { recursion_depth: 0, predicate: ty::Binder::dummy(ty::TraitRef { def_id: clone_trait_did, - substs: self.tcx.mk_substs_trait_non_const(expected_ty.into(), &[]), + substs: self.tcx.mk_substs_trait(expected_ty.into(), &[]), }) .to_predicate(self.tcx), }) diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 56343dad0cd9c..adb275976ffbc 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -1763,6 +1763,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics { } if has_constness || parent_has_constness { + trace!("adding constness param"); params.push(ty::GenericParamDef { name: Symbol::intern(""), index: type_start + i as u32, @@ -1774,7 +1775,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics { let param_def_id_to_index = params.iter().map(|param| (param.def_id, param.index)).collect(); - ty::Generics { + let generics = ty::Generics { parent: parent_def_id, parent_count, params, @@ -1782,7 +1783,9 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics { has_self: has_self || parent_has_self, has_constness: has_constness || parent_has_constness, has_late_bound_regions: has_late_bound_regions(tcx, node), - } + }; + trace!("{:#?}", generics); + generics } fn are_suggestable_generic_args(generic_args: &[hir::GenericArg<'_>]) -> bool { From 71bcd357f19e4eab62a2e1da8ea1825ae28f7e57 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 11 May 2022 10:51:42 +0000 Subject: [PATCH 27/51] Stop appending constness to all substs --- compiler/rustc_infer/src/infer/mod.rs | 1 + compiler/rustc_typeck/src/astconv/generics.rs | 14 +++------ compiler/rustc_typeck/src/astconv/mod.rs | 31 ++++++++++--------- .../rustc_typeck/src/check/fn_ctxt/_impl.rs | 6 +++- .../rustc_typeck/src/check/method/confirm.rs | 1 + 5 files changed, 29 insertions(+), 24 deletions(-) diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index e65700ee27409..bd9f118351916 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -1199,6 +1199,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { }); self.tcx.mk_const_var(const_var_id, self.tcx.type_of(param.def_id)).into() } + // TODO: this should actually figure out a yes/no answer from the context GenericParamDefKind::Constness => ty::ConstnessArg::Param.into(), } } diff --git a/compiler/rustc_typeck/src/astconv/generics.rs b/compiler/rustc_typeck/src/astconv/generics.rs index 4eece40b1203f..f9d996c781684 100644 --- a/compiler/rustc_typeck/src/astconv/generics.rs +++ b/compiler/rustc_typeck/src/astconv/generics.rs @@ -225,11 +225,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { if let Some(¶m) = params.peek() { if param.index == 0 { if let GenericParamDefKind::Type { .. } = param.kind { - substs.push( - self_ty - .map(|ty| ty.into()) - .unwrap_or_else(|| ctx.inferred_kind(None, param, true)), - ); + substs.push(self_ty.map(|ty| ty.into()).unwrap_or_else(|| { + ctx.inferred_kind(None, param, true, constness) + })); params.next(); } } @@ -278,7 +276,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { ) => { // We expected a lifetime argument, but got a type or const // argument. That means we're inferring the lifetimes. - substs.push(ctx.inferred_kind(None, param, infer_args)); + substs.push(ctx.inferred_kind(None, param, infer_args, constness)); force_infer_lt = Some((arg, param)); params.next(); } @@ -375,7 +373,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { (None, Some(¶m)) => { // If there are fewer arguments than parameters, it means // we're inferring the remaining arguments. - substs.push(ctx.inferred_kind(Some(&substs), param, infer_args)); + substs.push(ctx.inferred_kind(Some(&substs), param, infer_args, constness)); params.next(); } @@ -384,8 +382,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } } - substs.extend(constness.map(Into::into)); - tcx.intern_substs(&substs) } diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index 5f4980fdf0443..3ff4791b508a0 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -196,6 +196,7 @@ pub trait CreateSubstsForGenericArgsCtxt<'a, 'tcx> { substs: Option<&[subst::GenericArg<'tcx>]>, param: &ty::GenericParamDef, infer_args: bool, + constness: Option, ) -> subst::GenericArg<'tcx>; } @@ -492,6 +493,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { substs: Option<&[subst::GenericArg<'tcx>]>, param: &ty::GenericParamDef, infer_args: bool, + constness: Option, ) -> subst::GenericArg<'tcx> { let tcx = self.astconv.tcx(); match param.kind { @@ -568,21 +570,22 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } } GenericParamDefKind::Constness => { - match self.astconv.item_def_id() { - // no information available - // TODO: fall back to `Not`? - None => ty::ConstnessArg::Param, - Some(context) => { - if tcx.generics_of(context).has_constness_param() { - ty::ConstnessArg::Param - } else { - // TODO: should use `Required` if we're in a const context - // like `const`/`static` item initializers. - ty::ConstnessArg::Not + constness + .unwrap_or_else(|| match self.astconv.item_def_id() { + // no information available + // TODO: fall back to `Not`? + None => ty::ConstnessArg::Param, + Some(context) => { + if tcx.generics_of(context).has_constness_param() { + ty::ConstnessArg::Param + } else { + // TODO: should use `Required` if we're in a const context + // like `const`/`static` item initializers. + ty::ConstnessArg::Not + } } - } - } - .into() + }) + .into() } } } diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs index 712895fc24fa0..2f69bc4941662 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs @@ -1409,6 +1409,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { substs: Option<&[subst::GenericArg<'tcx>]>, param: &ty::GenericParamDef, infer_args: bool, + constness: Option, ) -> subst::GenericArg<'tcx> { let tcx = self.fcx.tcx(); match param.kind { @@ -1441,7 +1442,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.fcx.var_for_def(self.span, param) } } - GenericParamDefKind::Constness => self.fcx.var_for_def(self.span, param), + GenericParamDefKind::Constness => match constness { + None => self.fcx.var_for_def(self.span, param), + Some(constness) => constness.into(), + }, } } } diff --git a/compiler/rustc_typeck/src/check/method/confirm.rs b/compiler/rustc_typeck/src/check/method/confirm.rs index f2ebea68956c3..c787d97d3c493 100644 --- a/compiler/rustc_typeck/src/check/method/confirm.rs +++ b/compiler/rustc_typeck/src/check/method/confirm.rs @@ -397,6 +397,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { _substs: Option<&[subst::GenericArg<'tcx>]>, param: &ty::GenericParamDef, _infer_args: bool, + _constness: Option, ) -> subst::GenericArg<'tcx> { self.cfcx.var_for_def(self.cfcx.span, param) } From c59a58c091d9a796fdab021b3bc92ada123724d3 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 31 May 2022 15:40:55 +0000 Subject: [PATCH 28/51] Allow the constness argument anywhere in the generics list --- compiler/rustc_middle/src/ty/generics.rs | 4 +-- compiler/rustc_middle/src/ty/sty.rs | 29 +++++++++---------- .../rustc_typeck/src/check/method/probe.rs | 4 +-- compiler/rustc_typeck/src/collect.rs | 7 ++--- 4 files changed, 20 insertions(+), 24 deletions(-) diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs index 33b7189a0ce25..b1e544fa7a6bb 100644 --- a/compiler/rustc_middle/src/ty/generics.rs +++ b/compiler/rustc_middle/src/ty/generics.rs @@ -241,9 +241,7 @@ impl<'tcx> Generics { /// Returns the `ConstnessArg` pub fn has_constness_param(&'tcx self) -> bool { - self.params - .last() - .map_or(false, |param| matches!(param.kind, ty::GenericParamDefKind::Constness)) + self.params.iter().any(|param| matches!(param.kind, ty::GenericParamDefKind::Constness)) } /// Returns `true` if `params` has `impl Trait`. diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index ea73d71bd4764..cb80704bffcbd 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -816,20 +816,21 @@ impl<'tcx> TraitRef<'tcx> { } pub fn constness(self) -> ty::ConstnessArg { - match self.substs.last().expect("constness").unpack() { - ty::subst::GenericArgKind::Constness(constness) => constness, - _ => ty::ConstnessArg::Not, + for arg in self.substs.iter() { + match arg.unpack() { + ty::subst::GenericArgKind::Constness(constness) => return constness, + _ => {} + } } + ty::ConstnessArg::Not } pub fn without_const(mut self, tcx: TyCtxt<'tcx>) -> Self { if self.constness().is_const() { - self.substs = tcx.mk_substs( - self.substs - .iter() - .take(self.substs.len() - 1) - .chain(Some(ty::ConstnessArg::Not.into())), - ); + self.substs = tcx.mk_substs(self.substs.iter().map(|arg| match arg.unpack() { + ty::subst::GenericArgKind::Constness(_) => ty::ConstnessArg::Not.into(), + _ => arg, + })); } self @@ -837,12 +838,10 @@ impl<'tcx> TraitRef<'tcx> { pub fn with_const(mut self, tcx: TyCtxt<'tcx>) -> Self { if !self.constness().is_const() { - self.substs = tcx.mk_substs( - self.substs - .iter() - .take(self.substs.len() - 1) - .chain(Some(ty::ConstnessArg::Required.into())), - ); + self.substs = tcx.mk_substs(self.substs.iter().map(|arg| match arg.unpack() { + ty::subst::GenericArgKind::Constness(_) => ty::ConstnessArg::Required.into(), + _ => arg, + })); } self diff --git a/compiler/rustc_typeck/src/check/method/probe.rs b/compiler/rustc_typeck/src/check/method/probe.rs index 232d7ebf8ba35..4bbe18fe8e9a8 100644 --- a/compiler/rustc_typeck/src/check/method/probe.rs +++ b/compiler/rustc_typeck/src/check/method/probe.rs @@ -1784,9 +1784,9 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { assert_eq!( substs.len(), generics.parent_count as usize, - "{:#?} vs {:#?}", + "substs: {:#?}\ngenerics: {:#?}", substs, - generics.params + generics ); let xform_fn_sig = if generics.params.is_empty() { diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index adb275976ffbc..986d002e7fd9a 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -1633,10 +1633,9 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics { assert!(!has_self); parent_has_self = generics.has_self; own_start = generics.count() as u32; - // if parent has constness param, we do not inherit it from the parent, and we - // get it in the end instead of the middle. + // if the parent has a constness param, we inherit it from the parent parent_has_constness = generics.has_constness; - generics.parent_count + generics.params.len() - parent_has_constness as usize + generics.parent_count + generics.params.len() }); let mut params: Vec<_> = Vec::with_capacity(ast_generics.params.len() + has_self as usize); @@ -1762,7 +1761,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics { } } - if has_constness || parent_has_constness { + if has_constness && !parent_has_constness { trace!("adding constness param"); params.push(ty::GenericParamDef { name: Symbol::intern(""), From b8675a2e4be37af25ea2b0f0704bd261e85aae24 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 1 Jun 2022 09:16:34 +0000 Subject: [PATCH 29/51] HACK: Remove all const trait impls and `~const` from libcore/libstd this makes debugging much easier, as all examples are limited to ui tests --- compiler/rustc_ast/src/ptr.rs | 2 +- library/alloc/src/alloc.rs | 23 +-- library/alloc/src/borrow.rs | 5 +- library/alloc/src/boxed.rs | 78 ++++------ library/alloc/src/lib.rs | 4 - library/alloc/src/string.rs | 3 +- library/alloc/src/vec/mod.rs | 3 +- library/core/src/array/mod.rs | 22 +-- library/core/src/bool.rs | 14 +- library/core/src/borrow.rs | 15 +- library/core/src/cell.rs | 12 +- library/core/src/char/convert.rs | 12 +- library/core/src/clone.rs | 23 +-- library/core/src/cmp.rs | 2 - library/core/src/convert/mod.rs | 41 ++--- library/core/src/convert/num.rs | 18 +-- library/core/src/default.rs | 3 +- library/core/src/hash/mod.rs | 3 +- library/core/src/internal_macros.rs | 75 +-------- library/core/src/intrinsics.rs | 40 +---- library/core/src/iter/sources/empty.rs | 3 +- library/core/src/iter/traits/collect.rs | 3 +- library/core/src/lib.rs | 8 - library/core/src/marker.rs | 3 +- library/core/src/mem/manually_drop.rs | 6 +- library/core/src/mem/maybe_uninit.rs | 2 +- library/core/src/num/error.rs | 5 +- library/core/src/num/f32.rs | 125 ++------------- library/core/src/num/f64.rs | 88 +---------- library/core/src/num/nonzero.rs | 24 +-- library/core/src/num/wrapping.rs | 168 ++++++++------------ library/core/src/ops/arith.rs | 65 ++++---- library/core/src/ops/bit.rs | 57 +++---- library/core/src/ops/deref.rs | 6 +- library/core/src/option.rs | 196 +++++++----------------- library/core/src/ptr/const_ptr.rs | 16 +- library/core/src/ptr/mod.rs | 14 +- library/core/src/ptr/mut_ptr.rs | 14 +- library/core/src/ptr/non_null.rs | 17 +- library/core/src/ptr/unique.rs | 10 +- library/core/src/result.rs | 70 +++------ library/core/src/slice/index.rs | 79 ++-------- library/core/src/slice/mod.rs | 26 ++-- library/core/src/slice/raw.rs | 2 +- library/core/src/str/converts.rs | 7 +- library/core/src/str/mod.rs | 39 +---- library/core/src/str/traits.rs | 28 ++-- library/core/src/str/validations.rs | 3 +- library/core/src/sync/atomic.rs | 18 +-- library/core/src/task/poll.rs | 3 +- library/core/src/time.rs | 22 +-- 51 files changed, 408 insertions(+), 1117 deletions(-) diff --git a/compiler/rustc_ast/src/ptr.rs b/compiler/rustc_ast/src/ptr.rs index 30481eddf9160..0a93841414938 100644 --- a/compiler/rustc_ast/src/ptr.rs +++ b/compiler/rustc_ast/src/ptr.rs @@ -127,7 +127,7 @@ impl> Encodable for P { } impl P<[T]> { - pub const fn new() -> P<[T]> { + pub fn new() -> P<[T]> { P { ptr: Box::default() } } diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs index 649aeb0890dc0..a18a12183455c 100644 --- a/library/alloc/src/alloc.rs +++ b/library/alloc/src/alloc.rs @@ -14,8 +14,6 @@ use core::ptr::{self, NonNull}; #[doc(inline)] pub use core::alloc::*; -use core::marker::Destruct; - #[cfg(test)] mod tests; @@ -325,16 +323,12 @@ unsafe fn exchange_malloc(size: usize, align: usize) -> *mut u8 { #[cfg_attr(not(test), lang = "box_free")] #[inline] -#[rustc_const_unstable(feature = "const_box", issue = "92521")] // This signature has to be the same as `Box`, otherwise an ICE will happen. // When an additional parameter to `Box` is added (like `A: Allocator`), this has to be added here as // well. // For example if `Box` is changed to `struct Box(Unique, A)`, // this function has to be changed to `fn box_free(Unique, A)` as well. -pub(crate) const unsafe fn box_free( - ptr: Unique, - alloc: A, -) { +pub(crate) unsafe fn box_free(ptr: Unique, alloc: A) { unsafe { let size = size_of_val(ptr.as_ref()); let align = min_align_of_val(ptr.as_ref()); @@ -366,21 +360,12 @@ extern "Rust" { /// [`set_alloc_error_hook`]: ../../std/alloc/fn.set_alloc_error_hook.html /// [`take_alloc_error_hook`]: ../../std/alloc/fn.take_alloc_error_hook.html #[stable(feature = "global_alloc", since = "1.28.0")] -#[rustc_const_unstable(feature = "const_alloc_error", issue = "92523")] #[cfg(all(not(no_global_oom_handling), not(test)))] #[cold] -pub const fn handle_alloc_error(layout: Layout) -> ! { - const fn ct_error(_: Layout) -> ! { - panic!("allocation failed"); - } - - fn rt_error(layout: Layout) -> ! { - unsafe { - __rust_alloc_error_handler(layout.size(), layout.align()); - } +pub fn handle_alloc_error(layout: Layout) -> ! { + unsafe { + __rust_alloc_error_handler(layout.size(), layout.align()); } - - unsafe { core::intrinsics::const_eval_select((layout,), ct_error, rt_error) } } // For alloc test `std::alloc::handle_alloc_error` can be used directly. diff --git a/library/alloc/src/borrow.rs b/library/alloc/src/borrow.rs index 904a53bb4acc7..94f0b2c524b4b 100644 --- a/library/alloc/src/borrow.rs +++ b/library/alloc/src/borrow.rs @@ -329,10 +329,9 @@ impl Cow<'_, B> { } #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_deref", issue = "88955")] -impl const Deref for Cow<'_, B> +impl Deref for Cow<'_, B> where - B::Owned: ~const Borrow, + B::Owned: Borrow, { type Target = B; diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index d83bab7bbbdad..d2ee3b4668f08 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -157,7 +157,7 @@ use core::hash::{Hash, Hasher}; #[cfg(not(no_global_oom_handling))] use core::iter::FromIterator; use core::iter::{FusedIterator, Iterator}; -use core::marker::{Destruct, Unpin, Unsize}; +use core::marker::{Unpin, Unsize}; use core::mem; use core::ops::{ CoerceUnsized, Deref, DerefMut, DispatchFromDyn, Generator, GeneratorState, Receiver, @@ -373,12 +373,11 @@ impl Box { /// ``` #[cfg(not(no_global_oom_handling))] #[unstable(feature = "allocator_api", issue = "32838")] - #[rustc_const_unstable(feature = "const_box", issue = "92521")] #[must_use] #[inline] - pub const fn new_in(x: T, alloc: A) -> Self + pub fn new_in(x: T, alloc: A) -> Self where - A: ~const Allocator + ~const Destruct, + A: Allocator, { let mut boxed = Self::new_uninit_in(alloc); unsafe { @@ -403,12 +402,10 @@ impl Box { /// # Ok::<(), std::alloc::AllocError>(()) /// ``` #[unstable(feature = "allocator_api", issue = "32838")] - #[rustc_const_unstable(feature = "const_box", issue = "92521")] #[inline] - pub const fn try_new_in(x: T, alloc: A) -> Result + pub fn try_new_in(x: T, alloc: A) -> Result where - T: ~const Destruct, - A: ~const Allocator + ~const Destruct, + A: Allocator, { let mut boxed = Self::try_new_uninit_in(alloc)?; unsafe { @@ -438,13 +435,12 @@ impl Box { /// assert_eq!(*five, 5) /// ``` #[unstable(feature = "allocator_api", issue = "32838")] - #[rustc_const_unstable(feature = "const_box", issue = "92521")] #[cfg(not(no_global_oom_handling))] #[must_use] // #[unstable(feature = "new_uninit", issue = "63291")] - pub const fn new_uninit_in(alloc: A) -> Box, A> + pub fn new_uninit_in(alloc: A) -> Box, A> where - A: ~const Allocator + ~const Destruct, + A: Allocator, { let layout = Layout::new::>(); // NOTE: Prefer match over unwrap_or_else since closure sometimes not inlineable. @@ -479,10 +475,9 @@ impl Box { /// ``` #[unstable(feature = "allocator_api", issue = "32838")] // #[unstable(feature = "new_uninit", issue = "63291")] - #[rustc_const_unstable(feature = "const_box", issue = "92521")] - pub const fn try_new_uninit_in(alloc: A) -> Result, A>, AllocError> + pub fn try_new_uninit_in(alloc: A) -> Result, A>, AllocError> where - A: ~const Allocator + ~const Destruct, + A: Allocator, { let layout = Layout::new::>(); let ptr = alloc.allocate(layout)?.cast(); @@ -510,13 +505,12 @@ impl Box { /// /// [zeroed]: mem::MaybeUninit::zeroed #[unstable(feature = "allocator_api", issue = "32838")] - #[rustc_const_unstable(feature = "const_box", issue = "92521")] #[cfg(not(no_global_oom_handling))] // #[unstable(feature = "new_uninit", issue = "63291")] #[must_use] - pub const fn new_zeroed_in(alloc: A) -> Box, A> + pub fn new_zeroed_in(alloc: A) -> Box, A> where - A: ~const Allocator + ~const Destruct, + A: Allocator, { let layout = Layout::new::>(); // NOTE: Prefer match over unwrap_or_else since closure sometimes not inlineable. @@ -551,10 +545,9 @@ impl Box { /// [zeroed]: mem::MaybeUninit::zeroed #[unstable(feature = "allocator_api", issue = "32838")] // #[unstable(feature = "new_uninit", issue = "63291")] - #[rustc_const_unstable(feature = "const_box", issue = "92521")] - pub const fn try_new_zeroed_in(alloc: A) -> Result, A>, AllocError> + pub fn try_new_zeroed_in(alloc: A) -> Result, A>, AllocError> where - A: ~const Allocator + ~const Destruct, + A: Allocator, { let layout = Layout::new::>(); let ptr = alloc.allocate_zeroed(layout)?.cast(); @@ -570,12 +563,11 @@ impl Box { /// construct a (pinned) `Box` in a different way than with [`Box::new_in`]. #[cfg(not(no_global_oom_handling))] #[unstable(feature = "allocator_api", issue = "32838")] - #[rustc_const_unstable(feature = "const_box", issue = "92521")] #[must_use] #[inline(always)] - pub const fn pin_in(x: T, alloc: A) -> Pin + pub fn pin_in(x: T, alloc: A) -> Pin where - A: 'static + ~const Allocator + ~const Destruct, + A: 'static + Allocator, { Self::into_pin(Self::new_in(x, alloc)) } @@ -584,8 +576,7 @@ impl Box { /// /// This conversion does not allocate on the heap and happens in place. #[unstable(feature = "box_into_boxed_slice", issue = "71582")] - #[rustc_const_unstable(feature = "const_box", issue = "92521")] - pub const fn into_boxed_slice(boxed: Self) -> Box<[T], A> { + pub fn into_boxed_slice(boxed: Self) -> Box<[T], A> { let (raw, alloc) = Box::into_raw_with_allocator(boxed); unsafe { Box::from_raw_in(raw as *mut [T; 1], alloc) } } @@ -602,12 +593,8 @@ impl Box { /// assert_eq!(Box::into_inner(c), 5); /// ``` #[unstable(feature = "box_into_inner", issue = "80437")] - #[rustc_const_unstable(feature = "const_box", issue = "92521")] #[inline] - pub const fn into_inner(boxed: Self) -> T - where - Self: ~const Destruct, - { + pub fn into_inner(boxed: Self) -> T { *boxed } } @@ -821,9 +808,8 @@ impl Box, A> { /// assert_eq!(*five, 5) /// ``` #[unstable(feature = "new_uninit", issue = "63291")] - #[rustc_const_unstable(feature = "const_box", issue = "92521")] #[inline] - pub const unsafe fn assume_init(self) -> Box { + pub unsafe fn assume_init(self) -> Box { let (raw, alloc) = Box::into_raw_with_allocator(self); unsafe { Box::from_raw_in(raw as *mut T, alloc) } } @@ -856,9 +842,8 @@ impl Box, A> { /// } /// ``` #[unstable(feature = "new_uninit", issue = "63291")] - #[rustc_const_unstable(feature = "const_box", issue = "92521")] #[inline] - pub const fn write(mut boxed: Self, value: T) -> Box { + pub fn write(mut boxed: Self, value: T) -> Box { unsafe { (*boxed).write(value); boxed.assume_init() @@ -1101,9 +1086,8 @@ impl Box { /// /// [memory layout]: self#memory-layout #[unstable(feature = "allocator_api", issue = "32838")] - #[rustc_const_unstable(feature = "const_box", issue = "92521")] #[inline] - pub const fn into_raw_with_allocator(b: Self) -> (*mut T, A) { + pub fn into_raw_with_allocator(b: Self) -> (*mut T, A) { let (leaked, alloc) = Box::into_unique(b); (leaked.as_ptr(), alloc) } @@ -1113,10 +1097,9 @@ impl Box { issue = "none", reason = "use `Box::leak(b).into()` or `Unique::from(Box::leak(b))` instead" )] - #[rustc_const_unstable(feature = "const_box", issue = "92521")] #[inline] #[doc(hidden)] - pub const fn into_unique(b: Self) -> (Unique, A) { + pub fn into_unique(b: Self) -> (Unique, A) { // Box is recognized as a "unique pointer" by Stacked Borrows, but internally it is a // raw pointer for the type system. Turning it directly into a raw pointer would not be // recognized as "releasing" the unique pointer to permit aliased raw accesses, @@ -1174,9 +1157,8 @@ impl Box { /// assert_eq!(*static_ref, [4, 2, 3]); /// ``` #[stable(feature = "box_leak", since = "1.26.0")] - #[rustc_const_unstable(feature = "const_box", issue = "92521")] #[inline] - pub const fn leak<'a>(b: Self) -> &'a mut T + pub fn leak<'a>(b: Self) -> &'a mut T where A: 'a, { @@ -1246,7 +1228,7 @@ impl Default for Box { #[cfg(not(no_global_oom_handling))] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] -impl const Default for Box<[T]> { +impl Default for Box<[T]> { fn default() -> Self { let ptr: Unique<[T]> = Unique::<[T; 0]>::dangling(); Box(ptr, Global) @@ -1256,7 +1238,7 @@ impl const Default for Box<[T]> { #[cfg(not(no_global_oom_handling))] #[stable(feature = "default_box_extra", since = "1.17.0")] #[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] -impl const Default for Box { +impl Default for Box { fn default() -> Self { // SAFETY: This is the same as `Unique::cast` but with an unsized `U = str`. let ptr: Unique = unsafe { @@ -1452,8 +1434,7 @@ impl From for Box { } #[stable(feature = "pin", since = "1.33.0")] -#[rustc_const_unstable(feature = "const_box", issue = "92521")] -impl const From> for Pin> +impl From> for Pin> where A: 'static, { @@ -1841,8 +1822,7 @@ impl fmt::Pointer for Box { } #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_box", issue = "92521")] -impl const Deref for Box { +impl Deref for Box { type Target = T; fn deref(&self) -> &T { @@ -1851,8 +1831,7 @@ impl const Deref for Box { } #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_box", issue = "92521")] -impl const DerefMut for Box { +impl DerefMut for Box { fn deref_mut(&mut self) -> &mut T { &mut **self } @@ -2031,8 +2010,7 @@ impl AsMut for Box { * could have a method to project a Pin from it. */ #[stable(feature = "pin", since = "1.33.0")] -#[rustc_const_unstable(feature = "const_box", issue = "92521")] -impl const Unpin for Box where A: 'static {} +impl Unpin for Box where A: 'static {} #[unstable(feature = "generator_trait", issue = "43122")] impl + Unpin, R, A: Allocator> Generator for Box diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index d3816d70b635d..0ec0068420886 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -95,11 +95,9 @@ #![feature(assert_matches)] #![feature(async_iterator)] #![feature(coerce_unsized)] -#![cfg_attr(not(no_global_oom_handling), feature(const_alloc_error))] #![feature(const_box)] #![cfg_attr(not(no_global_oom_handling), feature(const_btree_new))] #![feature(const_cow_is_borrowed)] -#![feature(const_convert)] #![feature(const_size_of_val)] #![feature(const_align_of_val)] #![feature(const_ptr_read)] @@ -109,7 +107,6 @@ #![feature(core_c_str)] #![feature(core_intrinsics)] #![feature(core_ffi_c)] -#![feature(const_eval_select)] #![feature(const_pin)] #![feature(cstr_from_bytes_until_nul)] #![feature(dispatch_from_dyn)] @@ -150,7 +147,6 @@ #![feature(allow_internal_unstable)] #![feature(associated_type_bounds)] #![feature(cfg_sanitize)] -#![feature(const_deref)] #![feature(const_mut_refs)] #![feature(const_ptr_write)] #![feature(const_precise_live_drops)] diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index b1513e5e0f31c..e0be3bfef809e 100644 --- a/library/alloc/src/string.rs +++ b/library/alloc/src/string.rs @@ -2212,8 +2212,7 @@ impl_eq! { Cow<'a, str>, &'b str } impl_eq! { Cow<'a, str>, String } #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] -impl const Default for String { +impl Default for String { /// Creates an empty `String`. #[inline] fn default() -> String { diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index fa9f2131c0c1d..859e6e9710eda 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -2924,8 +2924,7 @@ unsafe impl<#[may_dangle] T, A: Allocator> Drop for Vec { } #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] -impl const Default for Vec { +impl Default for Vec { /// Creates an empty `Vec`. fn default() -> Vec { Vec::new() diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs index c9823a136bc42..badeb7f5fa666 100644 --- a/library/core/src/array/mod.rs +++ b/library/core/src/array/mod.rs @@ -134,8 +134,7 @@ impl TryFromSliceError { } #[stable(feature = "try_from_slice_error", since = "1.36.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl const From for TryFromSliceError { +impl From for TryFromSliceError { fn from(x: Infallible) -> TryFromSliceError { match x {} } @@ -158,16 +157,14 @@ impl AsMut<[T]> for [T; N] { } #[stable(feature = "array_borrow", since = "1.4.0")] -#[rustc_const_unstable(feature = "const_borrow", issue = "91522")] -impl const Borrow<[T]> for [T; N] { +impl Borrow<[T]> for [T; N] { fn borrow(&self) -> &[T] { self } } #[stable(feature = "array_borrow", since = "1.4.0")] -#[rustc_const_unstable(feature = "const_borrow", issue = "91522")] -impl const BorrowMut<[T]> for [T; N] { +impl BorrowMut<[T]> for [T; N] { fn borrow_mut(&mut self) -> &mut [T] { self } @@ -274,10 +271,9 @@ impl<'a, T, const N: usize> IntoIterator for &'a mut [T; N] { } #[stable(feature = "index_trait_on_arrays", since = "1.50.0")] -#[rustc_const_unstable(feature = "const_slice_index", issue = "none")] -impl const Index for [T; N] +impl Index for [T; N] where - [T]: ~const Index, + [T]: Index, { type Output = <[T] as Index>::Output; @@ -288,10 +284,9 @@ where } #[stable(feature = "index_trait_on_arrays", since = "1.50.0")] -#[rustc_const_unstable(feature = "const_slice_index", issue = "none")] -impl const IndexMut for [T; N] +impl IndexMut for [T; N] where - [T]: ~const IndexMut, + [T]: IndexMut, { #[inline] fn index_mut(&mut self, index: I) -> &mut Self::Output { @@ -384,8 +379,7 @@ macro_rules! array_impl_default { }; {$n:expr,} => { #[stable(since = "1.4.0", feature = "array_default")] - #[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] - impl const Default for [T; $n] { + impl Default for [T; $n] { fn default() -> [T; $n] { [] } } }; diff --git a/library/core/src/bool.rs b/library/core/src/bool.rs index f7a8aa0d92156..d4103ff38554d 100644 --- a/library/core/src/bool.rs +++ b/library/core/src/bool.rs @@ -1,7 +1,5 @@ //! impl bool {} -use crate::marker::Destruct; - impl bool { /// Returns `Some(t)` if the `bool` is [`true`](../std/keyword.true.html), /// or `None` otherwise. @@ -13,12 +11,8 @@ impl bool { /// assert_eq!(true.then_some(0), Some(0)); /// ``` #[stable(feature = "bool_to_option", since = "1.62.0")] - #[rustc_const_unstable(feature = "const_bool_to_option", issue = "91917")] #[inline] - pub const fn then_some(self, t: T) -> Option - where - T: ~const Destruct, - { + pub fn then_some(self, t: T) -> Option { if self { Some(t) } else { None } } @@ -32,12 +26,10 @@ impl bool { /// assert_eq!(true.then(|| 0), Some(0)); /// ``` #[stable(feature = "lazy_bool_to_option", since = "1.50.0")] - #[rustc_const_unstable(feature = "const_bool_to_option", issue = "91917")] #[inline] - pub const fn then(self, f: F) -> Option + pub fn then(self, f: F) -> Option where - F: ~const FnOnce() -> T, - F: ~const Destruct, + F: FnOnce() -> T, { if self { Some(f()) } else { None } } diff --git a/library/core/src/borrow.rs b/library/core/src/borrow.rs index 58eabecf3f091..f28be20aaa1e6 100644 --- a/library/core/src/borrow.rs +++ b/library/core/src/borrow.rs @@ -205,8 +205,7 @@ pub trait BorrowMut: Borrow { } #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_borrow", issue = "91522")] -impl const Borrow for T { +impl Borrow for T { #[rustc_diagnostic_item = "noop_method_borrow"] fn borrow(&self) -> &T { self @@ -214,32 +213,28 @@ impl const Borrow for T { } #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_borrow", issue = "91522")] -impl const BorrowMut for T { +impl BorrowMut for T { fn borrow_mut(&mut self) -> &mut T { self } } #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_borrow", issue = "91522")] -impl const Borrow for &T { +impl Borrow for &T { fn borrow(&self) -> &T { &**self } } #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_borrow", issue = "91522")] -impl const Borrow for &mut T { +impl Borrow for &mut T { fn borrow(&self) -> &T { &**self } } #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_borrow", issue = "91522")] -impl const BorrowMut for &mut T { +impl BorrowMut for &mut T { fn borrow_mut(&mut self) -> &mut T { &mut **self } diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index 8a37fadc56f4c..85f5af660fb28 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -321,8 +321,7 @@ impl Ord for Cell { } #[stable(feature = "cell_from", since = "1.12.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl const From for Cell { +impl From for Cell { /// Creates a new `Cell` containing the given value. fn from(t: T) -> Cell { Cell::new(t) @@ -1253,8 +1252,7 @@ impl Ord for RefCell { } #[stable(feature = "cell_from", since = "1.12.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl const From for RefCell { +impl From for RefCell { /// Creates a new `RefCell` containing the given value. fn from(t: T) -> RefCell { RefCell::new(t) @@ -1997,8 +1995,7 @@ impl Default for UnsafeCell { } #[stable(feature = "cell_from", since = "1.12.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl const From for UnsafeCell { +impl From for UnsafeCell { /// Creates a new `UnsafeCell` containing the given value. fn from(t: T) -> UnsafeCell { UnsafeCell::new(t) @@ -2087,8 +2084,7 @@ impl Default for SyncUnsafeCell { } #[unstable(feature = "sync_unsafe_cell", issue = "95439")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl const From for SyncUnsafeCell { +impl From for SyncUnsafeCell { /// Creates a new `SyncUnsafeCell` containing the given value. fn from(t: T) -> SyncUnsafeCell { SyncUnsafeCell::new(t) diff --git a/library/core/src/char/convert.rs b/library/core/src/char/convert.rs index 7c5f82f5ea49d..d085312b38143 100644 --- a/library/core/src/char/convert.rs +++ b/library/core/src/char/convert.rs @@ -27,8 +27,7 @@ pub(super) const unsafe fn from_u32_unchecked(i: u32) -> char { } #[stable(feature = "char_convert", since = "1.13.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl const From for u32 { +impl From for u32 { /// Converts a [`char`] into a [`u32`]. /// /// # Examples @@ -47,8 +46,7 @@ impl const From for u32 { } #[stable(feature = "more_char_conversions", since = "1.51.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl const From for u64 { +impl From for u64 { /// Converts a [`char`] into a [`u64`]. /// /// # Examples @@ -69,8 +67,7 @@ impl const From for u64 { } #[stable(feature = "more_char_conversions", since = "1.51.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl const From for u128 { +impl From for u128 { /// Converts a [`char`] into a [`u128`]. /// /// # Examples @@ -123,8 +120,7 @@ impl TryFrom for u8 { /// for a superset of Windows-1252 that fills the remaining blanks with corresponding /// C0 and C1 control codes. #[stable(feature = "char_convert", since = "1.13.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl const From for char { +impl From for char { /// Converts a [`u8`] into a [`char`]. /// /// # Examples diff --git a/library/core/src/clone.rs b/library/core/src/clone.rs index 06dca7e59a2a6..1ff03a7147d54 100644 --- a/library/core/src/clone.rs +++ b/library/core/src/clone.rs @@ -36,8 +36,6 @@ #![stable(feature = "rust1", since = "1.0.0")] -use crate::marker::Destruct; - /// A common trait for the ability to explicitly duplicate an object. /// /// Differs from [`Copy`] in that [`Copy`] is implicit and an inexpensive bit-wise copy, while @@ -106,7 +104,6 @@ use crate::marker::Destruct; #[lang = "clone"] #[rustc_diagnostic_item = "Clone"] #[rustc_trivial_field_reads] -#[const_trait] pub trait Clone: Sized { /// Returns a copy of the value. /// @@ -129,10 +126,7 @@ pub trait Clone: Sized { /// allocations. #[inline] #[stable(feature = "rust1", since = "1.0.0")] - fn clone_from(&mut self, source: &Self) - where - Self: ~const Destruct, - { + fn clone_from(&mut self, source: &Self) { *self = source.clone() } } @@ -183,8 +177,7 @@ mod impls { ($($t:ty)*) => { $( #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_clone", issue = "91805")] - impl const Clone for $t { + impl Clone for $t { #[inline] fn clone(&self) -> Self { *self @@ -202,8 +195,7 @@ mod impls { } #[unstable(feature = "never_type", issue = "35121")] - #[rustc_const_unstable(feature = "const_clone", issue = "91805")] - impl const Clone for ! { + impl Clone for ! { #[inline] fn clone(&self) -> Self { *self @@ -211,8 +203,7 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_clone", issue = "91805")] - impl const Clone for *const T { + impl Clone for *const T { #[inline] fn clone(&self) -> Self { *self @@ -220,8 +211,7 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_clone", issue = "91805")] - impl const Clone for *mut T { + impl Clone for *mut T { #[inline] fn clone(&self) -> Self { *self @@ -230,8 +220,7 @@ mod impls { /// Shared references can be cloned, but mutable references *cannot*! #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_clone", issue = "91805")] - impl const Clone for &T { + impl Clone for &T { #[inline] #[rustc_diagnostic_item = "noop_method_clone"] fn clone(&self) -> Self { diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs index 1d3466696ed04..fd2914b04ab35 100644 --- a/library/core/src/cmp.rs +++ b/library/core/src/cmp.rs @@ -214,7 +214,6 @@ use self::Ordering::*; append_const_msg, ) )] -#[const_trait] #[rustc_diagnostic_item = "PartialEq"] pub trait PartialEq { /// This method tests for `self` and `other` values to be equal, and is used @@ -1053,7 +1052,6 @@ impl PartialOrd for Ordering { append_const_msg, ) )] -#[const_trait] #[rustc_diagnostic_item = "PartialOrd"] pub trait PartialOrd: PartialEq { /// This method returns an ordering between `self` and `other` values if one exists. diff --git a/library/core/src/convert/mod.rs b/library/core/src/convert/mod.rs index b30c8a4aeabdd..26821794f1b06 100644 --- a/library/core/src/convert/mod.rs +++ b/library/core/src/convert/mod.rs @@ -482,10 +482,9 @@ pub trait TryFrom: Sized { // As lifts over & #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl const AsRef for &T +impl AsRef for &T where - T: ~const AsRef, + T: AsRef, { #[inline] fn as_ref(&self) -> &U { @@ -495,10 +494,9 @@ where // As lifts over &mut #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl const AsRef for &mut T +impl AsRef for &mut T where - T: ~const AsRef, + T: AsRef, { #[inline] fn as_ref(&self) -> &U { @@ -516,10 +514,9 @@ where // AsMut lifts over &mut #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl const AsMut for &mut T +impl AsMut for &mut T where - T: ~const AsMut, + T: AsMut, { #[inline] fn as_mut(&mut self) -> &mut U { @@ -537,10 +534,9 @@ where // From implies Into #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl const Into for T +impl Into for T where - U: ~const From, + U: From, { /// Calls `U::from(self)`. /// @@ -553,8 +549,7 @@ where // From (and thus Into) is reflexive #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl const From for T { +impl From for T { /// Returns the argument unchanged. fn from(t: T) -> T { t @@ -570,8 +565,7 @@ impl const From for T { #[allow(unused_attributes)] // FIXME(#58633): do a principled fix instead. #[rustc_reservation_impl = "permitting this impl would forbid us from adding \ `impl From for T` later; see rust-lang/rust#64715 for details"] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl const From for T { +impl From for T { fn from(t: !) -> T { t } @@ -579,10 +573,9 @@ impl const From for T { // TryFrom implies TryInto #[stable(feature = "try_from", since = "1.34.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl const TryInto for T +impl TryInto for T where - U: ~const TryFrom, + U: TryFrom, { type Error = U::Error; @@ -594,10 +587,9 @@ where // Infallible conversions are semantically equivalent to fallible conversions // with an uninhabited error type. #[stable(feature = "try_from", since = "1.34.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl const TryFrom for T +impl TryFrom for T where - U: ~const Into, + U: Into, { type Error = Infallible; @@ -695,7 +687,7 @@ pub enum Infallible {} #[stable(feature = "convert_infallible", since = "1.34.0")] #[rustc_const_unstable(feature = "const_clone", issue = "91805")] -impl const Clone for Infallible { +impl Clone for Infallible { fn clone(&self) -> Infallible { match *self {} } @@ -740,8 +732,7 @@ impl Ord for Infallible { } #[stable(feature = "convert_infallible", since = "1.34.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl const From for Infallible { +impl From for Infallible { fn from(x: !) -> Self { x } diff --git a/library/core/src/convert/num.rs b/library/core/src/convert/num.rs index 4fa5d129bc6af..b6303a87003b3 100644 --- a/library/core/src/convert/num.rs +++ b/library/core/src/convert/num.rs @@ -44,8 +44,7 @@ impl_float_to_int!(f64 => u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize); macro_rules! impl_from { ($Small: ty, $Large: ty, #[$attr:meta], $doc: expr) => { #[$attr] - #[rustc_const_unstable(feature = "const_num_from_num", issue = "87852")] - impl const From<$Small> for $Large { + impl From<$Small> for $Large { // Rustdocs on the impl block show a "[+] show undocumented items" toggle. // Rustdocs on functions do not. #[doc = $doc] @@ -172,8 +171,7 @@ impl_from! { f32, f64, #[stable(feature = "lossless_float_conv", since = "1.6.0" macro_rules! try_from_unbounded { ($source:ty, $($target:ty),*) => {$( #[stable(feature = "try_from", since = "1.34.0")] - #[rustc_const_unstable(feature = "const_num_from_num", issue = "87852")] - impl const TryFrom<$source> for $target { + impl TryFrom<$source> for $target { type Error = TryFromIntError; /// Try to create the target number type from a source @@ -191,8 +189,7 @@ macro_rules! try_from_unbounded { macro_rules! try_from_lower_bounded { ($source:ty, $($target:ty),*) => {$( #[stable(feature = "try_from", since = "1.34.0")] - #[rustc_const_unstable(feature = "const_num_from_num", issue = "87852")] - impl const TryFrom<$source> for $target { + impl TryFrom<$source> for $target { type Error = TryFromIntError; /// Try to create the target number type from a source @@ -214,8 +211,7 @@ macro_rules! try_from_lower_bounded { macro_rules! try_from_upper_bounded { ($source:ty, $($target:ty),*) => {$( #[stable(feature = "try_from", since = "1.34.0")] - #[rustc_const_unstable(feature = "const_num_from_num", issue = "87852")] - impl const TryFrom<$source> for $target { + impl TryFrom<$source> for $target { type Error = TryFromIntError; /// Try to create the target number type from a source @@ -237,8 +233,7 @@ macro_rules! try_from_upper_bounded { macro_rules! try_from_both_bounded { ($source:ty, $($target:ty),*) => {$( #[stable(feature = "try_from", since = "1.34.0")] - #[rustc_const_unstable(feature = "const_num_from_num", issue = "87852")] - impl const TryFrom<$source> for $target { + impl TryFrom<$source> for $target { type Error = TryFromIntError; /// Try to create the target number type from a source @@ -389,8 +384,7 @@ use crate::num::NonZeroUsize; macro_rules! nzint_impl_from { ($Small: ty, $Large: ty, #[$attr:meta], $doc: expr) => { #[$attr] - #[rustc_const_unstable(feature = "const_num_from_num", issue = "87852")] - impl const From<$Small> for $Large { + impl From<$Small> for $Large { // Rustdocs on the impl block show a "[+] show undocumented items" toggle. // Rustdocs on functions do not. #[doc = $doc] diff --git a/library/core/src/default.rs b/library/core/src/default.rs index 1ce00828bf344..89a80b0f8e438 100644 --- a/library/core/src/default.rs +++ b/library/core/src/default.rs @@ -189,8 +189,7 @@ pub macro Default($item:item) { macro_rules! default_impl { ($t:ty, $v:expr, $doc:tt) => { #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] - impl const Default for $t { + impl Default for $t { #[inline] #[doc = $doc] fn default() -> $t { diff --git a/library/core/src/hash/mod.rs b/library/core/src/hash/mod.rs index cf428e0b1cf1d..7b182b447c9ba 100644 --- a/library/core/src/hash/mod.rs +++ b/library/core/src/hash/mod.rs @@ -780,8 +780,7 @@ impl Clone for BuildHasherDefault { } #[stable(since = "1.7.0", feature = "build_hasher")] -#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] -impl const Default for BuildHasherDefault { +impl Default for BuildHasherDefault { fn default() -> BuildHasherDefault { BuildHasherDefault(marker::PhantomData) } diff --git a/library/core/src/internal_macros.rs b/library/core/src/internal_macros.rs index 5d4c9ba73951a..4597bc5502b8d 100644 --- a/library/core/src/internal_macros.rs +++ b/library/core/src/internal_macros.rs @@ -1,23 +1,10 @@ // implements the unary operator "op &T" // based on "op T" where T is expected to be `Copy`able macro_rules! forward_ref_unop { - (impl const $imp:ident, $method:ident for $t:ty) => { - forward_ref_unop!(impl const $imp, $method for $t, + (impl $imp:ident, $method:ident for $t:ty) => { + forward_ref_unop!(impl $imp, $method for $t, #[stable(feature = "rust1", since = "1.0.0")]); }; - // Equivalent to the non-const version, with the addition of `rustc_const_unstable` - (impl const $imp:ident, $method:ident for $t:ty, #[$attr:meta]) => { - #[$attr] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const $imp for &$t { - type Output = <$t as $imp>::Output; - - #[inline] - fn $method(self) -> <$t as $imp>::Output { - $imp::$method(*self) - } - } - }; (impl $imp:ident, $method:ident for $t:ty, #[$attr:meta]) => { #[$attr] impl $imp for &$t { @@ -28,51 +15,16 @@ macro_rules! forward_ref_unop { $imp::$method(*self) } } - } + }; } // implements binary operators "&T op U", "T op &U", "&T op &U" // based on "T op U" where T and U are expected to be `Copy`able macro_rules! forward_ref_binop { - (impl const $imp:ident, $method:ident for $t:ty, $u:ty) => { - forward_ref_binop!(impl const $imp, $method for $t, $u, + (impl $imp:ident, $method:ident for $t:ty, $u:ty) => { + forward_ref_binop!(impl $imp, $method for $t, $u, #[stable(feature = "rust1", since = "1.0.0")]); }; - // Equivalent to the non-const version, with the addition of `rustc_const_unstable` - (impl const $imp:ident, $method:ident for $t:ty, $u:ty, #[$attr:meta]) => { - #[$attr] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl<'a> const $imp<$u> for &'a $t { - type Output = <$t as $imp<$u>>::Output; - - #[inline] - fn $method(self, other: $u) -> <$t as $imp<$u>>::Output { - $imp::$method(*self, other) - } - } - - #[$attr] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const $imp<&$u> for $t { - type Output = <$t as $imp<$u>>::Output; - - #[inline] - fn $method(self, other: &$u) -> <$t as $imp<$u>>::Output { - $imp::$method(self, *other) - } - } - - #[$attr] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const $imp<&$u> for &$t { - type Output = <$t as $imp<$u>>::Output; - - #[inline] - fn $method(self, other: &$u) -> <$t as $imp<$u>>::Output { - $imp::$method(*self, *other) - } - } - }; (impl $imp:ident, $method:ident for $t:ty, $u:ty, #[$attr:meta]) => { #[$attr] impl<'a> $imp<$u> for &'a $t { @@ -103,7 +55,7 @@ macro_rules! forward_ref_binop { $imp::$method(*self, *other) } } - } + }; } // implements "T op= &U", based on "T op= U" @@ -113,21 +65,6 @@ macro_rules! forward_ref_op_assign { forward_ref_op_assign!(impl $imp, $method for $t, $u, #[stable(feature = "op_assign_builtins_by_ref", since = "1.22.0")]); }; - (impl const $imp:ident, $method:ident for $t:ty, $u:ty) => { - forward_ref_op_assign!(impl const $imp, $method for $t, $u, - #[stable(feature = "op_assign_builtins_by_ref", since = "1.22.0")]); - }; - // Equivalent to the non-const version, with the addition of `rustc_const_unstable` - (impl const $imp:ident, $method:ident for $t:ty, $u:ty, #[$attr:meta]) => { - #[$attr] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const $imp<&$u> for $t { - #[inline] - fn $method(&mut self, other: &$u) { - $imp::$method(self, *other); - } - } - }; (impl $imp:ident, $method:ident for $t:ty, $u:ty, #[$attr:meta]) => { #[$attr] impl $imp<&$u> for $t { diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index 2895c923adc13..ec5e37b4f5715 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -55,7 +55,6 @@ #![allow(missing_docs)] use crate::marker::{Destruct, DiscriminantKind}; -use crate::mem; // These imports are used for simplifying intra-doc links #[allow(unused_imports)] @@ -2311,43 +2310,11 @@ extern "rust-intrinsic" { /// /// So in a sense it is UB if this macro is useful, but we expect callers of `unsafe fn` to make /// the occasional mistake, and this check should help them figure things out. -#[allow_internal_unstable(const_eval_select)] // permit this to be called in stably-const fn macro_rules! assert_unsafe_precondition { - ($e:expr) => { - if cfg!(debug_assertions) { - // Use a closure so that we can capture arbitrary expressions from the invocation - let runtime = || { - if !$e { - // abort instead of panicking to reduce impact on code size - ::core::intrinsics::abort(); - } - }; - const fn comptime() {} - - ::core::intrinsics::const_eval_select((), comptime, runtime); - } - }; + ($e:expr) => {{}}; } pub(crate) use assert_unsafe_precondition; -/// Checks whether `ptr` is properly aligned with respect to -/// `align_of::()`. -pub(crate) fn is_aligned_and_not_null(ptr: *const T) -> bool { - !ptr.is_null() && ptr.addr() % mem::align_of::() == 0 -} - -/// Checks whether the regions of memory starting at `src` and `dst` of size -/// `count * size_of::()` do *not* overlap. -pub(crate) fn is_nonoverlapping(src: *const T, dst: *const T, count: usize) -> bool { - let src_usize = src.addr(); - let dst_usize = dst.addr(); - let size = mem::size_of::().checked_mul(count).unwrap(); - let diff = if src_usize > dst_usize { src_usize - dst_usize } else { dst_usize - src_usize }; - // If the absolute distance between the ptrs is at least as big as the size of the buffer, - // they do not overlap. - diff >= size -} - /// Copies `count * size_of::()` bytes from `src` to `dst`. The source /// and destination must *not* overlap. /// @@ -2711,5 +2678,8 @@ where F: ~const FnOnce, G: FnOnce + ~const Destruct, { - called_in_const.call_once(arg) + crate::mem::forget(_called_at_rt); + crate::mem::forget(arg); + crate::mem::forget(called_in_const); + panic!() } diff --git a/library/core/src/iter/sources/empty.rs b/library/core/src/iter/sources/empty.rs index 98734c527f2b9..a693e26374083 100644 --- a/library/core/src/iter/sources/empty.rs +++ b/library/core/src/iter/sources/empty.rs @@ -86,8 +86,7 @@ impl Clone for Empty { // not #[derive] because that adds a Default bound on T, // which isn't necessary. #[stable(feature = "iter_empty", since = "1.2.0")] -#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] -impl const Default for Empty { +impl Default for Empty { fn default() -> Empty { Empty(marker::PhantomData) } diff --git a/library/core/src/iter/traits/collect.rs b/library/core/src/iter/traits/collect.rs index 12ca508bed2b9..ceb40f8f05065 100644 --- a/library/core/src/iter/traits/collect.rs +++ b/library/core/src/iter/traits/collect.rs @@ -261,9 +261,8 @@ pub trait IntoIterator { fn into_iter(self) -> Self::IntoIter; } -#[rustc_const_unstable(feature = "const_intoiterator_identity", issue = "90603")] #[stable(feature = "rust1", since = "1.0.0")] -impl const IntoIterator for I { +impl IntoIterator for I { type Item = I::Item; type IntoIter = I; diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index f24a7ab61ae89..edef4520f03be 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -95,7 +95,6 @@ #![allow(explicit_outlives_requirements)] // // Library features: -#![feature(const_align_offset)] #![feature(const_align_of_val)] #![feature(const_arguments_as_str)] #![feature(const_array_into_iter_constructors)] @@ -106,12 +105,10 @@ #![feature(const_char_convert)] #![feature(const_clone)] #![feature(const_discriminant)] -#![feature(const_eval_select)] #![feature(const_float_bits_conv)] #![feature(const_float_classify)] #![feature(const_fmt_arguments_new)] #![feature(const_heap)] -#![feature(const_convert)] #![feature(const_inherent_unchecked_arith)] #![feature(const_int_unchecked_arith)] #![feature(const_intrinsic_forget)] @@ -120,10 +117,8 @@ #![feature(const_maybe_uninit_as_mut_ptr)] #![feature(const_maybe_uninit_assume_init)] #![feature(const_nonnull_new)] -#![feature(const_num_from_num)] #![feature(const_ops)] #![feature(const_option)] -#![feature(const_option_ext)] #![feature(const_pin)] #![feature(const_ptr_sub_ptr)] #![feature(const_replace)] @@ -141,7 +136,6 @@ #![feature(const_trait_impl)] #![feature(const_type_id)] #![feature(const_type_name)] -#![feature(const_default_impls)] #![feature(const_unsafecell_get_mut)] #![feature(core_panic)] #![feature(duration_consts_float)] @@ -154,8 +148,6 @@ #![feature(variant_count)] #![feature(const_array_from_ref)] #![feature(const_slice_from_ref)] -#![feature(const_slice_index)] -#![feature(const_is_char_boundary)] // // Language features: #![feature(abi_unadjusted)] diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index 2c57897956fcd..96836c9e84d37 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -525,8 +525,7 @@ macro_rules! impls { } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] - impl const Default for $t { + impl Default for $t { fn default() -> Self { Self } diff --git a/library/core/src/mem/manually_drop.rs b/library/core/src/mem/manually_drop.rs index 3d719afe49e4a..5f3d66e3773f1 100644 --- a/library/core/src/mem/manually_drop.rs +++ b/library/core/src/mem/manually_drop.rs @@ -146,8 +146,7 @@ impl ManuallyDrop { } #[stable(feature = "manually_drop", since = "1.20.0")] -#[rustc_const_unstable(feature = "const_deref", issue = "88955")] -impl const Deref for ManuallyDrop { +impl Deref for ManuallyDrop { type Target = T; #[inline(always)] fn deref(&self) -> &T { @@ -156,8 +155,7 @@ impl const Deref for ManuallyDrop { } #[stable(feature = "manually_drop", since = "1.20.0")] -#[rustc_const_unstable(feature = "const_deref", issue = "88955")] -impl const DerefMut for ManuallyDrop { +impl DerefMut for ManuallyDrop { #[inline(always)] fn deref_mut(&mut self) -> &mut T { &mut self.value diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs index b4ea536083392..b64d8e28ae60e 100644 --- a/library/core/src/mem/maybe_uninit.rs +++ b/library/core/src/mem/maybe_uninit.rs @@ -957,7 +957,7 @@ impl MaybeUninit { (&array as *const _ as *const [T; N]).read() }; - // FIXME: required to avoid `~const Destruct` bound + // FIXME: required to avoid `Destruct` bound super::forget(array); ret } diff --git a/library/core/src/num/error.rs b/library/core/src/num/error.rs index 1a223016dae0f..7c09ce2af09e2 100644 --- a/library/core/src/num/error.rs +++ b/library/core/src/num/error.rs @@ -29,15 +29,14 @@ impl fmt::Display for TryFromIntError { } #[stable(feature = "try_from", since = "1.34.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl const From for TryFromIntError { +impl From for TryFromIntError { fn from(x: Infallible) -> TryFromIntError { match x {} } } #[unstable(feature = "never_type", issue = "35121")] -impl const From for TryFromIntError { +impl From for TryFromIntError { fn from(never: !) -> TryFromIntError { // Match rather than coerce to make sure that code like // `From for TryFromIntError` above will keep working diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs index 6548ad2e514fb..21b4824126188 100644 --- a/library/core/src/num/f32.rs +++ b/library/core/src/num/f32.rs @@ -614,23 +614,6 @@ impl f32 { } } - // This operates on bits, and only bits, so it can ignore concerns about weird FPUs. - // FIXME(jubilee): In a just world, this would be the entire impl for classify, - // plus a transmute. We do not live in a just world, but we can make it more so. - #[rustc_const_unstable(feature = "const_float_classify", issue = "72505")] - const fn classify_bits(b: u32) -> FpCategory { - const EXP_MASK: u32 = 0x7f800000; - const MAN_MASK: u32 = 0x007fffff; - - match (b & MAN_MASK, b & EXP_MASK) { - (0, EXP_MASK) => FpCategory::Infinite, - (_, EXP_MASK) => FpCategory::Nan, - (0, 0) => FpCategory::Zero, - (_, 0) => FpCategory::Subnormal, - _ => FpCategory::Normal, - } - } - /// Returns `true` if `self` has a positive sign, including `+0.0`, NaNs with /// positive sign bit and positive infinity. Note that IEEE-745 doesn't assign any /// meaning to the sign bit in case of a NaN, and as Rust doesn't guarantee that @@ -893,52 +876,12 @@ impl f32 { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[stable(feature = "float_bits_conv", since = "1.20.0")] - #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")] #[inline] - pub const fn to_bits(self) -> u32 { - // SAFETY: `u32` is a plain old datatype so we can always transmute to it. - // ...sorta. - // - // It turns out that at runtime, it is possible for a floating point number - // to be subject to a floating point mode that alters nonzero subnormal numbers - // to zero on reads and writes, aka "denormals are zero" and "flush to zero". - // This is not a problem per se, but at least one tier2 platform for Rust - // actually exhibits this behavior by default. - // - // In addition, on x86 targets with SSE or SSE2 disabled and the x87 FPU enabled, - // i.e. not soft-float, the way Rust does parameter passing can actually alter - // a number that is "not infinity" to have the same exponent as infinity, - // in a slightly unpredictable manner. - // - // And, of course evaluating to a NaN value is fairly nondeterministic. - // More precisely: when NaN should be returned is knowable, but which NaN? - // So far that's defined by a combination of LLVM and the CPU, not Rust. - // This function, however, allows observing the bitstring of a NaN, - // thus introspection on CTFE. - // - // In order to preserve, at least for the moment, const-to-runtime equivalence, - // we reject any of these possible situations from happening. - #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")] - const fn ct_f32_to_u32(ct: f32) -> u32 { - match ct.classify() { - FpCategory::Nan => { - panic!("const-eval error: cannot use f32::to_bits on a NaN") - } - FpCategory::Subnormal => { - panic!("const-eval error: cannot use f32::to_bits on a subnormal number") - } - FpCategory::Infinite | FpCategory::Normal | FpCategory::Zero => { - // SAFETY: We have a normal floating point number. Now we transmute, i.e. do a bitcopy. - unsafe { mem::transmute::(ct) } - } - } - } + pub fn to_bits(self) -> u32 { // SAFETY: `u32` is a plain old datatype so we can always... uh... // ...look, just pretend you forgot what you just read. // Stability concerns. - let rt_f32_to_u32 = |rt| unsafe { mem::transmute::(rt) }; - // SAFETY: We use internal implementations that either always work or fail at compile time. - unsafe { intrinsics::const_eval_select((self,), ct_f32_to_u32, rt_f32_to_u32) } + unsafe { mem::transmute::(self) } } /// Raw transmutation from `u32`. @@ -978,55 +921,13 @@ impl f32 { /// assert_eq!(v, 12.5); /// ``` #[stable(feature = "float_bits_conv", since = "1.20.0")] - #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")] #[must_use] #[inline] - pub const fn from_bits(v: u32) -> Self { - // It turns out the safety issues with sNaN were overblown! Hooray! - // SAFETY: `u32` is a plain old datatype so we can always transmute from it - // ...sorta. - // - // It turns out that at runtime, it is possible for a floating point number - // to be subject to floating point modes that alter nonzero subnormal numbers - // to zero on reads and writes, aka "denormals are zero" and "flush to zero". - // This is not a problem usually, but at least one tier2 platform for Rust - // actually exhibits this behavior by default: thumbv7neon - // aka "the Neon FPU in AArch32 state" - // - // In addition, on x86 targets with SSE or SSE2 disabled and the x87 FPU enabled, - // i.e. not soft-float, the way Rust does parameter passing can actually alter - // a number that is "not infinity" to have the same exponent as infinity, - // in a slightly unpredictable manner. - // - // And, of course evaluating to a NaN value is fairly nondeterministic. - // More precisely: when NaN should be returned is knowable, but which NaN? - // So far that's defined by a combination of LLVM and the CPU, not Rust. - // This function, however, allows observing the bitstring of a NaN, - // thus introspection on CTFE. - // - // In order to preserve, at least for the moment, const-to-runtime equivalence, - // reject any of these possible situations from happening. - #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")] - const fn ct_u32_to_f32(ct: u32) -> f32 { - match f32::classify_bits(ct) { - FpCategory::Subnormal => { - panic!("const-eval error: cannot use f32::from_bits on a subnormal number") - } - FpCategory::Nan => { - panic!("const-eval error: cannot use f32::from_bits on NaN") - } - FpCategory::Infinite | FpCategory::Normal | FpCategory::Zero => { - // SAFETY: It's not a frumious number - unsafe { mem::transmute::(ct) } - } - } - } + pub fn from_bits(v: u32) -> Self { // SAFETY: `u32` is a plain old datatype so we can always... uh... // ...look, just pretend you forgot what you just read. // Stability concerns. - let rt_u32_to_f32 = |rt| unsafe { mem::transmute::(rt) }; - // SAFETY: We use internal implementations that either always work or fail at compile time. - unsafe { intrinsics::const_eval_select((v,), ct_u32_to_f32, rt_u32_to_f32) } + unsafe { mem::transmute::(v) } } /// Return the memory representation of this floating point number as a byte array in @@ -1044,9 +945,8 @@ impl f32 { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[stable(feature = "float_to_from_bytes", since = "1.40.0")] - #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")] #[inline] - pub const fn to_be_bytes(self) -> [u8; 4] { + pub fn to_be_bytes(self) -> [u8; 4] { self.to_bits().to_be_bytes() } @@ -1065,9 +965,8 @@ impl f32 { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[stable(feature = "float_to_from_bytes", since = "1.40.0")] - #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")] #[inline] - pub const fn to_le_bytes(self) -> [u8; 4] { + pub fn to_le_bytes(self) -> [u8; 4] { self.to_bits().to_le_bytes() } @@ -1099,9 +998,8 @@ impl f32 { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[stable(feature = "float_to_from_bytes", since = "1.40.0")] - #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")] #[inline] - pub const fn to_ne_bytes(self) -> [u8; 4] { + pub fn to_ne_bytes(self) -> [u8; 4] { self.to_bits().to_ne_bytes() } @@ -1117,10 +1015,9 @@ impl f32 { /// assert_eq!(value, 12.5); /// ``` #[stable(feature = "float_to_from_bytes", since = "1.40.0")] - #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")] #[must_use] #[inline] - pub const fn from_be_bytes(bytes: [u8; 4]) -> Self { + pub fn from_be_bytes(bytes: [u8; 4]) -> Self { Self::from_bits(u32::from_be_bytes(bytes)) } @@ -1136,10 +1033,9 @@ impl f32 { /// assert_eq!(value, 12.5); /// ``` #[stable(feature = "float_to_from_bytes", since = "1.40.0")] - #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")] #[must_use] #[inline] - pub const fn from_le_bytes(bytes: [u8; 4]) -> Self { + pub fn from_le_bytes(bytes: [u8; 4]) -> Self { Self::from_bits(u32::from_le_bytes(bytes)) } @@ -1166,10 +1062,9 @@ impl f32 { /// assert_eq!(value, 12.5); /// ``` #[stable(feature = "float_to_from_bytes", since = "1.40.0")] - #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")] #[must_use] #[inline] - pub const fn from_ne_bytes(bytes: [u8; 4]) -> Self { + pub fn from_ne_bytes(bytes: [u8; 4]) -> Self { Self::from_bits(u32::from_ne_bytes(bytes)) } diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs index 75c92c2f8834a..85550ff59400c 100644 --- a/library/core/src/num/f64.rs +++ b/library/core/src/num/f64.rs @@ -606,23 +606,6 @@ impl f64 { } } - // This operates on bits, and only bits, so it can ignore concerns about weird FPUs. - // FIXME(jubilee): In a just world, this would be the entire impl for classify, - // plus a transmute. We do not live in a just world, but we can make it more so. - #[rustc_const_unstable(feature = "const_float_classify", issue = "72505")] - const fn classify_bits(b: u64) -> FpCategory { - const EXP_MASK: u64 = 0x7ff0000000000000; - const MAN_MASK: u64 = 0x000fffffffffffff; - - match (b & MAN_MASK, b & EXP_MASK) { - (0, EXP_MASK) => FpCategory::Infinite, - (_, EXP_MASK) => FpCategory::Nan, - (0, 0) => FpCategory::Zero, - (_, 0) => FpCategory::Subnormal, - _ => FpCategory::Normal, - } - } - /// Returns `true` if `self` has a positive sign, including `+0.0`, NaNs with /// positive sign bit and positive infinity. Note that IEEE-745 doesn't assign any /// meaning to the sign bit in case of a NaN, and as Rust doesn't guarantee that @@ -907,31 +890,10 @@ impl f64 { #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")] #[inline] pub const fn to_bits(self) -> u64 { - // SAFETY: `u64` is a plain old datatype so we can always transmute to it. - // ...sorta. - // - // See the SAFETY comment in f64::from_bits for more. - #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")] - const fn ct_f64_to_u64(ct: f64) -> u64 { - match ct.classify() { - FpCategory::Nan => { - panic!("const-eval error: cannot use f64::to_bits on a NaN") - } - FpCategory::Subnormal => { - panic!("const-eval error: cannot use f64::to_bits on a subnormal number") - } - FpCategory::Infinite | FpCategory::Normal | FpCategory::Zero => { - // SAFETY: We have a normal floating point number. Now we transmute, i.e. do a bitcopy. - unsafe { mem::transmute::(ct) } - } - } - } // SAFETY: `u64` is a plain old datatype so we can always... uh... // ...look, just pretend you forgot what you just read. // Stability concerns. - let rt_f64_to_u64 = |rt| unsafe { mem::transmute::(rt) }; - // SAFETY: We use internal implementations that either always work or fail at compile time. - unsafe { intrinsics::const_eval_select((self,), ct_f64_to_u64, rt_f64_to_u64) } + unsafe { mem::transmute::(self) } } /// Raw transmutation from `u64`. @@ -975,56 +937,10 @@ impl f64 { #[must_use] #[inline] pub const fn from_bits(v: u64) -> Self { - // It turns out the safety issues with sNaN were overblown! Hooray! - // SAFETY: `u64` is a plain old datatype so we can always transmute from it - // ...sorta. - // - // It turns out that at runtime, it is possible for a floating point number - // to be subject to floating point modes that alter nonzero subnormal numbers - // to zero on reads and writes, aka "denormals are zero" and "flush to zero". - // This is not a problem usually, but at least one tier2 platform for Rust - // actually exhibits an FTZ behavior by default: thumbv7neon - // aka "the Neon FPU in AArch32 state" - // - // Even with this, not all instructions exhibit the FTZ behaviors on thumbv7neon, - // so this should load the same bits if LLVM emits the "correct" instructions, - // but LLVM sometimes makes interesting choices about float optimization, - // and other FPUs may do similar. Thus, it is wise to indulge luxuriously in caution. - // - // In addition, on x86 targets with SSE or SSE2 disabled and the x87 FPU enabled, - // i.e. not soft-float, the way Rust does parameter passing can actually alter - // a number that is "not infinity" to have the same exponent as infinity, - // in a slightly unpredictable manner. - // - // And, of course evaluating to a NaN value is fairly nondeterministic. - // More precisely: when NaN should be returned is knowable, but which NaN? - // So far that's defined by a combination of LLVM and the CPU, not Rust. - // This function, however, allows observing the bitstring of a NaN, - // thus introspection on CTFE. - // - // In order to preserve, at least for the moment, const-to-runtime equivalence, - // reject any of these possible situations from happening. - #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")] - const fn ct_u64_to_f64(ct: u64) -> f64 { - match f64::classify_bits(ct) { - FpCategory::Subnormal => { - panic!("const-eval error: cannot use f64::from_bits on a subnormal number") - } - FpCategory::Nan => { - panic!("const-eval error: cannot use f64::from_bits on NaN") - } - FpCategory::Infinite | FpCategory::Normal | FpCategory::Zero => { - // SAFETY: It's not a frumious number - unsafe { mem::transmute::(ct) } - } - } - } // SAFETY: `u64` is a plain old datatype so we can always... uh... // ...look, just pretend you forgot what you just read. // Stability concerns. - let rt_u64_to_f64 = |rt| unsafe { mem::transmute::(rt) }; - // SAFETY: We use internal implementations that either always work or fail at compile time. - unsafe { intrinsics::const_eval_select((v,), ct_u64_to_f64, rt_u64_to_f64) } + unsafe { mem::transmute::(v) } } /// Return the memory representation of this floating point number as a byte array in diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs index 92d03b724b40e..dbc7a8e9acb3a 100644 --- a/library/core/src/num/nonzero.rs +++ b/library/core/src/num/nonzero.rs @@ -85,8 +85,7 @@ macro_rules! nonzero_integers { } #[stable(feature = "from_nonzero", since = "1.31.0")] - #[rustc_const_unstable(feature = "const_num_from_num", issue = "87852")] - impl const From<$Ty> for $Int { + impl From<$Ty> for $Int { #[doc = concat!("Converts a `", stringify!($Ty), "` into an `", stringify!($Int), "`")] #[inline] fn from(nonzero: $Ty) -> Self { @@ -95,8 +94,7 @@ macro_rules! nonzero_integers { } #[stable(feature = "nonzero_bitor", since = "1.45.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const BitOr for $Ty { + impl BitOr for $Ty { type Output = Self; #[inline] fn bitor(self, rhs: Self) -> Self::Output { @@ -107,8 +105,7 @@ macro_rules! nonzero_integers { } #[stable(feature = "nonzero_bitor", since = "1.45.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const BitOr<$Int> for $Ty { + impl BitOr<$Int> for $Ty { type Output = Self; #[inline] fn bitor(self, rhs: $Int) -> Self::Output { @@ -120,8 +117,7 @@ macro_rules! nonzero_integers { } #[stable(feature = "nonzero_bitor", since = "1.45.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const BitOr<$Ty> for $Int { + impl BitOr<$Ty> for $Int { type Output = $Ty; #[inline] fn bitor(self, rhs: $Ty) -> Self::Output { @@ -133,8 +129,7 @@ macro_rules! nonzero_integers { } #[stable(feature = "nonzero_bitor", since = "1.45.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const BitOrAssign for $Ty { + impl BitOrAssign for $Ty { #[inline] fn bitor_assign(&mut self, rhs: Self) { *self = *self | rhs; @@ -142,8 +137,7 @@ macro_rules! nonzero_integers { } #[stable(feature = "nonzero_bitor", since = "1.45.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const BitOrAssign<$Int> for $Ty { + impl BitOrAssign<$Int> for $Ty { #[inline] fn bitor_assign(&mut self, rhs: $Int) { *self = *self | rhs; @@ -265,8 +259,7 @@ macro_rules! nonzero_integers_div { ( $( $Ty: ident($Int: ty); )+ ) => { $( #[stable(feature = "nonzero_div", since = "1.51.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Div<$Ty> for $Int { + impl Div<$Ty> for $Int { type Output = $Int; /// This operation rounds towards zero, /// truncating any fractional part of the exact result, and cannot panic. @@ -279,8 +272,7 @@ macro_rules! nonzero_integers_div { } #[stable(feature = "nonzero_div", since = "1.51.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Rem<$Ty> for $Int { + impl Rem<$Ty> for $Int { type Output = $Int; /// This operation satisfies `n % d == n - (n / d) * d`, and cannot panic. #[inline] diff --git a/library/core/src/num/wrapping.rs b/library/core/src/num/wrapping.rs index 5353d900e7662..ed354a2e50bda 100644 --- a/library/core/src/num/wrapping.rs +++ b/library/core/src/num/wrapping.rs @@ -87,8 +87,7 @@ impl fmt::UpperHex for Wrapping { macro_rules! sh_impl_signed { ($t:ident, $f:ident) => { #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Shl<$f> for Wrapping<$t> { + impl Shl<$f> for Wrapping<$t> { type Output = Wrapping<$t>; #[inline] @@ -100,22 +99,20 @@ macro_rules! sh_impl_signed { } } } - forward_ref_binop! { impl const Shl, shl for Wrapping<$t>, $f, + forward_ref_binop! { impl Shl, shl for Wrapping<$t>, $f, #[stable(feature = "wrapping_ref_ops", since = "1.39.0")] } #[stable(feature = "op_assign_traits", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const ShlAssign<$f> for Wrapping<$t> { + impl ShlAssign<$f> for Wrapping<$t> { #[inline] fn shl_assign(&mut self, other: $f) { *self = *self << other; } } - forward_ref_op_assign! { impl const ShlAssign, shl_assign for Wrapping<$t>, $f } + forward_ref_op_assign! { impl ShlAssign, shl_assign for Wrapping<$t>, $f } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Shr<$f> for Wrapping<$t> { + impl Shr<$f> for Wrapping<$t> { type Output = Wrapping<$t>; #[inline] @@ -127,26 +124,24 @@ macro_rules! sh_impl_signed { } } } - forward_ref_binop! { impl const Shr, shr for Wrapping<$t>, $f, + forward_ref_binop! { impl Shr, shr for Wrapping<$t>, $f, #[stable(feature = "wrapping_ref_ops", since = "1.39.0")] } #[stable(feature = "op_assign_traits", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const ShrAssign<$f> for Wrapping<$t> { + impl ShrAssign<$f> for Wrapping<$t> { #[inline] fn shr_assign(&mut self, other: $f) { *self = *self >> other; } } - forward_ref_op_assign! { impl const ShrAssign, shr_assign for Wrapping<$t>, $f } + forward_ref_op_assign! { impl ShrAssign, shr_assign for Wrapping<$t>, $f } }; } macro_rules! sh_impl_unsigned { ($t:ident, $f:ident) => { #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Shl<$f> for Wrapping<$t> { + impl Shl<$f> for Wrapping<$t> { type Output = Wrapping<$t>; #[inline] @@ -154,22 +149,20 @@ macro_rules! sh_impl_unsigned { Wrapping(self.0.wrapping_shl((other & self::shift_max::$t as $f) as u32)) } } - forward_ref_binop! { impl const Shl, shl for Wrapping<$t>, $f, + forward_ref_binop! { impl Shl, shl for Wrapping<$t>, $f, #[stable(feature = "wrapping_ref_ops", since = "1.39.0")] } #[stable(feature = "op_assign_traits", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const ShlAssign<$f> for Wrapping<$t> { + impl ShlAssign<$f> for Wrapping<$t> { #[inline] fn shl_assign(&mut self, other: $f) { *self = *self << other; } } - forward_ref_op_assign! { impl const ShlAssign, shl_assign for Wrapping<$t>, $f } + forward_ref_op_assign! { impl ShlAssign, shl_assign for Wrapping<$t>, $f } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Shr<$f> for Wrapping<$t> { + impl Shr<$f> for Wrapping<$t> { type Output = Wrapping<$t>; #[inline] @@ -177,18 +170,17 @@ macro_rules! sh_impl_unsigned { Wrapping(self.0.wrapping_shr((other & self::shift_max::$t as $f) as u32)) } } - forward_ref_binop! { impl const Shr, shr for Wrapping<$t>, $f, + forward_ref_binop! { impl Shr, shr for Wrapping<$t>, $f, #[stable(feature = "wrapping_ref_ops", since = "1.39.0")] } #[stable(feature = "op_assign_traits", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const ShrAssign<$f> for Wrapping<$t> { + impl ShrAssign<$f> for Wrapping<$t> { #[inline] fn shr_assign(&mut self, other: $f) { *self = *self >> other; } } - forward_ref_op_assign! { impl const ShrAssign, shr_assign for Wrapping<$t>, $f } + forward_ref_op_assign! { impl ShrAssign, shr_assign for Wrapping<$t>, $f } }; } @@ -217,8 +209,7 @@ sh_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize } macro_rules! wrapping_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Add for Wrapping<$t> { + impl Add for Wrapping<$t> { type Output = Wrapping<$t>; #[inline] @@ -226,32 +217,29 @@ macro_rules! wrapping_impl { Wrapping(self.0.wrapping_add(other.0)) } } - forward_ref_binop! { impl const Add, add for Wrapping<$t>, Wrapping<$t>, + forward_ref_binop! { impl Add, add for Wrapping<$t>, Wrapping<$t>, #[stable(feature = "wrapping_ref", since = "1.14.0")] } #[stable(feature = "op_assign_traits", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const AddAssign for Wrapping<$t> { + impl AddAssign for Wrapping<$t> { #[inline] fn add_assign(&mut self, other: Wrapping<$t>) { *self = *self + other; } } - forward_ref_op_assign! { impl const AddAssign, add_assign for Wrapping<$t>, Wrapping<$t> } + forward_ref_op_assign! { impl AddAssign, add_assign for Wrapping<$t>, Wrapping<$t> } #[stable(feature = "wrapping_int_assign_impl", since = "1.60.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const AddAssign<$t> for Wrapping<$t> { + impl AddAssign<$t> for Wrapping<$t> { #[inline] fn add_assign(&mut self, other: $t) { *self = *self + Wrapping(other); } } - forward_ref_op_assign! { impl const AddAssign, add_assign for Wrapping<$t>, $t } + forward_ref_op_assign! { impl AddAssign, add_assign for Wrapping<$t>, $t } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Sub for Wrapping<$t> { + impl Sub for Wrapping<$t> { type Output = Wrapping<$t>; #[inline] @@ -259,32 +247,29 @@ macro_rules! wrapping_impl { Wrapping(self.0.wrapping_sub(other.0)) } } - forward_ref_binop! { impl const Sub, sub for Wrapping<$t>, Wrapping<$t>, + forward_ref_binop! { impl Sub, sub for Wrapping<$t>, Wrapping<$t>, #[stable(feature = "wrapping_ref", since = "1.14.0")] } #[stable(feature = "op_assign_traits", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const SubAssign for Wrapping<$t> { + impl SubAssign for Wrapping<$t> { #[inline] fn sub_assign(&mut self, other: Wrapping<$t>) { *self = *self - other; } } - forward_ref_op_assign! { impl const SubAssign, sub_assign for Wrapping<$t>, Wrapping<$t> } + forward_ref_op_assign! { impl SubAssign, sub_assign for Wrapping<$t>, Wrapping<$t> } #[stable(feature = "wrapping_int_assign_impl", since = "1.60.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const SubAssign<$t> for Wrapping<$t> { + impl SubAssign<$t> for Wrapping<$t> { #[inline] fn sub_assign(&mut self, other: $t) { *self = *self - Wrapping(other); } } - forward_ref_op_assign! { impl const SubAssign, sub_assign for Wrapping<$t>, $t } + forward_ref_op_assign! { impl SubAssign, sub_assign for Wrapping<$t>, $t } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Mul for Wrapping<$t> { + impl Mul for Wrapping<$t> { type Output = Wrapping<$t>; #[inline] @@ -296,28 +281,25 @@ macro_rules! wrapping_impl { #[stable(feature = "wrapping_ref", since = "1.14.0")] } #[stable(feature = "op_assign_traits", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const MulAssign for Wrapping<$t> { + impl MulAssign for Wrapping<$t> { #[inline] fn mul_assign(&mut self, other: Wrapping<$t>) { *self = *self * other; } } - forward_ref_op_assign! { impl const MulAssign, mul_assign for Wrapping<$t>, Wrapping<$t> } + forward_ref_op_assign! { impl MulAssign, mul_assign for Wrapping<$t>, Wrapping<$t> } #[stable(feature = "wrapping_int_assign_impl", since = "1.60.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const MulAssign<$t> for Wrapping<$t> { + impl MulAssign<$t> for Wrapping<$t> { #[inline] fn mul_assign(&mut self, other: $t) { *self = *self * Wrapping(other); } } - forward_ref_op_assign! { impl const MulAssign, mul_assign for Wrapping<$t>, $t } + forward_ref_op_assign! { impl MulAssign, mul_assign for Wrapping<$t>, $t } #[stable(feature = "wrapping_div", since = "1.3.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Div for Wrapping<$t> { + impl Div for Wrapping<$t> { type Output = Wrapping<$t>; #[inline] @@ -325,32 +307,29 @@ macro_rules! wrapping_impl { Wrapping(self.0.wrapping_div(other.0)) } } - forward_ref_binop! { impl const Div, div for Wrapping<$t>, Wrapping<$t>, + forward_ref_binop! { impl Div, div for Wrapping<$t>, Wrapping<$t>, #[stable(feature = "wrapping_ref", since = "1.14.0")] } #[stable(feature = "op_assign_traits", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const DivAssign for Wrapping<$t> { + impl DivAssign for Wrapping<$t> { #[inline] fn div_assign(&mut self, other: Wrapping<$t>) { *self = *self / other; } } - forward_ref_op_assign! { impl const DivAssign, div_assign for Wrapping<$t>, Wrapping<$t> } + forward_ref_op_assign! { impl DivAssign, div_assign for Wrapping<$t>, Wrapping<$t> } #[stable(feature = "wrapping_int_assign_impl", since = "1.60.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const DivAssign<$t> for Wrapping<$t> { + impl DivAssign<$t> for Wrapping<$t> { #[inline] fn div_assign(&mut self, other: $t) { *self = *self / Wrapping(other); } } - forward_ref_op_assign! { impl const DivAssign, div_assign for Wrapping<$t>, $t } + forward_ref_op_assign! { impl DivAssign, div_assign for Wrapping<$t>, $t } #[stable(feature = "wrapping_impls", since = "1.7.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Rem for Wrapping<$t> { + impl Rem for Wrapping<$t> { type Output = Wrapping<$t>; #[inline] @@ -358,32 +337,29 @@ macro_rules! wrapping_impl { Wrapping(self.0.wrapping_rem(other.0)) } } - forward_ref_binop! { impl const Rem, rem for Wrapping<$t>, Wrapping<$t>, + forward_ref_binop! { impl Rem, rem for Wrapping<$t>, Wrapping<$t>, #[stable(feature = "wrapping_ref", since = "1.14.0")] } #[stable(feature = "op_assign_traits", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const RemAssign for Wrapping<$t> { + impl RemAssign for Wrapping<$t> { #[inline] fn rem_assign(&mut self, other: Wrapping<$t>) { *self = *self % other; } } - forward_ref_op_assign! { impl const RemAssign, rem_assign for Wrapping<$t>, Wrapping<$t> } + forward_ref_op_assign! { impl RemAssign, rem_assign for Wrapping<$t>, Wrapping<$t> } #[stable(feature = "wrapping_int_assign_impl", since = "1.60.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const RemAssign<$t> for Wrapping<$t> { + impl RemAssign<$t> for Wrapping<$t> { #[inline] fn rem_assign(&mut self, other: $t) { *self = *self % Wrapping(other); } } - forward_ref_op_assign! { impl const RemAssign, rem_assign for Wrapping<$t>, $t } + forward_ref_op_assign! { impl RemAssign, rem_assign for Wrapping<$t>, $t } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Not for Wrapping<$t> { + impl Not for Wrapping<$t> { type Output = Wrapping<$t>; #[inline] @@ -391,12 +367,11 @@ macro_rules! wrapping_impl { Wrapping(!self.0) } } - forward_ref_unop! { impl const Not, not for Wrapping<$t>, + forward_ref_unop! { impl Not, not for Wrapping<$t>, #[stable(feature = "wrapping_ref", since = "1.14.0")] } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const BitXor for Wrapping<$t> { + impl BitXor for Wrapping<$t> { type Output = Wrapping<$t>; #[inline] @@ -404,32 +379,29 @@ macro_rules! wrapping_impl { Wrapping(self.0 ^ other.0) } } - forward_ref_binop! { impl const BitXor, bitxor for Wrapping<$t>, Wrapping<$t>, + forward_ref_binop! { impl BitXor, bitxor for Wrapping<$t>, Wrapping<$t>, #[stable(feature = "wrapping_ref", since = "1.14.0")] } #[stable(feature = "op_assign_traits", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const BitXorAssign for Wrapping<$t> { + impl BitXorAssign for Wrapping<$t> { #[inline] fn bitxor_assign(&mut self, other: Wrapping<$t>) { *self = *self ^ other; } } - forward_ref_op_assign! { impl const BitXorAssign, bitxor_assign for Wrapping<$t>, Wrapping<$t> } + forward_ref_op_assign! { impl BitXorAssign, bitxor_assign for Wrapping<$t>, Wrapping<$t> } #[stable(feature = "wrapping_int_assign_impl", since = "1.60.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const BitXorAssign<$t> for Wrapping<$t> { + impl BitXorAssign<$t> for Wrapping<$t> { #[inline] fn bitxor_assign(&mut self, other: $t) { *self = *self ^ Wrapping(other); } } - forward_ref_op_assign! { impl const BitXorAssign, bitxor_assign for Wrapping<$t>, $t } + forward_ref_op_assign! { impl BitXorAssign, bitxor_assign for Wrapping<$t>, $t } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const BitOr for Wrapping<$t> { + impl BitOr for Wrapping<$t> { type Output = Wrapping<$t>; #[inline] @@ -437,32 +409,29 @@ macro_rules! wrapping_impl { Wrapping(self.0 | other.0) } } - forward_ref_binop! { impl const BitOr, bitor for Wrapping<$t>, Wrapping<$t>, + forward_ref_binop! { impl BitOr, bitor for Wrapping<$t>, Wrapping<$t>, #[stable(feature = "wrapping_ref", since = "1.14.0")] } #[stable(feature = "op_assign_traits", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const BitOrAssign for Wrapping<$t> { + impl BitOrAssign for Wrapping<$t> { #[inline] fn bitor_assign(&mut self, other: Wrapping<$t>) { *self = *self | other; } } - forward_ref_op_assign! { impl const BitOrAssign, bitor_assign for Wrapping<$t>, Wrapping<$t> } + forward_ref_op_assign! { impl BitOrAssign, bitor_assign for Wrapping<$t>, Wrapping<$t> } #[stable(feature = "wrapping_int_assign_impl", since = "1.60.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const BitOrAssign<$t> for Wrapping<$t> { + impl BitOrAssign<$t> for Wrapping<$t> { #[inline] fn bitor_assign(&mut self, other: $t) { *self = *self | Wrapping(other); } } - forward_ref_op_assign! { impl const BitOrAssign, bitor_assign for Wrapping<$t>, $t } + forward_ref_op_assign! { impl BitOrAssign, bitor_assign for Wrapping<$t>, $t } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const BitAnd for Wrapping<$t> { + impl BitAnd for Wrapping<$t> { type Output = Wrapping<$t>; #[inline] @@ -470,39 +439,36 @@ macro_rules! wrapping_impl { Wrapping(self.0 & other.0) } } - forward_ref_binop! { impl const BitAnd, bitand for Wrapping<$t>, Wrapping<$t>, + forward_ref_binop! { impl BitAnd, bitand for Wrapping<$t>, Wrapping<$t>, #[stable(feature = "wrapping_ref", since = "1.14.0")] } #[stable(feature = "op_assign_traits", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const BitAndAssign for Wrapping<$t> { + impl BitAndAssign for Wrapping<$t> { #[inline] fn bitand_assign(&mut self, other: Wrapping<$t>) { *self = *self & other; } } - forward_ref_op_assign! { impl const BitAndAssign, bitand_assign for Wrapping<$t>, Wrapping<$t> } + forward_ref_op_assign! { impl BitAndAssign, bitand_assign for Wrapping<$t>, Wrapping<$t> } #[stable(feature = "wrapping_int_assign_impl", since = "1.60.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const BitAndAssign<$t> for Wrapping<$t> { + impl BitAndAssign<$t> for Wrapping<$t> { #[inline] fn bitand_assign(&mut self, other: $t) { *self = *self & Wrapping(other); } } - forward_ref_op_assign! { impl const BitAndAssign, bitand_assign for Wrapping<$t>, $t } + forward_ref_op_assign! { impl BitAndAssign, bitand_assign for Wrapping<$t>, $t } #[stable(feature = "wrapping_neg", since = "1.10.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Neg for Wrapping<$t> { + impl Neg for Wrapping<$t> { type Output = Self; #[inline] fn neg(self) -> Self { Wrapping(0) - self } } - forward_ref_unop! { impl const Neg, neg for Wrapping<$t>, + forward_ref_unop! { impl Neg, neg for Wrapping<$t>, #[stable(feature = "wrapping_ref", since = "1.14.0")] } )*) diff --git a/library/core/src/ops/arith.rs b/library/core/src/ops/arith.rs index e367be8c167c7..134c6db140258 100644 --- a/library/core/src/ops/arith.rs +++ b/library/core/src/ops/arith.rs @@ -117,8 +117,7 @@ pub trait Add { macro_rules! add_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Add for $t { + impl Add for $t { type Output = $t; #[inline] @@ -126,7 +125,7 @@ macro_rules! add_impl { fn add(self, other: $t) -> $t { self + other } } - forward_ref_binop! { impl const Add, add for $t, $t } + forward_ref_binop! { impl Add, add for $t, $t } )*) } @@ -224,8 +223,7 @@ pub trait Sub { macro_rules! sub_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Sub for $t { + impl Sub for $t { type Output = $t; #[inline] @@ -233,7 +231,7 @@ macro_rules! sub_impl { fn sub(self, other: $t) -> $t { self - other } } - forward_ref_binop! { impl const Sub, sub for $t, $t } + forward_ref_binop! { impl Sub, sub for $t, $t } )*) } @@ -353,8 +351,7 @@ pub trait Mul { macro_rules! mul_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Mul for $t { + impl Mul for $t { type Output = $t; #[inline] @@ -362,7 +359,7 @@ macro_rules! mul_impl { fn mul(self, other: $t) -> $t { self * other } } - forward_ref_binop! { impl const Mul, mul for $t, $t } + forward_ref_binop! { impl Mul, mul for $t, $t } )*) } @@ -492,15 +489,14 @@ macro_rules! div_impl_integer { /// #[doc = $panic] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Div for $t { + impl Div for $t { type Output = $t; #[inline] fn div(self, other: $t) -> $t { self / other } } - forward_ref_binop! { impl const Div, div for $t, $t } + forward_ref_binop! { impl Div, div for $t, $t } )*)*) } @@ -512,15 +508,14 @@ div_impl_integer! { macro_rules! div_impl_float { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Div for $t { + impl Div for $t { type Output = $t; #[inline] fn div(self, other: $t) -> $t { self / other } } - forward_ref_binop! { impl const Div, div for $t, $t } + forward_ref_binop! { impl Div, div for $t, $t } )*) } @@ -594,15 +589,14 @@ macro_rules! rem_impl_integer { /// #[doc = $panic] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Rem for $t { + impl Rem for $t { type Output = $t; #[inline] fn rem(self, other: $t) -> $t { self % other } } - forward_ref_binop! { impl const Rem, rem for $t, $t } + forward_ref_binop! { impl Rem, rem for $t, $t } )*)*) } @@ -629,15 +623,14 @@ macro_rules! rem_impl_float { /// assert_eq!(x % y, remainder); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Rem for $t { + impl Rem for $t { type Output = $t; #[inline] fn rem(self, other: $t) -> $t { self % other } } - forward_ref_binop! { impl const Rem, rem for $t, $t } + forward_ref_binop! { impl Rem, rem for $t, $t } )*) } @@ -703,8 +696,7 @@ pub trait Neg { macro_rules! neg_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Neg for $t { + impl Neg for $t { type Output = $t; #[inline] @@ -712,7 +704,7 @@ macro_rules! neg_impl { fn neg(self) -> $t { -self } } - forward_ref_unop! { impl const Neg, neg for $t } + forward_ref_unop! { impl Neg, neg for $t } )*) } @@ -772,14 +764,13 @@ pub trait AddAssign { macro_rules! add_assign_impl { ($($t:ty)+) => ($( #[stable(feature = "op_assign_traits", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const AddAssign for $t { + impl AddAssign for $t { #[inline] #[rustc_inherit_overflow_checks] fn add_assign(&mut self, other: $t) { *self += other } } - forward_ref_op_assign! { impl const AddAssign, add_assign for $t, $t } + forward_ref_op_assign! { impl AddAssign, add_assign for $t, $t } )+) } @@ -839,14 +830,13 @@ pub trait SubAssign { macro_rules! sub_assign_impl { ($($t:ty)+) => ($( #[stable(feature = "op_assign_traits", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const SubAssign for $t { + impl SubAssign for $t { #[inline] #[rustc_inherit_overflow_checks] fn sub_assign(&mut self, other: $t) { *self -= other } } - forward_ref_op_assign! { impl const SubAssign, sub_assign for $t, $t } + forward_ref_op_assign! { impl SubAssign, sub_assign for $t, $t } )+) } @@ -897,14 +887,13 @@ pub trait MulAssign { macro_rules! mul_assign_impl { ($($t:ty)+) => ($( #[stable(feature = "op_assign_traits", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const MulAssign for $t { + impl MulAssign for $t { #[inline] #[rustc_inherit_overflow_checks] fn mul_assign(&mut self, other: $t) { *self *= other } } - forward_ref_op_assign! { impl const MulAssign, mul_assign for $t, $t } + forward_ref_op_assign! { impl MulAssign, mul_assign for $t, $t } )+) } @@ -955,13 +944,12 @@ pub trait DivAssign { macro_rules! div_assign_impl { ($($t:ty)+) => ($( #[stable(feature = "op_assign_traits", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const DivAssign for $t { + impl DivAssign for $t { #[inline] fn div_assign(&mut self, other: $t) { *self /= other } } - forward_ref_op_assign! { impl const DivAssign, div_assign for $t, $t } + forward_ref_op_assign! { impl DivAssign, div_assign for $t, $t } )+) } @@ -1016,13 +1004,12 @@ pub trait RemAssign { macro_rules! rem_assign_impl { ($($t:ty)+) => ($( #[stable(feature = "op_assign_traits", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const RemAssign for $t { + impl RemAssign for $t { #[inline] fn rem_assign(&mut self, other: $t) { *self %= other } } - forward_ref_op_assign! { impl const RemAssign, rem_assign for $t, $t } + forward_ref_op_assign! { impl RemAssign, rem_assign for $t, $t } )+) } diff --git a/library/core/src/ops/bit.rs b/library/core/src/ops/bit.rs index 7c664226fc256..05e309c81b42d 100644 --- a/library/core/src/ops/bit.rs +++ b/library/core/src/ops/bit.rs @@ -54,15 +54,14 @@ pub trait Not { macro_rules! not_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Not for $t { + impl Not for $t { type Output = $t; #[inline] fn not(self) -> $t { !self } } - forward_ref_unop! { impl const Not, not for $t } + forward_ref_unop! { impl Not, not for $t } )*) } @@ -70,7 +69,7 @@ not_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } #[stable(feature = "not_never", since = "1.60.0")] #[rustc_const_unstable(feature = "const_ops", issue = "90080")] -impl const Not for ! { +impl Not for ! { type Output = !; #[inline] @@ -166,15 +165,14 @@ pub trait BitAnd { macro_rules! bitand_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const BitAnd for $t { + impl BitAnd for $t { type Output = $t; #[inline] fn bitand(self, rhs: $t) -> $t { self & rhs } } - forward_ref_binop! { impl const BitAnd, bitand for $t, $t } + forward_ref_binop! { impl BitAnd, bitand for $t, $t } )*) } @@ -267,15 +265,14 @@ pub trait BitOr { macro_rules! bitor_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const BitOr for $t { + impl BitOr for $t { type Output = $t; #[inline] fn bitor(self, rhs: $t) -> $t { self | rhs } } - forward_ref_binop! { impl const BitOr, bitor for $t, $t } + forward_ref_binop! { impl BitOr, bitor for $t, $t } )*) } @@ -368,15 +365,14 @@ pub trait BitXor { macro_rules! bitxor_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const BitXor for $t { + impl BitXor for $t { type Output = $t; #[inline] fn bitxor(self, other: $t) -> $t { self ^ other } } - forward_ref_binop! { impl const BitXor, bitxor for $t, $t } + forward_ref_binop! { impl BitXor, bitxor for $t, $t } )*) } @@ -466,8 +462,7 @@ pub trait Shl { macro_rules! shl_impl { ($t:ty, $f:ty) => { #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Shl<$f> for $t { + impl Shl<$f> for $t { type Output = $t; #[inline] @@ -477,7 +472,7 @@ macro_rules! shl_impl { } } - forward_ref_binop! { impl const Shl, shl for $t, $f } + forward_ref_binop! { impl Shl, shl for $t, $f } }; } @@ -585,8 +580,7 @@ pub trait Shr { macro_rules! shr_impl { ($t:ty, $f:ty) => { #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Shr<$f> for $t { + impl Shr<$f> for $t { type Output = $t; #[inline] @@ -596,7 +590,7 @@ macro_rules! shr_impl { } } - forward_ref_binop! { impl const Shr, shr for $t, $f } + forward_ref_binop! { impl Shr, shr for $t, $f } }; } @@ -721,13 +715,12 @@ pub trait BitAndAssign { macro_rules! bitand_assign_impl { ($($t:ty)+) => ($( #[stable(feature = "op_assign_traits", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const BitAndAssign for $t { + impl BitAndAssign for $t { #[inline] fn bitand_assign(&mut self, other: $t) { *self &= other } } - forward_ref_op_assign! { impl const BitAndAssign, bitand_assign for $t, $t } + forward_ref_op_assign! { impl BitAndAssign, bitand_assign for $t, $t } )+) } @@ -793,13 +786,12 @@ pub trait BitOrAssign { macro_rules! bitor_assign_impl { ($($t:ty)+) => ($( #[stable(feature = "op_assign_traits", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const BitOrAssign for $t { + impl BitOrAssign for $t { #[inline] fn bitor_assign(&mut self, other: $t) { *self |= other } } - forward_ref_op_assign! { impl const BitOrAssign, bitor_assign for $t, $t } + forward_ref_op_assign! { impl BitOrAssign, bitor_assign for $t, $t } )+) } @@ -865,13 +857,12 @@ pub trait BitXorAssign { macro_rules! bitxor_assign_impl { ($($t:ty)+) => ($( #[stable(feature = "op_assign_traits", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const BitXorAssign for $t { + impl BitXorAssign for $t { #[inline] fn bitxor_assign(&mut self, other: $t) { *self ^= other } } - forward_ref_op_assign! { impl const BitXorAssign, bitxor_assign for $t, $t } + forward_ref_op_assign! { impl BitXorAssign, bitxor_assign for $t, $t } )+) } @@ -927,8 +918,7 @@ pub trait ShlAssign { macro_rules! shl_assign_impl { ($t:ty, $f:ty) => { #[stable(feature = "op_assign_traits", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const ShlAssign<$f> for $t { + impl ShlAssign<$f> for $t { #[inline] #[rustc_inherit_overflow_checks] fn shl_assign(&mut self, other: $f) { @@ -936,7 +926,7 @@ macro_rules! shl_assign_impl { } } - forward_ref_op_assign! { impl const ShlAssign, shl_assign for $t, $f } + forward_ref_op_assign! { impl ShlAssign, shl_assign for $t, $f } }; } @@ -1010,8 +1000,7 @@ pub trait ShrAssign { macro_rules! shr_assign_impl { ($t:ty, $f:ty) => { #[stable(feature = "op_assign_traits", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const ShrAssign<$f> for $t { + impl ShrAssign<$f> for $t { #[inline] #[rustc_inherit_overflow_checks] fn shr_assign(&mut self, other: $f) { @@ -1019,7 +1008,7 @@ macro_rules! shr_assign_impl { } } - forward_ref_op_assign! { impl const ShrAssign, shr_assign for $t, $f } + forward_ref_op_assign! { impl ShrAssign, shr_assign for $t, $f } }; } diff --git a/library/core/src/ops/deref.rs b/library/core/src/ops/deref.rs index d68932402a411..08c35b6dac309 100644 --- a/library/core/src/ops/deref.rs +++ b/library/core/src/ops/deref.rs @@ -76,8 +76,7 @@ pub trait Deref { } #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_deref", issue = "88955")] -impl const Deref for &T { +impl Deref for &T { type Target = T; #[rustc_diagnostic_item = "noop_method_deref"] @@ -90,8 +89,7 @@ impl const Deref for &T { impl !DerefMut for &T {} #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_deref", issue = "88955")] -impl const Deref for &mut T { +impl Deref for &mut T { type Target = T; fn deref(&self) -> &T { diff --git a/library/core/src/option.rs b/library/core/src/option.rs index bca73cb770fbb..c7385b8dd6fd2 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -503,7 +503,6 @@ #![stable(feature = "rust1", since = "1.0.0")] use crate::iter::{self, FromIterator, FusedIterator, TrustedLen}; -use crate::marker::Destruct; use crate::panicking::{panic, panic_str}; use crate::pin::Pin; use crate::{ @@ -644,8 +643,7 @@ impl Option { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_option", issue = "67441")] - pub const fn as_mut(&mut self) -> Option<&mut T> { + pub fn as_mut(&mut self) -> Option<&mut T> { match *self { Some(ref mut x) => Some(x), None => None, @@ -658,8 +656,7 @@ impl Option { #[inline] #[must_use] #[stable(feature = "pin", since = "1.33.0")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn as_pin_ref(self: Pin<&Self>) -> Option> { + pub fn as_pin_ref(self: Pin<&Self>) -> Option> { match Pin::get_ref(self).as_ref() { // SAFETY: `x` is guaranteed to be pinned because it comes from `self` // which is pinned. @@ -674,8 +671,7 @@ impl Option { #[inline] #[must_use] #[stable(feature = "pin", since = "1.33.0")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn as_pin_mut(self: Pin<&mut Self>) -> Option> { + pub fn as_pin_mut(self: Pin<&mut Self>) -> Option> { // SAFETY: `get_unchecked_mut` is never used to move the `Option` inside `self`. // `x` is guaranteed to be pinned because it comes from `self` which is pinned. unsafe { @@ -792,11 +788,7 @@ impl Option { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn unwrap_or(self, default: T) -> T - where - T: ~const Destruct, - { + pub fn unwrap_or(self, default: T) -> T { match self { Some(x) => x, None => default, @@ -814,11 +806,9 @@ impl Option { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn unwrap_or_else(self, f: F) -> T + pub fn unwrap_or_else(self, f: F) -> T where - F: ~const FnOnce() -> T, - F: ~const Destruct, + F: FnOnce() -> T, { match self { Some(x) => x, @@ -854,10 +844,9 @@ impl Option { /// [`FromStr`]: crate::str::FromStr #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn unwrap_or_default(self) -> T + pub fn unwrap_or_default(self) -> T where - T: ~const Default, + T: Default, { match self { Some(x) => x, @@ -919,11 +908,9 @@ impl Option { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn map(self, f: F) -> Option + pub fn map(self, f: F) -> Option where - F: ~const FnOnce(T) -> U, - F: ~const Destruct, + F: FnOnce(T) -> U, { match self { Some(x) => Some(f(x)), @@ -948,11 +935,9 @@ impl Option { /// ``` #[inline] #[unstable(feature = "result_option_inspect", issue = "91345")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn inspect(self, f: F) -> Self + pub fn inspect(self, f: F) -> Self where - F: ~const FnOnce(&T), - F: ~const Destruct, + F: FnOnce(&T), { if let Some(ref x) = self { f(x); @@ -981,12 +966,9 @@ impl Option { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn map_or(self, default: U, f: F) -> U + pub fn map_or(self, default: U, f: F) -> U where - F: ~const FnOnce(T) -> U, - F: ~const Destruct, - U: ~const Destruct, + F: FnOnce(T) -> U, { match self { Some(t) => f(t), @@ -1010,13 +992,10 @@ impl Option { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn map_or_else(self, default: D, f: F) -> U + pub fn map_or_else(self, default: D, f: F) -> U where - D: ~const FnOnce() -> U, - D: ~const Destruct, - F: ~const FnOnce(T) -> U, - F: ~const Destruct, + D: FnOnce() -> U, + F: FnOnce(T) -> U, { match self { Some(t) => f(t), @@ -1047,11 +1026,7 @@ impl Option { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn ok_or(self, err: E) -> Result - where - E: ~const Destruct, - { + pub fn ok_or(self, err: E) -> Result { match self { Some(v) => Ok(v), None => Err(err), @@ -1076,11 +1051,9 @@ impl Option { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn ok_or_else(self, err: F) -> Result + pub fn ok_or_else(self, err: F) -> Result where - F: ~const FnOnce() -> E, - F: ~const Destruct, + F: FnOnce() -> E, { match self { Some(v) => Ok(v), @@ -1103,10 +1076,9 @@ impl Option { /// assert_eq!(x.as_deref(), None); /// ``` #[stable(feature = "option_deref", since = "1.40.0")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn as_deref(&self) -> Option<&T::Target> + pub fn as_deref(&self) -> Option<&T::Target> where - T: ~const Deref, + T: Deref, { match self.as_ref() { Some(t) => Some(t.deref()), @@ -1129,10 +1101,9 @@ impl Option { /// }), Some("HEY".to_owned().as_mut_str())); /// ``` #[stable(feature = "option_deref", since = "1.40.0")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn as_deref_mut(&mut self) -> Option<&mut T::Target> + pub fn as_deref_mut(&mut self) -> Option<&mut T::Target> where - T: ~const DerefMut, + T: DerefMut, { match self.as_mut() { Some(t) => Some(t.deref_mut()), @@ -1210,12 +1181,7 @@ impl Option { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn and(self, optb: Option) -> Option - where - T: ~const Destruct, - U: ~const Destruct, - { + pub fn and(self, optb: Option) -> Option { match self { Some(_) => optb, None => None, @@ -1252,11 +1218,9 @@ impl Option { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn and_then(self, f: F) -> Option + pub fn and_then(self, f: F) -> Option where - F: ~const FnOnce(T) -> Option, - F: ~const Destruct, + F: FnOnce(T) -> Option, { match self { Some(x) => f(x), @@ -1290,12 +1254,9 @@ impl Option { /// [`Some(t)`]: Some #[inline] #[stable(feature = "option_filter", since = "1.27.0")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn filter

(self, predicate: P) -> Self + pub fn filter

(self, predicate: P) -> Self where - T: ~const Destruct, - P: ~const FnOnce(&T) -> bool, - P: ~const Destruct, + P: FnOnce(&T) -> bool, { if let Some(x) = self { if predicate(&x) { @@ -1334,11 +1295,7 @@ impl Option { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn or(self, optb: Option) -> Option - where - T: ~const Destruct, - { + pub fn or(self, optb: Option) -> Option { match self { Some(x) => Some(x), None => optb, @@ -1360,11 +1317,9 @@ impl Option { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn or_else(self, f: F) -> Option + pub fn or_else(self, f: F) -> Option where - F: ~const FnOnce() -> Option, - F: ~const Destruct, + F: FnOnce() -> Option, { match self { Some(x) => Some(x), @@ -1395,11 +1350,7 @@ impl Option { /// ``` #[inline] #[stable(feature = "option_xor", since = "1.37.0")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn xor(self, optb: Option) -> Option - where - T: ~const Destruct, - { + pub fn xor(self, optb: Option) -> Option { match (self, optb) { (Some(a), None) => Some(a), (None, Some(b)) => Some(b), @@ -1433,11 +1384,7 @@ impl Option { #[must_use = "if you intended to set a value, consider assignment instead"] #[inline] #[stable(feature = "option_insert", since = "1.53.0")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn insert(&mut self, value: T) -> &mut T - where - T: ~const Destruct, - { + pub fn insert(&mut self, value: T) -> &mut T { *self = Some(value); // SAFETY: the code above just filled the option @@ -1466,11 +1413,7 @@ impl Option { /// ``` #[inline] #[stable(feature = "option_entry", since = "1.20.0")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn get_or_insert(&mut self, value: T) -> &mut T - where - T: ~const Destruct, - { + pub fn get_or_insert(&mut self, value: T) -> &mut T { if let None = *self { *self = Some(value); } @@ -1501,12 +1444,11 @@ impl Option { /// ``` #[inline] #[unstable(feature = "option_get_or_insert_default", issue = "82901")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn get_or_insert_default(&mut self) -> &mut T + pub fn get_or_insert_default(&mut self) -> &mut T where - T: ~const Default, + T: Default, { - const fn default() -> T { + fn default() -> T { T::default() } @@ -1532,11 +1474,9 @@ impl Option { /// ``` #[inline] #[stable(feature = "option_entry", since = "1.20.0")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn get_or_insert_with(&mut self, f: F) -> &mut T + pub fn get_or_insert_with(&mut self, f: F) -> &mut T where - F: ~const FnOnce() -> T, - F: ~const Destruct, + F: FnOnce() -> T, { if let None = *self { // the compiler isn't smart enough to know that we are not dropping a `T` @@ -1619,10 +1559,9 @@ impl Option { #[must_use] #[inline] #[unstable(feature = "option_result_contains", issue = "62358")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn contains(&self, x: &U) -> bool + pub fn contains(&self, x: &U) -> bool where - U: ~const PartialEq, + U: PartialEq, { match self { Some(y) => x.eq(y), @@ -1646,12 +1585,7 @@ impl Option { /// assert_eq!(x.zip(z), None); /// ``` #[stable(feature = "option_zip_option", since = "1.46.0")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn zip(self, other: Option) -> Option<(T, U)> - where - T: ~const Destruct, - U: ~const Destruct, - { + pub fn zip(self, other: Option) -> Option<(T, U)> { match (self, other) { (Some(a), Some(b)) => Some((a, b)), _ => None, @@ -1687,13 +1621,9 @@ impl Option { /// assert_eq!(x.zip_with(None, Point::new), None); /// ``` #[unstable(feature = "option_zip", issue = "70086")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn zip_with(self, other: Option, f: F) -> Option + pub fn zip_with(self, other: Option, f: F) -> Option where - F: ~const FnOnce(T, U) -> R, - F: ~const Destruct, - T: ~const Destruct, - U: ~const Destruct, + F: FnOnce(T, U) -> R, { match (self, other) { (Some(a), Some(b)) => Some(f(a, b)), @@ -1771,10 +1701,9 @@ impl Option<&T> { /// ``` #[must_use = "`self` will be dropped if the result is not used"] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_option_cloned", issue = "91582")] - pub const fn cloned(self) -> Option + pub fn cloned(self) -> Option where - T: ~const Clone, + T: Clone, { match self { Some(t) => Some(t.clone()), @@ -1823,10 +1752,9 @@ impl Option<&mut T> { /// ``` #[must_use = "`self` will be dropped if the result is not used"] #[stable(since = "1.26.0", feature = "option_ref_mut_cloned")] - #[rustc_const_unstable(feature = "const_option_cloned", issue = "91582")] - pub const fn cloned(self) -> Option + pub fn cloned(self) -> Option where - T: ~const Clone, + T: Clone, { match self { Some(t) => Some(t.clone()), @@ -1879,10 +1807,9 @@ const fn expect_failed(msg: &str) -> ! { ///////////////////////////////////////////////////////////////////////////// #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_clone", issue = "91805")] -impl const Clone for Option +impl Clone for Option where - T: ~const Clone + ~const Destruct, + T: Clone, { #[inline] fn clone(&self) -> Self { @@ -1902,8 +1829,7 @@ where } #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] -impl const Default for Option { +impl Default for Option { /// Returns [`None`][Option::None]. /// /// # Examples @@ -1963,8 +1889,7 @@ impl<'a, T> IntoIterator for &'a mut Option { } #[stable(since = "1.12.0", feature = "option_from")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl const From for Option { +impl From for Option { /// Moves `val` into a new [`Some`]. /// /// # Examples @@ -1980,8 +1905,7 @@ impl const From for Option { } #[stable(feature = "option_ref_from_ref_option", since = "1.30.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl<'a, T> const From<&'a Option> for Option<&'a T> { +impl<'a, T> From<&'a Option> for Option<&'a T> { /// Converts from `&Option` to `Option<&T>`. /// /// # Examples @@ -2008,8 +1932,7 @@ impl<'a, T> const From<&'a Option> for Option<&'a T> { } #[stable(feature = "option_ref_from_ref_option", since = "1.30.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl<'a, T> const From<&'a mut Option> for Option<&'a mut T> { +impl<'a, T> From<&'a mut Option> for Option<&'a mut T> { /// Converts from `&mut Option` to `Option<&mut T>` /// /// # Examples @@ -2276,8 +2199,7 @@ impl> FromIterator> for Option { } #[unstable(feature = "try_trait_v2", issue = "84277")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl const ops::Try for Option { +impl ops::Try for Option { type Output = T; type Residual = Option; @@ -2296,8 +2218,7 @@ impl const ops::Try for Option { } #[unstable(feature = "try_trait_v2", issue = "84277")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl const ops::FromResidual for Option { +impl ops::FromResidual for Option { #[inline] fn from_residual(residual: Option) -> Self { match residual { @@ -2346,8 +2267,7 @@ impl Option> { /// ``` #[inline] #[stable(feature = "option_flattening", since = "1.40.0")] - #[rustc_const_unstable(feature = "const_option", issue = "67441")] - pub const fn flatten(self) -> Option { + pub fn flatten(self) -> Option { match self { Some(inner) => inner, None => None, diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index 74aa0d9c7bcb2..f0727d4a749bc 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -737,7 +737,7 @@ impl *const T { { // SAFETY: The comparison has no side-effects, and the intrinsic // does this check internally in the CTFE implementation. - unsafe { assert_unsafe_precondition!(self >= origin) }; + assert_unsafe_precondition!(self >= origin); let pointee_size = mem::size_of::(); assert!(0 < pointee_size && pointee_size <= isize::MAX as usize); @@ -1269,8 +1269,7 @@ impl *const T { /// # } } /// ``` #[stable(feature = "align_offset", since = "1.36.0")] - #[rustc_const_unstable(feature = "const_align_offset", issue = "90962")] - pub const fn align_offset(self, align: usize) -> usize + pub fn align_offset(self, align: usize) -> usize where T: Sized, { @@ -1283,16 +1282,12 @@ impl *const T { unsafe { align_offset(p, align) } } - const fn ctfe_impl(_: *const T, _: usize) -> usize { - usize::MAX - } - // SAFETY: // It is permissible for `align_offset` to always return `usize::MAX`, // algorithm correctness can not depend on `align_offset` returning non-max values. // // As such the behaviour can't change after replacing `align_offset` with `usize::MAX`, only performance can. - unsafe { intrinsics::const_eval_select((self, align), ctfe_impl, rt_impl) } + rt_impl(self, align) } /// Returns whether the pointer is properly aligned for `T`. @@ -1395,11 +1390,10 @@ impl *const [T] { /// } /// ``` #[unstable(feature = "slice_ptr_get", issue = "74265")] - #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] #[inline] - pub const unsafe fn get_unchecked(self, index: I) -> *const I::Output + pub unsafe fn get_unchecked(self, index: I) -> *const I::Output where - I: ~const SliceIndex<[T]>, + I: SliceIndex<[T]>, { // SAFETY: the caller ensures that `self` is dereferenceable and `index` in-bounds. unsafe { index.get_unchecked(self) } diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 2fcff3dfc5c44..d0b87b38935f7 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -371,9 +371,7 @@ use crate::cmp::Ordering; use crate::fmt; use crate::hash; -use crate::intrinsics::{ - self, assert_unsafe_precondition, is_aligned_and_not_null, is_nonoverlapping, -}; +use crate::intrinsics::{self, assert_unsafe_precondition}; use crate::mem::{self, MaybeUninit}; @@ -883,13 +881,9 @@ pub const unsafe fn swap_nonoverlapping(x: *mut T, y: *mut T, count: usize) { // SAFETY: the caller must guarantee that `x` and `y` are // valid for writes and properly aligned. - unsafe { - assert_unsafe_precondition!( - is_aligned_and_not_null(x) - && is_aligned_and_not_null(y) - && is_nonoverlapping(x, y, count) - ); - } + assert_unsafe_precondition!( + is_aligned_and_not_null(x) && is_aligned_and_not_null(y) && is_nonoverlapping(x, y, count) + ); // NOTE(scottmcm) Miri is disabled here as reading in smaller units is a // pessimization for it. Also, if the type contains any unaligned pointers, diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index b988090f4bc4c..342500796bb60 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -1539,8 +1539,7 @@ impl *mut T { /// # } } /// ``` #[stable(feature = "align_offset", since = "1.36.0")] - #[rustc_const_unstable(feature = "const_align_offset", issue = "90962")] - pub const fn align_offset(self, align: usize) -> usize + pub fn align_offset(self, align: usize) -> usize where T: Sized, { @@ -1553,16 +1552,12 @@ impl *mut T { unsafe { align_offset(p, align) } } - const fn ctfe_impl(_: *mut T, _: usize) -> usize { - usize::MAX - } - // SAFETY: // It is permissible for `align_offset` to always return `usize::MAX`, // algorithm correctness can not depend on `align_offset` returning non-max values. // // As such the behaviour can't change after replacing `align_offset` with `usize::MAX`, only performance can. - unsafe { intrinsics::const_eval_select((self, align), ctfe_impl, rt_impl) } + rt_impl(self, align) } /// Returns whether the pointer is properly aligned for `T`. @@ -1781,11 +1776,10 @@ impl *mut [T] { /// } /// ``` #[unstable(feature = "slice_ptr_get", issue = "74265")] - #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] #[inline(always)] - pub const unsafe fn get_unchecked_mut(self, index: I) -> *mut I::Output + pub unsafe fn get_unchecked_mut(self, index: I) -> *mut I::Output where - I: ~const SliceIndex<[T]>, + I: SliceIndex<[T]>, { // SAFETY: the caller ensures that `self` is dereferenceable and `index` in-bounds. unsafe { index.get_unchecked_mut(self) } diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index f3ef094cbccc5..ad9152f78adec 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -684,11 +684,10 @@ impl NonNull<[T]> { /// } /// ``` #[unstable(feature = "slice_ptr_get", issue = "74265")] - #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] #[inline] - pub const unsafe fn get_unchecked_mut(self, index: I) -> NonNull + pub unsafe fn get_unchecked_mut(self, index: I) -> NonNull where - I: ~const SliceIndex<[T]>, + I: SliceIndex<[T]>, { // SAFETY: the caller ensures that `self` is dereferenceable and `index` in-bounds. // As a consequence, the resulting pointer cannot be null. @@ -697,8 +696,7 @@ impl NonNull<[T]> { } #[stable(feature = "nonnull", since = "1.25.0")] -#[rustc_const_unstable(feature = "const_clone", issue = "91805")] -impl const Clone for NonNull { +impl Clone for NonNull { #[inline] fn clone(&self) -> Self { *self @@ -764,8 +762,7 @@ impl hash::Hash for NonNull { } #[unstable(feature = "ptr_internals", issue = "none")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl const From> for NonNull { +impl From> for NonNull { #[inline] fn from(unique: Unique) -> Self { // SAFETY: A Unique pointer cannot be null, so the conditions for @@ -775,8 +772,7 @@ impl const From> for NonNull { } #[stable(feature = "nonnull", since = "1.25.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl const From<&mut T> for NonNull { +impl From<&mut T> for NonNull { /// Converts a `&mut T` to a `NonNull`. /// /// This conversion is safe and infallible since references cannot be null. @@ -788,8 +784,7 @@ impl const From<&mut T> for NonNull { } #[stable(feature = "nonnull", since = "1.25.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl const From<&T> for NonNull { +impl From<&T> for NonNull { /// Converts a `&T` to a `NonNull`. /// /// This conversion is safe and infallible since references cannot be null. diff --git a/library/core/src/ptr/unique.rs b/library/core/src/ptr/unique.rs index 64616142b4188..c08ef753f2607 100644 --- a/library/core/src/ptr/unique.rs +++ b/library/core/src/ptr/unique.rs @@ -70,7 +70,7 @@ impl Unique { #[must_use] #[inline] pub const fn dangling() -> Self { - Self::from(NonNull::dangling()) + Self { pointer: NonNull::dangling(), _marker: PhantomData } } } @@ -133,14 +133,14 @@ impl Unique { /// Casts to a pointer of another type. #[must_use = "`self` will be dropped if the result is not used"] #[inline] - pub const fn cast(self) -> Unique { + pub fn cast(self) -> Unique { Unique::from(self.pointer.cast()) } } #[unstable(feature = "ptr_internals", issue = "none")] #[rustc_const_unstable(feature = "const_clone", issue = "91805")] -impl const Clone for Unique { +impl Clone for Unique { #[inline] fn clone(&self) -> Self { *self @@ -171,7 +171,7 @@ impl fmt::Pointer for Unique { } #[unstable(feature = "ptr_internals", issue = "none")] -impl const From<&mut T> for Unique { +impl From<&mut T> for Unique { /// Converts a `&mut T` to a `Unique`. /// /// This conversion is infallible since references cannot be null. @@ -182,7 +182,7 @@ impl const From<&mut T> for Unique { } #[unstable(feature = "ptr_internals", issue = "none")] -impl const From> for Unique { +impl From> for Unique { /// Converts a `NonNull` to a `Unique`. /// /// This conversion is infallible since `NonNull` cannot be null. diff --git a/library/core/src/result.rs b/library/core/src/result.rs index 8a68cdf7d651b..97127643a7f6f 100644 --- a/library/core/src/result.rs +++ b/library/core/src/result.rs @@ -633,16 +633,10 @@ impl Result { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_result_drop", issue = "92384")] - pub const fn ok(self) -> Option - where - E: ~const Destruct, - { + pub fn ok(self) -> Option { match self { Ok(x) => Some(x), - // FIXME: ~const Drop doesn't quite work right yet - #[allow(unused_variables)] - Err(x) => None, + Err(_) => None, } } @@ -664,15 +658,9 @@ impl Result { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_result_drop", issue = "92384")] - pub const fn err(self) -> Option - where - T: ~const Destruct, - { + pub fn err(self) -> Option { match self { - // FIXME: ~const Drop doesn't quite work right yet - #[allow(unused_variables)] - Ok(x) => None, + Ok(_) => None, Err(x) => Some(x), } } @@ -731,8 +719,7 @@ impl Result { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_result", issue = "82814")] - pub const fn as_mut(&mut self) -> Result<&mut T, &mut E> { + pub fn as_mut(&mut self) -> Result<&mut T, &mut E> { match *self { Ok(ref mut x) => Ok(x), Err(ref mut x) => Err(x), @@ -1299,18 +1286,13 @@ impl Result { /// assert_eq!(x.and(y), Ok("different result type")); /// ``` #[inline] - #[rustc_const_unstable(feature = "const_result_drop", issue = "92384")] #[stable(feature = "rust1", since = "1.0.0")] - pub const fn and(self, res: Result) -> Result + pub fn and(self, res: Result) -> Result where - T: ~const Destruct, - U: ~const Destruct, - E: ~const Destruct, + U: Destruct, { match self { - // FIXME: ~const Drop doesn't quite work right yet - #[allow(unused_variables)] - Ok(x) => res, + Ok(_) => res, Err(e) => Err(e), } } @@ -1384,19 +1366,14 @@ impl Result { /// assert_eq!(x.or(y), Ok(2)); /// ``` #[inline] - #[rustc_const_unstable(feature = "const_result_drop", issue = "92384")] #[stable(feature = "rust1", since = "1.0.0")] - pub const fn or(self, res: Result) -> Result + pub fn or(self, res: Result) -> Result where - T: ~const Destruct, - E: ~const Destruct, - F: ~const Destruct, + F: Destruct, { match self { Ok(v) => Ok(v), - // FIXME: ~const Drop doesn't quite work right yet - #[allow(unused_variables)] - Err(e) => res, + Err(_) => res, } } @@ -1448,18 +1425,11 @@ impl Result { /// assert_eq!(x.unwrap_or(default), default); /// ``` #[inline] - #[rustc_const_unstable(feature = "const_result_drop", issue = "92384")] #[stable(feature = "rust1", since = "1.0.0")] - pub const fn unwrap_or(self, default: T) -> T - where - T: ~const Destruct, - E: ~const Destruct, - { + pub fn unwrap_or(self, default: T) -> T { match self { Ok(t) => t, - // FIXME: ~const Drop doesn't quite work right yet - #[allow(unused_variables)] - Err(e) => default, + Err(_) => default, } } @@ -1823,10 +1793,10 @@ fn unwrap_failed(_msg: &str, _error: &T) -> ! { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_unstable(feature = "const_clone", issue = "91805")] -impl const Clone for Result +impl Clone for Result where - T: ~const Clone + ~const Destruct, - E: ~const Clone + ~const Destruct, + T: Clone, + E: Clone, { #[inline] fn clone(&self) -> Self { @@ -2094,8 +2064,7 @@ impl> FromIterator> for Result { } #[unstable(feature = "try_trait_v2", issue = "84277")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl const ops::Try for Result { +impl ops::Try for Result { type Output = T; type Residual = Result; @@ -2114,10 +2083,7 @@ impl const ops::Try for Result { } #[unstable(feature = "try_trait_v2", issue = "84277")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl> const ops::FromResidual> - for Result -{ +impl> ops::FromResidual> for Result { #[inline] #[track_caller] fn from_residual(residual: Result) -> Self { diff --git a/library/core/src/slice/index.rs b/library/core/src/slice/index.rs index fd7ecf3daf316..6e80b39c3371d 100644 --- a/library/core/src/slice/index.rs +++ b/library/core/src/slice/index.rs @@ -1,15 +1,13 @@ //! Indexing implementations for `[T]`. use crate::intrinsics::assert_unsafe_precondition; -use crate::intrinsics::const_eval_select; use crate::ops; use crate::ptr; #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_slice_index", issue = "none")] -impl const ops::Index for [T] +impl ops::Index for [T] where - I: ~const SliceIndex<[T]>, + I: SliceIndex<[T]>, { type Output = I::Output; @@ -20,10 +18,9 @@ where } #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_slice_index", issue = "none")] -impl const ops::IndexMut for [T] +impl ops::IndexMut for [T] where - I: ~const SliceIndex<[T]>, + I: SliceIndex<[T]>, { #[inline] fn index_mut(&mut self, index: I) -> &mut I::Output { @@ -35,67 +32,26 @@ where #[cfg_attr(feature = "panic_immediate_abort", inline)] #[cold] #[track_caller] -#[rustc_const_unstable(feature = "const_slice_index", issue = "none")] -const fn slice_start_index_len_fail(index: usize, len: usize) -> ! { - // SAFETY: we are just panicking here - unsafe { - const_eval_select( - (index, len), - slice_start_index_len_fail_ct, - slice_start_index_len_fail_rt, - ) - } -} - -// FIXME const-hack -fn slice_start_index_len_fail_rt(index: usize, len: usize) -> ! { +fn slice_start_index_len_fail(index: usize, len: usize) -> ! { panic!("range start index {index} out of range for slice of length {len}"); } -const fn slice_start_index_len_fail_ct(_: usize, _: usize) -> ! { - panic!("slice start index is out of range for slice"); -} - #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))] #[cfg_attr(feature = "panic_immediate_abort", inline)] #[cold] #[track_caller] -#[rustc_const_unstable(feature = "const_slice_index", issue = "none")] -const fn slice_end_index_len_fail(index: usize, len: usize) -> ! { - // SAFETY: we are just panicking here - unsafe { - const_eval_select((index, len), slice_end_index_len_fail_ct, slice_end_index_len_fail_rt) - } -} - -// FIXME const-hack -fn slice_end_index_len_fail_rt(index: usize, len: usize) -> ! { +fn slice_end_index_len_fail(index: usize, len: usize) -> ! { panic!("range end index {index} out of range for slice of length {len}"); } -const fn slice_end_index_len_fail_ct(_: usize, _: usize) -> ! { - panic!("slice end index is out of range for slice"); -} - #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))] #[cfg_attr(feature = "panic_immediate_abort", inline)] #[cold] #[track_caller] -#[rustc_const_unstable(feature = "const_slice_index", issue = "none")] -const fn slice_index_order_fail(index: usize, end: usize) -> ! { - // SAFETY: we are just panicking here - unsafe { const_eval_select((index, end), slice_index_order_fail_ct, slice_index_order_fail_rt) } -} - -// FIXME const-hack -fn slice_index_order_fail_rt(index: usize, end: usize) -> ! { +fn slice_index_order_fail(index: usize, end: usize) -> ! { panic!("slice index starts at {index} but ends at {end}"); } -const fn slice_index_order_fail_ct(_: usize, _: usize) -> ! { - panic!("slice index start is larger than end"); -} - #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))] #[cfg_attr(feature = "panic_immediate_abort", inline)] #[cold] @@ -199,8 +155,7 @@ pub unsafe trait SliceIndex: private_slice_index::Sealed { } #[stable(feature = "slice_get_slice_impls", since = "1.15.0")] -#[rustc_const_unstable(feature = "const_slice_index", issue = "none")] -unsafe impl const SliceIndex<[T]> for usize { +unsafe impl SliceIndex<[T]> for usize { type Output = T; #[inline] @@ -250,8 +205,7 @@ unsafe impl const SliceIndex<[T]> for usize { } #[stable(feature = "slice_get_slice_impls", since = "1.15.0")] -#[rustc_const_unstable(feature = "const_slice_index", issue = "none")] -unsafe impl const SliceIndex<[T]> for ops::Range { +unsafe impl SliceIndex<[T]> for ops::Range { type Output = [T]; #[inline] @@ -320,8 +274,7 @@ unsafe impl const SliceIndex<[T]> for ops::Range { } #[stable(feature = "slice_get_slice_impls", since = "1.15.0")] -#[rustc_const_unstable(feature = "const_slice_index", issue = "none")] -unsafe impl const SliceIndex<[T]> for ops::RangeTo { +unsafe impl SliceIndex<[T]> for ops::RangeTo { type Output = [T]; #[inline] @@ -358,8 +311,7 @@ unsafe impl const SliceIndex<[T]> for ops::RangeTo { } #[stable(feature = "slice_get_slice_impls", since = "1.15.0")] -#[rustc_const_unstable(feature = "const_slice_index", issue = "none")] -unsafe impl const SliceIndex<[T]> for ops::RangeFrom { +unsafe impl SliceIndex<[T]> for ops::RangeFrom { type Output = [T]; #[inline] @@ -404,8 +356,7 @@ unsafe impl const SliceIndex<[T]> for ops::RangeFrom { } #[stable(feature = "slice_get_slice_impls", since = "1.15.0")] -#[rustc_const_unstable(feature = "const_slice_index", issue = "none")] -unsafe impl const SliceIndex<[T]> for ops::RangeFull { +unsafe impl SliceIndex<[T]> for ops::RangeFull { type Output = [T]; #[inline] @@ -440,8 +391,7 @@ unsafe impl const SliceIndex<[T]> for ops::RangeFull { } #[stable(feature = "inclusive_range", since = "1.26.0")] -#[rustc_const_unstable(feature = "const_slice_index", issue = "none")] -unsafe impl const SliceIndex<[T]> for ops::RangeInclusive { +unsafe impl SliceIndex<[T]> for ops::RangeInclusive { type Output = [T]; #[inline] @@ -484,8 +434,7 @@ unsafe impl const SliceIndex<[T]> for ops::RangeInclusive { } #[stable(feature = "inclusive_range", since = "1.26.0")] -#[rustc_const_unstable(feature = "const_slice_index", issue = "none")] -unsafe impl const SliceIndex<[T]> for ops::RangeToInclusive { +unsafe impl SliceIndex<[T]> for ops::RangeToInclusive { type Output = [T]; #[inline] diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index 77fd1ec2b8ea2..7c63a3a1ab83f 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -333,12 +333,11 @@ impl [T] { /// assert_eq!(None, v.get(0..4)); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] #[inline] #[must_use] - pub const fn get(&self, index: I) -> Option<&I::Output> + pub fn get(&self, index: I) -> Option<&I::Output> where - I: ~const SliceIndex, + I: SliceIndex, { index.get(self) } @@ -359,12 +358,11 @@ impl [T] { /// assert_eq!(x, &[0, 42, 2]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] #[inline] #[must_use] - pub const fn get_mut(&mut self, index: I) -> Option<&mut I::Output> + pub fn get_mut(&mut self, index: I) -> Option<&mut I::Output> where - I: ~const SliceIndex, + I: SliceIndex, { index.get_mut(self) } @@ -392,12 +390,11 @@ impl [T] { /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] #[inline] #[must_use] - pub const unsafe fn get_unchecked(&self, index: I) -> &I::Output + pub unsafe fn get_unchecked(&self, index: I) -> &I::Output where - I: ~const SliceIndex, + I: SliceIndex, { // SAFETY: the caller must uphold most of the safety requirements for `get_unchecked`; // the slice is dereferenceable because `self` is a safe reference. @@ -430,12 +427,11 @@ impl [T] { /// assert_eq!(x, &[1, 13, 4]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] #[inline] #[must_use] - pub const unsafe fn get_unchecked_mut(&mut self, index: I) -> &mut I::Output + pub unsafe fn get_unchecked_mut(&mut self, index: I) -> &mut I::Output where - I: ~const SliceIndex, + I: SliceIndex, { // SAFETY: the caller must uphold the safety requirements for `get_unchecked_mut`; // the slice is dereferenceable because `self` is a safe reference. @@ -4133,8 +4129,7 @@ where } #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] -impl const Default for &[T] { +impl Default for &[T] { /// Creates an empty slice. fn default() -> Self { &[] @@ -4142,8 +4137,7 @@ impl const Default for &[T] { } #[stable(feature = "mut_slice_default", since = "1.5.0")] -#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] -impl const Default for &mut [T] { +impl Default for &mut [T] { /// Creates a mutable empty slice. fn default() -> Self { &mut [] diff --git a/library/core/src/slice/raw.rs b/library/core/src/slice/raw.rs index 107e71ab68b01..d1dfbf6a9e20c 100644 --- a/library/core/src/slice/raw.rs +++ b/library/core/src/slice/raw.rs @@ -1,7 +1,7 @@ //! Free functions to create `&[T]` and `&mut [T]`. use crate::array; -use crate::intrinsics::{assert_unsafe_precondition, is_aligned_and_not_null}; +use crate::intrinsics::assert_unsafe_precondition; use crate::ops::Range; use crate::ptr; diff --git a/library/core/src/str/converts.rs b/library/core/src/str/converts.rs index b0c55ca4f5139..f5548c8269608 100644 --- a/library/core/src/str/converts.rs +++ b/library/core/src/str/converts.rs @@ -82,9 +82,7 @@ use super::Utf8Error; /// assert_eq!("💖", sparkle_heart); /// ``` #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_stable(feature = "const_str_from_utf8_shared", since = "1.63.0")] -#[rustc_allow_const_fn_unstable(str_internals)] -pub const fn from_utf8(v: &[u8]) -> Result<&str, Utf8Error> { +pub fn from_utf8(v: &[u8]) -> Result<&str, Utf8Error> { // FIXME: This should use `?` again, once it's `const` match run_utf8_validation(v) { Ok(_) => { @@ -126,8 +124,7 @@ pub const fn from_utf8(v: &[u8]) -> Result<&str, Utf8Error> { /// See the docs for [`Utf8Error`] for more details on the kinds of /// errors that can be returned. #[stable(feature = "str_mut_extras", since = "1.20.0")] -#[rustc_const_unstable(feature = "const_str_from_utf8", issue = "91006")] -pub const fn from_utf8_mut(v: &mut [u8]) -> Result<&mut str, Utf8Error> { +pub fn from_utf8_mut(v: &mut [u8]) -> Result<&mut str, Utf8Error> { // This should use `?` again, once it's `const` match run_utf8_validation(v) { Ok(_) => { diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index c4f2e283eb3bc..33cace645199d 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -79,23 +79,7 @@ use iter::{MatchesInternal, SplitNInternal}; #[inline(never)] #[cold] #[track_caller] -#[rustc_allow_const_fn_unstable(const_eval_select)] -const fn slice_error_fail(s: &str, begin: usize, end: usize) -> ! { - // SAFETY: panics for both branches - unsafe { - crate::intrinsics::const_eval_select( - (s, begin, end), - slice_error_fail_ct, - slice_error_fail_rt, - ) - } -} - -const fn slice_error_fail_ct(_: &str, _: usize, _: usize) -> ! { - panic!("failed to slice string"); -} - -fn slice_error_fail_rt(s: &str, begin: usize, end: usize) -> ! { +fn slice_error_fail(s: &str, begin: usize, end: usize) -> ! { const MAX_DISPLAY_LENGTH: usize = 256; let trunc_len = s.floor_char_boundary(MAX_DISPLAY_LENGTH); let s_trunc = &s[..trunc_len]; @@ -204,9 +188,8 @@ impl str { /// ``` #[must_use] #[stable(feature = "is_char_boundary", since = "1.9.0")] - #[rustc_const_unstable(feature = "const_is_char_boundary", issue = "none")] #[inline] - pub const fn is_char_boundary(&self, index: usize) -> bool { + pub fn is_char_boundary(&self, index: usize) -> bool { // 0 is always ok. // Test for 0 explicitly so that it can optimize out the check // easily and skip reading string data for that case. @@ -434,9 +417,8 @@ impl str { /// assert!(v.get(..42).is_none()); /// ``` #[stable(feature = "str_checked_slicing", since = "1.20.0")] - #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] #[inline] - pub const fn get>(&self, i: I) -> Option<&I::Output> { + pub fn get>(&self, i: I) -> Option<&I::Output> { i.get(self) } @@ -467,9 +449,8 @@ impl str { /// assert_eq!("HEllo", v); /// ``` #[stable(feature = "str_checked_slicing", since = "1.20.0")] - #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] #[inline] - pub const fn get_mut>(&mut self, i: I) -> Option<&mut I::Output> { + pub fn get_mut>(&mut self, i: I) -> Option<&mut I::Output> { i.get_mut(self) } @@ -500,9 +481,8 @@ impl str { /// } /// ``` #[stable(feature = "str_checked_slicing", since = "1.20.0")] - #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] #[inline] - pub const unsafe fn get_unchecked>(&self, i: I) -> &I::Output { + pub unsafe fn get_unchecked>(&self, i: I) -> &I::Output { // SAFETY: the caller must uphold the safety contract for `get_unchecked`; // the slice is dereferenceable because `self` is a safe reference. // The returned pointer is safe because impls of `SliceIndex` have to guarantee that it is. @@ -536,12 +516,8 @@ impl str { /// } /// ``` #[stable(feature = "str_checked_slicing", since = "1.20.0")] - #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] #[inline] - pub const unsafe fn get_unchecked_mut>( - &mut self, - i: I, - ) -> &mut I::Output { + pub unsafe fn get_unchecked_mut>(&mut self, i: I) -> &mut I::Output { // SAFETY: the caller must uphold the safety contract for `get_unchecked_mut`; // the slice is dereferenceable because `self` is a safe reference. // The returned pointer is safe because impls of `SliceIndex` have to guarantee that it is. @@ -2566,8 +2542,7 @@ impl AsRef<[u8]> for str { } #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] -impl const Default for &str { +impl Default for &str { /// Creates an empty str #[inline] fn default() -> Self { diff --git a/library/core/src/str/traits.rs b/library/core/src/str/traits.rs index 32c31803a5115..bc5ab07136aba 100644 --- a/library/core/src/str/traits.rs +++ b/library/core/src/str/traits.rs @@ -53,10 +53,9 @@ impl PartialOrd for str { } #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_slice_index", issue = "none")] -impl const ops::Index for str +impl ops::Index for str where - I: ~const SliceIndex, + I: SliceIndex, { type Output = I::Output; @@ -67,10 +66,9 @@ where } #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_slice_index", issue = "none")] -impl const ops::IndexMut for str +impl ops::IndexMut for str where - I: ~const SliceIndex, + I: SliceIndex, { #[inline] fn index_mut(&mut self, index: I) -> &mut I::Output { @@ -98,8 +96,7 @@ const fn str_index_overflow_fail() -> ! { /// /// Equivalent to `&self[0 .. len]` or `&mut self[0 .. len]`. #[stable(feature = "str_checked_slicing", since = "1.20.0")] -#[rustc_const_unstable(feature = "const_slice_index", issue = "none")] -unsafe impl const SliceIndex for ops::RangeFull { +unsafe impl SliceIndex for ops::RangeFull { type Output = str; #[inline] fn get(self, slice: &str) -> Option<&Self::Output> { @@ -163,8 +160,7 @@ unsafe impl const SliceIndex for ops::RangeFull { /// // &s[3 .. 100]; /// ``` #[stable(feature = "str_checked_slicing", since = "1.20.0")] -#[rustc_const_unstable(feature = "const_slice_index", issue = "none")] -unsafe impl const SliceIndex for ops::Range { +unsafe impl SliceIndex for ops::Range { type Output = str; #[inline] fn get(self, slice: &str) -> Option<&Self::Output> { @@ -251,8 +247,7 @@ unsafe impl const SliceIndex for ops::Range { /// Panics if `end` does not point to the starting byte offset of a /// character (as defined by `is_char_boundary`), or if `end > len`. #[stable(feature = "str_checked_slicing", since = "1.20.0")] -#[rustc_const_unstable(feature = "const_slice_index", issue = "none")] -unsafe impl const SliceIndex for ops::RangeTo { +unsafe impl SliceIndex for ops::RangeTo { type Output = str; #[inline] fn get(self, slice: &str) -> Option<&Self::Output> { @@ -322,8 +317,7 @@ unsafe impl const SliceIndex for ops::RangeTo { /// Panics if `begin` does not point to the starting byte offset of /// a character (as defined by `is_char_boundary`), or if `begin > len`. #[stable(feature = "str_checked_slicing", since = "1.20.0")] -#[rustc_const_unstable(feature = "const_slice_index", issue = "none")] -unsafe impl const SliceIndex for ops::RangeFrom { +unsafe impl SliceIndex for ops::RangeFrom { type Output = str; #[inline] fn get(self, slice: &str) -> Option<&Self::Output> { @@ -399,8 +393,7 @@ unsafe impl const SliceIndex for ops::RangeFrom { /// to the ending byte offset of a character (`end + 1` is either a starting /// byte offset or equal to `len`), if `begin > end`, or if `end >= len`. #[stable(feature = "inclusive_range", since = "1.26.0")] -#[rustc_const_unstable(feature = "const_slice_index", issue = "none")] -unsafe impl const SliceIndex for ops::RangeInclusive { +unsafe impl SliceIndex for ops::RangeInclusive { type Output = str; #[inline] fn get(self, slice: &str) -> Option<&Self::Output> { @@ -451,8 +444,7 @@ unsafe impl const SliceIndex for ops::RangeInclusive { /// (`end + 1` is either a starting byte offset as defined by /// `is_char_boundary`, or equal to `len`), or if `end >= len`. #[stable(feature = "inclusive_range", since = "1.26.0")] -#[rustc_const_unstable(feature = "const_slice_index", issue = "none")] -unsafe impl const SliceIndex for ops::RangeToInclusive { +unsafe impl SliceIndex for ops::RangeToInclusive { type Output = str; #[inline] fn get(self, slice: &str) -> Option<&Self::Output> { diff --git a/library/core/src/str/validations.rs b/library/core/src/str/validations.rs index 04bc665233e38..f38d68912f03d 100644 --- a/library/core/src/str/validations.rs +++ b/library/core/src/str/validations.rs @@ -123,8 +123,7 @@ const fn contains_nonascii(x: usize) -> bool { /// Walks through `v` checking that it's a valid UTF-8 sequence, /// returning `Ok(())` in that case, or, if it is invalid, `Err(err)`. #[inline(always)] -#[rustc_const_unstable(feature = "str_internals", issue = "none")] -pub(super) const fn run_utf8_validation(v: &[u8]) -> Result<(), Utf8Error> { +pub(super) fn run_utf8_validation(v: &[u8]) -> Result<(), Utf8Error> { let mut index = 0; let len = v.len(); diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index ebc769ac7ca3b..45f6f3c72dae4 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -147,8 +147,7 @@ pub struct AtomicBool { #[cfg(target_has_atomic_load_store = "8")] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] -impl const Default for AtomicBool { +impl Default for AtomicBool { /// Creates an `AtomicBool` initialized to `false`. #[inline] fn default() -> Self { @@ -179,8 +178,7 @@ pub struct AtomicPtr { #[cfg(target_has_atomic_load_store = "ptr")] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] -impl const Default for AtomicPtr { +impl Default for AtomicPtr { /// Creates a null `AtomicPtr`. fn default() -> AtomicPtr { AtomicPtr::new(crate::ptr::null_mut()) @@ -1796,8 +1794,7 @@ impl AtomicPtr { #[cfg(target_has_atomic_load_store = "8")] #[stable(feature = "atomic_bool_from", since = "1.24.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl const From for AtomicBool { +impl From for AtomicBool { /// Converts a `bool` into an `AtomicBool`. /// /// # Examples @@ -1815,8 +1812,7 @@ impl const From for AtomicBool { #[cfg(target_has_atomic_load_store = "ptr")] #[stable(feature = "atomic_from", since = "1.23.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl const From<*mut T> for AtomicPtr { +impl From<*mut T> for AtomicPtr { /// Converts a `*mut T` into an `AtomicPtr`. #[inline] fn from(p: *mut T) -> Self { @@ -1882,8 +1878,7 @@ macro_rules! atomic_int { pub const $atomic_init: $atomic_type = $atomic_type::new(0); #[$stable] - #[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] - impl const Default for $atomic_type { + impl Default for $atomic_type { #[inline] fn default() -> Self { Self::new(Default::default()) @@ -1891,8 +1886,7 @@ macro_rules! atomic_int { } #[$stable_from] - #[rustc_const_unstable(feature = "const_num_from_num", issue = "87852")] - impl const From<$int_type> for $atomic_type { + impl From<$int_type> for $atomic_type { #[doc = concat!("Converts an `", stringify!($int_type), "` into an `", stringify!($atomic_type), "`.")] #[inline] fn from(v: $int_type) -> Self { Self::new(v) } diff --git a/library/core/src/task/poll.rs b/library/core/src/task/poll.rs index 41f0a25dbc3e0..c06f2cf9ff5c2 100644 --- a/library/core/src/task/poll.rs +++ b/library/core/src/task/poll.rs @@ -241,8 +241,7 @@ impl Poll>> { } #[stable(feature = "futures_api", since = "1.36.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl const From for Poll { +impl From for Poll { /// Moves the value into a [`Poll::Ready`] to make a `Poll`. /// /// # Example diff --git a/library/core/src/time.rs b/library/core/src/time.rs index 756f1a1663ca7..ba6fe0dfbd31e 100644 --- a/library/core/src/time.rs +++ b/library/core/src/time.rs @@ -737,8 +737,7 @@ impl Duration { #[stable(feature = "duration_float", since = "1.38.0")] #[must_use] #[inline] - #[rustc_const_unstable(feature = "duration_consts_float", issue = "72440")] - pub const fn from_secs_f64(secs: f64) -> Duration { + pub fn from_secs_f64(secs: f64) -> Duration { match Duration::try_from_secs_f64(secs) { Ok(v) => v, Err(e) => panic!("{}", e.description()), @@ -775,8 +774,7 @@ impl Duration { #[stable(feature = "duration_float", since = "1.38.0")] #[must_use] #[inline] - #[rustc_const_unstable(feature = "duration_consts_float", issue = "72440")] - pub const fn from_secs_f32(secs: f32) -> Duration { + pub fn from_secs_f32(secs: f32) -> Duration { match Duration::try_from_secs_f32(secs) { Ok(v) => v, Err(e) => panic!("{}", e.description()), @@ -800,8 +798,7 @@ impl Duration { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - #[rustc_const_unstable(feature = "duration_consts_float", issue = "72440")] - pub const fn mul_f64(self, rhs: f64) -> Duration { + pub fn mul_f64(self, rhs: f64) -> Duration { Duration::from_secs_f64(rhs * self.as_secs_f64()) } @@ -822,8 +819,7 @@ impl Duration { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - #[rustc_const_unstable(feature = "duration_consts_float", issue = "72440")] - pub const fn mul_f32(self, rhs: f32) -> Duration { + pub fn mul_f32(self, rhs: f32) -> Duration { Duration::from_secs_f32(rhs * self.as_secs_f32()) } @@ -844,8 +840,7 @@ impl Duration { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - #[rustc_const_unstable(feature = "duration_consts_float", issue = "72440")] - pub const fn div_f64(self, rhs: f64) -> Duration { + pub fn div_f64(self, rhs: f64) -> Duration { Duration::from_secs_f64(self.as_secs_f64() / rhs) } @@ -868,8 +863,7 @@ impl Duration { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - #[rustc_const_unstable(feature = "duration_consts_float", issue = "72440")] - pub const fn div_f32(self, rhs: f32) -> Duration { + pub fn div_f32(self, rhs: f32) -> Duration { Duration::from_secs_f32(self.as_secs_f32() / rhs) } @@ -1389,7 +1383,7 @@ impl Duration { /// ``` #[unstable(feature = "duration_checked_float", issue = "83400")] #[inline] - pub const fn try_from_secs_f32(secs: f32) -> Result { + pub fn try_from_secs_f32(secs: f32) -> Result { try_from_secs!( secs = secs, mantissa_bits = 23, @@ -1467,7 +1461,7 @@ impl Duration { /// ``` #[unstable(feature = "duration_checked_float", issue = "83400")] #[inline] - pub const fn try_from_secs_f64(secs: f64) -> Result { + pub fn try_from_secs_f64(secs: f64) -> Result { try_from_secs!( secs = secs, mantissa_bits = 52, From 03d3d0d80ed41d63b8e7a82059e266b9d906997f Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 1 Jun 2022 09:23:07 +0000 Subject: [PATCH 30/51] Fix up some trivial test changes --- src/test/ui/rfc-2632-const-trait-impl/attr-misuse.rs | 1 + src/test/ui/unsized/issue-30355.rs | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/ui/rfc-2632-const-trait-impl/attr-misuse.rs b/src/test/ui/rfc-2632-const-trait-impl/attr-misuse.rs index 01ac74feff74d..ddc6ca80c38fe 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/attr-misuse.rs +++ b/src/test/ui/rfc-2632-const-trait-impl/attr-misuse.rs @@ -8,3 +8,4 @@ trait A { #[const_trait] //~ ERROR attribute should be applied fn main() {} +//~^ ERROR `main` function is not allowed to have generic parameters diff --git a/src/test/ui/unsized/issue-30355.rs b/src/test/ui/unsized/issue-30355.rs index 0181109050320..6ff5b37f6e5b9 100644 --- a/src/test/ui/unsized/issue-30355.rs +++ b/src/test/ui/unsized/issue-30355.rs @@ -4,7 +4,6 @@ pub static Y: &'static X = { const Y: &'static [u8] = b""; &X(*Y) //~^ ERROR E0277 - //~| ERROR E0277 }; fn main() {} From 2b7ec4f03ca264c74e6e9190c8ef196473f54f07 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 1 Jun 2022 13:04:55 +0000 Subject: [PATCH 31/51] Require explicitly handling the tristate constness --- compiler/rustc_middle/src/ty/mod.rs | 6 ------ compiler/rustc_middle/src/ty/sty.rs | 4 ++-- .../src/traits/error_reporting/mod.rs | 2 +- .../src/traits/select/candidate_assembly.rs | 2 +- .../src/traits/select/confirmation.rs | 2 +- .../src/traits/select/mod.rs | 8 ++++++-- .../src/impl_wf_check/min_specialization.rs | 5 +---- .../const-default-method-bodies.stderr | 7 ++++--- ...ault-method-body-is-const-same-trait-ck.stderr | 15 ++++----------- .../impl-with-default-fn-fail.stderr | 9 ++++++++- 10 files changed, 28 insertions(+), 32 deletions(-) diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 80ea92e8766ba..b7260dcb85287 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -317,12 +317,6 @@ pub enum ConstnessArg { Param, } -impl ConstnessArg { - pub fn is_const(self) -> bool { - matches!(self, ConstnessArg::Required) - } -} - impl fmt::Display for ConstnessArg { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str(match self { diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index cb80704bffcbd..2bf35aec4bf4b 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -826,7 +826,7 @@ impl<'tcx> TraitRef<'tcx> { } pub fn without_const(mut self, tcx: TyCtxt<'tcx>) -> Self { - if self.constness().is_const() { + if self.constness() != ty::ConstnessArg::Not { self.substs = tcx.mk_substs(self.substs.iter().map(|arg| match arg.unpack() { ty::subst::GenericArgKind::Constness(_) => ty::ConstnessArg::Not.into(), _ => arg, @@ -837,7 +837,7 @@ impl<'tcx> TraitRef<'tcx> { } pub fn with_const(mut self, tcx: TyCtxt<'tcx>) -> Self { - if !self.constness().is_const() { + if self.constness() != ty::ConstnessArg::Required { self.substs = tcx.mk_substs(self.substs.iter().map(|arg| match arg.unpack() { ty::subst::GenericArgKind::Constness(_) => ty::ConstnessArg::Required.into(), _ => arg, 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 b914135543b47..ff3037b4bafaf 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -489,7 +489,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { self.suggest_borrowing_for_object_cast(&mut err, &root_obligation, *concrete_ty, *obj_ty); } - if trait_predicate.constness().is_const() { + if trait_predicate.constness() != ty::ConstnessArg::Not { let non_const_predicate = trait_ref.without_const(self.tcx); let non_const_obligation = Obligation { cause: obligation.cause.clone(), 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 b5eaaea885156..66f9d3fb9507e 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -957,7 +957,7 @@ 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.predicate.constness().is_const() { + if obligation.predicate.constness() == ty::ConstnessArg::Not { 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 49dc01eb22861..f5a967c885bdd 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -1101,7 +1101,7 @@ 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.predicate.constness().is_const() { + if obligation.predicate.constness() == ty::ConstnessArg::Not { return Ok(ImplSourceConstDestructData { nested: vec![] }); } diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 1d68c1a6f940b..91433b51448e4 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1191,12 +1191,16 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { for candidate in candidates { // Respect const trait obligations - if obligation.predicate.constness().is_const() { + if obligation.predicate.constness() == ty::ConstnessArg::Const { match candidate { // const impl ImplCandidate(def_id) if tcx.constness(def_id) == hir::Constness::Const => {} // const param - ParamCandidate(trait_pred) if trait_pred.constness().is_const() => {} + ParamCandidate(trait_pred) + if trait_pred.constness() != ty::ConstnessArg::Not => + { + debug_assert_eq!(trait_pred.constness(), ty::ConstnessArg::Param); + } // auto trait impl AutoImplCandidate(..) => {} // generator, this will raise error in other places diff --git a/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs b/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs index 04742518cd0d7..783206e40bf0d 100644 --- a/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs +++ b/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs @@ -369,10 +369,7 @@ fn check_specialization_on<'tcx>(tcx: TyCtxt<'tcx>, predicate: ty::Predicate<'tc _ if predicate.is_global() => (), // We allow specializing on explicitly marked traits with no associated // items. - ty::PredicateKind::Trait(ty::TraitPredicate { - trait_ref, - polarity: _, - }) if !trait_ref.constness().is_const() => { // TODO fix this + ty::PredicateKind::Trait(ty::TraitPredicate { trait_ref, polarity: _ }) => { if !matches!( trait_predicate_kind(tcx, predicate), Some(TraitSpecializationKind::Marker) diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-default-method-bodies.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-default-method-bodies.stderr index fe788b43a5416..370211cb1951a 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/const-default-method-bodies.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/const-default-method-bodies.stderr @@ -5,10 +5,11 @@ 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:18 + --> $DIR/const-default-method-bodies.rs:15:6 | -LL | NonConstImpl.a(); - | ^^^ +LL | impl ConstDefaultFn for NonConstImpl { + | ^^^^^^^^^^^^^^ + = help: the trait `ConstDefaultFn` is implemented for `NonConstImpl` error[E0015]: cannot call non-const fn `::a` in constant functions --> $DIR/const-default-method-bodies.rs:24:18 diff --git a/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr b/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr index 8bb7f0141033d..a8c65f81878fc 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr @@ -5,18 +5,11 @@ 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:12 - | -LL | ().a() - | ^^^ - -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() - | ^^^ + --> $DIR/default-method-body-is-const-same-trait-ck.rs:14:6 | - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants +LL | impl Tr for () {} + | ^^ + = help: the trait `Tr` is implemented for `()` error: aborting due to 2 previous errors diff --git a/src/test/ui/rfc-2632-const-trait-impl/impl-with-default-fn-fail.stderr b/src/test/ui/rfc-2632-const-trait-impl/impl-with-default-fn-fail.stderr index 6c6ca9f5db820..0169538fc425e 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/impl-with-default-fn-fail.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/impl-with-default-fn-fail.stderr @@ -5,7 +5,14 @@ LL | fn req(&self); | -------------- `req` from trait ... LL | impl const Tr for u16 { - | ^^^^^^^^^^^^^^^^^^^^^ missing `req` in implementation + | ^^ the trait `Tr` is not implemented for `u16` + | +note: the trait `Tr` is implemented for `u16`, but that implementation is not `const` + --> $DIR/impl-with-default-fn-fail.rs:12:12 + | +LL | impl const Tr for u16 { + | ^^ + = help: the trait `Tr` is implemented for `u16` error: aborting due to previous error From 4c0f2d0b529b4c8e27f4682e19a8afffe1e31cfe Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 1 Jun 2022 18:19:38 +0000 Subject: [PATCH 32/51] Actually substitute constness params --- compiler/rustc_middle/src/ty/context.rs | 2 +- compiler/rustc_middle/src/ty/fold.rs | 12 ++++++++ compiler/rustc_middle/src/ty/print/pretty.rs | 7 +++++ .../rustc_middle/src/ty/structural_impls.rs | 28 ++++++++++++++++- compiler/rustc_middle/src/ty/subst.rs | 18 +++++++++-- compiler/rustc_typeck/src/astconv/mod.rs | 27 +++++++++++++---- compiler/rustc_typeck/src/collect.rs | 7 ++++- .../call-const-trait-method-fail.rs | 4 +-- .../call-const-trait-method-fail.stderr | 26 ++++++---------- .../call-generic-method-fail.rs | 3 +- .../const-default-method-bodies.rs | 3 +- .../const-default-method-bodies.stderr | 30 ++++++++----------- .../cross-crate.gated.stderr | 21 ++++--------- .../cross-crate.stock.stderr | 20 +++++-------- ...ault-method-body-is-const-same-trait-ck.rs | 3 +- ...-method-body-is-const-same-trait-ck.stderr | 17 +++++------ .../impl-with-default-fn-fail.stderr | 9 +----- .../rfc-2632-const-trait-impl/issue-88155.rs | 3 +- 18 files changed, 141 insertions(+), 99 deletions(-) diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 1b6ae3cb55813..6e386bfe1bd2f 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1824,7 +1824,7 @@ nop_list_lift! {bound_variable_kinds; ty::BoundVariableKind => ty::BoundVariable // This is the impl for `&'a InternalSubsts<'a>`. nop_list_lift! {substs; GenericArg<'a> => GenericArg<'tcx>} -CloneLiftImpls! { for<'tcx> { Constness, traits::WellFormedLoc, } } +CloneLiftImpls! { for<'tcx> { ty::ConstnessArg, Constness, traits::WellFormedLoc, } } pub mod tls { use super::{ptr_eq, GlobalCtxt, TyCtxt}; diff --git a/compiler/rustc_middle/src/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs index f8893ae29f58e..624e45b8fb928 100644 --- a/compiler/rustc_middle/src/ty/fold.rs +++ b/compiler/rustc_middle/src/ty/fold.rs @@ -131,6 +131,10 @@ pub trait TypeFolder<'tcx>: FallibleTypeFolder<'tcx, Error = !> { uv.super_fold_with(self) } + fn fold_constness(&mut self, c: ty::ConstnessArg) -> ty::ConstnessArg { + c.super_fold_with(self) + } + fn fold_predicate(&mut self, p: ty::Predicate<'tcx>) -> ty::Predicate<'tcx> { p.super_fold_with(self) } @@ -178,6 +182,10 @@ pub trait FallibleTypeFolder<'tcx>: Sized { c.try_super_fold_with(self) } + fn try_fold_constness(&mut self, c: ty::ConstnessArg) -> Result { + c.try_super_fold_with(self) + } + fn try_fold_predicate( &mut self, p: ty::Predicate<'tcx>, @@ -224,6 +232,10 @@ where Ok(self.fold_const(c)) } + fn try_fold_constness(&mut self, c: ty::ConstnessArg) -> Result { + Ok(self.fold_constness(c)) + } + fn try_fold_unevaluated( &mut self, c: ty::Unevaluated<'tcx>, diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 21cd417708918..73ab09688646a 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -2519,6 +2519,13 @@ define_print_and_forward_display! { } TraitRefPrintOnlyTraitPath<'tcx> { + if cx.tcx().sess.verbose() { + match self.0.constness() { + ty::ConstnessArg::Not => {}, + ty::ConstnessArg::Required => p!(write("const ")), + ty::ConstnessArg::Param => p!(write("~const ")), + } + } p!(print_def_path(self.0.def_id, self.0.substs)); } diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index e668acd0d5d93..625c29d8a285d 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -215,7 +215,6 @@ TrivialTypeTraversalAndLiftImpls! { crate::ty::adjustment::AutoBorrowMutability, crate::ty::AdtKind, crate::ty::BoundConstness, - crate::ty::ConstnessArg, // Including `BoundRegionKind` is a *bit* dubious, but direct // references to bound region appear in `ty::Error`, and aren't // really meant to be folded. In general, we can only fold a fully @@ -1107,6 +1106,33 @@ impl<'tcx> TypeSuperVisitable<'tcx> for ty::Region<'tcx> { } } +impl<'tcx> TypeFoldable<'tcx> for ty::ConstnessArg { + fn try_fold_with>(self, folder: &mut F) -> Result { + folder.try_fold_constness(self) + } +} + +impl<'tcx> TypeSuperFoldable<'tcx> for ty::ConstnessArg { + fn try_super_fold_with>( + self, + _folder: &mut F, + ) -> Result { + Ok(self) + } +} + +impl<'tcx> TypeVisitable<'tcx> for ty::ConstnessArg { + fn visit_with>(&self, visitor: &mut V) -> ControlFlow { + visitor.visit_constness_arg(*self) + } +} + +impl<'tcx> TypeSuperVisitable<'tcx> for ty::ConstnessArg { + fn super_visit_with>(&self, _visitor: &mut V) -> ControlFlow { + ControlFlow::CONTINUE + } +} + impl<'tcx> TypeFoldable<'tcx> for ty::Predicate<'tcx> { fn try_fold_with>(self, folder: &mut F) -> Result { folder.try_fold_predicate(self) diff --git a/compiler/rustc_middle/src/ty/subst.rs b/compiler/rustc_middle/src/ty/subst.rs index 8560799bd7ec7..681716dbb9670 100644 --- a/compiler/rustc_middle/src/ty/subst.rs +++ b/compiler/rustc_middle/src/ty/subst.rs @@ -227,7 +227,7 @@ impl<'tcx> TypeFoldable<'tcx> for GenericArg<'tcx> { GenericArgKind::Lifetime(lt) => lt.try_fold_with(folder).map(Into::into), GenericArgKind::Type(ty) => ty.try_fold_with(folder).map(Into::into), GenericArgKind::Const(ct) => ct.try_fold_with(folder).map(Into::into), - GenericArgKind::Constness(_) => Ok(self), + GenericArgKind::Constness(cn) => cn.try_fold_with(folder).map(Into::into), } } } @@ -238,7 +238,7 @@ impl<'tcx> TypeVisitable<'tcx> for GenericArg<'tcx> { GenericArgKind::Lifetime(lt) => lt.visit_with(visitor), GenericArgKind::Type(ty) => ty.visit_with(visitor), GenericArgKind::Const(ct) => ct.visit_with(visitor), - GenericArgKind::Constness(_) => ControlFlow::CONTINUE, + GenericArgKind::Constness(cn) => cn.visit_with(visitor), } } } @@ -610,6 +610,20 @@ impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> { } } + fn fold_constness(&mut self, c: ty::ConstnessArg) -> ty::ConstnessArg { + if let ty::ConstnessArg::Param = c { + self.substs + .iter() + .find_map(|param| match param.unpack() { + GenericArgKind::Constness(c) => Some(c), + _ => None, + }) + .unwrap_or(c) + } else { + c.super_fold_with(self) + } + } + #[inline] fn fold_mir_const(&mut self, c: mir::ConstantKind<'tcx>) -> mir::ConstantKind<'tcx> { c.super_fold_with(self) diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index 3ff4791b508a0..d50e9a33df18d 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -713,6 +713,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { &self, trait_ref: &hir::TraitRef<'_>, self_ty: Ty<'tcx>, + constness: hir::Constness, ) -> ty::TraitRef<'tcx> { self.prohibit_generics(trait_ref.path.segments.split_last().unwrap().1.iter(), |_| {}); @@ -722,6 +723,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { self_ty, trait_ref.path.segments.last().unwrap(), true, + match constness { + hir::Constness::Const => ty::ConstnessArg::Param, + hir::Constness::NotConst => ty::ConstnessArg::Not, + }, ) } @@ -877,6 +882,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { self_ty: Ty<'tcx>, trait_segment: &hir::PathSegment<'_>, is_impl: bool, + constness: ty::ConstnessArg, ) -> ty::TraitRef<'tcx> { let (substs, _) = self.create_substs_for_ast_trait_ref( span, @@ -884,6 +890,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { self_ty, trait_segment, is_impl, + constness, ); let assoc_bindings = self.create_assoc_bindings_for_generic_args(trait_segment.args()); if let Some(b) = assoc_bindings.first() { @@ -900,6 +907,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { self_ty: Ty<'tcx>, trait_segment: &'a hir::PathSegment<'a>, is_impl: bool, + constness: ty::ConstnessArg, ) -> (SubstsRef<'tcx>, GenericArgCountResult) { self.complain_about_internal_fn_trait(span, trait_def_id, trait_segment, is_impl); @@ -911,7 +919,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { trait_segment.args(), trait_segment.infer_args, Some(self_ty), - Some(ty::ConstnessArg::Not), + Some(constness), ) } @@ -2122,8 +2130,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { debug!("qpath_to_ty: self_type={:?}", self_ty); - let trait_ref = - self.ast_path_to_mono_trait_ref(span, trait_def_id, self_ty, trait_segment, false); + let trait_ref = self.ast_path_to_mono_trait_ref( + span, + trait_def_id, + self_ty, + trait_segment, + false, + ty::ConstnessArg::Not, + ); let item_substs = self.create_substs_for_associated_item( tcx, @@ -2926,8 +2940,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(i), .. }) = hir.get(hir.get_parent_node(fn_hir_id)) else { bug!("ImplItem should have Impl parent") }; - let trait_ref = - self.instantiate_mono_trait_ref(i.of_trait.as_ref()?, self.ast_ty_to_ty(i.self_ty)); + let trait_ref = self.instantiate_mono_trait_ref( + i.of_trait.as_ref()?, + self.ast_ty_to_ty(i.self_ty), + hir::Constness::NotConst, + ); let assoc = tcx.associated_items(trait_ref.def_id).find_by_name_and_kind( tcx, diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 986d002e7fd9a..721ec28d4958f 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -1990,7 +1990,12 @@ fn impl_trait_ref(tcx: TyCtxt<'_>, def_id: DefId) -> Option> { match tcx.hir().expect_item(def_id.expect_local()).kind { hir::ItemKind::Impl(ref impl_) => impl_.of_trait.as_ref().map(|ast_trait_ref| { let selfty = tcx.type_of(def_id); - >::instantiate_mono_trait_ref(&icx, ast_trait_ref, selfty) + >::instantiate_mono_trait_ref( + &icx, + ast_trait_ref, + selfty, + impl_.constness, + ) }), _ => bug!(), } diff --git a/src/test/ui/rfc-2632-const-trait-impl/call-const-trait-method-fail.rs b/src/test/ui/rfc-2632-const-trait-impl/call-const-trait-method-fail.rs index 24b9235bb9a76..691237a56856f 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/call-const-trait-method-fail.rs +++ b/src/test/ui/rfc-2632-const-trait-impl/call-const-trait-method-fail.rs @@ -1,5 +1,6 @@ #![feature(const_trait_impl)] +#[const_trait] pub trait Plus { fn plus(self, rhs: Self) -> Self; } @@ -22,8 +23,7 @@ pub const fn add_i32(a: i32, b: i32) -> i32 { pub const fn add_u32(a: u32, b: u32) -> u32 { a.plus(b) - //~^ ERROR the trait bound - //~| ERROR cannot call non-const fn + //~^ ERROR no method named `plus` found for type `u32` in the current scope } fn main() {} diff --git a/src/test/ui/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr b/src/test/ui/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr index 1fc9db277610e..bd91395fe5562 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr @@ -1,24 +1,16 @@ -error[E0277]: the trait bound `u32: ~const Plus` is not satisfied - --> $DIR/call-const-trait-method-fail.rs:24:7 +error[E0599]: no method named `plus` found for type `u32` in the current scope + --> $DIR/call-const-trait-method-fail.rs:25:7 | LL | a.plus(b) - | ^^^^^^^ the trait `~const Plus` is not implemented for `u32` + | ^^^^ method not found in `u32` | -note: the trait `Plus` is implemented for `u32`, but that implementation is not `const` - --> $DIR/call-const-trait-method-fail.rs:24:7 + = help: items from traits can only be used if the trait is implemented and in scope +note: `Plus` defines an item `plus`, perhaps you need to implement it + --> $DIR/call-const-trait-method-fail.rs:4:1 | -LL | a.plus(b) - | ^^^^^^^ - -error[E0015]: cannot call non-const fn `::plus` in constant functions - --> $DIR/call-const-trait-method-fail.rs:24:7 - | -LL | a.plus(b) - | ^^^^^^^ - | - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants +LL | pub trait Plus { + | ^^^^^^^^^^^^^^ 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 E0599`. diff --git a/src/test/ui/rfc-2632-const-trait-impl/call-generic-method-fail.rs b/src/test/ui/rfc-2632-const-trait-impl/call-generic-method-fail.rs index 8df68225d44cd..a9b653f82dd63 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/call-generic-method-fail.rs +++ b/src/test/ui/rfc-2632-const-trait-impl/call-generic-method-fail.rs @@ -2,8 +2,7 @@ pub const fn equals_self(t: &T) -> bool { *t == *t - //~^ ERROR can't compare - //~| ERROR cannot call non-const + //~^ ERROR cannot call non-const } fn main() {} diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-default-method-bodies.rs b/src/test/ui/rfc-2632-const-trait-impl/const-default-method-bodies.rs index 0b981d1621eca..484a2fd4d5702 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/const-default-method-bodies.rs +++ b/src/test/ui/rfc-2632-const-trait-impl/const-default-method-bodies.rs @@ -22,8 +22,7 @@ impl const ConstDefaultFn for ConstImpl { const fn test() { NonConstImpl.a(); - //~^ ERROR the trait bound - //~| ERROR cannot call non-const fn + //~^ ERROR no method named `a` found for struct `NonConstImpl` ConstImpl.a(); } diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-default-method-bodies.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-default-method-bodies.stderr index 370211cb1951a..98284d6a239a5 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/const-default-method-bodies.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/const-default-method-bodies.stderr @@ -1,25 +1,19 @@ -error[E0277]: the trait bound `NonConstImpl: ~const ConstDefaultFn` is not satisfied +error[E0599]: no method named `a` found for struct `NonConstImpl` in the current scope --> $DIR/const-default-method-bodies.rs:24:18 | +LL | struct NonConstImpl; + | -------------------- method `a` not found for this +... LL | NonConstImpl.a(); - | ^^^ the trait `~const ConstDefaultFn` is not implemented for `NonConstImpl` + | ^ method not found in `NonConstImpl` | -note: the trait `ConstDefaultFn` is implemented for `NonConstImpl`, but that implementation is not `const` - --> $DIR/const-default-method-bodies.rs:15:6 + = help: items from traits can only be used if the trait is implemented and in scope +note: `ConstDefaultFn` defines an item `a`, perhaps you need to implement it + --> $DIR/const-default-method-bodies.rs:4:1 | -LL | impl ConstDefaultFn for NonConstImpl { - | ^^^^^^^^^^^^^^ - = help: the trait `ConstDefaultFn` is implemented for `NonConstImpl` +LL | trait ConstDefaultFn: Sized { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0015]: cannot call non-const fn `::a` in constant functions - --> $DIR/const-default-method-bodies.rs:24:18 - | -LL | NonConstImpl.a(); - | ^^^ - | - = 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 E0599`. diff --git a/src/test/ui/rfc-2632-const-trait-impl/cross-crate.gated.stderr b/src/test/ui/rfc-2632-const-trait-impl/cross-crate.gated.stderr index 3ca9abb139b86..42203a46f5b83 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/cross-crate.gated.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/cross-crate.gated.stderr @@ -1,24 +1,15 @@ -error[E0277]: the trait bound `cross_crate::NonConst: ~const cross_crate::MyTrait` is not satisfied - --> $DIR/cross-crate.rs:15:14 - | -LL | NonConst.func(); - | ^^^^^^ the trait `~const cross_crate::MyTrait` is not implemented for `cross_crate::NonConst` - | -note: the trait `cross_crate::MyTrait` is implemented for `cross_crate::NonConst`, but that implementation is not `const` - --> $DIR/cross-crate.rs:15:14 +error[E0599]: no method named `func` found for struct `cross_crate::NonConst` in the current scope + --> $DIR/cross-crate.rs:10:14 | LL | NonConst.func(); - | ^^^^^^ + | ^^^^ method not found in `cross_crate::NonConst` -error[E0015]: cannot call non-const fn `::func` in constant functions +error[E0599]: no method named `func` found for struct `cross_crate::NonConst` in the current scope --> $DIR/cross-crate.rs:15:14 | LL | NonConst.func(); - | ^^^^^^ - | - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants + | ^^^^ method not found in `cross_crate::NonConst` 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 E0599`. diff --git a/src/test/ui/rfc-2632-const-trait-impl/cross-crate.stock.stderr b/src/test/ui/rfc-2632-const-trait-impl/cross-crate.stock.stderr index ea75ad0aeaf8c..42203a46f5b83 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/cross-crate.stock.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/cross-crate.stock.stderr @@ -1,19 +1,15 @@ -error[E0015]: cannot call non-const fn `::func` in constant functions - --> $DIR/cross-crate.rs:15:14 +error[E0599]: no method named `func` found for struct `cross_crate::NonConst` in the current scope + --> $DIR/cross-crate.rs:10:14 | LL | NonConst.func(); - | ^^^^^^ - | - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants + | ^^^^ method not found in `cross_crate::NonConst` -error[E0015]: cannot call non-const fn `::func` in constant functions - --> $DIR/cross-crate.rs:17:11 - | -LL | Const.func(); - | ^^^^^^ +error[E0599]: no method named `func` found for struct `cross_crate::NonConst` in the current scope + --> $DIR/cross-crate.rs:15:14 | - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants +LL | NonConst.func(); + | ^^^^ method not found in `cross_crate::NonConst` error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0015`. +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.rs b/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.rs index d798516ff70fd..8bb4e39cc0157 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.rs +++ b/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.rs @@ -6,8 +6,7 @@ pub trait Tr { fn b(&self) { ().a() - //~^ ERROR the trait bound - //~| ERROR cannot call + //~^ ERROR no method named `a` found for unit type `()` in the current scope } } diff --git a/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr b/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr index a8c65f81878fc..f0e0eb1e67681 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr @@ -1,17 +1,16 @@ -error[E0277]: the trait bound `(): ~const Tr` is not satisfied +error[E0599]: no method named `a` found for unit type `()` in the current scope --> $DIR/default-method-body-is-const-same-trait-ck.rs:8:12 | LL | ().a() - | ^^^ the trait `~const Tr` is not implemented for `()` + | ^ method not found in `()` | -note: the trait `Tr` is implemented for `()`, but that implementation is not `const` - --> $DIR/default-method-body-is-const-same-trait-ck.rs:14:6 + = help: items from traits can only be used if the trait is implemented and in scope +note: `Tr` defines an item `a`, perhaps you need to implement it + --> $DIR/default-method-body-is-const-same-trait-ck.rs:4:1 | -LL | impl Tr for () {} - | ^^ - = help: the trait `Tr` is implemented for `()` +LL | pub trait Tr { + | ^^^^^^^^^^^^ 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 E0599`. diff --git a/src/test/ui/rfc-2632-const-trait-impl/impl-with-default-fn-fail.stderr b/src/test/ui/rfc-2632-const-trait-impl/impl-with-default-fn-fail.stderr index 0169538fc425e..6c6ca9f5db820 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/impl-with-default-fn-fail.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/impl-with-default-fn-fail.stderr @@ -5,14 +5,7 @@ LL | fn req(&self); | -------------- `req` from trait ... LL | impl const Tr for u16 { - | ^^ the trait `Tr` is not implemented for `u16` - | -note: the trait `Tr` is implemented for `u16`, but that implementation is not `const` - --> $DIR/impl-with-default-fn-fail.rs:12:12 - | -LL | impl const Tr for u16 { - | ^^ - = help: the trait `Tr` is implemented for `u16` + | ^^^^^^^^^^^^^^^^^^^^^ missing `req` in implementation error: aborting due to previous error diff --git a/src/test/ui/rfc-2632-const-trait-impl/issue-88155.rs b/src/test/ui/rfc-2632-const-trait-impl/issue-88155.rs index b132c395ac7b4..46f6343002642 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/issue-88155.rs +++ b/src/test/ui/rfc-2632-const-trait-impl/issue-88155.rs @@ -6,8 +6,7 @@ pub trait A { pub const fn foo() -> bool { T::assoc() - //~^ ERROR the trait bound - //~| ERROR cannot call non-const fn + //~^ ERROR cannot call non-const fn } fn main() {} From d0db6fefbc147f423c8a40ce4352ca346bab6495 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 1 Jun 2022 18:19:51 +0000 Subject: [PATCH 33/51] Some tracing for better debugging --- compiler/rustc_trait_selection/src/traits/wf.rs | 6 +++++- compiler/rustc_typeck/src/astconv/mod.rs | 1 + compiler/rustc_typeck/src/check/wfcheck.rs | 2 ++ compiler/rustc_typeck/src/collect.rs | 1 + 4 files changed, 9 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 392ff2ccad4aa..483c4193f6016 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -295,11 +295,12 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { } /// Pushes the obligations required for `trait_ref` to be WF into `self.out`. + #[instrument(level = "debug", skip(self))] fn compute_trait_ref(&mut self, trait_ref: &ty::TraitRef<'tcx>, elaborate: Elaborate) { let tcx = self.infcx.tcx; let obligations = self.nominal_obligations(trait_ref.def_id, trait_ref.substs); - debug!("compute_trait_ref obligations {:?}", obligations); + debug!(?obligations); let param_env = self.param_env; let depth = self.recursion_depth; @@ -699,12 +700,14 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { } } + #[instrument(level = "trace", skip(self))] fn nominal_obligations( &mut self, def_id: DefId, substs: SubstsRef<'tcx>, ) -> Vec> { let predicates = self.infcx.tcx.predicates_of(def_id); + trace!(?predicates); let mut origins = vec![def_id; predicates.predicates.len()]; let mut head = predicates; while let Some(parent) = head.parent { @@ -713,6 +716,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { } let predicates = predicates.instantiate(self.infcx.tcx, substs); + trace!(?predicates, "instantiated"); debug_assert_eq!(predicates.predicates.len(), origins.len()); iter::zip(iter::zip(predicates.predicates, predicates.spans), origins.into_iter().rev()) diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index d50e9a33df18d..da195c133cd87 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -709,6 +709,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { /// /// If the `projections` argument is `None`, then assoc type bindings like `Foo` /// are disallowed. Otherwise, they are pushed onto the vector given. + #[instrument(level = "debug", skip(self))] pub fn instantiate_mono_trait_ref( &self, trait_ref: &hir::TraitRef<'_>, diff --git a/compiler/rustc_typeck/src/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs index 5ee52981856b7..173753bcf9cd7 100644 --- a/compiler/rustc_typeck/src/check/wfcheck.rs +++ b/compiler/rustc_typeck/src/check/wfcheck.rs @@ -1229,8 +1229,10 @@ fn check_impl<'tcx>( // therefore don't need to be WF (the trait's `Self: Trait` predicate // won't hold). let trait_ref = tcx.impl_trait_ref(item.def_id).unwrap(); + trace!(?trait_ref); let trait_ref = fcx.normalize_associated_types_in(ast_trait_ref.path.span, trait_ref); + trace!(?trait_ref, "normalized"); let obligations = traits::wf::trait_obligations( fcx, fcx.param_env, diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 721ec28d4958f..237407ee2b623 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -1985,6 +1985,7 @@ fn infer_return_ty_for_fn_sig<'tcx>( } } +#[instrument(level = "debug", skip(tcx))] fn impl_trait_ref(tcx: TyCtxt<'_>, def_id: DefId) -> Option> { let icx = ItemCtxt::new(tcx, def_id); match tcx.hir().expect_item(def_id.expect_local()).kind { From 4a58caa70e3b00bc528ac2cf93ec89263e907fff Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Fri, 3 Jun 2022 18:47:50 +1000 Subject: [PATCH 34/51] Fix typeck probing code to use constness from FnCtxt --- compiler/rustc_typeck/src/check/fn_ctxt/mod.rs | 18 ++++++++++++++++++ .../rustc_typeck/src/check/method/probe.rs | 4 +++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs b/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs index 05bcc710e1625..8755ec67a89d9 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs @@ -118,6 +118,7 @@ pub struct FnCtxt<'a, 'tcx> { /// True if the return type has an Opaque type pub(super) return_type_has_opaque: bool, + constness: ty::ConstnessArg, } impl<'a, 'tcx> FnCtxt<'a, 'tcx> { @@ -145,6 +146,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { inh, return_type_pre_known: true, return_type_has_opaque: false, + constness: { + if body_id.is_owner() { + let did = body_id.expect_owner(); + if inh.tcx.is_const_fn_raw(did.to_def_id()) || inh.tcx.is_const_default_method(did.to_def_id()) || inh.tcx.def_kind(did.to_def_id()) == hir::def::DefKind::Const { + ty::ConstnessArg::Param + } else { + ty::ConstnessArg::Not + } + } else { + // TODO: check correctness + ty::ConstnessArg::Not + } + }, } } @@ -163,6 +177,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub fn errors_reported_since_creation(&self) -> bool { self.tcx.sess.err_count() > self.err_count_on_creation } + + pub fn constness(&self) -> ty::ConstnessArg { + self.constness + } } impl<'a, 'tcx> Deref for FnCtxt<'a, 'tcx> { diff --git a/compiler/rustc_typeck/src/check/method/probe.rs b/compiler/rustc_typeck/src/check/method/probe.rs index 4bbe18fe8e9a8..190222b1ee9c5 100644 --- a/compiler/rustc_typeck/src/check/method/probe.rs +++ b/compiler/rustc_typeck/src/check/method/probe.rs @@ -1549,7 +1549,9 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { let predicate = ty::Binder::dummy(trait_ref).to_predicate(self.tcx); parent_pred = Some(predicate); let obligation = traits::Obligation::new(cause, self.param_env, predicate); + trace!(?obligation); if !self.predicate_may_hold(&obligation) { + trace!("predicate does not hold"); result = ProbeResult::NoMatch; if self.probe(|_| { match self.select_trait_candidate(trait_ref) { @@ -1839,7 +1841,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { }; self.next_const_var(self.tcx.type_of(param.def_id), origin).into() } - GenericParamDefKind::Constness => ty::ConstnessArg::Param.into(), + GenericParamDefKind::Constness => self.fcx.constness().into(), }) } From 57493e5cef47a19178b2e35e78b5b45549067857 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Sat, 4 Jun 2022 22:53:30 +1000 Subject: [PATCH 35/51] Introduce ConstnessArg::Infer and fix some tests --- compiler/rustc_infer/src/infer/mod.rs | 3 +-- compiler/rustc_middle/src/ty/fast_reject.rs | 2 ++ compiler/rustc_middle/src/ty/mod.rs | 2 ++ compiler/rustc_middle/src/ty/print/pretty.rs | 1 + compiler/rustc_middle/src/ty/sty.rs | 10 ++++++++++ compiler/rustc_middle/src/ty/subst.rs | 4 +++- .../src/traits/select/mod.rs | 3 ++- compiler/rustc_typeck/src/astconv/generics.rs | 7 ++++++- compiler/rustc_typeck/src/astconv/mod.rs | 6 +++--- .../rustc_typeck/src/check/method/confirm.rs | 14 ++++++++++++-- .../const-trait-const-impl-and-call.rs | 17 +++++++++++++++++ .../const-trait-non-const-impl-and-call.rs | 19 +++++++++++++++++++ 12 files changed, 78 insertions(+), 10 deletions(-) create mode 100644 src/test/ui/rfc-2632-const-trait-impl/const-trait-const-impl-and-call.rs create mode 100644 src/test/ui/rfc-2632-const-trait-impl/const-trait-non-const-impl-and-call.rs diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index bd9f118351916..20b5c8d43e014 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -1199,8 +1199,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { }); self.tcx.mk_const_var(const_var_id, self.tcx.type_of(param.def_id)).into() } - // TODO: this should actually figure out a yes/no answer from the context - GenericParamDefKind::Constness => ty::ConstnessArg::Param.into(), + GenericParamDefKind::Constness => constness.unwrap_or(ty::ConstnessArg::Infer).into(), } } diff --git a/compiler/rustc_middle/src/ty/fast_reject.rs b/compiler/rustc_middle/src/ty/fast_reject.rs index 3e9bd0437cd50..c43d3d48b7553 100644 --- a/compiler/rustc_middle/src/ty/fast_reject.rs +++ b/compiler/rustc_middle/src/ty/fast_reject.rs @@ -417,6 +417,8 @@ impl DeepRejectCtxt { TreatParams::AsPlaceholder => false, TreatParams::AsInfer => true, }, + (ty::ConstnessArg::Infer, _) => true, + (ty::ConstnessArg::Not, ty::ConstnessArg::Required) => true, _ => obligation_ct == impl_ct, } } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index b7260dcb85287..22d911b93832d 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -315,6 +315,7 @@ pub enum ConstnessArg { Required, Not, Param, + Infer, } impl fmt::Display for ConstnessArg { @@ -323,6 +324,7 @@ impl fmt::Display for ConstnessArg { Self::Required => "(constness: required)", Self::Not => "(constness: not)", Self::Param => "(constness: parameterized)", + Self::Infer => "(constness: infer)" }) } } diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 73ab09688646a..df9d62095e059 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -2524,6 +2524,7 @@ define_print_and_forward_display! { ty::ConstnessArg::Not => {}, ty::ConstnessArg::Required => p!(write("const ")), ty::ConstnessArg::Param => p!(write("~const ")), + ty::ConstnessArg::Infer => p!(write("_const ")), // TODO wonky } } p!(print_def_path(self.0.def_id, self.0.substs)); diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 2bf35aec4bf4b..7f519f34c3406 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -815,6 +815,16 @@ impl<'tcx> TraitRef<'tcx> { ty::TraitRef { def_id: trait_id, substs: tcx.intern_substs(&substs[..defs.params.len()]) } } + // TODO remove this hack! + pub fn normalize_constness_equate(&self, tcx: TyCtxt<'tcx>, actual: &mut Self) { + if self.constness() == ty::ConstnessArg::Not { + *actual = tcx.mk_substs(actual.iter().filter(|arg| match arg.unpack() { + ty::subst::GenericArgKind::Constness(_) => false, + _ => true, + })); + } + } + pub fn constness(self) -> ty::ConstnessArg { for arg in self.substs.iter() { match arg.unpack() { diff --git a/compiler/rustc_middle/src/ty/subst.rs b/compiler/rustc_middle/src/ty/subst.rs index 681716dbb9670..a69fc6d26b1e9 100644 --- a/compiler/rustc_middle/src/ty/subst.rs +++ b/compiler/rustc_middle/src/ty/subst.rs @@ -101,6 +101,7 @@ impl<'tcx> GenericArgKind<'tcx> { ty::ConstnessArg::Not => 0, ty::ConstnessArg::Required => 0b100, ty::ConstnessArg::Param => 0b1000, + ty::ConstnessArg::Infer => 0b10000, }, ), }; @@ -182,6 +183,7 @@ impl<'tcx> GenericArg<'tcx> { 0 => ty::ConstnessArg::Not, 0b100 => ty::ConstnessArg::Required, 0b1000 => ty::ConstnessArg::Param, + 0b10000 => ty::ConstnessArg::Infer, _ => intrinsics::unreachable(), }), _ => intrinsics::unreachable(), @@ -611,7 +613,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> { } fn fold_constness(&mut self, c: ty::ConstnessArg) -> ty::ConstnessArg { - if let ty::ConstnessArg::Param = c { + if let ty::ConstnessArg::Param | ty::ConstnessArg::Infer = c { self.substs .iter() .find_map(|param| match param.unpack() { diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 91433b51448e4..e8719465450fa 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -2157,7 +2157,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let impl_substs = self.infcx.fresh_substs_for_item(obligation.cause.span, impl_def_id); - let impl_trait_ref = impl_trait_ref.subst(self.tcx(), impl_substs); + let mut impl_trait_ref = impl_trait_ref.subst(self.tcx(), impl_substs); + placeholder_obligation_trait_ref.normalize_constness_equate(self.tcx(), &mut impl_trait_ref); debug!(?impl_trait_ref); diff --git a/compiler/rustc_typeck/src/astconv/generics.rs b/compiler/rustc_typeck/src/astconv/generics.rs index f9d996c781684..241837969a1db 100644 --- a/compiler/rustc_typeck/src/astconv/generics.rs +++ b/compiler/rustc_typeck/src/astconv/generics.rs @@ -213,7 +213,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // If we have already computed substitutions for parents, we can use those directly. while let Some(¶m) = params.peek() { if let Some(&kind) = parent_substs.get(param.index as usize) { - substs.push(kind); + if let subst::GenericArgKind::Constness(ty::ConstnessArg::Infer) = kind.unpack() + { + substs.push(ctx.inferred_kind(None, param, false, None)) + } else { + substs.push(kind); + } params.next(); } else { break; diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index da195c133cd87..0b5c4fdb7428c 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -574,7 +574,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { .unwrap_or_else(|| match self.astconv.item_def_id() { // no information available // TODO: fall back to `Not`? - None => ty::ConstnessArg::Param, + None => if infer_args { ty::ConstnessArg::Infer } else { ty::ConstnessArg::Param }, Some(context) => { if tcx.generics_of(context).has_constness_param() { ty::ConstnessArg::Param @@ -724,8 +724,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { self_ty, trait_ref.path.segments.last().unwrap(), true, - match constness { - hir::Constness::Const => ty::ConstnessArg::Param, + match constness { // TODO check this again + hir::Constness::Const => ty::ConstnessArg::Required, hir::Constness::NotConst => ty::ConstnessArg::Not, }, ) diff --git a/compiler/rustc_typeck/src/check/method/confirm.rs b/compiler/rustc_typeck/src/check/method/confirm.rs index c787d97d3c493..8ce8489cfbee5 100644 --- a/compiler/rustc_typeck/src/check/method/confirm.rs +++ b/compiler/rustc_typeck/src/check/method/confirm.rs @@ -397,9 +397,19 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { _substs: Option<&[subst::GenericArg<'tcx>]>, param: &ty::GenericParamDef, _infer_args: bool, - _constness: Option, + constness: Option, ) -> subst::GenericArg<'tcx> { - self.cfcx.var_for_def(self.cfcx.span, param) + if let ty::GenericParamDefKind::Constness = param.kind { + let constness = if let Some(constness) = constness { + constness + } else { + self.cfcx.fcx.constness() + }; + debug!("inferred_kind constness={constness:?}"); + constness.into() + } else { + self.cfcx.var_for_def(self.cfcx.span, param) + } } } >::create_substs_for_generic_args( diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-trait-const-impl-and-call.rs b/src/test/ui/rfc-2632-const-trait-impl/const-trait-const-impl-and-call.rs new file mode 100644 index 0000000000000..87ff744a28f48 --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/const-trait-const-impl-and-call.rs @@ -0,0 +1,17 @@ +// check-pass +#![feature(const_trait_impl)] + +#[const_trait] +trait Foo { + fn foo(&self); +} + +struct S; + +impl const Foo for S { + fn foo(&self) {} +} + +const FOO: () = S.foo(); + +fn main() {} \ No newline at end of file diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-trait-non-const-impl-and-call.rs b/src/test/ui/rfc-2632-const-trait-impl/const-trait-non-const-impl-and-call.rs new file mode 100644 index 0000000000000..e928eec48a347 --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/const-trait-non-const-impl-and-call.rs @@ -0,0 +1,19 @@ +// check-pass +#![feature(const_trait_impl)] + +#[const_trait] +trait Foo { + fn foo(&self); +} + +pub struct S; + +impl Foo for S { + fn foo(&self) {} +} + +fn non_const() { + S.foo(); +} + +fn main() {} \ No newline at end of file From cbb2cf8b9e7e80f70a45f14df43abea681009286 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Sat, 4 Jun 2022 23:57:55 +1000 Subject: [PATCH 36/51] Handle matches added by rebase --- .../rustc_infer/src/infer/error_reporting/need_type_info.rs | 4 +++- compiler/rustc_middle/src/ty/generics.rs | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs index b4e1399824ba2..7c4e7214e1ebf 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs @@ -618,7 +618,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> { /// Computes cost for the given source. /// - /// Sources with a small cost are prefer and should result + /// Sources with a small cost are preferred and should result /// in a clearer and idiomatic suggestion. fn source_cost(&self, source: &InferSource<'tcx>) -> usize { #[derive(Clone, Copy)] @@ -631,6 +631,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> { GenericArgKind::Lifetime(_) => 0, // erased GenericArgKind::Type(ty) => self.ty_cost(ty), GenericArgKind::Const(_) => 3, // some non-zero value + GenericArgKind::Constness(_) => 1, } } fn ty_cost(self, ty: Ty<'tcx>) -> usize { @@ -748,6 +749,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> { } match inner.unpack() { GenericArgKind::Lifetime(_) => {} + GenericArgKind::Constness(_) => {} GenericArgKind::Type(ty) => { if matches!(ty.kind(), ty::Opaque(..) | ty::Closure(..) | ty::Generator(..)) { // Opaque types can't be named by the user right now. diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs index b1e544fa7a6bb..db8b71355cfd7 100644 --- a/compiler/rustc_middle/src/ty/generics.rs +++ b/compiler/rustc_middle/src/ty/generics.rs @@ -78,7 +78,7 @@ impl GenericParamDef { match self.kind { GenericParamDefKind::Type { has_default, .. } | GenericParamDefKind::Const { has_default } => has_default, - GenericParamDefKind::Lifetime => false, + GenericParamDefKind::Lifetime | GenericParamDefKind::Constness => false, } } From ad467aec3b798989cfad971e2dbb07da1e6ac3b4 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Mon, 6 Jun 2022 18:05:37 +1000 Subject: [PATCH 37/51] More attempts to fix ui errors --- .../src/transform/check_consts/check.rs | 2 +- .../src/transform/check_consts/qualifs.rs | 4 +-- compiler/rustc_infer/src/infer/combine.rs | 17 ++++++++++ compiler/rustc_infer/src/infer/equate.rs | 9 ++++++ compiler/rustc_infer/src/infer/glb.rs | 11 ++++++- compiler/rustc_infer/src/infer/lub.rs | 10 +++++- .../rustc_infer/src/infer/nll_relate/mod.rs | 18 +++++++++++ compiler/rustc_infer/src/infer/sub.rs | 17 +++++++++- compiler/rustc_middle/src/ty/_match.rs | 14 ++++++++ compiler/rustc_middle/src/ty/relate.rs | 32 +++++++++++++++---- .../src/traits/select/candidate_assembly.rs | 3 +- .../src/traits/select/confirmation.rs | 4 +-- .../src/traits/select/mod.rs | 7 ++-- compiler/rustc_typeck/src/astconv/mod.rs | 2 +- compiler/rustc_typeck/src/check/dropck.rs | 9 +++++- .../rustc_typeck/src/check/fn_ctxt/_impl.rs | 2 +- .../const-trait-bound.rs | 13 ++++++++ 17 files changed, 153 insertions(+), 21 deletions(-) create mode 100644 src/test/ui/rfc-2632-const-trait-impl/const-trait-bound.rs 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 f5225f03b47e6..ec2af7c1800f7 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -736,7 +736,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { }); match implsrc { - Ok(Some(ImplSource::Param(_, ty::ConstnessArg::Required))) => { + Ok(Some(ImplSource::Param(_, ty::ConstnessArg::Required | ty::ConstnessArg::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 b1aa8448678a3..41bdb424590c3 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs @@ -161,7 +161,7 @@ impl Qualif for NeedsNonConstDrop { ty::Binder::dummy(ty::TraitPredicate { trait_ref: ty::TraitRef { def_id: destruct, - substs: cx.tcx.mk_substs_trait(ty, &[ty::ConstnessArg::Required.into()]), + substs: cx.tcx.mk_substs_trait(ty, &[ty::ConstnessArg::Param.into()]), }, polarity: ty::ImplPolarity::Positive, }), @@ -176,7 +176,7 @@ impl Qualif for NeedsNonConstDrop { if !matches!( impl_src, - ImplSource::ConstDestruct(_) | ImplSource::Param(_, ty::ConstnessArg::Required) + ImplSource::ConstDestruct(_) | ImplSource::Param(_, ty::ConstnessArg::Required | ty::ConstnessArg::Param) ) { // If our const destruct candidate is not ConstDestruct or implied by the param env, // then it's bad diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs index 8bf1de34a9b5c..5602598632e2d 100644 --- a/compiler/rustc_infer/src/infer/combine.rs +++ b/compiler/rustc_infer/src/infer/combine.rs @@ -767,6 +767,15 @@ impl<'tcx> TypeRelation<'tcx> for Generalizer<'_, 'tcx> { _ => relate::super_relate_consts(self, c, c), } } + + fn constness_args( + &mut self, + a: ty::ConstnessArg, + b: ty::ConstnessArg, + ) -> RelateResult<'tcx, ty::ConstnessArg> { + assert_eq!(a, b); + Ok(a) + } } pub trait ConstEquateRelation<'tcx>: TypeRelation<'tcx> { @@ -998,4 +1007,12 @@ impl<'tcx> TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> { _ => relate::super_relate_consts(self, c, c), } } + fn constness_args( + &mut self, + a: ty::ConstnessArg, + b: ty::ConstnessArg, + ) -> RelateResult<'tcx, ty::ConstnessArg> { + assert_eq!(a, b); + Ok(a) + } } diff --git a/compiler/rustc_infer/src/infer/equate.rs b/compiler/rustc_infer/src/infer/equate.rs index 3b1798ca73746..712cdd603f88b 100644 --- a/compiler/rustc_infer/src/infer/equate.rs +++ b/compiler/rustc_infer/src/infer/equate.rs @@ -160,6 +160,15 @@ impl<'tcx> TypeRelation<'tcx> for Equate<'_, '_, 'tcx> { } Ok(a) } + + fn constness_args( + &mut self, + a: ty::ConstnessArg, + b: ty::ConstnessArg, + ) -> RelateResult<'tcx, ty::ConstnessArg> { + // TODO handle infer + relate::super_relate_constness(self, a, b) + } } impl<'tcx> ConstEquateRelation<'tcx> for Equate<'_, '_, 'tcx> { diff --git a/compiler/rustc_infer/src/infer/glb.rs b/compiler/rustc_infer/src/infer/glb.rs index 1570a08f3ca8b..7fb51f96cd83f 100644 --- a/compiler/rustc_infer/src/infer/glb.rs +++ b/compiler/rustc_infer/src/infer/glb.rs @@ -7,7 +7,7 @@ use super::Subtype; use crate::infer::combine::ConstEquateRelation; use crate::traits::{ObligationCause, PredicateObligation}; -use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation}; +use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation}; use rustc_middle::ty::{self, Ty, TyCtxt}; /// "Greatest lower bound" (common subtype) @@ -110,6 +110,15 @@ impl<'tcx> TypeRelation<'tcx> for Glb<'_, '_, 'tcx> { Ok(ty::Binder::dummy(self.relate(a.skip_binder(), b.skip_binder())?)) } } + + fn constness_args( + &mut self, + a: ty::ConstnessArg, + b: ty::ConstnessArg, + ) -> RelateResult<'tcx, ty::ConstnessArg> { + // TODO. + relate::super_relate_constness(self, a, b) + } } impl<'combine, 'infcx, 'tcx> LatticeDir<'infcx, 'tcx> for Glb<'combine, 'infcx, 'tcx> { diff --git a/compiler/rustc_infer/src/infer/lub.rs b/compiler/rustc_infer/src/infer/lub.rs index 9f96d52c85034..954656f2532b6 100644 --- a/compiler/rustc_infer/src/infer/lub.rs +++ b/compiler/rustc_infer/src/infer/lub.rs @@ -7,7 +7,7 @@ use super::Subtype; use crate::infer::combine::ConstEquateRelation; use crate::traits::{ObligationCause, PredicateObligation}; -use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation}; +use rustc_middle::ty::relate::{super_relate_constness, Relate, RelateResult, TypeRelation}; use rustc_middle::ty::{self, Ty, TyCtxt}; /// "Least upper bound" (common supertype) @@ -110,6 +110,14 @@ impl<'tcx> TypeRelation<'tcx> for Lub<'_, '_, 'tcx> { Ok(ty::Binder::dummy(self.relate(a.skip_binder(), b.skip_binder())?)) } } + + fn constness_args( + &mut self, + a: ty::ConstnessArg, + b: ty::ConstnessArg, + ) -> RelateResult<'tcx, ty::ConstnessArg> { + super_relate_constness(self, a, b) + } } impl<'tcx> ConstEquateRelation<'tcx> for Lub<'_, '_, 'tcx> { diff --git a/compiler/rustc_infer/src/infer/nll_relate/mod.rs b/compiler/rustc_infer/src/infer/nll_relate/mod.rs index bab4f3e9e362f..2b1c376a46af2 100644 --- a/compiler/rustc_infer/src/infer/nll_relate/mod.rs +++ b/compiler/rustc_infer/src/infer/nll_relate/mod.rs @@ -784,6 +784,15 @@ where Ok(a) } + + fn constness_args( + &mut self, + a: ty::ConstnessArg, + b: ty::ConstnessArg, + ) -> RelateResult<'tcx, ty::ConstnessArg> { + // TODO. + relate::super_relate_constness(self, a, b) + } } impl<'tcx, D> ConstEquateRelation<'tcx> for TypeRelating<'_, 'tcx, D> @@ -1077,4 +1086,13 @@ where self.first_free_index.shift_out(1); Ok(a.rebind(result)) } + + fn constness_args( + &mut self, + a: ty::ConstnessArg, + b: ty::ConstnessArg, + ) -> RelateResult<'tcx, ty::ConstnessArg> { + // TODO + relate::super_relate_constness(self, a, b) + } } diff --git a/compiler/rustc_infer/src/infer/sub.rs b/compiler/rustc_infer/src/infer/sub.rs index b27571275b733..743e263783c96 100644 --- a/compiler/rustc_infer/src/infer/sub.rs +++ b/compiler/rustc_infer/src/infer/sub.rs @@ -4,7 +4,7 @@ use super::SubregionOrigin; use crate::infer::combine::ConstEquateRelation; use crate::infer::{TypeVariableOrigin, TypeVariableOriginKind}; use crate::traits::Obligation; -use rustc_middle::ty::relate::{Cause, Relate, RelateResult, TypeRelation}; +use rustc_middle::ty::relate::{self, Cause, Relate, RelateResult, TypeRelation}; use rustc_middle::ty::visit::TypeVisitable; use rustc_middle::ty::TyVar; use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt}; @@ -201,6 +201,21 @@ impl<'tcx> TypeRelation<'tcx> for Sub<'_, '_, 'tcx> { self.fields.higher_ranked_sub(a, b, self.a_is_expected)?; Ok(a) } + + fn constness_args( + &mut self, + a: ty::ConstnessArg, + b: ty::ConstnessArg, + ) -> RelateResult<'tcx, ty::ConstnessArg> { + trace!(?a, ?b); + match (a, b) { + (ty::ConstnessArg::Required, _) => Ok(a), + (a, ty::ConstnessArg::Infer) => Ok(a), + (ty::ConstnessArg::Infer, b) => Ok(b), + (a, ty::ConstnessArg::Not) => Ok(a), + _ => relate::super_relate_constness(self, a, b), + } + } } impl<'tcx> ConstEquateRelation<'tcx> for Sub<'_, '_, 'tcx> { diff --git a/compiler/rustc_middle/src/ty/_match.rs b/compiler/rustc_middle/src/ty/_match.rs index e6aab30a150de..2bc34ead8ba6e 100644 --- a/compiler/rustc_middle/src/ty/_match.rs +++ b/compiler/rustc_middle/src/ty/_match.rs @@ -121,4 +121,18 @@ impl<'tcx> TypeRelation<'tcx> for Match<'tcx> { { Ok(a.rebind(self.relate(a.skip_binder(), b.skip_binder())?)) } + + fn constness_args( + &mut self, + a: ty::ConstnessArg, + b: ty::ConstnessArg, + ) -> RelateResult<'tcx, ty::ConstnessArg> { + match (a, b) { + (_, ty::ConstnessArg::Infer) => return Ok(a), + (ty::ConstnessArg::Infer, _) => { + return Err(TypeError::ConstnessArgMismatch(relate::expected_found(self, a, b))); + } + _ => relate::super_relate_constness(self, a, b), + } + } } diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index d7afde01a96e4..01aaa17f28b91 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -99,6 +99,12 @@ pub trait TypeRelation<'tcx>: Sized { ) -> RelateResult<'tcx, ty::Binder<'tcx, T>> where T: Relate<'tcx>; + + fn constness_args( + &mut self, + a: ty::ConstnessArg, + b: ty::ConstnessArg, + ) -> RelateResult<'tcx, ty::ConstnessArg>; } pub trait Relate<'tcx>: TypeFoldable<'tcx> + Copy { @@ -141,7 +147,11 @@ pub fn relate_substs<'tcx, R: TypeRelation<'tcx>>( b_subst: SubstsRef<'tcx>, ) -> RelateResult<'tcx, SubstsRef<'tcx>> { relation.tcx().mk_substs(iter::zip(a_subst, b_subst).map(|(a, b)| { - relation.relate_with_variance(ty::Invariant, ty::VarianceDiagInfo::default(), a, b) + if let GenericArgKind::Constness(_) = a.unpack() && let GenericArgKind::Constness(_) = b.unpack() { + relation.relate(a, b) + } else { + relation.relate_with_variance(ty::Invariant, ty::VarianceDiagInfo::default(), a, b) + } })) } @@ -232,11 +242,7 @@ impl<'tcx> Relate<'tcx> for ty::ConstnessArg { a: ty::ConstnessArg, b: ty::ConstnessArg, ) -> RelateResult<'tcx, ty::ConstnessArg> { - if a == b { - Ok(a) - } else { - Err(TypeError::ConstnessArgMismatch(expected_found(relation, a, b))) - } + relation.constness_args(a, b) } } @@ -660,6 +666,20 @@ pub fn super_relate_consts<'tcx, R: TypeRelation<'tcx>>( if is_match { Ok(a) } else { Err(TypeError::ConstMismatch(expected_found(relation, a, b))) } } +pub fn super_relate_constness<'tcx, R: TypeRelation<'tcx>>( + relation: &mut R, + a: ty::ConstnessArg, + b: ty::ConstnessArg, +) -> RelateResult<'tcx, ty::ConstnessArg> { + match (a, b) { + (ty::ConstnessArg::Infer, _) | (_, ty::ConstnessArg::Infer) => { + bug!("var types encountered in super_relate_contness: {a:?} {b:?}"); + } + (a, b) if a == b => Ok(a), + _ => Err(TypeError::ConstnessArgMismatch(expected_found(relation, a, b))), + } +} + impl<'tcx> Relate<'tcx> for &'tcx ty::List>> { fn relate>( relation: &mut R, 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 66f9d3fb9507e..b5360e5028a75 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -423,8 +423,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // Keep only those bounds which may apply, and propagate overflow if it occurs. for bound in matching_bounds { - // FIXME(oli-obk): it is suspicious that we are dropping the constness and - // polarity here. + // FIXME(oli-obk): it is suspicious that we are dropping the polarity here. let wc = self.where_clause_may_apply(stack, bound.map_bound(|t| t.trait_ref))?; if wc.may_apply() { candidates.vec.push(ParamCandidate(bound)); diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index f5a967c885bdd..0b727597acb35 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -1207,7 +1207,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { .require_lang_item(LangItem::Destruct, None), substs: self.tcx().mk_substs_trait( nested_ty, - &[ty::ConstnessArg::Required.into()], + &[ty::ConstnessArg::Param.into()], ), }, polarity: ty::ImplPolarity::Positive, @@ -1235,7 +1235,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { def_id: self.tcx().require_lang_item(LangItem::Destruct, None), substs: self.tcx().mk_substs_trait( nested_ty, - &[ty::ConstnessArg::Required.into()], + &[ty::ConstnessArg::Param.into()], ), }, 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 e8719465450fa..6623bf74dbeb2 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -2232,7 +2232,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { obligation: &TraitObligation<'tcx>, poly_trait_ref: ty::PolyTraitRef<'tcx>, ) -> Result>, ()> { - self.infcx + let ret = self + .infcx .at(&obligation.cause, obligation.param_env) // We don't want predicates for opaque types to just match all other types, // if there is an obligation on the opaque type, then that obligation must be met @@ -2241,7 +2242,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { .define_opaque_types(false) .sup(obligation.predicate.to_poly_trait_ref(), poly_trait_ref) .map(|InferOk { obligations, .. }| obligations) - .map_err(|_| ()) + .map_err(|_| ()); + trace!(?ret); + ret } /////////////////////////////////////////////////////////////////////////// diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index 0b5c4fdb7428c..88ecfa27afd0b 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -725,7 +725,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { trait_ref.path.segments.last().unwrap(), true, match constness { // TODO check this again - hir::Constness::Const => ty::ConstnessArg::Required, + hir::Constness::Const => ty::ConstnessArg::Param, hir::Constness::NotConst => ty::ConstnessArg::Not, }, ) diff --git a/compiler/rustc_typeck/src/check/dropck.rs b/compiler/rustc_typeck/src/check/dropck.rs index 5381e309adb24..7e0aaf9b85ef6 100644 --- a/compiler/rustc_typeck/src/check/dropck.rs +++ b/compiler/rustc_typeck/src/check/dropck.rs @@ -4,7 +4,7 @@ use crate::hir::def_id::{DefId, LocalDefId}; use rustc_errors::{struct_span_err, ErrorGuaranteed}; use rustc_middle::ty::error::TypeError; -use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation}; +use rustc_middle::ty::relate::{super_relate_constness, Relate, RelateResult, TypeRelation}; use rustc_middle::ty::subst::SubstsRef; use rustc_middle::ty::util::IgnoreRegions; use rustc_middle::ty::{self, Predicate, Ty, TyCtxt}; @@ -323,4 +323,11 @@ impl<'tcx> TypeRelation<'tcx> for SimpleEqRelation<'tcx> { Ok(a) } + fn constness_args( + &mut self, + a: ty::ConstnessArg, + b: ty::ConstnessArg, + ) -> RelateResult<'tcx, ty::ConstnessArg> { + super_relate_constness(self, a, b) + } } diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs index 2f69bc4941662..7a61af47722a3 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs @@ -1465,7 +1465,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { infer_args_for_err: &infer_args_for_err, segments, }, - None, + Some(self.constness()), ) }); assert!(!substs.has_escaping_bound_vars()); diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound.rs b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound.rs new file mode 100644 index 0000000000000..27639e107f08b --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound.rs @@ -0,0 +1,13 @@ +#![feature(const_trait_impl)] + +#[const_trait] +trait Foo { + fn foo(); +} + +const fn foo() { + T::foo(); +} + + +fn main() {} \ No newline at end of file From 84054f71905908812f28a1696d7ffcae8af206d5 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Mon, 6 Jun 2022 18:27:40 +1000 Subject: [PATCH 38/51] Merge ::Required and ::Param --- .../rustc_borrowck/src/region_infer/opaque_types.rs | 2 +- .../src/transform/check_consts/check.rs | 2 +- .../src/transform/check_consts/qualifs.rs | 4 ++-- compiler/rustc_infer/src/infer/sub.rs | 2 +- compiler/rustc_middle/src/ty/context.rs | 2 +- compiler/rustc_middle/src/ty/fast_reject.rs | 7 +------ compiler/rustc_middle/src/ty/mod.rs | 8 +++----- compiler/rustc_middle/src/ty/print/pretty.rs | 3 +-- compiler/rustc_middle/src/ty/sty.rs | 4 ++-- compiler/rustc_middle/src/ty/subst.rs | 12 +++++------- .../src/traits/error_reporting/mod.rs | 2 +- .../src/traits/select/confirmation.rs | 4 ++-- .../rustc_trait_selection/src/traits/select/mod.rs | 2 +- compiler/rustc_traits/src/chalk/db.rs | 2 +- compiler/rustc_typeck/src/astconv/mod.rs | 11 ++++++----- compiler/rustc_typeck/src/check/compare_method.rs | 2 +- compiler/rustc_typeck/src/check/fn_ctxt/mod.rs | 2 +- .../rfc-2632-const-trait-impl/const-trait-bound.rs | 1 + 18 files changed, 32 insertions(+), 40 deletions(-) diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index 768a54f4772f3..bd23350557479 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -381,7 +381,7 @@ fn check_opaque_type_parameter_valid( matches!(*lt, ty::ReEarlyBound(_) | ty::ReFree(_)) } GenericArgKind::Const(ct) => matches!(ct.kind(), ty::ConstKind::Param(_)), - GenericArgKind::Constness(ct) => matches!(ct, ty::ConstnessArg::Param), + GenericArgKind::Constness(_) => false, }; if arg_is_param { 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 ec2af7c1800f7..69d8d3f285e95 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -736,7 +736,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { }); match implsrc { - Ok(Some(ImplSource::Param(_, ty::ConstnessArg::Required | ty::ConstnessArg::Param))) => { + Ok(Some(ImplSource::Param(_, ty::ConstnessArg::Const))) => { 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 41bdb424590c3..27e8e848cdc5e 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs @@ -161,7 +161,7 @@ impl Qualif for NeedsNonConstDrop { ty::Binder::dummy(ty::TraitPredicate { trait_ref: ty::TraitRef { def_id: destruct, - substs: cx.tcx.mk_substs_trait(ty, &[ty::ConstnessArg::Param.into()]), + substs: cx.tcx.mk_substs_trait(ty, &[ty::ConstnessArg::Const.into()]), }, polarity: ty::ImplPolarity::Positive, }), @@ -176,7 +176,7 @@ impl Qualif for NeedsNonConstDrop { if !matches!( impl_src, - ImplSource::ConstDestruct(_) | ImplSource::Param(_, ty::ConstnessArg::Required | ty::ConstnessArg::Param) + ImplSource::ConstDestruct(_) | ImplSource::Param(_, ty::ConstnessArg::Const) ) { // If our const destruct candidate is not ConstDestruct or implied by the param env, // then it's bad diff --git a/compiler/rustc_infer/src/infer/sub.rs b/compiler/rustc_infer/src/infer/sub.rs index 743e263783c96..61f6100b83899 100644 --- a/compiler/rustc_infer/src/infer/sub.rs +++ b/compiler/rustc_infer/src/infer/sub.rs @@ -209,7 +209,7 @@ impl<'tcx> TypeRelation<'tcx> for Sub<'_, '_, 'tcx> { ) -> RelateResult<'tcx, ty::ConstnessArg> { trace!(?a, ?b); match (a, b) { - (ty::ConstnessArg::Required, _) => Ok(a), + (ty::ConstnessArg::Const, _) => Ok(a), (a, ty::ConstnessArg::Infer) => Ok(a), (ty::ConstnessArg::Infer, b) => Ok(b), (a, ty::ConstnessArg::Not) => Ok(a), diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 6e386bfe1bd2f..7b3c2b11685d3 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2629,7 +2629,7 @@ impl<'tcx> TyCtxt<'tcx> { GenericParamDefKind::Const { .. } => { self.mk_const_param(param.index, param.name, self.type_of(param.def_id)).into() } - GenericParamDefKind::Constness => ty::ConstnessArg::Param.into(), + GenericParamDefKind::Constness => ty::ConstnessArg::Not.into(), // TODO sus } } diff --git a/compiler/rustc_middle/src/ty/fast_reject.rs b/compiler/rustc_middle/src/ty/fast_reject.rs index c43d3d48b7553..310eecca63031 100644 --- a/compiler/rustc_middle/src/ty/fast_reject.rs +++ b/compiler/rustc_middle/src/ty/fast_reject.rs @@ -412,13 +412,8 @@ impl DeepRejectCtxt { impl_ct: ty::ConstnessArg, ) -> bool { match (obligation_ct, impl_ct) { - (_, ty::ConstnessArg::Param) => true, - (ty::ConstnessArg::Param, _) => match self.treat_obligation_params { - TreatParams::AsPlaceholder => false, - TreatParams::AsInfer => true, - }, + (_, ty::ConstnessArg::Const) => true, (ty::ConstnessArg::Infer, _) => true, - (ty::ConstnessArg::Not, ty::ConstnessArg::Required) => true, _ => obligation_ct == impl_ct, } } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 22d911b93832d..b52ec657fc8c0 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -312,19 +312,17 @@ impl fmt::Display for BoundConstness { Ord )] pub enum ConstnessArg { - Required, + Const, Not, - Param, Infer, } impl fmt::Display for ConstnessArg { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str(match self { - Self::Required => "(constness: required)", Self::Not => "(constness: not)", - Self::Param => "(constness: parameterized)", - Self::Infer => "(constness: infer)" + Self::Const => "(constness: const)", + Self::Infer => "(constness: infer)", }) } } diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index df9d62095e059..c818983f2e38a 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -2522,8 +2522,7 @@ define_print_and_forward_display! { if cx.tcx().sess.verbose() { match self.0.constness() { ty::ConstnessArg::Not => {}, - ty::ConstnessArg::Required => p!(write("const ")), - ty::ConstnessArg::Param => p!(write("~const ")), + ty::ConstnessArg::Const => p!(write("~const ")), ty::ConstnessArg::Infer => p!(write("_const ")), // TODO wonky } } diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 7f519f34c3406..0aba7e86f3a5f 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -847,9 +847,9 @@ impl<'tcx> TraitRef<'tcx> { } pub fn with_const(mut self, tcx: TyCtxt<'tcx>) -> Self { - if self.constness() != ty::ConstnessArg::Required { + if self.constness() != ty::ConstnessArg::Const { self.substs = tcx.mk_substs(self.substs.iter().map(|arg| match arg.unpack() { - ty::subst::GenericArgKind::Constness(_) => ty::ConstnessArg::Required.into(), + ty::subst::GenericArgKind::Constness(_) => ty::ConstnessArg::Const.into(), _ => arg, })); } diff --git a/compiler/rustc_middle/src/ty/subst.rs b/compiler/rustc_middle/src/ty/subst.rs index a69fc6d26b1e9..cf0844a80d0a7 100644 --- a/compiler/rustc_middle/src/ty/subst.rs +++ b/compiler/rustc_middle/src/ty/subst.rs @@ -99,9 +99,8 @@ impl<'tcx> GenericArgKind<'tcx> { CONSTNESS_TAG, match carg { ty::ConstnessArg::Not => 0, - ty::ConstnessArg::Required => 0b100, - ty::ConstnessArg::Param => 0b1000, - ty::ConstnessArg::Infer => 0b10000, + ty::ConstnessArg::Const => 0b100, + ty::ConstnessArg::Infer => 0b1000, }, ), }; @@ -181,9 +180,8 @@ impl<'tcx> GenericArg<'tcx> { ))), CONSTNESS_TAG => GenericArgKind::Constness(match ptr & (!TAG_MASK) { 0 => ty::ConstnessArg::Not, - 0b100 => ty::ConstnessArg::Required, - 0b1000 => ty::ConstnessArg::Param, - 0b10000 => ty::ConstnessArg::Infer, + 0b100 => ty::ConstnessArg::Const, + 0b1000 => ty::ConstnessArg::Infer, _ => intrinsics::unreachable(), }), _ => intrinsics::unreachable(), @@ -613,7 +611,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> { } fn fold_constness(&mut self, c: ty::ConstnessArg) -> ty::ConstnessArg { - if let ty::ConstnessArg::Param | ty::ConstnessArg::Infer = c { + if let ty::ConstnessArg::Const | ty::ConstnessArg::Infer = c { self.substs .iter() .find_map(|param| match param.unpack() { 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 ff3037b4bafaf..1d389ceddee1d 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -328,7 +328,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { let trait_predicate = self.resolve_vars_if_possible(trait_predicate); let predicate_is_const = - ty::ConstnessArg::Required == trait_predicate.skip_binder().constness(); + ty::ConstnessArg::Const == trait_predicate.skip_binder().constness(); if self.tcx.sess.has_errors().is_some() && trait_predicate.references_error() diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 0b727597acb35..f459b4cd4540b 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -1207,7 +1207,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { .require_lang_item(LangItem::Destruct, None), substs: self.tcx().mk_substs_trait( nested_ty, - &[ty::ConstnessArg::Param.into()], + &[ty::ConstnessArg::Const.into()], ), }, polarity: ty::ImplPolarity::Positive, @@ -1235,7 +1235,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { def_id: self.tcx().require_lang_item(LangItem::Destruct, None), substs: self.tcx().mk_substs_trait( nested_ty, - &[ty::ConstnessArg::Param.into()], + &[ty::ConstnessArg::Const.into()], ), }, 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 6623bf74dbeb2..8998dbbe000da 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1199,7 +1199,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ParamCandidate(trait_pred) if trait_pred.constness() != ty::ConstnessArg::Not => { - debug_assert_eq!(trait_pred.constness(), ty::ConstnessArg::Param); + debug_assert_eq!(trait_pred.constness(), ty::ConstnessArg::Const); } // auto trait impl AutoImplCandidate(..) => {} diff --git a/compiler/rustc_traits/src/chalk/db.rs b/compiler/rustc_traits/src/chalk/db.rs index eeeea52ef5f7b..23f4be5c54eb3 100644 --- a/compiler/rustc_traits/src/chalk/db.rs +++ b/compiler/rustc_traits/src/chalk/db.rs @@ -741,7 +741,7 @@ fn bound_vars_for_item<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> SubstsRef<'tcx }) .into(), ty::GenericParamDefKind::Constness => { - ty::ConstnessArg::Param.into() // TODO Confirm + ty::ConstnessArg::Not.into() // TODO Confirm } }) } diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index 88ecfa27afd0b..7c951a0832f2f 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -574,10 +574,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { .unwrap_or_else(|| match self.astconv.item_def_id() { // no information available // TODO: fall back to `Not`? - None => if infer_args { ty::ConstnessArg::Infer } else { ty::ConstnessArg::Param }, + None => if infer_args { ty::ConstnessArg::Infer } else { ty::ConstnessArg::Not }, Some(context) => { if tcx.generics_of(context).has_constness_param() { - ty::ConstnessArg::Param + ty::ConstnessArg::Const } else { // TODO: should use `Required` if we're in a const context // like `const`/`static` item initializers. @@ -724,8 +724,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { self_ty, trait_ref.path.segments.last().unwrap(), true, - match constness { // TODO check this again - hir::Constness::Const => ty::ConstnessArg::Param, + match constness { + // TODO check this again + hir::Constness::Const => ty::ConstnessArg::Const, hir::Constness::NotConst => ty::ConstnessArg::Not, }, ) @@ -1028,7 +1029,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { match ast_bound { hir::GenericBound::Trait(poly_trait_ref, modifier) => { let constness = match modifier { - hir::TraitBoundModifier::MaybeConst => ty::ConstnessArg::Param, + hir::TraitBoundModifier::MaybeConst => ty::ConstnessArg::Const, hir::TraitBoundModifier::None => ty::ConstnessArg::Not, hir::TraitBoundModifier::Maybe => continue, }; diff --git a/compiler/rustc_typeck/src/check/compare_method.rs b/compiler/rustc_typeck/src/check/compare_method.rs index 299f473042cee..f6c7e25fd94a0 100644 --- a/compiler/rustc_typeck/src/check/compare_method.rs +++ b/compiler/rustc_typeck/src/check/compare_method.rs @@ -1378,7 +1378,7 @@ pub fn check_type_bounds<'tcx>( }) .into() } - GenericParamDefKind::Constness => ty::ConstnessArg::Param.into(), + GenericParamDefKind::Constness => ty::ConstnessArg::Const.into(), }); let bound_vars = tcx.mk_bound_variable_kinds(bound_vars.into_iter()); let impl_ty_substs = tcx.intern_substs(&substs); diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs b/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs index 8755ec67a89d9..d7fa86317b279 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs @@ -150,7 +150,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if body_id.is_owner() { let did = body_id.expect_owner(); if inh.tcx.is_const_fn_raw(did.to_def_id()) || inh.tcx.is_const_default_method(did.to_def_id()) || inh.tcx.def_kind(did.to_def_id()) == hir::def::DefKind::Const { - ty::ConstnessArg::Param + ty::ConstnessArg::Const } else { ty::ConstnessArg::Not } diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound.rs b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound.rs index 27639e107f08b..954e6571f9506 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound.rs +++ b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound.rs @@ -1,3 +1,4 @@ +// check-pass #![feature(const_trait_impl)] #[const_trait] From cd2edf64b723ee71845da7cf61936543ad90f363 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Tue, 7 Jun 2022 16:54:44 +1000 Subject: [PATCH 39/51] Add CosntnessArg::Const when needed --- compiler/rustc_typeck/src/astconv/generics.rs | 10 ++++- compiler/rustc_typeck/src/astconv/mod.rs | 9 +++- .../const-trait-bound.rs | 1 - .../const-trait-impl-bound.rs | 17 ++++++++ .../tilde-const-invalid-places.rs | 2 + .../tilde-const-invalid-places.stderr | 41 +++++++++++++++---- 6 files changed, 70 insertions(+), 10 deletions(-) create mode 100644 src/test/ui/rfc-2632-const-trait-impl/const-trait-impl-bound.rs diff --git a/compiler/rustc_typeck/src/astconv/generics.rs b/compiler/rustc_typeck/src/astconv/generics.rs index 241837969a1db..77374b7d5797a 100644 --- a/compiler/rustc_typeck/src/astconv/generics.rs +++ b/compiler/rustc_typeck/src/astconv/generics.rs @@ -206,6 +206,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // methods in `subst.rs`, so that we can iterate over the arguments and // parameters in lock-step linearly, instead of trying to match each pair. let mut substs: SmallVec<[subst::GenericArg<'tcx>; 8]> = SmallVec::with_capacity(count); + let mut has_constness = false; // Iterate over each segment of the path. while let Some((def_id, defs)) = stack.pop() { let mut params = defs.params.iter().peekable(); @@ -219,6 +220,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } else { substs.push(kind); } + if let subst::GenericArgKind::Constness(_) = kind.unpack() { + has_constness = true; + } params.next(); } else { break; @@ -386,7 +390,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } } } - + if !has_constness && has_self && let Some(constness) = constness { + if let ty::ConstnessArg::Const = constness { + substs.push(constness.into()); + } + } tcx.intern_substs(&substs) } diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index 7c951a0832f2f..b729c9f8f7fa4 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -574,7 +574,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { .unwrap_or_else(|| match self.astconv.item_def_id() { // no information available // TODO: fall back to `Not`? - None => if infer_args { ty::ConstnessArg::Infer } else { ty::ConstnessArg::Not }, + None => { + trace!("uh oh"); + if infer_args { + ty::ConstnessArg::Infer + } else { + ty::ConstnessArg::Not + } + } Some(context) => { if tcx.generics_of(context).has_constness_param() { ty::ConstnessArg::Const diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound.rs b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound.rs index 954e6571f9506..60067477e05eb 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound.rs +++ b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound.rs @@ -10,5 +10,4 @@ const fn foo() { T::foo(); } - fn main() {} \ No newline at end of file diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-trait-impl-bound.rs b/src/test/ui/rfc-2632-const-trait-impl/const-trait-impl-bound.rs new file mode 100644 index 0000000000000..6033927006bef --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/const-trait-impl-bound.rs @@ -0,0 +1,17 @@ +// check-pass +#![feature(const_trait_impl)] + +#[const_trait] +trait Foo { + fn foo(); +} + +pub struct W(T); + +impl const Foo for W { + fn foo() { + ::foo(); + } +} + +fn main() {} diff --git a/src/test/ui/rfc-2632-const-trait-impl/tilde-const-invalid-places.rs b/src/test/ui/rfc-2632-const-trait-impl/tilde-const-invalid-places.rs index b4302f3e75fd4..9ee7caa80c5de 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/tilde-const-invalid-places.rs +++ b/src/test/ui/rfc-2632-const-trait-impl/tilde-const-invalid-places.rs @@ -7,12 +7,14 @@ impl T for S {} fn rpit() -> impl ~const T { S } //~^ ERROR `~const` is not allowed +//~| ERROR the trait bound fn apit(_: impl ~const T) {} //~^ ERROR `~const` is not allowed fn rpit_assoc_bound() -> impl IntoIterator { Some(S) } //~^ ERROR `~const` is not allowed +//~| ERROR the trait bound fn apit_assoc_bound(_: impl IntoIterator) {} //~^ ERROR `~const` is not allowed diff --git a/src/test/ui/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr b/src/test/ui/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr index 033ec21ba8408..47736309d8418 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr @@ -7,7 +7,7 @@ LL | fn rpit() -> impl ~const T { S } = note: only allowed on bounds on traits' associated types and functions, const fns, const impls and its associated functions error: `~const` is not allowed here - --> $DIR/tilde-const-invalid-places.rs:11:17 + --> $DIR/tilde-const-invalid-places.rs:12:17 | LL | fn apit(_: impl ~const T) {} | ^^^^^^^^ @@ -15,7 +15,7 @@ LL | fn apit(_: impl ~const T) {} = note: only allowed on bounds on traits' associated types and functions, const fns, const impls and its associated functions error: `~const` is not allowed here - --> $DIR/tilde-const-invalid-places.rs:14:50 + --> $DIR/tilde-const-invalid-places.rs:15:50 | LL | fn rpit_assoc_bound() -> impl IntoIterator { Some(S) } | ^^^^^^^^ @@ -23,7 +23,7 @@ LL | fn rpit_assoc_bound() -> impl IntoIterator { Some(S) } = note: only allowed on bounds on traits' associated types and functions, const fns, const impls and its associated functions error: `~const` is not allowed here - --> $DIR/tilde-const-invalid-places.rs:17:48 + --> $DIR/tilde-const-invalid-places.rs:19:48 | LL | fn apit_assoc_bound(_: impl IntoIterator) {} | ^^^^^^^^ @@ -31,7 +31,7 @@ LL | fn apit_assoc_bound(_: impl IntoIterator) {} = note: only allowed on bounds on traits' associated types and functions, const fns, const impls and its associated functions error: `~const` is not allowed here - --> $DIR/tilde-const-invalid-places.rs:20:15 + --> $DIR/tilde-const-invalid-places.rs:22:15 | LL | fn generic() {} | ^^^^^^^^ @@ -39,7 +39,7 @@ LL | fn generic() {} = note: only allowed on bounds on traits' associated types and functions, const fns, const impls and its associated functions error: `~const` is not allowed here - --> $DIR/tilde-const-invalid-places.rs:23:31 + --> $DIR/tilde-const-invalid-places.rs:25:31 | LL | fn where_clause

() where P: ~const T {} | ^^^^^^^^ @@ -47,10 +47,37 @@ LL | fn where_clause

() where P: ~const T {} = note: only allowed on bounds on traits' associated types and functions, const fns, const impls and its associated functions error: `~const` and `?` are mutually exclusive - --> $DIR/tilde-const-invalid-places.rs:26:25 + --> $DIR/tilde-const-invalid-places.rs:28:25 | LL | struct TildeQuestion(std::marker::PhantomData); | ^^^^^^^^^^^^^ -error: aborting due to 7 previous errors +error[E0277]: the trait bound `S: T` is not satisfied + --> $DIR/tilde-const-invalid-places.rs:8:14 + | +LL | fn rpit() -> impl ~const T { S } + | ^^^^^^^^^^^^^ the trait `T` is not implemented for `S` + | +note: the trait `T` is implemented for `S`, but that implementation is not `const` + --> $DIR/tilde-const-invalid-places.rs:8:14 + | +LL | fn rpit() -> impl ~const T { S } + | ^^^^^^^^^^^^^ + = help: the trait `T` is implemented for `S` + +error[E0277]: the trait bound `S: T` is not satisfied + --> $DIR/tilde-const-invalid-places.rs:15:26 + | +LL | fn rpit_assoc_bound() -> impl IntoIterator { Some(S) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `T` is not implemented for `S` + | +note: the trait `T` is implemented for `S`, but that implementation is not `const` + --> $DIR/tilde-const-invalid-places.rs:15:26 + | +LL | fn rpit_assoc_bound() -> impl IntoIterator { Some(S) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = help: the trait `T` is implemented for `S` + +error: aborting due to 9 previous errors +For more information about this error, try `rustc --explain E0277`. From d4551d257e0019f50fae839554846173086a6dce Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Wed, 15 Jun 2022 18:18:17 +1000 Subject: [PATCH 40/51] Fixed error with more TODOs --- compiler/rustc_middle/src/ty/subst.rs | 7 ++++-- .../rustc_typeck/src/check/fn_ctxt/mod.rs | 7 ++++-- compiler/rustc_typeck/src/check/wfcheck.rs | 21 +++++++++++++++-- .../const-trait-further-normalize.rs | 23 +++++++++++++++++++ 4 files changed, 52 insertions(+), 6 deletions(-) create mode 100644 src/test/ui/rfc-2632-const-trait-impl/const-trait-further-normalize.rs diff --git a/compiler/rustc_middle/src/ty/subst.rs b/compiler/rustc_middle/src/ty/subst.rs index cf0844a80d0a7..20eb1eefa2252 100644 --- a/compiler/rustc_middle/src/ty/subst.rs +++ b/compiler/rustc_middle/src/ty/subst.rs @@ -612,13 +612,16 @@ impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> { fn fold_constness(&mut self, c: ty::ConstnessArg) -> ty::ConstnessArg { if let ty::ConstnessArg::Const | ty::ConstnessArg::Infer = c { - self.substs + let ret = self + .substs .iter() .find_map(|param| match param.unpack() { GenericArgKind::Constness(c) => Some(c), _ => None, }) - .unwrap_or(c) + .unwrap_or(ty::ConstnessArg::Not); // <- since there is no constness in subst, it must be non-const + trace!(?c, ?ret); + ret } else { c.super_fold_with(self) } diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs b/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs index d7fa86317b279..4251613d0d237 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs @@ -127,7 +127,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { param_env: ty::ParamEnv<'tcx>, body_id: hir::HirId, ) -> FnCtxt<'a, 'tcx> { - FnCtxt { + let fcx = FnCtxt { body_id, param_env, err_count_on_creation: inh.tcx.sess.err_count(), @@ -159,7 +159,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty::ConstnessArg::Not } }, - } + }; + let constness = fcx.constness; + trace!(?constness); + fcx } pub fn cause(&self, span: Span, code: ObligationCauseCode<'tcx>) -> ObligationCause<'tcx> { diff --git a/compiler/rustc_typeck/src/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs index 173753bcf9cd7..6eff8a68a99c0 100644 --- a/compiler/rustc_typeck/src/check/wfcheck.rs +++ b/compiler/rustc_typeck/src/check/wfcheck.rs @@ -1340,7 +1340,7 @@ fn check_where_clauses<'tcx, 'fcx>( // First we build the defaulted substitution. let substs = InternalSubsts::for_item(tcx, def_id.to_def_id(), |param, _| { match param.kind { - GenericParamDefKind::Constness | GenericParamDefKind::Lifetime => { + GenericParamDefKind::Lifetime => { // All regions are identity. tcx.mk_param_from_def(param) } @@ -1371,6 +1371,8 @@ fn check_where_clauses<'tcx, 'fcx>( tcx.mk_param_from_def(param) } + + GenericParamDefKind::Constness => fcx.constness().into(), } }); @@ -1828,9 +1830,24 @@ fn check_false_global_bounds(fcx: &FnCtxt<'_, '_>, mut span: Span, id: hir::HirI let pred = obligation.predicate; // Match the existing behavior. if pred.is_global() && !pred.has_late_bound_regions() { - let pred = fcx.normalize_associated_types_in(span, pred); + let /* mut */ pred = fcx.normalize_associated_types_in(span, pred); let hir_node = fcx.tcx.hir().find(id); + if fcx.constness() == ty::ConstnessArg::Not { + struct NotConstFolder<'tcx>(TyCtxt<'tcx>); // TODO justify this hack + + impl<'tcx> ty::TypeFolder<'tcx> for NotConstFolder<'tcx> { + fn tcx<'a>(&'a self) -> TyCtxt<'tcx> { + self.0 + } + fn fold_constness(&mut self, _: ty::ConstnessArg) -> ty::ConstnessArg { + ty::ConstnessArg::Not + } + } + + pred = pred.fold_with(&mut NotConstFolder(fcx.tcx)) + } + // only use the span of the predicate clause (#90869) if let Some(hir::Generics { predicates, .. }) = diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-trait-further-normalize.rs b/src/test/ui/rfc-2632-const-trait-impl/const-trait-further-normalize.rs new file mode 100644 index 0000000000000..e3908eda503f7 --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/const-trait-further-normalize.rs @@ -0,0 +1,23 @@ +// check-pass +#![feature(const_trait_impl)] + +#[const_trait] +trait Foo { + fn foo(&self); +} + +struct S1; +struct S2; + +impl Foo for S1 { + fn foo(&self) {} +} + +impl const Foo for S2 where S1: ~const Foo { + fn foo(&self) {} +} + +fn main() { + S2.foo(); +} + From a319331eb1a3ad332cb85bb1c35cbce57a6af0fe Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Fri, 17 Jun 2022 15:17:29 +1000 Subject: [PATCH 41/51] Don't require has_self when adding constness This can help with typeck and fixes ui tests. --- compiler/rustc_typeck/src/astconv/generics.rs | 2 +- compiler/rustc_typeck/src/check/check.rs | 1 + .../rustc_typeck/src/check/fn_ctxt/_impl.rs | 1 + compiler/rustc_typeck/src/check/fn_ctxt/mod.rs | 18 ++++++++++++++---- 4 files changed, 17 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_typeck/src/astconv/generics.rs b/compiler/rustc_typeck/src/astconv/generics.rs index 77374b7d5797a..59048792ba46f 100644 --- a/compiler/rustc_typeck/src/astconv/generics.rs +++ b/compiler/rustc_typeck/src/astconv/generics.rs @@ -390,7 +390,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } } } - if !has_constness && has_self && let Some(constness) = constness { + if !has_constness && let Some(constness) = constness { if let ty::ConstnessArg::Const = constness { substs.push(constness.into()); } diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs index dfcd35d2178e7..1cdee4c13a667 100644 --- a/compiler/rustc_typeck/src/check/check.rs +++ b/compiler/rustc_typeck/src/check/check.rs @@ -84,6 +84,7 @@ pub(super) fn check_fn<'a, 'tcx>( can_be_generator: Option, return_type_pre_known: bool, ) -> (FnCtxt<'a, 'tcx>, Option>) { + debug!(?body.value.hir_id); // Create the function context. This is either derived from scratch or, // in the case of closures, based on the outer context. let mut fcx = FnCtxt::new(inherited, param_env, body.value.hir_id); diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs index 7a61af47722a3..bf2a27620fa4f 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs @@ -845,6 +845,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expect_args } + #[tracing::instrument(level = "debug", skip(self))] pub(in super::super) fn resolve_lang_item_path( &self, lang_item: hir::LangItem, diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs b/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs index 4251613d0d237..0c940abf63361 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs @@ -147,15 +147,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return_type_pre_known: true, return_type_has_opaque: false, constness: { - if body_id.is_owner() { - let did = body_id.expect_owner(); - if inh.tcx.is_const_fn_raw(did.to_def_id()) || inh.tcx.is_const_default_method(did.to_def_id()) || inh.tcx.def_kind(did.to_def_id()) == hir::def::DefKind::Const { + fn get_constness(tcx: TyCtxt<'_>, did: DefId) -> ty::ConstnessArg { + if tcx.is_const_fn_raw(did) || tcx.is_const_default_method(did) || tcx.def_kind(did) == hir::def::DefKind::Const { + trace!("const"); ty::ConstnessArg::Const } else { + trace!("not const"); + ty::ConstnessArg::Not + } + } + if body_id.is_owner() { + let did = body_id.expect_owner(); + get_constness(inh.tcx, did.to_def_id()) + } else if let Some(hir::Node::Expr(hir::Expr { kind, .. })) = inh.tcx.hir().find(body_id) { + if let hir::ExprKind::Closure { .. } = kind { ty::ConstnessArg::Not + } else { + get_constness(inh.tcx, body_id.owner.to_def_id()) } } else { - // TODO: check correctness ty::ConstnessArg::Not } }, From d2322b22aec2c73c415e2492a84ee3aa27f29f83 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Sun, 19 Jun 2022 15:26:54 +1000 Subject: [PATCH 42/51] Return unimplemented when feature is not enabled --- .../src/traits/select/confirmation.rs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index f459b4cd4540b..2bdc0f0e5fe49 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -15,6 +15,7 @@ use rustc_middle::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, Subst, use rustc_middle::ty::{self, GenericParamDefKind, Ty, TyCtxt}; use rustc_middle::ty::{ToPolyTraitRef, ToPredicate}; use rustc_span::def_id::DefId; +use rustc_span::sym; use crate::traits::project::{normalize_with_depth, normalize_with_depth_to}; use crate::traits::util::{self, closure_trait_ref_and_return_type, predicate_for_trait_def}; @@ -44,6 +45,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ) -> Result, SelectionError<'tcx>> { // let new_obligation; + // when const_trait_impl not enabled, all const predicates are unimplemented + if obligation.predicate.constness() == ty::ConstnessArg::Const { + if !self.tcx().features().enabled(sym::const_trait_impl) { + return Err(SelectionError::Unimplemented) + } + } + // TODO rm // HACK(const_trait_impl): the surrounding environment is remapped to a non-const context // because nested obligations might be actually `~const` then (incorrectly) requiring // const impls. for example: @@ -1233,10 +1241,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { .rebind(ty::TraitPredicate { trait_ref: ty::TraitRef { def_id: self.tcx().require_lang_item(LangItem::Destruct, None), - substs: self.tcx().mk_substs_trait( - nested_ty, - &[ty::ConstnessArg::Const.into()], - ), + substs: self + .tcx() + .mk_substs_trait(nested_ty, &[ty::ConstnessArg::Const.into()]), }, polarity: ty::ImplPolarity::Positive, }) From cb8bde3d19fb09e2a6dc722a274e10ceea1c0b0d Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Sun, 19 Jun 2022 15:27:18 +1000 Subject: [PATCH 43/51] const impls have constness --- compiler/rustc_typeck/src/collect.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 237407ee2b623..f73f057249c8b 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -1624,7 +1624,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics { }; let has_self = opt_self.is_some(); - let has_constness = tcx.has_attr(def_id, sym::const_trait); + let has_constness = tcx.has_attr(def_id, sym::const_trait) || (tcx.def_kind(def_id) == DefKind::Impl && tcx.impl_constness(def_id) == hir::Constness::Const); let mut parent_has_self = false; let mut parent_has_constness = false; let mut own_start = has_self as u32; From 6dfe452bfdb2401c628babffedc671580560a0a8 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Sun, 19 Jun 2022 15:28:52 +1000 Subject: [PATCH 44/51] var_for_def uses actual constness sometimes --- compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs | 8 ++++---- compiler/rustc_typeck/src/check/fn_ctxt/mod.rs | 13 +++++++++---- compiler/rustc_typeck/src/check/method/confirm.rs | 4 ++-- compiler/rustc_typeck/src/check/method/mod.rs | 4 ++-- compiler/rustc_typeck/src/check/method/probe.rs | 4 +++- 5 files changed, 20 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs index bf2a27620fa4f..fe0d792c92ae3 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs @@ -193,7 +193,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { substs: InternalSubsts::for_item(self.tcx, method.def_id, |param, _| { let i = param.index as usize; if i < method_generics.parent_count { - self.infcx.var_for_def(DUMMY_SP, param) + self.infcx.var_for_def(DUMMY_SP, param, Some(self.constness)) } else { *method.substs.get(i).unwrap_or_else(|| { span_bug!( @@ -1431,7 +1431,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // This case also occurs as a result of some malformed input, e.g. // a lifetime argument being given instead of a type parameter. // Using inference instead of `Error` gives better error messages. - self.fcx.var_for_def(self.span, param) + self.fcx.var_for_def(self.span, param, None) } } GenericParamDefKind::Const { has_default } => { @@ -1440,11 +1440,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .subst(tcx, substs.unwrap()) .into() } else { - self.fcx.var_for_def(self.span, param) + self.fcx.var_for_def(self.span, param, None) } } GenericParamDefKind::Constness => match constness { - None => self.fcx.var_for_def(self.span, param), + None => self.fcx.constness().into(), Some(constness) => constness.into(), }, } diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs b/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs index 0c940abf63361..22ccecad01ff2 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs @@ -148,7 +148,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return_type_has_opaque: false, constness: { fn get_constness(tcx: TyCtxt<'_>, did: DefId) -> ty::ConstnessArg { - if tcx.is_const_fn_raw(did) || tcx.is_const_default_method(did) || tcx.def_kind(did) == hir::def::DefKind::Const { + if tcx.is_const_fn_raw(did) + || tcx.is_const_default_method(did) + || tcx.def_kind(did) == hir::def::DefKind::Const + { trace!("const"); ty::ConstnessArg::Const } else { @@ -159,7 +162,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if body_id.is_owner() { let did = body_id.expect_owner(); get_constness(inh.tcx, did.to_def_id()) - } else if let Some(hir::Node::Expr(hir::Expr { kind, .. })) = inh.tcx.hir().find(body_id) { + } else if let Some(hir::Node::Expr(hir::Expr { kind, .. })) = + inh.tcx.hir().find(body_id) + { if let hir::ExprKind::Closure { .. } = kind { ty::ConstnessArg::Not } else { @@ -253,7 +258,7 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> { fn ty_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx> { if let Some(param) = param { - if let GenericArgKind::Type(ty) = self.var_for_def(span, param).unpack() { + if let GenericArgKind::Type(ty) = self.var_for_def(span, param, None).unpack() { return ty; } unreachable!() @@ -272,7 +277,7 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> { span: Span, ) -> Const<'tcx> { if let Some(param) = param { - if let GenericArgKind::Const(ct) = self.var_for_def(span, param).unpack() { + if let GenericArgKind::Const(ct) = self.var_for_def(span, param, None).unpack() { return ct; } unreachable!() diff --git a/compiler/rustc_typeck/src/check/method/confirm.rs b/compiler/rustc_typeck/src/check/method/confirm.rs index 8ce8489cfbee5..c02b76657e6c2 100644 --- a/compiler/rustc_typeck/src/check/method/confirm.rs +++ b/compiler/rustc_typeck/src/check/method/confirm.rs @@ -405,10 +405,10 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { } else { self.cfcx.fcx.constness() }; - debug!("inferred_kind constness={constness:?}"); + debug!(?constness); constness.into() } else { - self.cfcx.var_for_def(self.cfcx.span, param) + self.cfcx.var_for_def(self.cfcx.span, param, None) } } } diff --git a/compiler/rustc_typeck/src/check/method/mod.rs b/compiler/rustc_typeck/src/check/method/mod.rs index ba7ef85879069..d4573b7aac0ad 100644 --- a/compiler/rustc_typeck/src/check/method/mod.rs +++ b/compiler/rustc_typeck/src/check/method/mod.rs @@ -295,7 +295,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } } - self.var_for_def(span, param) + self.var_for_def(span, param, Some(self.constness())) }); let trait_ref = ty::TraitRef::new(trait_def_id, substs); @@ -336,7 +336,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } } - self.var_for_def(span, param) + self.var_for_def(span, param, Some(self.constness())) }); let trait_ref = ty::TraitRef::new(trait_def_id, substs); diff --git a/compiler/rustc_typeck/src/check/method/probe.rs b/compiler/rustc_typeck/src/check/method/probe.rs index 190222b1ee9c5..8afc25f143e14 100644 --- a/compiler/rustc_typeck/src/check/method/probe.rs +++ b/compiler/rustc_typeck/src/check/method/probe.rs @@ -1806,7 +1806,9 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } GenericParamDefKind::Constness | GenericParamDefKind::Type { .. } - | GenericParamDefKind::Const { .. } => self.var_for_def(self.span, param), + | GenericParamDefKind::Const { .. } => { + self.var_for_def(self.span, param, Some(self.constness())) + } } } }); From a0cd8a2938055cb8f9f504897fbc77ba2c35d652 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Mon, 20 Jun 2022 14:33:05 +1000 Subject: [PATCH 45/51] Fix more ui tests --- compiler/rustc_middle/src/ty/sty.rs | 2 +- .../src/traits/select/confirmation.rs | 2 +- .../src/traits/select/mod.rs | 7 ++--- .../rustc_typeck/src/check/method/probe.rs | 4 ++- compiler/rustc_typeck/src/check/wfcheck.rs | 18 +++---------- compiler/rustc_typeck/src/collect.rs | 4 ++- .../call-const-trait-method-fail.rs | 3 ++- .../call-const-trait-method-fail.stderr | 27 +++++++++++++------ .../cross-crate.gated.stderr | 22 ++++++++++----- .../rfc-2632-const-trait-impl/cross-crate.rs | 4 +-- .../cross-crate.stock.stderr | 20 ++++++++------ 11 files changed, 67 insertions(+), 46 deletions(-) diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 0aba7e86f3a5f..90a948dd1a772 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -816,7 +816,7 @@ impl<'tcx> TraitRef<'tcx> { } // TODO remove this hack! - pub fn normalize_constness_equate(&self, tcx: TyCtxt<'tcx>, actual: &mut Self) { + pub fn normalize_constness_equate(&self, tcx: TyCtxt<'tcx>, actual: &mut SubstsRef<'tcx>) { if self.constness() == ty::ConstnessArg::Not { *actual = tcx.mk_substs(actual.iter().filter(|arg| match arg.unpack() { ty::subst::GenericArgKind::Constness(_) => false, diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 2bdc0f0e5fe49..6041ca677cb33 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -48,7 +48,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // when const_trait_impl not enabled, all const predicates are unimplemented if obligation.predicate.constness() == ty::ConstnessArg::Const { if !self.tcx().features().enabled(sym::const_trait_impl) { - return Err(SelectionError::Unimplemented) + return Err(SelectionError::Unimplemented); } } // TODO rm diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 8998dbbe000da..cae99ad92ea5c 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -2155,10 +2155,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { self.infcx().replace_bound_vars_with_placeholders(obligation.predicate); let placeholder_obligation_trait_ref = placeholder_obligation.trait_ref; - let impl_substs = self.infcx.fresh_substs_for_item(obligation.cause.span, impl_def_id); + let mut impl_substs = self.infcx.fresh_substs_for_item(obligation.cause.span, impl_def_id); - let mut impl_trait_ref = impl_trait_ref.subst(self.tcx(), impl_substs); - placeholder_obligation_trait_ref.normalize_constness_equate(self.tcx(), &mut impl_trait_ref); + placeholder_obligation_trait_ref.normalize_constness_equate(self.tcx(), &mut impl_substs); + + let impl_trait_ref = impl_trait_ref.subst(self.tcx(), impl_substs); debug!(?impl_trait_ref); diff --git a/compiler/rustc_typeck/src/check/method/probe.rs b/compiler/rustc_typeck/src/check/method/probe.rs index 8afc25f143e14..42c69f0d491d3 100644 --- a/compiler/rustc_typeck/src/check/method/probe.rs +++ b/compiler/rustc_typeck/src/check/method/probe.rs @@ -1843,7 +1843,9 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { }; self.next_const_var(self.tcx.type_of(param.def_id), origin).into() } - GenericParamDefKind::Constness => self.fcx.constness().into(), + // there is no need to require constness even when we are in a const context. + // just check if the trait is implemented. + GenericParamDefKind::Constness => ty::ConstnessArg::Not.into(), }) } diff --git a/compiler/rustc_typeck/src/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs index 6eff8a68a99c0..90f3bc0aac4e0 100644 --- a/compiler/rustc_typeck/src/check/wfcheck.rs +++ b/compiler/rustc_typeck/src/check/wfcheck.rs @@ -1833,20 +1833,10 @@ fn check_false_global_bounds(fcx: &FnCtxt<'_, '_>, mut span: Span, id: hir::HirI let /* mut */ pred = fcx.normalize_associated_types_in(span, pred); let hir_node = fcx.tcx.hir().find(id); - if fcx.constness() == ty::ConstnessArg::Not { - struct NotConstFolder<'tcx>(TyCtxt<'tcx>); // TODO justify this hack - - impl<'tcx> ty::TypeFolder<'tcx> for NotConstFolder<'tcx> { - fn tcx<'a>(&'a self) -> TyCtxt<'tcx> { - self.0 - } - fn fold_constness(&mut self, _: ty::ConstnessArg) -> ty::ConstnessArg { - ty::ConstnessArg::Not - } - } - - pred = pred.fold_with(&mut NotConstFolder(fcx.tcx)) - } + // TODO + /*if fcx.constness() == ty::ConstnessArg::Not { + pred = pred.without_const(fcx.tcx) + }*/ // only use the span of the predicate clause (#90869) diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index f73f057249c8b..4ec70ad70a3fa 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -1624,7 +1624,9 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics { }; let has_self = opt_self.is_some(); - let has_constness = tcx.has_attr(def_id, sym::const_trait) || (tcx.def_kind(def_id) == DefKind::Impl && tcx.impl_constness(def_id) == hir::Constness::Const); + let has_constness = tcx.has_attr(def_id, sym::const_trait) + || (tcx.def_kind(def_id) == DefKind::Impl + && tcx.impl_constness(def_id) == hir::Constness::Const); let mut parent_has_self = false; let mut parent_has_constness = false; let mut own_start = has_self as u32; diff --git a/src/test/ui/rfc-2632-const-trait-impl/call-const-trait-method-fail.rs b/src/test/ui/rfc-2632-const-trait-impl/call-const-trait-method-fail.rs index 691237a56856f..e13903f6182cf 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/call-const-trait-method-fail.rs +++ b/src/test/ui/rfc-2632-const-trait-impl/call-const-trait-method-fail.rs @@ -23,7 +23,8 @@ pub const fn add_i32(a: i32, b: i32) -> i32 { pub const fn add_u32(a: u32, b: u32) -> u32 { a.plus(b) - //~^ ERROR no method named `plus` found for type `u32` in the current scope + //~^ ERROR the trait bound + //~| ERROR cannot call } fn main() {} diff --git a/src/test/ui/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr b/src/test/ui/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr index bd91395fe5562..bc92719f6fd60 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr @@ -1,16 +1,27 @@ -error[E0599]: no method named `plus` found for type `u32` in the current scope +error[E0277]: the trait bound `u32: Plus` is not satisfied --> $DIR/call-const-trait-method-fail.rs:25:7 | LL | a.plus(b) - | ^^^^ method not found in `u32` + | ^^^^^^^ the trait `Plus` is not implemented for `u32` | - = help: items from traits can only be used if the trait is implemented and in scope -note: `Plus` defines an item `plus`, perhaps you need to implement it - --> $DIR/call-const-trait-method-fail.rs:4:1 +note: the trait `Plus` is implemented for `u32`, but that implementation is not `const` + --> $DIR/call-const-trait-method-fail.rs:25:7 + | +LL | a.plus(b) + | ^^^^^^^ + = help: the following other types implement trait `Plus`: + > + > + +error[E0015]: cannot call non-const fn `>::plus` in constant functions + --> $DIR/call-const-trait-method-fail.rs:25:7 + | +LL | a.plus(b) + | ^^^^^^^ | -LL | pub trait Plus { - | ^^^^^^^^^^^^^^ + = 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 E0599`. +Some errors have detailed explanations: E0015, E0277. +For more information about an error, try `rustc --explain E0015`. diff --git a/src/test/ui/rfc-2632-const-trait-impl/cross-crate.gated.stderr b/src/test/ui/rfc-2632-const-trait-impl/cross-crate.gated.stderr index 42203a46f5b83..7e5eb8742160f 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/cross-crate.gated.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/cross-crate.gated.stderr @@ -1,15 +1,25 @@ -error[E0599]: no method named `func` found for struct `cross_crate::NonConst` in the current scope - --> $DIR/cross-crate.rs:10:14 +error[E0277]: the trait bound `NonConst: MyTrait` is not satisfied + --> $DIR/cross-crate.rs:15:14 + | +LL | NonConst.func(); + | ^^^^^^ the trait `MyTrait` is not implemented for `NonConst` + | +note: the trait `MyTrait` is implemented for `NonConst`, but that implementation is not `const` + --> $DIR/cross-crate.rs:15:14 | LL | NonConst.func(); - | ^^^^ method not found in `cross_crate::NonConst` + | ^^^^^^ + = help: the trait `MyTrait` is implemented for `NonConst` -error[E0599]: no method named `func` found for struct `cross_crate::NonConst` in the current scope +error[E0015]: cannot call non-const fn `>::func` in constant functions --> $DIR/cross-crate.rs:15:14 | LL | NonConst.func(); - | ^^^^ method not found in `cross_crate::NonConst` + | ^^^^^^ + | + = 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 E0599`. +Some errors have detailed explanations: E0015, E0277. +For more information about an error, try `rustc --explain E0015`. diff --git a/src/test/ui/rfc-2632-const-trait-impl/cross-crate.rs b/src/test/ui/rfc-2632-const-trait-impl/cross-crate.rs index fa049ab86ff49..590f0ad3d42a9 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/cross-crate.rs +++ b/src/test/ui/rfc-2632-const-trait-impl/cross-crate.rs @@ -12,10 +12,10 @@ fn non_const_context() { } const fn const_context() { - NonConst.func(); //~ ERROR: cannot call non-const fn + NonConst.func(); //~ ERROR: cannot call //[gated]~^ ERROR: the trait bound Const.func(); - //[stock]~^ ERROR: cannot call non-const fn + //[stock]~^ ERROR: cannot call } fn main() {} diff --git a/src/test/ui/rfc-2632-const-trait-impl/cross-crate.stock.stderr b/src/test/ui/rfc-2632-const-trait-impl/cross-crate.stock.stderr index 42203a46f5b83..00f26cd771765 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/cross-crate.stock.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/cross-crate.stock.stderr @@ -1,15 +1,19 @@ -error[E0599]: no method named `func` found for struct `cross_crate::NonConst` in the current scope - --> $DIR/cross-crate.rs:10:14 +error[E0015]: cannot call non-const fn `>::func` in constant functions + --> $DIR/cross-crate.rs:15:14 | LL | NonConst.func(); - | ^^^^ method not found in `cross_crate::NonConst` + | ^^^^^^ + | + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants -error[E0599]: no method named `func` found for struct `cross_crate::NonConst` in the current scope - --> $DIR/cross-crate.rs:15:14 +error[E0015]: cannot call non-const fn `>::func` in constant functions + --> $DIR/cross-crate.rs:17:11 | -LL | NonConst.func(); - | ^^^^ method not found in `cross_crate::NonConst` +LL | Const.func(); + | ^^^^^^ + | + = 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 E0599`. +For more information about this error, try `rustc --explain E0015`. From 1ee0614a437a771b1cc4e2f1d303e5f32cd7d68a Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Mon, 20 Jun 2022 19:41:32 +1000 Subject: [PATCH 46/51] Equate candidates modulo constness --- compiler/rustc_infer/src/traits/project.rs | 1 + compiler/rustc_middle/src/ty/print/pretty.rs | 7 ++++--- compiler/rustc_middle/src/ty/sty.rs | 15 ++++++++++++++- .../rustc_trait_selection/src/traits/project.rs | 16 +++++++++++++--- .../src/traits/select/mod.rs | 6 ++++-- 5 files changed, 36 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_infer/src/traits/project.rs b/compiler/rustc_infer/src/traits/project.rs index 5d22f9f972e10..cb4a16204842a 100644 --- a/compiler/rustc_infer/src/traits/project.rs +++ b/compiler/rustc_infer/src/traits/project.rs @@ -228,6 +228,7 @@ impl<'tcx> ProjectionCache<'_, 'tcx> { /// type information (in which case, the "fully resolved" key will /// be different). pub fn ambiguous(&mut self, key: ProjectionCacheKey<'tcx>) { + debug!(?key, "ambiguous"); let fresh = self.map().insert(key, ProjectionCacheEntry::Ambiguous); assert!(!fresh, "never started projecting `{:?}`", key); } diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index c818983f2e38a..084caa722c614 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1824,12 +1824,13 @@ impl<'tcx> Printer<'tcx> for FmtPrinter<'_, 'tcx> { GenericArgKind::Lifetime(r) => !r.is_erased(), _ => false, }); - let args = args.iter().cloned().filter(|arg| match arg.unpack() { + let mut args = args.iter().cloned().filter(|arg| match arg.unpack() { GenericArgKind::Lifetime(_) => print_regions, + GenericArgKind::Constness(_) => false, _ => true, - }); + }).peekable(); - if args.clone().next().is_some() { + if args.peek().is_some() { if self.in_value { write!(self, "::")?; } diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 90a948dd1a772..8431500135c9d 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -32,6 +32,8 @@ use rustc_type_ir::sty::TyKind::*; use rustc_type_ir::RegionKind as IrRegionKind; use rustc_type_ir::TyKind as IrTyKind; +use super::GenericArgKind; + // Re-export the `TyKind` from `rustc_type_ir` here for convenience #[rustc_diagnostic_item = "TyKind"] pub type TyKind<'tcx> = IrTyKind>; @@ -849,13 +851,19 @@ impl<'tcx> TraitRef<'tcx> { pub fn with_const(mut self, tcx: TyCtxt<'tcx>) -> Self { if self.constness() != ty::ConstnessArg::Const { self.substs = tcx.mk_substs(self.substs.iter().map(|arg| match arg.unpack() { - ty::subst::GenericArgKind::Constness(_) => ty::ConstnessArg::Const.into(), + GenericArgKind::Constness(_) => ty::ConstnessArg::Const.into(), _ => arg, })); } self } + + pub fn eq_modulo_constness(&self, other: &TraitRef<'tcx>) -> bool { + let f = |s: &GenericArg<'_>| !matches!(s.unpack(), GenericArgKind::Constness(_)); + self.def_id == other.def_id + && self.substs.iter().filter(f).eq(other.substs.iter().filter(f)) + } } pub type PolyTraitRef<'tcx> = Binder<'tcx, TraitRef<'tcx>>; @@ -887,6 +895,11 @@ impl<'tcx> PolyTraitRef<'tcx> { pub fn without_const(self, tcx: TyCtxt<'tcx>) -> Self { self.map_bound(|tr| tr.without_const(tcx)) } + + pub fn eq_modulo_constness(&self, other: &Self) -> bool { + self.bound_vars() == other.bound_vars() + && self.skip_binder().eq_modulo_constness(other.as_ref().skip_binder()) + } } /// An existential reference to a trait, where `Self` is erased. diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 39e4be063980f..9dc6a831b7101 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -91,7 +91,8 @@ impl<'tcx> ProjectionCandidateSet<'tcx> { // Returns true if the push was successful, or false if the candidate // was discarded -- this could be because of ambiguity, or because // a higher-priority candidate is already there. - fn push_candidate(&mut self, candidate: ProjectionCandidate<'tcx>) -> bool { + #[tracing::instrument(level = "debug", skip(self, tcx))] + fn push_candidate(&mut self, tcx: TyCtxt<'tcx>, candidate: ProjectionCandidate<'tcx>) -> bool { use self::ProjectionCandidate::*; use self::ProjectionCandidateSet::*; @@ -126,6 +127,15 @@ impl<'tcx> ProjectionCandidateSet<'tcx> { // clauses are the safer choice. See the comment on // `select::SelectionCandidate` and #21974 for more details. match (current, candidate) { + // HACK(fee1-dead) + // If both candidates are the same, except for the constness argument, it is not an ambiguity + (ParamEnv(a), ParamEnv(b)) + if a.required_poly_trait_ref(tcx) + .eq_modulo_constness(&b.required_poly_trait_ref(tcx)) + && a.term() == b.term() => + { + return false; + } (ParamEnv(..), ParamEnv(..)) => convert_to_ambiguous = (), (ParamEnv(..), _) => return false, (_, ParamEnv(..)) => unreachable!(), @@ -1365,7 +1375,7 @@ fn assemble_candidates_from_predicates<'cx, 'tcx>( match is_match { ProjectionMatchesProjection::Yes => { - candidate_set.push_candidate(ctor(data)); + candidate_set.push_candidate(infcx.tcx, ctor(data)); if potentially_unnormalized_candidates && !obligation.predicate.has_infer_types_or_consts() @@ -1635,7 +1645,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( }; if eligible { - if candidate_set.push_candidate(ProjectionCandidate::Select(impl_source)) { + if candidate_set.push_candidate(selcx.tcx(), ProjectionCandidate::Select(impl_source)) { Ok(()) } else { Err(()) diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index cae99ad92ea5c..1bac985b4c66e 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1645,7 +1645,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, '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 { @@ -1655,7 +1654,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, '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. other.bound_vars().len() <= victim.bound_vars().len() - } else if other.skip_binder().trait_ref == victim.skip_binder().trait_ref + } else if other + .skip_binder() + .trait_ref + .eq_modulo_constness(&victim.skip_binder().trait_ref) && victim.skip_binder().constness() == ty::ConstnessArg::Not && other.skip_binder().polarity == victim.skip_binder().polarity { From 7316ca48b5328a2d19b205a06fe9ca895fbf0b80 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Mon, 20 Jun 2022 19:59:58 +1000 Subject: [PATCH 47/51] Revert "HACK: Remove all const trait impls and `~const` from libcore/libstd" This reverts commit 7dc2fab2895041f82fabc6525c895cc574b3d044. --- compiler/rustc_ast/src/ptr.rs | 2 +- library/alloc/src/alloc.rs | 23 ++- library/alloc/src/borrow.rs | 5 +- library/alloc/src/boxed.rs | 78 ++++++---- library/alloc/src/lib.rs | 4 + library/alloc/src/string.rs | 3 +- library/alloc/src/vec/mod.rs | 3 +- library/core/src/array/mod.rs | 22 ++- library/core/src/bool.rs | 14 +- library/core/src/borrow.rs | 15 +- library/core/src/cell.rs | 12 +- library/core/src/char/convert.rs | 12 +- library/core/src/clone.rs | 23 ++- library/core/src/cmp.rs | 2 + library/core/src/convert/mod.rs | 41 +++-- library/core/src/convert/num.rs | 18 ++- library/core/src/default.rs | 3 +- library/core/src/hash/mod.rs | 3 +- library/core/src/internal_macros.rs | 75 ++++++++- library/core/src/intrinsics.rs | 40 ++++- library/core/src/iter/sources/empty.rs | 3 +- library/core/src/iter/traits/collect.rs | 3 +- library/core/src/lib.rs | 8 + library/core/src/marker.rs | 3 +- library/core/src/mem/manually_drop.rs | 6 +- library/core/src/mem/maybe_uninit.rs | 2 +- library/core/src/num/error.rs | 5 +- library/core/src/num/f32.rs | 125 +++++++++++++-- library/core/src/num/f64.rs | 88 ++++++++++- library/core/src/num/nonzero.rs | 24 ++- library/core/src/num/wrapping.rs | 168 ++++++++++++-------- library/core/src/ops/arith.rs | 65 ++++---- library/core/src/ops/bit.rs | 57 ++++--- library/core/src/ops/deref.rs | 6 +- library/core/src/option.rs | 196 +++++++++++++++++------- library/core/src/ptr/const_ptr.rs | 16 +- library/core/src/ptr/mod.rs | 14 +- library/core/src/ptr/mut_ptr.rs | 14 +- library/core/src/ptr/non_null.rs | 17 +- library/core/src/ptr/unique.rs | 10 +- library/core/src/result.rs | 70 ++++++--- library/core/src/slice/index.rs | 79 ++++++++-- library/core/src/slice/mod.rs | 26 ++-- library/core/src/slice/raw.rs | 2 +- library/core/src/str/converts.rs | 6 +- library/core/src/str/mod.rs | 39 ++++- library/core/src/str/traits.rs | 28 ++-- library/core/src/str/validations.rs | 3 +- library/core/src/sync/atomic.rs | 18 ++- library/core/src/task/poll.rs | 3 +- library/core/src/time.rs | 22 ++- 51 files changed, 1116 insertions(+), 408 deletions(-) diff --git a/compiler/rustc_ast/src/ptr.rs b/compiler/rustc_ast/src/ptr.rs index 0a93841414938..30481eddf9160 100644 --- a/compiler/rustc_ast/src/ptr.rs +++ b/compiler/rustc_ast/src/ptr.rs @@ -127,7 +127,7 @@ impl> Encodable for P { } impl P<[T]> { - pub fn new() -> P<[T]> { + pub const fn new() -> P<[T]> { P { ptr: Box::default() } } diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs index a18a12183455c..649aeb0890dc0 100644 --- a/library/alloc/src/alloc.rs +++ b/library/alloc/src/alloc.rs @@ -14,6 +14,8 @@ use core::ptr::{self, NonNull}; #[doc(inline)] pub use core::alloc::*; +use core::marker::Destruct; + #[cfg(test)] mod tests; @@ -323,12 +325,16 @@ unsafe fn exchange_malloc(size: usize, align: usize) -> *mut u8 { #[cfg_attr(not(test), lang = "box_free")] #[inline] +#[rustc_const_unstable(feature = "const_box", issue = "92521")] // This signature has to be the same as `Box`, otherwise an ICE will happen. // When an additional parameter to `Box` is added (like `A: Allocator`), this has to be added here as // well. // For example if `Box` is changed to `struct Box(Unique, A)`, // this function has to be changed to `fn box_free(Unique, A)` as well. -pub(crate) unsafe fn box_free(ptr: Unique, alloc: A) { +pub(crate) const unsafe fn box_free( + ptr: Unique, + alloc: A, +) { unsafe { let size = size_of_val(ptr.as_ref()); let align = min_align_of_val(ptr.as_ref()); @@ -360,12 +366,21 @@ extern "Rust" { /// [`set_alloc_error_hook`]: ../../std/alloc/fn.set_alloc_error_hook.html /// [`take_alloc_error_hook`]: ../../std/alloc/fn.take_alloc_error_hook.html #[stable(feature = "global_alloc", since = "1.28.0")] +#[rustc_const_unstable(feature = "const_alloc_error", issue = "92523")] #[cfg(all(not(no_global_oom_handling), not(test)))] #[cold] -pub fn handle_alloc_error(layout: Layout) -> ! { - unsafe { - __rust_alloc_error_handler(layout.size(), layout.align()); +pub const fn handle_alloc_error(layout: Layout) -> ! { + const fn ct_error(_: Layout) -> ! { + panic!("allocation failed"); + } + + fn rt_error(layout: Layout) -> ! { + unsafe { + __rust_alloc_error_handler(layout.size(), layout.align()); + } } + + unsafe { core::intrinsics::const_eval_select((layout,), ct_error, rt_error) } } // For alloc test `std::alloc::handle_alloc_error` can be used directly. diff --git a/library/alloc/src/borrow.rs b/library/alloc/src/borrow.rs index 94f0b2c524b4b..904a53bb4acc7 100644 --- a/library/alloc/src/borrow.rs +++ b/library/alloc/src/borrow.rs @@ -329,9 +329,10 @@ impl Cow<'_, B> { } #[stable(feature = "rust1", since = "1.0.0")] -impl Deref for Cow<'_, B> +#[rustc_const_unstable(feature = "const_deref", issue = "88955")] +impl const Deref for Cow<'_, B> where - B::Owned: Borrow, + B::Owned: ~const Borrow, { type Target = B; diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index d2ee3b4668f08..d83bab7bbbdad 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -157,7 +157,7 @@ use core::hash::{Hash, Hasher}; #[cfg(not(no_global_oom_handling))] use core::iter::FromIterator; use core::iter::{FusedIterator, Iterator}; -use core::marker::{Unpin, Unsize}; +use core::marker::{Destruct, Unpin, Unsize}; use core::mem; use core::ops::{ CoerceUnsized, Deref, DerefMut, DispatchFromDyn, Generator, GeneratorState, Receiver, @@ -373,11 +373,12 @@ impl Box { /// ``` #[cfg(not(no_global_oom_handling))] #[unstable(feature = "allocator_api", issue = "32838")] + #[rustc_const_unstable(feature = "const_box", issue = "92521")] #[must_use] #[inline] - pub fn new_in(x: T, alloc: A) -> Self + pub const fn new_in(x: T, alloc: A) -> Self where - A: Allocator, + A: ~const Allocator + ~const Destruct, { let mut boxed = Self::new_uninit_in(alloc); unsafe { @@ -402,10 +403,12 @@ impl Box { /// # Ok::<(), std::alloc::AllocError>(()) /// ``` #[unstable(feature = "allocator_api", issue = "32838")] + #[rustc_const_unstable(feature = "const_box", issue = "92521")] #[inline] - pub fn try_new_in(x: T, alloc: A) -> Result + pub const fn try_new_in(x: T, alloc: A) -> Result where - A: Allocator, + T: ~const Destruct, + A: ~const Allocator + ~const Destruct, { let mut boxed = Self::try_new_uninit_in(alloc)?; unsafe { @@ -435,12 +438,13 @@ impl Box { /// assert_eq!(*five, 5) /// ``` #[unstable(feature = "allocator_api", issue = "32838")] + #[rustc_const_unstable(feature = "const_box", issue = "92521")] #[cfg(not(no_global_oom_handling))] #[must_use] // #[unstable(feature = "new_uninit", issue = "63291")] - pub fn new_uninit_in(alloc: A) -> Box, A> + pub const fn new_uninit_in(alloc: A) -> Box, A> where - A: Allocator, + A: ~const Allocator + ~const Destruct, { let layout = Layout::new::>(); // NOTE: Prefer match over unwrap_or_else since closure sometimes not inlineable. @@ -475,9 +479,10 @@ impl Box { /// ``` #[unstable(feature = "allocator_api", issue = "32838")] // #[unstable(feature = "new_uninit", issue = "63291")] - pub fn try_new_uninit_in(alloc: A) -> Result, A>, AllocError> + #[rustc_const_unstable(feature = "const_box", issue = "92521")] + pub const fn try_new_uninit_in(alloc: A) -> Result, A>, AllocError> where - A: Allocator, + A: ~const Allocator + ~const Destruct, { let layout = Layout::new::>(); let ptr = alloc.allocate(layout)?.cast(); @@ -505,12 +510,13 @@ impl Box { /// /// [zeroed]: mem::MaybeUninit::zeroed #[unstable(feature = "allocator_api", issue = "32838")] + #[rustc_const_unstable(feature = "const_box", issue = "92521")] #[cfg(not(no_global_oom_handling))] // #[unstable(feature = "new_uninit", issue = "63291")] #[must_use] - pub fn new_zeroed_in(alloc: A) -> Box, A> + pub const fn new_zeroed_in(alloc: A) -> Box, A> where - A: Allocator, + A: ~const Allocator + ~const Destruct, { let layout = Layout::new::>(); // NOTE: Prefer match over unwrap_or_else since closure sometimes not inlineable. @@ -545,9 +551,10 @@ impl Box { /// [zeroed]: mem::MaybeUninit::zeroed #[unstable(feature = "allocator_api", issue = "32838")] // #[unstable(feature = "new_uninit", issue = "63291")] - pub fn try_new_zeroed_in(alloc: A) -> Result, A>, AllocError> + #[rustc_const_unstable(feature = "const_box", issue = "92521")] + pub const fn try_new_zeroed_in(alloc: A) -> Result, A>, AllocError> where - A: Allocator, + A: ~const Allocator + ~const Destruct, { let layout = Layout::new::>(); let ptr = alloc.allocate_zeroed(layout)?.cast(); @@ -563,11 +570,12 @@ impl Box { /// construct a (pinned) `Box` in a different way than with [`Box::new_in`]. #[cfg(not(no_global_oom_handling))] #[unstable(feature = "allocator_api", issue = "32838")] + #[rustc_const_unstable(feature = "const_box", issue = "92521")] #[must_use] #[inline(always)] - pub fn pin_in(x: T, alloc: A) -> Pin + pub const fn pin_in(x: T, alloc: A) -> Pin where - A: 'static + Allocator, + A: 'static + ~const Allocator + ~const Destruct, { Self::into_pin(Self::new_in(x, alloc)) } @@ -576,7 +584,8 @@ impl Box { /// /// This conversion does not allocate on the heap and happens in place. #[unstable(feature = "box_into_boxed_slice", issue = "71582")] - pub fn into_boxed_slice(boxed: Self) -> Box<[T], A> { + #[rustc_const_unstable(feature = "const_box", issue = "92521")] + pub const fn into_boxed_slice(boxed: Self) -> Box<[T], A> { let (raw, alloc) = Box::into_raw_with_allocator(boxed); unsafe { Box::from_raw_in(raw as *mut [T; 1], alloc) } } @@ -593,8 +602,12 @@ impl Box { /// assert_eq!(Box::into_inner(c), 5); /// ``` #[unstable(feature = "box_into_inner", issue = "80437")] + #[rustc_const_unstable(feature = "const_box", issue = "92521")] #[inline] - pub fn into_inner(boxed: Self) -> T { + pub const fn into_inner(boxed: Self) -> T + where + Self: ~const Destruct, + { *boxed } } @@ -808,8 +821,9 @@ impl Box, A> { /// assert_eq!(*five, 5) /// ``` #[unstable(feature = "new_uninit", issue = "63291")] + #[rustc_const_unstable(feature = "const_box", issue = "92521")] #[inline] - pub unsafe fn assume_init(self) -> Box { + pub const unsafe fn assume_init(self) -> Box { let (raw, alloc) = Box::into_raw_with_allocator(self); unsafe { Box::from_raw_in(raw as *mut T, alloc) } } @@ -842,8 +856,9 @@ impl Box, A> { /// } /// ``` #[unstable(feature = "new_uninit", issue = "63291")] + #[rustc_const_unstable(feature = "const_box", issue = "92521")] #[inline] - pub fn write(mut boxed: Self, value: T) -> Box { + pub const fn write(mut boxed: Self, value: T) -> Box { unsafe { (*boxed).write(value); boxed.assume_init() @@ -1086,8 +1101,9 @@ impl Box { /// /// [memory layout]: self#memory-layout #[unstable(feature = "allocator_api", issue = "32838")] + #[rustc_const_unstable(feature = "const_box", issue = "92521")] #[inline] - pub fn into_raw_with_allocator(b: Self) -> (*mut T, A) { + pub const fn into_raw_with_allocator(b: Self) -> (*mut T, A) { let (leaked, alloc) = Box::into_unique(b); (leaked.as_ptr(), alloc) } @@ -1097,9 +1113,10 @@ impl Box { issue = "none", reason = "use `Box::leak(b).into()` or `Unique::from(Box::leak(b))` instead" )] + #[rustc_const_unstable(feature = "const_box", issue = "92521")] #[inline] #[doc(hidden)] - pub fn into_unique(b: Self) -> (Unique, A) { + pub const fn into_unique(b: Self) -> (Unique, A) { // Box is recognized as a "unique pointer" by Stacked Borrows, but internally it is a // raw pointer for the type system. Turning it directly into a raw pointer would not be // recognized as "releasing" the unique pointer to permit aliased raw accesses, @@ -1157,8 +1174,9 @@ impl Box { /// assert_eq!(*static_ref, [4, 2, 3]); /// ``` #[stable(feature = "box_leak", since = "1.26.0")] + #[rustc_const_unstable(feature = "const_box", issue = "92521")] #[inline] - pub fn leak<'a>(b: Self) -> &'a mut T + pub const fn leak<'a>(b: Self) -> &'a mut T where A: 'a, { @@ -1228,7 +1246,7 @@ impl Default for Box { #[cfg(not(no_global_oom_handling))] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] -impl Default for Box<[T]> { +impl const Default for Box<[T]> { fn default() -> Self { let ptr: Unique<[T]> = Unique::<[T; 0]>::dangling(); Box(ptr, Global) @@ -1238,7 +1256,7 @@ impl Default for Box<[T]> { #[cfg(not(no_global_oom_handling))] #[stable(feature = "default_box_extra", since = "1.17.0")] #[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] -impl Default for Box { +impl const Default for Box { fn default() -> Self { // SAFETY: This is the same as `Unique::cast` but with an unsized `U = str`. let ptr: Unique = unsafe { @@ -1434,7 +1452,8 @@ impl From for Box { } #[stable(feature = "pin", since = "1.33.0")] -impl From> for Pin> +#[rustc_const_unstable(feature = "const_box", issue = "92521")] +impl const From> for Pin> where A: 'static, { @@ -1822,7 +1841,8 @@ impl fmt::Pointer for Box { } #[stable(feature = "rust1", since = "1.0.0")] -impl Deref for Box { +#[rustc_const_unstable(feature = "const_box", issue = "92521")] +impl const Deref for Box { type Target = T; fn deref(&self) -> &T { @@ -1831,7 +1851,8 @@ impl Deref for Box { } #[stable(feature = "rust1", since = "1.0.0")] -impl DerefMut for Box { +#[rustc_const_unstable(feature = "const_box", issue = "92521")] +impl const DerefMut for Box { fn deref_mut(&mut self) -> &mut T { &mut **self } @@ -2010,7 +2031,8 @@ impl AsMut for Box { * could have a method to project a Pin from it. */ #[stable(feature = "pin", since = "1.33.0")] -impl Unpin for Box where A: 'static {} +#[rustc_const_unstable(feature = "const_box", issue = "92521")] +impl const Unpin for Box where A: 'static {} #[unstable(feature = "generator_trait", issue = "43122")] impl + Unpin, R, A: Allocator> Generator for Box diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 0ec0068420886..d3816d70b635d 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -95,9 +95,11 @@ #![feature(assert_matches)] #![feature(async_iterator)] #![feature(coerce_unsized)] +#![cfg_attr(not(no_global_oom_handling), feature(const_alloc_error))] #![feature(const_box)] #![cfg_attr(not(no_global_oom_handling), feature(const_btree_new))] #![feature(const_cow_is_borrowed)] +#![feature(const_convert)] #![feature(const_size_of_val)] #![feature(const_align_of_val)] #![feature(const_ptr_read)] @@ -107,6 +109,7 @@ #![feature(core_c_str)] #![feature(core_intrinsics)] #![feature(core_ffi_c)] +#![feature(const_eval_select)] #![feature(const_pin)] #![feature(cstr_from_bytes_until_nul)] #![feature(dispatch_from_dyn)] @@ -147,6 +150,7 @@ #![feature(allow_internal_unstable)] #![feature(associated_type_bounds)] #![feature(cfg_sanitize)] +#![feature(const_deref)] #![feature(const_mut_refs)] #![feature(const_ptr_write)] #![feature(const_precise_live_drops)] diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index e0be3bfef809e..b1513e5e0f31c 100644 --- a/library/alloc/src/string.rs +++ b/library/alloc/src/string.rs @@ -2212,7 +2212,8 @@ impl_eq! { Cow<'a, str>, &'b str } impl_eq! { Cow<'a, str>, String } #[stable(feature = "rust1", since = "1.0.0")] -impl Default for String { +#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] +impl const Default for String { /// Creates an empty `String`. #[inline] fn default() -> String { diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 859e6e9710eda..fa9f2131c0c1d 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -2924,7 +2924,8 @@ unsafe impl<#[may_dangle] T, A: Allocator> Drop for Vec { } #[stable(feature = "rust1", since = "1.0.0")] -impl Default for Vec { +#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] +impl const Default for Vec { /// Creates an empty `Vec`. fn default() -> Vec { Vec::new() diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs index badeb7f5fa666..c9823a136bc42 100644 --- a/library/core/src/array/mod.rs +++ b/library/core/src/array/mod.rs @@ -134,7 +134,8 @@ impl TryFromSliceError { } #[stable(feature = "try_from_slice_error", since = "1.36.0")] -impl From for TryFromSliceError { +#[rustc_const_unstable(feature = "const_convert", issue = "88674")] +impl const From for TryFromSliceError { fn from(x: Infallible) -> TryFromSliceError { match x {} } @@ -157,14 +158,16 @@ impl AsMut<[T]> for [T; N] { } #[stable(feature = "array_borrow", since = "1.4.0")] -impl Borrow<[T]> for [T; N] { +#[rustc_const_unstable(feature = "const_borrow", issue = "91522")] +impl const Borrow<[T]> for [T; N] { fn borrow(&self) -> &[T] { self } } #[stable(feature = "array_borrow", since = "1.4.0")] -impl BorrowMut<[T]> for [T; N] { +#[rustc_const_unstable(feature = "const_borrow", issue = "91522")] +impl const BorrowMut<[T]> for [T; N] { fn borrow_mut(&mut self) -> &mut [T] { self } @@ -271,9 +274,10 @@ impl<'a, T, const N: usize> IntoIterator for &'a mut [T; N] { } #[stable(feature = "index_trait_on_arrays", since = "1.50.0")] -impl Index for [T; N] +#[rustc_const_unstable(feature = "const_slice_index", issue = "none")] +impl const Index for [T; N] where - [T]: Index, + [T]: ~const Index, { type Output = <[T] as Index>::Output; @@ -284,9 +288,10 @@ where } #[stable(feature = "index_trait_on_arrays", since = "1.50.0")] -impl IndexMut for [T; N] +#[rustc_const_unstable(feature = "const_slice_index", issue = "none")] +impl const IndexMut for [T; N] where - [T]: IndexMut, + [T]: ~const IndexMut, { #[inline] fn index_mut(&mut self, index: I) -> &mut Self::Output { @@ -379,7 +384,8 @@ macro_rules! array_impl_default { }; {$n:expr,} => { #[stable(since = "1.4.0", feature = "array_default")] - impl Default for [T; $n] { + #[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] + impl const Default for [T; $n] { fn default() -> [T; $n] { [] } } }; diff --git a/library/core/src/bool.rs b/library/core/src/bool.rs index d4103ff38554d..f7a8aa0d92156 100644 --- a/library/core/src/bool.rs +++ b/library/core/src/bool.rs @@ -1,5 +1,7 @@ //! impl bool {} +use crate::marker::Destruct; + impl bool { /// Returns `Some(t)` if the `bool` is [`true`](../std/keyword.true.html), /// or `None` otherwise. @@ -11,8 +13,12 @@ impl bool { /// assert_eq!(true.then_some(0), Some(0)); /// ``` #[stable(feature = "bool_to_option", since = "1.62.0")] + #[rustc_const_unstable(feature = "const_bool_to_option", issue = "91917")] #[inline] - pub fn then_some(self, t: T) -> Option { + pub const fn then_some(self, t: T) -> Option + where + T: ~const Destruct, + { if self { Some(t) } else { None } } @@ -26,10 +32,12 @@ impl bool { /// assert_eq!(true.then(|| 0), Some(0)); /// ``` #[stable(feature = "lazy_bool_to_option", since = "1.50.0")] + #[rustc_const_unstable(feature = "const_bool_to_option", issue = "91917")] #[inline] - pub fn then(self, f: F) -> Option + pub const fn then(self, f: F) -> Option where - F: FnOnce() -> T, + F: ~const FnOnce() -> T, + F: ~const Destruct, { if self { Some(f()) } else { None } } diff --git a/library/core/src/borrow.rs b/library/core/src/borrow.rs index f28be20aaa1e6..58eabecf3f091 100644 --- a/library/core/src/borrow.rs +++ b/library/core/src/borrow.rs @@ -205,7 +205,8 @@ pub trait BorrowMut: Borrow { } #[stable(feature = "rust1", since = "1.0.0")] -impl Borrow for T { +#[rustc_const_unstable(feature = "const_borrow", issue = "91522")] +impl const Borrow for T { #[rustc_diagnostic_item = "noop_method_borrow"] fn borrow(&self) -> &T { self @@ -213,28 +214,32 @@ impl Borrow for T { } #[stable(feature = "rust1", since = "1.0.0")] -impl BorrowMut for T { +#[rustc_const_unstable(feature = "const_borrow", issue = "91522")] +impl const BorrowMut for T { fn borrow_mut(&mut self) -> &mut T { self } } #[stable(feature = "rust1", since = "1.0.0")] -impl Borrow for &T { +#[rustc_const_unstable(feature = "const_borrow", issue = "91522")] +impl const Borrow for &T { fn borrow(&self) -> &T { &**self } } #[stable(feature = "rust1", since = "1.0.0")] -impl Borrow for &mut T { +#[rustc_const_unstable(feature = "const_borrow", issue = "91522")] +impl const Borrow for &mut T { fn borrow(&self) -> &T { &**self } } #[stable(feature = "rust1", since = "1.0.0")] -impl BorrowMut for &mut T { +#[rustc_const_unstable(feature = "const_borrow", issue = "91522")] +impl const BorrowMut for &mut T { fn borrow_mut(&mut self) -> &mut T { &mut **self } diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index 85f5af660fb28..8a37fadc56f4c 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -321,7 +321,8 @@ impl Ord for Cell { } #[stable(feature = "cell_from", since = "1.12.0")] -impl From for Cell { +#[rustc_const_unstable(feature = "const_convert", issue = "88674")] +impl const From for Cell { /// Creates a new `Cell` containing the given value. fn from(t: T) -> Cell { Cell::new(t) @@ -1252,7 +1253,8 @@ impl Ord for RefCell { } #[stable(feature = "cell_from", since = "1.12.0")] -impl From for RefCell { +#[rustc_const_unstable(feature = "const_convert", issue = "88674")] +impl const From for RefCell { /// Creates a new `RefCell` containing the given value. fn from(t: T) -> RefCell { RefCell::new(t) @@ -1995,7 +1997,8 @@ impl Default for UnsafeCell { } #[stable(feature = "cell_from", since = "1.12.0")] -impl From for UnsafeCell { +#[rustc_const_unstable(feature = "const_convert", issue = "88674")] +impl const From for UnsafeCell { /// Creates a new `UnsafeCell` containing the given value. fn from(t: T) -> UnsafeCell { UnsafeCell::new(t) @@ -2084,7 +2087,8 @@ impl Default for SyncUnsafeCell { } #[unstable(feature = "sync_unsafe_cell", issue = "95439")] -impl From for SyncUnsafeCell { +#[rustc_const_unstable(feature = "const_convert", issue = "88674")] +impl const From for SyncUnsafeCell { /// Creates a new `SyncUnsafeCell` containing the given value. fn from(t: T) -> SyncUnsafeCell { SyncUnsafeCell::new(t) diff --git a/library/core/src/char/convert.rs b/library/core/src/char/convert.rs index d085312b38143..7c5f82f5ea49d 100644 --- a/library/core/src/char/convert.rs +++ b/library/core/src/char/convert.rs @@ -27,7 +27,8 @@ pub(super) const unsafe fn from_u32_unchecked(i: u32) -> char { } #[stable(feature = "char_convert", since = "1.13.0")] -impl From for u32 { +#[rustc_const_unstable(feature = "const_convert", issue = "88674")] +impl const From for u32 { /// Converts a [`char`] into a [`u32`]. /// /// # Examples @@ -46,7 +47,8 @@ impl From for u32 { } #[stable(feature = "more_char_conversions", since = "1.51.0")] -impl From for u64 { +#[rustc_const_unstable(feature = "const_convert", issue = "88674")] +impl const From for u64 { /// Converts a [`char`] into a [`u64`]. /// /// # Examples @@ -67,7 +69,8 @@ impl From for u64 { } #[stable(feature = "more_char_conversions", since = "1.51.0")] -impl From for u128 { +#[rustc_const_unstable(feature = "const_convert", issue = "88674")] +impl const From for u128 { /// Converts a [`char`] into a [`u128`]. /// /// # Examples @@ -120,7 +123,8 @@ impl TryFrom for u8 { /// for a superset of Windows-1252 that fills the remaining blanks with corresponding /// C0 and C1 control codes. #[stable(feature = "char_convert", since = "1.13.0")] -impl From for char { +#[rustc_const_unstable(feature = "const_convert", issue = "88674")] +impl const From for char { /// Converts a [`u8`] into a [`char`]. /// /// # Examples diff --git a/library/core/src/clone.rs b/library/core/src/clone.rs index 1ff03a7147d54..3c2ffd0392d3f 100644 --- a/library/core/src/clone.rs +++ b/library/core/src/clone.rs @@ -36,6 +36,8 @@ #![stable(feature = "rust1", since = "1.0.0")] +use crate::marker::Destruct; + /// A common trait for the ability to explicitly duplicate an object. /// /// Differs from [`Copy`] in that [`Copy`] is implicit and an inexpensive bit-wise copy, while @@ -104,6 +106,7 @@ #[lang = "clone"] #[rustc_diagnostic_item = "Clone"] #[rustc_trivial_field_reads] +#[cfg_attr(not(bootstrap), const_trait)] pub trait Clone: Sized { /// Returns a copy of the value. /// @@ -126,7 +129,10 @@ pub trait Clone: Sized { /// allocations. #[inline] #[stable(feature = "rust1", since = "1.0.0")] - fn clone_from(&mut self, source: &Self) { + fn clone_from(&mut self, source: &Self) + where + Self: ~const Destruct, + { *self = source.clone() } } @@ -177,7 +183,8 @@ mod impls { ($($t:ty)*) => { $( #[stable(feature = "rust1", since = "1.0.0")] - impl Clone for $t { + #[rustc_const_unstable(feature = "const_clone", issue = "91805")] + impl const Clone for $t { #[inline] fn clone(&self) -> Self { *self @@ -195,7 +202,8 @@ mod impls { } #[unstable(feature = "never_type", issue = "35121")] - impl Clone for ! { + #[rustc_const_unstable(feature = "const_clone", issue = "91805")] + impl const Clone for ! { #[inline] fn clone(&self) -> Self { *self @@ -203,7 +211,8 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - impl Clone for *const T { + #[rustc_const_unstable(feature = "const_clone", issue = "91805")] + impl const Clone for *const T { #[inline] fn clone(&self) -> Self { *self @@ -211,7 +220,8 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - impl Clone for *mut T { + #[rustc_const_unstable(feature = "const_clone", issue = "91805")] + impl const Clone for *mut T { #[inline] fn clone(&self) -> Self { *self @@ -220,7 +230,8 @@ mod impls { /// Shared references can be cloned, but mutable references *cannot*! #[stable(feature = "rust1", since = "1.0.0")] - impl Clone for &T { + #[rustc_const_unstable(feature = "const_clone", issue = "91805")] + impl const Clone for &T { #[inline] #[rustc_diagnostic_item = "noop_method_clone"] fn clone(&self) -> Self { diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs index fd2914b04ab35..7147475789e62 100644 --- a/library/core/src/cmp.rs +++ b/library/core/src/cmp.rs @@ -214,6 +214,7 @@ use self::Ordering::*; append_const_msg, ) )] +#[cfg_attr(not(bootstrap), const_trait)] #[rustc_diagnostic_item = "PartialEq"] pub trait PartialEq { /// This method tests for `self` and `other` values to be equal, and is used @@ -1052,6 +1053,7 @@ impl PartialOrd for Ordering { append_const_msg, ) )] +#[cfg_attr(not(bootstrap), const_trait)] #[rustc_diagnostic_item = "PartialOrd"] pub trait PartialOrd: PartialEq { /// This method returns an ordering between `self` and `other` values if one exists. diff --git a/library/core/src/convert/mod.rs b/library/core/src/convert/mod.rs index 26821794f1b06..b30c8a4aeabdd 100644 --- a/library/core/src/convert/mod.rs +++ b/library/core/src/convert/mod.rs @@ -482,9 +482,10 @@ pub trait TryFrom: Sized { // As lifts over & #[stable(feature = "rust1", since = "1.0.0")] -impl AsRef for &T +#[rustc_const_unstable(feature = "const_convert", issue = "88674")] +impl const AsRef for &T where - T: AsRef, + T: ~const AsRef, { #[inline] fn as_ref(&self) -> &U { @@ -494,9 +495,10 @@ where // As lifts over &mut #[stable(feature = "rust1", since = "1.0.0")] -impl AsRef for &mut T +#[rustc_const_unstable(feature = "const_convert", issue = "88674")] +impl const AsRef for &mut T where - T: AsRef, + T: ~const AsRef, { #[inline] fn as_ref(&self) -> &U { @@ -514,9 +516,10 @@ where // AsMut lifts over &mut #[stable(feature = "rust1", since = "1.0.0")] -impl AsMut for &mut T +#[rustc_const_unstable(feature = "const_convert", issue = "88674")] +impl const AsMut for &mut T where - T: AsMut, + T: ~const AsMut, { #[inline] fn as_mut(&mut self) -> &mut U { @@ -534,9 +537,10 @@ where // From implies Into #[stable(feature = "rust1", since = "1.0.0")] -impl Into for T +#[rustc_const_unstable(feature = "const_convert", issue = "88674")] +impl const Into for T where - U: From, + U: ~const From, { /// Calls `U::from(self)`. /// @@ -549,7 +553,8 @@ where // From (and thus Into) is reflexive #[stable(feature = "rust1", since = "1.0.0")] -impl From for T { +#[rustc_const_unstable(feature = "const_convert", issue = "88674")] +impl const From for T { /// Returns the argument unchanged. fn from(t: T) -> T { t @@ -565,7 +570,8 @@ impl From for T { #[allow(unused_attributes)] // FIXME(#58633): do a principled fix instead. #[rustc_reservation_impl = "permitting this impl would forbid us from adding \ `impl From for T` later; see rust-lang/rust#64715 for details"] -impl From for T { +#[rustc_const_unstable(feature = "const_convert", issue = "88674")] +impl const From for T { fn from(t: !) -> T { t } @@ -573,9 +579,10 @@ impl From for T { // TryFrom implies TryInto #[stable(feature = "try_from", since = "1.34.0")] -impl TryInto for T +#[rustc_const_unstable(feature = "const_convert", issue = "88674")] +impl const TryInto for T where - U: TryFrom, + U: ~const TryFrom, { type Error = U::Error; @@ -587,9 +594,10 @@ where // Infallible conversions are semantically equivalent to fallible conversions // with an uninhabited error type. #[stable(feature = "try_from", since = "1.34.0")] -impl TryFrom for T +#[rustc_const_unstable(feature = "const_convert", issue = "88674")] +impl const TryFrom for T where - U: Into, + U: ~const Into, { type Error = Infallible; @@ -687,7 +695,7 @@ pub enum Infallible {} #[stable(feature = "convert_infallible", since = "1.34.0")] #[rustc_const_unstable(feature = "const_clone", issue = "91805")] -impl Clone for Infallible { +impl const Clone for Infallible { fn clone(&self) -> Infallible { match *self {} } @@ -732,7 +740,8 @@ impl Ord for Infallible { } #[stable(feature = "convert_infallible", since = "1.34.0")] -impl From for Infallible { +#[rustc_const_unstable(feature = "const_convert", issue = "88674")] +impl const From for Infallible { fn from(x: !) -> Self { x } diff --git a/library/core/src/convert/num.rs b/library/core/src/convert/num.rs index b6303a87003b3..4fa5d129bc6af 100644 --- a/library/core/src/convert/num.rs +++ b/library/core/src/convert/num.rs @@ -44,7 +44,8 @@ impl_float_to_int!(f64 => u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize); macro_rules! impl_from { ($Small: ty, $Large: ty, #[$attr:meta], $doc: expr) => { #[$attr] - impl From<$Small> for $Large { + #[rustc_const_unstable(feature = "const_num_from_num", issue = "87852")] + impl const From<$Small> for $Large { // Rustdocs on the impl block show a "[+] show undocumented items" toggle. // Rustdocs on functions do not. #[doc = $doc] @@ -171,7 +172,8 @@ impl_from! { f32, f64, #[stable(feature = "lossless_float_conv", since = "1.6.0" macro_rules! try_from_unbounded { ($source:ty, $($target:ty),*) => {$( #[stable(feature = "try_from", since = "1.34.0")] - impl TryFrom<$source> for $target { + #[rustc_const_unstable(feature = "const_num_from_num", issue = "87852")] + impl const TryFrom<$source> for $target { type Error = TryFromIntError; /// Try to create the target number type from a source @@ -189,7 +191,8 @@ macro_rules! try_from_unbounded { macro_rules! try_from_lower_bounded { ($source:ty, $($target:ty),*) => {$( #[stable(feature = "try_from", since = "1.34.0")] - impl TryFrom<$source> for $target { + #[rustc_const_unstable(feature = "const_num_from_num", issue = "87852")] + impl const TryFrom<$source> for $target { type Error = TryFromIntError; /// Try to create the target number type from a source @@ -211,7 +214,8 @@ macro_rules! try_from_lower_bounded { macro_rules! try_from_upper_bounded { ($source:ty, $($target:ty),*) => {$( #[stable(feature = "try_from", since = "1.34.0")] - impl TryFrom<$source> for $target { + #[rustc_const_unstable(feature = "const_num_from_num", issue = "87852")] + impl const TryFrom<$source> for $target { type Error = TryFromIntError; /// Try to create the target number type from a source @@ -233,7 +237,8 @@ macro_rules! try_from_upper_bounded { macro_rules! try_from_both_bounded { ($source:ty, $($target:ty),*) => {$( #[stable(feature = "try_from", since = "1.34.0")] - impl TryFrom<$source> for $target { + #[rustc_const_unstable(feature = "const_num_from_num", issue = "87852")] + impl const TryFrom<$source> for $target { type Error = TryFromIntError; /// Try to create the target number type from a source @@ -384,7 +389,8 @@ use crate::num::NonZeroUsize; macro_rules! nzint_impl_from { ($Small: ty, $Large: ty, #[$attr:meta], $doc: expr) => { #[$attr] - impl From<$Small> for $Large { + #[rustc_const_unstable(feature = "const_num_from_num", issue = "87852")] + impl const From<$Small> for $Large { // Rustdocs on the impl block show a "[+] show undocumented items" toggle. // Rustdocs on functions do not. #[doc = $doc] diff --git a/library/core/src/default.rs b/library/core/src/default.rs index 89a80b0f8e438..1ce00828bf344 100644 --- a/library/core/src/default.rs +++ b/library/core/src/default.rs @@ -189,7 +189,8 @@ pub macro Default($item:item) { macro_rules! default_impl { ($t:ty, $v:expr, $doc:tt) => { #[stable(feature = "rust1", since = "1.0.0")] - impl Default for $t { + #[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] + impl const Default for $t { #[inline] #[doc = $doc] fn default() -> $t { diff --git a/library/core/src/hash/mod.rs b/library/core/src/hash/mod.rs index 7b182b447c9ba..cf428e0b1cf1d 100644 --- a/library/core/src/hash/mod.rs +++ b/library/core/src/hash/mod.rs @@ -780,7 +780,8 @@ impl Clone for BuildHasherDefault { } #[stable(since = "1.7.0", feature = "build_hasher")] -impl Default for BuildHasherDefault { +#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] +impl const Default for BuildHasherDefault { fn default() -> BuildHasherDefault { BuildHasherDefault(marker::PhantomData) } diff --git a/library/core/src/internal_macros.rs b/library/core/src/internal_macros.rs index 4597bc5502b8d..5d4c9ba73951a 100644 --- a/library/core/src/internal_macros.rs +++ b/library/core/src/internal_macros.rs @@ -1,10 +1,23 @@ // implements the unary operator "op &T" // based on "op T" where T is expected to be `Copy`able macro_rules! forward_ref_unop { - (impl $imp:ident, $method:ident for $t:ty) => { - forward_ref_unop!(impl $imp, $method for $t, + (impl const $imp:ident, $method:ident for $t:ty) => { + forward_ref_unop!(impl const $imp, $method for $t, #[stable(feature = "rust1", since = "1.0.0")]); }; + // Equivalent to the non-const version, with the addition of `rustc_const_unstable` + (impl const $imp:ident, $method:ident for $t:ty, #[$attr:meta]) => { + #[$attr] + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const $imp for &$t { + type Output = <$t as $imp>::Output; + + #[inline] + fn $method(self) -> <$t as $imp>::Output { + $imp::$method(*self) + } + } + }; (impl $imp:ident, $method:ident for $t:ty, #[$attr:meta]) => { #[$attr] impl $imp for &$t { @@ -15,16 +28,51 @@ macro_rules! forward_ref_unop { $imp::$method(*self) } } - }; + } } // implements binary operators "&T op U", "T op &U", "&T op &U" // based on "T op U" where T and U are expected to be `Copy`able macro_rules! forward_ref_binop { - (impl $imp:ident, $method:ident for $t:ty, $u:ty) => { - forward_ref_binop!(impl $imp, $method for $t, $u, + (impl const $imp:ident, $method:ident for $t:ty, $u:ty) => { + forward_ref_binop!(impl const $imp, $method for $t, $u, #[stable(feature = "rust1", since = "1.0.0")]); }; + // Equivalent to the non-const version, with the addition of `rustc_const_unstable` + (impl const $imp:ident, $method:ident for $t:ty, $u:ty, #[$attr:meta]) => { + #[$attr] + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl<'a> const $imp<$u> for &'a $t { + type Output = <$t as $imp<$u>>::Output; + + #[inline] + fn $method(self, other: $u) -> <$t as $imp<$u>>::Output { + $imp::$method(*self, other) + } + } + + #[$attr] + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const $imp<&$u> for $t { + type Output = <$t as $imp<$u>>::Output; + + #[inline] + fn $method(self, other: &$u) -> <$t as $imp<$u>>::Output { + $imp::$method(self, *other) + } + } + + #[$attr] + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const $imp<&$u> for &$t { + type Output = <$t as $imp<$u>>::Output; + + #[inline] + fn $method(self, other: &$u) -> <$t as $imp<$u>>::Output { + $imp::$method(*self, *other) + } + } + }; (impl $imp:ident, $method:ident for $t:ty, $u:ty, #[$attr:meta]) => { #[$attr] impl<'a> $imp<$u> for &'a $t { @@ -55,7 +103,7 @@ macro_rules! forward_ref_binop { $imp::$method(*self, *other) } } - }; + } } // implements "T op= &U", based on "T op= U" @@ -65,6 +113,21 @@ macro_rules! forward_ref_op_assign { forward_ref_op_assign!(impl $imp, $method for $t, $u, #[stable(feature = "op_assign_builtins_by_ref", since = "1.22.0")]); }; + (impl const $imp:ident, $method:ident for $t:ty, $u:ty) => { + forward_ref_op_assign!(impl const $imp, $method for $t, $u, + #[stable(feature = "op_assign_builtins_by_ref", since = "1.22.0")]); + }; + // Equivalent to the non-const version, with the addition of `rustc_const_unstable` + (impl const $imp:ident, $method:ident for $t:ty, $u:ty, #[$attr:meta]) => { + #[$attr] + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const $imp<&$u> for $t { + #[inline] + fn $method(&mut self, other: &$u) { + $imp::$method(self, *other); + } + } + }; (impl $imp:ident, $method:ident for $t:ty, $u:ty, #[$attr:meta]) => { #[$attr] impl $imp<&$u> for $t { diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index ec5e37b4f5715..2895c923adc13 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -55,6 +55,7 @@ #![allow(missing_docs)] use crate::marker::{Destruct, DiscriminantKind}; +use crate::mem; // These imports are used for simplifying intra-doc links #[allow(unused_imports)] @@ -2310,11 +2311,43 @@ extern "rust-intrinsic" { /// /// So in a sense it is UB if this macro is useful, but we expect callers of `unsafe fn` to make /// the occasional mistake, and this check should help them figure things out. +#[allow_internal_unstable(const_eval_select)] // permit this to be called in stably-const fn macro_rules! assert_unsafe_precondition { - ($e:expr) => {{}}; + ($e:expr) => { + if cfg!(debug_assertions) { + // Use a closure so that we can capture arbitrary expressions from the invocation + let runtime = || { + if !$e { + // abort instead of panicking to reduce impact on code size + ::core::intrinsics::abort(); + } + }; + const fn comptime() {} + + ::core::intrinsics::const_eval_select((), comptime, runtime); + } + }; } pub(crate) use assert_unsafe_precondition; +/// Checks whether `ptr` is properly aligned with respect to +/// `align_of::()`. +pub(crate) fn is_aligned_and_not_null(ptr: *const T) -> bool { + !ptr.is_null() && ptr.addr() % mem::align_of::() == 0 +} + +/// Checks whether the regions of memory starting at `src` and `dst` of size +/// `count * size_of::()` do *not* overlap. +pub(crate) fn is_nonoverlapping(src: *const T, dst: *const T, count: usize) -> bool { + let src_usize = src.addr(); + let dst_usize = dst.addr(); + let size = mem::size_of::().checked_mul(count).unwrap(); + let diff = if src_usize > dst_usize { src_usize - dst_usize } else { dst_usize - src_usize }; + // If the absolute distance between the ptrs is at least as big as the size of the buffer, + // they do not overlap. + diff >= size +} + /// Copies `count * size_of::()` bytes from `src` to `dst`. The source /// and destination must *not* overlap. /// @@ -2678,8 +2711,5 @@ where F: ~const FnOnce, G: FnOnce + ~const Destruct, { - crate::mem::forget(_called_at_rt); - crate::mem::forget(arg); - crate::mem::forget(called_in_const); - panic!() + called_in_const.call_once(arg) } diff --git a/library/core/src/iter/sources/empty.rs b/library/core/src/iter/sources/empty.rs index a693e26374083..98734c527f2b9 100644 --- a/library/core/src/iter/sources/empty.rs +++ b/library/core/src/iter/sources/empty.rs @@ -86,7 +86,8 @@ impl Clone for Empty { // not #[derive] because that adds a Default bound on T, // which isn't necessary. #[stable(feature = "iter_empty", since = "1.2.0")] -impl Default for Empty { +#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] +impl const Default for Empty { fn default() -> Empty { Empty(marker::PhantomData) } diff --git a/library/core/src/iter/traits/collect.rs b/library/core/src/iter/traits/collect.rs index ceb40f8f05065..12ca508bed2b9 100644 --- a/library/core/src/iter/traits/collect.rs +++ b/library/core/src/iter/traits/collect.rs @@ -261,8 +261,9 @@ pub trait IntoIterator { fn into_iter(self) -> Self::IntoIter; } +#[rustc_const_unstable(feature = "const_intoiterator_identity", issue = "90603")] #[stable(feature = "rust1", since = "1.0.0")] -impl IntoIterator for I { +impl const IntoIterator for I { type Item = I::Item; type IntoIter = I; diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index edef4520f03be..f24a7ab61ae89 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -95,6 +95,7 @@ #![allow(explicit_outlives_requirements)] // // Library features: +#![feature(const_align_offset)] #![feature(const_align_of_val)] #![feature(const_arguments_as_str)] #![feature(const_array_into_iter_constructors)] @@ -105,10 +106,12 @@ #![feature(const_char_convert)] #![feature(const_clone)] #![feature(const_discriminant)] +#![feature(const_eval_select)] #![feature(const_float_bits_conv)] #![feature(const_float_classify)] #![feature(const_fmt_arguments_new)] #![feature(const_heap)] +#![feature(const_convert)] #![feature(const_inherent_unchecked_arith)] #![feature(const_int_unchecked_arith)] #![feature(const_intrinsic_forget)] @@ -117,8 +120,10 @@ #![feature(const_maybe_uninit_as_mut_ptr)] #![feature(const_maybe_uninit_assume_init)] #![feature(const_nonnull_new)] +#![feature(const_num_from_num)] #![feature(const_ops)] #![feature(const_option)] +#![feature(const_option_ext)] #![feature(const_pin)] #![feature(const_ptr_sub_ptr)] #![feature(const_replace)] @@ -136,6 +141,7 @@ #![feature(const_trait_impl)] #![feature(const_type_id)] #![feature(const_type_name)] +#![feature(const_default_impls)] #![feature(const_unsafecell_get_mut)] #![feature(core_panic)] #![feature(duration_consts_float)] @@ -148,6 +154,8 @@ #![feature(variant_count)] #![feature(const_array_from_ref)] #![feature(const_slice_from_ref)] +#![feature(const_slice_index)] +#![feature(const_is_char_boundary)] // // Language features: #![feature(abi_unadjusted)] diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index 96836c9e84d37..2c57897956fcd 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -525,7 +525,8 @@ macro_rules! impls { } #[stable(feature = "rust1", since = "1.0.0")] - impl Default for $t { + #[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] + impl const Default for $t { fn default() -> Self { Self } diff --git a/library/core/src/mem/manually_drop.rs b/library/core/src/mem/manually_drop.rs index 5f3d66e3773f1..3d719afe49e4a 100644 --- a/library/core/src/mem/manually_drop.rs +++ b/library/core/src/mem/manually_drop.rs @@ -146,7 +146,8 @@ impl ManuallyDrop { } #[stable(feature = "manually_drop", since = "1.20.0")] -impl Deref for ManuallyDrop { +#[rustc_const_unstable(feature = "const_deref", issue = "88955")] +impl const Deref for ManuallyDrop { type Target = T; #[inline(always)] fn deref(&self) -> &T { @@ -155,7 +156,8 @@ impl Deref for ManuallyDrop { } #[stable(feature = "manually_drop", since = "1.20.0")] -impl DerefMut for ManuallyDrop { +#[rustc_const_unstable(feature = "const_deref", issue = "88955")] +impl const DerefMut for ManuallyDrop { #[inline(always)] fn deref_mut(&mut self) -> &mut T { &mut self.value diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs index b64d8e28ae60e..b4ea536083392 100644 --- a/library/core/src/mem/maybe_uninit.rs +++ b/library/core/src/mem/maybe_uninit.rs @@ -957,7 +957,7 @@ impl MaybeUninit { (&array as *const _ as *const [T; N]).read() }; - // FIXME: required to avoid `Destruct` bound + // FIXME: required to avoid `~const Destruct` bound super::forget(array); ret } diff --git a/library/core/src/num/error.rs b/library/core/src/num/error.rs index 7c09ce2af09e2..1a223016dae0f 100644 --- a/library/core/src/num/error.rs +++ b/library/core/src/num/error.rs @@ -29,14 +29,15 @@ impl fmt::Display for TryFromIntError { } #[stable(feature = "try_from", since = "1.34.0")] -impl From for TryFromIntError { +#[rustc_const_unstable(feature = "const_convert", issue = "88674")] +impl const From for TryFromIntError { fn from(x: Infallible) -> TryFromIntError { match x {} } } #[unstable(feature = "never_type", issue = "35121")] -impl From for TryFromIntError { +impl const From for TryFromIntError { fn from(never: !) -> TryFromIntError { // Match rather than coerce to make sure that code like // `From for TryFromIntError` above will keep working diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs index 21b4824126188..6548ad2e514fb 100644 --- a/library/core/src/num/f32.rs +++ b/library/core/src/num/f32.rs @@ -614,6 +614,23 @@ impl f32 { } } + // This operates on bits, and only bits, so it can ignore concerns about weird FPUs. + // FIXME(jubilee): In a just world, this would be the entire impl for classify, + // plus a transmute. We do not live in a just world, but we can make it more so. + #[rustc_const_unstable(feature = "const_float_classify", issue = "72505")] + const fn classify_bits(b: u32) -> FpCategory { + const EXP_MASK: u32 = 0x7f800000; + const MAN_MASK: u32 = 0x007fffff; + + match (b & MAN_MASK, b & EXP_MASK) { + (0, EXP_MASK) => FpCategory::Infinite, + (_, EXP_MASK) => FpCategory::Nan, + (0, 0) => FpCategory::Zero, + (_, 0) => FpCategory::Subnormal, + _ => FpCategory::Normal, + } + } + /// Returns `true` if `self` has a positive sign, including `+0.0`, NaNs with /// positive sign bit and positive infinity. Note that IEEE-745 doesn't assign any /// meaning to the sign bit in case of a NaN, and as Rust doesn't guarantee that @@ -876,12 +893,52 @@ impl f32 { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[stable(feature = "float_bits_conv", since = "1.20.0")] + #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")] #[inline] - pub fn to_bits(self) -> u32 { + pub const fn to_bits(self) -> u32 { + // SAFETY: `u32` is a plain old datatype so we can always transmute to it. + // ...sorta. + // + // It turns out that at runtime, it is possible for a floating point number + // to be subject to a floating point mode that alters nonzero subnormal numbers + // to zero on reads and writes, aka "denormals are zero" and "flush to zero". + // This is not a problem per se, but at least one tier2 platform for Rust + // actually exhibits this behavior by default. + // + // In addition, on x86 targets with SSE or SSE2 disabled and the x87 FPU enabled, + // i.e. not soft-float, the way Rust does parameter passing can actually alter + // a number that is "not infinity" to have the same exponent as infinity, + // in a slightly unpredictable manner. + // + // And, of course evaluating to a NaN value is fairly nondeterministic. + // More precisely: when NaN should be returned is knowable, but which NaN? + // So far that's defined by a combination of LLVM and the CPU, not Rust. + // This function, however, allows observing the bitstring of a NaN, + // thus introspection on CTFE. + // + // In order to preserve, at least for the moment, const-to-runtime equivalence, + // we reject any of these possible situations from happening. + #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")] + const fn ct_f32_to_u32(ct: f32) -> u32 { + match ct.classify() { + FpCategory::Nan => { + panic!("const-eval error: cannot use f32::to_bits on a NaN") + } + FpCategory::Subnormal => { + panic!("const-eval error: cannot use f32::to_bits on a subnormal number") + } + FpCategory::Infinite | FpCategory::Normal | FpCategory::Zero => { + // SAFETY: We have a normal floating point number. Now we transmute, i.e. do a bitcopy. + unsafe { mem::transmute::(ct) } + } + } + } // SAFETY: `u32` is a plain old datatype so we can always... uh... // ...look, just pretend you forgot what you just read. // Stability concerns. - unsafe { mem::transmute::(self) } + let rt_f32_to_u32 = |rt| unsafe { mem::transmute::(rt) }; + // SAFETY: We use internal implementations that either always work or fail at compile time. + unsafe { intrinsics::const_eval_select((self,), ct_f32_to_u32, rt_f32_to_u32) } } /// Raw transmutation from `u32`. @@ -921,13 +978,55 @@ impl f32 { /// assert_eq!(v, 12.5); /// ``` #[stable(feature = "float_bits_conv", since = "1.20.0")] + #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")] #[must_use] #[inline] - pub fn from_bits(v: u32) -> Self { + pub const fn from_bits(v: u32) -> Self { + // It turns out the safety issues with sNaN were overblown! Hooray! + // SAFETY: `u32` is a plain old datatype so we can always transmute from it + // ...sorta. + // + // It turns out that at runtime, it is possible for a floating point number + // to be subject to floating point modes that alter nonzero subnormal numbers + // to zero on reads and writes, aka "denormals are zero" and "flush to zero". + // This is not a problem usually, but at least one tier2 platform for Rust + // actually exhibits this behavior by default: thumbv7neon + // aka "the Neon FPU in AArch32 state" + // + // In addition, on x86 targets with SSE or SSE2 disabled and the x87 FPU enabled, + // i.e. not soft-float, the way Rust does parameter passing can actually alter + // a number that is "not infinity" to have the same exponent as infinity, + // in a slightly unpredictable manner. + // + // And, of course evaluating to a NaN value is fairly nondeterministic. + // More precisely: when NaN should be returned is knowable, but which NaN? + // So far that's defined by a combination of LLVM and the CPU, not Rust. + // This function, however, allows observing the bitstring of a NaN, + // thus introspection on CTFE. + // + // In order to preserve, at least for the moment, const-to-runtime equivalence, + // reject any of these possible situations from happening. + #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")] + const fn ct_u32_to_f32(ct: u32) -> f32 { + match f32::classify_bits(ct) { + FpCategory::Subnormal => { + panic!("const-eval error: cannot use f32::from_bits on a subnormal number") + } + FpCategory::Nan => { + panic!("const-eval error: cannot use f32::from_bits on NaN") + } + FpCategory::Infinite | FpCategory::Normal | FpCategory::Zero => { + // SAFETY: It's not a frumious number + unsafe { mem::transmute::(ct) } + } + } + } // SAFETY: `u32` is a plain old datatype so we can always... uh... // ...look, just pretend you forgot what you just read. // Stability concerns. - unsafe { mem::transmute::(v) } + let rt_u32_to_f32 = |rt| unsafe { mem::transmute::(rt) }; + // SAFETY: We use internal implementations that either always work or fail at compile time. + unsafe { intrinsics::const_eval_select((v,), ct_u32_to_f32, rt_u32_to_f32) } } /// Return the memory representation of this floating point number as a byte array in @@ -945,8 +1044,9 @@ impl f32 { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[stable(feature = "float_to_from_bytes", since = "1.40.0")] + #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")] #[inline] - pub fn to_be_bytes(self) -> [u8; 4] { + pub const fn to_be_bytes(self) -> [u8; 4] { self.to_bits().to_be_bytes() } @@ -965,8 +1065,9 @@ impl f32 { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[stable(feature = "float_to_from_bytes", since = "1.40.0")] + #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")] #[inline] - pub fn to_le_bytes(self) -> [u8; 4] { + pub const fn to_le_bytes(self) -> [u8; 4] { self.to_bits().to_le_bytes() } @@ -998,8 +1099,9 @@ impl f32 { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[stable(feature = "float_to_from_bytes", since = "1.40.0")] + #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")] #[inline] - pub fn to_ne_bytes(self) -> [u8; 4] { + pub const fn to_ne_bytes(self) -> [u8; 4] { self.to_bits().to_ne_bytes() } @@ -1015,9 +1117,10 @@ impl f32 { /// assert_eq!(value, 12.5); /// ``` #[stable(feature = "float_to_from_bytes", since = "1.40.0")] + #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")] #[must_use] #[inline] - pub fn from_be_bytes(bytes: [u8; 4]) -> Self { + pub const fn from_be_bytes(bytes: [u8; 4]) -> Self { Self::from_bits(u32::from_be_bytes(bytes)) } @@ -1033,9 +1136,10 @@ impl f32 { /// assert_eq!(value, 12.5); /// ``` #[stable(feature = "float_to_from_bytes", since = "1.40.0")] + #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")] #[must_use] #[inline] - pub fn from_le_bytes(bytes: [u8; 4]) -> Self { + pub const fn from_le_bytes(bytes: [u8; 4]) -> Self { Self::from_bits(u32::from_le_bytes(bytes)) } @@ -1062,9 +1166,10 @@ impl f32 { /// assert_eq!(value, 12.5); /// ``` #[stable(feature = "float_to_from_bytes", since = "1.40.0")] + #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")] #[must_use] #[inline] - pub fn from_ne_bytes(bytes: [u8; 4]) -> Self { + pub const fn from_ne_bytes(bytes: [u8; 4]) -> Self { Self::from_bits(u32::from_ne_bytes(bytes)) } diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs index 85550ff59400c..75c92c2f8834a 100644 --- a/library/core/src/num/f64.rs +++ b/library/core/src/num/f64.rs @@ -606,6 +606,23 @@ impl f64 { } } + // This operates on bits, and only bits, so it can ignore concerns about weird FPUs. + // FIXME(jubilee): In a just world, this would be the entire impl for classify, + // plus a transmute. We do not live in a just world, but we can make it more so. + #[rustc_const_unstable(feature = "const_float_classify", issue = "72505")] + const fn classify_bits(b: u64) -> FpCategory { + const EXP_MASK: u64 = 0x7ff0000000000000; + const MAN_MASK: u64 = 0x000fffffffffffff; + + match (b & MAN_MASK, b & EXP_MASK) { + (0, EXP_MASK) => FpCategory::Infinite, + (_, EXP_MASK) => FpCategory::Nan, + (0, 0) => FpCategory::Zero, + (_, 0) => FpCategory::Subnormal, + _ => FpCategory::Normal, + } + } + /// Returns `true` if `self` has a positive sign, including `+0.0`, NaNs with /// positive sign bit and positive infinity. Note that IEEE-745 doesn't assign any /// meaning to the sign bit in case of a NaN, and as Rust doesn't guarantee that @@ -890,10 +907,31 @@ impl f64 { #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")] #[inline] pub const fn to_bits(self) -> u64 { + // SAFETY: `u64` is a plain old datatype so we can always transmute to it. + // ...sorta. + // + // See the SAFETY comment in f64::from_bits for more. + #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")] + const fn ct_f64_to_u64(ct: f64) -> u64 { + match ct.classify() { + FpCategory::Nan => { + panic!("const-eval error: cannot use f64::to_bits on a NaN") + } + FpCategory::Subnormal => { + panic!("const-eval error: cannot use f64::to_bits on a subnormal number") + } + FpCategory::Infinite | FpCategory::Normal | FpCategory::Zero => { + // SAFETY: We have a normal floating point number. Now we transmute, i.e. do a bitcopy. + unsafe { mem::transmute::(ct) } + } + } + } // SAFETY: `u64` is a plain old datatype so we can always... uh... // ...look, just pretend you forgot what you just read. // Stability concerns. - unsafe { mem::transmute::(self) } + let rt_f64_to_u64 = |rt| unsafe { mem::transmute::(rt) }; + // SAFETY: We use internal implementations that either always work or fail at compile time. + unsafe { intrinsics::const_eval_select((self,), ct_f64_to_u64, rt_f64_to_u64) } } /// Raw transmutation from `u64`. @@ -937,10 +975,56 @@ impl f64 { #[must_use] #[inline] pub const fn from_bits(v: u64) -> Self { + // It turns out the safety issues with sNaN were overblown! Hooray! + // SAFETY: `u64` is a plain old datatype so we can always transmute from it + // ...sorta. + // + // It turns out that at runtime, it is possible for a floating point number + // to be subject to floating point modes that alter nonzero subnormal numbers + // to zero on reads and writes, aka "denormals are zero" and "flush to zero". + // This is not a problem usually, but at least one tier2 platform for Rust + // actually exhibits an FTZ behavior by default: thumbv7neon + // aka "the Neon FPU in AArch32 state" + // + // Even with this, not all instructions exhibit the FTZ behaviors on thumbv7neon, + // so this should load the same bits if LLVM emits the "correct" instructions, + // but LLVM sometimes makes interesting choices about float optimization, + // and other FPUs may do similar. Thus, it is wise to indulge luxuriously in caution. + // + // In addition, on x86 targets with SSE or SSE2 disabled and the x87 FPU enabled, + // i.e. not soft-float, the way Rust does parameter passing can actually alter + // a number that is "not infinity" to have the same exponent as infinity, + // in a slightly unpredictable manner. + // + // And, of course evaluating to a NaN value is fairly nondeterministic. + // More precisely: when NaN should be returned is knowable, but which NaN? + // So far that's defined by a combination of LLVM and the CPU, not Rust. + // This function, however, allows observing the bitstring of a NaN, + // thus introspection on CTFE. + // + // In order to preserve, at least for the moment, const-to-runtime equivalence, + // reject any of these possible situations from happening. + #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")] + const fn ct_u64_to_f64(ct: u64) -> f64 { + match f64::classify_bits(ct) { + FpCategory::Subnormal => { + panic!("const-eval error: cannot use f64::from_bits on a subnormal number") + } + FpCategory::Nan => { + panic!("const-eval error: cannot use f64::from_bits on NaN") + } + FpCategory::Infinite | FpCategory::Normal | FpCategory::Zero => { + // SAFETY: It's not a frumious number + unsafe { mem::transmute::(ct) } + } + } + } // SAFETY: `u64` is a plain old datatype so we can always... uh... // ...look, just pretend you forgot what you just read. // Stability concerns. - unsafe { mem::transmute::(v) } + let rt_u64_to_f64 = |rt| unsafe { mem::transmute::(rt) }; + // SAFETY: We use internal implementations that either always work or fail at compile time. + unsafe { intrinsics::const_eval_select((v,), ct_u64_to_f64, rt_u64_to_f64) } } /// Return the memory representation of this floating point number as a byte array in diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs index dbc7a8e9acb3a..92d03b724b40e 100644 --- a/library/core/src/num/nonzero.rs +++ b/library/core/src/num/nonzero.rs @@ -85,7 +85,8 @@ macro_rules! nonzero_integers { } #[stable(feature = "from_nonzero", since = "1.31.0")] - impl From<$Ty> for $Int { + #[rustc_const_unstable(feature = "const_num_from_num", issue = "87852")] + impl const From<$Ty> for $Int { #[doc = concat!("Converts a `", stringify!($Ty), "` into an `", stringify!($Int), "`")] #[inline] fn from(nonzero: $Ty) -> Self { @@ -94,7 +95,8 @@ macro_rules! nonzero_integers { } #[stable(feature = "nonzero_bitor", since = "1.45.0")] - impl BitOr for $Ty { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const BitOr for $Ty { type Output = Self; #[inline] fn bitor(self, rhs: Self) -> Self::Output { @@ -105,7 +107,8 @@ macro_rules! nonzero_integers { } #[stable(feature = "nonzero_bitor", since = "1.45.0")] - impl BitOr<$Int> for $Ty { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const BitOr<$Int> for $Ty { type Output = Self; #[inline] fn bitor(self, rhs: $Int) -> Self::Output { @@ -117,7 +120,8 @@ macro_rules! nonzero_integers { } #[stable(feature = "nonzero_bitor", since = "1.45.0")] - impl BitOr<$Ty> for $Int { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const BitOr<$Ty> for $Int { type Output = $Ty; #[inline] fn bitor(self, rhs: $Ty) -> Self::Output { @@ -129,7 +133,8 @@ macro_rules! nonzero_integers { } #[stable(feature = "nonzero_bitor", since = "1.45.0")] - impl BitOrAssign for $Ty { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const BitOrAssign for $Ty { #[inline] fn bitor_assign(&mut self, rhs: Self) { *self = *self | rhs; @@ -137,7 +142,8 @@ macro_rules! nonzero_integers { } #[stable(feature = "nonzero_bitor", since = "1.45.0")] - impl BitOrAssign<$Int> for $Ty { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const BitOrAssign<$Int> for $Ty { #[inline] fn bitor_assign(&mut self, rhs: $Int) { *self = *self | rhs; @@ -259,7 +265,8 @@ macro_rules! nonzero_integers_div { ( $( $Ty: ident($Int: ty); )+ ) => { $( #[stable(feature = "nonzero_div", since = "1.51.0")] - impl Div<$Ty> for $Int { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const Div<$Ty> for $Int { type Output = $Int; /// This operation rounds towards zero, /// truncating any fractional part of the exact result, and cannot panic. @@ -272,7 +279,8 @@ macro_rules! nonzero_integers_div { } #[stable(feature = "nonzero_div", since = "1.51.0")] - impl Rem<$Ty> for $Int { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const Rem<$Ty> for $Int { type Output = $Int; /// This operation satisfies `n % d == n - (n / d) * d`, and cannot panic. #[inline] diff --git a/library/core/src/num/wrapping.rs b/library/core/src/num/wrapping.rs index ed354a2e50bda..5353d900e7662 100644 --- a/library/core/src/num/wrapping.rs +++ b/library/core/src/num/wrapping.rs @@ -87,7 +87,8 @@ impl fmt::UpperHex for Wrapping { macro_rules! sh_impl_signed { ($t:ident, $f:ident) => { #[stable(feature = "rust1", since = "1.0.0")] - impl Shl<$f> for Wrapping<$t> { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const Shl<$f> for Wrapping<$t> { type Output = Wrapping<$t>; #[inline] @@ -99,20 +100,22 @@ macro_rules! sh_impl_signed { } } } - forward_ref_binop! { impl Shl, shl for Wrapping<$t>, $f, + forward_ref_binop! { impl const Shl, shl for Wrapping<$t>, $f, #[stable(feature = "wrapping_ref_ops", since = "1.39.0")] } #[stable(feature = "op_assign_traits", since = "1.8.0")] - impl ShlAssign<$f> for Wrapping<$t> { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const ShlAssign<$f> for Wrapping<$t> { #[inline] fn shl_assign(&mut self, other: $f) { *self = *self << other; } } - forward_ref_op_assign! { impl ShlAssign, shl_assign for Wrapping<$t>, $f } + forward_ref_op_assign! { impl const ShlAssign, shl_assign for Wrapping<$t>, $f } #[stable(feature = "rust1", since = "1.0.0")] - impl Shr<$f> for Wrapping<$t> { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const Shr<$f> for Wrapping<$t> { type Output = Wrapping<$t>; #[inline] @@ -124,24 +127,26 @@ macro_rules! sh_impl_signed { } } } - forward_ref_binop! { impl Shr, shr for Wrapping<$t>, $f, + forward_ref_binop! { impl const Shr, shr for Wrapping<$t>, $f, #[stable(feature = "wrapping_ref_ops", since = "1.39.0")] } #[stable(feature = "op_assign_traits", since = "1.8.0")] - impl ShrAssign<$f> for Wrapping<$t> { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const ShrAssign<$f> for Wrapping<$t> { #[inline] fn shr_assign(&mut self, other: $f) { *self = *self >> other; } } - forward_ref_op_assign! { impl ShrAssign, shr_assign for Wrapping<$t>, $f } + forward_ref_op_assign! { impl const ShrAssign, shr_assign for Wrapping<$t>, $f } }; } macro_rules! sh_impl_unsigned { ($t:ident, $f:ident) => { #[stable(feature = "rust1", since = "1.0.0")] - impl Shl<$f> for Wrapping<$t> { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const Shl<$f> for Wrapping<$t> { type Output = Wrapping<$t>; #[inline] @@ -149,20 +154,22 @@ macro_rules! sh_impl_unsigned { Wrapping(self.0.wrapping_shl((other & self::shift_max::$t as $f) as u32)) } } - forward_ref_binop! { impl Shl, shl for Wrapping<$t>, $f, + forward_ref_binop! { impl const Shl, shl for Wrapping<$t>, $f, #[stable(feature = "wrapping_ref_ops", since = "1.39.0")] } #[stable(feature = "op_assign_traits", since = "1.8.0")] - impl ShlAssign<$f> for Wrapping<$t> { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const ShlAssign<$f> for Wrapping<$t> { #[inline] fn shl_assign(&mut self, other: $f) { *self = *self << other; } } - forward_ref_op_assign! { impl ShlAssign, shl_assign for Wrapping<$t>, $f } + forward_ref_op_assign! { impl const ShlAssign, shl_assign for Wrapping<$t>, $f } #[stable(feature = "rust1", since = "1.0.0")] - impl Shr<$f> for Wrapping<$t> { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const Shr<$f> for Wrapping<$t> { type Output = Wrapping<$t>; #[inline] @@ -170,17 +177,18 @@ macro_rules! sh_impl_unsigned { Wrapping(self.0.wrapping_shr((other & self::shift_max::$t as $f) as u32)) } } - forward_ref_binop! { impl Shr, shr for Wrapping<$t>, $f, + forward_ref_binop! { impl const Shr, shr for Wrapping<$t>, $f, #[stable(feature = "wrapping_ref_ops", since = "1.39.0")] } #[stable(feature = "op_assign_traits", since = "1.8.0")] - impl ShrAssign<$f> for Wrapping<$t> { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const ShrAssign<$f> for Wrapping<$t> { #[inline] fn shr_assign(&mut self, other: $f) { *self = *self >> other; } } - forward_ref_op_assign! { impl ShrAssign, shr_assign for Wrapping<$t>, $f } + forward_ref_op_assign! { impl const ShrAssign, shr_assign for Wrapping<$t>, $f } }; } @@ -209,7 +217,8 @@ sh_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize } macro_rules! wrapping_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - impl Add for Wrapping<$t> { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const Add for Wrapping<$t> { type Output = Wrapping<$t>; #[inline] @@ -217,29 +226,32 @@ macro_rules! wrapping_impl { Wrapping(self.0.wrapping_add(other.0)) } } - forward_ref_binop! { impl Add, add for Wrapping<$t>, Wrapping<$t>, + forward_ref_binop! { impl const Add, add for Wrapping<$t>, Wrapping<$t>, #[stable(feature = "wrapping_ref", since = "1.14.0")] } #[stable(feature = "op_assign_traits", since = "1.8.0")] - impl AddAssign for Wrapping<$t> { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const AddAssign for Wrapping<$t> { #[inline] fn add_assign(&mut self, other: Wrapping<$t>) { *self = *self + other; } } - forward_ref_op_assign! { impl AddAssign, add_assign for Wrapping<$t>, Wrapping<$t> } + forward_ref_op_assign! { impl const AddAssign, add_assign for Wrapping<$t>, Wrapping<$t> } #[stable(feature = "wrapping_int_assign_impl", since = "1.60.0")] - impl AddAssign<$t> for Wrapping<$t> { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const AddAssign<$t> for Wrapping<$t> { #[inline] fn add_assign(&mut self, other: $t) { *self = *self + Wrapping(other); } } - forward_ref_op_assign! { impl AddAssign, add_assign for Wrapping<$t>, $t } + forward_ref_op_assign! { impl const AddAssign, add_assign for Wrapping<$t>, $t } #[stable(feature = "rust1", since = "1.0.0")] - impl Sub for Wrapping<$t> { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const Sub for Wrapping<$t> { type Output = Wrapping<$t>; #[inline] @@ -247,29 +259,32 @@ macro_rules! wrapping_impl { Wrapping(self.0.wrapping_sub(other.0)) } } - forward_ref_binop! { impl Sub, sub for Wrapping<$t>, Wrapping<$t>, + forward_ref_binop! { impl const Sub, sub for Wrapping<$t>, Wrapping<$t>, #[stable(feature = "wrapping_ref", since = "1.14.0")] } #[stable(feature = "op_assign_traits", since = "1.8.0")] - impl SubAssign for Wrapping<$t> { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const SubAssign for Wrapping<$t> { #[inline] fn sub_assign(&mut self, other: Wrapping<$t>) { *self = *self - other; } } - forward_ref_op_assign! { impl SubAssign, sub_assign for Wrapping<$t>, Wrapping<$t> } + forward_ref_op_assign! { impl const SubAssign, sub_assign for Wrapping<$t>, Wrapping<$t> } #[stable(feature = "wrapping_int_assign_impl", since = "1.60.0")] - impl SubAssign<$t> for Wrapping<$t> { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const SubAssign<$t> for Wrapping<$t> { #[inline] fn sub_assign(&mut self, other: $t) { *self = *self - Wrapping(other); } } - forward_ref_op_assign! { impl SubAssign, sub_assign for Wrapping<$t>, $t } + forward_ref_op_assign! { impl const SubAssign, sub_assign for Wrapping<$t>, $t } #[stable(feature = "rust1", since = "1.0.0")] - impl Mul for Wrapping<$t> { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const Mul for Wrapping<$t> { type Output = Wrapping<$t>; #[inline] @@ -281,25 +296,28 @@ macro_rules! wrapping_impl { #[stable(feature = "wrapping_ref", since = "1.14.0")] } #[stable(feature = "op_assign_traits", since = "1.8.0")] - impl MulAssign for Wrapping<$t> { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const MulAssign for Wrapping<$t> { #[inline] fn mul_assign(&mut self, other: Wrapping<$t>) { *self = *self * other; } } - forward_ref_op_assign! { impl MulAssign, mul_assign for Wrapping<$t>, Wrapping<$t> } + forward_ref_op_assign! { impl const MulAssign, mul_assign for Wrapping<$t>, Wrapping<$t> } #[stable(feature = "wrapping_int_assign_impl", since = "1.60.0")] - impl MulAssign<$t> for Wrapping<$t> { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const MulAssign<$t> for Wrapping<$t> { #[inline] fn mul_assign(&mut self, other: $t) { *self = *self * Wrapping(other); } } - forward_ref_op_assign! { impl MulAssign, mul_assign for Wrapping<$t>, $t } + forward_ref_op_assign! { impl const MulAssign, mul_assign for Wrapping<$t>, $t } #[stable(feature = "wrapping_div", since = "1.3.0")] - impl Div for Wrapping<$t> { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const Div for Wrapping<$t> { type Output = Wrapping<$t>; #[inline] @@ -307,29 +325,32 @@ macro_rules! wrapping_impl { Wrapping(self.0.wrapping_div(other.0)) } } - forward_ref_binop! { impl Div, div for Wrapping<$t>, Wrapping<$t>, + forward_ref_binop! { impl const Div, div for Wrapping<$t>, Wrapping<$t>, #[stable(feature = "wrapping_ref", since = "1.14.0")] } #[stable(feature = "op_assign_traits", since = "1.8.0")] - impl DivAssign for Wrapping<$t> { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const DivAssign for Wrapping<$t> { #[inline] fn div_assign(&mut self, other: Wrapping<$t>) { *self = *self / other; } } - forward_ref_op_assign! { impl DivAssign, div_assign for Wrapping<$t>, Wrapping<$t> } + forward_ref_op_assign! { impl const DivAssign, div_assign for Wrapping<$t>, Wrapping<$t> } #[stable(feature = "wrapping_int_assign_impl", since = "1.60.0")] - impl DivAssign<$t> for Wrapping<$t> { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const DivAssign<$t> for Wrapping<$t> { #[inline] fn div_assign(&mut self, other: $t) { *self = *self / Wrapping(other); } } - forward_ref_op_assign! { impl DivAssign, div_assign for Wrapping<$t>, $t } + forward_ref_op_assign! { impl const DivAssign, div_assign for Wrapping<$t>, $t } #[stable(feature = "wrapping_impls", since = "1.7.0")] - impl Rem for Wrapping<$t> { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const Rem for Wrapping<$t> { type Output = Wrapping<$t>; #[inline] @@ -337,29 +358,32 @@ macro_rules! wrapping_impl { Wrapping(self.0.wrapping_rem(other.0)) } } - forward_ref_binop! { impl Rem, rem for Wrapping<$t>, Wrapping<$t>, + forward_ref_binop! { impl const Rem, rem for Wrapping<$t>, Wrapping<$t>, #[stable(feature = "wrapping_ref", since = "1.14.0")] } #[stable(feature = "op_assign_traits", since = "1.8.0")] - impl RemAssign for Wrapping<$t> { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const RemAssign for Wrapping<$t> { #[inline] fn rem_assign(&mut self, other: Wrapping<$t>) { *self = *self % other; } } - forward_ref_op_assign! { impl RemAssign, rem_assign for Wrapping<$t>, Wrapping<$t> } + forward_ref_op_assign! { impl const RemAssign, rem_assign for Wrapping<$t>, Wrapping<$t> } #[stable(feature = "wrapping_int_assign_impl", since = "1.60.0")] - impl RemAssign<$t> for Wrapping<$t> { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const RemAssign<$t> for Wrapping<$t> { #[inline] fn rem_assign(&mut self, other: $t) { *self = *self % Wrapping(other); } } - forward_ref_op_assign! { impl RemAssign, rem_assign for Wrapping<$t>, $t } + forward_ref_op_assign! { impl const RemAssign, rem_assign for Wrapping<$t>, $t } #[stable(feature = "rust1", since = "1.0.0")] - impl Not for Wrapping<$t> { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const Not for Wrapping<$t> { type Output = Wrapping<$t>; #[inline] @@ -367,11 +391,12 @@ macro_rules! wrapping_impl { Wrapping(!self.0) } } - forward_ref_unop! { impl Not, not for Wrapping<$t>, + forward_ref_unop! { impl const Not, not for Wrapping<$t>, #[stable(feature = "wrapping_ref", since = "1.14.0")] } #[stable(feature = "rust1", since = "1.0.0")] - impl BitXor for Wrapping<$t> { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const BitXor for Wrapping<$t> { type Output = Wrapping<$t>; #[inline] @@ -379,29 +404,32 @@ macro_rules! wrapping_impl { Wrapping(self.0 ^ other.0) } } - forward_ref_binop! { impl BitXor, bitxor for Wrapping<$t>, Wrapping<$t>, + forward_ref_binop! { impl const BitXor, bitxor for Wrapping<$t>, Wrapping<$t>, #[stable(feature = "wrapping_ref", since = "1.14.0")] } #[stable(feature = "op_assign_traits", since = "1.8.0")] - impl BitXorAssign for Wrapping<$t> { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const BitXorAssign for Wrapping<$t> { #[inline] fn bitxor_assign(&mut self, other: Wrapping<$t>) { *self = *self ^ other; } } - forward_ref_op_assign! { impl BitXorAssign, bitxor_assign for Wrapping<$t>, Wrapping<$t> } + forward_ref_op_assign! { impl const BitXorAssign, bitxor_assign for Wrapping<$t>, Wrapping<$t> } #[stable(feature = "wrapping_int_assign_impl", since = "1.60.0")] - impl BitXorAssign<$t> for Wrapping<$t> { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const BitXorAssign<$t> for Wrapping<$t> { #[inline] fn bitxor_assign(&mut self, other: $t) { *self = *self ^ Wrapping(other); } } - forward_ref_op_assign! { impl BitXorAssign, bitxor_assign for Wrapping<$t>, $t } + forward_ref_op_assign! { impl const BitXorAssign, bitxor_assign for Wrapping<$t>, $t } #[stable(feature = "rust1", since = "1.0.0")] - impl BitOr for Wrapping<$t> { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const BitOr for Wrapping<$t> { type Output = Wrapping<$t>; #[inline] @@ -409,29 +437,32 @@ macro_rules! wrapping_impl { Wrapping(self.0 | other.0) } } - forward_ref_binop! { impl BitOr, bitor for Wrapping<$t>, Wrapping<$t>, + forward_ref_binop! { impl const BitOr, bitor for Wrapping<$t>, Wrapping<$t>, #[stable(feature = "wrapping_ref", since = "1.14.0")] } #[stable(feature = "op_assign_traits", since = "1.8.0")] - impl BitOrAssign for Wrapping<$t> { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const BitOrAssign for Wrapping<$t> { #[inline] fn bitor_assign(&mut self, other: Wrapping<$t>) { *self = *self | other; } } - forward_ref_op_assign! { impl BitOrAssign, bitor_assign for Wrapping<$t>, Wrapping<$t> } + forward_ref_op_assign! { impl const BitOrAssign, bitor_assign for Wrapping<$t>, Wrapping<$t> } #[stable(feature = "wrapping_int_assign_impl", since = "1.60.0")] - impl BitOrAssign<$t> for Wrapping<$t> { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const BitOrAssign<$t> for Wrapping<$t> { #[inline] fn bitor_assign(&mut self, other: $t) { *self = *self | Wrapping(other); } } - forward_ref_op_assign! { impl BitOrAssign, bitor_assign for Wrapping<$t>, $t } + forward_ref_op_assign! { impl const BitOrAssign, bitor_assign for Wrapping<$t>, $t } #[stable(feature = "rust1", since = "1.0.0")] - impl BitAnd for Wrapping<$t> { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const BitAnd for Wrapping<$t> { type Output = Wrapping<$t>; #[inline] @@ -439,36 +470,39 @@ macro_rules! wrapping_impl { Wrapping(self.0 & other.0) } } - forward_ref_binop! { impl BitAnd, bitand for Wrapping<$t>, Wrapping<$t>, + forward_ref_binop! { impl const BitAnd, bitand for Wrapping<$t>, Wrapping<$t>, #[stable(feature = "wrapping_ref", since = "1.14.0")] } #[stable(feature = "op_assign_traits", since = "1.8.0")] - impl BitAndAssign for Wrapping<$t> { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const BitAndAssign for Wrapping<$t> { #[inline] fn bitand_assign(&mut self, other: Wrapping<$t>) { *self = *self & other; } } - forward_ref_op_assign! { impl BitAndAssign, bitand_assign for Wrapping<$t>, Wrapping<$t> } + forward_ref_op_assign! { impl const BitAndAssign, bitand_assign for Wrapping<$t>, Wrapping<$t> } #[stable(feature = "wrapping_int_assign_impl", since = "1.60.0")] - impl BitAndAssign<$t> for Wrapping<$t> { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const BitAndAssign<$t> for Wrapping<$t> { #[inline] fn bitand_assign(&mut self, other: $t) { *self = *self & Wrapping(other); } } - forward_ref_op_assign! { impl BitAndAssign, bitand_assign for Wrapping<$t>, $t } + forward_ref_op_assign! { impl const BitAndAssign, bitand_assign for Wrapping<$t>, $t } #[stable(feature = "wrapping_neg", since = "1.10.0")] - impl Neg for Wrapping<$t> { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const Neg for Wrapping<$t> { type Output = Self; #[inline] fn neg(self) -> Self { Wrapping(0) - self } } - forward_ref_unop! { impl Neg, neg for Wrapping<$t>, + forward_ref_unop! { impl const Neg, neg for Wrapping<$t>, #[stable(feature = "wrapping_ref", since = "1.14.0")] } )*) diff --git a/library/core/src/ops/arith.rs b/library/core/src/ops/arith.rs index 134c6db140258..e367be8c167c7 100644 --- a/library/core/src/ops/arith.rs +++ b/library/core/src/ops/arith.rs @@ -117,7 +117,8 @@ pub trait Add { macro_rules! add_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - impl Add for $t { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const Add for $t { type Output = $t; #[inline] @@ -125,7 +126,7 @@ macro_rules! add_impl { fn add(self, other: $t) -> $t { self + other } } - forward_ref_binop! { impl Add, add for $t, $t } + forward_ref_binop! { impl const Add, add for $t, $t } )*) } @@ -223,7 +224,8 @@ pub trait Sub { macro_rules! sub_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - impl Sub for $t { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const Sub for $t { type Output = $t; #[inline] @@ -231,7 +233,7 @@ macro_rules! sub_impl { fn sub(self, other: $t) -> $t { self - other } } - forward_ref_binop! { impl Sub, sub for $t, $t } + forward_ref_binop! { impl const Sub, sub for $t, $t } )*) } @@ -351,7 +353,8 @@ pub trait Mul { macro_rules! mul_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - impl Mul for $t { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const Mul for $t { type Output = $t; #[inline] @@ -359,7 +362,7 @@ macro_rules! mul_impl { fn mul(self, other: $t) -> $t { self * other } } - forward_ref_binop! { impl Mul, mul for $t, $t } + forward_ref_binop! { impl const Mul, mul for $t, $t } )*) } @@ -489,14 +492,15 @@ macro_rules! div_impl_integer { /// #[doc = $panic] #[stable(feature = "rust1", since = "1.0.0")] - impl Div for $t { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const Div for $t { type Output = $t; #[inline] fn div(self, other: $t) -> $t { self / other } } - forward_ref_binop! { impl Div, div for $t, $t } + forward_ref_binop! { impl const Div, div for $t, $t } )*)*) } @@ -508,14 +512,15 @@ div_impl_integer! { macro_rules! div_impl_float { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - impl Div for $t { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const Div for $t { type Output = $t; #[inline] fn div(self, other: $t) -> $t { self / other } } - forward_ref_binop! { impl Div, div for $t, $t } + forward_ref_binop! { impl const Div, div for $t, $t } )*) } @@ -589,14 +594,15 @@ macro_rules! rem_impl_integer { /// #[doc = $panic] #[stable(feature = "rust1", since = "1.0.0")] - impl Rem for $t { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const Rem for $t { type Output = $t; #[inline] fn rem(self, other: $t) -> $t { self % other } } - forward_ref_binop! { impl Rem, rem for $t, $t } + forward_ref_binop! { impl const Rem, rem for $t, $t } )*)*) } @@ -623,14 +629,15 @@ macro_rules! rem_impl_float { /// assert_eq!(x % y, remainder); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - impl Rem for $t { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const Rem for $t { type Output = $t; #[inline] fn rem(self, other: $t) -> $t { self % other } } - forward_ref_binop! { impl Rem, rem for $t, $t } + forward_ref_binop! { impl const Rem, rem for $t, $t } )*) } @@ -696,7 +703,8 @@ pub trait Neg { macro_rules! neg_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - impl Neg for $t { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const Neg for $t { type Output = $t; #[inline] @@ -704,7 +712,7 @@ macro_rules! neg_impl { fn neg(self) -> $t { -self } } - forward_ref_unop! { impl Neg, neg for $t } + forward_ref_unop! { impl const Neg, neg for $t } )*) } @@ -764,13 +772,14 @@ pub trait AddAssign { macro_rules! add_assign_impl { ($($t:ty)+) => ($( #[stable(feature = "op_assign_traits", since = "1.8.0")] - impl AddAssign for $t { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const AddAssign for $t { #[inline] #[rustc_inherit_overflow_checks] fn add_assign(&mut self, other: $t) { *self += other } } - forward_ref_op_assign! { impl AddAssign, add_assign for $t, $t } + forward_ref_op_assign! { impl const AddAssign, add_assign for $t, $t } )+) } @@ -830,13 +839,14 @@ pub trait SubAssign { macro_rules! sub_assign_impl { ($($t:ty)+) => ($( #[stable(feature = "op_assign_traits", since = "1.8.0")] - impl SubAssign for $t { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const SubAssign for $t { #[inline] #[rustc_inherit_overflow_checks] fn sub_assign(&mut self, other: $t) { *self -= other } } - forward_ref_op_assign! { impl SubAssign, sub_assign for $t, $t } + forward_ref_op_assign! { impl const SubAssign, sub_assign for $t, $t } )+) } @@ -887,13 +897,14 @@ pub trait MulAssign { macro_rules! mul_assign_impl { ($($t:ty)+) => ($( #[stable(feature = "op_assign_traits", since = "1.8.0")] - impl MulAssign for $t { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const MulAssign for $t { #[inline] #[rustc_inherit_overflow_checks] fn mul_assign(&mut self, other: $t) { *self *= other } } - forward_ref_op_assign! { impl MulAssign, mul_assign for $t, $t } + forward_ref_op_assign! { impl const MulAssign, mul_assign for $t, $t } )+) } @@ -944,12 +955,13 @@ pub trait DivAssign { macro_rules! div_assign_impl { ($($t:ty)+) => ($( #[stable(feature = "op_assign_traits", since = "1.8.0")] - impl DivAssign for $t { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const DivAssign for $t { #[inline] fn div_assign(&mut self, other: $t) { *self /= other } } - forward_ref_op_assign! { impl DivAssign, div_assign for $t, $t } + forward_ref_op_assign! { impl const DivAssign, div_assign for $t, $t } )+) } @@ -1004,12 +1016,13 @@ pub trait RemAssign { macro_rules! rem_assign_impl { ($($t:ty)+) => ($( #[stable(feature = "op_assign_traits", since = "1.8.0")] - impl RemAssign for $t { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const RemAssign for $t { #[inline] fn rem_assign(&mut self, other: $t) { *self %= other } } - forward_ref_op_assign! { impl RemAssign, rem_assign for $t, $t } + forward_ref_op_assign! { impl const RemAssign, rem_assign for $t, $t } )+) } diff --git a/library/core/src/ops/bit.rs b/library/core/src/ops/bit.rs index 05e309c81b42d..7c664226fc256 100644 --- a/library/core/src/ops/bit.rs +++ b/library/core/src/ops/bit.rs @@ -54,14 +54,15 @@ pub trait Not { macro_rules! not_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - impl Not for $t { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const Not for $t { type Output = $t; #[inline] fn not(self) -> $t { !self } } - forward_ref_unop! { impl Not, not for $t } + forward_ref_unop! { impl const Not, not for $t } )*) } @@ -69,7 +70,7 @@ not_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } #[stable(feature = "not_never", since = "1.60.0")] #[rustc_const_unstable(feature = "const_ops", issue = "90080")] -impl Not for ! { +impl const Not for ! { type Output = !; #[inline] @@ -165,14 +166,15 @@ pub trait BitAnd { macro_rules! bitand_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - impl BitAnd for $t { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const BitAnd for $t { type Output = $t; #[inline] fn bitand(self, rhs: $t) -> $t { self & rhs } } - forward_ref_binop! { impl BitAnd, bitand for $t, $t } + forward_ref_binop! { impl const BitAnd, bitand for $t, $t } )*) } @@ -265,14 +267,15 @@ pub trait BitOr { macro_rules! bitor_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - impl BitOr for $t { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const BitOr for $t { type Output = $t; #[inline] fn bitor(self, rhs: $t) -> $t { self | rhs } } - forward_ref_binop! { impl BitOr, bitor for $t, $t } + forward_ref_binop! { impl const BitOr, bitor for $t, $t } )*) } @@ -365,14 +368,15 @@ pub trait BitXor { macro_rules! bitxor_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - impl BitXor for $t { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const BitXor for $t { type Output = $t; #[inline] fn bitxor(self, other: $t) -> $t { self ^ other } } - forward_ref_binop! { impl BitXor, bitxor for $t, $t } + forward_ref_binop! { impl const BitXor, bitxor for $t, $t } )*) } @@ -462,7 +466,8 @@ pub trait Shl { macro_rules! shl_impl { ($t:ty, $f:ty) => { #[stable(feature = "rust1", since = "1.0.0")] - impl Shl<$f> for $t { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const Shl<$f> for $t { type Output = $t; #[inline] @@ -472,7 +477,7 @@ macro_rules! shl_impl { } } - forward_ref_binop! { impl Shl, shl for $t, $f } + forward_ref_binop! { impl const Shl, shl for $t, $f } }; } @@ -580,7 +585,8 @@ pub trait Shr { macro_rules! shr_impl { ($t:ty, $f:ty) => { #[stable(feature = "rust1", since = "1.0.0")] - impl Shr<$f> for $t { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const Shr<$f> for $t { type Output = $t; #[inline] @@ -590,7 +596,7 @@ macro_rules! shr_impl { } } - forward_ref_binop! { impl Shr, shr for $t, $f } + forward_ref_binop! { impl const Shr, shr for $t, $f } }; } @@ -715,12 +721,13 @@ pub trait BitAndAssign { macro_rules! bitand_assign_impl { ($($t:ty)+) => ($( #[stable(feature = "op_assign_traits", since = "1.8.0")] - impl BitAndAssign for $t { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const BitAndAssign for $t { #[inline] fn bitand_assign(&mut self, other: $t) { *self &= other } } - forward_ref_op_assign! { impl BitAndAssign, bitand_assign for $t, $t } + forward_ref_op_assign! { impl const BitAndAssign, bitand_assign for $t, $t } )+) } @@ -786,12 +793,13 @@ pub trait BitOrAssign { macro_rules! bitor_assign_impl { ($($t:ty)+) => ($( #[stable(feature = "op_assign_traits", since = "1.8.0")] - impl BitOrAssign for $t { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const BitOrAssign for $t { #[inline] fn bitor_assign(&mut self, other: $t) { *self |= other } } - forward_ref_op_assign! { impl BitOrAssign, bitor_assign for $t, $t } + forward_ref_op_assign! { impl const BitOrAssign, bitor_assign for $t, $t } )+) } @@ -857,12 +865,13 @@ pub trait BitXorAssign { macro_rules! bitxor_assign_impl { ($($t:ty)+) => ($( #[stable(feature = "op_assign_traits", since = "1.8.0")] - impl BitXorAssign for $t { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const BitXorAssign for $t { #[inline] fn bitxor_assign(&mut self, other: $t) { *self ^= other } } - forward_ref_op_assign! { impl BitXorAssign, bitxor_assign for $t, $t } + forward_ref_op_assign! { impl const BitXorAssign, bitxor_assign for $t, $t } )+) } @@ -918,7 +927,8 @@ pub trait ShlAssign { macro_rules! shl_assign_impl { ($t:ty, $f:ty) => { #[stable(feature = "op_assign_traits", since = "1.8.0")] - impl ShlAssign<$f> for $t { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const ShlAssign<$f> for $t { #[inline] #[rustc_inherit_overflow_checks] fn shl_assign(&mut self, other: $f) { @@ -926,7 +936,7 @@ macro_rules! shl_assign_impl { } } - forward_ref_op_assign! { impl ShlAssign, shl_assign for $t, $f } + forward_ref_op_assign! { impl const ShlAssign, shl_assign for $t, $f } }; } @@ -1000,7 +1010,8 @@ pub trait ShrAssign { macro_rules! shr_assign_impl { ($t:ty, $f:ty) => { #[stable(feature = "op_assign_traits", since = "1.8.0")] - impl ShrAssign<$f> for $t { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const ShrAssign<$f> for $t { #[inline] #[rustc_inherit_overflow_checks] fn shr_assign(&mut self, other: $f) { @@ -1008,7 +1019,7 @@ macro_rules! shr_assign_impl { } } - forward_ref_op_assign! { impl ShrAssign, shr_assign for $t, $f } + forward_ref_op_assign! { impl const ShrAssign, shr_assign for $t, $f } }; } diff --git a/library/core/src/ops/deref.rs b/library/core/src/ops/deref.rs index 08c35b6dac309..d68932402a411 100644 --- a/library/core/src/ops/deref.rs +++ b/library/core/src/ops/deref.rs @@ -76,7 +76,8 @@ pub trait Deref { } #[stable(feature = "rust1", since = "1.0.0")] -impl Deref for &T { +#[rustc_const_unstable(feature = "const_deref", issue = "88955")] +impl const Deref for &T { type Target = T; #[rustc_diagnostic_item = "noop_method_deref"] @@ -89,7 +90,8 @@ impl Deref for &T { impl !DerefMut for &T {} #[stable(feature = "rust1", since = "1.0.0")] -impl Deref for &mut T { +#[rustc_const_unstable(feature = "const_deref", issue = "88955")] +impl const Deref for &mut T { type Target = T; fn deref(&self) -> &T { diff --git a/library/core/src/option.rs b/library/core/src/option.rs index c7385b8dd6fd2..bca73cb770fbb 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -503,6 +503,7 @@ #![stable(feature = "rust1", since = "1.0.0")] use crate::iter::{self, FromIterator, FusedIterator, TrustedLen}; +use crate::marker::Destruct; use crate::panicking::{panic, panic_str}; use crate::pin::Pin; use crate::{ @@ -643,7 +644,8 @@ impl Option { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn as_mut(&mut self) -> Option<&mut T> { + #[rustc_const_unstable(feature = "const_option", issue = "67441")] + pub const fn as_mut(&mut self) -> Option<&mut T> { match *self { Some(ref mut x) => Some(x), None => None, @@ -656,7 +658,8 @@ impl Option { #[inline] #[must_use] #[stable(feature = "pin", since = "1.33.0")] - pub fn as_pin_ref(self: Pin<&Self>) -> Option> { + #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] + pub const fn as_pin_ref(self: Pin<&Self>) -> Option> { match Pin::get_ref(self).as_ref() { // SAFETY: `x` is guaranteed to be pinned because it comes from `self` // which is pinned. @@ -671,7 +674,8 @@ impl Option { #[inline] #[must_use] #[stable(feature = "pin", since = "1.33.0")] - pub fn as_pin_mut(self: Pin<&mut Self>) -> Option> { + #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] + pub const fn as_pin_mut(self: Pin<&mut Self>) -> Option> { // SAFETY: `get_unchecked_mut` is never used to move the `Option` inside `self`. // `x` is guaranteed to be pinned because it comes from `self` which is pinned. unsafe { @@ -788,7 +792,11 @@ impl Option { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn unwrap_or(self, default: T) -> T { + #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] + pub const fn unwrap_or(self, default: T) -> T + where + T: ~const Destruct, + { match self { Some(x) => x, None => default, @@ -806,9 +814,11 @@ impl Option { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn unwrap_or_else(self, f: F) -> T + #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] + pub const fn unwrap_or_else(self, f: F) -> T where - F: FnOnce() -> T, + F: ~const FnOnce() -> T, + F: ~const Destruct, { match self { Some(x) => x, @@ -844,9 +854,10 @@ impl Option { /// [`FromStr`]: crate::str::FromStr #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn unwrap_or_default(self) -> T + #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] + pub const fn unwrap_or_default(self) -> T where - T: Default, + T: ~const Default, { match self { Some(x) => x, @@ -908,9 +919,11 @@ impl Option { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn map(self, f: F) -> Option + #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] + pub const fn map(self, f: F) -> Option where - F: FnOnce(T) -> U, + F: ~const FnOnce(T) -> U, + F: ~const Destruct, { match self { Some(x) => Some(f(x)), @@ -935,9 +948,11 @@ impl Option { /// ``` #[inline] #[unstable(feature = "result_option_inspect", issue = "91345")] - pub fn inspect(self, f: F) -> Self + #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] + pub const fn inspect(self, f: F) -> Self where - F: FnOnce(&T), + F: ~const FnOnce(&T), + F: ~const Destruct, { if let Some(ref x) = self { f(x); @@ -966,9 +981,12 @@ impl Option { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn map_or(self, default: U, f: F) -> U + #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] + pub const fn map_or(self, default: U, f: F) -> U where - F: FnOnce(T) -> U, + F: ~const FnOnce(T) -> U, + F: ~const Destruct, + U: ~const Destruct, { match self { Some(t) => f(t), @@ -992,10 +1010,13 @@ impl Option { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn map_or_else(self, default: D, f: F) -> U + #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] + pub const fn map_or_else(self, default: D, f: F) -> U where - D: FnOnce() -> U, - F: FnOnce(T) -> U, + D: ~const FnOnce() -> U, + D: ~const Destruct, + F: ~const FnOnce(T) -> U, + F: ~const Destruct, { match self { Some(t) => f(t), @@ -1026,7 +1047,11 @@ impl Option { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn ok_or(self, err: E) -> Result { + #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] + pub const fn ok_or(self, err: E) -> Result + where + E: ~const Destruct, + { match self { Some(v) => Ok(v), None => Err(err), @@ -1051,9 +1076,11 @@ impl Option { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn ok_or_else(self, err: F) -> Result + #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] + pub const fn ok_or_else(self, err: F) -> Result where - F: FnOnce() -> E, + F: ~const FnOnce() -> E, + F: ~const Destruct, { match self { Some(v) => Ok(v), @@ -1076,9 +1103,10 @@ impl Option { /// assert_eq!(x.as_deref(), None); /// ``` #[stable(feature = "option_deref", since = "1.40.0")] - pub fn as_deref(&self) -> Option<&T::Target> + #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] + pub const fn as_deref(&self) -> Option<&T::Target> where - T: Deref, + T: ~const Deref, { match self.as_ref() { Some(t) => Some(t.deref()), @@ -1101,9 +1129,10 @@ impl Option { /// }), Some("HEY".to_owned().as_mut_str())); /// ``` #[stable(feature = "option_deref", since = "1.40.0")] - pub fn as_deref_mut(&mut self) -> Option<&mut T::Target> + #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] + pub const fn as_deref_mut(&mut self) -> Option<&mut T::Target> where - T: DerefMut, + T: ~const DerefMut, { match self.as_mut() { Some(t) => Some(t.deref_mut()), @@ -1181,7 +1210,12 @@ impl Option { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn and(self, optb: Option) -> Option { + #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] + pub const fn and(self, optb: Option) -> Option + where + T: ~const Destruct, + U: ~const Destruct, + { match self { Some(_) => optb, None => None, @@ -1218,9 +1252,11 @@ impl Option { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn and_then(self, f: F) -> Option + #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] + pub const fn and_then(self, f: F) -> Option where - F: FnOnce(T) -> Option, + F: ~const FnOnce(T) -> Option, + F: ~const Destruct, { match self { Some(x) => f(x), @@ -1254,9 +1290,12 @@ impl Option { /// [`Some(t)`]: Some #[inline] #[stable(feature = "option_filter", since = "1.27.0")] - pub fn filter

(self, predicate: P) -> Self + #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] + pub const fn filter

(self, predicate: P) -> Self where - P: FnOnce(&T) -> bool, + T: ~const Destruct, + P: ~const FnOnce(&T) -> bool, + P: ~const Destruct, { if let Some(x) = self { if predicate(&x) { @@ -1295,7 +1334,11 @@ impl Option { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn or(self, optb: Option) -> Option { + #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] + pub const fn or(self, optb: Option) -> Option + where + T: ~const Destruct, + { match self { Some(x) => Some(x), None => optb, @@ -1317,9 +1360,11 @@ impl Option { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn or_else(self, f: F) -> Option + #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] + pub const fn or_else(self, f: F) -> Option where - F: FnOnce() -> Option, + F: ~const FnOnce() -> Option, + F: ~const Destruct, { match self { Some(x) => Some(x), @@ -1350,7 +1395,11 @@ impl Option { /// ``` #[inline] #[stable(feature = "option_xor", since = "1.37.0")] - pub fn xor(self, optb: Option) -> Option { + #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] + pub const fn xor(self, optb: Option) -> Option + where + T: ~const Destruct, + { match (self, optb) { (Some(a), None) => Some(a), (None, Some(b)) => Some(b), @@ -1384,7 +1433,11 @@ impl Option { #[must_use = "if you intended to set a value, consider assignment instead"] #[inline] #[stable(feature = "option_insert", since = "1.53.0")] - pub fn insert(&mut self, value: T) -> &mut T { + #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] + pub const fn insert(&mut self, value: T) -> &mut T + where + T: ~const Destruct, + { *self = Some(value); // SAFETY: the code above just filled the option @@ -1413,7 +1466,11 @@ impl Option { /// ``` #[inline] #[stable(feature = "option_entry", since = "1.20.0")] - pub fn get_or_insert(&mut self, value: T) -> &mut T { + #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] + pub const fn get_or_insert(&mut self, value: T) -> &mut T + where + T: ~const Destruct, + { if let None = *self { *self = Some(value); } @@ -1444,11 +1501,12 @@ impl Option { /// ``` #[inline] #[unstable(feature = "option_get_or_insert_default", issue = "82901")] - pub fn get_or_insert_default(&mut self) -> &mut T + #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] + pub const fn get_or_insert_default(&mut self) -> &mut T where - T: Default, + T: ~const Default, { - fn default() -> T { + const fn default() -> T { T::default() } @@ -1474,9 +1532,11 @@ impl Option { /// ``` #[inline] #[stable(feature = "option_entry", since = "1.20.0")] - pub fn get_or_insert_with(&mut self, f: F) -> &mut T + #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] + pub const fn get_or_insert_with(&mut self, f: F) -> &mut T where - F: FnOnce() -> T, + F: ~const FnOnce() -> T, + F: ~const Destruct, { if let None = *self { // the compiler isn't smart enough to know that we are not dropping a `T` @@ -1559,9 +1619,10 @@ impl Option { #[must_use] #[inline] #[unstable(feature = "option_result_contains", issue = "62358")] - pub fn contains(&self, x: &U) -> bool + #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] + pub const fn contains(&self, x: &U) -> bool where - U: PartialEq, + U: ~const PartialEq, { match self { Some(y) => x.eq(y), @@ -1585,7 +1646,12 @@ impl Option { /// assert_eq!(x.zip(z), None); /// ``` #[stable(feature = "option_zip_option", since = "1.46.0")] - pub fn zip(self, other: Option) -> Option<(T, U)> { + #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] + pub const fn zip(self, other: Option) -> Option<(T, U)> + where + T: ~const Destruct, + U: ~const Destruct, + { match (self, other) { (Some(a), Some(b)) => Some((a, b)), _ => None, @@ -1621,9 +1687,13 @@ impl Option { /// assert_eq!(x.zip_with(None, Point::new), None); /// ``` #[unstable(feature = "option_zip", issue = "70086")] - pub fn zip_with(self, other: Option, f: F) -> Option + #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] + pub const fn zip_with(self, other: Option, f: F) -> Option where - F: FnOnce(T, U) -> R, + F: ~const FnOnce(T, U) -> R, + F: ~const Destruct, + T: ~const Destruct, + U: ~const Destruct, { match (self, other) { (Some(a), Some(b)) => Some(f(a, b)), @@ -1701,9 +1771,10 @@ impl Option<&T> { /// ``` #[must_use = "`self` will be dropped if the result is not used"] #[stable(feature = "rust1", since = "1.0.0")] - pub fn cloned(self) -> Option + #[rustc_const_unstable(feature = "const_option_cloned", issue = "91582")] + pub const fn cloned(self) -> Option where - T: Clone, + T: ~const Clone, { match self { Some(t) => Some(t.clone()), @@ -1752,9 +1823,10 @@ impl Option<&mut T> { /// ``` #[must_use = "`self` will be dropped if the result is not used"] #[stable(since = "1.26.0", feature = "option_ref_mut_cloned")] - pub fn cloned(self) -> Option + #[rustc_const_unstable(feature = "const_option_cloned", issue = "91582")] + pub const fn cloned(self) -> Option where - T: Clone, + T: ~const Clone, { match self { Some(t) => Some(t.clone()), @@ -1807,9 +1879,10 @@ const fn expect_failed(msg: &str) -> ! { ///////////////////////////////////////////////////////////////////////////// #[stable(feature = "rust1", since = "1.0.0")] -impl Clone for Option +#[rustc_const_unstable(feature = "const_clone", issue = "91805")] +impl const Clone for Option where - T: Clone, + T: ~const Clone + ~const Destruct, { #[inline] fn clone(&self) -> Self { @@ -1829,7 +1902,8 @@ where } #[stable(feature = "rust1", since = "1.0.0")] -impl Default for Option { +#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] +impl const Default for Option { /// Returns [`None`][Option::None]. /// /// # Examples @@ -1889,7 +1963,8 @@ impl<'a, T> IntoIterator for &'a mut Option { } #[stable(since = "1.12.0", feature = "option_from")] -impl From for Option { +#[rustc_const_unstable(feature = "const_convert", issue = "88674")] +impl const From for Option { /// Moves `val` into a new [`Some`]. /// /// # Examples @@ -1905,7 +1980,8 @@ impl From for Option { } #[stable(feature = "option_ref_from_ref_option", since = "1.30.0")] -impl<'a, T> From<&'a Option> for Option<&'a T> { +#[rustc_const_unstable(feature = "const_convert", issue = "88674")] +impl<'a, T> const From<&'a Option> for Option<&'a T> { /// Converts from `&Option` to `Option<&T>`. /// /// # Examples @@ -1932,7 +2008,8 @@ impl<'a, T> From<&'a Option> for Option<&'a T> { } #[stable(feature = "option_ref_from_ref_option", since = "1.30.0")] -impl<'a, T> From<&'a mut Option> for Option<&'a mut T> { +#[rustc_const_unstable(feature = "const_convert", issue = "88674")] +impl<'a, T> const From<&'a mut Option> for Option<&'a mut T> { /// Converts from `&mut Option` to `Option<&mut T>` /// /// # Examples @@ -2199,7 +2276,8 @@ impl> FromIterator> for Option { } #[unstable(feature = "try_trait_v2", issue = "84277")] -impl ops::Try for Option { +#[rustc_const_unstable(feature = "const_convert", issue = "88674")] +impl const ops::Try for Option { type Output = T; type Residual = Option; @@ -2218,7 +2296,8 @@ impl ops::Try for Option { } #[unstable(feature = "try_trait_v2", issue = "84277")] -impl ops::FromResidual for Option { +#[rustc_const_unstable(feature = "const_convert", issue = "88674")] +impl const ops::FromResidual for Option { #[inline] fn from_residual(residual: Option) -> Self { match residual { @@ -2267,7 +2346,8 @@ impl Option> { /// ``` #[inline] #[stable(feature = "option_flattening", since = "1.40.0")] - pub fn flatten(self) -> Option { + #[rustc_const_unstable(feature = "const_option", issue = "67441")] + pub const fn flatten(self) -> Option { match self { Some(inner) => inner, None => None, diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index f0727d4a749bc..74aa0d9c7bcb2 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -737,7 +737,7 @@ impl *const T { { // SAFETY: The comparison has no side-effects, and the intrinsic // does this check internally in the CTFE implementation. - assert_unsafe_precondition!(self >= origin); + unsafe { assert_unsafe_precondition!(self >= origin) }; let pointee_size = mem::size_of::(); assert!(0 < pointee_size && pointee_size <= isize::MAX as usize); @@ -1269,7 +1269,8 @@ impl *const T { /// # } } /// ``` #[stable(feature = "align_offset", since = "1.36.0")] - pub fn align_offset(self, align: usize) -> usize + #[rustc_const_unstable(feature = "const_align_offset", issue = "90962")] + pub const fn align_offset(self, align: usize) -> usize where T: Sized, { @@ -1282,12 +1283,16 @@ impl *const T { unsafe { align_offset(p, align) } } + const fn ctfe_impl(_: *const T, _: usize) -> usize { + usize::MAX + } + // SAFETY: // It is permissible for `align_offset` to always return `usize::MAX`, // algorithm correctness can not depend on `align_offset` returning non-max values. // // As such the behaviour can't change after replacing `align_offset` with `usize::MAX`, only performance can. - rt_impl(self, align) + unsafe { intrinsics::const_eval_select((self, align), ctfe_impl, rt_impl) } } /// Returns whether the pointer is properly aligned for `T`. @@ -1390,10 +1395,11 @@ impl *const [T] { /// } /// ``` #[unstable(feature = "slice_ptr_get", issue = "74265")] + #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] #[inline] - pub unsafe fn get_unchecked(self, index: I) -> *const I::Output + pub const unsafe fn get_unchecked(self, index: I) -> *const I::Output where - I: SliceIndex<[T]>, + I: ~const SliceIndex<[T]>, { // SAFETY: the caller ensures that `self` is dereferenceable and `index` in-bounds. unsafe { index.get_unchecked(self) } diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index d0b87b38935f7..2fcff3dfc5c44 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -371,7 +371,9 @@ use crate::cmp::Ordering; use crate::fmt; use crate::hash; -use crate::intrinsics::{self, assert_unsafe_precondition}; +use crate::intrinsics::{ + self, assert_unsafe_precondition, is_aligned_and_not_null, is_nonoverlapping, +}; use crate::mem::{self, MaybeUninit}; @@ -881,9 +883,13 @@ pub const unsafe fn swap_nonoverlapping(x: *mut T, y: *mut T, count: usize) { // SAFETY: the caller must guarantee that `x` and `y` are // valid for writes and properly aligned. - assert_unsafe_precondition!( - is_aligned_and_not_null(x) && is_aligned_and_not_null(y) && is_nonoverlapping(x, y, count) - ); + unsafe { + assert_unsafe_precondition!( + is_aligned_and_not_null(x) + && is_aligned_and_not_null(y) + && is_nonoverlapping(x, y, count) + ); + } // NOTE(scottmcm) Miri is disabled here as reading in smaller units is a // pessimization for it. Also, if the type contains any unaligned pointers, diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index 342500796bb60..b988090f4bc4c 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -1539,7 +1539,8 @@ impl *mut T { /// # } } /// ``` #[stable(feature = "align_offset", since = "1.36.0")] - pub fn align_offset(self, align: usize) -> usize + #[rustc_const_unstable(feature = "const_align_offset", issue = "90962")] + pub const fn align_offset(self, align: usize) -> usize where T: Sized, { @@ -1552,12 +1553,16 @@ impl *mut T { unsafe { align_offset(p, align) } } + const fn ctfe_impl(_: *mut T, _: usize) -> usize { + usize::MAX + } + // SAFETY: // It is permissible for `align_offset` to always return `usize::MAX`, // algorithm correctness can not depend on `align_offset` returning non-max values. // // As such the behaviour can't change after replacing `align_offset` with `usize::MAX`, only performance can. - rt_impl(self, align) + unsafe { intrinsics::const_eval_select((self, align), ctfe_impl, rt_impl) } } /// Returns whether the pointer is properly aligned for `T`. @@ -1776,10 +1781,11 @@ impl *mut [T] { /// } /// ``` #[unstable(feature = "slice_ptr_get", issue = "74265")] + #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] #[inline(always)] - pub unsafe fn get_unchecked_mut(self, index: I) -> *mut I::Output + pub const unsafe fn get_unchecked_mut(self, index: I) -> *mut I::Output where - I: SliceIndex<[T]>, + I: ~const SliceIndex<[T]>, { // SAFETY: the caller ensures that `self` is dereferenceable and `index` in-bounds. unsafe { index.get_unchecked_mut(self) } diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index ad9152f78adec..f3ef094cbccc5 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -684,10 +684,11 @@ impl NonNull<[T]> { /// } /// ``` #[unstable(feature = "slice_ptr_get", issue = "74265")] + #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] #[inline] - pub unsafe fn get_unchecked_mut(self, index: I) -> NonNull + pub const unsafe fn get_unchecked_mut(self, index: I) -> NonNull where - I: SliceIndex<[T]>, + I: ~const SliceIndex<[T]>, { // SAFETY: the caller ensures that `self` is dereferenceable and `index` in-bounds. // As a consequence, the resulting pointer cannot be null. @@ -696,7 +697,8 @@ impl NonNull<[T]> { } #[stable(feature = "nonnull", since = "1.25.0")] -impl Clone for NonNull { +#[rustc_const_unstable(feature = "const_clone", issue = "91805")] +impl const Clone for NonNull { #[inline] fn clone(&self) -> Self { *self @@ -762,7 +764,8 @@ impl hash::Hash for NonNull { } #[unstable(feature = "ptr_internals", issue = "none")] -impl From> for NonNull { +#[rustc_const_unstable(feature = "const_convert", issue = "88674")] +impl const From> for NonNull { #[inline] fn from(unique: Unique) -> Self { // SAFETY: A Unique pointer cannot be null, so the conditions for @@ -772,7 +775,8 @@ impl From> for NonNull { } #[stable(feature = "nonnull", since = "1.25.0")] -impl From<&mut T> for NonNull { +#[rustc_const_unstable(feature = "const_convert", issue = "88674")] +impl const From<&mut T> for NonNull { /// Converts a `&mut T` to a `NonNull`. /// /// This conversion is safe and infallible since references cannot be null. @@ -784,7 +788,8 @@ impl From<&mut T> for NonNull { } #[stable(feature = "nonnull", since = "1.25.0")] -impl From<&T> for NonNull { +#[rustc_const_unstable(feature = "const_convert", issue = "88674")] +impl const From<&T> for NonNull { /// Converts a `&T` to a `NonNull`. /// /// This conversion is safe and infallible since references cannot be null. diff --git a/library/core/src/ptr/unique.rs b/library/core/src/ptr/unique.rs index c08ef753f2607..64616142b4188 100644 --- a/library/core/src/ptr/unique.rs +++ b/library/core/src/ptr/unique.rs @@ -70,7 +70,7 @@ impl Unique { #[must_use] #[inline] pub const fn dangling() -> Self { - Self { pointer: NonNull::dangling(), _marker: PhantomData } + Self::from(NonNull::dangling()) } } @@ -133,14 +133,14 @@ impl Unique { /// Casts to a pointer of another type. #[must_use = "`self` will be dropped if the result is not used"] #[inline] - pub fn cast(self) -> Unique { + pub const fn cast(self) -> Unique { Unique::from(self.pointer.cast()) } } #[unstable(feature = "ptr_internals", issue = "none")] #[rustc_const_unstable(feature = "const_clone", issue = "91805")] -impl Clone for Unique { +impl const Clone for Unique { #[inline] fn clone(&self) -> Self { *self @@ -171,7 +171,7 @@ impl fmt::Pointer for Unique { } #[unstable(feature = "ptr_internals", issue = "none")] -impl From<&mut T> for Unique { +impl const From<&mut T> for Unique { /// Converts a `&mut T` to a `Unique`. /// /// This conversion is infallible since references cannot be null. @@ -182,7 +182,7 @@ impl From<&mut T> for Unique { } #[unstable(feature = "ptr_internals", issue = "none")] -impl From> for Unique { +impl const From> for Unique { /// Converts a `NonNull` to a `Unique`. /// /// This conversion is infallible since `NonNull` cannot be null. diff --git a/library/core/src/result.rs b/library/core/src/result.rs index 97127643a7f6f..8a68cdf7d651b 100644 --- a/library/core/src/result.rs +++ b/library/core/src/result.rs @@ -633,10 +633,16 @@ impl Result { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn ok(self) -> Option { + #[rustc_const_unstable(feature = "const_result_drop", issue = "92384")] + pub const fn ok(self) -> Option + where + E: ~const Destruct, + { match self { Ok(x) => Some(x), - Err(_) => None, + // FIXME: ~const Drop doesn't quite work right yet + #[allow(unused_variables)] + Err(x) => None, } } @@ -658,9 +664,15 @@ impl Result { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn err(self) -> Option { + #[rustc_const_unstable(feature = "const_result_drop", issue = "92384")] + pub const fn err(self) -> Option + where + T: ~const Destruct, + { match self { - Ok(_) => None, + // FIXME: ~const Drop doesn't quite work right yet + #[allow(unused_variables)] + Ok(x) => None, Err(x) => Some(x), } } @@ -719,7 +731,8 @@ impl Result { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn as_mut(&mut self) -> Result<&mut T, &mut E> { + #[rustc_const_unstable(feature = "const_result", issue = "82814")] + pub const fn as_mut(&mut self) -> Result<&mut T, &mut E> { match *self { Ok(ref mut x) => Ok(x), Err(ref mut x) => Err(x), @@ -1286,13 +1299,18 @@ impl Result { /// assert_eq!(x.and(y), Ok("different result type")); /// ``` #[inline] + #[rustc_const_unstable(feature = "const_result_drop", issue = "92384")] #[stable(feature = "rust1", since = "1.0.0")] - pub fn and(self, res: Result) -> Result + pub const fn and(self, res: Result) -> Result where - U: Destruct, + T: ~const Destruct, + U: ~const Destruct, + E: ~const Destruct, { match self { - Ok(_) => res, + // FIXME: ~const Drop doesn't quite work right yet + #[allow(unused_variables)] + Ok(x) => res, Err(e) => Err(e), } } @@ -1366,14 +1384,19 @@ impl Result { /// assert_eq!(x.or(y), Ok(2)); /// ``` #[inline] + #[rustc_const_unstable(feature = "const_result_drop", issue = "92384")] #[stable(feature = "rust1", since = "1.0.0")] - pub fn or(self, res: Result) -> Result + pub const fn or(self, res: Result) -> Result where - F: Destruct, + T: ~const Destruct, + E: ~const Destruct, + F: ~const Destruct, { match self { Ok(v) => Ok(v), - Err(_) => res, + // FIXME: ~const Drop doesn't quite work right yet + #[allow(unused_variables)] + Err(e) => res, } } @@ -1425,11 +1448,18 @@ impl Result { /// assert_eq!(x.unwrap_or(default), default); /// ``` #[inline] + #[rustc_const_unstable(feature = "const_result_drop", issue = "92384")] #[stable(feature = "rust1", since = "1.0.0")] - pub fn unwrap_or(self, default: T) -> T { + pub const fn unwrap_or(self, default: T) -> T + where + T: ~const Destruct, + E: ~const Destruct, + { match self { Ok(t) => t, - Err(_) => default, + // FIXME: ~const Drop doesn't quite work right yet + #[allow(unused_variables)] + Err(e) => default, } } @@ -1793,10 +1823,10 @@ fn unwrap_failed(_msg: &str, _error: &T) -> ! { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_unstable(feature = "const_clone", issue = "91805")] -impl Clone for Result +impl const Clone for Result where - T: Clone, - E: Clone, + T: ~const Clone + ~const Destruct, + E: ~const Clone + ~const Destruct, { #[inline] fn clone(&self) -> Self { @@ -2064,7 +2094,8 @@ impl> FromIterator> for Result { } #[unstable(feature = "try_trait_v2", issue = "84277")] -impl ops::Try for Result { +#[rustc_const_unstable(feature = "const_convert", issue = "88674")] +impl const ops::Try for Result { type Output = T; type Residual = Result; @@ -2083,7 +2114,10 @@ impl ops::Try for Result { } #[unstable(feature = "try_trait_v2", issue = "84277")] -impl> ops::FromResidual> for Result { +#[rustc_const_unstable(feature = "const_convert", issue = "88674")] +impl> const ops::FromResidual> + for Result +{ #[inline] #[track_caller] fn from_residual(residual: Result) -> Self { diff --git a/library/core/src/slice/index.rs b/library/core/src/slice/index.rs index 6e80b39c3371d..fd7ecf3daf316 100644 --- a/library/core/src/slice/index.rs +++ b/library/core/src/slice/index.rs @@ -1,13 +1,15 @@ //! Indexing implementations for `[T]`. use crate::intrinsics::assert_unsafe_precondition; +use crate::intrinsics::const_eval_select; use crate::ops; use crate::ptr; #[stable(feature = "rust1", since = "1.0.0")] -impl ops::Index for [T] +#[rustc_const_unstable(feature = "const_slice_index", issue = "none")] +impl const ops::Index for [T] where - I: SliceIndex<[T]>, + I: ~const SliceIndex<[T]>, { type Output = I::Output; @@ -18,9 +20,10 @@ where } #[stable(feature = "rust1", since = "1.0.0")] -impl ops::IndexMut for [T] +#[rustc_const_unstable(feature = "const_slice_index", issue = "none")] +impl const ops::IndexMut for [T] where - I: SliceIndex<[T]>, + I: ~const SliceIndex<[T]>, { #[inline] fn index_mut(&mut self, index: I) -> &mut I::Output { @@ -32,26 +35,67 @@ where #[cfg_attr(feature = "panic_immediate_abort", inline)] #[cold] #[track_caller] -fn slice_start_index_len_fail(index: usize, len: usize) -> ! { +#[rustc_const_unstable(feature = "const_slice_index", issue = "none")] +const fn slice_start_index_len_fail(index: usize, len: usize) -> ! { + // SAFETY: we are just panicking here + unsafe { + const_eval_select( + (index, len), + slice_start_index_len_fail_ct, + slice_start_index_len_fail_rt, + ) + } +} + +// FIXME const-hack +fn slice_start_index_len_fail_rt(index: usize, len: usize) -> ! { panic!("range start index {index} out of range for slice of length {len}"); } +const fn slice_start_index_len_fail_ct(_: usize, _: usize) -> ! { + panic!("slice start index is out of range for slice"); +} + #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))] #[cfg_attr(feature = "panic_immediate_abort", inline)] #[cold] #[track_caller] -fn slice_end_index_len_fail(index: usize, len: usize) -> ! { +#[rustc_const_unstable(feature = "const_slice_index", issue = "none")] +const fn slice_end_index_len_fail(index: usize, len: usize) -> ! { + // SAFETY: we are just panicking here + unsafe { + const_eval_select((index, len), slice_end_index_len_fail_ct, slice_end_index_len_fail_rt) + } +} + +// FIXME const-hack +fn slice_end_index_len_fail_rt(index: usize, len: usize) -> ! { panic!("range end index {index} out of range for slice of length {len}"); } +const fn slice_end_index_len_fail_ct(_: usize, _: usize) -> ! { + panic!("slice end index is out of range for slice"); +} + #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))] #[cfg_attr(feature = "panic_immediate_abort", inline)] #[cold] #[track_caller] -fn slice_index_order_fail(index: usize, end: usize) -> ! { +#[rustc_const_unstable(feature = "const_slice_index", issue = "none")] +const fn slice_index_order_fail(index: usize, end: usize) -> ! { + // SAFETY: we are just panicking here + unsafe { const_eval_select((index, end), slice_index_order_fail_ct, slice_index_order_fail_rt) } +} + +// FIXME const-hack +fn slice_index_order_fail_rt(index: usize, end: usize) -> ! { panic!("slice index starts at {index} but ends at {end}"); } +const fn slice_index_order_fail_ct(_: usize, _: usize) -> ! { + panic!("slice index start is larger than end"); +} + #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))] #[cfg_attr(feature = "panic_immediate_abort", inline)] #[cold] @@ -155,7 +199,8 @@ pub unsafe trait SliceIndex: private_slice_index::Sealed { } #[stable(feature = "slice_get_slice_impls", since = "1.15.0")] -unsafe impl SliceIndex<[T]> for usize { +#[rustc_const_unstable(feature = "const_slice_index", issue = "none")] +unsafe impl const SliceIndex<[T]> for usize { type Output = T; #[inline] @@ -205,7 +250,8 @@ unsafe impl SliceIndex<[T]> for usize { } #[stable(feature = "slice_get_slice_impls", since = "1.15.0")] -unsafe impl SliceIndex<[T]> for ops::Range { +#[rustc_const_unstable(feature = "const_slice_index", issue = "none")] +unsafe impl const SliceIndex<[T]> for ops::Range { type Output = [T]; #[inline] @@ -274,7 +320,8 @@ unsafe impl SliceIndex<[T]> for ops::Range { } #[stable(feature = "slice_get_slice_impls", since = "1.15.0")] -unsafe impl SliceIndex<[T]> for ops::RangeTo { +#[rustc_const_unstable(feature = "const_slice_index", issue = "none")] +unsafe impl const SliceIndex<[T]> for ops::RangeTo { type Output = [T]; #[inline] @@ -311,7 +358,8 @@ unsafe impl SliceIndex<[T]> for ops::RangeTo { } #[stable(feature = "slice_get_slice_impls", since = "1.15.0")] -unsafe impl SliceIndex<[T]> for ops::RangeFrom { +#[rustc_const_unstable(feature = "const_slice_index", issue = "none")] +unsafe impl const SliceIndex<[T]> for ops::RangeFrom { type Output = [T]; #[inline] @@ -356,7 +404,8 @@ unsafe impl SliceIndex<[T]> for ops::RangeFrom { } #[stable(feature = "slice_get_slice_impls", since = "1.15.0")] -unsafe impl SliceIndex<[T]> for ops::RangeFull { +#[rustc_const_unstable(feature = "const_slice_index", issue = "none")] +unsafe impl const SliceIndex<[T]> for ops::RangeFull { type Output = [T]; #[inline] @@ -391,7 +440,8 @@ unsafe impl SliceIndex<[T]> for ops::RangeFull { } #[stable(feature = "inclusive_range", since = "1.26.0")] -unsafe impl SliceIndex<[T]> for ops::RangeInclusive { +#[rustc_const_unstable(feature = "const_slice_index", issue = "none")] +unsafe impl const SliceIndex<[T]> for ops::RangeInclusive { type Output = [T]; #[inline] @@ -434,7 +484,8 @@ unsafe impl SliceIndex<[T]> for ops::RangeInclusive { } #[stable(feature = "inclusive_range", since = "1.26.0")] -unsafe impl SliceIndex<[T]> for ops::RangeToInclusive { +#[rustc_const_unstable(feature = "const_slice_index", issue = "none")] +unsafe impl const SliceIndex<[T]> for ops::RangeToInclusive { type Output = [T]; #[inline] diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index 7c63a3a1ab83f..77fd1ec2b8ea2 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -333,11 +333,12 @@ impl [T] { /// assert_eq!(None, v.get(0..4)); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] #[inline] #[must_use] - pub fn get(&self, index: I) -> Option<&I::Output> + pub const fn get(&self, index: I) -> Option<&I::Output> where - I: SliceIndex, + I: ~const SliceIndex, { index.get(self) } @@ -358,11 +359,12 @@ impl [T] { /// assert_eq!(x, &[0, 42, 2]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] #[inline] #[must_use] - pub fn get_mut(&mut self, index: I) -> Option<&mut I::Output> + pub const fn get_mut(&mut self, index: I) -> Option<&mut I::Output> where - I: SliceIndex, + I: ~const SliceIndex, { index.get_mut(self) } @@ -390,11 +392,12 @@ impl [T] { /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] #[inline] #[must_use] - pub unsafe fn get_unchecked(&self, index: I) -> &I::Output + pub const unsafe fn get_unchecked(&self, index: I) -> &I::Output where - I: SliceIndex, + I: ~const SliceIndex, { // SAFETY: the caller must uphold most of the safety requirements for `get_unchecked`; // the slice is dereferenceable because `self` is a safe reference. @@ -427,11 +430,12 @@ impl [T] { /// assert_eq!(x, &[1, 13, 4]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] #[inline] #[must_use] - pub unsafe fn get_unchecked_mut(&mut self, index: I) -> &mut I::Output + pub const unsafe fn get_unchecked_mut(&mut self, index: I) -> &mut I::Output where - I: SliceIndex, + I: ~const SliceIndex, { // SAFETY: the caller must uphold the safety requirements for `get_unchecked_mut`; // the slice is dereferenceable because `self` is a safe reference. @@ -4129,7 +4133,8 @@ where } #[stable(feature = "rust1", since = "1.0.0")] -impl Default for &[T] { +#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] +impl const Default for &[T] { /// Creates an empty slice. fn default() -> Self { &[] @@ -4137,7 +4142,8 @@ impl Default for &[T] { } #[stable(feature = "mut_slice_default", since = "1.5.0")] -impl Default for &mut [T] { +#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] +impl const Default for &mut [T] { /// Creates a mutable empty slice. fn default() -> Self { &mut [] diff --git a/library/core/src/slice/raw.rs b/library/core/src/slice/raw.rs index d1dfbf6a9e20c..107e71ab68b01 100644 --- a/library/core/src/slice/raw.rs +++ b/library/core/src/slice/raw.rs @@ -1,7 +1,7 @@ //! Free functions to create `&[T]` and `&mut [T]`. use crate::array; -use crate::intrinsics::assert_unsafe_precondition; +use crate::intrinsics::{assert_unsafe_precondition, is_aligned_and_not_null}; use crate::ops::Range; use crate::ptr; diff --git a/library/core/src/str/converts.rs b/library/core/src/str/converts.rs index f5548c8269608..d00a56af05155 100644 --- a/library/core/src/str/converts.rs +++ b/library/core/src/str/converts.rs @@ -82,7 +82,8 @@ use super::Utf8Error; /// assert_eq!("💖", sparkle_heart); /// ``` #[stable(feature = "rust1", since = "1.0.0")] -pub fn from_utf8(v: &[u8]) -> Result<&str, Utf8Error> { +#[rustc_const_unstable(feature = "const_str_from_utf8", issue = "91006")] +pub const fn from_utf8(v: &[u8]) -> Result<&str, Utf8Error> { // FIXME: This should use `?` again, once it's `const` match run_utf8_validation(v) { Ok(_) => { @@ -124,7 +125,8 @@ pub fn from_utf8(v: &[u8]) -> Result<&str, Utf8Error> { /// See the docs for [`Utf8Error`] for more details on the kinds of /// errors that can be returned. #[stable(feature = "str_mut_extras", since = "1.20.0")] -pub fn from_utf8_mut(v: &mut [u8]) -> Result<&mut str, Utf8Error> { +#[rustc_const_unstable(feature = "const_str_from_utf8", issue = "91006")] +pub const fn from_utf8_mut(v: &mut [u8]) -> Result<&mut str, Utf8Error> { // This should use `?` again, once it's `const` match run_utf8_validation(v) { Ok(_) => { diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index 33cace645199d..c4f2e283eb3bc 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -79,7 +79,23 @@ use iter::{MatchesInternal, SplitNInternal}; #[inline(never)] #[cold] #[track_caller] -fn slice_error_fail(s: &str, begin: usize, end: usize) -> ! { +#[rustc_allow_const_fn_unstable(const_eval_select)] +const fn slice_error_fail(s: &str, begin: usize, end: usize) -> ! { + // SAFETY: panics for both branches + unsafe { + crate::intrinsics::const_eval_select( + (s, begin, end), + slice_error_fail_ct, + slice_error_fail_rt, + ) + } +} + +const fn slice_error_fail_ct(_: &str, _: usize, _: usize) -> ! { + panic!("failed to slice string"); +} + +fn slice_error_fail_rt(s: &str, begin: usize, end: usize) -> ! { const MAX_DISPLAY_LENGTH: usize = 256; let trunc_len = s.floor_char_boundary(MAX_DISPLAY_LENGTH); let s_trunc = &s[..trunc_len]; @@ -188,8 +204,9 @@ impl str { /// ``` #[must_use] #[stable(feature = "is_char_boundary", since = "1.9.0")] + #[rustc_const_unstable(feature = "const_is_char_boundary", issue = "none")] #[inline] - pub fn is_char_boundary(&self, index: usize) -> bool { + pub const fn is_char_boundary(&self, index: usize) -> bool { // 0 is always ok. // Test for 0 explicitly so that it can optimize out the check // easily and skip reading string data for that case. @@ -417,8 +434,9 @@ impl str { /// assert!(v.get(..42).is_none()); /// ``` #[stable(feature = "str_checked_slicing", since = "1.20.0")] + #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] #[inline] - pub fn get>(&self, i: I) -> Option<&I::Output> { + pub const fn get>(&self, i: I) -> Option<&I::Output> { i.get(self) } @@ -449,8 +467,9 @@ impl str { /// assert_eq!("HEllo", v); /// ``` #[stable(feature = "str_checked_slicing", since = "1.20.0")] + #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] #[inline] - pub fn get_mut>(&mut self, i: I) -> Option<&mut I::Output> { + pub const fn get_mut>(&mut self, i: I) -> Option<&mut I::Output> { i.get_mut(self) } @@ -481,8 +500,9 @@ impl str { /// } /// ``` #[stable(feature = "str_checked_slicing", since = "1.20.0")] + #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] #[inline] - pub unsafe fn get_unchecked>(&self, i: I) -> &I::Output { + pub const unsafe fn get_unchecked>(&self, i: I) -> &I::Output { // SAFETY: the caller must uphold the safety contract for `get_unchecked`; // the slice is dereferenceable because `self` is a safe reference. // The returned pointer is safe because impls of `SliceIndex` have to guarantee that it is. @@ -516,8 +536,12 @@ impl str { /// } /// ``` #[stable(feature = "str_checked_slicing", since = "1.20.0")] + #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] #[inline] - pub unsafe fn get_unchecked_mut>(&mut self, i: I) -> &mut I::Output { + pub const unsafe fn get_unchecked_mut>( + &mut self, + i: I, + ) -> &mut I::Output { // SAFETY: the caller must uphold the safety contract for `get_unchecked_mut`; // the slice is dereferenceable because `self` is a safe reference. // The returned pointer is safe because impls of `SliceIndex` have to guarantee that it is. @@ -2542,7 +2566,8 @@ impl AsRef<[u8]> for str { } #[stable(feature = "rust1", since = "1.0.0")] -impl Default for &str { +#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] +impl const Default for &str { /// Creates an empty str #[inline] fn default() -> Self { diff --git a/library/core/src/str/traits.rs b/library/core/src/str/traits.rs index bc5ab07136aba..32c31803a5115 100644 --- a/library/core/src/str/traits.rs +++ b/library/core/src/str/traits.rs @@ -53,9 +53,10 @@ impl PartialOrd for str { } #[stable(feature = "rust1", since = "1.0.0")] -impl ops::Index for str +#[rustc_const_unstable(feature = "const_slice_index", issue = "none")] +impl const ops::Index for str where - I: SliceIndex, + I: ~const SliceIndex, { type Output = I::Output; @@ -66,9 +67,10 @@ where } #[stable(feature = "rust1", since = "1.0.0")] -impl ops::IndexMut for str +#[rustc_const_unstable(feature = "const_slice_index", issue = "none")] +impl const ops::IndexMut for str where - I: SliceIndex, + I: ~const SliceIndex, { #[inline] fn index_mut(&mut self, index: I) -> &mut I::Output { @@ -96,7 +98,8 @@ const fn str_index_overflow_fail() -> ! { /// /// Equivalent to `&self[0 .. len]` or `&mut self[0 .. len]`. #[stable(feature = "str_checked_slicing", since = "1.20.0")] -unsafe impl SliceIndex for ops::RangeFull { +#[rustc_const_unstable(feature = "const_slice_index", issue = "none")] +unsafe impl const SliceIndex for ops::RangeFull { type Output = str; #[inline] fn get(self, slice: &str) -> Option<&Self::Output> { @@ -160,7 +163,8 @@ unsafe impl SliceIndex for ops::RangeFull { /// // &s[3 .. 100]; /// ``` #[stable(feature = "str_checked_slicing", since = "1.20.0")] -unsafe impl SliceIndex for ops::Range { +#[rustc_const_unstable(feature = "const_slice_index", issue = "none")] +unsafe impl const SliceIndex for ops::Range { type Output = str; #[inline] fn get(self, slice: &str) -> Option<&Self::Output> { @@ -247,7 +251,8 @@ unsafe impl SliceIndex for ops::Range { /// Panics if `end` does not point to the starting byte offset of a /// character (as defined by `is_char_boundary`), or if `end > len`. #[stable(feature = "str_checked_slicing", since = "1.20.0")] -unsafe impl SliceIndex for ops::RangeTo { +#[rustc_const_unstable(feature = "const_slice_index", issue = "none")] +unsafe impl const SliceIndex for ops::RangeTo { type Output = str; #[inline] fn get(self, slice: &str) -> Option<&Self::Output> { @@ -317,7 +322,8 @@ unsafe impl SliceIndex for ops::RangeTo { /// Panics if `begin` does not point to the starting byte offset of /// a character (as defined by `is_char_boundary`), or if `begin > len`. #[stable(feature = "str_checked_slicing", since = "1.20.0")] -unsafe impl SliceIndex for ops::RangeFrom { +#[rustc_const_unstable(feature = "const_slice_index", issue = "none")] +unsafe impl const SliceIndex for ops::RangeFrom { type Output = str; #[inline] fn get(self, slice: &str) -> Option<&Self::Output> { @@ -393,7 +399,8 @@ unsafe impl SliceIndex for ops::RangeFrom { /// to the ending byte offset of a character (`end + 1` is either a starting /// byte offset or equal to `len`), if `begin > end`, or if `end >= len`. #[stable(feature = "inclusive_range", since = "1.26.0")] -unsafe impl SliceIndex for ops::RangeInclusive { +#[rustc_const_unstable(feature = "const_slice_index", issue = "none")] +unsafe impl const SliceIndex for ops::RangeInclusive { type Output = str; #[inline] fn get(self, slice: &str) -> Option<&Self::Output> { @@ -444,7 +451,8 @@ unsafe impl SliceIndex for ops::RangeInclusive { /// (`end + 1` is either a starting byte offset as defined by /// `is_char_boundary`, or equal to `len`), or if `end >= len`. #[stable(feature = "inclusive_range", since = "1.26.0")] -unsafe impl SliceIndex for ops::RangeToInclusive { +#[rustc_const_unstable(feature = "const_slice_index", issue = "none")] +unsafe impl const SliceIndex for ops::RangeToInclusive { type Output = str; #[inline] fn get(self, slice: &str) -> Option<&Self::Output> { diff --git a/library/core/src/str/validations.rs b/library/core/src/str/validations.rs index f38d68912f03d..04bc665233e38 100644 --- a/library/core/src/str/validations.rs +++ b/library/core/src/str/validations.rs @@ -123,7 +123,8 @@ const fn contains_nonascii(x: usize) -> bool { /// Walks through `v` checking that it's a valid UTF-8 sequence, /// returning `Ok(())` in that case, or, if it is invalid, `Err(err)`. #[inline(always)] -pub(super) fn run_utf8_validation(v: &[u8]) -> Result<(), Utf8Error> { +#[rustc_const_unstable(feature = "str_internals", issue = "none")] +pub(super) const fn run_utf8_validation(v: &[u8]) -> Result<(), Utf8Error> { let mut index = 0; let len = v.len(); diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index 45f6f3c72dae4..ebc769ac7ca3b 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -147,7 +147,8 @@ pub struct AtomicBool { #[cfg(target_has_atomic_load_store = "8")] #[stable(feature = "rust1", since = "1.0.0")] -impl Default for AtomicBool { +#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] +impl const Default for AtomicBool { /// Creates an `AtomicBool` initialized to `false`. #[inline] fn default() -> Self { @@ -178,7 +179,8 @@ pub struct AtomicPtr { #[cfg(target_has_atomic_load_store = "ptr")] #[stable(feature = "rust1", since = "1.0.0")] -impl Default for AtomicPtr { +#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] +impl const Default for AtomicPtr { /// Creates a null `AtomicPtr`. fn default() -> AtomicPtr { AtomicPtr::new(crate::ptr::null_mut()) @@ -1794,7 +1796,8 @@ impl AtomicPtr { #[cfg(target_has_atomic_load_store = "8")] #[stable(feature = "atomic_bool_from", since = "1.24.0")] -impl From for AtomicBool { +#[rustc_const_unstable(feature = "const_convert", issue = "88674")] +impl const From for AtomicBool { /// Converts a `bool` into an `AtomicBool`. /// /// # Examples @@ -1812,7 +1815,8 @@ impl From for AtomicBool { #[cfg(target_has_atomic_load_store = "ptr")] #[stable(feature = "atomic_from", since = "1.23.0")] -impl From<*mut T> for AtomicPtr { +#[rustc_const_unstable(feature = "const_convert", issue = "88674")] +impl const From<*mut T> for AtomicPtr { /// Converts a `*mut T` into an `AtomicPtr`. #[inline] fn from(p: *mut T) -> Self { @@ -1878,7 +1882,8 @@ macro_rules! atomic_int { pub const $atomic_init: $atomic_type = $atomic_type::new(0); #[$stable] - impl Default for $atomic_type { + #[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] + impl const Default for $atomic_type { #[inline] fn default() -> Self { Self::new(Default::default()) @@ -1886,7 +1891,8 @@ macro_rules! atomic_int { } #[$stable_from] - impl From<$int_type> for $atomic_type { + #[rustc_const_unstable(feature = "const_num_from_num", issue = "87852")] + impl const From<$int_type> for $atomic_type { #[doc = concat!("Converts an `", stringify!($int_type), "` into an `", stringify!($atomic_type), "`.")] #[inline] fn from(v: $int_type) -> Self { Self::new(v) } diff --git a/library/core/src/task/poll.rs b/library/core/src/task/poll.rs index c06f2cf9ff5c2..41f0a25dbc3e0 100644 --- a/library/core/src/task/poll.rs +++ b/library/core/src/task/poll.rs @@ -241,7 +241,8 @@ impl Poll>> { } #[stable(feature = "futures_api", since = "1.36.0")] -impl From for Poll { +#[rustc_const_unstable(feature = "const_convert", issue = "88674")] +impl const From for Poll { /// Moves the value into a [`Poll::Ready`] to make a `Poll`. /// /// # Example diff --git a/library/core/src/time.rs b/library/core/src/time.rs index ba6fe0dfbd31e..756f1a1663ca7 100644 --- a/library/core/src/time.rs +++ b/library/core/src/time.rs @@ -737,7 +737,8 @@ impl Duration { #[stable(feature = "duration_float", since = "1.38.0")] #[must_use] #[inline] - pub fn from_secs_f64(secs: f64) -> Duration { + #[rustc_const_unstable(feature = "duration_consts_float", issue = "72440")] + pub const fn from_secs_f64(secs: f64) -> Duration { match Duration::try_from_secs_f64(secs) { Ok(v) => v, Err(e) => panic!("{}", e.description()), @@ -774,7 +775,8 @@ impl Duration { #[stable(feature = "duration_float", since = "1.38.0")] #[must_use] #[inline] - pub fn from_secs_f32(secs: f32) -> Duration { + #[rustc_const_unstable(feature = "duration_consts_float", issue = "72440")] + pub const fn from_secs_f32(secs: f32) -> Duration { match Duration::try_from_secs_f32(secs) { Ok(v) => v, Err(e) => panic!("{}", e.description()), @@ -798,7 +800,8 @@ impl Duration { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub fn mul_f64(self, rhs: f64) -> Duration { + #[rustc_const_unstable(feature = "duration_consts_float", issue = "72440")] + pub const fn mul_f64(self, rhs: f64) -> Duration { Duration::from_secs_f64(rhs * self.as_secs_f64()) } @@ -819,7 +822,8 @@ impl Duration { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub fn mul_f32(self, rhs: f32) -> Duration { + #[rustc_const_unstable(feature = "duration_consts_float", issue = "72440")] + pub const fn mul_f32(self, rhs: f32) -> Duration { Duration::from_secs_f32(rhs * self.as_secs_f32()) } @@ -840,7 +844,8 @@ impl Duration { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub fn div_f64(self, rhs: f64) -> Duration { + #[rustc_const_unstable(feature = "duration_consts_float", issue = "72440")] + pub const fn div_f64(self, rhs: f64) -> Duration { Duration::from_secs_f64(self.as_secs_f64() / rhs) } @@ -863,7 +868,8 @@ impl Duration { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub fn div_f32(self, rhs: f32) -> Duration { + #[rustc_const_unstable(feature = "duration_consts_float", issue = "72440")] + pub const fn div_f32(self, rhs: f32) -> Duration { Duration::from_secs_f32(self.as_secs_f32() / rhs) } @@ -1383,7 +1389,7 @@ impl Duration { /// ``` #[unstable(feature = "duration_checked_float", issue = "83400")] #[inline] - pub fn try_from_secs_f32(secs: f32) -> Result { + pub const fn try_from_secs_f32(secs: f32) -> Result { try_from_secs!( secs = secs, mantissa_bits = 23, @@ -1461,7 +1467,7 @@ impl Duration { /// ``` #[unstable(feature = "duration_checked_float", issue = "83400")] #[inline] - pub fn try_from_secs_f64(secs: f64) -> Result { + pub const fn try_from_secs_f64(secs: f64) -> Result { try_from_secs!( secs = secs, mantissa_bits = 52, From 25be7a4567fc41d7063d2b7630492bfe2e16f347 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Tue, 21 Jun 2022 19:03:31 +1000 Subject: [PATCH 48/51] attempt to fix std ice --- compiler/rustc_typeck/src/check/mod.rs | 2 +- compiler/rustc_typeck/src/check/op.rs | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_typeck/src/check/mod.rs b/compiler/rustc_typeck/src/check/mod.rs index dee58791cec18..45d89f3a18d46 100644 --- a/compiler/rustc_typeck/src/check/mod.rs +++ b/compiler/rustc_typeck/src/check/mod.rs @@ -963,7 +963,7 @@ fn has_expected_num_generic_args<'tcx>( ) -> bool { trait_did.map_or(true, |trait_did| { let generics = tcx.generics_of(trait_did); - generics.count() == expected + if generics.has_self { 1 } else { 0 } + generics.count() == expected + if generics.has_self { 1 } else { 0 } + if generics.has_constness { 1 } else { 0 } }) } diff --git a/compiler/rustc_typeck/src/check/op.rs b/compiler/rustc_typeck/src/check/op.rs index 0887c27ea360c..982e46240d477 100644 --- a/compiler/rustc_typeck/src/check/op.rs +++ b/compiler/rustc_typeck/src/check/op.rs @@ -859,6 +859,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.lookup_op_method_in_trait(span, opname, trait_did, lhs_ty, other_ty, other_ty_expr) }); + debug!("lookup_op_method(method={method:?}"); + match (method, trait_did) { (Some(ok), _) => { let method = self.register_infer_ok_obligations(ok); From 4f50485d6c1499e47dd0d6bc58add37d249fbd15 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Sun, 26 Jun 2022 09:37:05 +0000 Subject: [PATCH 49/51] More attempts to fix ICE --- compiler/rustc_infer/src/infer/equate.rs | 6 ++++-- compiler/rustc_middle/src/ty/context.rs | 9 +++++++++ compiler/rustc_middle/src/ty/generics.rs | 11 +++++++++++ compiler/rustc_middle/src/ty/print/pretty.rs | 14 +++++++++----- compiler/rustc_middle/src/ty/subst.rs | 4 ++-- compiler/rustc_typeck/src/astconv/mod.rs | 6 +++++- compiler/rustc_typeck/src/check/method/confirm.rs | 2 +- compiler/rustc_typeck/src/check/method/mod.rs | 2 +- compiler/rustc_typeck/src/check/method/probe.rs | 5 ++--- compiler/rustc_typeck/src/check/mod.rs | 5 ++++- compiler/rustc_typeck/src/collect.rs | 6 +++--- library/core/src/ops/function.rs | 1 + library/core/src/slice/index.rs | 1 + 13 files changed, 53 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_infer/src/infer/equate.rs b/compiler/rustc_infer/src/infer/equate.rs index 712cdd603f88b..033e9a7224c4b 100644 --- a/compiler/rustc_infer/src/infer/equate.rs +++ b/compiler/rustc_infer/src/infer/equate.rs @@ -166,8 +166,10 @@ impl<'tcx> TypeRelation<'tcx> for Equate<'_, '_, 'tcx> { a: ty::ConstnessArg, b: ty::ConstnessArg, ) -> RelateResult<'tcx, ty::ConstnessArg> { - // TODO handle infer - relate::super_relate_constness(self, a, b) + match (a, b) { + (ty::ConstnessArg::Infer, x) | (x, ty::ConstnessArg::Infer) => Ok(x), + _ => relate::super_relate_constness(self, a, b), + } } } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 7b3c2b11685d3..5d9d6f8df3fc4 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2964,6 +2964,15 @@ impl<'tcx> TyCtxt<'tcx> { }) ) } + + pub fn should_have_constness(self, def_id: DefId) -> bool { + match self.def_kind(def_id) { + DefKind::Trait => true, + DefKind::Impl if self.constness(def_id) == hir::Constness::Const => true, + DefKind::AssocFn => self.should_have_constness(self.parent(def_id)), + _ => false, + } + } } impl<'tcx> TyCtxtAt<'tcx> { diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs index db8b71355cfd7..b102f3ab076cb 100644 --- a/compiler/rustc_middle/src/ty/generics.rs +++ b/compiler/rustc_middle/src/ty/generics.rs @@ -123,6 +123,7 @@ pub struct Generics { pub has_self: bool, pub has_constness: bool, + pub parent_has_constness: bool, pub has_late_bound_regions: Option, } @@ -240,6 +241,7 @@ impl<'tcx> Generics { } /// Returns the `ConstnessArg` + // TODO just use self.has_constness? pub fn has_constness_param(&'tcx self) -> bool { self.params.iter().any(|param| matches!(param.kind, ty::GenericParamDefKind::Constness)) } @@ -295,6 +297,15 @@ impl<'tcx> Generics { let own = &substs[self.parent_count..][..self.params.len()]; if self.has_self && self.parent.is_none() { &own[1..] } else { &own } } + + /*pub fn expected_arg_count(&self) -> std::ops::RangeInclusive { + self.count() + todo!() + }*/ + + pub fn expected_parent_count(&self) -> std::ops::RangeInclusive { + self.parent_count..=self.parent_count + self.parent_has_constness as usize + } } /// Bounds on generics. diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 084caa722c614..3e66355ba3c93 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1824,11 +1824,15 @@ impl<'tcx> Printer<'tcx> for FmtPrinter<'_, 'tcx> { GenericArgKind::Lifetime(r) => !r.is_erased(), _ => false, }); - let mut args = args.iter().cloned().filter(|arg| match arg.unpack() { - GenericArgKind::Lifetime(_) => print_regions, - GenericArgKind::Constness(_) => false, - _ => true, - }).peekable(); + let mut args = args + .iter() + .cloned() + .filter(|arg| match arg.unpack() { + GenericArgKind::Lifetime(_) => print_regions, + GenericArgKind::Constness(_) => false, + _ => true, + }) + .peekable(); if args.peek().is_some() { if self.in_value { diff --git a/compiler/rustc_middle/src/ty/subst.rs b/compiler/rustc_middle/src/ty/subst.rs index 20eb1eefa2252..e65740c61ceb8 100644 --- a/compiler/rustc_middle/src/ty/subst.rs +++ b/compiler/rustc_middle/src/ty/subst.rs @@ -580,8 +580,8 @@ impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> { _ => { let msg = format!( "Region parameter out of range \ - when substituting in region {} (index={})", - data.name, data.index + when substituting in region {} (index={}, substs={:?})", + data.name, data.index, self.substs ); span_bug!(DUMMY_SP, "{}", msg); } diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index b729c9f8f7fa4..24d9f4d429b34 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -376,7 +376,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // non-`Self` generic parameters. if generics.params.is_empty() { return ( - tcx.intern_substs(&constness.map(Into::into).into_iter().collect::>()), + tcx.intern_substs(&if let Some(ty::ConstnessArg::Const) = constness { + vec![ty::ConstnessArg::Const.into()] + } else { + vec![] + }), arg_count, ); } diff --git a/compiler/rustc_typeck/src/check/method/confirm.rs b/compiler/rustc_typeck/src/check/method/confirm.rs index c02b76657e6c2..971246d399e98 100644 --- a/compiler/rustc_typeck/src/check/method/confirm.rs +++ b/compiler/rustc_typeck/src/check/method/confirm.rs @@ -345,7 +345,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { // Create subst for early-bound lifetime parameters, combining // parameters from the type and those from the method. - assert_eq!(generics.parent_count, parent_substs.len()); + assert!(generics.expected_parent_count().contains(&parent_substs.len())); struct MethodSubstsCtxt<'a, 'tcx> { cfcx: &'a ConfirmContext<'a, 'tcx>, diff --git a/compiler/rustc_typeck/src/check/method/mod.rs b/compiler/rustc_typeck/src/check/method/mod.rs index d4573b7aac0ad..d3e7607c263d3 100644 --- a/compiler/rustc_typeck/src/check/method/mod.rs +++ b/compiler/rustc_typeck/src/check/method/mod.rs @@ -454,7 +454,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; let def_id = method_item.def_id; let generics = tcx.generics_of(def_id); - assert_eq!(generics.params.len(), generics.has_constness as usize); // no generics except for constness + assert!(generics.params.len() <= generics.has_constness as usize); // no generics except for constness debug!("lookup_in_trait_adjusted: method_item={:?}", method_item); let mut obligations = vec![]; diff --git a/compiler/rustc_typeck/src/check/method/probe.rs b/compiler/rustc_typeck/src/check/method/probe.rs index 42c69f0d491d3..ac5929e62aa59 100644 --- a/compiler/rustc_typeck/src/check/method/probe.rs +++ b/compiler/rustc_typeck/src/check/method/probe.rs @@ -1783,9 +1783,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { // method yet. So create fresh variables here for those too, // if there are any. let generics = self.tcx.generics_of(method); - assert_eq!( - substs.len(), - generics.parent_count as usize, + assert!( + generics.expected_parent_count().contains(&substs.len()), "substs: {:#?}\ngenerics: {:#?}", substs, generics diff --git a/compiler/rustc_typeck/src/check/mod.rs b/compiler/rustc_typeck/src/check/mod.rs index 45d89f3a18d46..ac3dc149e2936 100644 --- a/compiler/rustc_typeck/src/check/mod.rs +++ b/compiler/rustc_typeck/src/check/mod.rs @@ -963,7 +963,10 @@ fn has_expected_num_generic_args<'tcx>( ) -> bool { trait_did.map_or(true, |trait_did| { let generics = tcx.generics_of(trait_did); - generics.count() == expected + if generics.has_self { 1 } else { 0 } + if generics.has_constness { 1 } else { 0 } + generics.count() + == expected + + if generics.has_self { 1 } else { 0 } + + if generics.has_constness { 1 } else { 0 } }) } diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 4ec70ad70a3fa..1bcecf7aec89d 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -1519,6 +1519,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics { param_def_id_to_index, has_self: generics.has_self, has_constness: generics.has_constness, + parent_has_constness: generics.parent_has_constness, has_late_bound_regions: generics.has_late_bound_regions, }; } @@ -1624,9 +1625,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics { }; let has_self = opt_self.is_some(); - let has_constness = tcx.has_attr(def_id, sym::const_trait) - || (tcx.def_kind(def_id) == DefKind::Impl - && tcx.impl_constness(def_id) == hir::Constness::Const); + let has_constness = tcx.should_have_constness(def_id); let mut parent_has_self = false; let mut parent_has_constness = false; let mut own_start = has_self as u32; @@ -1783,6 +1782,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics { param_def_id_to_index, has_self: has_self || parent_has_self, has_constness: has_constness || parent_has_constness, + parent_has_constness: parent_has_constness, has_late_bound_regions: has_late_bound_regions(tcx, node), }; trace!("{:#?}", generics); diff --git a/library/core/src/ops/function.rs b/library/core/src/ops/function.rs index c5a194b7d0a41..63e11980d3924 100644 --- a/library/core/src/ops/function.rs +++ b/library/core/src/ops/function.rs @@ -237,6 +237,7 @@ pub trait FnMut: FnOnce { )] #[fundamental] // so that regex can rely that `&str: !FnMut` #[must_use = "closures are lazy and do nothing unless called"] +#[cfg_attr(not(bootstrap), const_trait)] pub trait FnOnce { /// The returned type after the call operator is used. #[lang = "fn_once_output"] diff --git a/library/core/src/slice/index.rs b/library/core/src/slice/index.rs index fd7ecf3daf316..234c5ac98c41e 100644 --- a/library/core/src/slice/index.rs +++ b/library/core/src/slice/index.rs @@ -152,6 +152,7 @@ mod private_slice_index { message = "the type `{T}` cannot be indexed by `{Self}`", label = "slice indices are of type `usize` or ranges of `usize`" )] +#[cfg_attr(not(bootstrap), const_trait)] pub unsafe trait SliceIndex: private_slice_index::Sealed { /// The output type returned by methods. #[stable(feature = "slice_get_slice", since = "1.28.0")] From 4845b3546a3ae1a62fa23211255f6f5375389443 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Wed, 13 Jul 2022 17:34:24 +0000 Subject: [PATCH 50/51] general fixes --- compiler/rustc_middle/src/ty/impls_ty.rs | 1 - compiler/rustc_middle/src/ty/mod.rs | 1 - 2 files changed, 2 deletions(-) diff --git a/compiler/rustc_middle/src/ty/impls_ty.rs b/compiler/rustc_middle/src/ty/impls_ty.rs index a76578b09d765..43db77b03339d 100644 --- a/compiler/rustc_middle/src/ty/impls_ty.rs +++ b/compiler/rustc_middle/src/ty/impls_ty.rs @@ -99,7 +99,6 @@ impl<'a, 'tcx> HashStable> for ty::subst::GenericArgKin } ty::subst::GenericArgKind::Constness(constness) => { 0xFFu8.hash_stable(hcx, hasher); - mem::discriminant(self).hash_stable(hcx, hasher); constness.hash_stable(hcx, hasher); } } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index b52ec657fc8c0..f9d38260d1100 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -329,7 +329,6 @@ impl fmt::Display for ConstnessArg { #[derive(Clone, Debug, PartialEq, Eq, Copy, Hash, TyEncodable, TyDecodable, HashStable)] #[derive(TypeFoldable, TypeVisitable)] ->>>>>>> Add new generic param pub struct ClosureSizeProfileData<'tcx> { /// Tuple containing the types of closure captures before the feature `capture_disjoint_fields` pub before_feature_tys: Ty<'tcx>, From b8bbee6273192809396aa4a0cbbdb4a9e5301dea Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Fri, 15 Jul 2022 06:31:52 +0000 Subject: [PATCH 51/51] fixup --- compiler/rustc_infer/src/infer/mod.rs | 4 ++-- .../rustc_infer/src/infer/outlives/test_type_match.rs | 9 +++++++++ compiler/rustc_middle/src/mir/interpret/queries.rs | 5 ++--- compiler/rustc_middle/src/ty/visit.rs | 4 ++++ 4 files changed, 17 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 20b5c8d43e014..6e763f8189509 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -1155,7 +1155,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { self.next_region_var_in_universe(RegionVariableOrigin::Nll(origin), universe) } - pub fn var_for_def(&self, span: Span, param: &ty::GenericParamDef) -> GenericArg<'tcx> { + pub fn var_for_def(&self, span: Span, param: &ty::GenericParamDef, constness: Option) -> GenericArg<'tcx> { match param.kind { GenericParamDefKind::Lifetime => { // Create a region inference variable for the given @@ -1206,7 +1206,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { /// Given a set of generics defined on a type or impl, returns a substitution mapping each /// type/region parameter to a fresh inference variable. pub fn fresh_substs_for_item(&self, span: Span, def_id: DefId) -> SubstsRef<'tcx> { - InternalSubsts::for_item(self.tcx, def_id, |param, _| self.var_for_def(span, param)) + InternalSubsts::for_item(self.tcx, def_id, |param, _| self.var_for_def(span, param, None)) } /// Returns `true` if errors have been reported since this infcx was diff --git a/compiler/rustc_infer/src/infer/outlives/test_type_match.rs b/compiler/rustc_infer/src/infer/outlives/test_type_match.rs index 772e297b7b445..1f13828eb99a9 100644 --- a/compiler/rustc_infer/src/infer/outlives/test_type_match.rs +++ b/compiler/rustc_infer/src/infer/outlives/test_type_match.rs @@ -204,4 +204,13 @@ impl<'tcx> TypeRelation<'tcx> for Match<'tcx> { self.pattern_depth.shift_out(1); result } + + fn constness_args( + &mut self, + a: ty::ConstnessArg, + b: ty::ConstnessArg, + ) -> RelateResult<'tcx, ty::ConstnessArg> { + // TODO + relate::super_relate_constness(self, a, b) + } } diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs index 8f6be48e563a7..07fb341cd5612 100644 --- a/compiler/rustc_middle/src/mir/interpret/queries.rs +++ b/compiler/rustc_middle/src/mir/interpret/queries.rs @@ -180,8 +180,7 @@ impl<'tcx> TyCtxtEnsure<'tcx> { let substs = InternalSubsts::identity_for_item(self.tcx, def_id); let instance = ty::Instance::new(def_id, substs); let cid = GlobalId { instance, promoted: None }; - let param_env = - self.tcx.param_env(def_id).with_reveal_all_normalized(self.tcx).with_const(); + let param_env = self.tcx.param_env(def_id).with_reveal_all_normalized(self.tcx); // Const-eval shouldn't depend on lifetimes at all, so we can erase them, which should // improve caching of queries. let inputs = self.tcx.erase_regions(param_env.and(cid)); @@ -194,7 +193,7 @@ impl<'tcx> TyCtxtEnsure<'tcx> { assert!(self.tcx.is_static(def_id)); let instance = ty::Instance::mono(self.tcx, def_id); let gid = GlobalId { instance, promoted: None }; - let param_env = ty::ParamEnv::reveal_all().with_const(); + let param_env = ty::ParamEnv::reveal_all(); trace!("eval_to_allocation: Need to compute {:?}", gid); self.eval_to_allocation_raw(param_env.and(gid)) } diff --git a/compiler/rustc_middle/src/ty/visit.rs b/compiler/rustc_middle/src/ty/visit.rs index 5365067209af9..9b2bf3d353de9 100644 --- a/compiler/rustc_middle/src/ty/visit.rs +++ b/compiler/rustc_middle/src/ty/visit.rs @@ -210,6 +210,10 @@ pub trait TypeVisitor<'tcx>: Sized { fn visit_mir_const(&mut self, c: mir::ConstantKind<'tcx>) -> ControlFlow { c.super_visit_with(self) } + + fn visit_constness_arg(&mut self, c: ty::ConstnessArg) -> ControlFlow { + c.super_visit_with(self) + } } ///////////////////////////////////////////////////////////////////////////