diff --git a/src/bootstrap/clean.rs b/src/bootstrap/clean.rs index a66ed46fe464f..e9547ee42d077 100644 --- a/src/bootstrap/clean.rs +++ b/src/bootstrap/clean.rs @@ -22,9 +22,9 @@ use std::path::Path; use Build; pub fn clean(build: &Build) { - rm_rf(build, "tmp".as_ref()); - rm_rf(build, &build.out.join("tmp")); - rm_rf(build, &build.out.join("dist")); + rm_rf("tmp".as_ref()); + rm_rf(&build.out.join("tmp")); + rm_rf(&build.out.join("dist")); for host in build.config.host.iter() { let entries = match build.out.join(host).read_dir() { @@ -38,12 +38,12 @@ pub fn clean(build: &Build) { continue } let path = t!(entry.path().canonicalize()); - rm_rf(build, &path); + rm_rf(&path); } } } -fn rm_rf(build: &Build, path: &Path) { +fn rm_rf(path: &Path) { if !path.exists() { return } @@ -55,7 +55,7 @@ fn rm_rf(build: &Build, path: &Path) { let file = t!(file).path(); if file.is_dir() { - rm_rf(build, &file); + rm_rf(&file); } else { // On windows we can't remove a readonly file, and git will // often clone files as readonly. As a result, we have some diff --git a/src/doc/unstable-book/src/SUMMARY.md b/src/doc/unstable-book/src/SUMMARY.md index 44eda204a3d29..7820d44920829 100644 --- a/src/doc/unstable-book/src/SUMMARY.md +++ b/src/doc/unstable-book/src/SUMMARY.md @@ -71,6 +71,7 @@ - [repr_simd](repr-simd.md) - [rustc_attrs](rustc-attrs.md) - [rustc_diagnostic_macros](rustc-diagnostic-macros.md) +- [rvalue_static_promotion](rvalue-static-promotion.md) - [sanitizer_runtime](sanitizer-runtime.md) - [simd](simd.md) - [simd_ffi](simd-ffi.md) diff --git a/src/doc/unstable-book/src/rvalue-static-promotion.md b/src/doc/unstable-book/src/rvalue-static-promotion.md new file mode 100644 index 0000000000000..2583d350ebe11 --- /dev/null +++ b/src/doc/unstable-book/src/rvalue-static-promotion.md @@ -0,0 +1,23 @@ +# `rvalue_static_promotion` + +The tracking issue for this feature is: [#38865] + +[#38865]: https://github.com/rust-lang/rust/issues/38865 + +------------------------ + +The `rvalue_static_promotion` feature allows directly creating `'static` references to +constant `rvalue`s, which in particular allowing for more concise code in the common case +in which a `'static` reference is all that's needed. + + +## Examples + +```rust +#![feature(rvalue_static_promotion)] + +fn main() { + let DEFAULT_VALUE: &'static u32 = &42; + assert_eq!(*DEFAULT_VALUE, 42); +} +``` diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs index 11fc1d553f28e..653310b8cb591 100644 --- a/src/libcollections/slice.rs +++ b/src/libcollections/slice.rs @@ -230,7 +230,7 @@ impl [T] { core_slice::SliceExt::first_mut(self) } - /// Returns the first and all the rest of the elements of a slice. + /// Returns the first and all the rest of the elements of a slice, or `None` if it is empty. /// /// # Examples /// @@ -248,7 +248,7 @@ impl [T] { core_slice::SliceExt::split_first(self) } - /// Returns the first and all the rest of the elements of a slice. + /// Returns the first and all the rest of the elements of a slice, or `None` if it is empty. /// /// # Examples /// @@ -268,7 +268,7 @@ impl [T] { core_slice::SliceExt::split_first_mut(self) } - /// Returns the last and all the rest of the elements of a slice. + /// Returns the last and all the rest of the elements of a slice, or `None` if it is empty. /// /// # Examples /// @@ -287,7 +287,7 @@ impl [T] { } - /// Returns the last and all the rest of the elements of a slice. + /// Returns the last and all the rest of the elements of a slice, or `None` if it is empty. /// /// # Examples /// @@ -437,8 +437,8 @@ impl [T] { /// The caller must ensure that the slice outlives the pointer this /// function returns, or else it will end up pointing to garbage. /// - /// Modifying the slice may cause its buffer to be reallocated, which - /// would also make any pointers to it invalid. + /// Modifying the container referenced by this slice may cause its buffer + /// to be reallocated, which would also make any pointers to it invalid. /// /// # Examples /// @@ -463,8 +463,8 @@ impl [T] { /// The caller must ensure that the slice outlives the pointer this /// function returns, or else it will end up pointing to garbage. /// - /// Modifying the slice may cause its buffer to be reallocated, which - /// would also make any pointers to it invalid. + /// Modifying the container referenced by this slice may cause its buffer + /// to be reallocated, which would also make any pointers to it invalid. /// /// # Examples /// diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index b0c85e2ef4cd4..0cf53826dd427 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -195,6 +195,21 @@ pub struct cmt_<'tcx> { pub type cmt<'tcx> = Rc>; impl<'tcx> cmt_<'tcx> { + pub fn get_def(&self) -> Option { + match self.cat { + Categorization::Deref(ref cmt, ..) | + Categorization::Interior(ref cmt, _) | + Categorization::Downcast(ref cmt, _) => { + if let Categorization::Local(nid) = cmt.cat { + Some(nid) + } else { + None + } + } + _ => None + } + } + pub fn get_field(&self, name: ast::Name) -> Option { match self.cat { Categorization::Deref(ref cmt, ..) | @@ -843,11 +858,10 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { let promotable = self.tcx().rvalue_promotable_to_static.borrow().get(&id).cloned() .unwrap_or(false); - // Only promote `[T; 0]` before an RFC for rvalue promotions - // is accepted. + // When the corresponding feature isn't toggled, only promote `[T; 0]`. let promotable = match expr_ty.sty { ty::TyArray(_, 0) => true, - _ => promotable & false + _ => promotable && self.tcx().sess.features.borrow().rvalue_static_promotion, }; // Compute maximum lifetime of this rvalue. This is 'static if diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index b441a231874a6..20d495976b05f 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -662,6 +662,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { pub fn bckerr_to_diag(&self, err: &BckError<'tcx>) -> DiagnosticBuilder<'a> { let span = err.span.clone(); let mut immutable_field = None; + let mut local_def = None; let msg = &match err.code { err_mutbl => { @@ -711,6 +712,14 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { } None }); + local_def = err.cmt.get_def() + .and_then(|nid| { + if !self.tcx.hir.is_argument(nid) { + Some(self.tcx.hir.span(nid)) + } else { + None + } + }); format!("cannot borrow {} as mutable", descr) } @@ -741,6 +750,11 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { if let Some((span, msg)) = immutable_field { db.span_label(span, &msg); } + if let Some(let_span) = local_def { + if let Ok(snippet) = self.tcx.sess.codemap().span_to_snippet(let_span) { + db.span_label(let_span, &format!("consider changing this to `mut {}`", snippet)); + } + } db } @@ -1109,6 +1123,11 @@ before rustc 1.16, this temporary lived longer - see issue #39283 \ } else { db.span_label(*error_span, &format!("cannot borrow mutably")); } + } else if let Categorization::Interior(ref cmt, _) = err.cmt.cat { + if let mc::MutabilityCategory::McImmutable = cmt.mutbl { + db.span_label(*error_span, + &"cannot mutably borrow immutable field"); + } } } } diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 03c61067d64c2..be905a9d0f94a 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -23,7 +23,7 @@ use {resolve_error, resolve_struct_error, ResolutionError}; use rustc::middle::cstore::LoadedMacro; use rustc::hir::def::*; -use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId}; +use rustc::hir::def_id::{CrateNum, BUILTIN_MACROS_CRATE, CRATE_DEF_INDEX, DefId}; use rustc::ty; use std::cell::Cell; @@ -496,6 +496,9 @@ impl<'a> Resolver<'a> { let def_id = self.macro_defs[&expansion]; if let Some(id) = self.definitions.as_local_node_id(def_id) { self.local_macro_def_scopes[&id] + } else if def_id.krate == BUILTIN_MACROS_CRATE { + // FIXME(jseyfried): This happens when `include!()`ing a `$crate::` path, c.f, #40469. + self.graph_root } else { let module_def_id = ty::DefIdTree::parent(&*self, def_id).unwrap(); self.get_extern_crate_root(module_def_id.krate) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 660fa647882aa..eff848be2b8b9 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1387,7 +1387,7 @@ impl<'tcx> Clean for ty::AssociatedItem { decl: decl, abi: sig.abi(), - // trait methods canot (currently, at least) be const + // trait methods cannot (currently, at least) be const constness: hir::Constness::NotConst, }) } else { diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index a9da8edc379fc..7b60d497932de 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -60,6 +60,7 @@ use rustc::middle::privacy::AccessLevels; use rustc::middle::stability; use rustc::hir; use rustc::util::nodemap::{FxHashMap, FxHashSet}; +use rustc::session::config::nightly_options::is_nightly_build; use rustc_data_structures::flock; use clean::{self, AttributesExt, GetDefId, SelfTy, Mutability}; @@ -2316,9 +2317,10 @@ fn render_assoc_item(w: &mut fmt::Formatter, } }; // FIXME(#24111): remove when `const_fn` is stabilized - let vis_constness = match UnstableFeatures::from_environment() { - UnstableFeatures::Allow => constness, - _ => hir::Constness::NotConst + let vis_constness = if is_nightly_build() { + constness + } else { + hir::Constness::NotConst }; let prefix = format!("{}{}{:#}fn {}{:#}", ConstnessSpace(vis_constness), diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index 3ca8b41347a26..5733217008146 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -222,8 +222,8 @@ const DISPLACEMENT_THRESHOLD: usize = 128; /// resistance against HashDoS attacks. The algorithm is randomly seeded, and a /// reasonable best-effort is made to generate this seed from a high quality, /// secure source of randomness provided by the host without blocking the -/// program. Because of this, the randomness of the seed is dependant on the -/// quality of the system's random number generator at the time it is created. +/// program. Because of this, the randomness of the seed depends on the output +/// quality of the system's random number generator when the seed is created. /// In particular, seeds generated when the system's entropy pool is abnormally /// low such as during system boot may be of a lower quality. /// diff --git a/src/libstd/net/ip.rs b/src/libstd/net/ip.rs index 5d6e8d319d7b2..24e0e6f3fa659 100644 --- a/src/libstd/net/ip.rs +++ b/src/libstd/net/ip.rs @@ -636,6 +636,7 @@ impl FromInner for Ipv4Addr { #[stable(feature = "ip_u32", since = "1.1.0")] impl From for u32 { + /// It performs the conversion in network order (big-endian). fn from(ip: Ipv4Addr) -> u32 { let ip = ip.octets(); ((ip[0] as u32) << 24) + ((ip[1] as u32) << 16) + ((ip[2] as u32) << 8) + (ip[3] as u32) @@ -644,6 +645,7 @@ impl From for u32 { #[stable(feature = "ip_u32", since = "1.1.0")] impl From for Ipv4Addr { + /// It performs the conversion in network order (big-endian). fn from(ip: u32) -> Ipv4Addr { Ipv4Addr::new((ip >> 24) as u8, (ip >> 16) as u8, (ip >> 8) as u8, ip as u8) } diff --git a/src/libstd/path.rs b/src/libstd/path.rs index a744407903b1e..db446d88900c1 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -1501,7 +1501,7 @@ impl Path { /// assert_eq!(path.to_string_lossy(), "foo.txt"); /// ``` /// - /// Had `os_str` contained invalid unicode, the `to_string_lossy` call might + /// Had `path` contained invalid unicode, the `to_string_lossy` call might /// have returned `"fo�.txt"`. #[stable(feature = "rust1", since = "1.0.0")] pub fn to_string_lossy(&self) -> Cow { diff --git a/src/libstd/sync/mutex.rs b/src/libstd/sync/mutex.rs index 48d8d34dbe090..d79be2944c9e3 100644 --- a/src/libstd/sync/mutex.rs +++ b/src/libstd/sync/mutex.rs @@ -132,7 +132,7 @@ unsafe impl Sync for Mutex { } /// An RAII implementation of a "scoped lock" of a mutex. When this structure is /// dropped (falls out of scope), the lock will be unlocked. /// -/// The data protected by the mutex can be access through this guard via its +/// The data protected by the mutex can be accessed through this guard via its /// [`Deref`] and [`DerefMut`] implementations. /// /// This structure is created by the [`lock`] and [`try_lock`] methods on diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 1e06ee97e0bc7..d07069d030a1b 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -342,6 +342,9 @@ declare_features! ( // Allows the `catch {...}` expression (active, catch_expr, "1.17.0", Some(31436)), + + // See rust-lang/rfcs#1414. Allows code like `let x: &'static u32 = &42` to work. + (active, rvalue_static_promotion, "1.15.1", Some(38865)), ); declare_features! ( diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index de8a87e3a2b32..d48cf6911ed37 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -725,7 +725,7 @@ impl<'a> StringReader<'a> { base = 16; num_digits = self.scan_digits(16, 16); } - '0'...'9' | '_' | '.' => { + '0'...'9' | '_' | '.' | 'e' | 'E' => { num_digits = self.scan_digits(10, 10) + 1; } _ => { diff --git a/src/test/compile-fail/feature-gate-rvalue_static_promotion.rs b/src/test/compile-fail/feature-gate-rvalue_static_promotion.rs new file mode 100644 index 0000000000000..f33d0a71481d2 --- /dev/null +++ b/src/test/compile-fail/feature-gate-rvalue_static_promotion.rs @@ -0,0 +1,15 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[allow(unused_variables)] +fn main() { + let x: &'static u32 = &42; //~ error: does not live long enough + let y: &'static Option = &None; //~ error: does not live long enough +} diff --git a/src/test/run-pass/auxiliary/issue_40469.rs b/src/test/run-pass/auxiliary/issue_40469.rs new file mode 100644 index 0000000000000..4970bba431a84 --- /dev/null +++ b/src/test/run-pass/auxiliary/issue_40469.rs @@ -0,0 +1,11 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +macro_rules! m { () => { $crate::main(); } } diff --git a/src/test/run-pass/issue-34571.rs b/src/test/run-pass/issue-34571.rs new file mode 100644 index 0000000000000..7d80415657655 --- /dev/null +++ b/src/test/run-pass/issue-34571.rs @@ -0,0 +1,20 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[repr(u8)] +enum Foo { + Foo(u8), +} + +fn main() { + match Foo::Foo(1) { + _ => () + } +} diff --git a/src/test/run-pass/issue-40408.rs b/src/test/run-pass/issue-40408.rs new file mode 100644 index 0000000000000..a73dc1966b4be --- /dev/null +++ b/src/test/run-pass/issue-40408.rs @@ -0,0 +1,16 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + println!("{}", 0E+10); + println!("{}", 0e+10); + println!("{}", 00e+10); + println!("{}", 00E+10); +} diff --git a/src/test/run-pass/issue-40469.rs b/src/test/run-pass/issue-40469.rs new file mode 100644 index 0000000000000..30055e532cd45 --- /dev/null +++ b/src/test/run-pass/issue-40469.rs @@ -0,0 +1,18 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// ignore-pretty issue #37195 + +#![allow(dead_code)] + +include!("auxiliary/issue_40469.rs"); +fn f() { m!(); } + +fn main() {} diff --git a/src/test/run-pass/rvalue-static-promotion.rs b/src/test/run-pass/rvalue-static-promotion.rs new file mode 100644 index 0000000000000..30643cfc3eb7d --- /dev/null +++ b/src/test/run-pass/rvalue-static-promotion.rs @@ -0,0 +1,17 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(rvalue_static_promotion)] + +#[allow(unused_variables)] +fn main() { + let x: &'static u32 = &42; + let y: &'static Option = &None; +} diff --git a/src/test/rustdoc/const.rs b/src/test/rustdoc/const.rs new file mode 100644 index 0000000000000..380feb941d6fe --- /dev/null +++ b/src/test/rustdoc/const.rs @@ -0,0 +1,22 @@ +// Copyright 2015 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![crate_type="lib"] + +#![feature(const_fn)] + +pub struct Foo; + +impl Foo { + // @has const/struct.Foo.html '//*[@id="new.v"]//code' 'const unsafe fn new' + pub const unsafe fn new() -> Foo { + Foo + } +} diff --git a/src/test/ui/did_you_mean/issue-39544.stderr b/src/test/ui/did_you_mean/issue-39544.stderr index c0088f39ad3e1..7f124e6d34d35 100644 --- a/src/test/ui/did_you_mean/issue-39544.stderr +++ b/src/test/ui/did_you_mean/issue-39544.stderr @@ -1,8 +1,10 @@ error: cannot borrow immutable field `z.x` as mutable --> $DIR/issue-39544.rs:21:18 | +20 | let z = Z { x: X::Y }; + | - consider changing this to `mut z` 21 | let _ = &mut z.x; - | ^^^ + | ^^^ cannot mutably borrow immutable field error: aborting due to previous error