Auto merge of #121636 - matthiaskrgr:rollup-1tt2o5n, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - #121389 (llvm-wrapper: fix few warnings) - #121493 (By changing some attributes to only_local, reducing encoding attributes in the crate metadate.) - #121615 (Move `emit_stashed_diagnostic` call in rustfmt.) - #121617 (Actually use the right closure kind when checking async Fn goals) - #121628 (Do not const prop unions) - #121629 (fix some references to no-longer-existing ReprOptions.layout_seed) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
829308e9af
@ -958,7 +958,7 @@ fn univariant<
|
|||||||
#[cfg(feature = "randomize")]
|
#[cfg(feature = "randomize")]
|
||||||
{
|
{
|
||||||
use rand::{seq::SliceRandom, SeedableRng};
|
use rand::{seq::SliceRandom, SeedableRng};
|
||||||
// `ReprOptions.layout_seed` is a deterministic seed we can use to randomize field
|
// `ReprOptions.field_shuffle_seed` is a deterministic seed we can use to randomize field
|
||||||
// ordering.
|
// ordering.
|
||||||
let mut rng =
|
let mut rng =
|
||||||
rand_xoshiro::Xoshiro128StarStar::seed_from_u64(repr.field_shuffle_seed);
|
rand_xoshiro::Xoshiro128StarStar::seed_from_u64(repr.field_shuffle_seed);
|
||||||
|
@ -41,7 +41,7 @@ bitflags! {
|
|||||||
// Internal only for now. If true, don't reorder fields.
|
// Internal only for now. If true, don't reorder fields.
|
||||||
const IS_LINEAR = 1 << 3;
|
const IS_LINEAR = 1 << 3;
|
||||||
// If true, the type's layout can be randomized using
|
// If true, the type's layout can be randomized using
|
||||||
// the seed stored in `ReprOptions.layout_seed`
|
// the seed stored in `ReprOptions.field_shuffle_seed`
|
||||||
const RANDOMIZE_LAYOUT = 1 << 4;
|
const RANDOMIZE_LAYOUT = 1 << 4;
|
||||||
// Any of these flags being set prevent field reordering optimisation.
|
// Any of these flags being set prevent field reordering optimisation.
|
||||||
const IS_UNOPTIMISABLE = ReprFlags::IS_C.bits()
|
const IS_UNOPTIMISABLE = ReprFlags::IS_C.bits()
|
||||||
|
@ -36,7 +36,7 @@ use rustc_span::InnerSpan;
|
|||||||
use rustc_target::spec::{CodeModel, RelocModel, SanitizerSet, SplitDebuginfo, TlsModel};
|
use rustc_target::spec::{CodeModel, RelocModel, SanitizerSet, SplitDebuginfo, TlsModel};
|
||||||
|
|
||||||
use crate::llvm::diagnostic::OptimizationDiagnosticKind;
|
use crate::llvm::diagnostic::OptimizationDiagnosticKind;
|
||||||
use libc::{c_char, c_int, c_uint, c_void, size_t};
|
use libc::{c_char, c_int, c_void, size_t};
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::io::{self, Write};
|
use std::io::{self, Write};
|
||||||
@ -406,7 +406,7 @@ fn report_inline_asm(
|
|||||||
cgcx: &CodegenContext<LlvmCodegenBackend>,
|
cgcx: &CodegenContext<LlvmCodegenBackend>,
|
||||||
msg: String,
|
msg: String,
|
||||||
level: llvm::DiagnosticLevel,
|
level: llvm::DiagnosticLevel,
|
||||||
mut cookie: c_uint,
|
mut cookie: u64,
|
||||||
source: Option<(String, Vec<InnerSpan>)>,
|
source: Option<(String, Vec<InnerSpan>)>,
|
||||||
) {
|
) {
|
||||||
// In LTO build we may get srcloc values from other crates which are invalid
|
// In LTO build we may get srcloc values from other crates which are invalid
|
||||||
@ -420,7 +420,7 @@ fn report_inline_asm(
|
|||||||
llvm::DiagnosticLevel::Warning => Level::Warning,
|
llvm::DiagnosticLevel::Warning => Level::Warning,
|
||||||
llvm::DiagnosticLevel::Note | llvm::DiagnosticLevel::Remark => Level::Note,
|
llvm::DiagnosticLevel::Note | llvm::DiagnosticLevel::Remark => Level::Note,
|
||||||
};
|
};
|
||||||
cgcx.diag_emitter.inline_asm_error(cookie as u32, msg, level, source);
|
cgcx.diag_emitter.inline_asm_error(cookie.try_into().unwrap(), msg, level, source);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe extern "C" fn diagnostic_handler(info: &DiagnosticInfo, user: *mut c_void) {
|
unsafe extern "C" fn diagnostic_handler(info: &DiagnosticInfo, user: *mut c_void) {
|
||||||
|
@ -123,7 +123,7 @@ impl SrcMgrDiagnostic {
|
|||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct InlineAsmDiagnostic {
|
pub struct InlineAsmDiagnostic {
|
||||||
pub level: super::DiagnosticLevel,
|
pub level: super::DiagnosticLevel,
|
||||||
pub cookie: c_uint,
|
pub cookie: u64,
|
||||||
pub message: String,
|
pub message: String,
|
||||||
pub source: Option<(String, Vec<InnerSpan>)>,
|
pub source: Option<(String, Vec<InnerSpan>)>,
|
||||||
}
|
}
|
||||||
@ -149,7 +149,7 @@ impl InlineAsmDiagnostic {
|
|||||||
let smdiag = SrcMgrDiagnostic::unpack(super::LLVMRustGetSMDiagnostic(di, &mut cookie));
|
let smdiag = SrcMgrDiagnostic::unpack(super::LLVMRustGetSMDiagnostic(di, &mut cookie));
|
||||||
InlineAsmDiagnostic {
|
InlineAsmDiagnostic {
|
||||||
level: smdiag.level,
|
level: smdiag.level,
|
||||||
cookie,
|
cookie: cookie.into(),
|
||||||
message: smdiag.message,
|
message: smdiag.message,
|
||||||
source: smdiag.source,
|
source: smdiag.source,
|
||||||
}
|
}
|
||||||
|
@ -2256,7 +2256,7 @@ extern "C" {
|
|||||||
pub fn LLVMRustUnpackInlineAsmDiagnostic<'a>(
|
pub fn LLVMRustUnpackInlineAsmDiagnostic<'a>(
|
||||||
DI: &'a DiagnosticInfo,
|
DI: &'a DiagnosticInfo,
|
||||||
level_out: &mut DiagnosticLevel,
|
level_out: &mut DiagnosticLevel,
|
||||||
cookie_out: &mut c_uint,
|
cookie_out: &mut u64,
|
||||||
message_out: &mut Option<&'a Twine>,
|
message_out: &mut Option<&'a Twine>,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -277,25 +277,35 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
|
|||||||
ungated!(cfg_attr, Normal, template!(List: "predicate, attr1, attr2, ..."), DuplicatesOk),
|
ungated!(cfg_attr, Normal, template!(List: "predicate, attr1, attr2, ..."), DuplicatesOk),
|
||||||
|
|
||||||
// Testing:
|
// Testing:
|
||||||
ungated!(ignore, Normal, template!(Word, NameValueStr: "reason"), WarnFollowing),
|
ungated!(
|
||||||
|
ignore, Normal, template!(Word, NameValueStr: "reason"), WarnFollowing,
|
||||||
|
@only_local: true,
|
||||||
|
),
|
||||||
ungated!(
|
ungated!(
|
||||||
should_panic, Normal,
|
should_panic, Normal,
|
||||||
template!(Word, List: r#"expected = "reason""#, NameValueStr: "reason"), FutureWarnFollowing,
|
template!(Word, List: r#"expected = "reason""#, NameValueStr: "reason"), FutureWarnFollowing,
|
||||||
|
@only_local: true,
|
||||||
),
|
),
|
||||||
// FIXME(Centril): This can be used on stable but shouldn't.
|
// FIXME(Centril): This can be used on stable but shouldn't.
|
||||||
ungated!(reexport_test_harness_main, CrateLevel, template!(NameValueStr: "name"), ErrorFollowing),
|
ungated!(
|
||||||
|
reexport_test_harness_main, CrateLevel, template!(NameValueStr: "name"), ErrorFollowing,
|
||||||
|
@only_local: true,
|
||||||
|
),
|
||||||
|
|
||||||
// Macros:
|
// Macros:
|
||||||
ungated!(automatically_derived, Normal, template!(Word), WarnFollowing),
|
ungated!(automatically_derived, Normal, template!(Word), WarnFollowing),
|
||||||
ungated!(macro_use, Normal, template!(Word, List: "name1, name2, ..."), WarnFollowingWordOnly),
|
|
||||||
ungated!(macro_escape, Normal, template!(Word), WarnFollowing), // Deprecated synonym for `macro_use`.
|
|
||||||
ungated!(macro_export, Normal, template!(Word, List: "local_inner_macros"), WarnFollowing),
|
|
||||||
ungated!(proc_macro, Normal, template!(Word), ErrorFollowing),
|
|
||||||
ungated!(
|
ungated!(
|
||||||
proc_macro_derive, Normal,
|
macro_use, Normal, template!(Word, List: "name1, name2, ..."), WarnFollowingWordOnly,
|
||||||
template!(List: "TraitName, /*opt*/ attributes(name1, name2, ...)"), ErrorFollowing,
|
@only_local: true,
|
||||||
),
|
),
|
||||||
ungated!(proc_macro_attribute, Normal, template!(Word), ErrorFollowing),
|
ungated!(macro_escape, Normal, template!(Word), WarnFollowing, @only_local: true), // Deprecated synonym for `macro_use`.
|
||||||
|
ungated!(macro_export, Normal, template!(Word, List: "local_inner_macros"), WarnFollowing),
|
||||||
|
ungated!(proc_macro, Normal, template!(Word), ErrorFollowing, @only_local: true),
|
||||||
|
ungated!(
|
||||||
|
proc_macro_derive, Normal, template!(List: "TraitName, /*opt*/ attributes(name1, name2, ...)"),
|
||||||
|
ErrorFollowing, @only_local: true,
|
||||||
|
),
|
||||||
|
ungated!(proc_macro_attribute, Normal, template!(Word), ErrorFollowing, @only_local: true),
|
||||||
|
|
||||||
// Lints:
|
// Lints:
|
||||||
ungated!(
|
ungated!(
|
||||||
@ -308,7 +318,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
|
|||||||
),
|
),
|
||||||
gated!(
|
gated!(
|
||||||
expect, Normal, template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#), DuplicatesOk,
|
expect, Normal, template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#), DuplicatesOk,
|
||||||
lint_reasons, experimental!(expect)
|
@only_local: true, lint_reasons, experimental!(expect)
|
||||||
),
|
),
|
||||||
ungated!(
|
ungated!(
|
||||||
forbid, Normal, template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#),
|
forbid, Normal, template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#),
|
||||||
@ -334,32 +344,48 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
|
|||||||
),
|
),
|
||||||
|
|
||||||
// Crate properties:
|
// Crate properties:
|
||||||
ungated!(crate_name, CrateLevel, template!(NameValueStr: "name"), FutureWarnFollowing),
|
ungated!(
|
||||||
ungated!(crate_type, CrateLevel, template!(NameValueStr: "bin|lib|..."), DuplicatesOk),
|
crate_name, CrateLevel, template!(NameValueStr: "name"), FutureWarnFollowing,
|
||||||
|
@only_local: true,
|
||||||
|
),
|
||||||
|
ungated!(
|
||||||
|
crate_type, CrateLevel, template!(NameValueStr: "bin|lib|..."), DuplicatesOk,
|
||||||
|
@only_local: true,
|
||||||
|
),
|
||||||
// crate_id is deprecated
|
// crate_id is deprecated
|
||||||
ungated!(crate_id, CrateLevel, template!(NameValueStr: "ignored"), FutureWarnFollowing),
|
ungated!(
|
||||||
|
crate_id, CrateLevel, template!(NameValueStr: "ignored"), FutureWarnFollowing,
|
||||||
|
@only_local: true,
|
||||||
|
),
|
||||||
|
|
||||||
// ABI, linking, symbols, and FFI
|
// ABI, linking, symbols, and FFI
|
||||||
ungated!(
|
ungated!(
|
||||||
link, Normal,
|
link, Normal,
|
||||||
template!(List: r#"name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...", /*opt*/ import_name_type = "decorated|noprefix|undecorated""#),
|
template!(List: r#"name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...", /*opt*/ import_name_type = "decorated|noprefix|undecorated""#),
|
||||||
DuplicatesOk,
|
DuplicatesOk,
|
||||||
|
@only_local: true,
|
||||||
),
|
),
|
||||||
ungated!(link_name, Normal, template!(NameValueStr: "name"), FutureWarnPreceding),
|
ungated!(link_name, Normal, template!(NameValueStr: "name"), FutureWarnPreceding),
|
||||||
ungated!(no_link, Normal, template!(Word), WarnFollowing),
|
ungated!(no_link, Normal, template!(Word), WarnFollowing, @only_local: true),
|
||||||
ungated!(repr, Normal, template!(List: "C"), DuplicatesOk, @only_local: true),
|
ungated!(repr, Normal, template!(List: "C"), DuplicatesOk, @only_local: true),
|
||||||
ungated!(export_name, Normal, template!(NameValueStr: "name"), FutureWarnPreceding),
|
ungated!(export_name, Normal, template!(NameValueStr: "name"), FutureWarnPreceding, @only_local: true),
|
||||||
ungated!(link_section, Normal, template!(NameValueStr: "name"), FutureWarnPreceding),
|
ungated!(link_section, Normal, template!(NameValueStr: "name"), FutureWarnPreceding, @only_local: true),
|
||||||
ungated!(no_mangle, Normal, template!(Word), WarnFollowing, @only_local: true),
|
ungated!(no_mangle, Normal, template!(Word), WarnFollowing, @only_local: true),
|
||||||
ungated!(used, Normal, template!(Word, List: "compiler|linker"), WarnFollowing, @only_local: true),
|
ungated!(used, Normal, template!(Word, List: "compiler|linker"), WarnFollowing, @only_local: true),
|
||||||
ungated!(link_ordinal, Normal, template!(List: "ordinal"), ErrorPreceding),
|
ungated!(link_ordinal, Normal, template!(List: "ordinal"), ErrorPreceding),
|
||||||
|
|
||||||
// Limits:
|
// Limits:
|
||||||
ungated!(recursion_limit, CrateLevel, template!(NameValueStr: "N"), FutureWarnFollowing),
|
ungated!(
|
||||||
ungated!(type_length_limit, CrateLevel, template!(NameValueStr: "N"), FutureWarnFollowing),
|
recursion_limit, CrateLevel, template!(NameValueStr: "N"), FutureWarnFollowing,
|
||||||
|
@only_local: true
|
||||||
|
),
|
||||||
|
ungated!(
|
||||||
|
type_length_limit, CrateLevel, template!(NameValueStr: "N"), FutureWarnFollowing,
|
||||||
|
@only_local: true
|
||||||
|
),
|
||||||
gated!(
|
gated!(
|
||||||
move_size_limit, CrateLevel, template!(NameValueStr: "N"), ErrorFollowing,
|
move_size_limit, CrateLevel, template!(NameValueStr: "N"), ErrorFollowing,
|
||||||
large_assignments, experimental!(move_size_limit)
|
@only_local: true, large_assignments, experimental!(move_size_limit)
|
||||||
),
|
),
|
||||||
|
|
||||||
// Entry point:
|
// Entry point:
|
||||||
|
@ -67,7 +67,7 @@ typedef RustArchiveIterator *LLVMRustArchiveIteratorRef;
|
|||||||
|
|
||||||
extern "C" LLVMRustArchiveRef LLVMRustOpenArchive(char *Path) {
|
extern "C" LLVMRustArchiveRef LLVMRustOpenArchive(char *Path) {
|
||||||
ErrorOr<std::unique_ptr<MemoryBuffer>> BufOr =
|
ErrorOr<std::unique_ptr<MemoryBuffer>> BufOr =
|
||||||
MemoryBuffer::getFile(Path, -1, false);
|
MemoryBuffer::getFile(Path, /*IsText*/false, /*RequiresNullTerminator=*/false);
|
||||||
if (!BufOr) {
|
if (!BufOr) {
|
||||||
LLVMRustSetLastError(BufOr.getError().message().c_str());
|
LLVMRustSetLastError(BufOr.getError().message().c_str());
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -1262,7 +1262,7 @@ enum class LLVMRustDiagnosticLevel {
|
|||||||
extern "C" void
|
extern "C" void
|
||||||
LLVMRustUnpackInlineAsmDiagnostic(LLVMDiagnosticInfoRef DI,
|
LLVMRustUnpackInlineAsmDiagnostic(LLVMDiagnosticInfoRef DI,
|
||||||
LLVMRustDiagnosticLevel *LevelOut,
|
LLVMRustDiagnosticLevel *LevelOut,
|
||||||
unsigned *CookieOut,
|
uint64_t *CookieOut,
|
||||||
LLVMTwineRef *MessageOut) {
|
LLVMTwineRef *MessageOut) {
|
||||||
// Undefined to call this not on an inline assembly diagnostic!
|
// Undefined to call this not on an inline assembly diagnostic!
|
||||||
llvm::DiagnosticInfoInlineAsm *IA =
|
llvm::DiagnosticInfoInlineAsm *IA =
|
||||||
|
@ -585,20 +585,32 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
|
|||||||
val.into()
|
val.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
Aggregate(ref kind, ref fields) => Value::Aggregate {
|
Aggregate(ref kind, ref fields) => {
|
||||||
fields: fields
|
// Do not const pop union fields as they can be
|
||||||
.iter()
|
// made to produce values that don't match their
|
||||||
.map(|field| self.eval_operand(field).map_or(Value::Uninit, Value::Immediate))
|
// underlying layout's type (see ICE #121534).
|
||||||
.collect(),
|
// If the last element of the `Adt` tuple
|
||||||
variant: match **kind {
|
// is `Some` it indicates the ADT is a union
|
||||||
AggregateKind::Adt(_, variant, _, _, _) => variant,
|
if let AggregateKind::Adt(_, _, _, _, Some(_)) = **kind {
|
||||||
AggregateKind::Array(_)
|
return None;
|
||||||
| AggregateKind::Tuple
|
};
|
||||||
| AggregateKind::Closure(_, _)
|
Value::Aggregate {
|
||||||
| AggregateKind::Coroutine(_, _)
|
fields: fields
|
||||||
| AggregateKind::CoroutineClosure(_, _) => VariantIdx::new(0),
|
.iter()
|
||||||
},
|
.map(|field| {
|
||||||
},
|
self.eval_operand(field).map_or(Value::Uninit, Value::Immediate)
|
||||||
|
})
|
||||||
|
.collect(),
|
||||||
|
variant: match **kind {
|
||||||
|
AggregateKind::Adt(_, variant, _, _, _) => variant,
|
||||||
|
AggregateKind::Array(_)
|
||||||
|
| AggregateKind::Tuple
|
||||||
|
| AggregateKind::Closure(_, _)
|
||||||
|
| AggregateKind::Coroutine(_, _)
|
||||||
|
| AggregateKind::CoroutineClosure(_, _) => VariantIdx::new(0),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Repeat(ref op, n) => {
|
Repeat(ref op, n) => {
|
||||||
trace!(?op, ?n);
|
trace!(?op, ?n);
|
||||||
|
@ -934,7 +934,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
(trait_ref, Ty::from_closure_kind(tcx, ty::ClosureKind::Fn))
|
(trait_ref, Ty::from_closure_kind(tcx, ty::ClosureKind::Fn))
|
||||||
}
|
}
|
||||||
ty::Closure(_, args) => {
|
ty::Closure(_, args) => {
|
||||||
let sig = args.as_closure().sig();
|
let args = args.as_closure();
|
||||||
|
let sig = args.sig();
|
||||||
let trait_ref = sig.map_bound(|sig| {
|
let trait_ref = sig.map_bound(|sig| {
|
||||||
ty::TraitRef::new(
|
ty::TraitRef::new(
|
||||||
self.tcx(),
|
self.tcx(),
|
||||||
@ -950,7 +951,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
ty::TraitRef::new(tcx, future_trait_def_id, [sig.output()])
|
ty::TraitRef::new(tcx, future_trait_def_id, [sig.output()])
|
||||||
}),
|
}),
|
||||||
));
|
));
|
||||||
(trait_ref, Ty::from_closure_kind(tcx, ty::ClosureKind::Fn))
|
(trait_ref, args.kind_ty())
|
||||||
}
|
}
|
||||||
_ => bug!("expected callable type for AsyncFn candidate"),
|
_ => bug!("expected callable type for AsyncFn candidate"),
|
||||||
};
|
};
|
||||||
|
@ -109,7 +109,7 @@ fn format_project<T: FormatHandler>(
|
|||||||
let main_file = input.file_name();
|
let main_file = input.file_name();
|
||||||
let input_is_stdin = main_file == FileName::Stdin;
|
let input_is_stdin = main_file == FileName::Stdin;
|
||||||
|
|
||||||
let parse_session = ParseSess::new(config)?;
|
let mut parse_session = ParseSess::new(config)?;
|
||||||
if config.skip_children() && parse_session.ignore_file(&main_file) {
|
if config.skip_children() && parse_session.ignore_file(&main_file) {
|
||||||
return Ok(FormatReport::new());
|
return Ok(FormatReport::new());
|
||||||
}
|
}
|
||||||
@ -117,11 +117,21 @@ fn format_project<T: FormatHandler>(
|
|||||||
// Parse the crate.
|
// Parse the crate.
|
||||||
let mut report = FormatReport::new();
|
let mut report = FormatReport::new();
|
||||||
let directory_ownership = input.to_directory_ownership();
|
let directory_ownership = input.to_directory_ownership();
|
||||||
let krate = match Parser::parse_crate(input, &parse_session) {
|
|
||||||
Ok(krate) => krate,
|
// rustfmt doesn't use `run_compiler` like other tools, so it must emit any
|
||||||
// Surface parse error via Session (errors are merged there from report)
|
// stashed diagnostics itself, otherwise the `DiagCtxt` will assert when
|
||||||
Err(e) => {
|
// dropped. The final result here combines the parsing result and the
|
||||||
let forbid_verbose = input_is_stdin || e != ParserError::ParsePanicError;
|
// `emit_stashed_diagnostics` result.
|
||||||
|
let parse_res = Parser::parse_crate(input, &parse_session);
|
||||||
|
let stashed_res = parse_session.emit_stashed_diagnostics();
|
||||||
|
let krate = match (parse_res, stashed_res) {
|
||||||
|
(Ok(krate), None) => krate,
|
||||||
|
(parse_res, _) => {
|
||||||
|
// Surface parse error via Session (errors are merged there from report).
|
||||||
|
let forbid_verbose = match parse_res {
|
||||||
|
Err(e) if e != ParserError::ParsePanicError => true,
|
||||||
|
_ => input_is_stdin,
|
||||||
|
};
|
||||||
should_emit_verbose(forbid_verbose, config, || {
|
should_emit_verbose(forbid_verbose, config, || {
|
||||||
eprintln!("The Rust parser panicked");
|
eprintln!("The Rust parser panicked");
|
||||||
});
|
});
|
||||||
|
@ -162,22 +162,14 @@ impl<'a> Parser<'a> {
|
|||||||
|
|
||||||
fn parse_crate_mod(&mut self) -> Result<ast::Crate, ParserError> {
|
fn parse_crate_mod(&mut self) -> Result<ast::Crate, ParserError> {
|
||||||
let mut parser = AssertUnwindSafe(&mut self.parser);
|
let mut parser = AssertUnwindSafe(&mut self.parser);
|
||||||
|
|
||||||
// rustfmt doesn't use `run_compiler` like other tools, so it must emit
|
|
||||||
// any stashed diagnostics itself, otherwise the `DiagCtxt` will assert
|
|
||||||
// when dropped. The final result here combines the parsing result and
|
|
||||||
// the `emit_stashed_diagnostics` result.
|
|
||||||
let parse_res = catch_unwind(move || parser.parse_crate_mod());
|
|
||||||
let stashed_res = self.parser.dcx().emit_stashed_diagnostics();
|
|
||||||
let err = Err(ParserError::ParsePanicError);
|
let err = Err(ParserError::ParsePanicError);
|
||||||
match (parse_res, stashed_res) {
|
match catch_unwind(move || parser.parse_crate_mod()) {
|
||||||
(Ok(Ok(k)), None) => Ok(k),
|
Ok(Ok(k)) => Ok(k),
|
||||||
(Ok(Ok(_)), Some(_guar)) => err,
|
Ok(Err(db)) => {
|
||||||
(Ok(Err(db)), _) => {
|
|
||||||
db.emit();
|
db.emit();
|
||||||
err
|
err
|
||||||
}
|
}
|
||||||
(Err(_), _) => err,
|
Err(_) => err,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ use rustc_data_structures::sync::{IntoDynSyncSend, Lrc};
|
|||||||
use rustc_errors::emitter::{DynEmitter, Emitter, HumanEmitter};
|
use rustc_errors::emitter::{DynEmitter, Emitter, HumanEmitter};
|
||||||
use rustc_errors::translation::Translate;
|
use rustc_errors::translation::Translate;
|
||||||
use rustc_errors::{
|
use rustc_errors::{
|
||||||
ColorConfig, DiagCtxt, Diagnostic, DiagnosticBuilder, Level as DiagnosticLevel,
|
ColorConfig, DiagCtxt, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, Level as DiagnosticLevel,
|
||||||
};
|
};
|
||||||
use rustc_session::parse::ParseSess as RawParseSess;
|
use rustc_session::parse::ParseSess as RawParseSess;
|
||||||
use rustc_span::{
|
use rustc_span::{
|
||||||
@ -230,6 +230,10 @@ impl ParseSess {
|
|||||||
self.ignore_path_set.as_ref().is_match(path)
|
self.ignore_path_set.as_ref().is_match(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn emit_stashed_diagnostics(&mut self) -> Option<ErrorGuaranteed> {
|
||||||
|
self.parse_sess.dcx.emit_stashed_diagnostics()
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn set_silent_emitter(&mut self) {
|
pub(crate) fn set_silent_emitter(&mut self) {
|
||||||
self.parse_sess.dcx = DiagCtxt::with_emitter(silent_emitter());
|
self.parse_sess.dcx = DiagCtxt::with_emitter(silent_emitter());
|
||||||
}
|
}
|
||||||
|
@ -62,3 +62,10 @@ fn crate_parsing_stashed_diag() {
|
|||||||
let filename = "tests/parser/stashed-diag.rs";
|
let filename = "tests/parser/stashed-diag.rs";
|
||||||
assert_parser_error(filename);
|
assert_parser_error(filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn crate_parsing_stashed_diag2() {
|
||||||
|
// See also https://github.com/rust-lang/rust/issues/121517
|
||||||
|
let filename = "tests/parser/stashed-diag2.rs";
|
||||||
|
assert_parser_error(filename);
|
||||||
|
}
|
||||||
|
3
src/tools/rustfmt/tests/parser/stashed-diag2.rs
Normal file
3
src/tools/rustfmt/tests/parser/stashed-diag2.rs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
trait Trait<'1> { s> {}
|
||||||
|
|
||||||
|
fn main() {}
|
@ -1,7 +1,5 @@
|
|||||||
//@ edition:2021
|
//@ edition:2021
|
||||||
|
|
||||||
// FIXME(async_closures): This needs a better error message!
|
|
||||||
|
|
||||||
#![feature(async_closure)]
|
#![feature(async_closure)]
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
@ -12,4 +10,10 @@ fn main() {
|
|||||||
//~^ ERROR expected a closure that implements the `async Fn` trait, but this closure only implements `async FnMut`
|
//~^ ERROR expected a closure that implements the `async Fn` trait, but this closure only implements `async FnMut`
|
||||||
x += 1;
|
x += 1;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let x = String::new();
|
||||||
|
needs_async_fn(move || async move {
|
||||||
|
//~^ ERROR expected a closure that implements the `async Fn` trait, but this closure only implements `async FnOnce`
|
||||||
|
println!("{x}");
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
error[E0525]: expected a closure that implements the `async Fn` trait, but this closure only implements `async FnMut`
|
error[E0525]: expected a closure that implements the `async Fn` trait, but this closure only implements `async FnMut`
|
||||||
--> $DIR/wrong-fn-kind.rs:11:20
|
--> $DIR/wrong-fn-kind.rs:9:20
|
||||||
|
|
|
|
||||||
LL | needs_async_fn(async || {
|
LL | needs_async_fn(async || {
|
||||||
| -------------- -^^^^^^^
|
| -------------- -^^^^^^^
|
||||||
@ -14,11 +14,32 @@ LL | | });
|
|||||||
| |_____- the requirement to implement `async Fn` derives from here
|
| |_____- the requirement to implement `async Fn` derives from here
|
||||||
|
|
|
|
||||||
note: required by a bound in `needs_async_fn`
|
note: required by a bound in `needs_async_fn`
|
||||||
--> $DIR/wrong-fn-kind.rs:8:31
|
--> $DIR/wrong-fn-kind.rs:6:31
|
||||||
|
|
|
|
||||||
LL | fn needs_async_fn(_: impl async Fn()) {}
|
LL | fn needs_async_fn(_: impl async Fn()) {}
|
||||||
| ^^^^^^^^^^ required by this bound in `needs_async_fn`
|
| ^^^^^^^^^^ required by this bound in `needs_async_fn`
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error[E0525]: expected a closure that implements the `async Fn` trait, but this closure only implements `async FnOnce`
|
||||||
|
--> $DIR/wrong-fn-kind.rs:15:20
|
||||||
|
|
|
||||||
|
LL | needs_async_fn(move || async move {
|
||||||
|
| -------------- -^^^^^^
|
||||||
|
| | |
|
||||||
|
| _____|______________this closure implements `async FnOnce`, not `async Fn`
|
||||||
|
| | |
|
||||||
|
| | required by a bound introduced by this call
|
||||||
|
LL | |
|
||||||
|
LL | | println!("{x}");
|
||||||
|
| | - closure is `async FnOnce` because it moves the variable `x` out of its environment
|
||||||
|
LL | | });
|
||||||
|
| |_____- the requirement to implement `async Fn` derives from here
|
||||||
|
|
|
||||||
|
note: required by a bound in `needs_async_fn`
|
||||||
|
--> $DIR/wrong-fn-kind.rs:6:31
|
||||||
|
|
|
||||||
|
LL | fn needs_async_fn(_: impl async Fn()) {}
|
||||||
|
| ^^^^^^^^^^ required by this bound in `needs_async_fn`
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0525`.
|
For more information about this error, try `rustc --explain E0525`.
|
||||||
|
21
tests/ui/lint/ice-unions-known-panics-lint-issue-121534.rs
Normal file
21
tests/ui/lint/ice-unions-known-panics-lint-issue-121534.rs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
// Regression test for #121534
|
||||||
|
// Tests that no ICE occurs in KnownPanicsLint when it
|
||||||
|
// evaluates an operation whose operands have different
|
||||||
|
// layout types even though they have the same type.
|
||||||
|
// This situation can be contrived through the use of
|
||||||
|
// unions as in this test
|
||||||
|
|
||||||
|
//@ build-pass
|
||||||
|
union Union {
|
||||||
|
u32_field: u32,
|
||||||
|
i32_field: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn main() {
|
||||||
|
let u32_variant = Union { u32_field: 2 };
|
||||||
|
let i32_variant = Union { i32_field: 3 };
|
||||||
|
let a = unsafe { u32_variant.u32_field };
|
||||||
|
let b = unsafe { i32_variant.u32_field };
|
||||||
|
|
||||||
|
let _diff = a - b;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user