GCC Rust Monthly Report #6 May 2021

May Overview

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

Milestone Progress

Generics were completed this month, and since then all my time has gone into planning for Traits. While developing this compiler, it has become critical to find the appropriate ordering of features such that they layer up like building blocks, this means the project can avoid breaking changes as much as possible. For instance, in order to implement Traits, the first part is to refactor the type resolution system to understand Trait Obligations, this is a core piece of the type system which is very subtle in effect to the programmer. Once the compiler is able to understand trait obligations this allows me to then work on coercions defined in: https://doc.rust-lang.org/nomicon/coercions.html. Though before the compiler can be made to store and manage trait obligations, we must first be able to parse and understand a simple trait in order to actually start working with the notion of obligations.

Monthly Community Call

We will be having our 3nd community call over on Zulip as the first Friday of the month: 4th June 2021 at: 1000 utc +1. The agenda can be found on our zulip channel topic: https://gcc-rust.zulipchat.com/#narrow/stream/266897-general/topic/Monthly.20Status.20Report.20Call

GCC Rust mailing list

Please find our new GCC Mailing list over on: https://gcc.gnu.org/mailman/listinfo/gcc-rust

This mailing list is about respecting the traditional methods of communication and development of GCC. It also displays the intent of the project to be aligned and upstreamed with the GCC project. Main development will still continue on GitHub, but we aim to ensure patches sent via mail on GCC channels are repsected the same as those on GitHub.

Compiler Explorer

We are available for testing on https://godbolt.org/, which does seem to have updated fully now. Thanks to Marc for this work fixing this.

Detailed changelog

Support impl items with generic parameters

Rust allows for the impl block to be generic like we have already seen in previous status reports, but it also allows for the impl items which inherit those generic parameters to also then be generic. This was a great test for the generics implementation since it required a cleanup of existing code rather than rewriting or changing the implementation to fit. The compiler in this instance is performing 2 substitutions in order to support this.

  • Where the method test applies the substitutions from the variable ‘a’ Foo<i32, f32> onto self
  • Infer the final type parameter X on the method or apply the turbo fish.
struct Foo<A, B>(A, B);

impl<T> Foo<T, f32> {
    fn test<X>(self, a: X) -> (T, X) {
        (self.0, a)
    }
}

fn main() {
    let a;
    a = Foo(123, 456f32);

    let b;
    b = a.test::<bool>(false);
}

Symbol mangling

Rustc supports two types of symbol mangling:

V0 is used in the Rust Linux project but as it is unstable/incomplete it seems prudent to wait for that to stabalise before implementing this but the goal is that GCC Rust should implement both Legacy and V0. The Issue with the legacy symbol magnling is that it uses characters such as $ and has an unstable SIP128 has at the end of the symbol. We now support the legacy symbol mangling but the hash is an FNV-128 hash for now as FNV is simpler to implement than SIP-128.

With the latest version of binutils you can invoke the rust-demangling with:

$ /opt/binutils-master/bin/c++filt --format=rust _ZN9TestCrate3foo17h3085c8a5747c85a8E
TestCrate::foo::h3085c8a5747c85a8

Fix Duplicate function generation

When we have generic methods/functions the compiler needs to substitute the types appropriately so when we see Foo::new called with the same type the compiler needs to check if we have already generated a generic function implementation for this already. Otherwise, this leads to duplicate symbol generation issues and increased code size.

struct Foo<A, B>(A, B);

impl Foo<i32, bool> {
    fn new<T>(a: T) -> (Self, T) {
        (Self(123, false), a)
    }
}

fn main() {
    let _a = Foo::new(123f32);
    let _b = Foo::new(123f32);

    let _d = Foo::new(123u32);
    let _d = Foo::new(123u32);
}

In this example there should only be 2 versions of Foo::new generated.

  • Foo::new<f32>
  • Foo::new<u32>

Issue and PR Templates

