From 0a61bc4d36e737cb6dca3d3953985a5ad469387d Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Thu, 1 Jun 2023 03:27:16 +0900 Subject: [PATCH 01/12] Support 128-bit atomics on all x86_64 Apple targets --- compiler/rustc_target/src/spec/x86_64_apple_ios.rs | 2 +- compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs | 2 +- compiler/rustc_target/src/spec/x86_64_apple_tvos.rs | 2 +- compiler/rustc_target/src/spec/x86_64_apple_watchos_sim.rs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_target/src/spec/x86_64_apple_ios.rs b/compiler/rustc_target/src/spec/x86_64_apple_ios.rs index 1dcb47056a463..061b6a96fc888 100644 --- a/compiler/rustc_target/src/spec/x86_64_apple_ios.rs +++ b/compiler/rustc_target/src/spec/x86_64_apple_ios.rs @@ -13,7 +13,7 @@ pub fn target() -> Target { .into(), arch: arch.target_arch(), options: TargetOptions { - max_atomic_width: Some(64), + max_atomic_width: Some(128), stack_probes: StackProbeType::X86, ..base }, diff --git a/compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs b/compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs index 9f3b0fab697e6..50f359c357bdf 100644 --- a/compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs +++ b/compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs @@ -15,7 +15,7 @@ pub fn target() -> Target { .into(), arch: arch.target_arch(), options: TargetOptions { - max_atomic_width: Some(64), + max_atomic_width: Some(128), stack_probes: StackProbeType::X86, ..base }, diff --git a/compiler/rustc_target/src/spec/x86_64_apple_tvos.rs b/compiler/rustc_target/src/spec/x86_64_apple_tvos.rs index 550ce0b9ce577..76de7d20c4c6f 100644 --- a/compiler/rustc_target/src/spec/x86_64_apple_tvos.rs +++ b/compiler/rustc_target/src/spec/x86_64_apple_tvos.rs @@ -9,7 +9,7 @@ pub fn target() -> Target { data_layout: "e-m:o-i64:64-f80:128-n8:16:32:64-S128".into(), arch: arch.target_arch(), options: TargetOptions { - max_atomic_width: Some(64), + max_atomic_width: Some(128), stack_probes: StackProbeType::X86, ..opts("tvos", arch) }, diff --git a/compiler/rustc_target/src/spec/x86_64_apple_watchos_sim.rs b/compiler/rustc_target/src/spec/x86_64_apple_watchos_sim.rs index 75ce02cba1de0..5fcc00a86ff95 100644 --- a/compiler/rustc_target/src/spec/x86_64_apple_watchos_sim.rs +++ b/compiler/rustc_target/src/spec/x86_64_apple_watchos_sim.rs @@ -10,7 +10,7 @@ pub fn target() -> Target { .into(), arch: arch.target_arch(), options: TargetOptions { - max_atomic_width: Some(64), + max_atomic_width: Some(128), stack_probes: StackProbeType::X86, forces_embed_bitcode: true, // Taken from a clang build on Xcode 11.4.1. From bbf41279fad5bf1604b9cf3f9575c76a00254114 Mon Sep 17 00:00:00 2001 From: Boxy Date: Tue, 16 May 2023 19:58:54 +0100 Subject: [PATCH 02/12] Require that const param tys implement ConstParamTy --- .../rustc_hir_analysis/src/check/wfcheck.rs | 91 +++---------------- library/core/src/mem/transmutability.rs | 5 + 2 files changed, 19 insertions(+), 77 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index fff417fcb2909..5a5a405d9e7a8 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -829,83 +829,20 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) { let ty = tcx.type_of(param.def_id).subst_identity(); if tcx.features().adt_const_params { - if let Some(non_structural_match_ty) = - traits::search_for_adt_const_param_violation(param.span, tcx, ty) - { - // We use the same error code in both branches, because this is really the same - // issue: we just special-case the message for type parameters to make it - // clearer. - match non_structural_match_ty.kind() { - ty::Param(_) => { - // Const parameters may not have type parameters as their types, - // because we cannot be sure that the type parameter derives `PartialEq` - // and `Eq` (just implementing them is not enough for `structural_match`). - struct_span_err!( - tcx.sess, - hir_ty.span, - E0741, - "`{ty}` is not guaranteed to `#[derive(PartialEq, Eq)]`, so may not be \ - used as the type of a const parameter", - ) - .span_label( - hir_ty.span, - format!("`{ty}` may not derive both `PartialEq` and `Eq`"), - ) - .note( - "it is not currently possible to use a type parameter as the type of a \ - const parameter", - ) - .emit(); - } - ty::Float(_) => { - struct_span_err!( - tcx.sess, - hir_ty.span, - E0741, - "`{ty}` is forbidden as the type of a const generic parameter", - ) - .note("floats do not derive `Eq` or `Ord`, which are required for const parameters") - .emit(); - } - ty::FnPtr(_) => { - struct_span_err!( - tcx.sess, - hir_ty.span, - E0741, - "using function pointers as const generic parameters is forbidden", - ) - .emit(); - } - ty::RawPtr(_) => { - struct_span_err!( - tcx.sess, - hir_ty.span, - E0741, - "using raw pointers as const generic parameters is forbidden", - ) - .emit(); - } - _ => { - let mut diag = struct_span_err!( - tcx.sess, - hir_ty.span, - E0741, - "`{}` must be annotated with `#[derive(PartialEq, Eq)]` to be used as \ - the type of a const parameter", - non_structural_match_ty, - ); - - if ty == non_structural_match_ty { - diag.span_label( - hir_ty.span, - format!("`{ty}` doesn't derive both `PartialEq` and `Eq`"), - ); - } - - diag.emit(); - } - } - } + enter_wf_checking_ctxt(tcx, hir_ty.span, param.def_id, |wfcx| { + let trait_def_id = + tcx.require_lang_item(LangItem::ConstParamTy, Some(hir_ty.span)); + wfcx.register_bound( + ObligationCause::new( + hir_ty.span, + param.def_id, + ObligationCauseCode::WellFormed(Some(hir_ty.span)), + ), + wfcx.param_env, + ty, + trait_def_id, + ); + }); } else { let err_ty_str; let mut is_ptr = true; diff --git a/library/core/src/mem/transmutability.rs b/library/core/src/mem/transmutability.rs index 87ae30619c63b..a6f792ed0e3e9 100644 --- a/library/core/src/mem/transmutability.rs +++ b/library/core/src/mem/transmutability.rs @@ -1,3 +1,5 @@ +use crate::marker::ConstParamTy; + /// Are values of a type transmutable into values of another type? /// /// This trait is implemented on-the-fly by the compiler for types `Src` and `Self` when the bits of @@ -33,6 +35,9 @@ pub struct Assume { pub validity: bool, } +#[unstable(feature = "transmutability", issue = "99571")] +impl ConstParamTy for Assume {} + impl Assume { /// Do not assume that *you* have ensured any safety properties are met. #[unstable(feature = "transmutability", issue = "99571")] From 8ab10bacdf6ea55c594252062f80b7e931d93d7c Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 17 May 2023 18:51:45 +0000 Subject: [PATCH 03/12] remove search_for_adt_const_param_violation --- .../rustc_trait_selection/src/traits/mod.rs | 4 +- .../src/traits/structural_match.rs | 70 +++++-------------- 2 files changed, 19 insertions(+), 55 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index f7389bda159e5..c2f94cb638566 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -62,9 +62,7 @@ pub use self::specialize::specialization_graph::FutureCompatOverlapErrorKind; pub use self::specialize::{ specialization_graph, translate_substs, translate_substs_with_cause, OverlapError, }; -pub use self::structural_match::{ - search_for_adt_const_param_violation, search_for_structural_match_violation, -}; +pub use self::structural_match::search_for_structural_match_violation; pub use self::structural_normalize::StructurallyNormalizeExt; pub use self::util::elaborate; pub use self::util::{expand_trait_aliases, TraitAliasExpander}; diff --git a/compiler/rustc_trait_selection/src/traits/structural_match.rs b/compiler/rustc_trait_selection/src/traits/structural_match.rs index e38ae9381c1d7..420f8c5dceb50 100644 --- a/compiler/rustc_trait_selection/src/traits/structural_match.rs +++ b/compiler/rustc_trait_selection/src/traits/structural_match.rs @@ -34,24 +34,7 @@ pub fn search_for_structural_match_violation<'tcx>( tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, ) -> Option> { - ty.visit_with(&mut Search { tcx, span, seen: FxHashSet::default(), adt_const_param: false }) - .break_value() -} - -/// This method traverses the structure of `ty`, trying to find any -/// types that are not allowed to be used in a const generic. -/// -/// This is either because the type does not implement `StructuralEq` -/// and `StructuralPartialEq`, or because the type is intentionally -/// not supported in const generics (such as floats and raw pointers, -/// which are allowed in match blocks). -pub fn search_for_adt_const_param_violation<'tcx>( - span: Span, - tcx: TyCtxt<'tcx>, - ty: Ty<'tcx>, -) -> Option> { - ty.visit_with(&mut Search { tcx, span, seen: FxHashSet::default(), adt_const_param: true }) - .break_value() + ty.visit_with(&mut Search { tcx, span, seen: FxHashSet::default() }).break_value() } /// This implements the traversal over the structure of a given type to try to @@ -65,11 +48,6 @@ struct Search<'tcx> { /// Tracks ADTs previously encountered during search, so that /// we will not recur on them again. seen: FxHashSet, - - // Additionally deny things that have been allowed in patterns, - // but are not allowed in adt const params, such as floats and - // fn ptrs. - adt_const_param: bool, } impl<'tcx> Search<'tcx> { @@ -124,41 +102,29 @@ impl<'tcx> TypeVisitor> for Search<'tcx> { } ty::FnPtr(..) => { - if !self.adt_const_param { - return ControlFlow::Continue(()); - } else { - return ControlFlow::Break(ty); - } + return ControlFlow::Continue(()); } ty::RawPtr(..) => { - if !self.adt_const_param { - // structural-match ignores substructure of - // `*const _`/`*mut _`, so skip `super_visit_with`. - // - // For example, if you have: - // ``` - // struct NonStructural; - // #[derive(PartialEq, Eq)] - // struct T(*const NonStructural); - // const C: T = T(std::ptr::null()); - // ``` - // - // Even though `NonStructural` does not implement `PartialEq`, - // structural equality on `T` does not recur into the raw - // pointer. Therefore, one can still use `C` in a pattern. - return ControlFlow::Continue(()); - } else { - return ControlFlow::Break(ty); - } + // structural-match ignores substructure of + // `*const _`/`*mut _`, so skip `super_visit_with`. + // + // For example, if you have: + // ``` + // struct NonStructural; + // #[derive(PartialEq, Eq)] + // struct T(*const NonStructural); + // const C: T = T(std::ptr::null()); + // ``` + // + // Even though `NonStructural` does not implement `PartialEq`, + // structural equality on `T` does not recur into the raw + // pointer. Therefore, one can still use `C` in a pattern. + return ControlFlow::Continue(()); } ty::Float(_) => { - if !self.adt_const_param { - return ControlFlow::Continue(()); - } else { - return ControlFlow::Break(ty); - } + return ControlFlow::Continue(()); } ty::Array(..) | ty::Slice(_) | ty::Ref(..) | ty::Tuple(..) => { From a9fcb524ffbcccc0c0f56e9ecde431961a4619a9 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 17 May 2023 03:00:19 +0000 Subject: [PATCH 04/12] Impl ConstParamTy for tuples, make PartialStructuralEq a supertrait too --- .../rustc_trait_selection/src/traits/misc.rs | 3 ++- library/core/src/marker.rs | 26 ++++++++++++++++--- library/core/src/tuple.rs | 25 ++++++++++++++++++ .../adt_const_params/const_param_ty_good.rs | 4 ++- .../const_param_ty_impl_no_structural_eq.rs | 2 ++ .../const_param_ty_impl_union.rs | 1 + .../const_param_ty_impl_union.stderr | 14 ++++++++-- 7 files changed, 68 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/misc.rs b/compiler/rustc_trait_selection/src/traits/misc.rs index 2210ef975e6c8..e9cfd63e2eddc 100644 --- a/compiler/rustc_trait_selection/src/traits/misc.rs +++ b/compiler/rustc_trait_selection/src/traits/misc.rs @@ -100,7 +100,8 @@ pub fn type_allowed_to_implement_const_param_ty<'tcx>( | ty::Str | ty::Array(..) | ty::Slice(_) - | ty::Ref(.., hir::Mutability::Not) => return Ok(()), + | ty::Ref(.., hir::Mutability::Not) + | ty::Tuple(_) => return Ok(()), &ty::Adt(adt, substs) => (adt, substs), diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index 2d2d5d4917588..9a541ccaeacbc 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -205,6 +205,20 @@ pub trait StructuralPartialEq { // Empty. } +marker_impls! { + #[unstable(feature = "structural_match", issue = "31434")] + StructuralPartialEq for + usize, u8, u16, u32, u64, u128, + isize, i8, i16, i32, i64, i128, + bool, + char, + str /* Technically requires `[u8]: StructuralEq` */, + (), + {T, const N: usize} [T; N], + {T} [T], + {T: ?Sized} &T, +} + /// Required trait for constants used in pattern matches. /// /// Any type that derives `Eq` automatically implements this trait, *regardless* @@ -267,6 +281,7 @@ marker_impls! { bool, char, str /* Technically requires `[u8]: StructuralEq` */, + (), {T, const N: usize} [T; N], {T} [T], {T: ?Sized} &T, @@ -974,7 +989,8 @@ pub trait PointerLike {} #[lang = "const_param_ty"] #[unstable(feature = "adt_const_params", issue = "95174")] #[rustc_on_unimplemented(message = "`{Self}` can't be used as a const parameter type")] -pub trait ConstParamTy: StructuralEq {} +#[allow(multiple_supertrait_upcastable)] +pub trait ConstParamTy: StructuralEq + StructuralPartialEq {} /// Derive macro generating an impl of the trait `ConstParamTy`. #[rustc_builtin_macro] @@ -983,8 +999,7 @@ pub macro ConstParamTy($item:item) { /* compiler built-in */ } -// FIXME(generic_const_parameter_types): handle `ty::FnDef`/`ty::Closure` -// FIXME(generic_const_parameter_types): handle `ty::Tuple` +// FIXME(adt_const_params): handle `ty::FnDef`/`ty::Closure` marker_impls! { #[unstable(feature = "adt_const_params", issue = "95174")] ConstParamTy for @@ -998,6 +1013,11 @@ marker_impls! { {T: ?Sized + ConstParamTy} &T, } +// FIXME(adt_const_params): Add to marker_impls call above once not in bootstrap +#[unstable(feature = "adt_const_params", issue = "95174")] +#[cfg(not(bootstrap))] +impl ConstParamTy for () {} + /// A common trait implemented by all function pointers. #[unstable( feature = "fn_ptr_trait", diff --git a/library/core/src/tuple.rs b/library/core/src/tuple.rs index a1388dfeee643..ac8d04a82860e 100644 --- a/library/core/src/tuple.rs +++ b/library/core/src/tuple.rs @@ -1,6 +1,9 @@ // See src/libstd/primitive_docs.rs for documentation. use crate::cmp::Ordering::{self, *}; +#[cfg(not(bootstrap))] +use crate::marker::ConstParamTy; +use crate::marker::{StructuralEq, StructuralPartialEq}; // Recursive macro for implementing n-ary tuple functions and operations // @@ -45,6 +48,28 @@ macro_rules! tuple_impls { {} } + maybe_tuple_doc! { + $($T)+ @ + #[unstable(feature = "structural_match", issue = "31434")] + #[cfg(not(bootstrap))] + impl<$($T: ConstParamTy),+> ConstParamTy for ($($T,)+) + {} + } + + maybe_tuple_doc! { + $($T)+ @ + #[unstable(feature = "structural_match", issue = "31434")] + impl<$($T),+> StructuralPartialEq for ($($T,)+) + {} + } + + maybe_tuple_doc! { + $($T)+ @ + #[unstable(feature = "structural_match", issue = "31434")] + impl<$($T),+> StructuralEq for ($($T,)+) + {} + } + maybe_tuple_doc! { $($T)+ @ #[stable(feature = "rust1", since = "1.0.0")] diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_good.rs b/tests/ui/const-generics/adt_const_params/const_param_ty_good.rs index 87ae83dd96603..100ab332a40d8 100644 --- a/tests/ui/const-generics/adt_const_params/const_param_ty_good.rs +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_good.rs @@ -49,5 +49,7 @@ fn main() { check::>(); check::>(); - // FIXME: test tuples + check::<()>(); + check::<(i32,)>(); + check::<(D, D)>(); } diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.rs b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.rs index 37986de481f11..08f7c5cb5423e 100644 --- a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.rs +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.rs @@ -9,9 +9,11 @@ struct CantParam(ImplementsConstParamTy); impl std::marker::ConstParamTy for CantParam {} //~^ error: the type `CantParam` does not `#[derive(Eq)]` +//~| error: the type `CantParam` does not `#[derive(PartialEq)]` #[derive(std::marker::ConstParamTy)] //~^ error: the type `CantParamDerive` does not `#[derive(Eq)]` +//~| error: the type `CantParamDerive` does not `#[derive(PartialEq)]` struct CantParamDerive(ImplementsConstParamTy); fn check() {} diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_union.rs b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_union.rs index d70377a20c170..c04e96c569b41 100644 --- a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_union.rs +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_union.rs @@ -14,6 +14,7 @@ impl Eq for Union {} impl std::marker::StructuralEq for Union {} impl std::marker::ConstParamTy for Union {} +//~^ ERROR the type `Union` does not `#[derive(PartialEq)]` #[derive(std::marker::ConstParamTy)] //~^ ERROR this trait cannot be derived for unions diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_union.stderr b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_union.stderr index 2937030460503..985b933c40c79 100644 --- a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_union.stderr +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_union.stderr @@ -1,8 +1,18 @@ error: this trait cannot be derived for unions - --> $DIR/const_param_ty_impl_union.rs:18:10 + --> $DIR/const_param_ty_impl_union.rs:19:10 | LL | #[derive(std::marker::ConstParamTy)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to previous error +error[E0277]: the type `Union` does not `#[derive(PartialEq)]` + --> $DIR/const_param_ty_impl_union.rs:16:36 + | +LL | impl std::marker::ConstParamTy for Union {} + | ^^^^^ the trait `StructuralPartialEq` is not implemented for `Union` + | +note: required by a bound in `ConstParamTy` + --> $SRC_DIR/core/src/marker.rs:LL:COL + +error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0277`. From 847d50453c3e78399b3af193762673a220c23562 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 17 May 2023 04:05:46 +0000 Subject: [PATCH 05/12] Implement custom diagnostic for ConstParamTy --- .../src/error_codes/E0741.md | 12 +- .../rustc_hir_analysis/src/check/wfcheck.rs | 2 +- compiler/rustc_middle/src/traits/mod.rs | 3 + .../src/traits/error_reporting/mod.rs | 110 ++++++++++++++++++ .../src/traits/error_reporting/suggestions.rs | 3 +- .../ui/same_functions_in_if_condition.rs | 4 +- .../ui/same_functions_in_if_condition.stderr | 24 ++-- .../const-generics/hash-tyvid-regression-1.rs | 14 ++- .../const-generics/hash-tyvid-regression-2.rs | 16 ++- .../issue-77708-3.rs | 13 ++- .../const_param_ty_bad.stderr | 20 ++++ ...onst_param_ty_impl_no_structural_eq.stderr | 23 +++- ...const-param-with-additional-obligations.rs | 17 +++ ...t-param-with-additional-obligations.stderr | 11 ++ .../float-generic.adt_const_params.stderr | 2 - .../forbid-non-structural_match-types.rs | 6 +- .../forbid-non-structural_match-types.stderr | 12 +- ...y-size-in-generic-struct-param.full.stderr | 2 +- ...ay-size-in-generic-struct-param.min.stderr | 4 +- .../array-size-in-generic-struct-param.rs | 4 + tests/ui/const-generics/invalid-enum.rs | 4 +- tests/ui/const-generics/invalid-enum.stderr | 14 +-- tests/ui/const-generics/issue-66451.rs | 6 +- tests/ui/const-generics/issue-66451.stderr | 2 +- tests/ui/const-generics/issue-80471.rs | 2 +- tests/ui/const-generics/issue-80471.stderr | 8 +- .../issues/issue-63322-forbid-dyn.full.stderr | 4 +- .../issues/issue-63322-forbid-dyn.rs | 2 +- .../issues/issue-71381.full.stderr | 17 +-- tests/ui/const-generics/issues/issue-71381.rs | 10 +- .../issues/issue-71611.full.stderr | 11 +- tests/ui/const-generics/issues/issue-71611.rs | 4 +- .../issues/issue-74255.min.stderr | 2 +- tests/ui/const-generics/issues/issue-74255.rs | 4 + .../issues/issue-74950.min.stderr | 10 +- tests/ui/const-generics/issues/issue-74950.rs | 3 + tests/ui/const-generics/issues/issue-87076.rs | 4 +- tests/ui/const-generics/issues/issue-97278.rs | 2 +- .../const-generics/issues/issue-97278.stderr | 8 +- tests/ui/const-generics/issues/issue-99641.rs | 4 +- .../const-generics/issues/issue-99641.stderr | 8 +- tests/ui/const-generics/overlapping_impls.rs | 5 +- .../std/const-generics-range.full.stderr | 39 +++++++ .../std/const-generics-range.min.stderr | 12 +- .../std/const-generics-range.rs | 3 +- .../consts/refs_check_const_eq-issue-88384.rs | 4 +- .../refs_check_const_eq-issue-88384.stderr | 16 ++- tests/ui/mir/thir-constparam-temp.rs | 4 +- tests/ui/mir/thir-constparam-temp.stderr | 6 +- .../const-generics-structural-demangling.rs | 25 ++-- ...onst-generics-structural-demangling.stderr | 62 +++++----- 51 files changed, 455 insertions(+), 152 deletions(-) create mode 100644 tests/ui/const-generics/const-param-with-additional-obligations.rs create mode 100644 tests/ui/const-generics/const-param-with-additional-obligations.stderr create mode 100644 tests/ui/const-generics/std/const-generics-range.full.stderr diff --git a/compiler/rustc_error_codes/src/error_codes/E0741.md b/compiler/rustc_error_codes/src/error_codes/E0741.md index 70d963cd41f21..0c7010526655e 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0741.md +++ b/compiler/rustc_error_codes/src/error_codes/E0741.md @@ -10,15 +10,19 @@ struct A; struct B; // error! ``` -Only structural-match types (that is, types that derive `PartialEq` and `Eq`) -may be used as the types of const generic parameters. +Only structural-match types, which are types that derive `PartialEq` and `Eq` +and implement `ConstParamTy`, may be used as the types of const generic +parameters. -To fix the previous code example, we derive `PartialEq` and `Eq`: +To fix the previous code example, we derive `PartialEq`, `Eq`, and +`ConstParamTy`: ``` #![feature(adt_const_params)] -#[derive(PartialEq, Eq)] // We derive both traits here. +use std::marker::ConstParamTy; + +#[derive(PartialEq, Eq, ConstParamTy)] // We derive both traits here. struct A; struct B; // ok! diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 5a5a405d9e7a8..69e32c35ed8d3 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -836,7 +836,7 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) { ObligationCause::new( hir_ty.span, param.def_id, - ObligationCauseCode::WellFormed(Some(hir_ty.span)), + ObligationCauseCode::ConstParam(ty), ), wfcx.param_env, ty, diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index 0a903a76974da..bf3872e81d4a7 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -445,6 +445,9 @@ pub enum ObligationCauseCode<'tcx> { /// Obligations to prove that a `std::ops::Drop` impl is not stronger than /// the ADT it's being implemented for. DropImpl, + + /// Requirement for a `const N: Ty` to implement `Ty: ConstParamTy` + ConstParam(Ty<'tcx>), } /// The 'location' at which we try to perform HIR-based wf checking. 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 1470dc452a18d..01c74be7057c9 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -149,6 +149,12 @@ pub trait TypeErrCtxtExt<'tcx> { root_obligation: &PredicateObligation<'tcx>, error: &SelectionError<'tcx>, ); + + fn report_const_param_not_wf( + &self, + ty: Ty<'tcx>, + obligation: &PredicateObligation<'tcx>, + ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed>; } impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { @@ -641,6 +647,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { span = obligation.cause.span; } } + if let ObligationCauseCode::CompareImplItemObligation { impl_item_def_id, trait_item_def_id, @@ -657,6 +664,13 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { return; } + // Report a const-param specific error + if let ObligationCauseCode::ConstParam(ty) = *obligation.cause.code().peel_derives() + { + self.report_const_param_not_wf(ty, &obligation).emit(); + return; + } + let bound_predicate = obligation.predicate.kind(); match bound_predicate.skip_binder() { ty::PredicateKind::Clause(ty::Clause::Trait(trait_predicate)) => { @@ -1163,6 +1177,102 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { self.point_at_returns_when_relevant(&mut err, &obligation); err.emit(); } + + fn report_const_param_not_wf( + &self, + ty: Ty<'tcx>, + obligation: &PredicateObligation<'tcx>, + ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { + let span = obligation.cause.span; + + let mut diag = match ty.kind() { + _ if ty.has_param() => { + span_bug!(span, "const param tys cannot mention other generic parameters"); + } + ty::Float(_) => { + struct_span_err!( + self.tcx.sess, + span, + E0741, + "`{ty}` is forbidden as the type of a const generic parameter", + ) + } + ty::FnPtr(_) => { + struct_span_err!( + self.tcx.sess, + span, + E0741, + "using function pointers as const generic parameters is forbidden", + ) + } + ty::RawPtr(_) => { + struct_span_err!( + self.tcx.sess, + span, + E0741, + "using raw pointers as const generic parameters is forbidden", + ) + } + ty::Adt(def, _) => { + // We should probably see if we're *allowed* to derive `ConstParamTy` on the type... + let mut diag = struct_span_err!( + self.tcx.sess, + span, + E0741, + "`{ty}` must implement `ConstParamTy` to be used as the type of a const generic parameter", + ); + // Only suggest derive if this isn't a derived obligation, + // and the struct is local. + if let Some(span) = self.tcx.hir().span_if_local(def.did()) + && obligation.cause.code().parent().is_none() + { + if ty.is_structural_eq_shallow(self.tcx) { + diag.span_suggestion( + span, + "add `#[derive(ConstParamTy)]` to the struct", + "#[derive(ConstParamTy)]\n", + Applicability::MachineApplicable, + ); + } else { + // FIXME(adt_const_params): We should check there's not already an + // overlapping `Eq`/`PartialEq` impl. + diag.span_suggestion( + span, + "add `#[derive(ConstParamTy, PartialEq, Eq)]` to the struct", + "#[derive(ConstParamTy, PartialEq, Eq)]\n", + Applicability::MachineApplicable, + ); + } + } + diag + } + _ => { + struct_span_err!( + self.tcx.sess, + span, + E0741, + "`{ty}` can't be used as a const parameter type", + ) + } + }; + + let mut code = obligation.cause.code(); + let mut pred = obligation.predicate.to_opt_poly_trait_pred(); + while let Some((next_code, next_pred)) = code.parent() { + if let Some(pred) = pred { + let pred = self.instantiate_binder_with_placeholders(pred); + diag.note(format!( + "`{}` must implement `{}`, but it does not", + pred.self_ty(), + pred.print_modifiers_and_trait_path() + )); + } + code = next_code; + pred = next_pred; + } + + diag + } } trait InferCtxtPrivExt<'tcx> { 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 b5b8c7fe3ac56..204d6fd043b3c 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -2655,7 +2655,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { | ObligationCauseCode::BinOp { .. } | ObligationCauseCode::AscribeUserTypeProvePredicate(..) | ObligationCauseCode::RustCall - | ObligationCauseCode::DropImpl => {} + | ObligationCauseCode::DropImpl + | ObligationCauseCode::ConstParam(_) => {} ObligationCauseCode::SliceOrArrayElem => { err.note("slice and array elements must have `Sized` type"); } diff --git a/src/tools/clippy/tests/ui/same_functions_in_if_condition.rs b/src/tools/clippy/tests/ui/same_functions_in_if_condition.rs index aea1507cc5bd9..08916398cbb28 100644 --- a/src/tools/clippy/tests/ui/same_functions_in_if_condition.rs +++ b/src/tools/clippy/tests/ui/same_functions_in_if_condition.rs @@ -10,6 +10,8 @@ clippy::uninlined_format_args )] +use std::marker::ConstParamTy; + fn function() -> bool { true } @@ -96,7 +98,7 @@ fn main() { }; println!("{}", os); - #[derive(PartialEq, Eq)] + #[derive(PartialEq, Eq, ConstParamTy)] enum E { A, B, diff --git a/src/tools/clippy/tests/ui/same_functions_in_if_condition.stderr b/src/tools/clippy/tests/ui/same_functions_in_if_condition.stderr index aade3b1fa4571..6aacc73b90dc1 100644 --- a/src/tools/clippy/tests/ui/same_functions_in_if_condition.stderr +++ b/src/tools/clippy/tests/ui/same_functions_in_if_condition.stderr @@ -1,11 +1,11 @@ error: this `if` has the same function call as a previous `if` - --> $DIR/same_functions_in_if_condition.rs:37:15 + --> $DIR/same_functions_in_if_condition.rs:39:15 | LL | } else if function() { | ^^^^^^^^^^ | note: same as this - --> $DIR/same_functions_in_if_condition.rs:36:8 + --> $DIR/same_functions_in_if_condition.rs:38:8 | LL | if function() { | ^^^^^^^^^^ @@ -16,61 +16,61 @@ LL | #![deny(clippy::same_functions_in_if_condition)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this `if` has the same function call as a previous `if` - --> $DIR/same_functions_in_if_condition.rs:42:15 + --> $DIR/same_functions_in_if_condition.rs:44:15 | LL | } else if fn_arg(a) { | ^^^^^^^^^ | note: same as this - --> $DIR/same_functions_in_if_condition.rs:41:8 + --> $DIR/same_functions_in_if_condition.rs:43:8 | LL | if fn_arg(a) { | ^^^^^^^^^ error: this `if` has the same function call as a previous `if` - --> $DIR/same_functions_in_if_condition.rs:47:15 + --> $DIR/same_functions_in_if_condition.rs:49:15 | LL | } else if obj.method() { | ^^^^^^^^^^^^ | note: same as this - --> $DIR/same_functions_in_if_condition.rs:46:8 + --> $DIR/same_functions_in_if_condition.rs:48:8 | LL | if obj.method() { | ^^^^^^^^^^^^ error: this `if` has the same function call as a previous `if` - --> $DIR/same_functions_in_if_condition.rs:52:15 + --> $DIR/same_functions_in_if_condition.rs:54:15 | LL | } else if obj.method_arg(a) { | ^^^^^^^^^^^^^^^^^ | note: same as this - --> $DIR/same_functions_in_if_condition.rs:51:8 + --> $DIR/same_functions_in_if_condition.rs:53:8 | LL | if obj.method_arg(a) { | ^^^^^^^^^^^^^^^^^ error: this `if` has the same function call as a previous `if` - --> $DIR/same_functions_in_if_condition.rs:59:15 + --> $DIR/same_functions_in_if_condition.rs:61:15 | LL | } else if v.pop().is_none() { | ^^^^^^^^^^^^^^^^^ | note: same as this - --> $DIR/same_functions_in_if_condition.rs:57:8 + --> $DIR/same_functions_in_if_condition.rs:59:8 | LL | if v.pop().is_none() { | ^^^^^^^^^^^^^^^^^ error: this `if` has the same function call as a previous `if` - --> $DIR/same_functions_in_if_condition.rs:64:15 + --> $DIR/same_functions_in_if_condition.rs:66:15 | LL | } else if v.len() == 42 { | ^^^^^^^^^^^^^ | note: same as this - --> $DIR/same_functions_in_if_condition.rs:62:8 + --> $DIR/same_functions_in_if_condition.rs:64:8 | LL | if v.len() == 42 { | ^^^^^^^^^^^^^ diff --git a/tests/incremental/const-generics/hash-tyvid-regression-1.rs b/tests/incremental/const-generics/hash-tyvid-regression-1.rs index 5ff7b19d8945e..06d674234510a 100644 --- a/tests/incremental/const-generics/hash-tyvid-regression-1.rs +++ b/tests/incremental/const-generics/hash-tyvid-regression-1.rs @@ -1,8 +1,20 @@ // revisions: cfail #![feature(generic_const_exprs, adt_const_params)] #![allow(incomplete_features)] + +use std::marker::ConstParamTy; + +#[derive(PartialEq, Eq, ConstParamTy)] +struct NonZeroUsize(usize); + +impl NonZeroUsize { + const fn get(self) -> usize { + self.0 + } +} + // regression test for #77650 -fn c() +fn c() where [T; N.get()]: Sized, { diff --git a/tests/incremental/const-generics/hash-tyvid-regression-2.rs b/tests/incremental/const-generics/hash-tyvid-regression-2.rs index 5cdd43cd782c4..33f226ff611e8 100644 --- a/tests/incremental/const-generics/hash-tyvid-regression-2.rs +++ b/tests/incremental/const-generics/hash-tyvid-regression-2.rs @@ -1,11 +1,23 @@ // revisions: cfail #![feature(generic_const_exprs, adt_const_params)] #![allow(incomplete_features)] + +use std::marker::ConstParamTy; + +#[derive(PartialEq, Eq, ConstParamTy)] +struct NonZeroUsize(usize); + +impl NonZeroUsize { + const fn get(self) -> usize { + self.0 + } +} + // regression test for #77650 -struct C([T; N.get()]) +struct C([T; N.get()]) where [T; N.get()]: Sized; -impl<'a, const N: core::num::NonZeroUsize, A, B: PartialEq> PartialEq<&'a [A]> for C +impl<'a, const N: NonZeroUsize, A, B: PartialEq> PartialEq<&'a [A]> for C where [B; N.get()]: Sized, { diff --git a/tests/incremental/const-generics/try_unify_abstract_const_regression_tests/issue-77708-3.rs b/tests/incremental/const-generics/try_unify_abstract_const_regression_tests/issue-77708-3.rs index fc114f224a2fa..f1c108fed11ba 100644 --- a/tests/incremental/const-generics/try_unify_abstract_const_regression_tests/issue-77708-3.rs +++ b/tests/incremental/const-generics/try_unify_abstract_const_regression_tests/issue-77708-3.rs @@ -2,7 +2,18 @@ #![feature(generic_const_exprs, adt_const_params)] #![allow(incomplete_features)] -use std::{convert::TryFrom, num::NonZeroUsize}; +use std::{convert::TryFrom}; + +use std::marker::ConstParamTy; + +#[derive(PartialEq, Eq, ConstParamTy)] +struct NonZeroUsize(usize); + +impl NonZeroUsize { + const fn get(self) -> usize { + self.0 + } +} struct A([u8; N.get()]) where diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_bad.stderr b/tests/ui/const-generics/adt_const_params/const_param_ty_bad.stderr index de5704ee429ed..48910b82a1032 100644 --- a/tests/ui/const-generics/adt_const_params/const_param_ty_bad.stderr +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_bad.stderr @@ -11,6 +11,10 @@ note: required by a bound in `check` | LL | fn check(_: impl std::marker::ConstParamTy) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `check` +help: use parentheses to call this function + | +LL | check(main()); + | ++ error[E0277]: `[closure@$DIR/const_param_ty_bad.rs:8:11: 8:13]` can't be used as a const parameter type --> $DIR/const_param_ty_bad.rs:8:11 @@ -25,6 +29,10 @@ note: required by a bound in `check` | LL | fn check(_: impl std::marker::ConstParamTy) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `check` +help: use parentheses to call this closure + | +LL | check(|| {}()); + | ++ error[E0277]: `fn()` can't be used as a const parameter type --> $DIR/const_param_ty_bad.rs:9:11 @@ -39,6 +47,10 @@ note: required by a bound in `check` | LL | fn check(_: impl std::marker::ConstParamTy) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `check` +help: use parentheses to call this function pointer + | +LL | check(main as fn()()); + | ++ error[E0277]: `&mut ()` can't be used as a const parameter type --> $DIR/const_param_ty_bad.rs:10:11 @@ -48,11 +60,17 @@ LL | check(&mut ()); | | | required by a bound introduced by this call | + = note: `ConstParamTy` is implemented for `&()`, but not for `&mut ()` note: required by a bound in `check` --> $DIR/const_param_ty_bad.rs:4:18 | LL | fn check(_: impl std::marker::ConstParamTy) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `check` +help: consider removing the leading `&`-reference + | +LL - check(&mut ()); +LL + check(()); + | error[E0277]: `*mut ()` can't be used as a const parameter type --> $DIR/const_param_ty_bad.rs:11:11 @@ -62,6 +80,7 @@ LL | check(&mut () as *mut ()); | | | required by a bound introduced by this call | + = help: the trait `ConstParamTy` is implemented for `()` note: required by a bound in `check` --> $DIR/const_param_ty_bad.rs:4:18 | @@ -76,6 +95,7 @@ LL | check(&() as *const ()); | | | required by a bound introduced by this call | + = help: the trait `ConstParamTy` is implemented for `()` note: required by a bound in `check` --> $DIR/const_param_ty_bad.rs:4:18 | diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.stderr b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.stderr index 52701d5591442..43c5b96dc7cb8 100644 --- a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.stderr +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.stderr @@ -1,3 +1,12 @@ +error[E0277]: the type `CantParam` does not `#[derive(PartialEq)]` + --> $DIR/const_param_ty_impl_no_structural_eq.rs:10:36 + | +LL | impl std::marker::ConstParamTy for CantParam {} + | ^^^^^^^^^ the trait `StructuralPartialEq` is not implemented for `CantParam` + | +note: required by a bound in `ConstParamTy` + --> $SRC_DIR/core/src/marker.rs:LL:COL + error[E0277]: the type `CantParam` does not `#[derive(Eq)]` --> $DIR/const_param_ty_impl_no_structural_eq.rs:10:36 | @@ -7,8 +16,18 @@ LL | impl std::marker::ConstParamTy for CantParam {} note: required by a bound in `ConstParamTy` --> $SRC_DIR/core/src/marker.rs:LL:COL +error[E0277]: the type `CantParamDerive` does not `#[derive(PartialEq)]` + --> $DIR/const_param_ty_impl_no_structural_eq.rs:14:10 + | +LL | #[derive(std::marker::ConstParamTy)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `StructuralPartialEq` is not implemented for `CantParamDerive` + | +note: required by a bound in `ConstParamTy` + --> $SRC_DIR/core/src/marker.rs:LL:COL + = note: this error originates in the derive macro `std::marker::ConstParamTy` (in Nightly builds, run with -Z macro-backtrace for more info) + error[E0277]: the type `CantParamDerive` does not `#[derive(Eq)]` - --> $DIR/const_param_ty_impl_no_structural_eq.rs:13:10 + --> $DIR/const_param_ty_impl_no_structural_eq.rs:14:10 | LL | #[derive(std::marker::ConstParamTy)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `StructuralEq` is not implemented for `CantParamDerive` @@ -17,6 +36,6 @@ note: required by a bound in `ConstParamTy` --> $SRC_DIR/core/src/marker.rs:LL:COL = note: this error originates in the derive macro `std::marker::ConstParamTy` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 2 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/const-generics/const-param-with-additional-obligations.rs b/tests/ui/const-generics/const-param-with-additional-obligations.rs new file mode 100644 index 0000000000000..f53cf85cdd39c --- /dev/null +++ b/tests/ui/const-generics/const-param-with-additional-obligations.rs @@ -0,0 +1,17 @@ +#![feature(adt_const_params)] +#![allow(incomplete_features)] + +use std::marker::ConstParamTy; + +#[derive(Eq, PartialEq)] +struct Foo(T); + +trait Other {} + +impl ConstParamTy for Foo where T: Other + ConstParamTy {} + +fn foo>() {} +//~^ ERROR `Foo` must implement `ConstParamTy` to be used as the type of a const generic parameter +//~| NOTE `u8` must implement `Other`, but it does not + +fn main() {} diff --git a/tests/ui/const-generics/const-param-with-additional-obligations.stderr b/tests/ui/const-generics/const-param-with-additional-obligations.stderr new file mode 100644 index 0000000000000..f7ec4d57401c1 --- /dev/null +++ b/tests/ui/const-generics/const-param-with-additional-obligations.stderr @@ -0,0 +1,11 @@ +error[E0741]: `Foo` must implement `ConstParamTy` to be used as the type of a const generic parameter + --> $DIR/const-param-with-additional-obligations.rs:13:17 + | +LL | fn foo>() {} + | ^^^^^^^ + | + = note: `u8` must implement `Other`, but it does not + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0741`. diff --git a/tests/ui/const-generics/float-generic.adt_const_params.stderr b/tests/ui/const-generics/float-generic.adt_const_params.stderr index fef5ef0d1facf..6fe5390471ddc 100644 --- a/tests/ui/const-generics/float-generic.adt_const_params.stderr +++ b/tests/ui/const-generics/float-generic.adt_const_params.stderr @@ -3,8 +3,6 @@ error[E0741]: `f32` is forbidden as the type of a const generic parameter | LL | fn foo() {} | ^^^ - | - = note: floats do not derive `Eq` or `Ord`, which are required for const parameters error: aborting due to previous error diff --git a/tests/ui/const-generics/forbid-non-structural_match-types.rs b/tests/ui/const-generics/forbid-non-structural_match-types.rs index 6ae9d5cfbb54f..4fec2a9f32f81 100644 --- a/tests/ui/const-generics/forbid-non-structural_match-types.rs +++ b/tests/ui/const-generics/forbid-non-structural_match-types.rs @@ -1,13 +1,15 @@ #![feature(adt_const_params)] #![allow(incomplete_features)] -#[derive(PartialEq, Eq)] +use std::marker::ConstParamTy; + +#[derive(PartialEq, Eq, ConstParamTy)] struct A; struct B; // ok struct C; -struct D; //~ ERROR `C` must be annotated with `#[derive(PartialEq, Eq)]` +struct D; //~ ERROR `C` must implement `ConstParamTy` to be used as the type of a const generic parameter fn main() {} diff --git a/tests/ui/const-generics/forbid-non-structural_match-types.stderr b/tests/ui/const-generics/forbid-non-structural_match-types.stderr index 81b9bdfbd6027..0efb9e9d3c287 100644 --- a/tests/ui/const-generics/forbid-non-structural_match-types.stderr +++ b/tests/ui/const-generics/forbid-non-structural_match-types.stderr @@ -1,8 +1,14 @@ -error[E0741]: `C` must be annotated with `#[derive(PartialEq, Eq)]` to be used as the type of a const parameter - --> $DIR/forbid-non-structural_match-types.rs:11:19 +error[E0741]: `C` must implement `ConstParamTy` to be used as the type of a const generic parameter + --> $DIR/forbid-non-structural_match-types.rs:13:19 | LL | struct D; - | ^ `C` doesn't derive both `PartialEq` and `Eq` + | ^ + | +help: add `#[derive(ConstParamTy, PartialEq, Eq)]` to the struct + | +LL + #[derive(ConstParamTy, PartialEq, Eq)] +LL | struct C; + | error: aborting due to previous error diff --git a/tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.full.stderr b/tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.full.stderr index 1d10dfdf10c6e..c478718b4cc79 100644 --- a/tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.full.stderr +++ b/tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.full.stderr @@ -7,7 +7,7 @@ LL | struct ArithArrayLen([u32; 0 + N]); = help: try adding a `where` bound using this expression: `where [(); 0 + N]:` error: overly complex generic constant - --> $DIR/array-size-in-generic-struct-param.rs:19:15 + --> $DIR/array-size-in-generic-struct-param.rs:23:15 | LL | arr: [u8; CFG.arr_size], | ^^^^^^^^^^^^ field access is not supported in generic constants diff --git a/tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.min.stderr b/tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.min.stderr index 18e9135d07235..956e9c9c988a4 100644 --- a/tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.min.stderr +++ b/tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.min.stderr @@ -8,7 +8,7 @@ LL | struct ArithArrayLen([u32; 0 + N]); = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/array-size-in-generic-struct-param.rs:19:15 + --> $DIR/array-size-in-generic-struct-param.rs:23:15 | LL | arr: [u8; CFG.arr_size], | ^^^ cannot perform const operation using `CFG` @@ -17,7 +17,7 @@ LL | arr: [u8; CFG.arr_size], = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions error: `Config` is forbidden as the type of a const generic parameter - --> $DIR/array-size-in-generic-struct-param.rs:17:21 + --> $DIR/array-size-in-generic-struct-param.rs:21:21 | LL | struct B { | ^^^^^^ diff --git a/tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.rs b/tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.rs index 7d3fe413c1706..33ca6dcb3049c 100644 --- a/tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.rs +++ b/tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.rs @@ -9,7 +9,11 @@ struct ArithArrayLen([u32; 0 + N]); //[full]~^ ERROR unconstrained generic constant //[min]~^^ ERROR generic parameters may not be used in const operations +#[cfg(full)] +use std::marker::ConstParamTy; + #[derive(PartialEq, Eq)] +#[cfg_attr(full, derive(ConstParamTy))] struct Config { arr_size: usize, } diff --git a/tests/ui/const-generics/invalid-enum.rs b/tests/ui/const-generics/invalid-enum.rs index cb6d05349db97..fcfad300c44e5 100644 --- a/tests/ui/const-generics/invalid-enum.rs +++ b/tests/ui/const-generics/invalid-enum.rs @@ -1,7 +1,9 @@ #![feature(adt_const_params)] #![allow(incomplete_features)] -#[derive(PartialEq, Eq)] +use std::marker::ConstParamTy; + +#[derive(PartialEq, Eq, ConstParamTy)] enum CompileFlag { A, B, diff --git a/tests/ui/const-generics/invalid-enum.stderr b/tests/ui/const-generics/invalid-enum.stderr index 0d3643f6f899a..7e8a632b34f79 100644 --- a/tests/ui/const-generics/invalid-enum.stderr +++ b/tests/ui/const-generics/invalid-enum.stderr @@ -1,5 +1,5 @@ error[E0573]: expected type, found variant `CompileFlag::A` - --> $DIR/invalid-enum.rs:21:12 + --> $DIR/invalid-enum.rs:23:12 | LL | test_1::(); | ^^^^^^^^^^^^^^ @@ -8,7 +8,7 @@ LL | test_1::(); | help: try using the variant's enum: `CompileFlag` error[E0573]: expected type, found variant `CompileFlag::A` - --> $DIR/invalid-enum.rs:25:15 + --> $DIR/invalid-enum.rs:27:15 | LL | test_2::<_, CompileFlag::A>(0); | ^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | test_2::<_, CompileFlag::A>(0); | help: try using the variant's enum: `CompileFlag` error[E0573]: expected type, found variant `CompileFlag::A` - --> $DIR/invalid-enum.rs:29:18 + --> $DIR/invalid-enum.rs:31:18 | LL | let _: Example = Example { x: 0 }; | ^^^^^^^^^^^^^^ @@ -26,7 +26,7 @@ LL | let _: Example = Example { x: 0 }; | help: try using the variant's enum: `CompileFlag` error[E0747]: unresolved item provided when a constant was expected - --> $DIR/invalid-enum.rs:29:18 + --> $DIR/invalid-enum.rs:31:18 | LL | let _: Example = Example { x: 0 }; | ^^^^^^^^^^^^^^ @@ -37,7 +37,7 @@ LL | let _: Example<{ CompileFlag::A }, _> = Example { x: 0 }; | + + error[E0747]: type provided when a constant was expected - --> $DIR/invalid-enum.rs:33:18 + --> $DIR/invalid-enum.rs:35:18 | LL | let _: Example = Example { x: 0 }; | ^^^^^^^^^^^^^^^^^^^ @@ -48,7 +48,7 @@ LL | let _: Example<{ Example::ASSOC_FLAG }, _> = Example { x: 0 }; | + + error[E0747]: unresolved item provided when a constant was expected - --> $DIR/invalid-enum.rs:21:12 + --> $DIR/invalid-enum.rs:23:12 | LL | test_1::(); | ^^^^^^^^^^^^^^ @@ -59,7 +59,7 @@ LL | test_1::<{ CompileFlag::A }>(); | + + error[E0747]: unresolved item provided when a constant was expected - --> $DIR/invalid-enum.rs:25:15 + --> $DIR/invalid-enum.rs:27:15 | LL | test_2::<_, CompileFlag::A>(0); | ^^^^^^^^^^^^^^ diff --git a/tests/ui/const-generics/issue-66451.rs b/tests/ui/const-generics/issue-66451.rs index 3335f7d598480..c8d5515e98739 100644 --- a/tests/ui/const-generics/issue-66451.rs +++ b/tests/ui/const-generics/issue-66451.rs @@ -1,13 +1,15 @@ #![feature(adt_const_params)] #![allow(incomplete_features)] -#[derive(Debug, PartialEq, Eq)] +use std::marker::ConstParamTy; + +#[derive(Debug, PartialEq, Eq, ConstParamTy)] struct Foo { value: i32, nested: &'static Bar, } -#[derive(Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq, Eq, ConstParamTy)] struct Bar(T); struct Test; diff --git a/tests/ui/const-generics/issue-66451.stderr b/tests/ui/const-generics/issue-66451.stderr index e0cb0b661ff65..946d5148667ec 100644 --- a/tests/ui/const-generics/issue-66451.stderr +++ b/tests/ui/const-generics/issue-66451.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/issue-66451.rs:27:10 + --> $DIR/issue-66451.rs:29:10 | LL | let y: Test<{ | ____________- diff --git a/tests/ui/const-generics/issue-80471.rs b/tests/ui/const-generics/issue-80471.rs index d0af8a5eaa89f..fa6f1fde435a0 100644 --- a/tests/ui/const-generics/issue-80471.rs +++ b/tests/ui/const-generics/issue-80471.rs @@ -8,6 +8,6 @@ enum Nat { } fn foo() {} -//~^ ERROR `Box` must be annotated with `#[derive(PartialEq, Eq)]` to be used as the type of a const parameter +//~^ ERROR `Nat` must implement `ConstParamTy` to be used as the type of a const generic parameter fn main() {} diff --git a/tests/ui/const-generics/issue-80471.stderr b/tests/ui/const-generics/issue-80471.stderr index b89706710bcf2..3b7143de543d7 100644 --- a/tests/ui/const-generics/issue-80471.stderr +++ b/tests/ui/const-generics/issue-80471.stderr @@ -7,11 +7,17 @@ LL | #![feature(adt_const_params)] = note: see issue #95174 for more information = note: `#[warn(incomplete_features)]` on by default -error[E0741]: `Box` must be annotated with `#[derive(PartialEq, Eq)]` to be used as the type of a const parameter +error[E0741]: `Nat` must implement `ConstParamTy` to be used as the type of a const generic parameter --> $DIR/issue-80471.rs:10:17 | LL | fn foo() {} | ^^^ + | +help: add `#[derive(ConstParamTy)]` to the struct + | +LL + #[derive(ConstParamTy)] +LL | enum Nat { + | error: aborting due to previous error; 1 warning emitted diff --git a/tests/ui/const-generics/issues/issue-63322-forbid-dyn.full.stderr b/tests/ui/const-generics/issues/issue-63322-forbid-dyn.full.stderr index 16fabd1e88fd0..e2d8c5ca0e148 100644 --- a/tests/ui/const-generics/issues/issue-63322-forbid-dyn.full.stderr +++ b/tests/ui/const-generics/issues/issue-63322-forbid-dyn.full.stderr @@ -1,8 +1,10 @@ -error[E0741]: `(dyn A + 'static)` must be annotated with `#[derive(PartialEq, Eq)]` to be used as the type of a const parameter +error[E0741]: `&'static (dyn A + 'static)` can't be used as a const parameter type --> $DIR/issue-63322-forbid-dyn.rs:9:18 | LL | fn test() { | ^^^^^^^^^^^^^^ + | + = note: `(dyn A + 'static)` must implement `ConstParamTy`, but it does not error: aborting due to previous error diff --git a/tests/ui/const-generics/issues/issue-63322-forbid-dyn.rs b/tests/ui/const-generics/issues/issue-63322-forbid-dyn.rs index 116c3fcfb2170..8bc35ab3d3795 100644 --- a/tests/ui/const-generics/issues/issue-63322-forbid-dyn.rs +++ b/tests/ui/const-generics/issues/issue-63322-forbid-dyn.rs @@ -7,7 +7,7 @@ struct B; impl A for B {} fn test() { - //[full]~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]` to be used + //[full]~^ ERROR `&'static (dyn A + 'static)` can't be used as a const parameter type //[min]~^^ ERROR `&'static (dyn A + 'static)` is forbidden unimplemented!() } diff --git a/tests/ui/const-generics/issues/issue-71381.full.stderr b/tests/ui/const-generics/issues/issue-71381.full.stderr index 962eaf75b98f5..b6460e0017fa5 100644 --- a/tests/ui/const-generics/issues/issue-71381.full.stderr +++ b/tests/ui/const-generics/issues/issue-71381.full.stderr @@ -14,19 +14,6 @@ LL | const FN: unsafe extern "C" fn(Args), | = note: type parameters may not be used in the type of const parameters -error[E0741]: using function pointers as const generic parameters is forbidden - --> $DIR/issue-71381.rs:14:61 - | -LL | pub fn call_me(&self) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error[E0741]: using function pointers as const generic parameters is forbidden - --> $DIR/issue-71381.rs:23:19 - | -LL | const FN: unsafe extern "C" fn(Args), - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 4 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0741, E0770. -For more information about an error, try `rustc --explain E0741`. +For more information about this error, try `rustc --explain E0770`. diff --git a/tests/ui/const-generics/issues/issue-71381.rs b/tests/ui/const-generics/issues/issue-71381.rs index 66f819dbe06e2..8a878efb42a0e 100644 --- a/tests/ui/const-generics/issues/issue-71381.rs +++ b/tests/ui/const-generics/issues/issue-71381.rs @@ -12,8 +12,8 @@ unsafe extern "C" fn pass(args: PassArg) { impl Test { pub fn call_me(&self) { - //~^ ERROR: using function pointers as const generic parameters is forbidden - //~| ERROR: the type of const parameters must not depend on other generic parameters + //[min]~^ ERROR: using function pointers as const generic parameters is forbidden + //~^^ ERROR: the type of const parameters must not depend on other generic parameters self.0 = Self::trampiline:: as _ } @@ -21,8 +21,8 @@ impl Test { Args: Sized, const IDX: usize, const FN: unsafe extern "C" fn(Args), - //~^ ERROR: using function pointers as const generic parameters is forbidden - //~| ERROR: the type of const parameters must not depend on other generic parameters + //[min]~^ ERROR: using function pointers as const generic parameters is forbidden + //~^^ ERROR: the type of const parameters must not depend on other generic parameters >( args: Args, ) { @@ -31,6 +31,6 @@ impl Test { } fn main() { - let x = Test(); + let x = Test(std::ptr::null()); x.call_me::() } diff --git a/tests/ui/const-generics/issues/issue-71611.full.stderr b/tests/ui/const-generics/issues/issue-71611.full.stderr index e109459f2be6f..b55f410a02370 100644 --- a/tests/ui/const-generics/issues/issue-71611.full.stderr +++ b/tests/ui/const-generics/issues/issue-71611.full.stderr @@ -6,13 +6,6 @@ LL | fn func(outer: A) { | = note: type parameters may not be used in the type of const parameters -error[E0741]: using function pointers as const generic parameters is forbidden - --> $DIR/issue-71611.rs:5:21 - | -LL | fn func(outer: A) { - | ^^^^^^^^^^^^ - -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0741, E0770. -For more information about an error, try `rustc --explain E0741`. +For more information about this error, try `rustc --explain E0770`. diff --git a/tests/ui/const-generics/issues/issue-71611.rs b/tests/ui/const-generics/issues/issue-71611.rs index fbb91ca18aa4f..c917f66818bad 100644 --- a/tests/ui/const-generics/issues/issue-71611.rs +++ b/tests/ui/const-generics/issues/issue-71611.rs @@ -3,8 +3,8 @@ #![cfg_attr(full, allow(incomplete_features))] fn func(outer: A) { - //~^ ERROR: using function pointers as const generic parameters is forbidden - //~| ERROR: the type of const parameters must not depend on other generic parameters + //[min]~^ ERROR: using function pointers as const generic parameters is forbidden + //~^^ ERROR: the type of const parameters must not depend on other generic parameters F(outer); } diff --git a/tests/ui/const-generics/issues/issue-74255.min.stderr b/tests/ui/const-generics/issues/issue-74255.min.stderr index b462d84487ee8..bbcf8682b7119 100644 --- a/tests/ui/const-generics/issues/issue-74255.min.stderr +++ b/tests/ui/const-generics/issues/issue-74255.min.stderr @@ -1,5 +1,5 @@ error: `IceEnum` is forbidden as the type of a const generic parameter - --> $DIR/issue-74255.rs:14:31 + --> $DIR/issue-74255.rs:18:31 | LL | fn ice_struct_fn() {} | ^^^^^^^ diff --git a/tests/ui/const-generics/issues/issue-74255.rs b/tests/ui/const-generics/issues/issue-74255.rs index 0e523926fb0b1..60b2fd37c44f6 100644 --- a/tests/ui/const-generics/issues/issue-74255.rs +++ b/tests/ui/const-generics/issues/issue-74255.rs @@ -3,7 +3,11 @@ #![cfg_attr(full, feature(adt_const_params))] #![cfg_attr(full, allow(incomplete_features))] +#[cfg(full)] +use std::marker::ConstParamTy; + #[derive(PartialEq, Eq)] +#[cfg_attr(full, derive(ConstParamTy))] enum IceEnum { Variant } diff --git a/tests/ui/const-generics/issues/issue-74950.min.stderr b/tests/ui/const-generics/issues/issue-74950.min.stderr index 729ecc2022c99..c37ee93d420fd 100644 --- a/tests/ui/const-generics/issues/issue-74950.min.stderr +++ b/tests/ui/const-generics/issues/issue-74950.min.stderr @@ -1,5 +1,5 @@ error: `Inner` is forbidden as the type of a const generic parameter - --> $DIR/issue-74950.rs:17:23 + --> $DIR/issue-74950.rs:20:23 | LL | struct Outer; | ^^^^^ @@ -8,7 +8,7 @@ LL | struct Outer; = help: more complex types are supported with `#![feature(adt_const_params)]` error: `Inner` is forbidden as the type of a const generic parameter - --> $DIR/issue-74950.rs:17:23 + --> $DIR/issue-74950.rs:20:23 | LL | struct Outer; | ^^^^^ @@ -17,7 +17,7 @@ LL | struct Outer; = help: more complex types are supported with `#![feature(adt_const_params)]` error: `Inner` is forbidden as the type of a const generic parameter - --> $DIR/issue-74950.rs:17:23 + --> $DIR/issue-74950.rs:20:23 | LL | struct Outer; | ^^^^^ @@ -26,7 +26,7 @@ LL | struct Outer; = help: more complex types are supported with `#![feature(adt_const_params)]` error: `Inner` is forbidden as the type of a const generic parameter - --> $DIR/issue-74950.rs:17:23 + --> $DIR/issue-74950.rs:20:23 | LL | struct Outer; | ^^^^^ @@ -35,7 +35,7 @@ LL | struct Outer; = help: more complex types are supported with `#![feature(adt_const_params)]` error: `Inner` is forbidden as the type of a const generic parameter - --> $DIR/issue-74950.rs:17:23 + --> $DIR/issue-74950.rs:20:23 | LL | struct Outer; | ^^^^^ diff --git a/tests/ui/const-generics/issues/issue-74950.rs b/tests/ui/const-generics/issues/issue-74950.rs index 3e1ca4735db61..43bb322656b3e 100644 --- a/tests/ui/const-generics/issues/issue-74950.rs +++ b/tests/ui/const-generics/issues/issue-74950.rs @@ -3,8 +3,11 @@ #![cfg_attr(full, feature(adt_const_params))] #![cfg_attr(full, allow(incomplete_features))] +#[cfg(full)] +use std::marker::ConstParamTy; #[derive(PartialEq, Eq)] +#[cfg_attr(full, derive(ConstParamTy))] struct Inner; // Note: We emit the error 5 times if we don't deduplicate: diff --git a/tests/ui/const-generics/issues/issue-87076.rs b/tests/ui/const-generics/issues/issue-87076.rs index 8a567678b824e..a32c1f965f8b5 100644 --- a/tests/ui/const-generics/issues/issue-87076.rs +++ b/tests/ui/const-generics/issues/issue-87076.rs @@ -3,7 +3,9 @@ #![feature(adt_const_params)] #![allow(incomplete_features)] -#[derive(PartialEq, Eq)] +use std::marker::ConstParamTy; + +#[derive(PartialEq, Eq, ConstParamTy)] pub struct UnitDims { pub time: u8, pub length: u8, diff --git a/tests/ui/const-generics/issues/issue-97278.rs b/tests/ui/const-generics/issues/issue-97278.rs index da0a9776fd40f..8e7a1fcd99597 100644 --- a/tests/ui/const-generics/issues/issue-97278.rs +++ b/tests/ui/const-generics/issues/issue-97278.rs @@ -9,6 +9,6 @@ enum Bar { } fn test() {} -//~^ ERROR `Arc` must be annotated with `#[derive(PartialEq, Eq)]` +//~^ ERROR `Bar` must implement `ConstParamTy` to be used as the type of a const generic parameter fn main() {} diff --git a/tests/ui/const-generics/issues/issue-97278.stderr b/tests/ui/const-generics/issues/issue-97278.stderr index ff13cb505ab9b..31e92f840e189 100644 --- a/tests/ui/const-generics/issues/issue-97278.stderr +++ b/tests/ui/const-generics/issues/issue-97278.stderr @@ -1,8 +1,14 @@ -error[E0741]: `Arc` must be annotated with `#[derive(PartialEq, Eq)]` to be used as the type of a const parameter +error[E0741]: `Bar` must implement `ConstParamTy` to be used as the type of a const generic parameter --> $DIR/issue-97278.rs:11:20 | LL | fn test() {} | ^^^ + | +help: add `#[derive(ConstParamTy)]` to the struct + | +LL + #[derive(ConstParamTy)] +LL | enum Bar { + | error: aborting due to previous error diff --git a/tests/ui/const-generics/issues/issue-99641.rs b/tests/ui/const-generics/issues/issue-99641.rs index fae6d3fc41fb8..dd075a6ad0524 100644 --- a/tests/ui/const-generics/issues/issue-99641.rs +++ b/tests/ui/const-generics/issues/issue-99641.rs @@ -3,10 +3,10 @@ fn main() { pub struct Color; - //~^ ERROR using function pointers + //~^ ERROR `(fn(),)` can't be used as a const parameter type impl Color { - //~^ ERROR using function pointers + //~^ ERROR `(fn(),)` can't be used as a const parameter type pub fn new() -> Self { Color:: } diff --git a/tests/ui/const-generics/issues/issue-99641.stderr b/tests/ui/const-generics/issues/issue-99641.stderr index 349ebba08d53f..800aec3ef2ce7 100644 --- a/tests/ui/const-generics/issues/issue-99641.stderr +++ b/tests/ui/const-generics/issues/issue-99641.stderr @@ -1,14 +1,18 @@ -error[E0741]: using function pointers as const generic parameters is forbidden +error[E0741]: `(fn(),)` can't be used as a const parameter type --> $DIR/issue-99641.rs:5:35 | LL | pub struct Color; | ^^^^^^^ + | + = note: `fn()` must implement `ConstParamTy`, but it does not -error[E0741]: using function pointers as const generic parameters is forbidden +error[E0741]: `(fn(),)` can't be used as a const parameter type --> $DIR/issue-99641.rs:8:23 | LL | impl Color { | ^^^^^^^ + | + = note: `fn()` must implement `ConstParamTy`, but it does not error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/overlapping_impls.rs b/tests/ui/const-generics/overlapping_impls.rs index e599eadd8cf48..2ce6c4a823c37 100644 --- a/tests/ui/const-generics/overlapping_impls.rs +++ b/tests/ui/const-generics/overlapping_impls.rs @@ -2,7 +2,8 @@ #![allow(incomplete_features)] #![feature(adt_const_params)] #![feature(generic_const_exprs)] -use std::marker::PhantomData; + +use std::marker::{ConstParamTy, PhantomData}; struct Foo {} @@ -22,7 +23,7 @@ pub struct Foo2 { _marker: PhantomData, } -#[derive(PartialEq, Eq)] +#[derive(PartialEq, Eq, ConstParamTy)] pub enum Protocol { Variant1, Variant2, diff --git a/tests/ui/const-generics/std/const-generics-range.full.stderr b/tests/ui/const-generics/std/const-generics-range.full.stderr new file mode 100644 index 0000000000000..5bf48ad738587 --- /dev/null +++ b/tests/ui/const-generics/std/const-generics-range.full.stderr @@ -0,0 +1,39 @@ +error[E0741]: `std::ops::Range` must implement `ConstParamTy` to be used as the type of a const generic parameter + --> $DIR/const-generics-range.rs:8:24 + | +LL | struct _Range>; + | ^^^^^^^^^^^^^^^^^^^^^^ + +error[E0741]: `RangeFrom` must implement `ConstParamTy` to be used as the type of a const generic parameter + --> $DIR/const-generics-range.rs:13:28 + | +LL | struct _RangeFrom>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0741]: `RangeFull` must implement `ConstParamTy` to be used as the type of a const generic parameter + --> $DIR/const-generics-range.rs:18:28 + | +LL | struct _RangeFull; + | ^^^^^^^^^^^^^^^^^^^ + +error[E0741]: `RangeInclusive` must implement `ConstParamTy` to be used as the type of a const generic parameter + --> $DIR/const-generics-range.rs:24:33 + | +LL | struct _RangeInclusive>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0741]: `RangeTo` must implement `ConstParamTy` to be used as the type of a const generic parameter + --> $DIR/const-generics-range.rs:29:26 + | +LL | struct _RangeTo>; + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0741]: `RangeToInclusive` must implement `ConstParamTy` to be used as the type of a const generic parameter + --> $DIR/const-generics-range.rs:34:35 + | +LL | struct _RangeToInclusive>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0741`. diff --git a/tests/ui/const-generics/std/const-generics-range.min.stderr b/tests/ui/const-generics/std/const-generics-range.min.stderr index d4b2ad6fd0c7b..53fca6e884a9a 100644 --- a/tests/ui/const-generics/std/const-generics-range.min.stderr +++ b/tests/ui/const-generics/std/const-generics-range.min.stderr @@ -1,5 +1,5 @@ error: `std::ops::Range` is forbidden as the type of a const generic parameter - --> $DIR/const-generics-range.rs:7:24 + --> $DIR/const-generics-range.rs:8:24 | LL | struct _Range>; | ^^^^^^^^^^^^^^^^^^^^^^ @@ -8,7 +8,7 @@ LL | struct _Range>; = help: more complex types are supported with `#![feature(adt_const_params)]` error: `RangeFrom` is forbidden as the type of a const generic parameter - --> $DIR/const-generics-range.rs:12:28 + --> $DIR/const-generics-range.rs:13:28 | LL | struct _RangeFrom>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | struct _RangeFrom>; = help: more complex types are supported with `#![feature(adt_const_params)]` error: `RangeFull` is forbidden as the type of a const generic parameter - --> $DIR/const-generics-range.rs:17:28 + --> $DIR/const-generics-range.rs:18:28 | LL | struct _RangeFull; | ^^^^^^^^^^^^^^^^^^^ @@ -26,7 +26,7 @@ LL | struct _RangeFull; = help: more complex types are supported with `#![feature(adt_const_params)]` error: `RangeInclusive` is forbidden as the type of a const generic parameter - --> $DIR/const-generics-range.rs:23:33 + --> $DIR/const-generics-range.rs:24:33 | LL | struct _RangeInclusive>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -35,7 +35,7 @@ LL | struct _RangeInclusive>; = help: more complex types are supported with `#![feature(adt_const_params)]` error: `RangeTo` is forbidden as the type of a const generic parameter - --> $DIR/const-generics-range.rs:28:26 + --> $DIR/const-generics-range.rs:29:26 | LL | struct _RangeTo>; | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -44,7 +44,7 @@ LL | struct _RangeTo>; = help: more complex types are supported with `#![feature(adt_const_params)]` error: `RangeToInclusive` is forbidden as the type of a const generic parameter - --> $DIR/const-generics-range.rs:33:35 + --> $DIR/const-generics-range.rs:34:35 | LL | struct _RangeToInclusive>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/const-generics/std/const-generics-range.rs b/tests/ui/const-generics/std/const-generics-range.rs index 46c06f312b98f..bda59f3ec4590 100644 --- a/tests/ui/const-generics/std/const-generics-range.rs +++ b/tests/ui/const-generics/std/const-generics-range.rs @@ -1,4 +1,5 @@ -// [full] check-pass +// [full] known-bug: unknown + // revisions: full min #![cfg_attr(full, feature(adt_const_params))] #![cfg_attr(full, allow(incomplete_features))] diff --git a/tests/ui/consts/refs_check_const_eq-issue-88384.rs b/tests/ui/consts/refs_check_const_eq-issue-88384.rs index 1496b28bd3ee6..fb0405b651cc5 100644 --- a/tests/ui/consts/refs_check_const_eq-issue-88384.rs +++ b/tests/ui/consts/refs_check_const_eq-issue-88384.rs @@ -8,10 +8,10 @@ struct CompileTimeSettings{ } struct Foo; -//~^ ERROR using function pointers as const generic parameters is forbidden +//~^ ERROR `CompileTimeSettings` must implement `ConstParamTy` to be used as the type of a const generic parameter impl Foo { - //~^ ERROR using function pointers as const generic parameters is forbidden + //~^ ERROR `CompileTimeSettings` must implement `ConstParamTy` to be used as the type of a const generic parameter fn call_hooks(){ } } diff --git a/tests/ui/consts/refs_check_const_eq-issue-88384.stderr b/tests/ui/consts/refs_check_const_eq-issue-88384.stderr index 3855b5f2a68e0..c490cd053e70e 100644 --- a/tests/ui/consts/refs_check_const_eq-issue-88384.stderr +++ b/tests/ui/consts/refs_check_const_eq-issue-88384.stderr @@ -7,17 +7,29 @@ LL | #![feature(adt_const_params)] = note: see issue #95174 for more information = note: `#[warn(incomplete_features)]` on by default -error[E0741]: using function pointers as const generic parameters is forbidden +error[E0741]: `CompileTimeSettings` must implement `ConstParamTy` to be used as the type of a const generic parameter --> $DIR/refs_check_const_eq-issue-88384.rs:10:21 | LL | struct Foo; | ^^^^^^^^^^^^^^^^^^^ + | +help: add `#[derive(ConstParamTy)]` to the struct + | +LL + #[derive(ConstParamTy)] +LL | struct CompileTimeSettings{ + | -error[E0741]: using function pointers as const generic parameters is forbidden +error[E0741]: `CompileTimeSettings` must implement `ConstParamTy` to be used as the type of a const generic parameter --> $DIR/refs_check_const_eq-issue-88384.rs:13:15 | LL | impl Foo { | ^^^^^^^^^^^^^^^^^^^ + | +help: add `#[derive(ConstParamTy)]` to the struct + | +LL + #[derive(ConstParamTy)] +LL | struct CompileTimeSettings{ + | error: aborting due to 2 previous errors; 1 warning emitted diff --git a/tests/ui/mir/thir-constparam-temp.rs b/tests/ui/mir/thir-constparam-temp.rs index cdc5910b36cfa..7eedc325d60f6 100644 --- a/tests/ui/mir/thir-constparam-temp.rs +++ b/tests/ui/mir/thir-constparam-temp.rs @@ -3,7 +3,9 @@ #![feature(adt_const_params)] #![allow(incomplete_features)] -#[derive(PartialEq, Eq)] +use std::marker::ConstParamTy; + +#[derive(PartialEq, Eq, ConstParamTy)] struct Yikes; impl Yikes { diff --git a/tests/ui/mir/thir-constparam-temp.stderr b/tests/ui/mir/thir-constparam-temp.stderr index b77d67e084f6c..d50747e5434fa 100644 --- a/tests/ui/mir/thir-constparam-temp.stderr +++ b/tests/ui/mir/thir-constparam-temp.stderr @@ -1,5 +1,5 @@ warning: taking a mutable reference to a `const` item - --> $DIR/thir-constparam-temp.rs:14:5 + --> $DIR/thir-constparam-temp.rs:16:5 | LL | YIKES.mut_self() | ^^^^^^^^^^^^^^^^ @@ -7,12 +7,12 @@ LL | YIKES.mut_self() = note: each usage of a `const` item creates a new temporary = note: the mutable reference will refer to this temporary, not the original `const` item note: mutable reference created due to call to this method - --> $DIR/thir-constparam-temp.rs:10:5 + --> $DIR/thir-constparam-temp.rs:12:5 | LL | fn mut_self(&mut self) {} | ^^^^^^^^^^^^^^^^^^^^^^ note: `const` item defined here - --> $DIR/thir-constparam-temp.rs:13:8 + --> $DIR/thir-constparam-temp.rs:15:8 | LL | fn foo() { | ^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/symbol-names/const-generics-structural-demangling.rs b/tests/ui/symbol-names/const-generics-structural-demangling.rs index df09ba494a74f..947fddf3f31b5 100644 --- a/tests/ui/symbol-names/const-generics-structural-demangling.rs +++ b/tests/ui/symbol-names/const-generics-structural-demangling.rs @@ -1,14 +1,13 @@ // build-fail // compile-flags: -C symbol-mangling-version=v0 --crate-name=c -// NOTE(eddyb) we need `core` for `core::option::Option`, normalize away its -// disambiguator hash, which can/should change (including between stage{1,2}). -// normalize-stderr-test: "core\[[0-9a-f]+\]" -> "core[HASH]" // normalize-stderr-test: "c\[[0-9a-f]+\]" -> "c[HASH]" #![feature(adt_const_params, decl_macro, rustc_attrs)] #![allow(incomplete_features)] +use std::marker::ConstParamTy; + pub struct RefByte; #[rustc_symbol_name] @@ -43,25 +42,31 @@ pub struct TupleByteBool; //~| ERROR demangling-alt(>) impl TupleByteBool<{(1, false)}> {} -pub struct OptionUsize>; +#[derive(PartialEq, Eq, ConstParamTy)] +pub enum MyOption { + Some(T), + None, +} + +pub struct OptionUsize>; // HACK(eddyb) the full mangling is only in `.stderr` because we can normalize // the `core` disambiguator hash away there, but not here. #[rustc_symbol_name] //~^ ERROR symbol-name //~| ERROR demangling -//~| ERROR demangling-alt(::None}>>) -impl OptionUsize<{None}> {} +//~| ERROR demangling-alt(::None}>>) +impl OptionUsize<{MyOption::None}> {} // HACK(eddyb) the full mangling is only in `.stderr` because we can normalize // the `core` disambiguator hash away there, but not here. #[rustc_symbol_name] //~^ ERROR symbol-name //~| ERROR demangling -//~| ERROR demangling-alt(::Some(0)}>>) -impl OptionUsize<{Some(0)}> {} +//~| ERROR demangling-alt(::Some(0)}>>) +impl OptionUsize<{MyOption::Some(0)}> {} -#[derive(PartialEq, Eq)] +#[derive(PartialEq, Eq, ConstParamTy)] pub struct Foo { s: &'static str, ch: char, @@ -78,7 +83,7 @@ impl Foo_<{Foo { s: "abc", ch: 'x', slice: &[1, 2, 3] }}> {} // NOTE(eddyb) this tests specifically the use of disambiguators in field names, // using macros 2.0 hygiene to create a `struct` with conflicting field names. macro duplicate_field_name_test($x:ident) { - #[derive(PartialEq, Eq)] + #[derive(PartialEq, Eq, ConstParamTy)] pub struct Bar { $x: u8, x: u16, diff --git a/tests/ui/symbol-names/const-generics-structural-demangling.stderr b/tests/ui/symbol-names/const-generics-structural-demangling.stderr index a4c997477ee79..96dea154d05c0 100644 --- a/tests/ui/symbol-names/const-generics-structural-demangling.stderr +++ b/tests/ui/symbol-names/const-generics-structural-demangling.stderr @@ -1,131 +1,131 @@ error: symbol-name(_RMCsCRATE_HASH_1cINtB_7RefByteKRh7b_E) - --> $DIR/const-generics-structural-demangling.rs:14:1 + --> $DIR/const-generics-structural-demangling.rs:13:1 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(>) - --> $DIR/const-generics-structural-demangling.rs:14:1 + --> $DIR/const-generics-structural-demangling.rs:13:1 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(>) - --> $DIR/const-generics-structural-demangling.rs:14:1 + --> $DIR/const-generics-structural-demangling.rs:13:1 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_RMs_CsCRATE_HASH_1cINtB_6RefZstKRAEE) - --> $DIR/const-generics-structural-demangling.rs:24:1 + --> $DIR/const-generics-structural-demangling.rs:23:1 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(>) - --> $DIR/const-generics-structural-demangling.rs:24:1 + --> $DIR/const-generics-structural-demangling.rs:23:1 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(>) - --> $DIR/const-generics-structural-demangling.rs:24:1 + --> $DIR/const-generics-structural-demangling.rs:23:1 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_RMs0_CsCRATE_HASH_1cINtB_11Array3BytesKAh1_h2_h3_EE) - --> $DIR/const-generics-structural-demangling.rs:32:1 + --> $DIR/const-generics-structural-demangling.rs:31:1 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(>) - --> $DIR/const-generics-structural-demangling.rs:32:1 + --> $DIR/const-generics-structural-demangling.rs:31:1 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(>) - --> $DIR/const-generics-structural-demangling.rs:32:1 + --> $DIR/const-generics-structural-demangling.rs:31:1 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_RMs1_CsCRATE_HASH_1cINtB_13TupleByteBoolKTh1_b0_EE) - --> $DIR/const-generics-structural-demangling.rs:40:1 + --> $DIR/const-generics-structural-demangling.rs:39:1 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(>) - --> $DIR/const-generics-structural-demangling.rs:40:1 + --> $DIR/const-generics-structural-demangling.rs:39:1 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(>) - --> $DIR/const-generics-structural-demangling.rs:40:1 + --> $DIR/const-generics-structural-demangling.rs:39:1 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ -error: symbol-name(_RMs2_CsCRATE_HASH_1cINtB_11OptionUsizeKVNtINtNtCsCRATE_HASH_4core6option6OptionjE4NoneUE) - --> $DIR/const-generics-structural-demangling.rs:50:1 +error: symbol-name(_RMs2_CsCRATE_HASH_1cINtB_11OptionUsizeKVNtINtB_8MyOptionjE4NoneUE) + --> $DIR/const-generics-structural-demangling.rs:55:1 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ -error: demangling(::None}>>) - --> $DIR/const-generics-structural-demangling.rs:50:1 +error: demangling(::None}>>) + --> $DIR/const-generics-structural-demangling.rs:55:1 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ -error: demangling-alt(::None}>>) - --> $DIR/const-generics-structural-demangling.rs:50:1 +error: demangling-alt(::None}>>) + --> $DIR/const-generics-structural-demangling.rs:55:1 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ -error: symbol-name(_RMs3_CsCRATE_HASH_1cINtB_11OptionUsizeKVNtINtNtCsCRATE_HASH_4core6option6OptionjE4SomeTj0_EE) - --> $DIR/const-generics-structural-demangling.rs:58:1 +error: symbol-name(_RMs3_CsCRATE_HASH_1cINtB_11OptionUsizeKVNtINtB_8MyOptionjE4SomeTj0_EE) + --> $DIR/const-generics-structural-demangling.rs:63:1 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ -error: demangling(::Some(0usize)}>>) - --> $DIR/const-generics-structural-demangling.rs:58:1 +error: demangling(::Some(0usize)}>>) + --> $DIR/const-generics-structural-demangling.rs:63:1 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ -error: demangling-alt(::Some(0)}>>) - --> $DIR/const-generics-structural-demangling.rs:58:1 +error: demangling-alt(::Some(0)}>>) + --> $DIR/const-generics-structural-demangling.rs:63:1 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_RMs4_CsCRATE_HASH_1cINtB_4Foo_KVNtB_3FooS1sRe616263_2chc78_5sliceRAh1_h2_h3_EEE) - --> $DIR/const-generics-structural-demangling.rs:72:1 + --> $DIR/const-generics-structural-demangling.rs:77:1 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(>) - --> $DIR/const-generics-structural-demangling.rs:72:1 + --> $DIR/const-generics-structural-demangling.rs:77:1 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(>) - --> $DIR/const-generics-structural-demangling.rs:72:1 + --> $DIR/const-generics-structural-demangling.rs:77:1 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ -error: symbol-name(_RMs9_CsCRATE_HASH_1cINtB_4Bar_KVNtB_3BarS1xh7b_s_1xt1000_EE) - --> $DIR/const-generics-structural-demangling.rs:88:5 +error: symbol-name(_RMsf_CsCRATE_HASH_1cINtB_4Bar_KVNtB_3BarS1xh7b_s_1xt1000_EE) + --> $DIR/const-generics-structural-demangling.rs:93:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ @@ -136,7 +136,7 @@ LL | duplicate_field_name_test!(x); = note: this error originates in the macro `duplicate_field_name_test` (in Nightly builds, run with -Z macro-backtrace for more info) error: demangling(>) - --> $DIR/const-generics-structural-demangling.rs:88:5 + --> $DIR/const-generics-structural-demangling.rs:93:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ @@ -147,7 +147,7 @@ LL | duplicate_field_name_test!(x); = note: this error originates in the macro `duplicate_field_name_test` (in Nightly builds, run with -Z macro-backtrace for more info) error: demangling-alt(>) - --> $DIR/const-generics-structural-demangling.rs:88:5 + --> $DIR/const-generics-structural-demangling.rs:93:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ From 97bacbab57128725887c3c9600bb0ad83ca42e50 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 19 May 2023 22:04:25 +0000 Subject: [PATCH 06/12] Remove adt_const_params usage from compiler --- .../rustc_errors/src/diagnostic_builder.rs | 32 +++++-------------- compiler/rustc_errors/src/lib.rs | 3 +- 2 files changed, 9 insertions(+), 26 deletions(-) diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs index 7d9d0c76450d8..08ff2cfba5c26 100644 --- a/compiler/rustc_errors/src/diagnostic_builder.rs +++ b/compiler/rustc_errors/src/diagnostic_builder.rs @@ -115,36 +115,22 @@ pub trait EmissionGuarantee: Sized { ) -> DiagnosticBuilder<'_, Self>; } -/// Private module for sealing the `IsError` helper trait. -mod sealed_level_is_error { - use crate::Level; - - /// Sealed helper trait for statically checking that a `Level` is an error. - pub(crate) trait IsError {} - - impl IsError<{ Level::Bug }> for () {} - impl IsError<{ Level::DelayedBug }> for () {} - impl IsError<{ Level::Fatal }> for () {} - // NOTE(eddyb) `Level::Error { lint: true }` is also an error, but lints - // don't need error guarantees, as their levels are always dynamic. - impl IsError<{ Level::Error { lint: false } }> for () {} -} - impl<'a> DiagnosticBuilder<'a, ErrorGuaranteed> { /// Convenience function for internal use, clients should use one of the /// `struct_*` methods on [`Handler`]. #[track_caller] - pub(crate) fn new_guaranteeing_error, const L: Level>( + pub(crate) fn new_guaranteeing_error>( handler: &'a Handler, message: M, - ) -> Self - where - (): sealed_level_is_error::IsError, - { + ) -> Self { Self { inner: DiagnosticBuilderInner { state: DiagnosticBuilderState::Emittable(handler), - diagnostic: Box::new(Diagnostic::new_with_code(L, None, message)), + diagnostic: Box::new(Diagnostic::new_with_code( + Level::Error { lint: false }, + None, + message, + )), }, _marker: PhantomData, } @@ -203,9 +189,7 @@ impl EmissionGuarantee for ErrorGuaranteed { handler: &Handler, msg: impl Into, ) -> DiagnosticBuilder<'_, Self> { - DiagnosticBuilder::new_guaranteeing_error::<_, { Level::Error { lint: false } }>( - handler, msg, - ) + DiagnosticBuilder::new_guaranteeing_error(handler, msg) } } diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 6c5f3e62454ab..bf77ed81f9bd0 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -6,7 +6,6 @@ #![feature(array_windows)] #![feature(drain_filter)] #![feature(if_let_guard)] -#![feature(adt_const_params)] #![feature(let_chains)] #![feature(never_type)] #![feature(result_option_inspect)] @@ -845,7 +844,7 @@ impl Handler { &self, msg: impl Into, ) -> DiagnosticBuilder<'_, ErrorGuaranteed> { - DiagnosticBuilder::new_guaranteeing_error::<_, { Level::Error { lint: false } }>(self, msg) + DiagnosticBuilder::new_guaranteeing_error(self, msg) } /// This should only be used by `rustc_middle::lint::struct_lint_level`. Do not use it for hard errors. From 780719b2dcf1f1f229564f026310ca59a108d5e1 Mon Sep 17 00:00:00 2001 From: sladynnunes Date: Sun, 28 May 2023 01:25:54 -0700 Subject: [PATCH 07/12] Migrate to Askama Implemented wrap_item_write Update wrap_item --- src/librustdoc/html/render/print_item.rs | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 62027a3fa1941..394f97930e79d 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -1102,7 +1102,12 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean: ); } -fn item_trait_alias(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean::TraitAlias) { +fn item_trait_alias( + w: &mut impl fmt::Write, + cx: &mut Context<'_>, + it: &clean::Item, + t: &clean::TraitAlias, +) { wrap_item(w, |w| { write!( w, @@ -1112,16 +1117,17 @@ fn item_trait_alias(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: & print_where_clause(&t.generics, cx, 0, Ending::Newline), bounds(&t.bounds, true, cx), attrs = render_attributes_in_pre(it, "", cx.tcx()), - ); + ) + .unwrap(); }); - write!(w, "{}", document(cx, it, None, HeadingOffset::H2)); - + write!(w, "{}", document(cx, it, None, HeadingOffset::H2)).unwrap(); // Render any items associated directly to this alias, as otherwise they // won't be visible anywhere in the docs. It would be nice to also show // associated items from the aliased type (see discussion in #32077), but // we need #14072 to make sense of the generics. write!(w, "{}", render_assoc_items(cx, it, it.item_id.expect_def_id(), AssocItemRender::All)) + .unwrap(); } fn item_opaque_ty(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean::OpaqueTy) { @@ -1666,13 +1672,14 @@ fn bounds(t_bounds: &[clean::GenericBound], trait_alias: bool, cx: &Context<'_>) bounds } -fn wrap_item(w: &mut Buffer, f: F) +fn wrap_item(w: &mut W, f: F) where - F: FnOnce(&mut Buffer), + W: fmt::Write, + F: FnOnce(&mut W), { - w.write_str(r#"
"#);
+    write!(w, r#"
"#).unwrap();
     f(w);
-    w.write_str("
"); + write!(w, "
").unwrap(); } #[derive(PartialEq, Eq)] From 76ff5ec88624ea61ae49b728ce4d382df8fb7fe3 Mon Sep 17 00:00:00 2001 From: Ramon de C Valle Date: Wed, 24 May 2023 15:44:52 +0000 Subject: [PATCH 08/12] CFI: Fix cfi with async: transform_ty: unexpected GeneratorWitness(Binde Fixes #111184 by encoding ty::Generator parent substs only. --- .../src/typeid/typeid_itanium_cxx_abi.rs | 29 +++++++++++++++---- .../issue-111184-generator-witness.rs | 17 +++++++++++ 2 files changed, 41 insertions(+), 5 deletions(-) create mode 100644 tests/ui/sanitize/issue-111184-generator-witness.rs diff --git a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs index da8a16dee8ac7..da3dafedd9b24 100644 --- a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs +++ b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs @@ -608,9 +608,7 @@ fn encode_ty<'tcx>( } // Function types - ty::FnDef(def_id, substs) - | ty::Closure(def_id, substs) - | ty::Generator(def_id, substs, ..) => { + ty::FnDef(def_id, substs) | ty::Closure(def_id, substs) => { // u[IE], where is , // as vendor extended type. let mut s = String::new(); @@ -621,6 +619,23 @@ fn encode_ty<'tcx>( typeid.push_str(&s); } + ty::Generator(def_id, substs, ..) => { + // u[IE], where is , + // as vendor extended type. + let mut s = String::new(); + let name = encode_ty_name(tcx, *def_id); + let _ = write!(s, "u{}{}", name.len(), &name); + // Encode parent substs only + s.push_str(&encode_substs( + tcx, + tcx.mk_substs(substs.as_generator().parent_substs()), + dict, + options, + )); + compress(dict, DictKey::Ty(ty, TyQ::None), &mut s); + typeid.push_str(&s); + } + // Pointer types ty::Ref(region, ty0, ..) => { // [U3mut]u3refIE as vendor extended type qualifier and type @@ -739,7 +754,12 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio let mut ty = ty; match ty.kind() { - ty::Float(..) | ty::Char | ty::Str | ty::Never | ty::Foreign(..) => {} + ty::Float(..) + | ty::Char + | ty::Str + | ty::Never + | ty::Foreign(..) + | ty::GeneratorWitness(..) => {} ty::Bool => { if options.contains(EncodeTyOptions::NORMALIZE_INTEGERS) { @@ -922,7 +942,6 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio ty::Bound(..) | ty::Error(..) - | ty::GeneratorWitness(..) | ty::GeneratorWitnessMIR(..) | ty::Infer(..) | ty::Alias(..) diff --git a/tests/ui/sanitize/issue-111184-generator-witness.rs b/tests/ui/sanitize/issue-111184-generator-witness.rs new file mode 100644 index 0000000000000..8f4118057cec4 --- /dev/null +++ b/tests/ui/sanitize/issue-111184-generator-witness.rs @@ -0,0 +1,17 @@ +// Regression test for issue 111184, where ty::GeneratorWitness were not expected to occur in +// encode_ty and caused the compiler to ICE. +// +// needs-sanitizer-cfi +// compile-flags: -Clto -Ctarget-feature=-crt-static -Zsanitizer=cfi --edition=2021 +// no-prefer-dynamic +// only-x86_64-unknown-linux-gnu +// run-pass + +use std::future::Future; + +async fn foo() {} +fn bar(_: impl Future) {} + +fn main() { + bar(foo()); +} From c625880a416ebea68c956590694cd13bbae53148 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 10 Feb 2023 10:26:24 +1100 Subject: [PATCH 09/12] Improve comments on `TyCtxt` and `GlobalCtxt`. --- compiler/rustc_middle/src/ty/context.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index b05e791211d10..673d09cddf4ab 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -478,6 +478,17 @@ impl<'tcx> TyCtxtFeed<'tcx, LocalDefId> { /// [rustc dev guide] for more details. /// /// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/ty.html +/// +/// An implementation detail: `TyCtxt` is a wrapper type for [GlobalCtxt], +/// which is the struct that actually holds all the data. `TyCtxt` derefs to +/// `GlobalCtxt`, and in practice `TyCtxt` is passed around everywhere, and all +/// operations are done via `TyCtxt`. A `TyCtxt` is obtained for a `GlobalCtxt` +/// by calling `enter` with a closure `f`. That function creates both the +/// `TyCtxt`, and an `ImplicitCtxt` around it that is put into TLS. Within `f`: +/// - The `ImplicitCtxt` is available implicitly via TLS. +/// - The `TyCtxt` is available explicitly via the `tcx` parameter, and also +/// implicitly within the `ImplicitCtxt`. Explicit access is preferred when +/// possible. #[derive(Copy, Clone)] #[rustc_diagnostic_item = "TyCtxt"] #[rustc_pass_by_value] @@ -493,6 +504,7 @@ impl<'tcx> Deref for TyCtxt<'tcx> { } } +/// See [TyCtxt] for details about this type. pub struct GlobalCtxt<'tcx> { pub arena: &'tcx WorkerLocal>, pub hir_arena: &'tcx WorkerLocal>, From 731601ccd1617a9ca4b1fe09fdb5906c2019110b Mon Sep 17 00:00:00 2001 From: clubby789 Date: Fri, 2 Jun 2023 00:41:02 +0000 Subject: [PATCH 10/12] Check tuple elements are `Sized` in `offset_of` --- compiler/rustc_hir_typeck/src/expr.rs | 19 ++++++++++--------- tests/ui/offset-of/offset-of-dst-field.rs | 2 ++ tests/ui/offset-of/offset-of-dst-field.stderr | 19 ++++++++++++++----- tests/ui/offset-of/offset-of-unsized.rs | 3 ++- 4 files changed, 28 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 19ff77d8349aa..5e10add013b05 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -3117,16 +3117,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } ty::Tuple(tys) => { - let fstr = field.as_str(); - - if let Ok(index) = fstr.parse::() { - if fstr == index.to_string() { - if let Some(&field_ty) = tys.get(index) { - field_indices.push(index.into()); - current_container = field_ty; + if let Ok(index) = field.as_str().parse::() + && field.name == sym::integer(index) + { + for ty in tys.iter().take(index + 1) { + self.require_type_is_sized(ty, expr.span, traits::MiscObligation); + } + if let Some(&field_ty) = tys.get(index) { + field_indices.push(index.into()); + current_container = field_ty; - continue; - } + continue; } } } diff --git a/tests/ui/offset-of/offset-of-dst-field.rs b/tests/ui/offset-of/offset-of-dst-field.rs index 3b8dc0b84a460..e393b159e64d5 100644 --- a/tests/ui/offset-of/offset-of-dst-field.rs +++ b/tests/ui/offset-of/offset-of-dst-field.rs @@ -36,6 +36,8 @@ fn main() { offset_of!(Alpha, z); //~ ERROR the size for values of type offset_of!(Beta, z); //~ ERROR the size for values of type offset_of!(Gamma, z); //~ ERROR the size for values of type + offset_of!((u8, dyn Trait), 0); // ok + offset_of!((u8, dyn Trait), 1); //~ ERROR the size for values of type } fn delta() { diff --git a/tests/ui/offset-of/offset-of-dst-field.stderr b/tests/ui/offset-of/offset-of-dst-field.stderr index 128c783d5dd2d..4eaceaa935817 100644 --- a/tests/ui/offset-of/offset-of-dst-field.stderr +++ b/tests/ui/offset-of/offset-of-dst-field.stderr @@ -25,8 +25,17 @@ LL | offset_of!(Gamma, z); = help: the trait `Sized` is not implemented for `Extern` = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info) +error[E0277]: the size for values of type `dyn Trait` cannot be known at compilation time + --> $DIR/offset-of-dst-field.rs:40:5 + | +LL | offset_of!((u8, dyn Trait), 1); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `dyn Trait` + = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info) + error[E0277]: the size for values of type `Extern` cannot be known at compilation time - --> $DIR/offset-of-dst-field.rs:43:5 + --> $DIR/offset-of-dst-field.rs:45:5 | LL | offset_of!(Delta, z); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -35,7 +44,7 @@ LL | offset_of!(Delta, z); = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the size for values of type `dyn Trait` cannot be known at compilation time - --> $DIR/offset-of-dst-field.rs:44:5 + --> $DIR/offset-of-dst-field.rs:46:5 | LL | offset_of!(Delta, z); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -44,7 +53,7 @@ LL | offset_of!(Delta, z); = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the size for values of type `[u8]` cannot be known at compilation time - --> $DIR/offset-of-dst-field.rs:42:5 + --> $DIR/offset-of-dst-field.rs:44:5 | LL | offset_of!(Delta, z); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -58,7 +67,7 @@ LL | struct Alpha { = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the size for values of type `T` cannot be known at compilation time - --> $DIR/offset-of-dst-field.rs:48:5 + --> $DIR/offset-of-dst-field.rs:50:5 | LL | fn generic_with_maybe_sized() -> usize { | - this type parameter needs to be `std::marker::Sized` @@ -72,6 +81,6 @@ LL - fn generic_with_maybe_sized() -> usize { LL + fn generic_with_maybe_sized() -> usize { | -error: aborting due to 7 previous errors +error: aborting due to 8 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/offset-of/offset-of-unsized.rs b/tests/ui/offset-of/offset-of-unsized.rs index 666387e615ef2..49c8328da5c55 100644 --- a/tests/ui/offset-of/offset-of-unsized.rs +++ b/tests/ui/offset-of/offset-of-unsized.rs @@ -1,5 +1,6 @@ // build-pass -// regression test for #112051 +// regression test for #112051, not in `offset-of-dst` as the issue is in codegen, +// and isn't triggered in the presence of typeck errors #![feature(offset_of)] From d722f27684f30e5ada53309608b5ca308ca2e0ce Mon Sep 17 00:00:00 2001 From: clubby789 Date: Fri, 2 Jun 2023 01:29:39 +0000 Subject: [PATCH 11/12] Test invalid tuple field identifiers --- tests/ui/offset-of/offset-of-tuple.rs | 10 ++++++ tests/ui/offset-of/offset-of-tuple.stderr | 37 +++++++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 tests/ui/offset-of/offset-of-tuple.rs create mode 100644 tests/ui/offset-of/offset-of-tuple.stderr diff --git a/tests/ui/offset-of/offset-of-tuple.rs b/tests/ui/offset-of/offset-of-tuple.rs new file mode 100644 index 0000000000000..4077538b77f27 --- /dev/null +++ b/tests/ui/offset-of/offset-of-tuple.rs @@ -0,0 +1,10 @@ +#![feature(offset_of)] +#![feature(builtin_syntax)] + +fn main() { + core::mem::offset_of!((u8, u8), _0); //~ ERROR no field `_0` + core::mem::offset_of!((u8, u8), +1); //~ ERROR no rules expected + core::mem::offset_of!((u8, u8), -1); //~ ERROR no rules expected + builtin # offset_of((u8, u8), _0); //~ ERROR no field `_0` + builtin # offset_of((u8, u8), +1); //~ ERROR expected identifier +} diff --git a/tests/ui/offset-of/offset-of-tuple.stderr b/tests/ui/offset-of/offset-of-tuple.stderr new file mode 100644 index 0000000000000..cc9ce0f34550c --- /dev/null +++ b/tests/ui/offset-of/offset-of-tuple.stderr @@ -0,0 +1,37 @@ +error: expected identifier, found `+` + --> $DIR/offset-of-tuple.rs:9:35 + | +LL | builtin # offset_of((u8, u8), +1); + | ^ expected identifier + +error: no rules expected the token `1` + --> $DIR/offset-of-tuple.rs:6:38 + | +LL | core::mem::offset_of!((u8, u8), +1); + | ^ no rules expected this token in macro call + | + = note: while trying to match sequence start + +error: no rules expected the token `1` + --> $DIR/offset-of-tuple.rs:7:38 + | +LL | core::mem::offset_of!((u8, u8), -1); + | ^ no rules expected this token in macro call + | + = note: while trying to match sequence start + +error[E0609]: no field `_0` on type `(u8, u8)` + --> $DIR/offset-of-tuple.rs:5:37 + | +LL | core::mem::offset_of!((u8, u8), _0); + | ^^ + +error[E0609]: no field `_0` on type `(u8, u8)` + --> $DIR/offset-of-tuple.rs:8:35 + | +LL | builtin # offset_of((u8, u8), _0); + | ^^ + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0609`. From bbfadf067c893c0cbcb86ff9be7e8182220da042 Mon Sep 17 00:00:00 2001 From: cui fliter Date: Thu, 1 Jun 2023 19:44:49 +0800 Subject: [PATCH 12/12] Fix broken link Signed-off-by: cui fliter --- compiler/rustc_target/src/abi/call/x86_64.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_target/src/abi/call/x86_64.rs b/compiler/rustc_target/src/abi/call/x86_64.rs index 9427f27d1b7bb..74ef53915c929 100644 --- a/compiler/rustc_target/src/abi/call/x86_64.rs +++ b/compiler/rustc_target/src/abi/call/x86_64.rs @@ -1,5 +1,5 @@ // The classification code for the x86_64 ABI is taken from the clay language -// https://github.com/jckarter/clay/blob/master/compiler/src/externals.cpp +// https://github.com/jckarter/clay/blob/db0bd2702ab0b6e48965cd85f8859bbd5f60e48e/compiler/externals.cpp use crate::abi::call::{ArgAbi, CastTarget, FnAbi, Reg, RegKind}; use crate::abi::{self, Abi, HasDataLayout, Size, TyAbiInterface, TyAndLayout};