GCC Rust Weekly Status Report 51

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

Milestone Progress

This week we continued with steady progress. Unfortunately, many of the features we are working on are blocked until we fix our root path resolution with the crate and super keywords. Once this piece is in place, the remaining issues in our milestone will flow nicely. Notice the addition of new goal test case tables to track our progress on these. Tracking our progress purely from the milestone table does not tell the whole story, especially when we recently allocated so much time to bug fixing

We allocated time to introduce our Google Summer of Code students to help them get set up and feel part of the community. Note Arthur was on vacation this week, and Philbert is on vacation from Friday until Tuesday.

In terms of the progress for our imports and visibility milestone, as we have said previously, we will be going over by about two weeks from our target date, but this seems reasonable given the time spent on bug fixing has been very useful.

Completed Activities

  • Canonicalize types based on hashing PR1265
  • Add dead-code analysis support to Match Expressions PR1267
  • Make TyTy::destructure recursive with recursion guards PR1266
  • Add name reoslution for IfLet expression PR1241
  • Fix the Slice type layout PR1268
  • Wrap unit-testing code in CHECKING_P guards PR1276
  • Refactor array index expression PR1277
  • Implement TypeChecking for IfLet expression PR1279
  • Remove old hack for untyped bindings which is no longer required PR1275
  • Refactor how we detect if we are inside a loop for error handling break/continue expression PR1278
  • Add build badges for Marks build farm PR1282
  • Add test case to show bug is fixed PR1281
  • Str’s have the same type layout as Slices PR1280
  • Refactor const expr inteface PR1283

Contributors this week

Overall Task Status

CategoryLast WeekThis WeekDelta
TODO147146-1
In Progress2626
Completed381387+6
GitHub Issues

Test Cases

CategoryLast WeekThis WeekDelta
Passing62786301+23
Failed
XFAIL2523-2
XPASS
make check-rust

Bugs

CategoryLast WeekThis WeekDelta
TODO5354+1
In Progress1312-1
Completed158163+5
GitHub Bugs

Milestone 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 expansion100100%1st Dec 202131st Mar 202228th Mar 2022
Imports and Visibility65%72%+7%29th Mar 202227th May 2022
Const Generics0%0%30th May 202229th Aug 2022
Intrinsics0%0%6th Sept 202230th 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

Goal TestCases

Blake3

CategoryLast WeekThis WeekDelta
TODO1
In Progress1
Completed49
see: Rust-GCC/gccrs#682

Libcore SIP Hasher

CategoryLast WeekThis WeekDelta
TODO5
In Progress0
Completed11
see: Rust-GCC/gccrs#1247

Planned Activities

  • Work on our testsuite dashboard
  • Reworking our AST dump
  • Continue work on metadata export
  • Continue bug fixing in aim of compiling our goal test case

Detailed changelog

Slice Type Layout

Slice’s are a type of DST so as I mentioned in our previous report ‘*const [T]’ or ‘&mut [T]’ have the same layout which is twice the size of a pointer. We have updated the compiler to enforce this layout which which is represented by the FatPtr object in libcore. This layout is really important as the slice_from_raw_parts function needs to be able to maintain the data integrety of this structure which requires this or we end up with a reference to garbage data on the stack.

See this compiler explorer link: https://godbolt.org/z/9xe4Wvs3e

Str type layout

Str represents the raw string type in Rust which has specific type checking rules as it is another DST which happens to be the same layout of a Slice. Below is an example which shows Borrowing has no effect on type. The rules here are likely to affect all DST’s in regards to borrows and dereferences.

let a:&str = "TEST 1";
let b:&str = &"TEST 2";

When we have the same layout of a Slice we can actually get the length of the string by transmuting to a slice which is what libcore does:

mod mem {
    extern "rust-intrinsic" {
        fn transmute<T, U>(_: T) -> U;
    }
}

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

struct FatPtr<T> {
    data: *const T,
    len: usize,
}

pub union Repr<T> {
    rust: *const [T],
    rust_mut: *mut [T],
    raw: FatPtr<T>,
}

impl<T> [T] {
    pub const fn len(&self) -> usize {
        unsafe { Repr { rust: self }.raw.len }
    }
}

impl str {
    pub const fn len(&self) -> usize {
        self.as_bytes().len()
    }

    pub const fn as_bytes(&self) -> &[u8] {
        unsafe { mem::transmute(self) }
    }
}

fn main() -> i32 {
    let t1: &str = "TEST1";
    let t2: &str = &"TEST_12345";

    let t1sz = t1.len();
    let t2sz = t2.len();

    unsafe {
        let a = "t1sz=%i t2sz=%i\n";
        let b = a as *const str;
        let c = b as *const i8;

        printf(c, t1sz as i32, t2sz as i32);
    }

    0
}

Which in turn generates the following GIMPLE:

__attribute__((cdecl))
struct &[u8] str::as_bytes (const struct  self)
{
  struct &[u8] D.253;

  {
    RUSTTMP.2 = transmute<&str, &[u8]> (self);
  }
  D.253 = RUSTTMP.2;
  return D.253;
}


struct &[u8] transmute<&str, &[u8]> (const struct  _)
{
  struct &[u8] D.255;

  D.255 = VIEW_CONVERT_EXPR<struct &[u8]>(_);
  return D.255;
}


__attribute__((cdecl))
usize T::len<u8> (const struct &[u8] self)
{
  union 
{
  struct *const [u8] rust;
  struct *mut [u8] rust_mut;
  struct test::FatPtr<u8> raw;
} D.257;
  usize D.258;

  {
    D.257.rust = self;
    RUSTTMP.4 = D.257.raw.len;
  }
  D.258 = RUSTTMP.4;
  return D.258;
}


__attribute__((cdecl))
usize str::len (const struct  self)
{
  usize D.260;
  struct 
{
  u8 * data;
  usize len;
} D.261;

  D.261 = str::as_bytes (self);
  D.260 = T::len<u8> (D.261);
  return D.260;
}


__attribute__((cdecl))
i32 test::main ()
{
  i32 D.263;
  const struct  t1;
  const struct  t2;
  const usize t1sz;
  const usize t2sz;

  try
    {
      t1.data = "TEST1";
      t1.len = 5;
      t2.data = "TEST_12345";
      t2.len = 10;
      t1sz = str::len (t1);
      t2sz = str::len (t2);
      {
        const struct  a;
        const struct  b;
        const i8 * const c;

        try
          {
            a.data = "t1sz=%i t2sz=%i\n";
            a.len = 16;
            b = a;
            c = b.data;
            _1 = (i32) t2sz;
            _2 = (i32) t1sz;
            printf (c, _2, _1);
          }
        finally
          {
            a = {CLOBBER};
            b = {CLOBBER};
          }
      }
      D.263 = 0;
      return D.263;
    }
  finally
    {
      t1 = {CLOBBER};
      t2 = {CLOBBER};
    }
}

Leave a Reply

Your email address will not be published.