Skip to content
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

Plucked cherries for 1.1 #26409

Merged
merged 5 commits into from
Jun 18, 2015
Merged
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
107 changes: 101 additions & 6 deletions RELEASES.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
Version 1.1.0 (July 2015)
========================
Version 1.1.0 (June 2015)
=========================

* NNNN changes, numerous bugfixes
* ~850 changes, numerous bugfixes

Libraries
---------
Highlights
----------

* The [`std::fs` module has been expanded][fs-expand] to expand the set of
functionality exposed:
Expand All @@ -13,8 +13,103 @@ Libraries
* A `symlink_metadata` function has been added.
* The `fs::Metadata` structure now lowers to its OS counterpart, providing
access to all underlying information.
* The compiler contains extended explanations of many errors. When it
emits such an error it also suggests using the `--explain` flag to
read the extended explanations, which are also [cataloged on the web
site][err].
* Thanks to multiple [improvements][sk] to [type checking][pre], as
well as other work, the time to bootstrap the compiler decreased by
32%.

Libraries
---------

* The `str::split_whitespace` method splits a string on unicode
whitespace boundaries.
* On both Windows and Unix, new extension traits provide conversion of
I/O types to and from the underlying system handles. On Unix, these
traits are [`FrowRawFd`] and [`AsRawFd`], on Windows `FromRawHandle`
and `AsRawHandle`. These are implemented for `File`, `TcpStream`,
`TcpListener`, and `UpdSocket`. Further implementations for
`std::process` will be stabilized later.
* On Unix, [`std::os::unix::symlink`] creates symlinks. On
Windows, symlinks can be created with
`std::os::windows::symlink_dir` and
`std::os::windows::symlink_file`.
* The `mpsc::Receiver` type can now be converted into an iterator with
`into_iter` on the [`IntoIterator`] trait.
* `Ipv4Addr` can be created from `u32` with the `From<u32>`
implementation of the [`From`] trait.
* The `Debug` implementation for `RangeFull` [creates output that is
more consistent with other implementations][rf].
* [`Debug` is implemented for `File`][file].
* The `Default` implementation for `Arc` [no longer requires `Sync +
Send`][arc].
* [The `Iterator` methods `count`, `nth`, and `last` have been
overridden for slices to have O(1) performance instead of O(n)][si].
* Incorrect handling of paths on Windows has been improved in both the
compiler and the standard library.
* [`AtomicPtr` gained a `Default` implementation][ap].
* In accordance with Rust's policy on arithmetic overflow `abs` now
[panics on overflow when debug assertions are enabled][abs].
* The [`Cloned`] iterator, which was accidentally left unstable for
1.0 [has been stabilized][c].
* The [`Incoming`] iterator, which iterates over incoming TCP
connections, and which was accidentally unnamable in 1.0, [is now
properly exported][inc].
* [`BinaryHeap`] no longer corrupts itself [when functions called by
`sift_up` or `sift_down` panic][bh].
* The [`split_off`] method of `LinkedList` [no longer corrupts
the list in certain scenarios][ll].

Misc
----

[fs-expand]: https://github.com/rust-lang/rust/pull/25844
* Type checking performance [has improved notably][sk] with
[multiple improvements][pre].
* The compiler [suggests code changes][ch] for more errors.
* rustc and it's build system have experimental support for [building
toolchains against MUSL][m] instead of glibc on Linux.
* The compiler defines the `target_env` cfg value, which is used for
distinguishing toolchains that are otherwise for the same
platform. Presently this is set to `gnu` for common GNU Linux
targets and for MinGW targets, and `musl` for MUSL Linux targets.
* The [`cargo rustc`][crc] command invokes a build with custom flags
to rustc.
* [Android executables are always position independent][pie].
* [The `drop_with_repr_extern` lint warns about mixing `repr(C)`
with `Drop`][drop].

