aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2021-04-20 10:22:59 +0000
committerGitHub <noreply@github.com>2021-04-20 10:22:59 +0000
commitee5afc03f94e8a76c1b1b9306849cd932d5d9090 (patch)
tree73d5e75e413238df82303e52357b60cf45e4b5bd /gcc
parent498758a1c238a539b364ac2c632742a9b64ab4a5 (diff)
parentbb103b62d47fd6efedb581f26e7a89bec35caef2 (diff)
downloadgcc-ee5afc03f94e8a76c1b1b9306849cd932d5d9090.zip
gcc-ee5afc03f94e8a76c1b1b9306849cd932d5d9090.tar.gz
gcc-ee5afc03f94e8a76c1b1b9306849cd932d5d9090.tar.bz2
Merge #381
381: Fix crash on empty parameters to generic data type r=philberty a=philberty When no parameters are passed to generic data types we cannot properly infer the usage of the generic block. This brings in a canonicalized check for `rustc --explain E0107` Fixes #379 Co-authored-by: Philip Herron <philip.herron@embecosm.com>
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/hir/tree/rust-hir-path.h4
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-toplevel.h5
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-type.h96
-rw-r--r--gcc/rust/typecheck/rust-substitution-mapper.h6
-rw-r--r--gcc/testsuite/rust.test/xfail_compile/expected_type_args2.rs6
-rw-r--r--gcc/testsuite/rust.test/xfail_compile/expected_type_args3.rs8
-rw-r--r--gcc/testsuite/rust.test/xfail_compile/generics8.rs15
7 files changed, 86 insertions, 54 deletions
diff --git a/gcc/rust/hir/tree/rust-hir-path.h b/gcc/rust/hir/tree/rust-hir-path.h
index d6f9fc0..262a04a 100644
--- a/gcc/rust/hir/tree/rust-hir-path.h
+++ b/gcc/rust/hir/tree/rust-hir-path.h
@@ -165,11 +165,11 @@ public:
GenericArgs &operator= (GenericArgs &&other) = default;
// Creates an empty GenericArgs (no arguments)
- static GenericArgs create_empty ()
+ static GenericArgs create_empty (Location locus = Location ())
{
return GenericArgs (std::vector<Lifetime> (),
std::vector<std::unique_ptr<Type> > (),
- std::vector<GenericArgsBinding> ());
+ std::vector<GenericArgsBinding> (), locus);
}
bool is_empty () const
diff --git a/gcc/rust/typecheck/rust-hir-type-check-toplevel.h b/gcc/rust/typecheck/rust-hir-type-check-toplevel.h
index 356faa6..8b23920 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-toplevel.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-toplevel.h
@@ -214,10 +214,7 @@ public:
auto self
= TypeCheckType::Resolve (impl_block.get_type ().get (), &substitutions);
if (self == nullptr || self->get_kind () == TyTy::TypeKind::ERROR)
- {
- rust_error_at (impl_block.get_locus (), "failed to resolve impl type");
- return;
- }
+ return;
for (auto &impl_item : impl_block.get_impl_items ())
TypeCheckTopLevelImplItem::Resolve (impl_item.get (), self,
diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.h b/gcc/rust/typecheck/rust-hir-type-check-type.h
index 6556947..5c21d5a 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-type.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-type.h
@@ -72,7 +72,7 @@ class TypeCheckResolveGenericArguments : public TypeCheckBase
public:
static HIR::GenericArgs resolve (HIR::TypePathSegment *segment)
{
- TypeCheckResolveGenericArguments resolver;
+ TypeCheckResolveGenericArguments resolver (segment->get_locus ());
segment->accept_vis (resolver);
return resolver.args;
};
@@ -83,8 +83,8 @@ public:
}
private:
- TypeCheckResolveGenericArguments ()
- : TypeCheckBase (), args (HIR::GenericArgs::create_empty ())
+ TypeCheckResolveGenericArguments (Location locus)
+ : TypeCheckBase (), args (HIR::GenericArgs::create_empty (locus))
{}
HIR::GenericArgs args;
@@ -165,57 +165,57 @@ public:
return;
}
- // reverse lookup the hir node from ast node id
HirId hir_lookup;
- if (context->lookup_type_by_node_id (ref, &hir_lookup))
+ if (!context->lookup_type_by_node_id (ref, &hir_lookup))
{
- // we got an HIR node
- if (context->lookup_type (hir_lookup, &translated))
- {
- translated = translated->clone ();
- auto ref = path.get_mappings ().get_hirid ();
- translated->set_ref (ref);
-
- HIR::TypePathSegment *final_seg = path.get_final_segment ();
- HIR::GenericArgs args
- = TypeCheckResolveGenericArguments::resolve (final_seg);
-
- bool path_declared_generic_arguments = !args.is_empty ();
- if (path_declared_generic_arguments)
- {
- if (translated->has_subsititions_defined ())
- {
- translated
- = SubstMapper::Resolve (translated, path.get_locus (),
- &args);
- if (translated->get_kind () != TyTy::TypeKind::ERROR
- && mappings != nullptr)
- {
- check_for_unconstrained (args.get_type_args ());
- }
- }
- else
- {
- rust_error_at (
- path.get_locus (),
- "TypePath %s declares generic argument's but "
- "the type %s does not have any",
- path.as_string ().c_str (),
- translated->as_string ().c_str ());
- }
- }
- else if (translated->has_subsititions_defined ())
- {
- translated
- = SubstMapper::InferSubst (translated, path.get_locus ());
- }
+ rust_error_at (path.get_locus (), "failed to lookup HIR node");
+ return;
+ }
+
+ TyTy::BaseType *lookup = nullptr;
+ if (!context->lookup_type (hir_lookup, &lookup))
+ {
+ rust_error_at (path.get_locus (), "failed to lookup HIR TyTy");
+ return;
+ }
+
+ TyTy::BaseType *path_type = lookup->clone ();
+ path_type->set_ref (path.get_mappings ().get_hirid ());
+
+ HIR::TypePathSegment *final_seg = path.get_final_segment ();
+ HIR::GenericArgs args
+ = TypeCheckResolveGenericArguments::resolve (final_seg);
+
+ bool is_big_self = final_seg->is_ident_only ()
+ && (final_seg->as_string ().compare ("Self") == 0);
+ if (path_type->needs_generic_substitutions ())
+ {
+ if (is_big_self)
+ {
+ translated = path_type;
return;
}
- }
- rust_error_at (path.get_locus (), "failed to type-resolve TypePath: %s",
- path.as_string ().c_str ());
+ translated = SubstMapper::Resolve (path_type, path.get_locus (), &args);
+ if (translated->get_kind () != TyTy::TypeKind::ERROR
+ && mappings != nullptr)
+ {
+ check_for_unconstrained (args.get_type_args ());
+ }
+ }
+ else if (!args.is_empty ())
+ {
+ rust_error_at (path.get_locus (),
+ "TypePath %s declares generic argument's but "
+ "the type %s does not have any",
+ path.as_string ().c_str (),
+ translated->as_string ().c_str ());
+ }
+ else
+ {
+ translated = path_type;
+ }
}
void visit (HIR::ArrayType &type) override
diff --git a/gcc/rust/typecheck/rust-substitution-mapper.h b/gcc/rust/typecheck/rust-substitution-mapper.h
index bc20e4b..cd04b0e 100644
--- a/gcc/rust/typecheck/rust-substitution-mapper.h
+++ b/gcc/rust/typecheck/rust-substitution-mapper.h
@@ -57,6 +57,9 @@ public:
{
TyTy::SubstitutionArgumentMappings mappings
= type.get_mappings_from_generic_args (*generics);
+ if (mappings.is_error ())
+ return;
+
concrete = type.handle_substitions (mappings);
}
@@ -77,6 +80,9 @@ public:
{
TyTy::SubstitutionArgumentMappings mappings
= type.get_mappings_from_generic_args (*generics);
+ if (mappings.is_error ())
+ return;
+
concrete = type.handle_substitions (mappings);
}
diff --git a/gcc/testsuite/rust.test/xfail_compile/expected_type_args2.rs b/gcc/testsuite/rust.test/xfail_compile/expected_type_args2.rs
new file mode 100644
index 0000000..b92c48f
--- /dev/null
+++ b/gcc/testsuite/rust.test/xfail_compile/expected_type_args2.rs
@@ -0,0 +1,6 @@
+struct Foo<A>(A);
+
+fn main() {
+ let a: Foo = Foo::<i32>(123);
+ // { dg-error "Invalid number of generic arguments to generic type" "" { target { *-*-* } } .-1 }
+}
diff --git a/gcc/testsuite/rust.test/xfail_compile/expected_type_args3.rs b/gcc/testsuite/rust.test/xfail_compile/expected_type_args3.rs
new file mode 100644
index 0000000..4c164ff
--- /dev/null
+++ b/gcc/testsuite/rust.test/xfail_compile/expected_type_args3.rs
@@ -0,0 +1,8 @@
+struct Foo<A>(A);
+
+impl Foo {
+ // { dg-error "Invalid number of generic arguments to generic type" "" { target { *-*-* } } .-1 }
+ fn test() -> i32 {
+ 123
+ }
+}
diff --git a/gcc/testsuite/rust.test/xfail_compile/generics8.rs b/gcc/testsuite/rust.test/xfail_compile/generics8.rs
new file mode 100644
index 0000000..70bad1a
--- /dev/null
+++ b/gcc/testsuite/rust.test/xfail_compile/generics8.rs
@@ -0,0 +1,15 @@
+struct Foo<A, B>(A, B);
+
+impl<T> Foo<i32, T> {
+ fn test(a: T) -> T { // { dg-error "duplicate definitions with name test" }
+ a
+ }
+}
+
+impl Foo<i32, f32> {
+ fn test() -> f32 { // { dg-error "duplicate definitions with name test" }
+ 123f32
+ }
+}
+
+fn main() {}