GCC Rust Weekly Status Report 43

Thanks again to Open Source Security, inc and Embecosm for their ongoing support for this project.

Milestone Progress

Almost all valid rust macro syntax is supported, with some error cases remaining unchecked. We will continue to use the time of the milestone to improve this. In relation to our slices we are very close to having this working; there are three outstanding pieces of work to finish before libcore 1.49.0’s implementation of slices will work, Unsized method resolution, a bug with type-checking generic pointers and finally, an issue with generic associated types from higher-ranked trait bounds. Slices in rust (1.49.0) are pretty interesting and complex so we will write a blog post on this later in the year and the differences in later rustc versions.

Completed Activities

  • Support placeholders becoming slices PR1037
  • Handle -fsyntax-only PR1035
  • Fix bad copy-past in can equal interface for pointer types PR1033
  • Add AST kind information PR1032
  • Rewrite our unconstrained type-param error checking PR1030
  • Macro in trait impl block PR1029
  • Allow parsing statements without closing semicolon PR1027
  • Fix memory corruption in generation of builtin functions PR1025
  • Fix spurious stripping of tail expression PR1022
  • Do not try and re-expand macros if depth has exceeded recursion limit PR1021

Contributors this week

Overall Task Status

CategoryLast WeekThis WeekDelta
TODO109110+1
In Progress2218-4
Completed317327+10
GitHub Issues

Test Cases

CategoryLast WeekThis WeekDelta
Passing54675511+44
Failed
XFAIL2122+1
XPASS
make check-rust

Bugs

CategoryLast WeekThis WeekDelta
TODO3534-1
In Progress108-2
Completed118125+7
GitHub Bugs

Milestones Progress

MilestoneLast WeekThis WeekDeltaStart DateCompletion DateTarget
Data Structures 1 – Core100%100%30th Nov 202027th Jan 202129th Jan 2021
Control Flow 1 – Core100%100%28th Jan 202110th Feb 202126th Feb 2021
Data Structures 2 – Generics100%100%11th Feb 202114th May 202128th May 2021
Data Structures 3 – Traits100%100%20th May 202117th Sept 202127th Aug 2021
Control Flow 2 – Pattern Matching100%100%20th Sept 20219th Dec 202129th Nov 2021
Macros and cfg expansion78%87%+9%1st Dec 202128th Mar 2022
Imports and Visibility0%0%29th Mar 202227th May 2022
Const Generics0%0%30th May 202225th Jul 2022
Intrinsics0%0%6th Sept 202130th Sept 2022
GitHub Milestones

Risks

RiskImpact (1-3)Likelihood (0-10)Risk (I * L)Mitigation
Rust Language Changes3721Keep up to date with the Rust language on a regular basis
Going over target dates2510Maintain status reports and issue tracking to stakeholders

Planned Activities

  • Merge unsized method resolution
  • Fix bug in generic associated types for slices
  • Continue work on error cases with macros

Detailed changelog

Expanding macros in more contexts

Last week’s macro improvements were focused on adding a base for in-place macro expansion. We worked on getting them properly expanded in two places, namely block statements and as crate items. However, macros can be used in many more ways:

A macro invocation expands a macro at compile-time and replaces the invocation with the result of the macro. Macros may be invoked in the following situations:

  1. Expressions and statements
  2. Patterns
  3. Types
  4. Items including associated items
  5. macro_rules transcribers
  6. External blocks

You can now call macros from inside `impl` blocks, external blocks and trait definitions or implementations. If you’ve been following the Rust-for-Linux effort, you might have seen this pattern when defining file operations for a type. This allows defining your own function or relying on the kernel’s defaults safely.

macro_rules! c_fn {
    (int $name:ident ( const char_ptr $arg_name:ident)) => {
        fn $name($arg_name: *const i8) -> i32;
    };
}

extern "C" {
    c_fn! {int puts (const char_ptr s)}
}

macro_rules! add_distract_fn {
    () => {
        fn distract() {
            unsafe {
                puts("wait this isn't C\0" as *const str as *const i8);
            }
        }
    };
}

struct Abstract;

impl Abstract {
    add_distract_fn!();
}

macro_rules! require_proc {
    ($fn_name:ident) => {
        fn $fn_name();
    };
}

trait Abstractable {
    require_proc!(extract);
}

macro_rules! extract {
    ($fn_block:block) => {
        fn extract() $fn_block
    }
}

impl Abstractable for Abstract {
    extract! {{ Abstract::distract(); }}
}

Relaxed parsing rules in macro definitions and invocations

To improve usability, parsing rules when expanding macro nodes are a little more relaxed. As an example, this is completely valid rust code:

macro_rules! take_stmt {
    ($s:stmt) => {
        $s
    };
}

fn f() -> i32 {
    16
}

macro_rules! expand_to_stmt_or_expr {
    () => {
        f()
    };
}

fn main() {
    take_stmt!(let a1 = 15);

    let a2 = {
        expand_to_stmt_or_expr!(); // f is called as an expression-statement
        expand_to_stmt_or_expr!() // f is called as a tail expression
    };
}

This is now handled properly and makes for prettier macros and invocations, and avoids the necessity of adding extra semicolons in some cases.

4 thoughts on “GCC Rust Weekly Status Report 43

    1. Thanks for that we will fix those in the future reports we have a script to generate a bunch of that data must have a typo

Leave a Reply

Your email address will not be published. Required fields are marked *