Auto merge of #48860 - Manishearth:rollup, r=Manishearth
Rollup of 5 pull requests - Successful merges: #48527, #48588, #48801, #48856, #48857 - Failed merges:
This commit is contained in:
commit
2079a084df
12
src/Cargo.lock
generated
12
src/Cargo.lock
generated
@ -78,7 +78,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
version = "0.2.6"
|
||||
version = "0.2.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -179,7 +179,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
name = "cargo"
|
||||
version = "0.26.0"
|
||||
dependencies = [
|
||||
"atty 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"atty 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bufstream 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cargotest 0.1.0",
|
||||
"core-foundation 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -289,7 +289,7 @@ version = "2.29.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"atty 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"atty 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -645,7 +645,7 @@ name = "env_logger"
|
||||
version = "0.5.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"atty 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"atty 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -1923,9 +1923,11 @@ dependencies = [
|
||||
name = "rustc_errors"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"atty 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc_data_structures 0.0.0",
|
||||
"serialize 0.0.0",
|
||||
"syntax_pos 0.0.0",
|
||||
"termcolor 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@ -2843,7 +2845,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
"checksum ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6b3568b48b7cefa6b8ce125f9bb4989e52fbcc29ebea88df04cc7c5f12f70455"
|
||||
"checksum ar 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "35c7a5669cb64f085739387e1308b74e6d44022464b7f1b63bbd4ceb6379ec31"
|
||||
"checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef"
|
||||
"checksum atty 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "8352656fd42c30a0c3c89d26dea01e3b77c0ab2af18230835c15e2e13cd51859"
|
||||
"checksum atty 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "af80143d6f7608d746df1520709e5d141c96f240b0e62b0aa41bdfb53374d9d4"
|
||||
"checksum backtrace 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ebbbf59b1c43eefa8c3ede390fcc36820b4999f7914104015be25025e0d62af2"
|
||||
"checksum backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "44585761d6161b0f57afc49482ab6bd067e4edef48c12a152c237eb0203f7661"
|
||||
"checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d"
|
||||
|
@ -17,7 +17,6 @@
|
||||
use errors::DiagnosticBuilder;
|
||||
use lint::{LintPass, LateLintPass, LintArray};
|
||||
use session::Session;
|
||||
use session::config::Epoch;
|
||||
use syntax::codemap::Span;
|
||||
|
||||
declare_lint! {
|
||||
@ -264,9 +263,8 @@
|
||||
|
||||
declare_lint! {
|
||||
pub BARE_TRAIT_OBJECT,
|
||||
Warn,
|
||||
"suggest using `dyn Trait` for trait objects",
|
||||
Epoch::Epoch2018
|
||||
Allow,
|
||||
"suggest using `dyn Trait` for trait objects"
|
||||
}
|
||||
|
||||
declare_lint! {
|
||||
|
@ -42,6 +42,7 @@
|
||||
use std::default::Default as StdDefault;
|
||||
use std::cell::{Ref, RefCell};
|
||||
use syntax::ast;
|
||||
use syntax::epoch;
|
||||
use syntax_pos::{MultiSpan, Span};
|
||||
use errors::DiagnosticBuilder;
|
||||
use hir;
|
||||
@ -105,7 +106,7 @@ pub struct FutureIncompatibleInfo {
|
||||
pub reference: &'static str,
|
||||
/// If this is an epoch fixing lint, the epoch in which
|
||||
/// this lint becomes obsolete
|
||||
pub epoch: Option<config::Epoch>,
|
||||
pub epoch: Option<epoch::Epoch>,
|
||||
}
|
||||
|
||||
/// The target of the `by_name` map, which accounts for renaming/deprecation.
|
||||
@ -201,7 +202,7 @@ pub fn register_future_incompatible(&mut self,
|
||||
sess: Option<&Session>,
|
||||
lints: Vec<FutureIncompatibleInfo>) {
|
||||
|
||||
for epoch in config::ALL_EPOCHS {
|
||||
for epoch in epoch::ALL_EPOCHS {
|
||||
let lints = lints.iter().filter(|f| f.epoch == Some(*epoch)).map(|f| f.id)
|
||||
.collect::<Vec<_>>();
|
||||
if !lints.is_empty() {
|
||||
|
@ -38,10 +38,11 @@
|
||||
use hir::intravisit::{self, FnKind};
|
||||
use hir;
|
||||
use lint::builtin::BuiltinLintDiagnostics;
|
||||
use session::{config, Session, DiagnosticMessageId};
|
||||
use session::{Session, DiagnosticMessageId};
|
||||
use std::hash;
|
||||
use syntax::ast;
|
||||
use syntax::codemap::MultiSpan;
|
||||
use syntax::epoch::Epoch;
|
||||
use syntax::symbol::Symbol;
|
||||
use syntax::visit as ast_visit;
|
||||
use syntax_pos::Span;
|
||||
@ -77,7 +78,7 @@ pub struct Lint {
|
||||
pub desc: &'static str,
|
||||
|
||||
/// Deny lint after this epoch
|
||||
pub epoch_deny: Option<config::Epoch>,
|
||||
pub epoch_deny: Option<Epoch>,
|
||||
}
|
||||
|
||||
impl Lint {
|
||||
@ -492,9 +493,14 @@ pub fn struct_lint_level<'a>(sess: &'a Session,
|
||||
// Check for future incompatibility lints and issue a stronger warning.
|
||||
let lints = sess.lint_store.borrow();
|
||||
if let Some(future_incompatible) = lints.future_incompatible(LintId::of(lint)) {
|
||||
let future = if let Some(epoch) = future_incompatible.epoch {
|
||||
format!("the {} epoch", epoch)
|
||||
} else {
|
||||
"a future release".to_owned()
|
||||
};
|
||||
let explanation = format!("this was previously accepted by the compiler \
|
||||
but is being phased out; \
|
||||
it will become a hard error in a future release!");
|
||||
it will become a hard error in {}!", future);
|
||||
let citation = format!("for more information, see {}",
|
||||
future_incompatible.reference);
|
||||
err.warn(&explanation);
|
||||
|
@ -28,6 +28,7 @@
|
||||
|
||||
use syntax::ast::{self, IntTy, UintTy};
|
||||
use syntax::codemap::{FileName, FilePathMapping};
|
||||
use syntax::epoch::Epoch;
|
||||
use syntax::parse::token;
|
||||
use syntax::parse;
|
||||
use syntax::symbol::Symbol;
|
||||
@ -111,59 +112,6 @@ pub enum OutputType {
|
||||
DepInfo,
|
||||
}
|
||||
|
||||
/// The epoch of the compiler (RFC 2052)
|
||||
#[derive(Clone, Copy, Hash, PartialOrd, Ord, Eq, PartialEq, Debug)]
|
||||
#[non_exhaustive]
|
||||
pub enum Epoch {
|
||||
// epochs must be kept in order, newest to oldest
|
||||
/// The 2015 epoch
|
||||
Epoch2015,
|
||||
/// The 2018 epoch
|
||||
Epoch2018,
|
||||
// when adding new epochs, be sure to update:
|
||||
//
|
||||
// - the list in the `parse_epoch` static
|
||||
// - the match in the `parse_epoch` function
|
||||
// - add a `rust_####()` function to the session
|
||||
// - update the enum in Cargo's sources as well
|
||||
//
|
||||
// When -Zepoch becomes --epoch, there will
|
||||
// also be a check for the epoch being nightly-only
|
||||
// somewhere. That will need to be updated
|
||||
// whenever we're stabilizing/introducing a new epoch
|
||||
// as well as changing the default Cargo template.
|
||||
}
|
||||
|
||||
pub const ALL_EPOCHS: &[Epoch] = &[Epoch::Epoch2015, Epoch::Epoch2018];
|
||||
|
||||
impl ToString for Epoch {
|
||||
fn to_string(&self) -> String {
|
||||
match *self {
|
||||
Epoch::Epoch2015 => "2015".into(),
|
||||
Epoch::Epoch2018 => "2018".into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Epoch {
|
||||
pub fn lint_name(&self) -> &'static str {
|
||||
match *self {
|
||||
Epoch::Epoch2015 => "epoch_2015",
|
||||
Epoch::Epoch2018 => "epoch_2018",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl str::FromStr for Epoch {
|
||||
type Err = ();
|
||||
fn from_str(s: &str) -> Result<Self, ()> {
|
||||
match s {
|
||||
"2015" => Ok(Epoch::Epoch2015),
|
||||
"2018" => Ok(Epoch::Epoch2018),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl_stable_hash_for!(enum self::OutputType {
|
||||
Bitcode,
|
||||
@ -829,9 +777,10 @@ mod $mod_desc {
|
||||
|
||||
#[allow(dead_code)]
|
||||
mod $mod_set {
|
||||
use super::{$struct_name, Passes, SomePasses, AllPasses, Sanitizer, Lto, Epoch};
|
||||
use super::{$struct_name, Passes, SomePasses, AllPasses, Sanitizer, Lto};
|
||||
use rustc_back::{LinkerFlavor, PanicStrategy, RelroLevel};
|
||||
use std::path::PathBuf;
|
||||
use syntax::epoch::Epoch;
|
||||
|
||||
$(
|
||||
pub fn $opt(cg: &mut $struct_name, v: Option<&str>) -> bool {
|
||||
|
@ -20,7 +20,7 @@
|
||||
use middle::allocator::AllocatorKind;
|
||||
use middle::dependency_format;
|
||||
use session::search_paths::PathKind;
|
||||
use session::config::{DebugInfoLevel, Epoch, OutputType};
|
||||
use session::config::{DebugInfoLevel, OutputType};
|
||||
use ty::tls;
|
||||
use util::nodemap::{FxHashMap, FxHashSet};
|
||||
use util::common::{duration_to_secs_str, ErrorReported};
|
||||
@ -30,6 +30,7 @@
|
||||
use syntax::ast::NodeId;
|
||||
use errors::{self, DiagnosticBuilder, DiagnosticId};
|
||||
use errors::emitter::{Emitter, EmitterWriter};
|
||||
use syntax::epoch::Epoch;
|
||||
use syntax::json::JsonEmitter;
|
||||
use syntax::feature_gate;
|
||||
use syntax::symbol::Symbol;
|
||||
|
@ -647,7 +647,9 @@ pub fn phase_2_configure_and_expand_inner<'a, F>(sess: &'a Session,
|
||||
{
|
||||
let time_passes = sess.time_passes();
|
||||
|
||||
let (mut krate, features) = syntax::config::features(krate, &sess.parse_sess, sess.opts.test);
|
||||
let (mut krate, features) = syntax::config::features(krate, &sess.parse_sess,
|
||||
sess.opts.test,
|
||||
sess.opts.debugging_opts.epoch);
|
||||
// these need to be set "early" so that expansion sees `quote` if enabled.
|
||||
sess.init_features(features);
|
||||
|
||||
|
@ -13,3 +13,5 @@ serialize = { path = "../libserialize" }
|
||||
syntax_pos = { path = "../libsyntax_pos" }
|
||||
rustc_data_structures = { path = "../librustc_data_structures" }
|
||||
unicode-width = "0.1.4"
|
||||
atty = "0.2"
|
||||
termcolor = "0.3"
|
||||
|
@ -17,12 +17,14 @@
|
||||
use styled_buffer::StyledBuffer;
|
||||
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use atty;
|
||||
use std::borrow::Cow;
|
||||
use std::io::prelude::*;
|
||||
use std::io;
|
||||
use term;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::cmp::min;
|
||||
use termcolor::{StandardStream, ColorChoice, ColorSpec, BufferWriter};
|
||||
use termcolor::{WriteColor, Color, Buffer};
|
||||
use unicode_width;
|
||||
|
||||
const ANONYMIZED_LINE_NUM: &str = "LL";
|
||||
@ -95,11 +97,14 @@ pub enum ColorConfig {
|
||||
}
|
||||
|
||||
impl ColorConfig {
|
||||
fn use_color(&self) -> bool {
|
||||
fn to_color_choice(&self) -> ColorChoice {
|
||||
match *self {
|
||||
ColorConfig::Always => true,
|
||||
ColorConfig::Never => false,
|
||||
ColorConfig::Auto => stderr_isatty(),
|
||||
ColorConfig::Always => ColorChoice::Always,
|
||||
ColorConfig::Never => ColorChoice::Never,
|
||||
ColorConfig::Auto if atty::is(atty::Stream::Stderr) => {
|
||||
ColorChoice::Auto
|
||||
}
|
||||
ColorConfig::Auto => ColorChoice::Never,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -123,25 +128,26 @@ impl Drop for EmitterWriter {
|
||||
fn drop(&mut self) {
|
||||
if !self.short_message && !self.error_codes.is_empty() {
|
||||
let mut error_codes = self.error_codes.clone().into_iter().collect::<Vec<_>>();
|
||||
let mut dst = self.dst.writable();
|
||||
error_codes.sort();
|
||||
if error_codes.len() > 1 {
|
||||
let limit = if error_codes.len() > 9 { 9 } else { error_codes.len() };
|
||||
writeln!(self.dst,
|
||||
writeln!(dst,
|
||||
"You've got a few errors: {}{}",
|
||||
error_codes[..limit].join(", "),
|
||||
if error_codes.len() > 9 { "..." } else { "" }
|
||||
).expect("failed to give tips...");
|
||||
writeln!(self.dst,
|
||||
writeln!(dst,
|
||||
"If you want more information on an error, try using \
|
||||
\"rustc --explain {}\"",
|
||||
&error_codes[0]).expect("failed to give tips...");
|
||||
} else {
|
||||
writeln!(self.dst,
|
||||
writeln!(dst,
|
||||
"If you want more information on this error, try using \
|
||||
\"rustc --explain {}\"",
|
||||
&error_codes[0]).expect("failed to give tips...");
|
||||
}
|
||||
self.dst.flush().expect("failed to emit errors");
|
||||
dst.flush().expect("failed to emit errors");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -152,25 +158,14 @@ pub fn stderr(color_config: ColorConfig,
|
||||
short_message: bool,
|
||||
teach: bool)
|
||||
-> EmitterWriter {
|
||||
if color_config.use_color() {
|
||||
let dst = Destination::from_stderr();
|
||||
EmitterWriter {
|
||||
dst,
|
||||
cm: code_map,
|
||||
short_message,
|
||||
teach,
|
||||
error_codes: HashSet::new(),
|
||||
ui_testing: false,
|
||||
}
|
||||
} else {
|
||||
EmitterWriter {
|
||||
dst: Raw(Box::new(io::stderr())),
|
||||
cm: code_map,
|
||||
short_message,
|
||||
teach,
|
||||
error_codes: HashSet::new(),
|
||||
ui_testing: false,
|
||||
}
|
||||
let dst = Destination::from_stderr(color_config);
|
||||
EmitterWriter {
|
||||
dst,
|
||||
cm: code_map,
|
||||
short_message,
|
||||
teach,
|
||||
error_codes: HashSet::new(),
|
||||
ui_testing: false,
|
||||
}
|
||||
}
|
||||
|
||||
@ -1356,10 +1351,12 @@ fn emit_messages_default(&mut self,
|
||||
}
|
||||
Err(e) => panic!("failed to emit error: {}", e),
|
||||
}
|
||||
match write!(&mut self.dst, "\n") {
|
||||
|
||||
let mut dst = self.dst.writable();
|
||||
match write!(dst, "\n") {
|
||||
Err(e) => panic!("failed to emit error: {}", e),
|
||||
_ => {
|
||||
match self.dst.flush() {
|
||||
match dst.flush() {
|
||||
Err(e) => panic!("failed to emit error: {}", e),
|
||||
_ => (),
|
||||
}
|
||||
@ -1424,6 +1421,8 @@ fn emit_to_destination(rendered_buffer: &Vec<Vec<StyledString>>,
|
||||
-> io::Result<()> {
|
||||
use lock;
|
||||
|
||||
let mut dst = dst.writable();
|
||||
|
||||
// In order to prevent error message interleaving, where multiple error lines get intermixed
|
||||
// when multiple compiler processes error simultaneously, we emit errors with additional
|
||||
// steps.
|
||||
@ -1444,7 +1443,7 @@ fn emit_to_destination(rendered_buffer: &Vec<Vec<StyledString>>,
|
||||
if !short_message && part.text.len() == 12 && part.text.starts_with("error[E") {
|
||||
error_codes.insert(part.text[6..11].to_owned());
|
||||
}
|
||||
dst.reset_attrs()?;
|
||||
dst.reset()?;
|
||||
}
|
||||
if !short_message {
|
||||
write!(dst, "\n")?;
|
||||
@ -1454,180 +1453,136 @@ fn emit_to_destination(rendered_buffer: &Vec<Vec<StyledString>>,
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn stderr_isatty() -> bool {
|
||||
use libc;
|
||||
unsafe { libc::isatty(libc::STDERR_FILENO) != 0 }
|
||||
}
|
||||
#[cfg(windows)]
|
||||
fn stderr_isatty() -> bool {
|
||||
type DWORD = u32;
|
||||
type BOOL = i32;
|
||||
type HANDLE = *mut u8;
|
||||
const STD_ERROR_HANDLE: DWORD = -12i32 as DWORD;
|
||||
extern "system" {
|
||||
fn GetStdHandle(which: DWORD) -> HANDLE;
|
||||
fn GetConsoleMode(hConsoleHandle: HANDLE, lpMode: *mut DWORD) -> BOOL;
|
||||
}
|
||||
unsafe {
|
||||
let handle = GetStdHandle(STD_ERROR_HANDLE);
|
||||
let mut out = 0;
|
||||
GetConsoleMode(handle, &mut out) != 0
|
||||
}
|
||||
}
|
||||
|
||||
pub type BufferedStderr = term::Terminal<Output = BufferedWriter> + Send;
|
||||
|
||||
pub enum Destination {
|
||||
Terminal(Box<term::StderrTerminal>),
|
||||
BufferedTerminal(Box<BufferedStderr>),
|
||||
Terminal(StandardStream),
|
||||
Buffered(BufferWriter),
|
||||
Raw(Box<Write + Send>),
|
||||
}
|
||||
|
||||
/// Buffered writer gives us a way on Unix to buffer up an entire error message before we output
|
||||
/// it. This helps to prevent interleaving of multiple error messages when multiple compiler
|
||||
/// processes error simultaneously
|
||||
pub struct BufferedWriter {
|
||||
buffer: Vec<u8>,
|
||||
}
|
||||
|
||||
impl BufferedWriter {
|
||||
// note: we use _new because the conditional compilation at its use site may make this
|
||||
// this function unused on some platforms
|
||||
fn _new() -> BufferedWriter {
|
||||
BufferedWriter { buffer: vec![] }
|
||||
}
|
||||
}
|
||||
|
||||
impl Write for BufferedWriter {
|
||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
for b in buf {
|
||||
self.buffer.push(*b);
|
||||
}
|
||||
Ok(buf.len())
|
||||
}
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
let mut stderr = io::stderr();
|
||||
let result = stderr.write_all(&self.buffer)
|
||||
.and_then(|_| stderr.flush());
|
||||
self.buffer.clear();
|
||||
result
|
||||
}
|
||||
pub enum WritableDst<'a> {
|
||||
Terminal(&'a mut StandardStream),
|
||||
Buffered(&'a mut BufferWriter, Buffer),
|
||||
Raw(&'a mut Box<Write + Send>),
|
||||
}
|
||||
|
||||
impl Destination {
|
||||
#[cfg(not(windows))]
|
||||
/// When not on Windows, prefer the buffered terminal so that we can buffer an entire error
|
||||
/// to be emitted at one time.
|
||||
fn from_stderr() -> Destination {
|
||||
let stderr: Option<Box<BufferedStderr>> =
|
||||
term::TerminfoTerminal::new(BufferedWriter::_new())
|
||||
.map(|t| Box::new(t) as Box<BufferedStderr>);
|
||||
|
||||
match stderr {
|
||||
Some(t) => BufferedTerminal(t),
|
||||
None => Raw(Box::new(io::stderr())),
|
||||
fn from_stderr(color: ColorConfig) -> Destination {
|
||||
let choice = color.to_color_choice();
|
||||
// On Windows we'll be performing global synchronization on the entire
|
||||
// system for emitting rustc errors, so there's no need to buffer
|
||||
// anything.
|
||||
//
|
||||
// On non-Windows we rely on the atomicity of `write` to ensure errors
|
||||
// don't get all jumbled up.
|
||||
if cfg!(windows) {
|
||||
Terminal(StandardStream::stderr(choice))
|
||||
} else {
|
||||
Buffered(BufferWriter::stderr(choice))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
/// Return a normal, unbuffered terminal when on Windows.
|
||||
fn from_stderr() -> Destination {
|
||||
let stderr: Option<Box<term::StderrTerminal>> = term::TerminfoTerminal::new(io::stderr())
|
||||
.map(|t| Box::new(t) as Box<term::StderrTerminal>)
|
||||
.or_else(|| {
|
||||
term::WinConsole::new(io::stderr())
|
||||
.ok()
|
||||
.map(|t| Box::new(t) as Box<term::StderrTerminal>)
|
||||
});
|
||||
|
||||
match stderr {
|
||||
Some(t) => Terminal(t),
|
||||
None => Raw(Box::new(io::stderr())),
|
||||
fn writable<'a>(&'a mut self) -> WritableDst<'a> {
|
||||
match *self {
|
||||
Destination::Terminal(ref mut t) => WritableDst::Terminal(t),
|
||||
Destination::Buffered(ref mut t) => {
|
||||
let buf = t.buffer();
|
||||
WritableDst::Buffered(t, buf)
|
||||
}
|
||||
Destination::Raw(ref mut t) => WritableDst::Raw(t),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> WritableDst<'a> {
|
||||
fn apply_style(&mut self, lvl: Level, style: Style) -> io::Result<()> {
|
||||
let mut spec = ColorSpec::new();
|
||||
match style {
|
||||
Style::LineAndColumn => {}
|
||||
Style::LineNumber => {
|
||||
self.start_attr(term::Attr::Bold)?;
|
||||
spec.set_bold(true);
|
||||
spec.set_intense(true);
|
||||
if cfg!(windows) {
|
||||
self.start_attr(term::Attr::ForegroundColor(term::color::BRIGHT_CYAN))?;
|
||||
spec.set_fg(Some(Color::Cyan));
|
||||
} else {
|
||||
self.start_attr(term::Attr::ForegroundColor(term::color::BRIGHT_BLUE))?;
|
||||
spec.set_fg(Some(Color::Blue));
|
||||
}
|
||||
}
|
||||
Style::Quotation => {}
|
||||
Style::OldSchoolNoteText | Style::HeaderMsg => {
|
||||
self.start_attr(term::Attr::Bold)?;
|
||||
spec.set_bold(true);
|
||||
if cfg!(windows) {
|
||||
self.start_attr(term::Attr::ForegroundColor(term::color::BRIGHT_WHITE))?;
|
||||
spec.set_intense(true)
|
||||
.set_fg(Some(Color::White));
|
||||
}
|
||||
}
|
||||
Style::UnderlinePrimary | Style::LabelPrimary => {
|
||||
self.start_attr(term::Attr::Bold)?;
|
||||
self.start_attr(term::Attr::ForegroundColor(lvl.color()))?;
|
||||
spec = lvl.color();
|
||||
spec.set_bold(true);
|
||||
}
|
||||
Style::UnderlineSecondary |
|
||||
Style::LabelSecondary => {
|
||||
self.start_attr(term::Attr::Bold)?;
|
||||
spec.set_bold(true)
|
||||
.set_intense(true);
|
||||
if cfg!(windows) {
|
||||
self.start_attr(term::Attr::ForegroundColor(term::color::BRIGHT_CYAN))?;
|
||||
spec.set_fg(Some(Color::Cyan));
|
||||
} else {
|
||||
self.start_attr(term::Attr::ForegroundColor(term::color::BRIGHT_BLUE))?;
|
||||
spec.set_fg(Some(Color::Blue));
|
||||
}
|
||||
}
|
||||
Style::NoStyle => {}
|
||||
Style::Level(l) => {
|
||||
self.start_attr(term::Attr::Bold)?;
|
||||
self.start_attr(term::Attr::ForegroundColor(l.color()))?;
|
||||
Style::Level(lvl) => {
|
||||
spec = lvl.color();
|
||||
spec.set_bold(true);
|
||||
}
|
||||
Style::Highlight => {
|
||||
spec.set_bold(true);
|
||||
}
|
||||
Style::Highlight => self.start_attr(term::Attr::Bold)?,
|
||||
}
|
||||
Ok(())
|
||||
self.set_color(&spec)
|
||||
}
|
||||
|
||||
fn start_attr(&mut self, attr: term::Attr) -> io::Result<()> {
|
||||
fn set_color(&mut self, color: &ColorSpec) -> io::Result<()> {
|
||||
match *self {
|
||||
Terminal(ref mut t) => {
|
||||
t.attr(attr)?;
|
||||
}
|
||||
BufferedTerminal(ref mut t) => {
|
||||
t.attr(attr)?;
|
||||
}
|
||||
Raw(_) => {}
|
||||
WritableDst::Terminal(ref mut t) => t.set_color(color),
|
||||
WritableDst::Buffered(_, ref mut t) => t.set_color(color),
|
||||
WritableDst::Raw(_) => Ok(())
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn reset_attrs(&mut self) -> io::Result<()> {
|
||||
fn reset(&mut self) -> io::Result<()> {
|
||||
match *self {
|
||||
Terminal(ref mut t) => {
|
||||
t.reset()?;
|
||||
}
|
||||
BufferedTerminal(ref mut t) => {
|
||||
t.reset()?;
|
||||
}
|
||||
Raw(_) => {}
|
||||
WritableDst::Terminal(ref mut t) => t.reset(),
|
||||
WritableDst::Buffered(_, ref mut t) => t.reset(),
|
||||
WritableDst::Raw(_) => Ok(()),
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Write for Destination {
|
||||
impl<'a> Write for WritableDst<'a> {
|
||||
fn write(&mut self, bytes: &[u8]) -> io::Result<usize> {
|
||||
match *self {
|
||||
Terminal(ref mut t) => t.write(bytes),
|
||||
BufferedTerminal(ref mut t) => t.write(bytes),
|
||||
Raw(ref mut w) => w.write(bytes),
|
||||
WritableDst::Terminal(ref mut t) => t.write(bytes),
|
||||
WritableDst::Buffered(_, ref mut buf) => buf.write(bytes),
|
||||
WritableDst::Raw(ref mut w) => w.write(bytes),
|
||||
}
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
match *self {
|
||||
Terminal(ref mut t) => t.flush(),
|
||||
BufferedTerminal(ref mut t) => t.flush(),
|
||||
Raw(ref mut w) => w.flush(),
|
||||
WritableDst::Terminal(ref mut t) => t.flush(),
|
||||
WritableDst::Buffered(_, ref mut buf) => buf.flush(),
|
||||
WritableDst::Raw(ref mut w) => w.flush(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Drop for WritableDst<'a> {
|
||||
fn drop(&mut self) {
|
||||
match *self {
|
||||
WritableDst::Buffered(ref mut dst, ref mut buf) => {
|
||||
drop(dst.print(buf));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,8 @@
|
||||
#![feature(i128_type)]
|
||||
#![feature(optin_builtin_traits)]
|
||||
|
||||
extern crate term;
|
||||
extern crate atty;
|
||||
extern crate termcolor;
|
||||
#[cfg(unix)]
|
||||
extern crate libc;
|
||||
extern crate rustc_data_structures;
|
||||
@ -47,6 +48,8 @@
|
||||
use std::sync::atomic::Ordering::SeqCst;
|
||||
use std::panic;
|
||||
|
||||
use termcolor::{ColorSpec, Color};
|
||||
|
||||
mod diagnostic;
|
||||
mod diagnostic_builder;
|
||||
pub mod emitter;
|
||||
@ -660,20 +663,28 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
}
|
||||
|
||||
impl Level {
|
||||
fn color(self) -> term::color::Color {
|
||||
fn color(self) -> ColorSpec {
|
||||
let mut spec = ColorSpec::new();
|
||||
match self {
|
||||
Bug | Fatal | PhaseFatal | Error => term::color::BRIGHT_RED,
|
||||
Warning => {
|
||||
if cfg!(windows) {
|
||||
term::color::BRIGHT_YELLOW
|
||||
} else {
|
||||
term::color::YELLOW
|
||||
}
|
||||
Bug | Fatal | PhaseFatal | Error => {
|
||||
spec.set_fg(Some(Color::Red))
|
||||
.set_intense(true);
|
||||
}
|
||||
Warning => {
|
||||
spec.set_fg(Some(Color::Yellow))
|
||||
.set_intense(cfg!(windows));
|
||||
}
|
||||
Note => {
|
||||
spec.set_fg(Some(Color::Green))
|
||||
.set_intense(true);
|
||||
}
|
||||
Help => {
|
||||
spec.set_fg(Some(Color::Cyan))
|
||||
.set_intense(true);
|
||||
}
|
||||
Note => term::color::BRIGHT_GREEN,
|
||||
Help => term::color::BRIGHT_CYAN,
|
||||
Cancelled => unreachable!(),
|
||||
}
|
||||
return spec
|
||||
}
|
||||
|
||||
pub fn to_str(self) -> &'static str {
|
||||
|
@ -1263,7 +1263,7 @@ fn check_item(&mut self, ctx: &LateContext, item: &hir::Item) {
|
||||
pub struct UnreachablePub;
|
||||
|
||||
declare_lint! {
|
||||
UNREACHABLE_PUB,
|
||||
pub UNREACHABLE_PUB,
|
||||
Allow,
|
||||
"`pub` items not reachable from crate root"
|
||||
}
|
||||
|
@ -43,10 +43,12 @@
|
||||
extern crate syntax_pos;
|
||||
|
||||
use rustc::lint;
|
||||
use rustc::lint::builtin::BARE_TRAIT_OBJECT;
|
||||
use rustc::session;
|
||||
use rustc::util;
|
||||
|
||||
use session::Session;
|
||||
use syntax::epoch::Epoch;
|
||||
use lint::LintId;
|
||||
use lint::FutureIncompatibleInfo;
|
||||
|
||||
@ -176,6 +178,11 @@ macro_rules! add_lint_group {
|
||||
UNUSED_FEATURES,
|
||||
UNUSED_PARENS);
|
||||
|
||||
add_lint_group!(sess,
|
||||
"rust_2018_idioms",
|
||||
BARE_TRAIT_OBJECT,
|
||||
UNREACHABLE_PUB);
|
||||
|
||||
// Guidelines for creating a future incompatibility lint:
|
||||
//
|
||||
// - Create a lint defaulting to warn as normal, with ideally the same error
|
||||
@ -274,13 +281,8 @@ macro_rules! add_lint_group {
|
||||
FutureIncompatibleInfo {
|
||||
id: LintId::of(TYVAR_BEHIND_RAW_POINTER),
|
||||
reference: "issue #46906 <https://github.com/rust-lang/rust/issues/46906>",
|
||||
epoch: None,
|
||||
},
|
||||
FutureIncompatibleInfo {
|
||||
id: LintId::of(lint::builtin::BARE_TRAIT_OBJECT),
|
||||
reference: "issue #48457 <https://github.com/rust-lang/rust/issues/48457>",
|
||||
epoch: Some(session::config::Epoch::Epoch2018),
|
||||
}
|
||||
epoch: Some(Epoch::Epoch2018),
|
||||
}
|
||||
]);
|
||||
|
||||
// Register renamed and removed lints
|
||||
|
@ -472,7 +472,7 @@ macro_rules! concat {
|
||||
/// The expanded expression has type `u32` and is 1-based, so the first line
|
||||
/// in each file evaluates to 1, the second to 2, etc. This is consistent
|
||||
/// with error messages by common compilers or popular editors.
|
||||
/// The returned line is not the invocation of the `line!` macro itself,
|
||||
/// The returned line is *not necessarily* the line of the `line!` invocation itself,
|
||||
/// but rather the first macro invocation leading up to the invocation
|
||||
/// of the `line!` macro.
|
||||
///
|
||||
@ -497,7 +497,7 @@ macro_rules! line { () => ({ /* compiler built-in */ }) }
|
||||
/// The expanded expression has type `u32` and is 1-based, so the first column
|
||||
/// in each line evaluates to 1, the second to 2, etc. This is consistent
|
||||
/// with error messages by common compilers or popular editors.
|
||||
/// The returned column is not the invocation of the `column!` macro itself,
|
||||
/// The returned column is *not necessarily* the line of the `column!` invocation itself,
|
||||
/// but rather the first macro invocation leading up to the invocation
|
||||
/// of the `column!` macro.
|
||||
///
|
||||
|
@ -13,6 +13,7 @@
|
||||
use {fold, attr};
|
||||
use ast;
|
||||
use codemap::Spanned;
|
||||
use epoch::Epoch;
|
||||
use parse::{token, ParseSess};
|
||||
|
||||
use ptr::P;
|
||||
@ -26,7 +27,7 @@ pub struct StripUnconfigured<'a> {
|
||||
}
|
||||
|
||||
// `cfg_attr`-process the crate's attributes and compute the crate's features.
|
||||
pub fn features(mut krate: ast::Crate, sess: &ParseSess, should_test: bool)
|
||||
pub fn features(mut krate: ast::Crate, sess: &ParseSess, should_test: bool, epoch: Epoch)
|
||||
-> (ast::Crate, Features) {
|
||||
let features;
|
||||
{
|
||||
@ -46,7 +47,7 @@ pub fn features(mut krate: ast::Crate, sess: &ParseSess, should_test: bool)
|
||||
return (krate, Features::new());
|
||||
}
|
||||
|
||||
features = get_features(&sess.span_diagnostic, &krate.attrs);
|
||||
features = get_features(&sess.span_diagnostic, &krate.attrs, epoch);
|
||||
|
||||
// Avoid reconfiguring malformed `cfg_attr`s
|
||||
if err_count == sess.span_diagnostic.err_count() {
|
||||
|
69
src/libsyntax/epoch.rs
Normal file
69
src/libsyntax/epoch.rs
Normal file
@ -0,0 +1,69 @@
|
||||
// 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.
|
||||
|
||||
use std::fmt;
|
||||
use std::str::FromStr;
|
||||
|
||||
/// The epoch of the compiler (RFC 2052)
|
||||
#[derive(Clone, Copy, Hash, PartialOrd, Ord, Eq, PartialEq, Debug)]
|
||||
#[non_exhaustive]
|
||||
pub enum Epoch {
|
||||
// epochs must be kept in order, newest to oldest
|
||||
|
||||
/// The 2015 epoch
|
||||
Epoch2015,
|
||||
/// The 2018 epoch
|
||||
Epoch2018,
|
||||
|
||||
// when adding new epochs, be sure to update:
|
||||
//
|
||||
// - the list in the `parse_epoch` static in librustc::session::config
|
||||
// - add a `rust_####()` function to the session
|
||||
// - update the enum in Cargo's sources as well
|
||||
//
|
||||
// When -Zepoch becomes --epoch, there will
|
||||
// also be a check for the epoch being nightly-only
|
||||
// somewhere. That will need to be updated
|
||||
// whenever we're stabilizing/introducing a new epoch
|
||||
// as well as changing the default Cargo template.
|
||||
}
|
||||
|
||||
// must be in order from oldest to newest
|
||||
pub const ALL_EPOCHS: &[Epoch] = &[Epoch::Epoch2015, Epoch::Epoch2018];
|
||||
|
||||
impl fmt::Display for Epoch {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let s = match *self {
|
||||
Epoch::Epoch2015 => "2015",
|
||||
Epoch::Epoch2018 => "2018",
|
||||
};
|
||||
write!(f, "{}", s)
|
||||
}
|
||||
}
|
||||
|
||||
impl Epoch {
|
||||
pub fn lint_name(&self) -> &'static str {
|
||||
match *self {
|
||||
Epoch::Epoch2015 => "epoch_2015",
|
||||
Epoch::Epoch2018 => "epoch_2018",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for Epoch {
|
||||
type Err = ();
|
||||
fn from_str(s: &str) -> Result<Self, ()> {
|
||||
match s {
|
||||
"2015" => Ok(Epoch::Epoch2015),
|
||||
"2018" => Ok(Epoch::Epoch2018),
|
||||
_ => Err(())
|
||||
}
|
||||
}
|
||||
}
|
@ -28,8 +28,9 @@
|
||||
use abi::Abi;
|
||||
use ast::{self, NodeId, PatKind, RangeEnd, RangeSyntax};
|
||||
use attr;
|
||||
use epoch::Epoch;
|
||||
use codemap::Spanned;
|
||||
use syntax_pos::Span;
|
||||
use syntax_pos::{Span, DUMMY_SP};
|
||||
use errors::{DiagnosticBuilder, Handler, FatalError};
|
||||
use visit::{self, FnKind, Visitor};
|
||||
use parse::ParseSess;
|
||||
@ -54,12 +55,13 @@ fn f(features: &mut Features, _: Span) {
|
||||
}
|
||||
|
||||
macro_rules! declare_features {
|
||||
($((active, $feature: ident, $ver: expr, $issue: expr),)+) => {
|
||||
($((active, $feature: ident, $ver: expr, $issue: expr, $epoch: expr),)+) => {
|
||||
/// Represents active features that are currently being implemented or
|
||||
/// currently being considered for addition/removal.
|
||||
const ACTIVE_FEATURES:
|
||||
&'static [(&'static str, &'static str, Option<u32>, fn(&mut Features, Span))] =
|
||||
&[$((stringify!($feature), $ver, $issue, set!($feature))),+];
|
||||
&'static [(&'static str, &'static str, Option<u32>,
|
||||
Option<Epoch>, fn(&mut Features, Span))] =
|
||||
&[$((stringify!($feature), $ver, $issue, $epoch, set!($feature))),+];
|
||||
|
||||
/// A set of features to be used by later passes.
|
||||
#[derive(Clone)]
|
||||
@ -88,21 +90,21 @@ pub fn walk_feature_fields<F>(&self, mut f: F)
|
||||
}
|
||||
};
|
||||
|
||||
($((removed, $feature: ident, $ver: expr, $issue: expr),)+) => {
|
||||
($((removed, $feature: ident, $ver: expr, $issue: expr, None),)+) => {
|
||||
/// Represents unstable features which have since been removed (it was once Active)
|
||||
const REMOVED_FEATURES: &'static [(&'static str, &'static str, Option<u32>)] = &[
|
||||
$((stringify!($feature), $ver, $issue)),+
|
||||
];
|
||||
};
|
||||
|
||||
($((stable_removed, $feature: ident, $ver: expr, $issue: expr),)+) => {
|
||||
($((stable_removed, $feature: ident, $ver: expr, $issue: expr, None),)+) => {
|
||||
/// Represents stable features which have since been removed (it was once Accepted)
|
||||
const STABLE_REMOVED_FEATURES: &'static [(&'static str, &'static str, Option<u32>)] = &[
|
||||
$((stringify!($feature), $ver, $issue)),+
|
||||
];
|
||||
};
|
||||
|
||||
($((accepted, $feature: ident, $ver: expr, $issue: expr),)+) => {
|
||||
($((accepted, $feature: ident, $ver: expr, $issue: expr, None),)+) => {
|
||||
/// Those language feature has since been Accepted (it was once Active)
|
||||
const ACCEPTED_FEATURES: &'static [(&'static str, &'static str, Option<u32>)] = &[
|
||||
$((stringify!($feature), $ver, $issue)),+
|
||||
@ -122,78 +124,78 @@ pub fn walk_feature_fields<F>(&self, mut f: F)
|
||||
// source, so take care when modifying it.
|
||||
|
||||
declare_features! (
|
||||
(active, asm, "1.0.0", Some(29722)),
|
||||
(active, concat_idents, "1.0.0", Some(29599)),
|
||||
(active, link_args, "1.0.0", Some(29596)),
|
||||
(active, log_syntax, "1.0.0", Some(29598)),
|
||||
(active, non_ascii_idents, "1.0.0", Some(28979)),
|
||||
(active, plugin_registrar, "1.0.0", Some(29597)),
|
||||
(active, thread_local, "1.0.0", Some(29594)),
|
||||
(active, trace_macros, "1.0.0", Some(29598)),
|
||||
(active, asm, "1.0.0", Some(29722), None),
|
||||
(active, concat_idents, "1.0.0", Some(29599), None),
|
||||
(active, link_args, "1.0.0", Some(29596), None),
|
||||
(active, log_syntax, "1.0.0", Some(29598), None),
|
||||
(active, non_ascii_idents, "1.0.0", Some(28979), None),
|
||||
(active, plugin_registrar, "1.0.0", Some(29597), None),
|
||||
(active, thread_local, "1.0.0", Some(29594), None),
|
||||
(active, trace_macros, "1.0.0", Some(29598), None),
|
||||
|
||||
// rustc internal, for now:
|
||||
(active, intrinsics, "1.0.0", None),
|
||||
(active, lang_items, "1.0.0", None),
|
||||
(active, intrinsics, "1.0.0", None, None),
|
||||
(active, lang_items, "1.0.0", None, None),
|
||||
|
||||
(active, link_llvm_intrinsics, "1.0.0", Some(29602)),
|
||||
(active, linkage, "1.0.0", Some(29603)),
|
||||
(active, quote, "1.0.0", Some(29601)),
|
||||
(active, link_llvm_intrinsics, "1.0.0", Some(29602), None),
|
||||
(active, linkage, "1.0.0", Some(29603), None),
|
||||
(active, quote, "1.0.0", Some(29601), None),
|
||||
|
||||
|
||||
// rustc internal
|
||||
(active, rustc_diagnostic_macros, "1.0.0", None),
|
||||
(active, rustc_const_unstable, "1.0.0", None),
|
||||
(active, advanced_slice_patterns, "1.0.0", Some(23121)),
|
||||
(active, box_syntax, "1.0.0", Some(27779)),
|
||||
(active, placement_in_syntax, "1.0.0", Some(27779)),
|
||||
(active, unboxed_closures, "1.0.0", Some(29625)),
|
||||
(active, rustc_diagnostic_macros, "1.0.0", None, None),
|
||||
(active, rustc_const_unstable, "1.0.0", None, None),
|
||||
(active, advanced_slice_patterns, "1.0.0", Some(23121), None),
|
||||
(active, box_syntax, "1.0.0", Some(27779), None),
|
||||
(active, placement_in_syntax, "1.0.0", Some(27779), None),
|
||||
(active, unboxed_closures, "1.0.0", Some(29625), None),
|
||||
|
||||
(active, fundamental, "1.0.0", Some(29635)),
|
||||
(active, main, "1.0.0", Some(29634)),
|
||||
(active, needs_allocator, "1.4.0", Some(27389)),
|
||||
(active, on_unimplemented, "1.0.0", Some(29628)),
|
||||
(active, plugin, "1.0.0", Some(29597)),
|
||||
(active, simd_ffi, "1.0.0", Some(27731)),
|
||||
(active, start, "1.0.0", Some(29633)),
|
||||
(active, structural_match, "1.8.0", Some(31434)),
|
||||
(active, panic_runtime, "1.10.0", Some(32837)),
|
||||
(active, needs_panic_runtime, "1.10.0", Some(32837)),
|
||||
(active, fundamental, "1.0.0", Some(29635), None),
|
||||
(active, main, "1.0.0", Some(29634), None),
|
||||
(active, needs_allocator, "1.4.0", Some(27389), None),
|
||||
(active, on_unimplemented, "1.0.0", Some(29628), None),
|
||||
(active, plugin, "1.0.0", Some(29597), None),
|
||||
(active, simd_ffi, "1.0.0", Some(27731), None),
|
||||
(active, start, "1.0.0", Some(29633), None),
|
||||
(active, structural_match, "1.8.0", Some(31434), None),
|
||||
(active, panic_runtime, "1.10.0", Some(32837), None),
|
||||
(active, needs_panic_runtime, "1.10.0", Some(32837), None),
|
||||
|
||||
// OIBIT specific features
|
||||
(active, optin_builtin_traits, "1.0.0", Some(13231)),
|
||||
(active, optin_builtin_traits, "1.0.0", Some(13231), None),
|
||||
|
||||
// macro re-export needs more discussion and stabilization
|
||||
(active, macro_reexport, "1.0.0", Some(29638)),
|
||||
(active, macro_reexport, "1.0.0", Some(29638), None),
|
||||
|
||||
// Allows use of #[staged_api]
|
||||
// rustc internal
|
||||
(active, staged_api, "1.0.0", None),
|
||||
(active, staged_api, "1.0.0", None, None),
|
||||
|
||||
// Allows using #![no_core]
|
||||
(active, no_core, "1.3.0", Some(29639)),
|
||||
(active, no_core, "1.3.0", Some(29639), None),
|
||||
|
||||
// Allows using `box` in patterns; RFC 469
|
||||
(active, box_patterns, "1.0.0", Some(29641)),
|
||||
(active, box_patterns, "1.0.0", Some(29641), None),
|
||||
|
||||
// Allows using the unsafe_destructor_blind_to_params attribute;
|
||||
// RFC 1238
|
||||
(active, dropck_parametricity, "1.3.0", Some(28498)),
|
||||
(active, dropck_parametricity, "1.3.0", Some(28498), None),
|
||||
|
||||
// Allows using the may_dangle attribute; RFC 1327
|
||||
(active, dropck_eyepatch, "1.10.0", Some(34761)),
|
||||
(active, dropck_eyepatch, "1.10.0", Some(34761), None),
|
||||
|
||||
// Allows the use of custom attributes; RFC 572
|
||||
(active, custom_attribute, "1.0.0", Some(29642)),
|
||||
(active, custom_attribute, "1.0.0", Some(29642), None),
|
||||
|
||||
// Allows the use of #[derive(Anything)] as sugar for
|
||||
// #[derive_Anything].
|
||||
(active, custom_derive, "1.0.0", Some(29644)),
|
||||
(active, custom_derive, "1.0.0", Some(29644), None),
|
||||
|
||||
// Allows the use of rustc_* attributes; RFC 572
|
||||
(active, rustc_attrs, "1.0.0", Some(29642)),
|
||||
(active, rustc_attrs, "1.0.0", Some(29642), None),
|
||||
|
||||
// Allows the use of non lexical lifetimes; RFC 2094
|
||||
(active, nll, "1.0.0", Some(43234)),
|
||||
(active, nll, "1.0.0", Some(43234), None),
|
||||
|
||||
// Allows the use of #[allow_internal_unstable]. This is an
|
||||
// attribute on macro_rules! and can't use the attribute handling
|
||||
@ -201,7 +203,7 @@ pub fn walk_feature_fields<F>(&self, mut f: F)
|
||||
// macros disappear).
|
||||
//
|
||||
// rustc internal
|
||||
(active, allow_internal_unstable, "1.0.0", None),
|
||||
(active, allow_internal_unstable, "1.0.0", None, None),
|
||||
|
||||
// Allows the use of #[allow_internal_unsafe]. This is an
|
||||
// attribute on macro_rules! and can't use the attribute handling
|
||||
@ -209,349 +211,349 @@ pub fn walk_feature_fields<F>(&self, mut f: F)
|
||||
// macros disappear).
|
||||
//
|
||||
// rustc internal
|
||||
(active, allow_internal_unsafe, "1.0.0", None),
|
||||
(active, allow_internal_unsafe, "1.0.0", None, None),
|
||||
|
||||
// #23121. Array patterns have some hazards yet.
|
||||
(active, slice_patterns, "1.0.0", Some(23121)),
|
||||
(active, slice_patterns, "1.0.0", Some(23121), None),
|
||||
|
||||
// Allows the definition of `const fn` functions.
|
||||
(active, const_fn, "1.2.0", Some(24111)),
|
||||
(active, const_fn, "1.2.0", Some(24111), None),
|
||||
|
||||
// Allows using #[prelude_import] on glob `use` items.
|
||||
//
|
||||
// rustc internal
|
||||
(active, prelude_import, "1.2.0", None),
|
||||
(active, prelude_import, "1.2.0", None, None),
|
||||
|
||||
// Allows default type parameters to influence type inference.
|
||||
(active, default_type_parameter_fallback, "1.3.0", Some(27336)),
|
||||
(active, default_type_parameter_fallback, "1.3.0", Some(27336), None),
|
||||
|
||||
// Allows associated type defaults
|
||||
(active, associated_type_defaults, "1.2.0", Some(29661)),
|
||||
(active, associated_type_defaults, "1.2.0", Some(29661), None),
|
||||
|
||||
// allow `repr(simd)`, and importing the various simd intrinsics
|
||||
(active, repr_simd, "1.4.0", Some(27731)),
|
||||
(active, repr_simd, "1.4.0", Some(27731), None),
|
||||
|
||||
// Allows cfg(target_feature = "...").
|
||||
(active, cfg_target_feature, "1.4.0", Some(29717)),
|
||||
(active, cfg_target_feature, "1.4.0", Some(29717), None),
|
||||
|
||||
// allow `extern "platform-intrinsic" { ... }`
|
||||
(active, platform_intrinsics, "1.4.0", Some(27731)),
|
||||
(active, platform_intrinsics, "1.4.0", Some(27731), None),
|
||||
|
||||
// allow `#[unwind(..)]`
|
||||
// rust runtime internal
|
||||
(active, unwind_attributes, "1.4.0", None),
|
||||
(active, unwind_attributes, "1.4.0", None, None),
|
||||
|
||||
// allow the use of `#[naked]` on functions.
|
||||
(active, naked_functions, "1.9.0", Some(32408)),
|
||||
(active, naked_functions, "1.9.0", Some(32408), None),
|
||||
|
||||
// allow `#[no_debug]`
|
||||
(active, no_debug, "1.5.0", Some(29721)),
|
||||
(active, no_debug, "1.5.0", Some(29721), None),
|
||||
|
||||
// allow `#[omit_gdb_pretty_printer_section]`
|
||||
// rustc internal.
|
||||
(active, omit_gdb_pretty_printer_section, "1.5.0", None),
|
||||
(active, omit_gdb_pretty_printer_section, "1.5.0", None, None),
|
||||
|
||||
// Allows cfg(target_vendor = "...").
|
||||
(active, cfg_target_vendor, "1.5.0", Some(29718)),
|
||||
(active, cfg_target_vendor, "1.5.0", Some(29718), None),
|
||||
|
||||
// Allow attributes on expressions and non-item statements
|
||||
(active, stmt_expr_attributes, "1.6.0", Some(15701)),
|
||||
(active, stmt_expr_attributes, "1.6.0", Some(15701), None),
|
||||
|
||||
// allow using type ascription in expressions
|
||||
(active, type_ascription, "1.6.0", Some(23416)),
|
||||
(active, type_ascription, "1.6.0", Some(23416), None),
|
||||
|
||||
// Allows cfg(target_thread_local)
|
||||
(active, cfg_target_thread_local, "1.7.0", Some(29594)),
|
||||
(active, cfg_target_thread_local, "1.7.0", Some(29594), None),
|
||||
|
||||
// rustc internal
|
||||
(active, abi_vectorcall, "1.7.0", None),
|
||||
(active, abi_vectorcall, "1.7.0", None, None),
|
||||
|
||||
// a..=b and ..=b
|
||||
(active, inclusive_range_syntax, "1.7.0", Some(28237)),
|
||||
(active, inclusive_range_syntax, "1.7.0", Some(28237), None),
|
||||
|
||||
// X..Y patterns
|
||||
(active, exclusive_range_pattern, "1.11.0", Some(37854)),
|
||||
(active, exclusive_range_pattern, "1.11.0", Some(37854), None),
|
||||
|
||||
// impl specialization (RFC 1210)
|
||||
(active, specialization, "1.7.0", Some(31844)),
|
||||
(active, specialization, "1.7.0", Some(31844), None),
|
||||
|
||||
// Allows cfg(target_has_atomic = "...").
|
||||
(active, cfg_target_has_atomic, "1.9.0", Some(32976)),
|
||||
(active, cfg_target_has_atomic, "1.9.0", Some(32976), None),
|
||||
|
||||
// Allows `impl Trait` in function return types.
|
||||
(active, conservative_impl_trait, "1.12.0", Some(34511)),
|
||||
(active, conservative_impl_trait, "1.12.0", Some(34511), None),
|
||||
|
||||
// Allows `impl Trait` in function arguments.
|
||||
(active, universal_impl_trait, "1.23.0", Some(34511)),
|
||||
(active, universal_impl_trait, "1.23.0", Some(34511), None),
|
||||
|
||||
// The `!` type
|
||||
(active, never_type, "1.13.0", Some(35121)),
|
||||
(active, never_type, "1.13.0", Some(35121), None),
|
||||
|
||||
// Allows all literals in attribute lists and values of key-value pairs.
|
||||
(active, attr_literals, "1.13.0", Some(34981)),
|
||||
(active, attr_literals, "1.13.0", Some(34981), None),
|
||||
|
||||
// Allows untagged unions `union U { ... }`
|
||||
(active, untagged_unions, "1.13.0", Some(32836)),
|
||||
(active, untagged_unions, "1.13.0", Some(32836), None),
|
||||
|
||||
// Used to identify the `compiler_builtins` crate
|
||||
// rustc internal
|
||||
(active, compiler_builtins, "1.13.0", None),
|
||||
(active, compiler_builtins, "1.13.0", None, None),
|
||||
|
||||
// Allows attributes on lifetime/type formal parameters in generics (RFC 1327)
|
||||
(active, generic_param_attrs, "1.11.0", Some(34761)),
|
||||
(active, generic_param_attrs, "1.11.0", Some(34761), None),
|
||||
|
||||
// Allows #[link(..., cfg(..))]
|
||||
(active, link_cfg, "1.14.0", Some(37406)),
|
||||
(active, link_cfg, "1.14.0", Some(37406), None),
|
||||
|
||||
(active, use_extern_macros, "1.15.0", Some(35896)),
|
||||
(active, use_extern_macros, "1.15.0", Some(35896), None),
|
||||
|
||||
// Allows #[target_feature(...)]
|
||||
(active, target_feature, "1.15.0", None),
|
||||
(active, target_feature, "1.15.0", None, None),
|
||||
|
||||
// `extern "ptx-*" fn()`
|
||||
(active, abi_ptx, "1.15.0", None),
|
||||
(active, abi_ptx, "1.15.0", None, None),
|
||||
|
||||
// The `i128` type
|
||||
(active, i128_type, "1.16.0", Some(35118)),
|
||||
(active, i128_type, "1.16.0", Some(35118), None),
|
||||
|
||||
// The `repr(i128)` annotation for enums
|
||||
(active, repr128, "1.16.0", Some(35118)),
|
||||
(active, repr128, "1.16.0", Some(35118), None),
|
||||
|
||||
// The `unadjusted` ABI. Perma unstable.
|
||||
(active, abi_unadjusted, "1.16.0", None),
|
||||
(active, abi_unadjusted, "1.16.0", None, None),
|
||||
|
||||
// Procedural macros 2.0.
|
||||
(active, proc_macro, "1.16.0", Some(38356)),
|
||||
(active, proc_macro, "1.16.0", Some(38356), None),
|
||||
|
||||
// Declarative macros 2.0 (`macro`).
|
||||
(active, decl_macro, "1.17.0", Some(39412)),
|
||||
(active, decl_macro, "1.17.0", Some(39412), None),
|
||||
|
||||
// Allows #[link(kind="static-nobundle"...]
|
||||
(active, static_nobundle, "1.16.0", Some(37403)),
|
||||
(active, static_nobundle, "1.16.0", Some(37403), None),
|
||||
|
||||
// `extern "msp430-interrupt" fn()`
|
||||
(active, abi_msp430_interrupt, "1.16.0", Some(38487)),
|
||||
(active, abi_msp430_interrupt, "1.16.0", Some(38487), None),
|
||||
|
||||
// Used to identify crates that contain sanitizer runtimes
|
||||
// rustc internal
|
||||
(active, sanitizer_runtime, "1.17.0", None),
|
||||
(active, sanitizer_runtime, "1.17.0", None, None),
|
||||
|
||||
// Used to identify crates that contain the profiler runtime
|
||||
// rustc internal
|
||||
(active, profiler_runtime, "1.18.0", None),
|
||||
(active, profiler_runtime, "1.18.0", None, None),
|
||||
|
||||
// `extern "x86-interrupt" fn()`
|
||||
(active, abi_x86_interrupt, "1.17.0", Some(40180)),
|
||||
(active, abi_x86_interrupt, "1.17.0", Some(40180), None),
|
||||
|
||||
|
||||
// Allows the `catch {...}` expression
|
||||
(active, catch_expr, "1.17.0", Some(31436)),
|
||||
(active, catch_expr, "1.17.0", Some(31436), None),
|
||||
|
||||
// Used to preserve symbols (see llvm.used)
|
||||
(active, used, "1.18.0", Some(40289)),
|
||||
(active, used, "1.18.0", Some(40289), None),
|
||||
|
||||
// Allows module-level inline assembly by way of global_asm!()
|
||||
(active, global_asm, "1.18.0", Some(35119)),
|
||||
(active, global_asm, "1.18.0", Some(35119), None),
|
||||
|
||||
// Allows overlapping impls of marker traits
|
||||
(active, overlapping_marker_traits, "1.18.0", Some(29864)),
|
||||
(active, overlapping_marker_traits, "1.18.0", Some(29864), None),
|
||||
|
||||
// Allows use of the :vis macro fragment specifier
|
||||
(active, macro_vis_matcher, "1.18.0", Some(41022)),
|
||||
(active, macro_vis_matcher, "1.18.0", Some(41022), None),
|
||||
|
||||
// rustc internal
|
||||
(active, abi_thiscall, "1.19.0", None),
|
||||
(active, abi_thiscall, "1.19.0", None, None),
|
||||
|
||||
// Allows a test to fail without failing the whole suite
|
||||
(active, allow_fail, "1.19.0", Some(42219)),
|
||||
(active, allow_fail, "1.19.0", Some(42219), None),
|
||||
|
||||
// Allows unsized tuple coercion.
|
||||
(active, unsized_tuple_coercion, "1.20.0", Some(42877)),
|
||||
(active, unsized_tuple_coercion, "1.20.0", Some(42877), None),
|
||||
|
||||
// Generators
|
||||
(active, generators, "1.21.0", None),
|
||||
(active, generators, "1.21.0", None, None),
|
||||
|
||||
// Trait aliases
|
||||
(active, trait_alias, "1.24.0", Some(41517)),
|
||||
(active, trait_alias, "1.24.0", Some(41517), None),
|
||||
|
||||
// global allocators and their internals
|
||||
(active, global_allocator, "1.20.0", None),
|
||||
(active, allocator_internals, "1.20.0", None),
|
||||
(active, global_allocator, "1.20.0", None, None),
|
||||
(active, allocator_internals, "1.20.0", None, None),
|
||||
|
||||
// #[doc(cfg(...))]
|
||||
(active, doc_cfg, "1.21.0", Some(43781)),
|
||||
(active, doc_cfg, "1.21.0", Some(43781), None),
|
||||
// #[doc(masked)]
|
||||
(active, doc_masked, "1.21.0", Some(44027)),
|
||||
(active, doc_masked, "1.21.0", Some(44027), None),
|
||||
// #[doc(spotlight)]
|
||||
(active, doc_spotlight, "1.22.0", Some(45040)),
|
||||
(active, doc_spotlight, "1.22.0", Some(45040), None),
|
||||
// #[doc(include="some-file")]
|
||||
(active, external_doc, "1.22.0", Some(44732)),
|
||||
(active, external_doc, "1.22.0", Some(44732), None),
|
||||
|
||||
// allow `#[must_use]` on functions and comparison operators (RFC 1940)
|
||||
(active, fn_must_use, "1.21.0", Some(43302)),
|
||||
(active, fn_must_use, "1.21.0", Some(43302), None),
|
||||
|
||||
// Future-proofing enums/structs with #[non_exhaustive] attribute (RFC 2008)
|
||||
(active, non_exhaustive, "1.22.0", Some(44109)),
|
||||
(active, non_exhaustive, "1.22.0", Some(44109), None),
|
||||
|
||||
// Copy/Clone closures (RFC 2132)
|
||||
(active, clone_closures, "1.22.0", Some(44490)),
|
||||
(active, copy_closures, "1.22.0", Some(44490)),
|
||||
(active, clone_closures, "1.22.0", Some(44490), None),
|
||||
(active, copy_closures, "1.22.0", Some(44490), None),
|
||||
|
||||
// allow `'_` placeholder lifetimes
|
||||
(active, underscore_lifetimes, "1.22.0", Some(44524)),
|
||||
(active, underscore_lifetimes, "1.22.0", Some(44524), None),
|
||||
|
||||
// allow `..=` in patterns (RFC 1192)
|
||||
(active, dotdoteq_in_patterns, "1.22.0", Some(28237)),
|
||||
(active, dotdoteq_in_patterns, "1.22.0", Some(28237), None),
|
||||
|
||||
// Default match binding modes (RFC 2005)
|
||||
(active, match_default_bindings, "1.22.0", Some(42640)),
|
||||
(active, match_default_bindings, "1.22.0", Some(42640), None),
|
||||
|
||||
// Trait object syntax with `dyn` prefix
|
||||
(active, dyn_trait, "1.22.0", Some(44662)),
|
||||
(active, dyn_trait, "1.22.0", Some(44662), Some(Epoch::Epoch2018)),
|
||||
|
||||
// `crate` as visibility modifier, synonymous to `pub(crate)`
|
||||
(active, crate_visibility_modifier, "1.23.0", Some(45388)),
|
||||
(active, crate_visibility_modifier, "1.23.0", Some(45388), None),
|
||||
|
||||
// extern types
|
||||
(active, extern_types, "1.23.0", Some(43467)),
|
||||
(active, extern_types, "1.23.0", Some(43467), None),
|
||||
|
||||
// Allow trait methods with arbitrary self types
|
||||
(active, arbitrary_self_types, "1.23.0", Some(44874)),
|
||||
(active, arbitrary_self_types, "1.23.0", Some(44874), None),
|
||||
|
||||
// `crate` in paths
|
||||
(active, crate_in_paths, "1.23.0", Some(45477)),
|
||||
(active, crate_in_paths, "1.23.0", Some(45477), None),
|
||||
|
||||
// In-band lifetime bindings (e.g. `fn foo(x: &'a u8) -> &'a u8`)
|
||||
(active, in_band_lifetimes, "1.23.0", Some(44524)),
|
||||
(active, in_band_lifetimes, "1.23.0", Some(44524), None),
|
||||
|
||||
// generic associated types (RFC 1598)
|
||||
(active, generic_associated_types, "1.23.0", Some(44265)),
|
||||
(active, generic_associated_types, "1.23.0", Some(44265), None),
|
||||
|
||||
// Resolve absolute paths as paths from other crates
|
||||
(active, extern_absolute_paths, "1.24.0", Some(44660)),
|
||||
(active, extern_absolute_paths, "1.24.0", Some(44660), None),
|
||||
|
||||
// `foo.rs` as an alternative to `foo/mod.rs`
|
||||
(active, non_modrs_mods, "1.24.0", Some(44660)),
|
||||
(active, non_modrs_mods, "1.24.0", Some(44660), None),
|
||||
|
||||
// Termination trait in main (RFC 1937)
|
||||
(active, termination_trait, "1.24.0", Some(43301)),
|
||||
(active, termination_trait, "1.24.0", Some(43301), None),
|
||||
|
||||
// Allows use of the :lifetime macro fragment specifier
|
||||
(active, macro_lifetime_matcher, "1.24.0", Some(46895)),
|
||||
(active, macro_lifetime_matcher, "1.24.0", Some(46895), None),
|
||||
|
||||
// `extern` in paths
|
||||
(active, extern_in_paths, "1.23.0", Some(44660)),
|
||||
(active, extern_in_paths, "1.23.0", Some(44660), None),
|
||||
|
||||
// Allows `#[repr(transparent)]` attribute on newtype structs
|
||||
(active, repr_transparent, "1.25.0", Some(43036)),
|
||||
(active, repr_transparent, "1.25.0", Some(43036), None),
|
||||
|
||||
// Use `?` as the Kleene "at most one" operator
|
||||
(active, macro_at_most_once_rep, "1.25.0", Some(48075)),
|
||||
(active, macro_at_most_once_rep, "1.25.0", Some(48075), None),
|
||||
|
||||
// Multiple patterns with `|` in `if let` and `while let`
|
||||
(active, if_while_or_patterns, "1.26.0", Some(48215)),
|
||||
(active, if_while_or_patterns, "1.26.0", Some(48215), None),
|
||||
|
||||
// Parentheses in patterns
|
||||
(active, pattern_parentheses, "1.26.0", None),
|
||||
(active, pattern_parentheses, "1.26.0", None, None),
|
||||
);
|
||||
|
||||
declare_features! (
|
||||
(removed, import_shadowing, "1.0.0", None),
|
||||
(removed, managed_boxes, "1.0.0", None),
|
||||
(removed, import_shadowing, "1.0.0", None, None),
|
||||
(removed, managed_boxes, "1.0.0", None, None),
|
||||
// Allows use of unary negate on unsigned integers, e.g. -e for e: u8
|
||||
(removed, negate_unsigned, "1.0.0", Some(29645)),
|
||||
(removed, reflect, "1.0.0", Some(27749)),
|
||||
(removed, negate_unsigned, "1.0.0", Some(29645), None),
|
||||
(removed, reflect, "1.0.0", Some(27749), None),
|
||||
// A way to temporarily opt out of opt in copy. This will *never* be accepted.
|
||||
(removed, opt_out_copy, "1.0.0", None),
|
||||
(removed, quad_precision_float, "1.0.0", None),
|
||||
(removed, struct_inherit, "1.0.0", None),
|
||||
(removed, test_removed_feature, "1.0.0", None),
|
||||
(removed, visible_private_types, "1.0.0", None),
|
||||
(removed, unsafe_no_drop_flag, "1.0.0", None),
|
||||
(removed, opt_out_copy, "1.0.0", None, None),
|
||||
(removed, quad_precision_float, "1.0.0", None, None),
|
||||
(removed, struct_inherit, "1.0.0", None, None),
|
||||
(removed, test_removed_feature, "1.0.0", None, None),
|
||||
(removed, visible_private_types, "1.0.0", None, None),
|
||||
(removed, unsafe_no_drop_flag, "1.0.0", None, None),
|
||||
// Allows using items which are missing stability attributes
|
||||
// rustc internal
|
||||
(removed, unmarked_api, "1.0.0", None),
|
||||
(removed, pushpop_unsafe, "1.2.0", None),
|
||||
(removed, allocator, "1.0.0", None),
|
||||
(removed, unmarked_api, "1.0.0", None, None),
|
||||
(removed, pushpop_unsafe, "1.2.0", None, None),
|
||||
(removed, allocator, "1.0.0", None, None),
|
||||
// Allows the `#[simd]` attribute -- removed in favor of `#[repr(simd)]`
|
||||
(removed, simd, "1.0.0", Some(27731)),
|
||||
(removed, simd, "1.0.0", Some(27731), None),
|
||||
);
|
||||
|
||||
declare_features! (
|
||||
(stable_removed, no_stack_check, "1.0.0", None),
|
||||
(stable_removed, no_stack_check, "1.0.0", None, None),
|
||||
);
|
||||
|
||||
declare_features! (
|
||||
(accepted, associated_types, "1.0.0", None),
|
||||
(accepted, associated_types, "1.0.0", None, None),
|
||||
// allow overloading augmented assignment operations like `a += b`
|
||||
(accepted, augmented_assignments, "1.8.0", Some(28235)),
|
||||
(accepted, augmented_assignments, "1.8.0", Some(28235), None),
|
||||
// allow empty structs and enum variants with braces
|
||||
(accepted, braced_empty_structs, "1.8.0", Some(29720)),
|
||||
(accepted, braced_empty_structs, "1.8.0", Some(29720), None),
|
||||
// Allows indexing into constant arrays.
|
||||
(accepted, const_indexing, "1.24.0", Some(29947)),
|
||||
(accepted, default_type_params, "1.0.0", None),
|
||||
(accepted, globs, "1.0.0", None),
|
||||
(accepted, if_let, "1.0.0", None),
|
||||
(accepted, const_indexing, "1.24.0", Some(29947), None),
|
||||
(accepted, default_type_params, "1.0.0", None, None),
|
||||
(accepted, globs, "1.0.0", None, None),
|
||||
(accepted, if_let, "1.0.0", None, None),
|
||||
// A temporary feature gate used to enable parser extensions needed
|
||||
// to bootstrap fix for #5723.
|
||||
(accepted, issue_5723_bootstrap, "1.0.0", None),
|
||||
(accepted, macro_rules, "1.0.0", None),
|
||||
(accepted, issue_5723_bootstrap, "1.0.0", None, None),
|
||||
(accepted, macro_rules, "1.0.0", None, None),
|
||||
// Allows using #![no_std]
|
||||
(accepted, no_std, "1.6.0", None),
|
||||
(accepted, slicing_syntax, "1.0.0", None),
|
||||
(accepted, struct_variant, "1.0.0", None),
|
||||
(accepted, no_std, "1.6.0", None, None),
|
||||
(accepted, slicing_syntax, "1.0.0", None, None),
|
||||
(accepted, struct_variant, "1.0.0", None, None),
|
||||
// These are used to test this portion of the compiler, they don't actually
|
||||
// mean anything
|
||||
(accepted, test_accepted_feature, "1.0.0", None),
|
||||
(accepted, tuple_indexing, "1.0.0", None),
|
||||
(accepted, test_accepted_feature, "1.0.0", None, None),
|
||||
(accepted, tuple_indexing, "1.0.0", None, None),
|
||||
// Allows macros to appear in the type position.
|
||||
(accepted, type_macros, "1.13.0", Some(27245)),
|
||||
(accepted, while_let, "1.0.0", None),
|
||||
(accepted, type_macros, "1.13.0", Some(27245), None),
|
||||
(accepted, while_let, "1.0.0", None, None),
|
||||
// Allows `#[deprecated]` attribute
|
||||
(accepted, deprecated, "1.9.0", Some(29935)),
|
||||
(accepted, deprecated, "1.9.0", Some(29935), None),
|
||||
// `expr?`
|
||||
(accepted, question_mark, "1.13.0", Some(31436)),
|
||||
(accepted, question_mark, "1.13.0", Some(31436), None),
|
||||
// Allows `..` in tuple (struct) patterns
|
||||
(accepted, dotdot_in_tuple_patterns, "1.14.0", Some(33627)),
|
||||
(accepted, item_like_imports, "1.15.0", Some(35120)),
|
||||
(accepted, dotdot_in_tuple_patterns, "1.14.0", Some(33627), None),
|
||||
(accepted, item_like_imports, "1.15.0", Some(35120), None),
|
||||
// Allows using `Self` and associated types in struct expressions and patterns.
|
||||
(accepted, more_struct_aliases, "1.16.0", Some(37544)),
|
||||
(accepted, more_struct_aliases, "1.16.0", Some(37544), None),
|
||||
// elide `'static` lifetimes in `static`s and `const`s
|
||||
(accepted, static_in_const, "1.17.0", Some(35897)),
|
||||
(accepted, static_in_const, "1.17.0", Some(35897), None),
|
||||
// Allows field shorthands (`x` meaning `x: x`) in struct literal expressions.
|
||||
(accepted, field_init_shorthand, "1.17.0", Some(37340)),
|
||||
(accepted, field_init_shorthand, "1.17.0", Some(37340), None),
|
||||
// Allows the definition recursive static items.
|
||||
(accepted, static_recursion, "1.17.0", Some(29719)),
|
||||
(accepted, static_recursion, "1.17.0", Some(29719), None),
|
||||
// pub(restricted) visibilities (RFC 1422)
|
||||
(accepted, pub_restricted, "1.18.0", Some(32409)),
|
||||
(accepted, pub_restricted, "1.18.0", Some(32409), None),
|
||||
// The #![windows_subsystem] attribute
|
||||
(accepted, windows_subsystem, "1.18.0", Some(37499)),
|
||||
(accepted, windows_subsystem, "1.18.0", Some(37499), None),
|
||||
// Allows `break {expr}` with a value inside `loop`s.
|
||||
(accepted, loop_break_value, "1.19.0", Some(37339)),
|
||||
(accepted, loop_break_value, "1.19.0", Some(37339), None),
|
||||
// Permits numeric fields in struct expressions and patterns.
|
||||
(accepted, relaxed_adts, "1.19.0", Some(35626)),
|
||||
(accepted, relaxed_adts, "1.19.0", Some(35626), None),
|
||||
// Coerces non capturing closures to function pointers
|
||||
(accepted, closure_to_fn_coercion, "1.19.0", Some(39817)),
|
||||
(accepted, closure_to_fn_coercion, "1.19.0", Some(39817), None),
|
||||
// Allows attributes on struct literal fields.
|
||||
(accepted, struct_field_attributes, "1.20.0", Some(38814)),
|
||||
(accepted, struct_field_attributes, "1.20.0", Some(38814), None),
|
||||
// Allows the definition of associated constants in `trait` or `impl`
|
||||
// blocks.
|
||||
(accepted, associated_consts, "1.20.0", Some(29646)),
|
||||
(accepted, associated_consts, "1.20.0", Some(29646), None),
|
||||
// Usage of the `compile_error!` macro
|
||||
(accepted, compile_error, "1.20.0", Some(40872)),
|
||||
(accepted, compile_error, "1.20.0", Some(40872), None),
|
||||
// See rust-lang/rfcs#1414. Allows code like `let x: &'static u32 = &42` to work.
|
||||
(accepted, rvalue_static_promotion, "1.21.0", Some(38865)),
|
||||
(accepted, rvalue_static_promotion, "1.21.0", Some(38865), None),
|
||||
// Allow Drop types in constants (RFC 1440)
|
||||
(accepted, drop_types_in_const, "1.22.0", Some(33156)),
|
||||
(accepted, drop_types_in_const, "1.22.0", Some(33156), None),
|
||||
// Allows the sysV64 ABI to be specified on all platforms
|
||||
// instead of just the platforms on which it is the C ABI
|
||||
(accepted, abi_sysv64, "1.24.0", Some(36167)),
|
||||
(accepted, abi_sysv64, "1.24.0", Some(36167), None),
|
||||
// Allows `repr(align(16))` struct attribute (RFC 1358)
|
||||
(accepted, repr_align, "1.25.0", Some(33626)),
|
||||
(accepted, repr_align, "1.25.0", Some(33626), None),
|
||||
// allow '|' at beginning of match arms (RFC 1925)
|
||||
(accepted, match_beginning_vert, "1.25.0", Some(44101)),
|
||||
(accepted, match_beginning_vert, "1.25.0", Some(44101), None),
|
||||
// Nested groups in `use` (RFC 2128)
|
||||
(accepted, use_nested_groups, "1.25.0", Some(44494)),
|
||||
(accepted, use_nested_groups, "1.25.0", Some(44494), None),
|
||||
);
|
||||
|
||||
// If you change this, please modify src/doc/unstable-book as well. You must
|
||||
@ -1793,11 +1795,22 @@ fn visit_lifetime(&mut self, lt: &'a ast::Lifetime) {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute]) -> Features {
|
||||
pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute],
|
||||
epoch: Epoch) -> Features {
|
||||
let mut features = Features::new();
|
||||
|
||||
let mut feature_checker = FeatureChecker::default();
|
||||
|
||||
for &(.., f_epoch, set) in ACTIVE_FEATURES.iter() {
|
||||
if let Some(f_epoch) = f_epoch {
|
||||
if epoch >= f_epoch {
|
||||
// FIXME(Manishearth) there is currently no way to set
|
||||
// lang features by epoch
|
||||
set(&mut features, DUMMY_SP);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for attr in krate_attrs {
|
||||
if !attr.check_name("feature") {
|
||||
continue
|
||||
@ -1818,8 +1831,8 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute]) -> F
|
||||
continue
|
||||
};
|
||||
|
||||
if let Some(&(_, _, _, set)) = ACTIVE_FEATURES.iter()
|
||||
.find(|& &(n, _, _, _)| name == n) {
|
||||
if let Some(&(_, _, _, _, set)) = ACTIVE_FEATURES.iter()
|
||||
.find(|& &(n, ..)| name == n) {
|
||||
set(&mut features, mi.span);
|
||||
feature_checker.collect(&features, mi.span);
|
||||
}
|
||||
|
@ -23,6 +23,7 @@
|
||||
#![feature(unicode)]
|
||||
#![feature(rustc_diagnostic_macros)]
|
||||
#![feature(match_default_bindings)]
|
||||
#![feature(non_exhaustive)]
|
||||
#![feature(i128_type)]
|
||||
#![feature(const_atomic_usize_new)]
|
||||
#![feature(rustc_attrs)]
|
||||
@ -114,6 +115,7 @@ pub mod syntax {
|
||||
#[macro_use]
|
||||
pub mod config;
|
||||
pub mod entry;
|
||||
pub mod epoch;
|
||||
pub mod feature_gate;
|
||||
pub mod fold;
|
||||
pub mod parse;
|
||||
|
@ -3318,7 +3318,7 @@ pub fn parse_for_expr(&mut self, opt_label: Option<Label>,
|
||||
mut attrs: ThinVec<Attribute>) -> PResult<'a, P<Expr>> {
|
||||
// Parse: `for <src_pat> in <src_expr> <src_loop_block>`
|
||||
|
||||
let pat = self.parse_pat()?;
|
||||
let pat = self.parse_top_level_pat()?;
|
||||
if !self.eat_keyword(keywords::In) {
|
||||
let in_span = self.prev_span.between(self.span);
|
||||
let mut err = self.sess.span_diagnostic
|
||||
@ -3528,7 +3528,7 @@ fn parse_initializer(&mut self, skip_eq: bool) -> PResult<'a, Option<P<Expr>>> {
|
||||
fn parse_pats(&mut self) -> PResult<'a, Vec<P<Pat>>> {
|
||||
let mut pats = Vec::new();
|
||||
loop {
|
||||
pats.push(self.parse_pat()?);
|
||||
pats.push(self.parse_top_level_pat()?);
|
||||
|
||||
if self.token == token::OrOr {
|
||||
let mut err = self.struct_span_err(self.span,
|
||||
@ -3554,7 +3554,12 @@ fn parse_pats(&mut self) -> PResult<'a, Vec<P<Pat>>> {
|
||||
// Trailing commas are significant because (p) and (p,) are different patterns.
|
||||
fn parse_parenthesized_pat_list(&mut self) -> PResult<'a, (Vec<P<Pat>>, Option<usize>, bool)> {
|
||||
self.expect(&token::OpenDelim(token::Paren))?;
|
||||
let result = self.parse_pat_list()?;
|
||||
self.expect(&token::CloseDelim(token::Paren))?;
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
fn parse_pat_list(&mut self) -> PResult<'a, (Vec<P<Pat>>, Option<usize>, bool)> {
|
||||
let mut fields = Vec::new();
|
||||
let mut ddpos = None;
|
||||
let mut trailing_comma = false;
|
||||
@ -3584,8 +3589,6 @@ fn parse_parenthesized_pat_list(&mut self) -> PResult<'a, (Vec<P<Pat>>, Option<u
|
||||
self.span_err(self.prev_span, "trailing comma is not permitted after `..`");
|
||||
}
|
||||
|
||||
self.expect(&token::CloseDelim(token::Paren))?;
|
||||
|
||||
Ok((fields, ddpos, trailing_comma))
|
||||
}
|
||||
|
||||
@ -3767,6 +3770,37 @@ fn parse_as_ident(&mut self) -> bool {
|
||||
}))
|
||||
}
|
||||
|
||||
/// A wrapper around `parse_pat` with some special error handling for the
|
||||
/// "top-level" patterns in a match arm, `for` loop, `let`, &c. (in contast
|
||||
/// to subpatterns within such).
|
||||
pub fn parse_top_level_pat(&mut self) -> PResult<'a, P<Pat>> {
|
||||
let pat = self.parse_pat()?;
|
||||
if self.token == token::Comma {
|
||||
// An unexpected comma after a top-level pattern is a clue that the
|
||||
// user (perhaps more accustomed to some other language) forgot the
|
||||
// parentheses in what should have been a tuple pattern; return a
|
||||
// suggestion-enhanced error here rather than choking on the comma
|
||||
// later.
|
||||
let comma_span = self.span;
|
||||
self.bump();
|
||||
if let Err(mut err) = self.parse_pat_list() {
|
||||
// We didn't expect this to work anyway; we just wanted
|
||||
// to advance to the end of the comma-sequence so we know
|
||||
// the span to suggest parenthesizing
|
||||
err.cancel();
|
||||
}
|
||||
let seq_span = pat.span.to(self.prev_span);
|
||||
let mut err = self.struct_span_err(comma_span,
|
||||
"unexpected `,` in pattern");
|
||||
if let Ok(seq_snippet) = self.sess.codemap().span_to_snippet(seq_span) {
|
||||
err.span_suggestion(seq_span, "try adding parentheses",
|
||||
format!("({})", seq_snippet));
|
||||
}
|
||||
return Err(err);
|
||||
}
|
||||
Ok(pat)
|
||||
}
|
||||
|
||||
/// Parse a pattern.
|
||||
pub fn parse_pat(&mut self) -> PResult<'a, P<Pat>> {
|
||||
maybe_whole!(self, NtPat, |x| x);
|
||||
@ -3969,7 +4003,7 @@ fn parse_pat_ident(&mut self,
|
||||
/// Parse a local variable declaration
|
||||
fn parse_local(&mut self, attrs: ThinVec<Attribute>) -> PResult<'a, P<Local>> {
|
||||
let lo = self.prev_span;
|
||||
let pat = self.parse_pat()?;
|
||||
let pat = self.parse_top_level_pat()?;
|
||||
|
||||
let (err, ty) = if self.eat(&token::Colon) {
|
||||
// Save the state of the parser before parsing type normally, in case there is a `:`
|
||||
|
21
src/test/run-pass/epoch-gate-feature.rs
Normal file
21
src/test/run-pass/epoch-gate-feature.rs
Normal file
@ -0,0 +1,21 @@
|
||||
// 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.
|
||||
|
||||
// Checks if the correct registers are being used to pass arguments
|
||||
// when the sysv64 ABI is specified.
|
||||
|
||||
// compile-flags: -Zepoch=2018
|
||||
|
||||
pub trait Foo {}
|
||||
|
||||
// should compile without the dyn trait feature flag
|
||||
fn foo(x: &dyn Foo) {}
|
||||
|
||||
pub fn main() {}
|
@ -0,0 +1,97 @@
|
||||
// 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.
|
||||
|
||||
#![allow(unused)]
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
enum Nucleotide {
|
||||
Adenine,
|
||||
Thymine,
|
||||
Cytosine,
|
||||
Guanine
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct Autosome;
|
||||
|
||||
#[derive(Clone)]
|
||||
enum Allosome {
|
||||
X(Vec<Nucleotide>),
|
||||
Y(Vec<Nucleotide>)
|
||||
}
|
||||
|
||||
impl Allosome {
|
||||
fn is_x(&self) -> bool {
|
||||
match *self {
|
||||
Allosome::X(_) => true,
|
||||
Allosome::Y(_) => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct Genome {
|
||||
autosomes: [Autosome; 22],
|
||||
allosomes: (Allosome, Allosome)
|
||||
}
|
||||
|
||||
fn find_start_codon(strand: &[Nucleotide]) -> Option<usize> {
|
||||
let mut reading_frame = strand.windows(3);
|
||||
// (missing parentheses in `while let` tuple pattern)
|
||||
while let b1, b2, b3 = reading_frame.next().expect("there should be a start codon") {
|
||||
//~^ ERROR unexpected `,` in pattern
|
||||
// ...
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn find_thr(strand: &[Nucleotide]) -> Option<usize> {
|
||||
let mut reading_frame = strand.windows(3);
|
||||
let mut i = 0;
|
||||
// (missing parentheses in `if let` tuple pattern)
|
||||
if let b1, b2, b3 = reading_frame.next().unwrap() {
|
||||
//~^ ERROR unexpected `,` in pattern
|
||||
// ...
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn is_thr(codon: (Nucleotide, Nucleotide, Nucleotide)) -> bool {
|
||||
match codon {
|
||||
// (missing parentheses in match arm tuple pattern)
|
||||
Nucleotide::Adenine, Nucleotide::Cytosine, _ => true
|
||||
//~^ ERROR unexpected `,` in pattern
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
||||
fn analyze_female_sex_chromosomes(women: &[Genome]) {
|
||||
// (missing parentheses in `for` tuple pattern)
|
||||
for x, _barr_body in women.iter().map(|woman| woman.allosomes.clone()) {
|
||||
//~^ ERROR unexpected `,` in pattern
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
||||
fn analyze_male_sex_chromosomes(men: &[Genome]) {
|
||||
// (missing parentheses in pattern with `@` binding)
|
||||
for x, y @ Allosome::Y(_) in men.iter().map(|man| man.allosomes.clone()) {
|
||||
//~^ ERROR unexpected `,` in pattern
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let genomes = Vec::new();
|
||||
// (missing parentheses in `let` pattern)
|
||||
let women, men: (Vec<Genome>, Vec<Genome>) = genomes.iter().cloned()
|
||||
//~^ ERROR unexpected `,` in pattern
|
||||
.partition(|g: &Genome| g.allosomes.0.is_x() && g.allosomes.1.is_x());
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
error: unexpected `,` in pattern
|
||||
--> $DIR/issue-48492-tuple-destructure-missing-parens.rs:48:17
|
||||
|
|
||||
LL | while let b1, b2, b3 = reading_frame.next().expect("there should be a start codon") {
|
||||
| --^------- help: try adding parentheses: `(b1, b2, b3)`
|
||||
|
||||
error: unexpected `,` in pattern
|
||||
--> $DIR/issue-48492-tuple-destructure-missing-parens.rs:59:14
|
||||
|
|
||||
LL | if let b1, b2, b3 = reading_frame.next().unwrap() {
|
||||
| --^------- help: try adding parentheses: `(b1, b2, b3)`
|
||||
|
||||
error: unexpected `,` in pattern
|
||||
--> $DIR/issue-48492-tuple-destructure-missing-parens.rs:69:28
|
||||
|
|
||||
LL | Nucleotide::Adenine, Nucleotide::Cytosine, _ => true
|
||||
| -------------------^------------------------ help: try adding parentheses: `(Nucleotide::Adenine, Nucleotide::Cytosine, _)`
|
||||
|
||||
error: unexpected `,` in pattern
|
||||
--> $DIR/issue-48492-tuple-destructure-missing-parens.rs:77:10
|
||||
|
|
||||
LL | for x, _barr_body in women.iter().map(|woman| woman.allosomes.clone()) {
|
||||
| -^----------- help: try adding parentheses: `(x, _barr_body)`
|
||||
|
||||
error: unexpected `,` in pattern
|
||||
--> $DIR/issue-48492-tuple-destructure-missing-parens.rs:85:10
|
||||
|
|
||||
LL | for x, y @ Allosome::Y(_) in men.iter().map(|man| man.allosomes.clone()) {
|
||||
| -^------------------- help: try adding parentheses: `(x, y @ Allosome::Y(_))`
|
||||
|
||||
error: unexpected `,` in pattern
|
||||
--> $DIR/issue-48492-tuple-destructure-missing-parens.rs:94:14
|
||||
|
|
||||
LL | let women, men: (Vec<Genome>, Vec<Genome>) = genomes.iter().cloned()
|
||||
| -----^---- help: try adding parentheses: `(women, men)`
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
@ -5,6 +5,6 @@ LL | if data.is_null() {}
|
||||
| ^^^^^^^
|
||||
|
|
||||
= note: #[warn(tyvar_behind_raw_pointer)] on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 epoch!
|
||||
= note: for more information, see issue #46906 <https://github.com/rust-lang/rust/issues/46906>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user