[`split_whitespace`]: http://doc.rust-lang.org/nightly/std/primitive.str.html#method.split_whitespace
[`Iterator::cloned`]: http://doc.rust-lang.org/nightly/core/iter/trait.Iterator.html#method.cloned
[`FromRawFd`]: http://doc.rust-lang.org/nightly/std/os/unix/io/trait.FromRawFd.html
[`AsRawFd`]: http://doc.rust-lang.org/nightly/std/os/unix/io/trait.AsRawFd.html
[`std::os::unix::symlink`]: http://doc.rust-lang.org/nightly/std/os/unix/fs/fn.symlink.html
[`IntoIterator`]: http://doc.rust-lang.org/nightly/std/iter/trait.IntoIterator.html
[`From`]: http://doc.rust-lang.org/nightly/std/convert/trait.From.html
[rf]: https://github.com/rust-lang/rust/pull/24491
[err]: http://doc.rust-lang.org/error-index.html
[sk]: https://github.com/rust-lang/rust/pull/24615
[pre]: https://github.com/rust-lang/rust/pull/25323
[file]: https://github.com/rust-lang/rust/pull/24598
[ch]: https://github.com/rust-lang/rust/pull/24683
[arc]: https://github.com/rust-lang/rust/pull/24695
[si]: https://github.com/rust-lang/rust/pull/24701
[ap]: https://github.com/rust-lang/rust/pull/24834
[m]: https://github.com/rust-lang/rust/pull/24777
[fs]: https://github.com/rust-lang/rfcs/blob/master/text/1044-io-fs-2.1.md
[crc]: https://github.com/rust-lang/cargo/pull/1568
[pie]: https://github.com/rust-lang/rust/pull/24953
[abs]: https://github.com/rust-lang/rust/pull/25441
[c]: https://github.com/rust-lang/rust/pull/25496
[`Cloned`]: http://doc.rust-lang.org/nightly/std/iter/struct.Cloned.html
[`Incoming`]: http://doc.rust-lang.org/nightly/std/net/struct.Incoming.html
[inc]: https://github.com/rust-lang/rust/pull/25522
[bh]: https://github.com/rust-lang/rust/pull/25856
[`BinaryHeap`]: http://doc.rust-lang.org/nightly/std/collections/struct.BinaryHeap.html
[ll]: https://github.com/rust-lang/rust/pull/26022
[`split_off`]: http://doc.rust-lang.org/nightly/collections/linked_list/struct.LinkedList.html#method.split_off
[drop]: https://github.com/rust-lang/rust/pull/24935

Version 1.0.0 (May 2015)
========================
Expand Down
7 changes: 7 additions & 0 deletions src/librustc_trans/trans/cleanup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -954,8 +954,15 @@ impl<'blk, 'tcx> CleanupScope<'blk, 'tcx> {
}
}

/// Manipulate cleanup scope for call arguments. Conceptually, each
/// argument to a call is an lvalue, and performing the call moves each
/// of the arguments into a new rvalue (which gets cleaned up by the
/// callee). As an optimization, instead of actually performing all of
/// those moves, trans just manipulates the cleanup scope to obtain the
/// same effect.
pub fn drop_non_lifetime_clean(&mut self) {
self.cleanups.retain(|c| c.is_lifetime_end());
self.clear_cached_exits();
}
}

Expand Down
97 changes: 44 additions & 53 deletions src/libsyntax/codemap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
//! within the CodeMap, which upon request can be converted to line and column
//! information, source code snippets, etc.

pub use self::MacroFormat::*;
pub use self::ExpnFormat::*;

use std::cell::RefCell;
use std::ops::{Add, Sub};
Expand Down Expand Up @@ -226,17 +226,17 @@ pub struct FileMapAndBytePos { pub fm: Rc<FileMap>, pub pos: BytePos }


// _____________________________________________________________________________
// MacroFormat, NameAndSpan, ExpnInfo, ExpnId
// ExpnFormat, NameAndSpan, ExpnInfo, ExpnId
//

