Auto merge of #68115 - Centril:rollup-e2fszdv, r=Centril
Rollup of 8 pull requests Successful merges: - #67666 (make use of pointer::is_null) - #67806 (Extract `rustc_ast_passes`, move gating, & refactor linting) - #68043 (Add some missing timers) - #68074 (Add `llvm-skip-rebuild` flag to `x.py`) - #68079 (Clarify suggestion for E0013) - #68084 (Do not ICE on unicode next point) - #68102 (Inline some conversion methods around OsStr) - #68106 (Fix issue with using `self` module via indirection) Failed merges: r? @ghost
This commit is contained in:
commit
88d1109600
24
Cargo.lock
24
Cargo.lock
@ -3363,6 +3363,21 @@ dependencies = [
|
||||
"syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc_ast_passes"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"log",
|
||||
"rustc_data_structures",
|
||||
"rustc_error_codes",
|
||||
"rustc_errors",
|
||||
"rustc_feature",
|
||||
"rustc_parse",
|
||||
"rustc_session",
|
||||
"rustc_span",
|
||||
"syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc_builtin_macros"
|
||||
version = "0.0.0"
|
||||
@ -3375,6 +3390,7 @@ dependencies = [
|
||||
"rustc_expand",
|
||||
"rustc_feature",
|
||||
"rustc_parse",
|
||||
"rustc_session",
|
||||
"rustc_span",
|
||||
"rustc_target",
|
||||
"smallvec 1.0.0",
|
||||
@ -3528,11 +3544,13 @@ name = "rustc_expand"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"log",
|
||||
"rustc_ast_passes",
|
||||
"rustc_data_structures",
|
||||
"rustc_errors",
|
||||
"rustc_feature",
|
||||
"rustc_lexer",
|
||||
"rustc_parse",
|
||||
"rustc_session",
|
||||
"rustc_span",
|
||||
"serialize",
|
||||
"smallvec 1.0.0",
|
||||
@ -3602,6 +3620,7 @@ dependencies = [
|
||||
"rustc",
|
||||
"rustc-rayon",
|
||||
"rustc_ast_lowering",
|
||||
"rustc_ast_passes",
|
||||
"rustc_builtin_macros",
|
||||
"rustc_codegen_llvm",
|
||||
"rustc_codegen_ssa",
|
||||
@ -3619,6 +3638,7 @@ dependencies = [
|
||||
"rustc_plugin_impl",
|
||||
"rustc_privacy",
|
||||
"rustc_resolve",
|
||||
"rustc_session",
|
||||
"rustc_span",
|
||||
"rustc_target",
|
||||
"rustc_traits",
|
||||
@ -3735,6 +3755,7 @@ dependencies = [
|
||||
"rustc_errors",
|
||||
"rustc_feature",
|
||||
"rustc_lexer",
|
||||
"rustc_session",
|
||||
"rustc_span",
|
||||
"smallvec 1.0.0",
|
||||
"syntax",
|
||||
@ -3753,7 +3774,7 @@ dependencies = [
|
||||
"rustc_feature",
|
||||
"rustc_hir",
|
||||
"rustc_index",
|
||||
"rustc_parse",
|
||||
"rustc_session",
|
||||
"rustc_span",
|
||||
"rustc_target",
|
||||
"syntax",
|
||||
@ -3833,6 +3854,7 @@ dependencies = [
|
||||
"log",
|
||||
"num_cpus",
|
||||
"rustc_data_structures",
|
||||
"rustc_error_codes",
|
||||
"rustc_errors",
|
||||
"rustc_feature",
|
||||
"rustc_fs_util",
|
||||
|
@ -493,9 +493,13 @@ impl Config {
|
||||
config.mandir = install.mandir.clone().map(PathBuf::from);
|
||||
}
|
||||
|
||||
// We want the llvm-skip-rebuild flag to take precedence over the
|
||||
// skip-rebuild config.toml option so we store it separately
|
||||
// so that we can infer the right value
|
||||
let mut llvm_skip_rebuild = flags.llvm_skip_rebuild;
|
||||
|
||||
// Store off these values as options because if they're not provided
|
||||
// we'll infer default values for them later
|
||||
let mut llvm_skip_rebuild = None;
|
||||
let mut llvm_assertions = None;
|
||||
let mut debug = None;
|
||||
let mut debug_assertions = None;
|
||||
@ -517,7 +521,7 @@ impl Config {
|
||||
}
|
||||
set(&mut config.ninja, llvm.ninja);
|
||||
llvm_assertions = llvm.assertions;
|
||||
llvm_skip_rebuild = llvm.skip_rebuild;
|
||||
llvm_skip_rebuild = llvm_skip_rebuild.or(llvm.skip_rebuild);
|
||||
set(&mut config.llvm_optimize, llvm.optimize);
|
||||
set(&mut config.llvm_thin_lto, llvm.thin_lto);
|
||||
set(&mut config.llvm_release_debuginfo, llvm.release_debuginfo);
|
||||
|
@ -38,6 +38,8 @@ pub struct Flags {
|
||||
//
|
||||
// true => deny, false => warn
|
||||
pub deny_warnings: Option<bool>,
|
||||
|
||||
pub llvm_skip_rebuild: Option<bool>,
|
||||
}
|
||||
|
||||
pub enum Subcommand {
|
||||
@ -150,6 +152,14 @@ To learn more about a subcommand, run `./x.py <subcommand> -h`",
|
||||
"VALUE",
|
||||
);
|
||||
opts.optopt("", "error-format", "rustc error format", "FORMAT");
|
||||
opts.optopt(
|
||||
"",
|
||||
"llvm-skip-rebuild",
|
||||
"whether rebuilding llvm should be skipped \
|
||||
a VALUE of TRUE indicates that llvm will not be rebuilt \
|
||||
VALUE overrides the skip-rebuild option in config.toml.",
|
||||
"VALUE",
|
||||
);
|
||||
|
||||
// fn usage()
|
||||
let usage =
|
||||
@ -487,6 +497,9 @@ Arguments:
|
||||
.map(|p| p.into())
|
||||
.collect::<Vec<_>>(),
|
||||
deny_warnings: parse_deny_warnings(&matches),
|
||||
llvm_skip_rebuild: matches.opt_str("llvm-skip-rebuild").map(|s| s.to_lowercase()).map(
|
||||
|s| s.parse::<bool>().expect("`llvm-skip-rebuild` should be either true or false"),
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -63,7 +63,7 @@ pub unsafe fn cleanup(ptr: *mut u8) -> Box<dyn Any + Send> {
|
||||
pub unsafe fn panic(data: Box<dyn Any + Send>) -> u32 {
|
||||
let sz = mem::size_of_val(&data);
|
||||
let exception = __cxa_allocate_exception(sz);
|
||||
if exception == ptr::null_mut() {
|
||||
if exception.is_null() {
|
||||
return uw::_URC_FATAL_PHASE1_ERROR as u32;
|
||||
}
|
||||
ptr::write(exception as *mut _, data);
|
||||
|
@ -17,20 +17,21 @@
|
||||
use self::TargetLint::*;
|
||||
|
||||
use crate::hir::map::{definitions::DisambiguatedDefPathData, DefPathData};
|
||||
use crate::lint::builtin::BuiltinLintDiagnostics;
|
||||
use crate::lint::levels::{LintLevelSets, LintLevelsBuilder};
|
||||
use crate::lint::{EarlyLintPassObject, LateLintPassObject};
|
||||
use crate::lint::{FutureIncompatibleInfo, Level, Lint, LintBuffer, LintId};
|
||||
use crate::middle::privacy::AccessLevels;
|
||||
use crate::middle::stability;
|
||||
use crate::session::Session;
|
||||
use crate::ty::layout::{LayoutError, LayoutOf, TyLayout};
|
||||
use crate::ty::{self, print::Printer, subst::GenericArg, Ty, TyCtxt};
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_data_structures::sync;
|
||||
use rustc_error_codes::*;
|
||||
use rustc_errors::{struct_span_err, DiagnosticBuilder};
|
||||
use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::{CrateNum, DefId};
|
||||
use rustc_session::lint::BuiltinLintDiagnostics;
|
||||
use rustc_session::lint::{FutureIncompatibleInfo, Level, Lint, LintBuffer, LintId};
|
||||
use rustc_span::{symbol::Symbol, MultiSpan, Span, DUMMY_SP};
|
||||
use syntax::ast;
|
||||
use syntax::util::lev_distance::find_best_match_for_name;
|
||||
@ -64,17 +65,6 @@ pub struct LintStore {
|
||||
lint_groups: FxHashMap<&'static str, LintGroup>,
|
||||
}
|
||||
|
||||
/// Lints that are buffered up early on in the `Session` before the
|
||||
/// `LintLevels` is calculated
|
||||
#[derive(PartialEq, Debug)]
|
||||
pub struct BufferedEarlyLint {
|
||||
pub lint_id: LintId,
|
||||
pub ast_id: ast::NodeId,
|
||||
pub span: MultiSpan,
|
||||
pub msg: String,
|
||||
pub diagnostic: BuiltinLintDiagnostics,
|
||||
}
|
||||
|
||||
/// The target of the `by_name` map, which accounts for renaming/deprecation.
|
||||
enum TargetLint {
|
||||
/// A direct lint target
|
||||
@ -477,6 +467,48 @@ impl LintPassObject for EarlyLintPassObject {}
|
||||
|
||||
impl LintPassObject for LateLintPassObject {}
|
||||
|
||||
pub fn add_elided_lifetime_in_path_suggestion(
|
||||
sess: &Session,
|
||||
db: &mut DiagnosticBuilder<'_>,
|
||||
n: usize,
|
||||
path_span: Span,
|
||||
incl_angl_brckt: bool,
|
||||
insertion_span: Span,
|
||||
anon_lts: String,
|
||||
) {
|
||||
let (replace_span, suggestion) = if incl_angl_brckt {
|
||||
(insertion_span, anon_lts)
|
||||
} else {
|
||||
// When possible, prefer a suggestion that replaces the whole
|
||||
// `Path<T>` expression with `Path<'_, T>`, rather than inserting `'_, `
|
||||
// at a point (which makes for an ugly/confusing label)
|
||||
if let Ok(snippet) = sess.source_map().span_to_snippet(path_span) {
|
||||
// But our spans can get out of whack due to macros; if the place we think
|
||||
// we want to insert `'_` isn't even within the path expression's span, we
|
||||
// should bail out of making any suggestion rather than panicking on a
|
||||
// subtract-with-overflow or string-slice-out-out-bounds (!)
|
||||
// FIXME: can we do better?
|
||||
if insertion_span.lo().0 < path_span.lo().0 {
|
||||
return;
|
||||
}
|
||||
let insertion_index = (insertion_span.lo().0 - path_span.lo().0) as usize;
|
||||
if insertion_index > snippet.len() {
|
||||
return;
|
||||
}
|
||||
let (before, after) = snippet.split_at(insertion_index);
|
||||
(path_span, format!("{}{}{}", before, anon_lts, after))
|
||||
} else {
|
||||
(insertion_span, anon_lts)
|
||||
}
|
||||
};
|
||||
db.span_suggestion(
|
||||
replace_span,
|
||||
&format!("indicate the anonymous lifetime{}", pluralize!(n)),
|
||||
suggestion,
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
}
|
||||
|
||||
pub trait LintContext: Sized {
|
||||
type PassObject: LintPassObject;
|
||||
|
||||
@ -495,7 +527,85 @@ pub trait LintContext: Sized {
|
||||
diagnostic: BuiltinLintDiagnostics,
|
||||
) {
|
||||
let mut db = self.lookup(lint, span, msg);
|
||||
diagnostic.run(self.sess(), &mut db);
|
||||
|
||||
let sess = self.sess();
|
||||
match diagnostic {
|
||||
BuiltinLintDiagnostics::Normal => (),
|
||||
BuiltinLintDiagnostics::BareTraitObject(span, is_global) => {
|
||||
let (sugg, app) = match sess.source_map().span_to_snippet(span) {
|
||||
Ok(s) if is_global => {
|
||||
(format!("dyn ({})", s), Applicability::MachineApplicable)
|
||||
}
|
||||
Ok(s) => (format!("dyn {}", s), Applicability::MachineApplicable),
|
||||
Err(_) => ("dyn <type>".to_string(), Applicability::HasPlaceholders),
|
||||
};
|
||||
db.span_suggestion(span, "use `dyn`", sugg, app);
|
||||
}
|
||||
BuiltinLintDiagnostics::AbsPathWithModule(span) => {
|
||||
let (sugg, app) = match sess.source_map().span_to_snippet(span) {
|
||||
Ok(ref s) => {
|
||||
// FIXME(Manishearth) ideally the emitting code
|
||||
// can tell us whether or not this is global
|
||||
let opt_colon = if s.trim_start().starts_with("::") { "" } else { "::" };
|
||||
|
||||
(format!("crate{}{}", opt_colon, s), Applicability::MachineApplicable)
|
||||
}
|
||||
Err(_) => ("crate::<path>".to_string(), Applicability::HasPlaceholders),
|
||||
};
|
||||
db.span_suggestion(span, "use `crate`", sugg, app);
|
||||
}
|
||||
BuiltinLintDiagnostics::ProcMacroDeriveResolutionFallback(span) => {
|
||||
db.span_label(
|
||||
span,
|
||||
"names from parent modules are not accessible without an explicit import",
|
||||
);
|
||||
}
|
||||
BuiltinLintDiagnostics::MacroExpandedMacroExportsAccessedByAbsolutePaths(span_def) => {
|
||||
db.span_note(span_def, "the macro is defined here");
|
||||
}
|
||||
BuiltinLintDiagnostics::ElidedLifetimesInPaths(
|
||||
n,
|
||||
path_span,
|
||||
incl_angl_brckt,
|
||||
insertion_span,
|
||||
anon_lts,
|
||||
) => {
|
||||
add_elided_lifetime_in_path_suggestion(
|
||||
sess,
|
||||
&mut db,
|
||||
n,
|
||||
path_span,
|
||||
incl_angl_brckt,
|
||||
insertion_span,
|
||||
anon_lts,
|
||||
);
|
||||
}
|
||||
BuiltinLintDiagnostics::UnknownCrateTypes(span, note, sugg) => {
|
||||
db.span_suggestion(span, ¬e, sugg, Applicability::MaybeIncorrect);
|
||||
}
|
||||
BuiltinLintDiagnostics::UnusedImports(message, replaces) => {
|
||||
if !replaces.is_empty() {
|
||||
db.tool_only_multipart_suggestion(
|
||||
&message,
|
||||
replaces,
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
}
|
||||
}
|
||||
BuiltinLintDiagnostics::RedundantImport(spans, ident) => {
|
||||
for (span, is_imported) in spans {
|
||||
let introduced = if is_imported { "imported" } else { "defined" };
|
||||
db.span_label(
|
||||
span,
|
||||
format!("the item `{}` is already {} here", ident, introduced),
|
||||
);
|
||||
}
|
||||
}
|
||||
BuiltinLintDiagnostics::DeprecatedMacro(suggestion, span) => {
|
||||
stability::deprecation_suggestion(&mut db, suggestion, span)
|
||||
}
|
||||
}
|
||||
|
||||
db.emit();
|
||||
}
|
||||
|
||||
|
@ -1,13 +1,11 @@
|
||||
//! Some lints that are only useful in the compiler or crates that use compiler internals, such as
|
||||
//! Clippy.
|
||||
|
||||
use crate::lint::{
|
||||
EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintArray, LintContext, LintPass,
|
||||
};
|
||||
use crate::lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{GenericArg, HirId, MutTy, Mutability, Path, PathSegment, QPath, Ty, TyKind};
|
||||
use rustc_session::declare_tool_lint;
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint, impl_lint_pass};
|
||||
use rustc_span::symbol::{sym, Symbol};
|
||||
use syntax::ast::{Ident, Item, ItemKind};
|
||||
|
||||
|
@ -13,8 +13,8 @@ use rustc_span::source_map::MultiSpan;
|
||||
use rustc_span::symbol::{sym, Symbol};
|
||||
use syntax::ast;
|
||||
use syntax::attr;
|
||||
use syntax::feature_gate;
|
||||
use syntax::print::pprust;
|
||||
use syntax::sess::feature_err;
|
||||
|
||||
use rustc_error_codes::*;
|
||||
|
||||
@ -223,7 +223,7 @@ impl<'a> LintLevelsBuilder<'a> {
|
||||
// don't have any lint names (`#[level(reason = "foo")]`)
|
||||
if let ast::LitKind::Str(rationale, _) = name_value.kind {
|
||||
if !self.sess.features_untracked().lint_reasons {
|
||||
feature_gate::feature_err(
|
||||
feature_err(
|
||||
&self.sess.parse_sess,
|
||||
sym::lint_reasons,
|
||||
item.span,
|
||||
|
@ -21,12 +21,11 @@
|
||||
pub use self::Level::*;
|
||||
pub use self::LintSource::*;
|
||||
|
||||
use crate::lint::builtin::BuiltinLintDiagnostics;
|
||||
use crate::ty::TyCtxt;
|
||||
use rustc_data_structures::sync;
|
||||
use rustc_errors::{DiagnosticBuilder, DiagnosticId};
|
||||
use rustc_hir as hir;
|
||||
use rustc_session::node_id::NodeMap;
|
||||
use rustc_session::lint::builtin::HardwiredLints;
|
||||
use rustc_session::{DiagnosticMessageId, Session};
|
||||
use rustc_span::hygiene::MacroKind;
|
||||
use rustc_span::source_map::{DesugaringKind, ExpnKind, MultiSpan};
|
||||
@ -35,48 +34,13 @@ use rustc_span::Span;
|
||||
use syntax::ast;
|
||||
|
||||
pub use crate::lint::context::{
|
||||
BufferedEarlyLint, CheckLintNameResult, EarlyContext, LateContext, LintContext, LintStore,
|
||||
add_elided_lifetime_in_path_suggestion, CheckLintNameResult, EarlyContext, LateContext,
|
||||
LintContext, LintStore,
|
||||
};
|
||||
|
||||
pub use rustc_session::lint::{FutureIncompatibleInfo, Level, Lint, LintId};
|
||||
|
||||
/// Declares a static `LintArray` and return it as an expression.
|
||||
#[macro_export]
|
||||
macro_rules! lint_array {
|
||||
($( $lint:expr ),* ,) => { lint_array!( $($lint),* ) };
|
||||
($( $lint:expr ),*) => {{
|
||||
vec![$($lint),*]
|
||||
}}
|
||||
}
|
||||
|
||||
pub type LintArray = Vec<&'static Lint>;
|
||||
|
||||
pub trait LintPass {
|
||||
fn name(&self) -> &'static str;
|
||||
}
|
||||
|
||||
/// Implements `LintPass for $name` with the given list of `Lint` statics.
|
||||
#[macro_export]
|
||||
macro_rules! impl_lint_pass {
|
||||
($name:ident => [$($lint:expr),* $(,)?]) => {
|
||||
impl LintPass for $name {
|
||||
fn name(&self) -> &'static str { stringify!($name) }
|
||||
}
|
||||
impl $name {
|
||||
pub fn get_lints() -> LintArray { $crate::lint_array!($($lint),*) }
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Declares a type named `$name` which implements `LintPass`.
|
||||
/// To the right of `=>` a comma separated list of `Lint` statics is given.
|
||||
#[macro_export]
|
||||
macro_rules! declare_lint_pass {
|
||||
($(#[$m:meta])* $name:ident => [$($lint:expr),* $(,)?]) => {
|
||||
$(#[$m])* #[derive(Copy, Clone)] pub struct $name;
|
||||
$crate::impl_lint_pass!($name => [$($lint),*]);
|
||||
};
|
||||
}
|
||||
pub use rustc_session::lint::builtin;
|
||||
pub use rustc_session::lint::{BufferedEarlyLint, FutureIncompatibleInfo, Level, Lint, LintId};
|
||||
pub use rustc_session::lint::{LintArray, LintPass};
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! late_lint_methods {
|
||||
@ -168,6 +132,8 @@ macro_rules! declare_late_lint_pass {
|
||||
|
||||
late_lint_methods!(declare_late_lint_pass, [], ['tcx]);
|
||||
|
||||
impl LateLintPass<'_, '_> for HardwiredLints {}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! expand_combined_late_lint_pass_method {
|
||||
([$($passes:ident),*], $self: ident, $name: ident, $params:tt) => ({
|
||||
@ -366,66 +332,12 @@ pub enum LintSource {
|
||||
|
||||
pub type LevelSource = (Level, LintSource);
|
||||
|
||||
pub mod builtin;
|
||||
mod context;
|
||||
pub mod internal;
|
||||
mod levels;
|
||||
|
||||
pub use self::levels::{LintLevelMap, LintLevelSets, LintLevelsBuilder};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct LintBuffer {
|
||||
pub map: NodeMap<Vec<BufferedEarlyLint>>,
|
||||
}
|
||||
|
||||
impl LintBuffer {
|
||||
pub fn add_lint(
|
||||
&mut self,
|
||||
lint: &'static Lint,
|
||||
id: ast::NodeId,
|
||||
sp: MultiSpan,
|
||||
msg: &str,
|
||||
diagnostic: BuiltinLintDiagnostics,
|
||||
) {
|
||||
let early_lint = BufferedEarlyLint {
|
||||
lint_id: LintId::of(lint),
|
||||
ast_id: id,
|
||||
span: sp,
|
||||
msg: msg.to_string(),
|
||||
diagnostic,
|
||||
};
|
||||
let arr = self.map.entry(id).or_default();
|
||||
if !arr.contains(&early_lint) {
|
||||
arr.push(early_lint);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn take(&mut self, id: ast::NodeId) -> Vec<BufferedEarlyLint> {
|
||||
self.map.remove(&id).unwrap_or_default()
|
||||
}
|
||||
|
||||
pub fn buffer_lint<S: Into<MultiSpan>>(
|
||||
&mut self,
|
||||
lint: &'static Lint,
|
||||
id: ast::NodeId,
|
||||
sp: S,
|
||||
msg: &str,
|
||||
) {
|
||||
self.add_lint(lint, id, sp.into(), msg, BuiltinLintDiagnostics::Normal)
|
||||
}
|
||||
|
||||
pub fn buffer_lint_with_diagnostic<S: Into<MultiSpan>>(
|
||||
&mut self,
|
||||
lint: &'static Lint,
|
||||
id: ast::NodeId,
|
||||
sp: S,
|
||||
msg: &str,
|
||||
diagnostic: BuiltinLintDiagnostics,
|
||||
) {
|
||||
self.add_lint(lint, id, sp.into(), msg, diagnostic)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn struct_lint_level<'a>(
|
||||
sess: &'a Session,
|
||||
lint: &'static Lint,
|
||||
|
@ -3,7 +3,6 @@
|
||||
|
||||
pub use self::StabilityLevel::*;
|
||||
|
||||
use crate::lint::builtin::BuiltinLintDiagnostics;
|
||||
use crate::lint::{self, in_derive_expansion, Lint};
|
||||
use crate::session::{DiagnosticMessageId, Session};
|
||||
use crate::ty::{self, TyCtxt};
|
||||
@ -14,11 +13,12 @@ use rustc_hir as hir;
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX};
|
||||
use rustc_hir::{self, HirId};
|
||||
use rustc_session::lint::{BuiltinLintDiagnostics, LintBuffer};
|
||||
use rustc_span::symbol::{sym, Symbol};
|
||||
use rustc_span::{MultiSpan, Span};
|
||||
use syntax::ast::CRATE_NODE_ID;
|
||||
use syntax::attr::{self, ConstStability, Deprecation, RustcDeprecation, Stability};
|
||||
use syntax::feature_gate::feature_err_issue;
|
||||
use syntax::sess::feature_err_issue;
|
||||
|
||||
use std::num::NonZeroU32;
|
||||
|
||||
@ -195,7 +195,7 @@ pub fn rustc_deprecation_message(depr: &RustcDeprecation, path: &str) -> (String
|
||||
}
|
||||
|
||||
pub fn early_report_deprecation(
|
||||
lint_buffer: &'a mut lint::LintBuffer,
|
||||
lint_buffer: &'a mut LintBuffer,
|
||||
message: &str,
|
||||
suggestion: Option<Symbol>,
|
||||
lint: &'static Lint,
|
||||
|
@ -37,7 +37,6 @@ use rustc::arena::Arena;
|
||||
use rustc::dep_graph::DepGraph;
|
||||
use rustc::hir::map::definitions::{DefKey, DefPathData, Definitions};
|
||||
use rustc::hir::map::Map;
|
||||
use rustc::lint;
|
||||
use rustc::lint::builtin;
|
||||
use rustc::{bug, span_bug};
|
||||
use rustc_data_structures::captures::Captures;
|
||||
@ -52,6 +51,7 @@ use rustc_hir::intravisit;
|
||||
use rustc_hir::{ConstArg, GenericArg, ParamName};
|
||||
use rustc_index::vec::IndexVec;
|
||||
use rustc_session::config::nightly_options;
|
||||
use rustc_session::lint::{BuiltinLintDiagnostics, LintBuffer};
|
||||
use rustc_session::node_id::NodeMap;
|
||||
use rustc_session::Session;
|
||||
use rustc_span::hygiene::ExpnId;
|
||||
@ -198,7 +198,7 @@ pub trait Resolver {
|
||||
ns: Namespace,
|
||||
) -> (ast::Path, Res<NodeId>);
|
||||
|
||||
fn lint_buffer(&mut self) -> &mut lint::LintBuffer;
|
||||
fn lint_buffer(&mut self) -> &mut LintBuffer;
|
||||
|
||||
fn next_node_id(&mut self) -> NodeId;
|
||||
}
|
||||
@ -268,7 +268,7 @@ pub fn lower_crate<'a, 'hir>(
|
||||
// incr. comp. yet.
|
||||
dep_graph.assert_ignored();
|
||||
|
||||
let _prof_timer = sess.prof.generic_activity("hir_lowering");
|
||||
let _prof_timer = sess.prof.verbose_generic_activity("hir_lowering");
|
||||
|
||||
LoweringContext {
|
||||
crate_root: sess.parse_sess.injected_crate_name.try_get().copied(),
|
||||
@ -2617,7 +2617,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
id,
|
||||
span,
|
||||
"trait objects without an explicit `dyn` are deprecated",
|
||||
builtin::BuiltinLintDiagnostics::BareTraitObject(span, is_global),
|
||||
BuiltinLintDiagnostics::BareTraitObject(span, is_global),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
use super::{AnonymousLifetimeMode, ImplTraitContext, LoweringContext, ParamMode};
|
||||
use super::{GenericArgsCtor, ParenthesizedGenericArgs};
|
||||
|
||||
use rustc::lint::builtin::{self, ELIDED_LIFETIMES_IN_PATHS};
|
||||
use rustc::lint::builtin::ELIDED_LIFETIMES_IN_PATHS;
|
||||
use rustc::span_bug;
|
||||
use rustc_error_codes::*;
|
||||
use rustc_errors::{struct_span_err, Applicability};
|
||||
@ -9,6 +9,7 @@ use rustc_hir as hir;
|
||||
use rustc_hir::def::{DefKind, PartialRes, Res};
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::GenericArg;
|
||||
use rustc_session::lint::BuiltinLintDiagnostics;
|
||||
use rustc_span::Span;
|
||||
use syntax::ast::{self, *};
|
||||
|
||||
@ -304,7 +305,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
E0726,
|
||||
"implicit elided lifetime not allowed here"
|
||||
);
|
||||
crate::lint::builtin::add_elided_lifetime_in_path_suggestion(
|
||||
rustc::lint::add_elided_lifetime_in_path_suggestion(
|
||||
&self.sess,
|
||||
&mut err,
|
||||
expected_lifetimes,
|
||||
@ -321,7 +322,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
CRATE_NODE_ID,
|
||||
path_span,
|
||||
"hidden lifetime parameters in types are deprecated",
|
||||
builtin::BuiltinLintDiagnostics::ElidedLifetimesInPaths(
|
||||
BuiltinLintDiagnostics::ElidedLifetimesInPaths(
|
||||
expected_lifetimes,
|
||||
path_span,
|
||||
incl_angl_brckt,
|
||||
|
20
src/librustc_ast_passes/Cargo.toml
Normal file
20
src/librustc_ast_passes/Cargo.toml
Normal file
@ -0,0 +1,20 @@
|
||||
[package]
|
||||
authors = ["The Rust Project Developers"]
|
||||
name = "rustc_ast_passes"
|
||||
version = "0.0.0"
|
||||
edition = "2018"
|
||||
|
||||
[lib]
|
||||
name = "rustc_ast_passes"
|
||||
path = "lib.rs"
|
||||
|
||||
[dependencies]
|
||||
log = "0.4"
|
||||
rustc_data_structures = { path = "../librustc_data_structures" }
|
||||
rustc_errors = { path = "../librustc_errors", package = "rustc_errors" }
|
||||
rustc_error_codes = { path = "../librustc_error_codes" }
|
||||
rustc_feature = { path = "../librustc_feature" }
|
||||
rustc_parse = { path = "../librustc_parse" }
|
||||
rustc_session = { path = "../librustc_session" }
|
||||
rustc_span = { path = "../librustc_span" }
|
||||
syntax = { path = "../libsyntax" }
|
@ -6,11 +6,12 @@
|
||||
// This pass is supposed to perform only simple checks not requiring name resolution
|
||||
// or type checking or some other kind of complex analysis.
|
||||
|
||||
use rustc::lint;
|
||||
use rustc::session::Session;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_errors::{struct_span_err, Applicability, FatalError};
|
||||
use rustc_parse::validate_attr;
|
||||
use rustc_session::lint::builtin::PATTERNS_IN_FNS_WITHOUT_BODY;
|
||||
use rustc_session::lint::LintBuffer;
|
||||
use rustc_session::Session;
|
||||
use rustc_span::source_map::Spanned;
|
||||
use rustc_span::symbol::{kw, sym};
|
||||
use rustc_span::Span;
|
||||
@ -65,7 +66,7 @@ struct AstValidator<'a> {
|
||||
/// certain positions.
|
||||
is_assoc_ty_bound_banned: bool,
|
||||
|
||||
lint_buffer: &'a mut lint::LintBuffer,
|
||||
lint_buffer: &'a mut LintBuffer,
|
||||
}
|
||||
|
||||
impl<'a> AstValidator<'a> {
|
||||
@ -906,7 +907,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
Some(Constness::Const) => bug!("Parser should reject bare `const` on bounds"),
|
||||
Some(Constness::Const) => panic!("Parser should reject bare `const` on bounds"),
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
@ -992,7 +993,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
Self::check_decl_no_pat(&sig.decl, |span, mut_ident| {
|
||||
if mut_ident {
|
||||
self.lint_buffer.buffer_lint(
|
||||
lint::builtin::PATTERNS_IN_FNS_WITHOUT_BODY,
|
||||
PATTERNS_IN_FNS_WITHOUT_BODY,
|
||||
ti.id,
|
||||
span,
|
||||
"patterns aren't allowed in methods without bodies",
|
||||
@ -1021,7 +1022,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn check_crate(session: &Session, krate: &Crate, lints: &mut lint::LintBuffer) -> bool {
|
||||
pub fn check_crate(session: &Session, krate: &Crate, lints: &mut LintBuffer) -> bool {
|
||||
let mut validator = AstValidator {
|
||||
session,
|
||||
has_proc_macro_decls: false,
|
@ -1,22 +1,15 @@
|
||||
use crate::ast::{self, AssocTyConstraint, AssocTyConstraintKind, NodeId};
|
||||
use crate::ast::{GenericParam, GenericParamKind, PatKind, RangeEnd, VariantData};
|
||||
use crate::attr;
|
||||
use crate::sess::ParseSess;
|
||||
use crate::visit::{self, FnKind, Visitor};
|
||||
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_error_codes::*;
|
||||
use rustc_errors::{error_code, struct_span_err, Applicability, DiagnosticBuilder, Handler};
|
||||
use rustc_feature::{find_feature_issue, GateIssue};
|
||||
use rustc_errors::{struct_span_err, Handler};
|
||||
use rustc_feature::{AttributeGate, BUILTIN_ATTRIBUTE_MAP};
|
||||
use rustc_feature::{Feature, Features, State as FeatureState, UnstableFeatures};
|
||||
use rustc_feature::{
|
||||
ACCEPTED_FEATURES, ACTIVE_FEATURES, REMOVED_FEATURES, STABLE_REMOVED_FEATURES,
|
||||
};
|
||||
use rustc_span::edition::{Edition, ALL_EDITIONS};
|
||||
use rustc_feature::{Features, GateIssue, UnstableFeatures};
|
||||
use rustc_span::source_map::Spanned;
|
||||
use rustc_span::symbol::{sym, Symbol};
|
||||
use rustc_span::{MultiSpan, Span, DUMMY_SP};
|
||||
use rustc_span::symbol::sym;
|
||||
use rustc_span::Span;
|
||||
use syntax::ast::{self, AssocTyConstraint, AssocTyConstraintKind, NodeId};
|
||||
use syntax::ast::{GenericParam, GenericParamKind, PatKind, RangeEnd, VariantData};
|
||||
use syntax::attr;
|
||||
use syntax::sess::{feature_err, leveled_feature_err, GateStrength, ParseSess};
|
||||
use syntax::visit::{self, FnKind, Visitor};
|
||||
|
||||
use log::debug;
|
||||
|
||||
@ -53,70 +46,6 @@ pub fn check_attribute(attr: &ast::Attribute, parse_sess: &ParseSess, features:
|
||||
PostExpansionVisitor { parse_sess, features }.visit_attribute(attr)
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub enum GateStrength {
|
||||
/// A hard error. (Most feature gates should use this.)
|
||||
Hard,
|
||||
/// Only a warning. (Use this only as backwards-compatibility demands.)
|
||||
Soft,
|
||||
}
|
||||
|
||||
pub fn feature_err<'a>(
|
||||
sess: &'a ParseSess,
|
||||
feature: Symbol,
|
||||
span: impl Into<MultiSpan>,
|
||||
explain: &str,
|
||||
) -> DiagnosticBuilder<'a> {
|
||||
feature_err_issue(sess, feature, span, GateIssue::Language, explain)
|
||||
}
|
||||
|
||||
pub fn feature_err_issue<'a>(
|
||||
sess: &'a ParseSess,
|
||||
feature: Symbol,
|
||||
span: impl Into<MultiSpan>,
|
||||
issue: GateIssue,
|
||||
explain: &str,
|
||||
) -> DiagnosticBuilder<'a> {
|
||||
leveled_feature_err(sess, feature, span, issue, explain, GateStrength::Hard)
|
||||
}
|
||||
|
||||
fn leveled_feature_err<'a>(
|
||||
sess: &'a ParseSess,
|
||||
feature: Symbol,
|
||||
span: impl Into<MultiSpan>,
|
||||
issue: GateIssue,
|
||||
explain: &str,
|
||||
level: GateStrength,
|
||||
) -> DiagnosticBuilder<'a> {
|
||||
let diag = &sess.span_diagnostic;
|
||||
|
||||
let mut err = match level {
|
||||
GateStrength::Hard => diag.struct_span_err_with_code(span, explain, error_code!(E0658)),
|
||||
GateStrength::Soft => diag.struct_span_warn(span, explain),
|
||||
};
|
||||
|
||||
if let Some(n) = find_feature_issue(feature, issue) {
|
||||
err.note(&format!(
|
||||
"for more information, see https://github.com/rust-lang/rust/issues/{}",
|
||||
n,
|
||||
));
|
||||
}
|
||||
|
||||
// #23973: do not suggest `#![feature(...)]` if we are in beta/stable
|
||||
if sess.unstable_features.is_nightly_build() {
|
||||
err.help(&format!("add `#![feature({})]` to the crate attributes to enable", feature));
|
||||
}
|
||||
|
||||
// If we're on stable and only emitting a "soft" warning, add a note to
|
||||
// clarify that the feature isn't "on" (rather than being on but
|
||||
// warning-worthy).
|
||||
if !sess.unstable_features.is_nightly_build() && level == GateStrength::Soft {
|
||||
err.help("a nightly build of the compiler is required to enable this feature");
|
||||
}
|
||||
|
||||
err
|
||||
}
|
||||
|
||||
struct PostExpansionVisitor<'a> {
|
||||
parse_sess: &'a ParseSess,
|
||||
features: &'a Features,
|
||||
@ -724,168 +653,6 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_features(
|
||||
span_handler: &Handler,
|
||||
krate_attrs: &[ast::Attribute],
|
||||
crate_edition: Edition,
|
||||
allow_features: &Option<Vec<String>>,
|
||||
) -> Features {
|
||||
fn feature_removed(span_handler: &Handler, span: Span, reason: Option<&str>) {
|
||||
let mut err = struct_span_err!(span_handler, span, E0557, "feature has been removed");
|
||||
err.span_label(span, "feature has been removed");
|
||||
if let Some(reason) = reason {
|
||||
err.note(reason);
|
||||
}
|
||||
err.emit();
|
||||
}
|
||||
|
||||
let mut features = Features::default();
|
||||
let mut edition_enabled_features = FxHashMap::default();
|
||||
|
||||
for &edition in ALL_EDITIONS {
|
||||
if edition <= crate_edition {
|
||||
// The `crate_edition` implies its respective umbrella feature-gate
|
||||
// (i.e., `#![feature(rust_20XX_preview)]` isn't needed on edition 20XX).
|
||||
edition_enabled_features.insert(edition.feature_name(), edition);
|
||||
}
|
||||
}
|
||||
|
||||
for feature in active_features_up_to(crate_edition) {
|
||||
feature.set(&mut features, DUMMY_SP);
|
||||
edition_enabled_features.insert(feature.name, crate_edition);
|
||||
}
|
||||
|
||||
// Process the edition umbrella feature-gates first, to ensure
|
||||
// `edition_enabled_features` is completed before it's queried.
|
||||
for attr in krate_attrs {
|
||||
if !attr.check_name(sym::feature) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let list = match attr.meta_item_list() {
|
||||
Some(list) => list,
|
||||
None => continue,
|
||||
};
|
||||
|
||||
for mi in list {
|
||||
if !mi.is_word() {
|
||||
continue;
|
||||
}
|
||||
|
||||
let name = mi.name_or_empty();
|
||||
|
||||
let edition = ALL_EDITIONS.iter().find(|e| name == e.feature_name()).copied();
|
||||
if let Some(edition) = edition {
|
||||
if edition <= crate_edition {
|
||||
continue;
|
||||
}
|
||||
|
||||
for feature in active_features_up_to(edition) {
|
||||
// FIXME(Manishearth) there is currently no way to set
|
||||
// lib features by edition
|
||||
feature.set(&mut features, DUMMY_SP);
|
||||
edition_enabled_features.insert(feature.name, edition);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for attr in krate_attrs {
|
||||
if !attr.check_name(sym::feature) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let list = match attr.meta_item_list() {
|
||||
Some(list) => list,
|
||||
None => continue,
|
||||
};
|
||||
|
||||
let bad_input = |span| {
|
||||
struct_span_err!(span_handler, span, E0556, "malformed `feature` attribute input")
|
||||
};
|
||||
|
||||
for mi in list {
|
||||
let name = match mi.ident() {
|
||||
Some(ident) if mi.is_word() => ident.name,
|
||||
Some(ident) => {
|
||||
bad_input(mi.span())
|
||||
.span_suggestion(
|
||||
mi.span(),
|
||||
"expected just one word",
|
||||
format!("{}", ident.name),
|
||||
Applicability::MaybeIncorrect,
|
||||
)
|
||||
.emit();
|
||||
continue;
|
||||
}
|
||||
None => {
|
||||
bad_input(mi.span()).span_label(mi.span(), "expected just one word").emit();
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(edition) = edition_enabled_features.get(&name) {
|
||||
let msg =
|
||||
&format!("the feature `{}` is included in the Rust {} edition", name, edition);
|
||||
span_handler.struct_span_warn_with_code(mi.span(), msg, error_code!(E0705)).emit();
|
||||
continue;
|
||||
}
|
||||
|
||||
if ALL_EDITIONS.iter().any(|e| name == e.feature_name()) {
|
||||
// Handled in the separate loop above.
|
||||
continue;
|
||||
}
|
||||
|
||||
let removed = REMOVED_FEATURES.iter().find(|f| name == f.name);
|
||||
let stable_removed = STABLE_REMOVED_FEATURES.iter().find(|f| name == f.name);
|
||||
if let Some(Feature { state, .. }) = removed.or(stable_removed) {
|
||||
if let FeatureState::Removed { reason } | FeatureState::Stabilized { reason } =
|
||||
state
|
||||
{
|
||||
feature_removed(span_handler, mi.span(), *reason);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(Feature { since, .. }) = ACCEPTED_FEATURES.iter().find(|f| name == f.name) {
|
||||
let since = Some(Symbol::intern(since));
|
||||
features.declared_lang_features.push((name, mi.span(), since));
|
||||
continue;
|
||||
}
|
||||
|
||||
if let Some(allowed) = allow_features.as_ref() {
|
||||
if allowed.iter().find(|&f| name.as_str() == *f).is_none() {
|
||||
struct_span_err!(
|
||||
span_handler,
|
||||
mi.span(),
|
||||
E0725,
|
||||
"the feature `{}` is not in the list of allowed features",
|
||||
name
|
||||
)
|
||||
.emit();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(f) = ACTIVE_FEATURES.iter().find(|f| name == f.name) {
|
||||
f.set(&mut features, mi.span());
|
||||
features.declared_lang_features.push((name, mi.span(), None));
|
||||
continue;
|
||||
}
|
||||
|
||||
features.declared_lib_features.push((name, mi.span()));
|
||||
}
|
||||
}
|
||||
|
||||
features
|
||||
}
|
||||
|
||||
fn active_features_up_to(edition: Edition) -> impl Iterator<Item = &'static Feature> {
|
||||
ACTIVE_FEATURES.iter().filter(move |feature| {
|
||||
if let Some(feature_edition) = feature.edition { feature_edition <= edition } else { false }
|
||||
})
|
||||
}
|
||||
|
||||
pub fn check_crate(
|
||||
krate: &ast::Crate,
|
||||
parse_sess: &ParseSess,
|
9
src/librustc_ast_passes/lib.rs
Normal file
9
src/librustc_ast_passes/lib.rs
Normal file
@ -0,0 +1,9 @@
|
||||
//! The `rustc_ast_passes` crate contains passes which validate the AST in `syntax`
|
||||
//! parsed by `rustc_parse` and then lowered, after the passes in this crate,
|
||||
//! by `rustc_ast_lowering`.
|
||||
|
||||
#![feature(slice_patterns)]
|
||||
|
||||
pub mod ast_validation;
|
||||
pub mod feature_gate;
|
||||
pub mod show_span;
|
@ -5,9 +5,9 @@
|
||||
|
||||
use std::str::FromStr;
|
||||
|
||||
use crate::ast;
|
||||
use crate::visit;
|
||||
use crate::visit::Visitor;
|
||||
use syntax::ast;
|
||||
use syntax::visit;
|
||||
use syntax::visit::Visitor;
|
||||
|
||||
enum Mode {
|
||||
Expression,
|
@ -17,6 +17,7 @@ rustc_errors = { path = "../librustc_errors" }
|
||||
rustc_feature = { path = "../librustc_feature" }
|
||||
rustc_parse = { path = "../librustc_parse" }
|
||||
rustc_target = { path = "../librustc_target" }
|
||||
rustc_session = { path = "../librustc_session" }
|
||||
smallvec = { version = "1.0", features = ["union", "may_dangle"] }
|
||||
syntax = { path = "../libsyntax" }
|
||||
rustc_expand = { path = "../librustc_expand" }
|
||||
|
@ -106,7 +106,7 @@ fn parse_assert<'a>(
|
||||
let custom_message =
|
||||
if let token::Literal(token::Lit { kind: token::Str, .. }) = parser.token.kind {
|
||||
let mut err = cx.struct_span_warn(parser.token.span, "unexpected string literal");
|
||||
let comma_span = cx.source_map().next_point(parser.prev_span);
|
||||
let comma_span = parser.prev_span.shrink_to_hi();
|
||||
err.span_suggestion_short(
|
||||
comma_span,
|
||||
"try adding a comma",
|
||||
|
@ -1,15 +1,15 @@
|
||||
use rustc_expand::base::{self, *};
|
||||
use rustc_expand::panictry;
|
||||
use rustc_parse::{self, new_sub_parser_from_file, parser::Parser, DirectoryOwnership};
|
||||
use rustc_session::lint::builtin::INCOMPLETE_INCLUDE;
|
||||
use rustc_span::symbol::Symbol;
|
||||
use rustc_span::{self, Pos, Span};
|
||||
use syntax::ast;
|
||||
use syntax::early_buffered_lints::INCOMPLETE_INCLUDE;
|
||||
use syntax::print::pprust;
|
||||
use syntax::ptr::P;
|
||||
use syntax::token;
|
||||
use syntax::tokenstream::TokenStream;
|
||||
|
||||
use rustc_span::{self, Pos, Span};
|
||||
use smallvec::SmallVec;
|
||||
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
|
@ -53,6 +53,7 @@ pub fn link_binary<'a, B: ArchiveBuilder<'a>>(
|
||||
crate_name: &str,
|
||||
target_cpu: &str,
|
||||
) {
|
||||
let _timer = sess.timer("link_binary");
|
||||
let output_metadata = sess.opts.output_types.contains_key(&OutputType::Metadata);
|
||||
for &crate_type in sess.crate_types.borrow().iter() {
|
||||
// Ignore executable crates if we have -Z no-codegen, as they will error.
|
||||
@ -71,9 +72,11 @@ pub fn link_binary<'a, B: ArchiveBuilder<'a>>(
|
||||
);
|
||||
}
|
||||
|
||||
for obj in codegen_results.modules.iter().filter_map(|m| m.object.as_ref()) {
|
||||
check_file_is_writeable(obj, sess);
|
||||
}
|
||||
sess.time("link_binary_check_files_are_writeable", || {
|
||||
for obj in codegen_results.modules.iter().filter_map(|m| m.object.as_ref()) {
|
||||
check_file_is_writeable(obj, sess);
|
||||
}
|
||||
});
|
||||
|
||||
let tmpdir = TempFileBuilder::new()
|
||||
.prefix("rustc")
|
||||
@ -84,6 +87,7 @@ pub fn link_binary<'a, B: ArchiveBuilder<'a>>(
|
||||
let out_filename = out_filename(sess, crate_type, outputs, crate_name);
|
||||
match crate_type {
|
||||
config::CrateType::Rlib => {
|
||||
let _timer = sess.timer("link_rlib");
|
||||
link_rlib::<B>(
|
||||
sess,
|
||||
codegen_results,
|
||||
@ -118,29 +122,34 @@ pub fn link_binary<'a, B: ArchiveBuilder<'a>>(
|
||||
}
|
||||
|
||||
// Remove the temporary object file and metadata if we aren't saving temps
|
||||
if !sess.opts.cg.save_temps {
|
||||
if sess.opts.output_types.should_codegen() && !preserve_objects_for_their_debuginfo(sess) {
|
||||
for obj in codegen_results.modules.iter().filter_map(|m| m.object.as_ref()) {
|
||||
sess.time("link_binary_remove_temps", || {
|
||||
if !sess.opts.cg.save_temps {
|
||||
if sess.opts.output_types.should_codegen()
|
||||
&& !preserve_objects_for_their_debuginfo(sess)
|
||||
{
|
||||
for obj in codegen_results.modules.iter().filter_map(|m| m.object.as_ref()) {
|
||||
remove(sess, obj);
|
||||
}
|
||||
}
|
||||
for obj in codegen_results.modules.iter().filter_map(|m| m.bytecode_compressed.as_ref())
|
||||
{
|
||||
remove(sess, obj);
|
||||
}
|
||||
}
|
||||
for obj in codegen_results.modules.iter().filter_map(|m| m.bytecode_compressed.as_ref()) {
|
||||
remove(sess, obj);
|
||||
}
|
||||
if let Some(ref metadata_module) = codegen_results.metadata_module {
|
||||
if let Some(ref obj) = metadata_module.object {
|
||||
remove(sess, obj);
|
||||
if let Some(ref metadata_module) = codegen_results.metadata_module {
|
||||
if let Some(ref obj) = metadata_module.object {
|
||||
remove(sess, obj);
|
||||
}
|
||||
}
|
||||
if let Some(ref allocator_module) = codegen_results.allocator_module {
|
||||
if let Some(ref obj) = allocator_module.object {
|
||||
remove(sess, obj);
|
||||
}
|
||||
if let Some(ref bc) = allocator_module.bytecode_compressed {
|
||||
remove(sess, bc);
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(ref allocator_module) = codegen_results.allocator_module {
|
||||
if let Some(ref obj) = allocator_module.object {
|
||||
remove(sess, obj);
|
||||
}
|
||||
if let Some(ref bc) = allocator_module.bytecode_compressed {
|
||||
remove(sess, bc);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// The third parameter is for env vars, used on windows to set up the
|
||||
|
@ -479,6 +479,8 @@ fn copy_all_cgu_workproducts_to_incr_comp_cache_dir(
|
||||
return work_products;
|
||||
}
|
||||
|
||||
let _timer = sess.timer("incr_comp_copy_cgu_workproducts");
|
||||
|
||||
for module in compiled_modules.modules.iter().filter(|m| m.kind == ModuleKind::Regular) {
|
||||
let mut files = vec![];
|
||||
|
||||
@ -1714,8 +1716,11 @@ pub struct OngoingCodegen<B: ExtraBackendMethods> {
|
||||
|
||||
impl<B: ExtraBackendMethods> OngoingCodegen<B> {
|
||||
pub fn join(self, sess: &Session) -> (CodegenResults, FxHashMap<WorkProductId, WorkProduct>) {
|
||||
let _timer = sess.timer("finish_ongoing_codegen");
|
||||
|
||||
self.shared_emitter_main.check(sess, true);
|
||||
let compiled_modules = match self.future.join() {
|
||||
let future = self.future;
|
||||
let compiled_modules = sess.time("join_worker_thread", || match future.join() {
|
||||
Ok(Ok(compiled_modules)) => compiled_modules,
|
||||
Ok(Err(())) => {
|
||||
sess.abort_if_errors();
|
||||
@ -1724,7 +1729,7 @@ impl<B: ExtraBackendMethods> OngoingCodegen<B> {
|
||||
Err(_) => {
|
||||
bug!("panic during codegen/LLVM phase");
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
sess.cgu_reuse_tracker.check_expected_reuse(sess.diagnostic());
|
||||
|
||||
|
@ -495,6 +495,12 @@ impl<'a> TimingGuard<'a> {
|
||||
pub fn none() -> TimingGuard<'a> {
|
||||
TimingGuard(None)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn run<R>(self, f: impl FnOnce() -> R) -> R {
|
||||
let _timer = self;
|
||||
f()
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
|
@ -389,6 +389,7 @@ pub fn run_compiler(
|
||||
})?;
|
||||
} else {
|
||||
// Drop AST after creating GlobalCtxt to free memory
|
||||
let _timer = sess.prof.generic_activity("drop_ast");
|
||||
mem::drop(queries.expansion()?.take());
|
||||
}
|
||||
|
||||
@ -413,6 +414,7 @@ pub fn run_compiler(
|
||||
})?;
|
||||
|
||||
if let Some(linker) = linker {
|
||||
let _timer = sess.timer("link");
|
||||
linker.link()?
|
||||
}
|
||||
|
||||
|
@ -182,7 +182,7 @@ impl CodeSuggestion {
|
||||
|
||||
// Find the bounding span.
|
||||
let lo = substitution.parts.iter().map(|part| part.span.lo()).min().unwrap();
|
||||
let hi = substitution.parts.iter().map(|part| part.span.hi()).min().unwrap();
|
||||
let hi = substitution.parts.iter().map(|part| part.span.hi()).max().unwrap();
|
||||
let bounding_span = Span::with_root_ctxt(lo, hi);
|
||||
let lines = cm.span_to_lines(bounding_span).unwrap();
|
||||
assert!(!lines.lines.is_empty());
|
||||
|
@ -14,10 +14,12 @@ doctest = false
|
||||
rustc_serialize = { path = "../libserialize", package = "serialize" }
|
||||
log = "0.4"
|
||||
rustc_span = { path = "../librustc_span" }
|
||||
rustc_ast_passes = { path = "../librustc_ast_passes" }
|
||||
rustc_data_structures = { path = "../librustc_data_structures" }
|
||||
rustc_errors = { path = "../librustc_errors" }
|
||||
rustc_feature = { path = "../librustc_feature" }
|
||||
rustc_lexer = { path = "../librustc_lexer" }
|
||||
rustc_parse = { path = "../librustc_parse" }
|
||||
rustc_session = { path = "../librustc_session" }
|
||||
smallvec = { version = "1.0", features = ["union", "may_dangle"] }
|
||||
syntax = { path = "../libsyntax" }
|
||||
|
@ -18,11 +18,10 @@ use rustc_span::{FileName, Span, DUMMY_SP};
|
||||
use syntax::ast::{self, AttrItem, Block, Ident, LitKind, NodeId, PatKind, Path};
|
||||
use syntax::ast::{ItemKind, MacArgs, MacStmtStyle, StmtKind};
|
||||
use syntax::attr::{self, is_builtin_attr, HasAttrs};
|
||||
use syntax::feature_gate::{self, feature_err};
|
||||
use syntax::mut_visit::*;
|
||||
use syntax::print::pprust;
|
||||
use syntax::ptr::P;
|
||||
use syntax::sess::ParseSess;
|
||||
use syntax::sess::{feature_err, ParseSess};
|
||||
use syntax::token;
|
||||
use syntax::tokenstream::{TokenStream, TokenTree};
|
||||
use syntax::util::map_in_place::MapInPlace;
|
||||
@ -1062,7 +1061,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
|
||||
fn check_attributes(&mut self, attrs: &[ast::Attribute]) {
|
||||
let features = self.cx.ecfg.features.unwrap();
|
||||
for attr in attrs.iter() {
|
||||
feature_gate::check_attribute(attr, self.cx.parse_sess, features);
|
||||
rustc_ast_passes::feature_gate::check_attribute(attr, self.cx.parse_sess, features);
|
||||
validate_attr::check_meta(self.cx.parse_sess, attr);
|
||||
|
||||
// macros are expanded before any lint passes so this warning has to be hardcoded
|
||||
|
@ -106,14 +106,14 @@
|
||||
//! bound.
|
||||
use crate::mbe::{KleeneToken, TokenTree};
|
||||
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_session::lint::builtin::META_VARIABLE_MISUSE;
|
||||
use rustc_session::parse::ParseSess;
|
||||
use rustc_span::symbol::{kw, sym};
|
||||
use rustc_span::{symbol::Ident, MultiSpan, Span};
|
||||
use syntax::ast::NodeId;
|
||||
use syntax::early_buffered_lints::META_VARIABLE_MISUSE;
|
||||
use syntax::sess::ParseSess;
|
||||
use syntax::token::{DelimToken, Token, TokenKind};
|
||||
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_span::{symbol::Ident, MultiSpan, Span};
|
||||
use smallvec::SmallVec;
|
||||
|
||||
/// Stack represented as linked list.
|
||||
|
@ -696,7 +696,7 @@ pub(super) fn parse(
|
||||
if parser.token.span.is_dummy() {
|
||||
parser.token.span
|
||||
} else {
|
||||
sess.source_map().next_point(parser.token.span)
|
||||
parser.token.span.shrink_to_hi()
|
||||
},
|
||||
),
|
||||
"missing tokens in macro arguments",
|
||||
|
@ -190,6 +190,8 @@ pub fn prepare_session_directory(
|
||||
return;
|
||||
}
|
||||
|
||||
let _timer = sess.timer("incr_comp_prepare_session_directory");
|
||||
|
||||
debug!("prepare_session_directory");
|
||||
|
||||
// {incr-comp-dir}/{crate-name-and-disambiguator}
|
||||
@ -306,6 +308,8 @@ pub fn finalize_session_directory(sess: &Session, svh: Svh) {
|
||||
return;
|
||||
}
|
||||
|
||||
let _timer = sess.timer("incr_comp_finalize_session_directory");
|
||||
|
||||
let incr_comp_session_dir: PathBuf = sess.incr_comp_session_dir().clone();
|
||||
|
||||
if sess.has_errors_or_delayed_span_bugs() {
|
||||
|
@ -102,6 +102,8 @@ pub fn load_dep_graph(sess: &Session) -> DepGraphFuture {
|
||||
return MaybeAsync::Sync(LoadResult::Ok { data: Default::default() });
|
||||
}
|
||||
|
||||
let _timer = sess.prof.generic_activity("incr_comp_prepare_load_dep_graph");
|
||||
|
||||
// Calling `sess.incr_comp_session_dir()` will panic if `sess.opts.incremental.is_none()`.
|
||||
// Fortunately, we just checked that this isn't the case.
|
||||
let path = dep_graph_path_from(&sess.incr_comp_session_dir());
|
||||
|
@ -17,10 +17,12 @@ syntax = { path = "../libsyntax" }
|
||||
rustc_builtin_macros = { path = "../librustc_builtin_macros" }
|
||||
rustc_expand = { path = "../librustc_expand" }
|
||||
rustc_parse = { path = "../librustc_parse" }
|
||||
rustc_session = { path = "../librustc_session" }
|
||||
rustc_span = { path = "../librustc_span" }
|
||||
rustc_serialize = { path = "../libserialize", package = "serialize" }
|
||||
rustc = { path = "../librustc" }
|
||||
rustc_ast_lowering = { path = "../librustc_ast_lowering" }
|
||||
rustc_ast_passes = { path = "../librustc_ast_passes" }
|
||||
rustc_incremental = { path = "../librustc_incremental" }
|
||||
rustc_traits = { path = "../librustc_traits" }
|
||||
rustc_data_structures = { path = "../librustc_data_structures" }
|
||||
|
@ -177,11 +177,17 @@ pub fn run_compiler_in_existing_thread_pool<R>(
|
||||
override_queries: config.override_queries,
|
||||
};
|
||||
|
||||
let _sess_abort_error = OnDrop(|| {
|
||||
compiler.sess.diagnostic().print_error_count(registry);
|
||||
});
|
||||
let r = {
|
||||
let _sess_abort_error = OnDrop(|| {
|
||||
compiler.sess.diagnostic().print_error_count(registry);
|
||||
});
|
||||
|
||||
f(&compiler)
|
||||
f(&compiler)
|
||||
};
|
||||
|
||||
let prof = compiler.sess.prof.clone();
|
||||
prof.generic_activity("drop_compiler").run(move || drop(compiler));
|
||||
r
|
||||
}
|
||||
|
||||
pub fn run_compiler<R: Send>(mut config: Config, f: impl FnOnce(&Compiler) -> R + Send) -> R {
|
||||
|
@ -29,7 +29,7 @@ use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
|
||||
use rustc_incremental;
|
||||
use rustc_mir as mir;
|
||||
use rustc_parse::{parse_crate_from_file, parse_crate_from_source_str};
|
||||
use rustc_passes::{self, ast_validation, hir_stats, layout_test};
|
||||
use rustc_passes::{self, hir_stats, layout_test};
|
||||
use rustc_plugin_impl as plugin;
|
||||
use rustc_privacy;
|
||||
use rustc_resolve::{Resolver, ResolverArenas};
|
||||
@ -37,7 +37,6 @@ use rustc_span::symbol::Symbol;
|
||||
use rustc_span::FileName;
|
||||
use rustc_traits;
|
||||
use rustc_typeck as typeck;
|
||||
use syntax::early_buffered_lints::BufferedEarlyLint;
|
||||
use syntax::mut_visit::MutVisitor;
|
||||
use syntax::util::node_count::NodeCounter;
|
||||
use syntax::{self, ast, visit};
|
||||
@ -71,7 +70,7 @@ pub fn parse<'a>(sess: &'a Session, input: &Input) -> PResult<'a, ast::Crate> {
|
||||
}
|
||||
|
||||
if let Some(ref s) = sess.opts.debugging_opts.show_span {
|
||||
syntax::show_span::run(sess.diagnostic(), s, &krate);
|
||||
rustc_ast_passes::show_span::run(sess.diagnostic(), s, &krate);
|
||||
}
|
||||
|
||||
if sess.opts.debugging_opts.hir_stats {
|
||||
@ -345,7 +344,7 @@ fn configure_and_expand_inner<'a>(
|
||||
}
|
||||
|
||||
let has_proc_macro_decls = sess.time("AST_validation", || {
|
||||
ast_validation::check_crate(sess, &krate, &mut resolver.lint_buffer())
|
||||
rustc_ast_passes::ast_validation::check_crate(sess, &krate, &mut resolver.lint_buffer())
|
||||
});
|
||||
|
||||
let crate_types = sess.crate_types.borrow();
|
||||
@ -400,7 +399,7 @@ fn configure_and_expand_inner<'a>(
|
||||
|
||||
// Needs to go *after* expansion to be able to check the results of macro expansion.
|
||||
sess.time("complete_gated_feature_checking", || {
|
||||
syntax::feature_gate::check_crate(
|
||||
rustc_ast_passes::feature_gate::check_crate(
|
||||
&krate,
|
||||
&sess.parse_sess,
|
||||
&sess.features_untracked(),
|
||||
@ -411,8 +410,8 @@ fn configure_and_expand_inner<'a>(
|
||||
// Add all buffered lints from the `ParseSess` to the `Session`.
|
||||
sess.parse_sess.buffered_lints.with_lock(|buffered_lints| {
|
||||
info!("{} parse sess buffered_lints", buffered_lints.len());
|
||||
for BufferedEarlyLint { id, span, msg, lint_id } in buffered_lints.drain(..) {
|
||||
resolver.lint_buffer().buffer_lint(lint_id, id, span, &msg);
|
||||
for early_lint in buffered_lints.drain(..) {
|
||||
resolver.lint_buffer().add_early_lint(early_lint);
|
||||
}
|
||||
});
|
||||
|
||||
@ -611,6 +610,8 @@ pub fn prepare_outputs(
|
||||
boxed_resolver: &Steal<Rc<RefCell<BoxedResolver>>>,
|
||||
crate_name: &str,
|
||||
) -> Result<OutputFilenames> {
|
||||
let _timer = sess.timer("prepare_outputs");
|
||||
|
||||
// FIXME: rustdoc passes &[] instead of &krate.attrs here
|
||||
let outputs = util::build_output_filenames(
|
||||
&compiler.input,
|
||||
@ -734,20 +735,22 @@ pub fn create_global_ctxt<'tcx>(
|
||||
callback(sess, &mut local_providers, &mut extern_providers);
|
||||
}
|
||||
|
||||
let gcx = global_ctxt.init_locking(|| {
|
||||
TyCtxt::create_global_ctxt(
|
||||
sess,
|
||||
lint_store,
|
||||
local_providers,
|
||||
extern_providers,
|
||||
&all_arenas,
|
||||
arena,
|
||||
resolver_outputs,
|
||||
hir_map,
|
||||
query_result_on_disk_cache,
|
||||
&crate_name,
|
||||
&outputs,
|
||||
)
|
||||
let gcx = sess.time("setup_global_ctxt", || {
|
||||
global_ctxt.init_locking(|| {
|
||||
TyCtxt::create_global_ctxt(
|
||||
sess,
|
||||
lint_store,
|
||||
local_providers,
|
||||
extern_providers,
|
||||
&all_arenas,
|
||||
arena,
|
||||
resolver_outputs,
|
||||
hir_map,
|
||||
query_result_on_disk_cache,
|
||||
&crate_name,
|
||||
&outputs,
|
||||
)
|
||||
})
|
||||
});
|
||||
|
||||
// Do some initialization of the DepGraph that can only be done with the tcx available.
|
||||
|
@ -176,6 +176,7 @@ impl<'tcx> Queries<'tcx> {
|
||||
self.expansion.compute(|| {
|
||||
let crate_name = self.crate_name()?.peek().clone();
|
||||
let (krate, lint_store) = self.register_plugins()?.take();
|
||||
let _timer = self.session().timer("configure_and_expand");
|
||||
passes::configure_and_expand(
|
||||
self.session().clone(),
|
||||
lint_store.clone(),
|
||||
@ -256,6 +257,7 @@ impl<'tcx> Queries<'tcx> {
|
||||
let lint_store = self.expansion()?.peek().2.clone();
|
||||
let hir = self.lower_to_hir()?.peek();
|
||||
let (ref hir_forest, ref resolver_outputs) = &*hir;
|
||||
let _timer = self.session().timer("create_global_ctxt");
|
||||
Ok(passes::create_global_ctxt(
|
||||
self.compiler,
|
||||
lint_store,
|
||||
@ -312,14 +314,19 @@ pub struct Linker {
|
||||
|
||||
impl Linker {
|
||||
pub fn link(self) -> Result<()> {
|
||||
self.codegen_backend
|
||||
let r = self
|
||||
.codegen_backend
|
||||
.join_codegen_and_link(
|
||||
self.ongoing_codegen,
|
||||
&self.sess,
|
||||
&self.dep_graph,
|
||||
&self.prepare_outputs,
|
||||
)
|
||||
.map_err(|_| ErrorReported)
|
||||
.map_err(|_| ErrorReported);
|
||||
let prof = self.sess.prof.clone();
|
||||
let dep_graph = self.dep_graph;
|
||||
prof.generic_activity("drop_dep_graph").run(move || drop(dep_graph));
|
||||
r
|
||||
}
|
||||
}
|
||||
|
||||
@ -328,6 +335,7 @@ impl Compiler {
|
||||
where
|
||||
F: for<'tcx> FnOnce(&'tcx Queries<'tcx>) -> T,
|
||||
{
|
||||
let mut _timer = None;
|
||||
let queries = Queries::new(&self);
|
||||
let ret = f(&queries);
|
||||
|
||||
@ -337,6 +345,8 @@ impl Compiler {
|
||||
}
|
||||
}
|
||||
|
||||
_timer = Some(self.session().timer("free_global_ctxt"));
|
||||
|
||||
ret
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,5 @@
|
||||
use log::info;
|
||||
use rustc::lint;
|
||||
use rustc::session::config::{ErrorOutputType, Input, OutputFilenames};
|
||||
use rustc::session::CrateDisambiguator;
|
||||
use rustc::session::{self, config, early_error, filesearch, DiagnosticOutput, Session};
|
||||
use rustc::ty;
|
||||
use rustc_codegen_utils::codegen_backend::CodegenBackend;
|
||||
use rustc_data_structures::fingerprint::Fingerprint;
|
||||
@ -14,6 +11,11 @@ use rustc_data_structures::sync::{Lock, Lrc};
|
||||
use rustc_errors::registry::Registry;
|
||||
use rustc_metadata::dynamic_lib::DynamicLibrary;
|
||||
use rustc_resolve::{self, Resolver};
|
||||
use rustc_session as session;
|
||||
use rustc_session::config::{ErrorOutputType, Input, OutputFilenames};
|
||||
use rustc_session::lint::{BuiltinLintDiagnostics, LintBuffer};
|
||||
use rustc_session::CrateDisambiguator;
|
||||
use rustc_session::{config, early_error, filesearch, DiagnosticOutput, Session};
|
||||
use rustc_span::edition::Edition;
|
||||
use rustc_span::source_map::{FileLoader, RealFileLoader, SourceMap};
|
||||
use rustc_span::symbol::{sym, Symbol};
|
||||
@ -420,7 +422,7 @@ pub(crate) fn compute_crate_disambiguator(session: &Session) -> CrateDisambiguat
|
||||
CrateDisambiguator::from(hasher.finish::<Fingerprint>())
|
||||
}
|
||||
|
||||
pub(crate) fn check_attr_crate_type(attrs: &[ast::Attribute], lint_buffer: &mut lint::LintBuffer) {
|
||||
pub(crate) fn check_attr_crate_type(attrs: &[ast::Attribute], lint_buffer: &mut LintBuffer) {
|
||||
// Unconditionally collect crate types from attributes to make them used
|
||||
for a in attrs.iter() {
|
||||
if a.check_name(sym::crate_type) {
|
||||
@ -442,7 +444,7 @@ pub(crate) fn check_attr_crate_type(attrs: &[ast::Attribute], lint_buffer: &mut
|
||||
ast::CRATE_NODE_ID,
|
||||
span,
|
||||
"invalid `crate_type` value",
|
||||
lint::builtin::BuiltinLintDiagnostics::UnknownCrateTypes(
|
||||
BuiltinLintDiagnostics::UnknownCrateTypes(
|
||||
span,
|
||||
"did you mean".to_string(),
|
||||
format!("\"{}\"", candidate),
|
||||
|
@ -1,5 +1,4 @@
|
||||
use crate::lint::{LateContext, LateLintPass, LintArray, LintContext, LintPass};
|
||||
use rustc::lint::FutureIncompatibleInfo;
|
||||
use rustc::lint::{FutureIncompatibleInfo, LateContext, LateLintPass, LintContext};
|
||||
use rustc::ty;
|
||||
use rustc::ty::adjustment::{Adjust, Adjustment};
|
||||
use rustc_errors::Applicability;
|
||||
|
@ -21,13 +21,8 @@
|
||||
//! If you define a new `LateLintPass`, you will also need to add it to the
|
||||
//! `late_lint_methods!` invocation in `lib.rs`.
|
||||
|
||||
use std::fmt::Write;
|
||||
|
||||
use lint::{EarlyContext, EarlyLintPass, LateLintPass, LintPass};
|
||||
use lint::{LateContext, LintArray, LintContext};
|
||||
use rustc::hir::map::Map;
|
||||
use rustc::lint;
|
||||
use rustc::lint::FutureIncompatibleInfo;
|
||||
use rustc::lint::{self, EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
|
||||
use rustc::traits::misc::can_type_implement_copy;
|
||||
use rustc::ty::{self, layout::VariantIdx, Ty, TyCtxt};
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
@ -39,6 +34,7 @@ use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::{GenericParamKind, PatKind};
|
||||
use rustc_hir::{HirIdSet, Node};
|
||||
use rustc_session::lint::FutureIncompatibleInfo;
|
||||
use rustc_span::edition::Edition;
|
||||
use rustc_span::source_map::Spanned;
|
||||
use rustc_span::symbol::{kw, sym, Symbol};
|
||||
@ -52,6 +48,7 @@ use syntax::visit::FnKind;
|
||||
use crate::nonstandard_style::{method_context, MethodLateContext};
|
||||
|
||||
use log::debug;
|
||||
use std::fmt::Write;
|
||||
|
||||
// hardwired lints from librustc
|
||||
pub use lint::builtin::*;
|
||||
|
@ -16,15 +16,15 @@
|
||||
|
||||
use rustc::lint::{EarlyContext, LintStore};
|
||||
use rustc::lint::{EarlyLintPass, EarlyLintPassObject};
|
||||
use rustc::lint::{LintBuffer, LintContext, LintPass};
|
||||
use rustc::session::Session;
|
||||
|
||||
use rustc::lint::{LintContext, LintPass};
|
||||
use rustc_session::lint::LintBuffer;
|
||||
use rustc_session::Session;
|
||||
use rustc_span::Span;
|
||||
use std::slice;
|
||||
use syntax::ast;
|
||||
use syntax::visit as ast_visit;
|
||||
|
||||
use log::debug;
|
||||
use std::slice;
|
||||
|
||||
macro_rules! run_early_pass { ($cx:expr, $f:ident, $($args:expr),*) => ({
|
||||
$cx.pass.$f(&$cx.context, $($args),*);
|
||||
|
@ -16,7 +16,6 @@
|
||||
|
||||
use rustc::hir::map::Map;
|
||||
use rustc::lint::LateContext;
|
||||
use rustc::lint::LintPass;
|
||||
use rustc::lint::{LateLintPass, LateLintPassObject};
|
||||
use rustc::ty::{self, TyCtxt};
|
||||
use rustc_data_structures::sync::{join, par_iter, ParallelIterator};
|
||||
@ -24,12 +23,13 @@ use rustc_hir as hir;
|
||||
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
|
||||
use rustc_hir::intravisit as hir_visit;
|
||||
use rustc_hir::intravisit::Visitor;
|
||||
use rustc_session::lint::LintPass;
|
||||
use rustc_span::Span;
|
||||
use std::slice;
|
||||
use syntax::ast;
|
||||
use syntax::walk_list;
|
||||
|
||||
use log::debug;
|
||||
use syntax::walk_list;
|
||||
use std::slice;
|
||||
|
||||
macro_rules! lint_callback { ($cx:expr, $f:ident, $($args:expr),*) => ({
|
||||
$cx.pass.$f(&$cx.context, $($args),*);
|
||||
|
@ -38,11 +38,12 @@ use rustc::lint::builtin::{
|
||||
BARE_TRAIT_OBJECTS, ELIDED_LIFETIMES_IN_PATHS, EXPLICIT_OUTLIVES_REQUIREMENTS,
|
||||
INTRA_DOC_LINK_RESOLUTION_FAILURE, MISSING_DOC_CODE_EXAMPLES, PRIVATE_DOC_TESTS,
|
||||
};
|
||||
use rustc::lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass};
|
||||
use rustc::ty::query::Providers;
|
||||
use rustc::ty::TyCtxt;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_session::lint::{LintArray, LintPass};
|
||||
|
||||
use rustc_span::Span;
|
||||
use syntax::ast;
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::lint::{EarlyContext, EarlyLintPass, LintArray, LintContext, LintPass};
|
||||
use rustc::lint::{EarlyContext, EarlyLintPass, LintContext};
|
||||
use syntax::ast;
|
||||
|
||||
declare_lint! {
|
||||
|
@ -1,6 +1,4 @@
|
||||
use lint::{EarlyContext, LateContext, LintArray, LintContext};
|
||||
use lint::{EarlyLintPass, LateLintPass, LintPass};
|
||||
use rustc::lint;
|
||||
use rustc::lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
|
||||
use rustc::ty;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir as hir;
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::lint::{EarlyContext, EarlyLintPass, LintArray, LintContext, LintPass};
|
||||
use rustc::lint::{EarlyContext, EarlyLintPass, LintContext};
|
||||
use rustc_errors::Applicability;
|
||||
use syntax::ast::{ExprKind, Stmt, StmtKind};
|
||||
|
||||
|
@ -1,9 +1,6 @@
|
||||
#![allow(non_snake_case)]
|
||||
|
||||
use crate::hir::def_id::DefId;
|
||||
use lint::{LateContext, LintArray, LintContext};
|
||||
use lint::{LateLintPass, LintPass};
|
||||
use rustc::lint;
|
||||
use rustc::lint::{LateContext, LateLintPass, LintContext};
|
||||
use rustc::mir::interpret::{sign_extend, truncate};
|
||||
use rustc::ty::layout::{self, IntegerExt, LayoutOf, SizeSkeleton, VariantIdx};
|
||||
use rustc::ty::subst::SubstsRef;
|
||||
@ -11,6 +8,7 @@ use rustc::ty::{self, AdtKind, ParamEnv, Ty, TyCtxt};
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::{is_range_literal, ExprKind, Node};
|
||||
use rustc_index::vec::Idx;
|
||||
use rustc_span::source_map;
|
||||
|
@ -1,7 +1,5 @@
|
||||
use lint::{EarlyContext, LateContext, LintArray, LintContext};
|
||||
use lint::{EarlyLintPass, LateLintPass, LintPass};
|
||||
use rustc::lint;
|
||||
use rustc::lint::builtin::UNUSED_ATTRIBUTES;
|
||||
use rustc::lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
|
||||
use rustc::ty::adjustment;
|
||||
use rustc::ty::{self, Ty};
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
|
@ -1,4 +1,5 @@
|
||||
use rustc::middle::cstore::{self, NativeLibrary};
|
||||
use rustc::session::parse::feature_err;
|
||||
use rustc::session::Session;
|
||||
use rustc::ty::TyCtxt;
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
@ -10,7 +11,6 @@ use rustc_span::source_map::Span;
|
||||
use rustc_span::symbol::{kw, sym, Symbol};
|
||||
use rustc_target::spec::abi::Abi;
|
||||
use syntax::attr;
|
||||
use syntax::feature_gate::feature_err;
|
||||
|
||||
crate fn collect(tcx: TyCtxt<'_>) -> Vec<NativeLibrary> {
|
||||
let mut collector = Collector { tcx, libs: Vec::new() };
|
||||
|
@ -6,6 +6,7 @@ use super::{PatCtxt, PatKind, PatternError};
|
||||
|
||||
use rustc::hir::map::Map;
|
||||
use rustc::lint;
|
||||
use rustc::session::parse::feature_err;
|
||||
use rustc::session::Session;
|
||||
use rustc::ty::subst::{InternalSubsts, SubstsRef};
|
||||
use rustc::ty::{self, Ty, TyCtxt};
|
||||
@ -19,7 +20,6 @@ use rustc_hir::{HirId, Pat};
|
||||
use rustc_span::symbol::sym;
|
||||
use rustc_span::{MultiSpan, Span};
|
||||
use syntax::ast::Mutability;
|
||||
use syntax::feature_gate::feature_err;
|
||||
|
||||
use std::slice;
|
||||
|
||||
|
@ -1,12 +1,12 @@
|
||||
//! Concrete error types for all operations which may be invalid in a certain const context.
|
||||
|
||||
use rustc::session::config::nightly_options;
|
||||
use rustc::session::parse::feature_err;
|
||||
use rustc::ty::TyCtxt;
|
||||
use rustc_errors::struct_span_err;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_span::symbol::sym;
|
||||
use rustc_span::{Span, Symbol};
|
||||
use syntax::feature_gate::feature_err;
|
||||
|
||||
use super::{ConstKind, Item};
|
||||
|
||||
@ -350,16 +350,18 @@ impl NonConstOp for StaticAccess {
|
||||
item.tcx.sess,
|
||||
span,
|
||||
E0013,
|
||||
"{}s cannot refer to statics, use \
|
||||
a constant instead",
|
||||
"{}s cannot refer to statics",
|
||||
item.const_kind()
|
||||
);
|
||||
err.help(
|
||||
"consider extracting the value of the `static` to a `const`, and referring to that",
|
||||
);
|
||||
if item.tcx.sess.teach(&err.get_code().unwrap()) {
|
||||
err.note(
|
||||
"Static and const variables can refer to other const variables. \
|
||||
But a const variable cannot refer to a static variable.",
|
||||
"`static` and `const` variables can refer to other `const` variables. \
|
||||
A `const` variable, however, cannot refer to a `static` variable.",
|
||||
);
|
||||
err.help("To fix this, the value can be extracted as a const and then used.");
|
||||
err.help("To fix this, the value can be extracted to a `const` and then used.");
|
||||
}
|
||||
err.emit();
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ rustc_lexer = { path = "../librustc_lexer" }
|
||||
rustc_errors = { path = "../librustc_errors" }
|
||||
rustc_error_codes = { path = "../librustc_error_codes" }
|
||||
smallvec = { version = "1.0", features = ["union", "may_dangle"] }
|
||||
rustc_session = { path = "../librustc_session" }
|
||||
rustc_span = { path = "../librustc_span" }
|
||||
syntax = { path = "../libsyntax" }
|
||||
unicode-normalization = "0.1.11"
|
||||
|
@ -9,18 +9,22 @@
|
||||
//! [#64197]: https://github.com/rust-lang/rust/issues/64197
|
||||
|
||||
use crate::{parse_in, validate_attr};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_feature::Features;
|
||||
use rustc_span::edition::Edition;
|
||||
use rustc_span::symbol::sym;
|
||||
use rustc_span::Span;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_error_codes::*;
|
||||
use rustc_errors::{error_code, struct_span_err, Applicability, Handler};
|
||||
use rustc_feature::{Feature, Features, State as FeatureState};
|
||||
use rustc_feature::{
|
||||
ACCEPTED_FEATURES, ACTIVE_FEATURES, REMOVED_FEATURES, STABLE_REMOVED_FEATURES,
|
||||
};
|
||||
use rustc_span::edition::{Edition, ALL_EDITIONS};
|
||||
use rustc_span::symbol::{sym, Symbol};
|
||||
use rustc_span::{Span, DUMMY_SP};
|
||||
use syntax::ast::{self, AttrItem, Attribute, MetaItem};
|
||||
use syntax::attr;
|
||||
use syntax::attr::HasAttrs;
|
||||
use syntax::feature_gate::{feature_err, get_features};
|
||||
use syntax::mut_visit::*;
|
||||
use syntax::ptr::P;
|
||||
use syntax::sess::ParseSess;
|
||||
use syntax::sess::{feature_err, ParseSess};
|
||||
use syntax::util::map_in_place::MapInPlace;
|
||||
|
||||
use smallvec::SmallVec;
|
||||
@ -31,6 +35,172 @@ pub struct StripUnconfigured<'a> {
|
||||
pub features: Option<&'a Features>,
|
||||
}
|
||||
|
||||
fn get_features(
|
||||
span_handler: &Handler,
|
||||
krate_attrs: &[ast::Attribute],
|
||||
crate_edition: Edition,
|
||||
allow_features: &Option<Vec<String>>,
|
||||
) -> Features {
|
||||
fn feature_removed(span_handler: &Handler, span: Span, reason: Option<&str>) {
|
||||
let mut err = struct_span_err!(span_handler, span, E0557, "feature has been removed");
|
||||
err.span_label(span, "feature has been removed");
|
||||
if let Some(reason) = reason {
|
||||
err.note(reason);
|
||||
}
|
||||
err.emit();
|
||||
}
|
||||
|
||||
fn active_features_up_to(edition: Edition) -> impl Iterator<Item = &'static Feature> {
|
||||
ACTIVE_FEATURES.iter().filter(move |feature| {
|
||||
if let Some(feature_edition) = feature.edition {
|
||||
feature_edition <= edition
|
||||
} else {
|
||||
false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
let mut features = Features::default();
|
||||
let mut edition_enabled_features = FxHashMap::default();
|
||||
|
||||
for &edition in ALL_EDITIONS {
|
||||
if edition <= crate_edition {
|
||||
// The `crate_edition` implies its respective umbrella feature-gate
|
||||
// (i.e., `#![feature(rust_20XX_preview)]` isn't needed on edition 20XX).
|
||||
edition_enabled_features.insert(edition.feature_name(), edition);
|
||||
}
|
||||
}
|
||||
|
||||
for feature in active_features_up_to(crate_edition) {
|
||||
feature.set(&mut features, DUMMY_SP);
|
||||
edition_enabled_features.insert(feature.name, crate_edition);
|
||||
}
|
||||
|
||||
// Process the edition umbrella feature-gates first, to ensure
|
||||
// `edition_enabled_features` is completed before it's queried.
|
||||
for attr in krate_attrs {
|
||||
if !attr.check_name(sym::feature) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let list = match attr.meta_item_list() {
|
||||
Some(list) => list,
|
||||
None => continue,
|
||||
};
|
||||
|
||||
for mi in list {
|
||||
if !mi.is_word() {
|
||||
continue;
|
||||
}
|
||||
|
||||
let name = mi.name_or_empty();
|
||||
|
||||
let edition = ALL_EDITIONS.iter().find(|e| name == e.feature_name()).copied();
|
||||
if let Some(edition) = edition {
|
||||
if edition <= crate_edition {
|
||||
continue;
|
||||
}
|
||||
|
||||
for feature in active_features_up_to(edition) {
|
||||
// FIXME(Manishearth) there is currently no way to set
|
||||
// lib features by edition
|
||||
feature.set(&mut features, DUMMY_SP);
|
||||
edition_enabled_features.insert(feature.name, edition);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for attr in krate_attrs {
|
||||
if !attr.check_name(sym::feature) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let list = match attr.meta_item_list() {
|
||||
Some(list) => list,
|
||||
None => continue,
|
||||
};
|
||||
|
||||
let bad_input = |span| {
|
||||
struct_span_err!(span_handler, span, E0556, "malformed `feature` attribute input")
|
||||
};
|
||||
|
||||
for mi in list {
|
||||
let name = match mi.ident() {
|
||||
Some(ident) if mi.is_word() => ident.name,
|
||||
Some(ident) => {
|
||||
bad_input(mi.span())
|
||||
.span_suggestion(
|
||||
mi.span(),
|
||||
"expected just one word",
|
||||
format!("{}", ident.name),
|
||||
Applicability::MaybeIncorrect,
|
||||
)
|
||||
.emit();
|
||||
continue;
|
||||
}
|
||||
None => {
|
||||
bad_input(mi.span()).span_label(mi.span(), "expected just one word").emit();
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(edition) = edition_enabled_features.get(&name) {
|
||||
let msg =
|
||||
&format!("the feature `{}` is included in the Rust {} edition", name, edition);
|
||||
span_handler.struct_span_warn_with_code(mi.span(), msg, error_code!(E0705)).emit();
|
||||
continue;
|
||||
}
|
||||
|
||||
if ALL_EDITIONS.iter().any(|e| name == e.feature_name()) {
|
||||
// Handled in the separate loop above.
|
||||
continue;
|
||||
}
|
||||
|
||||
let removed = REMOVED_FEATURES.iter().find(|f| name == f.name);
|
||||
let stable_removed = STABLE_REMOVED_FEATURES.iter().find(|f| name == f.name);
|
||||
if let Some(Feature { state, .. }) = removed.or(stable_removed) {
|
||||
if let FeatureState::Removed { reason } | FeatureState::Stabilized { reason } =
|
||||
state
|
||||
{
|
||||
feature_removed(span_handler, mi.span(), *reason);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(Feature { since, .. }) = ACCEPTED_FEATURES.iter().find(|f| name == f.name) {
|
||||
let since = Some(Symbol::intern(since));
|
||||
features.declared_lang_features.push((name, mi.span(), since));
|
||||
continue;
|
||||
}
|
||||
|
||||
if let Some(allowed) = allow_features.as_ref() {
|
||||
if allowed.iter().find(|&f| name.as_str() == *f).is_none() {
|
||||
struct_span_err!(
|
||||
span_handler,
|
||||
mi.span(),
|
||||
E0725,
|
||||
"the feature `{}` is not in the list of allowed features",
|
||||
name
|
||||
)
|
||||
.emit();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(f) = ACTIVE_FEATURES.iter().find(|f| name == f.name) {
|
||||
f.set(&mut features, mi.span());
|
||||
features.declared_lang_features.push((name, mi.span(), None));
|
||||
continue;
|
||||
}
|
||||
|
||||
features.declared_lib_features.push((name, mi.span()));
|
||||
}
|
||||
}
|
||||
|
||||
features
|
||||
}
|
||||
|
||||
// `cfg_attr`-process the crate's attributes and compute the crate's features.
|
||||
pub fn features(
|
||||
mut krate: ast::Crate,
|
||||
|
@ -259,10 +259,7 @@ impl<'a> Parser<'a> {
|
||||
};
|
||||
(
|
||||
format!("expected one of {}, found {}", expect, actual),
|
||||
(
|
||||
self.sess.source_map().next_point(self.prev_span),
|
||||
format!("expected one of {}", short_expect),
|
||||
),
|
||||
(self.prev_span.shrink_to_hi(), format!("expected one of {}", short_expect)),
|
||||
)
|
||||
} else if expected.is_empty() {
|
||||
(
|
||||
@ -272,7 +269,7 @@ impl<'a> Parser<'a> {
|
||||
} else {
|
||||
(
|
||||
format!("expected {}, found {}", expect, actual),
|
||||
(self.sess.source_map().next_point(self.prev_span), format!("expected {}", expect)),
|
||||
(self.prev_span.shrink_to_hi(), format!("expected {}", expect)),
|
||||
)
|
||||
};
|
||||
self.last_unexpected_token_span = Some(self.token.span);
|
||||
@ -803,7 +800,7 @@ impl<'a> Parser<'a> {
|
||||
_ if self.prev_span == DUMMY_SP => (self.token.span, self.token.span),
|
||||
// EOF, don't want to point at the following char, but rather the last token.
|
||||
(token::Eof, None) => (self.prev_span, self.token.span),
|
||||
_ => (self.sess.source_map().next_point(self.prev_span), self.token.span),
|
||||
_ => (self.prev_span.shrink_to_hi(), self.token.span),
|
||||
};
|
||||
let msg = format!(
|
||||
"expected `{}`, found {}",
|
||||
@ -1126,7 +1123,7 @@ impl<'a> Parser<'a> {
|
||||
err.span_label(sp, "unclosed delimiter");
|
||||
}
|
||||
err.span_suggestion_short(
|
||||
self.sess.source_map().next_point(self.prev_span),
|
||||
self.prev_span.shrink_to_hi(),
|
||||
&format!("{} may belong here", delim.to_string()),
|
||||
delim.to_string(),
|
||||
Applicability::MaybeIncorrect,
|
||||
|
@ -1645,7 +1645,7 @@ impl<'a> Parser<'a> {
|
||||
// | |
|
||||
// | parsed until here as `"y" & X`
|
||||
err.span_suggestion_short(
|
||||
cm.next_point(arm_start_span),
|
||||
arm_start_span.shrink_to_hi(),
|
||||
"missing a comma here to end this `match` arm",
|
||||
",".to_owned(),
|
||||
Applicability::MachineApplicable,
|
||||
|
@ -1510,7 +1510,7 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
let sp = self.sess.source_map().next_point(self.prev_span);
|
||||
let sp = self.prev_span.shrink_to_hi();
|
||||
let mut err = self.struct_span_err(
|
||||
sp,
|
||||
&format!("expected `,`, or `}}`, found {}", super::token_descr(&self.token)),
|
||||
@ -1649,7 +1649,7 @@ impl<'a> Parser<'a> {
|
||||
// it's safe to peel off one character only when it has the close delim
|
||||
self.prev_span.with_lo(self.prev_span.hi() - BytePos(1))
|
||||
} else {
|
||||
self.sess.source_map().next_point(self.prev_span)
|
||||
self.prev_span.shrink_to_hi()
|
||||
};
|
||||
|
||||
self.struct_span_err(
|
||||
@ -1665,7 +1665,7 @@ impl<'a> Parser<'a> {
|
||||
Applicability::MaybeIncorrect,
|
||||
)
|
||||
.span_suggestion(
|
||||
self.sess.source_map().next_point(self.prev_span),
|
||||
self.prev_span.shrink_to_hi(),
|
||||
"add a semicolon",
|
||||
';'.to_string(),
|
||||
Applicability::MaybeIncorrect,
|
||||
|
@ -765,7 +765,7 @@ impl<'a> Parser<'a> {
|
||||
break;
|
||||
}
|
||||
Err(mut expect_err) => {
|
||||
let sp = self.sess.source_map().next_point(self.prev_span);
|
||||
let sp = self.prev_span.shrink_to_hi();
|
||||
let token_str = pprust::token_kind_to_string(t);
|
||||
|
||||
// Attempt to keep parsing if it was a similar separator.
|
||||
|
@ -4,10 +4,10 @@ use crate::parse_in;
|
||||
|
||||
use rustc_errors::{Applicability, PResult};
|
||||
use rustc_feature::{AttributeTemplate, BUILTIN_ATTRIBUTE_MAP};
|
||||
use rustc_session::lint::builtin::ILL_FORMED_ATTRIBUTE_INPUT;
|
||||
use rustc_session::parse::ParseSess;
|
||||
use rustc_span::{sym, Symbol};
|
||||
use syntax::ast::{self, Attribute, MacArgs, MacDelimiter, MetaItem, MetaItemKind};
|
||||
use syntax::early_buffered_lints::ILL_FORMED_ATTRIBUTE_INPUT;
|
||||
use syntax::sess::ParseSess;
|
||||
use syntax::tokenstream::DelimSpan;
|
||||
|
||||
pub fn check_meta(sess: &ParseSess, attr: &Attribute) {
|
||||
|
@ -16,7 +16,7 @@ rustc_errors = { path = "../librustc_errors" }
|
||||
rustc_feature = { path = "../librustc_feature" }
|
||||
rustc_hir = { path = "../librustc_hir" }
|
||||
rustc_index = { path = "../librustc_index" }
|
||||
rustc_parse = { path = "../librustc_parse" }
|
||||
rustc_session = { path = "../librustc_session" }
|
||||
rustc_target = { path = "../librustc_target" }
|
||||
syntax = { path = "../libsyntax" }
|
||||
rustc_span = { path = "../librustc_span" }
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
use rustc::hir::map::Map;
|
||||
use rustc::session::config::nightly_options;
|
||||
use rustc::session::parse::feature_err;
|
||||
use rustc::ty::query::Providers;
|
||||
use rustc::ty::TyCtxt;
|
||||
use rustc_error_codes::*;
|
||||
@ -18,7 +19,6 @@ use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
|
||||
use rustc_span::{sym, Span, Symbol};
|
||||
use syntax::ast::Mutability;
|
||||
use syntax::feature_gate::feature_err;
|
||||
|
||||
use std::fmt;
|
||||
|
||||
|
@ -17,7 +17,6 @@ extern crate log;
|
||||
|
||||
use rustc::ty::query::Providers;
|
||||
|
||||
pub mod ast_validation;
|
||||
mod check_const;
|
||||
pub mod dead;
|
||||
mod diagnostic_items;
|
||||
|
@ -5,6 +5,7 @@ use rustc::hir::map::Map;
|
||||
use rustc::lint;
|
||||
use rustc::middle::privacy::AccessLevels;
|
||||
use rustc::middle::stability::{DeprecationEntry, Index};
|
||||
use rustc::session::parse::feature_err;
|
||||
use rustc::session::Session;
|
||||
use rustc::traits::misc::can_type_implement_copy;
|
||||
use rustc::ty::query::Providers;
|
||||
@ -20,7 +21,6 @@ use rustc_span::symbol::{sym, Symbol};
|
||||
use rustc_span::Span;
|
||||
use syntax::ast::Attribute;
|
||||
use syntax::attr::{self, Stability};
|
||||
use syntax::feature_gate::feature_err;
|
||||
|
||||
use std::cmp::Ordering;
|
||||
use std::mem::replace;
|
||||
|
@ -652,6 +652,9 @@ impl EmbargoVisitor<'tcx> {
|
||||
if let Some(item) = module
|
||||
.res
|
||||
.and_then(|res| res.mod_def_id())
|
||||
// If the module is `self`, i.e. the current crate,
|
||||
// there will be no corresponding item.
|
||||
.filter(|def_id| def_id.index != CRATE_DEF_INDEX || def_id.krate != LOCAL_CRATE)
|
||||
.and_then(|def_id| self.tcx.hir().as_local_hir_id(def_id))
|
||||
.map(|module_hir_id| self.tcx.hir().expect_item(module_hir_id))
|
||||
{
|
||||
|
@ -29,6 +29,7 @@ use crate::Resolver;
|
||||
use rustc::{lint, ty};
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_errors::pluralize;
|
||||
use rustc_session::lint::BuiltinLintDiagnostics;
|
||||
use rustc_session::node_id::NodeMap;
|
||||
use rustc_span::{MultiSpan, Span, DUMMY_SP};
|
||||
use syntax::ast;
|
||||
@ -317,7 +318,7 @@ impl Resolver<'_> {
|
||||
unused.use_tree_id,
|
||||
ms,
|
||||
&msg,
|
||||
lint::builtin::BuiltinLintDiagnostics::UnusedImports(fix_msg.into(), fixes),
|
||||
BuiltinLintDiagnostics::UnusedImports(fix_msg.into(), fixes),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -12,9 +12,7 @@ use crate::{CrateLint, Module, ModuleOrUniformRoot, ParentScope, PerNS, ScopeSet
|
||||
use crate::{NameBinding, NameBindingKind, PathResult, PrivacyError, ToNameBinding};
|
||||
|
||||
use rustc::hir::exports::Export;
|
||||
use rustc::lint::builtin::BuiltinLintDiagnostics;
|
||||
use rustc::lint::builtin::{PUB_USE_OF_PRIVATE_EXTERN_CRATE, UNUSED_IMPORTS};
|
||||
use rustc::session::DiagnosticMessageId;
|
||||
use rustc::ty;
|
||||
use rustc::{bug, span_bug};
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
@ -22,6 +20,8 @@ use rustc_data_structures::ptr_key::PtrKey;
|
||||
use rustc_errors::{pluralize, struct_span_err, Applicability};
|
||||
use rustc_hir::def::{self, PartialRes};
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_session::lint::BuiltinLintDiagnostics;
|
||||
use rustc_session::DiagnosticMessageId;
|
||||
use rustc_span::hygiene::ExpnId;
|
||||
use rustc_span::symbol::kw;
|
||||
use rustc_span::{MultiSpan, Span};
|
||||
|
@ -24,7 +24,6 @@ use rustc::hir::exports::ExportMap;
|
||||
use rustc::hir::map::{DefKey, Definitions};
|
||||
use rustc::lint;
|
||||
use rustc::middle::cstore::{CrateStore, MetadataLoaderDyn};
|
||||
use rustc::session::Session;
|
||||
use rustc::span_bug;
|
||||
use rustc::ty::query::Providers;
|
||||
use rustc::ty::{self, DefIdTree, ResolverOutputs};
|
||||
@ -39,7 +38,9 @@ use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, CRATE_DEF_INDEX, LOCAL_CRATE}
|
||||
use rustc_hir::PrimTy::{self, Bool, Char, Float, Int, Str, Uint};
|
||||
use rustc_hir::{GlobMap, TraitMap};
|
||||
use rustc_metadata::creader::{CStore, CrateLoader};
|
||||
use rustc_session::lint::{BuiltinLintDiagnostics, LintBuffer};
|
||||
use rustc_session::node_id::{NodeMap, NodeSet};
|
||||
use rustc_session::Session;
|
||||
use rustc_span::hygiene::{ExpnId, ExpnKind, MacroKind, SyntaxContext, Transparency};
|
||||
use rustc_span::source_map::Spanned;
|
||||
use rustc_span::symbol::{kw, sym};
|
||||
@ -960,7 +961,7 @@ pub struct Resolver<'a> {
|
||||
/// when visiting the correspondent variants.
|
||||
variant_vis: DefIdMap<ty::Visibility>,
|
||||
|
||||
lint_buffer: lint::LintBuffer,
|
||||
lint_buffer: LintBuffer,
|
||||
|
||||
next_node_id: NodeId,
|
||||
}
|
||||
@ -1082,7 +1083,7 @@ impl rustc_ast_lowering::Resolver for Resolver<'_> {
|
||||
&mut self.definitions
|
||||
}
|
||||
|
||||
fn lint_buffer(&mut self) -> &mut lint::LintBuffer {
|
||||
fn lint_buffer(&mut self) -> &mut LintBuffer {
|
||||
&mut self.lint_buffer
|
||||
}
|
||||
|
||||
@ -1241,7 +1242,7 @@ impl<'a> Resolver<'a> {
|
||||
.chain(features.declared_lang_features.iter().map(|(feat, ..)| *feat))
|
||||
.collect(),
|
||||
variant_vis: Default::default(),
|
||||
lint_buffer: lint::LintBuffer::default(),
|
||||
lint_buffer: LintBuffer::default(),
|
||||
next_node_id: NodeId::from_u32(1),
|
||||
}
|
||||
}
|
||||
@ -1256,7 +1257,7 @@ impl<'a> Resolver<'a> {
|
||||
self.next_node_id
|
||||
}
|
||||
|
||||
pub fn lint_buffer(&mut self) -> &mut lint::LintBuffer {
|
||||
pub fn lint_buffer(&mut self) -> &mut LintBuffer {
|
||||
&mut self.lint_buffer
|
||||
}
|
||||
|
||||
@ -1713,10 +1714,10 @@ impl<'a> Resolver<'a> {
|
||||
if let Some(node_id) = poisoned {
|
||||
self.lint_buffer.buffer_lint_with_diagnostic(
|
||||
lint::builtin::PROC_MACRO_DERIVE_RESOLUTION_FALLBACK,
|
||||
node_id, ident.span,
|
||||
node_id,
|
||||
ident.span,
|
||||
&format!("cannot find {} `{}` in this scope", ns.descr(), ident),
|
||||
lint::builtin::BuiltinLintDiagnostics::
|
||||
ProcMacroDeriveResolutionFallback(ident.span),
|
||||
BuiltinLintDiagnostics::ProcMacroDeriveResolutionFallback(ident.span),
|
||||
);
|
||||
}
|
||||
return Some(LexicalScopeBinding::Item(binding));
|
||||
@ -2267,7 +2268,7 @@ impl<'a> Resolver<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
let diag = lint::builtin::BuiltinLintDiagnostics::AbsPathWithModule(diag_span);
|
||||
let diag = BuiltinLintDiagnostics::AbsPathWithModule(diag_span);
|
||||
self.lint_buffer.buffer_lint_with_diagnostic(
|
||||
lint::builtin::ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE,
|
||||
diag_id,
|
||||
@ -2562,9 +2563,10 @@ impl<'a> Resolver<'a> {
|
||||
cannot be referred to by absolute paths";
|
||||
self.lint_buffer.buffer_lint_with_diagnostic(
|
||||
lint::builtin::MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS,
|
||||
CRATE_NODE_ID, span_use, msg,
|
||||
lint::builtin::BuiltinLintDiagnostics::
|
||||
MacroExpandedMacroExportsAccessedByAbsolutePaths(span_def),
|
||||
CRATE_NODE_ID,
|
||||
span_use,
|
||||
msg,
|
||||
BuiltinLintDiagnostics::MacroExpandedMacroExportsAccessedByAbsolutePaths(span_def),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,7 @@ use crate::{AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, Determinacy};
|
||||
use crate::{CrateLint, ParentScope, ResolutionError, Resolver, Scope, ScopeSet, Weak};
|
||||
use crate::{ModuleKind, ModuleOrUniformRoot, NameBinding, PathResult, Segment, ToNameBinding};
|
||||
use rustc::middle::stability;
|
||||
use rustc::session::parse::feature_err;
|
||||
use rustc::session::Session;
|
||||
use rustc::{lint, span_bug, ty};
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
@ -23,7 +24,6 @@ use rustc_span::symbol::{kw, sym, Symbol};
|
||||
use rustc_span::{Span, DUMMY_SP};
|
||||
use syntax::ast::{self, Ident, NodeId};
|
||||
use syntax::attr::{self, StabilityLevel};
|
||||
use syntax::feature_gate::feature_err;
|
||||
use syntax::print::pprust;
|
||||
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
|
@ -10,6 +10,7 @@ path = "lib.rs"
|
||||
|
||||
[dependencies]
|
||||
log = "0.4"
|
||||
rustc_error_codes = { path = "../librustc_error_codes" }
|
||||
rustc_errors = { path = "../librustc_errors" }
|
||||
rustc_feature = { path = "../librustc_feature" }
|
||||
rustc_target = { path = "../librustc_target" }
|
||||
|
@ -1,8 +1,10 @@
|
||||
pub use self::Level::*;
|
||||
use crate::node_id::NodeId;
|
||||
use crate::node_id::{NodeId, NodeMap};
|
||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
|
||||
use rustc_span::edition::Edition;
|
||||
use rustc_span::{sym, MultiSpan, Symbol};
|
||||
use rustc_span::{sym, symbol::Ident, MultiSpan, Span, Symbol};
|
||||
|
||||
pub mod builtin;
|
||||
|
||||
/// Setting for how to handle a lint.
|
||||
#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]
|
||||
@ -174,7 +176,25 @@ impl<HCX> ToStableHashKey<HCX> for LintId {
|
||||
}
|
||||
}
|
||||
|
||||
/// Stores buffered lint info which can later be passed to `librustc`.
|
||||
// This could be a closure, but then implementing derive trait
|
||||
// becomes hacky (and it gets allocated).
|
||||
#[derive(PartialEq)]
|
||||
pub enum BuiltinLintDiagnostics {
|
||||
Normal,
|
||||
BareTraitObject(Span, /* is_global */ bool),
|
||||
AbsPathWithModule(Span),
|
||||
ProcMacroDeriveResolutionFallback(Span),
|
||||
MacroExpandedMacroExportsAccessedByAbsolutePaths(Span),
|
||||
ElidedLifetimesInPaths(usize, Span, bool, Span, String),
|
||||
UnknownCrateTypes(Span, String, String),
|
||||
UnusedImports(String, Vec<(Span, String)>),
|
||||
RedundantImport(Vec<(Span, bool)>, Ident),
|
||||
DeprecatedMacro(Option<Symbol>, Span),
|
||||
}
|
||||
|
||||
/// Lints that are buffered up early on in the `Session` before the
|
||||
/// `LintLevels` is calculated. These are later passed to `librustc`.
|
||||
#[derive(PartialEq)]
|
||||
pub struct BufferedEarlyLint {
|
||||
/// The span of code that we are linting on.
|
||||
pub span: MultiSpan,
|
||||
@ -183,10 +203,65 @@ pub struct BufferedEarlyLint {
|
||||
pub msg: String,
|
||||
|
||||
/// The `NodeId` of the AST node that generated the lint.
|
||||
pub id: NodeId,
|
||||
pub node_id: NodeId,
|
||||
|
||||
/// A lint Id that can be passed to `rustc::lint::Lint::from_parser_lint_id`.
|
||||
pub lint_id: &'static Lint,
|
||||
pub lint_id: LintId,
|
||||
|
||||
/// Customization of the `DiagnosticBuilder<'_>` for the lint.
|
||||
pub diagnostic: BuiltinLintDiagnostics,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct LintBuffer {
|
||||
pub map: NodeMap<Vec<BufferedEarlyLint>>,
|
||||
}
|
||||
|
||||
impl LintBuffer {
|
||||
pub fn add_early_lint(&mut self, early_lint: BufferedEarlyLint) {
|
||||
let arr = self.map.entry(early_lint.node_id).or_default();
|
||||
if !arr.contains(&early_lint) {
|
||||
arr.push(early_lint);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_lint(
|
||||
&mut self,
|
||||
lint: &'static Lint,
|
||||
node_id: NodeId,
|
||||
span: MultiSpan,
|
||||
msg: &str,
|
||||
diagnostic: BuiltinLintDiagnostics,
|
||||
) {
|
||||
let lint_id = LintId::of(lint);
|
||||
let msg = msg.to_string();
|
||||
self.add_early_lint(BufferedEarlyLint { lint_id, node_id, span, msg, diagnostic });
|
||||
}
|
||||
|
||||
pub fn take(&mut self, id: NodeId) -> Vec<BufferedEarlyLint> {
|
||||
self.map.remove(&id).unwrap_or_default()
|
||||
}
|
||||
|
||||
pub fn buffer_lint(
|
||||
&mut self,
|
||||
lint: &'static Lint,
|
||||
id: NodeId,
|
||||
sp: impl Into<MultiSpan>,
|
||||
msg: &str,
|
||||
) {
|
||||
self.add_lint(lint, id, sp.into(), msg, BuiltinLintDiagnostics::Normal)
|
||||
}
|
||||
|
||||
pub fn buffer_lint_with_diagnostic(
|
||||
&mut self,
|
||||
lint: &'static Lint,
|
||||
id: NodeId,
|
||||
sp: impl Into<MultiSpan>,
|
||||
msg: &str,
|
||||
diagnostic: BuiltinLintDiagnostics,
|
||||
) {
|
||||
self.add_lint(lint, id, sp.into(), msg, diagnostic)
|
||||
}
|
||||
}
|
||||
|
||||
/// Declares a static item of type `&'static Lint`.
|
||||
@ -253,3 +328,41 @@ macro_rules! declare_tool_lint {
|
||||
};
|
||||
);
|
||||
}
|
||||
|
||||
/// Declares a static `LintArray` and return it as an expression.
|
||||
#[macro_export]
|
||||
macro_rules! lint_array {
|
||||
($( $lint:expr ),* ,) => { lint_array!( $($lint),* ) };
|
||||
($( $lint:expr ),*) => {{
|
||||
vec![$($lint),*]
|
||||
}}
|
||||
}
|
||||
|
||||
pub type LintArray = Vec<&'static Lint>;
|
||||
|
||||
pub trait LintPass {
|
||||
fn name(&self) -> &'static str;
|
||||
}
|
||||
|
||||
/// Implements `LintPass for $name` with the given list of `Lint` statics.
|
||||
#[macro_export]
|
||||
macro_rules! impl_lint_pass {
|
||||
($name:ident => [$($lint:expr),* $(,)?]) => {
|
||||
impl $crate::lint::LintPass for $name {
|
||||
fn name(&self) -> &'static str { stringify!($name) }
|
||||
}
|
||||
impl $name {
|
||||
pub fn get_lints() -> $crate::lint::LintArray { $crate::lint_array!($($lint),*) }
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Declares a type named `$name` which implements `LintPass`.
|
||||
/// To the right of `=>` a comma separated list of `Lint` statics is given.
|
||||
#[macro_export]
|
||||
macro_rules! declare_lint_pass {
|
||||
($(#[$m:meta])* $name:ident => [$($lint:expr),* $(,)?]) => {
|
||||
$(#[$m])* #[derive(Copy, Clone)] pub struct $name;
|
||||
$crate::impl_lint_pass!($name => [$($lint),*]);
|
||||
};
|
||||
}
|
||||
|
@ -4,16 +4,31 @@
|
||||
//! compiler code, rather than using their own custom pass. Those
|
||||
//! lints are all available in `rustc_lint::builtin`.
|
||||
|
||||
use crate::lint::{FutureIncompatibleInfo, LateLintPass, LintArray, LintPass};
|
||||
use crate::middle::stability;
|
||||
use crate::session::Session;
|
||||
use rustc_errors::{pluralize, Applicability, DiagnosticBuilder};
|
||||
use rustc_session::declare_lint;
|
||||
use crate::lint::FutureIncompatibleInfo;
|
||||
use crate::{declare_lint, declare_lint_pass};
|
||||
use rustc_span::edition::Edition;
|
||||
use rustc_span::source_map::Span;
|
||||
use rustc_span::symbol::Symbol;
|
||||
use syntax::ast;
|
||||
use syntax::early_buffered_lints::{ILL_FORMED_ATTRIBUTE_INPUT, META_VARIABLE_MISUSE};
|
||||
|
||||
declare_lint! {
|
||||
pub ILL_FORMED_ATTRIBUTE_INPUT,
|
||||
Deny,
|
||||
"ill-formed attribute inputs that were previously accepted and used in practice",
|
||||
@future_incompatible = FutureIncompatibleInfo {
|
||||
reference: "issue #57571 <https://github.com/rust-lang/rust/issues/57571>",
|
||||
edition: None,
|
||||
};
|
||||
}
|
||||
|
||||
declare_lint! {
|
||||
pub META_VARIABLE_MISUSE,
|
||||
Allow,
|
||||
"possible meta-variable misuse at macro definition"
|
||||
}
|
||||
|
||||
declare_lint! {
|
||||
pub INCOMPLETE_INCLUDE,
|
||||
Deny,
|
||||
"trailing content in included file"
|
||||
}
|
||||
|
||||
declare_lint! {
|
||||
pub EXCEEDING_BITSHIFTS,
|
||||
@ -513,145 +528,3 @@ declare_lint_pass! {
|
||||
SOFT_UNSTABLE,
|
||||
]
|
||||
}
|
||||
|
||||
// this could be a closure, but then implementing derive traits
|
||||
// becomes hacky (and it gets allocated)
|
||||
#[derive(PartialEq, RustcEncodable, RustcDecodable, Debug)]
|
||||
pub enum BuiltinLintDiagnostics {
|
||||
Normal,
|
||||
BareTraitObject(Span, /* is_global */ bool),
|
||||
AbsPathWithModule(Span),
|
||||
ProcMacroDeriveResolutionFallback(Span),
|
||||
MacroExpandedMacroExportsAccessedByAbsolutePaths(Span),
|
||||
ElidedLifetimesInPaths(usize, Span, bool, Span, String),
|
||||
UnknownCrateTypes(Span, String, String),
|
||||
UnusedImports(String, Vec<(Span, String)>),
|
||||
RedundantImport(Vec<(Span, bool)>, ast::Ident),
|
||||
DeprecatedMacro(Option<Symbol>, Span),
|
||||
}
|
||||
|
||||
pub fn add_elided_lifetime_in_path_suggestion(
|
||||
sess: &Session,
|
||||
db: &mut DiagnosticBuilder<'_>,
|
||||
n: usize,
|
||||
path_span: Span,
|
||||
incl_angl_brckt: bool,
|
||||
insertion_span: Span,
|
||||
anon_lts: String,
|
||||
) {
|
||||
let (replace_span, suggestion) = if incl_angl_brckt {
|
||||
(insertion_span, anon_lts)
|
||||
} else {
|
||||
// When possible, prefer a suggestion that replaces the whole
|
||||
// `Path<T>` expression with `Path<'_, T>`, rather than inserting `'_, `
|
||||
// at a point (which makes for an ugly/confusing label)
|
||||
if let Ok(snippet) = sess.source_map().span_to_snippet(path_span) {
|
||||
// But our spans can get out of whack due to macros; if the place we think
|
||||
// we want to insert `'_` isn't even within the path expression's span, we
|
||||
// should bail out of making any suggestion rather than panicking on a
|
||||
// subtract-with-overflow or string-slice-out-out-bounds (!)
|
||||
// FIXME: can we do better?
|
||||
if insertion_span.lo().0 < path_span.lo().0 {
|
||||
return;
|
||||
}
|
||||
let insertion_index = (insertion_span.lo().0 - path_span.lo().0) as usize;
|
||||
if insertion_index > snippet.len() {
|
||||
return;
|
||||
}
|
||||
let (before, after) = snippet.split_at(insertion_index);
|
||||
(path_span, format!("{}{}{}", before, anon_lts, after))
|
||||
} else {
|
||||
(insertion_span, anon_lts)
|
||||
}
|
||||
};
|
||||
db.span_suggestion(
|
||||
replace_span,
|
||||
&format!("indicate the anonymous lifetime{}", pluralize!(n)),
|
||||
suggestion,
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
}
|
||||
|
||||
impl BuiltinLintDiagnostics {
|
||||
pub fn run(self, sess: &Session, db: &mut DiagnosticBuilder<'_>) {
|
||||
match self {
|
||||
BuiltinLintDiagnostics::Normal => (),
|
||||
BuiltinLintDiagnostics::BareTraitObject(span, is_global) => {
|
||||
let (sugg, app) = match sess.source_map().span_to_snippet(span) {
|
||||
Ok(ref s) if is_global => {
|
||||
(format!("dyn ({})", s), Applicability::MachineApplicable)
|
||||
}
|
||||
Ok(s) => (format!("dyn {}", s), Applicability::MachineApplicable),
|
||||
Err(_) => ("dyn <type>".to_string(), Applicability::HasPlaceholders),
|
||||
};
|
||||
db.span_suggestion(span, "use `dyn`", sugg, app);
|
||||
}
|
||||
BuiltinLintDiagnostics::AbsPathWithModule(span) => {
|
||||
let (sugg, app) = match sess.source_map().span_to_snippet(span) {
|
||||
Ok(ref s) => {
|
||||
// FIXME(Manishearth) ideally the emitting code
|
||||
// can tell us whether or not this is global
|
||||
let opt_colon = if s.trim_start().starts_with("::") { "" } else { "::" };
|
||||
|
||||
(format!("crate{}{}", opt_colon, s), Applicability::MachineApplicable)
|
||||
}
|
||||
Err(_) => ("crate::<path>".to_string(), Applicability::HasPlaceholders),
|
||||
};
|
||||
db.span_suggestion(span, "use `crate`", sugg, app);
|
||||
}
|
||||
BuiltinLintDiagnostics::ProcMacroDeriveResolutionFallback(span) => {
|
||||
db.span_label(
|
||||
span,
|
||||
"names from parent modules are not \
|
||||
accessible without an explicit import",
|
||||
);
|
||||
}
|
||||
BuiltinLintDiagnostics::MacroExpandedMacroExportsAccessedByAbsolutePaths(span_def) => {
|
||||
db.span_note(span_def, "the macro is defined here");
|
||||
}
|
||||
BuiltinLintDiagnostics::ElidedLifetimesInPaths(
|
||||
n,
|
||||
path_span,
|
||||
incl_angl_brckt,
|
||||
insertion_span,
|
||||
anon_lts,
|
||||
) => {
|
||||
add_elided_lifetime_in_path_suggestion(
|
||||
sess,
|
||||
db,
|
||||
n,
|
||||
path_span,
|
||||
incl_angl_brckt,
|
||||
insertion_span,
|
||||
anon_lts,
|
||||
);
|
||||
}
|
||||
BuiltinLintDiagnostics::UnknownCrateTypes(span, note, sugg) => {
|
||||
db.span_suggestion(span, ¬e, sugg, Applicability::MaybeIncorrect);
|
||||
}
|
||||
BuiltinLintDiagnostics::UnusedImports(message, replaces) => {
|
||||
if !replaces.is_empty() {
|
||||
db.tool_only_multipart_suggestion(
|
||||
&message,
|
||||
replaces,
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
}
|
||||
}
|
||||
BuiltinLintDiagnostics::RedundantImport(spans, ident) => {
|
||||
for (span, is_imported) in spans {
|
||||
let introduced = if is_imported { "imported" } else { "defined" };
|
||||
db.span_label(
|
||||
span,
|
||||
format!("the item `{}` is already {} here", ident, introduced),
|
||||
);
|
||||
}
|
||||
}
|
||||
BuiltinLintDiagnostics::DeprecatedMacro(suggestion, span) => {
|
||||
stability::deprecation_suggestion(db, suggestion, span)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for HardwiredLints {}
|
@ -1,15 +1,15 @@
|
||||
//! Contains `ParseSess` which holds state living beyond what one `Parser` might.
|
||||
//! It also serves as an input to the parser itself.
|
||||
|
||||
use crate::lint::BufferedEarlyLint;
|
||||
use crate::lint::{BufferedEarlyLint, BuiltinLintDiagnostics, Lint, LintId};
|
||||
use crate::node_id::NodeId;
|
||||
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_data_structures::sync::{Lock, Lrc, Once};
|
||||
use rustc_errors::{
|
||||
emitter::SilentEmitter, Applicability, ColorConfig, DiagnosticBuilder, Handler,
|
||||
};
|
||||
use rustc_feature::UnstableFeatures;
|
||||
use rustc_error_codes::E0658;
|
||||
use rustc_errors::{emitter::SilentEmitter, ColorConfig, Handler};
|
||||
use rustc_errors::{error_code, Applicability, DiagnosticBuilder};
|
||||
use rustc_feature::{find_feature_issue, GateIssue, UnstableFeatures};
|
||||
use rustc_span::edition::Edition;
|
||||
use rustc_span::hygiene::ExpnId;
|
||||
use rustc_span::source_map::{FilePathMapping, SourceMap};
|
||||
@ -62,6 +62,81 @@ impl GatedSpans {
|
||||
}
|
||||
}
|
||||
|
||||
/// The strenght of a feature gate.
|
||||
/// Either it is a `Hard` error, or only a `Soft` warning.
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub enum GateStrength {
|
||||
/// A hard error. (Most feature gates should use this.)
|
||||
Hard,
|
||||
/// Only a warning. (Use this only as backwards-compatibility demands.)
|
||||
Soft,
|
||||
}
|
||||
|
||||
/// Construct a diagnostic for a language feature error due to the given `span`.
|
||||
/// The `feature`'s `Symbol` is the one you used in `active.rs` and `rustc_span::symbols`.
|
||||
pub fn feature_err<'a>(
|
||||
sess: &'a ParseSess,
|
||||
feature: Symbol,
|
||||
span: impl Into<MultiSpan>,
|
||||
explain: &str,
|
||||
) -> DiagnosticBuilder<'a> {
|
||||
feature_err_issue(sess, feature, span, GateIssue::Language, explain)
|
||||
}
|
||||
|
||||
/// Construct a diagnostic for a feature gate error.
|
||||
///
|
||||
/// This variant allows you to control whether it is a library or language feature.
|
||||
/// Almost always, you want to use this for a language feature. If so, prefer `feature_err`.
|
||||
pub fn feature_err_issue<'a>(
|
||||
sess: &'a ParseSess,
|
||||
feature: Symbol,
|
||||
span: impl Into<MultiSpan>,
|
||||
issue: GateIssue,
|
||||
explain: &str,
|
||||
) -> DiagnosticBuilder<'a> {
|
||||
leveled_feature_err(sess, feature, span, issue, explain, GateStrength::Hard)
|
||||
}
|
||||
|
||||
/// Construct a diagnostic for a feature gate error / warning.
|
||||
///
|
||||
/// You should typically just use `feature_err` instead.
|
||||
pub fn leveled_feature_err<'a>(
|
||||
sess: &'a ParseSess,
|
||||
feature: Symbol,
|
||||
span: impl Into<MultiSpan>,
|
||||
issue: GateIssue,
|
||||
explain: &str,
|
||||
level: GateStrength,
|
||||
) -> DiagnosticBuilder<'a> {
|
||||
let diag = &sess.span_diagnostic;
|
||||
|
||||
let mut err = match level {
|
||||
GateStrength::Hard => diag.struct_span_err_with_code(span, explain, error_code!(E0658)),
|
||||
GateStrength::Soft => diag.struct_span_warn(span, explain),
|
||||
};
|
||||
|
||||
if let Some(n) = find_feature_issue(feature, issue) {
|
||||
err.note(&format!(
|
||||
"for more information, see https://github.com/rust-lang/rust/issues/{}",
|
||||
n,
|
||||
));
|
||||
}
|
||||
|
||||
// #23973: do not suggest `#![feature(...)]` if we are in beta/stable
|
||||
if sess.unstable_features.is_nightly_build() {
|
||||
err.help(&format!("add `#![feature({})]` to the crate attributes to enable", feature));
|
||||
}
|
||||
|
||||
// If we're on stable and only emitting a "soft" warning, add a note to
|
||||
// clarify that the feature isn't "on" (rather than being on but
|
||||
// warning-worthy).
|
||||
if !sess.unstable_features.is_nightly_build() && level == GateStrength::Soft {
|
||||
err.help("a nightly build of the compiler is required to enable this feature");
|
||||
}
|
||||
|
||||
err
|
||||
}
|
||||
|
||||
/// Info about a parsing session.
|
||||
pub struct ParseSess {
|
||||
pub span_diagnostic: Handler,
|
||||
@ -123,17 +198,18 @@ impl ParseSess {
|
||||
|
||||
pub fn buffer_lint(
|
||||
&self,
|
||||
lint_id: &'static crate::lint::Lint,
|
||||
lint: &'static Lint,
|
||||
span: impl Into<MultiSpan>,
|
||||
id: NodeId,
|
||||
node_id: NodeId,
|
||||
msg: &str,
|
||||
) {
|
||||
self.buffered_lints.with_lock(|buffered_lints| {
|
||||
buffered_lints.push(BufferedEarlyLint {
|
||||
span: span.into(),
|
||||
id,
|
||||
node_id,
|
||||
msg: msg.into(),
|
||||
lint_id,
|
||||
lint_id: LintId::of(lint),
|
||||
diagnostic: BuiltinLintDiagnostics::Normal,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -710,7 +710,7 @@ impl SourceMap {
|
||||
pub fn next_point(&self, sp: Span) -> Span {
|
||||
let start_of_next_point = sp.hi().0;
|
||||
|
||||
let width = self.find_width_of_character_at_span(sp, true);
|
||||
let width = self.find_width_of_character_at_span(sp.shrink_to_hi(), true);
|
||||
// If the width is 1, then the next span should point to the same `lo` and `hi`. However,
|
||||
// in the case of a multibyte character, where the width != 1, the next span should
|
||||
// span multiple bytes to include the whole character.
|
||||
|
@ -10,6 +10,7 @@ use crate::namespace::Namespace;
|
||||
use crate::require_c_abi_if_c_variadic;
|
||||
use crate::util::common::ErrorReported;
|
||||
use rustc::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS;
|
||||
use rustc::session::parse::feature_err;
|
||||
use rustc::traits;
|
||||
use rustc::traits::astconv_object_safety_violations;
|
||||
use rustc::traits::error_reporting::report_object_safety_error;
|
||||
@ -30,7 +31,6 @@ use rustc_span::{MultiSpan, Span, DUMMY_SP};
|
||||
use rustc_target::spec::abi;
|
||||
use smallvec::SmallVec;
|
||||
use syntax::ast;
|
||||
use syntax::feature_gate::feature_err;
|
||||
use syntax::util::lev_distance::find_best_match_for_name;
|
||||
|
||||
use std::collections::BTreeSet;
|
||||
|
@ -240,7 +240,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
) = (parent_node, callee_node)
|
||||
{
|
||||
let start = sp.shrink_to_lo();
|
||||
let end = self.tcx.sess.source_map().next_point(callee_span);
|
||||
let end = callee_span.shrink_to_hi();
|
||||
err.multipart_suggestion(
|
||||
"if you meant to create this closure and immediately call it, surround the \
|
||||
closure with parenthesis",
|
||||
@ -317,9 +317,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
let call_is_multiline =
|
||||
self.tcx.sess.source_map().is_multiline(call_expr.span);
|
||||
if call_is_multiline {
|
||||
let span = self.tcx.sess.source_map().next_point(callee.span);
|
||||
err.span_suggestion(
|
||||
span,
|
||||
callee.span.shrink_to_hi(),
|
||||
"try adding a semicolon",
|
||||
";".to_owned(),
|
||||
Applicability::MaybeIncorrect,
|
||||
|
@ -53,6 +53,7 @@
|
||||
use crate::check::{FnCtxt, Needs};
|
||||
use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
||||
use rustc::infer::{Coercion, InferOk, InferResult};
|
||||
use rustc::session::parse::feature_err;
|
||||
use rustc::traits::{self, ObligationCause, ObligationCauseCode};
|
||||
use rustc::ty::adjustment::{
|
||||
Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, PointerCast,
|
||||
@ -62,6 +63,7 @@ use rustc::ty::fold::TypeFoldable;
|
||||
use rustc::ty::relate::RelateResult;
|
||||
use rustc::ty::subst::SubstsRef;
|
||||
use rustc::ty::{self, Ty, TypeAndMut};
|
||||
use rustc_error_codes::*;
|
||||
use rustc_errors::{struct_span_err, DiagnosticBuilder};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::DefId;
|
||||
@ -70,9 +72,6 @@ use rustc_span::symbol::sym;
|
||||
use rustc_target::spec::abi::Abi;
|
||||
use smallvec::{smallvec, SmallVec};
|
||||
use std::ops::Deref;
|
||||
use syntax::feature_gate;
|
||||
|
||||
use rustc_error_codes::*;
|
||||
|
||||
struct Coerce<'a, 'tcx> {
|
||||
fcx: &'a FnCtxt<'a, 'tcx>,
|
||||
@ -627,7 +626,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
}
|
||||
|
||||
if has_unsized_tuple_coercion && !self.tcx.features().unsized_tuple_coercion {
|
||||
feature_gate::feature_err(
|
||||
feature_err(
|
||||
&self.tcx.sess.parse_sess,
|
||||
sym::unsized_tuple_coercion,
|
||||
self.cause.span,
|
||||
|
@ -99,6 +99,7 @@ use rustc::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
|
||||
use rustc::infer::{self, InferCtxt, InferOk, InferResult};
|
||||
use rustc::middle::region;
|
||||
use rustc::mir::interpret::ConstValue;
|
||||
use rustc::session::parse::feature_err;
|
||||
use rustc::traits::error_reporting::recursive_type_with_infinite_size_error;
|
||||
use rustc::traits::{self, ObligationCause, ObligationCauseCode, TraitEngine};
|
||||
use rustc::ty::adjustment::{
|
||||
@ -130,7 +131,6 @@ use rustc_span::{self, BytePos, MultiSpan, Span};
|
||||
use rustc_target::spec::abi::Abi;
|
||||
use syntax::ast;
|
||||
use syntax::attr;
|
||||
use syntax::feature_gate::feature_err;
|
||||
use syntax::util::parser::ExprPrecedence;
|
||||
|
||||
use rustc_error_codes::*;
|
||||
@ -4952,9 +4952,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
| ExprKind::Loop(..)
|
||||
| ExprKind::Match(..)
|
||||
| ExprKind::Block(..) => {
|
||||
let sp = self.tcx.sess.source_map().next_point(cause_span);
|
||||
err.span_suggestion(
|
||||
sp,
|
||||
cause_span.shrink_to_hi(),
|
||||
"try adding a semicolon",
|
||||
";".to_string(),
|
||||
Applicability::MachineApplicable,
|
||||
|
@ -3,6 +3,7 @@ use crate::constrained_generic_params::{identify_constrained_generic_params, Par
|
||||
|
||||
use rustc::infer::opaque_types::may_define_opaque_type;
|
||||
use rustc::middle::lang_items;
|
||||
use rustc::session::parse::feature_err;
|
||||
use rustc::traits::{self, ObligationCause, ObligationCauseCode};
|
||||
use rustc::ty::subst::{InternalSubsts, Subst};
|
||||
use rustc::ty::{self, AdtKind, GenericParamDefKind, ToPredicate, Ty, TyCtxt, TypeFoldable};
|
||||
@ -13,7 +14,6 @@ use rustc_hir::ItemKind;
|
||||
use rustc_span::symbol::sym;
|
||||
use rustc_span::Span;
|
||||
use syntax::ast;
|
||||
use syntax::feature_gate;
|
||||
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::itemlikevisit::ParItemLikeVisitor;
|
||||
@ -821,7 +821,7 @@ fn check_method_receiver<'fcx, 'tcx>(
|
||||
if !receiver_is_valid(fcx, span, receiver_ty, self_ty, false) {
|
||||
if receiver_is_valid(fcx, span, receiver_ty, self_ty, true) {
|
||||
// Report error; would have worked with `arbitrary_self_types`.
|
||||
feature_gate::feature_err(
|
||||
feature_err(
|
||||
&fcx.tcx.sess.parse_sess,
|
||||
sym::arbitrary_self_types,
|
||||
span,
|
||||
|
@ -23,6 +23,7 @@ use crate::middle::weak_lang_items;
|
||||
use rustc::hir::map::Map;
|
||||
use rustc::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
|
||||
use rustc::mir::mono::Linkage;
|
||||
use rustc::session::parse::feature_err;
|
||||
use rustc::traits;
|
||||
use rustc::ty::query::Providers;
|
||||
use rustc::ty::subst::GenericArgKind;
|
||||
@ -45,7 +46,6 @@ use rustc_target::spec::abi;
|
||||
use syntax::ast;
|
||||
use syntax::ast::{Ident, MetaItemKind};
|
||||
use syntax::attr::{list_contains_name, mark_used, InlineAttr, OptimizeAttr};
|
||||
use syntax::feature_gate;
|
||||
|
||||
use rustc_error_codes::*;
|
||||
|
||||
@ -1537,7 +1537,7 @@ fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
|
||||
_ => None,
|
||||
};
|
||||
if let Some(unsupported_type) = err {
|
||||
feature_gate::feature_err(
|
||||
feature_err(
|
||||
&tcx.sess.parse_sess,
|
||||
sym::const_compare_raw_pointers,
|
||||
hir_ty.span,
|
||||
@ -2633,7 +2633,7 @@ fn from_target_feature(
|
||||
None => true,
|
||||
};
|
||||
if !allowed && id.is_local() {
|
||||
feature_gate::feature_err(
|
||||
feature_err(
|
||||
&tcx.sess.parse_sess,
|
||||
feature_gate.unwrap(),
|
||||
item.span(),
|
||||
|
@ -250,6 +250,7 @@ impl From<String> for Box<dyn Error + Send + Sync> {
|
||||
/// assert!(
|
||||
/// mem::size_of::<Box<dyn Error + Send + Sync>>() == mem::size_of_val(&a_boxed_error))
|
||||
/// ```
|
||||
#[inline]
|
||||
fn from(err: String) -> Box<dyn Error + Send + Sync> {
|
||||
struct StringError(String);
|
||||
|
||||
@ -317,6 +318,7 @@ impl<'a> From<&str> for Box<dyn Error + Send + Sync + 'a> {
|
||||
/// assert!(
|
||||
/// mem::size_of::<Box<dyn Error + Send + Sync>>() == mem::size_of_val(&a_boxed_error))
|
||||
/// ```
|
||||
#[inline]
|
||||
fn from(err: &str) -> Box<dyn Error + Send + Sync + 'a> {
|
||||
From::from(String::from(err))
|
||||
}
|
||||
|
@ -615,6 +615,7 @@ impl OsStr {
|
||||
/// assert!(!os_str.is_empty());
|
||||
/// ```
|
||||
#[stable(feature = "osstring_simple_functions", since = "1.9.0")]
|
||||
#[inline]
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.inner.inner.is_empty()
|
||||
}
|
||||
@ -965,6 +966,7 @@ impl AsRef<OsStr> for OsStr {
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl AsRef<OsStr> for OsString {
|
||||
#[inline]
|
||||
fn as_ref(&self) -> &OsStr {
|
||||
self
|
||||
}
|
||||
|
@ -1475,6 +1475,7 @@ impl From<OsString> for PathBuf {
|
||||
/// Converts a `OsString` into a `PathBuf`
|
||||
///
|
||||
/// This conversion does not allocate or copy memory.
|
||||
#[inline]
|
||||
fn from(s: OsString) -> PathBuf {
|
||||
PathBuf { inner: s }
|
||||
}
|
||||
@ -1535,7 +1536,7 @@ impl fmt::Debug for PathBuf {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl ops::Deref for PathBuf {
|
||||
type Target = Path;
|
||||
|
||||
#[inline]
|
||||
fn deref(&self) -> &Path {
|
||||
Path::new(&self.inner)
|
||||
}
|
||||
@ -2655,6 +2656,7 @@ impl AsRef<Path> for OsString {
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl AsRef<Path> for str {
|
||||
#[inline]
|
||||
fn as_ref(&self) -> &Path {
|
||||
Path::new(self)
|
||||
}
|
||||
@ -2669,6 +2671,7 @@ impl AsRef<Path> for String {
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl AsRef<Path> for PathBuf {
|
||||
#[inline]
|
||||
fn as_ref(&self) -> &Path {
|
||||
self
|
||||
}
|
||||
|
@ -6,7 +6,6 @@ use crate::io;
|
||||
use crate::marker::PhantomData;
|
||||
use crate::memchr;
|
||||
use crate::path::{self, PathBuf};
|
||||
use crate::ptr;
|
||||
use crate::str;
|
||||
use crate::sync::Mutex;
|
||||
use crate::sys::hermit::abi;
|
||||
@ -77,13 +76,17 @@ pub fn init_environment(env: *const *const i8) {
|
||||
unsafe {
|
||||
ENV = Some(Mutex::new(HashMap::new()));
|
||||
|
||||
if env.is_null() {
|
||||
return;
|
||||
}
|
||||
|
||||
let mut guard = ENV.as_ref().unwrap().lock().unwrap();
|
||||
let mut environ = env;
|
||||
while environ != ptr::null() && *environ != ptr::null() {
|
||||
while !(*environ).is_null() {
|
||||
if let Some((key, value)) = parse(CStr::from_ptr(*environ).to_bytes()) {
|
||||
guard.insert(key, value);
|
||||
}
|
||||
environ = environ.offset(1);
|
||||
environ = environ.add(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -18,14 +18,14 @@ static KEYS_LOCK: Mutex = Mutex::new();
|
||||
static mut LOCALS: *mut BTreeMap<Key, *mut u8> = ptr::null_mut();
|
||||
|
||||
unsafe fn keys() -> &'static mut BTreeMap<Key, Option<Dtor>> {
|
||||
if KEYS == ptr::null_mut() {
|
||||
if KEYS.is_null() {
|
||||
KEYS = Box::into_raw(Box::new(BTreeMap::new()));
|
||||
}
|
||||
&mut *KEYS
|
||||
}
|
||||
|
||||
unsafe fn locals() -> &'static mut BTreeMap<Key, *mut u8> {
|
||||
if LOCALS == ptr::null_mut() {
|
||||
if LOCALS.is_null() {
|
||||
LOCALS = Box::into_raw(Box::new(BTreeMap::new()));
|
||||
}
|
||||
&mut *LOCALS
|
||||
|
@ -70,7 +70,7 @@ impl<'a> Drop for ActiveTls<'a> {
|
||||
any_non_null_dtor = false;
|
||||
for (value, dtor) in TLS_KEY_IN_USE.iter().filter_map(&value_with_destructor) {
|
||||
let value = value.replace(ptr::null_mut());
|
||||
if value != ptr::null_mut() {
|
||||
if !value.is_null() {
|
||||
any_non_null_dtor = true;
|
||||
unsafe { dtor(value) }
|
||||
}
|
||||
|
@ -480,11 +480,13 @@ pub fn env() -> Env {
|
||||
let _guard = env_lock();
|
||||
let mut environ = *environ();
|
||||
let mut result = Vec::new();
|
||||
while environ != ptr::null() && *environ != ptr::null() {
|
||||
if let Some(key_value) = parse(CStr::from_ptr(*environ).to_bytes()) {
|
||||
result.push(key_value);
|
||||
if !environ.is_null() {
|
||||
while !(*environ).is_null() {
|
||||
if let Some(key_value) = parse(CStr::from_ptr(*environ).to_bytes()) {
|
||||
result.push(key_value);
|
||||
}
|
||||
environ = environ.add(1);
|
||||
}
|
||||
environ = environ.offset(1);
|
||||
}
|
||||
return Env { iter: result.into_iter(), _dont_send_or_sync_me: PhantomData };
|
||||
}
|
||||
|
@ -7,7 +7,6 @@ use crate::marker::PhantomData;
|
||||
use crate::mem;
|
||||
use crate::memchr;
|
||||
use crate::path::{self, Path, PathBuf};
|
||||
use crate::ptr;
|
||||
use crate::slice;
|
||||
use crate::str;
|
||||
use crate::sys::cvt;
|
||||
@ -226,15 +225,15 @@ pub fn env() -> Env {
|
||||
unsafe {
|
||||
let _guard = env_lock();
|
||||
let mut environ = *environ();
|
||||
if environ == ptr::null() {
|
||||
if environ.is_null() {
|
||||
panic!("os::env() failure getting env string from OS: {}", io::Error::last_os_error());
|
||||
}
|
||||
let mut result = Vec::new();
|
||||
while *environ != ptr::null() {
|
||||
while !(*environ).is_null() {
|
||||
if let Some(key_value) = parse(CStr::from_ptr(*environ).to_bytes()) {
|
||||
result.push(key_value);
|
||||
}
|
||||
environ = environ.offset(1);
|
||||
environ = environ.add(1);
|
||||
}
|
||||
return Env { iter: result.into_iter(), _dont_send_or_sync_me: PhantomData };
|
||||
}
|
||||
|
@ -6,7 +6,6 @@ use crate::io;
|
||||
use crate::marker::PhantomData;
|
||||
use crate::os::wasi::prelude::*;
|
||||
use crate::path::{self, PathBuf};
|
||||
use crate::ptr;
|
||||
use crate::str;
|
||||
use crate::sys::memchr;
|
||||
use crate::sys::{unsupported, Void};
|
||||
@ -107,11 +106,13 @@ pub fn env() -> Env {
|
||||
let _guard = env_lock();
|
||||
let mut environ = libc::environ;
|
||||
let mut result = Vec::new();
|
||||
while environ != ptr::null_mut() && *environ != ptr::null_mut() {
|
||||
if let Some(key_value) = parse(CStr::from_ptr(*environ).to_bytes()) {
|
||||
result.push(key_value);
|
||||
if !environ.is_null() {
|
||||
while !(*environ).is_null() {
|
||||
if let Some(key_value) = parse(CStr::from_ptr(*environ).to_bytes()) {
|
||||
result.push(key_value);
|
||||
}
|
||||
environ = environ.add(1);
|
||||
}
|
||||
environ = environ.offset(1);
|
||||
}
|
||||
return Env { iter: result.into_iter(), _dont_send_or_sync_me: PhantomData };
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ pub fn error_string(mut errnum: i32) -> String {
|
||||
];
|
||||
module = c::GetModuleHandleW(NTDLL_DLL.as_ptr());
|
||||
|
||||
if module != ptr::null_mut() {
|
||||
if !module.is_null() {
|
||||
errnum ^= c::FACILITY_NT_BIT as i32;
|
||||
flags = c::FORMAT_MESSAGE_FROM_HMODULE;
|
||||
}
|
||||
|
@ -104,6 +104,7 @@ impl Buf {
|
||||
self.inner.shrink_to(min_capacity)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn as_slice(&self) -> &Slice {
|
||||
unsafe { mem::transmute(&*self.inner) }
|
||||
}
|
||||
|
@ -2,9 +2,8 @@
|
||||
|
||||
use super::{mark_used, MetaItemKind};
|
||||
use crate::ast::{self, Attribute, MetaItem, NestedMetaItem};
|
||||
use crate::feature_gate::feature_err;
|
||||
use crate::print::pprust;
|
||||
use crate::sess::ParseSess;
|
||||
use crate::sess::{feature_err, ParseSess};
|
||||
|
||||
use rustc_errors::{struct_span_err, Applicability, Handler};
|
||||
use rustc_feature::{find_gated_cfg, is_builtin_attr_name, Features, GatedCfg};
|
||||
|
@ -1,30 +0,0 @@
|
||||
//! Allows the buffering of lints for later.
|
||||
//!
|
||||
//! Since we cannot have a dependency on `librustc`, we implement some types here that are somewhat
|
||||
//! redundant. Later, these types can be converted to types for use by the rest of the compiler.
|
||||
|
||||
use rustc_session::declare_lint;
|
||||
pub use rustc_session::lint::BufferedEarlyLint;
|
||||
use rustc_session::lint::FutureIncompatibleInfo;
|
||||
|
||||
declare_lint! {
|
||||
pub ILL_FORMED_ATTRIBUTE_INPUT,
|
||||
Deny,
|
||||
"ill-formed attribute inputs that were previously accepted and used in practice",
|
||||
@future_incompatible = FutureIncompatibleInfo {
|
||||
reference: "issue #57571 <https://github.com/rust-lang/rust/issues/57571>",
|
||||
edition: None,
|
||||
};
|
||||
}
|
||||
|
||||
declare_lint! {
|
||||
pub META_VARIABLE_MISUSE,
|
||||
Allow,
|
||||
"possible meta-variable misuse at macro definition"
|
||||
}
|
||||
|
||||
declare_lint! {
|
||||
pub INCOMPLETE_INCLUDE,
|
||||
Deny,
|
||||
"trailing content in included file"
|
||||
}
|
@ -75,13 +75,8 @@ pub mod ast;
|
||||
pub mod attr;
|
||||
pub mod entry;
|
||||
pub mod expand;
|
||||
pub mod feature_gate {
|
||||
mod check;
|
||||
pub use check::{check_attribute, check_crate, feature_err, feature_err_issue, get_features};
|
||||
}
|
||||
pub mod mut_visit;
|
||||
pub mod ptr;
|
||||
pub mod show_span;
|
||||
pub use rustc_session::parse as sess;
|
||||
pub mod token;
|
||||
pub mod tokenstream;
|
||||
@ -93,8 +88,6 @@ pub mod print {
|
||||
pub mod pprust;
|
||||
}
|
||||
|
||||
pub mod early_buffered_lints;
|
||||
|
||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||
|
||||
/// Requirements for a `StableHashingContext` to be used in this crate.
|
||||
|
@ -6,9 +6,8 @@
|
||||
extern crate rustc;
|
||||
extern crate rustc_session;
|
||||
|
||||
use rustc::lint::{LintArray, LintPass};
|
||||
use rustc::{declare_lint_pass, impl_lint_pass};
|
||||
use rustc_session::declare_lint;
|
||||
use rustc_session::lint::{LintArray, LintPass};
|
||||
use rustc_session::{declare_lint, declare_lint_pass, impl_lint_pass};
|
||||
|
||||
declare_lint! {
|
||||
pub TEST_LINT,
|
||||
|
@ -1,5 +1,5 @@
|
||||
error: implementing `LintPass` by hand
|
||||
--> $DIR/lint_pass_impl_without_macro.rs:21:6
|
||||
--> $DIR/lint_pass_impl_without_macro.rs:20:6
|
||||
|
|
||||
LL | impl LintPass for Foo {
|
||||
| ^^^^^^^^
|
||||
@ -12,7 +12,7 @@ LL | #![deny(rustc::lint_pass_impl_without_macro)]
|
||||
= help: try using `declare_lint_pass!` or `impl_lint_pass!` instead
|
||||
|
||||
error: implementing `LintPass` by hand
|
||||
--> $DIR/lint_pass_impl_without_macro.rs:31:14
|
||||
--> $DIR/lint_pass_impl_without_macro.rs:30:14
|
||||
|
|
||||
LL | impl LintPass for Custom {
|
||||
| ^^^^^^^^
|
||||
|
@ -4,17 +4,21 @@ error[E0015]: calls in constant functions are limited to constant functions, tup
|
||||
LL | random()
|
||||
| ^^^^^^^^
|
||||
|
||||
error[E0013]: constant functions cannot refer to statics, use a constant instead
|
||||
error[E0013]: constant functions cannot refer to statics
|
||||
--> $DIR/const-fn-not-safe-for-const.rs:20:5
|
||||
|
|
||||
LL | Y
|
||||
| ^
|
||||
|
|
||||
= help: consider extracting the value of the `static` to a `const`, and referring to that
|
||||
|
||||
error[E0013]: constant functions cannot refer to statics, use a constant instead
|
||||
error[E0013]: constant functions cannot refer to statics
|
||||
--> $DIR/const-fn-not-safe-for-const.rs:25:6
|
||||
|
|
||||
LL | &Y
|
||||
| ^
|
||||
|
|
||||
= help: consider extracting the value of the `static` to a `const`, and referring to that
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
@ -7,17 +7,21 @@ LL | const C1: &'static mut [usize] = &mut [];
|
||||
= note: for more information, see https://github.com/rust-lang/rust/issues/57349
|
||||
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
|
||||
|
||||
error[E0013]: constants cannot refer to statics, use a constant instead
|
||||
error[E0013]: constants cannot refer to statics
|
||||
--> $DIR/issue-17718-const-bad-values.rs:5:46
|
||||
|
|
||||
LL | const C2: &'static mut usize = unsafe { &mut S };
|
||||
| ^
|
||||
|
|
||||
= help: consider extracting the value of the `static` to a `const`, and referring to that
|
||||
|
||||
error[E0013]: constants cannot refer to statics, use a constant instead
|
||||
error[E0013]: constants cannot refer to statics
|
||||
--> $DIR/issue-17718-const-bad-values.rs:5:46
|
||||
|
|
||||
LL | const C2: &'static mut usize = unsafe { &mut S };
|
||||
| ^
|
||||
|
|
||||
= help: consider extracting the value of the `static` to a `const`, and referring to that
|
||||
|
||||
error[E0658]: references in constants may only refer to immutable values
|
||||
--> $DIR/issue-17718-const-bad-values.rs:5:41
|
||||
|
@ -1,20 +1,26 @@
|
||||
error[E0013]: constants cannot refer to statics, use a constant instead
|
||||
error[E0013]: constants cannot refer to statics
|
||||
--> $DIR/issue-17718-references.rs:9:29
|
||||
|
|
||||
LL | const T2: &'static usize = &S;
|
||||
| ^
|
||||
|
|
||||
= help: consider extracting the value of the `static` to a `const`, and referring to that
|
||||
|
||||
error[E0013]: constants cannot refer to statics, use a constant instead
|
||||
error[E0013]: constants cannot refer to statics
|
||||
--> $DIR/issue-17718-references.rs:14:19
|
||||
|
|
||||
LL | const T6: usize = S;
|
||||
| ^
|
||||
|
|
||||
= help: consider extracting the value of the `static` to a `const`, and referring to that
|
||||
|
||||
error[E0013]: constants cannot refer to statics, use a constant instead
|
||||
error[E0013]: constants cannot refer to statics
|
||||
--> $DIR/issue-17718-references.rs:19:33
|
||||
|
|
||||
LL | const T10: Struct = Struct { a: S };
|
||||
| ^
|
||||
|
|
||||
= help: consider extracting the value of the `static` to a `const`, and referring to that
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
pub fn main() {
|
||||
const z: &'static isize = {
|
||||
static p: isize = 3;
|
||||
&p
|
||||
//~^ ERROR constants cannot refer to statics, use a constant instead
|
||||
&p //~ ERROR constants cannot refer to statics
|
||||
};
|
||||
}
|
||||
|
@ -1,8 +1,10 @@
|
||||
error[E0013]: constants cannot refer to statics, use a constant instead
|
||||
error[E0013]: constants cannot refer to statics
|
||||
--> $DIR/issue-18118-2.rs:4:10
|
||||
|
|
||||
LL | &p
|
||||
| ^
|
||||
|
|
||||
= help: consider extracting the value of the `static` to a `const`, and referring to that
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -1,8 +1,10 @@
|
||||
error[E0013]: constants cannot refer to statics, use a constant instead
|
||||
error[E0013]: constants cannot refer to statics
|
||||
--> $DIR/issue-52060.rs:4:26
|
||||
|
|
||||
LL | static B: [u32; 1] = [0; A.len()];
|
||||
| ^
|
||||
|
|
||||
= help: consider extracting the value of the `static` to a `const`, and referring to that
|
||||
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/issue-52060.rs:4:26
|
||||
|
@ -0,0 +1,6 @@
|
||||
pub struct Foo {
|
||||
pub bar: Vec<i32>ö
|
||||
//~^ ERROR expected `,`, or `}`, found `ö`
|
||||
} //~ ERROR expected `:`, found `}`
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,17 @@
|
||||
error: expected `,`, or `}`, found `ö`
|
||||
--> $DIR/issue-68000-unicode-ident-after-missing-comma.rs:2:22
|
||||
|
|
||||
LL | pub bar: Vec<i32>ö
|
||||
| ^ help: try adding a comma: `,`
|
||||
|
||||
error: expected `:`, found `}`
|
||||
--> $DIR/issue-68000-unicode-ident-after-missing-comma.rs:4:1
|
||||
|
|
||||
LL | pub bar: Vec<i32>ö
|
||||
| - expected `:`
|
||||
LL |
|
||||
LL | }
|
||||
| ^ unexpected token
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
9
src/test/ui/issues/issue-68091-unicode-ident-after-if.rs
Normal file
9
src/test/ui/issues/issue-68091-unicode-ident-after-if.rs
Normal file
@ -0,0 +1,9 @@
|
||||
macro_rules! x {
|
||||
($($c:tt)*) => {
|
||||
$($c)ö* {} //~ ERROR missing condition for `if` expression
|
||||
}; //~| ERROR mismatched types
|
||||
}
|
||||
|
||||
fn main() {
|
||||
x!(if);
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user