Skip to content

Commit 2e10913

Browse files
committed
Auto merge of #152187 - cuviper:beta-next, r=cuviper
[beta] backports, plus stable versions in stdarch - Replace `stdarch` version placeholders with 1.94 - Parse ident with allowing recovery when trying to diagnose #151249 - Revert enabling `outline-atomics` on various platforms #151896 - Revert doc attribute parsing errors to future warnings #151952 - Remove the 4 failing tests from rustdoc-gui #152194 - Remove rustdoc GUI flaky test #152116 - Align `ArrayWindows` trait impls with `Windows` #151613 - Fix suppression of `unused_assignment` in binding of `unused_variable` #151556 - layout: handle rigid aliases without params #151814 - Fix missing unused_variables lint when using a match guard #151990 - Partially revert "resolve: Update `NameBindingData::vis` in place" #152498 - [BETA]: parse array lengths without stripping const blocks #152237 r? cuviper
2 parents 23a44d3 + 9cc698e commit 2e10913

112 files changed

Lines changed: 2205 additions & 2416 deletions

File tree

Some content is hidden

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

compiler/rustc_attr_parsing/src/attributes/doc.rs

Lines changed: 83 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,42 @@ fn check_attr_crate_level<S: Stage>(cx: &mut AcceptContext<'_, '_, S>, span: Spa
7070
true
7171
}
7272