/// The syntax with which a macro was invoked.
#[derive(Clone, Copy, Hash, Debug)]
pub enum MacroFormat {
/// The source of expansion.
#[derive(Clone, Copy, Hash, Debug, PartialEq, Eq)]
pub enum ExpnFormat {
/// e.g. #[derive(...)] <item>
MacroAttribute,
/// e.g. `format!()`
MacroBang,
/// Expansion performed by the compiler (libsyntax::expand).
/// Syntax sugar expansion performed by the compiler (libsyntax::expand).
CompilerExpansion,
}

Expand All @@ -246,7 +246,7 @@ pub struct NameAndSpan {
/// with this Span.
pub name: String,
/// The format with which the macro was invoked.
pub format: MacroFormat,
pub format: ExpnFormat,
/// Whether the macro is allowed to use #[unstable]/feature-gated
/// features internally without forcing the whole crate to opt-in
/// to them.
Expand All @@ -257,11 +257,11 @@ pub struct NameAndSpan {
pub span: Option<Span>
}

/// Extra information for tracking macro expansion of spans
/// Extra information for tracking spans of macro and syntax sugar expansion
#[derive(Hash, Debug)]
pub struct ExpnInfo {
/// The location of the actual macro invocation, e.g. `let x =
/// foo!();`
/// The location of the actual macro invocation or syntax sugar , e.g.
/// `let x = foo!();` or `if let Some(y) = x {}`
///
/// This may recursively refer to other macro invocations, e.g. if
/// `foo!()` invoked `bar!()` internally, and there was an
Expand All @@ -270,12 +270,7 @@ pub struct ExpnInfo {
/// call_site span would have its own ExpnInfo, with the call_site
/// pointing to the `foo!` invocation.
pub call_site: Span,
/// Information about the macro and its definition.
///
/// The `callee` of the inner expression in the `call_site`
/// example would point to the `macro_rules! bar { ... }` and that
/// of the `bar!()` invocation would point to the `macro_rules!
/// foo { ... }`.
/// Information about the expansion.
pub callee: NameAndSpan
}

Expand Down Expand Up @@ -633,7 +628,39 @@ impl CodeMap {

/// Lookup source information about a BytePos
pub fn lookup_char_pos(&self, pos: BytePos) -> Loc {
self.lookup_pos(pos)
let FileMapAndLine {fm: f, line: a} = self.lookup_line(pos);
let line = a + 1; // Line numbers start at 1
let chpos = self.bytepos_to_file_charpos(pos);
let linebpos = (*f.lines.borrow())[a];
let linechpos = self.bytepos_to_file_charpos(linebpos);
debug!("byte pos {:?} is on the line at byte pos {:?}",
pos, linebpos);
debug!("char pos {:?} is on the line at char pos {:?}",
chpos, linechpos);
debug!("byte is on line: {}", line);
assert!(chpos >= linechpos);
Loc {
file: f,
line: line,
col: chpos - linechpos
}
}

fn lookup_line(&self, pos: BytePos) -> FileMapAndLine {
let idx = self.lookup_filemap_idx(pos);

let files = self.files.borrow();
let f = (*files)[idx].clone();
let mut a = 0;
{
let lines = f.lines.borrow();
let mut b = lines.len();
while b - a > 1 {
let m = (a + b) / 2;
if (*lines)[m] > pos { b = m; } else { a = m; }
}
}
FileMapAndLine {fm: f, line: a}
}

pub fn lookup_char_pos_adj(&self, pos: BytePos) -> LocWithOpt {
Expand Down Expand Up @@ -833,42 +860,6 @@ impl CodeMap {
return a;
}

fn lookup_line(&self, pos: BytePos) -> FileMapAndLine {
let idx = self.lookup_filemap_idx(pos);

let files = self.files.borrow();
let f = (*files)[idx].clone();
let mut a = 0;
{
let lines = f.lines.borrow();
let mut b = lines.len();
while b - a > 1 {
let m = (a + b) / 2;
if (*lines)[m] > pos { b = m; } else { a = m; }
}
}
FileMapAndLine {fm: f, line: a}
}

fn lookup_pos(&self, pos: BytePos) -> Loc {
let FileMapAndLine {fm: f, line: a} = self.lookup_line(pos);
let line = a + 1; // Line numbers start at 1
let chpos = self.bytepos_to_file_charpos(pos);
let linebpos = (*f.lines.borrow())[a];
let linechpos = self.bytepos_to_file_charpos(linebpos);
debug!("byte pos {:?} is on the line at byte pos {:?}",
pos, linebpos);
debug!("char pos {:?} is on the line at char pos {:?}",
chpos, linechpos);
debug!("byte is on line: {}", line);
assert!(chpos >= linechpos);
Loc {
file: f,
line: line,
col: chpos - linechpos
}
}

pub fn record_expansion(&self, expn_info: ExpnInfo) -> ExpnId {
let mut expansions = self.expansions.borrow_mut();
expansions.push(expn_info);
Expand Down
39 changes: 23 additions & 16 deletions src/libsyntax/ext/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ pub use self::SyntaxExtension::*;
use ast;
use ast::Name;
use codemap;
use codemap::{CodeMap, Span, ExpnId, ExpnInfo, NO_EXPANSION};
use codemap::{CodeMap, Span, ExpnId, ExpnInfo, NO_EXPANSION, CompilerExpansion};
use ext;
use ext::expand;
use ext::tt::macro_rules;
Expand Down Expand Up @@ -658,6 +658,8 @@ impl<'a> ExtCtxt<'a> {
})
}
pub fn backtrace(&self) -> ExpnId { self.backtrace }

/// Original span that caused the current exapnsion to happen.
pub fn original_span(&self) -> Span {
let mut expn_id = self.backtrace;
let mut call_site = None;
Expand All @@ -672,26 +674,31 @@ impl<'a> ExtCtxt<'a> {
}
call_site.expect("missing expansion backtrace")
}
pub fn original_span_in_file(&self) -> Span {

/// Returns span for the macro which originally caused the current expansion to happen.
///
/// Stops backtracing at include! boundary.
pub fn expansion_cause(&self) -> Span {
let mut expn_id = self.backtrace;
let mut call_site = None;
let mut last_macro = None;
loop {
let expn_info = self.codemap().with_expn_info(expn_id, |ei| {
ei.map(|ei| (ei.call_site, ei.callee.name == "include"))
});
match expn_info {
None => break,
Some((cs, is_include)) => {
if is_include {
// Don't recurse into file using "include!".
break;
if self.codemap().with_expn_info(expn_id, |info| {
info.map_or(None, |i| {
if i.callee.name == "include" {
// Stop going up the backtrace once include! is encountered
return None;
}
call_site = Some(cs);
expn_id = cs.expn_id;
}
expn_id = i.call_site.expn_id;
if i.callee.format != CompilerExpansion {
last_macro = Some(i.call_site)
}
return Some(());
})
}).is_none() {
break
}
}
call_site.expect("missing expansion backtrace")
last_macro.expect("missing expansion backtrace")
}

pub fn mod_push(&mut self, i: ast::Ident) { self.mod_path.push(i); }
Expand Down
6 changes: 3 additions & 3 deletions src/libsyntax/ext/source_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ pub fn expand_line(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
-> Box<base::MacResult+'static> {
base::check_zero_tts(cx, sp, tts, "line!");

let topmost = cx.original_span_in_file();
let topmost = cx.expansion_cause();
let loc = cx.codemap().lookup_char_pos(topmost.lo);

base::MacEager::expr(cx.expr_u32(topmost, loc.line as u32))
Expand All @@ -45,7 +45,7 @@ pub fn expand_column(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
-> Box<base::MacResult+'static> {
base::check_zero_tts(cx, sp, tts, "column!");

let topmost = cx.original_span_in_file();
let topmost = cx.expansion_cause();
let loc = cx.codemap().lookup_char_pos(topmost.lo);

base::MacEager::expr(cx.expr_u32(topmost, loc.col.to_usize() as u32))
Expand All @@ -58,7 +58,7 @@ pub fn expand_file(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
-> Box<base::MacResult+'static> {
base::check_zero_tts(cx, sp, tts, "file!");

let topmost = cx.original_span_in_file();
let topmost = cx.expansion_cause();
let loc = cx.codemap().lookup_char_pos(topmost.lo);
let filename = token::intern_and_get_ident(&loc.file.name);
base::MacEager::expr(cx.expr_str(topmost, filename))
Expand Down
Loading