| author | bors <bors@rust-lang.org> 2024-07-19 13:39:12 UTC |
| committer | bors <bors@rust-lang.org> 2024-07-19 13:39:12 UTC |
| log | 3811f40d2701b3a8923d2d46e36dd3a93a824b49 |
| tree | c4dd3eced80c90cb45e2eb3dbb4f56a5160a5155 |
| parent | 11e57241f166194a328438d9264b68c98a18d51f |
| parent | 6fe68f88e72fd0b813dc39345d7a5e2a291c1e7c |
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: rollup50 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 |
| 269 | 269 | .negative = negative because of this |
| 270 | 270 | .unsafe = unsafe because of this |
| 271 | 271 | |
| 272 | ast_passes_unsafe_static = | |
| 273 | static items cannot be declared with `unsafe` safety qualifier outside of `extern` block | |
| 274 | ||
| 272 | 275 | ast_passes_visibility_not_permitted = |
| 273 | 276 | visibility qualifiers are not permitted here |
| 274 | 277 | .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> { |
| 438 | 438 | } |
| 439 | 439 | } |
| 440 | 440 | |
| 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. | |
| 441 | 446 | fn check_item_safety(&self, span: Span, safety: Safety) { |
| 442 | 447 | match self.extern_mod_safety { |
| 443 | 448 | Some(extern_safety) => { |
| ... | ... | @@ -1177,6 +1182,9 @@ impl<'a> Visitor<'a> for AstValidator<'a> { |
| 1177 | 1182 | } |
| 1178 | 1183 | ItemKind::Static(box StaticItem { expr, safety, .. }) => { |
| 1179 | 1184 | self.check_item_safety(item.span, *safety); |
| 1185 | if matches!(safety, Safety::Unsafe(_)) { | |
| 1186 | self.dcx().emit_err(errors::UnsafeStatic { span: item.span }); | |
| 1187 | } | |
| 1180 | 1188 | |
| 1181 | 1189 | if expr.is_none() { |
| 1182 | 1190 | self.dcx().emit_err(errors::StaticWithoutBody { |
compiler/rustc_ast_passes/src/errors.rs+7| ... | ... | @@ -224,6 +224,13 @@ pub struct InvalidSafetyOnBareFn { |
| 224 | 224 | pub span: Span, |
| 225 | 225 | } |
| 226 | 226 | |
| 227 | #[derive(Diagnostic)] | |
| 228 | #[diag(ast_passes_unsafe_static)] | |
| 229 | pub struct UnsafeStatic { | |
| 230 | #[primary_span] | |
| 231 | pub span: Span, | |
| 232 | } | |
| 233 | ||
| 227 | 234 | #[derive(Diagnostic)] |
| 228 | 235 | #[diag(ast_passes_bound_in_context)] |
| 229 | 236 | pub struct BoundInContext<'a> { |
compiler/rustc_builtin_macros/src/cmdline_attrs.rs+9-7| ... | ... | @@ -4,6 +4,7 @@ use crate::errors; |
| 4 | 4 | use rustc_ast::attr::mk_attr; |
| 5 | 5 | use rustc_ast::token; |
| 6 | 6 | use rustc_ast::{self as ast, AttrItem, AttrStyle}; |
| 7 | use rustc_parse::parser::ForceCollect; | |
| 7 | 8 | use rustc_parse::{new_parser_from_source_str, unwrap_or_emit_fatal}; |
| 8 | 9 | use rustc_session::parse::ParseSess; |
| 9 | 10 | use rustc_span::FileName; |
| ... | ... | @@ -17,13 +18,14 @@ pub fn inject(krate: &mut ast::Crate, psess: &ParseSess, attrs: &[String]) { |
| 17 | 18 | )); |
| 18 | 19 | |
| 19 | 20 | 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 | }; | |
| 27 | 29 | let end_span = parser.token.span; |
| 28 | 30 | if parser.token != token::Eof { |
| 29 | 31 | 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} |
| 524 | 524 | .label_opening_candidate = closing delimiter possibly meant for this |
| 525 | 525 | .label_unclosed = unclosed delimiter |
| 526 | 526 | |
| 527 | parse_misplaced_return_type = place the return type after the function parameters | |
| 528 | ||
| 527 | 529 | parse_missing_comma_after_match_arm = expected `,` following `match` arm |
| 528 | 530 | .suggestion = missing a comma here to end this `match` arm |
| 529 | 531 |
compiler/rustc_parse/src/errors.rs+15-7| ... | ... | @@ -1502,6 +1502,20 @@ pub(crate) struct FnPtrWithGenerics { |
| 1502 | 1502 | pub sugg: Option<FnPtrWithGenericsSugg>, |
| 1503 | 1503 | } |
| 1504 | 1504 | |
| 1505 | #[derive(Subdiagnostic)] | |
| 1506 | #[multipart_suggestion( | |
| 1507 | parse_misplaced_return_type, | |
| 1508 | style = "verbose", | |
| 1509 | applicability = "maybe-incorrect" | |
| 1510 | )] | |
| 1511 | pub(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 | ||
| 1505 | 1519 | #[derive(Subdiagnostic)] |
| 1506 | 1520 | #[multipart_suggestion(parse_suggestion, applicability = "maybe-incorrect")] |
| 1507 | 1521 | pub(crate) struct FnPtrWithGenericsSugg { |
| ... | ... | @@ -1516,7 +1530,6 @@ pub(crate) struct FnPtrWithGenericsSugg { |
| 1516 | 1530 | |
| 1517 | 1531 | pub(crate) struct FnTraitMissingParen { |
| 1518 | 1532 | pub span: Span, |
| 1519 | pub machine_applicable: bool, | |
| 1520 | 1533 | } |
| 1521 | 1534 | |
| 1522 | 1535 | impl Subdiagnostic for FnTraitMissingParen { |
| ... | ... | @@ -1526,16 +1539,11 @@ impl Subdiagnostic for FnTraitMissingParen { |
| 1526 | 1539 | _: &F, |
| 1527 | 1540 | ) { |
| 1528 | 1541 | 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 | }; | |
| 1534 | 1542 | diag.span_suggestion_short( |
| 1535 | 1543 | self.span.shrink_to_hi(), |
| 1536 | 1544 | crate::fluent_generated::parse_add_paren, |
| 1537 | 1545 | "()", |
| 1538 | applicability, | |
| 1546 | Applicability::MachineApplicable, | |
| 1539 | 1547 | ); |
| 1540 | 1548 | } |
| 1541 | 1549 | } |
compiler/rustc_parse/src/parser/attr.rs+7-8| ... | ... | @@ -124,7 +124,7 @@ impl<'a> Parser<'a> { |
| 124 | 124 | if this.eat(&token::Not) { ast::AttrStyle::Inner } else { ast::AttrStyle::Outer }; |
| 125 | 125 | |
| 126 | 126 | this.expect(&token::OpenDelim(Delimiter::Bracket))?; |
| 127 | let item = this.parse_attr_item(false)?; | |
| 127 | let item = this.parse_attr_item(ForceCollect::No)?; | |
| 128 | 128 | this.expect(&token::CloseDelim(Delimiter::Bracket))?; |
| 129 | 129 | let attr_sp = lo.to(this.prev_token.span); |
| 130 | 130 | |
| ... | ... | @@ -248,16 +248,15 @@ impl<'a> Parser<'a> { |
| 248 | 248 | /// PATH |
| 249 | 249 | /// PATH `=` UNSUFFIXED_LIT |
| 250 | 250 | /// 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> { | |
| 252 | 252 | maybe_whole!(self, NtMeta, |attr| attr.into_inner()); |
| 253 | 253 | |
| 254 | let do_parse = |this: &mut Self| { | |
| 254 | let do_parse = |this: &mut Self, _empty_attrs| { | |
| 255 | 255 | let is_unsafe = this.eat_keyword(kw::Unsafe); |
| 256 | 256 | let unsafety = if is_unsafe { |
| 257 | 257 | let unsafe_span = this.prev_token.span; |
| 258 | 258 | this.psess.gated_spans.gate(sym::unsafe_attributes, unsafe_span); |
| 259 | 259 | this.expect(&token::OpenDelim(Delimiter::Parenthesis))?; |
| 260 | ||
| 261 | 260 | ast::Safety::Unsafe(unsafe_span) |
| 262 | 261 | } else { |
| 263 | 262 | ast::Safety::Default |
| ... | ... | @@ -268,10 +267,10 @@ impl<'a> Parser<'a> { |
| 268 | 267 | if is_unsafe { |
| 269 | 268 | this.expect(&token::CloseDelim(Delimiter::Parenthesis))?; |
| 270 | 269 | } |
| 271 | Ok(ast::AttrItem { unsafety, path, args, tokens: None }) | |
| 270 | Ok((ast::AttrItem { unsafety, path, args, tokens: None }, false)) | |
| 272 | 271 | }; |
| 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) | |
| 275 | 274 | } |
| 276 | 275 | |
| 277 | 276 | /// Parses attributes that appear after the opening of an item. These should |
| ... | ... | @@ -340,7 +339,7 @@ impl<'a> Parser<'a> { |
| 340 | 339 | let mut expanded_attrs = Vec::with_capacity(1); |
| 341 | 340 | while self.token.kind != token::Eof { |
| 342 | 341 | let lo = self.token.span; |
| 343 | let item = self.parse_attr_item(true)?; | |
| 342 | let item = self.parse_attr_item(ForceCollect::Yes)?; | |
| 344 | 343 | expanded_attrs.push((item, lo.to(self.prev_token.span))); |
| 345 | 344 | if !self.eat(&token::Comma) { |
| 346 | 345 | break; |
compiler/rustc_parse/src/parser/diagnostics.rs+4-4| ... | ... | @@ -430,7 +430,7 @@ impl<'a> Parser<'a> { |
| 430 | 430 | &mut self, |
| 431 | 431 | edible: &[TokenKind], |
| 432 | 432 | inedible: &[TokenKind], |
| 433 | ) -> PResult<'a, Recovered> { | |
| 433 | ) -> PResult<'a, ErrorGuaranteed> { | |
| 434 | 434 | debug!("expected_one_of_not_found(edible: {:?}, inedible: {:?})", edible, inedible); |
| 435 | 435 | fn tokens_to_string(tokens: &[TokenType]) -> String { |
| 436 | 436 | let mut i = tokens.iter(); |
| ... | ... | @@ -533,7 +533,7 @@ impl<'a> Parser<'a> { |
| 533 | 533 | sugg: ExpectedSemiSugg::ChangeToSemi(self.token.span), |
| 534 | 534 | }); |
| 535 | 535 | self.bump(); |
| 536 | return Ok(Recovered::Yes(guar)); | |
| 536 | return Ok(guar); | |
| 537 | 537 | } else if self.look_ahead(0, |t| { |
| 538 | 538 | t == &token::CloseDelim(Delimiter::Brace) |
| 539 | 539 | || ((t.can_begin_expr() || t.can_begin_item()) |
| ... | ... | @@ -557,7 +557,7 @@ impl<'a> Parser<'a> { |
| 557 | 557 | unexpected_token_label: Some(self.token.span), |
| 558 | 558 | sugg: ExpectedSemiSugg::AddSemi(span), |
| 559 | 559 | }); |
| 560 | return Ok(Recovered::Yes(guar)); | |
| 560 | return Ok(guar); | |
| 561 | 561 | } |
| 562 | 562 | } |
| 563 | 563 | |
| ... | ... | @@ -712,7 +712,7 @@ impl<'a> Parser<'a> { |
| 712 | 712 | if self.check_too_many_raw_str_terminators(&mut err) { |
| 713 | 713 | if expected.contains(&TokenType::Token(token::Semi)) && self.eat(&token::Semi) { |
| 714 | 714 | let guar = err.emit(); |
| 715 | return Ok(Recovered::Yes(guar)); | |
| 715 | return Ok(guar); | |
| 716 | 716 | } else { |
| 717 | 717 | return Err(err); |
| 718 | 718 | } |
compiler/rustc_parse/src/parser/item.rs+96-28| ... | ... | @@ -17,6 +17,7 @@ use rustc_span::edit_distance::edit_distance; |
| 17 | 17 | use rustc_span::edition::Edition; |
| 18 | 18 | use rustc_span::source_map; |
| 19 | 19 | use rustc_span::symbol::{kw, sym, Ident, Symbol}; |
| 20 | use rustc_span::ErrorGuaranteed; | |
| 20 | 21 | use rustc_span::{Span, DUMMY_SP}; |
| 21 | 22 | use std::fmt::Write; |
| 22 | 23 | use std::mem; |
| ... | ... | @@ -2332,14 +2333,106 @@ impl<'a> Parser<'a> { |
| 2332 | 2333 | } |
| 2333 | 2334 | } |
| 2334 | 2335 | }; |
| 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 | ||
| 2335 | 2341 | generics.where_clause = self.parse_where_clause()?; // `where T: Ord` |
| 2336 | 2342 | |
| 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 | ||
| 2337 | 2347 | 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)?; | |
| 2339 | 2351 | let fn_sig_span = sig_lo.to(sig_hi); |
| 2340 | 2352 | Ok((ident, FnSig { header, decl, span: fn_sig_span }, generics, body)) |
| 2341 | 2353 | } |
| 2342 | 2354 | |
| 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 | ||
| 2343 | 2436 | /// Parse the "body" of a function. |
| 2344 | 2437 | /// This can either be `;` when there's no body, |
| 2345 | 2438 | /// or e.g. a block when the function is a provided one. |
| ... | ... | @@ -2349,6 +2442,7 @@ impl<'a> Parser<'a> { |
| 2349 | 2442 | ident: &Ident, |
| 2350 | 2443 | sig_hi: &mut Span, |
| 2351 | 2444 | req_body: bool, |
| 2445 | fn_params_end: Option<Span>, | |
| 2352 | 2446 | ) -> PResult<'a, Option<P<Block>>> { |
| 2353 | 2447 | let has_semi = if req_body { |
| 2354 | 2448 | self.token.kind == TokenKind::Semi |
| ... | ... | @@ -2377,33 +2471,7 @@ impl<'a> Parser<'a> { |
| 2377 | 2471 | }); |
| 2378 | 2472 | (AttrVec::new(), Some(self.mk_block_err(span, guar))) |
| 2379 | 2473 | } 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)?; | |
| 2407 | 2475 | (AttrVec::new(), None) |
| 2408 | 2476 | }; |
| 2409 | 2477 | attrs.extend(inner_attrs); |
compiler/rustc_parse/src/parser/mod.rs+5-5| ... | ... | @@ -501,6 +501,7 @@ impl<'a> Parser<'a> { |
| 501 | 501 | FatalError.raise(); |
| 502 | 502 | } else { |
| 503 | 503 | self.expected_one_of_not_found(edible, inedible) |
| 504 | .map(|error_guaranteed| Recovered::Yes(error_guaranteed)) | |
| 504 | 505 | } |
| 505 | 506 | } |
| 506 | 507 | |
| ... | ... | @@ -948,11 +949,10 @@ impl<'a> Parser<'a> { |
| 948 | 949 | let initial_semicolon = self.token.span; |
| 949 | 950 | |
| 950 | 951 | 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 | }); | |
| 956 | 956 | } |
| 957 | 957 | |
| 958 | 958 | expect_err |
compiler/rustc_parse/src/parser/nonterminal.rs+1-1| ... | ... | @@ -171,7 +171,7 @@ impl<'a> Parser<'a> { |
| 171 | 171 | NonterminalKind::Path => { |
| 172 | 172 | NtPath(P(self.collect_tokens_no_attrs(|this| this.parse_path(PathStyle::Type))?)) |
| 173 | 173 | } |
| 174 | NonterminalKind::Meta => NtMeta(P(self.parse_attr_item(true)?)), | |
| 174 | NonterminalKind::Meta => NtMeta(P(self.parse_attr_item(ForceCollect::Yes)?)), | |
| 175 | 175 | NonterminalKind::Vis => { |
| 176 | 176 | NtVis(P(self |
| 177 | 177 | .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> { |
| 72 | 72 | lo, |
| 73 | 73 | attrs, |
| 74 | 74 | errors::InvalidVariableDeclarationSub::MissingLet, |
| 75 | force_collect, | |
| 75 | 76 | )? |
| 76 | 77 | } else if self.is_kw_followed_by_ident(kw::Auto) && self.may_recover() { |
| 77 | 78 | self.bump(); // `auto` |
| ... | ... | @@ -79,6 +80,7 @@ impl<'a> Parser<'a> { |
| 79 | 80 | lo, |
| 80 | 81 | attrs, |
| 81 | 82 | errors::InvalidVariableDeclarationSub::UseLetNotAuto, |
| 83 | force_collect, | |
| 82 | 84 | )? |
| 83 | 85 | } else if self.is_kw_followed_by_ident(sym::var) && self.may_recover() { |
| 84 | 86 | self.bump(); // `var` |
| ... | ... | @@ -86,6 +88,7 @@ impl<'a> Parser<'a> { |
| 86 | 88 | lo, |
| 87 | 89 | attrs, |
| 88 | 90 | errors::InvalidVariableDeclarationSub::UseLetNotVar, |
| 91 | force_collect, | |
| 89 | 92 | )? |
| 90 | 93 | } else if self.check_path() |
| 91 | 94 | && !self.token.is_qpath_start() |
| ... | ... | @@ -96,17 +99,17 @@ impl<'a> Parser<'a> { |
| 96 | 99 | // or `auto trait` items. We aim to parse an arbitrary path `a::b` but not something |
| 97 | 100 | // that starts like a path (1 token), but it fact not a path. |
| 98 | 101 | // 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); | |
| 102 | 112 | } |
| 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 | }, | |
| 110 | 113 | } |
| 111 | 114 | } else if let Some(item) = self.parse_item_common( |
| 112 | 115 | attrs.clone(), |
| ... | ... | @@ -123,12 +126,13 @@ impl<'a> Parser<'a> { |
| 123 | 126 | self.mk_stmt(lo, StmtKind::Empty) |
| 124 | 127 | } else if self.token != token::CloseDelim(Delimiter::Brace) { |
| 125 | 128 | // 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 | )?; | |
| 132 | 136 | if matches!(e.kind, ExprKind::Assign(..)) && self.eat_keyword(kw::Else) { |
| 133 | 137 | let bl = self.parse_block()?; |
| 134 | 138 | // Destructuring assignment ... else. |
| ... | ... | @@ -231,13 +235,13 @@ impl<'a> Parser<'a> { |
| 231 | 235 | lo: Span, |
| 232 | 236 | attrs: AttrWrapper, |
| 233 | 237 | subdiagnostic: fn(Span) -> errors::InvalidVariableDeclarationSub, |
| 238 | force_collect: ForceCollect, | |
| 234 | 239 | ) -> 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 | })?; | |
| 241 | 245 | self.dcx() |
| 242 | 246 | .emit_err(errors::InvalidVariableDeclaration { span: lo, sub: subdiagnostic(lo) }); |
| 243 | 247 | Ok(stmt) |
compiler/rustc_parse/src/parser/ty.rs+5| ... | ... | @@ -21,6 +21,11 @@ use rustc_span::symbol::{kw, sym, Ident}; |
| 21 | 21 | use rustc_span::{ErrorGuaranteed, Span, Symbol}; |
| 22 | 22 | use thin_vec::{thin_vec, ThinVec}; |
| 23 | 23 | |
| 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 | |
| 24 | 29 | #[derive(Copy, Clone, PartialEq)] |
| 25 | 30 | pub(super) enum AllowPlus { |
| 26 | 31 | Yes, |
compiler/rustc_resolve/messages.ftl+2| ... | ... | @@ -232,6 +232,8 @@ resolve_is_private = |
| 232 | 232 | resolve_item_was_behind_feature = |
| 233 | 233 | the item is gated behind the `{$feature}` feature |
| 234 | 234 | |
| 235 | resolve_item_was_cfg_out = the item is gated here | |
| 236 | ||
| 235 | 237 | resolve_items_in_traits_are_not_importable = |
| 236 | 238 | items in traits are not importable |
| 237 | 239 |
compiler/rustc_resolve/src/diagnostics.rs+7-1| ... | ... | @@ -2532,7 +2532,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { |
| 2532 | 2532 | && let NestedMetaItem::MetaItem(meta_item) = &nested[0] |
| 2533 | 2533 | && let MetaItemKind::NameValue(feature_name) = &meta_item.kind |
| 2534 | 2534 | { |
| 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 }; | |
| 2536 | 2542 | err.subdiagnostic(note); |
| 2537 | 2543 | } |
| 2538 | 2544 | } |
compiler/rustc_resolve/src/errors.rs+9| ... | ... | @@ -1228,6 +1228,15 @@ pub(crate) struct FoundItemConfigureOut { |
| 1228 | 1228 | #[note(resolve_item_was_behind_feature)] |
| 1229 | 1229 | pub(crate) struct ItemWasBehindFeature { |
| 1230 | 1230 | pub(crate) feature: Symbol, |
| 1231 | #[primary_span] | |
| 1232 | pub(crate) span: Span, | |
| 1233 | } | |
| 1234 | ||
| 1235 | #[derive(Subdiagnostic)] | |
| 1236 | #[note(resolve_item_was_cfg_out)] | |
| 1237 | pub(crate) struct ItemWasCfgOut { | |
| 1238 | #[primary_span] | |
| 1239 | pub(crate) span: Span, | |
| 1231 | 1240 | } |
| 1232 | 1241 | |
| 1233 | 1242 | #[derive(Diagnostic)] |
src/librustdoc/html/static/js/main.js+5-3| ... | ... | @@ -529,11 +529,13 @@ function preLoadCss(cssUrl) { |
| 529 | 529 | } |
| 530 | 530 | const link = document.createElement("a"); |
| 531 | 531 | link.href = path; |
| 532 | if (path === current_page) { | |
| 533 | link.className = "current"; | |
| 534 | } | |
| 535 | 532 | link.textContent = name; |
| 536 | 533 | 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 | } | |
| 537 | 539 | li.appendChild(link); |
| 538 | 540 | ul.appendChild(li); |
| 539 | 541 | } |
src/tools/tidy/src/allowed_run_make_makefiles.txt-2| ... | ... | @@ -37,8 +37,6 @@ run-make/interdependent-c-libraries/Makefile |
| 37 | 37 | run-make/issue-107094/Makefile |
| 38 | 38 | run-make/issue-14698/Makefile |
| 39 | 39 | run-make/issue-15460/Makefile |
| 40 | run-make/issue-22131/Makefile | |
| 41 | run-make/issue-26006/Makefile | |
| 42 | 40 | run-make/issue-28595/Makefile |
| 43 | 41 | run-make/issue-33329/Makefile |
| 44 | 42 | run-make/issue-35164/Makefile |
tests/run-make/invalid-symlink-search-path/in/bar/lib.rs created+5| ... | ... | @@ -0,0 +1,5 @@ |
| 1 | extern crate foo; | |
| 2 | ||
| 3 | pub 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 @@ |
| 1 | pub 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 | ||
| 10 | use run_make_support::{rfs, rustc}; | |
| 11 | ||
| 12 | fn 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 | |
| 2 | include ../tools.mk | |
| 3 | ||
| 4 | all: 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")] | |
| 5 | pub fn foo() -> i32 { | |
| 6 | 1 | |
| 7 | } |
tests/run-make/issue-26006/Makefile deleted-17| ... | ... | @@ -1,17 +0,0 @@ |
| 1 | # ignore-cross-compile | |
| 2 | include ../tools.mk | |
| 3 | ||
| 4 | # ignore-windows | |
| 5 | ||
| 6 | OUT := $(TMPDIR)/out | |
| 7 | ||
| 8 | all: time | |
| 9 | ||
| 10 | time: 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 | ||
| 15 | libc: | |
| 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 | ||
| 3 | pub fn something() {} |
tests/run-make/issue-26006/in/time/lib.rs deleted-4| ... | ... | @@ -1,4 +0,0 @@ |
| 1 | #![feature(rustc_private)] | |
| 2 | extern crate libc; | |
| 3 | ||
| 4 | fn 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")] | |
| 5 | pub 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 | ||
| 9 | use run_make_support::{cwd, rustc, rustdoc}; | |
| 10 | ||
| 11 | fn 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" |
| 72 | 72 | assert-count: (".sidebar .sidebar-crate", 1) |
| 73 | 73 | assert-count: (".sidebar .location", 1) |
| 74 | 74 | assert-count: (".sidebar h2", 3) |
| 75 | assert-text: (".sidebar-elems ul.block > li.current > a", "Foo") | |
| 75 | 76 | // We check that there is no crate listed outside of the top level. |
| 76 | 77 | assert-false: ".sidebar-elems > .crate" |
| 77 | 78 | |
| ... | ... | @@ -110,6 +111,7 @@ click: "#functions + .item-table .item-name > a" |
| 110 | 111 | assert-text: (".sidebar > .sidebar-crate > h2 > a", "lib2") |
| 111 | 112 | assert-count: (".sidebar .location", 0) |
| 112 | 113 | assert-count: (".sidebar h2", 1) |
| 114 | assert-text: (".sidebar-elems ul.block > li.current > a", "foobar") | |
| 113 | 115 | // We check that we don't have the crate list. |
| 114 | 116 | assert-false: ".sidebar-elems > .crate" |
| 115 | 117 | |
| ... | ... | @@ -118,6 +120,7 @@ assert-property: (".sidebar", {"clientWidth": "200"}) |
| 118 | 120 | assert-text: (".sidebar > .sidebar-crate > h2 > a", "lib2") |
| 119 | 121 | assert-text: (".sidebar > .location", "Module module") |
| 120 | 122 | assert-count: (".sidebar .location", 1) |
| 123 | assert-text: (".sidebar-elems ul.block > li.current > a", "module") | |
| 121 | 124 | // Module page requires three headings: |
| 122 | 125 | // - Presistent crate branding (name and version) |
| 123 | 126 | // - Module name, followed by TOC for module headings |
| ... | ... | @@ -138,6 +141,7 @@ assert-text: (".sidebar > .sidebar-elems > h2", "In lib2::module::sub_module") |
| 138 | 141 | assert-property: (".sidebar > .sidebar-elems > h2 > a", { |
| 139 | 142 | "href": "/module/sub_module/index.html", |
| 140 | 143 | }, ENDS_WITH) |
| 144 | assert-text: (".sidebar-elems ul.block > li.current > a", "sub_sub_module") | |
| 141 | 145 | // We check that we don't have the crate list. |
| 142 | 146 | assert-false: ".sidebar-elems .crate" |
| 143 | 147 | assert-text: (".sidebar-elems > section ul > li:nth-child(1)", "Functions") |
tests/ui/cfg/diagnostics-cross-crate.rs+3| ... | ... | @@ -11,12 +11,14 @@ fn main() { |
| 11 | 11 | cfged_out::inner::uwu(); //~ ERROR cannot find function |
| 12 | 12 | //~^ NOTE found an item that was configured out |
| 13 | 13 | //~| NOTE not found in `cfged_out::inner` |
| 14 | //~| NOTE the item is gated here | |
| 14 | 15 | |
| 15 | 16 | // The module isn't found - we would like to get a diagnostic, but currently don't due to |
| 16 | 17 | // the awkward way the resolver diagnostics are currently implemented. |
| 17 | 18 | cfged_out::inner::doesnt_exist::hello(); //~ ERROR failed to resolve |
| 18 | 19 | //~^ NOTE could not find `doesnt_exist` in `inner` |
| 19 | 20 | //~| NOTE found an item that was configured out |
| 21 | //~| NOTE the item is gated here | |
| 20 | 22 | |
| 21 | 23 | // It should find the one in the right module, not the wrong one. |
| 22 | 24 | cfged_out::inner::right::meow(); //~ ERROR cannot find function |
| ... | ... | @@ -28,4 +30,5 @@ fn main() { |
| 28 | 30 | cfged_out::vanished(); //~ ERROR cannot find function |
| 29 | 31 | //~^ NOTE found an item that was configured out |
| 30 | 32 | //~| NOTE not found in `cfged_out` |
| 33 | //~| NOTE the item is gated here | |
| 31 | 34 | } |
tests/ui/cfg/diagnostics-cross-crate.stderr+23-4| ... | ... | @@ -1,5 +1,5 @@ |
| 1 | 1 | error[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 | |
| 3 | 3 | | |
| 4 | 4 | LL | cfged_out::inner::doesnt_exist::hello(); |
| 5 | 5 | | ^^^^^^^^^^^^ could not find `doesnt_exist` in `inner` |
| ... | ... | @@ -9,6 +9,11 @@ note: found an item that was configured out |
| 9 | 9 | | |
| 10 | 10 | LL | pub mod doesnt_exist { |
| 11 | 11 | | ^^^^^^^^^^^^ |
| 12 | note: the item is gated here | |
| 13 | --> $DIR/auxiliary/cfged_out.rs:5:5 | |
| 14 | | | |
| 15 | LL | #[cfg(FALSE)] | |
| 16 | | ^^^^^^^^^^^^^ | |
| 12 | 17 | |
| 13 | 18 | error[E0425]: cannot find function `uwu` in crate `cfged_out` |
| 14 | 19 | --> $DIR/diagnostics-cross-crate.rs:7:16 |
| ... | ... | @@ -27,9 +32,14 @@ note: found an item that was configured out |
| 27 | 32 | | |
| 28 | 33 | LL | pub fn uwu() {} |
| 29 | 34 | | ^^^ |
| 35 | note: the item is gated here | |
| 36 | --> $DIR/auxiliary/cfged_out.rs:2:5 | |
| 37 | | | |
| 38 | LL | #[cfg(FALSE)] | |
| 39 | | ^^^^^^^^^^^^^ | |
| 30 | 40 | |
| 31 | 41 | error[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 | |
| 33 | 43 | | |
| 34 | 44 | LL | cfged_out::inner::right::meow(); |
| 35 | 45 | | ^^^^ not found in `cfged_out::inner::right` |
| ... | ... | @@ -39,10 +49,14 @@ note: found an item that was configured out |
| 39 | 49 | | |
| 40 | 50 | LL | pub fn meow() {} |
| 41 | 51 | | ^^^^ |
| 42 | = note: the item is gated behind the `what-a-cool-feature` feature | |
| 52 | note: the item is gated behind the `what-a-cool-feature` feature | |
| 53 | --> $DIR/auxiliary/cfged_out.rs:16:15 | |
| 54 | | | |
| 55 | LL | #[cfg(feature = "what-a-cool-feature")] | |
| 56 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 43 | 57 | |
| 44 | 58 | error[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 | |
| 46 | 60 | | |
| 47 | 61 | LL | cfged_out::vanished(); |
| 48 | 62 | | ^^^^^^^^ not found in `cfged_out` |
| ... | ... | @@ -52,6 +66,11 @@ note: found an item that was configured out |
| 52 | 66 | | |
| 53 | 67 | LL | pub fn vanished() {} |
| 54 | 68 | | ^^^^^^^^ |
| 69 | note: the item is gated here | |
| 70 | --> $DIR/auxiliary/cfged_out.rs:21:1 | |
| 71 | | | |
| 72 | LL | #[cfg(i_dont_exist_and_you_can_do_nothing_about_it)] | |
| 73 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 55 | 74 | |
| 56 | 75 | error: aborting due to 5 previous errors |
| 57 | 76 |
tests/ui/cfg/diagnostics-reexport.rs+4-4| ... | ... | @@ -4,7 +4,7 @@ pub mod inner { |
| 4 | 4 | pub fn uwu() {} |
| 5 | 5 | } |
| 6 | 6 | |
| 7 | #[cfg(FALSE)] | |
| 7 | #[cfg(FALSE)] //~ NOTE the item is gated here | |
| 8 | 8 | pub use super::uwu; |
| 9 | 9 | //~^ NOTE found an item that was configured out |
| 10 | 10 | } |
| ... | ... | @@ -14,7 +14,7 @@ pub use a::x; |
| 14 | 14 | //~| NOTE no `x` in `a` |
| 15 | 15 | |
| 16 | 16 | mod a { |
| 17 | #[cfg(FALSE)] | |
| 17 | #[cfg(FALSE)] //~ NOTE the item is gated here | |
| 18 | 18 | pub fn x() {} |
| 19 | 19 | //~^ NOTE found an item that was configured out |
| 20 | 20 | } |
| ... | ... | @@ -25,10 +25,10 @@ pub use b::{x, y}; |
| 25 | 25 | //~| NOTE no `y` in `b` |
| 26 | 26 | |
| 27 | 27 | mod b { |
| 28 | #[cfg(FALSE)] | |
| 28 | #[cfg(FALSE)] //~ NOTE the item is gated here | |
| 29 | 29 | pub fn x() {} |
| 30 | 30 | //~^ NOTE found an item that was configured out |
| 31 | #[cfg(FALSE)] | |
| 31 | #[cfg(FALSE)] //~ NOTE the item is gated here | |
| 32 | 32 | pub fn y() {} |
| 33 | 33 | //~^ NOTE found an item that was configured out |
| 34 | 34 | } |
tests/ui/cfg/diagnostics-reexport.stderr+20| ... | ... | @@ -9,6 +9,11 @@ note: found an item that was configured out |
| 9 | 9 | | |
| 10 | 10 | LL | pub fn x() {} |
| 11 | 11 | | ^ |
| 12 | note: the item is gated here | |
| 13 | --> $DIR/diagnostics-reexport.rs:17:5 | |
| 14 | | | |
| 15 | LL | #[cfg(FALSE)] | |
| 16 | | ^^^^^^^^^^^^^ | |
| 12 | 17 | |
| 13 | 18 | error[E0432]: unresolved imports `b::x`, `b::y` |
| 14 | 19 | --> $DIR/diagnostics-reexport.rs:22:13 |
| ... | ... | @@ -23,11 +28,21 @@ note: found an item that was configured out |
| 23 | 28 | | |
| 24 | 29 | LL | pub fn x() {} |
| 25 | 30 | | ^ |
| 31 | note: the item is gated here | |
| 32 | --> $DIR/diagnostics-reexport.rs:28:5 | |
| 33 | | | |
| 34 | LL | #[cfg(FALSE)] | |
| 35 | | ^^^^^^^^^^^^^ | |
| 26 | 36 | note: found an item that was configured out |
| 27 | 37 | --> $DIR/diagnostics-reexport.rs:32:12 |
| 28 | 38 | | |
| 29 | 39 | LL | pub fn y() {} |
| 30 | 40 | | ^ |
| 41 | note: the item is gated here | |
| 42 | --> $DIR/diagnostics-reexport.rs:31:5 | |
| 43 | | | |
| 44 | LL | #[cfg(FALSE)] | |
| 45 | | ^^^^^^^^^^^^^ | |
| 31 | 46 | |
| 32 | 47 | error[E0425]: cannot find function `uwu` in module `inner` |
| 33 | 48 | --> $DIR/diagnostics-reexport.rs:38:12 |
| ... | ... | @@ -40,6 +55,11 @@ note: found an item that was configured out |
| 40 | 55 | | |
| 41 | 56 | LL | pub use super::uwu; |
| 42 | 57 | | ^^^ |
| 58 | note: the item is gated here | |
| 59 | --> $DIR/diagnostics-reexport.rs:7:5 | |
| 60 | | | |
| 61 | LL | #[cfg(FALSE)] | |
| 62 | | ^^^^^^^^^^^^^ | |
| 43 | 63 | |
| 44 | 64 | error: aborting due to 3 previous errors |
| 45 | 65 |
tests/ui/cfg/diagnostics-same-crate.rs+5-4| ... | ... | @@ -1,11 +1,13 @@ |
| 1 | 1 | #![allow(unexpected_cfgs)] // since we want to recognize them as unexpected |
| 2 | 2 | |
| 3 | 3 | pub mod inner { |
| 4 | #[cfg(FALSE)] | |
| 4 | #[cfg(FALSE)] //~ NOTE the item is gated here | |
| 5 | 5 | pub fn uwu() {} |
| 6 | 6 | //~^ NOTE found an item that was configured out |
| 7 | 7 | |
| 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 | |
| 9 | 11 | pub mod doesnt_exist { |
| 10 | 12 | //~^ NOTE found an item that was configured out |
| 11 | 13 | //~| NOTE found an item that was configured out |
| ... | ... | @@ -20,7 +22,7 @@ pub mod inner { |
| 20 | 22 | } |
| 21 | 23 | |
| 22 | 24 | 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 | |
| 24 | 26 | pub fn meow() {} |
| 25 | 27 | //~^ NOTE found an item that was configured out |
| 26 | 28 | } |
| ... | ... | @@ -55,7 +57,6 @@ fn main() { |
| 55 | 57 | // It should find the one in the right module, not the wrong one. |
| 56 | 58 | inner::right::meow(); //~ ERROR cannot find function |
| 57 | 59 | //~| NOTE not found in `inner::right |
| 58 | //~| NOTE the item is gated behind the `what-a-cool-feature` feature | |
| 59 | 60 | |
| 60 | 61 | // Exists in the crate root - we would generally want a diagnostic, |
| 61 | 62 | // but currently don't have one. |
tests/ui/cfg/diagnostics-same-crate.stderr+36-12| ... | ... | @@ -1,41 +1,56 @@ |
| 1 | 1 | error[E0432]: unresolved import `super::inner::doesnt_exist` |
| 2 | --> $DIR/diagnostics-same-crate.rs:30:9 | |
| 2 | --> $DIR/diagnostics-same-crate.rs:32:9 | |
| 3 | 3 | | |
| 4 | 4 | LL | use super::inner::doesnt_exist; |
| 5 | 5 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^ no `doesnt_exist` in `inner` |
| 6 | 6 | | |
| 7 | 7 | note: found an item that was configured out |
| 8 | --> $DIR/diagnostics-same-crate.rs:9:13 | |
| 8 | --> $DIR/diagnostics-same-crate.rs:11:13 | |
| 9 | 9 | | |
| 10 | 10 | LL | pub mod doesnt_exist { |
| 11 | 11 | | ^^^^^^^^^^^^ |
| 12 | note: the item is gated here | |
| 13 | --> $DIR/diagnostics-same-crate.rs:8:5 | |
| 14 | | | |
| 15 | LL | #[cfg(FALSE)] | |
| 16 | | ^^^^^^^^^^^^^ | |
| 12 | 17 | |
| 13 | 18 | error[E0432]: unresolved import `super::inner::doesnt_exist` |
| 14 | --> $DIR/diagnostics-same-crate.rs:33:23 | |
| 19 | --> $DIR/diagnostics-same-crate.rs:35:23 | |
| 15 | 20 | | |
| 16 | 21 | LL | use super::inner::doesnt_exist::hi; |
| 17 | 22 | | ^^^^^^^^^^^^ could not find `doesnt_exist` in `inner` |
| 18 | 23 | | |
| 19 | 24 | note: found an item that was configured out |
| 20 | --> $DIR/diagnostics-same-crate.rs:9:13 | |
| 25 | --> $DIR/diagnostics-same-crate.rs:11:13 | |
| 21 | 26 | | |
| 22 | 27 | LL | pub mod doesnt_exist { |
| 23 | 28 | | ^^^^^^^^^^^^ |
| 29 | note: the item is gated here | |
| 30 | --> $DIR/diagnostics-same-crate.rs:8:5 | |
| 31 | | | |
| 32 | LL | #[cfg(FALSE)] | |
| 33 | | ^^^^^^^^^^^^^ | |
| 24 | 34 | |
| 25 | 35 | error[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 | |
| 27 | 37 | | |
| 28 | 38 | LL | inner::doesnt_exist::hello(); |
| 29 | 39 | | ^^^^^^^^^^^^ could not find `doesnt_exist` in `inner` |
| 30 | 40 | | |
| 31 | 41 | note: found an item that was configured out |
| 32 | --> $DIR/diagnostics-same-crate.rs:9:13 | |
| 42 | --> $DIR/diagnostics-same-crate.rs:11:13 | |
| 33 | 43 | | |
| 34 | 44 | LL | pub mod doesnt_exist { |
| 35 | 45 | | ^^^^^^^^^^^^ |
| 46 | note: the item is gated here | |
| 47 | --> $DIR/diagnostics-same-crate.rs:8:5 | |
| 48 | | | |
| 49 | LL | #[cfg(FALSE)] | |
| 50 | | ^^^^^^^^^^^^^ | |
| 36 | 51 | |
| 37 | 52 | error[E0425]: cannot find function `uwu` in module `inner` |
| 38 | --> $DIR/diagnostics-same-crate.rs:47:12 | |
| 53 | --> $DIR/diagnostics-same-crate.rs:49:12 | |
| 39 | 54 | | |
| 40 | 55 | LL | inner::uwu(); |
| 41 | 56 | | ^^^ not found in `inner` |
| ... | ... | @@ -45,28 +60,37 @@ note: found an item that was configured out |
| 45 | 60 | | |
| 46 | 61 | LL | pub fn uwu() {} |
| 47 | 62 | | ^^^ |
| 63 | note: the item is gated here | |
| 64 | --> $DIR/diagnostics-same-crate.rs:4:5 | |
| 65 | | | |
| 66 | LL | #[cfg(FALSE)] | |
| 67 | | ^^^^^^^^^^^^^ | |
| 48 | 68 | |
| 49 | 69 | error[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 | |
| 51 | 71 | | |
| 52 | 72 | LL | inner::right::meow(); |
| 53 | 73 | | ^^^^ not found in `inner::right` |
| 54 | 74 | | |
| 55 | 75 | note: found an item that was configured out |
| 56 | --> $DIR/diagnostics-same-crate.rs:24:16 | |
| 76 | --> $DIR/diagnostics-same-crate.rs:26:16 | |
| 57 | 77 | | |
| 58 | 78 | LL | pub fn meow() {} |
| 59 | 79 | | ^^^^ |
| 60 | = note: the item is gated behind the `what-a-cool-feature` feature | |
| 80 | note: the item is gated behind the `what-a-cool-feature` feature | |
| 81 | --> $DIR/diagnostics-same-crate.rs:25:15 | |
| 82 | | | |
| 83 | LL | #[cfg(feature = "what-a-cool-feature")] | |
| 84 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 61 | 85 | |
| 62 | 86 | error[E0425]: cannot find function `uwu` in this scope |
| 63 | --> $DIR/diagnostics-same-crate.rs:43:5 | |
| 87 | --> $DIR/diagnostics-same-crate.rs:45:5 | |
| 64 | 88 | | |
| 65 | 89 | LL | uwu(); |
| 66 | 90 | | ^^^ not found in this scope |
| 67 | 91 | |
| 68 | 92 | error[E0425]: cannot find function `vanished` in this scope |
| 69 | --> $DIR/diagnostics-same-crate.rs:63:5 | |
| 93 | --> $DIR/diagnostics-same-crate.rs:64:5 | |
| 70 | 94 | | |
| 71 | 95 | LL | vanished(); |
| 72 | 96 | | ^^^^^^^^ not found in this scope |
tests/ui/macros/builtin-std-paths-fail.stderr+2| ... | ... | @@ -104,6 +104,8 @@ LL | #[std::test] |
| 104 | 104 | | |
| 105 | 105 | note: found an item that was configured out |
| 106 | 106 | --> $SRC_DIR/std/src/lib.rs:LL:COL |
| 107 | note: the item is gated here | |
| 108 | --> $SRC_DIR/std/src/lib.rs:LL:COL | |
| 107 | 109 | |
| 108 | 110 | error: aborting due to 16 previous errors |
| 109 | 111 |
tests/ui/macros/macro-outer-attributes.stderr+11| ... | ... | @@ -9,6 +9,17 @@ note: found an item that was configured out |
| 9 | 9 | | |
| 10 | 10 | LL | pub fn bar() { }); |
| 11 | 11 | | ^^^ |
| 12 | note: the item is gated here | |
| 13 | --> $DIR/macro-outer-attributes.rs:5:45 | |
| 14 | | | |
| 15 | LL | $i:item) => (mod $nm { #[$a] $i }); } | |
| 16 | | ^^^^^ | |
| 17 | LL | | |
| 18 | LL | / test!(a, | |
| 19 | LL | | #[cfg(FALSE)], | |
| 20 | LL | | 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) | |
| 12 | 23 | help: consider importing this function |
| 13 | 24 | | |
| 14 | 25 | LL + use b::bar; |
tests/ui/parser/issues/misplaced-return-type-complex-type-issue-126311.rs created+5| ... | ... | @@ -0,0 +1,5 @@ |
| 1 | fn 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 | ||
| 5 | fn main() {} |
tests/ui/parser/issues/misplaced-return-type-complex-type-issue-126311.stderr created+14| ... | ... | @@ -0,0 +1,14 @@ |
| 1 | error: return type should be specified after the function parameters | |
| 2 | --> $DIR/misplaced-return-type-complex-type-issue-126311.rs:1:30 | |
| 3 | | | |
| 4 | LL | fn foo<T>() where T: Default -> impl Default + 'static {} | |
| 5 | | ^^ expected one of `(`, `+`, `,`, `::`, `<`, or `{` | |
| 6 | | | |
| 7 | help: place the return type after the function parameters | |
| 8 | | | |
| 9 | LL - fn foo<T>() where T: Default -> impl Default + 'static {} | |
| 10 | LL + fn foo<T>() -> impl Default + 'static where T: Default {} | |
| 11 | | | |
| 12 | ||
| 13 | error: aborting due to 1 previous error | |
| 14 |
tests/ui/parser/issues/misplaced-return-type-issue-126311.rs created+5| ... | ... | @@ -0,0 +1,5 @@ |
| 1 | fn 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 | ||
| 5 | fn main() {} |
tests/ui/parser/issues/misplaced-return-type-issue-126311.stderr created+14| ... | ... | @@ -0,0 +1,14 @@ |
| 1 | error: return type should be specified after the function parameters | |
| 2 | --> $DIR/misplaced-return-type-issue-126311.rs:1:30 | |
| 3 | | | |
| 4 | LL | fn foo<T>() where T: Default -> u8 {} | |
| 5 | | ^^ expected one of `(`, `+`, `,`, `::`, `<`, or `{` | |
| 6 | | | |
| 7 | help: place the return type after the function parameters | |
| 8 | | | |
| 9 | LL - fn foo<T>() where T: Default -> u8 {} | |
| 10 | LL + fn foo<T>() -> u8 where T: Default {} | |
| 11 | | | |
| 12 | ||
| 13 | error: 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 @@ |
| 1 | fn foo<T, K>() | |
| 2 | //~^ HELP place the return type after the function parameters | |
| 3 | where | |
| 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 | ||
| 11 | fn main() {} |
tests/ui/parser/issues/misplaced-return-type-where-in-next-line-issue-126311.stderr created+17| ... | ... | @@ -0,0 +1,17 @@ |
| 1 | error: return type should be specified after the function parameters | |
| 2 | --> $DIR/misplaced-return-type-where-in-next-line-issue-126311.rs:5:15 | |
| 3 | | | |
| 4 | LL | K: Clone, -> Result<u8, String> | |
| 5 | | ^^ expected one of `{`, lifetime, or type | |
| 6 | | | |
| 7 | help: place the return type after the function parameters | |
| 8 | | | |
| 9 | LL ~ fn foo<T, K>() -> Result<u8, String> | |
| 10 | LL | | |
| 11 | LL | where | |
| 12 | LL | T: Default, | |
| 13 | LL ~ K: Clone, | |
| 14 | | | |
| 15 | ||
| 16 | error: 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 @@ |
| 1 | fn foo<T>() where T: Default -> { | |
| 2 | //~^ ERROR expected one of `(`, `+`, `,`, `::`, `<`, or `{`, found `->` | |
| 3 | 0 | |
| 4 | } | |
| 5 | ||
| 6 | fn main() {} |
tests/ui/parser/issues/misplaced-return-type-without-type-issue-126311.stderr created+8| ... | ... | @@ -0,0 +1,8 @@ |
| 1 | error: expected one of `(`, `+`, `,`, `::`, `<`, or `{`, found `->` | |
| 2 | --> $DIR/misplaced-return-type-without-type-issue-126311.rs:1:30 | |
| 3 | | | |
| 4 | LL | fn foo<T>() where T: Default -> { | |
| 5 | | ^^ expected one of `(`, `+`, `,`, `::`, `<`, or `{` | |
| 6 | ||
| 7 | error: 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 @@ |
| 1 | fn bar<T>() -> u8 -> u64 {} | |
| 2 | //~^ ERROR expected one of `!`, `(`, `+`, `::`, `<`, `where`, or `{`, found `->` | |
| 3 | ||
| 4 | fn main() {} |
tests/ui/parser/issues/misplaced-return-type-without-where-issue-126311.stderr created+8| ... | ... | @@ -0,0 +1,8 @@ |
| 1 | error: expected one of `!`, `(`, `+`, `::`, `<`, `where`, or `{`, found `->` | |
| 2 | --> $DIR/misplaced-return-type-without-where-issue-126311.rs:1:19 | |
| 3 | | | |
| 4 | LL | fn bar<T>() -> u8 -> u64 {} | |
| 5 | | ^^ expected one of 7 possible tokens | |
| 6 | ||
| 7 | error: 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 |
| 28 | 28 | LL | type FnPtr = safe fn(i32, i32) -> i32; |
| 29 | 29 | | ^^^^^^^^^^^^^^^^^^^^^^^^ |
| 30 | 30 | |
| 31 | error: aborting due to 5 previous errors | |
| 31 | error: static items cannot be declared with `unsafe` safety qualifier outside of `extern` block | |
| 32 | --> $DIR/safe-outside-extern.rs:28:1 | |
| 33 | | | |
| 34 | LL | unsafe static LOL: u8 = 0; | |
| 35 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 36 | ||
| 37 | error: aborting due to 6 previous errors | |
| 32 | 38 |
tests/ui/rust-2024/safe-outside-extern.rs+3| ... | ... | @@ -25,4 +25,7 @@ type FnPtr = safe fn(i32, i32) -> i32; |
| 25 | 25 | //~^ ERROR: function pointers cannot be declared with `safe` safety qualifier |
| 26 | 26 | //[ungated]~| ERROR: unsafe extern {}` blocks and `safe` keyword are experimental [E0658] |
| 27 | 27 | |
| 28 | unsafe static LOL: u8 = 0; | |
| 29 | //~^ ERROR: static items cannot be declared with `unsafe` safety qualifier outside of `extern` block | |
| 30 | ||
| 28 | 31 | fn 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 |
| 28 | 28 | LL | type FnPtr = safe fn(i32, i32) -> i32; |
| 29 | 29 | | ^^^^^^^^^^^^^^^^^^^^^^^^ |
| 30 | 30 | |
| 31 | error: static items cannot be declared with `unsafe` safety qualifier outside of `extern` block | |
| 32 | --> $DIR/safe-outside-extern.rs:28:1 | |
| 33 | | | |
| 34 | LL | unsafe static LOL: u8 = 0; | |
| 35 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 36 | ||
| 31 | 37 | error[E0658]: `unsafe extern {}` blocks and `safe` keyword are experimental |
| 32 | 38 | --> $DIR/safe-outside-extern.rs:4:1 |
| 33 | 39 | | |
| ... | ... | @@ -78,6 +84,6 @@ LL | type FnPtr = safe fn(i32, i32) -> i32; |
| 78 | 84 | = help: add `#![feature(unsafe_extern_blocks)]` to the crate attributes to enable |
| 79 | 85 | = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date |
| 80 | 86 | |
| 81 | error: aborting due to 10 previous errors | |
| 87 | error: aborting due to 11 previous errors | |
| 82 | 88 | |
| 83 | 89 | For more information about this error, try `rustc --explain E0658`. |