Skip to content

Commit 7e1e3eb

Browse files
committed
Auto merge of rust-lang#88662 - m-ou-se:rollup-h6lgp7k, r=m-ou-se
Rollup of 4 pull requests Successful merges: - rust-lang#88257 (Provide more context on incorrect inner attribute) - rust-lang#88432 (Fix a typo in raw_vec) - rust-lang#88511 (x.py clippy: don't run with --all-targets by default) - rust-lang#88657 (Fix 2021 `dyn` suggestion that used code as label) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 6b9a227 + b4d06bf commit 7e1e3eb

20 files changed

+426
-74
lines changed

compiler/rustc_parse/src/parser/attr.rs

+119-21
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
use super::{AttrWrapper, Capturing, Parser, PathStyle};
1+
use super::{AttrWrapper, Capturing, ForceCollect, Parser, PathStyle};
22
use rustc_ast as ast;
33
use rustc_ast::attr;
44
use rustc_ast::token::{self, Nonterminal};
55
use rustc_ast_pretty::pprust;
6-
use rustc_errors::{error_code, PResult};
7-
use rustc_span::{sym, Span};
6+
use rustc_errors::{error_code, DiagnosticBuilder, PResult};
7+
use rustc_span::{sym, BytePos, Span};
88
use std::convert::TryInto;
99

1010
use tracing::debug;
@@ -25,6 +25,12 @@ pub(super) const DEFAULT_INNER_ATTR_FORBIDDEN: InnerAttrPolicy<'_> = InnerAttrPo
2525
prev_attr_sp: None,
2626
};
2727

