Auto merge of #128805 - tgross35:rollup-wajzi6w, r=tgross35

Rollup of 7 pull requests

Successful merges:

 - #128520 (Skip over args when determining if async-closure's inner coroutine consumes its upvars)
 - #128552 (Emit an error for invalid use of the `#[no_sanitize]` attribute)
 - #128691 (Update `compiler-builtins` to 0.1.117)
 - #128702 (Add -Zmetrics-dir=PATH to save diagnostic metadata to disk)
 - #128797 (Fuchsia Test Runner: enable ffx repository server)
 - #128798 (refactor(rustc_expand::mbe): Don't require full ExtCtxt when not necessary)
 - #128800 (Add tracking issue to core-pattern-type)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2024-08-08 04:10:56 +00:00
commit 9337f7afa6
19 changed files with 321 additions and 75 deletions

1
.gitignore vendored
View File

@ -19,6 +19,7 @@ Session.vim
*.iml
.vscode
.project
.vim/
.favorites.json
.settings/
.vs/

View File

@ -51,7 +51,8 @@ use rustc_metadata::creader::MetadataLoader;
use rustc_metadata::locator;
use rustc_parse::{new_parser_from_file, new_parser_from_source_str, unwrap_or_emit_fatal};
use rustc_session::config::{
nightly_options, ErrorOutputType, Input, OutFileName, OutputType, CG_OPTIONS, Z_OPTIONS,
nightly_options, ErrorOutputType, Input, OutFileName, OutputType, UnstableOptions, CG_OPTIONS,
Z_OPTIONS,
};
use rustc_session::getopts::{self, Matches};
use rustc_session::lint::{Lint, LintId};
@ -301,6 +302,8 @@ fn run_compiler(
let Some(matches) = handle_options(&default_early_dcx, &args) else { return Ok(()) };
let sopts = config::build_session_options(&mut default_early_dcx, &matches);
// fully initialize ice path static once unstable options are available as context
let ice_file = ice_path_with_config(Some(&sopts.unstable_opts)).clone();
if let Some(ref code) = matches.opt_str("explain") {
handle_explain(&default_early_dcx, diagnostics_registry(), code, sopts.color);
@ -315,7 +318,7 @@ fn run_compiler(
input: Input::File(PathBuf::new()),
output_file: ofile,
output_dir: odir,
ice_file: ice_path().clone(),
ice_file,
file_loader,
locale_resources: DEFAULT_LOCALE_RESOURCES,
lint_caps: Default::default(),
@ -1306,25 +1309,43 @@ pub fn catch_with_exit_code(f: impl FnOnce() -> interface::Result<()>) -> i32 {
static ICE_PATH: OnceLock<Option<PathBuf>> = OnceLock::new();
// This function should only be called from the ICE hook.
//
// The intended behavior is that `run_compiler` will invoke `ice_path_with_config` early in the
// initialization process to properly initialize the ICE_PATH static based on parsed CLI flags.
//
// Subsequent calls to either function will then return the proper ICE path as configured by
// the environment and cli flags
fn ice_path() -> &'static Option<PathBuf> {
ice_path_with_config(None)
}
fn ice_path_with_config(config: Option<&UnstableOptions>) -> &'static Option<PathBuf> {
if ICE_PATH.get().is_some() && config.is_some() && cfg!(debug_assertions) {
tracing::warn!(
"ICE_PATH has already been initialized -- files may be emitted at unintended paths"
)
}
ICE_PATH.get_or_init(|| {
if !rustc_feature::UnstableFeatures::from_environment(None).is_nightly_build() {
return None;
}
if let Some(s) = std::env::var_os("RUST_BACKTRACE")
&& s == "0"
{
return None;
}
let mut path = match std::env::var_os("RUSTC_ICE") {
Some(s) => {
if s == "0" {
// Explicitly opting out of writing ICEs to disk.
return None;
}
if let Some(unstable_opts) = config && unstable_opts.metrics_dir.is_some() {
tracing::warn!("ignoring -Zerror-metrics in favor of RUSTC_ICE for destination of ICE report files");
}
PathBuf::from(s)
}
None => std::env::current_dir().unwrap_or_default(),
None => config
.and_then(|unstable_opts| unstable_opts.metrics_dir.to_owned())
.or_else(|| std::env::current_dir().ok())
.unwrap_or_default(),
};
let now: OffsetDateTime = SystemTime::now().into();
let file_now = now

View File

@ -3,34 +3,32 @@ use std::borrow::Cow;
use rustc_ast::token::{self, Token, TokenKind};
use rustc_ast::tokenstream::TokenStream;
use rustc_ast_pretty::pprust;
use rustc_errors::{Applicability, Diag, DiagMessage};
use rustc_errors::{Applicability, Diag, DiagCtxtHandle, DiagMessage};
use rustc_macros::Subdiagnostic;
use rustc_parse::parser::{Parser, Recovery};
use rustc_session::parse::ParseSess;
use rustc_span::source_map::SourceMap;
use rustc_span::symbol::Ident;
use rustc_span::{ErrorGuaranteed, Span};
use tracing::debug;
use super::macro_rules::{parser_from_cx, NoopTracker};
use crate::base::{DummyResult, ExtCtxt, MacResult};
use crate::expand::{parse_ast_fragment, AstFragmentKind};
use crate::mbe::macro_parser::ParseResult::*;
use crate::mbe::macro_parser::{MatcherLoc, NamedParseResult, TtParser};
use crate::mbe::macro_rules::{try_match_macro, Tracker};
pub(super) fn failed_to_match_macro<'cx>(
cx: &'cx mut ExtCtxt<'_>,
pub(super) fn failed_to_match_macro(
psess: &ParseSess,
sp: Span,
def_span: Span,
name: Ident,
arg: TokenStream,
lhses: &[Vec<MatcherLoc>],
) -> Box<dyn MacResult + 'cx> {
let psess = &cx.sess.psess;
) -> (Span, ErrorGuaranteed) {
// An error occurred, try the expansion again, tracking the expansion closely for better
// diagnostics.
let mut tracker = CollectTrackerAndEmitter::new(cx, sp);
let mut tracker = CollectTrackerAndEmitter::new(psess.dcx(), sp);
let try_success_result = try_match_macro(psess, name, &arg, lhses, &mut tracker);
@ -38,7 +36,7 @@ pub(super) fn failed_to_match_macro<'cx>(
// Nonterminal parser recovery might turn failed matches into successful ones,
// but for that it must have emitted an error already
assert!(
tracker.cx.dcx().has_errors().is_some(),
tracker.dcx.has_errors().is_some(),
"Macro matching returned a success on the second try"
);
}
@ -50,15 +48,15 @@ pub(super) fn failed_to_match_macro<'cx>(
let Some(BestFailure { token, msg: label, remaining_matcher, .. }) = tracker.best_failure
else {
return DummyResult::any(sp, cx.dcx().span_delayed_bug(sp, "failed to match a macro"));
return (sp, psess.dcx().span_delayed_bug(sp, "failed to match a macro"));
};
let span = token.span.substitute_dummy(sp);
let mut err = cx.dcx().struct_span_err(span, parse_failure_msg(&token, None));
let mut err = psess.dcx().struct_span_err(span, parse_failure_msg(&token, None));
err.span_label(span, label);
if !def_span.is_dummy() && !cx.source_map().is_imported(def_span) {
err.span_label(cx.source_map().guess_head_span(def_span), "when calling this macro");
if !def_span.is_dummy() && !psess.source_map().is_imported(def_span) {
err.span_label(psess.source_map().guess_head_span(def_span), "when calling this macro");
}
annotate_doc_comment(&mut err, psess.source_map(), span);
@ -76,7 +74,7 @@ pub(super) fn failed_to_match_macro<'cx>(
err.note("captured metavariables except for `:tt`, `:ident` and `:lifetime` cannot be compared to other tokens");
err.note("see <https://doc.rust-lang.org/nightly/reference/macros-by-example.html#forwarding-a-matched-fragment> for more information");
if !def_span.is_dummy() && !cx.source_map().is_imported(def_span) {
if !def_span.is_dummy() && !psess.source_map().is_imported(def_span) {
err.help("try using `:tt` instead in the macro definition");
}
}
@ -104,18 +102,17 @@ pub(super) fn failed_to_match_macro<'cx>(
}
}
let guar = err.emit();
cx.trace_macros_diag();
DummyResult::any(sp, guar)
(sp, guar)
}
/// The tracker used for the slow error path that collects useful info for diagnostics.
struct CollectTrackerAndEmitter<'a, 'cx, 'matcher> {
cx: &'a mut ExtCtxt<'cx>,
struct CollectTrackerAndEmitter<'dcx, 'matcher> {
dcx: DiagCtxtHandle<'dcx>,
remaining_matcher: Option<&'matcher MatcherLoc>,
/// Which arm's failure should we report? (the one furthest along)
best_failure: Option<BestFailure>,
root_span: Span,
result: Option<Box<dyn MacResult + 'cx>>,
result: Option<(Span, ErrorGuaranteed)>,
}
struct BestFailure {
@ -131,7 +128,7 @@ impl BestFailure {
}
}
impl<'a, 'cx, 'matcher> Tracker<'matcher> for CollectTrackerAndEmitter<'a, 'cx, 'matcher> {
impl<'dcx, 'matcher> Tracker<'matcher> for CollectTrackerAndEmitter<'dcx, 'matcher> {
type Failure = (Token, u32, &'static str);
fn build_failure(tok: Token, position: u32, msg: &'static str) -> Self::Failure {
@ -151,7 +148,7 @@ impl<'a, 'cx, 'matcher> Tracker<'matcher> for CollectTrackerAndEmitter<'a, 'cx,
Success(_) => {
// Nonterminal parser recovery might turn failed matches into successful ones,
// but for that it must have emitted an error already
self.cx.dcx().span_delayed_bug(
self.dcx.span_delayed_bug(
self.root_span,
"should not collect detailed info for successful macro match",
);
@ -177,10 +174,10 @@ impl<'a, 'cx, 'matcher> Tracker<'matcher> for CollectTrackerAndEmitter<'a, 'cx,
}
Error(err_sp, msg) => {
let span = err_sp.substitute_dummy(self.root_span);
let guar = self.cx.dcx().span_err(span, msg.clone());
self.result = Some(DummyResult::any(span, guar));
let guar = self.dcx.span_err(span, msg.clone());
self.result = Some((span, guar));
}
ErrorReported(guar) => self.result = Some(DummyResult::any(self.root_span, *guar)),
ErrorReported(guar) => self.result = Some((self.root_span, *guar)),
}
}
@ -193,9 +190,9 @@ impl<'a, 'cx, 'matcher> Tracker<'matcher> for CollectTrackerAndEmitter<'a, 'cx,
}
}
impl<'a, 'cx> CollectTrackerAndEmitter<'a, 'cx, '_> {
fn new(cx: &'a mut ExtCtxt<'cx>, root_span: Span) -> Self {
Self { cx, remaining_matcher: None, best_failure: None, root_span, result: None }
impl<'dcx> CollectTrackerAndEmitter<'dcx, '_> {
fn new(dcx: DiagCtxtHandle<'dcx>, root_span: Span) -> Self {
Self { dcx, remaining_matcher: None, best_failure: None, root_span, result: None }
}
}

View File

@ -268,7 +268,10 @@ fn expand_macro<'cx>(
}
Err(CanRetry::Yes) => {
// Retry and emit a better error.
diagnostics::failed_to_match_macro(cx, sp, def_span, name, arg, lhses)
let (span, guar) =
diagnostics::failed_to_match_macro(cx.psess(), sp, def_span, name, arg, lhses);
cx.trace_macros_diag();
DummyResult::any(span, guar)
}
}
}

