servo: Merge #4405 - Update rustc to revision 3dcd2157403163789aaf21a9ab3c4d30a7c6494d (from servo:rustup_20141124); r=jdm
authorGlenn Watson <gw@intuitionlibrary.com>
Wed, 17 Dec 2014 18:45:49 -0700
changeset 382114 89d19cc1484e35200aefe2fe1860519cbd4d8e0a
parent 382113 12a9c85c9ccd074b5db3b8abc48434f73ba13094
child 382115 9a8843f2eedc10b63a43a867b522cdb85da54f32
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 #4405 - Update rustc to revision 3dcd2157403163789aaf21a9ab3c4d30a7c6494d (from servo:rustup_20141124); r=jdm Source-Repo: https://github.com/servo/servo Source-Revision: fbf42c951b2f53d91e2f32f8035484a07ea83493
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/scrolling.rs
servo/components/compositing/windowing.rs
servo/components/devtools/actors/console.rs
servo/components/devtools/actors/inspector.rs
servo/components/gfx/Cargo.toml
servo/components/gfx/display_list/mod.rs
servo/components/gfx/font_cache_task.rs
servo/components/gfx/paint_context.rs
servo/components/gfx/paint_task.rs
servo/components/gfx/platform/freetype/font.rs
servo/components/gfx/platform/macos/font.rs
servo/components/gfx/text/glyph.rs
servo/components/gfx/text/util.rs
servo/components/layout/block.rs
servo/components/layout/construct.rs
servo/components/layout/css/matching.rs
servo/components/layout/css/node_style.rs
servo/components/layout/display_list_builder.rs
servo/components/layout/floats.rs
servo/components/layout/flow.rs
servo/components/layout/fragment.rs
servo/components/layout/inline.rs
servo/components/layout/layout_task.rs
servo/components/layout/list_item.rs
servo/components/layout/model.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/msg/constellation_msg.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/holder.rs
servo/components/net/image_cache_task.rs
servo/components/net/local_image_cache.rs
servo/components/net/resource_task.rs
servo/components/net/storage_task.rs
servo/components/plugins/lints.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/codegen/CodegenRust.py
servo/components/script/dom/bindings/conversions.rs
servo/components/script/dom/bindings/global.rs
servo/components/script/dom/bindings/str.rs
servo/components/script/dom/bindings/utils.rs
servo/components/script/dom/blob.rs
servo/components/script/dom/characterdata.rs
servo/components/script/dom/comment.rs
servo/components/script/dom/create.rs
servo/components/script/dom/customevent.rs
servo/components/script/dom/dedicatedworkerglobalscope.rs
servo/components/script/dom/document.rs
servo/components/script/dom/documentfragment.rs
servo/components/script/dom/documenttype.rs
servo/components/script/dom/domexception.rs
servo/components/script/dom/domimplementation.rs
servo/components/script/dom/domparser.rs
servo/components/script/dom/domrect.rs
servo/components/script/dom/domtokenlist.rs
servo/components/script/dom/element.rs
servo/components/script/dom/errorevent.rs
servo/components/script/dom/event.rs
servo/components/script/dom/eventdispatcher.rs
servo/components/script/dom/eventtarget.rs
servo/components/script/dom/file.rs
servo/components/script/dom/formdata.rs
servo/components/script/dom/htmlanchorelement.rs
servo/components/script/dom/htmlappletelement.rs
servo/components/script/dom/htmlareaelement.rs
servo/components/script/dom/htmlaudioelement.rs
servo/components/script/dom/htmlbaseelement.rs
servo/components/script/dom/htmlbodyelement.rs
servo/components/script/dom/htmlbrelement.rs
servo/components/script/dom/htmlbuttonelement.rs
servo/components/script/dom/htmlcanvaselement.rs
servo/components/script/dom/htmlcollection.rs
servo/components/script/dom/htmldataelement.rs
servo/components/script/dom/htmldatalistelement.rs
servo/components/script/dom/htmldirectoryelement.rs
servo/components/script/dom/htmldivelement.rs
servo/components/script/dom/htmldlistelement.rs
servo/components/script/dom/htmlelement.rs
servo/components/script/dom/htmlembedelement.rs
servo/components/script/dom/htmlfieldsetelement.rs
servo/components/script/dom/htmlfontelement.rs
servo/components/script/dom/htmlformelement.rs
servo/components/script/dom/htmlframeelement.rs
servo/components/script/dom/htmlframesetelement.rs
servo/components/script/dom/htmlheadelement.rs
servo/components/script/dom/htmlheadingelement.rs
servo/components/script/dom/htmlhrelement.rs
servo/components/script/dom/htmlhtmlelement.rs
servo/components/script/dom/htmliframeelement.rs
servo/components/script/dom/htmlimageelement.rs
servo/components/script/dom/htmlinputelement.rs
servo/components/script/dom/htmllabelelement.rs
servo/components/script/dom/htmllegendelement.rs
servo/components/script/dom/htmllielement.rs
servo/components/script/dom/htmllinkelement.rs
servo/components/script/dom/htmlmapelement.rs
servo/components/script/dom/htmlmediaelement.rs
servo/components/script/dom/htmlmetaelement.rs
servo/components/script/dom/htmlmeterelement.rs
servo/components/script/dom/htmlmodelement.rs
servo/components/script/dom/htmlobjectelement.rs
servo/components/script/dom/htmlolistelement.rs
servo/components/script/dom/htmloptgroupelement.rs
servo/components/script/dom/htmloptionelement.rs
servo/components/script/dom/htmloutputelement.rs
servo/components/script/dom/htmlparagraphelement.rs
servo/components/script/dom/htmlparamelement.rs
servo/components/script/dom/htmlpreelement.rs
servo/components/script/dom/htmlprogresselement.rs
servo/components/script/dom/htmlquoteelement.rs
servo/components/script/dom/htmlscriptelement.rs
servo/components/script/dom/htmlselectelement.rs
servo/components/script/dom/htmlserializer.rs
servo/components/script/dom/htmlsourceelement.rs
servo/components/script/dom/htmlspanelement.rs
servo/components/script/dom/htmlstyleelement.rs
servo/components/script/dom/htmltablecaptionelement.rs
servo/components/script/dom/htmltablecellelement.rs
servo/components/script/dom/htmltablecolelement.rs
servo/components/script/dom/htmltabledatacellelement.rs
servo/components/script/dom/htmltableelement.rs
servo/components/script/dom/htmltableheadercellelement.rs
servo/components/script/dom/htmltablerowelement.rs
servo/components/script/dom/htmltablesectionelement.rs
servo/components/script/dom/htmltemplateelement.rs
servo/components/script/dom/htmltextareaelement.rs
servo/components/script/dom/htmltimeelement.rs
servo/components/script/dom/htmltitleelement.rs
servo/components/script/dom/htmltrackelement.rs
servo/components/script/dom/htmlulistelement.rs
servo/components/script/dom/htmlunknownelement.rs
servo/components/script/dom/htmlvideoelement.rs
servo/components/script/dom/keyboardevent.rs
servo/components/script/dom/messageevent.rs
servo/components/script/dom/mouseevent.rs
servo/components/script/dom/node.rs
servo/components/script/dom/nodelist.rs
servo/components/script/dom/processinginstruction.rs
servo/components/script/dom/progressevent.rs
servo/components/script/dom/testbinding.rs
servo/components/script/dom/text.rs
servo/components/script/dom/treewalker.rs
servo/components/script/dom/uievent.rs
servo/components/script/dom/urlsearchparams.rs
servo/components/script/dom/virtualmethods.rs
servo/components/script/dom/websocket.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/dom/xmlhttprequestupload.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/textinput.rs
servo/components/script/timers.rs
servo/components/servo/Cargo.lock
servo/components/servo/Cargo.toml
servo/components/servo/lib.rs
servo/components/servo/main.rs
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/properties/common_types.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/util/Cargo.toml
servo/components/util/bloom.rs
servo/components/util/geometry.rs
servo/components/util/memory.rs
servo/components/util/opts.rs
servo/components/util/range.rs
servo/components/util/rtinstrument.rs
servo/components/util/smallvec.rs
servo/components/util/str.rs
servo/components/util/task.rs
servo/components/util/time.rs
servo/components/util/workqueue.rs
servo/ports/cef/Cargo.lock
servo/ports/cef/browser.rs
servo/ports/cef/browser_host.rs
servo/ports/cef/core.rs
servo/ports/cef/frame.rs
servo/ports/cef/render_handler.rs
servo/ports/cef/window.rs
servo/ports/glfw/Cargo.toml
servo/ports/glfw/window.rs
servo/ports/glutin/Cargo.toml
servo/ports/glutin/window.rs
servo/ports/gonk/Cargo.lock
servo/ports/gonk/Cargo.toml
servo/rust-snapshot-hash
servo/tests/reftest.rs
--- a/servo/components/canvas/canvas_paint_task.rs
+++ b/servo/components/canvas/canvas_paint_task.rs
@@ -37,21 +37,21 @@ impl CanvasPaintTask {
 
     pub fn start(size: Size2D<i32>) -> Sender<CanvasMsg> {
         let (chan, port) = comm::channel::<CanvasMsg>();
         spawn_named("CanvasTask", proc() {
             let mut painter = CanvasPaintTask::new(size);
 
             loop {
                 match port.recv() {
-                    FillRect(ref rect) => painter.fill_rect(rect),
-                    StrokeRect(ref rect) => painter.stroke_rect(rect),
-                    ClearRect(ref rect) => painter.clear_rect(rect),
-                    Recreate(size) => painter.recreate(size),
-                    Close => break,
+                    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::Close => break,
                 }
             }
         });
         chan
     }
 
     fn fill_rect(&self, rect: &Rect<f32>) {
         let drawopts = DrawOptions::new(1.0, 0);
--- a/servo/components/compositing/Cargo.toml
+++ b/servo/components/compositing/Cargo.toml
@@ -49,8 +49,11 @@ 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"
--- a/servo/components/compositing/compositor.rs
+++ b/servo/components/compositing/compositor.rs
@@ -1,31 +1,20 @@
 /* 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 compositor_layer::{CompositorData, CompositorLayer, DoesntWantScrollEvents};
-use compositor_layer::{WantsScrollEvents};
-use compositor_task;
-use compositor_task::{ChangePageLoadData, ChangePageTitle, ChangePaintState, ChangeReadyState};
-use compositor_task::{CompositorEventListener, CompositorProxy, CompositorReceiver};
-use compositor_task::{CompositorTask, CreateOrUpdateDescendantLayer, CreateOrUpdateRootLayer};
-use compositor_task::{Exit, FrameTreeUpdateMsg, GetGraphicsMetadata, LayerProperties};
-use compositor_task::{LoadComplete, Msg, Paint, PaintMsgDiscarded, ScrollFragmentPoint};
-use compositor_task::{ScrollTimeout, SetIds, SetLayerOrigin, ShutdownComplete};
+use compositor_layer::{CompositorData, CompositorLayer, WantsScrollEventsFlag};
+use compositor_task::{CompositorEventListener, CompositorProxy, CompositorReceiver, CompositorTask};
+use compositor_task::{LayerProperties, Msg};
 use constellation::{FrameId, FrameTreeDiff, SendableFrameTree};
 use pipeline::CompositionPipeline;
 use scrolling::ScrollingTimerProxy;
 use windowing;
-use windowing::{IdleWindowEvent, InitializeCompositingWindowEvent};
-use windowing::{KeyEvent, LoadUrlWindowEvent, MouseWindowClickEvent, MouseWindowEvent};
-use windowing::{MouseWindowEventClass, MouseWindowMouseDownEvent, MouseWindowMouseUpEvent};
-use windowing::{MouseWindowMoveEventClass, NavigationWindowEvent, PinchZoomWindowEvent};
-use windowing::{QuitWindowEvent, RefreshWindowEvent, ResizeWindowEvent, ScrollWindowEvent};
-use windowing::{WindowEvent, WindowMethods, WindowNavigateMsg, ZoomWindowEvent};
+use windowing::{MouseWindowEvent, WindowEvent, WindowMethods, WindowNavigateMsg};
 
 use azure::azure_hl;
 use std::cmp;
 use std::mem;
 use std::num::Zero;
 use geom::point::{Point2D, TypedPoint2D};
 use geom::rect::{Rect, TypedRect};
 use geom::size::TypedSize2D;
@@ -49,16 +38,17 @@ use servo_msg::constellation_msg::{Windo
 use servo_util::geometry::{PagePx, ScreenPx, ViewportPx};
 use servo_util::memory::MemoryProfilerChan;
 use servo_util::opts;
 use servo_util::time::{profile, TimeProfilerChan};
 use servo_util::{memory, time};
 use std::collections::HashMap;
 use std::collections::hash_map::{Occupied, Vacant};
 use std::path::Path;
+use std::num::FloatMath;
 use std::rc::Rc;
 use std::slice::bytes::copy_memory;
 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.
@@ -187,19 +177,19 @@ impl<Window: WindowMethods> IOCompositor
             root_pipeline: None,
             scene: Scene::new(Rect {
                 origin: Zero::zero(),
                 size: window_size.as_f32(),
             }),
             window_size: window_size,
             hidpi_factor: hidpi_factor,
             scrolling_timer: ScrollingTimerProxy::new(sender),
-            composition_request: NoCompositingNecessary,
+            composition_request: CompositionRequest::NoCompositingNecessary,
             pending_scroll_events: Vec::new(),
-            shutdown_state: NotShuttingDown,
+            shutdown_state: ShutdownState::NotShuttingDown,
             page_zoom: ScaleFactor(1.0),
             viewport_zoom: ScaleFactor(1.0),
             zoom_action: false,
             zoom_time: 0f64,
             ready_states: HashMap::new(),
             paint_states: HashMap::new(),
             got_load_complete_message: false,
             got_set_ids_message: false,
@@ -232,124 +222,131 @@ impl<Window: WindowMethods> IOCompositor
         // Tell the constellation about the initial window size.
         compositor.send_window_size();
 
         compositor
     }
 
     fn handle_browser_message(&mut self, msg: Msg) -> bool {
         match (msg, self.shutdown_state) {
-            (_, FinishedShuttingDown) =>
+            (_, ShutdownState::FinishedShuttingDown) =>
                 panic!("compositor shouldn't be handling messages after shutting down"),
 
-            (Exit(chan), _) => {
+            (Msg::Exit(chan), _) => {
                 debug!("shutting down the constellation");
                 let ConstellationChan(ref con_chan) = self.constellation_chan;
                 con_chan.send(ExitMsg);
                 chan.send(());
-                self.shutdown_state = ShuttingDown;
+                self.shutdown_state = ShutdownState::ShuttingDown;
             }
 
-            (ShutdownComplete, _) => {
+            (Msg::ShutdownComplete, _) => {
                 debug!("constellation completed shutdown");
-                self.shutdown_state = FinishedShuttingDown;
+                self.shutdown_state = ShutdownState::FinishedShuttingDown;
                 return false;
             }
 
-            (ChangeReadyState(pipeline_id, ready_state), NotShuttingDown) => {
+            (Msg::ChangeReadyState(pipeline_id, ready_state), ShutdownState::NotShuttingDown) => {
                 self.change_ready_state(pipeline_id, ready_state);
             }
 
-            (ChangePaintState(pipeline_id, paint_state), NotShuttingDown) => {
+            (Msg::ChangePaintState(pipeline_id, paint_state), ShutdownState::NotShuttingDown) => {
                 self.change_paint_state(pipeline_id, paint_state);
             }
 
-            (ChangePageTitle(pipeline_id, title), NotShuttingDown) => {
+            (Msg::ChangePageTitle(pipeline_id, title), ShutdownState::NotShuttingDown) => {
                 self.change_page_title(pipeline_id, title);
             }
 
-            (ChangePageLoadData(frame_id, load_data), NotShuttingDown) => {
+            (Msg::ChangePageLoadData(frame_id, load_data), ShutdownState::NotShuttingDown) => {
                 self.change_page_load_data(frame_id, load_data);
             }
 
-            (PaintMsgDiscarded, NotShuttingDown) => {
+            (Msg::PaintMsgDiscarded, ShutdownState::NotShuttingDown) => {
                 self.remove_outstanding_paint_msg();
             }
 
-            (SetIds(frame_tree, response_chan, new_constellation_chan), NotShuttingDown) => {
+            (Msg::SetIds(frame_tree, response_chan, new_constellation_chan),
+             ShutdownState::NotShuttingDown) => {
                 self.set_frame_tree(&frame_tree,
                                     response_chan,
                                     new_constellation_chan);
                 self.send_viewport_rects_for_all_layers();
             }
 
-            (FrameTreeUpdateMsg(frame_tree_diff, response_channel), NotShuttingDown) => {
+            (Msg::FrameTreeUpdate(frame_tree_diff, response_channel),
+             ShutdownState::NotShuttingDown) => {
                 self.update_frame_tree(&frame_tree_diff);
                 response_channel.send(());
             }
 
-            (CreateOrUpdateRootLayer(layer_properties), NotShuttingDown) => {
+            (Msg::CreateOrUpdateRootLayer(layer_properties), ShutdownState::NotShuttingDown) => {
                 self.create_or_update_root_layer(layer_properties);
             }
 
-            (CreateOrUpdateDescendantLayer(layer_properties), NotShuttingDown) => {
+            (Msg::CreateOrUpdateDescendantLayer(layer_properties),
+             ShutdownState::NotShuttingDown) => {
                 self.create_or_update_descendant_layer(layer_properties);
             }
 
-            (GetGraphicsMetadata(chan), NotShuttingDown) => {
+            (Msg::GetGraphicsMetadata(chan), ShutdownState::NotShuttingDown) => {
                 chan.send(Some(self.window.native_metadata()));
             }
 
-            (SetLayerOrigin(pipeline_id, layer_id, origin), NotShuttingDown) => {
+            (Msg::SetLayerOrigin(pipeline_id, layer_id, origin),
+             ShutdownState::NotShuttingDown) => {
                 self.set_layer_origin(pipeline_id, layer_id, origin);
             }
 
-            (Paint(pipeline_id, epoch, replies), NotShuttingDown) => {
+            (Msg::Paint(pipeline_id, epoch, replies), ShutdownState::NotShuttingDown) => {
                 for (layer_id, new_layer_buffer_set) in replies.into_iter() {
                     self.paint(pipeline_id, layer_id, new_layer_buffer_set, epoch);
                 }
                 self.remove_outstanding_paint_msg();
             }
 
-            (ScrollFragmentPoint(pipeline_id, layer_id, point), NotShuttingDown) => {
+            (Msg::ScrollFragmentPoint(pipeline_id, layer_id, point),
+             ShutdownState::NotShuttingDown) => {
                 self.scroll_fragment_to_point(pipeline_id, layer_id, point);
             }
 
-            (LoadComplete, NotShuttingDown) => {
+            (Msg::LoadComplete, ShutdownState::NotShuttingDown) => {
                 self.got_load_complete_message = true;
 
                 // If we're painting in headless mode, schedule a recomposite.
                 if opts::get().output_file.is_some() {
                     self.composite_if_necessary();
                 }
 
                 // Inform the embedder that the load has finished.
                 //
                 // TODO(pcwalton): Specify which frame's load completed.
                 self.window.load_end();
             }
 
-            (ScrollTimeout(timestamp), NotShuttingDown) => {
+            (Msg::ScrollTimeout(timestamp), ShutdownState::NotShuttingDown) => {
                 debug!("scroll timeout, drawing unpainted content!");
                 match self.composition_request {
-                    CompositeOnScrollTimeout(this_timestamp) if timestamp == this_timestamp => {
-                        self.composition_request = CompositeNow
+                    CompositionRequest::CompositeOnScrollTimeout(this_timestamp) => {
+                        if timestamp == this_timestamp {
+                            self.composition_request = CompositionRequest::CompositeNow
+                        }
                     }
                     _ => {}
                 }
             }
 
-            (compositor_task::KeyEvent(key, modified), NotShuttingDown) => {
+            (Msg::KeyEvent(key, modified), ShutdownState::NotShuttingDown) => {
                 self.window.handle_key(key, modified);
             }
 
             // When we are shutting_down, we need to avoid performing operations
             // such as Paint that may crash because we have begun tearing down
             // the rest of our resources.
-            (_, ShuttingDown) => { }
+            (_, ShutdownState::ShuttingDown) => { }
         }
 
         true
     }
 
     fn change_ready_state(&mut self, pipeline_id: PipelineId, ready_state: ReadyState) {
         match self.ready_states.entry(pipeline_id) {
             Occupied(entry) => {
@@ -497,20 +494,21 @@ impl<Window: WindowMethods> IOCompositor
 
     fn create_or_update_root_layer(&mut self, layer_properties: LayerProperties) {
         let need_new_root_layer = !self.update_layer_if_exists(layer_properties);
         if need_new_root_layer {
             let root_layer = self.find_pipeline_root_layer(layer_properties.pipeline_id);
             root_layer.update_layer_except_size(layer_properties);
 
             let root_layer_pipeline = root_layer.extra_data.borrow().pipeline.clone();
-            let first_child = CompositorData::new_layer(root_layer_pipeline.clone(),
-                                                        layer_properties,
-                                                        DoesntWantScrollEvents,
-                                                        opts::get().tile_size);
+            let first_child = CompositorData::new_layer(
+                root_layer_pipeline.clone(),
+                layer_properties,
+                WantsScrollEventsFlag::DoesntWantScrollEvents,
+                opts::get().tile_size);
 
             // Add the first child / base layer to the front of the child list, so that
             // child iframe layers are painted on top of the base layer. These iframe
             // layers were added previously when creating the layer tree skeleton in
             // create_frame_tree_root_layers.
             root_layer.children().insert(0, first_child);
         }
 
@@ -528,17 +526,17 @@ impl<Window: WindowMethods> IOCompositor
         self.send_buffer_requests_for_all_layers();
     }
 
     fn create_descendant_layer(&self, layer_properties: LayerProperties) {
         let root_layer = self.find_pipeline_root_layer(layer_properties.pipeline_id);
         let root_layer_pipeline = root_layer.extra_data.borrow().pipeline.clone();
         let new_layer = CompositorData::new_layer(root_layer_pipeline,
                                                   layer_properties,
-                                                  DoesntWantScrollEvents,
+                                                  WantsScrollEventsFlag::DoesntWantScrollEvents,
                                                   root_layer.tile_size);
         root_layer.add_child(new_layer);
     }
 
     fn send_window_size(&self) {
         let dppx = self.page_zoom * self.device_pixels_per_screen_px();
         let initial_viewport = self.window_size.as_f32() / dppx;
         let visible_viewport = initial_viewport / self.viewport_zoom;
@@ -553,17 +551,17 @@ impl<Window: WindowMethods> IOCompositor
 
     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) {
             Some(ref layer) => {
-                if layer.extra_data.borrow().wants_scroll_events == WantsScrollEvents {
+                if layer.wants_scroll_events() == WantsScrollEventsFlag::WantsScrollEvents {
                     layer.clamp_scroll_offset_and_scroll_layer(TypedPoint2D(0f32, 0f32) - origin);
                 }
                 true
             }
             None => false,
         }
     }
 
@@ -579,23 +577,24 @@ impl<Window: WindowMethods> IOCompositor
                 self.start_scrolling_timer_if_necessary();
             }
             None => {}
         }
     }
 
     fn start_scrolling_timer_if_necessary(&mut self) {
         match self.composition_request {
-            CompositeNow | CompositeOnScrollTimeout(_) => return,
-            NoCompositingNecessary => {}
+            CompositionRequest::CompositeNow | CompositionRequest::CompositeOnScrollTimeout(_) =>
+                return,
+            CompositionRequest::NoCompositingNecessary => {}
         }
 
         let timestamp = precise_time_ns();
         self.scrolling_timer.scroll_event_processed(timestamp);
-        self.composition_request = CompositeOnScrollTimeout(timestamp);
+        self.composition_request = CompositionRequest::CompositeOnScrollTimeout(timestamp);
     }
 
     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) => {
@@ -646,67 +645,67 @@ impl<Window: WindowMethods> IOCompositor
             }
         } else {
             self.fragment_point = Some(point);
         }
     }
 
     fn handle_window_message(&mut self, event: WindowEvent) {
         match event {
-            IdleWindowEvent => {}
+            WindowEvent::Idle => {}
 
-            RefreshWindowEvent => {
+            WindowEvent::Refresh => {
                 self.composite();
             }
 
-            InitializeCompositingWindowEvent => {
+            WindowEvent::InitializeCompositing => {
                 self.initialize_compositing();
             }
 
-            ResizeWindowEvent(size) => {
+            WindowEvent::Resize(size) => {
                 self.on_resize_window_event(size);
             }
 
-            LoadUrlWindowEvent(url_string) => {
+            WindowEvent::LoadUrl(url_string) => {
                 self.on_load_url_window_event(url_string);
             }
 
-            MouseWindowEventClass(mouse_window_event) => {
+            WindowEvent::MouseWindowEventClass(mouse_window_event) => {
                 self.on_mouse_window_event_class(mouse_window_event);
             }
 
-            MouseWindowMoveEventClass(cursor) => {
+            WindowEvent::MouseWindowMoveEventClass(cursor) => {
                 self.on_mouse_window_move_event_class(cursor);
             }
 
-            ScrollWindowEvent(delta, cursor) => {
+            WindowEvent::Scroll(delta, cursor) => {
                 self.on_scroll_window_event(delta, cursor);
             }
 
-            ZoomWindowEvent(magnification) => {
+            WindowEvent::Zoom(magnification) => {
                 self.on_zoom_window_event(magnification);
             }
 
-            PinchZoomWindowEvent(magnification) => {
+            WindowEvent::PinchZoom(magnification) => {
                 self.on_pinch_zoom_window_event(magnification);
             }
 
-            NavigationWindowEvent(direction) => {
+            WindowEvent::Navigation(direction) => {
                 self.on_navigation_window_event(direction);
             }
 
-            KeyEvent(key, state, modifiers) => {
+            WindowEvent::KeyEvent(key, state, modifiers) => {
                 self.on_key_event(key, state, modifiers);
             }
 
-            QuitWindowEvent => {
-                debug!("shutting down the constellation for QuitWindowEvent");
+            WindowEvent::Quit => {
+                debug!("shutting down the constellation for WindowEvent::Quit");
                 let ConstellationChan(ref chan) = self.constellation_chan;
                 chan.send(ExitMsg);
-                self.shutdown_state = ShuttingDown;
+                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());
 
         // A size change could also mean a resolution change.
@@ -726,31 +725,31 @@ impl<Window: WindowMethods> IOCompositor
         self.send_window_size();
     }
 
     fn on_load_url_window_event(&mut self, url_string: String) {
         debug!("osmain: loading URL `{:s}`", url_string);
         self.got_load_complete_message = false;
         let root_pipeline_id = match self.scene.root {
             Some(ref layer) => layer.extra_data.borrow().pipeline.id.clone(),
-            None => panic!("Compositor: Received LoadUrlWindowEvent without initialized compositor \
+            None => panic!("Compositor: Received WindowEvent::LoadUrl without initialized compositor \
                            layers"),
         };
 
         let msg = LoadUrlMsg(root_pipeline_id,
                              LoadData::new(Url::parse(url_string.as_slice()).unwrap()));
         let ConstellationChan(ref chan) = self.constellation_chan;
         chan.send(msg);
     }
 
     fn on_mouse_window_event_class(&self, mouse_window_event: MouseWindowEvent) {
         let point = match mouse_window_event {
-            MouseWindowClickEvent(_, p) => p,
-            MouseWindowMouseDownEvent(_, p) => p,
-            MouseWindowMouseUpEvent(_, p) => p,
+            MouseWindowEvent::MouseWindowClickEvent(_, p) => p,
+            MouseWindowEvent::MouseWindowMouseDownEvent(_, p) => p,
+            MouseWindowEvent::MouseWindowMouseUpEvent(_, p) => p,
         };
         match self.find_topmost_layer_at_point(point / self.scene.scale) {
             Some(result) => result.layer.send_mouse_event(mouse_window_event, result.point),
             None => {},
         }
     }
 
     fn on_mouse_window_move_event_class(&self, cursor: TypedPoint2D<DevicePixel, f32>) {
@@ -848,18 +847,18 @@ impl<Window: WindowMethods> IOCompositor
         }
 
         self.send_viewport_rects_for_all_layers();
         self.composite_if_necessary();
     }
 
     fn on_navigation_window_event(&self, direction: WindowNavigateMsg) {
         let direction = match direction {
-            windowing::Forward => constellation_msg::Forward,
-            windowing::Back => constellation_msg::Back,
+            windowing::WindowNavigateMsg::Forward => constellation_msg::Forward,
+            windowing::WindowNavigateMsg::Back => constellation_msg::Back,
         };
         let ConstellationChan(ref chan) = self.constellation_chan;
         chan.send(NavigateMsg(direction))
     }
 
     fn on_key_event(&self, key: Key, state: KeyState, modifiers: KeyModifiers) {
         let ConstellationChan(ref chan) = self.constellation_chan;
         chan.send(constellation_msg::KeyEvent(key, state, modifiers))
@@ -1072,31 +1071,31 @@ impl<Window: WindowMethods> IOCompositor
                 pixels: png::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(ExitMsg);
-            self.shutdown_state = ShuttingDown;
+            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();
 
-        self.composition_request = NoCompositingNecessary;
+        self.composition_request = CompositionRequest::NoCompositingNecessary;
         self.process_pending_scroll_events();
     }
 
     fn composite_if_necessary(&mut self) {
-        if self.composition_request == NoCompositingNecessary {
-            self.composition_request = CompositeNow
+        if self.composition_request == CompositionRequest::NoCompositingNecessary {
+            self.composition_request = CompositionRequest::CompositeNow
         }
     }
 
     fn initialize_compositing(&mut self) {
         let context = CompositorTask::create_graphics_context(&self.window.native_metadata());
         let show_debug_borders = opts::get().show_debug_borders;
         self.context = Some(rendergl::RenderContext::new(context, show_debug_borders))
     }
@@ -1203,17 +1202,17 @@ fn create_root_layer_for_pipeline_and_re
         id: LayerId::null(),
         rect: Rect::zero(),
         background_color: azure_hl::Color::new(0., 0., 0., 0.),
         scroll_policy: Scrollable,
     };
 
     let root_layer = CompositorData::new_layer(pipeline.clone(),
                                                layer_properties,
-                                               WantsScrollEvents,
+                                               WantsScrollEventsFlag::WantsScrollEvents,
                                                opts::get().tile_size);
 
     // All root layers mask to bounds.
     *root_layer.masks_to_bounds.borrow_mut() = true;
 
     match frame_rect {
         Some(ref frame_rect) => {
             let frame_rect = frame_rect.to_untyped();
@@ -1234,17 +1233,17 @@ impl<Window> CompositorEventListener for
                 Some(msg) => {
                     if !self.handle_browser_message(msg) {
                         break
                     }
                 }
             }
         }
 
-        if self.shutdown_state == FinishedShuttingDown {
+        if self.shutdown_state == ShutdownState::FinishedShuttingDown {
             // We have exited the compositor and passing window
             // messages to script may crash.
             debug!("Exiting the compositor due to a request from script.");
             return false;
         }
 
         // Handle the message coming from the windowing system.
         self.handle_window_message(msg);
@@ -1252,32 +1251,32 @@ impl<Window> CompositorEventListener for
         // If a pinch-zoom happened recently, ask for tiles at the new resolution
         if self.zoom_action && precise_time_s() - self.zoom_time > 0.3 {
             self.zoom_action = false;
             self.scene.mark_layer_contents_as_changed_recursively();
             self.send_buffer_requests_for_all_layers();
         }
 
         match self.composition_request {
-            NoCompositingNecessary | CompositeOnScrollTimeout(_) => {}
-            CompositeNow => self.composite(),
+            CompositionRequest::NoCompositingNecessary | CompositionRequest::CompositeOnScrollTimeout(_) => {}
+            CompositionRequest::CompositeNow => self.composite(),
         }
 
-        self.shutdown_state != FinishedShuttingDown
+        self.shutdown_state != ShutdownState::FinishedShuttingDown
     }
 
     /// Repaints and recomposites synchronously. You must be careful when calling this, as if a
     /// paint is not scheduled the compositor will hang forever.
     ///
     /// This is used when resizing the window.
     fn repaint_synchronously(&mut self) {
-        while self.shutdown_state != ShuttingDown {
+        while self.shutdown_state != ShutdownState::ShuttingDown {
             let msg = self.port.recv_compositor_msg();
             let is_paint = match msg {
-                Paint(..) => true,
+                Msg::Paint(..) => true,
                 _ => false,
             };
             let keep_going = self.handle_browser_message(msg);
             if is_paint {
                 self.composite();
                 break
             }
             if !keep_going {
@@ -1294,20 +1293,20 @@ impl<Window> CompositorEventListener for
         }
 
         // Drain compositor port, sometimes messages contain channels that are blocking
         // another task from finishing (i.e. SetIds)
         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::ExitMsg);
+        time_profiler_chan.send(time::TimeProfilerMsg::Exit);
 
         let MemoryProfilerChan(ref memory_profiler_chan) = self.memory_profiler_chan;
-        memory_profiler_chan.send(memory::ExitMsg);
+        memory_profiler_chan.send(memory::MemoryProfilerMsg::Exit);
 
         self.scrolling_timer.shutdown();
     }
 
     fn pinch_zoom_level(&self) -> f32 {
         self.viewport_zoom.get() as f32
     }
 
--- a/servo/components/compositing/compositor_layer.rs
+++ b/servo/components/compositing/compositor_layer.rs
@@ -1,32 +1,32 @@
 /* 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 compositor_task::LayerProperties;
 use pipeline::CompositionPipeline;
-use windowing::{MouseWindowEvent, MouseWindowClickEvent, MouseWindowMouseDownEvent};
-use windowing::MouseWindowMouseUpEvent;
-use windowing::WindowMethods;
+use windowing::{MouseWindowEvent, WindowMethods};
 
 use azure::azure_hl;
 use geom::length::Length;
 use geom::matrix::identity;
 use geom::point::{Point2D, TypedPoint2D};
 use geom::size::{Size2D, TypedSize2D};
 use geom::rect::Rect;
 use gfx::paint_task::UnusedBufferMsg;
 use layers::color::Color;
 use layers::geometry::LayerPixel;
 use layers::layers::{Layer, LayerBufferSet};
 use layers::platform::surface::NativeSurfaceMethods;
 use script_traits::{ClickEvent, MouseDownEvent, MouseMoveEvent, MouseUpEvent, SendEventMsg};
 use script_traits::{ScriptControlChan};
 use servo_msg::compositor_msg::{Epoch, FixedPosition, LayerId, ScrollPolicy};
+use std::num::Float;
+use std::num::FloatMath;
 use std::rc::Rc;
 
 pub struct CompositorData {
     /// This layer's pipeline. BufferRequests and mouse events will be sent through this.
     pub pipeline: CompositionPipeline,
 
     /// The ID of this layer within the pipeline.
     pub id: LayerId,
@@ -112,16 +112,19 @@ pub trait CompositorLayer {
 
     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;
 }
 
 #[deriving(PartialEq, Clone)]
 pub enum WantsScrollEventsFlag {
     WantsScrollEvents,
     DoesntWantScrollEvents,
 }
 
@@ -255,28 +258,28 @@ impl CompositorLayer for Layer<Composito
     }
 
     fn handle_scroll_event(&self,
                            delta: TypedPoint2D<LayerPixel, f32>,
                            cursor: TypedPoint2D<LayerPixel, f32>)
                            -> ScrollEventResult {
         // If this layer doesn't want scroll events, neither it nor its children can handle scroll
         // events.
-        if self.extra_data.borrow().wants_scroll_events != WantsScrollEvents {
-            return ScrollEventUnhandled;
+        if self.wants_scroll_events() != WantsScrollEventsFlag::WantsScrollEvents {
+            return ScrollEventResult::ScrollEventUnhandled;
         }
 
         //// Allow children to scroll.
         let scroll_offset = self.extra_data.borrow().scroll_offset;
         let new_cursor = cursor - scroll_offset;
         for child in self.children().iter() {
             let child_bounds = child.bounds.borrow();
             if child_bounds.contains(&new_cursor) {
                 let result = child.handle_scroll_event(delta, new_cursor - child_bounds.origin);
-                if result != ScrollEventUnhandled {
+                if result != ScrollEventResult::ScrollEventUnhandled {
                     return result;
                 }
             }
         }
 
         self.clamp_scroll_offset_and_scroll_layer(scroll_offset + delta)
     }
 
@@ -287,43 +290,46 @@ impl CompositorLayer for Layer<Composito
         let content_size = calculate_content_size_for_layer(self);
         let min_x = (layer_size.width - content_size.width).get().min(0.0);
         let min_y = (layer_size.height - content_size.height).get().min(0.0);
         let new_offset : TypedPoint2D<LayerPixel, f32> =
             Point2D(Length(new_offset.x.get().clamp(&min_x, &0.0)),
                     Length(new_offset.y.get().clamp(&min_y, &0.0)));
 
         if self.extra_data.borrow().scroll_offset == new_offset {
-            return ScrollPositionUnchanged;
+            return ScrollEventResult::ScrollPositionUnchanged;
         }
 
         // The scroll offset is just a record of the scroll position of this scrolling root,
         // but scroll_layer_and_all_child_layers actually moves the child layers.
         self.extra_data.borrow_mut().scroll_offset = new_offset;
 
         let mut result = false;
         for child in self.children().iter() {
             result |= child.scroll_layer_and_all_child_layers(new_offset);
         }
 
         if result {
-            return ScrollPositionChanged;
+            return ScrollEventResult::ScrollPositionChanged;
         } else {
-            return ScrollPositionUnchanged;
+            return ScrollEventResult::ScrollPositionUnchanged;
         }
     }
 
     fn send_mouse_event(&self,
                         event: MouseWindowEvent,
                         cursor: TypedPoint2D<LayerPixel, f32>) {
         let event_point = cursor.to_untyped();
         let message = match event {
-            MouseWindowClickEvent(button, _) => ClickEvent(button, event_point),
-            MouseWindowMouseDownEvent(button, _) => MouseDownEvent(button, event_point),
-            MouseWindowMouseUpEvent(button, _) => MouseUpEvent(button, event_point),
+            MouseWindowEvent::MouseWindowClickEvent(button, _) =>
+                ClickEvent(button, event_point),
+            MouseWindowEvent::MouseWindowMouseDownEvent(button, _) =>
+                MouseDownEvent(button, event_point),
+            MouseWindowEvent::MouseWindowMouseUpEvent(button, _) =>
+                MouseUpEvent(button, event_point),
         };
         let pipeline = &self.extra_data.borrow().pipeline;
         let ScriptControlChan(ref chan) = pipeline.script_chan;
         let _ = chan.send_opt(SendEventMsg(pipeline.id.clone(), message));
     }
 
     fn send_mouse_move_event(&self,
                              cursor: TypedPoint2D<LayerPixel, f32>) {
@@ -351,9 +357,13 @@ impl CompositorLayer for Layer<Composito
         let offset_for_children = new_offset + self.extra_data.borrow().scroll_offset;
         for child in self.children().iter() {
             result |= child.scroll_layer_and_all_child_layers(offset_for_children);
         }
 
         return result;
     }
 
+    fn wants_scroll_events(&self) -> WantsScrollEventsFlag {
+        self.extra_data.borrow().wants_scroll_events
+    }
+
 }
--- a/servo/components/compositing/compositor_task.rs
+++ b/servo/components/compositing/compositor_task.rs
@@ -57,44 +57,44 @@ impl CompositorReceiver for Receiver<Msg
     fn recv_compositor_msg(&mut self) -> Msg {
         self.recv()
     }
 }
 
 /// 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 = ChangeReadyState(pipeline_id, ready_state);
+        let msg = Msg::ChangeReadyState(pipeline_id, ready_state);
         self.send(msg);
     }
 
     fn scroll_fragment_point(&mut self,
                              pipeline_id: PipelineId,
                              layer_id: LayerId,
                              point: Point2D<f32>) {
-        self.send(ScrollFragmentPoint(pipeline_id, layer_id, point));
+        self.send(Msg::ScrollFragmentPoint(pipeline_id, layer_id, point));
     }
 
     fn close(&mut self) {
         let (chan, port) = channel();
-        self.send(Exit(chan));
+        self.send(Msg::Exit(chan));
         port.recv();
     }
 
     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(ChangePageTitle(pipeline_id, title))
+        self.send(Msg::ChangePageTitle(pipeline_id, title))
     }
 
     fn send_key_event(&mut self, key: Key, state: KeyState, modifiers: KeyModifiers) {
         if state == Pressed {
-            self.send(KeyEvent(key, modifiers));
+            self.send(Msg::KeyEvent(key, modifiers));
         }
     }
 }
 
 /// Information about each layer that the compositor keeps.
 pub struct LayerProperties {
     pub pipeline_id: PipelineId,
     pub epoch: Epoch,
@@ -119,52 +119,52 @@ 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(GetGraphicsMetadata(chan));
+        self.send(Msg::GetGraphicsMetadata(chan));
         port.recv()
     }
 
     fn paint(&mut self,
              pipeline_id: PipelineId,
              epoch: Epoch,
              replies: Vec<(LayerId, Box<LayerBufferSet>)>) {
-        self.send(Paint(pipeline_id, epoch, replies));
+        self.send(Msg::Paint(pipeline_id, epoch, replies));
     }
 
     fn initialize_layers_for_pipeline(&mut self,
                                       pipeline_id: PipelineId,
                                       metadata: Vec<LayerMetadata>,
                                       epoch: Epoch) {
         // FIXME(#2004, pcwalton): This assumes that the first layer determines the page size, and
         // that all other layers are immediate children of it. This is sufficient to handle
         // `position: fixed` but will not be sufficient to handle `overflow: scroll` or transforms.
         let mut first = true;
         for metadata in metadata.iter() {
             let layer_properties = LayerProperties::new(pipeline_id, epoch, metadata);
             if first {
-                self.send(CreateOrUpdateRootLayer(layer_properties));
+                self.send(Msg::CreateOrUpdateRootLayer(layer_properties));
                 first = false
             } else {
-                self.send(CreateOrUpdateDescendantLayer(layer_properties));
+                self.send(Msg::CreateOrUpdateDescendantLayer(layer_properties));
             }
         }
     }
 
     fn paint_msg_discarded(&mut self) {
-        self.send(PaintMsgDiscarded);
+        self.send(Msg::PaintMsgDiscarded);
     }
 
     fn set_paint_state(&mut self, pipeline_id: PipelineId, paint_state: PaintState) {
-        self.send(ChangePaintState(pipeline_id, paint_state))
+        self.send(Msg::ChangePaintState(pipeline_id, paint_state))
     }
 }
 
 /// Messages from the painting task and the constellation task to the compositor task.
 pub enum Msg {
     /// Requests that the compositor shut down.
     Exit(Sender<()>),
 
@@ -200,47 +200,47 @@ pub enum Msg {
     ChangePageTitle(PipelineId, Option<String>),
     /// Alerts the compositor that the current page has changed its load data (including URL).
     ChangePageLoadData(FrameId, LoadData),
     /// Alerts the compositor that a `PaintMsg` has been discarded.
     PaintMsgDiscarded,
     /// Sets the channel to the current layout and paint tasks, along with their ID.
     SetIds(SendableFrameTree, Sender<()>, ConstellationChan),
     /// Sends an updated version of the frame tree.
-    FrameTreeUpdateMsg(FrameTreeDiff, Sender<()>),
+    FrameTreeUpdate(FrameTreeDiff, Sender<()>),
     /// The load of a page has completed.
     LoadComplete,
     /// Indicates that the scrolling timeout with the given starting timestamp has happened and a
     /// composite should happen. (See the `scrolling` module.)
     ScrollTimeout(u64),
     /// Sends an unconsumed key event back to the compositor.
     KeyEvent(Key, KeyModifiers),
 }
 
 impl Show for Msg {
     fn fmt(&self, f: &mut Formatter) -> Result<(),FormatError> {
         match *self {
-            Exit(..) => write!(f, "Exit"),
-            ShutdownComplete(..) => write!(f, "ShutdownComplete"),
-            GetGraphicsMetadata(..) => write!(f, "GetGraphicsMetadata"),
-            CreateOrUpdateRootLayer(..) => write!(f, "CreateOrUpdateRootLayer"),
-            CreateOrUpdateDescendantLayer(..) => write!(f, "CreateOrUpdateDescendantLayer"),
-            SetLayerOrigin(..) => write!(f, "SetLayerOrigin"),
-            ScrollFragmentPoint(..) => write!(f, "ScrollFragmentPoint"),
-            Paint(..) => write!(f, "Paint"),
-            ChangeReadyState(..) => write!(f, "ChangeReadyState"),
-            ChangePaintState(..) => write!(f, "ChangePaintState"),
-            ChangePageTitle(..) => write!(f, "ChangePageTitle"),
-            ChangePageLoadData(..) => write!(f, "ChangePageLoadData"),
-            PaintMsgDiscarded(..) => write!(f, "PaintMsgDiscarded"),
-            SetIds(..) => write!(f, "SetIds"),
-            FrameTreeUpdateMsg(..) => write!(f, "FrameTreeUpdateMsg"),
-            LoadComplete => write!(f, "LoadComplete"),
-            ScrollTimeout(..) => write!(f, "ScrollTimeout"),
-            KeyEvent(..) => write!(f, "KeyEvent"),
+            Msg::Exit(..) => write!(f, "Exit"),
+            Msg::ShutdownComplete(..) => write!(f, "ShutdownComplete"),
+            Msg::GetGraphicsMetadata(..) => write!(f, "GetGraphicsMetadata"),
+            Msg::CreateOrUpdateRootLayer(..) => write!(f, "CreateOrUpdateRootLayer"),
+            Msg::CreateOrUpdateDescendantLayer(..) => write!(f, "CreateOrUpdateDescendantLayer"),
+            Msg::SetLayerOrigin(..) => write!(f, "SetLayerOrigin"),
+            Msg::ScrollFragmentPoint(..) => write!(f, "ScrollFragmentPoint"),
+            Msg::Paint(..) => write!(f, "Paint"),
+            Msg::ChangeReadyState(..) => write!(f, "ChangeReadyState"),
+            Msg::ChangePaintState(..) => write!(f, "ChangePaintState"),
+            Msg::ChangePageTitle(..) => write!(f, "ChangePageTitle"),
+            Msg::ChangePageLoadData(..) => write!(f, "ChangePageLoadData"),
+            Msg::PaintMsgDiscarded(..) => write!(f, "PaintMsgDiscarded"),
+            Msg::SetIds(..) => write!(f, "SetIds"),
+            Msg::FrameTreeUpdate(..) => write!(f, "FrameTreeUpdateMsg"),
+            Msg::LoadComplete => write!(f, "LoadComplete"),
+            Msg::ScrollTimeout(..) => write!(f, "ScrollTimeout"),
+            Msg::KeyEvent(..) => write!(f, "KeyEvent"),
         }
     }
 }
 
 pub struct CompositorTask;
 
 impl CompositorTask {
     /// Creates a graphics context. Platform-specific.
--- a/servo/components/compositing/constellation.rs
+++ b/servo/components/compositing/constellation.rs
@@ -1,35 +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/. */
 
 use pipeline::{Pipeline, CompositionPipeline};
 
-use compositor_task::{ChangePageLoadData, ChangePageTitle, CompositorProxy, FrameTreeUpdateMsg};
-use compositor_task::{LoadComplete, SetLayerOrigin, SetIds, ShutdownComplete};
+use compositor_task::CompositorProxy;
+use compositor_task::Msg as CompositorMsg;
 use devtools_traits;
 use devtools_traits::DevtoolsControlChan;
 use geom::rect::{Rect, TypedRect};
 use geom::scale_factor::ScaleFactor;
 use gfx::font_cache_task::FontCacheTask;
 use gfx::paint_task;
 use layers::geometry::DevicePixel;
 use layout_traits::{LayoutControlChan, LayoutTaskFactory, ExitNowMsg};
 use libc;
 use script_traits::{mod, GetTitleMsg, ResizeMsg, ResizeInactiveMsg, ExitPipelineMsg, SendEventMsg};
 use script_traits::{ScriptControlChan, ScriptTaskFactory};
 use servo_msg::compositor_msg::LayerId;
 use servo_msg::constellation_msg::{ConstellationChan, ExitMsg, FailureMsg, Failure, FrameRectMsg};
 use servo_msg::constellation_msg::{GetPipelineTitleMsg};
 use servo_msg::constellation_msg::{IFrameSandboxState, IFrameUnsandboxed, InitLoadUrlMsg};
 use servo_msg::constellation_msg::{KeyEvent, Key, KeyState, KeyModifiers, LoadCompleteMsg};
-use servo_msg::constellation_msg::{LoadData, LoadUrlMsg, Msg, NavigateMsg, NavigationType};
+use servo_msg::constellation_msg::{LoadData, LoadUrlMsg, NavigateMsg, NavigationType};
 use servo_msg::constellation_msg::{PainterReadyMsg, PipelineId, ResizedWindowMsg};
 use servo_msg::constellation_msg::{ScriptLoadedURLInIFrameMsg, SubpageId, WindowSizeData};
+use servo_msg::constellation_msg::Msg as ConstellationMsg;
 use servo_msg::constellation_msg;
 use servo_net::image_cache_task::{ImageCacheTask, ImageCacheTaskClient};
 use servo_net::resource_task::ResourceTask;
 use servo_net::resource_task;
 use servo_net::storage_task::StorageTask;
 use servo_net::storage_task;
 use servo_util::geometry::{PagePx, ViewportPx};
 use servo_util::opts;
@@ -43,17 +44,17 @@ use std::rc::Rc;
 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.
-    pub request_port: Receiver<Msg>,
+    pub request_port: Receiver<ConstellationMsg>,
 
     /// A channel (the implementation of which is port-specific) through which messages can be sent
     /// to the compositor.
     pub compositor_proxy: Box<CompositorProxy>,
 
     /// A channel through which messages can be sent to the resource task.
     pub resource_task: ResourceTask,
 
@@ -198,22 +199,22 @@ impl FrameTreeTraversal for Rc<FrameTree
     fn replace_child(&self, id: PipelineId, new_child: Rc<FrameTree>) -> ReplaceResult {
         for frame_tree in self.iter() {
             let mut children = frame_tree.children.borrow_mut();
             let child = children.iter_mut()
                 .find(|child| child.frame_tree.pipeline.id == id);
             match child {
                 Some(child) => {
                     *new_child.parent.borrow_mut() = child.frame_tree.parent.borrow().clone();
-                    return ReplacedNode(replace(&mut child.frame_tree, new_child));
+                    return ReplaceResult::ReplacedNode(replace(&mut child.frame_tree, new_child));
                 }
                 None => (),
             }
         }
-        OriginalNode(new_child)
+        ReplaceResult::OriginalNode(new_child)
     }
 
     fn iter(&self) -> FrameTreeIterator {
         FrameTreeIterator {
             stack: vec!(self.clone()),
         }
     }
 }
@@ -328,18 +329,19 @@ impl NavigationContext {
             frame_tree.contains(pipeline_id)
         })
     }
 
     /// Always use this method to set the currently-displayed frame. It correctly informs the
     /// compositor of the new URLs.
     fn set_current(&mut self, new_frame: Rc<FrameTree>, compositor_proxy: &mut CompositorProxy) {
         self.current = Some(new_frame.clone());
-        compositor_proxy.send(ChangePageLoadData(new_frame.id,
-                                                 new_frame.pipeline.load_data.clone()));
+        compositor_proxy.send(CompositorMsg::ChangePageLoadData(
+            new_frame.id,
+            new_frame.pipeline.load_data.clone()));
     }
 }
 
 impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
     pub fn start(compositor_proxy: Box<CompositorProxy+Send>,
                  resource_task: ResourceTask,
                  image_cache_task: ImageCacheTask,
                  font_cache_task: FontCacheTask,
@@ -437,17 +439,17 @@ impl<LTF: LayoutTaskFactory, STF: Script
         let mut matching_navi_frames = self.navigation_context.find_all(pipeline_id);
         matching_navi_frames.extend(self.pending_frames.iter().filter_map(|frame_change| {
             frame_change.after.find(pipeline_id)
         }));
         matching_navi_frames
     }
 
     /// Handles loading pages, navigation, and granting access to the compositor
-    fn handle_request(&mut self, request: Msg) -> bool {
+    fn handle_request(&mut self, request: ConstellationMsg) -> bool {
         match request {
             ExitMsg => {
                 debug!("constellation exiting");
                 self.handle_exit();
                 return false;
             }
             FailureMsg(Failure { pipeline_id, subpage_id }) => {
                 self.handle_failure_msg(pipeline_id, subpage_id);
@@ -476,17 +478,17 @@ impl<LTF: LayoutTaskFactory, STF: Script
             LoadUrlMsg(source_id, load_data) => {
                 debug!("constellation got URL load message");
                 self.handle_load_url_msg(source_id, load_data);
             }
             // A page loaded through one of several methods above has completed all parsing,
             // script, and reflow messages have been sent.
             LoadCompleteMsg => {
                 debug!("constellation got load complete message");
-                self.compositor_proxy.send(LoadComplete);
+                self.compositor_proxy.send(CompositorMsg::LoadComplete);
             }
             // Handle a forward or back request
             NavigateMsg(direction) => {
                 debug!("constellation got navigation message");
                 self.handle_navigate_msg(direction);
             }
             // Notification that painting has finished and is requesting permission to paint.
             PainterReadyMsg(pipeline_id) => {
@@ -515,17 +517,17 @@ impl<LTF: LayoutTaskFactory, STF: Script
         }
         self.image_cache_task.exit();
         self.resource_task.send(resource_task::Exit);
         self.devtools_chan.as_ref().map(|chan| {
             chan.send(devtools_traits::ServerExitMsg);
         });
         self.storage_task.send(storage_task::Exit);
         self.font_cache_task.exit();
-        self.compositor_proxy.send(ShutdownComplete);
+        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);
 
         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.
@@ -676,19 +678,20 @@ impl<LTF: LayoutTaskFactory, STF: Script
             if !already_sent.contains(&pipeline.id) {
                 if is_active {
                     let ScriptControlChan(ref script_chan) = pipeline.script_chan;
                     script_chan.send(ResizeMsg(pipeline.id, WindowSizeData {
                         visible_viewport: rect.size,
                         initial_viewport: rect.size * ScaleFactor(1.0),
                         device_pixel_ratio: device_pixel_ratio,
                     }));
-                    compositor_proxy.send(SetLayerOrigin(pipeline.id,
-                                                         LayerId::null(),
-                                                         rect.to_untyped().origin));
+                    compositor_proxy.send(CompositorMsg::SetLayerOrigin(
+                        pipeline.id,
+                        LayerId::null(),
+                        rect.to_untyped().origin));
                 } else {
                     already_sent.insert(pipeline.id);
                 }
             };
         }
     }
 
 
@@ -838,17 +841,17 @@ impl<LTF: LayoutTaskFactory, STF: Script
         self.current_frame().as_ref().map(|frame| {
             let ScriptControlChan(ref chan) = frame.pipeline.script_chan;
             chan.send(SendEventMsg(frame.pipeline.id, script_traits::KeyEvent(key, state, mods)));
         });
     }
 
     fn handle_get_pipeline_title_msg(&mut self, pipeline_id: PipelineId) {
         match self.pipelines.get(&pipeline_id) {
-            None => self.compositor_proxy.send(ChangePageTitle(pipeline_id, None)),
+            None => self.compositor_proxy.send(CompositorMsg::ChangePageTitle(pipeline_id, None)),
             Some(pipeline) => {
                 let ScriptControlChan(ref script_channel) = pipeline.script_chan;
                 script_channel.send(GetTitleMsg(pipeline_id));
             }
         }
     }
 
     fn handle_painter_ready_msg(&mut self, pipeline_id: PipelineId) {
@@ -1013,17 +1016,19 @@ impl<LTF: LayoutTaskFactory, STF: Script
                 debug!("ignoring non-load navigation type");
             }
         }
     }
 
     fn set_ids(&mut self, frame_tree: &Rc<FrameTree>) {
         let (chan, port) = channel();
         debug!("Constellation sending SetIds");
-        self.compositor_proxy.send(SetIds(frame_tree.to_sendable(), chan, self.chan.clone()));
+        self.compositor_proxy.send(CompositorMsg::SetIds(frame_tree.to_sendable(),
+                                                         chan,
+                                                         self.chan.clone()));
         match port.recv_opt() {
             Ok(()) => {
                 let mut iter = frame_tree.iter();
                 for frame in iter {
                     frame.has_compositor_layer.set(true);
                     frame.pipeline.grant_paint_permission();
                 }
             }
@@ -1070,17 +1075,17 @@ impl<LTF: LayoutTaskFactory, STF: Script
 
         let sendable_frame_tree_diff = FrameTreeDiff {
             parent_pipeline: parent.pipeline.to_sendable(),
             pipeline: child.frame_tree.pipeline.to_sendable(),
             rect: child.rect,
         };
 
         let (chan, port) = channel();
-        self.compositor_proxy.send(FrameTreeUpdateMsg(sendable_frame_tree_diff, chan));
+        self.compositor_proxy.send(CompositorMsg::FrameTreeUpdate(sendable_frame_tree_diff, chan));
         match port.recv_opt() {
             Ok(()) => {
                 child.frame_tree.has_compositor_layer.set(true);
                 child.frame_tree.pipeline.grant_paint_permission();
             }
             Err(()) => {} // The message has been discarded, we are probably shutting down.
         }
     }
--- a/servo/components/compositing/headless.rs
+++ b/servo/components/compositing/headless.rs
@@ -1,17 +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/. */
 
-use compositor_task::{GetGraphicsMetadata, CreateOrUpdateRootLayer, CreateOrUpdateDescendantLayer};
-use compositor_task::{Exit, ChangeReadyState, LoadComplete, Paint, ScrollFragmentPoint, SetIds};
-use compositor_task::{SetLayerOrigin, ShutdownComplete, ChangePaintState, PaintMsgDiscarded};
-use compositor_task::{CompositorEventListener, CompositorReceiver, ScrollTimeout, ChangePageTitle};
-use compositor_task::{ChangePageLoadData, FrameTreeUpdateMsg, KeyEvent};
+use compositor_task::{CompositorEventListener, CompositorReceiver, Msg};
 use windowing::WindowEvent;
 
 use geom::scale_factor::ScaleFactor;
 use geom::size::TypedSize2D;
 use servo_msg::constellation_msg::{ConstellationChan, ExitMsg, ResizedWindowMsg, WindowSizeData};
 use servo_util::memory::MemoryProfilerChan;
 use servo_util::memory;
 use servo_util::time::TimeProfilerChan;
@@ -68,63 +64,63 @@ impl NullCompositor {
 
         compositor
     }
 }
 
 impl CompositorEventListener for NullCompositor {
     fn handle_event(&mut self, _: WindowEvent) -> bool {
         match self.port.recv_compositor_msg() {
-            Exit(chan) => {
+            Msg::Exit(chan) => {
                 debug!("shutting down the constellation");
                 let ConstellationChan(ref con_chan) = self.constellation_chan;
                 con_chan.send(ExitMsg);
                 chan.send(());
             }
 
-            ShutdownComplete => {
+            Msg::ShutdownComplete => {
                 debug!("constellation completed shutdown");
                 return false
             }
 
-            GetGraphicsMetadata(chan) => {
+            Msg::GetGraphicsMetadata(chan) => {
                 chan.send(None);
             }
 
-            SetIds(_, response_chan, _) => {
+            Msg::SetIds(_, response_chan, _) => {
                 response_chan.send(());
             }
 
-            FrameTreeUpdateMsg(_, response_channel) => {
+            Msg::FrameTreeUpdate(_, response_channel) => {
                 response_channel.send(());
             }
 
             // Explicitly list ignored messages so that when we add a new one,
             // we'll notice and think about whether it needs a response, like
             // SetIds.
 
-            CreateOrUpdateRootLayer(..) |
-            CreateOrUpdateDescendantLayer(..) |
-            SetLayerOrigin(..) | Paint(..) |
-            ChangeReadyState(..) | ChangePaintState(..) | ScrollFragmentPoint(..) |
-            LoadComplete | PaintMsgDiscarded(..) | ScrollTimeout(..) | ChangePageTitle(..) |
-            ChangePageLoadData(..) | KeyEvent(..) => ()
+            Msg::CreateOrUpdateRootLayer(..) |
+            Msg::CreateOrUpdateDescendantLayer(..) |
+            Msg::SetLayerOrigin(..) | Msg::Paint(..) |
+            Msg::ChangeReadyState(..) | Msg::ChangePaintState(..) | Msg::ScrollFragmentPoint(..) |
+            Msg::LoadComplete | Msg::PaintMsgDiscarded(..) | Msg::ScrollTimeout(..) | Msg::ChangePageTitle(..) |
+            Msg::ChangePageLoadData(..) | Msg::KeyEvent(..) => ()
         }
         true
     }
 
     fn repaint_synchronously(&mut self) {}
 
     fn shutdown(&mut self) {
         // Drain compositor port, sometimes messages contain channels that are blocking
         // another task from finishing (i.e. SetIds)
         while self.port.try_recv_compositor_msg().is_some() {}
 
-        self.time_profiler_chan.send(time::ExitMsg);
-        self.memory_profiler_chan.send(memory::ExitMsg);
+        self.time_profiler_chan.send(time::TimeProfilerMsg::Exit);
+        self.memory_profiler_chan.send(memory::MemoryProfilerMsg::Exit);
     }
 
     fn pinch_zoom_level(&self) -> f32 {
         1.0
     }
 
     fn get_title_for_main_frame(&self) {}
 }
--- a/servo/components/compositing/scrolling.rs
+++ b/servo/components/compositing/scrolling.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/. */
 
 //! A timer thread that gives the painting task a little time to catch up when the user scrolls.
 
-use compositor_task::{CompositorProxy, ScrollTimeout};
+use compositor_task::{CompositorProxy, Msg};
 
 use native::task::NativeTaskBuilder;
 use std::io::timer;
 use std::task::TaskBuilder;
 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
@@ -42,32 +42,32 @@ impl ScrollingTimerProxy {
             scrolling_timer.run();
         });
         ScrollingTimerProxy {
             sender: to_scrolling_timer_sender,
         }
     }
 
     pub fn scroll_event_processed(&mut self, timestamp: u64) {
-        self.sender.send(ScrollEventProcessedMsg(timestamp))
+        self.sender.send(ToScrollingTimerMsg::ScrollEventProcessedMsg(timestamp))
     }
 
     pub fn shutdown(&mut self) {
-        self.sender.send(ExitMsg);
+        self.sender.send(ToScrollingTimerMsg::ExitMsg);
     }
 }
 
 impl ScrollingTimer {
     pub fn run(&mut self) {
         loop {
             match self.receiver.recv_opt() {
-                Ok(ScrollEventProcessedMsg(timestamp)) => {
+                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(ScrollTimeout(timestamp));
+                    self.compositor_proxy.send(Msg::ScrollTimeout(timestamp));
                 }
-                Ok(ExitMsg) | Err(_) => break,
+                Ok(ToScrollingTimerMsg::ExitMsg) | Err(_) => break,
             }
         }
     }
 }
 
--- a/servo/components/compositing/windowing.rs
+++ b/servo/components/compositing/windowing.rs
@@ -31,62 +31,62 @@ pub enum WindowNavigateMsg {
 /// Events that the windowing system sends to Servo.
 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.
-    IdleWindowEvent,
+    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.
-    RefreshWindowEvent,
+    Refresh,
     /// Sent to initialize the GL context. The windowing system must have a valid, current GL
     /// context when this message is sent.
-    InitializeCompositingWindowEvent,
+    InitializeCompositing,
     /// Sent when the window is resized.
-    ResizeWindowEvent(TypedSize2D<DevicePixel, uint>),
+    Resize(TypedSize2D<DevicePixel, uint>),
     /// Sent when a new URL is to be loaded.
-    LoadUrlWindowEvent(String),
+    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.
-    ScrollWindowEvent(TypedPoint2D<DevicePixel, f32>, TypedPoint2D<DevicePixel, i32>),
+    Scroll(TypedPoint2D<DevicePixel, f32>, TypedPoint2D<DevicePixel, i32>),
     /// Sent when the user zooms.
-    ZoomWindowEvent(f32),
+    Zoom(f32),
     /// Simulated "pinch zoom" gesture for non-touch platforms (e.g. ctrl-scrollwheel).
-    PinchZoomWindowEvent(f32),
+    PinchZoom(f32),
     /// Sent when the user uses chrome navigation (i.e. backspace or shift-backspace).
-    NavigationWindowEvent(WindowNavigateMsg),
+    Navigation(WindowNavigateMsg),
     /// Sent when the user quits the application
-    QuitWindowEvent,
+    Quit,
     /// Sent when a key input state changes
     KeyEvent(Key, KeyState, KeyModifiers),
 }
 
 impl Show for WindowEvent {
     fn fmt(&self, f: &mut Formatter) -> Result<(),FormatError> {
         match *self {
-            IdleWindowEvent => write!(f, "Idle"),
-            RefreshWindowEvent => write!(f, "Refresh"),
-            InitializeCompositingWindowEvent => write!(f, "InitializeCompositing"),
-            ResizeWindowEvent(..) => write!(f, "Resize"),
-            KeyEvent(..) => write!(f, "Key"),
-            LoadUrlWindowEvent(..) => write!(f, "LoadUrl"),
-            MouseWindowEventClass(..) => write!(f, "Mouse"),
-            MouseWindowMoveEventClass(..) => write!(f, "MouseMove"),
-            ScrollWindowEvent(..) => write!(f, "Scroll"),
-            ZoomWindowEvent(..) => write!(f, "Zoom"),
-            PinchZoomWindowEvent(..) => write!(f, "PinchZoom"),
-            NavigationWindowEvent(..) => write!(f, "Navigation"),
-            QuitWindowEvent => write!(f, "Quit"),
+            WindowEvent::Idle => write!(f, "Idle"),
+            WindowEvent::Refresh => write!(f, "Refresh"),
+            WindowEvent::InitializeCompositing => write!(f, "InitializeCompositing"),
+            WindowEvent::Resize(..) => write!(f, "Resize"),
+            WindowEvent::KeyEvent(..) => write!(f, "Key"),
+            WindowEvent::LoadUrl(..) => write!(f, "LoadUrl"),
+            WindowEvent::MouseWindowEventClass(..) => write!(f, "Mouse"),
+            WindowEvent::MouseWindowMoveEventClass(..) => write!(f, "MouseMove"),
+            WindowEvent::Scroll(..) => write!(f, "Scroll"),
+            WindowEvent::Zoom(..) => write!(f, "Zoom"),
+            WindowEvent::PinchZoom(..) => write!(f, "PinchZoom"),
+            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>;
     /// Returns the size of the window in density-independent "px" units.
--- a/servo/components/devtools/actors/console.rs
+++ b/servo/components/devtools/actors/console.rs
@@ -13,16 +13,17 @@ use devtools_traits::{EvaluateJS, NullVa
 use devtools_traits::{ActorValue, DevtoolScriptControlMsg};
 use servo_msg::constellation_msg::PipelineId;
 
 use collections::TreeMap;
 use core::cell::RefCell;
 use serialize::json;
 use serialize::json::ToJson;
 use std::io::TcpStream;
+use std::num::Float;
 
 #[deriving(Encodable)]
 struct StartedListenersTraits {
     customNetworkRequest: bool,
 }
 
 #[deriving(Encodable)]
 struct StartedListenersReply {
--- a/servo/components/devtools/actors/inspector.rs
+++ b/servo/components/devtools/actors/inspector.rs
@@ -11,16 +11,17 @@ use actor::{Actor, ActorRegistry};
 use protocol::JsonPacketStream;
 
 use collections::TreeMap;
 use servo_msg::constellation_msg::PipelineId;
 use serialize::json;
 use serialize::json::ToJson;
 use std::cell::RefCell;
 use std::io::TcpStream;
+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,
--- a/servo/components/gfx/Cargo.toml
+++ b/servo/components/gfx/Cargo.toml
@@ -57,8 +57,10 @@ 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"
--- a/servo/components/gfx/display_list/mod.rs
+++ b/servo/components/gfx/display_list/mod.rs
@@ -9,16 +9,19 @@
 //! Finally, display lists allow tiles to be farmed out onto multiple CPUs and painted in
 //! parallel (although this benefit does not apply to GPU-based painting).
 //!
 //! Display items describe relatively high-level drawing operations (for example, entire borders
 //! and shadows instead of lines and blur operations), to reduce the amount of allocation required.
 //! They are therefore not exactly analogous to constructs like Skia pictures, which consist of
 //! low-level drawing primitives.
 
+use self::DisplayItem::*;
+use self::DisplayItemIterator::*;
+
 use color::Color;
 use display_list::optimizer::DisplayListOptimizer;
 use paint_context::{PaintContext, ToAzureRect};
 use text::glyph::CharIndex;
 use text::TextRun;
 
 use azure::azure::AzFloat;
 use collections::dlist::{mod, DList};
--- a/servo/components/gfx/font_cache_task.rs
+++ b/servo/components/gfx/font_cache_task.rs
@@ -1,27 +1,30 @@
 /* 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 self::Command::*;
+use self::Reply::*;
+
 use platform::font_list::get_available_families;
 use platform::font_list::get_system_default_family;
 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::collections::HashMap;
 use sync::Arc;
 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, LocalSource, UrlSource_};
+use style::Source;
 
 /// A list of font templates that make up a given font family.
 struct FontFamily {
     templates: Vec<FontTemplate>,
 }
 
 impl FontFamily {
     fn new() -> FontFamily {
@@ -123,30 +126,30 @@ impl FontCache {
                 AddWebFont(family_name, src, result) => {
                     let family_name = LowercaseString::new(family_name.as_slice());
                     if !self.web_families.contains_key(&family_name) {
                         let family = FontFamily::new();
                         self.web_families.insert(family_name.clone(), family);
                     }
 
                     match src {
-                        UrlSource_(ref url_source) => {
+                        Source::Url(ref url_source) => {
                             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);
                                 }
                             }
                         }
-                        LocalSource(ref local_family_name) => {
+                        Source::Local(ref local_family_name) => {
                             let family = &mut self.web_families[family_name];
                             get_variations_for_family(local_family_name.as_slice(), |path| {
                                 family.add_template(path.as_slice(), None);
                             });
                         }
                     }
                     result.send(());
                 }
--- a/servo/components/gfx/paint_context.rs
+++ b/servo/components/gfx/paint_context.rs
@@ -8,18 +8,18 @@ use azure::azure::AzIntSize;
 use azure::azure_hl::{A8, B8G8R8A8, Color, ColorPattern, ColorPatternRef, DrawOptions};
 use azure::azure_hl::{DrawSurfaceOptions, DrawTarget, ExtendClamp, GaussianBlurFilterType};
 use azure::azure_hl::{GaussianBlurInput, GradientStop, Linear, LinearGradientPattern};
 use azure::azure_hl::{LinearGradientPatternRef, Path, SourceOp, StdDeviationGaussianBlurAttribute};
 use azure::azure_hl::{StrokeOptions};
 use azure::scaled_font::ScaledFont;
 use azure::{AZ_CAP_BUTT, AzFloat, struct__AzDrawOptions, struct__AzGlyph};
 use azure::{struct__AzGlyphBuffer, struct__AzPoint, AzDrawTargetFillGlyphs};
-use display_list::{BOX_SHADOW_INFLATION_FACTOR, BorderRadii, SidewaysLeft, SidewaysRight};
-use display_list::{TextDisplayItem, Upright};
+use display_list::{BOX_SHADOW_INFLATION_FACTOR, TextDisplayItem, BorderRadii};
+use display_list::TextOrientation::{SidewaysLeft, SidewaysRight, Upright};
 use font_context::FontContext;
 use geom::matrix2d::Matrix2D;
 use geom::point::Point2D;
 use geom::rect::Rect;
 use geom::side_offsets::SideOffsets2D;
 use geom::size::Size2D;
 use libc::size_t;
 use libc::types::common::c99::{uint16_t, uint32_t};
@@ -81,20 +81,20 @@ impl<'a> PaintContext<'a> {
                        radius: &BorderRadii<Au>,
                        color: SideOffsets2D<Color>,
                        style: SideOffsets2D<border_style::T>) {
         let border = border.to_float_px();
         let radius = radius.to_radii_px();
 
         self.draw_target.make_current();
 
-        self.draw_border_segment(Top, bounds, border, &radius, color, style);
-        self.draw_border_segment(Right, bounds, border, &radius, color, style);
-        self.draw_border_segment(Bottom, bounds, border, &radius, color, style);
-        self.draw_border_segment(Left, bounds, border, &radius, color, style);
+        self.draw_border_segment(Direction::Top, bounds, border, &radius, color, style);
+        self.draw_border_segment(Direction::Right, bounds, border, &radius, color, style);
+        self.draw_border_segment(Direction::Bottom, bounds, border, &radius, color, style);
+        self.draw_border_segment(Direction::Left, bounds, border, &radius, color, style);
     }
 
     pub fn draw_line(&self,
                      bounds: &Rect<Au>,
                      color: Color,
                      style: border_style::T) {
         self.draw_target.make_current();
 
@@ -166,33 +166,33 @@ impl<'a> PaintContext<'a> {
     fn draw_border_segment(&self,
                            direction: Direction,
                            bounds: &Rect<Au>,
                            border: SideOffsets2D<f32>,
                            radius: &BorderRadii<AzFloat>,
                            color: SideOffsets2D<Color>,
                            style: SideOffsets2D<border_style::T>) {
         let (style_select, color_select) = match direction {
-            Top => (style.top, color.top),
-            Left => (style.left, color.left),
-            Right => (style.right, color.right),
-            Bottom => (style.bottom, color.bottom)
+            Direction::Top => (style.top, color.top),
+            Direction::Left => (style.left, color.left),
+            Direction::Right => (style.right, color.right),
+            Direction::Bottom => (style.bottom, color.bottom)
         };
 
         match style_select{
             border_style::none                         => {
             }
             border_style::hidden                       => {
             }
             //FIXME(sammykim): This doesn't work with dash_pattern and cap_style well. I referred firefox code.
             border_style::dotted                       => {
-                self.draw_dashed_border_segment(direction, bounds, border, color_select, DottedBorder);
+                self.draw_dashed_border_segment(direction, bounds, border, color_select, DashSize::DottedBorder);
             }
             border_style::dashed                       => {
-                self.draw_dashed_border_segment(direction, bounds, border, color_select, DashedBorder);
+                self.draw_dashed_border_segment(direction, bounds, border, color_select, DashSize::DashedBorder);
             }
             border_style::solid                        => {
                 self.draw_solid_border_segment(direction,bounds,border,radius,color_select);
             }
             border_style::double                       => {
                 self.draw_double_border_segment(direction, bounds, border, radius, color_select);
             }
             border_style::groove | border_style::ridge => {
@@ -205,32 +205,32 @@ impl<'a> PaintContext<'a> {
     }
 
     fn draw_line_segment(&self, bounds: &Rect<Au>, radius: &BorderRadii<AzFloat>, color: Color, style: border_style::T) {
         let border = SideOffsets2D::new_all_same(bounds.size.width).to_float_px();
 
         match style {
             border_style::none | border_style::hidden  => {}
             border_style::dotted                       => {
-                self.draw_dashed_border_segment(Right, bounds, border, color, DottedBorder);
+                self.draw_dashed_border_segment(Direction::Right, bounds, border, color, DashSize::DottedBorder);
             }
             border_style::dashed                       => {
-                self.draw_dashed_border_segment(Right, bounds, border, color, DashedBorder);
+                self.draw_dashed_border_segment(Direction::Right, bounds, border, color, DashSize::DashedBorder);
             }
             border_style::solid                        => {
-                self.draw_solid_border_segment(Right, bounds, border, radius, color);
+                self.draw_solid_border_segment(Direction::Right, bounds, border, radius, color);
             }
             border_style::double                       => {
-                self.draw_double_border_segment(Right, bounds, border, radius, color);
+                self.draw_double_border_segment(Direction::Right, bounds, border, radius, color);
             }
             border_style::groove | border_style::ridge => {
-                self.draw_groove_ridge_border_segment(Right, bounds, border, radius, color, style);
+                self.draw_groove_ridge_border_segment(Direction::Right, bounds, border, radius, color, style);
             }
             border_style::inset | border_style::outset => {
-                self.draw_inset_outset_border_segment(Right, bounds, border, radius, color, style);
+                self.draw_inset_outset_border_segment(Direction::Right, bounds, border, radius, color, style);
             }
         }
     }
 
     // The following comment is wonderful, and stolen from
     // gecko:gfx/thebes/gfxContext.cpp:RoundedRectangle for reference.
     //
     // It does not currently apply to the code, but will be extremely useful in
@@ -349,17 +349,17 @@ impl<'a> PaintContext<'a> {
             Point2D(if cond { dx } else { 0. }, 0.)
         }
 
         fn dy_if(cond: bool, dy: AzFloat) -> Point2D<AzFloat> {
             Point2D(0., if cond { dy } else { 0. })
         }
 
         match direction {
-            Top    => {
+            Direction::Top    => {
                 let edge_TL = box_TL  + dx(radius.top_left.max(border.left));
                 let edge_TR = box_TR  + dx(-radius.top_right.max(border.right));
                 let edge_BR = edge_TR + dy(border.top);
                 let edge_BL = edge_TL + dy(border.top);
 
                 let corner_TL = edge_TL + dx_if(radius.top_left == 0., -border.left);
                 let corner_TR = edge_TR + dx_if(radius.top_right == 0., border.right);
 
@@ -382,17 +382,17 @@ impl<'a> PaintContext<'a> {
                 if radius.top_left != 0. {
                     let origin = edge_TL + Point2D(-(border.left - radius.top_left).max(0.), radius.top_left);
                     let distance_to_elbow = (radius.top_left - border.top).max(0.);
 
                     path_builder.arc(origin, distance_to_elbow, rad_T, rad_TL, true);
                     path_builder.arc(origin, radius.top_left,   rad_TL, rad_T, false);
                 }
             }
-            Left   => {
+            Direction::Left   => {
                 let edge_TL = box_TL  + dy(radius.top_left.max(border.top));
                 let edge_BL = box_BL  + dy(-radius.bottom_left.max(border.bottom));
                 let edge_TR = edge_TL + dx(border.left);
                 let edge_BR = edge_BL + dx(border.left);
 
                 let corner_TL = edge_TL + dy_if(radius.top_left == 0., -border.top);
                 let corner_BL = edge_BL + dy_if(radius.bottom_left == 0., border.bottom);
 
@@ -413,17 +413,17 @@ impl<'a> PaintContext<'a> {
                 if radius.bottom_left != 0. {
                     let origin = edge_BL + Point2D(radius.bottom_left, (border.bottom - radius.bottom_left).max(0.));
                     let distance_to_elbow = (radius.bottom_left - border.left).max(0.);
 
                     path_builder.arc(origin, distance_to_elbow,  rad_L, rad_BL, true);
                     path_builder.arc(origin, radius.bottom_left, rad_BL, rad_L, false);
                 }
             }
-            Right  => {
+            Direction::Right  => {
                 let edge_TR = box_TR  + dy(radius.top_right.max(border.top));
                 let edge_BR = box_BR  + dy(-radius.bottom_right.max(border.bottom));
                 let edge_TL = edge_TR + dx(-border.right);
                 let edge_BL = edge_BR + dx(-border.right);
 
                 let corner_TR = edge_TR + dy_if(radius.top_right == 0., -border.top);
                 let corner_BR = edge_BR + dy_if(radius.bottom_right == 0., border.bottom);
 
@@ -444,17 +444,17 @@ impl<'a> PaintContext<'a> {
                 if radius.bottom_right != 0. {
                     let origin = edge_BR + Point2D(-radius.bottom_right, (border.bottom - radius.bottom_right).max(0.));
                     let distance_to_elbow = (radius.bottom_right - border.right).max(0.);
 
                     path_builder.arc(origin, radius.bottom_right, rad_R, rad_BR, false);
                     path_builder.arc(origin, distance_to_elbow,   rad_BR, rad_R, true);
                 }
             }
-            Bottom => {
+            Direction::Bottom => {
                 let edge_BL = box_BL  + dx(radius.bottom_left.max(border.left));
                 let edge_BR = box_BR  + dx(-radius.bottom_right.max(border.right));
                 let edge_TL = edge_BL + dy(-border.bottom);
                 let edge_TR = edge_BR + dy(-border.bottom);
 
                 let corner_BR = edge_BR + dx_if(radius.bottom_right == 0., border.right);
                 let corner_BL = edge_BL + dx_if(radius.bottom_left == 0., -border.left);
 
@@ -495,48 +495,48 @@ impl<'a> PaintContext<'a> {
         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];
 
         stroke_opts.set_cap_style(AZ_CAP_BUTT as u8);
 
         let border_width = match direction {
-            Top => border.top,
-            Left => border.left,
-            Right => border.right,
-            Bottom => border.bottom
+            Direction::Top => border.top,
+            Direction::Left => border.left,
+            Direction::Right => border.right,
+            Direction::Bottom => border.bottom
         };
 
         stroke_opts.line_width = border_width;
         dash[0] = border_width * (dash_size as int) as AzFloat;
         dash[1] = border_width * (dash_size as int) as AzFloat;
         stroke_opts.mDashPattern = dash.as_mut_ptr();
         stroke_opts.mDashLength = dash.len() as size_t;
 
         let (start, end)  = match direction {
-            Top => {
+            Direction::Top => {
                 let y = rect.origin.y + border.top * 0.5;
                 let start = Point2D(rect.origin.x, y);
                 let end = Point2D(rect.origin.x + rect.size.width, y);
                 (start, end)
             }
-            Left => {
+            Direction::Left => {
                 let x = rect.origin.x + border.left * 0.5;
                 let start = Point2D(x, rect.origin.y + rect.size.height);
                 let end = Point2D(x, rect.origin.y + border.top);
                 (start, end)
             }
-            Right => {
+            Direction::Right => {
                 let x = rect.origin.x + rect.size.width - border.right * 0.5;
                 let start = Point2D(x, rect.origin.y);
                 let end = Point2D(x, rect.origin.y + rect.size.height);
                 (start, end)
             }
-            Bottom => {
+            Direction::Bottom => {
                 let y = rect.origin.y + rect.size.height - border.bottom * 0.5;
                 let start = Point2D(rect.origin.x + rect.size.width, y);
                 let end = Point2D(rect.origin.x + border.left, y);
                 (start, end)
             }
         };
 
         self.draw_target.stroke_line(start,
@@ -612,18 +612,20 @@ impl<'a> PaintContext<'a> {
             lighter_color = color;
         } else {
             // You can't scale black color (i.e. 'scaled = 0 * scale', equals black).
             darker_color = Color::new(0.3, 0.3, 0.3, color.a);
             lighter_color = Color::new(0.7, 0.7, 0.7, color.a);
         }
 
         let (outer_color, inner_color) = match (direction, is_groove) {
-            (Top, true)  | (Left, true)  | (Right, false) | (Bottom, false) => (darker_color, lighter_color),
-            (Top, false) | (Left, false) | (Right, true)  | (Bottom, true)  => (lighter_color, darker_color)
+            (Direction::Top, true)  | (Direction::Left, true)  |
+            (Direction::Right, false) | (Direction::Bottom, false) => (darker_color, lighter_color),
+            (Direction::Top, false) | (Direction::Left, false) |
+            (Direction::Right, true)  | (Direction::Bottom, true)  => (lighter_color, darker_color)
         };
         // outer portion of the border
         self.draw_border_path(&original_bounds, direction, scaled_border, radius, outer_color);
         // inner portion of the border
         self.draw_border_path(&inner_scaled_bounds, direction, scaled_border, radius, inner_color);
     }
 
     fn draw_inset_outset_border_segment(&self,
@@ -637,18 +639,18 @@ impl<'a> PaintContext<'a> {
                 border_style::inset  =>  true,
                 border_style::outset =>  false,
                 _                    =>  panic!("invalid border style")
         };
         // original bounds as a Rect<f32>
         let original_bounds = self.get_scaled_bounds(bounds, border, 0.0);
         // select and scale the color appropriately.
         let scaled_color    = match direction {
-            Top | Left      => self.scale_color(color, if is_inset { 2.0/3.0 } else { 1.0     }),
-            Right | Bottom  => self.scale_color(color, if is_inset { 1.0     } else { 2.0/3.0 })
+            Direction::Top | Direction::Left      => self.scale_color(color, if is_inset { 2.0/3.0 } else { 1.0     }),
+            Direction::Right | Direction::Bottom  => self.scale_color(color, if is_inset { 1.0     } else { 2.0/3.0 })
         };
         self.draw_border_path(&original_bounds, direction, border, radius, scaled_color);
     }
 
     pub fn draw_text(&mut self, text: &TextDisplayItem) {
         let current_transform = self.draw_target.get_transform();
 
         // Optimization: Don’t set a transform matrix for upright text, and pass a start point to
--- a/servo/components/gfx/paint_task.rs
+++ b/servo/components/gfx/paint_task.rs
@@ -1,14 +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/. */
 
 //! The task that handles all painting.
 
+use self::Msg::*;
+use self::MsgFromWorkerThread::*;
+use self::MsgToWorkerThread::*;
+
 use buffer_map::BufferMap;
 use display_list::{mod, StackingContext};
 use font_cache_task::FontCacheTask;
 use font_context::FontContext;
 use paint_context::PaintContext;
 
 use azure::azure_hl::{B8G8R8A8, Color, DrawTarget, SkiaBackend, StolenGLResources};
 use azure::AzFloat;
--- a/servo/components/gfx/platform/freetype/font.rs
+++ b/servo/components/gfx/platform/freetype/font.rs
@@ -21,16 +21,17 @@ use freetype::freetype::{FT_New_Memory_F
 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 std::mem;
+use std::num::Float;
 use std::ptr;
 use std::string;
 
 use sync::Arc;
 
 fn float_to_fixed_ft(f: f64) -> i32 {
     float_to_fixed(6, f)
 }
--- a/servo/components/gfx/platform/macos/font.rs
+++ b/servo/components/gfx/platform/macos/font.rs
@@ -22,16 +22,17 @@ use core_foundation::base::CFIndex;
 use core_foundation::data::CFData;
 use core_foundation::string::UniChar;
 use core_graphics::font::CGGlyph;
 use core_graphics::geometry::CGRect;
 use core_text::font::CTFont;
 use core_text::font_descriptor::{SymbolicTraitAccessors, TraitAccessors};
 use core_text::font_descriptor::{kCTFontDefaultOrientation};
 
+use std::num::Float;
 use std::ptr;
 use sync::Arc;
 
 pub struct FontTable {
     data: CFData,
 }
 
 // Noncopyable.
--- a/servo/components/gfx/text/glyph.rs
+++ b/servo/components/gfx/text/glyph.rs
@@ -1,12 +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 self::BreakType::*;
+use self::GlyphInfo::*;
+
 use servo_util::vec::*;
 use servo_util::range;
 use servo_util::range::{Range, RangeIndex, IntRangeIndex, EachIndex};
 use servo_util::geometry::Au;
 
 use std::cmp::PartialOrd;
 use std::num::{NumCast, Zero};
 use std::mem;
--- a/servo/components/gfx/text/util.rs
+++ b/servo/components/gfx/text/util.rs
@@ -1,12 +1,14 @@
 /* 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 self::CompressionMode::*;
+
 use text::glyph::CharIndex;
 
 #[deriving(PartialEq)]
 pub enum CompressionMode {
     CompressNone,
     CompressWhitespace,
     CompressWhitespaceNewline,
     DiscardNewline
--- a/servo/components/layout/block.rs
+++ b/servo/components/layout/block.rs
@@ -26,47 +26,46 @@
 //!   http://dev.w3.org/csswg/css-sizing/
 
 #![deny(unsafe_blocks)]
 
 use construct::FlowConstructor;
 use context::LayoutContext;
 use css::node_style::StyledNode;
 use display_list_builder::{BlockFlowDisplayListBuilding, FragmentDisplayListBuilding};
-use floats::{ClearBoth, ClearLeft, ClearRight, FloatKind, FloatLeft, Floats, PlacementInfo};
-use flow::{AbsolutePositionInfo, BaseFlow, BlockFlowClass, FloatIfNecessary, FlowClass, Flow};
-use flow::{ForceNonfloated, ImmutableFlowUtils, MutableFlowUtils, PreorderFlowTraversal};
+use floats::{ClearType, FloatKind, Floats, PlacementInfo};
+use flow::{AbsolutePositionInfo, BaseFlow, ForceNonfloatedFlag, FlowClass, Flow};
+use flow::{ImmutableFlowUtils, MutableFlowUtils, PreorderFlowTraversal};
 use flow::{PostorderFlowTraversal, mut_base};
 use flow::{HAS_LEFT_FLOATED_DESCENDANTS, HAS_RIGHT_FLOATED_DESCENDANTS};
 use flow::{IMPACTED_BY_LEFT_FLOATS, IMPACTED_BY_RIGHT_FLOATS};
 use flow::{LAYERS_NEEDED_FOR_DESCENDANTS, NEEDS_LAYER};
 use flow::{IS_ABSOLUTELY_POSITIONED};
 use flow::{CLEARS_LEFT, CLEARS_RIGHT};
 use flow;
-use fragment::{Fragment, ImageFragment, InlineBlockFragment, FragmentBoundsIterator};
-use fragment::ScannedTextFragment;
+use fragment::{Fragment, FragmentBoundsIterator, SpecificFragmentInfo};
 use incremental::{REFLOW, REFLOW_OUT_OF_FLOW};
 use layout_debug;
-use model::{Auto, IntrinsicISizes, MarginCollapseInfo, MarginsCollapse, MarginsCollapseThrough};
-use model::{MaybeAuto, NoCollapsibleMargins, Specified, specified, specified_or_none};
+use model::{IntrinsicISizes, MarginCollapseInfo};
+use model::{MaybeAuto, CollapsibleMargins, specified, specified_or_none};
 use table::ColumnComputedInlineSize;
 use wrapper::ThreadSafeLayoutNode;
 
 use geom::Size2D;
 use gfx::display_list::DisplayList;
 use serialize::{Encoder, Encodable};
 use servo_msg::compositor_msg::LayerId;
 use servo_util::geometry::{Au, MAX_AU, MAX_RECT, ZERO_POINT};
 use servo_util::logical_geometry::{LogicalPoint, LogicalRect, LogicalSize};
 use servo_util::opts;
 use std::cmp::{max, min};
 use std::fmt;
 use style::ComputedValues;
-use style::computed_values::{LPA_Auto, LPA_Length, LPA_Percentage, LPN_Length, LPN_None};
-use style::computed_values::{LPN_Percentage, LP_Length, LP_Percentage, box_sizing, display, float};
+use style::computed_values::{LengthOrPercentageOrAuto, LengthOrPercentageOrNone};
+use style::computed_values::{LengthOrPercentage, box_sizing, display, float};
 use style::computed_values::{overflow, position};
 use sync::Arc;
 
 /// Information specific to floated blocks.
 #[deriving(Clone, Encodable)]
 pub struct FloatedBlockInfo {
     /// The amount of inline size that is available for the float.
     pub containing_inline_size: Au,
@@ -133,91 +132,91 @@ impl BSizeConstraintSolution {
                                                   static_b_offset: Au)
                                                   -> BSizeConstraintSolution {
         // Distance from the block-start edge of the Absolute Containing Block to the
         // block-start margin edge of a hypothetical box that would have been the
         // first box of the element.
         let static_position_block_start = static_b_offset;
 
         let (block_start, block_end, block_size, margin_block_start, margin_block_end) = match (block_start, block_end, block_size) {
-            (Auto, Auto, Auto) => {
+            (MaybeAuto::Auto, MaybeAuto::Auto, MaybeAuto::Auto) => {
                 let margin_block_start = block_start_margin.specified_or_zero();
                 let margin_block_end = block_end_margin.specified_or_zero();
                 let block_start = static_position_block_start;
                 // Now it is the same situation as block-start Specified and block-end
                 // and block-size Auto.
 
                 let block_size = content_block_size;
                 let sum = block_start + block_size + margin_block_start + margin_block_end;
                 (block_start, available_block_size - sum, block_size, margin_block_start, margin_block_end)
             }
-            (Specified(block_start), Specified(block_end), Specified(block_size)) => {
+            (MaybeAuto::Specified(block_start), MaybeAuto::Specified(block_end), MaybeAuto::Specified(block_size)) => {
                 match (block_start_margin, block_end_margin) {
-                    (Auto, Auto) => {
+                    (MaybeAuto::Auto, MaybeAuto::Auto) => {
                         let total_margin_val = available_block_size - block_start - block_end - block_size;
                         (block_start, block_end, block_size,
                          total_margin_val.scale_by(0.5),
                          total_margin_val.scale_by(0.5))
                     }
-                    (Specified(margin_block_start), Auto) => {
+                    (MaybeAuto::Specified(margin_block_start), MaybeAuto::Auto) => {
                         let sum = block_start + block_end + block_size + margin_block_start;
                         (block_start, block_end, block_size, margin_block_start, available_block_size - sum)
                     }
-                    (Auto, Specified(margin_block_end)) => {
+                    (MaybeAuto::Auto, MaybeAuto::Specified(margin_block_end)) => {
                         let sum = block_start + block_end + block_size + margin_block_end;
                         (block_start, block_end, block_size, available_block_size - sum, margin_block_end)
                     }
-                    (Specified(margin_block_start), Specified(margin_block_end)) => {
+                    (MaybeAuto::Specified(margin_block_start), MaybeAuto::Specified(margin_block_end)) => {
                         // Values are over-constrained. Ignore value for 'block-end'.
                         let sum = block_start + block_size + margin_block_start + margin_block_end;
                         (block_start, available_block_size - sum, block_size, margin_block_start, margin_block_end)
                     }
                 }
             }
 
             // For the rest of the cases, auto values for margin are set to 0
 
             // If only one is Auto, solve for it
-            (Auto, Specified(block_end), Specified(block_size)) => {
+            (MaybeAuto::Auto, MaybeAuto::Specified(block_end), MaybeAuto::Specified(block_size)) => {
                 let margin_block_start = block_start_margin.specified_or_zero();
                 let margin_block_end = block_end_margin.specified_or_zero();
                 let sum = block_end + block_size + margin_block_start + margin_block_end;
                 (available_block_size - sum, block_end, block_size, margin_block_start, margin_block_end)
             }
-            (Specified(block_start), Auto, Specified(block_size)) => {
+            (MaybeAuto::Specified(block_start), MaybeAuto::Auto, MaybeAuto::Specified(block_size)) => {
                 let margin_block_start = block_start_margin.specified_or_zero();
                 let margin_block_end = block_end_margin.specified_or_zero();
                 let sum = block_start + block_size + margin_block_start + margin_block_end;
                 (block_start, available_block_size - sum, block_size, margin_block_start, margin_block_end)
             }
-            (Specified(block_start), Specified(block_end), Auto) => {
+            (MaybeAuto::Specified(block_start), MaybeAuto::Specified(block_end), MaybeAuto::Auto) => {
                 let margin_block_start = block_start_margin.specified_or_zero();
                 let margin_block_end = block_end_margin.specified_or_zero();
                 let sum = block_start + block_end + margin_block_start + margin_block_end;
                 (block_start, block_end, available_block_size - sum, margin_block_start, margin_block_end)
             }
 
             // If block-size is auto, then block-size is content block-size. Solve for the
             // non-auto value.
-            (Specified(block_start), Auto, Auto) => {
+            (MaybeAuto::Specified(block_start), MaybeAuto::Auto, MaybeAuto::Auto) => {
                 let margin_block_start = block_start_margin.specified_or_zero();
                 let margin_block_end = block_end_margin.specified_or_zero();
                 let block_size = content_block_size;
                 let sum = block_start + block_size + margin_block_start + margin_block_end;
                 (block_start, available_block_size - sum, block_size, margin_block_start, margin_block_end)
             }
-            (Auto, Specified(block_end), Auto) => {
+            (MaybeAuto::Auto, MaybeAuto::Specified(block_end), MaybeAuto::Auto) => {
                 let margin_block_start = block_start_margin.specified_or_zero();
                 let margin_block_end = block_end_margin.specified_or_zero();
                 let block_size = content_block_size;
                 let sum = block_end + block_size + margin_block_start + margin_block_end;
                 (available_block_size - sum, block_end, block_size, margin_block_start, margin_block_end)
             }
 
-            (Auto, Auto, Specified(block_size)) => {
+            (MaybeAuto::Auto, MaybeAuto::Auto, MaybeAuto::Specified(block_size)) => {
                 let margin_block_start = block_start_margin.specified_or_zero();
                 let margin_block_end = block_end_margin.specified_or_zero();
                 let block_start = static_position_block_start;
                 let sum = block_start + block_size + margin_block_start + margin_block_end;
                 (block_start, available_block_size - sum, block_size, margin_block_start, margin_block_end)
             }
         };
         BSizeConstraintSolution::new(block_start, block_end, block_size, margin_block_start, margin_block_end)
@@ -244,55 +243,55 @@ impl BSizeConstraintSolution {
                                                static_b_offset: Au)
                                                -> BSizeConstraintSolution {
         // Distance from the block-start edge of the Absolute Containing Block to the
         // block-start margin edge of a hypothetical box that would have been the
         // first box of the element.
         let static_position_block_start = static_b_offset;
 
         let (block_start, block_end, block_size, margin_block_start, margin_block_end) = match (block_start, block_end) {
-            (Auto, Auto) => {
+            (MaybeAuto::Auto, MaybeAuto::Auto) => {
                 let margin_block_start = block_start_margin.specified_or_zero();
                 let margin_block_end = block_end_margin.specified_or_zero();
                 let block_start = static_position_block_start;
                 let sum = block_start + block_size + margin_block_start + margin_block_end;
                 (block_start, available_block_size - sum, block_size, margin_block_start, margin_block_end)
             }
-            (Specified(block_start), Specified(block_end)) => {
+            (MaybeAuto::Specified(block_start), MaybeAuto::Specified(block_end)) => {
                 match (block_start_margin, block_end_margin) {
-                    (Auto, Auto) => {
+                    (MaybeAuto::Auto, MaybeAuto::Auto) => {
                         let total_margin_val = available_block_size - block_start - block_end - block_size;
                         (block_start, block_end, block_size,
                          total_margin_val.scale_by(0.5),
                          total_margin_val.scale_by(0.5))
                     }
-                    (Specified(margin_block_start), Auto) => {
+                    (MaybeAuto::Specified(margin_block_start), MaybeAuto::Auto) => {
                         let sum = block_start + block_end + block_size + margin_block_start;
                         (block_start, block_end, block_size, margin_block_start, available_block_size - sum)
                     }
-                    (Auto, Specified(margin_block_end)) => {
+                    (MaybeAuto::Auto, MaybeAuto::Specified(margin_block_end)) => {
                         let sum = block_start + block_end + block_size + margin_block_end;
                         (block_start, block_end, block_size, available_block_size - sum, margin_block_end)
                     }
-                    (Specified(margin_block_start), Specified(margin_block_end)) => {
+                    (MaybeAuto::Specified(margin_block_start), MaybeAuto::Specified(margin_block_end)) => {
                         // Values are over-constrained. Ignore value for 'block-end'.
                         let sum = block_start + block_size + margin_block_start + margin_block_end;
                         (block_start, available_block_size - sum, block_size, margin_block_start, margin_block_end)
                     }
                 }
             }
 
             // If only one is Auto, solve for it
-            (Auto, Specified(block_end)) => {
+            (MaybeAuto::Auto, MaybeAuto::Specified(block_end)) => {
                 let margin_block_start = block_start_margin.specified_or_zero();
                 let margin_block_end = block_end_margin.specified_or_zero();
                 let sum = block_end + block_size + margin_block_start + margin_block_end;
                 (available_block_size - sum, block_end, block_size, margin_block_start, margin_block_end)
             }
-            (Specified(block_start), Auto) => {
+            (MaybeAuto::Specified(block_start), MaybeAuto::Auto) => {
                 let margin_block_start = block_start_margin.specified_or_zero();
                 let margin_block_end = block_end_margin.specified_or_zero();
                 let sum = block_start + block_size + margin_block_start + margin_block_end;
                 (block_start, available_block_size - sum, block_size, margin_block_start, margin_block_end)
             }
         };
         BSizeConstraintSolution::new(block_start, block_end, block_size, margin_block_start, margin_block_end)
     }
@@ -320,102 +319,103 @@ impl CandidateBSizeIterator {
                -> CandidateBSizeIterator {
         // Per CSS 2.1 § 10.7, (assuming an horizontal writing mode,)
         // percentages in `min-height` and `max-height` refer to the height of
         // the containing block.
         // If that is not determined yet by the time we need to resolve
         // `min-height` and `max-height`, percentage values are ignored.
 
         let block_size = match (fragment.style.content_block_size(), block_container_block_size) {
-            (LPA_Percentage(percent), Some(block_container_block_size)) => {
-                Specified(block_container_block_size.scale_by(percent))
+            (LengthOrPercentageOrAuto::Percentage(percent), Some(block_container_block_size)) => {
+                MaybeAuto::Specified(block_container_block_size.scale_by(percent))
             }
-            (LPA_Percentage(_), None) | (LPA_Auto, _) => Auto,
-            (LPA_Length(length), _) => Specified(length),
+            (LengthOrPercentageOrAuto::Percentage(_), None) | (LengthOrPercentageOrAuto::Auto, _) => MaybeAuto::Auto,
+            (LengthOrPercentageOrAuto::Length(length), _) => MaybeAuto::Specified(length),
         };
         let max_block_size = match (fragment.style.max_block_size(), block_container_block_size) {
-            (LPN_Percentage(percent), Some(block_container_block_size)) => {
+            (LengthOrPercentageOrNone::Percentage(percent), Some(block_container_block_size)) => {
                 Some(block_container_block_size.scale_by(percent))
             }
-            (LPN_Percentage(_), None) | (LPN_None, _) => None,
-            (LPN_Length(length), _) => Some(length),
+            (LengthOrPercentageOrNone::Percentage(_), None) |
+            (LengthOrPercentageOrNone::None, _) => None,
+            (LengthOrPercentageOrNone::Length(length), _) => Some(length),
         };
         let min_block_size = match (fragment.style.min_block_size(), block_container_block_size) {
-            (LP_Percentage(percent), Some(block_container_block_size)) => {
+            (LengthOrPercentage::Percentage(percent), Some(block_container_block_size)) => {
                 block_container_block_size.scale_by(percent)
             }
-            (LP_Percentage(_), None) => Au(0),
-            (LP_Length(length), _) => length,
+            (LengthOrPercentage::Percentage(_), None) => Au(0),
+            (LengthOrPercentage::Length(length), _) => length,
         };
 
         // If the style includes `box-sizing: border-box`, subtract the border and padding.
         let adjustment_for_box_sizing = match fragment.style.get_box().box_sizing {
             box_sizing::border_box => fragment.border_padding.block_start_end(),
             box_sizing::content_box => Au(0),
         };
 
         return CandidateBSizeIterator {
             block_size: block_size.map(|size| adjust(size, adjustment_for_box_sizing)),
             max_block_size: max_block_size.map(|size| adjust(size, adjustment_for_box_sizing)),
             min_block_size: adjust(min_block_size, adjustment_for_box_sizing),
             candidate_value: Au(0),
-            status: InitialCandidateBSizeStatus,
+            status: CandidateBSizeIteratorStatus::Initial,
         };
 
         fn adjust(size: Au, delta: Au) -> Au {
             max(size - delta, Au(0))
         }
     }
 }
 
 impl Iterator<MaybeAuto> for CandidateBSizeIterator {
     fn next(&mut self) -> Option<MaybeAuto> {
         self.status = match self.status {
-            InitialCandidateBSizeStatus => TryingBSizeCandidateBSizeStatus,
-            TryingBSizeCandidateBSizeStatus => {
+            CandidateBSizeIteratorStatus::Initial => CandidateBSizeIteratorStatus::Trying,
+            CandidateBSizeIteratorStatus::Trying => {
                 match self.max_block_size {
                     Some(max_block_size) if self.candidate_value > max_block_size => {
-                        TryingMaxCandidateBSizeStatus
+                        CandidateBSizeIteratorStatus::TryingMax
                     }
-                    _ if self.candidate_value < self.min_block_size => TryingMinCandidateBSizeStatus,
-                    _ => FoundCandidateBSizeStatus,
+                    _ if self.candidate_value < self.min_block_size => CandidateBSizeIteratorStatus::TryingMin,
+                    _ => CandidateBSizeIteratorStatus::Found,
                 }
             }
-            TryingMaxCandidateBSizeStatus => {
+            CandidateBSizeIteratorStatus::TryingMax => {
                 if self.candidate_value < self.min_block_size {
-                    TryingMinCandidateBSizeStatus
+                    CandidateBSizeIteratorStatus::TryingMin
                 } else {
-                    FoundCandidateBSizeStatus
+                    CandidateBSizeIteratorStatus::Found
                 }
             }
-            TryingMinCandidateBSizeStatus | FoundCandidateBSizeStatus => {
-                FoundCandidateBSizeStatus
+            CandidateBSizeIteratorStatus::TryingMin | CandidateBSizeIteratorStatus::Found => {
+                CandidateBSizeIteratorStatus::Found
             }
         };
 
         match self.status {
-            TryingBSizeCandidateBSizeStatus => Some(self.block_size),
-            TryingMaxCandidateBSizeStatus => {
-                Some(Specified(self.max_block_size.unwrap()))
+            CandidateBSizeIteratorStatus::Trying => Some(self.block_size),
+            CandidateBSizeIteratorStatus::TryingMax => {
+                Some(MaybeAuto::Specified(self.max_block_size.unwrap()))
             }
-            TryingMinCandidateBSizeStatus => {
-                Some(Specified(self.min_block_size))
+            CandidateBSizeIteratorStatus::TryingMin => {
+                Some(MaybeAuto::Specified(self.min_block_size))
             }
-            FoundCandidateBSizeStatus => None,
-            InitialCandidateBSizeStatus => panic!(),
+            CandidateBSizeIteratorStatus::Found => None,
+            CandidateBSizeIteratorStatus::Initial => panic!(),
         }
     }
 }
 
 enum CandidateBSizeIteratorStatus {
-    InitialCandidateBSizeStatus,
-    TryingBSizeCandidateBSizeStatus,
-    TryingMaxCandidateBSizeStatus,
-    TryingMinCandidateBSizeStatus,
-    FoundCandidateBSizeStatus,
+    Initial,
+    Trying,
+    TryingMax,
+    TryingMin,
+    Found,
 }
 
 // A helper function used in block-size calculation.
 fn translate_including_floats(cur_b: &mut Au, delta: Au, floats: &mut Floats) {
     *cur_b = *cur_b + delta;
     let writing_mode = floats.writing_mode;
     floats.translate(LogicalSize::new(writing_mode, Au(0), -delta));
 }
@@ -474,35 +474,35 @@ impl<'a> PostorderFlowTraversal for Abso
             return;
         }
 
         flow.store_overflow(self.layout_context);
     }
 }
 
 pub enum BlockType {
-    BlockReplacedType,
-    BlockNonReplacedType,
-    AbsoluteReplacedType,
-    AbsoluteNonReplacedType,
-    FloatReplacedType,
-    FloatNonReplacedType,
+    Replaced,
+    NonReplaced,
+    AbsoluteReplaced,
+    AbsoluteNonReplaced,
+    FloatReplaced,
+    FloatNonReplaced,
 }
 
 #[deriving(Clone, PartialEq)]
 pub enum MarginsMayCollapseFlag {
     MarginsMayCollapse,
     MarginsMayNotCollapse,
 }
 
 #[deriving(PartialEq)]
 enum FormattingContextType {
-    NonformattingContext,
-    BlockFormattingContext,
-    OtherFormattingContext,
+    None,
+    Block,
+    Other,
 }
 
 // Propagates the `layers_needed_for_descendants` flag appropriately from a child. This is called
 // as part of block-size assignment.
 //
 // If any fixed descendants of kids are present, this kid needs a layer.
 //
 // FIXME(#2006, pcwalton): This is too layer-happy. Like WebKit, we shouldn't do this unless
@@ -566,65 +566,65 @@ impl<'a,E,S> Encodable<S,E> for BlockFlo
         self.bits().encode(e)
     }
 }
 
 impl BlockFlow {
     pub fn from_node(constructor: &mut FlowConstructor, node: &ThreadSafeLayoutNode) -> BlockFlow {
         let writing_mode = node.style().writing_mode;
         BlockFlow {
-            base: BaseFlow::new(Some((*node).clone()), writing_mode, ForceNonfloated),
+            base: BaseFlow::new(Some((*node).clone()), writing_mode, ForceNonfloatedFlag::ForceNonfloated),
             fragment: Fragment::new(constructor, node),
             static_b_offset: Au::new(0),
             inline_size_of_preceding_left_floats: Au(0),
             inline_size_of_preceding_right_floats: Au(0),
             hypothetical_position: LogicalPoint::new(writing_mode, Au(0), Au(0)),
             float: None,
             flags: BlockFlowFlags::empty(),
         }
     }
 
     pub fn from_node_and_fragment(node: &ThreadSafeLayoutNode, fragment: Fragment) -> BlockFlow {
         let writing_mode = node.style().writing_mode;
         BlockFlow {
-            base: BaseFlow::new(Some((*node).clone()), writing_mode, ForceNonfloated),
+            base: BaseFlow::new(Some((*node).clone()), writing_mode, ForceNonfloatedFlag::ForceNonfloated),
             fragment: fragment,
             static_b_offset: Au::new(0),
             inline_size_of_preceding_left_floats: Au(0),
             inline_size_of_preceding_right_floats: Au(0),
             hypothetical_position: LogicalPoint::new(writing_mode, Au(0), Au(0)),
             float: None,
             flags: BlockFlowFlags::empty(),
         }
     }
 
     pub fn float_from_node(constructor: &mut FlowConstructor,
                            node: &ThreadSafeLayoutNode,
                            float_kind: FloatKind)
                            -> BlockFlow {
         let writing_mode = node.style().writing_mode;
         BlockFlow {
-            base: BaseFlow::new(Some((*node).clone()), writing_mode, FloatIfNecessary),
+            base: BaseFlow::new(Some((*node).clone()), writing_mode, ForceNonfloatedFlag::FloatIfNecessary),
             fragment: Fragment::new(constructor, node),
             static_b_offset: Au::new(0),
             inline_size_of_preceding_left_floats: Au(0),
             inline_size_of_preceding_right_floats: Au(0),
             hypothetical_position: LogicalPoint::new(writing_mode, Au(0), Au(0)),
             float: Some(box FloatedBlockInfo::new(float_kind)),
             flags: BlockFlowFlags::empty(),
         }
     }
 
     pub fn float_from_node_and_fragment(node: &ThreadSafeLayoutNode,
                                         fragment: Fragment,
                                         float_kind: FloatKind)
                                         -> BlockFlow {
         let writing_mode = node.style().writing_mode;
         BlockFlow {
-            base: BaseFlow::new(Some((*node).clone()), writing_mode, FloatIfNecessary),
+            base: BaseFlow::new(Some((*node).clone()), writing_mode, ForceNonfloatedFlag::FloatIfNecessary),
             fragment: fragment,
             static_b_offset: Au::new(0),
             inline_size_of_preceding_left_floats: Au(0),
             inline_size_of_preceding_right_floats: Au(0),
             hypothetical_position: LogicalPoint::new(writing_mode, Au(0), Au(0)),
             float: Some(box FloatedBlockInfo::new(float_kind)),
             flags: BlockFlowFlags::empty(),
         }
@@ -632,62 +632,62 @@ impl BlockFlow {
 
     /// Return the type of this block.
     ///
     /// This determines the algorithm used to calculate inline-size, block-size, and the
     /// relevant margins for this Block.
     pub fn block_type(&self) -> BlockType {
         if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
             if self.is_replaced_content() {
-                AbsoluteReplacedType
+                BlockType::AbsoluteReplaced
             } else {
-                AbsoluteNonReplacedType
+                BlockType::AbsoluteNonReplaced
             }
         } else if self.base.flags.is_float() {
             if self.is_replaced_content() {
-                FloatReplacedType
+                BlockType::FloatReplaced
             } else {
-                FloatNonReplacedType
+                BlockType::FloatNonReplaced
             }
         } else {
             if self.is_replaced_content() {
-                BlockReplacedType
+                BlockType::Replaced
             } else {
-                BlockNonReplacedType
+                BlockType::NonReplaced
             }
         }
     }
 
     /// Compute the actual inline size and position for this block.
     pub fn compute_used_inline_size(&mut self,
                                     ctx: &LayoutContext,
                                     containing_block_inline_size: Au) {
         let block_type = self.block_type();
         match block_type {
-            AbsoluteReplacedType => {
+            BlockType::AbsoluteReplaced => {
                 let inline_size_computer = AbsoluteReplaced;
                 inline_size_computer.compute_used_inline_size(self, ctx, containing_block_inline_size);
             }
-            AbsoluteNonReplacedType => {
+            BlockType::AbsoluteNonReplaced => {
                 let inline_size_computer = AbsoluteNonReplaced;
                 inline_size_computer.compute_used_inline_size(self, ctx, containing_block_inline_size);
             }
-            FloatReplacedType => {
+            BlockType::FloatReplaced => {
                 let inline_size_computer = FloatReplaced;
                 inline_size_computer.compute_used_inline_size(self, ctx, containing_block_inline_size);
             }
-            FloatNonReplacedType => {
+            BlockType::FloatNonReplaced => {
                 let inline_size_computer = FloatNonReplaced;
                 inline_size_computer.compute_used_inline_size(self, ctx, containing_block_inline_size);
             }
-            BlockReplacedType => {
+            BlockType::Replaced => {
                 let inline_size_computer = BlockReplaced;
                 inline_size_computer.compute_used_inline_size(self, ctx, containing_block_inline_size);
             }
-            BlockNonReplacedType => {
+            BlockType::NonReplaced => {
                 let inline_size_computer = BlockNonReplaced;
                 inline_size_computer.compute_used_inline_size(self, ctx, containing_block_inline_size);
             }
         }
     }
 
     /// Return this flow's fragment.
     pub fn fragment<'a>(&'a mut self) -> &'a mut Fragment {
@@ -762,17 +762,17 @@ impl BlockFlow {
     }
 
     /// Return true if this has a replaced fragment.
     ///
     /// The only two types of replaced fragments currently are text fragments
     /// and image fragments.
     fn is_replaced_content(&self) -> bool {
         match self.fragment.specific {
-            ScannedTextFragment(_) | ImageFragment(_) | InlineBlockFragment(_) => true,
+            SpecificFragmentInfo::ScannedText(_) | SpecificFragmentInfo::Image(_) | SpecificFragmentInfo::InlineBlock(_) => true,
             _ => false,
         }
     }
 
     /// Return shrink-to-fit inline-size.
     ///
     /// This is where we use the preferred inline-sizes and minimum inline-sizes
     /// calculated in the bubble-inline-sizes traversal.
@@ -788,21 +788,21 @@ impl BlockFlow {
     /// TODO(#2017, pcwalton): This is somewhat inefficient (traverses kids twice); can we do
     /// better?
     fn adjust_fragments_for_collapsed_margins_if_root(&mut self) {
         if !self.is_root() {
             return
         }
 
         let (block_start_margin_value, block_end_margin_value) = match self.base.collapsible_margins {
-            MarginsCollapseThrough(_) => panic!("Margins unexpectedly collapsed through root flow."),
-            MarginsCollapse(block_start_margin, block_end_margin) => {
+            CollapsibleMargins::CollapseThrough(_) => panic!("Margins unexpectedly collapsed through root flow."),
+            CollapsibleMargins::Collapse(block_start_margin, block_end_margin) => {
                 (block_start_margin.collapse(), block_end_margin.collapse())
             }
-            NoCollapsibleMargins(block_start, block_end) => (block_start, block_end),
+            CollapsibleMargins::None(block_start, block_end) => (block_start, block_end),
         };
 
         // Shift all kids down (or up, if margins are negative) if necessary.
         if block_start_margin_value != Au(0) {
             for kid in self.base.child_iter() {
                 let kid_base = flow::mut_base(kid);
                 kid_base.position.start.b = kid_base.position.start.b + block_start_margin_value
             }
@@ -835,30 +835,30 @@ impl BlockFlow {
 
         if self.base.restyle_damage.contains(REFLOW) {
             // Our current border-box position.
             let mut cur_b = Au(0);
 
             // Absolute positioning establishes a block formatting context. Don't propagate floats
             // in or out. (But do propagate them between kids.)
             if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) ||
-                    margins_may_collapse != MarginsMayCollapse {
+                    margins_may_collapse != MarginsMayCollapseFlag::MarginsMayCollapse {
                 self.base.floats = Floats::new(self.fragment.style.writing_mode);
             }
 
             let mut margin_collapse_info = MarginCollapseInfo::new();
             self.base.floats.translate(LogicalSize::new(
                 self.fragment.style.writing_mode, -self.fragment.inline_start_offset(), Au(0)));
 
             // The sum of our block-start border and block-start padding.
             let block_start_offset = self.fragment.border_padding.block_start;
             translate_including_floats(&mut cur_b, block_start_offset, &mut self.base.floats);
 
             let can_collapse_block_start_margin_with_kids =
-                margins_may_collapse == MarginsMayCollapse &&
+                margins_may_collapse == MarginsMayCollapseFlag::MarginsMayCollapse &&
                 !self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) &&
                 self.fragment.border_padding.block_start == Au(0);
             margin_collapse_info.initialize_block_start_margin(
                 &self.fragment,
                 can_collapse_block_start_margin_with_kids);
 
             // At this point, `cur_b` is at the content edge of our box. Now iterate over children.
             let mut floats = self.base.floats.clone();
@@ -919,19 +919,19 @@ impl BlockFlow {
                 let delta = margin_collapse_info.advance_block_start_margin(
                     &flow::base(kid).collapsible_margins);
                 translate_including_floats(&mut cur_b, delta, &mut floats);
 
                 // Clear past the floats that came in, if necessary.
                 let clearance = match (flow::base(kid).flags.contains(CLEARS_LEFT),
                                        flow::base(kid).flags.contains(CLEARS_RIGHT)) {
                     (false, false) => Au(0),
-                    (true, false) => floats.clearance(ClearLeft),
-                    (false, true) => floats.clearance(ClearRight),
-                    (true, true) => floats.clearance(ClearBoth),
+                    (true, false) => floats.clearance(ClearType::Left),
+                    (false, true) => floats.clearance(ClearType::Right),
+                    (true, true) => floats.clearance(ClearType::Both),
                 };
                 translate_including_floats(&mut cur_b, clearance, &mut floats);
 
                 // At this point, `cur_b` is at the border edge of the child.
                 flow::mut_base(kid).position.start.b = cur_b;
 
                 // Now pull out the child's outgoing floats. We didn't do this immediately after
                 // the `assign_block_size_for_inorder_child_if_necessary` call because clearance on
@@ -956,17 +956,17 @@ impl BlockFlow {
             // order (CSS 2.1, Appendix E).
             self.base.flags.set(LAYERS_NEEDED_FOR_DESCENDANTS, layers_needed_for_descendants);
 
             // Collect various offsets needed by absolutely positioned descendants.
             (&mut *self as &mut Flow).collect_static_block_offsets_from_children();
 
             // Add in our block-end margin and compute our collapsible margins.
             let can_collapse_block_end_margin_with_kids =
-                margins_may_collapse == MarginsMayCollapse &&
+                margins_may_collapse == MarginsMayCollapseFlag::MarginsMayCollapse &&
                 !self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) &&
                 self.fragment.border_padding.block_end == Au(0);
             let (collapsible_margins, delta) =
                 margin_collapse_info.finish_and_compute_collapsible_margins(
                 &self.fragment,
                 can_collapse_block_end_margin_with_kids);
             self.base.collapsible_margins = collapsible_margins;
             translate_including_floats(&mut cur_b, delta, &mut floats);
@@ -978,21 +978,21 @@ impl BlockFlow {
             let mut block_size = cur_b - block_start_offset;
             let is_root = self.is_root();
             if is_root {
                 let screen_size = LogicalSize::from_physical(self.fragment.style.writing_mode,
                                                              layout_context.shared.screen_size);
                 block_size = Au::max(screen_size.block, block_size)
             }
 
-            if is_root || self.formatting_context_type() != NonformattingContext ||
+            if is_root || self.formatting_context_type() != FormattingContextType::None ||
                     self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
                 // The content block-size includes all the floats per CSS 2.1 § 10.6.7. The easiest
                 // way to handle this is to just treat it as clearance.
-                block_size = block_size + floats.clearance(ClearBoth);
+                block_size = block_size + floats.clearance(ClearType::Both);
             }
 
             if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
                 // Fixed position layers get layers.
                 if self.is_fixed() {
                     self.base.flags.insert(NEEDS_LAYER);
                 }
 
@@ -1009,18 +1009,18 @@ impl BlockFlow {
             let mut candidate_block_size_iterator = CandidateBSizeIterator::new(
                 &self.fragment,
                 self.base.block_container_explicit_block_size);
             loop {
                 match candidate_block_size_iterator.next() {
                     Some(candidate_block_size) => {
                         candidate_block_size_iterator.candidate_value =
                             match candidate_block_size {
-                                Auto => block_size,
-                                Specified(value) => value
+                                MaybeAuto::Auto => block_size,
+                                MaybeAuto::Specified(value) => value
                             }
                     }
                     None => break,
                 }
             }
 
             // Adjust `cur_b` as necessary to account for the explicitly-specified block-size.
             block_size = candidate_block_size_iterator.candidate_value;
@@ -1064,17 +1064,17 @@ impl BlockFlow {
             });
         }
 
         // Don't remove the dirty bits yet if we're absolutely-positioned, since our final size
         // has not been calculated yet. (See `calculate_absolute_block_size_and_margins` for that.)
         // Also don't remove the dirty bits if we're a block formatting context since our inline
         // size has not yet been computed. (See `assign_inline_position_for_formatting_context()`.)
         if (self.base.flags.is_float() ||
-                self.formatting_context_type() == NonformattingContext) &&
+                self.formatting_context_type() == FormattingContextType::None) &&
                 !self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
             self.base.restyle_damage.remove(REFLOW_OUT_OF_FLOW | REFLOW);
         }
     }
 
     /// Add placement information about current float flow for use by the parent.
     ///
     /// Also, use information given by parent about other floats to find out our relative position.
@@ -1142,22 +1142,22 @@ impl BlockFlow {
         let content_block_size = self.fragment.content_box().size.block;
 
         let mut solution = None;
         {
             // Non-auto margin-block-start and margin-block-end values have already been
             // calculated during assign-inline-size.
             let margin = self.fragment.style().logical_margin();
             let margin_block_start = match margin.block_start {
-                LPA_Auto => Auto,
-                _ => Specified(self.fragment.margin.block_start)
+                LengthOrPercentageOrAuto::Auto => MaybeAuto::Auto,
+                _ => MaybeAuto::Specified(self.fragment.margin.block_start)
             };
             let margin_block_end = match margin.block_end {
-                LPA_Auto => Auto,
-                _ => Specified(self.fragment.margin.block_end)
+                LengthOrPercentageOrAuto::Auto => MaybeAuto::Auto,
+                _ => MaybeAuto::Specified(self.fragment.margin.block_end)
             };
 
             let block_start;
             let block_end;
             {
                 let position = self.fragment.style().logical_position();
                 block_start = MaybeAuto::from_style(position.block_start,
                                                     containing_block_block_size);
@@ -1287,30 +1287,30 @@ impl BlockFlow {
 
         // Remember the inline-sizes of the last left and right floats, if there were any. These
         // are used for estimating the inline-sizes of block formatting contexts. (We estimate that
         // the inline-size of any block formatting context that we see will be based on the
         // inline-size of the containing block as well as the last float seen before it in each
         // direction.)
         let mut inline_size_of_preceding_left_floats = Au(0);
         let mut inline_size_of_preceding_right_floats = Au(0);
-        if self.formatting_context_type() == NonformattingContext {
+        if self.formatting_context_type() == FormattingContextType::None {
             inline_size_of_preceding_left_floats = self.inline_size_of_preceding_left_floats;
             inline_size_of_preceding_right_floats = self.inline_size_of_preceding_right_floats;
         }
 
         // Calculate non-auto block size to pass to children.
         let content_block_size = self.fragment.style().content_block_size();
         let explicit_content_size = match (content_block_size,
                                            self.base.block_container_explicit_block_size) {
-            (LPA_Percentage(percent), Some(container_size)) => {
+            (LengthOrPercentageOrAuto::Percentage(percent), Some(container_size)) => {
                 Some(container_size.scale_by(percent))
             }
-            (LPA_Percentage(_), None) | (LPA_Auto, _) => None,
-            (LPA_Length(length), _) => Some(length),
+            (LengthOrPercentageOrAuto::Percentage(_), None) | (LengthOrPercentageOrAuto::Auto, _) => None,
+            (LengthOrPercentageOrAuto::Length(length), _) => Some(length),
         };
 
         // Calculate containing block inline size.
         let containing_block_size = if flags.contains(IS_ABSOLUTELY_POSITIONED) {
             self.containing_block_size(layout_context.shared.screen_size).inline
         } else {
             content_inline_size
         };
@@ -1405,24 +1405,24 @@ impl BlockFlow {
         }
     }
 
     /// Determines the type of formatting context this is. See the definition of
     /// `FormattingContextType`.
     fn formatting_context_type(&self) -> FormattingContextType {
         let style = self.fragment.style();
         if style.get_box().float != float::none {
-            return OtherFormattingContext
+            return FormattingContextType::Other
         }
         match style.get_box().display {
             display::table_cell | display::table_caption | display::inline_block => {
-                OtherFormattingContext
+                FormattingContextType::Other
             }
-            _ if style.get_box().overflow != overflow::visible => BlockFormattingContext,
-            _ => NonformattingContext,
+            _ if style.get_box().overflow != overflow::visible => FormattingContextType::Block,
+            _ => FormattingContextType::None,
         }
     }
 
     /// Per CSS 2.1 § 9.5, block formatting contexts' inline widths and positions are affected by
     /// the presence of floats. This is the part of the assign-heights traversal that computes
     /// the final inline position and width for such flows.
     ///
     /// Note that this is part of the assign-block-sizes traversal, not the assign-inline-sizes
@@ -1430,31 +1430,31 @@ impl BlockFlow {
     /// until heights are assigned. To work around this unfortunate circular dependency, by the
     /// time we get here we have already estimated the width of the block formatting context based
     /// on the floats we could see at the time of inline-size assignment. The job of this function,
     /// therefore, is not only to assign the final size but also to perform the layout again for
     /// this block formatting context if our speculation was wrong.
     ///
     /// FIXME(pcwalton): This code is not incremental-reflow-safe (i.e. not idempotent).
     fn assign_inline_position_for_formatting_context(&mut self) {
-        debug_assert!(self.formatting_context_type() != NonformattingContext);
+        debug_assert!(self.formatting_context_type() != FormattingContextType::None);
 
         if !self.base.restyle_damage.intersects(REFLOW_OUT_OF_FLOW | REFLOW) {
             return
         }
 
         let info = PlacementInfo {
             size: LogicalSize::new(self.fragment.style.writing_mode,
                                    self.base.position.size.inline +
                                         self.fragment.margin.inline_start_end() +
                                         self.fragment.border_padding.inline_start_end(),
                                    self.fragment.border_box.size.block),
             ceiling: self.base.position.start.b,
             max_inline_size: MAX_AU,
-            kind: FloatLeft,
+            kind: FloatKind::Left,
         };
 
         // Offset our position by whatever displacement is needed to not impact the floats.
         let rect = self.base.floats.place_between_floats(&info);
         self.base.position.start.i = self.hypothetical_position.i + rect.start.i;
 
         // TODO(pcwalton): If the inline-size of this flow is different from the size we estimated
         // earlier, lay it out again.
@@ -1477,17 +1477,17 @@ impl BlockFlow {
             preferred_inline_size: self.base.intrinsic_inline_sizes.preferred_inline_size -
                                     surrounding_inline_size,
         }
     }
 }
 
 impl Flow for BlockFlow {
     fn class(&self) -> FlowClass {
-        BlockFlowClass
+        FlowClass::Block
     }
 
     fn as_block<'a>(&'a mut self) -> &'a mut BlockFlow {
         self
     }
 
     fn as_immutable_block<'a>(&'a self) -> &'a BlockFlow {
         self
@@ -1505,17 +1505,17 @@ impl Flow for BlockFlow {
         let mut flags = self.base.flags;
         flags.remove(HAS_LEFT_FLOATED_DESCENDANTS);
         flags.remove(HAS_RIGHT_FLOATED_DESCENDANTS);
 
         // If this block has a fixed width, just use that for the minimum
         // and preferred width, rather than bubbling up children inline
         // width.
         let fixed_width = match self.fragment.style().get_box().width {
-            LPA_Length(_) => true,
+            LengthOrPercentageOrAuto::Length(_) => true,
             _ => false,
         };
 
         // Find the maximum inline-size from children.
         let mut computation = self.fragment.compute_intrinsic_inline_sizes();
         let mut left_float_width = Au(0);
         let mut right_float_width = Au(0);
         for kid in self.base.child_iter() {
@@ -1597,30 +1597,30 @@ impl Flow for BlockFlow {
         }
 
         // Our inline-size was set to the inline-size of the containing block by the flow's parent.
         // Now compute the real value.
         self.propagate_and_compute_used_inline_size(layout_context);
 
         // Formatting contexts are never impacted by floats.
         match self.formatting_context_type() {
-            NonformattingContext => {}
-            BlockFormattingContext => {
+            FormattingContextType::None => {}
+            FormattingContextType::Block => {
                 self.base.flags.remove(IMPACTED_BY_LEFT_FLOATS);
                 self.base.flags.remove(IMPACTED_BY_RIGHT_FLOATS);
 
                 // We can't actually compute the inline-size of this block now, because floats
                 // might affect it. Speculate that its inline-size is equal to the inline-size
                 // computed above minus the inline-size of the previous left and/or right floats.
                 self.fragment.border_box.size.inline =
                     self.fragment.border_box.size.inline -
                     self.inline_size_of_preceding_left_floats -
                     self.inline_size_of_preceding_right_floats;
             }
-            OtherFormattingContext => {
+            FormattingContextType::Other => {
                 self.base.flags.remove(IMPACTED_BY_LEFT_FLOATS);
                 self.base.flags.remove(IMPACTED_BY_RIGHT_FLOATS);
             }
         }
 
         // Move in from the inline-start border edge.
         let inline_start_content_edge = self.fragment.border_box.start.i +
             self.fragment.border_padding.inline_start;
@@ -1641,17 +1641,17 @@ impl Flow for BlockFlow {
 
     fn assign_block_size_for_inorder_child_if_necessary<'a>(&mut self,
                                                             layout_context: &'a LayoutContext<'a>)
                                                             -> bool {
         if self.base.flags.is_float() {
             return false
         }
 
-        let is_formatting_context = self.formatting_context_type() != NonformattingContext;
+        let is_formatting_context = self.formatting_context_type() != FormattingContextType::None;
         if !self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) && is_formatting_context {
             self.assign_inline_position_for_formatting_context();
         }
 
         if self.base.flags.impacted_by_floats() {
             if self.base.restyle_damage.intersects(REFLOW_OUT_OF_FLOW | REFLOW) {
                 self.assign_block_size(layout_context);
                 // Don't remove the restyle damage; `assign_block_size` decides whether that is
@@ -1682,20 +1682,20 @@ impl Flow for BlockFlow {
                 self.base.block_container_explicit_block_size.unwrap_or(Au(0));
             self.fragment.assign_replaced_block_size_if_necessary(containing_block_block_size);
             if !self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
                 self.base.position.size.block = self.fragment.border_box.size.block;
             }
         } else if self.is_root() || self.base.flags.is_float() || self.is_inline_block() {
             // Root element margins should never be collapsed according to CSS § 8.3.1.
             debug!("assign_block_size: assigning block_size for root flow");
-            self.assign_block_size_block_base(ctx, MarginsMayNotCollapse);
+            self.assign_block_size_block_base(ctx, MarginsMayCollapseFlag::MarginsMayNotCollapse);
         } else {
             debug!("assign_block_size: assigning block_size for block");
-            self.assign_block_size_block_base(ctx, MarginsMayCollapse);
+            self.assign_block_size_block_base(ctx, MarginsMayCollapseFlag::MarginsMayCollapse);
         }
     }
 
     fn compute_absolute_position(&mut self) {
         // FIXME(#2795): Get the real container size
         let container_size = Size2D::zero();
 
         if self.is_root() {
@@ -1834,26 +1834,26 @@ impl Flow for BlockFlow {
     }
 
     fn is_absolute_containing_block(&self) -> bool {
         self.is_positioned()
     }
 
     fn update_late_computed_inline_position_if_necessary(&mut self, inline_position: Au) {
         if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) &&
-                self.fragment.style().logical_position().inline_start == LPA_Auto &&
-                self.fragment.style().logical_position().inline_end == LPA_Auto {
+                self.fragment.style().logical_position().inline_start == LengthOrPercentageOrAuto::Auto &&
+                self.fragment.style().logical_position().inline_end == LengthOrPercentageOrAuto::Auto {
             self.base.position.start.i = inline_position
         }
     }
 
     fn update_late_computed_block_position_if_necessary(&mut self, block_position: Au) {
         if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) &&
-                self.fragment.style().logical_position().block_start == LPA_Auto &&
-                self.fragment.style().logical_position().block_end == LPA_Auto {
+                self.fragment.style().logical_position().block_start == LengthOrPercentageOrAuto::Auto &&
+                self.fragment.style().logical_position().block_end == LengthOrPercentageOrAuto::Auto {
             self.base.position.start.b = block_position
         }
     }
 
     fn build_display_list(&mut self, layout_context: &LayoutContext) {
         self.build_display_list_for_block(box DisplayList::new(), layout_context);
         if opts::get().validate_display_list_geometry {
             self.base.validate_display_list_geometry();
@@ -1971,21 +1971,21 @@ pub trait ISizeAndMarginsComputer {
         block.fragment.compute_border_and_padding(containing_block_inline_size);
 
         let mut computed_inline_size = self.initial_computed_inline_size(block,
                                                                          parent_flow_inline_size,
                                                                          layout_context);
 
         let style = block.fragment.style();
         match (computed_inline_size, style.get_box().box_sizing) {
-            (Specified(size), box_sizing::border_box) => {
+            (MaybeAuto::Specified(size), box_sizing::border_box) => {
                 computed_inline_size =
-                    Specified(size - block.fragment.border_padding.inline_start_end())
+                    MaybeAuto::Specified(size - block.fragment.border_padding.inline_start_end())
             }
-            (Auto, box_sizing::border_box) | (_, box_sizing::content_box) => {}
+            (MaybeAuto::Auto, box_sizing::border_box) | (_, box_sizing::content_box) => {}
         }
 
         // The text alignment of a block flow is the text alignment of its box's style.
         block.base.flags.set_text_align(style.get_inheritedtext().text_align);
 
         let margin = style.logical_margin();
         let position = style.logical_position();
 
@@ -2085,29 +2085,29 @@ pub trait ISizeAndMarginsComputer {
         let mut solution = self.solve_inline_size_constraints(block, &input);
 
         // If the tentative used inline-size is greater than 'max-inline-size', inline-size should
         // be recalculated, but this time using the computed value of 'max-inline-size' as the
         // computed value for 'inline-size'.
         match specified_or_none(block.fragment().style().max_inline_size(),
                                 containing_block_inline_size) {
             Some(max_inline_size) if max_inline_size < solution.inline_size => {
-                input.computed_inline_size = Specified(max_inline_size);
+                input.computed_inline_size = MaybeAuto::Specified(max_inline_size);
                 solution = self.solve_inline_size_constraints(block, &input);
             }
             _ => {}
         }
 
         // If the resulting inline-size is smaller than 'min-inline-size', inline-size should be
         // recalculated, but this time using the value of 'min-inline-size' as the computed value
         // for 'inline-size'.
         let computed_min_inline_size = specified(block.fragment().style().min_inline_size(),
                                                  containing_block_inline_size);
         if computed_min_inline_size > solution.inline_size {
-            input.computed_inline_size = Specified(computed_min_inline_size);
+            input.computed_inline_size = MaybeAuto::Specified(computed_min_inline_size);
             solution = self.solve_inline_size_constraints(block, &input);
         }
 
         self.set_inline_size_constraint_solutions(block, solution);
         self.set_flow_x_coord_if_necessary(block, solution);
     }
 
     /// Computes inline-start and inline-end margins and inline-size.
@@ -2126,60 +2126,60 @@ pub trait ISizeAndMarginsComputer {
             (input.computed_inline_size,
              input.inline_start_margin,
              input.inline_end_margin,
              input.available_inline_size);
 
         // If inline-size is not 'auto', and inline-size + margins > available_inline-size, all
         // 'auto' margins are treated as 0.
         let (inline_start_margin, inline_end_margin) = match computed_inline_size {
-            Auto => (inline_start_margin, inline_end_margin),
-            Specified(inline_size) => {
+            MaybeAuto::Auto => (inline_start_margin, inline_end_margin),
+            MaybeAuto::Specified(inline_size) => {
                 let inline_start = inline_start_margin.specified_or_zero();
                 let inline_end = inline_end_margin.specified_or_zero();
 
                 if (inline_start + inline_end + inline_size) > available_inline_size {
-                    (Specified(inline_start), Specified(inline_end))
+                    (MaybeAuto::Specified(inline_start), MaybeAuto::Specified(inline_end))
                 } else {
                     (inline_start_margin, inline_end_margin)
                 }
             }
         };
 
         // Invariant: inline-start_margin + inline-size + inline-end_margin ==
         // available_inline-size
         let (inline_start_margin, inline_size, inline_end_margin) =
             match (inline_start_margin, computed_inline_size, inline_end_margin) {
                 // If all have a computed value other than 'auto', the system is
                 // over-constrained so we discard the end margin.
-                (Specified(margin_start), Specified(inline_size), Specified(_margin_end)) =>
+                (MaybeAuto::Specified(margin_start), MaybeAuto::Specified(inline_size), MaybeAuto::Specified(_margin_end)) =>
                     (margin_start, inline_size, available_inline_size -
                      (margin_start + inline_size)),
 
                 // If exactly one value is 'auto', solve for it
-                (Auto, Specified(inline_size), Specified(margin_end)) =>
+                (MaybeAuto::Auto, MaybeAuto::Specified(inline_size), MaybeAuto::Specified(margin_end)) =>
                     (available_inline_size - (inline_size + margin_end), inline_size, margin_end),
-                (Specified(margin_start), Auto, Specified(margin_end)) =>
+                (MaybeAuto::Specified(margin_start), MaybeAuto::Auto, MaybeAuto::Specified(margin_end)) =>
                     (margin_start, available_inline_size - (margin_start + margin_end),
                      margin_end),
-                (Specified(margin_start), Specified(inline_size), Auto) =>
+                (MaybeAuto::Specified(margin_start), MaybeAuto::Specified(inline_size), MaybeAuto::Auto) =>
                     (margin_start, inline_size, available_inline_size -
                      (margin_start + inline_size)),
 
                 // If inline-size is set to 'auto', any other 'auto' value becomes '0',
                 // and inline-size is solved for
-                (Auto, Auto, Specified(margin_end)) =>
+                (MaybeAuto::Auto, MaybeAuto::Auto, MaybeAuto::Specified(margin_end)) =>
                     (Au::new(0), available_inline_size - margin_end, margin_end),
-                (Specified(margin_start), Auto, Auto) =>
+                (MaybeAuto::Specified(margin_start), MaybeAuto::Auto, MaybeAuto::Auto) =>
                     (margin_start, available_inline_size - margin_start, Au::new(0)),
-                (Auto, Auto, Auto) =>
+                (MaybeAuto::Auto, MaybeAuto::Auto, MaybeAuto::Auto) =>
                     (Au::new(0), available_inline_size, Au::new(0)),
 
                 // If inline-start and inline-end margins are auto, they become equal
-                (Auto, Specified(inline_size), Auto) => {
+                (MaybeAuto::Auto, MaybeAuto::Specified(inline_size), MaybeAuto::Auto) => {
                     let margin = (available_inline_size - inline_size).scale_by(0.5);
                     (margin, inline_size, margin)
                 }
             };
         ISizeConstraintSolution::new(inline_size, inline_start_margin, inline_end_margin)
     }
 }
 
@@ -2224,105 +2224,105 @@ impl ISizeAndMarginsComputer for Absolut
         // Assume direction is 'ltr' for now
 
         // Distance from the inline-start edge of the Absolute Containing Block to the
         // inline-start margin edge of a hypothetical box that would have been the
         // first box of the element.
         let static_position_inline_start = static_i_offset;
 
         let (inline_start, inline_end, inline_size, margin_inline_start, margin_inline_end) = match (inline_start, inline_end, computed_inline_size) {
-            (Auto, Auto, Auto) => {
+            (MaybeAuto::Auto, MaybeAuto::Auto, MaybeAuto::Auto) => {
                 let margin_start = inline_start_margin.specified_or_zero();
                 let margin_end = inline_end_margin.specified_or_zero();
                 let inline_start = static_position_inline_start;
                 // Now it is the same situation as inline-start Specified and inline-end
                 // and inline-size Auto.
 
                 // Set inline-end to zero to calculate inline-size
                 let inline_size = block.get_shrink_to_fit_inline_size(
                     available_inline_size - (inline_start + margin_start + margin_end));
                 let sum = inline_start + inline_size + margin_start + margin_end;
                 (inline_start, available_inline_size - sum, inline_size, margin_start, margin_end)
             }
-            (Specified(inline_start), Specified(inline_end), Specified(inline_size)) => {
+            (MaybeAuto::Specified(inline_start), MaybeAuto::Specified(inline_end), MaybeAuto::Specified(inline_size)) => {
                 match (inline_start_margin, inline_end_margin) {
-                    (Auto, Auto) => {
+                    (MaybeAuto::Auto, MaybeAuto::Auto) => {
                         let total_margin_val = available_inline_size - inline_start - inline_end - inline_size;
                         if total_margin_val < Au(0) {
                             // margin-inline-start becomes 0 because direction is 'ltr'.
                             // TODO: Handle 'rtl' when it is implemented.
                             (inline_start, inline_end, inline_size, Au(0), total_margin_val)
                         } else {
                             // Equal margins
                             (inline_start, inline_end, inline_size,
                              total_margin_val.scale_by(0.5),
                              total_margin_val.scale_by(0.5))
                         }
                     }
-                    (Specified(margin_start), Auto) => {
+                    (MaybeAuto::Specified(margin_start), MaybeAuto::Auto) => {
                         let sum = inline_start + inline_end + inline_size + margin_start;
                         (inline_start, inline_end, inline_size, margin_start, available_inline_size - sum)
                     }
-                    (Auto, Specified(margin_end)) => {
+                    (MaybeAuto::Auto, MaybeAuto::Specified(margin_end)) => {
                         let sum = inline_start + inline_end + inline_size + margin_end;
                         (inline_start, inline_end, inline_size, available_inline_size - sum, margin_end)
                     }
-                    (Specified(margin_start), Specified(margin_end)) => {
+                    (MaybeAuto::Specified(margin_start), MaybeAuto::Specified(margin_end)) => {
                         // Values are over-constrained.
                         // Ignore value for 'inline-end' cos direction is 'ltr'.
                         // TODO: Handle 'rtl' when it is implemented.
                         let sum = inline_start + inline_size + margin_start + margin_end;
                         (inline_start, available_inline_size - sum, inline_size, margin_start, margin_end)
                     }
                 }
             }
             // For the rest of the cases, auto values for margin are set to 0
 
             // If only one is Auto, solve for it
-            (Auto, Specified(inline_end), Specified(inline_size)) => {
+            (MaybeAuto::Auto, MaybeAuto::Specified(inline_end), MaybeAuto::Specified(inline_size)) => {
                 let margin_start = inline_start_margin.specified_or_zero();
                 let margin_end = inline_end_margin.specified_or_zero();
                 let sum = inline_end + inline_size + margin_start + margin_end;
                 (available_inline_size - sum, inline_end, inline_size, margin_start, margin_end)
             }
-            (Specified(inline_start), Auto, Specified(inline_size)) => {
+            (MaybeAuto::Specified(inline_start), MaybeAuto::Auto, MaybeAuto::Specified(inline_size)) => {
                 let margin_start = inline_start_margin.specified_or_zero();
                 let margin_end = inline_end_margin.specified_or_zero();
                 let sum = inline_start + inline_size + margin_start + margin_end;
                 (inline_start, available_inline_size - sum, inline_size, margin_start, margin_end)
             }
-            (Specified(inline_start), Specified(inline_end), Auto) => {
+            (MaybeAuto::Specified(inline_start), MaybeAuto::Specified(inline_end), MaybeAuto::Auto) => {
                 let margin_start = inline_start_margin.specified_or_zero();
                 let margin_end = inline_end_margin.specified_or_zero();
                 let sum = inline_start + inline_end + margin_start + margin_end;
                 (inline_start, inline_end, available_inline_size - sum, margin_start, margin_end)
             }
 
             // If inline-size is auto, then inline-size is shrink-to-fit. Solve for the
             // non-auto value.
-            (Specified(inline_start), Auto, Auto) => {
+            (MaybeAuto::Specified(inline_start), MaybeAuto::Auto, MaybeAuto::Auto) => {
                 let margin_start = inline_start_margin.specified_or_zero();
                 let margin_end = inline_end_margin.specified_or_zero();
                 // Set inline-end to zero to calculate inline-size
                 let inline_size = block.get_shrink_to_fit_inline_size(
                     available_inline_size - (inline_start + margin_start + margin_end));
                 let sum = inline_start + inline_size + margin_start + margin_end;
                 (inline_start, available_inline_size - sum, inline_size, margin_start, margin_end)
             }
-            (Auto, Specified(inline_end), Auto) => {
+            (MaybeAuto::Auto, MaybeAuto::Specified(inline_end), MaybeAuto::Auto) => {
                 let margin_start = inline_start_margin.specified_or_zero();
                 let margin_end = inline_end_margin.specified_or_zero();
                 // Set inline-start to zero to calculate inline-size
                 let inline_size = block.get_shrink_to_fit_inline_size(
                     available_inline_size - (inline_end + margin_start + margin_end));
                 let sum = inline_end + inline_size + margin_start + margin_end;
                 (available_inline_size - sum, inline_end, inline_size, margin_start, margin_end)
             }
 
-            (Auto, Auto, Specified(inline_size)) => {
+            (MaybeAuto::Auto, MaybeAuto::Auto, MaybeAuto::Specified(inline_size)) => {
                 let margin_start = inline_start_margin.specified_or_zero();
                 let margin_end = inline_end_margin.specified_or_zero();
                 // Setting 'inline-start' to static position because direction is 'ltr'.
                 // TODO: Handle 'rtl' when it is implemented.
                 let inline_start = static_position_inline_start;
                 let sum = inline_start + inline_size + margin_start + margin_end;
                 (inline_start, available_inline_size - sum, inline_size, margin_start, margin_end)
             }
@@ -2369,71 +2369,71 @@ impl ISizeAndMarginsComputer for Absolut
         } = input;
         // TODO: Check for direction of static-position Containing Block (aka
         // parent flow, _not_ the actual Containing Block) when right-to-left
         // is implemented
         // Assume direction is 'ltr' for now
         // TODO: Handle all the cases for 'rtl' direction.
 
         let inline_size = match computed_inline_size {
-            Specified(w) => w,
+            MaybeAuto::Specified(w) => w,
             _ => panic!("{} {}",
                        "The used value for inline_size for absolute replaced flow",
                        "should have already been calculated by now.")
         };
 
         // Distance from the inline-start edge of the Absolute Containing Block to the
         // inline-start margin edge of a hypothetical box that would have been the
         // first box of the element.
         let static_position_inline_start = static_i_offset;
 
         let (inline_start, inline_end, inline_size, margin_inline_start, margin_inline_end) = match (inline_start, inline_end) {
-            (Auto, Auto) => {
+            (MaybeAuto::Auto, MaybeAuto::Auto) => {
                 let inline_start = static_position_inline_start;
                 let margin_start = inline_start_margin.specified_or_zero();
                 let margin_end = inline_end_margin.specified_or_zero();
                 let sum = inline_start + inline_size + margin_start + margin_end;
                 (inline_start, available_inline_size - sum, inline_size, margin_start, margin_end)
             }
             // If only one is Auto, solve for it
-            (Auto, Specified(inline_end)) => {
+            (MaybeAuto::Auto, MaybeAuto::Specified(inline_end)) => {
                 let margin_start = inline_start_margin.specified_or_zero();
                 let margin_end = inline_end_margin.specified_or_zero();
                 let sum = inline_end + inline_size + margin_start + margin_end;
                 (available_inline_size - sum, inline_end, inline_size, margin_start, margin_end)
             }
-            (Specified(inline_start), Auto) => {
+            (MaybeAuto::Specified(inline_start), MaybeAuto::Auto) => {
                 let margin_start = inline_start_margin.specified_or_zero();
                 let margin_end = inline_end_margin.specified_or_zero();
                 let sum = inline_start + inline_size + margin_start + margin_end;
                 (inline_start, available_inline_size - sum, inline_size, margin_start, margin_end)
             }
-            (Specified(inline_start), Specified(inline_end)) => {
+            (MaybeAuto::Specified(inline_start), MaybeAuto::Specified(inline_end)) => {
                 match (inline_start_margin, inline_end_margin) {
-                    (Auto, Auto) => {
+                    (MaybeAuto::Auto, MaybeAuto::Auto) => {
                         let total_margin_val = available_inline_size - inline_start - inline_end - inline_size;
                         if total_margin_val < Au(0) {
                             // margin-inline-start becomes 0 because direction is 'ltr'.
                             (inline_start, inline_end, inline_size, Au(0), total_margin_val)
                         } else {
                             // Equal margins
                             (inline_start, inline_end, inline_size,
                              total_margin_val.scale_by(0.5),
                              total_margin_val.scale_by(0.5))
                         }
                     }
-                    (Specified(margin_start), Auto) => {
+                    (MaybeAuto::Specified(margin_start), MaybeAuto::Auto) => {
                         let sum = inline_start + inline_end + inline_size + margin_start;
                         (inline_start, inline_end, inline_size, margin_start, available_inline_size - sum)
                     }
-                    (Auto, Specified(margin_end)) => {
+                    (MaybeAuto::Auto, MaybeAuto::Specified(margin_end)) => {
                         let sum = inline_start + inline_end + inline_size + margin_end;
                         (inline_start, inline_end, inline_size, available_inline_size - sum, margin_end)
                     }
-                    (Specified(margin_start), Specified(margin_end)) => {
+                    (MaybeAuto::Specified(margin_start), MaybeAuto::Specified(margin_end)) => {
                         // Values are over-constrained.
                         // Ignore value for 'inline-end' cos direction is 'ltr'.
                         let sum = inline_start + inline_size + margin_start + margin_end;
                         (inline_start, available_inline_size - sum, inline_size, margin_start, margin_end)
                     }
                 }
             }
         };
@@ -2447,17 +2447,17 @@ impl ISizeAndMarginsComputer for Absolut
                                     layout_context: &LayoutContext)
                                     -> MaybeAuto {
         let containing_block_inline_size =
             block.containing_block_size(layout_context.shared.screen_size).inline;
         let fragment = block.fragment();
         fragment.assign_replaced_inline_size_if_necessary(containing_block_inline_size);
         // For replaced absolute flow, the rest of the constraint solving will
         // take inline-size to be specified as the value computed here.
-        Specified(fragment.content_inline_size())
+        MaybeAuto::Specified(fragment.content_inline_size())
     }
 
     fn containing_block_inline_size(&self, block: &mut BlockFlow, _: Au, ctx: &LayoutContext) -> Au {
         block.containing_block_size(ctx.shared.screen_size).inline
     }
 
     fn set_flow_x_coord_if_necessary(&self, block: &mut BlockFlow, solution: ISizeConstraintSolution) {
         // Set the x-coordinate of the absolute flow wrt to its containing block.
@@ -2480,33 +2480,33 @@ impl ISizeAndMarginsComputer for BlockRe
     ///
     /// ISize has already been calculated. We now calculate the margins just
     /// like for non-replaced blocks.
     fn solve_inline_size_constraints(&self,
                                      block: &mut BlockFlow,
                                      input: &ISizeConstraintInput)
                                      -> ISizeConstraintSolution {
         match input.computed_inline_size {
-            Specified(_) => {},
-            Auto => panic!("BlockReplaced: inline_size should have been computed by now")
+            MaybeAuto::Specified(_) => {},
+            MaybeAuto::Auto => panic!("BlockReplaced: inline_size should have been computed by now")
         };
         self.solve_block_inline_size_constraints(block, input)
     }
 
     /// 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)
                                     -> MaybeAuto {
         let fragment = block.fragment();
         fragment.assign_replaced_inline_size_if_necessary(parent_flow_inline_size);
         // For replaced block flow, the rest of the constraint solving will
         // take inline-size to be specified as the value computed here.
-        Specified(fragment.content_inline_size())
+        MaybeAuto::Specified(fragment.content_inline_size())
     }
 
 }
 
 impl ISizeAndMarginsComputer for FloatNonReplaced {
     /// CSS Section 10.3.5
     ///
     /// If inline-size is computed as 'auto', the used value is the 'shrink-to-fit' inline-size.
@@ -2535,34 +2535,34 @@ impl ISizeAndMarginsComputer for FloatRe
     fn solve_inline_size_constraints(&self, _: &mut BlockFlow, input: &ISizeConstraintInput)
                                -> ISizeConstraintSolution {
         let (computed_inline_size, inline_start_margin, inline_end_margin) = (input.computed_inline_size,
                                                            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 {
-            Specified(w) => w,
-            Auto => panic!("FloatReplaced: inline_size should have been computed by now")
+            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);
         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)
                                     -> MaybeAuto {
         let fragment = block.fragment();
         fragment.assign_replaced_inline_size_if_necessary(parent_flow_inline_size);
         // For replaced block flow, the rest of the constraint solving will
         // take inline-size to be specified as the value computed here.
-        Specified(fragment.content_inline_size())
+        MaybeAuto::Specified(fragment.content_inline_size())
     }
 }
 
 fn propagate_column_inline_sizes_to_child(
         kid: &mut Flow,
         child_index: uint,
         content_inline_size: Au,
         column_computed_inline_sizes: &[ColumnComputedInlineSize],
--- a/servo/components/layout/construct.rs
+++ b/servo/components/layout/construct.rs
@@ -17,104 +17,96 @@ use css::node_style::StyledNode;
 use block::BlockFlow;
 use context::LayoutContext;
 use floats::FloatKind;
 use flow::{Flow, ImmutableFlowUtils, MutableOwnedFlowUtils};
 use flow::{Descendants, AbsDescendants};
 use flow::{IS_ABSOLUTELY_POSITIONED};
 use flow;
 use flow_ref::FlowRef;
-use fragment::{Fragment, GenericFragment, IframeFragment, IframeFragmentInfo, ImageFragment};
-use fragment::{ImageFragmentInfo, InlineAbsoluteHypotheticalFragment};
-use fragment::{InlineAbsoluteHypotheticalFragmentInfo, InlineBlockFragment};
-use fragment::{InlineBlockFragmentInfo, SpecificFragmentInfo, TableCellFragment};
-use fragment::{TableColumnFragment, TableColumnFragmentInfo, TableFragment, TableRowFragment};
-use fragment::{TableWrapperFragment, UnscannedTextFragment, UnscannedTextFragmentInfo};
+use fragment::{Fragment, IframeFragmentInfo};
+use fragment::ImageFragmentInfo;
+use fragment::InlineAbsoluteHypotheticalFragmentInfo;
+use fragment::{InlineBlockFragmentInfo, SpecificFragmentInfo};
+use fragment::TableColumnFragmentInfo;
+use fragment::UnscannedTextFragmentInfo;
 use incremental::{RECONSTRUCT_FLOW, RestyleDamage};
 use inline::InlineFlow;
 use list_item::{mod, ListItemFlow};
 use parallel;
 use table_wrapper::TableWrapperFlow;
 use table::TableFlow;
 use table_caption::TableCaptionFlow;
 use table_colgroup::TableColGroupFlow;
 use table_rowgroup::TableRowGroupFlow;
 use table_row::TableRowFlow;
 use table_cell::TableCellFlow;
 use text::TextRunScanner;
 use util::{HAS_NEWLY_CONSTRUCTED_FLOW, LayoutDataAccess, OpaqueNodeMethods, LayoutDataWrapper};
-use wrapper::{PostorderNodeMutTraversal, TLayoutNode, ThreadSafeLayoutNode};
-use wrapper::{Before, After, Normal};
+use wrapper::{PostorderNodeMutTraversal, PseudoElementType, TLayoutNode, ThreadSafeLayoutNode};
 
 use gfx::display_list::OpaqueNode;
-use script::dom::element::{HTMLIFrameElementTypeId, HTMLImageElementTypeId};
-use script::dom::element::{HTMLObjectElementTypeId, HTMLInputElementTypeId};
-use script::dom::element::{HTMLTableColElementTypeId, HTMLTableDataCellElementTypeId};
-use script::dom::element::{HTMLTableElementTypeId, HTMLTableHeaderCellElementTypeId};
-use script::dom::element::{HTMLTableRowElementTypeId, HTMLTableSectionElementTypeId};
-use script::dom::element::HTMLTextAreaElementTypeId;
-use script::dom::node::{CommentNodeTypeId, DoctypeNodeTypeId, DocumentFragmentNodeTypeId};
-use script::dom::node::{DocumentNodeTypeId, ElementNodeTypeId, ProcessingInstructionNodeTypeId};
-use script::dom::node::{TextNodeTypeId};
+use script::dom::element::ElementTypeId;
+use script::dom::node::NodeTypeId;
 use script::dom::htmlobjectelement::is_image_data;
 use servo_util::opts;
 use std::collections::DList;
 use std::mem;
 use std::sync::atomic::Relaxed;
 use style::ComputedValues;
 use style::computed_values::{display, position, float, list_style_position};
 use sync::Arc;
 use url::Url;
 
 /// The results of flow construction for a DOM node.
 #[deriving(Clone)]
 pub enum ConstructionResult {
     /// This node contributes nothing at all (`display: none`). Alternately, this is what newly
     /// created nodes have their `ConstructionResult` set to.
-    NoConstructionResult,
+    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.
-    FlowConstructionResult(FlowRef, AbsDescendants),
+    Flow(FlowRef, AbsDescendants),
 
     /// This node contributed some object or objects that will be needed to construct a proper flow
     /// later up the tree, but these objects have not yet found their home.
-    ConstructionItemConstructionResult(ConstructionItem),
+    ConstructionItem(ConstructionItem),
 }
 
 impl ConstructionResult {
     pub fn swap_out(&mut self) -> ConstructionResult {
         if opts::get().nonincremental_layout {
-            return mem::replace(self, NoConstructionResult)
+            return mem::replace(self, ConstructionResult::None)
         }
 
         (*self).clone()
     }
 
     pub fn debug_id(&self) -> uint {
         match self {
-            &NoConstructionResult => 0u,
-            &ConstructionItemConstructionResult(_) => 0u,
-            &FlowConstructionResult(ref flow_ref, _) => flow::base(flow_ref.deref()).debug_id(),
+            &ConstructionResult::None => 0u,
+            &ConstructionResult::ConstructionItem(_) => 0u,
+            &ConstructionResult::Flow(ref flow_ref, _) => flow::base(flow_ref.deref()).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)]
 pub enum ConstructionItem {
     /// Inline fragments and associated {ib} splits that have not yet found flows.
-    InlineFragmentsConstructionItem(InlineFragmentsConstructionResult),
+    InlineFragments(InlineFragmentsConstructionResult),
     /// Potentially ignorable whitespace.
-    WhitespaceConstructionItem(OpaqueNode, Arc<ComputedValues>, RestyleDamage),
+    Whitespace(OpaqueNode, Arc<ComputedValues>, RestyleDamage),
     /// TableColumn Fragment
-    TableColumnFragmentConstructionItem(Fragment),
+    TableColumnFragment(Fragment),
 }
 
 /// Represents inline fragments and {ib} splits that are bubbling up from an inline.
 #[deriving(Clone)]
 pub struct InlineFragmentsConstructionResult {
     /// Any {ib} splits that we're bubbling up.
     pub splits: DList<InlineBlockSplit>,
 
@@ -134,17 +126,17 @@ pub struct InlineFragmentsConstructionRe
 ///     <div>B</div>
 ///     C
 ///     </span>
 /// ```
 ///
 /// The resulting `ConstructionItem` for the outer `span` will be:
 ///
 /// ```ignore
-///     InlineFragmentsConstructionItem(Some(~[
+///     ConstructionItem::InlineFragments(Some(~[
 ///         InlineBlockSplit {
 ///             predecessor_fragments: ~[
 ///                 A
 ///             ],
 ///             block: ~BlockFlow {
 ///                 B
 ///             },
 ///         }),~[
@@ -208,19 +200,19 @@ impl InlineFragmentsAccumulator {
             }
             None => {}
         }
         fragments
     }
 }
 
 enum WhitespaceStrippingMode {
-    NoWhitespaceStripping,
-    StripWhitespaceFromStart,
-    StripWhitespaceFromEnd,
+    None,
+    FromStart,
+    FromEnd,
 }
 
 /// An object that knows how to create flows.
 pub struct FlowConstructor<'a> {
     /// The layout context.
     pub layout_context: &'a LayoutContext<'a>,
 }
 
@@ -232,21 +224,21 @@ impl<'a> FlowConstructor<'a> {
             layout_context: layout_context,
         }
     }
 
     /// Builds the `ImageFragmentInfo` for the given image. This is out of line to guide inlining.
     fn build_fragment_info_for_image(&mut self, node: &ThreadSafeLayoutNode, url: Option<Url>)
                                 -> SpecificFragmentInfo {
         match url {
-            None => GenericFragment,
+            None => SpecificFragmentInfo::Generic,
             Some(url) => {
                 // FIXME(pcwalton): The fact that image fragments store the cache within them makes
                 // little sense to me.
-                ImageFragment(box ImageFragmentInfo::new(node,
+                SpecificFragmentInfo::Image(box ImageFragmentInfo::new(node,
                                                          url,
                                                          self.layout_context
                                                              .shared
                                                              .image_cache
                                                              .clone()))
             }
         }
     }
@@ -255,38 +247,38 @@ impl<'a> FlowConstructor<'a> {
     ///
     /// This does *not* construct the text for generated content (but, for generated content with
     /// `display: block`, it does construct the generic fragment corresponding to the block).
     /// Construction of the text fragment is done specially by `build_flow_using_children()` and
     /// `build_fragments_for_replaced_inline_content()`.
     pub fn build_specific_fragment_info_for_node(&mut self, node: &ThreadSafeLayoutNode)
                                                  -> SpecificFragmentInfo {
         match node.type_id() {
-            Some(ElementNodeTypeId(HTMLIFrameElementTypeId)) => {
-                IframeFragment(box IframeFragmentInfo::new(node))
+            Some(NodeTypeId::Element(ElementTypeId::HTMLIFrameElement)) => {
+                SpecificFragmentInfo::Iframe(box IframeFragmentInfo::new(node))
             }
-            Some(ElementNodeTypeId(HTMLImageElementTypeId)) => {
+            Some(NodeTypeId::Element(ElementTypeId::HTMLImageElement)) => {
                 self.build_fragment_info_for_image(node, node.image_url())
             }
-            Some(ElementNodeTypeId(HTMLObjectElementTypeId)) => {
+            Some(NodeTypeId::Element(ElementTypeId::HTMLObjectElement)) => {
                 let data = node.get_object_data();
                 self.build_fragment_info_for_image(node, data)
             }
-            Some(ElementNodeTypeId(HTMLTableElementTypeId)) => TableWrapperFragment,
-            Some(ElementNodeTypeId(HTMLTableColElementTypeId)) => {
-                TableColumnFragment(TableColumnFragmentInfo::new(node))
+            Some(NodeTypeId::Element(ElementTypeId::HTMLTableElement)) => SpecificFragmentInfo::TableWrapper,
+            Some(NodeTypeId::Element(ElementTypeId::HTMLTableColElement)) => {
+                SpecificFragmentInfo::TableColumn(TableColumnFragmentInfo::new(node))
             }
-            Some(ElementNodeTypeId(HTMLTableDataCellElementTypeId)) |
-            Some(ElementNodeTypeId(HTMLTableHeaderCellElementTypeId)) => TableCellFragment,
-            Some(ElementNodeTypeId(HTMLTableRowElementTypeId)) |
-            Some(ElementNodeTypeId(HTMLTableSectionElementTypeId)) => TableRowFragment,
-            Some(TextNodeTypeId) => UnscannedTextFragment(UnscannedTextFragmentInfo::new(node)),
+            Some(NodeTypeId::Element(ElementTypeId::HTMLTableDataCellElement)) |
+            Some(NodeTypeId::Element(ElementTypeId::HTMLTableHeaderCellElement)) => SpecificFragmentInfo::TableCell,
+            Some(NodeTypeId::Element(ElementTypeId::HTMLTableRowElement)) |
+            Some(NodeTypeId::Element(ElementTypeId::HTMLTableSectionElement)) => SpecificFragmentInfo::TableRow,
+            Some(NodeTypeId::Text) => SpecificFragmentInfo::UnscannedText(UnscannedTextFragmentInfo::new(node)),
             _ => {
                 // This includes pseudo-elements.
-                GenericFragment
+                SpecificFragmentInfo::Generic
             }
         }
     }
 
     /// Creates an inline flow from a set of inline fragments, then adds it as a child of the given
     /// flow or pushes it onto the given flow list.
     ///
     /// `#[inline(always)]` because this is performance critical and LLVM will not inline it
@@ -299,37 +291,37 @@ impl<'a> FlowConstructor<'a> {
                                               whitespace_stripping: WhitespaceStrippingMode,
                                               node: &ThreadSafeLayoutNode) {
         let mut fragments = fragment_accumulator.to_dlist();
         if fragments.is_empty() {
             return
         };
 
         match whitespace_stripping {
-            NoWhitespaceStripping => {}
-            StripWhitespaceFromStart => {
+            WhitespaceStrippingMode::None => {}
+            WhitespaceStrippingMode::FromStart => {
                 strip_ignorable_whitespace_from_start(&mut fragments);
                 if fragments.is_empty() {
                     return
                 };
             }
-            StripWhitespaceFromEnd => {
+            WhitespaceStrippingMode::FromEnd => {
                 strip_ignorable_whitespace_from_end(&mut fragments);
                 if fragments.is_empty() {
                     return
                 };
             }
         }
 
         // Build a list of all the inline-block fragments before fragments is moved.
         let mut inline_block_flows = vec!();
         for f in fragments.iter() {
             match f.specific {
-                InlineBlockFragment(ref info) => inline_block_flows.push(info.flow_ref.clone()),
-                InlineAbsoluteHypotheticalFragment(ref info) => {
+                SpecificFragmentInfo::InlineBlock(ref info) => inline_block_flows.push(info.flow_ref.clone()),
+                SpecificFragmentInfo::InlineAbsoluteHypothetical(ref info) => {
                     inline_block_flows.push(info.flow_ref.clone())
                 }
                 _ => {}
             }
         }
 
         // We must scan for runs before computing minimum ascent and descent because scanning
         // for runs might collapse so much whitespace away that only hypothetical fragments
@@ -369,46 +361,46 @@ impl<'a> FlowConstructor<'a> {
                                                            consecutive_siblings: &mut Vec<FlowRef>,
                                                            node: &ThreadSafeLayoutNode,
                                                            kid: ThreadSafeLayoutNode,
                                                            inline_fragment_accumulator:
                                                            &mut InlineFragmentsAccumulator,
                                                            abs_descendants: &mut Descendants,
                                                            first_fragment: &mut bool) {
         match kid.swap_out_construction_result() {
-            NoConstructionResult => {}
-            FlowConstructionResult(kid_flow, kid_abs_descendants) => {
+            ConstructionResult::None => {}
+            ConstructionResult::Flow(kid_flow, kid_abs_descendants) => {
                 // If kid_flow is TableCaptionFlow, kid_flow should be added under
                 // TableWrapperFlow.
                 if flow.is_table() && kid_flow.deref().is_table_caption() {
-                    kid.set_flow_construction_result(FlowConstructionResult(kid_flow,
+                    kid.set_flow_construction_result(ConstructionResult::Flow(kid_flow,
                                                                             Descendants::new()))
                 } else if flow.need_anonymous_flow(&*kid_flow) {
                     consecutive_siblings.push(kid_flow)
                 } else {
                     // Flush any inline fragments that we were gathering up. This allows us to
                     // handle {ib} splits.
                     debug!("flushing {} inline box(es) to flow A",
                            inline_fragment_accumulator.fragments.len());
                     self.flush_inline_fragments_to_flow_or_list(
                         mem::replace(inline_fragment_accumulator,
                                      InlineFragmentsAccumulator::new()),
                         flow,
                         consecutive_siblings,
-                        StripWhitespaceFromStart,
+                        WhitespaceStrippingMode::FromStart,
                         node);
                     if !consecutive_siblings.is_empty() {
                         let consecutive_siblings = mem::replace(consecutive_siblings, vec!());
                         self.generate_anonymous_missing_child(consecutive_siblings, flow, node);
                     }
                     flow.add_new_child(kid_flow);
                 }
                 abs_descendants.push_descendants(kid_abs_descendants);
             }
-            ConstructionItemConstructionResult(InlineFragmentsConstructionItem(
+            ConstructionResult::ConstructionItem(ConstructionItem::InlineFragments(
                     InlineFragmentsConstructionResult {
                         splits,
                         fragments: successor_fragments,
                         abs_descendants: kid_abs_descendants,
                     })) => {
                 // Add any {ib} splits.
                 for split in splits.into_iter() {
                     // Pull apart the {ib} split object and push its predecessor fragments
@@ -418,19 +410,19 @@ impl<'a> FlowConstructor<'a> {
                         flow: kid_flow
                     } = split;
                     inline_fragment_accumulator.push_all(predecessors);
 
                     // If this is the first fragment in flow, then strip ignorable
                     // whitespace per CSS 2.1 § 9.2.1.1.
                     let whitespace_stripping = if *first_fragment {
                         *first_fragment = false;
-                        StripWhitespaceFromStart
+                        WhitespaceStrippingMode::FromStart
                     } else {
-                        NoWhitespaceStripping
+                        WhitespaceStrippingMode::None
                     };
 
                     // Flush any inline fragments that we were gathering up.
                     debug!("flushing {} inline box(es) to flow A",
                            inline_fragment_accumulator.fragments.len());
                     self.flush_inline_fragments_to_flow_or_list(
                             mem::replace(inline_fragment_accumulator,
                                          InlineFragmentsAccumulator::new()),
@@ -447,30 +439,30 @@ impl<'a> FlowConstructor<'a> {
                         flow.add_new_child(kid_flow)
                     }
                 }
 
                 // Add the fragments to the list we're maintaining.
                 inline_fragment_accumulator.push_all(successor_fragments);
                 abs_descendants.push_descendants(kid_abs_descendants);
             }
-            ConstructionItemConstructionResult(WhitespaceConstructionItem(whitespace_node,
+            ConstructionResult::ConstructionItem(ConstructionItem::Whitespace(whitespace_node,
                                                                           whitespace_style,
                                                                           whitespace_damage)) => {
                 // Add whitespace results. They will be stripped out later on when
                 // between block elements, and retained when between inline elements.
                 let fragment_info =
-                    UnscannedTextFragment(UnscannedTextFragmentInfo::from_text(" ".to_string()));
+                    SpecificFragmentInfo::UnscannedText(UnscannedTextFragmentInfo::from_text(" ".to_string()));
                 let fragment = Fragment::from_opaque_node_and_style(whitespace_node,
                                                                     whitespace_style,
                                                                     whitespace_damage,
                                                                     fragment_info);
                 inline_fragment_accumulator.fragments.push_back(fragment);
             }
-            ConstructionItemConstructionResult(TableColumnFragmentConstructionItem(_)) => {
+            ConstructionResult::ConstructionItem(ConstructionItem::TableColumnFragment(_)) => {
                 // TODO: Implement anonymous table objects for missing parents
                 // CSS 2.1 § 17.2.1, step 3-2
             }
         }
     }
 
     /// Constructs a block flow, beginning with the given `initial_fragment` if present and then
     /// appending the construction results of children to the child list of the block flow. {ib}
@@ -490,17 +482,17 @@ impl<'a> FlowConstructor<'a> {
                 inline_fragment_accumulator.fragments.push_back(initial_fragment);
                 false
             }
         };
 
         // List of absolute descendants, in tree order.
         let mut abs_descendants = Descendants::new();
         for kid in node.children() {
-            if kid.get_pseudo_element_type() != Normal {
+            if kid.get_pseudo_element_type() != PseudoElementType::Normal {
                 self.process(&kid);
             }
 
             self.build_block_flow_using_construction_result_of_child(
                 &mut flow,
                 &mut consecutive_siblings,
                 node,
                 kid,
@@ -509,17 +501,17 @@ impl<'a> FlowConstructor<'a> {
                 &mut first_fragment);
         }
 
         // Perform a final flush of any inline fragments that we were gathering up to handle {ib}
         // splits, after stripping ignorable whitespace.
         self.flush_inline_fragments_to_flow_or_list(inline_fragment_accumulator,
                                                     &mut flow,
                                                     &mut consecutive_siblings,
-                                                    StripWhitespaceFromEnd,
+                                                    WhitespaceStrippingMode::FromEnd,
                                                     node);
         if !consecutive_siblings.is_empty() {
             self.generate_anonymous_missing_child(consecutive_siblings, &mut flow, node);
         }
 
         // The flow is done.
         flow.finish();
 
@@ -532,45 +524,45 @@ impl<'a> FlowConstructor<'a> {
 
             abs_descendants = Descendants::new();
             if is_absolutely_positioned {
                 // This is now the only absolute flow in the subtree which hasn't yet
                 // reached its CB.
                 abs_descendants.push(flow.clone());
             }
         }
-        FlowConstructionResult(flow, abs_descendants)
+        ConstructionResult::Flow(flow, abs_descendants)
     }
 
     /// Constructs a flow for the given block node and its children. This method creates an
     /// initial fragment as appropriate and then dispatches to
     /// `build_flow_for_block_starting_with_fragment`. Currently the following kinds of flows get
     /// initial content:
     ///
     /// * Generated content gets the initial content specified by the `content` attribute of the
     ///   CSS.
     /// * `<input>` and `<textarea>` elements get their content.
     ///
     /// FIXME(pcwalton): It is not clear to me that there isn't a cleaner way to handle
     /// `<textarea>`.
     fn build_flow_for_block(&mut self, flow: FlowRef, node: &ThreadSafeLayoutNode)
                             -> ConstructionResult {
-        let initial_fragment = if node.get_pseudo_element_type() != Normal ||
-           node.type_id() == Some(ElementNodeTypeId(HTMLInputElementTypeId)) ||
-           node.type_id() == Some(ElementNodeTypeId(HTMLTextAreaElementTypeId)) {
+        let initial_fragment = if node.get_pseudo_element_type() != PseudoElementType::Normal ||
+           node.type_id() == Some(NodeTypeId::Element(ElementTypeId::HTMLInputElement)) ||
+           node.type_id() == Some(NodeTypeId::Element(ElementTypeId::HTMLTextAreaElement)) {
             // A TextArea's text contents are displayed through the input text
             // box, so don't construct them.
-            if node.type_id() == Some(ElementNodeTypeId(HTMLTextAreaElementTypeId)) {
+            if node.type_id() == Some(NodeTypeId::Element(ElementTypeId::HTMLTextAreaElement)) {
                 for kid in node.children() {
-                    kid.set_flow_construction_result(NoConstructionResult)
+                    kid.set_flow_construction_result(ConstructionResult::None)
                 }
             }
             Some(Fragment::new_from_specific_info(
                     node,
-                    UnscannedTextFragment(UnscannedTextFragmentInfo::new(node))))
+                    SpecificFragmentInfo::UnscannedText(UnscannedTextFragmentInfo::new(node))))
         } else {
             None
         };
 
         self.build_flow_for_block_starting_with_fragment(flow, node, initial_fragment)
     }
 
     /// Builds a flow for a node with `display: block`. This yields a `BlockFlow` with possibly
@@ -597,35 +589,35 @@ impl<'a> FlowConstructor<'a> {
     fn build_fragments_for_nonreplaced_inline_content(&mut self, node: &ThreadSafeLayoutNode)
                                                   -> ConstructionResult {
         let mut opt_inline_block_splits: DList<InlineBlockSplit> = DList::new();
         let mut fragment_accumulator = InlineFragmentsAccumulator::from_inline_node(node);
         let mut abs_descendants = Descendants::new();
 
         // Concatenate all the fragments of our kids, creating {ib} splits as necessary.
         for kid in node.children() {
-            if kid.get_pseudo_element_type() != Normal {
+            if kid.get_pseudo_element_type() != PseudoElementType::Normal {
                 self.process(&kid);
             }
             match kid.swap_out_construction_result() {
-                NoConstructionResult => {}
-                FlowConstructionResult(flow, kid_abs_descendants) => {
+                ConstructionResult::None => {}
+                ConstructionResult::Flow(flow, kid_abs_descendants) => {
                     // {ib} split. Flush the accumulator to our new split and make a new
                     // accumulator to hold any subsequent fragments we come across.
                     let split = InlineBlockSplit {
                         predecessors:
                             mem::replace(
                                 &mut fragment_accumulator,
                                 InlineFragmentsAccumulator::from_inline_node(node)).to_dlist(),
                         flow: flow,
                     };
                     opt_inline_block_splits.push_back(split);
                     abs_descendants.push_descendants(kid_abs_descendants);
                 }
-                ConstructionItemConstructionResult(InlineFragmentsConstructionItem(
+                ConstructionResult::ConstructionItem(ConstructionItem::InlineFragments(
                         InlineFragmentsConstructionResult {
                             splits,
                             fragments: successors,
                             abs_descendants: kid_abs_descendants,
                         })) => {
 
                     // Bubble up {ib} splits.
                     for split in splits.into_iter() {
@@ -644,137 +636,137 @@ impl<'a> FlowConstructor<'a> {
                         };
                         opt_inline_block_splits.push_back(split)
                     }
 
                     // Push residual fragments.
                     fragment_accumulator.push_all(successors);
                     abs_descendants.push_descendants(kid_abs_descendants);
                 }
-                ConstructionItemConstructionResult(WhitespaceConstructionItem(
+                ConstructionResult::ConstructionItem(ConstructionItem::Whitespace(
                         whitespace_node,
                         whitespace_style,
                         whitespace_damage)) => {
                     // Instantiate the whitespace fragment.
-                    let fragment_info = UnscannedTextFragment(UnscannedTextFragmentInfo::from_text(
+                    let fragment_info = SpecificFragmentInfo::UnscannedText(UnscannedTextFragmentInfo::from_text(
                             " ".to_string()));
                     let fragment = Fragment::from_opaque_node_and_style(whitespace_node,
                                                                         whitespace_style,
                                                                         whitespace_damage,
                                                                         fragment_info);
                     fragment_accumulator.fragments.push_back(fragment)
                 }
-                ConstructionItemConstructionResult(TableColumnFragmentConstructionItem(_)) => {
+                ConstructionResult::ConstructionItem(ConstructionItem::TableColumnFragment(_)) => {
                     // TODO: Implement anonymous table objects for missing parents
                     // CSS 2.1 § 17.2.1, step 3-2
                 }
             }
         }
 
         // Finally, make a new construction result.
         if opt_inline_block_splits.len() > 0 || fragment_accumulator.fragments.len() > 0
                 || abs_descendants.len() > 0 {
-            let construction_item = InlineFragmentsConstructionItem(
+            let construction_item = ConstructionItem::InlineFragments(
                     InlineFragmentsConstructionResult {
                 splits: opt_inline_block_splits,
                 fragments: fragment_accumulator.to_dlist(),
                 abs_descendants: abs_descendants,
             });
-            ConstructionItemConstructionResult(construction_item)
+            ConstructionResult::ConstructionItem(construction_item)
         } else {
-            NoConstructionResult
+            ConstructionResult::None
         }
     }
 
     /// Creates an `InlineFragmentsConstructionResult` for replaced content. Replaced content
     /// doesn't render its children, so this just nukes a child's fragments and creates a
     /// `Fragment`.
     fn build_fragments_for_replaced_inline_content(&mut self, node: &ThreadSafeLayoutNode)
                                                -> ConstructionResult {
         for kid in node.children() {
-            kid.set_flow_construction_result(NoConstructionResult)
+            kid.set_flow_construction_result(ConstructionResult::None)
         }
 
         // If this node is ignorable whitespace, bail out now.
         //
         // FIXME(#2001, pcwalton): Don't do this if there's padding or borders.
         if node.is_ignorable_whitespace() {
             let opaque_node = OpaqueNodeMethods::from_thread_safe_layout_node(node);
-            return ConstructionItemConstructionResult(WhitespaceConstructionItem(
+            return ConstructionResult::ConstructionItem(ConstructionItem::Whitespace(
                 opaque_node,
                 node.style().clone(),
                 node.restyle_damage()))
         }
 
         // If this is generated content, then we need to initialize the accumulator with the
         // fragment corresponding to that content. Otherwise, just initialize with the ordinary
         // fragment that needs to be generated for this inline node.
-        let fragment = if node.get_pseudo_element_type() != Normal {
-            let fragment_info = UnscannedTextFragment(UnscannedTextFragmentInfo::new(node));
+        let fragment = if node.get_pseudo_element_type() != PseudoElementType::Normal {
+            let fragment_info = SpecificFragmentInfo::UnscannedText(UnscannedTextFragmentInfo::new(node));
             Fragment::new_from_specific_info(node, fragment_info)
         } else {
             Fragment::new(self, node)
         };
 
         let mut fragments = DList::new();
         fragments.push_back(fragment);
 
-        let construction_item = InlineFragmentsConstructionItem(InlineFragmentsConstructionResult {
+        let construction_item = ConstructionItem::InlineFragments(InlineFragmentsConstructionResult {
             splits: DList::new(),
             fragments: fragments,
             abs_descendants: Descendants::new(),
         });
-        ConstructionItemConstructionResult(construction_item)
+        ConstructionResult::ConstructionItem(construction_item)
     }
 
     fn build_fragment_for_inline_block(&mut self, node: &ThreadSafeLayoutNode)
                                        -> ConstructionResult {
         let block_flow_result = self.build_flow_for_nonfloated_block(node);
         let (block_flow, abs_descendants) = match block_flow_result {
-            FlowConstructionResult(block_flow, abs_descendants) => (block_flow, abs_descendants),
+            ConstructionResult::Flow(block_flow, abs_descendants) => (block_flow, abs_descendants),
             _ => unreachable!()
         };
 
-        let fragment_info = InlineBlockFragment(InlineBlockFragmentInfo::new(block_flow));
+        let fragment_info = SpecificFragmentInfo::InlineBlock(InlineBlockFragmentInfo::new(block_flow));
         let fragment = Fragment::new_from_specific_info(node, fragment_info);
 
         let mut fragment_accumulator = InlineFragmentsAccumulator::from_inline_node(node);
         fragment_accumulator.fragments.push_back(fragment);
 
-        let construction_item = InlineFragmentsConstructionItem(InlineFragmentsConstructionResult {
+        let construction_item = ConstructionItem::InlineFragments(InlineFragmentsConstructionResult {
             splits: DList::new(),
             fragments: fragment_accumulator.to_dlist(),
             abs_descendants: abs_descendants,
         });
-        ConstructionItemConstructionResult(construction_item)
+        ConstructionResult::ConstructionItem(construction_item)
     }
 
     /// This is an annoying case, because the computed `display` value is `block`, but the
     /// hypothetical box is inline.
     fn build_fragment_for_absolutely_positioned_inline(&mut self, node: &ThreadSafeLayoutNode)
                                                        -> ConstructionResult {
         let block_flow_result = self.build_flow_for_nonfloated_block(node);
         let (block_flow, abs_descendants) = match block_flow_result {
-            FlowConstructionResult(block_flow, abs_descendants) => (block_flow, abs_descendants),
+            ConstructionResult::Flow(block_flow, abs_descendants) => (block_flow, abs_descendants),
             _ => unreachable!()
         };
 
-        let fragment_info = InlineAbsoluteHypotheticalFragment(
+        let fragment_info = SpecificFragmentInfo::InlineAbsoluteHypothetical(
             InlineAbsoluteHypotheticalFragmentInfo::new(block_flow));
         let fragment = Fragment::new_from_specific_info(node, fragment_info);
 
         let mut fragment_accumulator = InlineFragmentsAccumulator::from_inline_node(node);
         fragment_accumulator.fragments.push_back(fragment);
 
-        let construction_item = InlineFragmentsConstructionItem(InlineFragmentsConstructionResult {
+        let construction_item = ConstructionItem::InlineFragments(InlineFragmentsConstructionResult {
             splits: DList::new(),
             fragments: fragment_accumulator.to_dlist(),
             abs_descendants: abs_descendants,
         });
-        ConstructionItemConstructionResult(construction_item)
+        ConstructionResult::ConstructionItem(construction_item)
     }
 
     /// Builds one or more fragments for a node with `display: inline`. This yields an
     /// `InlineFragmentsConstructionResult`.
     fn build_fragments_for_inline(&mut self, node: &ThreadSafeLayoutNode) -> ConstructionResult {
         // Is this node replaced content?
         if !node.is_replaced_content() {
             // Go to a path that concatenates our kids' fragments.
@@ -787,18 +779,18 @@ impl<'a> FlowConstructor<'a> {
     }
 
     /// TableCaptionFlow is populated underneath TableWrapperFlow
     fn place_table_caption_under_table_wrapper(&mut self,
                                                table_wrapper_flow: &mut FlowRef,
                                                node: &ThreadSafeLayoutNode) {
         for kid in node.children() {
             match kid.swap_out_construction_result() {
-                NoConstructionResult | ConstructionItemConstructionResult(_) => {}
-                FlowConstructionResult(kid_flow, _) => {
+                ConstructionResult::None | ConstructionResult::ConstructionItem(_) => {}
+                ConstructionResult::Flow(kid_flow, _) => {
                     // Only kid flows with table-caption are matched here.
                     if kid_flow.deref().is_table_caption() {
                         table_wrapper_flow.add_new_child(kid_flow);
                     }
                 }
             }
         }
     }
@@ -831,43 +823,43 @@ impl<'a> FlowConstructor<'a> {
         anonymous_flow.finish();
         flow.add_new_child(anonymous_flow);
     }
 
     /// Builds a flow for a node with `display: table`. This yields a `TableWrapperFlow` with
     /// possibly other `TableCaptionFlow`s or `TableFlow`s underneath it.
     fn build_flow_for_table_wrapper(&mut self, node: &ThreadSafeLayoutNode,
                                     float_value: float::T) -> ConstructionResult {
-        let fragment = Fragment::new_from_specific_info(node, TableWrapperFragment);
+        let fragment = Fragment::new_from_specific_info(node, SpecificFragmentInfo::TableWrapper);
         let wrapper_flow = match float_value {
             float::none => box TableWrapperFlow::from_node_and_fragment(node, fragment),
             _ => {
                 let float_kind = FloatKind::from_property(float_value);
                 box TableWrapperFlow::float_from_node_and_fragment(node, fragment, float_kind)
             }
         };
         let mut wrapper_flow = FlowRef::new(wrapper_flow as Box<Flow>);
 
-        let table_fragment = Fragment::new_from_specific_info(node, TableFragment);
+        let table_fragment = Fragment::new_from_specific_info(node, SpecificFragmentInfo::Table);
         let table_flow = box TableFlow::from_node_and_fragment(node, table_fragment);
         let table_flow = FlowRef::new(table_flow as Box<Flow>);
 
         // We first populate the TableFlow with other flows than TableCaptionFlow.
         // We then populate the TableWrapperFlow with TableCaptionFlow, and attach
         // the TableFlow to the TableWrapperFlow
         let construction_result = self.build_flow_for_block(table_flow, node);
         self.place_table_caption_under_table_wrapper(&mut wrapper_flow, node);
 
         let mut abs_descendants = Descendants::new();
         let mut fixed_descendants = Descendants::new();
 
         // NOTE: The order of captions and table are not the same order as in the DOM tree.
         // All caption blocks are placed before the table flow
         match construction_result {
-            FlowConstructionResult(table_flow, table_abs_descendants) => {
+            ConstructionResult::Flow(table_flow, table_abs_descendants) => {
                 wrapper_flow.add_new_child(table_flow);
                 abs_descendants.push_descendants(table_abs_descendants);
             }
             _ => {}
         }
 
         // The flow is done.
         wrapper_flow.finish();
@@ -885,48 +877,48 @@ impl<'a> FlowConstructor<'a> {
                 fixed_descendants.push(wrapper_flow.clone());
             } else if is_absolutely_positioned {
                 // This is now the only absolute flow in the subtree which hasn't yet
                 // reached its containing block.
                 abs_descendants.push(wrapper_flow.clone());
             }
         }
 
-        FlowConstructionResult(wrapper_flow, abs_descendants)
+        ConstructionResult::Flow(wrapper_flow, abs_descendants)
     }
 
     /// Builds a flow for a node with `display: table-caption`. This yields a `TableCaptionFlow`
     /// with possibly other `BlockFlow`s or `InlineFlow`s underneath it.
     fn build_flow_for_table_caption(&mut self, node: &ThreadSafeLayoutNode) -> ConstructionResult {
         let flow = box TableCaptionFlow::from_node(self, node) as Box<Flow>;
         self.build_flow_for_block(FlowRef::new(flow), node)
     }
 
     /// Builds a flow for a node with `display: table-row-group`. This yields a `TableRowGroupFlow`
     /// with possibly other `TableRowFlow`s underneath it.
     fn build_flow_for_table_rowgroup(&mut self, node: &ThreadSafeLayoutNode)
                                      -> ConstructionResult {
-        let fragment = Fragment::new_from_specific_info(node, TableRowFragment);
+        let fragment = Fragment::new_from_specific_info(node, SpecificFragmentInfo::TableRow);
         let flow = box TableRowGroupFlow::from_node_and_fragment(node, fragment);
         let flow = flow as Box<Flow>;
         self.build_flow_for_block(FlowRef::new(flow), node)
     }
 
     /// Builds a flow for a node with `display: table-row`. This yields a `TableRowFlow` with
     /// possibly other `TableCellFlow`s underneath it.
     fn build_flow_for_table_row(&mut self, node: &ThreadSafeLayoutNode) -> ConstructionResult {
-        let fragment = Fragment::new_from_specific_info(node, TableRowFragment);
+        let fragment = Fragment::new_from_specific_info(node, SpecificFragmentInfo::TableRow);
         let flow = box TableRowFlow::from_node_and_fragment(node, fragment) as Box<Flow>;
         self.build_flow_for_block(FlowRef::new(flow), node)
     }
 
     /// Builds a flow for a node with `display: table-cell`. This yields a `TableCellFlow` with
     /// possibly other `BlockFlow`s or `InlineFlow`s underneath it.
     fn build_flow_for_table_cell(&mut self, node: &ThreadSafeLayoutNode) -> ConstructionResult {
-        let fragment = Fragment::new_from_specific_info(node, TableCellFragment);
+        let fragment = Fragment::new_from_specific_info(node, SpecificFragmentInfo::TableCell);
         let flow = box TableCellFlow::from_node_and_fragment(node, fragment) as Box<Flow>;
         self.build_flow_for_block(FlowRef::new(flow), node)
     }
 
     /// Builds a flow for a node with `display: list-item`. This yields a `ListItemFlow` with
     /// possibly other `BlockFlow`s or `InlineFlow`s underneath it.
     fn build_flow_for_list_item(&mut self, node: &ThreadSafeLayoutNode) -> ConstructionResult {
         let marker_fragment = match node.style().get_list().list_style_image {
@@ -940,17 +932,17 @@ impl<'a> FlowConstructor<'a> {
                                                                      .get_list()
                                                                      .list_style_type) {
                     None => None,
                     Some(text) => {
                         let text = text.to_string();
                         let mut unscanned_marker_fragments = DList::new();
                         unscanned_marker_fragments.push_back(Fragment::new_from_specific_info(
                             node,
-                            UnscannedTextFragment(UnscannedTextFragmentInfo::from_text(text))));
+                            SpecificFragmentInfo::UnscannedText(UnscannedTextFragmentInfo::from_text(text))));
                         let marker_fragments = TextRunScanner::new().scan_for_runs(
                             self.layout_context.font_context(),
                             unscanned_marker_fragments);
                         debug_assert!(marker_fragments.len() == 1);
                         marker_fragments.fragments.into_iter().next()
                     }
                 }
             }
@@ -979,55 +971,55 @@ impl<'a> FlowConstructor<'a> {
                                                          initial_fragment)
     }
 
     /// Creates a fragment for a node with `display: table-column`.
     fn build_fragments_for_table_column(&mut self, node: &ThreadSafeLayoutNode)
                                         -> ConstructionResult {
         // CSS 2.1 § 17.2.1. Treat all child fragments of a `table-column` as `display: none`.
         for kid in node.children() {
-            kid.set_flow_construction_result(NoConstructionResult)
+            kid.set_flow_construction_result(ConstructionResult::None)
         }
 
-        let specific = TableColumnFragment(TableColumnFragmentInfo::new(node));
-        let construction_item = TableColumnFragmentConstructionItem(
+        let specific = SpecificFragmentInfo::TableColumn(TableColumnFragmentInfo::new(node));
+        let construction_item = ConstructionItem::TableColumnFragment(
             Fragment::new_from_specific_info(node, specific)
         );
-        ConstructionItemConstructionResult(construction_item)
+        ConstructionResult::ConstructionItem(construction_item)
     }
 
     /// Builds a flow for a node with `display: table-column-group`.
     /// This yields a `TableColGroupFlow`.
     fn build_flow_for_table_colgroup(&mut self, node: &ThreadSafeLayoutNode)
                                      -> ConstructionResult {
         let fragment = Fragment::new_from_specific_info(
             node,
-            TableColumnFragment(TableColumnFragmentInfo::new(node)));
+            SpecificFragmentInfo::TableColumn(TableColumnFragmentInfo::new(node)));
         let mut col_fragments = vec!();
         for kid in node.children() {
             // CSS 2.1 § 17.2.1. Treat all non-column child fragments of `table-column-group`
             // as `display: none`.
             match kid.swap_out_construction_result() {
-                ConstructionItemConstructionResult(TableColumnFragmentConstructionItem(
+                ConstructionResult::ConstructionItem(ConstructionItem::TableColumnFragment(
                         fragment)) => {
                     col_fragments.push(fragment);
                 }
                 _ => {}
             }
         }
         if col_fragments.is_empty() {
-            debug!("add TableColumnFragment for empty colgroup");
-            let specific = TableColumnFragment(TableColumnFragmentInfo::new(node));
+            debug!("add SpecificFragmentInfo::TableColumn for empty colgroup");
+            let specific = SpecificFragmentInfo::TableColumn(TableColumnFragmentInfo::new(node));
             col_fragments.push(Fragment::new_from_specific_info(node, specific));
         }
         let flow = box TableColGroupFlow::from_node_and_fragments(node, fragment, col_fragments);
         let mut flow = FlowRef::new(flow as Box<Flow>);
         flow.finish();
 
-        FlowConstructionResult(flow, Descendants::new())
+        ConstructionResult::Flow(flow, Descendants::new())
     }
 
     /// Attempts to perform incremental repair to account for recent changes to this node. This
     /// can fail and return false, indicating that flows will need to be reconstructed.
     ///
     /// TODO(pcwalton): Add some more fast paths, like toggling `display: none`, adding block kids
     /// to block parents with no {ib} splits, adding out-of-flow kids, etc.
     pub fn repair_if_possible(&mut self, node: &ThreadSafeLayoutNode) -> bool {
@@ -1044,25 +1036,25 @@ impl<'a> FlowConstructor<'a> {
                 need_to_reconstruct = true
             }
         }
         if need_to_reconstruct {
             return false
         }
 
         match node.swap_out_construction_result() {
-            NoConstructionResult => true,
-            FlowConstructionResult(mut flow, _) => {
+            ConstructionResult::None => true,
+            ConstructionResult::Flow(mut flow, _) => {
                 // The node's flow is of the same type and has the same set of children and can
                 // therefore be repaired by simply propagating damage and style to the flow.
                 flow::mut_base(&mut *flow).restyle_damage.insert(node.restyle_damage());
                 flow.repair_style(node.style());
                 true
             }
-            ConstructionItemConstructionResult(_) => {
+            ConstructionResult::ConstructionItem(_) => {
                 false
             }
         }
     }
 }
 
 impl<'a> PostorderNodeMutTraversal for FlowConstructor<'a> {
     // Construct Flow based on 'display', 'position', and 'float' values.
@@ -1073,38 +1065,38 @@ impl<'a> PostorderNodeMutTraversal for F
     // final computed value for 'display'.
     fn process(&mut self, node: &ThreadSafeLayoutNode) -> bool {
         // Get the `display` property for this node, and determine whether this node is floated.
         let (display, float, positioning) = match node.type_id() {
             None => {
                 // Pseudo-element.
                 let style = node.style();
                 let display = match node.get_pseudo_element_type() {
-                    Normal => display::inline,
-                    Before(display) => display,
-                    After(display) => display,
+                    PseudoElementType::Normal => display::inline,
+                    PseudoElementType::Before(display) => display,
+                    PseudoElementType::After(display) => display,
                 };
                 (display, style.get_box().float, style.get_box().position)
             }
-            Some(ElementNodeTypeId(_)) => {
+            Some(NodeTypeId::Element(_)) => {
                 let style = node.style();
                 let munged_display = if style.get_box()._servo_display_for_hypothetical_box ==
                         display::inline {
                     display::inline
                 } else {
                     style.get_box().display
                 };
                 (munged_display, style.get_box().float, style.get_box().position)
             }
-            Some(TextNodeTypeId) => (display::inline, float::none, position::static_),
-            Some(CommentNodeTypeId) |
-            Some(DoctypeNodeTypeId) |
-            Some(DocumentFragmentNodeTypeId) |
-            Some(DocumentNodeTypeId) |
-            Some(ProcessingInstructionNodeTypeId) => {
+            Some(NodeTypeId::Text) => (display::inline, float::none, position::static_),
+            Some(NodeTypeId::Comment) |
+            Some(NodeTypeId::DocumentType) |
+            Some(NodeTypeId::DocumentFragment) |
+            Some(NodeTypeId::Document) |
+            Some(NodeTypeId::ProcessingInstruction) => {
                 (display::none, float::none, position::static_)
             }
         };
 
         debug!("building flow for node: {} {}", display, float);
 
         // Switch on display and floatedness.
         match (display, float, positioning) {
@@ -1223,42 +1215,42 @@ trait NodeUtils {
     /// Returns true if this node doesn't render its kids and false otherwise.
     fn is_replaced_content(&self) -> bool;
 
     fn get_construction_result<'a>(self, layout_data: &'a mut LayoutDataWrapper) -> &'a mut ConstructionResult;
 
     /// Sets the construction result of a flow.
     fn set_flow_construction_result(self, result: ConstructionResult);
 
-    /// Replaces the flow construction result in a node with `NoConstructionResult` and returns the
+    /// Replaces the flow construction result in a node with `ConstructionResult::None` and returns the
     /// old value.
     fn swap_out_construction_result(self) -> ConstructionResult;
 }
 
 impl<'ln> NodeUtils for ThreadSafeLayoutNode<'ln> {
     fn is_replaced_content(&self) -> bool {
         match self.type_id() {
-            Some(TextNodeTypeId) |
-            Some(ProcessingInstructionNodeTypeId) |
-            Some(CommentNodeTypeId) |
-            Some(DoctypeNodeTypeId) |
-            Some(DocumentFragmentNodeTypeId) |
-            Some(DocumentNodeTypeId) |
+            Some(NodeTypeId::Text) |
+            Some(NodeTypeId::ProcessingInstruction) |
+            Some(NodeTypeId::Comment) |
+            Some(NodeTypeId::DocumentType) |
+            Some(NodeTypeId::DocumentFragment) |
+            Some(NodeTypeId::Document) |
             None |
-            Some(ElementNodeTypeId(HTMLImageElementTypeId)) => true,
-            Some(ElementNodeTypeId(HTMLObjectElementTypeId)) => self.has_object_data(),
-            Some(ElementNodeTypeId(_)) => false,
+            Some(NodeTypeId::Element(ElementTypeId::HTMLImageElement)) => true,
+            Some(NodeTypeId::Element(ElementTypeId::HTMLObjectElement)) => self.has_object_data(),
+            Some(NodeTypeId::Element(_)) => false,
         }
     }
 
     fn get_construction_result<'a>(self, layout_data: &'a mut LayoutDataWrapper) -> &'a mut ConstructionResult {
         match self.get_pseudo_element_type() {
-            Before(_) => &mut layout_data.data.before_flow_construction_result,
-            After (_) => &mut layout_data.data.after_flow_construction_result,
-            Normal    => &mut layout_data.data.flow_construction_result,
+            PseudoElementType::Before(_) => &mut layout_data.data.before_flow_construction_result,
+            PseudoElementType::After (_) => &mut layout_data.data.after_flow_construction_result,
+            PseudoElementType::Normal    => &mut layout_data.data.flow_construction_result,
         }
     }
 
     #[inline(always)]
     fn set_flow_construction_result(self, result: ConstructionResult) {
         let mut layout_data_ref = self.mutate_layout_data();
         let layout_data = layout_data_ref.as_mut().expect("no layout data");
 
--- a/servo/components/layout/css/matching.rs
+++ b/servo/components/layout/css/matching.rs
@@ -4,27 +4,27 @@
 
 //! High-level interface to CSS selector matching.
 
 use css::node_style::StyledNode;
 use incremental::{mod, RestyleDamage};
 use util::{LayoutDataAccess, LayoutDataWrapper};
 use wrapper::{LayoutElement, LayoutNode, TLayoutNode};
 
-use script::dom::node::{TextNodeTypeId};
+use script::dom::node::NodeTypeId;
 use servo_util::bloom::BloomFilter;
 use servo_util::cache::{Cache, LRUCache, SimpleHashCache};
 use servo_util::smallvec::{SmallVec, SmallVec16};
 use servo_util::arc_ptr_eq;
 use std::mem;
 use std::hash::{Hash, sip};
 use std::slice::Items;
 use string_cache::{Atom, Namespace};
-use style::{mod, After, Before, ComputedValues, DeclarationBlock, Stylist, TElement, TNode};
-use style::{AttrIsEqualMode, AttrIsPresentMode, CommonStyleAffectingAttributes, cascade};
+use style::{mod, PseudoElement, ComputedValues, DeclarationBlock, Stylist, TElement, TNode};
+use style::{CommonStyleAffectingAttributeMode, CommonStyleAffectingAttributes, cascade};
 use sync::Arc;
 
 pub struct ApplicableDeclarations {
     pub normal: SmallVec16<DeclarationBlock>,
     pub before: Vec<DeclarationBlock>,
     pub after: Vec<DeclarationBlock>,
 
     /// Whether the `normal` declarations are shareable with other nodes.
@@ -148,22 +148,22 @@ pub struct StyleSharingCandidateCache {
     cache: LRUCache<StyleSharingCandidate,()>,
 }
 
 fn create_common_style_affecting_attributes_from_element(element: &LayoutElement)
                                                          -> CommonStyleAffectingAttributes {
     let mut flags = CommonStyleAffectingAttributes::empty();
     for attribute_info in style::common_style_affecting_attributes().iter() {
         match attribute_info.mode {
-            AttrIsPresentMode(flag) => {
+            CommonStyleAffectingAttributeMode::IsPresent(flag) => {
                 if element.get_attr(&ns!(""), &attribute_info.atom).is_some() {
                     flags.insert(flag)
                 }
             }
-            AttrIsEqualMode(target_value, flag) => {
+            CommonStyleAffectingAttributeMode::IsEqual(target_value, flag) => {
                 match element.get_attr(&ns!(""), &attribute_info.atom) {
                     Some(element_value) if element_value == target_value => {
                         flags.insert(flag)
                     }
                     _ => {}
                 }
             }
         }
@@ -268,23 +268,23 @@ impl StyleSharingCandidate {
             return false
         }
 
         // FIXME(pcwalton): It's probably faster to iterate over all the element's attributes and
         // use the {common, rare}-style-affecting-attributes tables as lookup tables.
 
         for attribute_info in style::common_style_affecting_attributes().iter() {
             match attribute_info.mode {
-                AttrIsPresentMode(flag) => {
+                CommonStyleAffectingAttributeMode::IsPresent(flag) => {
                     if self.common_style_affecting_attributes.contains(flag) !=
                             element.get_attr(&ns!(""), &attribute_info.atom).is_some() {
                         return false
                     }
                 }
-                AttrIsEqualMode(target_value, flag) => {
+                CommonStyleAffectingAttributeMode::IsEqual(target_value, flag) => {
                     match element.get_attr(&ns!(""), &attribute_info.atom) {
                         Some(ref element_value) if self.common_style_affecting_attributes
                                                        .contains(flag) &&
                                                        *element_value != target_value => {
                             return false
                         }
                         Some(_) if !self.common_style_affecting_attributes.contains(flag) => {
                             return false
@@ -496,62 +496,62 @@ impl<'ln> MatchMethods for LayoutNode<'l
             stylist.push_applicable_declarations(self,
                                                  parent_bf,
                                                  style_attribute,
                                                  None,
                                                  &mut applicable_declarations.normal);
         stylist.push_applicable_declarations(self,
                                              parent_bf,
                                              None,
-                                             Some(Before),
+                                             Some(PseudoElement::Before),
                                              &mut applicable_declarations.before);
         stylist.push_applicable_declarations(self,
                                              parent_bf,
                                              None,
-                                             Some(After),
+                                             Some(PseudoElement::After),
                                              &mut applicable_declarations.after);
 
         *shareable = applicable_declarations.normal_shareable &&
             applicable_declarations.before.len() == 0 &&
             applicable_declarations.after.len() == 0
     }
 
     unsafe fn share_style_if_possible(&self,
                                       style_sharing_candidate_cache:
                                         &mut StyleSharingCandidateCache,
                                       parent: Option<LayoutNode>)
                                       -> StyleSharingResult {
         if !self.is_element() {
-            return CannotShare(false)
+            return StyleSharingResult::CannotShare(false)
         }
         let ok = {
             let element = self.as_element();
             element.style_attribute().is_none() &&
                 element.get_attr(&ns!(""), &atom!("id")).is_none()
         };
         if !ok {
-            return CannotShare(false)
+            return StyleSharingResult::CannotShare(false)
         }
 
         for (i, &(ref candidate, ())) in style_sharing_candidate_cache.iter().enumerate() {
             match self.share_style_with_candidate_if_possible(parent.clone(), candidate) {
                 Some(shared_style) => {
                     // Yay, cache hit. Share the style.
                     let mut layout_data_ref = self.mutate_layout_data();
                     let shared_data = &mut layout_data_ref.as_mut().unwrap().shared_data;
                     let style = &mut shared_data.style;
                     let damage = incremental::compute_damage(style, &*shared_style);
                     *style = Some(shared_style);
-                    return StyleWasShared(i, damage)
+                    return StyleSharingResult::StyleWasShared(i, damage)
                 }
                 None => {}
             }
         }
 
-        CannotShare(true)
+        StyleSharingResult::CannotShare(true)
     }
 
     // The below two functions are copy+paste because I can't figure out how to
     // write a function which takes a generic function. I don't think it can
     // be done.
     //
     // Ideally, I'd want something like:
     //
@@ -609,17 +609,17 @@ impl<'ln> MatchMethods for LayoutNode<'l
             }
         };
 
         let mut layout_data_ref = self.mutate_layout_data();
         match &mut *layout_data_ref {
             &None => panic!("no layout data"),
             &Some(ref mut layout_data) => {
                 match self.type_id() {
-                    Some(TextNodeTypeId) => {
+                    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/css/node_style.rs
+++ b/servo/components/layout/css/node_style.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/. */
 
 //! Style retrieval from DOM elements.
 
-use wrapper::{After, Before, Normal, ThreadSafeLayoutNode};
+use wrapper::{PseudoElementType, ThreadSafeLayoutNode};
 
 use std::mem;
 use style::ComputedValues;
 use sync::Arc;
 
 /// Node mixin providing `style` method that returns a `NodeStyle`
 pub trait StyledNode {
     /// Returns the style results for the given node. If CSS selector matching has not yet been
@@ -22,33 +22,33 @@ pub trait StyledNode {
 }
 
 impl<'ln> StyledNode for ThreadSafeLayoutNode<'ln> {
     #[inline]
     fn style<'a>(&'a self) -> &'a Arc<ComputedValues> {
         unsafe {
             let layout_data_ref = self.borrow_layout_data();
             match self.get_pseudo_element_type() {
-                Before(_) => {
+                PseudoElementType::Before(_) => {
                      mem::transmute(layout_data_ref.as_ref()
                                                    .unwrap()
                                                    .data
                                                    .before_style
                                                    .as_ref()
                                                    .unwrap())
                 }
-                After(_) => {
+                PseudoElementType::After(_) => {
                     mem::transmute(layout_data_ref.as_ref()
                                                   .unwrap()
                                                   .data
                                                   .after_style
                                                   .as_ref()
                                                   .unwrap())
                 }
-                Normal => {
+                PseudoElementType::Normal => {
                     mem::transmute(layout_data_ref.as_ref()
                                                   .unwrap()
                                                   .shared_data
                                                   .style
                                                   .as_ref()
                                                   .unwrap())
                 }
             }
@@ -61,16 +61,16 @@ impl<'ln> StyledNode for ThreadSafeLayou
     }
 
     fn unstyle(self) {
         let mut layout_data_ref = self.mutate_layout_data();
         let layout_data = layout_data_ref.as_mut().expect("no layout data");
 
         let style =
             match self.get_pseudo_element_type() {
-                Before(_) => &mut layout_data.data.before_style,
-                After (_) => &mut layout_data.data.after_style,
-                Normal    => &mut layout_data.shared_data.style,
+                PseudoElementType::Before(_) => &mut layout_data.data.before_style,
+                PseudoElementType::After (_) => &mut layout_data.data.after_style,
+                PseudoElementType::Normal    => &mut layout_data.shared_data.style,
             };
 
         *style = None;
     }
 }
--- a/servo/components/layout/display_list_builder.rs
+++ b/servo/components/layout/display_list_builder.rs
@@ -8,21 +8,18 @@
 //! list building, as the actual painting does not happen here—only deciding *what* we're going to
 //! paint.
 
 #![deny(unsafe_blocks)]
 
 use block::BlockFlow;
 use context::LayoutContext;
 use flow::{mod, Flow, IS_ABSOLUTELY_POSITIONED, NEEDS_LAYER};
-use fragment::{Fragment, GenericFragment, IframeFragment, IframeFragmentInfo, ImageFragment};
-use fragment::{ImageFragmentInfo, InlineAbsoluteHypotheticalFragment, InlineBlockFragment};
-use fragment::{ScannedTextFragment, ScannedTextFragmentInfo, TableFragment};
-use fragment::{TableCellFragment, TableColumnFragment, TableRowFragment, TableWrapperFragment};
-use fragment::{UnscannedTextFragment};
+use fragment::{Fragment, SpecificFragmentInfo, IframeFragmentInfo, ImageFragmentInfo};
+use fragment::ScannedTextFragmentInfo;
 use list_item::ListItemFlow;
 use model;
 use util::{OpaqueNodeMethods, ToGfxColor};
 
 use geom::approxeq::ApproxEq;
 use geom::{Point2D, Rect, Size2D, SideOffsets2D};
 use gfx::color;
 use gfx::display_list::{BOX_SHADOW_INFLATION_FACTOR, BaseDisplayItem, BorderDisplayItem};
@@ -36,43 +33,44 @@ use gfx::display_list::{StackingContext,
 use gfx::paint_task::PaintLayer;
 use servo_msg::compositor_msg::{FixedPosition, Scrollable};
 use servo_msg::constellation_msg::{ConstellationChan, FrameRectMsg};
 use servo_net::image::holder::ImageHolder;
 use servo_util::geometry::{mod, Au, ZERO_POINT, ZERO_RECT};
 use servo_util::logical_geometry::{LogicalRect, WritingMode};
 use servo_util::opts;
 use std::default::Default;
-use style::computed::{AngleAoc, CornerAoc, LP_Length, LP_Percentage, LengthOrPercentage};
-use style::computed::{LinearGradient, LinearGradientImage, UrlImage};
+use std::num::FloatMath;
+use style::computed::{AngleOrCorner, LengthOrPercentage, HorizontalDirection, VerticalDirection};
+use style::computed::{Image, LinearGradient};
 use style::computed_values::{background_attachment, background_repeat, border_style, overflow};
 use style::computed_values::{visibility};
-use style::{ComputedValues, Bottom, Left, RGBA, Right, Top};
+use style::{ComputedValues, RGBA};
 use style::style_structs::Border;
 use sync::Arc;
 use url::Url;
 
 /// The results of display list building for a single flow.
 pub enum DisplayListBuildingResult {
-    NoDisplayListBuildingResult,
-    StackingContextResult(Arc<StackingContext>),
-    DisplayListResult(Box<DisplayList>),
+    None,
+    StackingContext(Arc<StackingContext>),
+    Normal(Box<DisplayList>),
 }
 
 impl DisplayListBuildingResult {
     /// Adds the display list items contained within this display list building result to the given
     /// display list, preserving stacking order. If this display list building result does not
     /// consist of an entire stacking context, it will be emptied.
     pub fn add_to(&mut self, display_list: &mut DisplayList) {
         match *self {
-            NoDisplayListBuildingResult => return,
-            StackingContextResult(ref mut stacking_context) => {
+            DisplayListBuildingResult::None => return,
+            DisplayListBuildingResult::StackingContext(ref mut stacking_context) => {
                 display_list.children.push_back((*stacking_context).clone())
             }
-            DisplayListResult(ref mut source_display_list) => {
+            DisplayListBuildingResult::Normal(ref mut source_display_list) => {
                 display_list.append_from(&mut **source_display_list)
             }
         }
     }
 }
 
 pub trait FragmentDisplayListBuilding {
     /// Adds the display items necessary to paint the background of this fragment to the display
@@ -205,25 +203,25 @@ impl FragmentDisplayListBuilding for Fra
         }
 
         // The background image is painted on top of the background color.
         // Implements background image, per spec:
         // http://www.w3.org/TR/CSS21/colors.html#background
         let background = style.get_background();
         match background.background_image {
             None => {}
-            Some(LinearGradientImage(ref gradient)) => {
+            Some(Image::LinearGradient(ref gradient)) => {
                 self.build_display_list_for_background_linear_gradient(display_list,
                                                                        level,
                                                                        absolute_bounds,
                                                                        clip_rect,
                                                                        gradient,
                                                                        style)
             }
-            Some(UrlImage(ref image_url)) => {
+            Some(Image::Url(ref image_url)) => {
                 self.build_display_list_for_background_image(style,
                                                              display_list,
                                                              layout_context,
                                                              level,
                                                              absolute_bounds,
                                                              clip_rect,
                                                              image_url)
             }
@@ -325,30 +323,30 @@ impl FragmentDisplayListBuilding for Fra
                                                          clip_rect: &Rect<Au>,
                                                          gradient: &LinearGradient,
                                                          style: &ComputedValues) {
         let clip_rect = clip_rect.intersection(absolute_bounds).unwrap_or(ZERO_RECT);
 
         // This is the distance between the center and the ending point; i.e. half of the distance
         // between the starting point and the ending point.
         let delta = match gradient.angle_or_corner {
-            AngleAoc(angle) => {
+            AngleOrCorner::Angle(angle) => {
                 Point2D(Au((angle.radians().sin() *
                              absolute_bounds.size.width.to_f64().unwrap() / 2.0) as i32),
                         Au((-angle.radians().cos() *
                              absolute_bounds.size.height.to_f64().unwrap() / 2.0) as i32))
             }
-            CornerAoc(horizontal, vertical) => {
+            AngleOrCorner::Corner(horizontal, vertical) => {
                 let x_factor = match horizontal {
-                    Left => -1,
-                    Right => 1,
+                    HorizontalDirection::Left => -1,
+                    HorizontalDirection::Right => 1,
                 };
                 let y_factor = match vertical {
-                    Top => -1,
-                    Bottom => 1,
+                    VerticalDirection::Top => -1,
+                    VerticalDirection::Bottom => 1,
                 };
                 Point2D(Au(x_factor * absolute_bounds.size.width.to_i32().unwrap() / 2),
                         Au(y_factor * absolute_bounds.size.height.to_i32().unwrap() / 2))
             }
         };
 
         // This is the length of the gradient line.
         let length = Au((delta.x.to_f64().unwrap() * 2.0).hypot(delta.y.to_f64().unwrap() * 2.0)
@@ -642,17 +640,17 @@ impl FragmentDisplayListBuilding for Fra
                             level,
                             &absolute_fragment_bounds,
                             clip_rect);
                     }
                 }
                 None => {}
             }
             match self.specific {
-                ScannedTextFragment(_) => {},
+                SpecificFragmentInfo::ScannedText(_) => {},
                 _ => {
                     self.build_display_list_for_box_shadow_if_applicable(
                         &*self.style,
                         display_list,
                         layout_context,
                         level,
                         &absolute_fragment_bounds,
                         clip_rect);
@@ -670,17 +668,17 @@ impl FragmentDisplayListBuilding for Fra
                             level,
                             &absolute_fragment_bounds,
                             clip_rect);
                     }
                 }
                 None => {}
             }
             match self.specific {
-                ScannedTextFragment(_) => {},
+                SpecificFragmentInfo::ScannedText(_) => {},
                 _ => {
                     self.build_display_list_for_background_if_applicable(
                         &*self.style,
                         display_list,
                         layout_context,
                         level,
                         &absolute_fragment_bounds,
                         clip_rect);
@@ -702,17 +700,17 @@ impl FragmentDisplayListBuilding for Fra
                             display_list,
                             &absolute_fragment_bounds,
                             clip_rect);
                     }
                 }
                 None => {}
             }
             match self.specific {
-                ScannedTextFragment(_) => {},
+                SpecificFragmentInfo::ScannedText(_) => {},
                 _ => {
                     self.build_display_list_for_borders_if_applicable(
                         &*self.style,
                         display_list,
                         &absolute_fragment_bounds,
                         level,
                         clip_rect);
                     self.build_display_list_for_outline_if_applicable(
@@ -724,19 +722,19 @@ impl FragmentDisplayListBuilding for Fra
             }
         }
 
         let content_box = self.content_box();
         let absolute_content_box = rect_to_absolute(self.style.writing_mode, content_box);
 
         // Create special per-fragment-type display items.
         match self.specific {
-            UnscannedTextFragment(_) => panic!("Shouldn't see unscanned fragments here."),
-            TableColumnFragment(_) => panic!("Shouldn't see table column fragments here."),
-            ScannedTextFragment(ref text_fragment) => {
+            SpecificFragmentInfo::UnscannedText(_) => panic!("Shouldn't see unscanned fragments here."),
+            SpecificFragmentInfo::TableColumn(_) => panic!("Shouldn't see table column fragments here."),
+            SpecificFragmentInfo::ScannedText(ref text_fragment) => {
                 // Create the text display item.
                 let orientation = if self.style.writing_mode.is_vertical() {
                     if self.style.writing_mode.is_sideways_left() {
                         SidewaysLeft
                     } else {
                         SidewaysRight
                     }
                 } else {
@@ -801,26 +799,26 @@ impl FragmentDisplayListBuilding for Fra
 
                 if opts::get().show_debug_fragment_borders {
                     self.build_debug_borders_around_text_fragments(display_list,
                                                                    flow_origin,
                                                                    &**text_fragment,
                                                                    clip_rect);
                 }
             }
-            GenericFragment | IframeFragment(..) | TableFragment | TableCellFragment |
-            TableRowFragment | TableWrapperFragment | InlineBlockFragment(_) |
-            InlineAbsoluteHypotheticalFragment(_) => {
+            SpecificFragmentInfo::Generic | SpecificFragmentInfo::Iframe(..) | SpecificFragmentInfo::Table | SpecificFragmentInfo::TableCell |
+            SpecificFragmentInfo::TableRow | SpecificFragmentInfo::TableWrapper | SpecificFragmentInfo::InlineBlock(_) |
+            SpecificFragmentInfo::InlineAbsoluteHypothetical(_) => {
                 if opts::get().show_debug_fragment_borders {
                     self.build_debug_borders_around_fragment(display_list,
                                                              flow_origin,
                                                              clip_rect);
                 }
             }
-            ImageFragment(ref mut image_fragment) => {
+            SpecificFragmentInfo::Image(ref mut image_fragment) => {
                 let image_ref = &mut image_fragment.image;
                 match image_ref.get_image(self.node.to_untrusted_node_address()) {
                     Some(image) => {
                         debug!("(building display list) building image fragment");
 
                         // Place the image into the display list.
                         display_list.content.push_back(ImageDisplayItemClass(box ImageDisplayItem {
                             base: BaseDisplayItem::new(absolute_content_box,
@@ -852,17 +850,17 @@ impl FragmentDisplayListBuilding for Fra
         // problematic if iframes are outside the area we're computing the display list for, since
         // they won't be able to reflow at all until the user scrolls to them. Perhaps we should
         // separate this into two parts: first we should send the size only to the constellation
         // once that's computed during assign-block-sizes, and second we should should send the
         // origin to the constellation here during display list construction. This should work
         // because layout for the iframe only needs to know size, and origin is only relevant if
         // the iframe is actually going to be displayed.
         match self.specific {
-            IframeFragment(ref iframe_fragment) => {
+            SpecificFragmentInfo::Iframe(ref iframe_fragment) => {
                 self.finalize_position_and_size_of_iframe(&**iframe_fragment,
                                                           absolute_fragment_bounds.origin,
                                                           layout_context)
             }
             _ => {}
         }
     }
 
@@ -886,17 +884,17 @@ impl FragmentDisplayListBuilding for Fra
                                iframe_fragment.subpage_id,
                                iframe_rect));
     }
 
     fn clip_rect_for_children(&self, current_clip_rect: Rect<Au>, flow_origin: Point2D<Au>)
                               -> Rect<Au> {
         // Don't clip if we're text.
         match self.specific {
-            ScannedTextFragment(_) => return current_clip_rect,
+            SpecificFragmentInfo::ScannedText(_) => return current_clip_rect,
             _ => {}
         }
 
         // Only clip if `overflow` tells us to.
         match self.style.get_box().overflow {
             overflow::hidden | overflow::auto | overflow::scroll => {}
             _ => return current_clip_rect,
         }
@@ -957,79 +955,79 @@ impl BlockFlowDisplayListBuilding for Bl
                                            mut display_list: Box<DisplayList>,
                                            layout_context: &LayoutContext,
                                            background_border_level: BackgroundAndBorderLevel) {
         self.build_display_list_for_block_base(&mut *display_list,
                                                layout_context,
                                                background_border_level);
 
         self.base.display_list_building_result = if self.fragment.establishes_stacking_context() {
-            StackingContextResult(self.create_stacking_context(display_list, None))
+            DisplayListBuildingResult::StackingContext(self.create_stacking_context(display_list, None))
         } else {
-            DisplayListResult(display_list)
+            DisplayListBuildingResult::Normal(display_list)
         }
     }
 
     fn build_display_list_for_absolutely_positioned_block(&mut self,
                                                           mut display_list: Box<DisplayList>,
                                                           layout_context: &LayoutContext) {
         self.build_display_list_for_block_base(&mut *display_list,
                                                layout_context,
-                                               RootOfStackingContextLevel);
+                                               BackgroundAndBorderLevel::RootOfStackingContext);
 
         if !self.base.absolute_position_info.layers_needed_for_positioned_flows &&
                 !self.base.flags.contains(NEEDS_LAYER) {
             // We didn't need a layer.
             self.base.display_list_building_result =
-                StackingContextResult(self.create_stacking_context(display_list, None));
+                DisplayListBuildingResult::StackingContext(self.create_stacking_context(display_list, None));
             return
         }
 
         // If we got here, then we need a new layer.
         let scroll_policy = if self.is_fixed() {
             FixedPosition
         } else {
             Scrollable
         };
 
         let transparent = color::rgba(1.0, 1.0, 1.0, 0.0);
         let stacking_context =
             self.create_stacking_context(display_list,
                                          Some(Arc::new(PaintLayer::new(self.layer_id(0),
                                                                        transparent,
                                                                        scroll_policy))));
-        self.base.display_list_building_result = StackingContextResult(stacking_context)
+        self.base.display_list_building_result = DisplayListBuildingResult::StackingContext(stacking_context)
     }
 
     fn build_display_list_for_floating_block(&mut self,
                                              mut display_list: Box<DisplayList>,
                                              layout_context: &LayoutContext) {
         self.build_display_list_for_block_base(&mut *display_list,
                                                layout_context,
-                                               RootOfStackingContextLevel);
+                                               BackgroundAndBorderLevel::RootOfStackingContext);
         display_list.form_float_pseudo_stacking_context();
 
         self.base.display_list_building_result = if self.fragment.establishes_stacking_context() {
-            StackingContextResult(self.create_stacking_context(display_list, None))
+            DisplayListBuildingResult::StackingContext(self.create_stacking_context(display_list, None))
         } else {
-            DisplayListResult(display_list)
+            DisplayListBuildingResult::Normal(display_list)
         }
     }
 
     fn build_display_list_for_block(&mut self,
                                     display_list: Box<DisplayList>,
                                     layout_context: &LayoutContext) {
         if self.base.flags.is_float() {
             // TODO(#2009, pcwalton): This is a pseudo-stacking context. We need to merge `z-index:
             // auto` kids into the parent stacking context, when that is supported.
             self.build_display_list_for_floating_block(display_list, layout_context)
         } else if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
             self.build_display_list_for_absolutely_positioned_block(display_list, layout_context)
         } else {
-            self.build_display_list_for_static_block(display_list, layout_context, BlockLevel)
+            self.build_display_list_for_static_block(display_list, layout_context, BackgroundAndBorderLevel::Block)
         }
     }
 
     fn create_stacking_context(&self,
                                display_list: Box<DisplayList>,
                                layer: Option<Arc<PaintLayer>>)
                                -> Arc<StackingContext> {
         let bounds = Rect(self.base.stacking_relative_position,
@@ -1054,17 +1052,17 @@ impl ListItemFlowDisplayListBuilding for
         match self.marker {
             None => {}
             Some(ref mut marker) => {
                 let stacking_relative_fragment_origin =
                     self.block_flow.base.stacking_relative_position_of_child_fragment(marker);
                 marker.build_display_list(&mut *display_list,
                                           layout_context,
                                           stacking_relative_fragment_origin,
-                                          ContentLevel,
+                                          BackgroundAndBorderLevel::Content,
                                           &self.block_flow.base.clip_rect);
             }
         }
 
         // Draw the rest of the block.
         self.block_flow.build_display_list_for_block(display_list, layout_context)
     }
 }
@@ -1082,60 +1080,60 @@ fn fmin(a: f32, b: f32) -> f32 {
         a
     } else {
         b
     }
 }
 
 fn position_to_offset(position: LengthOrPercentage, Au(total_length): Au) -> f32 {
     match position {
-        LP_Length(Au(length)) => fmin(1.0, (length as f32) / (total_length as f32)),
-        LP_Percentage(percentage) => percentage as f32,
+        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)]
 pub enum StackingLevel {
     /// The border and backgrounds for the root of this stacking context: steps 1 and 2.
-    BackgroundAndBordersStackingLevel,
+    BackgroundAndBorders,
     /// Borders and backgrounds for block-level descendants: step 4.
-    BlockBackgroundsAndBordersStackingLevel,
+    BlockBackgroundsAndBorders,
     /// All other content.
-    ContentStackingLevel,
+    Content,
 }
 
 impl StackingLevel {
     #[inline]
     pub fn from_background_and_border_level(level: BackgroundAndBorderLevel) -> StackingLevel {
         match level {
-            RootOfStackingContextLevel => BackgroundAndBordersStackingLevel,
-            BlockLevel => BlockBackgroundsAndBordersStackingLevel,
-            ContentLevel => ContentStackingLevel,
+            BackgroundAndBorderLevel::RootOfStackingContext => StackingLevel::BackgroundAndBorders,
+            BackgroundAndBorderLevel::Block => StackingLevel::BlockBackgroundsAndBorders,
+            BackgroundAndBorderLevel::Content => StackingLevel::Content,
         }
     }
 }
 
 /// Which level to place backgrounds and borders in.
 pub enum BackgroundAndBorderLevel {
-    RootOfStackingContextLevel,
-    BlockLevel,
-    ContentLevel,
+    RootOfStackingContext,
+    Block,
+    Content,
 }
 
 trait StackingContextConstruction {
     /// Adds the given display item at the specified level to this display list.
     fn push(&mut self, display_item: DisplayItem, level: StackingLevel);
 }
 
 impl StackingContextConstruction for DisplayList {
     fn push(&mut self, display_item: DisplayItem, level: StackingLevel) {
         match level {
-            BackgroundAndBordersStackingLevel => {
+            StackingLevel::BackgroundAndBorders => {
                 self.background_and_borders.push_back(display_item)
             }
-            BlockBackgroundsAndBordersStackingLevel => {
+            StackingLevel::BlockBackgroundsAndBorders => {
                 self.block_backgrounds_and_borders.push_back(display_item)
             }
-            ContentStackingLevel => self.content.push_back(display_item),
+            StackingLevel::Content => self.content.push_back(display_item),
         }
     }
 }
--- a/servo/components/layout/floats.rs
+++ b/servo/components/layout/floats.rs
@@ -9,35 +9,35 @@ use servo_util::persistent_list::Persist
 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)]
 pub enum FloatKind {
-    FloatLeft,
-    FloatRight
+    Left,
+    Right
 }
 
 impl FloatKind {
     pub fn from_property(property: float::T) -> FloatKind {
         match property {
             float::none => panic!("can't create a float type from an unfloated property"),
-            float::left => FloatLeft,
-            float::right => FloatRight,
+            float::left => FloatKind::Left,
+            float::right => FloatKind::Right,
         }
     }
 }
 
 /// The kind of clearance: left, right, or both.
 pub enum ClearType {
-    ClearLeft,
-    ClearRight,
-    ClearBoth,
+    Left,
+    Right,
+    Both,
 }
 
 /// Information about a single float.
 #[deriving(Clone)]
 struct Float {
     /// The boundaries of this float.
     bounds: LogicalRect<Au>,
     /// The kind of float: left or right.
@@ -179,40 +179,40 @@ impl Floats {
         // 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);
             match float.kind {
-                FloatLeft if float_pos.i + float_size.inline > max_inline_start &&
+                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);
                 }
-                FloatRight if float_pos.i < min_inline_end &&
+                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 {}",
                             min_inline_end);
                 }
-                FloatLeft | FloatRight => {}
+                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
         // two areas. Also make sure we never return a block-start smaller than the
         // given upper bound.
         let (block_start, block_end) = match (r_block_start,
@@ -302,25 +302,25 @@ impl Floats {
     /// 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);
 
         // If no floats, use this fast path.
         if !self.list.is_present() {
             match info.kind {
-                FloatLeft => {
+                FloatKind::Left => {
                     return LogicalRect::new(
                         self.writing_mode,
                         Au(0),
                         info.ceiling,
                         info.max_inline_size,
                         Au(i32::MAX))
                 }
-                FloatRight => {
+                FloatKind::Right => {
                     return LogicalRect::new(
                         self.writing_mode,
                         info.max_inline_size - info.size.inline,
                         info.ceiling,
                         info.max_inline_size,
                         Au(i32::MAX))
                 }
             }
@@ -333,25 +333,25 @@ impl Floats {
                                                      info.size.block,
                                                      info.max_inline_size);
             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 {
-                        FloatLeft => {
+                        FloatKind::Left => {
                             LogicalRect::new(
                                 self.writing_mode,
                                 Au(0),
                                 float_b,
                                 info.max_inline_size,
                                 Au(i32::MAX))
                         }
-                        FloatRight => {
+                        FloatKind::Right => {
                             LogicalRect::new(
                                 self.writing_mode,
                                 info.max_inline_size - info.size.inline,
                                 float_b,
                                 info.max_inline_size,
                                 Au(i32::MAX))
                         }
                     }
@@ -362,25 +362,25 @@ impl Floats {
 
                     // Place here if there is enough room
                     if rect.size.inline >= info.size.inline {
                         let block_size = self.max_block_size_for_bounds(rect.start.i,
                                                                 rect.start.b,
                                                                 rect.size.inline);
                         let block_size = block_size.unwrap_or(Au(i32::MAX));
                         return match info.kind {
-                            FloatLeft => {
+                            FloatKind::Left => {
                                 LogicalRect::new(
                                     self.writing_mode,
                                     rect.start.i,
                                     float_b,
                                     rect.size.inline,
                                     block_size)
                             }
-                            FloatRight => {
+                            FloatKind::Right => {
                                 LogicalRect::new(
                                     self.writing_mode,
                                     rect.start.i + rect.size.inline - info.size.inline,
                                     float_b,
                                     rect.size.inline,
                                     block_size)
                             }
                         }
@@ -394,19 +394,19 @@ impl Floats {
         }
     }
 
     pub fn clearance(&self, clear: ClearType) -> Au {
         let list = &self.list;
         let mut clearance = Au(0);
         for float in list.floats.iter() {
             match (clear, float.kind) {
-                (ClearLeft, FloatLeft) |
-                (ClearRight, FloatRight) |
-                (ClearBoth, _) => {
+                (ClearType::Left, FloatKind::Left) |
+                (ClearType::Right, FloatKind::Right) |
+                (ClearType::Both, _) => {
                     let b = self.offset.block + float.bounds.start.b + float.bounds.size.block;
                     clearance = max(clearance, b);
                 }
                 _ => {}
             }
         }
         clearance
     }
--- a/servo/components/layout/flow.rs
+++ b/servo/components/layout/flow.rs
@@ -23,22 +23,21 @@
 /// * `InlineFlow`: A flow that establishes an inline context. It has a flat list of child
 ///   fragments/flows that are subject to inline layout and line breaking and structs to represent
 ///   line breaks and mapping to CSS boxes, for the purpose of handling `getClientRects()` and
 ///   similar methods.
 
 use css::node_style::StyledNode;
 use block::BlockFlow;
 use context::LayoutContext;
-use display_list_builder::{DisplayListBuildingResult, DisplayListResult};
-use display_list_builder::{NoDisplayListBuildingResult, StackingContextResult};
+use display_list_builder::DisplayListBuildingResult;
 use floats::Floats;
 use flow_list::{FlowList, FlowListIterator, MutFlowListIterator};
 use flow_ref::FlowRef;
-use fragment::{Fragment, FragmentBoundsIterator, TableRowFragment, TableCellFragment};
+use fragment::{Fragment, FragmentBoundsIterator, SpecificFragmentInfo};
 use incremental::{RECONSTRUCT_FLOW, REFLOW, REFLOW_OUT_OF_FLOW, RestyleDamage};
 use inline::InlineFlow;
 use model::{CollapsibleMargins, IntrinsicISizes, MarginCollapseInfo};
 use parallel::FlowParallelInfo;
 use table::{ColumnComputedInlineSize, ColumnIntrinsicInlineSize, TableFlow};
 use table_caption::TableCaptionFlow;
 use table_cell::TableCellFlow;
 use table_colgroup::TableColGroupFlow;
@@ -423,26 +422,26 @@ 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)]
 pub enum FlowClass {
-    BlockFlowClass,
-    InlineFlowClass,
-    ListItemFlowClass,
-    TableWrapperFlowClass,
-    TableFlowClass,
-    TableColGroupFlowClass,
-    TableRowGroupFlowClass,
-    TableRowFlowClass,
-    TableCaptionFlowClass,
-    TableCellFlowClass,
+    Block,
+    Inline,
+    ListItem,
+    TableWrapper,
+    Table,
+    TableColGroup,
+    TableRowGroup,
+    TableRow,
+    TableCaption,
+    TableCell,
 }
 
 /// A top-down traversal.
 pub trait PreorderFlowTraversal {
     /// The operation to perform. Return true to continue or false to stop.
     fn process(&self, flow: &mut Flow);
 
     /// Returns true if this node must be processed in-order. If this returns false,
@@ -805,23 +804,23 @@ impl<E, S: Encoder<E>> Encodable<S, E> f
             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)))
                                 e.emit_struct_field("data", 1, |e| {
                                     match c.class() {
-                                        BlockFlowClass => c.as_immutable_block().encode(e),
-                                        InlineFlowClass => c.as_immutable_inline().encode(e),
-                                        TableFlowClass => c.as_immutable_table().encode(e),
-                                        TableWrapperFlowClass => c.as_immutable_table_wrapper().encode(e),
-                                        TableRowGroupFlowClass => c.as_immutable_table_rowgroup().encode(e),
-                                        TableRowFlowClass => c.as_immutable_table_row().encode(e),
-                                        TableCellFlowClass => c.as_immutable_table_cell().encode(e),
+                                        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(())
@@ -864,17 +863,17 @@ impl BaseFlow {
                 let node_style = node.style();
                 match node_style.get_box().position {
                     position::absolute | position::fixed => {
                         flags.insert(IS_ABSOLUTELY_POSITIONED)
                     }
                     _ => {}
                 }
 
-                if force_nonfloated == FloatIfNecessary {
+                if force_nonfloated == ForceNonfloatedFlag::FloatIfNecessary {
                     match node_style.get_box().float {
                         float::none => {}
                         float::left => flags.insert(FLOATS_LEFT),
                         float::right => flags.insert(FLOATS_RIGHT),
                     }
                 }
 
                 match node_style.get_box().clear {
@@ -905,17 +904,17 @@ impl BaseFlow {
             collapsible_margins: CollapsibleMargins::new(),
             stacking_relative_position: Zero::zero(),
             abs_descendants: Descendants::new(),
             absolute_static_i_offset: Au(0),
             fixed_static_i_offset: Au(0),
             block_container_inline_size: Au(0),
             block_container_explicit_block_size: None,
             absolute_cb: ContainingBlockLink::new(),
-            display_list_building_result: NoDisplayListBuildingResult,
+            display_list_building_result: DisplayListBuildingResult::None,
             absolute_position_info: AbsolutePositionInfo::new(writing_mode),
             clip_rect: Rect(Zero::zero(), Size2D(Au(0), Au(0))),
             flags: flags,
             writing_mode: writing_mode,
         }
     }
 
     pub fn child_iter<'a>(&'a mut self) -> MutFlowListIterator<'a> {
@@ -935,21 +934,21 @@ impl BaseFlow {
     /// rect. This should only be used for debugging.
     pub fn validate_display_list_geometry(&self) {
         let position_with_overflow = self.position.union(&self.overflow);
         let bounds = Rect(self.stacking_relative_position,
                           Size2D(position_with_overflow.size.inline,
                                  position_with_overflow.size.block));
 
         let all_items = match self.display_list_building_result {
-            NoDisplayListBuildingResult => Vec::new(),
-            StackingContextResult(ref stacking_context) => {
+            DisplayListBuildingResult::None => Vec::new(),
+            DisplayListBuildingResult::StackingContext(ref stacking_context) => {
                 stacking_context.display_list.all_display_items()
             }
-            DisplayListResult(ref display_list) => display_list.all_display_items(),
+            DisplayListBuildingResult::Normal(ref display_list) => display_list.all_display_items(),
         };
 
         for item in all_items.iter() {
             let paint_bounds = match item.base().bounds.intersection(&item.base().clip_rect) {
                 None => continue,
                 Some(rect) => rect,
             };
 
@@ -974,110 +973,110 @@ impl BaseFlow {
         self.stacking_relative_position.add_size(&relative_offset.to_physical(self.writing_mode))
     }
 }
 
 impl<'a> ImmutableFlowUtils for &'a Flow + 'a {
     /// Returns true if this flow is a block flow.
     fn is_block_like(self) -> bool {
         match self.class() {
-            BlockFlowClass => true,
+            FlowClass::Block => true,
             _ => false,
         }
     }
 
     /// Returns true if this flow is a proper table child.
     /// 'Proper table child' is defined as table-row flow, table-rowgroup flow,
     /// table-column-group flow, or table-caption flow.
     fn is_proper_table_child(self) -> bool {
         match self.class() {
-            TableRowFlowClass | TableRowGroupFlowClass |
-                TableColGroupFlowClass | TableCaptionFlowClass => true,
+            FlowClass::TableRow | FlowClass::TableRowGroup |
+                FlowClass::TableColGroup | FlowClass::TableCaption => true,
             _ => false,
         }
     }
 
     /// Returns true if this flow is a table row flow.
     fn is_table_row(self) -> bool {
         match self.class() {
-            TableRowFlowClass => true,
+            FlowClass::TableRow => true,
             _ => false,
         }
     }
 
     /// Returns true if this flow is a table cell flow.
     fn is_table_cell(self) -> bool {
         match self.class() {
-            TableCellFlowClass => true,
+            FlowClass::TableCell => true,
             _ => false,
         }
     }
 
     /// Returns true if this flow is a table colgroup flow.
     fn is_table_colgroup(self) -> bool {
         match self.class() {
-            TableColGroupFlowClass => true,
+            FlowClass::TableColGroup => true,
             _ => false,
         }
     }
 
     /// Returns true if this flow is a table flow.
     fn is_table(self) -> bool {
         match self.class() {
-            TableFlowClass => true,
+            FlowClass::Table => true,
             _ => false,
         }
     }
 
     /// Returns true if this flow is a table caption flow.
     fn is_table_caption(self) -> bool {
         match self.class() {
-            TableCaptionFlowClass => true,
+            FlowClass::TableCaption => true,
             _ => false,
         }
     }
 
     /// Returns true if this flow is a table rowgroup flow.
     fn is_table_rowgroup(self) -> bool {
         match self.class() {
-            TableRowGroupFlowClass => true,
+            FlowClass::TableRowGroup => true,
             _ => false,
         }
     }
 
     /// Returns true if this flow is one of table-related flows.
     fn is_table_kind(self) -> bool {
         match self.class() {
-            TableWrapperFlowClass | TableFlowClass |
-                TableColGroupFlowClass | TableRowGroupFlowClass |
-                TableRowFlowClass | TableCaptionFlowClass | TableCellFlowClass => true,
+            FlowClass::TableWrapper | FlowClass::Table |
+                FlowClass::TableColGroup | FlowClass::TableRowGroup |
+                FlowClass::TableRow | FlowClass::TableCaption | FlowClass::TableCell => true,
             _ => false,
         }
     }
 
     /// Returns true if anonymous flow is needed between this flow and child flow.
     /// Spec: http://www.w3.org/TR/CSS21/tables.html#anonymous-boxes
     fn need_anonymous_flow(self, child: &Flow) -> bool {
         match self.class() {
-            TableFlowClass => !child.is_proper_table_child(),
-            TableRowGroupFlowClass => !child.is_table_row(),
-            TableRowFlowClass => !child.is_table_cell(),
+            FlowClass::Table => !child.is_proper_table_child(),
+            FlowClass::TableRowGroup => !child.is_table_row(),
+            FlowClass::TableRow => !child.is_table_cell(),
             _ => false
         }
     }
 
     /// Generates missing child flow of this flow.
     fn generate_missing_child_flow(self, node: &ThreadSafeLayoutNode) -> FlowRef {
         let flow = match self.class() {
-            TableFlowClass | TableRowGroupFlowClass => {
-                let fragment = Fragment::new_anonymous_table_fragment(node, TableRowFragment);
+            FlowClass::Table | FlowClass::TableRowGroup => {
+                let fragment = Fragment::new_anonymous_table_fragment(node, SpecificFragmentInfo::TableRow);
                 box TableRowFlow::from_node_and_fragment(node, fragment) as Box<Flow>
             },
-            TableRowFlowClass => {
-                let fragment = Fragment::new_anonymous_table_fragment(node, TableCellFragment);
+            FlowClass::TableRow => {
+                let fragment = Fragment::new_anonymous_table_fragment(node, SpecificFragmentInfo::TableCell);
                 box TableCellFlow::from_node_and_fragment(node, fragment) as Box<Flow>
             },
             _ => {
                 panic!("no need to generate a missing child")
             }
         };
         FlowRef::new(flow)
     }
@@ -1096,36 +1095,36 @@ impl<'a> ImmutableFlowUtils for &'a Flow
     ///
     /// Except for table fragments and replaced elements, block-level fragments (`BlockFlow`) are
     /// also block container fragments.
     /// Non-replaced inline blocks and non-replaced table cells are also block
     /// containers.
     fn is_block_container(self) -> bool {
         match self.class() {
             // TODO: Change this when inline-blocks are supported.
-            BlockFlowClass | TableCaptionFlowClass | TableCellFlowClass => {
+            FlowClass::Block | FlowClass::TableCaption | FlowClass::TableCell => {
                 // FIXME: Actually check the type of the node
                 self.child_count() != 0
             }
             _ => false,
         }
     }
 
     /// Returns true if this flow is a block flow.
     fn is_block_flow(self) -> bool {
         match self.class() {
-            BlockFlowClass => true,
+            FlowClass::Block => true,
             _ => false,
         }
     }
 
     /// Returns true if this flow is an inline flow.
     fn is_inline_flow(self) -> bool {
         match self.class() {
-            InlineFlowClass => true,
+            FlowClass::Inline => true,
             _ => false,
         }
     }
 
     /// Dumps the flow tree for debugging.
     fn dump(self) {
         self.dump_with_level(0)
     }
--- a/servo/components/layout/fragment.rs
+++ b/servo/components/layout/fragment.rs
@@ -4,24 +4,24 @@
 
 //! The `Fragment` type, which represents the leaves of the layout tree.
 
 #![deny(unsafe_blocks)]
 
 use css::node_style::StyledNode;
 use construct::FlowConstructor;
 use context::LayoutContext;
-use floats::{ClearBoth, ClearLeft, ClearRight, ClearType};
+use floats::ClearType;
 use flow;
 use flow::Flow;
 use flow_ref::FlowRef;
 use incremental::RestyleDamage;
 use inline::{InlineFragmentContext, InlineMetrics};
 use layout_debug;
-use model::{Auto, IntrinsicISizes, IntrinsicISizesContribution, MaybeAuto, Specified, specified};
+use model::{IntrinsicISizes, IntrinsicISizesContribution, MaybeAuto, specified};
 use model;
 use text;
 use util::OpaqueNodeMethods;
 use wrapper::{TLayoutNode, ThreadSafeLayoutNode};
 
 use geom::{Point2D, Rect, Size2D};
 use gfx::display_list::OpaqueNode;
 use gfx::text::glyph::CharIndex;
@@ -34,22 +34,22 @@ use servo_net::local_image_cache::LocalI
 use servo_util::geometry::Au;
 use servo_util::geometry;
 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::from_str::FromStr;
+use std::str::FromStr;
 use string_cache::Atom;
 use style::{ComputedValues, TElement, TNode, cascade_anonymous};
 use style::computed_values::{LengthOrPercentage, LengthOrPercentageOrAuto};
 use style::computed_values::{LengthOrPercentageOrNone};
-use style::computed_values::{LPA_Auto, clear, overflow_wrap, position, text_align};
+use style::computed_values::{clear, overflow_wrap, position, text_align};
 use style::computed_values::{text_decoration, vertical_align, white_space};
 use sync::{Arc, Mutex};
 use url::Url;
 
 /// Fragments (`struct Fragment`) are the leaves of the layout tree. They cannot position
 /// themselves. In general, fragments do not have a simple correspondence with CSS fragments in the
 /// specification:
 ///
@@ -57,17 +57,17 @@ use url::Url;
 /// broken across two lines is represented by two fragments.
 ///
 /// * Some CSS fragments are not created at all, such as some anonymous block fragments induced by
 ///   inline fragments with block-level sibling fragments. In that case, Servo uses an `InlineFlow`
 ///   with `BlockFlow` siblings; the `InlineFlow` is block-level, but not a block container. It is
 ///   positioned as if it were a block fragment, but its children are positioned according to
 ///   inline flow.
 ///
-/// A `GenericFragment` is an empty fragment that contributes only borders, margins, padding, and
+/// A `SpecificFragmentInfo::Generic` is an empty fragment that contributes only borders, margins, padding, and
 /// backgrounds. It is analogous to a CSS nonreplaced content box.
 ///
 /// A fragment's type influences how its styles are interpreted during layout. For example,
 /// replaced content such as images are resized differently from tables, text, or other content.
 /// 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
@@ -119,69 +119,69 @@ impl<E, S: Encoder<E>> Encodable<S, E> f
     }
 }
 
 /// 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)]
 pub enum SpecificFragmentInfo {
-    GenericFragment,
-    IframeFragment(Box<IframeFragmentInfo>),
-    ImageFragment(Box<ImageFragmentInfo>),
+    Generic,
+    Iframe(Box<IframeFragmentInfo>),
+    Image(Box<ImageFragmentInfo>),
 
     /// A hypothetical box (see CSS 2.1 § 10.3.7) for an absolutely-positioned block that was
     /// declared with `display: inline;`.
-    InlineAbsoluteHypotheticalFragment(InlineAbsoluteHypotheticalFragmentInfo),
+    InlineAbsoluteHypothetical(InlineAbsoluteHypotheticalFragmentInfo),
 
-    InlineBlockFragment(InlineBlockFragmentInfo),
-    ScannedTextFragment(Box<ScannedTextFragmentInfo>),
-    TableFragment,
-    TableCellFragment,
-    TableColumnFragment(TableColumnFragmentInfo),
-    TableRowFragment,
-    TableWrapperFragment,
-    UnscannedTextFragment(UnscannedTextFragmentInfo),
+    InlineBlock(InlineBlockFragmentInfo),
+    ScannedText(Box<ScannedTextFragmentInfo>),
+    Table,
+    TableCell,
+    TableColumn(TableColumnFragmentInfo),
+    TableRow,
+    TableWrapper,
+    UnscannedText(UnscannedTextFragmentInfo),
 }
 
 impl SpecificFragmentInfo {
     fn restyle_damage(&self) -> RestyleDamage {
         let flow =
             match *self {
-                IframeFragment(_)
-                | ImageFragment(_)
-                | ScannedTextFragment(_)
-                | TableFragment
-                | TableCellFragment
-                | TableColumnFragment(_)
-                | TableRowFragment
-                | TableWrapperFragment
-                | UnscannedTextFragment(_)
-                | GenericFragment => return RestyleDamage::empty(),
-                InlineAbsoluteHypotheticalFragment(ref info) => &info.flow_ref,
-                InlineBlockFragment(ref info) => &info.flow_ref,
+                SpecificFragmentInfo::Iframe(_)
+                | SpecificFragmentInfo::Image(_)
+                | SpecificFragmentInfo::ScannedText(_)
+                | SpecificFragmentInfo::Table
+                | SpecificFragmentInfo::TableCell
+                | SpecificFragmentInfo::TableColumn(_)
+                | SpecificFragmentInfo::TableRow
+                | SpecificFragmentInfo::TableWrapper
+                | SpecificFragmentInfo::UnscannedText(_)
+                | SpecificFragmentInfo::Generic => return RestyleDamage::empty(),
+                SpecificFragmentInfo::InlineAbsoluteHypothetical(ref info) => &info.flow_ref,
+                SpecificFragmentInfo::InlineBlock(ref info) => &info.flow_ref,
             };
 
         flow::base(flow.deref()).restyle_damage
     }
 
     pub fn get_type(&self) -> &'static str {
         match *self {
-            GenericFragment => "GenericFragment",
-            IframeFragment(_) => "IframeFragment",
-            ImageFragment(_) => "ImageFragment",
-            InlineAbsoluteHypotheticalFragment(_) => "InlineAbsoluteHypotheticalFragment",
-            InlineBlockFragment(_) => "InlineBlockFragment",
-            ScannedTextFragment(_) => "ScannedTextFragment",
-            TableFragment => "TableFragment",
-            TableCellFragment => "TableCellFragment",
-            TableColumnFragment(_) => "TableColumnFragment",
-            TableRowFragment => "TableRowFragment",
-            TableWrapperFragment => "TableWrapperFragment",
-            UnscannedTextFragment(_) => "UnscannedTextFragment",
+            SpecificFragmentInfo::Generic => "SpecificFragmentInfo::Generic",
+            SpecificFragmentInfo::Iframe(_) => "SpecificFragmentInfo::Iframe",
+            SpecificFragmentInfo::Image(_) => "SpecificFragmentInfo::Image",
+            SpecificFragmentInfo::InlineAbsoluteHypothetical(_) => "SpecificFragmentInfo::InlineAbsoluteHypothetical",
+            SpecificFragmentInfo::InlineBlock(_) => "SpecificFragmentInfo::InlineBlock",
+            SpecificFragmentInfo::ScannedText(_) => "SpecificFragmentInfo::ScannedText",
+            SpecificFragmentInfo::Table => "SpecificFragmentInfo::Table",
+            SpecificFragmentInfo::TableCell => "SpecificFragmentInfo::TableCell",
+            SpecificFragmentInfo::TableColumn(_) => "SpecificFragmentInfo::TableColumn",
+            SpecificFragmentInfo::TableRow => "SpecificFragmentInfo::TableRow",
+            SpecificFragmentInfo::TableWrapper => "SpecificFragmentInfo::TableWrapper",
+            SpecificFragmentInfo::UnscannedText(_) => "SpecificFragmentInfo::UnscannedText",
         }
     }
 }
 
 /// 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
@@ -289,24 +289,24 @@ impl ImageFragmentInfo {
     // Return used value for inline-size or block-size.
     //
     // `dom_length`: inline-size or block-size as specified in the `img` tag.
     // `style_length`: inline-size as given in the CSS
     pub fn style_length(style_length: LengthOrPercentageOrAuto,
                         dom_length: Option<Au>,
                         container_inline_size: Au) -> MaybeAuto {
         match (MaybeAuto::from_style(style_length,container_inline_size),dom_length) {
-            (Specified(length),_) => {
-                Specified(length)
+            (MaybeAuto::Specified(length),_) => {
+                MaybeAuto::Specified(length)
             },
-            (Auto,Some(length)) => {
-                Specified(length)
+            (MaybeAuto::Auto,Some(length)) => {
+                MaybeAuto::Specified(length)
             },
-            (Auto,None) => {
-                Auto
+            (MaybeAuto::Auto,None) => {
+                MaybeAuto::Auto
             }
         }
     }
 
     /// Clamp a value obtained from style_length, based on min / max lengths.
     pub fn clamp_size(size: Au, min_size: LengthOrPercentage, max_size: LengthOrPercentageOrNone,
                         container_inline_size: Au) -> Au {
         let min_size = model::specified(min_size, container_inline_size);
@@ -526,17 +526,17 @@ impl Fragment {
                                         -> Fragment {
         // CSS 2.1 § 17.2.1 This is for non-inherited properties on anonymous table fragments
         // example:
         //
         //     <div style="display: table">
         //         Foo
         //     </div>
         //
-        // Anonymous table fragments, TableRowFragment and TableCellFragment, are generated around
+        // Anonymous table fragments, SpecificFragmentInfo::TableRow and SpecificFragmentInfo::TableCell, are generated around
         // `Foo`, but they shouldn't inherit the border.
 
         let node_style = cascade_anonymous(&**node.style());
         let writing_mode = node_style.writing_mode;
         Fragment {
             node: OpaqueNodeMethods::from_thread_safe_layout_node(node),
             style: Arc::new(node_style),
             restyle_damage: node.restyle_damage(),
@@ -569,32 +569,32 @@ impl Fragment {
         }
     }
 
     pub fn reset_inline_sizes(&mut self) {
         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 `ScannedTextFragment`. This will fail
+    /// 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 {
-            &ScannedTextFragment(ref mut info) => {
+            &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 {
-            &ScannedTextFragment(ref mut info) => {
+            &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
             }
             _ => {}
         }
@@ -618,17 +618,17 @@ impl Fragment {
 
         Fragment {
             node: self.node,
             style: self.style.clone(),
             restyle_damage: RestyleDamage::all(),
             border_box: new_border_box,
             border_padding: self.border_padding,
             margin: self.margin,
-            specific: ScannedTextFragment(info),
+            specific: SpecificFragmentInfo::ScannedText(info),
             inline_context: self.inline_context.clone(),
             debug_id: self.debug_id,
         }
     }
 
     pub fn restyle_damage(&self) -> RestyleDamage {
         self.restyle_damage | self.specific.restyle_damage()
     }
@@ -642,35 +642,35 @@ impl Fragment {
         self.inline_context.as_mut().unwrap().styles.push(style.clone());
     }
 
     /// Determines which quantities (border/padding/margin/specified) should be included in the
     /// intrinsic inline size of this fragment.
     fn quantities_included_in_intrinsic_inline_size(&self)
                                                     -> QuantitiesIncludedInIntrinsicInlineSizes {
         match self.specific {
-            GenericFragment | IframeFragment(_) | ImageFragment(_) | InlineBlockFragment(_) => {
+            SpecificFragmentInfo::Generic | SpecificFragmentInfo::Iframe(_) | SpecificFragmentInfo::Image(_) | SpecificFragmentInfo::InlineBlock(_) => {
                 QuantitiesIncludedInIntrinsicInlineSizes::all()
             }
-            TableFragment | TableCellFragment => {
+            SpecificFragmentInfo::Table | SpecificFragmentInfo::TableCell => {
                 INTRINSIC_INLINE_SIZE_INCLUDES_PADDING |
                     INTRINSIC_INLINE_SIZE_INCLUDES_BORDER |
                     INTRINSIC_INLINE_SIZE_INCLUDES_SPECIFIED
             }
-            TableWrapperFragment => {
+            SpecificFragmentInfo::TableWrapper => {
                 INTRINSIC_INLINE_SIZE_INCLUDES_MARGINS |
                     INTRINSIC_INLINE_SIZE_INCLUDES_BORDER |
                     INTRINSIC_INLINE_SIZE_INCLUDES_SPECIFIED
             }
-            TableRowFragment => {
+            SpecificFragmentInfo::TableRow => {
                 INTRINSIC_INLINE_SIZE_INCLUDES_BORDER |
                     INTRINSIC_INLINE_SIZE_INCLUDES_SPECIFIED
             }
-            ScannedTextFragment(_) | TableColumnFragment(_) | UnscannedTextFragment(_) |
-            InlineAbsoluteHypotheticalFragment(_) => {
+            SpecificFragmentInfo::ScannedText(_) | SpecificFragmentInfo::TableColumn(_) | SpecificFragmentInfo::UnscannedText(_) |
+            SpecificFragmentInfo::InlineAbsoluteHypothetical(_) => {
                 QuantitiesIncludedInIntrinsicInlineSizes::empty()
             }
         }
     }
 
     /// Returns the portion of the intrinsic inline-size that consists of borders, padding, and/or
     /// margins.
     ///
@@ -739,17 +739,17 @@ impl Fragment {
         text::line_height_from_style(&*self.style, &font_metrics)
     }
 
     /// Returns the sum of the inline-sizes of all the borders of this fragment. Note that this
     /// can be expensive to compute, so if possible use the `border_padding` field instead.
     #[inline]
     pub fn border_width(&self) -> LogicalMargin<Au> {
         let style_border_width = match self.specific {
-            ScannedTextFragment(_) => LogicalMargin::zero(self.style.writing_mode),
+            SpecificFragmentInfo::ScannedText(_) => LogicalMargin::zero(self.style.writing_mode),
             _ => self.style().logical_border_width(),
         };
 
         match self.inline_context {
             None => style_border_width,
             Some(ref inline_fragment_context) => {
                 inline_fragment_context.styles.iter().fold(style_border_width,
                                             |acc, style| acc + style.logical_border_width())
@@ -759,17 +759,17 @@ impl Fragment {
 
     /// Computes the margins in the inline direction from the containing block inline-size and the
     /// style. After this call, the inline direction of the `margin` field will be correct.
     ///
     /// Do not use this method if the inline direction margins are to be computed some other way
     /// (for example, via constraint solving for blocks).
     pub fn compute_inline_direction_margins(&mut self, containing_block_inline_size: Au) {
         match self.specific {
-            TableFragment | TableCellFragment | TableRowFragment | TableColumnFragment(_) => {
+            SpecificFragmentInfo::Table | SpecificFragmentInfo::TableCell | SpecificFragmentInfo::TableRow | SpecificFragmentInfo::TableColumn(_) => {
                 self.margin.inline_start = Au(0);
                 self.margin.inline_end = Au(0)
             }
             _ => {
                 let margin = self.style().logical_margin();
                 self.margin.inline_start =
                     MaybeAuto::from_style(margin.inline_start, containing_block_inline_size)
                     .specified_or_zero();
@@ -782,17 +782,17 @@ impl Fragment {
 
     /// Computes the margins in the block direction from the containing block inline-size and the
     /// style. After this call, the block direction of the `margin` field will be correct.
     ///
     /// Do not use this method if the block direction margins are to be computed some other way
     /// (for example, via constraint solving for absolutely-positioned flows).
     pub fn compute_block_direction_margins(&mut self, containing_block_inline_size: Au) {
         match self.specific {
-            TableFragment | TableCellFragment | TableRowFragment | TableColumnFragment(_) => {
+            SpecificFragmentInfo::Table | SpecificFragmentInfo::TableCell | SpecificFragmentInfo::TableRow | SpecificFragmentInfo::TableColumn(_) => {
                 self.margin.block_start = Au(0);
                 self.margin.block_end = Au(0)
             }
             _ => {
                 // NB: Percentages are relative to containing block inline-size (not block-size)
                 // per CSS 2.1.
                 let margin = self.style().logical_margin();
                 self.margin.block_start =
@@ -809,21 +809,21 @@ impl Fragment {
     /// block inline-size and the style. After this call, the `border_padding` field will be
     /// correct.
     pub fn compute_border_and_padding(&mut self, containing_block_inline_size: Au) {
         // Compute border.
         let border = self.border_width();
 
         // Compute padding.
         let padding = match self.specific {
-            TableColumnFragment(_) | TableRowFragment |
-            TableWrapperFragment => LogicalMargin::zero(self.style.writing_mode),
+            SpecificFragmentInfo::TableColumn(_) | SpecificFragmentInfo::TableRow |
+            SpecificFragmentInfo::TableWrapper => LogicalMargin::zero(self.style.writing_mode),
             _ => {
                 let style_padding = match self.specific {
-                    ScannedTextFragment(_) => LogicalMargin::zero(self.style.writing_mode),
+                    SpecificFragmentInfo::ScannedText(_) => LogicalMargin::zero(self.style.writing_mode),
                     _ => model::padding_from_style(self.style(), containing_block_inline_size),
                 };
 
                 match self.inline_context {
                     None => style_padding,
                     Some(ref inline_fragment_context) => {
                         inline_fragment_context.styles.iter().fold(style_padding,
                                 |acc, style| acc + model::padding_from_style(&**style, Au(0)))
@@ -837,22 +837,22 @@ impl Fragment {
 
     // Return offset from original position because of `position: relative`.
     pub fn relative_position(&self,
                              containing_block_size: &LogicalSize<Au>)
                              -> LogicalSize<Au> {
         fn from_style(style: &ComputedValues, container_size: &LogicalSize<Au>)
                       -> LogicalSize<Au> {
             let offsets = style.logical_position();
-            let offset_i = if offsets.inline_start != LPA_Auto {
+            let offset_i = if offsets.inline_start != LengthOrPercentageOrAuto::Auto {
                 MaybeAuto::from_style(offsets.inline_start, container_size.inline).specified_or_zero()
             } else {
                 -MaybeAuto::from_style(offsets.inline_end, container_size.inline).specified_or_zero()
             };
-            let offset_b = if offsets.block_start != LPA_Auto {
+            let offset_b = if offsets.block_start != LengthOrPercentageOrAuto::Auto {
                 MaybeAuto::from_style(offsets.block_start, container_size.inline).specified_or_zero()
             } else {
                 -MaybeAuto::from_style(offsets.block_end, container_size.inline).specified_or_zero()
             };
             LogicalSize::new(style.writing_mode, offset_i, offset_b)
         }
 
         // Go over the ancestor fragments and add all relative offsets (if any).
@@ -878,19 +878,19 @@ impl Fragment {
     /// Always inline for SCCP.
     ///
     /// FIXME(pcwalton): Just replace with the clear type from the style module for speed?
     #[inline(always)]
     pub fn clear(&self) -> Option<ClearType> {
         let style = self.style();
         match style.get_box().clear {
             clear::none => None,
-            clear::left => Some(ClearLeft),
-            clear::right => Some(ClearRight),
-            clear::both => Some(ClearBoth),
+            clear::left => Some(ClearType::Left),
+            clear::right => Some(ClearType::Right),
+            clear::both => Some(ClearType::Both),
         }
     }
 
     #[inline(always)]
     pub fn style<'a>(&'a self) -> &'a ComputedValues {
         &*self.style
     }
 
@@ -920,86 +920,86 @@ impl Fragment {
     }
 
     /// Returns the inline-start offset from margin edge to content edge.
     ///
     /// FIXME(#2262, pcwalton): I think this method is pretty bogus, because it won't work for
     /// inlines.
     pub fn inline_start_offset(&self) -> Au {
         match self.specific {
-            TableWrapperFragment => self.margin.inline_start,
-            TableFragment | TableCellFragment | TableRowFragment => self.border_padding.inline_start,
-            TableColumnFragment(_) => Au(0),
+            SpecificFragmentInfo::TableWrapper => self.margin.inline_start,
+            SpecificFragmentInfo::Table | SpecificFragmentInfo::TableCell | SpecificFragmentInfo::TableRow => self.border_padding.inline_start,
+            SpecificFragmentInfo::TableColumn(_) => Au(0),
             _ => self.margin.inline_start + self.border_padding.inline_start,
         }
     }
 
     /// Returns true if this element can be split. This is true for text fragments.
     pub fn can_split(&self) -> bool {
         self.is_scanned_text_fragment()
     }
 
     /// Returns the newline positions of this fragment, if it's a scanned text fragment.
     pub fn newline_positions(&self) -> Option<&Vec<CharIndex>> {
         match self.specific {
-            ScannedTextFragment(ref info) => Some(&info.new_line_pos),
+            SpecificFragmentInfo::ScannedText(ref info) => Some(&info.new_line_pos),
             _ => None,
         }
     }
 
     /// Returns the newline positions of this fragment, if it's a scanned text fragment.
     pub fn newline_positions_mut(&mut self) -> Option<&mut Vec<CharIndex>> {
         match self.specific {
-            ScannedTextFragment(ref mut info) => Some(&mut info.new_line_pos),
+            SpecificFragmentInfo::ScannedText(ref mut info) => Some(&mut info.new_line_pos),
             _ => None,
         }
     }
 
     /// Returns true if and only if this is a scanned text fragment.
     fn is_scanned_text_fragment(&self) -> bool {
         match self.specific {
-            ScannedTextFragment(..) => true,
+            SpecificFragmentInfo::ScannedText(..) => true,
             _ => false,
         }
     }
 
     /// Computes the intrinsic inline-sizes of this fragment.
     pub fn compute_intrinsic_inline_sizes(&mut self) -> IntrinsicISizesContribution {
         let mut result = self.style_specified_intrinsic_inline_size();
         match self.specific {
-            GenericFragment | IframeFragment(_) | TableFragment | TableCellFragment |
-            TableColumnFragment(_) | TableRowFragment | TableWrapperFragment |
-            InlineAbsoluteHypotheticalFragment(_) => {}
-            InlineBlockFragment(ref mut info) => {
+            SpecificFragmentInfo::Generic | SpecificFragmentInfo::Iframe(_) | SpecificFragmentInfo::Table | SpecificFragmentInfo::TableCell |
+            SpecificFragmentInfo::TableColumn(_) | SpecificFragmentInfo::TableRow | SpecificFragmentInfo::TableWrapper |
+            SpecificFragmentInfo::InlineAbsoluteHypothetical(_) => {}
+            SpecificFragmentInfo::InlineBlock(ref mut info) => {
                 let block_flow = info.flow_ref.as_block();
                 result.union_block(&block_flow.base.intrinsic_inline_sizes)
             }
-            ImageFragment(ref mut image_fragment_info) => {
+            SpecificFragmentInfo::Image(ref mut image_fragment_info) => {
                 let image_inline_size = image_fragment_info.image_inline_size();
                 result.union_block(&IntrinsicISizes {
                     minimum_inline_size: image_inline_size,
                     preferred_inline_size: image_inline_size,
                 })
             }
-            ScannedTextFragment(ref text_fragment_info) => {
+            SpecificFragmentInfo::ScannedText(ref text_fragment_info) => {
                 let range = &text_fragment_info.range;
                 let min_line_inline_size = text_fragment_info.run.min_width_for_range(range);
 
                 // See http://dev.w3.org/csswg/css-sizing/#max-content-inline-size.
                 // TODO: Account for soft wrap opportunities.
                 let max_line_inline_size = text_fragment_info.run
                                                              .metrics_for_range(range)
                                                              .advance_width;
 
                 result.union_block(&IntrinsicISizes {
                     minimum_inline_size: min_line_inline_size,
                     preferred_inline_size: max_line_inline_size,
                 })
             }
-            UnscannedTextFragment(..) => {
+            SpecificFragmentInfo::UnscannedText(..) => {
                 panic!("Unscanned text fragments should have been scanned by now!")
             }
         };
 
         // Take borders and padding for parent inline fragments into account, if necessary.
         if self.is_primary_fragment() {
             match self.inline_context {
                 None => {}
@@ -1014,50 +1014,50 @@ impl Fragment {
                 }
             }
         }
 
         result
     }
 
 
-    /// TODO: What exactly does this function return? Why is it Au(0) for GenericFragment?
+    /// TODO: What exactly does this function return? Why is it Au(0) for SpecificFragmentInfo::Generic?
     pub fn content_inline_size(&self) -> Au {
         match self.specific {
-            GenericFragment | IframeFragment(_) | TableFragment | TableCellFragment |
-            TableRowFragment | TableWrapperFragment | InlineBlockFragment(_) |
-            InlineAbsoluteHypotheticalFragment(_) => Au(0),
-            ImageFragment(ref image_fragment_info) => {
+            SpecificFragmentInfo::Generic | SpecificFragmentInfo::Iframe(_) | SpecificFragmentInfo::Table | SpecificFragmentInfo::TableCell |
+            SpecificFragmentInfo::TableRow | SpecificFragmentInfo::TableWrapper | SpecificFragmentInfo::InlineBlock(_) |
+            SpecificFragmentInfo::InlineAbsoluteHypothetical(_) => Au(0),
+            SpecificFragmentInfo::Image(ref image_fragment_info) => {
                 image_fragment_info.computed_inline_size()
             }
-            ScannedTextFragment(ref text_fragment_info) => {
+            SpecificFragmentInfo::ScannedText(ref text_fragment_info) => {
                 let (range, run) = (&text_fragment_info.range, &text_fragment_info.run);
                 let text_bounds = run.metrics_for_range(range).bounding_box;
                 text_bounds.size.width
             }
-            TableColumnFragment(_) => panic!("Table column fragments do not have inline_size"),
-            UnscannedTextFragment(_) => panic!("Unscanned text fragments should have been scanned by now!"),
+            SpecificFragmentInfo::TableColumn(_) => panic!("Table column fragments do not have inline_size"),
+            SpecificFragmentInfo::UnscannedText(_) => panic!("Unscanned text fragments should have been scanned by now!"),
         }
     }
 
     /// Returns, and computes, the block-size of this fragment.
     pub fn content_block_size(&self, layout_context: &LayoutContext) -> Au {
         match self.specific {
-            GenericFragment | IframeFragment(_) | TableFragment | TableCellFragment |
-            TableRowFragment | TableWrapperFragment | InlineBlockFragment(_) |
-            InlineAbsoluteHypotheticalFragment(_) => Au(0),
-            ImageFragment(ref image_fragment_info) => {
+            SpecificFragmentInfo::Generic | SpecificFragmentInfo::Iframe(_) | SpecificFragmentInfo::Table | SpecificFragmentInfo::TableCell |
+            SpecificFragmentInfo::TableRow | SpecificFragmentInfo::TableWrapper | SpecificFragmentInfo::InlineBlock(_) |
+            SpecificFragmentInfo::InlineAbsoluteHypothetical(_) => Au(0),
+            SpecificFragmentInfo::Image(ref image_fragment_info) => {
                 image_fragment_info.computed_block_size()
             }
-            ScannedTextFragment(_) => {
+            SpecificFragmentInfo::ScannedText(_) => {
                 // Compute the block-size based on the line-block-size and font size.
                 self.calculate_line_height(layout_context)
             }
-            TableColumnFragment(_) => panic!("Table column fragments do not have block_size"),
-            UnscannedTextFragment(_) => panic!("Unscanned text fragments should have been scanned by now!"),
+            SpecificFragmentInfo::TableColumn(_) => panic!("Table column fragments do not have block_size"),
+            SpecificFragmentInfo::UnscannedText(_) => panic!("Unscanned text fragments should have been scanned by now!"),
         }
     }
 
     /// Returns the dimensions of the content box.
     ///
     /// This is marked `#[inline]` because it is frequently called when only one or two of the
     /// values are needed and that will save computation.
     #[inline]
@@ -1071,24 +1071,24 @@ impl Fragment {
     /// Otherwise the split information is returned. The right information is
     /// optional due to the possibility of it being whitespace.
     //
     // TODO(bjz): The text run should be removed in the future, but it is currently needed for
     // the current method of fragment splitting in the `inline::try_append_*` functions.
     pub fn find_split_info_by_new_line(&self)
             -> Option<(SplitInfo, Option<SplitInfo>, Arc<Box<TextRun>> /* TODO(bjz): remove */)> {
         match self.specific {
-            GenericFragment | IframeFragment(_) | ImageFragment(_) | TableFragment | TableCellFragment |
-            TableRowFragment | TableWrapperFragment => None,
-            TableColumnFragment(_) => panic!("Table column fragments do not need to split"),
-            UnscannedTextFragment(_) => panic!("Unscanned text fragments should have been scanned by now!"),
-            InlineBlockFragment(_) | InlineAbsoluteHypotheticalFragment(_) => {
+            SpecificFragmentInfo::Generic | SpecificFragmentInfo::Iframe(_) | SpecificFragmentInfo::Image(_) | SpecificFragmentInfo::Table | SpecificFragmentInfo::TableCell |
+            SpecificFragmentInfo::TableRow | SpecificFragmentInfo::TableWrapper => None,
+            SpecificFragmentInfo::TableColumn(_) => panic!("Table column fragments do not need to split"),
+            SpecificFragmentInfo::UnscannedText(_) => 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")
             }
-            ScannedTextFragment(ref text_fragment_info) => {
+            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 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)));
@@ -1113,24 +1113,24 @@ impl Fragment {
     /// than `max_inline_size`.
     ///
     /// A return value of `None` indicates that the fragment could not be split. Otherwise the
     /// information pertaining to the split is returned. The inline-start and inline-end split
     /// information are both optional due to the possibility of them being whitespace.
     pub fn calculate_split_position(&self, max_inline_size: Au, starts_line: bool)
                                     -> Option<SplitResult> {
         let text_fragment_info = match self.specific {
-            GenericFragment | IframeFragment(_) | ImageFragment(_) | TableFragment |
-            TableCellFragment | TableRowFragment | TableWrapperFragment | InlineBlockFragment(_) |
-            InlineAbsoluteHypotheticalFragment(_) => return None,
-            TableColumnFragment(_) => panic!("Table column fragments do not have inline_size"),
-            UnscannedTextFragment(_) => {
+            SpecificFragmentInfo::Generic | SpecificFragmentInfo::Iframe(_) | SpecificFragmentInfo::Image(_) | SpecificFragmentInfo::Table |
+            SpecificFragmentInfo::TableCell | SpecificFragmentInfo::TableRow | SpecificFragmentInfo::TableWrapper | SpecificFragmentInfo::InlineBlock(_) |
+            SpecificFragmentInfo::InlineAbsoluteHypothetical(_) => return None,
+            SpecificFragmentInfo::TableColumn(_) => panic!("Table column fragments do not have inline_size"),
+            SpecificFragmentInfo::UnscannedText(_) => {
                 panic!("Unscanned text fragments should have been scanned by now!")
             }
-            ScannedTextFragment(ref text_fragment_info) => text_fragment_info,
+            SpecificFragmentInfo::ScannedText(ref text_fragment_info) => text_fragment_info,
         };
 
         let mut flags = SplitOptions::empty();
         if starts_line {
             flags.insert(STARTS_LINE);
             if self.style().get_inheritedtext().overflow_wrap == overflow_wrap::break_word {
                 flags.insert(RETRY_AT_CHARACTER_BOUNDARIES)
             }
@@ -1147,24 +1147,24 @@ impl Fragment {
     /// 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>> {
         let text_fragment_info = match self.specific {
-            GenericFragment | IframeFragment(_) | ImageFragment(_) | TableFragment |
-            TableCellFragment | TableRowFragment | TableWrapperFragment | InlineBlockFragment(_) |
-            InlineAbsoluteHypotheticalFragment(_) => return None,
-            TableColumnFragment(_) => panic!("Table column fragments do not have inline_size"),
-            UnscannedTextFragment(_) => {
+            SpecificFragmentInfo::Generic | SpecificFragmentInfo::Iframe(_) | SpecificFragmentInfo::Image(_) | SpecificFragmentInfo::Table |
+            SpecificFragmentInfo::TableCell | SpecificFragmentInfo::TableRow | SpecificFragmentInfo::TableWrapper | SpecificFragmentInfo::InlineBlock(_) |
+            SpecificFragmentInfo::InlineAbsoluteHypothetical(_) => return None,
+            SpecificFragmentInfo::TableColumn(_) => panic!("Table column fragments do not have inline_size"),
+            SpecificFragmentInfo::UnscannedText(_) => {
                 panic!("Unscanned text fragments should have been scanned by now!")
             }
-            ScannedTextFragment(ref text_fragment_info) => text_fragment_info,
+            SpecificFragmentInfo::ScannedText(ref text_fragment_info) => text_fragment_info,
         };
 
         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={}, \
@@ -1257,100 +1257,100 @@ impl Fragment {
     /// Returns true if this fragment is an unscanned text fragment that consists entirely of
     /// whitespace that should be stripped.
     pub fn is_ignorable_whitespace(&self) -> bool {
         match self.white_space() {
             white_space::pre => return false,
             white_space::normal | white_space::nowrap => {}
         }
         match self.specific {
-            UnscannedTextFragment(ref text_fragment_info) => {
+            SpecificFragmentInfo::UnscannedText(ref text_fragment_info) => {
                 is_whitespace(text_fragment_info.text.as_slice())
             }
             _ => false,
         }
     }
 
     /// Assigns replaced inline-size, padding, and margins for this fragment only if it is replaced
     /// content per CSS 2.1 § 10.3.2.
     pub fn assign_replaced_inline_size_if_necessary(&mut self, container_inline_size: Au) {
         match self.specific {
-            GenericFragment | IframeFragment(_) | TableFragment | TableCellFragment |
-            TableRowFragment | TableWrapperFragment => return,
-            TableColumnFragment(_) => panic!("Table column fragments do not have inline_size"),
-            UnscannedTextFragment(_) => {
+            SpecificFragmentInfo::Generic | SpecificFragmentInfo::Iframe(_) | SpecificFragmentInfo::Table | SpecificFragmentInfo::TableCell |
+            SpecificFragmentInfo::TableRow | SpecificFragmentInfo::TableWrapper => return,
+            SpecificFragmentInfo::TableColumn(_) => panic!("Table column fragments do not have inline_size"),
+            SpecificFragmentInfo::UnscannedText(_) => {
                 panic!("Unscanned text fragments should have been scanned by now!")
             }
-            ImageFragment(_) | ScannedTextFragment(_) | InlineBlockFragment(_) |
-            InlineAbsoluteHypotheticalFragment(_) => {}
+            SpecificFragmentInfo::Image(_) | SpecificFragmentInfo::ScannedText(_) | SpecificFragmentInfo::InlineBlock(_) |
+            SpecificFragmentInfo::InlineAbsoluteHypothetical(_) => {}
         };
 
         let style_inline_size = self.style().content_inline_size();
         let style_block_size = self.style().content_block_size();
         let style_min_inline_size = self.style().min_inline_size();
         let style_max_inline_size = self.style().max_inline_size();
         let style_min_block_size = self.style().min_block_size();
         let style_max_block_size = self.style().max_block_size();
         let noncontent_inline_size = self.border_padding.inline_start_end();
 
         match self.specific {
-            InlineAbsoluteHypotheticalFragment(ref mut info) => {
+            SpecificFragmentInfo::InlineAbsoluteHypothetical(ref mut info) => {
                 let block_flow = info.flow_ref.as_block();
                 block_flow.base.position.size.inline =
                     block_flow.base.intrinsic_inline_sizes.preferred_inline_size;
 
                 // This is a hypothetical box, so it takes up no space.
                 self.border_box.size.inline = Au(0);
             }
-            InlineBlockFragment(ref mut info) => {
+            SpecificFragmentInfo::InlineBlock(ref mut info) => {
                 let block_flow = info.flow_ref.as_block();
                 self.border_box.size.inline =
                     block_flow.base.intrinsic_inline_sizes.preferred_inline_size;
                 block_flow.base.block_container_inline_size = self.border_box.size.inline;
             }
-            ScannedTextFragment(ref info) => {
+            SpecificFragmentInfo::ScannedText(ref info) => {
                 // Scanned text fragments will have already had their content inline-sizes assigned
                 // by this point.
                 self.border_box.size.inline = info.content_size.inline + noncontent_inline_size
             }
-            ImageFragment(ref mut image_fragment_info) => {
+            SpecificFragmentInfo::Image(ref mut image_fragment_info) => {
                 // TODO(ksh8281): compute border,margin
                 let inline_size = ImageFragmentInfo::style_length(
                     style_inline_size,
                     image_fragment_info.dom_inline_size,
                     container_inline_size);
 
                 let inline_size = match inline_size {
-                    Auto => {
+                    MaybeAuto::Auto => {
                         let intrinsic_width = image_fragment_info.image_inline_size();
                         let intrinsic_height = image_fragment_info.image_block_size();
 
                         if intrinsic_height == Au(0) {
                             intrinsic_width
                         } else {
                             let ratio = intrinsic_width.to_f32().unwrap() /
                                         intrinsic_height.to_f32().unwrap();
 
                             let specified_height = ImageFragmentInfo::style_length(
                                 style_block_size,
                                 image_fragment_info.dom_block_size,
                                 Au(0));
                             let specified_height = match specified_height {
-                                Auto => intrinsic_height,
-                                Specified(h) => h,
+                                MaybeAuto::Auto => intrinsic_height,
+                                MaybeAuto::Specified(h) => h,
                             };
                             let specified_height = ImageFragmentInfo::clamp_size(
                                 specified_height,
                                 style_min_block_size,
                                 style_max_block_size,
                                 Au(0));
                             Au((specified_height.to_f32().unwrap() * ratio) as i32)
                         }
                     },
-                    Specified(w) => w,
+                    MaybeAuto::Specified(w) => w,
                 };
 
                 let inline_size = ImageFragmentInfo::clamp_size(inline_size,
                                                                 style_min_inline_size,
                                                                 style_max_inline_size,
                                                                 container_inline_size);
 
                 self.border_box.size.inline = inline_size + noncontent_inline_size;
@@ -1361,107 +1361,107 @@ impl Fragment {
     }
 
     /// Assign block-size for this fragment if it is replaced content. The inline-size must have
     /// been assigned first.
     ///
     /// Ideally, this should follow CSS 2.1 § 10.6.2.
     pub fn assign_replaced_block_size_if_necessary(&mut self, containing_block_block_size: Au) {
         match self.specific {
-            GenericFragment | IframeFragment(_) | TableFragment | TableCellFragment |
-            TableRowFragment | TableWrapperFragment => return,
-            TableColumnFragment(_) => panic!("Table column fragments do not have block_size"),
-            UnscannedTextFragment(_) => {
+            SpecificFragmentInfo::Generic | SpecificFragmentInfo::Iframe(_) | SpecificFragmentInfo::Table | SpecificFragmentInfo::TableCell |
+            SpecificFragmentInfo::TableRow | SpecificFragmentInfo::TableWrapper => return,
+            SpecificFragmentInfo::TableColumn(_) => panic!("Table column fragments do not have block_size"),
+            SpecificFragmentInfo::UnscannedText(_) => {
                 panic!("Unscanned text fragments should have been scanned by now!")
             }
-            ImageFragment(_) | ScannedTextFragment(_) | InlineBlockFragment(_) |
-            InlineAbsoluteHypotheticalFragment(_) => {}
+            SpecificFragmentInfo::Image(_) | SpecificFragmentInfo::ScannedText(_) | SpecificFragmentInfo::InlineBlock(_) |
+            SpecificFragmentInfo::InlineAbsoluteHypothetical(_) => {}
         }
 
         let style_block_size = self.style().content_block_size();
         let style_min_block_size = self.style().min_block_size();
         let style_max_block_size = self.style().max_block_size();
         let noncontent_block_size = self.border_padding.block_start_end();
 
         match self.specific {
-            ImageFragment(ref mut image_fragment_info) => {
+            SpecificFragmentInfo::Image(ref mut image_fragment_info) => {
                 // TODO(ksh8281): compute border,margin,padding
                 let inline_size = image_fragment_info.computed_inline_size();
                 let block_size = ImageFragmentInfo::style_length(
                     style_block_size,
                     image_fragment_info.dom_block_size,
                     containing_block_block_size);
 
                 let block_size = match block_size {
-                    Auto => {
+                    MaybeAuto::Auto => {
                         let scale = image_fragment_info.image_inline_size().to_f32().unwrap()
                             / inline_size.to_f32().unwrap();
                         Au((image_fragment_info.image_block_size().to_f32().unwrap() / scale)
                            as i32)
                     },
-                    Specified(h) => {
+                    MaybeAuto::Specified(h) => {
                         h
                     }
                 };
 
                 let block_size = ImageFragmentInfo::clamp_size(block_size, style_min_block_size,
                                                                style_max_block_size,
                                                                Au(0));
 
                 image_fragment_info.computed_block_size = Some(block_size);
                 self.border_box.size.block = block_size + noncontent_block_size
             }
-            ScannedTextFragment(ref info) => {
+            SpecificFragmentInfo::ScannedText(ref info) => {
                 // Scanned text fragments' content block-sizes are calculated by the text run
                 // scanner during flow construction.
                 self.border_box.size.block = info.content_size.block + noncontent_block_size
             }
-            InlineBlockFragment(ref mut info) => {
+            SpecificFragmentInfo::InlineBlock(ref mut info) => {
                 // Not the primary fragment, so we do not take the noncontent size into account.
                 let block_flow = info.flow_ref.as_block();
                 self.border_box.size.block = block_flow.base.position.size.block +
                     block_flow.fragment.margin.block_start_end()
             }
-            InlineAbsoluteHypotheticalFragment(ref mut info) => {
+            SpecificFragmentInfo::InlineAbsoluteHypothetical(ref mut info) => {
                 // Not the primary fragment, so we do not take the noncontent size into account.
                 let block_flow = info.flow_ref.as_block();
                 self.border_box.size.block = block_flow.base.position.size.block;
             }
             _ => panic!("should have been handled above"),
         }
     }
 
     /// Calculates block-size above baseline, depth below baseline, and ascent for this fragment when
     /// used in an inline formatting context. See CSS 2.1 § 10.8.1.
     pub fn inline_metrics(&self, layout_context: &LayoutContext) -> InlineMetrics {
         match self.specific {
-            ImageFragment(ref image_fragment_info) => {
+            SpecificFragmentInfo::Image(ref image_fragment_info) => {
                 let computed_block_size = image_fragment_info.computed_block_size();
                 InlineMetrics {
                     block_size_above_baseline: computed_block_size + self.border_padding.block_start_end(),
                     depth_below_baseline: Au(0),
                     ascent: computed_block_size + self.border_padding.block_end,
                 }
             }
-            ScannedTextFragment(ref text_fragment) => {
+            SpecificFragmentInfo::ScannedText(ref text_fragment) => {
                 // See CSS 2.1 § 10.8.1.
                 let line_height = self.calculate_line_height(layout_context);
                 InlineMetrics::from_font_metrics(&text_fragment.run.font_metrics, line_height)
             }
-            InlineBlockFragment(ref info) => {
+            SpecificFragmentInfo::InlineBlock(ref info) => {
                 // See CSS 2.1 § 10.8.1.
                 let block_flow = info.flow_ref.deref().as_immutable_block();
                 let font_style = self.style.get_font_arc();
                 let font_metrics = text::font_metrics_for_style(layout_context.font_context(),
                                                                 font_style);
                 InlineMetrics::from_block_height(&font_metrics,
                                                  block_flow.base.position.size.block +
                                                  block_flow.fragment.margin.block_start_end())
             }
-            InlineAbsoluteHypotheticalFragment(_) => {
+            SpecificFragmentInfo::InlineAbsoluteHypothetical(_) => {
                 // Hypothetical boxes take up no space.
                 InlineMetrics {
                     block_size_above_baseline: Au(0),
                     depth_below_baseline: Au(0),
                     ascent: Au(0),
                 }
             }
             _ => {
@@ -1472,25 +1472,25 @@ impl Fragment {
                 }
             }
         }
     }
 
     /// Returns true if this fragment is a hypothetical box. See CSS 2.1 § 10.3.7.
     pub fn is_hypothetical(&self) -> bool {
         match self.specific {
-            InlineAbsoluteHypotheticalFragment(_) => true,
+            SpecificFragmentInfo::InlineAbsoluteHypothetical(_) => true,
             _ => false,
         }
     }
 
     /// Returns true if this fragment can merge with another adjacent fragment or false otherwise.
     pub fn can_merge_with_fragment(&self, other: &Fragment) -> bool {
         match (&self.specific, &other.specific) {
-            (&UnscannedTextFragment(_), &UnscannedTextFragment(_)) => {
+            (&SpecificFragmentInfo::UnscannedText(_), &SpecificFragmentInfo::UnscannedText(_)) => {
                 // FIXME: Should probably use a whitelist of styles that can safely differ (#3165)
                 self.style().get_font() == other.style().get_font() &&
                     self.text_decoration() == other.text_decoration() &&
                     self.white_space() == other.white_space()
             }
             _ => false,
         }
     }
@@ -1501,37 +1501,37 @@ impl Fragment {
     /// margins into account. Every style object has at most one primary fragment.
     ///
     /// At present, all fragments are primary fragments except for inline-block and table wrapper
     /// fragments. Inline-block fragments are not primary fragments because the corresponding block
     /// flow is the primary fragment, while table wrapper fragments are not primary fragments
     /// because the corresponding table flow is the primary fragment.
     pub fn is_primary_fragment(&self) -> bool {
         match self.specific {
-            InlineBlockFragment(_) | InlineAbsoluteHypotheticalFragment(_) |
-            TableWrapperFragment => false,
-            GenericFragment | IframeFragment(_) | ImageFragment(_) | ScannedTextFragment(_) |
-            TableFragment | TableCellFragment | TableColumnFragment(_) | TableRowFragment |
-            UnscannedTextFragment(_) => true,
+            SpecificFragmentInfo::InlineBlock(_) | SpecificFragmentInfo::InlineAbsoluteHypothetical(_) |
+            SpecificFragmentInfo::TableWrapper => false,
+            SpecificFragmentInfo::Generic | SpecificFragmentInfo::Iframe(_) | SpecificFragmentInfo::Image(_) | SpecificFragmentInfo::ScannedText(_) |
+            SpecificFragmentInfo::Table | SpecificFragmentInfo::TableCell | SpecificFragmentInfo::TableColumn(_) | SpecificFragmentInfo::TableRow |
+            SpecificFragmentInfo::UnscannedText(_) => true,
         }
     }
 
     pub fn update_late_computed_inline_position_if_necessary(&mut self) {
         match self.specific {
-            InlineAbsoluteHypotheticalFragment(ref mut info) => {
+            SpecificFragmentInfo::InlineAbsoluteHypothetical(ref mut info) => {
                 let position = self.border_box.start.i;
                 info.flow_ref.update_late_computed_inline_position_if_necessary(position)
             }
             _ => {}
         }
     }
 
     pub fn update_late_computed_block_position_if_necessary(&mut self) {
         match self.specific {
-            InlineAbsoluteHypotheticalFragment(ref mut info) => {
+            SpecificFragmentInfo::InlineAbsoluteHypothetical(ref mut info) => {
                 let position = self.border_box.start.b;
                 info.flow_ref.update_late_computed_block_position_if_necessary(position)
             }
             _ => {}
         }
     }
 
     pub fn repair_style(&mut self, new_style: &Arc<ComputedValues>) {
--- a/servo/components/layout/inline.rs
+++ b/servo/components/layout/inline.rs
@@ -1,23 +1,23 @@
 /* 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/. */
 
 #![deny(unsafe_blocks)]
 
 use css::node_style::StyledNode;
 use context::LayoutContext;
-use display_list_builder::{ContentLevel, DisplayListResult, FragmentDisplayListBuilding};
-use floats::{FloatLeft, Floats, PlacementInfo};
-use flow::{BaseFlow, FlowClass, Flow, ForceNonfloated, InlineFlowClass, MutableFlowUtils};
+use display_list_builder::{BackgroundAndBorderLevel, DisplayListBuildingResult, FragmentDisplayListBuilding};
+use floats::{FloatKind, Floats, PlacementInfo};
+use flow::{BaseFlow, FlowClass, Flow, MutableFlowUtils, ForceNonfloatedFlag};
 use flow::{IS_ABSOLUTELY_POSITIONED};
 use flow;
-use fragment::{Fragment, InlineAbsoluteHypotheticalFragment, InlineBlockFragment};
-use fragment::{FragmentBoundsIterator, ScannedTextFragment, ScannedTextFragmentInfo};
+use fragment::{Fragment, SpecificFragmentInfo};
+use fragment::{FragmentBoundsIterator, ScannedTextFragmentInfo};
 use fragment::SplitInfo;
 use incremental::{REFLOW, REFLOW_OUT_OF_FLOW};
 use layout_debug;
 use model::IntrinsicISizesContribution;
 use text;
 
 use collections::{RingBuf};
 use geom::Size2D;
@@ -340,18 +340,18 @@ impl LineBreaker {
             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) {
-                (&ScannedTextFragment(ref mut result_info),
-                 &ScannedTextFragment(ref candidate_info))
+                (&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,
             };
@@ -407,17 +407,17 @@ impl LineBreaker {
 
         // Try to place the fragment between floats.
         let line_bounds = self.floats.place_between_floats(&PlacementInfo {
             size: LogicalSize::new(self.floats.writing_mode,
                                    placement_inline_size,
                                    first_fragment.border_box.size.block),
             ceiling: ceiling,
             max_inline_size: flow.base.position.size.inline,
-            kind: FloatLeft,
+            kind: FloatKind::Left,
         });
 
         // Simple case: if the fragment fits, then we can stop here.
         if line_bounds.size.inline > first_fragment.border_box.size.inline {
             debug!("LineBreaker: fragment fits on line {}", self.lines.len());
             return (line_bounds, first_fragment.border_box.size.inline);
         }
 
@@ -739,17 +739,17 @@ pub struct InlineFlow {
     /// (because percentages are relative to the containing block, and we aren't in a position to
     /// compute things relative to our parent's containing block).
     pub first_line_indentation: Au,
 }
 
 impl InlineFlow {
     pub fn from_fragments(fragments: InlineFragments, writing_mode: WritingMode) -> InlineFlow {
         InlineFlow {
-            base: BaseFlow::new(None, writing_mode, ForceNonfloated),
+            base: BaseFlow::new(None, writing_mode, ForceNonfloatedFlag::ForceNonfloated),
             fragments: fragments,
             lines: Vec::new(),
             minimum_block_size_above_baseline: Au(0),
             minimum_depth_below_baseline: Au(0),
             first_line_indentation: Au(0),
         }
     }
 
@@ -941,17 +941,17 @@ impl InlineFlow {
         }
 
         self.base.restyle_damage = damage;
     }
 }
 
 impl Flow for InlineFlow {
     fn class(&self) -> FlowClass {
-        InlineFlowClass
+        FlowClass::Inline
     }
 
     fn as_immutable_inline<'a>(&'a self) -> &'a InlineFlow {
         self
     }
 
     fn as_inline<'a>(&'a mut self) -> &'a mut InlineFlow {
         self
@@ -1183,29 +1183,29 @@ impl Flow for InlineFlow {
                                                     -self.base.position.size.block));
 
         self.base.restyle_damage.remove(REFLOW_OUT_OF_FLOW | REFLOW);
     }
 
     fn compute_absolute_position(&mut self) {
         for fragment in self.fragments.fragments.iter_mut() {
             let stacking_relative_position = match fragment.specific {
-                InlineBlockFragment(ref mut info) => {
+                SpecificFragmentInfo::InlineBlock(ref mut info) => {
                     let block_flow = info.flow_ref.as_block();
                     block_flow.base.absolute_position_info = self.base.absolute_position_info;
 
                     // FIXME(#2795): Get the real container size
                     let container_size = Size2D::zero();
                     block_flow.base.stacking_relative_position =
                         self.base.stacking_relative_position +
                         fragment.border_box.start.to_physical(self.base.writing_mode,
                                                               container_size);
                     block_flow.base.stacking_relative_position
                 }
-                InlineAbsoluteHypotheticalFragment(ref mut info) => {
+                SpecificFragmentInfo::InlineAbsoluteHypothetical(ref mut info) => {
                     let block_flow = info.flow_ref.as_block();
                     block_flow.base.absolute_position_info = self.base.absolute_position_info;
 
                     // FIXME(#2795): Get the real container size
                     let container_size = Size2D::zero();
                     block_flow.base.stacking_relative_position =
                         self.base.stacking_relative_position +
                         fragment.border_box.start.to_physical(self.base.writing_mode,
@@ -1215,20 +1215,20 @@ impl Flow for InlineFlow {
                 }
                 _ => continue,
             };
 
             let clip_rect = fragment.clip_rect_for_children(self.base.clip_rect,
                                                             stacking_relative_position);
 
             match fragment.specific {
-                InlineBlockFragment(ref mut info) => {
+                SpecificFragmentInfo::InlineBlock(ref mut info) => {
                     flow::mut_base(info.flow_ref.deref_mut()).clip_rect = clip_rect
                 }
-                InlineAbsoluteHypotheticalFragment(ref mut info) => {
+                SpecificFragmentInfo::InlineAbsoluteHypothetical(ref mut info) => {
                     flow::mut_base(info.flow_ref.deref_mut()).clip_rect = clip_rect
                 }
                 _ => {}
             }
         }
     }
 
     fn update_late_computed_inline_position_if_necessary(&mut self, _: Au) {}
@@ -1241,34 +1241,34 @@ impl Flow for InlineFlow {
         debug!("Flow: building display list for {:u} inline fragments", self.fragments.len());
 
         let mut display_list = box DisplayList::new();
         for fragment in self.fragments.fragments.iter_mut() {
             let fragment_origin = self.base.stacking_relative_position_of_child_fragment(fragment);
             fragment.build_display_list(&mut *display_list,
                                         layout_context,
                                         fragment_origin,
-                                        ContentLevel,
+                                        BackgroundAndBorderLevel::Content,
                                         &self.base.clip_rect);
             match fragment.specific {
-                InlineBlockFragment(ref mut block_flow) => {
+                SpecificFragmentInfo::InlineBlock(ref mut block_flow) => {
                     let block_flow = block_flow.flow_ref.deref_mut();
                     flow::mut_base(block_flow).display_list_building_result
                                               .add_to(&mut *display_list)
                 }
-                InlineAbsoluteHypotheticalFragment(ref mut block_flow) => {
+                SpecificFragmentInfo::InlineAbsoluteHypothetical(ref mut block_flow) => {
                     let block_flow = block_flow.flow_ref.deref_mut();
                     flow::mut_base(block_flow).display_list_building_result
                                               .add_to(&mut *display_list)
                 }
                 _ => {}
             }
         }
 
-        self.base.display_list_building_result = DisplayListResult(display_list);
+        self.base.display_list_building_result = DisplayListBuildingResult::Normal(display_list);
 
         if opts::get().validate_display_list_geometry {
             self.base.validate_display_list_geometry();
         }
     }
 
     fn repair_style(&mut self, _: &Arc<ComputedValues>) {}
 
--- a/servo/components/layout/layout_task.rs
+++ b/servo/components/layout/layout_task.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/. */
 
 //! The layout task. Performs layout on the DOM, builds display lists and sends them to be
 //! painted.
 
 use css::node_style::StyledNode;
-use construct::FlowConstructionResult;
+use construct::ConstructionResult;
 use context::SharedLayoutContext;
 use flow::{mod, Flow, ImmutableFlowUtils, MutableFlowUtils, MutableOwnedFlowUtils};
 use flow_ref::FlowRef;
 use fragment::{Fragment, FragmentBoundsIterator};
 use incremental::{LayoutDamageComputation, REFLOW, REFLOW_ENTIRE_DOCUMENT, REPAINT};
 use layout_debug;
 use parallel::UnsafeFlow;
 use parallel;
@@ -28,18 +28,18 @@ use geom::scale_factor::ScaleFactor;
 use gfx::color;
 use gfx::display_list::{DisplayList, OpaqueNode, StackingContext};
 use gfx::font_cache_task::FontCacheTask;
 use gfx::paint_task::{mod, PaintInitMsg, PaintChan, PaintLayer};
 use layout_traits;
 use layout_traits::{LayoutControlMsg, LayoutTaskFactory};
 use log;
 use script::dom::bindings::js::JS;
-use script::dom::node::{ElementNodeTypeId, LayoutDataRef, Node};
-use script::dom::element::{HTMLBodyElementTypeId, HTMLHtmlElementTypeId};
+use script::dom::node::{LayoutDataRef, Node, NodeTypeId};
+use script::dom::element::ElementTypeId;
 use script::layout_interface::{AddStylesheetMsg, ContentBoxResponse, ContentBoxesResponse};
 use script::layout_interface::{ContentBoxesQuery, ContentBoxQuery, ExitNowMsg, GetRPCMsg};
 use script::layout_interface::{HitTestResponse, LayoutChan, LayoutRPC, LoadStylesheetMsg};
 use script::layout_interface::{MouseOverResponse, Msg, NoQuery, PrepareToExitMsg};
 use script::layout_interface::{ReapLayoutDataMsg, Reflow, ReflowForDisplay, ReflowMsg};
 use script::layout_interface::{ScriptLayoutChan, SetQuirksModeMsg, TrustedNodeAddress};
 use script_traits::{SendEventMsg, ReflowEvent, ReflowCompleteMsg, OpaqueScriptLayoutChannel};
 use script_traits::{ScriptControlChan, UntrustedNodeAddress};
@@ -49,25 +49,25 @@ use servo_net::image_cache_task::{ImageC
 use servo_net::local_image_cache::{ImageResponder, LocalImageCache};
 use servo_net::resource_task::{ResourceTask, load_bytes_iter};
 use servo_util::geometry::Au;
 use servo_util::logical_geometry::LogicalPoint;
 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::{TimeProfilerChan, profile, TimeRootWindow, TimeIFrame, TimeIncremental, TimeFirstReflow};
+use servo_util::time::{TimeProfilerChan, profile, TimerMetadataFrameType, TimerMetadataReflowType};
 use servo_util::time;
 use servo_util::workqueue::WorkQueue;
 use std::cell::Cell;
 use std::comm::{channel, Sender, Receiver, Select};
 use std::mem;
 use std::ptr;
-use style::{AuthorOrigin, Stylesheet, Stylist, TNode, iter_font_face_rules};
-use style::{Device, Screen};
+use style::{StylesheetOrigin, Stylesheet, Stylist, TNode, iter_font_face_rules};
+use style::{MediaType, Device};
 use sync::{Arc, Mutex, MutexGuard};
 use url::Url;
 
 /// Mutable data belonging to the LayoutTask.
 ///
 /// This needs to be protected by a mutex so we can do fast RPCs.
 pub struct LayoutTaskData {
     /// The local image cache.
@@ -212,27 +212,27 @@ enum RWGuard<'a> {
     /// 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> {
     fn deref(&self) -> &LayoutTaskData {
         match *self {
-            Held(ref x) => x.deref(),
-            Used(ref x) => x.deref(),
+            RWGuard::Held(ref x) => x.deref(),
+            RWGuard::Used(ref x) => x.deref(),
         }
     }
 }
 
 impl<'a> DerefMut<LayoutTaskData> for RWGuard<'a> {
     fn deref_mut(&mut self) -> &mut LayoutTaskData {
         match *self {
-            Held(ref mut x) => x.deref_mut(),
-            Used(ref mut x) => x.deref_mut(),
+            RWGuard::Held(ref mut x) => x.deref_mut(),
+            RWGuard::Used(ref mut x) => x.deref_mut(),
         }
     }
 }
 
 impl LayoutTask {
     /// Creates a new `LayoutTask` structure.
     fn new(id: PipelineId,
            port: Receiver<Msg>,
@@ -244,17 +244,17 @@ impl LayoutTask {
            resource_task: ResourceTask,
            image_cache_task: ImageCacheTask,
            font_cache_task: FontCacheTask,
            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(Screen, opts::get().initial_window_size.as_f32() * ScaleFactor(1.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()))
         } else {
             None
         };
 
         LayoutTask {
@@ -327,62 +327,62 @@ impl LayoutTask {
             let mut port1 = sel.handle(&self.port);
             let mut port2 = sel.handle(&self.pipeline_port);
             unsafe {
                 port1.add();
                 port2.add();
             }
             let ret = sel.wait();
             if ret == port1.id() {
-                Script
+                PortToRead::Script
             } else if ret == port2.id() {
-                Pipeline
+                PortToRead::Pipeline
             } else {
                 panic!("invalid select result");
             }
         };
 
         match port_to_read {
-            Pipeline => {
+            PortToRead::Pipeline => {
                 match self.pipeline_port.recv() {
                     layout_traits::ExitNowMsg => {
                         self.handle_script_request(ExitNowMsg, possibly_locked_rw_data)
                     }
                 }
             },
-            Script => {
+            PortToRead::Script => {
                 let msg = self.port.recv();
                 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    => Used(self.rw_data.lock()),
-            Some(x) => Held(x),
+            None    => RWGuard::Used(self.rw_data.lock()),
+            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>>,
                           rw_data: RWGuard<'a>) {
         match rw_data {
-            Used(x) => drop(x),
-            Held(x) => *possibly_locked_rw_data = Some(x),
+            RWGuard::Used(x) => drop(x),
+            RWGuard::Held(x) => *possibly_locked_rw_data = Some(x),
         }
     }
 
     /// Receives and dispatches messages from the script task.
     fn handle_script_request<'a>(&'a self,
                                  request: Msg,
                                  possibly_locked_rw_data: &mut Option<MutexGuard<'a,
                                                                                  LayoutTaskData>>)
@@ -393,18 +393,18 @@ impl LayoutTask {
             SetQuirksModeMsg => self.handle_set_quirks_mode(possibly_locked_rw_data),
             GetRPCMsg(response_chan) => {
                 response_chan.send(box LayoutRPCImpl(self.rw_data.clone()) as
                                    Box<LayoutRPC + Send>);
             },
             ReflowMsg(data) => {
                 profile(time::LayoutPerformCategory,
                         Some((&data.url,
-                        if data.iframe { TimeIFrame } else { TimeRootWindow },
-                        if self.first_reflow.get() { TimeFirstReflow } else { TimeIncremental })),
+                        if data.iframe { TimerMetadataFrameType::IFrame } else { TimerMetadataFrameType::RootWindow },
+                        if self.first_reflow.get() { TimerMetadataReflowType::FirstReflow } else { TimerMetadataReflowType::Incremental })),
                         self.time_profiler_chan.clone(),
                         || self.handle_reflow(&*data, possibly_locked_rw_data));
             },
             ReapLayoutDataMsg(dead_layout_data) => {
                 unsafe {
                     LayoutTask::handle_reap_layout_data(dead_layout_data)
                 }
             },
@@ -478,17 +478,17 @@ impl LayoutTask {
         let (metadata, iter) = load_bytes_iter(&self.resource_task, url);
         let protocol_encoding_label = metadata.charset.as_ref().map(|s| s.as_slice());
         let final_url = metadata.final_url;
 
         let sheet = Stylesheet::from_bytes_iter(iter,
                                                 final_url,
                                                 protocol_encoding_label,
                                                 Some(environment_encoding),
-                                                AuthorOrigin);
+                                                StylesheetOrigin::Author);
         self.handle_add_stylesheet(sheet, possibly_locked_rw_data);
     }
 
     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.
@@ -517,17 +517,17 @@ impl LayoutTask {
             match layout_data_ref.as_mut() {
                 None              => return None,
                 Some(layout_data) => layout_data,
             };
 
         let result = layout_data.data.flow_construction_result.swap_out();
 
         let mut flow = match result {
-            FlowConstructionResult(mut flow, abs_descendants) => {
+            ConstructionResult::Flow(mut flow, abs_descendants) => {
                 // Note: Assuming that the root has display 'static' (as per
                 // CSS Section 9.3.1). Otherwise, if it were absolutely
                 // positioned, it would return a reference to itself in
                 // `abs_descendants` and would lead to a circular reference.
                 // Set Root as CB for any remaining absolute descendants.
                 flow.set_absolute_descendants(abs_descendants);
                 flow
             }
@@ -569,18 +569,18 @@ impl LayoutTask {
 
         match rw_data.parallel_traversal {
             None => panic!("solve_contraints_parallel() called with no parallel traversal ready"),
             Some(ref mut traversal) => {
                 // NOTE: this currently computes borders, so any pruning should separate that
                 // operation out.
                 parallel::traverse_flow_tree_preorder(layout_root,
                                                       &data.url,
-                                                      if data.iframe { TimeIFrame } else { TimeRootWindow },
-                                                      if self.first_reflow.get() { TimeFirstReflow } else { TimeIncremental },
+                                                      if data.iframe { TimerMetadataFrameType::IFrame } else { TimerMetadataFrameType::RootWindow },
+                                                      if self.first_reflow.get() { TimerMetadataReflowType::FirstReflow } else { TimerMetadataReflowType::Incremental },
                                                       self.time_profiler_chan.clone(),
                                                       shared_layout_context,
                                                       traversal);
             }
         }
     }
 
     /// Verifies that every node was either marked as a leaf or as a nonleaf in the flow tree.
@@ -624,18 +624,18 @@ impl LayoutTask {
                                          data: &Reflow,
                                          node: &mut LayoutNode,
                                          layout_root: &mut FlowRef,
                                          shared_layout_ctx: &mut SharedLayoutContext,
                                          rw_data: &mut RWGuard<'a>) {
         let writing_mode = flow::base(&**layout_root).writing_mode;
         profile(time::LayoutDispListBuildCategory,
                 Some((&data.url,
-                if data.iframe { TimeIFrame } else { TimeRootWindow },
-                if self.first_reflow.get() { TimeFirstReflow } else { TimeIncremental })),
+                if data.iframe { TimerMetadataFrameType::IFrame } else { TimerMetadataFrameType::RootWindow },
+                if self.first_reflow.get() { TimerMetadataReflowType::FirstReflow } else { TimerMetadataReflowType::Incremental })),
                      self.time_profiler_chan.clone(),
                      || {
             shared_layout_ctx.dirty =
                 flow::base(&**layout_root).position.to_physical(writing_mode,
                                                                      rw_data.screen_size);
             flow::mut_base(&mut **layout_root).stacking_relative_position =
                 LogicalPoint::zero(writing_mode).to_physical(writing_mode,
                                                              rw_data.screen_size);
@@ -645,32 +645,32 @@ impl LayoutTask {
             let rw_data = rw_data.deref_mut();
             match rw_data.parallel_traversal {
                 None => {
                     sequential::build_display_list_for_subtree(layout_root, shared_layout_ctx);
                 }
                 Some(ref mut traversal) => {
                     parallel::build_display_list_for_subtree(layout_root,
                                                              &data.url,
-                                                             if data.iframe { TimeIFrame } else { TimeRootWindow },
-                                                             if self.first_reflow.get() { TimeFirstReflow } else { TimeIncremental },
+                                                             if data.iframe { TimerMetadataFrameType::IFrame } else { TimerMetadataFrameType::RootWindow },
+                                                             if self.first_reflow.get() { TimerMetadataReflowType::FirstReflow } else { TimerMetadataReflowType::Incremental },
                                                              self.time_profiler_chan.clone(),
                                                              shared_layout_ctx,
                                                              traversal);
                 }
             }
 
             debug!("Done building display list.");
 
             // FIXME(pcwalton): This is really ugly and can't handle overflow: scroll. Refactor
             // it with extreme prejudice.
             let mut color = color::rgba(1.0, 1.0, 1.0, 1.0);
             for child in node.traverse_preorder() {
-                if child.type_id() == Some(ElementNodeTypeId(HTMLHtmlElementTypeId)) ||
-                        child.type_id() == Some(ElementNodeTypeId(HTMLBodyElementTypeId)) {
+                if child.type_id() == Some(NodeTypeId::Element(ElementTypeId::HTMLHtmlElement)) ||
+                        child.type_id() == Some(NodeTypeId::Element(ElementTypeId::HTMLBodyElement)) {
                     let element_bg_color = {
                         let thread_safe_child = ThreadSafeLayoutNode::new(&child);
                         thread_safe_child.style()
                                          .resolve_color(thread_safe_child.style()
                                                                          .get_background()
                                                                          .background_color)
                                          .to_gfx_color()
                     };
@@ -749,17 +749,17 @@ impl LayoutTask {
         let mut shared_layout_ctx = self.build_shared_layout_context(rw_data.deref(),
                                                                      node,
                                                                      &data.url);
 
         // Handle conditions where the entire flow tree is invalid.
         let screen_size_changed = current_screen_size != old_screen_size;
 
         if screen_size_changed {
-            let device = Device::new(Screen, data.window_size.initial_viewport);
+            let device = Device::new(MediaType::Screen, data.window_size.initial_viewport);
             rw_data.stylist.set_device(device);
         }
 
         let needs_dirtying = rw_data.stylist.update();
 
         // If the entire flow tree is invalid, then it will be reflowed anyhow.
         let needs_reflow = screen_size_changed && !needs_dirtying;
 
@@ -771,18 +771,18 @@ impl LayoutTask {
 
         if needs_reflow {
             self.try_get_layout_root(*node).map(
                 |mut flow| LayoutTask::reflow_all_nodes(flow.deref_mut()));
         }
 
         let mut layout_root = profile(time::LayoutStyleRecalcCategory,
                                       Some((&data.url,
-                                      if data.iframe { TimeIFrame } else { TimeRootWindow },
-                                      if self.first_reflow.get() { TimeFirstReflow } else { TimeIncremental })),
+                                      if data.iframe { TimerMetadataFrameType::IFrame } else { TimerMetadataFrameType::RootWindow },
+                                      if self.first_reflow.get() { TimerMetadataReflowType::FirstReflow } else { TimerMetadataReflowType::Incremental })),
                                       self.time_profiler_chan.clone(),
                                       || {
             // Perform CSS selector matching and flow construction.
             let rw_data = rw_data.deref_mut();
             match rw_data.parallel_traversal {
                 None => {
                     sequential::traverse_dom_preorder(*node, &shared_layout_ctx);
                 }
@@ -791,18 +791,18 @@ impl LayoutTask {
                 }
             }
 
             self.get_layout_root((*node).clone())
         });
 
         profile(time::LayoutRestyleDamagePropagation,
                 Some((&data.url,
-                if data.iframe { TimeIFrame } else { TimeRootWindow },
-                if self.first_reflow.get() { TimeFirstReflow } else { TimeIncremental })),
+                if data.iframe { TimerMetadataFrameType::IFrame } else { TimerMetadataFrameType::RootWindow },
+                if self.first_reflow.get() { TimerMetadataReflowType::FirstReflow } else { TimerMetadataReflowType::Incremental })),
                 self.time_profiler_chan.clone(),
                 || {
             if opts::get().nonincremental_layout ||
                     layout_root.deref_mut().compute_layout_damage().contains(REFLOW_ENTIRE_DOCUMENT) {
                 layout_root.deref_mut().reflow_entire_document()
             }
         });
 
@@ -814,18 +814,18 @@ impl LayoutTask {
         if opts::get().trace_layout {
             layout_debug::begin_trace(layout_root.clone());
         }
 
         // Perform the primary layout passes over the flow tree to compute the locations of all
         // the boxes.
         profile(time::LayoutMainCategory,
                 Some((&data.url,
-                if data.iframe { TimeIFrame } else { TimeRootWindow },
-                if self.first_reflow.get() { TimeFirstReflow } else { TimeIncremental })),
+                if data.iframe { TimerMetadataFrameType::IFrame } else { TimerMetadataFrameType::RootWindow },
+                if self.first_reflow.get() { TimerMetadataReflowType::FirstReflow } else { TimerMetadataReflowType::Incremental })),
                 self.time_profiler_chan.clone(),
                 || {
             let rw_data = rw_data.deref_mut();
             match rw_data.parallel_traversal {
                 None => {
                     // Sequential mode.
                     self.solve_constraints(&mut layout_root, &shared_layout_ctx)
                 }
--- a/servo/components/layout/list_item.rs
+++ b/servo/components/layout/list_item.rs
@@ -6,17 +6,17 @@
 //! block and an extra inline fragment for the marker.
 
 #![deny(unsafe_blocks)]
 
 use block::BlockFlow;
 use construct::FlowConstructor;
 use context::LayoutContext;
 use display_list_builder::ListItemFlowDisplayListBuilding;
-use flow::{Flow, FlowClass, ListItemFlowClass};
+use flow::{Flow, FlowClass};
 use fragment::{Fragment, FragmentBoundsIterator};
 use wrapper::ThreadSafeLayoutNode;
 
 use gfx::display_list::DisplayList;
 use servo_util::geometry::Au;
 use servo_util::opts;
 use style::ComputedValues;
 use style::computed_values::list_style_type;
@@ -41,17 +41,17 @@ impl ListItemFlow {
             block_flow: BlockFlow::from_node(constructor, node),
             marker: marker_fragment,
         }
     }
 }
 
 impl Flow for ListItemFlow {
     fn class(&self) -> FlowClass {
-        ListItemFlowClass
+        FlowClass::ListItem
     }
 
     fn as_block<'a>(&'a mut self) -> &'a mut BlockFlow {
         &mut self.block_flow
     }
 
     fn bubble_inline_sizes(&mut self) {
         // The marker contributes no intrinsic inline-size, so…
--- a/servo/components/layout/model.rs
+++ b/servo/components/layout/model.rs
@@ -5,17 +5,17 @@
 //! Borders, padding, and margins.
 
 #![deny(unsafe_blocks)]
 
 use fragment::Fragment;
 
 use style::computed_values as computed;
 use geom::SideOffsets2D;
-use style::computed_values::{LPA_Auto, LPA_Length, LPA_Percentage, LP_Length, LP_Percentage};
+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.
 pub struct AdjoiningMargins {
@@ -57,184 +57,184 @@ 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.
 pub enum CollapsibleMargins {
     /// Margins may not collapse with this flow.
-    NoCollapsibleMargins(Au, Au),
+    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.
-    MarginsCollapse(AdjoiningMargins, AdjoiningMargins),
+    Collapse(AdjoiningMargins, AdjoiningMargins),
 
     /// Margins collapse *through* this flow. This means, essentially, that the flow doesn’t
     /// have any border, padding, or out-of-flow (floating or positioned) content
-    MarginsCollapseThrough(AdjoiningMargins),
+    CollapseThrough(AdjoiningMargins),
 }
 
 impl CollapsibleMargins {
     pub fn new() -> CollapsibleMargins {
-        NoCollapsibleMargins(Au(0), Au(0))
+        CollapsibleMargins::None(Au(0), Au(0))
     }
 }
 
 enum FinalMarginState {
-    MarginsCollapseThroughFinalMarginState,
-    BottomMarginCollapsesFinalMarginState,
+    MarginsCollapseThrough,
+    BottomMarginCollapses,
 }
 
 pub struct MarginCollapseInfo {
     pub state: MarginCollapseState,
     pub block_start_margin: AdjoiningMargins,
     pub margin_in: AdjoiningMargins,
 }
 
 impl MarginCollapseInfo {
     /// TODO(#2012, pcwalton): Remove this method once `fragment` is not an `Option`.
     pub fn new() -> MarginCollapseInfo {
         MarginCollapseInfo {
-            state: AccumulatingCollapsibleTopMargin,
+            state: MarginCollapseState::AccumulatingCollapsibleTopMargin,
             block_start_margin: AdjoiningMargins::new(),
             margin_in: AdjoiningMargins::new(),
         }
     }
 
     pub fn initialize_block_start_margin(&mut self,
                                  fragment: &Fragment,
                                  can_collapse_block_start_margin_with_kids: bool) {
         if !can_collapse_block_start_margin_with_kids {
-            self.state = AccumulatingMarginIn
+            self.state = MarginCollapseState::AccumulatingMarginIn
         }
 
         self.block_start_margin = AdjoiningMargins::from_margin(fragment.margin.block_start)
     }
 
     pub fn finish_and_compute_collapsible_margins(mut self,
                                                   fragment: &Fragment,
                                                   can_collapse_block_end_margin_with_kids: bool)
                                                   -> (CollapsibleMargins, Au) {
         let state = match self.state {
-            AccumulatingCollapsibleTopMargin => {
+            MarginCollapseState::AccumulatingCollapsibleTopMargin => {
                 match fragment.style().content_block_size() {
-                    LPA_Auto | LPA_Length(Au(0)) | LPA_Percentage(0.) => {
+                    LengthOrPercentageOrAuto::Auto | LengthOrPercentageOrAuto::Length(Au(0)) | LengthOrPercentageOrAuto::Percentage(0.) => {
                         match fragment.style().min_block_size() {
-                            LP_Length(Au(0)) | LP_Percentage(0.) => {
-                                MarginsCollapseThroughFinalMarginState
+                            LengthOrPercentage::Length(Au(0)) | LengthOrPercentage::Percentage(0.) => {
+                                FinalMarginState::MarginsCollapseThrough
                             },
                             _ => {
                                 // If the fragment has non-zero min-block-size, margins may not
                                 // collapse through it.
-                                BottomMarginCollapsesFinalMarginState
+                                FinalMarginState::BottomMarginCollapses
                             }
                         }
                     },
                     _ => {
                         // If the fragment has an explicitly specified block-size, margins may not
                         // collapse through it.
-                        BottomMarginCollapsesFinalMarginState
+                        FinalMarginState::BottomMarginCollapses
                     }
                 }
             }
-            AccumulatingMarginIn => BottomMarginCollapsesFinalMarginState,
+            MarginCollapseState::AccumulatingMarginIn => FinalMarginState::BottomMarginCollapses,
         };
 
         // Different logic is needed here depending on whether this flow can collapse its block-end
         // margin with its children.
         let block_end_margin = fragment.margin.block_end;
         if !can_collapse_block_end_margin_with_kids {
             match state {
-                MarginsCollapseThroughFinalMarginState => {
+                FinalMarginState::MarginsCollapseThrough => {
                     let advance = self.block_start_margin.collapse();
                     self.margin_in.union(AdjoiningMargins::from_margin(block_end_margin));
-                    (MarginsCollapse(self.block_start_margin, self.margin_in), advance)
+                    (CollapsibleMargins::Collapse(self.block_start_margin, self.margin_in), advance)
                 }
-                BottomMarginCollapsesFinalMarginState => {
+                FinalMarginState::BottomMarginCollapses => {
                     let advance = self.margin_in.collapse();
                     self.margin_in.union(AdjoiningMargins::from_margin(block_end_margin));
-                    (MarginsCollapse(self.block_start_margin, self.margin_in), advance)
+                    (CollapsibleMargins::Collapse(self.block_start_margin, self.margin_in), advance)
                 }
             }
         } else {
             match state {
-                MarginsCollapseThroughFinalMarginState => {
+                FinalMarginState::MarginsCollapseThrough => {
                     self.block_start_margin.union(AdjoiningMargins::from_margin(block_end_margin));
-                    (MarginsCollapseThrough(self.block_start_margin), Au(0))
+                    (CollapsibleMargins::CollapseThrough(self.block_start_margin), Au(0))
                 }
-                BottomMarginCollapsesFinalMarginState => {
+                FinalMarginState::BottomMarginCollapses => {
                     self.margin_in.union(AdjoiningMargins::from_margin(block_end_margin));
-                    (MarginsCollapse(self.block_start_margin, self.margin_in), Au(0))
+                    (CollapsibleMargins::Collapse(self.block_start_margin, self.margin_in), Au(0))
                 }
             }
         }
     }
 
     pub fn current_float_ceiling(&mut self) -> Au {
         match self.state {
-            AccumulatingCollapsibleTopMargin => self.block_start_margin.collapse(),
-            AccumulatingMarginIn => self.margin_in.collapse(),
+            MarginCollapseState::AccumulatingCollapsibleTopMargin => self.block_start_margin.collapse(),
+            MarginCollapseState::AccumulatingMarginIn => self.margin_in.collapse(),
         }
     }
 
     /// Adds the child's potentially collapsible block-start margin to the current margin state and
     /// advances the Y offset by the appropriate amount to handle that margin. Returns the amount
     /// that should be added to the Y offset during block layout.
     pub fn advance_block_start_margin(&mut self, child_collapsible_margins: &CollapsibleMargins) -> Au {
         match (self.state, *child_collapsible_margins) {
-            (AccumulatingCollapsibleTopMargin, NoCollapsibleMargins(block_start, _)) => {
-                self.state = AccumulatingMarginIn;
+            (MarginCollapseState::AccumulatingCollapsibleTopMargin, CollapsibleMargins::None(block_start, _)) => {
+                self.state = MarginCollapseState::AccumulatingMarginIn;
                 block_start
             }
-            (AccumulatingCollapsibleTopMargin, MarginsCollapse(block_start, _)) => {
+            (MarginCollapseState::AccumulatingCollapsibleTopMargin, CollapsibleMargins::Collapse(block_start, _)) => {
                 self.block_start_margin.union(block_start);
-                self.state = AccumulatingMarginIn;
+                self.state = MarginCollapseState::AccumulatingMarginIn;
                 Au(0)
             }
-            (AccumulatingMarginIn, NoCollapsibleMargins(block_start, _)) => {
+            (MarginCollapseState::AccumulatingMarginIn, CollapsibleMargins::None(block_start, _)) => {
                 let previous_margin_value = self.margin_in.collapse();
                 self.margin_in = AdjoiningMargins::new();
                 previous_margin_value + block_start
             }
-            (AccumulatingMarginIn, MarginsCollapse(block_start, _)) => {
+            (MarginCollapseState::AccumulatingMarginIn, CollapsibleMargins::Collapse(block_start, _)) => {
                 self.margin_in.union(block_start);
                 let margin_value = self.margin_in.collapse();
                 self.margin_in = AdjoiningMargins::new();
                 margin_value
             }
-            (_, MarginsCollapseThrough(_)) => {
+            (_, CollapsibleMargins::CollapseThrough(_)) => {
                 // For now, we ignore this; this will be handled by `advance_block-end_margin` below.
                 Au(0)
             }
         }
     }
 
     /// Adds the child's potentially collapsible block-end margin to the current margin state and
     /// advances the Y offset by the appropriate amount to handle that margin. Returns the amount
     /// that should be added to the Y offset during block layout.
     pub fn advance_block_end_margin(&mut self, child_collapsible_margins: &CollapsibleMargins) -> Au {
         match (self.state, *child_collapsible_margins) {
-            (AccumulatingCollapsibleTopMargin, NoCollapsibleMargins(..)) |
-            (AccumulatingCollapsibleTopMargin, MarginsCollapse(..)) => {
+            (MarginCollapseState::AccumulatingCollapsibleTopMargin, CollapsibleMargins::None(..)) |
+            (MarginCollapseState::AccumulatingCollapsibleTopMargin, CollapsibleMargins::Collapse(..)) => {
                 // Can't happen because the state will have been replaced with
-                // `AccumulatingMarginIn` above.
+                // `MarginCollapseState::AccumulatingMarginIn` above.
                 panic!("should not be accumulating collapsible block_start margins anymore!")
             }
-            (AccumulatingCollapsibleTopMargin, MarginsCollapseThrough(margin)) => {
+            (MarginCollapseState::AccumulatingCollapsibleTopMargin, CollapsibleMargins::CollapseThrough(margin)) => {
                 self.block_start_margin.union(margin);
                 Au(0)
             }
-            (AccumulatingMarginIn, NoCollapsibleMargins(_, block_end)) => {
+            (MarginCollapseState::AccumulatingMarginIn, CollapsibleMargins::None(_, block_end)) => {
                 assert_eq!(self.margin_in.most_positive, Au(0));
                 assert_eq!(self.margin_in.most_negative, Au(0));
                 block_end
             }
-            (AccumulatingMarginIn, MarginsCollapse(_, block_end)) |
-            (AccumulatingMarginIn, MarginsCollapseThrough(block_end)) => {
+            (MarginCollapseState::AccumulatingMarginIn, CollapsibleMargins::Collapse(_, block_end)) |
+            (MarginCollapseState::AccumulatingMarginIn, CollapsibleMargins::CollapseThrough(block_end)) => {
                 self.margin_in.union(block_end);
                 Au(0)
             }
         }
     }
 }
 
 pub enum MarginCollapseState {
@@ -328,58 +328,58 @@ pub enum MaybeAuto {
     Specified(Au),
 }
 
 impl MaybeAuto {
     #[inline]
     pub fn from_style(length: computed::LengthOrPercentageOrAuto, containing_length: Au)
                       -> MaybeAuto {
         match length {
-            computed::LPA_Auto => Auto,
-            computed::LPA_Percentage(percent) => {
-                Specified(containing_length.scale_by(percent))
+            computed::LengthOrPercentageOrAuto::Auto => MaybeAuto::Auto,
+            computed::LengthOrPercentageOrAuto::Percentage(percent) => {
+                MaybeAuto::Specified(containing_length.scale_by(percent))
             }
-            computed::LPA_Length(length) => Specified(length)
+            computed::LengthOrPercentageOrAuto::Length(length) => MaybeAuto::Specified(length)
         }
     }
 
     #[inline]
     pub fn specified_or_default(&self, default: Au) -> Au {
         match *self {
-            Auto => default,
-            Specified(value) => value,
+            MaybeAuto::Auto => default,
+            MaybeAuto::Specified(value) => value,
         }
     }
 
     #[inline]
     pub fn specified_or_zero(&self) -> Au {
         self.specified_or_default(Au::new(0))
     }
 
     #[inline]
     pub fn map(&self, mapper: |Au| -> Au) -> MaybeAuto {
         match *self {
-            Auto => Auto,
-            Specified(value) => Specified(mapper(value)),
+            MaybeAuto::Auto => MaybeAuto::Auto,
+            MaybeAuto::Specified(value) => MaybeAuto::Specified(mapper(value)),
         }
     }
 }
 
 pub fn specified_or_none(length: computed::LengthOrPercentageOrNone, containing_length: Au) -> Option<Au> {
     match length {
-        computed::LPN_None => None,
-        computed::LPN_Percentage(percent) => Some(containing_length.scale_by(percent)),
-        computed::LPN_Length(length) => Some(length),
+        computed::LengthOrPercentageOrNone::None => None,
+        computed::LengthOrPercentageOrNone::Percentage(percent) => Some(containing_length.scale_by(percent)),
+        computed::LengthOrPercentageOrNone::Length(length) => Some(length),
     }
 }
 
 pub fn specified(length: computed::LengthOrPercentage, containing_length: Au) -> Au {
     match length {
-        computed::LP_Length(length) => length,
-        computed::LP_Percentage(p) => containing_length.scale_by(p)
+        computed::LengthOrPercentage::Length(length) => length,
+        computed::LengthOrPercentage::Percentage(p) => containing_length.scale_by(p)
     }
 }
 
 #[inline]
 pub fn padding_from_style(style: &ComputedValues, containing_block_inline_size: Au)
                           -> LogicalMargin<Au> {
     let padding_style = style.get_padding();
     LogicalMargin::from_physical(style.writing_mode, SideOffsets2D::new(
--- a/servo/components/layout/table.rs
+++ b/servo/components/layout/table.rs
@@ -1,36 +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/. */
 
 //! CSS table formatting contexts.
 
 #![deny(unsafe_blocks)]
 
-use block::{BlockFlow, MarginsMayNotCollapse, ISizeAndMarginsComputer};
+use block::{BlockFlow, ISizeAndMarginsComputer, MarginsMayCollapseFlag};
 use block::{ISizeConstraintInput, ISizeConstraintSolution};
 use construct::FlowConstructor;
 use context::LayoutContext;
 use floats::FloatKind;
 use flow::{mod, Flow, FlowClass, IMPACTED_BY_LEFT_FLOATS, IMPACTED_BY_RIGHT_FLOATS};
-use flow::{ImmutableFlowUtils, TableFlowClass};
+use flow::ImmutableFlowUtils;
 use fragment::{Fragment, FragmentBoundsIterator};
 use layout_debug;
 use model::{IntrinsicISizes, IntrinsicISizesContribution};
 use table_row::CellIntrinsicInlineSize;
-use table_wrapper::{TableLayout, FixedLayout, AutoLayout};
+use table_wrapper::TableLayout;
 use wrapper::ThreadSafeLayoutNode;
 
 use servo_util::geometry::Au;
 use servo_util::logical_geometry::LogicalRect;
 use std::cmp::max;
 use std::fmt;
 use style::{ComputedValues, CSSFloat};
-use style::computed_values::{LPA_Auto, LPA_Length, LPA_Percentage, table_layout};
+use style::computed_values::{LengthOrPercentageOrAuto, table_layout};
 use 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)]
 pub struct TableFlow {
     pub block_flow: BlockFlow,
@@ -49,56 +49,56 @@ pub struct TableFlow {
 
 impl TableFlow {
     pub fn from_node_and_fragment(node: &ThreadSafeLayoutNode,
                                   fragment: Fragment)
                                   -> TableFlow {
         let mut block_flow = BlockFlow::from_node_and_fragment(node, fragment);
         let table_layout = if block_flow.fragment().style().get_table().table_layout ==
                               table_layout::fixed {
-            FixedLayout
+            TableLayout::Fixed
         } else {
-            AutoLayout
+            TableLayout::Auto
         };
         TableFlow {
             block_flow: block_flow,
             column_intrinsic_inline_sizes: Vec::new(),
             column_computed_inline_sizes: Vec::new(),
             table_layout: table_layout
         }
     }
 
     pub fn from_node(constructor: &mut FlowConstructor,
                      node: &ThreadSafeLayoutNode)
                      -> TableFlow {
         let mut block_flow = BlockFlow::from_node(constructor, node);
         let table_layout = if block_flow.fragment().style().get_table().table_layout ==
                               table_layout::fixed {
-            FixedLayout
+            TableLayout::Fixed
         } else {
-            AutoLayout
+            TableLayout::Auto
         };
         TableFlow {
             block_flow: block_flow,
             column_intrinsic_inline_sizes: Vec::new(),
             column_computed_inline_sizes: Vec::new(),
             table_layout: table_layout
         }
     }
 
     pub fn float_from_node(constructor: &mut FlowConstructor,
                            node: &ThreadSafeLayoutNode,
                            float_kind: FloatKind)
                            -> TableFlow {
         let mut block_flow = BlockFlow::float_from_node(constructor, node, float_kind);
         let table_layout = if block_flow.fragment().style().get_table().table_layout ==
                               table_layout::fixed {
-            FixedLayout
+            TableLayout::Fixed
         } else {
-            AutoLayout
+            TableLayout::Auto
         };
         TableFlow {
             block_flow: block_flow,
             column_intrinsic_inline_sizes: Vec::new(),
             column_computed_inline_sizes: Vec::new(),
             table_layout: table_layout
         }
     }
@@ -159,56 +159,56 @@ impl TableFlow {
     /// Assign block-size for table flow.
     ///
     /// TODO(#2014, pcwalton): This probably doesn't handle margin collapse right.
     ///
     /// inline(always) because this is only ever called by in-order or non-in-order top-level
     /// methods
     #[inline(always)]
     fn assign_block_size_table_base<'a>(&mut self, layout_context: &'a LayoutContext<'a>) {
-        self.block_flow.assign_block_size_block_base(layout_context, MarginsMayNotCollapse);
+        self.block_flow.assign_block_size_block_base(layout_context, MarginsMayCollapseFlag::MarginsMayNotCollapse);
     }
 
     /// Updates the minimum and preferred inline-size calculation for a single row. This is
     /// factored out into a separate function because we process children of rowgroups too.
     fn update_column_inline_sizes_for_row(child: &mut Flow,
                                           column_inline_sizes: &mut Vec<ColumnIntrinsicInlineSize>,
                                           computation: &mut IntrinsicISizesContribution,
                                           did_first_row: &mut bool,
                                           table_layout: TableLayout) {
         // Read column inline-sizes from the table-row, and assign inline-size=0 for the columns
         // not defined in the column group.
         //
         // FIXME: Need to read inline-sizes from either table-header-group OR the first table-row.
         debug_assert!(child.is_table_row());
         let row = child.as_table_row();
         match table_layout {
-            FixedLayout => {
+            TableLayout::Fixed => {
                 // Fixed table layout only looks at the first row.
                 //
                 // FIXME(pcwalton): This is really inefficient. We should stop after the first row!
                 if !*did_first_row {
                     *did_first_row = true;
                     for cell_inline_size in row.cell_intrinsic_inline_sizes.iter() {
                         column_inline_sizes.push(cell_inline_size.column_size);
                     }
                 }
             }
-            AutoLayout => {
+            TableLayout::Auto => {
                 computation.union_block(&TableFlow::update_automatic_column_inline_sizes(
                     column_inline_sizes,
                     row.cell_intrinsic_inline_sizes.as_slice()))
             }
         }
     }
 }
 
 impl Flow for TableFlow {
     fn class(&self) -> FlowClass {
-        TableFlowClass
+        FlowClass::Table
     }
 
     fn as_table<'a>(&'a mut self) -> &'a mut TableFlow {
         self
     }
 
     fn as_immutable_table<'a>(&'a self) -> &'a TableFlow {
         self
@@ -237,22 +237,22 @@ impl Flow for TableFlow {
         let mut computation = IntrinsicISizesContribution::new();
         let mut did_first_row = false;
         for kid in self.block_flow.base.child_iter() {
             debug_assert!(kid.is_proper_table_child());
             if kid.is_table_colgroup() {
                 for specified_inline_size in kid.as_table_colgroup().inline_sizes.iter() {
                     self.column_intrinsic_inline_sizes.push(ColumnIntrinsicInlineSize {
                         minimum_length: match *specified_inline_size {
-                            LPA_Auto | LPA_Percentage(_) => Au(0),
-                            LPA_Length(length) => length,
+                            LengthOrPercentageOrAuto::Auto | LengthOrPercentageOrAuto::Percentage(_) => Au(0),
+                            LengthOrPercentageOrAuto::Length(length) => length,
                         },
                         percentage: match *specified_inline_size {
-                            LPA_Auto | LPA_Length(_) => 0.0,
-                            LPA_Percentage(percentage) => percentage,
+                            LengthOrPercentageOrAuto::Auto | LengthOrPercentageOrAuto::Length(_) => 0.0,
+                            LengthOrPercentageOrAuto::Percentage(percentage) => percentage,
                         },
                         preferred: Au(0),
                         constrained: false,
                     })
                 }
             } else if kid.is_table_rowgroup() {
                 for grandkid in flow::mut_base(kid).child_iter() {
                     TableFlow::update_column_inline_sizes_for_row(
@@ -303,17 +303,17 @@ impl Flow for TableFlow {
                                                       containing_block_inline_size);
 
         let inline_start_content_edge = self.block_flow.fragment.border_padding.inline_start;
         let padding_and_borders = self.block_flow.fragment.border_padding.inline_start_end();
         let content_inline_size =
             self.block_flow.fragment.border_box.size.inline - padding_and_borders;
 
         match self.table_layout {
-            FixedLayout => {
+            TableLayout::Fixed => {
                 // In fixed table layout, we distribute extra space among the unspecified columns
                 // if there are any, or among all the columns if all are specified.
                 self.column_computed_inline_sizes.clear();
                 if num_unspecified_inline_sizes == 0 {
                     let ratio = content_inline_size.to_subpx() /
                         total_column_inline_size.to_subpx();
                     for column_inline_size in self.column_intrinsic_inline_sizes.iter() {
                         self.column_computed_inline_sizes.push(ColumnComputedInlineSize {
--- a/servo/components/layout/table_caption.rs
+++ b/servo/components/layout/table_caption.rs
@@ -4,17 +4,17 @@
 
 //! CSS table formatting contexts.
 
 #![deny(unsafe_blocks)]
 
 use block::BlockFlow;
 use construct::FlowConstructor;
 use context::LayoutContext;
-use flow::{TableCaptionFlowClass, FlowClass, Flow};
+use flow::{FlowClass, Flow};
 use fragment::FragmentBoundsIterator;
 use wrapper::ThreadSafeLayoutNode;
 
 use servo_util::geometry::Au;
 use std::fmt;
 use style::ComputedValues;
 use sync::Arc;
 
@@ -30,17 +30,17 @@ impl TableCaptionFlow {
         TableCaptionFlow {
             block_flow: BlockFlow::from_node(constructor, node)
         }
     }
 }
 
 impl Flow for TableCaptionFlow {
     fn class(&self) -> FlowClass {
-        TableCaptionFlowClass
+        FlowClass::TableCaption
     }
 
     fn as_table_caption<'a>(&'a mut self) -> &'a mut TableCaptionFlow {
         self
     }
 
     fn as_block<'a>(&'a mut self) -> &'a mut BlockFlow {
         &mut self.block_flow
--- a/servo/components/layout/table_cell.rs
+++ b/servo/components/layout/table_cell.rs
@@ -1,45 +1,45 @@
 /* This Source Code Form is