aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2022-07-18 12:15:20 +0000
committerGitHub <noreply@github.com>2022-07-18 12:15:20 +0000
commit6920d2294b3c6f106478fd3decaa511faf3cac84 (patch)
tree9425005eaae1a0d2815c0819e01445ccc0197283 /gcc
parente4cdb24c468b8a848980f7138767fbe093471c5b (diff)
parent43cd742e348d376ed4e7e0375b23289286525c8a (diff)
downloadgcc-6920d2294b3c6f106478fd3decaa511faf3cac84.zip
gcc-6920d2294b3c6f106478fd3decaa511faf3cac84.tar.gz
gcc-6920d2294b3c6f106478fd3decaa511faf3cac84.tar.bz2
Merge #1373
1373: Typecheck const generic params r=CohenArthur a=CohenArthur ```rust struct Foo<const N: usize>; struct Bar<const N: usize = { 15i32 }>; // { dg-error "expected .usize. got .i32." } ``` This PR allows us to typecheck the type of const generics as well as make sure that the optional default expression fits that type Co-authored-by: Arthur Cohen <arthur.cohen@embecosm.com>
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/hir/rust-hir-dump.cc4
-rw-r--r--gcc/rust/hir/rust-hir-dump.h1
-rw-r--r--gcc/rust/hir/tree/rust-hir-full-decls.h1
-rw-r--r--gcc/rust/hir/tree/rust-hir-visitor.h2
-rw-r--r--gcc/rust/hir/tree/rust-hir.h10
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-toplevel.cc20
-rw-r--r--gcc/testsuite/rust/compile/const_generics_6.rs2
7 files changed, 38 insertions, 2 deletions
diff --git a/gcc/rust/hir/rust-hir-dump.cc b/gcc/rust/hir/rust-hir-dump.cc
index 5063344..006a254 100644
--- a/gcc/rust/hir/rust-hir-dump.cc
+++ b/gcc/rust/hir/rust-hir-dump.cc
@@ -239,6 +239,10 @@ Dump::visit (TypeParam &)
{}
void
+Dump::visit (ConstGenericParam &)
+{}
+
+void
Dump::visit (LifetimeWhereClauseItem &)
{}
void
diff --git a/gcc/rust/hir/rust-hir-dump.h b/gcc/rust/hir/rust-hir-dump.h
index 4569c90..af104da 100644
--- a/gcc/rust/hir/rust-hir-dump.h
+++ b/gcc/rust/hir/rust-hir-dump.h
@@ -108,6 +108,7 @@ private:
virtual void visit (AsyncBlockExpr &) override;
virtual void visit (TypeParam &) override;
+ virtual void visit (ConstGenericParam &) override;
virtual void visit (LifetimeWhereClauseItem &) override;
virtual void visit (TypeBoundWhereClauseItem &) override;
diff --git a/gcc/rust/hir/tree/rust-hir-full-decls.h b/gcc/rust/hir/tree/rust-hir-full-decls.h
index c250830..af838fd 100644
--- a/gcc/rust/hir/tree/rust-hir-full-decls.h
+++ b/gcc/rust/hir/tree/rust-hir-full-decls.h
@@ -141,6 +141,7 @@ class ExprStmtWithBlock;
// rust-item.h
class TypeParam;
+class ConstGenericParam;
class WhereClauseItem;
class LifetimeWhereClauseItem;
class TypeBoundWhereClauseItem;
diff --git a/gcc/rust/hir/tree/rust-hir-visitor.h b/gcc/rust/hir/tree/rust-hir-visitor.h
index 42cc1ab..11eacbe 100644
--- a/gcc/rust/hir/tree/rust-hir-visitor.h
+++ b/gcc/rust/hir/tree/rust-hir-visitor.h
@@ -93,6 +93,7 @@ public:
virtual void visit (AwaitExpr &expr) = 0;
virtual void visit (AsyncBlockExpr &expr) = 0;
virtual void visit (TypeParam &param) = 0;
+ virtual void visit (ConstGenericParam &param) = 0;
virtual void visit (LifetimeWhereClauseItem &item) = 0;
virtual void visit (TypeBoundWhereClauseItem &item) = 0;
virtual void visit (Module &module) = 0;
@@ -238,6 +239,7 @@ public:
virtual void visit (AsyncBlockExpr &) override {}
virtual void visit (TypeParam &) override {}
+ virtual void visit (ConstGenericParam &) override {}
virtual void visit (LifetimeWhereClauseItem &) override {}
virtual void visit (TypeBoundWhereClauseItem &) override {}
diff --git a/gcc/rust/hir/tree/rust-hir.h b/gcc/rust/hir/tree/rust-hir.h
index ff4c39e..58f4db2 100644
--- a/gcc/rust/hir/tree/rust-hir.h
+++ b/gcc/rust/hir/tree/rust-hir.h
@@ -769,6 +769,16 @@ public:
Location get_locus () const override final { return locus; };
+ bool has_default_expression () { return default_expression != nullptr; }
+
+ std::unique_ptr<Type> &get_type () { return type; }
+ std::unique_ptr<Expr> &get_default_expression ()
+ {
+ rust_assert (has_default_expression ());
+
+ return default_expression;
+ }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
diff --git a/gcc/rust/typecheck/rust-hir-type-check-toplevel.cc b/gcc/rust/typecheck/rust-hir-type-check-toplevel.cc
index 78188cc..69377e2 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-toplevel.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-toplevel.cc
@@ -38,10 +38,26 @@ TypeCheckTopLevel::resolve_generic_params (
switch (generic_param.get ()->get_kind ())
{
case HIR::GenericParam::GenericKind::LIFETIME:
- case HIR::GenericParam::GenericKind::CONST:
- // FIXME: Skipping Lifetime and Const completely until better
+ // FIXME: Skipping Lifetime completely until better
// handling.
break;
+ case HIR::GenericParam::GenericKind::CONST: {
+ auto param
+ = static_cast<HIR::ConstGenericParam *> (generic_param.get ());
+ auto specified_type
+ = TypeCheckType::Resolve (param->get_type ().get ());
+
+ if (param->has_default_expression ())
+ {
+ auto expr_type = TypeCheckExpr::Resolve (
+ param->get_default_expression ().get ());
+ specified_type->coerce (expr_type);
+ }
+
+ context->insert_type (generic_param->get_mappings (),
+ specified_type);
+ }
+ break;
case HIR::GenericParam::GenericKind::TYPE: {
auto param_type
diff --git a/gcc/testsuite/rust/compile/const_generics_6.rs b/gcc/testsuite/rust/compile/const_generics_6.rs
new file mode 100644
index 0000000..de26123
--- /dev/null
+++ b/gcc/testsuite/rust/compile/const_generics_6.rs
@@ -0,0 +1,2 @@
+struct Foo<const N: usize>;
+struct Bar<const N: usize = { 15i32 }>; // { dg-error "expected .usize. got .i32." }