View File

@ -219,7 +219,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// `async-await/async-closures/force-move-due-to-inferred-kind.rs`.
//
// 2. If the coroutine-closure is forced to be `FnOnce` due to the way it
// uses its upvars, but not *all* upvars would force the closure to `FnOnce`.
// uses its upvars (e.g. it consumes a non-copy value), but not *all* upvars
// would force the closure to `FnOnce`.
// See the test: `async-await/async-closures/force-move-due-to-actually-fnonce.rs`.
//
// This would lead to an impossible to satisfy situation, since `AsyncFnOnce`
@ -227,11 +228,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// we force the inner coroutine to also be `move`. This only matters for
// coroutine-closures that are `move` since otherwise they themselves will
// be borrowing from the outer environment, so there's no self-borrows occuring.
//
// One *important* note is that we do a call to `process_collected_capture_information`
// to eagerly test whether the coroutine would end up `FnOnce`, but we do this
// *before* capturing all the closure args by-value below, since that would always
// cause the analysis to return `FnOnce`.
if let UpvarArgs::Coroutine(..) = args
&& let hir::CoroutineKind::Desugared(_, hir::CoroutineSource::Closure) =
self.tcx.coroutine_kind(closure_def_id).expect("coroutine should have kind")
@ -246,19 +242,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
capture_clause = hir::CaptureBy::Value { move_kw };
}
// (2.) The way that the closure uses its upvars means it's `FnOnce`.
else if let (_, ty::ClosureKind::FnOnce, _) = self
.process_collected_capture_information(
capture_clause,
&delegate.capture_information,
)
{
else if self.coroutine_body_consumes_upvars(closure_def_id, body) {
capture_clause = hir::CaptureBy::Value { move_kw };
}
}
// As noted in `lower_coroutine_body_with_moved_arguments`, we default the capture mode
// to `ByRef` for the `async {}` block internal to async fns/closure. This means
// that we would *not* be moving all of the parameters into the async block by default.
// that we would *not* be moving all of the parameters into the async block in all cases.
// For example, when one of the arguments is `Copy`, we turn a consuming use into a copy of
// a reference, so for `async fn x(t: i32) {}`, we'd only take a reference to `t`.
//
// We force all of these arguments to be captured by move before we do expr use analysis.
//
@ -535,6 +528,53 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
/// Determines whether the body of the coroutine uses its upvars in a way that
/// consumes (i.e. moves) the value, which would force the coroutine to `FnOnce`.
/// In a more detailed comment above, we care whether this happens, since if
/// this happens, we want to force the coroutine to move all of the upvars it
/// would've borrowed from the parent coroutine-closure.
///
/// This only really makes sense to be called on the child coroutine of a
/// coroutine-closure.
fn coroutine_body_consumes_upvars(
&self,
coroutine_def_id: LocalDefId,
body: &'tcx hir::Body<'tcx>,
) -> bool {
// This block contains argument capturing details. Since arguments
// aren't upvars, we do not care about them for determining if the
// coroutine body actually consumes its upvars.
let hir::ExprKind::Block(&hir::Block { expr: Some(body), .. }, None) = body.value.kind
else {
bug!();
};
// Specifically, we only care about the *real* body of the coroutine.
// We skip out into the drop-temps within the block of the body in order
// to skip over the args of the desugaring.
let hir::ExprKind::DropTemps(body) = body.kind else {
bug!();
};
let mut delegate = InferBorrowKind {
closure_def_id: coroutine_def_id,
capture_information: Default::default(),
fake_reads: Default::default(),
};
let _ = euv::ExprUseVisitor::new(
&FnCtxt::new(self, self.tcx.param_env(coroutine_def_id), coroutine_def_id),
&mut delegate,
)
.consume_expr(body);
let (_, kind, _) = self.process_collected_capture_information(
hir::CaptureBy::Ref,
&delegate.capture_information,
);
matches!(kind, ty::ClosureKind::FnOnce)
}
// Returns a list of `Ty`s for each upvar.
fn final_upvar_tys(&self, closure_id: LocalDefId) -> Vec<Ty<'tcx>> {
self.typeck_results

