mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 06:44:35 +00:00
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:
commit
9337f7afa6
1
.gitignore
vendored
1
.gitignore
vendored
@ -19,6 +19,7 @@ Session.vim
|
|||||||
*.iml
|
*.iml
|
||||||
.vscode
|
.vscode
|
||||||
.project
|
.project
|
||||||
|
.vim/
|
||||||
.favorites.json
|
.favorites.json
|
||||||
.settings/
|
.settings/
|
||||||
.vs/
|
.vs/
|
||||||
|
@ -51,7 +51,8 @@ use rustc_metadata::creader::MetadataLoader;
|
|||||||
use rustc_metadata::locator;
|
use rustc_metadata::locator;
|
||||||
use rustc_parse::{new_parser_from_file, new_parser_from_source_str, unwrap_or_emit_fatal};
|
use rustc_parse::{new_parser_from_file, new_parser_from_source_str, unwrap_or_emit_fatal};
|
||||||
use rustc_session::config::{
|
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::getopts::{self, Matches};
|
||||||
use rustc_session::lint::{Lint, LintId};
|
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 Some(matches) = handle_options(&default_early_dcx, &args) else { return Ok(()) };
|
||||||
|
|
||||||
let sopts = config::build_session_options(&mut default_early_dcx, &matches);
|
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") {
|
if let Some(ref code) = matches.opt_str("explain") {
|
||||||
handle_explain(&default_early_dcx, diagnostics_registry(), code, sopts.color);
|
handle_explain(&default_early_dcx, diagnostics_registry(), code, sopts.color);
|
||||||
@ -315,7 +318,7 @@ fn run_compiler(
|
|||||||
input: Input::File(PathBuf::new()),
|
input: Input::File(PathBuf::new()),
|
||||||
output_file: ofile,
|
output_file: ofile,
|
||||||
output_dir: odir,
|
output_dir: odir,
|
||||||
ice_file: ice_path().clone(),
|
ice_file,
|
||||||
file_loader,
|
file_loader,
|
||||||
locale_resources: DEFAULT_LOCALE_RESOURCES,
|
locale_resources: DEFAULT_LOCALE_RESOURCES,
|
||||||
lint_caps: Default::default(),
|
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();
|
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> {
|
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(|| {
|
ICE_PATH.get_or_init(|| {
|
||||||
if !rustc_feature::UnstableFeatures::from_environment(None).is_nightly_build() {
|
if !rustc_feature::UnstableFeatures::from_environment(None).is_nightly_build() {
|
||||||
return None;
|
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") {
|
let mut path = match std::env::var_os("RUSTC_ICE") {
|
||||||
Some(s) => {
|
Some(s) => {
|
||||||
if s == "0" {
|
if s == "0" {
|
||||||
// Explicitly opting out of writing ICEs to disk.
|
// Explicitly opting out of writing ICEs to disk.
|
||||||
return None;
|
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)
|
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 now: OffsetDateTime = SystemTime::now().into();
|
||||||
let file_now = now
|
let file_now = now
|
||||||
|
@ -3,34 +3,32 @@ use std::borrow::Cow;
|
|||||||
use rustc_ast::token::{self, Token, TokenKind};
|
use rustc_ast::token::{self, Token, TokenKind};
|
||||||
use rustc_ast::tokenstream::TokenStream;
|
use rustc_ast::tokenstream::TokenStream;
|
||||||
use rustc_ast_pretty::pprust;
|
use rustc_ast_pretty::pprust;
|
||||||
use rustc_errors::{Applicability, Diag, DiagMessage};
|
use rustc_errors::{Applicability, Diag, DiagCtxtHandle, DiagMessage};
|
||||||
use rustc_macros::Subdiagnostic;
|
use rustc_macros::Subdiagnostic;
|
||||||
use rustc_parse::parser::{Parser, Recovery};
|
use rustc_parse::parser::{Parser, Recovery};
|
||||||
|
use rustc_session::parse::ParseSess;
|
||||||
use rustc_span::source_map::SourceMap;
|
use rustc_span::source_map::SourceMap;
|
||||||
use rustc_span::symbol::Ident;
|
use rustc_span::symbol::Ident;
|
||||||
use rustc_span::{ErrorGuaranteed, Span};
|
use rustc_span::{ErrorGuaranteed, Span};
|
||||||
use tracing::debug;
|
use tracing::debug;
|
||||||
|
|
||||||
use super::macro_rules::{parser_from_cx, NoopTracker};
|
use super::macro_rules::{parser_from_cx, NoopTracker};
|
||||||
use crate::base::{DummyResult, ExtCtxt, MacResult};
|
|
||||||
use crate::expand::{parse_ast_fragment, AstFragmentKind};
|
use crate::expand::{parse_ast_fragment, AstFragmentKind};
|
||||||
use crate::mbe::macro_parser::ParseResult::*;
|
use crate::mbe::macro_parser::ParseResult::*;
|
||||||
use crate::mbe::macro_parser::{MatcherLoc, NamedParseResult, TtParser};
|
use crate::mbe::macro_parser::{MatcherLoc, NamedParseResult, TtParser};
|
||||||
use crate::mbe::macro_rules::{try_match_macro, Tracker};
|
use crate::mbe::macro_rules::{try_match_macro, Tracker};
|
||||||
|
|
||||||
pub(super) fn failed_to_match_macro<'cx>(
|
pub(super) fn failed_to_match_macro(
|
||||||
cx: &'cx mut ExtCtxt<'_>,
|
psess: &ParseSess,
|
||||||
sp: Span,
|
sp: Span,
|
||||||
def_span: Span,
|
def_span: Span,
|
||||||
name: Ident,
|
name: Ident,
|
||||||
arg: TokenStream,
|
arg: TokenStream,
|
||||||
lhses: &[Vec<MatcherLoc>],
|
lhses: &[Vec<MatcherLoc>],
|
||||||
) -> Box<dyn MacResult + 'cx> {
|
) -> (Span, ErrorGuaranteed) {
|
||||||
let psess = &cx.sess.psess;
|
|
||||||
|
|
||||||
// An error occurred, try the expansion again, tracking the expansion closely for better
|
// An error occurred, try the expansion again, tracking the expansion closely for better
|
||||||
// diagnostics.
|
// 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);
|
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,
|
// Nonterminal parser recovery might turn failed matches into successful ones,
|
||||||
// but for that it must have emitted an error already
|
// but for that it must have emitted an error already
|
||||||
assert!(
|
assert!(
|
||||||
tracker.cx.dcx().has_errors().is_some(),
|
tracker.dcx.has_errors().is_some(),
|
||||||
"Macro matching returned a success on the second try"
|
"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
|
let Some(BestFailure { token, msg: label, remaining_matcher, .. }) = tracker.best_failure
|
||||||
else {
|
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 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);
|
err.span_label(span, label);
|
||||||
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.span_label(cx.source_map().guess_head_span(def_span), "when calling this macro");
|
err.span_label(psess.source_map().guess_head_span(def_span), "when calling this macro");
|
||||||
}
|
}
|
||||||
|
|
||||||
annotate_doc_comment(&mut err, psess.source_map(), span);
|
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("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");
|
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");
|
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();
|
let guar = err.emit();
|
||||||
cx.trace_macros_diag();
|
(sp, guar)
|
||||||
DummyResult::any(sp, guar)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The tracker used for the slow error path that collects useful info for diagnostics.
|
/// The tracker used for the slow error path that collects useful info for diagnostics.
|
||||||
struct CollectTrackerAndEmitter<'a, 'cx, 'matcher> {
|
struct CollectTrackerAndEmitter<'dcx, 'matcher> {
|
||||||
cx: &'a mut ExtCtxt<'cx>,
|
dcx: DiagCtxtHandle<'dcx>,
|
||||||
remaining_matcher: Option<&'matcher MatcherLoc>,
|
remaining_matcher: Option<&'matcher MatcherLoc>,
|
||||||
/// Which arm's failure should we report? (the one furthest along)
|
/// Which arm's failure should we report? (the one furthest along)
|
||||||
best_failure: Option<BestFailure>,
|
best_failure: Option<BestFailure>,
|
||||||
root_span: Span,
|
root_span: Span,
|
||||||
result: Option<Box<dyn MacResult + 'cx>>,
|
result: Option<(Span, ErrorGuaranteed)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct BestFailure {
|
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);
|
type Failure = (Token, u32, &'static str);
|
||||||
|
|
||||||
fn build_failure(tok: Token, position: u32, msg: &'static str) -> Self::Failure {
|
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(_) => {
|
Success(_) => {
|
||||||
// Nonterminal parser recovery might turn failed matches into successful ones,
|
// Nonterminal parser recovery might turn failed matches into successful ones,
|
||||||
// but for that it must have emitted an error already
|
// but for that it must have emitted an error already
|
||||||
self.cx.dcx().span_delayed_bug(
|
self.dcx.span_delayed_bug(
|
||||||
self.root_span,
|
self.root_span,
|
||||||
"should not collect detailed info for successful macro match",
|
"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) => {
|
Error(err_sp, msg) => {
|
||||||
let span = err_sp.substitute_dummy(self.root_span);
|
let span = err_sp.substitute_dummy(self.root_span);
|
||||||
let guar = self.cx.dcx().span_err(span, msg.clone());
|
let guar = self.dcx.span_err(span, msg.clone());
|
||||||
self.result = Some(DummyResult::any(span, guar));
|
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, '_> {
|
impl<'dcx> CollectTrackerAndEmitter<'dcx, '_> {
|
||||||
fn new(cx: &'a mut ExtCtxt<'cx>, root_span: Span) -> Self {
|
fn new(dcx: DiagCtxtHandle<'dcx>, root_span: Span) -> Self {
|
||||||
Self { cx, remaining_matcher: None, best_failure: None, root_span, result: None }
|
Self { dcx, remaining_matcher: None, best_failure: None, root_span, result: None }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -268,7 +268,10 @@ fn expand_macro<'cx>(
|
|||||||
}
|
}
|
||||||
Err(CanRetry::Yes) => {
|
Err(CanRetry::Yes) => {
|
||||||
// Retry and emit a better error.
|
// 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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -219,7 +219,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
// `async-await/async-closures/force-move-due-to-inferred-kind.rs`.
|
// `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
|
// 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`.
|
// 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`
|
// 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
|
// we force the inner coroutine to also be `move`. This only matters for
|
||||||
// coroutine-closures that are `move` since otherwise they themselves will
|
// coroutine-closures that are `move` since otherwise they themselves will
|
||||||
// be borrowing from the outer environment, so there's no self-borrows occuring.
|
// 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
|
if let UpvarArgs::Coroutine(..) = args
|
||||||
&& let hir::CoroutineKind::Desugared(_, hir::CoroutineSource::Closure) =
|
&& let hir::CoroutineKind::Desugared(_, hir::CoroutineSource::Closure) =
|
||||||
self.tcx.coroutine_kind(closure_def_id).expect("coroutine should have kind")
|
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 };
|
capture_clause = hir::CaptureBy::Value { move_kw };
|
||||||
}
|
}
|
||||||
// (2.) The way that the closure uses its upvars means it's `FnOnce`.
|
// (2.) The way that the closure uses its upvars means it's `FnOnce`.
|
||||||
else if let (_, ty::ClosureKind::FnOnce, _) = self
|
else if self.coroutine_body_consumes_upvars(closure_def_id, body) {
|
||||||
.process_collected_capture_information(
|
|
||||||
capture_clause,
|
|
||||||
&delegate.capture_information,
|
|
||||||
)
|
|
||||||
{
|
|
||||||
capture_clause = hir::CaptureBy::Value { move_kw };
|
capture_clause = hir::CaptureBy::Value { move_kw };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// As noted in `lower_coroutine_body_with_moved_arguments`, we default the capture mode
|
// 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
|
// 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.
|
// 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.
|
// Returns a list of `Ty`s for each upvar.
|
||||||
fn final_upvar_tys(&self, closure_id: LocalDefId) -> Vec<Ty<'tcx>> {
|
fn final_upvar_tys(&self, closure_id: LocalDefId) -> Vec<Ty<'tcx>> {
|
||||||
self.typeck_results
|
self.typeck_results
|
||||||
|
@ -125,6 +125,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||||||
[sym::inline, ..] => self.check_inline(hir_id, attr, span, target),
|
[sym::inline, ..] => self.check_inline(hir_id, attr, span, target),
|
||||||
[sym::coverage, ..] => self.check_coverage(attr, span, target),
|
[sym::coverage, ..] => self.check_coverage(attr, span, target),
|
||||||
[sym::optimize, ..] => self.check_optimize(hir_id, attr, 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::non_exhaustive, ..] => self.check_non_exhaustive(hir_id, attr, span, target),
|
||||||
[sym::marker, ..] => self.check_marker(hir_id, attr, span, target),
|
[sym::marker, ..] => self.check_marker(hir_id, attr, span, target),
|
||||||
[sym::target_feature, ..] => {
|
[sym::target_feature, ..] => {
|
||||||
@ -256,7 +257,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||||||
| sym::may_dangle // FIXME(dropck_eyepatch)
|
| sym::may_dangle // FIXME(dropck_eyepatch)
|
||||||
| sym::pointee // FIXME(derive_smart_pointer)
|
| sym::pointee // FIXME(derive_smart_pointer)
|
||||||
| sym::linkage // FIXME(linkage)
|
| sym::linkage // FIXME(linkage)
|
||||||
| sym::no_sanitize // FIXME(no_sanitize)
|
|
||||||
| sym::omit_gdb_pretty_printer_section // FIXME(omit_gdb_pretty_printer_section)
|
| sym::omit_gdb_pretty_printer_section // FIXME(omit_gdb_pretty_printer_section)
|
||||||
| sym::used // handled elsewhere to restrict to static items
|
| sym::used // handled elsewhere to restrict to static items
|
||||||
| sym::repr // handled elsewhere to restrict to type decls 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(
|
fn check_generic_attr(
|
||||||
&self,
|
&self,
|
||||||
hir_id: HirId,
|
hir_id: HirId,
|
||||||
|
@ -1827,6 +1827,8 @@ options! {
|
|||||||
the same values as the target option of the same name"),
|
the same values as the target option of the same name"),
|
||||||
meta_stats: bool = (false, parse_bool, [UNTRACKED],
|
meta_stats: bool = (false, parse_bool, [UNTRACKED],
|
||||||
"gather metadata statistics (default: no)"),
|
"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],
|
mir_emit_retag: bool = (false, parse_bool, [TRACKED],
|
||||||
"emit Retagging MIR statements, interpreted e.g., by miri; implies -Zmir-opt-level=0 \
|
"emit Retagging MIR statements, interpreted e.g., by miri; implies -Zmir-opt-level=0 \
|
||||||
(default: no)"),
|
(default: no)"),
|
||||||
|
@ -58,9 +58,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "compiler_builtins"
|
name = "compiler_builtins"
|
||||||
version = "0.1.114"
|
version = "0.1.117"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "eb58b199190fcfe0846f55a3b545cd6b07a34bdd5930a476ff856f3ebcc5558a"
|
checksum = "a91dae36d82fe12621dfb5b596d7db766187747749b22e33ac068e1bfc356f4a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"rustc-std-workspace-core",
|
"rustc-std-workspace-core",
|
||||||
|
@ -10,10 +10,7 @@ edition = "2021"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
core = { path = "../core" }
|
core = { path = "../core" }
|
||||||
compiler_builtins = { version = "0.1.114", features = ['rustc-dep-of-std'] }
|
compiler_builtins = { version = "0.1.117", 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"] }
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
rand = { version = "0.8.5", default-features = false, features = ["alloc"] }
|
rand = { version = "0.8.5", default-features = false, features = ["alloc"] }
|
||||||
|
@ -391,7 +391,7 @@ pub mod net;
|
|||||||
pub mod option;
|
pub mod option;
|
||||||
pub mod panic;
|
pub mod panic;
|
||||||
pub mod panicking;
|
pub mod panicking;
|
||||||
#[unstable(feature = "core_pattern_types", issue = "none")]
|
#[unstable(feature = "core_pattern_types", issue = "123646")]
|
||||||
pub mod pat;
|
pub mod pat;
|
||||||
pub mod pin;
|
pub mod pin;
|
||||||
#[unstable(feature = "new_range_api", issue = "125687")]
|
#[unstable(feature = "new_range_api", issue = "125687")]
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
/// ```
|
/// ```
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
#[rustc_builtin_macro(pattern_type)]
|
#[rustc_builtin_macro(pattern_type)]
|
||||||
#[unstable(feature = "core_pattern_type", issue = "none")]
|
#[unstable(feature = "core_pattern_type", issue = "123646")]
|
||||||
macro_rules! pattern_type {
|
macro_rules! pattern_type {
|
||||||
($($arg:tt)*) => {
|
($($arg:tt)*) => {
|
||||||
/* compiler built-in */
|
/* compiler built-in */
|
||||||
|
@ -17,7 +17,7 @@ cfg-if = { version = "1.0", features = ['rustc-dep-of-std'] }
|
|||||||
panic_unwind = { path = "../panic_unwind", optional = true }
|
panic_unwind = { path = "../panic_unwind", optional = true }
|
||||||
panic_abort = { path = "../panic_abort" }
|
panic_abort = { path = "../panic_abort" }
|
||||||
core = { path = "../core", public = true }
|
core = { path = "../core", public = true }
|
||||||
compiler_builtins = { version = "0.1.114" }
|
compiler_builtins = { version = "0.1.117" }
|
||||||
profiler_builtins = { path = "../profiler_builtins", optional = true }
|
profiler_builtins = { path = "../profiler_builtins", optional = true }
|
||||||
unwind = { path = "../unwind" }
|
unwind = { path = "../unwind" }
|
||||||
hashbrown = { version = "0.14", default-features = false, features = [
|
hashbrown = { version = "0.14", default-features = false, features = [
|
||||||
|
@ -586,7 +586,7 @@ pub mod net;
|
|||||||
pub mod num;
|
pub mod num;
|
||||||
pub mod os;
|
pub mod os;
|
||||||
pub mod panic;
|
pub mod panic;
|
||||||
#[unstable(feature = "core_pattern_types", issue = "none")]
|
#[unstable(feature = "core_pattern_types", issue = "123646")]
|
||||||
pub mod pat;
|
pub mod pat;
|
||||||
pub mod path;
|
pub mod path;
|
||||||
#[unstable(feature = "anonymous_pipe", issue = "127154")]
|
#[unstable(feature = "anonymous_pipe", issue = "127154")]
|
||||||
|
@ -571,6 +571,19 @@ class TestEnvironment:
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Start repository server
|
# 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(
|
check_call_with_logging(
|
||||||
[
|
[
|
||||||
ffx_path,
|
ffx_path,
|
||||||
|
@ -4,6 +4,10 @@
|
|||||||
// or full.
|
// or full.
|
||||||
// - Check that disabling ICE logging results in zero files created.
|
// - Check that disabling ICE logging results in zero files created.
|
||||||
// - Check that the ICE files contain some of the expected strings.
|
// - 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
|
// See https://github.com/rust-lang/rust/pull/108714
|
||||||
|
|
||||||
use run_make_support::{cwd, has_extension, has_prefix, rfs, rustc, shallow_find_files};
|
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() {
|
fn main() {
|
||||||
rustc().input("lib.rs").arg("-Ztreat-err-as-bug=1").run_fail();
|
rustc().input("lib.rs").arg("-Ztreat-err-as-bug=1").run_fail();
|
||||||
let default = get_text_from_ice(".").lines().count();
|
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();
|
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 ice_text = get_text_from_ice(cwd());
|
||||||
let default_set = ice_text.lines().count();
|
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();
|
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.
|
// Ensure that the ICE dump path doesn't contain `:`, because they cause problems on Windows.
|
||||||
assert!(!ice_file_name.contains(":"), "{ice_file_name}");
|
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();
|
clear_ice_files();
|
||||||
rustc()
|
rustc()
|
||||||
.env("RUSTC_ICE", cwd())
|
.env("RUSTC_ICE", cwd())
|
||||||
@ -34,6 +59,11 @@ fn main() {
|
|||||||
.arg("-Ztreat-err-as-bug=1")
|
.arg("-Ztreat-err-as-bug=1")
|
||||||
.run_fail();
|
.run_fail();
|
||||||
let short = get_text_from_ice(cwd()).lines().count();
|
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();
|
clear_ice_files();
|
||||||
rustc()
|
rustc()
|
||||||
.env("RUSTC_ICE", cwd())
|
.env("RUSTC_ICE", cwd())
|
||||||
@ -42,23 +72,49 @@ fn main() {
|
|||||||
.arg("-Ztreat-err-as-bug=1")
|
.arg("-Ztreat-err-as-bug=1")
|
||||||
.run_fail();
|
.run_fail();
|
||||||
let full = get_text_from_ice(cwd()).lines().count();
|
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();
|
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.
|
fn metrics_dir(baseline: usize) {
|
||||||
rustc().env("RUSTC_ICE", "0").input("lib.rs").arg("-Ztreat-err-as-bug=1").run_fail();
|
test_flag_only(baseline);
|
||||||
let ice_files = shallow_find_files(cwd(), |path| {
|
test_flag_and_env(baseline);
|
||||||
has_prefix(path, "rustc-ice") && has_extension(path, "txt")
|
}
|
||||||
});
|
|
||||||
assert!(ice_files.is_empty()); // There should be 0 ICE files.
|
|
||||||
|
|
||||||
// The line count should not change.
|
fn test_flag_only(baseline: usize) {
|
||||||
assert_eq!(short, default_set);
|
clear_ice_files();
|
||||||
assert_eq!(short, default);
|
let metrics_arg = format!("-Zmetrics-dir={}", cwd().display());
|
||||||
assert_eq!(full, default_set);
|
rustc().input("lib.rs").arg("-Ztreat-err-as-bug=1").arg(metrics_arg).run_fail();
|
||||||
assert!(default > 0);
|
let output = get_text_from_ice(cwd()).lines().count();
|
||||||
// Some of the expected strings in an ICE file should appear.
|
assert_eq!(output, baseline);
|
||||||
assert!(content.contains("thread 'rustc' panicked at"));
|
}
|
||||||
assert!(content.contains("stack backtrace:"));
|
|
||||||
|
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() {
|
fn clear_ice_files() {
|
||||||
|
@ -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;
|
||||||
|
});
|
||||||
|
}
|
34
tests/ui/attributes/no-sanitize.rs
Normal file
34
tests/ui/attributes/no-sanitize.rs
Normal 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() {}
|
55
tests/ui/attributes/no-sanitize.stderr
Normal file
55
tests/ui/attributes/no-sanitize.stderr
Normal 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
|
||||||
|
|
@ -4,6 +4,7 @@ error[E0658]: use of unstable library feature 'core_pattern_type'
|
|||||||
LL | type NonNullU32 = pattern_type!(u32 is 1..);
|
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
|
= 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
|
= 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);
|
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
|
= 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
|
= 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);
|
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
|
= 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
|
= 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..);
|
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
|
= 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
|
= 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(_));
|
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
|
= 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
|
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user