Skip to content

Commit

Permalink
Merge pull request #38884 from nikomatsakis/beta-unmerged
Browse files Browse the repository at this point in the history
More beta backports
  • Loading branch information
alexcrichton authored Jan 7, 2017
2 parents c80d225 + 793a395 commit 1e34b5e
Show file tree
Hide file tree
Showing 13 changed files with 264 additions and 40 deletions.
11 changes: 10 additions & 1 deletion src/bootstrap/doc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,16 @@ pub fn std(build: &Build, stage: u32, target: &str) {
cargo.arg("--manifest-path")
.arg(build.src.join("src/rustc/std_shim/Cargo.toml"))
.arg("--features").arg(build.std_features())
.arg("-p").arg("std");
.arg("--no-deps");

for krate in &["alloc", "collections", "core", "std", "std_unicode"] {
cargo.arg("-p").arg(krate);
// Create all crate output directories first to make sure rustdoc uses
// relative links.
// FIXME: Cargo should probably do this itself.
t!(fs::create_dir_all(out_dir.join(krate)));
}

build.run(&mut cargo);
cp_r(&out_dir, &out)
}
Expand Down
3 changes: 2 additions & 1 deletion src/librustc/session/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1172,7 +1172,8 @@ pub fn rustc_short_optgroups() -> Vec<RustcOptGroup> {
the compiler to emit",
"[asm|llvm-bc|llvm-ir|obj|link|dep-info]"),
opt::multi_s("", "print", "Comma separated list of compiler information to \
print on stdout", &print_opts.join("|")),
print on stdout", &format!("[{}]",
&print_opts.join("|"))),
opt::flagmulti_s("g", "", "Equivalent to -C debuginfo=2"),
opt::flagmulti_s("O", "", "Equivalent to -C opt-level=2"),
opt::opt_s("o", "", "Write output to <filename>", "FILENAME"),
Expand Down
6 changes: 5 additions & 1 deletion src/librustc_trans/mir/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,11 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
load
} else {
let op = self.trans_consume(&bcx, &mir::Lvalue::Local(mir::RETURN_POINTER));
op.pack_if_pair(&bcx).immediate()
if let Ref(llval) = op.val {
bcx.with_block(|bcx| base::load_ty(&bcx, llval, op.ty))
} else {
op.pack_if_pair(&bcx).immediate()
}
};
bcx.ret(llval);
}
Expand Down
9 changes: 8 additions & 1 deletion src/librustc_typeck/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4580,7 +4580,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
// Check provided lifetime parameters.
let lifetime_defs = segment.map_or(&[][..], |(_, generics)| &generics.regions);
if lifetimes.len() > lifetime_defs.len() {
let span = lifetimes[lifetime_defs.len()].span;
struct_span_err!(self.tcx.sess, span, E0088,
"too many lifetime parameters provided: \
expected {}, found {}",
Expand All @@ -4589,6 +4588,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
.span_label(span, &format!("unexpected lifetime parameter{}",
match lifetimes.len() { 1 => "", _ => "s" }))
.emit();
} else if lifetimes.len() > 0 && lifetimes.len() < lifetime_defs.len() {
struct_span_err!(self.tcx.sess, span, E0090,
"too few lifetime parameters provided: \
expected {}, found {}",
count(lifetime_defs.len()),
count(lifetimes.len()))
.span_label(span, &format!("too few lifetime parameters"))
.emit();
}

// The case where there is not enough lifetime parameters is not checked,
Expand Down
1 change: 1 addition & 0 deletions src/libstd/sys/windows/c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,7 @@ pub const EXCEPTION_STACK_OVERFLOW: DWORD = 0xc00000fd;
pub const EXCEPTION_MAXIMUM_PARAMETERS: usize = 15;

pub const PIPE_ACCESS_INBOUND: DWORD = 0x00000001;
pub const PIPE_ACCESS_OUTBOUND: DWORD = 0x00000002;
pub const FILE_FLAG_FIRST_PIPE_INSTANCE: DWORD = 0x00080000;
pub const FILE_FLAG_OVERLAPPED: DWORD = 0x40000000;
pub const PIPE_WAIT: DWORD = 0x00000000;
Expand Down
77 changes: 57 additions & 20 deletions src/libstd/sys/windows/pipe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,43 @@ pub struct AnonPipe {
inner: Handle,
}

pub fn anon_pipe() -> io::Result<(AnonPipe, AnonPipe)> {
pub struct Pipes {
pub ours: AnonPipe,
pub theirs: AnonPipe,
}

/// Although this looks similar to `anon_pipe` in the Unix module it's actually
/// subtly different. Here we'll return two pipes in the `Pipes` return value,
/// but one is intended for "us" where as the other is intended for "someone
/// else".
///
/// Currently the only use case for this function is pipes for stdio on
/// processes in the standard library, so "ours" is the one that'll stay in our
/// process whereas "theirs" will be inherited to a child.
///
/// The ours/theirs pipes are *not* specifically readable or writable. Each
/// one only supports a read or a write, but which is which depends on the
/// boolean flag given. If `ours_readable` is true then `ours` is readable where
/// `theirs` is writable. Conversely if `ours_readable` is false then `ours` is
/// writable where `theirs` is readable.
///
/// Also note that the `ours` pipe is always a handle opened up in overlapped
/// mode. This means that technically speaking it should only ever be used
/// with `OVERLAPPED` instances, but also works out ok if it's only ever used
/// once at a time (which we do indeed guarantee).
pub fn anon_pipe(ours_readable: bool) -> io::Result<Pipes> {
// Note that we specifically do *not* use `CreatePipe` here because
// unfortunately the anonymous pipes returned do not support overlapped
// operations.
//
// Instead, we create a "hopefully unique" name and create a named pipe
// which has overlapped operations enabled.
// operations. Instead, we create a "hopefully unique" name and create a
// named pipe which has overlapped operations enabled.
//
// Once we do this, we connect do it as usual via `CreateFileW`, and then we
// return those reader/writer halves.
// Once we do this, we connect do it as usual via `CreateFileW`, and then
// we return those reader/writer halves. Note that the `ours` pipe return
// value is always the named pipe, whereas `theirs` is just the normal file.
// This should hopefully shield us from child processes which assume their
// stdout is a named pipe, which would indeed be odd!
unsafe {
let reader;
let ours;
let mut name;
let mut tries = 0;
let mut reject_remote_clients_flag = c::PIPE_REJECT_REMOTE_CLIENTS;
Expand All @@ -54,11 +79,16 @@ pub fn anon_pipe() -> io::Result<(AnonPipe, AnonPipe)> {
.encode_wide()
.chain(Some(0))
.collect::<Vec<_>>();
let mut flags = c::FILE_FLAG_FIRST_PIPE_INSTANCE |
c::FILE_FLAG_OVERLAPPED;
if ours_readable {
flags |= c::PIPE_ACCESS_INBOUND;
} else {
flags |= c::PIPE_ACCESS_OUTBOUND;
}

let handle = c::CreateNamedPipeW(wide_name.as_ptr(),
c::PIPE_ACCESS_INBOUND |
c::FILE_FLAG_FIRST_PIPE_INSTANCE |
c::FILE_FLAG_OVERLAPPED,
flags,
c::PIPE_TYPE_BYTE |
c::PIPE_READMODE_BYTE |
c::PIPE_WAIT |
Expand Down Expand Up @@ -101,21 +131,28 @@ pub fn anon_pipe() -> io::Result<(AnonPipe, AnonPipe)> {
}
return Err(err)
}
reader = Handle::new(handle);
ours = Handle::new(handle);
break
}

// Connect to the named pipe we just created in write-only mode (also
// overlapped for async I/O below).
// Connect to the named pipe we just created. This handle is going to be
// returned in `theirs`, so if `ours` is readable we want this to be
// writable, otherwise if `ours` is writable we want this to be
// readable.
//
// Additionally we don't enable overlapped mode on this because most
// client processes aren't enabled to work with that.
let mut opts = OpenOptions::new();
opts.write(true);
opts.read(false);
opts.write(ours_readable);
opts.read(!ours_readable);
opts.share_mode(0);
opts.attributes(c::FILE_FLAG_OVERLAPPED);
let writer = File::open(Path::new(&name), &opts)?;
let writer = AnonPipe { inner: writer.into_handle() };
let theirs = File::open(Path::new(&name), &opts)?;
let theirs = AnonPipe { inner: theirs.into_handle() };

Ok((AnonPipe { inner: reader }, AnonPipe { inner: writer.into_handle() }))
Ok(Pipes {
ours: AnonPipe { inner: ours },
theirs: AnonPipe { inner: theirs.into_handle() },
})
}
}

Expand Down
14 changes: 5 additions & 9 deletions src/libstd/sys/windows/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -264,19 +264,15 @@ impl Stdio {
}

Stdio::MakePipe => {
let (reader, writer) = pipe::anon_pipe()?;
let (ours, theirs) = if stdio_id == c::STD_INPUT_HANDLE {
(writer, reader)
} else {
(reader, writer)
};
*pipe = Some(ours);
let ours_readable = stdio_id != c::STD_INPUT_HANDLE;
let pipes = pipe::anon_pipe(ours_readable)?;
*pipe = Some(pipes.ours);
cvt(unsafe {
c::SetHandleInformation(theirs.handle().raw(),
c::SetHandleInformation(pipes.theirs.handle().raw(),
c::HANDLE_FLAG_INHERIT,
c::HANDLE_FLAG_INHERIT)
})?;
Ok(theirs.into_handle())
Ok(pipes.theirs.into_handle())
}

Stdio::Handle(ref handle) => {
Expand Down
14 changes: 7 additions & 7 deletions src/libsyntax/fold.rs
Original file line number Diff line number Diff line change
Expand Up @@ -544,19 +544,19 @@ pub fn noop_fold_arg<T: Folder>(Arg {id, pat, ty}: Arg, fld: &mut T) -> Arg {
pub fn noop_fold_tt<T: Folder>(tt: &TokenTree, fld: &mut T) -> TokenTree {
match *tt {
TokenTree::Token(span, ref tok) =>
TokenTree::Token(span, fld.fold_token(tok.clone())),
TokenTree::Token(fld.new_span(span), fld.fold_token(tok.clone())),
TokenTree::Delimited(span, ref delimed) => {
TokenTree::Delimited(span, Rc::new(
TokenTree::Delimited(fld.new_span(span), Rc::new(
Delimited {
delim: delimed.delim,
open_span: delimed.open_span,
open_span: fld.new_span(delimed.open_span),
tts: fld.fold_tts(&delimed.tts),
close_span: delimed.close_span,
close_span: fld.new_span(delimed.close_span),
}
))
},
TokenTree::Sequence(span, ref seq) =>
TokenTree::Sequence(span,
TokenTree::Sequence(fld.new_span(span),
Rc::new(SequenceRepetition {
tts: fld.fold_tts(&seq.tts),
separator: seq.separator.clone().map(|tok| fld.fold_token(tok)),
Expand Down Expand Up @@ -649,7 +649,7 @@ pub fn noop_fold_fn_decl<T: Folder>(decl: P<FnDecl>, fld: &mut T) -> P<FnDecl> {
inputs: inputs.move_map(|x| fld.fold_arg(x)),
output: match output {
FunctionRetTy::Ty(ty) => FunctionRetTy::Ty(fld.fold_ty(ty)),
FunctionRetTy::Default(span) => FunctionRetTy::Default(span),
FunctionRetTy::Default(span) => FunctionRetTy::Default(fld.new_span(span)),
},
variadic: variadic
})
Expand All @@ -676,7 +676,7 @@ pub fn noop_fold_ty_param<T: Folder>(tp: TyParam, fld: &mut T) -> TyParam {
ident: ident,
bounds: fld.fold_bounds(bounds),
default: default.map(|x| fld.fold_ty(x)),
span: span
span: fld.new_span(span),
}
}

Expand Down
22 changes: 22 additions & 0 deletions src/test/compile-fail-fulldeps/proc-macro/auxiliary/issue_38586.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// force-host
// no-prefer-dynamic

#![feature(proc_macro, proc_macro_lib)]
#![crate_type = "proc-macro"]

extern crate proc_macro;

#[proc_macro_derive(A)]
pub fn derive_a(_: proc_macro::TokenStream) -> proc_macro::TokenStream {
"fn f() { println!(\"{}\", foo); }".parse().unwrap()
}
21 changes: 21 additions & 0 deletions src/test/compile-fail-fulldeps/proc-macro/issue-38586.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// aux-build:issue_38586.rs

#![feature(proc_macro)]

#[macro_use]
extern crate issue_38586;

#[derive(A)] //~ ERROR `foo`
struct A;

fn main() {}
15 changes: 15 additions & 0 deletions src/test/compile-fail/E0090.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

fn foo<'a: 'b, 'b: 'a>() {}
fn main() {
foo::<'static>();//~ ERROR E0090
//~^ too few lifetime parameters
}
21 changes: 21 additions & 0 deletions src/test/run-pass/issue-38727.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#[repr(u64)]
enum A {
A = 0u64,
B = !0u64,
}

fn cmp() -> A {
A::B
}

fn main() {}
Loading

0 comments on commit 1e34b5e

Please sign in to comment.