Skip to content

Commit 878aef7

Browse files
committed
Auto merge of rust-lang#100810 - matthiaskrgr:rollup-xep778s, r=matthiaskrgr
Rollup of 9 pull requests Successful merges: - rust-lang#97963 (net listen backlog set to negative on Linux.) - rust-lang#99935 (Reenable disabled early syntax gates as future-incompatibility lints) - rust-lang#100129 (add miri-test-libstd support to libstd) - rust-lang#100500 (Ban references to `Self` in trait object substs for projection predicates too.) - rust-lang#100636 (Revert "Revert "Allow dynamic linking for iOS/tvOS targets."") - rust-lang#100718 ([rustdoc] Fix item info display) - rust-lang#100769 (Suggest adding a reference to a trait assoc item) - rust-lang#100777 (elaborate how revisions work with FileCheck stuff in src/test/codegen) - rust-lang#100796 (Refactor: remove unnecessary string searchings) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 48853a3 + d793cd2 commit 878aef7

File tree

51 files changed

+754
-150
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+754
-150
lines changed

Diff for: compiler/rustc_ast_passes/src/feature_gate.rs

+35-23
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ use rustc_ast as ast;
22
use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor};
33
use rustc_ast::{AssocConstraint, AssocConstraintKind, NodeId};
44
use rustc_ast::{PatKind, RangeEnd, VariantData};
5-
use rustc_errors::{struct_span_err, Applicability};
5+
use rustc_errors::{struct_span_err, Applicability, StashKey};
6+
use rustc_feature::Features;
67
use rustc_feature::{AttributeGate, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP};
7-
use rustc_feature::{Features, GateIssue};
8-
use rustc_session::parse::{feature_err, feature_err_issue};
8+
use rustc_session::parse::{feature_err, feature_warn};
99
use rustc_session::Session;
1010
use rustc_span::source_map::Spanned;
1111
use rustc_span::symbol::sym;
@@ -20,9 +20,7 @@ macro_rules! gate_feature_fn {
2020
let has_feature: bool = has_feature(visitor.features);
2121
debug!("gate_feature(feature = {:?}, span = {:?}); has? {}", name, span, has_feature);
2222
if !has_feature && !span.allows_unstable($name) {
23-
feature_err_issue(&visitor.sess.parse_sess, name, span, GateIssue::Language, explain)
24-
.help(help)
25-
.emit();
23+
feature_err(&visitor.sess.parse_sess, name, span, explain).help(help).emit();
2624
}
2725
}};
2826
($visitor: expr, $has_feature: expr, $span: expr, $name: expr, $explain: expr) => {{
@@ -31,8 +29,19 @@ macro_rules! gate_feature_fn {
3129
let has_feature: bool = has_feature(visitor.features);
3230
debug!("gate_feature(feature = {:?}, span = {:?}); has? {}", name, span, has_feature);
3331
if !has_feature && !span.allows_unstable($name) {
34-
feature_err_issue(&visitor.sess.parse_sess, name, span, GateIssue::Language, explain)
35-
.emit();
32+
feature_err(&visitor.sess.parse_sess, name, span, explain).emit();
33+
}
34+
}};
35+
(future_incompatible; $visitor: expr, $has_feature: expr, $span: expr, $name: expr, $explain: expr) => {{
36+
let (visitor, has_feature, span, name, explain) =
37+
(&*$visitor, $has_feature, $span, $name, $explain);
38+
let has_feature: bool = has_feature(visitor.features);
39+
debug!(
40+
"gate_feature(feature = {:?}, span = {:?}); has? {} (future_incompatible)",
41+
name, span, has_feature
42+
);
43+
if !has_feature && !span.allows_unstable($name) {
44+
feature_warn(&visitor.sess.parse_sess, name, span, explain);
3645
}
3746
}};
3847
}
@@ -44,6 +53,9 @@ macro_rules! gate_feature_post {
4453
($visitor: expr, $feature: ident, $span: expr, $explain: expr) => {
4554
gate_feature_fn!($visitor, |x: &Features| x.$feature, $span, sym::$feature, $explain)
4655
};
56+
(future_incompatible; $visitor: expr, $feature: ident, $span: expr, $explain: expr) => {
57+
gate_feature_fn!(future_incompatible; $visitor, |x: &Features| x.$feature, $span, sym::$feature, $explain)
58+
};
4759
}
4860

