Skip to content

Rollup of 17 pull requests #58338

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 27 commits into from
Closed
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
7cdcdb5
Update reference of rlibc crate to compiler-builtins crate
king6cong Jan 2, 2019
5581207
Remove outdated comment
king6cong Jan 9, 2019
87f5a98
Use `to_ne_bytes` for converting IPv4Address to octets
JakubOnderka Jan 18, 2019
b4d3c87
Tiny improvement to docs for `core::convert`.
icefoxen Jan 26, 2019
4deb595
display sugared return types for async functions
euclio Feb 5, 2019
1d05f81
Add #[must_use] message to Fn* traits
taiki-e Feb 7, 2019
541503a
std::sys::unix::stdio: explain why we do into_raw
RalfJung Feb 8, 2019
b962ecc
Cleanup JS a bit
GuillaumeGomez Feb 8, 2019
66adf52
miri: give non-generic functions a stable address
RalfJung Feb 9, 2019
a01efbc
operand-to-place copies should never be overlapping
RalfJung Feb 9, 2019
3a3691f
when there are multiple filenames, print what got interpreted as 2nd …
RalfJung Feb 10, 2019
adb3300
rpath computation: explain why we pop()
RalfJung Feb 10, 2019
55f90c7
Fix failing tidy (line endings on Windows)
petrochenkov Feb 10, 2019
eaf81c2
miri value visitor: use in macro
RalfJung Feb 10, 2019
a4c775d
Rollup merge of #57259 - king6cong:master, r=alexcrichton
Mark-Simulacrum Feb 10, 2019
039958b
Rollup merge of #57740 - JakubOnderka:ipv4addr-to_ne_bytes, r=scottmcm
Mark-Simulacrum Feb 10, 2019
4164064
Rollup merge of #57926 - icefoxen:test-doc-pr, r=frewsxcv
Mark-Simulacrum Feb 10, 2019
e830e0f
Rollup merge of #58203 - euclio:rustdoc-async, r=GuillaumeGomez
Mark-Simulacrum Feb 10, 2019
4cfd0bb
Rollup merge of #58262 - taiki-e:must_use, r=estebank
Mark-Simulacrum Feb 10, 2019
8bdd01f
Rollup merge of #58295 - RalfJung:stdio, r=alexcrichton
Mark-Simulacrum Feb 10, 2019
a80aef5
Rollup merge of #58297 - GuillaumeGomez:cleanup-js, r=QuietMisdreavus
Mark-Simulacrum Feb 10, 2019
f4e8926
Rollup merge of #58324 - RalfJung:fn-ptr-eq, r=oli-obk
Mark-Simulacrum Feb 10, 2019
3c2b171
Rollup merge of #58332 - RalfJung:miri-copy-nonoverlapping, r=oli-obk
Mark-Simulacrum Feb 10, 2019
10e3e3c
Rollup merge of #58345 - RalfJung:2nd-filename, r=matthewjasper
Mark-Simulacrum Feb 10, 2019
74e450c
Rollup merge of #58346 - RalfJung:rpath-pop, r=Mark-Simulacrum
Mark-Simulacrum Feb 10, 2019
5b74980
Rollup merge of #58350 - petrochenkov:embed, r=frewsxcv
Mark-Simulacrum Feb 10, 2019
67011ac
Rollup merge of #58352 - RalfJung:macro, r=oli-obk
Mark-Simulacrum Feb 10, 2019
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
2 changes: 1 addition & 1 deletion src/doc/embedded-book
5 changes: 4 additions & 1 deletion src/libcore/convert.rs
Original file line number Diff line number Diff line change
@@ -17,7 +17,10 @@
//! [`TryFrom<T>`][`TryFrom`] rather than [`Into<U>`][`Into`] or [`TryInto<U>`][`TryInto`],
//! as [`From`] and [`TryFrom`] provide greater flexibility and offer
//! equivalent [`Into`] or [`TryInto`] implementations for free, thanks to a
//! blanket implementation in the standard library.
//! blanket implementation in the standard library. However, there are some cases
//! where this is not possible, such as creating conversions into a type defined
//! outside your library, so implementing [`Into`] instead of [`From`] is
//! sometimes necessary.
//!
//! # Generic Implementations
//!
2 changes: 1 addition & 1 deletion src/libcore/lib.rs
Original file line number Diff line number Diff line change
@@ -24,7 +24,7 @@
//! often generated by LLVM. Additionally, this library can make explicit
//! calls to these functions. Their signatures are the same as found in C.
//! These functions are often provided by the system libc, but can also be
//! provided by the [rlibc crate](https://crates.io/crates/rlibc).
//! provided by the [compiler-builtins crate](https://crates.io/crates/compiler_builtins).
//!
//! * `rust_begin_panic` - This function takes four arguments, a
//! `fmt::Arguments`, a `&'static str`, and two `u32`'s. These four arguments
6 changes: 3 additions & 3 deletions src/libcore/ops/function.rs
Original file line number Diff line number Diff line change
@@ -62,7 +62,7 @@
label="expected an `Fn<{Args}>` closure, found `{Self}`",
)]
#[fundamental] // so that regex can rely that `&str: !FnMut`
#[must_use]
#[must_use = "closures are lazy and do nothing unless called"]
pub trait Fn<Args> : FnMut<Args> {
/// Performs the call operation.
#[unstable(feature = "fn_traits", issue = "29625")]
@@ -141,7 +141,7 @@ pub trait Fn<Args> : FnMut<Args> {
label="expected an `FnMut<{Args}>` closure, found `{Self}`",
)]
#[fundamental] // so that regex can rely that `&str: !FnMut`
#[must_use]
#[must_use = "closures are lazy and do nothing unless called"]
pub trait FnMut<Args> : FnOnce<Args> {
/// Performs the call operation.
#[unstable(feature = "fn_traits", issue = "29625")]
@@ -220,7 +220,7 @@ pub trait FnMut<Args> : FnOnce<Args> {
label="expected an `FnOnce<{Args}>` closure, found `{Self}`",
)]
#[fundamental] // so that regex can rely that `&str: !FnMut`
#[must_use]
#[must_use = "closures are lazy and do nothing unless called"]
pub trait FnOnce<Args> {
/// The returned type after the call operator is used.
#[stable(feature = "fn_once_output", since = "1.12.0")]
31 changes: 23 additions & 8 deletions src/librustc/mir/interpret/mod.rs
Original file line number Diff line number Diff line change
@@ -27,7 +27,7 @@ pub use self::pointer::{Pointer, PointerArithmetic};
use std::fmt;
use crate::mir;
use crate::hir::def_id::DefId;
use crate::ty::{self, TyCtxt, Instance};
use crate::ty::{self, TyCtxt, Instance, subst::UnpackedKind};
use crate::ty::layout::{self, Size};
use std::io;
use crate::rustc_serialize::{Encoder, Decodable, Encodable};
@@ -318,14 +318,29 @@ impl<'tcx> AllocMap<'tcx> {
id
}

/// Functions cannot be identified by pointers, as asm-equal functions can get deduplicated
/// by the linker and functions can be duplicated across crates.
/// We thus generate a new `AllocId` for every mention of a function. This means that
/// `main as fn() == main as fn()` is false, while `let x = main as fn(); x == x` is true.
pub fn create_fn_alloc(&mut self, instance: Instance<'tcx>) -> AllocId {
let id = self.reserve();
self.id_to_kind.insert(id, AllocKind::Function(instance));
id
// Functions cannot be identified by pointers, as asm-equal functions can get deduplicated
// by the linker (we set the "unnamed_addr" attribute for LLVM) and functions can be
// duplicated across crates.
// We thus generate a new `AllocId` for every mention of a function. This means that
// `main as fn() == main as fn()` is false, while `let x = main as fn(); x == x` is true.
// However, formatting code relies on function identity (see #58320), so we only do
// this for generic functions. Lifetime parameters are ignored.
let is_generic = instance.substs.into_iter().any(|kind| {
match kind.unpack() {
UnpackedKind::Lifetime(_) => false,
_ => true,
}
});
if is_generic {
// Get a fresh ID
let id = self.reserve();
self.id_to_kind.insert(id, AllocKind::Function(instance));
id
} else {
// Deduplicate
self.intern(AllocKind::Function(instance))
}
}

/// Returns `None` in case the `AllocId` is dangling. An `EvalContext` can still have a
4 changes: 2 additions & 2 deletions src/librustc_codegen_llvm/back/rpath.rs
Original file line number Diff line number Diff line change
@@ -101,9 +101,9 @@ fn get_rpath_relative_to_output(config: &mut RPathConfig, lib: &Path) -> String

let cwd = env::current_dir().unwrap();
let mut lib = fs::canonicalize(&cwd.join(lib)).unwrap_or_else(|_| cwd.join(lib));
lib.pop();
lib.pop(); // strip filename
let mut output = cwd.join(&config.out_filename);
output.pop();
output.pop(); // strip filename
let output = fs::canonicalize(&output).unwrap_or(output);
let relative = path_relative_from(&lib, &output).unwrap_or_else(||
panic!("couldn't create relative path from {:?} to {:?}", output, lib));
10 changes: 9 additions & 1 deletion src/librustc_driver/lib.rs
Original file line number Diff line number Diff line change
@@ -838,7 +838,15 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
early_error(sopts.error_format, "no input filename given");
}
1 => panic!("make_input should have provided valid inputs"),
_ => early_error(sopts.error_format, "multiple input filenames provided"),
_ =>
early_error(
sopts.error_format,
&format!(
"multiple input filenames provided (first two filenames are `{}` and `{}`)",
matches.free[0],
matches.free[1],
),
)
}
}

