Auto merge of #59684 - Centril:rollup-n7pnare, r=Centril

Rollup of 6 pull requests

Successful merges:

 - #59316 (Internal lints take 2)
 - #59663 (Be more direct about borrow contract)
 - #59664 (Updated the documentation of spin_loop and spin_loop_hint)
 - #59666 (Updated the environment description in rustc.)
 - #59669 (Reduce repetition in librustc(_lint) wrt. impl LintPass by using macros)
 - #59677 (rustfix coverage: Skip UI tests with non-json error-format)

Failed merges:

r? @ghost
This commit is contained in:
bors 2019-04-04 02:31:46 +00:00
commit a5dfdc589a
72 changed files with 939 additions and 716 deletions

View File

@ -316,6 +316,11 @@ fn main() {
}
}
// This is required for internal lints.
if stage != "0" {
cmd.arg("-Zunstable-options");
}
// Force all crates compiled by this compiler to (a) be unstable and (b)
// allow the `rustc_private` feature to link to other unstable crates
// also in the sysroot. We also do this for host crates, since those

View File

@ -265,8 +265,8 @@ Optimize with possible levels 0\[en]3
.SH ENVIRONMENT
Some of these affect the output of the compiler, while others affect programs
which link to the standard library.
Some of these affect only test harness programs (generated via rustc --test);
others affect all programs which link to the Rust standard library.
.TP
\fBRUST_TEST_THREADS\fR

View File

@ -12,6 +12,7 @@
test(no_crate_inject, attr(deny(warnings))))]
#![deny(rust_2018_idioms)]
#![cfg_attr(not(stage0), deny(internal))]
#![feature(alloc)]
#![feature(core_intrinsics)]

View File

@ -32,6 +32,10 @@
/// on the identical behavior of these additional trait implementations.
/// These traits will likely appear as additional trait bounds.
///
/// In particular `Eq`, `Ord` and `Hash` must be equivalent for
/// borrowed and owned values: `x.borrow() == y.borrow()` should give the
/// same result as `x == y`.
///
/// If generic code merely needs to work for all types that can
/// provide a reference to related type `T`, it is often better to use
/// [`AsRef<T>`] as more types can safely implement it.

View File

@ -105,11 +105,13 @@ pub const fn identity<T>(x: T) -> T { x }
/// `&T` or write a custom function.
///
///
/// `AsRef` is very similar to, but serves a slightly different purpose than [`Borrow`]:
/// `AsRef` has the same signature as [`Borrow`], but `Borrow` is different in few aspects:
///
/// - Use `AsRef` when the goal is to simply convert into a reference
/// - Use `Borrow` when the goal is related to writing code that is agnostic to
/// the type of borrow and whether it is a reference or value
/// - Unlike `AsRef`, `Borrow` has a blanket impl for any `T`, and can be used to accept either
/// a reference or a value.
/// - `Borrow` also requires that `Hash`, `Eq` and `Ord` for borrowed value are
/// equivalent to those of the owned value. For this reason, if you want to
/// borrow only a single field of a struct you can implement `AsRef`, but not `Borrow`.
///
/// [`Borrow`]: ../../std/borrow/trait.Borrow.html
///

View File

@ -50,15 +50,28 @@ pub unsafe fn unreachable_unchecked() -> ! {
intrinsics::unreachable()
}
/// Save power or switch hyperthreads in a busy-wait spin-loop.
/// Signals the processor that it is entering a busy-wait spin-loop.
///
/// This function is deliberately more primitive than
/// [`std::thread::yield_now`](../../std/thread/fn.yield_now.html) and
/// does not directly yield to the system's scheduler.
/// In some cases it might be useful to use a combination of both functions.
/// Careful benchmarking is advised.
/// Upon receiving spin-loop signal the processor can optimize its behavior by, for example, saving
/// power or switching hyper-threads.
///
/// On some platforms this function may not do anything at all.
/// This function is different than [`std::thread::yield_now`] which directly yields to the
/// system's scheduler, whereas `spin_loop` only signals the processor that it is entering a
/// busy-wait spin-loop without yielding control to the system's scheduler.
///
/// Using a busy-wait spin-loop with `spin_loop` is ideally used in situations where a
/// contended lock is held by another thread executed on a different CPU and where the waiting
/// times are relatively small. Because entering busy-wait spin-loop does not trigger the system's
/// scheduler, no overhead for switching threads occurs. However, if the thread holding the
/// contended lock is running on the same CPU, the spin-loop is likely to occupy an entire CPU slice
/// before switching to the thread that holds the lock. If the contending lock is held by a thread
/// on the same CPU or if the waiting times for acquiring the lock are longer, it is often better to
/// use [`std::thread::yield_now`].
///
/// **Note**: On platforms that do not support receiving spin-loop hints this function does not
/// do anything at all.
///
/// [`std::thread::yield_now`]: ../../std/thread/fn.yield_now.html
#[inline]
#[unstable(feature = "renamed_spin_loop", issue = "55002")]
pub fn spin_loop() {

View File

@ -124,15 +124,28 @@ use fmt;
use hint::spin_loop;
/// Save power or switch hyperthreads in a busy-wait spin-loop.
/// Signals the processor that it is entering a busy-wait spin-loop.
///
/// This function is deliberately more primitive than
/// [`std::thread::yield_now`](../../../std/thread/fn.yield_now.html) and
/// does not directly yield to the system's scheduler.
/// In some cases it might be useful to use a combination of both functions.
/// Careful benchmarking is advised.
/// Upon receiving spin-loop signal the processor can optimize its behavior by, for example, saving
/// power or switching hyper-threads.
///
/// On some platforms this function may not do anything at all.
/// This function is different than [`std::thread::yield_now`] which directly yields to the
/// system's scheduler, whereas `spin_loop_hint` only signals the processor that it is entering a
/// busy-wait spin-loop without yielding control to the system's scheduler.
///
/// Using a busy-wait spin-loop with `spin_loop_hint` is ideally used in situations where a
/// contended lock is held by another thread executed on a different CPU and where the waiting
/// times are relatively small. Because entering busy-wait spin-loop does not trigger the system's
/// scheduler, no overhead for switching threads occurs. However, if the thread holding the
/// contended lock is running on the same CPU, the spin-loop is likely to occupy an entire CPU slice
/// before switching to the thread that holds the lock. If the contending lock is held by a thread
/// on the same CPU or if the waiting times for acquiring the lock are longer, it is often better to
/// use [`std::thread::yield_now`].
///
/// **Note**: On platforms that do not support receiving spin-loop hints this function does not
/// do anything at all.
///
/// [`std::thread::yield_now`]: ../../../std/thread/fn.yield_now.html
#[inline]
#[stable(feature = "spin_loop_hint", since = "1.24.0")]
pub fn spin_loop_hint() {

View File

@ -9,6 +9,7 @@
test(attr(deny(warnings))))]
#![deny(rust_2018_idioms)]
#![cfg_attr(not(stage0), deny(internal))]
#![feature(nll)]
#![feature(rustc_private)]

View File

@ -1,10 +1,10 @@
use crate::ty;
use crate::ty::TyCtxt;
use crate::hir::map::definitions::FIRST_FREE_HIGH_DEF_INDEX;
use crate::ty::{self, print::Printer, subst::Kind, Ty, TyCtxt};
use crate::hir::map::definitions::{DisambiguatedDefPathData, FIRST_FREE_HIGH_DEF_INDEX};
use rustc_data_structures::indexed_vec::Idx;
use serialize;
use std::fmt;
use std::u32;
use syntax::symbol::{LocalInternedString, Symbol};
newtype_index! {
pub struct CrateId {
@ -252,6 +252,107 @@ impl DefId {
format!("module `{}`", tcx.def_path_str(*self))
}
}
/// Check if a `DefId`'s path matches the given absolute type path usage.
// Uplifted from rust-lang/rust-clippy
pub fn match_path<'a, 'tcx>(self, tcx: TyCtxt<'a, 'tcx, 'tcx>, path: &[&str]) -> bool {
pub struct AbsolutePathPrinter<'a, 'tcx> {
pub tcx: TyCtxt<'a, 'tcx, 'tcx>,
}
impl<'tcx> Printer<'tcx, 'tcx> for AbsolutePathPrinter<'_, 'tcx> {
type Error = !;
type Path = Vec<LocalInternedString>;
type Region = ();
type Type = ();
type DynExistential = ();
fn tcx<'a>(&'a self) -> TyCtxt<'a, 'tcx, 'tcx> {
self.tcx
}
fn print_region(self, _region: ty::Region<'_>) -> Result<Self::Region, Self::Error> {
Ok(())
}
fn print_type(self, _ty: Ty<'tcx>) -> Result<Self::Type, Self::Error> {
Ok(())
}
fn print_dyn_existential(
self,
_predicates: &'tcx ty::List<ty::ExistentialPredicate<'tcx>>,
) -> Result<Self::DynExistential, Self::Error> {
Ok(())
}
fn path_crate(self, cnum: CrateNum) -> Result<Self::Path, Self::Error> {
Ok(vec![self.tcx.original_crate_name(cnum).as_str()])
}
fn path_qualified(
self,
self_ty: Ty<'tcx>,
trait_ref: Option<ty::TraitRef<'tcx>>,
) -> Result<Self::Path, Self::Error> {
if trait_ref.is_none() {
if let ty::Adt(def, substs) = self_ty.sty {
return self.print_def_path(def.did, substs);
}
}
// This shouldn't ever be needed, but just in case:
Ok(vec![match trait_ref {
Some(trait_ref) => Symbol::intern(&format!("{:?}", trait_ref)).as_str(),
None => Symbol::intern(&format!("<{}>", self_ty)).as_str(),
}])
}
fn path_append_impl(
self,
print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
_disambiguated_data: &DisambiguatedDefPathData,
self_ty: Ty<'tcx>,
trait_ref: Option<ty::TraitRef<'tcx>>,
) -> Result<Self::Path, Self::Error> {
let mut path = print_prefix(self)?;
// This shouldn't ever be needed, but just in case:
path.push(match trait_ref {
Some(trait_ref) => {
Symbol::intern(&format!("<impl {} for {}>", trait_ref, self_ty)).as_str()
},
None => Symbol::intern(&format!("<impl {}>", self_ty)).as_str(),
});
Ok(path)
}
fn path_append(
self,
print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
disambiguated_data: &DisambiguatedDefPathData,
) -> Result<Self::Path, Self::Error> {
let mut path = print_prefix(self)?;
path.push(disambiguated_data.data.as_interned_str().as_str());
Ok(path)
}
fn path_generic_args(
self,
print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
_args: &[Kind<'tcx>],
) -> Result<Self::Path, Self::Error> {
print_prefix(self)
}
}
let names = AbsolutePathPrinter { tcx }.print_def_path(self, &[]).unwrap();
names.len() == path.len()
&& names.into_iter().zip(path.iter()).all(|(a, &b)| *a == *b)
}
}
impl serialize::UseSpecializedEncodable for DefId {}

View File

