Skip to content

Internal lints: usage_of_qualified_ty & ty_pass_by_reference #60317

New issue

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

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

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Apr 28, 2019
12 changes: 6 additions & 6 deletions src/librustc/infer/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -690,7 +690,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
name: String,
sub: ty::subst::SubstsRef<'tcx>,
pos: usize,
other_ty: &Ty<'tcx>,
other_ty: Ty<'tcx>,
) {
// `value` and `other_value` hold two incomplete type representation for display.
// `name` is the path of both types being compared. `sub`
Expand Down Expand Up @@ -768,10 +768,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
path: String,
sub: ty::subst::SubstsRef<'tcx>,
other_path: String,
other_ty: &Ty<'tcx>,
other_ty: Ty<'tcx>,
) -> Option<()> {
for (i, ta) in sub.types().enumerate() {
if &ta == other_ty {
if ta == other_ty {
self.highlight_outer(&mut t1_out, &mut t2_out, path, sub, i, &other_ty);
return Some(());
}
Expand Down Expand Up @@ -839,7 +839,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
/// Compares two given types, eliding parts that are the same between them and highlighting
/// relevant differences, and return two representation of those types for highlighted printing.
fn cmp(&self, t1: Ty<'tcx>, t2: Ty<'tcx>) -> (DiagnosticStyledString, DiagnosticStyledString) {
fn equals<'tcx>(a: &Ty<'tcx>, b: &Ty<'tcx>) -> bool {
fn equals<'tcx>(a: Ty<'tcx>, b: Ty<'tcx>) -> bool {
match (&a.sty, &b.sty) {
(a, b) if *a == *b => true,
(&ty::Int(_), &ty::Infer(ty::InferTy::IntVar(_)))
Expand Down Expand Up @@ -1099,7 +1099,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
}
};

let span = cause.span(&self.tcx);
let span = cause.span(self.tcx);

diag.span_label(span, terr.to_string());
if let Some((sp, msg)) = secondary_span {
Expand Down Expand Up @@ -1233,7 +1233,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
trace, terr
);

let span = trace.cause.span(&self.tcx);
let span = trace.cause.span(self.tcx);
let failure_code = trace.cause.as_failure_code(terr);
let mut diag = match failure_code {
FailureCode::Error0317(failure_str) => {
Expand Down
10 changes: 5 additions & 5 deletions src/librustc/infer/error_reporting/need_type_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use errors::DiagnosticBuilder;

struct FindLocalByTypeVisitor<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
target_ty: &'a Ty<'tcx>,
target_ty: Ty<'tcx>,
hir_map: &'a hir::map::Map<'gcx>,
found_local_pattern: Option<&'gcx Pat>,
found_arg_pattern: Option<&'gcx Pat>,
Expand All @@ -26,7 +26,7 @@ impl<'a, 'gcx, 'tcx> FindLocalByTypeVisitor<'a, 'gcx, 'tcx> {
Some(ty) => {
let ty = self.infcx.resolve_type_vars_if_possible(&ty);
ty.walk().any(|inner_ty| {
inner_ty == *self.target_ty || match (&inner_ty.sty, &self.target_ty.sty) {
inner_ty == self.target_ty || match (&inner_ty.sty, &self.target_ty.sty) {
(&Infer(TyVar(a_vid)), &Infer(TyVar(b_vid))) => {
self.infcx
.type_variables
Expand Down Expand Up @@ -68,10 +68,10 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for FindLocalByTypeVisitor<'a, 'gcx, 'tcx> {
impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
pub fn extract_type_name(
&self,
ty: &'a Ty<'tcx>,
ty: Ty<'tcx>,
highlight: Option<ty::print::RegionHighlightMode>,
) -> String {
if let ty::Infer(ty::TyVar(ty_vid)) = (*ty).sty {
if let ty::Infer(ty::TyVar(ty_vid)) = ty.sty {
let ty_vars = self.type_variables.borrow();
if let TypeVariableOrigin::TypeParameterDefinition(_, name) =
*ty_vars.var_origin(ty_vid) {
Expand Down Expand Up @@ -102,7 +102,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {

let mut local_visitor = FindLocalByTypeVisitor {
infcx: &self,
target_ty: &ty,
target_ty: ty,
hir_map: &self.tcx.hir(),
found_local_pattern: None,
found_arg_pattern: None,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ impl NiceRegionError<'me, 'gcx, 'tcx> {
);

let mut err = self.tcx().sess.struct_span_err(
cause.span(&self.tcx()),
cause.span(self.tcx()),
&format!(
"implementation of `{}` is not general enough",
self.tcx().def_path_str(trait_def_id),
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/infer/nll_relate/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ where
fn relate_projection_ty(
&mut self,
projection_ty: ty::ProjectionTy<'tcx>,
value_ty: ty::Ty<'tcx>,
value_ty: Ty<'tcx>,
) -> Ty<'tcx> {
use crate::infer::type_variable::TypeVariableOrigin;
use crate::traits::WhereClause;
Expand Down
132 changes: 122 additions & 10 deletions src/librustc/lint/internal.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! 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::hir::{GenericArg, HirId, MutTy, Mutability, Path, PathSegment, QPath, Ty, TyKind};
use crate::lint::{
EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintArray, LintContext, LintPass,
};
Expand Down Expand Up @@ -57,12 +57,28 @@ impl EarlyLintPass for DefaultHashTypes {
declare_lint! {
pub USAGE_OF_TY_TYKIND,
Allow,
"Usage of `ty::TyKind` outside of the `ty::sty` module"
"usage of `ty::TyKind` outside of the `ty::sty` module"
}

declare_lint_pass!(TyKindUsage => [USAGE_OF_TY_TYKIND]);
declare_lint! {
pub TY_PASS_BY_REFERENCE,
Allow,
"passing `Ty` or `TyCtxt` by reference"
}

declare_lint! {
pub USAGE_OF_QUALIFIED_TY,
Allow,
"using `ty::{Ty,TyCtxt}` instead of importing it"
}

declare_lint_pass!(TyTyKind => [
USAGE_OF_TY_TYKIND,
TY_PASS_BY_REFERENCE,
USAGE_OF_QUALIFIED_TY,
]);

impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TyKindUsage {
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TyTyKind {
fn check_path(&mut self, cx: &LateContext<'_, '_>, path: &'tcx Path, _: HirId) {
let segments = path.segments.iter().rev().skip(1).rev();

Expand All @@ -82,16 +98,72 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TyKindUsage {
}

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")
match &ty.node {
TyKind::Path(qpath) => {
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` instead")
.emit();
} else {
if ty.span.ctxt().outer().expn_info().is_some() {
return;
}
if let Some(t) = is_ty_or_ty_ctxt(cx, ty) {
if path.segments.len() > 1 {
cx.struct_span_lint(
USAGE_OF_QUALIFIED_TY,
path.span,
&format!("usage of qualified `ty::{}`", t),
)
.span_suggestion(
path.span,
"try using it unqualified",
t,
// The import probably needs to be changed
Applicability::MaybeIncorrect,
)
.emit();
}
}
}
}
}
}
TyKind::Rptr(
_,
MutTy {
ty: inner_ty,
mutbl: Mutability::MutImmutable,
},
) => {
if let Some(impl_did) = cx.tcx.impl_of_method(ty.hir_id.owner_def_id()) {
if cx.tcx.impl_trait_ref(impl_did).is_some() {
return;
}
}
if let Some(t) = is_ty_or_ty_ctxt(cx, &inner_ty) {
cx.struct_span_lint(
TY_PASS_BY_REFERENCE,
ty.span,
&format!("passing `{}` by reference", t),
)
.span_suggestion(
ty.span,
"try passing by value",
t,
// Changing type of function argument
Applicability::MaybeIncorrect,
)
.emit();
}
}
_ => {}
}
}
}
Expand All @@ -107,3 +179,43 @@ fn lint_ty_kind_usage(cx: &LateContext<'_, '_>, segment: &PathSegment) -> bool {

false
}

fn is_ty_or_ty_ctxt(cx: &LateContext<'_, '_>, ty: &Ty) -> Option<String> {
match &ty.node {
TyKind::Path(qpath) => {
if let QPath::Resolved(_, path) = qpath {
let did = path.def.opt_def_id()?;
if cx.match_def_path(did, &["rustc", "ty", "Ty"]) {
return Some(format!("Ty{}", gen_args(path.segments.last().unwrap())));
} else if cx.match_def_path(did, &["rustc", "ty", "context", "TyCtxt"]) {
return Some(format!("TyCtxt{}", gen_args(path.segments.last().unwrap())));
}
}
}
_ => {}
}

None
}

fn gen_args(segment: &PathSegment) -> String {
if let Some(args) = &segment.args {
let lifetimes = args
.args
.iter()
.filter_map(|arg| {
if let GenericArg::Lifetime(lt) = arg {
Some(lt.name.ident().to_string())
} else {
None
}
})
.collect::<Vec<_>>();

if !lifetimes.is_empty() {
return format!("<{}>", lifetimes.join(", "));
}
}

String::new()
}
8 changes: 4 additions & 4 deletions src/librustc/middle/exported_symbols.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use rustc_data_structures::stable_hasher::{StableHasher, HashStable,
StableHasherResult};
use std::cmp;
use std::mem;
use crate::ty;
use crate::ty::{self, TyCtxt};
use crate::ty::subst::SubstsRef;

/// The SymbolExportLevel of a symbols specifies from which kinds of crates
Expand Down Expand Up @@ -39,7 +39,7 @@ pub enum ExportedSymbol<'tcx> {

impl<'tcx> ExportedSymbol<'tcx> {
pub fn symbol_name(&self,
tcx: ty::TyCtxt<'_, 'tcx, '_>)
tcx: TyCtxt<'_, 'tcx, '_>)
-> ty::SymbolName {
match *self {
ExportedSymbol::NonGeneric(def_id) => {
Expand All @@ -55,7 +55,7 @@ impl<'tcx> ExportedSymbol<'tcx> {
}

pub fn compare_stable(&self,
tcx: ty::TyCtxt<'_, 'tcx, '_>,
tcx: TyCtxt<'_, 'tcx, '_>,
other: &ExportedSymbol<'tcx>)
-> cmp::Ordering {
match *self {
Expand Down Expand Up @@ -92,7 +92,7 @@ impl<'tcx> ExportedSymbol<'tcx> {
}
}

pub fn metadata_symbol_name(tcx: ty::TyCtxt<'_, '_, '_>) -> String {
pub fn metadata_symbol_name(tcx: TyCtxt<'_, '_, '_>) -> String {
format!("rust_metadata_{}_{}",
tcx.original_crate_name(LOCAL_CRATE),
tcx.crate_disambiguator(LOCAL_CRATE).to_fingerprint().to_hex())
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/mir/mono.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ pub enum MonoItem<'tcx> {
}

impl<'tcx> MonoItem<'tcx> {
pub fn size_estimate<'a>(&self, tcx: &TyCtxt<'a, 'tcx, 'tcx>) -> usize {
pub fn size_estimate<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> usize {
match *self {
MonoItem::Fn(instance) => {
// Estimate the size of a function based on how many statements
Expand Down Expand Up @@ -144,7 +144,7 @@ impl<'tcx> CodegenUnit<'tcx> {
base_n::encode(hash, base_n::CASE_INSENSITIVE)
}

pub fn estimate_size<'a>(&mut self, tcx: &TyCtxt<'a, 'tcx, 'tcx>) {
pub fn estimate_size<'a>(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>) {
// Estimate the size of a codegen unit as (approximately) the number of MIR
// statements it corresponds to.
self.size_estimate = Some(self.items.keys().map(|mi| mi.size_estimate(tcx)).sum());
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/mir/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ macro_rules! make_mir_visitor {
}

fn visit_ty(&mut self,
ty: & $($mutability)? Ty<'tcx>,
ty: $(& $mutability)? Ty<'tcx>,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow, that's a neat trick! cc @nikomatsakis how did we not think of this?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

{visit,super}_{local,region,const} (and maybe a few others?) should probably get the same treatment.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

heh, a good question.

_: TyContext) {
self.super_ty(ty);
}
Expand Down Expand Up @@ -864,7 +864,7 @@ macro_rules! make_mir_visitor {
self.visit_ty(& $($mutability)? ty.inferred_ty, TyContext::UserTy(ty.span));
}

fn super_ty(&mut self, _ty: & $($mutability)? Ty<'tcx>) {
fn super_ty(&mut self, _ty: $(& $mutability)? Ty<'tcx>) {
}

fn super_region(&mut self, _region: & $($mutability)? ty::Region<'tcx>) {
Expand Down
8 changes: 4 additions & 4 deletions src/librustc/traits/auto_trait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,11 @@ pub struct AutoTraitInfo<'cx> {
}

pub struct AutoTraitFinder<'a, 'tcx: 'a> {
tcx: &'a TyCtxt<'a, 'tcx, 'tcx>,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
}

impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
pub fn new(tcx: &'a TyCtxt<'a, 'tcx, 'tcx>) -> Self {
pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Self {
AutoTraitFinder { tcx }
}

Expand Down Expand Up @@ -291,7 +291,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
infcx: &InferCtxt<'b, 'tcx, 'c>,
ty_did: DefId,
trait_did: DefId,
ty: ty::Ty<'c>,
ty: Ty<'c>,
param_env: ty::ParamEnv<'c>,
user_env: ty::ParamEnv<'c>,
fresh_preds: &mut FxHashSet<ty::Predicate<'c>>,
Expand Down Expand Up @@ -661,7 +661,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
T: Iterator<Item = Obligation<'cx, ty::Predicate<'cx>>>,
>(
&self,
ty: ty::Ty<'_>,
ty: Ty<'_>,
nested: T,
computed_preds: &'b mut FxHashSet<ty::Predicate<'cx>>,
fresh_preds: &'b mut FxHashSet<ty::Predicate<'cx>>,
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/traits/error_reporting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1242,7 +1242,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
found: ty::PolyTraitRef<'tcx>)
-> DiagnosticBuilder<'tcx>
{
fn build_fn_sig_string<'a, 'gcx, 'tcx>(tcx: ty::TyCtxt<'a, 'gcx, 'tcx>,
fn build_fn_sig_string<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
trait_ref: &ty::TraitRef<'tcx>) -> String {
let inputs = trait_ref.substs.type_at(1);
let sig = if let ty::Tuple(inputs) = inputs.sty {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ pub struct ObligationCause<'tcx> {
}

impl<'tcx> ObligationCause<'tcx> {
pub fn span<'a, 'gcx>(&self, tcx: &TyCtxt<'a, 'gcx, 'tcx>) -> Span {
pub fn span<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Span {
match self.code {
ObligationCauseCode::CompareImplMethodObligation { .. } |
ObligationCauseCode::MainFunctionType |
Expand Down
Loading