Skip to content

Rollup of 11 pull requests #66485

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 29 commits into from
Nov 17, 2019
Merged
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
6fc18a9
Centralize panic macro documentation
czipperz Jun 4, 2019
91aadf0
find_deprecation: deprecation attr may be ill-formed meta.
Centril Nov 13, 2019
8444e16
move DIAGNOSTICS usage to rustc_driver
Centril Nov 15, 2019
e85f40c
add missing 'static lifetime in docs
mulimoen Nov 16, 2019
52d7246
miri panic_unwind: fix hack for SEH platforms
RalfJung Nov 16, 2019
e8ff465
avoid linking errors
RalfJung Nov 16, 2019
bd63c59
Use "field is never read" instead of "field is never used"
Nov 16, 2019
8575743
rustc_plugin: Remove `Registry::register_attribute`
petrochenkov Nov 12, 2019
266f547
ast: Keep `extern` qualifiers in functions more precisely
petrochenkov Nov 9, 2019
00bc449
ast: Keep string literals in ABIs precisely
petrochenkov Nov 9, 2019
b85a3da
parse: Support parsing optional literals
petrochenkov Nov 10, 2019
a699f17
parse: Use string literal parsing in the `asm` macro
petrochenkov Nov 10, 2019
8c7530a
Improve documentation of `Vec::split_off(...)`
mqudsi Oct 23, 2019
a36c3f6
Revise the text of `vec::split_off()` per review in #65739
mqudsi Nov 16, 2019
3407c49
Clarify transmute_copy documentation example
ALSchwalm Nov 16, 2019
11580ce
Address review comments
petrochenkov Nov 16, 2019
28aec1b
Add some more tests
petrochenkov Nov 16, 2019
cfe94b4
Add test for issue 63116
Alexendoo Nov 16, 2019
d8f2526
Rollup merge of #65739 - mqudsi:vec_split_off_docs, r=dtolnay
JohnTitor Nov 17, 2019
b83d50d
Rollup merge of #66271 - petrochenkov:abism, r=Centril
JohnTitor Nov 17, 2019
54998d1
Rollup merge of #66344 - petrochenkov:noregattr, r=matthewjasper
JohnTitor Nov 17, 2019
842612f
Rollup merge of #66381 - Centril:66340, r=petrochenkov
JohnTitor Nov 17, 2019
05482d0
Rollup merge of #66395 - jplatte:centralize-panic-docs, r=Dylan-DPC
JohnTitor Nov 17, 2019
6e6c46c
Rollup merge of #66456 - Centril:driver-codes, r=Mark-Simulacrum
JohnTitor Nov 17, 2019
404081f
Rollup merge of #66465 - mulimoen:fix_lifetime_elision_not_shown, r=r…
JohnTitor Nov 17, 2019
937195b
Rollup merge of #66466 - RalfJung:seh, r=oli-obk
JohnTitor Nov 17, 2019
c0fccf5
Rollup merge of #66469 - CosineP:fix/field-lint, r=petrochenkov
JohnTitor Nov 17, 2019
750dd03
Rollup merge of #66471 - Alexendoo:test-issue-63116, r=Centril
JohnTitor Nov 17, 2019
f65cb87
Rollup merge of #66477 - ALSchwalm:clarify-transmute-copy, r=Centril
JohnTitor Nov 17, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.lock
Original file line number Diff line number Diff line change
@@ -3522,6 +3522,7 @@ dependencies = [
"rustc",
"rustc_codegen_utils",
"rustc_data_structures",
"rustc_error_codes",
"rustc_errors",
"rustc_interface",
"rustc_lint",
@@ -3595,7 +3596,6 @@ dependencies = [
"rustc_codegen_ssa",
"rustc_codegen_utils",
"rustc_data_structures",
"rustc_error_codes",
"rustc_errors",
"rustc_incremental",
"rustc_lint",
7 changes: 3 additions & 4 deletions src/liballoc/vec.rs
Original file line number Diff line number Diff line change
@@ -1333,10 +1333,9 @@ impl<T> Vec<T> {

/// Splits the collection into two at the given index.
///
/// Returns a newly allocated `Self`. `self` contains elements `[0, at)`,
/// and the returned `Self` contains elements `[at, len)`.
///
/// Note that the capacity of `self` does not change.
/// Returns a newly allocated vector containing the elements in the range
/// `[at, len)`. After the call, the original vector will be left containing
/// the elements `[0, at)` with its previous capacity unchanged.
///
/// # Panics
///
4 changes: 1 addition & 3 deletions src/libcore/macros.rs → src/libcore/macros/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
/// Panics the current thread.
///
/// For details, see `std::macros`.
#[doc(include = "panic.md")]
#[macro_export]
#[allow_internal_unstable(core_panic,
// FIXME(anp, eddyb) `core_intrinsics` is used here to allow calling
47 changes: 47 additions & 0 deletions src/libcore/macros/panic.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
Panics the current thread.

This allows a program to terminate immediately and provide feedback
to the caller of the program. `panic!` should be used when a program reaches
an unrecoverable state.

This macro is the perfect way to assert conditions in example code and in
tests. `panic!` is closely tied with the `unwrap` method of both [`Option`]
and [`Result`][runwrap] enums. Both implementations call `panic!` when they are set
to None or Err variants.

This macro is used to inject panic into a Rust thread, causing the thread to
panic entirely. Each thread's panic can be reaped as the `Box<Any>` type,
and the single-argument form of the `panic!` macro will be the value which
is transmitted.

[`Result`] enum is often a better solution for recovering from errors than
using the `panic!` macro. This macro should be used to avoid proceeding using
incorrect values, such as from external sources. Detailed information about
error handling is found in the [book].

The multi-argument form of this macro panics with a string and has the
[`format!`] syntax for building a string.

See also the macro [`compile_error!`], for raising errors during compilation.

[runwrap]: ../std/result/enum.Result.html#method.unwrap
[`Option`]: ../std/option/enum.Option.html#method.unwrap
[`Result`]: ../std/result/enum.Result.html
[`format!`]: ../std/macro.format.html
[`compile_error!`]: ../std/macro.compile_error.html
[book]: ../book/ch09-00-error-handling.html

# Current implementation

If the main thread panics it will terminate all your threads and end your
program with code `101`.

# Examples

```should_panic
# #![allow(unreachable_code)]
panic!();
panic!("this is a terrible mistake!");
panic!(4); // panic with the value of 4 to be collected elsewhere
panic!("this is a {} {message}", "fancy", message = "message");
```
10 changes: 5 additions & 5 deletions src/libcore/mem/mod.rs
Original file line number Diff line number Diff line change
@@ -744,20 +744,20 @@ pub fn drop<T>(_x: T) { }
/// bar: u8,
/// }
///
/// let foo_slice = [10u8];
/// let foo_array = [10u8];
///
/// unsafe {
/// // Copy the data from 'foo_slice' and treat it as a 'Foo'
/// let mut foo_struct: Foo = mem::transmute_copy(&foo_slice);
/// // Copy the data from 'foo_array' and treat it as a 'Foo'
/// let mut foo_struct: Foo = mem::transmute_copy(&foo_array);
/// assert_eq!(foo_struct.bar, 10);
///
/// // Modify the copied data
/// foo_struct.bar = 20;
/// assert_eq!(foo_struct.bar, 20);
/// }
///
/// // The contents of 'foo_slice' should not have changed
/// assert_eq!(foo_slice, [10]);
/// // The contents of 'foo_array' should not have changed
/// assert_eq!(foo_array, [10]);
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
5 changes: 0 additions & 5 deletions src/libpanic_unwind/lib.rs
Original file line number Diff line number Diff line change
@@ -39,11 +39,6 @@ cfg_if::cfg_if! {
if #[cfg(miri)] {
#[path = "miri.rs"]
mod imp;
// On MSVC we need the SEH lang items as well...
// This should match the conditions of the `seh.rs` import below.
#[cfg(all(target_env = "msvc", not(target_arch = "aarch64")))]
#[allow(unused)]
mod seh;
} else if #[cfg(target_os = "emscripten")] {
#[path = "emcc.rs"]
mod imp;
21 changes: 20 additions & 1 deletion src/libpanic_unwind/miri.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#![allow(nonstandard_style)]

use core::any::Any;
use alloc::boxed::Box;

@@ -13,11 +15,28 @@ pub unsafe fn cleanup(ptr: *mut u8) -> Box<dyn Any + Send> {
Box::from_raw(ptr)
}


// This is required by the compiler to exist (e.g., it's a lang item),
// but is never used by Miri. Therefore, we just use a stub here
#[lang = "eh_personality"]
#[cfg(not(test))]
fn rust_eh_personality() {
unsafe { core::intrinsics::abort() }
}

// The rest is required on *some* targets to exist (specifically, MSVC targets that use SEH).
// We just add it on all targets. Copied from `seh.rs`.
#[repr(C)]
pub struct _TypeDescriptor {
pub pVFTable: *const u8,
pub spare: *mut u8,
pub name: [u8; 11],
}

const TYPE_NAME: [u8; 11] = *b"rust_panic\0";

#[cfg_attr(not(test), lang = "eh_catch_typeinfo")]
static mut TYPE_DESCRIPTOR: _TypeDescriptor = _TypeDescriptor {
pVFTable: core::ptr::null(),
spare: core::ptr::null_mut(),
name: TYPE_NAME,
};
6 changes: 1 addition & 5 deletions src/librustc/hir/def.rs
Original file line number Diff line number Diff line change
@@ -42,8 +42,6 @@ pub enum NonMacroAttrKind {
DeriveHelper,
/// Single-segment custom attribute registered with `#[register_attr]`.
Registered,
/// Single-segment custom attribute registered by a legacy plugin (`register_attribute`).
LegacyPluginHelper,
}

#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, HashStable)]
@@ -330,7 +328,6 @@ impl NonMacroAttrKind {
NonMacroAttrKind::Tool => "tool attribute",
NonMacroAttrKind::DeriveHelper => "derive helper attribute",
NonMacroAttrKind::Registered => "explicitly registered attribute",
NonMacroAttrKind::LegacyPluginHelper => "legacy plugin helper attribute",
}
}

@@ -345,8 +342,7 @@ impl NonMacroAttrKind {
pub fn is_used(self) -> bool {
match self {
NonMacroAttrKind::Tool | NonMacroAttrKind::DeriveHelper => true,
NonMacroAttrKind::Builtin | NonMacroAttrKind::Registered |
NonMacroAttrKind::LegacyPluginHelper => false,
NonMacroAttrKind::Builtin | NonMacroAttrKind::Registered => false,
}
}
}
2 changes: 1 addition & 1 deletion src/librustc/hir/lowering.rs
Original file line number Diff line number Diff line change
@@ -1219,7 +1219,7 @@ impl<'a> LoweringContext<'a> {
ImplTraitContext::disallowed(),
),
unsafety: f.unsafety,
abi: this.lower_abi(f.abi),
abi: this.lower_extern(f.ext),
decl: this.lower_fn_decl(&f.decl, None, false, None),
param_names: this.lower_fn_params_to_names(&f.decl),
}))
18 changes: 13 additions & 5 deletions src/librustc/hir/lowering/item.rs
Original file line number Diff line number Diff line change
@@ -735,7 +735,7 @@ impl LoweringContext<'_> {