@ -9,7 +9,6 @@ use crate::session::Session;
use std::cmp::Ord;
use std::hash as std_hash;
use std::collections::HashMap;
use std::cell::RefCell;
use syntax::ast;
@ -394,13 +393,12 @@ impl<'a> HashStable<StableHashingContext<'a>> for DelimSpan {
}
}
pub fn hash_stable_trait_impls<'a, 'gcx, W, R>(
pub fn hash_stable_trait_impls<'a, 'gcx, W>(
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>,
blanket_impls: &[DefId],
non_blanket_impls: &HashMap<fast_reject::SimplifiedType, Vec<DefId>, R>)
where W: StableHasherResult,
R: std_hash::BuildHasher,
non_blanket_impls: &FxHashMap<fast_reject::SimplifiedType, Vec<DefId>>)
where W: StableHasherResult
{
{
let mut blanket_impls: SmallVec<[_; 8]> = blanket_impls

View File

@ -56,7 +56,7 @@ use crate::hir::Node;
use crate::middle::region;
use crate::traits::{ObligationCause, ObligationCauseCode};
use crate::ty::error::TypeError;
use crate::ty::{self, subst::{Subst, SubstsRef}, Region, Ty, TyCtxt, TyKind, TypeFoldable};
use crate::ty::{self, subst::{Subst, SubstsRef}, Region, Ty, TyCtxt, TypeFoldable};
use errors::{Applicability, DiagnosticBuilder, DiagnosticStyledString};
use std::{cmp, fmt};
use syntax_pos::{Pos, Span};
@ -1094,14 +1094,14 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
(_, false, _) => {
if let Some(exp_found) = exp_found {
let (def_id, ret_ty) = match exp_found.found.sty {
TyKind::FnDef(def, _) => {
ty::FnDef(def, _) => {
(Some(def), Some(self.tcx.fn_sig(def).output()))
}
_ => (None, None),
};
let exp_is_struct = match exp_found.expected.sty {
TyKind::Adt(def, _) => def.is_struct(),
ty::Adt(def, _) => def.is_struct(),
_ => false,
};
@ -1140,8 +1140,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
diag: &mut DiagnosticBuilder<'tcx>,
) {
match (&exp_found.expected.sty, &exp_found.found.sty) {
(TyKind::Adt(exp_def, exp_substs), TyKind::Ref(_, found_ty, _)) => {
if let TyKind::Adt(found_def, found_substs) = found_ty.sty {
(ty::Adt(exp_def, exp_substs), ty::Ref(_, found_ty, _)) => {
if let ty::Adt(found_def, found_substs) = found_ty.sty {
let path_str = format!("{:?}", exp_def);
if exp_def == &found_def {
let opt_msg = "you can convert from `&Option<T>` to `Option<&T>` using \
@ -1164,17 +1164,17 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
let mut show_suggestion = true;
for (exp_ty, found_ty) in exp_substs.types().zip(found_substs.types()) {
match exp_ty.sty {
TyKind::Ref(_, exp_ty, _) => {
ty::Ref(_, exp_ty, _) => {
match (&exp_ty.sty, &found_ty.sty) {
(_, TyKind::Param(_)) |
(_, TyKind::Infer(_)) |
(TyKind::Param(_), _) |
(TyKind::Infer(_), _) => {}
(_, ty::Param(_)) |
(_, ty::Infer(_)) |
(ty::Param(_), _) |
(ty::Infer(_), _) => {}
_ if ty::TyS::same_type(exp_ty, found_ty) => {}
_ => show_suggestion = false,
};
}
TyKind::Param(_) | TyKind::Infer(_) => {}
ty::Param(_) | ty::Infer(_) => {}
_ => show_suggestion = false,
}
}

View File

@ -29,6 +29,7 @@
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
#![deny(rust_2018_idioms)]
#![cfg_attr(not(stage0), deny(internal))]
#![allow(explicit_outlives_requirements)]
#![feature(arbitrary_self_types)]

View File

@ -392,81 +392,72 @@ declare_lint! {
"nested occurrence of `impl Trait` type"
}
/// Does nothing as a lint pass, but registers some `Lint`s
/// that are used by other parts of the compiler.
#[derive(Copy, Clone)]
pub struct HardwiredLints;
impl LintPass for HardwiredLints {
fn name(&self) -> &'static str {
"HardwiredLints"
}
fn get_lints(&self) -> LintArray {
lint_array!(
ILLEGAL_FLOATING_POINT_LITERAL_PATTERN,
EXCEEDING_BITSHIFTS,
UNUSED_IMPORTS,
UNUSED_EXTERN_CRATES,
UNUSED_QUALIFICATIONS,
UNKNOWN_LINTS,
UNUSED_VARIABLES,
UNUSED_ASSIGNMENTS,
DEAD_CODE,
UNREACHABLE_CODE,
UNREACHABLE_PATTERNS,
UNUSED_MACROS,
WARNINGS,
UNUSED_FEATURES,
STABLE_FEATURES,
UNKNOWN_CRATE_TYPES,
TRIVIAL_CASTS,
TRIVIAL_NUMERIC_CASTS,
PRIVATE_IN_PUBLIC,
EXPORTED_PRIVATE_DEPENDENCIES,
PUB_USE_OF_PRIVATE_EXTERN_CRATE,
INVALID_TYPE_PARAM_DEFAULT,
CONST_ERR,
RENAMED_AND_REMOVED_LINTS,
SAFE_EXTERN_STATICS,
SAFE_PACKED_BORROWS,
PATTERNS_IN_FNS_WITHOUT_BODY,
LEGACY_DIRECTORY_OWNERSHIP,
LEGACY_CONSTRUCTOR_VISIBILITY,
MISSING_FRAGMENT_SPECIFIER,
PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES,
LATE_BOUND_LIFETIME_ARGUMENTS,
INCOHERENT_FUNDAMENTAL_IMPLS,
ORDER_DEPENDENT_TRAIT_OBJECTS,
DEPRECATED,
UNUSED_UNSAFE,
UNUSED_MUT,
UNCONDITIONAL_RECURSION,
SINGLE_USE_LIFETIMES,
UNUSED_LIFETIMES,
UNUSED_LABELS,
TYVAR_BEHIND_RAW_POINTER,
ELIDED_LIFETIMES_IN_PATHS,
BARE_TRAIT_OBJECTS,
ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE,
UNSTABLE_NAME_COLLISIONS,
IRREFUTABLE_LET_PATTERNS,
DUPLICATE_MACRO_EXPORTS,
INTRA_DOC_LINK_RESOLUTION_FAILURE,
MISSING_DOC_CODE_EXAMPLES,
PRIVATE_DOC_TESTS,
WHERE_CLAUSES_OBJECT_SAFETY,
PROC_MACRO_DERIVE_RESOLUTION_FALLBACK,
MACRO_USE_EXTERN_CRATE,
MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS,
parser::QUESTION_MARK_MACRO_SEP,
parser::ILL_FORMED_ATTRIBUTE_INPUT,
DEPRECATED_IN_FUTURE,
AMBIGUOUS_ASSOCIATED_ITEMS,
NESTED_IMPL_TRAIT,
DUPLICATE_MATCHER_BINDING_NAME,
)
}
declare_lint_pass! {
/// Does nothing as a lint pass, but registers some `Lint`s
/// that are used by other parts of the compiler.
HardwiredLints => [
ILLEGAL_FLOATING_POINT_LITERAL_PATTERN,
EXCEEDING_BITSHIFTS,
UNUSED_IMPORTS,
UNUSED_EXTERN_CRATES,
UNUSED_QUALIFICATIONS,
UNKNOWN_LINTS,
UNUSED_VARIABLES,
UNUSED_ASSIGNMENTS,
DEAD_CODE,
UNREACHABLE_CODE,
UNREACHABLE_PATTERNS,
UNUSED_MACROS,
WARNINGS,
UNUSED_FEATURES,
STABLE_FEATURES,
UNKNOWN_CRATE_TYPES,
TRIVIAL_CASTS,
TRIVIAL_NUMERIC_CASTS,
PRIVATE_IN_PUBLIC,
EXPORTED_PRIVATE_DEPENDENCIES,
PUB_USE_OF_PRIVATE_EXTERN_CRATE,
INVALID_TYPE_PARAM_DEFAULT,
CONST_ERR,
RENAMED_AND_REMOVED_LINTS,
SAFE_EXTERN_STATICS,
SAFE_PACKED_BORROWS,
PATTERNS_IN_FNS_WITHOUT_BODY,
LEGACY_DIRECTORY_OWNERSHIP,
LEGACY_CONSTRUCTOR_VISIBILITY,
MISSING_FRAGMENT_SPECIFIER,
PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES,
LATE_BOUND_LIFETIME_ARGUMENTS,
INCOHERENT_FUNDAMENTAL_IMPLS,
ORDER_DEPENDENT_TRAIT_OBJECTS,
DEPRECATED,
UNUSED_UNSAFE,
UNUSED_MUT,
UNCONDITIONAL_RECURSION,
SINGLE_USE_LIFETIMES,
UNUSED_LIFETIMES,
UNUSED_LABELS,
TYVAR_BEHIND_RAW_POINTER,
ELIDED_LIFETIMES_IN_PATHS,
BARE_TRAIT_OBJECTS,
ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE,
UNSTABLE_NAME_COLLISIONS,
IRREFUTABLE_LET_PATTERNS,
DUPLICATE_MACRO_EXPORTS,
INTRA_DOC_LINK_RESOLUTION_FAILURE,
MISSING_DOC_CODE_EXAMPLES,
PRIVATE_DOC_TESTS,
WHERE_CLAUSES_OBJECT_SAFETY,
PROC_MACRO_DERIVE_RESOLUTION_FALLBACK,
MACRO_USE_EXTERN_CRATE,
MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS,
parser::QUESTION_MARK_MACRO_SEP,
parser::ILL_FORMED_ATTRIBUTE_INPUT,
DEPRECATED_IN_FUTURE,
AMBIGUOUS_ASSOCIATED_ITEMS,
NESTED_IMPL_TRAIT,
DUPLICATE_MATCHER_BINDING_NAME,
]
}
// this could be a closure, but then implementing derive traits

View File

@ -0,0 +1,127 @@
//! Some lints that are only useful in the compiler or crates that use compiler internals, such as
//! Clippy.
use crate::hir::{HirId, Path, PathSegment, QPath, Ty, TyKind};
use crate::lint::{
EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintArray, LintContext, LintPass,
};
use errors::Applicability;
use rustc_data_structures::fx::FxHashMap;
use syntax::ast::Ident;
declare_lint! {
pub DEFAULT_HASH_TYPES,
Allow,
"forbid HashMap and HashSet and suggest the FxHash* variants"
}
pub struct DefaultHashTypes {
map: FxHashMap<String, String>,
}
impl DefaultHashTypes {
pub fn new() -> Self {
let mut map = FxHashMap::default();
map.insert("HashMap".to_string(), "FxHashMap".to_string());
map.insert("HashSet".to_string(), "FxHashSet".to_string());
Self { map }
}
}
impl LintPass for DefaultHashTypes {
fn get_lints(&self) -> LintArray {
lint_array!(DEFAULT_HASH_TYPES)
}
fn name(&self) -> &'static str {
"DefaultHashTypes"
}
}
impl EarlyLintPass for DefaultHashTypes {
fn check_ident(&mut self, cx: &EarlyContext<'_>, ident: Ident) {
let ident_string = ident.to_string();
if let Some(replace) = self.map.get(&ident_string) {
let msg = format!(
"Prefer {} over {}, it has better performance",
replace, ident_string
);
let mut db = cx.struct_span_lint(DEFAULT_HASH_TYPES, ident.span, &msg);
db.span_suggestion(
ident.span,
"use",
replace.to_string(),
Applicability::MaybeIncorrect, // FxHashMap, ... needs another import
);
db.note(&format!(
"a `use rustc_data_structures::fx::{}` may be necessary",
replace
))
.emit();
}
}
}
declare_lint! {
pub USAGE_OF_TY_TYKIND,
Allow,
"Usage of `ty::TyKind` outside of the `ty::sty` module"
}
pub struct TyKindUsage;
impl LintPass for TyKindUsage {
fn get_lints(&self) -> LintArray {
lint_array!(USAGE_OF_TY_TYKIND)
}
fn name(&self) -> &'static str {
"TyKindUsage"
}
}
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TyKindUsage {
fn check_path(&mut self, cx: &LateContext<'_, '_>, path: &'tcx Path, _: HirId) {
let segments = path.segments.iter().rev().skip(1).rev();
if let Some(last) = segments.last() {
let span = path.span.with_hi(last.ident.span.hi());
if lint_ty_kind_usage(cx, last) {
cx.struct_span_lint(USAGE_OF_TY_TYKIND, span, "usage of `ty::TyKind::<kind>`")
.span_suggestion(
span,
"try using ty::<kind> directly",
"ty".to_string(),
Applicability::MaybeIncorrect, // ty maybe needs an import
)
.emit();
}
}
}
fn check_ty(&mut self, cx: &LateContext<'_, '_>, ty: &'tcx Ty) {
if let TyKind::Path(qpath) = &ty.node {
if let QPath::Resolved(_, path) = qpath {
if let Some(last) = path.segments.iter().last() {
if lint_ty_kind_usage(cx, last) {
cx.struct_span_lint(USAGE_OF_TY_TYKIND, path.span, "usage of `ty::TyKind`")
.help("try using `ty::Ty` instead")
.emit();
}
}
}
}
}
}
fn lint_ty_kind_usage(cx: &LateContext<'_, '_>, segment: &PathSegment) -> bool {
if segment.ident.as_str() == "TyKind" {
if let Some(def) = segment.def {
if let Some(did) = def.opt_def_id() {
return did.match_path(cx.tcx, &["rustc", "ty", "sty", "TyKind"]);
}
}
}
false
}

View File

@ -181,6 +181,27 @@ pub trait LintPass {
fn get_lints(&self) -> LintArray;
}
/// 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) }
fn get_lints(&self) -> 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),*]);
};
}
#[macro_export]
macro_rules! late_lint_methods {
($macro:path, $args:tt, [$hir:tt]) => (
@ -574,6 +595,7 @@ impl_stable_hash_for!(enum self::LintSource {
pub type LevelSource = (Level, LintSource);
pub mod builtin;
pub mod internal;
mod context;
mod levels;

View File

@ -36,7 +36,7 @@ impl<'a, 'gcx, 'tcx> PlaceTy<'tcx> {
pub fn field_ty(self, tcx: TyCtxt<'a, 'gcx, 'tcx>, f: &Field) -> Ty<'tcx>
{
let answer = match self.ty.sty {
ty::TyKind::Adt(adt_def, substs) => {
ty::Adt(adt_def, substs) => {
let variant_def = match self.variant_index {
None => adt_def.non_enum_variant(),
Some(variant_index) => {

View File

@ -219,6 +219,11 @@ pub struct CommonTypes<'tcx> {
pub never: Ty<'tcx>,
pub err: Ty<'tcx>,
/// Dummy type used for the `Self` of a `TraitRef` created for converting
/// a trait object, and which gets removed in `ExistentialTraitRef`.
/// This type must not appear anywhere in other converted types.
pub trait_object_dummy_self: Ty<'tcx>,
pub re_empty: Region<'tcx>,
pub re_static: Region<'tcx>,
pub re_erased: Region<'tcx>,
@ -955,6 +960,8 @@ impl<'tcx> CommonTypes<'tcx> {
f32: mk(Float(ast::FloatTy::F32)),
f64: mk(Float(ast::FloatTy::F64)),
trait_object_dummy_self: mk(Infer(ty::FreshTy(0))),
re_empty: mk_region(RegionKind::ReEmpty),
re_static: mk_region(RegionKind::ReStatic),
re_erased: mk_region(RegionKind::ReErased),

View File

@ -1,3 +1,5 @@
#![cfg_attr(not(stage0), allow(usage_of_ty_tykind))]
pub use self::Variance::*;
pub use self::AssociatedItemContainer::*;
pub use self::BorrowKind::*;

View File

@ -1,11 +1,10 @@
#![allow(non_camel_case_types)]
use rustc_data_structures::sync::Lock;
use rustc_data_structures::{fx::FxHashMap, sync::Lock};
use std::cell::{RefCell, Cell};
use std::collections::HashMap;
use std::fmt::Debug;
use std::hash::{Hash, BuildHasher};
use std::hash::Hash;
use std::panic;
use std::env;
use std::time::{Duration, Instant};
@ -341,8 +340,8 @@ pub trait MemoizationMap {
where OP: FnOnce() -> Self::Value;
}
impl<K, V, S> MemoizationMap for RefCell<HashMap<K,V,S>>
where K: Hash+Eq+Clone, V: Clone, S: BuildHasher
impl<K, V> MemoizationMap for RefCell<FxHashMap<K,V>>
where K: Hash+Eq+Clone, V: Clone
{
type Key = K;
type Value = V;

View File

@ -2,6 +2,7 @@
#![feature(rustc_private)]
#![deny(rust_2018_idioms)]
#![cfg_attr(not(stage0), deny(internal))]
pub mod expand;

View File

@ -2,6 +2,7 @@
#![allow(non_camel_case_types)]
#![deny(rust_2018_idioms)]
#![cfg_attr(not(stage0), deny(internal))]
#![feature(nll)]

View File

@ -14,6 +14,7 @@
#![allow(unused_attributes)]
#![allow(dead_code)]
#![deny(rust_2018_idioms)]
#![cfg_attr(not(stage0), deny(internal))]
#![allow(explicit_outlives_requirements)]
#![recursion_limit="256"]

View File

@ -16,6 +16,7 @@
#![recursion_limit="256"]
#![deny(rust_2018_idioms)]
#![cfg_attr(not(stage0), deny(internal))]
#[macro_use]
extern crate rustc;

View File

@ -17,6 +17,7 @@
#![recursion_limit="256"]
#![deny(rust_2018_idioms)]
#![cfg_attr(not(stage0), deny(internal))]
pub extern crate getopts;
#[cfg(unix)]

View File

@ -6,6 +6,7 @@
#![feature(nll)]
#![feature(optin_builtin_traits)]
#![deny(rust_2018_idioms)]
#![cfg_attr(not(stage0), deny(internal))]
#[allow(unused_extern_crates)]
extern crate serialize as rustc_serialize; // used by deriving

View File

@ -8,6 +8,7 @@
#![recursion_limit="256"]
#![deny(rust_2018_idioms)]
#![cfg_attr(not(stage0), deny(internal))]
#[macro_use] extern crate rustc;
#[allow(unused_extern_crates)]

View File

@ -12,7 +12,6 @@ use rustc_data_structures::OnDrop;
use rustc_data_structures::sync::Lrc;
use rustc_data_structures::fx::{FxHashSet, FxHashMap};
use rustc_metadata::cstore::CStore;
use std::collections::HashSet;
use std::io::Write;
use std::path::PathBuf;
use std::result;

View File

@ -7,6 +7,7 @@
#![cfg_attr(unix, feature(libc))]
#![deny(rust_2018_idioms)]
#![cfg_attr(not(stage0), deny(internal))]
#![allow(unused_imports)]

View File

@ -21,7 +21,6 @@ use rustc_plugin;
use rustc_privacy;
use rustc_resolve;
use rustc_typeck;
use std::collections::HashSet;
use std::env;
use std::env::consts::{DLL_PREFIX, DLL_SUFFIX};
use std::io::{self, Write};
@ -109,6 +108,9 @@ pub fn create_session(
let codegen_backend = get_codegen_backend(&sess);
rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
if sess.unstable_options() {
rustc_lint::register_internals(&mut sess.lint_store.borrow_mut(), Some(&sess));
}
let mut cfg = config::build_configuration(&sess, config::to_crate_config(cfg));
add_configuration(&mut cfg, &sess, &*codegen_backend);

View File

@ -63,18 +63,7 @@ declare_lint! {
"suggest using `loop { }` instead of `while true { }`"
}
#[derive(Copy, Clone)]
pub struct WhileTrue;
impl LintPass for WhileTrue {
fn name(&self) -> &'static str {
"WhileTrue"
}
fn get_lints(&self) -> LintArray {
lint_array!(WHILE_TRUE)
}
}
declare_lint_pass!(WhileTrue => [WHILE_TRUE]);
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for WhileTrue {
fn check_expr(&mut self, cx: &LateContext<'_, '_>, e: &hir::Expr) {
@ -105,8 +94,7 @@ declare_lint! {
"use of owned (Box type) heap memory"
}
#[derive(Copy, Clone)]
pub struct BoxPointers;
declare_lint_pass!(BoxPointers => [BOX_POINTERS]);
impl BoxPointers {
fn check_heap_type<'a, 'tcx>(&self, cx: &LateContext<'_, '_>, span: Span, ty: Ty<'_>) {
@ -119,16 +107,6 @@ impl BoxPointers {
}
}
impl LintPass for BoxPointers {
fn name(&self) -> &'static str {
"BoxPointers"
}
fn get_lints(&self) -> LintArray {
lint_array!(BOX_POINTERS)
}
}
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BoxPointers {
fn check_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::Item) {
match it.node {
@ -169,18 +147,7 @@ declare_lint! {
"using `Struct { x: x }` instead of `Struct { x }` in a pattern"
}
#[derive(Copy, Clone)]
pub struct NonShorthandFieldPatterns;
impl LintPass for NonShorthandFieldPatterns {
fn name(&self) -> &'static str {
"NonShorthandFieldPatterns"
}
fn get_lints(&self) -> LintArray {
lint_array!(NON_SHORTHAND_FIELD_PATTERNS)
}
}
declare_lint_pass!(NonShorthandFieldPatterns => [NON_SHORTHAND_FIELD_PATTERNS]);
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonShorthandFieldPatterns {
fn check_pat(&mut self, cx: &LateContext<'_, '_>, pat: &hir::Pat) {
@ -226,18 +193,7 @@ declare_lint! {
"usage of `unsafe` code"
}
#[derive(Copy, Clone)]
pub struct UnsafeCode;
impl LintPass for UnsafeCode {
fn name(&self) -> &'static str {
"UnsafeCode"
}
fn get_lints(&self) -> LintArray {
lint_array!(UNSAFE_CODE)
}
}
declare_lint_pass!(UnsafeCode => [UNSAFE_CODE]);
impl UnsafeCode {
fn report_unsafe(&self, cx: &EarlyContext<'_>, span: Span, desc: &'static str) {
@ -327,6 +283,8 @@ pub struct MissingDoc {
private_traits: FxHashSet<hir::HirId>,
}
impl_lint_pass!(MissingDoc => [MISSING_DOCS]);
fn has_doc(attr: &ast::Attribute) -> bool {
if !attr.check_name("doc") {
return false;
@ -394,16 +352,6 @@ impl MissingDoc {
}
}
impl LintPass for MissingDoc {
fn name(&self) -> &'static str {
"MissingDoc"
}
fn get_lints(&self) -> LintArray {
lint_array!(MISSING_DOCS)
}
}
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDoc {
fn enter_lint_attrs(&mut self, _: &LateContext<'_, '_>, attrs: &[ast::Attribute]) {
let doc_hidden = self.doc_hidden() ||
@ -541,18 +489,7 @@ declare_lint! {
"detects potentially-forgotten implementations of `Copy`"
}
#[derive(Copy, Clone)]
pub struct MissingCopyImplementations;
impl LintPass for MissingCopyImplementations {
fn name(&self) -> &'static str {
"MissingCopyImplementations"
}
fn get_lints(&self) -> LintArray {
lint_array!(MISSING_COPY_IMPLEMENTATIONS)
}
}
declare_lint_pass!(MissingCopyImplementations => [MISSING_COPY_IMPLEMENTATIONS]);
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingCopyImplementations {
fn check_item(&mut self, cx: &LateContext<'_, '_>, item: &hir::Item) {
@ -609,22 +546,14 @@ pub struct MissingDebugImplementations {
impling_types: Option<HirIdSet>,
}
impl_lint_pass!(MissingDebugImplementations => [MISSING_DEBUG_IMPLEMENTATIONS]);
impl MissingDebugImplementations {
pub fn new() -> MissingDebugImplementations {
MissingDebugImplementations { impling_types: None }
}
}
impl LintPass for MissingDebugImplementations {
fn name(&self) -> &'static str {
"MissingDebugImplementations"
}
fn get_lints(&self) -> LintArray {
lint_array!(MISSING_DEBUG_IMPLEMENTATIONS)
}
}
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDebugImplementations {
fn check_item(&mut self, cx: &LateContext<'_, '_>, item: &hir::Item) {
if !cx.access_levels.is_reachable(item.hir_id) {
@ -672,19 +601,10 @@ declare_lint! {
"detects anonymous parameters"
}
/// Checks for use of anonymous parameters (RFC 1685).
#[derive(Copy, Clone)]
pub struct AnonymousParameters;
impl LintPass for AnonymousParameters {
fn name(&self) -> &'static str {
"AnonymousParameters"
}
fn get_lints(&self) -> LintArray {
lint_array!(ANONYMOUS_PARAMETERS)
}
}
declare_lint_pass!(
/// Checks for use of anonymous parameters (RFC 1685).
AnonymousParameters => [ANONYMOUS_PARAMETERS]
);
impl EarlyLintPass for AnonymousParameters {
fn check_trait_item(&mut self, cx: &EarlyContext<'_>, it: &ast::TraitItem) {
@ -736,6 +656,8 @@ pub struct DeprecatedAttr {
depr_attrs: Vec<&'static (&'static str, AttributeType, AttributeTemplate, AttributeGate)>,
}
impl_lint_pass!(DeprecatedAttr => []);
impl DeprecatedAttr {
pub fn new() -> DeprecatedAttr {
DeprecatedAttr {
@ -744,16 +666,6 @@ impl DeprecatedAttr {
}
}
impl LintPass for DeprecatedAttr {
fn name(&self) -> &'static str {
"DeprecatedAttr"
}
fn get_lints(&self) -> LintArray {
lint_array!()
}
}
impl EarlyLintPass for DeprecatedAttr {
fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &ast::Attribute) {
let name = attr.name_or_empty();
@ -786,18 +698,7 @@ declare_lint! {
"detects doc comments that aren't used by rustdoc"
}
#[derive(Copy, Clone)]
pub struct UnusedDocComment;
impl LintPass for UnusedDocComment {
fn name(&self) -> &'static str {
"UnusedDocComment"
}
fn get_lints(&self) -> LintArray {
lint_array![UNUSED_DOC_COMMENTS]
}
}
declare_lint_pass!(UnusedDocComment => [UNUSED_DOC_COMMENTS]);
impl UnusedDocComment {
fn warn_if_doc(
@ -884,18 +785,7 @@ declare_lint! {
"compiler plugin used as ordinary library in non-plugin crate"
}
#[derive(Copy, Clone)]
pub struct PluginAsLibrary;
impl LintPass for PluginAsLibrary {
fn name(&self) -> &'static str {
"PluginAsLibrary"
}
fn get_lints(&self) -> LintArray {
lint_array![PLUGIN_AS_LIBRARY]
}
}
declare_lint_pass!(PluginAsLibrary => [PLUGIN_AS_LIBRARY]);
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for PluginAsLibrary {
fn check_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::Item) {
@ -940,19 +830,7 @@ declare_lint! {
"generic items must be mangled"
}
#[derive(Copy, Clone)]
pub struct InvalidNoMangleItems;
impl LintPass for InvalidNoMangleItems {
fn name(&self) -> &'static str {
"InvalidNoMangleItems"
}
fn get_lints(&self) -> LintArray {
lint_array!(NO_MANGLE_CONST_ITEMS,
NO_MANGLE_GENERIC_ITEMS)
}
}
declare_lint_pass!(InvalidNoMangleItems => [NO_MANGLE_CONST_ITEMS, NO_MANGLE_GENERIC_ITEMS]);
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidNoMangleItems {
fn check_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::Item) {
@ -1011,24 +889,13 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidNoMangleItems {
}
}
#[derive(Clone, Copy)]
pub struct MutableTransmutes;
declare_lint! {
MUTABLE_TRANSMUTES,
Deny,
"mutating transmuted &mut T from &T may cause undefined behavior"
}
impl LintPass for MutableTransmutes {
fn name(&self) -> &'static str {
"MutableTransmutes"
}
fn get_lints(&self) -> LintArray {
lint_array!(MUTABLE_TRANSMUTES)
}
}
declare_lint_pass!(MutableTransmutes => [MUTABLE_TRANSMUTES]);
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MutableTransmutes {
fn check_expr(&mut self, cx: &LateContext<'_, '_>, expr: &hir::Expr) {
@ -1036,7 +903,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MutableTransmutes {
let msg = "mutating transmuted &mut T from &T may cause undefined behavior, \
consider instead using an UnsafeCell";
match get_transmute_from_to(cx, expr) {
match get_transmute_from_to(cx, expr).map(|(ty1, ty2)| (&ty1.sty, &ty2.sty)) {
Some((&ty::Ref(_, _, from_mt), &ty::Ref(_, _, to_mt))) => {
if to_mt == hir::Mutability::MutMutable &&
from_mt == hir::Mutability::MutImmutable {
@ -1049,7 +916,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MutableTransmutes {
fn get_transmute_from_to<'a, 'tcx>
(cx: &LateContext<'a, 'tcx>,
expr: &hir::Expr)
-> Option<(&'tcx ty::TyKind<'tcx>, &'tcx ty::TyKind<'tcx>)> {
-> Option<(Ty<'tcx>, Ty<'tcx>)> {
let def = if let hir::ExprKind::Path(ref qpath) = expr.node {
cx.tables.qpath_def(qpath, expr.hir_id)
} else {
@ -1062,7 +929,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MutableTransmutes {
let sig = cx.tables.node_type(expr.hir_id).fn_sig(cx.tcx);
let from = sig.inputs().skip_binder()[0];
let to = *sig.output().skip_binder();
return Some((&from.sty, &to.sty));
return Some((from, to));
}
None
}
@ -1074,25 +941,16 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MutableTransmutes {
}
}
/// Forbids using the `#[feature(...)]` attribute
#[derive(Copy, Clone)]
pub struct UnstableFeatures;
declare_lint! {
UNSTABLE_FEATURES,
Allow,
"enabling unstable features (deprecated. do not use)"
}
impl LintPass for UnstableFeatures {
fn name(&self) -> &'static str {
"UnstableFeatures"
}
fn get_lints(&self) -> LintArray {
lint_array!(UNSTABLE_FEATURES)
}
}
declare_lint_pass!(
/// Forbids using the `#[feature(...)]` attribute
UnstableFeatures => [UNSTABLE_FEATURES]
);
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnstableFeatures {
fn check_attribute(&mut self, ctx: &LateContext<'_, '_>, attr: &ast::Attribute) {
@ -1106,24 +964,16 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnstableFeatures {
}
}
/// Lint for unions that contain fields with possibly non-trivial destructors.
pub struct UnionsWithDropFields;
declare_lint! {
UNIONS_WITH_DROP_FIELDS,
Warn,
"use of unions that contain fields with possibly non-trivial drop code"
}
impl LintPass for UnionsWithDropFields {
fn name(&self) -> &'static str {
"UnionsWithDropFields"
}
fn get_lints(&self) -> LintArray {
lint_array!(UNIONS_WITH_DROP_FIELDS)
}
}
declare_lint_pass!(
/// Lint for unions that contain fields with possibly non-trivial destructors.
UnionsWithDropFields => [UNIONS_WITH_DROP_FIELDS]
);
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnionsWithDropFields {
fn check_item(&mut self, ctx: &LateContext<'_, '_>, item: &hir::Item) {
@ -1143,25 +993,16 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnionsWithDropFields {
}
}
/// Lint for items marked `pub` that aren't reachable from other crates.
#[derive(Copy, Clone)]
pub struct UnreachablePub;
declare_lint! {
pub UNREACHABLE_PUB,
Allow,
"`pub` items not reachable from crate root"
}
impl LintPass for UnreachablePub {
fn name(&self) -> &'static str {
"UnreachablePub"
}
fn get_lints(&self) -> LintArray {
lint_array!(UNREACHABLE_PUB)
}
}
declare_lint_pass!(
/// Lint for items marked `pub` that aren't reachable from other crates.
UnreachablePub => [UNREACHABLE_PUB]
);
impl UnreachablePub {
fn perform_lint(&self, cx: &LateContext<'_, '_>, what: &str, id: hir::HirId,
@ -1197,7 +1038,6 @@ impl UnreachablePub {
}
}
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnreachablePub {
fn check_item(&mut self, cx: &LateContext<'_, '_>, item: &hir::Item) {
self.perform_lint(cx, "item", item.hir_id, &item.vis, item.span, true);
@ -1217,27 +1057,18 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnreachablePub {
}
}
/// Lint for trait and lifetime bounds in type aliases being mostly ignored.
/// They are relevant when using associated types, but otherwise neither checked
/// at definition site nor enforced at use site.
pub struct TypeAliasBounds;
declare_lint! {
TYPE_ALIAS_BOUNDS,
Warn,
"bounds in type aliases are not enforced"
}
impl LintPass for TypeAliasBounds {
fn name(&self) -> &'static str {
"TypeAliasBounds"
}
fn get_lints(&self) -> LintArray {
lint_array!(TYPE_ALIAS_BOUNDS)
}
}
declare_lint_pass!(
/// Lint for trait and lifetime bounds in type aliases being mostly ignored.
/// They are relevant when using associated types, but otherwise neither checked
/// at definition site nor enforced at use site.
TypeAliasBounds => [TYPE_ALIAS_BOUNDS]
);
impl TypeAliasBounds {
fn is_type_variable_assoc(qpath: &hir::QPath) -> bool {
@ -1331,21 +1162,14 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeAliasBounds {
}
}
/// Lint constants that are erroneous.
/// Without this lint, we might not get any diagnostic if the constant is
/// unused within this crate, even though downstream crates can't use it
/// without producing an error.
pub struct UnusedBrokenConst;
declare_lint_pass!(
/// Lint constants that are erroneous.
/// Without this lint, we might not get any diagnostic if the constant is
/// unused within this crate, even though downstream crates can't use it
/// without producing an error.
UnusedBrokenConst => []
);
impl LintPass for UnusedBrokenConst {
fn name(&self) -> &'static str {
"UnusedBrokenConst"
}
fn get_lints(&self) -> LintArray {
lint_array!()
}
}
fn check_const(cx: &LateContext<'_, '_>, body_id: hir::BodyId) {
let def_id = cx.tcx.hir().body_owner_def_id(body_id);
let is_static = cx.tcx.is_static(def_id).is_some();
@ -1378,25 +1202,17 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedBrokenConst {
}
}
/// Lint for trait and lifetime bounds that don't depend on type parameters
/// which either do nothing, or stop the item from being used.
pub struct TrivialConstraints;
declare_lint! {
TRIVIAL_BOUNDS,
Warn,
"these bounds don't depend on an type parameters"
}
impl LintPass for TrivialConstraints {
fn name(&self) -> &'static str {
"TrivialConstraints"
}
fn get_lints(&self) -> LintArray {
lint_array!(TRIVIAL_BOUNDS)
}
}
declare_lint_pass!(
/// Lint for trait and lifetime bounds that don't depend on type parameters
/// which either do nothing, or stop the item from being used.
TrivialConstraints => [TRIVIAL_BOUNDS]
);
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TrivialConstraints {
fn check_item(
@ -1440,40 +1256,30 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TrivialConstraints {
}
}
/// Does nothing as a lint pass, but registers some `Lint`s
/// which are used by other parts of the compiler.
#[derive(Copy, Clone)]
pub struct SoftLints;
impl LintPass for SoftLints {
fn name(&self) -> &'static str {
"SoftLints"
}
fn get_lints(&self) -> LintArray {
lint_array!(
WHILE_TRUE,
BOX_POINTERS,
NON_SHORTHAND_FIELD_PATTERNS,
UNSAFE_CODE,
MISSING_DOCS,
MISSING_COPY_IMPLEMENTATIONS,
MISSING_DEBUG_IMPLEMENTATIONS,
ANONYMOUS_PARAMETERS,
UNUSED_DOC_COMMENTS,
PLUGIN_AS_LIBRARY,
NO_MANGLE_CONST_ITEMS,
NO_MANGLE_GENERIC_ITEMS,
MUTABLE_TRANSMUTES,
UNSTABLE_FEATURES,
UNIONS_WITH_DROP_FIELDS,
UNREACHABLE_PUB,
TYPE_ALIAS_BOUNDS,
TRIVIAL_BOUNDS
)
}
}
declare_lint_pass!(
/// Does nothing as a lint pass, but registers some `Lint`s
/// which are used by other parts of the compiler.
SoftLints => [
WHILE_TRUE,
BOX_POINTERS,
NON_SHORTHAND_FIELD_PATTERNS,
UNSAFE_CODE,
MISSING_DOCS,
MISSING_COPY_IMPLEMENTATIONS,
MISSING_DEBUG_IMPLEMENTATIONS,
ANONYMOUS_PARAMETERS,
UNUSED_DOC_COMMENTS,
PLUGIN_AS_LIBRARY,
NO_MANGLE_CONST_ITEMS,
NO_MANGLE_GENERIC_ITEMS,
MUTABLE_TRANSMUTES,
UNSTABLE_FEATURES,
UNIONS_WITH_DROP_FIELDS,
UNREACHABLE_PUB,
TYPE_ALIAS_BOUNDS,
TRIVIAL_BOUNDS
]
);
declare_lint! {
pub ELLIPSIS_INCLUSIVE_RANGE_PATTERNS,
@ -1481,18 +1287,7 @@ declare_lint! {
"`...` range patterns are deprecated"
}
pub struct EllipsisInclusiveRangePatterns;
impl LintPass for EllipsisInclusiveRangePatterns {
fn name(&self) -> &'static str {
"EllipsisInclusiveRangePatterns"
}
fn get_lints(&self) -> LintArray {
lint_array!(ELLIPSIS_INCLUSIVE_RANGE_PATTERNS)
}
}
declare_lint_pass!(EllipsisInclusiveRangePatterns => [ELLIPSIS_INCLUSIVE_RANGE_PATTERNS]);
impl EarlyLintPass for EllipsisInclusiveRangePatterns {
fn check_pat(&mut self, cx: &EarlyContext<'_>, pat: &ast::Pat, visit_subpats: &mut bool) {
@ -1553,6 +1348,8 @@ pub struct UnnameableTestItems {
items_nameable: bool,
}
impl_lint_pass!(UnnameableTestItems => [UNNAMEABLE_TEST_ITEMS]);
impl UnnameableTestItems {
pub fn new() -> Self {
Self {
@ -1562,16 +1359,6 @@ impl UnnameableTestItems {
}
}
impl LintPass for UnnameableTestItems {
fn name(&self) -> &'static str {
"UnnameableTestItems"
}
fn get_lints(&self) -> LintArray {
lint_array!(UNNAMEABLE_TEST_ITEMS)
}
}
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnnameableTestItems {
fn check_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::Item) {
if self.items_nameable {
@ -1605,19 +1392,10 @@ declare_lint! {
"detects edition keywords being used as an identifier"
}
/// Check for uses of edition keywords used as an identifier.
#[derive(Copy, Clone)]
pub struct KeywordIdents;
impl LintPass for KeywordIdents {
fn name(&self) -> &'static str {
"KeywordIdents"
}
fn get_lints(&self) -> LintArray {
lint_array!(KEYWORD_IDENTS)
}
}
declare_lint_pass!(
/// Check for uses of edition keywords used as an identifier.
KeywordIdents => [KEYWORD_IDENTS]
);
struct UnderMacro(bool);
@ -1740,18 +1518,7 @@ impl EarlyLintPass for KeywordIdents {
}
}
pub struct ExplicitOutlivesRequirements;
impl LintPass for ExplicitOutlivesRequirements {
fn name(&self) -> &'static str {
"ExplicitOutlivesRequirements"
}
fn get_lints(&self) -> LintArray {
lint_array![EXPLICIT_OUTLIVES_REQUIREMENTS]
}
}
declare_lint_pass!(ExplicitOutlivesRequirements => [EXPLICIT_OUTLIVES_REQUIREMENTS]);
impl ExplicitOutlivesRequirements {
fn collect_outlives_bound_spans(

View File

@ -20,6 +20,7 @@
#![recursion_limit="256"]
#![deny(rust_2018_idioms)]
#![cfg_attr(not(stage0), deny(internal))]
#[macro_use]
extern crate rustc;
@ -61,6 +62,7 @@ use nonstandard_style::*;
use builtin::*;
use types::*;
use unused::*;
use rustc::lint::internal::*;
/// Useful for other parts of the compiler.
pub use builtin::SoftLints;
@ -488,3 +490,18 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
store.register_removed("bad_repr",
"replaced with a generic attribute input check");
}
pub fn register_internals(store: &mut lint::LintStore, sess: Option<&Session>) {
store.register_early_pass(sess, false, false, box DefaultHashTypes::new());
store.register_late_pass(sess, false, false, false, box TyKindUsage);
store.register_group(
sess,
false,
"internal",
None,
vec![
LintId::of(DEFAULT_HASH_TYPES),
LintId::of(USAGE_OF_TY_TYKIND),
],
);
}

View File

@ -38,6 +38,8 @@ declare_lint! {
"types, variants, traits and type parameters should have camel case names"
}
declare_lint_pass!(NonCamelCaseTypes => [NON_CAMEL_CASE_TYPES]);
fn char_has_case(c: char) -> bool {
c.is_lowercase() || c.is_uppercase()
}
@ -105,9 +107,6 @@ fn to_camel_case(s: &str) -> String {
.0
}
#[derive(Copy, Clone)]
pub struct NonCamelCaseTypes;
impl NonCamelCaseTypes {
fn check_case(&self, cx: &EarlyContext<'_>, sort: &str, ident: &Ident) {
let name = &ident.name.as_str();
@ -126,16 +125,6 @@ impl NonCamelCaseTypes {
}
}
impl LintPass for NonCamelCaseTypes {
fn name(&self) -> &'static str {
"NonCamelCaseTypes"
}
fn get_lints(&self) -> LintArray {
lint_array!(NON_CAMEL_CASE_TYPES)
}
}
impl EarlyLintPass for NonCamelCaseTypes {
fn check_item(&mut self, cx: &EarlyContext<'_>, it: &ast::Item) {
let has_repr_c = it.attrs
@ -173,8 +162,7 @@ declare_lint! {
"variables, methods, functions, lifetime parameters and modules should have snake case names"
}
#[derive(Copy, Clone)]
pub struct NonSnakeCase;
declare_lint_pass!(NonSnakeCase => [NON_SNAKE_CASE]);
impl NonSnakeCase {
fn to_snake_case(mut str: &str) -> String {
@ -256,16 +244,6 @@ impl NonSnakeCase {
}
}
impl LintPass for NonSnakeCase {
fn name(&self) -> &'static str {
"NonSnakeCase"
}
fn get_lints(&self) -> LintArray {
lint_array!(NON_SNAKE_CASE)
}
}
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonSnakeCase {
fn check_mod(&mut self, cx: &LateContext<'_, '_>, _: &'tcx hir::Mod, _: Span, id: hir::HirId) {
if id != hir::CRATE_HIR_ID {
@ -387,8 +365,7 @@ declare_lint! {
"static constants should have uppercase identifiers"
}
#[derive(Copy, Clone)]
pub struct NonUpperCaseGlobals;
declare_lint_pass!(NonUpperCaseGlobals => [NON_UPPER_CASE_GLOBALS]);
impl NonUpperCaseGlobals {
fn check_upper_case(cx: &LateContext<'_, '_>, sort: &str, ident: &Ident) {
@ -410,16 +387,6 @@ impl NonUpperCaseGlobals {
}
}
impl LintPass for NonUpperCaseGlobals {
fn name(&self) -> &'static str {
"NonUpperCaseGlobals"
}
fn get_lints(&self) -> LintArray {
lint_array!(NON_UPPER_CASE_GLOBALS)
}
}
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonUpperCaseGlobals {
fn check_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::Item) {
match it.node {

View File

@ -49,23 +49,14 @@ pub struct TypeLimits {
negated_expr_id: hir::HirId,
}
impl_lint_pass!(TypeLimits => [UNUSED_COMPARISONS, OVERFLOWING_LITERALS]);
impl TypeLimits {
pub fn new() -> TypeLimits {
TypeLimits { negated_expr_id: hir::DUMMY_HIR_ID }
}
}
impl LintPass for TypeLimits {
fn name(&self) -> &'static str {
"TypeLimits"
}
fn get_lints(&self) -> LintArray {
lint_array!(UNUSED_COMPARISONS,
OVERFLOWING_LITERALS)
}
}
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits {
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx hir::Expr) {
match e.node {
@ -104,7 +95,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits {
report_bin_hex_error(
cx,
e,
ty::Int(t),
attr::IntType::SignedInt(t),
repr_str,
v,
negative,
@ -159,7 +150,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits {
report_bin_hex_error(
cx,
e,
ty::Uint(t),
attr::IntType::UnsignedInt(t),
repr_str,
lit_val,
false,
@ -321,7 +312,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits {
//
// No suggestion for: `isize`, `usize`.
fn get_type_suggestion<'a>(
t: &ty::TyKind<'_>,
t: Ty<'_>,
val: u128,
negative: bool,
) -> Option<String> {
@ -347,14 +338,14 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits {
}
}
}
match t {
&ty::Int(i) => find_fit!(i, val, negative,
match t.sty {
ty::Int(i) => find_fit!(i, val, negative,
I8 => [U8] => [I16, I32, I64, I128],
I16 => [U16] => [I32, I64, I128],
I32 => [U32] => [I64, I128],
I64 => [U64] => [I128],
I128 => [U128] => []),
&ty::Uint(u) => find_fit!(u, val, negative,
ty::Uint(u) => find_fit!(u, val, negative,
U8 => [U8, U16, U32, U64, U128] => [],
U16 => [U16, U32, U64, U128] => [],
U32 => [U32, U64, U128] => [],
@ -367,25 +358,21 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits {
fn report_bin_hex_error(
cx: &LateContext<'_, '_>,
expr: &hir::Expr,
ty: ty::TyKind<'_>,
ty: attr::IntType,
repr_str: String,
val: u128,
negative: bool,
) {
let size = layout::Integer::from_attr(&cx.tcx, ty).size();
let (t, actually) = match ty {
ty::Int(t) => {
let ity = attr::IntType::SignedInt(t);
let size = layout::Integer::from_attr(&cx.tcx, ity).size();
attr::IntType::SignedInt(t) => {
let actually = sign_extend(val, size) as i128;
(format!("{:?}", t), actually.to_string())
}
ty::Uint(t) => {
let ity = attr::IntType::UnsignedInt(t);
let size = layout::Integer::from_attr(&cx.tcx, ity).size();
attr::IntType::UnsignedInt(t) => {
let actually = truncate(val, size);
(format!("{:?}", t), actually.to_string())
}
_ => bug!(),
};
let mut err = cx.struct_span_lint(
OVERFLOWING_LITERALS,
@ -398,7 +385,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits {
repr_str, val, t, actually, t
));
if let Some(sugg_ty) =
get_type_suggestion(&cx.tables.node_type(expr.hir_id).sty, val, negative)
get_type_suggestion(&cx.tables.node_type(expr.hir_id), val, negative)
{
if let Some(pos) = repr_str.chars().position(|c| c == 'i' || c == 'u') {
let (sans_suffix, _) = repr_str.split_at(pos);
@ -424,6 +411,8 @@ declare_lint! {
"proper use of libc types in foreign modules"
}
declare_lint_pass!(ImproperCTypes => [IMPROPER_CTYPES]);
struct ImproperCTypesVisitor<'a, 'tcx: 'a> {
cx: &'a LateContext<'a, 'tcx>,
}
@ -793,19 +782,6 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
}
}
#[derive(Copy, Clone)]
pub struct ImproperCTypes;
impl LintPass for ImproperCTypes {
fn name(&self) -> &'static str {
"ImproperCTypes"
}
fn get_lints(&self) -> LintArray {
lint_array!(IMPROPER_CTYPES)
}
}
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ImproperCTypes {
fn check_foreign_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::ForeignItem) {
let mut vis = ImproperCTypesVisitor { cx };
@ -824,17 +800,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ImproperCTypes {
}
}
pub struct VariantSizeDifferences;
impl LintPass for VariantSizeDifferences {
fn name(&self) -> &'static str {
"VariantSizeDifferences"
}
fn get_lints(&self) -> LintArray {
lint_array!(VARIANT_SIZE_DIFFERENCES)
}
}
declare_lint_pass!(VariantSizeDifferences => [VARIANT_SIZE_DIFFERENCES]);
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for VariantSizeDifferences {
fn check_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::Item) {

View File

@ -32,18 +32,7 @@ declare_lint! {
"unused result of an expression in a statement"
}
#[derive(Copy, Clone)]
pub struct UnusedResults;
impl LintPass for UnusedResults {
fn name(&self) -> &'static str {
"UnusedResults"
}
fn get_lints(&self) -> LintArray {
lint_array!(UNUSED_MUST_USE, UNUSED_RESULTS)
}
}
declare_lint_pass!(UnusedResults => [UNUSED_MUST_USE, UNUSED_RESULTS]);
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults {
fn check_stmt(&mut self, cx: &LateContext<'_, '_>, s: &hir::Stmt) {
@ -203,18 +192,7 @@ declare_lint! {
"path statements with no effect"
}
#[derive(Copy, Clone)]
pub struct PathStatements;
impl LintPass for PathStatements {
fn name(&self) -> &'static str {
"PathStatements"
}
fn get_lints(&self) -> LintArray {
lint_array!(PATH_STATEMENTS)
}
}
declare_lint_pass!(PathStatements => [PATH_STATEMENTS]);
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for PathStatements {
fn check_stmt(&mut self, cx: &LateContext<'_, '_>, s: &hir::Stmt) {
@ -232,18 +210,7 @@ declare_lint! {
"detects attributes that were not used by the compiler"
}
#[derive(Copy, Clone)]
pub struct UnusedAttributes;
impl LintPass for UnusedAttributes {
fn name(&self) -> &'static str {
"UnusedAttributes"
}
fn get_lints(&self) -> LintArray {
lint_array!(UNUSED_ATTRIBUTES)
}
}
declare_lint_pass!(UnusedAttributes => [UNUSED_ATTRIBUTES]);
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedAttributes {
fn check_attribute(&mut self, cx: &LateContext<'_, '_>, attr: &ast::Attribute) {
@ -305,8 +272,7 @@ declare_lint! {
"`if`, `match`, `while` and `return` do not need parentheses"
}
#[derive(Copy, Clone)]
pub struct UnusedParens;
declare_lint_pass!(UnusedParens => [UNUSED_PARENS]);
impl UnusedParens {
fn check_unused_parens_expr(&self,
@ -383,16 +349,6 @@ impl UnusedParens {
}
}
impl LintPass for UnusedParens {
fn name(&self) -> &'static str {
"UnusedParens"
}
fn get_lints(&self) -> LintArray {
lint_array!(UNUSED_PARENS)
}
}
impl EarlyLintPass for UnusedParens {
fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) {
use syntax::ast::ExprKind::*;
@ -465,8 +421,7 @@ declare_lint! {
"unnecessary braces around an imported item"
}
#[derive(Copy, Clone)]
pub struct UnusedImportBraces;
declare_lint_pass!(UnusedImportBraces => [UNUSED_IMPORT_BRACES]);
impl UnusedImportBraces {
fn check_use_tree(&self, cx: &EarlyContext<'_>, use_tree: &ast::UseTree, item: &ast::Item) {
@ -505,16 +460,6 @@ impl UnusedImportBraces {
}
}
impl LintPass for UnusedImportBraces {
fn name(&self) -> &'static str {
"UnusedImportBraces"
}
fn get_lints(&self) -> LintArray {
lint_array!(UNUSED_IMPORT_BRACES)
}
}
impl EarlyLintPass for UnusedImportBraces {
fn check_item(&mut self, cx: &EarlyContext<'_>, item: &ast::Item) {
if let ast::ItemKind::Use(ref use_tree) = item.node {
@ -529,18 +474,7 @@ declare_lint! {
"detects unnecessary allocations that can be eliminated"
}
#[derive(Copy, Clone)]
pub struct UnusedAllocation;
impl LintPass for UnusedAllocation {
fn name(&self) -> &'static str {
"UnusedAllocation"
}
fn get_lints(&self) -> LintArray {
lint_array!(UNUSED_ALLOCATION)
}
}
declare_lint_pass!(UnusedAllocation => [UNUSED_ALLOCATION]);
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedAllocation {
fn check_expr(&mut self, cx: &LateContext<'_, '_>, e: &hir::Expr) {

View File

@ -14,6 +14,7 @@
#![recursion_limit="256"]
#![deny(rust_2018_idioms)]
#![cfg_attr(not(stage0), deny(internal))]
extern crate libc;
#[allow(unused_extern_crates)]

View File

@ -223,7 +223,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
Some(ref name) => format!("`{}`", name),
None => "value".to_owned(),
};
if let ty::TyKind::Param(param_ty) = ty.sty {
if let ty::Param(param_ty) = ty.sty {
let tcx = self.infcx.tcx;
let generics = tcx.generics_of(self.mir_def_id);
let def_id = generics.type_param(&param_ty, tcx).def_id;
@ -1529,7 +1529,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
if let TerminatorKind::Call {
func: Operand::Constant(box Constant {
literal: ty::Const {
ty: &ty::TyS { sty: ty::TyKind::FnDef(id, _), .. },
ty: &ty::TyS { sty: ty::FnDef(id, _), .. },
..
},
..
@ -1547,7 +1547,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
};
debug!("add_moved_or_invoked_closure_note: closure={:?}", closure);
if let ty::TyKind::Closure(did, _) = self.mir.local_decls[closure].ty.sty {
if let ty::Closure(did, _) = self.mir.local_decls[closure].ty.sty {
let hir_id = self.infcx.tcx.hir().as_local_hir_id(did).unwrap();
if let Some((span, name)) = self.infcx.tcx.typeck_tables_of(did)
@ -1570,7 +1570,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
// Check if we are just moving a closure after it has been invoked.
if let Some(target) = target {
if let ty::TyKind::Closure(did, _) = self.mir.local_decls[target].ty.sty {
if let ty::Closure(did, _) = self.mir.local_decls[target].ty.sty {
let hir_id = self.infcx.tcx.hir().as_local_hir_id(did).unwrap();
if let Some((span, name)) = self.infcx.tcx.typeck_tables_of(did)
@ -1919,7 +1919,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
} else {
let ty = self.infcx.tcx.type_of(self.mir_def_id);
match ty.sty {
ty::TyKind::FnDef(_, _) | ty::TyKind::FnPtr(_) => self.annotate_fn_sig(
ty::FnDef(_, _) | ty::FnPtr(_) => self.annotate_fn_sig(
self.mir_def_id,
self.infcx.tcx.fn_sig(self.mir_def_id),
),
@ -2164,12 +2164,12 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
// anything.
let return_ty = sig.output();
match return_ty.skip_binder().sty {
ty::TyKind::Ref(return_region, _, _) if return_region.has_name() && !is_closure => {
ty::Ref(return_region, _, _) if return_region.has_name() && !is_closure => {
// This is case 1 from above, return type is a named reference so we need to
// search for relevant arguments.
let mut arguments = Vec::new();
for (index, argument) in sig.inputs().skip_binder().iter().enumerate() {
if let ty::TyKind::Ref(argument_region, _, _) = argument.sty {
if let ty::Ref(argument_region, _, _) = argument.sty {
if argument_region == return_region {
// Need to use the `rustc::ty` types to compare against the
// `return_region`. Then use the `rustc::hir` type to get only
@ -2206,7 +2206,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
return_span,
})
}
ty::TyKind::Ref(_, _, _) if is_closure => {
ty::Ref(_, _, _) if is_closure => {
// This is case 2 from above but only for closures, return type is anonymous
// reference so we select
// the first argument.
@ -2215,9 +2215,9 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
// Closure arguments are wrapped in a tuple, so we need to get the first
// from that.
if let ty::TyKind::Tuple(elems) = argument_ty.sty {
if let ty::Tuple(elems) = argument_ty.sty {
let argument_ty = elems.first()?;
if let ty::TyKind::Ref(_, _, _) = argument_ty.sty {
if let ty::Ref(_, _, _) = argument_ty.sty {
return Some(AnnotatedBorrowFnSignature::Closure {
argument_ty,
argument_span,
@ -2227,7 +2227,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
None
}
ty::TyKind::Ref(_, _, _) => {
ty::Ref(_, _, _) => {
// This is also case 2 from above but for functions, return type is still an
// anonymous reference so we select the first argument.
let argument_span = fn_decl.inputs.first()?.span;
@ -2238,7 +2238,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
// We expect the first argument to be a reference.
match argument_ty.sty {
ty::TyKind::Ref(_, _, _) => {}
ty::Ref(_, _, _) => {}
_ => return None,
}
@ -2366,8 +2366,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
// this by hooking into the pretty printer and telling it to label the
// lifetimes without names with the value `'0`.
match ty.sty {
ty::TyKind::Ref(ty::RegionKind::ReLateBound(_, br), _, _)
| ty::TyKind::Ref(
ty::Ref(ty::RegionKind::ReLateBound(_, br), _, _)
| ty::Ref(
ty::RegionKind::RePlaceholder(ty::PlaceholderRegion { name: br, .. }),
_,
_,
@ -2386,7 +2386,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
let mut printer = ty::print::FmtPrinter::new(self.infcx.tcx, &mut s, Namespace::TypeNS);
let region = match ty.sty {
ty::TyKind::Ref(region, _, _) => {
ty::Ref(region, _, _) => {
match region {
ty::RegionKind::ReLateBound(_, br)
| ty::RegionKind::RePlaceholder(ty::PlaceholderRegion { name: br, .. }) => {

View File

@ -1741,7 +1741,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
// no move out from an earlier location) then this is an attempt at initialization
// of the union - we should error in that case.
let tcx = this.infcx.tcx;
if let ty::TyKind::Adt(def, _) = base.ty(this.mir, tcx).ty.sty {
if let ty::Adt(def, _) = base.ty(this.mir, tcx).ty.sty {
if def.is_union() {
if this.move_data.path_map[mpi].iter().any(|moi| {
this.move_data.moves[*moi].source.is_predecessor_of(

View File

@ -532,7 +532,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
if let StatementKind::Assign(_, box Rvalue::Ref(_, _, source)) = &stmt.kind {
let ty = source.ty(self.mir, self.infcx.tcx).ty;
let ty = match ty.sty {
ty::TyKind::Ref(_, ty, _) => ty,
ty::Ref(_, ty, _) => ty,
_ => ty,
};
debug!("borrowed_content_source: ty={:?}", ty);
@ -557,7 +557,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
let ty = source.ty(self.mir, self.infcx.tcx).ty;
let ty = match ty.sty {
ty::TyKind::Ref(_, ty, _) => ty,
ty::Ref(_, ty, _) => ty,
_ => ty,
};
debug!("borrowed_content_source: ty={:?}", ty);

View File

@ -5,7 +5,7 @@ use rustc::mir::{
Mutability, Operand, Place, PlaceBase, Projection, ProjectionElem, Static, StaticKind,
};
use rustc::mir::{Terminator, TerminatorKind};
use rustc::ty::{self, Const, DefIdTree, TyS, TyKind, TyCtxt};
use rustc::ty::{self, Const, DefIdTree, TyS, TyCtxt};
use rustc_data_structures::indexed_vec::Idx;
use syntax_pos::Span;
use syntax_pos::symbol::keywords;
@ -261,7 +261,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
// Otherwise, check if the name is the self kewyord - in which case
// we have an explicit self. Do the same thing in this case and check
// for a `self: &mut Self` to suggest removing the `&mut`.
if let ty::TyKind::Ref(
if let ty::Ref(
_, _, hir::Mutability::MutMutable
) = local_decl.ty.sty {
true
@ -476,7 +476,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
func: Operand::Constant(box Constant {
literal: Const {
ty: &TyS {
sty: TyKind::FnDef(id, substs),
sty: ty::FnDef(id, substs),
..
},
..
@ -633,8 +633,8 @@ fn annotate_struct_field(
field: &mir::Field,
) -> Option<(Span, String)> {
// Expect our local to be a reference to a struct of some kind.
if let ty::TyKind::Ref(_, ty, _) = ty.sty {
if let ty::TyKind::Adt(def, _) = ty.sty {
if let ty::Ref(_, ty, _) = ty.sty {
if let ty::Adt(def, _) = ty.sty {
let field = def.all_fields().nth(field.index())?;
// Use the HIR types to construct the diagnostic message.
let hir_id = tcx.hir().as_local_hir_id(field.did)?;

View File

@ -589,7 +589,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
// Check the type for a trait object.
return match ty.sty {
// `&dyn Trait`
ty::TyKind::Ref(_, ty, _) if ty.is_trait() => true,
ty::Ref(_, ty, _) if ty.is_trait() => true,
// `Box<dyn Trait>`
_ if ty.is_box() && ty.boxed_ty().is_trait() => true,
// `dyn Trait`

View File

@ -583,7 +583,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
(self.to_error_region(fr), self.to_error_region(outlived_fr))
{
if let Some(ty::TyS {
sty: ty::TyKind::Opaque(did, substs),
sty: ty::Opaque(did, substs),
..
}) = infcx
.tcx

View File

@ -39,7 +39,7 @@ use rustc::traits::{ObligationCause, PredicateObligations};
use rustc::ty::fold::TypeFoldable;
use rustc::ty::subst::{Subst, SubstsRef, UnpackedKind, UserSubsts};
use rustc::ty::{
self, RegionVid, ToPolyTraitRef, Ty, TyCtxt, TyKind, UserType,
self, RegionVid, ToPolyTraitRef, Ty, TyCtxt, UserType,
CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations,
UserTypeAnnotationIndex,
};
@ -746,7 +746,7 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
let (variant, substs) = match base_ty {
PlaceTy { ty, variant_index: Some(variant_index) } => {
match ty.sty {
ty::TyKind::Adt(adt_def, substs) => (&adt_def.variants[variant_index], substs),
ty::Adt(adt_def, substs) => (&adt_def.variants[variant_index], substs),
_ => bug!("can't have downcast of non-adt type"),
}
}
@ -1136,7 +1136,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
category: ConstraintCategory,
) -> Fallible<()> {
if let Err(terr) = self.sub_types(sub, sup, locations, category) {
if let TyKind::Opaque(..) = sup.sty {
if let ty::Opaque(..) = sup.sty {
// When you have `let x: impl Foo = ...` in a closure,
// the resulting inferend values are stored with the
// def-id of the base function.
@ -1389,7 +1389,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
} => {
let place_type = place.ty(mir, tcx).ty;
let adt = match place_type.sty {
TyKind::Adt(adt, _) if adt.is_enum() => adt,
ty::Adt(adt, _) if adt.is_enum() => adt,
_ => {
span_bug!(
stmt.source_info.span,

View File

@ -425,7 +425,7 @@ impl<'b, 'a, 'gcx, 'tcx> Gatherer<'b, 'a, 'gcx, 'tcx> {
base,
elem: ProjectionElem::Field(_, _),
}) if match base.ty(self.builder.mir, self.builder.tcx).ty.sty {
ty::TyKind::Adt(def, _) if def.is_union() => true,
ty::Adt(def, _) if def.is_union() => true,
_ => false,
} => base,
// Otherwise, lookup the place.

View File

@ -1754,7 +1754,7 @@ fn specialize<'p, 'a: 'p, 'tcx: 'a>(
// they should be pointing to memory is when they are subslices of nonzero
// slices
let (opt_ptr, n, ty) = match value.ty.sty {
ty::TyKind::Array(t, n) => {
ty::Array(t, n) => {
match value.val {
ConstValue::ByRef(ptr, alloc) => (
Some((ptr, alloc)),
@ -1767,7 +1767,7 @@ fn specialize<'p, 'a: 'p, 'tcx: 'a>(
),
}
},
ty::TyKind::Slice(t) => {
ty::Slice(t) => {
match value.val {
ConstValue::Slice(ptr, n) => (
ptr.to_ptr().ok().map(|ptr| (

View File

@ -10,7 +10,7 @@ use rustc::middle::expr_use_visitor as euv;
use rustc::middle::mem_categorization::cmt_;
use rustc::middle::region;
use rustc::session::Session;
use rustc::ty::{self, Ty, TyCtxt, TyKind};
use rustc::ty::{self, Ty, TyCtxt};
use rustc::ty::subst::{InternalSubsts, SubstsRef};
use rustc::lint;
use rustc_errors::{Applicability, DiagnosticBuilder};
@ -481,7 +481,7 @@ fn check_exhaustive<'p, 'a: 'p, 'tcx: 'a>(
}
let patterns = witnesses.iter().map(|p| (**p).clone()).collect::<Vec<Pattern<'_>>>();
if patterns.len() < 4 {
for sp in maybe_point_at_variant(cx, &scrut_ty.sty, patterns.as_slice()) {
for sp in maybe_point_at_variant(cx, scrut_ty, patterns.as_slice()) {
err.span_label(sp, "not covered");
}
}
@ -498,11 +498,11 @@ fn check_exhaustive<'p, 'a: 'p, 'tcx: 'a>(
fn maybe_point_at_variant(
cx: &mut MatchCheckCtxt<'a, 'tcx>,
sty: &TyKind<'tcx>,
ty: Ty<'tcx>,
patterns: &[Pattern<'_>],
) -> Vec<Span> {
let mut covered = vec![];
if let ty::Adt(def, _) = sty {
if let ty::Adt(def, _) = ty.sty {
// Don't point at variants that have already been covered due to other patterns to avoid
// visual clutter
for pattern in patterns {
@ -518,7 +518,7 @@ fn maybe_point_at_variant(
.map(|field_pattern| field_pattern.pattern.clone())
.collect::<Vec<_>>();
covered.extend(
maybe_point_at_variant(cx, sty, subpatterns.as_slice()),
maybe_point_at_variant(cx, ty, subpatterns.as_slice()),
);
}
}
@ -526,7 +526,7 @@ fn maybe_point_at_variant(
let subpatterns = subpatterns.iter()
.map(|field_pattern| field_pattern.pattern.clone())
.collect::<Vec<_>>();
covered.extend(maybe_point_at_variant(cx, sty, subpatterns.as_slice()));
covered.extend(maybe_point_at_variant(cx, ty, subpatterns.as_slice()));
}
}
}

View File

@ -28,6 +28,7 @@ Rust MIR: a lowered representation of Rust. Also: an experiment!
#![recursion_limit="256"]
#![deny(rust_2018_idioms)]
#![cfg_attr(not(stage0), deny(internal))]
#![allow(explicit_outlives_requirements)]
#[macro_use] extern crate log;

View File

@ -4,7 +4,7 @@ use rustc::hir::intravisit::FnKind;
use rustc::hir::map::blocks::FnLikeNode;
use rustc::lint::builtin::UNCONDITIONAL_RECURSION;
use rustc::mir::{self, Mir, TerminatorKind};
use rustc::ty::{AssociatedItem, AssociatedItemContainer, Instance, TyCtxt, TyKind};
use rustc::ty::{self, AssociatedItem, AssociatedItemContainer, Instance, TyCtxt};
use rustc::ty::subst::InternalSubsts;
pub fn check(tcx: TyCtxt<'a, 'tcx, 'tcx>,
@ -86,7 +86,7 @@ fn check_fn_for_unconditional_recursion(tcx: TyCtxt<'a, 'tcx, 'tcx>,
TerminatorKind::Call { ref func, .. } => {
let func_ty = func.ty(mir, tcx);
if let TyKind::FnDef(fn_def_id, substs) = func_ty.sty {
if let ty::FnDef(fn_def_id, substs) = func_ty.sty {
let (call_fn_id, call_substs) =
if let Some(instance) = Instance::resolve(tcx,
param_env,

View File

@ -2,7 +2,7 @@
use rustc::mir::{Constant, Location, Place, PlaceBase, Mir, Operand, ProjectionElem, Rvalue, Local};
use rustc::mir::visit::{MutVisitor, Visitor};
use rustc::ty::{TyCtxt, TyKind};
use rustc::ty::{self, TyCtxt};
use rustc::util::nodemap::{FxHashMap, FxHashSet};
use rustc_data_structures::indexed_vec::Idx;
use std::mem;
@ -90,7 +90,7 @@ impl<'b, 'a, 'tcx> Visitor<'tcx> for OptimizationFinder<'b, 'a, 'tcx> {
if let Rvalue::Len(ref place) = *rvalue {
let place_ty = place.ty(&self.mir.local_decls, self.tcx).ty;
if let TyKind::Array(_, len) = place_ty.sty {
if let ty::Array(_, len) = place_ty.sty {
let span = self.mir.source_info(location).span;
let ty = self.tcx.types.usize;
let constant = Constant { span, ty, literal: len, user_ty: None };

View File

@ -3,7 +3,7 @@
use rustc::hir::def_id::DefId;
use rustc::middle::lang_items::LangItem;
use rustc::mir::*;
use rustc::ty::{List, Ty, TyCtxt, TyKind};
use rustc::ty::{self, List, Ty, TyCtxt};
use rustc_data_structures::indexed_vec::{Idx};
use crate::transform::{MirPass, MirSource};
@ -183,8 +183,8 @@ impl RhsKind {
fn sign_of_128bit(ty: Ty<'_>) -> Option<bool> {
match ty.sty {
TyKind::Int(syntax::ast::IntTy::I128) => Some(true),
TyKind::Uint(syntax::ast::UintTy::U128) => Some(false),
ty::Int(syntax::ast::IntTy::I128) => Some(true),
ty::Uint(syntax::ast::UintTy::U128) => Some(false),
_ => None,
}
}

View File

@ -12,6 +12,7 @@
#![recursion_limit="256"]
#![deny(rust_2018_idioms)]
#![cfg_attr(not(stage0), deny(internal))]
#[macro_use]
extern crate rustc;

View File

@ -1,6 +1,7 @@
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
#![deny(rust_2018_idioms)]
#![cfg_attr(not(stage0), deny(internal))]
#![feature(nll)]
#![feature(rustc_diagnostic_macros)]

View File

@ -8,6 +8,7 @@
#![recursion_limit="256"]
#![deny(rust_2018_idioms)]
#![cfg_attr(not(stage0), deny(internal))]
pub use rustc::hir::def::{Namespace, PerNS};

View File

@ -2,6 +2,7 @@
#![feature(custom_attribute)]
#![feature(nll)]
#![deny(rust_2018_idioms)]
#![cfg_attr(not(stage0), deny(internal))]
#![allow(unused_attributes)]
#![recursion_limit="256"]

View File

@ -16,6 +16,7 @@
#![feature(step_trait)]
#![deny(rust_2018_idioms)]
#![cfg_attr(not(stage0), deny(internal))]
#[macro_use] extern crate log;

View File

@ -2,6 +2,7 @@
//! the guts are broken up into modules; see the comments in those modules.
#![deny(rust_2018_idioms)]
#![cfg_attr(not(stage0), deny(internal))]
#![feature(crate_visibility_modifier)]
#![feature(in_band_lifetimes)]

View File

@ -99,11 +99,6 @@ enum GenericArgPosition {
MethodCall,
}
/// Dummy type used for the `Self` of a `TraitRef` created for converting
/// a trait object, and which gets removed in `ExistentialTraitRef`.
/// This type must not appear anywhere in other converted types.
const TRAIT_OBJECT_DUMMY_SELF: ty::TyKind<'static> = ty::Infer(ty::FreshTy(0));
impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
pub fn ast_region_to_region(&self,
lifetime: &hir::Lifetime,
@ -595,7 +590,9 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
infer_types,
);
let is_object = self_ty.map_or(false, |ty| ty.sty == TRAIT_OBJECT_DUMMY_SELF);
let is_object = self_ty.map_or(false, |ty| {
ty == self.tcx().types.trait_object_dummy_self
});
let default_needs_object_self = |param: &ty::GenericParamDef| {
if let GenericParamDefKind::Type { has_default, .. } = param.kind {
if is_object && has_default {
@ -956,10 +953,10 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
}
/// Transform a `PolyTraitRef` into a `PolyExistentialTraitRef` by
/// removing the dummy `Self` type (`TRAIT_OBJECT_DUMMY_SELF`).
/// removing the dummy `Self` type (`trait_object_dummy_self`).
fn trait_ref_to_existential(&self, trait_ref: ty::TraitRef<'tcx>)
-> ty::ExistentialTraitRef<'tcx> {
if trait_ref.self_ty().sty != TRAIT_OBJECT_DUMMY_SELF {
if trait_ref.self_ty() != self.tcx().types.trait_object_dummy_self {
bug!("trait_ref_to_existential called on {:?} with non-dummy Self", trait_ref);
}
ty::ExistentialTraitRef::erase_self_ty(self.tcx(), trait_ref)
@ -980,7 +977,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
}
let mut projection_bounds = Vec::new();
let dummy_self = tcx.mk_ty(TRAIT_OBJECT_DUMMY_SELF);
let dummy_self = self.tcx().types.trait_object_dummy_self;
let (principal, potential_assoc_types) = self.instantiate_poly_trait_ref(
&trait_bounds[0],
dummy_self,
@ -1030,7 +1027,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
}
ty::Predicate::Projection(pred) => {
// A `Self` within the original bound will be substituted with a
// `TRAIT_OBJECT_DUMMY_SELF`, so check for that.
// `trait_object_dummy_self`, so check for that.
let references_self =
pred.skip_binder().ty.walk().any(|t| t == dummy_self);
@ -1130,7 +1127,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
err.emit();
}
// Erase the `dummy_self` (`TRAIT_OBJECT_DUMMY_SELF`) used above.
// Erase the `dummy_self` (`trait_object_dummy_self`) used above.
let existential_principal = principal.map_bound(|trait_ref| {
self.trait_ref_to_existential(trait_ref)
});

View File

@ -3,7 +3,7 @@ use crate::constrained_generic_params::{identify_constrained_generic_params, Par
use crate::hir::def_id::DefId;
use rustc::traits::{self, ObligationCauseCode};
use rustc::ty::{self, Lift, Ty, TyCtxt, TyKind, GenericParamDefKind, TypeFoldable, ToPredicate};
use rustc::ty::{self, Lift, Ty, TyCtxt, GenericParamDefKind, TypeFoldable, ToPredicate};
use rustc::ty::subst::{Subst, InternalSubsts};
use rustc::util::nodemap::{FxHashSet, FxHashMap};
use rustc::mir::interpret::ConstValue;
@ -354,7 +354,7 @@ fn check_item_type<'a, 'tcx>(
let mut forbid_unsized = true;
if allow_foreign_ty {
if let TyKind::Foreign(_) = fcx.tcx.struct_tail(item_ty).sty {
if let ty::Foreign(_) = fcx.tcx.struct_tail(item_ty).sty {
forbid_unsized = false;
}
}

View File

@ -71,6 +71,7 @@ This API is completely unstable and subject to change.
#![recursion_limit="256"]
#![deny(rust_2018_idioms)]
#![cfg_attr(not(stage0), deny(internal))]
#![allow(explicit_outlives_requirements)]
#[macro_use] extern crate log;

View File

@ -1,4 +1,5 @@
#![deny(rust_2018_idioms)]
#![cfg_attr(not(stage0), deny(internal))]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/",
html_playground_url = "https://play.rust-lang.org/")]

View File

@ -8,6 +8,7 @@
test(attr(deny(warnings))))]
#![deny(rust_2018_idioms)]
#![cfg_attr(not(stage0), deny(internal))]
#![feature(crate_visibility_modifier)]
#![feature(label_break_value)]

View File

@ -3,6 +3,7 @@
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
#![deny(rust_2018_idioms)]
#![cfg_attr(not(stage0), deny(internal))]
#![feature(in_band_lifetimes)]
#![feature(proc_macro_diagnostic)]

View File

@ -7,6 +7,7 @@
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
#![deny(rust_2018_idioms)]
#![cfg_attr(not(stage0), deny(internal))]
#![feature(const_fn)]
#![feature(crate_visibility_modifier)]

View File

@ -26,21 +26,14 @@ pub fn plugin_registrar(reg: &mut Registry) {
reg.register_attribute("whitelisted_attr".to_string(), Whitelisted);
}
declare_lint!(MISSING_WHITELISTED_ATTR, Deny,
"Checks for missing `whitelisted_attr` attribute");
struct MissingWhitelistedAttrPass;
impl LintPass for MissingWhitelistedAttrPass {
fn name(&self) -> &'static str {
"MissingWhitelistedAttrPass"
}
fn get_lints(&self) -> LintArray {
lint_array!(MISSING_WHITELISTED_ATTR)
}
declare_lint! {
MISSING_WHITELISTED_ATTR,
Deny,
"Checks for missing `whitelisted_attr` attribute"
}
declare_lint_pass!(MissingWhitelistedAttrPass => [MISSING_WHITELISTED_ATTR]);
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingWhitelistedAttrPass {
fn check_fn(&mut self,
cx: &LateContext<'a, 'tcx>,

View File

@ -12,20 +12,14 @@ use rustc_plugin::Registry;
use rustc::hir;
use syntax::attr;
declare_lint!(CRATE_NOT_OKAY, Warn, "crate not marked with #![crate_okay]");
struct Pass;
impl LintPass for Pass {
fn name(&self) -> &'static str {
"Pass"
}
fn get_lints(&self) -> LintArray {
lint_array!(CRATE_NOT_OKAY)
}
declare_lint! {
CRATE_NOT_OKAY,
Warn,
"crate not marked with #![crate_okay]"
}
declare_lint_pass!(Pass => [CRATE_NOT_OKAY]);
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
fn check_crate(&mut self, cx: &LateContext, krate: &hir::Crate) {
if !attr::contains_name(&krate.attrs, "crate_okay") {

View File

@ -16,17 +16,7 @@ declare_lint!(TEST_LINT, Warn, "Warn about items named 'lintme'");
declare_lint!(PLEASE_LINT, Warn, "Warn about items named 'pleaselintme'");
struct Pass;
impl LintPass for Pass {
fn name(&self) -> &'static str {
"Pass"
}
fn get_lints(&self) -> LintArray {
lint_array!(TEST_LINT, PLEASE_LINT)
}
}
declare_lint_pass!(Pass => [TEST_LINT, PLEASE_LINT]);
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
fn check_item(&mut self, cx: &LateContext, it: &hir::Item) {

View File

@ -16,17 +16,7 @@ use rustc_plugin::Registry;
use syntax::ast;
declare_lint!(TEST_LINT, Warn, "Warn about items named 'lintme'");
struct Pass;
impl LintPass for Pass {
fn name(&self) -> &'static str {
"Pass"
}
fn get_lints(&self) -> LintArray {
lint_array!(TEST_LINT)
}
}
declare_lint_pass!(Pass => [TEST_LINT]);
impl EarlyLintPass for Pass {
fn check_item(&mut self, cx: &EarlyContext, it: &ast::Item) {

View File

@ -19,17 +19,7 @@ declare_tool_lint!(
Warn, "Warn about other stuff"
);
struct Pass;
impl LintPass for Pass {
fn name(&self) -> &'static str {
"Pass"
}
fn get_lints(&self) -> LintArray {
lint_array!(TEST_LINT, TEST_GROUP)
}
}
declare_lint_pass!(Pass => [TEST_LINT, TEST_GROUP]);
impl EarlyLintPass for Pass {
fn check_item(&mut self, cx: &EarlyContext, it: &ast::Item) {

View File

@ -0,0 +1,22 @@
// compile-flags: -Z unstable-options
#![feature(rustc_private)]
extern crate rustc_data_structures;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use std::collections::{HashMap, HashSet};
#[deny(default_hash_types)]
fn main() {
let _map: HashMap<String, String> = HashMap::default();
//~^ ERROR Prefer FxHashMap over HashMap, it has better performance
//~^^ ERROR Prefer FxHashMap over HashMap, it has better performance
let _set: HashSet<String> = HashSet::default();
//~^ ERROR Prefer FxHashSet over HashSet, it has better performance
//~^^ ERROR Prefer FxHashSet over HashSet, it has better performance
// test that the lint doesn't also match the Fx variants themselves
let _fx_map: FxHashMap<String, String> = FxHashMap::default();
let _fx_set: FxHashSet<String> = FxHashSet::default();
}

View File

@ -0,0 +1,39 @@
error: Prefer FxHashMap over HashMap, it has better performance
--> $DIR/default_hash_types.rs:12:15
|
LL | let _map: HashMap<String, String> = HashMap::default();
| ^^^^^^^ help: use: `FxHashMap`
|
note: lint level defined here
--> $DIR/default_hash_types.rs:10:8
|
LL | #[deny(default_hash_types)]
| ^^^^^^^^^^^^^^^^^^
= note: a `use rustc_data_structures::fx::FxHashMap` may be necessary
error: Prefer FxHashMap over HashMap, it has better performance
--> $DIR/default_hash_types.rs:12:41
|
LL | let _map: HashMap<String, String> = HashMap::default();
| ^^^^^^^ help: use: `FxHashMap`
|
= note: a `use rustc_data_structures::fx::FxHashMap` may be necessary
error: Prefer FxHashSet over HashSet, it has better performance
--> $DIR/default_hash_types.rs:15:15
|
LL | let _set: HashSet<String> = HashSet::default();
| ^^^^^^^ help: use: `FxHashSet`
|
= note: a `use rustc_data_structures::fx::FxHashSet` may be necessary
error: Prefer FxHashSet over HashSet, it has better performance
--> $DIR/default_hash_types.rs:15:33
|
LL | let _set: HashSet<String> = HashSet::default();
| ^^^^^^^ help: use: `FxHashSet`
|
= note: a `use rustc_data_structures::fx::FxHashSet` may be necessary
error: aborting due to 4 previous errors

View File

@ -0,0 +1,49 @@
// compile-flags: -Z unstable-options
#![feature(rustc_private)]
extern crate rustc;
use rustc::ty::{self, Ty, TyKind};
#[deny(usage_of_ty_tykind)]
fn main() {
let sty = TyKind::Bool; //~ ERROR usage of `ty::TyKind::<kind>`
match sty {
TyKind::Bool => (), //~ ERROR usage of `ty::TyKind::<kind>`
TyKind::Char => (), //~ ERROR usage of `ty::TyKind::<kind>`
TyKind::Int(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
TyKind::Uint(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
TyKind::Float(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
TyKind::Adt(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
TyKind::Foreign(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
TyKind::Str => (), //~ ERROR usage of `ty::TyKind::<kind>`
TyKind::Array(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
TyKind::Slice(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
TyKind::RawPtr(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
TyKind::Ref(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
TyKind::FnDef(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
TyKind::FnPtr(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
TyKind::Dynamic(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
TyKind::Closure(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
TyKind::Generator(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
TyKind::GeneratorWitness(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
TyKind::Never => (), //~ ERROR usage of `ty::TyKind::<kind>`
TyKind::Tuple(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
TyKind::Projection(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
TyKind::UnnormalizedProjection(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
TyKind::Opaque(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
TyKind::Param(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
TyKind::Bound(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
TyKind::Placeholder(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
TyKind::Infer(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
TyKind::Error => (), //~ ERROR usage of `ty::TyKind::<kind>`
}
if let ty::Int(int_ty) = sty {}
if let TyKind::Int(int_ty) = sty {} //~ ERROR usage of `ty::TyKind::<kind>`
fn ty_kind(ty_bad: TyKind<'_>, ty_good: Ty<'_>) {} //~ ERROR usage of `ty::TyKind`
}

View File

@ -0,0 +1,196 @@
error: usage of `ty::TyKind::<kind>`
--> $DIR/ty_tykind_usage.rs:11:15
|
LL | let sty = TyKind::Bool;
| ^^^^^^ help: try using ty::<kind> directly: `ty`
|
note: lint level defined here
--> $DIR/ty_tykind_usage.rs:9:8
|
LL | #[deny(usage_of_ty_tykind)]
| ^^^^^^^^^^^^^^^^^^
error: usage of `ty::TyKind::<kind>`
--> $DIR/ty_tykind_usage.rs:14:9
|
LL | TyKind::Bool => (),
| ^^^^^^ help: try using ty::<kind> directly: `ty`
error: usage of `ty::TyKind::<kind>`
--> $DIR/ty_tykind_usage.rs:15:9
|
LL | TyKind::Char => (),
| ^^^^^^ help: try using ty::<kind> directly: `ty`
error: usage of `ty::TyKind::<kind>`
--> $DIR/ty_tykind_usage.rs:16:9
|
LL | TyKind::Int(..) => (),
| ^^^^^^ help: try using ty::<kind> directly: `ty`
error: usage of `ty::TyKind::<kind>`
--> $DIR/ty_tykind_usage.rs:17:9
|
LL | TyKind::Uint(..) => (),
| ^^^^^^ help: try using ty::<kind> directly: `ty`
error: usage of `ty::TyKind::<kind>`
--> $DIR/ty_tykind_usage.rs:18:9
|
LL | TyKind::Float(..) => (),
| ^^^^^^ help: try using ty::<kind> directly: `ty`
error: usage of `ty::TyKind::<kind>`
--> $DIR/ty_tykind_usage.rs:19:9
|
LL | TyKind::Adt(..) => (),
| ^^^^^^ help: try using ty::<kind> directly: `ty`
error: usage of `ty::TyKind::<kind>`
--> $DIR/ty_tykind_usage.rs:20:9
|
LL | TyKind::Foreign(..) => (),
| ^^^^^^ help: try using ty::<kind> directly: `ty`
error: usage of `ty::TyKind::<kind>`
--> $DIR/ty_tykind_usage.rs:21:9
|
LL | TyKind::Str => (),
| ^^^^^^ help: try using ty::<kind> directly: `ty`
error: usage of `ty::TyKind::<kind>`
--> $DIR/ty_tykind_usage.rs:22:9
|
LL | TyKind::Array(..) => (),
| ^^^^^^ help: try using ty::<kind> directly: `ty`
error: usage of `ty::TyKind::<kind>`
--> $DIR/ty_tykind_usage.rs:23:9
|
LL | TyKind::Slice(..) => (),
| ^^^^^^ help: try using ty::<kind> directly: `ty`
error: usage of `ty::TyKind::<kind>`
--> $DIR/ty_tykind_usage.rs:24:9
|
LL | TyKind::RawPtr(..) => (),
| ^^^^^^ help: try using ty::<kind> directly: `ty`
error: usage of `ty::TyKind::<kind>`
--> $DIR/ty_tykind_usage.rs:25:9
|
LL | TyKind::Ref(..) => (),
| ^^^^^^ help: try using ty::<kind> directly: `ty`
error: usage of `ty::TyKind::<kind>`
--> $DIR/ty_tykind_usage.rs:26:9
|
LL | TyKind::FnDef(..) => (),
| ^^^^^^ help: try using ty::<kind> directly: `ty`
error: usage of `ty::TyKind::<kind>`
--> $DIR/ty_tykind_usage.rs:27:9
|
LL | TyKind::FnPtr(..) => (),
| ^^^^^^ help: try using ty::<kind> directly: `ty`
error: usage of `ty::TyKind::<kind>`
--> $DIR/ty_tykind_usage.rs:28:9
|
LL | TyKind::Dynamic(..) => (),
| ^^^^^^ help: try using ty::<kind> directly: `ty`
error: usage of `ty::TyKind::<kind>`
--> $DIR/ty_tykind_usage.rs:29:9
|
LL | TyKind::Closure(..) => (),
| ^^^^^^ help: try using ty::<kind> directly: `ty`
error: usage of `ty::TyKind::<kind>`
--> $DIR/ty_tykind_usage.rs:30:9
|
LL | TyKind::Generator(..) => (),
| ^^^^^^ help: try using ty::<kind> directly: `ty`
error: usage of `ty::TyKind::<kind>`
--> $DIR/ty_tykind_usage.rs:31:9
|
LL | TyKind::GeneratorWitness(..) => (),
| ^^^^^^ help: try using ty::<kind> directly: `ty`
error: usage of `ty::TyKind::<kind>`
--> $DIR/ty_tykind_usage.rs:32:9
|
LL | TyKind::Never => (),
| ^^^^^^ help: try using ty::<kind> directly: `ty`
error: usage of `ty::TyKind::<kind>`
--> $DIR/ty_tykind_usage.rs:33:9
|
LL | TyKind::Tuple(..) => (),
| ^^^^^^ help: try using ty::<kind> directly: `ty`
error: usage of `ty::TyKind::<kind>`
--> $DIR/ty_tykind_usage.rs:34:9
|
LL | TyKind::Projection(..) => (),
| ^^^^^^ help: try using ty::<kind> directly: `ty`
error: usage of `ty::TyKind::<kind>`
--> $DIR/ty_tykind_usage.rs:35:9
|
LL | TyKind::UnnormalizedProjection(..) => (),
| ^^^^^^ help: try using ty::<kind> directly: `ty`
error: usage of `ty::TyKind::<kind>`
--> $DIR/ty_tykind_usage.rs:36:9
|
LL | TyKind::Opaque(..) => (),
| ^^^^^^ help: try using ty::<kind> directly: `ty`
error: usage of `ty::TyKind::<kind>`
--> $DIR/ty_tykind_usage.rs:37:9
|
LL | TyKind::Param(..) => (),
| ^^^^^^ help: try using ty::<kind> directly: `ty`
error: usage of `ty::TyKind::<kind>`
--> $DIR/ty_tykind_usage.rs:38:9
|
LL | TyKind::Bound(..) => (),
| ^^^^^^ help: try using ty::<kind> directly: `ty`
error: usage of `ty::TyKind::<kind>`
--> $DIR/ty_tykind_usage.rs:39:9
|
LL | TyKind::Placeholder(..) => (),
| ^^^^^^ help: try using ty::<kind> directly: `ty`
error: usage of `ty::TyKind::<kind>`
--> $DIR/ty_tykind_usage.rs:40:9
|
LL | TyKind::Infer(..) => (),
| ^^^^^^ help: try using ty::<kind> directly: `ty`
error: usage of `ty::TyKind::<kind>`
--> $DIR/ty_tykind_usage.rs:41:9
|
LL | TyKind::Error => (),
| ^^^^^^ help: try using ty::<kind> directly: `ty`
error: usage of `ty::TyKind::<kind>`
--> $DIR/ty_tykind_usage.rs:46:12
|
LL | if let TyKind::Int(int_ty) = sty {}
| ^^^^^^ help: try using ty::<kind> directly: `ty`
error: usage of `ty::TyKind`
--> $DIR/ty_tykind_usage.rs:48:24
|
LL | fn ty_kind(ty_bad: TyKind<'_>, ty_good: Ty<'_>) {}
| ^^^^^^^^^^
|
= help: try using `ty::Ty` instead
error: aborting due to 31 previous errors

View File

@ -2820,12 +2820,15 @@ impl<'test> TestCx<'test> {
// don't test rustfix with nll right now
} else if self.config.rustfix_coverage {
// Find out which tests have `MachineApplicable` suggestions but are missing
// `run-rustfix` or `run-rustfix-only-machine-applicable` headers
// `run-rustfix` or `run-rustfix-only-machine-applicable` headers.
//
// This will return an empty `Vec` in case the executed test file has a
// `compile-flags: --error-format=xxxx` header with a value other than `json`.
let suggestions = get_suggestions_from_json(
&proc_res.stderr,
&HashSet::new(),
Filter::MachineApplicableOnly
).unwrap();
).unwrap_or_default();
if suggestions.len() > 0
&& !self.props.run_rustfix
&& !self.props.rustfix_only_machine_applicable {