We now have added issue and PR templates to GitHub which should help guide new contributors in this area.

Raw Identifiers

New contributor Mark Wielaard has posted quite a few fixes for the compiler including fixes for Fedora 33 on x86 but also fixes for aarch64. Here he fixed the parser to handle raw identifiers which in rust allows you to use keywords as names like ‘match’ for example.

fn main() {
    let r#match = 123;
}

Unsupported testsuite

Marc has provided support for an unsupported testsuite section for the compiler allowing us to add test cases for this that we don’t support yet. When we do add/fix the issues these should turn into XPASS which will fail the CI build and require changes to update the test suite accordingly

Fixes for arm64

New contributor Mark Wielaard has also found that on arm64 we were hitting an ICE in the parser queue due to a bad calculation on when to extend the buffer.

Fix bug parsing attributes

Google Summer of code student Wenzhang Yang has fixed the parser in parsing attributes correctly. Note we still have not implemented any attributes.

Don’t warn unused when name is prefixed with ‘_’

Google Summer of code student Arthur Cohen has fixed the scan for unused to only emit a warning if the name is not prefixed with an underscore in line with the offical rust behaviour.

Fix ICE on Fedora

We had issues on Fedora where some of the test cases were failing this was due to a bad bit mask. In rust all toplevel items are given a LocalDefId which forms half of the DefId which is the Crate number and LocalDefId. In Rust this is actually achieved via a struct but in GCC Rust this was a uint64 bitmask of the two u32’s. The bug here was that the value was shifted by sizeof(u32) which is bytes and it needed to be shifted by 32 bits in order to correctly format the value correctly. This lead to duplicates being added to the HIR mappings tables causing an ICE.

Fix GCC Rust on ppc64le and sparc64

Recently with the discussion on the GCC mailing list, new contributor Thomas Fitzsimmons posted patches to fix the build of GCC Rust on ppc64le, this work really helps the project move forward. At the same time thanks to the Compile Farm project Google Summer of Code student, Thomas Yonug was able to fix the build on Sparc64, although for it there are failing tests.

Completed Activities

  • Fix duplicate generic function/method generation – PR427
  • Add legacy symbol mangling – PR425 PR430
  • Support Impl items to also be generic – PR424
  • Add testcase to cover bug report (already fixed) – PR422
  • Add Issue and PR Templates – PR431
  • Allow unused underscore identifiers – PR433
  • Fix parsing of attributes – PR436
  • DefId is a bit mask of CrateNum & LocalDefId – PR438
  • Fix Raw Identifiers – PR443
  • ARM64 Fixes – PR444 PR445 PR446 PR448
  • Add unsupported testsuite – PR393
  • Fix ppc64le – PR454
  • Fix build on sparc64 – PR451

Overall Task Status

CategoryLast MonthThis MonthDelta
TODO6779+12
In Progress76-1
Completed125139+14
GitHub Issues

Test Cases

CategoryLast MonthThis MonthDelta
Passes21902368+178
XFAIL3826-12
make check-rust

Bugs

CategoryLast MonthThis MonthDelta
TODO1417+3
In Progress32-1
Completed3545+10
GitHub Bugs

Milestones Progress

MilestoneLast MonthThis MonthDeltaStart 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 – Generics92%100%+8%11th Feb 202114th May 202128th May 2021
Data Structures 3 – Traits0%0%20th May 202127th Aug 2021
Control Flow 2 – Pattern Matching0%0%29th Oct 2021
Imports and Visibility0%0%TBD
GitHub milestones

Risks

RiskImpact (1-3)Likelihood (0-10)Risk (I * L)Mitigation
Copyright assignments2510Be up front on all PRs that the code is destined to be upstreamed to FSF
Rust Language Changes3721Keep up to date with the Rust language on a regular basis

Planned Activities

  • Name resolution of traits
  • Type Resolution cleanups

Leave a Reply

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