28+
enum OuterAttributeType {
29+
DocComment,
30+
DocBlockComment,
31+
Attribute,
32+
}
33+
2834
impl<'a> Parser<'a> {
2935
/// Parses attributes that appear before an item.
3036
pub(super) fn parse_outer_attributes(&mut self) -> PResult<'a, AttrWrapper> {
@@ -49,18 +55,32 @@ impl<'a> Parser<'a> {
4955
Some(self.parse_attribute(inner_parse_policy)?)
5056
} else if let token::DocComment(comment_kind, attr_style, data) = self.token.kind {
5157
if attr_style != ast::AttrStyle::Outer {
52-
self.sess
53-
.span_diagnostic
54-
.struct_span_err_with_code(
55-
self.token.span,
56-
"expected outer doc comment",
57-
error_code!(E0753),
58-
)
59-
.note(
60-
"inner doc comments like this (starting with \
61-
`//!` or `/*!`) can only appear before items",
62-
)
63-
.emit();
58+
let span = self.token.span;
59+
let mut err = self.sess.span_diagnostic.struct_span_err_with_code(
60+
span,
61+
"expected outer doc comment",
62+
error_code!(E0753),
63+
);
64+
if let Some(replacement_span) = self.annotate_following_item_if_applicable(
65+
&mut err,
66+
span,
67+
match comment_kind {
68+
token::CommentKind::Line => OuterAttributeType::DocComment,
69+
token::CommentKind::Block => OuterAttributeType::DocBlockComment,
70+
},
71+
) {
72+
err.note(
73+
"inner doc comments like this (starting with `//!` or `/*!`) can \
74+
only appear before items",
75+
);
76+
err.span_suggestion_verbose(
77+
replacement_span,
78+
"you might have meant to write a regular comment",
79+
String::new(),
80+
rustc_errors::Applicability::MachineApplicable,
81+
);
82+
}
83+
err.emit();
6484
}
6585
self.bump();
6686
just_parsed_doc_comment = true;
@@ -97,7 +117,7 @@ impl<'a> Parser<'a> {
97117
inner_parse_policy, self.token
98118
);
99119
let lo = self.token.span;
100-
// Attributse can't have attributes of their own
120+
// Attributes can't have attributes of their own [Editor's note: not with that attitude]
101121
self.collect_tokens_no_attrs(|this| {
102122
if this.eat(&token::Pound) {
103123
let style = if this.eat(&token::Not) {
@@ -125,6 +145,75 @@ impl<'a> Parser<'a> {
125145
})
126146
}
127147

148+
fn annotate_following_item_if_applicable(
149+
&self,
150+
err: &mut DiagnosticBuilder<'_>,
151+
span: Span,
152+
attr_type: OuterAttributeType,
153+
) -> Option<Span> {
154+
let mut snapshot = self.clone();
155+
let lo = span.lo()
156+
+ BytePos(match attr_type {
157+
OuterAttributeType::Attribute => 1,
158+
_ => 2,
159+
});
160+
let hi = lo + BytePos(1);
161+
let replacement_span = span.with_lo(lo).with_hi(hi);
162+
if let OuterAttributeType::DocBlockComment | OuterAttributeType::DocComment = attr_type {
163+
snapshot.bump();
164+
}
165+
loop {
166+
// skip any other attributes, we want the item
167+
if snapshot.token.kind == token::Pound {
168+
if let Err(mut err) = snapshot.parse_attribute(InnerAttrPolicy::Permitted) {
169+
err.cancel();
170+
return Some(replacement_span);
171+
}
172+
} else {
173+
break;
174+
}
175+
}
176+
match snapshot.parse_item_common(
177+
AttrWrapper::empty(),
178+
true,
179+
false,
180+
|_| true,
181+
ForceCollect::No,
182+
) {
183+
Ok(Some(item)) => {
184+
let attr_name = match attr_type {
185+
OuterAttributeType::Attribute => "attribute",
186+
_ => "doc comment",
187+
};
188+
err.span_label(
189+
item.span,
190+
&format!("the inner {} doesn't annotate this {}", attr_name, item.kind.descr()),
191+
);
192+
err.span_suggestion_verbose(
193+
replacement_span,
194+
&format!(
195+
"to annotate the {}, change the {} from inner to outer style",
196+
item.kind.descr(),
197+
attr_name
198+
),
199+
(match attr_type {
200+
OuterAttributeType::Attribute => "",
201+
OuterAttributeType::DocBlockComment => "*",
202+
OuterAttributeType::DocComment => "/",
203+
})
204+
.to_string(),
205+
rustc_errors::Applicability::MachineApplicable,
206+
);
207+
return None;
208+
}
209+
Err(mut item_err) => {
210+
item_err.cancel();
211+
}
212+
Ok(None) => {}
213+
}
214+
Some(replacement_span)
215+
}
216+
128217
pub(super) fn error_on_forbidden_inner_attr(&self, attr_sp: Span, policy: InnerAttrPolicy<'_>) {
129218
if let InnerAttrPolicy::Forbidden { reason, saw_doc_comment, prev_attr_sp } = policy {
130219
let prev_attr_note =
@@ -138,11 +227,20 @@ impl<'a> Parser<'a> {
138227
}
139228

140229
diag.note(
141-
"inner attributes, like `#![no_std]`, annotate the item enclosing them, \
142-
and are usually found at the beginning of source files. \
143-
Outer attributes, like `#[test]`, annotate the item following them.",
144-
)
145-
.emit();
230+
"inner attributes, like `#![no_std]`, annotate the item enclosing them, and \
231+
are usually found at the beginning of source files",
232+
);
233+
if self
234+
.annotate_following_item_if_applicable(
235+
&mut diag,
236+
attr_sp,
237+
OuterAttributeType::Attribute,
238+
)
239+
.is_some()
240+
{
241+
diag.note("outer attributes, like `#[test]`, annotate the item following them");
242+
};
243+
diag.emit();
146244
}
147245
}
148246

compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -945,7 +945,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
945945
Ok(s) if s.starts_with('<') => sugg,
946946
_ => format!("<{}>", sugg),
947947
};
948-
let replace = String::from("use `dyn`");
948+
let sugg_label = "use `dyn`";
949949
if self.sess().edition() >= Edition::Edition2021 {
950950
let mut err = rustc_errors::struct_span_err!(
951951
self.sess(),
@@ -956,8 +956,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
956956
);
957957
err.span_suggestion(
958958
self_ty.span,
959-
&sugg,
960-
replace,
959+
sugg_label,
960+
sugg,
961961
Applicability::MachineApplicable,
962962
)
963963
.emit();
@@ -968,7 +968,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
968968
self_ty.span,
969969
|lint| {
970970
let mut db = lint.build(msg);
971-
db.span_suggestion(self_ty.span, &replace, sugg, app);
971+
db.span_suggestion(self_ty.span, sugg_label, sugg, app);
972972
db.emit()
973973
},
974974
);

library/alloc/src/raw_vec.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ impl<T, A: Allocator> RawVec<T, A> {
323323
pub fn reserve(&mut self, len: usize, additional: usize) {
324324
// Callers expect this function to be very cheap when there is already sufficient capacity.
325325
// Therefore, we move all the resizing and error-handling logic from grow_amortized and
326-
// handle_reserve behind a call, while making sure that the this function is likely to be
326+
// handle_reserve behind a call, while making sure that this function is likely to be
327327
// inlined as just a comparison and a call if the comparison fails.
328328
#[cold]
329329
fn do_reserve_and_handle<T, A: Allocator>(

src/bootstrap/check.rs

+18-2
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,11 @@ impl Step for Std {
107107
add_to_sysroot(&builder, &libdir, &hostdir, &libstd_stamp(builder, compiler, target));
108108
}
109109

110+
// don't run on std twice with x.py clippy
111+
if builder.kind == Kind::Clippy {
112+
return;
113+
}
114+
110115
// Then run cargo again, once we've put the rmeta files for the library
111116
// crates into the sysroot. This is needed because e.g., core's tests
112117
// depend on `libtest` -- Cargo presumes it will exist, but it doesn't
@@ -120,6 +125,7 @@ impl Step for Std {
120125
target,
121126
cargo_subcommand(builder.kind),
122127
);
128+
123129
cargo.arg("--all-targets");
124130
std_cargo(builder, target, compiler.stage, &mut cargo);
125131

@@ -192,7 +198,12 @@ impl Step for Rustc {
192198
cargo_subcommand(builder.kind),
193199
);
194200
rustc_cargo(builder, &mut cargo, target);
195-
cargo.arg("--all-targets");
201+
202+
// For ./x.py clippy, don't run with --all-targets because
203+
// linting tests and benchmarks can produce very noisy results
204+
if builder.kind != Kind::Clippy {
205+
cargo.arg("--all-targets");
206+
}
196207

197208
// Explicitly pass -p for all compiler krates -- this will force cargo
198209
// to also check the tests/benches/examples for these crates, rather
@@ -313,7 +324,12 @@ macro_rules! tool_check_step {
313324
$source_type,
314325
&[],
315326
);
316-
cargo.arg("--all-targets");
327+
328+
// For ./x.py clippy, don't run with --all-targets because
329+
// linting tests and benchmarks can produce very noisy results
330+
if builder.kind != Kind::Clippy {
331+
cargo.arg("--all-targets");
332+
}
317333

318334
// Enable internal lints for clippy and rustdoc
319335
// NOTE: this doesn't enable lints for any other tools unless they explicitly add `#![warn(rustc::internal)]`
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// edition:2021
2+
3+
trait Foo<T> {}
4+
5+
impl<T> dyn Foo<T> {
6+
fn hi(_x: T) {}
7+
}
8+
9+
fn main() {
10+
Foo::hi(123);
11+
//~^ ERROR trait objects without an explicit `dyn` are deprecated
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0783]: trait objects without an explicit `dyn` are deprecated
2+
--> $DIR/dyn-trait-sugg-2021.rs:10:5
3+
|
4+
LL | Foo::hi(123);
5+
| ^^^ help: use `dyn`: `<dyn Foo>`
6+
7+
error: aborting due to previous error
8+
9+
For more information about this error, try `rustc --explain E0783`.

0 commit comments

Comments
 (0)