GCC Front-End For Rust

Alternative Rust Compiler for GCC

View the Project on GitHub

March 2023 Monthly report

Overview

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

Milestone Progress

We have received many GSoC proposals over the past few weeks and are starting to review them in more detail. Remember, proposals are open until the 4th of April, and will be reviewed until the 27th of April. We kept on receiving a high number of contributions this month, with around 50 PRs submitted, reviewed and merged in three weeks. Please note that why this amount is lower than previous months, this report was also written and published a week earlier than past months. Out of 13 proposals submitted to the GSoC portal so far, 9 of them concern gccrs.

We have opened many issues pertaining to the compilation of libcore 1.49 and feel confident that we are getting closer and closer to compiling it. However, due to the GCC staging process, we will not be able to make the changes required to the build system for libcore to be distributed as part of GCC 13, nor will we have a completely working version of libcore at this point. In the last few weeks that remain before GCC 13 releases, we will not be able to implement some of the more complex features remaining, such as inline assembly, format string parsing and handling, or the remaining compiler builtins.

For this reason, we have chosen to go with quite an early cutoff for the GCC 13 release, which means we’ll have more time to focus on documentation and user experience for the GCC 13 release. We will spend some time in the coming weeks upstreaming commits to GCC’s master and figuring out our next steps for the compiler.

Arthur also spent one week this month at Embedded World talking about the project with many interesting people from different backgrounds. Thank you to everyone who stopped by or attended our little Rust compilation challenge. We had pleasant discussions around gccrs with individuals from AdaCore and Ferrous Systems and had a lovely time.

Finally, one of the big changes this month was the renaming of our compiler proper from rust1 to crab1. The compiler proper is different from the compiler driver, gccrs, which users interact with. Because only gccrs hackers will ever interact with the compiler proper, we thought it would be fun to change its name. The project was originally started as a hobby and passion project, and we think that keeping things light is an important aspect of it. Hence, if you do contribute to gccrs, you’ll now use gcc/crab1 instead of gcc/rust1 to see if your changes have taken into effect!

Community call

We had our monthly community call on the 3rd of April. You can subscribe to our calendar to see when the next one will be held. The call is open to everyone, even if you would just like to sit-in and listen. You can also subscribe to our mailing-list or join our Zulip chat to be notified of upcoming events.

Completed Activities

Contributors this month

Overall Task Status

Category Last Month This Month Delta
TODO 198 218 +20
In Progress 40 43 +3
Completed 522 614 +90

Test Cases

TestCases Last Month This Month Delta
Passing 5613 5728 +115
Failed - - -
XFAIL 40 40 -
XPASS - - -

Bugs

Category Last Month This Month Delta
TODO 54 65 +11
In Progress 21 18 -3
Completed 265 287 +22

Milestones Progress

We are putting together milestones regarding projects such as libproc and will update the Milestone.

Note that the intrinsics milestone percentage on github is not representative: It shows a 69% completion rate, but does not take into account the tracking issues with dozens of unresolved items. Thus the percentage is computed using the sum of issues and tracked items done divided by the sums of issues and tracked items overall. Similarly, the Update GCC’s master branch milestone contains a tracking issue containing over 200 tasks. The percentage shown here takes this into account.

Milestone Last Week This Week Delta Start Date Completion Date Target
Data Structures 1 - Core 100% 100% - 30th Nov 2020 27th Jan 2021 29th Jan 2021
Control Flow 1 - Core 100% 100% - 28th Jan 2021 10th Feb 2021 26th Feb 2021
Data Structures 2 - Generics 100% 100% - 11th Feb 2021 14th May 2021 28th May 2021
Data Structures 3 - Traits 100% 100% - 20th May 2021 17th Sep 2021 27th Aug 2021
Control Flow 2 - Pattern Matching 100% 100% - 20th Sep 2021 9th Dec 2021 29th Nov 2021
Macros and cfg expansion 100% 100% - 1st Dec 2021 31st Mar 2022 28th Mar 2022
Imports and Visibility 100% 100% - 29th Mar 2022 13th Jul 2022 27th May 2022
Const Generics 100% 100% - 30th May 2022 10th Oct 2022 17th Oct 2022
Initial upstream patches 100% 100% - 10th Oct 2022 13th Nov 2022 13th Nov 2022
Upstream initial patchset 100% 100% - 13th Nov 2022 13th Dec 2022 19th Dec 2022
Update GCC’s master branch 100% 100% - 1st Jan 2023 21st Feb 2023 3rd Mar 2023
Final set of upstream patches 70% 74% +4% 16th Nov 2022 - 30th Apr 2023
Intrinsics and builtins 18% 18% - 6th Sept 2022 - TBD
Borrow checking 0% 0% - TBD - TBD
Const Generics 2 0% 0% - TBD - TBD
Rust-for-Linux compilation 0% 0% - TBD - TBD

