<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
 
 <title>Bluish Coder: rust</title>
 <link href="http://bluishcoder.co.nz/tag/rust/atom.xml" rel="self"/>
 <link href="http://bluishcoder.co.nz/"/>
 <updated>2020-07-10T16:25:05+12:00</updated>
 <id>http://bluishcoder.co.nz/</id>
 <author>
   <name>Bluishcoder</name>
   <email>admin@bluishcoder.co.nz</email>
 </author>

 
 <entry>
   <title>Contributing to Servo</title>
   <link href="http://bluishcoder.co.nz/2015/03/24/contributing-to-servo.html"/>
   <updated>2015-03-24T16:00:00+13:00</updated>
   <id>http://bluishcoder.co.nz/2015/03/24/contributing-to-servo</id>
   <content type="html">&lt;p&gt;&lt;a href=&quot;https://github.com/servo/servo&quot;&gt;Servo&lt;/a&gt; is a web browser engine written in the &lt;a href=&quot;http://www.rust-lang.org/&quot;&gt;Rust programming language&lt;/a&gt;. It is being developed by &lt;a href=&quot;https://www.mozilla.org&quot;&gt;Mozilla&lt;/a&gt;. Servo is open source and the project is developed on github.&lt;/p&gt;

&lt;p&gt;I was looking for a small project to do some Rust programming and Servo being written in Rust seemed likely to have tasks that were small enough to do in my spare time yet be useful contributions to the project. This post outlines how I built Servo, found issues to work on, and got them merged.&lt;/p&gt;

&lt;h2&gt;Preparing Servo&lt;/h2&gt;

&lt;p&gt;The &lt;a href=&quot;https://github.com/servo/servo/blob/master/README.md&quot;&gt;Servo README&lt;/a&gt; has details on the pre-requisites needed. Installing the pre-requisites and cloning the repository on Ubuntu was:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ sudo apt-get install curl freeglut3-dev \
   libfreetype6-dev libgl1-mesa-dri libglib2.0-dev xorg-dev \
   msttcorefonts gperf g++ cmake python-virtualenv \
   libssl-dev libbz2-dev libosmesa6-dev 
...
$ git clone https://github.com/servo/servo
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Building Rust&lt;/h2&gt;

&lt;p&gt;The Rust programming language has been fairly volatile in terms of language and library changes. Servo deals with this by requiring a specific git commit of the Rust compiler to build. The Servo source is periodically updated for new Rust versions. The commit id for Rust that is required to build is stored in the &lt;a href=&quot;https://github.com/servo/servo/blob/master/rust-snapshot-hash&quot;&gt;rust-snapshot-hash file&lt;/a&gt; in the Servo repository.&lt;/p&gt;

&lt;p&gt;If the Rust compiler isn&#39;t installed already there are two options for building Servo. The first is to build the required version of Rust yourself, as outlined below. The second is to let the Servo build system, &lt;code&gt;mach&lt;/code&gt;, download a binary snapshot and use that. If you wish to do the latter, and it may make things easier when starting out, skip this step to build Rust.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ cat servo/rust-snapshot-hash
d3c49d2140fc65e8bb7d7cf25bfe74dda6ce5ecf/rustc-1.0.0-dev
$ git clone https://github.com/rust-lang/rust
$ cd rust
$ git checkout -b servo d3c49d2140fc65e8bb7d7cf25bfe74dda6ce5ecf
$ ./configure --prefix=/home/myuser/rust
$ make
$ make install
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note that I configure Rust to be installed in a directory off my home directory. I do this out of preference to enable managing different Rust versions. The build will take a long time and once built you need to add the prefix directories to the &lt;code&gt;PATH&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ export PATH=$PATH:/home/myuser/rust/bin
$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/myuser/rust/lib
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Building Servo&lt;/h2&gt;

&lt;p&gt;There is a configuration file used by the Servo build system to store information on what Rust compiler to use, whether to use a system wide Cargo (Rust package manager) install and various paths. This file, &lt;code&gt;.servobuild&lt;/code&gt;, should exist in the root of the Servo source that was cloned. There is a &lt;a href=&quot;https://github.com/servo/servo/blob/master/servobuild.example&quot;&gt;sample file&lt;/a&gt; that can be used as a template. The values I used were:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;[tools]
system-rust = true
system-cargo = false

[build]
android = false
debug-mozjs = false
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If you want to use a downloaded binary snapshot of Rust to build Servo you should set the &lt;code&gt;system-rust&lt;/code&gt; setting to &lt;code&gt;false&lt;/code&gt;. With it set to &lt;code&gt;true&lt;/code&gt; as above it will expect to find a Rust of the correct version in the path.&lt;/p&gt;

&lt;p&gt;Servo uses the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Mozilla/Developer_guide/mach&quot;&gt;mach command line interface&lt;/a&gt; that is used to build Firefox. Once the &lt;code&gt;.servobuild&lt;/code&gt; is created then Servo can be built with:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ ./mach build
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Servo can be run with:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ ./mach run http://bluishcoder.co.nz
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To run the test suite:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ ./mach test
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Finding something to work on&lt;/h2&gt;

&lt;p&gt;The &lt;a href=&quot;https://github.com/servo/servo/issues&quot;&gt;github issue list&lt;/a&gt; has three useful &lt;a href=&quot;https://github.com/servo/servo/labels&quot;&gt;labels&lt;/a&gt; for finding work. They are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/servo/servo/labels/E-easy&quot;&gt;E-easy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/servo/servo/labels/E-less%20easy&quot;&gt;E-less easy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/servo/servo/labels/E-hard&quot;&gt;E-hard&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;For my first task I searched for &lt;code&gt;E-easy&lt;/code&gt; issues that were not currently assigned (using the &lt;code&gt;C-assigned&lt;/code&gt; label). I commented in the issue asking if I could work on it and it was then assigned to me by a Servo maintainer.&lt;/p&gt;

&lt;h2&gt;Submitting the Fix&lt;/h2&gt;

&lt;p&gt;Fixing the issue involved:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fork the &lt;a href=&quot;https://github.com/servo/servo&quot;&gt;Servo repository on github&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Clone my fork localling and make the changes required to the source in a branch I created for the issue I was working on.&lt;/li&gt;
&lt;li&gt;Commit the changes locally and push them to my fork on github.&lt;/li&gt;
&lt;li&gt;Raise a pull request for my branch.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Raising the pull request runs a couple of automated actions on the Servo repository. The first is an &lt;a href=&quot;https://github.com/servo/servo/pull/5219#issuecomment-80935607&quot;&gt;automated response thanking you for the changes&lt;/a&gt; followed by &lt;a href=&quot;https://github.com/servo/servo/pull/5219#issuecomment-80935612&quot;&gt;a link to the external critic review system&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Reviews&lt;/h2&gt;

&lt;p&gt;The Servo project uses the &lt;a href=&quot;https://critic.hoppipolla.co.uk/&quot;&gt;Critic review tool&lt;/a&gt;. This will &lt;a href=&quot;https://critic.hoppipolla.co.uk/r/4268&quot;&gt;contain data from your pull request&lt;/a&gt; and any reviews made by Servo reviewers.&lt;/p&gt;

