Skip to content

Commit

Permalink
Rollup merge of #114959 - mojave2:issue-113702, r=petrochenkov
Browse files Browse the repository at this point in the history
fix #113702 emit a proper diagnostic message for unstable lints passed from CLI

Current output:
```bash
$ build/host/stage1/bin/rustc hello.rs -Wunnameable_types
warning: unknown lint: `unnameable_types`
  |
  = note: the `unnameable_types` lint is unstable
  = note: see issue #48054 <#48054> for more information
  = help: add `-Zcrate-attr="feature(type_privacy_lints)"` to the command-line options to enable
  = note: `#[warn(unknown_lints)]` on by default

warning: 1 warning emitted
```

Previously, the feature gate diagnostic message is like below, which is the same as the message for unstable lints from the root module.

```shell
= help: add `#![feature(type_privacy_lints)]` to the crate attributes to enable
```

Fixes #113702
  • Loading branch information
compiler-errors committed Aug 22, 2023
2 parents d8c69df + d274417 commit 6c7678d
Show file tree
Hide file tree
Showing 7 changed files with 46 additions and 21 deletions.
1 change: 1 addition & 0 deletions compiler/rustc_hir_analysis/src/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,7 @@ fn default_body_is_unstable(
&tcx.sess.parse_sess,
feature,
rustc_feature::GateIssue::Library(issue),
false,
);

err.emit();
Expand Down
28 changes: 18 additions & 10 deletions compiler/rustc_lint/src/levels.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +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_feature::{Features, GateIssue};
use rustc_hir as hir;
use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::HirId;
Expand All @@ -24,12 +24,14 @@ use rustc_middle::lint::{
};
use rustc_middle::query::Providers;
use rustc_middle::ty::{RegisteredTools, TyCtxt};
use rustc_session::lint::builtin::{RENAMED_AND_REMOVED_LINTS, UNKNOWN_LINTS, UNUSED_ATTRIBUTES};
use rustc_session::lint::{
builtin::{self, FORBIDDEN_LINT_GROUPS, SINGLE_USE_LIFETIMES, UNFULFILLED_LINT_EXPECTATIONS},
builtin::{
self, FORBIDDEN_LINT_GROUPS, RENAMED_AND_REMOVED_LINTS, SINGLE_USE_LIFETIMES,
UNFULFILLED_LINT_EXPECTATIONS, UNKNOWN_LINTS, UNUSED_ATTRIBUTES,
},
Level, Lint, LintExpectationId, LintId,
};
use rustc_session::parse::{add_feature_diagnostics, feature_err};
use rustc_session::parse::feature_err;
use rustc_session::Session;
use rustc_span::symbol::{sym, Symbol};
use rustc_span::{Span, DUMMY_SP};
Expand Down Expand Up @@ -566,7 +568,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
continue;
}

if self.check_gated_lint(id, DUMMY_SP) {
if self.check_gated_lint(id, DUMMY_SP, true) {
let src = LintLevelSource::CommandLine(lint_flag_val, orig_level);
self.insert(id, (level, src));
}
Expand Down Expand Up @@ -837,7 +839,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
reason,
};
for &id in *ids {
if self.check_gated_lint(id, attr.span) {
if self.check_gated_lint(id, attr.span, false) {
self.insert_spec(id, (level, src));
}
}
Expand All @@ -854,7 +856,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
reason,
};
for &id in ids {
if self.check_gated_lint(id, attr.span) {
if self.check_gated_lint(id, attr.span, false) {
self.insert_spec(id, (level, src));
}
}
Expand Down Expand Up @@ -955,7 +957,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
reason,
};
for &id in ids {
if self.check_gated_lint(id, attr.span) {
if self.check_gated_lint(id, attr.span, false) {
self.insert_spec(id, (level, src));
}
}
Expand Down Expand Up @@ -1000,7 +1002,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
// FIXME only emit this once for each attribute, instead of repeating it 4 times for
// pre-expansion lints, post-expansion lints, `shallow_lint_levels_on` and `lint_expectations`.
#[track_caller]
fn check_gated_lint(&self, lint_id: LintId, span: Span) -> bool {
fn check_gated_lint(&self, lint_id: LintId, span: Span, lint_from_cli: bool) -> bool {
if let Some(feature) = lint_id.lint.feature_gate {
if !self.features.enabled(feature) {
let lint = builtin::UNKNOWN_LINTS;
Expand All @@ -1015,7 +1017,13 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
|lint| {
lint.set_arg("name", lint_id.lint.name_lower());
lint.note(fluent::lint_note);
add_feature_diagnostics(lint, &self.sess.parse_sess, feature);
rustc_session::parse::add_feature_diagnostics_for_issue(
lint,
&self.sess.parse_sess,
feature,
GateIssue::Language,
lint_from_cli,
);
lint
},
);
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_session/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ session_cannot_mix_and_match_sanitizers = `-Zsanitizer={$first}` is incompatible
session_cgu_not_recorded =
CGU-reuse for `{$cgu_user_name}` is (mangled: `{$cgu_name}`) was not recorded
session_cli_feature_diagnostic_help =
add `-Zcrate-attr="feature({$feature})"` to the command-line options to enable
session_crate_name_does_not_match = `--crate-name` and `#[crate_name]` are required to match, but `{$s}` != `{$name}`
session_crate_name_empty = crate name must not be empty
Expand Down
6 changes: 6 additions & 0 deletions compiler/rustc_session/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@ pub struct FeatureDiagnosticHelp {
pub feature: Symbol,
}

