From: Utkarsh Bahuguna <[email protected]>
is_refutable looked path patterns up by the last segment's hir id, which
doesn't point at the item, so let and fn param paths hit
rust_unreachable. Go through name resolution instead, consts count as
refutable and anything else falls back to the scrutinee type.
Fixes Rust-GCC/gccrs#4732
Assisted-by: Claude Opus (Anthropic)
gcc/rust/ChangeLog:
* hir/tree/rust-hir-pattern-abstract.cc (PathPattern::is_refutable):
Resolve the path through name resolution instead of its final
segment, and handle associated constants and const generics.
gcc/testsuite/ChangeLog:
* rust/compile/refutable-path.rs: Remove dg-ice and add associated
const and const generic cases.
* rust/compile/irrefutable-path-single-variant.rs: New test.
Signed-off-by: Utkarsh Bahuguna <[email protected]>
---
This change was merged into the gccrs repository and is posted here for
upstream visibility and potential drive-by review, as requested by GCC
release managers.
Each commit email contains a link to its details on github from where you can
find the Pull-Request and associated discussions.
Commit on github:
https://github.com/Rust-GCC/gccrs/commit/cd47eb1fd1c94e316693b6300d1f8282905c6553
The commit has been mentioned in the following issue(s):
- Rust-GCC/gccrs#4732: https://github.com/Rust-GCC/gccrs/issues/4732
The commit has been mentioned in the following pull-request(s):
- https://github.com/Rust-GCC/gccrs/pull/4808
.../hir/tree/rust-hir-pattern-abstract.cc | 54 ++++++++++++-------
.../irrefutable-path-single-variant.rs | 16 ++++++
gcc/testsuite/rust/compile/refutable-path.rs | 25 +++++++--
3 files changed, 70 insertions(+), 25 deletions(-)
create mode 100644
gcc/testsuite/rust/compile/irrefutable-path-single-variant.rs
diff --git a/gcc/rust/hir/tree/rust-hir-pattern-abstract.cc
b/gcc/rust/hir/tree/rust-hir-pattern-abstract.cc
index 146208c47..eac09e2d5 100644
--- a/gcc/rust/hir/tree/rust-hir-pattern-abstract.cc
+++ b/gcc/rust/hir/tree/rust-hir-pattern-abstract.cc
@@ -22,6 +22,7 @@
#include "optional.h"
#include "rust-tyty.h"
#include "rust-hir-type-check.h"
+#include "rust-finalized-name-resolution-context.h"
namespace Rust {
namespace HIR {
@@ -55,34 +56,47 @@ PathPattern::is_refutable (const TyTy::BaseType &scrutinee)
const
rust_assert (kind != Kind::LangItem);
auto &mappings = Analysis::Mappings::get ();
- HirId hir_id = get_final_segment ().get_mappings ().get_hirid ();
- if (hir_id)
+ auto &nr_ctx = Resolver2_0::FinalizedNameResolutionContext::get ();
+ // Resolve the path through name resolution because its final segment's
+ // HirId does not necessarily identify the referenced item directly.
+ if (auto def = nr_ctx.lookup (get_mappings ().get_nodeid (),
+ Resolver2_0::Namespace::Values,
+ Resolver2_0::Namespace::Types))
{
- auto item = mappings.hir.items.lookup (hir_id);
- if (item && item.value ()->get_item_kind () == Item::ItemKind::Constant)
- {
- return true;
- }
- else
+ if (auto def_hir_id = mappings.lookup_node_to_hir (def->id))
{
- rust_internal_error_at (
- get_locus (),
- "failed to lookup hir item during refutability checks");
- return true;
+ auto item = mappings.hir.items.lookup (*def_hir_id);
+ if (item
+ && item.value ()->get_item_kind () == Item::ItemKind::Constant)
+ return true;
+
+ // Associated constants live in the impl-item and trait-item maps,
+ // not the item map, so they need their own lookups.
+ if (auto implitem = mappings.lookup_hir_implitem (*def_hir_id))
+ if (implitem->first->get_impl_item_type ()
+ == ImplItem::ImplItemType::CONSTANT)
+ return true;
+
+ if (auto traititem = mappings.hir.trait_items.lookup (*def_hir_id))
+ if (traititem.value ()->get_item_kind ()
+ == TraitItem::TraitItemKind::CONST)
+ return true;
}
}
- // A path pattern is irrefutable if it corresponds to an enum with one
variant
- if (scrutinee.get_kind () == TyTy::TypeKind::ADT)
+ // A failed item lookup is fine since refutability can still be checked
+ // from the scrutinee's ADT type.
+ const auto *inner = scrutinee.destructure ();
+ if (inner->get_kind () == TyTy::TypeKind::ADT)
{
- const auto &adt = static_cast<const TyTy::ADTType &> (scrutinee);
+ const auto &adt = static_cast<const TyTy::ADTType &> (*inner);
if (adt.is_enum ())
- {
- return adt.number_of_variants () > 1;
- }
+ return adt.number_of_variants () > 1;
+ return false;
}
- // cannot have a Path that is neither a constant or an enum-like ADT
- rust_unreachable ();
+
+ // A failed lookup is fine since a non-ADT constant matches one value.
+ return true;
}
bool
diff --git a/gcc/testsuite/rust/compile/irrefutable-path-single-variant.rs
b/gcc/testsuite/rust/compile/irrefutable-path-single-variant.rs
new file mode 100644
index 000000000..1b7ab9554
--- /dev/null
+++ b/gcc/testsuite/rust/compile/irrefutable-path-single-variant.rs
@@ -0,0 +1,16 @@
+// { dg-additional-options "-w" }
+#![feature(no_core)]
+#![no_core]
+
+enum E {
+ A,
+}
+
+struct S;
+
+fn main() {
+ // A single-variant enum's unit variant is irrefutable.
+ let E::A: E;
+ // A unit struct is irrefutable.
+ let S: S;
+}
diff --git a/gcc/testsuite/rust/compile/refutable-path.rs
b/gcc/testsuite/rust/compile/refutable-path.rs
index 89da0453a..08f2676b1 100644
--- a/gcc/testsuite/rust/compile/refutable-path.rs
+++ b/gcc/testsuite/rust/compile/refutable-path.rs
@@ -1,14 +1,29 @@
#![feature(no_core)]
#![no_core]
-// { dg-ice "" }
enum E {
A,
B,
}
const A: u32 = 0;
-fn a(E::A: E) {}
-fn b(A: u32) {}
+struct S;
+impl S {
+ const C: u32 = 0;
+}
+fn a(E::A: E) {} // { dg-error "refutable pattern in function parameter" }
+fn b(A: u32) {} // { dg-error "refutable pattern in function parameter" }
fn main() {
- let A: u32;
- let E::A: E;
+ let A: u32; // { dg-error "refutable pattern in local binding" }
+ let E::A: E; // { dg-error "refutable pattern in local binding" }
+ let S::C: u32; // { dg-error "refutable pattern in local binding" }
+}
+fn f<const N: usize>(x: usize) {
+ let N = x; // { dg-error "refutable pattern in local binding" }
+}
+
+struct U;
+impl U {
+ const K: U = U;
+}
+fn g() {
+ let U::K: U; // { dg-error "refutable pattern in local binding" }
}
base-commit: 5f761a8444bee30c342b6d02283d862d9aa462d3
--
2.56.0