add `const_param_ty_unchecked` gate
diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index 828a163..06f7a83 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -229,6 +229,8 @@ pub fn internal(&self, feature: Symbol) -> bool {
     (internal, cfg_target_has_reliable_f16_f128, "1.88.0", None),
     /// Allows identifying the `compiler_builtins` crate.
     (internal, compiler_builtins, "1.13.0", None),
+    /// Allows skipping `ConstParamTy_` trait implementation checks
+    (internal, const_param_ty_unchecked, "CURRENT_RUSTC_VERSION", None),
     /// Allows writing custom MIR
     (internal, custom_mir, "1.65.0", None),
     /// Implementation details of externally implementable items
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index 460a9d7..f5aae98 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -844,7 +844,12 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &ty::GenericParamDef) -> Result<(), Er
             let span = tcx.def_span(param.def_id);
             let def_id = param.def_id.expect_local();
 
-            if tcx.features().adt_const_params() || tcx.features().min_adt_const_params() {
+            if tcx.features().const_param_ty_unchecked() {
+                enter_wf_checking_ctxt(tcx, tcx.local_parent(def_id), |wfcx| {
+                    wfcx.register_wf_obligation(span, None, ty.into());
+                    Ok(())
+                })
+            } else if tcx.features().adt_const_params() || tcx.features().min_adt_const_params() {
                 enter_wf_checking_ctxt(tcx, tcx.local_parent(def_id), |wfcx| {
                     wfcx.register_bound(
                         ObligationCause::new(span, def_id, ObligationCauseCode::ConstParam(ty)),
@@ -1348,12 +1353,14 @@ pub(super) fn check_type_const<'tcx>(
     let tcx = wfcx.tcx();
     let span = tcx.def_span(def_id);
 
-    wfcx.register_bound(
-        ObligationCause::new(span, def_id, ObligationCauseCode::ConstParam(item_ty)),
-        wfcx.param_env,
-        item_ty,
-        tcx.require_lang_item(LangItem::ConstParamTy, span),
-    );
+    if !tcx.features().const_param_ty_unchecked() {
+        wfcx.register_bound(
+            ObligationCause::new(span, def_id, ObligationCauseCode::ConstParam(item_ty)),
+            wfcx.param_env,
+            item_ty,
+            tcx.require_lang_item(LangItem::ConstParamTy, span),
+        );
+    }
 
     if has_value {
         let raw_ct = tcx.const_of_item(def_id).instantiate_identity();
diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs
index 61453e5..9100d0e 100644
--- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs
@@ -184,6 +184,10 @@ fn visit_implementation_of_const_param_ty(checker: &Checker<'_>) -> Result<(), E
         return Ok(());
     }
 
+    if tcx.features().const_param_ty_unchecked() {
+        return Ok(());
+    }
+
     if !tcx.features().adt_const_params() {
         match *self_type.kind() {
             ty::Adt(adt, _) if adt.is_struct() => {
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 9cd66bc..09025b7 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -679,6 +679,7 @@
         const_panic,
         const_panic_fmt,
         const_param_ty,
+        const_param_ty_unchecked,
         const_precise_live_drops,
         const_ptr_cast,
         const_raw_ptr_deref,
diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs
index 377505e..5dee256 100644
--- a/compiler/rustc_trait_selection/src/traits/wf.rs
+++ b/compiler/rustc_trait_selection/src/traits/wf.rs
@@ -574,6 +574,11 @@ fn nominal_obligations(
         if self.tcx().is_lang_item(def_id, LangItem::Sized) {
             return Default::default();
         }
+        if self.tcx().is_lang_item(def_id, LangItem::ConstParamTy)
+            && self.tcx().features().const_param_ty_unchecked()
+        {
+            return Default::default();
+        }
 
         let predicates = self.tcx().predicates_of(def_id);
         let mut origins = vec![def_id; predicates.predicates.len()];
diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_unchecked-unsupported.rs b/tests/ui/const-generics/adt_const_params/const_param_ty_unchecked-unsupported.rs
new file mode 100644
index 0000000..3d4d7d2
--- /dev/null
+++ b/tests/ui/const-generics/adt_const_params/const_param_ty_unchecked-unsupported.rs
@@ -0,0 +1,19 @@
+//! Ensure we don't allow Vec<[u8]> as const parameter even with
+//! `const_param_ty_unchecked` feature.
+#![allow(incomplete_features)]
+#![feature(adt_const_params, const_param_ty_unchecked, const_param_ty_trait)]
+use std::marker::ConstParamTy_;
+
+struct VectorOfBytes {
+    a: Vec<[u8]>
+    //~^ ERROR: the size for values of type `[u8]` cannot be known at compilation time [E0277]
+}
+impl ConstParamTy_ for VectorOfBytes {}
+
+fn bar<const N: VectorOfBytes>() {}
+fn foo<const N: Vec<[u8]>>() {}
+    //~^ ERROR: the size for values of type `[u8]` cannot be known at compilation time [E0277]
+    //~| ERROR: the size for values of type `[u8]` cannot be known at compilation time [E0277]
+
+
+fn main() {}
diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_unchecked-unsupported.stderr b/tests/ui/const-generics/adt_const_params/const_param_ty_unchecked-unsupported.stderr
new file mode 100644
index 0000000..c24f676
--- /dev/null
+++ b/tests/ui/const-generics/adt_const_params/const_param_ty_unchecked-unsupported.stderr
@@ -0,0 +1,34 @@
+error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
+  --> $DIR/const_param_ty_unchecked-unsupported.rs:8:8
+   |
+LL |     a: Vec<[u8]>
+   |        ^^^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `[u8]`
+note: required by an implicit `Sized` bound in `Vec`
+  --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
+
+error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
+  --> $DIR/const_param_ty_unchecked-unsupported.rs:14:8
+   |
+LL | fn foo<const N: Vec<[u8]>>() {}
+   |        ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `[u8]`
+note: required by an implicit `Sized` bound in `Vec`
+  --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
+
+error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
+  --> $DIR/const_param_ty_unchecked-unsupported.rs:14:8
+   |
+LL | fn foo<const N: Vec<[u8]>>() {}
+   |        ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `[u8]`
+note: required by an implicit `Sized` bound in `Vec`
+  --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_unchecked.rs b/tests/ui/const-generics/adt_const_params/const_param_ty_unchecked.rs
new file mode 100644
index 0000000..b3f69fc
--- /dev/null
+++ b/tests/ui/const-generics/adt_const_params/const_param_ty_unchecked.rs
@@ -0,0 +1,26 @@
+//@run-pass
+//! Ensure that const_param_ty_unchecked gate allow
+//! bypassing `ConstParamTy_` implementation check
+
+#![allow(dead_code, incomplete_features)]
+#![feature(const_param_ty_unchecked, const_param_ty_trait)]
+
+use std::marker::ConstParamTy_;
+
+struct Miow;
+
+struct Meoww(Miow);
+
+struct Float {
+    float: f32,
+}
+
+impl ConstParamTy_ for Meoww {}
+impl ConstParamTy_ for Float {}
+
+fn something2<const N: *mut u8>() {}
+fn something<const N: f64>(a: f64) -> f64 {
+    N + a
+}
+
+fn main() {}
diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_unchecked_fail.rs b/tests/ui/const-generics/adt_const_params/const_param_ty_unchecked_fail.rs
new file mode 100644
index 0000000..3f09a30
--- /dev/null
+++ b/tests/ui/const-generics/adt_const_params/const_param_ty_unchecked_fail.rs
@@ -0,0 +1,31 @@
+// gate-test-const_param_ty_unchecked
+//! Ensure this fails when const_param_ty_unchecked isn't used
+#![allow(incomplete_features)]
+#![feature(const_param_ty_trait)]
+
+use std::marker::ConstParamTy_;
+
+struct Miow;
+
+struct Meoww(Miow);
+
+struct Float {
+    float: f32,
+}
+
+impl ConstParamTy_ for Meoww {}
+                    //~^ ERROR: the trait `ConstParamTy_` cannot be implemented for this type [E0204]
+impl ConstParamTy_ for Float {}
+                    //~^ ERROR: the trait `ConstParamTy_` cannot be implemented for this type [E0204]
+
+fn something2<const N: *mut u8>() {}
+                   //~^ ERROR: using raw pointers as const generic parameters is forbidden
+fn something<const N: f64>(a: f64) -> f64 {
+                   //~^ ERROR: `f64` is forbidden as the type of a const generic parameter
+    N + a
+}
+fn foo<const N: Vec<[u8]>>() {}
+    //~^  ERROR: the size for values of type `[u8]` cannot be known at compilation time [E0277]
+          //~^^ ERROR: `Vec<[u8]>` is forbidden as the type of a const generic parameter
+
+fn main() {}
diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_unchecked_fail.stderr b/tests/ui/const-generics/adt_const_params/const_param_ty_unchecked_fail.stderr
new file mode 100644
index 0000000..ae1ae61
--- /dev/null
+++ b/tests/ui/const-generics/adt_const_params/const_param_ty_unchecked_fail.stderr
@@ -0,0 +1,56 @@
+error[E0204]: the trait `ConstParamTy_` cannot be implemented for this type
+  --> $DIR/const_param_ty_unchecked_fail.rs:16:24
+   |
+LL | struct Meoww(Miow);
+   |              ---- this field does not implement `ConstParamTy_`
+...
+LL | impl ConstParamTy_ for Meoww {}
+   |                        ^^^^^
+
+error[E0204]: the trait `ConstParamTy_` cannot be implemented for this type
+  --> $DIR/const_param_ty_unchecked_fail.rs:18:24
+   |
+LL |     float: f32,
+   |     ---------- this field does not implement `ConstParamTy_`
+...
+LL | impl ConstParamTy_ for Float {}
+   |                        ^^^^^
+
+error: using raw pointers as const generic parameters is forbidden
+  --> $DIR/const_param_ty_unchecked_fail.rs:21:24
+   |
+LL | fn something2<const N: *mut u8>() {}
+   |                        ^^^^^^^
+   |
+   = note: the only supported types are integers, `bool`, and `char`
+
+error: `f64` is forbidden as the type of a const generic parameter
+  --> $DIR/const_param_ty_unchecked_fail.rs:23:23
+   |
+LL | fn something<const N: f64>(a: f64) -> f64 {
+   |                       ^^^
+   |
+   = note: the only supported types are integers, `bool`, and `char`
+
+error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
+  --> $DIR/const_param_ty_unchecked_fail.rs:27:8
+   |
+LL | fn foo<const N: Vec<[u8]>>() {}
+   |        ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `[u8]`
+note: required by an implicit `Sized` bound in `Vec`
+  --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
+
+error: `Vec<[u8]>` is forbidden as the type of a const generic parameter
+  --> $DIR/const_param_ty_unchecked_fail.rs:27:17
+   |
+LL | fn foo<const N: Vec<[u8]>>() {}
+   |                 ^^^^^^^^^
+   |
+   = note: the only supported types are integers, `bool`, and `char`
+
+error: aborting due to 6 previous errors
+
+Some errors have detailed explanations: E0204, E0277.
+For more information about an error, try `rustc --explain E0204`.