GCC Rust Weekly Status Report 42

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

Milestone Progress

We are nearing the end of declarative macro expansion, with only a few more cases to support. Furthermore, support for slices is almost complete with more language items being added and supported. We have also started utilizing existing gcc infrastructure in order to implement helpful rust constructs, which will become very useful as we start supporting more attributes and built-ins.

Two weeks remain before the end of the Macro Expansion deadline, which does not contain any significant difficulties to overcome. We will keep on working on adding support for the various constructs used in the core library, which we would like to start compiling soon.

Note this week there is a drop in the passing tests for our test-suite. We have no removed any tests but in dejagnu we had many bad/duplicate unused code warnings these are now fixed by reusing CPP unused variable detection code. It also removed our old AST unused code scan and improves our existing dead-code scan pass.

Completed Activities

  • Fix bad unused code warnings PR992
  • Macros can allow any delimiters for the innovcation PR997
  • Fix bugs in parsing macro repetitions PR994
  • Refactor ABI options into an enum during HIR lowering PR999
  • Handle macro invocations as statements vs expressions PR998
  • Cleanup how multiple matches are handled PR1002
  • Refactor how builtins/intrinsics are handled and add unreachable, abort, size_of and offset PR1003
  • Bug fix ICE on impl blocks for arrays or slices PR1007
  • Add missing generic substitution for covariants types slices and arrays PR1009
  • Add const_ptr lang item mappings PR1008
  • Implement HIR lowering for AST::SliceType PR1016
  • Refactor attribute visitor into its own file PR1017
  • Add more documentation for builtin macros PR1018
  • Generate GCC code for the libcore FatPtr/SliceType PR1015
  • Implement the builtin column! macro PR1004

Contributors this month

Overall Task Status

CategoryLast WeekThis WeekDelta
TODO113109-4
In Progress1722+5
Completed306317+11
GitHub Issues

Test Cases

CategoryLast WeekThis WeekDelta
Passing61775467-710
Failed
XFAIL2121
XPASS
make check-rust

Bugs

CategoryLast WeekThis WeekDelta
TODO3835-3
In Progress610+4
Completed112118+6
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 expansion70%78%+8%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 final PR for Slices
  • Finish supporting in place macro expansion
  • Improve error messages and edge case handling for declarative macros
  • Fix dynamic traits to support inheritance

Detailed changelog

Implement proper repetition separators

Rust allows users to define separators to use in macro repetitions. These separators help in making repeating macro invocations cleaner, and avoid this:

macro_rules! add0 {
    ($a:literal) => { $a };
    ($a:literal $($b:literal)+) => { $a + add0!($($b)*) }
}

macro_rules! add1 {
    ($a:literal,) => { $a };
    ($a:literal, $($b:literal,)+) => { $a + add1!($($b ,)*) }
}

add0!(1 2 3 4 67); // no separator
add1!(1, 2, 3, 4, 67,); // extra separator

Macro repetition separators are made of one token and positioned just before the repetition operator (?, * or +). We can now parse them, match them and expand them properly:

macro_rules! add {
    ($a:literal) => { $a };
    ($a:literal, $($b:literal),+) => { $a + add!($($b),*) }
}

add!(1, 2, 3, 4, 67);

Defining items and statements through macros

Macros can be used to avoid boilerplate and repetitive code, such as defining a large number of types and their implementation should they all be similar.

This can be seen in the standard rust library in various builtin-types related code:

// Reduced version.
// This implements the `Sub` trait for all builtin number types
// The implementation is always the same, so macros help
pub trait Sub<Rhs = Self> {
    type Output;
    fn sub(self, rhs: Rhs) -> Self::Output;
}

macro_rules! sub_impl {
    ($($t:ty)*) => ($(
        impl Sub for $t {
            type Output = $t;

            #[inline]
            fn sub(self, other: $t) -> $t { self - other }
        }
    )*)
}

sub_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }

This expands to a proper implementation of the Sub trait for all types mentioned, with proper expansion of the sub method and associated Output type. We are now able to parse those items correctly and expand them in place.

Likewise, macro invocations can also be expanded to multiple statements inside a block:

macro_rules! define_vars {
    ($([ $name:ident $value:literal ])*) => {
        $(let $name = $value;)*
    }
}

fn needs_lots_of_locals() {
    define_vars!([pear 14] [apple 'm'] [mango "Pi"]);
}

Leave a Reply

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