mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-17 06:26:55 +00:00
Auto merge of #137093 - matthiaskrgr:rollup-72j7mut, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - #127581 (Fix crate name validation) - #136490 (Do not allow attributes on struct field rest patterns) - #136808 (Try to recover from path sep error in type parsing) - #137055 (rustdoc: Properly restore search input placeholder) - #137068 (fix(rustdoc): Fixed `Copy Item Path` in rust doc) - #137070 (Do not generate invalid links in job summaries) - #137074 (compiletest: add `{ignore,only}-rustc_abi-x86-sse2` directives) - #137076 (triagebot.toml: ping me on changes to `tests/rustdoc-json`) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
500a686ba8
@ -667,11 +667,12 @@ fn print_crate_info(
|
||||
return Compilation::Continue;
|
||||
};
|
||||
let t_outputs = rustc_interface::util::build_output_filenames(attrs, sess);
|
||||
let id = rustc_session::output::find_crate_name(sess, attrs);
|
||||
let crate_name = passes::get_crate_name(sess, attrs);
|
||||
let crate_types = collect_crate_types(sess, attrs);
|
||||
for &style in &crate_types {
|
||||
let fname =
|
||||
rustc_session::output::filename_for_input(sess, style, id, &t_outputs);
|
||||
let fname = rustc_session::output::filename_for_input(
|
||||
sess, style, crate_name, &t_outputs,
|
||||
);
|
||||
println_info!("{}", fname.as_path().file_name().unwrap().to_string_lossy());
|
||||
}
|
||||
}
|
||||
@ -680,8 +681,7 @@ fn print_crate_info(
|
||||
// no crate attributes, print out an error and exit
|
||||
return Compilation::Continue;
|
||||
};
|
||||
let id = rustc_session::output::find_crate_name(sess, attrs);
|
||||
println_info!("{id}");
|
||||
println_info!("{}", passes::get_crate_name(sess, attrs));
|
||||
}
|
||||
Cfg => {
|
||||
let mut cfgs = sess
|
||||
|
@ -183,12 +183,12 @@ pub(crate) fn mod_file_path_from_attr(
|
||||
let first_path = attrs.iter().find(|at| at.has_name(sym::path))?;
|
||||
let Some(path_sym) = first_path.value_str() else {
|
||||
// This check is here mainly to catch attempting to use a macro,
|
||||
// such as #[path = concat!(...)]. This isn't currently supported
|
||||
// because otherwise the InvocationCollector would need to defer
|
||||
// loading a module until the #[path] attribute was expanded, and
|
||||
// it doesn't support that (and would likely add a bit of
|
||||
// complexity). Usually bad forms are checked in AstValidator (via
|
||||
// `check_builtin_attribute`), but by the time that runs the macro
|
||||
// such as `#[path = concat!(...)]`. This isn't supported because
|
||||
// otherwise the `InvocationCollector` would need to defer loading
|
||||
// a module until the `#[path]` attribute was expanded, and it
|
||||
// doesn't support that (and would likely add a bit of complexity).
|
||||
// Usually bad forms are checked during semantic analysis via
|
||||
// `TyCtxt::check_mod_attrs`), but by the time that runs the macro
|
||||
// is expanded, and it doesn't give an error.
|
||||
validate_attr::emit_fatal_malformed_builtin_attribute(&sess.psess, first_path, sym::path);
|
||||
};
|
||||
|
@ -117,8 +117,9 @@ use rustc_data_structures::{base_n, flock};
|
||||
use rustc_fs_util::{LinkOrCopy, link_or_copy, try_canonicalize};
|
||||
use rustc_middle::bug;
|
||||
use rustc_session::config::CrateType;
|
||||
use rustc_session::output::{collect_crate_types, find_crate_name};
|
||||
use rustc_session::output::collect_crate_types;
|
||||
use rustc_session::{Session, StableCrateId};
|
||||
use rustc_span::Symbol;
|
||||
use tracing::debug;
|
||||
|
||||
use crate::errors;
|
||||
@ -211,7 +212,7 @@ pub fn in_incr_comp_dir(incr_comp_session_dir: &Path, file_name: &str) -> PathBu
|
||||
/// The garbage collection will take care of it.
|
||||
///
|
||||
/// [`rustc_interface::queries::dep_graph`]: ../../rustc_interface/struct.Queries.html#structfield.dep_graph
|
||||
pub(crate) fn prepare_session_directory(sess: &Session) {
|
||||
pub(crate) fn prepare_session_directory(sess: &Session, crate_name: Symbol) {
|
||||
if sess.opts.incremental.is_none() {
|
||||
return;
|
||||
}
|
||||
@ -221,7 +222,7 @@ pub(crate) fn prepare_session_directory(sess: &Session) {
|
||||
debug!("prepare_session_directory");
|
||||
|
||||
// {incr-comp-dir}/{crate-name-and-disambiguator}
|
||||
let crate_dir = crate_path(sess);
|
||||
let crate_dir = crate_path(sess, crate_name);
|
||||
debug!("crate-dir: {}", crate_dir.display());
|
||||
create_dir(sess, &crate_dir, "crate");
|
||||
|
||||
@ -594,10 +595,9 @@ fn string_to_timestamp(s: &str) -> Result<SystemTime, &'static str> {
|
||||
Ok(UNIX_EPOCH + duration)
|
||||
}
|
||||
|
||||
fn crate_path(sess: &Session) -> PathBuf {
|
||||
fn crate_path(sess: &Session, crate_name: Symbol) -> PathBuf {
|
||||
let incr_dir = sess.opts.incremental.as_ref().unwrap().clone();
|
||||
|
||||
let crate_name = find_crate_name(sess, &[]);
|
||||
let crate_types = collect_crate_types(sess, &[]);
|
||||
let stable_crate_id = StableCrateId::new(
|
||||
crate_name,
|
||||
|
@ -11,6 +11,7 @@ use rustc_serialize::Decodable;
|
||||
use rustc_serialize::opaque::MemDecoder;
|
||||
use rustc_session::Session;
|
||||
use rustc_session::config::IncrementalStateAssertion;
|
||||
use rustc_span::Symbol;
|
||||
use tracing::{debug, warn};
|
||||
|
||||
use super::data::*;
|
||||
@ -203,9 +204,9 @@ pub fn load_query_result_cache(sess: &Session) -> Option<OnDiskCache> {
|
||||
|
||||
/// Setups the dependency graph by loading an existing graph from disk and set up streaming of a
|
||||
/// new graph to an incremental session directory.
|
||||
pub fn setup_dep_graph(sess: &Session) -> DepGraph {
|
||||
pub fn setup_dep_graph(sess: &Session, crate_name: Symbol) -> DepGraph {
|
||||
// `load_dep_graph` can only be called after `prepare_session_directory`.
|
||||
prepare_session_directory(sess);
|
||||
prepare_session_directory(sess, crate_name);
|
||||
|
||||
let res = sess.opts.build_dep_graph().then(|| load_dep_graph(sess));
|
||||
|
||||
|
@ -6,6 +6,10 @@ interface_abi_required_feature_issue = for more information, see issue #116344 <
|
||||
interface_cant_emit_mir =
|
||||
could not emit MIR: {$error}
|
||||
|
||||
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}`
|
||||
|
||||
|
@ -4,6 +4,21 @@ use std::path::Path;
|
||||
use rustc_macros::Diagnostic;
|
||||
use rustc_span::{Span, Symbol};
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(interface_crate_name_does_not_match)]
|
||||
pub(crate) struct CrateNameDoesNotMatch {
|
||||
#[primary_span]
|
||||
pub(crate) span: Span,
|
||||
pub(crate) crate_name: Symbol,
|
||||
pub(crate) attr_crate_name: Symbol,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(interface_crate_name_invalid)]
|
||||
pub(crate) struct CrateNameInvalid<'a> {
|
||||
pub(crate) crate_name: &'a str,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(interface_ferris_identifier)]
|
||||
pub struct FerrisIdentifier {
|
||||
|
@ -28,10 +28,12 @@ use rustc_passes::{abi_test, input_stats, layout_test};
|
||||
use rustc_resolve::Resolver;
|
||||
use rustc_session::config::{CrateType, Input, OutFileName, OutputFilenames, OutputType};
|
||||
use rustc_session::cstore::Untracked;
|
||||
use rustc_session::output::{collect_crate_types, filename_for_input, find_crate_name};
|
||||
use rustc_session::output::{collect_crate_types, filename_for_input};
|
||||
use rustc_session::search_paths::PathKind;
|
||||
use rustc_session::{Limit, Session};
|
||||
use rustc_span::{ErrorGuaranteed, FileName, SourceFileHash, SourceFileHashAlgorithm, Symbol, sym};
|
||||
use rustc_span::{
|
||||
ErrorGuaranteed, FileName, SourceFileHash, SourceFileHashAlgorithm, Span, Symbol, sym,
|
||||
};
|
||||
use rustc_target::spec::PanicStrategy;
|
||||
use rustc_trait_selection::traits;
|
||||
use tracing::{info, instrument};
|
||||
@ -725,8 +727,7 @@ pub fn create_and_enter_global_ctxt<T, F: for<'tcx> FnOnce(TyCtxt<'tcx>) -> T>(
|
||||
|
||||
let pre_configured_attrs = rustc_expand::config::pre_configure_attrs(sess, &krate.attrs);
|
||||
|
||||
// parse `#[crate_name]` even if `--crate-name` was passed, to make sure it matches.
|
||||
let crate_name = find_crate_name(sess, &pre_configured_attrs);
|
||||
let crate_name = get_crate_name(sess, &pre_configured_attrs);
|
||||
let crate_types = collect_crate_types(sess, &pre_configured_attrs);
|
||||
let stable_crate_id = StableCrateId::new(
|
||||
crate_name,
|
||||
@ -735,7 +736,7 @@ pub fn create_and_enter_global_ctxt<T, F: for<'tcx> FnOnce(TyCtxt<'tcx>) -> T>(
|
||||
sess.cfg_version,
|
||||
);
|
||||
let outputs = util::build_output_filenames(&pre_configured_attrs, sess);
|
||||
let dep_graph = setup_dep_graph(sess);
|
||||
let dep_graph = setup_dep_graph(sess, crate_name);
|
||||
|
||||
let cstore =
|
||||
FreezeLock::new(Box::new(CStore::new(compiler.codegen_backend.metadata_loader())) as _);
|
||||
@ -1080,23 +1081,85 @@ pub(crate) fn start_codegen<'tcx>(
|
||||
codegen
|
||||
}
|
||||
|
||||
fn get_recursion_limit(krate_attrs: &[ast::Attribute], sess: &Session) -> Limit {
|
||||
if let Some(attr) = krate_attrs
|
||||
.iter()
|
||||
.find(|attr| attr.has_name(sym::recursion_limit) && attr.value_str().is_none())
|
||||
{
|
||||
// This is here mainly to check for using a macro, such as
|
||||
// #![recursion_limit = foo!()]. That is not supported since that
|
||||
// would require expanding this while in the middle of expansion,
|
||||
// which needs to know the limit before expanding. Otherwise,
|
||||
// validation would normally be caught in AstValidator (via
|
||||
// `check_builtin_attribute`), but by the time that runs the macro
|
||||
// is expanded, and it doesn't give an error.
|
||||
validate_attr::emit_fatal_malformed_builtin_attribute(
|
||||
&sess.psess,
|
||||
attr,
|
||||
sym::recursion_limit,
|
||||
);
|
||||
/// Compute and validate the crate name.
|
||||
pub fn get_crate_name(sess: &Session, krate_attrs: &[ast::Attribute]) -> Symbol {
|
||||
// We validate *all* occurrences of `#![crate_name]`, pick the first find and
|
||||
// if a crate name was passed on the command line via `--crate-name` we enforce
|
||||
// that they match.
|
||||
// We perform the validation step here instead of later to ensure it gets run
|
||||
// in all code paths that require the crate name very early on, namely before
|
||||
// macro expansion.
|
||||
|
||||
let attr_crate_name =
|
||||
validate_and_find_value_str_builtin_attr(sym::crate_name, sess, krate_attrs);
|
||||
|
||||
let validate = |name, span| {
|
||||
rustc_session::output::validate_crate_name(sess, name, span);
|
||||
name
|
||||
};
|
||||
|
||||
if let Some(crate_name) = &sess.opts.crate_name {
|
||||
let crate_name = Symbol::intern(crate_name);
|
||||
if let Some((attr_crate_name, span)) = attr_crate_name
|
||||
&& attr_crate_name != crate_name
|
||||
{
|
||||
sess.dcx().emit_err(errors::CrateNameDoesNotMatch {
|
||||
span,
|
||||
crate_name,
|
||||
attr_crate_name,
|
||||
});
|
||||
}
|
||||
return validate(crate_name, None);
|
||||
}
|
||||
|
||||
if let Some((crate_name, span)) = attr_crate_name {
|
||||
return validate(crate_name, Some(span));
|
||||
}
|
||||
|
||||
if let Input::File(ref path) = sess.io.input
|
||||
&& let Some(file_stem) = path.file_stem().and_then(|s| s.to_str())
|
||||
{
|
||||
if file_stem.starts_with('-') {
|
||||
sess.dcx().emit_err(errors::CrateNameInvalid { crate_name: file_stem });
|
||||
} else {
|
||||
return validate(Symbol::intern(&file_stem.replace('-', "_")), None);
|
||||
}
|
||||
}
|
||||
|
||||
sym::rust_out
|
||||
}
|
||||
|
||||
fn get_recursion_limit(krate_attrs: &[ast::Attribute], sess: &Session) -> Limit {
|
||||
// We don't permit macro calls inside of the attribute (e.g., #![recursion_limit = `expand!()`])
|
||||
// because that would require expanding this while in the middle of expansion, which needs to
|
||||
// know the limit before expanding.
|
||||
let _ = validate_and_find_value_str_builtin_attr(sym::recursion_limit, sess, krate_attrs);
|
||||
rustc_middle::middle::limits::get_recursion_limit(krate_attrs, sess)
|
||||
}
|
||||
|
||||
/// Validate *all* occurrences of the given "[value-str]" built-in attribute and return the first find.
|
||||
///
|
||||
/// This validator is intended for built-in attributes whose value needs to be known very early
|
||||
/// during compilation (namely, before macro expansion) and it mainly exists to reject macro calls
|
||||
/// inside of the attributes, such as in `#![name = expand!()]`. Normal attribute validation happens
|
||||
/// during semantic analysis via [`TyCtxt::check_mod_attrs`] which happens *after* macro expansion
|
||||
/// when such macro calls (here: `expand`) have already been expanded and we can no longer check for
|
||||
/// their presence.
|
||||
///
|
||||
/// [value-str]: ast::Attribute::value_str
|
||||
fn validate_and_find_value_str_builtin_attr(
|
||||
name: Symbol,
|
||||
sess: &Session,
|
||||
krate_attrs: &[ast::Attribute],
|
||||
) -> Option<(Symbol, Span)> {
|
||||
let mut result = None;
|
||||
// Validate *all* relevant attributes, not just the first occurrence.
|
||||
for attr in ast::attr::filter_by_name(krate_attrs, name) {
|
||||
let Some(value) = attr.value_str() else {
|
||||
validate_attr::emit_fatal_malformed_builtin_attribute(&sess.psess, attr, name)
|
||||
};
|
||||
// Choose the first occurrence as our result.
|
||||
result.get_or_insert((value, attr.span));
|
||||
}
|
||||
result
|
||||
}
|
||||
|
@ -433,11 +433,11 @@ pub(crate) fn check_attr_crate_type(
|
||||
}
|
||||
} else {
|
||||
// This is here mainly to check for using a macro, such as
|
||||
// #![crate_type = foo!()]. That is not supported since the
|
||||
// `#![crate_type = foo!()]`. That is not supported since the
|
||||
// crate type needs to be known very early in compilation long
|
||||
// before expansion. Otherwise, validation would normally be
|
||||
// caught in AstValidator (via `check_builtin_attribute`), but
|
||||
// by the time that runs the macro is expanded, and it doesn't
|
||||
// caught during semantic analysis via `TyCtxt::check_mod_attrs`,
|
||||
// but by the time that runs the macro is expanded, and it doesn't
|
||||
// give an error.
|
||||
validate_attr::emit_fatal_malformed_builtin_attribute(
|
||||
&sess.psess,
|
||||
|
@ -743,9 +743,6 @@ parse_single_colon_import_path = expected `::`, found `:`
|
||||
.suggestion = use double colon
|
||||
.note = import paths are delimited using `::`
|
||||
|
||||
parse_single_colon_struct_type = found single colon in a struct field type path
|
||||
.suggestion = write a path separator here
|
||||
|
||||
parse_static_with_generics = static items may not have generic parameters
|
||||
|
||||
parse_struct_literal_body_without_path =
|
||||
|
@ -3071,14 +3071,6 @@ pub(crate) struct BadItemKind {
|
||||
pub help: bool,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(parse_single_colon_struct_type)]
|
||||
pub(crate) struct SingleColonStructType {
|
||||
#[primary_span]
|
||||
#[suggestion(code = "::", applicability = "maybe-incorrect", style = "verbose")]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(parse_macro_rules_missing_bang)]
|
||||
pub(crate) struct MacroRulesMissingBang {
|
||||
|
@ -2043,9 +2043,6 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
self.expect_field_ty_separator()?;
|
||||
let ty = self.parse_ty()?;
|
||||
if self.token == token::Colon && self.look_ahead(1, |t| *t != token::Colon) {
|
||||
self.dcx().emit_err(errors::SingleColonStructType { span: self.token.span });
|
||||
}
|
||||
let default = if self.token == token::Eq {
|
||||
self.bump();
|
||||
let const_expr = self.parse_expr_anon_const()?;
|
||||
|
@ -1472,17 +1472,6 @@ impl<'a> Parser<'a> {
|
||||
let mut last_non_comma_dotdot_span = None;
|
||||
|
||||
while self.token != token::CloseDelim(Delimiter::Brace) {
|
||||
let attrs = match self.parse_outer_attributes() {
|
||||
Ok(attrs) => attrs,
|
||||
Err(err) => {
|
||||
if let Some(delayed) = delayed_err {
|
||||
delayed.emit();
|
||||
}
|
||||
return Err(err);
|
||||
}
|
||||
};
|
||||
let lo = self.token.span;
|
||||
|
||||
// check that a comma comes after every field
|
||||
if !ate_comma {
|
||||
let err = if self.token == token::At {
|
||||
@ -1585,6 +1574,17 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
let attrs = match self.parse_outer_attributes() {
|
||||
Ok(attrs) => attrs,
|
||||
Err(err) => {
|
||||
if let Some(delayed) = delayed_err {
|
||||
delayed.emit();
|
||||
}
|
||||
return Err(err);
|
||||
}
|
||||
};
|
||||
let lo = self.token.span;
|
||||
|
||||
let field = self.collect_tokens(None, attrs, ForceCollect::No, |this, attrs| {
|
||||
let field = match this.parse_pat_field(lo, attrs) {
|
||||
Ok(field) => Ok(field),
|
||||
|
@ -246,8 +246,19 @@ impl<'a> Parser<'a> {
|
||||
segments.push(segment);
|
||||
|
||||
if self.is_import_coupler() || !self.eat_path_sep() {
|
||||
if style == PathStyle::Expr
|
||||
&& self.may_recover()
|
||||
let ok_for_recovery = self.may_recover()
|
||||
&& match style {
|
||||
PathStyle::Expr => true,
|
||||
PathStyle::Type if let Some((ident, _)) = self.prev_token.ident() => {
|
||||
self.token == token::Colon
|
||||
&& ident.as_str().chars().all(|c| c.is_lowercase())
|
||||
&& self.token.span.lo() == self.prev_token.span.hi()
|
||||
&& self
|
||||
.look_ahead(1, |token| self.token.span.hi() == token.span.lo())
|
||||
}
|
||||
_ => false,
|
||||
};
|
||||
if ok_for_recovery
|
||||
&& self.token == token::Colon
|
||||
&& self.look_ahead(1, |token| token.is_ident() && !token.is_reserved_ident())
|
||||
{
|
||||
|
@ -8,12 +8,8 @@ session_cannot_mix_and_match_sanitizers = `-Zsanitizer={$first}` is incompatible
|
||||
session_cli_feature_diagnostic_help =
|
||||
add `-Zcrate-attr="feature({$feature})"` to the command-line options to enable
|
||||
|
||||
session_crate_name_does_not_match = `--crate-name` and `#[crate_name]` are required to match, but `{$s}` != `{$name}`
|
||||
|
||||
session_crate_name_empty = crate name must not be empty
|
||||
|
||||
session_crate_name_invalid = crate names cannot start with a `-`, but `{$s}` has a leading hyphen
|
||||
|
||||
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
|
||||
@ -52,8 +48,8 @@ session_instrumentation_not_supported = {$us} instrumentation is not supported f
|
||||
session_int_literal_too_large = integer literal is too large
|
||||
.note = value exceeds limit of `{$limit}`
|
||||
|
||||
session_invalid_character_in_create_name = invalid character `{$character}` in crate name: `{$crate_name}`
|
||||
session_invalid_character_in_create_name_help = you can either pass `--crate-name` on the command line or add `#![crate_name="…"]` to set the crate name
|
||||
session_invalid_character_in_crate_name = invalid character {$character} in crate name: `{$crate_name}`
|
||||
.help = you can either pass `--crate-name` on the command line or add `#![crate_name = "…"]` to set the crate name
|
||||
|
||||
session_invalid_float_literal_suffix = invalid suffix `{$suffix}` for float literal
|
||||
.label = invalid suffix `{$suffix}`
|
||||
|
@ -212,21 +212,6 @@ pub(crate) struct FileWriteFail<'a> {
|
||||
pub(crate) err: String,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(session_crate_name_does_not_match)]
|
||||
pub(crate) struct CrateNameDoesNotMatch {
|
||||
#[primary_span]
|
||||
pub(crate) span: Span,
|
||||
pub(crate) s: Symbol,
|
||||
pub(crate) name: Symbol,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(session_crate_name_invalid)]
|
||||
pub(crate) struct CrateNameInvalid<'a> {
|
||||
pub(crate) s: &'a str,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(session_crate_name_empty)]
|
||||
pub(crate) struct CrateNameEmpty {
|
||||
@ -235,20 +220,14 @@ pub(crate) struct CrateNameEmpty {
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(session_invalid_character_in_create_name)]
|
||||
#[diag(session_invalid_character_in_crate_name)]
|
||||
pub(crate) struct InvalidCharacterInCrateName {
|
||||
#[primary_span]
|
||||
pub(crate) span: Option<Span>,
|
||||
pub(crate) character: char,
|
||||
pub(crate) crate_name: Symbol,
|
||||
#[subdiagnostic]
|
||||
pub(crate) crate_name_help: Option<InvalidCrateNameHelp>,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
pub(crate) enum InvalidCrateNameHelp {
|
||||
#[help(session_invalid_character_in_create_name_help)]
|
||||
AddCrateName,
|
||||
#[help]
|
||||
pub(crate) help: Option<()>,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
|
@ -2,15 +2,12 @@
|
||||
|
||||
use std::path::Path;
|
||||
|
||||
use rustc_ast::{self as ast, attr};
|
||||
use rustc_ast as ast;
|
||||
use rustc_span::{Span, Symbol, sym};
|
||||
|
||||
use crate::Session;
|
||||
use crate::config::{self, CrateType, Input, OutFileName, OutputFilenames, OutputType};
|
||||
use crate::errors::{
|
||||
self, CrateNameDoesNotMatch, CrateNameEmpty, CrateNameInvalid, FileIsNotWriteable,
|
||||
InvalidCharacterInCrateName, InvalidCrateNameHelp,
|
||||
};
|
||||
use crate::config::{self, CrateType, OutFileName, OutputFilenames, OutputType};
|
||||
use crate::errors::{self, CrateNameEmpty, FileIsNotWriteable, InvalidCharacterInCrateName};
|
||||
|
||||
pub fn out_filename(
|
||||
sess: &Session,
|
||||
@ -49,69 +46,31 @@ fn is_writeable(p: &Path) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn find_crate_name(sess: &Session, attrs: &[ast::Attribute]) -> Symbol {
|
||||
let validate = |s: Symbol, span: Option<Span>| {
|
||||
validate_crate_name(sess, s, span);
|
||||
s
|
||||
};
|
||||
|
||||
// Look in attributes 100% of the time to make sure the attribute is marked
|
||||
// as used. After doing this, however, we still prioritize a crate name from
|
||||
// the command line over one found in the #[crate_name] attribute. If we
|
||||
// find both we ensure that they're the same later on as well.
|
||||
let attr_crate_name =
|
||||
attr::find_by_name(attrs, sym::crate_name).and_then(|at| at.value_str().map(|s| (at, s)));
|
||||
|
||||
if let Some(ref s) = sess.opts.crate_name {
|
||||
let s = Symbol::intern(s);
|
||||
if let Some((attr, name)) = attr_crate_name {
|
||||
if name != s {
|
||||
sess.dcx().emit_err(CrateNameDoesNotMatch { span: attr.span, s, name });
|
||||
}
|
||||
}
|
||||
return validate(s, None);
|
||||
}
|
||||
|
||||
if let Some((attr, s)) = attr_crate_name {
|
||||
return validate(s, Some(attr.span));
|
||||
}
|
||||
if let Input::File(ref path) = sess.io.input {
|
||||
if let Some(s) = path.file_stem().and_then(|s| s.to_str()) {
|
||||
if s.starts_with('-') {
|
||||
sess.dcx().emit_err(CrateNameInvalid { s });
|
||||
} else {
|
||||
return validate(Symbol::intern(&s.replace('-', "_")), None);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sym::rust_out
|
||||
}
|
||||
|
||||
pub fn validate_crate_name(sess: &Session, s: Symbol, sp: Option<Span>) {
|
||||
/// Validate the given crate name.
|
||||
///
|
||||
/// Note that this validation is more permissive than identifier parsing. It considers
|
||||
/// non-empty sequences of alphanumeric and underscore characters to be valid crate names.
|
||||
/// Most notably, it accepts names starting with a numeric character like `0`!
|
||||
///
|
||||
/// Furthermore, this shouldn't be taken as the canonical crate name validator.
|
||||
/// Other places may use a more restrictive grammar (e.g., identifier or ASCII identifier).
|
||||
pub fn validate_crate_name(sess: &Session, crate_name: Symbol, span: Option<Span>) {
|
||||
let mut guar = None;
|
||||
{
|
||||
if s.is_empty() {
|
||||
guar = Some(sess.dcx().emit_err(CrateNameEmpty { span: sp }));
|
||||
}
|
||||
for c in s.as_str().chars() {
|
||||
if c.is_alphanumeric() {
|
||||
continue;
|
||||
}
|
||||
if c == '_' {
|
||||
continue;
|
||||
}
|
||||
guar = Some(sess.dcx().emit_err(InvalidCharacterInCrateName {
|
||||
span: sp,
|
||||
character: c,
|
||||
crate_name: s,
|
||||
crate_name_help: if sp.is_none() {
|
||||
Some(InvalidCrateNameHelp::AddCrateName)
|
||||
} else {
|
||||
None
|
||||
},
|
||||
}));
|
||||
|
||||
if crate_name.is_empty() {
|
||||
guar = Some(sess.dcx().emit_err(CrateNameEmpty { span }));
|
||||
}
|
||||
|
||||
for c in crate_name.as_str().chars() {
|
||||
if c.is_alphanumeric() || c == '_' {
|
||||
continue;
|
||||
}
|
||||
guar = Some(sess.dcx().emit_err(InvalidCharacterInCrateName {
|
||||
span,
|
||||
character: c,
|
||||
crate_name,
|
||||
help: span.is_none().then_some(()),
|
||||
}));
|
||||
}
|
||||
|
||||
if let Some(guar) = guar {
|
||||
|
@ -52,10 +52,15 @@ access_url="https://ci-artifacts.rust-lang.org/${deploy_dir}/$(ciCommit)"
|
||||
# to make them easily accessible.
|
||||
if [ -n "${GITHUB_STEP_SUMMARY}" ]
|
||||
then
|
||||
echo "# CI artifacts" >> "${GITHUB_STEP_SUMMARY}"
|
||||
archives=($(find "${upload_dir}" -maxdepth 1 -name "*.xz"))
|
||||
|
||||
for filename in "${upload_dir}"/*.xz; do
|
||||
filename=$(basename "${filename}")
|
||||
echo "- [${filename}](${access_url}/${filename})" >> "${GITHUB_STEP_SUMMARY}"
|
||||
done
|
||||
# Avoid generating an invalid "*.xz" file if there are no archives
|
||||
if [ ${#archives[@]} -gt 0 ]; then
|
||||
echo "# CI artifacts" >> "${GITHUB_STEP_SUMMARY}"
|
||||
|
||||
for filename in "${upload_dir}"/*.xz; do
|
||||
filename=$(basename "${filename}")
|
||||
echo "- [${filename}](${access_url}/${filename})" >> "${GITHUB_STEP_SUMMARY}"
|
||||
done
|
||||
fi
|
||||
fi
|
||||
|
@ -154,6 +154,7 @@ Some examples of `X` in `ignore-X` or `only-X`:
|
||||
`ignore-coverage-map`, `ignore-coverage-run`
|
||||
- When testing a dist toolchain: `dist`
|
||||
- This needs to be enabled with `COMPILETEST_ENABLE_DIST_TESTS=1`
|
||||
- The `rustc_abi` of the target: e.g. `rustc_abi-x86_64-sse2`
|
||||
|
||||
The following directives will check rustc build settings and target
|
||||
settings:
|
||||
|
@ -2039,7 +2039,10 @@ function preLoadCss(cssUrl) {
|
||||
// Most page titles are '<Item> in <path::to::module> - Rust', except
|
||||
// modules (which don't have the first part) and keywords/primitives
|
||||
// (which don't have a module path)
|
||||
const [item, module] = document.title.split(" in ");
|
||||
const titleElement = document.querySelector("title");
|
||||
const title = titleElement && titleElement.textContent ?
|
||||
titleElement.textContent.replace(" - Rust", "") : "";
|
||||
const [item, module] = title.split(" in ");
|
||||
const path = [item];
|
||||
if (module !== undefined) {
|
||||
path.unshift(module);
|
||||
|
@ -5318,8 +5318,9 @@ function registerSearchEvents() {
|
||||
|
||||
// @ts-expect-error
|
||||
searchState.input.addEventListener("blur", () => {
|
||||
// @ts-expect-error
|
||||
searchState.input.placeholder = searchState.input.origPlaceholder;
|
||||
if (window.searchState.input) {
|
||||
window.searchState.input.placeholder = window.searchState.origPlaceholder;
|
||||
}
|
||||
});
|
||||
|
||||
// Push and pop states are used to add search results to the browser
|
||||
|
@ -517,6 +517,7 @@ pub struct TargetCfgs {
|
||||
pub all_abis: HashSet<String>,
|
||||
pub all_families: HashSet<String>,
|
||||
pub all_pointer_widths: HashSet<String>,
|
||||
pub all_rustc_abis: HashSet<String>,
|
||||
}
|
||||
|
||||
impl TargetCfgs {
|
||||
@ -536,6 +537,9 @@ impl TargetCfgs {
|
||||
let mut all_abis = HashSet::new();
|
||||
let mut all_families = HashSet::new();
|
||||
let mut all_pointer_widths = HashSet::new();
|
||||
// NOTE: for distinction between `abi` and `rustc_abi`, see comment on
|
||||
// `TargetCfg::rustc_abi`.
|
||||
let mut all_rustc_abis = HashSet::new();
|
||||
|
||||
// If current target is not included in the `--print=all-target-specs-json` output,
|
||||
// we check whether it is a custom target from the user or a synthetic target from bootstrap.
|
||||
@ -576,7 +580,9 @@ impl TargetCfgs {
|
||||
all_families.insert(family.clone());
|
||||
}
|
||||
all_pointer_widths.insert(format!("{}bit", cfg.pointer_width));
|
||||
|
||||
if let Some(rustc_abi) = &cfg.rustc_abi {
|
||||
all_rustc_abis.insert(rustc_abi.clone());
|
||||
}
|
||||
all_targets.insert(target.clone());
|
||||
}
|
||||
|
||||
@ -590,6 +596,7 @@ impl TargetCfgs {
|
||||
all_abis,
|
||||
all_families,
|
||||
all_pointer_widths,
|
||||
all_rustc_abis,
|
||||
}
|
||||
}
|
||||
|
||||
@ -676,6 +683,10 @@ pub struct TargetCfg {
|
||||
pub(crate) xray: bool,
|
||||
#[serde(default = "default_reloc_model")]
|
||||
pub(crate) relocation_model: String,
|
||||
// NOTE: `rustc_abi` should not be confused with `abi`. `rustc_abi` was introduced in #137037 to
|
||||
// make SSE2 *required* by the ABI (kind of a hack to make a target feature *required* via the
|
||||
// target spec).
|
||||
pub(crate) rustc_abi: Option<String>,
|
||||
|
||||
// Not present in target cfg json output, additional derived information.
|
||||
#[serde(skip)]
|
||||
|
@ -87,6 +87,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
|
||||
"ignore-remote",
|
||||
"ignore-riscv64",
|
||||
"ignore-rustc-debug-assertions",
|
||||
"ignore-rustc_abi-x86-sse2",
|
||||
"ignore-s390x",
|
||||
"ignore-sgx",
|
||||
"ignore-sparc64",
|
||||
@ -198,6 +199,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
|
||||
"only-nvptx64",
|
||||
"only-powerpc",
|
||||
"only-riscv64",
|
||||
"only-rustc_abi-x86-sse2",
|
||||
"only-s390x",
|
||||
"only-sparc",
|
||||
"only-sparc64",
|
||||
|
@ -234,6 +234,14 @@ fn parse_cfg_name_directive<'a>(
|
||||
allowed_names: ["coverage-map", "coverage-run"],
|
||||
message: "when the test mode is {name}",
|
||||
}
|
||||
condition! {
|
||||
name: target_cfg.rustc_abi.as_ref().map(|abi| format!("rustc_abi-{abi}")).unwrap_or_default(),
|
||||
allowed_names: ContainsPrefixed {
|
||||
prefix: "rustc_abi-",
|
||||
inner: target_cfgs.all_rustc_abis.clone(),
|
||||
},
|
||||
message: "when the target `rustc_abi` is {name}",
|
||||
}
|
||||
|
||||
condition! {
|
||||
name: "dist",
|
||||
|
@ -889,3 +889,17 @@ fn test_needs_target_has_atomic() {
|
||||
assert!(!check_ignore(&config, "//@ needs-target-has-atomic: 8, ptr"));
|
||||
assert!(check_ignore(&config, "//@ needs-target-has-atomic: 8, ptr, 128"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
// FIXME: this test will fail against stage 0 until #137037 changes reach beta.
|
||||
#[cfg_attr(bootstrap, ignore)]
|
||||
fn test_rustc_abi() {
|
||||
let config = cfg().target("i686-unknown-linux-gnu").build();
|
||||
assert_eq!(config.target_cfg().rustc_abi, Some("x86-sse2".to_string()));
|
||||
assert!(check_ignore(&config, "//@ ignore-rustc_abi-x86-sse2"));
|
||||
assert!(!check_ignore(&config, "//@ only-rustc_abi-x86-sse2"));
|
||||
let config = cfg().target("x86_64-unknown-linux-gnu").build();
|
||||
assert_eq!(config.target_cfg().rustc_abi, None);
|
||||
assert!(!check_ignore(&config, "//@ ignore-rustc_abi-x86-sse2"));
|
||||
assert!(check_ignore(&config, "//@ only-rustc_abi-x86-sse2"));
|
||||
}
|
||||
|
6
tests/ui/attributes/crate-name-macro-call.rs
Normal file
6
tests/ui/attributes/crate-name-macro-call.rs
Normal file
@ -0,0 +1,6 @@
|
||||
// issue: rust-lang/rust#122001
|
||||
// Ensure we reject macro calls inside `#![crate_name]` as their result wouldn't get honored anyway.
|
||||
|
||||
#![crate_name = concat!("my", "crate")] //~ ERROR malformed `crate_name` attribute input
|
||||
|
||||
fn main() {}
|
8
tests/ui/attributes/crate-name-macro-call.stderr
Normal file
8
tests/ui/attributes/crate-name-macro-call.stderr
Normal file
@ -0,0 +1,8 @@
|
||||
error: malformed `crate_name` attribute input
|
||||
--> $DIR/crate-name-macro-call.rs:4:1
|
||||
|
|
||||
LL | #![crate_name = concat!("my", "crate")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#![crate_name = "name"]`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
@ -1,5 +1,5 @@
|
||||
error: malformed `crate_type` attribute input
|
||||
--> $DIR/invalid_crate_type_syntax.rs:2:1
|
||||
--> $DIR/crate-type-delimited.rs:2:1
|
||||
|
|
||||
LL | #![crate_type(lib)]
|
||||
| ^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#![crate_type = "bin|lib|..."]`
|
@ -1,5 +1,5 @@
|
||||
error: malformed `crate_type` attribute input
|
||||
--> $DIR/no_crate_type.rs:2:1
|
||||
--> $DIR/crate-type-empty.rs:2:1
|
||||
|
|
||||
LL | #![crate_type]
|
||||
| ^^^^^^^^^^^^^^ help: must be of the form: `#![crate_type = "bin|lib|..."]`
|
@ -1,5 +1,5 @@
|
||||
error: malformed `crate_type` attribute input
|
||||
--> $DIR/invalid-crate-type-macro.rs:1:1
|
||||
--> $DIR/crate-type-macro-call.rs:1:1
|
||||
|
|
||||
LL | #![crate_type = foo!()]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#![crate_type = "bin|lib|..."]`
|
@ -1,6 +0,0 @@
|
||||
error: invalid character `'$'` in crate name: `need_crate_arg_ignore_tidy$x`
|
||||
|
|
||||
= help: you can either pass `--crate-name` on the command line or add `#![crate_name="…"]` to set the crate name
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
@ -1,8 +1,6 @@
|
||||
error: path separator must be a double colon
|
||||
--> $DIR/single-colon-path-not-const-generics.rs:8:18
|
||||
|
|
||||
LL | pub struct Foo {
|
||||
| --- while parsing this struct
|
||||
LL | a: Vec<foo::bar:A>,
|
||||
| ^
|
||||
|
|
||||
@ -10,7 +8,7 @@ LL | a: Vec<foo::bar:A>,
|
||||
help: use a double colon instead
|
||||
|
|
||||
LL | a: Vec<foo::bar::A>,
|
||||
| +
|
||||
| +
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
@ -0,0 +1,6 @@
|
||||
error: invalid character '$' in crate name: `need_crate_arg_ignore_tidy$x`
|
||||
|
|
||||
= help: you can either pass `--crate-name` on the command line or add `#![crate_name = "…"]` to set the crate name
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
@ -0,0 +1,5 @@
|
||||
// Ensure we validate `#![crate_name]` on print requests and reject macro calls inside of it.
|
||||
// See also <https://github.com/rust-lang/rust/issues/122001>.
|
||||
|
||||
//@ compile-flags: --print=crate-name
|
||||
#![crate_name = concat!("wrapped")] //~ ERROR malformed `crate_name` attribute input
|
@ -0,0 +1,8 @@
|
||||
error: malformed `crate_name` attribute input
|
||||
--> $DIR/print-crate-name-request-malformed-crate-name.rs:5:1
|
||||
|
|
||||
LL | #![crate_name = concat!("wrapped")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#![crate_name = "name"]`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
@ -0,0 +1,4 @@
|
||||
// Ensure we validate `#![crate_name]` on print requests.
|
||||
|
||||
//@ compile-flags: --print=file-names
|
||||
#![crate_name] //~ ERROR malformed `crate_name` attribute input
|
@ -0,0 +1,8 @@
|
||||
error: malformed `crate_name` attribute input
|
||||
--> $DIR/print-file-names-request-malformed-crate-name-1.rs:4:1
|
||||
|
|
||||
LL | #![crate_name]
|
||||
| ^^^^^^^^^^^^^^ help: must be of the form: `#![crate_name = "name"]`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
@ -0,0 +1,7 @@
|
||||
// Ensure that we validate *all* `#![crate_name]`s on print requests, not just the first,
|
||||
// and that we reject macro calls inside of them.
|
||||
// See also <https://github.com/rust-lang/rust/issues/122001>.
|
||||
|
||||
//@ compile-flags: --print=file-names
|
||||
#![crate_name = "this_one_is_okay"]
|
||||
#![crate_name = concat!("this_one_is_not")] //~ ERROR malformed `crate_name` attribute input
|
@ -0,0 +1,8 @@
|
||||
error: malformed `crate_name` attribute input
|
||||
--> $DIR/print-file-names-request-malformed-crate-name-2.rs:7:1
|
||||
|
|
||||
LL | #![crate_name = concat!("this_one_is_not")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#![crate_name = "name"]`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
@ -0,0 +1,5 @@
|
||||
// Ensure we validate `#![crate_name]` on print requests and reject macro calls inside of it.
|
||||
// See also <https://github.com/rust-lang/rust/issues/122001>.
|
||||
|
||||
//@ compile-flags: --print=file-names
|
||||
#![crate_name = concat!("wrapped")] //~ ERROR malformed `crate_name` attribute input
|
@ -0,0 +1,8 @@
|
||||
error: malformed `crate_name` attribute input
|
||||
--> $DIR/print-file-names-request-malformed-crate-name.rs:5:1
|
||||
|
|
||||
LL | #![crate_name = concat!("wrapped")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#![crate_name = "name"]`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
8
tests/ui/parser/attribute/attr-pat-struct-rest.rs
Normal file
8
tests/ui/parser/attribute/attr-pat-struct-rest.rs
Normal file
@ -0,0 +1,8 @@
|
||||
// #81282: Attributes are not allowed on struct field rest patterns (the ..).
|
||||
|
||||
struct S {}
|
||||
|
||||
fn main() {
|
||||
let S { #[cfg(any())] .. } = S {};
|
||||
//~^ ERROR expected identifier, found `..`
|
||||
}
|
10
tests/ui/parser/attribute/attr-pat-struct-rest.stderr
Normal file
10
tests/ui/parser/attribute/attr-pat-struct-rest.stderr
Normal file
@ -0,0 +1,10 @@
|
||||
error: expected identifier, found `..`
|
||||
--> $DIR/attr-pat-struct-rest.rs:6:27
|
||||
|
|
||||
LL | let S { #[cfg(any())] .. } = S {};
|
||||
| - ^^ expected identifier
|
||||
| |
|
||||
| while parsing the fields for this pattern
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
@ -0,0 +1,15 @@
|
||||
//@ run-rustfix
|
||||
|
||||
use std::fmt;
|
||||
|
||||
struct Hello;
|
||||
|
||||
impl fmt::Display for Hello {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { //~ ERROR path separator must be a double colon
|
||||
write!(f, "hello")
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let _ = Hello;
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
//@ run-rustfix
|
||||
|
||||
use std::fmt;
|
||||
|
||||
struct Hello;
|
||||
|
||||
impl fmt::Display for Hello {
|
||||
fn fmt(&self, f: &mut fmt:Formatter) -> fmt::Result { //~ ERROR path separator must be a double colon
|
||||
write!(f, "hello")
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let _ = Hello;
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
error: path separator must be a double colon
|
||||
--> $DIR/argument-list-from-path-sep-error-129273.rs:8:30
|
||||
|
|
||||
LL | fn fmt(&self, f: &mut fmt:Formatter) -> fmt::Result {
|
||||
| ^
|
||||
|
|
||||
= note: if you meant to annotate an expression with a type, the type ascription syntax has been removed, see issue #101728 <https://github.com/rust-lang/rust/issues/101728>
|
||||
help: use a double colon instead
|
||||
|
|
||||
LL | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
| +
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
@ -7,14 +7,14 @@ mod foo {
|
||||
|
||||
struct Foo {
|
||||
a: foo:A,
|
||||
//~^ ERROR found single colon in a struct field type path
|
||||
//~| expected `,`, or `}`, found `:`
|
||||
//~^ ERROR path separator must be a double colon
|
||||
//~| ERROR struct `A` is private
|
||||
}
|
||||
|
||||
struct Bar {
|
||||
b: foo::bar:B,
|
||||
//~^ ERROR found single colon in a struct field type path
|
||||
//~| expected `,`, or `}`, found `:`
|
||||
//~^ ERROR path separator must be a double colon
|
||||
//~| ERROR module `bar` is private
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,40 +1,53 @@
|
||||
error: found single colon in a struct field type path
|
||||
error: path separator must be a double colon
|
||||
--> $DIR/struct-field-type-including-single-colon.rs:9:11
|
||||
|
|
||||
LL | a: foo:A,
|
||||
| ^
|
||||
|
|
||||
help: write a path separator here
|
||||
= note: if you meant to annotate an expression with a type, the type ascription syntax has been removed, see issue #101728 <https://github.com/rust-lang/rust/issues/101728>
|
||||
help: use a double colon instead
|
||||
|
|
||||
LL | a: foo::A,
|
||||
| +
|
||||
|
||||
error: expected `,`, or `}`, found `:`
|
||||
--> $DIR/struct-field-type-including-single-colon.rs:9:11
|
||||
|
|
||||
LL | struct Foo {
|
||||
| --- while parsing this struct
|
||||
LL | a: foo:A,
|
||||
| ^
|
||||
|
||||
error: found single colon in a struct field type path
|
||||
error: path separator must be a double colon
|
||||
--> $DIR/struct-field-type-including-single-colon.rs:15:16
|
||||
|
|
||||
LL | b: foo::bar:B,
|
||||
| ^
|
||||
|
|
||||
help: write a path separator here
|
||||
= note: if you meant to annotate an expression with a type, the type ascription syntax has been removed, see issue #101728 <https://github.com/rust-lang/rust/issues/101728>
|
||||
help: use a double colon instead
|
||||
|
|
||||
LL | b: foo::bar::B,
|
||||
| +
|
||||
|
||||
error: expected `,`, or `}`, found `:`
|
||||
--> $DIR/struct-field-type-including-single-colon.rs:15:16
|
||||
error[E0603]: struct `A` is private
|
||||
--> $DIR/struct-field-type-including-single-colon.rs:9:12
|
||||
|
|
||||
LL | a: foo:A,
|
||||
| ^ private struct
|
||||
|
|
||||
note: the struct `A` is defined here
|
||||
--> $DIR/struct-field-type-including-single-colon.rs:2:5
|
||||
|
|
||||
LL | struct A;
|
||||
| ^^^^^^^^^
|
||||
|
||||
error[E0603]: module `bar` is private
|
||||
--> $DIR/struct-field-type-including-single-colon.rs:15:13
|
||||
|
|
||||
LL | struct Bar {
|
||||
| --- while parsing this struct
|
||||
LL | b: foo::bar:B,
|
||||
| ^
|
||||
| ^^^ - struct `B` is not publicly re-exported
|
||||
| |
|
||||
| private module
|
||||
|
|
||||
note: the module `bar` is defined here
|
||||
--> $DIR/struct-field-type-including-single-colon.rs:3:5
|
||||
|
|
||||
LL | mod bar {
|
||||
| ^^^^^^^
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0603`.
|
||||
|
@ -962,6 +962,9 @@ message = "This PR changes how LLVM is built. Consider updating src/bootstrap/do
|
||||
[mentions."test/crashes"]
|
||||
message = "This PR changes a file inside `tests/crashes`. If a crash was fixed, please move into the corresponding `ui` subdir and add 'Fixes #<issueNr>' to the PR description to autoclose the issue upon merge."
|
||||
|
||||
[mentions."tests/rustdoc-json"]
|
||||
cc = ["@aDotInTheVoid"]
|
||||
|
||||
[mentions."tests/ui/deriving/deriving-all-codegen.stdout"]
|
||||
message = "Changes to the code generated for builtin derived traits."
|
||||
cc = ["@nnethercote"]
|
||||
|
Loading…
Reference in New Issue
Block a user