diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2022-08-22 14:37:10 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-08-22 14:37:10 +0000 |
commit | 8d1a6deb4e69e7dc162e741377674cf03459bcd9 (patch) | |
tree | 976a9fa43b737d776185a7d91a0621cf184f9f31 /gcc | |
parent | 0f4ec11e8c2399ca20f80b4006e294794f9b2e0f (diff) | |
parent | 56f503b88a240f1d77c8d6564656bc22269b4842 (diff) | |
download | gcc-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.cc | 40 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-path.cc | 3 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-type.cc | 21 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-type.h | 4 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-path.cc | 6 | ||||
-rw-r--r-- | gcc/testsuite/rust/execute/torture/issue-1249.rs | 39 |
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 +} |