&lt;p&gt;To address reviews I made the required changes and committed them to my local branch as seperate commits using the &lt;code&gt;fixup&lt;/code&gt; flag to &lt;code&gt;git commit&lt;/code&gt;. This associates the new commit with the original commit that contained the change. It allows easier squashing later.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git commit --fixup=&amp;lt;commit id of original commit&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The changes are then pushed to the github fork and the previously made pull request is automatically updated. The Critic review tool also automatically picks up the change and will associate the fix with the relevant lines in the review.&lt;/p&gt;

&lt;p&gt;With some back and forth the changes get approved and a request might be made to squash the commits. If &lt;code&gt;fixup&lt;/code&gt; was used to record the review changes then they will be squashed into the correct commits when you rebase:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git fetch origin
$ git rebase --autosquash origin/master
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Force pushing this to the fork will result in the pull request being updated. When the reviewer marks this as &lt;code&gt;r+&lt;/code&gt; the merge to master will start automatically, along with a build and test runs. If test failures happen these get added to the pull request and the review process starts again. If tests pass and it merges then it will be closed and the task is done.&lt;/p&gt;

&lt;p&gt;A full overview of the process is available on the github wiki under &lt;a href=&quot;https://github.com/servo/servo/wiki/Github-%26-Critic-PR-handling-101&quot;&gt;Github and Critic PR handling 101&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;The process overhead of committing to Servo is quite low. There are plenty of small tasks that don&#39;t require a deep knowledge of Rust. The first task I worked on was &lt;a href=&quot;https://github.com/servo/servo/pull/5202&quot;&gt;basically a search/replace&lt;/a&gt;. The second was more involved, implementing &lt;a href=&quot;https://github.com/servo/servo/pull/5219&quot;&gt;view-source protocol and text/plain handling&lt;/a&gt;. The latter allows the following to work in Servo:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ ./mach run view-source:http://bluishcoder.co.nz
$ ./mach run http://cd.pn/plainttext.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The main issues I encountered working with Rust and Servo were:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Compiling Servo is quite slow. Even changing private functions in a module would result in other modules rebuilding. I assume this is due to cross module inlining.&lt;/li&gt;
&lt;li&gt;I&#39;d hoped to get away from intermittent test failures like there are in Gecko but there seems to be the occasional &lt;a href=&quot;https://github.com/servo/servo/pull/5219#issuecomment-82340911&quot;&gt;intermittent reftest failure&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;The things I liked:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Very helpful Servo maintainers on IRC and in github/review comments.&lt;/li&gt;
&lt;li&gt;Typechecking in Rust helped find errors early.&lt;/li&gt;
&lt;li&gt;I found it easier comparing Servo code to HTML specifications and following them together than I do in Gecko.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;I hope to contribute more as time permits.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Phantom Types in Rust</title>
   <link href="http://bluishcoder.co.nz/2013/08/15/phantom_types_in_rust.html"/>
   <updated>2013-08-15T18:00:00+12:00</updated>
   <id>http://bluishcoder.co.nz/2013/08/15/phantom_types_in_rust</id>
   <content type="html">&lt;p&gt;Update 2013-08-16, I&#39;ve updated the first example based on feedback from the &lt;a href=&quot;https://news.ycombinator.com/item?id=6217314&quot;&gt;hacker news&lt;/a&gt;, &lt;a href=&quot;http://www.reddit.com/r/rust/comments/1kessp/phantom_types_in_rust/&quot;&gt;/r/rust&lt;/a&gt;, and &lt;a href=&quot;http://www.reddit.com/r/programming/comments/1keyx7/phantom_types_in_rust/&quot;&gt;/r/programming&lt;/a&gt; threads.&lt;/p&gt;

&lt;p&gt;I attended an overview of how the &lt;a href=&quot;https://github.com/mozilla/servo&quot;&gt;Servo&lt;/a&gt; browser engine, written in the &lt;a href=&quot;http://www.rust-lang.org/&quot;&gt;Rust programming language&lt;/a&gt;, implements the task of laying out of elements on a web page.  &lt;a href=&quot;http://pcwalton.github.io/&quot;&gt;Patrick Walton&lt;/a&gt; gave the talk and highlighted some of the implementation idioms in Servo. &lt;a href=&quot;http://www.haskell.org/haskellwiki/Phantom_type&quot;&gt;Phantom Types&lt;/a&gt; are used in a number of places so I thought I&#39;d try some phantom type examples to help learn more about Rust and Servo.&lt;/p&gt;

&lt;h2&gt;DSL type checking&lt;/h2&gt;

&lt;p&gt;Rust supports &lt;a href=&quot;http://static.rust-lang.org/doc/tutorial.html#generics&quot;&gt;generics&lt;/a&gt;. A phantom type is a type parameter that isn&#39;t used in the definition of the type. Imagine a datatype that is used to represent types in a simple DSL:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;enum T  { TI(int), TS(~str) }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The type &lt;code&gt;T&lt;/code&gt; has two constructors. A &lt;code&gt;TI&lt;/code&gt; representing an integer and a &lt;code&gt;TS&lt;/code&gt; representing a string. In Rust the &lt;code&gt;~&lt;/code&gt; prefixing &lt;code&gt;str&lt;/code&gt; means &#39;owned pointer to a string allocated on the heap&#39;.&lt;/p&gt;

&lt;p&gt;We have two functions that operate on this type. One to add two integers and the other to concatenate two strings:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;fn plus (lhs: T, rhs: T) -&amp;gt; T
fn concat (lhs: T, rhs: T) -&amp;gt; T 
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Using these functions looks like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;let d1 = TI(1);
let d2 = TI(2);
let x = plus(d1, d2);
display(&amp;amp;x);