5 changes: 4 additions & 1 deletion src/librustc_mir/interpret/place.rs
Original file line number Diff line number Diff line change
@@ -823,6 +823,8 @@ where
let src = match self.try_read_immediate(src)? {
Ok(src_val) => {
// Yay, we got a value that we can write directly.
// FIXME: Add a check to make sure that if `src` is indirect,
// it does not overlap with `dest`.
return self.write_immediate_no_validate(src_val, dest);
}
Err(mplace) => mplace,
@@ -836,7 +838,8 @@ where
self.memory.copy(
src_ptr, src_align,
dest_ptr, dest_align,
dest.layout.size, false
dest.layout.size,
/*nonoverlapping*/ true,
)?;

Ok(())
6 changes: 3 additions & 3 deletions src/librustc_mir/interpret/visitor.rs
Original file line number Diff line number Diff line change
@@ -125,14 +125,14 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Value<'a, 'mir, 'tcx, M>
}

macro_rules! make_value_visitor {
($visitor_trait_name:ident, $($mutability:ident)*) => {
($visitor_trait_name:ident, $($mutability:ident)?) => {
// How to traverse a value and what to do when we are at the leaves.
pub trait $visitor_trait_name<'a, 'mir, 'tcx: 'mir+'a, M: Machine<'a, 'mir, 'tcx>>: Sized {
type V: Value<'a, 'mir, 'tcx, M>;

/// The visitor must have an `EvalContext` in it.
fn ecx(&$($mutability)* self)
-> &$($mutability)* EvalContext<'a, 'mir, 'tcx, M>;
fn ecx(&$($mutability)? self)
-> &$($mutability)? EvalContext<'a, 'mir, 'tcx, M>;

// Recursive actions, ready to be overloaded.
/// Visit the given value, dispatching as appropriate to more specialized visitors.
39 changes: 39 additions & 0 deletions src/librustdoc/clean/mod.rs
Original file line number Diff line number Diff line change
@@ -1724,6 +1724,30 @@ impl FnDecl {
pub fn self_type(&self) -> Option<SelfTy> {
self.inputs.values.get(0).and_then(|v| v.to_self())
}

/// Returns the sugared return type for an async function.
///
/// For example, if the return type is `impl std::future::Future<Output = i32>`, this function
/// will return `i32`.
///
/// # Panics
///
/// This function will panic if the return type does not match the expected sugaring for async
/// functions.
pub fn sugared_async_return_type(&self) -> FunctionRetTy {
match &self.output {
FunctionRetTy::Return(Type::ImplTrait(bounds)) => {
match &bounds[0] {
GenericBound::TraitBound(PolyTrait { trait_, .. }, ..) => {
let bindings = trait_.bindings().unwrap();
FunctionRetTy::Return(bindings[0].ty.clone())
}
_ => panic!("unexpected desugaring of async function"),
}
}
_ => panic!("unexpected desugaring of async function"),
}
}
}

#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
@@ -2282,6 +2306,21 @@ impl Type {
_ => None,
}
}

pub fn bindings(&self) -> Option<&[TypeBinding]> {
match *self {
ResolvedPath { ref path, .. } => {
path.segments.last().and_then(|seg| {
if let GenericArgs::AngleBracketed { ref bindings, .. } = seg.args {
Some(&**bindings)
} else {
None
}
})
}
_ => None
}
}
}

impl GetDefId for Type {
23 changes: 16 additions & 7 deletions src/librustdoc/html/format.rs
Original file line number Diff line number Diff line change
@@ -5,6 +5,7 @@
//! assume that HTML output is desired, although it may be possible to redesign
//! them in the future to instead emit any format desired.

use std::borrow::Cow;
use std::fmt;

use rustc::hir::def_id::DefId;
@@ -44,14 +45,16 @@ pub struct GenericBounds<'a>(pub &'a [clean::GenericBound]);
pub struct CommaSep<'a, T: 'a>(pub &'a [T]);
pub struct AbiSpace(pub Abi);

/// Wrapper struct for properly emitting a method declaration.
pub struct Method<'a> {
/// Wrapper struct for properly emitting a function or method declaration.
pub struct Function<'a> {
/// The declaration to emit.
pub decl: &'a clean::FnDecl,
/// The length of the function's "name", used to determine line-wrapping.
pub name_len: usize,
/// The number of spaces to indent each successive line with, if line-wrapping is necessary.
pub indent: usize,
/// Whether the function is async or not.
pub asyncness: hir::IsAsync,
}

/// Wrapper struct for emitting a where clause from Generics.
@@ -829,9 +832,9 @@ impl fmt::Display for clean::FnDecl {
}
}

impl<'a> fmt::Display for Method<'a> {
impl<'a> fmt::Display for Function<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let &Method { decl, name_len, indent } = self;
let &Function { decl, name_len, indent, asyncness } = self;
let amp = if f.alternate() { "&" } else { "&amp;" };
let mut args = String::new();
let mut args_plain = String::new();
@@ -891,11 +894,17 @@ impl<'a> fmt::Display for Method<'a> {
args_plain.push_str(", ...");
}

let arrow_plain = format!("{:#}", decl.output);
let output = if let hir::IsAsync::Async = asyncness {
Cow::Owned(decl.sugared_async_return_type())
} else {
Cow::Borrowed(&decl.output)
};

let arrow_plain = format!("{:#}", &output);
let arrow = if f.alternate() {
format!("{:#}", decl.output)
format!("{:#}", &output)
} else {
decl.output.to_string()
output.to_string()
};

let pad = " ".repeat(name_len);
8 changes: 5 additions & 3 deletions src/librustdoc/html/render.rs
Original file line number Diff line number Diff line change
@@ -62,7 +62,7 @@ use fold::DocFolder;
use html::escape::Escape;
use html::format::{AsyncSpace, ConstnessSpace};
use html::format::{GenericBounds, WhereClause, href, AbiSpace};
use html::format::{VisSpace, Method, UnsafetySpace, MutableSpace};
use html::format::{VisSpace, Function, UnsafetySpace, MutableSpace};
use html::format::fmt_impl_for_trait_page;
use html::item_type::ItemType;
use html::markdown::{self, Markdown, MarkdownHtml, MarkdownSummaryLine, ErrorCodes, IdMap};
@@ -2977,10 +2977,11 @@ fn item_function(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
name = it.name.as_ref().unwrap(),
generics = f.generics,
where_clause = WhereClause { gens: &f.generics, indent: 0, end_newline: true },
decl = Method {
decl = Function {
decl: &f.decl,
name_len,
indent: 0,
asyncness: f.header.asyncness,
})?;
document(w, cx, it)
}
@@ -3424,10 +3425,11 @@ fn render_assoc_item(w: &mut fmt::Formatter,
href = href,
name = name,
generics = *g,
decl = Method {
decl = Function {
decl: d,
name_len: head_len,
indent,
asyncness: header.asyncness,
},
where_clause = WhereClause {
gens: g,
14 changes: 6 additions & 8 deletions src/librustdoc/html/static/main.js
Original file line number Diff line number Diff line change
@@ -79,8 +79,6 @@ if (!DOMTokenList.prototype.remove) {
// 2 for "In Return Types"
var currentTab = 0;

var themesWidth = null;

var titleBeforeSearch = document.title;

function getPageId() {
@@ -240,7 +238,7 @@ if (!DOMTokenList.prototype.remove) {
return String.fromCharCode(c);
}

function displayHelp(display, ev) {
function displayHelp(display, ev, help) {
if (display === true) {
if (hasClass(help, "hidden")) {
ev.preventDefault();
@@ -258,7 +256,7 @@ if (!DOMTokenList.prototype.remove) {
hideModal();
var search = document.getElementById("search");
if (hasClass(help, "hidden") === false) {
displayHelp(false, ev);
displayHelp(false, ev, help);
} else if (hasClass(search, "hidden") === false) {
ev.preventDefault();
addClass(search, "hidden");
@@ -289,7 +287,7 @@ if (!DOMTokenList.prototype.remove) {

case "s":
case "S":
displayHelp(false, ev);
displayHelp(false, ev, help);
hideModal();
ev.preventDefault();
focusSearchBar();
@@ -304,7 +302,7 @@ if (!DOMTokenList.prototype.remove) {
case "?":
if (ev.shiftKey) {
hideModal();
displayHelp(true, ev);
displayHelp(true, ev, help);
}
break;
}
@@ -654,7 +652,7 @@ if (!DOMTokenList.prototype.remove) {
return MAX_LEV_DISTANCE + 1;
}
}
return lev_distance;//Math.ceil(total / done);
return Math.ceil(total / done);
}
}
return MAX_LEV_DISTANCE + 1;
@@ -2432,7 +2430,7 @@ if (!DOMTokenList.prototype.remove) {
// for vertical layout (column-oriented flex layout for divs caused
// errors in mobile browsers).
if (e.tagName === "H2" || e.tagName === "H3") {
let nextTagName = e.nextElementSibling.tagName;
var nextTagName = e.nextElementSibling.tagName;
if (nextTagName == "H2" || nextTagName == "H3") {
e.nextElementSibling.style.display = "flex";
} else {
3 changes: 1 addition & 2 deletions src/libstd/net/ip.rs
Original file line number Diff line number Diff line change
@@ -392,8 +392,7 @@ impl Ipv4Addr {
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn octets(&self) -> [u8; 4] {
let bits = u32::from_be(self.inner.s_addr);
[(bits >> 24) as u8, (bits >> 16) as u8, (bits >> 8) as u8, bits as u8]
self.inner.s_addr.to_ne_bytes()
}

/// Returns [`true`] for the special 'unspecified' address (0.0.0.0).
6 changes: 3 additions & 3 deletions src/libstd/sys/unix/stdio.rs
Original file line number Diff line number Diff line change
@@ -12,7 +12,7 @@ impl Stdin {
pub fn read(&self, data: &mut [u8]) -> io::Result<usize> {
let fd = FileDesc::new(libc::STDIN_FILENO);
let ret = fd.read(data);
fd.into_raw();
fd.into_raw(); // do not close this FD
ret
}
}
@@ -23,7 +23,7 @@ impl Stdout {
pub fn write(&self, data: &[u8]) -> io::Result<usize> {
let fd = FileDesc::new(libc::STDOUT_FILENO);
let ret = fd.write(data);
fd.into_raw();
fd.into_raw(); // do not close this FD
ret
}

@@ -38,7 +38,7 @@ impl Stderr {
pub fn write(&self, data: &[u8]) -> io::Result<usize> {
let fd = FileDesc::new(libc::STDERR_FILENO);
let ret = fd.write(data);
fd.into_raw();
fd.into_raw(); // do not close this FD
ret
}

35 changes: 28 additions & 7 deletions src/test/rustdoc/async-fn.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,35 @@
// edition:2018
// compile-flags:-Z unstable-options

// FIXME: once `--edition` is stable in rustdoc, remove that `compile-flags` directive

#![feature(async_await, futures_api)]

// @has async_fn/struct.S.html
// @has - '//code' 'pub async fn f()'
pub struct S;
// @has async_fn/fn.foo.html '//pre[@class="rust fn"]' 'pub async fn foo() -> Option<Foo>'
pub async fn foo() -> Option<Foo> {
None
}

// @has async_fn/fn.bar.html '//pre[@class="rust fn"]' 'pub async fn bar(a: i32, b: i32) -> i32'
pub async fn bar(a: i32, b: i32) -> i32 {
0
}

// @has async_fn/fn.baz.html '//pre[@class="rust fn"]' 'pub async fn baz<T>(a: T) -> T'
pub async fn baz<T>(a: T) -> T {
a
}

trait Bar {}

impl Bar for () {}

// @has async_fn/fn.quux.html '//pre[@class="rust fn"]' 'pub async fn quux() -> impl Bar'
pub async fn quux() -> impl Bar {
()
}

// @has async_fn/struct.Foo.html
// @matches - '//code' 'pub async fn f\(\)$'
pub struct Foo;

impl S {
impl Foo {
pub async fn f() {}
}