Thanks again to Open Source Security, inc and Embecosm for their ongoing support for this project.
Milestone Progress
Macros are still under development; the code still needs more work before it can be merged. So this week, I will focus on compiling simple macros like an add macro that we enforce two expressions as the first part of the implementation that we can merge. This will serve as a jumping point to get into more complex macro rules.
This work on macros has indirectly improved how we can work with attributes, so to take advantage of this, we merged code to support the rust inline attribute.
Other than working on macros, I merged a lot of code cleanup in our code generation pass; this means we have one canonical path in how we compile functions now, which helps us handle attributes and ABI options without any duplication.
Completed Activities
- Refactor TypeKind ToString from header to implementation PR911
- Bug Fix multiple generic substitution on path expressions PR912
- Support the inline attribute PR916 PR922
- Reuse C/C++ front-end mark_addressable code PR917
- Cleanup code generation to remove duplication PR918
- Support deref_mut lang item during method resolution PR920
Overall Task Status
Category | Last Week | This Week | Delta |
TODO | 106 | 105 | -1 |
In Progress | 11 | 11 | – |
Completed | 279 | 284 | +5 |
Test Cases
Category | Last Week | This Week | Delta |
Passing | 5686 | 5746 | +60 |
Failed | – | – | – |
XFAIL | 21 | 21 | – |
XPASS | – | – | – |
Bugs
Category | Last Week | This Week | Delta |
TODO | 38 | 38 | – |
In Progress | 1 | 1 | – |
Completed | 105 | 107 | +2 |
Milestones Progress
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 Sept 2021 | 27th Aug 2021 |
Control Flow 2 – Pattern Matching | 100% | 100% | – | 20th Sept 2021 | 9th Dec 2021 | 29th Nov 2021 |
Macros and cfg expansion | 45% | 50% | +5% | 1st Dec 2021 | – | 28th Mar 2022 |
Imports and Visibility | 0% | 0% | – | 29th Mar 2022 | – | 27th May 2022 |
Const Generics | 0% | 0% | – | 30th May 2022 | – | 25th Jul 2022 |
Intrinsics | 0% | 0% | – | 6th Sept 2021 | – | 30th Sept 2022 |
Risks
Risk | Impact (1-3) | Likelihood (0-10) | Risk (I * L) | Mitigation |
Rust Language Changes | 3 | 7 | 21 | Keep up to date with the Rust language on a regular basis |
Going over target dates | 3 | 5 | 15 | Maintain status reports and issue tracking to stakeholders |
Planned Activities
- Merge macro xfail testcases
- Continue work macros
- Add more good-first-pr issues with guides
Detailed changelog
inline attributes
In Rust the inline attribute takes three forms:
- #[inline]
- #[inline(always)]
- #[inline(never)]
Inline without any option is analogous to C style inline keyword giving a hint to the compiler that this function is a good candidate for inlining. Inline always can be acheived with GCC’s inline always attribute: https://gcc.gnu.org/onlinedocs/gcc/Inline.html. Finally never we can mark functions as DECL_UNINLINEABLE. The one difference is that inline optimizations require optimizations to be enabled. So when compiling at -O0 no inlining will occur, any level greater than this, the inline pass will be enforced.
We have always added some simple error handling for bad inline options such as:
#[inline(A)]
fn test() {}
test.rs:2:3: error: unknown inline option
2 | #[inline(A)]
| ^
#[inline(A,B)]
fn test() {}
test.rs:5:3: error: invalid number of arguments
5 | #[inline(A, B)]
| ^
deref_mut lang item
Work on method resolution has continued steadily and we now support the deref_mut lang item so that for methods that require a &mut self reference we try to lookup any relevant deref_mut lang item to get the indirection required from the receiver.
extern "C" {
fn printf(s: *const i8, ...);
}
#[lang = "deref"]
pub trait Deref {
type Target;
fn deref(&self) -> &Self::Target;
}
#[lang = "deref_mut"]
pub trait DerefMut: Deref {
fn deref_mut(&mut self) -> &mut Self::Target;
}
impl<T> Deref for &T {
type Target = T;
fn deref(&self) -> &T {
*self
}
}
impl<T> Deref for &mut T {
type Target = T;
fn deref(&self) -> &T {
*self
}
}
pub struct Bar(i32);
impl Bar {
pub fn foobar(&mut self) -> i32 {
self.0
}
}
pub struct Foo<T>(T);
impl<T> Deref for Foo<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T> DerefMut for Foo<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe {
let a = "mut_deref\n\0";
let b = a as *const str;
let c = b as *const i8;
printf(c);
}
&mut self.0
}
}
pub fn main() -> i32 {
let bar = Bar(123);
let mut foo: Foo<Bar> = Foo(bar);
let foobar = foo.foobar();
foobar - 123
}