@@ -945,6 +945,7 @@ macro_rules! atomic_int {
$stable_debug:meta,
$stable_access:meta,
$stable_from:meta,
$stable_nand:meta,
$s_int_type:expr, $int_ref:expr,
$int_type:ident $atomic_type:ident $atomic_init:ident) => {
/// An integer type which can be safely shared between threads.
@@ -1325,6 +1326,29 @@ macro_rules! atomic_int {
unsafe { atomic_and(self.v.get(), val, order) }
}

/// Bitwise "nand" with the current value.
///
/// Performs a bitwise "nand" operation on the current value and the argument `val`, and
/// sets the new value to the result.
///
/// Returns the previous value.
///
/// # Examples
///
/// ```
/// #![feature(atomic_nand)]
///
/// use std::sync::atomic::{AtomicIsize, Ordering};
///
/// let foo = AtomicIsize::new(0xf731);
/// assert_eq!(foo.fetch_nand(0x137f, Ordering::SeqCst), 0xf731);
/// assert_eq!(foo.load(Ordering::SeqCst), !(0xf731 & 0x137f));
#[inline]
#[$stable_nand]
pub fn fetch_nand(&self, val: $int_type, order: Ordering) -> $int_type {
unsafe { atomic_nand(self.v.get(), val, order) }
}

/// Bitwise "or" with the current value.
///
/// Performs a bitwise "or" operation on the current value and the argument `val`, and
@@ -1377,6 +1401,7 @@ atomic_int! {
unstable(feature = "integer_atomics", issue = "32976"),
unstable(feature = "integer_atomics", issue = "32976"),
unstable(feature = "integer_atomics", issue = "32976"),
unstable(feature = "atomic_nand", issue = "13226"),
"i8", "../../../std/primitive.i8.html",
i8 AtomicI8 ATOMIC_I8_INIT
}
@@ -1387,6 +1412,7 @@ atomic_int! {
unstable(feature = "integer_atomics", issue = "32976"),
unstable(feature = "integer_atomics", issue = "32976"),
unstable(feature = "integer_atomics", issue = "32976"),
unstable(feature = "atomic_nand", issue = "13226"),
"u8", "../../../std/primitive.u8.html",
u8 AtomicU8 ATOMIC_U8_INIT
}
@@ -1397,6 +1423,7 @@ atomic_int! {
unstable(feature = "integer_atomics", issue = "32976"),
unstable(feature = "integer_atomics", issue = "32976"),
unstable(feature = "integer_atomics", issue = "32976"),
unstable(feature = "atomic_nand", issue = "13226"),
"i16", "../../../std/primitive.i16.html",
i16 AtomicI16 ATOMIC_I16_INIT
}
@@ -1407,6 +1434,7 @@ atomic_int! {
unstable(feature = "integer_atomics", issue = "32976"),
unstable(feature = "integer_atomics", issue = "32976"),
unstable(feature = "integer_atomics", issue = "32976"),
unstable(feature = "atomic_nand", issue = "13226"),
"u16", "../../../std/primitive.u16.html",
u16 AtomicU16 ATOMIC_U16_INIT
}
@@ -1417,6 +1445,7 @@ atomic_int! {
unstable(feature = "integer_atomics", issue = "32976"),
unstable(feature = "integer_atomics", issue = "32976"),
unstable(feature = "integer_atomics", issue = "32976"),
unstable(feature = "atomic_nand", issue = "13226"),
"i32", "../../../std/primitive.i32.html",
i32 AtomicI32 ATOMIC_I32_INIT
}
@@ -1427,6 +1456,7 @@ atomic_int! {
unstable(feature = "integer_atomics", issue = "32976"),
unstable(feature = "integer_atomics", issue = "32976"),
unstable(feature = "integer_atomics", issue = "32976"),
unstable(feature = "atomic_nand", issue = "13226"),
"u32", "../../../std/primitive.u32.html",
u32 AtomicU32 ATOMIC_U32_INIT
}
@@ -1437,6 +1467,7 @@ atomic_int! {
unstable(feature = "integer_atomics", issue = "32976"),
unstable(feature = "integer_atomics", issue = "32976"),
unstable(feature = "integer_atomics", issue = "32976"),
unstable(feature = "atomic_nand", issue = "13226"),
"i64", "../../../std/primitive.i64.html",
i64 AtomicI64 ATOMIC_I64_INIT
}
@@ -1447,6 +1478,7 @@ atomic_int! {
unstable(feature = "integer_atomics", issue = "32976"),
unstable(feature = "integer_atomics", issue = "32976"),
unstable(feature = "integer_atomics", issue = "32976"),
unstable(feature = "atomic_nand", issue = "13226"),
"u64", "../../../std/primitive.u64.html",
u64 AtomicU64 ATOMIC_U64_INIT
}
@@ -1457,6 +1489,7 @@ atomic_int!{
stable(feature = "atomic_debug", since = "1.3.0"),
stable(feature = "atomic_access", since = "1.15.0"),
stable(feature = "atomic_from", since = "1.23.0"),
unstable(feature = "atomic_nand", issue = "13226"),
"isize", "../../../std/primitive.isize.html",
isize AtomicIsize ATOMIC_ISIZE_INIT
}
@@ -1467,6 +1500,7 @@ atomic_int!{
stable(feature = "atomic_debug", since = "1.3.0"),
stable(feature = "atomic_access", since = "1.15.0"),
stable(feature = "atomic_from", since = "1.23.0"),
unstable(feature = "atomic_nand", issue = "13226"),
"usize", "../../../std/primitive.usize.html",
usize AtomicUsize ATOMIC_USIZE_INIT
}
@@ -1609,6 +1643,18 @@ unsafe fn atomic_and<T>(dst: *mut T, val: T, order: Ordering) -> T {
}
}

