Skip to content

Handle const blocks #3738

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

CohenArthur
Copy link
Member

This adds some handling towards const { ... } expressions. I haven't added specific handling for const folding them, but they are properly handled by the const checker

@CohenArthur CohenArthur requested review from philberty and P-E-P April 15, 2025 15:34
{
auto inner_expr = ASTLoweringExpr::translate (expr.get_const_expr ());

// we know this will always be an `AnonConst`, or we have an issue. Let's
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this not be in the visitor above?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so I meant that the const block nodes should always just contain an AnonConst, which is why we do the assertion that it is actually one and then static cast and store an AnonConst instead of a unique_ptr<Expr> in the HIR::ConstBlock

AnonConst should be used within const blocks but also within things like array expressions (e.g. in let x = [15; size] size should technically be represented as an AnonConst) so the visitor needs to be a little generic

Copy link
Member

@philberty philberty left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM implementing this should be straight forward in the backend if you look at rust-compile-item.cc ConstantDecl we have wrapper for supporting constant blocks.

  ctx->push_const_context ();
  tree value
    = compile_constant_item (var.get_mappings ().get_hirid (), expr_type,
			     resolved_type, *canonical_path, const_value_expr,
			     var.get_locus (), const_value_expr.get_locus ());
  ctx->pop_const_context ();

Then you can do whatever you need with the value for your case you will be implementing this in rust-compile-expr.cc so it will just be:

  TyTy::BaseType *expr_type = nullptr;
  bool ok = ctx->get_tyctx ()->lookup_type (const.get_mappings ().get_hirid (),
					    &expr_type);
  rust_assert (ok);
  
    Resolver::CanonicalPath canonical_path
    = Resolver::CanonicalPath::create_empty ();
    
    HIR::Expr* const_value_expr = const.get_const_block ();

  ctx->push_const_context ();
  translated
    = compile_constant_item (const.get_mappings ().get_hirid (), expr_type,
			     expr_type, *canonical_path, const_value_expr,
			     const.get_locus (), const_value_expr.get_locus ());
  ctx->pop_const_context ();

something like that should just do it

gcc/rust/ChangeLog:

	* ast/rust-expr.h: Declare AnonConst and ConstBlock and use them.
	* ast/rust-ast-full-decls.h: Likewise.
	* ast/rust-ast.cc: Add implementation for AnonConst and ConstBlock.
	* ast/rust-ast.h: Likewise.
	* ast/rust-ast-collector.cc (TokenCollector::visit): Likewise.
	* ast/rust-ast-collector.h: Likewise.
	* ast/rust-ast-visitor.cc (DefaultASTVisitor::visit): Likewise.
	* ast/rust-ast-visitor.h: Likewise.
	* expand/rust-derive.h: Likewise.
	* hir/rust-ast-lower-base.cc (ASTLoweringBase::visit): Likewise.
	* hir/rust-ast-lower-base.h: Likewise.
	* hir/rust-ast-lower-expr.cc (translate_operand_const): Likewise.
	* resolve/rust-ast-resolve-base.cc (ResolverBase::visit): Likewise.
	* resolve/rust-ast-resolve-base.h: Likewise.
	* resolve/rust-ast-resolve-expr.h: Likewise.
	* resolve/rust-ast-resolve-expr.cc: Likewise.
gcc/rust/ChangeLog:

	* parse/rust-parse-impl.h (Parser::parse_const_block_expr): New function.
	* parse/rust-parse.h: Declare it.
gcc/rust/ChangeLog:

	* hir/tree/rust-hir-expr.h: New classes.
	* hir/tree/rust-hir-full-decls.h: Likewise.
	* hir/tree/rust-hir.cc: Handle AnonConst and ConstBlock.
	* backend/rust-compile-block.cc: Likewise.
	* backend/rust-compile-block.h: Likewise.
	* 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: 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: 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.
	(translate_operand_out): Likewise.
	(translate_operand_inout): Likewise.
	(translate_operand_const): Likewise.
	* hir/rust-ast-lower-expr.h: Likewise.
	* hir/rust-hir-dump.cc (Dump::visit): Likewise.
	* hir/rust-hir-dump.h: Likewise.
	* hir/tree/rust-hir-expr-abstract.h: Likewise.
	* hir/tree/rust-hir-expr.cc (AnonConst::AnonConst): Likewise.
	(AnonConst::operator=): Likewise.
	(ConstBlock::ConstBlock): Likewise.
	(ConstBlock::operator=): Likewise.
	* hir/tree/rust-hir-visitor.h:
	* typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): Likewise.
	(typecheck_inline_asm_operand): Likewise.
	* typecheck/rust-hir-type-check-expr.h: Likewise.
gcc/testsuite/ChangeLog:

	* rust/execute/torture/const_block1.rs: New test.
@CohenArthur CohenArthur force-pushed the handle-const-blocks branch from 14dafa6 to 4717a95 Compare April 16, 2025 14:41
@@ -410,7 +411,8 @@ CompileExpr::visit (HIR::BlockExpr &expr)
if (!ctx->get_tyctx ()->lookup_type (expr.get_mappings ().get_hirid (),
&block_tyty))
{
rust_error_at (expr.get_locus (), "failed to lookup type of BlockExpr");
rust_error_at (expr.get_locus (),
"failed to lookup type of BlockExpr 414");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does the 414 means here ? Is it supposed to be

rust_error_at (expr.get_locus (), ErrorCode::E0414,
		     "failed to lookup type of BlockExpr");

instead ?

std::string
AnonConst::as_string () const
{
std::string istr = indent_spaces (enter);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could be replaced with a string_stream

add_error (Error (locus, "failed to parse inner block in const block"));
skip_after_end_block ();

return nullptr;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should probably return an unexpected error and let the caller chose instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants