aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2022-08-22 14:37:10 +0000
committerGitHub <noreply@github.com>2022-08-22 14:37:10 +0000
commit8d1a6deb4e69e7dc162e741377674cf03459bcd9 (patch)
tree976a9fa43b737d776185a7d91a0621cf184f9f31 /gcc
parent0f4ec11e8c2399ca20f80b4006e294794f9b2e0f (diff)
parent56f503b88a240f1d77c8d6564656bc22269b4842 (diff)
downloadgcc-8d1a6deb4e69e7dc162e741377674cf03459bcd9.zip
gcc-8d1a6deb4e69e7dc162e741377674cf03459bcd9.tar.gz
gcc-8d1a6deb4e69e7dc162e741377674cf03459bcd9.tar.bz2
Merge #1493
1493: Fix ICE in dyn impl block r=philberty a=philberty The issue here was that our name resolution assumed qualified path always has an as clause. We also had missing visitors to generate the canonical path for impl blocks using dynamic trait objects. We should investigate implementing the fine-grained visitors for the AST similar to the ones we have for HIR. This will solve the issue where we have missing visitors. Fixes #1249 Co-authored-by: Philip Herron <philip.herron@embecosm.com>
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-item.cc40
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-path.cc3
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-type.cc21
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-type.h4
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-path.cc6
-rw-r--r--gcc/testsuite/rust/execute/torture/issue-1249.rs39
6 files changed, 84 insertions, 29 deletions
diff --git a/gcc/rust/resolve/rust-ast-resolve-item.cc b/gcc/rust/resolve/rust-ast-resolve-item.cc
index 75bd2e1..0c38f28 100644
--- a/gcc/rust/resolve/rust-ast-resolve-item.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-item.cc
@@ -534,25 +534,17 @@ ResolveItem::visit (AST::InherentImpl &impl_block)
// FIXME this needs to be protected behind nominal type-checks see:
// rustc --explain E0118
-
- NodeId resolved_node = ResolveType::go (impl_block.get_type ().get ());
- if (resolved_node == UNKNOWN_NODEID)
- {
- resolver->get_type_scope ().pop ();
- resolver->get_name_scope ().pop ();
- return;
- }
+ ResolveType::go (impl_block.get_type ().get ());
// Setup paths
CanonicalPath self_cpath = CanonicalPath::create_empty ();
bool ok = ResolveTypeToCanonicalPath::go (impl_block.get_type ().get (),
self_cpath);
rust_assert (ok);
+ rust_debug ("AST::InherentImpl resolve Self: {%s}",
+ self_cpath.get ().c_str ());
- std::string raw_impl_type_path = impl_block.get_type ()->as_string ();
- CanonicalPath impl_type
- = CanonicalPath::new_seg (impl_block.get_type ()->get_node_id (),
- raw_impl_type_path);
+ CanonicalPath impl_type = self_cpath;
CanonicalPath impl_prefix = prefix.append (impl_type);
// see https://godbolt.org/z/a3vMbsT6W
@@ -580,6 +572,9 @@ ResolveItem::visit (AST::InherentImpl &impl_block)
for (auto &impl_item : impl_block.get_impl_items ())
{
+ rust_debug (
+ "AST::InherentImpl resolve_impl_item: impl_prefix={%s} cpath={%s}",
+ impl_prefix.get ().c_str (), cpath.get ().c_str ());
resolve_impl_item (impl_item.get (), impl_prefix, cpath);
}
@@ -703,22 +698,20 @@ ResolveItem::visit (AST::TraitImpl &impl_block)
canonical_trait_type);
rust_assert (ok);
+ rust_debug ("AST::TraitImpl resolve trait type: {%s}",
+ canonical_trait_type.get ().c_str ());
+
CanonicalPath canonical_impl_type = CanonicalPath::create_empty ();
ok = ResolveTypeToCanonicalPath::go (impl_block.get_type ().get (),
canonical_impl_type);
rust_assert (ok);
- // raw paths
- std::string raw_impl_type_path = impl_block.get_type ()->as_string ();
- CanonicalPath impl_type_seg
- = CanonicalPath::new_seg (impl_block.get_type ()->get_node_id (),
- raw_impl_type_path);
-
- std::string raw_trait_type_path = impl_block.get_trait_path ().as_string ();
- CanonicalPath trait_type_seg
- = CanonicalPath::new_seg (impl_block.get_trait_path ().get_node_id (),
- raw_trait_type_path);
+ rust_debug ("AST::TraitImpl resolve self: {%s}",
+ canonical_impl_type.get ().c_str ());
+ // raw paths
+ CanonicalPath impl_type_seg = canonical_impl_type;
+ CanonicalPath trait_type_seg = canonical_trait_type;
CanonicalPath projection
= CanonicalPath::trait_impl_projection_seg (impl_block.get_node_id (),
trait_type_seg, impl_type_seg);
@@ -756,6 +749,9 @@ ResolveItem::visit (AST::TraitImpl &impl_block)
for (auto &impl_item : impl_block.get_impl_items ())
{
+ rust_debug (
+ "AST::TraitImpl resolve_impl_item: impl_prefix={%s} cpath={%s}",
+ impl_prefix.get ().c_str (), cpath.get ().c_str ());
resolve_impl_item (impl_item.get (), impl_prefix, cpath);
}
diff --git a/gcc/rust/resolve/rust-ast-resolve-path.cc b/gcc/rust/resolve/rust-ast-resolve-path.cc
index 27f32aa..b139c6a 100644
--- a/gcc/rust/resolve/rust-ast-resolve-path.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-path.cc
@@ -242,8 +242,9 @@ void
ResolvePath::resolve_path (AST::QualifiedPathInExpression *expr)
{
AST::QualifiedPathType &root_segment = expr->get_qualified_path_type ();
- ResolveType::go (&root_segment.get_as_type_path ());
ResolveType::go (root_segment.get_type ().get ());
+ if (root_segment.has_as_clause ())
+ ResolveType::go (&root_segment.get_as_type_path ());
for (auto &segment : expr->get_segments ())
{
diff --git a/gcc/rust/resolve/rust-ast-resolve-type.cc b/gcc/rust/resolve/rust-ast-resolve-type.cc
index a8931ce..6b08613 100644
--- a/gcc/rust/resolve/rust-ast-resolve-type.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-type.cc
@@ -477,6 +477,27 @@ ResolveTypeToCanonicalPath::visit (AST::SliceType &type)
}
}
+void
+ResolveTypeToCanonicalPath::visit (AST::TraitObjectTypeOneBound &type)
+{
+ CanonicalPath path = CanonicalPath::create_empty ();
+ bool ok
+ = ResolveTypeToCanonicalPath::go (&type.get_trait_bound ().get_type_path (),
+ path);
+ if (ok)
+ {
+ std::string slice_path = "<dyn " + path.get () + ">";
+ result = CanonicalPath::new_seg (type.get_node_id (), slice_path);
+ }
+}
+
+void
+ResolveTypeToCanonicalPath::visit (AST::TraitObjectType &type)
+{
+ // FIXME is this actually allowed? dyn A+B
+ gcc_unreachable ();
+}
+
ResolveTypeToCanonicalPath::ResolveTypeToCanonicalPath ()
: ResolverBase (), result (CanonicalPath::create_empty ())
{}
diff --git a/gcc/rust/resolve/rust-ast-resolve-type.h b/gcc/rust/resolve/rust-ast-resolve-type.h
index b57b513..5a71268 100644
--- a/gcc/rust/resolve/rust-ast-resolve-type.h
+++ b/gcc/rust/resolve/rust-ast-resolve-type.h
@@ -242,6 +242,10 @@ public:
void visit (AST::SliceType &type) override;
+ void visit (AST::TraitObjectTypeOneBound &type) override;
+
+ void visit (AST::TraitObjectType &type) override;
+
private:
ResolveTypeToCanonicalPath ();
diff --git a/gcc/rust/typecheck/rust-hir-type-check-path.cc b/gcc/rust/typecheck/rust-hir-type-check-path.cc
index fd0ca3e..84f3b6e 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-path.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-path.cc
@@ -34,13 +34,7 @@ TypeCheckExpr::visit (HIR::QualifiedPathInExpression &expr)
if (!qual_path_type.has_as_clause ())
{
- // then this is just a normal path-in-expression
NodeId root_resolved_node_id = UNKNOWN_NODEID;
- bool ok = resolver->lookup_resolved_type (
- qual_path_type.get_type ()->get_mappings ().get_nodeid (),
- &root_resolved_node_id);
- rust_assert (ok);
-
resolve_segments (root_resolved_node_id, expr.get_segments (), 0, root,
expr.get_mappings (), expr.get_locus ());
return;
diff --git a/gcc/testsuite/rust/execute/torture/issue-1249.rs b/gcc/testsuite/rust/execute/torture/issue-1249.rs
new file mode 100644
index 0000000..072204e
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/issue-1249.rs
@@ -0,0 +1,39 @@
+// { dg-options "-w" }
+// { dg-output "1\n2\n" }
+
+extern "C" {
+ fn printf(s: *const i8, ...);
+}
+
+trait T {
+ fn foo(&self);
+}
+
+impl dyn T {
+ fn bar(&self) {
+ unsafe {
+ let a = "1\n\0";
+ let b = a as *const str;
+ let c = b as *const i8;
+ printf(c);
+ }
+ self.foo()
+ }
+}
+
+struct S;
+impl T for S {
+ fn foo(&self) {
+ unsafe {
+ let a = "2\n\0";
+ let b = a as *const str;
+ let c = b as *const i8;
+ printf(c);
+ }
+ }
+}
+
+pub fn main() -> i32 {
+ <dyn T>::bar(&S);
+ 0
+}