Risks

The last remaining risk was for gccrs to not get merged in GCC 13 by us missing the stage deadline, but that is no longer the case.

Testing project

The testing project is on hold as we try and figure out some of the issues we’re running into with GitHub and our various automations around it.

Planned Activities

Detailed changelog

Bare trait objects

During testing libcore code we found that we didn’t support bare trait objects where it does not specify the ‘dyn’ keyword: https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html#bare_trait_objects

This is depreciated code but we aiming to compile older versions of libcore first so we need to be able to handle this before this became a hard error.

trait Foo {
    fn bar(&mut self, other: &mut Foo);
}

struct Baz;
impl Foo for Baz {
    fn bar(&mut self, other: &mut Foo) {}
}

Reference patterns

One of our new contributors Mahmoud Adel has been working on adding support for patterns within gccrs. Reference patterns was added recently which allows the users to automatically destructure the reference parameters here to their element types without requiring dereference syntax.

fn foo (&a: &i32, b: i32) -> i32 {
  a + b
}

Use declarations as the Rustc prelude

When working with Result and Option gccrs did not support the prelude use declarations which meant you had to specify Option::Some or Result::Ok rather than the usual Ok and Some. In order to support this Rust uses a special decalration to add these enum variant names directly to the namespace so for exmaple:

pub use result::Result::{self, Err, Ok};

extern "C" {
    fn printf(s: *const i8, ...);
}

mod result {
    pub enum Result<T, E> {
        #[lang = "Ok"]
        Ok(T),

        #[lang = "Err"]
        Err(E),
    }
}

pub fn test(a: i32) -> Result<i32, bool> {
    if a > 5 {
        Ok(123)
    } else {
        Err(false)
    }
}

Due to the use declaration it is now ok to directly use Err and Ok without specifying Result::<variant> directly.

Renaming our compiler proper from rust1 to crab1

This is an important change going forward to remember to have fun. For those who are not aware when you invoke gcc to compile C code fro example you should try doing so but pass the ‘-v’ flag and you will see that it ends up invoking a program called ‘cc1’. For gccrs we used to invoke one called rust1 we have now renamed this ‘crab1’.

See our zulip for fun discussions on this and associated PR https://github.com/Rust-GCC/gccrs/pull/1988

Add length checks for tuple patterns

When assigning tuples and patterns in general we did not have any sized checks so it used to be possible to assign a pattern of differing sizes which would lead to UB and or and ICE. Thanks to one of our new contributors Nikos Alexandris we now have proper checks such as:

fn foo() -> i32 { // { dg-error "expected .i32. got .bool." }
    let (a, _) = (true, 2, 3); // { dg-error "expected a tuple with 3 elements, found one with 2 elements" }
    a
}

see: https://godbolt.org/z/3njj6K14j

Uninit intrinsic

Although we add intrinsics fairly regularly this one is interesting from a compiler perspective, sometimes you just need uninitilized memory which is used in the mem::ptr modules in libcore which gets called from the iterator code to swap data around for the next element. We got some advice from bjorn3 here on our zulip which suggests the best way to implement an uninit intrinsic is to memset with 0x01 as it seems to be the least dangerous in an unsafe context.

As rust is designed to limit unitilized memory it would be great in the future to look at this in more detail in the future for now we are copying Rustc.