gccrs: Add input/output from inout and split in out
Inline assembly was incomplete and input/output from inout or split in
out were not handled.
gcc/rust/ChangeLog:
* backend/rust-compile-asm.cc (get_out_expr): Return valid output from
an operand.
(CompileAsm::asm_construct_outputs): Handle every output
(get_in_expr): Return valid input from an operand.
(CompileAsm::asm_construct_inputs): Handle every input
* hir/rust-hir-dump.cc (Dump::visit): Dump inline assembly fields
* hir/tree/rust-hir-expr.h: Add non const getter and avoid operand copy
from getters.
* hir/tree/rust-hir-visitor.cc (DefaultHIRVisitor::walk): Use non const
reference.
* rust-backend.h: New slice_index_expression function.
* rust-gcc.cc: Implementation of slice_index_expression to generate tree node for
accessing slice elements.
* backend/rust-compile-pattern.cc: Implement SlicePattern check expression & binding
compilation against SliceType scrutinee.
gccrs: Update SlicePattern typechecking against slice reference parents
gcc/rust/ChangeLog:
* typecheck/rust-hir-type-check-pattern.cc (TypeCheckPattern::visit(SlicePattern)):
Add new type check case for SliceType wrapped in ReferenceType.
* backend/rust-compile-pattern.cc: Adjusted the asserts accordingly for
CompilePatternCheckExpr(SlicePattern) & CompilePatternBindings(SlicePattern).
Arthur Cohen [Tue, 22 Jul 2025 11:30:11 +0000 (13:30 +0200)]
gccrs: desugar: Handle try-blocks
gcc/rust/ChangeLog:
* Make-lang.in: Compile it.
* ast/rust-expression-yeast.cc (ExpressionYeast::dispatch): Dispatch to try-block
desugar.
* ast/rust-desugar-try-block.cc: New file.
* ast/rust-desugar-try-block.h: New file.
gccrs: Handle IfLetExprConseqElse in DefaultResolver
This relies on the DefaultASTVisitor visitor for IfLetExprConseqElse
performing a virtual call of the visitor for IfLetExpr, which doesn't
hold when DefaultASTVisitor is generated by the X-macro-DSL-system I
have in another patch.
Arthur Cohen [Mon, 21 Jul 2025 09:27:01 +0000 (11:27 +0200)]
gccrs: desugar: Add desugar dispatch for all desugars
Since we are doing more and more "external" desugars, as in desugars
that take a pointer and replace it with another one, rather than
modifying it from within, having an external visitor dispatch to the
proper desugar helps with code clarity.
gcc/rust/ChangeLog:
* Make-lang.in: Compile it.
* rust-session-manager.cc: Call the expression desugar dispatcher.
* ast/rust-desugar-question-mark.cc: Rework class API.
* ast/rust-desugar-question-mark.h: Likewise.
* ast/rust-expression-yeast.cc: New file.
* ast/rust-expression-yeast.h: New file.
TopLevel would ignore just-loaded modules but Early and ExpandVisitor
wouldn't. The latter would produce errors when it hit attributes which
should have been indirectly CfgStrip'd away.
gcc/rust/ChangeLog:
* expand/rust-cfg-strip.cc (CfgStrip::visit): Load unloaded
modules.
* resolve/rust-toplevel-name-resolver-2.0.cc (TopLevel::visit):
Assume modules have been loaded by CfgStrip.
* expand/rust-expand-visitor.cc
(ExpandVisitor::expand_inner_items): Adjust call to
expand_macro_children.
(ExpandVisitor::expand_inner_stmts): Likewise.
(ExpandVisitor::visit): Likewise.
* expand/rust-expand-visitor.h
(ExpandVisitor::expand_macro_children): Take a pointer to member
function instead of a std::function.
Philip Herron [Sun, 20 Jul 2025 20:48:18 +0000 (21:48 +0100)]
gccrs: fix bad monomophization of generic paths
When we have generic paths like T::foobar during codegen sometimes we need
to enforce an extra lookup for this generic parameter type to the mono
morphized underlying type.
Fixes Rust-GCC#3915
Fixes Rust-GCC#1247
gcc/rust/ChangeLog:
* backend/rust-compile-resolve-path.cc (HIRCompileBase::query_compile): do another lookup
gcc/testsuite/ChangeLog:
* rust/compile/issue-3915.rs: New test.
* rust/execute/torture/sip-hasher.rs: New test.
Signed-off-by: Philip Herron <herron.philip@googlemail.com>
This should make it easier for us to handle attribute meta items of the
form <SimplePath> '=' <Expression> where the expression isn't a literal.
Some low hanging fruit remains here, but I think I should keep this
patch small as I had some trouble debugging it as-is (see:
Rust::Token::as_string vs Rust::Token::get_str vs
Rust::AST::Token::as_string).
gcc/rust/ChangeLog:
* ast/rust-ast.cc: Include "rust-macro-invoc-lexer.h".
(AttributeParser::~AttributeParser): Move function definition
here.
(AttributeParser::AttributeParser): Likewise and adjust member
initialization.
(AttributeParser::parse_meta_item_inner): Handle changes to
peek_token.
(AttributeParser::parse_literal): Likewise.
(AttributeParser::parse_simple_path_segment): Likewise.
(AttributeParser::parse_meta_item_seq): Handle changes to
AttributeParser fields.
(AttributeParser::peek_token): Move function definition here and
wrap MacroInvocLexer.
(AttributeParser::skip_token): Likewise.
* ast/rust-macro.h (class MacroInvocLexer): Forward declare.
(class Parser): Likewise.
(AttributeParser::token_stream): Remove field.
(AttributeParser::stream_pos): Likewise.
(AttributeParser::lexer): New field.
(AttributeParser::parser): Likewise.
(AttributeParser::AttributeParser): Move definition to
"rust-ast.cc".
(AttributeParser::~AttributeParser): Likewise.
(AttributeParser::peek_token): Likewise.
(AttributeParser::skip_token): Likewise.
Philip Herron [Fri, 18 Jul 2025 14:46:59 +0000 (15:46 +0100)]
gccrs: Add initial support for deffered operator overload resolution
In the test case:
fn test (len: usize) -> u64 {
let mut i = 0;
let mut out = 0;
if i + 3 < len {
out = 123;
}
out
}
The issue is to determine the correct type of 'i', out is simple because it hits a
coercion site in the resturn position for u64. But 'i + 3', 'i' is an integer infer
variable and the same for the literal '3'. So when it comes to resolving the type for
the Add expression we hit the resolve the operator overload code and because of this:
macro_rules! add_impl {
($($t:ty)*) => ($(
impl Add for $t {
type Output = $t;
This means the resolution for 'i + 3' is ambigious because it could be any of these Add
implementations. But because we unify against the '< len' where len is defined as usize
later in the resolution we determine 'i' is actually a usize. Which means if we defer the
resolution of this operator overload in the ambigious case we can simply resolve it at the
end.
Fixes Rust-GCC#3916
gcc/rust/ChangeLog:
* hir/tree/rust-hir-expr.cc (OperatorExprMeta::OperatorExprMeta): track the rhs
* hir/tree/rust-hir-expr.h: likewise
* hir/tree/rust-hir-path.h: get rid of old comments
* typecheck/rust-hir-trait-reference.cc (TraitReference::get_trait_substs): return
references instead of copy
* typecheck/rust-hir-trait-reference.h: update header
* typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::ResolveOpOverload): write ambigious
operator overloads to a table and try to resolve it at the end
* typecheck/rust-hir-type-check-expr.h: new static helper
* typecheck/rust-hir-type-check.h (struct DeferredOpOverload): new model to defer resolution
* typecheck/rust-typecheck-context.cc (TypeCheckContext::lookup_operator_overload): new
(TypeCheckContext::compute_ambigious_op_overload): likewise
(TypeCheckContext::compute_inference_variables): likewise
gcc/testsuite/ChangeLog:
* rust/compile/issue-3916.rs: New test.
Signed-off-by: Philip Herron <herron.philip@googlemail.com>
Philip Herron [Fri, 18 Jul 2025 15:22:44 +0000 (16:22 +0100)]
gccrs: Fix ICE with duplicate root item main function
Rust seems to allow duplicate HIR::Item 'main' functions but it needs
to be a root item to be the true main entry point. This means we can
use the canonical path to determine if this is a root one where
its CrateName::main or CrateName::Module::main.
Fixes Rust-GCC#3978
gcc/rust/ChangeLog:
* backend/rust-compile-base.cc: check the canonical path
gcc/testsuite/ChangeLog:
* rust/compile/issue-3978.rs: New test.
Signed-off-by: Philip Herron <herron.philip@googlemail.com>
* parse/rust-parse-impl.h (Parser::parse_simple_path): Be more
careful about skipping SCOPE_RESOLUTION tokens.
(Parser::parse_simple_path_segment): Allow parsing from a
starting offset.
(Parser::parse_use_tree): Handle a non-skipped SCOPE_RESOLUTION
token.
* parse/rust-parse.h (Parser::parse_simple_path_segment): Add
parameter for parsing from a starting offset.
gcc/testsuite/ChangeLog:
* rust/compile/parse_simple_path_fail_1.rs: New test.
* rust/compile/parse_simple_path_fail_2.rs: New test.
* rust-backend.h: New size_constant_expression function.
* rust-gcc.cc: Implementation of size_constant_expression function to generate tree node
for array access.
* backend/rust-compile-pattern.h: Remove empty visits for SlicePattern.
* backend/rust-compile-pattern.cc: Implement SlicePattern check expression & binding
compilation against ArrayType scrutinee.
* typecheck/rust-hir-type-check-pattern.cc(TypeCheckPattern::visit(SlicePattern)):
Implement size checking for SlicePattern when type checking against array parent
Philip Herron [Thu, 10 Jul 2025 18:24:37 +0000 (19:24 +0100)]
gccrs: Fix cast rules logic to try simple casts then fall back to coercions
This case:
let i = 1;
let j = i as i64;
'i' is meant to default to i32 but the inference was making both of these
i64 because the code was prefering coercion logic which can end up with a
default unify which causes the ?integer to unify with i64 making them both
i64.
But all we need to do is allow the simple cast rules to run first then
fallback to coercions but special consideration has to be made to ensure
that if there are dyn objects needed then this needs a unsize coercion, but
also we need to ensure the underlying types are a valid simple cast too
otherwise these also need to fallback to the coercion code.
Fixes Rust-GCC#2680
gcc/rust/ChangeLog:
* typecheck/rust-casts.cc (TypeCastRules::resolve): optional emit_error flag
(TypeCastRules::check): try the simple cast rules then fallback to coercions
(TypeCastRules::check_ptr_ptr_cast): ensure the underlying's
(TypeCastRules::emit_cast_error): make this a static helper
* typecheck/rust-casts.h: new emit_error prototype
gcc/testsuite/ChangeLog:
* rust/compile/issue-2680.rs: New test.
Signed-off-by: Philip Herron <herron.philip@googlemail.com>
The super trait of PartialEq<Rhs> is a generic substitution and we reuse
our bounds code here for normal generic bounds and generics an invalid
bounds check was occuring when PartialEq<Rhs> was getting substituted becase
this is a trait doing proper bounds checking is not valid here because this
is telling us about the bounds in this case.
Fixes Rust-GCC#3836
gcc/rust/ChangeLog:
* typecheck/rust-hir-trait-resolve.cc (TraitResolver::resolve_trait): track is super trait
* typecheck/rust-hir-type-bounds.h: refactor bounds scan
* typecheck/rust-hir-type-check-base.h: track from super trait
* typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): likewise
* typecheck/rust-tyty-bounds.cc (TypeBoundsProbe::is_bound_satisfied_for_type): refactor
(TypeBoundsProbe::scan): likewise
(TypeBoundPredicate::apply_generic_arguments): likewise
* typecheck/rust-tyty-subst.cc: optional bounds checking on parm subst
* typecheck/rust-tyty-subst.h: likewise
* typecheck/rust-tyty.h: likewise
gcc/testsuite/ChangeLog:
* rust/compile/derive_partial_ord1.rs: this is now fully supported
* rust/execute/torture/basic_partial_ord1.rs: add missing i32 impl
* rust/execute/torture/basic_partial_ord2.rs: likewise
* rust/compile/issue-3836.rs: New test.
* rust/execute/torture/issue-3836.rs: New test.
* rust/execute/torture/partial-ord-6.rs: New test.
Signed-off-by: Philip Herron <herron.philip@googlemail.com>
Philip Herron [Tue, 8 Jul 2025 20:13:48 +0000 (21:13 +0100)]
gccrs: Do proper const folding during typechecking for array capacities
This patch adds proper folding to the const expression for array capacity we
already have the const folding mechanics and the query system needed to handle cases
where the capacity is a function call in a const context. This leverages and pulls the
gcc tree capacity into the TyTy::ArrayType so it can be used for more typechecking and
eventually doing more const generics work.
This is the first patch in a set intended to fully remove name
resolution 1.0. As such, it should leave name resolution 1.0 technically
available but broken.
Arthur Cohen [Tue, 20 May 2025 12:25:07 +0000 (14:25 +0200)]
gccrs: ast: reconstruct: Add base for reconstructing and asserting different IDs
gcc/rust/ChangeLog:
* ast/rust-ast.h (reconstruct): New function for calling the `reconstruct_*_impl` method
and asserting that the new NodeId is different, and then wrap it in a unique_ptr<T>.
(reconstruct_vec): Likewise, but for vectors of unique_ptr<T>
Owen Avery [Thu, 29 May 2025 21:04:46 +0000 (17:04 -0400)]
gccrs: nr2.0: Adjust resolution of modules
This prioritizes resolution in the language prelude over resolution as a
module.
gcc/rust/ChangeLog:
* resolve/rust-forever-stack.hxx (ForeverStack::resolve_path):
Resolve final segments which point to modules.
* resolve/rust-toplevel-name-resolver-2.0.cc (TopLevel::visit):
Avoid inserting module names into ribs in the type namespace.
Owen Avery [Sat, 24 May 2025 15:51:29 +0000 (11:51 -0400)]
gccrs: nr2.0: Add more checks for alternate patterns
gcc/rust/ChangeLog:
* resolve/rust-late-name-resolver-2.0.cc
(visit_identifier_as_pattern): Handle is_ref and is_mut.
(Late::visit): Likewise.
* resolve/rust-name-resolution-context.cc
(BindingLayer::insert_ident): Likewise.
(BindingLayer::bind_test): Handle changes to BindingLayer
fields.
(BindingLayer::merge): Likewise and emit more error messages.
* resolve/rust-name-resolution-context.h
(struct IdentifierMode): New.
(Binding::has_expected_bindings): New field.
(Binding::set): Rename field to...
(Binding::idents): ...here and convert from a set to a map.
(Binding::Binding): Initialize has_expected_bindings.
(BindingLayer::insert_ident): Adjust parameters.
Owen Avery [Mon, 16 Jun 2025 21:05:09 +0000 (17:05 -0400)]
gccrs: nr2.0: Adjust resolution of external crates
This ensures Session::load_extern_crate doesn't try to use the old name
resolver when nr2.0 is enabled, while also ensuring that nr2.0 handles
external crates.
gcc/rust/ChangeLog:
* resolve/rust-default-resolver.cc
(DefaultResolver::visit_extern_crate): New function.
(DefaultResolver::visit): New visitor function for ExternCrate.
* resolve/rust-default-resolver.h
(DefaultResolver::visit_extern_crate): New function.
(DefaultResolver::visit): New visitor function for ExternCrate.
* resolve/rust-toplevel-name-resolver-2.0.cc (TopLevel::visit):
Adjust ExternCrate visitor and rename to...
(TopLevel::visit_extern_crate): ...here.
* resolve/rust-toplevel-name-resolver-2.0.h (TopLevel::visit):
Remove ExternCrate visitor override.
(TopLevel::visit_extern_crate): New function.
* rust-session-manager.cc (Session::load_extern_crate): Only run
name resolution 1.0 if name resolution 2.0 is disabled.
Zhi Heng [Thu, 26 Jun 2025 14:33:15 +0000 (22:33 +0800)]
gccrs: Implement type checking for ItemType::RANGED in TuplePattern
This patch implements the previously unimplemented type checking for RANGED item
type for TuplePattern, which serves as the start for implementing compilation of
RestPattern.
gcc/rust/ChangeLog:
* typecheck/rust-hir-type-check-pattern.cc (TypeCheckPattern::visit(TuplePattern)):
Implement type checking for ItemType::RANGED.
Owen Avery [Mon, 23 Jun 2025 16:33:54 +0000 (12:33 -0400)]
gccrs: Fix scan-assembler regexp in recurse2.rs
gcc/testsuite/ChangeLog:
* rust/compile/macros/builtin/recurse2.rs: Match "abheyho\0" as
well as "abheyho", to handle slight differences in assembly
output for null-terminated strings.
Philip Herron [Mon, 23 Jun 2025 11:59:33 +0000 (12:59 +0100)]
gccrs: Fix bug with non compiled const decl
There was a sily bug where if you reorder this test case to declare A before B
this test would work but its meant to work in any order. So this fixes the bug
during code gen to fall back to our query compile system if this is needed.
Fixes Rust-GCC#3525
gcc/rust/ChangeLog:
* backend/rust-compile-resolve-path.cc: if this fails fall back to query compile
gcc/testsuite/ChangeLog:
* rust/compile/issue-3525.rs: New test.
Signed-off-by: Philip Herron <herron.philip@googlemail.com>
Code for TupleStructPattern compilation previously only assumes that it is derived from
an enum. This commit adds a check for that, and compiles non-enum TupleStructPatterns
similarly to TuplePatterns if it is not an enum.
gcc/rust/ChangeLog:
* backend/rust-compile-pattern.cc(CompilePatternCheckExpr::visit(TupleStructPattern)):
Fix error thrown when compiling non-enum TupleStructPattern.
Philip Herron [Sat, 21 Jun 2025 14:40:50 +0000 (15:40 +0100)]
gccrs: Refactor marker builtin trait assembly
Rename assemble_sized_builtin to assemble_marker_builtins and reorganize
the type matching to properly handle function pointers and closures with
their associated traits (Fn, FnMut, FnOnce).
gcc/rust/ChangeLog:
* typecheck/rust-hir-type-bounds.h: Rename method.
* typecheck/rust-tyty-bounds.cc: Refactor marker trait assembly
and add proper Fn trait handling for function types.
Philip Herron [Wed, 18 Jun 2025 17:25:14 +0000 (18:25 +0100)]
gccrs: Fix ICE when constant is missing and expression
This is an invalid test case and doesnt work with rustc, we dont fully pick
up the errors. Nr2 does handle this and puts out an extra good diagnostic
but the old NR doesnt so for now i added this to the exclude list and then
when we remove old name resolver this issue goes away.
Owen Avery [Mon, 16 Jun 2025 21:04:22 +0000 (17:04 -0400)]
gccrs: Adjust external crate lowering and type checking
The 2.0 name resolver is provided through
ImmutableNameResolutionContext after it is done being mutated. The
typechecker attempts to use ImmutableNameResolutionContext, so it needs
to be run after ImmutableNameResolutionContext has been initialized
(after all name resolution has been completed). Additionally, although I
haven't seen any issues with lowering AST to HIR before name resolution
2.0 is complete, it makes sense to perform all lowering in lockstep as
well.
gcc/rust/ChangeLog:
* hir/rust-ast-lower-item.cc (ASTLoweringItem::visit): Add
visitor for ExternCrate.
* hir/rust-ast-lower-item.h (ASTLoweringItem::visit): Likewise.
* rust-session-manager.cc (Session::load_extern_crate): Avoid
lowering or type resolving external crates here.
* typecheck/rust-hir-type-check-item.cc (TypeCheckItem::visit):
Add visitor for ExternCrate.
* typecheck/rust-hir-type-check-item.h (TypeCheckItem::visit):
Replace empty definition with a declaration.
Philip Herron [Tue, 17 Jun 2025 10:32:21 +0000 (11:32 +0100)]
gccrs: Fix issues around PartialEq Eq Ord Partial Ord
There is still an issue with derive on PartialOrd but this adds good tests
and fixes a bug we had handling the default Rhs = Self generic type param
substitutions on the comparison traits.
gcc/rust/ChangeLog:
* typecheck/rust-tyty.cc (ParamType::handle_substitions): make this consistent
gcc/testsuite/ChangeLog:
* rust/compile/bug-with-default-generic.rs: New test.
* rust/execute/torture/partial-eq-1.rs: New test.
* rust/execute/torture/partial-eq-2.rs: New test.
* rust/execute/torture/partial-eq-3.rs: New test.
* rust/execute/torture/partial-eq-4.rs: New test.
* rust/execute/torture/partial-ord-1.rs: New test.
* rust/execute/torture/partial-ord-2.rs: New test.
* rust/execute/torture/partial-ord-3.rs: New test.
* rust/execute/torture/partial-ord-4.rs: New test.
* rust/execute/torture/partial-ord-5.rs: New test.
Signed-off-by: Philip Herron <herron.philip@googlemail.com>
Zhi Heng [Fri, 13 Jun 2025 14:19:33 +0000 (22:19 +0800)]
gccrs: Implement name resolution for IdentifierPattern's subpattern
gcc/rust/ChangeLog:
* resolve/rust-ast-resolve-pattern.cc: Implement name resolution for
IdentifierPattern's subpattern.
* resolve/rust-late-name-resolver-2.0.cc: Ditto, but for nr2.
Owen Avery [Fri, 9 May 2025 18:37:55 +0000 (14:37 -0400)]
gccrs: nr2.0: Adjust lookup of associated items
gcc/rust/ChangeLog:
* resolve/rust-default-resolver.cc (DefaultResolver::visit):
Adjust scoping of trait definitions and their generic
parameters.
* resolve/rust-forever-stack.hxx (ForeverStack::get): Prevent
lookups inside TraitOrImpl ribs.
(ForeverStack::resolve_segments): Prevent lookups of the first
segment inside TraitOrImpl ribs.
Arthur Cohen [Tue, 27 May 2025 12:23:39 +0000 (14:23 +0200)]
gccrs: derive(Ord): Handle unit structs properly
gcc/rust/ChangeLog:
* expand/rust-derive-ord.cc (DeriveOrd::make_cmp_arms): Use new make_equal function.
(DeriveOrd::make_equal): New function.
(DeriveOrd::recursive_match): Handle the unit struct/tuple case.
* expand/rust-derive-ord.h: Declare make_equal.