servo: Merge #4719 - Update rustc to 00b112c45a604fa6f4b59af2a40c9deeadfdb7c6/rustc-1.0.0-dev (from servo:rustup_20150109); r=jdm
authorJosh Matthews <josh@joshmatthews.net>
Tue, 27 Jan 2015 18:15:50 -0700
changeset 382278 683502b1b8e9954f61459faa23dada130de02ead
parent 382277 cbd090b9078c79c94021aff204dbfcf28b5eb05e
child 382279 33b951eaf1d23781e147c3cf7a66ab3a4e031170
push id7198
push userjlorenzo@mozilla.com
push dateTue, 18 Apr 2017 12:07:49 +0000
treeherdermozilla-beta@d57aa49c3948 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjdm
servo: Merge #4719 - Update rustc to 00b112c45a604fa6f4b59af2a40c9deeadfdb7c6/rustc-1.0.0-dev (from servo:rustup_20150109); r=jdm Source-Repo: https://github.com/servo/servo Source-Revision: 3f9012864a2cd927cf17a8e11dfa6922add1b7df
servo/cargo-nightly-build
servo/components/canvas/canvas_paint_task.rs
servo/components/compositing/Cargo.toml
servo/components/compositing/compositor.rs
servo/components/compositing/compositor_layer.rs
servo/components/compositing/compositor_task.rs
servo/components/compositing/constellation.rs
servo/components/compositing/headless.rs
servo/components/compositing/lib.rs
servo/components/compositing/pipeline.rs
servo/components/compositing/scrolling.rs
servo/components/compositing/windowing.rs
servo/components/devtools/actor.rs
servo/components/devtools/actors/console.rs
servo/components/devtools/actors/inspector.rs
servo/components/devtools/actors/root.rs
servo/components/devtools/actors/tab.rs
servo/components/devtools/lib.rs
servo/components/devtools/protocol.rs
servo/components/devtools_traits/lib.rs
servo/components/gfx/Cargo.toml
servo/components/gfx/buffer_map.rs
servo/components/gfx/display_list/mod.rs
servo/components/gfx/display_list/optimizer.rs
servo/components/gfx/filters.rs
servo/components/gfx/font.rs
servo/components/gfx/font_cache_task.rs
servo/components/gfx/font_template.rs
servo/components/gfx/lib.rs
servo/components/gfx/paint_context.rs
servo/components/gfx/paint_task.rs
servo/components/gfx/platform/freetype/font.rs
servo/components/gfx/platform/freetype/font_context.rs
servo/components/gfx/platform/freetype/font_list.rs
servo/components/gfx/platform/macos/font.rs
servo/components/gfx/platform/macos/font_context.rs
servo/components/gfx/platform/macos/font_list.rs
servo/components/gfx/platform/macos/font_template.rs
servo/components/gfx/text/glyph.rs
servo/components/gfx/text/text_run.rs
servo/components/gfx/text/util.rs
servo/components/layout/Cargo.toml
servo/components/layout/block.rs
servo/components/layout/construct.rs
servo/components/layout/context.rs
servo/components/layout/css/matching.rs
servo/components/layout/display_list_builder.rs
servo/components/layout/floats.rs
servo/components/layout/flow.rs
servo/components/layout/flow_list.rs
servo/components/layout/flow_ref.rs
servo/components/layout/fragment.rs
servo/components/layout/incremental.rs
servo/components/layout/inline.rs
servo/components/layout/layout_debug.rs
servo/components/layout/layout_task.rs
servo/components/layout/lib.rs
servo/components/layout/list_item.rs
servo/components/layout/model.rs
servo/components/layout/parallel.rs
servo/components/layout/table.rs
servo/components/layout/table_caption.rs
servo/components/layout/table_cell.rs
servo/components/layout/table_colgroup.rs
servo/components/layout/table_row.rs
servo/components/layout/table_rowgroup.rs
servo/components/layout/table_wrapper.rs
servo/components/layout/text.rs
servo/components/layout/traversal.rs
servo/components/layout/util.rs
servo/components/layout/wrapper.rs
servo/components/layout_traits/lib.rs
servo/components/msg/Cargo.toml
servo/components/msg/compositor_msg.rs
servo/components/msg/constellation_msg.rs
servo/components/msg/lib.rs
servo/components/net/Cargo.toml
servo/components/net/about_loader.rs
servo/components/net/data_loader.rs
servo/components/net/fetch/cors_cache.rs
servo/components/net/fetch/request.rs
servo/components/net/fetch/response.rs
servo/components/net/file_loader.rs
servo/components/net/http_loader.rs
servo/components/net/image/base.rs
servo/components/net/image/holder.rs
servo/components/net/image_cache_task.rs
servo/components/net/lib.rs
servo/components/net/local_image_cache.rs
servo/components/net/resource_task.rs
servo/components/net/sniffer_task.rs
servo/components/net/storage_task.rs
servo/components/plugins/jstraceable.rs
servo/components/plugins/lib.rs
servo/components/plugins/lints/ban.rs
servo/components/plugins/lints/inheritance_integrity.rs
servo/components/plugins/lints/privatize.rs
servo/components/plugins/lints/str_to_string.rs
servo/components/plugins/lints/transmute_type.rs
servo/components/plugins/lints/unrooted_must_root.rs
servo/components/plugins/reflector.rs
servo/components/plugins/utils.rs
servo/components/script/Cargo.toml
servo/components/script/cors.rs
servo/components/script/devtools.rs
servo/components/script/dom/attr.rs
servo/components/script/dom/bindings/callback.rs
servo/components/script/dom/bindings/codegen/Bindings.conf
servo/components/script/dom/bindings/codegen/CodegenRust.py
servo/components/script/dom/bindings/conversions.rs
servo/components/script/dom/bindings/error.rs
servo/components/script/dom/bindings/global.rs
servo/components/script/dom/bindings/js.rs
servo/components/script/dom/bindings/refcounted.rs
servo/components/script/dom/bindings/str.rs
servo/components/script/dom/bindings/structuredclone.rs
servo/components/script/dom/bindings/trace.rs
servo/components/script/dom/bindings/utils.rs
servo/components/script/dom/blob.rs
servo/components/script/dom/browsercontext.rs
servo/components/script/dom/canvasrenderingcontext2d.rs
servo/components/script/dom/create.rs
servo/components/script/dom/cssstyledeclaration.rs
servo/components/script/dom/dedicatedworkerglobalscope.rs
servo/components/script/dom/document.rs
servo/components/script/dom/domexception.rs
servo/components/script/dom/domtokenlist.rs
servo/components/script/dom/element.rs
servo/components/script/dom/event.rs
servo/components/script/dom/eventtarget.rs
servo/components/script/dom/formdata.rs
servo/components/script/dom/htmlbuttonelement.rs
servo/components/script/dom/htmlcanvaselement.rs
servo/components/script/dom/htmlcollection.rs
servo/components/script/dom/htmlelement.rs
servo/components/script/dom/htmlfieldsetelement.rs
servo/components/script/dom/htmlformelement.rs
servo/components/script/dom/htmliframeelement.rs
servo/components/script/dom/htmlimageelement.rs
servo/components/script/dom/htmlinputelement.rs
servo/components/script/dom/htmllinkelement.rs
servo/components/script/dom/htmlmediaelement.rs
servo/components/script/dom/htmlobjectelement.rs
servo/components/script/dom/htmloptgroupelement.rs
servo/components/script/dom/htmloptionelement.rs
servo/components/script/dom/htmlscriptelement.rs
servo/components/script/dom/htmlselectelement.rs
servo/components/script/dom/htmltablecellelement.rs
servo/components/script/dom/htmltableelement.rs
servo/components/script/dom/htmltextareaelement.rs
servo/components/script/dom/keyboardevent.rs
servo/components/script/dom/macros.rs
servo/components/script/dom/node.rs
servo/components/script/dom/storage.rs
servo/components/script/dom/treewalker.rs
servo/components/script/dom/urlsearchparams.rs
servo/components/script/dom/window.rs
servo/components/script/dom/worker.rs
servo/components/script/dom/workerglobalscope.rs
servo/components/script/dom/xmlhttprequest.rs
servo/components/script/dom/xmlhttprequesteventtarget.rs
servo/components/script/layout_interface.rs
servo/components/script/lib.rs
servo/components/script/page.rs
servo/components/script/parse/html.rs
servo/components/script/script_task.rs
servo/components/script/tests.rs
servo/components/script/textinput.rs
servo/components/script/timers.rs
servo/components/script_traits/Cargo.toml
servo/components/script_traits/lib.rs
servo/components/servo/.cargo/config
servo/components/servo/Cargo.lock
servo/components/servo/Cargo.toml
servo/components/servo/lib.rs
servo/components/servo/main.rs
servo/components/style/Cargo.toml
servo/components/style/font_face.rs
servo/components/style/legacy.rs
servo/components/style/lib.rs
servo/components/style/media_queries.rs
servo/components/style/namespaces.rs
servo/components/style/node.rs
servo/components/style/properties/mod.rs.mako
servo/components/style/selector_matching.rs
servo/components/style/selectors.rs
servo/components/style/stylesheets.rs
servo/components/style/values.rs
servo/components/util/Cargo.toml
servo/components/util/bloom.rs
servo/components/util/cache.rs
servo/components/util/cursor.rs
servo/components/util/deque/mod.rs
servo/components/util/fnv.rs
servo/components/util/geometry.rs
servo/components/util/lib.rs
servo/components/util/logical_geometry.rs
servo/components/util/memory.rs
servo/components/util/opts.rs
servo/components/util/persistent_list.rs
servo/components/util/range.rs
servo/components/util/smallvec.rs
servo/components/util/sort.rs
servo/components/util/str.rs
servo/components/util/task.rs
servo/components/util/task_state.rs
servo/components/util/taskpool.rs
servo/components/util/tid.rs
servo/components/util/time.rs
servo/components/util/vec.rs
servo/components/util/workqueue.rs
servo/ports/cef/.cargo/config
servo/ports/cef/Cargo.lock
servo/ports/cef/browser.rs
servo/ports/cef/browser_host.rs
servo/ports/cef/command_line.rs
servo/ports/cef/cookie.rs
servo/ports/cef/core.rs
servo/ports/cef/drag_data.rs
servo/ports/cef/eutil.rs
servo/ports/cef/frame.rs
servo/ports/cef/lib.rs
servo/ports/cef/macros.rs
servo/ports/cef/print_settings.rs
servo/ports/cef/process_message.rs
servo/ports/cef/request.rs
servo/ports/cef/request_context.rs
servo/ports/cef/response.rs
servo/ports/cef/stream.rs
servo/ports/cef/string.rs
servo/ports/cef/string_map.rs
servo/ports/cef/string_multimap.rs
servo/ports/cef/stubs.rs
servo/ports/cef/task.rs
servo/ports/cef/v8.rs
servo/ports/cef/values.rs
servo/ports/cef/window.rs
servo/ports/cef/wrappers.rs
servo/ports/cef/xml_reader.rs
servo/ports/cef/zip_reader.rs
servo/ports/glfw/Cargo.toml
servo/ports/glutin/Cargo.toml
servo/ports/glutin/lib.rs
servo/ports/glutin/window.rs
servo/ports/gonk/.cargo/config
servo/ports/gonk/Cargo.lock
servo/ports/gonk/src/lib.rs
servo/ports/gonk/src/window.rs
servo/python/servo/build_commands.py
servo/rust-snapshot-hash
servo/support/rust-task_info/src/lib.rs
servo/tests/contenttest.rs
servo/tests/reftest.rs
--- a/servo/cargo-nightly-build
+++ b/servo/cargo-nightly-build
@@ -1,1 +1,1 @@
-2014-12-18
+2015-01-09
--- a/servo/components/canvas/canvas_paint_task.rs
+++ b/servo/components/canvas/canvas_paint_task.rs
@@ -4,19 +4,19 @@
 
 use azure::azure_hl::{DrawTarget, Color, SurfaceFormat, BackendType, StrokeOptions, DrawOptions};
 use azure::azure_hl::{ColorPattern, PatternRef};
 use geom::rect::Rect;
 use geom::size::Size2D;
 use servo_util::task::spawn_named;
 
 use std::borrow::ToOwned;
-use std::comm;
+use std::sync::mpsc::{channel, Sender};
 
-#[deriving(Clone)]
+#[derive(Clone)]
 pub enum CanvasMsg {
     FillRect(Rect<f32>),
     ClearRect(Rect<f32>),
     StrokeRect(Rect<f32>),
     Recreate(Size2D<i32>),
     SendPixelContents(Sender<Vec<u8>>),
     Close,
 }
@@ -34,22 +34,22 @@ impl CanvasPaintTask {
             drawtarget: CanvasPaintTask::create(size),
             fill_color: ColorPattern::new(Color::new(0., 0., 0., 1.)),
             stroke_color: ColorPattern::new(Color::new(0., 0., 0., 1.)),
             stroke_opts: StrokeOptions::new(1.0, 1.0),
         }
     }
 
     pub fn start(size: Size2D<i32>) -> Sender<CanvasMsg> {
-        let (chan, port) = comm::channel::<CanvasMsg>();
-        spawn_named("CanvasTask".to_owned(), proc() {
+        let (chan, port) = channel::<CanvasMsg>();
+        spawn_named("CanvasTask".to_owned(), move || {
             let mut painter = CanvasPaintTask::new(size);
 
             loop {
-                match port.recv() {
+                match port.recv().unwrap() {
                     CanvasMsg::FillRect(ref rect) => painter.fill_rect(rect),
                     CanvasMsg::StrokeRect(ref rect) => painter.stroke_rect(rect),
                     CanvasMsg::ClearRect(ref rect) => painter.clear_rect(rect),
                     CanvasMsg::Recreate(size) => painter.recreate(size),
                     CanvasMsg::SendPixelContents(chan) => painter.send_pixel_contents(chan),
                     CanvasMsg::Close => break,
                 }
             }
@@ -76,12 +76,12 @@ impl CanvasPaintTask {
     }
 
     fn recreate(&mut self, size: Size2D<i32>) {
         self.drawtarget = CanvasPaintTask::create(size);
     }
 
     fn send_pixel_contents(&mut self, chan: Sender<Vec<u8>>) {
         self.drawtarget.snapshot().get_data_surface().with_data(|element| {
-            chan.send(element.to_vec());
+            chan.send(element.to_vec()).unwrap();
         })
     }
 }
--- a/servo/components/compositing/Cargo.toml
+++ b/servo/components/compositing/Cargo.toml
@@ -38,22 +38,20 @@ git = "https://github.com/servo/rust-azu
 git = "https://github.com/servo/rust-geom"
 
 [dependencies.layers]
 git = "https://github.com/servo/rust-layers"
 
 [dependencies.png]
 git = "https://github.com/servo/rust-png"
 
-[dependencies.url]
-git = "https://github.com/servo/rust-url"
-
 [dependencies.core_graphics]
 git = "https://github.com/servo/rust-core-graphics"
 
 [dependencies.core_text]
 git = "https://github.com/servo/rust-core-text"
 
 [dependencies.gleam]
 git = "https://github.com/servo/gleam"
 
-[dependencies.time]
-git = "https://github.com/rust-lang/time"
+[dependencies]
+url = "*"
+time = "*"
\ No newline at end of file
--- a/servo/components/compositing/compositor.rs
+++ b/servo/components/compositing/compositor.rs
@@ -36,21 +36,22 @@ use servo_msg::constellation_msg::Msg as
 use servo_msg::constellation_msg::{Key, KeyModifiers, KeyState, LoadData};
 use servo_msg::constellation_msg::{PipelineId, WindowSizeData};
 use servo_util::geometry::{PagePx, ScreenPx, ViewportPx};
 use servo_util::memory::MemoryProfilerChan;
 use servo_util::opts;
 use servo_util::time::{TimeProfilerCategory, profile, TimeProfilerChan};
 use servo_util::{memory, time};
 use std::collections::HashMap;
-use std::collections::hash_map::{Occupied, Vacant};
+use std::collections::hash_map::Entry::{Occupied, Vacant};
 use std::path::Path;
-use std::num::FloatMath;
+use std::num::Float;
 use std::rc::Rc;
 use std::slice::bytes::copy_memory;
+use std::sync::mpsc::Sender;
 use time::{precise_time_ns, precise_time_s};
 use url::Url;
 
 /// NB: Never block on the constellation, because sometimes the constellation blocks on us.
 pub struct IOCompositor<Window: WindowMethods> {
     /// The application window.
     window: Rc<Window>,
 
@@ -66,17 +67,17 @@ pub struct IOCompositor<Window: WindowMe
 
     /// Tracks details about each active pipeline that the compositor knows about.
     pipeline_details: HashMap<PipelineId, PipelineDetails>,
 
     /// The canvas to paint a page.
     scene: Scene<CompositorData>,
 
     /// The application window size.
-    window_size: TypedSize2D<DevicePixel, uint>,
+    window_size: TypedSize2D<DevicePixel, u32>,
 
     /// "Mobile-style" zoom that does not reflow the page.
     viewport_zoom: ScaleFactor<PagePx, ViewportPx, f32>,
 
     /// "Desktop-style" zoom that resizes the viewport to fit the window.
     /// See `ViewportPx` docs in util/geom.rs for details.
     page_zoom: ScaleFactor<ViewportPx, ScreenPx, f32>,
 
@@ -129,24 +130,24 @@ pub struct IOCompositor<Window: WindowMe
     pending_scroll_events: Vec<ScrollEvent>,
 }
 
 pub struct ScrollEvent {
     delta: TypedPoint2D<DevicePixel,f32>,
     cursor: TypedPoint2D<DevicePixel,i32>,
 }
 
-#[deriving(PartialEq)]
+#[derive(PartialEq)]
 enum CompositionRequest {
     NoCompositingNecessary,
     CompositeOnScrollTimeout(u64),
     CompositeNow,
 }
 
-#[deriving(Copy, PartialEq, Show)]
+#[derive(Copy, PartialEq, Show)]
 enum ShutdownState {
     NotShuttingDown,
     ShuttingDown,
     FinishedShuttingDown,
 }
 
 struct HitTestResult {
     layer: Rc<Layer<CompositorData>>,
@@ -245,18 +246,18 @@ impl<Window: WindowMethods> IOCompositor
     fn handle_browser_message(&mut self, msg: Msg) -> bool {
         match (msg, self.shutdown_state) {
             (_, ShutdownState::FinishedShuttingDown) =>
                 panic!("compositor shouldn't be handling messages after shutting down"),
 
             (Msg::Exit(chan), _) => {
                 debug!("shutting down the constellation");
                 let ConstellationChan(ref con_chan) = self.constellation_chan;
-                con_chan.send(ConstellationMsg::Exit);
-                chan.send(());
+                con_chan.send(ConstellationMsg::Exit).unwrap();
+                chan.send(()).unwrap();
                 self.shutdown_state = ShutdownState::ShuttingDown;
             }
 
             (Msg::ShutdownComplete, _) => {
                 debug!("constellation completed shutdown");
                 self.shutdown_state = ShutdownState::FinishedShuttingDown;
                 return false;
             }
@@ -287,36 +288,36 @@ impl<Window: WindowMethods> IOCompositor
                                     response_chan,
                                     new_constellation_chan);
                 self.send_viewport_rects_for_all_layers();
             }
 
             (Msg::ChangeLayerPipelineAndRemoveChildren(old_pipeline, new_pipeline, response_channel),
              ShutdownState::NotShuttingDown) => {
                 self.handle_change_layer_pipeline_and_remove_children(old_pipeline, new_pipeline);
-                response_channel.send(());
+                response_channel.send(()).unwrap();
             }
 
             (Msg::CreateRootLayerForPipeline(parent_pipeline, pipeline, rect, response_channel),
              ShutdownState::NotShuttingDown) => {
                 self.handle_create_root_layer_for_pipeline(parent_pipeline, pipeline, rect);
-                response_channel.send(());
+                response_channel.send(()).unwrap();
             }
 
             (Msg::CreateOrUpdateBaseLayer(layer_properties), ShutdownState::NotShuttingDown) => {
                 self.create_or_update_base_layer(layer_properties);
             }
 
             (Msg::CreateOrUpdateDescendantLayer(layer_properties),
              ShutdownState::NotShuttingDown) => {
                 self.create_or_update_descendant_layer(layer_properties);
             }
 
             (Msg::GetGraphicsMetadata(chan), ShutdownState::NotShuttingDown) => {
-                chan.send(Some(self.window.native_metadata()));
+                chan.send(Some(self.window.native_metadata())).unwrap();
             }
 
             (Msg::SetLayerOrigin(pipeline_id, layer_id, origin),
              ShutdownState::NotShuttingDown) => {
                 self.set_layer_origin(pipeline_id, layer_id, origin);
             }
 
             (Msg::AssignPaintedBuffers(pipeline_id, epoch, replies), ShutdownState::NotShuttingDown) => {
@@ -414,22 +415,22 @@ impl<Window: WindowMethods> IOCompositor
         return self.pipeline_details.get_mut(&pipeline_id).unwrap();
     }
 
     pub fn get_pipeline<'a>(&'a self, pipeline_id: PipelineId) -> &'a CompositionPipeline {
         match self.pipeline_details.get(&pipeline_id) {
             Some(ref details) => {
                 match details.pipeline {
                     Some(ref pipeline) => pipeline,
-                    None => panic!("Compositor layer has an unitialized pipeline ({}).",
+                    None => panic!("Compositor layer has an unitialized pipeline ({:?}).",
                                    pipeline_id),
 
                 }
             }
-            None => panic!("Compositor layer has an unknown pipeline ({}).", pipeline_id),
+            None => panic!("Compositor layer has an unknown pipeline ({:?}).", pipeline_id),
         }
     }
 
     fn change_page_title(&mut self, _: PipelineId, title: Option<String>) {
         self.window.set_page_title(title);
     }
 
     fn change_page_load_data(&mut self, _: FrameId, load_data: LoadData) {
@@ -454,17 +455,17 @@ impl<Window: WindowMethods> IOCompositor
         self.has_paint_msg_tracking() && self.outstanding_paint_msgs > 0
     }
 
     fn add_outstanding_paint_msg(&mut self, count: uint) {
         // return early if not tracking paint_msg's
         if !self.has_paint_msg_tracking() {
             return;
         }
-        debug!("add_outstanding_paint_msg {}", self.outstanding_paint_msgs);
+        debug!("add_outstanding_paint_msg {:?}", self.outstanding_paint_msgs);
         self.outstanding_paint_msgs += count;
     }
 
     fn remove_outstanding_paint_msg(&mut self) {
         if !self.has_paint_msg_tracking() {
             return;
         }
         if self.outstanding_paint_msgs > 0 {
@@ -473,17 +474,17 @@ impl<Window: WindowMethods> IOCompositor
             debug!("too many repaint msgs completed");
         }
     }
 
     fn set_frame_tree(&mut self,
                       frame_tree: &SendableFrameTree,
                       response_chan: Sender<()>,
                       new_constellation_chan: ConstellationChan) {
-        response_chan.send(());
+        response_chan.send(()).unwrap();
 
         self.root_pipeline = Some(frame_tree.pipeline.clone());
 
         // If we have an old root layer, release all old tiles before replacing it.
         match self.scene.root {
             Some(ref layer) => layer.clear_all_tiles(self),
             None => { }
         }
@@ -541,17 +542,18 @@ impl<Window: WindowMethods> IOCompositor
     }
 
     fn handle_change_layer_pipeline_and_remove_children(&mut self,
                                                         old_pipeline: CompositionPipeline,
                                                         new_pipeline: CompositionPipeline) {
         let root_layer = match self.find_pipeline_root_layer(old_pipeline.id) {
             Some(root_layer) => root_layer,
             None => {
-                debug!("Ignoring ChangeLayerPipelineAndRemoveChildren message for pipeline ({}) shutting down.",
+                debug!("Ignoring ChangeLayerPipelineAndRemoveChildren message \
+                        for pipeline ({:?}) shutting down.",
                        old_pipeline.id);
                 return;
             }
         };
 
         root_layer.clear_all_tiles(self);
         root_layer.children().clear();
 
@@ -576,17 +578,18 @@ impl<Window: WindowMethods> IOCompositor
             }
             None => {}
         }
 
         let pipeline_id = parent_pipeline.id;
         let parent_layer = match self.find_pipeline_root_layer(pipeline_id) {
             Some(root_layer) => root_layer,
             None => {
-                debug!("Ignoring FrameTreeUpdate message for pipeline ({}) shutting down.",
+                debug!("Ignoring FrameTreeUpdate message for pipeline ({:?}) \
+                        shutting down.",
                        pipeline_id);
                 return;
             }
         };
         parent_layer.add_child(root_layer);
     }
 
     fn find_pipeline_root_layer(&self, pipeline_id: PipelineId) -> Option<Rc<Layer<CompositorData>>> {
@@ -606,17 +609,18 @@ impl<Window: WindowMethods> IOCompositor
         }
     }
 
     fn create_or_update_base_layer(&mut self, layer_properties: LayerProperties) {
         let pipeline_id = layer_properties.pipeline_id;
         let root_layer = match self.find_pipeline_root_layer(pipeline_id) {
             Some(root_layer) => root_layer,
             None => {
-                debug!("Ignoring CreateOrUpdateBaseLayer message for pipeline ({}) shutting down.",
+                debug!("Ignoring CreateOrUpdateBaseLayer message for pipeline \
+                        ({:?}) shutting down.",
                        pipeline_id);
                 return;
             }
         };
 
         let need_new_base_layer = !self.update_layer_if_exists(layer_properties);
         if need_new_base_layer {
             root_layer.update_layer_except_bounds(layer_properties);
@@ -664,17 +668,17 @@ impl<Window: WindowMethods> IOCompositor
         let initial_viewport = self.window_size.as_f32() / dppx;
         let visible_viewport = initial_viewport / self.viewport_zoom;
 
         let ConstellationChan(ref chan) = self.constellation_chan;
         chan.send(ConstellationMsg::ResizedWindow(WindowSizeData {
             device_pixel_ratio: dppx,
             initial_viewport: initial_viewport,
             visible_viewport: visible_viewport,
-        }));
+        })).unwrap()
     }
 
     pub fn move_layer(&self,
                       pipeline_id: PipelineId,
                       layer_id: LayerId,
                       origin: TypedPoint2D<LayerPixel, f32>)
                       -> bool {
         match self.find_layer_with_pipeline_and_layer_id(pipeline_id, layer_id) {
@@ -718,17 +722,18 @@ impl<Window: WindowMethods> IOCompositor
     fn set_layer_origin(&mut self,
                         pipeline_id: PipelineId,
                         layer_id: LayerId,
                         new_origin: Point2D<f32>) {
         match self.find_layer_with_pipeline_and_layer_id(pipeline_id, layer_id) {
             Some(ref layer) => {
                 layer.bounds.borrow_mut().origin = Point2D::from_untyped(&new_origin)
             }
-            None => panic!("Compositor received SetLayerOrigin for nonexistent layer: {}", pipeline_id),
+            None => panic!("Compositor received SetLayerOrigin for nonexistent \
+                            layer: {:?}", pipeline_id),
         };
 
         self.send_buffer_requests_for_all_layers();
     }
 
     fn assign_painted_buffers(&mut self,
                               pipeline_id: PipelineId,
                               layer_id: LayerId,
@@ -739,24 +744,24 @@ impl<Window: WindowMethods> IOCompositor
                 self.assign_painted_buffers_to_layer(layer, new_layer_buffer_set, epoch);
                 return;
             }
             None => {}
         }
 
         let pipeline = self.get_pipeline(pipeline_id);
         let message = PaintMsg::UnusedBuffer(new_layer_buffer_set.buffers);
-        let _ = pipeline.paint_chan.send_opt(message);
+        let _ = pipeline.paint_chan.send(message);
     }
 
     fn assign_painted_buffers_to_layer(&mut self,
                                        layer: Rc<Layer<CompositorData>>,
                                        new_layer_buffer_set: Box<LayerBufferSet>,
                                        epoch: Epoch) {
-        debug!("compositor received new frame at size {}x{}",
+        debug!("compositor received new frame at size {:?}x{:?}",
                self.window_size.width.get(),
                self.window_size.height.get());
 
         // From now on, if we destroy the buffers, they will leak.
         let mut new_layer_buffer_set = new_layer_buffer_set;
         new_layer_buffer_set.mark_will_leak();
 
         // FIXME(pcwalton): This is going to cause problems with inconsistent frames since
@@ -824,24 +829,24 @@ impl<Window: WindowMethods> IOCompositor
 
             WindowEvent::KeyEvent(key, state, modifiers) => {
                 self.on_key_event(key, state, modifiers);
             }
 
             WindowEvent::Quit => {
                 debug!("shutting down the constellation for WindowEvent::Quit");
                 let ConstellationChan(ref chan) = self.constellation_chan;
-                chan.send(ConstellationMsg::Exit);
+                chan.send(ConstellationMsg::Exit).unwrap();
                 self.shutdown_state = ShutdownState::ShuttingDown;
             }
         }
     }
 
-    fn on_resize_window_event(&mut self, new_size: TypedSize2D<DevicePixel, uint>) {
-        debug!("compositor resizing to {}", new_size.to_untyped());
+    fn on_resize_window_event(&mut self, new_size: TypedSize2D<DevicePixel, u32>) {
+        debug!("compositor resizing to {:?}", new_size.to_untyped());
 
         // A size change could also mean a resolution change.
         let new_hidpi_factor = self.window.hidpi_factor();
         if self.hidpi_factor != new_hidpi_factor {
             self.hidpi_factor = new_hidpi_factor;
             self.update_zoom_transform();
         }
 
@@ -862,17 +867,17 @@ impl<Window: WindowMethods> IOCompositor
             Some(ref layer) => layer.get_pipeline_id(),
             None => panic!("Compositor: Received WindowEvent::LoadUrl without initialized compositor \
                            layers"),
         };
 
         let msg = ConstellationMsg::LoadUrl(root_pipeline_id,
             LoadData::new(Url::parse(url_string.as_slice()).unwrap()));
         let ConstellationChan(ref chan) = self.constellation_chan;
-        chan.send(msg);
+        chan.send(msg).unwrap()
     }
 
     fn on_mouse_window_event_class(&self, mouse_window_event: MouseWindowEvent) {
         let point = match mouse_window_event {
             MouseWindowEvent::Click(_, p) => p,
             MouseWindowEvent::MouseDown(_, p) => p,
             MouseWindowEvent::MouseUp(_, p) => p,
         };
@@ -981,39 +986,39 @@ impl<Window: WindowMethods> IOCompositor
     }
 
     fn on_navigation_window_event(&self, direction: WindowNavigateMsg) {
         let direction = match direction {
             windowing::WindowNavigateMsg::Forward => NavigationDirection::Forward,
             windowing::WindowNavigateMsg::Back => NavigationDirection::Back,
         };
         let ConstellationChan(ref chan) = self.constellation_chan;
-        chan.send(ConstellationMsg::Navigate(direction))
+        chan.send(ConstellationMsg::Navigate(direction)).unwrap()
     }
 
     fn on_key_event(&self, key: Key, state: KeyState, modifiers: KeyModifiers) {
         let ConstellationChan(ref chan) = self.constellation_chan;
-        chan.send(ConstellationMsg::KeyEvent(key, state, modifiers))
+        chan.send(ConstellationMsg::KeyEvent(key, state, modifiers)).unwrap()
     }
 
     fn convert_buffer_requests_to_pipeline_requests_map(&self,
                                                         requests: Vec<(Rc<Layer<CompositorData>>,
                                                                        Vec<BufferRequest>)>)
                                                         -> HashMap<PipelineId, Vec<PaintRequest>> {
         let scale = self.device_pixels_per_page_px();
         let mut results: HashMap<PipelineId, Vec<PaintRequest>> = HashMap::new();
 
         for (layer, mut layer_requests) in requests.into_iter() {
             let vec = match results.entry(layer.get_pipeline_id()) {
                 Occupied(mut entry) => {
                     *entry.get_mut() = Vec::new();
                     entry.into_mut()
                 }
                 Vacant(entry) => {
-                    entry.set(Vec::new())
+                    entry.insert(Vec::new())
                 }
             };
 
             // All the BufferRequests are in layer/device coordinates, but the paint task
             // wants to know the page coordinates. We scale them before sending them.
             for request in layer_requests.iter_mut() {
                 request.page_rect = request.page_rect / scale.get();
             }
@@ -1030,30 +1035,30 @@ impl<Window: WindowMethods> IOCompositor
     }
 
     fn send_back_unused_buffers(&mut self) {
         match self.root_pipeline {
             Some(ref pipeline) => {
                 let unused_buffers = self.scene.collect_unused_buffers();
                 if unused_buffers.len() != 0 {
                     let message = PaintMsg::UnusedBuffer(unused_buffers);
-                    let _ = pipeline.paint_chan.send_opt(message);
+                    let _ = pipeline.paint_chan.send(message);
                 }
             },
             None => {}
         }
     }
 
     fn send_viewport_rect_for_layer(&self, layer: Rc<Layer<CompositorData>>) {
         if layer.extra_data.borrow().id == LayerId::null() {
             let layer_rect = Rect(-layer.extra_data.borrow().scroll_offset.to_untyped(),
                                   layer.bounds.borrow().size.to_untyped());
             let pipeline = self.get_pipeline(layer.get_pipeline_id());
             let ScriptControlChan(ref chan) = pipeline.script_chan;
-            chan.send(ConstellationControlMsg::Viewport(pipeline.id.clone(), layer_rect));
+            chan.send(ConstellationControlMsg::Viewport(pipeline.id.clone(), layer_rect)).unwrap();
         }
 
         for kid in layer.children().iter() {
             self.send_viewport_rect_for_layer(kid.clone());
         }
     }
 
     fn send_viewport_rects_for_all_layers(&self) {
@@ -1079,17 +1084,17 @@ impl<Window: WindowMethods> IOCompositor
         // We want to batch requests for each pipeline to avoid race conditions
         // when handling the resulting BufferRequest responses.
         let pipeline_requests =
             self.convert_buffer_requests_to_pipeline_requests_map(layers_and_requests);
 
         let mut num_paint_msgs_sent = 0;
         for (pipeline_id, requests) in pipeline_requests.into_iter() {
             num_paint_msgs_sent += 1;
-            let _ = self.get_pipeline(pipeline_id).paint_chan.send_opt(PaintMsg::Paint(requests));
+            let _ = self.get_pipeline(pipeline_id).paint_chan.send(PaintMsg::Paint(requests));
         }
 
         self.add_outstanding_paint_msg(num_paint_msgs_sent);
         true
     }
 
     fn is_ready_to_paint_image_output(&self) -> bool {
         if !self.got_load_complete_message {
@@ -1120,17 +1125,17 @@ impl<Window: WindowMethods> IOCompositor
             return
         }
 
         let output_image = opts::get().output_file.is_some() &&
                             self.is_ready_to_paint_image_output();
 
         let mut framebuffer_ids = vec!();
         let mut texture_ids = vec!();
-        let (width, height) = (self.window_size.width.get(), self.window_size.height.get());
+        let (width, height) = (self.window_size.width.get() as usize, self.window_size.height.get() as usize);
 
         if output_image {
             framebuffer_ids = gl::gen_framebuffers(1);
             gl::bind_framebuffer(gl::FRAMEBUFFER, framebuffer_ids[0]);
 
             texture_ids = gl::gen_textures(1);
             gl::bind_texture(gl::TEXTURE_2D, texture_ids[0]);
 
@@ -1164,18 +1169,18 @@ impl<Window: WindowMethods> IOCompositor
                         }
                     }
                 }
                 None => {}
             }
         });
 
         if output_image {
-            let path =
-                from_str::<Path>(opts::get().output_file.as_ref().unwrap().as_slice()).unwrap();
+            let path: Path =
+                opts::get().output_file.as_ref().unwrap().as_slice().parse().unwrap();
             let mut pixels = gl::read_pixels(0, 0,
                                              width as gl::GLsizei,
                                              height as gl::GLsizei,
                                              gl::RGB, gl::UNSIGNED_BYTE);
 
             gl::bind_framebuffer(gl::FRAMEBUFFER, 0);
 
             gl::delete_buffers(texture_ids.as_slice());
@@ -1196,17 +1201,17 @@ impl<Window: WindowMethods> IOCompositor
                 height: height as u32,
                 pixels: png::PixelsByColorType::RGB8(pixels),
             };
             let res = png::store_png(&mut img, &path);
             assert!(res.is_ok());
 
             debug!("shutting down the constellation after generating an output file");
             let ConstellationChan(ref chan) = self.constellation_chan;
-            chan.send(ConstellationMsg::Exit);
+            chan.send(ConstellationMsg::Exit).unwrap();
             self.shutdown_state = ShutdownState::ShuttingDown;
         }
 
         // Perform the page flip. This will likely block for a while.
         self.window.present();
 
         self.last_composite_time = precise_time_ns();
 
@@ -1388,29 +1393,29 @@ impl<Window> CompositorEventListener for
         }
 
         // Drain compositor port, sometimes messages contain channels that are blocking
         // another task from finishing (i.e. SetFrameTree).
         while self.port.try_recv_compositor_msg().is_some() {}
 
         // Tell the profiler, memory profiler, and scrolling timer to shut down.
         let TimeProfilerChan(ref time_profiler_chan) = self.time_profiler_chan;
-        time_profiler_chan.send(time::TimeProfilerMsg::Exit);
+        time_profiler_chan.send(time::TimeProfilerMsg::Exit).unwrap();
 
         let MemoryProfilerChan(ref memory_profiler_chan) = self.memory_profiler_chan;
-        memory_profiler_chan.send(memory::MemoryProfilerMsg::Exit);
+        memory_profiler_chan.send(memory::MemoryProfilerMsg::Exit).unwrap();
 
         self.scrolling_timer.shutdown();
     }
 
     fn pinch_zoom_level(&self) -> f32 {
         self.viewport_zoom.get() as f32
     }
 
     fn get_title_for_main_frame(&self) {
         let root_pipeline_id = match self.root_pipeline {
             None => return,
             Some(ref root_pipeline) => root_pipeline.id,
         };
         let ConstellationChan(ref chan) = self.constellation_chan;
-        chan.send(ConstellationMsg::GetPipelineTitle(root_pipeline_id));
+        chan.send(ConstellationMsg::GetPipelineTitle(root_pipeline_id)).unwrap();
     }
 }
--- a/servo/components/compositing/compositor_layer.rs
+++ b/servo/components/compositing/compositor_layer.rs
@@ -16,17 +16,16 @@ use gfx::paint_task::Msg as PaintMsg;
 use layers::color::Color;
 use layers::geometry::LayerPixel;
 use layers::layers::{Layer, LayerBufferSet};
 use script_traits::CompositorEvent::{ClickEvent, MouseDownEvent, MouseMoveEvent, MouseUpEvent};
 use script_traits::{ScriptControlChan, ConstellationControlMsg};
 use servo_msg::compositor_msg::{Epoch, LayerId, ScrollPolicy};
 use servo_msg::constellation_msg::PipelineId;
 use std::num::Float;
-use std::num::FloatMath;
 use std::rc::Rc;
 
 pub struct CompositorData {
     /// This layer's pipeline id. The compositor can associate this id with an
     /// actual CompositionPipeline.
     pub pipeline_id: PipelineId,
 
     /// The ID of this layer within the pipeline.
@@ -63,34 +62,35 @@ impl CompositorData {
 
         Rc::new(Layer::new(Rect::from_untyped(&layer_properties.rect),
                            tile_size,
                            to_layers_color(&layer_properties.background_color),
                            new_compositor_data))
     }
 }
 
-pub trait CompositorLayer<Window: WindowMethods> {
+pub trait CompositorLayer {
     fn update_layer_except_bounds(&self, layer_properties: LayerProperties);
 
     fn update_layer(&self, layer_properties: LayerProperties);
 
-    fn add_buffers(&self,
-                   compositor: &IOCompositor<Window>,
-                   new_buffers: Box<LayerBufferSet>,
-                   epoch: Epoch)
-                   -> bool;
+    fn add_buffers<Window>(&self,
+                           compositor: &IOCompositor<Window>,
+                           new_buffers: Box<LayerBufferSet>,
+                           epoch: Epoch)
+                           -> bool
+                           where Window: WindowMethods;
 
     /// Destroys all layer tiles, sending the buffers back to the painter to be destroyed or
     /// reused.
-    fn clear(&self, compositor: &IOCompositor<Window>);
+    fn clear<Window>(&self, compositor: &IOCompositor<Window>) where Window: WindowMethods;
 
     /// Destroys tiles for this layer and all descendent layers, sending the buffers back to the
     /// painter to be destroyed or reused.
-    fn clear_all_tiles(&self, compositor: &IOCompositor<Window>);
+    fn clear_all_tiles<Window>(&self, compositor: &IOCompositor<Window>) where Window: WindowMethods;
 
     /// Destroys all tiles of all layers, including children, *without* sending them back to the
     /// painter. You must call this only when the paint task is destined to be going down;
     /// otherwise, you will leak tiles.
     ///
     /// This is used during shutdown, when we know the paint task is going away.
     fn forget_all_tiles(&self);
 
@@ -102,41 +102,43 @@ pub trait CompositorLayer<Window: Window
     fn handle_scroll_event(&self,
                            delta: TypedPoint2D<LayerPixel, f32>,
                            cursor: TypedPoint2D<LayerPixel, f32>)
                            -> ScrollEventResult;
 
     // Takes in a MouseWindowEvent, determines if it should be passed to children, and
     // sends the event off to the appropriate pipeline. NB: the cursor position is in
     // page coordinates.
-    fn send_mouse_event(&self,
-                        compositor: &IOCompositor<Window>,
-                        event: MouseWindowEvent,
-                        cursor: TypedPoint2D<LayerPixel, f32>);
+    fn send_mouse_event<Window>(&self,
+                                compositor: &IOCompositor<Window>,
+                                event: MouseWindowEvent,
+                                cursor: TypedPoint2D<LayerPixel, f32>)
+                                where Window: WindowMethods;
 
-    fn send_mouse_move_event(&self,
-                             compositor: &IOCompositor<Window>,
-                             cursor: TypedPoint2D<LayerPixel, f32>);
+    fn send_mouse_move_event<Window>(&self,
+                                     compositor: &IOCompositor<Window>,
+                                     cursor: TypedPoint2D<LayerPixel, f32>)
+                                     where Window: WindowMethods;
 
     fn clamp_scroll_offset_and_scroll_layer(&self,
                                             new_offset: TypedPoint2D<LayerPixel, f32>)
                                             -> ScrollEventResult;
 
     fn scroll_layer_and_all_child_layers(&self,
                                          new_offset: TypedPoint2D<LayerPixel, f32>)
                                          -> bool;
 
     /// Return a flag describing how this layer deals with scroll events.
     fn wants_scroll_events(&self) -> WantsScrollEventsFlag;
 
     /// Return the pipeline id associated with this layer.
     fn get_pipeline_id(&self) -> PipelineId;
 }
 
-#[deriving(Copy, PartialEq, Clone)]
+#[derive(Copy, PartialEq, Clone)]
 pub enum WantsScrollEventsFlag {
     WantsScrollEvents,
     DoesntWantScrollEvents,
 }
 
 fn to_layers_color(color: &azure_hl::Color) -> Color {
     Color { r: color.r, g: color.g, b: color.b, a: color.a }
 }
@@ -162,24 +164,24 @@ impl Clampable for f32 {
 fn calculate_content_size_for_layer(layer: &Layer<CompositorData>)
                                     -> TypedSize2D<LayerPixel, f32> {
     layer.children().iter().fold(Rect::zero(),
                                  |unioned_rect, child_rect| {
                                     unioned_rect.union(&*child_rect.bounds.borrow())
                                  }).size
 }
 
-#[deriving(PartialEq)]
+#[derive(PartialEq)]
 pub enum ScrollEventResult {
     ScrollEventUnhandled,
     ScrollPositionChanged,
     ScrollPositionUnchanged,
 }
 
-impl<Window: WindowMethods> CompositorLayer<Window> for Layer<CompositorData> {
+impl CompositorLayer for Layer<CompositorData> {
     fn update_layer_except_bounds(&self, layer_properties: LayerProperties) {
         self.extra_data.borrow_mut().epoch = layer_properties.epoch;
         self.extra_data.borrow_mut().scroll_policy = layer_properties.scroll_policy;
 
         *self.background_color.borrow_mut() = to_layers_color(&layer_properties.background_color);
 
         self.contents_changed();
     }
@@ -194,63 +196,66 @@ impl<Window: WindowMethods> CompositorLa
     }
 
     // Add LayerBuffers to the specified layer. Returns the layer buffer set back if the layer that
     // matches the given pipeline ID was not found; otherwise returns None and consumes the layer
     // buffer set.
     //
     // If the epoch of the message does not match the layer's epoch, the message is ignored, the
     // layer buffer set is consumed, and None is returned.
-    fn add_buffers(&self,
-                   compositor: &IOCompositor<Window>,
-                   new_buffers: Box<LayerBufferSet>,
-                   epoch: Epoch)
-                   -> bool {
+    fn add_buffers<Window>(&self,
+                           compositor: &IOCompositor<Window>,
+                           new_buffers: Box<LayerBufferSet>,
+                           epoch: Epoch)
+                           -> bool
+                           where Window: WindowMethods {
         if self.extra_data.borrow().epoch != epoch {
-            debug!("add_buffers: compositor epoch mismatch: {} != {}, id: {}",
+            debug!("add_buffers: compositor epoch mismatch: {:?} != {:?}, id: {:?}",
                    self.extra_data.borrow().epoch,
                    epoch,
                    self.get_pipeline_id());
             let pipeline = compositor.get_pipeline(self.get_pipeline_id());
-            let _ = pipeline.paint_chan.send_opt(PaintMsg::UnusedBuffer(new_buffers.buffers));
+            let _ = pipeline.paint_chan.send(PaintMsg::UnusedBuffer(new_buffers.buffers));
             return false;
         }
 
         for buffer in new_buffers.buffers.into_iter().rev() {
             self.add_buffer(buffer);
         }
 
         let unused_buffers = self.collect_unused_buffers();
         if !unused_buffers.is_empty() { // send back unused buffers
             let pipeline = compositor.get_pipeline(self.get_pipeline_id());
-            let _ = pipeline.paint_chan.send_opt(PaintMsg::UnusedBuffer(unused_buffers));
+            let _ = pipeline.paint_chan.send(PaintMsg::UnusedBuffer(unused_buffers));
         }
 
         return true;
     }
 
-    fn clear(&self, compositor: &IOCompositor<Window>) {
+    fn clear<Window>(&self, compositor: &IOCompositor<Window>) where Window: WindowMethods {
         let mut buffers = self.collect_buffers();
 
         if !buffers.is_empty() {
             // We have no way of knowing without a race whether the paint task is even up and
             // running, but mark the buffers as not leaking. If the paint task died, then the
             // buffers are going to be cleaned up.
             for buffer in buffers.iter_mut() {
                 buffer.mark_wont_leak()
             }
 
             let pipeline = compositor.get_pipeline(self.get_pipeline_id());
-            let _ = pipeline.paint_chan.send_opt(PaintMsg::UnusedBuffer(buffers));
+            let _ = pipeline.paint_chan.send(PaintMsg::UnusedBuffer(buffers));
         }
     }
 
     /// Destroys tiles for this layer and all descendent layers, sending the buffers back to the
     /// painter to be destroyed or reused.
-    fn clear_all_tiles(&self, compositor: &IOCompositor<Window>) {
+    fn clear_all_tiles<Window>(&self,
+                               compositor: &IOCompositor<Window>)
+                               where Window: WindowMethods {
         self.clear(compositor);
         for kid in self.children().iter() {
             kid.clear_all_tiles(compositor);
         }
     }
 
     /// Destroys all tiles of all layers, including children, *without* sending them back to the
     /// painter. You must call this only when the paint task is destined to be going down;
@@ -320,42 +325,44 @@ impl<Window: WindowMethods> CompositorLa
 
         if result {
             return ScrollEventResult::ScrollPositionChanged;
         } else {
             return ScrollEventResult::ScrollPositionUnchanged;
         }
     }
 
-    fn send_mouse_event(&self,
-                        compositor: &IOCompositor<Window>,
-                        event: MouseWindowEvent,
-                        cursor: TypedPoint2D<LayerPixel, f32>) {
+    fn send_mouse_event<Window>(&self,
+                                compositor: &IOCompositor<Window>,
+                                event: MouseWindowEvent,
+                                cursor: TypedPoint2D<LayerPixel, f32>)
+                                where Window: WindowMethods {
         let event_point = cursor.to_untyped();
         let message = match event {
             MouseWindowEvent::Click(button, _) =>
                 ClickEvent(button, event_point),
             MouseWindowEvent::MouseDown(button, _) =>
                 MouseDownEvent(button, event_point),
             MouseWindowEvent::MouseUp(button, _) =>
                 MouseUpEvent(button, event_point),
         };
 
         let pipeline = compositor.get_pipeline(self.get_pipeline_id());
         let ScriptControlChan(ref chan) = pipeline.script_chan;
-        let _ = chan.send_opt(ConstellationControlMsg::SendEvent(pipeline.id.clone(), message));
+        let _ = chan.send(ConstellationControlMsg::SendEvent(pipeline.id.clone(), message));
     }
 
-    fn send_mouse_move_event(&self,
-                             compositor: &IOCompositor<Window>,
-                             cursor: TypedPoint2D<LayerPixel, f32>) {
+    fn send_mouse_move_event<Window>(&self,
+                                     compositor: &IOCompositor<Window>,
+                                     cursor: TypedPoint2D<LayerPixel, f32>)
+                                     where Window: WindowMethods {
         let message = MouseMoveEvent(cursor.to_untyped());
         let pipeline = compositor.get_pipeline(self.get_pipeline_id());
         let ScriptControlChan(ref chan) = pipeline.script_chan;
-        let _ = chan.send_opt(ConstellationControlMsg::SendEvent(pipeline.id.clone(), message));
+        let _ = chan.send(ConstellationControlMsg::SendEvent(pipeline.id.clone(), message));
     }
 
     fn scroll_layer_and_all_child_layers(&self, new_offset: TypedPoint2D<LayerPixel, f32>)
                                          -> bool {
         let mut result = false;
 
         // Only scroll this layer if it's not fixed-positioned.
         if self.extra_data.borrow().scroll_policy != ScrollPolicy::FixedPosition {
--- a/servo/components/compositing/compositor_task.rs
+++ b/servo/components/compositing/compositor_task.rs
@@ -21,49 +21,49 @@ use pipeline::CompositionPipeline;
 use servo_msg::compositor_msg::{Epoch, LayerId, LayerMetadata, ReadyState};
 use servo_msg::compositor_msg::{PaintListener, PaintState, ScriptListener, ScrollPolicy};
 use servo_msg::constellation_msg::{ConstellationChan, LoadData, PipelineId};
 use servo_msg::constellation_msg::{Key, KeyState, KeyModifiers};
 use servo_util::cursor::Cursor;
 use servo_util::geometry::PagePx;
 use servo_util::memory::MemoryProfilerChan;
 use servo_util::time::TimeProfilerChan;
-use std::comm::{channel, Sender, Receiver};
+use std::sync::mpsc::{channel, Sender, Receiver};
 use std::fmt::{Error, Formatter, Show};
 use std::rc::Rc;
 
 /// Sends messages to the compositor. This is a trait supplied by the port because the method used
 /// to communicate with the compositor may have to kick OS event loops awake, communicate cross-
 /// process, and so forth.
 pub trait CompositorProxy : 'static + Send {
     /// Sends a message to the compositor.
     fn send(&mut self, msg: Msg);
     /// Clones the compositor proxy.
     fn clone_compositor_proxy(&self) -> Box<CompositorProxy+'static+Send>;
 }
 
 /// The port that the compositor receives messages on. As above, this is a trait supplied by the
 /// Servo port.
-pub trait CompositorReceiver for Sized? : 'static {
+pub trait CompositorReceiver : 'static {
     /// Receives the next message inbound for the compositor. This must not block.
     fn try_recv_compositor_msg(&mut self) -> Option<Msg>;
     /// Synchronously waits for, and returns, the next message inbound for the compositor.
     fn recv_compositor_msg(&mut self) -> Msg;
 }
 
 /// A convenience implementation of `CompositorReceiver` for a plain old Rust `Receiver`.
 impl CompositorReceiver for Receiver<Msg> {
     fn try_recv_compositor_msg(&mut self) -> Option<Msg> {
         match self.try_recv() {
             Ok(msg) => Some(msg),
             Err(_) => None,
         }
     }
     fn recv_compositor_msg(&mut self) -> Msg {
-        self.recv()
+        self.recv().unwrap()
     }
 }
 
 /// Implementation of the abstract `ScriptListener` interface.
 impl ScriptListener for Box<CompositorProxy+'static+Send> {
     fn set_ready_state(&mut self, pipeline_id: PipelineId, ready_state: ReadyState) {
         let msg = Msg::ChangeReadyState(pipeline_id, ready_state);
         self.send(msg);
@@ -74,17 +74,17 @@ impl ScriptListener for Box<CompositorPr
                              layer_id: LayerId,
                              point: Point2D<f32>) {
         self.send(Msg::ScrollFragmentPoint(pipeline_id, layer_id, point));
     }
 
     fn close(&mut self) {
         let (chan, port) = channel();
         self.send(Msg::Exit(chan));
-        port.recv();
+        port.recv().unwrap();
     }
 
     fn dup(&mut self) -> Box<ScriptListener+'static> {
         box self.clone_compositor_proxy() as Box<ScriptListener+'static>
     }
 
     fn set_title(&mut self, pipeline_id: PipelineId, title: Option<String>) {
         self.send(Msg::ChangePageTitle(pipeline_id, title))
@@ -93,17 +93,17 @@ impl ScriptListener for Box<CompositorPr
     fn send_key_event(&mut self, key: Key, state: KeyState, modifiers: KeyModifiers) {
         if state == KeyState::Pressed {
             self.send(Msg::KeyEvent(key, modifiers));
         }
     }
 }
 
 /// Information about each layer that the compositor keeps.
-#[deriving(Copy)]
+#[derive(Copy)]
 pub struct LayerProperties {
     pub pipeline_id: PipelineId,
     pub epoch: Epoch,
     pub id: LayerId,
     pub rect: Rect<f32>,
     pub background_color: Color,
     pub scroll_policy: ScrollPolicy,
 }
@@ -124,17 +124,17 @@ impl LayerProperties {
     }
 }
 
 /// Implementation of the abstract `PaintListener` interface.
 impl PaintListener for Box<CompositorProxy+'static+Send> {
     fn get_graphics_metadata(&mut self) -> Option<NativeGraphicsMetadata> {
         let (chan, port) = channel();
         self.send(Msg::GetGraphicsMetadata(chan));
-        port.recv()
+        port.recv().unwrap()
     }
 
     fn assign_painted_buffers(&mut self,
                               pipeline_id: PipelineId,
                               epoch: Epoch,
                               replies: Vec<(LayerId, Box<LayerBufferSet>)>) {
         self.send(Msg::AssignPaintedBuffers(pipeline_id, epoch, replies));
     }
--- a/servo/components/compositing/constellation.rs
+++ b/servo/components/compositing/constellation.rs
@@ -12,17 +12,17 @@ use geom::rect::{Rect, TypedRect};
 use geom::scale_factor::ScaleFactor;
 use gfx::font_cache_task::FontCacheTask;
 use layers::geometry::DevicePixel;
 use layout_traits::LayoutTaskFactory;
 use libc;
 use script_traits::{CompositorEvent, ConstellationControlMsg};
 use script_traits::{ScriptControlChan, ScriptTaskFactory};
 use servo_msg::compositor_msg::LayerId;
-use servo_msg::constellation_msg::{mod, ConstellationChan, Failure};
+use servo_msg::constellation_msg::{self, ConstellationChan, Failure};
 use servo_msg::constellation_msg::{IFrameSandboxState, NavigationDirection};
 use servo_msg::constellation_msg::{Key, KeyState, KeyModifiers};
 use servo_msg::constellation_msg::{LoadData, NavigationType};
 use servo_msg::constellation_msg::{PipelineExitType, PipelineId};
 use servo_msg::constellation_msg::{SubpageId, WindowSizeData};
 use servo_msg::constellation_msg::Msg as ConstellationMsg;
 use servo_net::image_cache_task::{ImageCacheTask, ImageCacheTaskClient};
 use servo_net::resource_task::ResourceTask;
@@ -34,16 +34,17 @@ use servo_util::opts;
 use servo_util::task::spawn_named;
 use servo_util::time::TimeProfilerChan;
 use std::borrow::ToOwned;
 use std::cell::{Cell, RefCell};
 use std::collections::{HashMap, HashSet};
 use std::io;
 use std::mem::replace;
 use std::rc::Rc;
+use std::sync::mpsc::{Receiver, channel};
 use url::Url;
 
 /// Maintains the pipelines and navigation context and grants permission to composite.
 pub struct Constellation<LTF, STF> {
     /// A channel through which messages can be sent to this object.
     pub chan: ConstellationChan,
 
     /// Receives messages.
@@ -86,17 +87,17 @@ pub struct Constellation<LTF, STF> {
 
     /// A channel through which messages can be sent to the time profiler.
     pub time_profiler_chan: TimeProfilerChan,
 
     pub window_size: WindowSizeData,
 }
 
 /// A unique ID used to identify a frame.
-#[deriving(Copy)]
+#[derive(Copy)]
 pub struct FrameId(u32);
 
 /// One frame in the hierarchy.
 struct FrameTree {
     /// The ID of this frame.
     pub id: FrameId,
     /// The pipeline for this frame.
     pub pipeline: RefCell<Rc<Pipeline>>,
@@ -120,17 +121,17 @@ impl FrameTree {
         }
     }
 
     fn add_child(&self, new_child: ChildFrameTree) {
         self.children.borrow_mut().push(new_child);
     }
 }
 
-#[deriving(Clone)]
+#[derive(Clone)]
 struct ChildFrameTree {
     frame_tree: Rc<FrameTree>,
     /// Clipping rect representing the size and position, in page coordinates, of the visible
     /// region of the child frame relative to the parent.
     pub rect: Option<TypedRect<PagePx, f32>>,
 }
 
 impl ChildFrameTree {
@@ -229,17 +230,18 @@ impl ChildFrameTree {
 
 /// An iterator over a frame tree, returning nodes in depth-first order.
 /// Note that this iterator should _not_ be used to mutate nodes _during_
 /// iteration. Mutating nodes once the iterator is out of scope is OK.
 struct FrameTreeIterator {
     stack: Vec<Rc<FrameTree>>,
 }
 
-impl Iterator<Rc<FrameTree>> for FrameTreeIterator {
+impl Iterator for FrameTreeIterator {
+    type Item = Rc<FrameTree>;
     fn next(&mut self) -> Option<Rc<FrameTree>> {
         match self.stack.pop() {
             Some(next) => {
                 for cft in next.children.borrow().iter() {
                     self.stack.push(cft.frame_tree.clone());
                 }
                 Some(next)
             }
@@ -289,17 +291,17 @@ impl NavigationContext {
         let next = self.next.pop().unwrap();
         self.set_current(next.clone(), compositor_proxy);
         next
     }
 
     /// Loads a new set of page frames, returning all evicted frame trees
     fn load(&mut self, frame_tree: Rc<FrameTree>, compositor_proxy: &mut CompositorProxy)
             -> Vec<Rc<FrameTree>> {
-        debug!("navigating to {}", frame_tree.pipeline.borrow().id);
+        debug!("navigating to {:?}", frame_tree.pipeline.borrow().id);
         let evicted = replace(&mut self.next, vec!());
         match self.current.take() {
             Some(current) => self.previous.push(current),
             None => (),
         }
         self.set_current(frame_tree, compositor_proxy);
         evicted
     }
@@ -345,17 +347,17 @@ impl<LTF: LayoutTaskFactory, STF: Script
                  image_cache_task: ImageCacheTask,
                  font_cache_task: FontCacheTask,
                  time_profiler_chan: TimeProfilerChan,
                  devtools_chan: Option<DevtoolsControlChan>,
                  storage_task: StorageTask)
                  -> ConstellationChan {
         let (constellation_port, constellation_chan) = ConstellationChan::new();
         let constellation_chan_clone = constellation_chan.clone();
-        spawn_named("Constellation".to_owned(), proc() {
+        spawn_named("Constellation".to_owned(), move || {
             let mut constellation: Constellation<LTF, STF> = Constellation {
                 chan: constellation_chan_clone,
                 request_port: constellation_port,
                 compositor_proxy: compositor_proxy,
                 devtools_chan: devtools_chan,
                 resource_task: resource_task,
                 image_cache_task: image_cache_task,
                 font_cache_task: font_cache_task,
@@ -375,17 +377,17 @@ impl<LTF: LayoutTaskFactory, STF: Script
             };
             constellation.run();
         });
         constellation_chan
     }
 
     fn run(&mut self) {
         loop {
-            let request = self.request_port.recv();
+            let request = self.request_port.recv().unwrap();
             if !self.handle_request(request) {
                 break;
             }
         }
     }
 
     /// Helper function for creating a pipeline
     fn new_pipeline(&mut self,
@@ -512,27 +514,27 @@ impl<LTF: LayoutTaskFactory, STF: Script
         true
     }
 
     fn handle_exit(&mut self) {
         for (_id, ref pipeline) in self.pipelines.iter() {
             pipeline.exit(PipelineExitType::Complete);
         }
         self.image_cache_task.exit();
-        self.resource_task.send(resource_task::ControlMsg::Exit);
+        self.resource_task.send(resource_task::ControlMsg::Exit).unwrap();
         self.devtools_chan.as_ref().map(|chan| {
-            chan.send(devtools_traits::ServerExitMsg);
+            chan.send(devtools_traits::ServerExitMsg).unwrap();
         });
-        self.storage_task.send(StorageTaskMsg::Exit);
+        self.storage_task.send(StorageTaskMsg::Exit).unwrap();
         self.font_cache_task.exit();
         self.compositor_proxy.send(CompositorMsg::ShutdownComplete);
     }
 
     fn handle_failure_msg(&mut self, pipeline_id: PipelineId, subpage_id: Option<SubpageId>) {
-        debug!("handling failure message from pipeline {}, {}", pipeline_id, subpage_id);
+        debug!("handling failure message from pipeline {:?}, {:?}", pipeline_id, subpage_id);
 
         if opts::get().hard_fail {
             // It's quite difficult to make Servo exit cleanly if some tasks have failed.
             // Hard fail exists for test runners so we crash and that's good enough.
             let mut stderr = io::stderr();
             stderr.write_str("Pipeline failed in hard-fail mode.  Crashing!\n").unwrap();
             stderr.flush().unwrap();
             unsafe { libc::exit(1); }
@@ -599,21 +601,21 @@ impl<LTF: LayoutTaskFactory, STF: Script
         self.browse(None,
                     Rc::new(FrameTree::new(next_frame_id, pipeline.clone(), None)),
                     NavigationType::Load);
         self.pipelines.insert(pipeline.id, pipeline);
     }
 
     fn handle_frame_rect_msg(&mut self, pipeline_id: PipelineId, subpage_id: SubpageId,
                              rect: TypedRect<PagePx, f32>) {
-        debug!("Received frame rect {} from {}, {}", rect, pipeline_id, subpage_id);
+        debug!("Received frame rect {:?} from {:?}, {:?}", rect, pipeline_id, subpage_id);
         let mut already_sent = HashSet::new();
 
         // Returns true if a child frame tree's subpage id matches the given subpage id
-        let subpage_eq = |child_frame_tree: & &mut ChildFrameTree| {
+        let subpage_eq = |&:child_frame_tree: & &mut ChildFrameTree| {
             child_frame_tree.frame_tree.pipeline.borrow().
                 subpage_id.expect("Constellation:
                 child frame does not have a subpage id. This should not be possible.")
                 == subpage_id
         };
 
         let frames = self.find_all(pipeline_id);
 
@@ -674,17 +676,17 @@ impl<LTF: LayoutTaskFactory, STF: Script
             let pipeline = &*child_frame_tree.frame_tree.pipeline.borrow();
             if !already_sent.contains(&pipeline.id) {
                 if is_active {
                     let ScriptControlChan(ref script_chan) = pipeline.script_chan;
                     script_chan.send(ConstellationControlMsg::Resize(pipeline.id, WindowSizeData {
                         visible_viewport: rect.size,
                         initial_viewport: rect.size * ScaleFactor(1.0),
                         device_pixel_ratio: device_pixel_ratio,
-                    }));
+                    })).unwrap();
                     compositor_proxy.send(CompositorMsg::SetLayerOrigin(
                         pipeline.id,
                         LayerId::null(),
                         rect.to_untyped().origin));
                 } else {
                     already_sent.insert(pipeline.id);
                 }
             };
@@ -692,17 +694,17 @@ impl<LTF: LayoutTaskFactory, STF: Script
     }
 
     fn update_child_pipeline(&mut self,
                              frame_tree: Rc<FrameTree>,
                              new_pipeline: Rc<Pipeline>,
                              old_subpage_id: SubpageId) {
         let existing_tree = match frame_tree.find_with_subpage_id(Some(old_subpage_id)) {
             Some(existing_tree) => existing_tree.clone(),
-            None => panic!("Tried to update non-existing frame tree with pipeline={} subpage={}",
+            None => panic!("Tried to update non-existing frame tree with pipeline={:?} subpage={:?}",
                            new_pipeline.id,
                            old_subpage_id),
         };
 
         let old_pipeline = existing_tree.pipeline.borrow().clone();
         *existing_tree.pipeline.borrow_mut() = new_pipeline.clone();
 
         // If we have not yet sent this frame to the compositor for layer creation, we don't
@@ -711,17 +713,17 @@ impl<LTF: LayoutTaskFactory, STF: Script
             return;
         }
 
         let (chan, port) = channel();
         self.compositor_proxy.send(CompositorMsg::ChangeLayerPipelineAndRemoveChildren(
             old_pipeline.to_sendable(),
             new_pipeline.to_sendable(),
             chan));
-        let _ = port.recv_opt();
+        let _ = port.recv();
     }
 
     fn create_or_update_child_pipeline(&mut self,
                                        frame_tree: Rc<FrameTree>,
                                        new_pipeline: Rc<Pipeline>,
                                        new_rect: Option<TypedRect<PagePx, f32>>,
                                        old_subpage_id: Option<SubpageId>) {
         match old_subpage_id {
@@ -765,20 +767,20 @@ impl<LTF: LayoutTaskFactory, STF: Script
         let source_url = source_pipeline.load_data.url.clone();
 
         let same_script = (source_url.host() == url.host() &&
                            source_url.port() == url.port()) &&
                            sandbox == IFrameSandboxState::IFrameUnsandboxed;
         // FIXME(tkuehn): Need to follow the standardized spec for checking same-origin
         // Reuse the script task if the URL is same-origin
         let script_pipeline = if same_script {
-            debug!("Constellation: loading same-origin iframe at {}", url);
+            debug!("Constellation: loading same-origin iframe at {:?}", url);
             Some(source_pipeline.clone())
         } else {
-            debug!("Constellation: loading cross-origin iframe at {}", url);
+            debug!("Constellation: loading cross-origin iframe at {:?}", url);
             None
         };
 
         let new_frame_pipeline_id = self.get_next_pipeline_id();
         let pipeline = self.new_pipeline(
             new_frame_pipeline_id,
             Some(new_subpage_id),
             script_pipeline,
@@ -796,17 +798,17 @@ impl<LTF: LayoutTaskFactory, STF: Script
     }
 
     fn handle_set_cursor_msg(&mut self, cursor: Cursor) {
         self.compositor_proxy.send(CompositorMsg::SetCursor(cursor))
     }
 
     fn handle_load_url_msg(&mut self, source_id: PipelineId, load_data: LoadData) {
         let url = load_data.url.to_string();
-        debug!("Constellation: received message to load {}", url);
+        debug!("Constellation: received message to load {:?}", url);
         // Make sure no pending page would be overridden.
         let source_frame = self.current_frame().as_ref().unwrap().find(source_id).expect(
             "Constellation: received a LoadUrl message from a pipeline_id associated
             with a pipeline not in the active frame tree. This should be
             impossible.");
 
         for frame_change in self.pending_frames.iter() {
             let old_id = frame_change.before.expect("Constellation: Received load msg
@@ -832,17 +834,17 @@ impl<LTF: LayoutTaskFactory, STF: Script
                     Rc::new(FrameTree::new(next_frame_id,
                                            pipeline.clone(),
                                            parent.borrow().clone())),
                     NavigationType::Load);
         self.pipelines.insert(pipeline.id, pipeline);
     }
 
     fn handle_navigate_msg(&mut self, direction: constellation_msg::NavigationDirection) {
-        debug!("received message to navigate {}", direction);
+        debug!("received message to navigate {:?}", direction);
 
         // TODO(tkuehn): what is the "critical point" beyond which pending frames
         // should not be cleared? Currently, the behavior is that forward/back
         // navigation always has navigation priority, and after that new page loading is
         // first come, first served.
         let destination_frame = match direction {
             NavigationDirection::Forward => {
                 if self.navigation_context.next.is_empty() {
@@ -881,32 +883,32 @@ impl<LTF: LayoutTaskFactory, STF: Script
         self.current_frame().iter()
             .any(|current_frame| current_frame.contains(pipeline_id))
     }
 
     fn handle_key_msg(&self, key: Key, state: KeyState, mods: KeyModifiers) {
         self.current_frame().as_ref().map(|frame| {
             let ScriptControlChan(ref chan) = frame.pipeline.borrow().script_chan;
             chan.send(ConstellationControlMsg::SendEvent(
-                frame.pipeline.borrow().id, CompositorEvent::KeyEvent(key, state, mods)));
+                frame.pipeline.borrow().id, CompositorEvent::KeyEvent(key, state, mods))).unwrap();
         });
     }
 
     fn handle_get_pipeline_title_msg(&mut self, pipeline_id: PipelineId) {
         match self.pipelines.get(&pipeline_id) {
             None => self.compositor_proxy.send(CompositorMsg::ChangePageTitle(pipeline_id, None)),
             Some(pipeline) => {
                 let ScriptControlChan(ref script_channel) = pipeline.script_chan;
-                script_channel.send(ConstellationControlMsg::GetTitle(pipeline_id));
+                script_channel.send(ConstellationControlMsg::GetTitle(pipeline_id)).unwrap();
             }
         }
     }
 
     fn handle_painter_ready_msg(&mut self, pipeline_id: PipelineId) {
-        debug!("Painter {} ready to send paint msg", pipeline_id);
+        debug!("Painter {:?} ready to send paint msg", pipeline_id);
         // This message could originate from a pipeline in the navigation context or
         // from a pending frame. The only time that we will grant paint permission is
         // when the message originates from a pending frame or the current frame.
 
         // Messages originating in the current frame are not navigations;
         // they may come from a page load in a subframe.
         if self.pipeline_is_in_current_frame(pipeline_id) {
             self.create_compositor_layer_for_iframe_if_necessary(pipeline_id);
@@ -916,48 +918,48 @@ impl<LTF: LayoutTaskFactory, STF: Script
         // Find the pending frame change whose new pipeline id is pipeline_id.
         // If it is not found, it simply means that this pipeline will not receive
         // permission to paint.
         let pending_index = self.pending_frames.iter().rposition(|frame_change| {
             frame_change.after.pipeline.borrow().id == pipeline_id
         });
         match pending_index {
             Some(pending_index) => {
-                let frame_change = self.pending_frames.swap_remove(pending_index).unwrap();
+                let frame_change = self.pending_frames.swap_remove(pending_index);
                 let to_add = frame_change.after.clone();
 
                 // Create the next frame tree that will be given to the compositor
                 let next_frame_tree = if to_add.parent.borrow().is_some() {
                     // NOTE: work around borrowchk issues
                     self.current_frame().as_ref().unwrap().clone()
                 } else {
                     to_add.clone()
                 };
 
                 // If there are frames to revoke permission from, do so now.
                 match frame_change.before {
                     Some(revoke_id) if self.current_frame().is_some() => {
-                        debug!("Constellation: revoking permission from {}", revoke_id);
+                        debug!("Constellation: revoking permission from {:?}", revoke_id);
                         let current_frame = self.current_frame().as_ref().unwrap();
 
                         let to_revoke = current_frame.find(revoke_id).expect(
                             "Constellation: pending frame change refers to an old \
                             frame not contained in the current frame. This is a bug");
 
                         for frame in to_revoke.iter() {
                             frame.pipeline.borrow().revoke_paint_permission();
                         }
 
                         // If to_add is not the root frame, then replace revoked_frame with it.
                         // This conveniently keeps scissor rect size intact.
                         // NOTE: work around borrowchk issue
                         let mut flag = false;
                         {
                             if to_add.parent.borrow().is_some() {
-                                debug!("Constellation: replacing {} with {} in {}",
+                                debug!("Constellation: replacing {:?} with {:?} in {:?}",
                                        revoke_id, to_add.pipeline.borrow().id,
                                        next_frame_tree.pipeline.borrow().id);
                                 flag = true;
                             }
                         }
                         if flag {
                             next_frame_tree.replace_child(revoke_id, to_add);
                         }
@@ -989,39 +991,39 @@ impl<LTF: LayoutTaskFactory, STF: Script
 
     /// Called when the window is resized.
     fn handle_resized_window_msg(&mut self, new_size: WindowSizeData) {
         let mut already_seen = HashSet::new();
         for frame_tree in self.current_frame().iter() {
             debug!("constellation sending resize message to active frame");
             let pipeline = &*frame_tree.pipeline.borrow();;
             let ScriptControlChan(ref chan) = pipeline.script_chan;
-            let _ = chan.send_opt(ConstellationControlMsg::Resize(pipeline.id, new_size));
+            let _ = chan.send(ConstellationControlMsg::Resize(pipeline.id, new_size));
             already_seen.insert(pipeline.id);
         }
         for frame_tree in self.navigation_context.previous.iter()
             .chain(self.navigation_context.next.iter()) {
             let pipeline = &*frame_tree.pipeline.borrow();
             if !already_seen.contains(&pipeline.id) {
                 debug!("constellation sending resize message to inactive frame");
                 let ScriptControlChan(ref chan) = pipeline.script_chan;
-                let _ = chan.send_opt(ConstellationControlMsg::ResizeInactive(pipeline.id, new_size));
+                let _ = chan.send(ConstellationControlMsg::ResizeInactive(pipeline.id, new_size));
                 already_seen.insert(pipeline.id);
             }
         }
 
         // If there are any pending outermost frames, then tell them to resize. (This is how the
         // initial window size gets sent to the first page loaded, giving it permission to reflow.)
         for change in self.pending_frames.iter() {
             let frame_tree = &change.after;
             if frame_tree.parent.borrow().is_none() {
-                debug!("constellation sending resize message to pending outer frame ({})",
+                debug!("constellation sending resize message to pending outer frame ({:?})",
                        frame_tree.pipeline.borrow().id);
                 let ScriptControlChan(ref chan) = frame_tree.pipeline.borrow().script_chan;
-                let _ = chan.send_opt(ConstellationControlMsg::Resize(
+                let _ = chan.send(ConstellationControlMsg::Resize(
                     frame_tree.pipeline.borrow().id, new_size));
             }
         }
 
         self.window_size = new_size;
     }
 
     // Close all pipelines at and beneath a given frame
@@ -1066,17 +1068,17 @@ impl<LTF: LayoutTaskFactory, STF: Script
 
     // Grants a frame tree permission to paint; optionally updates navigation to reflect a new page
     fn send_frame_tree_and_grant_paint_permission(&mut self, frame_tree: Rc<FrameTree>) {
         debug!("Constellation sending SetFrameTree");
         let (chan, port) = channel();
         self.compositor_proxy.send(CompositorMsg::SetFrameTree(frame_tree.to_sendable(),
                                                                chan,
                                                                self.chan.clone()));
-        if port.recv_opt().is_err() {
+        if port.recv().is_err() {
             debug!("Compositor has discarded SetFrameTree");
             return; // Our message has been discarded, probably shutting down.
         }
 
         let mut iter = frame_tree.iter();
         for frame in iter {
             frame.has_compositor_layer.set(true);
             frame.pipeline.borrow().grant_paint_permission();
@@ -1121,17 +1123,17 @@ impl<LTF: LayoutTaskFactory, STF: Script
         }
 
         let (chan, port) = channel();
         self.compositor_proxy.send(CompositorMsg::CreateRootLayerForPipeline(
             parent.pipeline.borrow().to_sendable(),
             child.frame_tree.pipeline.borrow().to_sendable(),
             child.rect,
             chan));
-        match port.recv_opt() {
+        match port.recv() {
             Ok(()) => {
                 child.frame_tree.has_compositor_layer.set(true);
                 child.frame_tree.pipeline.borrow().grant_paint_permission();
             }
-            Err(()) => {} // The message has been discarded, we are probably shutting down.
+            Err(_) => {} // The message has been discarded, we are probably shutting down.
         }
     }
 }
--- a/servo/components/compositing/headless.rs
+++ b/servo/components/compositing/headless.rs
@@ -55,52 +55,52 @@ impl NullCompositor {
 
         // Tell the constellation about the initial fake size.
         {
             let ConstellationChan(ref chan) = compositor.constellation_chan;
             chan.send(ConstellationMsg::ResizedWindow(WindowSizeData {
                 initial_viewport: TypedSize2D(640_f32, 480_f32),
                 visible_viewport: TypedSize2D(640_f32, 480_f32),
                 device_pixel_ratio: ScaleFactor(1.0),
-            }));
+            })).unwrap();
         }
 
         compositor
     }
 }
 
 impl CompositorEventListener for NullCompositor {
     fn handle_event(&mut self, _: WindowEvent) -> bool {
         match self.port.recv_compositor_msg() {
             Msg::Exit(chan) => {
                 debug!("shutting down the constellation");
                 let ConstellationChan(ref con_chan) = self.constellation_chan;
-                con_chan.send(ConstellationMsg::Exit);
-                chan.send(());
+                con_chan.send(ConstellationMsg::Exit).unwrap();
+                chan.send(()).unwrap();
             }
 
             Msg::ShutdownComplete => {
                 debug!("constellation completed shutdown");
                 return false
             }
 
             Msg::GetGraphicsMetadata(chan) => {
-                chan.send(None);
+                chan.send(None).unwrap();
             }
 
             Msg::SetFrameTree(_, response_chan, _) => {
-                response_chan.send(());
+                response_chan.send(()).unwrap();
             }
 
             Msg::ChangeLayerPipelineAndRemoveChildren(_, _, response_channel) => {
-                response_channel.send(());
+                response_channel.send(()).unwrap();
             }
 
             Msg::CreateRootLayerForPipeline(_, _, _, response_channel) => {
-                response_channel.send(());
+                response_channel.send(()).unwrap();
             }
 
             // Explicitly list ignored messages so that when we add a new one,
             // we'll notice and think about whether it needs a response, like
             // SetFrameTree.
 
             Msg::CreateOrUpdateBaseLayer(..) |
             Msg::CreateOrUpdateDescendantLayer(..) |
--- a/servo/components/compositing/lib.rs
+++ b/servo/components/compositing/lib.rs
@@ -1,32 +1,34 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#![feature(globs, phase, macro_rules)]
+#![feature(box_syntax, plugin)]
+#![feature(int_uint)]
 
 #![deny(unused_imports)]
 #![deny(unused_variables)]
 #![allow(missing_copy_implementations)]
+#![allow(unstable)]
 
-#[phase(plugin, link)]
+#[macro_use]
 extern crate log;
 
 extern crate azure;
 extern crate devtools_traits;
 extern crate geom;
 extern crate gfx;
 extern crate layers;
 extern crate layout_traits;
 extern crate png;
 extern crate script_traits;
 extern crate "msg" as servo_msg;
 extern crate "net" as servo_net;
-#[phase(plugin, link)]
+#[macro_use]
 extern crate "util" as servo_util;
 extern crate gleam;
 
 extern crate libc;
 extern crate time;
 extern crate url;
 
 #[cfg(target_os="macos")]
--- a/servo/components/compositing/pipeline.rs
+++ b/servo/components/compositing/pipeline.rs
@@ -13,16 +13,17 @@ use gfx::paint_task::{PaintChan, PaintTa
 use servo_msg::constellation_msg::{ConstellationChan, Failure, PipelineId, SubpageId};
 use servo_msg::constellation_msg::{LoadData, WindowSizeData, PipelineExitType};
 use servo_net::image_cache_task::ImageCacheTask;
 use gfx::font_cache_task::FontCacheTask;
 use servo_net::resource_task::ResourceTask;
 use servo_net::storage_task::StorageTask;
 use servo_util::time::TimeProfilerChan;
 use std::rc::Rc;
+use std::sync::mpsc::{Receiver, channel};
 
 /// A uniquely-identifiable pipeline of script task, layout task, and paint task.
 pub struct Pipeline {
     pub id: PipelineId,
     pub subpage_id: Option<SubpageId>,
     pub script_chan: ScriptControlChan,
     pub layout_chan: LayoutControlChan,
     pub paint_chan: PaintChan,
@@ -30,17 +31,17 @@ pub struct Pipeline {
     pub paint_shutdown_port: Receiver<()>,
     /// Load data corresponding to the most recently-loaded page.
     pub load_data: LoadData,
     /// The title of the most recently-loaded page.
     pub title: Option<String>,
 }
 
 /// The subset of the pipeline that is needed for layer composition.
-#[deriving(Clone)]
+#[derive(Clone)]
 pub struct CompositionPipeline {
     pub id: PipelineId,
     pub script_chan: ScriptControlChan,
     pub paint_chan: PaintChan,
 }
 
 impl Pipeline {
     /// Starts a paint task, layout task, and possibly a script task.
@@ -94,17 +95,17 @@ impl Pipeline {
                 let new_layout_info = NewLayoutInfo {
                     old_pipeline_id: spipe.id.clone(),
                     new_pipeline_id: id,
                     subpage_id: subpage_id.expect("script_pipeline != None but subpage_id == None"),
                     layout_chan: ScriptTaskFactory::clone_layout_channel(None::<&mut STF>, &layout_pair),
                 };
 
                 let ScriptControlChan(ref chan) = spipe.script_chan;
-                chan.send(ConstellationControlMsg::AttachLayout(new_layout_info));
+                chan.send(ConstellationControlMsg::AttachLayout(new_layout_info)).unwrap();
                 spipe.script_chan.clone()
             }
         };
 
         PaintTask::create(id,
                           paint_port,
                           compositor_proxy,
                           constellation_chan.clone(),
@@ -156,51 +157,52 @@ impl Pipeline {
             paint_shutdown_port: paint_shutdown_port,
             load_data: load_data,
             title: None,
         }
     }
 
     pub fn load(&self) {
         let ScriptControlChan(ref chan) = self.script_chan;
-        chan.send(ConstellationControlMsg::Load(self.id, self.load_data.clone()));
+        chan.send(ConstellationControlMsg::Load(self.id, self.load_data.clone())).unwrap();
     }
 
     pub fn grant_paint_permission(&self) {
-        let _ = self.paint_chan.send_opt(PaintMsg::PaintPermissionGranted);
+        let _ = self.paint_chan.send(PaintMsg::PaintPermissionGranted);
     }
 
     pub fn revoke_paint_permission(&self) {
         debug!("pipeline revoking paint channel paint permission");
-        let _ = self.paint_chan.send_opt(PaintMsg::PaintPermissionRevoked);
+        let _ = self.paint_chan.send(PaintMsg::PaintPermissionRevoked);
     }
 
     pub fn exit(&self, exit_type: PipelineExitType) {
-        debug!("pipeline {} exiting", self.id);
+        debug!("pipeline {:?} exiting", self.id);
 
         // Script task handles shutting down layout, and layout handles shutting down the painter.
         // For now, if the script task has failed, we give up on clean shutdown.
         let ScriptControlChan(ref chan) = self.script_chan;
-        if chan.send_opt(ConstellationControlMsg::ExitPipeline(self.id, exit_type)).is_ok() {
+        if chan.send(ConstellationControlMsg::ExitPipeline(self.id, exit_type)).is_ok() {
             // Wait until all slave tasks have terminated and run destructors
             // NOTE: We don't wait for script task as we don't always own it
-            let _ = self.paint_shutdown_port.recv_opt();
-            let _ = self.layout_shutdown_port.recv_opt();
+            let _ = self.paint_shutdown_port.recv();
+            let _ = self.layout_shutdown_port.recv();
         }
 
     }
 
     pub fn force_exit(&self) {
         let ScriptControlChan(ref script_channel) = self.script_chan;
-        let _ = script_channel.send_opt(
+        let _ = script_channel.send(
             ConstellationControlMsg::ExitPipeline(self.id,
-                                                  PipelineExitType::PipelineOnly));
-        let _ = self.paint_chan.send_opt(PaintMsg::Exit(None, PipelineExitType::PipelineOnly));
+                                                  PipelineExitType::PipelineOnly)).unwrap();
+        let _ = self.paint_chan.send(PaintMsg::Exit(None, PipelineExitType::PipelineOnly));
         let LayoutControlChan(ref layout_channel) = self.layout_chan;
-        let _ = layout_channel.send_opt(LayoutControlMsg::ExitNowMsg(PipelineExitType::PipelineOnly));
+        let _ = layout_channel.send(
+            LayoutControlMsg::ExitNowMsg(PipelineExitType::PipelineOnly)).unwrap();
     }
 
     pub fn to_sendable(&self) -> CompositionPipeline {
         CompositionPipeline {
             id: self.id.clone(),
             script_chan: self.script_chan.clone(),
             paint_chan: self.paint_chan.clone(),
         }
--- a/servo/components/compositing/scrolling.rs
+++ b/servo/components/compositing/scrolling.rs
@@ -2,17 +2,18 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 //! A timer thread that gives the painting task a little time to catch up when the user scrolls.
 
 use compositor_task::{CompositorProxy, Msg};
 
 use std::io::timer;
-use std::task::TaskBuilder;
+use std::sync::mpsc::{Receiver, Sender, channel};
+use std::thread::Builder;
 use std::time::duration::Duration;
 use time;
 
 /// The amount of time in nanoseconds that we give to the painting thread to paint new tiles upon
 /// processing a scroll event that caused new tiles to be revealed. When this expires, we give up
 /// and composite anyway (showing a "checkerboard") to avoid dropping the frame.
 static TIMEOUT: i64 = 12_000_000;
 
@@ -28,41 +29,41 @@ pub struct ScrollingTimer {
 enum ToScrollingTimerMsg {
     ExitMsg,
     ScrollEventProcessedMsg(u64),
 }
 
 impl ScrollingTimerProxy {
     pub fn new(compositor_proxy: Box<CompositorProxy+Send>) -> ScrollingTimerProxy {
         let (to_scrolling_timer_sender, to_scrolling_timer_receiver) = channel();
-        TaskBuilder::new().spawn(proc() {
+        Builder::new().spawn(move || {
             let mut scrolling_timer = ScrollingTimer {
                 compositor_proxy: compositor_proxy,
                 receiver: to_scrolling_timer_receiver,
             };
             scrolling_timer.run();
         });
         ScrollingTimerProxy {
             sender: to_scrolling_timer_sender,
         }
     }
 
     pub fn scroll_event_processed(&mut self, timestamp: u64) {
-        self.sender.send(ToScrollingTimerMsg::ScrollEventProcessedMsg(timestamp))
+        self.sender.send(ToScrollingTimerMsg::ScrollEventProcessedMsg(timestamp)).unwrap()
     }
 
     pub fn shutdown(&mut self) {
-        self.sender.send(ToScrollingTimerMsg::ExitMsg);
+        self.sender.send(ToScrollingTimerMsg::ExitMsg).unwrap()
     }
 }
 
 impl ScrollingTimer {
     pub fn run(&mut self) {
         loop {
-            match self.receiver.recv_opt() {
+            match self.receiver.recv() {
                 Ok(ToScrollingTimerMsg::ScrollEventProcessedMsg(timestamp)) => {
                     let target = timestamp as i64 + TIMEOUT;
                     let delta = target - (time::precise_time_ns() as i64);
                     timer::sleep(Duration::nanoseconds(delta));
                     self.compositor_proxy.send(Msg::ScrollTimeout(timestamp));
                 }
                 Ok(ToScrollingTimerMsg::ExitMsg) | Err(_) => break,
             }
--- a/servo/components/compositing/windowing.rs
+++ b/servo/components/compositing/windowing.rs
@@ -13,47 +13,47 @@ use layers::geometry::DevicePixel;
 use layers::platform::surface::NativeGraphicsMetadata;
 use servo_msg::compositor_msg::{PaintState, ReadyState};
 use servo_msg::constellation_msg::{Key, KeyState, KeyModifiers, LoadData};
 use servo_util::cursor::Cursor;
 use servo_util::geometry::ScreenPx;
 use std::fmt::{Error, Formatter, Show};
 use std::rc::Rc;
 
-#[deriving(Clone)]
+#[derive(Clone)]
 pub enum MouseWindowEvent {
     Click(uint, TypedPoint2D<DevicePixel, f32>),
     MouseDown(uint, TypedPoint2D<DevicePixel, f32>),
     MouseUp(uint, TypedPoint2D<DevicePixel, f32>),
 }
 
-#[deriving(Clone)]
+#[derive(Clone)]
 pub enum WindowNavigateMsg {
     Forward,
     Back,
 }
 
 /// Events that the windowing system sends to Servo.
-#[deriving(Clone)]
+#[derive(Clone)]
 pub enum WindowEvent {
     /// Sent when no message has arrived, but the event loop was kicked for some reason (perhaps
     /// by another Servo subsystem).
     ///
     /// FIXME(pcwalton): This is kind of ugly and may not work well with multiprocess Servo.
     /// It's possible that this should be something like
     /// `CompositorMessageWindowEvent(compositor_task::Msg)` instead.
     Idle,
     /// Sent when part of the window is marked dirty and needs to be redrawn. Before sending this
     /// message, the window must make the same GL context as in `PrepareRenderingEvent` current.
     Refresh,
     /// Sent to initialize the GL context. The windowing system must have a valid, current GL
     /// context when this message is sent.
     InitializeCompositing,
     /// Sent when the window is resized.
-    Resize(TypedSize2D<DevicePixel, uint>),
+    Resize(TypedSize2D<DevicePixel, u32>),
     /// Sent when a new URL is to be loaded.
     LoadUrl(String),
     /// Sent when a mouse hit test is to be performed.
     MouseWindowEventClass(MouseWindowEvent),
     /// Sent when a mouse move.
     MouseWindowMoveEventClass(TypedPoint2D<DevicePixel, f32>),
     /// Sent when the user scrolls. The first point is the delta and the second point is the
     /// origin.
@@ -87,17 +87,17 @@ impl Show for WindowEvent {
             WindowEvent::Navigation(..) => write!(f, "Navigation"),
             WindowEvent::Quit => write!(f, "Quit"),
         }
     }
 }
 
 pub trait WindowMethods {
     /// Returns the size of the window in hardware pixels.
-    fn framebuffer_size(&self) -> TypedSize2D<DevicePixel, uint>;
+    fn framebuffer_size(&self) -> TypedSize2D<DevicePixel, u32>;
     /// Returns the size of the window in density-independent "px" units.
     fn size(&self) -> TypedSize2D<ScreenPx, f32>;
     /// Presents the window to the screen (perhaps by page flipping).
     fn present(&self);
 
     /// Sets the ready state of the current page.
     fn set_ready_state(&self, ready_state: ReadyState);
     /// Sets the paint state of the current page.
--- a/servo/components/devtools/actor.rs
+++ b/servo/components/devtools/actor.rs
@@ -1,75 +1,33 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /// General actor system infrastructure.
 
-use std::any::{Any, AnyRefExt, AnyMutRefExt};
+use std::any::Any;
 use std::collections::HashMap;
 use std::cell::{Cell, RefCell};
-use std::intrinsics::TypeId;
 use std::io::TcpStream;
-use std::mem::{transmute, transmute_copy, replace};
-use std::raw::TraitObject;
+use std::mem::replace;
 use serialize::json;
 
 /// A common trait for all devtools actors that encompasses an immutable name
 /// and the ability to process messages that are directed to particular actors.
 /// TODO: ensure the name is immutable
 pub trait Actor : Any {
     fn handle_message(&self,
                       registry: &ActorRegistry,
                       msg_type: &String,
                       msg: &json::Object,
                       stream: &mut TcpStream) -> Result<bool, ()>;
     fn name(&self) -> String;
 }
 
-impl<'a> AnyMutRefExt<'a> for &'a mut (Actor + 'a) {
-    fn downcast_mut<T: 'static>(self) -> Option<&'a mut T> {
-        if self.is::<T>() {
-            unsafe {
-                // Get the raw representation of the trait object
-                let to: TraitObject = transmute_copy(&self);
-
-                // Extract the data pointer
-                Some(transmute(to.data))
-            }
-        } else {
-            None
-        }
-    }
-}
-
-impl<'a> AnyRefExt<'a> for &'a (Actor + 'a) {
-    fn is<T: 'static>(self) -> bool {
-        // This implementation is only needed so long as there's a Rust bug that
-        // prevents downcast_ref from giving realistic return values.
-        let t = TypeId::of::<T>();
-        let boxed: TypeId = (*self).get_type_id();
-        t == boxed
-    }
-
-    fn downcast_ref<T: 'static>(self) -> Option<&'a T> {
-        if self.is::<T>() {
-            unsafe {
-                // Get the raw representation of the trait object
-                let to: TraitObject = transmute_copy(&self);
-
-                // Extract the data pointer
-                Some(transmute(to.data))
-            }
-        } else {
-            None
-        }
-    }
-}
-
 /// A list of known, owned actors.
 pub struct ActorRegistry {
     actors: HashMap<String, Box<Actor+Send+Sized>>,
     new_actors: RefCell<Vec<Box<Actor+Send+Sized>>>,
     script_actors: RefCell<HashMap<String, String>>,
     next: Cell<u32>,
 }
 
@@ -125,30 +83,24 @@ impl ActorRegistry {
 
     pub fn register_later(&self, actor: Box<Actor+Send+Sized>) {
         let mut actors = self.new_actors.borrow_mut();
         actors.push(actor);
     }
 
     /// Find an actor by registered name
     pub fn find<'a, T: 'static>(&'a self, name: &str) -> &'a T {
-        //FIXME: Rust bug forces us to implement bogus Any for Actor since downcast_ref currently
-        //       fails for unknown reasons.
-        /*let actor: &Actor+Send+Sized = *self.actors.find(&name.to_string()).unwrap();
-        (actor as &Any).downcast_ref::<T>().unwrap()*/
-        self.actors.get(&name.to_string()).unwrap().downcast_ref::<T>().unwrap()
+        let actor: &Any = self.actors.get(&name.to_string()).unwrap();
+        actor.downcast_ref::<T>().unwrap()
     }
 
     /// Find an actor by registered name
     pub fn find_mut<'a, T: 'static>(&'a mut self, name: &str) -> &'a mut T {
-        //FIXME: Rust bug forces us to implement bogus Any for Actor since downcast_ref currently
-        //       fails for unknown reasons.
-        /*let actor: &mut Actor+Send+Sized = *self.actors.find_mut(&name.to_string()).unwrap();
-        (actor as &mut Any).downcast_mut::<T>().unwrap()*/
-        self.actors.get_mut(&name.to_string()).unwrap().downcast_mut::<T>().unwrap()
+        let actor: &mut Any = self.actors.get_mut(&name.to_string()).unwrap();
+        actor.downcast_mut::<T>().unwrap()
     }
 
     /// Attempt to process a message as directed by its `to` property. If the actor is not
     /// found or does not indicate that it knew how to process the message, ignore the failure.
     pub fn handle_message(&mut self,
                           msg: &json::Object,
                           stream: &mut TcpStream)
                           -> Result<(), ()> {
--- a/servo/components/devtools/actors/console.rs
+++ b/servo/components/devtools/actors/console.rs
@@ -8,42 +8,43 @@
 
 use actor::{Actor, ActorRegistry};
 use protocol::JsonPacketStream;
 
 use devtools_traits::{EvaluateJS, NullValue, VoidValue, NumberValue, StringValue, BooleanValue};
 use devtools_traits::{ActorValue, DevtoolScriptControlMsg};
 use servo_msg::constellation_msg::PipelineId;
 
-use collections::TreeMap;
+use collections::BTreeMap;
 use core::cell::RefCell;
 use serialize::json::{mod, Json, ToJson};
 use std::io::TcpStream;
 use std::num::Float;
+use std::sync::mpsc::{channel, Sender};
 
-#[deriving(Encodable)]
+#[derive(RustcEncodable)]
 struct StartedListenersTraits {
     customNetworkRequest: bool,
 }
 
-#[deriving(Encodable)]
+#[derive(RustcEncodable)]
 struct StartedListenersReply {
     from: String,
     nativeConsoleAPI: bool,
     startedListeners: Vec<String>,
     traits: StartedListenersTraits,
 }
 
-#[deriving(Encodable)]
+#[derive(RustcEncodable)]
 #[allow(dead_code)]
 struct ConsoleAPIMessage {
     _type: String, //FIXME: should this be __type__ instead?
 }
 
-#[deriving(Encodable)]
+#[derive(RustcEncodable)]
 #[allow(dead_code)]
 struct PageErrorMessage {
     _type: String, //FIXME: should this be __type__ instead?
     errorMessage: String,
     sourceName: String,
     lineText: String,
     lineNumber: uint,
     columnNumber: uint,
@@ -51,52 +52,52 @@ struct PageErrorMessage {
     timeStamp: uint,
     warning: bool,
     error: bool,
     exception: bool,
     strict: bool,
     private: bool,
 }
 
-#[deriving(Encodable)]
+#[derive(RustcEncodable)]
 #[allow(dead_code)]
 struct LogMessage {
     _type: String, //FIXME: should this be __type__ instead?
     timeStamp: uint,
     message: String,
 }
 
-#[deriving(Encodable)]
+#[derive(RustcEncodable)]
 #[allow(dead_code)]
 enum ConsoleMessageType {
     ConsoleAPIType(ConsoleAPIMessage),
     PageErrorType(PageErrorMessage),
     LogMessageType(LogMessage),
 }
 
-#[deriving(Encodable)]
+#[derive(RustcEncodable)]
 struct GetCachedMessagesReply {
     from: String,
     messages: Vec<json::Object>,
 }
 
-#[deriving(Encodable)]
+#[derive(RustcEncodable)]
 struct StopListenersReply {
     from: String,
     stoppedListeners: Vec<String>,
 }
 
-#[deriving(Encodable)]
+#[derive(RustcEncodable)]
 struct AutocompleteReply {
     from: String,
     matches: Vec<String>,
     matchProp: String,
 }
 
-#[deriving(Encodable)]
+#[derive(RustcEncodable)]
 struct EvaluateJSReply {
     from: String,
     input: String,
     result: Json,
     timestamp: uint,
     exception: Json,
     exceptionMessage: String,
     helperResult: Json,
@@ -215,75 +216,75 @@ impl Actor for ConsoleActor {
                 };
                 stream.write_json_packet(&msg);
                 true
             }
 
             "evaluateJS" => {
                 let input = msg.get(&"text".to_string()).unwrap().as_string().unwrap().to_string();
                 let (chan, port) = channel();
-                self.script_chan.send(EvaluateJS(self.pipeline, input.clone(), chan));
+                self.script_chan.send(EvaluateJS(self.pipeline, input.clone(), chan)).unwrap();
 
                 //TODO: extract conversion into protocol module or some other useful place
-                let result = match try!(port.recv_opt()) {
+                let result = match try!(port.recv().map_err(|_| ())) {
                     VoidValue => {
-                        let mut m = TreeMap::new();
+                        let mut m = BTreeMap::new();
                         m.insert("type".to_string(), "undefined".to_string().to_json());
                         Json::Object(m)
                     }
                     NullValue => {
-                        let mut m = TreeMap::new();
+                        let mut m = BTreeMap::new();
                         m.insert("type".to_string(), "null".to_string().to_json());
                         Json::Object(m)
                     }
                     BooleanValue(val) => val.to_json(),
                     NumberValue(val) => {
                         if val.is_nan() {
-                            let mut m = TreeMap::new();
+                            let mut m = BTreeMap::new();
                             m.insert("type".to_string(), "NaN".to_string().to_json());
                             Json::Object(m)
                         } else if val.is_infinite() {
-                            let mut m = TreeMap::new();
+                            let mut m = BTreeMap::new();
                             if val < 0. {
                                 m.insert("type".to_string(), "-Infinity".to_string().to_json());
                             } else {
                                 m.insert("type".to_string(), "Infinity".to_string().to_json());
                             }
                             Json::Object(m)
                         } else if val == Float::neg_zero() {
-                            let mut m = TreeMap::new();
+                            let mut m = BTreeMap::new();
                             m.insert("type".to_string(), "-0".to_string().to_json());
                             Json::Object(m)
                         } else {
                             val.to_json()
                         }
                     }
                     StringValue(s) => s.to_json(),
                     ActorValue(s) => {
                         //TODO: make initial ActorValue message include these properties.
-                        let mut m = TreeMap::new();
+                        let mut m = BTreeMap::new();
                         m.insert("type".to_string(), "object".to_string().to_json());
                         m.insert("class".to_string(), "???".to_string().to_json());
                         m.insert("actor".to_string(), s.to_json());
                         m.insert("extensible".to_string(), true.to_json());
                         m.insert("frozen".to_string(), false.to_json());
                         m.insert("sealed".to_string(), false.to_json());
                         Json::Object(m)
                     }
                 };
 
                 //TODO: catch and return exception values from JS evaluation
                 let msg = EvaluateJSReply {
                     from: self.name(),
                     input: input,
                     result: result,
                     timestamp: 0,
-                    exception: Json::Object(TreeMap::new()),
+                    exception: Json::Object(BTreeMap::new()),
                     exceptionMessage: "".to_string(),
-                    helperResult: Json::Object(TreeMap::new()),
+                    helperResult: Json::Object(BTreeMap::new()),
                 };
                 stream.write_json_packet(&msg);
                 true
             }
 
             _ => false
         })
     }
--- a/servo/components/devtools/actors/inspector.rs
+++ b/servo/components/devtools/actors/inspector.rs
@@ -5,59 +5,60 @@
 /// Liberally derived from the [Firefox JS implementation](http://mxr.mozilla.org/mozilla-central/source/toolkit/devtools/server/actors/inspector.js).
 
 use devtools_traits::{GetRootNode, GetDocumentElement, GetChildren, DevtoolScriptControlMsg};
 use devtools_traits::{GetLayout, NodeInfo, ModifyAttribute};
 
 use actor::{Actor, ActorRegistry};
 use protocol::JsonPacketStream;
 
-use collections::TreeMap;
+use collections::BTreeMap;
 use servo_msg::constellation_msg::PipelineId;
 use serialize::json::{mod, Json, ToJson};
 use std::cell::RefCell;
 use std::io::TcpStream;
+use std::sync::mpsc::{channel, Sender};
 use std::num::Float;
 
 pub struct InspectorActor {
     pub name: String,
     pub walker: RefCell<Option<String>>,
     pub pageStyle: RefCell<Option<String>>,
     pub highlighter: RefCell<Option<String>>,
     pub script_chan: Sender<DevtoolScriptControlMsg>,
     pub pipeline: PipelineId,
 }
 
-#[deriving(Encodable)]
+#[derive(RustcEncodable)]
 struct GetHighlighterReply {
     highligter: HighlighterMsg, // sic.
     from: String,
 }
 
-#[deriving(Encodable)]
+#[derive(RustcEncodable)]
 struct HighlighterMsg {
     actor: String,
 }
 
 struct HighlighterActor {
     name: String,
 }
 
 pub struct NodeActor {
     pub name: String,
     script_chan: Sender<DevtoolScriptControlMsg>,
     pipeline: PipelineId,
 }
 
-#[deriving(Encodable)]
+#[derive(RustcEncodable)]
 struct ShowBoxModelReply {
     from: String,
 }
 
-#[deriving(Encodable)]
+#[derive(RustcEncodable)]
 struct HideBoxModelReply {
     from: String,
 }
 
 impl Actor for HighlighterActor {
     fn name(&self) -> String {
         self.name.clone()
     }
@@ -84,17 +85,17 @@ impl Actor for HighlighterActor {
                 true
             }
 
             _ => false,
         })
     }
 }
 
-#[deriving(Encodable)]
+#[derive(RustcEncodable)]
 struct ModifyAttributeReply{
     from: String,
 }
 
 impl Actor for NodeActor {
     fn name(&self) -> String {
         self.name.clone()
     }
@@ -109,49 +110,50 @@ impl Actor for NodeActor {
                 let target = msg.get(&"to".to_string()).unwrap().as_string().unwrap();
                 let mods = msg.get(&"modifications".to_string()).unwrap().as_array().unwrap();
                 let modifications = mods.iter().map(|json_mod| {
                     json::decode(json_mod.to_string().as_slice()).unwrap()
                 }).collect();
 
                 self.script_chan.send(ModifyAttribute(self.pipeline,
                                                       registry.actor_to_script(target.to_string()),
-                                                      modifications));
+                                                      modifications))
+                                .unwrap();
                 let reply = ModifyAttributeReply{
                     from: self.name(),
                 };
                 stream.write_json_packet(&reply);
                 true
             }
 
             _ => false,
         })
     }
 }
 
-#[deriving(Encodable)]
+#[derive(RustcEncodable)]
 struct GetWalkerReply {
     from: String,
     walker: WalkerMsg,
 }
 
-#[deriving(Encodable)]
+#[derive(RustcEncodable)]
 struct WalkerMsg {
     actor: String,
     root: NodeActorMsg,
 }
 
-#[deriving(Encodable)]
+#[derive(RustcEncodable)]
 struct AttrMsg {
     namespace: String,
     name: String,
     value: String,
 }
 
-#[deriving(Encodable)]
+#[derive(RustcEncodable)]
 struct NodeActorMsg {
     actor: String,
     baseURI: String,
     parent: String,
     nodeType: uint,
     namespaceURI: String,
     nodeName: String,
     numChildren: uint,
@@ -238,33 +240,33 @@ impl NodeInfoToProtocol for NodeInfo {
 }
 
 struct WalkerActor {
     name: String,
     script_chan: Sender<DevtoolScriptControlMsg>,
     pipeline: PipelineId,
 }
 
-#[deriving(Encodable)]
+#[derive(RustcEncodable)]
 struct QuerySelectorReply {
     from: String,
 }
 
-#[deriving(Encodable)]
+#[derive(RustcEncodable)]
 struct DocumentElementReply {
     from: String,
     node: NodeActorMsg,
 }
 
-#[deriving(Encodable)]
+#[derive(RustcEncodable)]
 struct ClearPseudoclassesReply {
     from: String,
 }
 
-#[deriving(Encodable)]
+#[derive(RustcEncodable)]
 struct ChildrenReply {
     hasFirst: bool,
     hasLast: bool,
     nodes: Vec<NodeActorMsg>,
     from: String,
 }
 
 impl Actor for WalkerActor {
@@ -283,18 +285,18 @@ impl Actor for WalkerActor {
                     from: self.name(),
                 };
                 stream.write_json_packet(&msg);
                 true
             }
 
             "documentElement" => {
                 let (tx, rx) = channel();
-                self.script_chan.send(GetDocumentElement(self.pipeline, tx));
-                let doc_elem_info = rx.recv();
+                self.script_chan.send(GetDocumentElement(self.pipeline, tx)).unwrap();
+                let doc_elem_info = rx.recv().unwrap();
                 let node = doc_elem_info.encode(registry, true, self.script_chan.clone(), self.pipeline);
 
                 let msg = DocumentElementReply {
                     from: self.name(),
                     node: node,
                 };
                 stream.write_json_packet(&msg);
                 true
@@ -308,18 +310,19 @@ impl Actor for WalkerActor {
                 true
             }
 
             "children" => {
                 let target = msg.get(&"node".to_string()).unwrap().as_string().unwrap();
                 let (tx, rx) = channel();
                 self.script_chan.send(GetChildren(self.pipeline,
                                                   registry.actor_to_script(target.to_string()),
-                                                  tx));
-                let children = rx.recv();
+                                                  tx))
+                                .unwrap();
+                let children = rx.recv().unwrap();
 
                 let msg = ChildrenReply {
                     hasFirst: true,
                     hasLast: true,
                     nodes: children.into_iter().map(|child| {
                         child.encode(registry, true, self.script_chan.clone(), self.pipeline)
                     }).collect(),
                     from: self.name(),
@@ -328,87 +331,87 @@ impl Actor for WalkerActor {
                 true
             }
 
             _ => false,
         })
     }
 }
 
-#[deriving(Encodable)]
+#[derive(RustcEncodable)]
 struct GetPageStyleReply {
     from: String,
     pageStyle: PageStyleMsg,
 }
 
-#[deriving(Encodable)]
+#[derive(RustcEncodable)]
 struct PageStyleMsg {
     actor: String,
 }
 
 struct PageStyleActor {
     name: String,
     script_chan: Sender<DevtoolScriptControlMsg>,
     pipeline: PipelineId,
 }
 
-#[deriving(Encodable)]
+#[derive(RustcEncodable)]
 struct GetAppliedReply {
     entries: Vec<AppliedEntry>,
     rules: Vec<AppliedRule>,
     sheets: Vec<AppliedSheet>,
     from: String,
 }
 
-#[deriving(Encodable)]
+#[derive(RustcEncodable)]
 struct GetComputedReply {
     computed: Vec<uint>, //XXX all css props
     from: String,
 }
 
-#[deriving(Encodable)]
+#[derive(RustcEncodable)]
 struct AppliedEntry {
     rule: String,
     pseudoElement: Json,
     isSystem: bool,
     matchedSelectors: Vec<String>,
 }
 
-#[deriving(Encodable)]
+#[derive(RustcEncodable)]
 struct AppliedRule {
     actor: String,
     __type__: uint,
     href: String,
     cssText: String,
     line: uint,
     column: uint,
     parentStyleSheet: String,
 }
 
-#[deriving(Encodable)]
+#[derive(RustcEncodable)]
 struct AppliedSheet {
     actor: String,
     href: String,
     nodeHref: String,
     disabled: bool,
     title: String,
     system: bool,
     styleSheetIndex: int,
     ruleCount: uint,
 }
 
-#[deriving(Encodable)]
+#[derive(RustcEncodable)]
 struct GetLayoutReply {
     width: int,
     height: int,
     autoMargins: Json,
     from: String,
 }
 
-#[deriving(Encodable)]
+#[derive(RustcEncodable)]
 #[allow(dead_code)]
 struct AutoMargins {
     top: String,
     bottom: String,
     left: String,
     right: String,
 }
 
@@ -445,30 +448,31 @@ impl Actor for PageStyleActor {
                 true
             }
 
             //TODO: query script for box layout properties of node (msg.node)
             "getLayout" => {
                 let target = msg.get(&"node".to_string()).unwrap().as_string().unwrap();
                 let (tx, rx) = channel();
                 self.script_chan.send(GetLayout(self.pipeline,
-                                                registry.actor_to_script(target.to_string()),
-                                                tx));
-                let (width, height) = rx.recv();
+                                      registry.actor_to_script(target.to_string()),
+                                      tx))
+                                .unwrap();
+                let (width, height) = rx.recv().unwrap();
 
                 let auto_margins = msg.get(&"autoMargins".to_string()).unwrap().as_boolean().unwrap();
 
                 //TODO: the remaining layout properties (margin, border, padding, position)
                 //      as specified in getLayout in http://mxr.mozilla.org/mozilla-central/source/toolkit/devtools/server/actors/styles.js
                 let msg = GetLayoutReply {
                     width: width.round() as int,
                     height: height.round() as int,
                     autoMargins: if auto_margins {
                         //TODO: real values like processMargins in http://mxr.mozilla.org/mozilla-central/source/toolkit/devtools/server/actors/styles.js
-                        let mut m = TreeMap::new();
+                        let mut m = BTreeMap::new();
                         m.insert("top".to_string(), "auto".to_string().to_json());
                         m.insert("bottom".to_string(), "auto".to_string().to_json());
                         m.insert("left".to_string(), "auto".to_string().to_json());
                         m.insert("right".to_string(), "auto".to_string().to_json());
                         Json::Object(m)
                     } else {
                         Json::Null
                     },
@@ -502,18 +506,18 @@ impl Actor for InspectorActor {
                         pipeline: self.pipeline,
                     };
                     let mut walker_name = self.walker.borrow_mut();
                     *walker_name = Some(walker.name());
                     registry.register_later(box walker);
                 }
 
                 let (tx, rx) = channel();
-                self.script_chan.send(GetRootNode(self.pipeline, tx));
-                let root_info = rx.recv();
+                self.script_chan.send(GetRootNode(self.pipeline, tx)).unwrap();
+                let root_info = rx.recv().unwrap();
 
                 let node = root_info.encode(registry, false, self.script_chan.clone(), self.pipeline);
 
                 let msg = GetWalkerReply {
                     from: self.name(),
                     walker: WalkerMsg {
                         actor: self.walker.borrow().clone().unwrap(),
                         root: node,
--- a/servo/components/devtools/actors/root.rs
+++ b/servo/components/devtools/actors/root.rs
@@ -8,38 +8,38 @@
 
 use actor::{Actor, ActorRegistry};
 use actors::tab::{TabActor, TabActorMsg};
 use protocol::JsonPacketStream;
 
 use serialize::json;
 use std::io::TcpStream;
 
-#[deriving(Encodable)]
+#[derive(RustcEncodable)]
 struct ActorTraits {
     sources: bool,
     highlightable: bool,
     customHighlighters: Vec<String>,
 }
 
-#[deriving(Encodable)]
+#[derive(RustcEncodable)]
 struct ErrorReply {
     from: String,
     error: String,
     message: String,
 }
 
-#[deriving(Encodable)]
+#[derive(RustcEncodable)]
 struct ListTabsReply {
     from: String,
     selected: uint,
     tabs: Vec<TabActorMsg>,
 }
 
-#[deriving(Encodable)]
+#[derive(RustcEncodable)]
 struct RootActorMsg {
     from: String,
     applicationType: String,
     traits: ActorTraits,
 }
 
 pub struct RootActor {
     pub tabs: Vec<String>,
--- a/servo/components/devtools/actors/tab.rs
+++ b/servo/components/devtools/actors/tab.rs
@@ -8,55 +8,55 @@
 
 use actor::{Actor, ActorRegistry};
 use actors::console::ConsoleActor;
 use protocol::JsonPacketStream;
 
 use serialize::json;
 use std::io::TcpStream;
 
-#[deriving(Encodable)]
+#[derive(RustcEncodable)]
 struct TabTraits;
 
-#[deriving(Encodable)]
+#[derive(RustcEncodable)]
 struct TabAttachedReply {
     from: String,
     __type__: String,
     threadActor: String,
     cacheDisabled: bool,
     javascriptEnabled: bool,
     traits: TabTraits,
 }
 
-#[deriving(Encodable)]
+#[derive(RustcEncodable)]
 struct TabDetachedReply {
     from: String,
     __type__: String,
 }
 
-#[deriving(Encodable)]
+#[derive(RustcEncodable)]
 struct ReconfigureReply {
     from: String
 }
 
-#[deriving(Encodable)]
+#[derive(RustcEncodable)]
 struct ListFramesReply {
     from: String,
     frames: Vec<FrameMsg>,
 }
 
-#[deriving(Encodable)]
+#[derive(RustcEncodable)]
 struct FrameMsg {
     id: uint,
     url: String,
     title: String,
     parentID: uint,
 }
 
-#[deriving(Encodable)]
+#[derive(RustcEncodable)]
 pub struct TabActorMsg {
     actor: String,
     title: String,
     url: String,
     outerWindowID: uint,
     consoleActor: String,
     inspectorActor: String,
 }
--- a/servo/components/devtools/lib.rs
+++ b/servo/components/devtools/lib.rs
@@ -5,27 +5,29 @@
 //! An actor-based remote devtools server implementation. Only tested with
 //! nightly Firefox versions at time of writing. Largely based on
 //! reverse-engineering of Firefox chrome devtool logs and reading of
 //! [code](http://mxr.mozilla.org/mozilla-central/source/toolkit/devtools/server/).
 
 #![crate_name = "devtools"]
 #![crate_type = "rlib"]
 
+#![feature(int_uint, box_syntax)]
+
 #![allow(non_snake_case)]
 #![allow(missing_copy_implementations)]
+#![allow(unstable)]
 
-#![feature(phase)]
-
-#[phase(plugin, link)]
+#[macro_use]
 extern crate log;
 
 extern crate collections;
 extern crate core;
 extern crate devtools_traits;
+extern crate "serialize" as rustc_serialize;
 extern crate serialize;
 extern crate "msg" as servo_msg;
 extern crate "util" as servo_util;
 
 use actor::{Actor, ActorRegistry};
 use actors::console::ConsoleActor;
 use actors::inspector::InspectorActor;
 use actors::root::RootActor;
@@ -34,36 +36,36 @@ use protocol::JsonPacketStream;
 
 use devtools_traits::{ServerExitMsg, DevtoolsControlMsg, NewGlobal, DevtoolScriptControlMsg, DevtoolsPageInfo};
 use servo_msg::constellation_msg::PipelineId;
 use servo_util::task::spawn_named;
 
 use std::borrow::ToOwned;
 use std::cell::RefCell;
 use std::collections::HashMap;
-use std::comm;
-use std::comm::{Disconnected, Empty};
+use std::sync::mpsc::{channel, Receiver, Sender};
+use std::sync::mpsc::TryRecvError::{Disconnected, Empty};
 use std::io::{TcpListener, TcpStream};
 use std::io::{Acceptor, Listener, TimedOut};
 use std::sync::{Arc, Mutex};
 
 mod actor;
 /// Corresponds to http://mxr.mozilla.org/mozilla-central/source/toolkit/devtools/server/actors/
 mod actors {
     pub mod console;
     pub mod inspector;
     pub mod root;
     pub mod tab;
 }
 mod protocol;
 
 /// Spin up a devtools server that listens for connections on the specified port.
 pub fn start_server(port: u16) -> Sender<DevtoolsControlMsg> {
-    let (sender, receiver) = comm::channel();
-    spawn_named("Devtools".to_owned(), proc() {
+    let (sender, receiver) = channel();
+    spawn_named("Devtools".to_owned(), move || {
         run_server(receiver, port)
     });
     sender
 }
 
 static POLL_TIMEOUT: u64 = 300;
 
 fn run_server(receiver: Receiver<DevtoolsControlMsg>, port: u16) {
@@ -87,26 +89,27 @@ fn run_server(receiver: Receiver<Devtool
     let mut accepted_connections: Vec<TcpStream> = Vec::new();
 
     let mut actor_pipelines: HashMap<PipelineId, String> = HashMap::new();
 
     /// Process the input from a single devtools client until EOF.
     fn handle_client(actors: Arc<Mutex<ActorRegistry>>, mut stream: TcpStream) {
         println!("connection established to {}", stream.peer_name().unwrap());
         {
-            let actors = actors.lock();
+            let actors = actors.lock().unwrap();
             let msg = actors.find::<RootActor>("root").encodable();
             stream.write_json_packet(&msg);
         }
 
         'outer: loop {
             match stream.read_json_packet() {
                 Ok(json_packet) => {
-                    match actors.lock().handle_message(json_packet.as_object().unwrap(),
-                                                       &mut stream) {
+                    let mut actors = actors.lock().unwrap();
+                    match actors.handle_message(json_packet.as_object().unwrap(),
+                                                &mut stream) {
                         Ok(()) => {},
                         Err(()) => {
                             println!("error: devtools actor stopped responding");
                             let _ = stream.close_read();
                             let _ = stream.close_write();
                             break 'outer
                         }
                     }
@@ -122,17 +125,17 @@ fn run_server(receiver: Receiver<Devtool
     // We need separate actor representations for each script global that exists;
     // clients can theoretically connect to multiple globals simultaneously.
     // TODO: move this into the root or tab modules?
     fn handle_new_global(actors: Arc<Mutex<ActorRegistry>>,
                          pipeline: PipelineId,
                          sender: Sender<DevtoolScriptControlMsg>,
                          actor_pipelines: &mut HashMap<PipelineId, String>,
                          page_info: DevtoolsPageInfo) {
-        let mut actors = actors.lock();
+        let mut actors = actors.lock().unwrap();
 
         //TODO: move all this actor creation into a constructor method on TabActor
         let (tab, console, inspector) = {
             let console = ConsoleActor {
                 name: actors.new_name("console"),
                 script_chan: sender.clone(),
                 pipeline: pipeline,
                 streams: RefCell::new(Vec::new()),
@@ -180,17 +183,17 @@ fn run_server(receiver: Receiver<Devtool
                     Ok(NewGlobal(id, sender, pageinfo)) => handle_new_global(actors.clone(), id, sender, &mut actor_pipelines, pageinfo),
                     Err(Empty) => acceptor.set_timeout(Some(POLL_TIMEOUT)),
                 }
             }
             Err(_e) => { /* connection failed */ }
             Ok(stream) => {
                 let actors = actors.clone();
                 accepted_connections.push(stream.clone());
-                spawn_named("DevtoolsClientHandler".to_owned(), proc() {
+                spawn_named("DevtoolsClientHandler".to_owned(), move || {
                     // connection succeeded
                     handle_client(actors, stream.clone())
                 })
             }
         }
     }
 
     for connection in accepted_connections.iter_mut() {
--- a/servo/components/devtools/protocol.rs
+++ b/servo/components/devtools/protocol.rs
@@ -7,22 +7,22 @@
 //! (https://wiki.mozilla.org/Remote_Debugging_Protocol_Stream_Transport#JSON_Packets).
 
 use serialize::{json, Encodable};
 use serialize::json::Json;
 use std::io::{IoError, OtherIoError, EndOfFile, TcpStream, IoResult};
 use std::num;
 
 pub trait JsonPacketStream {
-    fn write_json_packet<'a, T: Encodable<json::Encoder<'a>,IoError>>(&mut self, obj: &T);
+    fn write_json_packet<'a, T: Encodable>(&mut self, obj: &T);
     fn read_json_packet(&mut self) -> IoResult<Json>;
 }
 
 impl JsonPacketStream for TcpStream {
-    fn write_json_packet<'a, T: Encodable<json::Encoder<'a>,IoError>>(&mut self, obj: &T) {
+    fn write_json_packet<'a, T: Encodable>(&mut self, obj: &T) {
         let s = json::encode(obj).replace("__type__", "type");
         println!("<- {}", s);
         self.write_str(s.len().to_string().as_slice()).unwrap();
         self.write_u8(':' as u8).unwrap();
         self.write_str(s.as_slice()).unwrap();
     }
 
     fn read_json_packet<'a>(&mut self) -> IoResult<Json> {
--- a/servo/components/devtools_traits/lib.rs
+++ b/servo/components/devtools_traits/lib.rs
@@ -4,34 +4,37 @@
 
 //! This module contains shared types and messages for use by devtools/script.
 //! The traits are here instead of in script so that the devtools crate can be
 //! modified independently of the rest of Servo.
 
 #![crate_name = "devtools_traits"]
 #![crate_type = "rlib"]
 
+#![feature(int_uint)]
+
 #![allow(non_snake_case)]
 #![allow(missing_copy_implementations)]
-#![feature(globs)]
 
 extern crate "msg" as servo_msg;
 extern crate serialize;
 extern crate url;
 extern crate "util" as servo_util;
 
 pub use self::DevtoolsControlMsg::*;
 pub use self::DevtoolScriptControlMsg::*;
 pub use self::EvaluateJSReply::*;
 
 use serialize::{Decodable, Decoder};
 use servo_msg::constellation_msg::PipelineId;
 use servo_util::str::DOMString;
 use url::Url;
 
+use std::sync::mpsc::{Sender, Receiver};
+
 pub type DevtoolsControlChan = Sender<DevtoolsControlMsg>;
 pub type DevtoolsControlPort = Receiver<DevtoolScriptControlMsg>;
 
 // Information would be attached to NewGlobal to be received and show in devtools.
 // Extend these fields if we need more information.
 pub struct DevtoolsPageInfo {
     pub title: DOMString,
     pub url: Url
@@ -94,24 +97,24 @@ pub enum DevtoolScriptControlMsg {
 
 /// Messages to instruct devtools server to update its state relating to a particular
 /// tab.
 pub enum ScriptDevtoolControlMsg {
     /// Report a new JS error message
     ReportConsoleMsg(String),
 }
 
-#[deriving(Encodable)]
+#[derive(Encodable)]
 pub struct Modification{
     pub attributeName: String,
     pub newValue: Option<String>,
 }
 
-impl<D:Decoder<E>, E> Decodable<D, E> for Modification {
-    fn decode(d: &mut D) -> Result<Modification, E> {
+impl Decodable for Modification {
+    fn decode<D: Decoder>(d: &mut D) -> Result<Modification, D::Error> {
         d.read_struct("Modification", 2u, |d|
             Ok(Modification {
                 attributeName: try!(d.read_struct_field("attributeName", 0u, |d| Decodable::decode(d))),
                 newValue: match d.read_struct_field("newValue", 1u, |d| Decodable::decode(d)) {
                     Ok(opt) => opt,
                     Err(_) => None
                 }
             })
--- a/servo/components/gfx/Cargo.toml
+++ b/servo/components/gfx/Cargo.toml
@@ -33,19 +33,16 @@ git = "https://github.com/servo/rust-geo
 git = "https://github.com/servo/rust-layers"
 
 [dependencies.stb_image]
 git = "https://github.com/servo/rust-stb-image"
 
 [dependencies.png]
 git = "https://github.com/servo/rust-png"
 
-[dependencies.url]
-git = "https://github.com/servo/rust-url"
-
 [dependencies.harfbuzz]
 git = "https://github.com/servo/rust-harfbuzz"
 
 [dependencies.fontconfig]
 git = "https://github.com/servo/rust-fontconfig"
 
 [dependencies.freetype]
 git = "https://github.com/servo/rust-freetype"
@@ -57,10 +54,11 @@ git = "https://github.com/servo/rust-cor
 git = "https://github.com/servo/rust-core-graphics"
 
 [dependencies.core_text]
 git = "https://github.com/servo/rust-core-text"
 
 [dependencies.script_traits]
 path = "../script_traits"
 
-[dependencies.time]
-git = "https://github.com/rust-lang/time"
+[dependencies]
+url = "*"
+time = "*"
\ No newline at end of file
--- a/servo/components/gfx/buffer_map.rs
+++ b/servo/components/gfx/buffer_map.rs
@@ -1,19 +1,18 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 use std::collections::HashMap;
-use std::collections::hash_map::{Occupied, Vacant};
+use std::collections::hash_map::Entry::{Occupied, Vacant};
 use geom::size::Size2D;
 use layers::platform::surface::NativePaintingGraphicsContext;
 use layers::layers::LayerBuffer;
-use std::hash::Hash;
-use std::hash::sip::SipState;
+use std::hash::{Hash, Hasher, Writer};
 use std::mem;
 
 /// This is a struct used to store buffers when they are not in use.
 /// The paint task can quickly query for a particular size of buffer when it
 /// needs it.
 pub struct BufferMap {
     /// A HashMap that stores the Buffers.
     map: HashMap<BufferKey, BufferValue>,
@@ -22,21 +21,21 @@ pub struct BufferMap {
     /// The maximum allowed memory. Unused buffers will be deleted
     /// when this threshold is exceeded.
     max_mem: uint,
     /// A monotonically increasing counter to track how recently tile sizes were used.
     counter: uint,
 }
 
 /// A key with which to store buffers. It is based on the size of the buffer.
-#[deriving(Eq, Copy)]
-struct BufferKey([uint, ..2]);
+#[derive(Eq, Copy)]
+struct BufferKey([uint; 2]);
 
-impl Hash for BufferKey {
-    fn hash(&self, state: &mut SipState) {
+impl<H: Hasher+Writer> Hash<H> for BufferKey {
+    fn hash(&self, state: &mut H) {
         let BufferKey(ref bytes) = *self;
         bytes.as_slice().hash(state);
     }
 }
 
 impl PartialEq for BufferKey {
     fn eq(&self, other: &BufferKey) -> bool {
         let BufferKey(s) = *self;
@@ -86,17 +85,17 @@ impl BufferMap {
         self.mem += new_buffer.get_mem();
         // use lazy insertion function to prevent unnecessary allocation
         let counter = &self.counter;
         match self.map.entry(new_key) {
             Occupied(entry) => {
                 entry.into_mut().buffers.push(new_buffer);
             }
             Vacant(entry) => {
-                entry.set(BufferValue {
+                entry.insert(BufferValue {
                     buffers: vec!(new_buffer),
                     last_action: *counter,
                 });
             }
         }
 
         let mut opt_key: Option<BufferKey> = None;
         while self.mem > self.max_mem {
--- a/servo/components/gfx/display_list/mod.rs
+++ b/servo/components/gfx/display_list/mod.rs
@@ -33,17 +33,17 @@ use paint_task::PaintLayer;
 use servo_msg::compositor_msg::LayerId;
 use servo_net::image::base::Image;
 use servo_util::cursor::Cursor;
 use servo_util::dlist as servo_dlist;
 use servo_util::geometry::{mod, Au, MAX_RECT, ZERO_RECT};
 use servo_util::range::Range;
 use servo_util::smallvec::{SmallVec, SmallVec8};
 use std::fmt;
-use std::slice::Items;
+use std::slice::Iter;
 use std::sync::Arc;
 use style::ComputedValues;
 use style::computed_values::{border_style, cursor, filter, mix_blend_mode, pointer_events};
 
 // It seems cleaner to have layout code not mention Azure directly, so let's just reexport this for
 // layout to use.
 pub use azure::azure_hl::GradientStop;
 
@@ -55,17 +55,17 @@ pub mod optimizer;
 pub static BOX_SHADOW_INFLATION_FACTOR: i32 = 3;
 
 /// An opaque handle to a node. The only safe operation that can be performed on this node is to
 /// compare it to another opaque handle or to another node.
 ///
 /// Because the script task's GC does not trace layout, node data cannot be safely stored in layout
 /// data structures. Also, layout code tends to be faster when the DOM is not being accessed, for
 /// locality reasons. Using `OpaqueNode` enforces this invariant.
-#[deriving(Clone, PartialEq, Copy)]
+#[derive(Clone, PartialEq, Copy)]
 pub struct OpaqueNode(pub uintptr_t);
 
 impl OpaqueNode {
     /// Returns the address of this node, for debugging purposes.
     pub fn id(&self) -> uintptr_t {
         let OpaqueNode(pointer) = *self;
         pointer
     }
@@ -351,17 +351,17 @@ impl StackingContext {
     pub fn hit_test(&self,
                     point: Point2D<Au>,
                     result: &mut Vec<DisplayItemMetadata>,
                     topmost_only: bool) {
         fn hit_test_in_list<'a,I>(point: Point2D<Au>,
                                   result: &mut Vec<DisplayItemMetadata>,
                                   topmost_only: bool,
                                   mut iterator: I)
-                                  where I: Iterator<&'a DisplayItem> {
+                                  where I: Iterator<Item=&'a DisplayItem> {
             for item in iterator {
                 // TODO(pcwalton): Use a precise algorithm here. This will allow us to properly hit
                 // test elements with `border-radius`, for example.
                 if !item.base().clip.might_intersect_point(&point) {
                     // Clipped out.
                     continue
                 }
                 if !geometry::rect_contains_point(item.bounds(), point) {
@@ -468,29 +468,29 @@ pub fn find_stacking_context_with_layer_
             None => {}
         }
     }
 
     None
 }
 
 /// One drawing command in the list.
-#[deriving(Clone)]
+#[derive(Clone)]
 pub enum DisplayItem {
     SolidColorClass(Box<SolidColorDisplayItem>),
     TextClass(Box<TextDisplayItem>),
     ImageClass(Box<ImageDisplayItem>),
     BorderClass(Box<BorderDisplayItem>),
     GradientClass(Box<GradientDisplayItem>),
     LineClass(Box<LineDisplayItem>),
     BoxShadowClass(Box<BoxShadowDisplayItem>),
 }
 
 /// Information common to all display items.
-#[deriving(Clone)]
+#[derive(Clone)]
 pub struct BaseDisplayItem {
     /// The boundaries of the display item, in layer coordinates.
     pub bounds: Rect<Au>,
 
     /// Metadata attached to this display item.
     pub metadata: DisplayItemMetadata,
 
     /// The region to clip to.
@@ -507,31 +507,31 @@ impl BaseDisplayItem {
             clip: clip,
         }
     }
 }
 
 /// A clipping region for a display item. Currently, this can describe rectangles, rounded
 /// rectangles (for `border-radius`), or arbitrary intersections of the two. Arbitrary transforms
 /// are not supported because those are handled by the higher-level `StackingContext` abstraction.
-#[deriving(Clone, PartialEq, Show)]
+#[derive(Clone, PartialEq, Show)]
 pub struct ClippingRegion {
     /// The main rectangular region. This does not include any corners.
     pub main: Rect<Au>,
     /// Any complex regions.
     ///
     /// TODO(pcwalton): Atomically reference count these? Not sure if it's worth the trouble.
     /// Measure and follow up.
     pub complex: Vec<ComplexClippingRegion>,
 }
 
 /// A complex clipping region. These don't as easily admit arbitrary intersection operations, so
 /// they're stored in a list over to the side. Currently a complex clipping region is just a
 /// rounded rectangle, but the CSS WGs will probably make us throw more stuff in here eventually.
-#[deriving(Clone, PartialEq, Show)]
+#[derive(Clone, PartialEq, Show)]
 pub struct ComplexClippingRegion {
     /// The boundaries of the rectangle.
     pub rect: Rect<Au>,
     /// Border radii of this rectangle.
     pub radii: BorderRadii<Au>,
 }
 
 impl ClippingRegion {
@@ -632,17 +632,17 @@ impl ClippingRegion {
             }).collect(),
         }
     }
 }
 
 /// Metadata attached to each display item. This is useful for performing auxiliary tasks with
 /// the display list involving hit testing: finding the originating DOM node and determining the
 /// cursor to use when the element is hovered over.
-#[deriving(Clone, Copy)]
+#[derive(Clone, Copy)]
 pub struct DisplayItemMetadata {
     /// The DOM node from which this display item originated.
     pub node: OpaqueNode,
     /// The value of the `cursor` property when the mouse hovers over this display item. If `None`,
     /// this display item is ineligible for pointer events (`pointer-events: none`).
     pub pointing: Option<Cursor>,
 }
 
@@ -661,24 +661,24 @@ impl DisplayItemMetadata {
                 (pointer_events::T::auto, cursor::T::AutoCursor) => Some(default_cursor),
                 (pointer_events::T::auto, cursor::T::SpecifiedCursor(cursor)) => Some(cursor),
             },
         }
     }
 }
 
 /// Paints a solid color.
-#[deriving(Clone)]
+#[derive(Clone)]
 pub struct SolidColorDisplayItem {
     pub base: BaseDisplayItem,
     pub color: Color,
 }
 
 /// Paints text.
-#[deriving(Clone)]
+#[derive(Clone)]
 pub struct TextDisplayItem {
     /// Fields common to all display items.
     pub base: BaseDisplayItem,
 
     /// The text run.
     pub text_run: Arc<Box<TextRun>>,
 
     /// The range of text within the text run.
@@ -686,53 +686,53 @@ pub struct TextDisplayItem {
 
     /// The color of the text.
     pub text_color: Color,
 
     pub baseline_origin: Point2D<Au>,
     pub orientation: TextOrientation,
 }
 
-#[deriving(Clone, Eq, PartialEq)]
+#[derive(Clone, Eq, PartialEq)]
 pub enum TextOrientation {
     Upright,
     SidewaysLeft,
     SidewaysRight,
 }
 
 /// Paints an image.
-#[deriving(Clone)]
+#[derive(Clone)]
 pub struct ImageDisplayItem {
     pub base: BaseDisplayItem,
     pub image: Arc<Box<Image>>,
 
     /// The dimensions to which the image display item should be stretched. If this is smaller than
     /// the bounds of this display item, then the image will be repeated in the appropriate
     /// direction to tile the entire bounds.
     pub stretch_size: Size2D<Au>,
 }
 
 /// Paints a gradient.
-#[deriving(Clone)]
+#[derive(Clone)]
 pub struct GradientDisplayItem {
     /// Fields common to all display items.
     pub base: BaseDisplayItem,
 
     /// The start point of the gradient (computed during display list construction).
     pub start_point: Point2D<Au>,
 
     /// The end point of the gradient (computed during display list construction).
     pub end_point: Point2D<Au>,
 
     /// A list of color stops.
     pub stops: Vec<GradientStop>,
 }
 
 /// Paints a border.
-#[deriving(Clone)]
+#[derive(Clone)]
 pub struct BorderDisplayItem {
     /// Fields common to all display items.
     pub base: BaseDisplayItem,
 
     /// Border widths.
     pub border_widths: SideOffsets2D<Au>,
 
     /// Border colors.
@@ -745,17 +745,17 @@ pub struct BorderDisplayItem {
     ///
     /// TODO(pcwalton): Elliptical radii.
     pub radius: BorderRadii<Au>,
 }
 
 /// Information about the border radii.
 ///
 /// TODO(pcwalton): Elliptical radii.
-#[deriving(Clone, Default, PartialEq, Show, Copy)]
+#[derive(Clone, Default, PartialEq, Show, Copy)]
 pub struct BorderRadii<T> {
     pub top_left: T,
     pub top_right: T,
     pub bottom_right: T,
     pub bottom_left: T,
 }
 
 impl<T> BorderRadii<T> where T: PartialEq + Zero {
@@ -763,29 +763,29 @@ impl<T> BorderRadii<T> where T: PartialE
     pub fn is_square(&self) -> bool {
         let zero = Zero::zero();
         self.top_left == zero && self.top_right == zero && self.bottom_right == zero &&
             self.bottom_left == zero
     }
 }
 
 /// Paints a line segment.
-#[deriving(Clone)]
+#[derive(Clone)]
 pub struct LineDisplayItem {
     pub base: BaseDisplayItem,
 
     /// The line segment color.
     pub color: Color,
 
     /// The line segment style.
     pub style: border_style::T
 }
 
 /// Paints a box shadow per CSS-BACKGROUNDS.
-#[deriving(Clone)]
+#[derive(Clone)]
 pub struct BoxShadowDisplayItem {
     /// Fields common to all display items.
     pub base: BaseDisplayItem,
 
     /// The dimensions of the box that we're placing a shadow around.
     pub box_bounds: Rect<Au>,
 
     /// The offset of this shadow from the box.
@@ -801,20 +801,21 @@ pub struct BoxShadowDisplayItem {
     pub spread_radius: Au,
 
     /// True if this shadow is inset; false if it's outset.
     pub inset: bool,
 }
 
 pub enum DisplayItemIterator<'a> {
     Empty,
-    Parent(dlist::Items<'a,DisplayItem>),
+    Parent(dlist::Iter<'a,DisplayItem>),
 }
 
-impl<'a> Iterator<&'a DisplayItem> for DisplayItemIterator<'a> {
+impl<'a> Iterator for DisplayItemIterator<'a> {
+    type Item = &'a DisplayItem;
     #[inline]
     fn next(&mut self) -> Option<&'a DisplayItem> {
         match *self {
             DisplayItemIterator::Empty => None,
             DisplayItemIterator::Parent(ref mut subiterator) => subiterator.next(),
         }
     }
 }
@@ -831,24 +832,24 @@ impl DisplayItem {
         }
 
         match *self {
             DisplayItem::SolidColorClass(ref solid_color) => {
                 paint_context.draw_solid_color(&solid_color.base.bounds, solid_color.color)
             }
 
             DisplayItem::TextClass(ref text) => {
-                debug!("Drawing text at {}.", text.base.bounds);
+                debug!("Drawing text at {:?}.", text.base.bounds);
                 paint_context.draw_text(&**text);
             }
 
             DisplayItem::ImageClass(ref image_item) => {
                 // FIXME(pcwalton): This is a really inefficient way to draw a tiled image; use a
                 // brush instead.
-                debug!("Drawing image at {}.", image_item.base.bounds);
+                debug!("Drawing image at {:?}.", image_item.base.bounds);
 
                 let mut y_offset = Au(0);
                 while y_offset < image_item.base.bounds.size.height {
                     let mut x_offset = Au(0);
                     while x_offset < image_item.base.bounds.size.width {
                         let mut bounds = image_item.base.bounds;
                         bounds.origin.x = bounds.origin.x + x_offset;
                         bounds.origin.y = bounds.origin.y + y_offset;
@@ -921,23 +922,23 @@ impl DisplayItem {
         self.base().bounds
     }
 
     pub fn debug_with_level(&self, level: uint) {
         let mut indent = String::new();
         for _ in range(0, level) {
             indent.push_str("| ")
         }
-        println!("{}+ {}", indent, self);
+        println!("{}+ {:?}", indent, self);
     }
 }
 
 impl fmt::Show for DisplayItem {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "{} @ {} ({:x})",
+        write!(f, "{} @ {:?} ({:x})",
             match *self {
                 DisplayItem::SolidColorClass(_) => "SolidColor",
                 DisplayItem::TextClass(_) => "Text",
                 DisplayItem::ImageClass(_) => "Image",
                 DisplayItem::BorderClass(_) => "Border",
                 DisplayItem::GradientClass(_) => "Gradient",
                 DisplayItem::LineClass(_) => "Line",
                 DisplayItem::BoxShadowClass(_) => "BoxShadow",
--- a/servo/components/gfx/display_list/optimizer.rs
+++ b/servo/components/gfx/display_list/optimizer.rs
@@ -39,30 +39,30 @@ impl DisplayListOptimizer {
         self.add_in_bounds_stacking_contexts(&mut result.children, display_list.children.iter());
         result
     }
 
     /// Adds display items that intersect the visible rect to `result_list`.
     fn add_in_bounds_display_items<'a,I>(&self,
                                          result_list: &mut DList<DisplayItem>,
                                          mut display_items: I)
-                                         where I: Iterator<&'a DisplayItem> {
+                                         where I: Iterator<Item=&'a DisplayItem> {
         for display_item in display_items {
             if self.visible_rect.intersects(&display_item.base().bounds) &&
                     display_item.base().clip.might_intersect_rect(&self.visible_rect) {
                 result_list.push_back((*display_item).clone())
             }
         }
     }
 
     /// Adds child stacking contexts whose boundaries intersect the visible rect to `result_list`.
     fn add_in_bounds_stacking_contexts<'a,I>(&self,
                                              result_list: &mut DList<Arc<StackingContext>>,
                                              mut stacking_contexts: I)
-                                             where I: Iterator<&'a Arc<StackingContext>> {
+                                             where I: Iterator<Item=&'a Arc<StackingContext>> {
         for stacking_context in stacking_contexts {
             let overflow = stacking_context.overflow.translate(&stacking_context.bounds.origin);
             if self.visible_rect.intersects(&overflow) {
                 result_list.push_back((*stacking_context).clone())
             }
         }
     }
 }
--- a/servo/components/gfx/filters.rs
+++ b/servo/components/gfx/filters.rs
@@ -4,17 +4,17 @@
 
 //! CSS and SVG filter support.
 
 use azure::AzFloat;
 use azure::azure_hl::{ColorMatrixAttribute, ColorMatrixInput, CompositeInput, DrawTarget};
 use azure::azure_hl::{FilterNode, FilterType, LinearTransferAttribute, LinearTransferInput};
 use azure::azure_hl::{Matrix5x4, TableTransferAttribute, TableTransferInput};
 
-use std::num::FloatMath;
+use std::num::Float;
 use style::computed_values::filter;
 
 /// Creates a filter pipeline from a set of CSS filters. Returns the destination end of the filter
 /// pipeline and the opacity.
 pub fn create_filters(draw_target: &DrawTarget,
                       temporary_draw_target: &DrawTarget,
                       style_filters: &filter::T)
                       -> (FilterNode, AzFloat) {
--- a/servo/components/gfx/font.rs
+++ b/servo/components/gfx/font.rs
@@ -3,23 +3,23 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 use geom::{Point2D, Rect, Size2D};
 use std::borrow::ToOwned;
 use std::mem;
 use std::slice;
 use std::rc::Rc;
 use std::cell::RefCell;
-use servo_util::cache::{Cache, HashCache};
+use servo_util::cache::HashCache;
 use servo_util::smallvec::{SmallVec, SmallVec8};
 use style::computed_values::{font_variant, font_weight};
 use style::style_structs::Font as FontStyle;
 use std::sync::Arc;
 
-use collections::hash::Hash;
+use std::hash::Hash;
 use platform::font_context::FontContextHandle;
 use platform::font::{FontHandle, FontTable};
 use servo_util::geometry::Au;
 use text::glyph::{GlyphStore, GlyphId};
 use text::shaping::ShaperMethods;
 use text::{Shaper, TextRun};
 use font_template::FontTemplateDescriptor;
 use platform::font_template::FontTemplateData;
@@ -61,20 +61,20 @@ impl FontTableTagConversions for FontTab
             let mut bytes = slice::from_raw_buf(&pointer, 4).to_vec();
             bytes.reverse();
             String::from_utf8_unchecked(bytes)
         }
     }
 }
 
 pub trait FontTableMethods {
-    fn with_buffer(&self, |*const u8, uint|);
+    fn with_buffer<F>(&self, F) where F: FnOnce(*const u8, uint);
 }
 
-#[deriving(Clone, Show)]
+#[derive(Clone, Show)]
 pub struct FontMetrics {
     pub underline_size:   Au,
     pub underline_offset: Au,
     pub strikeout_size:   Au,
     pub strikeout_offset: Au,
     pub leading:          Au,
     pub x_height:         Au,
     pub em_size:          Au,
@@ -96,70 +96,58 @@ pub struct Font {
     pub requested_pt_size: Au,
     pub actual_pt_size: Au,
     pub shaper: Option<Shaper>,
     pub shape_cache: HashCache<ShapeCacheEntry,Arc<GlyphStore>>,
     pub glyph_advance_cache: HashCache<u32,FractionalPixel>,
 }
 
 bitflags! {
-    #[deriving(Copy)]
     flags ShapingFlags: u8 {
         #[doc="Set if the text is entirely whitespace."]
         const IS_WHITESPACE_SHAPING_FLAG = 0x01,
         #[doc="Set if we are to ignore ligatures."]
         const IGNORE_LIGATURES_SHAPING_FLAG = 0x02,
         #[doc="Set if we are to disable kerning."]
         const DISABLE_KERNING_SHAPING_FLAG = 0x04
     }
 }
 
 /// Various options that control text shaping.
-#[deriving(Clone, Eq, PartialEq, Hash, Copy)]
+#[derive(Clone, Eq, PartialEq, Hash, Copy)]
 pub struct ShapingOptions {
     /// Spacing to add between each letter. Corresponds to the CSS 2.1 `letter-spacing` property.
     /// NB: You will probably want to set the `IGNORE_LIGATURES_SHAPING_FLAG` if this is non-null.
     pub letter_spacing: Option<Au>,
     /// Spacing to add between each word. Corresponds to the CSS 2.1 `word-spacing` property.
     pub word_spacing: Au,
     /// Various flags.
     pub flags: ShapingFlags,
 }
 
 /// An entry in the shape cache.
-#[deriving(Clone, Eq, PartialEq, Hash)]
+#[derive(Clone, Eq, PartialEq, Hash)]
 pub struct ShapeCacheEntry {
     text: String,
     options: ShapingOptions,
 }
 
-#[deriving(Clone, Eq, PartialEq, Hash)]
-struct ShapeCacheEntryRef<'a> {
-    text: &'a str,
-    options: &'a ShapingOptions,
-}
-
-impl<'a> Equiv<ShapeCacheEntry> for ShapeCacheEntryRef<'a> {
-    fn equiv(&self, other: &ShapeCacheEntry) -> bool {
-        self.text == other.text.as_slice() && *self.options == other.options
-    }
-}
-
 impl Font {
     pub fn shape_text(&mut self, text: &str, options: &ShapingOptions) -> Arc<GlyphStore> {
         self.make_shaper(options);
 
+        //FIXME: find the equivalent of Equiv and the old ShapeCacheEntryRef
         let shaper = &self.shaper;
-        let lookup_key = ShapeCacheEntryRef {
-            text: text,
-            options: options,
+        let lookup_key = ShapeCacheEntry {
+            text: text.to_owned(),
+            options: options.clone(),
         };
-        match self.shape_cache.find_equiv(&lookup_key) {
+        match self.shape_cache.find(&lookup_key) {
             None => {}
-            Some(glyphs) => return (*glyphs).clone(),
+            Some(glyphs) => return glyphs.clone(),
         }
 
         let mut glyphs = GlyphStore::new(text.chars().count() as int,
                                          options.flags.contains(IS_WHITESPACE_SHAPING_FLAG));
         shaper.as_ref().unwrap().shape_text(text, options, &mut glyphs);
 
         let glyphs = Arc::new(glyphs);
         self.shape_cache.insert(ShapeCacheEntry {
--- a/servo/components/gfx/font_cache_task.rs
+++ b/servo/components/gfx/font_cache_task.rs
@@ -7,16 +7,17 @@ use platform::font_list::get_system_defa
 use platform::font_list::get_variations_for_family;
 use platform::font_list::get_last_resort_font_families;
 use platform::font_context::FontContextHandle;
 
 use collections::str::Str;
 use std::borrow::ToOwned;
 use std::collections::HashMap;
 use std::sync::Arc;
+use std::sync::mpsc::{Sender, Receiver, channel};
 use font_template::{FontTemplate, FontTemplateDescriptor};
 use platform::font_template::FontTemplateData;
 use servo_net::resource_task::{ResourceTask, load_whole_resource};
 use servo_util::task::spawn_named;
 use servo_util::str::LowercaseString;
 use style::Source;
 
 /// A list of font templates that make up a given font family.
@@ -75,21 +76,25 @@ impl FontFamily {
 /// Commands that the FontContext sends to the font cache task.
 pub enum Command {
     GetFontTemplate(String, FontTemplateDescriptor, Sender<Reply>),
     GetLastResortFontTemplate(FontTemplateDescriptor, Sender<Reply>),
     AddWebFont(String, Source, Sender<()>),
     Exit(Sender<()>),
 }
 
+unsafe impl Send for Command {}
+
 /// Reply messages sent from the font cache task to the FontContext caller.
 pub enum Reply {
     GetFontTemplateReply(Option<Arc<FontTemplateData>>),
 }
 
+unsafe impl Send for Reply {}
+
 /// The font cache task itself. It maintains a list of reference counted
 /// font templates that are currently in use.
 struct FontCache {
     port: Receiver<Command>,
     generic_fonts: HashMap<LowercaseString, LowercaseString>,
     local_families: HashMap<LowercaseString, FontFamily>,
     web_families: HashMap<LowercaseString, FontFamily>,
     font_context: FontContextHandle,
@@ -104,17 +109,17 @@ fn add_generic_font(generic_fonts: &mut 
         None => LowercaseString::new(mapped_name),
     };
     generic_fonts.insert(LowercaseString::new(generic_name), family_name);
 }
 
 impl FontCache {
     fn run(&mut self) {
         loop {
-            let msg = self.port.recv();
+            let msg = self.port.recv().unwrap();
 
             match msg {
                 Command::GetFontTemplate(family, descriptor, result) => {
                     let family = LowercaseString::new(family.as_slice());
                     let maybe_font_template = self.get_font_template(&family, &descriptor);
                     result.send(Reply::GetFontTemplateReply(maybe_font_template));
                 }
                 Command::GetLastResortFontTemplate(descriptor, result) => {
@@ -133,23 +138,23 @@ impl FontCache {
                             let url = &url_source.url;
                             let maybe_resource = load_whole_resource(&self.resource_task, url.clone());
                             match maybe_resource {
                                 Ok((_, bytes)) => {
                                     let family = &mut self.web_families[family_name];
                                     family.add_template(url.to_string().as_slice(), Some(bytes));
                                 },
                                 Err(_) => {
-                                    debug!("Failed to load web font: family={} url={}", family_name, url);
+                                    debug!("Failed to load web font: family={:?} url={}", family_name, url);
                                 }
                             }
                         }
                         Source::Local(ref local_family_name) => {
                             let family = &mut self.web_families[family_name];
-                            get_variations_for_family(local_family_name.as_slice(), |path| {
+                            get_variations_for_family(local_family_name.as_slice(), |&mut:path| {
                                 family.add_template(path.as_slice(), None);
                             });
                         }
                     }
                     result.send(());
                 }
                 Command::Exit(result) => {
                     result.send(());
@@ -181,17 +186,17 @@ impl FontCache {
                                 -> Option<Arc<FontTemplateData>> {
         // TODO(Issue #188): look up localized font family names if canonical name not found
         // look up canonical name
         if self.local_families.contains_key(family_name) {
             debug!("FontList: Found font family with name={}", family_name.as_slice());
             let s = &mut self.local_families[*family_name];
 
             if s.templates.len() == 0 {
-                get_variations_for_family(family_name.as_slice(), |path| {
+                get_variations_for_family(family_name.as_slice(), |&mut:path| {
                     s.add_template(path.as_slice(), None);
                 });
             }
 
             // TODO(Issue #192: handle generic font families, like 'serif' and 'sans-serif'.
             // if such family exists, try to match style to a font
             let result = s.find_font_for_style(desc, &self.font_context);
             if result.is_some() {
@@ -239,26 +244,26 @@ impl FontCache {
         }
 
         panic!("Unable to find any fonts that match (do you have fallback fonts installed?)");
     }
 }
 
 /// The public interface to the font cache task, used exclusively by
 /// the per-thread/task FontContext structures.
-#[deriving(Clone)]
+#[derive(Clone)]
 pub struct FontCacheTask {
     chan: Sender<Command>,
 }
 
 impl FontCacheTask {
     pub fn new(resource_task: ResourceTask) -> FontCacheTask {
         let (chan, port) = channel();
 
-        spawn_named("FontCacheTask".to_owned(), proc() {
+        spawn_named("FontCacheTask".to_owned(), move || {
             // TODO: Allow users to specify these.
             let mut generic_fonts = HashMap::with_capacity(5);
             add_generic_font(&mut generic_fonts, "serif", "Times New Roman");
             add_generic_font(&mut generic_fonts, "sans-serif", "Arial");
             add_generic_font(&mut generic_fonts, "cursive", "Apple Chancery");
             add_generic_font(&mut generic_fonts, "fantasy", "Papyrus");
             add_generic_font(&mut generic_fonts, "monospace", "Menlo");
 
@@ -281,32 +286,32 @@ impl FontCacheTask {
     }
 
     pub fn get_font_template(&self, family: String, desc: FontTemplateDescriptor)
                                                 -> Option<Arc<FontTemplateData>> {
 
         let (response_chan, response_port) = channel();
         self.chan.send(Command::GetFontTemplate(family, desc, response_chan));
 
-        let reply = response_port.recv();
+        let reply = response_port.recv().unwrap();
 
         match reply {
             Reply::GetFontTemplateReply(data) => {
                 data
             }
         }
     }
 
     pub fn get_last_resort_font_template(&self, desc: FontTemplateDescriptor)
                                                 -> Arc<FontTemplateData> {
 
         let (response_chan, response_port) = channel();
         self.chan.send(Command::GetLastResortFontTemplate(desc, response_chan));
 
-        let reply = response_port.recv();
+        let reply = response_port.recv().unwrap();
 
         match reply {
             Reply::GetFontTemplateReply(data) => {
                 data.unwrap()
             }
         }
     }
 
--- a/servo/components/gfx/font_template.rs
+++ b/servo/components/gfx/font_template.rs
@@ -10,17 +10,17 @@ use platform::font_template::FontTemplat
 use std::borrow::ToOwned;
 use std::sync::{Arc, Weak};
 use font::FontHandleMethods;
 
 /// Describes how to select a font from a given family.
 /// This is very basic at the moment and needs to be
 /// expanded or refactored when we support more of the
 /// font styling parameters.
-#[deriving(Clone, Copy)]
+#[derive(Clone, Copy)]
 pub struct FontTemplateDescriptor {
     pub weight: font_weight::T,
     pub italic: bool,
 }
 
 impl FontTemplateDescriptor {
     pub fn new(weight: font_weight::T, italic: bool) -> FontTemplateDescriptor {
         FontTemplateDescriptor {
--- a/servo/components/gfx/lib.rs
+++ b/servo/components/gfx/lib.rs
@@ -1,37 +1,36 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#![feature(globs, macro_rules, phase, unsafe_destructor, default_type_params)]
+#![feature(unsafe_destructor, int_uint, plugin, box_syntax)]
 
 #![deny(unused_imports)]
 #![deny(unused_variables)]
 #![allow(missing_copy_implementations)]
+#![allow(unstable)]
 
-#![feature(phase)]
-#[phase(plugin, link)]
+#[macro_use]
 extern crate log;
 
 extern crate azure;
 extern crate collections;
 extern crate geom;
 extern crate layers;
 extern crate libc;
-extern crate rustrt;
 extern crate stb_image;
 extern crate png;
 extern crate script_traits;
-extern crate serialize;
+extern crate "serialize" as rustc_serialize;
 extern crate unicode;
-#[phase(plugin)]
+#[no_link] #[plugin]
 extern crate "plugins" as servo_plugins;
 extern crate "net" as servo_net;
-#[phase(plugin, link)]
+#[macro_use]
 extern crate "util" as servo_util;
 extern crate "msg" as servo_msg;
 extern crate style;
 extern crate time;
 extern crate url;
 
 // Eventually we would like the shaper to be pluggable, as many operating systems have their own
 // shapers. For now, however, this is a hard dependency.
--- a/servo/components/gfx/paint_context.rs
+++ b/servo/components/gfx/paint_context.rs
@@ -27,17 +27,17 @@ use libc::types::common::c99::{uint16_t,
 use png::PixelsByColorType;
 use servo_net::image::base::Image;
 use servo_util::geometry::{Au, MAX_RECT};
 use servo_util::opts;
 use servo_util::range::Range;
 use std::default::Default;
 use std::f32;
 use std::mem;
-use std::num::{Float, FloatMath};
+use std::num::Float;
 use std::ptr;
 use style::computed_values::{border_style, filter, mix_blend_mode};
 use std::sync::Arc;
 use text::TextRun;
 use text::glyph::CharIndex;
 
 pub struct PaintContext<'a> {
     pub draw_target: DrawTarget,
@@ -49,25 +49,25 @@ pub struct PaintContext<'a> {
     /// The clipping rect for the stacking context as a whole.
     pub clip_rect: Option<Rect<Au>>,
     /// The current transient clipping region, if any. A "transient clipping region" is the
     /// clipping region used by the last display item. We cache the last value so that we avoid
     /// pushing and popping clipping regions unnecessarily.
     pub transient_clip: Option<ClippingRegion>,
 }
 
-#[deriving(Copy)]
+#[derive(Copy)]
 enum Direction {
     Top,
     Left,
     Right,
     Bottom
 }
 
-#[deriving(Copy)]
+#[derive(Copy)]
 enum DashSize {
     DottedBorder = 1,
     DashedBorder = 3
 }
 
 impl<'a> PaintContext<'a> {
     pub fn get_draw_target(&self) -> &DrawTarget {
         &self.draw_target
@@ -603,17 +603,17 @@ impl<'a> PaintContext<'a> {
                                   direction: Direction,
                                   bounds: &Rect<Au>,
                                   border: &SideOffsets2D<f32>,
                                   color: Color,
                                   dash_size: DashSize) {
         let rect = bounds.to_azure_rect();
         let draw_opts = DrawOptions::new(1u as AzFloat, 0 as uint16_t);
         let mut stroke_opts = StrokeOptions::new(0u as AzFloat, 10u as AzFloat);
-        let mut dash: [AzFloat, ..2] = [0u as AzFloat, 0u as AzFloat];
+        let mut dash: [AzFloat; 2] = [0u as AzFloat, 0u as AzFloat];
 
         stroke_opts.set_cap_style(AZ_CAP_BUTT as u8);
 
         let border_width = match direction {
             Direction::Top => border.top,
             Direction::Left => border.left,
             Direction::Right => border.right,
             Direction::Bottom => border.bottom
--- a/servo/components/gfx/paint_task.rs
+++ b/servo/components/gfx/paint_task.rs
@@ -26,23 +26,23 @@ use servo_msg::constellation_msg::Msg as
 use servo_msg::constellation_msg::{ConstellationChan, Failure, PipelineId};
 use servo_msg::constellation_msg::PipelineExitType;
 use servo_util::geometry::{Au, ZERO_POINT};
 use servo_util::opts;
 use servo_util::smallvec::SmallVec;
 use servo_util::task::spawn_named_with_send_on_failure;
 use servo_util::task_state;
 use servo_util::time::{TimeProfilerChan, TimeProfilerCategory, profile};
-use std::comm::{Receiver, Sender, channel};
 use std::mem;
-use std::task::TaskBuilder;
+use std::thread::Builder;
 use std::sync::Arc;
+use std::sync::mpsc::{Receiver, Sender, channel};
 
 /// Information about a hardware graphics layer that layout sends to the painting task.
-#[deriving(Clone)]
+#[derive(Clone)]
 pub struct PaintLayer {
     /// A per-pipeline ID describing this layer that should be stable across reflows.
     pub id: LayerId,
     /// The color of the background in this layer. Used for unpainted content.
     pub background_color: Color,
     /// The scrolling policy of this layer.
     pub scroll_policy: ScrollPolicy,
 }
@@ -69,33 +69,32 @@ pub enum Msg {
     PaintInit(Arc<StackingContext>),
     Paint(Vec<PaintRequest>),
     UnusedBuffer(Vec<Box<LayerBuffer>>),
     PaintPermissionGranted,
     PaintPermissionRevoked,
     Exit(Option<Sender<()>>, PipelineExitType),
 }
 
-#[deriving(Clone)]
+#[derive(Clone)]
 pub struct PaintChan(Sender<Msg>);
 
 impl PaintChan {
     pub fn new() -> (Receiver<Msg>, PaintChan) {
         let (chan, port) = channel();
         (port, PaintChan(chan))
     }
 
     pub fn send(&self, msg: Msg) {
-        let &PaintChan(ref chan) = self;
-        assert!(chan.send_opt(msg).is_ok(), "PaintChan.send: paint port closed")
+        assert!(self.send_opt(msg).is_ok(), "PaintChan.send: paint port closed")
     }
 
     pub fn send_opt(&self, msg: Msg) -> Result<(), Msg> {
         let &PaintChan(ref chan) = self;
-        chan.send_opt(msg)
+        chan.send(msg).map_err(|e| e.0)
     }
 }
 
 pub struct PaintTask<C> {
     id: PipelineId,
     port: Receiver<Msg>,
     compositor: C,
     constellation_chan: ConstellationChan,
@@ -127,29 +126,29 @@ pub struct PaintTask<C> {
 }
 
 // If we implement this as a function, we get borrowck errors from borrowing
 // the whole PaintTask struct.
 macro_rules! native_graphics_context(
     ($task:expr) => (
         $task.native_graphics_context.as_ref().expect("Need a graphics context to do painting")
     )
-)
+);
 
 impl<C> PaintTask<C> where C: PaintListener + Send {
     pub fn create(id: PipelineId,
                   port: Receiver<Msg>,
                   compositor: C,
                   constellation_chan: ConstellationChan,
                   font_cache_task: FontCacheTask,
                   failure_msg: Failure,
                   time_profiler_chan: TimeProfilerChan,
                   shutdown_chan: Sender<()>) {
         let ConstellationChan(c) = constellation_chan.clone();
-        spawn_named_with_send_on_failure("PaintTask", task_state::PAINT, proc() {
+        spawn_named_with_send_on_failure("PaintTask", task_state::PAINT, move |:| {
             {
                 // Ensures that the paint task and graphics context are destroyed before the
                 // shutdown message.
                 let mut compositor = compositor;
                 let native_graphics_context = compositor.get_graphics_metadata().map(
                     |md| NativePaintingGraphicsContext::from_metadata(&md));
                 let worker_threads = WorkerThreadProxy::spawn(compositor.get_graphics_metadata(),
                                                               font_cache_task,
@@ -191,17 +190,17 @@ impl<C> PaintTask<C> where C: PaintListe
     }
 
     fn start(&mut self) {
         debug!("PaintTask: beginning painting loop");
 
         let mut exit_response_channel : Option<Sender<()>> = None;
         let mut waiting_for_compositor_buffers_to_exit = false;
         loop {
-            match self.port.recv() {
+            match self.port.recv().unwrap() {
                 Msg::PaintInit(stacking_context) => {
                     self.root_stacking_context = Some(stacking_context.clone());
 
                     if !self.paint_permission {
                         debug!("PaintTask: paint ready msg");
                         let ConstellationChan(ref mut c) = self.constellation_chan;
                         c.send(ConstellationMsg::PainterReady(self.id));
                         continue;
@@ -221,17 +220,17 @@ impl<C> PaintTask<C> where C: PaintListe
 
                     let mut replies = Vec::new();
                     self.compositor.set_paint_state(self.id, PaintState::Painting);
                     for PaintRequest { buffer_requests, scale, layer_id, epoch }
                           in requests.into_iter() {
                         if self.epoch == epoch {
                             self.paint(&mut replies, buffer_requests, scale, layer_id);
                         } else {
-                            debug!("painter epoch mismatch: {} != {}", self.epoch, epoch);
+                            debug!("painter epoch mismatch: {:?} != {:?}", self.epoch, epoch);
                         }
                     }
 
                     self.compositor.set_paint_state(self.id, PaintState::Idle);
 
                     for reply in replies.iter() {
                         let &(_, ref buffer_set) = reply;
                         self.used_buffer_count += (*buffer_set).buffers.len();
@@ -331,17 +330,17 @@ impl<C> PaintTask<C> where C: PaintListe
     }
 
     /// Paints one layer and sends the tiles back to the layer.
     fn paint(&mut self,
               replies: &mut Vec<(LayerId, Box<LayerBufferSet>)>,
               mut tiles: Vec<BufferRequest>,
               scale: f32,
               layer_id: LayerId) {
-        profile(TimeProfilerCategory::Painting, None, self.time_profiler_chan.clone(), || {
+        profile(TimeProfilerCategory::Painting, None, self.time_profiler_chan.clone(), |:| {
             // Bail out if there is no appropriate stacking context.
             let stacking_context = if let Some(ref stacking_context) = self.root_stacking_context {
                 match display_list::find_stacking_context_with_layer_id(stacking_context,
                                                                         layer_id) {
                     Some(stacking_context) => stacking_context,
                     None => return,
                 }
             } else {
@@ -355,20 +354,20 @@ impl<C> PaintTask<C> where C: PaintListe
             for (i, tile) in tiles.into_iter().enumerate() {
                 let thread_id = i % self.worker_threads.len();
                 let layer_buffer = self.find_or_create_layer_buffer_for_tile(&tile, scale);
                 self.worker_threads[thread_id].paint_tile(tile,
                                                           layer_buffer,
                                                           stacking_context.clone(),
                                                           scale);
             }
-            let new_buffers = Vec::from_fn(tile_count, |i| {
+            let new_buffers = (0..tile_count).map(|&mut :i| {
                 let thread_id = i % self.worker_threads.len();
                 self.worker_threads[thread_id].get_painted_tile_buffer()
-            });
+            }).collect();
 
             let layer_buffer_set = box LayerBufferSet {
                 buffers: new_buffers,
             };
             replies.push((layer_id, layer_buffer_set));
         })
     }
 
@@ -420,53 +419,53 @@ impl WorkerThreadProxy {
              font_cache_task: FontCacheTask,
              time_profiler_chan: TimeProfilerChan)
              -> Vec<WorkerThreadProxy> {
         let thread_count = if opts::get().gpu_painting {
             1
         } else {
             opts::get().layout_threads
         };
-        Vec::from_fn(thread_count, |_| {
+        (0..thread_count).map(|&:_| {
             let (from_worker_sender, from_worker_receiver) = channel();
             let (to_worker_sender, to_worker_receiver) = channel();
             let native_graphics_metadata = native_graphics_metadata.clone();
             let font_cache_task = font_cache_task.clone();
             let time_profiler_chan = time_profiler_chan.clone();
-            TaskBuilder::new().spawn(proc() {
+            Builder::new().spawn(move || {
                 let mut worker_thread = WorkerThread::new(from_worker_sender,
                                                           to_worker_receiver,
                                                           native_graphics_metadata,
                                                           font_cache_task,
                                                           time_profiler_chan);
                 worker_thread.main();
             });
             WorkerThreadProxy {
                 receiver: from_worker_receiver,
                 sender: to_worker_sender,
             }
-        })
+        }).collect()
     }
 
     fn paint_tile(&mut self,
                   tile: BufferRequest,
                   layer_buffer: Option<Box<LayerBuffer>>,
                   stacking_context: Arc<StackingContext>,
                   scale: f32) {
-        self.sender.send(MsgToWorkerThread::PaintTile(tile, layer_buffer, stacking_context, scale))
+        self.sender.send(MsgToWorkerThread::PaintTile(tile, layer_buffer, stacking_context, scale)).unwrap()
     }
 
     fn get_painted_tile_buffer(&mut self) -> Box<LayerBuffer> {
-        match self.receiver.recv() {
+        match self.receiver.recv().unwrap() {
             MsgFromWorkerThread::PaintedTile(layer_buffer) => layer_buffer,
         }
     }
 
     fn exit(&mut self) {
-        self.sender.send(MsgToWorkerThread::Exit)
+        self.sender.send(MsgToWorkerThread::Exit).unwrap()
     }
 }
 
 struct WorkerThread {
     sender: Sender<MsgFromWorkerThread>,
     receiver: Receiver<MsgToWorkerThread>,
     native_graphics_context: Option<NativePaintingGraphicsContext>,
     font_context: Box<FontContext>,
@@ -488,25 +487,25 @@ impl WorkerThread {
             }),
             font_context: box FontContext::new(font_cache_task.clone()),
             time_profiler_sender: time_profiler_sender,
         }
     }
 
     fn main(&mut self) {
         loop {
-            match self.receiver.recv() {
+            match self.receiver.recv().unwrap() {
                 MsgToWorkerThread::Exit => break,
                 MsgToWorkerThread::PaintTile(tile, layer_buffer, stacking_context, scale) => {
                     let draw_target = self.optimize_and_paint_tile(&tile, stacking_context, scale);
                     let buffer = self.create_layer_buffer_for_painted_tile(&tile,
                                                                            layer_buffer,
                                                                            draw_target,
                                                                            scale);
-                    self.sender.send(MsgFromWorkerThread::PaintedTile(buffer))
+                    self.sender.send(MsgFromWorkerThread::PaintedTile(buffer)).unwrap()
                 }
             }
         }
     }
 
     fn optimize_and_paint_tile(&mut self,
                                tile: &BufferRequest,
                                stacking_context: Arc<StackingContext>,
@@ -577,17 +576,17 @@ impl WorkerThread {
                                             -> Box<LayerBuffer> {
         // Extract the texture from the draw target and place it into its slot in the buffer. If
         // using CPU painting, upload it first.
         //
         // FIXME(pcwalton): We should supply the texture and native surface *to* the draw target in
         // GPU painting mode, so that it doesn't have to recreate it.
         if !opts::get().gpu_painting {
             let mut buffer = layer_buffer.unwrap();
-            draw_target.snapshot().get_data_surface().with_data(|data| {
+            draw_target.snapshot().get_data_surface().with_data(|&mut:data| {
                 buffer.native_surface.upload(native_graphics_context!(self), data);
                 debug!("painting worker thread uploading to native surface {}",
                        buffer.native_surface.get_id());
             });
             return buffer
         }
 
         // GPU painting path:
--- a/servo/components/gfx/platform/freetype/font.rs
+++ b/servo/components/gfx/platform/freetype/font.rs
@@ -3,16 +3,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 extern crate freetype;
 
 use font::{FontHandleMethods, FontMetrics, FontTableMethods};
 use font::{FontTableTag, FractionalPixel};
 use servo_util::geometry::Au;
 use servo_util::geometry;
+use servo_util::str::c_str_to_string;
 use platform::font_context::FontContextHandle;
 use text::glyph::GlyphId;
 use text::util::{float_to_fixed, fixed_to_float};
 use style::computed_values::font_weight;
 use platform::font_template::FontTemplateData;
 
 use freetype::freetype::{FT_Get_Char_Index, FT_Get_Postscript_Name};
 use freetype::freetype::{FT_Load_Glyph, FT_Set_Char_Size};
@@ -20,35 +21,34 @@ use freetype::freetype::{FT_Get_Kerning,
 use freetype::freetype::{FT_New_Memory_Face, FT_Done_Face};
 use freetype::freetype::{FTErrorMethods, FT_F26Dot6, FT_Face, FT_FaceRec};
 use freetype::freetype::{FT_GlyphSlot, FT_Library, FT_Long, FT_ULong};
 use freetype::freetype::{FT_KERNING_DEFAULT, FT_STYLE_FLAG_ITALIC, FT_STYLE_FLAG_BOLD};
 use freetype::freetype::{FT_SizeRec, FT_UInt, FT_Size_Metrics, struct_FT_Vector_};
 use freetype::freetype::{ft_sfnt_os2};
 use freetype::tt_os2::TT_OS2;
 
+use libc::c_char;
 use std::mem;
 use std::num::Float;
 use std::ptr;
-use std::string::String;
-
 use std::sync::Arc;
 
 fn float_to_fixed_ft(f: f64) -> i32 {
     float_to_fixed(6, f)
 }
 
 fn fixed_to_float_ft(f: i32) -> f64 {
     fixed_to_float(6, f)
 }
 
 pub struct FontTable;
 
 impl FontTableMethods for FontTable {
-    fn with_buffer(&self, _blk: |*const u8, uint|) {
+    fn with_buffer<F>(&self, _blk: F) where F: FnOnce(*const u8, uint) {
         panic!()
     }
 }
 
 pub struct FontHandle {
     // The font binary. This must stay valid for the lifetime of the font,
     // if the font is created using FT_Memory_Face.
     pub font_data: Arc<FontTemplateData>,
@@ -116,20 +116,24 @@ impl FontHandleMethods for FontHandle {
                 }
             }
         }
     }
     fn get_template(&self) -> Arc<FontTemplateData> {
         self.font_data.clone()
     }
     fn family_name(&self) -> String {
-        unsafe { String::from_raw_buf(&*(*self.face).family_name as *const i8 as *const u8) }
+        unsafe {
+            c_str_to_string((*self.face).family_name as *const c_char)
+        }
     }
     fn face_name(&self) -> String {
-        unsafe { String::from_raw_buf(&*FT_Get_Postscript_Name(self.face) as *const i8 as *const u8) }
+        unsafe {
+            c_str_to_string(FT_Get_Postscript_Name(self.face) as *const c_char)
+        }
     }
     fn is_italic(&self) -> bool {
         unsafe { (*self.face).style_flags & FT_STYLE_FLAG_ITALIC != 0 }
     }
     fn boldness(&self) -> font_weight::T {
         let default_weight = font_weight::T::Weight400;
         if unsafe { (*self.face).style_flags & FT_STYLE_FLAG_BOLD == 0 } {
             default_weight
@@ -248,17 +252,17 @@ impl FontHandleMethods for FontHandle {
             em_size:          em_size,
             ascent:           ascent,
             descent:          -descent, // linux font's seem to use the opposite sign from mac
             max_advance:      max_advance,
             average_advance:  average_advance,
             line_gap:         height,
         };
 
-        debug!("Font metrics (@{} pt): {}", geometry::to_pt(em_size), metrics);
+        debug!("Font metrics (@{} pt): {:?}", geometry::to_pt(em_size), metrics);
         return metrics;
     }
 
     fn get_table_for_tag(&self, _: FontTableTag) -> Option<FontTable> {
         None
     }
 }
 
--- a/servo/components/gfx/platform/freetype/font_context.rs
+++ b/servo/components/gfx/platform/freetype/font_context.rs
@@ -32,22 +32,22 @@ extern fn ft_free(_mem: FT_Memory, block
 
 extern fn ft_realloc(_mem: FT_Memory, _cur_size: c_long, new_size: c_long, block: *mut c_void) -> *mut c_void {
     unsafe {
         let ptr = libc::realloc(block, new_size as size_t);
         ptr as *mut c_void
     }
 }
 
-#[deriving(Clone)]
+#[derive(Clone)]
 pub struct FreeTypeLibraryHandle {
     pub ctx: FT_Library,
 }
 
-#[deriving(Clone)]
+#[derive(Clone)]
 pub struct FontContextHandle {
     pub ctx: Rc<FreeTypeLibraryHandle>,
 }
 
 impl Drop for FreeTypeLibraryHandle {
     fn drop(&mut self) {
         assert!(!self.ctx.is_null());
         unsafe { FT_Done_FreeType(self.ctx) };
--- a/servo/components/gfx/platform/freetype/font_list.rs
+++ b/servo/components/gfx/platform/freetype/font_list.rs
@@ -15,76 +15,80 @@ use fontconfig::fontconfig::{
     FcNameParse, FcPatternGetString,
     FcPatternDestroy, FcFontSetDestroy,
     FcMatchPattern,
     FcPatternCreate, FcPatternAddString,
     FcFontSetList, FcObjectSetCreate, FcObjectSetDestroy,
     FcObjectSetAdd, FcPatternGetInteger
 };
 
+use servo_util::str::c_str_to_string;
+
 use libc;
-use libc::c_int;
+use libc::{c_int, c_char};
 use std::borrow::ToOwned;
+use std::ffi::CString;
 use std::ptr;
-use std::string::String;
 
 static FC_FAMILY: &'static [u8] = b"family\0";
 static FC_FILE: &'static [u8] = b"file\0";
 static FC_INDEX: &'static [u8] = b"index\0";
 
-pub fn get_available_families(callback: |String|) {
+pub fn get_available_families<F>(mut callback: F) where F: FnMut(String) {
     unsafe {
         let config = FcConfigGetCurrent();
         let fontSet = FcConfigGetFonts(config, FcSetSystem);
         for i in range(0, (*fontSet).nfont as int) {
             let font = (*fontSet).fonts.offset(i);
             let mut family: *mut FcChar8 = ptr::null_mut();
             let mut v: c_int = 0;
-            while FcPatternGetString(*font, FC_FAMILY.as_ptr() as *mut i8, v, &mut family) == FcResultMatch {
-                let family_name = String::from_raw_buf(family as *const i8 as *const u8);
+            while FcPatternGetString(*font, FC_FAMILY.as_ptr() as *mut c_char, v, &mut family) == FcResultMatch {
+                let family_name = c_str_to_string(family as *const c_char);
                 callback(family_name);
                 v += 1;
             }
         }
     }
 }
 
-pub fn get_variations_for_family(family_name: &str, callback: |String|) {
+pub fn get_variations_for_family<F>(family_name: &str, mut callback: F)
+    where F: FnMut(String)
+{
     debug!("getting variations for {}", family_name);
     unsafe {
         let config = FcConfigGetCurrent();
         let mut font_set = FcConfigGetFonts(config, FcSetSystem);
         let font_set_array_ptr = &mut font_set;
         let pattern = FcPatternCreate();
         assert!(!pattern.is_null());
-        let mut family_name_c = family_name.to_c_str();
-        let family_name = family_name_c.as_mut_ptr();
-        let ok = FcPatternAddString(pattern, FC_FAMILY.as_ptr() as *mut i8, family_name as *mut FcChar8);
+        let family_name_c = CString::from_slice(family_name.as_bytes());
+        let family_name = family_name_c.as_ptr();
+        let ok = FcPatternAddString(pattern, FC_FAMILY.as_ptr() as *mut c_char, family_name as *mut FcChar8);
         assert!(ok != 0);
 
         let object_set = FcObjectSetCreate();
         assert!(!object_set.is_null());
 
-        FcObjectSetAdd(object_set, FC_FILE.as_ptr() as *mut i8);
-        FcObjectSetAdd(object_set, FC_INDEX.as_ptr() as *mut i8);
+        FcObjectSetAdd(object_set, FC_FILE.as_ptr() as *mut c_char);
+        FcObjectSetAdd(object_set, FC_INDEX.as_ptr() as *mut c_char);
 
         let matches = FcFontSetList(config, font_set_array_ptr, 1, pattern, object_set);
 
         debug!("found {} variations", (*matches).nfont);
 
         for i in range(0, (*matches).nfont as int) {
             let font = (*matches).fonts.offset(i);
             let mut file: *mut FcChar8 = ptr::null_mut();
-            let file = if FcPatternGetString(*font, FC_FILE.as_ptr() as *mut i8, 0, &mut file) == FcResultMatch {
-                String::from_raw_buf(file as *const i8 as *const u8)
+            let file = if FcPatternGetString(*font, FC_FILE.as_ptr() as *mut c_char, 0, &mut file) == FcResultMatch {
+                c_str_to_string(file as *const c_char)
             } else {
                 panic!();
             };
             let mut index: libc::c_int = 0;
-            let index = if FcPatternGetInteger(*font, FC_INDEX.as_ptr() as *mut i8, 0, &mut index) == FcResultMatch {
+            let index = if FcPatternGetInteger(*font, FC_INDEX.as_ptr() as *mut c_char, 0, &mut index) == FcResultMatch {
                 index
             } else {
                 panic!();
             };
 
             debug!("variation file: {}", file);
             debug!("variation index: {}", index);
 
@@ -93,32 +97,32 @@ pub fn get_variations_for_family(family_
 
         FcFontSetDestroy(matches);
         FcPatternDestroy(pattern);
         FcObjectSetDestroy(object_set);
     }
 }
 
 pub fn get_system_default_family(generic_name: &str) -> Option<String> {
-    let mut generic_name_c = generic_name.to_c_str();
-    let generic_name_ptr = generic_name_c.as_mut_ptr();
+    let generic_name_c = CString::from_slice(generic_name.as_bytes());
+    let generic_name_ptr = generic_name_c.as_ptr();
 
     unsafe {
         let pattern = FcNameParse(generic_name_ptr as *mut FcChar8);
 
         FcConfigSubstitute(ptr::null_mut(), pattern, FcMatchPattern);
         FcDefaultSubstitute(pattern);
 
         let mut result = 0;
         let family_match = FcFontMatch(ptr::null_mut(), pattern, &mut result);
 
         let family_name = if result == FcResultMatch {
             let mut match_string: *mut FcChar8 = ptr::null_mut();
-            FcPatternGetString(family_match, FC_FAMILY.as_ptr() as *mut i8, 0, &mut match_string);
-            let result = String::from_raw_buf(match_string as *const i8 as *const u8);
+            FcPatternGetString(family_match, FC_FAMILY.as_ptr() as *mut c_char, 0, &mut match_string);
+            let result = c_str_to_string(match_string as *const c_char);
             FcPatternDestroy(family_match);
             Some(result)
         } else {
             None
         };
 
         FcPatternDestroy(pattern);
         family_name
--- a/servo/components/gfx/platform/macos/font.rs
+++ b/servo/components/gfx/platform/macos/font.rs
@@ -42,17 +42,17 @@ impl Drop for FontTable {
 
 impl FontTable {
     pub fn wrap(data: CFData) -> FontTable {
         FontTable { data: data }
     }
 }
 
 impl FontTableMethods for FontTable {
-    fn with_buffer(&self, blk: |*const u8, uint|) {
+    fn with_buffer<F>(&self, blk: F) where F: FnOnce(*const u8, uint) {
         blk(self.data.bytes().as_ptr(), self.data.len() as uint);
     }
 }
 
 pub struct FontHandle {
     pub font_data: Arc<FontTemplateData>,
     pub ctfont: CTFont,
 }
@@ -107,18 +107,18 @@ impl FontHandleMethods for FontHandle {
         if normalized < 5.0 { return font_weight::T::Weight500; }
         if normalized < 6.0 { return font_weight::T::Weight600; }
         if normalized < 7.0 { return font_weight::T::Weight700; }
         if normalized < 8.0 { return font_weight::T::Weight800; }
         return font_weight::T::Weight900;
     }
 
     fn glyph_index(&self, codepoint: char) -> Option<GlyphId> {
-        let characters: [UniChar,  ..1] = [codepoint as UniChar];
-        let mut glyphs: [CGGlyph, ..1] = [0 as CGGlyph];
+        let characters: [UniChar; 1] = [codepoint as UniChar];
+        let mut glyphs: [CGGlyph; 1] = [0 as CGGlyph];
         let count: CFIndex = 1;
 
         let result = self.ctfont.get_glyphs_for_characters(&characters[0],
                                                            &mut glyphs[0],
                                                            count);
 
         if !result {
             // No glyph for this character
@@ -174,17 +174,17 @@ impl FontHandleMethods for FontHandle {
             x_height:         Au::from_pt(self.ctfont.x_height() as f64),
             em_size:          em_size,
             ascent:           Au::from_pt(ascent * scale),
             descent:          Au::from_pt(descent * scale),
             max_advance:      max_advance_width,
             average_advance:  average_advance,
             line_gap:         Au::from_frac_px(line_gap),
         };
-        debug!("Font metrics (@{} pt): {}", self.ctfont.pt_size() as f64, metrics);
+        debug!("Font metrics (@{} pt): {:?}", self.ctfont.pt_size() as f64, metrics);
         return metrics;
     }
 
     fn get_table_for_tag(&self, tag: FontTableTag) -> Option<FontTable> {
         let result: Option<CFData> = self.ctfont.get_font_table(tag);
         result.and_then(|data| {
             Some(FontTable::wrap(data))
         })
--- a/servo/components/gfx/platform/macos/font_context.rs
+++ b/servo/components/gfx/platform/macos/font_context.rs
@@ -1,13 +1,13 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#[deriving(Clone)]
+#[derive(Clone)]
 pub struct FontContextHandle {
     ctx: ()
 }
 
 impl FontContextHandle {
     // this is a placeholder until NSFontManager or whatever is bound in here.
     pub fn new() -> FontContextHandle {
         FontContextHandle { ctx: () }
--- a/servo/components/gfx/platform/macos/font_list.rs
+++ b/servo/components/gfx/platform/macos/font_list.rs
@@ -5,27 +5,27 @@
 use core_foundation::base::TCFType;
 use core_foundation::string::{CFString, CFStringRef};
 use core_text::font_descriptor::{CTFontDescriptor, CTFontDescriptorRef};
 use core_text;
 
 use std::borrow::ToOwned;
 use std::mem;
 
-pub fn get_available_families(callback: |String|) {
+pub fn get_available_families<F>(mut callback: F) where F: FnMut(String) {
     let family_names = core_text::font_collection::get_family_names();
     for strref in family_names.iter() {
         let family_name_ref: CFStringRef = unsafe { mem::transmute(strref) };
         let family_name_cf: CFString = unsafe { TCFType::wrap_under_get_rule(family_name_ref) };
         let family_name = family_name_cf.to_string();
         callback(family_name);
     }
 }
 
-pub fn get_variations_for_family(family_name: &str, callback: |String|) {
+pub fn get_variations_for_family<F>(family_name: &str, mut callback: F) where F: FnMut(String) {
     debug!("Looking for faces of family: {}", family_name);
 
     let family_collection =
         core_text::font_collection::create_for_family(family_name.as_slice());
     match family_collection {
         Some(family_collection) => {
             let family_descriptors = family_collection.get_descriptors();
             for descref in family_descriptors.iter() {
--- a/servo/components/gfx/platform/macos/font_template.rs
+++ b/servo/components/gfx/platform/macos/font_template.rs
@@ -13,16 +13,19 @@ use std::borrow::ToOwned;
 /// The identifier is a PostScript font name. The
 /// CTFont object is cached here for use by the
 /// paint functions that create CGFont references.
 pub struct FontTemplateData {
     pub ctfont: Option<CTFont>,
     pub identifier: String,
 }
 
+unsafe impl Send for FontTemplateData {}
+unsafe impl Sync for FontTemplateData {}
+
 impl FontTemplateData {
     pub fn new(identifier: &str, font_data: Option<Vec<u8>>) -> FontTemplateData {
         let ctfont = match font_data {
             Some(bytes) => {
                 let fontprov = CGDataProvider::from_buffer(bytes.as_slice());
                 let cgfont_result = CGFont::from_data_provider(fontprov);
                 match cgfont_result {
                     Ok(cgfont) => Some(core_text::font::new_from_CGFont(&cgfont, 0.0)),
--- a/servo/components/gfx/text/glyph.rs
+++ b/servo/components/gfx/text/glyph.rs
@@ -4,31 +4,32 @@
 
 use servo_util::vec::*;
 use servo_util::range;
 use servo_util::range::{Range, RangeIndex, EachIndex};
 use servo_util::geometry::Au;
 
 use std::cmp::{Ordering, PartialOrd};
 use std::iter::repeat;
-use std::num::NumCast;
+use std::num::{ToPrimitive, NumCast};
 use std::mem;
+use std::ops::{Add, Sub, Mul, Neg, Div, Rem, BitAnd, BitOr, BitXor, Shl, Shr, Not};
 use std::u16;
 use std::vec::Vec;
 use geom::point::Point2D;
 
 /// GlyphEntry is a port of Gecko's CompressedGlyph scheme for storing glyph data compactly.
 ///
 /// In the common case (reasonable glyph advances, no offsets from the font em-box, and one glyph
 /// per character), we pack glyph advance, glyph id, and some flags into a single u32.
 ///
 /// In the uncommon case (multiple glyphs per unicode character, large glyph index/advance, or
 /// glyph offsets), we pack the glyph count into GlyphEntry, and store the other glyph information
 /// in DetailedGlyphStore.
-#[deriving(Clone, Show, Copy)]
+#[derive(Clone, Show, Copy)]
 struct GlyphEntry {
     value: u32,
 }
 
 impl GlyphEntry {
     fn new(value: u32) -> GlyphEntry {
         GlyphEntry {
             value: value,
@@ -83,17 +84,17 @@ impl GlyphEntry {
         GlyphEntry::new((glyph_count as u32) << GLYPH_COUNT_SHIFT as uint)
     }
 }
 
 /// The id of a particular glyph within a font
 pub type GlyphId = u32;
 
 // TODO: unify with bit flags?
-#[deriving(PartialEq, Copy)]
+#[derive(PartialEq, Copy)]
 pub enum BreakType {
     None,
     Normal,
     Hyphen,
 }
 
 static BREAK_TYPE_NONE:   u8 = 0x0;
 static BREAK_TYPE_NORMAL: u8 = 0x1;
@@ -247,17 +248,17 @@ impl GlyphEntry {
     #[inline(always)]
     fn adapt_character_flags_of_entry(&self, other: GlyphEntry) -> GlyphEntry {
         GlyphEntry { value: self.value | other.value }
     }
 }
 
 // Stores data for a detailed glyph, in the case that several glyphs
 // correspond to one character, or the glyph's data couldn't be packed.
-#[deriving(Clone, Show, Copy)]
+#[derive(Clone, Show, Copy)]
 struct DetailedGlyph {
     id: GlyphId,
     // glyph's advance, in the text's direction (RTL or RTL)
     advance: Au,
     // glyph's offset from the font's em-box (from top-left)
     offset: Point2D<Au>,
 }
 
@@ -266,17 +267,17 @@ impl DetailedGlyph {
         DetailedGlyph {
             id: id,
             advance: advance,
             offset: offset,
         }
     }
 }
 
-#[deriving(PartialEq, Clone, Eq, Show, Copy)]
+#[derive(PartialEq, Clone, Eq, Show, Copy)]
 struct DetailedGlyphRecord {
     // source string offset/GlyphEntry offset in the TextRun
     entry_offset: CharIndex,
     // offset into the detailed glyphs buffer
     detail_offset: int,
 }
 
 impl PartialOrd for DetailedGlyphRecord {
@@ -315,17 +316,17 @@ impl<'a> DetailedGlyphStore {
     }
 
     fn add_detailed_glyphs_for_entry(&mut self, entry_offset: CharIndex, glyphs: &[DetailedGlyph]) {
         let entry = DetailedGlyphRecord {
             entry_offset: entry_offset,
             detail_offset: self.detail_buffer.len() as int,
         };
 
-        debug!("Adding entry[off={}] for detailed glyphs: {}", entry_offset, glyphs);
+        debug!("Adding entry[off={:?}] for detailed glyphs: {:?}", entry_offset, glyphs);
 
         /* TODO: don't actually assert this until asserts are compiled
         in/out based on severity, debug/release, etc. This assertion
         would wreck the complexity of the lookup.
 
         See Rust Issue #3647, #2228, #3627 for related information.
 
         do self.detail_lookup.borrow |arr| {
@@ -335,17 +336,17 @@ impl<'a> DetailedGlyphStore {
 
         self.detail_lookup.push(entry);
         self.detail_buffer.push_all(glyphs);
         self.lookup_is_sorted = false;
     }
 
     fn get_detailed_glyphs_for_entry(&'a self, entry_offset: CharIndex, count: u16)
                                   -> &'a [DetailedGlyph] {
-        debug!("Requesting detailed glyphs[n={}] for entry[off={}]", count, entry_offset);
+        debug!("Requesting detailed glyphs[n={}] for entry[off={:?}]", count, entry_offset);
 
         // FIXME: Is this right? --pcwalton
         // TODO: should fix this somewhere else
         if count == 0 {
             return self.detail_buffer.slice(0, 0);
         }
 
         assert!((count as uint) <= self.detail_buffer.len());
@@ -407,17 +408,17 @@ impl<'a> DetailedGlyphStore {
         mem::swap(&mut self.detail_lookup, &mut sorted_records);
 
         self.lookup_is_sorted = true;
     }
 }
 
 // This struct is used by GlyphStore clients to provide new glyph data.
 // It should be allocated on the stack and passed by reference to GlyphStore.
-#[deriving(Copy)]
+#[derive(Copy)]
 pub struct GlyphData {
     id: GlyphId,
     advance: Au,
     offset: Point2D<Au>,
     is_missing: bool,
     cluster_start: bool,
     ligature_start: bool,
 }
@@ -440,17 +441,17 @@ impl GlyphData {
         }
     }
 }
 
 // This enum is a proxy that's provided to GlyphStore clients when iterating
 // through glyphs (either for a particular TextRun offset, or all glyphs).
 // Rather than eagerly assembling and copying glyph data, it only retrieves
 // values as they are needed from the GlyphStore, using provided offsets.
-#[deriving(Copy)]
+#[derive(Copy)]
 pub enum GlyphInfo<'a> {
     Simple(&'a GlyphStore, CharIndex),
     Detail(&'a GlyphStore, CharIndex, u16),
 }
 
 impl<'a> GlyphInfo<'a> {
     pub fn id(self) -> GlyphId {
         match self {
@@ -509,17 +510,17 @@ pub struct GlyphStore {
     /// A store of the detailed glyph data. Detailed glyphs contained in the
     /// `entry_buffer` point to locations in this data structure.
     detail_store: DetailedGlyphStore,
 
     is_whitespace: bool,
 }
 
 int_range_index! {
-    #[deriving(Encodable)]
+    #[derive(RustcEncodable)]
     #[doc = "An index that refers to a character in a text run. This could \
              point to the middle of a glyph."]
     struct CharIndex(int)
 }
 
 impl<'a> GlyphStore {
     // Initializes the glyph store, but doesn't actually shape anything.
     // Use the set_glyph, set_glyphs() methods to store glyph data.
@@ -575,40 +576,40 @@ impl<'a> GlyphStore {
         assert!(data_for_glyphs.len() > 0);
 
         let glyph_count = data_for_glyphs.len() as int;
 
         let first_glyph_data = data_for_glyphs[0];
         let entry = match first_glyph_data.is_missing {
             true  => GlyphEntry::missing(glyph_count),
             false => {
-                let glyphs_vec = Vec::from_fn(glyph_count as uint, |i| {
+                let glyphs_vec: Vec<DetailedGlyph> = (0..glyph_count as uint).map(|&:i| {
                     DetailedGlyph::new(data_for_glyphs[i].id,
                                        data_for_glyphs[i].advance,
                                        data_for_glyphs[i].offset)
-                });
+                }).collect();
 
                 self.detail_store.add_detailed_glyphs_for_entry(i, glyphs_vec.as_slice());
                 GlyphEntry::complex(first_glyph_data.cluster_start,
                                     first_glyph_data.ligature_start,
                                     glyph_count)
             }
         }.adapt_character_flags_of_entry(self.entry_buffer[i.to_uint()]);
 
-        debug!("Adding multiple glyphs[idx={}, count={}]: {}", i, glyph_count, entry);
+        debug!("Adding multiple glyphs[idx={:?}, count={}]: {:?}", i, glyph_count, entry);
 
         self.entry_buffer[i.to_uint()] = entry;
     }
 
     // used when a character index has no associated glyph---for example, a ligature continuation.
     pub fn add_nonglyph_for_char_index(&mut self, i: CharIndex, cluster_start: bool, ligature_start: bool) {
         assert!(i < self.char_len());
 
         let entry = GlyphEntry::complex(cluster_start, ligature_start, 0);
-        debug!("adding spacer for chracter without associated glyph[idx={}]", i);
+        debug!("adding spacer for chracter without associated glyph[idx={:?}]", i);
 
         self.entry_buffer[i.to_uint()] = entry;
     }
 
     pub fn iter_glyphs_for_char_index(&'a self, i: CharIndex) -> GlyphIterator<'a> {
         self.iter_glyphs_for_char_range(&Range::new(i, CharIndex(1)))
     }
 
@@ -720,32 +721,34 @@ impl<'a> GlyphIterator<'a> {
     fn next_complex_glyph(&mut self, entry: &GlyphEntry, i: CharIndex)
                           -> Option<(CharIndex, GlyphInfo<'a>)> {
         let glyphs = self.store.detail_store.get_detailed_glyphs_for_entry(i, entry.glyph_count());
         self.glyph_range = Some(range::each_index(CharIndex(0), CharIndex(glyphs.len() as int)));
         self.next()
     }
 }
 
-impl<'a> Iterator<(CharIndex, GlyphInfo<'a>)> for GlyphIterator<'a> {
+impl<'a> Iterator for GlyphIterator<'a> {
+    type Item  = (CharIndex, GlyphInfo<'a>);
+
     // I tried to start with something simpler and apply FlatMap, but the
     // inability to store free variables in the FlatMap struct was problematic.
     //
     // This function consists of the fast path and is designed to be inlined into its caller. The
     // slow paths, which should not be inlined, are `next_glyph_range()` and
     // `next_complex_glyph()`.
     #[inline(always)]
     fn next(&mut self) -> Option<(CharIndex, GlyphInfo<'a>)> {
         // Would use 'match' here but it borrows contents in a way that
         // interferes with mutation.
         if self.glyph_range.is_some() {
             self.next_glyph_range()
         } else {
             // No glyph range. Look at next character.
-            self.char_range.next().and_then(|i| {
+            self.char_range.next().and_then(|:i| {
                 self.char_index = i;
                 assert!(i < self.store.char_len());
                 let entry = self.store.entry_buffer[i.to_uint()];
                 if entry.is_simple() {
                     Some((self.char_index, GlyphInfo::Simple(self.store, i)))
                 } else {
                     // Fall back to the slow path.
                     self.next_complex_glyph(&entry, i)
--- a/servo/components/gfx/text/text_run.rs
+++ b/servo/components/gfx/text/text_run.rs
@@ -4,42 +4,42 @@
 
 use font::{Font, FontHandleMethods, FontMetrics, IS_WHITESPACE_SHAPING_FLAG, RunMetrics};
 use font::{ShapingOptions};
 use platform::font_template::FontTemplateData;
 use servo_util::geometry::Au;
 use servo_util::range::Range;
 use servo_util::vec::{Comparator, FullBinarySearchMethods};
 use std::cmp::Ordering;
-use std::slice::Items;
+use std::slice::Iter;
 use std::sync::Arc;
 use text::glyph::{CharIndex, GlyphStore};
 
 /// A single "paragraph" of text in one font size and style.
-#[deriving(Clone)]
+#[derive(Clone)]
 pub struct TextRun {
     pub text: Arc<String>,
     pub font_template: Arc<FontTemplateData>,
     pub actual_pt_size: Au,
     pub font_metrics: FontMetrics,
     /// The glyph runs that make up this text run.
     pub glyphs: Arc<Vec<GlyphRun>>,
 }
 
 /// A single series of glyphs within a text run.
-#[deriving(Clone)]
+#[derive(Clone)]
 pub struct GlyphRun {
     /// The glyphs.
     pub glyph_store: Arc<GlyphStore>,
     /// The range of characters in the containing run.
     pub range: Range<CharIndex>,
 }
 
 pub struct NaturalWordSliceIterator<'a> {
-    glyph_iter: Items<'a, GlyphRun>,
+    glyph_iter: Iter<'a, GlyphRun>,
     range: Range<CharIndex>,
 }
 
 struct CharIndexComparator;
 
 impl Comparator<CharIndex,GlyphRun> for CharIndexComparator {
     fn compare(&self, key: &CharIndex, value: &GlyphRun) -> Ordering {
         if *key < value.range.begin() {
@@ -68,17 +68,19 @@ impl<'a> TextRunSlice<'a> {
     #[inline]
     pub fn text_run_range(&self) -> Range<CharIndex> {
         let mut range = self.range;
         range.shift_by(self.offset);
         range
     }
 }
 
-impl<'a> Iterator<TextRunSlice<'a>> for NaturalWordSliceIterator<'a> {
+impl<'a> Iterator for NaturalWordSliceIterator<'a> {
+    type Item = TextRunSlice<'a>;
+
     // inline(always) due to the inefficient rt failures messing up inline heuristics, I think.
     #[inline(always)]
     fn next(&mut self) -> Option<TextRunSlice<'a>> {
         let slice_glyphs = self.glyph_iter.next();
         if slice_glyphs.is_none() {
             return None;
         }
         let slice_glyphs = slice_glyphs.unwrap();
@@ -96,21 +98,23 @@ impl<'a> Iterator<TextRunSlice<'a>> for 
         } else {
             None
         }
     }
 }
 
 pub struct CharacterSliceIterator<'a> {
     glyph_run: Option<&'a GlyphRun>,
-    glyph_run_iter: Items<'a, GlyphRun>,
+    glyph_run_iter: Iter<'a, GlyphRun>,
     range: Range<CharIndex>,
 }
 
-impl<'a> Iterator<TextRunSlice<'a>> for CharacterSliceIterator<'a> {
+impl<'a> Iterator for CharacterSliceIterator<'a> {
+    type Item = TextRunSlice<'a>;
+
     // inline(always) due to the inefficient rt failures messing up inline heuristics, I think.
     #[inline(always)]
     fn next(&mut self) -> Option<TextRunSlice<'a>> {
         let glyph_run = match self.glyph_run {
             None => return None,
             Some(glyph_run) => glyph_run,
         };
 
@@ -135,17 +139,19 @@ impl<'a> Iterator<TextRunSlice<'a>> for 
 }
 
 pub struct LineIterator<'a> {
     range: Range<CharIndex>,
     clump: Option<Range<CharIndex>>,
     slices: NaturalWordSliceIterator<'a>,
 }
 
-impl<'a> Iterator<Range<CharIndex>> for LineIterator<'a> {
+impl<'a> Iterator for LineIterator<'a> {
+    type Item = Range<CharIndex>;
+
     fn next(&mut self) -> Option<Range<CharIndex>> {
         // Loop until we hit whitespace and are in a clump.
         loop {
             match self.slices.next() {
                 Some(slice) => {
                     match (slice.glyphs.is_whitespace(), self.clump) {
                         (false, Some(ref mut c))  => {
                             c.extend_by(slice.range.length());
@@ -306,19 +312,19 @@ impl<'a> TextRun {
 
     pub fn metrics_for_slice(&self, glyphs: &GlyphStore, slice_range: &Range<CharIndex>) -> RunMetrics {
         RunMetrics::new(glyphs.advance_for_char_range(slice_range),
                         self.font_metrics.ascent,
                         self.font_metrics.descent)
     }
 
     pub fn min_width_for_range(&self, range: &Range<CharIndex>) -> Au {
-        debug!("iterating outer range {}", range);
+        debug!("iterating outer range {:?}", range);
         self.natural_word_slices_in_range(range).fold(Au(0), |max_piece_width, slice| {
-            debug!("iterated on {}[{}]", slice.offset, slice.range);
+            debug!("iterated on {:?}[{:?}]", slice.offset, slice.range);
             Au::max(max_piece_width, self.advance_for_range(&slice.range))
         })
     }
 
     /// Returns the first glyph run containing the given character index.
     pub fn first_glyph_run_containing(&'a self, index: CharIndex) -> Option<&'a GlyphRun> {
         self.index_of_first_glyph_run_containing(index).map(|index| &self.glyphs[index])
     }
--- a/servo/components/gfx/text/util.rs
+++ b/servo/components/gfx/text/util.rs
@@ -1,15 +1,15 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 use text::glyph::CharIndex;
 
-#[deriving(PartialEq, Eq, Copy)]
+#[derive(PartialEq, Eq, Copy)]
 pub enum CompressionMode {
     CompressNone,
     CompressWhitespace,
     CompressWhitespaceNewline,
     DiscardNewline
 }
 
 // ported from Gecko's nsTextFrameUtils::TransformText.
--- a/servo/components/layout/Cargo.toml
+++ b/servo/components/layout/Cargo.toml
@@ -2,16 +2,19 @@
 name = "layout"
 version = "0.0.1"
 authors = ["The Servo Project Developers"]
 
 [lib]
 name = "layout"
 path = "lib.rs"
 
+[dependencies.canvas]
+path = "../canvas"
+
 [dependencies.gfx]
 path = "../gfx"
 
 [dependencies.script]
 path = "../script"
 
 [dependencies.layout_traits]
 path = "../layout_traits"
@@ -32,19 +35,17 @@ path = "../net"
 path = "../util"
 
 [dependencies.cssparser]
 git = "https://github.com/servo/rust-cssparser"
 
 [dependencies.geom]
 git = "https://github.com/servo/rust-geom"
 
-[dependencies.url]
-git = "https://github.com/servo/rust-url"
-
 [dependencies.string_cache]
 git = "https://github.com/servo/string-cache"
 
 [dependencies.string_cache_macros]
 git = "https://github.com/servo/string-cache"
 
 [dependencies]
 encoding = "0.2"
+url = "*"
\ No newline at end of file
--- a/servo/components/layout/block.rs
+++ b/servo/components/layout/block.rs
@@ -59,17 +59,17 @@ use std::cmp::{max, min};
 use std::fmt;
 use style::ComputedValues;
 use style::computed_values::{LengthOrPercentageOrAuto, LengthOrPercentageOrNone};
 use style::computed_values::{LengthOrPercentage, box_sizing, display, float};
 use style::computed_values::{overflow, position};
 use std::sync::Arc;
 
 /// Information specific to floated blocks.
-#[deriving(Clone, Encodable)]
+#[derive(Clone, Encodable)]
 pub struct FloatedBlockInfo {
     /// The amount of inline size that is available for the float.
     pub containing_inline_size: Au,
 
     /// The float ceiling, relative to `BaseFlow::position::cur_b` (i.e. the top part of the border
     /// box).
     pub float_ceiling: Au,
 
@@ -87,17 +87,17 @@ impl FloatedBlockInfo {
             float_ceiling: Au(0),
             index: None,
             float_kind: float_kind,
         }
     }
 }
 
 /// The solutions for the block-size-and-margins constraint equation.
-#[deriving(Copy)]
+#[derive(Copy)]
 struct BSizeConstraintSolution {
     block_start: Au,
     _block_end: Au,
     block_size: Au,
     margin_block_start: Au,
     margin_block_end: Au
 }
 
@@ -361,17 +361,18 @@ impl CandidateBSizeIterator {
         };
 
         fn adjust(size: Au, delta: Au) -> Au {
             max(size - delta, Au(0))
         }
     }
 }
 
-impl Iterator<MaybeAuto> for CandidateBSizeIterator {
+impl Iterator for CandidateBSizeIterator {
+    type Item = MaybeAuto;
     fn next(&mut self) -> Option<MaybeAuto> {
         self.status = match self.status {
             CandidateBSizeIteratorStatus::Initial => CandidateBSizeIteratorStatus::Trying,
             CandidateBSizeIteratorStatus::Trying => {
                 match self.max_block_size {
                     Some(max_block_size) if self.candidate_value > max_block_size => {
                         CandidateBSizeIteratorStatus::TryingMax
                     }
@@ -482,23 +483,23 @@ pub enum BlockType {
     Replaced,
     NonReplaced,
     AbsoluteReplaced,
     AbsoluteNonReplaced,
     FloatReplaced,
     FloatNonReplaced,
 }
 
-#[deriving(Clone, PartialEq)]
+#[derive(Clone, PartialEq)]
 pub enum MarginsMayCollapseFlag {
     MarginsMayCollapse,
     MarginsMayNotCollapse,
 }
 
-#[deriving(PartialEq)]
+#[derive(PartialEq)]
 enum FormattingContextType {
     None,
     Block,
     Other,
 }
 
 // Propagates the `layers_needed_for_descendants` flag appropriately from a child. This is called
 // as part of block-size assignment.
@@ -520,17 +521,17 @@ fn propagate_layer_flag_from_child(layer
         let kid_base = flow::mut_base(kid);
         if kid_base.flags.contains(LAYERS_NEEDED_FOR_DESCENDANTS) {
             *layers_needed_for_descendants = true
         }
     }
 }
 
 // A block formatting context.
-#[deriving(Encodable)]
+#[derive(RustcEncodable)]
 pub struct BlockFlow {
     /// Data common to all flows.
     pub base: BaseFlow,
 
     /// The associated fragment.
     pub fragment: Fragment,
 
     /// Static y offset of an absolute flow from its CB.
@@ -556,18 +557,18 @@ pub struct BlockFlow {
 
 bitflags! {
     flags BlockFlowFlags: u8 {
         #[doc="If this is set, then this block flow is the root flow."]
         const IS_ROOT = 0x01,
     }
 }
 
-impl<'a,E,S> Encodable<S,E> for BlockFlowFlags where S: Encoder<E> {
-    fn encode(&self, e: &mut S) -> Result<(),E> {
+impl Encodable for BlockFlowFlags {
+    fn encode<S: Encoder>(&self, e: &mut S) -> Result<(), S::Error> {
         self.bits().encode(e)
     }
 }
 
 impl BlockFlow {
     pub fn from_node(constructor: &mut FlowConstructor, node: &ThreadSafeLayoutNode) -> BlockFlow {
         let writing_mode = node.style().writing_mode;
         BlockFlow {
@@ -1900,26 +1901,26 @@ impl Flow for BlockFlow {
                                                             CoordinateSystem::Parent)
                               .translate(stacking_context_position));
     }
 }
 
 impl fmt::Show for BlockFlow {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         write!(f,
-               "{} - {:x}: frag={} ({})",
+               "{:?} - {:x}: frag={:?} ({:?})",
                self.class(),
                self.base.debug_id(),
                self.fragment,
                self.base)
     }
 }
 
 /// The inputs for the inline-sizes-and-margins constraint equation.
-#[deriving(Show, Copy)]
+#[derive(Show, Copy)]
 pub struct ISizeConstraintInput {
     pub computed_inline_size: MaybeAuto,
     pub inline_start_margin: MaybeAuto,
     pub inline_end_margin: MaybeAuto,
     pub inline_start: MaybeAuto,
     pub inline_end: MaybeAuto,
     pub available_inline_size: Au,
     pub static_i_offset: Au,
@@ -1942,17 +1943,17 @@ impl ISizeConstraintInput {
             inline_end: inline_end,
             available_inline_size: available_inline_size,
             static_i_offset: static_i_offset,
         }
     }
 }
 
 /// The solutions for the inline-size-and-margins constraint equation.
-#[deriving(Copy, Show)]
+#[derive(Copy, Show)]
 pub struct ISizeConstraintSolution {
     pub inline_start: Au,
     pub inline_end: Au,
     pub inline_size: Au,
     pub margin_inline_start: Au,
     pub margin_inline_end: Au
 }
 
@@ -2555,17 +2556,17 @@ impl ISizeAndMarginsComputer for FloatNo
                                                                             input.inline_start_margin,
                                                                             input.inline_end_margin,
                                                                             input.available_inline_size);
         let margin_inline_start = inline_start_margin.specified_or_zero();
         let margin_inline_end = inline_end_margin.specified_or_zero();
         let available_inline_size_float = available_inline_size - margin_inline_start - margin_inline_end;
         let shrink_to_fit = block.get_shrink_to_fit_inline_size(available_inline_size_float);
         let inline_size = computed_inline_size.specified_or_default(shrink_to_fit);
-        debug!("assign_inline_sizes_float -- inline_size: {}", inline_size);
+        debug!("assign_inline_sizes_float -- inline_size: {:?}", inline_size);
         ISizeConstraintSolution::new(inline_size, margin_inline_start, margin_inline_end)
     }
 }
 
 impl ISizeAndMarginsComputer for FloatReplaced {
     /// CSS Section 10.3.5
     ///
     /// If inline-size is computed as 'auto', the used value is the 'shrink-to-fit' inline-size.
@@ -2575,17 +2576,17 @@ impl ISizeAndMarginsComputer for FloatRe
                                                            input.inline_start_margin,
                                                            input.inline_end_margin);
         let margin_inline_start = inline_start_margin.specified_or_zero();
         let margin_inline_end = inline_end_margin.specified_or_zero();
         let inline_size = match computed_inline_size {
             MaybeAuto::Specified(w) => w,
             MaybeAuto::Auto => panic!("FloatReplaced: inline_size should have been computed by now")
         };
-        debug!("assign_inline_sizes_float -- inline_size: {}", inline_size);
+        debug!("assign_inline_sizes_float -- inline_size: {:?}", inline_size);
         ISizeConstraintSolution::new(inline_size, margin_inline_start, margin_inline_end)
     }
 
     /// Calculate used value of inline-size just like we do for inline replaced elements.
     fn initial_computed_inline_size(&self,
                                     block: &mut BlockFlow,
                                     parent_flow_inline_size: Au,
                                     _: &LayoutContext)
--- a/servo/components/layout/construct.rs
+++ b/servo/components/layout/construct.rs
@@ -56,17 +56,17 @@ use std::mem;
 use std::sync::atomic::Ordering;
 use style::computed_values::{caption_side, display, empty_cells, float, list_style_position};
 use style::computed_values::{position};
 use style::{mod, ComputedValues};
 use std::sync::Arc;
 use url::Url;
 
 /// The results of flow construction for a DOM node.
-#[deriving(Clone)]
+#[derive(Clone)]
 pub enum ConstructionResult {
     /// This node contributes nothing at all (`display: none`). Alternately, this is what newly
     /// created nodes have their `ConstructionResult` set to.
     None,
 
     /// This node contributed a flow at the proper position in the tree.
     /// Nothing more needs to be done for this node. It has bubbled up fixed
     /// and absolute descendant flows that have a containing block above it.
@@ -93,28 +93,28 @@ impl ConstructionResult {
             &ConstructionResult::Flow(ref flow_ref, _) => flow::base(&**flow_ref).debug_id(),
         }
     }
 }
 
 /// Represents the output of flow construction for a DOM node that has not yet resulted in a
 /// complete flow. Construction items bubble up the tree until they find a `Flow` to be attached
 /// to.
-#[deriving(Clone)]
+#[derive(Clone)]
 pub enum ConstructionItem {
     /// Inline fragments and associated {ib} splits that have not yet found flows.
     InlineFragments(InlineFragmentsConstructionResult),
     /// Potentially ignorable whitespace.
     Whitespace(OpaqueNode, Arc<ComputedValues>, RestyleDamage),
     /// TableColumn Fragment
     TableColumnFragment(Fragment),
 }
 
 /// Represents inline fragments and {ib} splits that are bubbling up from an inline.
-#[deriving(Clone)]
+#[derive(Clone)]
 pub struct InlineFragmentsConstructionResult {
     /// Any {ib} splits that we're bubbling up.
     pub splits: DList<InlineBlockSplit>,
 
     /// Any fragments that succeed the {ib} splits.
     pub fragments: DList<Fragment>,
 
     /// Any absolute descendants that we're bubbling up.
@@ -142,17 +142,17 @@ pub struct InlineFragmentsConstructionRe
 ///             ],
 ///             block: ~BlockFlow {
 ///                 B
 ///             },
 ///         }),~[
 ///             C
 ///         ])
 /// ```
-#[deriving(Clone)]
+#[derive(Clone)]
 pub struct InlineBlockSplit {
     /// The inline fragments that precede the flow.
     pub predecessors: DList<Fragment>,
 
     /// The flow that caused this {ib} split.
     pub flow: FlowRef,
 }
 
@@ -1145,17 +1145,17 @@ impl<'a> PostorderNodeMutTraversal for F
             Some(NodeTypeId::DocumentType) |
             Some(NodeTypeId::DocumentFragment) |
             Some(NodeTypeId::Document) |
             Some(NodeTypeId::ProcessingInstruction) => {
                 (display::T::none, float::T::none, position::T::static_)
             }
         };
 
-        debug!("building flow for node: {} {} {}", display, float, node.type_id());
+        debug!("building flow for node: {:?} {:?} {:?}", display, float, node.type_id());
 
         // Switch on display and floatedness.
         match (display, float, positioning) {
             // `display: none` contributes no flow construction result. Nuke the flow construction
             // results of children.
             (display::T::none, _, _) => {
                 for child in node.children() {
                     drop(child.swap_out_construction_result())
--- a/servo/components/layout/context.rs
+++ b/servo/components/layout/context.rs
@@ -23,17 +23,17 @@ use style::Stylist;
 use url::Url;
 
 struct LocalLayoutContext {
     font_context: FontContext,
     applicable_declarations_cache: ApplicableDeclarationsCache,
     style_sharing_candidate_cache: StyleSharingCandidateCache,
 }
 
-thread_local!(static LOCAL_CONTEXT_KEY: Cell<*mut LocalLayoutContext> = Cell::new(ptr::null_mut()))
+thread_local!(static LOCAL_CONTEXT_KEY: Cell<*mut LocalLayoutContext> = Cell::new(ptr::null_mut()));
 
 fn create_or_get_local_context(shared_layout_context: &SharedLayoutContext) -> *mut LocalLayoutContext {
     LOCAL_CONTEXT_KEY.with(|ref r| {
         if r.get().is_null() {
             let context = box LocalLayoutContext {
                 font_context: FontContext::new(shared_layout_context.font_cache_task.clone()),
                 applicable_declarations_cache: ApplicableDeclarationsCache::new(),
                 style_sharing_candidate_cache: StyleSharingCandidateCache::new(),
@@ -75,16 +75,19 @@ pub struct SharedLayoutContext {
     /// The dirty rectangle, used during display list building.
     pub dirty: Rect<Au>,
 
     /// Starts at zero, and increased by one every time a layout completes.
     /// This can be used to easily check for invalid stale data.
     pub generation: uint,
 }
 
+pub struct SharedLayoutContextWrapper(pub *const SharedLayoutContext);
+unsafe impl Send for SharedLayoutContextWrapper {}
+
 pub struct LayoutContext<'a> {
     pub shared: &'a SharedLayoutContext,
     cached_local_layout_context: *mut LocalLayoutContext,
 }
 
 impl<'a> LayoutContext<'a> {
     pub fn new(shared_layout_context: &'a SharedLayoutContext) -> LayoutContext<'a> {
 
--- a/servo/components/layout/css/matching.rs
+++ b/servo/components/layout/css/matching.rs
@@ -6,23 +6,23 @@
 
 use css::node_style::StyledNode;
 use incremental::{mod, RestyleDamage};
 use util::{LayoutDataAccess, LayoutDataWrapper};
 use wrapper::{LayoutElement, LayoutNode, TLayoutNode};
 
 use script::dom::node::NodeTypeId;
 use servo_util::bloom::BloomFilter;
-use servo_util::cache::{Cache, LRUCache, SimpleHashCache};
+use servo_util::cache::{LRUCache, SimpleHashCache};
 use servo_util::smallvec::{SmallVec, SmallVec16};
 use servo_util::arc_ptr_eq;
 use std::borrow::ToOwned;
 use std::mem;
-use std::hash::{Hash, sip};
-use std::slice::Items;
+use std::hash::{Hash, Hasher, Writer};
+use std::slice::Iter;
 use string_cache::{Atom, Namespace};
 use style::{mod, PseudoElement, ComputedValues, DeclarationBlock, Stylist, TElement, TNode};
 use style::{CommonStyleAffectingAttributeMode, CommonStyleAffectingAttributes, cascade};
 use std::sync::Arc;
 
 pub struct ApplicableDeclarations {
     pub normal: SmallVec16<DeclarationBlock>,
     pub before: Vec<DeclarationBlock>,
@@ -45,38 +45,39 @@ impl ApplicableDeclarations {
     pub fn clear(&mut self) {
         self.normal = SmallVec16::new();
         self.before = Vec::new();
         self.after = Vec::new();
         self.normal_shareable = false;
     }
 }
 
-#[deriving(Clone)]
+#[derive(Clone)]
 pub struct ApplicableDeclarationsCacheEntry {
     pub declarations: Vec<DeclarationBlock>,
 }
 
 impl ApplicableDeclarationsCacheEntry {
     fn new(declarations: Vec<DeclarationBlock>) -> ApplicableDeclarationsCacheEntry {
         ApplicableDeclarationsCacheEntry {
             declarations: declarations,
         }
     }
 }
 
 impl PartialEq for ApplicableDeclarationsCacheEntry {
     fn eq(&self, other: &ApplicableDeclarationsCacheEntry) -> bool {
         let this_as_query = ApplicableDeclarationsCacheQuery::new(self.declarations.as_slice());
-        this_as_query.equiv(other)
+        this_as_query.eq(other)
     }
 }
+impl Eq for ApplicableDeclarationsCacheEntry {}
 
-impl Hash for ApplicableDeclarationsCacheEntry {
-    fn hash(&self, state: &mut sip::SipState) {
+impl<H: Hasher+Writer> Hash<H> for ApplicableDeclarationsCacheEntry {
+    fn hash(&self, state: &mut H) {
         let tmp = ApplicableDeclarationsCacheQuery::new(self.declarations.as_slice());
         tmp.hash(state);
     }
 }
 
 struct ApplicableDeclarationsCacheQuery<'a> {
     declarations: &'a [DeclarationBlock],
 }
@@ -84,33 +85,40 @@ struct ApplicableDeclarationsCacheQuery<
 impl<'a> ApplicableDeclarationsCacheQuery<'a> {
     fn new(declarations: &'a [DeclarationBlock]) -> ApplicableDeclarationsCacheQuery<'a> {
         ApplicableDeclarationsCacheQuery {
             declarations: declarations,
         }
     }
 }
 
-impl<'a> Equiv<ApplicableDeclarationsCacheEntry> for ApplicableDeclarationsCacheQuery<'a> {
-    fn equiv(&self, other: &ApplicableDeclarationsCacheEntry) -> bool {
+impl<'a> PartialEq for ApplicableDeclarationsCacheQuery<'a> {
+    fn eq(&self, other: &ApplicableDeclarationsCacheQuery<'a>) -> bool {
         if self.declarations.len() != other.declarations.len() {
             return false
         }
         for (this, other) in self.declarations.iter().zip(other.declarations.iter()) {
             if !arc_ptr_eq(&this.declarations, &other.declarations) {
                 return false
             }
         }
         return true
     }
 }
-
+impl<'a> Eq for ApplicableDeclarationsCacheQuery<'a> {}
 
-impl<'a> Hash for ApplicableDeclarationsCacheQuery<'a> {
-    fn hash(&self, state: &mut sip::SipState) {
+impl<'a> PartialEq<ApplicableDeclarationsCacheEntry> for ApplicableDeclarationsCacheQuery<'a> {
+    fn eq(&self, other: &ApplicableDeclarationsCacheEntry) -> bool {
+        let other_as_query = ApplicableDeclarationsCacheQuery::new(other.declarations.as_slice());
+        self.eq(&other_as_query)
+    }
+}
+
+impl<'a, H: Hasher+Writer> Hash<H> for ApplicableDeclarationsCacheQuery<'a> {
+    fn hash(&self, state: &mut H) {
         for declaration in self.declarations.iter() {
             let ptr: uint = unsafe {
                 mem::transmute_copy(declaration)
             };
             ptr.hash(state);
         }
     }
 }
@@ -124,17 +132,17 @@ pub struct ApplicableDeclarationsCache {
 impl ApplicableDeclarationsCache {
     pub fn new() -> ApplicableDeclarationsCache {
         ApplicableDeclarationsCache {
             cache: SimpleHashCache::new(APPLICABLE_DECLARATIONS_CACHE_SIZE),
         }
     }
 
     fn find(&self, declarations: &[DeclarationBlock]) -> Option<Arc<ComputedValues>> {
-        match self.cache.find_equiv(&ApplicableDeclarationsCacheQuery::new(declarations)) {
+        match self.cache.find(&ApplicableDeclarationsCacheQuery::new(declarations)) {
             None => None,
             Some(ref values) => Some((*values).clone()),
         }
     }
 
     fn insert(&mut self, declarations: Vec<DeclarationBlock>, style: Arc<ComputedValues>) {
         self.cache.insert(ApplicableDeclarationsCacheEntry::new(declarations), style)
     }
@@ -163,17 +171,17 @@ fn create_common_style_affecting_attribu
                     _ => {}
                 }
             }
         }
     }
     flags
 }
 
-#[deriving(Clone)]
+#[derive(Clone)]
 pub struct StyleSharingCandidate {
     pub style: Arc<ComputedValues>,
     pub parent_style: Arc<ComputedValues>,
     pub local_name: Atom,
     // FIXME(pcwalton): Should be a list of atoms instead.
     pub class: Option<String>,
     pub namespace: Namespace,
     pub common_style_affecting_attributes: CommonStyleAffectingAttributes,
@@ -316,17 +324,17 @@ static STYLE_SHARING_CANDIDATE_CACHE_SIZ
 
 impl StyleSharingCandidateCache {
     pub fn new() -> StyleSharingCandidateCache {
         StyleSharingCandidateCache {
             cache: LRUCache::new(STYLE_SHARING_CANDIDATE_CACHE_SIZE),
         }
     }
 
-    pub fn iter<'a>(&'a self) -> Items<'a,(StyleSharingCandidate,())> {
+    pub fn iter<'a>(&'a self) -> Iter<'a,(StyleSharingCandidate,())> {
         self.cache.iter()
     }
 
     pub fn insert_if_possible(&mut self, node: &LayoutNode) {
         match StyleSharingCandidate::new(node) {
             None => {}
             Some(candidate) => self.cache.insert(candidate, ())
         }
@@ -603,18 +611,18 @@ impl<'ln> MatchMethods for LayoutNode<'l
                 let parent_layout_data = (&*parent_layout_data_ref).as_ref().expect("no parent data!?");
                 let parent_style = parent_layout_data.shared_data.style.as_ref().expect("parent hasn't been styled yet!");
                 Some(parent_style)
             }
         };
 
         let mut layout_data_ref = self.mutate_layout_data();
         match &mut *layout_data_ref {
-            &None => panic!("no layout data"),
-            &Some(ref mut layout_data) => {
+            &mut None => panic!("no layout data"),
+            &mut Some(ref mut layout_data) => {
                 match self.type_id() {
                     Some(NodeTypeId::Text) => {
                         // Text nodes get a copy of the parent style. This ensures
                         // that during fragment construction any non-inherited
                         // CSS properties (such as vertical-align) are correctly
                         // set on the fragment(s).
                         let cloned_parent_style = parent_style.unwrap().clone();
                         layout_data.shared_data.style = Some(cloned_parent_style);
--- a/servo/components/layout/display_list_builder.rs
+++ b/servo/components/layout/display_list_builder.rs
@@ -40,25 +40,27 @@ use servo_msg::constellation_msg::Msg as
 use servo_msg::constellation_msg::ConstellationChan;
 use servo_net::image::holder::ImageHolder;
 use servo_util::cursor::Cursor;
 use servo_util::geometry::{mod, Au, to_px};
 use servo_util::logical_geometry::{LogicalPoint, LogicalRect, LogicalSize};
 use servo_util::opts;
 use std::default::Default;
 use std::iter::repeat;
-use std::num::FloatMath;
+use std::num::Float;
 use style::values::specified::{AngleOrCorner, HorizontalDirection, VerticalDirection};
 use style::computed::{Image, LinearGradient, LengthOrPercentage};
 use style::computed_values::filter::Filter;
 use style::computed_values::{background_attachment, background_repeat, border_style, overflow};
 use style::computed_values::{position, visibility};
 use style::style_structs::Border;
 use style::{ComputedValues, RGBA};
+use std::num::ToPrimitive;
 use std::sync::Arc;
+use std::sync::mpsc::channel;
 use url::Url;
 
 /// The results of display list building for a single flow.
 pub enum DisplayListBuildingResult {
     None,
     StackingContext(Arc<StackingContext>),
     Normal(Box<DisplayList>),
 }
@@ -684,17 +686,17 @@ impl FragmentDisplayListBuilding for Fra
         // Compute the fragment position relative to the parent stacking context. If the fragment
         // itself establishes a stacking context, then the origin of its position will be (0, 0)
         // for the purposes of this computation.
         let stacking_relative_border_box =
             self.stacking_relative_border_box(stacking_relative_flow_origin,
                                               relative_containing_block_size,
                                               CoordinateSystem::Self);
 
-        debug!("Fragment::build_display_list at rel={}, abs={}, dirty={}, flow origin={}: {}",
+        debug!("Fragment::build_display_list at rel={:?}, abs={:?}, dirty={:?}, flow origin={:?}: {:?}",
                self.border_box,
                stacking_relative_border_box,
                layout_context.shared.dirty,
                stacking_relative_flow_origin,
                self);
 
         if self.style().get_inheritedbox().visibility != visibility::T::visible {
             return
@@ -874,18 +876,18 @@ impl FragmentDisplayListBuilding for Fra
                 let width = canvas_fragment_info.replaced_image_fragment_info
                     .computed_inline_size.map_or(0, |w| to_px(w) as uint);
                 let height = canvas_fragment_info.replaced_image_fragment_info
                     .computed_block_size.map_or(0, |h| to_px(h) as uint);
 
                 let (sender, receiver) = channel::<Vec<u8>>();
                 let canvas_data = match canvas_fragment_info.renderer {
                     Some(ref renderer) =>  {
-                        renderer.lock().send(SendPixelContents(sender));
-                        receiver.recv()
+                        renderer.lock().unwrap().send(SendPixelContents(sender));
+                        receiver.recv().unwrap()
                     },
                     None => repeat(0xFFu8).take(width * height * 4).collect(),
                 };
 
                 let canvas_display_item = box ImageDisplayItem {
                     base: BaseDisplayItem::new(stacking_relative_content_box,
                                                DisplayItemMetadata::new(self.node,
                                                                             &*self.style,
@@ -911,17 +913,17 @@ impl FragmentDisplayListBuilding for Fra
                                             layout_context: &LayoutContext) {
         let border_padding = (self.border_padding).to_physical(self.style.writing_mode);
         let content_size = self.content_box().size.to_physical(self.style.writing_mode);
         let iframe_rect = Rect(Point2D(geometry::to_frac_px(offset.x + border_padding.left) as f32,
                                        geometry::to_frac_px(offset.y + border_padding.top) as f32),
                                Size2D(geometry::to_frac_px(content_size.width) as f32,
                                       geometry::to_frac_px(content_size.height) as f32));
 
-        debug!("finalizing position and size of iframe for {},{}",
+        debug!("finalizing position and size of iframe for {:?},{:?}",
                iframe_fragment.pipeline_id,
                iframe_fragment.subpage_id);
         let ConstellationChan(ref chan) = layout_context.shared.constellation_chan;
         chan.send(ConstellationMsg::FrameRect(iframe_fragment.pipeline_id,
                                               iframe_fragment.subpage_id,
                                               iframe_rect));
     }
 
@@ -1271,17 +1273,17 @@ impl ListItemFlowDisplayListBuilding for
         }
 
         // Draw the rest of the block.
         self.block_flow.build_display_list_for_block(display_list, layout_context)
     }
 }
 
 // A helper data structure for gradients.
-#[deriving(Copy)]
+#[derive(Copy)]
 struct StopRun {
     start_offset: f32,
     end_offset: f32,
     start_index: uint,
     stop_count: uint,
 }
 
 fn fmin(a: f32, b: f32) -> f32 {
@@ -1295,17 +1297,17 @@ fn fmin(a: f32, b: f32) -> f32 {
 fn position_to_offset(position: LengthOrPercentage, Au(total_length): Au) -> f32 {
     match position {
         LengthOrPercentage::Length(Au(length)) => fmin(1.0, (length as f32) / (total_length as f32)),
         LengthOrPercentage::Percentage(percentage) => percentage as f32,
     }
 }
 
 /// "Steps" as defined by CSS 2.1 § E.2.
-#[deriving(Clone, PartialEq, Show, Copy)]
+#[derive(Clone, PartialEq, Show, Copy)]
 pub enum StackingLevel {
     /// The border and backgrounds for the root of this stacking context: steps 1 and 2.
     BackgroundAndBorders,
     /// Borders and backgrounds for block-level descendants: step 4.
     BlockBackgroundsAndBorders,
     /// All other content.
     Content,
 }
--- a/servo/components/layout/floats.rs
+++ b/servo/components/layout/floats.rs
@@ -7,57 +7,57 @@ use servo_util::logical_geometry::Writin
 use servo_util::logical_geometry::{LogicalPoint, LogicalRect, LogicalSize};
 use servo_util::persistent_list::PersistentList;
 use std::cmp::{max, min};
 use std::i32;
 use std::fmt;
 use style::computed_values::float;
 
 /// The kind of float: left or right.
-#[deriving(Clone, Encodable, Show, Copy)]
+#[derive(Clone, RustcEncodable, Show, Copy)]
 pub enum FloatKind {
     Left,
     Right
 }
 
 impl FloatKind {
     pub fn from_property(property: float::T) -> FloatKind {
         match property {
             float::T::none => panic!("can't create a float type from an unfloated property"),
             float::T::left => FloatKind::Left,
             float::T::right => FloatKind::Right,
         }
     }
 }
 
 /// The kind of clearance: left, right, or both.
-#[deriving(Copy)]
+#[derive(Copy)]
 pub enum ClearType {
     Left,
     Right,
     Both,
 }
 
 /// Information about a single float.
-#[deriving(Clone, Copy)]
+#[derive(Clone, Copy)]
 struct Float {
     /// The boundaries of this float.
     bounds: LogicalRect<Au>,
     /// The kind of float: left or right.
     kind: FloatKind,
 }
 
 impl fmt::Show for Float {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "bounds={} kind={}", self.bounds, self.kind)
+        write!(f, "bounds={:?} kind={:?}", self.bounds, self.kind)
     }
 }
 
 /// Information about the floats next to a flow.
-#[deriving(Clone)]
+#[derive(Clone)]
 struct FloatList {
     /// Information about each of the floats here.
     floats: PersistentList<Float>,
     /// Cached copy of the maximum block-start offset of the float.
     max_block_start: Au,
 }
 
 impl FloatList {
@@ -72,17 +72,17 @@ impl FloatList {
     /// not to be any floats.
     fn is_present(&self) -> bool {
         self.floats.len() > 0
     }
 }
 
 impl fmt::Show for FloatList {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "max_block_start={} floats={}", self.max_block_start, self.floats.len())
+        write!(f, "max_block_start={:?} floats={}", self.max_block_start, self.floats.len())
     }
 }
 
 /// All the information necessary to place a float.
 pub struct PlacementInfo {
     /// The dimensions of the float.
     pub size: LogicalSize<Au>,
     /// The minimum block-start of the float, as determined by earlier elements.
@@ -91,46 +91,46 @@ pub struct PlacementInfo {
     pub max_inline_size: Au,
     /// The kind of float.
     pub kind: FloatKind
 }
 
 impl fmt::Show for PlacementInfo {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         write!(f,
-               "size={} ceiling={} max_inline_size={} kind={}",
+               "size={:?} ceiling={:?} max_inline_size={:?} kind={:?}",
                self.size,
                self.ceiling,
                self.max_inline_size,
                self.kind)
     }
 }
 
 fn range_intersect(block_start_1: Au, block_end_1: Au, block_start_2: Au, block_end_2: Au) -> (Au, Au) {
     (max(block_start_1, block_start_2), min(block_end_1, block_end_2))
 }
 
 /// Encapsulates information about floats. This is optimized to avoid allocation if there are
 /// no floats, and to avoid copying when translating the list of floats downward.
-#[deriving(Clone)]
+#[derive(Clone)]
 pub struct Floats {
     /// The list of floats.
     list: FloatList,
     /// The offset of the flow relative to the first float.
     offset: LogicalSize<Au>,
     /// The writing mode of these floats.
     pub writing_mode: WritingMode,
 }
 
 impl fmt::Show for Floats {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         if !self.list.is_present() {
             write!(f, "[empty]")
         } else {
-            write!(f, "offset={} floats={}", self.offset, self.list)
+            write!(f, "offset={:?} floats={:?}", self.offset, self.list)
         }
     }
 }
 
 impl Floats {
     /// Creates a new `Floats` object.
     pub fn new(writing_mode: WritingMode) -> Floats {
         Floats {
@@ -161,56 +161,56 @@ impl Floats {
     /// with inline-size small enough that it doesn't collide with any floats. max_x is the
     /// inline-size beyond which floats have no effect. (Generally this is the containing block
     /// inline-size.)
     pub fn available_rect(&self, block_start: Au, block_size: Au, max_x: Au)
                           -> Option<LogicalRect<Au>> {
         let list = &self.list;
         let block_start = block_start - self.offset.block;
 
-        debug!("available_rect: trying to find space at {}", block_start);
+        debug!("available_rect: trying to find space at {:?}", block_start);
 
         // Relevant dimensions for the inline-end-most inline-start float
         let mut max_inline_start = Au(0) - self.offset.inline;
         let mut l_block_start = None;
         let mut l_block_end = None;
         // Relevant dimensions for the inline-start-most inline-end float
         let mut min_inline_end = max_x - self.offset.inline;
         let mut r_block_start = None;
         let mut r_block_end = None;
 
         // Find the float collisions for the given range in the block direction.
         for float in list.floats.iter() {
             debug!("available_rect: Checking for collision against float");
             let float_pos = float.bounds.start;
             let float_size = float.bounds.size;
 
-            debug!("float_pos: {}, float_size: {}", float_pos, float_size);
+            debug!("float_pos: {:?}, float_size: {:?}", float_pos, float_size);
             match float.kind {
                 FloatKind::Left if float_pos.i + float_size.inline > max_inline_start &&
                         float_pos.b + float_size.block > block_start &&
                         float_pos.b < block_start + block_size => {
                     max_inline_start = float_pos.i + float_size.inline;
 
                     l_block_start = Some(float_pos.b);
                     l_block_end = Some(float_pos.b + float_size.block);
 
                     debug!("available_rect: collision with inline_start float: new \
-                            max_inline_start is {}",
+                            max_inline_start is {:?}",
                            max_inline_start);
                 }
                 FloatKind::Right if float_pos.i < min_inline_end &&
                        float_pos.b + float_size.block > block_start &&
                        float_pos.b < block_start + block_size => {
                     min_inline_end = float_pos.i;
 
                     r_block_start = Some(float_pos.b);
                     r_block_end = Some(float_pos.b + float_size.block);
                     debug!("available_rect: collision with inline_end float: new min_inline_end \
-                            is {}",
+                            is {:?}",
                             min_inline_end);
                 }
                 FloatKind::Left | FloatKind::Right => {}
             }
         }
 
         // Extend the vertical range of the rectangle to the closest floats.
         // If there are floats on both sides, take the intersection of the
@@ -257,17 +257,17 @@ impl Floats {
             new_info = PlacementInfo {
                 size: info.size,
                 ceiling: max(info.ceiling, self.list.max_block_start + self.offset.block),
                 max_inline_size: info.max_inline_size,
                 kind: info.kind
             }
         }
 
-        debug!("add_float: added float with info {}", new_info);
+        debug!("add_float: added float with info {:?}", new_info);
 
         let new_float = Float {
             bounds: LogicalRect::from_point_size(
                 self.writing_mode,
                 self.place_between_floats(&new_info).start - self.offset,
                 info.size,
             ),
             kind: info.kind
@@ -298,17 +298,17 @@ impl Floats {
         }
 
         max_block_size.map(|h| h + self.offset.block)
     }
 
     /// Given placement information, finds the closest place a fragment can be positioned without
     /// colliding with any floats.
     pub fn place_between_floats(&self, info: &PlacementInfo) -> LogicalRect<Au> {
-        debug!("place_between_floats: Placing object with {}", info.size);
+        debug!("place_between_floats: Placing object with {:?}", info.size);
 
         // If no floats, use this fast path.
         if !self.list.is_present() {
             match info.kind {
                 FloatKind::Left => {
                     return LogicalRect::new(
                         self.writing_mode,
                         Au(0),
@@ -328,17 +328,17 @@ impl Floats {
         }
 
         // Can't go any higher than previous floats or previous elements in the document.
         let mut float_b = info.ceiling;
         loop {
             let maybe_location = self.available_rect(float_b,
                                                      info.size.block,
                                                      info.max_inline_size);
-            debug!("place_float: Got available rect: {} for y-pos: {}", maybe_location, float_b);
+            debug!("place_float: Got available rect: {:?} for y-pos: {:?}", maybe_location, float_b);
             match maybe_location {
                 // If there are no floats blocking us, return the current location
                 // TODO(eatkinson): integrate with overflow
                 None => {
                     return match info.kind {
                         FloatKind::Left => {
                             LogicalRect::new(
                                 self.writing_mode,
--- a/servo/components/layout/flow.rs
+++ b/servo/components/layout/flow.rs
@@ -50,44 +50,45 @@ use geom::{Point2D, Rect, Size2D};
 use gfx::display_list::ClippingRegion;
 use serialize::{Encoder, Encodable};
 use servo_msg::compositor_msg::LayerId;
 use servo_util::geometry::{Au, ZERO_RECT};
 use servo_util::logical_geometry::{LogicalRect, LogicalSize, WritingMode};
 use std::mem;
 use std::fmt;
 use std::iter::Zip;
+use std::num::FromPrimitive;
 use std::raw;
 use std::sync::atomic::{AtomicUint, Ordering};
-use std::slice::MutItems;
+use std::slice::IterMut;
 use style::computed_values::{clear, empty_cells, float, position, text_align};
 use style::ComputedValues;
 use std::sync::Arc;
 
 /// Virtual methods that make up a float context.
 ///
 /// Note that virtual methods have a cost; we should not overuse them in Servo. Consider adding
 /// methods to `ImmutableFlowUtils` or `MutableFlowUtils` before adding more methods here.
-pub trait Flow: fmt::Show + ToString + Sync {
+pub trait Flow: fmt::Show + Sync {
     // RTTI
     //
     // TODO(pcwalton): Use Rust's RTTI, once that works.
 
     /// Returns the class of flow that this is.
     fn class(&self) -> FlowClass;
 
     /// If this is a block flow, returns the underlying object, borrowed immutably. Fails
     /// otherwise.
     fn as_immutable_block<'a>(&'a self) -> &'a BlockFlow {
         panic!("called as_immutable_block() on a non-block flow")
     }
 
     /// If this is a block flow, returns the underlying object. Fails otherwise.
     fn as_block<'a>(&'a mut self) -> &'a mut BlockFlow {
-        debug!("called as_block() on a flow of type {}", self.class());
+        debug!("called as_block() on a flow of type {:?}", self.class());
         panic!("called as_block() on a non-block flow")
     }
 
     /// If this is an inline flow, returns the underlying object, borrowed immutably. Fails
     /// otherwise.
     fn as_immutable_inline<'a>(&'a self) -> &'a InlineFlow {
         panic!("called as_immutable_inline() on a non-inline flow")
     }
@@ -199,20 +200,20 @@ pub trait Flow: fmt::Show + ToString + S
     fn place_float_if_applicable<'a>(&mut self, _: &'a LayoutContext<'a>) {}
 
     /// Assigns block-sizes in-order; or, if this is a float, places the float. The default
     /// implementation simply assigns block-sizes if this flow is impacted by floats. Returns true
     /// if this child was impacted by floats or false otherwise.
     fn assign_block_size_for_inorder_child_if_necessary<'a>(&mut self,
                                                             layout_context: &'a LayoutContext<'a>)
                                                             -> bool {
-        let impacted = base(&*self).flags.impacted_by_floats();
+        let impacted = base(self).flags.impacted_by_floats();
         if impacted {
             self.assign_block_size(layout_context);
-            mut_base(&mut *self).restyle_damage.remove(REFLOW_OUT_OF_FLOW | REFLOW);
+            mut_base(self).restyle_damage.remove(REFLOW_OUT_OF_FLOW | REFLOW);
         }
         impacted
     }
 
     /// Phase 4 of reflow: computes absolute positions.
     fn compute_absolute_position(&mut self) {
         // The default implementation is a no-op.
     }
@@ -290,45 +291,46 @@ pub trait Flow: fmt::Show + ToString + S
     /// implications because this can be called on parents concurrently from descendants!
     fn generated_containing_block_rect(&self) -> LogicalRect<Au> {
         panic!("generated_containing_block_rect not yet implemented for this flow")
     }
 
     /// Returns a layer ID for the given fragment.
     fn layer_id(&self, fragment_id: uint) -> LayerId {
         unsafe {
-            let pointer: uint = mem::transmute(self);
+            let obj = mem::transmute::<&&Self, &raw::TraitObject>(&self);
+            let pointer: uint = mem::transmute(obj.data);
             LayerId(pointer, fragment_id)
         }
     }
 
     /// Attempts to perform incremental fixup of this flow by replacing its fragment's style with
     /// the new style. This can only succeed if the flow has exactly one fragment.
     fn repair_style(&mut self, new_style: &Arc<ComputedValues>);
 }
 
 // Base access
 
 #[inline(always)]
-pub fn base<'a>(this: &'a Flow) -> &'a BaseFlow {
+pub fn base<'a, T: ?Sized + Flow>(this: &'a T) -> &'a BaseFlow {
     unsafe {
-        let obj = mem::transmute::<&'a Flow, raw::TraitObject>(this);
+        let obj = mem::transmute::<&&'a T, &'a raw::TraitObject>(&this);
         mem::transmute::<*mut (), &'a BaseFlow>(obj.data)
     }
 }
 
 /// Iterates over the children of this immutable flow.
 pub fn imm_child_iter<'a>(flow: &'a Flow) -> FlowListIterator<'a> {
     base(flow).children.iter()
 }
 
 #[inline(always)]
-pub fn mut_base<'a>(this: &'a mut Flow) -> &'a mut BaseFlow {
+pub fn mut_base<'a, T: ?Sized + Flow>(this: &'a mut T) -> &'a mut BaseFlow {
     unsafe {
-        let obj = mem::transmute::<&'a mut Flow, raw::TraitObject>(this);
+        let obj = mem::transmute::<&&'a mut T, &'a raw::TraitObject>(&this);
         mem::transmute::<*mut (), &'a mut BaseFlow>(obj.data)
     }
 }
 
 /// Iterates over the children of this flow.
 pub fn child_iter<'a>(flow: &'a mut Flow) -> MutFlowListIterator<'a> {
     mut_base(flow).children.iter_mut()
 }
@@ -418,17 +420,17 @@ pub trait MutableFlowUtils {
 
 pub trait MutableOwnedFlowUtils {
     /// Set absolute descendants for this flow.
     ///
     /// Set this flow as the Containing Block for all the absolute descendants.
     fn set_absolute_descendants(&mut self, abs_descendants: AbsDescendants);
 }
 
-#[deriving(Encodable, PartialEq, Show)]
+#[derive(RustcEncodable, PartialEq, Show)]
 pub enum FlowClass {
     Block,
     Inline,
     ListItem,
     TableWrapper,
     Table,
     TableColGroup,
     TableRowGroup,
@@ -460,17 +462,16 @@ pub trait PostorderFlowTraversal {
     /// child nodes are visited.
     fn should_process(&self, _flow: &mut Flow) -> bool {
         true
     }
 }
 
 bitflags! {
     #[doc = "Flags used in flows."]
-    #[deriving(Copy)]
     flags FlowFlags: u16 {
         // floated descendants flags
         #[doc = "Whether this flow has descendants that float left in the same block formatting"]
         #[doc = "context."]
         const HAS_LEFT_FLOATED_DESCENDANTS = 0b0000_0000_0000_0001,
         #[doc = "Whether this flow has descendants that float right in the same block formatting"]
         #[doc = "context."]
         const HAS_RIGHT_FLOATED_DESCENDANTS = 0b0000_0000_0000_0010,
@@ -535,17 +536,17 @@ impl FlowFlags {
     #[inline]
     pub fn text_align(self) -> text_align::T {
         FromPrimitive::from_u16((self & TEXT_ALIGN).bits() >> TEXT_ALIGN_SHIFT).unwrap()
     }
 
     #[inline]
     pub fn set_text_align(&mut self, value: text_align::T) {
         *self = (*self & !TEXT_ALIGN) |
-            FlowFlags::from_bits(value as u16 << TEXT_ALIGN_SHIFT).unwrap();
+            FlowFlags::from_bits((value as u16) << TEXT_ALIGN_SHIFT).unwrap();
     }
 
     #[inline]
     pub fn set_text_align_override(&mut self, parent: FlowFlags) {
         self.insert(parent & TEXT_ALIGN);
     }
 
     #[inline]
@@ -587,17 +588,17 @@ impl FlowFlags {
     pub fn clears_floats(&self) -> bool {
         self.contains(CLEARS_LEFT) || self.contains(CLEARS_RIGHT)
     }
 }
 
 /// The Descendants of a flow.
 ///
 /// Also, details about their position wrt this flow.
-#[deriving(Clone)]
+#[derive(Clone)]
 pub struct Descendants {
     /// Links to every descendant. This must be private because it is unsafe to leak `FlowRef`s to
     /// layout.
     descendant_links: Vec<FlowRef>,
 
     /// Static block-direction offsets of all descendants from the start of this flow box.
     pub static_block_offsets: Vec<Au>,
 }
@@ -645,30 +646,31 @@ impl Descendants {
         };
         descendant_iter.zip(self.static_block_offsets.slice_from_mut(0).iter_mut())
     }
 }
 
 pub type AbsDescendants = Descendants;
 
 pub struct DescendantIter<'a> {
-    iter: MutItems<'a, FlowRef>,
+    iter: IterMut<'a, FlowRef>,
 }
 
-impl<'a> Iterator<&'a mut (Flow + 'a)> for DescendantIter<'a> {
+impl<'a> Iterator for DescendantIter<'a> {
+    type Item = &'a mut (Flow + 'a);
     fn next(&mut self) -> Option<&'a mut (Flow + 'a)> {
         self.iter.next().map(|flow| &mut **flow)
     }
 }
 
-pub type DescendantOffsetIter<'a> = Zip<DescendantIter<'a>, MutItems<'a, Au>>;
+pub type DescendantOffsetIter<'a> = Zip<DescendantIter<'a>, IterMut<'a, Au>>;
 
 /// Information needed to compute absolute (i.e. viewport-relative) flow positions (not to be
 /// confused with absolutely-positioned flows).
-#[deriving(Encodable, Copy)]
+#[derive(RustcEncodable, Copy)]
 pub struct AbsolutePositionInfo {
     /// The size of the containing block for relatively-positioned descendants.
     pub relative_containing_block_size: LogicalSize<Au>,
 
     /// The position of the absolute containing block relative to the nearest ancestor stacking
     /// context. If the absolute containing block establishes the stacking context for this flow,
     /// and this flow is not itself absolutely-positioned, then this is (0, 0).
     pub stacking_relative_position_of_absolute_containing_block: Point2D<Au>,
@@ -771,58 +773,61 @@ pub struct BaseFlow {
 
     /// The writing mode for this flow.
     pub writing_mode: WritingMode,
 
     /// Various flags for flows, tightly packed to save space.
     pub flags: FlowFlags,
 }
 
+unsafe impl Send for BaseFlow {}
+unsafe impl Sync for BaseFlow {}
+
 impl fmt::Show for BaseFlow {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         write!(f,
-               "@ {}, CC {}, ADC {}",
+               "@ {:?}, CC {}, ADC {}",
                self.position,
                self.parallel.children_count.load(Ordering::SeqCst),
                self.abs_descendants.len())
     }
 }
 
-impl<E, S: Encoder<E>> Encodable<S, E> for BaseFlow {
-    fn encode(&self, e: &mut S) -> Result<(), E> {
+impl Encodable for BaseFlow {
+    fn encode<S: Encoder>(&self, e: &mut S) -> Result<(), S::Error> {
         e.emit_struct("base", 0, |e| {
-            try!(e.emit_struct_field("id", 0, |e| self.debug_id().encode(e)))
+            try!(e.emit_struct_field("id", 0, |e| self.debug_id().encode(e)));
             try!(e.emit_struct_field("stacking_relative_position",
                                      1,
-                                     |e| self.stacking_relative_position.encode(e)))
+                                     |e| self.stacking_relative_position.encode(e)));
             try!(e.emit_struct_field("intrinsic_inline_sizes",
                                      2,
-                                     |e| self.intrinsic_inline_sizes.encode(e)))
-            try!(e.emit_struct_field("position", 3, |e| self.position.encode(e)))
+                                     |e| self.intrinsic_inline_sizes.encode(e)));
+            try!(e.emit_struct_field("position", 3, |e| self.position.encode(e)));
             e.emit_struct_field("children", 4, |e| {
                 e.emit_seq(self.children.len(), |e| {
                     for (i, c) in self.children.iter().enumerate() {
                         try!(e.emit_seq_elt(i, |e| {
                             try!(e.emit_struct("flow", 0, |e| {
-                                try!(e.emit_struct_field("class", 0, |e| c.class().encode(e)))
+                                try!(e.emit_struct_field("class", 0, |e| c.class().encode(e)));
                                 e.emit_struct_field("data", 1, |e| {
                                     match c.class() {
                                         FlowClass::Block => c.as_immutable_block().encode(e),
                                         FlowClass::Inline => c.as_immutable_inline().encode(e),
                                         FlowClass::Table => c.as_immutable_table().encode(e),
                                         FlowClass::TableWrapper => c.as_immutable_table_wrapper().encode(e),
                                         FlowClass::TableRowGroup => c.as_immutable_table_rowgroup().encode(e),
                                         FlowClass::TableRow => c.as_immutable_table_row().encode(e),
                                         FlowClass::TableCell => c.as_immutable_table_cell().encode(e),
                                         _ => { Ok(()) }     // TODO: Support captions
                                     }
                                 })
-                            }))
+                            }));
                             Ok(())
-                        }))
+                        }));
                     }
                     Ok(())
                 })
 
             })
         })
     }
 }
@@ -833,17 +838,17 @@ impl Drop for BaseFlow {
         if self.ref_count.load(Ordering::SeqCst) != 0 {
             panic!("Flow destroyed before its ref count hit zero—this is unsafe!")
         }
     }
 }
 
 /// Whether a base flow should be forced to be nonfloated. This can affect e.g. `TableFlow`, which
 /// is never floated because the table wrapper flow is the floated one.
-#[deriving(Clone, PartialEq)]
+#[derive(Clone, PartialEq)]
 pub enum ForceNonfloatedFlag {
     /// The flow should be floated if the node has a `float` property.
     FloatIfNecessary,
     /// The flow should be forced to be nonfloated.
     ForceNonfloated,
 }
 
 impl BaseFlow {
@@ -946,17 +951,17 @@ impl BaseFlow {
 
         for item in all_items.iter() {
             let paint_bounds = item.base().clip.clone().intersect_rect(&item.base().bounds);
             if !paint_bounds.might_be_nonempty() {
                 continue;
             }
 
             if bounds.union(&paint_bounds.bounding_rect()) != bounds {
-                error!("DisplayList item {} outside of Flow overflow ({})", item, paint_bounds);
+                error!("DisplayList item {:?} outside of Flow overflow ({:?})", item, paint_bounds);
             }
         }
     }
 }
 
 impl<'a> ImmutableFlowUtils for &'a (Flow + 'a) {
     /// Returns true if this flow is a block flow.
     fn is_block_like(self) -> bool {
@@ -1120,17 +1125,18 @@ impl<'a> ImmutableFlowUtils for &'a (Flo
 
     /// Dumps the flow tree for debugging, with a prefix to indicate that we're at the given level.
     fn dump_with_level(self, level: uint) {
         let mut indent = String::new();
         for _ in range(0, level) {
             indent.push_str("| ")
         }
 
-        println!("{}+ {}", indent, self.to_string());
+        // TODO: ICE, already fixed in rustc.
+        //println!("{}+ {:?}", indent, self);
 
         for kid in imm_child_iter(self) {
             kid.dump_with_level(level + 1)
         }
     }
 }
 
 impl<'a> MutableFlowUtils for &'a mut (Flow + 'a) {
--- a/servo/components/layout/flow_list.rs
+++ b/servo/components/layout/flow_list.rs
@@ -10,21 +10,21 @@ use std::collections::{dlist, DList};
 // This needs to be reworked now that we have dynamically-sized types in Rust.
 // Until then, it's just a wrapper around DList.
 
 pub struct FlowList {
     flows: DList<FlowRef>,
 }
 
 pub struct FlowListIterator<'a> {
-    it: dlist::Items<'a, FlowRef>,
+    it: dlist::Iter<'a, FlowRef>,
 }
 
 pub struct MutFlowListIterator<'a> {
-    it: dlist::MutItems<'a, FlowRef>,
+    it: dlist::IterMut<'a, FlowRef>,
 }
 
 impl FlowList {
     /// Provide a reference to the front element, or None if the list is empty
     #[inline]
     pub fn front<'a>(&'a self) -> Option<&'a Flow> {
         self.flows.front().map(|head| &**head)
     }
@@ -100,29 +100,31 @@ impl FlowList {
 
     /// O(1)
     #[inline]
     pub fn len(&self) -> uint {
         self.flows.len()
     }
 }
 
-impl<'a> Iterator<&'a (Flow + 'a)> for FlowListIterator<'a> {
+impl<'a> Iterator for FlowListIterator<'a> {
+    type Item = &'a (Flow + 'a);
     #[inline]
     fn next(&mut self) -> Option<&'a (Flow + 'a)> {
         self.it.next().map(|x| &**x)
     }
 
     #[inline]
     fn size_hint(&self) -> (uint, Option<uint>) {
         self.it.size_hint()
     }
 }
 
-impl<'a> Iterator<&'a mut (Flow + 'a)> for MutFlowListIterator<'a> {
+impl<'a> Iterator for MutFlowListIterator<'a> {
+    type Item = &'a mut (Flow + 'a);
     #[inline]
     fn next(&mut self) -> Option<&'a mut (Flow + 'a)> {
         self.it.next().map(|x| &mut **x)
     }
 
     #[inline]
     fn size_hint(&self) -> (uint, Option<uint>) {
         self.it.size_hint()
--- a/servo/components/layout/flow_ref.rs
+++ b/servo/components/layout/flow_ref.rs
@@ -5,48 +5,53 @@
 /// Reference-counted pointers to flows.
 ///
 /// Eventually, with dynamically sized types in Rust, much of this code will be superfluous.
 
 use flow::Flow;
 use flow;
 
 use std::mem;
+use std::ops::{Deref, DerefMut};
 use std::ptr;
 use std::raw;
 use std::sync::atomic::Ordering;
 
 #[unsafe_no_drop_flag]
 pub struct FlowRef {
     object: raw::TraitObject,
 }
 
+unsafe impl Send for FlowRef {}
+unsafe impl Sync for FlowRef {}
+
 impl FlowRef {
     pub fn new(mut flow: Box<Flow>) -> FlowRef {
         unsafe {
             let result = {
                 let flow_ref: &mut Flow = &mut *flow;
                 let object = mem::transmute::<&mut Flow, raw::TraitObject>(flow_ref);
                 FlowRef { object: object }
             };
             mem::forget(flow);
             result
         }
     }
 }
 
-impl<'a> Deref<Flow + 'a> for FlowRef {
+impl<'a> Deref for FlowRef {
+    type Target = Flow + 'a;
     fn deref(&self) -> &(Flow + 'a) {
         unsafe {
             mem::transmute_copy::<raw::TraitObject, &(Flow + 'a)>(&self.object)
         }
     }
 }
 
-impl<'a> DerefMut<Flow + 'a> for FlowRef {
+impl<'a> DerefMut for FlowRef {
     fn deref_mut<'a>(&mut self) -> &mut (Flow + 'a) {
         unsafe {
             mem::transmute_copy::<raw::TraitObject, &mut (Flow + 'a)>(&self.object)
         }
     }
 }
 
 impl Drop for FlowRef {
--- a/servo/components/layout/fragment.rs
+++ b/servo/components/layout/fragment.rs
@@ -34,18 +34,20 @@ use servo_net::image::holder::ImageHolde
 use servo_net::local_image_cache::LocalImageCache;
 use servo_util::geometry::{mod, Au, ZERO_POINT};
 use servo_util::logical_geometry::{LogicalRect, LogicalSize, LogicalMargin};
 use servo_util::range::*;
 use servo_util::smallvec::SmallVec;
 use servo_util::str::is_whitespace;
 use std::cmp::{max, min};
 use std::fmt;
+use std::num::ToPrimitive;
 use std::str::FromStr;
 use std::sync::{Arc, Mutex};
+use std::sync::mpsc::Sender;
 use string_cache::Atom;
 use style::{ComputedValues, TElement, TNode, cascade_anonymous};
 use style::computed_values::{LengthOrPercentage, LengthOrPercentageOrAuto};
 use style::computed_values::{LengthOrPercentageOrNone, clear, mix_blend_mode, overflow_wrap};
 use style::computed_values::{position, text_align, text_decoration, vertical_align, white_space};
 use style::computed_values::{word_break};
 use url::Url;
 
@@ -70,17 +72,17 @@ use url::Url;
 /// Different types of fragments may also contain custom data; for example, text fragments contain
 /// text.
 ///
 /// Do not add fields to this structure unless they're really really mega necessary! Fragments get
 /// moved around a lot and thus their size impacts performance of layout quite a bit.
 ///
 /// FIXME(#2260, pcwalton): This can be slimmed down some by (at least) moving `inline_context`
 /// to be on `InlineFlow` only.
-#[deriving(Clone)]
+#[derive(Clone)]
 pub struct Fragment {
     /// An opaque reference to the DOM node that this `Fragment` originates from.
     pub node: OpaqueNode,
 
     /// The CSS style of this fragment.
     pub style: Arc<ComputedValues>,
 
     /// The position of this fragment relative to its owning flow. The size includes padding and
@@ -106,30 +108,33 @@ pub struct Fragment {
     /// A debug ID that is consistent for the life of
     /// this fragment (via transform etc).
     pub debug_id: u16,
 
     /// How damaged this fragment is since last reflow.
     pub restyle_damage: RestyleDamage,
 }
 
-impl<E, S: Encoder<E>> Encodable<S, E> for Fragment {
-    fn encode(&self, e: &mut S) -> Result<(), E> {
+unsafe impl Send for Fragment {}
+unsafe impl Sync for Fragment {}
+
+impl Encodable for Fragment {
+    fn encode<S: Encoder>(&self, e: &mut S) -> Result<(), S::Error> {
         e.emit_struct("fragment", 0, |e| {
-            try!(e.emit_struct_field("id", 0, |e| self.debug_id().encode(e)))
-            try!(e.emit_struct_field("border_box", 1, |e| self.border_box.encode(e)))
+            try!(e.emit_struct_field("id", 0, |e| self.debug_id().encode(e)));
+            try!(e.emit_struct_field("border_box", 1, |e| self.border_box.encode(e)));
             e.emit_struct_field("margin", 2, |e| self.margin.encode(e))
         })
     }
 }
 
 /// Info specific to the kind of fragment.
 ///
 /// Keep this enum small. As in, no more than one word. Or pcwalton will yell at you.
-#[deriving(Clone)]
+#[derive(Clone)]
 pub enum SpecificFragmentInfo {
     Generic,
     Iframe(Box<IframeFragmentInfo>),
     Image(Box<ImageFragmentInfo>),
     Canvas(Box<CanvasFragmentInfo>),
 
     /// A hypothetical box (see CSS 2.1 § 10.3.7) for an absolutely-positioned block that was
     /// declared with `display: inline;`.
@@ -186,47 +191,47 @@ impl SpecificFragmentInfo {
     }
 }
 
 /// A hypothetical box (see CSS 2.1 § 10.3.7) for an absolutely-positioned block that was declared
 /// with `display: inline;`.
 ///
 /// FIXME(pcwalton): Stop leaking this `FlowRef` to layout; that is not memory safe because layout
 /// can clone it.
-#[deriving(Clone)]
+#[derive(Clone)]
 pub struct InlineAbsoluteHypotheticalFragmentInfo {
     pub flow_ref: FlowRef,
 }
 
 impl InlineAbsoluteHypotheticalFragmentInfo {
     pub fn new(flow_ref: FlowRef) -> InlineAbsoluteHypotheticalFragmentInfo {
         InlineAbsoluteHypotheticalFragmentInfo {
             flow_ref: flow_ref,
         }
     }
 }
 
 /// A fragment that represents an inline-block element.
 ///
 /// FIXME(pcwalton): Stop leaking this `FlowRef` to layout; that is not memory safe because layout
 /// can clone it.
-#[deriving(Clone)]
+#[derive(Clone)]
 pub struct InlineBlockFragmentInfo {
     pub flow_ref: FlowRef,
 }
 
 impl InlineBlockFragmentInfo {
     pub fn new(flow_ref: FlowRef) -> InlineBlockFragmentInfo {
         InlineBlockFragmentInfo {
             flow_ref: flow_ref,
         }
     }
 }
 
-#[deriving(Clone)]
+#[derive(Clone)]
 pub struct CanvasFragmentInfo {
     pub replaced_image_fragment_info: ReplacedImageFragmentInfo,
     pub renderer: Option<Arc<Mutex<Sender<CanvasMsg>>>>,
 }
 
 impl CanvasFragmentInfo {
     pub fn new(node: &ThreadSafeLayoutNode) -> CanvasFragmentInfo {
         CanvasFragmentInfo {
@@ -245,17 +250,17 @@ impl CanvasFragmentInfo {
     /// Returns the original block-size of the canvas.
     pub fn canvas_block_size(&self) -> Au {
         self.replaced_image_fragment_info.dom_block_size.unwrap_or(Au(0))
     }
 }
 
 
 /// A fragment that represents a replaced content image and its accompanying borders, shadows, etc.
-#[deriving(Clone)]
+#[derive(Clone)]
 pub struct ImageFragmentInfo {
     /// The image held within this fragment.
     pub replaced_image_fragment_info: ReplacedImageFragmentInfo,
     pub image: ImageHolder<UntrustedNodeAddress>,
 }
 
 impl ImageFragmentInfo {
     /// Creates a new image fragment from the given URL and local image cache.
@@ -304,17 +309,17 @@ impl ImageFragmentInfo {
         let tile_count = (delta_pixels + image_size - 1) / image_size;
         let offset = Au::from_px(image_size * tile_count);
         let new_position = virtual_position - offset;
         *size = *position - new_position + *size;
         *position = new_position;
     }
 }
 
-#[deriving(Clone)]
+#[derive(Clone)]
 pub struct ReplacedImageFragmentInfo {
     pub for_node: UntrustedNodeAddress,
     pub computed_inline_size: Option<Au>,
     pub computed_block_size: Option<Au>,
     pub dom_inline_size: Option<Au>,
     pub dom_block_size: Option<Au>,
     pub writing_mode_is_vertical: bool,
 }
@@ -474,17 +479,17 @@ impl ReplacedImageFragmentInfo {
 
         self.computed_block_size = Some(block_size);
         block_size + noncontent_block_size
     }
 }
 
 /// A fragment that represents an inline frame (iframe). This stores the pipeline ID so that the size
 /// of this iframe can be communicated via the constellation to the iframe's own layout task.
-#[deriving(Clone)]
+#[derive(Clone)]
 pub struct IframeFragmentInfo {
     /// The pipeline ID of this iframe.
     pub pipeline_id: PipelineId,
     /// The subpage ID of this iframe.
     pub subpage_id: SubpageId,
 }
 
 impl IframeFragmentInfo {
@@ -497,17 +502,17 @@ impl IframeFragmentInfo {
         }
     }
 }
 
 /// A scanned text fragment represents a single run of text with a distinct style. A `TextFragment`
 /// may be split into two or more fragments across line breaks. Several `TextFragment`s may
 /// correspond to a single DOM text node. Split text fragments are implemented by referring to
 /// subsets of a single `TextRun` object.
-#[deriving(Clone)]
+#[derive(Clone)]
 pub struct ScannedTextFragmentInfo {
     /// The text run that this represents.
     pub run: Arc<Box<TextRun>>,
 
     /// The range within the above text run that this represents.
     pub range: Range<CharIndex>,
 
     /// The positions of newlines within this scanned text fragment.
@@ -538,17 +543,17 @@ impl ScannedTextFragmentInfo {
             original_new_line_pos: None,
             content_size: content_size,
         }
     }
 }
 
 /// Describes how to split a fragment. This is used during line breaking as part of the return
 /// value of `find_split_info_for_inline_size()`.
-#[deriving(Show, Clone)]
+#[derive(Show, Clone)]
 pub struct SplitInfo {
     // TODO(bjz): this should only need to be a single character index, but both values are
     // currently needed for splitting in the `inline::try_append_*` functions.
     pub range: Range<CharIndex>,
     pub inline_size: Au,
 }
 
 impl SplitInfo {
@@ -567,17 +572,17 @@ pub struct SplitResult {
     /// The part of the fragment that goes on the second line.
     pub inline_end: Option<SplitInfo>,
     /// The text run which is being split.
     pub text_run: Arc<Box<TextRun>>,
 }
 
 /// Data for an unscanned text fragment. Unscanned text fragments are the results of flow
 /// construction that have not yet had their inline-size determined.
-#[deriving(Clone)]
+#[derive(Clone)]
 pub struct UnscannedTextFragmentInfo {
     /// The text inside the fragment.
     ///
     /// FIXME(pcwalton): Is there something more clever we can do here that avoids the double
     /// indirection while not penalizing all fragments?
     pub text: Box<String>,
 }
 
@@ -595,17 +600,17 @@ impl UnscannedTextFragmentInfo {
     pub fn from_text(text: String) -> UnscannedTextFragmentInfo {
         UnscannedTextFragmentInfo {
             text: box text,
         }
     }
 }
 
 /// A fragment that represents a table column.
-#[deriving(Copy, Clone)]
+#[derive(Copy, Clone)]
 pub struct TableColumnFragmentInfo {
     /// the number of columns a <col> element should span
     pub span: int,
 }
 
 impl TableColumnFragmentInfo {
     /// Create the information specific to an table column fragment.
     pub fn new(node: &ThreadSafeLayoutNode) -> TableColumnFragmentInfo {
@@ -738,28 +743,28 @@ impl Fragment {
         self.border_padding = LogicalMargin::zero(self.style.writing_mode);
         self.margin = LogicalMargin::zero(self.style.writing_mode);
     }
 
     /// Saves the new_line_pos vector into a `SpecificFragmentInfo::ScannedText`. This will fail
     /// if called on any other type of fragment.
     pub fn save_new_line_pos(&mut self) {
         match &mut self.specific {
-            &SpecificFragmentInfo::ScannedText(ref mut info) => {
+            &mut SpecificFragmentInfo::ScannedText(ref mut info) => {
                 if !info.new_line_pos.is_empty() {
                     info.original_new_line_pos = Some(info.new_line_pos.clone());
                 }
             }
             _ => {}
         }
     }
 
     pub fn restore_new_line_pos(&mut self) {
         match &mut self.specific {
-            &SpecificFragmentInfo::ScannedText(ref mut info) => {
+            &mut SpecificFragmentInfo::ScannedText(ref mut info) => {
                 match info.original_new_line_pos.take() {
                     None => {}
                     Some(new_line_pos) => info.new_line_pos = new_line_pos,
                 }
                 return
             }
             _ => {}
         }
@@ -1273,17 +1278,17 @@ impl Fragment {
                 panic!("Unscanned text fragments should have been scanned by now!")
             }
             SpecificFragmentInfo::InlineBlock(_) |
             SpecificFragmentInfo::InlineAbsoluteHypothetical(_) => {
                 panic!("Inline blocks or inline absolute hypothetical fragments do not get split")
             }
             SpecificFragmentInfo::ScannedText(ref text_fragment_info) => {
                 let mut new_line_pos = text_fragment_info.new_line_pos.clone();
-                let cur_new_line_pos = new_line_pos.remove(0).unwrap();
+                let cur_new_line_pos = new_line_pos.remove(0);
 
                 let inline_start_range = Range::new(text_fragment_info.range.begin(),
                                                     cur_new_line_pos);
                 let inline_end_range = Range::new(
                     text_fragment_info.range.begin() + cur_new_line_pos + CharIndex(1),
                     text_fragment_info.range.length() - (cur_new_line_pos + CharIndex(1)));
 
                 // Left fragment is for inline-start text of first founded new-line character.
@@ -1350,38 +1355,38 @@ impl Fragment {
 
     /// A helper method that uses the breaking strategy described by `slice_iterator` (at present,
     /// either natural word breaking or character breaking) to split this fragment.
     fn calculate_split_position_using_breaking_strategy<'a,I>(&self,
                                                               mut slice_iterator: I,
                                                               max_inline_size: Au,
                                                               flags: SplitOptions)
                                                               -> Option<SplitResult>
-                                                              where I: Iterator<TextRunSlice<'a>> {
+                                                              where I: Iterator<Item=TextRunSlice<'a>> {
         let text_fragment_info =
             if let SpecificFragmentInfo::ScannedText(ref text_fragment_info) = self.specific {
                 text_fragment_info
             } else {
                 return None
             };
 
         let mut pieces_processed_count: uint = 0;
         let mut remaining_inline_size = max_inline_size;
         let mut inline_start_range = Range::new(text_fragment_info.range.begin(), CharIndex(0));
         let mut inline_end_range = None;
 
-        debug!("calculate_split_position: splitting text fragment (strlen={}, range={}, \
-                max_inline_size={})",
+        debug!("calculate_split_position: splitting text fragment (strlen={}, range={:?}, \
+                max_inline_size={:?})",
                text_fragment_info.run.text.len(),
                text_fragment_info.range,
                max_inline_size);
 
         for slice in slice_iterator {
-            debug!("calculate_split_position: considering slice (offset={}, slice range={}, \
-                    remaining_inline_size={})",
+            debug!("calculate_split_position: considering slice (offset={:?}, slice range={:?}, \
+                    remaining_inline_size={:?})",
                    slice.offset,
                    slice.range,
                    remaining_inline_size);
 
             let metrics = text_fragment_info.run.metrics_for_slice(slice.glyphs, &slice.range);
             let advance = metrics.advance_width;
 
             // Have we found the split point?
@@ -1403,17 +1408,17 @@ impl Fragment {
             // The advance is more than the remaining inline-size, so split here.
             let slice_begin = slice.text_run_range().begin();
             if slice_begin < text_fragment_info.range.end() {
                 // There still some things left over at the end of the line, so create the
                 // inline-end chunk.
                 let mut inline_end = slice.text_run_range();
                 inline_end.extend_to(text_fragment_info.range.end());
                 inline_end_range = Some(inline_end);
-                debug!("calculate_split_position: splitting remainder with inline-end range={}",
+                debug!("calculate_split_position: splitting remainder with inline-end range={:?}",
                        inline_end);
             }
 
             pieces_processed_count += 1;
             break
         }
 
         // If we failed to find a suitable split point, we're on the verge of overflowing the line.
@@ -1811,19 +1816,19 @@ impl Fragment {
         // box too.
         overflow
     }
 }
 
 impl fmt::Show for Fragment {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         try!(write!(f, "({} {} ", self.debug_id(), self.specific.get_type()));
-        try!(write!(f, "bp {}", self.border_padding));
+        try!(write!(f, "bp {:?}", self.border_padding));
         try!(write!(f, " "));
-        try!(write!(f, "m {}", self.margin));
+        try!(write!(f, "m {:?}", self.margin));
         write!(f, ")")
     }
 }
 
 bitflags! {
     flags QuantitiesIncludedInIntrinsicInlineSizes: u8 {
         const INTRINSIC_INLINE_SIZE_INCLUDES_MARGINS = 0x01,
         const INTRINSIC_INLINE_SIZE_INCLUDES_PADDING = 0x02,
@@ -1851,16 +1856,16 @@ pub trait FragmentBorderBoxIterator {
 
     /// Returns true if this fragment must be processed in-order. If this returns false,
     /// we skip the operation for this fragment, but continue processing siblings.
     fn should_process(&mut self, fragment: &Fragment) -> bool;
 }
 
 /// The coordinate system used in `stacking_relative_border_box()`. See the documentation of that
 /// method for details.
-#[deriving(Clone, PartialEq, Show)]
+#[derive(Clone, PartialEq, Show)]
 pub enum CoordinateSystem {
     /// The border box returned is relative to the fragment's parent stacking context.
     Parent,
     /// The border box returned is relative to the fragment's own stacking context, if applicable.
     Self,
 }
 
--- a/servo/components/layout/incremental.rs
+++ b/servo/components/layout/incremental.rs
@@ -7,17 +7,16 @@ use flow::{IS_ABSOLUTELY_POSITIONED};
 
 use std::fmt;
 use std::sync::Arc;
 use style::computed_values::float;
 use style::ComputedValues;
 
 bitflags! {
     #[doc = "Individual layout actions that may be necessary after restyling."]
-    #[deriving(Copy)]
     flags RestyleDamage: u8 {
         #[doc = "Repaint the node itself."]
         #[doc = "Currently unused; need to decide how this propagates."]
         const REPAINT = 0x01,
 
         #[doc = "Recompute intrinsic inline_sizes (minimum and preferred)."]
         #[doc = "Propagates down the flow tree because the computation is"]
         #[doc = "bottom-up."]
@@ -120,17 +119,17 @@ impl fmt::Show for RestyleDamage {
 // breakage on modifications.
 macro_rules! add_if_not_equal(
     ($old:ident, $new:ident, $damage:ident,
      [ $($effect:ident),* ], [ $($style_struct_getter:ident.$name:ident),* ]) => ({
         if $( ($old.$style_struct_getter().$name != $new.$style_struct_getter().$name) )||* {
             $damage.insert($($effect)|*);
         }
     })
-)
+);
 
 pub fn compute_damage(old: &Option<Arc<ComputedValues>>, new: &ComputedValues) -> RestyleDamage {
     let old: &ComputedValues =
         match old.as_ref() {
             None => return RestyleDamage::all(),
             Some(cv) => &**cv,
         };
 
--- a/servo/components/layout/inline.rs
+++ b/servo/components/layout/inline.rs
@@ -26,16 +26,18 @@ use gfx::font_context::FontContext;
 use gfx::text::glyph::CharIndex;
 use servo_util::arc_ptr_eq;
 use servo_util::geometry::{Au, ZERO_RECT};
 use servo_util::logical_geometry::{LogicalRect, LogicalSize, WritingMode};
 use servo_util::range::{Range, RangeIndex};
 use std::cmp::max;
 use std::fmt;
 use std::mem;
+use std::num::ToPrimitive;
+use std::ops::{Add, Sub, Mul, Div, Rem, Neg, Shl, Shr, Not, BitOr, BitAnd, BitXor};
 use std::u16;
 use style::computed_values::{text_align, vertical_align, white_space};
 use style::ComputedValues;
 use std::sync::Arc;
 
 // From gfxFontConstants.h in Firefox
 static FONT_SUBSCRIPT_OFFSET_RATIO: f64 = 0.20;
 static FONT_SUPERSCRIPT_OFFSET_RATIO: f64 = 0.34;
@@ -60,17 +62,17 @@ static FONT_SUPERSCRIPT_OFFSET_RATIO: f6
 /// serve as the starting point, but the current design doesn't make it
 /// hard to try out that alternative.
 ///
 /// Line fragments also contain some metadata used during line breaking. The
 /// green zone is the area that the line can expand to before it collides
 /// with a float or a horizontal wall of the containing block. The block-start
 /// inline-start corner of the green zone is the same as that of the line, but
 /// the green zone can be taller and wider than the line itself.
-#[deriving(Encodable, Show, Copy)]
+#[derive(RustcEncodable, Show, Copy)]
 pub struct Line {
     /// A range of line indices that describe line breaks.
     ///
     /// For example, consider the following HTML and rendered element with
     /// linebreaks:
     ///
     /// ~~~html
     /// <span>I <span>like truffles, <img></span> yes I do.</span>
@@ -145,17 +147,17 @@ pub struct Line {
     /// === line
     /// ::: green zone
     /// FFF float
     /// ~~~
     pub green_zone: LogicalSize<Au>,
 }
 
 int_range_index! {
-    #[deriving(Encodable)]
+    #[derive(RustcEncodable)]
     #[doc = "The index of a fragment in a flattened vector of DOM elements."]
     struct FragmentIndex(int)
 }
 
 bitflags! {
     flags InlineReflowFlags: u8 {
         #[doc="The `white-space: nowrap` property from CSS 2.1 § 16.6 is in effect."]
         const NO_WRAP_INLINE_REFLOW_FLAG = 0x01
@@ -251,17 +253,17 @@ impl LineBreaker {
         flow.lines = mem::replace(&mut self.lines, Vec::new());
     }
 
     /// Reflows the given fragments, which have been plucked out of the inline flow.
     fn reflow_fragments<'a,I>(&mut self,
                               mut old_fragment_iter: I,
                               flow: &'a InlineFlow,
                               layout_context: &LayoutContext)
-                              where I: Iterator<Fragment> {
+                              where I: Iterator<Item=Fragment> {
         loop {
             // Acquire the next fragment to lay out from the work list or fragment list, as
             // appropriate.
             let fragment = match self.next_unbroken_fragment(&mut old_fragment_iter) {
                 None => break,
                 Some(fragment) => fragment,
             };
 
@@ -300,54 +302,54 @@ impl LineBreaker {
             self.flush_current_line()
         }
     }
 
     /// Acquires a new fragment to lay out from the work list or fragment list as appropriate.
     /// Note that you probably don't want to call this method directly in order to be
     /// incremental-reflow-safe; try `next_unbroken_fragment` instead.
     fn next_fragment<I>(&mut self, old_fragment_iter: &mut I) -> Option<Fragment>
-                        where I: Iterator<Fragment> {
+                        where I: Iterator<Item=Fragment> {
         if self.work_list.is_empty() {
             return match old_fragment_iter.next() {
                 None => None,
                 Some(fragment) => {
-                    debug!("LineBreaker: working with fragment from flow: {}", fragment);
+                    debug!("LineBreaker: working with fragment from flow: {:?}", fragment);
                     Some(fragment)
                 }
             }
         }
 
-        debug!("LineBreaker: working with fragment from work list: {}", self.work_list.front());
+        debug!("LineBreaker: working with fragment from work list: {:?}", self.work_list.front());
         self.work_list.pop_front()
     }
 
     /// Acquires a new fragment to lay out from the work list or fragment list, merging it with any
     /// subsequent fragments as appropriate. In effect, what this method does is to return the next
     /// fragment to lay out, undoing line break operations that any previous reflows may have
     /// performed. You probably want to be using this method instead of `next_fragment`.
     fn next_unbroken_fragment<I>(&mut self, old_fragment_iter: &mut I) -> Option<Fragment>
-                                 where I: Iterator<Fragment> {
+                                 where I: Iterator<Item=Fragment> {
         let mut result = match self.next_fragment(old_fragment_iter) {
             None => return None,
             Some(fragment) => fragment,
         };
 
         loop {
             // FIXME(pcwalton): Yuck! I hate this `new_line_pos` stuff. Can we avoid having to do
             // this?
             result.restore_new_line_pos();
 
             let candidate = match self.next_fragment(old_fragment_iter) {
                 None => return Some(result),
                 Some(fragment) => fragment,
             };
 
             let need_to_merge = match (&mut result.specific, &candidate.specific) {
-                (&SpecificFragmentInfo::ScannedText(ref mut result_info),
+                (&mut SpecificFragmentInfo::ScannedText(ref mut result_info),
                  &SpecificFragmentInfo::ScannedText(ref candidate_info))
                     if arc_ptr_eq(&result_info.run, &candidate_info.run) &&
                         result_info.range.end() + CharIndex(1) == candidate_info.range.begin() => {
                     // We found a previously-broken fragment. Merge it up.
                     result_info.range.extend_by(candidate_info.range.length() + CharIndex(1));
                     true
                 }
                 _ => false,
@@ -357,17 +359,17 @@ impl LineBreaker {
                 self.work_list.push_front(candidate);
                 return Some(result)
             }
         }
     }
 
     /// Commits a line to the list.
     fn flush_current_line(&mut self) {
-        debug!("LineBreaker: flushing line {}: {}", self.lines.len(), self.pending_line);
+        debug!("LineBreaker: flushing line {}: {:?}", self.lines.len(), self.pending_line);
         self.lines.push(self.pending_line);
         self.cur_b = self.pending_line.bounds.start.b + self.pending_line.bounds.size.block;
         self.reset_line();
     }
 
     // FIXME(eatkinson): this assumes that the tallest fragment in the line determines the line
     // block-size. This might not be the case with some weird text fonts.
     fn new_block_size_for_line(&self, new_fragment: &Fragment, layout_context: &LayoutContext)
@@ -383,17 +385,17 @@ impl LineBreaker {
     /// Computes the position of a line that has only the provided fragment. Returns the bounding
     /// rect of the line's green zone (whose origin coincides with the line's origin) and the
     /// actual inline-size of the first fragment after splitting.
     fn initial_line_placement(&self,
                               flow: &InlineFlow,
                               first_fragment: &Fragment,
                               ceiling: Au)
                               -> (LogicalRect<Au>, Au) {
-        debug!("LineBreaker: trying to place first fragment of line {}; fragment size: {}, \
+        debug!("LineBreaker: trying to place first fragment of line {}; fragment size: {:?}, \
                 splittable: {}",
                self.lines.len(),
                first_fragment.border_box.size,
                first_fragment.can_split());
 
         // Initially, pretend a splittable fragment has zero inline-size. We will move it later if
         // it has nonzero inline-size and that causes problems.
         let placement_inline_size = if first_fragment.can_split() {
@@ -491,17 +493,17 @@ impl LineBreaker {
 
         debug!("LineBreaker: Found a new-line character, so splitting the line.");
 
         let (inline_start, inline_end, run) =
             in_fragment.find_split_info_by_new_line()
                        .expect("LineBreaker: this split case makes no sense!");
         let writing_mode = self.floats.writing_mode;
 
-        let split_fragment = |split: SplitInfo| {
+        let split_fragment = |&:split: SplitInfo| {
             let info = box ScannedTextFragmentInfo::new(run.clone(),
                                                         split.range,
                                                         (*in_fragment.newline_positions()
                                                                      .unwrap()).clone(),
                                                         in_fragment.border_box.size);
             let size = LogicalSize::new(writing_mode,
                                         split.inline_size,
                                         in_fragment.border_box.size.block);
@@ -536,17 +538,17 @@ impl LineBreaker {
                                            -> bool {
         // Determine initial placement for the fragment if we need to.
         if self.pending_line_is_empty() {
             let (line_bounds, _) = self.initial_line_placement(flow, &fragment, self.cur_b);
             self.pending_line.bounds.start = line_bounds.start;
             self.pending_line.green_zone = line_bounds.size;
         }
 
-        debug!("LineBreaker: trying to append to line {} (fragment size: {}, green zone: {}): {}",
+        debug!("LineBreaker: trying to append to line {} (fragment size: {:?}, green zone: {:?}): {:?}",
                self.lines.len(),
                fragment.border_box.size,
                self.pending_line.green_zone,
                fragment);
 
         // NB: At this point, if `green_zone.inline < self.pending_line.bounds.size.inline` or
         // `green_zone.block < self.pending_line.bounds.size.block`, then we committed a line that
         // overlaps with floats.
@@ -581,23 +583,23 @@ impl LineBreaker {
 
         // Split it up!
         let available_inline_size = green_zone.inline - self.pending_line.bounds.size.inline -
             indentation;
         let (inline_start_fragment, inline_end_fragment) =
             match fragment.calculate_split_position(available_inline_size,
                                                     self.pending_line_is_empty()) {
                 None => {
-                    debug!("LineBreaker: fragment was unsplittable; deferring to next line: {}",
+                    debug!("LineBreaker: fragment was unsplittable; deferring to next line: {:?}",
                            fragment);
                     self.work_list.push_front(fragment);
                     return false
                 }
                 Some(split_result) => {
-                    let split_fragment = |split: SplitInfo| {
+                    let split_fragment = |&:split: SplitInfo| {
                         let info = box ScannedTextFragmentInfo::new(split_result.text_run.clone(),
                                                                     split.range,
                                                                     Vec::new(),
                                                                     fragment.border_box.size);
                         let size = LogicalSize::new(self.floats.writing_mode,
                                                     split.inline_size,
                                                     fragment.border_box.size.block);
                         fragment.transform(size, info)
@@ -652,25 +654,25 @@ impl LineBreaker {
 
     /// Returns true if the pending line is empty and false otherwise.
     fn pending_line_is_empty(&self) -> bool {
         self.pending_line.range.length() == FragmentIndex(0)
     }
 }
 
 /// Represents a list of inline fragments, including element ranges.
-#[deriving(Encodable, Clone)]
+#[derive(RustcEncodable, Clone)]
 pub struct InlineFragments {
     /// The fragments themselves.
     pub fragments: Vec<Fragment>,
 }
 
 impl fmt::Show for InlineFragments {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "{}", self.fragments)
+        write!(f, "{:?}", self.fragments)
     }
 }
 
 
 impl InlineFragments {
     /// Creates an empty set of inline fragments.
     pub fn new() -> InlineFragments {
         InlineFragments {
@@ -706,17 +708,17 @@ impl InlineFragments {
 
     /// A convenience function to return a mutable reference to the fragment at a given index.
     pub fn get_mut<'a>(&'a mut self, index: uint) -> &'a mut Fragment {
         &mut self.fragments[index]
     }
 }
 
 /// Flows for inline layout.
-#[deriving(Encodable)]
+#[derive(RustcEncodable)]
 pub struct InlineFlow {
     /// Data common to all flows.
     pub base: BaseFlow,
 
     /// A vector of all inline fragments. Several fragments may correspond to one node/element.
     pub fragments: InlineFragments,
 
     /// A vector of ranges into fragments that represents line positions. These ranges are disjoint
@@ -961,33 +963,33 @@ impl Flow for InlineFlow {
 
         let writing_mode = self.base.writing_mode;
         for kid in self.base.child_iter() {
             flow::mut_base(kid).floats = Floats::new(writing_mode);
         }
 
         let mut computation = IntrinsicISizesContribution::new();
         for fragment in self.fragments.fragments.iter_mut() {
-            debug!("Flow: measuring {}", *fragment);
+            debug!("Flow: measuring {:?}", *fragment);
             computation.union_inline(&fragment.compute_intrinsic_inline_sizes().finish())
         }
         self.base.intrinsic_inline_sizes = computation.finish()
     }
 
     /// Recursively (top-down) determines the actual inline-size of child contexts and fragments.
     /// When called on this context, the context has had its inline-size set by the parent context.
     fn assign_inline_sizes(&mut self, _: &LayoutContext) {
         let _scope = layout_debug_scope!("inline::assign_inline_sizes {:x}", self.base.debug_id());
 
         // Initialize content fragment inline-sizes if they haven't been initialized already.
         //
         // TODO: Combine this with `LineBreaker`'s walk in the fragment list, or put this into
         // `Fragment`.
 
-        debug!("InlineFlow::assign_inline_sizes: floats in: {}", self.base.floats);
+        debug!("InlineFlow::assign_inline_sizes: floats in: {:?}", self.base.floats);
 
         self.base.position.size.inline = self.base.block_container_inline_size;
 
         {
             let inline_size = self.base.position.size.inline;
             let this = &mut *self;
             for fragment in this.fragments.fragments.iter_mut() {
                 fragment.compute_border_and_padding(inline_size);
@@ -1017,17 +1019,17 @@ impl Flow for InlineFlow {
         //
         // TODO(pcwalton, #226): Get the CSS `line-height` property from the style of the
         // containing block to determine the minimum line block size.
         //
         // TODO(pcwalton, #226): Get the CSS `line-height` property from each non-replaced inline
         // element to determine its block-size for computing the line's own block-size.
         //
         // TODO(pcwalton): Cache the line scanner?
-        debug!("assign_block_size_inline: floats in: {}", self.base.floats);
+        debug!("assign_block_size_inline: floats in: {:?}", self.base.floats);
 
         // Assign the block-size for the inline fragments.
         let containing_block_block_size =
             self.base.block_container_explicit_block_size.unwrap_or(Au(0));
         for fragment in self.fragments.fragments.iter_mut() {
             fragment.assign_replaced_block_size_if_necessary(
                 containing_block_block_size);
         }
@@ -1249,21 +1251,21 @@ impl Flow for InlineFlow {
                                                                     CoordinateSystem::Parent)
                                       .translate(stacking_context_position))
         }
     }
 }
 
 impl fmt::Show for InlineFlow {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "{} - {:x} - {}", self.class(), self.base.debug_id(), self.fragments)
+        write!(f, "{:?} - {:x} - {:?}", self.class(), self.base.debug_id(), self.fragments)
     }
 }
 
-#[deriving(Clone)]
+#[derive(Clone)]
 pub struct InlineFragmentContext {
     pub styles: Vec<Arc<ComputedValues>>,
 }
 
 impl InlineFragmentContext {
     pub fn new() -> InlineFragmentContext {
         InlineFragmentContext {
             styles: vec!()
--- a/servo/components/layout/layout_debug.rs
+++ b/servo/components/layout/layout_debug.rs
@@ -9,36 +9,36 @@
 
 use flow_ref::FlowRef;
 use flow;
 use serialize::json;
 
 use std::borrow::ToOwned;
 use std::cell::RefCell;
 use std::io::File;
-use std::sync::atomic::{AtomicUint, Ordering, INIT_ATOMIC_UINT};
+use std::sync::atomic::{AtomicUint, Ordering, ATOMIC_UINT_INIT};
 
-thread_local!(static STATE_KEY: RefCell<Option<State>> = RefCell::new(None))
+thread_local!(static STATE_KEY: RefCell<Option<State>> = RefCell::new(None));
 
-static mut DEBUG_ID_COUNTER: AtomicUint = INIT_ATOMIC_UINT;
+static mut DEBUG_ID_COUNTER: AtomicUint = ATOMIC_UINT_INIT;
 
 pub struct Scope;
 
 #[macro_export]
 macro_rules! layout_debug_scope(
     ($($arg:tt)*) => (
         if cfg!(not(ndebug)) {
             layout_debug::Scope::new(format!($($arg)*))
         } else {
             layout_debug::Scope
         }
     )
-)
+);
 
-#[deriving(Encodable)]
+#[derive(RustcEncodable)]
 struct ScopeData {
     name: String,
     pre: String,
     post: String,
     children: Vec<Box<ScopeData>>,
 }
 
 impl ScopeData {
@@ -58,40 +58,40 @@ struct State {
 }
 
 /// A layout debugging scope. The entire state of the flow tree
 /// will be output at the beginning and end of this scope.
 impl Scope {
     pub fn new(name: String) -> Scope {
         STATE_KEY.with(|ref r| {
             match &mut *r.borrow_mut() {
-                &Some(ref mut state) => {
+                &mut Some(ref mut state) => {
                     let flow_trace = json::encode(&flow::base(&*state.flow_root));
                     let data = box ScopeData::new(name.clone(), flow_trace);
                     state.scope_stack.push(data);
                 }
-                &None => {}
+                &mut None => {}
             }
         });
         Scope
     }
 }
 
 #[cfg(not(ndebug))]
 impl Drop for Scope {
     fn drop(&mut self) {
         STATE_KEY.with(|ref r| {
             match &mut *r.borrow_mut() {
-                &Some(ref mut state) => {
+                &mut Some(ref mut state) => {
                     let mut current_scope = state.scope_stack.pop().unwrap();
                     current_scope.post = json::encode(&flow::base(&*state.flow_root));
                     let previous_scope = state.scope_stack.last_mut().unwrap();
                     previous_scope.children.push(current_scope);
                 }
-                &None => {}
+                &mut None => {}
             }
         });
     }
 }
 
 /// Generate a unique ID. This is used for items such as Fragment
 /// which are often reallocated but represent essentially the
 /// same data.
--- a/servo/components/layout/layout_task.rs
+++ b/servo/components/layout/layout_task.rs
@@ -2,17 +2,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 //! The layout task. Performs layout on the DOM, builds display lists and sends them to be
 //! painted.
 
 use css::node_style::StyledNode;
 use construct::ConstructionResult;
-use context::SharedLayoutContext;
+use context::{SharedLayoutContext, SharedLayoutContextWrapper};
 use flow::{mod, Flow, ImmutableFlowUtils, MutableFlowUtils, MutableOwnedFlowUtils};
 use flow_ref::FlowRef;
 use fragment::{Fragment, FragmentBorderBoxIterator};
 use incremental::{LayoutDamageComputation, REFLOW, REFLOW_ENTIRE_DOCUMENT, REPAINT};
 use layout_debug;
 use parallel::{mod, UnsafeFlow};
 use sequential;
 use util::{LayoutDataAccess, LayoutDataWrapper, OpaqueNodeMethods, ToGfxColor};
@@ -56,17 +56,18 @@ use servo_util::opts;
 use servo_util::smallvec::{SmallVec, SmallVec1, VecLike};
 use servo_util::task::spawn_named_with_send_on_failure;
 use servo_util::task_state;
 use servo_util::time::{TimeProfilerCategory, ProfilerMetadata, TimeProfilerChan};
 use servo_util::time::{TimerMetadataFrameType, TimerMetadataReflowType, profile};
 use servo_util::workqueue::WorkQueue;
 use std::borrow::ToOwned;
 use std::cell::Cell;
-use std::comm::{channel, Sender, Receiver, Select};
+use std::ops::{Deref, DerefMut};
+use std::sync::mpsc::{channel, Sender, Receiver, Select};
 use std::mem;
 use std::ptr;
 use style::computed_values::{filter, mix_blend_mode};
 use style::{StylesheetOrigin, Stylesheet, Stylist, TNode, iter_font_face_rules};
 use style::{MediaType, Device};
 use std::sync::{Arc, Mutex, MutexGuard};
 use url::Url;
 
@@ -84,17 +85,17 @@ pub struct LayoutTaskData {
     pub screen_size: Size2D<Au>,
 
     /// The root stacking context.
     pub stacking_context: Option<Arc<StackingContext>>,
 
     pub stylist: Box<Stylist>,
 
     /// The workers that we use for parallel operation.
-    pub parallel_traversal: Option<WorkQueue<*const SharedLayoutContext, UnsafeFlow>>,
+    pub parallel_traversal: Option<WorkQueue<SharedLayoutContextWrapper, UnsafeFlow>>,
 
     /// The dirty rect. Used during display list construction.
     pub dirty: Rect<Au>,
 
     /// Starts at zero, and increased by one every time a layout completes.
     /// This can be used to easily check for invalid stale data.
     pub generation: uint,
 
@@ -148,29 +149,27 @@ pub struct LayoutTask {
 }
 
 struct LayoutImageResponder {
     id: PipelineId,
     script_chan: ScriptControlChan,
 }
 
 impl ImageResponder<UntrustedNodeAddress> for LayoutImageResponder {
-    fn respond(&self) -> proc(ImageResponseMsg, UntrustedNodeAddress):Send {
+    fn respond(&self) -> Box<Fn(ImageResponseMsg, UntrustedNodeAddress)+Send> {
         let id = self.id.clone();
         let script_chan = self.script_chan.clone();
-        let f: proc(ImageResponseMsg, UntrustedNodeAddress):Send =
-            proc(_, node_address) {
-                let ScriptControlChan(chan) = script_chan;
-                debug!("Dirtying {:x}", node_address.0 as uint);
-                let mut nodes = SmallVec1::new();
-                nodes.vec_push(node_address);
-                drop(chan.send_opt(ConstellationControlMsg::SendEvent(
-                    id.clone(), CompositorEvent::ReflowEvent(nodes))))
-            };
-        f
+        box move |&:_, node_address| {
+            let ScriptControlChan(ref chan) = script_chan;
+            debug!("Dirtying {:x}", node_address.0 as uint);
+            let mut nodes = SmallVec1::new();
+            nodes.vec_push(node_address);
+            drop(chan.send(ConstellationControlMsg::SendEvent(
+                id, CompositorEvent::ReflowEvent(nodes))))
+        }
     }
 }
 
 impl LayoutTaskFactory for LayoutTask {
     /// Spawns a new layout task.
     fn create(_phantom: Option<&mut LayoutTask>,
                   id: PipelineId,
                   chan: OpaqueScriptLayoutChannel,
@@ -180,17 +179,17 @@ impl LayoutTaskFactory for LayoutTask {
                   script_chan: ScriptControlChan,
                   paint_chan: PaintChan,
                   resource_task: ResourceTask,
                   img_cache_task: ImageCacheTask,
                   font_cache_task: FontCacheTask,
                   time_profiler_chan: TimeProfilerChan,
                   shutdown_chan: Sender<()>) {
         let ConstellationChan(con_chan) = constellation_chan.clone();
-        spawn_named_with_send_on_failure("LayoutTask", task_state::LAYOUT, proc() {
+        spawn_named_with_send_on_failure("LayoutTask", task_state::LAYOUT, move || {
             { // Ensures layout task is destroyed before we send shutdown message
                 let sender = chan.sender();
                 let layout =
                     LayoutTask::new(
                         id,
                         chan.receiver(),
                         LayoutChan(sender),
                         pipeline_port,
@@ -214,26 +213,27 @@ impl LayoutTaskFactory for LayoutTask {
 enum RWGuard<'a> {
     /// If the lock was previously held, from when the task started.
     Held(MutexGuard<'a, LayoutTaskData>),
     /// If the lock was just used, and has been returned since there has been
     /// a reflow already.
     Used(MutexGuard<'a, LayoutTaskData>),
 }
 
-impl<'a> Deref<LayoutTaskData> for RWGuard<'a> {
+impl<'a> Deref for RWGuard<'a> {
+    type Target = LayoutTaskData;
     fn deref(&self) -> &LayoutTaskData {
         match *self {
             RWGuard::Held(ref x) => &**x,
             RWGuard::Used(ref x) => &**x,
         }
     }
 }
 
-impl<'a> DerefMut<LayoutTaskData> for RWGuard<'a> {
+impl<'a> DerefMut for RWGuard<'a> {
     fn deref_mut(&mut self) -> &mut LayoutTaskData {
         match *self {
             RWGuard::Held(ref mut x) => &mut **x,
             RWGuard::Used(ref mut x) => &mut **x,
         }
     }
 }
 
@@ -252,17 +252,17 @@ impl LayoutTask {
            time_profiler_chan: TimeProfilerChan)
            -> LayoutTask {
         let local_image_cache =
             Arc::new(Mutex::new(LocalImageCache::new(image_cache_task.clone())));
         let screen_size = Size2D(Au(0), Au(0));
         let device = Device::new(MediaType::Screen, opts::get().initial_window_size.as_f32() * ScaleFactor(1.0));
         let parallel_traversal = if opts::get().layout_threads != 1 {
             Some(WorkQueue::new("LayoutWorker", task_state::LAYOUT,
-                                opts::get().layout_threads, ptr::null()))
+                                opts::get().layout_threads, SharedLayoutContextWrapper(ptr::null())))
         } else {
             None
         };
 
         LayoutTask {
             id: id,
             port: port,
             pipeline_port: pipeline_port,
@@ -287,17 +287,17 @@ impl LayoutTask {
                     content_box_response: Rect::zero(),
                     content_boxes_response: Vec::new(),
               })),
         }
     }
 
     /// Starts listening on the port.
     fn start(self) {
-        let mut possibly_locked_rw_data = Some(self.rw_data.lock());
+        let mut possibly_locked_rw_data = Some((*self.rw_data).lock().unwrap());
         while self.handle_request(&mut possibly_locked_rw_data) {
             // Loop indefinitely.
         }
     }
 
     // Create a layout context for use in building display lists, hit testing, &c.
     fn build_shared_layout_context(&self,
                                    rw_data: &LayoutTaskData,
@@ -342,40 +342,40 @@ impl LayoutTask {
                 PortToRead::Pipeline
             } else {
                 panic!("invalid select result");
             }
         };
 
         match port_to_read {
             PortToRead::Pipeline => {
-                match self.pipeline_port.recv() {
+                match self.pipeline_port.recv().unwrap() {
                     LayoutControlMsg::ExitNowMsg(exit_type) => {
                         self.handle_script_request(Msg::ExitNow(exit_type), possibly_locked_rw_data)
                     }
                 }
             },
             PortToRead::Script => {
-                let msg = self.port.recv();
+                let msg = self.port.recv().unwrap();
                 self.handle_script_request(msg, possibly_locked_rw_data)
             }
         }
     }
 
     /// If no reflow has happened yet, this will just return the lock in
     /// `possibly_locked_rw_data`. Otherwise, it will acquire the `rw_data` lock.
     ///
     /// If you do not wish RPCs to remain blocked, just drop the `RWGuard`
     /// returned from this function. If you _do_ wish for them to remain blocked,
     /// use `return_rw_data`.
     fn lock_rw_data<'a>(&'a self,
                         possibly_locked_rw_data: &mut Option<MutexGuard<'a, LayoutTaskData>>)
                         -> RWGuard<'a> {
         match possibly_locked_rw_data.take() {
-            None    => RWGuard::Used(self.rw_data.lock()),
+            None    => RWGuard::Used((*self.rw_data).lock().unwrap()),
             Some(x) => RWGuard::Held(x),
         }
     }
 
     /// If no reflow has ever been triggered, this will keep the lock, locked
     /// (and saved in `possibly_locked_rw_data`). If it has been, the lock will
     /// be unlocked.
     fn return_rw_data<'a>(possibly_locked_rw_data: &mut Option<MutexGuard<'a, LayoutTaskData>>,
@@ -429,17 +429,17 @@ impl LayoutTask {
     /// Enters a quiescent state in which no new messages except for `layout_interface::Msg::ReapLayoutData` will be
     /// processed until an `ExitNowMsg` is received. A pong is immediately sent on the given
     /// response channel.
     fn prepare_to_exit<'a>(&'a self,
                            response_chan: Sender<()>,
                            possibly_locked_rw_data: &mut Option<MutexGuard<'a, LayoutTaskData>>) {
         response_chan.send(());
         loop {
-            match self.port.recv() {
+            match self.port.recv().unwrap() {
                 Msg::ReapLayoutData(dead_layout_data) => {
                     unsafe {
                         LayoutTask::handle_reap_layout_data(dead_layout_data)
                     }
                 }
                 Msg::ExitNow(exit_type) => {
                     debug!("layout task is exiting...");
                     self.exit_now(possibly_locked_rw_data, exit_type);
@@ -465,17 +465,17 @@ impl LayoutTask {
             match (&mut *rw_data).parallel_traversal {
                 None => {}
                 Some(ref mut traversal) => traversal.shutdown(),
             }
             LayoutTask::return_rw_data(possibly_locked_rw_data, rw_data);
         }
 
         self.paint_chan.send(PaintMsg::Exit(Some(response_chan), exit_type));
-        response_port.recv()
+        response_port.recv().unwrap()
     }
 
     fn handle_load_stylesheet<'a>(&'a self,
                                   url: Url,
                                   possibly_locked_rw_data:
                                     &mut Option<MutexGuard<'a, LayoutTaskData>>) {
         // TODO: Get the actual value. http://dev.w3.org/csswg/css-syntax/#environment-encoding
         let environment_encoding = UTF_8 as EncodingRef;
@@ -494,17 +494,17 @@ impl LayoutTask {
 
     fn handle_add_stylesheet<'a>(&'a self,
                                  sheet: Stylesheet,
                                  possibly_locked_rw_data:
                                     &mut Option<MutexGuard<'a, LayoutTaskData>>) {
         // Find all font-face rules and notify the font cache of them.
         // GWTODO: Need to handle unloading web fonts (when we handle unloading stylesheets!)
         let mut rw_data = self.lock_rw_data(possibly_locked_rw_data);
-        iter_font_face_rules(&sheet, &rw_data.stylist.device, |family, src| {
+        iter_font_face_rules(&sheet, &rw_data.stylist.device, &|&:family, src| {
             self.font_cache_task.add_web_font(family.to_owned(), (*src).clone());
         });
         rw_data.stylist.add_stylesheet(sheet);
         LayoutTask::return_rw_data(possibly_locked_rw_data, rw_data);
     }
 
     /// Sets quirks mode for the document, causing the quirks mode stylesheet to be loaded.
     fn handle_set_quirks_mode<'a>(&'a self,
@@ -729,17 +729,17 @@ impl LayoutTask {
         if log_enabled!(log::DEBUG) {
             node.dump();
         }
 
         let mut rw_data = self.lock_rw_data(possibly_locked_rw_data);
 
         {
             // Reset the image cache.
-            let mut local_image_cache = rw_data.local_image_cache.lock();
+            let mut local_image_cache = rw_data.local_image_cache.lock().unwrap();
             local_image_cache.next_round(self.make_on_image_available_cb());
         }
 
         // TODO: Calculate the "actual viewport":
         // http://www.w3.org/TR/css-device-adapt/#actual-viewport
         let viewport_size = data.window_size.initial_viewport;
 
         let old_screen_size = rw_data.screen_size;
@@ -941,33 +941,33 @@ impl LayoutTask {
 
 struct LayoutRPCImpl(Arc<Mutex<LayoutTaskData>>);
 
 impl LayoutRPC for LayoutRPCImpl {
     // The neat thing here is that in order to answer the following two queries we only
     // need to compare nodes for equality. Thus we can safely work only with `OpaqueNode`.
     fn content_box(&self) -> ContentBoxResponse {
         let &LayoutRPCImpl(ref rw_data) = self;
-        let rw_data = rw_data.lock();
+        let rw_data = rw_data.lock().unwrap();
         ContentBoxResponse(rw_data.content_box_response)
     }
 
     /// Requests the dimensions of all the content boxes, as in the `getClientRects()` call.
     fn content_boxes(&self) -> ContentBoxesResponse {
         let &LayoutRPCImpl(ref rw_data) = self;
-        let rw_data = rw_data.lock();
+        let rw_data = rw_data.lock().unwrap();
         ContentBoxesResponse(rw_data.content_boxes_response.clone())
     }
 
     /// Requests the node containing the point of interest.
     fn hit_test(&self, _: TrustedNodeAddress, point: Point2D<f32>) -> Result<HitTestResponse, ()> {
         let point = Point2D(Au::from_frac_px(point.x as f64), Au::from_frac_px(point.y as f64));
         let resp = {
             let &LayoutRPCImpl(ref rw_data) = self;
-            let rw_data = rw_data.lock();
+            let rw_data = rw_data.lock().unwrap();
             match rw_data.stacking_context {
                 None => panic!("no root stacking context!"),
                 Some(ref stacking_context) => {
                     let mut result = Vec::new();
                     stacking_context.hit_test(point, &mut result, true);
                     if !result.is_empty() {
                         Some(HitTestResponse(result[0].node.to_untrusted_node_address()))
                     } else {
@@ -984,17 +984,17 @@ impl LayoutRPC for LayoutRPCImpl {
     }
 
     fn mouse_over(&self, _: TrustedNodeAddress, point: Point2D<f32>)
                   -> Result<MouseOverResponse, ()> {
         let mut mouse_over_list: Vec<DisplayItemMetadata> = vec!();
         let point = Point2D(Au::from_frac_px(point.x as f64), Au::from_frac_px(point.y as f64));
         {
             let &LayoutRPCImpl(ref rw_data) = self;
-            let rw_data = rw_data.lock();
+            let rw_data = rw_data.lock().unwrap();
             match rw_data.stacking_context {
                 None => panic!("no root stacking context!"),
                 Some(ref stacking_context) => {
                     stacking_context.hit_test(point, &mut mouse_over_list, false);
                 }
             }
 
             // Compute the new cursor.
--- a/servo/components/layout/lib.rs
+++ b/servo/components/layout/lib.rs
@@ -1,40 +1,43 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#![feature(globs, macro_rules, phase, thread_local, unsafe_destructor)]
+#![feature(thread_local, unsafe_destructor, box_syntax, plugin, int_uint)]
 
 #![deny(unused_imports)]
 #![deny(unused_variables)]
 #![allow(unrooted_must_root)]
 #![allow(missing_copy_implementations)]
+#![allow(unstable)]
 
-#[phase(plugin, link)]
+#[macro_use]
 extern crate log;
 
 extern crate cssparser;
 extern crate canvas;
 extern crate geom;
 extern crate gfx;
 extern crate layout_traits;
 extern crate script;
 extern crate script_traits;
+extern crate "serialize" as rustc_serialize;
 extern crate serialize;
 extern crate png;
 extern crate style;
-#[phase(plugin)]
+#[macro_use]
+#[no_link] #[plugin]
 extern crate "plugins" as servo_plugins;
 extern crate "net" as servo_net;
 extern crate "msg" as servo_msg;
-#[phase(plugin, link)]
+#[macro_use]
 extern crate "util" as servo_util;
 
-#[phase(plugin)]
+#[no_link] #[macro_use] #[plugin]
 extern crate string_cache_macros;
 extern crate string_cache;
 
 extern crate collections;
 extern crate encoding;
 extern crate libc;
 extern crate url;
 
--- a/servo/components/layout/list_item.rs
+++ b/servo/components/layout/list_item.rs
@@ -19,17 +19,17 @@ use geom::{Point2D, Rect};
 use gfx::display_list::DisplayList;
 use servo_util::geometry::Au;
 use servo_util::opts;
 use style::ComputedValues;
 use style::computed_values::list_style_type;
 use std::sync::Arc;
 
 /// A block with the CSS `display` property equal to `list-item`.
-#[deriving(Show)]
+#[derive(Show)]
 pub struct ListItemFlow {
     /// Data common to all block flows.
     pub block_flow: BlockFlow,
     /// The marker, if outside. (Markers that are inside are instead just fragments on the interior
     /// `InlineFlow`.)
     pub marker: Option<Fragment>,
 }
 
--- a/servo/components/layout/model.rs
+++ b/servo/components/layout/model.rs
@@ -13,17 +13,17 @@ use geom::SideOffsets2D;
 use style::computed_values::{LengthOrPercentageOrAuto, LengthOrPercentage};
 use style::ComputedValues;
 use servo_util::geometry::Au;
 use servo_util::logical_geometry::LogicalMargin;
 use std::cmp::{max, min};
 use std::fmt;
 
 /// A collapsible margin. See CSS 2.1 § 8.3.1.
-#[deriving(Copy)]
+#[derive(Copy)]
 pub struct AdjoiningMargins {
     /// The value of the greatest positive margin.
     pub most_positive: Au,
 
     /// The actual value (not the absolute value) of the negative margin with the largest absolute
     /// value. Since this is not the absolute value, this is always zero or negative.
     pub most_negative: Au,
 }
@@ -56,17 +56,17 @@ impl AdjoiningMargins {
     }
 
     pub fn collapse(&self) -> Au {
         self.most_positive + self.most_negative
     }
 }
 
 /// Represents the block-start and block-end margins of a flow with collapsible margins. See CSS 2.1 § 8.3.1.
-#[deriving(Copy)]
+#[derive(Copy)]
 pub enum CollapsibleMargins {
     /// Margins may not collapse with this flow.
     None(Au, Au),
 
     /// Both the block-start and block-end margins (specified here in that order) may collapse, but the
     /// margins do not collapse through this flow.
     Collapse(AdjoiningMargins, AdjoiningMargins),
 
@@ -234,34 +234,34 @@ impl MarginCollapseInfo {
             (MarginCollapseState::AccumulatingMarginIn, CollapsibleMargins::CollapseThrough(block_end)) => {
                 self.margin_in.union(block_end);
                 Au(0)
             }
         }
     }
 }
 
-#[deriving(Copy)]
+#[derive(Copy)]
 pub enum MarginCollapseState {
     AccumulatingCollapsibleTopMargin,
     AccumulatingMarginIn,
 }
 
 /// Intrinsic inline-sizes, which consist of minimum and preferred.
-#[deriving(Encodable)]
+#[derive(RustcEncodable)]
 pub struct IntrinsicISizes {
     /// The *minimum inline-size* of the content.
     pub minimum_inline_size: Au,
     /// The *preferred inline-size* of the content.
     pub preferred_inline_size: Au,
 }
 
 impl fmt::Show for IntrinsicISizes {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "min={}, pref={}", self.minimum_inline_size, self.preferred_inline_size)
+        write!(f, "min={:?}, pref={:?}", self.minimum_inline_size, self.preferred_inline_size)
     }
 }
 
 impl IntrinsicISizes {
     pub fn new() -> IntrinsicISizes {
         IntrinsicISizes {
             minimum_inline_size: Au(0),
             preferred_inline_size: Au(0),
@@ -320,17 +320,17 @@ impl IntrinsicISizesContribution {
         self.content_intrinsic_sizes.minimum_inline_size =
             max(self.content_intrinsic_sizes.minimum_inline_size, sizes.minimum_inline_size);
         self.content_intrinsic_sizes.preferred_inline_size =
             max(self.content_intrinsic_sizes.preferred_inline_size, sizes.preferred_inline_size)
     }
 }
 
 /// Useful helper data type when computing values for blocks and positioned elements.
-#[deriving(Copy, PartialEq, Show)]
+#[derive(Copy, PartialEq, Show)]
 pub enum MaybeAuto {
     Auto,
     Specified(Au),
 }
 
 impl MaybeAuto {
     #[inline]
     pub fn from_style(length: computed::LengthOrPercentageOrAuto, containing_length: Au)
@@ -353,17 +353,17 @@ impl MaybeAuto {
     }
 
     #[inline]
     pub fn specified_or_zero(&self) -> Au {
         self.specified_or_default(Au::new(0))
     }
 
     #[inline]
-    pub fn map(&self, mapper: |Au| -> Au) -> MaybeAuto {
+    pub fn map<F>(&self, mapper: F) -> MaybeAuto where F: FnOnce(Au) -> Au {
         match *self {
             MaybeAuto::Auto => MaybeAuto::Auto,
             MaybeAuto::Specified(value) => MaybeAuto::Specified(mapper(value)),
         }
     }
 }
 
 pub fn specified_or_none(length: computed::LengthOrPercentageOrNone, containing_length: Au) -> Option<Au> {
--- a/servo/components/layout/parallel.rs
+++ b/servo/components/layout/parallel.rs
@@ -1,17 +1,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 //! Implements parallel traversals over the DOM and flow trees.
 //!
 //! This code is highly unsafe. Keep this file small and easy to audit.
 
-use context::{LayoutContext, SharedLayoutContext};
+use context::{LayoutContext, SharedLayoutContextWrapper, SharedLayoutContext};
 use flow::{Flow, MutableFlowUtils, PreorderFlowTraversal, PostorderFlowTraversal};
 use flow;
 use flow_ref::FlowRef;
 use traversal::{RecalcStyleForNode, ConstructFlows};
 use traversal::{BubbleISizes, AssignISizes, AssignBSizesAndStoreOverflow};
 use traversal::{ComputeAbsolutePositions, BuildDisplayList};
 use util::{LayoutDataAccess, LayoutDataWrapper};
 use wrapper::{layout_node_to_unsafe_layout_node, layout_node_from_unsafe_layout_node, LayoutNode};
@@ -76,27 +76,27 @@ impl DomParallelInfo {
         }
     }
 }
 
 /// A parallel top-down DOM traversal.
 pub trait ParallelPreorderDomTraversal : PreorderDomTraversal {
     fn run_parallel(&self,
                     node: UnsafeLayoutNode,
-                    proxy: &mut WorkerProxy<*const SharedLayoutContext,UnsafeLayoutNode>);
+                    proxy: &mut WorkerProxy<SharedLayoutContextWrapper,UnsafeLayoutNode>);
 
     #[inline(always)]
     fn run_parallel_helper(&self,
                            unsafe_node: UnsafeLayoutNode,
-                           proxy: &mut WorkerProxy<*const SharedLayoutContext,UnsafeLayoutNode>,
+                           proxy: &mut WorkerProxy<SharedLayoutContextWrapper,UnsafeLayoutNode>,
                            top_down_func: extern "Rust" fn(UnsafeFlow,
-                                                           &mut WorkerProxy<*const SharedLayoutContext,
+                                                           &mut WorkerProxy<SharedLayoutContextWrapper,
                                                                             UnsafeLayoutNode>),
                            bottom_up_func: extern "Rust" fn(UnsafeFlow,
-                                                            &mut WorkerProxy<*const SharedLayoutContext,
+                                                            &mut WorkerProxy<SharedLayoutContextWrapper,
                                                                              UnsafeFlow>)) {
         // Get a real layout node.
         let node: LayoutNode = unsafe {
             layout_node_from_unsafe_layout_node(&unsafe_node)
         };
 
         // Perform the appropriate traversal.
         self.process(node);
@@ -136,27 +136,27 @@ trait ParallelPostorderDomTraversal : Po
     /// Thus, if we start with all the leaves of a tree, we end up traversing
     /// the whole tree bottom-up because each parent will be processed exactly
     /// once (by the last child that finishes processing).
     ///
     /// The only communication between siblings is that they both
     /// fetch-and-subtract the parent's children count.
     fn run_parallel(&self,
                     mut unsafe_node: UnsafeLayoutNode,
-                    proxy: &mut WorkerProxy<*const SharedLayoutContext,UnsafeLayoutNode>) {
+                    proxy: &mut WorkerProxy<SharedLayoutContextWrapper,UnsafeLayoutNode>) {
         loop {
             // Get a real layout node.
             let node: LayoutNode = unsafe {
                 layout_node_from_unsafe_layout_node(&unsafe_node)
             };
 
             // Perform the appropriate traversal.
             self.process(node);
 
-            let shared_layout_context = unsafe { &**proxy.user_data() };
+            let shared_layout_context = unsafe { &*(proxy.user_data().0) };
             let layout_context = LayoutContext::new(shared_layout_context);
 
             let parent =
                 match node.layout_parent_node(layout_context.shared) {
                     None         => break,
                     Some(parent) => parent,
                 };
 
@@ -211,17 +211,17 @@ trait ParallelPostorderFlowTraversal : P
     /// Thus, if we start with all the leaves of a tree, we end up traversing
     /// the whole tree bottom-up because each parent will be processed exactly
     /// once (by the last child that finishes processing).
     ///
     /// The only communication between siblings is that they both
     /// fetch-and-subtract the parent's children count.
     fn run_parallel(&self,
                     mut unsafe_flow: UnsafeFlow,
-                    _: &mut WorkerProxy<*const SharedLayoutContext,UnsafeFlow>) {
+                    _: &mut WorkerProxy<SharedLayoutContextWrapper,UnsafeFlow>) {
         loop {
             unsafe {
                 // Get a real flow.
                 let flow: &mut FlowRef = mem::transmute(&unsafe_flow);
 
                 // Perform the appropriate traversal.
                 if self.should_process(&mut **flow) {
                     self.process(&mut **flow);
@@ -256,27 +256,27 @@ trait ParallelPostorderFlowTraversal : P
         }
     }
 }
 
 /// A parallel top-down flow traversal.
 trait ParallelPreorderFlowTraversal : PreorderFlowTraversal {
     fn run_parallel(&self,
                     unsafe_flow: UnsafeFlow,
-                    proxy: &mut WorkerProxy<*const SharedLayoutContext,UnsafeFlow>);
+                    proxy: &mut WorkerProxy<SharedLayoutContextWrapper,UnsafeFlow>);
 
     #[inline(always)]
     fn run_parallel_helper(&self,
                            unsafe_flow: UnsafeFlow,
-                           proxy: &mut WorkerProxy<*const SharedLayoutContext,UnsafeFlow>,
+                           proxy: &mut WorkerProxy<SharedLayoutContextWrapper,UnsafeFlow>,
                            top_down_func: extern "Rust" fn(UnsafeFlow,
-                                                           &mut WorkerProxy<*const SharedLayoutContext,
+                                                           &mut WorkerProxy<SharedLayoutContextWrapper,
                                                                             UnsafeFlow>),
                            bottom_up_func: extern "Rust" fn(UnsafeFlow,
-                                                            &mut WorkerProxy<*const SharedLayoutContext,
+                                                            &mut WorkerProxy<SharedLayoutContextWrapper,
                                                                              UnsafeFlow>)) {
         let mut had_children = false;
         unsafe {
             // Get a real flow.
             let flow: &mut FlowRef = mem::transmute(&unsafe_flow);
 
             if self.should_process(&mut **flow) {
                 // Perform the appropriate traversal.
@@ -301,166 +301,166 @@ trait ParallelPreorderFlowTraversal : Pr
     }
 }
 
 impl<'a> ParallelPostorderFlowTraversal for BubbleISizes<'a> {}
 
 impl<'a> ParallelPreorderFlowTraversal for AssignISizes<'a> {
     fn run_parallel(&self,
                     unsafe_flow: UnsafeFlow,
-                    proxy: &mut WorkerProxy<*const SharedLayoutContext,UnsafeFlow>) {
+                    proxy: &mut WorkerProxy<SharedLayoutContextWrapper,UnsafeFlow>) {
         self.run_parallel_helper(unsafe_flow,
                                  proxy,
                                  assign_inline_sizes,
                                  assign_block_sizes_and_store_overflow)
     }
 }
 
 impl<'a> ParallelPostorderFlowTraversal for AssignBSizesAndStoreOverflow<'a> {}
 
 impl<'a> ParallelPreorderFlowTraversal for ComputeAbsolutePositions<'a> {
     fn run_parallel(&self,
                     unsafe_flow: UnsafeFlow,
-                    proxy: &mut WorkerProxy<*const SharedLayoutContext, UnsafeFlow>) {
+                    proxy: &mut WorkerProxy<SharedLayoutContextWrapper, UnsafeFlow>) {
         self.run_parallel_helper(unsafe_flow,
                                  proxy,
                                  compute_absolute_positions,
                                  build_display_list)
     }
 }
 
 impl<'a> ParallelPostorderFlowTraversal for BuildDisplayList<'a> {}
 
 impl<'a> ParallelPostorderDomTraversal for ConstructFlows<'a> {}
 
 impl <'a> ParallelPreorderDomTraversal for RecalcStyleForNode<'a> {
     fn run_parallel(&self,
                     unsafe_node: UnsafeLayoutNode,
-                    proxy: &mut WorkerProxy<*const SharedLayoutContext, UnsafeLayoutNode>) {
+                    proxy: &mut WorkerProxy<SharedLayoutContextWrapper, UnsafeLayoutNode>) {
         self.run_parallel_helper(unsafe_node,
                                  proxy,
                                  recalc_style,
                                  construct_flows)
     }
 }
 
 fn recalc_style(unsafe_node: UnsafeLayoutNode,
-                proxy: &mut WorkerProxy<*const SharedLayoutContext, UnsafeLayoutNode>) {
-    let shared_layout_context = unsafe { &**proxy.user_data() };
+                proxy: &mut WorkerProxy<SharedLayoutContextWrapper, UnsafeLayoutNode>) {
+    let shared_layout_context = unsafe { &*(proxy.user_data().0) };
     let layout_context = LayoutContext::new(shared_layout_context);
     let recalc_style_for_node_traversal = RecalcStyleForNode {
         layout_context: &layout_context,
     };
     recalc_style_for_node_traversal.run_parallel(unsafe_node, proxy)
 }
 
 fn construct_flows(unsafe_node: UnsafeLayoutNode,
-                   proxy: &mut WorkerProxy<*const SharedLayoutContext, UnsafeLayoutNode>) {
-    let shared_layout_context = unsafe { &**proxy.user_data() };
+                   proxy: &mut WorkerProxy<SharedLayoutContextWrapper, UnsafeLayoutNode>) {
+    let shared_layout_context = unsafe { &*(proxy.user_data().0) };
     let layout_context = LayoutContext::new(shared_layout_context);
     let construct_flows_traversal = ConstructFlows {
         layout_context: &layout_context,
     };
     construct_flows_traversal.run_parallel(unsafe_node, proxy)
 }
 
 fn assign_inline_sizes(unsafe_flow: UnsafeFlow,
-                       proxy: &mut WorkerProxy<*const SharedLayoutContext,UnsafeFlow>) {
-    let shared_layout_context = unsafe { &**proxy.user_data() };
+                       proxy: &mut WorkerProxy<SharedLayoutContextWrapper,UnsafeFlow>) {
+    let shared_layout_context = unsafe { &*(proxy.user_data().0) };
     let layout_context = LayoutContext::new(shared_layout_context);
     let assign_inline_sizes_traversal = AssignISizes {
         layout_context: &layout_context,
     };
     assign_inline_sizes_traversal.run_parallel(unsafe_flow, proxy)
 }
 
 fn assign_block_sizes_and_store_overflow(unsafe_flow: UnsafeFlow,
-                                         proxy: &mut WorkerProxy<*const SharedLayoutContext,UnsafeFlow>) {
-    let shared_layout_context = unsafe { &**proxy.user_data() };
+                                         proxy: &mut WorkerProxy<SharedLayoutContextWrapper,UnsafeFlow>) {
+    let shared_layout_context = unsafe { &*(proxy.user_data().0) };
     let layout_context = LayoutContext::new(shared_layout_context);
     let assign_block_sizes_traversal = AssignBSizesAndStoreOverflow {
         layout_context: &layout_context,
     };
     assign_block_sizes_traversal.run_parallel(unsafe_flow, proxy)
 }
 
 fn compute_absolute_positions(unsafe_flow: UnsafeFlow,
-                              proxy: &mut WorkerProxy<*const SharedLayoutContext, UnsafeFlow>) {
-    let shared_layout_context = unsafe { &**proxy.user_data() };
+                              proxy: &mut WorkerProxy<SharedLayoutContextWrapper, UnsafeFlow>) {
+    let shared_layout_context = unsafe { &*(proxy.user_data().0) };
     let layout_context = LayoutContext::new(shared_layout_context);
     let compute_absolute_positions_traversal = ComputeAbsolutePositions {
         layout_context: &layout_context,
     };
     compute_absolute_positions_traversal.run_parallel(unsafe_flow, proxy);
 }
 
 fn build_display_list(unsafe_flow: UnsafeFlow,
-                      proxy: &mut WorkerProxy<*const SharedLayoutContext, UnsafeFlow>) {
-    let shared_layout_context = unsafe { &**proxy.user_data() };
+                      proxy: &mut WorkerProxy<SharedLayoutContextWrapper, UnsafeFlow>) {
+    let shared_layout_context = unsafe { &*(proxy.user_data().0) };
     let layout_context = LayoutContext::new(shared_layout_context);
 
     let build_display_list_traversal = BuildDisplayList {
         layout_context: &layout_context,
     };
 
     build_display_list_traversal.run_parallel(unsafe_flow, proxy);
 }
 
 pub fn traverse_dom_preorder(root: LayoutNode,
                              shared_layout_context: &SharedLayoutContext,
-                             queue: &mut WorkQueue<*const SharedLayoutContext, UnsafeLayoutNode>) {
-    queue.data = shared_layout_context as *const _;
+                             queue: &mut WorkQueue<SharedLayoutContextWrapper, UnsafeLayoutNode>) {
+    queue.data = SharedLayoutContextWrapper(shared_layout_context as *const _);
 
     queue.push(WorkUnit {
         fun:  recalc_style,
         data: layout_node_to_unsafe_layout_node(&root),
     });
 
     queue.run();
 
-    queue.data = ptr::null();
+    queue.data = SharedLayoutContextWrapper(ptr::null());
 }
 
 pub fn traverse_flow_tree_preorder(root: &mut FlowRef,
                                    profiler_metadata: ProfilerMetadata,
                                    time_profiler_chan: TimeProfilerChan,
                                    shared_layout_context: &SharedLayoutContext,
-                                   queue: &mut WorkQueue<*const SharedLayoutContext,UnsafeFlow>) {
+                                   queue: &mut WorkQueue<SharedLayoutContextWrapper,UnsafeFlow>) {
     if opts::get().bubble_inline_sizes_separately {
         let layout_context = LayoutContext::new(shared_layout_context);
         let bubble_inline_sizes = BubbleISizes { layout_context: &layout_context };
         root.traverse_postorder(&bubble_inline_sizes);
     }
 
-    queue.data = shared_layout_context as *const _;
+    queue.data = SharedLayoutContextWrapper(shared_layout_context as *const _);
 
     profile(TimeProfilerCategory::LayoutParallelWarmup, profiler_metadata,
             time_profiler_chan, || {
         queue.push(WorkUnit {
             fun: assign_inline_sizes,
             data: mut_owned_flow_to_unsafe_flow(root),
         })
     });
 
     queue.run();
 
-    queue.data = ptr::null()
+    queue.data = SharedLayoutContextWrapper(ptr::null())
 }
 
 pub fn build_display_list_for_subtree(root: &mut FlowRef,
                                       profiler_metadata: ProfilerMetadata,
                                       time_profiler_chan: TimeProfilerChan,
                                       shared_layout_context: &SharedLayoutContext,
-                                      queue: &mut WorkQueue<*const SharedLayoutContext,UnsafeFlow>) {
-    queue.data = shared_layout_context as *const _;
+                                      queue: &mut WorkQueue<SharedLayoutContextWrapper,UnsafeFlow>) {
+    queue.data = SharedLayoutContextWrapper(shared_layout_context as *const _);
 
     profile(TimeProfilerCategory::LayoutParallelWarmup, profiler_metadata,
             time_profiler_chan, || {
         queue.push(WorkUnit {
             fun: compute_absolute_positions,
             data: mut_owned_flow_to_unsafe_flow(root),
         })
     });
 
     queue.run();
 
-    queue.data = ptr::null()
+    queue.data = SharedLayoutContextWrapper(ptr::null())
 }
--- a/servo/components/layout/table.rs
+++ b/servo/components/layout/table.rs
@@ -27,17 +27,17 @@ use std::cmp::max;
 use std::fmt;
 use style::{ComputedValues, CSSFloat};
 use style::computed_values::{LengthOrPercentageOrAuto, table_layout};
 use std::sync::Arc;
 
 /// A table flow corresponded to the table's internal table fragment under a table wrapper flow.
 /// The properties `position`, `float`, and `margin-*` are used on the table wrapper fragment,
 /// not table fragment per CSS 2.1 § 10.5.
-#[deriving(Encodable)]
+#[derive(RustcEncodable)]
 pub struct TableFlow {
     pub block_flow: BlockFlow,
 
     /// Information about the intrinsic inline-sizes of each column, computed bottom-up during
     /// intrinsic inline-size bubbling.
     pub column_intrinsic_inline_sizes: Vec<ColumnIntrinsicInlineSize>,
 
     /// Information about the actual inline-sizes of each column, computed top-down during actual
@@ -394,17 +394,17 @@ impl Flow for TableFlow {
                                              stacking_context_position: &Point2D<Au>) {
         self.block_flow.iterate_through_fragment_border_boxes(iterator, stacking_context_position)
     }
 }
 
 impl fmt::Show for TableFlow {
     /// Outputs a debugging string describing this table flow.
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "TableFlow: {}", self.block_flow)
+        write!(f, "TableFlow: {:?}", self.block_flow)
     }
 }
 
 /// Table, TableRowGroup, TableRow, TableCell types.
 /// Their inline-sizes are calculated in the same way and do not have margins.
 pub struct InternalTable;
 
 impl ISizeAndMarginsComputer for InternalTable {
@@ -436,17 +436,17 @@ impl ISizeAndMarginsComputer for Interna
 /// specific width constraint. For instance, one cell might say that it wants to be 100 pixels wide
 /// in the inline direction and another cell might say that it wants to take up 20% of the inline-
 /// size of the table. Now because we bubble up these constraints during the bubble-inline-sizes
 /// phase of layout, we don't know yet how wide the table is ultimately going to be in the inline
 /// direction. As we need to pick the maximum width of all cells for a column (in this case, the
 /// maximum of 100 pixels and 20% of the table), the preceding constraint means that we must
 /// potentially store both a specified width *and* a specified percentage, so that the inline-size
 /// assignment phase of layout will know which one to pick.
-#[deriving(Clone, Encodable, Show, Copy)]
+#[derive(Clone, RustcEncodable, Show, Copy)]
 pub struct ColumnIntrinsicInlineSize {
     /// The preferred intrinsic inline size.
     pub preferred: Au,
     /// The largest specified size of this column as a length.
     pub minimum_length: Au,
     /// The largest specified size of this column as a percentage (`width` property).
     pub percentage: CSSFloat,
     /// Whether the column inline size is *constrained* per INTRINSIC § 4.1.
@@ -480,13 +480,13 @@ impl ColumnIntrinsicInlineSize {
         }
     }
 }
 
 /// The actual inline size for each column.
 ///
 /// TODO(pcwalton): There will probably be some `border-collapse`-related info in here too
 /// eventually.
-#[deriving(Encodable, Copy)]
+#[derive(RustcEncodable, Copy)]
 pub struct ColumnComputedInlineSize {
     /// The computed size of this inline column.
     pub size: Au,
 }
--- a/servo/components/layout/table_caption.rs
+++ b/servo/components/layout/table_caption.rs
@@ -90,11 +90,11 @@ impl Flow for TableCaptionFlow {
                                              iterator: &mut FragmentBorderBoxIterator,
                                              stacking_context_position: &Point2D<Au>) {
         self.block_flow.iterate_through_fragment_border_boxes(iterator, stacking_context_position)
     }
 }
 
 impl fmt::Show for TableCaptionFlow {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "TableCaptionFlow: {}", self.block_flow)
+        write!(f, "TableCaptionFlow: {:?}", self.block_flow)
     }
 }
--- a/servo/components/layout/table_cell.rs
+++ b/servo/components/layout/table_cell.rs
@@ -17,17 +17,17 @@ use wrapper::ThreadSafeLayoutNode;
 
 use geom::{Point2D, Rect};
 use servo_util::geometry::Au;
 use std::fmt;
 use style::{UnsignedIntegerAttribute, ComputedValues};
 use std::sync::Arc;
 
 /// A table formatting context.
-#[deriving(Encodable)]
+#[derive(RustcEncodable)]
 pub struct TableCellFlow {
     /// Data common to all block flows.
     pub block_flow: BlockFlow,
     /// The column span of this cell.
     pub column_span: u32,
     /// Whether this cell is visible. If false, the value of `empty-cells` means that we must not
     /// display this cell.
     pub visible: bool,
@@ -171,11 +171,11 @@ impl Flow for TableCellFlow {
                                              iterator: &mut FragmentBorderBoxIterator,
                                              stacking_context_position: &Point2D<Au>) {
         self.block_flow.iterate_through_fragment_border_boxes(iterator, stacking_context_position)
     }
 }
 
 impl fmt::Show for TableCellFlow {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "TableCellFlow: {}", self.block_flow)
+        write!(f, "TableCellFlow: {:?}", self.block_flow)
     }
 }
--- a/servo/components/layout/table_colgroup.rs
+++ b/servo/components/layout/table_colgroup.rs
@@ -104,13 +104,13 @@ impl Flow for TableColGroupFlow {
     fn iterate_through_fragment_border_boxes(&self,
                                              _: &mut FragmentBorderBoxIterator,
                                              _: &Point2D<Au>) {}
 }
 
 impl fmt::Show for TableColGroupFlow {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match self.fragment {
-            Some(ref rb) => write!(f, "TableColGroupFlow: {}", rb),
+            Some(ref rb) => write!(f, "TableColGroupFlow: {:?}", rb),
             None => write!(f, "TableColGroupFlow"),
         }
     }
 }
--- a/servo/components/layout/table_row.rs
+++ b/servo/components/layout/table_row.rs
@@ -22,29 +22,29 @@ use geom::{Point2D, Rect};
 use servo_util::geometry::Au;
 use std::cmp::max;
 use std::fmt;
 use style::ComputedValues;
 use style::computed_values::LengthOrPercentageOrAuto;
 use std::sync::Arc;
 
 /// A single row of a table.
-#[deriving(Encodable)]
+#[derive(RustcEncodable)]
 pub struct TableRowFlow {
     pub block_flow: BlockFlow,
 
     /// Information about the intrinsic inline-sizes of each cell.
     pub cell_intrinsic_inline_sizes: Vec<CellIntrinsicInlineSize>,
 
     /// Information about the computed inline-sizes of each column.
     pub column_computed_inline_sizes: Vec<ColumnComputedInlineSize>,
 }
 
 /// Information about the column inline size and span for each cell.
-#[deriving(Encodable, Copy)]
+#[derive(RustcEncodable, Copy)]
 pub struct CellIntrinsicInlineSize {
     /// Inline sizes that this cell contributes to the column.
     pub column_size: ColumnIntrinsicInlineSize,
     /// The column span of this cell.
     pub column_span: u32,
 }
 
 impl TableRowFlow {
@@ -324,11 +324,11 @@ impl Flow for TableRowFlow {
                                              iterator: &mut FragmentBorderBoxIterator,
                                              stacking_context_position: &Point2D<Au>) {
         self.block_flow.iterate_through_fragment_border_boxes(iterator, stacking_context_position)
     }
 }
 
 impl fmt::Show for TableRowFlow {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "TableRowFlow: {}", self.block_flow.fragment)
+        write!(f, "TableRowFlow: {:?}", self.block_flow.fragment)
     }
 }
--- a/servo/components/layout/table_rowgroup.rs
+++ b/servo/components/layout/table_rowgroup.rs
@@ -17,17 +17,17 @@ use wrapper::ThreadSafeLayoutNode;
 
 use geom::{Point2D, Rect};
 use servo_util::geometry::Au;
 use std::fmt;
 use style::ComputedValues;
 use std::sync::Arc;
 
 /// A table formatting context.
-#[deriving(Encodable)]
+#[derive(RustcEncodable)]
 pub struct TableRowGroupFlow {
     /// Fields common to all block flows.
     pub block_flow: BlockFlow,
 
     /// Information about the intrinsic inline-sizes of each column.
     pub column_intrinsic_inline_sizes: Vec<ColumnIntrinsicInlineSize>,
 
     /// Information about the actual inline sizes of each column.
@@ -159,11 +159,11 @@ impl Flow for TableRowGroupFlow {
                                              iterator: &mut FragmentBorderBoxIterator,
                                              stacking_context_position: &Point2D<Au>) {
         self.block_flow.iterate_through_fragment_border_boxes(iterator, stacking_context_position)
     }
 }
 
 impl fmt::Show for TableRowGroupFlow {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "TableRowGroupFlow: {}", self.block_flow.fragment)
+        write!(f, "TableRowGroupFlow: {:?}", self.block_flow.fragment)
     }
 }
--- a/servo/components/layout/table_wrapper.rs
+++ b/servo/components/layout/table_wrapper.rs
@@ -22,28 +22,29 @@ use flow::{IMPACTED_BY_LEFT_FLOATS, IMPA
 use fragment::{Fragment, FragmentBorderBoxIterator};
 use table::{ColumnComputedInlineSize, ColumnIntrinsicInlineSize};
 use wrapper::ThreadSafeLayoutNode;
 
 use geom::{Point2D, Rect};
 use servo_util::geometry::Au;
 use std::cmp::{max, min};
 use std::fmt;
+use std::ops::Add;
 use style::{ComputedValues, CSSFloat};
 use style::computed_values::{table_layout, LengthOrPercentageOrAuto};
 use std::sync::Arc;
 
-#[deriving(Copy, Encodable, Show)]
+#[derive(Copy, RustcEncodable, Show)]
 pub enum TableLayout {
     Fixed,
     Auto
 }
 
 /// A table wrapper flow based on a block formatting context.
-#[deriving(Encodable)]
+#[derive(RustcEncodable)]
 pub struct TableWrapperFlow {
     pub block_flow: BlockFlow,
 
     /// Intrinsic column inline sizes according to INTRINSIC § 4.1
     pub column_intrinsic_inline_sizes: Vec<ColumnIntrinsicInlineSize>,
 
     /// Table-layout property
     pub table_layout: TableLayout,
@@ -139,21 +140,21 @@ impl TableWrapperFlow {
             // to correspond with CSS 2.1 § 17.5.2.2 under "Column and caption widths
             // influence the final table width as follows: ..."
             _ => available_inline_size,
         };
 
         // Compute all the guesses for the column sizes, and sum them.
         let mut total_guess = AutoLayoutCandidateGuess::new();
         let guesses: Vec<AutoLayoutCandidateGuess> =
-            self.column_intrinsic_inline_sizes.iter().map(|column_intrinsic_inline_size| {
+            self.column_intrinsic_inline_sizes.iter().map(|&mut:column_intrinsic_inline_size| {
                 let guess = AutoLayoutCandidateGuess::from_column_intrinsic_inline_size(
                     column_intrinsic_inline_size,
                     available_inline_size);
-                total_guess = total_guess + guess;
+                total_guess = &total_guess + &guess;
                 guess
             }).collect();
 
         // Assign inline sizes.
         let selection = SelectedAutoLayoutCandidateGuess::select(&total_guess,
                                                                  available_inline_size);
         let mut total_used_inline_size = Au(0);
         for (intermediate_column_inline_size, guess) in
@@ -378,19 +379,19 @@ impl Flow for TableWrapperFlow {
                                              stacking_context_position: &Point2D<Au>) {
         self.block_flow.iterate_through_fragment_border_boxes(iterator, stacking_context_position)
     }
 }
 
 impl fmt::Show for TableWrapperFlow {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         if self.block_flow.base.flags.is_float() {
-            write!(f, "TableWrapperFlow(Float): {}", self.block_flow.fragment)
+            write!(f, "TableWrapperFlow(Float): {:?}", self.block_flow.fragment)
         } else {
-            write!(f, "TableWrapperFlow: {}", self.block_flow.fragment)
+            write!(f, "TableWrapperFlow: {:?}", self.block_flow.fragment)
         }
     }
 }
 
 /// The layout "guesses" defined in INTRINSIC § 4.3.
 struct AutoLayoutCandidateGuess {
     /// The column inline-size assignment where each column is assigned its intrinsic minimum
     /// inline-size.
@@ -477,32 +478,33 @@ impl AutoLayoutCandidateGuess {
             }
             SelectedAutoLayoutCandidateGuess::UsePreferredGuessAndDistributeExcessInlineSize => {
                 self.preferred_guess
             }
         }
     }
 }
 
-impl Add<AutoLayoutCandidateGuess,AutoLayoutCandidateGuess> for AutoLayoutCandidateGuess {
+impl<'a> Add for &'a AutoLayoutCandidateGuess {
+    type Output = AutoLayoutCandidateGuess;
     #[inline]
-    fn add(&self, other: &AutoLayoutCandidateGuess) -> AutoLayoutCandidateGuess {
+    fn add(self, other: &AutoLayoutCandidateGuess) -> AutoLayoutCandidateGuess {
         AutoLayoutCandidateGuess {
             minimum_guess: self.minimum_guess + other.minimum_guess,
             minimum_percentage_guess:
                 self.minimum_percentage_guess + other.minimum_percentage_guess,
             minimum_specified_guess: self.minimum_specified_guess + other.minimum_specified_guess,
             preferred_guess: self.preferred_guess + other.preferred_guess,
         }
     }
 }
 
 /// The `CSSFloat` member specifies the weight of the smaller of the two guesses, on a scale from
 /// 0.0 to 1.0.
-#[deriving(Copy, PartialEq, Show)]
+#[derive(Copy, PartialEq, Show)]
 enum SelectedAutoLayoutCandidateGuess {
     UseMinimumGuess,
     InterpolateBetweenMinimumGuessAndMinimumPercentageGuess(CSSFloat),
     InterpolateBetweenMinimumPercentageGuessAndMinimumSpecifiedGuess(CSSFloat),
     InterpolateBetweenMinimumSpecifiedGuessAndPreferredGuess(CSSFloat),
     UsePreferredGuessAndDistributeExcessInlineSize,
 }
 
--- a/servo/components/layout/text.rs
+++ b/servo/components/layout/text.rs
@@ -190,23 +190,23 @@ impl TextRunScanner {
 
         // Make new fragments with the run and adjusted text indices.
         debug!("TextRunScanner: pushing {} fragment(s)", self.clump.len());
         for (logical_offset, old_fragment) in
                 mem::replace(&mut self.clump, DList::new()).into_iter().enumerate() {
             let range = *new_ranges.get(logical_offset);
             if range.is_empty() {
                 debug!("Elided an `SpecificFragmentInfo::UnscannedText` because it was zero-length after \
-                        compression; {}",
+                        compression; {:?}",
                        old_fragment);
                 continue
             }
 
             let text_size = old_fragment.border_box.size;
-            let &NewLinePositions(ref mut new_line_positions) =
+            let &mut NewLinePositions(ref mut new_line_positions) =
                 new_line_positions.get_mut(logical_offset);
             let new_text_fragment_info =
                 box ScannedTextFragmentInfo::new(run.clone(),
                                                  range,
                                                  mem::replace(new_line_positions, Vec::new()),
                                                  text_size);
             let new_metrics = new_text_fragment_info.run.metrics_for_range(&range);
             let bounding_box_size = bounding_box_for_run_metrics(&new_metrics,
--- a/servo/components/layout/traversal.rs
+++ b/servo/components/layout/traversal.rs
@@ -43,17 +43,17 @@ type Generation = uint;
 /// rejected.
 ///
 /// When done styling a node, all selectors previously inserted into the filter
 /// are removed.
 ///
 /// Since a work-stealing queue is used for styling, sometimes, the bloom filter
 /// will no longer be the for the parent of the node we're currently on. When
 /// this happens, the task local bloom filter will be thrown away and rebuilt.
-thread_local!(static STYLE_BLOOM: RefCell<Option<(Box<BloomFilter>, UnsafeLayoutNode, Generation)>> = RefCell::new(None))
+thread_local!(static STYLE_BLOOM: RefCell<Option<(Box<BloomFilter>, UnsafeLayoutNode, Generation)>> = RefCell::new(None));
 
 /// Returns the task local bloom filter.
 ///
 /// If one does not exist, a new one will be made for you. If it is out of date,
 /// it will be thrown out and a new one will be made for you.
 fn take_task_local_bloom_filter(parent_node: Option<LayoutNode>, layout_context: &LayoutContext)
                                 -> Box<BloomFilter> {
     STYLE_BLOOM.with(|style_bloom| {
@@ -69,17 +69,17 @@ fn take_task_local_bloom_filter(parent_n
                 insert_ancestors_into_bloom_filter(&mut bloom_filter, parent, layout_context);
                 bloom_filter
             }
             // Found cached bloom filter.
             (Some(parent), Some((mut bloom_filter, old_node, old_generation))) => {
                 // Hey, the cached parent is our parent! We can reuse the bloom filter.
                 if old_node == layout_node_to_unsafe_layout_node(&parent) &&
                     old_generation == layout_context.shared.generation {
-                    debug!("[{}] Parent matches (={}). Reusing bloom filter.", tid(), old_node.val0());
+                    debug!("[{}] Parent matches (={}). Reusing bloom filter.", tid(), old_node.0);
                     bloom_filter.clone()
                 } else {
                     // Oh no. the cached parent is stale. I guess we need a new one. Reuse the existing
                     // allocation to avoid malloc churn.
                     *bloom_filter = BloomFilter::new();
                     insert_ancestors_into_bloom_filter(&mut bloom_filter, parent, layout_context);
                     bloom_filter
                 }
@@ -115,17 +115,17 @@ fn insert_ancestors_into_bloom_filter(bf
             Some(p) => p,
         };
     }
     debug!("[{}] Inserted {} ancestors.", tid(), ancestors);