authorbors <bors@rust-lang.org> 2024-07-19 13:39:12 UTC
committerbors <bors@rust-lang.org> 2024-07-19 13:39:12 UTC
log3811f40d2701b3a8923d2d46e36dd3a93a824b49
treec4dd3eced80c90cb45e2eb3dbb4f56a5160a5155
parent11e57241f166194a328438d9264b68c98a18d51f
parent6fe68f88e72fd0b813dc39345d7a5e2a291c1e7c

Auto merge of #127957 - matthiaskrgr:rollup-1u5ivck, r=matthiaskrgr

Rollup of 6 pull requests Successful merges: - #127350 (Parser: Suggest Placing the Return Type After Function Parameters) - #127621 (Rewrite and rename `issue-22131` and `issue-26006` `run-make` tests to rmake) - #127662 (When finding item gated behind a `cfg` flag, point at it) - #127903 (`force_collect` improvements) - #127932 (rustdoc: fix `current` class on sidebar modnav) - #127943 (Don't allow unsafe statics outside of extern blocks) r? `@ghost` `@rustbot` modify labels: rollup

50 files changed, 497 insertions(+), 153 deletions(-)

compiler/rustc_ast_passes/messages.ftl+3
......@@ -269,6 +269,9 @@ ast_passes_unsafe_negative_impl = negative impls cannot be unsafe
269269 .negative = negative because of this
270270 .unsafe = unsafe because of this
271271
272ast_passes_unsafe_static =
273 static items cannot be declared with `unsafe` safety qualifier outside of `extern` block
274
272275ast_passes_visibility_not_permitted =
273276 visibility qualifiers are not permitted here
274277 .enum_variant = enum variants and their fields always share the visibility of the enum they are in
compiler/rustc_ast_passes/src/ast_validation.rs+8
......@@ -438,6 +438,11 @@ impl<'a> AstValidator<'a> {
438438 }
439439 }
440440
441 /// This ensures that items can only be `unsafe` (or unmarked) outside of extern
442 /// blocks.
443 ///
444 /// This additionally ensures that within extern blocks, items can only be
445 /// `safe`/`unsafe` inside of a `unsafe`-adorned extern block.
441446 fn check_item_safety(&self, span: Span, safety: Safety) {
442447 match self.extern_mod_safety {
443448 Some(extern_safety) => {
......@@ -1177,6 +1182,9 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
11771182 }
11781183 ItemKind::Static(box StaticItem { expr, safety, .. }) => {
11791184 self.check_item_safety(item.span, *safety);
1185 if matches!(safety, Safety::Unsafe(_)) {
1186 self.dcx().emit_err(errors::UnsafeStatic { span: item.span });
1187 }
11801188
11811189 if expr.is_none() {
11821190 self.dcx().emit_err(errors::StaticWithoutBody {
compiler/rustc_ast_passes/src/errors.rs+7
......@@ -224,6 +224,13 @@ pub struct InvalidSafetyOnBareFn {
224224 pub span: Span,
225225}
226226
227#[derive(Diagnostic)]
228#[diag(ast_passes_unsafe_static)]
229pub struct UnsafeStatic {
230 #[primary_span]
231 pub span: Span,
232}
233
227234#[derive(Diagnostic)]
228235#[diag(ast_passes_bound_in_context)]
229236pub struct BoundInContext<'a> {
compiler/rustc_builtin_macros/src/cmdline_attrs.rs+9-7
......@@ -4,6 +4,7 @@ use crate::errors;
44use rustc_ast::attr::mk_attr;
55use rustc_ast::token;
66use rustc_ast::{self as ast, AttrItem, AttrStyle};
7use rustc_parse::parser::ForceCollect;
78use rustc_parse::{new_parser_from_source_str, unwrap_or_emit_fatal};
89use rustc_session::parse::ParseSess;
910use rustc_span::FileName;
......@@ -17,13 +18,14 @@ pub fn inject(krate: &mut ast::Crate, psess: &ParseSess, attrs: &[String]) {
1718 ));
1819
1920 let start_span = parser.token.span;
20 let AttrItem { unsafety, path, args, tokens: _ } = match parser.parse_attr_item(false) {
21 Ok(ai) => ai,
22 Err(err) => {
23 err.emit();
24 continue;
25 }
26 };
21 let AttrItem { unsafety, path, args, tokens: _ } =
22 match parser.parse_attr_item(ForceCollect::No) {
23 Ok(ai) => ai,
24 Err(err) => {
25 err.emit();
26 continue;
27 }
28 };
2729 let end_span = parser.token.span;
2830 if parser.token != token::Eof {
2931 psess.dcx().emit_err(errors::InvalidCrateAttr { span: start_span.to(end_span) });
compiler/rustc_parse/messages.ftl+2
......@@ -524,6 +524,8 @@ parse_mismatched_closing_delimiter = mismatched closing delimiter: `{$delimiter}
524524 .label_opening_candidate = closing delimiter possibly meant for this
525525 .label_unclosed = unclosed delimiter
526526
527parse_misplaced_return_type = place the return type after the function parameters
528
527529parse_missing_comma_after_match_arm = expected `,` following `match` arm
528530 .suggestion = missing a comma here to end this `match` arm
529531
compiler/rustc_parse/src/errors.rs+15-7
......@@ -1502,6 +1502,20 @@ pub(crate) struct FnPtrWithGenerics {
15021502 pub sugg: Option<FnPtrWithGenericsSugg>,
15031503}
15041504
1505#[derive(Subdiagnostic)]
1506#[multipart_suggestion(
1507 parse_misplaced_return_type,
1508 style = "verbose",
1509 applicability = "maybe-incorrect"
1510)]
1511pub(crate) struct MisplacedReturnType {
1512 #[suggestion_part(code = " {snippet}")]
1513 pub fn_params_end: Span,
1514 pub snippet: String,
1515 #[suggestion_part(code = "")]
1516 pub ret_ty_span: Span,
1517}
1518
15051519#[derive(Subdiagnostic)]
15061520#[multipart_suggestion(parse_suggestion, applicability = "maybe-incorrect")]
15071521pub(crate) struct FnPtrWithGenericsSugg {
......@@ -1516,7 +1530,6 @@ pub(crate) struct FnPtrWithGenericsSugg {
15161530
15171531pub(crate) struct FnTraitMissingParen {
15181532 pub span: Span,
1519 pub machine_applicable: bool,
15201533}
15211534
15221535impl Subdiagnostic for FnTraitMissingParen {
......@@ -1526,16 +1539,11 @@ impl Subdiagnostic for FnTraitMissingParen {
15261539 _: &F,
15271540 ) {
15281541 diag.span_label(self.span, crate::fluent_generated::parse_fn_trait_missing_paren);
1529 let applicability = if self.machine_applicable {
1530 Applicability::MachineApplicable
1531 } else {
1532 Applicability::MaybeIncorrect
1533 };
15341542 diag.span_suggestion_short(
15351543 self.span.shrink_to_hi(),
15361544 crate::fluent_generated::parse_add_paren,
15371545 "()",
1538 applicability,
1546 Applicability::MachineApplicable,
15391547 );
15401548 }
15411549}
compiler/rustc_parse/src/parser/attr.rs+7-8
......@@ -124,7 +124,7 @@ impl<'a> Parser<'a> {
124124 if this.eat(&token::Not) { ast::AttrStyle::Inner } else { ast::AttrStyle::Outer };
125125
126126 this.expect(&token::OpenDelim(Delimiter::Bracket))?;
127 let item = this.parse_attr_item(false)?;
127 let item = this.parse_attr_item(ForceCollect::No)?;
128128 this.expect(&token::CloseDelim(Delimiter::Bracket))?;
129129 let attr_sp = lo.to(this.prev_token.span);
130130
......@@ -248,16 +248,15 @@ impl<'a> Parser<'a> {
248248 /// PATH
249249 /// PATH `=` UNSUFFIXED_LIT
250250 /// The delimiters or `=` are still put into the resulting token stream.
251 pub fn parse_attr_item(&mut self, capture_tokens: bool) -> PResult<'a, ast::AttrItem> {
251 pub fn parse_attr_item(&mut self, force_collect: ForceCollect) -> PResult<'a, ast::AttrItem> {
252252 maybe_whole!(self, NtMeta, |attr| attr.into_inner());
253253
254 let do_parse = |this: &mut Self| {
254 let do_parse = |this: &mut Self, _empty_attrs| {
255255 let is_unsafe = this.eat_keyword(kw::Unsafe);
256256 let unsafety = if is_unsafe {
257257 let unsafe_span = this.prev_token.span;
258258 this.psess.gated_spans.gate(sym::unsafe_attributes, unsafe_span);
259259 this.expect(&token::OpenDelim(Delimiter::Parenthesis))?;
260
261260 ast::Safety::Unsafe(unsafe_span)
262261 } else {
263262 ast::Safety::Default
......@@ -268,10 +267,10 @@ impl<'a> Parser<'a> {
268267 if is_unsafe {
269268 this.expect(&token::CloseDelim(Delimiter::Parenthesis))?;
270269 }
271 Ok(ast::AttrItem { unsafety, path, args, tokens: None })
270 Ok((ast::AttrItem { unsafety, path, args, tokens: None }, false))
272271 };
273 // Attr items don't have attributes
274 if capture_tokens { self.collect_tokens_no_attrs(do_parse) } else { do_parse(self) }
272 // Attr items don't have attributes.
273 self.collect_tokens_trailing_token(AttrWrapper::empty(), force_collect, do_parse)
275274 }
276275
277276 /// Parses attributes that appear after the opening of an item. These should
......@@ -340,7 +339,7 @@ impl<'a> Parser<'a> {
340339 let mut expanded_attrs = Vec::with_capacity(1);
341340 while self.token.kind != token::Eof {
342341 let lo = self.token.span;
343 let item = self.parse_attr_item(true)?;
342 let item = self.parse_attr_item(ForceCollect::Yes)?;
344343 expanded_attrs.push((item, lo.to(self.prev_token.span)));
345344 if !self.eat(&token::Comma) {
346345 break;
compiler/rustc_parse/src/parser/diagnostics.rs+4-4
......@@ -430,7 +430,7 @@ impl<'a> Parser<'a> {
430430 &mut self,
431431 edible: &[TokenKind],
432432 inedible: &[TokenKind],
433 ) -> PResult<'a, Recovered> {
433 ) -> PResult<'a, ErrorGuaranteed> {
434434 debug!("expected_one_of_not_found(edible: {:?}, inedible: {:?})", edible, inedible);
435435 fn tokens_to_string(tokens: &[TokenType]) -> String {
436436 let mut i = tokens.iter();
......@@ -533,7 +533,7 @@ impl<'a> Parser<'a> {
533533 sugg: ExpectedSemiSugg::ChangeToSemi(self.token.span),
534534 });
535535 self.bump();
536 return Ok(Recovered::Yes(guar));
536 return Ok(guar);
537537 } else if self.look_ahead(0, |t| {
538538 t == &token::CloseDelim(Delimiter::Brace)
539539 || ((t.can_begin_expr() || t.can_begin_item())
......@@ -557,7 +557,7 @@ impl<'a> Parser<'a> {
557557 unexpected_token_label: Some(self.token.span),
558558 sugg: ExpectedSemiSugg::AddSemi(span),
559559 });
560 return Ok(Recovered::Yes(guar));
560 return Ok(guar);
561561 }
562562 }
563563
......@@ -712,7 +712,7 @@ impl<'a> Parser<'a> {
712712 if self.check_too_many_raw_str_terminators(&mut err) {
713713 if expected.contains(&TokenType::Token(token::Semi)) && self.eat(&token::Semi) {
714714 let guar = err.emit();
715 return Ok(Recovered::Yes(guar));
715 return Ok(guar);
716716 } else {
717717 return Err(err);
718718 }
compiler/rustc_parse/src/parser/item.rs+96-28
......@@ -17,6 +17,7 @@ use rustc_span::edit_distance::edit_distance;
1717use rustc_span::edition::Edition;
1818use rustc_span::source_map;
1919use rustc_span::symbol::{kw, sym, Ident, Symbol};
20use rustc_span::ErrorGuaranteed;
2021use rustc_span::{Span, DUMMY_SP};
2122use std::fmt::Write;
2223use std::mem;
......@@ -2332,14 +2333,106 @@ impl<'a> Parser<'a> {
23322333 }
23332334 }
23342335 };
2336
2337 // Store the end of function parameters to give better diagnostics
2338 // inside `parse_fn_body()`.
2339 let fn_params_end = self.prev_token.span.shrink_to_hi();
2340
23352341 generics.where_clause = self.parse_where_clause()?; // `where T: Ord`
23362342
2343 // `fn_params_end` is needed only when it's followed by a where clause.
2344 let fn_params_end =
2345 if generics.where_clause.has_where_token { Some(fn_params_end) } else { None };
2346
23372347 let mut sig_hi = self.prev_token.span;
2338 let body = self.parse_fn_body(attrs, &ident, &mut sig_hi, fn_parse_mode.req_body)?; // `;` or `{ ... }`.
2348 // Either `;` or `{ ... }`.
2349 let body =
2350 self.parse_fn_body(attrs, &ident, &mut sig_hi, fn_parse_mode.req_body, fn_params_end)?;
23392351 let fn_sig_span = sig_lo.to(sig_hi);
23402352 Ok((ident, FnSig { header, decl, span: fn_sig_span }, generics, body))
23412353 }
23422354
2355 /// Provide diagnostics when function body is not found
2356 fn error_fn_body_not_found(
2357 &mut self,
2358 ident_span: Span,
2359 req_body: bool,
2360 fn_params_end: Option<Span>,
2361 ) -> PResult<'a, ErrorGuaranteed> {
2362 let expected = if req_body {
2363 &[token::OpenDelim(Delimiter::Brace)][..]
2364 } else {
2365 &[token::Semi, token::OpenDelim(Delimiter::Brace)]
2366 };
2367 match self.expected_one_of_not_found(&[], expected) {
2368 Ok(error_guaranteed) => Ok(error_guaranteed),
2369 Err(mut err) => {
2370 if self.token.kind == token::CloseDelim(Delimiter::Brace) {
2371 // The enclosing `mod`, `trait` or `impl` is being closed, so keep the `fn` in
2372 // the AST for typechecking.
2373 err.span_label(ident_span, "while parsing this `fn`");
2374 Ok(err.emit())
2375 } else if self.token.kind == token::RArrow
2376 && let Some(fn_params_end) = fn_params_end
2377 {
2378 // Instead of a function body, the parser has encountered a right arrow
2379 // preceded by a where clause.
2380
2381 // Find whether token behind the right arrow is a function trait and
2382 // store its span.
2383 let fn_trait_span =
2384 [sym::FnOnce, sym::FnMut, sym::Fn].into_iter().find_map(|symbol| {
2385 if self.prev_token.is_ident_named(symbol) {
2386 Some(self.prev_token.span)
2387 } else {
2388 None
2389 }
2390 });
2391
2392 // Parse the return type (along with the right arrow) and store its span.
2393 // If there's a parse error, cancel it and return the existing error
2394 // as we are primarily concerned with the
2395 // expected-function-body-but-found-something-else error here.
2396 let arrow_span = self.token.span;
2397 let ty_span = match self.parse_ret_ty(
2398 AllowPlus::Yes,
2399 RecoverQPath::Yes,
2400 RecoverReturnSign::Yes,
2401 ) {
2402 Ok(ty_span) => ty_span.span().shrink_to_hi(),
2403 Err(parse_error) => {
2404 parse_error.cancel();
2405 return Err(err);
2406 }
2407 };
2408 let ret_ty_span = arrow_span.to(ty_span);
2409
2410 if let Some(fn_trait_span) = fn_trait_span {
2411 // Typo'd Fn* trait bounds such as
2412 // fn foo<F>() where F: FnOnce -> () {}
2413 err.subdiagnostic(errors::FnTraitMissingParen { span: fn_trait_span });
2414 } else if let Ok(snippet) = self.psess.source_map().span_to_snippet(ret_ty_span)
2415 {
2416 // If token behind right arrow is not a Fn* trait, the programmer
2417 // probably misplaced the return type after the where clause like
2418 // `fn foo<T>() where T: Default -> u8 {}`
2419 err.primary_message(
2420 "return type should be specified after the function parameters",
2421 );
2422 err.subdiagnostic(errors::MisplacedReturnType {
2423 fn_params_end,
2424 snippet,
2425 ret_ty_span,
2426 });
2427 }
2428 Err(err)
2429 } else {
2430 Err(err)
2431 }
2432 }
2433 }
2434 }
2435
23432436 /// Parse the "body" of a function.
23442437 /// This can either be `;` when there's no body,
23452438 /// or e.g. a block when the function is a provided one.
......@@ -2349,6 +2442,7 @@ impl<'a> Parser<'a> {
23492442 ident: &Ident,
23502443 sig_hi: &mut Span,
23512444 req_body: bool,
2445 fn_params_end: Option<Span>,
23522446 ) -> PResult<'a, Option<P<Block>>> {
23532447 let has_semi = if req_body {
23542448 self.token.kind == TokenKind::Semi
......@@ -2377,33 +2471,7 @@ impl<'a> Parser<'a> {
23772471 });
23782472 (AttrVec::new(), Some(self.mk_block_err(span, guar)))
23792473 } else {
2380 let expected = if req_body {
2381 &[token::OpenDelim(Delimiter::Brace)][..]
2382 } else {
2383 &[token::Semi, token::OpenDelim(Delimiter::Brace)]
2384 };
2385 if let Err(mut err) = self.expected_one_of_not_found(&[], expected) {
2386 if self.token.kind == token::CloseDelim(Delimiter::Brace) {
2387 // The enclosing `mod`, `trait` or `impl` is being closed, so keep the `fn` in
2388 // the AST for typechecking.
2389 err.span_label(ident.span, "while parsing this `fn`");
2390 err.emit();
2391 } else {
2392 // check for typo'd Fn* trait bounds such as
2393 // fn foo<F>() where F: FnOnce -> () {}
2394 if self.token.kind == token::RArrow {
2395 let machine_applicable = [sym::FnOnce, sym::FnMut, sym::Fn]
2396 .into_iter()
2397 .any(|s| self.prev_token.is_ident_named(s));
2398
2399 err.subdiagnostic(errors::FnTraitMissingParen {
2400 span: self.prev_token.span,
2401 machine_applicable,
2402 });
2403 }
2404 return Err(err);
2405 }
2406 }
2474 self.error_fn_body_not_found(ident.span, req_body, fn_params_end)?;
24072475 (AttrVec::new(), None)
24082476 };
24092477 attrs.extend(inner_attrs);
compiler/rustc_parse/src/parser/mod.rs+5-5
......@@ -501,6 +501,7 @@ impl<'a> Parser<'a> {
501501 FatalError.raise();
502502 } else {
503503 self.expected_one_of_not_found(edible, inedible)
504 .map(|error_guaranteed| Recovered::Yes(error_guaranteed))
504505 }
505506 }
506507
......@@ -948,11 +949,10 @@ impl<'a> Parser<'a> {
948949 let initial_semicolon = self.token.span;
949950
950951 while self.eat(&TokenKind::Semi) {
951 let _ =
952 self.parse_stmt_without_recovery(false, ForceCollect::Yes).unwrap_or_else(|e| {
953 e.cancel();
954 None
955 });
952 let _ = self.parse_stmt_without_recovery(false, ForceCollect::No).unwrap_or_else(|e| {
953 e.cancel();
954 None
955 });
956956 }
957957
958958 expect_err
compiler/rustc_parse/src/parser/nonterminal.rs+1-1
......@@ -171,7 +171,7 @@ impl<'a> Parser<'a> {
171171 NonterminalKind::Path => {
172172 NtPath(P(self.collect_tokens_no_attrs(|this| this.parse_path(PathStyle::Type))?))
173173 }
174 NonterminalKind::Meta => NtMeta(P(self.parse_attr_item(true)?)),
174 NonterminalKind::Meta => NtMeta(P(self.parse_attr_item(ForceCollect::Yes)?)),
175175 NonterminalKind::Vis => {
176176 NtVis(P(self
177177 .collect_tokens_no_attrs(|this| this.parse_visibility(FollowedByType::Yes))?))
compiler/rustc_parse/src/parser/stmt.rs+26-22
......@@ -72,6 +72,7 @@ impl<'a> Parser<'a> {
7272 lo,
7373 attrs,
7474 errors::InvalidVariableDeclarationSub::MissingLet,
75 force_collect,
7576 )?
7677 } else if self.is_kw_followed_by_ident(kw::Auto) && self.may_recover() {
7778 self.bump(); // `auto`
......@@ -79,6 +80,7 @@ impl<'a> Parser<'a> {
7980 lo,
8081 attrs,
8182 errors::InvalidVariableDeclarationSub::UseLetNotAuto,
83 force_collect,
8284 )?
8385 } else if self.is_kw_followed_by_ident(sym::var) && self.may_recover() {
8486 self.bump(); // `var`
......@@ -86,6 +88,7 @@ impl<'a> Parser<'a> {
8688 lo,
8789 attrs,
8890 errors::InvalidVariableDeclarationSub::UseLetNotVar,
91 force_collect,
8992 )?
9093 } else if self.check_path()
9194 && !self.token.is_qpath_start()
......@@ -96,17 +99,17 @@ impl<'a> Parser<'a> {
9699 // or `auto trait` items. We aim to parse an arbitrary path `a::b` but not something
97100 // that starts like a path (1 token), but it fact not a path.
98101 // Also, we avoid stealing syntax from `parse_item_`.
99 match force_collect {
100 ForceCollect::Yes => {
101 self.collect_tokens_no_attrs(|this| this.parse_stmt_path_start(lo, attrs))?
102 let stmt = self.collect_tokens_trailing_token(
103 AttrWrapper::empty(),
104 force_collect,
105 |this, _empty_attrs| Ok((this.parse_stmt_path_start(lo, attrs)?, false)),
106 );
107 match stmt {
108 Ok(stmt) => stmt,
109 Err(mut err) => {
110 self.suggest_add_missing_let_for_stmt(&mut err);
111 return Err(err);
102112 }
103 ForceCollect::No => match self.parse_stmt_path_start(lo, attrs) {
104 Ok(stmt) => stmt,
105 Err(mut err) => {
106 self.suggest_add_missing_let_for_stmt(&mut err);
107 return Err(err);
108 }
109 },
110113 }
111114 } else if let Some(item) = self.parse_item_common(
112115 attrs.clone(),
......@@ -123,12 +126,13 @@ impl<'a> Parser<'a> {
123126 self.mk_stmt(lo, StmtKind::Empty)
124127 } else if self.token != token::CloseDelim(Delimiter::Brace) {
125128 // Remainder are line-expr stmts.
126 let e = match force_collect {
127 ForceCollect::Yes => self.collect_tokens_no_attrs(|this| {
128 this.parse_expr_res(Restrictions::STMT_EXPR, attrs)
129 })?,
130 ForceCollect::No => self.parse_expr_res(Restrictions::STMT_EXPR, attrs)?,
131 };
129 let e = self.collect_tokens_trailing_token(
130 AttrWrapper::empty(),
131 force_collect,
132 |this, _empty_attrs| {
133 Ok((this.parse_expr_res(Restrictions::STMT_EXPR, attrs)?, false))
134 },
135 )?;
132136 if matches!(e.kind, ExprKind::Assign(..)) && self.eat_keyword(kw::Else) {
133137 let bl = self.parse_block()?;
134138 // Destructuring assignment ... else.
......@@ -231,13 +235,13 @@ impl<'a> Parser<'a> {
231235 lo: Span,
232236 attrs: AttrWrapper,
233237 subdiagnostic: fn(Span) -> errors::InvalidVariableDeclarationSub,
238 force_collect: ForceCollect,
234239 ) -> PResult<'a, Stmt> {
235 let stmt =
236 self.collect_tokens_trailing_token(attrs, ForceCollect::Yes, |this, attrs| {
237 let local = this.parse_local(attrs)?;
238 // FIXME - maybe capture semicolon in recovery?
239 Ok((this.mk_stmt(lo.to(this.prev_token.span), StmtKind::Let(local)), false))
240 })?;
240 let stmt = self.collect_tokens_trailing_token(attrs, force_collect, |this, attrs| {
241 let local = this.parse_local(attrs)?;
242 // FIXME - maybe capture semicolon in recovery?
243 Ok((this.mk_stmt(lo.to(this.prev_token.span), StmtKind::Let(local)), false))
244 })?;
241245 self.dcx()
242246 .emit_err(errors::InvalidVariableDeclaration { span: lo, sub: subdiagnostic(lo) });
243247 Ok(stmt)
compiler/rustc_parse/src/parser/ty.rs+5
......@@ -21,6 +21,11 @@ use rustc_span::symbol::{kw, sym, Ident};
2121use rustc_span::{ErrorGuaranteed, Span, Symbol};
2222use thin_vec::{thin_vec, ThinVec};
2323
24/// Signals whether parsing a type should allow `+`.
25///
26/// For example, let T be the type `impl Default + 'static`
27/// With `AllowPlus::Yes`, T will be parsed successfully
28/// With `AllowPlus::No`, parsing T will return a parse error
2429#[derive(Copy, Clone, PartialEq)]
2530pub(super) enum AllowPlus {
2631 Yes,
compiler/rustc_resolve/messages.ftl+2
......@@ -232,6 +232,8 @@ resolve_is_private =
232232resolve_item_was_behind_feature =
233233 the item is gated behind the `{$feature}` feature
234234
235resolve_item_was_cfg_out = the item is gated here
236
235237resolve_items_in_traits_are_not_importable =
236238 items in traits are not importable
237239
compiler/rustc_resolve/src/diagnostics.rs+7-1
......@@ -2532,7 +2532,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
25322532 && let NestedMetaItem::MetaItem(meta_item) = &nested[0]
25332533 && let MetaItemKind::NameValue(feature_name) = &meta_item.kind
25342534 {
2535 let note = errors::ItemWasBehindFeature { feature: feature_name.symbol };
2535 let note = errors::ItemWasBehindFeature {
2536 feature: feature_name.symbol,
2537 span: meta_item.span,
2538 };
2539 err.subdiagnostic(note);
2540 } else {
2541 let note = errors::ItemWasCfgOut { span: cfg.span };
25362542 err.subdiagnostic(note);
25372543 }
25382544 }
compiler/rustc_resolve/src/errors.rs+9
......@@ -1228,6 +1228,15 @@ pub(crate) struct FoundItemConfigureOut {
12281228#[note(resolve_item_was_behind_feature)]
12291229pub(crate) struct ItemWasBehindFeature {
12301230 pub(crate) feature: Symbol,
1231 #[primary_span]
1232 pub(crate) span: Span,
1233}
1234
1235#[derive(Subdiagnostic)]
1236#[note(resolve_item_was_cfg_out)]
1237pub(crate) struct ItemWasCfgOut {
1238 #[primary_span]
1239 pub(crate) span: Span,
12311240}
12321241
12331242#[derive(Diagnostic)]
src/librustdoc/html/static/js/main.js+5-3
......@@ -529,11 +529,13 @@ function preLoadCss(cssUrl) {
529529 }
530530 const link = document.createElement("a");
531531 link.href = path;
532 if (path === current_page) {
533 link.className = "current";
534 }
535532 link.textContent = name;
536533 const li = document.createElement("li");
534 // Don't "optimize" this to just use `path`.
535 // We want the browser to normalize this into an absolute URL.
536 if (link.href === current_page) {
537 li.classList.add("current");
538 }
537539 li.appendChild(link);
538540 ul.appendChild(li);
539541 }
src/tools/tidy/src/allowed_run_make_makefiles.txt-2
......@@ -37,8 +37,6 @@ run-make/interdependent-c-libraries/Makefile
3737run-make/issue-107094/Makefile
3838run-make/issue-14698/Makefile
3939run-make/issue-15460/Makefile
40run-make/issue-22131/Makefile
41run-make/issue-26006/Makefile
4240run-make/issue-28595/Makefile
4341run-make/issue-33329/Makefile
4442run-make/issue-35164/Makefile
tests/run-make/invalid-symlink-search-path/in/bar/lib.rs created+5
......@@ -0,0 +1,5 @@
1extern crate foo;
2
3pub fn main() {
4 let _ = foo::hello_world();
5}
tests/run-make/invalid-symlink-search-path/in/foo/lib.rs created+3
......@@ -0,0 +1,3 @@
1pub fn hello_world() -> i32 {
2 42
3}
tests/run-make/invalid-symlink-search-path/rmake.rs created+33
......@@ -0,0 +1,33 @@
1// In this test, the symlink created is invalid (valid relative to the root, but not
2// relatively to where it is located), and used to cause an internal
3// compiler error (ICE) when passed as a library search path. This was fixed in #26044,
4// and this test checks that the invalid symlink is instead simply ignored.
5// See https://github.com/rust-lang/rust/issues/26006
6
7//@ needs-symlink
8//Reason: symlink requires elevated permission in Windows
9
10use run_make_support::{rfs, rustc};
11
12fn main() {
13 // We create two libs: `bar` which depends on `foo`. We need to compile `foo` first.
14 rfs::create_dir("out");
15 rfs::create_dir("out/foo");
16 rustc()
17 .input("in/foo/lib.rs")
18 .crate_name("foo")
19 .crate_type("lib")
20 .metadata("foo")
21 .output("out/foo/libfoo.rlib")
22 .run();
23 rfs::create_dir("out/bar");
24 rfs::create_dir("out/bar/deps");
25 rfs::create_symlink("out/foo/libfoo.rlib", "out/bar/deps/libfoo.rlib");
26 // Check that the invalid symlink does not cause an ICE
27 rustc()
28 .input("in/bar/lib.rs")
29 .library_search_path("dependency=out/bar/deps")
30 .run_fail()
31 .assert_exit_code(1)
32 .assert_stderr_not_contains("internal compiler error");
33}
tests/run-make/issue-22131/Makefile deleted-8
......@@ -1,8 +0,0 @@
1# ignore-cross-compile
2include ../tools.mk
3
4all: foo.rs
5 $(RUSTC) --cfg 'feature="bar"' --crate-type lib foo.rs
6 $(RUSTDOC) --test --cfg 'feature="bar"' \
7 -L $(TMPDIR) foo.rs |\
8 $(CGREP) 'foo.rs - foo (line 1) ... ok'
tests/run-make/issue-22131/foo.rs deleted-7
......@@ -1,7 +0,0 @@
1/// ```rust
2/// assert_eq!(foo::foo(), 1);
3/// ```
4#[cfg(feature = "bar")]
5pub fn foo() -> i32 {
6 1
7}
tests/run-make/issue-26006/Makefile deleted-17
......@@ -1,17 +0,0 @@
1# ignore-cross-compile
2include ../tools.mk
3
4# ignore-windows
5
6OUT := $(TMPDIR)/out
7
8all: time
9
10time: libc
11 mkdir -p $(OUT)/time $(OUT)/time/deps
12 ln -sf $(OUT)/libc/liblibc.rlib $(OUT)/time/deps/
13 $(RUSTC) in/time/lib.rs -Ldependency=$(OUT)/time/deps/
14
15libc:
16 mkdir -p $(OUT)/libc
17 $(RUSTC) in/libc/lib.rs --crate-name=libc -Cmetadata=foo -o $(OUT)/libc/liblibc.rlib
tests/run-make/issue-26006/in/libc/lib.rs deleted-3
......@@ -1,3 +0,0 @@
1#![crate_type = "rlib"]
2
3pub fn something() {}
tests/run-make/issue-26006/in/time/lib.rs deleted-4
......@@ -1,4 +0,0 @@
1#![feature(rustc_private)]
2extern crate libc;
3
4fn main() {}
tests/run-make/rustdoc-cfgspec-parsing/foo.rs created+7
......@@ -0,0 +1,7 @@
1/// ```rust
2/// assert_eq!(foo::foo(), 1);
3/// ```
4#[cfg(feature = "bar")]
5pub fn foo() -> i32 {
6 1
7}
tests/run-make/rustdoc-cfgspec-parsing/rmake.rs created+21
......@@ -0,0 +1,21 @@
1// A rustdoc bug caused the `feature=bar` syntax for the cfg flag to be interpreted
2// wrongly, with `feature=bar` instead of just `bar` being understood as the feature name.
3// After this was fixed in #22135, this test checks that this bug does not make a resurgence.
4// See https://github.com/rust-lang/rust/issues/22131
5
6//@ ignore-cross-compile
7// Reason: rustdoc fails to find the "foo" crate
8
9use run_make_support::{cwd, rustc, rustdoc};
10
11fn main() {
12 rustc().cfg(r#"feature="bar""#).crate_type("lib").input("foo.rs").run();
13 rustdoc()
14 .arg("--test")
15 .arg("--cfg")
16 .arg(r#"feature="bar""#)
17 .library_search_path(cwd())
18 .input("foo.rs")
19 .run()
20 .assert_stdout_contains("foo.rs - foo (line 1) ... ok");
21}
tests/rustdoc-gui/sidebar.goml+4
......@@ -72,6 +72,7 @@ click: "#structs + .item-table .item-name > a"
7272assert-count: (".sidebar .sidebar-crate", 1)
7373assert-count: (".sidebar .location", 1)
7474assert-count: (".sidebar h2", 3)
75assert-text: (".sidebar-elems ul.block > li.current > a", "Foo")
7576// We check that there is no crate listed outside of the top level.
7677assert-false: ".sidebar-elems > .crate"
7778
......@@ -110,6 +111,7 @@ click: "#functions + .item-table .item-name > a"
110111assert-text: (".sidebar > .sidebar-crate > h2 > a", "lib2")
111112assert-count: (".sidebar .location", 0)
112113assert-count: (".sidebar h2", 1)
114assert-text: (".sidebar-elems ul.block > li.current > a", "foobar")
113115// We check that we don't have the crate list.
114116assert-false: ".sidebar-elems > .crate"
115117
......@@ -118,6 +120,7 @@ assert-property: (".sidebar", {"clientWidth": "200"})
118120assert-text: (".sidebar > .sidebar-crate > h2 > a", "lib2")
119121assert-text: (".sidebar > .location", "Module module")
120122assert-count: (".sidebar .location", 1)
123assert-text: (".sidebar-elems ul.block > li.current > a", "module")
121124// Module page requires three headings:
122125// - Presistent crate branding (name and version)
123126// - Module name, followed by TOC for module headings
......@@ -138,6 +141,7 @@ assert-text: (".sidebar > .sidebar-elems > h2", "In lib2::module::sub_module")
138141assert-property: (".sidebar > .sidebar-elems > h2 > a", {
139142 "href": "/module/sub_module/index.html",
140143}, ENDS_WITH)
144assert-text: (".sidebar-elems ul.block > li.current > a", "sub_sub_module")
141145// We check that we don't have the crate list.
142146assert-false: ".sidebar-elems .crate"
143147assert-text: (".sidebar-elems > section ul > li:nth-child(1)", "Functions")
tests/ui/cfg/diagnostics-cross-crate.rs+3
......@@ -11,12 +11,14 @@ fn main() {
1111 cfged_out::inner::uwu(); //~ ERROR cannot find function
1212 //~^ NOTE found an item that was configured out
1313 //~| NOTE not found in `cfged_out::inner`
14 //~| NOTE the item is gated here
1415
1516 // The module isn't found - we would like to get a diagnostic, but currently don't due to
1617 // the awkward way the resolver diagnostics are currently implemented.
1718 cfged_out::inner::doesnt_exist::hello(); //~ ERROR failed to resolve
1819 //~^ NOTE could not find `doesnt_exist` in `inner`
1920 //~| NOTE found an item that was configured out
21 //~| NOTE the item is gated here
2022
2123 // It should find the one in the right module, not the wrong one.
2224 cfged_out::inner::right::meow(); //~ ERROR cannot find function
......@@ -28,4 +30,5 @@ fn main() {
2830 cfged_out::vanished(); //~ ERROR cannot find function
2931 //~^ NOTE found an item that was configured out
3032 //~| NOTE not found in `cfged_out`
33 //~| NOTE the item is gated here
3134}
tests/ui/cfg/diagnostics-cross-crate.stderr+23-4
......@@ -1,5 +1,5 @@
11error[E0433]: failed to resolve: could not find `doesnt_exist` in `inner`
2 --> $DIR/diagnostics-cross-crate.rs:17:23
2 --> $DIR/diagnostics-cross-crate.rs:18:23
33 |
44LL | cfged_out::inner::doesnt_exist::hello();
55 | ^^^^^^^^^^^^ could not find `doesnt_exist` in `inner`
......@@ -9,6 +9,11 @@ note: found an item that was configured out
99 |
1010LL | pub mod doesnt_exist {
1111 | ^^^^^^^^^^^^
12note: the item is gated here
13 --> $DIR/auxiliary/cfged_out.rs:5:5
14 |
15LL | #[cfg(FALSE)]
16 | ^^^^^^^^^^^^^
1217
1318error[E0425]: cannot find function `uwu` in crate `cfged_out`
1419 --> $DIR/diagnostics-cross-crate.rs:7:16
......@@ -27,9 +32,14 @@ note: found an item that was configured out
2732 |
2833LL | pub fn uwu() {}
2934 | ^^^
35note: the item is gated here
36 --> $DIR/auxiliary/cfged_out.rs:2:5
37 |
38LL | #[cfg(FALSE)]
39 | ^^^^^^^^^^^^^
3040
3141error[E0425]: cannot find function `meow` in module `cfged_out::inner::right`
32 --> $DIR/diagnostics-cross-crate.rs:22:30
42 --> $DIR/diagnostics-cross-crate.rs:24:30
3343 |
3444LL | cfged_out::inner::right::meow();
3545 | ^^^^ not found in `cfged_out::inner::right`
......@@ -39,10 +49,14 @@ note: found an item that was configured out
3949 |
4050LL | pub fn meow() {}
4151 | ^^^^
42 = note: the item is gated behind the `what-a-cool-feature` feature
52note: the item is gated behind the `what-a-cool-feature` feature
53 --> $DIR/auxiliary/cfged_out.rs:16:15
54 |
55LL | #[cfg(feature = "what-a-cool-feature")]
56 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4357
4458error[E0425]: cannot find function `vanished` in crate `cfged_out`
45 --> $DIR/diagnostics-cross-crate.rs:28:16
59 --> $DIR/diagnostics-cross-crate.rs:30:16
4660 |
4761LL | cfged_out::vanished();
4862 | ^^^^^^^^ not found in `cfged_out`
......@@ -52,6 +66,11 @@ note: found an item that was configured out
5266 |
5367LL | pub fn vanished() {}
5468 | ^^^^^^^^
69note: the item is gated here
70 --> $DIR/auxiliary/cfged_out.rs:21:1
71 |
72LL | #[cfg(i_dont_exist_and_you_can_do_nothing_about_it)]
73 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5574
5675error: aborting due to 5 previous errors
5776
tests/ui/cfg/diagnostics-reexport.rs+4-4
......@@ -4,7 +4,7 @@ pub mod inner {
44 pub fn uwu() {}
55 }
66
7 #[cfg(FALSE)]
7 #[cfg(FALSE)] //~ NOTE the item is gated here
88 pub use super::uwu;
99 //~^ NOTE found an item that was configured out
1010}
......@@ -14,7 +14,7 @@ pub use a::x;
1414//~| NOTE no `x` in `a`
1515
1616mod a {
17 #[cfg(FALSE)]
17 #[cfg(FALSE)] //~ NOTE the item is gated here
1818 pub fn x() {}
1919 //~^ NOTE found an item that was configured out
2020}
......@@ -25,10 +25,10 @@ pub use b::{x, y};
2525//~| NOTE no `y` in `b`
2626
2727mod b {
28 #[cfg(FALSE)]
28 #[cfg(FALSE)] //~ NOTE the item is gated here
2929 pub fn x() {}
3030 //~^ NOTE found an item that was configured out
31 #[cfg(FALSE)]
31 #[cfg(FALSE)] //~ NOTE the item is gated here
3232 pub fn y() {}
3333 //~^ NOTE found an item that was configured out
3434}
tests/ui/cfg/diagnostics-reexport.stderr+20
......@@ -9,6 +9,11 @@ note: found an item that was configured out
99 |
1010LL | pub fn x() {}
1111 | ^
12note: the item is gated here
13 --> $DIR/diagnostics-reexport.rs:17:5
14 |
15LL | #[cfg(FALSE)]
16 | ^^^^^^^^^^^^^
1217
1318error[E0432]: unresolved imports `b::x`, `b::y`
1419 --> $DIR/diagnostics-reexport.rs:22:13
......@@ -23,11 +28,21 @@ note: found an item that was configured out
2328 |
2429LL | pub fn x() {}
2530 | ^
31note: the item is gated here
32 --> $DIR/diagnostics-reexport.rs:28:5
33 |
34LL | #[cfg(FALSE)]
35 | ^^^^^^^^^^^^^
2636note: found an item that was configured out
2737 --> $DIR/diagnostics-reexport.rs:32:12
2838 |
2939LL | pub fn y() {}
3040 | ^
41note: the item is gated here
42 --> $DIR/diagnostics-reexport.rs:31:5
43 |
44LL | #[cfg(FALSE)]
45 | ^^^^^^^^^^^^^
3146
3247error[E0425]: cannot find function `uwu` in module `inner`
3348 --> $DIR/diagnostics-reexport.rs:38:12
......@@ -40,6 +55,11 @@ note: found an item that was configured out
4055 |
4156LL | pub use super::uwu;
4257 | ^^^
58note: the item is gated here
59 --> $DIR/diagnostics-reexport.rs:7:5
60 |
61LL | #[cfg(FALSE)]
62 | ^^^^^^^^^^^^^
4363
4464error: aborting due to 3 previous errors
4565
tests/ui/cfg/diagnostics-same-crate.rs+5-4
......@@ -1,11 +1,13 @@
11#![allow(unexpected_cfgs)] // since we want to recognize them as unexpected
22
33pub mod inner {
4 #[cfg(FALSE)]
4 #[cfg(FALSE)] //~ NOTE the item is gated here
55 pub fn uwu() {}
66 //~^ NOTE found an item that was configured out
77
8 #[cfg(FALSE)]
8 #[cfg(FALSE)] //~ NOTE the item is gated here
9 //~^ NOTE the item is gated here
10 //~| NOTE the item is gated here
911 pub mod doesnt_exist {
1012 //~^ NOTE found an item that was configured out
1113 //~| NOTE found an item that was configured out
......@@ -20,7 +22,7 @@ pub mod inner {
2022 }
2123
2224 pub mod right {
23 #[cfg(feature = "what-a-cool-feature")]
25 #[cfg(feature = "what-a-cool-feature")] //~ NOTE the item is gated behind the `what-a-cool-feature` feature
2426 pub fn meow() {}
2527 //~^ NOTE found an item that was configured out
2628 }
......@@ -55,7 +57,6 @@ fn main() {
5557 // It should find the one in the right module, not the wrong one.
5658 inner::right::meow(); //~ ERROR cannot find function
5759 //~| NOTE not found in `inner::right
58 //~| NOTE the item is gated behind the `what-a-cool-feature` feature
5960
6061 // Exists in the crate root - we would generally want a diagnostic,
6162 // but currently don't have one.
tests/ui/cfg/diagnostics-same-crate.stderr+36-12
......@@ -1,41 +1,56 @@
11error[E0432]: unresolved import `super::inner::doesnt_exist`
2 --> $DIR/diagnostics-same-crate.rs:30:9
2 --> $DIR/diagnostics-same-crate.rs:32:9
33 |
44LL | use super::inner::doesnt_exist;
55 | ^^^^^^^^^^^^^^^^^^^^^^^^^^ no `doesnt_exist` in `inner`
66 |
77note: found an item that was configured out
8 --> $DIR/diagnostics-same-crate.rs:9:13
8 --> $DIR/diagnostics-same-crate.rs:11:13
99 |
1010LL | pub mod doesnt_exist {
1111 | ^^^^^^^^^^^^
12note: the item is gated here
13 --> $DIR/diagnostics-same-crate.rs:8:5
14 |
15LL | #[cfg(FALSE)]
16 | ^^^^^^^^^^^^^
1217
1318error[E0432]: unresolved import `super::inner::doesnt_exist`
14 --> $DIR/diagnostics-same-crate.rs:33:23
19 --> $DIR/diagnostics-same-crate.rs:35:23
1520 |
1621LL | use super::inner::doesnt_exist::hi;
1722 | ^^^^^^^^^^^^ could not find `doesnt_exist` in `inner`
1823 |
1924note: found an item that was configured out
20 --> $DIR/diagnostics-same-crate.rs:9:13
25 --> $DIR/diagnostics-same-crate.rs:11:13
2126 |
2227LL | pub mod doesnt_exist {
2328 | ^^^^^^^^^^^^
29note: the item is gated here
30 --> $DIR/diagnostics-same-crate.rs:8:5
31 |
32LL | #[cfg(FALSE)]
33 | ^^^^^^^^^^^^^
2434
2535error[E0433]: failed to resolve: could not find `doesnt_exist` in `inner`
26 --> $DIR/diagnostics-same-crate.rs:52:12
36 --> $DIR/diagnostics-same-crate.rs:54:12
2737 |
2838LL | inner::doesnt_exist::hello();
2939 | ^^^^^^^^^^^^ could not find `doesnt_exist` in `inner`
3040 |
3141note: found an item that was configured out
32 --> $DIR/diagnostics-same-crate.rs:9:13
42 --> $DIR/diagnostics-same-crate.rs:11:13
3343 |
3444LL | pub mod doesnt_exist {
3545 | ^^^^^^^^^^^^
46note: the item is gated here
47 --> $DIR/diagnostics-same-crate.rs:8:5
48 |
49LL | #[cfg(FALSE)]
50 | ^^^^^^^^^^^^^
3651
3752error[E0425]: cannot find function `uwu` in module `inner`
38 --> $DIR/diagnostics-same-crate.rs:47:12
53 --> $DIR/diagnostics-same-crate.rs:49:12
3954 |
4055LL | inner::uwu();
4156 | ^^^ not found in `inner`
......@@ -45,28 +60,37 @@ note: found an item that was configured out
4560 |
4661LL | pub fn uwu() {}
4762 | ^^^
63note: the item is gated here
64 --> $DIR/diagnostics-same-crate.rs:4:5
65 |
66LL | #[cfg(FALSE)]
67 | ^^^^^^^^^^^^^
4868
4969error[E0425]: cannot find function `meow` in module `inner::right`
50 --> $DIR/diagnostics-same-crate.rs:56:19
70 --> $DIR/diagnostics-same-crate.rs:58:19
5171 |
5272LL | inner::right::meow();
5373 | ^^^^ not found in `inner::right`
5474 |
5575note: found an item that was configured out
56 --> $DIR/diagnostics-same-crate.rs:24:16
76 --> $DIR/diagnostics-same-crate.rs:26:16
5777 |
5878LL | pub fn meow() {}
5979 | ^^^^
60 = note: the item is gated behind the `what-a-cool-feature` feature
80note: the item is gated behind the `what-a-cool-feature` feature
81 --> $DIR/diagnostics-same-crate.rs:25:15
82 |
83LL | #[cfg(feature = "what-a-cool-feature")]
84 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6185
6286error[E0425]: cannot find function `uwu` in this scope
63 --> $DIR/diagnostics-same-crate.rs:43:5
87 --> $DIR/diagnostics-same-crate.rs:45:5
6488 |
6589LL | uwu();
6690 | ^^^ not found in this scope
6791
6892error[E0425]: cannot find function `vanished` in this scope
69 --> $DIR/diagnostics-same-crate.rs:63:5
93 --> $DIR/diagnostics-same-crate.rs:64:5
7094 |
7195LL | vanished();
7296 | ^^^^^^^^ not found in this scope
tests/ui/macros/builtin-std-paths-fail.stderr+2
......@@ -104,6 +104,8 @@ LL | #[std::test]
104104 |
105105note: found an item that was configured out
106106 --> $SRC_DIR/std/src/lib.rs:LL:COL
107note: the item is gated here
108 --> $SRC_DIR/std/src/lib.rs:LL:COL
107109
108110error: aborting due to 16 previous errors
109111
tests/ui/macros/macro-outer-attributes.stderr+11
......@@ -9,6 +9,17 @@ note: found an item that was configured out
99 |
1010LL | pub fn bar() { });
1111 | ^^^
12note: the item is gated here
13 --> $DIR/macro-outer-attributes.rs:5:45
14 |
15LL | $i:item) => (mod $nm { #[$a] $i }); }
16 | ^^^^^
17LL |
18LL | / test!(a,
19LL | | #[cfg(FALSE)],
20LL | | pub fn bar() { });
21 | |_______________________- in this macro invocation
22 = note: this error originates in the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info)
1223help: consider importing this function
1324 |
1425LL + use b::bar;
tests/ui/parser/issues/misplaced-return-type-complex-type-issue-126311.rs created+5
......@@ -0,0 +1,5 @@
1fn foo<T>() where T: Default -> impl Default + 'static {}
2//~^ ERROR return type should be specified after the function parameters
3//~| HELP place the return type after the function parameters
4
5fn main() {}
tests/ui/parser/issues/misplaced-return-type-complex-type-issue-126311.stderr created+14
......@@ -0,0 +1,14 @@
1error: return type should be specified after the function parameters
2 --> $DIR/misplaced-return-type-complex-type-issue-126311.rs:1:30
3 |
4LL | fn foo<T>() where T: Default -> impl Default + 'static {}
5 | ^^ expected one of `(`, `+`, `,`, `::`, `<`, or `{`
6 |
7help: place the return type after the function parameters
8 |
9LL - fn foo<T>() where T: Default -> impl Default + 'static {}
10LL + fn foo<T>() -> impl Default + 'static where T: Default {}
11 |
12
13error: aborting due to 1 previous error
14
tests/ui/parser/issues/misplaced-return-type-issue-126311.rs created+5
......@@ -0,0 +1,5 @@
1fn foo<T>() where T: Default -> u8 {}
2//~^ ERROR return type should be specified after the function parameters
3//~| HELP place the return type after the function parameters
4
5fn main() {}
tests/ui/parser/issues/misplaced-return-type-issue-126311.stderr created+14
......@@ -0,0 +1,14 @@
1error: return type should be specified after the function parameters
2 --> $DIR/misplaced-return-type-issue-126311.rs:1:30
3 |
4LL | fn foo<T>() where T: Default -> u8 {}
5 | ^^ expected one of `(`, `+`, `,`, `::`, `<`, or `{`
6 |
7help: place the return type after the function parameters
8 |
9LL - fn foo<T>() where T: Default -> u8 {}
10LL + fn foo<T>() -> u8 where T: Default {}
11 |
12
13error: aborting due to 1 previous error
14
tests/ui/parser/issues/misplaced-return-type-where-in-next-line-issue-126311.rs created+11
......@@ -0,0 +1,11 @@
1fn foo<T, K>()
2//~^ HELP place the return type after the function parameters
3where
4 T: Default,
5 K: Clone, -> Result<u8, String>
6//~^ ERROR return type should be specified after the function parameters
7{
8 Ok(0)
9}
10
11fn main() {}
tests/ui/parser/issues/misplaced-return-type-where-in-next-line-issue-126311.stderr created+17
......@@ -0,0 +1,17 @@
1error: return type should be specified after the function parameters
2 --> $DIR/misplaced-return-type-where-in-next-line-issue-126311.rs:5:15
3 |
4LL | K: Clone, -> Result<u8, String>
5 | ^^ expected one of `{`, lifetime, or type
6 |
7help: place the return type after the function parameters
8 |
9LL ~ fn foo<T, K>() -> Result<u8, String>
10LL |
11LL | where
12LL | T: Default,
13LL ~ K: Clone,
14 |
15
16error: aborting due to 1 previous error
17
tests/ui/parser/issues/misplaced-return-type-without-type-issue-126311.rs created+6
......@@ -0,0 +1,6 @@
1fn foo<T>() where T: Default -> {
2//~^ ERROR expected one of `(`, `+`, `,`, `::`, `<`, or `{`, found `->`
3 0
4}
5
6fn main() {}
tests/ui/parser/issues/misplaced-return-type-without-type-issue-126311.stderr created+8
......@@ -0,0 +1,8 @@
1error: expected one of `(`, `+`, `,`, `::`, `<`, or `{`, found `->`
2 --> $DIR/misplaced-return-type-without-type-issue-126311.rs:1:30
3 |
4LL | fn foo<T>() where T: Default -> {
5 | ^^ expected one of `(`, `+`, `,`, `::`, `<`, or `{`
6
7error: aborting due to 1 previous error
8
tests/ui/parser/issues/misplaced-return-type-without-where-issue-126311.rs created+4
......@@ -0,0 +1,4 @@
1fn bar<T>() -> u8 -> u64 {}
2//~^ ERROR expected one of `!`, `(`, `+`, `::`, `<`, `where`, or `{`, found `->`
3
4fn main() {}
tests/ui/parser/issues/misplaced-return-type-without-where-issue-126311.stderr created+8
......@@ -0,0 +1,8 @@
1error: expected one of `!`, `(`, `+`, `::`, `<`, `where`, or `{`, found `->`
2 --> $DIR/misplaced-return-type-without-where-issue-126311.rs:1:19
3 |
4LL | fn bar<T>() -> u8 -> u64 {}
5 | ^^ expected one of 7 possible tokens
6
7error: aborting due to 1 previous error
8
tests/ui/rust-2024/safe-outside-extern.gated.stderr+7-1
......@@ -28,5 +28,11 @@ error: function pointers cannot be declared with `safe` safety qualifier
2828LL | type FnPtr = safe fn(i32, i32) -> i32;
2929 | ^^^^^^^^^^^^^^^^^^^^^^^^
3030
31error: aborting due to 5 previous errors
31error: static items cannot be declared with `unsafe` safety qualifier outside of `extern` block
32 --> $DIR/safe-outside-extern.rs:28:1
33 |
34LL | unsafe static LOL: u8 = 0;
35 | ^^^^^^^^^^^^^^^^^^^^^^^^^^
36
37error: aborting due to 6 previous errors
3238
tests/ui/rust-2024/safe-outside-extern.rs+3
......@@ -25,4 +25,7 @@ type FnPtr = safe fn(i32, i32) -> i32;
2525//~^ ERROR: function pointers cannot be declared with `safe` safety qualifier
2626//[ungated]~| ERROR: unsafe extern {}` blocks and `safe` keyword are experimental [E0658]
2727
28unsafe static LOL: u8 = 0;
29//~^ ERROR: static items cannot be declared with `unsafe` safety qualifier outside of `extern` block
30
2831fn main() {}
tests/ui/rust-2024/safe-outside-extern.ungated.stderr+7-1
......@@ -28,6 +28,12 @@ error: function pointers cannot be declared with `safe` safety qualifier
2828LL | type FnPtr = safe fn(i32, i32) -> i32;
2929 | ^^^^^^^^^^^^^^^^^^^^^^^^
3030
31error: static items cannot be declared with `unsafe` safety qualifier outside of `extern` block
32 --> $DIR/safe-outside-extern.rs:28:1
33 |
34LL | unsafe static LOL: u8 = 0;
35 | ^^^^^^^^^^^^^^^^^^^^^^^^^^
36
3137error[E0658]: `unsafe extern {}` blocks and `safe` keyword are experimental
3238 --> $DIR/safe-outside-extern.rs:4:1
3339 |
......@@ -78,6 +84,6 @@ LL | type FnPtr = safe fn(i32, i32) -> i32;
7884 = help: add `#![feature(unsafe_extern_blocks)]` to the crate attributes to enable
7985 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
8086
81error: aborting due to 10 previous errors
87error: aborting due to 11 previous errors
8288
8389For more information about this error, try `rustc --explain E0658`.