#[derive(Subdiagnostic)]
#[help(session_cli_feature_diagnostic_help)]
pub struct CliFeatureDiagnosticHelp {
pub feature: Symbol,
}

#[derive(Diagnostic)]
#[diag(session_not_circumvent_feature)]
pub struct NotCircumventFeature;
Expand Down
17 changes: 12 additions & 5 deletions compiler/rustc_session/src/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
//! It also serves as an input to the parser itself.

use crate::config::CheckCfg;
use crate::errors::{FeatureDiagnosticForIssue, FeatureDiagnosticHelp, FeatureGateError};
use crate::errors::{
CliFeatureDiagnosticHelp, FeatureDiagnosticForIssue, FeatureDiagnosticHelp, FeatureGateError,
};
use crate::lint::{
builtin::UNSTABLE_SYNTAX_PRE_EXPANSION, BufferedEarlyLint, BuiltinLintDiagnostics, Lint, LintId,
};
Expand Down Expand Up @@ -110,7 +112,7 @@ pub fn feature_err_issue(
}

let mut err = sess.create_err(FeatureGateError { span, explain: explain.into() });
add_feature_diagnostics_for_issue(&mut err, sess, feature, issue);
add_feature_diagnostics_for_issue(&mut err, sess, feature, issue, false);
err
}

Expand Down Expand Up @@ -139,7 +141,7 @@ pub fn feature_warn_issue(
explain: &'static str,
) {
let mut err = sess.span_diagnostic.struct_span_warn(span, explain);
add_feature_diagnostics_for_issue(&mut err, sess, feature, issue);
add_feature_diagnostics_for_issue(&mut err, sess, feature, issue, false);

// Decorate this as a future-incompatibility lint as in rustc_middle::lint::struct_lint_level
let lint = UNSTABLE_SYNTAX_PRE_EXPANSION;
Expand All @@ -158,7 +160,7 @@ pub fn feature_warn_issue(

/// Adds the diagnostics for a feature to an existing error.
pub fn add_feature_diagnostics(err: &mut Diagnostic, sess: &ParseSess, feature: Symbol) {
add_feature_diagnostics_for_issue(err, sess, feature, GateIssue::Language);
add_feature_diagnostics_for_issue(err, sess, feature, GateIssue::Language, false);
}

/// Adds the diagnostics for a feature to an existing error.
Expand All @@ -171,14 +173,19 @@ pub fn add_feature_diagnostics_for_issue(
sess: &ParseSess,
feature: Symbol,
issue: GateIssue,
feature_from_cli: bool,
) {
if let Some(n) = find_feature_issue(feature, issue) {
err.subdiagnostic(FeatureDiagnosticForIssue { n });
}

// #23973: do not suggest `#![feature(...)]` if we are in beta/stable
if sess.unstable_features.is_nightly_build() {
err.subdiagnostic(FeatureDiagnosticHelp { feature });
if feature_from_cli {
err.subdiagnostic(CliFeatureDiagnosticHelp { feature });
} else {
err.subdiagnostic(FeatureDiagnosticHelp { feature });
}
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
error: unknown lint: `test_unstable_lint`
|
= note: the `test_unstable_lint` lint is unstable
= help: add `#![feature(test_unstable_lint)]` to the crate attributes to enable
= help: add `-Zcrate-attr="feature(test_unstable_lint)"` to the command-line options to enable
= note: requested on the command line with `-D unknown-lints`

error: unknown lint: `test_unstable_lint`
|
= note: the `test_unstable_lint` lint is unstable
= help: add `#![feature(test_unstable_lint)]` to the crate attributes to enable
= help: add `-Zcrate-attr="feature(test_unstable_lint)"` to the command-line options to enable

error: unknown lint: `test_unstable_lint`
|
= note: the `test_unstable_lint` lint is unstable
= help: add `#![feature(test_unstable_lint)]` to the crate attributes to enable
= help: add `-Zcrate-attr="feature(test_unstable_lint)"` to the command-line options to enable

error: aborting due to 3 previous errors

Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
warning: unknown lint: `test_unstable_lint`
|
= note: the `test_unstable_lint` lint is unstable
= help: add `#![feature(test_unstable_lint)]` to the crate attributes to enable
= help: add `-Zcrate-attr="feature(test_unstable_lint)"` to the command-line options to enable
= note: requested on the command line with `-W unknown-lints`

warning: unknown lint: `test_unstable_lint`
|
= note: the `test_unstable_lint` lint is unstable
= help: add `#![feature(test_unstable_lint)]` to the crate attributes to enable
= help: add `-Zcrate-attr="feature(test_unstable_lint)"` to the command-line options to enable

warning: unknown lint: `test_unstable_lint`
|
= note: the `test_unstable_lint` lint is unstable
= help: add `#![feature(test_unstable_lint)]` to the crate attributes to enable
= help: add `-Zcrate-attr="feature(test_unstable_lint)"` to the command-line options to enable

warning: 3 warnings emitted

0 comments on commit 6c7678d

Please sign in to comment.