diff --git a/gcc/rust/typecheck/rust-hir-inherent-impl-check.h b/gcc/rust/typecheck/rust-hir-inherent-impl-check.h
new file mode 100644
index 00000000000..3b8d3df8b34
--- /dev/null
+++ b/gcc/rust/typecheck/rust-hir-inherent-impl-check.h
@@ -0,0 +1,81 @@
+// Copyright (C) 2020-2024 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3. If not see
+// .
+#ifndef RUST_HIR_INHERENT_IMPL_ITEM_CHECK_H
+#define RUST_HIR_INHERENT_IMPL_ITEM_CHECK_H
+
+#include "rust-hir-item.h"
+#include "rust-hir-type-check-base.h"
+#include "rust-type-util.h"
+#include
+
+namespace Rust {
+namespace Resolver {
+
+class PrimitiveImplCheck : public TypeCheckBase
+{
+public:
+ static void go ()
+ {
+ PrimitiveImplCheck pass;
+
+ pass.scan ();
+ }
+
+private:
+ void scan ()
+
+ {
+ std::vector possible_primitive_impl;
+ mappings.iterate_impl_blocks ([&] (HirId id, HIR::ImplBlock *impl) -> bool {
+ // filtering trait-impl-blocks
+ if (impl->has_trait_ref ())
+ return true;
+ HirId impl_ty_id = impl->get_type ().get_mappings ().get_hirid ();
+ TyTy::BaseType *impl_type = nullptr;
+ if (!query_type (impl_ty_id, &impl_type))
+ return true;
+ if (is_primitive_type_kind (impl_type->get_kind ()))
+ {
+ possible_primitive_impl.push_back (impl);
+ }
+ return true;
+ });
+
+ for (auto impl : possible_primitive_impl)
+ {
+ report_error (impl);
+ }
+ }
+
+ void report_error (HIR::ImplBlock *impl)
+
+ {
+ rich_location r (line_table, impl->get_locus ());
+ std::string msg = "consider using an extension trait instead";
+ r.add_fixit_replace (impl->get_locus (), msg.c_str ());
+ r.add_range (impl->get_locus ());
+ std::string err = "impl";
+ err = "cannot define inherent `" + err + "` for primitive types";
+ rust_error_at (r, ErrorCode::E0390, "%s", err.c_str ());
+ }
+};
+
+} // namespace Resolver
+} // namespace Rust
+
+#endif // RUST_HIR_INHERENT_IMPL_ITEM_CHECK_H
diff --git a/gcc/rust/typecheck/rust-hir-type-check.cc b/gcc/rust/typecheck/rust-hir-type-check.cc
index 1e9f7d2f00d..6f3acb0313b 100644
--- a/gcc/rust/typecheck/rust-hir-type-check.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check.cc
@@ -18,7 +18,9 @@
#include "rust-hir-type-check.h"
#include "rust-hir-full.h"
+#include "rust-hir-inherent-impl-check.h"
#include "rust-hir-inherent-impl-overlap.h"
+#include "rust-hir-inherent-impl-check.h"
#include "rust-hir-pattern.h"
#include "rust-hir-type-check-expr.h"
#include "rust-hir-type-check-item.h"
@@ -77,6 +79,10 @@ TypeResolution::Resolve (HIR::Crate &crate)
if (saw_errors ())
return;
+ PrimitiveImplCheck::go ();
+ if (saw_errors ())
+ return;
+
OverlappingImplItemPass::go ();
if (saw_errors ())
return;
diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc
index 116c1abdf8e..2e1728b3a86 100644
--- a/gcc/rust/typecheck/rust-tyty.cc
+++ b/gcc/rust/typecheck/rust-tyty.cc
@@ -131,6 +131,12 @@ is_primitive_type_kind (TypeKind kind)
case TypeKind::FLOAT:
case TypeKind::NEVER:
case TypeKind::STR:
+ case TypeKind::ARRAY:
+ case TypeKind::SLICE:
+ case TypeKind::POINTER:
+ case TypeKind::REF:
+ case TypeKind::FNPTR:
+ case TypeKind::TUPLE:
return true;
default:
return false;
diff --git a/gcc/testsuite/rust/compile/issue-2500-rustc.rs b/gcc/testsuite/rust/compile/issue-2500-rustc.rs
new file mode 100644
index 00000000000..e9dbc5aa354
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-2500-rustc.rs
@@ -0,0 +1,25 @@
+impl u8 {
+ // { dg-error "cannot define inherent `impl` for primitive types" "" { target *-*-* } .-1 }
+ pub const B: u8 = 0;
+}
+
+impl str {
+ // { dg-error "cannot define inherent `impl` for primitive types" "" { target *-*-* } .-1 }
+ fn foo() {}
+}
+
+impl char {
+ // { dg-error "cannot define inherent `impl` for primitive types" "" { target *-*-* } .-1 }
+ pub const B: u8 = 0;
+ pub const C: u8 = 0;
+ fn foo() {}
+ fn bar(self) {}
+}
+
+struct MyType;
+impl &MyType {
+ // { dg-error "cannot define inherent `impl` for primitive types" "" { target *-*-* } .-1 }
+ pub fn for_ref(self) {}
+}
+
+fn main() {}
diff --git a/gcc/testsuite/rust/compile/issue-2500.rs b/gcc/testsuite/rust/compile/issue-2500.rs
new file mode 100644
index 00000000000..eacb45a7728
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-2500.rs
@@ -0,0 +1,9 @@
+#![allow(unused)]
+fn main() {
+struct Foo {
+ x: i32
+}
+
+impl *mut Foo {}
+// { dg-error "cannot define inherent `impl` for primitive types" "" { target *-*-* } .-1 }
+}
\ No newline at end of file