fn lower_foreign_mod(&mut self, fm: &ForeignMod) -> hir::ForeignMod {
hir::ForeignMod {
abi: self.lower_abi(fm.abi),
abi: fm.abi.map_or(abi::Abi::C, |abi| self.lower_abi(abi)),
items: fm.items
.iter()
.map(|x| self.lower_foreign_item(x))
@@ -1283,18 +1283,26 @@ impl LoweringContext<'_> {
unsafety: h.unsafety,
asyncness: self.lower_asyncness(h.asyncness.node),
constness: h.constness.node,
abi: self.lower_abi(h.abi),
abi: self.lower_extern(h.ext),
}
}

pub(super) fn lower_abi(&mut self, abi: Abi) -> abi::Abi {
abi::lookup(&abi.symbol.as_str()).unwrap_or_else(|| {
pub(super) fn lower_abi(&mut self, abi: StrLit) -> abi::Abi {
abi::lookup(&abi.symbol_unescaped.as_str()).unwrap_or_else(|| {
self.error_on_invalid_abi(abi);
abi::Abi::Rust
})
}

fn error_on_invalid_abi(&self, abi: Abi) {
pub(super) fn lower_extern(&mut self, ext: Extern) -> abi::Abi {
match ext {
Extern::None => abi::Abi::Rust,
Extern::Implicit => abi::Abi::C,
Extern::Explicit(abi) => self.lower_abi(abi),
}
}

fn error_on_invalid_abi(&self, abi: StrLit) {
struct_span_err!(
self.sess,
abi.span,
14 changes: 5 additions & 9 deletions src/librustc/session/mod.rs
Original file line number Diff line number Diff line change
@@ -21,11 +21,10 @@ use errors::emitter::{Emitter, EmitterWriter};
use errors::emitter::HumanReadableErrorType;
use errors::annotate_snippet_emitter_writer::{AnnotateSnippetEmitterWriter};
use syntax::edition::Edition;
use syntax::feature_gate::{self, AttributeType};
use syntax::feature_gate;
use errors::json::JsonEmitter;
use syntax::source_map;
use syntax::sess::{ParseSess, ProcessCfgMod};
use syntax::symbol::Symbol;
use syntax_pos::{MultiSpan, Span};

use rustc_target::spec::{PanicStrategy, RelroLevel, Target, TargetTriple};
@@ -79,7 +78,6 @@ pub struct Session {
/// in order to avoid redundantly verbose output (Issue #24690, #44953).
pub one_time_diagnostics: Lock<FxHashSet<(DiagnosticMessageId, Option<Span>, String)>>,
pub plugin_llvm_passes: OneThread<RefCell<Vec<String>>>,
pub plugin_attributes: Lock<Vec<(Symbol, AttributeType)>>,
pub crate_types: Once<Vec<config::CrateType>>,
/// The `crate_disambiguator` is constructed out of all the `-C metadata`
/// arguments passed to the compiler. Its value together with the crate-name
@@ -1039,12 +1037,11 @@ pub fn build_session_with_source_map(

let external_macro_backtrace = sopts.debugging_opts.external_macro_backtrace;

let emitter = match diagnostics_output {
DiagnosticOutput::Default => default_emitter(&sopts, registry, &source_map, None),
DiagnosticOutput::Raw(write) => {
default_emitter(&sopts, registry, &source_map, Some(write))
}
let write_dest = match diagnostics_output {
DiagnosticOutput::Default => None,
DiagnosticOutput::Raw(write) => Some(write),
};
let emitter = default_emitter(&sopts, registry, &source_map, write_dest);

let diagnostic_handler = errors::Handler::with_emitter_and_flags(
emitter,
@@ -1166,7 +1163,6 @@ fn build_session_(
working_dir,
one_time_diagnostics: Default::default(),
plugin_llvm_passes: OneThread::new(RefCell::new(Vec::new())),
plugin_attributes: Lock::new(Vec::new()),
crate_types: Once::new(),
crate_disambiguator: Once::new(),
features: Once::new(),
1 change: 1 addition & 0 deletions src/librustc_driver/Cargo.toml
Original file line number Diff line number Diff line change
@@ -26,6 +26,7 @@ rustc_plugin = { path = "../librustc_plugin/deprecated" } # To get this in the s
rustc_plugin_impl = { path = "../librustc_plugin" }
rustc_save_analysis = { path = "../librustc_save_analysis" }
rustc_codegen_utils = { path = "../librustc_codegen_utils" }
rustc_error_codes = { path = "../librustc_error_codes" }
rustc_interface = { path = "../librustc_interface" }
rustc_serialize = { path = "../libserialize", package = "serialize" }
rustc_resolve = { path = "../librustc_resolve" }
16 changes: 10 additions & 6 deletions src/librustc_driver/lib.rs
Original file line number Diff line number Diff line change
@@ -40,7 +40,7 @@ use rustc::ty::TyCtxt;
use rustc::util::common::{set_time_depth, time, print_time_passes_entry, ErrorReported};
use rustc_metadata::locator;
use rustc_codegen_utils::codegen_backend::CodegenBackend;
use errors::PResult;
use errors::{PResult, registry::Registry};
use rustc_interface::interface;
use rustc_interface::util::get_codegen_sysroot;
use rustc_data_structures::sync::SeqCst;
@@ -140,6 +140,10 @@ impl Callbacks for TimePassesCallbacks {
}
}

pub fn diagnostics_registry() -> Registry {
Registry::new(&rustc_error_codes::DIAGNOSTICS)
}

// Parse args and run the compiler. This is the primary entry point for rustc.
// See comments on CompilerCalls below for details about the callbacks argument.
// The FileLoader provides a way to load files from sources other than the file system.
@@ -182,13 +186,14 @@ pub fn run_compiler(
lint_caps: Default::default(),
register_lints: None,
override_queries: None,
registry: diagnostics_registry(),
};
callbacks.config(&mut config);
config
};

if let Some(ref code) = matches.opt_str("explain") {
handle_explain(code, sopts.error_format);
handle_explain(diagnostics_registry(), code, sopts.error_format);
return Ok(());
}

@@ -261,6 +266,7 @@ pub fn run_compiler(
lint_caps: Default::default(),
register_lints: None,
override_queries: None,
registry: diagnostics_registry(),
};

callbacks.config(&mut config);
@@ -510,15 +516,13 @@ fn stdout_isatty() -> bool {
}
}

fn handle_explain(code: &str,
output: ErrorOutputType) {
let descriptions = rustc_interface::util::diagnostics_registry();
fn handle_explain(registry: Registry, code: &str, output: ErrorOutputType) {
let normalised = if code.starts_with("E") {
code.to_string()
} else {
format!("E{0:0>4}", code)
};
match descriptions.find_description(&normalised) {
match registry.find_description(&normalised) {
Some(ref description) => {
let mut is_in_code_block = false;
let mut text = String::new();
3 changes: 1 addition & 2 deletions src/librustc_error_codes/error_codes.rs
Original file line number Diff line number Diff line change
@@ -7,8 +7,7 @@
// Error messages' format must follow the RFC 1567 available here:
// https://github.com/rust-lang/rfcs/pull/1567

crate::register_diagnostics! {

register_diagnostics! {
E0001: include_str!("./error_codes/E0001.md"),
E0002: include_str!("./error_codes/E0002.md"),
E0004: include_str!("./error_codes/E0004.md"),
11 changes: 3 additions & 8 deletions src/librustc_error_codes/lib.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@
//! This library is used to gather all error codes into one place. The goal
//! being to make their maintenance easier.
//! This library is used to gather all error codes into one place,
//! the goal being to make their maintenance easier.

#[macro_export]
macro_rules! register_diagnostics {
($($ecode:ident: $message:expr,)*) => (
$crate::register_diagnostics!{$($ecode:$message,)* ;}
);

($($ecode:ident: $message:expr,)* ; $($code:ident,)*) => (
pub static DIAGNOSTICS: &[(&str, &str)] = &[
$( (stringify!($ecode), $message), )*
];

$(
pub const $ecode: &str = $message;
pub const $ecode: () = ();
)*
$(
pub const $code: () = ();
1 change: 0 additions & 1 deletion src/librustc_interface/Cargo.toml
Original file line number Diff line number Diff line change
@@ -34,7 +34,6 @@ rustc_errors = { path = "../librustc_errors" }
rustc_plugin = { path = "../librustc_plugin", package = "rustc_plugin_impl" }
rustc_privacy = { path = "../librustc_privacy" }
rustc_resolve = { path = "../librustc_resolve" }
rustc_error_codes = { path = "../librustc_error_codes" }
tempfile = "3.0.5"
once_cell = "1"

28 changes: 13 additions & 15 deletions src/librustc_interface/interface.rs
Original file line number Diff line number Diff line change
@@ -11,6 +11,7 @@ use rustc_codegen_utils::codegen_backend::CodegenBackend;
use rustc_data_structures::OnDrop;
use rustc_data_structures::sync::Lrc;
use rustc_data_structures::fx::{FxHashSet, FxHashMap};
use rustc_errors::registry::Registry;
use rustc_parse::new_parser_from_source_str;
use rustc::ty;
use std::path::PathBuf;
@@ -141,19 +142,24 @@ pub struct Config {
/// The second parameter is local providers and the third parameter is external providers.
pub override_queries:
Option<fn(&Session, &mut ty::query::Providers<'_>, &mut ty::query::Providers<'_>)>,

/// Registry of diagnostics codes.
pub registry: Registry,
}

pub fn run_compiler_in_existing_thread_pool<F, R>(config: Config, f: F) -> R
where
F: FnOnce(&Compiler) -> R,
{
pub fn run_compiler_in_existing_thread_pool<R>(
config: Config,
f: impl FnOnce(&Compiler) -> R,
) -> R {
let registry = &config.registry;
let (sess, codegen_backend, source_map) = util::create_session(
config.opts,
config.crate_cfg,
config.diagnostic_output,
config.file_loader,
config.input_path.clone(),
config.lint_caps,
registry.clone(),
);

let compiler = Compiler {
@@ -171,17 +177,13 @@ where
};

let _sess_abort_error = OnDrop(|| {
compiler.sess.diagnostic().print_error_count(&util::diagnostics_registry());
compiler.sess.diagnostic().print_error_count(registry);
});

f(&compiler)
}

pub fn run_compiler<F, R>(mut config: Config, f: F) -> R
where
F: FnOnce(&Compiler) -> R + Send,
R: Send,
{
pub fn run_compiler<R: Send>(mut config: Config, f: impl FnOnce(&Compiler) -> R + Send) -> R {
let stderr = config.stderr.take();
util::spawn_thread_pool(
config.opts.edition,
@@ -191,11 +193,7 @@ where
)
}

pub fn default_thread_pool<F, R>(edition: edition::Edition, f: F) -> R
where
F: FnOnce() -> R + Send,
R: Send,
{
pub fn default_thread_pool<R: Send>(edition: edition::Edition, f: impl FnOnce() -> R + Send) -> R {
// the 1 here is duplicating code in config.opts.debugging_opts.threads
// which also defaults to 1; it ultimately doesn't matter as the default
// isn't threaded, and just ignores this parameter
9 changes: 1 addition & 8 deletions src/librustc_interface/passes.rs
Original file line number Diff line number Diff line change
@@ -240,15 +240,8 @@ pub fn register_plugins<'a>(
}
});

let Registry {
syntax_exts,
llvm_passes,
attributes,
..
} = registry;

let Registry { syntax_exts, llvm_passes, .. } = registry;
*sess.plugin_llvm_passes.borrow_mut() = llvm_passes;
*sess.plugin_attributes.borrow_mut() = attributes;

Ok((krate, PluginInfo { syntax_exts }, Lrc::new(lint_store)))
}
13 changes: 1 addition & 12 deletions src/librustc_interface/util.rs
Original file line number Diff line number Diff line change
@@ -15,7 +15,6 @@ use rustc_data_structures::fx::{FxHashSet, FxHashMap};
use rustc_errors::registry::Registry;
use rustc_metadata::dynamic_lib::DynamicLibrary;
use rustc_resolve::{self, Resolver};
use rustc_error_codes;
use std::env;
use std::env::consts::{DLL_PREFIX, DLL_SUFFIX};
use std::io::{self, Write};
@@ -37,15 +36,6 @@ use syntax_pos::edition::Edition;
#[cfg(not(parallel_compiler))]
use std::{thread, panic};

pub fn diagnostics_registry() -> Registry {
let mut all_errors = Vec::new();
all_errors.extend_from_slice(&rustc_error_codes::DIAGNOSTICS);
// FIXME: need to figure out a way to get these back in here
// all_errors.extend_from_slice(get_codegen_backend(sess).diagnostics());

Registry::new(&all_errors)
}

/// Adds `target_feature = "..."` cfgs for a variety of platform
/// specific features (SSE, NEON etc.).
///
@@ -77,9 +67,8 @@ pub fn create_session(
file_loader: Option<Box<dyn FileLoader + Send + Sync + 'static>>,
input_path: Option<PathBuf>,
lint_caps: FxHashMap<lint::LintId, lint::Level>,
descriptions: Registry,
) -> (Lrc<Session>, Lrc<Box<dyn CodegenBackend>>, Lrc<SourceMap>) {
let descriptions = diagnostics_registry();

let loader = file_loader.unwrap_or(box RealFileLoader);
let source_map = Lrc::new(SourceMap::with_file_loader(
loader,
20 changes: 1 addition & 19 deletions src/librustc_lint/unused.rs
Original file line number Diff line number Diff line change
@@ -309,29 +309,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedAttributes {
}
}

let plugin_attributes = cx.sess().plugin_attributes.borrow();
for &(name, ty) in plugin_attributes.iter() {
if ty == AttributeType::Whitelisted && attr.check_name(name) {
debug!("{:?} (plugin attr) is whitelisted with ty {:?}", name, ty);
break;
}
}

let name = attr.name_or_empty();
if !attr::is_used(attr) {
debug!("emitting warning for: {:?}", attr);
cx.span_lint(UNUSED_ATTRIBUTES, attr.span, "unused attribute");
// Is it a builtin attribute that must be used at the crate level?
let known_crate = attr_info.map(|&&(_, ty, ..)| {
ty == AttributeType::CrateLevel
}).unwrap_or(false);

// Has a plugin registered this attribute as one that must be used at
// the crate level?
let plugin_crate = plugin_attributes.iter()
.find(|&&(x, t)| name == x && AttributeType::CrateLevel == t)
.is_some();
if known_crate || plugin_crate {
if attr_info.map_or(false, |(_, ty, ..)| ty == &AttributeType::CrateLevel) {
let msg = match attr.style {
ast::AttrStyle::Outer => {
"crate-level attribute should be an inner attribute: add an exclamation \
50 changes: 38 additions & 12 deletions src/librustc_parse/parser/expr.rs
Original file line number Diff line number Diff line change
@@ -778,13 +778,12 @@ impl<'a> Parser<'a> {

macro_rules! parse_lit {
() => {
match self.parse_lit() {
Ok(literal) => {
match self.parse_opt_lit() {
Some(literal) => {
hi = self.prev_span;
ex = ExprKind::Lit(literal);
}
Err(mut err) => {
err.cancel();
None => {
return Err(self.expected_expression_found());
}
}
@@ -1074,11 +1073,39 @@ impl<'a> Parser<'a> {
self.maybe_recover_from_bad_qpath(expr, true)
}

/// Matches `lit = true | false | token_lit`.
/// Returns a string literal if the next token is a string literal.
/// In case of error returns `Some(lit)` if the next token is a literal with a wrong kind,
/// and returns `None` if the next token is not literal at all.
pub fn parse_str_lit(&mut self) -> Result<ast::StrLit, Option<Lit>> {
match self.parse_opt_lit() {
Some(lit) => match lit.kind {
ast::LitKind::Str(symbol_unescaped, style) => Ok(ast::StrLit {
style,
symbol: lit.token.symbol,
suffix: lit.token.suffix,
span: lit.span,
symbol_unescaped,
}),
_ => Err(Some(lit)),
}
None => Err(None),
}
}

pub(super) fn parse_lit(&mut self) -> PResult<'a, Lit> {
self.parse_opt_lit().ok_or_else(|| {
let msg = format!("unexpected token: {}", self.this_token_descr());
self.span_fatal(self.token.span, &msg)
})
}

/// Matches `lit = true | false | token_lit`.
/// Returns `None` if the next token is not a literal.
pub(super) fn parse_opt_lit(&mut self) -> Option<Lit> {
let mut recovered = None;
if self.token == token::Dot {
// Attempt to recover `.4` as `0.4`.
// Attempt to recover `.4` as `0.4`. We don't currently have any syntax where
// dot would follow an optional literal, so we do this unconditionally.
recovered = self.look_ahead(1, |next_token| {
if let token::Literal(token::Lit { kind: token::Integer, symbol, suffix })
= next_token.kind {
@@ -1107,11 +1134,10 @@ impl<'a> Parser<'a> {
match Lit::from_token(token) {
Ok(lit) => {
self.bump();
Ok(lit)
Some(lit)
}
Err(LitError::NotLiteral) => {
let msg = format!("unexpected token: {}", self.this_token_descr());
Err(self.span_fatal(token.span, &msg))
None
}
Err(err) => {
let span = token.span;
@@ -1120,18 +1146,18 @@ impl<'a> Parser<'a> {
_ => unreachable!(),
};
self.bump();
self.error_literal_from_token(err, lit, span);
self.report_lit_error(err, lit, span);
// Pack possible quotes and prefixes from the original literal into
// the error literal's symbol so they can be pretty-printed faithfully.
let suffixless_lit = token::Lit::new(lit.kind, lit.symbol, None);
let symbol = Symbol::intern(&suffixless_lit.to_string());
let lit = token::Lit::new(token::Err, symbol, lit.suffix);
Lit::from_lit_token(lit, span).map_err(|_| unreachable!())
Some(Lit::from_lit_token(lit, span).unwrap_or_else(|_| unreachable!()))
}
}
}

fn error_literal_from_token(&self, err: LitError, lit: token::Lit, span: Span) {
fn report_lit_error(&self, err: LitError, lit: token::Lit, span: Span) {
// Checks if `s` looks like i32 or u1234 etc.
fn looks_like_width_suffix(first_chars: &[char], s: &str) -> bool {
s.len() > 1
41 changes: 24 additions & 17 deletions src/librustc_parse/parser/item.rs
Original file line number Diff line number Diff line change
@@ -3,9 +3,9 @@ use super::diagnostics::{Error, dummy_arg, ConsumeClosingDelim};

use crate::maybe_whole;

use syntax::ast::{self, Abi, DUMMY_NODE_ID, Ident, Attribute, AttrKind, AttrStyle, AnonConst, Item};
use syntax::ast::{self, DUMMY_NODE_ID, Ident, Attribute, AttrKind, AttrStyle, AnonConst, Item};
use syntax::ast::{ItemKind, ImplItem, ImplItemKind, TraitItem, TraitItemKind, UseTree, UseTreeKind};
use syntax::ast::{PathSegment, IsAuto, Constness, IsAsync, Unsafety, Defaultness};
use syntax::ast::{PathSegment, IsAuto, Constness, IsAsync, Unsafety, Defaultness, Extern, StrLit};
use syntax::ast::{Visibility, VisibilityKind, Mutability, FnHeader, ForeignItem, ForeignItemKind};
use syntax::ast::{Ty, TyKind, Generics, TraitRef, EnumDef, VariantData, StructField};
use syntax::ast::{Mac, MacDelimiter, Block, BindingMode, FnDecl, FnSig, SelfKind, Param};
@@ -105,7 +105,7 @@ impl<'a> Parser<'a> {
return Ok(Some(self.parse_item_extern_crate(lo, vis, attrs)?));
}

let abi = self.parse_opt_abi()?;
let abi = self.parse_abi();

if self.eat_keyword(kw::Fn) {
// EXTERN FUNCTION ITEM
@@ -114,7 +114,7 @@ impl<'a> Parser<'a> {
unsafety: Unsafety::Normal,
asyncness: respan(fn_span, IsAsync::NotAsync),
constness: respan(fn_span, Constness::NotConst),
abi,
ext: Extern::from_abi(abi),
};
return self.parse_item_fn(lo, vis, attrs, header);
} else if self.check(&token::OpenDelim(token::Brace)) {
@@ -143,14 +143,14 @@ impl<'a> Parser<'a> {
if self.check_keyword(kw::Extern) {
self.sess.gated_spans.gate(sym::const_extern_fn, lo.to(self.token.span));
}
let abi = self.parse_extern_abi()?;
let ext = self.parse_extern()?;
self.bump(); // `fn`

let header = FnHeader {
unsafety,
asyncness: respan(const_span, IsAsync::NotAsync),
constness: respan(const_span, Constness::Const),
abi,
ext,
};
return self.parse_item_fn(lo, vis, attrs, header);
}
@@ -193,7 +193,7 @@ impl<'a> Parser<'a> {
unsafety,
asyncness,
constness: respan(fn_span, Constness::NotConst),
abi: Abi::new(sym::Rust, fn_span),
ext: Extern::None,
};
return self.parse_item_fn(lo, vis, attrs, header);
}
@@ -230,7 +230,7 @@ impl<'a> Parser<'a> {
unsafety: Unsafety::Normal,
asyncness: respan(fn_span, IsAsync::NotAsync),
constness: respan(fn_span, Constness::NotConst),
abi: Abi::new(sym::Rust, fn_span),
ext: Extern::None,
};
return self.parse_item_fn(lo, vis, attrs, header);
}
@@ -242,14 +242,14 @@ impl<'a> Parser<'a> {
self.bump(); // `unsafe`
// `{` is also expected after `unsafe`; in case of error, include it in the diagnostic.
self.check(&token::OpenDelim(token::Brace));
let abi = self.parse_extern_abi()?;
let ext = self.parse_extern()?;
self.expect_keyword(kw::Fn)?;
let fn_span = self.prev_span;
let header = FnHeader {
unsafety: Unsafety::Unsafe,
asyncness: respan(fn_span, IsAsync::NotAsync),
constness: respan(fn_span, Constness::NotConst),
abi,
ext,
};
return self.parse_item_fn(lo, vis, attrs, header);
}
@@ -1100,7 +1100,7 @@ impl<'a> Parser<'a> {
fn parse_item_foreign_mod(
&mut self,
lo: Span,
abi: Abi,
abi: Option<StrLit>,
visibility: Visibility,
mut attrs: Vec<Attribute>,
extern_sp: Span,
@@ -1775,9 +1775,16 @@ impl<'a> Parser<'a> {
attrs: Vec<Attribute>,
header: FnHeader,
) -> PResult<'a, Option<P<Item>>> {
let is_c_abi = match header.ext {
ast::Extern::None => false,
ast::Extern::Implicit => true,
ast::Extern::Explicit(abi) => abi.symbol_unescaped == sym::C,
};
let (ident, decl, generics) = self.parse_fn_sig(ParamCfg {
is_self_allowed: false,
allow_c_variadic: header.abi.symbol == sym::C && header.unsafety == Unsafety::Unsafe,
// FIXME: Parsing should not depend on ABI or unsafety and
// the variadic parameter should always be parsed.
allow_c_variadic: is_c_abi && header.unsafety == Unsafety::Unsafe,
is_name_required: |_| true,
})?;
let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
@@ -1905,19 +1912,19 @@ impl<'a> Parser<'a> {
}
let asyncness = respan(self.prev_span, asyncness);
let unsafety = self.parse_unsafety();
let (constness, unsafety, abi) = if is_const_fn {
(respan(const_span, Constness::Const), unsafety, Abi::default())
let (constness, unsafety, ext) = if is_const_fn {
(respan(const_span, Constness::Const), unsafety, Extern::None)
} else {
let abi = self.parse_extern_abi()?;
(respan(self.prev_span, Constness::NotConst), unsafety, abi)
let ext = self.parse_extern()?;
(respan(self.prev_span, Constness::NotConst), unsafety, ext)
};
if !self.eat_keyword(kw::Fn) {
// It is possible for `expect_one_of` to recover given the contents of
// `self.expected_tokens`, therefore, do not use `self.unexpected()` which doesn't
// account for this.
if !self.expect_one_of(&[], &[])? { unreachable!() }
}
Ok(FnHeader { constness, unsafety, asyncness, abi })
Ok(FnHeader { constness, unsafety, asyncness, ext })
}

/// Parse the "signature", including the identifier, parameters, and generics of a function.
64 changes: 15 additions & 49 deletions src/librustc_parse/parser/mod.rs
Original file line number Diff line number Diff line change
@@ -15,8 +15,8 @@ use crate::{Directory, DirectoryOwnership};
use crate::lexer::UnmatchedBrace;

use syntax::ast::{
self, Abi, DUMMY_NODE_ID, AttrStyle, Attribute, CrateSugar, Ident,
IsAsync, MacDelimiter, Mutability, StrStyle, Visibility, VisibilityKind, Unsafety,
self, DUMMY_NODE_ID, AttrStyle, Attribute, CrateSugar, Extern, Ident, StrLit,
IsAsync, MacDelimiter, Mutability, Visibility, VisibilityKind, Unsafety,
};

use syntax::print::pprust;
@@ -1212,40 +1212,34 @@ impl<'a> Parser<'a> {
}

/// Parses `extern string_literal?`.
/// If `extern` is not found, the Rust ABI is used.
/// If `extern` is found and a `string_literal` does not follow, the C ABI is used.
fn parse_extern_abi(&mut self) -> PResult<'a, Abi> {
fn parse_extern(&mut self) -> PResult<'a, Extern> {
Ok(if self.eat_keyword(kw::Extern) {
self.parse_opt_abi()?
Extern::from_abi(self.parse_abi())
} else {
Abi::default()
Extern::None
})
}

/// Parses a string literal as an ABI spec.
/// If one is not found, the "C" ABI is used.
fn parse_opt_abi(&mut self) -> PResult<'a, Abi> {
let span = if self.token.can_begin_literal_or_bool() {
let ast::Lit { span, kind, .. } = self.parse_lit()?;
match kind {
ast::LitKind::Str(symbol, _) => return Ok(Abi::new(symbol, span)),
ast::LitKind::Err(_) => {}
fn parse_abi(&mut self) -> Option<StrLit> {
match self.parse_str_lit() {
Ok(str_lit) => Some(str_lit),
Err(Some(lit)) => match lit.kind {
ast::LitKind::Err(_) => None,
_ => {
self.struct_span_err(span, "non-string ABI literal")
self.struct_span_err(lit.span, "non-string ABI literal")
.span_suggestion(
span,
lit.span,
"specify the ABI with a string literal",
"\"C\"".to_string(),
Applicability::MaybeIncorrect,
)
.emit();
None
}
}
span
} else {
self.prev_span
};
Ok(Abi::new(sym::C, span))
Err(None) => None,
}
}

/// We are parsing `async fn`. If we are on Rust 2015, emit an error.
@@ -1337,34 +1331,6 @@ impl<'a> Parser<'a> {
self.look_ahead(1, |t| *t == token::OpenDelim(token::Brace) ||
*t == token::BinOp(token::Star))
}

fn parse_optional_str(&mut self) -> Option<(Symbol, ast::StrStyle, Option<ast::Name>)> {
let ret = match self.token.kind {
token::Literal(token::Lit { kind: token::Str, symbol, suffix }) =>
(symbol, ast::StrStyle::Cooked, suffix),
token::Literal(token::Lit { kind: token::StrRaw(n), symbol, suffix }) =>
(symbol, ast::StrStyle::Raw(n), suffix),
_ => return None
};
self.bump();
Some(ret)
}

pub fn parse_str(&mut self) -> PResult<'a, (Symbol, StrStyle)> {
match self.parse_optional_str() {
Some((s, style, suf)) => {
let sp = self.prev_span;
self.expect_no_suffix(sp, "a string literal", suf);
Ok((s, style))
}
_ => {
let msg = "expected string literal";
let mut err = self.fatal(msg);
err.span_label(self.token.span, msg);
Err(err)
}
}
}
}

crate fn make_unclosed_delims_error(
4 changes: 2 additions & 2 deletions src/librustc_parse/parser/ty.rs
Original file line number Diff line number Diff line change
@@ -287,7 +287,7 @@ impl<'a> Parser<'a> {
*/

let unsafety = self.parse_unsafety();
let abi = self.parse_extern_abi()?;
let ext = self.parse_extern()?;
self.expect_keyword(kw::Fn)?;
let cfg = ParamCfg {
is_self_allowed: false,
@@ -296,7 +296,7 @@ impl<'a> Parser<'a> {
};
let decl = self.parse_fn_decl(cfg, false)?;
Ok(TyKind::BareFn(P(BareFnTy {
abi,
ext,
unsafety,
generic_params,
decl,
2 changes: 1 addition & 1 deletion src/librustc_passes/dead.rs
Original file line number Diff line number Diff line change
@@ -631,7 +631,7 @@ impl Visitor<'tcx> for DeadVisitor<'tcx> {

fn visit_struct_field(&mut self, field: &'tcx hir::StructField) {
if self.should_warn_about_field(&field) {
self.warn_dead_code(field.hir_id, field.span, field.ident.name, "field", "used");
self.warn_dead_code(field.hir_id, field.span, field.ident.name, "field", "read");
}
intravisit::walk_struct_field(self, field);
}
13 changes: 0 additions & 13 deletions src/librustc_plugin/registry.rs
Original file line number Diff line number Diff line change
@@ -7,7 +7,6 @@ use syntax_expand::base::{SyntaxExtension, SyntaxExtensionKind, NamedSyntaxExten
use syntax_expand::base::MacroExpanderFn;
use syntax::symbol::Symbol;
use syntax::ast;
use syntax::feature_gate::AttributeType;
use syntax_pos::Span;

use std::borrow::ToOwned;
@@ -39,9 +38,6 @@ pub struct Registry<'a> {

#[doc(hidden)]
pub llvm_passes: Vec<String>,

#[doc(hidden)]
pub attributes: Vec<(Symbol, AttributeType)>,
}

impl<'a> Registry<'a> {
@@ -54,7 +50,6 @@ impl<'a> Registry<'a> {
krate_span,
syntax_exts: vec![],
llvm_passes: vec![],
attributes: vec![],
}
}

@@ -98,12 +93,4 @@ impl<'a> Registry<'a> {
pub fn register_llvm_pass(&mut self, name: &str) {
self.llvm_passes.push(name.to_owned());
}

/// Register an attribute with an attribute type.
///
/// `Whitelisted` attributes will additionally not trigger the `unused_attribute`
/// lint. `CrateLevel` attributes will not be allowed on anything other than a crate.
pub fn register_attribute(&mut self, name: Symbol, ty: AttributeType) {
self.attributes.push((name, ty));
}
}
9 changes: 0 additions & 9 deletions src/librustc_resolve/diagnostics.rs
Original file line number Diff line number Diff line change
@@ -437,15 +437,6 @@ impl<'a> Resolver<'a> {
}));
}
}
Scope::LegacyPluginHelpers => {
let res = Res::NonMacroAttr(NonMacroAttrKind::LegacyPluginHelper);
if filter_fn(res) {
let plugin_attributes = this.session.plugin_attributes.borrow();
suggestions.extend(plugin_attributes.iter().map(|(name, _)| {
TypoSuggestion::from_res(*name, res)
}));
}
}
Scope::ExternPrelude => {
suggestions.extend(this.extern_prelude.iter().filter_map(|(ident, _)| {
let res = Res::Def(DefKind::Mod, DefId::local(CRATE_DEF_INDEX));
8 changes: 1 addition & 7 deletions src/librustc_resolve/lib.rs
Original file line number Diff line number Diff line change
@@ -105,7 +105,6 @@ enum Scope<'a> {
RegisteredAttrs,
MacroUsePrelude,
BuiltinAttrs,
LegacyPluginHelpers,
ExternPrelude,
ToolPrelude,
StdLibPrelude,
@@ -1466,9 +1465,6 @@ impl<'a> Resolver<'a> {
// 4b. "Standard library prelude" part implemented through `macro-use` (closed, controlled).
// 4c. Standard library prelude (de-facto closed, controlled).
// 6. Language prelude: builtin attributes (closed, controlled).
// 4-6. Legacy plugin helpers (open, not controlled). Similar to derive helpers,
// but introduced by legacy plugins using `register_attribute`. Priority is somewhere
// in prelude, not sure where exactly (creates ambiguities with any other prelude names).

let rust_2015 = ident.span.rust_2015();
let (ns, macro_kind, is_absolute_path) = match scope_set {
@@ -1498,7 +1494,6 @@ impl<'a> Resolver<'a> {
Scope::RegisteredAttrs => use_prelude,
Scope::MacroUsePrelude => use_prelude || rust_2015,
Scope::BuiltinAttrs => true,
Scope::LegacyPluginHelpers => use_prelude || rust_2015,
Scope::ExternPrelude => use_prelude || is_absolute_path,
Scope::ToolPrelude => use_prelude,
Scope::StdLibPrelude => use_prelude || ns == MacroNS,
@@ -1558,8 +1553,7 @@ impl<'a> Resolver<'a> {
}
Scope::RegisteredAttrs => Scope::MacroUsePrelude,
Scope::MacroUsePrelude => Scope::StdLibPrelude,
Scope::BuiltinAttrs => Scope::LegacyPluginHelpers,
Scope::LegacyPluginHelpers => break, // nowhere else to search
Scope::BuiltinAttrs => break, // nowhere else to search
Scope::ExternPrelude if is_absolute_path => break,
Scope::ExternPrelude => Scope::ToolPrelude,
Scope::ToolPrelude => Scope::StdLibPrelude,
7 changes: 0 additions & 7 deletions src/librustc_resolve/macros.rs
Original file line number Diff line number Diff line change
@@ -613,13 +613,6 @@ impl<'a> Resolver<'a> {
} else {
Err(Determinacy::Determined)
}
Scope::LegacyPluginHelpers => if this.session.plugin_attributes.borrow().iter()
.any(|(name, _)| ident.name == *name) {
let res = Res::NonMacroAttr(NonMacroAttrKind::LegacyPluginHelper);
ok(res, DUMMY_SP, this.arenas)
} else {
Err(Determinacy::Determined)
}
Scope::ExternPrelude => match this.extern_prelude_get(ident, !record_used) {
Some(binding) => Ok((binding, Flags::empty())),
None => Err(Determinacy::determined(
17 changes: 9 additions & 8 deletions src/librustc_save_analysis/sig.rs
Original file line number Diff line number Diff line change
@@ -30,9 +30,8 @@ use crate::{id_from_def_id, id_from_node_id, SaveContext};
use rls_data::{SigElement, Signature};

use rustc::hir::def::{Res, DefKind};
use syntax::ast::{self, NodeId};
use syntax::ast::{self, Extern, NodeId};
use syntax::print::pprust;
use syntax_pos::sym;

pub fn item_signature(item: &ast::Item, scx: &SaveContext<'_, '_>) -> Option<Signature> {
if !scx.config.signatures {
@@ -157,9 +156,11 @@ fn text_sig(text: String) -> Signature {
}
}

fn push_abi(text: &mut String, abi: ast::Abi) {
if abi.symbol != sym::Rust {
text.push_str(&format!("extern \"{}\" ", abi.symbol));
fn push_extern(text: &mut String, ext: Extern) {
match ext {
Extern::None => {}
Extern::Implicit => text.push_str("extern "),
Extern::Explicit(abi) => text.push_str(&format!("extern \"{}\" ", abi.symbol)),
}
}

@@ -237,7 +238,7 @@ impl Sig for ast::Ty {
if f.unsafety == ast::Unsafety::Unsafe {
text.push_str("unsafe ");
}
push_abi(&mut text, f.abi);
push_extern(&mut text, f.ext);
text.push_str("fn(");

let mut defs = vec![];
@@ -387,7 +388,7 @@ impl Sig for ast::Item {
if header.unsafety == ast::Unsafety::Unsafe {
text.push_str("unsafe ");
}
push_abi(&mut text, header.abi);
push_extern(&mut text, header.ext);
text.push_str("fn ");

let mut sig = name_and_generics(text, offset, generics, self.id, self.ident, scx)?;
@@ -936,7 +937,7 @@ fn make_method_signature(
if m.header.unsafety == ast::Unsafety::Unsafe {
text.push_str("unsafe ");
}
push_abi(&mut text, m.header.abi);
push_extern(&mut text, m.header.ext);
text.push_str("fn ");

let mut sig = name_and_generics(text, 0, generics, id, ident, scx)?;
2 changes: 1 addition & 1 deletion src/librustdoc/core.rs
Original file line number Diff line number Diff line change
@@ -21,7 +21,6 @@ use syntax::feature_gate::UnstableFeatures;
use errors::json::JsonEmitter;
use syntax::symbol::sym;
use syntax_pos::DUMMY_SP;
use errors;
use errors::emitter::{Emitter, EmitterWriter};

use std::cell::RefCell;
@@ -341,6 +340,7 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt
lint_caps,
register_lints: None,
override_queries: None,
registry: rustc_driver::diagnostics_registry(),
};

interface::run_compiler_in_existing_thread_pool(config, |compiler| {
3 changes: 2 additions & 1 deletion src/librustdoc/lib.rs
Original file line number Diff line number Diff line change
@@ -23,8 +23,9 @@ extern crate getopts;
extern crate env_logger;
extern crate rustc;
extern crate rustc_data_structures;
extern crate rustc_index;
extern crate rustc_driver;
extern crate rustc_error_codes;
extern crate rustc_index;
extern crate rustc_resolve;
extern crate rustc_lint;
extern crate rustc_interface;
1 change: 1 addition & 0 deletions src/librustdoc/test.rs
Original file line number Diff line number Diff line change
@@ -80,6 +80,7 @@ pub fn run(options: Options) -> i32 {
lint_caps: Default::default(),
register_lints: None,
override_queries: None,
registry: rustc_driver::diagnostics_registry(),
};

let mut test_args = options.test_args.clone();
2 changes: 1 addition & 1 deletion src/libstd/keyword_docs.rs
Original file line number Diff line number Diff line change
@@ -126,7 +126,7 @@ mod break_keyword { }
/// look like this:
///
/// ```rust
/// const WORDS: &str = "hello rust!";
/// const WORDS: &'static str = "hello rust!";
/// ```
///
/// Thanks to static lifetime elision, you usually don't have to explicitly use 'static:
48 changes: 1 addition & 47 deletions src/libstd/macros.rs
Original file line number Diff line number Diff line change
@@ -4,53 +4,7 @@
//! library. Each macro is available for use when linking against the standard
//! library.
/// Panics the current thread.
///
/// This allows a program to terminate immediately and provide feedback
/// to the caller of the program. `panic!` should be used when a program reaches
/// an unrecoverable state.
///
/// This macro is the perfect way to assert conditions in example code and in
/// tests. `panic!` is closely tied with the `unwrap` method of both [`Option`]
/// and [`Result`][runwrap] enums. Both implementations call `panic!` when they are set
/// to None or Err variants.
///
/// This macro is used to inject panic into a Rust thread, causing the thread to
/// panic entirely. Each thread's panic can be reaped as the `Box<Any>` type,
/// and the single-argument form of the `panic!` macro will be the value which
/// is transmitted.
///
/// [`Result`] enum is often a better solution for recovering from errors than
/// using the `panic!` macro. This macro should be used to avoid proceeding using
/// incorrect values, such as from external sources. Detailed information about
/// error handling is found in the [book].
///
/// The multi-argument form of this macro panics with a string and has the
/// [`format!`] syntax for building a string.
///
/// See also the macro [`compile_error!`], for raising errors during compilation.
///
/// [runwrap]: ../std/result/enum.Result.html#method.unwrap
/// [`Option`]: ../std/option/enum.Option.html#method.unwrap
/// [`Result`]: ../std/result/enum.Result.html
/// [`format!`]: ../std/macro.format.html
/// [`compile_error!`]: ../std/macro.compile_error.html
/// [book]: ../book/ch09-00-error-handling.html
///
/// # Current implementation
///
/// If the main thread panics it will terminate all your threads and end your
/// program with code `101`.
///
/// # Examples
///
/// ```should_panic
/// # #![allow(unreachable_code)]
/// panic!();
/// panic!("this is a terrible mistake!");
/// panic!(4); // panic with the value of 4 to be collected elsewhere
/// panic!("this is a {} {message}", "fancy", message = "message");
/// ```
#[doc(include = "../libcore/macros/panic.md")]
#[macro_export]
#[stable(feature = "rust1", since = "1.0.0")]
#[allow_internal_unstable(libstd_sys_internals)]
60 changes: 40 additions & 20 deletions src/libsyntax/ast.rs
Original file line number Diff line number Diff line change
@@ -1422,6 +1422,33 @@ pub struct Lit {
pub span: Span,
}

/// Same as `Lit`, but restricted to string literals.
#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug)]
pub struct StrLit {
/// The original literal token as written in source code.
pub style: StrStyle,
pub symbol: Symbol,
pub suffix: Option<Symbol>,
pub span: Span,
/// The unescaped "semantic" representation of the literal lowered from the original token.
/// FIXME: Remove this and only create the semantic representation during lowering to HIR.
pub symbol_unescaped: Symbol,
}

impl StrLit {
crate fn as_lit(&self) -> Lit {
let token_kind = match self.style {
StrStyle::Cooked => token::Str,
StrStyle::Raw(n) => token::StrRaw(n),
};
Lit {
token: token::Lit::new(token_kind, self.symbol, self.suffix),
span: self.span,
kind: LitKind::Str(self.symbol_unescaped, self.style),
}
}
}

// Clippy uses Hash and PartialEq
/// Type of the integer literal based on provided suffix.
#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug, Hash, PartialEq)]
@@ -1745,7 +1772,7 @@ pub struct Ty {
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
pub struct BareFnTy {
pub unsafety: Unsafety,
pub abi: Abi,
pub ext: Extern,
pub generic_params: Vec<GenericParam>,
pub decl: P<FnDecl>,
}
@@ -2128,7 +2155,7 @@ pub struct Mod {
/// E.g., `extern { .. }` or `extern C { .. }`.
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
pub struct ForeignMod {
pub abi: Abi,
pub abi: Option<StrLit>,
pub items: Vec<ForeignItem>,
}

@@ -2411,24 +2438,17 @@ impl Item {
}
}

/// A reference to an ABI.
///
/// In AST our notion of an ABI is still syntactic unlike in `rustc_target::spec::abi::Abi`.
#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug, PartialEq)]
pub struct Abi {
pub symbol: Symbol,
pub span: Span,
}

impl Abi {
pub fn new(symbol: Symbol, span: Span) -> Self {
Self { symbol, span }
}
/// `extern` qualifier on a function item or function type.
#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug)]
pub enum Extern {
None,
Implicit,
Explicit(StrLit),
}

impl Default for Abi {
fn default() -> Self {
Self::new(sym::Rust, DUMMY_SP)
impl Extern {
pub fn from_abi(abi: Option<StrLit>) -> Extern {
abi.map_or(Extern::Implicit, Extern::Explicit)
}
}

@@ -2441,7 +2461,7 @@ pub struct FnHeader {
pub unsafety: Unsafety,
pub asyncness: Spanned<IsAsync>,
pub constness: Spanned<Constness>,
pub abi: Abi,
pub ext: Extern,
}

impl Default for FnHeader {
@@ -2450,7 +2470,7 @@ impl Default for FnHeader {
unsafety: Unsafety::Normal,
asyncness: dummy_spanned(IsAsync::NotAsync),
constness: dummy_spanned(Constness::NotConst),
abi: Abi::default(),
ext: Extern::None,
}
}
}
5 changes: 4 additions & 1 deletion src/libsyntax/attr/builtin.rs
Original file line number Diff line number Diff line change
@@ -667,7 +667,10 @@ fn find_deprecation_generic<'a, I>(sess: &ParseSess,
break
}

let meta = attr.meta().unwrap();
let meta = match attr.meta() {
Some(meta) => meta,
None => continue,
};
depr = match &meta.kind {
MetaItemKind::Word => Some(Deprecation { since: None, note: None }),
MetaItemKind::NameValue(..) => {
22 changes: 15 additions & 7 deletions src/libsyntax/feature_gate/check.rs
Original file line number Diff line number Diff line change
@@ -191,10 +191,10 @@ macro_rules! gate_feature_post {
}

impl<'a> PostExpansionVisitor<'a> {
fn check_abi(&self, abi: ast::Abi) {
let ast::Abi { symbol, span } = abi;
fn check_abi(&self, abi: ast::StrLit) {
let ast::StrLit { symbol_unescaped, span, .. } = abi;

match &*symbol.as_str() {
match &*symbol_unescaped.as_str() {
// Stable
"Rust" |
"C" |
@@ -258,6 +258,12 @@ impl<'a> PostExpansionVisitor<'a> {
}
}

fn check_extern(&self, ext: ast::Extern) {
if let ast::Extern::Explicit(abi) = ext {
self.check_abi(abi);
}
}

fn maybe_report_invalid_custom_discriminants(&self, variants: &[ast::Variant]) {
let has_fields = variants.iter().any(|variant| match variant.data {
VariantData::Tuple(..) | VariantData::Struct(..) => true,
@@ -388,7 +394,9 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
fn visit_item(&mut self, i: &'a ast::Item) {
match i.kind {
ast::ItemKind::ForeignMod(ref foreign_module) => {
self.check_abi(foreign_module.abi);
if let Some(abi) = foreign_module.abi {
self.check_abi(abi);
}
}

ast::ItemKind::Fn(..) => {
@@ -511,7 +519,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
fn visit_ty(&mut self, ty: &'a ast::Ty) {
match ty.kind {
ast::TyKind::BareFn(ref bare_fn_ty) => {
self.check_abi(bare_fn_ty.abi);
self.check_extern(bare_fn_ty.ext);
}
ast::TyKind::Never => {
gate_feature_post!(&self, never_type, ty.span,
@@ -605,7 +613,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
// Stability of const fn methods are covered in
// `visit_trait_item` and `visit_impl_item` below; this is
// because default methods don't pass through this point.
self.check_abi(header.abi);
self.check_extern(header.ext);
}

if fn_decl.c_variadic() {
@@ -639,7 +647,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
match ti.kind {
ast::TraitItemKind::Method(ref sig, ref block) => {
if block.is_none() {
self.check_abi(sig.header.abi);
self.check_extern(sig.header.ext);
}
if sig.decl.c_variadic() {
gate_feature_post!(&self, c_variadic, ti.span,
4 changes: 2 additions & 2 deletions src/libsyntax/mut_visit.rs
Original file line number Diff line number Diff line change
@@ -441,7 +441,7 @@ pub fn noop_visit_ty<T: MutVisitor>(ty: &mut P<Ty>, vis: &mut T) {
vis.visit_mt(mt);
}
TyKind::BareFn(bft) => {
let BareFnTy { unsafety: _, abi: _, generic_params, decl } = bft.deref_mut();
let BareFnTy { unsafety: _, ext: _, generic_params, decl } = bft.deref_mut();
generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param));
vis.visit_fn_decl(decl);
}
@@ -974,7 +974,7 @@ pub fn noop_flat_map_impl_item<T: MutVisitor>(mut item: ImplItem, visitor: &mut
}

pub fn noop_visit_fn_header<T: MutVisitor>(header: &mut FnHeader, vis: &mut T) {
let FnHeader { unsafety: _, asyncness, constness: _, abi: _ } = header;
let FnHeader { unsafety: _, asyncness, constness: _, ext: _ } = header;
vis.visit_asyncness(&mut asyncness.node);
}

28 changes: 17 additions & 11 deletions src/libsyntax/print/pprust.rs
Original file line number Diff line number Diff line change
@@ -1013,7 +1013,7 @@ impl<'a> State<'a> {
self.pclose();
}
ast::TyKind::BareFn(ref f) => {
self.print_ty_fn(f.abi,
self.print_ty_fn(f.ext,
f.unsafety,
&f.decl,
None,
@@ -1232,7 +1232,10 @@ impl<'a> State<'a> {
}
ast::ItemKind::ForeignMod(ref nmod) => {
self.head("extern");
self.print_abi(nmod.abi);
if let Some(abi) = nmod.abi {
self.print_literal(&abi.as_lit());
self.nbsp();
}
self.bopen();
self.print_foreign_mod(nmod, &item.attrs);
self.bclose(item.span);
@@ -2805,7 +2808,7 @@ impl<'a> State<'a> {
}

crate fn print_ty_fn(&mut self,
abi: ast::Abi,
ext: ast::Extern,
unsafety: ast::Unsafety,
decl: &ast::FnDecl,
name: Option<ast::Ident>,
@@ -2825,7 +2828,7 @@ impl<'a> State<'a> {
span: syntax_pos::DUMMY_SP,
};
self.print_fn(decl,
ast::FnHeader { unsafety, abi, ..ast::FnHeader::default() },
ast::FnHeader { unsafety, ext, ..ast::FnHeader::default() },
name,
&generics,
&source_map::dummy_spanned(ast::VisibilityKind::Inherited));
@@ -2866,18 +2869,21 @@ impl<'a> State<'a> {
self.print_asyncness(header.asyncness.node);
self.print_unsafety(header.unsafety);

if header.abi.symbol != sym::Rust {
self.word_nbsp("extern");
self.print_abi(header.abi);
match header.ext {
ast::Extern::None => {}
ast::Extern::Implicit => {
self.word_nbsp("extern");
}
ast::Extern::Explicit(abi) => {
self.word_nbsp("extern");
self.print_literal(&abi.as_lit());
self.nbsp();
}
}

self.s.word("fn")
}

fn print_abi(&mut self, abi: ast::Abi) {
self.word_nbsp(format!("\"{}\"", abi.symbol));
}

crate fn print_unsafety(&mut self, s: ast::Unsafety) {
match s {
ast::Unsafety::Normal => {},
38 changes: 24 additions & 14 deletions src/libsyntax_ext/asm.rs
Original file line number Diff line number Diff line change
@@ -2,19 +2,17 @@
//
use State::*;

use errors::{DiagnosticBuilder, PResult};
use rustc_data_structures::thin_vec::ThinVec;

use errors::DiagnosticBuilder;

use syntax::ast;
use syntax_expand::base::{self, *};
use syntax::token::{self, Token};
use rustc_parse::parser::Parser;
use syntax_expand::base::*;
use syntax_pos::Span;
use syntax::{span_err, struct_span_err};
use syntax::ast::{self, AsmDialect};
use syntax::ptr::P;
use syntax::symbol::{kw, sym, Symbol};
use syntax::ast::AsmDialect;
use syntax_pos::Span;
use syntax::token::{self, Token};
use syntax::tokenstream::{self, TokenStream};
use syntax::{span_err, struct_span_err};

use rustc_error_codes::*;

@@ -45,7 +43,7 @@ const OPTIONS: &[Symbol] = &[sym::volatile, sym::alignstack, sym::intel];
pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt<'_>,
sp: Span,
tts: TokenStream)
-> Box<dyn base::MacResult + 'cx> {
-> Box<dyn MacResult + 'cx> {
let mut inline_asm = match parse_inline_asm(cx, sp, tts) {
Ok(Some(inline_asm)) => inline_asm,
Ok(None) => return DummyResult::any(sp),
@@ -69,6 +67,18 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt<'_>,
}))
}

fn parse_asm_str<'a>(p: &mut Parser<'a>) -> PResult<'a, Symbol> {
match p.parse_str_lit() {
Ok(str_lit) => Ok(str_lit.symbol_unescaped),
Err(opt_lit) => {
let span = opt_lit.map_or(p.token.span, |lit| lit.span);
let mut err = p.sess.span_diagnostic.struct_span_err(span, "expected string literal");
err.span_label(span, "not a string literal");
Err(err)
}
}
}

fn parse_inline_asm<'a>(
cx: &mut ExtCtxt<'a>,
sp: Span,
@@ -144,7 +154,7 @@ fn parse_inline_asm<'a>(
p.eat(&token::Comma);
}

let (constraint, _) = p.parse_str()?;
let constraint = parse_asm_str(&mut p)?;

let span = p.prev_span;

@@ -189,7 +199,7 @@ fn parse_inline_asm<'a>(
p.eat(&token::Comma);
}

let (constraint, _) = p.parse_str()?;
let constraint = parse_asm_str(&mut p)?;

if constraint.as_str().starts_with("=") {
span_err!(cx, p.prev_span, E0662,
@@ -212,7 +222,7 @@ fn parse_inline_asm<'a>(
p.eat(&token::Comma);
}

let (s, _) = p.parse_str()?;
let s = parse_asm_str(&mut p)?;

if OPTIONS.iter().any(|&opt| s == opt) {
cx.span_warn(p.prev_span, "expected a clobber, found an option");
@@ -225,7 +235,7 @@ fn parse_inline_asm<'a>(
}
}
Options => {
let (option, _) = p.parse_str()?;
let option = parse_asm_str(&mut p)?;

if option == sym::volatile {
// Indicates that the inline assembly has side effects
7 changes: 2 additions & 5 deletions src/libsyntax_ext/deriving/generic/mod.rs
Original file line number Diff line number Diff line change
@@ -182,7 +182,7 @@ use std::iter;
use std::vec;

use rustc_data_structures::thin_vec::ThinVec;
use syntax::ast::{self, Abi, BinOpKind, EnumDef, Expr, Generics, Ident, PatKind};
use syntax::ast::{self, BinOpKind, EnumDef, Expr, Generics, Ident, PatKind};
use syntax::ast::{VariantData, GenericParamKind, GenericArg};
use syntax::attr;
use syntax::source_map::respan;
@@ -737,7 +737,6 @@ impl<'a> TraitDef<'a> {
self,
type_ident,
generics,
sym::Rust,
explicit_self,
tys,
body)
@@ -792,7 +791,6 @@ impl<'a> TraitDef<'a> {
self,
type_ident,
generics,
sym::Rust,
explicit_self,
tys,
body)
@@ -918,7 +916,6 @@ impl<'a> MethodDef<'a> {
trait_: &TraitDef<'_>,
type_ident: Ident,
generics: &Generics,
abi: Symbol,
explicit_self: Option<ast::ExplicitSelf>,
arg_types: Vec<(Ident, P<ast::Ty>)>,
body: P<Expr>)
@@ -953,7 +950,7 @@ impl<'a> MethodDef<'a> {
let sig = ast::FnSig {
header: ast::FnHeader {
unsafety,
abi: Abi::new(abi, trait_lo_sp),
ext: ast::Extern::None,
..ast::FnHeader::default()
},
decl: fn_decl,
1 change: 0 additions & 1 deletion src/libsyntax_pos/symbol.rs
Original file line number Diff line number Diff line change
@@ -570,7 +570,6 @@ symbols! {
rust_2018_preview,
rust_begin_unwind,
rustc,
Rust,
RustcDecodable,
RustcEncodable,
rustc_allocator,
3 changes: 2 additions & 1 deletion src/test/run-make-fulldeps/issue-19371/foo.rs
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@

extern crate rustc;
extern crate rustc_interface;
extern crate rustc_driver as _;
extern crate rustc_driver;
extern crate syntax;

use rustc::session::DiagnosticOutput;
@@ -61,6 +61,7 @@ fn compile(code: String, output: PathBuf, sysroot: PathBuf) {
lint_caps: Default::default(),
register_lints: None,
override_queries: None,
registry: rustc_driver::diagnostics_registry(),
};

interface::run_compiler(config, |compiler| {
3 changes: 0 additions & 3 deletions src/test/ui-fulldeps/auxiliary/attr-plugin-test.rs
Original file line number Diff line number Diff line change
@@ -14,9 +14,6 @@ use syntax::symbol::Symbol;

#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
reg.register_attribute(Symbol::intern("foo"), AttributeType::Normal);
reg.register_attribute(Symbol::intern("bar"), AttributeType::CrateLevel);
reg.register_attribute(Symbol::intern("baz"), AttributeType::Whitelisted);
reg.register_syntax_extension(
Symbol::intern("mac"), SyntaxExtension::dummy_bang(reg.sess.edition())
);
15 changes: 4 additions & 11 deletions src/test/ui-fulldeps/auxiliary/issue-40001-plugin.rs
Original file line number Diff line number Diff line change
@@ -5,25 +5,17 @@
extern crate rustc;
extern crate rustc_driver;
extern crate syntax;
extern crate syntax_expand;

use rustc_driver::plugin::Registry;
use syntax::attr;
use syntax_expand::base::*;
use syntax::feature_gate::AttributeType::Whitelisted;
use syntax::symbol::Symbol;

use rustc::hir;
use rustc::hir::intravisit;
use hir::Node;
use rustc::hir::{self, intravisit, Node};
use rustc::lint::{LateContext, LintPass, LintArray, LateLintPass, LintContext};
use syntax::print::pprust;
use syntax::source_map;

#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
reg.lint_store.register_lints(&[&MISSING_WHITELISTED_ATTR]);
reg.lint_store.register_late_pass(|| box MissingWhitelistedAttrPass);
reg.register_attribute(Symbol::intern("whitelisted_attr"), Whitelisted);
}

declare_lint! {
@@ -48,7 +40,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingWhitelistedAttrPass {
_ => cx.tcx.hir().expect_item(cx.tcx.hir().get_parent_item(id)),
};

if !attr::contains_name(&item.attrs, Symbol::intern("whitelisted_attr")) {
let whitelisted = |attr| pprust::attribute_to_string(attr).contains("whitelisted_attr");
if !item.attrs.iter().any(whitelisted) {
cx.span_lint(MISSING_WHITELISTED_ATTR, span,
"Missing 'whitelisted_attr' attribute");
}
5 changes: 3 additions & 2 deletions src/test/ui-fulldeps/issue-40001.rs
Original file line number Diff line number Diff line change
@@ -2,8 +2,9 @@
// aux-build:issue-40001-plugin.rs
// ignore-stage1

#![feature(plugin)]
#![feature(plugin, register_tool)]
#![plugin(issue_40001_plugin)] //~ WARNING compiler plugins are deprecated
#![register_tool(plugin)]

#[whitelisted_attr]
#[plugin::whitelisted_attr]
fn main() {}
21 changes: 0 additions & 21 deletions src/test/ui-fulldeps/plugin-attr-register-deny.rs

This file was deleted.

34 changes: 0 additions & 34 deletions src/test/ui-fulldeps/plugin-attr-register-deny.stderr

This file was deleted.

12 changes: 12 additions & 0 deletions src/test/ui/asm/asm-literal-escaping.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// build-pass
// only-x86_64

#![feature(asm)]

fn main() {
unsafe {
// "nop" :: "r"(x) : "eax" : "volatile"
let x = 10;
asm!("\x6Eop" :: "\x72"(x) : "\x65ax" : "\x76olatile");
}
}
10 changes: 5 additions & 5 deletions src/test/ui/asm/asm-parse-errors.stderr
Original file line number Diff line number Diff line change
@@ -8,13 +8,13 @@ error: expected string literal
--> $DIR/asm-parse-errors.rs:5:18
|
LL | asm!("nop" : struct);
| ^^^^^^ expected string literal
| ^^^^^^ not a string literal

error: expected string literal
--> $DIR/asm-parse-errors.rs:6:30
|
LL | asm!("mov %eax, $$0x2" : struct);
| ^^^^^^ expected string literal
| ^^^^^^ not a string literal

error: expected `(`, found keyword `struct`
--> $DIR/asm-parse-errors.rs:7:39
@@ -32,7 +32,7 @@ error: expected string literal
--> $DIR/asm-parse-errors.rs:9:44
|
LL | asm!("in %dx, %al" : "={al}"(result) : struct);
| ^^^^^^ expected string literal
| ^^^^^^ not a string literal

error: expected `(`, found keyword `struct`
--> $DIR/asm-parse-errors.rs:10:51
@@ -50,13 +50,13 @@ error: expected string literal
--> $DIR/asm-parse-errors.rs:12:36
|
LL | asm!("mov $$0x200, %eax" : : : struct);
| ^^^^^^ expected string literal
| ^^^^^^ not a string literal

error: expected string literal
--> $DIR/asm-parse-errors.rs:13:45
|
LL | asm!("mov eax, 2" : "={eax}"(foo) : : : struct);
| ^^^^^^ expected string literal
| ^^^^^^ not a string literal

error: inline assembly must be a string literal
--> $DIR/asm-parse-errors.rs:14:10
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// The original problem in #66340 was that `find_deprecation_generic`
// called `attr.meta().unwrap()` under the assumption that the attribute
// was a well-formed `MetaItem`.

fn main() {
foo()
}

#[deprecated(note = test)]
//~^ ERROR expected unsuffixed literal or identifier, found `test`
fn foo() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
error: expected unsuffixed literal or identifier, found `test`
--> $DIR/issue-66340-deprecated-attr-non-meta-grammar.rs:9:21
|
LL | #[deprecated(note = test)]
| ^^^^

error: aborting due to previous error

10 changes: 5 additions & 5 deletions src/test/ui/lint/dead-code/lint-dead-code-4.rs
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@

struct Foo {
x: usize,
b: bool, //~ ERROR: field is never used
b: bool, //~ ERROR: field is never read
}

fn field_read(f: Foo) -> usize {
@@ -36,8 +36,8 @@ enum IJK {
I, //~ ERROR variant is never constructed
J {
a: String,
b: i32, //~ ERROR field is never used
c: i32, //~ ERROR field is never used
b: i32, //~ ERROR field is never read
c: i32, //~ ERROR field is never read
},
K //~ ERROR variant is never constructed

@@ -58,9 +58,9 @@ fn field_match_in_patterns(b: XYZ) -> String {
}

struct Bar {
x: usize, //~ ERROR: field is never used
x: usize, //~ ERROR: field is never read
b: bool,
c: bool, //~ ERROR: field is never used
c: bool, //~ ERROR: field is never read
_guard: ()
}

10 changes: 5 additions & 5 deletions src/test/ui/lint/dead-code/lint-dead-code-4.stderr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error: field is never used: `b`
error: field is never read: `b`
--> $DIR/lint-dead-code-4.rs:7:5
|
LL | b: bool,
@@ -38,13 +38,13 @@ error: variant is never constructed: `I`
LL | I,
| ^

error: field is never used: `b`
error: field is never read: `b`
--> $DIR/lint-dead-code-4.rs:39:9
|
LL | b: i32,
| ^^^^^^

error: field is never used: `c`
error: field is never read: `c`
--> $DIR/lint-dead-code-4.rs:40:9
|
LL | c: i32,
@@ -56,13 +56,13 @@ error: variant is never constructed: `K`
LL | K
| ^

error: field is never used: `x`
error: field is never read: `x`
--> $DIR/lint-dead-code-4.rs:61:5
|
LL | x: usize,
| ^^^^^^^^

error: field is never used: `c`
error: field is never read: `c`
--> $DIR/lint-dead-code-4.rs:63:5
|
LL | c: bool,
3 changes: 3 additions & 0 deletions src/test/ui/parser/issue-63116.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// fixed by #66361
// error-pattern: aborting due to 3 previous errors
impl W <s(f;Y(;]
24 changes: 24 additions & 0 deletions src/test/ui/parser/issue-63116.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
error: this file contains an un-closed delimiter
--> $DIR/issue-63116.rs:3:18
|
LL | impl W <s(f;Y(;]
| - ^
| |
| un-closed delimiter

error: expected one of `!`, `(`, `)`, `+`, `,`, `::`, or `<`, found `;`
--> $DIR/issue-63116.rs:3:12
|
LL | impl W <s(f;Y(;]
| ^ expected one of 7 possible tokens

error: expected one of `!`, `&&`, `&`, `(`, `)`, `*`, `+`, `,`, `->`, `...`, `::`, `<`, `>`, `?`, `[`, `_`, `dyn`, `extern`, `fn`, `for`, `impl`, `unsafe`, or lifetime, found `;`
--> $DIR/issue-63116.rs:3:15
|
LL | impl W <s(f;Y(;]
| -^ help: `)` may belong here
| |
| unclosed delimiter

error: aborting due to 3 previous errors

20 changes: 13 additions & 7 deletions src/test/ui/proc-macro/span-preservation.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
//~ ERROR mismatched types
// aux-build:test-macros.rs

// For each of these, we should get the appropriate type mismatch error message,
// and the function should be echoed.

// aux-build:test-macros.rs

#[macro_use]
extern crate test_macros;

@@ -35,17 +34,24 @@ fn c() {
let y = Foo { a: 10, b: 10isize }; //~ ERROR has no field named `b`
}

// FIXME: This doesn't work at the moment. See the one below. The pretty-printer
// injects a "C" between `extern` and `fn` which causes a "probably_eq"
// `TokenStream` mismatch. The lack of `"C"` should be preserved in the AST.
#[recollect_attr]
extern fn bar() {
0
0 //~ ERROR mismatched types
}

#[recollect_attr]
extern "C" fn baz() {
0 //~ ERROR mismatched types
}

#[recollect_attr]
extern "Rust" fn rust_abi() {
0 //~ ERROR mismatched types
}

#[recollect_attr]
extern "\x43" fn c_abi_escaped() {
0 //~ ERROR mismatched types
}

fn main() {}
50 changes: 39 additions & 11 deletions src/test/ui/proc-macro/span-preservation.stderr
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
error[E0308]: mismatched types
|
= note: expected type `()`
found type `{integer}`

error[E0308]: mismatched types
--> $DIR/span-preservation.rs:12:20
--> $DIR/span-preservation.rs:11:20
|
LL | let x: usize = "hello";
| ^^^^^^^ expected usize, found reference
@@ -13,7 +8,7 @@ LL | let x: usize = "hello";
found type `&'static str`

error[E0308]: mismatched types
--> $DIR/span-preservation.rs:18:29
--> $DIR/span-preservation.rs:17:29
|
LL | fn b(x: Option<isize>) -> usize {
| ----- expected `usize` because of return type
@@ -22,21 +17,32 @@ LL | Some(x) => { return x },
| ^ expected usize, found isize

error[E0308]: mismatched types
--> $DIR/span-preservation.rs:34:22
--> $DIR/span-preservation.rs:33:22
|
LL | let x = Foo { a: 10isize };
| ^^^^^^^ expected usize, found isize

error[E0560]: struct `c::Foo` has no field named `b`
--> $DIR/span-preservation.rs:35:26
--> $DIR/span-preservation.rs:34:26
|
LL | let y = Foo { a: 10, b: 10isize };
| ^ `c::Foo` does not have this field
|
= note: available fields are: `a`

error[E0308]: mismatched types
--> $DIR/span-preservation.rs:48:5
--> $DIR/span-preservation.rs:39:5
|
LL | extern fn bar() {
| - possibly return type missing here?
LL | 0
| ^ expected (), found integer
|
= note: expected type `()`
found type `{integer}`

error[E0308]: mismatched types
--> $DIR/span-preservation.rs:44:5
|
LL | extern "C" fn baz() {
| - possibly return type missing here?
@@ -46,7 +52,29 @@ LL | 0
= note: expected type `()`
found type `{integer}`

error: aborting due to 6 previous errors
error[E0308]: mismatched types
--> $DIR/span-preservation.rs:49:5
|
LL | extern "Rust" fn rust_abi() {
| - possibly return type missing here?
LL | 0
| ^ expected (), found integer
|
= note: expected type `()`
found type `{integer}`

error[E0308]: mismatched types
--> $DIR/span-preservation.rs:54:5
|
LL | extern "\x43" fn c_abi_escaped() {
| - possibly return type missing here?
LL | 0
| ^ expected (), found integer
|
= note: expected type `()`
found type `{integer}`

error: aborting due to 8 previous errors

Some errors have detailed explanations: E0308, E0560.
For more information about an error, try `rustc --explain E0308`.
8 changes: 4 additions & 4 deletions src/test/ui/union/union-fields-1.rs
Original file line number Diff line number Diff line change
@@ -3,19 +3,19 @@
union U1 {
a: u8, // should not be reported
b: u8, // should not be reported
c: u8, //~ ERROR field is never used
c: u8, //~ ERROR field is never read
}
union U2 {
a: u8, //~ ERROR field is never used
a: u8, //~ ERROR field is never read
b: u8, // should not be reported
c: u8, // should not be reported
}
union NoDropLike { a: u8 } //~ ERROR field is never used
union NoDropLike { a: u8 } //~ ERROR field is never read

union U {
a: u8, // should not be reported
b: u8, // should not be reported
c: u8, //~ ERROR field is never used
c: u8, //~ ERROR field is never read
}
type A = U;

8 changes: 4 additions & 4 deletions src/test/ui/union/union-fields-1.stderr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error: field is never used: `c`
error: field is never read: `c`
--> $DIR/union-fields-1.rs:6:5
|
LL | c: u8,
@@ -10,19 +10,19 @@ note: lint level defined here
LL | #![deny(dead_code)]
| ^^^^^^^^^

error: field is never used: `a`
error: field is never read: `a`
--> $DIR/union-fields-1.rs:9:5
|
LL | a: u8,
| ^^^^^

error: field is never used: `a`
error: field is never read: `a`
--> $DIR/union-fields-1.rs:13:20
|
LL | union NoDropLike { a: u8 }
| ^^^^^

error: field is never used: `c`
error: field is never read: `c`
--> $DIR/union-fields-1.rs:18:5
|
LL | c: u8,
2 changes: 1 addition & 1 deletion src/test/ui/union/union-lint-dead-code.rs
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@

union Foo {
x: usize,
b: bool, //~ ERROR: field is never used
b: bool, //~ ERROR: field is never read
_unused: u16,
}

2 changes: 1 addition & 1 deletion src/test/ui/union/union-lint-dead-code.stderr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error: field is never used: `b`
error: field is never read: `b`
--> $DIR/union-lint-dead-code.rs:5:5
|
LL | b: bool,