Thanks again to Open Source Security, inc and Embecosm for their ongoing support for this project.
Milestone Progress
In the month of June, I’ve focused on working with Trait impl blocks, and enforcing their obligations. This includes associated types and optional traits which are still in progress but need some cleanup and testing. I believe that Traits break down into three phases:
- Trait impl blocks and enforcing the obligations of the trait
- Support the implicit Self on Traits
- Support optional trait obligations
- TypeBounds and update the type system to handle coercions
- Where constraints and Least upper bound coercions and testing
Now the first part is almost complete, but it is hard to say if I am 100% on track as TypeBounds have been a tricky one to work on; though over the next few weeks if progress remains steady we will be in a good place.
Here is some interesting reading, which is what I am using as a reference.
- https://rustc-dev-guide.rust-lang.org/traits/resolution.html
- https://rustc-dev-guide.rust-lang.org/traits/chalk.html
Monthly Community Call
We had our monthly community call on jitsi please find the meeting notes here: https://github.com/Rust-GCC/Reporting/blob/main/2021-07-02-community-call.md
Google Summer of Code
Please find their respective monthly reports over on:
- https://github.com/Rust-GCC/Reporting/blob/main/2021-06-gsoc-2021-thomas-young-monthly-report.org
- https://github.com/Rust-GCC/Reporting/blob/main/2021-06-gsoc-2021-arthur-cohen-monthly-report.md
Detailed changelog
Reorganise the testsuite
Recently I noticed that the test suite numbers didn’t really match up to what I epxected. Thomas has cleaned this up again. Since the front-end is still early on there are many features of Rust we do not support yet so we have an unsupported set of tests that are now marked with XFAIL since we expect these tests to fail, since they are not supported yet. We still contain expected failure test cases such as ensuring we error correctly for bad types, for example, the only difference now is that these expected failures are now counted as a normally expected pass.
Build fixes for arm32, mips and rs6000
Thanks to our new contributor John Paul Adrian Glaubitz has been testing GCC Rust on as many architectures as he can which has resulted in many bug fixes for our TargetOptions support. This is key for Arthur’s google summer of code project, but also for cfg expansions.
Trait impl blocks
In order to begin work on traits we must first be able to implement a trait. This was a big PR and allows us begin work on Trait Obligations and desugar the AST into HIR further. Since TraitImplItems should be treated the same an normal Impl Items.
trait Foo {
fn bar() -> i32;
}
struct Test<T>(T);
impl<T> Foo for Test<T> {
fn bar() -> i32 {
123
}
}
fn main() {
let a: i32;
a = Test::<i32>::bar();
}
What was nice to see is that the work on generics did not need hanged to support this example test case. The compiler currently is not enforcing the trait here, but this is the building block to begin this work since trait obligations will be used anywhere to enforce any predicate of a trait.
Improve GDB support
Thanks to our new contributor Tom Tromey who is a GDB/GCC developer and has fixed bugs for upstream GDB support for Rust. His patches to the GCC Rust compiler include:
- Fix tuple field names PR-514
- Set the correct DWARF for Rust primitive types PR-505
- Use DW_LANG_Rust in DWARF emission PR-503 PR-513
Your GCC Rust mug is on its way.
HIR Cleanup
The compiler has several IRs involved within the compilation pipeline, first, the code is parsed into the AST which gives a full representation of the code. The next is HIR, a high-level IR which follows the convention of Rustc, this desugars the syntax a lot which helps ensure we canonicalize as many cases as possible to follow the same code paths.
Since our HIR was bootstrapped from the AST structures we ended up with a lot of duplication of handling methods separately from methods, and even had a trait impl block and a normal impl block. This made sense within the AST but for HIR this is not nessecary
Trait Obligations
When we create an impl block for a trait, each item must be part of the trait; by enforcing this rule, we know that this type fully implements the trait. I was able to merge the first part of trait obligations, which enforces that items declared within a trait impl block must be part of that trait and conform correctly for example:
trait Foo {
fn Bar() -> i32 {}
}
struct Baz;
impl Foo for Baz {
fn Barrr() {}
}
We can see that the function ‘Barrr’ is not part of the trait so we are able to provide the error:
test.rs:8:5: error: method ‘Barrr’ is not a member of trait ‘Foo’
1 | trait Foo {
| ~
......
8 | fn Barrr() {}
| ^
The other error we can provide is ensuring that the item is actually the correct type:
trait Foo {
fn Bar() -> i32 {}
}
struct Baz;
impl Foo for Baz {
fn Bar() {}
}
fn main() {}
Gives this error showing that the return types are not compatible.
test.rs:8:5: error: expected [i32] got [()]
2 | fn Bar() -> i32 {}
| ~
......
8 | fn Bar() {}
| ^
test.rs:8:5: error: method ‘Bar’ has an incompatible type for trait ‘Foo’
There is a branch here to add support for this onto methods, constants and associated types but it needs more work.
Unit Type support and GCC
Unit types were neglected in GCC rust for some time, but recently we made a breakthrough. I used void_type_node to represent them into GCC’s GENERIC, but this led to an ICE with GCC. Thanks to our new contributor Tom Tromey suggested that I try a zero precision unsigned integer to represent the unit-type; this solves the issue. However, if we use this as the return type for functions, we end up with one ICE when optimizations are active. Though if we leave functions as void_type_node, everything works fine with optimizations turned on. I will need to reach out to the GCC mailing list in order to get the prefered solution.
Nested Items
We now support nested functions and nested structure definitions. Rust allows for blocks to define new Items: https://doc.rust-lang.org/reference/statements.html
This means we can now compile the following:
pub fn main() {
struct foo {
a: i32,
b: f32,
};
let a;
a = foo { a: 123, b: 456f32 };
fn bar<T>(x: T) -> T {
x
}
let mut a = 123;
a = bar(a);
let mut b = 456f32;
b = bar(b);
}
Whats interested is that nested functions are not closures, they cannot encapsulate the state of the lexical scope it is defined within, which means they can be extracted as a normal function item as you can see here: https://godbolt.org/z/GMqvYjn6x
Completed Activities
- Build Fixes for arm32 and rs6000 – PR488 PR482 PR475 PR478
- Fix warnings for format specifiers – PR486
- Ensure all toplevel items respect their Canonical Path prefix – PR485
- Trait impl block support – PR484
- Add -frust-debug for verbose debug output – PR480 PR466
- Reuse AST attributes – PR469 PR453
- Support pipe input – PR458 PR460
- Improve GDB support PR-503 PR-513 PR-505 PR-514
- Bug fix path-expressions PR-493
- HIR cleanup PR492 PR495 PR498
- Fix the CanonicalPath for TraitImplItems PR496
- Fix build issues on MacOS bugsur PR497
- Code cleanup PR508 PR507 PR506 PR499
- Trait Obligations: PR502
- Fix attribute parsing: PR530
- Mark more live symbols: PR528 PR529 PR525
- Reject non-pure decimal for TupleIndexExpr: PR527
- Add unit-type support: PR521 PR522 PR526
- Add nested function support: PR523
- Suport block level struct definitions: PR520
- DWARF tuple field names: PR514
- Various cleanup: PR517 PR518
Contributors this month
- Marc Poulhiès
- Wenzhang Yang
- Arthur Cohen
- Thomas Schwinge
- Tom Tromey
- Mark Wielaard
- John Paul Adrian Glaubitz
Excluding merges, 9 authors have pushed 80 commits to master and 82 commits to all branches. On master, 146 files have changed and there have been 4,190 additions and 3,541 deletions.
Overall Task Status
Category | Last Month | This Month | Delta |
TODO | 79 | 86 | +7 |
In Progress | 6 | 7 | +1 |
Completed | 139 | 157 | +18 |
Test Cases
Category | Last Month | This Month | Delta |
Passing | 2368 | 3027 | +659 |
XFAIL | 26 | 15 | -11 |
Bugs
Category | Last Month | This Month | Delta |
TODO | 17 | 19 | +2 |
In Progress | 2 | 4 | +2 |
Completed | 45 | 51 | +6 |
Milestones Progress
Milestone | Last Month | This Month | 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 | 0% | 40% | +40% | 20th May 2021 | – | 27th Aug 2021 |
Control Flow 2 – Pattern Matching | 0% | 0% | – | – | – | 29th Oct 2021 |
Imports and Visibility | 0% | 0% | – | – | – | TBD |
Risks
Risk | Impact (1-3) | Likelihood (0-10) | Risk (I * L) | Mitigation |
Copyright assignments | 2 | 2 | 4 | Be up front on all PRs that the code is destined to be upstreamed to FSF |
Rust Language Changes | 3 | 7 | 21 | Keep up to date with the Rust language on a regular basis |
Planned Activities
- Trait Bounds and Where constraints
- Type Coercions