let d1 = TS(~&quot;Hello, &quot;);
let d2 = TS(~&quot;World&quot;);
let y = concat (d1,d2);
display(&amp;amp;y);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Unforunately with the type definition of &lt;code&gt;T&lt;/code&gt; it is possible to add an integer and a string:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;let d1 = TI(1);
let d2 = TS(~&quot;Hello, &quot;);
let x = plus(d1, d2);
display(&amp;amp;x);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This won&#39;t be caught at compile time but, assuming the &lt;code&gt;plus&lt;/code&gt; function aborts on incorrect types, will fail at runtime. A full example that demonstrates this available in &lt;a href=&quot;http://bluishcoder.co.nz/rust/pt/test1.rs&quot;&gt;test1.rs&lt;/a&gt;. Compiling with &lt;code&gt;rustc test.rs&lt;/code&gt; and running the resulting &lt;code&gt;test&lt;/code&gt; produces:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;int: 3
str: Hello, World
task &amp;lt;unnamed&amp;gt; failed at &#39;error&#39;, test1.rs:12
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We can detect this issue at compile time by using phantom types. This involves changing the &lt;code&gt;T&lt;/code&gt; type to be:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;enum T&amp;lt;A&amp;gt;  { TI(int), TS(~str) }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Notice that the type index &lt;code&gt;A&lt;/code&gt; does not appear anywhere in the type definition on the right hand side. The definitions of &lt;code&gt;plus&lt;/code&gt; and &lt;code&gt;concat&lt;/code&gt; are changed to have a different type for the type index &lt;code&gt;A&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;fn plus (lhs: T&amp;lt;int&amp;gt;, rhs: T&amp;lt;int&amp;gt;) -&amp;gt; T&amp;lt;int&amp;gt;
fn concat (lhs: T&amp;lt;~str&amp;gt;, rhs: T&amp;lt;~str&amp;gt;) -&amp;gt; T&amp;lt;~str&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We also have to change the code that creates the &lt;code&gt;TI&lt;/code&gt; and &lt;code&gt;TS&lt;/code&gt; types. Code like the following will successfully typecheck:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;let d1 = TI(1);
let d2 = TS(~&quot;hello&quot;);
let x = plus(d1, d2);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is because &lt;code&gt;d1&lt;/code&gt; and &lt;code&gt;d2&lt;/code&gt; get their types inferred as &lt;code&gt;T&amp;lt;int&amp;gt;&lt;/code&gt; due to &lt;code&gt;plus&lt;/code&gt; requiring two &lt;code&gt;T&amp;lt;int&amp;gt;&lt;/code&gt; types. What&#39;s needed is to constrain the types of &lt;code&gt;d1&lt;/code&gt; and &lt;code&gt;d2&lt;/code&gt; to &lt;code&gt;T&amp;lt;int&amp;gt;&lt;/code&gt; and &lt;code&gt;T&amp;lt;~str&amp;gt;&lt;/code&gt; at the point of definition. This can be done with:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;let d1: T&amp;lt;int&amp;gt; = TI(1);
let d2: T&amp;lt;~str&amp;gt; = TS(~&quot;foo&quot;);
let x = plus(d1, d2);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Unfortunately this will still work:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;let d1: T&amp;lt;int&amp;gt; = TI(1);
let d2: T&amp;lt;int&amp;gt; = TS(~&quot;foo&quot;);
let x = plus(d1, d2);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;A better approach is to not use the constructors for the &lt;code&gt;T&amp;lt;A&amp;gt;&lt;/code&gt; enum and instead create our own:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;fn make_int (i: int)  -&amp;gt; T&amp;lt;int&amp;gt;  { TI(i) }
fn make_str (s: ~str) -&amp;gt; T&amp;lt;~str&amp;gt; { TS(s) }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Using these to create our values will ensure that they have the type of the argument passed to the function. Passing the wrong type is now an error:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;let d1 = make_int(1);
let d2 = make_str(~&quot;foo&quot;);
let x = plus(d1, d2);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In real code it&#39;s best to ensure that the constructors for &lt;code&gt;T&amp;lt;A&amp;gt;&lt;/code&gt; aren&#39;t public to ensure that callers from outside the module can&#39;t create them and subvert our attempts at better type checking.&lt;/p&gt;

