Skip to content

Remove the magic deref behavior of newtype structs and enums #11188

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions doc/tutorial.md
Original file line number Diff line number Diff line change
Expand Up @@ -793,15 +793,6 @@ synonym for an existing type but is rather its own distinct type.
struct GizmoId(int);
~~~~

For convenience, you can extract the contents of such a struct with the
dereference (`*`) unary operator:

~~~~
# struct GizmoId(int);
let my_gizmo_id: GizmoId = GizmoId(10);
let id_int: int = *my_gizmo_id;
~~~~

Types like this can be useful to differentiate between data that have
the same underlying type but must be used in different ways.

Expand All @@ -811,7 +802,16 @@ struct Centimeters(int);
~~~~

The above definitions allow for a simple way for programs to avoid
confusing numbers that correspond to different units.
confusing numbers that correspond to different units. Their integer
values can be extracted with pattern matching:

~~~
# struct Inches(int);

let length_with_unit = Inches(10);
let Inches(integer_length) = length_with_unit;
println!("length is {} inches", integer_length);
~~~

# Functions

Expand Down Expand Up @@ -2595,7 +2595,7 @@ the `priv` keyword:
mod farm {
# pub type Chicken = int;
# struct Human(int);
# impl Human { fn rest(&self) { } }
# impl Human { pub fn rest(&self) { } }
# pub fn make_me_a_farm() -> Farm { Farm { chickens: ~[], farmer: Human(0) } }
pub struct Farm {
priv chickens: ~[Chicken],
Expand Down
25 changes: 17 additions & 8 deletions src/libextra/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,8 @@ impl<Q:Send> Sem<Q> {
pub fn acquire(&self) {
unsafe {
let mut waiter_nobe = None;
(**self).with(|state| {
let Sem(ref lock) = *self;
lock.with(|state| {
state.count -= 1;
if state.count < 0 {
// Create waiter nobe, enqueue ourself, and tell
Expand All @@ -126,7 +127,8 @@ impl<Q:Send> Sem<Q> {

pub fn release(&self) {
unsafe {
(**self).with(|state| {
let Sem(ref lock) = *self;
lock.with(|state| {
state.count += 1;
if state.count <= 0 {
state.waiters.signal();
Expand Down Expand Up @@ -206,7 +208,8 @@ impl<'a> Condvar<'a> {
let mut out_of_bounds = None;
// Release lock, 'atomically' enqueuing ourselves in so doing.
unsafe {
(**self.sem).with(|state| {
let Sem(ref queue) = *self.sem;
queue.with(|state| {
if condvar_id < state.blocked.len() {
// Drop the lock.
state.count += 1;
Expand Down Expand Up @@ -248,7 +251,8 @@ impl<'a> Condvar<'a> {
unsafe {
let mut out_of_bounds = None;
let mut result = false;
(**self.sem).with(|state| {
let Sem(ref lock) = *self.sem;
lock.with(|state| {
if condvar_id < state.blocked.len() {
result = state.blocked[condvar_id].signal();
} else {
Expand All @@ -270,7 +274,8 @@ impl<'a> Condvar<'a> {
let mut out_of_bounds = None;
let mut queue = None;
unsafe {
(**self.sem).with(|state| {
let Sem(ref lock) = *self.sem;
lock.with(|state| {
if condvar_id < state.blocked.len() {
// To avoid :broadcast_heavy, we make a new waitqueue,
// swap it out with the old one, and broadcast on the
Expand Down Expand Up @@ -336,7 +341,8 @@ pub struct Semaphore { priv sem: Sem<()> }
impl Clone for Semaphore {
/// Create a new handle to the semaphore.
fn clone(&self) -> Semaphore {
Semaphore { sem: Sem((*self.sem).clone()) }
let Sem(ref lock) = self.sem;
Semaphore { sem: Sem(lock.clone()) }
}
}

Expand Down Expand Up @@ -378,7 +384,9 @@ impl Semaphore {
pub struct Mutex { priv sem: Sem<~[WaitQueue]> }
impl Clone for Mutex {
/// Create a new handle to the mutex.
fn clone(&self) -> Mutex { Mutex { sem: Sem((*self.sem).clone()) } }
fn clone(&self) -> Mutex {
let Sem(ref queue) = self.sem;
Mutex { sem: Sem(queue.clone()) } }
}

impl Mutex {
Expand Down Expand Up @@ -467,8 +475,9 @@ impl RWLock {

/// Create a new handle to the rwlock.
pub fn clone(&self) -> RWLock {
let Sem(ref access_lock_queue) = self.access_lock;
RWLock { order_lock: (&(self.order_lock)).clone(),
access_lock: Sem((*self.access_lock).clone()),
access_lock: Sem(access_lock_queue.clone()),
state: self.state.clone() }
}

Expand Down
20 changes: 15 additions & 5 deletions src/libextra/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,8 @@ pub struct MetricMap(TreeMap<~str,Metric>);

impl Clone for MetricMap {
fn clone(&self) -> MetricMap {
MetricMap((**self).clone())
let MetricMap(ref map) = *self;
MetricMap(map.clone())
}
}

Expand Down Expand Up @@ -584,6 +585,7 @@ impl<T: Writer> ConsoleTestState<T> {
}

pub fn fmt_metrics(mm: &MetricMap) -> ~str {
let MetricMap(ref mm) = *mm;
let v : ~[~str] = mm.iter()
.map(|(k,v)| format!("{}: {} (+/- {})",
*k,
Expand Down Expand Up @@ -622,6 +624,7 @@ pub fn run_tests_console(opts: &TestOpts,
TrIgnored => st.ignored += 1,
TrMetrics(mm) => {
let tname = test.name.to_str();
let MetricMap(mm) = mm;
for (k,v) in mm.iter() {
st.metrics.insert_metric(tname + "." + *k,
v.value, v.noise);
Expand Down Expand Up @@ -950,7 +953,8 @@ impl MetricMap {
/// Write MetricDiff to a file.
pub fn save(&self, p: &Path) {
let mut file = File::create(p);
self.to_json().to_pretty_writer(&mut file)
let MetricMap(ref map) = *self;
map.to_json().to_pretty_writer(&mut file)
}

/// Compare against another MetricMap. Optionally compare all
Expand All @@ -962,8 +966,10 @@ impl MetricMap {
pub fn compare_to_old(&self, old: &MetricMap,
noise_pct: Option<f64>) -> MetricDiff {
let mut diff : MetricDiff = TreeMap::new();
let MetricMap(ref selfmap) = *self;
let MetricMap(ref old) = *old;
for (k, vold) in old.iter() {
let r = match self.find(k) {
let r = match selfmap.find(k) {
None => MetricRemoved,
Some(v) => {
let delta = (v.value - vold.value);
Expand Down Expand Up @@ -999,7 +1005,8 @@ impl MetricMap {
};
diff.insert((*k).clone(), r);
}
for (k, _) in self.iter() {
let MetricMap(ref map) = *self;
for (k, _) in map.iter() {
if !diff.contains_key(k) {
diff.insert((*k).clone(), MetricAdded);
}
Expand All @@ -1025,7 +1032,8 @@ impl MetricMap {
value: value,
noise: noise
};
self.insert(name.to_owned(), m);
let MetricMap(ref mut map) = *self;
map.insert(name.to_owned(), m);
}

/// Attempt to "ratchet" an external metric file. This involves loading
Expand Down Expand Up @@ -1464,6 +1472,7 @@ mod tests {

// Check that it was not rewritten.
let m3 = MetricMap::load(&pth);
let MetricMap(m3) = m3;
assert_eq!(m3.len(), 2);
assert_eq!(*(m3.find(&~"runtime").unwrap()), Metric { value: 1000.0, noise: 2.0 });
assert_eq!(*(m3.find(&~"throughput").unwrap()), Metric { value: 50.0, noise: 2.0 });
Expand All @@ -1478,6 +1487,7 @@ mod tests {

// Check that it was rewritten.
let m4 = MetricMap::load(&pth);
let MetricMap(m4) = m4;
assert_eq!(m4.len(), 2);
assert_eq!(*(m4.find(&~"runtime").unwrap()), Metric { value: 1100.0, noise: 2.0 });
assert_eq!(*(m4.find(&~"throughput").unwrap()), Metric { value: 50.0, noise: 2.0 });
Expand Down
21 changes: 14 additions & 7 deletions src/libextra/workcache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,13 +116,14 @@ impl WorkMap {

fn insert_work_key(&mut self, k: WorkKey, val: ~str) {
let WorkKey { kind, name } = k;
match self.find_mut(&name) {
let WorkMap(ref mut map) = *self;
match map.find_mut(&name) {
Some(&KindMap(ref mut m)) => { m.insert(kind, val); return; }
None => ()
}
let mut new_map = TreeMap::new();
new_map.insert(kind, val);
self.insert(name, KindMap(new_map));
map.insert(name, KindMap(new_map));
}
}

Expand Down Expand Up @@ -328,8 +329,10 @@ impl Exec {
// returns pairs of (kind, name)
pub fn lookup_discovered_inputs(&self) -> ~[(~str, ~str)] {
let mut rs = ~[];
for (k, v) in self.discovered_inputs.iter() {
for (k1, _) in v.iter() {
let WorkMap(ref discovered_inputs) = self.discovered_inputs;
for (k, v) in discovered_inputs.iter() {
let KindMap(ref vmap) = *v;
for (k1, _) in vmap.iter() {
rs.push((k1.clone(), k.clone()));
}
}
Expand All @@ -348,8 +351,10 @@ impl<'a> Prep<'a> {

pub fn lookup_declared_inputs(&self) -> ~[~str] {
let mut rs = ~[];
for (_, v) in self.declared_inputs.iter() {
for (inp, _) in v.iter() {
let WorkMap(ref declared_inputs) = self.declared_inputs;
for (_, v) in declared_inputs.iter() {
let KindMap(ref vmap) = *v;
for (inp, _) in vmap.iter() {
rs.push(inp.clone());
}
}
Expand Down Expand Up @@ -386,8 +391,10 @@ impl<'a> Prep<'a> {
}

fn all_fresh(&self, cat: &str, map: &WorkMap) -> bool {
let WorkMap(ref map) = *map;
for (k_name, kindmap) in map.iter() {
for (k_kind, v) in kindmap.iter() {
let KindMap(ref kindmap_) = *kindmap;
for (k_kind, v) in kindmap_.iter() {
if ! self.is_fresh(cat, *k_kind, *k_name, *v) {
return false;
}
Expand Down
4 changes: 2 additions & 2 deletions src/libgreen/stack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,11 @@ pub struct StackPool(());
impl StackPool {
pub fn new() -> StackPool { StackPool(()) }

fn take_segment(&self, min_size: uint) -> StackSegment {
pub fn take_segment(&self, min_size: uint) -> StackSegment {
StackSegment::new(min_size)
}

fn give_segment(&self, _stack: StackSegment) {
pub fn give_segment(&self, _stack: StackSegment) {
}
}

Expand Down
34 changes: 23 additions & 11 deletions src/librustc/middle/borrowck/move_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,15 @@ pub struct FlowedMoveData {
#[deriving(Eq)]
pub struct MovePathIndex(uint);

impl MovePathIndex {
fn get(&self) -> uint {
let MovePathIndex(v) = *self; v
}
}

impl Clone for MovePathIndex {
fn clone(&self) -> MovePathIndex {
MovePathIndex(**self)
MovePathIndex(self.get())
}
}

Expand All @@ -85,6 +91,12 @@ static InvalidMovePathIndex: MovePathIndex =
#[deriving(Eq)]
pub struct MoveIndex(uint);

impl MoveIndex {
fn get(&self) -> uint {
let MoveIndex(v) = *self; v
}
}

static InvalidMoveIndex: MoveIndex =
MoveIndex(uint::max_value);

Expand Down Expand Up @@ -177,47 +189,47 @@ impl MoveData {

fn path_loan_path(&self, index: MovePathIndex) -> @LoanPath {
let paths = self.paths.borrow();
paths.get()[*index].loan_path
paths.get()[index.get()].loan_path
}

fn path_parent(&self, index: MovePathIndex) -> MovePathIndex {
let paths = self.paths.borrow();
paths.get()[*index].parent
paths.get()[index.get()].parent
}

fn path_first_move(&self, index: MovePathIndex) -> MoveIndex {
let paths = self.paths.borrow();
paths.get()[*index].first_move
paths.get()[index.get()].first_move
}

fn path_first_child(&self, index: MovePathIndex) -> MovePathIndex {
let paths = self.paths.borrow();
paths.get()[*index].first_child
paths.get()[index.get()].first_child
}

fn path_next_sibling(&self, index: MovePathIndex) -> MovePathIndex {
let paths = self.paths.borrow();
paths.get()[*index].next_sibling
paths.get()[index.get()].next_sibling
}

fn set_path_first_move(&self,
index: MovePathIndex,
first_move: MoveIndex) {
let mut paths = self.paths.borrow_mut();
paths.get()[*index].first_move = first_move
paths.get()[index.get()].first_move = first_move
}

fn set_path_first_child(&self,
index: MovePathIndex,
first_child: MovePathIndex) {
let mut paths = self.paths.borrow_mut();
paths.get()[*index].first_child = first_child
paths.get()[index.get()].first_child = first_child
}

fn move_next_move(&self, index: MoveIndex) -> MoveIndex {
//! Type safe indexing operator
let moves = self.moves.borrow();
moves.get()[*index].next_move
moves.get()[index.get()].next_move
}

fn is_var_path(&self, index: MovePathIndex) -> bool {
Expand Down Expand Up @@ -291,7 +303,7 @@ impl MoveData {
index);

let paths = self.paths.borrow();
assert_eq!(*index, paths.get().len() - 1);
assert_eq!(index.get(), paths.get().len() - 1);

let mut path_map = self.path_map.borrow_mut();
path_map.get().insert(lp, index);
Expand Down Expand Up @@ -549,7 +561,7 @@ impl MoveData {
kill_id: ast::NodeId,
dfcx_moves: &mut MoveDataFlow) {
self.each_applicable_move(path, |move_index| {
dfcx_moves.add_kill(kill_id, *move_index);
dfcx_moves.add_kill(kill_id, move_index.get());
true
});
}
Expand Down
Loading