View File

@ -125,6 +125,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
[sym::inline, ..] => self.check_inline(hir_id, attr, span, target),
[sym::coverage, ..] => self.check_coverage(attr, span, target),
[sym::optimize, ..] => self.check_optimize(hir_id, attr, target),
[sym::no_sanitize, ..] => self.check_no_sanitize(hir_id, attr, span, target),
[sym::non_exhaustive, ..] => self.check_non_exhaustive(hir_id, attr, span, target),
[sym::marker, ..] => self.check_marker(hir_id, attr, span, target),
[sym::target_feature, ..] => {
@ -256,7 +257,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
| sym::may_dangle // FIXME(dropck_eyepatch)
| sym::pointee // FIXME(derive_smart_pointer)
| sym::linkage // FIXME(linkage)
| sym::no_sanitize // FIXME(no_sanitize)
| sym::omit_gdb_pretty_printer_section // FIXME(omit_gdb_pretty_printer_section)
| sym::used // handled elsewhere to restrict to static items
| sym::repr // handled elsewhere to restrict to type decls items
@ -451,6 +451,11 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
}
}
/// Checks that `#[no_sanitize(..)]` is applied to a function or method.
fn check_no_sanitize(&self, hir_id: HirId, attr: &Attribute, span: Span, target: Target) {
self.check_applied_to_fn_or_method(hir_id, attr, span, target)
}
fn check_generic_attr(
&self,
hir_id: HirId,

View File

@ -1827,6 +1827,8 @@ options! {
the same values as the target option of the same name"),
meta_stats: bool = (false, parse_bool, [UNTRACKED],
"gather metadata statistics (default: no)"),
metrics_dir: Option<PathBuf> = (None, parse_opt_pathbuf, [UNTRACKED],
"stores metrics about the errors being emitted by rustc to disk"),
mir_emit_retag: bool = (false, parse_bool, [TRACKED],
"emit Retagging MIR statements, interpreted e.g., by miri; implies -Zmir-opt-level=0 \
(default: no)"),

View File

@ -58,9 +58,9 @@ dependencies = [
[[package]]
name = "compiler_builtins"
version = "0.1.114"
version = "0.1.117"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb58b199190fcfe0846f55a3b545cd6b07a34bdd5930a476ff856f3ebcc5558a"
checksum = "a91dae36d82fe12621dfb5b596d7db766187747749b22e33ac068e1bfc356f4a"
dependencies = [
"cc",
"rustc-std-workspace-core",

View File

@ -10,10 +10,7 @@ edition = "2021"
[dependencies]
core = { path = "../core" }
compiler_builtins = { version = "0.1.114", features = ['rustc-dep-of-std'] }
[target.'cfg(not(any(target_arch = "aarch64", target_arch = "x86", target_arch = "x86_64")))'.dependencies]
compiler_builtins = { version = "0.1.114", features = ["no-f16-f128"] }
compiler_builtins = { version = "0.1.117", features = ['rustc-dep-of-std'] }
[dev-dependencies]
rand = { version = "0.8.5", default-features = false, features = ["alloc"] }

View File

@ -391,7 +391,7 @@ pub mod net;
pub mod option;
pub mod panic;
pub mod panicking;
#[unstable(feature = "core_pattern_types", issue = "none")]
#[unstable(feature = "core_pattern_types", issue = "123646")]
pub mod pat;
pub mod pin;
#[unstable(feature = "new_range_api", issue = "125687")]

View File

@ -6,7 +6,7 @@
/// ```
#[macro_export]
#[rustc_builtin_macro(pattern_type)]
#[unstable(feature = "core_pattern_type", issue = "none")]
#[unstable(feature = "core_pattern_type", issue = "123646")]
macro_rules! pattern_type {
($($arg:tt)*) => {
/* compiler built-in */

View File

@ -17,7 +17,7 @@ cfg-if = { version = "1.0", features = ['rustc-dep-of-std'] }
panic_unwind = { path = "../panic_unwind", optional = true }
panic_abort = { path = "../panic_abort" }
core = { path = "../core", public = true }
compiler_builtins = { version = "0.1.114" }
compiler_builtins = { version = "0.1.117" }
profiler_builtins = { path = "../profiler_builtins", optional = true }
unwind = { path = "../unwind" }
hashbrown = { version = "0.14", default-features = false, features = [

View File

@ -586,7 +586,7 @@ pub mod net;
pub mod num;
pub mod os;
pub mod panic;
#[unstable(feature = "core_pattern_types", issue = "none")]
#[unstable(feature = "core_pattern_types", issue = "123646")]
pub mod pat;
pub mod path;
#[unstable(feature = "anonymous_pipe", issue = "127154")]

View File

@ -571,6 +571,19 @@ class TestEnvironment:
)
# Start repository server
# Note that we must first enable the repository server daemon.
check_call_with_logging(
[
ffx_path,
"config",
"set",
"repository.server.enabled",
"true",
],
env=ffx_env,
stdout_handler=self.subprocess_logger.debug,
stderr_handler=self.subprocess_logger.debug,
)
check_call_with_logging(
[
ffx_path,

View File

@ -4,6 +4,10 @@
// or full.
// - Check that disabling ICE logging results in zero files created.
// - Check that the ICE files contain some of the expected strings.
// - exercise the -Zmetrics-dir nightly flag
// - verify what happens when both the nightly flag and env variable are set
// - test the RUST_BACKTRACE=0 behavior against the file creation
// See https://github.com/rust-lang/rust/pull/108714
use run_make_support::{cwd, has_extension, has_prefix, rfs, rustc, shallow_find_files};
@ -11,8 +15,8 @@ use run_make_support::{cwd, has_extension, has_prefix, rfs, rustc, shallow_find_
fn main() {
rustc().input("lib.rs").arg("-Ztreat-err-as-bug=1").run_fail();
let default = get_text_from_ice(".").lines().count();
clear_ice_files();
clear_ice_files();
rustc().env("RUSTC_ICE", cwd()).input("lib.rs").arg("-Ztreat-err-as-bug=1").run_fail();
let ice_text = get_text_from_ice(cwd());
let default_set = ice_text.lines().count();
@ -25,7 +29,28 @@ fn main() {
ice_files.first().and_then(|f| f.file_name()).and_then(|n| n.to_str()).unwrap();
// Ensure that the ICE dump path doesn't contain `:`, because they cause problems on Windows.
assert!(!ice_file_name.contains(":"), "{ice_file_name}");
assert_eq!(default, default_set);
assert!(default > 0);
// Some of the expected strings in an ICE file should appear.
assert!(content.contains("thread 'rustc' panicked at"));
assert!(content.contains("stack backtrace:"));
test_backtrace_short(default);
test_backtrace_full(default);
test_backtrace_disabled(default);
clear_ice_files();
// The ICE dump is explicitly disabled. Therefore, this should produce no files.
rustc().env("RUSTC_ICE", "0").input("lib.rs").arg("-Ztreat-err-as-bug=1").run_fail();
let ice_files = shallow_find_files(cwd(), |path| {
has_prefix(path, "rustc-ice") && has_extension(path, "txt")
});
assert!(ice_files.is_empty()); // There should be 0 ICE files.
metrics_dir(default);
}
fn test_backtrace_short(baseline: usize) {
clear_ice_files();
rustc()
.env("RUSTC_ICE", cwd())
@ -34,6 +59,11 @@ fn main() {
.arg("-Ztreat-err-as-bug=1")
.run_fail();
let short = get_text_from_ice(cwd()).lines().count();
// backtrace length in dump shouldn't be changed by RUST_BACKTRACE
assert_eq!(short, baseline);
}
fn test_backtrace_full(baseline: usize) {
clear_ice_files();
rustc()
.env("RUSTC_ICE", cwd())
@ -42,23 +72,49 @@ fn main() {
.arg("-Ztreat-err-as-bug=1")
.run_fail();
let full = get_text_from_ice(cwd()).lines().count();
// backtrace length in dump shouldn't be changed by RUST_BACKTRACE
assert_eq!(full, baseline);
}
fn test_backtrace_disabled(baseline: usize) {
clear_ice_files();
rustc()
.env("RUSTC_ICE", cwd())
.input("lib.rs")
.env("RUST_BACKTRACE", "0")
.arg("-Ztreat-err-as-bug=1")
.run_fail();
let disabled = get_text_from_ice(cwd()).lines().count();
// backtrace length in dump shouldn't be changed by RUST_BACKTRACE
assert_eq!(disabled, baseline);
}
// The ICE dump is explicitly disabled. Therefore, this should produce no files.
rustc().env("RUSTC_ICE", "0").input("lib.rs").arg("-Ztreat-err-as-bug=1").run_fail();
let ice_files = shallow_find_files(cwd(), |path| {
has_prefix(path, "rustc-ice") && has_extension(path, "txt")
});
assert!(ice_files.is_empty()); // There should be 0 ICE files.
fn metrics_dir(baseline: usize) {
test_flag_only(baseline);
test_flag_and_env(baseline);
}
// The line count should not change.
assert_eq!(short, default_set);
assert_eq!(short, default);
assert_eq!(full, default_set);
assert!(default > 0);
// Some of the expected strings in an ICE file should appear.
assert!(content.contains("thread 'rustc' panicked at"));
assert!(content.contains("stack backtrace:"));
fn test_flag_only(baseline: usize) {
clear_ice_files();
let metrics_arg = format!("-Zmetrics-dir={}", cwd().display());
rustc().input("lib.rs").arg("-Ztreat-err-as-bug=1").arg(metrics_arg).run_fail();
let output = get_text_from_ice(cwd()).lines().count();
assert_eq!(output, baseline);
}
fn test_flag_and_env(baseline: usize) {
clear_ice_files();
let metrics_arg = format!("-Zmetrics-dir={}", cwd().display());
let real_dir = cwd().join("actually_put_ice_here");
rfs::create_dir(real_dir.clone());
rustc()
.input("lib.rs")
.env("RUSTC_ICE", real_dir.clone())
.arg("-Ztreat-err-as-bug=1")
.arg(metrics_arg)
.run_fail();
let output = get_text_from_ice(real_dir).lines().count();
assert_eq!(output, baseline);
}
fn clear_ice_files() {

View File

@ -0,0 +1,17 @@
//@ aux-build:block-on.rs
//@ edition:2021
//@ build-pass
#![feature(async_closure)]
extern crate block_on;
fn wrapper(f: impl Fn(String)) -> impl async Fn(String) {
async move |s| f(s)
}
fn main() {
block_on::block_on(async {
wrapper(|who| println!("Hello, {who}!"))(String::from("world")).await;
});
}

View File

@ -0,0 +1,34 @@
#![feature(no_sanitize)]
#![feature(stmt_expr_attributes)]
#![deny(unused_attributes)]
#![allow(dead_code)]
fn invalid() {
#[no_sanitize(memory)] //~ ERROR attribute should be applied to a function definition
{
1
};
}
#[no_sanitize(memory)] //~ ERROR attribute should be applied to a function definition
type InvalidTy = ();
#[no_sanitize(memory)] //~ ERROR attribute should be applied to a function definition
mod invalid_module {}
fn main() {
let _ = #[no_sanitize(memory)] //~ ERROR attribute should be applied to a function definition
(|| 1);
}
#[no_sanitize(memory)] //~ ERROR attribute should be applied to a function definition
struct F;
#[no_sanitize(memory)] //~ ERROR attribute should be applied to a function definition
impl F {
#[no_sanitize(memory)]
fn valid(&self) {}
}
#[no_sanitize(memory)]
fn valid() {}

View File

@ -0,0 +1,55 @@
error: attribute should be applied to a function definition
--> $DIR/no-sanitize.rs:7:5
|
LL | #[no_sanitize(memory)]
| ^^^^^^^^^^^^^^^^^^^^^^
LL | / {
LL | | 1
LL | | };
| |_____- not a function definition
error: attribute should be applied to a function definition
--> $DIR/no-sanitize.rs:13:1
|
LL | #[no_sanitize(memory)]
| ^^^^^^^^^^^^^^^^^^^^^^
LL | type InvalidTy = ();
| -------------------- not a function definition
error: attribute should be applied to a function definition
--> $DIR/no-sanitize.rs:16:1
|
LL | #[no_sanitize(memory)]
| ^^^^^^^^^^^^^^^^^^^^^^
LL | mod invalid_module {}
| --------------------- not a function definition
error: attribute should be applied to a function definition
--> $DIR/no-sanitize.rs:20:13
|
LL | let _ = #[no_sanitize(memory)]
| ^^^^^^^^^^^^^^^^^^^^^^
LL | (|| 1);
| ------ not a function definition
error: attribute should be applied to a function definition
--> $DIR/no-sanitize.rs:24:1
|
LL | #[no_sanitize(memory)]
| ^^^^^^^^^^^^^^^^^^^^^^
LL | struct F;
| --------- not a function definition
error: attribute should be applied to a function definition
--> $DIR/no-sanitize.rs:27:1
|
LL | #[no_sanitize(memory)]
| ^^^^^^^^^^^^^^^^^^^^^^
LL | / impl F {
LL | | #[no_sanitize(memory)]
LL | | fn valid(&self) {}
LL | | }
| |_- not a function definition
error: aborting due to 6 previous errors

View File

@ -4,6 +4,7 @@ error[E0658]: use of unstable library feature 'core_pattern_type'
LL | type NonNullU32 = pattern_type!(u32 is 1..);
| ^^^^^^^^^^^^
|
= note: see issue #123646 <https://github.com/rust-lang/rust/issues/123646> for more information
= help: add `#![feature(core_pattern_type)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
@ -13,6 +14,7 @@ error[E0658]: use of unstable library feature 'core_pattern_type'
LL | type Percent = pattern_type!(u32 is 0..=100);
| ^^^^^^^^^^^^
|
= note: see issue #123646 <https://github.com/rust-lang/rust/issues/123646> for more information
= help: add `#![feature(core_pattern_type)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
@ -22,6 +24,7 @@ error[E0658]: use of unstable library feature 'core_pattern_type'
LL | type Negative = pattern_type!(i32 is ..=0);
| ^^^^^^^^^^^^
|
= note: see issue #123646 <https://github.com/rust-lang/rust/issues/123646> for more information
= help: add `#![feature(core_pattern_type)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
@ -31,6 +34,7 @@ error[E0658]: use of unstable library feature 'core_pattern_type'
LL | type Positive = pattern_type!(i32 is 0..);
| ^^^^^^^^^^^^
|
= note: see issue #123646 <https://github.com/rust-lang/rust/issues/123646> for more information
= help: add `#![feature(core_pattern_type)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
@ -40,6 +44,7 @@ error[E0658]: use of unstable library feature 'core_pattern_type'
LL | type Always = pattern_type!(Option<u32> is Some(_));
| ^^^^^^^^^^^^
|
= note: see issue #123646 <https://github.com/rust-lang/rust/issues/123646> for more information
= help: add `#![feature(core_pattern_type)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date