}),
),
);
- // In general, fields in packed structs are copied via a
- // block, e.g. `&{self.0}`. The one exception is `[u8]`
- // fields, which cannot be copied and also never cause
- // unaligned references. This exception is allowed to
- // handle the `FlexZeroSlice` type in the `zerovec` crate
- // within `icu4x-0.9.0`.
- //
- // Once use of `icu4x-0.9.0` has dropped sufficiently, this
- // exception should be removed.
- let is_u8_slice = if let TyKind::Slice(ty) = &struct_field.ty.kind &&
- let TyKind::Path(None, rustc_ast::Path { segments, .. }) = &ty.kind &&
- let [seg] = segments.as_slice() &&
- seg.ident.name == sym::u8 && seg.args.is_none()
- {
- true
- } else {
- false
- };
if is_packed {
- if is_u8_slice {
+ // In general, fields in packed structs are copied via a
+ // block, e.g. `&{self.0}`. The two exceptions are `[u8]`
+ // and `str` fields, which cannot be copied and also never
+ // cause unaligned references. These exceptions are allowed
+ // to handle the `FlexZeroSlice` type in the `zerovec`
+ // crate within `icu4x-0.9.0`.
+ //
+ // Once use of `icu4x-0.9.0` has dropped sufficiently, this
+ // exception should be removed.
+ let is_simple_path = |ty: &P<ast::Ty>, sym| {
+ if let TyKind::Path(None, ast::Path { segments, .. }) = &ty.kind &&
+ let [seg] = segments.as_slice() &&
+ seg.ident.name == sym && seg.args.is_none()
+ {
+ true
+ } else {
+ false
+ }
+ };
+
+ let exception = if let TyKind::Slice(ty) = &struct_field.ty.kind &&
+ is_simple_path(ty, sym::u8)
+ {
+ Some("byte")
+ } else if is_simple_path(&struct_field.ty, sym::str) {
+ Some("string")
+ } else {
+ None
+ };
+
+ if let Some(ty) = exception {
cx.sess.parse_sess.buffer_lint_with_diagnostic(
BYTE_SLICE_IN_PACKED_STRUCT_WITH_DERIVE,
sp,
ast::CRATE_NODE_ID,
- "byte slice in a packed struct that derives a built-in trait",
+ &format!(
+ "{} slice in a packed struct that derives a built-in trait",
+ ty
+ ),
rustc_lint_defs::BuiltinLintDiagnostics::ByteSliceInPackedStructWithDerive
);
} else {
// able to control the *exact* spelling of each of the symbols that are being imported:
// hence we don't want `dlltool` adding leading underscores automatically.
let dlltool = find_binutils_dlltool(sess);
+ let temp_prefix = {
+ let mut path = PathBuf::from(&output_path);
+ path.pop();
+ path.push(lib_name);
+ path
+ };
let result = std::process::Command::new(dlltool)
.args([
"-d",
"-l",
output_path.to_str().unwrap(),
"--no-leading-underscore",
+ "--temp-prefix",
+ temp_prefix.to_str().unwrap(),
])
.output();
registry: diagnostics_registry(),
};
- if !tracing::dispatcher::has_been_set() {
- init_rustc_env_logger_with_backtrace_option(&config.opts.unstable_opts.log_backtrace);
- }
-
match make_input(config.opts.error_format, &matches.free) {
Err(reported) => return Err(reported),
Ok(Some(input)) => {
/// This allows tools to enable rust logging without having to magically match rustc's
/// tracing crate version.
pub fn init_rustc_env_logger() {
- init_rustc_env_logger_with_backtrace_option(&None);
-}
-
-/// This allows tools to enable rust logging without having to magically match rustc's
-/// tracing crate version. In contrast to `init_rustc_env_logger` it allows you to
-/// choose a target module you wish to show backtraces along with its logging.
-pub fn init_rustc_env_logger_with_backtrace_option(backtrace_target: &Option<String>) {
- if let Err(error) = rustc_log::init_rustc_env_logger_with_backtrace_option(backtrace_target) {
- early_error(ErrorOutputType::default(), &error.to_string());
- }
+ init_env_logger("RUSTC_LOG");
}
/// This allows tools to enable rust logging without having to magically match rustc's
pub fn main() -> ! {
let start_time = Instant::now();
let start_rss = get_resident_set_size();
+ init_rustc_env_logger();
signal_handler::install();
let mut callbacks = TimePassesCallbacks::default();
install_ice_hook();
parse_help_set_edition_cargo = set `edition = "{$edition}"` in `Cargo.toml`
parse_help_set_edition_standalone = pass `--edition {$edition}` to `rustc`
parse_note_edition_guide = for more on editions, read https://doc.rust-lang.org/edition-guide
+
+parse_unexpected_token_after_dot = unexpected token: `{$actual}`
+
+parse_cannot_be_raw_ident = `{$ident}` cannot be a raw identifier
+
+parse_cr_doc_comment = bare CR not allowed in {$block ->
+ [true] block doc-comment
+ *[false] doc-comment
+}
+
+parse_no_digits_literal = no valid digits found for number
+
+parse_invalid_digit_literal = invalid digit for a base {$base} literal
+
+parse_empty_exponent_float = expected at least one digit in exponent
+
+parse_float_literal_unsupported_base = {$base} float literal is not supported
+
+parse_more_than_one_char = character literal may only contain one codepoint
+ .followed_by = this `{$chr}` is followed by the combining {$len ->
+ [one] mark
+ *[other] marks
+ } `{$escaped_marks}`
+ .non_printing = there are non-printing characters, the full sequence is `{$escaped}`
+ .consider_normalized = consider using the normalized form `{$ch}` of this character
+ .remove_non = consider removing the non-printing characters
+ .use_double_quotes = if you meant to write a {$is_byte ->
+ [true] byte string
+ *[false] `str`
+ } literal, use double quotes
+
+parse_no_brace_unicode_escape = incorrect unicode escape sequence
+ .label = {parse_no_brace_unicode_escape}
+ .use_braces = format of unicode escape sequences uses braces
+ .format_of_unicode = format of unicode escape sequences is `\u{"{...}"}`
+
+parse_invalid_unicode_escape = invalid unicode character escape
+ .label = invalid escape
+ .help = unicode escape must {$surrogate ->
+ [true] not be a surrogate
+ *[false] be at most 10FFFF
+ }
+
+parse_escape_only_char = {$byte ->
+ [true] byte
+ *[false] character
+ } constant must be escaped: `{$escaped_msg}`
+ .escape = escape the character
+
+parse_bare_cr = {$double_quotes ->
+ [true] bare CR not allowed in string, use `\r` instead
+ *[false] character constant must be escaped: `\r`
+ }
+ .escape = escape the character
+
+parse_bare_cr_in_raw_string = bare CR not allowed in raw string
+
+parse_too_short_hex_escape = numeric character escape is too short
+
+parse_invalid_char_in_escape = {parse_invalid_char_in_escape_msg}: `{$ch}`
+ .label = {parse_invalid_char_in_escape_msg}
+
+parse_invalid_char_in_escape_msg = invalid character in {$is_hex ->
+ [true] numeric character
+ *[false] unicode
+ } escape
+
+parse_out_of_range_hex_escape = out of range hex escape
+ .label = must be a character in the range [\x00-\x7f]
+
+parse_leading_underscore_unicode_escape = {parse_leading_underscore_unicode_escape_label}: `_`
+parse_leading_underscore_unicode_escape_label = invalid start of unicode escape
+
+parse_overlong_unicode_escape = overlong unicode escape
+ .label = must have at most 6 hex digits
+
+parse_unclosed_unicode_escape = unterminated unicode escape
+ .label = missing a closing `{"}"}`
+ .terminate = terminate the unicode escape
+
+parse_unicode_escape_in_byte = unicode escape in byte string
+ .label = {parse_unicode_escape_in_byte}
+ .help = unicode escape sequences cannot be used as a byte or in a byte string
+
+parse_empty_unicode_escape = empty unicode escape
+ .label = this escape must have at least 1 hex digit
+
+parse_zero_chars = empty character literal
+ .label = {parse_zero_chars}
+
+parse_lone_slash = invalid trailing slash in literal
+ .label = {parse_lone_slash}
+
+parse_unskipped_whitespace = non-ASCII whitespace symbol '{$ch}' is not skipped
+ .label = {parse_unskipped_whitespace}
+
+parse_multiple_skipped_lines = multiple lines skipped by escaped newline
+ .label = skipping everything up to and including this point
+
+parse_unknown_prefix = prefix `{$prefix}` is unknown
+ .label = unknown prefix
+ .note = prefixed identifiers and literals are reserved since Rust 2021
+ .suggestion_br = use `br` for a raw byte string
+ .suggestion_whitespace = consider inserting whitespace here
+
+parse_too_many_hashes = too many `#` symbols: raw strings may be delimited by up to 255 `#` symbols, but found {$num}
+
+parse_unknown_start_of_token = unknown start of token: {$escaped}
+ .sugg_quotes = Unicode characters '“' (Left Double Quotation Mark) and '”' (Right Double Quotation Mark) look like '{$ascii_str}' ({$ascii_name}), but are not
+ .sugg_other = Unicode character '{$ch}' ({$u_name}) looks like '{$ascii_str}' ({$ascii_name}), but it is not
+ .help_null = source files must contain UTF-8 encoded text, unexpected null bytes might occur when a different encoding is used
+ .note_repeats = character appears {$repeats ->
+ [one] once more
+ *[other] {$repeats} more times
+ }
let param_env = tcx.param_env(item_def_id);
for field in &def.non_enum_variant().fields {
- let field_ty = field.ty(tcx, substs);
+ let field_ty = tcx.normalize_erasing_regions(param_env, field.ty(tcx, substs));
if !allowed_union_field(field_ty, tcx, param_env) {
let (field_span, ty_span) = match tcx.hir().get_if_local(field.did) {
tracked!(link_only, true);
tracked!(llvm_plugins, vec![String::from("plugin_name")]);
tracked!(location_detail, LocationDetail { file: true, line: false, column: false });
- tracked!(log_backtrace, Some("filter".to_string()));
tracked!(maximal_hir_to_mir_coverage, true);
tracked!(merge_functions, Some(MergeFunctions::Disabled));
tracked!(mir_emit_retag, true);
declare_lint! {
/// The `byte_slice_in_packed_struct_with_derive` lint detects cases where a byte slice field
- /// (`[u8]`) is used in a `packed` struct that derives one or more built-in traits.
+ /// (`[u8]`) or string slice field (`str`) is used in a `packed` struct that derives one or
+ /// more built-in traits.
///
/// ### Example
///
/// ### Explanation
///
/// This was previously accepted but is being phased out, because fields in packed structs are
- /// now required to implement `Copy` for `derive` to work. Byte slices are a temporary
- /// exception because certain crates depended on them.
+ /// now required to implement `Copy` for `derive` to work. Byte slices and string slices are a
+ /// temporary exception because certain crates depended on them.
pub BYTE_SLICE_IN_PACKED_STRUCT_WITH_DERIVE,
Warn,
- "`[u8]` slice used in a packed struct with `derive`",
+ "`[u8]` or `str` used in a packed struct with `derive`",
@future_incompatible = FutureIncompatibleInfo {
reference: "issue #107457 <https://github.com/rust-lang/rust/issues/107457>",
reason: FutureIncompatibilityReason::FutureReleaseErrorReportNow,
use tracing_subscriber::layer::SubscriberExt;
pub fn init_rustc_env_logger() -> Result<(), Error> {
- init_rustc_env_logger_with_backtrace_option(&None)
-}
-
-pub fn init_rustc_env_logger_with_backtrace_option(
- backtrace_target: &Option<String>,
-) -> Result<(), Error> {
- init_env_logger_with_backtrace_option("RUSTC_LOG", backtrace_target)
+ init_env_logger("RUSTC_LOG")
}
/// In contrast to `init_rustc_env_logger` this allows you to choose an env var
/// other than `RUSTC_LOG`.
pub fn init_env_logger(env: &str) -> Result<(), Error> {
- init_env_logger_with_backtrace_option(env, &None)
-}
-
-pub fn init_env_logger_with_backtrace_option(
- env: &str,
- backtrace_target: &Option<String>,
-) -> Result<(), Error> {
let filter = match env::var(env) {
Ok(env) => EnvFilter::new(env),
_ => EnvFilter::default().add_directive(Directive::from(LevelFilter::WARN)),
let layer = layer.with_thread_ids(true).with_thread_names(true);
let subscriber = tracing_subscriber::Registry::default().with(filter).with(layer);
- match backtrace_target {
- Some(str) => {
+ match env::var(format!("{env}_BACKTRACE")) {
+ Ok(str) => {
let fmt_layer = tracing_subscriber::fmt::layer()
.with_writer(io::stderr)
.without_time()
let subscriber = subscriber.with(fmt_layer);
tracing::subscriber::set_global_default(subscriber).unwrap();
}
- None => {
+ Err(_) => {
tracing::subscriber::set_global_default(subscriber).unwrap();
}
};
pub span: Span,
}
+#[derive(Diagnostic)]
+#[diag(parse_unexpected_token_after_dot)]
+pub struct UnexpectedTokenAfterDot<'a> {
+ #[primary_span]
+ pub span: Span,
+ pub actual: Cow<'a, str>,
+}
+
#[derive(Diagnostic)]
#[diag(parse_visibility_not_followed_by_item)]
#[help]
},
}
+#[derive(Diagnostic)]
+#[diag(parse_cannot_be_raw_ident)]
+pub struct CannotBeRawIdent {
+ #[primary_span]
+ pub span: Span,
+ pub ident: Symbol,
+}
+
+#[derive(Diagnostic)]
+#[diag(parse_cr_doc_comment)]
+pub struct CrDocComment {
+ #[primary_span]
+ pub span: Span,
+ pub block: bool,
+}
+
+#[derive(Diagnostic)]
+#[diag(parse_no_digits_literal, code = "E0768")]
+pub struct NoDigitsLiteral {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(parse_invalid_digit_literal)]
+pub struct InvalidDigitLiteral {
+ #[primary_span]
+ pub span: Span,
+ pub base: u32,
+}
+
+#[derive(Diagnostic)]
+#[diag(parse_empty_exponent_float)]
+pub struct EmptyExponentFloat {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(parse_float_literal_unsupported_base)]
+pub struct FloatLiteralUnsupportedBase {
+ #[primary_span]
+ pub span: Span,
+ pub base: &'static str,
+}
+
+#[derive(Diagnostic)]
+#[diag(parse_unknown_prefix)]
+#[note]
+pub struct UnknownPrefix<'a> {
+ #[primary_span]
+ #[label]
+ pub span: Span,
+ pub prefix: &'a str,
+ #[subdiagnostic]
+ pub sugg: Option<UnknownPrefixSugg>,
+}
+
+#[derive(Subdiagnostic)]
+pub enum UnknownPrefixSugg {
+ #[suggestion(suggestion_br, code = "br", applicability = "maybe-incorrect", style = "verbose")]
+ UseBr(#[primary_span] Span),
+ #[suggestion(
+ suggestion_whitespace,
+ code = " ",
+ applicability = "maybe-incorrect",
+ style = "verbose"
+ )]
+ Whitespace(#[primary_span] Span),
+}
+
+#[derive(Diagnostic)]
+#[diag(parse_too_many_hashes)]
+pub struct TooManyHashes {
+ #[primary_span]
+ pub span: Span,
+ pub num: u32,
+}
+
+#[derive(Diagnostic)]
+#[diag(parse_unknown_start_of_token)]
+pub struct UnknownTokenStart {
+ #[primary_span]
+ pub span: Span,
+ pub escaped: String,
+ #[subdiagnostic]
+ pub sugg: Option<TokenSubstitution>,
+ #[subdiagnostic]
+ pub null: Option<UnknownTokenNull>,
+ #[subdiagnostic]
+ pub repeat: Option<UnknownTokenRepeat>,
+}
+
+#[derive(Subdiagnostic)]
+pub enum TokenSubstitution {
+ #[suggestion(sugg_quotes, code = "{suggestion}", applicability = "maybe-incorrect")]
+ DirectedQuotes {
+ #[primary_span]
+ span: Span,
+ suggestion: String,
+ ascii_str: &'static str,
+ ascii_name: &'static str,
+ },
+ #[suggestion(sugg_other, code = "{suggestion}", applicability = "maybe-incorrect")]
+ Other {
+ #[primary_span]
+ span: Span,
+ suggestion: String,
+ ch: String,
+ u_name: &'static str,
+ ascii_str: &'static str,
+ ascii_name: &'static str,
+ },
+}
+
+#[derive(Subdiagnostic)]
+#[note(note_repeats)]
+pub struct UnknownTokenRepeat {
+ pub repeats: usize,
+}
+
+#[derive(Subdiagnostic)]
+#[help(help_null)]
+pub struct UnknownTokenNull;
+
+#[derive(Diagnostic)]
+pub enum UnescapeError {
+ #[diag(parse_invalid_unicode_escape)]
+ #[help]
+ InvalidUnicodeEscape {
+ #[primary_span]
+ #[label]
+ span: Span,
+ surrogate: bool,
+ },
+ #[diag(parse_escape_only_char)]
+ EscapeOnlyChar {
+ #[primary_span]
+ span: Span,
+ #[suggestion(escape, applicability = "machine-applicable", code = "{escaped_sugg}")]
+ char_span: Span,
+ escaped_sugg: String,
+ escaped_msg: String,
+ byte: bool,
+ },
+ #[diag(parse_bare_cr)]
+ BareCr {
+ #[primary_span]
+ #[suggestion(escape, applicability = "machine-applicable", code = "\\r")]
+ span: Span,
+ double_quotes: bool,
+ },
+ #[diag(parse_bare_cr_in_raw_string)]
+ BareCrRawString(#[primary_span] Span),
+ #[diag(parse_too_short_hex_escape)]
+ TooShortHexEscape(#[primary_span] Span),
+ #[diag(parse_invalid_char_in_escape)]
+ InvalidCharInEscape {
+ #[primary_span]
+ #[label]
+ span: Span,
+ is_hex: bool,
+ ch: String,
+ },
+ #[diag(parse_out_of_range_hex_escape)]
+ OutOfRangeHexEscape(
+ #[primary_span]
+ #[label]
+ Span,
+ ),
+ #[diag(parse_leading_underscore_unicode_escape)]
+ LeadingUnderscoreUnicodeEscape {
+ #[primary_span]
+ #[label(parse_leading_underscore_unicode_escape_label)]
+ span: Span,
+ ch: String,
+ },
+ #[diag(parse_overlong_unicode_escape)]
+ OverlongUnicodeEscape(
+ #[primary_span]
+ #[label]
+ Span,
+ ),
+ #[diag(parse_unclosed_unicode_escape)]
+ UnclosedUnicodeEscape(
+ #[primary_span]
+ #[label]
+ Span,
+ #[suggestion(terminate, code = "}}", applicability = "maybe-incorrect", style = "verbose")]
+ Span,
+ ),
+ #[diag(parse_no_brace_unicode_escape)]
+ NoBraceInUnicodeEscape {
+ #[primary_span]
+ span: Span,
+ #[label]
+ label: Option<Span>,
+ #[subdiagnostic]
+ sub: NoBraceUnicodeSub,
+ },
+ #[diag(parse_unicode_escape_in_byte)]
+ #[help]
+ UnicodeEscapeInByte(
+ #[primary_span]
+ #[label]
+ Span,
+ ),
+ #[diag(parse_empty_unicode_escape)]
+ EmptyUnicodeEscape(
+ #[primary_span]
+ #[label]
+ Span,
+ ),
+ #[diag(parse_zero_chars)]
+ ZeroChars(
+ #[primary_span]
+ #[label]
+ Span,
+ ),
+ #[diag(parse_lone_slash)]
+ LoneSlash(
+ #[primary_span]
+ #[label]
+ Span,
+ ),
+ #[diag(parse_unskipped_whitespace)]
+ UnskippedWhitespace {
+ #[primary_span]
+ span: Span,
+ #[label]
+ char_span: Span,
+ ch: String,
+ },
+ #[diag(parse_multiple_skipped_lines)]
+ MultipleSkippedLinesWarning(
+ #[primary_span]
+ #[label]
+ Span,
+ ),
+ #[diag(parse_more_than_one_char)]
+ MoreThanOneChar {
+ #[primary_span]
+ span: Span,
+ #[subdiagnostic]
+ note: Option<MoreThanOneCharNote>,
+ #[subdiagnostic]
+ suggestion: MoreThanOneCharSugg,
+ },
+}
+
+#[derive(Subdiagnostic)]
+pub enum MoreThanOneCharSugg {
+ #[suggestion(consider_normalized, code = "{normalized}", applicability = "machine-applicable")]
+ NormalizedForm {
+ #[primary_span]
+ span: Span,
+ ch: String,
+ normalized: String,
+ },
+ #[suggestion(remove_non, code = "{ch}", applicability = "maybe-incorrect")]
+ RemoveNonPrinting {
+ #[primary_span]
+ span: Span,
+ ch: String,
+ },
+ #[suggestion(use_double_quotes, code = "{sugg}", applicability = "machine-applicable")]
+ Quotes {
+ #[primary_span]
+ span: Span,
+ is_byte: bool,
+ sugg: String,
+ },
+}
+
+#[derive(Subdiagnostic)]
+pub enum MoreThanOneCharNote {
+ #[note(followed_by)]
+ AllCombining {
+ #[primary_span]
+ span: Span,
+ chr: String,
+ len: usize,
+ escaped_marks: String,
+ },
+ #[note(non_printing)]
+ NonPrinting {
+ #[primary_span]
+ span: Span,
+ escaped: String,
+ },
+}
+
+#[derive(Subdiagnostic)]
+pub enum NoBraceUnicodeSub {
+ #[suggestion(use_braces, code = "{suggestion}", applicability = "maybe-incorrect")]
+ Suggestion {
+ #[primary_span]
+ span: Span,
+ suggestion: String,
+ },
+ #[help(format_of_unicode)]
+ Help,
+}
+
#[derive(Subdiagnostic)]
pub(crate) enum TopLevelOrPatternNotAllowedSugg {
#[suggestion(
+use crate::errors;
use crate::lexer::unicode_chars::UNICODE_ARRAY;
use rustc_ast::ast::{self, AttrStyle};
use rustc_ast::token::{self, CommentKind, Delimiter, Token, TokenKind};
use rustc_ast::tokenstream::TokenStream;
use rustc_ast::util::unicode::contains_text_flow_control_chars;
-use rustc_errors::{
- error_code, Applicability, DiagnosticBuilder, ErrorGuaranteed, PResult, StashKey,
-};
+use rustc_errors::{error_code, Applicability, DiagnosticBuilder, PResult, StashKey};
use rustc_lexer::unescape::{self, Mode};
use rustc_lexer::Cursor;
use rustc_lexer::{Base, DocStyle, RawStrError};
let span = self.mk_sp(start, self.pos);
self.sess.symbol_gallery.insert(sym, span);
if !sym.can_be_raw() {
- self.err_span(span, &format!("`{}` cannot be a raw identifier", sym));
+ self.sess.emit_err(errors::CannotBeRawIdent { span, ident: sym });
}
self.sess.raw_identifier_spans.borrow_mut().push(span);
token::Ident(sym, true)
self.nbsp_is_whitespace = true;
}
let repeats = it.take_while(|c1| *c1 == c).count();
- let mut err =
- self.struct_err_span_char(start, self.pos + Pos::from_usize(repeats * c.len_utf8()), "unknown start of token", c);
// FIXME: the lexer could be used to turn the ASCII version of unicode
// homoglyphs, instead of keeping a table in `check_for_substitution`into the
// token. Ideally, this should be inside `rustc_lexer`. However, we should
// first remove compound tokens like `<<` from `rustc_lexer`, and then add
// fancier error recovery to it, as there will be less overall work to do this
// way.
- let token = unicode_chars::check_for_substitution(self, start, c, &mut err, repeats+1);
- if c == '\x00' {
- err.help("source files must contain UTF-8 encoded text, unexpected null bytes might occur when a different encoding is used");
- }
- if repeats > 0 {
- if repeats == 1 {
- err.note(format!("character appears once more"));
- } else {
- err.note(format!("character appears {repeats} more times"));
- }
- swallow_next_invalid = repeats;
- }
- err.emit();
+ let (token, sugg) = unicode_chars::check_for_substitution(self, start, c, repeats+1);
+ self.sess.emit_err(errors::UnknownTokenStart {
+ span: self.mk_sp(start, self.pos + Pos::from_usize(repeats * c.len_utf8())),
+ escaped: escaped_char(c),
+ sugg,
+ null: if c == '\x00' {Some(errors::UnknownTokenNull)} else {None},
+ repeat: if repeats > 0 {
+ swallow_next_invalid = repeats;
+ Some(errors::UnknownTokenRepeat { repeats })
+ } else {None}
+ });
+
if let Some(token) = token {
token
} else {
}
}
- /// Report a fatal lexical error with a given span.
- fn fatal_span(&self, sp: Span, m: &str) -> ! {
- self.sess.span_diagnostic.span_fatal(sp, m)
- }
-
- /// Report a lexical error with a given span.
- fn err_span(&self, sp: Span, m: &str) {
- self.sess.span_diagnostic.struct_span_err(sp, m).emit();
- }
-
- /// Report a fatal error spanning [`from_pos`, `to_pos`).
- fn fatal_span_(&self, from_pos: BytePos, to_pos: BytePos, m: &str) -> ! {
- self.fatal_span(self.mk_sp(from_pos, to_pos), m)
- }
-
- /// Report a lexical error spanning [`from_pos`, `to_pos`).
- fn err_span_(&self, from_pos: BytePos, to_pos: BytePos, m: &str) {
- self.err_span(self.mk_sp(from_pos, to_pos), m)
- }
-
fn struct_fatal_span_char(
&self,
from_pos: BytePos,
.struct_span_fatal(self.mk_sp(from_pos, to_pos), &format!("{}: {}", m, escaped_char(c)))
}
- fn struct_err_span_char(
- &self,
- from_pos: BytePos,
- to_pos: BytePos,
- m: &str,
- c: char,
- ) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
- self.sess
- .span_diagnostic
- .struct_span_err(self.mk_sp(from_pos, to_pos), &format!("{}: {}", m, escaped_char(c)))
- }
-
/// Detect usages of Unicode codepoints changing the direction of the text on screen and loudly
/// complain about it.
fn lint_unicode_text_flow(&self, start: BytePos) {
) -> TokenKind {
if content.contains('\r') {
for (idx, _) in content.char_indices().filter(|&(_, c)| c == '\r') {
- self.err_span_(
+ let span = self.mk_sp(
content_start + BytePos(idx as u32),
content_start + BytePos(idx as u32 + 1),
- match comment_kind {
- CommentKind::Line => "bare CR not allowed in doc-comment",
- CommentKind::Block => "bare CR not allowed in block doc-comment",
- },
);
+ let block = matches!(comment_kind, CommentKind::Block);
+ self.sess.emit_err(errors::CrDocComment { span, block });
}
}
}
rustc_lexer::LiteralKind::Int { base, empty_int } => {
if empty_int {
- self.sess
- .span_diagnostic
- .struct_span_err_with_code(
- self.mk_sp(start, end),
- "no valid digits found for number",
- error_code!(E0768),
- )
- .emit();
+ let span = self.mk_sp(start, end);
+ self.sess.emit_err(errors::NoDigitsLiteral { span });
(token::Integer, sym::integer(0))
} else {
if matches!(base, Base::Binary | Base::Octal) {
let base = base as u32;
let s = self.str_from_to(start + BytePos(2), end);
for (idx, c) in s.char_indices() {
+ let span = self.mk_sp(
+ start + BytePos::from_usize(2 + idx),
+ start + BytePos::from_usize(2 + idx + c.len_utf8()),
+ );
if c != '_' && c.to_digit(base).is_none() {
- self.err_span_(
- start + BytePos::from_usize(2 + idx),
- start + BytePos::from_usize(2 + idx + c.len_utf8()),
- &format!("invalid digit for a base {} literal", base),
- );
+ self.sess.emit_err(errors::InvalidDigitLiteral { span, base });
}
}
}
}
rustc_lexer::LiteralKind::Float { base, empty_exponent } => {
if empty_exponent {
- self.err_span_(start, self.pos, "expected at least one digit in exponent");
+ let span = self.mk_sp(start, self.pos);
+ self.sess.emit_err(errors::EmptyExponentFloat { span });
}
- match base {
- Base::Hexadecimal => {
- self.err_span_(start, end, "hexadecimal float literal is not supported")
- }
- Base::Octal => {
- self.err_span_(start, end, "octal float literal is not supported")
- }
- Base::Binary => {
- self.err_span_(start, end, "binary float literal is not supported")
- }
- _ => {}
+ let base = match base {
+ Base::Hexadecimal => Some("hexadecimal"),
+ Base::Octal => Some("octal"),
+ Base::Binary => Some("binary"),
+ _ => None,
+ };
+ if let Some(base) = base {
+ let span = self.mk_sp(start, end);
+ self.sess.emit_err(errors::FloatLiteralUnsupportedBase { span, base });
}
(token::Float, self.symbol_from_to(start, end))
}
// identifier tokens.
fn report_unknown_prefix(&self, start: BytePos) {
let prefix_span = self.mk_sp(start, self.pos);
- let prefix_str = self.str_from_to(start, self.pos);
- let msg = format!("prefix `{}` is unknown", prefix_str);
+ let prefix = self.str_from_to(start, self.pos);
let expn_data = prefix_span.ctxt().outer_expn_data();
if expn_data.edition >= Edition::Edition2021 {
// In Rust 2021, this is a hard error.
- let mut err = self.sess.span_diagnostic.struct_span_err(prefix_span, &msg);
- err.span_label(prefix_span, "unknown prefix");
- if prefix_str == "rb" {
- err.span_suggestion_verbose(
- prefix_span,
- "use `br` for a raw byte string",
- "br",
- Applicability::MaybeIncorrect,
- );
+ let sugg = if prefix == "rb" {
+ Some(errors::UnknownPrefixSugg::UseBr(prefix_span))
} else if expn_data.is_root() {
- err.span_suggestion_verbose(
- prefix_span.shrink_to_hi(),
- "consider inserting whitespace here",
- " ",
- Applicability::MaybeIncorrect,
- );
- }
- err.note("prefixed identifiers and literals are reserved since Rust 2021");
- err.emit();
+ Some(errors::UnknownPrefixSugg::Whitespace(prefix_span.shrink_to_hi()))
+ } else {
+ None
+ };
+ self.sess.emit_err(errors::UnknownPrefix { span: prefix_span, prefix, sugg });
} else {
// Before Rust 2021, only emit a lint for migration.
self.sess.buffer_lint_with_diagnostic(
&RUST_2021_PREFIXES_INCOMPATIBLE_SYNTAX,
prefix_span,
ast::CRATE_NODE_ID,
- &msg,
+ &format!("prefix `{prefix}` is unknown"),
BuiltinLintDiagnostics::ReservedPrefix(prefix_span),
);
}
}
- fn report_too_many_hashes(&self, start: BytePos, found: u32) -> ! {
- self.fatal_span_(
- start,
- self.pos,
- &format!(
- "too many `#` symbols: raw strings may be delimited \
- by up to 255 `#` symbols, but found {}",
- found
- ),
- )
+ fn report_too_many_hashes(&self, start: BytePos, num: u32) -> ! {
+ self.sess.emit_fatal(errors::TooManyHashes { span: self.mk_sp(start, self.pos), num });
}
fn cook_quoted(
use std::iter::once;
use std::ops::Range;
-use rustc_errors::{pluralize, Applicability, Handler};
+use rustc_errors::{Applicability, Handler};
use rustc_lexer::unescape::{EscapeError, Mode};
use rustc_span::{BytePos, Span};
+use crate::errors::{MoreThanOneCharNote, MoreThanOneCharSugg, NoBraceUnicodeSub, UnescapeError};
+
pub(crate) fn emit_unescape_error(
handler: &Handler,
// interior part of the literal, without quotes
};
match error {
EscapeError::LoneSurrogateUnicodeEscape => {
- handler
- .struct_span_err(span, "invalid unicode character escape")
- .span_label(span, "invalid escape")
- .help("unicode escape must not be a surrogate")
- .emit();
+ handler.emit_err(UnescapeError::InvalidUnicodeEscape { span, surrogate: true });
}
EscapeError::OutOfRangeUnicodeEscape => {
- handler
- .struct_span_err(span, "invalid unicode character escape")
- .span_label(span, "invalid escape")
- .help("unicode escape must be at most 10FFFF")
- .emit();
+ handler.emit_err(UnescapeError::InvalidUnicodeEscape { span, surrogate: false });
}
EscapeError::MoreThanOneChar => {
use unicode_normalization::{char::is_combining_mark, UnicodeNormalization};
+ let mut sugg = None;
+ let mut note = None;
- let mut has_help = false;
- let mut handler = handler.struct_span_err(
- span_with_quotes,
- "character literal may only contain one codepoint",
- );
-
- if lit.chars().skip(1).all(|c| is_combining_mark(c)) {
- let escaped_marks =
- lit.chars().skip(1).map(|c| c.escape_default().to_string()).collect::<Vec<_>>();
- handler.span_note(
- span,
- &format!(
- "this `{}` is followed by the combining mark{} `{}`",
- lit.chars().next().unwrap(),
- pluralize!(escaped_marks.len()),
- escaped_marks.join(""),
- ),
- );
+ let lit_chars = lit.chars().collect::<Vec<_>>();
+ let (first, rest) = lit_chars.split_first().unwrap();
+ if rest.iter().copied().all(is_combining_mark) {
let normalized = lit.nfc().to_string();
if normalized.chars().count() == 1 {
- has_help = true;
- handler.span_suggestion(
- span,
- &format!(
- "consider using the normalized form `{}` of this character",
- normalized.chars().next().unwrap().escape_default()
- ),
- normalized,
- Applicability::MachineApplicable,
- );
+ let ch = normalized.chars().next().unwrap().escape_default().to_string();
+ sugg = Some(MoreThanOneCharSugg::NormalizedForm { span, ch, normalized });
}
+ let escaped_marks =
+ rest.iter().map(|c| c.escape_default().to_string()).collect::<Vec<_>>();
+ note = Some(MoreThanOneCharNote::AllCombining {
+ span,
+ chr: format!("{first}"),
+ len: escaped_marks.len(),
+ escaped_marks: escaped_marks.join(""),
+ });
} else {
let printable: Vec<char> = lit
.chars()
})
.collect();
- if let [ch] = printable.as_slice() {
- has_help = true;
-
- handler.span_note(
+ if let &[ch] = printable.as_slice() {
+ sugg =
+ Some(MoreThanOneCharSugg::RemoveNonPrinting { span, ch: ch.to_string() });
+ note = Some(MoreThanOneCharNote::NonPrinting {
span,
- &format!(
- "there are non-printing characters, the full sequence is `{}`",
- lit.escape_default(),
- ),
- );
-
- handler.span_suggestion(
- span,
- "consider removing the non-printing characters",
- ch,
- Applicability::MaybeIncorrect,
- );
+ escaped: lit.escape_default().to_string(),
+ });
}
- }
-
- if !has_help {
- let (prefix, msg) = if mode.is_byte() {
- ("b", "if you meant to write a byte string literal, use double quotes")
- } else {
- ("", "if you meant to write a `str` literal, use double quotes")
- };
+ };
+ let sugg = sugg.unwrap_or_else(|| {
+ let is_byte = mode.is_byte();
+ let prefix = if is_byte { "b" } else { "" };
let mut escaped = String::with_capacity(lit.len());
let mut chrs = lit.chars().peekable();
while let Some(first) = chrs.next() {
(c, _) => escaped.push(c),
};
}
- handler.span_suggestion(
- span_with_quotes,
- msg,
- format!("{prefix}\"{escaped}\""),
- Applicability::MachineApplicable,
- );
- }
-
- handler.emit();
+ let sugg = format!("{prefix}\"{escaped}\"");
+ MoreThanOneCharSugg::Quotes { span: span_with_quotes, is_byte, sugg }
+ });
+ handler.emit_err(UnescapeError::MoreThanOneChar {
+ span: span_with_quotes,
+ note,
+ suggestion: sugg,
+ });
}
EscapeError::EscapeOnlyChar => {
let (c, char_span) = last_char();
-
- let msg = if mode.is_byte() {
- "byte constant must be escaped"
- } else {
- "character constant must be escaped"
- };
- handler
- .struct_span_err(span, &format!("{}: `{}`", msg, escaped_char(c)))
- .span_suggestion(
- char_span,
- "escape the character",
- c.escape_default(),
- Applicability::MachineApplicable,
- )
- .emit();
+ handler.emit_err(UnescapeError::EscapeOnlyChar {
+ span,
+ char_span,
+ escaped_sugg: c.escape_default().to_string(),
+ escaped_msg: escaped_char(c),
+ byte: mode.is_byte(),
+ });
}
EscapeError::BareCarriageReturn => {
- let msg = if mode.in_double_quotes() {
- "bare CR not allowed in string, use `\\r` instead"
- } else {
- "character constant must be escaped: `\\r`"
- };
- handler
- .struct_span_err(span, msg)
- .span_suggestion(
- span,
- "escape the character",
- "\\r",
- Applicability::MachineApplicable,
- )
- .emit();
+ let double_quotes = mode.in_double_quotes();
+ handler.emit_err(UnescapeError::BareCr { span, double_quotes });
}
EscapeError::BareCarriageReturnInRawString => {
assert!(mode.in_double_quotes());
- let msg = "bare CR not allowed in raw string";
- handler.span_err(span, msg);
+ handler.emit_err(UnescapeError::BareCrRawString(span));
}
EscapeError::InvalidEscape => {
let (c, span) = last_char();
diag.emit();
}
EscapeError::TooShortHexEscape => {
- handler.span_err(span, "numeric character escape is too short");
+ handler.emit_err(UnescapeError::TooShortHexEscape(span));
}
EscapeError::InvalidCharInHexEscape | EscapeError::InvalidCharInUnicodeEscape => {
let (c, span) = last_char();
-
- let msg = if error == EscapeError::InvalidCharInHexEscape {
- "invalid character in numeric character escape"
- } else {
- "invalid character in unicode escape"
- };
- let c = escaped_char(c);
-
- handler
- .struct_span_err(span, &format!("{}: `{}`", msg, c))
- .span_label(span, msg)
- .emit();
+ let is_hex = error == EscapeError::InvalidCharInHexEscape;
+ let ch = escaped_char(c);
+ handler.emit_err(UnescapeError::InvalidCharInEscape { span, is_hex, ch });
}
EscapeError::NonAsciiCharInByte => {
let (c, span) = last_char();
err.emit();
}
EscapeError::OutOfRangeHexEscape => {
- handler
- .struct_span_err(span, "out of range hex escape")
- .span_label(span, "must be a character in the range [\\x00-\\x7f]")
- .emit();
+ handler.emit_err(UnescapeError::OutOfRangeHexEscape(span));
}
EscapeError::LeadingUnderscoreUnicodeEscape => {
let (c, span) = last_char();
- let msg = "invalid start of unicode escape";
- handler
- .struct_span_err(span, &format!("{}: `{}`", msg, c))
- .span_label(span, msg)
- .emit();
+ handler.emit_err(UnescapeError::LeadingUnderscoreUnicodeEscape {
+ span,
+ ch: escaped_char(c),
+ });
}
EscapeError::OverlongUnicodeEscape => {
- handler
- .struct_span_err(span, "overlong unicode escape")
- .span_label(span, "must have at most 6 hex digits")
- .emit();
+ handler.emit_err(UnescapeError::OverlongUnicodeEscape(span));
}
EscapeError::UnclosedUnicodeEscape => {
- handler
- .struct_span_err(span, "unterminated unicode escape")
- .span_label(span, "missing a closing `}`")
- .span_suggestion_verbose(
- span.shrink_to_hi(),
- "terminate the unicode escape",
- "}",
- Applicability::MaybeIncorrect,
- )
- .emit();
+ handler.emit_err(UnescapeError::UnclosedUnicodeEscape(span, span.shrink_to_hi()));
}
EscapeError::NoBraceInUnicodeEscape => {
- let msg = "incorrect unicode escape sequence";
- let mut diag = handler.struct_span_err(span, msg);
-
let mut suggestion = "\\u{".to_owned();
let mut suggestion_len = 0;
let (c, char_span) = last_char();
suggestion_len += c.len_utf8();
}
- if suggestion_len > 0 {
+ let (label, sub) = if suggestion_len > 0 {
suggestion.push('}');
let hi = char_span.lo() + BytePos(suggestion_len as u32);
- diag.span_suggestion(
- span.with_hi(hi),
- "format of unicode escape sequences uses braces",
- suggestion,
- Applicability::MaybeIncorrect,
- );
+ (None, NoBraceUnicodeSub::Suggestion { span: span.with_hi(hi), suggestion })
} else {
- diag.span_label(span, msg);
- diag.help("format of unicode escape sequences is `\\u{...}`");
- }
-
- diag.emit();
+ (Some(span), NoBraceUnicodeSub::Help)
+ };
+ handler.emit_err(UnescapeError::NoBraceInUnicodeEscape { span, label, sub });
}
EscapeError::UnicodeEscapeInByte => {
- let msg = "unicode escape in byte string";
- handler
- .struct_span_err(span, msg)
- .span_label(span, msg)
- .help("unicode escape sequences cannot be used as a byte or in a byte string")
- .emit();
+ handler.emit_err(UnescapeError::UnicodeEscapeInByte(span));
}
EscapeError::EmptyUnicodeEscape => {
- handler
- .struct_span_err(span, "empty unicode escape")
- .span_label(span, "this escape must have at least 1 hex digit")
- .emit();
+ handler.emit_err(UnescapeError::EmptyUnicodeEscape(span));
}
EscapeError::ZeroChars => {
- let msg = "empty character literal";
- handler.struct_span_err(span, msg).span_label(span, msg).emit();
+ handler.emit_err(UnescapeError::ZeroChars(span));
}
EscapeError::LoneSlash => {
- let msg = "invalid trailing slash in literal";
- handler.struct_span_err(span, msg).span_label(span, msg).emit();
+ handler.emit_err(UnescapeError::LoneSlash(span));
}
EscapeError::UnskippedWhitespaceWarning => {
let (c, char_span) = last_char();
- let msg =
- format!("non-ASCII whitespace symbol '{}' is not skipped", c.escape_unicode());
- handler.struct_span_warn(span, &msg).span_label(char_span, &msg).emit();
+ handler.emit_warning(UnescapeError::UnskippedWhitespace {
+ span,
+ ch: escaped_char(c),
+ char_span,
+ });
}
EscapeError::MultipleSkippedLinesWarning => {
- let msg = "multiple lines skipped by escaped newline";
- let bottom_msg = "skipping everything up to and including this point";
- handler.struct_span_warn(span, msg).span_label(span, bottom_msg).emit();
+ handler.emit_warning(UnescapeError::MultipleSkippedLinesWarning(span));
}
}
}
//! <https://www.unicode.org/Public/security/10.0.0/confusables.txt>
use super::StringReader;
-use crate::token::{self, Delimiter};
-use rustc_errors::{Applicability, Diagnostic};
+use crate::{
+ errors::TokenSubstitution,
+ token::{self, Delimiter},
+};
use rustc_span::{symbol::kw, BytePos, Pos, Span};
#[rustfmt::skip] // for line breaks
reader: &StringReader<'a>,
pos: BytePos,
ch: char,
- err: &mut Diagnostic,
count: usize,
-) -> Option<token::TokenKind> {
- let &(_, u_name, ascii_str) = UNICODE_ARRAY.iter().find(|&&(c, _, _)| c == ch)?;
+) -> (Option<token::TokenKind>, Option<TokenSubstitution>) {
+ let Some(&(_, u_name, ascii_str)) = UNICODE_ARRAY.iter().find(|&&(c, _, _)| c == ch) else {
+ return (None, None);
+ };
let span = Span::with_root_ctxt(pos, pos + Pos::from_usize(ch.len_utf8() * count));
let Some((_, ascii_name, token)) = ASCII_ARRAY.iter().find(|&&(s, _, _)| s == ascii_str) else {
let msg = format!("substitution character not found for '{}'", ch);
reader.sess.span_diagnostic.span_bug_no_panic(span, &msg);
- return None;
+ return (None, None);
};
// special help suggestion for "directed" double quotes
- if let Some(s) = peek_delimited(&reader.src[reader.src_index(pos)..], '“', '”') {
- let msg = format!(
- "Unicode characters '“' (Left Double Quotation Mark) and \
- '”' (Right Double Quotation Mark) look like '{}' ({}), but are not",
- ascii_str, ascii_name
- );
- err.span_suggestion(
- Span::with_root_ctxt(
- pos,
- pos + Pos::from_usize('“'.len_utf8() + s.len() + '”'.len_utf8()),
- ),
- &msg,
- format!("\"{}\"", s),
- Applicability::MaybeIncorrect,
+ let sugg = if let Some(s) = peek_delimited(&reader.src[reader.src_index(pos)..], '“', '”') {
+ let span = Span::with_root_ctxt(
+ pos,
+ pos + Pos::from_usize('“'.len_utf8() + s.len() + '”'.len_utf8()),
);
+ Some(TokenSubstitution::DirectedQuotes {
+ span,
+ suggestion: format!("\"{s}\""),
+ ascii_str,
+ ascii_name,
+ })
} else {
- let msg = format!(
- "Unicode character '{}' ({}) looks like '{}' ({}), but it is not",
- ch, u_name, ascii_str, ascii_name
- );
- err.span_suggestion(
+ let suggestion = ascii_str.to_string().repeat(count);
+ Some(TokenSubstitution::Other {
span,
- &msg,
- ascii_str.to_string().repeat(count),
- Applicability::MaybeIncorrect,
- );
- }
- token.clone()
+ suggestion,
+ ch: ch.to_string(),
+ u_name,
+ ascii_str,
+ ascii_name,
+ })
+ };
+ (token.clone(), sugg)
}
/// Extract string if found at current position with given delimiters
AttrWrapper, BlockMode, ClosureSpans, ForceCollect, Parser, PathStyle, Restrictions,
SemiColonMode, SeqSep, TokenExpectType, TokenType, TrailingToken,
};
+
use crate::errors;
use crate::maybe_recover_from_interpolated_ty_qpath;
use core::mem;
fn error_unexpected_after_dot(&self) {
// FIXME Could factor this out into non_fatal_unexpected or something.
let actual = pprust::token_to_string(&self.token);
- self.struct_span_err(self.token.span, &format!("unexpected token: `{actual}`")).emit();
+ self.sess.emit_err(errors::UnexpectedTokenAfterDot { span: self.token.span, actual });
}
// We need an identifier or integer, but the next token is a float.
-use crate::errors::{
- AmbiguousMissingKwForItemSub, AssociatedStaticItemNotAllowed, AsyncFnIn2015,
- BoundsNotAllowedOnTraitAliases, ConstGlobalCannotBeMutable, ConstLetMutuallyExclusive,
- DefaultNotFollowedByItem, DocCommentDoesNotDocumentAnything, EnumStructMutuallyExclusive,
- ExpectedTraitInTraitImplFoundType, ExternCrateNameWithDashes, ExternCrateNameWithDashesSugg,
- ExternItemCannotBeConst, HelpUseLatestEdition, MissingConstType, MissingForInTraitImpl,
- MissingKeywordForItemDefinition, MissingTraitInTraitImpl, SelfArgumentPointer,
- TraitAliasCannotBeAuto, TraitAliasCannotBeUnsafe, UnexpectedTokenAfterStructName,
- UseEmptyBlockNotSemi, VisibilityNotFollowedByItem,
-};
+use crate::errors;
use super::diagnostics::{dummy_arg, ConsumeClosingDelim};
use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign};
use super::{AttrWrapper, FollowedByType, ForceCollect, Parser, PathStyle, TrailingToken};
-use crate::errors::FnTypoWithImpl;
use rustc_ast::ast::*;
use rustc_ast::ptr::P;
use rustc_ast::token::{self, Delimiter, TokenKind};
// At this point, we have failed to parse an item.
if !matches!(vis.kind, VisibilityKind::Inherited) {
- self.sess.emit_err(VisibilityNotFollowedByItem { span: vis.span, vis });
+ self.sess.emit_err(errors::VisibilityNotFollowedByItem { span: vis.span, vis });
}
if let Defaultness::Default(span) = def {
- self.sess.emit_err(DefaultNotFollowedByItem { span });
+ self.sess.emit_err(errors::DefaultNotFollowedByItem { span });
}
if !attrs_allowed {
let err = if self.check(&token::OpenDelim(Delimiter::Brace)) {
// possible public struct definition where `struct` was forgotten
- Some(MissingKeywordForItemDefinition::Struct { span: sp, ident })
+ Some(errors::MissingKeywordForItemDefinition::Struct { span: sp, ident })
} else if self.check(&token::OpenDelim(Delimiter::Parenthesis)) {
// possible public function or tuple struct definition where `fn`/`struct` was
// forgotten
self.consume_block(Delimiter::Parenthesis, ConsumeClosingDelim::Yes);
- let err = if self.check(&token::RArrow)
- || self.check(&token::OpenDelim(Delimiter::Brace))
- {
- self.eat_to_tokens(&[&token::OpenDelim(Delimiter::Brace)]);
- self.bump(); // `{`
- self.consume_block(Delimiter::Brace, ConsumeClosingDelim::Yes);
- if is_method {
- MissingKeywordForItemDefinition::Method { span: sp, ident }
- } else {
- MissingKeywordForItemDefinition::Function { span: sp, ident }
- }
- } else if self.check(&token::Semi) {
- MissingKeywordForItemDefinition::Struct { span: sp, ident }
- } else {
- MissingKeywordForItemDefinition::Ambiguous {
- span: sp,
- subdiag: if found_generics {
- None
- } else if let Ok(snippet) = self.span_to_snippet(ident_sp) {
- Some(AmbiguousMissingKwForItemSub::SuggestMacro { span: full_sp, snippet })
+ let err =
+ if self.check(&token::RArrow) || self.check(&token::OpenDelim(Delimiter::Brace)) {
+ self.eat_to_tokens(&[&token::OpenDelim(Delimiter::Brace)]);
+ self.bump(); // `{`
+ self.consume_block(Delimiter::Brace, ConsumeClosingDelim::Yes);
+ if is_method {
+ errors::MissingKeywordForItemDefinition::Method { span: sp, ident }
} else {
- Some(AmbiguousMissingKwForItemSub::HelpMacro)
- },
- }
- };
+ errors::MissingKeywordForItemDefinition::Function { span: sp, ident }
+ }
+ } else if self.check(&token::Semi) {
+ errors::MissingKeywordForItemDefinition::Struct { span: sp, ident }
+ } else {
+ errors::MissingKeywordForItemDefinition::Ambiguous {
+ span: sp,
+ subdiag: if found_generics {
+ None
+ } else if let Ok(snippet) = self.span_to_snippet(ident_sp) {
+ Some(errors::AmbiguousMissingKwForItemSub::SuggestMacro {
+ span: full_sp,
+ snippet,
+ })
+ } else {
+ Some(errors::AmbiguousMissingKwForItemSub::HelpMacro)
+ },
+ }
+ };
Some(err)
} else if found_generics {
- Some(MissingKeywordForItemDefinition::Ambiguous { span: sp, subdiag: None })
+ Some(errors::MissingKeywordForItemDefinition::Ambiguous { span: sp, subdiag: None })
} else {
None
};
let ty_first = if self.token.is_keyword(kw::For) && self.look_ahead(1, |t| t != &token::Lt)
{
let span = self.prev_token.span.between(self.token.span);
- self.sess
- .emit_err(MissingTraitInTraitImpl { span, for_span: span.to(self.token.span) });
+ self.sess.emit_err(errors::MissingTraitInTraitImpl {
+ span,
+ for_span: span.to(self.token.span),
+ });
P(Ty {
kind: TyKind::Path(None, err_path(span)),
Some(ty_second) => {
// impl Trait for Type
if !has_for {
- self.sess.emit_err(MissingForInTraitImpl { span: missing_for_span });
+ self.sess.emit_err(errors::MissingForInTraitImpl { span: missing_for_span });
}
let ty_first = ty_first.into_inner();
// This notably includes paths passed through `ty` macro fragments (#46438).
TyKind::Path(None, path) => path,
_ => {
- self.sess
- .emit_err(ExpectedTraitInTraitImplFoundType { span: ty_first.span });
+ self.sess.emit_err(errors::ExpectedTraitInTraitImplFoundType {
+ span: ty_first.span,
+ });
err_path(ty_first.span)
}
};
// Recover `impl Ty;` instead of `impl Ty {}`
if self.token == TokenKind::Semi {
- self.sess.emit_err(UseEmptyBlockNotSemi { span: self.token.span });
+ self.sess.emit_err(errors::UseEmptyBlockNotSemi { span: self.token.span });
self.bump();
return Ok(vec![]);
}
// It's a trait alias.
if had_colon {
let span = span_at_colon.to(span_before_eq);
- self.sess.emit_err(BoundsNotAllowedOnTraitAliases { span });
+ self.sess.emit_err(errors::BoundsNotAllowedOnTraitAliases { span });
}
let bounds = self.parse_generic_bounds(None)?;
let whole_span = lo.to(self.prev_token.span);
if is_auto == IsAuto::Yes {
- self.sess.emit_err(TraitAliasCannotBeAuto { span: whole_span });
+ self.sess.emit_err(errors::TraitAliasCannotBeAuto { span: whole_span });
}
if let Unsafe::Yes(_) = unsafety {
- self.sess.emit_err(TraitAliasCannotBeUnsafe { span: whole_span });
+ self.sess.emit_err(errors::TraitAliasCannotBeUnsafe { span: whole_span });
}
self.sess.gated_spans.gate(sym::trait_alias, whole_span);
Ok(kind) => kind,
Err(kind) => match kind {
ItemKind::Static(a, _, b) => {
- self.sess.emit_err(AssociatedStaticItemNotAllowed { span });
+ self.sess.emit_err(errors::AssociatedStaticItemNotAllowed { span });
AssocItemKind::Const(Defaultness::Final, a, b)
}
_ => return self.error_bad_item_kind(span, &kind, "`trait`s or `impl`s"),
write!(fixed_name, "_{}", part.name).unwrap();
}
- self.sess.emit_err(ExternCrateNameWithDashes {
+ self.sess.emit_err(errors::ExternCrateNameWithDashes {
span: fixed_name_sp,
- sugg: ExternCrateNameWithDashesSugg { dashes },
+ sugg: errors::ExternCrateNameWithDashesSugg { dashes },
});
Ok(Ident::from_str_and_span(&fixed_name, fixed_name_sp))
Ok(kind) => kind,
Err(kind) => match kind {
ItemKind::Const(_, a, b) => {
- self.sess.emit_err(ExternItemCannotBeConst {
+ self.sess.emit_err(errors::ExternItemCannotBeConst {
ident_span: ident.span,
const_span: span.with_hi(ident.span.lo()),
});
fn recover_const_mut(&mut self, const_span: Span) {
if self.eat_keyword(kw::Mut) {
let span = self.prev_token.span;
- self.sess.emit_err(ConstGlobalCannotBeMutable { ident_span: span, const_span });
+ self.sess.emit_err(errors::ConstGlobalCannotBeMutable { ident_span: span, const_span });
} else if self.eat_keyword(kw::Let) {
let span = self.prev_token.span;
- self.sess.emit_err(ConstLetMutuallyExclusive { span: const_span.to(span) });
+ self.sess.emit_err(errors::ConstLetMutuallyExclusive { span: const_span.to(span) });
}
}
let span = self.prev_token.span.shrink_to_hi();
let err: DiagnosticBuilder<'_, ErrorGuaranteed> =
- MissingConstType { span, colon, kind }.into_diagnostic(&self.sess.span_diagnostic);
+ errors::MissingConstType { span, colon, kind }
+ .into_diagnostic(&self.sess.span_diagnostic);
err.stash(span, StashKey::ItemNoType);
// The user intended that the type be inferred,
fn parse_item_enum(&mut self) -> PResult<'a, ItemInfo> {
if self.token.is_keyword(kw::Struct) {
let span = self.prev_token.span.to(self.token.span);
- let err = EnumStructMutuallyExclusive { span };
+ let err = errors::EnumStructMutuallyExclusive { span };
if self.look_ahead(1, |t| t.is_ident()) {
self.bump();
self.sess.emit_err(err);
// Possibly recover `enum Foo;` instead of `enum Foo {}`
let (variants, _) = if self.token == TokenKind::Semi {
- self.sess.emit_err(UseEmptyBlockNotSemi { span: self.token.span });
+ self.sess.emit_err(errors::UseEmptyBlockNotSemi { span: self.token.span });
self.bump();
(vec![], false)
} else {
self.expect_semi()?;
body
} else {
- let err = UnexpectedTokenAfterStructName::new(self.token.span, self.token.clone());
+ let err =
+ errors::UnexpectedTokenAfterStructName::new(self.token.span, self.token.clone());
return Err(err.into_diagnostic(&self.sess.span_diagnostic));
};
token::CloseDelim(Delimiter::Brace) => {}
token::DocComment(..) => {
let previous_span = self.prev_token.span;
- let mut err = DocCommentDoesNotDocumentAnything {
+ let mut err = errors::DocCommentDoesNotDocumentAnything {
span: self.token.span,
missing_comma: None,
};
// If we see `for Ty ...` then user probably meant `impl` item.
if self.token.is_keyword(kw::For) {
old_err.cancel();
- return Err(self.sess.create_err(FnTypoWithImpl { fn_span }));
+ return Err(self.sess.create_err(errors::FnTypoWithImpl { fn_span }));
} else {
return Err(old_err);
}
if let Async::Yes { span, .. } = asyncness {
if span.is_rust_2015() {
- self.sess.emit_err(AsyncFnIn2015 { span, help: HelpUseLatestEdition::new() });
+ self.sess.emit_err(errors::AsyncFnIn2015 {
+ span,
+ help: errors::HelpUseLatestEdition::new(),
+ });
}
}
};
// Recover for the grammar `*self`, `*const self`, and `*mut self`.
let recover_self_ptr = |this: &mut Self| {
- self.sess.emit_err(SelfArgumentPointer { span: this.token.span });
+ self.sess.emit_err(errors::SelfArgumentPointer { span: this.token.span });
Ok((SelfKind::Value(Mutability::Not), expect_self_ident(this), this.prev_token.span))
};
// `where`, so stop if it's it.
// We also continue if we find types (not traits), again for error recovery.
while self.can_begin_bound()
- || self.token.can_begin_type()
- || (self.token.is_reserved_ident() && !self.token.is_keyword(kw::Where))
+ || (self.may_recover()
+ && (self.token.can_begin_type()
+ || (self.token.is_reserved_ident() && !self.token.is_keyword(kw::Where))))
{
if self.token.is_keyword(kw::Dyn) {
// Account for `&dyn Trait + dyn Other`.
"what location details should be tracked when using caller_location, either \
`none`, or a comma separated list of location details, for which \
valid options are `file`, `line`, and `column` (default: `file,line,column`)"),
- log_backtrace: Option<String> = (None, parse_opt_string, [TRACKED],
- "add a backtrace along with logging"),
ls: bool = (false, parse_bool, [UNTRACKED],
"list the symbols defined by a library crate (default: no)"),
macro_backtrace: bool = (false, parse_bool, [UNTRACKED],
use overflow::OverflowData;
use rustc_index::vec::IndexVec;
use rustc_middle::ty::TyCtxt;
-use std::collections::hash_map::Entry;
+use std::{collections::hash_map::Entry, mem};
rustc_index::newtype_index! {
pub struct StackDepth {}
let provisional_entry_index = *cache.lookup_table.get(&goal).unwrap();
let provisional_entry = &mut cache.entries[provisional_entry_index];
let depth = provisional_entry.depth;
+ // We eagerly update the response in the cache here. If we have to reevaluate
+ // this goal we use the new response when hitting a cycle, and we definitely
+ // want to access the final response whenever we look at the cache.
+ let prev_response = mem::replace(&mut provisional_entry.response, response);
+
// Was the current goal the root of a cycle and was the provisional response
// different from the final one.
- if has_been_used && provisional_entry.response != response {
- // If so, update the provisional reponse for this goal...
- provisional_entry.response = response;
- // ...remove all entries whose result depends on this goal
+ if has_been_used && prev_response != response {
+ // If so, remove all entries whose result depends on this goal
// from the provisional cache...
//
// That's not completely correct, as a nested goal can also
impl<I: Interner> PartialEq for TyKind<I> {
#[inline]
fn eq(&self, other: &TyKind<I>) -> bool {
- tykind_discriminant(self) == tykind_discriminant(other)
- && match (self, other) {
- (Int(a_i), Int(b_i)) => a_i == b_i,
- (Uint(a_u), Uint(b_u)) => a_u == b_u,
- (Float(a_f), Float(b_f)) => a_f == b_f,
- (Adt(a_d, a_s), Adt(b_d, b_s)) => a_d == b_d && a_s == b_s,
- (Foreign(a_d), Foreign(b_d)) => a_d == b_d,
- (Array(a_t, a_c), Array(b_t, b_c)) => a_t == b_t && a_c == b_c,
- (Slice(a_t), Slice(b_t)) => a_t == b_t,
- (RawPtr(a_t), RawPtr(b_t)) => a_t == b_t,
- (Ref(a_r, a_t, a_m), Ref(b_r, b_t, b_m)) => a_r == b_r && a_t == b_t && a_m == b_m,
- (FnDef(a_d, a_s), FnDef(b_d, b_s)) => a_d == b_d && a_s == b_s,
- (FnPtr(a_s), FnPtr(b_s)) => a_s == b_s,
- (Dynamic(a_p, a_r, a_repr), Dynamic(b_p, b_r, b_repr)) => {
- a_p == b_p && a_r == b_r && a_repr == b_repr
- }
- (Closure(a_d, a_s), Closure(b_d, b_s)) => a_d == b_d && a_s == b_s,
- (Generator(a_d, a_s, a_m), Generator(b_d, b_s, b_m)) => {
- a_d == b_d && a_s == b_s && a_m == b_m
- }
- (GeneratorWitness(a_g), GeneratorWitness(b_g)) => a_g == b_g,
- (
- &GeneratorWitnessMIR(ref a_d, ref a_s),
- &GeneratorWitnessMIR(ref b_d, ref b_s),
- ) => a_d == b_d && a_s == b_s,
- (Tuple(a_t), Tuple(b_t)) => a_t == b_t,
- (Alias(a_i, a_p), Alias(b_i, b_p)) => a_i == b_i && a_p == b_p,
- (Param(a_p), Param(b_p)) => a_p == b_p,
- (Bound(a_d, a_b), Bound(b_d, b_b)) => a_d == b_d && a_b == b_b,
- (Placeholder(a_p), Placeholder(b_p)) => a_p == b_p,
- (Infer(a_t), Infer(b_t)) => a_t == b_t,
- (Error(a_e), Error(b_e)) => a_e == b_e,
- (Bool, Bool) | (Char, Char) | (Str, Str) | (Never, Never) => true,
- _ => {
- debug_assert!(
- false,
- "This branch must be unreachable, maybe the match is missing an arm? self = self = {self:?}, other = {other:?}"
- );
- true
- }
+ // You might expect this `match` to be preceded with this:
+ //
+ // tykind_discriminant(self) == tykind_discriminant(other) &&
+ //
+ // but the data patterns in practice are such that a comparison
+ // succeeds 99%+ of the time, and it's faster to omit it.
+ match (self, other) {
+ (Int(a_i), Int(b_i)) => a_i == b_i,
+ (Uint(a_u), Uint(b_u)) => a_u == b_u,
+ (Float(a_f), Float(b_f)) => a_f == b_f,
+ (Adt(a_d, a_s), Adt(b_d, b_s)) => a_d == b_d && a_s == b_s,
+ (Foreign(a_d), Foreign(b_d)) => a_d == b_d,
+ (Array(a_t, a_c), Array(b_t, b_c)) => a_t == b_t && a_c == b_c,
+ (Slice(a_t), Slice(b_t)) => a_t == b_t,
+ (RawPtr(a_t), RawPtr(b_t)) => a_t == b_t,
+ (Ref(a_r, a_t, a_m), Ref(b_r, b_t, b_m)) => a_r == b_r && a_t == b_t && a_m == b_m,
+ (FnDef(a_d, a_s), FnDef(b_d, b_s)) => a_d == b_d && a_s == b_s,
+ (FnPtr(a_s), FnPtr(b_s)) => a_s == b_s,
+ (Dynamic(a_p, a_r, a_repr), Dynamic(b_p, b_r, b_repr)) => {
+ a_p == b_p && a_r == b_r && a_repr == b_repr
}
+ (Closure(a_d, a_s), Closure(b_d, b_s)) => a_d == b_d && a_s == b_s,
+ (Generator(a_d, a_s, a_m), Generator(b_d, b_s, b_m)) => {
+ a_d == b_d && a_s == b_s && a_m == b_m
+ }
+ (GeneratorWitness(a_g), GeneratorWitness(b_g)) => a_g == b_g,
+ (&GeneratorWitnessMIR(ref a_d, ref a_s), &GeneratorWitnessMIR(ref b_d, ref b_s)) => {
+ a_d == b_d && a_s == b_s
+ }
+ (Tuple(a_t), Tuple(b_t)) => a_t == b_t,
+ (Alias(a_i, a_p), Alias(b_i, b_p)) => a_i == b_i && a_p == b_p,
+ (Param(a_p), Param(b_p)) => a_p == b_p,
+ (Bound(a_d, a_b), Bound(b_d, b_b)) => a_d == b_d && a_b == b_b,
+ (Placeholder(a_p), Placeholder(b_p)) => a_p == b_p,
+ (Infer(a_t), Infer(b_t)) => a_t == b_t,
+ (Error(a_e), Error(b_e)) => a_e == b_e,
+ (Bool, Bool) | (Char, Char) | (Str, Str) | (Never, Never) => true,
+ _ => {
+ debug_assert!(
+ tykind_discriminant(self) != tykind_discriminant(other),
+ "This branch must be unreachable, maybe the match is missing an arm? self = self = {self:?}, other = {other:?}"
+ );
+ false
+ }
+ }
}
}
(Error(a_e), Error(b_e)) => a_e.cmp(b_e),
(Bool, Bool) | (Char, Char) | (Str, Str) | (Never, Never) => Ordering::Equal,
_ => {
- debug_assert!(false, "This branch must be unreachable, maybe the match is missing an arm? self = self = {self:?}, other = {other:?}");
+ debug_assert!(false, "This branch must be unreachable, maybe the match is missing an arm? self = {self:?}, other = {other:?}");
Ordering::Equal
}
}
#![feature(const_eval_select)]
#![feature(const_pin)]
#![feature(const_waker)]
-#![feature(cstr_from_bytes_until_nul)]
#![feature(dispatch_from_dyn)]
#![feature(error_generic_member_access)]
#![feature(error_in_core)]
}
}
-#[unstable(feature = "cstr_from_bytes_until_nul", issue = "95027")]
+#[stable(feature = "cstr_from_bytes_until_nul", since = "CURRENT_RUSTC_VERSION")]
impl Error for crate::ffi::FromBytesUntilNulError {}
#[unstable(feature = "get_many_mut", issue = "104642")]
/// This error is created by the [`CStr::from_bytes_until_nul`] method.
///
#[derive(Clone, PartialEq, Eq, Debug)]
-#[unstable(feature = "cstr_from_bytes_until_nul", issue = "95027")]
+#[stable(feature = "cstr_from_bytes_until_nul", since = "CURRENT_RUSTC_VERSION")]
pub struct FromBytesUntilNulError(());
-#[unstable(feature = "cstr_from_bytes_until_nul", issue = "95027")]
+#[stable(feature = "cstr_from_bytes_until_nul", since = "CURRENT_RUSTC_VERSION")]
impl fmt::Display for FromBytesUntilNulError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "data provided does not contain a nul")
///
/// # Examples
/// ```
- /// #![feature(cstr_from_bytes_until_nul)]
- ///
/// use std::ffi::CStr;
///
/// let mut buffer = [0u8; 16];
/// assert_eq!(c_str.to_str().unwrap(), "AAAAAAAA");
/// ```
///
- #[unstable(feature = "cstr_from_bytes_until_nul", issue = "95027")]
- #[rustc_const_unstable(feature = "cstr_from_bytes_until_nul", issue = "95027")]
+ #[rustc_allow_const_fn_unstable(const_slice_index)]
+ #[stable(feature = "cstr_from_bytes_until_nul", since = "CURRENT_RUSTC_VERSION")]
+ #[rustc_const_stable(feature = "cstr_from_bytes_until_nul", since = "CURRENT_RUSTC_VERSION")]
pub const fn from_bytes_until_nul(bytes: &[u8]) -> Result<&CStr, FromBytesUntilNulError> {
let nul_pos = memchr::memchr(0, bytes);
match nul_pos {
/// bytes where the borrow propagated all the way to the most significant
/// bit."
#[inline]
+#[rustc_const_stable(feature = "const_memchr", since = "1.65.0")]
const fn contains_zero_byte(x: usize) -> bool {
x.wrapping_sub(LO_USIZE) & !x & HI_USIZE != 0
}
-#[cfg(target_pointer_width = "16")]
#[inline]
+#[cfg(target_pointer_width = "16")]
+#[rustc_const_stable(feature = "const_memchr", since = "1.65.0")]
const fn repeat_byte(b: u8) -> usize {
(b as usize) << 8 | b as usize
}
-#[cfg(not(target_pointer_width = "16"))]
#[inline]
+#[cfg(not(target_pointer_width = "16"))]
+#[rustc_const_stable(feature = "const_memchr", since = "1.65.0")]
const fn repeat_byte(b: u8) -> usize {
(b as usize) * (usize::MAX / 255)
}
/// Returns the first index matching the byte `x` in `text`.
-#[must_use]
#[inline]
+#[must_use]
+#[rustc_const_stable(feature = "const_memchr", since = "1.65.0")]
pub const fn memchr(x: u8, text: &[u8]) -> Option<usize> {
// Fast path for small slices.
if text.len() < 2 * USIZE_BYTES {
}
#[inline]
+#[rustc_const_stable(feature = "const_memchr", since = "1.65.0")]
const fn memchr_naive(x: u8, text: &[u8]) -> Option<usize> {
let mut i = 0;
None
}
+#[rustc_allow_const_fn_unstable(const_cmp)]
+#[rustc_allow_const_fn_unstable(const_slice_index)]
+#[rustc_allow_const_fn_unstable(const_align_offset)]
+#[rustc_const_stable(feature = "const_memchr", since = "1.65.0")]
const fn memchr_aligned(x: u8, text: &[u8]) -> Option<usize> {
// Scan for a single byte value by reading two `usize` words at a time.
//
#![feature(char_error_internals)]
#![feature(char_internals)]
#![feature(core_intrinsics)]
-#![feature(cstr_from_bytes_until_nul)]
#![feature(cstr_internals)]
#![feature(duration_constants)]
#![feature(error_generic_member_access)]
}
}
+#[stable(feature = "asfd_rc", since = "CURRENT_RUSTC_VERSION")]
+impl<T: AsFd> AsFd for crate::rc::Rc<T> {
+ #[inline]
+ fn as_fd(&self) -> BorrowedFd<'_> {
+ (**self).as_fd()
+ }
+}
+
#[stable(feature = "asfd_ptrs", since = "1.64.0")]
impl<T: AsFd> AsFd for Box<T> {
#[inline]
}
}
+#[stable(feature = "asfd_rc", since = "CURRENT_RUSTC_VERSION")]
+impl<T: AsRawFd> AsRawFd for crate::rc::Rc<T> {
+ #[inline]
+ fn as_raw_fd(&self) -> RawFd {
+ (**self).as_raw_fd()
+ }
+}
+
#[stable(feature = "asrawfd_ptrs", since = "1.63.0")]
impl<T: AsRawFd> AsRawFd for Box<T> {
#[inline]
# If curl is not present on Win32, we should not sys.exit
# but raise `CalledProcessError` or `OSError` instead
require(["curl", "--version"], exception=platform_is_win32)
- run(["curl", option,
- "-L", # Follow redirect.
- "-y", "30", "-Y", "10", # timeout if speed is < 10 bytes/sec for > 30 seconds
- "--connect-timeout", "30", # timeout if cannot connect within 30 seconds
- "--retry", "3", "-Sf", "-o", path, url],
- verbose=verbose,
- exception=True, # Will raise RuntimeError on failure
- )
+ with open(path, "wb") as outfile:
+ run(["curl", option,
+ "-L", # Follow redirect.
+ "-y", "30", "-Y", "10", # timeout if speed is < 10 bytes/sec for > 30 seconds
+ "--connect-timeout", "30", # timeout if cannot connect within 30 seconds
+ "--retry", "3", "-Sf", url],
+ stdout=outfile, #Implements cli redirect operator '>'
+ verbose=verbose,
+ exception=True, # Will raise RuntimeError on failure
+ )
except (subprocess.CalledProcessError, OSError, RuntimeError):
# see http://serverfault.com/questions/301128/how-to-download
if platform_is_win32:
)
exit_code = 0
+ success_word = "successfully"
try:
bootstrap(args)
except (SystemExit, KeyboardInterrupt) as error:
else:
exit_code = 1
print(error)
+ success_word = "unsuccessfully"
if not help_triggered:
- print("Build completed successfully in", format_build_time(time() - start_time))
+ print("Build completed", success_word, "in", format_build_time(time() - start_time))
sys.exit(exit_code)
}
/// A list of historical hashes of `src/etc/vscode_settings.json`.
-/// New entries should be appended whenever this is updated so we can detected
+/// New entries should be appended whenever this is updated so we can detect
/// outdated vs. user-modified settings files.
-static SETTINGS_HASHES: &[&str] =
- &["ea67e259dedf60d4429b6c349a564ffcd1563cf41c920a856d1f5b16b4701ac8"];
+static SETTINGS_HASHES: &[&str] = &[
+ "ea67e259dedf60d4429b6c349a564ffcd1563cf41c920a856d1f5b16b4701ac8",
+ "56e7bf011c71c5d81e0bf42e84938111847a810eee69d906bba494ea90b51922",
+];
static VSCODE_SETTINGS: &str = include_str!("../etc/vscode_settings.json");
impl Profile {
{
+ "rust-analyzer.check.invocationLocation": "root",
+ "rust-analyzer.check.invocationStrategy": "once",
"rust-analyzer.checkOnSave.overrideCommand": [
"python3",
"x.py",
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="Capa_1" width="27.434" height="29.5" enable-background="new 0 0 27.434 29.5" version="1.1" viewBox="0 0 27.434 29.5" xml:space="preserve"><g><path d="M27.315,18.389c-0.165-0.604-0.509-1.113-0.981-1.459c-0.042-0.144-0.083-0.429-0.015-0.761l0.037-0.177v-0.182V14.8 c0-1.247-0.006-1.277-0.048-1.472c-0.076-0.354-0.035-0.653,0.007-0.803c0.477-0.346,0.828-0.861,0.996-1.476 c0.261-0.956,0.076-2.091-0.508-3.114l-0.591-1.032c-0.746-1.307-1.965-2.119-3.182-2.119c-0.378,0-0.75,0.081-1.085,0.235 c-0.198-0.025-0.554-0.15-0.855-0.389l-0.103-0.082l-0.114-0.065l-1.857-1.067L18.92,3.36l-0.105-0.044 c-0.376-0.154-0.658-0.41-0.768-0.556C17.918,1.172,16.349,0,14.296,0H13.14c-2.043,0-3.608,1.154-3.749,2.721 C9.277,2.862,8.999,3.104,8.633,3.25l-0.1,0.039L8.439,3.341L6.495,4.406L6.363,4.479L6.245,4.573 C5.936,4.82,5.596,4.944,5.416,4.977c-0.314-0.139-0.66-0.21-1.011-0.21c-1.198,0-2.411,0.819-3.165,2.139L0.65,7.938 c-0.412,0.72-0.642,1.521-0.644,2.258c-0.003,0.952,0.362,1.756,1.013,2.256c0.034,0.155,0.061,0.448-0.016,0.786 c-0.038,0.168-0.062,0.28-0.062,1.563c0,1.148,0,1.148,0.015,1.262l0.009,0.073l0.017,0.073c0.073,0.346,0.045,0.643,0.011,0.802 C0.348,17.512-0.01,18.314,0,19.268c0.008,0.729,0.238,1.523,0.648,2.242l0.589,1.031c0.761,1.331,1.967,2.159,3.15,2.159 c0.324,0,0.645-0.064,0.938-0.187c0.167,0.038,0.492,0.156,0.813,0.416l0.11,0.088l0.124,0.07l2.045,1.156l0.102,0.057l0.107,0.043 c0.364,0.147,0.646,0.381,0.766,0.521c0.164,1.52,1.719,2.634,3.745,2.634h1.155c2.037,0,3.598-1.134,3.747-2.675 c0.117-0.145,0.401-0.393,0.774-0.549l0.111-0.047l0.105-0.062l1.96-1.159l0.105-0.062l0.097-0.075 c0.309-0.246,0.651-0.371,0.832-0.402c0.313,0.138,0.662,0.212,1.016,0.212c1.199,0,2.412-0.82,3.166-2.139l0.59-1.032 C27.387,20.48,27.575,19.342,27.315,18.389z M25.274,20.635l-0.59,1.032c-0.438,0.765-1.104,1.251-1.639,1.251 c-0.133,0-0.258-0.029-0.369-0.094c-0.15-0.086-0.346-0.127-0.566-0.127c-0.596,0-1.383,0.295-2.01,0.796l-1.96,1.157 c-1.016,0.425-1.846,1.291-1.846,1.929s-0.898,1.159-1.998,1.159H13.14c-1.1,0-1.998-0.514-1.998-1.141s-0.834-1.477-1.854-1.888 l-2.046-1.157c-0.636-0.511-1.425-0.814-2.006-0.814c-0.202,0-0.379,0.037-0.516,0.115c-0.101,0.057-0.214,0.084-0.333,0.084 c-0.518,0-1.179-0.498-1.62-1.271l-0.591-1.032c-0.545-0.954-0.556-1.983-0.024-2.286c0.532-0.305,0.78-1.432,0.551-2.506 c0,0,0-0.003,0-1.042c0-1.088,0.021-1.18,0.021-1.18c0.238-1.072-0.01-2.203-0.552-2.513C1.631,10.8,1.634,9.765,2.18,8.812 L2.769,7.78c0.438-0.766,1.103-1.251,1.636-1.251c0.131,0,0.255,0.029,0.365,0.092C4.92,6.707,5.114,6.747,5.334,6.747 c0.596,0,1.38-0.296,2.007-0.795l1.944-1.065c1.021-0.407,1.856-1.277,1.856-1.933c0-0.656,0.898-1.192,1.998-1.192h1.156V1.761 c1.1,0,1.998,0.545,1.998,1.211c0,0.667,0.832,1.554,1.849,1.973L20,6.013c0.618,0.489,1.401,0.775,2.012,0.775 c0.24,0,0.454-0.045,0.62-0.139c0.122-0.069,0.259-0.102,0.403-0.102c0.551,0,1.221,0.476,1.653,1.231l0.59,1.032 c0.544,0.953,0.518,2.004-0.062,2.334c-0.577,0.331-0.859,1.48-0.627,2.554c0,0,0.01,0.042,0.01,1.103c0,1.012,0,1.012,0,1.012 c-0.218,1.049,0.068,2.174,0.636,2.498C25.802,18.635,25.819,19.68,25.274,20.635z"/><path d="M13.61,7.611c-3.913,0-7.084,3.173-7.084,7.085c0,3.914,3.171,7.085,7.084,7.085s7.085-3.172,7.085-7.085 C20.695,10.784,17.523,7.611,13.61,7.611z M13.61,20.02c-2.936,0-5.323-2.388-5.323-5.323c0-2.935,2.388-5.323,5.323-5.323 s5.324,2.388,5.324,5.323C18.934,17.632,16.546,20.02,13.61,20.02z"/><path d="M13.682,9.908c-2.602,0-4.718,2.116-4.718,4.718c0,2.601,2.116,4.716,4.718,4.716c2.601,0,4.717-2.115,4.717-4.716 C18.399,12.024,16.283,9.908,13.682,9.908z M13.682,17.581c-1.633,0-2.956-1.323-2.956-2.955s1.323-2.956,2.956-2.956 c1.632,0,2.956,1.324,2.956,2.956S15.314,17.581,13.682,17.581z"/></g></svg>
\ No newline at end of file
+<svg xmlns="http://www.w3.org/2000/svg" width="27.434" height="29.5" enable-background="new 0 0 27.434 29.5" viewBox="0 0 27.434 29.5"><path d="M27.316 18.39a2.696 2.696 0 0 0-.98-1.46 1.62 1.62 0 0 1-.016-.762l.035-.176v-1.191c0-1.246-.003-1.278-.046-1.473a1.717 1.717 0 0 1 .007-.805c.477-.343.829-.859.997-1.472.257-.957.074-2.094-.508-3.117l-.594-1.032c-.746-1.304-1.965-2.117-3.18-2.117-.379 0-.75.078-1.086.235a1.958 1.958 0 0 1-.855-.391l-.102-.082-.117-.063-1.855-1.07-.094-.055-.106-.043c-.378-.156-.66-.41-.77-.554C17.919 1.172 16.349 0 14.297 0h-1.155c-2.043 0-3.61 1.152-3.75 2.723-.114.14-.391.382-.758.527l-.102.04-.094.05-1.94 1.066-.134.074-.117.094a2.019 2.019 0 0 1-.832.403 2.518 2.518 0 0 0-1.008-.211c-1.199 0-2.414.82-3.168 2.14l-.59 1.032c-.41.718-.64 1.523-.64 2.257-.004.953.36 1.758 1.012 2.258.035.152.058.445-.016.785-.04.168-.063.282-.063 1.563 0 1.148 0 1.148.016 1.261l.008.075.015.074c.075.344.047.64.012.8-.644.5-1.004 1.302-.992 2.259.008.726.238 1.52.648 2.242l.59 1.027c.758 1.332 1.965 2.16 3.149 2.16.324 0 .644-.062.937-.187.168.039.492.156.813.418l.11.086.124.07 2.047 1.156.102.059.105.043c.363.144.648.379.766.52.164 1.519 1.718 2.632 3.746 2.632h1.156c2.035 0 3.598-1.133 3.746-2.672.117-.144.402-.394.773-.55l.114-.047.101-.063 1.961-1.156.106-.063.097-.078c.309-.246.653-.37.832-.398.313.136.66.21 1.016.21 1.2 0 2.41-.82 3.164-2.14l.594-1.031c.59-1.028.777-2.164.52-3.117Zm-2.043 2.247-.59 1.031c-.437.766-1.105 1.25-1.636 1.25a.7.7 0 0 1-.371-.094 1.146 1.146 0 0 0-.567-.129c-.593 0-1.382.297-2.007.797l-1.961 1.156c-1.016.426-1.848 1.293-1.848 1.93 0 .64-.898 1.16-1.996 1.16H13.14c-1.102 0-2-.515-2-1.14 0-.63-.832-1.477-1.852-1.887l-2.047-1.16c-.637-.512-1.426-.813-2.008-.813-.199 0-.379.035-.515.114a.648.648 0 0 1-.332.085c-.52 0-1.18-.5-1.621-1.273l-.59-1.031c-.543-.953-.555-1.98-.024-2.285.532-.305.782-1.434.551-2.504V14.8c0-1.09.02-1.18.02-1.18.238-1.074-.008-2.203-.551-2.516-.54-.304-.54-1.34.008-2.293l.59-1.03c.437-.766 1.101-1.255 1.636-1.255a.73.73 0 0 1 .364.094c.152.086.343.125.566.125.594 0 1.379-.297 2.004-.793l1.945-1.066c1.02-.407 1.856-1.278 1.856-1.934 0-.656.898-1.191 2-1.191h1.156c1.098 0 1.996.543 1.996 1.21 0 .669.832 1.555 1.848 1.973L20 6.012c.617.492 1.402.777 2.012.777.242 0 .453-.047.62-.14a.79.79 0 0 1 .403-.102c.55 0 1.223.476 1.652 1.23l.59 1.032c.543.953.52 2.004-.062 2.336-.574.332-.86 1.48-.625 2.554 0 0 .008.04.008 1.102v1.011c-.215 1.051.07 2.176.636 2.5.567.325.586 1.368.04 2.325Zm0 0"/><path d="M13.61 7.61a7.084 7.084 0 0 0-7.083 7.085 7.085 7.085 0 1 0 14.168 0A7.088 7.088 0 0 0 13.61 7.61Zm0 12.41a5.33 5.33 0 0 1-5.325-5.325 5.33 5.33 0 0 1 5.324-5.32 5.327 5.327 0 0 1 5.325 5.32 5.328 5.328 0 0 1-5.325 5.325Zm0 0"/><path d="M13.684 9.906a4.722 4.722 0 0 0-4.72 4.719 4.722 4.722 0 0 0 4.72 4.719 4.724 4.724 0 0 0 4.714-4.719 4.724 4.724 0 0 0-4.714-4.719Zm0 7.676a2.954 2.954 0 1 1 0-5.91 2.953 2.953 0 0 1 2.953 2.953 2.957 2.957 0 0 1-2.953 2.957Zm0 0"/></svg>
\ No newline at end of file
//@ignore-target-windows: No libc on Windows
-#![feature(cstr_from_bytes_until_nul)]
use std::ffi::{CStr, CString};
use std::thread;
-Z llvm-plugins=val -- a list LLVM plugins to enable (space separated)
-Z llvm-time-trace=val -- generate JSON tracing data file from LLVM data (default: no)
-Z location-detail=val -- what location details should be tracked when using caller_location, either `none`, or a comma separated list of location details, for which valid options are `file`, `line`, and `column` (default: `file,line,column`)
- -Z log-backtrace=val -- add a backtrace along with logging
-Z ls=val -- list the symbols defined by a library crate (default: no)
-Z macro-backtrace=val -- show macro backtraces (default: no)
-Z maximal-hir-to-mir-coverage=val -- save as much information as possible about the correspondence between MIR and HIR as source scopes (default: no)
// run-pass
//
-// This test makes sure that log-backtrace option doesn't give a compilation error.
+// This test makes sure that log-backtrace option at least parses correctly
//
// dont-check-compiler-stdout
// dont-check-compiler-stderr
// rustc-env:RUSTC_LOG=info
-// compile-flags: -Zlog-backtrace=rustc_metadata::creader
+// rustc-env:RUSTC_LOG_BACKTRACE=rustc_metadata::creader
fn main() {}
//~^^ this was previously accepted
}
+// Again, currently allowed, but will be phased out.
+#[derive(Debug)]
+#[repr(packed)]
+struct WithStr {
+ width: u8,
+ data: str,
+ //~^ WARNING string slice in a packed struct that derives a built-in trait
+ //~^^ this was previously accepted
+}
+
fn main() {}
= note: `#[warn(byte_slice_in_packed_struct_with_derive)]` on by default
= note: this warning originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
+warning: string slice in a packed struct that derives a built-in trait
+ --> $DIR/deriving-with-repr-packed.rs:41:5
+ |
+LL | #[derive(Debug)]
+ | ----- in this derive macro expansion
+...
+LL | data: str,
+ | ^^^^^^^^^
+ |
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #107457 <https://github.com/rust-lang/rust/issues/107457>
+ = help: consider implementing the trait by hand, or remove the `packed` attribute
+ = note: this warning originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
+
error[E0507]: cannot move out of `self` which is behind a shared reference
--> $DIR/deriving-with-repr-packed.rs:22:10
|
|
= note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
-error: aborting due to previous error; 1 warning emitted
+error: aborting due to previous error; 2 warnings emitted
For more information about this error, try `rustc --explain E0507`.
Future incompatibility report: Future breakage diagnostic:
= note: `#[warn(byte_slice_in_packed_struct_with_derive)]` on by default
= note: this warning originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
+Future breakage diagnostic:
+warning: string slice in a packed struct that derives a built-in trait
+ --> $DIR/deriving-with-repr-packed.rs:41:5
+ |
+LL | #[derive(Debug)]
+ | ----- in this derive macro expansion
+...
+LL | data: str,
+ | ^^^^^^^^^
+ |
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #107457 <https://github.com/rust-lang/rust/issues/107457>
+ = help: consider implementing the trait by hand, or remove the `packed` attribute
+ = note: `#[warn(byte_slice_in_packed_struct_with_derive)]` on by default
+ = note: this warning originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
+
--- /dev/null
+// check-pass
+
+// edition:2021
+// for the `impl` + keyword test
+
+macro_rules! impl_primitive {
+ ($ty:ty) => {
+ compile_error!("whoops");
+ };
+ (impl async) => {};
+}
+
+impl_primitive!(impl async);
+
+fn main() {}
--- /dev/null
+// check-pass
+
+macro_rules! impl_primitive {
+ ($ty:ty) => { impl_primitive!(impl $ty); };
+ (impl $ty:ty) => { fn a(_: $ty) {} }
+}
+
+impl_primitive! { u8 }
+
+macro_rules! test {
+ ($ty:ty) => { compile_error!("oh no"); };
+ (impl &) => {};
+}
+
+test!(impl &);
+
+fn main() {}
--- /dev/null
+// ignore-tidy-linelength
+
+fn main() {
+ let s: &str = r################################################################################################################################################################################################################################################################"very raw"################################################################################################################################################################################################################################################################;
+ //~^ ERROR too many `#` symbols: raw strings may be delimited by up to 255 `#` symbols, but found 256
+}
--- /dev/null
+error: too many `#` symbols: raw strings may be delimited by up to 255 `#` symbols, but found 256
+ --> $DIR/too-many-hash.rs:4:19
+ |
+LL | ... = r################################################################################################################################################################################################################################################################"very raw"##############################################################################################################################################################################################################################################################...
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
--- /dev/null
+// known-bug: unknown
+// compile-flags: -Ztrait-solver=next
+// failure-status: 101
+// normalize-stderr-test "note: .*\n\n" -> ""
+// normalize-stderr-test "thread 'rustc' panicked.*\n" -> ""
+// rustc-env:RUST_BACKTRACE=0
+
+// This tests checks that we update results in the provisional cache when
+// we pop a goal from the stack.
+#![feature(auto_traits)]
+auto trait Coinductive {}
+struct Foo<T>(T);
+struct Bar<T>(T);
+
+impl<T> Coinductive for Foo<T>
+where
+ Bar<T>: Coinductive
+{}
+
+impl<T> Coinductive for Bar<T>
+where
+ Foo<T>: Coinductive,
+ Bar<T>: ConstrainInfer,
+{}
+
+trait ConstrainInfer {}
+impl ConstrainInfer for Bar<u8> {}
+impl ConstrainInfer for Foo<u16> {}
+
+fn impls<T: Coinductive>() -> T { todo!() }
+
+fn constrain<T: ConstrainInfer>(_: T) {}
+
+fn main() {
+ // This should constrain `_` to `u8`.
+ impls::<Foo<_>>();
+}
--- /dev/null
+error: the compiler unexpectedly panicked. this is a bug.
+
+query stack during panic:
+#0 [check_well_formed] checking that `<impl at $DIR/provisional-result-done.rs:20:1: 20:31>` is well-formed
+#1 [check_mod_type_wf] checking that types are well-formed in top-level module
+end of query stack
--- /dev/null
+// Test to ensure that there is no ICE when normalizing a projection
+// which is invalid (from <https://github.com/rust-lang/rust/pull/106938>).
+
+#![crate_type = "lib"]
+
+trait Identity {
+ type Identity;
+}
+trait NotImplemented {}
+
+impl<T: NotImplemented> Identity for T {
+ type Identity = Self;
+}
+
+type Foo = u8;
+
+union Bar {
+ a: <Foo as Identity>::Identity, //~ ERROR
+ b: u8,
+}
--- /dev/null
+error[E0277]: the trait bound `u8: NotImplemented` is not satisfied
+ --> $DIR/projection-as-union-type-error-2.rs:18:8
+ |
+LL | a: <Foo as Identity>::Identity,
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NotImplemented` is not implemented for `u8`
+ |
+note: required for `u8` to implement `Identity`
+ --> $DIR/projection-as-union-type-error-2.rs:11:25
+ |
+LL | impl<T: NotImplemented> Identity for T {
+ | -------------- ^^^^^^^^ ^
+ | |
+ | unsatisfied trait bound introduced here
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
--- /dev/null
+// Test to ensure that there is no ICE when normalizing a projection
+// which is invalid (from <https://github.com/rust-lang/rust/pull/106938>).
+
+#![crate_type = "lib"]
+
+pub trait Identity {
+ type Identity;
+}
+
+pub type Foo = u8;
+
+pub union Bar {
+ a: <Foo as Identity>::Identity, //~ ERROR
+ b: u8,
+}
--- /dev/null
+error[E0277]: the trait bound `u8: Identity` is not satisfied
+ --> $DIR/projection-as-union-type-error.rs:13:9
+ |
+LL | a: <Foo as Identity>::Identity,
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Identity` is not implemented for `u8`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
--- /dev/null
+// Ensures that we can use projections as union field's type.
+// check-pass
+
+#![crate_type = "lib"]
+
+pub trait Identity {
+ type Identity;
+}
+
+impl<T> Identity for T {
+ type Identity = Self;
+}
+
+pub type Foo = u8;
+
+pub union Bar {
+ pub a: <Foo as Identity>::Identity,
+ pub b: u8,
+}