4961
pub fn check_attribute(attr: &ast::Attribute, sess: &Session, features: &Features) {
@@ -588,11 +600,10 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
588600
{
589601
// When we encounter a statement of the form `foo: Ty = val;`, this will emit a type
590602
// ascription error, but the likely intention was to write a `let` statement. (#78907).
591-
feature_err_issue(
603+
feature_err(
592604
&self.sess.parse_sess,
593605
sym::type_ascription,
594606
lhs.span,
595-
GateIssue::Language,
596607
"type ascription is experimental",
597608
).span_suggestion_verbose(
598609
lhs.span.shrink_to_lo(),
@@ -615,15 +626,22 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
615626
);
616627
}
617628
ast::ExprKind::Type(..) => {
618-
// To avoid noise about type ascription in common syntax errors, only emit if it
619-
// is the *only* error.
620629
if self.sess.parse_sess.span_diagnostic.err_count() == 0 {
630+
// To avoid noise about type ascription in common syntax errors,
631+
// only emit if it is the *only* error.
621632
gate_feature_post!(
622633
&self,
623634
type_ascription,
624635
e.span,
625636
"type ascription is experimental"
626637
);
638+
} else {
639+
// And if it isn't, cancel the early-pass warning.
640+
self.sess
641+
.parse_sess
642+
.span_diagnostic
643+
.steal_diagnostic(e.span, StashKey::EarlySyntaxWarning)
644+
.map(|err| err.cancel());
627645
}
628646
}
629647
ast::ExprKind::TryBlock(_) => {
@@ -789,14 +807,12 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) {
789807

790808
// All uses of `gate_all!` below this point were added in #65742,
791809
// and subsequently disabled (with the non-early gating readded).
810+
// We emit an early future-incompatible warning for these.
811+
// New syntax gates should go above here to get a hard error gate.
792812
macro_rules! gate_all {
793813
($gate:ident, $msg:literal) => {
794-
// FIXME(eddyb) do something more useful than always
795-
// disabling these uses of early feature-gatings.
796-
if false {
797-
for span in spans.get(&sym::$gate).unwrap_or(&vec![]) {
798-
gate_feature_post!(&visitor, $gate, *span, $msg);
799-
}
814+
for span in spans.get(&sym::$gate).unwrap_or(&vec![]) {
815+
gate_feature_post!(future_incompatible; &visitor, $gate, *span, $msg);
800816
}
801817
};
802818
}
@@ -809,11 +825,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) {
809825
gate_all!(try_blocks, "`try` blocks are unstable");
810826
gate_all!(label_break_value, "labels on blocks are unstable");
811827
gate_all!(box_syntax, "box expression syntax is experimental; you can call `Box::new` instead");
812-
// To avoid noise about type ascription in common syntax errors,
813-
// only emit if it is the *only* error. (Also check it last.)
814-
if sess.parse_sess.span_diagnostic.err_count() == 0 {
815-
gate_all!(type_ascription, "type ascription is experimental");
816-
}
828+
gate_all!(type_ascription, "type ascription is experimental");
817829

818830
visit::walk_crate(&mut visitor, krate);
819831
}

Diff for: compiler/rustc_errors/src/lib.rs

+63-12
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,7 @@ struct HandlerInner {
459459
pub enum StashKey {
460460
ItemNoType,
461461
UnderscoreForArrayLengths,
462+
EarlySyntaxWarning,
462463
}
463464

464465
fn default_track_diagnostic(_: &Diagnostic) {}
@@ -626,19 +627,13 @@ impl Handler {
626627
/// Stash a given diagnostic with the given `Span` and `StashKey` as the key for later stealing.
627628
pub fn stash_diagnostic(&self, span: Span, key: StashKey, diag: Diagnostic) {
628629
let mut inner = self.inner.borrow_mut();
629-
// FIXME(Centril, #69537): Consider reintroducing panic on overwriting a stashed diagnostic
630-
// if/when we have a more robust macro-friendly replacement for `(span, key)` as a key.
631-
// See the PR for a discussion.
632-
inner.stashed_diagnostics.insert((span, key), diag);
630+
inner.stash((span, key), diag);
633631
}
634632

635633
/// Steal a previously stashed diagnostic with the given `Span` and `StashKey` as the key.
636634
pub fn steal_diagnostic(&self, span: Span, key: StashKey) -> Option<DiagnosticBuilder<'_, ()>> {
637-
self.inner
638-
.borrow_mut()
639-
.stashed_diagnostics
640-
.remove(&(span, key))
641-
.map(|diag| DiagnosticBuilder::new_diagnostic(self, diag))
635+
let mut inner = self.inner.borrow_mut();
636+
inner.steal((span, key)).map(|diag| DiagnosticBuilder::new_diagnostic(self, diag))
642637
}
643638

644639
/// Emit all stashed diagnostics.
@@ -1106,13 +1101,31 @@ impl HandlerInner {
11061101

11071102
/// Emit all stashed diagnostics.
11081103
fn emit_stashed_diagnostics(&mut self) -> Option<ErrorGuaranteed> {
1104+
let has_errors = self.has_errors();
11091105
let diags = self.stashed_diagnostics.drain(..).map(|x| x.1).collect::<Vec<_>>();
11101106
let mut reported = None;
11111107
for mut diag in diags {
1108+
// Decrement the count tracking the stash; emitting will increment it.
11121109
if diag.is_error() {
1113-
reported = Some(ErrorGuaranteed(()));
1110+
if matches!(diag.level, Level::Error { lint: true }) {
1111+
self.lint_err_count -= 1;
1112+
} else {
1113+
self.err_count -= 1;
1114+
}
1115+
} else {
1116+
if diag.is_force_warn() {
1117+
self.warn_count -= 1;
1118+
} else {
1119+
// Unless they're forced, don't flush stashed warnings when
1120+
// there are errors, to avoid causing warning overload. The
1121+
// stash would've been stolen already if it were important.
1122+
if has_errors {
1123+
continue;
1124+
}
1125+
}
11141126
}
1115-
self.emit_diagnostic(&mut diag);
1127+
let reported_this = self.emit_diagnostic(&mut diag);
1128+
reported = reported.or(reported_this);
11161129
}
11171130
reported
11181131
}
@@ -1302,9 +1315,47 @@ impl HandlerInner {
13021315
}
13031316
}
13041317

1318+
fn stash(&mut self, key: (Span, StashKey), diagnostic: Diagnostic) {
1319+
// Track the diagnostic for counts, but don't panic-if-treat-err-as-bug
1320+
// yet; that happens when we actually emit the diagnostic.
1321+
if diagnostic.is_error() {
1322+
if matches!(diagnostic.level, Level::Error { lint: true }) {
1323+
self.lint_err_count += 1;
1324+
} else {
1325+
self.err_count += 1;
1326+
}
1327+
} else {
1328+
// Warnings are only automatically flushed if they're forced.
1329+
if diagnostic.is_force_warn() {
1330+
self.warn_count += 1;
1331+
}
1332+
}
1333+
1334+
// FIXME(Centril, #69537): Consider reintroducing panic on overwriting a stashed diagnostic
1335+
// if/when we have a more robust macro-friendly replacement for `(span, key)` as a key.
1336+
// See the PR for a discussion.
1337+
self.stashed_diagnostics.insert(key, diagnostic);
1338+
}
1339+
1340+
fn steal(&mut self, key: (Span, StashKey)) -> Option<Diagnostic> {
1341+
let diagnostic = self.stashed_diagnostics.remove(&key)?;
1342+
if diagnostic.is_error() {
1343+
if matches!(diagnostic.level, Level::Error { lint: true }) {
1344+
self.lint_err_count -= 1;
1345+
} else {
1346+
self.err_count -= 1;
1347+
}
1348+
} else {
1349+
if diagnostic.is_force_warn() {
1350+
self.warn_count -= 1;
1351+
}
1352+
}
1353+
Some(diagnostic)
1354+
}
1355+
13051356
#[inline]
13061357
fn err_count(&self) -> usize {
1307-
self.err_count + self.stashed_diagnostics.len()
1358+
self.err_count
13081359
}
13091360

13101361
fn has_errors(&self) -> bool {

Diff for: compiler/rustc_lint_defs/src/builtin.rs

+51
Original file line numberDiff line numberDiff line change
@@ -3212,6 +3212,56 @@ declare_lint! {
32123212
};
32133213
}
32143214

3215+
declare_lint! {
3216+
/// The `unstable_syntax_pre_expansion` lint detects the use of unstable
3217+
/// syntax that is discarded during attribute expansion.
3218+
///
3219+
/// ### Example
3220+
///
3221+
/// ```rust
3222+
/// #[cfg(FALSE)]
3223+
/// macro foo() {}
3224+
/// ```
3225+
///
3226+
/// {{produces}}
3227+
///
3228+
/// ### Explanation
3229+
///
3230+
/// The input to active attributes such as `#[cfg]` or procedural macro
3231+
/// attributes is required to be valid syntax. Previously, the compiler only
3232+
/// gated the use of unstable syntax features after resolving `#[cfg]` gates
3233+
/// and expanding procedural macros.
3234+
///
3235+
/// To avoid relying on unstable syntax, move the use of unstable syntax
3236+
/// into a position where the compiler does not parse the syntax, such as a
3237+
/// functionlike macro.
3238+
///
3239+
/// ```rust
3240+
/// # #![deny(unstable_syntax_pre_expansion)]
3241+
///
3242+
/// macro_rules! identity {
3243+
/// ( $($tokens:tt)* ) => { $($tokens)* }
3244+
/// }
3245+
///
3246+
/// #[cfg(FALSE)]
3247+
/// identity! {
3248+
/// macro foo() {}
3249+
/// }
3250+
/// ```
3251+
///
3252+
/// This is a [future-incompatible] lint to transition this
3253+
/// to a hard error in the future. See [issue #65860] for more details.
3254+
///
3255+
/// [issue #65860]: https://github.com/rust-lang/rust/issues/65860
3256+
/// [future-incompatible]: ../index.md#future-incompatible-lints
3257+
pub UNSTABLE_SYNTAX_PRE_EXPANSION,
3258+
Warn,
3259+
"unstable syntax can change at any point in the future, causing a hard error!",
3260+
@future_incompatible = FutureIncompatibleInfo {
3261+
reference: "issue #65860 <https://github.com/rust-lang/rust/issues/65860>",
3262+
};
3263+
}
3264+
32153265
declare_lint_pass! {
32163266
/// Does nothing as a lint pass, but registers some `Lint`s
32173267
/// that are used by other parts of the compiler.
@@ -3280,6 +3330,7 @@ declare_lint_pass! {
32803330
POINTER_STRUCTURAL_MATCH,
32813331
NONTRIVIAL_STRUCTURAL_MATCH,
32823332
SOFT_UNSTABLE,
3333+
UNSTABLE_SYNTAX_PRE_EXPANSION,
32833334
INLINE_NO_SANITIZE,
32843335
BAD_ASM_STYLE,
32853336
ASM_SUB_REGISTER,

Diff for: compiler/rustc_session/src/parse.rs

+52-3
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,17 @@
22
//! It also serves as an input to the parser itself.
33
44
use crate::config::CheckCfg;
5-
use crate::lint::{BufferedEarlyLint, BuiltinLintDiagnostics, Lint, LintId};
5+
use crate::lint::{
6+
builtin::UNSTABLE_SYNTAX_PRE_EXPANSION, BufferedEarlyLint, BuiltinLintDiagnostics, Lint, LintId,
7+
};
68
use crate::SessionDiagnostic;
79
use rustc_ast::node_id::NodeId;
810
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
911
use rustc_data_structures::sync::{Lock, Lrc};
1012
use rustc_errors::{emitter::SilentEmitter, ColorConfig, Handler};
1113
use rustc_errors::{
12-
error_code, fallback_fluent_bundle, Applicability, Diagnostic, DiagnosticBuilder,
13-
DiagnosticMessage, ErrorGuaranteed, MultiSpan,
14+
error_code, fallback_fluent_bundle, Applicability, Diagnostic, DiagnosticBuilder, DiagnosticId,
15+
DiagnosticMessage, ErrorGuaranteed, MultiSpan, StashKey,
1416
};
1517
use rustc_feature::{find_feature_issue, GateIssue, UnstableFeatures};
1618
use rustc_span::edition::Edition;
@@ -101,11 +103,58 @@ pub fn feature_err_issue<'a>(
101103
issue: GateIssue,
102104
explain: &str,
103105
) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
106+
let span = span.into();
107+
108+
// Cancel an earlier warning for this same error, if it exists.
109+
if let Some(span) = span.primary_span() {
110+
sess.span_diagnostic
111+
.steal_diagnostic(span, StashKey::EarlySyntaxWarning)
112+
.map(|err| err.cancel());
113+
}
114+
104115
let mut err = sess.span_diagnostic.struct_span_err_with_code(span, explain, error_code!(E0658));
105116
add_feature_diagnostics_for_issue(&mut err, sess, feature, issue);
106117
err
107118
}
108119

120+
/// Construct a future incompatibility diagnostic for a feature gate.
121+
///
122+
/// This diagnostic is only a warning and *does not cause compilation to fail*.
123+
pub fn feature_warn<'a>(sess: &'a ParseSess, feature: Symbol, span: Span, explain: &str) {
124+
feature_warn_issue(sess, feature, span, GateIssue::Language, explain);
125+
}
126+
127+
/// Construct a future incompatibility diagnostic for a feature gate.
128+
///
129+
/// This diagnostic is only a warning and *does not cause compilation to fail*.
130+
///
131+
/// This variant allows you to control whether it is a library or language feature.
132+
/// Almost always, you want to use this for a language feature. If so, prefer `feature_warn`.
133+
pub fn feature_warn_issue<'a>(
134+
sess: &'a ParseSess,
135+
feature: Symbol,
136+
span: Span,
137+
issue: GateIssue,
138+
explain: &str,
139+
) {
140+
let mut err = sess.span_diagnostic.struct_span_warn(span, explain);
141+
add_feature_diagnostics_for_issue(&mut err, sess, feature, issue);
142+
143+
// Decorate this as a future-incompatibility lint as in rustc_middle::lint::struct_lint_level
144+
let lint = UNSTABLE_SYNTAX_PRE_EXPANSION;
145+
let future_incompatible = lint.future_incompatible.as_ref().unwrap();
146+
err.code(DiagnosticId::Lint {
147+
name: lint.name_lower(),
148+
has_future_breakage: false,
149+
is_force_warn: false,
150+
});
151+
err.warn(lint.desc);
152+
err.note(format!("for more information, see {}", future_incompatible.reference));
153+
154+
// A later feature_err call can steal and cancel this warning.
155+
err.stash(span, StashKey::EarlySyntaxWarning);
156+
}
157+
109158
/// Adds the diagnostics for a feature to an existing error.
110159
pub fn add_feature_diagnostics<'a>(err: &mut Diagnostic, sess: &'a ParseSess, feature: Symbol) {
111160
add_feature_diagnostics_for_issue(err, sess, feature, GateIssue::Language);

Diff for: compiler/rustc_target/src/spec/apple_sdk_base.rs

-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ pub fn opts(os: &'static str, arch: Arch) -> TargetOptions {
6565
TargetOptions {
6666
abi: target_abi(arch).into(),
6767
cpu: target_cpu(arch).into(),
68-
dynamic_linking: false,
6968
link_env_remove: link_env_remove(arch),
7069
has_thread_local: false,
7170
..super::apple_base::opts(os, target_arch_name(arch), target_abi(arch))

0 commit comments

Comments
 (0)