Auto merge of #66485 - JohnTitor:rollup-vbwhg6r, r=JohnTitor
Rollup of 11 pull requests Successful merges: - #65739 (Improve documentation of `Vec::split_off(...)`) - #66271 (syntax: Keep string literals in ABIs and `asm!` more precisely) - #66344 (rustc_plugin: Remove `Registry::register_attribute`) - #66381 (find_deprecation: deprecation attr may be ill-formed meta.) - #66395 (Centralize panic macro documentation) - #66456 (Move `DIAGNOSTICS` usage to `rustc_driver`) - #66465 (add missing 'static lifetime in docs) - #66466 (miri panic_unwind: fix hack for SEH platforms) - #66469 (Use "field is never read" instead of "field is never used") - #66471 (Add test for issue 63116) - #66477 (Clarify transmute_copy documentation example) Failed merges: r? @ghost
This commit is contained in:
commit
8831d766ac
@ -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",
|
||||
|
@ -1333,10 +1333,9 @@ pub fn is_empty(&self) -> bool {
|
||||
|
||||
/// 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
|
||||
///
|
||||
|
@ -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
src/libcore/macros/panic.md
Normal file
47
src/libcore/macros/panic.md
Normal file
@ -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");
|
||||
```
|
@ -744,11 +744,11 @@ 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
|
||||
@ -756,8 +756,8 @@ pub fn drop<T>(_x: T) { }
|
||||
/// 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")]
|
||||
|
@ -39,11 +39,6 @@
|
||||
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;
|
||||
|
@ -1,3 +1,5 @@
|
||||
#![allow(nonstandard_style)]
|
||||
|
||||
use core::any::Any;
|
||||
use alloc::boxed::Box;
|
||||
|
||||
@ -13,7 +15,6 @@ 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"]
|
||||
@ -21,3 +22,21 @@ pub unsafe fn cleanup(ptr: *mut u8) -> Box<dyn Any + Send> {
|
||||
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,
|
||||
};
|
||||
|
@ -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 @@ pub fn descr(self) -> &'static str {
|
||||
NonMacroAttrKind::Tool => "tool attribute",
|
||||
NonMacroAttrKind::DeriveHelper => "derive helper attribute",
|
||||
NonMacroAttrKind::Registered => "explicitly registered attribute",
|
||||
NonMacroAttrKind::LegacyPluginHelper => "legacy plugin helper attribute",
|
||||
}
|
||||
}
|
||||
|
||||
@ -345,8 +342,7 @@ pub fn article(self) -> &'static str {
|
||||
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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1219,7 +1219,7 @@ fn lower_ty_direct(&mut self, t: &Ty, mut itctx: ImplTraitContext<'_>) -> hir::T
|
||||
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),
|
||||
}))
|
||||
|
@ -735,7 +735,7 @@ fn lower_foreign_item(&mut self, i: &ForeignItem) -> hir::ForeignItem {
|
||||
|
||||
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 @@ fn lower_fn_header(&mut self, h: FnHeader) -> hir::FnHeader {
|
||||
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,
|
||||
|
@ -21,11 +21,10 @@
|
||||
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(),
|
||||
|
@ -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" }
|
||||
|
@ -40,7 +40,7 @@
|
||||
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 @@ fn config(&mut self, config: &mut interface::Config) {
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
|
@ -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"),
|
||||
|
@ -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: () = ();
|
||||
|
@ -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"
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
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,12 +142,16 @@ 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,
|
||||
@ -154,6 +159,7 @@ pub fn run_compiler_in_existing_thread_pool<F, R>(config: Config, f: F) -> R
|
||||
config.file_loader,
|
||||
config.input_path.clone(),
|
||||
config.lint_caps,
|
||||
registry.clone(),
|
||||
);
|
||||
|
||||
let compiler = Compiler {
|
||||
@ -171,17 +177,13 @@ pub fn run_compiler_in_existing_thread_pool<F, R>(config: Config, f: F) -> R
|
||||
};
|
||||
|
||||
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 @@ pub fn run_compiler<F, R>(mut config: Config, f: F) -> R
|
||||
)
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -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)))
|
||||
}
|
||||
|
@ -15,7 +15,6 @@
|
||||
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 @@
|
||||
#[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,
|
||||
|
@ -309,29 +309,11 @@ fn check_attribute(&mut self, cx: &LateContext<'_, '_>, attr: &ast::Attribute) {
|
||||
}
|
||||
}
|
||||
|
||||
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 \
|
||||
|
@ -778,13 +778,12 @@ fn parse_bottom_expr(&mut self) -> PResult<'a, P<Expr>> {
|
||||
|
||||
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 @@ macro_rules! parse_lit {
|
||||
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 @@ pub(super) fn parse_lit(&mut self) -> PResult<'a, Lit> {
|
||||
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 @@ pub(super) fn parse_lit(&mut self) -> PResult<'a, Lit> {
|
||||
_ => 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
|
||||
|
@ -3,9 +3,9 @@
|
||||
|
||||
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 @@ fn parse_item_implementation(
|
||||
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 @@ fn parse_item_implementation(
|
||||
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 @@ fn parse_item_implementation(
|
||||
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 @@ fn parse_item_implementation(
|
||||
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 @@ fn parse_item_implementation(
|
||||
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 @@ fn parse_item_implementation(
|
||||
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 @@ fn parse_crate_name_with_dashes(&mut self) -> PResult<'a, ast::Ident> {
|
||||
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 @@ fn parse_item_fn(
|
||||
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,11 +1912,11 @@ fn parse_fn_front_matter(&mut self) -> PResult<'a, FnHeader> {
|
||||
}
|
||||
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
|
||||
@ -1917,7 +1924,7 @@ fn parse_fn_front_matter(&mut self) -> PResult<'a, FnHeader> {
|
||||
// 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.
|
||||
|
@ -15,8 +15,8 @@
|
||||
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 @@ fn recover_incorrect_vis_restriction(&mut self) -> PResult<'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 @@ fn is_import_coupler(&mut self) -> bool {
|
||||
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(
|
||||
|
@ -287,7 +287,7 @@ fn parse_ty_bare_fn(&mut self, generic_params: Vec<GenericParam>) -> PResult<'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 @@ fn parse_ty_bare_fn(&mut self, generic_params: Vec<GenericParam>) -> PResult<'a,
|
||||
};
|
||||
let decl = self.parse_fn_decl(cfg, false)?;
|
||||
Ok(TyKind::BareFn(P(BareFnTy {
|
||||
abi,
|
||||
ext,
|
||||
unsafety,
|
||||
generic_params,
|
||||
decl,
|
||||
|
@ -631,7 +631,7 @@ fn visit_foreign_item(&mut self, fi: &'tcx hir::ForeignItem) {
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -7,7 +7,6 @@
|
||||
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 @@ pub fn new(sess: &'a Session, lint_store: &'a mut LintStore, krate_span: Span) -
|
||||
krate_span,
|
||||
syntax_exts: vec![],
|
||||
llvm_passes: vec![],
|
||||
attributes: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
@ -98,12 +93,4 @@ pub fn register_macro(&mut self, name: &str, expander: MacroExpanderFn) {
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
@ -437,15 +437,6 @@ fn early_lookup_typo_candidate(
|
||||
}));
|
||||
}
|
||||
}
|
||||
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));
|
||||
|
@ -105,7 +105,6 @@ enum Scope<'a> {
|
||||
RegisteredAttrs,
|
||||
MacroUsePrelude,
|
||||
BuiltinAttrs,
|
||||
LegacyPluginHelpers,
|
||||
ExternPrelude,
|
||||
ToolPrelude,
|
||||
StdLibPrelude,
|
||||
@ -1466,9 +1465,6 @@ fn visit_scopes<T>(
|
||||
// 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 @@ fn visit_scopes<T>(
|
||||
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 @@ fn visit_scopes<T>(
|
||||
}
|
||||
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,
|
||||
|
@ -613,13 +613,6 @@ struct Flags: u8 {
|
||||
} 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(
|
||||
|
@ -30,9 +30,8 @@
|
||||
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 @@ fn make(&self, offset: usize, _parent_id: Option<NodeId>, scx: &SaveContext<'_,
|
||||
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 @@ fn make(&self, offset: usize, _parent_id: Option<NodeId>, scx: &SaveContext<'_,
|
||||
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)?;
|
||||
|
@ -21,7 +21,6 @@
|
||||
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| {
|
||||
|
@ -23,8 +23,9 @@
|
||||
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;
|
||||
|
@ -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();
|
||||
|
@ -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:
|
||||
|
@ -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)]
|
||||
|
@ -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 @@ pub fn span_with_attributes(&self) -> Span {
|
||||
}
|
||||
}
|
||||
|
||||
/// 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,
|
||||
/// `extern` qualifier on a function item or function type.
|
||||
#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug)]
|
||||
pub enum Extern {
|
||||
None,
|
||||
Implicit,
|
||||
Explicit(StrLit),
|
||||
}
|
||||
|
||||
impl Abi {
|
||||
pub fn new(symbol: Symbol, span: Span) -> Self {
|
||||
Self { symbol, span }
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ fn default() -> FnHeader {
|
||||
unsafety: Unsafety::Normal,
|
||||
asyncness: dummy_spanned(IsAsync::NotAsync),
|
||||
constness: dummy_spanned(Constness::NotConst),
|
||||
abi: Abi::default(),
|
||||
ext: Extern::None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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(..) => {
|
||||
|
@ -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 @@ fn check_abi(&self, abi: ast::Abi) {
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ fn visit_name(&mut self, sp: Span, name: ast::Name) {
|
||||
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 @@ fn visit_foreign_item(&mut self, i: &'a ast::ForeignItem) {
|
||||
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 @@ fn visit_fn(&mut self,
|
||||
// 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 @@ fn visit_trait_item(&mut self, ti: &'a ast::TraitItem) {
|
||||
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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -1013,7 +1013,7 @@ pub fn print_type(&mut self, ty: &ast::Ty) {
|
||||
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 @@ fn print_associated_type(&mut self,
|
||||
}
|
||||
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 @@ pub fn print_mutability(&mut self, mutbl: ast::Mutability) {
|
||||
}
|
||||
|
||||
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 @@ pub fn print_mutability(&mut self, mutbl: ast::Mutability) {
|
||||
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 @@ pub fn print_mutability(&mut self, mutbl: ast::Mutability) {
|
||||
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 => {},
|
||||
|
@ -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 @@ fn next(&self) -> State {
|
||||
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
|
||||
|
@ -182,7 +182,7 @@
|
||||
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 @@ fn expand_struct_def(&self,
|
||||
self,
|
||||
type_ident,
|
||||
generics,
|
||||
sym::Rust,
|
||||
explicit_self,
|
||||
tys,
|
||||
body)
|
||||
@ -792,7 +791,6 @@ fn expand_enum_def(&self,
|
||||
self,
|
||||
type_ident,
|
||||
generics,
|
||||
sym::Rust,
|
||||
explicit_self,
|
||||
tys,
|
||||
body)
|
||||
@ -918,7 +916,6 @@ fn create_method(&self,
|
||||
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 @@ fn create_method(&self,
|
||||
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,
|
||||
|
@ -570,7 +570,6 @@
|
||||
rust_2018_preview,
|
||||
rust_begin_unwind,
|
||||
rustc,
|
||||
Rust,
|
||||
RustcDecodable,
|
||||
RustcEncodable,
|
||||
rustc_allocator,
|
||||
|
@ -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| {
|
||||
|
@ -14,9 +14,6 @@
|
||||
|
||||
#[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())
|
||||
);
|
||||
|
@ -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 @@ fn check_fn(&mut self,
|
||||
_ => 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");
|
||||
}
|
||||
|
@ -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() {}
|
||||
|
@ -1,21 +0,0 @@
|
||||
// aux-build:attr-plugin-test.rs
|
||||
// ignore-stage1
|
||||
|
||||
#![feature(plugin)]
|
||||
#![plugin(attr_plugin_test)]
|
||||
//~^ WARN use of deprecated attribute `plugin`
|
||||
#![deny(unused_attributes)]
|
||||
|
||||
#[baz]
|
||||
fn baz() { } // no error
|
||||
|
||||
#[foo]
|
||||
pub fn main() {
|
||||
//~^^ ERROR unused
|
||||
#[bar]
|
||||
fn inner() {}
|
||||
//~^^ ERROR crate
|
||||
//~^^^ ERROR unused
|
||||
baz();
|
||||
inner();
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
|
||||
--> $DIR/plugin-attr-register-deny.rs:5:1
|
||||
|
|
||||
LL | #![plugin(attr_plugin_test)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
|
||||
|
|
||||
= note: `#[warn(deprecated)]` on by default
|
||||
|
||||
error: unused attribute
|
||||
--> $DIR/plugin-attr-register-deny.rs:15:5
|
||||
|
|
||||
LL | #[bar]
|
||||
| ^^^^^^
|
||||
|
|
||||
note: lint level defined here
|
||||
--> $DIR/plugin-attr-register-deny.rs:7:9
|
||||
|
|
||||
LL | #![deny(unused_attributes)]
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
|
||||
--> $DIR/plugin-attr-register-deny.rs:15:5
|
||||
|
|
||||
LL | #[bar]
|
||||
| ^^^^^^
|
||||
|
||||
error: unused attribute
|
||||
--> $DIR/plugin-attr-register-deny.rs:12:1
|
||||
|
|
||||
LL | #[foo]
|
||||
| ^^^^^^
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
12
src/test/ui/asm/asm-literal-escaping.rs
Normal file
12
src/test/ui/asm/asm-literal-escaping.rs
Normal file
@ -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");
|
||||
}
|
||||
}
|
@ -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
|
||||
|
@ -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() {}
|
@ -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
|
||||
|
@ -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: ()
|
||||
}
|
||||
|
||||
|
@ -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
src/test/ui/parser/issue-63116.rs
Normal file
3
src/test/ui/parser/issue-63116.rs
Normal file
@ -0,0 +1,3 @@
|
||||
// fixed by #66361
|
||||
// error-pattern: aborting due to 3 previous errors
|
||||
impl W <s(f;Y(;]
|
24
src/test/ui/parser/issue-63116.stderr
Normal file
24
src/test/ui/parser/issue-63116.stderr
Normal file
@ -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
|
||||
|
@ -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,12 +34,9 @@ struct Bar {
|
||||
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]
|
||||
@ -48,4 +44,14 @@ 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() {}
|
||||
|
@ -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,13 +17,13 @@ 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
|
||||
@ -36,7 +31,18 @@ LL | let y = Foo { a: 10, b: 10isize };
|
||||
= 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`.
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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,7 +2,7 @@
|
||||
|
||||
union Foo {
|
||||
x: usize,
|
||||
b: bool, //~ ERROR: field is never used
|
||||
b: bool, //~ ERROR: field is never read
|
||||
_unused: u16,
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user