&lt;p&gt;This code also ensures that the result of a &lt;code&gt;plus&lt;/code&gt; cannot be used in a &lt;code&gt;concat&lt;/code&gt; and vice versa. The following code produces a compile error:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;fn main() {
  let d1 = TI(1);
  let d2 = TI(2);
  let x = plus(d1, d2);
  display(&amp;amp;x);

  let d1 = TS(~&quot;Hello, &quot;);
  let d2 = TS(~&quot;World&quot;);
  let y = concat (d1,d2);
  display(&amp;amp;y);

  // Compile error here
  let z = concat(x, y);
  display(&amp;amp;z);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The full example is in &lt;a href=&quot;http://bluishcoder.co.nz/rust/pt/test2.rs&quot;&gt;test2.rs&lt;/a&gt; and compiling it results in:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;test2.rs:45:17: 45:18 error: mismatched types:
  expected `T&amp;lt;~str&amp;gt;` but found `T&amp;lt;int&amp;gt;` (expected ~str but found int)
test2.rs:45   let z = concat(x, y);
                         ^
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Commenting out the offending code allows the program to compile and run without errors. There is no runtime overhead or additional code generated when using phantom types. The types are erased at compile time and the resulting program is as if they hadn&#39;t been used at all - except that you know the code won&#39;t have the runtime failure as it passed type checking.&lt;/p&gt;

&lt;h2&gt;Safer strings&lt;/h2&gt;

&lt;p&gt;Another use of phantom types is for providing a taint to string types so they can&#39;t be used in an unsafe manner. An example of this is generating HTML template pages as the response to an HTTP request. The page is generated by concatenating various strings together. A string that comes from user input must be properly escaped before it is allowed to be embedded in an HTML page.&lt;/p&gt;

&lt;p&gt;In this example we have a type representing an HTML fragment used to compose an HTML page to be generated:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;enum Fragment { Str(~str) }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It only has one constructor, &lt;code&gt;Str&lt;/code&gt;, which holds the unique string containing the page data. A &lt;code&gt;render_page&lt;/code&gt; function displays a complete page:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;fn get_str(s: Fragment) -&amp;gt; ~str {
  match s {
    Str(s) =&amp;gt; { s }
  }
}

fn render_page(s: Fragment) {
  println(get_str(s));
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Functions exist to generate the head and body of the page with the latter including some form of data obtained elsewhere. Perhaps user input or the output of some other process:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;fn get_head() -&amp;gt; Fragment {
  Str(~&quot;&amp;lt;head&amp;gt;&amp;lt;/head&amp;gt;&quot;)
}  

fn get_body(s: Fragment) -&amp;gt; Fragment {
  Str(&quot;&amp;lt;body&amp;gt;&quot; + get_str(s) + &quot;&amp;lt;/body&amp;gt;&quot;)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Data from untrusted sources needs to be &#39;blessed&#39;. This should perform any escaping necessary to make the data safe to embed in the web page. The following is a &lt;code&gt;main&lt;/code&gt; program that generates and displays the page:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;fn main() {
  let user_input = get_user_input(~&quot;&amp;lt;script&amp;gt;alert(&#39;oops&#39;)&amp;lt;/script&amp;gt;&quot;);
  let page = generate_page(get_head(),
                           get_body(user_input));
  render_page(page);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This compiles and runs. The full example for trying it out is in &lt;a href=&quot;http://bluishcoder.co.nz/rust/pt/test3.rs&quot;&gt;test3.rs&lt;/a&gt;. The output is:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&amp;lt;script&amp;gt;alert(&#39;oops&#39;)&amp;lt;/script&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Unfortunately we forgot to call &lt;code&gt;bless&lt;/code&gt; and the user input was added unescaped. Ideally this should be a compile time error. If we add a phantom type to the &lt;code&gt;Fragment&lt;/code&gt; class we can differentiate between safe and unsafe strings with no runtime overhead:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;struct Safe;
struct Unsafe;

enum Fragment&amp;lt;T&amp;gt; { Str(~str) }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;All the generation functions now require safe fragments:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;fn generate_page(head: Fragment&amp;lt;Safe&amp;gt;, body: Fragment&amp;lt;Safe&amp;gt;) -&amp;gt; Fragment&amp;lt;Safe&amp;gt;
fn get_head() -&amp;gt; Fragment&amp;lt;Safe&amp;gt;
fn get_body(s: Fragment&amp;lt;Safe&amp;gt;) -&amp;gt; Fragment&amp;lt;Safe&amp;gt;
fn render_page(s: Fragment&amp;lt;Safe&amp;gt;)
fn bless(s: Fragment&amp;lt;Unsafe&amp;gt;) -&amp;gt; Fragment&amp;lt;Safe&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The exception is the function that obtains untrusted data. It returns an unsafe fragment:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;fn get_user_input(s: ~str) -&amp;gt; Fragment&amp;lt;Unsafe&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now the code that forgets to call bless (in &lt;a href=&quot;http://bluishcoder.co.nz/rust/pt/test4.rs&quot;&gt;test4.rs&lt;/a&gt;) results in a compile error:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;test4.rs:41:36: 41:46 error: mismatched types: expected `Fragment&amp;lt;Safe&amp;gt;`
   but found `Fragment&amp;lt;Unsafe&amp;gt;` (expected struct Safe but found struct Unsafe)
test4.rs:41                            get_body(user_input));
                                            ^~~~~~~~~~
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This approach can be used to help wherever untrusted data shouldn&#39;t be mixed with trusted data. Constructing SQL queries and generating URL&#39;s are other examples.&lt;/p&gt;

&lt;h2&gt;Servo&lt;/h2&gt;

&lt;p&gt;One of the uses of phantom types in Servo is in the &lt;a href=&quot;https://github.com/mozilla/servo/blob/master/src/components/script/dom/node.rs#L63&quot;&gt;Node&lt;/a&gt; type:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;// A phantom type representing the script task&#39;s view of this node. Script is able to mutate
/// nodes but may not access layout data.
pub struct ScriptView;

/// A phantom type representing the layout task&#39;s view of the node. Layout is not allowed to mutate
/// nodes but may access layout data.
pub struct LayoutView;

/// An HTML node.
///
/// `View` describes extra data associated with this node that this task has access to. For
/// the script task, this is the unit type `()`. For the layout task, this is
/// `layout::aux::LayoutData`.
pub struct Node&amp;lt;View&amp;gt; {
  ...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;A node has fields that should only be accessed or mutated on certain tasks. The script task can mutate nodes but cannot access data related to layout. The layout task is not allowed to mutate the node but can access the layout data. The prevents data races amongst the fields in the node.&lt;/p&gt;

&lt;p&gt;The is implemented using phantom types. The node type is indexed over a &lt;code&gt;View&lt;/code&gt; which can be &lt;code&gt;ScriptView&lt;/code&gt; or &lt;code&gt;LayoutView&lt;/code&gt;. There are methods implemented for &lt;code&gt;Node&amp;lt;ScriptView&amp;gt;&lt;/code&gt; which makes them only accessible to the script task:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;impl Node&amp;lt;ScriptView&amp;gt; {
  pub fn ....
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;An example of where the layout task gets the &lt;code&gt;LayoutView&lt;/code&gt; version of a &lt;code&gt;node&lt;/code&gt; is in &lt;code&gt;handle_reflow&lt;/code&gt;. This takes a &lt;a href=&quot;https://github.com/mozilla/servo/blob/master/src/components/script/layout_interface.rs#L93&quot;&gt;Reflow&lt;/a&gt; structure:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;pub struct Reflow {
    /// The document node.
    document_root: AbstractNode&amp;lt;ScriptView&amp;gt;,
    /// The style changes that need to be done.
    damage: DocumentDamage,
    /// The goal of reflow: either to render to the screen or to flush layout info for script.
    goal: ReflowGoal,
    /// The URL of the page.
    url: Url,
    /// The channel through which messages can be sent back to the script task.
    script_chan: ScriptChan,
    /// The current window size.
    window_size: Size2D&amp;lt;uint&amp;gt;,
    /// The channel that we send a notification to.
    script_join_chan: Chan&amp;lt;()&amp;gt;,
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note the &lt;code&gt;document_root&lt;/code&gt; is an &lt;code&gt;AbstractNode&amp;lt;ScriptView&amp;gt;&lt;/code&gt;. Inside the &lt;code&gt;handle_reflow&lt;/code&gt; function in the layout task it does:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;/// The high-level routine that performs layout tasks.
fn handle_reflow(&amp;amp;mut self, data: &amp;amp;Reflow) {
    // FIXME: Isolate this transmutation into a &quot;bridge&quot; module.
    let node: &amp;amp;AbstractNode&amp;lt;LayoutView&amp;gt; = unsafe {
        transmute(&amp;amp;data.document_root)
    };
    ...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The function &lt;code&gt;transmute&lt;/code&gt; is a cast. In this case it is converting the &lt;code&gt;AbstractNode&amp;lt;ScriptView&amp;gt;&lt;/code&gt; to an &lt;code&gt;AbstractNode&amp;lt;LayoutView&amp;gt;&lt;/code&gt;. The rest of the reflow deals with this so it can be proven to not access the script portions of the &lt;code&gt;node&lt;/code&gt; and therefore should not have data races in those parts.&lt;/p&gt;

&lt;h2&gt;Node simplified&lt;/h2&gt;

&lt;p&gt;I&#39;ve attempted to do a simplified example in Rust to test this type of phantom type usage. In &lt;a href=&quot;http://bluishcoder.co.nz/rust/pt/layout.rs&quot;&gt;layout.rs&lt;/a&gt; I have a basic &lt;code&gt;Node&lt;/code&gt; class that is indexed over the views:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;pub struct ScriptView;
pub struct LayoutView;

pub struct LayoutData {
  field3: ~str,
}

impl LayoutData {
  pub fn new() -&amp;gt; LayoutData {
    LayoutData { field3: ~&quot;layoutdata&quot; }
  }
}

pub struct Node&amp;lt;View&amp;gt; {
  field1: ~str,
  field2: ~str,

  priv layout_data: Option&amp;lt;@mut LayoutData&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note that &lt;code&gt;layout_data&lt;/code&gt; is private. A method implemented on &lt;code&gt;Node&amp;lt;LayoutView&amp;gt;&lt;/code&gt; provides public access to it:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;impl Node&amp;lt;LayoutView&amp;gt; {
  pub fn layout_data(&amp;amp;self) -&amp;gt; Option&amp;lt;@mut LayoutData&amp;gt; {
    self.layout_data
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Only the layout task has the &lt;code&gt;LayoutView&lt;/code&gt; of &lt;code&gt;Node&lt;/code&gt; so only it can get access to the layout_data method. A &lt;code&gt;LayoutView&lt;/code&gt; is obtained by casting (using &lt;code&gt;transmute&lt;/code&gt;):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;impl&amp;lt;View&amp;gt; Node&amp;lt;View&amp;gt; {
  pub fn change_view&amp;lt;View&amp;gt;(&amp;amp;self) -&amp;gt; &amp;amp;Node&amp;lt;View&amp;gt; {
    unsafe {
      transmute(self)
    }
  } 
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The file &lt;a href=&quot;http://bluishcoder.co.nz/rust/pt/main.rc&quot;&gt;main.rc&lt;/a&gt; contains the &lt;code&gt;main&lt;/code&gt; function that tests these layout types and functions:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;mod layout;

pub fn main() {
  use layout::*;

  let a = ~Node::new();
  std::io::println (a.field1);
  std::io::println (a.field2);
  let b: &amp;amp;Node&amp;lt;LayoutView&amp;gt; = a.change_view();
  match (b.layout_data()) {
    None =&amp;gt; { std::io::println(&quot;no layout data&quot;); }
    Some (data) =&amp;gt; { std::io::println(data.field3); }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This shows accessing the fields from the &lt;code&gt;ScriptView&lt;/code&gt; view of the &lt;code&gt;Node&lt;/code&gt; then switching to the &lt;code&gt;LayoutView&lt;/code&gt; to get access to the &lt;code&gt;layout_data&lt;/code&gt;. Trying to modify the non-layout fields with the &lt;code&gt;LayoutView&lt;/code&gt; should fail. Build the example with &lt;code&gt;rustc main.rc&lt;/code&gt; and make sure &lt;code&gt;main.rc&lt;/code&gt; and &lt;code&gt;layout.rs&lt;/code&gt; are in the current directory.&lt;/p&gt;

&lt;p&gt;The Servo code is quite a bit more complex than this but hopefully it helps with understanding the idiom of phantom type usage in nodes. If I&#39;ve made any mistakes in my understanding of how things work, please let me know!&lt;/p&gt;

&lt;h2&gt;Resources&lt;/h2&gt;

&lt;p&gt;Some resources I used in writing this post:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/mozilla/servo/&quot;&gt;Servo source&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/mozilla/rust/&quot;&gt;Rust source&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://en.wikibooks.org/wiki/Haskell/Phantom_types&quot;&gt;Wikibooks Haskell entry for Phantom Types&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.haskell.org/haskellwiki/Phantom_type&quot;&gt;Phantom Types on Haskell site&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://static.rust-lang.org/doc/tutorial.html&quot;&gt;Rust tutorial&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://pcwalton.github.io/blog/2012/12/26/typestate-is-dead/&quot;&gt;Typestate is dead&lt;/a&gt; post by Patrick Walton also uses phantom types.&lt;/li&gt;
&lt;/ul&gt;

</content>
 </entry>
 
 <entry>
   <title>Linking and calling Rust functions from C</title>
   <link href="http://bluishcoder.co.nz/2013/08/08/linking_and_calling_rust_functions_from_c.html"/>
   <updated>2013-08-08T01:00:00+12:00</updated>
   <id>http://bluishcoder.co.nz/2013/08/08/linking_and_calling_rust_functions_from_c</id>
   <content type="html">&lt;p&gt;At a recent &lt;a href=&quot;http://www.meetup.com/Functional-Programming-Auckland/events/126522972/&quot;&gt;functional programming meetup&lt;/a&gt; I was discussing with a colleague about how nice it would be to be able to use Rust in Gecko. This made me curious if it was possible to implement libraries in Rust and call them from C. After the meeting I asked in #rust and got pointed to some projects that showed the way.&lt;/p&gt;

&lt;p&gt;This lead me to trying to come up with as simple example as possible of compiling a Rust file into an object file, linking it to a C program and running it without the Rust runtime. The code is in my &lt;a href=&quot;https://github.com/doublec/rust-from-c-example&quot;&gt;rust-from-c-example&lt;/a&gt; github repository. It can be cloned and built with:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git clone http://github.com/doublec/rust-from-c-example
$ cd rust-from-c-example
$ make
$ ./test
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To avoid issues with integrating with the Rust runtime I&#39;ve opted to not use it. This means no threads and limits the standard library usage. This example is very simple, only demonstrating adding two numbers. Extending from this will be an interesting exercise to see how much Rust can be used.&lt;/p&gt;

&lt;p&gt;The Rust code is:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#[crate_type = &quot;lib&quot;];
#[no_std];
#[allow(ctypes)];

#[no_mangle]
pub extern fn add(lhs: uint, rhs: uint) -&amp;gt; uint {
  lhs + rhs
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The first three lines ensure that the file is compiled as a library, does not use the standard library and can use C types. The &lt;code&gt;no_mangle&lt;/code&gt; declaration stops the Rust default of mangling function names to include their module and version information. This means that &lt;code&gt;add&lt;/code&gt; in Rust is exported as &lt;code&gt;add&lt;/code&gt; for C programs. The &lt;code&gt;extern&lt;/code&gt; makes the function available from C and defaults to &lt;code&gt;cdecl&lt;/code&gt; calling format.&lt;/p&gt;

&lt;p&gt;To generate a &lt;code&gt;.o&lt;/code&gt; file that can be linked into a C program:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ rustc -c mylib.rs
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The C program creates an &lt;code&gt;extern&lt;/code&gt; declaration for &lt;code&gt;add&lt;/code&gt; and calls it:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;

extern unsigned int add(unsigned int lhs, unsigned int rhs);

int main() {
  printf(&quot;add(40,2) = %u\n&quot;, add(40,2));
  return 0;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Unfortunately we can&#39;t just compile and link with the &lt;code&gt;mylib.o&lt;/code&gt; file. This results in a linker error:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;mylib.o: In function `add&#39;:
mylib.rc:(.text+0x4f): undefined reference to `upcall_call_shim_on_rust_stack&#39;
collect2: error: ld returned 1 exit status
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Some searching pointed me to &lt;a href=&quot;https://github.com/neykov/armboot&quot;&gt;armboot&lt;/a&gt; which had a stub implementation for this in &lt;a href=&quot;https://github.com/neykov/armboot/blob/master/zero/zero.c&quot;&gt;zero.c&lt;/a&gt;. Compiling and linking to that worked successfully. A cut down variant of &lt;code&gt;zero.c&lt;/code&gt; is included in the project.&lt;/p&gt;

&lt;p&gt;There&#39;s a bunch of limitations with this approach. We&#39;re basically using Rust as a higher level C. This post on &lt;a href=&quot;http://brson.github.io/2013/03/10/embedding-rust-in-ruby/&quot;&gt;embedding Rust in Ruby&lt;/a&gt; details some of the limitations:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;When calling Rust code you will not be executing in a Rust task and will not have access to any runtime services that require task-local resources. Currently this means you can&#39;t use the local heap, nor can you spawn or communicate with tasks, nor call fail!() to unwind the stack. I/O doesn&#39;t work because core::io (unfortunately, and incorrectly) uses @-boxes. Even logging does not work. Calling any code that tries to access the task context will cause the process to abort. Because code is not executing in a task, it does not grow the stack, and instead runs on whatever stack the foreign caller was executing on. Recurse too deep and you will scribble on random memory.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;Hopefully some of these limitations will go away or &#39;zero runtime&#39; libraries will appear to make this sort of usage easier. Some resources that helped putting this together were:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://brson.github.io/2013/03/10/embedding-rust-in-ruby/&quot;&gt;Embedding Rust in Ruby&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/neykov/armboot&quot;&gt;armboot&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/pcwalton/sprocketnes&quot;&gt;sprocketnes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bitbucket.org/devin.jeanpierre/pyrite&quot;&gt;Pyrite&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</content>
 </entry>
 
 <entry>
   <title>Building Rust</title>
   <link href="http://bluishcoder.co.nz/2011/10/24/building-rust.html"/>
   <updated>2011-10-24T18:00:00+13:00</updated>
   <id>http://bluishcoder.co.nz/2011/10/24/building-rust</id>
   <content type="html">&lt;p&gt;Update 2011-11-08 - The steps to build Rust have changed since I wrote this post, there&#39;s now no need to build LLVM - it&#39;s included as a submodule in the Rust git repository and will automatically be cloned and built.&lt;/p&gt;

&lt;p&gt;A while ago I wrote a &lt;a href=&quot;http://bluishcoder.co.nz/2011/03/31/a-quick-look-at-the-rust-programming-language.html&quot;&gt;quick look at Rust&lt;/a&gt; post, describing how to build it and run some simple examples. Since that post the bootstrap compiler has gone away and the &lt;code&gt;rustc&lt;/code&gt; compiler, written in Rust, is the compiler to use.&lt;/p&gt;

&lt;p&gt;The instructions for &lt;a href=&quot;https://github.com/graydon/rust/wiki/Getting-started&quot;&gt;building Rust in the wiki&lt;/a&gt; are good but I&#39;ll briefly go through how I installed things on 64-bit Linux. The first step is to build the required version of &lt;code&gt;LLVM&lt;/code&gt; from the LLVM source repository. I use a git mirror and install to a local directory so as not to clash with other programs that use older &lt;code&gt;LLVM&lt;/code&gt; versions.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git clone git://github.com/earl/llvm-mirror.git
$ cd llvm-mirror
$ git reset --hard 9af578
$ CXX=&#39;g++ -m32&#39; CC=&#39;gcc -m32&#39; CFLAGS=-m32 CXXFLAGS=-m32 LDFLAGS=-m32 ./configure \
    --{build,host,target}=i686-unknown-linux-gnu \
    --enable-targets=x86,x86_64,cbe --enable-optimized --prefix=/home/chris/rust
$ make &amp;amp;&amp;amp; make install
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note the use of &lt;code&gt;prefix&lt;/code&gt; to ensure this custom &lt;code&gt;LLVM&lt;/code&gt; build is a local install. I also do a &lt;code&gt;git reset&lt;/code&gt; to go to the commit for SVN revision 142082 which is the current version that works with Rust according to the &lt;a href=&quot;https://github.com/graydon/rust/wiki/Getting-started&quot;&gt;wiki&lt;/a&gt;. After installation add the install &lt;code&gt;bin&lt;/code&gt; to the &lt;code&gt;PATH&lt;/code&gt; and &lt;code&gt;lib&lt;/code&gt; to &lt;code&gt;LD_LIBRARY_PATH&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ export PATH=~/rust/bin:$PATH
$ export LD_LIBRARY_PATH=~/rust/lib:$LD_LIBRARY_PATH
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Next step, clone and build Rust:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git clone git://github.com/graydon/rust
$ mkdir build
$ cd build
$ ../rust/configure
$ make
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The build process downloads an existing build for your platform to bootstrap from. It uses this to build a &lt;code&gt;stage1&lt;/code&gt; version of the compiler. This &lt;code&gt;stage1&lt;/code&gt; is used to build a &lt;code&gt;stage2&lt;/code&gt;, and that is then used to build a &lt;code&gt;stage3&lt;/code&gt;. All the built compilers should work exactly the same if things are working correctly. The compiler can be run within the &lt;code&gt;build&lt;/code&gt; directory, or outside it if you put the &lt;code&gt;stage3/bin&lt;/code&gt; directory in the path:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ export PATH=~/path/to/build/stage3/bin:$PATH
$ rustc
error: No input filename given.
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Test with a simple &#39;hello world&#39; program:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ cat hello.rs
use std;
import std::io::print;

fn main () {
  print (&quot;hello\n&quot;);
}
$ rustc hello.rs
$ ./hello
hello
&lt;/code&gt;&lt;/pre&gt;
</content>
 </entry>
 
 <entry>
   <title>A Quick Look at the Rust Programming Language</title>
   <link href="http://bluishcoder.co.nz/2011/03/31/a-quick-look-at-the-rust-programming-language.html"/>
   <updated>2011-03-31T20:00:00+13:00</updated>
   <id>http://bluishcoder.co.nz/2011/03/31/a-quick-look-at-the-rust-programming-language</id>
   <content type="html">&lt;p&gt;The &lt;a href=&quot;https://github.com/graydon/rust&quot;&gt;Rust Programming Language&lt;/a&gt; is a systems programming language being developed by Mozilla. It was announced last year and has seen quite a bit of development since then.&lt;/p&gt;

&lt;p&gt;I&#39;ve only been lightly following the development over the past year but recently decided to spend a bit more time looking at it. The following is a look at the language and implementation from someone who isn&#39;t heavily involved in the development so don&#39;t take anything I write as gospel. Hopefully I don&#39;t get too many things wrong.&lt;/p&gt;

&lt;p&gt;The &lt;a href=&quot;https://github.com/graydon/rust/wiki/Language-FAQ&quot;&gt;Rust Language FAQ&lt;/a&gt; lists the following summary of features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Memory safe. No null pointers, wild pointers, etc. Automatic storage management.&lt;/li&gt;
&lt;li&gt;Mutability control. Immutable by default. No shared mutable state across tasks.&lt;/li&gt;
&lt;li&gt;Dynamic execution safety: task failure / unwinding, trapping, logging. RAII / dtors.&lt;/li&gt;
&lt;li&gt;Typestate system: ability to define complex invariants that hold over data structures.&lt;/li&gt;
&lt;li&gt;Explicit memory control. Layout and allocation control. Interior / value types.&lt;/li&gt;
&lt;li&gt;Very lightweight tasks (coroutines). Cheap to spawn thousands-to-millions.&lt;/li&gt;
&lt;li&gt;Stack iterators (effectively lambda-blocks w/o heap allocation).&lt;/li&gt;
&lt;li&gt;Static, native compilation. Emits ELF / PE / Mach-o files.&lt;/li&gt;
&lt;li&gt;Direct and simple interface to C code (switch stacks and call, ~8 insns).&lt;/li&gt;
&lt;li&gt;Multi-paradigm. pure-functional, concurrent-actor, imperative-procedural, OO.&lt;/li&gt;
&lt;li&gt;First class functions with bindings.&lt;/li&gt;
&lt;li&gt;Structurally-typed objects (no nominal types or type hierarchy).&lt;/li&gt;
&lt;li&gt;Multi-platform. Developed on Windows, Linux, OSX.&lt;/li&gt;
&lt;li&gt;UTF8 strings, assortment of machine-level types.&lt;/li&gt;
&lt;li&gt;Works with existing native toolchains. GDB / Valgrind / Shark / etc.&lt;/li&gt;
&lt;li&gt;Practical rule-breaking: can break safety rules, if explicit about where and how.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;The Rust implementation is still in the &#39;only useful for Rust developers&#39; state since the implementation and libraries are still being developed. There are two Rust compilers in various states of development. They are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;rustboot - written in O&#39;Caml with it&#39;s own x86 code generation backend. This is being used to bootstrap the &#39;rustc&#39; implementation.&lt;/li&gt;
&lt;li&gt;rustc - self hosting compiler written in Rust and bootstrapped using &#39;rustbost&#39;. Code generation is done using LLVM.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;&lt;code&gt;rustboot&lt;/code&gt; can be used to write Rust programs and try out the language. &lt;code&gt;rustc&lt;/code&gt; is still in heavy development and only very basic stuff works from what I can see.&lt;/p&gt;

&lt;h2&gt;Building&lt;/h2&gt;

&lt;p&gt;Please note, as of 2011-10-24, the instructions for building Rust below are out of date. For updated instructions read &lt;a href=&quot;http://bluishcoder.co.nz/2011/10/24/building-rust.html&quot;&gt;my recent post on building Rust&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;a href=&quot;https://github.com/graydon/rust/wiki/Getting-started&quot;&gt;instructions to build Rust&lt;/a&gt; are in the wiki. One important point is you need an SVN version of LLVM. I built this from source using a git mirror of LLVM (on 64 bit x86 Linux):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git clone git://github.com/earl/llvm-mirror.git
$ cd llvm-miror
~/llvm-mirror $ CXX=&#39;g++ -m32&#39; CC=&#39;gcc -m32&#39; CFLAGS=-m32 CXXFLAGS=-m32 \
                LDFLAGS=-m32 ./configure --enable-shared --disable-bindings \
                 --{build,host,target}=i686-unknown-linux-gnu \
                 --enable-targets=x86,x86_64,cbe
~/llvm-mirror $ make &amp;amp;&amp;amp; make install
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Once you have LLVM and the other pre-requisites installed:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git clone git://github.com/graydon/rust.git
$ cd rust
~/rust $ mkdir build
~/rust $ cd build
~/rust/build $ ../configure
~/rust/build $ make check
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This builds the &lt;code&gt;rustboot&lt;/code&gt; compiler, uses that to compile &lt;code&gt;rustc&lt;/code&gt;, then runs a series of tests using both builds. If you have &lt;code&gt;valgrind&lt;/code&gt; installed this will be slow as the tests are run under &lt;code&gt;valgrind&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;Bootstrap Compiler&lt;/h2&gt;

&lt;p&gt;The bootstrap compiler executable is &lt;code&gt;boot/rustboot&lt;/code&gt;. The command to execute it, assuming the build occurred in the directory &lt;code&gt;~/rust/build&lt;/code&gt; is:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;~/rust/build $ OCAMLRUNPARAM=&quot;b1&quot; boot/rustboot -L boot -o hello hello.rs
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This will compile a Rust program in &lt;code&gt;hello.rs&lt;/code&gt; and leave an executable &lt;code&gt;hello&lt;/code&gt;. The &lt;code&gt;-L&lt;/code&gt; argument references the &lt;code&gt;boot&lt;/code&gt; subdirectory containing the Rust standard library in &lt;code&gt;libstd.so&lt;/code&gt;. A &#39;hello world&#39; program for testing is:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;use std;

fn main() {
  log &quot;Hello World&quot;;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To run the executable you&#39;ll need to adjust the &lt;code&gt;LD_LIBRARY_PATH&lt;/code&gt; to include the &lt;code&gt;rt&lt;/code&gt; subdirectory to pick up the Rust runtime shared library:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;~/rust/build $ OCAMLRUNPARAM=&quot;b1&quot; boot/rustboot -L boot -o test test.rs
~/rust/build $ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:~/rust/build/rt
~/rust/build $ ./hello
rt: ---
rt: ca09:main:main: rust: Hello World
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;rustc Compiler&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;rustc&lt;/code&gt; compiler lives in &lt;code&gt;stage0/rustc&lt;/code&gt;. The output of this compiler is LLVM bytecode which must then be compiled using LLVM tools. To compile the &lt;code&gt;hello.rs&lt;/code&gt; program mentioned in the previous section:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;~/rust/build $ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:~/rust/build/rt:~/rust/build/rustllvm
~/rust/build $ stage0/rustc -nowarn -L stage0 -o hello.bc hello.rs
~/rust/build $ llc -march=x86 -relocation-model=pic -o hello.s hello.bc
~/rust/build $ gcc -fPIC -march=i686 -m32 -fno-rtti -fno-exceptions -g \
               -o hello.o -c hello.s
~/rust/build $ gcc -fPIC -march=i686 -m32 -fno-rtti -fno-exceptions -g \
               stage0/glue.o -o hello hello.o -Lstage0 -Lrt -lrustrt
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note the need to add the &lt;code&gt;rustllvm&lt;/code&gt; directory to &lt;code&gt;LD_LIBRARY_PATH&lt;/code&gt; to pick up a shared library. That sequence of commands will compile the &lt;code&gt;hello.rs&lt;/code&gt; file to LLVM bytecode. &lt;code&gt;llc&lt;/code&gt; compiles the bytecode to x86 assembly. &lt;code&gt;gcc&lt;/code&gt; compiles this to an object file, followed by a final &lt;code&gt;gcc&lt;/code&gt; invocation to link it. And to run:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;~/rust/build $ ./hello
rt: ---
rt: ee0b:main:main: rust: Hello World
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Rust Language Details&lt;/h2&gt;

&lt;p&gt;For examples of the Rust language there are multiple tests and the source code to &lt;code&gt;rustc&lt;/code&gt; itself in the &lt;a href=&quot;git://github.com/graydon/rust.git&quot;&gt;github repository&lt;/a&gt;. The &lt;a href=&quot;https://github.com/graydon/rust/wiki&quot;&gt;wiki&lt;/a&gt; has a link to the PDF documentation, &lt;a href=&quot;https://github.com/downloads/graydon/rust/rust-2011-02-25-snap.pdf&quot;&gt;currently a snapshot from 2011-02-25&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The following are some quick examples of Rust features that work with the bootstrap compiler.&lt;/p&gt;

&lt;h3&gt;Foreign Function Interface&lt;/h3&gt;

&lt;p&gt;This program uses the C FFI to call the &#39;puts&#39; function from the C shared library:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;use std;
import std._str.rustrt.sbuf;
import std._str;

native mod libc = &quot;libc.so.6&quot; {
    fn puts(sbuf s) -&amp;gt; int;
}

unsafe fn main() {
  libc.puts(_str.buf(&quot;hello from C\n&quot;));
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Compile and run with:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;~/rust/build $ OCAMLRUNPARAM=&quot;b1&quot; boot/rustboot -L boot -o cffi cffi.rs
~/rust/build $ ./cffi
hello from C
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Command Line Arguments&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;use std;

fn main(vec[str] args) {
  for(str s in args) {
    log s;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;main&lt;/code&gt; function takes a vector of strings as the argument. This holds the command line arguments passed to the program. The example iterates over the vector printing out each element.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;~/rust/build $ OCAMLRUNPARAM=&quot;b1&quot; boot/rustboot -L boot -o args args.rs
~/rust/build $ ./args a b c
rt: ---
rt: ccca:main:main: rust: ./args
rt: ccca:main:main: rust: a
rt: ccca:main:main: rust: b
rt: ccca:main:main: rust: c
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Factorial&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;use std;

fn fac(uint x) -&amp;gt; uint {
  if (x &amp;lt;= 1u) {
    ret 1u;
  }
  else {
    ret x * fac(x-1u);
  }
}

fn main() {
  log fac(5u);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;No language is complete without showing how factorial can be computed.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;~/rust/build $ ./fac
rt: ---
rt: d158:main:main: rust: 120 (0x78)
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Spawning Tasks&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;use std;

impure fn logger(port[str] logs) {
  let int i = 0;
  while (i &amp;lt; 2) {
    auto msg &amp;lt;- logs;
    log msg;
    i = i + 1;
  }
  log &quot;logger exited&quot;;
}

impure fn main() {
  let port[str] logs = port();
  let task p = spawn logger(logs);
  auto out = chan(logs);
  out &amp;lt;| &quot;Hello&quot;;
  out &amp;lt;| &quot;World&quot;;
  join p;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;A port is the receiving end of a typed inter task communication mechanism. A channel is the sending end of the communication mechanism. &lt;code&gt;&amp;lt;|&lt;/code&gt; sends to the port and &lt;code&gt;&amp;lt;-&lt;/code&gt; receives from the channel.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;~/rust/build $ OCAMLRUNPARAM=&quot;b1&quot; boot/rustboot -L boot -o spawn spawn.rs
~/rust/build $ ./spawn
rt: ---
rt: 9a73:main:spawn.rs:1: rust: Hello
rt: 9a73:main:spawn.rs:1: rust: World
rt: 9a73:main:spawn.rs:1: rust: logger exited
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Types&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;use std;

tag list {
  nil;
  cons(int, @list);
}

fn list_len(@list l) -&amp;gt; uint {
   fn len(@list l, &amp;amp;uint n) -&amp;gt; uint {
    alt (*l) {
      case (nil) {
        ret n;
      }
      case (cons(_, ?xs)) {
        ret len(xs, n+1u);
      }
    }
  }
  ret len(l, 0u);
}

fn main() {
  let @list l = @cons(1, @cons(2, @cons(3, @nil)));
  log list_len(l);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This example creates a &lt;code&gt;list&lt;/code&gt; type. It has constructors for an empty list, &lt;code&gt;nil&lt;/code&gt;, and a &lt;code&gt;cons&lt;/code&gt; containing an integer and the rest of the list. The &#39;@&#39; prefixed to the &lt;code&gt;list&lt;/code&gt; type in places means that that variable holds a boxed object. That is, it&#39;s a reference-counted heap allocation.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;list_len&lt;/code&gt; function shows the use of a local function which pattern matches over the list (using the &lt;code&gt;alt&lt;/code&gt; keyword) and keeps a running total of the list length. The &lt;code&gt;main&lt;/code&gt; function creates a &lt;code&gt;list&lt;/code&gt; and prints the length.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;~/rust/build $ OCAMLRUNPARAM=&quot;b1&quot; boot/rustboot -L boot -o types types.rs
~/rust/build $ ./types
rt: ---
rt: 8126:main:main: rust: 3 (0x3)
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Typestate&lt;/h3&gt;

&lt;p&gt;The typestate system is one of the things that most interests me about Rust. If you&#39;ve been reading my &lt;a href=&quot;http://bluishcoder.co.nz/tags/ats/&quot;&gt;ATS&lt;/a&gt; posts, in particular the ones involving &lt;a href=&quot;http://bluishcoder.co.nz/2011/02/26/reading-data-from-a-file-in-ats.html&quot;&gt;type safe checking of array bounds&lt;/a&gt;, you&#39;ll know I&#39;m interested in languages that can help with detecting programming problems at compile time. It seems to me that the typesafe system can help here.&lt;/p&gt;

&lt;p&gt;Here&#39;s a contrived example demonstrating one use of typestate. &lt;code&gt;main&lt;/code&gt; takes a vector of strings containing the command line arguments. I want to call a function, &lt;code&gt;dosomething&lt;/code&gt;, that will use these arguments but for some reason there must be never more than 2 arguments. Imagine I&#39;m calling some C routine that&#39;ll die if I do.&lt;/p&gt;

&lt;p&gt;I could check at runtime that the number of arguments is less than three. Here&#39;s an example that does this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;use std;
import std._vec;

fn dosomething(&amp;amp;vec[str] args) {
  log &quot;vector length is less than 3&quot;;
}

fn main(vec[str] args) {
  log _vec.len[str](args);
  check (_vec.len[str](args) &amp;lt; 3u);
  dosomething(args);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Some example runs:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;~/rust/build $ OCAMLRUNPARAM=&quot;b1&quot; boot/rustboot -L boot -o ts1 ts1.rs
~/rust/build $ ./ts1 a
rt: ---
rt: b3b1:main:main: rust: 2 (0x2)
rt: b3b1:main:main: rust: vector length is less than 3
~/rust/build $ ./ts1 a b
rt: ---
rt: d884:main:main: rust: 3 (0x3)
rt: d884:main:main: upcall fail &#39;.t0 &amp;lt; 3u&#39;, ts2.rs:5
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Notice the last invocation has failed since three arguments are used (the program name is counted as an argument).&lt;/p&gt;

&lt;p&gt;It would be good to be able to check at compile time that somewhere the assertion holds that the number of arguments is less than three. In our example if we left the &lt;code&gt;check&lt;/code&gt; call out, the program would still compile, but &lt;code&gt;dosomething&lt;/code&gt; might do something disasterous. We can tell the typestate system that the precondition must hold for callers of &lt;code&gt;dosomething&lt;/code&gt; and to fail at compile time by adding a &#39;prove statement&#39; to the function:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;use std;
import std._vec;

fn prove_length(&amp;amp;vec[str] args, uint n) -&amp;gt; bool {
  ret _vec.len[str](args) &amp;lt; n;
}

fn dosomething(&amp;amp;vec[str] args) : prove_length(args, 3u) {
  log &quot;vector length is less than 3&quot;;
}

fn main(vec[str] args) {
  log _vec.len[str](args);
  dosomething(args);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The addition of &lt;code&gt;: prove_length(args, 3u)&lt;/code&gt; to the function tells the typestate system that this boolean function must evaluate to true. It examines what it knows of the constraints made via &lt;code&gt;check&lt;/code&gt; statements and the like to see if it can prove that this is the case. If it is not then a compile error occurs. The above program will fail to compile:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;~/rust/build $ OCAMLRUNPARAM=&quot;b1&quot; boot/rustboot -L boot -o ts2 ts2.rs
ts2.rs:14:13:14:19: error: Unsatisfied precondition constraint prove_length(args, 3u) 
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If we add a &lt;code&gt;check&lt;/code&gt; statement we are adding an assertion check that this precondition holds. Typestate makes note of this and will now allow that call to &lt;code&gt;dosomething&lt;/code&gt; to compile:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;use std;
import std._vec;

fn prove_length(&amp;amp;vec[str] args, uint n) -&amp;gt; bool {
  ret _vec.len[str](args) &amp;lt; n;
}

fn dosomething(&amp;amp;vec[str] args) : prove_length(args, 3u) {
  log &quot;vector length is less than 3&quot;;
}

fn main(vec[str] args) {
  log _vec.len[str](args);
  check prove_length(arg, 3u);
  dosomething(args);
}

~/rust/build $ OCAMLRUNPARAM=&quot;b1&quot; boot/rustboot -L boot -o ts3 ts3.rs
~/rust/build $ ./ts3
rt: ---
rt: d9e6:main:main:                       rust: 1 (0x1)
rt: d9e6:main:main:                       rust: vector length is less than 3
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It&#39;ll be interesting to see how typestate is used in the standard library and third party libraries to help with compile time checking of code.&lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Rust is an interesting language and there&#39;s quite a bit more to it than I&#39;ve covered here. I just picked random features to try. I&#39;m looking forward to &lt;code&gt;rustc&lt;/code&gt; being more complete and trying out some of the language features in more &#39;real world&#39; examples to get a feel for it.&lt;/p&gt;
</content>
 </entry>
 
 
</feed>