#[inline]
unsafe fn atomic_nand<T>(dst: *mut T, val: T, order: Ordering) -> T {
match order {
Acquire => intrinsics::atomic_nand_acq(dst, val),
Release => intrinsics::atomic_nand_rel(dst, val),
AcqRel => intrinsics::atomic_nand_acqrel(dst, val),
Relaxed => intrinsics::atomic_nand_relaxed(dst, val),
SeqCst => intrinsics::atomic_nand(dst, val),
__Nonexhaustive => panic!("invalid memory ordering"),
}
}

#[inline]
unsafe fn atomic_or<T>(dst: *mut T, val: T, order: Ordering) -> T {
match order {
@@ -48,6 +48,13 @@ fn uint_and() {
assert_eq!(x.load(SeqCst), 0xf731 & 0x137f);
}

#[test]
fn uint_nand() {
let x = AtomicUsize::new(0xf731);
assert_eq!(x.fetch_nand(0x137f, SeqCst), 0xf731);
assert_eq!(x.load(SeqCst), !(0xf731 & 0x137f));
}

#[test]
fn uint_or() {
let x = AtomicUsize::new(0xf731);
@@ -69,6 +76,13 @@ fn int_and() {
assert_eq!(x.load(SeqCst), 0xf731 & 0x137f);
}

#[test]
fn int_nand() {
let x = AtomicIsize::new(0xf731);
assert_eq!(x.fetch_nand(0x137f, SeqCst), 0xf731);
assert_eq!(x.load(SeqCst), !(0xf731 & 0x137f));
}

#[test]
fn int_or() {
let x = AtomicIsize::new(0xf731);
@@ -42,6 +42,7 @@
#![feature(try_from)]
#![feature(try_trait)]
#![feature(exact_chunks)]
#![feature(atomic_nand)]

extern crate core;
extern crate test;
@@ -73,7 +73,7 @@ pub struct FormatSpec<'a> {
/// Enum describing where an argument for a format can be located.
#[derive(Copy, Clone, PartialEq)]
pub enum Position<'a> {
/// The arugment is implied to be located at an index
/// The argument is implied to be located at an index
ArgumentImplicitlyIs(usize),
/// The argument is located at a specific index given in the format
ArgumentIs(usize),
@@ -965,8 +965,8 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
walk_list!(visitor, visit_expr, subexpressions);
}
ExprCall(ref callee_expression, ref arguments) => {
visitor.visit_expr(callee_expression);
walk_list!(visitor, visit_expr, arguments);
visitor.visit_expr(callee_expression)
}
ExprMethodCall(ref segment, _, ref arguments) => {
visitor.visit_path_segment(expression.span, segment);
@@ -764,8 +764,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
} else {
let (closure_span, found) = found_did
.and_then(|did| self.tcx.hir.get_if_local(did))
.map(|node| self.get_fn_like_arguments(node))
.unwrap_or((found_span.unwrap(), found));
.map(|node| {
let (found_span, found) = self.get_fn_like_arguments(node);
(Some(found_span), found)
}).unwrap_or((found_span, found));

self.report_arg_count_mismatch(span,
closure_span,
@@ -875,7 +877,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
fn report_arg_count_mismatch(
&self,
span: Span,
found_span: Span,
found_span: Option<Span>,
expected_args: Vec<ArgKind>,
found_args: Vec<ArgKind>,
is_closure: bool,
@@ -913,48 +915,51 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
);

err.span_label(span, format!( "expected {} that takes {}", kind, expected_str));
err.span_label(found_span, format!("takes {}", found_str));

if let &[ArgKind::Tuple(_, ref fields)] = &found_args[..] {
if fields.len() == expected_args.len() {
let sugg = fields.iter()
.map(|(name, _)| name.to_owned())
.collect::<Vec<String>>().join(", ");
err.span_suggestion(found_span,
"change the closure to take multiple arguments instead of \
a single tuple",
format!("|{}|", sugg));

if let Some(found_span) = found_span {
err.span_label(found_span, format!("takes {}", found_str));

if let &[ArgKind::Tuple(_, ref fields)] = &found_args[..] {
if fields.len() == expected_args.len() {
let sugg = fields.iter()
.map(|(name, _)| name.to_owned())
.collect::<Vec<String>>().join(", ");
err.span_suggestion(found_span,
"change the closure to take multiple arguments instead of \
a single tuple",
format!("|{}|", sugg));
}
}
}
if let &[ArgKind::Tuple(_, ref fields)] = &expected_args[..] {
if fields.len() == found_args.len() && is_closure {
let sugg = format!(
"|({}){}|",
found_args.iter()
.map(|arg| match arg {
ArgKind::Arg(name, _) => name.to_owned(),
_ => "_".to_owned(),
})
.collect::<Vec<String>>()
.join(", "),
// add type annotations if available
if found_args.iter().any(|arg| match arg {
ArgKind::Arg(_, ty) => ty != "_",
_ => false,
}) {
format!(": ({})",
fields.iter()
.map(|(_, ty)| ty.to_owned())
.collect::<Vec<String>>()
.join(", "))
} else {
"".to_owned()
},
);
err.span_suggestion(found_span,
"change the closure to accept a tuple instead of individual \
arguments",
sugg);
if let &[ArgKind::Tuple(_, ref fields)] = &expected_args[..] {
if fields.len() == found_args.len() && is_closure {
let sugg = format!(
"|({}){}|",
found_args.iter()
.map(|arg| match arg {
ArgKind::Arg(name, _) => name.to_owned(),
_ => "_".to_owned(),
})
.collect::<Vec<String>>()
.join(", "),
// add type annotations if available
if found_args.iter().any(|arg| match arg {
ArgKind::Arg(_, ty) => ty != "_",
_ => false,
}) {
format!(": ({})",
fields.iter()
.map(|(_, ty)| ty.to_owned())
.collect::<Vec<String>>()
.join(", "))
} else {
"".to_owned()
},
);
err.span_suggestion(found_span,
"change the closure to accept a tuple instead of \
individual arguments",
sugg);
}
}
}

This file was deleted.

Oops, something went wrong.
@@ -57,7 +57,6 @@ pub mod small_vec;
pub mod base_n;
pub mod bitslice;
pub mod bitvec;
pub mod blake2b;
pub mod graph;
pub mod indexed_set;
pub mod indexed_vec;
@@ -70,7 +69,6 @@ pub mod transitive_relation;
pub mod unify;
pub mod fx;
pub mod tuple_slice;
pub mod veccell;
pub mod control_flow_graph;
pub mod flock;
pub mod sync;

This file was deleted.

Oops, something went wrong.
@@ -170,6 +170,13 @@ pub fn compile_input(trans: Box<TransCrate>,
return Ok(())
}

if let &Some(ref dir) = outdir {
if fs::create_dir_all(dir).is_err() {
sess.err("failed to find or create the directory specified by --out-dir");
return Err(CompileIncomplete::Stopped);
}
}

let arenas = AllArenas::new();

// Construct the HIR map
@@ -716,6 +716,10 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
ReifyFnPointer => {
match self.eval_operand(operand)?.ty.sty {
ty::TyFnDef(def_id, substs) => {
if self.tcx.has_attr(def_id, "rustc_args_required_const") {
bug!("reifying a fn ptr that requires \
const arguments");
}
let instance = self.resolve(def_id, substs)?;
let fn_ptr = self.memory.create_fn_alloc(instance);
let valty = ValTy {
@@ -1026,9 +1026,17 @@ fn import_path_to_string(names: &[SpannedIdent],
if names.is_empty() {
import_directive_subclass_to_string(subclass)
} else {
(format!("{}::{}",
names_to_string(names),
import_directive_subclass_to_string(subclass)))
// Note that this code looks a little wonky, it's currently here to
// hopefully help debug #48116, but otherwise isn't intended to
// cause any problems.
let x = format!(
"{}::{}",
names_to_string(names),
import_directive_subclass_to_string(subclass),
);
assert!(!names.is_empty());
assert!(!x.starts_with("::"));
return x
}
}
}
@@ -714,6 +714,10 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
mir::CastKind::ReifyFnPointer => {
match operand.ty.sty {
ty::TyFnDef(def_id, substs) => {
if tcx.has_attr(def_id, "rustc_args_required_const") {
bug!("reifying a fn ptr that requires \
const arguments");
}
callee::resolve_and_get_fn(self.cx, def_id, substs)
}
_ => {
@@ -195,6 +195,10 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
mir::CastKind::ReifyFnPointer => {
match operand.layout.ty.sty {
ty::TyFnDef(def_id, substs) => {
if bx.cx.tcx.has_attr(def_id, "rustc_args_required_const") {
bug!("reifying a fn ptr that requires \
const arguments");
}
OperandValue::Immediate(
callee::resolve_and_get_fn(bx.cx, def_id, substs))
}
@@ -4897,13 +4897,45 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
}
}

self.check_rustc_args_require_const(def.def_id(), node_id, span);

debug!("instantiate_value_path: type of {:?} is {:?}",
node_id,
ty_substituted);
self.write_substs(self.tcx.hir.node_to_hir_id(node_id), substs);
ty_substituted
}

fn check_rustc_args_require_const(&self,
def_id: DefId,
node_id: ast::NodeId,
span: Span) {
// We're only interested in functions tagged with
// #[rustc_args_required_const], so ignore anything that's not.
if !self.tcx.has_attr(def_id, "rustc_args_required_const") {
return
}

// If our calling expression is indeed the function itself, we're good!
// If not, generate an error that this can only be called directly.
match self.tcx.hir.get(self.tcx.hir.get_parent_node(node_id)) {
Node::NodeExpr(expr) => {
match expr.node {
hir::ExprCall(ref callee, ..) => {
if callee.id == node_id {
return
}
}
_ => {}
}
}
_ => {}
}

self.tcx.sess.span_err(span, "this function can only be invoked \
directly, not through a function pointer");
}

/// Report errors if the provided parameters are too few or too many.
fn check_path_parameter_count(&self,
span: Span,
@@ -1051,6 +1051,10 @@ impl Clean<Attributes> for [ast::Attribute] {
if UnstableFeatures::from_environment().is_nightly_build() {
let dox = attrs.collapsed_doc_value().unwrap_or_else(String::new);
for link in markdown_links(&dox, cx.render_type) {
// bail early for real links
if link.contains('/') {
continue;
}
let (def, fragment) = {
let mut kind = PathKind::Unknown;
let path_str = if let Some(prefix) =
@@ -106,7 +106,9 @@ pub fn where_clauses(cx: &DocContext, clauses: Vec<WP>) -> Vec<WP> {
}
PP::Parenthesized { ref mut output, .. } => {
assert!(output.is_none());
*output = Some(rhs.clone());
if *rhs != clean::Type::Tuple(Vec::new()) {
*output = Some(rhs.clone());
}
}
};
true
@@ -123,25 +123,9 @@
sidebar.appendChild(div);
}
}
var themeChoices = document.getElementById("theme-choices");
if (themeChoices) {
if (!themesWidth) {
var savedState = themeChoices.style.display;
themeChoices.style.display = 'block';
themesWidth = themeChoices.offsetWidth + 'px';
themeChoices.style.display = savedState;
}
themeChoices.style.position = "fixed";
themeChoices.style.width = themesWidth;
themeChoices.style.top = '78px';
themeChoices.style.left = '250px';
}
document.getElementsByTagName("body")[0].style.marginTop = '45px';
var themePicker = document.getElementById("theme-picker");
if (themePicker) {
themePicker.style.position = "fixed";
themePicker.style.top = "50px";
themePicker.style.left = "250px";
var themePicker = document.getElementsByClassName("theme-picker");
if (themePicker && themePicker.length > 0) {
themePicker[0].style.display = "none";
}
}

@@ -157,18 +141,9 @@
filler.remove();
}
document.getElementsByTagName("body")[0].style.marginTop = '';
var themePicker = document.getElementById("theme-picker");
if (themePicker) {
themePicker.style.position = "absolute";
themePicker.style.top = null;
themePicker.style.left = null;
}
var themeChoices = document.getElementById("theme-choices");
if (themeChoices) {
themeChoices.style.position = 'absolute';
themeChoices.style.width = null;
themeChoices.style.top = null;
themeChoices.style.left = null;
var themePicker = document.getElementsByClassName("theme-picker");
if (themePicker && themePicker.length > 0) {
themePicker[0].style.display = null;
}
}

@@ -899,7 +899,7 @@ span.since {
}

#main {
margin-top: 50px;
margin-top: 45px;
padding: 0;
}

@@ -984,6 +984,11 @@ pub const BUILTIN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeG
"wasm_import_memory attribute is currently unstable",
cfg_fn!(wasm_import_memory))),

("rustc_args_required_const", Whitelisted, Gated(Stability::Unstable,
"rustc_attrs",
"never will be stable",
cfg_fn!(rustc_attrs))),

// Crate level attributes
("crate_name", CrateLevel, Ungated),
("crate_type", CrateLevel, Ungated),
Submodule llvm updated 14894 files
@@ -552,9 +552,11 @@ static unsigned fromRust(LLVMRustDIFlags Flags) {
if (isSet(Flags & LLVMRustDIFlags::FlagRValueReference)) {
Result |= DINode::DIFlags::FlagRValueReference;
}
#if LLVM_VERSION_LE(4, 0)
if (isSet(Flags & LLVMRustDIFlags::FlagExternalTypeRef)) {
Result |= DINode::DIFlags::FlagExternalTypeRef;
}
#endif
if (isSet(Flags & LLVMRustDIFlags::FlagIntroducedVirtual)) {
Result |= DINode::DIFlags::FlagIntroducedVirtual;
}
@@ -1,4 +1,4 @@
# If this file is modified, then llvm will be (optionally) cleaned and then rebuilt.
# The actual contents of this file do not matter, but to trigger a change on the
# build bots then the contents should be changed so git updates the mtime.
2018-01-25
2018-02-09
@@ -0,0 +1,20 @@
// Copyright 2018 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.

#![feature(attr_literals, rustc_attrs, const_fn)]

#[rustc_args_required_const(0)]
fn foo(_a: i32) {
}

fn main() {
let a = foo; //~ ERROR: this function can only be invoked directly
a(2);
}
@@ -15,11 +15,14 @@
// Unfortunately, LLVM has no "disable" option for this, so we have to set
// "enable" to 0 instead.

// compile-flags:-g -Cllvm-args=-enable-tail-merge=0
// compile-flags:-g -Cllvm-args=-enable-tail-merge=0 -Cllvm-args=-opt-bisect-limit=0
// ignore-pretty issue #37195
// ignore-cloudabi spawning processes is not supported
// ignore-emscripten spawning processes is not supported

// note that above `-opt-bisect-limit=0` is used to basically disable
// optimizations

use std::env;

#[path = "backtrace-debuginfo-aux.rs"] mod aux;
@@ -114,25 +117,34 @@ fn outer(mut counter: i32, main_pos: Pos) {
inner_inlined(&mut counter, main_pos, pos!());
}

fn check_trace(output: &str, error: &str) {
fn check_trace(output: &str, error: &str) -> Result<(), String> {
// reverse the position list so we can start with the last item (which was the first line)
let mut remaining: Vec<&str> = output.lines().map(|s| s.trim()).rev().collect();

assert!(error.contains("stack backtrace"), "no backtrace in the error: {}", error);
if !error.contains("stack backtrace") {
return Err(format!("no backtrace found in stderr:\n{}", error))
}
for line in error.lines() {
if !remaining.is_empty() && line.contains(remaining.last().unwrap()) {
remaining.pop();
}
}
assert!(remaining.is_empty(),
"trace does not match position list: {}\n---\n{}", error, output);
if !remaining.is_empty() {
return Err(format!("trace does not match position list\n\
still need to find {:?}\n\n\
--- stdout\n{}\n\
--- stderr\n{}",
remaining, output, error))
}
Ok(())
}

fn run_test(me: &str) {
use std::str;
use std::process::Command;

let mut i = 0;
let mut errors = Vec::new();
loop {
let out = Command::new(me)
.env("RUST_BACKTRACE", "full")
@@ -143,10 +155,20 @@ fn run_test(me: &str) {
assert!(output.contains("done."), "bad output for successful run: {}", output);
break;
} else {
check_trace(output, error);
if let Err(e) = check_trace(output, error) {
errors.push(e);
}
}
i += 1;
}
if errors.len() > 0 {
for error in errors {
println!("---------------------------------------");
println!("{}", error);
}

panic!("found some errors");
}
}

#[inline(never)]
@@ -0,0 +1,13 @@
// Copyright 2018 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.

pub fn f2<F: FnMut(u32) + Clone>(f: F) {}

pub fn f3<F: FnMut(u64) -> () + Clone>(f: F) {}
@@ -0,0 +1,27 @@
// Copyright 2018 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:unit-return.rs

#![crate_name = "foo"]

extern crate unit_return;

// @has 'foo/fn.f0.html' '//*[@class="rust fn"]' 'F: FnMut(u8) + Clone'
pub fn f0<F: FnMut(u8) + Clone>(f: F) {}

// @has 'foo/fn.f1.html' '//*[@class="rust fn"]' 'F: FnMut(u16) + Clone'
pub fn f1<F: FnMut(u16) -> () + Clone>(f: F) {}

// @has 'foo/fn.f2.html' '//*[@class="rust fn"]' 'F: FnMut(u32) + Clone'
pub use unit_return::f2;

// @has 'foo/fn.f3.html' '//*[@class="rust fn"]' 'F: FnMut(u64) + Clone'
pub use unit_return::f3;
@@ -0,0 +1,23 @@
// Copyright 2018 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.

#![feature(generators)]

fn main() {
let x = (|_| {},);

|| {
let x = x;

x.0({ //~ ERROR borrow may still be in use when generator yields
yield;
});
};
}
@@ -0,0 +1,10 @@
error[E0626]: borrow may still be in use when generator yields
--> $DIR/issue-48048.rs:19:9
|
19 | x.0({ //~ ERROR borrow may still be in use when generator yields
| ^^^
20 | yield;
| ----- possible yield occurs here

error: aborting due to previous error

@@ -10,7 +10,7 @@

fn main() {
1 + Some(1); //~ ERROR cannot add `std::option::Option<{integer}>` to `{integer}`
2 as usize - Some(1); //~ ERROR cannot substract `std::option::Option<{integer}>` from `usize`
2 as usize - Some(1); //~ ERROR cannot subtract `std::option::Option<{integer}>` from `usize`
3 * (); //~ ERROR cannot multiply `()` to `{integer}`
4 / ""; //~ ERROR cannot divide `{integer}` by `&str`
5 < String::new(); //~ ERROR is not satisfied
@@ -6,10 +6,10 @@ error[E0277]: cannot add `std::option::Option<{integer}>` to `{integer}`
|
= help: the trait `std::ops::Add<std::option::Option<{integer}>>` is not implemented for `{integer}`

error[E0277]: cannot substract `std::option::Option<{integer}>` from `usize`
error[E0277]: cannot subtract `std::option::Option<{integer}>` from `usize`
--> $DIR/binops.rs:13:16
|
13 | 2 as usize - Some(1); //~ ERROR cannot substract `std::option::Option<{integer}>` from `usize`
13 | 2 as usize - Some(1); //~ ERROR cannot subtract `std::option::Option<{integer}>` from `usize`
| ^ no implementation for `usize - std::option::Option<{integer}>`
|
= help: the trait `std::ops::Sub<std::option::Option<{integer}>>` is not implemented for `usize`
@@ -36,6 +36,9 @@ fn main() {
//~^ ERROR closure is expected to take
let _it = vec![1, 2, 3].into_iter().enumerate().map(qux);
//~^ ERROR function is expected to take

let _it = vec![1, 2, 3].into_iter().map(usize::checked_add);
//~^ ERROR function is expected to take
}

fn foo() {}
@@ -90,7 +90,7 @@ error[E0593]: function is expected to take a single 2-tuple as argument, but it
32 | let _it = vec![1, 2, 3].into_iter().enumerate().map(foo);
| ^^^ expected function that takes a single 2-tuple as argument
...
41 | fn foo() {}
44 | fn foo() {}
| -------- takes 0 arguments

error[E0593]: closure is expected to take a single 2-tuple as argument, but it takes 3 distinct arguments
@@ -107,8 +107,14 @@ error[E0593]: function is expected to take a single 2-tuple as argument, but it
37 | let _it = vec![1, 2, 3].into_iter().enumerate().map(qux);
| ^^^ expected function that takes a single 2-tuple as argument
...
42 | fn qux(x: usize, y: usize) {}
45 | fn qux(x: usize, y: usize) {}
| -------------------------- takes 2 distinct arguments

error: aborting due to 11 previous errors
error[E0593]: function is expected to take 1 argument, but it takes 2 arguments
--> $DIR/closure-arg-count.rs:40:41
|
40 | let _it = vec![1, 2, 3].into_iter().map(usize::checked_add);
| ^^^ expected function that takes 1 argument

error: aborting due to 12 previous errors