73+
// FIXME: To be removed once merged and replace with `cx.expected_name_value(span, _name)`.
74+
fn expected_name_value<S: Stage>(
75+
cx: &mut AcceptContext<'_, '_, S>,
76+
span: Span,
77+
_name: Option<Symbol>,
78+
) {
79+
cx.emit_lint(
80+
rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
81+
AttributeLintKind::ExpectedNameValue,
82+
span,
83+
);
84+
}
85+
86+
// FIXME: remove this method once merged and use `cx.expected_no_args(span)` instead.
87+
fn expected_no_args<S: Stage>(cx: &mut AcceptContext<'_, '_, S>, span: Span) {
88+
cx.emit_lint(
89+
rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
90+
AttributeLintKind::ExpectedNoArgs,
91+
span,
92+
);
93+
}
94+
95+
// FIXME: remove this method once merged and use `cx.expected_no_args(span)` instead.
96+
// cx.expected_string_literal(span, _actual_literal);
97+
fn expected_string_literal<S: Stage>(
98+
cx: &mut AcceptContext<'_, '_, S>,
99+
span: Span,
100+
_actual_literal: Option<&MetaItemLit>,
101+
) {
102+
cx.emit_lint(
103+
rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
104+
AttributeLintKind::MalformedDoc,
105+
span,
106+
);
107+
}
108+
73109
fn parse_keyword_and_attribute<S: Stage>(
74110
cx: &mut AcceptContext<'_, '_, S>,
75111
path: &OwnedPathParser,
@@ -78,12 +114,12 @@ fn parse_keyword_and_attribute<S: Stage>(
78114
attr_name: Symbol,
79115
) {
80116
let Some(nv) = args.name_value() else {
81-
cx.expected_name_value(args.span().unwrap_or(path.span()), path.word_sym());
117+
expected_name_value(cx, args.span().unwrap_or(path.span()), path.word_sym());
82118
return;
83119
};
84120

85121
let Some(value) = nv.value_as_str() else {
86-
cx.expected_string_literal(nv.value_span, Some(nv.value_as_lit()));
122+
expected_string_literal(cx, nv.value_span, Some(nv.value_as_lit()));
87123
return;
88124
};
89125

@@ -127,12 +163,21 @@ impl DocParser {
127163
match path.word_sym() {
128164
Some(sym::no_crate_inject) => {
129165
if let Err(span) = args.no_args() {
130-
cx.expected_no_args(span);
166+
expected_no_args(cx, span);
131167
return;
132168
}
133169

134-
if self.attribute.no_crate_inject.is_some() {
135-
cx.duplicate_key(path.span(), sym::no_crate_inject);
170+
if let Some(used_span) = self.attribute.no_crate_inject {
171+
let unused_span = path.span();
172+
cx.emit_lint(
173+
rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
174+
AttributeLintKind::UnusedDuplicate {
175+
this: unused_span,
176+
other: used_span,
177+
warning: true,
178+
},
179+
unused_span,
180+
);
136181
return;
137182
}
138183

@@ -144,7 +189,14 @@ impl DocParser {
144189
}
145190
Some(sym::attr) => {
146191
let Some(list) = args.list() else {
147-
cx.expected_list(cx.attr_span, args);
192+
// FIXME: remove this method once merged and uncomment the line below instead.
193+
// cx.expected_list(cx.attr_span, args);
194+
let span = cx.attr_span;
195+
cx.emit_lint(
196+
rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
197+
AttributeLintKind::MalformedDoc,
198+
span,
199+
);
148200
return;
149201
};
150202

@@ -246,7 +298,7 @@ impl DocParser {
246298
inline: DocInline,
247299
) {
248300
if let Err(span) = args.no_args() {
249-
cx.expected_no_args(span);
301+
expected_no_args(cx, span);
250302
return;
251303
}
252304

@@ -328,7 +380,14 @@ impl DocParser {
328380
match sub_item.args() {
329381
a @ (ArgParser::NoArgs | ArgParser::NameValue(_)) => {
330382
let Some(name) = sub_item.path().word_sym() else {
331-
cx.expected_identifier(sub_item.path().span());
383+
// FIXME: remove this method once merged and uncomment the line
384+
// below instead.
385+
// cx.expected_identifier(sub_item.path().span());
386+
cx.emit_lint(
387+
rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
388+
AttributeLintKind::MalformedDoc,
389+
sub_item.path().span(),
390+
);
332391
continue;
333392
};
334393
if let Ok(CfgEntry::NameValue { name, value, .. }) =
@@ -391,7 +450,7 @@ impl DocParser {
391450
macro_rules! no_args {
392451
($ident: ident) => {{
393452
if let Err(span) = args.no_args() {
394-
cx.expected_no_args(span);
453+
expected_no_args(cx, span);
395454
return;
396455
}
397456

@@ -410,7 +469,7 @@ impl DocParser {
410469
macro_rules! no_args_and_not_crate_level {
411470
($ident: ident) => {{
412471
if let Err(span) = args.no_args() {
413-
cx.expected_no_args(span);
472+
expected_no_args(cx, span);
414473
return;
415474
}
416475
let span = path.span();
@@ -423,7 +482,7 @@ impl DocParser {
423482
macro_rules! no_args_and_crate_level {
424483
($ident: ident) => {{
425484
if let Err(span) = args.no_args() {
426-
cx.expected_no_args(span);
485+
expected_no_args(cx, span);
427486
return;
428487
}
429488
let span = path.span();
@@ -436,12 +495,12 @@ impl DocParser {
436495
macro_rules! string_arg_and_crate_level {
437496
($ident: ident) => {{
438497
let Some(nv) = args.name_value() else {
439-
cx.expected_name_value(args.span().unwrap_or(path.span()), path.word_sym());
498+
expected_name_value(cx, args.span().unwrap_or(path.span()), path.word_sym());
440499
return;
441500
};
442501

443502
let Some(s) = nv.value_as_str() else {
444-
cx.expected_string_literal(nv.value_span, Some(nv.value_as_lit()));
503+
expected_string_literal(cx, nv.value_span, Some(nv.value_as_lit()));
445504
return;
446505
};
447506

@@ -512,7 +571,14 @@ impl DocParser {
512571
self.parse_single_test_doc_attr_item(cx, mip);
513572
}
514573
MetaItemOrLitParser::Lit(lit) => {
515-
cx.unexpected_literal(lit.span);
574+
// FIXME: remove this method once merged and uncomment the line
575+
// below instead.
576+
// cx.unexpected_literal(lit.span);
577+
cx.emit_lint(
578+
rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
579+
AttributeLintKind::MalformedDoc,
580+
lit.span,
581+
);
516582
}
517583
}
518584
}
@@ -582,7 +648,7 @@ impl DocParser {
582648
let suggestions = cx.suggestions();
583649
let span = cx.attr_span;
584650
cx.emit_lint(
585-
rustc_session::lint::builtin::ILL_FORMED_ATTRIBUTE_INPUT,
651+
rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
586652
AttributeLintKind::IllFormedAttributeInput { suggestions, docs: None },
587653
span,
588654
);
@@ -595,14 +661,14 @@ impl DocParser {
595661
self.parse_single_doc_attr_item(cx, mip);
596662
}
597663
MetaItemOrLitParser::Lit(lit) => {
598-
cx.expected_name_value(lit.span, None);
664+
expected_name_value(cx, lit.span, None);
599665
}
600666
}
601667
}
602668
}
603669
ArgParser::NameValue(nv) => {
604670
if nv.value_as_str().is_none() {
605-
cx.expected_string_literal(nv.value_span, Some(nv.value_as_lit()));
671+
expected_string_literal(cx, nv.value_span, Some(nv.value_as_lit()));
606672
} else {
607673
unreachable!(
608674
"Should have been handled at the same time as sugar-syntaxed doc comments"

compiler/rustc_lint/messages.ftl

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,14 @@ lint_expectation = this lint expectation is unfulfilled
329329
.note = the `unfulfilled_lint_expectations` lint can't be expected and will always produce this message
330330
.rationale = {$rationale}
331331
332+
lint_expected_name_value =
333+
expected this to be of the form `... = "..."`
334+
.warn = {-lint_previously_accepted}
335+
336+
lint_expected_no_args =
337+
didn't expect any arguments here
338+
.warn = {-lint_previously_accepted}
339+
332340
lint_for_loops_over_fallibles =
333341
for loop over {$article} `{$ref_prefix}{$ty}`. This is more readably written as an `if let` statement
334342
.suggestion = consider using `if let` to clear intent
@@ -558,6 +566,10 @@ lint_macro_expr_fragment_specifier_2024_migration =
558566
559567
lint_malformed_attribute = malformed lint attribute input
560568
569+
lint_malformed_doc =
570+
malformed `doc` attribute input
571+
.warn = {-lint_previously_accepted}
572+
561573
lint_map_unit_fn = `Iterator::map` call that discard the iterator's values
562574
.note = `Iterator::map`, like many of the methods on `Iterator`, gets executed lazily, meaning that its effects won't be visible until it is iterated
563575
.function_label = this function returns `()`, which is likely not what you wanted

compiler/rustc_lint/src/early/diagnostics.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,5 +423,11 @@ pub fn decorate_attribute_lint(
423423
&AttributeLintKind::DoNotRecommendDoesNotExpectArgs => {
424424
lints::DoNotRecommendDoesNotExpectArgs.decorate_lint(diag)
425425
}
426+
427+
&AttributeLintKind::MalformedDoc => lints::MalformedDoc.decorate_lint(diag),
428+
429+
&AttributeLintKind::ExpectedNoArgs => lints::ExpectedNoArgs.decorate_lint(diag),
430+
431+
&AttributeLintKind::ExpectedNameValue => lints::ExpectedNameValue.decorate_lint(diag),
426432
}
427433
}

compiler/rustc_lint/src/lints.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3196,6 +3196,21 @@ pub(crate) struct UnusedDuplicate {
31963196
pub warning: bool,
31973197
}
31983198

3199+
#[derive(LintDiagnostic)]
3200+
#[diag(lint_malformed_doc)]
3201+
#[warning]
3202+
pub(crate) struct MalformedDoc;
3203+
3204+
#[derive(LintDiagnostic)]
3205+
#[diag(lint_expected_no_args)]
3206+
#[warning]
3207+
pub(crate) struct ExpectedNoArgs;
3208+
3209+
#[derive(LintDiagnostic)]
3210+
#[diag(lint_expected_name_value)]
3211+
#[warning]
3212+
pub(crate) struct ExpectedNameValue;
3213+
31993214
#[derive(LintDiagnostic)]
32003215
#[diag(lint_unsafe_attr_outside_unsafe)]
32013216
pub(crate) struct UnsafeAttrOutsideUnsafeLint {

compiler/rustc_lint_defs/src/builtin.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3456,7 +3456,7 @@ declare_lint! {
34563456
/// but this lint was introduced to avoid breaking any existing
34573457
/// crates which included them.
34583458
pub INVALID_DOC_ATTRIBUTES,
3459-
Deny,
3459+
Warn,
34603460
"detects invalid `#[doc(...)]` attributes",
34613461
}
34623462

compiler/rustc_lint_defs/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -822,6 +822,9 @@ pub enum AttributeLintKind {
822822
DocTestLiteral,
823823
AttrCrateLevelOnly,
824824
DoNotRecommendDoesNotExpectArgs,
825+
MalformedDoc,
826+
ExpectedNoArgs,
827+
ExpectedNameValue,
825828
}
826829

827830
pub type RegisteredTools = FxIndexSet<Ident>;

compiler/rustc_mir_transform/src/liveness.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -986,7 +986,7 @@ impl<'a, 'tcx> AssignmentResult<'a, 'tcx> {
986986
// warn twice, for the unused local and for the unused assignment. Therefore, we remove
987987
// from the list of assignments the ones that happen at the definition site.
988988
statements.retain(|source_info, _| {
989-
source_info.span.find_ancestor_inside(binding.pat_span).is_none()
989+
!binding.introductions.iter().any(|intro| intro.span == source_info.span)
990990
});
991991

992992
// Extra assignments that we recognize thanks to the initialization span. We need to
@@ -1238,9 +1238,12 @@ struct TransferFunction<'a, 'tcx> {
12381238
impl<'tcx> Visitor<'tcx> for TransferFunction<'_, 'tcx> {
12391239
fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) {
12401240
match statement.kind {
1241-
// `ForLet(None)` fake read erroneously marks the just-assigned local as live.
1242-
// This defeats the purpose of the analysis for `let` bindings.
1243-
StatementKind::FakeRead(box (FakeReadCause::ForLet(None), _)) => return,
1241+
// `ForLet(None)` and `ForGuardBinding` fake reads erroneously mark the just-assigned
1242+
// locals as live. This defeats the purpose of the analysis for such bindings.
1243+
StatementKind::FakeRead(box (
1244+
FakeReadCause::ForLet(None) | FakeReadCause::ForGuardBinding,
1245+
_,
1246+
)) => return,
12441247
// Handle self-assignment by restricting the read/write they do.
12451248
StatementKind::Assign(box (ref dest, ref rvalue))
12461249
if self.self_assignment.contains(&location) =>

compiler/rustc_parse/src/parser/diagnostics.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2264,7 +2264,7 @@ impl<'a> Parser<'a> {
22642264
&& self.look_ahead(1, |t| *t == token::Comma || *t == token::CloseParen)
22652265
{
22662266
// `fn foo(String s) {}`
2267-
let ident = self.parse_ident().unwrap();
2267+
let ident = self.parse_ident_common(true).unwrap();
22682268
let span = pat.span.with_hi(ident.span.hi());
22692269

22702270
err.span_suggestion(

compiler/rustc_parse/src/parser/expr.rs

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1622,16 +1622,8 @@ impl<'a> Parser<'a> {
16221622
let first_expr = self.parse_expr()?;
16231623
if self.eat(exp!(Semi)) {
16241624
// Repeating array syntax: `[ 0; 512 ]`
1625-
let count = if self.eat_keyword(exp!(Const)) {
1626-
// While we could just disambiguate `Direct` from `AnonConst` by
1627-
// treating all const block exprs as `AnonConst`, that would
1628-
// complicate the DefCollector and likely all other visitors.
1629-
// So we strip the const blockiness and just store it as a block
1630-
// in the AST with the extra disambiguator on the AnonConst
1631-
self.parse_mgca_const_block(false)?
1632-
} else {
1633-
self.parse_expr_anon_const(|this, expr| this.mgca_direct_lit_hack(expr))?
1634-
};
1625+
let count =
1626+
self.parse_expr_anon_const(|this, expr| this.mgca_direct_lit_hack(expr))?;
16351627
self.expect(close)?;
16361628
ExprKind::Repeat(first_expr, count)
16371629
} else if self.eat(exp!(Comma)) {

compiler/rustc_parse/src/parser/item.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -408,12 +408,11 @@ impl<'a> Parser<'a> {
408408
let insert_span = ident_span.shrink_to_lo();
409409

410410
let ident = if self.token.is_ident()
411-
&& self.token.is_non_reserved_ident()
412411
&& (!is_const || self.look_ahead(1, |t| *t == token::OpenParen))
413412
&& self.look_ahead(1, |t| {
414413
matches!(t.kind, token::Lt | token::OpenBrace | token::OpenParen)
415414
}) {
416-
self.parse_ident().unwrap()
415+
self.parse_ident_common(true).unwrap()
417416
} else {
418417
return Ok(());
419418
};

0 commit comments

Comments
 (0)