From: Arthur Cohen <[email protected]>
gcc/rust/ChangeLog:
* hir/tree/rust-hir-expr.h (class OffsetOf): New.
* hir/tree/rust-hir-expr.cc: Define its methods.
* hir/tree/rust-hir-expr-abstract.h: Add ExprType::OffsetOf.
* hir/tree/rust-hir-full-decls.h (class OffsetOf): Declare it.
* backend/rust-compile-block.h: Add handling for OffsetOf.
* backend/rust-compile-expr.cc (CompileExpr::visit): Likewise.
* backend/rust-compile-expr.h: Likewise.
* checks/errors/borrowck/rust-bir-builder-expr-stmt.cc
(ExprStmtBuilder::visit): Likewise.
* checks/errors/borrowck/rust-bir-builder-expr-stmt.h
(RUST_BIR_BUILDER_EXPR_H): Likewise.
* checks/errors/borrowck/rust-bir-builder-lazyboolexpr.h: Likewise.
* checks/errors/borrowck/rust-bir-builder-struct.h: Likewise.
* checks/errors/borrowck/rust-function-collector.h: Likewise.
* checks/errors/privacy/rust-privacy-reporter.cc
(PrivacyReporter::visit): Likewise.
* checks/errors/privacy/rust-privacy-reporter.h
(RUST_PRIVACY_REPORTER_H): Likewise.
* checks/errors/rust-const-checker.cc (ConstChecker::visit): Likewise.
* checks/errors/rust-const-checker.h: Likewise.
* checks/errors/rust-hir-pattern-analysis.cc (PatternChecker::visit):
Likewise.
* checks/errors/rust-hir-pattern-analysis.h: Likewise.
* checks/errors/rust-unsafe-checker.cc (UnsafeChecker::visit): Likewise.
* checks/errors/rust-unsafe-checker.h: Likewise.
* hir/rust-ast-lower-expr.cc (ASTLoweringExpr::visit): Likewise.
* hir/rust-hir-dump.cc (Dump::visit): Likewise.
* hir/rust-hir-dump.h: Likewise.
* hir/tree/rust-hir-visitor.cc (DefaultHIRVisitor::walk): Likewise.
* hir/tree/rust-hir-visitor.h: Likewise.
* typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit):
Likewise.
* typecheck/rust-hir-type-check-expr.h (RUST_HIR_TYPE_CHECK_EXPR):
Likewise.
gcc/testsuite/ChangeLog:
* rust/compile/offset_of2.rs: New test.
---
gcc/rust/backend/rust-compile-block.h | 3 ++
gcc/rust/backend/rust-compile-expr.cc | 6 ++++
gcc/rust/backend/rust-compile-expr.h | 1 +
.../borrowck/rust-bir-builder-expr-stmt.cc | 4 +++
.../borrowck/rust-bir-builder-expr-stmt.h | 2 ++
.../borrowck/rust-bir-builder-lazyboolexpr.h | 1 +
.../errors/borrowck/rust-bir-builder-struct.h | 2 ++
.../errors/borrowck/rust-function-collector.h | 2 ++
.../errors/privacy/rust-privacy-reporter.cc | 6 ++++
.../errors/privacy/rust-privacy-reporter.h | 2 ++
gcc/rust/checks/errors/rust-const-checker.cc | 4 +++
gcc/rust/checks/errors/rust-const-checker.h | 1 +
.../errors/rust-hir-pattern-analysis.cc | 4 +++
.../checks/errors/rust-hir-pattern-analysis.h | 1 +
gcc/rust/checks/errors/rust-unsafe-checker.cc | 6 ++++
gcc/rust/checks/errors/rust-unsafe-checker.h | 1 +
gcc/rust/hir/rust-ast-lower-expr.cc | 12 +++++--
gcc/rust/hir/rust-hir-dump.cc | 11 ++++++
gcc/rust/hir/rust-hir-dump.h | 1 +
gcc/rust/hir/tree/rust-hir-expr-abstract.h | 1 +
gcc/rust/hir/tree/rust-hir-expr.cc | 36 +++++++++++++++++++
gcc/rust/hir/tree/rust-hir-expr.h | 36 +++++++++++++++++++
gcc/rust/hir/tree/rust-hir-full-decls.h | 1 +
gcc/rust/hir/tree/rust-hir-visitor.cc | 6 ++++
gcc/rust/hir/tree/rust-hir-visitor.h | 5 +++
.../typecheck/rust-hir-type-check-expr.cc | 13 +++++++
gcc/rust/typecheck/rust-hir-type-check-expr.h | 2 ++
gcc/testsuite/rust/compile/offset_of2.rs | 9 +++++
28 files changed, 177 insertions(+), 2 deletions(-)
create mode 100644 gcc/testsuite/rust/compile/offset_of2.rs
diff --git a/gcc/rust/backend/rust-compile-block.h
b/gcc/rust/backend/rust-compile-block.h
index 90515f64883..f84bace15af 100644
--- a/gcc/rust/backend/rust-compile-block.h
+++ b/gcc/rust/backend/rust-compile-block.h
@@ -20,6 +20,7 @@
#define RUST_COMPILE_BLOCK
#include "rust-compile-base.h"
+#include "rust-hir-expr.h"
#include "rust-hir-visitor.h"
namespace Rust {
@@ -103,6 +104,7 @@ public:
void visit (HIR::AsyncBlockExpr &) override {}
void visit (HIR::InlineAsm &) override {}
void visit (HIR::LlvmInlineAsm &) override {}
+ void visit (HIR::OffsetOf &) override {}
private:
CompileConditionalBlocks (Context *ctx, Bvariable *result)
@@ -192,6 +194,7 @@ public:
void visit (HIR::AsyncBlockExpr &) override {}
void visit (HIR::InlineAsm &) override {}
void visit (HIR::LlvmInlineAsm &) override {}
+ void visit (HIR::OffsetOf &) override {}
void visit (HIR::AnonConst &) override {}
private:
diff --git a/gcc/rust/backend/rust-compile-expr.cc
b/gcc/rust/backend/rust-compile-expr.cc
index 25da59d982d..547bb7c27a8 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -375,6 +375,12 @@ CompileExpr::visit (HIR::LlvmInlineAsm &expr)
ctx->add_statement (asm_codegen.tree_codegen_asm (expr));
}
+void
+CompileExpr::visit (HIR::OffsetOf &expr)
+{
+ rust_unreachable ();
+}
+
void
CompileExpr::visit (HIR::IfExprConseqElse &expr)
{
diff --git a/gcc/rust/backend/rust-compile-expr.h
b/gcc/rust/backend/rust-compile-expr.h
index bc347bf5066..b8b4e8dfdd5 100644
--- a/gcc/rust/backend/rust-compile-expr.h
+++ b/gcc/rust/backend/rust-compile-expr.h
@@ -72,6 +72,7 @@ public:
void visit (HIR::ClosureExpr &expr) override;
void visit (HIR::InlineAsm &expr) override;
void visit (HIR::LlvmInlineAsm &expr) override;
+ void visit (HIR::OffsetOf &expr) override;
// TODO
void visit (HIR::ErrorPropagationExpr &) override {}
diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.cc
b/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.cc
index 0799a4ea84c..5b22c1a68a3 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.cc
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.cc
@@ -330,6 +330,10 @@ void
ExprStmtBuilder::visit (HIR::LlvmInlineAsm &expr)
{}
+void
+ExprStmtBuilder::visit (HIR::OffsetOf &expr)
+{}
+
void
ExprStmtBuilder::visit (HIR::MethodCallExpr &expr)
{}
diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.h
b/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.h
index 45d3d584825..ba5db8b0c3e 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.h
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.h
@@ -19,6 +19,7 @@
#ifndef RUST_BIR_BUILDER_EXPR_H
#define RUST_BIR_BUILDER_EXPR_H
+#include "rust-hir-expr.h"
#include "rust-hir-visitor.h"
#include "rust-bir-builder-internal.h"
@@ -103,6 +104,7 @@ protected: // Expr
void visit (HIR::IfExprConseqElse &expr) override;
void visit (HIR::InlineAsm &expr) override;
void visit (HIR::LlvmInlineAsm &expr) override;
+ void visit (HIR::OffsetOf &expr) override;
void visit (HIR::MatchExpr &expr) override;
void visit (HIR::AwaitExpr &expr) override;
diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-builder-lazyboolexpr.h
b/gcc/rust/checks/errors/borrowck/rust-bir-builder-lazyboolexpr.h
index a5ec5690743..9108009de10 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-builder-lazyboolexpr.h
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-builder-lazyboolexpr.h
@@ -216,6 +216,7 @@ public:
void visit (HIR::InlineAsm &expr) override {}
void visit (HIR::LlvmInlineAsm &expr) override {}
+ void visit (HIR::OffsetOf &expr) override {}
protected: // Illegal at this position.
void visit (HIR::StructExprFieldIdentifier &field) override
diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-builder-struct.h
b/gcc/rust/checks/errors/borrowck/rust-bir-builder-struct.h
index 2e11f635110..d87ff8cb33c 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-builder-struct.h
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-builder-struct.h
@@ -21,6 +21,7 @@
#include "rust-bir-builder-internal.h"
#include "rust-bir-builder-expr-stmt.h"
+#include "rust-hir-expr.h"
namespace Rust {
namespace BIR {
@@ -156,6 +157,7 @@ protected:
void visit (HIR::AsyncBlockExpr &expr) override { rust_unreachable (); }
void visit (HIR::InlineAsm &expr) override { rust_unreachable (); }
void visit (HIR::LlvmInlineAsm &expr) override { rust_unreachable (); }
+ void visit (HIR::OffsetOf &expr) override { rust_unreachable (); }
void visit (HIR::TypeParam ¶m) override { rust_unreachable (); }
void visit (HIR::ConstGenericParam ¶m) override { rust_unreachable (); }
void visit (HIR::LifetimeWhereClauseItem &item) override
diff --git a/gcc/rust/checks/errors/borrowck/rust-function-collector.h
b/gcc/rust/checks/errors/borrowck/rust-function-collector.h
index 860915e0920..86f96c14d62 100644
--- a/gcc/rust/checks/errors/borrowck/rust-function-collector.h
+++ b/gcc/rust/checks/errors/borrowck/rust-function-collector.h
@@ -19,6 +19,7 @@
#ifndef RUST_HIR_FUNCTION_COLLECTOR_H
#define RUST_HIR_FUNCTION_COLLECTOR_H
+#include "rust-hir-expr.h"
#include "rust-hir-item.h"
#include "rust-hir-visitor.h"
#include "rust-hir.h"
@@ -126,6 +127,7 @@ public:
void visit (HIR::AsyncBlockExpr &expr) override {}
void visit (HIR::InlineAsm &expr) override {}
void visit (HIR::LlvmInlineAsm &expr) override {}
+ void visit (HIR::OffsetOf &expr) override {}
void visit (HIR::TypeParam ¶m) override {}
void visit (HIR::ConstGenericParam ¶m) override {}
void visit (HIR::LifetimeWhereClauseItem &item) override {}
diff --git a/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc
b/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc
index e8a679214d4..af529931b26 100644
--- a/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc
+++ b/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc
@@ -313,6 +313,12 @@ void
PrivacyReporter::visit (HIR::LlvmInlineAsm &)
{}
+void
+PrivacyReporter::visit (HIR::OffsetOf &expr)
+{
+ // TODO: Do we have to do anything?
+}
+
void
PrivacyReporter::visit (HIR::TypePath &path)
{
diff --git a/gcc/rust/checks/errors/privacy/rust-privacy-reporter.h
b/gcc/rust/checks/errors/privacy/rust-privacy-reporter.h
index 07eebf65df0..72716a6aa8a 100644
--- a/gcc/rust/checks/errors/privacy/rust-privacy-reporter.h
+++ b/gcc/rust/checks/errors/privacy/rust-privacy-reporter.h
@@ -19,6 +19,7 @@
#ifndef RUST_PRIVACY_REPORTER_H
#define RUST_PRIVACY_REPORTER_H
+#include "rust-hir-expr.h"
#include "rust-hir-map.h"
#include "rust-hir-visitor.h"
#include "rust-mapping-common.h"
@@ -128,6 +129,7 @@ types
virtual void visit (HIR::AsyncBlockExpr &expr);
virtual void visit (HIR::InlineAsm &expr);
virtual void visit (HIR::LlvmInlineAsm &expr);
+ virtual void visit (HIR::OffsetOf &expr);
virtual void visit (HIR::EnumItemTuple &);
virtual void visit (HIR::EnumItemStruct &);
diff --git a/gcc/rust/checks/errors/rust-const-checker.cc
b/gcc/rust/checks/errors/rust-const-checker.cc
index 5cbab3d554c..c40f9db7d2c 100644
--- a/gcc/rust/checks/errors/rust-const-checker.cc
+++ b/gcc/rust/checks/errors/rust-const-checker.cc
@@ -560,6 +560,10 @@ void
ConstChecker::visit (LlvmInlineAsm &)
{}
+void
+ConstChecker::visit (OffsetOf &)
+{}
+
void
ConstChecker::visit (TypeParam &)
{}
diff --git a/gcc/rust/checks/errors/rust-const-checker.h
b/gcc/rust/checks/errors/rust-const-checker.h
index 22398747e58..eb63095a225 100644
--- a/gcc/rust/checks/errors/rust-const-checker.h
+++ b/gcc/rust/checks/errors/rust-const-checker.h
@@ -135,6 +135,7 @@ private:
virtual void visit (AsyncBlockExpr &expr) override;
virtual void visit (InlineAsm &expr) override;
virtual void visit (LlvmInlineAsm &expr) override;
+ virtual void visit (OffsetOf &expr) override;
virtual void visit (TypeParam ¶m) override;
virtual void visit (ConstGenericParam ¶m) override;
diff --git a/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc
b/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc
index ec22a0ee92e..25669713a00 100644
--- a/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc
+++ b/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc
@@ -438,6 +438,10 @@ void
PatternChecker::visit (LlvmInlineAsm &expr)
{}
+void
+PatternChecker::visit (OffsetOf &expr)
+{}
+
void
PatternChecker::visit (TypeParam &)
{}
diff --git a/gcc/rust/checks/errors/rust-hir-pattern-analysis.h
b/gcc/rust/checks/errors/rust-hir-pattern-analysis.h
index 5766180ec79..dd44abca527 100644
--- a/gcc/rust/checks/errors/rust-hir-pattern-analysis.h
+++ b/gcc/rust/checks/errors/rust-hir-pattern-analysis.h
@@ -109,6 +109,7 @@ private:
virtual void visit (AsyncBlockExpr &expr) override;
virtual void visit (InlineAsm &expr) override;
virtual void visit (LlvmInlineAsm &expr) override;
+ virtual void visit (OffsetOf &expr) override;
virtual void visit (TypeParam ¶m) override;
virtual void visit (ConstGenericParam ¶m) override;
virtual void visit (LifetimeWhereClauseItem &item) override;
diff --git a/gcc/rust/checks/errors/rust-unsafe-checker.cc
b/gcc/rust/checks/errors/rust-unsafe-checker.cc
index d90088faf74..405c59be096 100644
--- a/gcc/rust/checks/errors/rust-unsafe-checker.cc
+++ b/gcc/rust/checks/errors/rust-unsafe-checker.cc
@@ -693,6 +693,12 @@ UnsafeChecker::visit (LlvmInlineAsm &expr)
"use of inline assembly is unsafe and requires unsafe function or block");
}
+void
+UnsafeChecker::visit (OffsetOf &expr)
+{
+ // nothing to do, offset_of!() is safe
+}
+
void
UnsafeChecker::visit (TypeParam &)
{}
diff --git a/gcc/rust/checks/errors/rust-unsafe-checker.h
b/gcc/rust/checks/errors/rust-unsafe-checker.h
index 8a9830f7cd6..dc3b482f15b 100644
--- a/gcc/rust/checks/errors/rust-unsafe-checker.h
+++ b/gcc/rust/checks/errors/rust-unsafe-checker.h
@@ -117,6 +117,7 @@ private:
virtual void visit (AsyncBlockExpr &expr) override;
virtual void visit (InlineAsm &expr) override;
virtual void visit (LlvmInlineAsm &expr) override;
+ virtual void visit (OffsetOf &expr) override;
virtual void visit (TypeParam ¶m) override;
virtual void visit (ConstGenericParam ¶m) override;
virtual void visit (LifetimeWhereClauseItem &item) override;
diff --git a/gcc/rust/hir/rust-ast-lower-expr.cc
b/gcc/rust/hir/rust-ast-lower-expr.cc
index 31126a8ad35..e9c9acc06c8 100644
--- a/gcc/rust/hir/rust-ast-lower-expr.cc
+++ b/gcc/rust/hir/rust-ast-lower-expr.cc
@@ -1059,8 +1059,16 @@ ASTLoweringExpr::visit (AST::FormatArgs &fmt)
void
ASTLoweringExpr::visit (AST::OffsetOf &offset_of)
{
- // FIXME: Implement HIR::OffsetOf node and const evaluation
- rust_unreachable ();
+ auto type = std::unique_ptr<Type> (
+ ASTLoweringType::translate (offset_of.get_type ()));
+
+ auto crate_num = mappings.get_current_crate ();
+ Analysis::NodeMapping mapping (crate_num, offset_of.get_node_id (),
+ mappings.get_next_hir_id (crate_num),
+ mappings.get_next_localdef_id (crate_num));
+
+ translated = new HIR::OffsetOf (std::move (type), offset_of.get_field (),
+ mapping, offset_of.get_locus ());
}
} // namespace HIR
diff --git a/gcc/rust/hir/rust-hir-dump.cc b/gcc/rust/hir/rust-hir-dump.cc
index 3d61de9e8bd..afee7b42f47 100644
--- a/gcc/rust/hir/rust-hir-dump.cc
+++ b/gcc/rust/hir/rust-hir-dump.cc
@@ -1602,6 +1602,17 @@ void
Dump::visit (LlvmInlineAsm &e)
{}
+void
+Dump::visit (OffsetOf &e)
+{
+ begin ("OffsetOf");
+
+ put_field ("type", e.get_type ().as_string ());
+ put_field ("field", e.get_field ());
+
+ end ("OffsetOf");
+}
+
void
Dump::visit (TypeParam &e)
{
diff --git a/gcc/rust/hir/rust-hir-dump.h b/gcc/rust/hir/rust-hir-dump.h
index 8c39f489baf..3e6ae3006a7 100644
--- a/gcc/rust/hir/rust-hir-dump.h
+++ b/gcc/rust/hir/rust-hir-dump.h
@@ -169,6 +169,7 @@ private:
virtual void visit (AsyncBlockExpr &) override;
virtual void visit (InlineAsm &) override;
virtual void visit (LlvmInlineAsm &) override;
+ virtual void visit (OffsetOf &) override;
virtual void visit (TypeParam &) override;
virtual void visit (ConstGenericParam &) override;
diff --git a/gcc/rust/hir/tree/rust-hir-expr-abstract.h
b/gcc/rust/hir/tree/rust-hir-expr-abstract.h
index 8272a82808c..371daa835a2 100644
--- a/gcc/rust/hir/tree/rust-hir-expr-abstract.h
+++ b/gcc/rust/hir/tree/rust-hir-expr-abstract.h
@@ -74,6 +74,7 @@ public:
Path,
InlineAsm,
LlvmInlineAsm,
+ OffsetOf,
};
BaseKind get_hir_kind () override final { return Node::BaseKind::EXPR; }
diff --git a/gcc/rust/hir/tree/rust-hir-expr.cc
b/gcc/rust/hir/tree/rust-hir-expr.cc
index 8544ed6708b..14786adf6f3 100644
--- a/gcc/rust/hir/tree/rust-hir-expr.cc
+++ b/gcc/rust/hir/tree/rust-hir-expr.cc
@@ -1526,5 +1526,41 @@ InlineAsm::InlineAsm (location_t locus, bool
is_global_asm,
clobber_abi (std::move (clobber_abi)), options (std::move (options))
{}
+OffsetOf &
+OffsetOf::operator= (const OffsetOf &other)
+{
+ ExprWithoutBlock::operator= (other);
+
+ type = other.type->clone_type ();
+ field = other.field;
+ loc = other.loc;
+
+ return *this;
+}
+
+ExprWithoutBlock *
+OffsetOf::clone_expr_without_block_impl () const
+{
+ return new OffsetOf (*this);
+}
+
+std::string
+OffsetOf::as_string () const
+{
+ return "OffsetOf(" + type->as_string () + ", " + field.as_string () + ")";
+}
+
+void
+OffsetOf::accept_vis (HIRExpressionVisitor &vis)
+{
+ vis.visit (*this);
+}
+
+void
+OffsetOf::accept_vis (HIRFullVisitor &vis)
+{
+ vis.visit (*this);
+}
+
} // namespace HIR
} // namespace Rust
diff --git a/gcc/rust/hir/tree/rust-hir-expr.h
b/gcc/rust/hir/tree/rust-hir-expr.h
index 64d01ee6f00..61e35905ea0 100644
--- a/gcc/rust/hir/tree/rust-hir-expr.h
+++ b/gcc/rust/hir/tree/rust-hir-expr.h
@@ -3236,6 +3236,42 @@ public:
AST::AttrVec outer_attribs = AST::AttrVec ());
};
+class OffsetOf : public ExprWithoutBlock
+{
+public:
+ OffsetOf (std::unique_ptr<Type> &&type, Identifier field,
+ Analysis::NodeMapping mappings, location_t loc)
+ : ExprWithoutBlock (mappings), type (std::move (type)), field (field),
+ loc (loc)
+ {}
+
+ OffsetOf (const OffsetOf &other)
+ : ExprWithoutBlock (other), type (other.type->clone_type ()),
+ field (other.field), loc (other.loc)
+ {}
+
+ OffsetOf &operator= (const OffsetOf &other);
+
+ ExprWithoutBlock *clone_expr_without_block_impl () const override;
+ std::string as_string () const override;
+
+ void accept_vis (HIRExpressionVisitor &vis) override;
+ void accept_vis (HIRFullVisitor &vis) override;
+
+ ExprType get_expression_type () const override { return ExprType::OffsetOf; }
+
+ location_t get_locus () const override { return loc; }
+
+ Type &get_type () { return *type; }
+ const Type &get_type () const { return *type; }
+ const Identifier &get_field () const { return field; }
+
+private:
+ std::unique_ptr<Type> type;
+ Identifier field;
+ location_t loc;
+};
+
struct LlvmOperand
{
std::string constraint;
diff --git a/gcc/rust/hir/tree/rust-hir-full-decls.h
b/gcc/rust/hir/tree/rust-hir-full-decls.h
index 2905117dcb7..57b3a4d0915 100644
--- a/gcc/rust/hir/tree/rust-hir-full-decls.h
+++ b/gcc/rust/hir/tree/rust-hir-full-decls.h
@@ -128,6 +128,7 @@ class InlineAsmRegClass;
class InlineAsmOperand;
class InlineAsm;
class LlvmInlineAsm;
+class OffsetOf;
// rust-stmt.h
class EmptyStmt;
diff --git a/gcc/rust/hir/tree/rust-hir-visitor.cc
b/gcc/rust/hir/tree/rust-hir-visitor.cc
index 77b96e547af..c77300aae3a 100644
--- a/gcc/rust/hir/tree/rust-hir-visitor.cc
+++ b/gcc/rust/hir/tree/rust-hir-visitor.cc
@@ -603,6 +603,12 @@ DefaultHIRVisitor::walk (LlvmInlineAsm &expr)
input.expr->accept_vis (*this);
}
+void
+DefaultHIRVisitor::walk (OffsetOf &expr)
+{
+ expr.get_type ().accept_vis (*this);
+}
+
void
DefaultHIRVisitor::walk (TypeParam ¶m)
{
diff --git a/gcc/rust/hir/tree/rust-hir-visitor.h
b/gcc/rust/hir/tree/rust-hir-visitor.h
index 544cf5128a5..79962604607 100644
--- a/gcc/rust/hir/tree/rust-hir-visitor.h
+++ b/gcc/rust/hir/tree/rust-hir-visitor.h
@@ -88,6 +88,7 @@ public:
virtual void visit (AsyncBlockExpr &expr) = 0;
virtual void visit (InlineAsm &expr) = 0;
virtual void visit (LlvmInlineAsm &expr) = 0;
+ virtual void visit (OffsetOf &expr) = 0;
virtual void visit (TypeParam ¶m) = 0;
virtual void visit (ConstGenericParam ¶m) = 0;
virtual void visit (LifetimeWhereClauseItem &item) = 0;
@@ -254,6 +255,7 @@ public:
virtual void visit (AsyncBlockExpr &node) override { walk (node); }
virtual void visit (InlineAsm &node) override { walk (node); }
virtual void visit (LlvmInlineAsm &node) override { walk (node); }
+ virtual void visit (OffsetOf &node) override { walk (node); }
virtual void visit (TypeParam &node) override { walk (node); }
virtual void visit (ConstGenericParam &node) override { walk (node); }
virtual void visit (LifetimeWhereClauseItem &node) override { walk (node); }
@@ -392,6 +394,7 @@ protected:
virtual void walk (AsyncBlockExpr &) final;
virtual void walk (InlineAsm &) final;
virtual void walk (LlvmInlineAsm &) final;
+ virtual void walk (OffsetOf &) final;
virtual void walk (TypeParam &) final;
virtual void walk (ConstGenericParam &) final;
virtual void walk (LifetimeWhereClauseItem &) final;
@@ -531,6 +534,7 @@ public:
virtual void visit (AsyncBlockExpr &) override {}
virtual void visit (InlineAsm &) override {}
virtual void visit (LlvmInlineAsm &) override {}
+ virtual void visit (OffsetOf &) override {}
virtual void visit (TypeParam &) override {}
virtual void visit (ConstGenericParam &) override {}
@@ -754,6 +758,7 @@ public:
virtual void visit (IfExpr &expr) = 0;
virtual void visit (IfExprConseqElse &expr) = 0;
virtual void visit (InlineAsm &expr) = 0;
+ virtual void visit (OffsetOf &expr) = 0;
virtual void visit (LlvmInlineAsm &expr) = 0;
virtual void visit (MatchExpr &expr) = 0;
virtual void visit (AwaitExpr &expr) = 0;
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc
b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
index ead751a0a7d..4a105e77d91 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
@@ -895,6 +895,19 @@ TypeCheckExpr::visit (HIR::LlvmInlineAsm &expr)
infered = TyTy::TupleType::get_unit_type ();
}
+void
+TypeCheckExpr::visit (HIR::OffsetOf &expr)
+{
+ TypeCheckType::Resolve (expr.get_type ());
+
+ // FIXME: Does offset_of always return a usize?
+ TyTy::BaseType *size_ty;
+ bool ok = context->lookup_builtin ("usize", &size_ty);
+ rust_assert (ok);
+
+ infered = size_ty;
+}
+
void
TypeCheckExpr::visit (HIR::RangeFullExpr &expr)
{
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h
b/gcc/rust/typecheck/rust-hir-type-check-expr.h
index 48f28c70079..0343922407e 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h
@@ -19,6 +19,7 @@
#ifndef RUST_HIR_TYPE_CHECK_EXPR
#define RUST_HIR_TYPE_CHECK_EXPR
+#include "rust-hir-expr.h"
#include "rust-hir-type-check-base.h"
#include "rust-hir-visitor.h"
#include "rust-tyty.h"
@@ -78,6 +79,7 @@ public:
void visit (HIR::ClosureExpr &expr) override;
void visit (HIR::InlineAsm &expr) override;
void visit (HIR::LlvmInlineAsm &expr) override;
+ void visit (HIR::OffsetOf &expr) override;
// TODO
void visit (HIR::ErrorPropagationExpr &) override {}
diff --git a/gcc/testsuite/rust/compile/offset_of2.rs
b/gcc/testsuite/rust/compile/offset_of2.rs
new file mode 100644
index 00000000000..d4ad9c2db31
--- /dev/null
+++ b/gcc/testsuite/rust/compile/offset_of2.rs
@@ -0,0 +1,9 @@
+// { dg-additional-options "-frust-compile-until=compilation
-frust-assume-builtin-offset-of" }
+
+pub struct Foo {
+ a: i32,
+}
+
+fn main() {
+ let _ = offset_of!(Foo, a); // valid
+}
--
2.49.0