Skip to content

libsyntax: Tighten up expressions in patterns #6417

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 6 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
81 changes: 40 additions & 41 deletions doc/rust.md
Original file line number Diff line number Diff line change
Expand Up @@ -618,7 +618,7 @@ each of which may have some number of [attributes](#attributes) attached to it.

~~~~~~~~ {.ebnf .gram}
item : mod_item | fn_item | type_item | struct_item | enum_item
| static_item | trait_item | impl_item | foreign_mod_item ;
| static_item | trait_item | impl_item | extern_block ;
~~~~~~~~

An _item_ is a component of a crate; some module items can be defined in crate
Expand Down Expand Up @@ -752,10 +752,11 @@ link_attr : ident '=' literal ;
~~~~~~~~

An _`extern mod` declaration_ specifies a dependency on an external crate.
The external crate is then bound into the declaring scope as the `ident` provided in the `extern_mod_decl`.
The external crate is then bound into the declaring scope
as the `ident` provided in the `extern_mod_decl`.

The external crate is resolved to a specific `soname` at compile time, and a
runtime linkage requirement to that `soname` is passed to the linker for
The external crate is resolved to a specific `soname` at compile time,
and a runtime linkage requirement to that `soname` is passed to the linker for
loading at runtime. The `soname` is resolved at compile time by scanning the
compiler's library path and matching the `link_attrs` provided in the
`use_decl` against any `#link` attributes that were declared on the external
Expand Down Expand Up @@ -992,10 +993,10 @@ Thus the return type on `f` only needs to reflect the `if` branch of the conditi
#### Extern functions

Extern functions are part of Rust's foreign function interface,
providing the opposite functionality to [foreign modules](#foreign-modules).
Whereas foreign modules allow Rust code to call foreign code,
extern functions with bodies defined in Rust code _can be called by foreign code_.
They are defined in the same way as any other Rust function,
providing the opposite functionality to [external blocks](#external-blocks).
Whereas external blocks allow Rust code to call foreign code,
extern functions with bodies defined in Rust code _can be called by foreign
code_. They are defined in the same way as any other Rust function,
except that they have the `extern` modifier.

~~~
Expand All @@ -1011,7 +1012,8 @@ let fptr: *u8 = new_vec;
~~~

The primary motivation for extern functions is
to create callbacks for foreign functions that expect to receive function pointers.
to create callbacks for foreign functions that expect to receive function
pointers.

### Type definitions

Expand Down Expand Up @@ -1308,64 +1310,61 @@ impl Seq<bool> for u32 {
}
~~~~

### Foreign modules
### External blocks

~~~ {.ebnf .gram}
foreign_mod_item : "extern mod" ident '{' foreign_mod '} ;
foreign_mod : [ foreign_fn ] * ;
extern_block_item : "extern" '{' extern_block '} ;
extern_block : [ foreign_fn ] * ;
~~~

Foreign modules form the basis for Rust's foreign function interface. A
foreign module describes functions in external, non-Rust
libraries.
Functions within foreign modules are declared in the same way as other Rust functions,
with the exception that they may not have a body and are instead terminated by a semicolon.
External blocks form the basis for Rust's foreign function interface.
Declarations in an external block describe symbols
in external, non-Rust libraries.

Functions within external blocks
are declared in the same way as other Rust functions,
with the exception that they may not have a body
and are instead terminated by a semicolon.

~~~
# use core::libc::{c_char, FILE};
# #[nolink]

extern mod c {
extern {
fn fopen(filename: *c_char, mode: *c_char) -> *FILE;
}
~~~

Functions within foreign modules may be called by Rust code, just like functions defined in Rust.
The Rust compiler automatically translates between the Rust ABI and the foreign ABI.

The name of the foreign module has special meaning to the Rust compiler in
that it will treat the module name as the name of a library to link to,
performing the linking as appropriate for the target platform. The name
given for the foreign module will be transformed in a platform-specific way
to determine the name of the library. For example, on Linux the name of the
foreign module is prefixed with 'lib' and suffixed with '.so', so the
foreign mod 'rustrt' would be linked to a library named 'librustrt.so'.
Functions within external blocks may be called by Rust code,
just like functions defined in Rust.
The Rust compiler automatically translates
between the Rust ABI and the foreign ABI.

A number of [attributes](#attributes) control the behavior of foreign
modules.
A number of [attributes](#attributes) control the behavior of external
blocks.

By default foreign modules assume that the library they are calling use the
standard C "cdecl" ABI. Other ABIs may be specified using the `abi`
attribute as in
By default external blocks assume
that the library they are calling uses the standard C "cdecl" ABI.
Other ABIs may be specified using the `abi` attribute as in

~~~{.xfail-test}
// Interface to the Windows API
#[abi = "stdcall"]
extern mod kernel32 { }
extern { }
~~~

The `link_name` attribute allows the default library naming behavior to
be overridden by explicitly specifying the name of the library.
The `link_name` attribute allows the name of the library to be specified.

~~~{.xfail-test}
#[link_name = "crypto"]
extern mod mycrypto { }
extern { }
~~~

The `nolink` attribute tells the Rust compiler not to do any linking for the foreign module.
This is particularly useful for creating foreign
modules for libc, which tends to not follow standard library naming
conventions and is linked to all Rust programs anyway.
The `nolink` attribute tells the Rust compiler
not to do any linking for the external block.
This is particularly useful for creating external blocks for libc,
which tends to not follow standard library naming conventions
and is linked to all Rust programs anyway.

## Attributes

Expand Down
3 changes: 2 additions & 1 deletion doc/tutorial-ffi.md
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,8 @@ convention to use:
~~~~
#[cfg(target_os = "win32")]
#[abi = "stdcall"]
extern mod kernel32 {
#[link_name = "kernel32"]
extern {
fn SetEnvironmentVariableA(n: *u8, v: *u8) -> int;
}
~~~~
Expand Down
12 changes: 6 additions & 6 deletions src/libcore/cell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,21 +44,21 @@ pub fn empty_cell<T>() -> Cell<T> {
pub impl<T> Cell<T> {
/// Yields the value, failing if the cell is empty.
fn take(&self) -> T {
let self = unsafe { transmute_mut(self) };
if self.is_empty() {
let this = unsafe { transmute_mut(self) };
if this.is_empty() {
fail!(~"attempt to take an empty cell");
}

replace(&mut self.value, None).unwrap()
replace(&mut this.value, None).unwrap()
}

/// Returns the value, failing if the cell is full.
fn put_back(&self, value: T) {
let self = unsafe { transmute_mut(self) };
if !self.is_empty() {
let this = unsafe { transmute_mut(self) };
if !this.is_empty() {
fail!(~"attempt to put a value back into a full cell");
}
self.value = Some(value);
this.value = Some(value);
}

/// Returns true if the cell is empty and false if the cell is full.
Expand Down
10 changes: 5 additions & 5 deletions src/libcore/num/strconv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -486,11 +486,11 @@ pub fn from_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Copy+Div<T,T>+
}
}

let (start, accum_positive) = match buf[0] {
'-' as u8 if !negative => return None,
'-' as u8 => (1u, false),
'+' as u8 => (1u, true),
_ => (0u, true)
let (start, accum_positive) = match buf[0] as char {
'-' if !negative => return None,
'-' => (1u, false),
'+' => (1u, true),
_ => (0u, true)
};

// Initialize accumulator with signed zero for floating point parsing to
Expand Down
80 changes: 43 additions & 37 deletions src/libcore/old_iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,66 +116,72 @@ pub trait Buildable<A> {
}

#[inline(always)]
pub fn _eachi<A,IA:BaseIter<A>>(self: &IA, blk: &fn(uint, &A) -> bool) -> bool {
pub fn _eachi<A,IA:BaseIter<A>>(this: &IA, blk: &fn(uint, &A) -> bool) -> bool {
let mut i = 0;
for self.each |a| {
if !blk(i, a) { return false; }
for this.each |a| {
if !blk(i, a) {
return false;
}
i += 1;
}
return true;
}

#[cfg(stage0)]
pub fn eachi<A,IA:BaseIter<A>>(self: &IA, blk: &fn(uint, &A) -> bool) {
_eachi(self, blk);
pub fn eachi<A,IA:BaseIter<A>>(this: &IA, blk: &fn(uint, &A) -> bool) {
_eachi(this, blk);
}
#[cfg(not(stage0))]
pub fn eachi<A,IA:BaseIter<A>>(self: &IA, blk: &fn(uint, &A) -> bool) -> bool {
_eachi(self, blk)
pub fn eachi<A,IA:BaseIter<A>>(this: &IA, blk: &fn(uint, &A) -> bool) -> bool {
_eachi(this, blk)
}

#[inline(always)]
pub fn all<A,IA:BaseIter<A>>(self: &IA, blk: &fn(&A) -> bool) -> bool {
for self.each |a| {
if !blk(a) { return false; }
pub fn all<A,IA:BaseIter<A>>(this: &IA, blk: &fn(&A) -> bool) -> bool {
for this.each |a| {
if !blk(a) {
return false;
}
}
return true;
}

#[inline(always)]
pub fn any<A,IA:BaseIter<A>>(self: &IA, blk: &fn(&A) -> bool) -> bool {
for self.each |a| {
if blk(a) { return true; }
pub fn any<A,IA:BaseIter<A>>(this: &IA, blk: &fn(&A) -> bool) -> bool {
for this.each |a| {
if blk(a) {
return true;
}
}
return false;
}

#[inline(always)]
pub fn filter_to_vec<A:Copy,IA:BaseIter<A>>(self: &IA,
pub fn filter_to_vec<A:Copy,IA:BaseIter<A>>(this: &IA,
prd: &fn(&A) -> bool)
-> ~[A] {
do vec::build_sized_opt(self.size_hint()) |push| {
for self.each |a| {
do vec::build_sized_opt(this.size_hint()) |push| {
for this.each |a| {
if prd(a) { push(*a); }
}
}
}

#[inline(always)]
pub fn map_to_vec<A,B,IA:BaseIter<A>>(self: &IA, op: &fn(&A) -> B) -> ~[B] {
do vec::build_sized_opt(self.size_hint()) |push| {
for self.each |a| {
pub fn map_to_vec<A,B,IA:BaseIter<A>>(this: &IA, op: &fn(&A) -> B) -> ~[B] {
do vec::build_sized_opt(this.size_hint()) |push| {
for this.each |a| {
push(op(a));
}
}
}

#[inline(always)]
pub fn flat_map_to_vec<A,B,IA:BaseIter<A>,IB:BaseIter<B>>(self: &IA,
pub fn flat_map_to_vec<A,B,IA:BaseIter<A>,IB:BaseIter<B>>(this: &IA,
op: &fn(&A) -> IB)
-> ~[B] {
do vec::build |push| {
for self.each |a| {
for this.each |a| {
for op(a).each |&b| {
push(b);
}
Expand All @@ -184,31 +190,31 @@ pub fn flat_map_to_vec<A,B,IA:BaseIter<A>,IB:BaseIter<B>>(self: &IA,
}

#[inline(always)]
pub fn foldl<A,B,IA:BaseIter<A>>(self: &IA, b0: B, blk: &fn(&B, &A) -> B)
pub fn foldl<A,B,IA:BaseIter<A>>(this: &IA, b0: B, blk: &fn(&B, &A) -> B)
-> B {
let mut b = b0;
for self.each |a| {
for this.each |a| {
b = blk(&b, a);
}
b
}

#[inline(always)]
pub fn to_vec<A:Copy,IA:BaseIter<A>>(self: &IA) -> ~[A] {
map_to_vec(self, |&x| x)
pub fn to_vec<A:Copy,IA:BaseIter<A>>(this: &IA) -> ~[A] {
map_to_vec(this, |&x| x)
}

#[inline(always)]
pub fn contains<A:Eq,IA:BaseIter<A>>(self: &IA, x: &A) -> bool {
for self.each |a| {
pub fn contains<A:Eq,IA:BaseIter<A>>(this: &IA, x: &A) -> bool {
for this.each |a| {
if *a == *x { return true; }
}
return false;
}

#[inline(always)]
pub fn count<A:Eq,IA:BaseIter<A>>(self: &IA, x: &A) -> uint {
do foldl(self, 0) |count, value| {
pub fn count<A:Eq,IA:BaseIter<A>>(this: &IA, x: &A) -> uint {
do foldl(this, 0) |count, value| {
if *value == *x {
*count + 1
} else {
Expand All @@ -218,10 +224,10 @@ pub fn count<A:Eq,IA:BaseIter<A>>(self: &IA, x: &A) -> uint {
}

#[inline(always)]
pub fn position<A,IA:BaseIter<A>>(self: &IA, f: &fn(&A) -> bool)
pub fn position<A,IA:BaseIter<A>>(this: &IA, f: &fn(&A) -> bool)
-> Option<uint> {
let mut i = 0;
for self.each |a| {
for this.each |a| {
if f(a) { return Some(i); }
i += 1;
}
Expand Down Expand Up @@ -253,8 +259,8 @@ pub fn repeat(times: uint, blk: &fn() -> bool) -> bool {
}

#[inline(always)]
pub fn min<A:Copy + Ord,IA:BaseIter<A>>(self: &IA) -> A {
match do foldl::<A,Option<A>,IA>(self, None) |a, b| {
pub fn min<A:Copy + Ord,IA:BaseIter<A>>(this: &IA) -> A {
match do foldl::<A,Option<A>,IA>(this, None) |a, b| {
match a {
&Some(ref a_) if *a_ < *b => {
*(a)
Expand All @@ -268,8 +274,8 @@ pub fn min<A:Copy + Ord,IA:BaseIter<A>>(self: &IA) -> A {
}

#[inline(always)]
pub fn max<A:Copy + Ord,IA:BaseIter<A>>(self: &IA) -> A {
match do foldl::<A,Option<A>,IA>(self, None) |a, b| {
pub fn max<A:Copy + Ord,IA:BaseIter<A>>(this: &IA) -> A {
match do foldl::<A,Option<A>,IA>(this, None) |a, b| {
match a {
&Some(ref a_) if *a_ > *b => {
*(a)
Expand All @@ -283,9 +289,9 @@ pub fn max<A:Copy + Ord,IA:BaseIter<A>>(self: &IA) -> A {
}

#[inline(always)]
pub fn find<A:Copy,IA:BaseIter<A>>(self: &IA, f: &fn(&A) -> bool)
pub fn find<A:Copy,IA:BaseIter<A>>(this: &IA, f: &fn(&A) -> bool)
-> Option<A> {
for self.each |i| {
for this.each |i| {
if f(i) { return Some(*i) }
}
return None;
Expand Down
Loading