Rollup merge of #152072 - JonathanBrouwer:convert_monomorphize, r=jdonszelmann Convert to inline diagnostics in `rustc_monomorphize` For https://github.com/rust-lang/rust/issues/151366 r? @jdonszelmann
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e6a00bb..4409d4f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml
@@ -165,9 +165,6 @@ - name: install sccache run: src/ci/scripts/install-sccache.sh - - name: select Xcode - run: src/ci/scripts/select-xcode.sh - - name: install clang run: src/ci/scripts/install-clang.sh
diff --git a/Cargo.lock b/Cargo.lock index b7dd59d..a13f3bd 100644 --- a/Cargo.lock +++ b/Cargo.lock
@@ -3543,7 +3543,6 @@ "rustc_ast_pretty", "rustc_errors", "rustc_feature", - "rustc_fluent_macro", "rustc_hir", "rustc_lexer", "rustc_macros", @@ -3684,7 +3683,6 @@ "rustc_macros", "rustc_metadata", "rustc_middle", - "rustc_query_system", "rustc_serialize", "rustc_session", "rustc_span", @@ -3780,7 +3778,6 @@ "rustc_ast_lowering", "rustc_ast_passes", "rustc_ast_pretty", - "rustc_attr_parsing", "rustc_borrowck", "rustc_builtin_macros", "rustc_codegen_ssa", @@ -3792,9 +3789,7 @@ "rustc_hir_analysis", "rustc_hir_pretty", "rustc_hir_typeck", - "rustc_incremental", "rustc_index", - "rustc_infer", "rustc_interface", "rustc_lexer", "rustc_lint", @@ -3803,20 +3798,16 @@ "rustc_metadata", "rustc_middle", "rustc_mir_build", - "rustc_mir_dataflow", "rustc_mir_transform", "rustc_parse", "rustc_passes", "rustc_pattern_analysis", - "rustc_privacy", "rustc_public", - "rustc_query_system", "rustc_resolve", "rustc_session", "rustc_span", "rustc_target", "rustc_trait_selection", - "rustc_ty_utils", "serde_json", "shlex", "tracing", @@ -4052,7 +4043,6 @@ "rustc_ast", "rustc_data_structures", "rustc_errors", - "rustc_fluent_macro", "rustc_fs_util", "rustc_graphviz", "rustc_hashes", @@ -4091,7 +4081,6 @@ dependencies = [ "rustc_data_structures", "rustc_errors", - "rustc_fluent_macro", "rustc_hir", "rustc_index", "rustc_macros", @@ -4122,7 +4111,6 @@ "rustc_errors", "rustc_expand", "rustc_feature", - "rustc_fluent_macro", "rustc_fs_util", "rustc_hir", "rustc_hir_analysis", @@ -4336,11 +4324,10 @@ "polonius-engine", "regex", "rustc_abi", - "rustc_ast", "rustc_data_structures", "rustc_errors", - "rustc_fluent_macro", "rustc_graphviz", + "rustc_hir", "rustc_index", "rustc_macros", "rustc_middle", @@ -4495,7 +4482,6 @@ "rustc_ast", "rustc_data_structures", "rustc_errors", - "rustc_fluent_macro", "rustc_hir", "rustc_macros", "rustc_middle", @@ -4569,7 +4555,6 @@ "rustc_data_structures", "rustc_errors", "rustc_feature", - "rustc_fluent_macro", "rustc_hashes", "rustc_hir", "rustc_index", @@ -4651,7 +4636,6 @@ "rustc_data_structures", "rustc_errors", "rustc_feature", - "rustc_fluent_macro", "rustc_fs_util", "rustc_hashes", "rustc_hir", @@ -4807,7 +4791,6 @@ "rustc_abi", "rustc_data_structures", "rustc_errors", - "rustc_fluent_macro", "rustc_hashes", "rustc_hir", "rustc_index",
diff --git a/compiler/rustc_attr_parsing/Cargo.toml b/compiler/rustc_attr_parsing/Cargo.toml index 79193f3..411f3f5 100644 --- a/compiler/rustc_attr_parsing/Cargo.toml +++ b/compiler/rustc_attr_parsing/Cargo.toml
@@ -10,7 +10,6 @@ rustc_ast_pretty = { path = "../rustc_ast_pretty" } rustc_errors = { path = "../rustc_errors" } rustc_feature = { path = "../rustc_feature" } -rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_hir = { path = "../rustc_hir" } rustc_lexer = { path = "../rustc_lexer" } rustc_macros = { path = "../rustc_macros" }
diff --git a/compiler/rustc_attr_parsing/messages.ftl b/compiler/rustc_attr_parsing/messages.ftl deleted file mode 100644 index 3e4c1a9..0000000 --- a/compiler/rustc_attr_parsing/messages.ftl +++ /dev/null
@@ -1,246 +0,0 @@ -attr_parsing_as_needed_compatibility = - linking modifier `as-needed` is only compatible with `dylib`, `framework` and `raw-dylib` linking kinds - -attr_parsing_bundle_needs_static = - linking modifier `bundle` is only compatible with `static` linking kind - -attr_parsing_cfg_attr_bad_delim = wrong `cfg_attr` delimiters - -attr_parsing_deprecated_item_suggestion = - suggestions on deprecated items are unstable - .help = add `#![feature(deprecated_suggestion)]` to the crate root - .note = see #94785 for more details - -attr_parsing_doc_alias_bad_char = - {$char_} character isn't allowed in {$attr_str} - -attr_parsing_doc_alias_empty = - {$attr_str} attribute cannot have empty value - -attr_parsing_doc_alias_malformed = - doc alias attribute expects a string `#[doc(alias = "a")]` or a list of strings `#[doc(alias("a", "b"))]` - -attr_parsing_doc_alias_start_end = - {$attr_str} cannot start or end with ' ' - -attr_parsing_doc_attr_not_crate_level = - `#![doc({$attr_name} = "...")]` isn't allowed as a crate-level attribute - -attr_parsing_doc_attribute_not_attribute = - nonexistent builtin attribute `{$attribute}` used in `#[doc(attribute = "...")]` - .help = only existing builtin attributes are allowed in core/std - -attr_parsing_doc_keyword_not_keyword = - nonexistent keyword `{$keyword}` used in `#[doc(keyword = "...")]` - .help = only existing keywords are allowed in core/std - -attr_parsing_empty_confusables = - expected at least one confusable name - -attr_parsing_empty_link_name = - link name must not be empty - .label = empty link name - -attr_parsing_expected_single_version_literal = - expected single version literal - -attr_parsing_expected_version_literal = - expected a version literal - -attr_parsing_expects_feature_list = - `{$name}` expects a list of feature names - -attr_parsing_expects_features = - `{$name}` expects feature names - -attr_parsing_import_name_type_raw = - import name type can only be used with link kind `raw-dylib` - -attr_parsing_import_name_type_x86 = - import name type is only supported on x86 - -attr_parsing_incompatible_wasm_link = - `wasm_import_module` is incompatible with other arguments in `#[link]` attributes - -attr_parsing_incorrect_repr_format_align_one_arg = - incorrect `repr(align)` attribute format: `align` takes exactly one argument in parentheses - -attr_parsing_incorrect_repr_format_expect_literal_integer = - incorrect `repr(align)` attribute format: `align` expects a literal integer as argument - -attr_parsing_incorrect_repr_format_generic = - incorrect `repr({$repr_arg})` attribute format - .suggestion = use parentheses instead - -attr_parsing_incorrect_repr_format_packed_expect_integer = - incorrect `repr(packed)` attribute format: `packed` expects a literal integer as argument - -attr_parsing_incorrect_repr_format_packed_one_or_zero_arg = - incorrect `repr(packed)` attribute format: `packed` takes exactly one parenthesized argument, or no parentheses at all - -attr_parsing_invalid_alignment_value = - invalid alignment value: {$error_part} - -attr_parsing_invalid_attr_unsafe = `{$name}` is not an unsafe attribute - .label = this is not an unsafe attribute - .suggestion = remove the `unsafe(...)` - .note = extraneous unsafe is not allowed in attributes - -attr_parsing_invalid_issue_string = - `issue` must be a non-zero numeric string or "none" - .must_not_be_zero = `issue` must not be "0", use "none" instead - .empty = cannot parse integer from empty string - .invalid_digit = invalid digit found in string - .pos_overflow = number too large to fit in target type - .neg_overflow = number too small to fit in target type - -attr_parsing_invalid_link_modifier = - invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed - -attr_parsing_invalid_meta_item = expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found {$descr} - .remove_neg_sugg = negative numbers are not literals, try removing the `-` sign - .quote_ident_sugg = surround the identifier with quotation marks to make it into a string literal - .label = {$descr}s are not allowed here - -attr_parsing_invalid_predicate = - invalid predicate `{$predicate}` - -attr_parsing_invalid_repr_align_need_arg = - invalid `repr(align)` attribute: `align` needs an argument - .suggestion = supply an argument here - -attr_parsing_invalid_repr_generic = - invalid `repr({$repr_arg})` attribute: {$error_part} - -attr_parsing_invalid_repr_hint_no_paren = - invalid representation hint: `{$name}` does not take a parenthesized argument list - -attr_parsing_invalid_repr_hint_no_value = - invalid representation hint: `{$name}` does not take a value - -attr_parsing_invalid_since = - 'since' must be a Rust version number, such as "1.31.0" - -attr_parsing_invalid_target = `#[{$name}]` attribute cannot be used on {$target} - .help = `#[{$name}]` can {$only}be applied to {$applied} - .suggestion = remove the attribute - -attr_parsing_limit_invalid = - `limit` must be a non-negative integer - .label = {$error_str} -attr_parsing_link_arg_unstable = - link kind `link-arg` is unstable - -attr_parsing_link_cfg_unstable = - link cfg is unstable - -attr_parsing_link_framework_apple = - link kind `framework` is only supported on Apple targets - -attr_parsing_link_ordinal_out_of_range = ordinal value in `link_ordinal` is too large: `{$ordinal}` - .note = the value may not exceed `u16::MAX` - -attr_parsing_link_requires_name = - `#[link]` attribute requires a `name = "string"` argument - .label = missing `name` argument - -attr_parsing_meta_bad_delim = wrong meta list delimiters -attr_parsing_meta_bad_delim_suggestion = the delimiters should be `(` and `)` - -attr_parsing_missing_feature = - missing 'feature' - -attr_parsing_missing_issue = - missing 'issue' - -attr_parsing_missing_note = - missing 'note' - -attr_parsing_missing_since = - missing 'since' - -attr_parsing_multiple_modifiers = - multiple `{$modifier}` modifiers in a single `modifiers` argument - -attr_parsing_multiple_stability_levels = - multiple stability levels - -attr_parsing_naked_functions_incompatible_attribute = - attribute incompatible with `#[unsafe(naked)]` - .label = the `{$attr}` attribute is incompatible with `#[unsafe(naked)]` - .naked_attribute = function marked with `#[unsafe(naked)]` here - -attr_parsing_non_ident_feature = - 'feature' is not an identifier - -attr_parsing_null_on_export = `export_name` may not contain null characters - -attr_parsing_null_on_link_section = `link_section` may not contain null characters - -attr_parsing_null_on_objc_class = `objc::class!` may not contain null characters - -attr_parsing_null_on_objc_selector = `objc::selector!` may not contain null characters - -attr_parsing_objc_class_expected_string_literal = `objc::class!` expected a string literal - -attr_parsing_objc_selector_expected_string_literal = `objc::selector!` expected a string literal - -attr_parsing_raw_dylib_elf_unstable = - link kind `raw-dylib` is unstable on ELF platforms - -attr_parsing_raw_dylib_no_nul = - link name must not contain NUL characters if link kind is `raw-dylib` - -attr_parsing_raw_dylib_only_windows = - link kind `raw-dylib` is only supported on Windows targets - -attr_parsing_repr_ident = - meta item in `repr` must be an identifier - -attr_parsing_rustc_allowed_unstable_pairing = - `rustc_allowed_through_unstable_modules` attribute must be paired with a `stable` attribute - -attr_parsing_rustc_promotable_pairing = - `rustc_promotable` attribute must be paired with either a `rustc_const_unstable` or a `rustc_const_stable` attribute - -attr_parsing_rustc_scalable_vector_count_out_of_range = element count in `rustc_scalable_vector` is too large: `{$n}` - .note = the value may not exceed `u16::MAX` - -attr_parsing_soft_no_args = - `soft` should not have any arguments - -attr_parsing_stability_outside_std = stability attributes may not be used outside of the standard library - -attr_parsing_suffixed_literal_in_attribute = suffixed literals are not allowed in attributes - .help = instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.) - -attr_parsing_unknown_version_literal = - unknown version literal format, assuming it refers to a future version - -attr_parsing_unrecognized_repr_hint = - unrecognized representation hint - .help = valid reprs are `Rust` (default), `C`, `align`, `packed`, `transparent`, `simd`, `i8`, `u8`, `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize`, `usize` - .note = for more information, visit <https://doc.rust-lang.org/reference/type-layout.html?highlight=repr#representations> - -attr_parsing_unsafe_attr_outside_unsafe = unsafe attribute used without unsafe - .label = usage of unsafe attribute -attr_parsing_unsafe_attr_outside_unsafe_suggestion = wrap the attribute in `unsafe(...)` - -attr_parsing_unstable_cfg_target_compact = - compact `cfg(target(..))` is experimental and subject to change - -attr_parsing_unstable_feature_bound_incompatible_stability = item annotated with `#[unstable_feature_bound]` should not be stable - .help = if this item is meant to be stable, do not use any functions annotated with `#[unstable_feature_bound]`. Otherwise, mark this item as unstable with `#[unstable]` - -attr_parsing_unsupported_instruction_set = target `{$current_target}` does not support `#[instruction_set({$instruction_set}::*)]` - -attr_parsing_unsupported_literal_suggestion = - consider removing the prefix - -attr_parsing_unused_multiple = - multiple `{$name}` attributes - .suggestion = remove this attribute - .note = attribute also specified here - -attr_parsing_whole_archive_needs_static = - linking modifier `whole-archive` is only compatible with `static` linking kind
diff --git a/compiler/rustc_attr_parsing/src/attributes/cfg.rs b/compiler/rustc_attr_parsing/src/attributes/cfg.rs index 157a91c..686d98a 100644 --- a/compiler/rustc_attr_parsing/src/attributes/cfg.rs +++ b/compiler/rustc_attr_parsing/src/attributes/cfg.rs
@@ -3,7 +3,7 @@ use rustc_ast::token::Delimiter; use rustc_ast::tokenstream::DelimSpan; use rustc_ast::{AttrItem, Attribute, CRATE_NODE_ID, LitKind, ast, token}; -use rustc_errors::{Applicability, PResult}; +use rustc_errors::{Applicability, PResult, inline_fluent}; use rustc_feature::{ AttrSuggestionStyle, AttributeTemplate, Features, GatedCfg, find_gated_cfg, template, }; @@ -25,7 +25,7 @@ AttributeParseError, AttributeParseErrorReason, CfgAttrBadDelim, MetaBadDelimSugg, ParsedDescription, }; -use crate::{AttributeParser, fluent_generated, parse_version, session_diagnostics}; +use crate::{AttributeParser, parse_version, session_diagnostics}; pub const CFG_TEMPLATE: AttributeTemplate = template!( List: &["predicate"], @@ -141,7 +141,7 @@ fn parse_cfg_entry_target<S: Stage>( cx.sess(), sym::cfg_target_compact, meta_span, - fluent_generated::attr_parsing_unstable_cfg_target_compact, + inline_fluent!("compact `cfg(target(..))` is experimental and subject to change"), ) .emit(); }
diff --git a/compiler/rustc_attr_parsing/src/attributes/doc.rs b/compiler/rustc_attr_parsing/src/attributes/doc.rs index a287c0c..f896863 100644 --- a/compiler/rustc_attr_parsing/src/attributes/doc.rs +++ b/compiler/rustc_attr_parsing/src/attributes/doc.rs
@@ -70,6 +70,42 @@ fn check_attr_crate_level<S: Stage>(cx: &mut AcceptContext<'_, '_, S>, span: Spa true } +// FIXME: To be removed once merged and replace with `cx.expected_name_value(span, _name)`. +fn expected_name_value<S: Stage>( + cx: &mut AcceptContext<'_, '_, S>, + span: Span, + _name: Option<Symbol>, +) { + cx.emit_lint( + rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES, + AttributeLintKind::ExpectedNameValue, + span, + ); +} + +// FIXME: remove this method once merged and use `cx.expected_no_args(span)` instead. +fn expected_no_args<S: Stage>(cx: &mut AcceptContext<'_, '_, S>, span: Span) { + cx.emit_lint( + rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES, + AttributeLintKind::ExpectedNoArgs, + span, + ); +} + +// FIXME: remove this method once merged and use `cx.expected_no_args(span)` instead. +// cx.expected_string_literal(span, _actual_literal); +fn expected_string_literal<S: Stage>( + cx: &mut AcceptContext<'_, '_, S>, + span: Span, + _actual_literal: Option<&MetaItemLit>, +) { + cx.emit_lint( + rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES, + AttributeLintKind::MalformedDoc, + span, + ); +} + fn parse_keyword_and_attribute<S: Stage>( cx: &mut AcceptContext<'_, '_, S>, path: &OwnedPathParser, @@ -78,12 +114,12 @@ fn parse_keyword_and_attribute<S: Stage>( attr_name: Symbol, ) { let Some(nv) = args.name_value() else { - cx.expected_name_value(args.span().unwrap_or(path.span()), path.word_sym()); + expected_name_value(cx, args.span().unwrap_or(path.span()), path.word_sym()); return; }; let Some(value) = nv.value_as_str() else { - cx.expected_string_literal(nv.value_span, Some(nv.value_as_lit())); + expected_string_literal(cx, nv.value_span, Some(nv.value_as_lit())); return; }; @@ -127,12 +163,21 @@ fn parse_single_test_doc_attr_item<S: Stage>( match path.word_sym() { Some(sym::no_crate_inject) => { if let Err(span) = args.no_args() { - cx.expected_no_args(span); + expected_no_args(cx, span); return; } - if self.attribute.no_crate_inject.is_some() { - cx.duplicate_key(path.span(), sym::no_crate_inject); + if let Some(used_span) = self.attribute.no_crate_inject { + let unused_span = path.span(); + cx.emit_lint( + rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES, + AttributeLintKind::UnusedDuplicate { + this: unused_span, + other: used_span, + warning: true, + }, + unused_span, + ); return; } @@ -144,7 +189,14 @@ fn parse_single_test_doc_attr_item<S: Stage>( } Some(sym::attr) => { let Some(list) = args.list() else { - cx.expected_list(cx.attr_span, args); + // FIXME: remove this method once merged and uncomment the line below instead. + // cx.expected_list(cx.attr_span, args); + let span = cx.attr_span; + cx.emit_lint( + rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES, + AttributeLintKind::MalformedDoc, + span, + ); return; }; @@ -246,7 +298,7 @@ fn parse_inline<S: Stage>( inline: DocInline, ) { if let Err(span) = args.no_args() { - cx.expected_no_args(span); + expected_no_args(cx, span); return; } @@ -328,7 +380,14 @@ fn parse_auto_cfg<S: Stage>( match sub_item.args() { a @ (ArgParser::NoArgs | ArgParser::NameValue(_)) => { let Some(name) = sub_item.path().word_sym() else { - cx.expected_identifier(sub_item.path().span()); + // FIXME: remove this method once merged and uncomment the line + // below instead. + // cx.expected_identifier(sub_item.path().span()); + cx.emit_lint( + rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES, + AttributeLintKind::MalformedDoc, + sub_item.path().span(), + ); continue; }; if let Ok(CfgEntry::NameValue { name, value, .. }) = @@ -391,7 +450,7 @@ fn parse_single_doc_attr_item<S: Stage>( macro_rules! no_args { ($ident: ident) => {{ if let Err(span) = args.no_args() { - cx.expected_no_args(span); + expected_no_args(cx, span); return; } @@ -410,7 +469,7 @@ macro_rules! no_args { macro_rules! no_args_and_not_crate_level { ($ident: ident) => {{ if let Err(span) = args.no_args() { - cx.expected_no_args(span); + expected_no_args(cx, span); return; } let span = path.span(); @@ -423,7 +482,7 @@ macro_rules! no_args_and_not_crate_level { macro_rules! no_args_and_crate_level { ($ident: ident) => {{ if let Err(span) = args.no_args() { - cx.expected_no_args(span); + expected_no_args(cx, span); return; } let span = path.span(); @@ -436,12 +495,12 @@ macro_rules! no_args_and_crate_level { macro_rules! string_arg_and_crate_level { ($ident: ident) => {{ let Some(nv) = args.name_value() else { - cx.expected_name_value(args.span().unwrap_or(path.span()), path.word_sym()); + expected_name_value(cx, args.span().unwrap_or(path.span()), path.word_sym()); return; }; let Some(s) = nv.value_as_str() else { - cx.expected_string_literal(nv.value_span, Some(nv.value_as_lit())); + expected_string_literal(cx, nv.value_span, Some(nv.value_as_lit())); return; }; @@ -512,7 +571,14 @@ macro_rules! string_arg_and_crate_level { self.parse_single_test_doc_attr_item(cx, mip); } MetaItemOrLitParser::Lit(lit) => { - cx.unexpected_literal(lit.span); + // FIXME: remove this method once merged and uncomment the line + // below instead. + // cx.unexpected_literal(lit.span); + cx.emit_lint( + rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES, + AttributeLintKind::MalformedDoc, + lit.span, + ); } } } @@ -582,7 +648,7 @@ fn accept_single_doc_attr<S: Stage>( let suggestions = cx.suggestions(); let span = cx.attr_span; cx.emit_lint( - rustc_session::lint::builtin::ILL_FORMED_ATTRIBUTE_INPUT, + rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES, AttributeLintKind::IllFormedAttributeInput { suggestions, docs: None }, span, ); @@ -595,14 +661,14 @@ fn accept_single_doc_attr<S: Stage>( self.parse_single_doc_attr_item(cx, mip); } MetaItemOrLitParser::Lit(lit) => { - cx.expected_name_value(lit.span, None); + expected_name_value(cx, lit.span, None); } } } } ArgParser::NameValue(nv) => { if nv.value_as_str().is_none() { - cx.expected_string_literal(nv.value_span, Some(nv.value_as_lit())); + expected_string_literal(cx, nv.value_span, Some(nv.value_as_lit())); } else { unreachable!( "Should have been handled at the same time as sugar-syntaxed doc comments"
diff --git a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs index 548f53a..6c52be9 100644 --- a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs
@@ -1,3 +1,4 @@ +use rustc_errors::inline_fluent; use rustc_feature::Features; use rustc_hir::attrs::AttributeKind::{LinkName, LinkOrdinal, LinkSection}; use rustc_hir::attrs::*; @@ -10,12 +11,11 @@ use super::prelude::*; use super::util::parse_single_integer; use crate::attributes::cfg::parse_cfg_entry; -use crate::fluent_generated; use crate::session_diagnostics::{ - AsNeededCompatibility, BundleNeedsStatic, EmptyLinkName, ImportNameTypeRaw, ImportNameTypeX86, - IncompatibleWasmLink, InvalidLinkModifier, LinkFrameworkApple, LinkOrdinalOutOfRange, - LinkRequiresName, MultipleModifiers, NullOnLinkSection, RawDylibNoNul, RawDylibOnlyWindows, - WholeArchiveNeedsStatic, + AsNeededCompatibility, BundleNeedsStatic, EmptyLinkName, ExportSymbolsNeedsStatic, + ImportNameTypeRaw, ImportNameTypeX86, IncompatibleWasmLink, InvalidLinkModifier, + LinkFrameworkApple, LinkOrdinalOutOfRange, LinkRequiresName, MultipleModifiers, + NullOnLinkSection, RawDylibNoNul, RawDylibOnlyWindows, WholeArchiveNeedsStatic, }; pub(crate) struct LinkNameParser; @@ -165,6 +165,14 @@ fn extend( cx.emit_err(BundleNeedsStatic { span }); } + (sym::export_symbols, Some(NativeLibKind::Static { export_symbols, .. })) => { + assign_modifier(export_symbols) + } + + (sym::export_symbols, _) => { + cx.emit_err(ExportSymbolsNeedsStatic { span }); + } + (sym::verbatim, _) => assign_modifier(&mut verbatim), ( @@ -190,6 +198,7 @@ fn extend( span, &[ sym::bundle, + sym::export_symbols, sym::verbatim, sym::whole_dash_archive, sym::as_dash_needed, @@ -285,7 +294,9 @@ fn parse_link_kind<S: Stage>( }; let link_kind = match link_kind { - kw::Static => NativeLibKind::Static { bundle: None, whole_archive: None }, + kw::Static => { + NativeLibKind::Static { bundle: None, whole_archive: None, export_symbols: None } + } sym::dylib => NativeLibKind::Dylib { as_needed: None }, sym::framework => { if !sess.target.is_like_darwin { @@ -305,7 +316,7 @@ fn parse_link_kind<S: Stage>( sess, sym::raw_dylib_elf, nv.value_span, - fluent_generated::attr_parsing_raw_dylib_elf_unstable, + inline_fluent!("link kind `raw-dylib` is unstable on ELF platforms"), ) .emit(); } else { @@ -320,7 +331,7 @@ fn parse_link_kind<S: Stage>( sess, sym::link_arg_attribute, nv.value_span, - fluent_generated::attr_parsing_link_arg_unstable, + inline_fluent!("link kind `link-arg` is unstable"), ) .emit(); } @@ -385,13 +396,8 @@ fn parse_link_cfg<S: Stage>( return true; }; if !features.link_cfg() { - feature_err( - sess, - sym::link_cfg, - item.span(), - fluent_generated::attr_parsing_link_cfg_unstable, - ) - .emit(); + feature_err(sess, sym::link_cfg, item.span(), inline_fluent!("link cfg is unstable")) + .emit(); } *cfg = parse_cfg_entry(cx, link_cfg).ok(); true
diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs index 250bcee..8961dc4 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs
@@ -1,5 +1,7 @@ +use std::path::PathBuf; + use rustc_ast::{LitIntType, LitKind, MetaItemLit}; -use rustc_hir::attrs::RustcLayoutType; +use rustc_hir::attrs::{BorrowckGraphvizFormatKind, RustcLayoutType, RustcMirKind}; use rustc_session::errors; use super::prelude::*; @@ -357,7 +359,6 @@ impl<S: Stage> CombineAttributeParser<S> for RustcLayoutParser { const TEMPLATE: AttributeTemplate = template!(List: &["abi", "align", "size", "homogenous_aggregate", "debug"]); - fn extend( cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser, @@ -397,6 +398,94 @@ fn extend( } } +pub(crate) struct RustcMirParser; + +impl<S: Stage> CombineAttributeParser<S> for RustcMirParser { + const PATH: &[rustc_span::Symbol] = &[sym::rustc_mir]; + + type Item = RustcMirKind; + + const CONVERT: ConvertFn<Self::Item> = |items, _| AttributeKind::RustcMir(items); + + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + Allow(Target::Fn), + Allow(Target::Method(MethodKind::Inherent)), + Allow(Target::Method(MethodKind::TraitImpl)), + Allow(Target::Method(MethodKind::Trait { body: false })), + Allow(Target::Method(MethodKind::Trait { body: true })), + ]); + + const TEMPLATE: AttributeTemplate = template!(List: &["arg1, arg2, ..."]); + + fn extend( + cx: &mut AcceptContext<'_, '_, S>, + args: &ArgParser, + ) -> impl IntoIterator<Item = Self::Item> { + let Some(list) = args.list() else { + cx.expected_list(cx.attr_span, args); + return ThinVec::new(); + }; + + list.mixed() + .filter_map(|arg| arg.meta_item()) + .filter_map(|mi| { + if let Some(ident) = mi.ident() { + match ident.name { + sym::rustc_peek_maybe_init => Some(RustcMirKind::PeekMaybeInit), + sym::rustc_peek_maybe_uninit => Some(RustcMirKind::PeekMaybeUninit), + sym::rustc_peek_liveness => Some(RustcMirKind::PeekLiveness), + sym::stop_after_dataflow => Some(RustcMirKind::StopAfterDataflow), + sym::borrowck_graphviz_postflow => { + let Some(nv) = mi.args().name_value() else { + cx.expected_name_value( + mi.span(), + Some(sym::borrowck_graphviz_postflow), + ); + return None; + }; + let Some(path) = nv.value_as_str() else { + cx.expected_string_literal(nv.value_span, None); + return None; + }; + let path = PathBuf::from(path.to_string()); + if path.file_name().is_some() { + Some(RustcMirKind::BorrowckGraphvizPostflow { path }) + } else { + cx.expected_filename_literal(nv.value_span); + None + } + } + sym::borrowck_graphviz_format => { + let Some(nv) = mi.args().name_value() else { + cx.expected_name_value( + mi.span(), + Some(sym::borrowck_graphviz_format), + ); + return None; + }; + let Some(format) = nv.value_as_ident() else { + cx.expected_identifier(nv.value_span); + return None; + }; + match format.name { + sym::two_phase => Some(RustcMirKind::BorrowckGraphvizFormat { + format: BorrowckGraphvizFormatKind::TwoPhase, + }), + _ => { + cx.expected_specific_argument(format.span, &[sym::two_phase]); + None + } + } + } + _ => None, + } + } else { + None + } + }) + .collect() + } +} pub(crate) struct RustcNonConstTraitMethodParser; impl<S: Stage> NoArgsAttributeParser<S> for RustcNonConstTraitMethodParser {
diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index f340b39..fa9f5b5 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs
@@ -16,90 +16,42 @@ use rustc_span::{ErrorGuaranteed, Span, Symbol}; use crate::AttributeParser; -use crate::attributes::allow_unstable::{ - AllowConstFnUnstableParser, AllowInternalUnstableParser, UnstableFeatureBoundParser, -}; -use crate::attributes::body::CoroutineParser; -use crate::attributes::cfi_encoding::CfiEncodingParser; -use crate::attributes::codegen_attrs::{ - ColdParser, CoverageParser, EiiForeignItemParser, ExportNameParser, ForceTargetFeatureParser, - NakedParser, NoMangleParser, ObjcClassParser, ObjcSelectorParser, OptimizeParser, - PatchableFunctionEntryParser, RustcPassIndirectlyInNonRusticAbisParser, SanitizeParser, - TargetFeatureParser, ThreadLocalParser, TrackCallerParser, UsedParser, -}; -use crate::attributes::confusables::ConfusablesParser; -use crate::attributes::crate_level::{ - CrateNameParser, CrateTypeParser, MoveSizeLimitParser, NeedsPanicRuntimeParser, - NoBuiltinsParser, NoCoreParser, NoMainParser, NoStdParser, PanicRuntimeParser, - PatternComplexityLimitParser, ProfilerRuntimeParser, RecursionLimitParser, - RustcCoherenceIsCoreParser, RustcPreserveUbChecksParser, TypeLengthLimitParser, - WindowsSubsystemParser, -}; -use crate::attributes::debugger::DebuggerViualizerParser; -use crate::attributes::deprecation::DeprecationParser; -use crate::attributes::do_not_recommend::DoNotRecommendParser; -use crate::attributes::doc::DocParser; -use crate::attributes::dummy::DummyParser; -use crate::attributes::inline::{InlineParser, RustcForceInlineParser}; -use crate::attributes::instruction_set::InstructionSetParser; -use crate::attributes::link_attrs::{ - CompilerBuiltinsParser, ExportStableParser, FfiConstParser, FfiPureParser, LinkNameParser, - LinkOrdinalParser, LinkParser, LinkSectionParser, LinkageParser, NeedsAllocatorParser, - StdInternalSymbolParser, -}; -use crate::attributes::lint_helpers::{ - AsPtrParser, AutomaticallyDerivedParser, PassByValueParser, PubTransparentParser, - RustcShouldNotBeCalledOnConstItems, -}; -use crate::attributes::loop_match::{ConstContinueParser, LoopMatchParser}; -use crate::attributes::macro_attrs::{ - AllowInternalUnsafeParser, CollapseDebugInfoParser, MacroEscapeParser, MacroExportParser, - MacroUseParser, -}; -use crate::attributes::must_not_suspend::MustNotSuspendParser; -use crate::attributes::must_use::MustUseParser; -use crate::attributes::no_implicit_prelude::NoImplicitPreludeParser; -use crate::attributes::no_link::NoLinkParser; -use crate::attributes::non_exhaustive::NonExhaustiveParser; +// Glob imports to avoid big, bitrotty import lists +use crate::attributes::allow_unstable::*; +use crate::attributes::body::*; +use crate::attributes::cfi_encoding::*; +use crate::attributes::codegen_attrs::*; +use crate::attributes::confusables::*; +use crate::attributes::crate_level::*; +use crate::attributes::debugger::*; +use crate::attributes::deprecation::*; +use crate::attributes::do_not_recommend::*; +use crate::attributes::doc::*; +use crate::attributes::dummy::*; +use crate::attributes::inline::*; +use crate::attributes::instruction_set::*; +use crate::attributes::link_attrs::*; +use crate::attributes::lint_helpers::*; +use crate::attributes::loop_match::*; +use crate::attributes::macro_attrs::*; +use crate::attributes::must_not_suspend::*; +use crate::attributes::must_use::*; +use crate::attributes::no_implicit_prelude::*; +use crate::attributes::no_link::*; +use crate::attributes::non_exhaustive::*; use crate::attributes::path::PathParser as PathAttributeParser; -use crate::attributes::pin_v2::PinV2Parser; -use crate::attributes::proc_macro_attrs::{ - ProcMacroAttributeParser, ProcMacroDeriveParser, ProcMacroParser, RustcBuiltinMacroParser, -}; -use crate::attributes::prototype::CustomMirParser; -use crate::attributes::repr::{AlignParser, AlignStaticParser, ReprParser}; -use crate::attributes::rustc_allocator::{ - RustcAllocatorParser, RustcAllocatorZeroedParser, RustcAllocatorZeroedVariantParser, - RustcDeallocatorParser, RustcReallocatorParser, -}; -use crate::attributes::rustc_dump::{ - RustcDumpDefParentsParser, RustcDumpItemBoundsParser, RustcDumpPredicatesParser, - RustcDumpUserArgsParser, RustcDumpVtableParser, -}; -use crate::attributes::rustc_internal::{ - RustcHasIncoherentInherentImplsParser, RustcHiddenTypeOfOpaquesParser, RustcLayoutParser, - RustcLayoutScalarValidRangeEndParser, RustcLayoutScalarValidRangeStartParser, - RustcLegacyConstGenericsParser, RustcLintOptDenyFieldAccessParser, RustcLintOptTyParser, - RustcLintQueryInstabilityParser, RustcLintUntrackedQueryInformationParser, RustcMainParser, - RustcMustImplementOneOfParser, RustcNeverReturnsNullPointerParser, - RustcNoImplicitAutorefsParser, RustcNonConstTraitMethodParser, RustcNounwindParser, - RustcObjectLifetimeDefaultParser, RustcOffloadKernelParser, RustcScalableVectorParser, - RustcSimdMonomorphizeLaneLimitParser, -}; -use crate::attributes::semantics::MayDangleParser; -use crate::attributes::stability::{ - BodyStabilityParser, ConstStabilityIndirectParser, ConstStabilityParser, StabilityParser, -}; -use crate::attributes::test_attrs::{ - IgnoreParser, RustcVarianceOfOpaquesParser, RustcVarianceParser, ShouldPanicParser, -}; -use crate::attributes::traits::{ - AllowIncoherentImplParser, CoinductiveParser, DenyExplicitImplParser, - DynIncompatibleTraitParser, FundamentalParser, MarkerParser, ParenSugarParser, PointeeParser, - SkipDuringMethodDispatchParser, SpecializationTraitParser, TypeConstParser, - UnsafeSpecializationMarkerParser, -}; -use crate::attributes::transparency::TransparencyParser; +use crate::attributes::pin_v2::*; +use crate::attributes::proc_macro_attrs::*; +use crate::attributes::prototype::*; +use crate::attributes::repr::*; +use crate::attributes::rustc_allocator::*; +use crate::attributes::rustc_dump::*; +use crate::attributes::rustc_internal::*; +use crate::attributes::semantics::*; +use crate::attributes::stability::*; +use crate::attributes::test_attrs::*; +use crate::attributes::traits::*; +use crate::attributes::transparency::*; use crate::attributes::{AttributeParser as _, Combine, Single, WithoutArgs}; use crate::parser::{ArgParser, RefPathParser}; use crate::session_diagnostics::{ @@ -202,6 +154,7 @@ mod late { Combine<LinkParser>, Combine<ReprParser>, Combine<RustcLayoutParser>, + Combine<RustcMirParser>, Combine<TargetFeatureParser>, Combine<UnstableFeatureBoundParser>, // tidy-alphabetical-end @@ -517,6 +470,11 @@ pub(crate) fn expected_string_literal( ) } + /// Error that a filename string literal was expected. + pub(crate) fn expected_filename_literal(&self, span: Span) { + self.emit_parse_error(span, AttributeParseErrorReason::ExpectedFilenameLiteral); + } + pub(crate) fn expected_integer_literal(&self, span: Span) -> ErrorGuaranteed { self.emit_parse_error(span, AttributeParseErrorReason::ExpectedIntegerLiteral) }
diff --git a/compiler/rustc_attr_parsing/src/lib.rs b/compiler/rustc_attr_parsing/src/lib.rs index 349e6c2..fe050250 100644 --- a/compiler/rustc_attr_parsing/src/lib.rs +++ b/compiler/rustc_attr_parsing/src/lib.rs
@@ -113,5 +113,3 @@ pub use context::{Early, Late, OmitDoc, ShouldEmit}; pub use interface::AttributeParser; pub use session_diagnostics::ParsedDescription; - -rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
diff --git a/compiler/rustc_attr_parsing/src/session_diagnostics.rs b/compiler/rustc_attr_parsing/src/session_diagnostics.rs index f974854..b0a3342 100644 --- a/compiler/rustc_attr_parsing/src/session_diagnostics.rs +++ b/compiler/rustc_attr_parsing/src/session_diagnostics.rs
@@ -11,10 +11,8 @@ use rustc_span::{Span, Symbol}; use rustc_target::spec::TargetTuple; -use crate::fluent_generated as fluent; - #[derive(Diagnostic)] -#[diag(attr_parsing_invalid_predicate, code = E0537)] +#[diag("invalid predicate `{$predicate}`", code = E0537)] pub(crate) struct InvalidPredicate { #[primary_span] pub span: Span, @@ -23,7 +21,7 @@ pub(crate) struct InvalidPredicate { } #[derive(Diagnostic)] -#[diag(attr_parsing_doc_alias_empty)] +#[diag("{$attr_str} attribute cannot have empty value")] pub(crate) struct DocAliasEmpty<'a> { #[primary_span] pub span: Span, @@ -31,7 +29,7 @@ pub(crate) struct DocAliasEmpty<'a> { } #[derive(Diagnostic)] -#[diag(attr_parsing_doc_alias_bad_char)] +#[diag("{$char_} character isn't allowed in {$attr_str}")] pub(crate) struct DocAliasBadChar<'a> { #[primary_span] pub span: Span, @@ -40,7 +38,7 @@ pub(crate) struct DocAliasBadChar<'a> { } #[derive(Diagnostic)] -#[diag(attr_parsing_doc_alias_start_end)] +#[diag("{$attr_str} cannot start or end with ' '")] pub(crate) struct DocAliasStartEnd<'a> { #[primary_span] pub span: Span, @@ -48,7 +46,7 @@ pub(crate) struct DocAliasStartEnd<'a> { } #[derive(Diagnostic)] -#[diag(attr_parsing_doc_attr_not_crate_level)] +#[diag("`#![doc({$attr_name} = \"...\")]` isn't allowed as a crate-level attribute")] pub(crate) struct DocAttrNotCrateLevel { #[primary_span] pub span: Span, @@ -56,8 +54,8 @@ pub(crate) struct DocAttrNotCrateLevel { } #[derive(Diagnostic)] -#[diag(attr_parsing_doc_keyword_not_keyword)] -#[help] +#[diag("nonexistent keyword `{$keyword}` used in `#[doc(keyword = \"...\")]`")] +#[help("only existing keywords are allowed in core/std")] pub(crate) struct DocKeywordNotKeyword { #[primary_span] pub span: Span, @@ -65,8 +63,8 @@ pub(crate) struct DocKeywordNotKeyword { } #[derive(Diagnostic)] -#[diag(attr_parsing_doc_attribute_not_attribute)] -#[help] +#[diag("nonexistent builtin attribute `{$attribute}` used in `#[doc(attribute = \"...\")]`")] +#[help("only existing builtin attributes are allowed in core/std")] pub(crate) struct DocAttributeNotAttribute { #[primary_span] pub span: Span, @@ -74,28 +72,28 @@ pub(crate) struct DocAttributeNotAttribute { } #[derive(Diagnostic)] -#[diag(attr_parsing_missing_since, code = E0542)] +#[diag("missing 'since'", code = E0542)] pub(crate) struct MissingSince { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(attr_parsing_missing_note, code = E0543)] +#[diag("missing 'note'", code = E0543)] pub(crate) struct MissingNote { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(attr_parsing_multiple_stability_levels, code = E0544)] +#[diag("multiple stability levels", code = E0544)] pub(crate) struct MultipleStabilityLevels { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(attr_parsing_invalid_issue_string, code = E0545)] +#[diag("`issue` must be a non-zero numeric string or \"none\"", code = E0545)] pub(crate) struct InvalidIssueString { #[primary_span] pub span: Span, @@ -108,31 +106,31 @@ pub(crate) struct InvalidIssueString { // translatable. #[derive(Subdiagnostic)] pub(crate) enum InvalidIssueStringCause { - #[label(attr_parsing_must_not_be_zero)] + #[label("`issue` must not be \"0\", use \"none\" instead")] MustNotBeZero { #[primary_span] span: Span, }, - #[label(attr_parsing_empty)] + #[label("cannot parse integer from empty string")] Empty { #[primary_span] span: Span, }, - #[label(attr_parsing_invalid_digit)] + #[label("invalid digit found in string")] InvalidDigit { #[primary_span] span: Span, }, - #[label(attr_parsing_pos_overflow)] + #[label("number too large to fit in target type")] PosOverflow { #[primary_span] span: Span, }, - #[label(attr_parsing_neg_overflow)] + #[label("number too small to fit in target type")] NegOverflow { #[primary_span] span: Span, @@ -153,21 +151,21 @@ pub(crate) fn from_int_error_kind(span: Span, kind: &IntErrorKind) -> Option<Sel } #[derive(Diagnostic)] -#[diag(attr_parsing_missing_feature, code = E0546)] +#[diag("missing 'feature'", code = E0546)] pub(crate) struct MissingFeature { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(attr_parsing_non_ident_feature, code = E0546)] +#[diag("'feature' is not an identifier", code = E0546)] pub(crate) struct NonIdentFeature { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(attr_parsing_missing_issue, code = E0547)] +#[diag("missing 'issue'", code = E0547)] pub(crate) struct MissingIssue { #[primary_span] pub span: Span, @@ -176,20 +174,20 @@ pub(crate) struct MissingIssue { // FIXME: Why is this the same error code as `InvalidReprHintNoParen` and `InvalidReprHintNoValue`? // It is more similar to `IncorrectReprFormatGeneric`. #[derive(Diagnostic)] -#[diag(attr_parsing_incorrect_repr_format_packed_one_or_zero_arg, code = E0552)] +#[diag("incorrect `repr(packed)` attribute format: `packed` takes exactly one parenthesized argument, or no parentheses at all", code = E0552)] pub(crate) struct IncorrectReprFormatPackedOneOrZeroArg { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(attr_parsing_incorrect_repr_format_packed_expect_integer, code = E0552)] +#[diag("incorrect `repr(packed)` attribute format: `packed` expects a literal integer as argument", code = E0552)] pub(crate) struct IncorrectReprFormatPackedExpectInteger { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(attr_parsing_invalid_repr_hint_no_paren, code = E0552)] +#[diag("invalid representation hint: `{$name}` does not take a parenthesized argument list", code = E0552)] pub(crate) struct InvalidReprHintNoParen { #[primary_span] pub span: Span, @@ -198,7 +196,7 @@ pub(crate) struct InvalidReprHintNoParen { } #[derive(Diagnostic)] -#[diag(attr_parsing_invalid_repr_hint_no_value, code = E0552)] +#[diag("invalid representation hint: `{$name}` does not take a value", code = E0552)] pub(crate) struct InvalidReprHintNoValue { #[primary_span] pub span: Span, @@ -207,15 +205,19 @@ pub(crate) struct InvalidReprHintNoValue { } #[derive(Diagnostic)] -#[diag(attr_parsing_invalid_repr_align_need_arg, code = E0589)] +#[diag("invalid `repr(align)` attribute: `align` needs an argument", code = E0589)] pub(crate) struct InvalidReprAlignNeedArg { #[primary_span] - #[suggestion(code = "align(...)", applicability = "has-placeholders")] + #[suggestion( + "supply an argument here", + code = "align(...)", + applicability = "has-placeholders" + )] pub span: Span, } #[derive(Diagnostic)] -#[diag(attr_parsing_invalid_repr_generic, code = E0589)] +#[diag("invalid `repr({$repr_arg})` attribute: {$error_part}", code = E0589)] pub(crate) struct InvalidReprGeneric<'a> { #[primary_span] pub span: Span, @@ -225,21 +227,21 @@ pub(crate) struct InvalidReprGeneric<'a> { } #[derive(Diagnostic)] -#[diag(attr_parsing_incorrect_repr_format_align_one_arg, code = E0693)] +#[diag("incorrect `repr(align)` attribute format: `align` takes exactly one argument in parentheses", code = E0693)] pub(crate) struct IncorrectReprFormatAlignOneArg { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(attr_parsing_incorrect_repr_format_expect_literal_integer, code = E0693)] +#[diag("incorrect `repr(align)` attribute format: `align` expects a literal integer as argument", code = E0693)] pub(crate) struct IncorrectReprFormatExpectInteger { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(attr_parsing_incorrect_repr_format_generic, code = E0693)] +#[diag("incorrect `repr({$repr_arg})` attribute format", code = E0693)] pub(crate) struct IncorrectReprFormatGeneric { #[primary_span] pub span: Span, @@ -253,7 +255,7 @@ pub(crate) struct IncorrectReprFormatGeneric { #[derive(Subdiagnostic)] pub(crate) enum IncorrectReprFormatGenericCause { #[suggestion( - attr_parsing_suggestion, + "use parentheses instead", code = "{name}({value})", applicability = "machine-applicable" )] @@ -269,7 +271,7 @@ pub(crate) enum IncorrectReprFormatGenericCause { }, #[suggestion( - attr_parsing_suggestion, + "use parentheses instead", code = "{name}({value})", applicability = "machine-applicable" )] @@ -298,48 +300,48 @@ pub(crate) fn from_lit_kind(span: Span, kind: &ast::LitKind, name: Symbol) -> Op } #[derive(Diagnostic)] -#[diag(attr_parsing_rustc_promotable_pairing, code = E0717)] +#[diag("`rustc_promotable` attribute must be paired with either a `rustc_const_unstable` or a `rustc_const_stable` attribute", code = E0717)] pub(crate) struct RustcPromotablePairing { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(attr_parsing_rustc_allowed_unstable_pairing, code = E0789)] +#[diag("`rustc_allowed_through_unstable_modules` attribute must be paired with a `stable` attribute", code = E0789)] pub(crate) struct RustcAllowedUnstablePairing { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(attr_parsing_deprecated_item_suggestion)] +#[diag("suggestions on deprecated items are unstable")] pub(crate) struct DeprecatedItemSuggestion { #[primary_span] pub span: Span, - #[help] + #[help("add `#![feature(deprecated_suggestion)]` to the crate root")] pub is_nightly: bool, - #[note] + #[note("see #94785 for more details")] pub details: (), } #[derive(Diagnostic)] -#[diag(attr_parsing_expected_single_version_literal)] +#[diag("expected single version literal")] pub(crate) struct ExpectedSingleVersionLiteral { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(attr_parsing_expected_version_literal)] +#[diag("expected a version literal")] pub(crate) struct ExpectedVersionLiteral { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(attr_parsing_expects_feature_list)] +#[diag("`{$name}` expects a list of feature names")] pub(crate) struct ExpectsFeatureList { #[primary_span] pub span: Span, @@ -348,7 +350,7 @@ pub(crate) struct ExpectsFeatureList { } #[derive(Diagnostic)] -#[diag(attr_parsing_expects_features)] +#[diag("`{$name}` expects feature names")] pub(crate) struct ExpectsFeatures { #[primary_span] pub span: Span, @@ -357,21 +359,21 @@ pub(crate) struct ExpectsFeatures { } #[derive(Diagnostic)] -#[diag(attr_parsing_invalid_since)] +#[diag("'since' must be a Rust version number, such as \"1.31.0\"")] pub(crate) struct InvalidSince { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(attr_parsing_soft_no_args)] +#[diag("`soft` should not have any arguments")] pub(crate) struct SoftNoArgs { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(attr_parsing_unknown_version_literal)] +#[diag("unknown version literal format, assuming it refers to a future version")] pub(crate) struct UnknownVersionLiteral { #[primary_span] pub span: Span, @@ -379,78 +381,83 @@ pub(crate) struct UnknownVersionLiteral { // FIXME(jdonszelmann) duplicated from `rustc_passes`, remove once `check_attr` is integrated. #[derive(Diagnostic)] -#[diag(attr_parsing_unused_multiple)] +#[diag("multiple `{$name}` attributes")] pub(crate) struct UnusedMultiple { #[primary_span] - #[suggestion(code = "", applicability = "machine-applicable")] + #[suggestion("remove this attribute", code = "", applicability = "machine-applicable")] pub this: Span, - #[note] + #[note("attribute also specified here")] pub other: Span, pub name: Symbol, } #[derive(Diagnostic)] -#[diag(attr_parsing_null_on_export, code = E0648)] +#[diag("`export_name` may not contain null characters", code = E0648)] pub(crate) struct NullOnExport { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(attr_parsing_null_on_link_section, code = E0648)] +#[diag("`link_section` may not contain null characters", code = E0648)] pub(crate) struct NullOnLinkSection { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(attr_parsing_null_on_objc_class)] +#[diag("`objc::class!` may not contain null characters")] pub(crate) struct NullOnObjcClass { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(attr_parsing_null_on_objc_selector)] +#[diag("`objc::selector!` may not contain null characters")] pub(crate) struct NullOnObjcSelector { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(attr_parsing_objc_class_expected_string_literal)] +#[diag("`objc::class!` expected a string literal")] pub(crate) struct ObjcClassExpectedStringLiteral { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(attr_parsing_objc_selector_expected_string_literal)] +#[diag("`objc::selector!` expected a string literal")] pub(crate) struct ObjcSelectorExpectedStringLiteral { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(attr_parsing_stability_outside_std, code = E0734)] +#[diag("stability attributes may not be used outside of the standard library", code = E0734)] pub(crate) struct StabilityOutsideStd { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(attr_parsing_empty_confusables)] +#[diag("expected at least one confusable name")] pub(crate) struct EmptyConfusables { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[help] -#[diag(attr_parsing_invalid_target)] +#[help("`#[{$name}]` can {$only}be applied to {$applied}")] +#[diag("`#[{$name}]` attribute cannot be used on {$target}")] pub(crate) struct InvalidTarget { #[primary_span] - #[suggestion(code = "", applicability = "machine-applicable", style = "tool-only")] + #[suggestion( + "remove the attribute", + code = "", + applicability = "machine-applicable", + style = "tool-only" + )] pub span: Span, pub name: AttrPath, pub target: &'static str, @@ -459,7 +466,7 @@ pub(crate) struct InvalidTarget { } #[derive(Diagnostic)] -#[diag(attr_parsing_invalid_alignment_value, code = E0589)] +#[diag("invalid alignment value: {$error_part}", code = E0589)] pub(crate) struct InvalidAlignmentValue { #[primary_span] pub span: Span, @@ -467,43 +474,49 @@ pub(crate) struct InvalidAlignmentValue { } #[derive(Diagnostic)] -#[diag(attr_parsing_repr_ident, code = E0565)] +#[diag("meta item in `repr` must be an identifier", code = E0565)] pub(crate) struct ReprIdent { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(attr_parsing_unrecognized_repr_hint, code = E0552)] -#[help] -#[note] +#[diag("unrecognized representation hint", code = E0552)] +#[help( + "valid reprs are `Rust` (default), `C`, `align`, `packed`, `transparent`, `simd`, `i8`, `u8`, `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize`, `usize`" +)] +#[note( + "for more information, visit <https://doc.rust-lang.org/reference/type-layout.html?highlight=repr#representations>" +)] pub(crate) struct UnrecognizedReprHint { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(attr_parsing_unstable_feature_bound_incompatible_stability)] -#[help] +#[diag("item annotated with `#[unstable_feature_bound]` should not be stable")] +#[help( + "if this item is meant to be stable, do not use any functions annotated with `#[unstable_feature_bound]`. Otherwise, mark this item as unstable with `#[unstable]`" +)] pub(crate) struct UnstableFeatureBoundIncompatibleStability { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(attr_parsing_naked_functions_incompatible_attribute, code = E0736)] +#[diag("attribute incompatible with `#[unsafe(naked)]`", code = E0736)] pub(crate) struct NakedFunctionIncompatibleAttribute { #[primary_span] - #[label] + #[label("the `{$attr}` attribute is incompatible with `#[unsafe(naked)]`")] pub span: Span, - #[label(attr_parsing_naked_attribute)] + #[label("function marked with `#[unsafe(naked)]` here")] pub naked_span: Span, pub attr: String, } #[derive(Diagnostic)] -#[diag(attr_parsing_link_ordinal_out_of_range)] -#[note] +#[diag("ordinal value in `link_ordinal` is too large: `{$ordinal}`")] +#[note("the value may not exceed `u16::MAX`")] pub(crate) struct LinkOrdinalOutOfRange { #[primary_span] pub span: Span, @@ -511,8 +524,8 @@ pub(crate) struct LinkOrdinalOutOfRange { } #[derive(Diagnostic)] -#[diag(attr_parsing_rustc_scalable_vector_count_out_of_range)] -#[note] +#[diag("element count in `rustc_scalable_vector` is too large: `{$n}`")] +#[note("the value may not exceed `u16::MAX`")] pub(crate) struct RustcScalableVectorCountOutOfRange { #[primary_span] pub span: Span, @@ -524,6 +537,7 @@ pub(crate) enum AttributeParseErrorReason<'a> { ExpectedStringLiteral { byte_string: Option<Span>, }, + ExpectedFilenameLiteral, ExpectedIntegerLiteral, ExpectedIntegerLiteralInRange { lower_bound: isize, @@ -586,7 +600,7 @@ fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G> { if let Some(start_point_span) = byte_string { diag.span_suggestion( start_point_span, - fluent::attr_parsing_unsupported_literal_suggestion, + "consider removing the prefix", "", Applicability::MaybeIncorrect, ); @@ -597,6 +611,9 @@ fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G> { diag.span_label(self.span, "expected a string literal here"); } } + AttributeParseErrorReason::ExpectedFilenameLiteral => { + diag.span_label(self.span, "expected a filename string literal here"); + } AttributeParseErrorReason::ExpectedIntegerLiteral => { diag.span_label(self.span, "expected an integer literal here"); } @@ -751,30 +768,27 @@ fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G> { } #[derive(Diagnostic)] -#[diag(attr_parsing_invalid_attr_unsafe)] -#[note] +#[diag("`{$name}` is not an unsafe attribute")] +#[note("extraneous unsafe is not allowed in attributes")] pub(crate) struct InvalidAttrUnsafe { #[primary_span] - #[label] + #[label("this is not an unsafe attribute")] pub span: Span, pub name: AttrPath, } #[derive(Diagnostic)] -#[diag(attr_parsing_unsafe_attr_outside_unsafe)] +#[diag("unsafe attribute used without unsafe")] pub(crate) struct UnsafeAttrOutsideUnsafe { #[primary_span] - #[label] + #[label("usage of unsafe attribute")] pub span: Span, #[subdiagnostic] pub suggestion: Option<UnsafeAttrOutsideUnsafeSuggestion>, } #[derive(Subdiagnostic)] -#[multipart_suggestion( - attr_parsing_unsafe_attr_outside_unsafe_suggestion, - applicability = "machine-applicable" -)] +#[multipart_suggestion("wrap the attribute in `unsafe(...)`", applicability = "machine-applicable")] pub(crate) struct UnsafeAttrOutsideUnsafeSuggestion { #[suggestion_part(code = "unsafe(")] pub left: Span, @@ -783,7 +797,7 @@ pub(crate) struct UnsafeAttrOutsideUnsafeSuggestion { } #[derive(Diagnostic)] -#[diag(attr_parsing_meta_bad_delim)] +#[diag("wrong meta list delimiters")] pub(crate) struct MetaBadDelim { #[primary_span] pub span: Span, @@ -793,7 +807,7 @@ pub(crate) struct MetaBadDelim { #[derive(Subdiagnostic)] #[multipart_suggestion( - attr_parsing_meta_bad_delim_suggestion, + "the delimiters should be `(` and `)`", applicability = "machine-applicable" )] pub(crate) struct MetaBadDelimSugg { @@ -804,7 +818,7 @@ pub(crate) struct MetaBadDelimSugg { } #[derive(Diagnostic)] -#[diag(attr_parsing_invalid_meta_item)] +#[diag("expected a literal (`1u8`, `1.0f32`, `\"string\"`, etc.) here, found {$descr}")] pub(crate) struct InvalidMetaItem { #[primary_span] pub span: Span, @@ -813,12 +827,15 @@ pub(crate) struct InvalidMetaItem { pub quote_ident_sugg: Option<InvalidMetaItemQuoteIdentSugg>, #[subdiagnostic] pub remove_neg_sugg: Option<InvalidMetaItemRemoveNegSugg>, - #[label] + #[label("{$descr}s are not allowed here")] pub label: Option<Span>, } #[derive(Subdiagnostic)] -#[multipart_suggestion(attr_parsing_quote_ident_sugg, applicability = "machine-applicable")] +#[multipart_suggestion( + "surround the identifier with quotation marks to make it into a string literal", + applicability = "machine-applicable" +)] pub(crate) struct InvalidMetaItemQuoteIdentSugg { #[suggestion_part(code = "\"")] pub before: Span, @@ -827,73 +844,80 @@ pub(crate) struct InvalidMetaItemQuoteIdentSugg { } #[derive(Subdiagnostic)] -#[multipart_suggestion(attr_parsing_remove_neg_sugg, applicability = "machine-applicable")] +#[multipart_suggestion( + "negative numbers are not literals, try removing the `-` sign", + applicability = "machine-applicable" +)] pub(crate) struct InvalidMetaItemRemoveNegSugg { #[suggestion_part(code = "")] pub negative_sign: Span, } #[derive(Diagnostic)] -#[diag(attr_parsing_suffixed_literal_in_attribute)] -#[help] +#[diag("suffixed literals are not allowed in attributes")] +#[help( + "instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.)" +)] pub(crate) struct SuffixedLiteralInAttribute { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(attr_parsing_empty_link_name, code = E0454)] +#[diag("link name must not be empty", code = E0454)] pub(crate) struct EmptyLinkName { #[primary_span] - #[label] + #[label("empty link name")] pub span: Span, } #[derive(Diagnostic)] -#[diag(attr_parsing_link_framework_apple, code = E0455)] +#[diag("link kind `framework` is only supported on Apple targets", code = E0455)] pub(crate) struct LinkFrameworkApple { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(attr_parsing_incompatible_wasm_link)] +#[diag("`wasm_import_module` is incompatible with other arguments in `#[link]` attributes")] pub(crate) struct IncompatibleWasmLink { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(attr_parsing_link_requires_name, code = E0459)] +#[diag("`#[link]` attribute requires a `name = \"string\"` argument", code = E0459)] pub(crate) struct LinkRequiresName { #[primary_span] - #[label] + #[label("missing `name` argument")] pub span: Span, } #[derive(Diagnostic)] -#[diag(attr_parsing_raw_dylib_no_nul)] +#[diag("link name must not contain NUL characters if link kind is `raw-dylib`")] pub(crate) struct RawDylibNoNul { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(attr_parsing_raw_dylib_only_windows, code = E0455)] +#[diag("link kind `raw-dylib` is only supported on Windows targets", code = E0455)] pub(crate) struct RawDylibOnlyWindows { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(attr_parsing_invalid_link_modifier)] +#[diag( + "invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed, export-symbols" +)] pub(crate) struct InvalidLinkModifier { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(attr_parsing_multiple_modifiers)] +#[diag("multiple `{$modifier}` modifiers in a single `modifiers` argument")] pub(crate) struct MultipleModifiers { #[primary_span] pub span: Span, @@ -901,52 +925,61 @@ pub(crate) struct MultipleModifiers { } #[derive(Diagnostic)] -#[diag(attr_parsing_import_name_type_x86)] +#[diag("import name type is only supported on x86")] pub(crate) struct ImportNameTypeX86 { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(attr_parsing_bundle_needs_static)] +#[diag("linking modifier `bundle` is only compatible with `static` linking kind")] pub(crate) struct BundleNeedsStatic { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(attr_parsing_whole_archive_needs_static)] +#[diag("linking modifier `export-symbols` is only compatible with `static` linking kind")] +pub(crate) struct ExportSymbolsNeedsStatic { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag("linking modifier `whole-archive` is only compatible with `static` linking kind")] pub(crate) struct WholeArchiveNeedsStatic { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(attr_parsing_as_needed_compatibility)] +#[diag( + "linking modifier `as-needed` is only compatible with `dylib`, `framework` and `raw-dylib` linking kinds" +)] pub(crate) struct AsNeededCompatibility { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(attr_parsing_import_name_type_raw)] +#[diag("import name type can only be used with link kind `raw-dylib`")] pub(crate) struct ImportNameTypeRaw { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(attr_parsing_limit_invalid)] +#[diag("`limit` must be a non-negative integer")] pub(crate) struct LimitInvalid<'a> { #[primary_span] pub span: Span, - #[label] + #[label("{$error_str}")] pub value_span: Span, pub error_str: &'a str, } #[derive(Diagnostic)] -#[diag(attr_parsing_cfg_attr_bad_delim)] +#[diag("wrong `cfg_attr` delimiters")] pub(crate) struct CfgAttrBadDelim { #[primary_span] pub span: Span, @@ -955,14 +988,16 @@ pub(crate) struct CfgAttrBadDelim { } #[derive(Diagnostic)] -#[diag(attr_parsing_doc_alias_malformed)] +#[diag( + "doc alias attribute expects a string `#[doc(alias = \"a\")]` or a list of strings `#[doc(alias(\"a\", \"b\"))]`" +)] pub(crate) struct DocAliasMalformed { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(attr_parsing_unsupported_instruction_set)] +#[diag("target `{$current_target}` does not support `#[instruction_set({$instruction_set}::*)]`")] pub(crate) struct UnsupportedInstructionSet<'a> { #[primary_span] pub span: Span,
diff --git a/compiler/rustc_codegen_ssa/Cargo.toml b/compiler/rustc_codegen_ssa/Cargo.toml index 9c5a3d8..3d045a0 100644 --- a/compiler/rustc_codegen_ssa/Cargo.toml +++ b/compiler/rustc_codegen_ssa/Cargo.toml
@@ -28,7 +28,6 @@ rustc_macros = { path = "../rustc_macros" } rustc_metadata = { path = "../rustc_metadata" } rustc_middle = { path = "../rustc_middle" } -rustc_query_system = { path = "../rustc_query_system" } rustc_serialize = { path = "../rustc_serialize" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" }
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index c8109db..5a73238 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -11,10 +11,11 @@ use find_msvc_tools; use itertools::Itertools; +use object::{Object, ObjectSection, ObjectSymbol}; use regex::Regex; use rustc_arena::TypedArena; use rustc_attr_parsing::eval_config_entry; -use rustc_data_structures::fx::FxIndexSet; +use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; use rustc_data_structures::memmap::Mmap; use rustc_data_structures::temp_dir::MaybeTempDir; use rustc_errors::{DiagCtxtHandle, LintDiagnostic}; @@ -2185,6 +2186,71 @@ fn add_rpath_args( } } +fn add_c_staticlib_symbols( + sess: &Session, + lib: &NativeLib, + out: &mut Vec<(String, SymbolExportKind)>, +) -> io::Result<()> { + let file_path = find_native_static_library(lib.name.as_str(), lib.verbatim, sess); + + let archive_map = unsafe { Mmap::map(File::open(&file_path)?)? }; + + let archive = object::read::archive::ArchiveFile::parse(&*archive_map) + .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?; + + for member in archive.members() { + let member = member.map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?; + + let data = member + .data(&*archive_map) + .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?; + + // clang LTO: raw LLVM bitcode + if data.starts_with(b"BC\xc0\xde") { + return Err(io::Error::new( + io::ErrorKind::InvalidData, + "LLVM bitcode object in C static library (LTO not supported)", + )); + } + + let object = object::File::parse(&*data) + .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?; + + // gcc / clang ELF / Mach-O LTO + if object.sections().any(|s| { + s.name().map(|n| n.starts_with(".gnu.lto_") || n == ".llvm.lto").unwrap_or(false) + }) { + return Err(io::Error::new( + io::ErrorKind::InvalidData, + "LTO object in C static library is not supported", + )); + } + + for symbol in object.symbols() { + if symbol.scope() != object::SymbolScope::Dynamic { + continue; + } + + let name = match symbol.name() { + Ok(n) => n, + Err(_) => continue, + }; + + let export_kind = match symbol.kind() { + object::SymbolKind::Text => SymbolExportKind::Text, + object::SymbolKind::Data => SymbolExportKind::Data, + _ => continue, + }; + + // FIXME:The symbol mangle rules are slightly different in Windows(32-bit) and Apple. + // Need to be resolved. + out.push((name.to_string(), export_kind)); + } + } + + Ok(()) +} + /// Produce the linker command line containing linker path and arguments. /// /// When comments in the function say "order-(in)dependent" they mean order-dependence between @@ -2217,6 +2283,25 @@ fn linker_with_args( ); let link_output_kind = link_output_kind(sess, crate_type); + let mut export_symbols = codegen_results.crate_info.exported_symbols[&crate_type].clone(); + + if crate_type == CrateType::Cdylib { + let mut seen = FxHashSet::default(); + + for lib in &codegen_results.crate_info.used_libraries { + if let NativeLibKind::Static { export_symbols: Some(true), .. } = lib.kind + && seen.insert((lib.name, lib.verbatim)) + { + if let Err(err) = add_c_staticlib_symbols(&sess, lib, &mut export_symbols) { + sess.dcx().fatal(format!( + "failed to process C static library `{}`: {}", + lib.name, err + )); + } + } + } + } + // ------------ Early order-dependent options ------------ // If we're building something like a dynamic library then some platforms @@ -2224,11 +2309,7 @@ fn linker_with_args( // dynamic library. // Must be passed before any libraries to prevent the symbols to export from being thrown away, // at least on some platforms (e.g. windows-gnu). - cmd.export_symbols( - tmpdir, - crate_type, - &codegen_results.crate_info.exported_symbols[&crate_type], - ); + cmd.export_symbols(tmpdir, crate_type, &export_symbols); // Can be used for adding custom CRT objects or overriding order-dependent options above. // FIXME: In practice built-in target specs use this for arbitrary order-independent options, @@ -2678,7 +2759,7 @@ fn add_native_libs_from_crate( let name = lib.name.as_str(); let verbatim = lib.verbatim; match lib.kind { - NativeLibKind::Static { bundle, whole_archive } => { + NativeLibKind::Static { bundle, whole_archive, .. } => { if link_static { let bundle = bundle.unwrap_or(true); let whole_archive = whole_archive == Some(true);
diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index 3ffc16d..5cca916 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs
@@ -24,7 +24,7 @@ use rustc_hir::CRATE_HIR_ID; use rustc_hir::attrs::{CfgEntry, NativeLibKind, WindowsSubsystemKind}; use rustc_hir::def_id::CrateNum; -use rustc_macros::{Decodable, Encodable, HashStable}; +use rustc_macros::{Decodable, Encodable}; use rustc_metadata::EncodedMetadata; use rustc_middle::dep_graph::WorkProduct; use rustc_middle::lint::LevelAndSource; @@ -175,7 +175,12 @@ pub struct MemFlags: u8 { } } -#[derive(Clone, Debug, Encodable, Decodable, HashStable)] +// This is the same as `rustc_session::cstore::NativeLib`, except: +// - (important) the `foreign_module` field is missing, because it contains a `DefId`, which can't +// be encoded with `FileEncoder`. +// - (less important) the `verbatim` field is a `bool` rather than an `Option<bool>`, because here +// we can treat `false` and `absent` the same. +#[derive(Clone, Debug, Encodable, Decodable)] pub struct NativeLib { pub kind: NativeLibKind, pub name: Symbol,
diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs index d472c14..fb07d5f 100644 --- a/compiler/rustc_const_eval/src/interpret/place.rs +++ b/compiler/rustc_const_eval/src/interpret/place.rs
@@ -5,8 +5,8 @@ use either::{Either, Left, Right}; use rustc_abi::{BackendRepr, HasDataLayout, Size}; use rustc_data_structures::assert_matches; -use rustc_middle::ty::Ty; use rustc_middle::ty::layout::TyAndLayout; +use rustc_middle::ty::{self, Ty}; use rustc_middle::{bug, mir, span_bug}; use tracing::field::Empty; use tracing::{instrument, trace}; @@ -884,10 +884,38 @@ pub(super) fn copy_op_no_validate( dest.layout().ty, ); } + // If the source has padding, we want to always do a mem-to-mem copy to ensure consistent + // padding in the target independent of layout choices. + let src_has_padding = match src.layout().backend_repr { + BackendRepr::Scalar(_) => false, + BackendRepr::ScalarPair(left, right) + if matches!(src.layout().ty.kind(), ty::Ref(..) | ty::RawPtr(..)) => + { + // Wide pointers never have padding, so we can avoid calling `size()`. + debug_assert_eq!(left.size(self) + right.size(self), src.layout().size); + false + } + BackendRepr::ScalarPair(left, right) => { + let left_size = left.size(self); + let right_size = right.size(self); + // We have padding if the sizes don't add up to the total. + left_size + right_size != src.layout().size + } + // Everything else can only exist in memory anyway, so it doesn't matter. + BackendRepr::SimdVector { .. } + | BackendRepr::ScalableVector { .. } + | BackendRepr::Memory { .. } => true, + }; - // Let us see if the layout is simple so we take a shortcut, - // avoid force_allocation. - let src = match self.read_immediate_raw(src)? { + let src_val = if src_has_padding { + // Do our best to get an mplace. If there's no mplace, then this is stored as an + // "optimized" local, so its padding is definitely uninitialized and we are fine. + src.to_op(self)?.as_mplace_or_imm() + } else { + // Do our best to get an immediate, to avoid having to force_allocate the destination. + self.read_immediate_raw(src)? + }; + let src = match src_val { Right(src_val) => { assert!(!src.layout().is_unsized()); assert!(!dest.layout().is_unsized());
diff --git a/compiler/rustc_const_eval/src/interpret/projection.rs b/compiler/rustc_const_eval/src/interpret/projection.rs index 027e634..db72c02 100644 --- a/compiler/rustc_const_eval/src/interpret/projection.rs +++ b/compiler/rustc_const_eval/src/interpret/projection.rs
@@ -97,7 +97,7 @@ fn transmute<M: Machine<'tcx, Provenance = Prov>>( } /// Convert this to an `OpTy`. This might be an irreversible transformation, but is useful for - /// reading from this thing. + /// reading from this thing. This will never actually do a read from memory! fn to_op<M: Machine<'tcx, Provenance = Prov>>( &self, ecx: &InterpCx<'tcx, M>,
diff --git a/compiler/rustc_data_structures/src/vec_cache.rs b/compiler/rustc_data_structures/src/vec_cache.rs index 70524ba..f9f5871 100644 --- a/compiler/rustc_data_structures/src/vec_cache.rs +++ b/compiler/rustc_data_structures/src/vec_cache.rs
@@ -359,6 +359,10 @@ pub fn iter(&self, f: &mut dyn FnMut(&K, &V, I)) { } } } + + pub fn len(&self) -> usize { + self.len.load(Ordering::Acquire) + } } #[cfg(test)]
diff --git a/compiler/rustc_driver_impl/Cargo.toml b/compiler/rustc_driver_impl/Cargo.toml index 28972d1..cae2e3b 100644 --- a/compiler/rustc_driver_impl/Cargo.toml +++ b/compiler/rustc_driver_impl/Cargo.toml
@@ -12,7 +12,6 @@ rustc_ast_lowering = { path = "../rustc_ast_lowering" } rustc_ast_passes = { path = "../rustc_ast_passes" } rustc_ast_pretty = { path = "../rustc_ast_pretty" } -rustc_attr_parsing = { path = "../rustc_attr_parsing" } rustc_borrowck = { path = "../rustc_borrowck" } rustc_builtin_macros = { path = "../rustc_builtin_macros" } rustc_codegen_ssa = { path = "../rustc_codegen_ssa" } @@ -24,9 +23,7 @@ rustc_hir_analysis = { path = "../rustc_hir_analysis" } rustc_hir_pretty = { path = "../rustc_hir_pretty" } rustc_hir_typeck = { path = "../rustc_hir_typeck" } -rustc_incremental = { path = "../rustc_incremental" } rustc_index = { path = "../rustc_index" } -rustc_infer = { path = "../rustc_infer" } rustc_interface = { path = "../rustc_interface" } rustc_lexer = { path = "../rustc_lexer" } rustc_lint = { path = "../rustc_lint" } @@ -35,20 +32,16 @@ rustc_metadata = { path = "../rustc_metadata" } rustc_middle = { path = "../rustc_middle" } rustc_mir_build = { path = "../rustc_mir_build" } -rustc_mir_dataflow = { path = "../rustc_mir_dataflow" } rustc_mir_transform = { path = "../rustc_mir_transform" } rustc_parse = { path = "../rustc_parse" } rustc_passes = { path = "../rustc_passes" } rustc_pattern_analysis = { path = "../rustc_pattern_analysis" } -rustc_privacy = { path = "../rustc_privacy" } rustc_public = { path = "../rustc_public", features = ["rustc_internal"] } -rustc_query_system = { path = "../rustc_query_system" } rustc_resolve = { path = "../rustc_resolve" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } rustc_trait_selection = { path = "../rustc_trait_selection" } -rustc_ty_utils = { path = "../rustc_ty_utils" } serde_json = "1.0.59" shlex = "1.0" tracing = { version = "0.1.35" }
diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 80724c6..3b9ca5f 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs
@@ -116,7 +116,6 @@ pub fn default_translator() -> Translator { // tidy-alphabetical-start rustc_ast_lowering::DEFAULT_LOCALE_RESOURCE, rustc_ast_passes::DEFAULT_LOCALE_RESOURCE, - rustc_attr_parsing::DEFAULT_LOCALE_RESOURCE, rustc_borrowck::DEFAULT_LOCALE_RESOURCE, rustc_builtin_macros::DEFAULT_LOCALE_RESOURCE, rustc_codegen_ssa::DEFAULT_LOCALE_RESOURCE, @@ -125,24 +124,16 @@ pub fn default_translator() -> Translator { rustc_expand::DEFAULT_LOCALE_RESOURCE, rustc_hir_analysis::DEFAULT_LOCALE_RESOURCE, rustc_hir_typeck::DEFAULT_LOCALE_RESOURCE, - rustc_incremental::DEFAULT_LOCALE_RESOURCE, - rustc_infer::DEFAULT_LOCALE_RESOURCE, - rustc_interface::DEFAULT_LOCALE_RESOURCE, rustc_lint::DEFAULT_LOCALE_RESOURCE, rustc_metadata::DEFAULT_LOCALE_RESOURCE, rustc_middle::DEFAULT_LOCALE_RESOURCE, rustc_mir_build::DEFAULT_LOCALE_RESOURCE, - rustc_mir_dataflow::DEFAULT_LOCALE_RESOURCE, rustc_mir_transform::DEFAULT_LOCALE_RESOURCE, rustc_parse::DEFAULT_LOCALE_RESOURCE, rustc_passes::DEFAULT_LOCALE_RESOURCE, rustc_pattern_analysis::DEFAULT_LOCALE_RESOURCE, - rustc_privacy::DEFAULT_LOCALE_RESOURCE, - rustc_query_system::DEFAULT_LOCALE_RESOURCE, rustc_resolve::DEFAULT_LOCALE_RESOURCE, - rustc_session::DEFAULT_LOCALE_RESOURCE, rustc_trait_selection::DEFAULT_LOCALE_RESOURCE, - rustc_ty_utils::DEFAULT_LOCALE_RESOURCE, // tidy-alphabetical-end ];
diff --git a/compiler/rustc_errors/src/translation.rs b/compiler/rustc_errors/src/translation.rs index 0ee2b7b..aba79c3 100644 --- a/compiler/rustc_errors/src/translation.rs +++ b/compiler/rustc_errors/src/translation.rs
@@ -166,3 +166,14 @@ pub fn translate_message<'a>( } } } + +/// This macro creates a translatable `DiagMessage` from a literal string. +/// It should be used in places where a translatable message is needed, but struct diagnostics are undesired. +/// +/// This is a macro because in the future we may want to globally register these messages. +#[macro_export] +macro_rules! inline_fluent { + ($inline: literal) => { + rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed($inline)) + }; +}
diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 48e2ee8..449dc95 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs
@@ -508,6 +508,7 @@ pub fn fully_expand_fragment(&mut self, input_fragment: AstFragment) -> AstFragm // Unresolved macros produce dummy outputs as a recovery measure. invocations.reverse(); let mut expanded_fragments = Vec::new(); + let mut expanded_fragments_len = 0; let mut undetermined_invocations = Vec::new(); let (mut progress, mut force) = (false, !self.monotonic); loop { @@ -602,6 +603,7 @@ pub fn fully_expand_fragment(&mut self, input_fragment: AstFragment) -> AstFragm expanded_fragments.push(Vec::new()); } expanded_fragments[depth - 1].push((expn_id, expanded_fragment)); + expanded_fragments_len += 1; invocations.extend(derive_invocations.into_iter().rev()); } ExpandResult::Retry(invoc) => { @@ -622,7 +624,7 @@ pub fn fully_expand_fragment(&mut self, input_fragment: AstFragment) -> AstFragm self.cx.force_mode = orig_force_mode; // Finally incorporate all the expanded macros into the input AST fragment. - let mut placeholder_expander = PlaceholderExpander::default(); + let mut placeholder_expander = PlaceholderExpander::with_capacity(expanded_fragments_len); while let Some(expanded_fragments) = expanded_fragments.pop() { for (expn_id, expanded_fragment) in expanded_fragments.into_iter().rev() { placeholder_expander
diff --git a/compiler/rustc_expand/src/placeholders.rs b/compiler/rustc_expand/src/placeholders.rs index 05f9a5a..2db1842 100644 --- a/compiler/rustc_expand/src/placeholders.rs +++ b/compiler/rustc_expand/src/placeholders.rs
@@ -218,12 +218,17 @@ fn mac_placeholder() -> Box<ast::MacCall> { } } -#[derive(Default)] pub(crate) struct PlaceholderExpander { expanded_fragments: FxHashMap<ast::NodeId, AstFragment>, } impl PlaceholderExpander { + pub(crate) fn with_capacity(capacity: usize) -> Self { + PlaceholderExpander { + expanded_fragments: FxHashMap::with_capacity_and_hasher(capacity, Default::default()), + } + } + pub(crate) fn add(&mut self, id: ast::NodeId, mut fragment: AstFragment) { fragment.mut_visit_with(self); self.expanded_fragments.insert(id, fragment);
diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index fba53c9..a53eff4 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs
@@ -331,6 +331,8 @@ pub enum NativeLibKind { bundle: Option<bool>, /// Whether to link static library without throwing any object files away whole_archive: Option<bool>, + /// Whether to export c static library symbols + export_symbols: Option<bool>, }, /// Dynamic library (e.g. `libfoo.so` on Linux) /// or an import library corresponding to a dynamic library (e.g. `foo.lib` on Windows/MSVC). @@ -363,8 +365,8 @@ pub enum NativeLibKind { impl NativeLibKind { pub fn has_modifiers(&self) -> bool { match self { - NativeLibKind::Static { bundle, whole_archive } => { - bundle.is_some() || whole_archive.is_some() + NativeLibKind::Static { bundle, whole_archive, export_symbols } => { + bundle.is_some() || whole_archive.is_some() || export_symbols.is_some() } NativeLibKind::Dylib { as_needed } | NativeLibKind::Framework { as_needed } @@ -699,6 +701,21 @@ pub enum RustcLayoutType { Debug, } +#[derive(Clone, Debug, HashStable_Generic, Encodable, Decodable, PrintAttribute, PartialEq, Eq)] +pub enum RustcMirKind { + PeekMaybeInit, + PeekMaybeUninit, + PeekLiveness, + StopAfterDataflow, + BorrowckGraphvizPostflow { path: PathBuf }, + BorrowckGraphvizFormat { format: BorrowckGraphvizFormatKind }, +} + +#[derive(Clone, Debug, HashStable_Generic, Encodable, Decodable, PrintAttribute, PartialEq, Eq)] +pub enum BorrowckGraphvizFormatKind { + TwoPhase, +} + /// Represents parsed *built-in* inert attributes. /// /// ## Overview @@ -1090,6 +1107,9 @@ pub enum AttributeKind { /// Represents `#[rustc_main]`. RustcMain, + /// Represents `#[rustc_mir]`. + RustcMir(ThinVec<RustcMirKind>), + /// Represents `#[rustc_must_implement_one_of]` RustcMustImplementOneOf { attr_span: Span, fn_names: ThinVec<Ident> },
diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index 26e5fc6..7ec1920 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs
@@ -122,6 +122,7 @@ pub fn encode_cross_crate(&self) -> EncodeCrossCrate { RustcLintUntrackedQueryInformation => Yes, RustcMacroTransparency(..) => Yes, RustcMain => No, + RustcMir(..) => Yes, RustcMustImplementOneOf { .. } => No, RustcNeverReturnsNullPointer => Yes, RustcNoImplicitAutorefs => Yes,
diff --git a/compiler/rustc_hir/src/attrs/pretty_printing.rs b/compiler/rustc_hir/src/attrs/pretty_printing.rs index c2ad644..bd268d2 100644 --- a/compiler/rustc_hir/src/attrs/pretty_printing.rs +++ b/compiler/rustc_hir/src/attrs/pretty_printing.rs
@@ -1,5 +1,6 @@ use std::num::NonZero; use std::ops::Deref; +use std::path::PathBuf; use rustc_abi::Align; use rustc_ast::attr::data_structures::CfgEntry; @@ -96,7 +97,15 @@ fn print_attribute(&self, p: &mut Printer) { p.word("]"); } } +impl PrintAttribute for PathBuf { + fn should_render(&self) -> bool { + true + } + fn print_attribute(&self, p: &mut Printer) { + p.word(self.display().to_string()); + } +} macro_rules! print_skip { ($($t: ty),* $(,)?) => {$( impl PrintAttribute for $t {
diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index d9f8eba..33b8d3c 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl
@@ -224,6 +224,10 @@ hir_analysis_impl_not_marked_default_err = `{$ident}` specializes an item from a parent `impl`, but that item is not marked `default` .note = parent implementation is in crate `{$cname}` +hir_analysis_impl_unpin_for_pin_projected_type = explicit impls for the `Unpin` trait are not permitted for structurally pinned types + .label = impl of `Unpin` not allowed + .help = `{$adt_name}` is structurally pinned because it is marked as `#[pin_v2]` + hir_analysis_inherent_dyn = cannot define inherent `impl` for a dyn auto trait .label = impl requires at least one non-auto trait .note = define and implement a new trait or type instead
diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index 61562cc..f81913a 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs
@@ -38,6 +38,7 @@ pub(super) fn check_trait<'tcx>( checker.check(lang_items.drop_trait(), visit_implementation_of_drop)?; checker.check(lang_items.async_drop_trait(), visit_implementation_of_drop)?; checker.check(lang_items.copy_trait(), visit_implementation_of_copy)?; + checker.check(lang_items.unpin_trait(), visit_implementation_of_unpin)?; checker.check(lang_items.const_param_ty_trait(), |checker| { visit_implementation_of_const_param_ty(checker) })?; @@ -134,6 +135,41 @@ fn visit_implementation_of_copy(checker: &Checker<'_>) -> Result<(), ErrorGuaran } } +fn visit_implementation_of_unpin(checker: &Checker<'_>) -> Result<(), ErrorGuaranteed> { + let tcx = checker.tcx; + let impl_header = checker.impl_header; + let impl_did = checker.impl_def_id; + debug!("visit_implementation_of_unpin: impl_did={:?}", impl_did); + + let self_type = impl_header.trait_ref.instantiate_identity().self_ty(); + debug!("visit_implementation_of_unpin: self_type={:?}", self_type); + + let span = tcx.def_span(impl_did); + + if tcx.features().pin_ergonomics() { + match self_type.kind() { + // Soundness concerns: a type `T` annotated with `#[pin_v2]` is allowed to project + // `Pin<&mut T>` to its field `Pin<&mut U>` safely (even if `U: !Unpin`). + // If `T` is allowed to impl `Unpin` manually (note that `Unpin` is a safe trait, + // which cannot carry safety properties), then `&mut U` could be obtained from + // `&mut T` that dereferenced by `Pin<&mut T>`, which breaks the safety contract of + // `Pin<&mut U>` for `U: !Unpin`. + ty::Adt(adt, _) if adt.is_pin_project() => { + return Err(tcx.dcx().emit_err(crate::errors::ImplUnpinForPinProjectedType { + span, + adt_span: tcx.def_span(adt.did()), + adt_name: tcx.item_name(adt.did()), + })); + } + ty::Adt(_, _) => {} + _ => { + return Err(tcx.dcx().span_delayed_bug(span, "impl of `Unpin` for a non-adt type")); + } + }; + } + Ok(()) +} + fn visit_implementation_of_const_param_ty(checker: &Checker<'_>) -> Result<(), ErrorGuaranteed> { let tcx = checker.tcx; let header = checker.impl_header;
diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 2a77d0b..f0c9023 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs
@@ -1690,3 +1690,14 @@ pub(crate) struct EiiWithGenerics { pub eii_name: Symbol, pub impl_name: Symbol, } + +#[derive(Diagnostic)] +#[diag(hir_analysis_impl_unpin_for_pin_projected_type)] +pub(crate) struct ImplUnpinForPinProjectedType { + #[primary_span] + #[label] + pub span: Span, + #[help] + pub adt_span: Span, + pub adt_name: Symbol, +}
diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 39c28c4..6e126b3 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs
@@ -200,6 +200,14 @@ fn typeck_with_inspect<'tcx>( let wf_code = ObligationCauseCode::WellFormed(Some(WellFormedLoc::Ty(def_id))); fcx.register_wf_obligation(expected_type.into(), body.value.span, wf_code); + if let hir::Node::AnonConst(_) = node { + fcx.require_type_is_sized( + expected_type, + body.value.span, + ObligationCauseCode::SizedConstOrStatic, + ); + } + fcx.check_expr_coercible_to_type(body.value, expected_type, None); fcx.write_ty(id, expected_type);
diff --git a/compiler/rustc_incremental/Cargo.toml b/compiler/rustc_incremental/Cargo.toml index db0a584..ae96cc6 100644 --- a/compiler/rustc_incremental/Cargo.toml +++ b/compiler/rustc_incremental/Cargo.toml
@@ -9,7 +9,6 @@ rustc_ast = { path = "../rustc_ast" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } -rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_fs_util = { path = "../rustc_fs_util" } rustc_graphviz = { path = "../rustc_graphviz" } rustc_hashes = { path = "../rustc_hashes" }
diff --git a/compiler/rustc_incremental/messages.ftl b/compiler/rustc_incremental/messages.ftl deleted file mode 100644 index bbc1fab..0000000 --- a/compiler/rustc_incremental/messages.ftl +++ /dev/null
@@ -1,102 +0,0 @@ -incremental_assert_loaded = - we asserted that an existing incremental cache directory should be successfully loaded, but it was not - -incremental_assert_not_loaded = - we asserted that the incremental cache should not be loaded, but it was loaded - -incremental_assertion_auto = - `except` specified DepNodes that can not be affected for "{$name}": "{$e}" - -incremental_associated_value_expected = expected an associated value - -incremental_associated_value_expected_for = associated value expected for `{$ident}` - -incremental_canonicalize_path = incremental compilation: error canonicalizing path `{$path}`: {$err} - -incremental_cargo_help_1 = - incremental compilation can be disabled by setting the environment variable CARGO_INCREMENTAL=0 (see https://doc.rust-lang.org/cargo/reference/profiles.html#incremental) -incremental_cargo_help_2 = - the entire build directory can be changed to a different filesystem by setting the environment variable CARGO_TARGET_DIR to a different path (see https://doc.rust-lang.org/cargo/reference/config.html#buildtarget-dir) - -incremental_copy_workproduct_to_cache = - error copying object file `{$from}` to incremental directory as `{$to}`: {$err} - -incremental_corrupt_file = corrupt incremental compilation artifact found at `{$path}`. This file will automatically be ignored and deleted. If you see this message repeatedly or can provoke it without manually manipulating the compiler's artifacts, please file an issue. The incremental compilation system relies on hardlinks and filesystem locks behaving correctly, and may not deal well with OS crashes, so whatever information you can provide about your filesystem or other state may be very relevant. - -incremental_create_dep_graph = failed to create dependency graph at `{$path}`: {$err} - -incremental_create_incr_comp_dir = - could not create incremental compilation {$tag} directory `{$path}`: {$err} - -incremental_create_lock = - incremental compilation: could not create session directory lock file: {$lock_err} -incremental_create_new = failed to create {$name} at `{$path}`: {$err} - -incremental_delete_full = error deleting incremental compilation session directory `{$path}`: {$err} - -incremental_delete_incompatible = - failed to delete invalidated or incompatible incremental compilation session directory contents `{$path}`: {$err} - -incremental_delete_lock = - error deleting lock file for incremental compilation session directory `{$path}`: {$err} - -incremental_delete_old = unable to delete old {$name} at `{$path}`: {$err} - -incremental_delete_partial = failed to delete partly initialized session dir `{$path}`: {$err} - -incremental_delete_workproduct = file-system error deleting outdated file `{$path}`: {$err} - -incremental_finalize = error finalizing incremental compilation session directory `{$path}`: {$err} - -incremental_finalized_gc_failed = - failed to garbage collect finalized incremental compilation session directory `{$path}`: {$err} - -incremental_hard_link_failed = - hard linking files in the incremental compilation cache failed. copying files instead. consider moving the cache directory to a file system which supports hard linking in session dir `{$path}` - -incremental_invalid_gc_failed = - failed to garbage collect invalid incremental compilation session directory `{$path}`: {$err} - -incremental_load_dep_graph = could not load dep-graph from `{$path}`: {$err} - -incremental_lock_unsupported = - the filesystem for the incremental path at {$session_dir} does not appear to support locking, consider changing the incremental path to a filesystem that supports locking or disable incremental compilation - -incremental_missing_depnode = missing `DepNode` variant - -incremental_missing_if_this_changed = no `#[rustc_if_this_changed]` annotation detected - -incremental_move_dep_graph = failed to move dependency graph from `{$from}` to `{$to}`: {$err} - -incremental_no_cfg = no cfg attribute - -incremental_no_path = no path from `{$source}` to `{$target}` - -incremental_not_clean = `{$dep_node_str}` should be clean but is not - -incremental_not_dirty = `{$dep_node_str}` should be dirty but is not - -incremental_not_loaded = `{$dep_node_str}` should have been loaded from disk but it was not - -incremental_ok = OK - -incremental_repeated_depnode_label = dep-node label `{$label}` is repeated - -incremental_session_gc_failed = - failed to garbage collect incremental compilation session directory `{$path}`: {$err} - -incremental_unchecked_clean = found unchecked `#[rustc_clean]` attribute - -incremental_undefined_clean_dirty_assertions = - clean/dirty auto-assertions not yet defined for {$kind} - -incremental_undefined_clean_dirty_assertions_item = - clean/dirty auto-assertions not yet defined for Node::Item.node={$kind} - -incremental_unknown_rustc_clean_argument = unknown `rustc_clean` argument - -incremental_unrecognized_depnode = unrecognized `DepNode` variant: {$name} - -incremental_unrecognized_depnode_label = dep-node label `{$label}` not recognized - -incremental_write_new = failed to write {$name} to `{$path}`: {$err}
diff --git a/compiler/rustc_incremental/src/errors.rs b/compiler/rustc_incremental/src/errors.rs index dbc72d0..65109fd 100644 --- a/compiler/rustc_incremental/src/errors.rs +++ b/compiler/rustc_incremental/src/errors.rs
@@ -4,7 +4,7 @@ use rustc_span::{Ident, Span, Symbol}; #[derive(Diagnostic)] -#[diag(incremental_unrecognized_depnode)] +#[diag("unrecognized `DepNode` variant: {$name}")] pub(crate) struct UnrecognizedDepNode { #[primary_span] pub span: Span, @@ -12,28 +12,28 @@ pub(crate) struct UnrecognizedDepNode { } #[derive(Diagnostic)] -#[diag(incremental_missing_depnode)] +#[diag("missing `DepNode` variant")] pub(crate) struct MissingDepNode { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(incremental_missing_if_this_changed)] +#[diag("no `#[rustc_if_this_changed]` annotation detected")] pub(crate) struct MissingIfThisChanged { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(incremental_ok)] +#[diag("OK")] pub(crate) struct Ok { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(incremental_no_path)] +#[diag("no path from `{$source}` to `{$target}`")] pub(crate) struct NoPath { #[primary_span] pub span: Span, @@ -42,7 +42,7 @@ pub(crate) struct NoPath { } #[derive(Diagnostic)] -#[diag(incremental_assertion_auto)] +#[diag("`except` specified DepNodes that can not be affected for \"{$name}\": \"{$e}\"")] pub(crate) struct AssertionAuto<'a> { #[primary_span] pub span: Span, @@ -51,7 +51,7 @@ pub(crate) struct AssertionAuto<'a> { } #[derive(Diagnostic)] -#[diag(incremental_undefined_clean_dirty_assertions_item)] +#[diag("clean/dirty auto-assertions not yet defined for Node::Item.node={$kind}")] pub(crate) struct UndefinedCleanDirtyItem { #[primary_span] pub span: Span, @@ -59,7 +59,7 @@ pub(crate) struct UndefinedCleanDirtyItem { } #[derive(Diagnostic)] -#[diag(incremental_undefined_clean_dirty_assertions)] +#[diag("clean/dirty auto-assertions not yet defined for {$kind}")] pub(crate) struct UndefinedCleanDirty { #[primary_span] pub span: Span, @@ -67,7 +67,7 @@ pub(crate) struct UndefinedCleanDirty { } #[derive(Diagnostic)] -#[diag(incremental_repeated_depnode_label)] +#[diag("dep-node label `{$label}` is repeated")] pub(crate) struct RepeatedDepNodeLabel<'a> { #[primary_span] pub span: Span, @@ -75,7 +75,7 @@ pub(crate) struct RepeatedDepNodeLabel<'a> { } #[derive(Diagnostic)] -#[diag(incremental_unrecognized_depnode_label)] +#[diag("dep-node label `{$label}` not recognized")] pub(crate) struct UnrecognizedDepNodeLabel<'a> { #[primary_span] pub span: Span, @@ -83,7 +83,7 @@ pub(crate) struct UnrecognizedDepNodeLabel<'a> { } #[derive(Diagnostic)] -#[diag(incremental_not_dirty)] +#[diag("`{$dep_node_str}` should be dirty but is not")] pub(crate) struct NotDirty<'a> { #[primary_span] pub span: Span, @@ -91,7 +91,7 @@ pub(crate) struct NotDirty<'a> { } #[derive(Diagnostic)] -#[diag(incremental_not_clean)] +#[diag("`{$dep_node_str}` should be clean but is not")] pub(crate) struct NotClean<'a> { #[primary_span] pub span: Span, @@ -99,7 +99,7 @@ pub(crate) struct NotClean<'a> { } #[derive(Diagnostic)] -#[diag(incremental_not_loaded)] +#[diag("`{$dep_node_str}` should have been loaded from disk but it was not")] pub(crate) struct NotLoaded<'a> { #[primary_span] pub span: Span, @@ -107,21 +107,21 @@ pub(crate) struct NotLoaded<'a> { } #[derive(Diagnostic)] -#[diag(incremental_unknown_rustc_clean_argument)] +#[diag("unknown `rustc_clean` argument")] pub(crate) struct UnknownRustcCleanArgument { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(incremental_no_cfg)] +#[diag("no cfg attribute")] pub(crate) struct NoCfg { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(incremental_associated_value_expected_for)] +#[diag("associated value expected for `{$ident}`")] pub(crate) struct AssociatedValueExpectedFor { #[primary_span] pub span: Span, @@ -129,21 +129,21 @@ pub(crate) struct AssociatedValueExpectedFor { } #[derive(Diagnostic)] -#[diag(incremental_associated_value_expected)] +#[diag("expected an associated value")] pub(crate) struct AssociatedValueExpected { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(incremental_unchecked_clean)] +#[diag("found unchecked `#[rustc_clean]` attribute")] pub(crate) struct UncheckedClean { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(incremental_delete_old)] +#[diag("unable to delete old {$name} at `{$path}`: {$err}")] pub(crate) struct DeleteOld<'a> { pub name: &'a str, pub path: PathBuf, @@ -151,7 +151,7 @@ pub(crate) struct DeleteOld<'a> { } #[derive(Diagnostic)] -#[diag(incremental_create_new)] +#[diag("failed to create {$name} at `{$path}`: {$err}")] pub(crate) struct CreateNew<'a> { pub name: &'a str, pub path: PathBuf, @@ -159,7 +159,7 @@ pub(crate) struct CreateNew<'a> { } #[derive(Diagnostic)] -#[diag(incremental_write_new)] +#[diag("failed to write {$name} to `{$path}`: {$err}")] pub(crate) struct WriteNew<'a> { pub name: &'a str, pub path: PathBuf, @@ -167,14 +167,14 @@ pub(crate) struct WriteNew<'a> { } #[derive(Diagnostic)] -#[diag(incremental_canonicalize_path)] +#[diag("incremental compilation: error canonicalizing path `{$path}`: {$err}")] pub(crate) struct CanonicalizePath { pub path: PathBuf, pub err: std::io::Error, } #[derive(Diagnostic)] -#[diag(incremental_create_incr_comp_dir)] +#[diag("could not create incremental compilation {$tag} directory `{$path}`: {$err}")] pub(crate) struct CreateIncrCompDir<'a> { pub tag: &'a str, pub path: &'a Path, @@ -182,96 +182,112 @@ pub(crate) struct CreateIncrCompDir<'a> { } #[derive(Diagnostic)] -#[diag(incremental_create_lock)] +#[diag("incremental compilation: could not create session directory lock file: {$lock_err}")] pub(crate) struct CreateLock<'a> { pub lock_err: std::io::Error, pub session_dir: &'a Path, - #[note(incremental_lock_unsupported)] + #[note( + "the filesystem for the incremental path at {$session_dir} does not appear to support locking, consider changing the incremental path to a filesystem that supports locking or disable incremental compilation" + )] pub is_unsupported_lock: bool, - #[help(incremental_cargo_help_1)] - #[help(incremental_cargo_help_2)] + #[help( + "incremental compilation can be disabled by setting the environment variable CARGO_INCREMENTAL=0 (see https://doc.rust-lang.org/cargo/reference/profiles.html#incremental)" + )] + #[help( + "the entire build directory can be changed to a different filesystem by setting the environment variable CARGO_TARGET_DIR to a different path (see https://doc.rust-lang.org/cargo/reference/config.html#buildtarget-dir)" + )] pub is_cargo: bool, } #[derive(Diagnostic)] -#[diag(incremental_delete_lock)] +#[diag("error deleting lock file for incremental compilation session directory `{$path}`: {$err}")] pub(crate) struct DeleteLock<'a> { pub path: &'a Path, pub err: std::io::Error, } #[derive(Diagnostic)] -#[diag(incremental_hard_link_failed)] +#[diag( + "hard linking files in the incremental compilation cache failed. copying files instead. consider moving the cache directory to a file system which supports hard linking in session dir `{$path}`" +)] pub(crate) struct HardLinkFailed<'a> { pub path: &'a Path, } #[derive(Diagnostic)] -#[diag(incremental_delete_partial)] +#[diag("failed to delete partly initialized session dir `{$path}`: {$err}")] pub(crate) struct DeletePartial<'a> { pub path: &'a Path, pub err: std::io::Error, } #[derive(Diagnostic)] -#[diag(incremental_delete_full)] +#[diag("error deleting incremental compilation session directory `{$path}`: {$err}")] pub(crate) struct DeleteFull<'a> { pub path: &'a Path, pub err: std::io::Error, } #[derive(Diagnostic)] -#[diag(incremental_finalize)] +#[diag("error finalizing incremental compilation session directory `{$path}`: {$err}")] pub(crate) struct Finalize<'a> { pub path: &'a Path, pub err: std::io::Error, } #[derive(Diagnostic)] -#[diag(incremental_invalid_gc_failed)] +#[diag( + "failed to garbage collect invalid incremental compilation session directory `{$path}`: {$err}" +)] pub(crate) struct InvalidGcFailed<'a> { pub path: &'a Path, pub err: std::io::Error, } #[derive(Diagnostic)] -#[diag(incremental_finalized_gc_failed)] +#[diag( + "failed to garbage collect finalized incremental compilation session directory `{$path}`: {$err}" +)] pub(crate) struct FinalizedGcFailed<'a> { pub path: &'a Path, pub err: std::io::Error, } #[derive(Diagnostic)] -#[diag(incremental_session_gc_failed)] +#[diag("failed to garbage collect incremental compilation session directory `{$path}`: {$err}")] pub(crate) struct SessionGcFailed<'a> { pub path: &'a Path, pub err: std::io::Error, } #[derive(Diagnostic)] -#[diag(incremental_assert_not_loaded)] +#[diag("we asserted that the incremental cache should not be loaded, but it was loaded")] pub(crate) struct AssertNotLoaded; #[derive(Diagnostic)] -#[diag(incremental_assert_loaded)] +#[diag( + "we asserted that an existing incremental cache directory should be successfully loaded, but it was not" +)] pub(crate) struct AssertLoaded; #[derive(Diagnostic)] -#[diag(incremental_delete_incompatible)] +#[diag( + "failed to delete invalidated or incompatible incremental compilation session directory contents `{$path}`: {$err}" +)] pub(crate) struct DeleteIncompatible { pub path: PathBuf, pub err: std::io::Error, } #[derive(Diagnostic)] -#[diag(incremental_load_dep_graph)] +#[diag("could not load dep-graph from `{$path}`: {$err}")] pub(crate) struct LoadDepGraph { pub path: PathBuf, pub err: std::io::Error, } #[derive(Diagnostic)] -#[diag(incremental_move_dep_graph)] +#[diag("failed to move dependency graph from `{$from}` to `{$to}`: {$err}")] pub(crate) struct MoveDepGraph<'a> { pub from: &'a Path, pub to: &'a Path, @@ -279,14 +295,14 @@ pub(crate) struct MoveDepGraph<'a> { } #[derive(Diagnostic)] -#[diag(incremental_create_dep_graph)] +#[diag("failed to create dependency graph at `{$path}`: {$err}")] pub(crate) struct CreateDepGraph<'a> { pub path: &'a Path, pub err: std::io::Error, } #[derive(Diagnostic)] -#[diag(incremental_copy_workproduct_to_cache)] +#[diag("error copying object file `{$from}` to incremental directory as `{$to}`: {$err}")] pub(crate) struct CopyWorkProductToCache<'a> { pub from: &'a Path, pub to: &'a Path, @@ -294,14 +310,16 @@ pub(crate) struct CopyWorkProductToCache<'a> { } #[derive(Diagnostic)] -#[diag(incremental_delete_workproduct)] +#[diag("file-system error deleting outdated file `{$path}`: {$err}")] pub(crate) struct DeleteWorkProduct<'a> { pub path: &'a Path, pub err: std::io::Error, } #[derive(Diagnostic)] -#[diag(incremental_corrupt_file)] +#[diag( + "corrupt incremental compilation artifact found at `{$path}`. This file will automatically be ignored and deleted. If you see this message repeatedly or can provoke it without manually manipulating the compiler's artifacts, please file an issue. The incremental compilation system relies on hardlinks and filesystem locks behaving correctly, and may not deal well with OS crashes, so whatever information you can provide about your filesystem or other state may be very relevant." +)] pub(crate) struct CorruptFile<'a> { pub path: &'a Path, }
diff --git a/compiler/rustc_incremental/src/lib.rs b/compiler/rustc_incremental/src/lib.rs index e750810..591ade3 100644 --- a/compiler/rustc_incremental/src/lib.rs +++ b/compiler/rustc_incremental/src/lib.rs
@@ -21,5 +21,3 @@ pub fn provide(providers: &mut Providers) { providers.hooks.save_dep_graph = |tcx| tcx.sess.time("serialize_dep_graph", || persist::save_dep_graph(tcx)); } - -rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
diff --git a/compiler/rustc_infer/Cargo.toml b/compiler/rustc_infer/Cargo.toml index 08c0361..c4fbe89 100644 --- a/compiler/rustc_infer/Cargo.toml +++ b/compiler/rustc_infer/Cargo.toml
@@ -10,7 +10,6 @@ # tidy-alphabetical-start rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } -rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_hir = { path = "../rustc_hir" } rustc_index = { path = "../rustc_index" } rustc_macros = { path = "../rustc_macros" }
diff --git a/compiler/rustc_infer/messages.ftl b/compiler/rustc_infer/messages.ftl deleted file mode 100644 index e51734f..0000000 --- a/compiler/rustc_infer/messages.ftl +++ /dev/null
@@ -1,5 +0,0 @@ -infer_opaque_hidden_type = - opaque type's hidden type cannot be another opaque type from the same scope - .label = one of the two opaque types used here has to be outside its defining scope - .opaque_type = opaque type whose hidden type is being assigned - .hidden_type = opaque type being used as hidden type
diff --git a/compiler/rustc_infer/src/errors.rs b/compiler/rustc_infer/src/errors.rs index 76ea9c3..7c6e3b4 100644 --- a/compiler/rustc_infer/src/errors.rs +++ b/compiler/rustc_infer/src/errors.rs
@@ -2,13 +2,13 @@ use rustc_span::Span; #[derive(Diagnostic)] -#[diag(infer_opaque_hidden_type)] +#[diag("opaque type's hidden type cannot be another opaque type from the same scope")] pub(crate) struct OpaqueHiddenTypeDiag { #[primary_span] - #[label] + #[label("one of the two opaque types used here has to be outside its defining scope")] pub span: Span, - #[note(infer_opaque_type)] + #[note("opaque type whose hidden type is being assigned")] pub opaque_type: Span, - #[note(infer_hidden_type)] + #[note("opaque type being used as hidden type")] pub hidden_type: Span, }
diff --git a/compiler/rustc_infer/src/lib.rs b/compiler/rustc_infer/src/lib.rs index 05ea0f8..2a1733e 100644 --- a/compiler/rustc_infer/src/lib.rs +++ b/compiler/rustc_infer/src/lib.rs
@@ -22,5 +22,3 @@ mod errors; pub mod infer; pub mod traits; - -rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
diff --git a/compiler/rustc_interface/Cargo.toml b/compiler/rustc_interface/Cargo.toml index d785030..3a3b4d5 100644 --- a/compiler/rustc_interface/Cargo.toml +++ b/compiler/rustc_interface/Cargo.toml
@@ -19,7 +19,6 @@ rustc_errors = { path = "../rustc_errors" } rustc_expand = { path = "../rustc_expand" } rustc_feature = { path = "../rustc_feature" } -rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_fs_util = { path = "../rustc_fs_util" } rustc_hir = { path = "../rustc_hir" } rustc_hir_analysis = { path = "../rustc_hir_analysis" }
diff --git a/compiler/rustc_interface/messages.ftl b/compiler/rustc_interface/messages.ftl deleted file mode 100644 index d898e9b..0000000 --- a/compiler/rustc_interface/messages.ftl +++ /dev/null
@@ -1,56 +0,0 @@ -interface_abi_required_feature = - target feature `{$feature}` must be {$enabled} to ensure that the ABI of the current target can be implemented correctly - .note = this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! -interface_abi_required_feature_issue = for more information, see issue #116344 <https://github.com/rust-lang/rust/issues/116344> - -interface_crate_name_does_not_match = `--crate-name` and `#[crate_name]` are required to match, but `{$crate_name}` != `{$attr_crate_name}` - -interface_crate_name_invalid = crate names cannot start with a `-`, but `{$crate_name}` has a leading hyphen - -interface_emoji_identifier = - identifiers cannot contain emoji: `{$ident}` - -interface_error_writing_dependencies = - error writing dependencies to `{$path}`: {$error} - -interface_failed_writing_file = - failed to write file {$path}: {$error}" - -interface_ferris_identifier = - Ferris cannot be used as an identifier - .suggestion = try using their name instead - -interface_generated_file_conflicts_with_directory = - the generated executable for the input file "{$input_path}" conflicts with the existing directory "{$dir_path}" - -interface_ignoring_extra_filename = ignoring -C extra-filename flag due to -o flag - -interface_ignoring_out_dir = ignoring --out-dir flag due to -o flag - -interface_input_file_would_be_overwritten = - the input file "{$path}" would be overwritten by the generated executable - -interface_mixed_bin_crate = - cannot mix `bin` crate type with others - -interface_mixed_proc_macro_crate = - cannot mix `proc-macro` crate type with others - -interface_multiple_output_types_adaption = - due to multiple output types requested, the explicitly specified output file name will be adapted for each output type - -interface_multiple_output_types_to_stdout = can't use option `-o` or `--emit` to write multiple output types to stdout -interface_out_dir_error = - failed to find or create the directory specified by `--out-dir` - -interface_proc_macro_crate_panic_abort = - building proc macro crate with `panic=abort` or `panic=immediate-abort` may crash the compiler should the proc-macro panic - -interface_temps_dir_error = - failed to find or create the directory specified by `--temps-dir` - -interface_unsupported_crate_type_for_codegen_backend = - dropping unsupported crate type `{$crate_type}` for codegen backend `{$codegen_backend}` - -interface_unsupported_crate_type_for_target = - dropping unsupported crate type `{$crate_type}` for target `{$target_triple}`
diff --git a/compiler/rustc_interface/src/errors.rs b/compiler/rustc_interface/src/errors.rs index aee8ec2..7e46718 100644 --- a/compiler/rustc_interface/src/errors.rs +++ b/compiler/rustc_interface/src/errors.rs
@@ -7,7 +7,9 @@ use rustc_target::spec::TargetTuple; #[derive(Diagnostic)] -#[diag(interface_crate_name_does_not_match)] +#[diag( + "`--crate-name` and `#[crate_name]` are required to match, but `{$crate_name}` != `{$attr_crate_name}`" +)] pub(crate) struct CrateNameDoesNotMatch { #[primary_span] pub(crate) span: Span, @@ -16,23 +18,27 @@ pub(crate) struct CrateNameDoesNotMatch { } #[derive(Diagnostic)] -#[diag(interface_crate_name_invalid)] +#[diag("crate names cannot start with a `-`, but `{$crate_name}` has a leading hyphen")] pub(crate) struct CrateNameInvalid<'a> { pub(crate) crate_name: &'a str, } #[derive(Diagnostic)] -#[diag(interface_ferris_identifier)] +#[diag("Ferris cannot be used as an identifier")] pub struct FerrisIdentifier { #[primary_span] pub spans: Vec<Span>, - #[suggestion(code = "{ferris_fix}", applicability = "maybe-incorrect")] + #[suggestion( + "try using their name instead", + code = "{ferris_fix}", + applicability = "maybe-incorrect" + )] pub first_span: Span, pub ferris_fix: &'static str, } #[derive(Diagnostic)] -#[diag(interface_emoji_identifier)] +#[diag("identifiers cannot contain emoji: `{$ident}`")] pub struct EmojiIdentifier { #[primary_span] pub spans: Vec<Span>, @@ -40,86 +46,96 @@ pub struct EmojiIdentifier { } #[derive(Diagnostic)] -#[diag(interface_mixed_bin_crate)] +#[diag("cannot mix `bin` crate type with others")] pub struct MixedBinCrate; #[derive(Diagnostic)] -#[diag(interface_mixed_proc_macro_crate)] +#[diag("cannot mix `proc-macro` crate type with others")] pub struct MixedProcMacroCrate; #[derive(Diagnostic)] -#[diag(interface_error_writing_dependencies)] +#[diag("error writing dependencies to `{$path}`: {$error}")] pub struct ErrorWritingDependencies<'a> { pub path: &'a Path, pub error: io::Error, } #[derive(Diagnostic)] -#[diag(interface_input_file_would_be_overwritten)] +#[diag("the input file \"{$path}\" would be overwritten by the generated executable")] pub struct InputFileWouldBeOverWritten<'a> { pub path: &'a Path, } #[derive(Diagnostic)] -#[diag(interface_generated_file_conflicts_with_directory)] +#[diag( + "the generated executable for the input file \"{$input_path}\" conflicts with the existing directory \"{$dir_path}\"" +)] pub struct GeneratedFileConflictsWithDirectory<'a> { pub input_path: &'a Path, pub dir_path: &'a Path, } #[derive(Diagnostic)] -#[diag(interface_temps_dir_error)] +#[diag("failed to find or create the directory specified by `--temps-dir`")] pub struct TempsDirError; #[derive(Diagnostic)] -#[diag(interface_out_dir_error)] +#[diag("failed to find or create the directory specified by `--out-dir`")] pub struct OutDirError; #[derive(Diagnostic)] -#[diag(interface_failed_writing_file)] +#[diag("failed to write file {$path}: {$error}\"")] pub struct FailedWritingFile<'a> { pub path: &'a Path, pub error: io::Error, } #[derive(Diagnostic)] -#[diag(interface_proc_macro_crate_panic_abort)] +#[diag( + "building proc macro crate with `panic=abort` or `panic=immediate-abort` may crash the compiler should the proc-macro panic" +)] pub struct ProcMacroCratePanicAbort; #[derive(Diagnostic)] -#[diag(interface_multiple_output_types_adaption)] +#[diag( + "due to multiple output types requested, the explicitly specified output file name will be adapted for each output type" +)] pub struct MultipleOutputTypesAdaption; #[derive(Diagnostic)] -#[diag(interface_ignoring_extra_filename)] +#[diag("ignoring -C extra-filename flag due to -o flag")] pub struct IgnoringExtraFilename; #[derive(Diagnostic)] -#[diag(interface_ignoring_out_dir)] +#[diag("ignoring --out-dir flag due to -o flag")] pub struct IgnoringOutDir; #[derive(Diagnostic)] -#[diag(interface_multiple_output_types_to_stdout)] +#[diag("can't use option `-o` or `--emit` to write multiple output types to stdout")] pub struct MultipleOutputTypesToStdout; #[derive(Diagnostic)] -#[diag(interface_abi_required_feature)] -#[note] -#[note(interface_abi_required_feature_issue)] +#[diag( + "target feature `{$feature}` must be {$enabled} to ensure that the ABI of the current target can be implemented correctly" +)] +#[note( + "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 #116344 <https://github.com/rust-lang/rust/issues/116344>")] pub(crate) struct AbiRequiredTargetFeature<'a> { pub feature: &'a str, pub enabled: &'a str, } #[derive(Diagnostic)] -#[diag(interface_unsupported_crate_type_for_codegen_backend)] +#[diag("dropping unsupported crate type `{$crate_type}` for codegen backend `{$codegen_backend}`")] pub(crate) struct UnsupportedCrateTypeForCodegenBackend { pub(crate) crate_type: CrateType, pub(crate) codegen_backend: &'static str, } #[derive(Diagnostic)] -#[diag(interface_unsupported_crate_type_for_target)] +#[diag("dropping unsupported crate type `{$crate_type}` for target `{$target_triple}`")] pub(crate) struct UnsupportedCrateTypeForTarget<'a> { pub(crate) crate_type: CrateType, pub(crate) target_triple: &'a TargetTuple,
diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs index f76e8d4..bb22bd2 100644 --- a/compiler/rustc_interface/src/interface.rs +++ b/compiler/rustc_interface/src/interface.rs
@@ -55,11 +55,7 @@ pub(crate) fn parse_cfg(dcx: DiagCtxtHandle<'_>, cfgs: Vec<String>) -> Cfg { cfgs.into_iter() .map(|s| { let psess = ParseSess::emitter_with_note( - vec![ - crate::DEFAULT_LOCALE_RESOURCE, - rustc_parse::DEFAULT_LOCALE_RESOURCE, - rustc_session::DEFAULT_LOCALE_RESOURCE, - ], + vec![rustc_parse::DEFAULT_LOCALE_RESOURCE], format!("this occurred on the command line: `--cfg={s}`"), ); let filename = FileName::cfg_spec_source_code(&s); @@ -131,11 +127,7 @@ pub(crate) fn parse_check_cfg(dcx: DiagCtxtHandle<'_>, specs: Vec<String>) -> Ch for s in specs { let psess = ParseSess::emitter_with_note( - vec![ - crate::DEFAULT_LOCALE_RESOURCE, - rustc_parse::DEFAULT_LOCALE_RESOURCE, - rustc_session::DEFAULT_LOCALE_RESOURCE, - ], + vec![rustc_parse::DEFAULT_LOCALE_RESOURCE], format!("this occurred on the command line: `--check-cfg={s}`"), ); let filename = FileName::cfg_spec_source_code(&s);
diff --git a/compiler/rustc_interface/src/lib.rs b/compiler/rustc_interface/src/lib.rs index ce2398f..b5e4a38 100644 --- a/compiler/rustc_interface/src/lib.rs +++ b/compiler/rustc_interface/src/lib.rs
@@ -21,5 +21,3 @@ #[cfg(test)] mod tests; - -rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 0f60e86..b0272d7 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs
@@ -379,7 +379,7 @@ fn test_native_libs_tracking_hash_different_values() { NativeLib { name: String::from("a"), new_name: None, - kind: NativeLibKind::Static { bundle: None, whole_archive: None }, + kind: NativeLibKind::Static { bundle: None, whole_archive: None, export_symbols: None }, verbatim: None, }, NativeLib { @@ -401,7 +401,7 @@ fn test_native_libs_tracking_hash_different_values() { NativeLib { name: String::from("a"), new_name: None, - kind: NativeLibKind::Static { bundle: None, whole_archive: None }, + kind: NativeLibKind::Static { bundle: None, whole_archive: None, export_symbols: None }, verbatim: None, }, NativeLib { @@ -423,13 +423,13 @@ fn test_native_libs_tracking_hash_different_values() { NativeLib { name: String::from("a"), new_name: None, - kind: NativeLibKind::Static { bundle: None, whole_archive: None }, + kind: NativeLibKind::Static { bundle: None, whole_archive: None, export_symbols: None }, verbatim: None, }, NativeLib { name: String::from("b"), new_name: None, - kind: NativeLibKind::Static { bundle: None, whole_archive: None }, + kind: NativeLibKind::Static { bundle: None, whole_archive: None, export_symbols: None }, verbatim: None, }, NativeLib { @@ -445,7 +445,7 @@ fn test_native_libs_tracking_hash_different_values() { NativeLib { name: String::from("a"), new_name: None, - kind: NativeLibKind::Static { bundle: None, whole_archive: None }, + kind: NativeLibKind::Static { bundle: None, whole_archive: None, export_symbols: None }, verbatim: None, }, NativeLib { @@ -467,7 +467,7 @@ fn test_native_libs_tracking_hash_different_values() { NativeLib { name: String::from("a"), new_name: None, - kind: NativeLibKind::Static { bundle: None, whole_archive: None }, + kind: NativeLibKind::Static { bundle: None, whole_archive: None, export_symbols: None }, verbatim: None, }, NativeLib { @@ -501,7 +501,7 @@ fn test_native_libs_tracking_hash_different_order() { NativeLib { name: String::from("a"), new_name: None, - kind: NativeLibKind::Static { bundle: None, whole_archive: None }, + kind: NativeLibKind::Static { bundle: None, whole_archive: None, export_symbols: None }, verbatim: None, }, NativeLib { @@ -528,7 +528,7 @@ fn test_native_libs_tracking_hash_different_order() { NativeLib { name: String::from("a"), new_name: None, - kind: NativeLibKind::Static { bundle: None, whole_archive: None }, + kind: NativeLibKind::Static { bundle: None, whole_archive: None, export_symbols: None }, verbatim: None, }, NativeLib { @@ -549,7 +549,7 @@ fn test_native_libs_tracking_hash_different_order() { NativeLib { name: String::from("a"), new_name: None, - kind: NativeLibKind::Static { bundle: None, whole_archive: None }, + kind: NativeLibKind::Static { bundle: None, whole_archive: None, export_symbols: None }, verbatim: None, }, NativeLib {
diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 867b937..2f5b7ed 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl
@@ -326,6 +326,14 @@ .note = the `unfulfilled_lint_expectations` lint can't be expected and will always produce this message .rationale = {$rationale} +lint_expected_name_value = + expected this to be of the form `... = "..."` + .warn = {-lint_previously_accepted} + +lint_expected_no_args = + didn't expect any arguments here + .warn = {-lint_previously_accepted} + lint_for_loops_over_fallibles = for loop over {$article} `{$ref_prefix}{$ty}`. This is more readably written as an `if let` statement .suggestion = consider using `if let` to clear intent @@ -558,6 +566,10 @@ lint_malformed_attribute = malformed lint attribute input +lint_malformed_doc = + malformed `doc` attribute input + .warn = {-lint_previously_accepted} + lint_map_unit_fn = `Iterator::map` call that discard the iterator's values .note = `Iterator::map`, like many of the methods on `Iterator`, gets executed lazily, meaning that its effects won't be visible until it is iterated .function_label = this function returns `()`, which is likely not what you wanted
diff --git a/compiler/rustc_lint/src/early/diagnostics.rs b/compiler/rustc_lint/src/early/diagnostics.rs index 377b3c4..c0ab0d1 100644 --- a/compiler/rustc_lint/src/early/diagnostics.rs +++ b/compiler/rustc_lint/src/early/diagnostics.rs
@@ -428,5 +428,11 @@ pub fn decorate_attribute_lint( sugg: suggested.map(|s| lints::UnknownCrateTypesSuggestion { span, snippet: s }), } .decorate_lint(diag), + + &AttributeLintKind::MalformedDoc => lints::MalformedDoc.decorate_lint(diag), + + &AttributeLintKind::ExpectedNoArgs => lints::ExpectedNoArgs.decorate_lint(diag), + + &AttributeLintKind::ExpectedNameValue => lints::ExpectedNameValue.decorate_lint(diag), } }
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index a20d90e..1a87cc0 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs
@@ -3186,6 +3186,21 @@ pub(crate) struct UnusedDuplicate { } #[derive(LintDiagnostic)] +#[diag(lint_malformed_doc)] +#[warning] +pub(crate) struct MalformedDoc; + +#[derive(LintDiagnostic)] +#[diag(lint_expected_no_args)] +#[warning] +pub(crate) struct ExpectedNoArgs; + +#[derive(LintDiagnostic)] +#[diag(lint_expected_name_value)] +#[warning] +pub(crate) struct ExpectedNameValue; + +#[derive(LintDiagnostic)] #[diag(lint_unsafe_attr_outside_unsafe)] pub(crate) struct UnsafeAttrOutsideUnsafeLint { #[label]
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index d1d5d0a..f4e6e93 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -3458,7 +3458,7 @@ /// but this lint was introduced to avoid breaking any existing /// crates which included them. pub INVALID_DOC_ATTRIBUTES, - Deny, + Warn, "detects invalid `#[doc(...)]` attributes", }
diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index 4c78287..b3e5b93 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs
@@ -826,6 +826,9 @@ pub enum AttributeLintKind { span: Span, suggested: Option<Symbol>, }, + MalformedDoc, + ExpectedNoArgs, + ExpectedNameValue, } pub type RegisteredTools = FxIndexSet<Ident>;
diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic.rs b/compiler/rustc_macros/src/diagnostics/diagnostic.rs index b4270f4..e835665 100644 --- a/compiler/rustc_macros/src/diagnostics/diagnostic.rs +++ b/compiler/rustc_macros/src/diagnostics/diagnostic.rs
@@ -31,7 +31,7 @@ pub(crate) fn into_tokens(self) -> TokenStream { return DiagnosticDeriveError::ErrorHandled.to_compile_error(); }; messages.borrow_mut().push(message.clone()); - let message = message.diag_message(variant); + let message = message.diag_message(Some(variant)); let init = quote! { let mut diag = rustc_errors::Diag::new( @@ -97,7 +97,7 @@ pub(crate) fn into_tokens(self) -> TokenStream { return DiagnosticDeriveError::ErrorHandled.to_compile_error(); }; messages.borrow_mut().push(message.clone()); - let message = message.diag_message(variant); + let message = message.diag_message(Some(variant)); let primary_message = quote! { diag.primary_message(#message); };
diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs b/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs index e6d9409..6107b18 100644 --- a/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs +++ b/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs
@@ -456,7 +456,7 @@ fn generate_inner_field_code( applicability.set_once(quote! { #static_applicability }, span); } - let message = slug.diag_message(variant); + let message = slug.diag_message(Some(variant)); let applicability = applicability .value() .unwrap_or_else(|| quote! { rustc_errors::Applicability::Unspecified }); @@ -487,7 +487,7 @@ fn add_spanned_subdiagnostic( variant: &VariantInfo<'_>, ) -> TokenStream { let fn_name = format_ident!("span_{}", kind); - let message = message.diag_message(variant); + let message = message.diag_message(Some(variant)); quote! { diag.#fn_name( #field_binding, @@ -504,7 +504,7 @@ fn add_subdiagnostic( message: Message, variant: &VariantInfo<'_>, ) -> TokenStream { - let message = message.diag_message(variant); + let message = message.diag_message(Some(variant)); quote! { diag.#kind(#message); }
diff --git a/compiler/rustc_macros/src/diagnostics/message.rs b/compiler/rustc_macros/src/diagnostics/message.rs index 153abec..6c8aded 100644 --- a/compiler/rustc_macros/src/diagnostics/message.rs +++ b/compiler/rustc_macros/src/diagnostics/message.rs
@@ -14,13 +14,18 @@ pub(crate) enum Message { } impl Message { - pub(crate) fn diag_message(&self, variant: &VariantInfo<'_>) -> TokenStream { + /// Get the diagnostic message for this diagnostic + /// The passed `variant` is used to check whether all variables in the message are used. + /// For subdiagnostics, we cannot check this. + pub(crate) fn diag_message(&self, variant: Option<&VariantInfo<'_>>) -> TokenStream { match self { Message::Slug(slug) => { quote! { crate::fluent_generated::#slug } } Message::Inline(message_span, message) => { - verify_fluent_message(*message_span, &message, variant); + if let Some(variant) = variant { + verify_fluent_message(*message_span, &message, variant); + } quote! { rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed(#message)) } } }
diff --git a/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs b/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs index adc968d..ac1fa98 100644 --- a/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs +++ b/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs
@@ -75,7 +75,7 @@ pub(crate) fn into_tokens(self, mut structure: Structure<'_>) -> TokenStream { has_subdiagnostic: false, is_enum, }; - builder.into_tokens(variant).unwrap_or_else(|v| v.to_compile_error()) + builder.into_tokens().unwrap_or_else(|v| v.to_compile_error()) }); quote! { @@ -497,10 +497,7 @@ fn generate_field_code_inner_list( } } - pub(crate) fn into_tokens( - &mut self, - variant: &VariantInfo<'_>, - ) -> Result<TokenStream, DiagnosticDeriveError> { + pub(crate) fn into_tokens(&mut self) -> Result<TokenStream, DiagnosticDeriveError> { let kind_slugs = self.identify_kind()?; let kind_stats: KindsStatistics = kind_slugs.iter().map(|(kind, _slug)| kind).collect(); @@ -538,7 +535,7 @@ pub(crate) fn into_tokens( let mut calls = TokenStream::new(); for (kind, slug) in kind_slugs { let message = format_ident!("__message"); - let message_stream = slug.diag_message(variant); + let message_stream = slug.diag_message(None); calls.extend(quote! { let #message = #diag.eagerly_translate(#message_stream); }); let name = format_ident!("{}{}", if span_field.is_some() { "span_" } else { "" }, kind);
diff --git a/compiler/rustc_macros/src/query.rs b/compiler/rustc_macros/src/query.rs index 0e2b16d..5d7204f 100644 --- a/compiler/rustc_macros/src/query.rs +++ b/compiler/rustc_macros/src/query.rs
@@ -289,7 +289,7 @@ fn add_query_desc_cached_impl( cached.extend(quote! { #[allow(unused_variables, unused_braces, rustc::pass_by_value)] #[inline] - pub fn #name<'tcx>(#tcx: TyCtxt<'tcx>, #key: &crate::query::queries::#name::Key<'tcx>) -> bool { + pub fn #name<'tcx>(#tcx: TyCtxt<'tcx>, #key: &crate::queries::#name::Key<'tcx>) -> bool { #ra_hint #expr } @@ -301,7 +301,7 @@ pub fn #name<'tcx>(#tcx: TyCtxt<'tcx>, #key: &crate::query::queries::#name::Key< let desc = quote! { #[allow(unused_variables)] - pub fn #name<'tcx>(tcx: TyCtxt<'tcx>, key: crate::query::queries::#name::Key<'tcx>) -> String { + pub fn #name<'tcx>(tcx: TyCtxt<'tcx>, key: crate::queries::#name::Key<'tcx>) -> String { let (#tcx, #key) = (tcx, key); format!(#desc) } @@ -357,6 +357,7 @@ macro_rules! passthrough { no_hash, anon, eval_always, + feedable, depth_limit, separate_provide_extern, return_result_from_ensure_ok,
diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs index b160b3f..0c06d1b 100644 --- a/compiler/rustc_metadata/src/native_libs.rs +++ b/compiler/rustc_metadata/src/native_libs.rs
@@ -161,7 +161,7 @@ fn find_bundled_library( tcx: TyCtxt<'_>, ) -> Option<Symbol> { let sess = tcx.sess; - if let NativeLibKind::Static { bundle: Some(true) | None, whole_archive } = kind + if let NativeLibKind::Static { bundle: Some(true) | None, whole_archive, .. } = kind && tcx.crate_types().iter().any(|t| matches!(t, &CrateType::Rlib | CrateType::StaticLib)) && (sess.opts.unstable_opts.packed_bundled_libs || has_cfg || whole_archive == Some(true)) {
diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 7bd3f7d..b1f3baf 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
@@ -11,7 +11,8 @@ use rustc_middle::metadata::{AmbigModChild, ModChild}; use rustc_middle::middle::exported_symbols::ExportedSymbol; use rustc_middle::middle::stability::DeprecationEntry; -use rustc_middle::query::{ExternProviders, LocalCrate}; +use rustc_middle::queries::ExternProviders; +use rustc_middle::query::LocalCrate; use rustc_middle::ty::fast_reject::SimplifiedType; use rustc_middle::ty::{self, TyCtxt}; use rustc_middle::util::Providers; @@ -134,8 +135,8 @@ macro_rules! provide_one { ($tcx:ident, $def_id:ident, $other:ident, $cdata:ident, $name:ident => $compute:block) => { fn $name<'tcx>( $tcx: TyCtxt<'tcx>, - def_id_arg: rustc_middle::query::queries::$name::Key<'tcx>, - ) -> rustc_middle::query::queries::$name::ProvidedValue<'tcx> { + def_id_arg: rustc_middle::queries::$name::Key<'tcx>, + ) -> rustc_middle::queries::$name::ProvidedValue<'tcx> { let _prof_timer = $tcx.prof.generic_activity(concat!("metadata_decode_entry_", stringify!($name)));
diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index 5682c21..bb94b4c 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs
@@ -86,6 +86,8 @@ #[macro_use] pub mod query; #[macro_use] +pub mod queries; +#[macro_use] pub mod dep_graph; // Allows macros to refer to this crate as `::rustc_middle`
diff --git a/compiler/rustc_middle/src/queries.rs b/compiler/rustc_middle/src/queries.rs new file mode 100644 index 0000000..ca8e5e9 --- /dev/null +++ b/compiler/rustc_middle/src/queries.rs
@@ -0,0 +1,2775 @@ +//! +//! # The rustc Query System: Query Definitions and Modifiers +//! +//! The core processes in rustc are shipped as queries. Each query is a demand-driven function from some key to a value. +//! The execution result of the function is cached and directly read during the next request, thereby improving compilation efficiency. +//! Some results are saved locally and directly read during the next compilation, which are core of incremental compilation. +//! +//! ## How to Read This Module +//! +//! Each `query` block in this file defines a single query, specifying its key and value types, along with various modifiers. +//! These query definitions are processed by the [`rustc_macros`], which expands them into the necessary boilerplate code +//! for the query system—including the [`Providers`] struct (a function table for all query implementations, where each field is +//! a function pointer to the actual provider), caching, and dependency graph integration. +//! **Note:** The `Providers` struct is not a Rust trait, but a struct generated by the `rustc_macros` to hold all provider functions. +//! The `rustc_macros` also supports a set of **query modifiers** (see below) that control the behavior of each query. +//! +//! The actual provider functions are implemented in various modules and registered into the `Providers` struct +//! during compiler initialization (see [`rustc_interface::passes::DEFAULT_QUERY_PROVIDERS`]). +//! +//! [`rustc_macros`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_macros/index.html +//! [`rustc_interface::passes::DEFAULT_QUERY_PROVIDERS`]: ../../rustc_interface/passes/static.DEFAULT_QUERY_PROVIDERS.html +//! +//! ## Query Modifiers +//! +//! Query modifiers are special flags that alter the behavior of a query. They are parsed and processed by the `rustc_macros` +//! The main modifiers are: +//! +//! - `desc { ... }`: Sets the human-readable description for diagnostics and profiling. Required for every query. +//! - `arena_cache`: Use an arena for in-memory caching of the query result. +//! - `cache_on_disk_if { ... }`: Cache the query result to disk if the provided block evaluates to true. +//! - `cycle_fatal`: If a dependency cycle is detected, abort compilation with a fatal error. +//! - `cycle_delay_bug`: If a dependency cycle is detected, emit a delayed bug instead of aborting immediately. +//! - `cycle_stash`: If a dependency cycle is detected, stash the error for later handling. +//! - `no_hash`: Do not hash the query result for incremental compilation; just mark as dirty if recomputed. +//! - `anon`: Make the query anonymous in the dependency graph (no dep node is created). +//! - `eval_always`: Always evaluate the query, ignoring its dependencies and cached results. +//! - `depth_limit`: Impose a recursion depth limit on the query to prevent stack overflows. +//! - `separate_provide_extern`: Use separate provider functions for local and external crates. +//! - `feedable`: Allow the query result to be set from another query ("fed" externally). +//! - `return_result_from_ensure_ok`: When called via `tcx.ensure_ok()`, return `Result<(), ErrorGuaranteed>` instead of `()`. +//! If the query needs to be executed and returns an error, the error is returned to the caller. +//! Only valid for queries returning `Result<_, ErrorGuaranteed>`. +//! +//! For the up-to-date list, see the `QueryModifiers` struct in +//! [`rustc_macros/src/query.rs`](https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc_macros/src/query.rs) +//! and for more details in incremental compilation, see the +//! [Query modifiers in incremental compilation](https://rustc-dev-guide.rust-lang.org/queries/incremental-compilation-in-detail.html#query-modifiers) section of the rustc-dev-guide. +//! +//! ## Query Expansion and Code Generation +//! +//! The [`rustc_macros::rustc_queries`] macro expands each query definition into: +//! - A method on [`TyCtxt`] (and [`crate::query::TyCtxtAt`]) for invoking the query. +//! - Provider traits and structs for supplying the query's value. +//! - Caching and dependency graph integration. +//! - Support for incremental compilation, disk caching, and arena allocation as controlled by the modifiers. +//! +//! [`rustc_macros::rustc_queries`]: ../../rustc_macros/macro.rustc_queries.html +//! +//! The macro-based approach allows the query system to be highly flexible and maintainable, while minimizing boilerplate. +//! +//! For more details, see the [rustc-dev-guide](https://rustc-dev-guide.rust-lang.org/query.html). + +#![allow(unused_parens)] + +use std::ffi::OsStr; +use std::mem; +use std::path::PathBuf; +use std::sync::Arc; + +use rustc_abi::Align; +use rustc_arena::TypedArena; +use rustc_ast::expand::allocator::AllocatorKind; +use rustc_ast::tokenstream::TokenStream; +use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; +use rustc_data_structures::sorted_map::SortedMap; +use rustc_data_structures::steal::Steal; +use rustc_data_structures::svh::Svh; +use rustc_data_structures::unord::{UnordMap, UnordSet}; +use rustc_errors::ErrorGuaranteed; +use rustc_hir::attrs::{EiiDecl, EiiImpl, StrippedCfgItem}; +use rustc_hir::def::{DefKind, DocLinkResMap}; +use rustc_hir::def_id::{ + CrateNum, DefId, DefIdMap, LocalDefId, LocalDefIdMap, LocalDefIdSet, LocalModDefId, +}; +use rustc_hir::lang_items::{LangItem, LanguageItems}; +use rustc_hir::{Crate, ItemLocalId, ItemLocalMap, PreciseCapturingArgKind, TraitCandidate}; +use rustc_index::IndexVec; +use rustc_lint_defs::LintId; +use rustc_macros::rustc_queries; +use rustc_session::Limits; +use rustc_session::config::{EntryFnType, OptLevel, OutputFilenames, SymbolManglingVersion}; +use rustc_session::cstore::{ + CrateDepKind, CrateSource, ExternCrate, ForeignModule, LinkagePreference, NativeLib, +}; +use rustc_session::lint::LintExpectationId; +use rustc_span::def_id::LOCAL_CRATE; +use rustc_span::source_map::Spanned; +use rustc_span::{DUMMY_SP, LocalExpnId, Span, Symbol}; +use rustc_target::spec::PanicStrategy; +use {rustc_abi as abi, rustc_ast as ast, rustc_hir as hir}; + +use crate::infer::canonical::{self, Canonical}; +use crate::lint::LintExpectation; +use crate::metadata::ModChild; +use crate::middle::codegen_fn_attrs::{CodegenFnAttrs, SanitizerFnAttrs}; +use crate::middle::debugger_visualizer::DebuggerVisualizerFile; +use crate::middle::deduced_param_attrs::DeducedParamAttrs; +use crate::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo}; +use crate::middle::lib_features::LibFeatures; +use crate::middle::privacy::EffectiveVisibilities; +use crate::middle::resolve_bound_vars::{ObjectLifetimeDefault, ResolveBoundVars, ResolvedArg}; +use crate::middle::stability::DeprecationEntry; +use crate::mir::interpret::{ + EvalStaticInitializerRawResult, EvalToAllocationRawResult, EvalToConstValueResult, + EvalToValTreeResult, GlobalId, LitToConstInput, +}; +use crate::mir::mono::{ + CodegenUnit, CollectionMode, MonoItem, MonoItemPartitions, NormalizationErrorInMono, +}; +use crate::query::describe_as_module; +use crate::query::plumbing::CyclePlaceholder; +use crate::traits::query::{ + CanonicalAliasGoal, CanonicalDropckOutlivesGoal, CanonicalImpliedOutlivesBoundsGoal, + CanonicalMethodAutoderefStepsGoal, CanonicalPredicateGoal, CanonicalTypeOpAscribeUserTypeGoal, + CanonicalTypeOpNormalizeGoal, CanonicalTypeOpProvePredicateGoal, DropckConstraint, + DropckOutlivesResult, MethodAutoderefStepsResult, NoSolution, NormalizationResult, + OutlivesBound, +}; +use crate::traits::{ + CodegenObligationError, DynCompatibilityViolation, EvaluationResult, ImplSource, + ObligationCause, OverflowError, WellFormedLoc, solve, specialization_graph, +}; +use crate::ty::fast_reject::SimplifiedType; +use crate::ty::layout::ValidityRequirement; +use crate::ty::print::PrintTraitRefExt; +use crate::ty::util::AlwaysRequiresDrop; +use crate::ty::{ + self, CrateInherentImpls, GenericArg, GenericArgsRef, PseudoCanonicalInput, SizedTraitKind, Ty, + TyCtxt, TyCtxtFeed, +}; +use crate::{dep_graph, mir, thir}; + +// Each of these queries corresponds to a function pointer field in the +// `Providers` struct for requesting a value of that type, and a method +// on `tcx: TyCtxt` (and `tcx.at(span)`) for doing that request in a way +// which memoizes and does dep-graph tracking, wrapping around the actual +// `Providers` that the driver creates (using several `rustc_*` crates). +// +// The result type of each query must implement `Clone`, and additionally +// `ty::query::values::Value`, which produces an appropriate placeholder +// (error) value if the query resulted in a query cycle. +// Queries marked with `cycle_fatal` do not need the latter implementation, +// as they will raise an fatal error on query cycles instead. +rustc_queries! { + /// Caches the expansion of a derive proc macro, e.g. `#[derive(Serialize)]`. + /// The key is: + /// - A unique key corresponding to the invocation of a macro. + /// - Token stream which serves as an input to the macro. + /// + /// The output is the token stream generated by the proc macro. + query derive_macro_expansion(key: (LocalExpnId, &'tcx TokenStream)) -> Result<&'tcx TokenStream, ()> { + desc { "expanding a derive (proc) macro" } + cache_on_disk_if { true } + } + + /// This exists purely for testing the interactions between delayed bugs and incremental. + query trigger_delayed_bug(key: DefId) { + desc { "triggering a delayed bug for testing incremental" } + } + + /// Collects the list of all tools registered using `#![register_tool]`. + query registered_tools(_: ()) -> &'tcx ty::RegisteredTools { + arena_cache + desc { "compute registered tools for crate" } + } + + query early_lint_checks(_: ()) { + desc { "perform lints prior to AST lowering" } + } + + /// Tracked access to environment variables. + /// + /// Useful for the implementation of `std::env!`, `proc-macro`s change + /// detection and other changes in the compiler's behaviour that is easier + /// to control with an environment variable than a flag. + /// + /// NOTE: This currently does not work with dependency info in the + /// analysis, codegen and linking passes, place extra code at the top of + /// `rustc_interface::passes::write_dep_info` to make that work. + query env_var_os(key: &'tcx OsStr) -> Option<&'tcx OsStr> { + // Environment variables are global state + eval_always + desc { "get the value of an environment variable" } + } + + query resolutions(_: ()) -> &'tcx ty::ResolverGlobalCtxt { + desc { "getting the resolver outputs" } + } + + query resolver_for_lowering_raw(_: ()) -> (&'tcx Steal<(ty::ResolverAstLowering, Arc<ast::Crate>)>, &'tcx ty::ResolverGlobalCtxt) { + eval_always + no_hash + desc { "getting the resolver for lowering" } + } + + /// Return the span for a definition. + /// + /// Contrary to `def_span` below, this query returns the full absolute span of the definition. + /// This span is meant for dep-tracking rather than diagnostics. It should not be used outside + /// of rustc_middle::hir::source_map. + query source_span(key: LocalDefId) -> Span { + // Accesses untracked data + eval_always + desc { "getting the source span" } + } + + /// Represents crate as a whole (as distinct from the top-level crate module). + /// + /// If you call `tcx.hir_crate(())` we will have to assume that any change + /// means that you need to be recompiled. This is because the `hir_crate` + /// query gives you access to all other items. To avoid this fate, do not + /// call `tcx.hir_crate(())`; instead, prefer wrappers like + /// [`TyCtxt::hir_visit_all_item_likes_in_crate`]. + query hir_crate(key: ()) -> &'tcx Crate<'tcx> { + arena_cache + eval_always + desc { "getting the crate HIR" } + } + + /// All items in the crate. + query hir_crate_items(_: ()) -> &'tcx rustc_middle::hir::ModuleItems { + arena_cache + eval_always + desc { "getting HIR crate items" } + } + + /// The items in a module. + /// + /// This can be conveniently accessed by `tcx.hir_visit_item_likes_in_module`. + /// Avoid calling this query directly. + query hir_module_items(key: LocalModDefId) -> &'tcx rustc_middle::hir::ModuleItems { + arena_cache + desc { |tcx| "getting HIR module items in `{}`", tcx.def_path_str(key) } + cache_on_disk_if { true } + } + + /// Returns HIR ID for the given `LocalDefId`. + query local_def_id_to_hir_id(key: LocalDefId) -> hir::HirId { + desc { |tcx| "getting HIR ID of `{}`", tcx.def_path_str(key) } + feedable + } + + /// Gives access to the HIR node's parent for the HIR owner `key`. + /// + /// This can be conveniently accessed by `tcx.hir_*` methods. + /// Avoid calling this query directly. + query hir_owner_parent_q(key: hir::OwnerId) -> hir::HirId { + desc { |tcx| "getting HIR parent of `{}`", tcx.def_path_str(key) } + } + + /// Gives access to the HIR nodes and bodies inside `key` if it's a HIR owner. + /// + /// This can be conveniently accessed by `tcx.hir_*` methods. + /// Avoid calling this query directly. + query opt_hir_owner_nodes(key: LocalDefId) -> Option<&'tcx hir::OwnerNodes<'tcx>> { + desc { |tcx| "getting HIR owner items in `{}`", tcx.def_path_str(key) } + feedable + } + + /// Gives access to the HIR attributes inside the HIR owner `key`. + /// + /// This can be conveniently accessed by `tcx.hir_*` methods. + /// Avoid calling this query directly. + query hir_attr_map(key: hir::OwnerId) -> &'tcx hir::AttributeMap<'tcx> { + desc { |tcx| "getting HIR owner attributes in `{}`", tcx.def_path_str(key) } + feedable + } + + /// Gives access to lints emitted during ast lowering. + /// + /// This can be conveniently accessed by `tcx.hir_*` methods. + /// Avoid calling this query directly. + query opt_ast_lowering_delayed_lints(key: hir::OwnerId) -> Option<&'tcx hir::lints::DelayedLints> { + desc { |tcx| "getting AST lowering delayed lints in `{}`", tcx.def_path_str(key) } + } + + /// Returns the *default* of the const pararameter given by `DefId`. + /// + /// E.g., given `struct Ty<const N: usize = 3>;` this returns `3` for `N`. + query const_param_default(param: DefId) -> ty::EarlyBinder<'tcx, ty::Const<'tcx>> { + desc { |tcx| "computing the default for const parameter `{}`", tcx.def_path_str(param) } + cache_on_disk_if { param.is_local() } + separate_provide_extern + } + + /// Returns the const of the RHS of a (free or assoc) const item, if it is a `#[type_const]`. + /// + /// When a const item is used in a type-level expression, like in equality for an assoc const + /// projection, this allows us to retrieve the typesystem-appropriate representation of the + /// const value. + /// + /// This query will ICE if given a const that is not marked with `#[type_const]`. + query const_of_item(def_id: DefId) -> ty::EarlyBinder<'tcx, ty::Const<'tcx>> { + desc { |tcx| "computing the type-level value for `{}`", tcx.def_path_str(def_id) } + cache_on_disk_if { def_id.is_local() } + separate_provide_extern + } + + /// Returns the *type* of the definition given by `DefId`. + /// + /// For type aliases (whether eager or lazy) and associated types, this returns + /// the underlying aliased type (not the corresponding [alias type]). + /// + /// For opaque types, this returns and thus reveals the hidden type! If you + /// want to detect cycle errors use `type_of_opaque` instead. + /// + /// To clarify, for type definitions, this does *not* return the "type of a type" + /// (aka *kind* or *sort*) in the type-theoretical sense! It merely returns + /// the type primarily *associated with* it. + /// + /// # Panics + /// + /// This query will panic if the given definition doesn't (and can't + /// conceptually) have an (underlying) type. + /// + /// [alias type]: rustc_middle::ty::AliasTy + query type_of(key: DefId) -> ty::EarlyBinder<'tcx, Ty<'tcx>> { + desc { |tcx| + "{action} `{path}`", + action = match tcx.def_kind(key) { + DefKind::TyAlias => "expanding type alias", + DefKind::TraitAlias => "expanding trait alias", + _ => "computing type of", + }, + path = tcx.def_path_str(key), + } + cache_on_disk_if { key.is_local() } + separate_provide_extern + feedable + } + + /// Returns the *hidden type* of the opaque type given by `DefId` unless a cycle occurred. + /// + /// This is a specialized instance of [`Self::type_of`] that detects query cycles. + /// Unless `CyclePlaceholder` needs to be handled separately, call [`Self::type_of`] instead. + /// This is used to improve the error message in cases where revealing the hidden type + /// for auto-trait leakage cycles. + /// + /// # Panics + /// + /// This query will panic if the given definition is not an opaque type. + query type_of_opaque(key: DefId) -> Result<ty::EarlyBinder<'tcx, Ty<'tcx>>, CyclePlaceholder> { + desc { |tcx| + "computing type of opaque `{path}`", + path = tcx.def_path_str(key), + } + cycle_stash + } + query type_of_opaque_hir_typeck(key: LocalDefId) -> ty::EarlyBinder<'tcx, Ty<'tcx>> { + desc { |tcx| + "computing type of opaque `{path}` via HIR typeck", + path = tcx.def_path_str(key), + } + } + + /// Returns whether the type alias given by `DefId` is lazy. + /// + /// I.e., if the type alias expands / ought to expand to a [free] [alias type] + /// instead of the underlying aliased type. + /// + /// Relevant for features `lazy_type_alias` and `type_alias_impl_trait`. + /// + /// # Panics + /// + /// This query *may* panic if the given definition is not a type alias. + /// + /// [free]: rustc_middle::ty::Free + /// [alias type]: rustc_middle::ty::AliasTy + query type_alias_is_lazy(key: DefId) -> bool { + desc { |tcx| + "computing whether the type alias `{path}` is lazy", + path = tcx.def_path_str(key), + } + separate_provide_extern + } + + query collect_return_position_impl_trait_in_trait_tys(key: DefId) + -> Result<&'tcx DefIdMap<ty::EarlyBinder<'tcx, Ty<'tcx>>>, ErrorGuaranteed> + { + desc { "comparing an impl and trait method signature, inferring any hidden `impl Trait` types in the process" } + cache_on_disk_if { key.is_local() } + separate_provide_extern + } + + query opaque_ty_origin(key: DefId) -> hir::OpaqueTyOrigin<DefId> + { + desc { "determine where the opaque originates from" } + separate_provide_extern + } + + query unsizing_params_for_adt(key: DefId) -> &'tcx rustc_index::bit_set::DenseBitSet<u32> + { + arena_cache + desc { |tcx| + "determining what parameters of `{}` can participate in unsizing", + tcx.def_path_str(key), + } + } + + /// The root query triggering all analysis passes like typeck or borrowck. + query analysis(key: ()) { + eval_always + desc { |tcx| + "running analysis passes on crate `{}`", + tcx.crate_name(LOCAL_CRATE), + } + } + + /// This query checks the fulfillment of collected lint expectations. + /// All lint emitting queries have to be done before this is executed + /// to ensure that all expectations can be fulfilled. + /// + /// This is an extra query to enable other drivers (like rustdoc) to + /// only execute a small subset of the `analysis` query, while allowing + /// lints to be expected. In rustc, this query will be executed as part of + /// the `analysis` query and doesn't have to be called a second time. + /// + /// Tools can additionally pass in a tool filter. That will restrict the + /// expectations to only trigger for lints starting with the listed tool + /// name. This is useful for cases were not all linting code from rustc + /// was called. With the default `None` all registered lints will also + /// be checked for expectation fulfillment. + query check_expectations(key: Option<Symbol>) { + eval_always + desc { "checking lint expectations (RFC 2383)" } + } + + /// Returns the *generics* of the definition given by `DefId`. + query generics_of(key: DefId) -> &'tcx ty::Generics { + desc { |tcx| "computing generics of `{}`", tcx.def_path_str(key) } + arena_cache + cache_on_disk_if { key.is_local() } + separate_provide_extern + feedable + } + + /// Returns the (elaborated) *predicates* of the definition given by `DefId` + /// that must be proven true at usage sites (and which can be assumed at definition site). + /// + /// This is almost always *the* "predicates query" that you want. + /// + /// **Tip**: You can use `#[rustc_dump_predicates]` on an item to basically print + /// the result of this query for use in UI tests or for debugging purposes. + query predicates_of(key: DefId) -> ty::GenericPredicates<'tcx> { + desc { |tcx| "computing predicates of `{}`", tcx.def_path_str(key) } + cache_on_disk_if { key.is_local() } + } + + query opaque_types_defined_by( + key: LocalDefId + ) -> &'tcx ty::List<LocalDefId> { + desc { + |tcx| "computing the opaque types defined by `{}`", + tcx.def_path_str(key.to_def_id()) + } + } + + /// A list of all bodies inside of `key`, nested bodies are always stored + /// before their parent. + query nested_bodies_within( + key: LocalDefId + ) -> &'tcx ty::List<LocalDefId> { + desc { + |tcx| "computing the coroutines defined within `{}`", + tcx.def_path_str(key.to_def_id()) + } + } + + /// Returns the explicitly user-written *bounds* on the associated or opaque type given by `DefId` + /// that must be proven true at definition site (and which can be assumed at usage sites). + /// + /// For associated types, these must be satisfied for an implementation + /// to be well-formed, and for opaque types, these are required to be + /// satisfied by the hidden type of the opaque. + /// + /// Bounds from the parent (e.g. with nested `impl Trait`) are not included. + /// + /// Syntactially, these are the bounds written on associated types in trait + /// definitions, or those after the `impl` keyword for an opaque: + /// + /// ```ignore (illustrative) + /// trait Trait { type X: Bound + 'lt; } + /// // ^^^^^^^^^^^ + /// fn function() -> impl Debug + Display { /*...*/ } + /// // ^^^^^^^^^^^^^^^ + /// ``` + query explicit_item_bounds(key: DefId) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> { + desc { |tcx| "finding item bounds for `{}`", tcx.def_path_str(key) } + cache_on_disk_if { key.is_local() } + separate_provide_extern + feedable + } + + /// Returns the explicitly user-written *bounds* that share the `Self` type of the item. + /// + /// These are a subset of the [explicit item bounds] that may explicitly be used for things + /// like closure signature deduction. + /// + /// [explicit item bounds]: Self::explicit_item_bounds + query explicit_item_self_bounds(key: DefId) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> { + desc { |tcx| "finding item bounds for `{}`", tcx.def_path_str(key) } + cache_on_disk_if { key.is_local() } + separate_provide_extern + feedable + } + + /// Returns the (elaborated) *bounds* on the associated or opaque type given by `DefId` + /// that must be proven true at definition site (and which can be assumed at usage sites). + /// + /// Bounds from the parent (e.g. with nested `impl Trait`) are not included. + /// + /// **Tip**: You can use `#[rustc_dump_item_bounds]` on an item to basically print + /// the result of this query for use in UI tests or for debugging purposes. + /// + /// # Examples + /// + /// ``` + /// trait Trait { type Assoc: Eq + ?Sized; } + /// ``` + /// + /// While [`Self::explicit_item_bounds`] returns `[<Self as Trait>::Assoc: Eq]` + /// here, `item_bounds` returns: + /// + /// ```text + /// [ + /// <Self as Trait>::Assoc: Eq, + /// <Self as Trait>::Assoc: PartialEq<<Self as Trait>::Assoc> + /// ] + /// ``` + query item_bounds(key: DefId) -> ty::EarlyBinder<'tcx, ty::Clauses<'tcx>> { + desc { |tcx| "elaborating item bounds for `{}`", tcx.def_path_str(key) } + } + + query item_self_bounds(key: DefId) -> ty::EarlyBinder<'tcx, ty::Clauses<'tcx>> { + desc { |tcx| "elaborating item assumptions for `{}`", tcx.def_path_str(key) } + } + + query item_non_self_bounds(key: DefId) -> ty::EarlyBinder<'tcx, ty::Clauses<'tcx>> { + desc { |tcx| "elaborating item assumptions for `{}`", tcx.def_path_str(key) } + } + + query impl_super_outlives(key: DefId) -> ty::EarlyBinder<'tcx, ty::Clauses<'tcx>> { + desc { |tcx| "elaborating supertrait outlives for trait of `{}`", tcx.def_path_str(key) } + } + + /// Look up all native libraries this crate depends on. + /// These are assembled from the following places: + /// - `extern` blocks (depending on their `link` attributes) + /// - the `libs` (`-l`) option + query native_libraries(_: CrateNum) -> &'tcx Vec<NativeLib> { + arena_cache + desc { "looking up the native libraries of a linked crate" } + separate_provide_extern + } + + query shallow_lint_levels_on(key: hir::OwnerId) -> &'tcx rustc_middle::lint::ShallowLintLevelMap { + arena_cache + desc { |tcx| "looking up lint levels for `{}`", tcx.def_path_str(key) } + } + + query lint_expectations(_: ()) -> &'tcx Vec<(LintExpectationId, LintExpectation)> { + arena_cache + desc { "computing `#[expect]`ed lints in this crate" } + } + + query lints_that_dont_need_to_run(_: ()) -> &'tcx UnordSet<LintId> { + arena_cache + desc { "Computing all lints that are explicitly enabled or with a default level greater than Allow" } + } + + query expn_that_defined(key: DefId) -> rustc_span::ExpnId { + desc { |tcx| "getting the expansion that defined `{}`", tcx.def_path_str(key) } + separate_provide_extern + } + + query is_panic_runtime(_: CrateNum) -> bool { + cycle_fatal + desc { "checking if the crate is_panic_runtime" } + separate_provide_extern + } + + /// Checks whether a type is representable or infinitely sized + query representability(_: LocalDefId) -> rustc_middle::ty::Representability { + desc { "checking if `{}` is representable", tcx.def_path_str(key) } + // infinitely sized types will cause a cycle + cycle_delay_bug + // we don't want recursive representability calls to be forced with + // incremental compilation because, if a cycle occurs, we need the + // entire cycle to be in memory for diagnostics + anon + } + + /// An implementation detail for the `representability` query + query representability_adt_ty(_: Ty<'tcx>) -> rustc_middle::ty::Representability { + desc { "checking if `{}` is representable", key } + cycle_delay_bug + anon + } + + /// Set of param indexes for type params that are in the type's representation + query params_in_repr(key: DefId) -> &'tcx rustc_index::bit_set::DenseBitSet<u32> { + desc { "finding type parameters in the representation" } + arena_cache + no_hash + separate_provide_extern + } + + /// Fetch the THIR for a given body. The THIR body gets stolen by unsafety checking unless + /// `-Zno-steal-thir` is on. + query thir_body(key: LocalDefId) -> Result<(&'tcx Steal<thir::Thir<'tcx>>, thir::ExprId), ErrorGuaranteed> { + // Perf tests revealed that hashing THIR is inefficient (see #85729). + no_hash + desc { |tcx| "building THIR for `{}`", tcx.def_path_str(key) } + } + + /// Set of all the `DefId`s in this crate that have MIR associated with + /// them. This includes all the body owners, but also things like struct + /// constructors. + query mir_keys(_: ()) -> &'tcx rustc_data_structures::fx::FxIndexSet<LocalDefId> { + arena_cache + desc { "getting a list of all mir_keys" } + } + + /// Maps DefId's that have an associated `mir::Body` to the result + /// of the MIR const-checking pass. This is the set of qualifs in + /// the final value of a `const`. + query mir_const_qualif(key: DefId) -> mir::ConstQualifs { + desc { |tcx| "const checking `{}`", tcx.def_path_str(key) } + cache_on_disk_if { key.is_local() } + separate_provide_extern + } + + /// Build the MIR for a given `DefId` and prepare it for const qualification. + /// + /// See the [rustc dev guide] for more info. + /// + /// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/mir/construction.html + query mir_built(key: LocalDefId) -> &'tcx Steal<mir::Body<'tcx>> { + desc { |tcx| "building MIR for `{}`", tcx.def_path_str(key) } + feedable + } + + /// Try to build an abstract representation of the given constant. + query thir_abstract_const( + key: DefId + ) -> Result<Option<ty::EarlyBinder<'tcx, ty::Const<'tcx>>>, ErrorGuaranteed> { + desc { + |tcx| "building an abstract representation for `{}`", tcx.def_path_str(key), + } + separate_provide_extern + } + + query mir_drops_elaborated_and_const_checked(key: LocalDefId) -> &'tcx Steal<mir::Body<'tcx>> { + no_hash + desc { |tcx| "elaborating drops for `{}`", tcx.def_path_str(key) } + } + + query mir_for_ctfe( + key: DefId + ) -> &'tcx mir::Body<'tcx> { + desc { |tcx| "caching mir of `{}` for CTFE", tcx.def_path_str(key) } + cache_on_disk_if { key.is_local() } + separate_provide_extern + } + + query mir_promoted(key: LocalDefId) -> ( + &'tcx Steal<mir::Body<'tcx>>, + &'tcx Steal<IndexVec<mir::Promoted, mir::Body<'tcx>>> + ) { + no_hash + desc { |tcx| "promoting constants in MIR for `{}`", tcx.def_path_str(key) } + } + + query closure_typeinfo(key: LocalDefId) -> ty::ClosureTypeInfo<'tcx> { + desc { + |tcx| "finding symbols for captures of closure `{}`", + tcx.def_path_str(key) + } + } + + /// Returns names of captured upvars for closures and coroutines. + /// + /// Here are some examples: + /// - `name__field1__field2` when the upvar is captured by value. + /// - `_ref__name__field` when the upvar is captured by reference. + /// + /// For coroutines this only contains upvars that are shared by all states. + query closure_saved_names_of_captured_variables(def_id: DefId) -> &'tcx IndexVec<abi::FieldIdx, Symbol> { + arena_cache + desc { |tcx| "computing debuginfo for closure `{}`", tcx.def_path_str(def_id) } + separate_provide_extern + } + + query mir_coroutine_witnesses(key: DefId) -> Option<&'tcx mir::CoroutineLayout<'tcx>> { + arena_cache + desc { |tcx| "coroutine witness types for `{}`", tcx.def_path_str(key) } + cache_on_disk_if { key.is_local() } + separate_provide_extern + } + + query check_coroutine_obligations(key: LocalDefId) -> Result<(), ErrorGuaranteed> { + desc { |tcx| "verify auto trait bounds for coroutine interior type `{}`", tcx.def_path_str(key) } + return_result_from_ensure_ok + } + + /// Used in case `mir_borrowck` fails to prove an obligation. We generally assume that + /// all goals we prove in MIR type check hold as we've already checked them in HIR typeck. + /// + /// However, we replace each free region in the MIR body with a unique region inference + /// variable. As we may rely on structural identity when proving goals this may cause a + /// goal to no longer hold. We store obligations for which this may happen during HIR + /// typeck in the `TypeckResults`. We then uniquify and reprove them in case MIR typeck + /// encounters an unexpected error. We expect this to result in an error when used and + /// delay a bug if it does not. + query check_potentially_region_dependent_goals(key: LocalDefId) -> Result<(), ErrorGuaranteed> { + desc { + |tcx| "reproving potentially region dependent HIR typeck goals for `{}", + tcx.def_path_str(key) + } + } + + /// MIR after our optimization passes have run. This is MIR that is ready + /// for codegen. This is also the only query that can fetch non-local MIR, at present. + query optimized_mir(key: DefId) -> &'tcx mir::Body<'tcx> { + desc { |tcx| "optimizing MIR for `{}`", tcx.def_path_str(key) } + cache_on_disk_if { key.is_local() } + separate_provide_extern + } + + /// Checks for the nearest `#[coverage(off)]` or `#[coverage(on)]` on + /// this def and any enclosing defs, up to the crate root. + /// + /// Returns `false` if `#[coverage(off)]` was found, or `true` if + /// either `#[coverage(on)]` or no coverage attribute was found. + query coverage_attr_on(key: LocalDefId) -> bool { + desc { |tcx| "checking for `#[coverage(..)]` on `{}`", tcx.def_path_str(key) } + feedable + } + + /// Scans through a function's MIR after MIR optimizations, to prepare the + /// information needed by codegen when `-Cinstrument-coverage` is active. + /// + /// This includes the details of where to insert `llvm.instrprof.increment` + /// intrinsics, and the expression tables to be embedded in the function's + /// coverage metadata. + /// + /// FIXME(Zalathar): This query's purpose has drifted a bit and should + /// probably be renamed, but that can wait until after the potential + /// follow-ups to #136053 have settled down. + /// + /// Returns `None` for functions that were not instrumented. + query coverage_ids_info(key: ty::InstanceKind<'tcx>) -> Option<&'tcx mir::coverage::CoverageIdsInfo> { + desc { |tcx| "retrieving coverage IDs info from MIR for `{}`", tcx.def_path_str(key.def_id()) } + arena_cache + } + + /// The `DefId` is the `DefId` of the containing MIR body. Promoteds do not have their own + /// `DefId`. This function returns all promoteds in the specified body. The body references + /// promoteds by the `DefId` and the `mir::Promoted` index. This is necessary, because + /// after inlining a body may refer to promoteds from other bodies. In that case you still + /// need to use the `DefId` of the original body. + query promoted_mir(key: DefId) -> &'tcx IndexVec<mir::Promoted, mir::Body<'tcx>> { + desc { |tcx| "optimizing promoted MIR for `{}`", tcx.def_path_str(key) } + cache_on_disk_if { key.is_local() } + separate_provide_extern + } + + /// Erases regions from `ty` to yield a new type. + /// Normally you would just use `tcx.erase_and_anonymize_regions(value)`, + /// however, which uses this query as a kind of cache. + query erase_and_anonymize_regions_ty(ty: Ty<'tcx>) -> Ty<'tcx> { + // This query is not expected to have input -- as a result, it + // is not a good candidates for "replay" because it is essentially a + // pure function of its input (and hence the expectation is that + // no caller would be green **apart** from just these + // queries). Making it anonymous avoids hashing the result, which + // may save a bit of time. + anon + desc { "erasing regions from `{}`", ty } + } + + query wasm_import_module_map(_: CrateNum) -> &'tcx DefIdMap<String> { + arena_cache + desc { "getting wasm import module map" } + } + + /// Returns the explicitly user-written *predicates and bounds* of the trait given by `DefId`. + /// + /// Traits are unusual, because predicates on associated types are + /// converted into bounds on that type for backwards compatibility: + /// + /// ``` + /// trait X where Self::U: Copy { type U; } + /// ``` + /// + /// becomes + /// + /// ``` + /// trait X { type U: Copy; } + /// ``` + /// + /// [`Self::explicit_predicates_of`] and [`Self::explicit_item_bounds`] will + /// then take the appropriate subsets of the predicates here. + /// + /// # Panics + /// + /// This query will panic if the given definition is not a trait. + query trait_explicit_predicates_and_bounds(key: LocalDefId) -> ty::GenericPredicates<'tcx> { + desc { |tcx| "computing explicit predicates of trait `{}`", tcx.def_path_str(key) } + } + + /// Returns the explicitly user-written *predicates* of the definition given by `DefId` + /// that must be proven true at usage sites (and which can be assumed at definition site). + /// + /// You should probably use [`Self::predicates_of`] unless you're looking for + /// predicates with explicit spans for diagnostics purposes. + query explicit_predicates_of(key: DefId) -> ty::GenericPredicates<'tcx> { + desc { |tcx| "computing explicit predicates of `{}`", tcx.def_path_str(key) } + cache_on_disk_if { key.is_local() } + separate_provide_extern + feedable + } + + /// Returns the *inferred outlives-predicates* of the item given by `DefId`. + /// + /// E.g., for `struct Foo<'a, T> { x: &'a T }`, this would return `[T: 'a]`. + /// + /// **Tip**: You can use `#[rustc_outlives]` on an item to basically print the + /// result of this query for use in UI tests or for debugging purposes. + query inferred_outlives_of(key: DefId) -> &'tcx [(ty::Clause<'tcx>, Span)] { + desc { |tcx| "computing inferred outlives-predicates of `{}`", tcx.def_path_str(key) } + cache_on_disk_if { key.is_local() } + separate_provide_extern + feedable + } + + /// Returns the explicitly user-written *super-predicates* of the trait given by `DefId`. + /// + /// These predicates are unelaborated and consequently don't contain transitive super-predicates. + /// + /// This is a subset of the full list of predicates. We store these in a separate map + /// because we must evaluate them even during type conversion, often before the full + /// predicates are available (note that super-predicates must not be cyclic). + query explicit_super_predicates_of(key: DefId) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> { + desc { |tcx| "computing the super predicates of `{}`", tcx.def_path_str(key) } + cache_on_disk_if { key.is_local() } + separate_provide_extern + } + + /// The predicates of the trait that are implied during elaboration. + /// + /// This is a superset of the super-predicates of the trait, but a subset of the predicates + /// of the trait. For regular traits, this includes all super-predicates and their + /// associated type bounds. For trait aliases, currently, this includes all of the + /// predicates of the trait alias. + query explicit_implied_predicates_of(key: DefId) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> { + desc { |tcx| "computing the implied predicates of `{}`", tcx.def_path_str(key) } + cache_on_disk_if { key.is_local() } + separate_provide_extern + } + + /// The Ident is the name of an associated type.The query returns only the subset + /// of supertraits that define the given associated type. This is used to avoid + /// cycles in resolving type-dependent associated item paths like `T::Item`. + query explicit_supertraits_containing_assoc_item( + key: (DefId, rustc_span::Ident) + ) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> { + desc { |tcx| "computing the super traits of `{}` with associated type name `{}`", + tcx.def_path_str(key.0), + key.1 + } + } + + /// Compute the conditions that need to hold for a conditionally-const item to be const. + /// That is, compute the set of `[const]` where clauses for a given item. + /// + /// This can be thought of as the `[const]` equivalent of `predicates_of`. These are the + /// predicates that need to be proven at usage sites, and can be assumed at definition. + /// + /// This query also computes the `[const]` where clauses for associated types, which are + /// not "const", but which have item bounds which may be `[const]`. These must hold for + /// the `[const]` item bound to hold. + query const_conditions( + key: DefId + ) -> ty::ConstConditions<'tcx> { + desc { |tcx| "computing the conditions for `{}` to be considered const", + tcx.def_path_str(key) + } + separate_provide_extern + } + + /// Compute the const bounds that are implied for a conditionally-const item. + /// + /// This can be though of as the `[const]` equivalent of `explicit_item_bounds`. These + /// are the predicates that need to proven at definition sites, and can be assumed at + /// usage sites. + query explicit_implied_const_bounds( + key: DefId + ) -> ty::EarlyBinder<'tcx, &'tcx [(ty::PolyTraitRef<'tcx>, Span)]> { + desc { |tcx| "computing the implied `[const]` bounds for `{}`", + tcx.def_path_str(key) + } + separate_provide_extern + } + + /// To avoid cycles within the predicates of a single item we compute + /// per-type-parameter predicates for resolving `T::AssocTy`. + query type_param_predicates( + key: (LocalDefId, LocalDefId, rustc_span::Ident) + ) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> { + desc { |tcx| "computing the bounds for type parameter `{}`", tcx.hir_ty_param_name(key.1) } + } + + query trait_def(key: DefId) -> &'tcx ty::TraitDef { + desc { |tcx| "computing trait definition for `{}`", tcx.def_path_str(key) } + arena_cache + cache_on_disk_if { key.is_local() } + separate_provide_extern + } + query adt_def(key: DefId) -> ty::AdtDef<'tcx> { + desc { |tcx| "computing ADT definition for `{}`", tcx.def_path_str(key) } + cache_on_disk_if { key.is_local() } + separate_provide_extern + } + query adt_destructor(key: DefId) -> Option<ty::Destructor> { + desc { |tcx| "computing `Drop` impl for `{}`", tcx.def_path_str(key) } + cache_on_disk_if { key.is_local() } + separate_provide_extern + } + query adt_async_destructor(key: DefId) -> Option<ty::AsyncDestructor> { + desc { |tcx| "computing `AsyncDrop` impl for `{}`", tcx.def_path_str(key) } + cache_on_disk_if { key.is_local() } + separate_provide_extern + } + query adt_sizedness_constraint( + key: (DefId, SizedTraitKind) + ) -> Option<ty::EarlyBinder<'tcx, Ty<'tcx>>> { + desc { |tcx| "computing the sizedness constraint for `{}`", tcx.def_path_str(key.0) } + } + + query adt_dtorck_constraint( + key: DefId + ) -> &'tcx DropckConstraint<'tcx> { + desc { |tcx| "computing drop-check constraints for `{}`", tcx.def_path_str(key) } + } + + /// Returns the constness of the function-like[^1] definition given by `DefId`. + /// + /// Tuple struct/variant constructors are *always* const, foreign functions are + /// *never* const. The rest is const iff marked with keyword `const` (or rather + /// its parent in the case of associated functions). + /// + /// <div class="warning"> + /// + /// **Do not call this query** directly. It is only meant to cache the base data for the + /// higher-level functions. Consider using `is_const_fn` or `is_const_trait_impl` instead. + /// + /// Also note that neither of them takes into account feature gates, stability and + /// const predicates/conditions! + /// + /// </div> + /// + /// # Panics + /// + /// This query will panic if the given definition is not function-like[^1]. + /// + /// [^1]: Tuple struct/variant constructors, closures and free, associated and foreign functions. + query constness(key: DefId) -> hir::Constness { + desc { |tcx| "checking if item is const: `{}`", tcx.def_path_str(key) } + separate_provide_extern + feedable + } + + query asyncness(key: DefId) -> ty::Asyncness { + desc { |tcx| "checking if the function is async: `{}`", tcx.def_path_str(key) } + separate_provide_extern + } + + /// Returns `true` if calls to the function may be promoted. + /// + /// This is either because the function is e.g., a tuple-struct or tuple-variant + /// constructor, or because it has the `#[rustc_promotable]` attribute. The attribute should + /// be removed in the future in favour of some form of check which figures out whether the + /// function does not inspect the bits of any of its arguments (so is essentially just a + /// constructor function). + query is_promotable_const_fn(key: DefId) -> bool { + desc { |tcx| "checking if item is promotable: `{}`", tcx.def_path_str(key) } + } + + /// The body of the coroutine, modified to take its upvars by move rather than by ref. + /// + /// This is used by coroutine-closures, which must return a different flavor of coroutine + /// when called using `AsyncFnOnce::call_once`. It is produced by the `ByMoveBody` pass which + /// is run right after building the initial MIR, and will only be populated for coroutines + /// which come out of the async closure desugaring. + query coroutine_by_move_body_def_id(def_id: DefId) -> DefId { + desc { |tcx| "looking up the coroutine by-move body for `{}`", tcx.def_path_str(def_id) } + separate_provide_extern + } + + /// Returns `Some(coroutine_kind)` if the node pointed to by `def_id` is a coroutine. + query coroutine_kind(def_id: DefId) -> Option<hir::CoroutineKind> { + desc { |tcx| "looking up coroutine kind of `{}`", tcx.def_path_str(def_id) } + separate_provide_extern + feedable + } + + query coroutine_for_closure(def_id: DefId) -> DefId { + desc { |_tcx| "Given a coroutine-closure def id, return the def id of the coroutine returned by it" } + separate_provide_extern + } + + query coroutine_hidden_types( + def_id: DefId, + ) -> ty::EarlyBinder<'tcx, ty::Binder<'tcx, ty::CoroutineWitnessTypes<TyCtxt<'tcx>>>> { + desc { "looking up the hidden types stored across await points in a coroutine" } + } + + /// Gets a map with the variances of every item in the local crate. + /// + /// <div class="warning"> + /// + /// **Do not call this query** directly, use [`Self::variances_of`] instead. + /// + /// </div> + query crate_variances(_: ()) -> &'tcx ty::CrateVariancesMap<'tcx> { + arena_cache + desc { "computing the variances for items in this crate" } + } + + /// Returns the (inferred) variances of the item given by `DefId`. + /// + /// The list of variances corresponds to the list of (early-bound) generic + /// parameters of the item (including its parents). + /// + /// **Tip**: You can use `#[rustc_variance]` on an item to basically print the + /// result of this query for use in UI tests or for debugging purposes. + query variances_of(def_id: DefId) -> &'tcx [ty::Variance] { + desc { |tcx| "computing the variances of `{}`", tcx.def_path_str(def_id) } + cache_on_disk_if { def_id.is_local() } + separate_provide_extern + cycle_delay_bug + } + + /// Gets a map with the inferred outlives-predicates of every item in the local crate. + /// + /// <div class="warning"> + /// + /// **Do not call this query** directly, use [`Self::inferred_outlives_of`] instead. + /// + /// </div> + query inferred_outlives_crate(_: ()) -> &'tcx ty::CratePredicatesMap<'tcx> { + arena_cache + desc { "computing the inferred outlives-predicates for items in this crate" } + } + + /// Maps from an impl/trait or struct/variant `DefId` + /// to a list of the `DefId`s of its associated items or fields. + query associated_item_def_ids(key: DefId) -> &'tcx [DefId] { + desc { |tcx| "collecting associated items or fields of `{}`", tcx.def_path_str(key) } + cache_on_disk_if { key.is_local() } + separate_provide_extern + } + + /// Maps from a trait/impl item to the trait/impl item "descriptor". + query associated_item(key: DefId) -> ty::AssocItem { + desc { |tcx| "computing associated item data for `{}`", tcx.def_path_str(key) } + cache_on_disk_if { key.is_local() } + separate_provide_extern + feedable + } + + /// Collects the associated items defined on a trait or impl. + query associated_items(key: DefId) -> &'tcx ty::AssocItems { + arena_cache + desc { |tcx| "collecting associated items of `{}`", tcx.def_path_str(key) } + } + + /// Maps from associated items on a trait to the corresponding associated + /// item on the impl specified by `impl_id`. + /// + /// For example, with the following code + /// + /// ``` + /// struct Type {} + /// // DefId + /// trait Trait { // trait_id + /// fn f(); // trait_f + /// fn g() {} // trait_g + /// } + /// + /// impl Trait for Type { // impl_id + /// fn f() {} // impl_f + /// fn g() {} // impl_g + /// } + /// ``` + /// + /// The map returned for `tcx.impl_item_implementor_ids(impl_id)` would be + ///`{ trait_f: impl_f, trait_g: impl_g }` + query impl_item_implementor_ids(impl_id: DefId) -> &'tcx DefIdMap<DefId> { + arena_cache + desc { |tcx| "comparing impl items against trait for `{}`", tcx.def_path_str(impl_id) } + } + + /// Given the `item_def_id` of a trait or impl, return a mapping from associated fn def id + /// to its associated type items that correspond to the RPITITs in its signature. + query associated_types_for_impl_traits_in_trait_or_impl(item_def_id: DefId) -> &'tcx DefIdMap<Vec<DefId>> { + arena_cache + desc { |tcx| "synthesizing RPITIT items for the opaque types for methods in `{}`", tcx.def_path_str(item_def_id) } + separate_provide_extern + } + + /// Given an `impl_id`, return the trait it implements along with some header information. + query impl_trait_header(impl_id: DefId) -> ty::ImplTraitHeader<'tcx> { + desc { |tcx| "computing trait implemented by `{}`", tcx.def_path_str(impl_id) } + cache_on_disk_if { impl_id.is_local() } + separate_provide_extern + } + + /// Given an `impl_def_id`, return true if the self type is guaranteed to be unsized due + /// to either being one of the built-in unsized types (str/slice/dyn) or to be a struct + /// whose tail is one of those types. + query impl_self_is_guaranteed_unsized(impl_def_id: DefId) -> bool { + desc { |tcx| "computing whether `{}` has a guaranteed unsized self type", tcx.def_path_str(impl_def_id) } + } + + /// Maps a `DefId` of a type to a list of its inherent impls. + /// Contains implementations of methods that are inherent to a type. + /// Methods in these implementations don't need to be exported. + query inherent_impls(key: DefId) -> &'tcx [DefId] { + desc { |tcx| "collecting inherent impls for `{}`", tcx.def_path_str(key) } + cache_on_disk_if { key.is_local() } + separate_provide_extern + } + + query incoherent_impls(key: SimplifiedType) -> &'tcx [DefId] { + desc { |tcx| "collecting all inherent impls for `{:?}`", key } + } + + /// Unsafety-check this `LocalDefId`. + query check_transmutes(key: LocalDefId) { + desc { |tcx| "check transmute calls inside `{}`", tcx.def_path_str(key) } + } + + /// Unsafety-check this `LocalDefId`. + query check_unsafety(key: LocalDefId) { + desc { |tcx| "unsafety-checking `{}`", tcx.def_path_str(key) } + } + + /// Checks well-formedness of tail calls (`become f()`). + query check_tail_calls(key: LocalDefId) -> Result<(), rustc_errors::ErrorGuaranteed> { + desc { |tcx| "tail-call-checking `{}`", tcx.def_path_str(key) } + return_result_from_ensure_ok + } + + /// Returns the types assumed to be well formed while "inside" of the given item. + /// + /// Note that we've liberated the late bound regions of function signatures, so + /// this can not be used to check whether these types are well formed. + query assumed_wf_types(key: LocalDefId) -> &'tcx [(Ty<'tcx>, Span)] { + desc { |tcx| "computing the implied bounds of `{}`", tcx.def_path_str(key) } + } + + /// We need to store the assumed_wf_types for an RPITIT so that impls of foreign + /// traits with return-position impl trait in traits can inherit the right wf types. + query assumed_wf_types_for_rpitit(key: DefId) -> &'tcx [(Ty<'tcx>, Span)] { + desc { |tcx| "computing the implied bounds of `{}`", tcx.def_path_str(key) } + separate_provide_extern + } + + /// Computes the signature of the function. + query fn_sig(key: DefId) -> ty::EarlyBinder<'tcx, ty::PolyFnSig<'tcx>> { + desc { |tcx| "computing function signature of `{}`", tcx.def_path_str(key) } + cache_on_disk_if { key.is_local() } + separate_provide_extern + cycle_delay_bug + } + + /// Performs lint checking for the module. + query lint_mod(key: LocalModDefId) { + desc { |tcx| "linting {}", describe_as_module(key, tcx) } + } + + query check_unused_traits(_: ()) { + desc { "checking unused trait imports in crate" } + } + + /// Checks the attributes in the module. + query check_mod_attrs(key: LocalModDefId) { + desc { |tcx| "checking attributes in {}", describe_as_module(key, tcx) } + } + + /// Checks for uses of unstable APIs in the module. + query check_mod_unstable_api_usage(key: LocalModDefId) { + desc { |tcx| "checking for unstable API usage in {}", describe_as_module(key, tcx) } + } + + query check_mod_privacy(key: LocalModDefId) { + desc { |tcx| "checking privacy in {}", describe_as_module(key.to_local_def_id(), tcx) } + } + + query check_liveness(key: LocalDefId) -> &'tcx rustc_index::bit_set::DenseBitSet<abi::FieldIdx> { + arena_cache + desc { |tcx| "checking liveness of variables in `{}`", tcx.def_path_str(key.to_def_id()) } + cache_on_disk_if(tcx) { tcx.is_typeck_child(key.to_def_id()) } + } + + /// Return the live symbols in the crate for dead code check. + /// + /// The second return value maps from ADTs to ignored derived traits (e.g. Debug and Clone). + query live_symbols_and_ignored_derived_traits(_: ()) -> &'tcx Result<( + LocalDefIdSet, + LocalDefIdMap<FxIndexSet<DefId>>, + ), ErrorGuaranteed> { + arena_cache + desc { "finding live symbols in crate" } + } + + query check_mod_deathness(key: LocalModDefId) { + desc { |tcx| "checking deathness of variables in {}", describe_as_module(key, tcx) } + } + + query check_type_wf(key: ()) -> Result<(), ErrorGuaranteed> { + desc { "checking that types are well-formed" } + return_result_from_ensure_ok + } + + /// Caches `CoerceUnsized` kinds for impls on custom types. + query coerce_unsized_info(key: DefId) -> Result<ty::adjustment::CoerceUnsizedInfo, ErrorGuaranteed> { + desc { |tcx| "computing CoerceUnsized info for `{}`", tcx.def_path_str(key) } + cache_on_disk_if { key.is_local() } + separate_provide_extern + return_result_from_ensure_ok + } + + query typeck(key: LocalDefId) -> &'tcx ty::TypeckResults<'tcx> { + desc { |tcx| "type-checking `{}`", tcx.def_path_str(key) } + cache_on_disk_if(tcx) { !tcx.is_typeck_child(key.to_def_id()) } + } + + query used_trait_imports(key: LocalDefId) -> &'tcx UnordSet<LocalDefId> { + desc { |tcx| "finding used_trait_imports `{}`", tcx.def_path_str(key) } + cache_on_disk_if { true } + } + + query coherent_trait(def_id: DefId) -> Result<(), ErrorGuaranteed> { + desc { |tcx| "coherence checking all impls of trait `{}`", tcx.def_path_str(def_id) } + return_result_from_ensure_ok + } + + /// Borrow-checks the given typeck root, e.g. functions, const/static items, + /// and its children, e.g. closures, inline consts. + query mir_borrowck(key: LocalDefId) -> Result< + &'tcx FxIndexMap<LocalDefId, ty::DefinitionSiteHiddenType<'tcx>>, + ErrorGuaranteed + > { + desc { |tcx| "borrow-checking `{}`", tcx.def_path_str(key) } + } + + /// Gets a complete map from all types to their inherent impls. + /// + /// <div class="warning"> + /// + /// **Not meant to be used** directly outside of coherence. + /// + /// </div> + query crate_inherent_impls(k: ()) -> (&'tcx CrateInherentImpls, Result<(), ErrorGuaranteed>) { + desc { "finding all inherent impls defined in crate" } + } + + /// Checks all types in the crate for overlap in their inherent impls. Reports errors. + /// + /// <div class="warning"> + /// + /// **Not meant to be used** directly outside of coherence. + /// + /// </div> + query crate_inherent_impls_validity_check(_: ()) -> Result<(), ErrorGuaranteed> { + desc { "check for inherent impls that should not be defined in crate" } + return_result_from_ensure_ok + } + + /// Checks all types in the crate for overlap in their inherent impls. Reports errors. + /// + /// <div class="warning"> + /// + /// **Not meant to be used** directly outside of coherence. + /// + /// </div> + query crate_inherent_impls_overlap_check(_: ()) -> Result<(), ErrorGuaranteed> { + desc { "check for overlap between inherent impls defined in this crate" } + return_result_from_ensure_ok + } + + /// Checks whether all impls in the crate pass the overlap check, returning + /// which impls fail it. If all impls are correct, the returned slice is empty. + query orphan_check_impl(key: LocalDefId) -> Result<(), ErrorGuaranteed> { + desc { |tcx| + "checking whether impl `{}` follows the orphan rules", + tcx.def_path_str(key), + } + return_result_from_ensure_ok + } + + /// Return the set of (transitive) callees that may result in a recursive call to `key`, + /// if we were able to walk all callees. + query mir_callgraph_cyclic(key: LocalDefId) -> &'tcx Option<UnordSet<LocalDefId>> { + cycle_fatal + arena_cache + desc { |tcx| + "computing (transitive) callees of `{}` that may recurse", + tcx.def_path_str(key), + } + cache_on_disk_if { true } + } + + /// Obtain all the calls into other local functions + query mir_inliner_callees(key: ty::InstanceKind<'tcx>) -> &'tcx [(DefId, GenericArgsRef<'tcx>)] { + cycle_fatal + desc { |tcx| + "computing all local function calls in `{}`", + tcx.def_path_str(key.def_id()), + } + } + + /// Computes the tag (if any) for a given type and variant. + /// + /// `None` means that the variant doesn't need a tag (because it is niched). + /// + /// # Panics + /// + /// This query will panic for uninhabited variants and if the passed type is not an enum. + query tag_for_variant( + key: PseudoCanonicalInput<'tcx, (Ty<'tcx>, abi::VariantIdx)>, + ) -> Option<ty::ScalarInt> { + desc { "computing variant tag for enum" } + } + + /// Evaluates a constant and returns the computed allocation. + /// + /// <div class="warning"> + /// + /// **Do not call this query** directly, use [`Self::eval_to_const_value_raw`] or + /// [`Self::eval_to_valtree`] instead. + /// + /// </div> + query eval_to_allocation_raw(key: ty::PseudoCanonicalInput<'tcx, GlobalId<'tcx>>) + -> EvalToAllocationRawResult<'tcx> { + desc { |tcx| + "const-evaluating + checking `{}`", + key.value.display(tcx) + } + cache_on_disk_if { true } + } + + /// Evaluate a static's initializer, returning the allocation of the initializer's memory. + query eval_static_initializer(key: DefId) -> EvalStaticInitializerRawResult<'tcx> { + desc { |tcx| + "evaluating initializer of static `{}`", + tcx.def_path_str(key) + } + cache_on_disk_if { key.is_local() } + separate_provide_extern + feedable + } + + /// Evaluates const items or anonymous constants[^1] into a representation + /// suitable for the type system and const generics. + /// + /// <div class="warning"> + /// + /// **Do not call this** directly, use one of the following wrappers: + /// [`TyCtxt::const_eval_poly`], [`TyCtxt::const_eval_resolve`], + /// [`TyCtxt::const_eval_instance`], or [`TyCtxt::const_eval_global_id`]. + /// + /// </div> + /// + /// [^1]: Such as enum variant explicit discriminants or array lengths. + query eval_to_const_value_raw(key: ty::PseudoCanonicalInput<'tcx, GlobalId<'tcx>>) + -> EvalToConstValueResult<'tcx> { + desc { |tcx| + "simplifying constant for the type system `{}`", + key.value.display(tcx) + } + depth_limit + cache_on_disk_if { true } + } + + /// Evaluate a constant and convert it to a type level constant or + /// return `None` if that is not possible. + query eval_to_valtree( + key: ty::PseudoCanonicalInput<'tcx, GlobalId<'tcx>> + ) -> EvalToValTreeResult<'tcx> { + desc { "evaluating type-level constant" } + } + + /// Converts a type-level constant value into a MIR constant value. + query valtree_to_const_val(key: ty::Value<'tcx>) -> mir::ConstValue { + desc { "converting type-level constant value to MIR constant value"} + } + + // FIXME get rid of this with valtrees + query lit_to_const( + key: LitToConstInput<'tcx> + ) -> ty::Const<'tcx> { + desc { "converting literal to const" } + } + + query check_match(key: LocalDefId) -> Result<(), rustc_errors::ErrorGuaranteed> { + desc { |tcx| "match-checking `{}`", tcx.def_path_str(key) } + return_result_from_ensure_ok + } + + /// Performs part of the privacy check and computes effective visibilities. + query effective_visibilities(_: ()) -> &'tcx EffectiveVisibilities { + eval_always + desc { "checking effective visibilities" } + } + query check_private_in_public(module_def_id: LocalModDefId) { + desc { |tcx| + "checking for private elements in public interfaces for {}", + describe_as_module(module_def_id, tcx) + } + } + + query reachable_set(_: ()) -> &'tcx LocalDefIdSet { + arena_cache + desc { "reachability" } + cache_on_disk_if { true } + } + + /// Per-body `region::ScopeTree`. The `DefId` should be the owner `DefId` for the body; + /// in the case of closures, this will be redirected to the enclosing function. + query region_scope_tree(def_id: DefId) -> &'tcx crate::middle::region::ScopeTree { + desc { |tcx| "computing drop scopes for `{}`", tcx.def_path_str(def_id) } + } + + /// Generates a MIR body for the shim. + query mir_shims(key: ty::InstanceKind<'tcx>) -> &'tcx mir::Body<'tcx> { + arena_cache + desc { + |tcx| "generating MIR shim for `{}`, instance={:?}", + tcx.def_path_str(key.def_id()), + key + } + } + + /// The `symbol_name` query provides the symbol name for calling a + /// given instance from the local crate. In particular, it will also + /// look up the correct symbol name of instances from upstream crates. + query symbol_name(key: ty::Instance<'tcx>) -> ty::SymbolName<'tcx> { + desc { "computing the symbol for `{}`", key } + cache_on_disk_if { true } + } + + query def_kind(def_id: DefId) -> DefKind { + desc { |tcx| "looking up definition kind of `{}`", tcx.def_path_str(def_id) } + cache_on_disk_if { def_id.is_local() } + separate_provide_extern + feedable + } + + /// Gets the span for the definition. + query def_span(def_id: DefId) -> Span { + desc { |tcx| "looking up span for `{}`", tcx.def_path_str(def_id) } + cache_on_disk_if { def_id.is_local() } + separate_provide_extern + feedable + } + + /// Gets the span for the identifier of the definition. + query def_ident_span(def_id: DefId) -> Option<Span> { + desc { |tcx| "looking up span for `{}`'s identifier", tcx.def_path_str(def_id) } + cache_on_disk_if { def_id.is_local() } + separate_provide_extern + feedable + } + + /// Gets the span for the type of the definition. + /// Panics if it is not a definition that has a single type. + query ty_span(def_id: LocalDefId) -> Span { + desc { |tcx| "looking up span for `{}`'s type", tcx.def_path_str(def_id) } + cache_on_disk_if { true } + } + + query lookup_stability(def_id: DefId) -> Option<hir::Stability> { + desc { |tcx| "looking up stability of `{}`", tcx.def_path_str(def_id) } + cache_on_disk_if { def_id.is_local() } + separate_provide_extern + } + + query lookup_const_stability(def_id: DefId) -> Option<hir::ConstStability> { + desc { |tcx| "looking up const stability of `{}`", tcx.def_path_str(def_id) } + cache_on_disk_if { def_id.is_local() } + separate_provide_extern + } + + query lookup_default_body_stability(def_id: DefId) -> Option<hir::DefaultBodyStability> { + desc { |tcx| "looking up default body stability of `{}`", tcx.def_path_str(def_id) } + separate_provide_extern + } + + query should_inherit_track_caller(def_id: DefId) -> bool { + desc { |tcx| "computing should_inherit_track_caller of `{}`", tcx.def_path_str(def_id) } + } + + query inherited_align(def_id: DefId) -> Option<Align> { + desc { |tcx| "computing inherited_align of `{}`", tcx.def_path_str(def_id) } + } + + query lookup_deprecation_entry(def_id: DefId) -> Option<DeprecationEntry> { + desc { |tcx| "checking whether `{}` is deprecated", tcx.def_path_str(def_id) } + cache_on_disk_if { def_id.is_local() } + separate_provide_extern + } + + /// Determines whether an item is annotated with `#[doc(hidden)]`. + query is_doc_hidden(def_id: DefId) -> bool { + desc { |tcx| "checking whether `{}` is `doc(hidden)`", tcx.def_path_str(def_id) } + separate_provide_extern + } + + /// Determines whether an item is annotated with `#[doc(notable_trait)]`. + query is_doc_notable_trait(def_id: DefId) -> bool { + desc { |tcx| "checking whether `{}` is `doc(notable_trait)`", tcx.def_path_str(def_id) } + } + + /// Returns the attributes on the item at `def_id`. + /// + /// Do not use this directly, use `tcx.get_attrs` instead. + query attrs_for_def(def_id: DefId) -> &'tcx [hir::Attribute] { + desc { |tcx| "collecting attributes of `{}`", tcx.def_path_str(def_id) } + separate_provide_extern + } + + /// Returns the `CodegenFnAttrs` for the item at `def_id`. + /// + /// If possible, use `tcx.codegen_instance_attrs` instead. That function takes the + /// instance kind into account. + /// + /// For example, the `#[naked]` attribute should be applied for `InstanceKind::Item`, + /// but should not be applied if the instance kind is `InstanceKind::ReifyShim`. + /// Using this query would include the attribute regardless of the actual instance + /// kind at the call site. + query codegen_fn_attrs(def_id: DefId) -> &'tcx CodegenFnAttrs { + desc { |tcx| "computing codegen attributes of `{}`", tcx.def_path_str(def_id) } + arena_cache + cache_on_disk_if { def_id.is_local() } + separate_provide_extern + feedable + } + + query asm_target_features(def_id: DefId) -> &'tcx FxIndexSet<Symbol> { + desc { |tcx| "computing target features for inline asm of `{}`", tcx.def_path_str(def_id) } + } + + query fn_arg_idents(def_id: DefId) -> &'tcx [Option<rustc_span::Ident>] { + desc { |tcx| "looking up function parameter identifiers for `{}`", tcx.def_path_str(def_id) } + separate_provide_extern + } + + /// Gets the rendered value of the specified constant or associated constant. + /// Used by rustdoc. + query rendered_const(def_id: DefId) -> &'tcx String { + arena_cache + desc { |tcx| "rendering constant initializer of `{}`", tcx.def_path_str(def_id) } + separate_provide_extern + } + + /// Gets the rendered precise capturing args for an opaque for use in rustdoc. + query rendered_precise_capturing_args(def_id: DefId) -> Option<&'tcx [PreciseCapturingArgKind<Symbol, Symbol>]> { + desc { |tcx| "rendering precise capturing args for `{}`", tcx.def_path_str(def_id) } + separate_provide_extern + } + + query impl_parent(def_id: DefId) -> Option<DefId> { + desc { |tcx| "computing specialization parent impl of `{}`", tcx.def_path_str(def_id) } + separate_provide_extern + } + + query is_ctfe_mir_available(key: DefId) -> bool { + desc { |tcx| "checking if item has CTFE MIR available: `{}`", tcx.def_path_str(key) } + cache_on_disk_if { key.is_local() } + separate_provide_extern + } + query is_mir_available(key: DefId) -> bool { + desc { |tcx| "checking if item has MIR available: `{}`", tcx.def_path_str(key) } + cache_on_disk_if { key.is_local() } + separate_provide_extern + } + + query own_existential_vtable_entries( + key: DefId + ) -> &'tcx [DefId] { + desc { |tcx| "finding all existential vtable entries for trait `{}`", tcx.def_path_str(key) } + } + + query vtable_entries(key: ty::TraitRef<'tcx>) + -> &'tcx [ty::VtblEntry<'tcx>] { + desc { |tcx| "finding all vtable entries for trait `{}`", tcx.def_path_str(key.def_id) } + } + + query first_method_vtable_slot(key: ty::TraitRef<'tcx>) -> usize { + desc { |tcx| "finding the slot within the vtable of `{}` for the implementation of `{}`", key.self_ty(), key.print_only_trait_name() } + } + + query supertrait_vtable_slot(key: (Ty<'tcx>, Ty<'tcx>)) -> Option<usize> { + desc { |tcx| "finding the slot within vtable for trait object `{}` vtable ptr during trait upcasting coercion from `{}` vtable", + key.1, key.0 } + } + + query vtable_allocation(key: (Ty<'tcx>, Option<ty::ExistentialTraitRef<'tcx>>)) -> mir::interpret::AllocId { + desc { |tcx| "vtable const allocation for <{} as {}>", + key.0, + key.1.map(|trait_ref| format!("{trait_ref}")).unwrap_or_else(|| "_".to_owned()) + } + } + + query codegen_select_candidate( + key: PseudoCanonicalInput<'tcx, ty::TraitRef<'tcx>> + ) -> Result<&'tcx ImplSource<'tcx, ()>, CodegenObligationError> { + cache_on_disk_if { true } + desc { |tcx| "computing candidate for `{}`", key.value } + } + + /// Return all `impl` blocks in the current crate. + query all_local_trait_impls(_: ()) -> &'tcx rustc_data_structures::fx::FxIndexMap<DefId, Vec<LocalDefId>> { + desc { "finding local trait impls" } + } + + /// Return all `impl` blocks of the given trait in the current crate. + query local_trait_impls(trait_id: DefId) -> &'tcx [LocalDefId] { + desc { "finding local trait impls of `{}`", tcx.def_path_str(trait_id) } + } + + /// Given a trait `trait_id`, return all known `impl` blocks. + query trait_impls_of(trait_id: DefId) -> &'tcx ty::trait_def::TraitImpls { + arena_cache + desc { |tcx| "finding trait impls of `{}`", tcx.def_path_str(trait_id) } + } + + query specialization_graph_of(trait_id: DefId) -> Result<&'tcx specialization_graph::Graph, ErrorGuaranteed> { + desc { |tcx| "building specialization graph of trait `{}`", tcx.def_path_str(trait_id) } + cache_on_disk_if { true } + return_result_from_ensure_ok + } + query dyn_compatibility_violations(trait_id: DefId) -> &'tcx [DynCompatibilityViolation] { + desc { |tcx| "determining dyn-compatibility of trait `{}`", tcx.def_path_str(trait_id) } + } + query is_dyn_compatible(trait_id: DefId) -> bool { + desc { |tcx| "checking if trait `{}` is dyn-compatible", tcx.def_path_str(trait_id) } + } + + /// Gets the ParameterEnvironment for a given item; this environment + /// will be in "user-facing" mode, meaning that it is suitable for + /// type-checking etc, and it does not normalize specializable + /// associated types. + /// + /// You should almost certainly not use this. If you already have an InferCtxt, then + /// you should also probably have a `ParamEnv` from when it was built. If you don't, + /// then you should take a `TypingEnv` to ensure that you handle opaque types correctly. + query param_env(def_id: DefId) -> ty::ParamEnv<'tcx> { + desc { |tcx| "computing normalized predicates of `{}`", tcx.def_path_str(def_id) } + feedable + } + + /// Like `param_env`, but returns the `ParamEnv` after all opaque types have been + /// replaced with their hidden type. This is used in the old trait solver + /// when in `PostAnalysis` mode and should not be called directly. + query typing_env_normalized_for_post_analysis(def_id: DefId) -> ty::TypingEnv<'tcx> { + desc { |tcx| "computing revealed normalized predicates of `{}`", tcx.def_path_str(def_id) } + } + + /// Trait selection queries. These are best used by invoking `ty.is_copy_modulo_regions()`, + /// `ty.is_copy()`, etc, since that will prune the environment where possible. + query is_copy_raw(env: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) -> bool { + desc { "computing whether `{}` is `Copy`", env.value } + } + /// Trait selection queries. These are best used by invoking `ty.is_use_cloned_modulo_regions()`, + /// `ty.is_use_cloned()`, etc, since that will prune the environment where possible. + query is_use_cloned_raw(env: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) -> bool { + desc { "computing whether `{}` is `UseCloned`", env.value } + } + /// Query backing `Ty::is_sized`. + query is_sized_raw(env: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) -> bool { + desc { "computing whether `{}` is `Sized`", env.value } + } + /// Query backing `Ty::is_freeze`. + query is_freeze_raw(env: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) -> bool { + desc { "computing whether `{}` is freeze", env.value } + } + /// Query backing `Ty::is_unpin`. + query is_unpin_raw(env: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) -> bool { + desc { "computing whether `{}` is `Unpin`", env.value } + } + /// Query backing `Ty::is_async_drop`. + query is_async_drop_raw(env: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) -> bool { + desc { "computing whether `{}` is `AsyncDrop`", env.value } + } + /// Query backing `Ty::needs_drop`. + query needs_drop_raw(env: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) -> bool { + desc { "computing whether `{}` needs drop", env.value } + } + /// Query backing `Ty::needs_async_drop`. + query needs_async_drop_raw(env: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) -> bool { + desc { "computing whether `{}` needs async drop", env.value } + } + /// Query backing `Ty::has_significant_drop_raw`. + query has_significant_drop_raw(env: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) -> bool { + desc { "computing whether `{}` has a significant drop", env.value } + } + + /// Query backing `Ty::is_structural_eq_shallow`. + /// + /// This is only correct for ADTs. Call `is_structural_eq_shallow` to handle all types + /// correctly. + query has_structural_eq_impl(ty: Ty<'tcx>) -> bool { + desc { + "computing whether `{}` implements `StructuralPartialEq`", + ty + } + } + + /// A list of types where the ADT requires drop if and only if any of + /// those types require drop. If the ADT is known to always need drop + /// then `Err(AlwaysRequiresDrop)` is returned. + query adt_drop_tys(def_id: DefId) -> Result<&'tcx ty::List<Ty<'tcx>>, AlwaysRequiresDrop> { + desc { |tcx| "computing when `{}` needs drop", tcx.def_path_str(def_id) } + cache_on_disk_if { true } + } + + /// A list of types where the ADT requires async drop if and only if any of + /// those types require async drop. If the ADT is known to always need async drop + /// then `Err(AlwaysRequiresDrop)` is returned. + query adt_async_drop_tys(def_id: DefId) -> Result<&'tcx ty::List<Ty<'tcx>>, AlwaysRequiresDrop> { + desc { |tcx| "computing when `{}` needs async drop", tcx.def_path_str(def_id) } + cache_on_disk_if { true } + } + + /// A list of types where the ADT requires drop if and only if any of those types + /// has significant drop. A type marked with the attribute `rustc_insignificant_dtor` + /// is considered to not be significant. A drop is significant if it is implemented + /// by the user or does anything that will have any observable behavior (other than + /// freeing up memory). If the ADT is known to have a significant destructor then + /// `Err(AlwaysRequiresDrop)` is returned. + query adt_significant_drop_tys(def_id: DefId) -> Result<&'tcx ty::List<Ty<'tcx>>, AlwaysRequiresDrop> { + desc { |tcx| "computing when `{}` has a significant destructor", tcx.def_path_str(def_id) } + } + + /// Returns a list of types which (a) have a potentially significant destructor + /// and (b) may be dropped as a result of dropping a value of some type `ty` + /// (in the given environment). + /// + /// The idea of "significant" drop is somewhat informal and is used only for + /// diagnostics and edition migrations. The idea is that a significant drop may have + /// some visible side-effect on execution; freeing memory is NOT considered a side-effect. + /// The rules are as follows: + /// * Type with no explicit drop impl do not have significant drop. + /// * Types with a drop impl are assumed to have significant drop unless they have a `#[rustc_insignificant_dtor]` annotation. + /// + /// Note that insignificant drop is a "shallow" property. A type like `Vec<LockGuard>` does not + /// have significant drop but the type `LockGuard` does, and so if `ty = Vec<LockGuard>` + /// then the return value would be `&[LockGuard]`. + /// *IMPORTANT*: *DO NOT* run this query before promoted MIR body is constructed, + /// because this query partially depends on that query. + /// Otherwise, there is a risk of query cycles. + query list_significant_drop_tys(ty: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) -> &'tcx ty::List<Ty<'tcx>> { + desc { |tcx| "computing when `{}` has a significant destructor", ty.value } + } + + /// Computes the layout of a type. Note that this implicitly + /// executes in `TypingMode::PostAnalysis`, and will normalize the input type. + query layout_of( + key: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>> + ) -> Result<ty::layout::TyAndLayout<'tcx>, &'tcx ty::layout::LayoutError<'tcx>> { + depth_limit + desc { "computing layout of `{}`", key.value } + // we emit our own error during query cycle handling + cycle_delay_bug + } + + /// Compute a `FnAbi` suitable for indirect calls, i.e. to `fn` pointers. + /// + /// NB: this doesn't handle virtual calls - those should use `fn_abi_of_instance` + /// instead, where the instance is an `InstanceKind::Virtual`. + query fn_abi_of_fn_ptr( + key: ty::PseudoCanonicalInput<'tcx, (ty::PolyFnSig<'tcx>, &'tcx ty::List<Ty<'tcx>>)> + ) -> Result<&'tcx rustc_target::callconv::FnAbi<'tcx, Ty<'tcx>>, &'tcx ty::layout::FnAbiError<'tcx>> { + desc { "computing call ABI of `{}` function pointers", key.value.0 } + } + + /// Compute a `FnAbi` suitable for declaring/defining an `fn` instance, and for + /// direct calls to an `fn`. + /// + /// NB: that includes virtual calls, which are represented by "direct calls" + /// to an `InstanceKind::Virtual` instance (of `<dyn Trait as Trait>::fn`). + query fn_abi_of_instance( + key: ty::PseudoCanonicalInput<'tcx, (ty::Instance<'tcx>, &'tcx ty::List<Ty<'tcx>>)> + ) -> Result<&'tcx rustc_target::callconv::FnAbi<'tcx, Ty<'tcx>>, &'tcx ty::layout::FnAbiError<'tcx>> { + desc { "computing call ABI of `{}`", key.value.0 } + } + + query dylib_dependency_formats(_: CrateNum) + -> &'tcx [(CrateNum, LinkagePreference)] { + desc { "getting dylib dependency formats of crate" } + separate_provide_extern + } + + query dependency_formats(_: ()) -> &'tcx Arc<crate::middle::dependency_format::Dependencies> { + arena_cache + desc { "getting the linkage format of all dependencies" } + } + + query is_compiler_builtins(_: CrateNum) -> bool { + cycle_fatal + desc { "checking if the crate is_compiler_builtins" } + separate_provide_extern + } + query has_global_allocator(_: CrateNum) -> bool { + // This query depends on untracked global state in CStore + eval_always + cycle_fatal + desc { "checking if the crate has_global_allocator" } + separate_provide_extern + } + query has_alloc_error_handler(_: CrateNum) -> bool { + // This query depends on untracked global state in CStore + eval_always + cycle_fatal + desc { "checking if the crate has_alloc_error_handler" } + separate_provide_extern + } + query has_panic_handler(_: CrateNum) -> bool { + cycle_fatal + desc { "checking if the crate has_panic_handler" } + separate_provide_extern + } + query is_profiler_runtime(_: CrateNum) -> bool { + cycle_fatal + desc { "checking if a crate is `#![profiler_runtime]`" } + separate_provide_extern + } + query has_ffi_unwind_calls(key: LocalDefId) -> bool { + desc { |tcx| "checking if `{}` contains FFI-unwind calls", tcx.def_path_str(key) } + cache_on_disk_if { true } + } + query required_panic_strategy(_: CrateNum) -> Option<PanicStrategy> { + cycle_fatal + desc { "getting a crate's required panic strategy" } + separate_provide_extern + } + query panic_in_drop_strategy(_: CrateNum) -> PanicStrategy { + cycle_fatal + desc { "getting a crate's configured panic-in-drop strategy" } + separate_provide_extern + } + query is_no_builtins(_: CrateNum) -> bool { + cycle_fatal + desc { "getting whether a crate has `#![no_builtins]`" } + separate_provide_extern + } + query symbol_mangling_version(_: CrateNum) -> SymbolManglingVersion { + cycle_fatal + desc { "getting a crate's symbol mangling version" } + separate_provide_extern + } + + query extern_crate(def_id: CrateNum) -> Option<&'tcx ExternCrate> { + eval_always + desc { "getting crate's ExternCrateData" } + separate_provide_extern + } + + query specialization_enabled_in(cnum: CrateNum) -> bool { + desc { "checking whether the crate enabled `specialization`/`min_specialization`" } + separate_provide_extern + } + + query specializes(_: (DefId, DefId)) -> bool { + desc { "computing whether impls specialize one another" } + } + query in_scope_traits_map(_: hir::OwnerId) + -> Option<&'tcx ItemLocalMap<Box<[TraitCandidate]>>> { + desc { "getting traits in scope at a block" } + } + + /// Returns whether the impl or associated function has the `default` keyword. + /// Note: This will ICE on inherent impl items. Consider using `AssocItem::defaultness`. + query defaultness(def_id: DefId) -> hir::Defaultness { + desc { |tcx| "looking up whether `{}` has `default`", tcx.def_path_str(def_id) } + separate_provide_extern + feedable + } + + /// Returns whether the field corresponding to the `DefId` has a default field value. + query default_field(def_id: DefId) -> Option<DefId> { + desc { |tcx| "looking up the `const` corresponding to the default for `{}`", tcx.def_path_str(def_id) } + separate_provide_extern + } + + query check_well_formed(key: LocalDefId) -> Result<(), ErrorGuaranteed> { + desc { |tcx| "checking that `{}` is well-formed", tcx.def_path_str(key) } + return_result_from_ensure_ok + } + + query enforce_impl_non_lifetime_params_are_constrained(key: LocalDefId) -> Result<(), ErrorGuaranteed> { + desc { |tcx| "checking that `{}`'s generics are constrained by the impl header", tcx.def_path_str(key) } + return_result_from_ensure_ok + } + + // The `DefId`s of all non-generic functions and statics in the given crate + // that can be reached from outside the crate. + // + // We expect this items to be available for being linked to. + // + // This query can also be called for `LOCAL_CRATE`. In this case it will + // compute which items will be reachable to other crates, taking into account + // the kind of crate that is currently compiled. Crates with only a + // C interface have fewer reachable things. + // + // Does not include external symbols that don't have a corresponding DefId, + // like the compiler-generated `main` function and so on. + query reachable_non_generics(_: CrateNum) + -> &'tcx DefIdMap<SymbolExportInfo> { + arena_cache + desc { "looking up the exported symbols of a crate" } + separate_provide_extern + } + query is_reachable_non_generic(def_id: DefId) -> bool { + desc { |tcx| "checking whether `{}` is an exported symbol", tcx.def_path_str(def_id) } + cache_on_disk_if { def_id.is_local() } + separate_provide_extern + } + query is_unreachable_local_definition(def_id: LocalDefId) -> bool { + desc { |tcx| + "checking whether `{}` is reachable from outside the crate", + tcx.def_path_str(def_id), + } + } + + /// The entire set of monomorphizations the local crate can safely + /// link to because they are exported from upstream crates. Do + /// not depend on this directly, as its value changes anytime + /// a monomorphization gets added or removed in any upstream + /// crate. Instead use the narrower `upstream_monomorphizations_for`, + /// `upstream_drop_glue_for`, `upstream_async_drop_glue_for`, or, + /// even better, `Instance::upstream_monomorphization()`. + query upstream_monomorphizations(_: ()) -> &'tcx DefIdMap<UnordMap<GenericArgsRef<'tcx>, CrateNum>> { + arena_cache + desc { "collecting available upstream monomorphizations" } + } + + /// Returns the set of upstream monomorphizations available for the + /// generic function identified by the given `def_id`. The query makes + /// sure to make a stable selection if the same monomorphization is + /// available in multiple upstream crates. + /// + /// You likely want to call `Instance::upstream_monomorphization()` + /// instead of invoking this query directly. + query upstream_monomorphizations_for(def_id: DefId) + -> Option<&'tcx UnordMap<GenericArgsRef<'tcx>, CrateNum>> + { + desc { |tcx| + "collecting available upstream monomorphizations for `{}`", + tcx.def_path_str(def_id), + } + separate_provide_extern + } + + /// Returns the upstream crate that exports drop-glue for the given + /// type (`args` is expected to be a single-item list containing the + /// type one wants drop-glue for). + /// + /// This is a subset of `upstream_monomorphizations_for` in order to + /// increase dep-tracking granularity. Otherwise adding or removing any + /// type with drop-glue in any upstream crate would invalidate all + /// functions calling drop-glue of an upstream type. + /// + /// You likely want to call `Instance::upstream_monomorphization()` + /// instead of invoking this query directly. + /// + /// NOTE: This query could easily be extended to also support other + /// common functions that have are large set of monomorphizations + /// (like `Clone::clone` for example). + query upstream_drop_glue_for(args: GenericArgsRef<'tcx>) -> Option<CrateNum> { + desc { "available upstream drop-glue for `{:?}`", args } + } + + /// Returns the upstream crate that exports async-drop-glue for + /// the given type (`args` is expected to be a single-item list + /// containing the type one wants async-drop-glue for). + /// + /// This is a subset of `upstream_monomorphizations_for` in order + /// to increase dep-tracking granularity. Otherwise adding or + /// removing any type with async-drop-glue in any upstream crate + /// would invalidate all functions calling async-drop-glue of an + /// upstream type. + /// + /// You likely want to call `Instance::upstream_monomorphization()` + /// instead of invoking this query directly. + /// + /// NOTE: This query could easily be extended to also support other + /// common functions that have are large set of monomorphizations + /// (like `Clone::clone` for example). + query upstream_async_drop_glue_for(args: GenericArgsRef<'tcx>) -> Option<CrateNum> { + desc { "available upstream async-drop-glue for `{:?}`", args } + } + + /// Returns a list of all `extern` blocks of a crate. + query foreign_modules(_: CrateNum) -> &'tcx FxIndexMap<DefId, ForeignModule> { + arena_cache + desc { "looking up the foreign modules of a linked crate" } + separate_provide_extern + } + + /// Lint against `extern fn` declarations having incompatible types. + query clashing_extern_declarations(_: ()) { + desc { "checking `extern fn` declarations are compatible" } + } + + /// Identifies the entry-point (e.g., the `main` function) for a given + /// crate, returning `None` if there is no entry point (such as for library crates). + query entry_fn(_: ()) -> Option<(DefId, EntryFnType)> { + desc { "looking up the entry function of a crate" } + } + + /// Finds the `rustc_proc_macro_decls` item of a crate. + query proc_macro_decls_static(_: ()) -> Option<LocalDefId> { + desc { "looking up the proc macro declarations for a crate" } + } + + // The macro which defines `rustc_metadata::provide_extern` depends on this query's name. + // Changing the name should cause a compiler error, but in case that changes, be aware. + // + // The hash should not be calculated before the `analysis` pass is complete, specifically + // until `tcx.untracked().definitions.freeze()` has been called, otherwise if incremental + // compilation is enabled calculating this hash can freeze this structure too early in + // compilation and cause subsequent crashes when attempting to write to `definitions` + query crate_hash(_: CrateNum) -> Svh { + eval_always + desc { "looking up the hash a crate" } + separate_provide_extern + } + + /// Gets the hash for the host proc macro. Used to support -Z dual-proc-macro. + query crate_host_hash(_: CrateNum) -> Option<Svh> { + eval_always + desc { "looking up the hash of a host version of a crate" } + separate_provide_extern + } + + /// Gets the extra data to put in each output filename for a crate. + /// For example, compiling the `foo` crate with `extra-filename=-a` creates a `libfoo-b.rlib` file. + query extra_filename(_: CrateNum) -> &'tcx String { + arena_cache + eval_always + desc { "looking up the extra filename for a crate" } + separate_provide_extern + } + + /// Gets the paths where the crate came from in the file system. + query crate_extern_paths(_: CrateNum) -> &'tcx Vec<PathBuf> { + arena_cache + eval_always + desc { "looking up the paths for extern crates" } + separate_provide_extern + } + + /// Given a crate and a trait, look up all impls of that trait in the crate. + /// Return `(impl_id, self_ty)`. + query implementations_of_trait(_: (CrateNum, DefId)) -> &'tcx [(DefId, Option<SimplifiedType>)] { + desc { "looking up implementations of a trait in a crate" } + separate_provide_extern + } + + /// Collects all incoherent impls for the given crate and type. + /// + /// Do not call this directly, but instead use the `incoherent_impls` query. + /// This query is only used to get the data necessary for that query. + query crate_incoherent_impls(key: (CrateNum, SimplifiedType)) -> &'tcx [DefId] { + desc { |tcx| "collecting all impls for a type in a crate" } + separate_provide_extern + } + + /// Get the corresponding native library from the `native_libraries` query + query native_library(def_id: DefId) -> Option<&'tcx NativeLib> { + desc { |tcx| "getting the native library for `{}`", tcx.def_path_str(def_id) } + } + + query inherit_sig_for_delegation_item(def_id: LocalDefId) -> &'tcx [Ty<'tcx>] { + desc { "inheriting delegation signature" } + } + + /// Does lifetime resolution on items. Importantly, we can't resolve + /// lifetimes directly on things like trait methods, because of trait params. + /// See `rustc_resolve::late::lifetimes` for details. + query resolve_bound_vars(owner_id: hir::OwnerId) -> &'tcx ResolveBoundVars<'tcx> { + arena_cache + desc { |tcx| "resolving lifetimes for `{}`", tcx.def_path_str(owner_id) } + } + query named_variable_map(owner_id: hir::OwnerId) -> &'tcx SortedMap<ItemLocalId, ResolvedArg> { + desc { |tcx| "looking up a named region inside `{}`", tcx.def_path_str(owner_id) } + } + query is_late_bound_map(owner_id: hir::OwnerId) -> Option<&'tcx FxIndexSet<ItemLocalId>> { + desc { |tcx| "testing if a region is late bound inside `{}`", tcx.def_path_str(owner_id) } + } + /// Returns the *default lifetime* to be used if a trait object type were to be passed for + /// the type parameter given by `DefId`. + /// + /// **Tip**: You can use `#[rustc_object_lifetime_default]` on an item to basically + /// print the result of this query for use in UI tests or for debugging purposes. + /// + /// # Examples + /// + /// - For `T` in `struct Foo<'a, T: 'a>(&'a T);`, this would be `Param('a)` + /// - For `T` in `struct Bar<'a, T>(&'a T);`, this would be `Empty` + /// + /// # Panics + /// + /// This query will panic if the given definition is not a type parameter. + query object_lifetime_default(def_id: DefId) -> ObjectLifetimeDefault { + desc { "looking up lifetime defaults for type parameter `{}`", tcx.def_path_str(def_id) } + separate_provide_extern + } + query late_bound_vars_map(owner_id: hir::OwnerId) + -> &'tcx SortedMap<ItemLocalId, Vec<ty::BoundVariableKind<'tcx>>> { + desc { |tcx| "looking up late bound vars inside `{}`", tcx.def_path_str(owner_id) } + } + /// For an opaque type, return the list of (captured lifetime, inner generic param). + /// ```ignore (illustrative) + /// fn foo<'a: 'a, 'b, T>(&'b u8) -> impl Into<Self> + 'b { ... } + /// ``` + /// + /// We would return `[('a, '_a), ('b, '_b)]`, with `'a` early-bound and `'b` late-bound. + /// + /// After hir_ty_lowering, we get: + /// ```ignore (pseudo-code) + /// opaque foo::<'a>::opaque<'_a, '_b>: Into<Foo<'_a>> + '_b; + /// ^^^^^^^^ inner generic params + /// fn foo<'a>: for<'b> fn(&'b u8) -> foo::<'a>::opaque::<'a, 'b> + /// ^^^^^^ captured lifetimes + /// ``` + query opaque_captured_lifetimes(def_id: LocalDefId) -> &'tcx [(ResolvedArg, LocalDefId)] { + desc { |tcx| "listing captured lifetimes for opaque `{}`", tcx.def_path_str(def_id) } + } + + /// Computes the visibility of the provided `def_id`. + /// + /// If the item from the `def_id` doesn't have a visibility, it will panic. For example + /// a generic type parameter will panic if you call this method on it: + /// + /// ``` + /// use std::fmt::Debug; + /// + /// pub trait Foo<T: Debug> {} + /// ``` + /// + /// In here, if you call `visibility` on `T`, it'll panic. + query visibility(def_id: DefId) -> ty::Visibility<DefId> { + desc { |tcx| "computing visibility of `{}`", tcx.def_path_str(def_id) } + separate_provide_extern + feedable + } + + query inhabited_predicate_adt(key: DefId) -> ty::inhabitedness::InhabitedPredicate<'tcx> { + desc { "computing the uninhabited predicate of `{:?}`", key } + } + + /// Do not call this query directly: invoke `Ty::inhabited_predicate` instead. + query inhabited_predicate_type(key: Ty<'tcx>) -> ty::inhabitedness::InhabitedPredicate<'tcx> { + desc { "computing the uninhabited predicate of `{}`", key } + } + + query dep_kind(_: CrateNum) -> CrateDepKind { + eval_always + desc { "fetching what a dependency looks like" } + separate_provide_extern + } + + /// Gets the name of the crate. + query crate_name(_: CrateNum) -> Symbol { + feedable + desc { "fetching what a crate is named" } + separate_provide_extern + } + query module_children(def_id: DefId) -> &'tcx [ModChild] { + desc { |tcx| "collecting child items of module `{}`", tcx.def_path_str(def_id) } + separate_provide_extern + } + + /// Gets the number of definitions in a foreign crate. + /// + /// This allows external tools to iterate over all definitions in a foreign crate. + /// + /// This should never be used for the local crate, instead use `iter_local_def_id`. + query num_extern_def_ids(_: CrateNum) -> usize { + desc { "fetching the number of definitions in a crate" } + separate_provide_extern + } + + query lib_features(_: CrateNum) -> &'tcx LibFeatures { + desc { "calculating the lib features defined in a crate" } + separate_provide_extern + arena_cache + } + /// Mapping from feature name to feature name based on the `implied_by` field of `#[unstable]` + /// attributes. If a `#[unstable(feature = "implier", implied_by = "impliee")]` attribute + /// exists, then this map will have a `impliee -> implier` entry. + /// + /// This mapping is necessary unless both the `#[stable]` and `#[unstable]` attributes should + /// specify their implications (both `implies` and `implied_by`). If only one of the two + /// attributes do (as in the current implementation, `implied_by` in `#[unstable]`), then this + /// mapping is necessary for diagnostics. When a "unnecessary feature attribute" error is + /// reported, only the `#[stable]` attribute information is available, so the map is necessary + /// to know that the feature implies another feature. If it were reversed, and the `#[stable]` + /// attribute had an `implies` meta item, then a map would be necessary when avoiding a "use of + /// unstable feature" error for a feature that was implied. + query stability_implications(_: CrateNum) -> &'tcx UnordMap<Symbol, Symbol> { + arena_cache + desc { "calculating the implications between `#[unstable]` features defined in a crate" } + separate_provide_extern + } + /// Whether the function is an intrinsic + query intrinsic_raw(def_id: DefId) -> Option<rustc_middle::ty::IntrinsicDef> { + desc { |tcx| "fetch intrinsic name if `{}` is an intrinsic", tcx.def_path_str(def_id) } + separate_provide_extern + } + /// Returns the lang items defined in another crate by loading it from metadata. + query get_lang_items(_: ()) -> &'tcx LanguageItems { + arena_cache + eval_always + desc { "calculating the lang items map" } + } + + /// Returns all diagnostic items defined in all crates. + query all_diagnostic_items(_: ()) -> &'tcx rustc_hir::diagnostic_items::DiagnosticItems { + arena_cache + eval_always + desc { "calculating the diagnostic items map" } + } + + /// Returns the lang items defined in another crate by loading it from metadata. + query defined_lang_items(_: CrateNum) -> &'tcx [(DefId, LangItem)] { + desc { "calculating the lang items defined in a crate" } + separate_provide_extern + } + + /// Returns the diagnostic items defined in a crate. + query diagnostic_items(_: CrateNum) -> &'tcx rustc_hir::diagnostic_items::DiagnosticItems { + arena_cache + desc { "calculating the diagnostic items map in a crate" } + separate_provide_extern + } + + query missing_lang_items(_: CrateNum) -> &'tcx [LangItem] { + desc { "calculating the missing lang items in a crate" } + separate_provide_extern + } + + /// The visible parent map is a map from every item to a visible parent. + /// It prefers the shortest visible path to an item. + /// Used for diagnostics, for example path trimming. + /// The parents are modules, enums or traits. + query visible_parent_map(_: ()) -> &'tcx DefIdMap<DefId> { + arena_cache + desc { "calculating the visible parent map" } + } + /// Collects the "trimmed", shortest accessible paths to all items for diagnostics. + /// See the [provider docs](`rustc_middle::ty::print::trimmed_def_paths`) for more info. + query trimmed_def_paths(_: ()) -> &'tcx DefIdMap<Symbol> { + arena_cache + desc { "calculating trimmed def paths" } + } + query missing_extern_crate_item(_: CrateNum) -> bool { + eval_always + desc { "seeing if we're missing an `extern crate` item for this crate" } + separate_provide_extern + } + query used_crate_source(_: CrateNum) -> &'tcx Arc<CrateSource> { + arena_cache + eval_always + desc { "looking at the source for a crate" } + separate_provide_extern + } + + /// Returns the debugger visualizers defined for this crate. + /// NOTE: This query has to be marked `eval_always` because it reads data + /// directly from disk that is not tracked anywhere else. I.e. it + /// represents a genuine input to the query system. + query debugger_visualizers(_: CrateNum) -> &'tcx Vec<DebuggerVisualizerFile> { + arena_cache + desc { "looking up the debugger visualizers for this crate" } + separate_provide_extern + eval_always + } + + query postorder_cnums(_: ()) -> &'tcx [CrateNum] { + eval_always + desc { "generating a postorder list of CrateNums" } + } + /// Returns whether or not the crate with CrateNum 'cnum' + /// is marked as a private dependency + query is_private_dep(c: CrateNum) -> bool { + eval_always + desc { "checking whether crate `{}` is a private dependency", c } + separate_provide_extern + } + query allocator_kind(_: ()) -> Option<AllocatorKind> { + eval_always + desc { "getting the allocator kind for the current crate" } + } + query alloc_error_handler_kind(_: ()) -> Option<AllocatorKind> { + eval_always + desc { "alloc error handler kind for the current crate" } + } + + query upvars_mentioned(def_id: DefId) -> Option<&'tcx FxIndexMap<hir::HirId, hir::Upvar>> { + desc { |tcx| "collecting upvars mentioned in `{}`", tcx.def_path_str(def_id) } + } + + /// All available crates in the graph, including those that should not be user-facing + /// (such as private crates). + query crates(_: ()) -> &'tcx [CrateNum] { + eval_always + desc { "fetching all foreign CrateNum instances" } + } + + // Crates that are loaded non-speculatively (not for diagnostics or doc links). + // FIXME: This is currently only used for collecting lang items, but should be used instead of + // `crates` in most other cases too. + query used_crates(_: ()) -> &'tcx [CrateNum] { + eval_always + desc { "fetching `CrateNum`s for all crates loaded non-speculatively" } + } + + /// All crates that share the same name as crate `c`. + /// + /// This normally occurs when multiple versions of the same dependency are present in the + /// dependency tree. + query duplicate_crate_names(c: CrateNum) -> &'tcx [CrateNum] { + desc { "fetching `CrateNum`s with same name as `{c:?}`" } + } + + /// A list of all traits in a crate, used by rustdoc and error reporting. + query traits(_: CrateNum) -> &'tcx [DefId] { + desc { "fetching all traits in a crate" } + separate_provide_extern + } + + query trait_impls_in_crate(_: CrateNum) -> &'tcx [DefId] { + desc { "fetching all trait impls in a crate" } + separate_provide_extern + } + + query stable_order_of_exportable_impls(_: CrateNum) -> &'tcx FxIndexMap<DefId, usize> { + desc { "fetching the stable impl's order" } + separate_provide_extern + } + + query exportable_items(_: CrateNum) -> &'tcx [DefId] { + desc { "fetching all exportable items in a crate" } + separate_provide_extern + } + + /// The list of non-generic symbols exported from the given crate. + /// + /// This is separate from exported_generic_symbols to avoid having + /// to deserialize all non-generic symbols too for upstream crates + /// in the upstream_monomorphizations query. + /// + /// - All names contained in `exported_non_generic_symbols(cnum)` are + /// guaranteed to correspond to a publicly visible symbol in `cnum` + /// machine code. + /// - The `exported_non_generic_symbols` and `exported_generic_symbols` + /// sets of different crates do not intersect. + query exported_non_generic_symbols(cnum: CrateNum) -> &'tcx [(ExportedSymbol<'tcx>, SymbolExportInfo)] { + desc { "collecting exported non-generic symbols for crate `{}`", cnum} + cache_on_disk_if { *cnum == LOCAL_CRATE } + separate_provide_extern + } + + /// The list of generic symbols exported from the given crate. + /// + /// - All names contained in `exported_generic_symbols(cnum)` are + /// guaranteed to correspond to a publicly visible symbol in `cnum` + /// machine code. + /// - The `exported_non_generic_symbols` and `exported_generic_symbols` + /// sets of different crates do not intersect. + query exported_generic_symbols(cnum: CrateNum) -> &'tcx [(ExportedSymbol<'tcx>, SymbolExportInfo)] { + desc { "collecting exported generic symbols for crate `{}`", cnum} + cache_on_disk_if { *cnum == LOCAL_CRATE } + separate_provide_extern + } + + query collect_and_partition_mono_items(_: ()) -> MonoItemPartitions<'tcx> { + eval_always + desc { "collect_and_partition_mono_items" } + } + + query is_codegened_item(def_id: DefId) -> bool { + desc { |tcx| "determining whether `{}` needs codegen", tcx.def_path_str(def_id) } + } + + query codegen_unit(sym: Symbol) -> &'tcx CodegenUnit<'tcx> { + desc { "getting codegen unit `{sym}`" } + } + + query backend_optimization_level(_: ()) -> OptLevel { + desc { "optimization level used by backend" } + } + + /// Return the filenames where output artefacts shall be stored. + /// + /// This query returns an `&Arc` because codegen backends need the value even after the `TyCtxt` + /// has been destroyed. + query output_filenames(_: ()) -> &'tcx Arc<OutputFilenames> { + feedable + desc { "getting output filenames" } + arena_cache + } + + /// <div class="warning"> + /// + /// Do not call this query directly: Invoke `normalize` instead. + /// + /// </div> + query normalize_canonicalized_projection( + goal: CanonicalAliasGoal<'tcx> + ) -> Result< + &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, NormalizationResult<'tcx>>>, + NoSolution, + > { + desc { "normalizing `{}`", goal.canonical.value.value } + } + + /// <div class="warning"> + /// + /// Do not call this query directly: Invoke `normalize` instead. + /// + /// </div> + query normalize_canonicalized_free_alias( + goal: CanonicalAliasGoal<'tcx> + ) -> Result< + &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, NormalizationResult<'tcx>>>, + NoSolution, + > { + desc { "normalizing `{}`", goal.canonical.value.value } + } + + /// <div class="warning"> + /// + /// Do not call this query directly: Invoke `normalize` instead. + /// + /// </div> + query normalize_canonicalized_inherent_projection( + goal: CanonicalAliasGoal<'tcx> + ) -> Result< + &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, NormalizationResult<'tcx>>>, + NoSolution, + > { + desc { "normalizing `{}`", goal.canonical.value.value } + } + + /// Do not call this query directly: invoke `try_normalize_erasing_regions` instead. + query try_normalize_generic_arg_after_erasing_regions( + goal: PseudoCanonicalInput<'tcx, GenericArg<'tcx>> + ) -> Result<GenericArg<'tcx>, NoSolution> { + desc { "normalizing `{}`", goal.value } + } + + query implied_outlives_bounds( + key: (CanonicalImpliedOutlivesBoundsGoal<'tcx>, bool) + ) -> Result< + &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, Vec<OutlivesBound<'tcx>>>>, + NoSolution, + > { + desc { "computing implied outlives bounds for `{}` (hack disabled = {:?})", key.0.canonical.value.value.ty, key.1 } + } + + /// Do not call this query directly: + /// invoke `DropckOutlives::new(dropped_ty)).fully_perform(typeck.infcx)` instead. + query dropck_outlives( + goal: CanonicalDropckOutlivesGoal<'tcx> + ) -> Result< + &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, DropckOutlivesResult<'tcx>>>, + NoSolution, + > { + desc { "computing dropck types for `{}`", goal.canonical.value.value.dropped_ty } + } + + /// Do not call this query directly: invoke `infcx.predicate_may_hold()` or + /// `infcx.predicate_must_hold()` instead. + query evaluate_obligation( + goal: CanonicalPredicateGoal<'tcx> + ) -> Result<EvaluationResult, OverflowError> { + desc { "evaluating trait selection obligation `{}`", goal.canonical.value.value } + } + + /// Do not call this query directly: part of the `Eq` type-op + query type_op_ascribe_user_type( + goal: CanonicalTypeOpAscribeUserTypeGoal<'tcx> + ) -> Result< + &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ()>>, + NoSolution, + > { + desc { "evaluating `type_op_ascribe_user_type` `{:?}`", goal.canonical.value.value } + } + + /// Do not call this query directly: part of the `ProvePredicate` type-op + query type_op_prove_predicate( + goal: CanonicalTypeOpProvePredicateGoal<'tcx> + ) -> Result< + &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ()>>, + NoSolution, + > { + desc { "evaluating `type_op_prove_predicate` `{:?}`", goal.canonical.value.value } + } + + /// Do not call this query directly: part of the `Normalize` type-op + query type_op_normalize_ty( + goal: CanonicalTypeOpNormalizeGoal<'tcx, Ty<'tcx>> + ) -> Result< + &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, Ty<'tcx>>>, + NoSolution, + > { + desc { "normalizing `{}`", goal.canonical.value.value.value } + } + + /// Do not call this query directly: part of the `Normalize` type-op + query type_op_normalize_clause( + goal: CanonicalTypeOpNormalizeGoal<'tcx, ty::Clause<'tcx>> + ) -> Result< + &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ty::Clause<'tcx>>>, + NoSolution, + > { + desc { "normalizing `{:?}`", goal.canonical.value.value.value } + } + + /// Do not call this query directly: part of the `Normalize` type-op + query type_op_normalize_poly_fn_sig( + goal: CanonicalTypeOpNormalizeGoal<'tcx, ty::PolyFnSig<'tcx>> + ) -> Result< + &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ty::PolyFnSig<'tcx>>>, + NoSolution, + > { + desc { "normalizing `{:?}`", goal.canonical.value.value.value } + } + + /// Do not call this query directly: part of the `Normalize` type-op + query type_op_normalize_fn_sig( + goal: CanonicalTypeOpNormalizeGoal<'tcx, ty::FnSig<'tcx>> + ) -> Result< + &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ty::FnSig<'tcx>>>, + NoSolution, + > { + desc { "normalizing `{:?}`", goal.canonical.value.value.value } + } + + query instantiate_and_check_impossible_predicates(key: (DefId, GenericArgsRef<'tcx>)) -> bool { + desc { |tcx| + "checking impossible instantiated predicates: `{}`", + tcx.def_path_str(key.0) + } + } + + query is_impossible_associated_item(key: (DefId, DefId)) -> bool { + desc { |tcx| + "checking if `{}` is impossible to reference within `{}`", + tcx.def_path_str(key.1), + tcx.def_path_str(key.0), + } + } + + query method_autoderef_steps( + goal: CanonicalMethodAutoderefStepsGoal<'tcx> + ) -> MethodAutoderefStepsResult<'tcx> { + desc { "computing autoderef types for `{}`", goal.canonical.value.value.self_ty } + } + + /// Used by `-Znext-solver` to compute proof trees. + query evaluate_root_goal_for_proof_tree_raw( + goal: solve::CanonicalInput<'tcx>, + ) -> (solve::QueryResult<'tcx>, &'tcx solve::inspect::Probe<TyCtxt<'tcx>>) { + no_hash + desc { "computing proof tree for `{}`", goal.canonical.value.goal.predicate } + } + + /// Returns the Rust target features for the current target. These are not always the same as LLVM target features! + query rust_target_features(_: CrateNum) -> &'tcx UnordMap<String, rustc_target::target_features::Stability> { + arena_cache + eval_always + desc { "looking up Rust target features" } + } + + query implied_target_features(feature: Symbol) -> &'tcx Vec<Symbol> { + arena_cache + eval_always + desc { "looking up implied target features" } + } + + query features_query(_: ()) -> &'tcx rustc_feature::Features { + feedable + desc { "looking up enabled feature gates" } + } + + query crate_for_resolver((): ()) -> &'tcx Steal<(rustc_ast::Crate, rustc_ast::AttrVec)> { + feedable + no_hash + desc { "the ast before macro expansion and name resolution" } + } + + /// Attempt to resolve the given `DefId` to an `Instance`, for the + /// given generics args (`GenericArgsRef`), returning one of: + /// * `Ok(Some(instance))` on success + /// * `Ok(None)` when the `GenericArgsRef` are still too generic, + /// and therefore don't allow finding the final `Instance` + /// * `Err(ErrorGuaranteed)` when the `Instance` resolution process + /// couldn't complete due to errors elsewhere - this is distinct + /// from `Ok(None)` to avoid misleading diagnostics when an error + /// has already been/will be emitted, for the original cause. + query resolve_instance_raw( + key: ty::PseudoCanonicalInput<'tcx, (DefId, GenericArgsRef<'tcx>)> + ) -> Result<Option<ty::Instance<'tcx>>, ErrorGuaranteed> { + desc { "resolving instance `{}`", ty::Instance::new_raw(key.value.0, key.value.1) } + } + + query reveal_opaque_types_in_bounds(key: ty::Clauses<'tcx>) -> ty::Clauses<'tcx> { + desc { "revealing opaque types in `{:?}`", key } + } + + query limits(key: ()) -> Limits { + desc { "looking up limits" } + } + + /// Performs an HIR-based well-formed check on the item with the given `HirId`. If + /// we get an `Unimplemented` error that matches the provided `Predicate`, return + /// the cause of the newly created obligation. + /// + /// This is only used by error-reporting code to get a better cause (in particular, a better + /// span) for an *existing* error. Therefore, it is best-effort, and may never handle + /// all of the cases that the normal `ty::Ty`-based wfcheck does. This is fine, + /// because the `ty::Ty`-based wfcheck is always run. + query diagnostic_hir_wf_check( + key: (ty::Predicate<'tcx>, WellFormedLoc) + ) -> Option<&'tcx ObligationCause<'tcx>> { + arena_cache + eval_always + no_hash + desc { "performing HIR wf-checking for predicate `{:?}` at item `{:?}`", key.0, key.1 } + } + + /// The list of backend features computed from CLI flags (`-Ctarget-cpu`, `-Ctarget-feature`, + /// `--target` and similar). + query global_backend_features(_: ()) -> &'tcx Vec<String> { + arena_cache + eval_always + desc { "computing the backend features for CLI flags" } + } + + query check_validity_requirement(key: (ValidityRequirement, ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>)) -> Result<bool, &'tcx ty::layout::LayoutError<'tcx>> { + desc { "checking validity requirement for `{}`: {}", key.1.value, key.0 } + } + + /// This takes the def-id of an associated item from a impl of a trait, + /// and checks its validity against the trait item it corresponds to. + /// + /// Any other def id will ICE. + query compare_impl_item(key: LocalDefId) -> Result<(), ErrorGuaranteed> { + desc { |tcx| "checking assoc item `{}` is compatible with trait definition", tcx.def_path_str(key) } + return_result_from_ensure_ok + } + + query deduced_param_attrs(def_id: DefId) -> &'tcx [DeducedParamAttrs] { + desc { |tcx| "deducing parameter attributes for {}", tcx.def_path_str(def_id) } + separate_provide_extern + } + + query doc_link_resolutions(def_id: DefId) -> &'tcx DocLinkResMap { + eval_always + desc { "resolutions for documentation links for a module" } + separate_provide_extern + } + + query doc_link_traits_in_scope(def_id: DefId) -> &'tcx [DefId] { + eval_always + desc { "traits in scope for documentation links for a module" } + separate_provide_extern + } + + /// Get all item paths that were stripped by a `#[cfg]` in a particular crate. + /// Should not be called for the local crate before the resolver outputs are created, as it + /// is only fed there. + query stripped_cfg_items(cnum: CrateNum) -> &'tcx [StrippedCfgItem] { + desc { "getting cfg-ed out item names" } + separate_provide_extern + } + + query generics_require_sized_self(def_id: DefId) -> bool { + desc { "check whether the item has a `where Self: Sized` bound" } + } + + query cross_crate_inlinable(def_id: DefId) -> bool { + desc { "whether the item should be made inlinable across crates" } + separate_provide_extern + } + + /// Perform monomorphization-time checking on this item. + /// This is used for lints/errors that can only be checked once the instance is fully + /// monomorphized. + query check_mono_item(key: ty::Instance<'tcx>) { + desc { "monomorphization-time checking" } + } + + /// Builds the set of functions that should be skipped for the move-size check. + query skip_move_check_fns(_: ()) -> &'tcx FxIndexSet<DefId> { + arena_cache + desc { "functions to skip for move-size check" } + } + + query items_of_instance(key: (ty::Instance<'tcx>, CollectionMode)) -> Result<(&'tcx [Spanned<MonoItem<'tcx>>], &'tcx [Spanned<MonoItem<'tcx>>]), NormalizationErrorInMono> { + desc { "collecting items used by `{}`", key.0 } + cache_on_disk_if { true } + } + + query size_estimate(key: ty::Instance<'tcx>) -> usize { + desc { "estimating codegen size of `{}`", key } + cache_on_disk_if { true } + } + + query anon_const_kind(def_id: DefId) -> ty::AnonConstKind { + desc { |tcx| "looking up anon const kind of `{}`", tcx.def_path_str(def_id) } + separate_provide_extern + } + + query trivial_const(def_id: DefId) -> Option<(mir::ConstValue, Ty<'tcx>)> { + desc { |tcx| "checking if `{}` is a trivial const", tcx.def_path_str(def_id) } + cache_on_disk_if { def_id.is_local() } + separate_provide_extern + } + + /// Checks for the nearest `#[sanitize(xyz = "off")]` or + /// `#[sanitize(xyz = "on")]` on this def and any enclosing defs, up to the + /// crate root. + /// + /// Returns the sanitizer settings for this def. + query sanitizer_settings_for(key: LocalDefId) -> SanitizerFnAttrs { + desc { |tcx| "checking what set of sanitizers are enabled on `{}`", tcx.def_path_str(key) } + feedable + } + + query check_externally_implementable_items(_: ()) { + desc { "check externally implementable items" } + } + + /// Returns a list of all `externally implementable items` crate. + query externally_implementable_items(cnum: CrateNum) -> &'tcx FxIndexMap<DefId, (EiiDecl, FxIndexMap<DefId, EiiImpl>)> { + arena_cache + desc { "looking up the externally implementable items of a crate" } + cache_on_disk_if { *cnum == LOCAL_CRATE } + separate_provide_extern + } +} + +rustc_with_all_queries! { define_callbacks! } +rustc_feedable_queries! { define_feedable! }
diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs index 3207159..99b1f6d 100644 --- a/compiler/rustc_middle/src/query/erase.rs +++ b/compiler/rustc_middle/src/query/erase.rs
@@ -15,7 +15,7 @@ use crate::mir::interpret::EvalToValTreeResult; use crate::mir::mono::{MonoItem, NormalizationErrorInMono}; -use crate::query::CyclePlaceholder; +use crate::query::plumbing::CyclePlaceholder; use crate::traits::solve; use crate::ty::adjustment::CoerceUnsizedInfo; use crate::ty::{self, Ty, TyCtxt};
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index c9291d8..24a38e7 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs
@@ -1,148 +1,12 @@ -//! -//! # The rustc Query System: Query Definitions and Modifiers -//! -//! The core processes in rustc are shipped as queries. Each query is a demand-driven function from some key to a value. -//! The execution result of the function is cached and directly read during the next request, thereby improving compilation efficiency. -//! Some results are saved locally and directly read during the next compilation, which are core of incremental compilation. -//! -//! ## How to Read This Module -//! -//! Each `query` block in this file defines a single query, specifying its key and value types, along with various modifiers. -//! These query definitions are processed by the [`rustc_macros`], which expands them into the necessary boilerplate code -//! for the query system—including the [`Providers`] struct (a function table for all query implementations, where each field is -//! a function pointer to the actual provider), caching, and dependency graph integration. -//! **Note:** The `Providers` struct is not a Rust trait, but a struct generated by the `rustc_macros` to hold all provider functions. -//! The `rustc_macros` also supports a set of **query modifiers** (see below) that control the behavior of each query. -//! -//! The actual provider functions are implemented in various modules and registered into the `Providers` struct -//! during compiler initialization (see [`rustc_interface::passes::DEFAULT_QUERY_PROVIDERS`]). -//! -//! [`rustc_macros`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_macros/index.html -//! [`rustc_interface::passes::DEFAULT_QUERY_PROVIDERS`]: ../../rustc_interface/passes/static.DEFAULT_QUERY_PROVIDERS.html -//! -//! ## Query Modifiers -//! -//! Query modifiers are special flags that alter the behavior of a query. They are parsed and processed by the `rustc_macros` -//! The main modifiers are: -//! -//! - `desc { ... }`: Sets the human-readable description for diagnostics and profiling. Required for every query. -//! - `arena_cache`: Use an arena for in-memory caching of the query result. -//! - `cache_on_disk_if { ... }`: Cache the query result to disk if the provided block evaluates to true. -//! - `cycle_fatal`: If a dependency cycle is detected, abort compilation with a fatal error. -//! - `cycle_delay_bug`: If a dependency cycle is detected, emit a delayed bug instead of aborting immediately. -//! - `cycle_stash`: If a dependency cycle is detected, stash the error for later handling. -//! - `no_hash`: Do not hash the query result for incremental compilation; just mark as dirty if recomputed. -//! - `anon`: Make the query anonymous in the dependency graph (no dep node is created). -//! - `eval_always`: Always evaluate the query, ignoring its dependencies and cached results. -//! - `depth_limit`: Impose a recursion depth limit on the query to prevent stack overflows. -//! - `separate_provide_extern`: Use separate provider functions for local and external crates. -//! - `feedable`: Allow the query result to be set from another query ("fed" externally). -//! - `return_result_from_ensure_ok`: When called via `tcx.ensure_ok()`, return `Result<(), ErrorGuaranteed>` instead of `()`. -//! If the query needs to be executed and returns an error, the error is returned to the caller. -//! Only valid for queries returning `Result<_, ErrorGuaranteed>`. -//! -//! For the up-to-date list, see the `QueryModifiers` struct in -//! [`rustc_macros/src/query.rs`](https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc_macros/src/query.rs) -//! and for more details in incremental compilation, see the -//! [Query modifiers in incremental compilation](https://rustc-dev-guide.rust-lang.org/queries/incremental-compilation-in-detail.html#query-modifiers) section of the rustc-dev-guide. -//! -//! ## Query Expansion and Code Generation -//! -//! The [`rustc_macros::rustc_queries`] macro expands each query definition into: -//! - A method on [`TyCtxt`] (and [`TyCtxtAt`]) for invoking the query. -//! - Provider traits and structs for supplying the query's value. -//! - Caching and dependency graph integration. -//! - Support for incremental compilation, disk caching, and arena allocation as controlled by the modifiers. -//! -//! [`rustc_macros::rustc_queries`]: ../../rustc_macros/macro.rustc_queries.html -//! -//! The macro-based approach allows the query system to be highly flexible and maintainable, while minimizing boilerplate. -//! -//! For more details, see the [rustc-dev-guide](https://rustc-dev-guide.rust-lang.org/query.html). - -#![allow(unused_parens)] - -use std::ffi::OsStr; -use std::mem; -use std::path::PathBuf; -use std::sync::Arc; - -use rustc_abi::Align; -use rustc_arena::TypedArena; -use rustc_ast::expand::allocator::AllocatorKind; -use rustc_ast::tokenstream::TokenStream; -use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; -use rustc_data_structures::sorted_map::SortedMap; -use rustc_data_structures::steal::Steal; -use rustc_data_structures::svh::Svh; -use rustc_data_structures::unord::{UnordMap, UnordSet}; -use rustc_errors::ErrorGuaranteed; -use rustc_hir::attrs::{EiiDecl, EiiImpl, StrippedCfgItem}; -use rustc_hir::def::{DefKind, DocLinkResMap}; -use rustc_hir::def_id::{ - CrateNum, DefId, DefIdMap, LocalDefId, LocalDefIdMap, LocalDefIdSet, LocalModDefId, -}; -use rustc_hir::lang_items::{LangItem, LanguageItems}; -use rustc_hir::{Crate, ItemLocalId, ItemLocalMap, PreciseCapturingArgKind, TraitCandidate}; -use rustc_index::IndexVec; -use rustc_lint_defs::LintId; -use rustc_macros::rustc_queries; -use rustc_query_system::query::{QueryMode, QueryState}; -use rustc_session::Limits; -use rustc_session::config::{EntryFnType, OptLevel, OutputFilenames, SymbolManglingVersion}; -use rustc_session::cstore::{ - CrateDepKind, CrateSource, ExternCrate, ForeignModule, LinkagePreference, NativeLib, -}; -use rustc_session::lint::LintExpectationId; -use rustc_span::def_id::LOCAL_CRATE; -use rustc_span::source_map::Spanned; -use rustc_span::{DUMMY_SP, LocalExpnId, Span, Symbol}; -use rustc_target::spec::PanicStrategy; -use {rustc_abi as abi, rustc_ast as ast, rustc_hir as hir}; +use rustc_hir::def_id::LocalDefId; +pub use rustc_query_system::query::{QueryMode, QueryState}; pub use self::keys::{AsLocalKey, Key, LocalCrate}; pub use self::plumbing::{IntoQueryParam, TyCtxtAt, TyCtxtEnsureDone, TyCtxtEnsureOk}; -use crate::infer::canonical::{self, Canonical}; -use crate::lint::LintExpectation; -use crate::metadata::ModChild; -use crate::middle::codegen_fn_attrs::{CodegenFnAttrs, SanitizerFnAttrs}; -use crate::middle::debugger_visualizer::DebuggerVisualizerFile; -use crate::middle::deduced_param_attrs::DeducedParamAttrs; -use crate::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo}; -use crate::middle::lib_features::LibFeatures; -use crate::middle::privacy::EffectiveVisibilities; -use crate::middle::resolve_bound_vars::{ObjectLifetimeDefault, ResolveBoundVars, ResolvedArg}; -use crate::middle::stability::DeprecationEntry; -use crate::mir::interpret::{ - EvalStaticInitializerRawResult, EvalToAllocationRawResult, EvalToConstValueResult, - EvalToValTreeResult, GlobalId, LitToConstInput, -}; -use crate::mir::mono::{ - CodegenUnit, CollectionMode, MonoItem, MonoItemPartitions, NormalizationErrorInMono, -}; -use crate::query::plumbing::CyclePlaceholder; -use crate::traits::query::{ - CanonicalAliasGoal, CanonicalDropckOutlivesGoal, CanonicalImpliedOutlivesBoundsGoal, - CanonicalMethodAutoderefStepsGoal, CanonicalPredicateGoal, CanonicalTypeOpAscribeUserTypeGoal, - CanonicalTypeOpNormalizeGoal, CanonicalTypeOpProvePredicateGoal, DropckConstraint, - DropckOutlivesResult, MethodAutoderefStepsResult, NoSolution, NormalizationResult, - OutlivesBound, -}; -use crate::traits::{ - CodegenObligationError, DynCompatibilityViolation, EvaluationResult, ImplSource, - ObligationCause, OverflowError, WellFormedLoc, solve, specialization_graph, -}; -use crate::ty::fast_reject::SimplifiedType; -use crate::ty::layout::ValidityRequirement; -use crate::ty::print::PrintTraitRefExt; -use crate::ty::util::AlwaysRequiresDrop; -use crate::ty::{ - self, CrateInherentImpls, GenericArg, GenericArgsRef, PseudoCanonicalInput, SizedTraitKind, Ty, - TyCtxt, TyCtxtFeed, -}; -use crate::{dep_graph, mir, thir}; +pub use crate::queries::Providers; +use crate::ty::TyCtxt; -mod arena_cached; +pub(crate) mod arena_cached; pub mod erase; pub(crate) mod inner; mod keys; @@ -150,2641 +14,7 @@ #[macro_use] pub mod plumbing; -// Each of these queries corresponds to a function pointer field in the -// `Providers` struct for requesting a value of that type, and a method -// on `tcx: TyCtxt` (and `tcx.at(span)`) for doing that request in a way -// which memoizes and does dep-graph tracking, wrapping around the actual -// `Providers` that the driver creates (using several `rustc_*` crates). -// -// The result type of each query must implement `Clone`, and additionally -// `ty::query::values::Value`, which produces an appropriate placeholder -// (error) value if the query resulted in a query cycle. -// Queries marked with `cycle_fatal` do not need the latter implementation, -// as they will raise an fatal error on query cycles instead. -rustc_queries! { - /// Caches the expansion of a derive proc macro, e.g. `#[derive(Serialize)]`. - /// The key is: - /// - A unique key corresponding to the invocation of a macro. - /// - Token stream which serves as an input to the macro. - /// - /// The output is the token stream generated by the proc macro. - query derive_macro_expansion(key: (LocalExpnId, &'tcx TokenStream)) -> Result<&'tcx TokenStream, ()> { - desc { "expanding a derive (proc) macro" } - cache_on_disk_if { true } - } - - /// This exists purely for testing the interactions between delayed bugs and incremental. - query trigger_delayed_bug(key: DefId) { - desc { "triggering a delayed bug for testing incremental" } - } - - /// Collects the list of all tools registered using `#![register_tool]`. - query registered_tools(_: ()) -> &'tcx ty::RegisteredTools { - arena_cache - desc { "compute registered tools for crate" } - } - - query early_lint_checks(_: ()) { - desc { "perform lints prior to AST lowering" } - } - - /// Tracked access to environment variables. - /// - /// Useful for the implementation of `std::env!`, `proc-macro`s change - /// detection and other changes in the compiler's behaviour that is easier - /// to control with an environment variable than a flag. - /// - /// NOTE: This currently does not work with dependency info in the - /// analysis, codegen and linking passes, place extra code at the top of - /// `rustc_interface::passes::write_dep_info` to make that work. - query env_var_os(key: &'tcx OsStr) -> Option<&'tcx OsStr> { - // Environment variables are global state - eval_always - desc { "get the value of an environment variable" } - } - - query resolutions(_: ()) -> &'tcx ty::ResolverGlobalCtxt { - desc { "getting the resolver outputs" } - } - - query resolver_for_lowering_raw(_: ()) -> (&'tcx Steal<(ty::ResolverAstLowering, Arc<ast::Crate>)>, &'tcx ty::ResolverGlobalCtxt) { - eval_always - no_hash - desc { "getting the resolver for lowering" } - } - - /// Return the span for a definition. - /// - /// Contrary to `def_span` below, this query returns the full absolute span of the definition. - /// This span is meant for dep-tracking rather than diagnostics. It should not be used outside - /// of rustc_middle::hir::source_map. - query source_span(key: LocalDefId) -> Span { - // Accesses untracked data - eval_always - desc { "getting the source span" } - } - - /// Represents crate as a whole (as distinct from the top-level crate module). - /// - /// If you call `tcx.hir_crate(())` we will have to assume that any change - /// means that you need to be recompiled. This is because the `hir_crate` - /// query gives you access to all other items. To avoid this fate, do not - /// call `tcx.hir_crate(())`; instead, prefer wrappers like - /// [`TyCtxt::hir_visit_all_item_likes_in_crate`]. - query hir_crate(key: ()) -> &'tcx Crate<'tcx> { - arena_cache - eval_always - desc { "getting the crate HIR" } - } - - /// All items in the crate. - query hir_crate_items(_: ()) -> &'tcx rustc_middle::hir::ModuleItems { - arena_cache - eval_always - desc { "getting HIR crate items" } - } - - /// The items in a module. - /// - /// This can be conveniently accessed by `tcx.hir_visit_item_likes_in_module`. - /// Avoid calling this query directly. - query hir_module_items(key: LocalModDefId) -> &'tcx rustc_middle::hir::ModuleItems { - arena_cache - desc { |tcx| "getting HIR module items in `{}`", tcx.def_path_str(key) } - cache_on_disk_if { true } - } - - /// Returns HIR ID for the given `LocalDefId`. - query local_def_id_to_hir_id(key: LocalDefId) -> hir::HirId { - desc { |tcx| "getting HIR ID of `{}`", tcx.def_path_str(key) } - feedable - } - - /// Gives access to the HIR node's parent for the HIR owner `key`. - /// - /// This can be conveniently accessed by `tcx.hir_*` methods. - /// Avoid calling this query directly. - query hir_owner_parent_q(key: hir::OwnerId) -> hir::HirId { - desc { |tcx| "getting HIR parent of `{}`", tcx.def_path_str(key) } - } - - /// Gives access to the HIR nodes and bodies inside `key` if it's a HIR owner. - /// - /// This can be conveniently accessed by `tcx.hir_*` methods. - /// Avoid calling this query directly. - query opt_hir_owner_nodes(key: LocalDefId) -> Option<&'tcx hir::OwnerNodes<'tcx>> { - desc { |tcx| "getting HIR owner items in `{}`", tcx.def_path_str(key) } - feedable - } - - /// Gives access to the HIR attributes inside the HIR owner `key`. - /// - /// This can be conveniently accessed by `tcx.hir_*` methods. - /// Avoid calling this query directly. - query hir_attr_map(key: hir::OwnerId) -> &'tcx hir::AttributeMap<'tcx> { - desc { |tcx| "getting HIR owner attributes in `{}`", tcx.def_path_str(key) } - feedable - } - - /// Gives access to lints emitted during ast lowering. - /// - /// This can be conveniently accessed by `tcx.hir_*` methods. - /// Avoid calling this query directly. - query opt_ast_lowering_delayed_lints(key: hir::OwnerId) -> Option<&'tcx hir::lints::DelayedLints> { - desc { |tcx| "getting AST lowering delayed lints in `{}`", tcx.def_path_str(key) } - } - - /// Returns the *default* of the const pararameter given by `DefId`. - /// - /// E.g., given `struct Ty<const N: usize = 3>;` this returns `3` for `N`. - query const_param_default(param: DefId) -> ty::EarlyBinder<'tcx, ty::Const<'tcx>> { - desc { |tcx| "computing the default for const parameter `{}`", tcx.def_path_str(param) } - cache_on_disk_if { param.is_local() } - separate_provide_extern - } - - /// Returns the const of the RHS of a (free or assoc) const item, if it is a `#[type_const]`. - /// - /// When a const item is used in a type-level expression, like in equality for an assoc const - /// projection, this allows us to retrieve the typesystem-appropriate representation of the - /// const value. - /// - /// This query will ICE if given a const that is not marked with `#[type_const]`. - query const_of_item(def_id: DefId) -> ty::EarlyBinder<'tcx, ty::Const<'tcx>> { - desc { |tcx| "computing the type-level value for `{}`", tcx.def_path_str(def_id) } - cache_on_disk_if { def_id.is_local() } - separate_provide_extern - } - - /// Returns the *type* of the definition given by `DefId`. - /// - /// For type aliases (whether eager or lazy) and associated types, this returns - /// the underlying aliased type (not the corresponding [alias type]). - /// - /// For opaque types, this returns and thus reveals the hidden type! If you - /// want to detect cycle errors use `type_of_opaque` instead. - /// - /// To clarify, for type definitions, this does *not* return the "type of a type" - /// (aka *kind* or *sort*) in the type-theoretical sense! It merely returns - /// the type primarily *associated with* it. - /// - /// # Panics - /// - /// This query will panic if the given definition doesn't (and can't - /// conceptually) have an (underlying) type. - /// - /// [alias type]: rustc_middle::ty::AliasTy - query type_of(key: DefId) -> ty::EarlyBinder<'tcx, Ty<'tcx>> { - desc { |tcx| - "{action} `{path}`", - action = match tcx.def_kind(key) { - DefKind::TyAlias => "expanding type alias", - DefKind::TraitAlias => "expanding trait alias", - _ => "computing type of", - }, - path = tcx.def_path_str(key), - } - cache_on_disk_if { key.is_local() } - separate_provide_extern - feedable - } - - /// Returns the *hidden type* of the opaque type given by `DefId` unless a cycle occurred. - /// - /// This is a specialized instance of [`Self::type_of`] that detects query cycles. - /// Unless `CyclePlaceholder` needs to be handled separately, call [`Self::type_of`] instead. - /// This is used to improve the error message in cases where revealing the hidden type - /// for auto-trait leakage cycles. - /// - /// # Panics - /// - /// This query will panic if the given definition is not an opaque type. - query type_of_opaque(key: DefId) -> Result<ty::EarlyBinder<'tcx, Ty<'tcx>>, CyclePlaceholder> { - desc { |tcx| - "computing type of opaque `{path}`", - path = tcx.def_path_str(key), - } - cycle_stash - } - query type_of_opaque_hir_typeck(key: LocalDefId) -> ty::EarlyBinder<'tcx, Ty<'tcx>> { - desc { |tcx| - "computing type of opaque `{path}` via HIR typeck", - path = tcx.def_path_str(key), - } - } - - /// Returns whether the type alias given by `DefId` is lazy. - /// - /// I.e., if the type alias expands / ought to expand to a [free] [alias type] - /// instead of the underlying aliased type. - /// - /// Relevant for features `lazy_type_alias` and `type_alias_impl_trait`. - /// - /// # Panics - /// - /// This query *may* panic if the given definition is not a type alias. - /// - /// [free]: rustc_middle::ty::Free - /// [alias type]: rustc_middle::ty::AliasTy - query type_alias_is_lazy(key: DefId) -> bool { - desc { |tcx| - "computing whether the type alias `{path}` is lazy", - path = tcx.def_path_str(key), - } - separate_provide_extern - } - - query collect_return_position_impl_trait_in_trait_tys(key: DefId) - -> Result<&'tcx DefIdMap<ty::EarlyBinder<'tcx, Ty<'tcx>>>, ErrorGuaranteed> - { - desc { "comparing an impl and trait method signature, inferring any hidden `impl Trait` types in the process" } - cache_on_disk_if { key.is_local() } - separate_provide_extern - } - - query opaque_ty_origin(key: DefId) -> hir::OpaqueTyOrigin<DefId> - { - desc { "determine where the opaque originates from" } - separate_provide_extern - } - - query unsizing_params_for_adt(key: DefId) -> &'tcx rustc_index::bit_set::DenseBitSet<u32> - { - arena_cache - desc { |tcx| - "determining what parameters of `{}` can participate in unsizing", - tcx.def_path_str(key), - } - } - - /// The root query triggering all analysis passes like typeck or borrowck. - query analysis(key: ()) { - eval_always - desc { |tcx| - "running analysis passes on crate `{}`", - tcx.crate_name(LOCAL_CRATE), - } - } - - /// This query checks the fulfillment of collected lint expectations. - /// All lint emitting queries have to be done before this is executed - /// to ensure that all expectations can be fulfilled. - /// - /// This is an extra query to enable other drivers (like rustdoc) to - /// only execute a small subset of the `analysis` query, while allowing - /// lints to be expected. In rustc, this query will be executed as part of - /// the `analysis` query and doesn't have to be called a second time. - /// - /// Tools can additionally pass in a tool filter. That will restrict the - /// expectations to only trigger for lints starting with the listed tool - /// name. This is useful for cases were not all linting code from rustc - /// was called. With the default `None` all registered lints will also - /// be checked for expectation fulfillment. - query check_expectations(key: Option<Symbol>) { - eval_always - desc { "checking lint expectations (RFC 2383)" } - } - - /// Returns the *generics* of the definition given by `DefId`. - query generics_of(key: DefId) -> &'tcx ty::Generics { - desc { |tcx| "computing generics of `{}`", tcx.def_path_str(key) } - arena_cache - cache_on_disk_if { key.is_local() } - separate_provide_extern - feedable - } - - /// Returns the (elaborated) *predicates* of the definition given by `DefId` - /// that must be proven true at usage sites (and which can be assumed at definition site). - /// - /// This is almost always *the* "predicates query" that you want. - /// - /// **Tip**: You can use `#[rustc_dump_predicates]` on an item to basically print - /// the result of this query for use in UI tests or for debugging purposes. - query predicates_of(key: DefId) -> ty::GenericPredicates<'tcx> { - desc { |tcx| "computing predicates of `{}`", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } - } - - query opaque_types_defined_by( - key: LocalDefId - ) -> &'tcx ty::List<LocalDefId> { - desc { - |tcx| "computing the opaque types defined by `{}`", - tcx.def_path_str(key.to_def_id()) - } - } - - /// A list of all bodies inside of `key`, nested bodies are always stored - /// before their parent. - query nested_bodies_within( - key: LocalDefId - ) -> &'tcx ty::List<LocalDefId> { - desc { - |tcx| "computing the coroutines defined within `{}`", - tcx.def_path_str(key.to_def_id()) - } - } - - /// Returns the explicitly user-written *bounds* on the associated or opaque type given by `DefId` - /// that must be proven true at definition site (and which can be assumed at usage sites). - /// - /// For associated types, these must be satisfied for an implementation - /// to be well-formed, and for opaque types, these are required to be - /// satisfied by the hidden type of the opaque. - /// - /// Bounds from the parent (e.g. with nested `impl Trait`) are not included. - /// - /// Syntactially, these are the bounds written on associated types in trait - /// definitions, or those after the `impl` keyword for an opaque: - /// - /// ```ignore (illustrative) - /// trait Trait { type X: Bound + 'lt; } - /// // ^^^^^^^^^^^ - /// fn function() -> impl Debug + Display { /*...*/ } - /// // ^^^^^^^^^^^^^^^ - /// ``` - query explicit_item_bounds(key: DefId) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> { - desc { |tcx| "finding item bounds for `{}`", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } - separate_provide_extern - feedable - } - - /// Returns the explicitly user-written *bounds* that share the `Self` type of the item. - /// - /// These are a subset of the [explicit item bounds] that may explicitly be used for things - /// like closure signature deduction. - /// - /// [explicit item bounds]: Self::explicit_item_bounds - query explicit_item_self_bounds(key: DefId) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> { - desc { |tcx| "finding item bounds for `{}`", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } - separate_provide_extern - feedable - } - - /// Returns the (elaborated) *bounds* on the associated or opaque type given by `DefId` - /// that must be proven true at definition site (and which can be assumed at usage sites). - /// - /// Bounds from the parent (e.g. with nested `impl Trait`) are not included. - /// - /// **Tip**: You can use `#[rustc_dump_item_bounds]` on an item to basically print - /// the result of this query for use in UI tests or for debugging purposes. - /// - /// # Examples - /// - /// ``` - /// trait Trait { type Assoc: Eq + ?Sized; } - /// ``` - /// - /// While [`Self::explicit_item_bounds`] returns `[<Self as Trait>::Assoc: Eq]` - /// here, `item_bounds` returns: - /// - /// ```text - /// [ - /// <Self as Trait>::Assoc: Eq, - /// <Self as Trait>::Assoc: PartialEq<<Self as Trait>::Assoc> - /// ] - /// ``` - query item_bounds(key: DefId) -> ty::EarlyBinder<'tcx, ty::Clauses<'tcx>> { - desc { |tcx| "elaborating item bounds for `{}`", tcx.def_path_str(key) } - } - - query item_self_bounds(key: DefId) -> ty::EarlyBinder<'tcx, ty::Clauses<'tcx>> { - desc { |tcx| "elaborating item assumptions for `{}`", tcx.def_path_str(key) } - } - - query item_non_self_bounds(key: DefId) -> ty::EarlyBinder<'tcx, ty::Clauses<'tcx>> { - desc { |tcx| "elaborating item assumptions for `{}`", tcx.def_path_str(key) } - } - - query impl_super_outlives(key: DefId) -> ty::EarlyBinder<'tcx, ty::Clauses<'tcx>> { - desc { |tcx| "elaborating supertrait outlives for trait of `{}`", tcx.def_path_str(key) } - } - - /// Look up all native libraries this crate depends on. - /// These are assembled from the following places: - /// - `extern` blocks (depending on their `link` attributes) - /// - the `libs` (`-l`) option - query native_libraries(_: CrateNum) -> &'tcx Vec<NativeLib> { - arena_cache - desc { "looking up the native libraries of a linked crate" } - separate_provide_extern - } - - query shallow_lint_levels_on(key: hir::OwnerId) -> &'tcx rustc_middle::lint::ShallowLintLevelMap { - arena_cache - desc { |tcx| "looking up lint levels for `{}`", tcx.def_path_str(key) } - } - - query lint_expectations(_: ()) -> &'tcx Vec<(LintExpectationId, LintExpectation)> { - arena_cache - desc { "computing `#[expect]`ed lints in this crate" } - } - - query lints_that_dont_need_to_run(_: ()) -> &'tcx UnordSet<LintId> { - arena_cache - desc { "Computing all lints that are explicitly enabled or with a default level greater than Allow" } - } - - query expn_that_defined(key: DefId) -> rustc_span::ExpnId { - desc { |tcx| "getting the expansion that defined `{}`", tcx.def_path_str(key) } - separate_provide_extern - } - - query is_panic_runtime(_: CrateNum) -> bool { - cycle_fatal - desc { "checking if the crate is_panic_runtime" } - separate_provide_extern - } - - /// Checks whether a type is representable or infinitely sized - query representability(_: LocalDefId) -> rustc_middle::ty::Representability { - desc { "checking if `{}` is representable", tcx.def_path_str(key) } - // infinitely sized types will cause a cycle - cycle_delay_bug - // we don't want recursive representability calls to be forced with - // incremental compilation because, if a cycle occurs, we need the - // entire cycle to be in memory for diagnostics - anon - } - - /// An implementation detail for the `representability` query - query representability_adt_ty(_: Ty<'tcx>) -> rustc_middle::ty::Representability { - desc { "checking if `{}` is representable", key } - cycle_delay_bug - anon - } - - /// Set of param indexes for type params that are in the type's representation - query params_in_repr(key: DefId) -> &'tcx rustc_index::bit_set::DenseBitSet<u32> { - desc { "finding type parameters in the representation" } - arena_cache - no_hash - separate_provide_extern - } - - /// Fetch the THIR for a given body. The THIR body gets stolen by unsafety checking unless - /// `-Zno-steal-thir` is on. - query thir_body(key: LocalDefId) -> Result<(&'tcx Steal<thir::Thir<'tcx>>, thir::ExprId), ErrorGuaranteed> { - // Perf tests revealed that hashing THIR is inefficient (see #85729). - no_hash - desc { |tcx| "building THIR for `{}`", tcx.def_path_str(key) } - } - - /// Set of all the `DefId`s in this crate that have MIR associated with - /// them. This includes all the body owners, but also things like struct - /// constructors. - query mir_keys(_: ()) -> &'tcx rustc_data_structures::fx::FxIndexSet<LocalDefId> { - arena_cache - desc { "getting a list of all mir_keys" } - } - - /// Maps DefId's that have an associated `mir::Body` to the result - /// of the MIR const-checking pass. This is the set of qualifs in - /// the final value of a `const`. - query mir_const_qualif(key: DefId) -> mir::ConstQualifs { - desc { |tcx| "const checking `{}`", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } - separate_provide_extern - } - - /// Build the MIR for a given `DefId` and prepare it for const qualification. - /// - /// See the [rustc dev guide] for more info. - /// - /// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/mir/construction.html - query mir_built(key: LocalDefId) -> &'tcx Steal<mir::Body<'tcx>> { - desc { |tcx| "building MIR for `{}`", tcx.def_path_str(key) } - feedable - } - - /// Try to build an abstract representation of the given constant. - query thir_abstract_const( - key: DefId - ) -> Result<Option<ty::EarlyBinder<'tcx, ty::Const<'tcx>>>, ErrorGuaranteed> { - desc { - |tcx| "building an abstract representation for `{}`", tcx.def_path_str(key), - } - separate_provide_extern - } - - query mir_drops_elaborated_and_const_checked(key: LocalDefId) -> &'tcx Steal<mir::Body<'tcx>> { - no_hash - desc { |tcx| "elaborating drops for `{}`", tcx.def_path_str(key) } - } - - query mir_for_ctfe( - key: DefId - ) -> &'tcx mir::Body<'tcx> { - desc { |tcx| "caching mir of `{}` for CTFE", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } - separate_provide_extern - } - - query mir_promoted(key: LocalDefId) -> ( - &'tcx Steal<mir::Body<'tcx>>, - &'tcx Steal<IndexVec<mir::Promoted, mir::Body<'tcx>>> - ) { - no_hash - desc { |tcx| "promoting constants in MIR for `{}`", tcx.def_path_str(key) } - } - - query closure_typeinfo(key: LocalDefId) -> ty::ClosureTypeInfo<'tcx> { - desc { - |tcx| "finding symbols for captures of closure `{}`", - tcx.def_path_str(key) - } - } - - /// Returns names of captured upvars for closures and coroutines. - /// - /// Here are some examples: - /// - `name__field1__field2` when the upvar is captured by value. - /// - `_ref__name__field` when the upvar is captured by reference. - /// - /// For coroutines this only contains upvars that are shared by all states. - query closure_saved_names_of_captured_variables(def_id: DefId) -> &'tcx IndexVec<abi::FieldIdx, Symbol> { - arena_cache - desc { |tcx| "computing debuginfo for closure `{}`", tcx.def_path_str(def_id) } - separate_provide_extern - } - - query mir_coroutine_witnesses(key: DefId) -> Option<&'tcx mir::CoroutineLayout<'tcx>> { - arena_cache - desc { |tcx| "coroutine witness types for `{}`", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } - separate_provide_extern - } - - query check_coroutine_obligations(key: LocalDefId) -> Result<(), ErrorGuaranteed> { - desc { |tcx| "verify auto trait bounds for coroutine interior type `{}`", tcx.def_path_str(key) } - return_result_from_ensure_ok - } - - /// Used in case `mir_borrowck` fails to prove an obligation. We generally assume that - /// all goals we prove in MIR type check hold as we've already checked them in HIR typeck. - /// - /// However, we replace each free region in the MIR body with a unique region inference - /// variable. As we may rely on structural identity when proving goals this may cause a - /// goal to no longer hold. We store obligations for which this may happen during HIR - /// typeck in the `TypeckResults`. We then uniquify and reprove them in case MIR typeck - /// encounters an unexpected error. We expect this to result in an error when used and - /// delay a bug if it does not. - query check_potentially_region_dependent_goals(key: LocalDefId) -> Result<(), ErrorGuaranteed> { - desc { - |tcx| "reproving potentially region dependent HIR typeck goals for `{}", - tcx.def_path_str(key) - } - } - - /// MIR after our optimization passes have run. This is MIR that is ready - /// for codegen. This is also the only query that can fetch non-local MIR, at present. - query optimized_mir(key: DefId) -> &'tcx mir::Body<'tcx> { - desc { |tcx| "optimizing MIR for `{}`", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } - separate_provide_extern - } - - /// Checks for the nearest `#[coverage(off)]` or `#[coverage(on)]` on - /// this def and any enclosing defs, up to the crate root. - /// - /// Returns `false` if `#[coverage(off)]` was found, or `true` if - /// either `#[coverage(on)]` or no coverage attribute was found. - query coverage_attr_on(key: LocalDefId) -> bool { - desc { |tcx| "checking for `#[coverage(..)]` on `{}`", tcx.def_path_str(key) } - feedable - } - - /// Scans through a function's MIR after MIR optimizations, to prepare the - /// information needed by codegen when `-Cinstrument-coverage` is active. - /// - /// This includes the details of where to insert `llvm.instrprof.increment` - /// intrinsics, and the expression tables to be embedded in the function's - /// coverage metadata. - /// - /// FIXME(Zalathar): This query's purpose has drifted a bit and should - /// probably be renamed, but that can wait until after the potential - /// follow-ups to #136053 have settled down. - /// - /// Returns `None` for functions that were not instrumented. - query coverage_ids_info(key: ty::InstanceKind<'tcx>) -> Option<&'tcx mir::coverage::CoverageIdsInfo> { - desc { |tcx| "retrieving coverage IDs info from MIR for `{}`", tcx.def_path_str(key.def_id()) } - arena_cache - } - - /// The `DefId` is the `DefId` of the containing MIR body. Promoteds do not have their own - /// `DefId`. This function returns all promoteds in the specified body. The body references - /// promoteds by the `DefId` and the `mir::Promoted` index. This is necessary, because - /// after inlining a body may refer to promoteds from other bodies. In that case you still - /// need to use the `DefId` of the original body. - query promoted_mir(key: DefId) -> &'tcx IndexVec<mir::Promoted, mir::Body<'tcx>> { - desc { |tcx| "optimizing promoted MIR for `{}`", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } - separate_provide_extern - } - - /// Erases regions from `ty` to yield a new type. - /// Normally you would just use `tcx.erase_and_anonymize_regions(value)`, - /// however, which uses this query as a kind of cache. - query erase_and_anonymize_regions_ty(ty: Ty<'tcx>) -> Ty<'tcx> { - // This query is not expected to have input -- as a result, it - // is not a good candidates for "replay" because it is essentially a - // pure function of its input (and hence the expectation is that - // no caller would be green **apart** from just these - // queries). Making it anonymous avoids hashing the result, which - // may save a bit of time. - anon - desc { "erasing regions from `{}`", ty } - } - - query wasm_import_module_map(_: CrateNum) -> &'tcx DefIdMap<String> { - arena_cache - desc { "getting wasm import module map" } - } - - /// Returns the explicitly user-written *predicates and bounds* of the trait given by `DefId`. - /// - /// Traits are unusual, because predicates on associated types are - /// converted into bounds on that type for backwards compatibility: - /// - /// ``` - /// trait X where Self::U: Copy { type U; } - /// ``` - /// - /// becomes - /// - /// ``` - /// trait X { type U: Copy; } - /// ``` - /// - /// [`Self::explicit_predicates_of`] and [`Self::explicit_item_bounds`] will - /// then take the appropriate subsets of the predicates here. - /// - /// # Panics - /// - /// This query will panic if the given definition is not a trait. - query trait_explicit_predicates_and_bounds(key: LocalDefId) -> ty::GenericPredicates<'tcx> { - desc { |tcx| "computing explicit predicates of trait `{}`", tcx.def_path_str(key) } - } - - /// Returns the explicitly user-written *predicates* of the definition given by `DefId` - /// that must be proven true at usage sites (and which can be assumed at definition site). - /// - /// You should probably use [`Self::predicates_of`] unless you're looking for - /// predicates with explicit spans for diagnostics purposes. - query explicit_predicates_of(key: DefId) -> ty::GenericPredicates<'tcx> { - desc { |tcx| "computing explicit predicates of `{}`", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } - separate_provide_extern - feedable - } - - /// Returns the *inferred outlives-predicates* of the item given by `DefId`. - /// - /// E.g., for `struct Foo<'a, T> { x: &'a T }`, this would return `[T: 'a]`. - /// - /// **Tip**: You can use `#[rustc_outlives]` on an item to basically print the - /// result of this query for use in UI tests or for debugging purposes. - query inferred_outlives_of(key: DefId) -> &'tcx [(ty::Clause<'tcx>, Span)] { - desc { |tcx| "computing inferred outlives-predicates of `{}`", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } - separate_provide_extern - feedable - } - - /// Returns the explicitly user-written *super-predicates* of the trait given by `DefId`. - /// - /// These predicates are unelaborated and consequently don't contain transitive super-predicates. - /// - /// This is a subset of the full list of predicates. We store these in a separate map - /// because we must evaluate them even during type conversion, often before the full - /// predicates are available (note that super-predicates must not be cyclic). - query explicit_super_predicates_of(key: DefId) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> { - desc { |tcx| "computing the super predicates of `{}`", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } - separate_provide_extern - } - - /// The predicates of the trait that are implied during elaboration. - /// - /// This is a superset of the super-predicates of the trait, but a subset of the predicates - /// of the trait. For regular traits, this includes all super-predicates and their - /// associated type bounds. For trait aliases, currently, this includes all of the - /// predicates of the trait alias. - query explicit_implied_predicates_of(key: DefId) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> { - desc { |tcx| "computing the implied predicates of `{}`", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } - separate_provide_extern - } - - /// The Ident is the name of an associated type.The query returns only the subset - /// of supertraits that define the given associated type. This is used to avoid - /// cycles in resolving type-dependent associated item paths like `T::Item`. - query explicit_supertraits_containing_assoc_item( - key: (DefId, rustc_span::Ident) - ) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> { - desc { |tcx| "computing the super traits of `{}` with associated type name `{}`", - tcx.def_path_str(key.0), - key.1 - } - } - - /// Compute the conditions that need to hold for a conditionally-const item to be const. - /// That is, compute the set of `[const]` where clauses for a given item. - /// - /// This can be thought of as the `[const]` equivalent of `predicates_of`. These are the - /// predicates that need to be proven at usage sites, and can be assumed at definition. - /// - /// This query also computes the `[const]` where clauses for associated types, which are - /// not "const", but which have item bounds which may be `[const]`. These must hold for - /// the `[const]` item bound to hold. - query const_conditions( - key: DefId - ) -> ty::ConstConditions<'tcx> { - desc { |tcx| "computing the conditions for `{}` to be considered const", - tcx.def_path_str(key) - } - separate_provide_extern - } - - /// Compute the const bounds that are implied for a conditionally-const item. - /// - /// This can be though of as the `[const]` equivalent of `explicit_item_bounds`. These - /// are the predicates that need to proven at definition sites, and can be assumed at - /// usage sites. - query explicit_implied_const_bounds( - key: DefId - ) -> ty::EarlyBinder<'tcx, &'tcx [(ty::PolyTraitRef<'tcx>, Span)]> { - desc { |tcx| "computing the implied `[const]` bounds for `{}`", - tcx.def_path_str(key) - } - separate_provide_extern - } - - /// To avoid cycles within the predicates of a single item we compute - /// per-type-parameter predicates for resolving `T::AssocTy`. - query type_param_predicates( - key: (LocalDefId, LocalDefId, rustc_span::Ident) - ) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> { - desc { |tcx| "computing the bounds for type parameter `{}`", tcx.hir_ty_param_name(key.1) } - } - - query trait_def(key: DefId) -> &'tcx ty::TraitDef { - desc { |tcx| "computing trait definition for `{}`", tcx.def_path_str(key) } - arena_cache - cache_on_disk_if { key.is_local() } - separate_provide_extern - } - query adt_def(key: DefId) -> ty::AdtDef<'tcx> { - desc { |tcx| "computing ADT definition for `{}`", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } - separate_provide_extern - } - query adt_destructor(key: DefId) -> Option<ty::Destructor> { - desc { |tcx| "computing `Drop` impl for `{}`", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } - separate_provide_extern - } - query adt_async_destructor(key: DefId) -> Option<ty::AsyncDestructor> { - desc { |tcx| "computing `AsyncDrop` impl for `{}`", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } - separate_provide_extern - } - query adt_sizedness_constraint( - key: (DefId, SizedTraitKind) - ) -> Option<ty::EarlyBinder<'tcx, Ty<'tcx>>> { - desc { |tcx| "computing the sizedness constraint for `{}`", tcx.def_path_str(key.0) } - } - - query adt_dtorck_constraint( - key: DefId - ) -> &'tcx DropckConstraint<'tcx> { - desc { |tcx| "computing drop-check constraints for `{}`", tcx.def_path_str(key) } - } - - /// Returns the constness of the function-like[^1] definition given by `DefId`. - /// - /// Tuple struct/variant constructors are *always* const, foreign functions are - /// *never* const. The rest is const iff marked with keyword `const` (or rather - /// its parent in the case of associated functions). - /// - /// <div class="warning"> - /// - /// **Do not call this query** directly. It is only meant to cache the base data for the - /// higher-level functions. Consider using `is_const_fn` or `is_const_trait_impl` instead. - /// - /// Also note that neither of them takes into account feature gates, stability and - /// const predicates/conditions! - /// - /// </div> - /// - /// # Panics - /// - /// This query will panic if the given definition is not function-like[^1]. - /// - /// [^1]: Tuple struct/variant constructors, closures and free, associated and foreign functions. - query constness(key: DefId) -> hir::Constness { - desc { |tcx| "checking if item is const: `{}`", tcx.def_path_str(key) } - separate_provide_extern - feedable - } - - query asyncness(key: DefId) -> ty::Asyncness { - desc { |tcx| "checking if the function is async: `{}`", tcx.def_path_str(key) } - separate_provide_extern - } - - /// Returns `true` if calls to the function may be promoted. - /// - /// This is either because the function is e.g., a tuple-struct or tuple-variant - /// constructor, or because it has the `#[rustc_promotable]` attribute. The attribute should - /// be removed in the future in favour of some form of check which figures out whether the - /// function does not inspect the bits of any of its arguments (so is essentially just a - /// constructor function). - query is_promotable_const_fn(key: DefId) -> bool { - desc { |tcx| "checking if item is promotable: `{}`", tcx.def_path_str(key) } - } - - /// The body of the coroutine, modified to take its upvars by move rather than by ref. - /// - /// This is used by coroutine-closures, which must return a different flavor of coroutine - /// when called using `AsyncFnOnce::call_once`. It is produced by the `ByMoveBody` pass which - /// is run right after building the initial MIR, and will only be populated for coroutines - /// which come out of the async closure desugaring. - query coroutine_by_move_body_def_id(def_id: DefId) -> DefId { - desc { |tcx| "looking up the coroutine by-move body for `{}`", tcx.def_path_str(def_id) } - separate_provide_extern - } - - /// Returns `Some(coroutine_kind)` if the node pointed to by `def_id` is a coroutine. - query coroutine_kind(def_id: DefId) -> Option<hir::CoroutineKind> { - desc { |tcx| "looking up coroutine kind of `{}`", tcx.def_path_str(def_id) } - separate_provide_extern - feedable - } - - query coroutine_for_closure(def_id: DefId) -> DefId { - desc { |_tcx| "Given a coroutine-closure def id, return the def id of the coroutine returned by it" } - separate_provide_extern - } - - query coroutine_hidden_types( - def_id: DefId, - ) -> ty::EarlyBinder<'tcx, ty::Binder<'tcx, ty::CoroutineWitnessTypes<TyCtxt<'tcx>>>> { - desc { "looking up the hidden types stored across await points in a coroutine" } - } - - /// Gets a map with the variances of every item in the local crate. - /// - /// <div class="warning"> - /// - /// **Do not call this query** directly, use [`Self::variances_of`] instead. - /// - /// </div> - query crate_variances(_: ()) -> &'tcx ty::CrateVariancesMap<'tcx> { - arena_cache - desc { "computing the variances for items in this crate" } - } - - /// Returns the (inferred) variances of the item given by `DefId`. - /// - /// The list of variances corresponds to the list of (early-bound) generic - /// parameters of the item (including its parents). - /// - /// **Tip**: You can use `#[rustc_variance]` on an item to basically print the - /// result of this query for use in UI tests or for debugging purposes. - query variances_of(def_id: DefId) -> &'tcx [ty::Variance] { - desc { |tcx| "computing the variances of `{}`", tcx.def_path_str(def_id) } - cache_on_disk_if { def_id.is_local() } - separate_provide_extern - cycle_delay_bug - } - - /// Gets a map with the inferred outlives-predicates of every item in the local crate. - /// - /// <div class="warning"> - /// - /// **Do not call this query** directly, use [`Self::inferred_outlives_of`] instead. - /// - /// </div> - query inferred_outlives_crate(_: ()) -> &'tcx ty::CratePredicatesMap<'tcx> { - arena_cache - desc { "computing the inferred outlives-predicates for items in this crate" } - } - - /// Maps from an impl/trait or struct/variant `DefId` - /// to a list of the `DefId`s of its associated items or fields. - query associated_item_def_ids(key: DefId) -> &'tcx [DefId] { - desc { |tcx| "collecting associated items or fields of `{}`", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } - separate_provide_extern - } - - /// Maps from a trait/impl item to the trait/impl item "descriptor". - query associated_item(key: DefId) -> ty::AssocItem { - desc { |tcx| "computing associated item data for `{}`", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } - separate_provide_extern - feedable - } - - /// Collects the associated items defined on a trait or impl. - query associated_items(key: DefId) -> &'tcx ty::AssocItems { - arena_cache - desc { |tcx| "collecting associated items of `{}`", tcx.def_path_str(key) } - } - - /// Maps from associated items on a trait to the corresponding associated - /// item on the impl specified by `impl_id`. - /// - /// For example, with the following code - /// - /// ``` - /// struct Type {} - /// // DefId - /// trait Trait { // trait_id - /// fn f(); // trait_f - /// fn g() {} // trait_g - /// } - /// - /// impl Trait for Type { // impl_id - /// fn f() {} // impl_f - /// fn g() {} // impl_g - /// } - /// ``` - /// - /// The map returned for `tcx.impl_item_implementor_ids(impl_id)` would be - ///`{ trait_f: impl_f, trait_g: impl_g }` - query impl_item_implementor_ids(impl_id: DefId) -> &'tcx DefIdMap<DefId> { - arena_cache - desc { |tcx| "comparing impl items against trait for `{}`", tcx.def_path_str(impl_id) } - } - - /// Given the `item_def_id` of a trait or impl, return a mapping from associated fn def id - /// to its associated type items that correspond to the RPITITs in its signature. - query associated_types_for_impl_traits_in_trait_or_impl(item_def_id: DefId) -> &'tcx DefIdMap<Vec<DefId>> { - arena_cache - desc { |tcx| "synthesizing RPITIT items for the opaque types for methods in `{}`", tcx.def_path_str(item_def_id) } - separate_provide_extern - } - - /// Given an `impl_id`, return the trait it implements along with some header information. - query impl_trait_header(impl_id: DefId) -> ty::ImplTraitHeader<'tcx> { - desc { |tcx| "computing trait implemented by `{}`", tcx.def_path_str(impl_id) } - cache_on_disk_if { impl_id.is_local() } - separate_provide_extern - } - - /// Given an `impl_def_id`, return true if the self type is guaranteed to be unsized due - /// to either being one of the built-in unsized types (str/slice/dyn) or to be a struct - /// whose tail is one of those types. - query impl_self_is_guaranteed_unsized(impl_def_id: DefId) -> bool { - desc { |tcx| "computing whether `{}` has a guaranteed unsized self type", tcx.def_path_str(impl_def_id) } - } - - /// Maps a `DefId` of a type to a list of its inherent impls. - /// Contains implementations of methods that are inherent to a type. - /// Methods in these implementations don't need to be exported. - query inherent_impls(key: DefId) -> &'tcx [DefId] { - desc { |tcx| "collecting inherent impls for `{}`", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } - separate_provide_extern - } - - query incoherent_impls(key: SimplifiedType) -> &'tcx [DefId] { - desc { |tcx| "collecting all inherent impls for `{:?}`", key } - } - - /// Unsafety-check this `LocalDefId`. - query check_transmutes(key: LocalDefId) { - desc { |tcx| "check transmute calls inside `{}`", tcx.def_path_str(key) } - } - - /// Unsafety-check this `LocalDefId`. - query check_unsafety(key: LocalDefId) { - desc { |tcx| "unsafety-checking `{}`", tcx.def_path_str(key) } - } - - /// Checks well-formedness of tail calls (`become f()`). - query check_tail_calls(key: LocalDefId) -> Result<(), rustc_errors::ErrorGuaranteed> { - desc { |tcx| "tail-call-checking `{}`", tcx.def_path_str(key) } - return_result_from_ensure_ok - } - - /// Returns the types assumed to be well formed while "inside" of the given item. - /// - /// Note that we've liberated the late bound regions of function signatures, so - /// this can not be used to check whether these types are well formed. - query assumed_wf_types(key: LocalDefId) -> &'tcx [(Ty<'tcx>, Span)] { - desc { |tcx| "computing the implied bounds of `{}`", tcx.def_path_str(key) } - } - - /// We need to store the assumed_wf_types for an RPITIT so that impls of foreign - /// traits with return-position impl trait in traits can inherit the right wf types. - query assumed_wf_types_for_rpitit(key: DefId) -> &'tcx [(Ty<'tcx>, Span)] { - desc { |tcx| "computing the implied bounds of `{}`", tcx.def_path_str(key) } - separate_provide_extern - } - - /// Computes the signature of the function. - query fn_sig(key: DefId) -> ty::EarlyBinder<'tcx, ty::PolyFnSig<'tcx>> { - desc { |tcx| "computing function signature of `{}`", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } - separate_provide_extern - cycle_delay_bug - } - - /// Performs lint checking for the module. - query lint_mod(key: LocalModDefId) { - desc { |tcx| "linting {}", describe_as_module(key, tcx) } - } - - query check_unused_traits(_: ()) { - desc { "checking unused trait imports in crate" } - } - - /// Checks the attributes in the module. - query check_mod_attrs(key: LocalModDefId) { - desc { |tcx| "checking attributes in {}", describe_as_module(key, tcx) } - } - - /// Checks for uses of unstable APIs in the module. - query check_mod_unstable_api_usage(key: LocalModDefId) { - desc { |tcx| "checking for unstable API usage in {}", describe_as_module(key, tcx) } - } - - query check_mod_privacy(key: LocalModDefId) { - desc { |tcx| "checking privacy in {}", describe_as_module(key.to_local_def_id(), tcx) } - } - - query check_liveness(key: LocalDefId) -> &'tcx rustc_index::bit_set::DenseBitSet<abi::FieldIdx> { - arena_cache - desc { |tcx| "checking liveness of variables in `{}`", tcx.def_path_str(key.to_def_id()) } - cache_on_disk_if(tcx) { tcx.is_typeck_child(key.to_def_id()) } - } - - /// Return the live symbols in the crate for dead code check. - /// - /// The second return value maps from ADTs to ignored derived traits (e.g. Debug and Clone). - query live_symbols_and_ignored_derived_traits(_: ()) -> &'tcx Result<( - LocalDefIdSet, - LocalDefIdMap<FxIndexSet<DefId>>, - ), ErrorGuaranteed> { - arena_cache - desc { "finding live symbols in crate" } - } - - query check_mod_deathness(key: LocalModDefId) { - desc { |tcx| "checking deathness of variables in {}", describe_as_module(key, tcx) } - } - - query check_type_wf(key: ()) -> Result<(), ErrorGuaranteed> { - desc { "checking that types are well-formed" } - return_result_from_ensure_ok - } - - /// Caches `CoerceUnsized` kinds for impls on custom types. - query coerce_unsized_info(key: DefId) -> Result<ty::adjustment::CoerceUnsizedInfo, ErrorGuaranteed> { - desc { |tcx| "computing CoerceUnsized info for `{}`", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } - separate_provide_extern - return_result_from_ensure_ok - } - - query typeck(key: LocalDefId) -> &'tcx ty::TypeckResults<'tcx> { - desc { |tcx| "type-checking `{}`", tcx.def_path_str(key) } - cache_on_disk_if(tcx) { !tcx.is_typeck_child(key.to_def_id()) } - } - - query used_trait_imports(key: LocalDefId) -> &'tcx UnordSet<LocalDefId> { - desc { |tcx| "finding used_trait_imports `{}`", tcx.def_path_str(key) } - cache_on_disk_if { true } - } - - query coherent_trait(def_id: DefId) -> Result<(), ErrorGuaranteed> { - desc { |tcx| "coherence checking all impls of trait `{}`", tcx.def_path_str(def_id) } - return_result_from_ensure_ok - } - - /// Borrow-checks the given typeck root, e.g. functions, const/static items, - /// and its children, e.g. closures, inline consts. - query mir_borrowck(key: LocalDefId) -> Result< - &'tcx FxIndexMap<LocalDefId, ty::DefinitionSiteHiddenType<'tcx>>, - ErrorGuaranteed - > { - desc { |tcx| "borrow-checking `{}`", tcx.def_path_str(key) } - } - - /// Gets a complete map from all types to their inherent impls. - /// - /// <div class="warning"> - /// - /// **Not meant to be used** directly outside of coherence. - /// - /// </div> - query crate_inherent_impls(k: ()) -> (&'tcx CrateInherentImpls, Result<(), ErrorGuaranteed>) { - desc { "finding all inherent impls defined in crate" } - } - - /// Checks all types in the crate for overlap in their inherent impls. Reports errors. - /// - /// <div class="warning"> - /// - /// **Not meant to be used** directly outside of coherence. - /// - /// </div> - query crate_inherent_impls_validity_check(_: ()) -> Result<(), ErrorGuaranteed> { - desc { "check for inherent impls that should not be defined in crate" } - return_result_from_ensure_ok - } - - /// Checks all types in the crate for overlap in their inherent impls. Reports errors. - /// - /// <div class="warning"> - /// - /// **Not meant to be used** directly outside of coherence. - /// - /// </div> - query crate_inherent_impls_overlap_check(_: ()) -> Result<(), ErrorGuaranteed> { - desc { "check for overlap between inherent impls defined in this crate" } - return_result_from_ensure_ok - } - - /// Checks whether all impls in the crate pass the overlap check, returning - /// which impls fail it. If all impls are correct, the returned slice is empty. - query orphan_check_impl(key: LocalDefId) -> Result<(), ErrorGuaranteed> { - desc { |tcx| - "checking whether impl `{}` follows the orphan rules", - tcx.def_path_str(key), - } - return_result_from_ensure_ok - } - - /// Return the set of (transitive) callees that may result in a recursive call to `key`, - /// if we were able to walk all callees. - query mir_callgraph_cyclic(key: LocalDefId) -> &'tcx Option<UnordSet<LocalDefId>> { - cycle_fatal - arena_cache - desc { |tcx| - "computing (transitive) callees of `{}` that may recurse", - tcx.def_path_str(key), - } - cache_on_disk_if { true } - } - - /// Obtain all the calls into other local functions - query mir_inliner_callees(key: ty::InstanceKind<'tcx>) -> &'tcx [(DefId, GenericArgsRef<'tcx>)] { - cycle_fatal - desc { |tcx| - "computing all local function calls in `{}`", - tcx.def_path_str(key.def_id()), - } - } - - /// Computes the tag (if any) for a given type and variant. - /// - /// `None` means that the variant doesn't need a tag (because it is niched). - /// - /// # Panics - /// - /// This query will panic for uninhabited variants and if the passed type is not an enum. - query tag_for_variant( - key: PseudoCanonicalInput<'tcx, (Ty<'tcx>, abi::VariantIdx)>, - ) -> Option<ty::ScalarInt> { - desc { "computing variant tag for enum" } - } - - /// Evaluates a constant and returns the computed allocation. - /// - /// <div class="warning"> - /// - /// **Do not call this query** directly, use [`Self::eval_to_const_value_raw`] or - /// [`Self::eval_to_valtree`] instead. - /// - /// </div> - query eval_to_allocation_raw(key: ty::PseudoCanonicalInput<'tcx, GlobalId<'tcx>>) - -> EvalToAllocationRawResult<'tcx> { - desc { |tcx| - "const-evaluating + checking `{}`", - key.value.display(tcx) - } - cache_on_disk_if { true } - } - - /// Evaluate a static's initializer, returning the allocation of the initializer's memory. - query eval_static_initializer(key: DefId) -> EvalStaticInitializerRawResult<'tcx> { - desc { |tcx| - "evaluating initializer of static `{}`", - tcx.def_path_str(key) - } - cache_on_disk_if { key.is_local() } - separate_provide_extern - feedable - } - - /// Evaluates const items or anonymous constants[^1] into a representation - /// suitable for the type system and const generics. - /// - /// <div class="warning"> - /// - /// **Do not call this** directly, use one of the following wrappers: - /// [`TyCtxt::const_eval_poly`], [`TyCtxt::const_eval_resolve`], - /// [`TyCtxt::const_eval_instance`], or [`TyCtxt::const_eval_global_id`]. - /// - /// </div> - /// - /// [^1]: Such as enum variant explicit discriminants or array lengths. - query eval_to_const_value_raw(key: ty::PseudoCanonicalInput<'tcx, GlobalId<'tcx>>) - -> EvalToConstValueResult<'tcx> { - desc { |tcx| - "simplifying constant for the type system `{}`", - key.value.display(tcx) - } - depth_limit - cache_on_disk_if { true } - } - - /// Evaluate a constant and convert it to a type level constant or - /// return `None` if that is not possible. - query eval_to_valtree( - key: ty::PseudoCanonicalInput<'tcx, GlobalId<'tcx>> - ) -> EvalToValTreeResult<'tcx> { - desc { "evaluating type-level constant" } - } - - /// Converts a type-level constant value into a MIR constant value. - query valtree_to_const_val(key: ty::Value<'tcx>) -> mir::ConstValue { - desc { "converting type-level constant value to MIR constant value"} - } - - // FIXME get rid of this with valtrees - query lit_to_const( - key: LitToConstInput<'tcx> - ) -> ty::Const<'tcx> { - desc { "converting literal to const" } - } - - query check_match(key: LocalDefId) -> Result<(), rustc_errors::ErrorGuaranteed> { - desc { |tcx| "match-checking `{}`", tcx.def_path_str(key) } - return_result_from_ensure_ok - } - - /// Performs part of the privacy check and computes effective visibilities. - query effective_visibilities(_: ()) -> &'tcx EffectiveVisibilities { - eval_always - desc { "checking effective visibilities" } - } - query check_private_in_public(module_def_id: LocalModDefId) { - desc { |tcx| - "checking for private elements in public interfaces for {}", - describe_as_module(module_def_id, tcx) - } - } - - query reachable_set(_: ()) -> &'tcx LocalDefIdSet { - arena_cache - desc { "reachability" } - cache_on_disk_if { true } - } - - /// Per-body `region::ScopeTree`. The `DefId` should be the owner `DefId` for the body; - /// in the case of closures, this will be redirected to the enclosing function. - query region_scope_tree(def_id: DefId) -> &'tcx crate::middle::region::ScopeTree { - desc { |tcx| "computing drop scopes for `{}`", tcx.def_path_str(def_id) } - } - - /// Generates a MIR body for the shim. - query mir_shims(key: ty::InstanceKind<'tcx>) -> &'tcx mir::Body<'tcx> { - arena_cache - desc { - |tcx| "generating MIR shim for `{}`, instance={:?}", - tcx.def_path_str(key.def_id()), - key - } - } - - /// The `symbol_name` query provides the symbol name for calling a - /// given instance from the local crate. In particular, it will also - /// look up the correct symbol name of instances from upstream crates. - query symbol_name(key: ty::Instance<'tcx>) -> ty::SymbolName<'tcx> { - desc { "computing the symbol for `{}`", key } - cache_on_disk_if { true } - } - - query def_kind(def_id: DefId) -> DefKind { - desc { |tcx| "looking up definition kind of `{}`", tcx.def_path_str(def_id) } - cache_on_disk_if { def_id.is_local() } - separate_provide_extern - feedable - } - - /// Gets the span for the definition. - query def_span(def_id: DefId) -> Span { - desc { |tcx| "looking up span for `{}`", tcx.def_path_str(def_id) } - cache_on_disk_if { def_id.is_local() } - separate_provide_extern - feedable - } - - /// Gets the span for the identifier of the definition. - query def_ident_span(def_id: DefId) -> Option<Span> { - desc { |tcx| "looking up span for `{}`'s identifier", tcx.def_path_str(def_id) } - cache_on_disk_if { def_id.is_local() } - separate_provide_extern - feedable - } - - /// Gets the span for the type of the definition. - /// Panics if it is not a definition that has a single type. - query ty_span(def_id: LocalDefId) -> Span { - desc { |tcx| "looking up span for `{}`'s type", tcx.def_path_str(def_id) } - cache_on_disk_if { true } - } - - query lookup_stability(def_id: DefId) -> Option<hir::Stability> { - desc { |tcx| "looking up stability of `{}`", tcx.def_path_str(def_id) } - cache_on_disk_if { def_id.is_local() } - separate_provide_extern - } - - query lookup_const_stability(def_id: DefId) -> Option<hir::ConstStability> { - desc { |tcx| "looking up const stability of `{}`", tcx.def_path_str(def_id) } - cache_on_disk_if { def_id.is_local() } - separate_provide_extern - } - - query lookup_default_body_stability(def_id: DefId) -> Option<hir::DefaultBodyStability> { - desc { |tcx| "looking up default body stability of `{}`", tcx.def_path_str(def_id) } - separate_provide_extern - } - - query should_inherit_track_caller(def_id: DefId) -> bool { - desc { |tcx| "computing should_inherit_track_caller of `{}`", tcx.def_path_str(def_id) } - } - - query inherited_align(def_id: DefId) -> Option<Align> { - desc { |tcx| "computing inherited_align of `{}`", tcx.def_path_str(def_id) } - } - - query lookup_deprecation_entry(def_id: DefId) -> Option<DeprecationEntry> { - desc { |tcx| "checking whether `{}` is deprecated", tcx.def_path_str(def_id) } - cache_on_disk_if { def_id.is_local() } - separate_provide_extern - } - - /// Determines whether an item is annotated with `#[doc(hidden)]`. - query is_doc_hidden(def_id: DefId) -> bool { - desc { |tcx| "checking whether `{}` is `doc(hidden)`", tcx.def_path_str(def_id) } - separate_provide_extern - } - - /// Determines whether an item is annotated with `#[doc(notable_trait)]`. - query is_doc_notable_trait(def_id: DefId) -> bool { - desc { |tcx| "checking whether `{}` is `doc(notable_trait)`", tcx.def_path_str(def_id) } - } - - /// Returns the attributes on the item at `def_id`. - /// - /// Do not use this directly, use `tcx.get_attrs` instead. - query attrs_for_def(def_id: DefId) -> &'tcx [hir::Attribute] { - desc { |tcx| "collecting attributes of `{}`", tcx.def_path_str(def_id) } - separate_provide_extern - } - - /// Returns the `CodegenFnAttrs` for the item at `def_id`. - /// - /// If possible, use `tcx.codegen_instance_attrs` instead. That function takes the - /// instance kind into account. - /// - /// For example, the `#[naked]` attribute should be applied for `InstanceKind::Item`, - /// but should not be applied if the instance kind is `InstanceKind::ReifyShim`. - /// Using this query would include the attribute regardless of the actual instance - /// kind at the call site. - query codegen_fn_attrs(def_id: DefId) -> &'tcx CodegenFnAttrs { - desc { |tcx| "computing codegen attributes of `{}`", tcx.def_path_str(def_id) } - arena_cache - cache_on_disk_if { def_id.is_local() } - separate_provide_extern - feedable - } - - query asm_target_features(def_id: DefId) -> &'tcx FxIndexSet<Symbol> { - desc { |tcx| "computing target features for inline asm of `{}`", tcx.def_path_str(def_id) } - } - - query fn_arg_idents(def_id: DefId) -> &'tcx [Option<rustc_span::Ident>] { - desc { |tcx| "looking up function parameter identifiers for `{}`", tcx.def_path_str(def_id) } - separate_provide_extern - } - - /// Gets the rendered value of the specified constant or associated constant. - /// Used by rustdoc. - query rendered_const(def_id: DefId) -> &'tcx String { - arena_cache - desc { |tcx| "rendering constant initializer of `{}`", tcx.def_path_str(def_id) } - separate_provide_extern - } - - /// Gets the rendered precise capturing args for an opaque for use in rustdoc. - query rendered_precise_capturing_args(def_id: DefId) -> Option<&'tcx [PreciseCapturingArgKind<Symbol, Symbol>]> { - desc { |tcx| "rendering precise capturing args for `{}`", tcx.def_path_str(def_id) } - separate_provide_extern - } - - query impl_parent(def_id: DefId) -> Option<DefId> { - desc { |tcx| "computing specialization parent impl of `{}`", tcx.def_path_str(def_id) } - separate_provide_extern - } - - query is_ctfe_mir_available(key: DefId) -> bool { - desc { |tcx| "checking if item has CTFE MIR available: `{}`", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } - separate_provide_extern - } - query is_mir_available(key: DefId) -> bool { - desc { |tcx| "checking if item has MIR available: `{}`", tcx.def_path_str(key) } - cache_on_disk_if { key.is_local() } - separate_provide_extern - } - - query own_existential_vtable_entries( - key: DefId - ) -> &'tcx [DefId] { - desc { |tcx| "finding all existential vtable entries for trait `{}`", tcx.def_path_str(key) } - } - - query vtable_entries(key: ty::TraitRef<'tcx>) - -> &'tcx [ty::VtblEntry<'tcx>] { - desc { |tcx| "finding all vtable entries for trait `{}`", tcx.def_path_str(key.def_id) } - } - - query first_method_vtable_slot(key: ty::TraitRef<'tcx>) -> usize { - desc { |tcx| "finding the slot within the vtable of `{}` for the implementation of `{}`", key.self_ty(), key.print_only_trait_name() } - } - - query supertrait_vtable_slot(key: (Ty<'tcx>, Ty<'tcx>)) -> Option<usize> { - desc { |tcx| "finding the slot within vtable for trait object `{}` vtable ptr during trait upcasting coercion from `{}` vtable", - key.1, key.0 } - } - - query vtable_allocation(key: (Ty<'tcx>, Option<ty::ExistentialTraitRef<'tcx>>)) -> mir::interpret::AllocId { - desc { |tcx| "vtable const allocation for <{} as {}>", - key.0, - key.1.map(|trait_ref| format!("{trait_ref}")).unwrap_or_else(|| "_".to_owned()) - } - } - - query codegen_select_candidate( - key: PseudoCanonicalInput<'tcx, ty::TraitRef<'tcx>> - ) -> Result<&'tcx ImplSource<'tcx, ()>, CodegenObligationError> { - cache_on_disk_if { true } - desc { |tcx| "computing candidate for `{}`", key.value } - } - - /// Return all `impl` blocks in the current crate. - query all_local_trait_impls(_: ()) -> &'tcx rustc_data_structures::fx::FxIndexMap<DefId, Vec<LocalDefId>> { - desc { "finding local trait impls" } - } - - /// Return all `impl` blocks of the given trait in the current crate. - query local_trait_impls(trait_id: DefId) -> &'tcx [LocalDefId] { - desc { "finding local trait impls of `{}`", tcx.def_path_str(trait_id) } - } - - /// Given a trait `trait_id`, return all known `impl` blocks. - query trait_impls_of(trait_id: DefId) -> &'tcx ty::trait_def::TraitImpls { - arena_cache - desc { |tcx| "finding trait impls of `{}`", tcx.def_path_str(trait_id) } - } - - query specialization_graph_of(trait_id: DefId) -> Result<&'tcx specialization_graph::Graph, ErrorGuaranteed> { - desc { |tcx| "building specialization graph of trait `{}`", tcx.def_path_str(trait_id) } - cache_on_disk_if { true } - return_result_from_ensure_ok - } - query dyn_compatibility_violations(trait_id: DefId) -> &'tcx [DynCompatibilityViolation] { - desc { |tcx| "determining dyn-compatibility of trait `{}`", tcx.def_path_str(trait_id) } - } - query is_dyn_compatible(trait_id: DefId) -> bool { - desc { |tcx| "checking if trait `{}` is dyn-compatible", tcx.def_path_str(trait_id) } - } - - /// Gets the ParameterEnvironment for a given item; this environment - /// will be in "user-facing" mode, meaning that it is suitable for - /// type-checking etc, and it does not normalize specializable - /// associated types. - /// - /// You should almost certainly not use this. If you already have an InferCtxt, then - /// you should also probably have a `ParamEnv` from when it was built. If you don't, - /// then you should take a `TypingEnv` to ensure that you handle opaque types correctly. - query param_env(def_id: DefId) -> ty::ParamEnv<'tcx> { - desc { |tcx| "computing normalized predicates of `{}`", tcx.def_path_str(def_id) } - feedable - } - - /// Like `param_env`, but returns the `ParamEnv` after all opaque types have been - /// replaced with their hidden type. This is used in the old trait solver - /// when in `PostAnalysis` mode and should not be called directly. - query typing_env_normalized_for_post_analysis(def_id: DefId) -> ty::TypingEnv<'tcx> { - desc { |tcx| "computing revealed normalized predicates of `{}`", tcx.def_path_str(def_id) } - } - - /// Trait selection queries. These are best used by invoking `ty.is_copy_modulo_regions()`, - /// `ty.is_copy()`, etc, since that will prune the environment where possible. - query is_copy_raw(env: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) -> bool { - desc { "computing whether `{}` is `Copy`", env.value } - } - /// Trait selection queries. These are best used by invoking `ty.is_use_cloned_modulo_regions()`, - /// `ty.is_use_cloned()`, etc, since that will prune the environment where possible. - query is_use_cloned_raw(env: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) -> bool { - desc { "computing whether `{}` is `UseCloned`", env.value } - } - /// Query backing `Ty::is_sized`. - query is_sized_raw(env: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) -> bool { - desc { "computing whether `{}` is `Sized`", env.value } - } - /// Query backing `Ty::is_freeze`. - query is_freeze_raw(env: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) -> bool { - desc { "computing whether `{}` is freeze", env.value } - } - /// Query backing `Ty::is_unpin`. - query is_unpin_raw(env: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) -> bool { - desc { "computing whether `{}` is `Unpin`", env.value } - } - /// Query backing `Ty::is_async_drop`. - query is_async_drop_raw(env: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) -> bool { - desc { "computing whether `{}` is `AsyncDrop`", env.value } - } - /// Query backing `Ty::needs_drop`. - query needs_drop_raw(env: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) -> bool { - desc { "computing whether `{}` needs drop", env.value } - } - /// Query backing `Ty::needs_async_drop`. - query needs_async_drop_raw(env: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) -> bool { - desc { "computing whether `{}` needs async drop", env.value } - } - /// Query backing `Ty::has_significant_drop_raw`. - query has_significant_drop_raw(env: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) -> bool { - desc { "computing whether `{}` has a significant drop", env.value } - } - - /// Query backing `Ty::is_structural_eq_shallow`. - /// - /// This is only correct for ADTs. Call `is_structural_eq_shallow` to handle all types - /// correctly. - query has_structural_eq_impl(ty: Ty<'tcx>) -> bool { - desc { - "computing whether `{}` implements `StructuralPartialEq`", - ty - } - } - - /// A list of types where the ADT requires drop if and only if any of - /// those types require drop. If the ADT is known to always need drop - /// then `Err(AlwaysRequiresDrop)` is returned. - query adt_drop_tys(def_id: DefId) -> Result<&'tcx ty::List<Ty<'tcx>>, AlwaysRequiresDrop> { - desc { |tcx| "computing when `{}` needs drop", tcx.def_path_str(def_id) } - cache_on_disk_if { true } - } - - /// A list of types where the ADT requires async drop if and only if any of - /// those types require async drop. If the ADT is known to always need async drop - /// then `Err(AlwaysRequiresDrop)` is returned. - query adt_async_drop_tys(def_id: DefId) -> Result<&'tcx ty::List<Ty<'tcx>>, AlwaysRequiresDrop> { - desc { |tcx| "computing when `{}` needs async drop", tcx.def_path_str(def_id) } - cache_on_disk_if { true } - } - - /// A list of types where the ADT requires drop if and only if any of those types - /// has significant drop. A type marked with the attribute `rustc_insignificant_dtor` - /// is considered to not be significant. A drop is significant if it is implemented - /// by the user or does anything that will have any observable behavior (other than - /// freeing up memory). If the ADT is known to have a significant destructor then - /// `Err(AlwaysRequiresDrop)` is returned. - query adt_significant_drop_tys(def_id: DefId) -> Result<&'tcx ty::List<Ty<'tcx>>, AlwaysRequiresDrop> { - desc { |tcx| "computing when `{}` has a significant destructor", tcx.def_path_str(def_id) } - } - - /// Returns a list of types which (a) have a potentially significant destructor - /// and (b) may be dropped as a result of dropping a value of some type `ty` - /// (in the given environment). - /// - /// The idea of "significant" drop is somewhat informal and is used only for - /// diagnostics and edition migrations. The idea is that a significant drop may have - /// some visible side-effect on execution; freeing memory is NOT considered a side-effect. - /// The rules are as follows: - /// * Type with no explicit drop impl do not have significant drop. - /// * Types with a drop impl are assumed to have significant drop unless they have a `#[rustc_insignificant_dtor]` annotation. - /// - /// Note that insignificant drop is a "shallow" property. A type like `Vec<LockGuard>` does not - /// have significant drop but the type `LockGuard` does, and so if `ty = Vec<LockGuard>` - /// then the return value would be `&[LockGuard]`. - /// *IMPORTANT*: *DO NOT* run this query before promoted MIR body is constructed, - /// because this query partially depends on that query. - /// Otherwise, there is a risk of query cycles. - query list_significant_drop_tys(ty: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) -> &'tcx ty::List<Ty<'tcx>> { - desc { |tcx| "computing when `{}` has a significant destructor", ty.value } - } - - /// Computes the layout of a type. Note that this implicitly - /// executes in `TypingMode::PostAnalysis`, and will normalize the input type. - query layout_of( - key: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>> - ) -> Result<ty::layout::TyAndLayout<'tcx>, &'tcx ty::layout::LayoutError<'tcx>> { - depth_limit - desc { "computing layout of `{}`", key.value } - // we emit our own error during query cycle handling - cycle_delay_bug - } - - /// Compute a `FnAbi` suitable for indirect calls, i.e. to `fn` pointers. - /// - /// NB: this doesn't handle virtual calls - those should use `fn_abi_of_instance` - /// instead, where the instance is an `InstanceKind::Virtual`. - query fn_abi_of_fn_ptr( - key: ty::PseudoCanonicalInput<'tcx, (ty::PolyFnSig<'tcx>, &'tcx ty::List<Ty<'tcx>>)> - ) -> Result<&'tcx rustc_target::callconv::FnAbi<'tcx, Ty<'tcx>>, &'tcx ty::layout::FnAbiError<'tcx>> { - desc { "computing call ABI of `{}` function pointers", key.value.0 } - } - - /// Compute a `FnAbi` suitable for declaring/defining an `fn` instance, and for - /// direct calls to an `fn`. - /// - /// NB: that includes virtual calls, which are represented by "direct calls" - /// to an `InstanceKind::Virtual` instance (of `<dyn Trait as Trait>::fn`). - query fn_abi_of_instance( - key: ty::PseudoCanonicalInput<'tcx, (ty::Instance<'tcx>, &'tcx ty::List<Ty<'tcx>>)> - ) -> Result<&'tcx rustc_target::callconv::FnAbi<'tcx, Ty<'tcx>>, &'tcx ty::layout::FnAbiError<'tcx>> { - desc { "computing call ABI of `{}`", key.value.0 } - } - - query dylib_dependency_formats(_: CrateNum) - -> &'tcx [(CrateNum, LinkagePreference)] { - desc { "getting dylib dependency formats of crate" } - separate_provide_extern - } - - query dependency_formats(_: ()) -> &'tcx Arc<crate::middle::dependency_format::Dependencies> { - arena_cache - desc { "getting the linkage format of all dependencies" } - } - - query is_compiler_builtins(_: CrateNum) -> bool { - cycle_fatal - desc { "checking if the crate is_compiler_builtins" } - separate_provide_extern - } - query has_global_allocator(_: CrateNum) -> bool { - // This query depends on untracked global state in CStore - eval_always - cycle_fatal - desc { "checking if the crate has_global_allocator" } - separate_provide_extern - } - query has_alloc_error_handler(_: CrateNum) -> bool { - // This query depends on untracked global state in CStore - eval_always - cycle_fatal - desc { "checking if the crate has_alloc_error_handler" } - separate_provide_extern - } - query has_panic_handler(_: CrateNum) -> bool { - cycle_fatal - desc { "checking if the crate has_panic_handler" } - separate_provide_extern - } - query is_profiler_runtime(_: CrateNum) -> bool { - cycle_fatal - desc { "checking if a crate is `#![profiler_runtime]`" } - separate_provide_extern - } - query has_ffi_unwind_calls(key: LocalDefId) -> bool { - desc { |tcx| "checking if `{}` contains FFI-unwind calls", tcx.def_path_str(key) } - cache_on_disk_if { true } - } - query required_panic_strategy(_: CrateNum) -> Option<PanicStrategy> { - cycle_fatal - desc { "getting a crate's required panic strategy" } - separate_provide_extern - } - query panic_in_drop_strategy(_: CrateNum) -> PanicStrategy { - cycle_fatal - desc { "getting a crate's configured panic-in-drop strategy" } - separate_provide_extern - } - query is_no_builtins(_: CrateNum) -> bool { - cycle_fatal - desc { "getting whether a crate has `#![no_builtins]`" } - separate_provide_extern - } - query symbol_mangling_version(_: CrateNum) -> SymbolManglingVersion { - cycle_fatal - desc { "getting a crate's symbol mangling version" } - separate_provide_extern - } - - query extern_crate(def_id: CrateNum) -> Option<&'tcx ExternCrate> { - eval_always - desc { "getting crate's ExternCrateData" } - separate_provide_extern - } - - query specialization_enabled_in(cnum: CrateNum) -> bool { - desc { "checking whether the crate enabled `specialization`/`min_specialization`" } - separate_provide_extern - } - - query specializes(_: (DefId, DefId)) -> bool { - desc { "computing whether impls specialize one another" } - } - query in_scope_traits_map(_: hir::OwnerId) - -> Option<&'tcx ItemLocalMap<Box<[TraitCandidate]>>> { - desc { "getting traits in scope at a block" } - } - - /// Returns whether the impl or associated function has the `default` keyword. - /// Note: This will ICE on inherent impl items. Consider using `AssocItem::defaultness`. - query defaultness(def_id: DefId) -> hir::Defaultness { - desc { |tcx| "looking up whether `{}` has `default`", tcx.def_path_str(def_id) } - separate_provide_extern - feedable - } - - /// Returns whether the field corresponding to the `DefId` has a default field value. - query default_field(def_id: DefId) -> Option<DefId> { - desc { |tcx| "looking up the `const` corresponding to the default for `{}`", tcx.def_path_str(def_id) } - separate_provide_extern - } - - query check_well_formed(key: LocalDefId) -> Result<(), ErrorGuaranteed> { - desc { |tcx| "checking that `{}` is well-formed", tcx.def_path_str(key) } - return_result_from_ensure_ok - } - - query enforce_impl_non_lifetime_params_are_constrained(key: LocalDefId) -> Result<(), ErrorGuaranteed> { - desc { |tcx| "checking that `{}`'s generics are constrained by the impl header", tcx.def_path_str(key) } - return_result_from_ensure_ok - } - - // The `DefId`s of all non-generic functions and statics in the given crate - // that can be reached from outside the crate. - // - // We expect this items to be available for being linked to. - // - // This query can also be called for `LOCAL_CRATE`. In this case it will - // compute which items will be reachable to other crates, taking into account - // the kind of crate that is currently compiled. Crates with only a - // C interface have fewer reachable things. - // - // Does not include external symbols that don't have a corresponding DefId, - // like the compiler-generated `main` function and so on. - query reachable_non_generics(_: CrateNum) - -> &'tcx DefIdMap<SymbolExportInfo> { - arena_cache - desc { "looking up the exported symbols of a crate" } - separate_provide_extern - } - query is_reachable_non_generic(def_id: DefId) -> bool { - desc { |tcx| "checking whether `{}` is an exported symbol", tcx.def_path_str(def_id) } - cache_on_disk_if { def_id.is_local() } - separate_provide_extern - } - query is_unreachable_local_definition(def_id: LocalDefId) -> bool { - desc { |tcx| - "checking whether `{}` is reachable from outside the crate", - tcx.def_path_str(def_id), - } - } - - /// The entire set of monomorphizations the local crate can safely - /// link to because they are exported from upstream crates. Do - /// not depend on this directly, as its value changes anytime - /// a monomorphization gets added or removed in any upstream - /// crate. Instead use the narrower `upstream_monomorphizations_for`, - /// `upstream_drop_glue_for`, `upstream_async_drop_glue_for`, or, - /// even better, `Instance::upstream_monomorphization()`. - query upstream_monomorphizations(_: ()) -> &'tcx DefIdMap<UnordMap<GenericArgsRef<'tcx>, CrateNum>> { - arena_cache - desc { "collecting available upstream monomorphizations" } - } - - /// Returns the set of upstream monomorphizations available for the - /// generic function identified by the given `def_id`. The query makes - /// sure to make a stable selection if the same monomorphization is - /// available in multiple upstream crates. - /// - /// You likely want to call `Instance::upstream_monomorphization()` - /// instead of invoking this query directly. - query upstream_monomorphizations_for(def_id: DefId) - -> Option<&'tcx UnordMap<GenericArgsRef<'tcx>, CrateNum>> - { - desc { |tcx| - "collecting available upstream monomorphizations for `{}`", - tcx.def_path_str(def_id), - } - separate_provide_extern - } - - /// Returns the upstream crate that exports drop-glue for the given - /// type (`args` is expected to be a single-item list containing the - /// type one wants drop-glue for). - /// - /// This is a subset of `upstream_monomorphizations_for` in order to - /// increase dep-tracking granularity. Otherwise adding or removing any - /// type with drop-glue in any upstream crate would invalidate all - /// functions calling drop-glue of an upstream type. - /// - /// You likely want to call `Instance::upstream_monomorphization()` - /// instead of invoking this query directly. - /// - /// NOTE: This query could easily be extended to also support other - /// common functions that have are large set of monomorphizations - /// (like `Clone::clone` for example). - query upstream_drop_glue_for(args: GenericArgsRef<'tcx>) -> Option<CrateNum> { - desc { "available upstream drop-glue for `{:?}`", args } - } - - /// Returns the upstream crate that exports async-drop-glue for - /// the given type (`args` is expected to be a single-item list - /// containing the type one wants async-drop-glue for). - /// - /// This is a subset of `upstream_monomorphizations_for` in order - /// to increase dep-tracking granularity. Otherwise adding or - /// removing any type with async-drop-glue in any upstream crate - /// would invalidate all functions calling async-drop-glue of an - /// upstream type. - /// - /// You likely want to call `Instance::upstream_monomorphization()` - /// instead of invoking this query directly. - /// - /// NOTE: This query could easily be extended to also support other - /// common functions that have are large set of monomorphizations - /// (like `Clone::clone` for example). - query upstream_async_drop_glue_for(args: GenericArgsRef<'tcx>) -> Option<CrateNum> { - desc { "available upstream async-drop-glue for `{:?}`", args } - } - - /// Returns a list of all `extern` blocks of a crate. - query foreign_modules(_: CrateNum) -> &'tcx FxIndexMap<DefId, ForeignModule> { - arena_cache - desc { "looking up the foreign modules of a linked crate" } - separate_provide_extern - } - - /// Lint against `extern fn` declarations having incompatible types. - query clashing_extern_declarations(_: ()) { - desc { "checking `extern fn` declarations are compatible" } - } - - /// Identifies the entry-point (e.g., the `main` function) for a given - /// crate, returning `None` if there is no entry point (such as for library crates). - query entry_fn(_: ()) -> Option<(DefId, EntryFnType)> { - desc { "looking up the entry function of a crate" } - } - - /// Finds the `rustc_proc_macro_decls` item of a crate. - query proc_macro_decls_static(_: ()) -> Option<LocalDefId> { - desc { "looking up the proc macro declarations for a crate" } - } - - // The macro which defines `rustc_metadata::provide_extern` depends on this query's name. - // Changing the name should cause a compiler error, but in case that changes, be aware. - // - // The hash should not be calculated before the `analysis` pass is complete, specifically - // until `tcx.untracked().definitions.freeze()` has been called, otherwise if incremental - // compilation is enabled calculating this hash can freeze this structure too early in - // compilation and cause subsequent crashes when attempting to write to `definitions` - query crate_hash(_: CrateNum) -> Svh { - eval_always - desc { "looking up the hash a crate" } - separate_provide_extern - } - - /// Gets the hash for the host proc macro. Used to support -Z dual-proc-macro. - query crate_host_hash(_: CrateNum) -> Option<Svh> { - eval_always - desc { "looking up the hash of a host version of a crate" } - separate_provide_extern - } - - /// Gets the extra data to put in each output filename for a crate. - /// For example, compiling the `foo` crate with `extra-filename=-a` creates a `libfoo-b.rlib` file. - query extra_filename(_: CrateNum) -> &'tcx String { - arena_cache - eval_always - desc { "looking up the extra filename for a crate" } - separate_provide_extern - } - - /// Gets the paths where the crate came from in the file system. - query crate_extern_paths(_: CrateNum) -> &'tcx Vec<PathBuf> { - arena_cache - eval_always - desc { "looking up the paths for extern crates" } - separate_provide_extern - } - - /// Given a crate and a trait, look up all impls of that trait in the crate. - /// Return `(impl_id, self_ty)`. - query implementations_of_trait(_: (CrateNum, DefId)) -> &'tcx [(DefId, Option<SimplifiedType>)] { - desc { "looking up implementations of a trait in a crate" } - separate_provide_extern - } - - /// Collects all incoherent impls for the given crate and type. - /// - /// Do not call this directly, but instead use the `incoherent_impls` query. - /// This query is only used to get the data necessary for that query. - query crate_incoherent_impls(key: (CrateNum, SimplifiedType)) -> &'tcx [DefId] { - desc { |tcx| "collecting all impls for a type in a crate" } - separate_provide_extern - } - - /// Get the corresponding native library from the `native_libraries` query - query native_library(def_id: DefId) -> Option<&'tcx NativeLib> { - desc { |tcx| "getting the native library for `{}`", tcx.def_path_str(def_id) } - } - - query inherit_sig_for_delegation_item(def_id: LocalDefId) -> &'tcx [Ty<'tcx>] { - desc { "inheriting delegation signature" } - } - - /// Does lifetime resolution on items. Importantly, we can't resolve - /// lifetimes directly on things like trait methods, because of trait params. - /// See `rustc_resolve::late::lifetimes` for details. - query resolve_bound_vars(owner_id: hir::OwnerId) -> &'tcx ResolveBoundVars<'tcx> { - arena_cache - desc { |tcx| "resolving lifetimes for `{}`", tcx.def_path_str(owner_id) } - } - query named_variable_map(owner_id: hir::OwnerId) -> &'tcx SortedMap<ItemLocalId, ResolvedArg> { - desc { |tcx| "looking up a named region inside `{}`", tcx.def_path_str(owner_id) } - } - query is_late_bound_map(owner_id: hir::OwnerId) -> Option<&'tcx FxIndexSet<ItemLocalId>> { - desc { |tcx| "testing if a region is late bound inside `{}`", tcx.def_path_str(owner_id) } - } - /// Returns the *default lifetime* to be used if a trait object type were to be passed for - /// the type parameter given by `DefId`. - /// - /// **Tip**: You can use `#[rustc_object_lifetime_default]` on an item to basically - /// print the result of this query for use in UI tests or for debugging purposes. - /// - /// # Examples - /// - /// - For `T` in `struct Foo<'a, T: 'a>(&'a T);`, this would be `Param('a)` - /// - For `T` in `struct Bar<'a, T>(&'a T);`, this would be `Empty` - /// - /// # Panics - /// - /// This query will panic if the given definition is not a type parameter. - query object_lifetime_default(def_id: DefId) -> ObjectLifetimeDefault { - desc { "looking up lifetime defaults for type parameter `{}`", tcx.def_path_str(def_id) } - separate_provide_extern - } - query late_bound_vars_map(owner_id: hir::OwnerId) - -> &'tcx SortedMap<ItemLocalId, Vec<ty::BoundVariableKind<'tcx>>> { - desc { |tcx| "looking up late bound vars inside `{}`", tcx.def_path_str(owner_id) } - } - /// For an opaque type, return the list of (captured lifetime, inner generic param). - /// ```ignore (illustrative) - /// fn foo<'a: 'a, 'b, T>(&'b u8) -> impl Into<Self> + 'b { ... } - /// ``` - /// - /// We would return `[('a, '_a), ('b, '_b)]`, with `'a` early-bound and `'b` late-bound. - /// - /// After hir_ty_lowering, we get: - /// ```ignore (pseudo-code) - /// opaque foo::<'a>::opaque<'_a, '_b>: Into<Foo<'_a>> + '_b; - /// ^^^^^^^^ inner generic params - /// fn foo<'a>: for<'b> fn(&'b u8) -> foo::<'a>::opaque::<'a, 'b> - /// ^^^^^^ captured lifetimes - /// ``` - query opaque_captured_lifetimes(def_id: LocalDefId) -> &'tcx [(ResolvedArg, LocalDefId)] { - desc { |tcx| "listing captured lifetimes for opaque `{}`", tcx.def_path_str(def_id) } - } - - /// Computes the visibility of the provided `def_id`. - /// - /// If the item from the `def_id` doesn't have a visibility, it will panic. For example - /// a generic type parameter will panic if you call this method on it: - /// - /// ``` - /// use std::fmt::Debug; - /// - /// pub trait Foo<T: Debug> {} - /// ``` - /// - /// In here, if you call `visibility` on `T`, it'll panic. - query visibility(def_id: DefId) -> ty::Visibility<DefId> { - desc { |tcx| "computing visibility of `{}`", tcx.def_path_str(def_id) } - separate_provide_extern - feedable - } - - query inhabited_predicate_adt(key: DefId) -> ty::inhabitedness::InhabitedPredicate<'tcx> { - desc { "computing the uninhabited predicate of `{:?}`", key } - } - - /// Do not call this query directly: invoke `Ty::inhabited_predicate` instead. - query inhabited_predicate_type(key: Ty<'tcx>) -> ty::inhabitedness::InhabitedPredicate<'tcx> { - desc { "computing the uninhabited predicate of `{}`", key } - } - - query dep_kind(_: CrateNum) -> CrateDepKind { - eval_always - desc { "fetching what a dependency looks like" } - separate_provide_extern - } - - /// Gets the name of the crate. - query crate_name(_: CrateNum) -> Symbol { - feedable - desc { "fetching what a crate is named" } - separate_provide_extern - } - query module_children(def_id: DefId) -> &'tcx [ModChild] { - desc { |tcx| "collecting child items of module `{}`", tcx.def_path_str(def_id) } - separate_provide_extern - } - - /// Gets the number of definitions in a foreign crate. - /// - /// This allows external tools to iterate over all definitions in a foreign crate. - /// - /// This should never be used for the local crate, instead use `iter_local_def_id`. - query num_extern_def_ids(_: CrateNum) -> usize { - desc { "fetching the number of definitions in a crate" } - separate_provide_extern - } - - query lib_features(_: CrateNum) -> &'tcx LibFeatures { - desc { "calculating the lib features defined in a crate" } - separate_provide_extern - arena_cache - } - /// Mapping from feature name to feature name based on the `implied_by` field of `#[unstable]` - /// attributes. If a `#[unstable(feature = "implier", implied_by = "impliee")]` attribute - /// exists, then this map will have a `impliee -> implier` entry. - /// - /// This mapping is necessary unless both the `#[stable]` and `#[unstable]` attributes should - /// specify their implications (both `implies` and `implied_by`). If only one of the two - /// attributes do (as in the current implementation, `implied_by` in `#[unstable]`), then this - /// mapping is necessary for diagnostics. When a "unnecessary feature attribute" error is - /// reported, only the `#[stable]` attribute information is available, so the map is necessary - /// to know that the feature implies another feature. If it were reversed, and the `#[stable]` - /// attribute had an `implies` meta item, then a map would be necessary when avoiding a "use of - /// unstable feature" error for a feature that was implied. - query stability_implications(_: CrateNum) -> &'tcx UnordMap<Symbol, Symbol> { - arena_cache - desc { "calculating the implications between `#[unstable]` features defined in a crate" } - separate_provide_extern - } - /// Whether the function is an intrinsic - query intrinsic_raw(def_id: DefId) -> Option<rustc_middle::ty::IntrinsicDef> { - desc { |tcx| "fetch intrinsic name if `{}` is an intrinsic", tcx.def_path_str(def_id) } - separate_provide_extern - } - /// Returns the lang items defined in another crate by loading it from metadata. - query get_lang_items(_: ()) -> &'tcx LanguageItems { - arena_cache - eval_always - desc { "calculating the lang items map" } - } - - /// Returns all diagnostic items defined in all crates. - query all_diagnostic_items(_: ()) -> &'tcx rustc_hir::diagnostic_items::DiagnosticItems { - arena_cache - eval_always - desc { "calculating the diagnostic items map" } - } - - /// Returns the lang items defined in another crate by loading it from metadata. - query defined_lang_items(_: CrateNum) -> &'tcx [(DefId, LangItem)] { - desc { "calculating the lang items defined in a crate" } - separate_provide_extern - } - - /// Returns the diagnostic items defined in a crate. - query diagnostic_items(_: CrateNum) -> &'tcx rustc_hir::diagnostic_items::DiagnosticItems { - arena_cache - desc { "calculating the diagnostic items map in a crate" } - separate_provide_extern - } - - query missing_lang_items(_: CrateNum) -> &'tcx [LangItem] { - desc { "calculating the missing lang items in a crate" } - separate_provide_extern - } - - /// The visible parent map is a map from every item to a visible parent. - /// It prefers the shortest visible path to an item. - /// Used for diagnostics, for example path trimming. - /// The parents are modules, enums or traits. - query visible_parent_map(_: ()) -> &'tcx DefIdMap<DefId> { - arena_cache - desc { "calculating the visible parent map" } - } - /// Collects the "trimmed", shortest accessible paths to all items for diagnostics. - /// See the [provider docs](`rustc_middle::ty::print::trimmed_def_paths`) for more info. - query trimmed_def_paths(_: ()) -> &'tcx DefIdMap<Symbol> { - arena_cache - desc { "calculating trimmed def paths" } - } - query missing_extern_crate_item(_: CrateNum) -> bool { - eval_always - desc { "seeing if we're missing an `extern crate` item for this crate" } - separate_provide_extern - } - query used_crate_source(_: CrateNum) -> &'tcx Arc<CrateSource> { - arena_cache - eval_always - desc { "looking at the source for a crate" } - separate_provide_extern - } - - /// Returns the debugger visualizers defined for this crate. - /// NOTE: This query has to be marked `eval_always` because it reads data - /// directly from disk that is not tracked anywhere else. I.e. it - /// represents a genuine input to the query system. - query debugger_visualizers(_: CrateNum) -> &'tcx Vec<DebuggerVisualizerFile> { - arena_cache - desc { "looking up the debugger visualizers for this crate" } - separate_provide_extern - eval_always - } - - query postorder_cnums(_: ()) -> &'tcx [CrateNum] { - eval_always - desc { "generating a postorder list of CrateNums" } - } - /// Returns whether or not the crate with CrateNum 'cnum' - /// is marked as a private dependency - query is_private_dep(c: CrateNum) -> bool { - eval_always - desc { "checking whether crate `{}` is a private dependency", c } - separate_provide_extern - } - query allocator_kind(_: ()) -> Option<AllocatorKind> { - eval_always - desc { "getting the allocator kind for the current crate" } - } - query alloc_error_handler_kind(_: ()) -> Option<AllocatorKind> { - eval_always - desc { "alloc error handler kind for the current crate" } - } - - query upvars_mentioned(def_id: DefId) -> Option<&'tcx FxIndexMap<hir::HirId, hir::Upvar>> { - desc { |tcx| "collecting upvars mentioned in `{}`", tcx.def_path_str(def_id) } - } - - /// All available crates in the graph, including those that should not be user-facing - /// (such as private crates). - query crates(_: ()) -> &'tcx [CrateNum] { - eval_always - desc { "fetching all foreign CrateNum instances" } - } - - // Crates that are loaded non-speculatively (not for diagnostics or doc links). - // FIXME: This is currently only used for collecting lang items, but should be used instead of - // `crates` in most other cases too. - query used_crates(_: ()) -> &'tcx [CrateNum] { - eval_always - desc { "fetching `CrateNum`s for all crates loaded non-speculatively" } - } - - /// All crates that share the same name as crate `c`. - /// - /// This normally occurs when multiple versions of the same dependency are present in the - /// dependency tree. - query duplicate_crate_names(c: CrateNum) -> &'tcx [CrateNum] { - desc { "fetching `CrateNum`s with same name as `{c:?}`" } - } - - /// A list of all traits in a crate, used by rustdoc and error reporting. - query traits(_: CrateNum) -> &'tcx [DefId] { - desc { "fetching all traits in a crate" } - separate_provide_extern - } - - query trait_impls_in_crate(_: CrateNum) -> &'tcx [DefId] { - desc { "fetching all trait impls in a crate" } - separate_provide_extern - } - - query stable_order_of_exportable_impls(_: CrateNum) -> &'tcx FxIndexMap<DefId, usize> { - desc { "fetching the stable impl's order" } - separate_provide_extern - } - - query exportable_items(_: CrateNum) -> &'tcx [DefId] { - desc { "fetching all exportable items in a crate" } - separate_provide_extern - } - - /// The list of non-generic symbols exported from the given crate. - /// - /// This is separate from exported_generic_symbols to avoid having - /// to deserialize all non-generic symbols too for upstream crates - /// in the upstream_monomorphizations query. - /// - /// - All names contained in `exported_non_generic_symbols(cnum)` are - /// guaranteed to correspond to a publicly visible symbol in `cnum` - /// machine code. - /// - The `exported_non_generic_symbols` and `exported_generic_symbols` - /// sets of different crates do not intersect. - query exported_non_generic_symbols(cnum: CrateNum) -> &'tcx [(ExportedSymbol<'tcx>, SymbolExportInfo)] { - desc { "collecting exported non-generic symbols for crate `{}`", cnum} - cache_on_disk_if { *cnum == LOCAL_CRATE } - separate_provide_extern - } - - /// The list of generic symbols exported from the given crate. - /// - /// - All names contained in `exported_generic_symbols(cnum)` are - /// guaranteed to correspond to a publicly visible symbol in `cnum` - /// machine code. - /// - The `exported_non_generic_symbols` and `exported_generic_symbols` - /// sets of different crates do not intersect. - query exported_generic_symbols(cnum: CrateNum) -> &'tcx [(ExportedSymbol<'tcx>, SymbolExportInfo)] { - desc { "collecting exported generic symbols for crate `{}`", cnum} - cache_on_disk_if { *cnum == LOCAL_CRATE } - separate_provide_extern - } - - query collect_and_partition_mono_items(_: ()) -> MonoItemPartitions<'tcx> { - eval_always - desc { "collect_and_partition_mono_items" } - } - - query is_codegened_item(def_id: DefId) -> bool { - desc { |tcx| "determining whether `{}` needs codegen", tcx.def_path_str(def_id) } - } - - query codegen_unit(sym: Symbol) -> &'tcx CodegenUnit<'tcx> { - desc { "getting codegen unit `{sym}`" } - } - - query backend_optimization_level(_: ()) -> OptLevel { - desc { "optimization level used by backend" } - } - - /// Return the filenames where output artefacts shall be stored. - /// - /// This query returns an `&Arc` because codegen backends need the value even after the `TyCtxt` - /// has been destroyed. - query output_filenames(_: ()) -> &'tcx Arc<OutputFilenames> { - feedable - desc { "getting output filenames" } - arena_cache - } - - /// <div class="warning"> - /// - /// Do not call this query directly: Invoke `normalize` instead. - /// - /// </div> - query normalize_canonicalized_projection( - goal: CanonicalAliasGoal<'tcx> - ) -> Result< - &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, NormalizationResult<'tcx>>>, - NoSolution, - > { - desc { "normalizing `{}`", goal.canonical.value.value } - } - - /// <div class="warning"> - /// - /// Do not call this query directly: Invoke `normalize` instead. - /// - /// </div> - query normalize_canonicalized_free_alias( - goal: CanonicalAliasGoal<'tcx> - ) -> Result< - &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, NormalizationResult<'tcx>>>, - NoSolution, - > { - desc { "normalizing `{}`", goal.canonical.value.value } - } - - /// <div class="warning"> - /// - /// Do not call this query directly: Invoke `normalize` instead. - /// - /// </div> - query normalize_canonicalized_inherent_projection( - goal: CanonicalAliasGoal<'tcx> - ) -> Result< - &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, NormalizationResult<'tcx>>>, - NoSolution, - > { - desc { "normalizing `{}`", goal.canonical.value.value } - } - - /// Do not call this query directly: invoke `try_normalize_erasing_regions` instead. - query try_normalize_generic_arg_after_erasing_regions( - goal: PseudoCanonicalInput<'tcx, GenericArg<'tcx>> - ) -> Result<GenericArg<'tcx>, NoSolution> { - desc { "normalizing `{}`", goal.value } - } - - query implied_outlives_bounds( - key: (CanonicalImpliedOutlivesBoundsGoal<'tcx>, bool) - ) -> Result< - &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, Vec<OutlivesBound<'tcx>>>>, - NoSolution, - > { - desc { "computing implied outlives bounds for `{}` (hack disabled = {:?})", key.0.canonical.value.value.ty, key.1 } - } - - /// Do not call this query directly: - /// invoke `DropckOutlives::new(dropped_ty)).fully_perform(typeck.infcx)` instead. - query dropck_outlives( - goal: CanonicalDropckOutlivesGoal<'tcx> - ) -> Result< - &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, DropckOutlivesResult<'tcx>>>, - NoSolution, - > { - desc { "computing dropck types for `{}`", goal.canonical.value.value.dropped_ty } - } - - /// Do not call this query directly: invoke `infcx.predicate_may_hold()` or - /// `infcx.predicate_must_hold()` instead. - query evaluate_obligation( - goal: CanonicalPredicateGoal<'tcx> - ) -> Result<EvaluationResult, OverflowError> { - desc { "evaluating trait selection obligation `{}`", goal.canonical.value.value } - } - - /// Do not call this query directly: part of the `Eq` type-op - query type_op_ascribe_user_type( - goal: CanonicalTypeOpAscribeUserTypeGoal<'tcx> - ) -> Result< - &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ()>>, - NoSolution, - > { - desc { "evaluating `type_op_ascribe_user_type` `{:?}`", goal.canonical.value.value } - } - - /// Do not call this query directly: part of the `ProvePredicate` type-op - query type_op_prove_predicate( - goal: CanonicalTypeOpProvePredicateGoal<'tcx> - ) -> Result< - &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ()>>, - NoSolution, - > { - desc { "evaluating `type_op_prove_predicate` `{:?}`", goal.canonical.value.value } - } - - /// Do not call this query directly: part of the `Normalize` type-op - query type_op_normalize_ty( - goal: CanonicalTypeOpNormalizeGoal<'tcx, Ty<'tcx>> - ) -> Result< - &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, Ty<'tcx>>>, - NoSolution, - > { - desc { "normalizing `{}`", goal.canonical.value.value.value } - } - - /// Do not call this query directly: part of the `Normalize` type-op - query type_op_normalize_clause( - goal: CanonicalTypeOpNormalizeGoal<'tcx, ty::Clause<'tcx>> - ) -> Result< - &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ty::Clause<'tcx>>>, - NoSolution, - > { - desc { "normalizing `{:?}`", goal.canonical.value.value.value } - } - - /// Do not call this query directly: part of the `Normalize` type-op - query type_op_normalize_poly_fn_sig( - goal: CanonicalTypeOpNormalizeGoal<'tcx, ty::PolyFnSig<'tcx>> - ) -> Result< - &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ty::PolyFnSig<'tcx>>>, - NoSolution, - > { - desc { "normalizing `{:?}`", goal.canonical.value.value.value } - } - - /// Do not call this query directly: part of the `Normalize` type-op - query type_op_normalize_fn_sig( - goal: CanonicalTypeOpNormalizeGoal<'tcx, ty::FnSig<'tcx>> - ) -> Result< - &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ty::FnSig<'tcx>>>, - NoSolution, - > { - desc { "normalizing `{:?}`", goal.canonical.value.value.value } - } - - query instantiate_and_check_impossible_predicates(key: (DefId, GenericArgsRef<'tcx>)) -> bool { - desc { |tcx| - "checking impossible instantiated predicates: `{}`", - tcx.def_path_str(key.0) - } - } - - query is_impossible_associated_item(key: (DefId, DefId)) -> bool { - desc { |tcx| - "checking if `{}` is impossible to reference within `{}`", - tcx.def_path_str(key.1), - tcx.def_path_str(key.0), - } - } - - query method_autoderef_steps( - goal: CanonicalMethodAutoderefStepsGoal<'tcx> - ) -> MethodAutoderefStepsResult<'tcx> { - desc { "computing autoderef types for `{}`", goal.canonical.value.value.self_ty } - } - - /// Used by `-Znext-solver` to compute proof trees. - query evaluate_root_goal_for_proof_tree_raw( - goal: solve::CanonicalInput<'tcx>, - ) -> (solve::QueryResult<'tcx>, &'tcx solve::inspect::Probe<TyCtxt<'tcx>>) { - no_hash - desc { "computing proof tree for `{}`", goal.canonical.value.goal.predicate } - } - - /// Returns the Rust target features for the current target. These are not always the same as LLVM target features! - query rust_target_features(_: CrateNum) -> &'tcx UnordMap<String, rustc_target::target_features::Stability> { - arena_cache - eval_always - desc { "looking up Rust target features" } - } - - query implied_target_features(feature: Symbol) -> &'tcx Vec<Symbol> { - arena_cache - eval_always - desc { "looking up implied target features" } - } - - query features_query(_: ()) -> &'tcx rustc_feature::Features { - feedable - desc { "looking up enabled feature gates" } - } - - query crate_for_resolver((): ()) -> &'tcx Steal<(rustc_ast::Crate, rustc_ast::AttrVec)> { - feedable - no_hash - desc { "the ast before macro expansion and name resolution" } - } - - /// Attempt to resolve the given `DefId` to an `Instance`, for the - /// given generics args (`GenericArgsRef`), returning one of: - /// * `Ok(Some(instance))` on success - /// * `Ok(None)` when the `GenericArgsRef` are still too generic, - /// and therefore don't allow finding the final `Instance` - /// * `Err(ErrorGuaranteed)` when the `Instance` resolution process - /// couldn't complete due to errors elsewhere - this is distinct - /// from `Ok(None)` to avoid misleading diagnostics when an error - /// has already been/will be emitted, for the original cause. - query resolve_instance_raw( - key: ty::PseudoCanonicalInput<'tcx, (DefId, GenericArgsRef<'tcx>)> - ) -> Result<Option<ty::Instance<'tcx>>, ErrorGuaranteed> { - desc { "resolving instance `{}`", ty::Instance::new_raw(key.value.0, key.value.1) } - } - - query reveal_opaque_types_in_bounds(key: ty::Clauses<'tcx>) -> ty::Clauses<'tcx> { - desc { "revealing opaque types in `{:?}`", key } - } - - query limits(key: ()) -> Limits { - desc { "looking up limits" } - } - - /// Performs an HIR-based well-formed check on the item with the given `HirId`. If - /// we get an `Unimplemented` error that matches the provided `Predicate`, return - /// the cause of the newly created obligation. - /// - /// This is only used by error-reporting code to get a better cause (in particular, a better - /// span) for an *existing* error. Therefore, it is best-effort, and may never handle - /// all of the cases that the normal `ty::Ty`-based wfcheck does. This is fine, - /// because the `ty::Ty`-based wfcheck is always run. - query diagnostic_hir_wf_check( - key: (ty::Predicate<'tcx>, WellFormedLoc) - ) -> Option<&'tcx ObligationCause<'tcx>> { - arena_cache - eval_always - no_hash - desc { "performing HIR wf-checking for predicate `{:?}` at item `{:?}`", key.0, key.1 } - } - - /// The list of backend features computed from CLI flags (`-Ctarget-cpu`, `-Ctarget-feature`, - /// `--target` and similar). - query global_backend_features(_: ()) -> &'tcx Vec<String> { - arena_cache - eval_always - desc { "computing the backend features for CLI flags" } - } - - query check_validity_requirement(key: (ValidityRequirement, ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>)) -> Result<bool, &'tcx ty::layout::LayoutError<'tcx>> { - desc { "checking validity requirement for `{}`: {}", key.1.value, key.0 } - } - - /// This takes the def-id of an associated item from a impl of a trait, - /// and checks its validity against the trait item it corresponds to. - /// - /// Any other def id will ICE. - query compare_impl_item(key: LocalDefId) -> Result<(), ErrorGuaranteed> { - desc { |tcx| "checking assoc item `{}` is compatible with trait definition", tcx.def_path_str(key) } - return_result_from_ensure_ok - } - - query deduced_param_attrs(def_id: DefId) -> &'tcx [DeducedParamAttrs] { - desc { |tcx| "deducing parameter attributes for {}", tcx.def_path_str(def_id) } - separate_provide_extern - } - - query doc_link_resolutions(def_id: DefId) -> &'tcx DocLinkResMap { - eval_always - desc { "resolutions for documentation links for a module" } - separate_provide_extern - } - - query doc_link_traits_in_scope(def_id: DefId) -> &'tcx [DefId] { - eval_always - desc { "traits in scope for documentation links for a module" } - separate_provide_extern - } - - /// Get all item paths that were stripped by a `#[cfg]` in a particular crate. - /// Should not be called for the local crate before the resolver outputs are created, as it - /// is only fed there. - query stripped_cfg_items(cnum: CrateNum) -> &'tcx [StrippedCfgItem] { - desc { "getting cfg-ed out item names" } - separate_provide_extern - } - - query generics_require_sized_self(def_id: DefId) -> bool { - desc { "check whether the item has a `where Self: Sized` bound" } - } - - query cross_crate_inlinable(def_id: DefId) -> bool { - desc { "whether the item should be made inlinable across crates" } - separate_provide_extern - } - - /// Perform monomorphization-time checking on this item. - /// This is used for lints/errors that can only be checked once the instance is fully - /// monomorphized. - query check_mono_item(key: ty::Instance<'tcx>) { - desc { "monomorphization-time checking" } - } - - /// Builds the set of functions that should be skipped for the move-size check. - query skip_move_check_fns(_: ()) -> &'tcx FxIndexSet<DefId> { - arena_cache - desc { "functions to skip for move-size check" } - } - - query items_of_instance(key: (ty::Instance<'tcx>, CollectionMode)) -> Result<(&'tcx [Spanned<MonoItem<'tcx>>], &'tcx [Spanned<MonoItem<'tcx>>]), NormalizationErrorInMono> { - desc { "collecting items used by `{}`", key.0 } - cache_on_disk_if { true } - } - - query size_estimate(key: ty::Instance<'tcx>) -> usize { - desc { "estimating codegen size of `{}`", key } - cache_on_disk_if { true } - } - - query anon_const_kind(def_id: DefId) -> ty::AnonConstKind { - desc { |tcx| "looking up anon const kind of `{}`", tcx.def_path_str(def_id) } - separate_provide_extern - } - - query trivial_const(def_id: DefId) -> Option<(mir::ConstValue, Ty<'tcx>)> { - desc { |tcx| "checking if `{}` is a trivial const", tcx.def_path_str(def_id) } - cache_on_disk_if { def_id.is_local() } - separate_provide_extern - } - - /// Checks for the nearest `#[sanitize(xyz = "off")]` or - /// `#[sanitize(xyz = "on")]` on this def and any enclosing defs, up to the - /// crate root. - /// - /// Returns the sanitizer settings for this def. - query sanitizer_settings_for(key: LocalDefId) -> SanitizerFnAttrs { - desc { |tcx| "checking what set of sanitizers are enabled on `{}`", tcx.def_path_str(key) } - feedable - } - - query check_externally_implementable_items(_: ()) { - desc { "check externally implementable items" } - } - - /// Returns a list of all `externally implementable items` crate. - query externally_implementable_items(cnum: CrateNum) -> &'tcx FxIndexMap<DefId, (EiiDecl, FxIndexMap<DefId, EiiImpl>)> { - arena_cache - desc { "looking up the externally implementable items of a crate" } - cache_on_disk_if { *cnum == LOCAL_CRATE } - separate_provide_extern - } -} - -rustc_with_all_queries! { define_callbacks! } -rustc_feedable_queries! { define_feedable! } - -fn describe_as_module(def_id: impl Into<LocalDefId>, tcx: TyCtxt<'_>) -> String { +pub fn describe_as_module(def_id: impl Into<LocalDefId>, tcx: TyCtxt<'_>) -> String { let def_id = def_id.into(); if def_id.is_top_level_module() { "top-level module".to_string()
diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs index 78879dc..0b7dc30 100644 --- a/compiler/rustc_middle/src/query/plumbing.rs +++ b/compiler/rustc_middle/src/query/plumbing.rs
@@ -12,10 +12,10 @@ use crate::dep_graph; use crate::dep_graph::DepKind; -use crate::query::on_disk_cache::{CacheEncoder, EncodedDepNodeIndex, OnDiskCache}; -use crate::query::{ +use crate::queries::{ ExternProviders, PerQueryVTables, Providers, QueryArenas, QueryCaches, QueryEngine, QueryStates, }; +use crate::query::on_disk_cache::{CacheEncoder, EncodedDepNodeIndex, OnDiskCache}; use crate::ty::TyCtxt; pub type WillCacheOnDiskForKeyFn<'tcx, Key> = fn(tcx: TyCtxt<'tcx>, key: &Key) -> bool; @@ -189,8 +189,8 @@ macro_rules! query_ensure_select { } macro_rules! query_helper_param_ty { - (DefId) => { impl IntoQueryParam<DefId> }; - (LocalDefId) => { impl IntoQueryParam<LocalDefId> }; + (DefId) => { impl $crate::query::IntoQueryParam<DefId> }; + (LocalDefId) => { impl $crate::query::IntoQueryParam<LocalDefId> }; ($K:ty) => { $K }; } @@ -213,7 +213,7 @@ macro_rules! local_key_if_separate_extern { $($K)* }; ([(separate_provide_extern) $($rest:tt)*] $($K:tt)*) => { - <$($K)* as AsLocalKey>::LocalKey + <$($K)* as $crate::query::AsLocalKey>::LocalKey }; ([$other:tt $($modifiers:tt)*] $($K:tt)*) => { local_key_if_separate_extern!([$($modifiers)*] $($K)*) @@ -227,8 +227,8 @@ macro_rules! separate_provide_extern_decl { ([(separate_provide_extern) $($rest:tt)*][$name:ident]) => { for<'tcx> fn( TyCtxt<'tcx>, - queries::$name::Key<'tcx>, - ) -> queries::$name::ProvidedValue<'tcx> + $name::Key<'tcx>, + ) -> $name::ProvidedValue<'tcx> }; ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => { separate_provide_extern_decl!([$($modifiers)*][$($args)*]) @@ -266,94 +266,90 @@ macro_rules! define_callbacks { [$($modifiers:tt)*] fn $name:ident($($K:tt)*) -> $V:ty, )* ) => { + $(#[allow(unused_lifetimes)] pub mod $name { + use super::*; + use $crate::query::erase::{self, Erased}; - #[allow(unused_lifetimes)] - pub mod queries { - $(pub mod $name { - use super::super::*; - use $crate::query::erase::{self, Erased}; + pub type Key<'tcx> = $($K)*; + pub type Value<'tcx> = $V; - pub type Key<'tcx> = $($K)*; - pub type Value<'tcx> = $V; + pub type LocalKey<'tcx> = local_key_if_separate_extern!([$($modifiers)*] $($K)*); - pub type LocalKey<'tcx> = local_key_if_separate_extern!([$($modifiers)*] $($K)*); + /// This type alias specifies the type returned from query providers and the type + /// used for decoding. For regular queries this is the declared returned type `V`, + /// but `arena_cache` will use `<V as ArenaCached>::Provided` instead. + pub type ProvidedValue<'tcx> = query_if_arena!( + [$($modifiers)*] + (<$V as $crate::query::arena_cached::ArenaCached<'tcx>>::Provided) + ($V) + ); - /// This type alias specifies the type returned from query providers and the type - /// used for decoding. For regular queries this is the declared returned type `V`, - /// but `arena_cache` will use `<V as ArenaCached>::Provided` instead. - pub type ProvidedValue<'tcx> = query_if_arena!( - [$($modifiers)*] - (<$V as $crate::query::arena_cached::ArenaCached<'tcx>>::Provided) - ($V) - ); + /// This function takes `ProvidedValue` and converts it to an erased `Value` by + /// allocating it on an arena if the query has the `arena_cache` modifier. The + /// value is then erased and returned. This will happen when computing the query + /// using a provider or decoding a stored result. + #[inline(always)] + pub fn provided_to_erased<'tcx>( + _tcx: TyCtxt<'tcx>, + provided_value: ProvidedValue<'tcx>, + ) -> Erased<Value<'tcx>> { + // Store the provided value in an arena and get a reference + // to it, for queries with `arena_cache`. + let value: Value<'tcx> = query_if_arena!([$($modifiers)*] + { + use $crate::query::arena_cached::ArenaCached; - /// This function takes `ProvidedValue` and converts it to an erased `Value` by - /// allocating it on an arena if the query has the `arena_cache` modifier. The - /// value is then erased and returned. This will happen when computing the query - /// using a provider or decoding a stored result. - #[inline(always)] - pub fn provided_to_erased<'tcx>( - _tcx: TyCtxt<'tcx>, - provided_value: ProvidedValue<'tcx>, - ) -> Erased<Value<'tcx>> { - // Store the provided value in an arena and get a reference - // to it, for queries with `arena_cache`. - let value: Value<'tcx> = query_if_arena!([$($modifiers)*] - { - use $crate::query::arena_cached::ArenaCached; - - if mem::needs_drop::<<$V as ArenaCached<'tcx>>::Allocated>() { - <$V as ArenaCached>::alloc_in_arena( - |v| _tcx.query_system.arenas.$name.alloc(v), - provided_value, - ) - } else { - <$V as ArenaCached>::alloc_in_arena( - |v| _tcx.arena.dropless.alloc(v), - provided_value, - ) - } + if mem::needs_drop::<<$V as ArenaCached<'tcx>>::Allocated>() { + <$V as ArenaCached>::alloc_in_arena( + |v| _tcx.query_system.arenas.$name.alloc(v), + provided_value, + ) + } else { + <$V as ArenaCached>::alloc_in_arena( + |v| _tcx.arena.dropless.alloc(v), + provided_value, + ) } - // Otherwise, the provided value is the value. - (provided_value) - ); - erase::erase_val(value) + } + // Otherwise, the provided value is the value. + (provided_value) + ); + erase::erase_val(value) + } + + pub type Storage<'tcx> = <$($K)* as $crate::query::Key>::Cache<Erased<$V>>; + + // Ensure that keys grow no larger than 88 bytes by accident. + // Increase this limit if necessary, but do try to keep the size low if possible + #[cfg(target_pointer_width = "64")] + const _: () = { + if size_of::<Key<'static>>() > 88 { + panic!("{}", concat!( + "the query `", + stringify!($name), + "` has a key type `", + stringify!($($K)*), + "` that is too large" + )); } + }; - pub type Storage<'tcx> = <$($K)* as keys::Key>::Cache<Erased<$V>>; - - // Ensure that keys grow no larger than 88 bytes by accident. - // Increase this limit if necessary, but do try to keep the size low if possible - #[cfg(target_pointer_width = "64")] - const _: () = { - if size_of::<Key<'static>>() > 88 { - panic!("{}", concat!( - "the query `", - stringify!($name), - "` has a key type `", - stringify!($($K)*), - "` that is too large" - )); - } - }; - - // Ensure that values grow no larger than 64 bytes by accident. - // Increase this limit if necessary, but do try to keep the size low if possible - #[cfg(target_pointer_width = "64")] - #[cfg(not(feature = "rustc_randomized_layouts"))] - const _: () = { - if size_of::<Value<'static>>() > 64 { - panic!("{}", concat!( - "the query `", - stringify!($name), - "` has a value type `", - stringify!($V), - "` that is too large" - )); - } - }; - })* - } + // Ensure that values grow no larger than 64 bytes by accident. + // Increase this limit if necessary, but do try to keep the size low if possible + #[cfg(target_pointer_width = "64")] + #[cfg(not(feature = "rustc_randomized_layouts"))] + const _: () = { + if size_of::<Value<'static>>() > 64 { + panic!("{}", concat!( + "the query `", + stringify!($name), + "` has a value type `", + stringify!($V), + "` that is too large" + )); + } + }; + })* /// Holds per-query arenas for queries with the `arena_cache` modifier. #[derive(Default)] @@ -371,10 +367,10 @@ pub struct QueryArenas<'tcx> { #[derive(Default)] pub struct QueryCaches<'tcx> { - $($(#[$attr])* pub $name: queries::$name::Storage<'tcx>,)* + $($(#[$attr])* pub $name: $name::Storage<'tcx>,)* } - impl<'tcx> TyCtxtEnsureOk<'tcx> { + impl<'tcx> $crate::query::TyCtxtEnsureOk<'tcx> { $($(#[$attr])* #[inline(always)] pub fn $name( @@ -386,13 +382,13 @@ pub fn $name( self.tcx, self.tcx.query_system.fns.engine.$name, &self.tcx.query_system.caches.$name, - key.into_query_param(), + $crate::query::IntoQueryParam::into_query_param(key), false, ) })* } - impl<'tcx> TyCtxtEnsureDone<'tcx> { + impl<'tcx> $crate::query::TyCtxtEnsureDone<'tcx> { $($(#[$attr])* #[inline(always)] pub fn $name(self, key: query_helper_param_ty!($($K)*)) { @@ -400,7 +396,7 @@ pub fn $name(self, key: query_helper_param_ty!($($K)*)) { self.tcx, self.tcx.query_system.fns.engine.$name, &self.tcx.query_system.caches.$name, - key.into_query_param(), + $crate::query::IntoQueryParam::into_query_param(key), true, ); })* @@ -416,7 +412,7 @@ pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> $V })* } - impl<'tcx> TyCtxtAt<'tcx> { + impl<'tcx> $crate::query::TyCtxtAt<'tcx> { $($(#[$attr])* #[inline(always)] pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> $V @@ -428,7 +424,7 @@ pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> $V self.tcx.query_system.fns.engine.$name, &self.tcx.query_system.caches.$name, self.span, - key.into_query_param(), + $crate::query::IntoQueryParam::into_query_param(key), )) })* } @@ -438,22 +434,22 @@ pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> $V /// ("Per" just makes this pluralized name more visually distinct.) pub struct PerQueryVTables<'tcx> { $( - pub $name: ::rustc_middle::query::plumbing::QueryVTable<'tcx, queries::$name::Storage<'tcx>>, + pub $name: ::rustc_middle::query::plumbing::QueryVTable<'tcx, $name::Storage<'tcx>>, )* } #[derive(Default)] pub struct QueryStates<'tcx> { $( - pub $name: QueryState<'tcx, $($K)*>, + pub $name: $crate::query::QueryState<'tcx, $($K)*>, )* } pub struct Providers { $(pub $name: for<'tcx> fn( TyCtxt<'tcx>, - queries::$name::LocalKey<'tcx>, - ) -> queries::$name::ProvidedValue<'tcx>,)* + $name::LocalKey<'tcx>, + ) -> $name::ProvidedValue<'tcx>,)* } pub struct ExternProviders { @@ -490,8 +486,8 @@ pub struct QueryEngine { $(pub $name: for<'tcx> fn( TyCtxt<'tcx>, Span, - queries::$name::Key<'tcx>, - QueryMode, + $name::Key<'tcx>, + $crate::query::QueryMode, ) -> Option<$crate::query::erase::Erased<$V>>,)* } }; @@ -499,14 +495,14 @@ pub struct QueryEngine { macro_rules! define_feedable { ($($(#[$attr:meta])* [$($modifiers:tt)*] fn $name:ident($($K:tt)*) -> $V:ty,)*) => { - $(impl<'tcx, K: IntoQueryParam<$($K)*> + Copy> TyCtxtFeed<'tcx, K> { + $(impl<'tcx, K: $crate::query::IntoQueryParam<$($K)*> + Copy> TyCtxtFeed<'tcx, K> { $(#[$attr])* #[inline(always)] - pub fn $name(self, value: queries::$name::ProvidedValue<'tcx>) { + pub fn $name(self, value: $name::ProvidedValue<'tcx>) { let key = self.key().into_query_param(); let tcx = self.tcx; - let erased_value = queries::$name::provided_to_erased(tcx, value); + let erased_value = $name::provided_to_erased(tcx, value); let dep_kind: dep_graph::DepKind = dep_graph::dep_kinds::$name;
diff --git a/compiler/rustc_middle/src/util/mod.rs b/compiler/rustc_middle/src/util/mod.rs index d5076a2..0bbe385 100644 --- a/compiler/rustc_middle/src/util/mod.rs +++ b/compiler/rustc_middle/src/util/mod.rs
@@ -2,7 +2,7 @@ #[derive(Default, Copy, Clone)] pub struct Providers { - pub queries: crate::query::Providers, - pub extern_queries: crate::query::ExternProviders, + pub queries: crate::queries::Providers, + pub extern_queries: crate::queries::ExternProviders, pub hooks: crate::hooks::Providers, }
diff --git a/compiler/rustc_mir_dataflow/Cargo.toml b/compiler/rustc_mir_dataflow/Cargo.toml index 9621f9f..156caa7 100644 --- a/compiler/rustc_mir_dataflow/Cargo.toml +++ b/compiler/rustc_mir_dataflow/Cargo.toml
@@ -8,11 +8,10 @@ polonius-engine = "0.13.0" regex = "1" rustc_abi = { path = "../rustc_abi" } -rustc_ast = { path = "../rustc_ast" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } -rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_graphviz = { path = "../rustc_graphviz" } +rustc_hir = { path = "../rustc_hir" } rustc_index = { path = "../rustc_index" } rustc_macros = { path = "../rustc_macros" } rustc_middle = { path = "../rustc_middle" }
diff --git a/compiler/rustc_mir_dataflow/messages.ftl b/compiler/rustc_mir_dataflow/messages.ftl deleted file mode 100644 index 5698367..0000000 --- a/compiler/rustc_mir_dataflow/messages.ftl +++ /dev/null
@@ -1,29 +0,0 @@ -mir_dataflow_duplicate_values_for = - duplicate values for `{$name}` - -mir_dataflow_path_must_end_in_filename = - path must end in a filename - -mir_dataflow_peek_argument_not_a_local = - rustc_peek: argument was not a local - -mir_dataflow_peek_argument_untracked = - rustc_peek: argument untracked - -mir_dataflow_peek_bit_not_set = - rustc_peek: bit not set - -mir_dataflow_peek_must_be_not_temporary = - dataflow::sanity_check cannot feed a non-temp to rustc_peek - -mir_dataflow_peek_must_be_place_or_ref_place = - rustc_peek: argument expression must be either `place` or `&place` - -mir_dataflow_requires_an_argument = - `{$name}` requires an argument - -mir_dataflow_stop_after_dataflow_ended_compilation = - stop_after_dataflow ended compilation - -mir_dataflow_unknown_formatter = - unknown formatter
diff --git a/compiler/rustc_mir_dataflow/src/errors.rs b/compiler/rustc_mir_dataflow/src/errors.rs index cfacc0e..051c030 100644 --- a/compiler/rustc_mir_dataflow/src/errors.rs +++ b/compiler/rustc_mir_dataflow/src/errors.rs
@@ -1,70 +1,40 @@ use rustc_macros::Diagnostic; -use rustc_span::{Span, Symbol}; +use rustc_span::Span; #[derive(Diagnostic)] -#[diag(mir_dataflow_path_must_end_in_filename)] -pub(crate) struct PathMustEndInFilename { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(mir_dataflow_unknown_formatter)] -pub(crate) struct UnknownFormatter { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(mir_dataflow_duplicate_values_for)] -pub(crate) struct DuplicateValuesFor { - #[primary_span] - pub span: Span, - pub name: Symbol, -} - -#[derive(Diagnostic)] -#[diag(mir_dataflow_requires_an_argument)] -pub(crate) struct RequiresAnArgument { - #[primary_span] - pub span: Span, - pub name: Symbol, -} - -#[derive(Diagnostic)] -#[diag(mir_dataflow_stop_after_dataflow_ended_compilation)] +#[diag("stop_after_dataflow ended compilation")] pub(crate) struct StopAfterDataFlowEndedCompilation; #[derive(Diagnostic)] -#[diag(mir_dataflow_peek_must_be_place_or_ref_place)] +#[diag("rustc_peek: argument expression must be either `place` or `&place`")] pub(crate) struct PeekMustBePlaceOrRefPlace { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(mir_dataflow_peek_must_be_not_temporary)] +#[diag("dataflow::sanity_check cannot feed a non-temp to rustc_peek")] pub(crate) struct PeekMustBeNotTemporary { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(mir_dataflow_peek_bit_not_set)] +#[diag("rustc_peek: bit not set")] pub(crate) struct PeekBitNotSet { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(mir_dataflow_peek_argument_not_a_local)] +#[diag("rustc_peek: argument was not a local")] pub(crate) struct PeekArgumentNotALocal { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(mir_dataflow_peek_argument_untracked)] +#[diag("rustc_peek: argument untracked")] pub(crate) struct PeekArgumentUntracked { #[primary_span] pub span: Span,
diff --git a/compiler/rustc_mir_dataflow/src/framework/graphviz.rs b/compiler/rustc_mir_dataflow/src/framework/graphviz.rs index 22bff380..c4b9b4c 100644 --- a/compiler/rustc_mir_dataflow/src/framework/graphviz.rs +++ b/compiler/rustc_mir_dataflow/src/framework/graphviz.rs
@@ -7,6 +7,9 @@ use std::{io, ops, str}; use regex::Regex; +use rustc_graphviz as dot; +use rustc_hir::attrs::{AttributeKind, BorrowckGraphvizFormatKind, RustcMirKind}; +use rustc_hir::find_attr; use rustc_index::bit_set::DenseBitSet; use rustc_middle::mir::{ self, BasicBlock, Body, Location, MirDumper, graphviz_safe_def_name, traversal, @@ -14,17 +17,12 @@ use rustc_middle::ty::TyCtxt; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_span::def_id::DefId; -use rustc_span::{Symbol, sym}; use tracing::debug; -use {rustc_ast as ast, rustc_graphviz as dot}; use super::fmt::{DebugDiffWithAdapter, DebugWithAdapter, DebugWithContext}; use super::{ Analysis, CallReturnPlaces, Direction, Results, ResultsCursor, ResultsVisitor, visit_results, }; -use crate::errors::{ - DuplicateValuesFor, PathMustEndInFilename, RequiresAnArgument, UnknownFormatter, -}; /// Writes a DOT file containing the results of a dataflow analysis if the user requested it via /// `rustc_mir` attributes and `-Z dump-mir-dataflow`. The `Result` in and the `Results` out are @@ -43,10 +41,7 @@ pub(super) fn write_graphviz_results<'tcx, A>( use std::io::Write; let def_id = body.source.def_id(); - let Ok(attrs) = RustcMirAttrs::parse(tcx, def_id) else { - // Invalid `rustc_mir` attrs are reported in `RustcMirAttrs::parse` - return Ok(()); - }; + let attrs = RustcMirAttrs::parse(tcx, def_id); let file = try { match attrs.output_path(A::NAME) { @@ -72,10 +67,7 @@ pub(super) fn write_graphviz_results<'tcx, A>( Err(e) => return Err(e), }; - let style = match attrs.formatter { - Some(sym::two_phase) => OutputStyle::BeforeAndAfter, - _ => OutputStyle::AfterOnly, - }; + let style = attrs.formatter.unwrap_or(OutputStyle::AfterOnly); let mut buf = Vec::new(); @@ -98,71 +90,33 @@ pub(super) fn write_graphviz_results<'tcx, A>( #[derive(Default)] struct RustcMirAttrs { basename_and_suffix: Option<PathBuf>, - formatter: Option<Symbol>, + formatter: Option<OutputStyle>, } impl RustcMirAttrs { - fn parse(tcx: TyCtxt<'_>, def_id: DefId) -> Result<Self, ()> { - let mut result = Ok(()); + fn parse(tcx: TyCtxt<'_>, def_id: DefId) -> Self { let mut ret = RustcMirAttrs::default(); - let rustc_mir_attrs = tcx - .get_attrs(def_id, sym::rustc_mir) - .flat_map(|attr| attr.meta_item_list().into_iter().flat_map(|v| v.into_iter())); - - for attr in rustc_mir_attrs { - let attr_result = match attr.name() { - Some(name @ sym::borrowck_graphviz_postflow) => { - Self::set_field(&mut ret.basename_and_suffix, tcx, name, &attr, |s| { - let path = PathBuf::from(s.to_string()); - match path.file_name() { - Some(_) => Ok(path), - None => { - tcx.dcx().emit_err(PathMustEndInFilename { span: attr.span() }); - Err(()) + let attrs = tcx.get_all_attrs(def_id); + if let Some(rustc_mir_attrs) = find_attr!(attrs, AttributeKind::RustcMir(kind) => kind) { + for attr in rustc_mir_attrs { + match attr { + RustcMirKind::BorrowckGraphvizPostflow { path } => { + ret.basename_and_suffix = Some(path.clone()); + } + RustcMirKind::BorrowckGraphvizFormat { format } => { + ret.formatter = match format { + BorrowckGraphvizFormatKind::TwoPhase => { + Some(OutputStyle::BeforeAndAfter) } - } - }) - } - Some(name @ sym::borrowck_graphviz_format) => { - Self::set_field(&mut ret.formatter, tcx, name, &attr, |s| match s { - sym::two_phase => Ok(s), - _ => { - tcx.dcx().emit_err(UnknownFormatter { span: attr.span() }); - Err(()) - } - }) - } - _ => Ok(()), - }; - - result = result.and(attr_result); + }; + } + _ => (), + }; + } } - result.map(|()| ret) - } - - fn set_field<T>( - field: &mut Option<T>, - tcx: TyCtxt<'_>, - name: Symbol, - attr: &ast::MetaItemInner, - mapper: impl FnOnce(Symbol) -> Result<T, ()>, - ) -> Result<(), ()> { - if field.is_some() { - tcx.dcx().emit_err(DuplicateValuesFor { span: attr.span(), name }); - - return Err(()); - } - - if let Some(s) = attr.value_str() { - *field = Some(mapper(s)?); - Ok(()) - } else { - tcx.dcx() - .emit_err(RequiresAnArgument { span: attr.span(), name: attr.name().unwrap() }); - Err(()) - } + ret } /// Returns the path where dataflow results should be written, or `None`
diff --git a/compiler/rustc_mir_dataflow/src/lib.rs b/compiler/rustc_mir_dataflow/src/lib.rs index 485925e..5f1cf12 100644 --- a/compiler/rustc_mir_dataflow/src/lib.rs +++ b/compiler/rustc_mir_dataflow/src/lib.rs
@@ -34,8 +34,6 @@ mod un_derefer; pub mod value_analysis; -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } - pub struct MoveDataTypingEnv<'tcx> { pub move_data: MoveData<'tcx>, pub typing_env: ty::TypingEnv<'tcx>,
diff --git a/compiler/rustc_mir_dataflow/src/rustc_peek.rs b/compiler/rustc_mir_dataflow/src/rustc_peek.rs index a899ec1..1c5b383 100644 --- a/compiler/rustc_mir_dataflow/src/rustc_peek.rs +++ b/compiler/rustc_mir_dataflow/src/rustc_peek.rs
@@ -1,8 +1,8 @@ -use rustc_ast::MetaItem; +use rustc_hir::attrs::{AttributeKind, RustcMirKind}; +use rustc_hir::find_attr; use rustc_middle::mir::{self, Body, Local, Location}; use rustc_middle::ty::{self, Ty, TyCtxt}; -use rustc_span::def_id::DefId; -use rustc_span::{Span, Symbol, sym}; +use rustc_span::{Span, sym}; use tracing::{debug, info}; use crate::errors::{ @@ -14,52 +14,37 @@ use crate::move_paths::{HasMoveData, LookupResult, MoveData, MovePathIndex}; use crate::{Analysis, JoinSemiLattice, ResultsCursor}; -fn has_rustc_mir_with(tcx: TyCtxt<'_>, def_id: DefId, name: Symbol) -> Option<MetaItem> { - for attr in tcx.get_attrs(def_id, sym::rustc_mir) { - let items = attr.meta_item_list(); - for item in items.iter().flat_map(|l| l.iter()) { - match item.meta_item() { - Some(mi) if mi.has_name(name) => return Some(mi.clone()), - _ => continue, - } - } - } - None -} - pub fn sanity_check<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) { let def_id = body.source.def_id(); - if !tcx.has_attr(def_id, sym::rustc_mir) { - debug!("skipping rustc_peek::SanityCheck on {}", tcx.def_path_str(def_id)); - return; - } else { + let attrs = tcx.get_all_attrs(def_id); + if let Some(kind) = find_attr!(attrs, AttributeKind::RustcMir(kind) => kind) { + let move_data = MoveData::gather_moves(body, tcx, |_| true); debug!("running rustc_peek::SanityCheck on {}", tcx.def_path_str(def_id)); - } + if kind.contains(&RustcMirKind::PeekMaybeInit) { + let flow_inits = MaybeInitializedPlaces::new(tcx, body, &move_data) + .iterate_to_fixpoint(tcx, body, None) + .into_results_cursor(body); + sanity_check_via_rustc_peek(tcx, flow_inits); + } - let move_data = MoveData::gather_moves(body, tcx, |_| true); + if kind.contains(&RustcMirKind::PeekMaybeUninit) { + let flow_uninits = MaybeUninitializedPlaces::new(tcx, body, &move_data) + .iterate_to_fixpoint(tcx, body, None) + .into_results_cursor(body); + sanity_check_via_rustc_peek(tcx, flow_uninits); + } - if has_rustc_mir_with(tcx, def_id, sym::rustc_peek_maybe_init).is_some() { - let flow_inits = MaybeInitializedPlaces::new(tcx, body, &move_data) - .iterate_to_fixpoint(tcx, body, None) - .into_results_cursor(body); - sanity_check_via_rustc_peek(tcx, flow_inits); - } + if kind.contains(&RustcMirKind::PeekLiveness) { + let flow_liveness = + MaybeLiveLocals.iterate_to_fixpoint(tcx, body, None).into_results_cursor(body); + sanity_check_via_rustc_peek(tcx, flow_liveness); + } - if has_rustc_mir_with(tcx, def_id, sym::rustc_peek_maybe_uninit).is_some() { - let flow_uninits = MaybeUninitializedPlaces::new(tcx, body, &move_data) - .iterate_to_fixpoint(tcx, body, None) - .into_results_cursor(body); - sanity_check_via_rustc_peek(tcx, flow_uninits); - } - - if has_rustc_mir_with(tcx, def_id, sym::rustc_peek_liveness).is_some() { - let flow_liveness = - MaybeLiveLocals.iterate_to_fixpoint(tcx, body, None).into_results_cursor(body); - sanity_check_via_rustc_peek(tcx, flow_liveness); - } - - if has_rustc_mir_with(tcx, def_id, sym::stop_after_dataflow).is_some() { - tcx.dcx().emit_fatal(StopAfterDataFlowEndedCompilation); + if kind.contains(&RustcMirKind::StopAfterDataflow) { + tcx.dcx().emit_fatal(StopAfterDataFlowEndedCompilation); + } + } else { + debug!("skipping rustc_peek::SanityCheck on {}", tcx.def_path_str(def_id)); } }
diff --git a/compiler/rustc_mir_transform/src/coverage/spans.rs b/compiler/rustc_mir_transform/src/coverage/spans.rs index b1ce006..bdc861e 100644 --- a/compiler/rustc_mir_transform/src/coverage/spans.rs +++ b/compiler/rustc_mir_transform/src/coverage/spans.rs
@@ -55,12 +55,10 @@ pub(super) fn extract_refined_covspans<'tcx>( } // Each pushed covspan should have the same context as the body span. - // If it somehow doesn't, discard the covspan, or panic in debug builds. + // If it somehow doesn't, discard the covspan. if !body_span.eq_ctxt(covspan_span) { - debug_assert!( - false, - "span context mismatch: body_span={body_span:?}, covspan.span={covspan_span:?}" - ); + // FIXME(Zalathar): Investigate how and why this is triggered + // by `tests/coverage/macros/context-mismatch-issue-147339.rs`. return false; }
diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index f8ff461..ab89af2 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl
@@ -87,6 +87,10 @@ passes_deprecated_attribute = deprecated attribute must be paired with either stable or unstable attribute +passes_diagnostic_diagnostic_on_const_only_for_non_const_trait_impls = + `#[diagnostic::on_const]` can only be applied to non-const trait impls + .label = this is a const trait impl + passes_diagnostic_diagnostic_on_const_only_for_trait_impls = `#[diagnostic::on_const]` can only be applied to trait impls .label = not a trait impl
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index bd02bc5..4784456 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs
@@ -67,6 +67,13 @@ struct DiagnosticOnConstOnlyForTraitImpls { item_span: Span, } +#[derive(LintDiagnostic)] +#[diag(passes_diagnostic_diagnostic_on_const_only_for_non_const_trait_impls)] +struct DiagnosticOnConstOnlyForNonConstTraitImpls { + #[label] + item_span: Span, +} + fn target_from_impl_item<'tcx>(tcx: TyCtxt<'tcx>, impl_item: &hir::ImplItem<'_>) -> Target { match impl_item.kind { hir::ImplItemKind::Const(..) => Target::AssocConst, @@ -309,6 +316,7 @@ fn check_attributes( | AttributeKind::RustcLintUntrackedQueryInformation | AttributeKind::RustcMacroTransparency(_) | AttributeKind::RustcMain + | AttributeKind::RustcMir(_) | AttributeKind::RustcNeverReturnsNullPointer | AttributeKind::RustcNoImplicitAutorefs | AttributeKind::RustcNonConstTraitMethod @@ -629,7 +637,16 @@ fn check_diagnostic_on_const( if target == (Target::Impl { of_trait: true }) { match item.unwrap() { ItemLike::Item(it) => match it.expect_impl().constness { - Constness::Const => {} + Constness::Const => { + let item_span = self.tcx.hir_span(hir_id); + self.tcx.emit_node_span_lint( + MISPLACED_DIAGNOSTIC_ATTRIBUTES, + hir_id, + attr_span, + DiagnosticOnConstOnlyForNonConstTraitImpls { item_span }, + ); + return; + } Constness::NotConst => return, }, ItemLike::ForeignItem => {}
diff --git a/compiler/rustc_privacy/Cargo.toml b/compiler/rustc_privacy/Cargo.toml index c8bfdb9..ff59c19 100644 --- a/compiler/rustc_privacy/Cargo.toml +++ b/compiler/rustc_privacy/Cargo.toml
@@ -8,7 +8,6 @@ rustc_ast = { path = "../rustc_ast" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } -rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_hir = { path = "../rustc_hir" } rustc_macros = { path = "../rustc_macros" } rustc_middle = { path = "../rustc_middle" }
diff --git a/compiler/rustc_privacy/messages.ftl b/compiler/rustc_privacy/messages.ftl deleted file mode 100644 index 43c34a1..0000000 --- a/compiler/rustc_privacy/messages.ftl +++ /dev/null
@@ -1,39 +0,0 @@ -privacy_field_is_private = - {$len -> - [1] field - *[other] fields - } {$field_names} of {$variant_descr} `{$def_path_str}` {$len -> - [1] is - *[other] are - } private - .label = in this type -privacy_field_is_private_is_update_syntax_label = {$rest_len -> - [1] field - *[other] fields - } {$rest_field_names} {$rest_len -> - [1] is - *[other] are - } private -privacy_field_is_private_label = private field - -privacy_from_private_dep_in_public_interface = - {$kind} `{$descr}` from private dependency '{$krate}' in public interface - -privacy_in_public_interface = {$vis_descr} {$kind} `{$descr}` in public interface - .label = can't leak {$vis_descr} {$kind} - .visibility_label = `{$descr}` declared as {$vis_descr} - -privacy_item_is_private = {$kind} `{$descr}` is private - .label = private {$kind} - -privacy_private_interface_or_bounds_lint = {$ty_kind} `{$ty_descr}` is more private than the item `{$item_descr}` - .item_label = {$item_kind} `{$item_descr}` is reachable at visibility `{$item_vis_descr}` - .ty_note = but {$ty_kind} `{$ty_descr}` is only usable at visibility `{$ty_vis_descr}` - -privacy_report_effective_visibility = {$descr} - -privacy_unnameable_types_lint = {$kind} `{$descr}` is reachable but cannot be named - .label = reachable at visibility `{$reachable_vis}`, but can only be named at visibility `{$reexported_vis}` - -privacy_unnamed_item_is_private = {$kind} is private - .label = private {$kind}
diff --git a/compiler/rustc_privacy/src/errors.rs b/compiler/rustc_privacy/src/errors.rs index 4d1d58c..af4f0d6 100644 --- a/compiler/rustc_privacy/src/errors.rs +++ b/compiler/rustc_privacy/src/errors.rs
@@ -4,11 +4,17 @@ use rustc_span::{Span, Symbol}; #[derive(Diagnostic)] -#[diag(privacy_field_is_private, code = E0451)] +#[diag("{$len -> + [1] field + *[other] fields +} {$field_names} of {$variant_descr} `{$def_path_str}` {$len -> + [1] is + *[other] are +} private", code = E0451)] pub(crate) struct FieldIsPrivate { #[primary_span] pub span: MultiSpan, - #[label] + #[label("in this type")] pub struct_span: Option<Span>, pub field_names: String, pub variant_descr: &'static str, @@ -20,14 +26,22 @@ pub(crate) struct FieldIsPrivate { #[derive(Subdiagnostic)] pub(crate) enum FieldIsPrivateLabel { - #[label(privacy_field_is_private_is_update_syntax_label)] + #[label( + "{$rest_len -> + [1] field + *[other] fields + } {$rest_field_names} {$rest_len -> + [1] is + *[other] are + } private" + )] IsUpdateSyntax { #[primary_span] span: Span, rest_field_names: String, rest_len: usize, }, - #[label(privacy_field_is_private_label)] + #[label("private field")] Other { #[primary_span] span: Span, @@ -35,17 +49,17 @@ pub(crate) enum FieldIsPrivateLabel { } #[derive(Diagnostic)] -#[diag(privacy_item_is_private)] +#[diag("{$kind} `{$descr}` is private")] pub(crate) struct ItemIsPrivate<'a> { #[primary_span] - #[label] + #[label("private {$kind}")] pub span: Span, pub kind: &'a str, pub descr: DiagArgFromDisplay<'a>, } #[derive(Diagnostic)] -#[diag(privacy_unnamed_item_is_private)] +#[diag("{$kind} is private")] pub(crate) struct UnnamedItemIsPrivate { #[primary_span] pub span: Span, @@ -53,20 +67,20 @@ pub(crate) struct UnnamedItemIsPrivate { } #[derive(Diagnostic)] -#[diag(privacy_in_public_interface, code = E0446)] +#[diag("{$vis_descr} {$kind} `{$descr}` in public interface", code = E0446)] pub(crate) struct InPublicInterface<'a> { #[primary_span] - #[label] + #[label("can't leak {$vis_descr} {$kind}")] pub span: Span, pub vis_descr: &'static str, pub kind: &'a str, pub descr: DiagArgFromDisplay<'a>, - #[label(privacy_visibility_label)] + #[label("`{$descr}` declared as {$vis_descr}")] pub vis_span: Span, } #[derive(Diagnostic)] -#[diag(privacy_report_effective_visibility)] +#[diag("{$descr}")] pub(crate) struct ReportEffectiveVisibility { #[primary_span] pub span: Span, @@ -74,7 +88,7 @@ pub(crate) struct ReportEffectiveVisibility { } #[derive(LintDiagnostic)] -#[diag(privacy_from_private_dep_in_public_interface)] +#[diag("{$kind} `{$descr}` from private dependency '{$krate}' in public interface")] pub(crate) struct FromPrivateDependencyInPublicInterface<'a> { pub kind: &'a str, pub descr: DiagArgFromDisplay<'a>, @@ -82,9 +96,11 @@ pub(crate) struct FromPrivateDependencyInPublicInterface<'a> { } #[derive(LintDiagnostic)] -#[diag(privacy_unnameable_types_lint)] +#[diag("{$kind} `{$descr}` is reachable but cannot be named")] pub(crate) struct UnnameableTypesLint<'a> { - #[label] + #[label( + "reachable at visibility `{$reachable_vis}`, but can only be named at visibility `{$reexported_vis}`" + )] pub span: Span, pub kind: &'a str, pub descr: DiagArgFromDisplay<'a>, @@ -96,14 +112,14 @@ pub(crate) struct UnnameableTypesLint<'a> { // They will replace private-in-public errors and compatibility lints in future. // See https://rust-lang.github.io/rfcs/2145-type-privacy.html for more details. #[derive(LintDiagnostic)] -#[diag(privacy_private_interface_or_bounds_lint)] +#[diag("{$ty_kind} `{$ty_descr}` is more private than the item `{$item_descr}`")] pub(crate) struct PrivateInterfacesOrBoundsLint<'a> { - #[label(privacy_item_label)] + #[label("{$item_kind} `{$item_descr}` is reachable at visibility `{$item_vis_descr}`")] pub item_span: Span, pub item_kind: &'a str, pub item_descr: DiagArgFromDisplay<'a>, pub item_vis_descr: &'a str, - #[note(privacy_ty_note)] + #[note("but {$ty_kind} `{$ty_descr}` is only usable at visibility `{$ty_vis_descr}`")] pub ty_span: Span, pub ty_kind: &'a str, pub ty_descr: DiagArgFromDisplay<'a>,
diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 3336775..4a88ea0 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs
@@ -39,8 +39,6 @@ use rustc_span::{Ident, Span, Symbol, sym}; use tracing::debug; -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } - //////////////////////////////////////////////////////////////////////////////// // Generic infrastructure used to implement specific visitors below. ////////////////////////////////////////////////////////////////////////////////
diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs index bd69c99..baa3711 100644 --- a/compiler/rustc_query_impl/src/lib.rs +++ b/compiler/rustc_query_impl/src/lib.rs
@@ -13,11 +13,12 @@ use rustc_data_structures::sync::AtomicU64; use rustc_middle::arena::Arena; use rustc_middle::dep_graph::{self, DepKind, DepKindVTable, DepNodeIndex}; +use rustc_middle::queries::{ + self, ExternProviders, Providers, QueryCaches, QueryEngine, QueryStates, +}; +use rustc_middle::query::AsLocalKey; use rustc_middle::query::on_disk_cache::{CacheEncoder, EncodedDepNodeIndex, OnDiskCache}; use rustc_middle::query::plumbing::{QuerySystem, QuerySystemFns, QueryVTable}; -use rustc_middle::query::{ - AsLocalKey, ExternProviders, Providers, QueryCaches, QueryEngine, QueryStates, queries, -}; use rustc_middle::ty::TyCtxt; use rustc_query_system::Value; use rustc_query_system::dep_graph::SerializedDepNodeIndex;
diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index d1721f1f..b074a9c 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs
@@ -410,9 +410,8 @@ pub(crate) fn query_key_hash_verify<'tcx>( ) { let _timer = qcx.tcx.prof.generic_activity_with_arg("query_key_hash_verify_for", query.name()); - let mut map = UnordMap::default(); - let cache = query.query_cache(qcx); + let mut map = UnordMap::with_capacity(cache.len()); cache.iter(&mut |key, _, _| { let node = DepNode::construct(qcx.tcx, query.dep_kind(), key); if let Some(other_key) = map.insert(node, *key) { @@ -648,7 +647,7 @@ pub(crate) fn make_query_vtable<'tcx>() query_state: std::mem::offset_of!(QueryStates<'tcx>, $name), query_cache: std::mem::offset_of!(QueryCaches<'tcx>, $name), will_cache_on_disk_for_key_fn: should_ever_cache_on_disk!([$($modifiers)*] { - Some(::rustc_middle::query::cached::$name) + Some(queries::cached::$name) } { None }), @@ -672,7 +671,7 @@ pub(crate) fn make_query_vtable<'tcx>() try_load_from_disk_fn: should_ever_cache_on_disk!([$($modifiers)*] { Some(|tcx, key, prev_index, index| { // Check the `cache_on_disk_if` condition for this key. - if !::rustc_middle::query::cached::$name(tcx, key) { + if !queries::cached::$name(tcx, key) { return None; } @@ -687,7 +686,7 @@ pub(crate) fn make_query_vtable<'tcx>() }), is_loadable_from_disk_fn: should_ever_cache_on_disk!([$($modifiers)*] { Some(|tcx, key, index| -> bool { - ::rustc_middle::query::cached::$name(tcx, key) && + ::rustc_middle::queries::cached::$name(tcx, key) && $crate::plumbing::loadable_from_disk(tcx, index) }) } { @@ -747,7 +746,7 @@ pub(crate) fn gather_active_jobs<'tcx>( let make_frame = |tcx, key| { let kind = rustc_middle::dep_graph::dep_kinds::$name; let name = stringify!($name); - $crate::plumbing::create_query_frame(tcx, rustc_middle::query::descs::$name, key, kind, name) + $crate::plumbing::create_query_frame(tcx, queries::descs::$name, key, kind, name) }; // Call `gather_active_jobs_inner` to do the actual work. @@ -817,8 +816,8 @@ pub(crate) fn engine(incremental: bool) -> QueryEngine { } } - pub fn make_query_vtables<'tcx>() -> ::rustc_middle::query::PerQueryVTables<'tcx> { - ::rustc_middle::query::PerQueryVTables { + pub fn make_query_vtables<'tcx>() -> queries::PerQueryVTables<'tcx> { + queries::PerQueryVTables { $( $name: query_impl::$name::make_query_vtable(), )*
diff --git a/compiler/rustc_query_system/Cargo.toml b/compiler/rustc_query_system/Cargo.toml index 0ad8143..761a299 100644 --- a/compiler/rustc_query_system/Cargo.toml +++ b/compiler/rustc_query_system/Cargo.toml
@@ -11,7 +11,6 @@ rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_feature = { path = "../rustc_feature" } -rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_hashes = { path = "../rustc_hashes" } rustc_hir = { path = "../rustc_hir" } rustc_index = { path = "../rustc_index" }
diff --git a/compiler/rustc_query_system/messages.ftl b/compiler/rustc_query_system/messages.ftl deleted file mode 100644 index d2ab2d3..0000000 --- a/compiler/rustc_query_system/messages.ftl +++ /dev/null
@@ -1,30 +0,0 @@ -query_system_cycle = cycle detected when {$stack_bottom} - .note = see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information - -query_system_cycle_recursive_trait_alias = trait aliases cannot be recursive - -query_system_cycle_recursive_ty_alias = type aliases cannot be recursive -query_system_cycle_recursive_ty_alias_help1 = consider using a struct, enum, or union instead to break the cycle -query_system_cycle_recursive_ty_alias_help2 = see <https://doc.rust-lang.org/reference/types.html#recursive-types> for more information - -query_system_cycle_stack_middle = ...which requires {$desc}... - -query_system_cycle_stack_multiple = ...which again requires {$stack_bottom}, completing the cycle - -query_system_cycle_stack_single = ...which immediately requires {$stack_bottom} again - -query_system_cycle_usage = cycle used when {$usage} - -query_system_increment_compilation = internal compiler error: encountered incremental compilation error with {$dep_node} - -query_system_increment_compilation_note1 = please follow the instructions below to create a bug report with the provided information -query_system_increment_compilation_note2 = for incremental compilation bugs, having a reproduction is vital -query_system_increment_compilation_note3 = an ideal reproduction consists of the code before and some patch that then triggers the bug when applied and compiled again -query_system_increment_compilation_note4 = as a workaround, you can run {$run_cmd} to allow your project to compile - -query_system_overflow_note = query depth increased by {$depth} when {$desc} - -query_system_query_overflow = queries overflow the depth limit! - .help = consider increasing the recursion limit by adding a `#![recursion_limit = "{$suggested_limit}"]` attribute to your crate (`{$crate_name}`) - -query_system_reentrant = internal compiler error: reentrant incremental verify failure, suppressing message
diff --git a/compiler/rustc_query_system/src/error.rs b/compiler/rustc_query_system/src/error.rs index 4b1effe..55f2feb 100644 --- a/compiler/rustc_query_system/src/error.rs +++ b/compiler/rustc_query_system/src/error.rs
@@ -4,7 +4,7 @@ use rustc_span::{Span, Symbol}; #[derive(Subdiagnostic)] -#[note(query_system_cycle_stack_middle)] +#[note("...which requires {$desc}...")] pub(crate) struct CycleStack { #[primary_span] pub span: Span, @@ -13,24 +13,26 @@ pub(crate) struct CycleStack { #[derive(Subdiagnostic)] pub(crate) enum StackCount { - #[note(query_system_cycle_stack_single)] + #[note("...which immediately requires {$stack_bottom} again")] Single, - #[note(query_system_cycle_stack_multiple)] + #[note("...which again requires {$stack_bottom}, completing the cycle")] Multiple, } #[derive(Subdiagnostic)] pub(crate) enum Alias { - #[note(query_system_cycle_recursive_ty_alias)] - #[help(query_system_cycle_recursive_ty_alias_help1)] - #[help(query_system_cycle_recursive_ty_alias_help2)] + #[note("type aliases cannot be recursive")] + #[help("consider using a struct, enum, or union instead to break the cycle")] + #[help( + "see <https://doc.rust-lang.org/reference/types.html#recursive-types> for more information" + )] Ty, - #[note(query_system_cycle_recursive_trait_alias)] + #[note("trait aliases cannot be recursive")] Trait, } #[derive(Subdiagnostic)] -#[note(query_system_cycle_usage)] +#[note("cycle used when {$usage}")] pub(crate) struct CycleUsage { #[primary_span] pub span: Span, @@ -38,7 +40,7 @@ pub(crate) struct CycleUsage { } #[derive(Diagnostic)] -#[diag(query_system_cycle, code = E0391)] +#[diag("cycle detected when {$stack_bottom}", code = E0391)] pub(crate) struct Cycle { #[primary_span] pub span: Span, @@ -51,28 +53,34 @@ pub(crate) struct Cycle { pub alias: Option<Alias>, #[subdiagnostic] pub cycle_usage: Option<CycleUsage>, - #[note] + #[note( + "see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information" + )] pub note_span: (), } #[derive(Diagnostic)] -#[diag(query_system_reentrant)] +#[diag("internal compiler error: reentrant incremental verify failure, suppressing message")] pub(crate) struct Reentrant; #[derive(Diagnostic)] -#[diag(query_system_increment_compilation)] -#[note(query_system_increment_compilation_note1)] -#[note(query_system_increment_compilation_note2)] -#[note(query_system_increment_compilation_note3)] -#[note(query_system_increment_compilation_note4)] +#[diag("internal compiler error: encountered incremental compilation error with {$dep_node}")] +#[note("please follow the instructions below to create a bug report with the provided information")] +#[note("for incremental compilation bugs, having a reproduction is vital")] +#[note( + "an ideal reproduction consists of the code before and some patch that then triggers the bug when applied and compiled again" +)] +#[note("as a workaround, you can run {$run_cmd} to allow your project to compile")] pub(crate) struct IncrementCompilation { pub run_cmd: String, pub dep_node: String, } #[derive(Diagnostic)] -#[help] -#[diag(query_system_query_overflow)] +#[help( + "consider increasing the recursion limit by adding a `#![recursion_limit = \"{$suggested_limit}\"]` attribute to your crate (`{$crate_name}`)" +)] +#[diag("queries overflow the depth limit!")] pub struct QueryOverflow { #[primary_span] pub span: Span, @@ -83,7 +91,7 @@ pub struct QueryOverflow { } #[derive(Subdiagnostic)] -#[note(query_system_overflow_note)] +#[note("query depth increased by {$depth} when {$desc}")] pub struct QueryOverflowNote { pub desc: String, pub depth: usize,
diff --git a/compiler/rustc_query_system/src/lib.rs b/compiler/rustc_query_system/src/lib.rs index cdfe345..d1907a8 100644 --- a/compiler/rustc_query_system/src/lib.rs +++ b/compiler/rustc_query_system/src/lib.rs
@@ -14,5 +14,3 @@ pub use error::{QueryOverflow, QueryOverflowNote}; pub use values::Value; - -rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
diff --git a/compiler/rustc_query_system/src/query/caches.rs b/compiler/rustc_query_system/src/query/caches.rs index 30b5d7e..67ad767 100644 --- a/compiler/rustc_query_system/src/query/caches.rs +++ b/compiler/rustc_query_system/src/query/caches.rs
@@ -30,6 +30,8 @@ pub trait QueryCache: Sized { fn complete(&self, key: Self::Key, value: Self::Value, index: DepNodeIndex); fn iter(&self, f: &mut dyn FnMut(&Self::Key, &Self::Value, DepNodeIndex)); + + fn len(&self) -> usize; } /// In-memory cache for queries whose keys aren't suitable for any of the @@ -71,6 +73,10 @@ fn iter(&self, f: &mut dyn FnMut(&Self::Key, &Self::Value, DepNodeIndex)) { } } } + + fn len(&self) -> usize { + self.cache.len() + } } /// In-memory cache for queries whose key type only has one value (e.g. `()`). @@ -107,6 +113,10 @@ fn iter(&self, f: &mut dyn FnMut(&Self::Key, &Self::Value, DepNodeIndex)) { f(&(), &value.0, value.1) } } + + fn len(&self) -> usize { + self.cache.get().is_some().into() + } } /// In-memory cache for queries whose key is a [`DefId`]. @@ -157,6 +167,10 @@ fn iter(&self, f: &mut dyn FnMut(&Self::Key, &Self::Value, DepNodeIndex)) { }); self.foreign.iter(f); } + + fn len(&self) -> usize { + self.local.len() + self.foreign.len() + } } impl<K, V> QueryCache for VecCache<K, V, DepNodeIndex> @@ -180,4 +194,8 @@ fn complete(&self, key: K, value: V, index: DepNodeIndex) { fn iter(&self, f: &mut dyn FnMut(&Self::Key, &Self::Value, DepNodeIndex)) { self.iter(f) } + + fn len(&self) -> usize { + self.len() + } }
diff --git a/compiler/rustc_session/Cargo.toml b/compiler/rustc_session/Cargo.toml index aebac38..d66e04f 100644 --- a/compiler/rustc_session/Cargo.toml +++ b/compiler/rustc_session/Cargo.toml
@@ -12,7 +12,6 @@ rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_feature = { path = "../rustc_feature" } -rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_fs_util = { path = "../rustc_fs_util" } rustc_hashes = { path = "../rustc_hashes" } rustc_hir = { path = "../rustc_hir" }
diff --git a/compiler/rustc_session/messages.ftl b/compiler/rustc_session/messages.ftl deleted file mode 100644 index 5c851cb..0000000 --- a/compiler/rustc_session/messages.ftl +++ /dev/null
@@ -1,149 +0,0 @@ -session_apple_deployment_target_invalid = - failed to parse deployment target specified in {$env_var}: {$error} - -session_apple_deployment_target_too_low = - deployment target in {$env_var} was set to {$version}, but the minimum supported by `rustc` is {$os_min} - -session_binary_float_literal_not_supported = binary float literal is not supported -session_branch_protection_requires_aarch64 = `-Zbranch-protection` is only supported on aarch64 - -session_cannot_enable_crt_static_linux = sanitizer is incompatible with statically linked libc, disable it using `-C target-feature=-crt-static` - -session_cannot_mix_and_match_sanitizers = `-Zsanitizer={$first}` is incompatible with `-Zsanitizer={$second}` - -session_cli_feature_diagnostic_help = - add `-Zcrate-attr="feature({$feature})"` to the command-line options to enable - -session_crate_name_empty = crate name must not be empty - -session_embed_source_insufficient_dwarf_version = `-Zembed-source=y` requires at least `-Z dwarf-version=5` but DWARF version is {$dwarf_version} - -session_embed_source_requires_debug_info = `-Zembed-source=y` requires debug information to be enabled - -session_expr_parentheses_needed = parentheses are required to parse this as an expression - -session_failed_to_create_profiler = failed to create profiler: {$err} - -session_feature_diagnostic_for_issue = - see issue #{$n} <https://github.com/rust-lang/rust/issues/{$n}> for more information - -session_feature_diagnostic_help = - add `#![feature({$feature})]` to the crate attributes to enable - -session_feature_diagnostic_suggestion = - add `#![feature({$feature})]` to the crate attributes to enable - -session_feature_suggest_upgrade_compiler = - this compiler was built on {$date}; consider upgrading it if it is out of date - -session_file_is_not_writeable = output file {$file} is not writeable -- check its permissions - -session_file_write_fail = failed to write `{$path}` due to error `{$err}` - -session_function_return_requires_x86_or_x86_64 = `-Zfunction-return` (except `keep`) is only supported on x86 and x86_64 - -session_function_return_thunk_extern_requires_non_large_code_model = `-Zfunction-return=thunk-extern` is only supported on non-large code models - -session_hexadecimal_float_literal_not_supported = hexadecimal float literal is not supported - -session_incompatible_linker_flavor = linker flavor `{$flavor}` is incompatible with the current target - .note = compatible flavors are: {$compatible_list} - -session_indirect_branch_cs_prefix_requires_x86_or_x86_64 = `-Zindirect-branch-cs-prefix` is only supported on x86 and x86_64 - -session_instrumentation_not_supported = {$us} instrumentation is not supported for this target - -session_int_literal_too_large = integer literal is too large - .note = value exceeds limit of `{$limit}` - -session_invalid_character_in_crate_name = invalid character {$character} in crate name: `{$crate_name}` - -session_invalid_float_literal_suffix = invalid suffix `{$suffix}` for float literal - .label = invalid suffix `{$suffix}` - .help = valid suffixes are `f32` and `f64` - -session_invalid_float_literal_width = invalid width `{$width}` for float literal - .help = valid widths are 32 and 64 - -session_invalid_int_literal_width = invalid width `{$width}` for integer literal - .help = valid widths are 8, 16, 32, 64 and 128 - -session_invalid_literal_suffix = suffixes on {$kind} literals are invalid - .label = invalid suffix `{$suffix}` - -session_invalid_num_literal_base_prefix = invalid base prefix for number literal - .note = base prefixes (`0xff`, `0b1010`, `0o755`) are lowercase - .suggestion = try making the prefix lowercase - -session_invalid_num_literal_suffix = invalid suffix `{$suffix}` for number literal - .label = invalid suffix `{$suffix}` - .help = the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.) - -session_linker_plugin_lto_windows_not_supported = linker plugin based LTO is not supported together with `-C prefer-dynamic` when targeting Windows-like targets - -session_must_be_name_of_associated_function = must be a name of an associated function - -session_not_circumvent_feature = `-Zunleash-the-miri-inside-of-you` may not be used to circumvent feature gates, except when testing error paths in the CTFE engine - -session_not_supported = not supported - -session_octal_float_literal_not_supported = octal float literal is not supported - -session_profile_sample_use_file_does_not_exist = file `{$path}` passed to `-C profile-sample-use` does not exist - -session_profile_use_file_does_not_exist = file `{$path}` passed to `-C profile-use` does not exist - -session_sanitizer_cfi_canonical_jump_tables_requires_cfi = `-Zsanitizer-cfi-canonical-jump-tables` requires `-Zsanitizer=cfi` - -session_sanitizer_cfi_generalize_pointers_requires_cfi = `-Zsanitizer-cfi-generalize-pointers` requires `-Zsanitizer=cfi` or `-Zsanitizer=kcfi` - -session_sanitizer_cfi_normalize_integers_requires_cfi = `-Zsanitizer-cfi-normalize-integers` requires `-Zsanitizer=cfi` or `-Zsanitizer=kcfi` - -session_sanitizer_cfi_requires_lto = `-Zsanitizer=cfi` requires `-Clto` or `-Clinker-plugin-lto` - -session_sanitizer_cfi_requires_single_codegen_unit = `-Zsanitizer=cfi` with `-Clto` requires `-Ccodegen-units=1` - -session_sanitizer_kcfi_arity_requires_kcfi = `-Zsanitizer-kcfi-arity` requires `-Zsanitizer=kcfi` - -session_sanitizer_kcfi_requires_panic_abort = `-Z sanitizer=kcfi` requires `-C panic=abort` - -session_sanitizer_not_supported = {$us} sanitizer is not supported for this target - -session_sanitizers_not_supported = {$us} sanitizers are not supported for this target - -session_skipping_const_checks = skipping const checks - -session_soft_float_deprecated = - `-Csoft-float` is unsound and deprecated; use a corresponding *eabi target instead - .note = it will be removed or ignored in a future version of Rust -session_soft_float_deprecated_issue = see issue #129893 <https://github.com/rust-lang/rust/issues/129893> for more information - -session_soft_float_ignored = - `-Csoft-float` is ignored on this target; it only has an effect on *eabihf targets - .note = this may become a hard error in a future version of Rust - -session_split_debuginfo_unstable_platform = `-Csplit-debuginfo={$debuginfo}` is unstable on this platform - -session_split_lto_unit_requires_lto = `-Zsplit-lto-unit` requires `-Clto`, `-Clto=thin`, or `-Clinker-plugin-lto` - -session_target_requires_unwind_tables = target requires unwind tables, they cannot be disabled with `-C force-unwind-tables=no` - -session_target_small_data_threshold_not_supported = `-Z small-data-threshold` is not supported for target {$target_triple} and will be ignored - -session_target_stack_protector_not_supported = `-Z stack-protector={$stack_protector}` is not supported for target {$target_triple} and will be ignored - -session_unexpected_builtin_cfg = unexpected `--cfg {$cfg}` flag - .controlled_by = config `{$cfg_name}` is only supposed to be controlled by `{$controlled_by}` - .incoherent = manually setting a built-in cfg can and does create incoherent behaviors - -session_unleashed_feature_help_named = skipping check for `{$gate}` feature -session_unleashed_feature_help_unnamed = skipping check that does not even have a feature gate - -session_unstable_virtual_function_elimination = `-Zvirtual-function-elimination` requires `-Clto` - -session_unsupported_dwarf_version = requested DWARF version {$dwarf_version} is not supported -session_unsupported_dwarf_version_help = supported DWARF versions are 2, 3, 4 and 5 - -session_unsupported_reg_struct_return_arch = `-Zreg-struct-return` is only supported on x86 -session_unsupported_regparm = `-Zregparm={$regparm}` is unsupported (valid values 0-3) -session_unsupported_regparm_arch = `-Zregparm=N` is only supported on x86
diff --git a/compiler/rustc_session/src/config/native_libs.rs b/compiler/rustc_session/src/config/native_libs.rs index 71d3e22..28e2d0f 100644 --- a/compiler/rustc_session/src/config/native_libs.rs +++ b/compiler/rustc_session/src/config/native_libs.rs
@@ -53,7 +53,9 @@ fn parse_native_lib(cx: &ParseNativeLibCx<'_>, value: &str) -> NativeLib { let NativeLibParts { kind, modifiers, name, new_name } = split_native_lib_value(value); let kind = kind.map_or(NativeLibKind::Unspecified, |kind| match kind { - "static" => NativeLibKind::Static { bundle: None, whole_archive: None }, + "static" => { + NativeLibKind::Static { bundle: None, whole_archive: None, export_symbols: None } + } "dylib" => NativeLibKind::Dylib { as_needed: None }, "framework" => NativeLibKind::Framework { as_needed: None }, "link-arg" => { @@ -105,7 +107,7 @@ fn parse_and_apply_modifier(cx: &ParseNativeLibCx<'_>, modifier: &str, native_li Some(("-", m)) => (m, false), _ => cx.early_dcx.early_fatal( "invalid linking modifier syntax, expected '+' or '-' prefix \ - before one of: bundle, verbatim, whole-archive, as-needed", + before one of: bundle, verbatim, whole-archive, as-needed, export-symbols", ), }; @@ -125,6 +127,13 @@ fn parse_and_apply_modifier(cx: &ParseNativeLibCx<'_>, modifier: &str, native_li ("bundle", _) => early_dcx .early_fatal("linking modifier `bundle` is only compatible with `static` linking kind"), + ("export-symbols", NativeLibKind::Static { export_symbols, .. }) => { + assign_modifier(export_symbols) + } + ("export-symbols", _) => early_dcx.early_fatal( + "linking modifier `export-symbols` is only compatible with `static` linking kind", + ), + ("verbatim", _) => assign_modifier(&mut native_lib.verbatim), ("whole-archive", NativeLibKind::Static { whole_archive, .. }) => { @@ -151,7 +160,7 @@ fn parse_and_apply_modifier(cx: &ParseNativeLibCx<'_>, modifier: &str, native_li _ => early_dcx.early_fatal(format!( "unknown linking modifier `{modifier}`, expected one \ - of: bundle, verbatim, whole-archive, as-needed" + of: bundle, verbatim, whole-archive, as-needed, export-symbols" )), } }
diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs index 54e792f..0c6a33f 100644 --- a/compiler/rustc_session/src/errors.rs +++ b/compiler/rustc_session/src/errors.rs
@@ -15,9 +15,11 @@ #[derive(Diagnostic)] pub(crate) enum AppleDeploymentTarget { - #[diag(session_apple_deployment_target_invalid)] + #[diag("failed to parse deployment target specified in {$env_var}: {$error}")] Invalid { env_var: &'static str, error: ParseIntError }, - #[diag(session_apple_deployment_target_too_low)] + #[diag( + "deployment target in {$env_var} was set to {$version}, but the minimum supported by `rustc` is {$os_min}" + )] TooLow { env_var: &'static str, version: String, os_min: String }, } @@ -34,13 +36,13 @@ fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G> { } #[derive(Subdiagnostic)] -#[note(session_feature_diagnostic_for_issue)] +#[note("see issue #{$n} <https://github.com/rust-lang/rust/issues/{$n}> for more information")] pub(crate) struct FeatureDiagnosticForIssue { pub(crate) n: NonZero<u32>, } #[derive(Subdiagnostic)] -#[note(session_feature_suggest_upgrade_compiler)] +#[note("this compiler was built on {$date}; consider upgrading it if it is out of date")] pub(crate) struct SuggestUpgradeCompiler { date: &'static str, } @@ -58,14 +60,14 @@ pub(crate) fn new() -> Option<Self> { } #[derive(Subdiagnostic)] -#[help(session_feature_diagnostic_help)] +#[help("add `#![feature({$feature})]` to the crate attributes to enable")] pub(crate) struct FeatureDiagnosticHelp { pub(crate) feature: Symbol, } #[derive(Subdiagnostic)] #[suggestion( - session_feature_diagnostic_suggestion, + "add `#![feature({$feature})]` to the crate attributes to enable", applicability = "maybe-incorrect", code = "#![feature({feature})]\n" )] @@ -76,169 +78,181 @@ pub struct FeatureDiagnosticSuggestion { } #[derive(Subdiagnostic)] -#[help(session_cli_feature_diagnostic_help)] +#[help("add `-Zcrate-attr=\"feature({$feature})\"` to the command-line options to enable")] pub(crate) struct CliFeatureDiagnosticHelp { pub(crate) feature: Symbol, } #[derive(Diagnostic)] -#[diag(session_must_be_name_of_associated_function)] +#[diag("must be a name of an associated function")] pub struct MustBeNameOfAssociatedFunction { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(session_not_circumvent_feature)] +#[diag( + "`-Zunleash-the-miri-inside-of-you` may not be used to circumvent feature gates, except when testing error paths in the CTFE engine" +)] pub(crate) struct NotCircumventFeature; #[derive(Diagnostic)] -#[diag(session_linker_plugin_lto_windows_not_supported)] +#[diag( + "linker plugin based LTO is not supported together with `-C prefer-dynamic` when targeting Windows-like targets" +)] pub(crate) struct LinkerPluginToWindowsNotSupported; #[derive(Diagnostic)] -#[diag(session_profile_use_file_does_not_exist)] +#[diag("file `{$path}` passed to `-C profile-use` does not exist")] pub(crate) struct ProfileUseFileDoesNotExist<'a> { pub(crate) path: &'a std::path::Path, } #[derive(Diagnostic)] -#[diag(session_profile_sample_use_file_does_not_exist)] +#[diag("file `{$path}` passed to `-C profile-sample-use` does not exist")] pub(crate) struct ProfileSampleUseFileDoesNotExist<'a> { pub(crate) path: &'a std::path::Path, } #[derive(Diagnostic)] -#[diag(session_target_requires_unwind_tables)] +#[diag("target requires unwind tables, they cannot be disabled with `-C force-unwind-tables=no`")] pub(crate) struct TargetRequiresUnwindTables; #[derive(Diagnostic)] -#[diag(session_instrumentation_not_supported)] +#[diag("{$us} instrumentation is not supported for this target")] pub(crate) struct InstrumentationNotSupported { pub(crate) us: String, } #[derive(Diagnostic)] -#[diag(session_sanitizer_not_supported)] +#[diag("{$us} sanitizer is not supported for this target")] pub(crate) struct SanitizerNotSupported { pub(crate) us: String, } #[derive(Diagnostic)] -#[diag(session_sanitizers_not_supported)] +#[diag("{$us} sanitizers are not supported for this target")] pub(crate) struct SanitizersNotSupported { pub(crate) us: String, } #[derive(Diagnostic)] -#[diag(session_cannot_mix_and_match_sanitizers)] +#[diag("`-Zsanitizer={$first}` is incompatible with `-Zsanitizer={$second}`")] pub(crate) struct CannotMixAndMatchSanitizers { pub(crate) first: String, pub(crate) second: String, } #[derive(Diagnostic)] -#[diag(session_cannot_enable_crt_static_linux)] +#[diag( + "sanitizer is incompatible with statically linked libc, disable it using `-C target-feature=-crt-static`" +)] pub(crate) struct CannotEnableCrtStaticLinux; #[derive(Diagnostic)] -#[diag(session_sanitizer_cfi_requires_lto)] +#[diag("`-Zsanitizer=cfi` requires `-Clto` or `-Clinker-plugin-lto`")] pub(crate) struct SanitizerCfiRequiresLto; #[derive(Diagnostic)] -#[diag(session_sanitizer_cfi_requires_single_codegen_unit)] +#[diag("`-Zsanitizer=cfi` with `-Clto` requires `-Ccodegen-units=1`")] pub(crate) struct SanitizerCfiRequiresSingleCodegenUnit; #[derive(Diagnostic)] -#[diag(session_sanitizer_cfi_canonical_jump_tables_requires_cfi)] +#[diag("`-Zsanitizer-cfi-canonical-jump-tables` requires `-Zsanitizer=cfi`")] pub(crate) struct SanitizerCfiCanonicalJumpTablesRequiresCfi; #[derive(Diagnostic)] -#[diag(session_sanitizer_cfi_generalize_pointers_requires_cfi)] +#[diag("`-Zsanitizer-cfi-generalize-pointers` requires `-Zsanitizer=cfi` or `-Zsanitizer=kcfi`")] pub(crate) struct SanitizerCfiGeneralizePointersRequiresCfi; #[derive(Diagnostic)] -#[diag(session_sanitizer_cfi_normalize_integers_requires_cfi)] +#[diag("`-Zsanitizer-cfi-normalize-integers` requires `-Zsanitizer=cfi` or `-Zsanitizer=kcfi`")] pub(crate) struct SanitizerCfiNormalizeIntegersRequiresCfi; #[derive(Diagnostic)] -#[diag(session_sanitizer_kcfi_arity_requires_kcfi)] +#[diag("`-Zsanitizer-kcfi-arity` requires `-Zsanitizer=kcfi`")] pub(crate) struct SanitizerKcfiArityRequiresKcfi; #[derive(Diagnostic)] -#[diag(session_sanitizer_kcfi_requires_panic_abort)] +#[diag("`-Z sanitizer=kcfi` requires `-C panic=abort`")] pub(crate) struct SanitizerKcfiRequiresPanicAbort; #[derive(Diagnostic)] -#[diag(session_split_lto_unit_requires_lto)] +#[diag("`-Zsplit-lto-unit` requires `-Clto`, `-Clto=thin`, or `-Clinker-plugin-lto`")] pub(crate) struct SplitLtoUnitRequiresLto; #[derive(Diagnostic)] -#[diag(session_unstable_virtual_function_elimination)] +#[diag("`-Zvirtual-function-elimination` requires `-Clto`")] pub(crate) struct UnstableVirtualFunctionElimination; #[derive(Diagnostic)] -#[diag(session_unsupported_dwarf_version)] -#[help(session_unsupported_dwarf_version_help)] +#[diag("requested DWARF version {$dwarf_version} is not supported")] +#[help("supported DWARF versions are 2, 3, 4 and 5")] pub(crate) struct UnsupportedDwarfVersion { pub(crate) dwarf_version: u32, } #[derive(Diagnostic)] -#[diag(session_embed_source_insufficient_dwarf_version)] +#[diag( + "`-Zembed-source=y` requires at least `-Z dwarf-version=5` but DWARF version is {$dwarf_version}" +)] pub(crate) struct EmbedSourceInsufficientDwarfVersion { pub(crate) dwarf_version: u32, } #[derive(Diagnostic)] -#[diag(session_embed_source_requires_debug_info)] +#[diag("`-Zembed-source=y` requires debug information to be enabled")] pub(crate) struct EmbedSourceRequiresDebugInfo; #[derive(Diagnostic)] -#[diag(session_target_stack_protector_not_supported)] +#[diag( + "`-Z stack-protector={$stack_protector}` is not supported for target {$target_triple} and will be ignored" +)] pub(crate) struct StackProtectorNotSupportedForTarget<'a> { pub(crate) stack_protector: StackProtector, pub(crate) target_triple: &'a TargetTuple, } #[derive(Diagnostic)] -#[diag(session_target_small_data_threshold_not_supported)] +#[diag( + "`-Z small-data-threshold` is not supported for target {$target_triple} and will be ignored" +)] pub(crate) struct SmallDataThresholdNotSupportedForTarget<'a> { pub(crate) target_triple: &'a TargetTuple, } #[derive(Diagnostic)] -#[diag(session_branch_protection_requires_aarch64)] +#[diag("`-Zbranch-protection` is only supported on aarch64")] pub(crate) struct BranchProtectionRequiresAArch64; #[derive(Diagnostic)] -#[diag(session_split_debuginfo_unstable_platform)] +#[diag("`-Csplit-debuginfo={$debuginfo}` is unstable on this platform")] pub(crate) struct SplitDebugInfoUnstablePlatform { pub(crate) debuginfo: SplitDebuginfo, } #[derive(Diagnostic)] -#[diag(session_file_is_not_writeable)] +#[diag("output file {$file} is not writeable -- check its permissions")] pub(crate) struct FileIsNotWriteable<'a> { pub(crate) file: &'a std::path::Path, } #[derive(Diagnostic)] -#[diag(session_file_write_fail)] +#[diag("failed to write `{$path}` due to error `{$err}`")] pub(crate) struct FileWriteFail<'a> { pub(crate) path: &'a std::path::Path, pub(crate) err: String, } #[derive(Diagnostic)] -#[diag(session_crate_name_empty)] +#[diag("crate name must not be empty")] pub(crate) struct CrateNameEmpty { #[primary_span] pub(crate) span: Option<Span>, } #[derive(Diagnostic)] -#[diag(session_invalid_character_in_crate_name)] +#[diag("invalid character {$character} in crate name: `{$crate_name}`")] pub(crate) struct InvalidCharacterInCrateName { #[primary_span] pub(crate) span: Option<Span>, @@ -247,7 +261,10 @@ pub(crate) struct InvalidCharacterInCrateName { } #[derive(Subdiagnostic)] -#[multipart_suggestion(session_expr_parentheses_needed, applicability = "machine-applicable")] +#[multipart_suggestion( + "parentheses are required to parse this as an expression", + applicability = "machine-applicable" +)] pub struct ExprParenthesesNeeded { #[suggestion_part(code = "(")] left: Span, @@ -262,7 +279,7 @@ pub fn surrounding(s: Span) -> Self { } #[derive(Diagnostic)] -#[diag(session_skipping_const_checks)] +#[diag("skipping const checks")] pub(crate) struct SkippingConstChecks { #[subdiagnostic] pub(crate) unleashed_features: Vec<UnleashedFeatureHelp>, @@ -270,13 +287,13 @@ pub(crate) struct SkippingConstChecks { #[derive(Subdiagnostic)] pub(crate) enum UnleashedFeatureHelp { - #[help(session_unleashed_feature_help_named)] + #[help("skipping check for `{$gate}` feature")] Named { #[primary_span] span: Span, gate: Symbol, }, - #[help(session_unleashed_feature_help_unnamed)] + #[help("skipping check that does not even have a feature gate")] Unnamed { #[primary_span] span: Span, @@ -284,10 +301,10 @@ pub(crate) enum UnleashedFeatureHelp { } #[derive(Diagnostic)] -#[diag(session_invalid_literal_suffix)] +#[diag("suffixes on {$kind} literals are invalid")] struct InvalidLiteralSuffix<'a> { #[primary_span] - #[label] + #[label("invalid suffix `{$suffix}`")] span: Span, // FIXME(#100717) kind: &'a str, @@ -295,8 +312,8 @@ struct InvalidLiteralSuffix<'a> { } #[derive(Diagnostic)] -#[diag(session_invalid_int_literal_width)] -#[help] +#[diag("invalid width `{$width}` for integer literal")] +#[help("valid widths are 8, 16, 32, 64 and 128")] struct InvalidIntLiteralWidth { #[primary_span] span: Span, @@ -304,28 +321,32 @@ struct InvalidIntLiteralWidth { } #[derive(Diagnostic)] -#[diag(session_invalid_num_literal_base_prefix)] -#[note] +#[diag("invalid base prefix for number literal")] +#[note("base prefixes (`0xff`, `0b1010`, `0o755`) are lowercase")] struct InvalidNumLiteralBasePrefix { #[primary_span] - #[suggestion(applicability = "maybe-incorrect", code = "{fixed}")] + #[suggestion( + "try making the prefix lowercase", + applicability = "maybe-incorrect", + code = "{fixed}" + )] span: Span, fixed: String, } #[derive(Diagnostic)] -#[diag(session_invalid_num_literal_suffix)] -#[help] +#[diag("invalid suffix `{$suffix}` for number literal")] +#[help("the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.)")] struct InvalidNumLiteralSuffix { #[primary_span] - #[label] + #[label("invalid suffix `{$suffix}`")] span: Span, suffix: String, } #[derive(Diagnostic)] -#[diag(session_invalid_float_literal_width)] -#[help] +#[diag("invalid width `{$width}` for float literal")] +#[help("valid widths are 32 and 64")] struct InvalidFloatLiteralWidth { #[primary_span] span: Span, @@ -333,18 +354,18 @@ struct InvalidFloatLiteralWidth { } #[derive(Diagnostic)] -#[diag(session_invalid_float_literal_suffix)] -#[help] +#[diag("invalid suffix `{$suffix}` for float literal")] +#[help("valid suffixes are `f32` and `f64`")] struct InvalidFloatLiteralSuffix { #[primary_span] - #[label] + #[label("invalid suffix `{$suffix}`")] span: Span, suffix: String, } #[derive(Diagnostic)] -#[diag(session_int_literal_too_large)] -#[note] +#[diag("integer literal is too large")] +#[note("value exceeds limit of `{$limit}`")] struct IntLiteralTooLarge { #[primary_span] span: Span, @@ -352,26 +373,26 @@ struct IntLiteralTooLarge { } #[derive(Diagnostic)] -#[diag(session_hexadecimal_float_literal_not_supported)] +#[diag("hexadecimal float literal is not supported")] struct HexadecimalFloatLiteralNotSupported { #[primary_span] - #[label(session_not_supported)] + #[label("not supported")] span: Span, } #[derive(Diagnostic)] -#[diag(session_octal_float_literal_not_supported)] +#[diag("octal float literal is not supported")] struct OctalFloatLiteralNotSupported { #[primary_span] - #[label(session_not_supported)] + #[label("not supported")] span: Span, } #[derive(Diagnostic)] -#[diag(session_binary_float_literal_not_supported)] +#[diag("binary float literal is not supported")] struct BinaryFloatLiteralNotSupported { #[primary_span] - #[label(session_not_supported)] + #[label("not supported")] span: Span, } @@ -457,60 +478,60 @@ fn fix_base_capitalisation(prefix: &str, suffix: &str) -> Option<String> { } #[derive(Diagnostic)] -#[diag(session_incompatible_linker_flavor)] -#[note] +#[diag("linker flavor `{$flavor}` is incompatible with the current target")] +#[note("compatible flavors are: {$compatible_list}")] pub(crate) struct IncompatibleLinkerFlavor { pub(crate) flavor: &'static str, pub(crate) compatible_list: String, } #[derive(Diagnostic)] -#[diag(session_function_return_requires_x86_or_x86_64)] +#[diag("`-Zfunction-return` (except `keep`) is only supported on x86 and x86_64")] pub(crate) struct FunctionReturnRequiresX86OrX8664; #[derive(Diagnostic)] -#[diag(session_function_return_thunk_extern_requires_non_large_code_model)] +#[diag("`-Zfunction-return=thunk-extern` is only supported on non-large code models")] pub(crate) struct FunctionReturnThunkExternRequiresNonLargeCodeModel; #[derive(Diagnostic)] -#[diag(session_indirect_branch_cs_prefix_requires_x86_or_x86_64)] +#[diag("`-Zindirect-branch-cs-prefix` is only supported on x86 and x86_64")] pub(crate) struct IndirectBranchCsPrefixRequiresX86OrX8664; #[derive(Diagnostic)] -#[diag(session_unsupported_regparm)] +#[diag("`-Zregparm={$regparm}` is unsupported (valid values 0-3)")] pub(crate) struct UnsupportedRegparm { pub(crate) regparm: u32, } #[derive(Diagnostic)] -#[diag(session_unsupported_regparm_arch)] +#[diag("`-Zregparm=N` is only supported on x86")] pub(crate) struct UnsupportedRegparmArch; #[derive(Diagnostic)] -#[diag(session_unsupported_reg_struct_return_arch)] +#[diag("`-Zreg-struct-return` is only supported on x86")] pub(crate) struct UnsupportedRegStructReturnArch; #[derive(Diagnostic)] -#[diag(session_failed_to_create_profiler)] +#[diag("failed to create profiler: {$err}")] pub(crate) struct FailedToCreateProfiler { pub(crate) err: String, } #[derive(Diagnostic)] -#[diag(session_soft_float_ignored)] -#[note] +#[diag("`-Csoft-float` is ignored on this target; it only has an effect on *eabihf targets")] +#[note("this may become a hard error in a future version of Rust")] pub(crate) struct SoftFloatIgnored; #[derive(Diagnostic)] -#[diag(session_soft_float_deprecated)] -#[note] -#[note(session_soft_float_deprecated_issue)] +#[diag("`-Csoft-float` is unsound and deprecated; use a corresponding *eabi target instead")] +#[note("it will be removed or ignored in a future version of Rust")] +#[note("see issue #129893 <https://github.com/rust-lang/rust/issues/129893> for more information")] pub(crate) struct SoftFloatDeprecated; #[derive(LintDiagnostic)] -#[diag(session_unexpected_builtin_cfg)] -#[note(session_controlled_by)] -#[note(session_incoherent)] +#[diag("unexpected `--cfg {$cfg}` flag")] +#[note("config `{$cfg_name}` is only supposed to be controlled by `{$controlled_by}`")] +#[note("manually setting a built-in cfg can and does create incoherent behaviors")] pub(crate) struct UnexpectedBuiltinCfg { pub(crate) cfg: String, pub(crate) cfg_name: Symbol,
diff --git a/compiler/rustc_session/src/lib.rs b/compiler/rustc_session/src/lib.rs index 90108e9..98731a2 100644 --- a/compiler/rustc_session/src/lib.rs +++ b/compiler/rustc_session/src/lib.rs
@@ -32,8 +32,6 @@ pub use getopts; -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } - /// Requirements for a `StableHashingContext` to be used in this crate. /// This is a hack to allow using the `HashStable_Generic` derive macro /// instead of implementing everything in `rustc_middle`.
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index b0ef95d..c88dd09 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs
@@ -1002,6 +1002,7 @@ explicit_tail_calls, export_name, export_stable, + export_symbols: "export-symbols", expr, expr_2021, expr_fragment_specifier_2024,
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 14e83cf..9799f3e 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs
@@ -3363,6 +3363,9 @@ fn load_file( Err(format!("could not find specification for target {target_tuple:?}")) } + TargetTuple::TargetJson { ref contents, .. } if !unstable_options => { + Err("custom targets are unstable and require `-Zunstable-options`".to_string()) + } TargetTuple::TargetJson { ref contents, .. } => Target::from_json(contents), } }
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index d54f381..22fa437 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
@@ -954,7 +954,9 @@ pub(super) fn check_for_binding_assigned_block_without_tail_expression( let new_obligation = self.mk_trait_obligation_with_new_self_ty(obligation.param_env, trait_pred_and_self); - if self.predicate_must_hold_modulo_regions(&new_obligation) { + if !matches!(tail_expr.kind, hir::ExprKind::Err(_)) + && self.predicate_must_hold_modulo_regions(&new_obligation) + { err.span_suggestion_short( stmt.span.with_lo(tail_expr.span.hi()), "remove this semicolon",
diff --git a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs index be70612..9371b55 100644 --- a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs +++ b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs
@@ -8,6 +8,7 @@ use rustc_errors::FatalError; use rustc_hir::attrs::AttributeKind; +use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; use rustc_hir::{self as hir, LangItem, find_attr}; use rustc_middle::query::Providers; @@ -833,8 +834,10 @@ fn visit_const(&mut self, ct: ty::Const<'tcx>) -> Self::Result { match ct.kind() { ty::ConstKind::Unevaluated(proj) if self.tcx.features().min_generic_const_args() => { match self.allow_self_projections { - AllowSelfProjections::Yes => { - let trait_def_id = self.tcx.parent(proj.def); + AllowSelfProjections::Yes + if let trait_def_id = self.tcx.parent(proj.def) + && self.tcx.def_kind(trait_def_id) == DefKind::Trait => + { let trait_ref = ty::TraitRef::from_assoc(self.tcx, trait_def_id, proj.args); // Only walk contained consts if the parent trait is not a supertrait. @@ -844,7 +847,7 @@ fn visit_const(&mut self, ct: ty::Const<'tcx>) -> Self::Result { ct.super_visit_with(self) } } - AllowSelfProjections::No => ct.super_visit_with(self), + _ => ct.super_visit_with(self), } } _ => ct.super_visit_with(self),
diff --git a/compiler/rustc_ty_utils/Cargo.toml b/compiler/rustc_ty_utils/Cargo.toml index ce08b30..682cf94 100644 --- a/compiler/rustc_ty_utils/Cargo.toml +++ b/compiler/rustc_ty_utils/Cargo.toml
@@ -9,7 +9,6 @@ rustc_abi = { path = "../rustc_abi" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } -rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_hashes = { path = "../rustc_hashes" } rustc_hir = { path = "../rustc_hir" } rustc_index = { path = "../rustc_index" }
diff --git a/compiler/rustc_ty_utils/messages.ftl b/compiler/rustc_ty_utils/messages.ftl deleted file mode 100644 index c1684bf..0000000 --- a/compiler/rustc_ty_utils/messages.ftl +++ /dev/null
@@ -1,61 +0,0 @@ -ty_utils_address_and_deref_not_supported = dereferencing or taking the address is not supported in generic constants - -ty_utils_adt_not_supported = struct/enum construction is not supported in generic constants - -ty_utils_array_not_supported = array construction is not supported in generic constants - -ty_utils_assign_not_supported = assignment is not supported in generic constants - -ty_utils_binary_not_supported = unsupported binary operation in generic constants - -ty_utils_block_not_supported = blocks are not supported in generic constants - -ty_utils_borrow_not_supported = borrowing is not supported in generic constants - -ty_utils_box_not_supported = allocations are not allowed in generic constants - -ty_utils_by_use_not_supported = .use is not allowed in generic constants - -ty_utils_closure_and_return_not_supported = closures and function keywords are not supported in generic constants - -ty_utils_const_block_not_supported = const blocks are not supported in generic constants - -ty_utils_control_flow_not_supported = control flow is not supported in generic constants - -ty_utils_field_not_supported = field access is not supported in generic constants - -ty_utils_generic_constant_too_complex = overly complex generic constant - .help = consider moving this anonymous constant into a `const` function - .maybe_supported = this operation may be supported in the future - -ty_utils_impl_trait_duplicate_arg = non-defining opaque type use in defining scope - .label = generic argument `{$arg}` used twice - .note = for this opaque type - -ty_utils_impl_trait_not_param = non-defining opaque type use in defining scope - .label = argument `{$arg}` is not a generic parameter - .note = for this opaque type - -ty_utils_index_not_supported = indexing is not supported in generic constants - -ty_utils_inline_asm_not_supported = assembly is not supported in generic constants - -ty_utils_logical_op_not_supported = unsupported operation in generic constants, short-circuiting operations would imply control flow - -ty_utils_loop_not_supported = loops and loop control flow are not supported in generic constants - -ty_utils_needs_drop_overflow = overflow while checking whether `{$query_ty}` requires drop - -ty_utils_never_to_any_not_supported = coercing the `never` type is not supported in generic constants - -ty_utils_non_primitive_simd_type = monomorphising SIMD type `{$ty}` with a non-primitive-scalar (integer/float/pointer) element type `{$e_ty}` - -ty_utils_operation_not_supported = unsupported operation in generic constants - -ty_utils_pointer_not_supported = pointer casts are not allowed in generic constants - -ty_utils_tuple_not_supported = tuple construction is not supported in generic constants - -ty_utils_unexpected_fnptr_associated_item = `FnPtr` trait with unexpected associated item - -ty_utils_yield_not_supported = coroutine control flow is not allowed in generic constants
diff --git a/compiler/rustc_ty_utils/src/errors.rs b/compiler/rustc_ty_utils/src/errors.rs index f92c405..ccea5a4 100644 --- a/compiler/rustc_ty_utils/src/errors.rs +++ b/compiler/rustc_ty_utils/src/errors.rs
@@ -6,18 +6,18 @@ use rustc_span::Span; #[derive(Diagnostic)] -#[diag(ty_utils_needs_drop_overflow)] +#[diag("overflow while checking whether `{$query_ty}` requires drop")] pub(crate) struct NeedsDropOverflow<'tcx> { pub query_ty: Ty<'tcx>, } #[derive(Diagnostic)] -#[diag(ty_utils_generic_constant_too_complex)] -#[help] +#[diag("overly complex generic constant")] +#[help("consider moving this anonymous constant into a `const` function")] pub(crate) struct GenericConstantTooComplex { #[primary_span] pub span: Span, - #[note(ty_utils_maybe_supported)] + #[note("this operation may be supported in the future")] pub maybe_supported: bool, #[subdiagnostic] pub sub: GenericConstantTooComplexSub, @@ -25,84 +25,88 @@ pub(crate) struct GenericConstantTooComplex { #[derive(Subdiagnostic)] pub(crate) enum GenericConstantTooComplexSub { - #[label(ty_utils_borrow_not_supported)] + #[label("borrowing is not supported in generic constants")] BorrowNotSupported(#[primary_span] Span), - #[label(ty_utils_address_and_deref_not_supported)] + #[label("dereferencing or taking the address is not supported in generic constants")] AddressAndDerefNotSupported(#[primary_span] Span), - #[label(ty_utils_array_not_supported)] + #[label("array construction is not supported in generic constants")] ArrayNotSupported(#[primary_span] Span), - #[label(ty_utils_block_not_supported)] + #[label("blocks are not supported in generic constants")] BlockNotSupported(#[primary_span] Span), - #[label(ty_utils_never_to_any_not_supported)] + #[label("coercing the `never` type is not supported in generic constants")] NeverToAnyNotSupported(#[primary_span] Span), - #[label(ty_utils_tuple_not_supported)] + #[label("tuple construction is not supported in generic constants")] TupleNotSupported(#[primary_span] Span), - #[label(ty_utils_index_not_supported)] + #[label("indexing is not supported in generic constants")] IndexNotSupported(#[primary_span] Span), - #[label(ty_utils_field_not_supported)] + #[label("field access is not supported in generic constants")] FieldNotSupported(#[primary_span] Span), - #[label(ty_utils_const_block_not_supported)] + #[label("const blocks are not supported in generic constants")] ConstBlockNotSupported(#[primary_span] Span), - #[label(ty_utils_adt_not_supported)] + #[label("struct/enum construction is not supported in generic constants")] AdtNotSupported(#[primary_span] Span), - #[label(ty_utils_pointer_not_supported)] + #[label("pointer casts are not allowed in generic constants")] PointerNotSupported(#[primary_span] Span), - #[label(ty_utils_yield_not_supported)] + #[label("coroutine control flow is not allowed in generic constants")] YieldNotSupported(#[primary_span] Span), - #[label(ty_utils_loop_not_supported)] + #[label("loops and loop control flow are not supported in generic constants")] LoopNotSupported(#[primary_span] Span), - #[label(ty_utils_box_not_supported)] + #[label("allocations are not allowed in generic constants")] BoxNotSupported(#[primary_span] Span), - #[label(ty_utils_binary_not_supported)] + #[label("unsupported binary operation in generic constants")] BinaryNotSupported(#[primary_span] Span), - #[label(ty_utils_by_use_not_supported)] + #[label(".use is not allowed in generic constants")] ByUseNotSupported(#[primary_span] Span), - #[label(ty_utils_logical_op_not_supported)] + #[label( + "unsupported operation in generic constants, short-circuiting operations would imply control flow" + )] LogicalOpNotSupported(#[primary_span] Span), - #[label(ty_utils_assign_not_supported)] + #[label("assignment is not supported in generic constants")] AssignNotSupported(#[primary_span] Span), - #[label(ty_utils_closure_and_return_not_supported)] + #[label("closures and function keywords are not supported in generic constants")] ClosureAndReturnNotSupported(#[primary_span] Span), - #[label(ty_utils_control_flow_not_supported)] + #[label("control flow is not supported in generic constants")] ControlFlowNotSupported(#[primary_span] Span), - #[label(ty_utils_inline_asm_not_supported)] + #[label("assembly is not supported in generic constants")] InlineAsmNotSupported(#[primary_span] Span), - #[label(ty_utils_operation_not_supported)] + #[label("unsupported operation in generic constants")] OperationNotSupported(#[primary_span] Span), } #[derive(Diagnostic)] -#[diag(ty_utils_unexpected_fnptr_associated_item)] +#[diag("`FnPtr` trait with unexpected associated item")] pub(crate) struct UnexpectedFnPtrAssociatedItem { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(ty_utils_non_primitive_simd_type)] +#[diag( + "monomorphising SIMD type `{$ty}` with a non-primitive-scalar (integer/float/pointer) element type `{$e_ty}`" +)] pub(crate) struct NonPrimitiveSimdType<'tcx> { pub ty: Ty<'tcx>, pub e_ty: Ty<'tcx>, } #[derive(Diagnostic)] -#[diag(ty_utils_impl_trait_duplicate_arg)] +#[diag("non-defining opaque type use in defining scope")] pub(crate) struct DuplicateArg<'tcx> { pub arg: GenericArg<'tcx>, #[primary_span] - #[label] + #[label("generic argument `{$arg}` used twice")] pub span: Span, - #[note] + #[note("for this opaque type")] pub opaque_span: Span, } #[derive(Diagnostic)] -#[diag(ty_utils_impl_trait_not_param, code = E0792)] +#[diag("non-defining opaque type use in defining scope", code = E0792)] pub(crate) struct NotParam<'tcx> { pub arg: GenericArg<'tcx>, #[primary_span] - #[label] + #[label("argument `{$arg}` is not a generic parameter")] pub span: Span, - #[note] + #[note("for this opaque type")] pub opaque_span: Span, }
diff --git a/compiler/rustc_ty_utils/src/lib.rs b/compiler/rustc_ty_utils/src/lib.rs index d8b50b2..9f8f3b2 100644 --- a/compiler/rustc_ty_utils/src/lib.rs +++ b/compiler/rustc_ty_utils/src/lib.rs
@@ -31,8 +31,6 @@ mod structural_match; mod ty; -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } - pub fn provide(providers: &mut Providers) { abi::provide(providers); assoc::provide(providers);
diff --git a/library/std/tests/windows_unix_socket.rs b/library/std/tests/windows_unix_socket.rs index 18f4c52..1f20cf5 100644 --- a/library/std/tests/windows_unix_socket.rs +++ b/library/std/tests/windows_unix_socket.rs
@@ -1,4 +1,5 @@ #![cfg(windows)] +#![cfg(not(miri))] // no socket support in Miri #![feature(windows_unix_domain_sockets)] // Now only test windows_unix_domain_sockets feature // in the future, will test both unix and windows uds
diff --git a/src/build_helper/src/metrics.rs b/src/build_helper/src/metrics.rs index 07157e3..98dd952 100644 --- a/src/build_helper/src/metrics.rs +++ b/src/build_helper/src/metrics.rs
@@ -111,6 +111,29 @@ pub struct JsonStepSystemStats { pub cpu_utilization_percent: f64, } +#[derive(Eq, Hash, PartialEq, Debug)] +pub enum DebuggerKind { + Gdb, + Lldb, + Cdb, +} + +impl DebuggerKind { + pub fn debuginfo_kind(name: &str) -> Option<DebuggerKind> { + let name = name.to_ascii_lowercase(); + + if name.contains("debuginfo-gdb") { + Some(DebuggerKind::Gdb) + } else if name.contains("debuginfo-lldb") { + Some(DebuggerKind::Lldb) + } else if name.contains("debuginfo-cdb") { + Some(DebuggerKind::Cdb) + } else { + None + } + } +} + fn null_as_f64_nan<'de, D: serde::Deserializer<'de>>(d: D) -> Result<f64, D::Error> { use serde::Deserialize as _; Option::<f64>::deserialize(d).map(|f| f.unwrap_or(f64::NAN))
diff --git a/src/ci/citool/Cargo.lock b/src/ci/citool/Cargo.lock index 9e1ded4..fe1c92f 100644 --- a/src/ci/citool/Cargo.lock +++ b/src/ci/citool/Cargo.lock
@@ -66,9 +66,9 @@ [[package]] name = "askama" -version = "0.15.1" +version = "0.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb7125972258312e79827b60c9eb93938334100245081cf701a2dee981b17427" +checksum = "08e1676b346cadfec169374f949d7490fd80a24193d37d2afce0c047cf695e57" dependencies = [ "askama_macros", "itoa", @@ -79,9 +79,9 @@ [[package]] name = "askama_derive" -version = "0.15.1" +version = "0.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ba5e7259a1580c61571e3116ebaaa01e3c001b2132b17c4cc5c70780ca3e994" +checksum = "7661ff56517787343f376f75db037426facd7c8d3049cef8911f1e75016f3a37" dependencies = [ "askama_parser", "basic-toml", @@ -96,18 +96,18 @@ [[package]] name = "askama_macros" -version = "0.15.1" +version = "0.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "236ce20b77cb13506eaf5024899f4af6e12e8825f390bd943c4c37fd8f322e46" +checksum = "713ee4dbfd1eb719c2dab859465b01fa1d21cb566684614a713a6b7a99a4e47b" dependencies = [ "askama_derive", ] [[package]] name = "askama_parser" -version = "0.15.1" +version = "0.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3c63392767bb2df6aa65a6e1e3b80fd89bb7af6d58359b924c0695620f1512e" +checksum = "1d62d674238a526418b30c0def480d5beadb9d8964e7f38d635b03bf639c704c" dependencies = [ "rustc-hash", "serde",
diff --git a/src/ci/citool/src/analysis.rs b/src/ci/citool/src/analysis.rs index 39b1151..b8048f3 100644 --- a/src/ci/citool/src/analysis.rs +++ b/src/ci/citool/src/analysis.rs
@@ -3,7 +3,7 @@ use std::time::Duration; use build_helper::metrics::{ - BuildStep, JsonRoot, TestOutcome, TestSuite, TestSuiteMetadata, escape_step_name, + BuildStep, DebuggerKind, JsonRoot, TestOutcome, TestSuite, TestSuiteMetadata, escape_step_name, format_build_steps, }; @@ -139,11 +139,39 @@ fn record_test_suites(metrics: &JsonRoot) { let table = render_table(aggregated); println!("\n# Test results\n"); println!("{table}"); + report_debuginfo_statistics(&suites); } else { eprintln!("No test suites found in metrics"); } } +fn report_debuginfo_statistics(suites: &[&TestSuite]) { + let mut debugger_test_record: HashMap<DebuggerKind, TestSuiteRecord> = HashMap::new(); + for suite in suites { + if let TestSuiteMetadata::Compiletest { .. } = suite.metadata { + for test in &suite.tests { + if let Some(kind) = DebuggerKind::debuginfo_kind(&test.name) { + let record = + debugger_test_record.entry(kind).or_insert(TestSuiteRecord::default()); + match test.outcome { + TestOutcome::Passed => record.passed += 1, + TestOutcome::Ignored { .. } => record.ignored += 1, + TestOutcome::Failed => record.failed += 1, + } + } + } + } + } + + println!("## DebugInfo Test Statistics"); + for (kind, record) in debugger_test_record { + println!( + "- {:?}: Passed ✅={}, Failed ❌={}, Ignored 🚫={}", + kind, record.passed, record.failed, record.ignored + ); + } +} + fn render_table(suites: BTreeMap<String, TestSuiteRecord>) -> String { use std::fmt::Write; @@ -194,8 +222,8 @@ pub fn output_test_diffs( report_test_diffs(aggregated_test_diffs, job_metrics, job_info_resolver); } -/// Prints the ten largest differences in bootstrap durations. -pub fn output_largest_duration_changes( +/// Prints the ten largest differences in job durations. +pub fn output_largest_job_duration_changes( job_metrics: &HashMap<JobName, JobMetrics>, job_info_resolver: &mut JobInfoResolver, ) { @@ -237,11 +265,11 @@ struct Entry<'a> { println!("# Job duration changes"); for (index, entry) in changes.into_iter().take(10).enumerate() { println!( - "{}. {}: {:.1}s -> {:.1}s ({:+.1}%)", + "{}. {}: {} -> {} ({:+.1}%)", index + 1, format_job_link(job_info_resolver, job_metrics, entry.job), - entry.before.as_secs_f64(), - entry.after.as_secs_f64(), + format_duration(entry.before), + format_duration(entry.after), entry.change ); } @@ -256,6 +284,27 @@ struct Entry<'a> { }); } +fn format_duration(duration: Duration) -> String { + let total_secs = duration.as_secs(); + let hours = total_secs / 3600; + let minutes = (total_secs % 3600) / 60; + let seconds = total_secs % 60; + + let mut res = String::new(); + + if hours > 0 { + res.push_str(&format!("{hours}h ")); + } + if minutes > 0 { + res.push_str(&format!("{minutes}m ")); + } + if hours == 0 && seconds > 0 { + res.push_str(&format!("{seconds}s")); + } + + res.trim().to_string() +} + #[derive(Default)] struct TestSuiteRecord { passed: u64,
diff --git a/src/ci/citool/src/main.rs b/src/ci/citool/src/main.rs index 01c0650..9b9cbe3 100644 --- a/src/ci/citool/src/main.rs +++ b/src/ci/citool/src/main.rs
@@ -17,7 +17,7 @@ use jobs::JobDatabase; use serde_yaml::Value; -use crate::analysis::{output_largest_duration_changes, output_test_diffs}; +use crate::analysis::{output_largest_job_duration_changes, output_test_diffs}; use crate::cpu_usage::load_cpu_usage; use crate::datadog::upload_datadog_metric; use crate::github::JobInfoResolver; @@ -205,7 +205,7 @@ fn post_merge_report(db: JobDatabase, current: String, parent: String) -> anyhow ); }); - output_largest_duration_changes(&metrics, &mut job_info_resolver); + output_largest_job_duration_changes(&metrics, &mut job_info_resolver); Ok(()) }
diff --git a/src/ci/citool/tests/jobs.rs b/src/ci/citool/tests/jobs.rs index 6787f00..b0309c5 100644 --- a/src/ci/citool/tests/jobs.rs +++ b/src/ci/citool/tests/jobs.rs
@@ -6,7 +6,7 @@ fn auto_jobs() { let stdout = get_matrix("push", "commit", "refs/heads/automation/bors/auto"); insta::assert_snapshot!(stdout, @r#" - jobs=[{"name":"aarch64-gnu","full_name":"auto - aarch64-gnu","os":"ubuntu-22.04-arm","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","DEPLOY_BUCKET":"rust-lang-ci2","TOOLSTATE_PUBLISH":1},"free_disk":true},{"name":"x86_64-gnu-llvm-18-1","full_name":"auto - x86_64-gnu-llvm-18-1","os":"ubuntu-24.04","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","DEPLOY_BUCKET":"rust-lang-ci2","DOCKER_SCRIPT":"stage_2_test_set1.sh","IMAGE":"x86_64-gnu-llvm-18","READ_ONLY_SRC":"0","RUST_BACKTRACE":1,"TOOLSTATE_PUBLISH":1},"free_disk":true},{"name":"aarch64-apple","full_name":"auto - aarch64-apple","os":"macos-14","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","DEPLOY_BUCKET":"rust-lang-ci2","MACOSX_DEPLOYMENT_TARGET":11.0,"MACOSX_STD_DEPLOYMENT_TARGET":11.0,"NO_DEBUG_ASSERTIONS":1,"NO_LLVM_ASSERTIONS":1,"NO_OVERFLOW_CHECKS":1,"RUSTC_RETRY_LINKER_ON_SEGFAULT":1,"RUST_CONFIGURE_ARGS":"--enable-sanitizers --enable-profiler --set rust.jemalloc","SCRIPT":"./x.py --stage 2 test --host=aarch64-apple-darwin --target=aarch64-apple-darwin","SELECT_XCODE":"/Applications/Xcode_15.4.app","TOOLSTATE_PUBLISH":1,"USE_XCODE_CLANG":1}},{"name":"dist-i686-msvc","full_name":"auto - dist-i686-msvc","os":"windows-2022","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","CODEGEN_BACKENDS":"llvm,cranelift","DEPLOY_BUCKET":"rust-lang-ci2","DIST_REQUIRE_ALL_TOOLS":1,"RUST_CONFIGURE_ARGS":"--build=i686-pc-windows-msvc --host=i686-pc-windows-msvc --target=i686-pc-windows-msvc,i586-pc-windows-msvc --enable-full-tools --enable-profiler","SCRIPT":"python x.py dist bootstrap --include-default-paths","TOOLSTATE_PUBLISH":1}},{"name":"pr-check-1","full_name":"auto - pr-check-1","os":"ubuntu-24.04","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","DEPLOY_BUCKET":"rust-lang-ci2","TOOLSTATE_PUBLISH":1},"continue_on_error":false,"free_disk":true},{"name":"pr-check-2","full_name":"auto - pr-check-2","os":"ubuntu-24.04","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","DEPLOY_BUCKET":"rust-lang-ci2","TOOLSTATE_PUBLISH":1},"continue_on_error":false,"free_disk":true},{"name":"tidy","full_name":"auto - tidy","os":"ubuntu-24.04","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","DEPLOY_BUCKET":"rust-lang-ci2","TOOLSTATE_PUBLISH":1},"continue_on_error":false,"free_disk":true,"doc_url":"https://foo.bar"}] + jobs=[{"name":"aarch64-gnu","full_name":"auto - aarch64-gnu","os":"ubuntu-22.04-arm","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","DEPLOY_BUCKET":"rust-lang-ci2","TOOLSTATE_PUBLISH":1},"free_disk":true},{"name":"x86_64-gnu-llvm-18-1","full_name":"auto - x86_64-gnu-llvm-18-1","os":"ubuntu-24.04","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","DEPLOY_BUCKET":"rust-lang-ci2","DOCKER_SCRIPT":"stage_2_test_set1.sh","IMAGE":"x86_64-gnu-llvm-18","READ_ONLY_SRC":"0","RUST_BACKTRACE":1,"TOOLSTATE_PUBLISH":1},"free_disk":true},{"name":"aarch64-apple","full_name":"auto - aarch64-apple","os":"macos-14","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","DEPLOY_BUCKET":"rust-lang-ci2","DEVELOPER_DIR":"/Applications/Xcode_15.4.app/Contents/Developer","MACOSX_DEPLOYMENT_TARGET":11.0,"MACOSX_STD_DEPLOYMENT_TARGET":11.0,"NO_DEBUG_ASSERTIONS":1,"NO_LLVM_ASSERTIONS":1,"NO_OVERFLOW_CHECKS":1,"RUSTC_RETRY_LINKER_ON_SEGFAULT":1,"RUST_CONFIGURE_ARGS":"--enable-sanitizers --enable-profiler --set rust.jemalloc","SCRIPT":"./x.py --stage 2 test --host=aarch64-apple-darwin --target=aarch64-apple-darwin","TOOLSTATE_PUBLISH":1,"USE_XCODE_CLANG":1}},{"name":"dist-i686-msvc","full_name":"auto - dist-i686-msvc","os":"windows-2022","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","CODEGEN_BACKENDS":"llvm,cranelift","DEPLOY_BUCKET":"rust-lang-ci2","DIST_REQUIRE_ALL_TOOLS":1,"RUST_CONFIGURE_ARGS":"--build=i686-pc-windows-msvc --host=i686-pc-windows-msvc --target=i686-pc-windows-msvc,i586-pc-windows-msvc --enable-full-tools --enable-profiler","SCRIPT":"python x.py dist bootstrap --include-default-paths","TOOLSTATE_PUBLISH":1}},{"name":"pr-check-1","full_name":"auto - pr-check-1","os":"ubuntu-24.04","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","DEPLOY_BUCKET":"rust-lang-ci2","TOOLSTATE_PUBLISH":1},"continue_on_error":false,"free_disk":true},{"name":"pr-check-2","full_name":"auto - pr-check-2","os":"ubuntu-24.04","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","DEPLOY_BUCKET":"rust-lang-ci2","TOOLSTATE_PUBLISH":1},"continue_on_error":false,"free_disk":true},{"name":"tidy","full_name":"auto - tidy","os":"ubuntu-24.04","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","DEPLOY_BUCKET":"rust-lang-ci2","TOOLSTATE_PUBLISH":1},"continue_on_error":false,"free_disk":true,"doc_url":"https://foo.bar"}] run_type=auto "#); }
diff --git a/src/ci/citool/tests/test-jobs.yml b/src/ci/citool/tests/test-jobs.yml index e261049..95cd328 100644 --- a/src/ci/citool/tests/test-jobs.yml +++ b/src/ci/citool/tests/test-jobs.yml
@@ -33,7 +33,7 @@ # Ensure that host tooling is tested on our minimum supported macOS version. MACOSX_DEPLOYMENT_TARGET: 10.12 MACOSX_STD_DEPLOYMENT_TARGET: 10.12 - SELECT_XCODE: /Applications/Xcode_15.2.app + DEVELOPER_DIR: /Applications/Xcode_15.2.app/Contents/Developer NO_LLVM_ASSERTIONS: 1 NO_DEBUG_ASSERTIONS: 1 NO_OVERFLOW_CHECKS: 1 @@ -112,7 +112,7 @@ --enable-profiler --set rust.jemalloc RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 - SELECT_XCODE: /Applications/Xcode_15.4.app + DEVELOPER_DIR: /Applications/Xcode_15.4.app/Contents/Developer USE_XCODE_CLANG: 1 # Aarch64 tooling only needs to support macOS 11.0 and up as nothing else # supports the hardware, so only need to test it there.
diff --git a/src/ci/docker/host-x86_64/dist-loongarch64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-loongarch64-linux/Dockerfile index 4b86ed3..96acc5e 100644 --- a/src/ci/docker/host-x86_64/dist-loongarch64-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-loongarch64-linux/Dockerfile
@@ -50,6 +50,9 @@ --enable-full-tools \ --enable-profiler \ --enable-sanitizers \ - --disable-docs + --disable-docs \ + --set rust.jemalloc \ + --set rust.lto=thin \ + --set rust.codegen-units=1 ENV SCRIPT python3 ../x.py dist --host $HOSTS --target $TARGETS
diff --git a/src/ci/docker/host-x86_64/dist-loongarch64-musl/Dockerfile b/src/ci/docker/host-x86_64/dist-loongarch64-musl/Dockerfile index 763b29a..44efc10 100644 --- a/src/ci/docker/host-x86_64/dist-loongarch64-musl/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-loongarch64-musl/Dockerfile
@@ -33,6 +33,9 @@ --enable-profiler \ --enable-sanitizers \ --disable-docs \ + --set rust.jemalloc \ + --set rust.lto=thin \ + --set rust.codegen-units=1 \ --set target.loongarch64-unknown-linux-musl.crt-static=false \ --musl-root-loongarch64=/x-tools/loongarch64-unknown-linux-musl/loongarch64-unknown-linux-musl/sysroot/usr
diff --git a/src/ci/docker/scripts/rfl-build.sh b/src/ci/docker/scripts/rfl-build.sh index e7f86e1..5352505 100755 --- a/src/ci/docker/scripts/rfl-build.sh +++ b/src/ci/docker/scripts/rfl-build.sh
@@ -2,8 +2,8 @@ set -euo pipefail -# https://github.com/rust-lang/rust/pull/145974 -LINUX_VERSION=842cfd8e5aff3157cb25481b2900b49c188d628a +# https://github.com/rust-lang/rust/pull/151534 +LINUX_VERSION=eb268c7972f65fa0b11b051c5ef2b92747bb2b62 # Build rustc, rustdoc, cargo, clippy-driver and rustfmt ../x.py build --stage 2 library rustdoc clippy rustfmt
diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index 6e07ffc..6f333ec 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml
@@ -459,7 +459,7 @@ # Ensure that host tooling is built to support our minimum support macOS version. MACOSX_DEPLOYMENT_TARGET: 10.12 MACOSX_STD_DEPLOYMENT_TARGET: 10.12 - SELECT_XCODE: /Applications/Xcode_15.4.app + DEVELOPER_DIR: /Applications/Xcode_15.4.app/Contents/Developer USE_XCODE_CLANG: 1 DIST_REQUIRE_ALL_TOOLS: 1 CODEGEN_BACKENDS: llvm,cranelift @@ -475,7 +475,7 @@ # FIXME(madsmtm): This might be redundant, as we're not building host tooling here (?) MACOSX_DEPLOYMENT_TARGET: 10.12 MACOSX_STD_DEPLOYMENT_TARGET: 10.12 - SELECT_XCODE: /Applications/Xcode_15.2.app + DEVELOPER_DIR: /Applications/Xcode_15.2.app/Contents/Developer <<: *job-macos - name: dist-aarch64-apple @@ -496,7 +496,7 @@ # supports the hardware. MACOSX_DEPLOYMENT_TARGET: 11.0 MACOSX_STD_DEPLOYMENT_TARGET: 11.0 - SELECT_XCODE: /Applications/Xcode_15.4.app + DEVELOPER_DIR: /Applications/Xcode_15.4.app/Contents/Developer USE_XCODE_CLANG: 1 DIST_REQUIRE_ALL_TOOLS: 1 CODEGEN_BACKENDS: llvm,cranelift @@ -511,7 +511,7 @@ --enable-sanitizers --enable-profiler --set rust.jemalloc - SELECT_XCODE: /Applications/Xcode_15.4.app + DEVELOPER_DIR: /Applications/Xcode_15.4.app/Contents/Developer USE_XCODE_CLANG: 1 # Aarch64 tooling only needs to support macOS 11.0 and up as nothing else # supports the hardware, so only need to test it there.
diff --git a/src/ci/scripts/select-xcode.sh b/src/ci/scripts/select-xcode.sh deleted file mode 100755 index 569c4a4..0000000 --- a/src/ci/scripts/select-xcode.sh +++ /dev/null
@@ -1,11 +0,0 @@ -#!/bin/bash -# This script selects the Xcode instance to use. - -set -euo pipefail -IFS=$'\n\t' - -source "$(cd "$(dirname "$0")" && pwd)/../shared.sh" - -if isMacOS; then - sudo xcode-select -s "${SELECT_XCODE}" -fi
diff --git a/src/tools/rustbook/README.md b/src/tools/rustbook/README.md index d9570c23..a9fd1b7 100644 --- a/src/tools/rustbook/README.md +++ b/src/tools/rustbook/README.md
@@ -10,7 +10,7 @@ ## Cargo workspace -This package defines a separate cargo workspace from the main Rust workspace for a few reasons (ref [#127786](https://github.com/rust-lang/rust/pull/127786): +This package defines a separate cargo workspace from the main Rust workspace for a few reasons (ref [#127786](https://github.com/rust-lang/rust/pull/127786)): - Avoids requiring checking out submodules for developers who are not working on the documentation. Otherwise, some submodules such as those that have custom preprocessors would be required for cargo to find the dependencies. - Avoids problems with updating dependencies. Unfortunately this workspace has a rather large set of dependencies, which can make coordinating updates difficult (see [#127890](https://github.com/rust-lang/rust/issues/127890)).
diff --git a/tests/codegen-llvm/autodiff/abi_handling.rs b/tests/codegen-llvm/autodiff/abi_handling.rs index 5c81268..a8bc482 100644 --- a/tests/codegen-llvm/autodiff/abi_handling.rs +++ b/tests/codegen-llvm/autodiff/abi_handling.rs
@@ -38,14 +38,14 @@ fn square(x: f32) -> f32 { // CHECK-LABEL: ; abi_handling::df1 // CHECK-NEXT: Function Attrs // debug-NEXT: define internal { float, float } -// debug-SAME: (ptr align 4 %x, ptr align 4 %bx_0) +// debug-SAME: (ptr {{.*}}%x, ptr {{.*}}%bx_0) // release-NEXT: define internal fastcc float // release-SAME: (float %x.0.val, float %x.4.val) // CHECK-LABEL: ; abi_handling::f1 // CHECK-NEXT: Function Attrs // debug-NEXT: define internal float -// debug-SAME: (ptr align 4 %x) +// debug-SAME: (ptr {{.*}}%x) // release-NEXT: define internal fastcc noundef float // release-SAME: (float %x.0.val, float %x.4.val) #[autodiff_forward(df1, Dual, Dual)] @@ -58,7 +58,7 @@ fn square(x: f32) -> f32 { // CHECK-NEXT: Function Attrs // debug-NEXT: define internal { float, float } // debug-SAME: (ptr %f, float %x, float %dret) -// release-NEXT: define internal fastcc float +// release-NEXT: define internal fastcc noundef float // release-SAME: (float noundef %x) // CHECK-LABEL: ; abi_handling::f2 @@ -77,13 +77,13 @@ fn f2(f: fn(f32) -> f32, x: f32) -> f32 { // CHECK-NEXT: Function Attrs // debug-NEXT: define internal { float, float } // debug-SAME: (ptr align 4 %x, ptr align 4 %bx_0, ptr align 4 %y, ptr align 4 %by_0) -// release-NEXT: define internal fastcc { float, float } +// release-NEXT: define internal fastcc float // release-SAME: (float %x.0.val) // CHECK-LABEL: ; abi_handling::f3 // CHECK-NEXT: Function Attrs // debug-NEXT: define internal float -// debug-SAME: (ptr align 4 %x, ptr align 4 %y) +// debug-SAME: (ptr {{.*}}%x, ptr {{.*}}%y) // release-NEXT: define internal fastcc noundef float // release-SAME: (float %x.0.val) #[autodiff_forward(df3, Dual, Dual, Dual)] @@ -160,7 +160,7 @@ fn f6(i: NestedInput) -> f32 { // CHECK-LABEL: ; abi_handling::f7 // CHECK-NEXT: Function Attrs // debug-NEXT: define internal float -// debug-SAME: (ptr align 4 %x.0, ptr align 4 %x.1) +// debug-SAME: (ptr {{.*}}%x.0, ptr {{.*}}%x.1) // release-NEXT: define internal fastcc noundef float // release-SAME: (float %x.0.0.val, float %x.1.0.val) #[autodiff_forward(df7, Dual, Dual)]
diff --git a/tests/codegen-llvm/autodiff/batched.rs b/tests/codegen-llvm/autodiff/batched.rs index 0ff6134..5a723ff 100644 --- a/tests/codegen-llvm/autodiff/batched.rs +++ b/tests/codegen-llvm/autodiff/batched.rs
@@ -1,13 +1,11 @@ //@ compile-flags: -Zautodiff=Enable,NoTT,NoPostopt -C opt-level=3 -Clto=fat //@ no-prefer-dynamic //@ needs-enzyme -// -// In Enzyme, we test against a large range of LLVM versions (5+) and don't have overly many -// breakages. One benefit is that we match the IR generated by Enzyme only after running it -// through LLVM's O3 pipeline, which will remove most of the noise. -// However, our integration test could also be affected by changes in how rustc lowers MIR into -// LLVM-IR, which could cause additional noise and thus breakages. If that's the case, we should -// reduce this test to only match the first lines and the ret instructions. + +// This test combines two features of Enzyme, automatic differentiation and batching. As such, it is +// especially prone to breakages. I reduced it therefore to a minimal check matches argument/return +// types. Based on the original batching author, implementing the batching feature over MLIR instead +// of LLVM should give significantly more reliable performance. #![feature(autodiff)] @@ -22,69 +20,20 @@ fn square(x: &f32) -> f32 { x * x } +// The base ("scalar") case d_square3, without batching. +// CHECK: define internal fastcc float @fwddiffesquare(float %x.0.val, float %"x'.0.val") +// CHECK: %0 = fadd fast float %"x'.0.val", %"x'.0.val" +// CHECK-NEXT: %1 = fmul fast float %0, %x.0.val +// CHECK-NEXT: ret float %1 +// CHECK-NEXT: } + // d_square2 -// CHECK: define internal [4 x float] @fwddiffe4square(ptr noalias noundef readonly align 4 captures(none) dereferenceable(4) %x, [4 x ptr] %"x'") -// CHECK-NEXT: start: -// CHECK-NEXT: %0 = extractvalue [4 x ptr] %"x'", 0 -// CHECK-NEXT: %"_2'ipl" = load float, ptr %0, align 4 -// CHECK-NEXT: %1 = extractvalue [4 x ptr] %"x'", 1 -// CHECK-NEXT: %"_2'ipl1" = load float, ptr %1, align 4 -// CHECK-NEXT: %2 = extractvalue [4 x ptr] %"x'", 2 -// CHECK-NEXT: %"_2'ipl2" = load float, ptr %2, align 4 -// CHECK-NEXT: %3 = extractvalue [4 x ptr] %"x'", 3 -// CHECK-NEXT: %"_2'ipl3" = load float, ptr %3, align 4 -// CHECK-NEXT: %_2 = load float, ptr %x, align 4 -// CHECK-NEXT: %4 = fmul fast float %"_2'ipl", %_2 -// CHECK-NEXT: %5 = fmul fast float %"_2'ipl1", %_2 -// CHECK-NEXT: %6 = fmul fast float %"_2'ipl2", %_2 -// CHECK-NEXT: %7 = fmul fast float %"_2'ipl3", %_2 -// CHECK-NEXT: %8 = fmul fast float %"_2'ipl", %_2 -// CHECK-NEXT: %9 = fmul fast float %"_2'ipl1", %_2 -// CHECK-NEXT: %10 = fmul fast float %"_2'ipl2", %_2 -// CHECK-NEXT: %11 = fmul fast float %"_2'ipl3", %_2 -// CHECK-NEXT: %12 = fadd fast float %4, %8 -// CHECK-NEXT: %13 = insertvalue [4 x float] undef, float %12, 0 -// CHECK-NEXT: %14 = fadd fast float %5, %9 -// CHECK-NEXT: %15 = insertvalue [4 x float] %13, float %14, 1 -// CHECK-NEXT: %16 = fadd fast float %6, %10 -// CHECK-NEXT: %17 = insertvalue [4 x float] %15, float %16, 2 -// CHECK-NEXT: %18 = fadd fast float %7, %11 -// CHECK-NEXT: %19 = insertvalue [4 x float] %17, float %18, 3 -// CHECK-NEXT: ret [4 x float] %19 +// CHECK: define internal fastcc [4 x float] @fwddiffe4square(float %x.0.val, [4 x ptr] %"x'") +// CHECK: ret [4 x float] // CHECK-NEXT: } -// d_square3, the extra float is the original return value (x * x) -// CHECK: define internal { float, [4 x float] } @fwddiffe4square.1(ptr noalias noundef readonly align 4 captures(none) dereferenceable(4) %x, [4 x ptr] %"x'") -// CHECK-NEXT: start: -// CHECK-NEXT: %0 = extractvalue [4 x ptr] %"x'", 0 -// CHECK-NEXT: %"_2'ipl" = load float, ptr %0, align 4 -// CHECK-NEXT: %1 = extractvalue [4 x ptr] %"x'", 1 -// CHECK-NEXT: %"_2'ipl1" = load float, ptr %1, align 4 -// CHECK-NEXT: %2 = extractvalue [4 x ptr] %"x'", 2 -// CHECK-NEXT: %"_2'ipl2" = load float, ptr %2, align 4 -// CHECK-NEXT: %3 = extractvalue [4 x ptr] %"x'", 3 -// CHECK-NEXT: %"_2'ipl3" = load float, ptr %3, align 4 -// CHECK-NEXT: %_2 = load float, ptr %x, align 4 -// CHECK-NEXT: %_0 = fmul float %_2, %_2 -// CHECK-NEXT: %4 = fmul fast float %"_2'ipl", %_2 -// CHECK-NEXT: %5 = fmul fast float %"_2'ipl1", %_2 -// CHECK-NEXT: %6 = fmul fast float %"_2'ipl2", %_2 -// CHECK-NEXT: %7 = fmul fast float %"_2'ipl3", %_2 -// CHECK-NEXT: %8 = fmul fast float %"_2'ipl", %_2 -// CHECK-NEXT: %9 = fmul fast float %"_2'ipl1", %_2 -// CHECK-NEXT: %10 = fmul fast float %"_2'ipl2", %_2 -// CHECK-NEXT: %11 = fmul fast float %"_2'ipl3", %_2 -// CHECK-NEXT: %12 = fadd fast float %4, %8 -// CHECK-NEXT: %13 = insertvalue [4 x float] undef, float %12, 0 -// CHECK-NEXT: %14 = fadd fast float %5, %9 -// CHECK-NEXT: %15 = insertvalue [4 x float] %13, float %14, 1 -// CHECK-NEXT: %16 = fadd fast float %6, %10 -// CHECK-NEXT: %17 = insertvalue [4 x float] %15, float %16, 2 -// CHECK-NEXT: %18 = fadd fast float %7, %11 -// CHECK-NEXT: %19 = insertvalue [4 x float] %17, float %18, 3 -// CHECK-NEXT: %20 = insertvalue { float, [4 x float] } undef, float %_0, 0 -// CHECK-NEXT: %21 = insertvalue { float, [4 x float] } %20, [4 x float] %19, 1 -// CHECK-NEXT: ret { float, [4 x float] } %21 +// CHECK: define internal fastcc { float, [4 x float] } @fwddiffe4square.{{.*}}(float %x.0.val, [4 x ptr] %"x'") +// CHECK: ret { float, [4 x float] } // CHECK-NEXT: } fn main() {
diff --git a/tests/codegen-llvm/autodiff/generic.rs b/tests/codegen-llvm/autodiff/generic.rs index 6f56460..b31468c 100644 --- a/tests/codegen-llvm/autodiff/generic.rs +++ b/tests/codegen-llvm/autodiff/generic.rs
@@ -1,6 +1,14 @@ //@ compile-flags: -Zautodiff=Enable -Zautodiff=NoPostopt -C opt-level=3 -Clto=fat //@ no-prefer-dynamic //@ needs-enzyme +//@ revisions: F32 F64 Main + +// Here we verify that the function `square` can be differentiated over f64. +// This is interesting to test, since the user never calls `square` with f64, so on it's own rustc +// would have no reason to monomorphize it that way. However, Enzyme needs the f64 version of +// `square` in order to be able to differentiate it, so we have logic to enforce the +// monomorphization. Here, we test this logic. + #![feature(autodiff)] use std::autodiff::autodiff_reverse; @@ -12,32 +20,37 @@ fn square<T: std::ops::Mul<Output = T> + Copy>(x: &T) -> T { } // Ensure that `d_square::<f32>` code is generated -// -// CHECK: ; generic::square -// CHECK-NEXT: ; Function Attrs: {{.*}} -// CHECK-NEXT: define internal {{.*}} float -// CHECK-NEXT: start: -// CHECK-NOT: ret -// CHECK: fmul float + +// F32-LABEL: ; generic::square::<f32> +// F32-NEXT: ; Function Attrs: {{.*}} +// F32-NEXT: define internal {{.*}} float +// F32-NEXT: start: +// F32-NOT: ret +// F32: fmul float // Ensure that `d_square::<f64>` code is generated even if `square::<f64>` was never called -// -// CHECK: ; generic::square -// CHECK-NEXT: ; Function Attrs: -// CHECK-NEXT: define internal {{.*}} double -// CHECK-NEXT: start: -// CHECK-NOT: ret -// CHECK: fmul double + +// F64-LABEL: ; generic::d_square::<f64> +// F64-NEXT: ; Function Attrs: {{.*}} +// F64-NEXT: define internal {{.*}} void +// F64-NEXT: start: +// F64-NEXT: {{(tail )?}}call {{(fastcc )?}}void @diffe_{{.*}}(double {{.*}}, ptr {{.*}}) +// F64-NEXT: ret void + +// Main-LABEL: ; generic::main +// Main: ; call generic::square::<f32> +// Main: ; call generic::d_square::<f64> fn main() { let xf32: f32 = std::hint::black_box(3.0); let xf64: f64 = std::hint::black_box(3.0); + let seed: f64 = std::hint::black_box(1.0); let outputf32 = square::<f32>(&xf32); assert_eq!(9.0, outputf32); let mut df_dxf64: f64 = std::hint::black_box(0.0); - let output_f64 = d_square::<f64>(&xf64, &mut df_dxf64, 1.0); + let output_f64 = d_square::<f64>(&xf64, &mut df_dxf64, seed); assert_eq!(6.0, df_dxf64); }
diff --git a/tests/codegen-llvm/autodiff/identical_fnc.rs b/tests/codegen-llvm/autodiff/identical_fnc.rs index 1c18e7a..a8b186c 100644 --- a/tests/codegen-llvm/autodiff/identical_fnc.rs +++ b/tests/codegen-llvm/autodiff/identical_fnc.rs
@@ -8,7 +8,7 @@ // merged placeholder function anymore, and compilation would fail. We prevent this by disabling // LLVM's merge_function pass before AD. Here we implicetely test that our solution keeps working. // We also explicetly test that we keep running merge_function after AD, by checking for two -// identical function calls in the LLVM-IR, while having two different calls in the Rust code. +// identical function calls in the LLVM-IR, despite having two different calls in the Rust code. #![feature(autodiff)] use std::autodiff::autodiff_reverse; @@ -27,14 +27,14 @@ fn square2(x: &f64) -> f64 { // CHECK:; identical_fnc::main // CHECK-NEXT:; Function Attrs: -// CHECK-NEXT:define internal void @_ZN13identical_fnc4main17h6009e4f751bf9407E() +// CHECK-NEXT:define internal void // CHECK-NEXT:start: // CHECK-NOT:br // CHECK-NOT:ret // CHECK:; call identical_fnc::d_square -// CHECK-NEXT:call fastcc void @_ZN13identical_fnc8d_square[[HASH:.+]](double %x.val, ptr noalias noundef align 8 dereferenceable(8) %dx1) +// CHECK-NEXT:call fastcc void @[[HASH:.+]](double %x.val, ptr noalias noundef align 8 dereferenceable(8) %dx1) // CHECK:; call identical_fnc::d_square -// CHECK-NEXT:call fastcc void @_ZN13identical_fnc8d_square[[HASH]](double %x.val, ptr noalias noundef align 8 dereferenceable(8) %dx2) +// CHECK-NEXT:call fastcc void @[[HASH]](double %x.val, ptr noalias noundef align 8 dereferenceable(8) %dx2) fn main() { let x = std::hint::black_box(3.0);
diff --git a/tests/coverage/macros/context-mismatch-issue-147339.cov-map b/tests/coverage/macros/context-mismatch-issue-147339.cov-map new file mode 100644 index 0000000..7aa829c --- /dev/null +++ b/tests/coverage/macros/context-mismatch-issue-147339.cov-map
@@ -0,0 +1,40 @@ +Function name: context_mismatch_issue_147339::a (unused) +Raw bytes (14): 0x[01, 01, 00, 02, 00, 0c, 27, 00, 35, 00, 00, 3b, 00, 3c] +Number of files: 1 +- file 0 => $DIR/context-mismatch-issue-147339.rs +Number of expressions: 0 +Number of file 0 mappings: 2 +- Code(Zero) at (prev + 12, 39) to (start + 0, 53) +- Code(Zero) at (prev + 0, 59) to (start + 0, 60) +Highest counter ID seen: (none) + +Function name: context_mismatch_issue_147339::b (unused) +Raw bytes (14): 0x[01, 01, 00, 02, 00, 0c, 27, 00, 35, 00, 00, 3b, 00, 3c] +Number of files: 1 +- file 0 => $DIR/context-mismatch-issue-147339.rs +Number of expressions: 0 +Number of file 0 mappings: 2 +- Code(Zero) at (prev + 12, 39) to (start + 0, 53) +- Code(Zero) at (prev + 0, 59) to (start + 0, 60) +Highest counter ID seen: (none) + +Function name: context_mismatch_issue_147339::c (unused) +Raw bytes (14): 0x[01, 01, 00, 02, 00, 0c, 27, 00, 35, 00, 00, 3b, 00, 3c] +Number of files: 1 +- file 0 => $DIR/context-mismatch-issue-147339.rs +Number of expressions: 0 +Number of file 0 mappings: 2 +- Code(Zero) at (prev + 12, 39) to (start + 0, 53) +- Code(Zero) at (prev + 0, 59) to (start + 0, 60) +Highest counter ID seen: (none) + +Function name: context_mismatch_issue_147339::main +Raw bytes (14): 0x[01, 01, 00, 02, 01, 14, 01, 00, 0a, 01, 00, 0c, 00, 0d] +Number of files: 1 +- file 0 => $DIR/context-mismatch-issue-147339.rs +Number of expressions: 0 +Number of file 0 mappings: 2 +- Code(Counter(0)) at (prev + 20, 1) to (start + 0, 10) +- Code(Counter(0)) at (prev + 0, 12) to (start + 0, 13) +Highest counter ID seen: c0 +
diff --git a/tests/coverage/macros/context-mismatch-issue-147339.coverage b/tests/coverage/macros/context-mismatch-issue-147339.coverage new file mode 100644 index 0000000..9b4fc67 --- /dev/null +++ b/tests/coverage/macros/context-mismatch-issue-147339.coverage
@@ -0,0 +1,28 @@ + LL| |//@ edition: 2024 + LL| | + LL| |// These nested macro expansions were found to cause span refinement to produce + LL| |// spans with a context that doesn't match the function body span, triggering + LL| |// a defensive check that discards the span. + LL| |// + LL| |// Reported in <https://github.com/rust-lang/rust/issues/147339>. + LL| | + LL| |macro_rules! foo { + LL| | ($($m:ident $($f:ident $v:tt)+),*) => { + LL| | $($(macro_rules! $f { () => { $v } })+)* + LL| 0| $(macro_rules! $m { () => { $(fn $f() -> i32 { $v })+ } })* + ------------------ + | Unexecuted instantiation: context_mismatch_issue_147339::a + ------------------ + | Unexecuted instantiation: context_mismatch_issue_147339::b + ------------------ + | Unexecuted instantiation: context_mismatch_issue_147339::c + ------------------ + LL| | } + LL| |} + LL| | + LL| |foo!(m a 1 b 2, n c 3); + LL| |m!(); + LL| |n!(); + LL| | + LL| 1|fn main() {} +
diff --git a/tests/coverage/macros/context-mismatch-issue-147339.rs b/tests/coverage/macros/context-mismatch-issue-147339.rs new file mode 100644 index 0000000..80e744a --- /dev/null +++ b/tests/coverage/macros/context-mismatch-issue-147339.rs
@@ -0,0 +1,20 @@ +//@ edition: 2024 + +// These nested macro expansions were found to cause span refinement to produce +// spans with a context that doesn't match the function body span, triggering +// a defensive check that discards the span. +// +// Reported in <https://github.com/rust-lang/rust/issues/147339>. + +macro_rules! foo { + ($($m:ident $($f:ident $v:tt)+),*) => { + $($(macro_rules! $f { () => { $v } })+)* + $(macro_rules! $m { () => { $(fn $f() -> i32 { $v })+ } })* + } +} + +foo!(m a 1 b 2, n c 3); +m!(); +n!(); + +fn main() {}
diff --git a/tests/crashes/137582.rs b/tests/crashes/137582.rs deleted file mode 100644 index e21b6c9..0000000 --- a/tests/crashes/137582.rs +++ /dev/null
@@ -1,16 +0,0 @@ -//@ known-bug: #137582 -#![feature(adt_const_params)] - -mod lib { - pub type Matrix = [&'static u32]; - - const EMPTY_MATRIX: Matrix = [[0; 4]; 4]; - - pub struct Walk<const CURRENT: usize, const REMAINING: Matrix> { - _p: (), - } - - impl<const CURRENT: usize> Walk<CURRENT, EMPTY_MATRIX> {} -} - -fn main() {}
diff --git a/tests/run-make/autodiff/type-trees/array-typetree/rmake.rs b/tests/run-make/autodiff/type-trees/array-typetree/rmake.rs index 20b6a06..41805d2 100644 --- a/tests/run-make/autodiff/type-trees/array-typetree/rmake.rs +++ b/tests/run-make/autodiff/type-trees/array-typetree/rmake.rs
@@ -4,6 +4,6 @@ use run_make_support::{llvm_filecheck, rfs, rustc}; fn main() { - rustc().input("test.rs").arg("-Zautodiff=Enable").emit("llvm-ir").run(); + rustc().input("test.rs").arg("-Zautodiff=Enable").arg("-Clto=fat").emit("llvm-ir").run(); llvm_filecheck().patterns("array.check").stdin_buf(rfs::read("test.ll")).run(); }
diff --git a/tests/run-make/autodiff/type-trees/mixed-struct-typetree/rmake.rs b/tests/run-make/autodiff/type-trees/mixed-struct-typetree/rmake.rs index 1c19963..d740596 100644 --- a/tests/run-make/autodiff/type-trees/mixed-struct-typetree/rmake.rs +++ b/tests/run-make/autodiff/type-trees/mixed-struct-typetree/rmake.rs
@@ -9,6 +9,7 @@ fn main() { .arg("-Zautodiff=Enable") .arg("-Zautodiff=NoPostopt") .opt_level("0") + .arg("-Clto=fat") .emit("llvm-ir") .run();
diff --git a/tests/run-make/autodiff/type-trees/nott-flag/rmake.rs b/tests/run-make/autodiff/type-trees/nott-flag/rmake.rs index de540b9..2e93d586 100644 --- a/tests/run-make/autodiff/type-trees/nott-flag/rmake.rs +++ b/tests/run-make/autodiff/type-trees/nott-flag/rmake.rs
@@ -8,6 +8,7 @@ fn main() { rustc() .input("test.rs") .arg("-Zautodiff=Enable,NoTT") + .arg("-Clto=fat") .emit("llvm-ir") .arg("-o") .arg("nott.ll") @@ -17,6 +18,7 @@ fn main() { rustc() .input("test.rs") .arg("-Zautodiff=Enable") + .arg("-Clto=fat") .emit("llvm-ir") .arg("-o") .arg("with_tt.ll")
diff --git a/tests/run-make/autodiff/type-trees/recursion-typetree/rmake.rs b/tests/run-make/autodiff/type-trees/recursion-typetree/rmake.rs index 78718f3..af1eb41 100644 --- a/tests/run-make/autodiff/type-trees/recursion-typetree/rmake.rs +++ b/tests/run-make/autodiff/type-trees/recursion-typetree/rmake.rs
@@ -4,6 +4,6 @@ use run_make_support::{llvm_filecheck, rfs, rustc}; fn main() { - rustc().input("test.rs").arg("-Zautodiff=Enable").emit("llvm-ir").run(); + rustc().input("test.rs").arg("-Zautodiff=Enable").arg("-Clto=fat").emit("llvm-ir").run(); llvm_filecheck().patterns("recursion.check").stdin_buf(rfs::read("test.ll")).run(); }
diff --git a/tests/run-make/autodiff/type-trees/scalar-types/f128-typetree/rmake.rs b/tests/run-make/autodiff/type-trees/scalar-types/f128-typetree/rmake.rs index 44320ec..b1672cd 100644 --- a/tests/run-make/autodiff/type-trees/scalar-types/f128-typetree/rmake.rs +++ b/tests/run-make/autodiff/type-trees/scalar-types/f128-typetree/rmake.rs
@@ -5,7 +5,7 @@ fn main() { // Compile with TypeTree enabled and emit LLVM IR - rustc().input("test.rs").arg("-Zautodiff=Enable").emit("llvm-ir").run(); + rustc().input("test.rs").arg("-Zautodiff=Enable").arg("-Clto=fat").emit("llvm-ir").run(); // Check that f128 TypeTree metadata is correctly generated llvm_filecheck().patterns("f128.check").stdin_buf(rfs::read("test.ll")).run();
diff --git a/tests/run-make/autodiff/type-trees/scalar-types/f16-typetree/rmake.rs b/tests/run-make/autodiff/type-trees/scalar-types/f16-typetree/rmake.rs index 0aebdbf..3e308a9 100644 --- a/tests/run-make/autodiff/type-trees/scalar-types/f16-typetree/rmake.rs +++ b/tests/run-make/autodiff/type-trees/scalar-types/f16-typetree/rmake.rs
@@ -5,7 +5,7 @@ fn main() { // Compile with TypeTree enabled and emit LLVM IR - rustc().input("test.rs").arg("-Zautodiff=Enable").emit("llvm-ir").run(); + rustc().input("test.rs").arg("-Zautodiff=Enable").arg("-Clto=fat").emit("llvm-ir").run(); // Check that f16 TypeTree metadata is correctly generated llvm_filecheck().patterns("f16.check").stdin_buf(rfs::read("test.ll")).run();
diff --git a/tests/run-make/autodiff/type-trees/scalar-types/f32-typetree/rmake.rs b/tests/run-make/autodiff/type-trees/scalar-types/f32-typetree/rmake.rs index ee3ab75..3faba69 100644 --- a/tests/run-make/autodiff/type-trees/scalar-types/f32-typetree/rmake.rs +++ b/tests/run-make/autodiff/type-trees/scalar-types/f32-typetree/rmake.rs
@@ -5,7 +5,7 @@ fn main() { // Compile with TypeTree enabled and emit LLVM IR - rustc().input("test.rs").arg("-Zautodiff=Enable").emit("llvm-ir").run(); + rustc().input("test.rs").arg("-Zautodiff=Enable").arg("-Clto=fat").emit("llvm-ir").run(); // Check that f32 TypeTree metadata is correctly generated llvm_filecheck().patterns("f32.check").stdin_buf(rfs::read("test.ll")).run();
diff --git a/tests/run-make/autodiff/type-trees/scalar-types/f64-typetree/rmake.rs b/tests/run-make/autodiff/type-trees/scalar-types/f64-typetree/rmake.rs index 5fac9b2..4f1c2ce 100644 --- a/tests/run-make/autodiff/type-trees/scalar-types/f64-typetree/rmake.rs +++ b/tests/run-make/autodiff/type-trees/scalar-types/f64-typetree/rmake.rs
@@ -5,7 +5,7 @@ fn main() { // Compile with TypeTree enabled and emit LLVM IR - rustc().input("test.rs").arg("-Zautodiff=Enable").emit("llvm-ir").run(); + rustc().input("test.rs").arg("-Zautodiff=Enable").arg("-Clto=fat").emit("llvm-ir").run(); // Check that f64 TypeTree metadata is correctly generated llvm_filecheck().patterns("f64.check").stdin_buf(rfs::read("test.ll")).run();
diff --git a/tests/run-make/autodiff/type-trees/scalar-types/i32-typetree/rmake.rs b/tests/run-make/autodiff/type-trees/scalar-types/i32-typetree/rmake.rs index a40fd55..328d690 100644 --- a/tests/run-make/autodiff/type-trees/scalar-types/i32-typetree/rmake.rs +++ b/tests/run-make/autodiff/type-trees/scalar-types/i32-typetree/rmake.rs
@@ -5,7 +5,7 @@ fn main() { // Compile with TypeTree enabled and emit LLVM IR - rustc().input("test.rs").arg("-Zautodiff=Enable").emit("llvm-ir").run(); + rustc().input("test.rs").arg("-Zautodiff=Enable").arg("-Clto=fat").emit("llvm-ir").run(); // Check that i32 TypeTree metadata is correctly generated llvm_filecheck().patterns("i32.check").stdin_buf(rfs::read("test.ll")).run();
diff --git a/tests/run-make/autodiff/type-trees/slice-typetree/rmake.rs b/tests/run-make/autodiff/type-trees/slice-typetree/rmake.rs index b81fb50..0cc6b42 100644 --- a/tests/run-make/autodiff/type-trees/slice-typetree/rmake.rs +++ b/tests/run-make/autodiff/type-trees/slice-typetree/rmake.rs
@@ -4,6 +4,6 @@ use run_make_support::{llvm_filecheck, rfs, rustc}; fn main() { - rustc().input("test.rs").arg("-Zautodiff=Enable").emit("llvm-ir").run(); + rustc().input("test.rs").arg("-Zautodiff=Enable").arg("-Clto=fat").emit("llvm-ir").run(); llvm_filecheck().patterns("slice.check").stdin_buf(rfs::read("test.ll")).run(); }
diff --git a/tests/run-make/autodiff/type-trees/struct-typetree/rmake.rs b/tests/run-make/autodiff/type-trees/struct-typetree/rmake.rs index 0af1b65..1049971 100644 --- a/tests/run-make/autodiff/type-trees/struct-typetree/rmake.rs +++ b/tests/run-make/autodiff/type-trees/struct-typetree/rmake.rs
@@ -4,6 +4,6 @@ use run_make_support::{llvm_filecheck, rfs, rustc}; fn main() { - rustc().input("test.rs").arg("-Zautodiff=Enable").emit("llvm-ir").run(); + rustc().input("test.rs").arg("-Zautodiff=Enable").arg("-Clto=fat").emit("llvm-ir").run(); llvm_filecheck().patterns("struct.check").stdin_buf(rfs::read("test.ll")).run(); }
diff --git a/tests/run-make/autodiff/type-trees/tuple-typetree/rmake.rs b/tests/run-make/autodiff/type-trees/tuple-typetree/rmake.rs index 7691382..4c0458f 100644 --- a/tests/run-make/autodiff/type-trees/tuple-typetree/rmake.rs +++ b/tests/run-make/autodiff/type-trees/tuple-typetree/rmake.rs
@@ -4,6 +4,6 @@ use run_make_support::{llvm_filecheck, rfs, rustc}; fn main() { - rustc().input("test.rs").arg("-Zautodiff=Enable").emit("llvm-ir").run(); + rustc().input("test.rs").arg("-Zautodiff=Enable").arg("-Clto=fat").emit("llvm-ir").run(); llvm_filecheck().patterns("tuple.check").stdin_buf(rfs::read("test.ll")).run(); }
diff --git a/tests/run-make/cdylib-export-c-library-symbols/foo.c b/tests/run-make/cdylib-export-c-library-symbols/foo.c new file mode 100644 index 0000000..a062aca --- /dev/null +++ b/tests/run-make/cdylib-export-c-library-symbols/foo.c
@@ -0,0 +1 @@ +void my_function() {}
diff --git a/tests/run-make/cdylib-export-c-library-symbols/foo.rs b/tests/run-make/cdylib-export-c-library-symbols/foo.rs new file mode 100644 index 0000000..ac641aa --- /dev/null +++ b/tests/run-make/cdylib-export-c-library-symbols/foo.rs
@@ -0,0 +1,10 @@ +extern "C" { + pub fn my_function(); +} + +#[no_mangle] +pub extern "C" fn rust_entry() { + unsafe { + my_function(); + } +}
diff --git a/tests/run-make/cdylib-export-c-library-symbols/foo_export.rs b/tests/run-make/cdylib-export-c-library-symbols/foo_export.rs new file mode 100644 index 0000000..1eda294 --- /dev/null +++ b/tests/run-make/cdylib-export-c-library-symbols/foo_export.rs
@@ -0,0 +1,10 @@ +extern "C" { + fn my_function(); +} + +#[no_mangle] +pub extern "C" fn rust_entry() { + unsafe { + my_function(); + } +}
diff --git a/tests/run-make/cdylib-export-c-library-symbols/rmake.rs b/tests/run-make/cdylib-export-c-library-symbols/rmake.rs new file mode 100644 index 0000000..cb237ec --- /dev/null +++ b/tests/run-make/cdylib-export-c-library-symbols/rmake.rs
@@ -0,0 +1,36 @@ +//@ ignore-nvptx64 +//@ ignore-wasm +//@ ignore-cross-compile +// FIXME:The symbol mangle rules are slightly different in Windows(32-bit) and Apple. +// Need to be resolved. +//@ ignore-windows +//@ ignore-apple +// Reason: the compiled binary is executed + +use run_make_support::{build_native_static_lib, cc, dynamic_lib_name, is_darwin, llvm_nm, rustc}; + +fn main() { + cc().input("foo.c").arg("-c").out_exe("foo.o").run(); + build_native_static_lib("foo"); + + rustc().input("foo.rs").arg("-lstatic=foo").crate_type("cdylib").run(); + + let out = llvm_nm() + .input(dynamic_lib_name("foo")) + .run() + .assert_stdout_not_contains_regex("T *my_function"); + + rustc().input("foo_export.rs").arg("-lstatic:+export-symbols=foo").crate_type("cdylib").run(); + + if is_darwin() { + let out = llvm_nm() + .input(dynamic_lib_name("foo_export")) + .run() + .assert_stdout_contains("T _my_function"); + } else { + let out = llvm_nm() + .input(dynamic_lib_name("foo_export")) + .run() + .assert_stdout_contains("T my_function"); + } +}
diff --git a/tests/run-make/rust-lld-custom-target/rmake.rs b/tests/run-make/rust-lld-custom-target/rmake.rs index 90ba424..d281d82 100644 --- a/tests/run-make/rust-lld-custom-target/rmake.rs +++ b/tests/run-make/rust-lld-custom-target/rmake.rs
@@ -15,7 +15,11 @@ fn main() { // Compile to a custom target spec with rust-lld enabled by default. We'll check that by asking // the linker to display its version number with a link-arg. assert_rustc_uses_lld( - rustc().crate_type("cdylib").target("custom-target.json").input("lib.rs"), + rustc() + .crate_type("cdylib") + .target("custom-target.json") + .arg("-Zunstable-options") + .input("lib.rs"), ); // But it can also be disabled via linker features.
diff --git a/tests/run-make/rustdoc-target-spec-json-path/rmake.rs b/tests/run-make/rustdoc-target-spec-json-path/rmake.rs index d43aa9b..8660556 100644 --- a/tests/run-make/rustdoc-target-spec-json-path/rmake.rs +++ b/tests/run-make/rustdoc-target-spec-json-path/rmake.rs
@@ -5,8 +5,14 @@ fn main() { let out_dir = "rustdoc-target-spec-json-path"; - rustc().crate_type("lib").input("dummy_core.rs").target("target.json").run(); + rustc() + .arg("-Zunstable-options") + .crate_type("lib") + .input("dummy_core.rs") + .target("target.json") + .run(); rustdoc() + .arg("-Zunstable-options") .input("my_crate.rs") .out_dir(out_dir) .library_search_path(cwd())
diff --git a/tests/run-make/target-specs/rmake.rs b/tests/run-make/target-specs/rmake.rs index 69292af..6c88f31 100644 --- a/tests/run-make/target-specs/rmake.rs +++ b/tests/run-make/target-specs/rmake.rs
@@ -20,13 +20,20 @@ fn main() { .target("my-incomplete-platform.json") .run_fail() .assert_stderr_contains("missing field `llvm-target`"); - let test_platform = rustc() + let _ = rustc() .input("foo.rs") .target("my-x86_64-unknown-linux-gnu-platform") .crate_type("lib") .emit("asm") .run_fail() .assert_stderr_contains("custom targets are unstable and require `-Zunstable-options`"); + let _ = rustc() + .input("foo.rs") + .target("my-awesome-platform.json") + .crate_type("lib") + .emit("asm") + .run_fail() + .assert_stderr_contains("custom targets are unstable and require `-Zunstable-options`"); rustc() .arg("-Zunstable-options") .env("RUST_TARGET_PATH", ".")
diff --git a/tests/rustdoc-gui/globals.goml b/tests/rustdoc-gui/globals.goml index 4f12175..7fd9c5b 100644 --- a/tests/rustdoc-gui/globals.goml +++ b/tests/rustdoc-gui/globals.goml
@@ -6,7 +6,7 @@ // URL query go-to: "file://" + |DOC_PATH| + "/test_docs/index.html?search=sa" wait-for: "#search-tabs" -assert-window-property-false: {"searchIndex": null} +wait-for-window-property-false: {"searchIndex": null} // Form input go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
diff --git a/tests/rustdoc-ui/bad-render-options.rs b/tests/rustdoc-ui/bad-render-options.rs index 0522f68..c85a818 100644 --- a/tests/rustdoc-ui/bad-render-options.rs +++ b/tests/rustdoc-ui/bad-render-options.rs
@@ -1,29 +1,30 @@ // regression test for https://github.com/rust-lang/rust/issues/149187 +#![deny(invalid_doc_attributes)] #![doc(html_favicon_url)] -//~^ ERROR: malformed `doc` attribute -//~| NOTE expected this to be of the form `html_favicon_url = "..."` +//~^ ERROR +//~| WARN #![doc(html_logo_url)] -//~^ ERROR: malformed `doc` attribute -//~| NOTE expected this to be of the form `html_logo_url = "..."` +//~^ ERROR +//~| WARN #![doc(html_playground_url)] -//~^ ERROR: malformed `doc` attribute -//~| NOTE expected this to be of the form `html_playground_url = "..."` +//~^ ERROR +//~| WARN #![doc(issue_tracker_base_url)] -//~^ ERROR: malformed `doc` attribute -//~| NOTE expected this to be of the form `issue_tracker_base_url = "..."` +//~^ ERROR +//~| WARN #![doc(html_favicon_url = 1)] -//~^ ERROR malformed `doc` attribute -//~| NOTE expected a string literal +//~^ ERROR +//~| WARN #![doc(html_logo_url = 2)] -//~^ ERROR malformed `doc` attribute -//~| NOTE expected a string literal +//~^ ERROR +//~| WARN #![doc(html_playground_url = 3)] -//~^ ERROR malformed `doc` attribute -//~| NOTE expected a string literal +//~^ ERROR +//~| WARN #![doc(issue_tracker_base_url = 4)] -//~^ ERROR malformed `doc` attribute -//~| NOTE expected a string literal +//~^ ERROR +//~| WARN #![doc(html_no_source = "asdf")] -//~^ ERROR malformed `doc` attribute -//~| NOTE didn't expect any arguments here +//~^ ERROR +//~| WARN
diff --git a/tests/rustdoc-ui/bad-render-options.stderr b/tests/rustdoc-ui/bad-render-options.stderr index 28d4533..dac6bc2 100644 --- a/tests/rustdoc-ui/bad-render-options.stderr +++ b/tests/rustdoc-ui/bad-render-options.stderr
@@ -1,76 +1,79 @@ -error[E0539]: malformed `doc` attribute input - --> $DIR/bad-render-options.rs:3:1 +error: expected this to be of the form `... = "..."` + --> $DIR/bad-render-options.rs:4:8 | LL | #![doc(html_favicon_url)] - | ^^^^^^^----------------^^ - | | - | expected this to be of the form `html_favicon_url = "..."` + | ^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! +note: the lint level is defined here + --> $DIR/bad-render-options.rs:2:9 + | +LL | #![deny(invalid_doc_attributes)] + | ^^^^^^^^^^^^^^^^^^^^^^ -error[E0539]: malformed `doc` attribute input - --> $DIR/bad-render-options.rs:6:1 +error: expected this to be of the form `... = "..."` + --> $DIR/bad-render-options.rs:7:8 | LL | #![doc(html_logo_url)] - | ^^^^^^^-------------^^ - | | - | expected this to be of the form `html_logo_url = "..."` + | ^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! -error[E0539]: malformed `doc` attribute input - --> $DIR/bad-render-options.rs:9:1 +error: expected this to be of the form `... = "..."` + --> $DIR/bad-render-options.rs:10:8 | LL | #![doc(html_playground_url)] - | ^^^^^^^-------------------^^ - | | - | expected this to be of the form `html_playground_url = "..."` + | ^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! -error[E0539]: malformed `doc` attribute input - --> $DIR/bad-render-options.rs:12:1 +error: expected this to be of the form `... = "..."` + --> $DIR/bad-render-options.rs:13:8 | LL | #![doc(issue_tracker_base_url)] - | ^^^^^^^----------------------^^ - | | - | expected this to be of the form `issue_tracker_base_url = "..."` + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! -error[E0539]: malformed `doc` attribute input - --> $DIR/bad-render-options.rs:15:1 +error: malformed `doc` attribute input + --> $DIR/bad-render-options.rs:16:27 | LL | #![doc(html_favicon_url = 1)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^-^^ - | | - | expected a string literal here + | ^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! -error[E0539]: malformed `doc` attribute input - --> $DIR/bad-render-options.rs:18:1 +error: malformed `doc` attribute input + --> $DIR/bad-render-options.rs:19:24 | LL | #![doc(html_logo_url = 2)] - | ^^^^^^^^^^^^^^^^^^^^^^^-^^ - | | - | expected a string literal here + | ^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! -error[E0539]: malformed `doc` attribute input - --> $DIR/bad-render-options.rs:21:1 +error: malformed `doc` attribute input + --> $DIR/bad-render-options.rs:22:30 | LL | #![doc(html_playground_url = 3)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-^^ - | | - | expected a string literal here + | ^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! -error[E0539]: malformed `doc` attribute input - --> $DIR/bad-render-options.rs:24:1 +error: malformed `doc` attribute input + --> $DIR/bad-render-options.rs:25:33 | LL | #![doc(issue_tracker_base_url = 4)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-^^ - | | - | expected a string literal here + | ^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! -error[E0565]: malformed `doc` attribute input - --> $DIR/bad-render-options.rs:27:1 +error: didn't expect any arguments here + --> $DIR/bad-render-options.rs:28:23 | LL | #![doc(html_no_source = "asdf")] - | ^^^^^^^^^^^^^^^^^^^^^^--------^^ - | | - | didn't expect any arguments here + | ^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! error: aborting due to 9 previous errors -Some errors have detailed explanations: E0539, E0565. -For more information about an error, try `rustc --explain E0539`.
diff --git a/tests/rustdoc-ui/deprecated-attrs.rs b/tests/rustdoc-ui/deprecated-attrs.rs index 26aaf0d4..dcca311 100644 --- a/tests/rustdoc-ui/deprecated-attrs.rs +++ b/tests/rustdoc-ui/deprecated-attrs.rs
@@ -1,11 +1,13 @@ //@ compile-flags: --passes unknown-pass +#![deny(invalid_doc_attributes)] +//~^ NOTE + #![doc(no_default_passes)] //~^ ERROR unknown `doc` attribute `no_default_passes` //~| NOTE no longer functions //~| NOTE see issue #44136 //~| NOTE `doc(no_default_passes)` is now a no-op -//~| NOTE `#[deny(invalid_doc_attributes)]` on by default #![doc(passes = "collapse-docs unindent-comments")] //~^ ERROR unknown `doc` attribute `passes` //~| NOTE no longer functions
diff --git a/tests/rustdoc-ui/deprecated-attrs.stderr b/tests/rustdoc-ui/deprecated-attrs.stderr index 6135b14..e32a1eb 100644 --- a/tests/rustdoc-ui/deprecated-attrs.stderr +++ b/tests/rustdoc-ui/deprecated-attrs.stderr
@@ -4,17 +4,21 @@ = help: you may want to use --document-private-items error: unknown `doc` attribute `no_default_passes` - --> $DIR/deprecated-attrs.rs:3:8 + --> $DIR/deprecated-attrs.rs:6:8 | LL | #![doc(no_default_passes)] | ^^^^^^^^^^^^^^^^^ no longer functions | = note: `doc` attribute `no_default_passes` no longer functions; see issue #44136 <https://github.com/rust-lang/rust/issues/44136> = note: `doc(no_default_passes)` is now a no-op - = note: `#[deny(invalid_doc_attributes)]` on by default +note: the lint level is defined here + --> $DIR/deprecated-attrs.rs:3:9 + | +LL | #![deny(invalid_doc_attributes)] + | ^^^^^^^^^^^^^^^^^^^^^^ error: unknown `doc` attribute `passes` - --> $DIR/deprecated-attrs.rs:9:8 + --> $DIR/deprecated-attrs.rs:11:8 | LL | #![doc(passes = "collapse-docs unindent-comments")] | ^^^^^^ no longer functions @@ -23,7 +27,7 @@ = note: `doc(passes)` is now a no-op error: unknown `doc` attribute `plugins` - --> $DIR/deprecated-attrs.rs:14:8 + --> $DIR/deprecated-attrs.rs:16:8 | LL | #![doc(plugins = "xxx")] | ^^^^^^^ no longer functions
diff --git a/tests/rustdoc-ui/doc-cfg-2.rs b/tests/rustdoc-ui/doc-cfg-2.rs index 7a5d1f3..f615e96 100644 --- a/tests/rustdoc-ui/doc-cfg-2.rs +++ b/tests/rustdoc-ui/doc-cfg-2.rs
@@ -1,3 +1,4 @@ +#![deny(invalid_doc_attributes)] #![feature(doc_cfg)] #[doc(cfg(foo), cfg(bar))]
diff --git a/tests/rustdoc-ui/doc-cfg-2.stderr b/tests/rustdoc-ui/doc-cfg-2.stderr index 1272e56..a842cbc 100644 --- a/tests/rustdoc-ui/doc-cfg-2.stderr +++ b/tests/rustdoc-ui/doc-cfg-2.stderr
@@ -1,5 +1,5 @@ warning: unexpected `cfg` condition name: `foo` - --> $DIR/doc-cfg-2.rs:3:11 + --> $DIR/doc-cfg-2.rs:4:11 | LL | #[doc(cfg(foo), cfg(bar))] | ^^^ @@ -10,7 +10,7 @@ = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition name: `bar` - --> $DIR/doc-cfg-2.rs:3:21 + --> $DIR/doc-cfg-2.rs:4:21 | LL | #[doc(cfg(foo), cfg(bar))] | ^^^ @@ -19,45 +19,49 @@ = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration error: only `hide` or `show` are allowed in `#[doc(auto_cfg(...))]` - --> $DIR/doc-cfg-2.rs:6:16 + --> $DIR/doc-cfg-2.rs:7:16 | LL | #[doc(auto_cfg(42))] | ^^ | - = note: `#[deny(invalid_doc_attributes)]` on by default +note: the lint level is defined here + --> $DIR/doc-cfg-2.rs:1:9 + | +LL | #![deny(invalid_doc_attributes)] + | ^^^^^^^^^^^^^^^^^^^^^^ error: `#![doc(auto_cfg(hide(...)))]` only accepts identifiers or key/value items - --> $DIR/doc-cfg-2.rs:7:21 + --> $DIR/doc-cfg-2.rs:8:21 | LL | #[doc(auto_cfg(hide(true)))] | ^^^^ error: `#![doc(auto_cfg(hide(...)))]` only accepts identifiers or key/value items - --> $DIR/doc-cfg-2.rs:8:21 + --> $DIR/doc-cfg-2.rs:9:21 | LL | #[doc(auto_cfg(hide(42)))] | ^^ error: `#![doc(auto_cfg(hide(...)))]` only accepts identifiers or key/value items - --> $DIR/doc-cfg-2.rs:9:21 + --> $DIR/doc-cfg-2.rs:10:21 | LL | #[doc(auto_cfg(hide("a")))] | ^^^ error: expected boolean for `#[doc(auto_cfg = ...)]` - --> $DIR/doc-cfg-2.rs:10:18 + --> $DIR/doc-cfg-2.rs:11:18 | LL | #[doc(auto_cfg = 42)] | ^^ error: expected boolean for `#[doc(auto_cfg = ...)]` - --> $DIR/doc-cfg-2.rs:11:18 + --> $DIR/doc-cfg-2.rs:12:18 | LL | #[doc(auto_cfg = "a")] | ^^^ warning: unexpected `cfg` condition name: `feature` - --> $DIR/doc-cfg-2.rs:14:21 + --> $DIR/doc-cfg-2.rs:15:21 | LL | #[doc(auto_cfg(hide(feature = "windows")))] | ^^^^^^^^^^^^^^^^^^^ @@ -66,7 +70,7 @@ = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition name: `foo` - --> $DIR/doc-cfg-2.rs:16:21 + --> $DIR/doc-cfg-2.rs:17:21 | LL | #[doc(auto_cfg(hide(foo)))] | ^^^
diff --git a/tests/rustdoc-ui/doc-cfg.rs b/tests/rustdoc-ui/doc-cfg.rs index f30d80a..abaea97 100644 --- a/tests/rustdoc-ui/doc-cfg.rs +++ b/tests/rustdoc-ui/doc-cfg.rs
@@ -1,9 +1,10 @@ +#![deny(invalid_doc_attributes)] #![feature(doc_cfg)] #[doc(cfg(), cfg(foo, bar))] -//~^ ERROR malformed `doc` attribute input -//~| ERROR malformed `doc` attribute input +//~^ ERROR +//~| ERROR #[doc(cfg())] //~ ERROR #[doc(cfg(foo, bar))] //~ ERROR -#[doc(auto_cfg(hide(foo::bar)))] //~ ERROR +#[doc(auto_cfg(hide(foo::bar)))] pub fn foo() {}
diff --git a/tests/rustdoc-ui/doc-cfg.stderr b/tests/rustdoc-ui/doc-cfg.stderr index ce16ec3..fa25a44 100644 --- a/tests/rustdoc-ui/doc-cfg.stderr +++ b/tests/rustdoc-ui/doc-cfg.stderr
@@ -1,5 +1,5 @@ error[E0805]: malformed `doc` attribute input - --> $DIR/doc-cfg.rs:3:1 + --> $DIR/doc-cfg.rs:4:1 | LL | #[doc(cfg(), cfg(foo, bar))] | ^^^^^^^^^--^^^^^^^^^^^^^^^^^ @@ -7,7 +7,7 @@ | expected a single argument here error[E0805]: malformed `doc` attribute input - --> $DIR/doc-cfg.rs:3:1 + --> $DIR/doc-cfg.rs:4:1 | LL | #[doc(cfg(), cfg(foo, bar))] | ^^^^^^^^^^^^^^^^----------^^ @@ -15,7 +15,7 @@ | expected a single argument here error[E0805]: malformed `doc` attribute input - --> $DIR/doc-cfg.rs:6:1 + --> $DIR/doc-cfg.rs:7:1 | LL | #[doc(cfg())] | ^^^^^^^^^--^^ @@ -23,22 +23,13 @@ | expected a single argument here error[E0805]: malformed `doc` attribute input - --> $DIR/doc-cfg.rs:7:1 + --> $DIR/doc-cfg.rs:8:1 | LL | #[doc(cfg(foo, bar))] | ^^^^^^^^^----------^^ | | | expected a single argument here -error[E0539]: malformed `doc` attribute input - --> $DIR/doc-cfg.rs:8:1 - | -LL | #[doc(auto_cfg(hide(foo::bar)))] - | ^^^^^^^^^^^^^^^^^^^^--------^^^^ - | | - | expected a valid identifier here +error: aborting due to 4 previous errors -error: aborting due to 5 previous errors - -Some errors have detailed explanations: E0539, E0805. -For more information about an error, try `rustc --explain E0539`. +For more information about this error, try `rustc --explain E0805`.
diff --git a/tests/rustdoc-ui/doc-include-suggestion.rs b/tests/rustdoc-ui/doc-include-suggestion.rs index aff0a24..1295805 100644 --- a/tests/rustdoc-ui/doc-include-suggestion.rs +++ b/tests/rustdoc-ui/doc-include-suggestion.rs
@@ -1,6 +1,8 @@ +#![deny(invalid_doc_attributes)] +//~^ NOTE + #[doc(include = "external-cross-doc.md")] //~^ ERROR unknown `doc` attribute `include` //~| HELP use `doc = include_str!` instead // FIXME(#85497): make this a deny instead so it's more clear what's happening -//~| NOTE on by default pub struct NeedMoreDocs;
diff --git a/tests/rustdoc-ui/doc-include-suggestion.stderr b/tests/rustdoc-ui/doc-include-suggestion.stderr index ea5261e..1587984 100644 --- a/tests/rustdoc-ui/doc-include-suggestion.stderr +++ b/tests/rustdoc-ui/doc-include-suggestion.stderr
@@ -1,10 +1,14 @@ error: unknown `doc` attribute `include` - --> $DIR/doc-include-suggestion.rs:1:7 + --> $DIR/doc-include-suggestion.rs:4:7 | LL | #[doc(include = "external-cross-doc.md")] | ^^^^^^^ help: use `doc = include_str!` instead: `#[doc = include_str!("external-cross-doc.md")]` | - = note: `#[deny(invalid_doc_attributes)]` on by default +note: the lint level is defined here + --> $DIR/doc-include-suggestion.rs:1:9 + | +LL | #![deny(invalid_doc_attributes)] + | ^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 1 previous error
diff --git a/tests/rustdoc-ui/doctest/doc-test-attr.rs b/tests/rustdoc-ui/doctest/doc-test-attr.rs index 8570252..e664f75 100644 --- a/tests/rustdoc-ui/doctest/doc-test-attr.rs +++ b/tests/rustdoc-ui/doctest/doc-test-attr.rs
@@ -1,3 +1,4 @@ +#![deny(invalid_doc_attributes)] #![crate_type = "lib"] #![doc(test)]
diff --git a/tests/rustdoc-ui/doctest/doc-test-attr.stderr b/tests/rustdoc-ui/doctest/doc-test-attr.stderr index cf7bce6..98e7b31 100644 --- a/tests/rustdoc-ui/doctest/doc-test-attr.stderr +++ b/tests/rustdoc-ui/doctest/doc-test-attr.stderr
@@ -1,19 +1,23 @@ error: `#[doc(test(...)]` takes a list of attributes - --> $DIR/doc-test-attr.rs:3:8 + --> $DIR/doc-test-attr.rs:4:8 | LL | #![doc(test)] | ^^^^ | - = note: `#[deny(invalid_doc_attributes)]` on by default +note: the lint level is defined here + --> $DIR/doc-test-attr.rs:1:9 + | +LL | #![deny(invalid_doc_attributes)] + | ^^^^^^^^^^^^^^^^^^^^^^ error: `#[doc(test(...)]` takes a list of attributes - --> $DIR/doc-test-attr.rs:5:13 + --> $DIR/doc-test-attr.rs:6:13 | LL | #![doc(test = "hello")] | ^^^^^^^^^ error: unknown `doc(test)` attribute `a` - --> $DIR/doc-test-attr.rs:7:13 + --> $DIR/doc-test-attr.rs:8:13 | LL | #![doc(test(a))] | ^
diff --git a/tests/rustdoc-ui/lints/doc-attr-2.rs b/tests/rustdoc-ui/lints/doc-attr-2.rs index e5198e3..9802fb5 100644 --- a/tests/rustdoc-ui/lints/doc-attr-2.rs +++ b/tests/rustdoc-ui/lints/doc-attr-2.rs
@@ -1,3 +1,4 @@ +#![deny(invalid_doc_attributes)] #![doc(as_ptr)] //~^ ERROR unknown `doc` attribute `as_ptr`
diff --git a/tests/rustdoc-ui/lints/doc-attr-2.stderr b/tests/rustdoc-ui/lints/doc-attr-2.stderr index c2bb45c..f96eab1 100644 --- a/tests/rustdoc-ui/lints/doc-attr-2.stderr +++ b/tests/rustdoc-ui/lints/doc-attr-2.stderr
@@ -1,25 +1,29 @@ error: unknown `doc` attribute `as_ptr` - --> $DIR/doc-attr-2.rs:4:7 + --> $DIR/doc-attr-2.rs:5:7 | LL | #[doc(as_ptr)] | ^^^^^^ | - = note: `#[deny(invalid_doc_attributes)]` on by default +note: the lint level is defined here + --> $DIR/doc-attr-2.rs:1:9 + | +LL | #![deny(invalid_doc_attributes)] + | ^^^^^^^^^^^^^^^^^^^^^^ error: unknown `doc` attribute `foo::bar` - --> $DIR/doc-attr-2.rs:8:7 + --> $DIR/doc-attr-2.rs:9:7 | LL | #[doc(foo::bar, crate::bar::baz = "bye")] | ^^^^^^^^ error: unknown `doc` attribute `crate::bar::baz` - --> $DIR/doc-attr-2.rs:8:17 + --> $DIR/doc-attr-2.rs:9:17 | LL | #[doc(foo::bar, crate::bar::baz = "bye")] | ^^^^^^^^^^^^^^^ error: unknown `doc` attribute `as_ptr` - --> $DIR/doc-attr-2.rs:1:8 + --> $DIR/doc-attr-2.rs:2:8 | LL | #![doc(as_ptr)] | ^^^^^^
diff --git a/tests/rustdoc-ui/lints/doc-attr.rs b/tests/rustdoc-ui/lints/doc-attr.rs index b27faa8..46d56e7 100644 --- a/tests/rustdoc-ui/lints/doc-attr.rs +++ b/tests/rustdoc-ui/lints/doc-attr.rs
@@ -1,8 +1,12 @@ #![crate_type = "lib"] +#![deny(invalid_doc_attributes)] #[doc(123)] -//~^ ERROR malformed `doc` attribute +//~^ ERROR +//~| WARN #[doc("hello", "bar")] -//~^ ERROR malformed `doc` attribute -//~| ERROR malformed `doc` attribute +//~^ ERROR +//~| ERROR +//~| WARN +//~| WARN fn bar() {}
diff --git a/tests/rustdoc-ui/lints/doc-attr.stderr b/tests/rustdoc-ui/lints/doc-attr.stderr index 8f8c600..263b068 100644 --- a/tests/rustdoc-ui/lints/doc-attr.stderr +++ b/tests/rustdoc-ui/lints/doc-attr.stderr
@@ -1,27 +1,31 @@ -error[E0539]: malformed `doc` attribute input - --> $DIR/doc-attr.rs:3:1 +error: expected this to be of the form `... = "..."` + --> $DIR/doc-attr.rs:4:7 | LL | #[doc(123)] - | ^^^^^^---^^ - | | - | expected this to be of the form `... = "..."` + | ^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! +note: the lint level is defined here + --> $DIR/doc-attr.rs:2:9 + | +LL | #![deny(invalid_doc_attributes)] + | ^^^^^^^^^^^^^^^^^^^^^^ -error[E0539]: malformed `doc` attribute input - --> $DIR/doc-attr.rs:5:1 +error: expected this to be of the form `... = "..."` + --> $DIR/doc-attr.rs:7:7 | LL | #[doc("hello", "bar")] - | ^^^^^^-------^^^^^^^^^ - | | - | expected this to be of the form `... = "..."` + | ^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! -error[E0539]: malformed `doc` attribute input - --> $DIR/doc-attr.rs:5:1 +error: expected this to be of the form `... = "..."` + --> $DIR/doc-attr.rs:7:16 | LL | #[doc("hello", "bar")] - | ^^^^^^^^^^^^^^^-----^^ - | | - | expected this to be of the form `... = "..."` + | ^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0539`.
diff --git a/tests/rustdoc-ui/lints/doc-spotlight.fixed b/tests/rustdoc-ui/lints/doc-spotlight.fixed index 0f8f11a..98b0fac 100644 --- a/tests/rustdoc-ui/lints/doc-spotlight.fixed +++ b/tests/rustdoc-ui/lints/doc-spotlight.fixed
@@ -1,5 +1,6 @@ //@ run-rustfix #![feature(doc_notable_trait)] +#![deny(invalid_doc_attributes)] #[doc(notable_trait)] //~^ ERROR unknown `doc` attribute `spotlight`
diff --git a/tests/rustdoc-ui/lints/doc-spotlight.rs b/tests/rustdoc-ui/lints/doc-spotlight.rs index c1f90dd..a0d874b 100644 --- a/tests/rustdoc-ui/lints/doc-spotlight.rs +++ b/tests/rustdoc-ui/lints/doc-spotlight.rs
@@ -1,5 +1,6 @@ //@ run-rustfix #![feature(doc_notable_trait)] +#![deny(invalid_doc_attributes)] #[doc(spotlight)] //~^ ERROR unknown `doc` attribute `spotlight`
diff --git a/tests/rustdoc-ui/lints/doc-spotlight.stderr b/tests/rustdoc-ui/lints/doc-spotlight.stderr index 9682a3c..8c6f973 100644 --- a/tests/rustdoc-ui/lints/doc-spotlight.stderr +++ b/tests/rustdoc-ui/lints/doc-spotlight.stderr
@@ -1,12 +1,16 @@ error: unknown `doc` attribute `spotlight` - --> $DIR/doc-spotlight.rs:4:7 + --> $DIR/doc-spotlight.rs:5:7 | LL | #[doc(spotlight)] | ^^^^^^^^^ help: use `notable_trait` instead | = note: `doc(spotlight)` was renamed to `doc(notable_trait)` = note: `doc(spotlight)` is now a no-op - = note: `#[deny(invalid_doc_attributes)]` on by default +note: the lint level is defined here + --> $DIR/doc-spotlight.rs:3:9 + | +LL | #![deny(invalid_doc_attributes)] + | ^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 1 previous error
diff --git a/tests/rustdoc-ui/lints/doc_cfg_hide.rs b/tests/rustdoc-ui/lints/doc_cfg_hide.rs index 397b213..6c190f9 100644 --- a/tests/rustdoc-ui/lints/doc_cfg_hide.rs +++ b/tests/rustdoc-ui/lints/doc_cfg_hide.rs
@@ -1,3 +1,4 @@ +#![deny(invalid_doc_attributes)] #![feature(doc_cfg)] #![doc(auto_cfg(hide = "test"))] //~ ERROR #![doc(auto_cfg(hide))] //~ ERROR
diff --git a/tests/rustdoc-ui/lints/doc_cfg_hide.stderr b/tests/rustdoc-ui/lints/doc_cfg_hide.stderr index acbe6ef..a5ec8fd 100644 --- a/tests/rustdoc-ui/lints/doc_cfg_hide.stderr +++ b/tests/rustdoc-ui/lints/doc_cfg_hide.stderr
@@ -1,19 +1,23 @@ error: `#![doc(auto_cfg(hide(...)))]` expects a list of items - --> $DIR/doc_cfg_hide.rs:2:17 + --> $DIR/doc_cfg_hide.rs:3:17 | LL | #![doc(auto_cfg(hide = "test"))] | ^^^^^^^^^^^^^ | - = note: `#[deny(invalid_doc_attributes)]` on by default +note: the lint level is defined here + --> $DIR/doc_cfg_hide.rs:1:9 + | +LL | #![deny(invalid_doc_attributes)] + | ^^^^^^^^^^^^^^^^^^^^^^ error: `#![doc(auto_cfg(hide(...)))]` expects a list of items - --> $DIR/doc_cfg_hide.rs:3:17 + --> $DIR/doc_cfg_hide.rs:4:17 | LL | #![doc(auto_cfg(hide))] | ^^^^ error: `#![doc(auto_cfg(hide(...)))]` only accepts identifiers or key/value items - --> $DIR/doc_cfg_hide.rs:4:22 + --> $DIR/doc_cfg_hide.rs:5:22 | LL | #![doc(auto_cfg(hide(not(windows))))] | ^^^^^^^^^^^^
diff --git a/tests/rustdoc-ui/lints/duplicated-attr.rs b/tests/rustdoc-ui/lints/duplicated-attr.rs new file mode 100644 index 0000000..b89908d --- /dev/null +++ b/tests/rustdoc-ui/lints/duplicated-attr.rs
@@ -0,0 +1,6 @@ +#![deny(invalid_doc_attributes)] +#![expect(unused_attributes)] +#![doc(test(no_crate_inject))] +#![doc(test(no_crate_inject))] +//~^ ERROR +//~| WARN
diff --git a/tests/rustdoc-ui/lints/duplicated-attr.stderr b/tests/rustdoc-ui/lints/duplicated-attr.stderr new file mode 100644 index 0000000..3682710 --- /dev/null +++ b/tests/rustdoc-ui/lints/duplicated-attr.stderr
@@ -0,0 +1,20 @@ +error: unused attribute + --> $DIR/duplicated-attr.rs:4:13 + | +LL | #![doc(test(no_crate_inject))] + | ^^^^^^^^^^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/duplicated-attr.rs:3:13 + | +LL | #![doc(test(no_crate_inject))] + | ^^^^^^^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! +note: the lint level is defined here + --> $DIR/duplicated-attr.rs:1:9 + | +LL | #![deny(invalid_doc_attributes)] + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error +
diff --git a/tests/rustdoc-ui/lints/invalid-crate-level-lint.rs b/tests/rustdoc-ui/lints/invalid-crate-level-lint.rs index 275e20e..afb0a59 100644 --- a/tests/rustdoc-ui/lints/invalid-crate-level-lint.rs +++ b/tests/rustdoc-ui/lints/invalid-crate-level-lint.rs
@@ -1,3 +1,4 @@ +#![deny(invalid_doc_attributes)] #![crate_type = "lib"] #[doc(test(no_crate_inject))]
diff --git a/tests/rustdoc-ui/lints/invalid-crate-level-lint.stderr b/tests/rustdoc-ui/lints/invalid-crate-level-lint.stderr index fdb95e7..7569cf5 100644 --- a/tests/rustdoc-ui/lints/invalid-crate-level-lint.stderr +++ b/tests/rustdoc-ui/lints/invalid-crate-level-lint.stderr
@@ -1,14 +1,18 @@ error: this attribute can only be applied at the crate level - --> $DIR/invalid-crate-level-lint.rs:3:12 + --> $DIR/invalid-crate-level-lint.rs:4:12 | LL | #[doc(test(no_crate_inject))] | ^^^^^^^^^^^^^^^ | = note: read <https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level> for more information - = note: `#[deny(invalid_doc_attributes)]` on by default +note: the lint level is defined here + --> $DIR/invalid-crate-level-lint.rs:1:9 + | +LL | #![deny(invalid_doc_attributes)] + | ^^^^^^^^^^^^^^^^^^^^^^ error: this attribute can only be applied at the crate level - --> $DIR/invalid-crate-level-lint.rs:7:17 + --> $DIR/invalid-crate-level-lint.rs:8:17 | LL | #![doc(test(no_crate_inject))] | ^^^^^^^^^^^^^^^ @@ -16,7 +20,7 @@ = note: read <https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level> for more information error: this attribute can only be applied at the crate level - --> $DIR/invalid-crate-level-lint.rs:10:16 + --> $DIR/invalid-crate-level-lint.rs:11:16 | LL | #[doc(test(no_crate_inject))] | ^^^^^^^^^^^^^^^
diff --git a/tests/rustdoc-ui/lints/invalid-doc-attr-2.rs b/tests/rustdoc-ui/lints/invalid-doc-attr-2.rs new file mode 100644 index 0000000..de99d5a --- /dev/null +++ b/tests/rustdoc-ui/lints/invalid-doc-attr-2.rs
@@ -0,0 +1,7 @@ +#![deny(invalid_doc_attributes)] + +#![doc("other attribute")] +//~^ ERROR +//~| WARN +#![doc] +//~^ ERROR
diff --git a/tests/rustdoc-ui/lints/invalid-doc-attr-2.stderr b/tests/rustdoc-ui/lints/invalid-doc-attr-2.stderr new file mode 100644 index 0000000..2457352 --- /dev/null +++ b/tests/rustdoc-ui/lints/invalid-doc-attr-2.stderr
@@ -0,0 +1,21 @@ +error: expected this to be of the form `... = "..."` + --> $DIR/invalid-doc-attr-2.rs:3:8 + | +LL | #![doc("other attribute")] + | ^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! +note: the lint level is defined here + --> $DIR/invalid-doc-attr-2.rs:1:9 + | +LL | #![deny(invalid_doc_attributes)] + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: valid forms for the attribute are `#![doc = "string"]`, `#![doc(alias)]`, `#![doc(attribute)]`, `#![doc(auto_cfg)]`, `#![doc(cfg)]`, `#![doc(fake_variadic)]`, `#![doc(hidden)]`, `#![doc(html_favicon_url)]`, `#![doc(html_logo_url)]`, `#![doc(html_no_source)]`, `#![doc(html_playground_url)]`, `#![doc(html_root_url)]`, `#![doc(include)]`, `#![doc(inline)]`, `#![doc(issue_tracker_base_url)]`, `#![doc(keyword)]`, `#![doc(masked)]`, `#![doc(no_default_passes)]`, `#![doc(no_inline)]`, `#![doc(notable_trait)]`, `#![doc(passes)]`, `#![doc(plugins)]`, `#![doc(rust_logo)]`, `#![doc(search_unbox)]`, `#![doc(spotlight)]`, and `#![doc(test)]` + --> $DIR/invalid-doc-attr-2.rs:6:1 + | +LL | #![doc] + | ^^^^^^^ + +error: aborting due to 2 previous errors +
diff --git a/tests/rustdoc-ui/lints/invalid-doc-attr-3.rs b/tests/rustdoc-ui/lints/invalid-doc-attr-3.rs new file mode 100644 index 0000000..1d2e444 --- /dev/null +++ b/tests/rustdoc-ui/lints/invalid-doc-attr-3.rs
@@ -0,0 +1,22 @@ +#![deny(invalid_doc_attributes)] + +#![doc(test(no_crate_inject = 1))] +//~^ ERROR +//~| WARN +#![doc(test(attr = 1))] +//~^ ERROR +//~| WARN + +#[doc(hidden = true)] +//~^ ERROR +//~| WARN +#[doc(hidden("or you will be fired"))] +//~^ ERROR +//~| WARN +#[doc(hidden = "handled transparently by codegen")] +//~^ ERROR +//~| WARN +#[doc = 1] +//~^ ERROR +//~| WARN +pub struct X;
diff --git a/tests/rustdoc-ui/lints/invalid-doc-attr-3.stderr b/tests/rustdoc-ui/lints/invalid-doc-attr-3.stderr new file mode 100644 index 0000000..9cec930 --- /dev/null +++ b/tests/rustdoc-ui/lints/invalid-doc-attr-3.stderr
@@ -0,0 +1,55 @@ +error: didn't expect any arguments here + --> $DIR/invalid-doc-attr-3.rs:10:14 + | +LL | #[doc(hidden = true)] + | ^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! +note: the lint level is defined here + --> $DIR/invalid-doc-attr-3.rs:1:9 + | +LL | #![deny(invalid_doc_attributes)] + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: didn't expect any arguments here + --> $DIR/invalid-doc-attr-3.rs:13:13 + | +LL | #[doc(hidden("or you will be fired"))] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + +error: didn't expect any arguments here + --> $DIR/invalid-doc-attr-3.rs:16:14 + | +LL | #[doc(hidden = "handled transparently by codegen")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + +error: malformed `doc` attribute input + --> $DIR/invalid-doc-attr-3.rs:19:9 + | +LL | #[doc = 1] + | ^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + +error: didn't expect any arguments here + --> $DIR/invalid-doc-attr-3.rs:3:29 + | +LL | #![doc(test(no_crate_inject = 1))] + | ^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + +error: malformed `doc` attribute input + --> $DIR/invalid-doc-attr-3.rs:6:1 + | +LL | #![doc(test(attr = 1))] + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + +error: aborting due to 6 previous errors +
diff --git a/tests/rustdoc-ui/lints/invalid-doc-attr.rs b/tests/rustdoc-ui/lints/invalid-doc-attr.rs index 169d092..60c2152 100644 --- a/tests/rustdoc-ui/lints/invalid-doc-attr.rs +++ b/tests/rustdoc-ui/lints/invalid-doc-attr.rs
@@ -1,3 +1,4 @@ +#![deny(invalid_doc_attributes)] #![crate_type = "lib"] #![feature(doc_masked)]
diff --git a/tests/rustdoc-ui/lints/invalid-doc-attr.stderr b/tests/rustdoc-ui/lints/invalid-doc-attr.stderr index e431b8d..2e9b9f0 100644 --- a/tests/rustdoc-ui/lints/invalid-doc-attr.stderr +++ b/tests/rustdoc-ui/lints/invalid-doc-attr.stderr
@@ -1,5 +1,5 @@ error: this attribute can only be applied to a `use` item - --> $DIR/invalid-doc-attr.rs:7:7 + --> $DIR/invalid-doc-attr.rs:8:7 | LL | #[doc(inline)] | ^^^^^^ only applicable on `use` items @@ -8,10 +8,14 @@ | ------------ not a `use` item | = note: read <https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#inline-and-no_inline> for more information - = note: `#[deny(invalid_doc_attributes)]` on by default +note: the lint level is defined here + --> $DIR/invalid-doc-attr.rs:1:9 + | +LL | #![deny(invalid_doc_attributes)] + | ^^^^^^^^^^^^^^^^^^^^^^ error: conflicting doc inlining attributes - --> $DIR/invalid-doc-attr.rs:17:7 + --> $DIR/invalid-doc-attr.rs:18:7 | LL | #[doc(inline)] | ^^^^^^ this attribute... @@ -21,7 +25,7 @@ = help: remove one of the conflicting attributes error: this attribute can only be applied to an `extern crate` item - --> $DIR/invalid-doc-attr.rs:23:7 + --> $DIR/invalid-doc-attr.rs:24:7 | LL | #[doc(masked)] | ^^^^^^ only applicable on `extern crate` items @@ -32,7 +36,7 @@ = note: read <https://doc.rust-lang.org/unstable-book/language-features/doc-masked.html> for more information error: this attribute cannot be applied to an `extern crate self` item - --> $DIR/invalid-doc-attr.rs:27:7 + --> $DIR/invalid-doc-attr.rs:28:7 | LL | #[doc(masked)] | ^^^^^^ not applicable on `extern crate self` items @@ -41,9 +45,10 @@ | --------------------------------- `extern crate self` defined here error: this attribute can only be applied to an `extern crate` item - --> $DIR/invalid-doc-attr.rs:4:8 + --> $DIR/invalid-doc-attr.rs:5:8 | -LL | / #![crate_type = "lib"] +LL | / #![deny(invalid_doc_attributes)] +LL | | #![crate_type = "lib"] LL | | #![feature(doc_masked)] LL | | LL | | #![doc(masked)] @@ -55,7 +60,7 @@ = note: read <https://doc.rust-lang.org/unstable-book/language-features/doc-masked.html> for more information error: this attribute can only be applied to a `use` item - --> $DIR/invalid-doc-attr.rs:12:11 + --> $DIR/invalid-doc-attr.rs:13:11 | LL | #[doc(inline)] | ^^^^^^ only applicable on `use` items
diff --git a/tests/ui-fulldeps/obtain-borrowck.rs b/tests/ui-fulldeps/obtain-borrowck.rs index a562d0c..ea2dab6 100644 --- a/tests/ui-fulldeps/obtain-borrowck.rs +++ b/tests/ui-fulldeps/obtain-borrowck.rs
@@ -37,7 +37,7 @@ use rustc_hir::def_id::LocalDefId; use rustc_interface::Config; use rustc_interface::interface::Compiler; -use rustc_middle::query::queries::mir_borrowck::ProvidedValue; +use rustc_middle::queries::mir_borrowck::ProvidedValue; use rustc_middle::ty::TyCtxt; use rustc_middle::util::Providers; use rustc_session::Session;
diff --git a/tests/ui/attributes/doc-attr.rs b/tests/ui/attributes/doc-attr.rs index 8d733be..8c81bc1 100644 --- a/tests/ui/attributes/doc-attr.rs +++ b/tests/ui/attributes/doc-attr.rs
@@ -1,3 +1,4 @@ +#![deny(invalid_doc_attributes)] #![crate_type = "lib"] #![doc(as_ptr)] //~^ ERROR unknown `doc` attribute @@ -7,10 +8,13 @@ pub fn foo() {} #[doc(123)] -//~^ ERROR malformed `doc` attribute +//~^ ERROR +//~| WARN #[doc("hello", "bar")] -//~^ ERROR malformed `doc` attribute -//~| ERROR malformed `doc` attribute +//~^ ERROR +//~| ERROR +//~| WARN +//~| WARN #[doc(foo::bar, crate::bar::baz = "bye")] //~^ ERROR unknown `doc` attribute //~| ERROR unknown `doc` attribute
diff --git a/tests/ui/attributes/doc-attr.stderr b/tests/ui/attributes/doc-attr.stderr index dfc0e8a..79d9fb5 100644 --- a/tests/ui/attributes/doc-attr.stderr +++ b/tests/ui/attributes/doc-attr.stderr
@@ -1,53 +1,56 @@ -error[E0539]: malformed `doc` attribute input - --> $DIR/doc-attr.rs:9:1 - | -LL | #[doc(123)] - | ^^^^^^---^^ - | | - | expected this to be of the form `... = "..."` - -error[E0539]: malformed `doc` attribute input - --> $DIR/doc-attr.rs:11:1 - | -LL | #[doc("hello", "bar")] - | ^^^^^^-------^^^^^^^^^ - | | - | expected this to be of the form `... = "..."` - -error[E0539]: malformed `doc` attribute input - --> $DIR/doc-attr.rs:11:1 - | -LL | #[doc("hello", "bar")] - | ^^^^^^^^^^^^^^^-----^^ - | | - | expected this to be of the form `... = "..."` - error: unknown `doc` attribute `as_ptr` - --> $DIR/doc-attr.rs:5:7 + --> $DIR/doc-attr.rs:6:7 | LL | #[doc(as_ptr)] | ^^^^^^ | - = note: `#[deny(invalid_doc_attributes)]` on by default +note: the lint level is defined here + --> $DIR/doc-attr.rs:1:9 + | +LL | #![deny(invalid_doc_attributes)] + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: expected this to be of the form `... = "..."` + --> $DIR/doc-attr.rs:10:7 + | +LL | #[doc(123)] + | ^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + +error: expected this to be of the form `... = "..."` + --> $DIR/doc-attr.rs:13:7 + | +LL | #[doc("hello", "bar")] + | ^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + +error: expected this to be of the form `... = "..."` + --> $DIR/doc-attr.rs:13:16 + | +LL | #[doc("hello", "bar")] + | ^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! error: unknown `doc` attribute `foo::bar` - --> $DIR/doc-attr.rs:14:7 + --> $DIR/doc-attr.rs:18:7 | LL | #[doc(foo::bar, crate::bar::baz = "bye")] | ^^^^^^^^ error: unknown `doc` attribute `crate::bar::baz` - --> $DIR/doc-attr.rs:14:17 + --> $DIR/doc-attr.rs:18:17 | LL | #[doc(foo::bar, crate::bar::baz = "bye")] | ^^^^^^^^^^^^^^^ error: unknown `doc` attribute `as_ptr` - --> $DIR/doc-attr.rs:2:8 + --> $DIR/doc-attr.rs:3:8 | LL | #![doc(as_ptr)] | ^^^^^^ error: aborting due to 7 previous errors -For more information about this error, try `rustc --explain E0539`.
diff --git a/tests/ui/attributes/doc-test-literal.rs b/tests/ui/attributes/doc-test-literal.rs index f9776e9..ceb8967 100644 --- a/tests/ui/attributes/doc-test-literal.rs +++ b/tests/ui/attributes/doc-test-literal.rs
@@ -1,4 +1,7 @@ +#![deny(invalid_doc_attributes)] + #![doc(test(""))] -//~^ ERROR malformed `doc` attribute input +//~^ ERROR +//~| WARN fn main() {}
diff --git a/tests/ui/attributes/doc-test-literal.stderr b/tests/ui/attributes/doc-test-literal.stderr index 2d70d5d..c26aa94 100644 --- a/tests/ui/attributes/doc-test-literal.stderr +++ b/tests/ui/attributes/doc-test-literal.stderr
@@ -1,11 +1,15 @@ -error[E0565]: malformed `doc` attribute input - --> $DIR/doc-test-literal.rs:1:1 +error: malformed `doc` attribute input + --> $DIR/doc-test-literal.rs:3:13 | LL | #![doc(test(""))] - | ^^^^^^^^^^^^--^^^ - | | - | didn't expect a literal here + | ^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! +note: the lint level is defined here + --> $DIR/doc-test-literal.rs:1:9 + | +LL | #![deny(invalid_doc_attributes)] + | ^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0565`.
diff --git a/tests/ui/attributes/malformed-attrs.rs b/tests/ui/attributes/malformed-attrs.rs index b0d8fd7..6dc3086 100644 --- a/tests/ui/attributes/malformed-attrs.rs +++ b/tests/ui/attributes/malformed-attrs.rs
@@ -1,5 +1,6 @@ // This file contains a bunch of malformed attributes. // We enable a bunch of features to not get feature-gate errs in this test. +#![deny(invalid_doc_attributes)] #![feature(rustc_attrs)] #![feature(rustc_allow_const_fn_unstable)] #![feature(allow_internal_unstable)] @@ -39,8 +40,7 @@ #[deprecated = 5] //~^ ERROR malformed #[doc] -//~^ ERROR valid forms for the attribute are -//~| WARN this was previously accepted by the compiler +//~^ ERROR #[rustc_macro_transparency] //~^ ERROR malformed //~| ERROR attribute cannot be used on @@ -75,8 +75,7 @@ //~^ ERROR malformed //~| WARN crate-level attribute should be an inner attribute #[doc] -//~^ ERROR valid forms for the attribute are -//~| WARN this was previously accepted by the compiler +//~^ ERROR #[target_feature] //~^ ERROR malformed #[export_stable = 1]
diff --git a/tests/ui/attributes/malformed-attrs.stderr b/tests/ui/attributes/malformed-attrs.stderr index f817a0b..22e222e 100644 --- a/tests/ui/attributes/malformed-attrs.stderr +++ b/tests/ui/attributes/malformed-attrs.stderr
@@ -1,5 +1,5 @@ error[E0539]: malformed `cfg` attribute input - --> $DIR/malformed-attrs.rs:108:1 + --> $DIR/malformed-attrs.rs:107:1 | LL | #[cfg] | ^^^^^^ @@ -10,7 +10,7 @@ = note: for more information, visit <https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg-attribute> error[E0539]: malformed `cfg_attr` attribute input - --> $DIR/malformed-attrs.rs:110:1 + --> $DIR/malformed-attrs.rs:109:1 | LL | #[cfg_attr] | ^^^^^^^^^^^ @@ -21,13 +21,13 @@ = note: for more information, visit <https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg_attr-attribute> error[E0463]: can't find crate for `wloop` - --> $DIR/malformed-attrs.rs:218:1 + --> $DIR/malformed-attrs.rs:217:1 | LL | extern crate wloop; | ^^^^^^^^^^^^^^^^^^^ can't find crate error: malformed `allow` attribute input - --> $DIR/malformed-attrs.rs:184:1 + --> $DIR/malformed-attrs.rs:183:1 | LL | #[allow] | ^^^^^^^^ @@ -43,7 +43,7 @@ | +++++++++++++++++++++++++++++++++++++ error: malformed `expect` attribute input - --> $DIR/malformed-attrs.rs:186:1 + --> $DIR/malformed-attrs.rs:185:1 | LL | #[expect] | ^^^^^^^^^ @@ -59,7 +59,7 @@ | +++++++++++++++++++++++++++++++++++++ error: malformed `warn` attribute input - --> $DIR/malformed-attrs.rs:188:1 + --> $DIR/malformed-attrs.rs:187:1 | LL | #[warn] | ^^^^^^^ @@ -75,7 +75,7 @@ | +++++++++++++++++++++++++++++++++++++ error: malformed `deny` attribute input - --> $DIR/malformed-attrs.rs:190:1 + --> $DIR/malformed-attrs.rs:189:1 | LL | #[deny] | ^^^^^^^ @@ -91,7 +91,7 @@ | +++++++++++++++++++++++++++++++++++++ error: malformed `forbid` attribute input - --> $DIR/malformed-attrs.rs:192:1 + --> $DIR/malformed-attrs.rs:191:1 | LL | #[forbid] | ^^^^^^^^^ @@ -107,25 +107,25 @@ | +++++++++++++++++++++++++++++++++++++ error: the `#[proc_macro]` attribute is only usable with crates of the `proc-macro` crate type - --> $DIR/malformed-attrs.rs:105:1 + --> $DIR/malformed-attrs.rs:104:1 | LL | #[proc_macro = 18] | ^^^^^^^^^^^^^^^^^^ error: the `#[proc_macro_attribute]` attribute is only usable with crates of the `proc-macro` crate type - --> $DIR/malformed-attrs.rs:122:1 + --> $DIR/malformed-attrs.rs:121:1 | LL | #[proc_macro_attribute = 19] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: the `#[proc_macro_derive]` attribute is only usable with crates of the `proc-macro` crate type - --> $DIR/malformed-attrs.rs:129:1 + --> $DIR/malformed-attrs.rs:128:1 | LL | #[proc_macro_derive] | ^^^^^^^^^^^^^^^^^^^^ error[E0658]: allow_internal_unsafe side-steps the unsafe_code lint - --> $DIR/malformed-attrs.rs:223:1 + --> $DIR/malformed-attrs.rs:222:1 | LL | #[allow_internal_unsafe = 1] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -134,7 +134,7 @@ = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0539]: malformed `windows_subsystem` attribute input - --> $DIR/malformed-attrs.rs:26:1 + --> $DIR/malformed-attrs.rs:27:1 | LL | #![windows_subsystem] | ^^^-----------------^ @@ -150,25 +150,25 @@ | +++++++++++ error[E0539]: malformed `export_name` attribute input - --> $DIR/malformed-attrs.rs:29:1 + --> $DIR/malformed-attrs.rs:30:1 | LL | #[unsafe(export_name)] | ^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[export_name = "name"]` error: `rustc_allow_const_fn_unstable` expects a list of feature names - --> $DIR/malformed-attrs.rs:31:1 + --> $DIR/malformed-attrs.rs:32:1 | LL | #[rustc_allow_const_fn_unstable] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `allow_internal_unstable` expects a list of feature names - --> $DIR/malformed-attrs.rs:34:1 + --> $DIR/malformed-attrs.rs:35:1 | LL | #[allow_internal_unstable] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0539]: malformed `rustc_confusables` attribute input - --> $DIR/malformed-attrs.rs:36:1 + --> $DIR/malformed-attrs.rs:37:1 | LL | #[rustc_confusables] | ^^^^^^^^^^^^^^^^^^^^ @@ -177,7 +177,7 @@ | help: must be of the form: `#[rustc_confusables("name1", "name2", ...)]` error: `#[rustc_confusables]` attribute cannot be used on functions - --> $DIR/malformed-attrs.rs:36:1 + --> $DIR/malformed-attrs.rs:37:1 | LL | #[rustc_confusables] | ^^^^^^^^^^^^^^^^^^^^ @@ -185,7 +185,7 @@ = help: `#[rustc_confusables]` can only be applied to inherent methods error[E0539]: malformed `deprecated` attribute input - --> $DIR/malformed-attrs.rs:39:1 + --> $DIR/malformed-attrs.rs:40:1 | LL | #[deprecated = 5] | ^^^^^^^^^^^^^^^-^ @@ -349,7 +349,7 @@ | ^^^^^^^^^^^^^ help: must be of the form: `#[crate_name = "name"]` error[E0539]: malformed `target_feature` attribute input - --> $DIR/malformed-attrs.rs:80:1 + --> $DIR/malformed-attrs.rs:79:1 | LL | #[target_feature] | ^^^^^^^^^^^^^^^^^ @@ -358,7 +358,7 @@ | help: must be of the form: `#[target_feature(enable = "feat1, feat2")]` error[E0565]: malformed `export_stable` attribute input - --> $DIR/malformed-attrs.rs:82:1 + --> $DIR/malformed-attrs.rs:81:1 | LL | #[export_stable = 1] | ^^^^^^^^^^^^^^^^---^ @@ -367,7 +367,7 @@ | help: must be of the form: `#[export_stable]` error[E0539]: malformed `link` attribute input - --> $DIR/malformed-attrs.rs:84:1 + --> $DIR/malformed-attrs.rs:83:1 | LL | #[link] | ^^^^^^^ expected this to be a list @@ -375,7 +375,7 @@ = note: for more information, visit <https://doc.rust-lang.org/reference/items/external-blocks.html#the-link-attribute> error[E0539]: malformed `link_name` attribute input - --> $DIR/malformed-attrs.rs:88:1 + --> $DIR/malformed-attrs.rs:87:1 | LL | #[link_name] | ^^^^^^^^^^^^ help: must be of the form: `#[link_name = "name"]` @@ -383,7 +383,7 @@ = note: for more information, visit <https://doc.rust-lang.org/reference/items/external-blocks.html#the-link_name-attribute> error[E0539]: malformed `link_section` attribute input - --> $DIR/malformed-attrs.rs:92:1 + --> $DIR/malformed-attrs.rs:91:1 | LL | #[link_section] | ^^^^^^^^^^^^^^^ help: must be of the form: `#[link_section = "name"]` @@ -391,7 +391,7 @@ = note: for more information, visit <https://doc.rust-lang.org/reference/abi.html#the-link_section-attribute> error[E0539]: malformed `coverage` attribute input - --> $DIR/malformed-attrs.rs:94:1 + --> $DIR/malformed-attrs.rs:93:1 | LL | #[coverage] | ^^^^^^^^^^^ this attribute is only valid with either `on` or `off` as an argument @@ -404,13 +404,13 @@ | ++++ error[E0539]: malformed `sanitize` attribute input - --> $DIR/malformed-attrs.rs:96:1 + --> $DIR/malformed-attrs.rs:95:1 | LL | #[sanitize] | ^^^^^^^^^^^ expected this to be a list error[E0565]: malformed `no_implicit_prelude` attribute input - --> $DIR/malformed-attrs.rs:101:1 + --> $DIR/malformed-attrs.rs:100:1 | LL | #[no_implicit_prelude = 23] | ^^^^^^^^^^^^^^^^^^^^^^----^ @@ -419,7 +419,7 @@ | help: must be of the form: `#[no_implicit_prelude]` error[E0565]: malformed `proc_macro` attribute input - --> $DIR/malformed-attrs.rs:105:1 + --> $DIR/malformed-attrs.rs:104:1 | LL | #[proc_macro = 18] | ^^^^^^^^^^^^^----^ @@ -428,7 +428,7 @@ | help: must be of the form: `#[proc_macro]` error[E0539]: malformed `instruction_set` attribute input - --> $DIR/malformed-attrs.rs:112:1 + --> $DIR/malformed-attrs.rs:111:1 | LL | #[instruction_set] | ^^^^^^^^^^^^^^^^^^ @@ -439,7 +439,7 @@ = note: for more information, visit <https://doc.rust-lang.org/reference/attributes/codegen.html#the-instruction_set-attribute> error[E0539]: malformed `patchable_function_entry` attribute input - --> $DIR/malformed-attrs.rs:114:1 + --> $DIR/malformed-attrs.rs:113:1 | LL | #[patchable_function_entry] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -448,7 +448,7 @@ | help: must be of the form: `#[patchable_function_entry(prefix_nops = m, entry_nops = n)]` error[E0565]: malformed `coroutine` attribute input - --> $DIR/malformed-attrs.rs:117:5 + --> $DIR/malformed-attrs.rs:116:5 | LL | #[coroutine = 63] || {} | ^^^^^^^^^^^^----^ @@ -457,7 +457,7 @@ | help: must be of the form: `#[coroutine]` error[E0565]: malformed `proc_macro_attribute` attribute input - --> $DIR/malformed-attrs.rs:122:1 + --> $DIR/malformed-attrs.rs:121:1 | LL | #[proc_macro_attribute = 19] | ^^^^^^^^^^^^^^^^^^^^^^^----^ @@ -466,7 +466,7 @@ | help: must be of the form: `#[proc_macro_attribute]` error[E0539]: malformed `must_use` attribute input - --> $DIR/malformed-attrs.rs:125:1 + --> $DIR/malformed-attrs.rs:124:1 | LL | #[must_use = 1] | ^^^^^^^^^^^^^-^ @@ -484,7 +484,7 @@ | error[E0539]: malformed `proc_macro_derive` attribute input - --> $DIR/malformed-attrs.rs:129:1 + --> $DIR/malformed-attrs.rs:128:1 | LL | #[proc_macro_derive] | ^^^^^^^^^^^^^^^^^^^^ expected this to be a list @@ -498,7 +498,7 @@ | ++++++++++++++++++++++++++++++++++++++++++ error[E0539]: malformed `rustc_layout_scalar_valid_range_start` attribute input - --> $DIR/malformed-attrs.rs:134:1 + --> $DIR/malformed-attrs.rs:133:1 | LL | #[rustc_layout_scalar_valid_range_start] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -507,7 +507,7 @@ | help: must be of the form: `#[rustc_layout_scalar_valid_range_start(start)]` error[E0539]: malformed `rustc_layout_scalar_valid_range_end` attribute input - --> $DIR/malformed-attrs.rs:136:1 + --> $DIR/malformed-attrs.rs:135:1 | LL | #[rustc_layout_scalar_valid_range_end] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -516,7 +516,7 @@ | help: must be of the form: `#[rustc_layout_scalar_valid_range_end(end)]` error[E0539]: malformed `must_not_suspend` attribute input - --> $DIR/malformed-attrs.rs:138:1 + --> $DIR/malformed-attrs.rs:137:1 | LL | #[must_not_suspend()] | ^^^^^^^^^^^^^^^^^^--^ @@ -532,7 +532,7 @@ | error[E0539]: malformed `cfi_encoding` attribute input - --> $DIR/malformed-attrs.rs:140:1 + --> $DIR/malformed-attrs.rs:139:1 | LL | #[cfi_encoding = ""] | ^^^^^^^^^^^^^^^^^--^ @@ -541,7 +541,7 @@ | help: must be of the form: `#[cfi_encoding = "encoding"]` error[E0565]: malformed `marker` attribute input - --> $DIR/malformed-attrs.rs:161:1 + --> $DIR/malformed-attrs.rs:160:1 | LL | #[marker = 3] | ^^^^^^^^^---^ @@ -550,7 +550,7 @@ | help: must be of the form: `#[marker]` error[E0565]: malformed `fundamental` attribute input - --> $DIR/malformed-attrs.rs:163:1 + --> $DIR/malformed-attrs.rs:162:1 | LL | #[fundamental()] | ^^^^^^^^^^^^^--^ @@ -559,7 +559,7 @@ | help: must be of the form: `#[fundamental]` error[E0565]: malformed `ffi_pure` attribute input - --> $DIR/malformed-attrs.rs:171:5 + --> $DIR/malformed-attrs.rs:170:5 | LL | #[unsafe(ffi_pure = 1)] | ^^^^^^^^^^^^^^^^^^---^^ @@ -568,7 +568,7 @@ | help: must be of the form: `#[ffi_pure]` error[E0539]: malformed `link_ordinal` attribute input - --> $DIR/malformed-attrs.rs:173:5 + --> $DIR/malformed-attrs.rs:172:5 | LL | #[link_ordinal] | ^^^^^^^^^^^^^^^ @@ -579,7 +579,7 @@ = note: for more information, visit <https://doc.rust-lang.org/reference/items/external-blocks.html#the-link_ordinal-attribute> error[E0565]: malformed `ffi_const` attribute input - --> $DIR/malformed-attrs.rs:177:5 + --> $DIR/malformed-attrs.rs:176:5 | LL | #[unsafe(ffi_const = 1)] | ^^^^^^^^^^^^^^^^^^^---^^ @@ -588,13 +588,13 @@ | help: must be of the form: `#[ffi_const]` error[E0539]: malformed `linkage` attribute input - --> $DIR/malformed-attrs.rs:179:5 + --> $DIR/malformed-attrs.rs:178:5 | LL | #[linkage] | ^^^^^^^^^^ expected this to be of the form `linkage = "..."` error[E0539]: malformed `debugger_visualizer` attribute input - --> $DIR/malformed-attrs.rs:194:1 + --> $DIR/malformed-attrs.rs:193:1 | LL | #[debugger_visualizer] | ^^^^^^^^^^^^^^^^^^^^^^ @@ -605,7 +605,7 @@ = note: for more information, visit <https://doc.rust-lang.org/reference/attributes/debugger.html#the-debugger_visualizer-attribute> error[E0565]: malformed `automatically_derived` attribute input - --> $DIR/malformed-attrs.rs:196:1 + --> $DIR/malformed-attrs.rs:195:1 | LL | #[automatically_derived = 18] | ^^^^^^^^^^^^^^^^^^^^^^^^----^ @@ -614,7 +614,7 @@ | help: must be of the form: `#[automatically_derived]` error[E0565]: malformed `non_exhaustive` attribute input - --> $DIR/malformed-attrs.rs:204:1 + --> $DIR/malformed-attrs.rs:203:1 | LL | #[non_exhaustive = 1] | ^^^^^^^^^^^^^^^^^---^ @@ -623,7 +623,7 @@ | help: must be of the form: `#[non_exhaustive]` error[E0565]: malformed `thread_local` attribute input - --> $DIR/malformed-attrs.rs:210:1 + --> $DIR/malformed-attrs.rs:209:1 | LL | #[thread_local()] | ^^^^^^^^^^^^^^--^ @@ -632,7 +632,7 @@ | help: must be of the form: `#[thread_local]` error[E0565]: malformed `no_link` attribute input - --> $DIR/malformed-attrs.rs:214:1 + --> $DIR/malformed-attrs.rs:213:1 | LL | #[no_link()] | ^^^^^^^^^--^ @@ -641,7 +641,7 @@ | help: must be of the form: `#[no_link]` error[E0539]: malformed `macro_use` attribute input - --> $DIR/malformed-attrs.rs:216:1 + --> $DIR/malformed-attrs.rs:215:1 | LL | #[macro_use = 1] | ^^^^^^^^^^^^---^ @@ -659,7 +659,7 @@ | error[E0539]: malformed `macro_export` attribute input - --> $DIR/malformed-attrs.rs:221:1 + --> $DIR/malformed-attrs.rs:220:1 | LL | #[macro_export = 18] | ^^^^^^^^^^^^^^^----^ @@ -676,7 +676,7 @@ | error[E0565]: malformed `allow_internal_unsafe` attribute input - --> $DIR/malformed-attrs.rs:223:1 + --> $DIR/malformed-attrs.rs:222:1 | LL | #[allow_internal_unsafe = 1] | ^^^^^^^^^^^^^^^^^^^^^^^^---^ @@ -685,7 +685,7 @@ | help: must be of the form: `#[allow_internal_unsafe]` error[E0565]: malformed `type_const` attribute input - --> $DIR/malformed-attrs.rs:149:5 + --> $DIR/malformed-attrs.rs:148:5 | LL | #[type_const = 1] | ^^^^^^^^^^^^^---^ @@ -694,7 +694,7 @@ | help: must be of the form: `#[type_const]` error: attribute should be applied to `const fn` - --> $DIR/malformed-attrs.rs:31:1 + --> $DIR/malformed-attrs.rs:32:1 | LL | #[rustc_allow_const_fn_unstable] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -706,7 +706,7 @@ | |_- not a `const fn` warning: attribute should be applied to an `extern` block with non-Rust ABI - --> $DIR/malformed-attrs.rs:84:1 + --> $DIR/malformed-attrs.rs:83:1 | LL | #[link] | ^^^^^^^ @@ -733,7 +733,7 @@ | ^^^^^^^ warning: missing options for `on_unimplemented` attribute - --> $DIR/malformed-attrs.rs:144:1 + --> $DIR/malformed-attrs.rs:143:1 | LL | #[diagnostic::on_unimplemented] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -742,7 +742,7 @@ = note: `#[warn(malformed_diagnostic_attributes)]` (part of `#[warn(unknown_or_malformed_diagnostic_attributes)]`) on by default warning: malformed `on_unimplemented` attribute - --> $DIR/malformed-attrs.rs:146:1 + --> $DIR/malformed-attrs.rs:145:1 | LL | #[diagnostic::on_unimplemented = 1] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid option found here @@ -750,14 +750,16 @@ = help: only `message`, `note` and `label` are allowed as options error: valid forms for the attribute are `#[doc = "string"]`, `#[doc(alias)]`, `#[doc(attribute)]`, `#[doc(auto_cfg)]`, `#[doc(cfg)]`, `#[doc(fake_variadic)]`, `#[doc(hidden)]`, `#[doc(html_favicon_url)]`, `#[doc(html_logo_url)]`, `#[doc(html_no_source)]`, `#[doc(html_playground_url)]`, `#[doc(html_root_url)]`, `#[doc(include)]`, `#[doc(inline)]`, `#[doc(issue_tracker_base_url)]`, `#[doc(keyword)]`, `#[doc(masked)]`, `#[doc(no_default_passes)]`, `#[doc(no_inline)]`, `#[doc(notable_trait)]`, `#[doc(passes)]`, `#[doc(plugins)]`, `#[doc(rust_logo)]`, `#[doc(search_unbox)]`, `#[doc(spotlight)]`, and `#[doc(test)]` - --> $DIR/malformed-attrs.rs:41:1 + --> $DIR/malformed-attrs.rs:42:1 | LL | #[doc] | ^^^^^^ | - = 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 #57571 <https://github.com/rust-lang/rust/issues/57571> - = note: `#[deny(ill_formed_attribute_input)]` (part of `#[deny(future_incompatible)]`) on by default +note: the lint level is defined here + --> $DIR/malformed-attrs.rs:3:9 + | +LL | #![deny(invalid_doc_attributes)] + | ^^^^^^^^^^^^^^^^^^^^^^ error: valid forms for the attribute are `#[inline(always)]`, `#[inline(never)]`, and `#[inline]` --> $DIR/malformed-attrs.rs:52:1 @@ -767,6 +769,7 @@ | = 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 #57571 <https://github.com/rust-lang/rust/issues/57571> + = note: `#[deny(ill_formed_attribute_input)]` (part of `#[deny(future_incompatible)]`) on by default warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![crate_name]` --> $DIR/malformed-attrs.rs:74:1 @@ -775,7 +778,7 @@ | ^^^^^^^^^^^^^ | note: this attribute does not have an `!`, which means it is applied to this function - --> $DIR/malformed-attrs.rs:116:1 + --> $DIR/malformed-attrs.rs:115:1 | LL | / fn test() { LL | | #[coroutine = 63] || {} @@ -788,12 +791,9 @@ | LL | #[doc] | ^^^^^^ - | - = 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 #57571 <https://github.com/rust-lang/rust/issues/57571> warning: `#[link_name]` attribute cannot be used on functions - --> $DIR/malformed-attrs.rs:88:1 + --> $DIR/malformed-attrs.rs:87:1 | LL | #[link_name] | ^^^^^^^^^^^^ @@ -802,7 +802,7 @@ = help: `#[link_name]` can be applied to foreign functions and foreign statics error: valid forms for the attribute are `#[ignore = "reason"]` and `#[ignore]` - --> $DIR/malformed-attrs.rs:98:1 + --> $DIR/malformed-attrs.rs:97:1 | LL | #[ignore()] | ^^^^^^^^^^^ @@ -811,7 +811,7 @@ = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571> warning: `#[no_implicit_prelude]` attribute cannot be used on functions - --> $DIR/malformed-attrs.rs:101:1 + --> $DIR/malformed-attrs.rs:100:1 | LL | #[no_implicit_prelude = 23] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -820,13 +820,13 @@ = help: `#[no_implicit_prelude]` can be applied to crates and modules warning: `#[diagnostic::do_not_recommend]` does not expect any arguments - --> $DIR/malformed-attrs.rs:155:1 + --> $DIR/malformed-attrs.rs:154:1 | LL | #[diagnostic::do_not_recommend()] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: `#[automatically_derived]` attribute cannot be used on modules - --> $DIR/malformed-attrs.rs:196:1 + --> $DIR/malformed-attrs.rs:195:1 | LL | #[automatically_derived = 18] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -835,7 +835,7 @@ = help: `#[automatically_derived]` can only be applied to trait impl blocks error: valid forms for the attribute are `#[ignore = "reason"]` and `#[ignore]` - --> $DIR/malformed-attrs.rs:230:1 + --> $DIR/malformed-attrs.rs:229:1 | LL | #[ignore = 1] | ^^^^^^^^^^^^^ @@ -844,7 +844,7 @@ = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571> error[E0308]: mismatched types - --> $DIR/malformed-attrs.rs:117:23 + --> $DIR/malformed-attrs.rs:116:23 | LL | fn test() { | - help: a return type might be missing here: `-> _` @@ -852,24 +852,13 @@ | ^^^^^ expected `()`, found coroutine | = note: expected unit type `()` - found coroutine `{coroutine@$DIR/malformed-attrs.rs:117:23: 117:25}` + found coroutine `{coroutine@$DIR/malformed-attrs.rs:116:23: 116:25}` error: aborting due to 76 previous errors; 8 warnings emitted Some errors have detailed explanations: E0308, E0463, E0539, E0565, E0658, E0805. For more information about an error, try `rustc --explain E0308`. Future incompatibility report: Future breakage diagnostic: -error: valid forms for the attribute are `#[doc = "string"]`, `#[doc(alias)]`, `#[doc(attribute)]`, `#[doc(auto_cfg)]`, `#[doc(cfg)]`, `#[doc(fake_variadic)]`, `#[doc(hidden)]`, `#[doc(html_favicon_url)]`, `#[doc(html_logo_url)]`, `#[doc(html_no_source)]`, `#[doc(html_playground_url)]`, `#[doc(html_root_url)]`, `#[doc(include)]`, `#[doc(inline)]`, `#[doc(issue_tracker_base_url)]`, `#[doc(keyword)]`, `#[doc(masked)]`, `#[doc(no_default_passes)]`, `#[doc(no_inline)]`, `#[doc(notable_trait)]`, `#[doc(passes)]`, `#[doc(plugins)]`, `#[doc(rust_logo)]`, `#[doc(search_unbox)]`, `#[doc(spotlight)]`, and `#[doc(test)]` - --> $DIR/malformed-attrs.rs:41:1 - | -LL | #[doc] - | ^^^^^^ - | - = 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 #57571 <https://github.com/rust-lang/rust/issues/57571> - = note: `#[deny(ill_formed_attribute_input)]` (part of `#[deny(future_incompatible)]`) on by default - -Future breakage diagnostic: error: valid forms for the attribute are `#[inline(always)]`, `#[inline(never)]`, and `#[inline]` --> $DIR/malformed-attrs.rs:52:1 | @@ -881,19 +870,8 @@ = note: `#[deny(ill_formed_attribute_input)]` (part of `#[deny(future_incompatible)]`) on by default Future breakage diagnostic: -error: valid forms for the attribute are `#[doc = "string"]`, `#[doc(alias)]`, `#[doc(attribute)]`, `#[doc(auto_cfg)]`, `#[doc(cfg)]`, `#[doc(fake_variadic)]`, `#[doc(hidden)]`, `#[doc(html_favicon_url)]`, `#[doc(html_logo_url)]`, `#[doc(html_no_source)]`, `#[doc(html_playground_url)]`, `#[doc(html_root_url)]`, `#[doc(include)]`, `#[doc(inline)]`, `#[doc(issue_tracker_base_url)]`, `#[doc(keyword)]`, `#[doc(masked)]`, `#[doc(no_default_passes)]`, `#[doc(no_inline)]`, `#[doc(notable_trait)]`, `#[doc(passes)]`, `#[doc(plugins)]`, `#[doc(rust_logo)]`, `#[doc(search_unbox)]`, `#[doc(spotlight)]`, and `#[doc(test)]` - --> $DIR/malformed-attrs.rs:77:1 - | -LL | #[doc] - | ^^^^^^ - | - = 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 #57571 <https://github.com/rust-lang/rust/issues/57571> - = note: `#[deny(ill_formed_attribute_input)]` (part of `#[deny(future_incompatible)]`) on by default - -Future breakage diagnostic: error: valid forms for the attribute are `#[ignore = "reason"]` and `#[ignore]` - --> $DIR/malformed-attrs.rs:98:1 + --> $DIR/malformed-attrs.rs:97:1 | LL | #[ignore()] | ^^^^^^^^^^^ @@ -904,7 +882,7 @@ Future breakage diagnostic: error: valid forms for the attribute are `#[ignore = "reason"]` and `#[ignore]` - --> $DIR/malformed-attrs.rs:230:1 + --> $DIR/malformed-attrs.rs:229:1 | LL | #[ignore = 1] | ^^^^^^^^^^^^^
diff --git a/tests/ui/check-cfg/values-target-json.rs b/tests/ui/check-cfg/values-target-json.rs index defb286..21b6af9b 100644 --- a/tests/ui/check-cfg/values-target-json.rs +++ b/tests/ui/check-cfg/values-target-json.rs
@@ -4,7 +4,8 @@ //@ check-pass //@ no-auto-check-cfg //@ needs-llvm-components: x86 -//@ compile-flags: --crate-type=lib --check-cfg=cfg() --target={{src-base}}/check-cfg/my-awesome-platform.json +//@ compile-flags: --crate-type=lib --check-cfg=cfg() +//@ compile-flags: -Zunstable-options --target={{src-base}}/check-cfg/my-awesome-platform.json //@ ignore-backends: gcc #![feature(lang_items, no_core, auto_traits, rustc_attrs)]
diff --git a/tests/ui/const-generics/adt_const_params/unsized-anon-const-err-1.rs b/tests/ui/const-generics/adt_const_params/unsized-anon-const-err-1.rs new file mode 100644 index 0000000..17910d5 --- /dev/null +++ b/tests/ui/const-generics/adt_const_params/unsized-anon-const-err-1.rs
@@ -0,0 +1,22 @@ +// regression test for issue #137582, where constant evaluating an unsized AnonConst would ICE + +#![feature(adt_const_params)] + +mod lib { + pub type Matrix = [&'static u32]; + + const EMPTY_MATRIX: Matrix = [[0; 4]; 4]; + //~^ ERROR the size for values of type `[&'static u32]` cannot be known at compilation time + //~| ERROR mismatched types + //~| ERROR mismatched types + + pub struct Walk<const CURRENT: usize, const REMAINING: Matrix> { + //~^ ERROR use of unstable library feature `unsized_const_params` + _p: (), + } + + impl<const CURRENT: usize> Walk<CURRENT, EMPTY_MATRIX> {} + //~^ ERROR the size for values of type `[&'static u32]` cannot be known at compilation time +} + +fn main() {}
diff --git a/tests/ui/const-generics/adt_const_params/unsized-anon-const-err-1.stderr b/tests/ui/const-generics/adt_const_params/unsized-anon-const-err-1.stderr new file mode 100644 index 0000000..daea55e --- /dev/null +++ b/tests/ui/const-generics/adt_const_params/unsized-anon-const-err-1.stderr
@@ -0,0 +1,44 @@ +error[E0277]: the size for values of type `[&'static u32]` cannot be known at compilation time + --> $DIR/unsized-anon-const-err-1.rs:8:25 + | +LL | const EMPTY_MATRIX: Matrix = [[0; 4]; 4]; + | ^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[&'static u32]` + = note: statics and constants must have a statically known size + +error[E0658]: use of unstable library feature `unsized_const_params` + --> $DIR/unsized-anon-const-err-1.rs:13:43 + | +LL | pub struct Walk<const CURRENT: usize, const REMAINING: Matrix> { + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add `#![feature(unsized_const_params)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = note: required for `[&'static u32]` to implement `ConstParamTy_` + +error[E0277]: the size for values of type `[&'static u32]` cannot be known at compilation time + --> $DIR/unsized-anon-const-err-1.rs:18:46 + | +LL | impl<const CURRENT: usize> Walk<CURRENT, EMPTY_MATRIX> {} + | ^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[&'static u32]` + = note: statics and constants must have a statically known size + +error[E0308]: mismatched types + --> $DIR/unsized-anon-const-err-1.rs:8:35 + | +LL | const EMPTY_MATRIX: Matrix = [[0; 4]; 4]; + | ^^^^^^ expected `&u32`, found `[{integer}; 4]` + +error[E0308]: mismatched types + --> $DIR/unsized-anon-const-err-1.rs:8:34 + | +LL | const EMPTY_MATRIX: Matrix = [[0; 4]; 4]; + | ^^^^^^^^^^^ expected `[&u32]`, found `[&u32; 4]` + +error: aborting due to 5 previous errors + +Some errors have detailed explanations: E0277, E0308, E0658. +For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/const-generics/adt_const_params/unsized-anon-const-err-2.rs b/tests/ui/const-generics/adt_const_params/unsized-anon-const-err-2.rs new file mode 100644 index 0000000..81b1ec6 --- /dev/null +++ b/tests/ui/const-generics/adt_const_params/unsized-anon-const-err-2.rs
@@ -0,0 +1,21 @@ +// regression test for issue #151591, where constant evaluating an unsized AnonConst would ICE + +#![feature(adt_const_params)] +#![feature(unsized_const_params)] +//~^ WARN the feature `unsized_const_params` is incomplete and may not be safe to use and/or cause compiler crashes + +#[derive(Clone)] +struct S<const L: [u8]>; + +const A: [u8]; +//~^ ERROR free constant item without body +//~| ERROR the size for values of type `[u8]` cannot be known at compilation time + +impl<const N: i32> Copy for S<A> {} +//~^ ERROR the size for values of type `[u8]` cannot be known at compilation time +//~| ERROR the const parameter `N` is not constrained by the impl trait, self type, or predicates +impl<const M: usize> Copy for S<A> {} +//~^ ERROR the size for values of type `[u8]` cannot be known at compilation time +//~| ERROR the const parameter `M` is not constrained by the impl trait, self type, or predicates + +fn main() {}
diff --git a/tests/ui/const-generics/adt_const_params/unsized-anon-const-err-2.stderr b/tests/ui/const-generics/adt_const_params/unsized-anon-const-err-2.stderr new file mode 100644 index 0000000..d538bb0 --- /dev/null +++ b/tests/ui/const-generics/adt_const_params/unsized-anon-const-err-2.stderr
@@ -0,0 +1,66 @@ +error: free constant item without body + --> $DIR/unsized-anon-const-err-2.rs:10:1 + | +LL | const A: [u8]; + | ^^^^^^^^^^^^^- + | | + | help: provide a definition for the constant: `= <expr>;` + +warning: the feature `unsized_const_params` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/unsized-anon-const-err-2.rs:4:12 + | +LL | #![feature(unsized_const_params)] + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #95174 <https://github.com/rust-lang/rust/issues/95174> for more information + = note: `#[warn(incomplete_features)]` on by default + +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/unsized-anon-const-err-2.rs:10:10 + | +LL | const A: [u8]; + | ^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` + = note: statics and constants must have a statically known size + +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/unsized-anon-const-err-2.rs:14:31 + | +LL | impl<const N: i32> Copy for S<A> {} + | ^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` + = note: statics and constants must have a statically known size + +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/unsized-anon-const-err-2.rs:17:33 + | +LL | impl<const M: usize> Copy for S<A> {} + | ^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` + = note: statics and constants must have a statically known size + +error[E0207]: the const parameter `N` is not constrained by the impl trait, self type, or predicates + --> $DIR/unsized-anon-const-err-2.rs:14:6 + | +LL | impl<const N: i32> Copy for S<A> {} + | ^^^^^^^^^^^^ unconstrained const parameter + | + = note: expressions using a const parameter must map each value to a distinct output value + = note: proving the result of expressions other than the parameter are unique is not supported + +error[E0207]: the const parameter `M` is not constrained by the impl trait, self type, or predicates + --> $DIR/unsized-anon-const-err-2.rs:17:6 + | +LL | impl<const M: usize> Copy for S<A> {} + | ^^^^^^^^^^^^^^ unconstrained const parameter + | + = note: expressions using a const parameter must map each value to a distinct output value + = note: proving the result of expressions other than the parameter are unique is not supported + +error: aborting due to 6 previous errors; 1 warning emitted + +Some errors have detailed explanations: E0207, E0277. +For more information about an error, try `rustc --explain E0207`.
diff --git a/tests/ui/const-generics/adt_const_params/unsized-anon-const-func-err.rs b/tests/ui/const-generics/adt_const_params/unsized-anon-const-func-err.rs new file mode 100644 index 0000000..a299cc2 --- /dev/null +++ b/tests/ui/const-generics/adt_const_params/unsized-anon-const-func-err.rs
@@ -0,0 +1,16 @@ +// manually reduced reproduction of issue #137582, where constant evaluating an unsized AnonConst +// would ICE + +#![feature(adt_const_params)] + +fn func<const V: [u32]>() {} +//~^ ERROR use of unstable library feature `unsized_const_params` + +const VALUE: [u32] = [0; 4]; +//~^ ERROR mismatched types +//~| ERROR the size for values of type `[u32]` cannot be known at compilation time + +fn main() { + func::<VALUE>(); + //~^ ERROR the size for values of type `[u32]` cannot be known at compilation time +}
diff --git a/tests/ui/const-generics/adt_const_params/unsized-anon-const-func-err.stderr b/tests/ui/const-generics/adt_const_params/unsized-anon-const-func-err.stderr new file mode 100644 index 0000000..14a41e8 --- /dev/null +++ b/tests/ui/const-generics/adt_const_params/unsized-anon-const-func-err.stderr
@@ -0,0 +1,38 @@ +error[E0658]: use of unstable library feature `unsized_const_params` + --> $DIR/unsized-anon-const-func-err.rs:6:9 + | +LL | fn func<const V: [u32]>() {} + | ^^^^^^^^^^^^^^ + | + = help: add `#![feature(unsized_const_params)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = note: required for `[u32]` to implement `ConstParamTy_` + +error[E0277]: the size for values of type `[u32]` cannot be known at compilation time + --> $DIR/unsized-anon-const-func-err.rs:9:14 + | +LL | const VALUE: [u32] = [0; 4]; + | ^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u32]` + = note: statics and constants must have a statically known size + +error[E0308]: mismatched types + --> $DIR/unsized-anon-const-func-err.rs:9:22 + | +LL | const VALUE: [u32] = [0; 4]; + | ^^^^^^ expected `[u32]`, found `[u32; 4]` + +error[E0277]: the size for values of type `[u32]` cannot be known at compilation time + --> $DIR/unsized-anon-const-func-err.rs:14:12 + | +LL | func::<VALUE>(); + | ^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u32]` + = note: statics and constants must have a statically known size + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0277, E0308, E0658. +For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/const-generics/adt_const_params/unsized-anon-const-struct-err.rs b/tests/ui/const-generics/adt_const_params/unsized-anon-const-struct-err.rs new file mode 100644 index 0000000..35407d0 --- /dev/null +++ b/tests/ui/const-generics/adt_const_params/unsized-anon-const-struct-err.rs
@@ -0,0 +1,16 @@ +// manually reduced reproduction of issue #137582, where constant evaluating an unsized AnonConst +// would ICE + +#![feature(adt_const_params)] + +const VALUE: [u32] = [0; 4]; +//~^ ERROR the size for values of type `[u32]` cannot be known at compilation time +//~| ERROR mismatched types + +struct SomeStruct<const V: [u32]> {} +//~^ ERROR use of unstable library feature `unsized_const_params` + +impl SomeStruct<VALUE> {} +//~^ ERROR the size for values of type `[u32]` cannot be known at compilation time + +fn main() {}
diff --git a/tests/ui/const-generics/adt_const_params/unsized-anon-const-struct-err.stderr b/tests/ui/const-generics/adt_const_params/unsized-anon-const-struct-err.stderr new file mode 100644 index 0000000..d9a1397 --- /dev/null +++ b/tests/ui/const-generics/adt_const_params/unsized-anon-const-struct-err.stderr
@@ -0,0 +1,38 @@ +error[E0277]: the size for values of type `[u32]` cannot be known at compilation time + --> $DIR/unsized-anon-const-struct-err.rs:6:14 + | +LL | const VALUE: [u32] = [0; 4]; + | ^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u32]` + = note: statics and constants must have a statically known size + +error[E0658]: use of unstable library feature `unsized_const_params` + --> $DIR/unsized-anon-const-struct-err.rs:10:19 + | +LL | struct SomeStruct<const V: [u32]> {} + | ^^^^^^^^^^^^^^ + | + = help: add `#![feature(unsized_const_params)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = note: required for `[u32]` to implement `ConstParamTy_` + +error[E0277]: the size for values of type `[u32]` cannot be known at compilation time + --> $DIR/unsized-anon-const-struct-err.rs:13:17 + | +LL | impl SomeStruct<VALUE> {} + | ^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u32]` + = note: statics and constants must have a statically known size + +error[E0308]: mismatched types + --> $DIR/unsized-anon-const-struct-err.rs:6:22 + | +LL | const VALUE: [u32] = [0; 4]; + | ^^^^^^ expected `[u32]`, found `[u32; 4]` + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0277, E0308, E0658. +For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/const-generics/mgca/type-const-used-in-trait.rs b/tests/ui/const-generics/mgca/type-const-used-in-trait.rs new file mode 100644 index 0000000..c98c147 --- /dev/null +++ b/tests/ui/const-generics/mgca/type-const-used-in-trait.rs
@@ -0,0 +1,13 @@ +//@ check-pass + +#![feature(min_generic_const_args)] +#![expect(incomplete_features)] + +#[type_const] +const N: usize = 2; + +trait CollectArray<A> { + fn inner_array(&mut self) -> [A; N]; +} + +fn main() {}
diff --git a/tests/ui/consts/const-eval/ptr_fragments.rs b/tests/ui/consts/const-eval/ptr_fragments.rs index d278040..f4d9212 100644 --- a/tests/ui/consts/const-eval/ptr_fragments.rs +++ b/tests/ui/consts/const-eval/ptr_fragments.rs
@@ -70,6 +70,7 @@ struct Thing { #[allow(dead_code)] #[cfg(not(target_arch = "s390x"))] // u128 is less aligned on s390x, removing the padding fn fragment_in_dst_padding_gets_overwritten() { + // We can't use `repr(align)` here as that would make this not a `ScalarPair` any more. #[repr(C)] struct Pair { x: u128,
diff --git a/tests/ui/consts/const-eval/ptr_fragments_in_final.rs b/tests/ui/consts/const-eval/ptr_fragments_in_final.rs index 4037a2d..76f292c 100644 --- a/tests/ui/consts/const-eval/ptr_fragments_in_final.rs +++ b/tests/ui/consts/const-eval/ptr_fragments_in_final.rs
@@ -37,4 +37,40 @@ } }; +/// This has pointer bytes in the padding of the memory that the final value is read from. +/// To ensure consistent behavior, we want to *always* copy that padding, even if the value +/// could be represented as a more efficient ScalarPair. Hence this must fail to compile. +fn fragment_in_padding() -> impl Copy { + // We can't use `repr(align)` here as that would make this not a `ScalarPair` any more. + #[repr(C)] + #[derive(Clone, Copy)] + struct Thing { + x: u128, + y: usize, + // at least one pointer worth of padding + } + // Ensure there is indeed padding. + const _: () = assert!(mem::size_of::<Thing>() > 16 + mem::size_of::<usize>()); + + #[derive(Clone, Copy)] + union PreservePad { + thing: Thing, + bytes: [u8; mem::size_of::<Thing>()], + } + + const A: Thing = unsafe { //~ERROR: partial pointer in final value + let mut buffer = [PreservePad { bytes: [0u8; mem::size_of::<Thing>()] }; 2]; + // The offset half a pointer from the end, so that copying a `Thing` copies exactly + // half the pointer. + let offset = mem::size_of::<Thing>() - mem::size_of::<usize>()/2; + // Ensure this is inside the padding. + assert!(offset >= std::mem::offset_of!(Thing, y) + mem::size_of::<usize>()); + + (&raw mut buffer).cast::<&i32>().byte_add(offset).write_unaligned(&1); + buffer[0].thing + }; + + A +} + fn main() {}
diff --git a/tests/ui/consts/const-eval/ptr_fragments_in_final.stderr b/tests/ui/consts/const-eval/ptr_fragments_in_final.stderr index 41a8224..de0cd4d 100644 --- a/tests/ui/consts/const-eval/ptr_fragments_in_final.stderr +++ b/tests/ui/consts/const-eval/ptr_fragments_in_final.stderr
@@ -14,5 +14,13 @@ | = note: while pointers can be broken apart into individual bytes during const-evaluation, only complete pointers (with all their bytes in the right order) are supported in the final value -error: aborting due to 2 previous errors +error: encountered partial pointer in final value of constant + --> $DIR/ptr_fragments_in_final.rs:61:5 + | +LL | const A: Thing = unsafe { + | ^^^^^^^^^^^^^^ + | + = note: while pointers can be broken apart into individual bytes during const-evaluation, only complete pointers (with all their bytes in the right order) are supported in the final value + +error: aborting due to 3 previous errors
diff --git a/tests/ui/diagnostic_namespace/on_const/misplaced_attr.rs b/tests/ui/diagnostic_namespace/on_const/misplaced_attr.rs index c0af549..f7babae 100644 --- a/tests/ui/diagnostic_namespace/on_const/misplaced_attr.rs +++ b/tests/ui/diagnostic_namespace/on_const/misplaced_attr.rs
@@ -6,7 +6,7 @@ pub struct Foo; #[diagnostic::on_const(message = "tadaa", note = "boing")] -//~^ ERROR: `#[diagnostic::on_const]` can only be applied to trait impls +//~^ ERROR: `#[diagnostic::on_const]` can only be applied to non-const trait impls impl const PartialEq for Foo { fn eq(&self, _other: &Foo) -> bool { true
diff --git a/tests/ui/diagnostic_namespace/on_const/misplaced_attr.stderr b/tests/ui/diagnostic_namespace/on_const/misplaced_attr.stderr index baa0b11..f92ea50 100644 --- a/tests/ui/diagnostic_namespace/on_const/misplaced_attr.stderr +++ b/tests/ui/diagnostic_namespace/on_const/misplaced_attr.stderr
@@ -13,14 +13,14 @@ LL | #![deny(misplaced_diagnostic_attributes)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: `#[diagnostic::on_const]` can only be applied to trait impls +error: `#[diagnostic::on_const]` can only be applied to non-const trait impls --> $DIR/misplaced_attr.rs:8:1 | LL | #[diagnostic::on_const(message = "tadaa", note = "boing")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ LL | LL | impl const PartialEq for Foo { - | ---------------------------- not a trait impl + | ---------------------------- this is a const trait impl error: `#[diagnostic::on_const]` can only be applied to trait impls --> $DIR/misplaced_attr.rs:16:1
diff --git a/tests/ui/feature-gates/feature-gate-link-arg-attribute.in_flag.stderr b/tests/ui/feature-gates/feature-gate-link-arg-attribute.in_flag.stderr index 4d65db3..218a476 100644 --- a/tests/ui/feature-gates/feature-gate-link-arg-attribute.in_flag.stderr +++ b/tests/ui/feature-gates/feature-gate-link-arg-attribute.in_flag.stderr
@@ -1,2 +1,2 @@ -error: unknown linking modifier `link-arg`, expected one of: bundle, verbatim, whole-archive, as-needed +error: unknown linking modifier `link-arg`, expected one of: bundle, verbatim, whole-archive, as-needed, export-symbols
diff --git a/tests/ui/feature-gates/removed-features-note-version-and-pr-issue-141619.rs b/tests/ui/feature-gates/removed-features-note-version-and-pr-issue-141619.rs index d8c5f48..a7dde7c 100644 --- a/tests/ui/feature-gates/removed-features-note-version-and-pr-issue-141619.rs +++ b/tests/ui/feature-gates/removed-features-note-version-and-pr-issue-141619.rs
@@ -1,3 +1,4 @@ +#![deny(invalid_doc_attributes)] #![feature(external_doc)] //~ ERROR feature has been removed #![doc(include("README.md"))] //~ ERROR unknown `doc` attribute `include`
diff --git a/tests/ui/feature-gates/removed-features-note-version-and-pr-issue-141619.stderr b/tests/ui/feature-gates/removed-features-note-version-and-pr-issue-141619.stderr index d955656..a009898 100644 --- a/tests/ui/feature-gates/removed-features-note-version-and-pr-issue-141619.stderr +++ b/tests/ui/feature-gates/removed-features-note-version-and-pr-issue-141619.stderr
@@ -1,5 +1,5 @@ error[E0557]: feature has been removed - --> $DIR/removed-features-note-version-and-pr-issue-141619.rs:1:12 + --> $DIR/removed-features-note-version-and-pr-issue-141619.rs:2:12 | LL | #![feature(external_doc)] | ^^^^^^^^^^^^ feature has been removed @@ -8,12 +8,16 @@ = note: use #[doc = include_str!("filename")] instead, which handles macro invocations error: unknown `doc` attribute `include` - --> $DIR/removed-features-note-version-and-pr-issue-141619.rs:2:8 + --> $DIR/removed-features-note-version-and-pr-issue-141619.rs:3:8 | LL | #![doc(include("README.md"))] | ^^^^^^^ | - = note: `#[deny(invalid_doc_attributes)]` on by default +note: the lint level is defined here + --> $DIR/removed-features-note-version-and-pr-issue-141619.rs:1:9 + | +LL | #![deny(invalid_doc_attributes)] + | ^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors
diff --git a/tests/ui/link-native-libs/link-arg-error2.rs b/tests/ui/link-native-libs/link-arg-error2.rs new file mode 100644 index 0000000..a51dec0 --- /dev/null +++ b/tests/ui/link-native-libs/link-arg-error2.rs
@@ -0,0 +1,5 @@ +//@ compile-flags: -l link-arg:+export-symbols=arg -Z unstable-options + +fn main() {} + +//~? ERROR linking modifier `export-symbols` is only compatible with `static` linking kind
diff --git a/tests/ui/link-native-libs/link-arg-error2.stderr b/tests/ui/link-native-libs/link-arg-error2.stderr new file mode 100644 index 0000000..61bcf7d --- /dev/null +++ b/tests/ui/link-native-libs/link-arg-error2.stderr
@@ -0,0 +1,2 @@ +error: linking modifier `export-symbols` is only compatible with `static` linking kind +
diff --git a/tests/ui/link-native-libs/link-arg-from-rs2.rs b/tests/ui/link-native-libs/link-arg-from-rs2.rs new file mode 100644 index 0000000..3074fec --- /dev/null +++ b/tests/ui/link-native-libs/link-arg-from-rs2.rs
@@ -0,0 +1,7 @@ +#![feature(link_arg_attribute)] + +#[link(kind = "link-arg", name = "arg", modifiers = "+export-symbols")] +//~^ ERROR linking modifier `export-symbols` is only compatible with `static` linking kind +extern "C" {} + +pub fn main() {}
diff --git a/tests/ui/link-native-libs/link-arg-from-rs2.stderr b/tests/ui/link-native-libs/link-arg-from-rs2.stderr new file mode 100644 index 0000000..af3b252 --- /dev/null +++ b/tests/ui/link-native-libs/link-arg-from-rs2.stderr
@@ -0,0 +1,8 @@ +error: linking modifier `export-symbols` is only compatible with `static` linking kind + --> $DIR/link-arg-from-rs2.rs:3:53 + | +LL | #[link(kind = "link-arg", name = "arg", modifiers = "+export-symbols")] + | ^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error +
diff --git a/tests/ui/link-native-libs/link-attr-validation-late.stderr b/tests/ui/link-native-libs/link-attr-validation-late.stderr index b09431f..4a4a193 100644 --- a/tests/ui/link-native-libs/link-attr-validation-late.stderr +++ b/tests/ui/link-native-libs/link-attr-validation-late.stderr
@@ -178,13 +178,13 @@ | = note: for more information, visit <https://doc.rust-lang.org/reference/items/external-blocks.html#the-link-attribute> -error: invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed +error: invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed, export-symbols --> $DIR/link-attr-validation-late.rs:31:34 | LL | #[link(name = "...", modifiers = "")] | ^^ -error: invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed +error: invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed, export-symbols --> $DIR/link-attr-validation-late.rs:32:34 | LL | #[link(name = "...", modifiers = "no-plus-minus")] @@ -196,7 +196,7 @@ LL | #[link(name = "...", modifiers = "+unknown")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^----------^^ | | - | valid arguments are "bundle", "verbatim", "whole-archive" or "as-needed" + | valid arguments are "bundle", "export-symbols", "verbatim", "whole-archive" or "as-needed" | = note: for more information, visit <https://doc.rust-lang.org/reference/items/external-blocks.html#the-link-attribute>
diff --git a/tests/ui/link-native-libs/modifiers-bad.blank.stderr b/tests/ui/link-native-libs/modifiers-bad.blank.stderr index ea36af0..6a1953e 100644 --- a/tests/ui/link-native-libs/modifiers-bad.blank.stderr +++ b/tests/ui/link-native-libs/modifiers-bad.blank.stderr
@@ -1,2 +1,2 @@ -error: invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed +error: invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed, export-symbols
diff --git a/tests/ui/link-native-libs/modifiers-bad.no-prefix.stderr b/tests/ui/link-native-libs/modifiers-bad.no-prefix.stderr index ea36af0..6a1953e 100644 --- a/tests/ui/link-native-libs/modifiers-bad.no-prefix.stderr +++ b/tests/ui/link-native-libs/modifiers-bad.no-prefix.stderr
@@ -1,2 +1,2 @@ -error: invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed +error: invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed, export-symbols
diff --git a/tests/ui/link-native-libs/modifiers-bad.prefix-only.stderr b/tests/ui/link-native-libs/modifiers-bad.prefix-only.stderr index 1e70137..46720cf 100644 --- a/tests/ui/link-native-libs/modifiers-bad.prefix-only.stderr +++ b/tests/ui/link-native-libs/modifiers-bad.prefix-only.stderr
@@ -1,2 +1,2 @@ -error: unknown linking modifier ``, expected one of: bundle, verbatim, whole-archive, as-needed +error: unknown linking modifier ``, expected one of: bundle, verbatim, whole-archive, as-needed, export-symbols
diff --git a/tests/ui/link-native-libs/modifiers-bad.unknown.stderr b/tests/ui/link-native-libs/modifiers-bad.unknown.stderr index 75950ad..d47694a 100644 --- a/tests/ui/link-native-libs/modifiers-bad.unknown.stderr +++ b/tests/ui/link-native-libs/modifiers-bad.unknown.stderr
@@ -1,2 +1,2 @@ -error: unknown linking modifier `ferris`, expected one of: bundle, verbatim, whole-archive, as-needed +error: unknown linking modifier `ferris`, expected one of: bundle, verbatim, whole-archive, as-needed, export-symbols
diff --git a/tests/ui/malformed/malformed-regressions.rs b/tests/ui/malformed/malformed-regressions.rs index c0f8c0d..63b9185 100644 --- a/tests/ui/malformed/malformed-regressions.rs +++ b/tests/ui/malformed/malformed-regressions.rs
@@ -1,5 +1,6 @@ +#![deny(invalid_doc_attributes)] + #[doc] //~ ERROR valid forms for the attribute are -//~^ WARN this was previously accepted #[ignore()] //~ ERROR valid forms for the attribute are //~^ WARN this was previously accepted #[inline = ""] //~ ERROR valid forms for the attribute are
diff --git a/tests/ui/malformed/malformed-regressions.stderr b/tests/ui/malformed/malformed-regressions.stderr index 2bf6ff3..283834a 100644 --- a/tests/ui/malformed/malformed-regressions.stderr +++ b/tests/ui/malformed/malformed-regressions.stderr
@@ -1,5 +1,5 @@ error[E0539]: malformed `link` attribute input - --> $DIR/malformed-regressions.rs:7:1 + --> $DIR/malformed-regressions.rs:8:1 | LL | #[link] | ^^^^^^^ expected this to be a list @@ -7,7 +7,7 @@ = note: for more information, visit <https://doc.rust-lang.org/reference/items/external-blocks.html#the-link-attribute> error[E0539]: malformed `link` attribute input - --> $DIR/malformed-regressions.rs:10:1 + --> $DIR/malformed-regressions.rs:11:1 | LL | #[link = ""] | ^^^^^^^----^ @@ -17,7 +17,7 @@ = note: for more information, visit <https://doc.rust-lang.org/reference/items/external-blocks.html#the-link-attribute> warning: attribute should be applied to an `extern` block with non-Rust ABI - --> $DIR/malformed-regressions.rs:7:1 + --> $DIR/malformed-regressions.rs:8:1 | LL | #[link] | ^^^^^^^ @@ -29,26 +29,29 @@ = note: requested on the command line with `-W unused-attributes` error: valid forms for the attribute are `#[doc = "string"]`, `#[doc(alias)]`, `#[doc(attribute)]`, `#[doc(auto_cfg)]`, `#[doc(cfg)]`, `#[doc(fake_variadic)]`, `#[doc(hidden)]`, `#[doc(html_favicon_url)]`, `#[doc(html_logo_url)]`, `#[doc(html_no_source)]`, `#[doc(html_playground_url)]`, `#[doc(html_root_url)]`, `#[doc(include)]`, `#[doc(inline)]`, `#[doc(issue_tracker_base_url)]`, `#[doc(keyword)]`, `#[doc(masked)]`, `#[doc(no_default_passes)]`, `#[doc(no_inline)]`, `#[doc(notable_trait)]`, `#[doc(passes)]`, `#[doc(plugins)]`, `#[doc(rust_logo)]`, `#[doc(search_unbox)]`, `#[doc(spotlight)]`, and `#[doc(test)]` - --> $DIR/malformed-regressions.rs:1:1 + --> $DIR/malformed-regressions.rs:3:1 | LL | #[doc] | ^^^^^^ | - = 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 #57571 <https://github.com/rust-lang/rust/issues/57571> - = note: `#[deny(ill_formed_attribute_input)]` (part of `#[deny(future_incompatible)]`) on by default +note: the lint level is defined here + --> $DIR/malformed-regressions.rs:1:9 + | +LL | #![deny(invalid_doc_attributes)] + | ^^^^^^^^^^^^^^^^^^^^^^ error: valid forms for the attribute are `#[ignore = "reason"]` and `#[ignore]` - --> $DIR/malformed-regressions.rs:3:1 + --> $DIR/malformed-regressions.rs:4:1 | LL | #[ignore()] | ^^^^^^^^^^^ | = 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 #57571 <https://github.com/rust-lang/rust/issues/57571> + = note: `#[deny(ill_formed_attribute_input)]` (part of `#[deny(future_incompatible)]`) on by default error: valid forms for the attribute are `#[inline(always)]`, `#[inline(never)]`, and `#[inline]` - --> $DIR/malformed-regressions.rs:5:1 + --> $DIR/malformed-regressions.rs:6:1 | LL | #[inline = ""] | ^^^^^^^^^^^^^^ @@ -60,19 +63,8 @@ For more information about this error, try `rustc --explain E0539`. Future incompatibility report: Future breakage diagnostic: -error: valid forms for the attribute are `#[doc = "string"]`, `#[doc(alias)]`, `#[doc(attribute)]`, `#[doc(auto_cfg)]`, `#[doc(cfg)]`, `#[doc(fake_variadic)]`, `#[doc(hidden)]`, `#[doc(html_favicon_url)]`, `#[doc(html_logo_url)]`, `#[doc(html_no_source)]`, `#[doc(html_playground_url)]`, `#[doc(html_root_url)]`, `#[doc(include)]`, `#[doc(inline)]`, `#[doc(issue_tracker_base_url)]`, `#[doc(keyword)]`, `#[doc(masked)]`, `#[doc(no_default_passes)]`, `#[doc(no_inline)]`, `#[doc(notable_trait)]`, `#[doc(passes)]`, `#[doc(plugins)]`, `#[doc(rust_logo)]`, `#[doc(search_unbox)]`, `#[doc(spotlight)]`, and `#[doc(test)]` - --> $DIR/malformed-regressions.rs:1:1 - | -LL | #[doc] - | ^^^^^^ - | - = 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 #57571 <https://github.com/rust-lang/rust/issues/57571> - = note: `#[deny(ill_formed_attribute_input)]` (part of `#[deny(future_incompatible)]`) on by default - -Future breakage diagnostic: error: valid forms for the attribute are `#[ignore = "reason"]` and `#[ignore]` - --> $DIR/malformed-regressions.rs:3:1 + --> $DIR/malformed-regressions.rs:4:1 | LL | #[ignore()] | ^^^^^^^^^^^ @@ -83,7 +75,7 @@ Future breakage diagnostic: error: valid forms for the attribute are `#[inline(always)]`, `#[inline(never)]`, and `#[inline]` - --> $DIR/malformed-regressions.rs:5:1 + --> $DIR/malformed-regressions.rs:6:1 | LL | #[inline = ""] | ^^^^^^^^^^^^^^
diff --git a/tests/ui/malformed/malformed-special-attrs.rs b/tests/ui/malformed/malformed-special-attrs.rs index 05b7ebe..f0e66ef 100644 --- a/tests/ui/malformed/malformed-special-attrs.rs +++ b/tests/ui/malformed/malformed-special-attrs.rs
@@ -1,3 +1,5 @@ +#![deny(invalid_doc_attributes)] + #[cfg_attr] //~ ERROR malformed `cfg_attr` attribute struct S1;
diff --git a/tests/ui/malformed/malformed-special-attrs.stderr b/tests/ui/malformed/malformed-special-attrs.stderr index 91e5939..a2501d2 100644 --- a/tests/ui/malformed/malformed-special-attrs.stderr +++ b/tests/ui/malformed/malformed-special-attrs.stderr
@@ -1,5 +1,5 @@ error[E0539]: malformed `cfg_attr` attribute input - --> $DIR/malformed-special-attrs.rs:1:1 + --> $DIR/malformed-special-attrs.rs:3:1 | LL | #[cfg_attr] | ^^^^^^^^^^^ @@ -10,7 +10,7 @@ = note: for more information, visit <https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg_attr-attribute> error[E0539]: malformed `cfg_attr` attribute input - --> $DIR/malformed-special-attrs.rs:4:1 + --> $DIR/malformed-special-attrs.rs:6:1 | LL | #[cfg_attr = ""] | ^^^^^^^^^^^^^^^^ @@ -21,13 +21,13 @@ = note: for more information, visit <https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg_attr-attribute> error: malformed `derive` attribute input - --> $DIR/malformed-special-attrs.rs:7:1 + --> $DIR/malformed-special-attrs.rs:9:1 | LL | #[derive] | ^^^^^^^^^ help: must be of the form: `#[derive(Trait1, Trait2, ...)]` error: malformed `derive` attribute input - --> $DIR/malformed-special-attrs.rs:10:1 + --> $DIR/malformed-special-attrs.rs:12:1 | LL | #[derive = ""] | ^^^^^^^^^^^^^^ help: must be of the form: `#[derive(Trait1, Trait2, ...)]`
diff --git a/tests/ui/pin-ergonomics/impl-unpin.adt.stderr b/tests/ui/pin-ergonomics/impl-unpin.adt.stderr new file mode 100644 index 0000000..56fac42 --- /dev/null +++ b/tests/ui/pin-ergonomics/impl-unpin.adt.stderr
@@ -0,0 +1,14 @@ +error: explicit impls for the `Unpin` trait are not permitted for structurally pinned types + --> $DIR/impl-unpin.rs:14:5 + | +LL | impl Unpin for Foo {} + | ^^^^^^^^^^^^^^^^^^ impl of `Unpin` not allowed + | +help: `Foo` is structurally pinned because it is marked as `#[pin_v2]` + --> $DIR/impl-unpin.rs:7:1 + | +LL | struct Foo; + | ^^^^^^^^^^ + +error: aborting due to 1 previous error +
diff --git a/tests/ui/pin-ergonomics/impl-unpin.assoc.stderr b/tests/ui/pin-ergonomics/impl-unpin.assoc.stderr new file mode 100644 index 0000000..7f0ee1d --- /dev/null +++ b/tests/ui/pin-ergonomics/impl-unpin.assoc.stderr
@@ -0,0 +1,15 @@ +error[E0321]: cross-crate traits with a default impl, like `Unpin`, can only be implemented for a struct/enum type, not `<Foo as Identity>::Assoc` + --> $DIR/impl-unpin.rs:68:5 + | +LL | impl Unpin for <Foo as Identity>::Assoc {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't implement cross-crate trait with a default impl for non-struct/enum type + +error[E0321]: cross-crate traits with a default impl, like `Unpin`, can only be implemented for a struct/enum type, not `<Bar as Identity>::Assoc` + --> $DIR/impl-unpin.rs:70:5 + | +LL | impl Unpin for <Bar as Identity>::Assoc {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't implement cross-crate trait with a default impl for non-struct/enum type + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0321`.
diff --git a/tests/ui/pin-ergonomics/impl-unpin.rs b/tests/ui/pin-ergonomics/impl-unpin.rs new file mode 100644 index 0000000..ded8b47 --- /dev/null +++ b/tests/ui/pin-ergonomics/impl-unpin.rs
@@ -0,0 +1,74 @@ +//@ revisions: adt tait ty_alias assoc +#![feature(pin_ergonomics)] +#![cfg_attr(tait, feature(type_alias_impl_trait))] +#![allow(incomplete_features)] + +#[pin_v2] +struct Foo; +struct Bar; + +#[cfg(adt)] +mod adt { + use super::*; + + impl Unpin for Foo {} + //[adt]~^ ERROR explicit impls for the `Unpin` trait are not permitted for structurally pinned types + impl Unpin for Bar {} // ok +} + +#[cfg(ty_alias)] +mod ty_alias { + use super::*; + + type Identity<T> = T; + + impl Unpin for Identity<Foo> {} + //[ty_alias]~^ ERROR explicit impls for the `Unpin` trait are not permitted for structurally pinned types + impl Unpin for Identity<Bar> {} // ok +} + +#[cfg(tait)] +mod tait { + use super::*; + + trait Identity<T> {} + + impl<T> Identity<T> for T {} + + type FooAlias = impl Identity<Foo>; + type BarAlias = impl Identity<Bar>; + + #[define_opaque(FooAlias)] + fn foo_alias() -> FooAlias { + Foo + } + #[define_opaque(BarAlias)] + fn bar_alias() -> BarAlias { + Bar + } + + impl Unpin for FooAlias {} + //[tait]~^ ERROR only traits defined in the current crate can be implemented for arbitrary types + impl Unpin for BarAlias {} + //[tait]~^ ERROR only traits defined in the current crate can be implemented for arbitrary types +} + +#[cfg(assoc)] +mod assoc { + use super::*; + + trait Identity { + type Assoc; + } + + impl<T> Identity for T { + type Assoc = T; + } + + impl Unpin for <Foo as Identity>::Assoc {} + //[assoc]~^ ERROR cross-crate traits with a default impl, like `Unpin`, can only be implemented for a struct/enum type, not `<Foo as Identity>::Assoc` + impl Unpin for <Bar as Identity>::Assoc {} + //[assoc]~^ ERROR cross-crate traits with a default impl, like `Unpin`, can only be implemented for a struct/enum type, not `<Bar as Identity>::Assoc` +} + +fn main() {}
diff --git a/tests/ui/pin-ergonomics/impl-unpin.tait.stderr b/tests/ui/pin-ergonomics/impl-unpin.tait.stderr new file mode 100644 index 0000000..5d93927 --- /dev/null +++ b/tests/ui/pin-ergonomics/impl-unpin.tait.stderr
@@ -0,0 +1,27 @@ +error[E0117]: only traits defined in the current crate can be implemented for arbitrary types + --> $DIR/impl-unpin.rs:50:5 + | +LL | impl Unpin for FooAlias {} + | ^^^^^^^^^^^^^^^-------- + | | + | type alias impl trait is treated as if it were foreign, because its hidden type could be from a foreign crate + | + = note: impl doesn't have any local type before any uncovered type parameters + = note: for more information see https://doc.rust-lang.org/reference/items/implementations.html#orphan-rules + = note: define and implement a trait or new type instead + +error[E0117]: only traits defined in the current crate can be implemented for arbitrary types + --> $DIR/impl-unpin.rs:52:5 + | +LL | impl Unpin for BarAlias {} + | ^^^^^^^^^^^^^^^-------- + | | + | type alias impl trait is treated as if it were foreign, because its hidden type could be from a foreign crate + | + = note: impl doesn't have any local type before any uncovered type parameters + = note: for more information see https://doc.rust-lang.org/reference/items/implementations.html#orphan-rules + = note: define and implement a trait or new type instead + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0117`.
diff --git a/tests/ui/pin-ergonomics/impl-unpin.ty_alias.stderr b/tests/ui/pin-ergonomics/impl-unpin.ty_alias.stderr new file mode 100644 index 0000000..82c1a7d --- /dev/null +++ b/tests/ui/pin-ergonomics/impl-unpin.ty_alias.stderr
@@ -0,0 +1,14 @@ +error: explicit impls for the `Unpin` trait are not permitted for structurally pinned types + --> $DIR/impl-unpin.rs:25:5 + | +LL | impl Unpin for Identity<Foo> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl of `Unpin` not allowed + | +help: `Foo` is structurally pinned because it is marked as `#[pin_v2]` + --> $DIR/impl-unpin.rs:7:1 + | +LL | struct Foo; + | ^^^^^^^^^^ + +error: aborting due to 1 previous error +
diff --git a/tests/ui/repr/invalid_repr_list_help.rs b/tests/ui/repr/invalid_repr_list_help.rs index 77f2a68..e8bf5fd 100644 --- a/tests/ui/repr/invalid_repr_list_help.rs +++ b/tests/ui/repr/invalid_repr_list_help.rs
@@ -1,3 +1,4 @@ +#![deny(invalid_doc_attributes)] #![crate_type = "lib"] #[repr(uwu)] //~ERROR: unrecognized representation hint
diff --git a/tests/ui/repr/invalid_repr_list_help.stderr b/tests/ui/repr/invalid_repr_list_help.stderr index f9d1593..3226508 100644 --- a/tests/ui/repr/invalid_repr_list_help.stderr +++ b/tests/ui/repr/invalid_repr_list_help.stderr
@@ -1,5 +1,5 @@ error[E0552]: unrecognized representation hint - --> $DIR/invalid_repr_list_help.rs:3:8 + --> $DIR/invalid_repr_list_help.rs:4:8 | LL | #[repr(uwu)] | ^^^ @@ -8,7 +8,7 @@ = note: for more information, visit <https://doc.rust-lang.org/reference/type-layout.html?highlight=repr#representations> error[E0552]: unrecognized representation hint - --> $DIR/invalid_repr_list_help.rs:6:8 + --> $DIR/invalid_repr_list_help.rs:7:8 | LL | #[repr(uwu = "a")] | ^^^^^^^^^ @@ -17,7 +17,7 @@ = note: for more information, visit <https://doc.rust-lang.org/reference/type-layout.html?highlight=repr#representations> error[E0552]: unrecognized representation hint - --> $DIR/invalid_repr_list_help.rs:9:8 + --> $DIR/invalid_repr_list_help.rs:10:8 | LL | #[repr(uwu(4))] | ^^^^^^ @@ -26,7 +26,7 @@ = note: for more information, visit <https://doc.rust-lang.org/reference/type-layout.html?highlight=repr#representations> error[E0552]: unrecognized representation hint - --> $DIR/invalid_repr_list_help.rs:14:8 + --> $DIR/invalid_repr_list_help.rs:15:8 | LL | #[repr(uwu, u8)] | ^^^ @@ -35,7 +35,7 @@ = note: for more information, visit <https://doc.rust-lang.org/reference/type-layout.html?highlight=repr#representations> error[E0552]: unrecognized representation hint - --> $DIR/invalid_repr_list_help.rs:19:8 + --> $DIR/invalid_repr_list_help.rs:20:8 | LL | #[repr(uwu)] | ^^^ @@ -44,12 +44,16 @@ = note: for more information, visit <https://doc.rust-lang.org/reference/type-layout.html?highlight=repr#representations> error: unknown `doc` attribute `owo` - --> $DIR/invalid_repr_list_help.rs:20:7 + --> $DIR/invalid_repr_list_help.rs:21:7 | LL | #[doc(owo)] | ^^^ | - = note: `#[deny(invalid_doc_attributes)]` on by default +note: the lint level is defined here + --> $DIR/invalid_repr_list_help.rs:1:9 + | +LL | #![deny(invalid_doc_attributes)] + | ^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 6 previous errors
diff --git a/tests/ui/type/recover-from-semicolon-trailing-undefined.rs b/tests/ui/type/recover-from-semicolon-trailing-undefined.rs new file mode 100644 index 0000000..3e2860e --- /dev/null +++ b/tests/ui/type/recover-from-semicolon-trailing-undefined.rs
@@ -0,0 +1,12 @@ +//@ compile-flags: -Znext-solver=globally + +// Regression test for https://github.com/rust-lang/rust/issues/151610 + +fn main() { + let x_str = { + x!("{}", x); + //~^ ERROR cannot find macro `x` in this scope + }; + println!("{}", x_str); + //~^ ERROR `()` doesn't implement `std::fmt::Display` +}
diff --git a/tests/ui/type/recover-from-semicolon-trailing-undefined.stderr b/tests/ui/type/recover-from-semicolon-trailing-undefined.stderr new file mode 100644 index 0000000..6a8295d --- /dev/null +++ b/tests/ui/type/recover-from-semicolon-trailing-undefined.stderr
@@ -0,0 +1,26 @@ +error: cannot find macro `x` in this scope + --> $DIR/recover-from-semicolon-trailing-undefined.rs:7:9 + | +LL | x!("{}", x); + | ^ + +error[E0277]: `()` doesn't implement `std::fmt::Display` + --> $DIR/recover-from-semicolon-trailing-undefined.rs:10:20 + | +LL | let x_str = { + | _________________- +LL | | x!("{}", x); +LL | | +LL | | }; + | |_____- this block is missing a tail expression +LL | println!("{}", x_str); + | -- ^^^^^ `()` cannot be formatted with the default formatter + | | + | required by this formatting parameter + | + = help: the trait `std::fmt::Display` is not implemented for `()` + = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`.
diff --git a/x b/x index 4fce0be..a8acbd4 100755 --- a/x +++ b/x
@@ -29,16 +29,19 @@ # On MacOS, `py` tries to install "Developer command line tools". Try `python3` first. # NOTE: running `bash -c ./x` from Windows doesn't set OSTYPE. case ${OSTYPE:-} in - cygwin*|msys*) SEARCH="py python3 python python2";; - *) SEARCH="python3 python py python2";; + cygwin*|msys*) SEARCH="py python3 python python2 uv";; + *) SEARCH="python3 python py python2 uv";; esac for SEARCH_PYTHON in $SEARCH; do if python=$(command -v $SEARCH_PYTHON) && [ -x "$python" ]; then - if [ $SEARCH_PYTHON = py ]; then - extra_arg="-3" - else - extra_arg="" - fi + case $SEARCH_PYTHON in + py) + extra_arg="-3";; + uv) + extra_arg="run";; + *) + extra_arg="";; + esac exec "$python" $extra_arg "$xpy" "$@" fi done