Skip to content
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

extend Ty and TyCtxt lints to self types #76914

Merged
merged 4 commits into from
Sep 22, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 27 additions & 5 deletions compiler/rustc_lint/src/internal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext}
use rustc_ast::{Item, ItemKind};
use rustc_data_structures::fx::FxHashMap;
use rustc_errors::Applicability;
use rustc_hir::def::Res;
use rustc_hir::{GenericArg, HirId, MutTy, Mutability, Path, PathSegment, QPath, Ty, TyKind};
use rustc_middle::ty;
use rustc_session::{declare_lint_pass, declare_tool_lint, impl_lint_pass};
use rustc_span::hygiene::{ExpnKind, MacroKind};
use rustc_span::symbol::{sym, Ident, Symbol};
Expand Down Expand Up @@ -177,11 +179,31 @@ fn lint_ty_kind_usage(cx: &LateContext<'_>, segment: &PathSegment<'_>) -> bool {
fn is_ty_or_ty_ctxt(cx: &LateContext<'_>, ty: &Ty<'_>) -> Option<String> {
if let TyKind::Path(qpath) = &ty.kind {
if let QPath::Resolved(_, path) = qpath {
let did = path.res.opt_def_id()?;
if cx.tcx.is_diagnostic_item(sym::Ty, did) {
return Some(format!("Ty{}", gen_args(path.segments.last().unwrap())));
} else if cx.tcx.is_diagnostic_item(sym::TyCtxt, did) {
return Some(format!("TyCtxt{}", gen_args(path.segments.last().unwrap())));
match path.res {
Res::Def(_, did) => {
if cx.tcx.is_diagnostic_item(sym::Ty, did) {
return Some(format!("Ty{}", gen_args(path.segments.last().unwrap())));
} else if cx.tcx.is_diagnostic_item(sym::TyCtxt, did) {
return Some(format!("TyCtxt{}", gen_args(path.segments.last().unwrap())));
}
}
// Only lint on `&Ty` and `&TyCtxt` if it is used outside of a trait.
Res::SelfTy(None, Some((did, _))) => {
if let ty::Adt(adt, substs) = cx.tcx.type_of(did).kind() {
if cx.tcx.is_diagnostic_item(sym::Ty, adt.did) {
// NOTE: This path is currently unreachable as `Ty<'tcx>` is
// defined as a type alias meaning that `impl<'tcx> Ty<'tcx>`
// is not actually allowed.
//
// I(@lcnr) still kept this branch in so we don't miss this
// if we ever change it in the future.
return Some(format!("Ty<{}>", substs[0]));
} else if cx.tcx.is_diagnostic_item(sym::TyCtxt, adt.did) {
return Some(format!("TyCtxt<{}>", substs[0]));
}
}
}
_ => (),
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_middle/src/middle/lang_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use rustc_target::spec::PanicStrategy;
impl<'tcx> TyCtxt<'tcx> {
/// Returns the `DefId` for a given `LangItem`.
/// If not found, fatally aborts compilation.
pub fn require_lang_item(&self, lang_item: LangItem, span: Option<Span>) -> DefId {
pub fn require_lang_item(self, lang_item: LangItem, span: Option<Span>) -> DefId {
self.lang_items().require(lang_item).unwrap_or_else(|msg| {
if let Some(span) = span {
self.sess.span_fatal(span, &msg)
Expand All @@ -27,7 +27,7 @@ impl<'tcx> TyCtxt<'tcx> {
})
}

pub fn fn_trait_kind_from_lang_item(&self, id: DefId) -> Option<ty::ClosureKind> {
pub fn fn_trait_kind_from_lang_item(self, id: DefId) -> Option<ty::ClosureKind> {
let items = self.lang_items();
match Some(id) {
x if x == items.fn_trait() => Some(ty::ClosureKind::Fn),
Expand All @@ -37,7 +37,7 @@ impl<'tcx> TyCtxt<'tcx> {
}
}

pub fn is_weak_lang_item(&self, item_def_id: DefId) -> bool {
pub fn is_weak_lang_item(self, item_def_id: DefId) -> bool {
self.lang_items().is_weak_lang_item(item_def_id)
}
}
Expand Down
18 changes: 9 additions & 9 deletions compiler/rustc_middle/src/mir/interpret/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -447,14 +447,14 @@ impl<'tcx> TyCtxt<'tcx> {
///
/// Make sure to call `set_alloc_id_memory` or `set_alloc_id_same_memory` before returning such
/// an `AllocId` from a query.
pub fn reserve_alloc_id(&self) -> AllocId {
pub fn reserve_alloc_id(self) -> AllocId {
self.alloc_map.lock().reserve()
}

/// Reserves a new ID *if* this allocation has not been dedup-reserved before.
/// Should only be used for function pointers and statics, we don't want
/// to dedup IDs for "real" memory!
fn reserve_and_set_dedup(&self, alloc: GlobalAlloc<'tcx>) -> AllocId {
fn reserve_and_set_dedup(self, alloc: GlobalAlloc<'tcx>) -> AllocId {
let mut alloc_map = self.alloc_map.lock();
match alloc {
GlobalAlloc::Function(..) | GlobalAlloc::Static(..) => {}
Expand All @@ -472,13 +472,13 @@ impl<'tcx> TyCtxt<'tcx> {

/// Generates an `AllocId` for a static or return a cached one in case this function has been
/// called on the same static before.
pub fn create_static_alloc(&self, static_id: DefId) -> AllocId {
pub fn create_static_alloc(self, static_id: DefId) -> AllocId {
self.reserve_and_set_dedup(GlobalAlloc::Static(static_id))
}

/// Generates an `AllocId` for a function. Depending on the function type,
/// this might get deduplicated or assigned a new ID each time.
pub fn create_fn_alloc(&self, instance: Instance<'tcx>) -> AllocId {
pub fn create_fn_alloc(self, instance: Instance<'tcx>) -> AllocId {
// Functions cannot be identified by pointers, as asm-equal functions can get deduplicated
// by the linker (we set the "unnamed_addr" attribute for LLVM) and functions can be
// duplicated across crates.
Expand Down Expand Up @@ -507,7 +507,7 @@ impl<'tcx> TyCtxt<'tcx> {
/// Statics with identical content will still point to the same `Allocation`, i.e.,
/// their data will be deduplicated through `Allocation` interning -- but they
/// are different places in memory and as such need different IDs.
pub fn create_memory_alloc(&self, mem: &'tcx Allocation) -> AllocId {
pub fn create_memory_alloc(self, mem: &'tcx Allocation) -> AllocId {
let id = self.reserve_alloc_id();
self.set_alloc_id_memory(id, mem);
id
Expand All @@ -519,7 +519,7 @@ impl<'tcx> TyCtxt<'tcx> {
/// This function exists to allow const eval to detect the difference between evaluation-
/// local dangling pointers and allocations in constants/statics.
#[inline]
pub fn get_global_alloc(&self, id: AllocId) -> Option<GlobalAlloc<'tcx>> {
pub fn get_global_alloc(self, id: AllocId) -> Option<GlobalAlloc<'tcx>> {
self.alloc_map.lock().alloc_map.get(&id).cloned()
}

Expand All @@ -529,7 +529,7 @@ impl<'tcx> TyCtxt<'tcx> {
/// constants (as all constants must pass interning and validation that check for dangling
/// ids), this function is frequently used throughout rustc, but should not be used within
/// the miri engine.
pub fn global_alloc(&self, id: AllocId) -> GlobalAlloc<'tcx> {
pub fn global_alloc(self, id: AllocId) -> GlobalAlloc<'tcx> {
match self.get_global_alloc(id) {
Some(alloc) => alloc,
None => bug!("could not find allocation for {}", id),
Expand All @@ -538,15 +538,15 @@ impl<'tcx> TyCtxt<'tcx> {

/// Freezes an `AllocId` created with `reserve` by pointing it at an `Allocation`. Trying to
/// call this function twice, even with the same `Allocation` will ICE the compiler.
pub fn set_alloc_id_memory(&self, id: AllocId, mem: &'tcx Allocation) {
pub fn set_alloc_id_memory(self, id: AllocId, mem: &'tcx Allocation) {
if let Some(old) = self.alloc_map.lock().alloc_map.insert(id, GlobalAlloc::Memory(mem)) {
bug!("tried to set allocation ID {}, but it was already existing as {:#?}", id, old);
}
}

/// Freezes an `AllocId` created with `reserve` by pointing it at an `Allocation`. May be called
/// twice for the same `(AllocId, Allocation)` pair.
fn set_alloc_id_same_memory(&self, id: AllocId, mem: &'tcx Allocation) {
fn set_alloc_id_same_memory(self, id: AllocId, mem: &'tcx Allocation) {
self.alloc_map.lock().alloc_map.insert_same(id, GlobalAlloc::Memory(mem));
}
}
Expand Down
20 changes: 10 additions & 10 deletions compiler/rustc_middle/src/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1179,7 +1179,7 @@ impl<'tcx> TyCtxt<'tcx> {
self.mk_const(ty::Const { val: ty::ConstKind::Error(DelaySpanBugEmitted(())), ty })
}

pub fn consider_optimizing<T: Fn() -> String>(&self, msg: T) -> bool {
pub fn consider_optimizing<T: Fn() -> String>(self, msg: T) -> bool {
let cname = self.crate_name(LOCAL_CRATE).as_str();
self.sess.consider_optimizing(&cname, msg)
}
Expand Down Expand Up @@ -1403,7 +1403,7 @@ impl<'tcx> TyCtxt<'tcx> {
}

// Returns the `DefId` and the `BoundRegion` corresponding to the given region.
pub fn is_suitable_region(&self, region: Region<'tcx>) -> Option<FreeRegionInfo> {
pub fn is_suitable_region(self, region: Region<'tcx>) -> Option<FreeRegionInfo> {
let (suitable_region_binding_scope, bound_region) = match *region {
ty::ReFree(ref free_region) => {
(free_region.scope.expect_local(), free_region.bound_region)
Expand Down Expand Up @@ -1433,7 +1433,7 @@ impl<'tcx> TyCtxt<'tcx> {

/// Given a `DefId` for an `fn`, return all the `dyn` and `impl` traits in its return type.
pub fn return_type_impl_or_dyn_traits(
&self,
self,
scope_def_id: LocalDefId,
) -> Vec<&'tcx hir::Ty<'tcx>> {
let hir_id = self.hir().local_def_id_to_hir_id(scope_def_id);
Expand Down Expand Up @@ -1479,7 +1479,7 @@ impl<'tcx> TyCtxt<'tcx> {
v.0
}

pub fn return_type_impl_trait(&self, scope_def_id: LocalDefId) -> Option<(Ty<'tcx>, Span)> {
pub fn return_type_impl_trait(self, scope_def_id: LocalDefId) -> Option<(Ty<'tcx>, Span)> {
// HACK: `type_of_def_id()` will fail on these (#55796), so return `None`.
let hir_id = self.hir().local_def_id_to_hir_id(scope_def_id);
match self.hir().get(hir_id) {
Expand All @@ -1497,7 +1497,7 @@ impl<'tcx> TyCtxt<'tcx> {
let ret_ty = self.type_of(scope_def_id);
match ret_ty.kind() {
ty::FnDef(_, _) => {
let sig = ret_ty.fn_sig(*self);
let sig = ret_ty.fn_sig(self);
let output = self.erase_late_bound_regions(&sig.output());
if output.is_impl_trait() {
let fn_decl = self.hir().fn_decl_by_hir_id(hir_id).unwrap();
Expand All @@ -1511,7 +1511,7 @@ impl<'tcx> TyCtxt<'tcx> {
}

// Checks if the bound region is in Impl Item.
pub fn is_bound_region_in_impl_item(&self, suitable_region_binding_scope: LocalDefId) -> bool {
pub fn is_bound_region_in_impl_item(self, suitable_region_binding_scope: LocalDefId) -> bool {
let container_id =
self.associated_item(suitable_region_binding_scope.to_def_id()).container.id();
if self.impl_trait_ref(container_id).is_some() {
Expand All @@ -1528,21 +1528,21 @@ impl<'tcx> TyCtxt<'tcx> {

/// Determines whether identifiers in the assembly have strict naming rules.
/// Currently, only NVPTX* targets need it.
pub fn has_strict_asm_symbol_naming(&self) -> bool {
pub fn has_strict_asm_symbol_naming(self) -> bool {
self.sess.target.target.arch.contains("nvptx")
}

/// Returns `&'static core::panic::Location<'static>`.
pub fn caller_location_ty(&self) -> Ty<'tcx> {
pub fn caller_location_ty(self) -> Ty<'tcx> {
self.mk_imm_ref(
self.lifetimes.re_static,
self.type_of(self.require_lang_item(LangItem::PanicLocation, None))
.subst(*self, self.mk_substs([self.lifetimes.re_static.into()].iter())),
.subst(self, self.mk_substs([self.lifetimes.re_static.into()].iter())),
)
}

/// Returns a displayable description and article for the given `def_id` (e.g. `("a", "struct")`).
pub fn article_and_description(&self, def_id: DefId) -> (&'static str, &'static str) {
pub fn article_and_description(self, def_id: DefId) -> (&'static str, &'static str) {
match self.def_kind(def_id) {
DefKind::Generator => match self.generator_kind(def_id).unwrap() {
rustc_hir::GeneratorKind::Async(..) => ("an", "async closure"),
Expand Down
16 changes: 8 additions & 8 deletions compiler/rustc_middle/src/ty/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -546,22 +546,22 @@ impl<T> Trait<T> for X {
}

fn suggest_constraint(
&self,
self,
db: &mut DiagnosticBuilder<'_>,
msg: &str,
body_owner_def_id: DefId,
proj_ty: &ty::ProjectionTy<'tcx>,
ty: Ty<'tcx>,
) -> bool {
let assoc = self.associated_item(proj_ty.item_def_id);
let trait_ref = proj_ty.trait_ref(*self);
let trait_ref = proj_ty.trait_ref(self);
if let Some(item) = self.hir().get_if_local(body_owner_def_id) {
if let Some(hir_generics) = item.generics() {
// Get the `DefId` for the type parameter corresponding to `A` in `<A as T>::Foo`.
// This will also work for `impl Trait`.
let def_id = if let ty::Param(param_ty) = proj_ty.self_ty().kind() {
let generics = self.generics_of(body_owner_def_id);
generics.type_param(&param_ty, *self).def_id
generics.type_param(param_ty, self).def_id
} else {
return false;
};
Expand Down Expand Up @@ -629,7 +629,7 @@ impl<T> Trait<T> for X {
/// and the `impl`, we provide a generic `help` to constrain the assoc type or call an assoc
/// fn that returns the type.
fn expected_projection(
&self,
self,
db: &mut DiagnosticBuilder<'_>,
proj_ty: &ty::ProjectionTy<'tcx>,
values: &ExpectedFound<Ty<'tcx>>,
Expand Down Expand Up @@ -734,7 +734,7 @@ fn foo(&self) -> Self::T { String::new() }
}

fn point_at_methods_that_satisfy_associated_type(
&self,
self,
db: &mut DiagnosticBuilder<'_>,
assoc_container_id: DefId,
current_method_ident: Option<Symbol>,
Expand Down Expand Up @@ -789,7 +789,7 @@ fn foo(&self) -> Self::T { String::new() }
}

fn point_at_associated_type(
&self,
self,
db: &mut DiagnosticBuilder<'_>,
body_owner_def_id: DefId,
found: Ty<'tcx>,
Expand Down Expand Up @@ -851,7 +851,7 @@ fn foo(&self) -> Self::T { String::new() }
/// Given a slice of `hir::GenericBound`s, if any of them corresponds to the `trait_ref`
/// requirement, provide a strucuted suggestion to constrain it to a given type `ty`.
fn constrain_generic_bound_associated_type_structured_suggestion(
&self,
self,
db: &mut DiagnosticBuilder<'_>,
trait_ref: &ty::TraitRef<'tcx>,
bounds: hir::GenericBounds<'_>,
Expand All @@ -875,7 +875,7 @@ fn foo(&self) -> Self::T { String::new() }
/// Given a span corresponding to a bound, provide a structured suggestion to set an
/// associated type to a given type `ty`.
fn constrain_associated_type_structured_suggestion(
&self,
self,
db: &mut DiagnosticBuilder<'_>,
span: Span,
assoc: &ty::AssocItem,
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_middle/src/ty/fold.rs
Original file line number Diff line number Diff line change
Expand Up @@ -623,7 +623,7 @@ impl<'tcx> TyCtxt<'tcx> {
/// Replaces any late-bound regions bound in `value` with
/// free variants attached to `all_outlive_scope`.
pub fn liberate_late_bound_regions<T>(
&self,
self,
all_outlive_scope: DefId,
value: &ty::Binder<T>,
) -> T
Expand All @@ -644,7 +644,7 @@ impl<'tcx> TyCtxt<'tcx> {
/// variables and equate `value` with something else, those
/// variables will also be equated.
pub fn collect_constrained_late_bound_regions<T>(
&self,
self,
value: &Binder<T>,
) -> FxHashSet<ty::BoundRegion>
where
Expand All @@ -655,7 +655,7 @@ impl<'tcx> TyCtxt<'tcx> {

/// Returns a set of all late-bound regions that appear in `value` anywhere.
pub fn collect_referenced_late_bound_regions<T>(
&self,
self,
value: &Binder<T>,
) -> FxHashSet<ty::BoundRegion>
where
Expand All @@ -665,7 +665,7 @@ impl<'tcx> TyCtxt<'tcx> {
}

fn collect_late_bound_regions<T>(
&self,
self,
value: &Binder<T>,
just_constraint: bool,
) -> FxHashSet<ty::BoundRegion>
Expand Down
10 changes: 4 additions & 6 deletions compiler/rustc_middle/src/ty/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,9 +170,7 @@ impl<'tcx> TyCtxt<'tcx> {
});
hasher.finish()
}
}

impl<'tcx> TyCtxt<'tcx> {
pub fn has_error_field(self, ty: Ty<'tcx>) -> bool {
if let ty::Adt(def, substs) = *ty.kind() {
for field in def.all_fields() {
Expand Down Expand Up @@ -526,22 +524,22 @@ impl<'tcx> TyCtxt<'tcx> {
}

/// Returns `true` if the node pointed to by `def_id` is a `static` item.
pub fn is_static(&self, def_id: DefId) -> bool {
pub fn is_static(self, def_id: DefId) -> bool {
self.static_mutability(def_id).is_some()
}

/// Returns `true` if this is a `static` item with the `#[thread_local]` attribute.
pub fn is_thread_local_static(&self, def_id: DefId) -> bool {
pub fn is_thread_local_static(self, def_id: DefId) -> bool {
self.codegen_fn_attrs(def_id).flags.contains(CodegenFnAttrFlags::THREAD_LOCAL)
}

/// Returns `true` if the node pointed to by `def_id` is a mutable `static` item.
pub fn is_mutable_static(&self, def_id: DefId) -> bool {
pub fn is_mutable_static(self, def_id: DefId) -> bool {
self.static_mutability(def_id) == Some(hir::Mutability::Mut)
}

/// Get the type of the pointer to the static that we use in MIR.
pub fn static_ptr_ty(&self, def_id: DefId) -> Ty<'tcx> {
pub fn static_ptr_ty(self, def_id: DefId) -> Ty<'tcx> {
// Make sure that any constants in the static's type are evaluated.
let static_ty = self.normalize_erasing_regions(ty::ParamEnv::empty(), self.type_of(def_id));

Expand Down
Loading