diff options
Diffstat (limited to 'compiler/rustc_lint')
| -rw-r--r-- | compiler/rustc_lint/src/builtin.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_lint/src/context.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_lint/src/early.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_lint/src/late.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_lint/src/levels.rs | 14 | ||||
| -rw-r--r-- | compiler/rustc_lint/src/lib.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_lint/src/reference_casting.rs | 85 | ||||
| -rw-r--r-- | compiler/rustc_lint/src/unused.rs | 18 |
8 files changed, 105 insertions, 34 deletions
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 2c9d212a6a6..4b6917fdfdd 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -2215,7 +2215,7 @@ declare_lint! { /// /// ### Example /// - /// ```rust,compile_fail + /// ```rust /// #![feature(rustc_attrs)] /// ``` /// @@ -2226,7 +2226,7 @@ declare_lint! { /// These features are an implementation detail of the compiler and standard /// library and are not supposed to be used in user code. pub INTERNAL_FEATURES, - Deny, + Warn, "internal features are not supposed to be used" } @@ -2237,7 +2237,7 @@ declare_lint_pass!( impl EarlyLintPass for IncompleteInternalFeatures { fn check_crate(&mut self, cx: &EarlyContext<'_>, _: &ast::Crate) { - let features = cx.sess().features_untracked(); + let features = cx.builder.features(); features .declared_lang_features .iter() diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index f7e56b30553..f73797415bc 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -27,6 +27,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync; use rustc_errors::{add_elided_lifetime_in_path_suggestion, DiagnosticBuilder, DiagnosticMessage}; use rustc_errors::{Applicability, DecorateLint, MultiSpan, SuggestionStyle}; +use rustc_feature::Features; use rustc_hir as hir; use rustc_hir::def::Res; use rustc_hir::def_id::{CrateNum, DefId}; @@ -1071,6 +1072,7 @@ pub trait LintContext: Sized { impl<'a> EarlyContext<'a> { pub(crate) fn new( sess: &'a Session, + features: &'a Features, warn_about_weird_lints: bool, lint_store: &'a LintStore, registered_tools: &'a RegisteredTools, @@ -1079,6 +1081,7 @@ impl<'a> EarlyContext<'a> { EarlyContext { builder: LintLevelsBuilder::new( sess, + features, warn_about_weird_lints, lint_store, registered_tools, diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs index 9f1f5a26ee5..211ea8f4347 100644 --- a/compiler/rustc_lint/src/early.rs +++ b/compiler/rustc_lint/src/early.rs @@ -20,6 +20,7 @@ use rustc_ast::ptr::P; use rustc_ast::visit::{self as ast_visit, Visitor}; use rustc_ast::{self as ast, walk_list, HasAttrs}; use rustc_data_structures::stack::ensure_sufficient_stack; +use rustc_feature::Features; use rustc_middle::ty::RegisteredTools; use rustc_session::lint::{BufferedEarlyLint, LintBuffer, LintPass}; use rustc_session::Session; @@ -381,6 +382,7 @@ impl<'a> EarlyCheckNode<'a> for (ast::NodeId, &'a [ast::Attribute], &'a [P<ast:: pub fn check_ast_node<'a>( sess: &Session, + features: &Features, pre_expansion: bool, lint_store: &LintStore, registered_tools: &RegisteredTools, @@ -390,6 +392,7 @@ pub fn check_ast_node<'a>( ) { let context = EarlyContext::new( sess, + features, !pre_expansion, lint_store, registered_tools, diff --git a/compiler/rustc_lint/src/late.rs b/compiler/rustc_lint/src/late.rs index 3331dbad4a9..73af51d9e90 100644 --- a/compiler/rustc_lint/src/late.rs +++ b/compiler/rustc_lint/src/late.rs @@ -19,7 +19,7 @@ use rustc_ast as ast; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_data_structures::sync::join; use rustc_hir as hir; -use rustc_hir::def_id::LocalDefId; +use rustc_hir::def_id::{LocalDefId, LocalModDefId}; use rustc_hir::intravisit as hir_visit; use rustc_hir::intravisit::Visitor; use rustc_middle::hir::nested_filter; @@ -338,7 +338,7 @@ crate::late_lint_methods!(impl_late_lint_pass, []); pub fn late_lint_mod<'tcx, T: LateLintPass<'tcx> + 'tcx>( tcx: TyCtxt<'tcx>, - module_def_id: LocalDefId, + module_def_id: LocalModDefId, builtin_lints: T, ) { let context = LateContext { @@ -369,7 +369,7 @@ pub fn late_lint_mod<'tcx, T: LateLintPass<'tcx> + 'tcx>( fn late_lint_mod_inner<'tcx, T: LateLintPass<'tcx>>( tcx: TyCtxt<'tcx>, - module_def_id: LocalDefId, + module_def_id: LocalModDefId, context: LateContext<'tcx>, pass: T, ) { diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index 18b178d8882..1f4e5fa4d3b 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -12,6 +12,7 @@ use rustc_ast as ast; use rustc_ast_pretty::pprust; use rustc_data_structures::fx::FxHashMap; use rustc_errors::{DecorateLint, DiagnosticBuilder, DiagnosticMessage, MultiSpan}; +use rustc_feature::Features; use rustc_hir as hir; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::HirId; @@ -119,6 +120,7 @@ fn lint_expectations(tcx: TyCtxt<'_>, (): ()) -> Vec<(LintExpectationId, LintExp let mut builder = LintLevelsBuilder { sess: tcx.sess, + features: tcx.features(), provider: QueryMapExpectationsWrapper { tcx, cur: hir::CRATE_HIR_ID, @@ -148,6 +150,7 @@ fn shallow_lint_levels_on(tcx: TyCtxt<'_>, owner: hir::OwnerId) -> ShallowLintLe let mut levels = LintLevelsBuilder { sess: tcx.sess, + features: tcx.features(), provider: LintLevelQueryMap { tcx, cur: owner.into(), @@ -435,6 +438,7 @@ impl<'tcx> Visitor<'tcx> for LintLevelsBuilder<'_, QueryMapExpectationsWrapper<' pub struct LintLevelsBuilder<'s, P> { sess: &'s Session, + features: &'s Features, provider: P, warn_about_weird_lints: bool, store: &'s LintStore, @@ -448,12 +452,14 @@ pub(crate) struct BuilderPush { impl<'s> LintLevelsBuilder<'s, TopDown> { pub(crate) fn new( sess: &'s Session, + features: &'s Features, warn_about_weird_lints: bool, store: &'s LintStore, registered_tools: &'s RegisteredTools, ) -> Self { let mut builder = LintLevelsBuilder { sess, + features, provider: TopDown { sets: LintLevelSets::new(), cur: COMMAND_LINE }, warn_about_weird_lints, store, @@ -526,6 +532,10 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { self.sess } + pub(crate) fn features(&self) -> &Features { + self.features + } + pub(crate) fn lint_store(&self) -> &LintStore { self.store } @@ -716,7 +726,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { ast::MetaItemKind::NameValue(ref name_value) => { if item.path == sym::reason { if let ast::LitKind::Str(rationale, _) = name_value.kind { - if !self.sess.features_untracked().lint_reasons { + if !self.features.lint_reasons { feature_err( &self.sess.parse_sess, sym::lint_reasons, @@ -992,7 +1002,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { #[track_caller] fn check_gated_lint(&self, lint_id: LintId, span: Span) -> bool { if let Some(feature) = lint_id.lint.feature_gate { - if !self.sess.features_untracked().enabled(feature) { + if !self.features.enabled(feature) { let lint = builtin::UNKNOWN_LINTS; let (level, src) = self.lint_level(builtin::UNKNOWN_LINTS); struct_lint_level( diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 42378951af3..585b10e79e4 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -90,7 +90,7 @@ use rustc_ast as ast; use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; use rustc_fluent_macro::fluent_messages; use rustc_hir as hir; -use rustc_hir::def_id::LocalDefId; +use rustc_hir::def_id::{LocalDefId, LocalModDefId}; use rustc_middle::query::Providers; use rustc_middle::ty::TyCtxt; use rustc_session::lint::builtin::{ @@ -145,7 +145,7 @@ pub fn provide(providers: &mut Providers) { *providers = Providers { lint_mod, ..*providers }; } -fn lint_mod(tcx: TyCtxt<'_>, module_def_id: LocalDefId) { +fn lint_mod(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) { late_lint_mod(tcx, module_def_id, BuiltinCombinedModuleLateLintPass::new()); } diff --git a/compiler/rustc_lint/src/reference_casting.rs b/compiler/rustc_lint/src/reference_casting.rs index ed3d4721049..2577cabb3f0 100644 --- a/compiler/rustc_lint/src/reference_casting.rs +++ b/compiler/rustc_lint/src/reference_casting.rs @@ -98,32 +98,69 @@ impl<'tcx> LateLintPass<'tcx> for InvalidReferenceCasting { fn is_cast_from_const_to_mut<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'tcx>) -> bool { let e = e.peel_blocks(); - // <expr> as *mut ... - let e = if let ExprKind::Cast(e, t) = e.kind - && let ty::RawPtr(TypeAndMut { mutbl: Mutability::Mut, .. }) = cx.typeck_results().node_type(t.hir_id).kind() { - e - // <expr>.cast_mut() - } else if let ExprKind::MethodCall(_, expr, [], _) = e.kind - && let Some(def_id) = cx.typeck_results().type_dependent_def_id(e.hir_id) - && cx.tcx.is_diagnostic_item(sym::ptr_cast_mut, def_id) { - expr - } else { - return false; - }; + fn from_casts<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'tcx>) -> Option<&'tcx Expr<'tcx>> { + // <expr> as *mut ... + let mut e = if let ExprKind::Cast(e, t) = e.kind + && let ty::RawPtr(TypeAndMut { mutbl: Mutability::Mut, .. }) = cx.typeck_results().node_type(t.hir_id).kind() { + e + // <expr>.cast_mut() + } else if let ExprKind::MethodCall(_, expr, [], _) = e.kind + && let Some(def_id) = cx.typeck_results().type_dependent_def_id(e.hir_id) + && cx.tcx.is_diagnostic_item(sym::ptr_cast_mut, def_id) { + expr + } else { + return None; + }; - let e = e.peel_blocks(); + let mut had_at_least_one_cast = false; + loop { + e = e.peel_blocks(); + // <expr> as *mut/const ... or <expr> as <uint> + e = if let ExprKind::Cast(expr, t) = e.kind + && matches!(cx.typeck_results().node_type(t.hir_id).kind(), ty::RawPtr(_) | ty::Uint(_)) { + had_at_least_one_cast = true; + expr + // <expr>.cast(), <expr>.cast_mut() or <expr>.cast_const() + } else if let ExprKind::MethodCall(_, expr, [], _) = e.kind + && let Some(def_id) = cx.typeck_results().type_dependent_def_id(e.hir_id) + && matches!( + cx.tcx.get_diagnostic_name(def_id), + Some(sym::ptr_cast | sym::const_ptr_cast | sym::ptr_cast_mut | sym::ptr_cast_const) + ) + { + had_at_least_one_cast = true; + expr + // ptr::from_ref(<expr>) + } else if let ExprKind::Call(path, [arg]) = e.kind + && let ExprKind::Path(ref qpath) = path.kind + && let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id() + && cx.tcx.is_diagnostic_item(sym::ptr_from_ref, def_id) { + return Some(arg); + } else if had_at_least_one_cast { + return Some(e); + } else { + return None; + }; + } + } + + fn from_transmute<'tcx>( + cx: &LateContext<'tcx>, + e: &'tcx Expr<'tcx>, + ) -> Option<&'tcx Expr<'tcx>> { + // mem::transmute::<_, *mut _>(<expr>) + if let ExprKind::Call(path, [arg]) = e.kind + && let ExprKind::Path(ref qpath) = path.kind + && let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id() + && cx.tcx.is_diagnostic_item(sym::transmute, def_id) + && let ty::RawPtr(TypeAndMut { mutbl: Mutability::Mut, .. }) = cx.typeck_results().node_type(e.hir_id).kind() { + Some(arg) + } else { + None + } + } - // <expr> as *const ... - let e = if let ExprKind::Cast(e, t) = e.kind - && let ty::RawPtr(TypeAndMut { mutbl: Mutability::Not, .. }) = cx.typeck_results().node_type(t.hir_id).kind() { - e - // ptr::from_ref(<expr>) - } else if let ExprKind::Call(path, [arg]) = e.kind - && let ExprKind::Path(ref qpath) = path.kind - && let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id() - && cx.tcx.is_diagnostic_item(sym::ptr_from_ref, def_id) { - arg - } else { + let Some(e) = from_casts(cx, e).or_else(|| from_transmute(cx, e)) else { return false; }; diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index 3db6b302790..6041f80753b 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -666,6 +666,24 @@ trait UnusedDelimLint { if !followed_by_block { return false; } + + // Check if we need parens for `match &( Struct { feild: }) {}`. + { + let mut innermost = inner; + loop { + innermost = match &innermost.kind { + ExprKind::AddrOf(_, _, expr) => expr, + _ => { + if parser::contains_exterior_struct_lit(&innermost) { + return true; + } else { + break; + } + } + } + } + } + let mut innermost = inner; loop { innermost = match &innermost.kind { |
