Skip to content

Instantly share code, notes, and snippets.

@Manishearth
Last active August 29, 2015 14:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Manishearth/967bc78db5c751c38d03 to your computer and use it in GitHub Desktop.
Save Manishearth/967bc78db5c751c38d03 to your computer and use it in GitHub Desktop.
Servo unstable feature usage

The following gates: plugin, box_syntax, custom_derive, custom_attribute were ignored for this analysis because these are features we don't plan on moving off unless absolutely necessary. Nevertheless, they're not strictly necessary for Servo to work; they just make some code nicer.

The main point of this exercise was to find what unstable APIs Servo uses/needs a lot, which might probably be needed by others too. Most of these have workarounds, and most of these are blocked on trivial things like naming (and could be easily stabilized). While I did remove some unstable usage in Servo, I didn't fix the majority of these even though it was easy to fix because we use nightly anyway (plugins, etc) and it would be nice to end up with the final, polished, performant APIs instead of a slightly more verbose workaround that we'll forget about.

Really common APIs

collections almost everywhere is just blocked on Vec.push_all(). We can immediately use extend() here if we want, or a for loop, but if this API is going to be replaced with something performant, I'd prefer to keep the existing code till it breaks and tells us the better API to use.

alloc needs Rc.make_unique()/Arc.make_unique() (which is unstable for some unknown reason), and from_raw/into_raw for Box (which are unstable for naming reasons). FnBox is also needed.

Other APIs which got used in more than one crate:

  • [T].tail() (naming)
  • slice::bytes::copy_memory (needs review)
  • NonZero
  • DefaultState (and the other custom hasher stuff to a lesser degree)
  • step_by (recently added)
  • CharRange (we could replace this easily)
  • Handle from the select API

Except for NonZero , DefaultState , and HandleI think our API usage for these would be relatively easy to convert to stable APIs. I'm not sure if DefaultState is necessary to be stable either.

Weak<T> is something that we don't use much but probably deserves to be stabilized.

Analysis of crates

Stuff in parentheses is the reason given by the stability tag for its instability. Stuff in brackets is a note on how necessary it is for us and if it could be replaced easily.

canvas

collections:

  • Vec.push_all() (May be replaced) [We could replace this with a for loop]

core:

  • copy_memory (needs review) [Can be replaced with other calls eg copy_nonoverlapping]

canvas_traits:

  • NonZero [Not necessary but slight optimization]

compositing

core:

  • copy_memory [Can be replaced]

collections:

  • push_all [Can be replaced with a for loop or extend()]

devtools

core:

  • Reflect / Any stuff [I think the API could be moved to enum-based dynamic dispatch if necessary]

gfx

alloc:

  • weak pointers (may not belong) [Using Rc here would lead to a slight perf drop, but doable]
  • boxed::into_raw and from_raw (naming) [Transmutes and other things would work]

collections:

  • Vec.push_all() (May be replaced) [Can be fixed with a loop or extend()]

core:

  • min_by (#15311) [Could just use a loop]
  • PI_2 (naming) [Can just use a hardcoded constant]

rustc_private:

  • FnvHasher [I think we can just use rust-fnv here]

std_misc:

  • Hash state stuff [I think this isn't necessayr, but DefaultState would be nice to have stable]

str_char:

  • CharRange usage [Can be replaced by regular iterators (char_indices)]

layout

We do lots of crazy pointer-fu and optimizations here. Perhaps this section should be ignored.

alloc:

  • make_unique()
  • direct calls into heap::allocate(), etc
  • boxed::into_raw() (naming)

collections:

  • slice_chars() (needs to prove its worth)

core:

  • lots and lots of pointer manip
  • raw stuff

std_misc:

  • Handle stuff
  • hasher stuff

str_char:

  • CharRange [Can be replaced with an iterator]

unsafe_no_drop_flag

  • For pointer-fu

net

std_misc:

  • Handle usage (API will be replaced and is perhaps broken) [No replacement without restructuring the code, which isn't too hard]

path_ext:

  • Checking if a file exists. [This is doable from the File directly, but needs some method chaining]

core:

  • FnBox

alloc:

  • boxed::into_raw() (naming)

net_traits

collections:

  • push_all again [ for loop or extend()]

step_by: step_by [Could easily be replaced by a loop]

plugins

Ahahahaha nope.

profile

collections:

  • [T].tail() (naming) [use iterators]

script

alloc:

  • Rc.make_unique()
  • into_raw / from_raw (naming). All over the bindings code.

collections:

  • Vec.push_all()
  • from_str
    • can be replaced by .to_owned()
  • from_raw_buf
    • could be done directly

core:

  • nonzero [ just a perf improvement]
  • UnsafeCell (as_unsafe_cell) [For our own interior mutability structs with DOM integration.]
  • Zeroable [Not really necessary]
  • Peekable.is_empty [Not really necessary]

std_misc:

  • Handle stuff

style

alloc:

  • Arc.make_unique() everywhere

core:

  • intrinsics::discriminant_value for a small optimization. Not sure what's happening here

hash:

  • Hasher.write_u16 (recently redesigned)

util

alloc / OIBIT : For deque (which was just copied from rust's source). Probably could be cleaned up to not use these.

collections:

  • [T].tail()
  • to_lowercase()

core:

  • FnBox
  • intrinsics::breakpoint() [only used for debugging[

exit_status: for setting exit status [Could be done in other ways]

path_ext: for is_dir and exists() [can be done in other ways]

step_by/step_trait: [use regular loops]

std_misc:

  • Thunk (same as FnBox)
  • DefaultState and other hasher stuff

zero_one: num::One [Not really necessary]

webdriver_server

ip_addr: for SocketAddr (new)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment