mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
Auto merge of #133803 - matthiaskrgr:rollup-8ag5ncy, r=matthiaskrgr
Rollup of 9 pull requests Successful merges: - #132612 (Gate async fn trait bound modifier on `async_trait_bounds`) - #133545 (Lint against Symbol::intern on a string literal) - #133558 (Structurally resolve in `probe_adt`) - #133696 (stabilize const_collections_with_hasher and build_hasher_default_const_new) - #133753 (Reduce false positives on some common cases from if-let-rescope lint) - #133762 (stabilize const_{size,align}_of_val) - #133777 (document -Zrandomize-layout in the unstable book) - #133779 (Use correct `hir_id` for array const arg infers) - #133796 (Update the definition of `borrowing_sub`) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
c44b3d50fe
@ -2011,7 +2011,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||||||
ExprKind::Underscore => {
|
ExprKind::Underscore => {
|
||||||
if self.tcx.features().generic_arg_infer() {
|
if self.tcx.features().generic_arg_infer() {
|
||||||
let ct_kind = hir::ConstArgKind::Infer(self.lower_span(c.value.span));
|
let ct_kind = hir::ConstArgKind::Infer(self.lower_span(c.value.span));
|
||||||
self.arena.alloc(hir::ConstArg { hir_id: self.next_id(), kind: ct_kind })
|
self.arena
|
||||||
|
.alloc(hir::ConstArg { hir_id: self.lower_node_id(c.id), kind: ct_kind })
|
||||||
} else {
|
} else {
|
||||||
feature_err(
|
feature_err(
|
||||||
&self.tcx.sess,
|
&self.tcx.sess,
|
||||||
|
@ -4,9 +4,9 @@ use rustc_ast::{NodeId, PatKind, attr, token};
|
|||||||
use rustc_feature::{AttributeGate, BUILTIN_ATTRIBUTE_MAP, BuiltinAttribute, Features, GateIssue};
|
use rustc_feature::{AttributeGate, BUILTIN_ATTRIBUTE_MAP, BuiltinAttribute, Features, GateIssue};
|
||||||
use rustc_session::Session;
|
use rustc_session::Session;
|
||||||
use rustc_session::parse::{feature_err, feature_err_issue, feature_warn};
|
use rustc_session::parse::{feature_err, feature_err_issue, feature_warn};
|
||||||
|
use rustc_span::Span;
|
||||||
use rustc_span::source_map::Spanned;
|
use rustc_span::source_map::Spanned;
|
||||||
use rustc_span::symbol::sym;
|
use rustc_span::symbol::{Symbol, sym};
|
||||||
use rustc_span::{Span, Symbol};
|
|
||||||
use rustc_target::spec::abi;
|
use rustc_target::spec::abi;
|
||||||
use thin_vec::ThinVec;
|
use thin_vec::ThinVec;
|
||||||
|
|
||||||
@ -516,6 +516,11 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
|
|||||||
"async closures are unstable",
|
"async closures are unstable",
|
||||||
"to use an async block, remove the `||`: `async {`"
|
"to use an async block, remove the `||`: `async {`"
|
||||||
);
|
);
|
||||||
|
gate_all!(
|
||||||
|
async_trait_bounds,
|
||||||
|
"`async` trait bounds are unstable",
|
||||||
|
"use the desugared name of the async trait, such as `AsyncFn`"
|
||||||
|
);
|
||||||
gate_all!(async_for_loop, "`for await` loops are experimental");
|
gate_all!(async_for_loop, "`for await` loops are experimental");
|
||||||
gate_all!(
|
gate_all!(
|
||||||
closure_lifetime_binder,
|
closure_lifetime_binder,
|
||||||
@ -690,6 +695,7 @@ fn check_new_solver_banned_features(sess: &Session, features: &Features) {
|
|||||||
.find(|feat| feat.gate_name == sym::generic_const_exprs)
|
.find(|feat| feat.gate_name == sym::generic_const_exprs)
|
||||||
.map(|feat| feat.attr_sp)
|
.map(|feat| feat.attr_sp)
|
||||||
{
|
{
|
||||||
|
#[cfg_attr(not(bootstrap), allow(rustc::symbol_intern_string_literal))]
|
||||||
sess.dcx().emit_err(errors::IncompatibleFeatures {
|
sess.dcx().emit_err(errors::IncompatibleFeatures {
|
||||||
spans: vec![gce_span],
|
spans: vec![gce_span],
|
||||||
f1: Symbol::intern("-Znext-solver=globally"),
|
f1: Symbol::intern("-Znext-solver=globally"),
|
||||||
|
@ -33,8 +33,8 @@ use rustc_middle::ty::{
|
|||||||
TyCtxt, TypeVisitableExt,
|
TyCtxt, TypeVisitableExt,
|
||||||
};
|
};
|
||||||
use rustc_middle::{bug, span_bug};
|
use rustc_middle::{bug, span_bug};
|
||||||
|
use rustc_span::ErrorGuaranteed;
|
||||||
use rustc_span::symbol::{kw, sym};
|
use rustc_span::symbol::{kw, sym};
|
||||||
use rustc_span::{ErrorGuaranteed, Symbol};
|
|
||||||
use tracing::{debug, instrument};
|
use tracing::{debug, instrument};
|
||||||
|
|
||||||
use crate::BorrowckInferCtxt;
|
use crate::BorrowckInferCtxt;
|
||||||
@ -524,7 +524,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
|||||||
|
|
||||||
let reg_vid = self
|
let reg_vid = self
|
||||||
.infcx
|
.infcx
|
||||||
.next_nll_region_var(FR, || RegionCtxt::Free(Symbol::intern("c-variadic")))
|
.next_nll_region_var(FR, || RegionCtxt::Free(sym::c_dash_variadic))
|
||||||
.as_var();
|
.as_var();
|
||||||
|
|
||||||
let region = ty::Region::new_var(self.infcx.tcx, reg_vid);
|
let region = ty::Region::new_var(self.infcx.tcx, reg_vid);
|
||||||
@ -540,10 +540,8 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let fr_fn_body = self
|
let fr_fn_body =
|
||||||
.infcx
|
self.infcx.next_nll_region_var(FR, || RegionCtxt::Free(sym::fn_body)).as_var();
|
||||||
.next_nll_region_var(FR, || RegionCtxt::Free(Symbol::intern("fn_body")))
|
|
||||||
.as_var();
|
|
||||||
|
|
||||||
let num_universals = self.infcx.num_region_vars();
|
let num_universals = self.infcx.num_region_vars();
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ fn create_jit_module(
|
|||||||
jit_builder.symbol("__clif_jit_fn", clif_jit_fn as *const u8);
|
jit_builder.symbol("__clif_jit_fn", clif_jit_fn as *const u8);
|
||||||
let mut jit_module = UnwindModule::new(JITModule::new(jit_builder), false);
|
let mut jit_module = UnwindModule::new(JITModule::new(jit_builder), false);
|
||||||
|
|
||||||
let cx = crate::CodegenCx::new(tcx, jit_module.isa(), false, Symbol::intern("dummy_cgu_name"));
|
let cx = crate::CodegenCx::new(tcx, jit_module.isa(), false, sym::dummy_cgu_name);
|
||||||
|
|
||||||
crate::allocator::codegen(tcx, &mut jit_module);
|
crate::allocator::codegen(tcx, &mut jit_module);
|
||||||
|
|
||||||
@ -276,12 +276,7 @@ fn jit_fn(instance_ptr: *const Instance<'static>, trampoline_ptr: *const u8) ->
|
|||||||
|
|
||||||
jit_module.module.prepare_for_function_redefine(func_id).unwrap();
|
jit_module.module.prepare_for_function_redefine(func_id).unwrap();
|
||||||
|
|
||||||
let mut cx = crate::CodegenCx::new(
|
let mut cx = crate::CodegenCx::new(tcx, jit_module.isa(), false, sym::dummy_cgu_name);
|
||||||
tcx,
|
|
||||||
jit_module.isa(),
|
|
||||||
false,
|
|
||||||
Symbol::intern("dummy_cgu_name"),
|
|
||||||
);
|
|
||||||
codegen_and_compile_fn(tcx, &mut cx, &mut Context::new(), jit_module, instance);
|
codegen_and_compile_fn(tcx, &mut cx, &mut Context::new(), jit_module, instance);
|
||||||
|
|
||||||
assert!(cx.global_asm.is_empty());
|
assert!(cx.global_asm.is_empty());
|
||||||
|
@ -189,18 +189,13 @@ impl CodegenBackend for CraneliftCodegenBackend {
|
|||||||
// FIXME return the actually used target features. this is necessary for #[cfg(target_feature)]
|
// FIXME return the actually used target features. this is necessary for #[cfg(target_feature)]
|
||||||
if sess.target.arch == "x86_64" && sess.target.os != "none" {
|
if sess.target.arch == "x86_64" && sess.target.os != "none" {
|
||||||
// x86_64 mandates SSE2 support
|
// x86_64 mandates SSE2 support
|
||||||
vec![Symbol::intern("fxsr"), sym::sse, Symbol::intern("sse2")]
|
vec![sym::fsxr, sym::sse, sym::sse2]
|
||||||
} else if sess.target.arch == "aarch64" {
|
} else if sess.target.arch == "aarch64" {
|
||||||
match &*sess.target.os {
|
match &*sess.target.os {
|
||||||
"none" => vec![],
|
"none" => vec![],
|
||||||
// On macOS the aes, sha2 and sha3 features are enabled by default and ring
|
// On macOS the aes, sha2 and sha3 features are enabled by default and ring
|
||||||
// fails to compile on macOS when they are not present.
|
// fails to compile on macOS when they are not present.
|
||||||
"macos" => vec![
|
"macos" => vec![sym::neon, sym::aes, sym::sha2, sym::sha3],
|
||||||
sym::neon,
|
|
||||||
Symbol::intern("aes"),
|
|
||||||
Symbol::intern("sha2"),
|
|
||||||
Symbol::intern("sha3"),
|
|
||||||
],
|
|
||||||
// AArch64 mandates Neon support
|
// AArch64 mandates Neon support
|
||||||
_ => vec![sym::neon],
|
_ => vec![sym::neon],
|
||||||
}
|
}
|
||||||
|
@ -394,6 +394,8 @@ declare_features! (
|
|||||||
(unstable, async_fn_track_caller, "1.73.0", Some(110011)),
|
(unstable, async_fn_track_caller, "1.73.0", Some(110011)),
|
||||||
/// Allows `for await` loops.
|
/// Allows `for await` loops.
|
||||||
(unstable, async_for_loop, "1.77.0", Some(118898)),
|
(unstable, async_for_loop, "1.77.0", Some(118898)),
|
||||||
|
/// Allows `async` trait bound modifier.
|
||||||
|
(unstable, async_trait_bounds, "CURRENT_RUSTC_VERSION", Some(62290)),
|
||||||
/// Allows using C-variadics.
|
/// Allows using C-variadics.
|
||||||
(unstable, c_variadic, "1.34.0", Some(44930)),
|
(unstable, c_variadic, "1.34.0", Some(44930)),
|
||||||
/// Allows the use of `#[cfg(<true/false>)]`.
|
/// Allows the use of `#[cfg(<true/false>)]`.
|
||||||
|
@ -419,7 +419,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
|
|||||||
if let Node::ConstBlock(_) = node {
|
if let Node::ConstBlock(_) = node {
|
||||||
own_params.push(ty::GenericParamDef {
|
own_params.push(ty::GenericParamDef {
|
||||||
index: next_index(),
|
index: next_index(),
|
||||||
name: Symbol::intern("<const_ty>"),
|
name: rustc_span::sym::const_ty_placeholder,
|
||||||
def_id: def_id.to_def_id(),
|
def_id: def_id.to_def_id(),
|
||||||
pure_wrt_drop: false,
|
pure_wrt_drop: false,
|
||||||
kind: ty::GenericParamDefKind::Type { has_default: false, synthetic: false },
|
kind: ty::GenericParamDefKind::Type { has_default: false, synthetic: false },
|
||||||
|
@ -307,7 +307,11 @@ impl<'tcx> HirTyLowerer<'tcx> for FnCtxt<'_, 'tcx> {
|
|||||||
ty::Alias(ty::Projection | ty::Inherent | ty::Weak, _)
|
ty::Alias(ty::Projection | ty::Inherent | ty::Weak, _)
|
||||||
if !ty.has_escaping_bound_vars() =>
|
if !ty.has_escaping_bound_vars() =>
|
||||||
{
|
{
|
||||||
self.normalize(span, ty).ty_adt_def()
|
if self.next_trait_solver() {
|
||||||
|
self.try_structurally_resolve_type(span, ty).ty_adt_def()
|
||||||
|
} else {
|
||||||
|
self.normalize(span, ty).ty_adt_def()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
|
@ -664,7 +664,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
let is_write = sugg_span.ctxt().outer_expn_data().macro_def_id.is_some_and(|def_id| {
|
let is_write = sugg_span.ctxt().outer_expn_data().macro_def_id.is_some_and(|def_id| {
|
||||||
tcx.is_diagnostic_item(sym::write_macro, def_id)
|
tcx.is_diagnostic_item(sym::write_macro, def_id)
|
||||||
|| tcx.is_diagnostic_item(sym::writeln_macro, def_id)
|
|| tcx.is_diagnostic_item(sym::writeln_macro, def_id)
|
||||||
}) && item_name.name == Symbol::intern("write_fmt");
|
}) && item_name.name == sym::write_fmt;
|
||||||
let mut err = if is_write && let SelfSource::MethodCall(rcvr_expr) = source {
|
let mut err = if is_write && let SelfSource::MethodCall(rcvr_expr) = source {
|
||||||
self.suggest_missing_writer(rcvr_ty, rcvr_expr)
|
self.suggest_missing_writer(rcvr_ty, rcvr_expr)
|
||||||
} else {
|
} else {
|
||||||
|
@ -775,6 +775,9 @@ lint_suspicious_double_ref_clone =
|
|||||||
lint_suspicious_double_ref_deref =
|
lint_suspicious_double_ref_deref =
|
||||||
using `.deref()` on a double reference, which returns `{$ty}` instead of dereferencing the inner type
|
using `.deref()` on a double reference, which returns `{$ty}` instead of dereferencing the inner type
|
||||||
|
|
||||||
|
lint_symbol_intern_string_literal = using `Symbol::intern` on a string literal
|
||||||
|
.help = consider adding the symbol to `compiler/rustc_span/src/symbol.rs`
|
||||||
|
|
||||||
lint_trailing_semi_macro = trailing semicolon in macro used in expression position
|
lint_trailing_semi_macro = trailing semicolon in macro used in expression position
|
||||||
.note1 = macro invocations at the end of a block are treated as expressions
|
.note1 = macro invocations at the end of a block are treated as expressions
|
||||||
.note2 = to ignore the value produced by the macro, add a semicolon after the invocation of `{$name}`
|
.note2 = to ignore the value produced by the macro, add a semicolon after the invocation of `{$name}`
|
||||||
|
@ -103,8 +103,11 @@ fn expr_parent_is_else(tcx: TyCtxt<'_>, hir_id: hir::HirId) -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn expr_parent_is_stmt(tcx: TyCtxt<'_>, hir_id: hir::HirId) -> bool {
|
fn expr_parent_is_stmt(tcx: TyCtxt<'_>, hir_id: hir::HirId) -> bool {
|
||||||
let Some((_, hir::Node::Stmt(stmt))) = tcx.hir().parent_iter(hir_id).next() else {
|
let mut parents = tcx.hir().parent_iter(hir_id);
|
||||||
return false;
|
let stmt = match parents.next() {
|
||||||
|
Some((_, hir::Node::Stmt(stmt))) => stmt,
|
||||||
|
Some((_, hir::Node::Block(_) | hir::Node::Arm(_))) => return true,
|
||||||
|
_ => return false,
|
||||||
};
|
};
|
||||||
let (hir::StmtKind::Semi(expr) | hir::StmtKind::Expr(expr)) = stmt.kind else { return false };
|
let (hir::StmtKind::Semi(expr) | hir::StmtKind::Expr(expr)) = stmt.kind else { return false };
|
||||||
expr.hir_id == hir_id
|
expr.hir_id == hir_id
|
||||||
|
@ -17,8 +17,9 @@ use tracing::debug;
|
|||||||
|
|
||||||
use crate::lints::{
|
use crate::lints::{
|
||||||
BadOptAccessDiag, DefaultHashTypesDiag, DiagOutOfImpl, LintPassByHand, NonExistentDocKeyword,
|
BadOptAccessDiag, DefaultHashTypesDiag, DiagOutOfImpl, LintPassByHand, NonExistentDocKeyword,
|
||||||
NonGlobImportTypeIrInherent, QueryInstability, QueryUntracked, SpanUseEqCtxtDiag, TyQualified,
|
NonGlobImportTypeIrInherent, QueryInstability, QueryUntracked, SpanUseEqCtxtDiag,
|
||||||
TykindDiag, TykindKind, TypeIrInherentUsage, UntranslatableDiag,
|
SymbolInternStringLiteralDiag, TyQualified, TykindDiag, TykindKind, TypeIrInherentUsage,
|
||||||
|
UntranslatableDiag,
|
||||||
};
|
};
|
||||||
use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
|
use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
|
||||||
|
|
||||||
@ -650,3 +651,33 @@ fn is_span_ctxt_call(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
|
|||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declare_tool_lint! {
|
||||||
|
/// The `symbol_intern_string_literal` detects `Symbol::intern` being called on a string literal
|
||||||
|
pub rustc::SYMBOL_INTERN_STRING_LITERAL,
|
||||||
|
// rustc_driver crates out of the compiler can't/shouldn't add preinterned symbols;
|
||||||
|
// bootstrap will deny this manually
|
||||||
|
Allow,
|
||||||
|
"Forbid uses of string literals in `Symbol::intern`, suggesting preinterning instead",
|
||||||
|
report_in_external_macro: true
|
||||||
|
}
|
||||||
|
|
||||||
|
declare_lint_pass!(SymbolInternStringLiteral => [SYMBOL_INTERN_STRING_LITERAL]);
|
||||||
|
|
||||||
|
impl<'tcx> LateLintPass<'tcx> for SymbolInternStringLiteral {
|
||||||
|
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx rustc_hir::Expr<'tcx>) {
|
||||||
|
if let ExprKind::Call(path, [arg]) = expr.kind
|
||||||
|
&& let ExprKind::Path(ref qpath) = path.kind
|
||||||
|
&& let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id()
|
||||||
|
&& cx.tcx.is_diagnostic_item(sym::SymbolIntern, def_id)
|
||||||
|
&& let ExprKind::Lit(kind) = arg.kind
|
||||||
|
&& let rustc_ast::LitKind::Str(_, _) = kind.node
|
||||||
|
{
|
||||||
|
cx.emit_span_lint(
|
||||||
|
SYMBOL_INTERN_STRING_LITERAL,
|
||||||
|
kind.span,
|
||||||
|
SymbolInternStringLiteralDiag,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -614,6 +614,8 @@ fn register_internals(store: &mut LintStore) {
|
|||||||
store.register_late_mod_pass(|_| Box::new(PassByValue));
|
store.register_late_mod_pass(|_| Box::new(PassByValue));
|
||||||
store.register_lints(&SpanUseEqCtxt::lint_vec());
|
store.register_lints(&SpanUseEqCtxt::lint_vec());
|
||||||
store.register_late_mod_pass(|_| Box::new(SpanUseEqCtxt));
|
store.register_late_mod_pass(|_| Box::new(SpanUseEqCtxt));
|
||||||
|
store.register_lints(&SymbolInternStringLiteral::lint_vec());
|
||||||
|
store.register_late_mod_pass(|_| Box::new(SymbolInternStringLiteral));
|
||||||
// FIXME(davidtwco): deliberately do not include `UNTRANSLATABLE_DIAGNOSTIC` and
|
// FIXME(davidtwco): deliberately do not include `UNTRANSLATABLE_DIAGNOSTIC` and
|
||||||
// `DIAGNOSTIC_OUTSIDE_OF_IMPL` here because `-Wrustc::internal` is provided to every crate and
|
// `DIAGNOSTIC_OUTSIDE_OF_IMPL` here because `-Wrustc::internal` is provided to every crate and
|
||||||
// these lints will trigger all of the time - change this once migration to diagnostic structs
|
// these lints will trigger all of the time - change this once migration to diagnostic structs
|
||||||
|
@ -907,6 +907,11 @@ pub(crate) struct QueryUntracked {
|
|||||||
#[diag(lint_span_use_eq_ctxt)]
|
#[diag(lint_span_use_eq_ctxt)]
|
||||||
pub(crate) struct SpanUseEqCtxtDiag;
|
pub(crate) struct SpanUseEqCtxtDiag;
|
||||||
|
|
||||||
|
#[derive(LintDiagnostic)]
|
||||||
|
#[diag(lint_symbol_intern_string_literal)]
|
||||||
|
#[help]
|
||||||
|
pub(crate) struct SymbolInternStringLiteralDiag;
|
||||||
|
|
||||||
#[derive(LintDiagnostic)]
|
#[derive(LintDiagnostic)]
|
||||||
#[diag(lint_tykind_kind)]
|
#[diag(lint_tykind_kind)]
|
||||||
pub(crate) struct TykindKind {
|
pub(crate) struct TykindKind {
|
||||||
|
@ -1563,7 +1563,7 @@ impl UnusedImportBraces {
|
|||||||
}
|
}
|
||||||
rename.unwrap_or(orig_ident).name
|
rename.unwrap_or(orig_ident).name
|
||||||
}
|
}
|
||||||
ast::UseTreeKind::Glob => Symbol::intern("*"),
|
ast::UseTreeKind::Glob => sym::asterisk,
|
||||||
ast::UseTreeKind::Nested { .. } => return,
|
ast::UseTreeKind::Nested { .. } => return,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -861,8 +861,10 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
|
|||||||
// First up we check for global allocators. Look at the crate graph here
|
// First up we check for global allocators. Look at the crate graph here
|
||||||
// and see what's a global allocator, including if we ourselves are a
|
// and see what's a global allocator, including if we ourselves are a
|
||||||
// global allocator.
|
// global allocator.
|
||||||
let mut global_allocator =
|
#[cfg_attr(not(bootstrap), allow(rustc::symbol_intern_string_literal))]
|
||||||
self.cstore.has_global_allocator.then(|| Symbol::intern("this crate"));
|
let this_crate = Symbol::intern("this crate");
|
||||||
|
|
||||||
|
let mut global_allocator = self.cstore.has_global_allocator.then_some(this_crate);
|
||||||
for (_, data) in self.cstore.iter_crate_data() {
|
for (_, data) in self.cstore.iter_crate_data() {
|
||||||
if data.has_global_allocator() {
|
if data.has_global_allocator() {
|
||||||
match global_allocator {
|
match global_allocator {
|
||||||
@ -876,8 +878,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let mut alloc_error_handler =
|
let mut alloc_error_handler = self.cstore.has_alloc_error_handler.then_some(this_crate);
|
||||||
self.cstore.has_alloc_error_handler.then(|| Symbol::intern("this crate"));
|
|
||||||
for (_, data) in self.cstore.iter_crate_data() {
|
for (_, data) in self.cstore.iter_crate_data() {
|
||||||
if data.has_alloc_error_handler() {
|
if data.has_alloc_error_handler() {
|
||||||
match alloc_error_handler {
|
match alloc_error_handler {
|
||||||
|
@ -872,6 +872,7 @@ impl MetadataBlob {
|
|||||||
|
|
||||||
let def_kind = root.tables.def_kind.get(blob, item).unwrap();
|
let def_kind = root.tables.def_kind.get(blob, item).unwrap();
|
||||||
let def_key = root.tables.def_keys.get(blob, item).unwrap().decode(blob);
|
let def_key = root.tables.def_keys.get(blob, item).unwrap().decode(blob);
|
||||||
|
#[cfg_attr(not(bootstrap), allow(rustc::symbol_intern_string_literal))]
|
||||||
let def_name = if item == CRATE_DEF_INDEX {
|
let def_name = if item == CRATE_DEF_INDEX {
|
||||||
rustc_span::symbol::kw::Crate
|
rustc_span::symbol::kw::Crate
|
||||||
} else {
|
} else {
|
||||||
|
@ -1389,10 +1389,14 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
|||||||
// `ConstArgKind::Path`. We never actually access this `DefId`
|
// `ConstArgKind::Path`. We never actually access this `DefId`
|
||||||
// anywhere so we don't need to encode it for other crates.
|
// anywhere so we don't need to encode it for other crates.
|
||||||
if def_kind == DefKind::AnonConst
|
if def_kind == DefKind::AnonConst
|
||||||
&& matches!(
|
&& match tcx.hir_node_by_def_id(local_id) {
|
||||||
tcx.hir_node_by_def_id(local_id),
|
hir::Node::ConstArg(hir::ConstArg { kind, .. }) => match kind {
|
||||||
hir::Node::ConstArg(hir::ConstArg { kind: hir::ConstArgKind::Path(..), .. })
|
// Skip encoding defs for these as they should not have had a `DefId` created
|
||||||
)
|
hir::ConstArgKind::Path(..) | hir::ConstArgKind::Infer(..) => true,
|
||||||
|
hir::ConstArgKind::Anon(..) => false,
|
||||||
|
},
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ use rustc_ast::{
|
|||||||
};
|
};
|
||||||
use rustc_errors::{Applicability, PResult};
|
use rustc_errors::{Applicability, PResult};
|
||||||
use rustc_span::symbol::{Ident, kw, sym};
|
use rustc_span::symbol::{Ident, kw, sym};
|
||||||
use rustc_span::{ErrorGuaranteed, Span, Symbol};
|
use rustc_span::{ErrorGuaranteed, Span};
|
||||||
use thin_vec::{ThinVec, thin_vec};
|
use thin_vec::{ThinVec, thin_vec};
|
||||||
|
|
||||||
use super::{Parser, PathStyle, SeqSep, TokenType, Trailing};
|
use super::{Parser, PathStyle, SeqSep, TokenType, Trailing};
|
||||||
@ -940,7 +940,7 @@ impl<'a> Parser<'a> {
|
|||||||
let asyncness = if self.token.uninterpolated_span().at_least_rust_2018()
|
let asyncness = if self.token.uninterpolated_span().at_least_rust_2018()
|
||||||
&& self.eat_keyword(kw::Async)
|
&& self.eat_keyword(kw::Async)
|
||||||
{
|
{
|
||||||
self.psess.gated_spans.gate(sym::async_closure, self.prev_token.span);
|
self.psess.gated_spans.gate(sym::async_trait_bounds, self.prev_token.span);
|
||||||
BoundAsyncness::Async(self.prev_token.span)
|
BoundAsyncness::Async(self.prev_token.span)
|
||||||
} else if self.may_recover()
|
} else if self.may_recover()
|
||||||
&& self.token.uninterpolated_span().is_rust_2015()
|
&& self.token.uninterpolated_span().is_rust_2015()
|
||||||
@ -951,7 +951,7 @@ impl<'a> Parser<'a> {
|
|||||||
span: self.prev_token.span,
|
span: self.prev_token.span,
|
||||||
help: HelpUseLatestEdition::new(),
|
help: HelpUseLatestEdition::new(),
|
||||||
});
|
});
|
||||||
self.psess.gated_spans.gate(sym::async_closure, self.prev_token.span);
|
self.psess.gated_spans.gate(sym::async_trait_bounds, self.prev_token.span);
|
||||||
BoundAsyncness::Async(self.prev_token.span)
|
BoundAsyncness::Async(self.prev_token.span)
|
||||||
} else {
|
} else {
|
||||||
BoundAsyncness::Normal
|
BoundAsyncness::Normal
|
||||||
@ -1136,7 +1136,7 @@ impl<'a> Parser<'a> {
|
|||||||
Some(ast::Path {
|
Some(ast::Path {
|
||||||
span: fn_token_span.to(self.prev_token.span),
|
span: fn_token_span.to(self.prev_token.span),
|
||||||
segments: thin_vec![ast::PathSegment {
|
segments: thin_vec![ast::PathSegment {
|
||||||
ident: Ident::new(Symbol::intern("Fn"), fn_token_span),
|
ident: Ident::new(sym::Fn, fn_token_span),
|
||||||
id: DUMMY_NODE_ID,
|
id: DUMMY_NODE_ID,
|
||||||
args: Some(P(ast::GenericArgs::Parenthesized(ast::ParenthesizedArgs {
|
args: Some(P(ast::GenericArgs::Parenthesized(ast::ParenthesizedArgs {
|
||||||
span: args_lo.to(self.prev_token.span),
|
span: args_lo.to(self.prev_token.span),
|
||||||
|
@ -3113,6 +3113,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg_attr(not(bootstrap), allow(rustc::symbol_intern_string_literal))]
|
||||||
let existing_name = match &in_scope_lifetimes[..] {
|
let existing_name = match &in_scope_lifetimes[..] {
|
||||||
[] => Symbol::intern("'a"),
|
[] => Symbol::intern("'a"),
|
||||||
[(existing, _)] => existing.name,
|
[(existing, _)] => existing.name,
|
||||||
|
@ -2257,7 +2257,7 @@ fn module_to_string(module: Module<'_>) -> Option<String> {
|
|||||||
collect_mod(names, parent);
|
collect_mod(names, parent);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
names.push(Symbol::intern("<opaque>"));
|
names.push(sym::opaque_module_name_placeholder);
|
||||||
collect_mod(names, module.parent.unwrap());
|
collect_mod(names, module.parent.unwrap());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -87,7 +87,7 @@ pub fn find_crate_name(sess: &Session, attrs: &[ast::Attribute]) -> Symbol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Symbol::intern("rust_out")
|
sym::rust_out
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn validate_crate_name(sess: &Session, s: Symbol, sp: Option<Span>) {
|
pub fn validate_crate_name(sess: &Session, s: Symbol, sp: Option<Span>) {
|
||||||
|
@ -298,6 +298,7 @@ symbols! {
|
|||||||
Return,
|
Return,
|
||||||
Right,
|
Right,
|
||||||
Rust,
|
Rust,
|
||||||
|
RustaceansAreAwesome,
|
||||||
RustcDecodable,
|
RustcDecodable,
|
||||||
RustcEncodable,
|
RustcEncodable,
|
||||||
RwLock,
|
RwLock,
|
||||||
@ -316,6 +317,7 @@ symbols! {
|
|||||||
StructuralPartialEq,
|
StructuralPartialEq,
|
||||||
SubdiagMessage,
|
SubdiagMessage,
|
||||||
Subdiagnostic,
|
Subdiagnostic,
|
||||||
|
SymbolIntern,
|
||||||
Sync,
|
Sync,
|
||||||
SyncUnsafeCell,
|
SyncUnsafeCell,
|
||||||
T,
|
T,
|
||||||
@ -377,6 +379,7 @@ symbols! {
|
|||||||
adt_const_params,
|
adt_const_params,
|
||||||
advanced_slice_patterns,
|
advanced_slice_patterns,
|
||||||
adx_target_feature,
|
adx_target_feature,
|
||||||
|
aes,
|
||||||
aggregate_raw_ptr,
|
aggregate_raw_ptr,
|
||||||
alias,
|
alias,
|
||||||
align,
|
align,
|
||||||
@ -440,6 +443,7 @@ symbols! {
|
|||||||
associated_types,
|
associated_types,
|
||||||
assume,
|
assume,
|
||||||
assume_init,
|
assume_init,
|
||||||
|
asterisk: "*",
|
||||||
async_await,
|
async_await,
|
||||||
async_call,
|
async_call,
|
||||||
async_call_mut,
|
async_call_mut,
|
||||||
@ -468,6 +472,7 @@ symbols! {
|
|||||||
async_for_loop,
|
async_for_loop,
|
||||||
async_iterator,
|
async_iterator,
|
||||||
async_iterator_poll_next,
|
async_iterator_poll_next,
|
||||||
|
async_trait_bounds,
|
||||||
atomic,
|
atomic,
|
||||||
atomic_mod,
|
atomic_mod,
|
||||||
atomics,
|
atomics,
|
||||||
@ -520,6 +525,7 @@ symbols! {
|
|||||||
btreeset_iter,
|
btreeset_iter,
|
||||||
builtin_syntax,
|
builtin_syntax,
|
||||||
c,
|
c,
|
||||||
|
c_dash_variadic,
|
||||||
c_str,
|
c_str,
|
||||||
c_str_literals,
|
c_str_literals,
|
||||||
c_unwind,
|
c_unwind,
|
||||||
@ -650,6 +656,7 @@ symbols! {
|
|||||||
const_trait_bound_opt_out,
|
const_trait_bound_opt_out,
|
||||||
const_trait_impl,
|
const_trait_impl,
|
||||||
const_try,
|
const_try,
|
||||||
|
const_ty_placeholder: "<const_ty>",
|
||||||
constant,
|
constant,
|
||||||
constructor,
|
constructor,
|
||||||
convert_identity,
|
convert_identity,
|
||||||
@ -779,6 +786,7 @@ symbols! {
|
|||||||
drop_types_in_const,
|
drop_types_in_const,
|
||||||
dropck_eyepatch,
|
dropck_eyepatch,
|
||||||
dropck_parametricity,
|
dropck_parametricity,
|
||||||
|
dummy_cgu_name,
|
||||||
dylib,
|
dylib,
|
||||||
dyn_compatible_for_dispatch,
|
dyn_compatible_for_dispatch,
|
||||||
dyn_metadata,
|
dyn_metadata,
|
||||||
@ -922,6 +930,7 @@ symbols! {
|
|||||||
fmuladdf32,
|
fmuladdf32,
|
||||||
fmuladdf64,
|
fmuladdf64,
|
||||||
fn_align,
|
fn_align,
|
||||||
|
fn_body,
|
||||||
fn_delegation,
|
fn_delegation,
|
||||||
fn_must_use,
|
fn_must_use,
|
||||||
fn_mut,
|
fn_mut,
|
||||||
@ -962,6 +971,7 @@ symbols! {
|
|||||||
fs_create_dir,
|
fs_create_dir,
|
||||||
fsub_algebraic,
|
fsub_algebraic,
|
||||||
fsub_fast,
|
fsub_fast,
|
||||||
|
fsxr,
|
||||||
full,
|
full,
|
||||||
fundamental,
|
fundamental,
|
||||||
fused_iterator,
|
fused_iterator,
|
||||||
@ -1385,6 +1395,7 @@ symbols! {
|
|||||||
on,
|
on,
|
||||||
on_unimplemented,
|
on_unimplemented,
|
||||||
opaque,
|
opaque,
|
||||||
|
opaque_module_name_placeholder: "<opaque>",
|
||||||
open_options_new,
|
open_options_new,
|
||||||
ops,
|
ops,
|
||||||
opt_out_copy,
|
opt_out_copy,
|
||||||
@ -1654,6 +1665,7 @@ symbols! {
|
|||||||
rust_eh_catch_typeinfo,
|
rust_eh_catch_typeinfo,
|
||||||
rust_eh_personality,
|
rust_eh_personality,
|
||||||
rust_logo,
|
rust_logo,
|
||||||
|
rust_out,
|
||||||
rustc,
|
rustc,
|
||||||
rustc_abi,
|
rustc_abi,
|
||||||
rustc_allocator,
|
rustc_allocator,
|
||||||
@ -1776,6 +1788,8 @@ symbols! {
|
|||||||
self_in_typedefs,
|
self_in_typedefs,
|
||||||
self_struct_ctor,
|
self_struct_ctor,
|
||||||
semitransparent,
|
semitransparent,
|
||||||
|
sha2,
|
||||||
|
sha3,
|
||||||
sha512_sm_x86,
|
sha512_sm_x86,
|
||||||
shadow_call_stack,
|
shadow_call_stack,
|
||||||
shallow,
|
shallow,
|
||||||
@ -1890,6 +1904,7 @@ symbols! {
|
|||||||
sreg,
|
sreg,
|
||||||
sreg_low16,
|
sreg_low16,
|
||||||
sse,
|
sse,
|
||||||
|
sse2,
|
||||||
sse4a_target_feature,
|
sse4a_target_feature,
|
||||||
stable,
|
stable,
|
||||||
staged_api,
|
staged_api,
|
||||||
@ -2177,6 +2192,7 @@ symbols! {
|
|||||||
wrapping_sub,
|
wrapping_sub,
|
||||||
wreg,
|
wreg,
|
||||||
write_bytes,
|
write_bytes,
|
||||||
|
write_fmt,
|
||||||
write_macro,
|
write_macro,
|
||||||
write_str,
|
write_str,
|
||||||
write_via_move,
|
write_via_move,
|
||||||
@ -2406,6 +2422,7 @@ impl Symbol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Maps a string to its interned representation.
|
/// Maps a string to its interned representation.
|
||||||
|
#[rustc_diagnostic_item = "SymbolIntern"]
|
||||||
pub fn intern(string: &str) -> Self {
|
pub fn intern(string: &str) -> Self {
|
||||||
with_session_globals(|session_globals| session_globals.symbol_interner.intern(string))
|
with_session_globals(|session_globals| session_globals.symbol_interner.intern(string))
|
||||||
}
|
}
|
||||||
|
@ -794,7 +794,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||||||
closure_def_id,
|
closure_def_id,
|
||||||
found_kind,
|
found_kind,
|
||||||
expected_kind,
|
expected_kind,
|
||||||
"async ",
|
"Async",
|
||||||
);
|
);
|
||||||
self.note_obligation_cause(&mut err, &obligation);
|
self.note_obligation_cause(&mut err, &obligation);
|
||||||
self.point_at_returns_when_relevant(&mut err, &obligation);
|
self.point_at_returns_when_relevant(&mut err, &obligation);
|
||||||
|
@ -18,7 +18,6 @@ use rustc_middle::ty::{
|
|||||||
TypeVisitableExt, TypeVisitor, TypingMode, Upcast,
|
TypeVisitableExt, TypeVisitor, TypingMode, Upcast,
|
||||||
};
|
};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use rustc_span::symbol::Symbol;
|
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use tracing::{debug, instrument};
|
use tracing::{debug, instrument};
|
||||||
|
|
||||||
@ -679,7 +678,7 @@ fn receiver_is_dispatchable<'tcx>(
|
|||||||
// FIXME(mikeyhew) this is a total hack. Once dyn_compatible_for_dispatch is stabilized, we can
|
// FIXME(mikeyhew) this is a total hack. Once dyn_compatible_for_dispatch is stabilized, we can
|
||||||
// replace this with `dyn Trait`
|
// replace this with `dyn Trait`
|
||||||
let unsized_self_ty: Ty<'tcx> =
|
let unsized_self_ty: Ty<'tcx> =
|
||||||
Ty::new_param(tcx, u32::MAX, Symbol::intern("RustaceansAreAwesome"));
|
Ty::new_param(tcx, u32::MAX, rustc_span::sym::RustaceansAreAwesome);
|
||||||
|
|
||||||
// `Receiver[Self => U]`
|
// `Receiver[Self => U]`
|
||||||
let unsized_receiver_ty =
|
let unsized_receiver_ty =
|
||||||
|
@ -179,6 +179,7 @@ impl Layout {
|
|||||||
/// or other unsized type like a slice).
|
/// or other unsized type like a slice).
|
||||||
#[stable(feature = "alloc_layout", since = "1.28.0")]
|
#[stable(feature = "alloc_layout", since = "1.28.0")]
|
||||||
#[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")]
|
#[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")]
|
||||||
|
#[rustc_const_stable_indirect]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn for_value<T: ?Sized>(t: &T) -> Self {
|
pub const fn for_value<T: ?Sized>(t: &T) -> Self {
|
||||||
@ -215,7 +216,6 @@ impl Layout {
|
|||||||
/// [trait object]: ../../book/ch17-02-trait-objects.html
|
/// [trait object]: ../../book/ch17-02-trait-objects.html
|
||||||
/// [extern type]: ../../unstable-book/language-features/extern-types.html
|
/// [extern type]: ../../unstable-book/language-features/extern-types.html
|
||||||
#[unstable(feature = "layout_for_ptr", issue = "69835")]
|
#[unstable(feature = "layout_for_ptr", issue = "69835")]
|
||||||
#[rustc_const_unstable(feature = "layout_for_ptr", issue = "69835")]
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub const unsafe fn for_value_raw<T: ?Sized>(t: *const T) -> Self {
|
pub const unsafe fn for_value_raw<T: ?Sized>(t: *const T) -> Self {
|
||||||
// SAFETY: we pass along the prerequisites of these functions to the caller
|
// SAFETY: we pass along the prerequisites of these functions to the caller
|
||||||
|
@ -752,10 +752,10 @@ pub struct BuildHasherDefault<H>(marker::PhantomData<fn() -> H>);
|
|||||||
|
|
||||||
impl<H> BuildHasherDefault<H> {
|
impl<H> BuildHasherDefault<H> {
|
||||||
/// Creates a new BuildHasherDefault for Hasher `H`.
|
/// Creates a new BuildHasherDefault for Hasher `H`.
|
||||||
#[unstable(
|
#[stable(feature = "build_hasher_default_const_new", since = "CURRENT_RUSTC_VERSION")]
|
||||||
|
#[rustc_const_stable(
|
||||||
feature = "build_hasher_default_const_new",
|
feature = "build_hasher_default_const_new",
|
||||||
issue = "123197",
|
since = "CURRENT_RUSTC_VERSION"
|
||||||
reason = "recently added"
|
|
||||||
)]
|
)]
|
||||||
pub const fn new() -> Self {
|
pub const fn new() -> Self {
|
||||||
BuildHasherDefault(marker::PhantomData)
|
BuildHasherDefault(marker::PhantomData)
|
||||||
|
@ -4099,6 +4099,7 @@ pub const fn variant_count<T>() -> usize {
|
|||||||
#[unstable(feature = "core_intrinsics", issue = "none")]
|
#[unstable(feature = "core_intrinsics", issue = "none")]
|
||||||
#[rustc_intrinsic]
|
#[rustc_intrinsic]
|
||||||
#[rustc_intrinsic_must_be_overridden]
|
#[rustc_intrinsic_must_be_overridden]
|
||||||
|
#[rustc_intrinsic_const_stable_indirect]
|
||||||
pub const unsafe fn size_of_val<T: ?Sized>(_ptr: *const T) -> usize {
|
pub const unsafe fn size_of_val<T: ?Sized>(_ptr: *const T) -> usize {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
@ -4114,6 +4115,7 @@ pub const unsafe fn size_of_val<T: ?Sized>(_ptr: *const T) -> usize {
|
|||||||
#[unstable(feature = "core_intrinsics", issue = "none")]
|
#[unstable(feature = "core_intrinsics", issue = "none")]
|
||||||
#[rustc_intrinsic]
|
#[rustc_intrinsic]
|
||||||
#[rustc_intrinsic_must_be_overridden]
|
#[rustc_intrinsic_must_be_overridden]
|
||||||
|
#[rustc_intrinsic_const_stable_indirect]
|
||||||
pub const unsafe fn min_align_of_val<T: ?Sized>(_ptr: *const T) -> usize {
|
pub const unsafe fn min_align_of_val<T: ?Sized>(_ptr: *const T) -> usize {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
|
@ -333,7 +333,7 @@ pub const fn size_of<T>() -> usize {
|
|||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[rustc_const_unstable(feature = "const_size_of_val", issue = "46571")]
|
#[rustc_const_stable(feature = "const_size_of_val", since = "CURRENT_RUSTC_VERSION")]
|
||||||
#[cfg_attr(not(test), rustc_diagnostic_item = "mem_size_of_val")]
|
#[cfg_attr(not(test), rustc_diagnostic_item = "mem_size_of_val")]
|
||||||
pub const fn size_of_val<T: ?Sized>(val: &T) -> usize {
|
pub const fn size_of_val<T: ?Sized>(val: &T) -> usize {
|
||||||
// SAFETY: `val` is a reference, so it's a valid raw pointer
|
// SAFETY: `val` is a reference, so it's a valid raw pointer
|
||||||
@ -390,7 +390,6 @@ pub const fn size_of_val<T: ?Sized>(val: &T) -> usize {
|
|||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[unstable(feature = "layout_for_ptr", issue = "69835")]
|
#[unstable(feature = "layout_for_ptr", issue = "69835")]
|
||||||
#[rustc_const_unstable(feature = "const_size_of_val_raw", issue = "46571")]
|
|
||||||
pub const unsafe fn size_of_val_raw<T: ?Sized>(val: *const T) -> usize {
|
pub const unsafe fn size_of_val_raw<T: ?Sized>(val: *const T) -> usize {
|
||||||
// SAFETY: the caller must provide a valid raw pointer
|
// SAFETY: the caller must provide a valid raw pointer
|
||||||
unsafe { intrinsics::size_of_val(val) }
|
unsafe { intrinsics::size_of_val(val) }
|
||||||
@ -485,7 +484,7 @@ pub const fn align_of<T>() -> usize {
|
|||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[rustc_const_unstable(feature = "const_align_of_val", issue = "46571")]
|
#[rustc_const_stable(feature = "const_align_of_val", since = "CURRENT_RUSTC_VERSION")]
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
pub const fn align_of_val<T: ?Sized>(val: &T) -> usize {
|
pub const fn align_of_val<T: ?Sized>(val: &T) -> usize {
|
||||||
// SAFETY: val is a reference, so it's a valid raw pointer
|
// SAFETY: val is a reference, so it's a valid raw pointer
|
||||||
@ -534,7 +533,6 @@ pub const fn align_of_val<T: ?Sized>(val: &T) -> usize {
|
|||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[unstable(feature = "layout_for_ptr", issue = "69835")]
|
#[unstable(feature = "layout_for_ptr", issue = "69835")]
|
||||||
#[rustc_const_unstable(feature = "const_align_of_val_raw", issue = "46571")]
|
|
||||||
pub const unsafe fn align_of_val_raw<T: ?Sized>(val: *const T) -> usize {
|
pub const unsafe fn align_of_val_raw<T: ?Sized>(val: *const T) -> usize {
|
||||||
// SAFETY: the caller must provide a valid raw pointer
|
// SAFETY: the caller must provide a valid raw pointer
|
||||||
unsafe { intrinsics::min_align_of_val(val) }
|
unsafe { intrinsics::min_align_of_val(val) }
|
||||||
|
@ -2445,7 +2445,7 @@ macro_rules! uint_impl {
|
|||||||
// to generate optimal code for now, and LLVM doesn't have an equivalent intrinsic
|
// to generate optimal code for now, and LLVM doesn't have an equivalent intrinsic
|
||||||
let (a, b) = self.overflowing_sub(rhs);
|
let (a, b) = self.overflowing_sub(rhs);
|
||||||
let (c, d) = a.overflowing_sub(borrow as $SelfT);
|
let (c, d) = a.overflowing_sub(borrow as $SelfT);
|
||||||
(c, b || d)
|
(c, b | d)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Calculates `self` - `rhs` with a signed `rhs`
|
/// Calculates `self` - `rhs` with a signed `rhs`
|
||||||
|
@ -13,7 +13,6 @@
|
|||||||
#![feature(bigint_helper_methods)]
|
#![feature(bigint_helper_methods)]
|
||||||
#![feature(cell_update)]
|
#![feature(cell_update)]
|
||||||
#![feature(clone_to_uninit)]
|
#![feature(clone_to_uninit)]
|
||||||
#![feature(const_align_of_val_raw)]
|
|
||||||
#![feature(const_black_box)]
|
#![feature(const_black_box)]
|
||||||
#![feature(const_eval_select)]
|
#![feature(const_eval_select)]
|
||||||
#![feature(const_nonnull_new)]
|
#![feature(const_nonnull_new)]
|
||||||
|
@ -204,6 +204,25 @@ use crate::ops::Index;
|
|||||||
/// println!("{viking:?} has {health} hp");
|
/// println!("{viking:?} has {health} hp");
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
///
|
||||||
|
/// # Usage in `const` and `static`
|
||||||
|
///
|
||||||
|
/// As explained above, `HashMap` is randomly seeded: each `HashMap` instance uses a different seed,
|
||||||
|
/// which means that `HashMap::new` cannot be used in const context. To construct a `HashMap` in the
|
||||||
|
/// initializer of a `const` or `static` item, you will have to use a different hasher that does not
|
||||||
|
/// involve a random seed, as demonstrated in the following example. **A `HashMap` constructed this
|
||||||
|
/// way is not resistant against HashDoS!**
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use std::collections::HashMap;
|
||||||
|
/// use std::hash::{BuildHasherDefault, DefaultHasher};
|
||||||
|
/// use std::sync::Mutex;
|
||||||
|
///
|
||||||
|
/// const EMPTY_MAP: HashMap<String, Vec<i32>, BuildHasherDefault<DefaultHasher>> =
|
||||||
|
/// HashMap::with_hasher(BuildHasherDefault::new());
|
||||||
|
/// static MAP: Mutex<HashMap<String, Vec<i32>, BuildHasherDefault<DefaultHasher>>> =
|
||||||
|
/// Mutex::new(HashMap::with_hasher(BuildHasherDefault::new()));
|
||||||
|
/// ```
|
||||||
|
|
||||||
#[cfg_attr(not(test), rustc_diagnostic_item = "HashMap")]
|
#[cfg_attr(not(test), rustc_diagnostic_item = "HashMap")]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
@ -277,7 +296,10 @@ impl<K, V, S> HashMap<K, V, S> {
|
|||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
#[stable(feature = "hashmap_build_hasher", since = "1.7.0")]
|
#[stable(feature = "hashmap_build_hasher", since = "1.7.0")]
|
||||||
#[rustc_const_unstable(feature = "const_collections_with_hasher", issue = "102575")]
|
#[rustc_const_stable(
|
||||||
|
feature = "const_collections_with_hasher",
|
||||||
|
since = "CURRENT_RUSTC_VERSION"
|
||||||
|
)]
|
||||||
pub const fn with_hasher(hash_builder: S) -> HashMap<K, V, S> {
|
pub const fn with_hasher(hash_builder: S) -> HashMap<K, V, S> {
|
||||||
HashMap { base: base::HashMap::with_hasher(hash_builder) }
|
HashMap { base: base::HashMap::with_hasher(hash_builder) }
|
||||||
}
|
}
|
||||||
|
@ -101,6 +101,25 @@ use crate::ops::{BitAnd, BitOr, BitXor, Sub};
|
|||||||
/// [`HashMap`]: crate::collections::HashMap
|
/// [`HashMap`]: crate::collections::HashMap
|
||||||
/// [`RefCell`]: crate::cell::RefCell
|
/// [`RefCell`]: crate::cell::RefCell
|
||||||
/// [`Cell`]: crate::cell::Cell
|
/// [`Cell`]: crate::cell::Cell
|
||||||
|
///
|
||||||
|
/// # Usage in `const` and `static`
|
||||||
|
///
|
||||||
|
/// Like `HashMap`, `HashSet` is randomly seeded: each `HashSet` instance uses a different seed,
|
||||||
|
/// which means that `HashSet::new` cannot be used in const context. To construct a `HashSet` in the
|
||||||
|
/// initializer of a `const` or `static` item, you will have to use a different hasher that does not
|
||||||
|
/// involve a random seed, as demonstrated in the following example. **A `HashSet` constructed this
|
||||||
|
/// way is not resistant against HashDoS!**
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use std::collections::HashSet;
|
||||||
|
/// use std::hash::{BuildHasherDefault, DefaultHasher};
|
||||||
|
/// use std::sync::Mutex;
|
||||||
|
///
|
||||||
|
/// const EMPTY_SET: HashSet<String, BuildHasherDefault<DefaultHasher>> =
|
||||||
|
/// HashSet::with_hasher(BuildHasherDefault::new());
|
||||||
|
/// static SET: Mutex<HashSet<String, BuildHasherDefault<DefaultHasher>>> =
|
||||||
|
/// Mutex::new(HashSet::with_hasher(BuildHasherDefault::new()));
|
||||||
|
/// ```
|
||||||
#[cfg_attr(not(test), rustc_diagnostic_item = "HashSet")]
|
#[cfg_attr(not(test), rustc_diagnostic_item = "HashSet")]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub struct HashSet<T, S = RandomState> {
|
pub struct HashSet<T, S = RandomState> {
|
||||||
@ -369,7 +388,10 @@ impl<T, S> HashSet<T, S> {
|
|||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
#[stable(feature = "hashmap_build_hasher", since = "1.7.0")]
|
#[stable(feature = "hashmap_build_hasher", since = "1.7.0")]
|
||||||
#[rustc_const_unstable(feature = "const_collections_with_hasher", issue = "102575")]
|
#[rustc_const_stable(
|
||||||
|
feature = "const_collections_with_hasher",
|
||||||
|
since = "CURRENT_RUSTC_VERSION"
|
||||||
|
)]
|
||||||
pub const fn with_hasher(hasher: S) -> HashSet<T, S> {
|
pub const fn with_hasher(hasher: S) -> HashSet<T, S> {
|
||||||
HashSet { base: base::HashSet::with_hasher(hasher) }
|
HashSet { base: base::HashSet::with_hasher(hasher) }
|
||||||
}
|
}
|
||||||
|
@ -320,7 +320,6 @@
|
|||||||
// Library features (core):
|
// Library features (core):
|
||||||
// tidy-alphabetical-start
|
// tidy-alphabetical-start
|
||||||
#![feature(array_chunks)]
|
#![feature(array_chunks)]
|
||||||
#![feature(build_hasher_default_const_new)]
|
|
||||||
#![feature(c_str_module)]
|
#![feature(c_str_module)]
|
||||||
#![feature(char_internals)]
|
#![feature(char_internals)]
|
||||||
#![feature(clone_to_uninit)]
|
#![feature(clone_to_uninit)]
|
||||||
|
@ -2756,6 +2756,10 @@ impl Step for Crate {
|
|||||||
// `lib.rs` file, and a `lib.miri.rs` file exists in the same folder, we build that
|
// `lib.rs` file, and a `lib.miri.rs` file exists in the same folder, we build that
|
||||||
// instead. But crucially we only do that for the library, not the test builds.
|
// instead. But crucially we only do that for the library, not the test builds.
|
||||||
cargo.env("MIRI_REPLACE_LIBRS_IF_NOT_TEST", "1");
|
cargo.env("MIRI_REPLACE_LIBRS_IF_NOT_TEST", "1");
|
||||||
|
// std needs to be built with `-Zforce-unstable-if-unmarked`. For some reason the builder
|
||||||
|
// does not set this directly, but relies on the rustc wrapper to set it, and we are not using
|
||||||
|
// the wrapper -- hence we have to set it ourselves.
|
||||||
|
cargo.rustflag("-Zforce-unstable-if-unmarked");
|
||||||
cargo
|
cargo
|
||||||
} else {
|
} else {
|
||||||
// Also prepare a sysroot for the target.
|
// Also prepare a sysroot for the target.
|
||||||
|
@ -1033,6 +1033,15 @@ impl Builder<'_> {
|
|||||||
|
|
||||||
if mode == Mode::Rustc {
|
if mode == Mode::Rustc {
|
||||||
rustflags.arg("-Wrustc::internal");
|
rustflags.arg("-Wrustc::internal");
|
||||||
|
// cfg(bootstrap) - remove this check when lint is in bootstrap compiler
|
||||||
|
if stage != 0 {
|
||||||
|
// Lint is allow by default so downstream tools don't get a lit
|
||||||
|
// they can do nothing about
|
||||||
|
// We shouldn't be preinterning symbols used by tests
|
||||||
|
if cmd_kind != Kind::Test {
|
||||||
|
rustflags.arg("-Drustc::symbol_intern_string_literal");
|
||||||
|
}
|
||||||
|
}
|
||||||
// FIXME(edition_2024): Change this to `-Wrust_2024_idioms` when all
|
// FIXME(edition_2024): Change this to `-Wrust_2024_idioms` when all
|
||||||
// of the individual lints are satisfied.
|
// of the individual lints are satisfied.
|
||||||
rustflags.arg("-Wkeyword_idents_2024");
|
rustflags.arg("-Wkeyword_idents_2024");
|
||||||
|
23
src/doc/unstable-book/src/compiler-flags/randomize-layout.md
Normal file
23
src/doc/unstable-book/src/compiler-flags/randomize-layout.md
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# `randomize-layout`
|
||||||
|
|
||||||
|
The tracking issue for this feature is: [#106764](https://github.com/rust-lang/rust/issues/106764).
|
||||||
|
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
The `-Zrandomize-layout` flag changes the layout algorithm for `repr(Rust)` types defined in the current crate from its normal
|
||||||
|
optimization goals to pseudorandomly rearranging fields within the degrees of freedom provided by the largely unspecified
|
||||||
|
default representation. This also affects type sizes and padding.
|
||||||
|
Downstream intantiations of generic types defined in a crate with randomization enabled will also be randomized.
|
||||||
|
|
||||||
|
It can be used to find unsafe code that accidentally relies on unspecified behavior.
|
||||||
|
|
||||||
|
Randomization is not guaranteed to use a different permutation for each compilation session.
|
||||||
|
`-Zlayout-seed=<u64>` can be used to supply additional entropy.
|
||||||
|
|
||||||
|
Randomization only approximates the intended freedom of repr(Rust). Sometimes two distinct types may still consistently
|
||||||
|
result in the same layout due to limitations of the current implementation. Randomization may become
|
||||||
|
more aggressive over time as our coverage of the available degrees of freedoms improves.
|
||||||
|
Corollary: Randomization is not a safety oracle. Two struct layouts being observably the same under different layout seeds
|
||||||
|
on the current compiler version does not guarantee that future compiler versions won't give them distinct layouts.
|
||||||
|
|
||||||
|
Randomization may also become less aggressive in the future if additional guarantees get added to the default layout.
|
@ -1,6 +1,6 @@
|
|||||||
// Same as rustc's `tests/ui/async-await/async-closures/captures.rs`, keep in sync
|
// Same as rustc's `tests/ui/async-await/async-closures/captures.rs`, keep in sync
|
||||||
|
|
||||||
#![feature(async_closure, noop_waker)]
|
#![feature(async_closure, noop_waker, async_trait_bounds)]
|
||||||
|
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
use std::pin::pin;
|
use std::pin::pin;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#![feature(async_closure, noop_waker, async_fn_traits)]
|
#![feature(async_closure, noop_waker, async_trait_bounds)]
|
||||||
|
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
use std::pin::pin;
|
use std::pin::pin;
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
#![no_std]
|
#![no_std]
|
||||||
#![feature(bigint_helper_methods)]
|
#![feature(bigint_helper_methods)]
|
||||||
|
|
||||||
// This checks that the `carrying_add` implementation successfully chains, to catch
|
// This checks that the `carrying_add` and `borrowing_sub` implementation successfully chain,
|
||||||
// issues like <https://github.com/rust-lang/rust/issues/85532#issuecomment-2495119815>
|
// to catch issues like <https://github.com/rust-lang/rust/issues/85532#issuecomment-2495119815>
|
||||||
|
|
||||||
// This forces the ABI to avoid the windows-vs-linux ABI differences.
|
// This forces the ABI to avoid the windows-vs-linux ABI differences.
|
||||||
|
|
||||||
@ -31,3 +31,24 @@ pub unsafe extern "sysv64" fn bigint_chain_carrying_add(
|
|||||||
}
|
}
|
||||||
carry
|
carry
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: bigint_chain_borrowing_sub:
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "sysv64" fn bigint_chain_borrowing_sub(
|
||||||
|
dest: *mut u64,
|
||||||
|
src1: *const u64,
|
||||||
|
src2: *const u64,
|
||||||
|
n: usize,
|
||||||
|
mut carry: bool,
|
||||||
|
) -> bool {
|
||||||
|
// CHECK: mov [[TEMP:r..]], qword ptr [rsi + 8*[[IND:r..]] + 8]
|
||||||
|
// CHECK: sbb [[TEMP]], qword ptr [rdx + 8*[[IND]] + 8]
|
||||||
|
// CHECK: mov qword ptr [rdi + 8*[[IND]] + 8], [[TEMP]]
|
||||||
|
// CHECK: mov [[TEMP]], qword ptr [rsi + 8*[[IND]] + 16]
|
||||||
|
// CHECK: sbb [[TEMP]], qword ptr [rdx + 8*[[IND]] + 16]
|
||||||
|
// CHECK: mov qword ptr [rdi + 8*[[IND]] + 16], [[TEMP]]
|
||||||
|
for i in 0..n {
|
||||||
|
(*dest.add(i), carry) = u64::borrowing_sub(*src1.add(i), *src2.add(i), carry);
|
||||||
|
}
|
||||||
|
carry
|
||||||
|
}
|
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
#![feature(async_closure)]
|
#![feature(async_closure)]
|
||||||
|
|
||||||
fn async_closure_test(upvar: &str) -> impl async Fn() + '_ {
|
fn async_closure_test(upvar: &str) -> impl AsyncFn() + '_ {
|
||||||
async move || {
|
async move || {
|
||||||
let hello = String::from("hello");
|
let hello = String::from("hello");
|
||||||
println!("{hello}, {upvar}");
|
println!("{hello}, {upvar}");
|
||||||
|
@ -1,19 +1,19 @@
|
|||||||
Function name: async_closure::call_once::<async_closure::main::{closure#0}>
|
Function name: async_closure::call_once::<async_closure::main::{closure#0}>
|
||||||
Raw bytes (9): 0x[01, 01, 00, 01, 01, 07, 01, 00, 2c]
|
Raw bytes (9): 0x[01, 01, 00, 01, 01, 07, 01, 00, 2b]
|
||||||
Number of files: 1
|
Number of files: 1
|
||||||
- file 0 => global file 1
|
- file 0 => global file 1
|
||||||
Number of expressions: 0
|
Number of expressions: 0
|
||||||
Number of file 0 mappings: 1
|
Number of file 0 mappings: 1
|
||||||
- Code(Counter(0)) at (prev + 7, 1) to (start + 0, 44)
|
- Code(Counter(0)) at (prev + 7, 1) to (start + 0, 43)
|
||||||
Highest counter ID seen: c0
|
Highest counter ID seen: c0
|
||||||
|
|
||||||
Function name: async_closure::call_once::<async_closure::main::{closure#0}>::{closure#0}
|
Function name: async_closure::call_once::<async_closure::main::{closure#0}>::{closure#0}
|
||||||
Raw bytes (14): 0x[01, 01, 00, 02, 01, 07, 2c, 01, 0e, 05, 02, 01, 00, 02]
|
Raw bytes (14): 0x[01, 01, 00, 02, 01, 07, 2b, 01, 0e, 05, 02, 01, 00, 02]
|
||||||
Number of files: 1
|
Number of files: 1
|
||||||
- file 0 => global file 1
|
- file 0 => global file 1
|
||||||
Number of expressions: 0
|
Number of expressions: 0
|
||||||
Number of file 0 mappings: 2
|
Number of file 0 mappings: 2
|
||||||
- Code(Counter(0)) at (prev + 7, 44) to (start + 1, 14)
|
- Code(Counter(0)) at (prev + 7, 43) to (start + 1, 14)
|
||||||
- Code(Counter(1)) at (prev + 2, 1) to (start + 0, 2)
|
- Code(Counter(1)) at (prev + 2, 1) to (start + 0, 2)
|
||||||
Highest counter ID seen: c1
|
Highest counter ID seen: c1
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
LL| |//@ aux-build: executor.rs
|
LL| |//@ aux-build: executor.rs
|
||||||
LL| |extern crate executor;
|
LL| |extern crate executor;
|
||||||
LL| |
|
LL| |
|
||||||
LL| 1|async fn call_once(f: impl async FnOnce()) {
|
LL| 1|async fn call_once(f: impl AsyncFnOnce()) {
|
||||||
LL| 1| f().await;
|
LL| 1| f().await;
|
||||||
LL| 1|}
|
LL| 1|}
|
||||||
LL| |
|
LL| |
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
//@ aux-build: executor.rs
|
//@ aux-build: executor.rs
|
||||||
extern crate executor;
|
extern crate executor;
|
||||||
|
|
||||||
async fn call_once(f: impl async FnOnce()) {
|
async fn call_once(f: impl AsyncFnOnce()) {
|
||||||
f().await;
|
f().await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
//@ known-bug: #124020
|
//@ known-bug: #124020
|
||||||
//@ compile-flags: -Zpolymorphize=on --edition=2018 --crate-type=lib
|
//@ compile-flags: -Zpolymorphize=on --edition=2018 --crate-type=lib
|
||||||
|
|
||||||
#![feature(async_closure, noop_waker, async_fn_traits)]
|
#![feature(async_closure, noop_waker, async_trait_bounds)]
|
||||||
|
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
use std::pin::pin;
|
use std::pin::pin;
|
||||||
@ -19,7 +19,7 @@ pub fn block_on<T>(fut: impl Future<Output = T>) -> T {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn call_once(f: impl async FnOnce(DropMe)) {
|
async fn call_once(f: impl AsyncFnOnce(DropMe)) {
|
||||||
f(DropMe("world")).await;
|
f(DropMe("world")).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,15 +0,0 @@
|
|||||||
//@ known-bug: #132320
|
|
||||||
//@ compile-flags: -Znext-solver=globally
|
|
||||||
|
|
||||||
trait Foo {
|
|
||||||
type Item;
|
|
||||||
fn foo(&mut self);
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Foo for () {
|
|
||||||
type Item = Option<()>;
|
|
||||||
|
|
||||||
fn foo(&mut self) {
|
|
||||||
let _ = Self::Item::None;
|
|
||||||
}
|
|
||||||
}
|
|
@ -10,7 +10,7 @@ fn main() {
|
|||||||
block_on::block_on(async {
|
block_on::block_on(async {
|
||||||
let x = async || {};
|
let x = async || {};
|
||||||
|
|
||||||
async fn needs_async_fn_mut(mut x: impl async FnMut()) {
|
async fn needs_async_fn_mut(mut x: impl AsyncFnMut()) {
|
||||||
x().await;
|
x().await;
|
||||||
}
|
}
|
||||||
needs_async_fn_mut(x).await;
|
needs_async_fn_mut(x).await;
|
||||||
|
@ -8,7 +8,7 @@ extern crate block_on;
|
|||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
block_on::block_on(async {
|
block_on::block_on(async {
|
||||||
async fn needs_async_fn_once(x: impl async FnOnce()) {
|
async fn needs_async_fn_once(x: impl AsyncFnOnce()) {
|
||||||
x().await;
|
x().await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,6 @@
|
|||||||
|
|
||||||
#![feature(async_closure)]
|
#![feature(async_closure)]
|
||||||
|
|
||||||
pub fn closure() -> impl async Fn() {
|
pub fn closure() -> impl AsyncFn() {
|
||||||
async || { /* Don't really need to do anything here. */ }
|
async || { /* Don't really need to do anything here. */ }
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ extern crate block_on;
|
|||||||
|
|
||||||
async fn empty() {}
|
async fn empty() {}
|
||||||
|
|
||||||
pub async fn call_once<F: async FnOnce()>(f: F) {
|
pub async fn call_once<F: AsyncFnOnce()>(f: F) {
|
||||||
f().await;
|
f().await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ impl Trait for (i32,) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn call_once(f: impl async FnOnce()) {
|
async fn call_once(f: impl AsyncFnOnce()) {
|
||||||
f().await;
|
f().await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ struct S;
|
|||||||
struct B<'b>(PhantomData<&'b mut &'b mut ()>);
|
struct B<'b>(PhantomData<&'b mut &'b mut ()>);
|
||||||
|
|
||||||
impl S {
|
impl S {
|
||||||
async fn q<F: async Fn(B<'_>)>(self, f: F) {
|
async fn q<F: AsyncFn(B<'_>)>(self, f: F) {
|
||||||
f(B(PhantomData)).await;
|
f(B(PhantomData)).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,11 +13,11 @@ fn main() {
|
|||||||
block_on::block_on(async_main());
|
block_on::block_on(async_main());
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn call<T>(f: &impl async Fn() -> T) -> T {
|
async fn call<T>(f: &impl AsyncFn() -> T) -> T {
|
||||||
f().await
|
f().await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn call_once<T>(f: impl async FnOnce() -> T) -> T {
|
async fn call_once<T>(f: impl AsyncFnOnce() -> T) -> T {
|
||||||
f().await
|
f().await
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,7 +80,7 @@ async fn async_main() {
|
|||||||
call_once(c).await;
|
call_once(c).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn force_fnonce<T>(f: impl async FnOnce() -> T) -> impl async FnOnce() -> T {
|
fn force_fnonce<T>(f: impl AsyncFnOnce() -> T) -> impl AsyncFnOnce() -> T {
|
||||||
f
|
f
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
extern crate block_on;
|
extern crate block_on;
|
||||||
|
|
||||||
async fn for_each(f: impl async FnOnce(&str) + Clone) {
|
async fn for_each(f: impl AsyncFnOnce(&str) + Clone) {
|
||||||
f.clone()("world").await;
|
f.clone()("world").await;
|
||||||
f.clone()("world2").await;
|
f.clone()("world2").await;
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
#![feature(async_closure)]
|
#![feature(async_closure)]
|
||||||
|
|
||||||
fn constrain<T: async FnOnce()>(t: T) -> T {
|
fn constrain<T: AsyncFnOnce()>(t: T) -> T {
|
||||||
t
|
t
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -14,7 +14,7 @@ fn call_once<T>(f: impl FnOnce() -> T) -> T {
|
|||||||
f()
|
f()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn async_call_once<T>(f: impl async FnOnce() -> T) -> T {
|
async fn async_call_once<T>(f: impl AsyncFnOnce() -> T) -> T {
|
||||||
f().await
|
f().await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
extern crate block_on;
|
extern crate block_on;
|
||||||
|
|
||||||
async fn call_once(f: impl async FnOnce()) {
|
async fn call_once(f: impl AsyncFnOnce()) {
|
||||||
f().await;
|
f().await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ impl Drop for DropMe {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn call_once(f: impl async FnOnce()) {
|
async fn call_once(f: impl AsyncFnOnce()) {
|
||||||
println!("before call");
|
println!("before call");
|
||||||
let fut = Box::pin(f());
|
let fut = Box::pin(f());
|
||||||
println!("after call");
|
println!("after call");
|
||||||
|
@ -10,7 +10,7 @@ use std::future::Future;
|
|||||||
#[target_feature(enable = "sse2")]
|
#[target_feature(enable = "sse2")]
|
||||||
fn target_feature() -> Pin<Box<dyn Future<Output = ()> + 'static>> { todo!() }
|
fn target_feature() -> Pin<Box<dyn Future<Output = ()> + 'static>> { todo!() }
|
||||||
|
|
||||||
fn test(f: impl async Fn()) {}
|
fn test(f: impl AsyncFn()) {}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
test(target_feature); //~ ERROR the trait bound
|
test(target_feature); //~ ERROR the trait bound
|
||||||
|
@ -9,8 +9,8 @@ LL | test(target_feature);
|
|||||||
note: required by a bound in `test`
|
note: required by a bound in `test`
|
||||||
--> $DIR/fn-exception-target-features.rs:13:17
|
--> $DIR/fn-exception-target-features.rs:13:17
|
||||||
|
|
|
|
||||||
LL | fn test(f: impl async Fn()) {}
|
LL | fn test(f: impl AsyncFn()) {}
|
||||||
| ^^^^^^^^^^ required by this bound in `test`
|
| ^^^^^^^^^ required by this bound in `test`
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ unsafe extern "C" {
|
|||||||
pub safe fn abi() -> Pin<Box<dyn Future<Output = ()> + 'static>>;
|
pub safe fn abi() -> Pin<Box<dyn Future<Output = ()> + 'static>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test(f: impl async Fn()) {}
|
fn test(f: impl AsyncFn()) {}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
test(unsafety); //~ ERROR the trait bound
|
test(unsafety); //~ ERROR the trait bound
|
||||||
|
@ -9,8 +9,8 @@ LL | test(unsafety);
|
|||||||
note: required by a bound in `test`
|
note: required by a bound in `test`
|
||||||
--> $DIR/fn-exception.rs:16:17
|
--> $DIR/fn-exception.rs:16:17
|
||||||
|
|
|
|
||||||
LL | fn test(f: impl async Fn()) {}
|
LL | fn test(f: impl AsyncFn()) {}
|
||||||
| ^^^^^^^^^^ required by this bound in `test`
|
| ^^^^^^^^^ required by this bound in `test`
|
||||||
|
|
||||||
error[E0277]: the trait bound `extern "C" fn() -> Pin<Box<(dyn Future<Output = ()> + 'static)>> {abi}: AsyncFn()` is not satisfied
|
error[E0277]: the trait bound `extern "C" fn() -> Pin<Box<(dyn Future<Output = ()> + 'static)>> {abi}: AsyncFn()` is not satisfied
|
||||||
--> $DIR/fn-exception.rs:20:10
|
--> $DIR/fn-exception.rs:20:10
|
||||||
@ -23,8 +23,8 @@ LL | test(abi);
|
|||||||
note: required by a bound in `test`
|
note: required by a bound in `test`
|
||||||
--> $DIR/fn-exception.rs:16:17
|
--> $DIR/fn-exception.rs:16:17
|
||||||
|
|
|
|
||||||
LL | fn test(f: impl async Fn()) {}
|
LL | fn test(f: impl AsyncFn()) {}
|
||||||
| ^^^^^^^^^^ required by this bound in `test`
|
| ^^^^^^^^^ required by this bound in `test`
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
extern crate block_on;
|
extern crate block_on;
|
||||||
|
|
||||||
fn force_fnonce<T: async FnOnce()>(t: T) -> T { t }
|
fn force_fnonce<T: AsyncFnOnce()>(t: T) -> T { t }
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
block_on::block_on(async {
|
block_on::block_on(async {
|
||||||
|
@ -12,7 +12,7 @@ extern crate foreign;
|
|||||||
|
|
||||||
struct NoCopy;
|
struct NoCopy;
|
||||||
|
|
||||||
async fn call_once(f: impl async FnOnce()) {
|
async fn call_once(f: impl AsyncFnOnce()) {
|
||||||
f().await;
|
f().await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
//@ build-pass
|
//@ build-pass
|
||||||
//@ edition: 2021
|
//@ edition: 2021
|
||||||
|
|
||||||
// Demonstrates that an async closure may implement `FnMut` (not just `async FnMut`!)
|
// Demonstrates that an async closure may implement `FnMut` (not just `AsyncFnMut`!)
|
||||||
// if it has no self-borrows. In this case, `&Ty` is not borrowed from the closure env,
|
// if it has no self-borrows. In this case, `&Ty` is not borrowed from the closure env,
|
||||||
// since it's fine to reborrow it with its original lifetime. See the doc comment on
|
// since it's fine to reborrow it with its original lifetime. See the doc comment on
|
||||||
// `should_reborrow_from_env_of_parent_coroutine_closure` for more detail for when we
|
// `should_reborrow_from_env_of_parent_coroutine_closure` for more detail for when we
|
||||||
|
@ -24,7 +24,7 @@ pub fn block_on<T>(fut: impl Future<Output = T>) -> T {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn call_once<T>(f: impl async FnOnce() -> T) -> T {
|
async fn call_once<T>(f: impl AsyncFnOnce() -> T) -> T {
|
||||||
f().await
|
f().await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,11 +13,11 @@ use std::future::Future;
|
|||||||
use std::pin::pin;
|
use std::pin::pin;
|
||||||
use std::task::*;
|
use std::task::*;
|
||||||
|
|
||||||
async fn call_mut(f: &mut impl async FnMut()) {
|
async fn call_mut(f: &mut impl AsyncFnMut()) {
|
||||||
f().await;
|
f().await;
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn call_once(f: impl async FnOnce()) {
|
async fn call_once(f: impl AsyncFnOnce()) {
|
||||||
f().await;
|
f().await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ impl<'scope, 'env: 'scope> Scope<'scope, 'env> {
|
|||||||
|
|
||||||
fn scope_with_closure<'env, B>(_body: B) -> BoxFuture<'env, ()>
|
fn scope_with_closure<'env, B>(_body: B) -> BoxFuture<'env, ()>
|
||||||
where
|
where
|
||||||
for<'scope> B: async FnOnce(&'scope Scope<'scope, 'env>),
|
for<'scope> B: AsyncFnOnce(&'scope Scope<'scope, 'env>),
|
||||||
{
|
{
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ fn main() {
|
|||||||
is_static(&c);
|
is_static(&c);
|
||||||
|
|
||||||
// Check that `<{async fn} as AsyncFnOnce>::CallOnceFuture` owns its captures.
|
// Check that `<{async fn} as AsyncFnOnce>::CallOnceFuture` owns its captures.
|
||||||
fn call_once<F: async FnOnce()>(f: F) -> F::CallOnceFuture { f() }
|
fn call_once<F: AsyncFnOnce()>(f: F) -> F::CallOnceFuture { f() }
|
||||||
is_static(&call_once(c));
|
is_static(&call_once(c));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
extern crate block_on;
|
extern crate block_on;
|
||||||
|
|
||||||
async fn call_once(f: impl async FnOnce()) { f().await; }
|
async fn call_once(f: impl AsyncFnOnce()) { f().await; }
|
||||||
|
|
||||||
pub async fn async_closure(x: &mut i32) {
|
pub async fn async_closure(x: &mut i32) {
|
||||||
let c = async move || {
|
let c = async move || {
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
fn outlives<'a>(_: impl Sized + 'a) {}
|
fn outlives<'a>(_: impl Sized + 'a) {}
|
||||||
|
|
||||||
async fn call_once(f: impl async FnOnce()) {
|
async fn call_once(f: impl AsyncFnOnce()) {
|
||||||
f().await;
|
f().await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
extern crate block_on;
|
extern crate block_on;
|
||||||
|
|
||||||
fn wrapper(f: impl Fn(String)) -> impl async Fn(String) {
|
fn wrapper(f: impl Fn(String)) -> impl AsyncFn(String) {
|
||||||
async move |s| f(s)
|
async move |s| f(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
extern crate block_on;
|
extern crate block_on;
|
||||||
|
|
||||||
async fn call_once(f: impl async FnOnce()) {
|
async fn call_once(f: impl AsyncFnOnce()) {
|
||||||
f().await;
|
f().await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
//@ revisions: call call_once force_once
|
//@ revisions: call call_once force_once
|
||||||
|
|
||||||
// call - Call the closure regularly.
|
// call - Call the closure regularly.
|
||||||
// call_once - Call the closure w/ `async FnOnce`, so exercising the by_move shim.
|
// call_once - Call the closure w/ `AsyncFnOnce`, so exercising the by_move shim.
|
||||||
// force_once - Force the closure mode to `FnOnce`, so exercising what was fixed
|
// force_once - Force the closure mode to `FnOnce`, so exercising what was fixed
|
||||||
// in <https://github.com/rust-lang/rust/pull/123350>.
|
// in <https://github.com/rust-lang/rust/pull/123350>.
|
||||||
|
|
||||||
@ -20,7 +20,7 @@ macro_rules! call {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(call_once)]
|
#[cfg(call_once)]
|
||||||
async fn call_once(f: impl async FnOnce()) {
|
async fn call_once(f: impl AsyncFnOnce()) {
|
||||||
f().await
|
f().await
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,7 +35,7 @@ macro_rules! guidance {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(force_once)]
|
#[cfg(force_once)]
|
||||||
fn infer_fnonce(c: impl async FnOnce()) -> impl async FnOnce() { c }
|
fn infer_fnonce(c: impl AsyncFnOnce()) -> impl AsyncFnOnce() { c }
|
||||||
|
|
||||||
#[cfg(force_once)]
|
#[cfg(force_once)]
|
||||||
macro_rules! guidance {
|
macro_rules! guidance {
|
||||||
|
@ -10,15 +10,15 @@ struct NoCopy;
|
|||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
block_on::block_on(async {
|
block_on::block_on(async {
|
||||||
async fn call_once(x: impl async Fn()) { x().await }
|
async fn call_once(x: impl AsyncFn()) { x().await }
|
||||||
|
|
||||||
// check that `&{async-closure}` implements `async Fn`.
|
// check that `&{async-closure}` implements `AsyncFn`.
|
||||||
call_once(&async || {}).await;
|
call_once(&async || {}).await;
|
||||||
|
|
||||||
// check that `&{closure}` implements `async Fn`.
|
// check that `&{closure}` implements `AsyncFn`.
|
||||||
call_once(&|| async {}).await;
|
call_once(&|| async {}).await;
|
||||||
|
|
||||||
// check that `&fndef` implements `async Fn`.
|
// check that `&fndef` implements `AsyncFn`.
|
||||||
async fn foo() {}
|
async fn foo() {}
|
||||||
call_once(&foo).await;
|
call_once(&foo).await;
|
||||||
});
|
});
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#![feature(async_closure)]
|
#![feature(async_closure)]
|
||||||
|
|
||||||
async fn foo(x: impl async Fn(&str) -> &str) {}
|
async fn foo(x: impl AsyncFn(&str) -> &str) {}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
foo(async |x| x);
|
foo(async |x| x);
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
fn outlives<'a>(_: impl Sized + 'a) {}
|
fn outlives<'a>(_: impl Sized + 'a) {}
|
||||||
|
|
||||||
async fn call_once(f: impl async FnOnce()) {
|
async fn call_once(f: impl AsyncFnOnce()) {
|
||||||
f().await;
|
f().await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#![feature(async_closure)]
|
#![feature(async_closure)]
|
||||||
|
|
||||||
fn needs_async_fn(_: impl async Fn()) {}
|
fn needs_async_fn(_: impl AsyncFn()) {}
|
||||||
|
|
||||||
fn a() {
|
fn a() {
|
||||||
let mut x = 1;
|
let mut x = 1;
|
||||||
@ -15,7 +15,7 @@ fn a() {
|
|||||||
fn b() {
|
fn b() {
|
||||||
let x = String::new();
|
let x = String::new();
|
||||||
needs_async_fn(move || async move {
|
needs_async_fn(move || async move {
|
||||||
//~^ ERROR expected a closure that implements the `async Fn` trait, but this closure only implements `async FnOnce`
|
//~^ ERROR expected a closure that implements the `AsyncFn` trait, but this closure only implements `AsyncFnOnce`
|
||||||
println!("{x}");
|
println!("{x}");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,29 +1,29 @@
|
|||||||
error[E0525]: expected a closure that implements the `async Fn` trait, but this closure only implements `async FnOnce`
|
error[E0525]: expected a closure that implements the `AsyncFn` trait, but this closure only implements `AsyncFnOnce`
|
||||||
--> $DIR/wrong-fn-kind.rs:17:20
|
--> $DIR/wrong-fn-kind.rs:17:20
|
||||||
|
|
|
|
||||||
LL | needs_async_fn(move || async move {
|
LL | needs_async_fn(move || async move {
|
||||||
| -------------- -^^^^^^
|
| -------------- -^^^^^^
|
||||||
| | |
|
| | |
|
||||||
| _____|______________this closure implements `async FnOnce`, not `async Fn`
|
| _____|______________this closure implements `AsyncFnOnce`, not `AsyncFn`
|
||||||
| | |
|
| | |
|
||||||
| | required by a bound introduced by this call
|
| | required by a bound introduced by this call
|
||||||
LL | |
|
LL | |
|
||||||
LL | | println!("{x}");
|
LL | | println!("{x}");
|
||||||
| | - closure is `async FnOnce` because it moves the variable `x` out of its environment
|
| | - closure is `AsyncFnOnce` because it moves the variable `x` out of its environment
|
||||||
LL | | });
|
LL | | });
|
||||||
| |_____- the requirement to implement `async Fn` derives from here
|
| |_____- the requirement to implement `AsyncFn` 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:5:27
|
--> $DIR/wrong-fn-kind.rs:5:27
|
||||||
|
|
|
|
||||||
LL | fn needs_async_fn(_: impl async Fn()) {}
|
LL | fn needs_async_fn(_: impl AsyncFn()) {}
|
||||||
| ^^^^^^^^^^ required by this bound in `needs_async_fn`
|
| ^^^^^^^^^ required by this bound in `needs_async_fn`
|
||||||
|
|
||||||
error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure
|
error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure
|
||||||
--> $DIR/wrong-fn-kind.rs:9:20
|
--> $DIR/wrong-fn-kind.rs:9:20
|
||||||
|
|
|
|
||||||
LL | fn needs_async_fn(_: impl async Fn()) {}
|
LL | fn needs_async_fn(_: impl AsyncFn()) {}
|
||||||
| --------------- change this to accept `FnMut` instead of `Fn`
|
| -------------- change this to accept `FnMut` instead of `Fn`
|
||||||
...
|
...
|
||||||
LL | needs_async_fn(async || {
|
LL | needs_async_fn(async || {
|
||||||
| -------------- ^^^^^^^^
|
| -------------- ^^^^^^^^
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#![feature(async_closure)]
|
#![feature(async_closure)]
|
||||||
|
|
||||||
fn foo(x: &dyn async Fn()) {}
|
fn foo(x: &dyn AsyncFn()) {}
|
||||||
//~^ ERROR the trait `AsyncFnMut` cannot be made into an object
|
//~^ ERROR the trait `AsyncFnMut` cannot be made into an object
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
error[E0038]: the trait `AsyncFnMut` cannot be made into an object
|
error[E0038]: the trait `AsyncFnMut` cannot be made into an object
|
||||||
--> $DIR/dyn-pos.rs:5:16
|
--> $DIR/dyn-pos.rs:5:16
|
||||||
|
|
|
|
||||||
LL | fn foo(x: &dyn async Fn()) {}
|
LL | fn foo(x: &dyn AsyncFn()) {}
|
||||||
| ^^^^^^^^^^ `AsyncFnMut` cannot be made into an object
|
| ^^^^^^^^^ `AsyncFnMut` cannot be made into an object
|
||||||
|
|
|
|
||||||
note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
|
note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
|
||||||
--> $SRC_DIR/core/src/ops/async_function.rs:LL:COL
|
--> $SRC_DIR/core/src/ops/async_function.rs:LL:COL
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
fn foo(x: impl async Fn()) -> impl async Fn() { x }
|
fn foo(x: impl async Fn()) -> impl async Fn() { x }
|
||||||
//~^ ERROR `async` trait bounds are only allowed in Rust 2018 or later
|
//~^ ERROR `async` trait bounds are only allowed in Rust 2018 or later
|
||||||
//~| ERROR `async` trait bounds are only allowed in Rust 2018 or later
|
//~| ERROR `async` trait bounds are only allowed in Rust 2018 or later
|
||||||
//~| ERROR async closures are unstable
|
//~| ERROR `async` trait bounds are unstable
|
||||||
//~| ERROR async closures are unstable
|
//~| ERROR `async` trait bounds are unstable
|
||||||
//~| ERROR use of unstable library feature `async_closure`
|
//~| ERROR use of unstable library feature `async_closure`
|
||||||
//~| ERROR use of unstable library feature `async_closure`
|
//~| ERROR use of unstable library feature `async_closure`
|
||||||
|
|
||||||
|
@ -16,27 +16,27 @@ LL | fn foo(x: impl async Fn()) -> impl async Fn() { x }
|
|||||||
= help: pass `--edition 2024` to `rustc`
|
= help: pass `--edition 2024` to `rustc`
|
||||||
= note: for more on editions, read https://doc.rust-lang.org/edition-guide
|
= note: for more on editions, read https://doc.rust-lang.org/edition-guide
|
||||||
|
|
||||||
error[E0658]: async closures are unstable
|
error[E0658]: `async` trait bounds are unstable
|
||||||
--> $DIR/edition-2015.rs:1:16
|
--> $DIR/edition-2015.rs:1:16
|
||||||
|
|
|
|
||||||
LL | fn foo(x: impl async Fn()) -> impl async Fn() { x }
|
LL | fn foo(x: impl async Fn()) -> impl async Fn() { x }
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
|
|
|
||||||
= note: see issue #62290 <https://github.com/rust-lang/rust/issues/62290> for more information
|
= note: see issue #62290 <https://github.com/rust-lang/rust/issues/62290> for more information
|
||||||
= help: add `#![feature(async_closure)]` to the crate attributes to enable
|
= help: add `#![feature(async_trait_bounds)]` 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
|
||||||
= help: to use an async block, remove the `||`: `async {`
|
= help: use the desugared name of the async trait, such as `AsyncFn`
|
||||||
|
|
||||||
error[E0658]: async closures are unstable
|
error[E0658]: `async` trait bounds are unstable
|
||||||
--> $DIR/edition-2015.rs:1:36
|
--> $DIR/edition-2015.rs:1:36
|
||||||
|
|
|
|
||||||
LL | fn foo(x: impl async Fn()) -> impl async Fn() { x }
|
LL | fn foo(x: impl async Fn()) -> impl async Fn() { x }
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
|
|
|
||||||
= note: see issue #62290 <https://github.com/rust-lang/rust/issues/62290> for more information
|
= note: see issue #62290 <https://github.com/rust-lang/rust/issues/62290> for more information
|
||||||
= help: add `#![feature(async_closure)]` to the crate attributes to enable
|
= help: add `#![feature(async_trait_bounds)]` 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
|
||||||
= help: to use an async block, remove the `||`: `async {`
|
= help: use the desugared name of the async trait, such as `AsyncFn`
|
||||||
|
|
||||||
error[E0658]: use of unstable library feature `async_closure`
|
error[E0658]: use of unstable library feature `async_closure`
|
||||||
--> $DIR/edition-2015.rs:1:42
|
--> $DIR/edition-2015.rs:1:42
|
||||||
|
@ -15,7 +15,7 @@ async fn f(arg: &i32) {}
|
|||||||
|
|
||||||
async fn func<F>(f: F)
|
async fn func<F>(f: F)
|
||||||
where
|
where
|
||||||
F: for<'a> async Fn(&'a i32),
|
F: for<'a> AsyncFn(&'a i32),
|
||||||
{
|
{
|
||||||
let x: i32 = 0;
|
let x: i32 = 0;
|
||||||
f(&x).await;
|
f(&x).await;
|
||||||
|
@ -3,13 +3,13 @@
|
|||||||
|
|
||||||
#![feature(async_closure, type_alias_impl_trait)]
|
#![feature(async_closure, type_alias_impl_trait)]
|
||||||
|
|
||||||
type Tait = impl async Fn();
|
type Tait = impl AsyncFn();
|
||||||
fn tait() -> Tait {
|
fn tait() -> Tait {
|
||||||
|| async {}
|
|| async {}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn foo(x: impl async Fn()) -> impl async Fn() { x }
|
fn foo(x: impl AsyncFn()) -> impl AsyncFn() { x }
|
||||||
|
|
||||||
fn param<T: async Fn()>() {}
|
fn param<T: AsyncFn()>() {}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
@ -13,9 +13,9 @@ macro_rules! demo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
demo! { impl async Trait }
|
demo! { impl async Trait }
|
||||||
//~^ ERROR async closures are unstable
|
//~^ ERROR `async` trait bounds are unstable
|
||||||
|
|
||||||
demo! { dyn async Trait }
|
demo! { dyn async Trait }
|
||||||
//~^ ERROR async closures are unstable
|
//~^ ERROR `async` trait bounds are unstable
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
@ -20,27 +20,27 @@ LL | demo! { dyn async Trait }
|
|||||||
|
|
|
|
||||||
= note: this error originates in the macro `demo` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in the macro `demo` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error[E0658]: async closures are unstable
|
error[E0658]: `async` trait bounds are unstable
|
||||||
--> $DIR/mbe-async-trait-bound-theoretical-regression.rs:15:14
|
--> $DIR/mbe-async-trait-bound-theoretical-regression.rs:15:14
|
||||||
|
|
|
|
||||||
LL | demo! { impl async Trait }
|
LL | demo! { impl async Trait }
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
|
|
|
||||||
= note: see issue #62290 <https://github.com/rust-lang/rust/issues/62290> for more information
|
= note: see issue #62290 <https://github.com/rust-lang/rust/issues/62290> for more information
|
||||||
= help: add `#![feature(async_closure)]` to the crate attributes to enable
|
= help: add `#![feature(async_trait_bounds)]` 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
|
||||||
= help: to use an async block, remove the `||`: `async {`
|
= help: use the desugared name of the async trait, such as `AsyncFn`
|
||||||
|
|
||||||
error[E0658]: async closures are unstable
|
error[E0658]: `async` trait bounds are unstable
|
||||||
--> $DIR/mbe-async-trait-bound-theoretical-regression.rs:18:13
|
--> $DIR/mbe-async-trait-bound-theoretical-regression.rs:18:13
|
||||||
|
|
|
|
||||||
LL | demo! { dyn async Trait }
|
LL | demo! { dyn async Trait }
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
|
|
|
||||||
= note: see issue #62290 <https://github.com/rust-lang/rust/issues/62290> for more information
|
= note: see issue #62290 <https://github.com/rust-lang/rust/issues/62290> for more information
|
||||||
= help: add `#![feature(async_closure)]` to the crate attributes to enable
|
= help: add `#![feature(async_trait_bounds)]` 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
|
||||||
= help: to use an async block, remove the `||`: `async {`
|
= help: use the desugared name of the async trait, such as `AsyncFn`
|
||||||
|
|
||||||
error: aborting due to 4 previous errors
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//@ edition:2018
|
//@ edition:2018
|
||||||
|
|
||||||
#![feature(async_closure)]
|
#![feature(async_trait_bounds)]
|
||||||
|
|
||||||
struct S;
|
struct S;
|
||||||
|
|
||||||
|
@ -6,7 +6,9 @@
|
|||||||
|
|
||||||
#![feature(async_closure, unboxed_closures, async_fn_traits)]
|
#![feature(async_closure, unboxed_closures, async_fn_traits)]
|
||||||
|
|
||||||
fn project<F: async Fn<()>>(_: F) -> Option<F::Output> { None }
|
use std::ops::AsyncFn;
|
||||||
|
|
||||||
|
fn project<F: AsyncFn<()>>(_: F) -> Option<F::Output> { None }
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let x: Option<i32> = project(|| async { 1i32 });
|
let x: Option<i32> = project(|| async { 1i32 });
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
//@ edition: 2021
|
//@ edition: 2021
|
||||||
//@ check-pass
|
//@ check-pass
|
||||||
|
|
||||||
#![feature(async_closure)]
|
#![feature(async_closure, async_trait_bounds)]
|
||||||
|
|
||||||
async fn foo() {}
|
async fn foo() {}
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ macro_rules! x {
|
|||||||
|
|
||||||
x! {
|
x! {
|
||||||
async fn foo() -> impl async Fn() { }
|
async fn foo() -> impl async Fn() { }
|
||||||
//~^ ERROR async closures are unstable
|
//~^ ERROR `async` trait bounds are unstable
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
error[E0658]: async closures are unstable
|
error[E0658]: `async` trait bounds are unstable
|
||||||
--> $DIR/trait-bounds-in-macro.rs:8:28
|
--> $DIR/trait-bounds-in-macro.rs:8:28
|
||||||
|
|
|
|
||||||
LL | async fn foo() -> impl async Fn() { }
|
LL | async fn foo() -> impl async Fn() { }
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
|
|
|
||||||
= note: see issue #62290 <https://github.com/rust-lang/rust/issues/62290> for more information
|
= note: see issue #62290 <https://github.com/rust-lang/rust/issues/62290> for more information
|
||||||
= help: add `#![feature(async_closure)]` to the crate attributes to enable
|
= help: add `#![feature(async_trait_bounds)]` 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
|
||||||
= help: to use an async block, remove the `||`: `async {`
|
= help: use the desugared name of the async trait, such as `AsyncFn`
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//@ edition:2018
|
//@ edition:2018
|
||||||
|
|
||||||
#![feature(async_closure)]
|
#![feature(async_trait_bounds)]
|
||||||
|
|
||||||
trait Foo {}
|
trait Foo {}
|
||||||
|
|
||||||
|
@ -0,0 +1,12 @@
|
|||||||
|
//@ check-pass
|
||||||
|
|
||||||
|
#![feature(generic_arg_infer)]
|
||||||
|
#![crate_type = "lib"]
|
||||||
|
|
||||||
|
// Test that encoding the hallucinated `DefId` for the `_` const argument doesn't
|
||||||
|
// ICE (see #133468). This requires this to be a library crate.
|
||||||
|
|
||||||
|
pub fn foo() {
|
||||||
|
let s: [u8; 10];
|
||||||
|
s = [0; _];
|
||||||
|
}
|
@ -1,6 +1,5 @@
|
|||||||
#![feature(extern_types)]
|
#![feature(extern_types)]
|
||||||
#![feature(core_intrinsics)]
|
#![feature(core_intrinsics)]
|
||||||
#![feature(const_size_of_val, const_align_of_val)]
|
|
||||||
|
|
||||||
use std::intrinsics::{min_align_of_val, size_of_val};
|
use std::intrinsics::{min_align_of_val, size_of_val};
|
||||||
|
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
error[E0080]: evaluation of constant value failed
|
error[E0080]: evaluation of constant value failed
|
||||||
--> $DIR/const-size_of_val-align_of_val-extern-type.rs:11:31
|
--> $DIR/const-size_of_val-align_of_val-extern-type.rs:10:31
|
||||||
|
|
|
|
||||||
LL | const _SIZE: usize = unsafe { size_of_val(&4 as *const i32 as *const Opaque) };
|
LL | const _SIZE: usize = unsafe { size_of_val(&4 as *const i32 as *const Opaque) };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `extern type` does not have known layout
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `extern type` does not have known layout
|
||||||
|
|
||||||
error[E0080]: evaluation of constant value failed
|
error[E0080]: evaluation of constant value failed
|
||||||
--> $DIR/const-size_of_val-align_of_val-extern-type.rs:12:32
|
--> $DIR/const-size_of_val-align_of_val-extern-type.rs:11:32
|
||||||
|
|
|
|
||||||
LL | const _ALIGN: usize = unsafe { min_align_of_val(&4 as *const i32 as *const Opaque) };
|
LL | const _ALIGN: usize = unsafe { min_align_of_val(&4 as *const i32 as *const Opaque) };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `extern type` does not have known layout
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `extern type` does not have known layout
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
//@ run-pass
|
//@ run-pass
|
||||||
|
|
||||||
#![feature(const_size_of_val, const_align_of_val)]
|
#![feature(layout_for_ptr)]
|
||||||
#![feature(const_size_of_val_raw, const_align_of_val_raw, layout_for_ptr)]
|
|
||||||
|
|
||||||
use std::{mem, ptr};
|
use std::{mem, ptr};
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ impl Drop for Droppy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Droppy {
|
impl Droppy {
|
||||||
fn get(&self) -> Option<u8> {
|
const fn get(&self) -> Option<u8> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -62,11 +62,10 @@ fn main() {
|
|||||||
//~| HELP: a `match` with a single arm can preserve the drop order up to Edition 2021
|
//~| HELP: a `match` with a single arm can preserve the drop order up to Edition 2021
|
||||||
}
|
}
|
||||||
|
|
||||||
if let () = { match Droppy.get() { Some(_value) => {} _ => {}} } {
|
if let () = { if let Some(_value) = Droppy.get() {} } {
|
||||||
//~^ ERROR: `if let` assigns a shorter lifetime since Edition 2024
|
// This should not lint.
|
||||||
//~| WARN: this changes meaning in Rust 2024
|
// This `if let` sits is a tail expression of a block.
|
||||||
//~| HELP: the value is now dropped here in Edition 2024
|
// In Edition 2024, the temporaries are dropped before exiting the surrounding block.
|
||||||
//~| HELP: a `match` with a single arm can preserve the drop order up to Edition 2021
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
@ -94,4 +93,17 @@ fn main() {
|
|||||||
//~| HELP: the value is now dropped here in Edition 2024
|
//~| HELP: the value is now dropped here in Edition 2024
|
||||||
//~| HELP: a `match` with a single arm can preserve the drop order up to Edition 2021
|
//~| HELP: a `match` with a single arm can preserve the drop order up to Edition 2021
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We want to keep the `if let`s below as direct descendents of match arms,
|
||||||
|
// so the formatting is suppressed.
|
||||||
|
#[rustfmt::skip]
|
||||||
|
match droppy().get() {
|
||||||
|
_ => if let Some(_value) = droppy().get() {},
|
||||||
|
// Should not lint
|
||||||
|
// There is implicitly a block surrounding the `if let`.
|
||||||
|
// Given that it is a tail expression, the temporaries are dropped duly before
|
||||||
|
// the execution is exiting the `match`.
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(_value) = droppy().get() {}
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ impl Drop for Droppy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Droppy {
|
impl Droppy {
|
||||||
fn get(&self) -> Option<u8> {
|
const fn get(&self) -> Option<u8> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -63,10 +63,9 @@ fn main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let () = { if let Some(_value) = Droppy.get() {} } {
|
if let () = { if let Some(_value) = Droppy.get() {} } {
|
||||||
//~^ ERROR: `if let` assigns a shorter lifetime since Edition 2024
|
// This should not lint.
|
||||||
//~| WARN: this changes meaning in Rust 2024
|
// This `if let` sits is a tail expression of a block.
|
||||||
//~| HELP: the value is now dropped here in Edition 2024
|
// In Edition 2024, the temporaries are dropped before exiting the surrounding block.
|
||||||
//~| HELP: a `match` with a single arm can preserve the drop order up to Edition 2021
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
@ -94,4 +93,17 @@ fn main() {
|
|||||||
//~| HELP: the value is now dropped here in Edition 2024
|
//~| HELP: the value is now dropped here in Edition 2024
|
||||||
//~| HELP: a `match` with a single arm can preserve the drop order up to Edition 2021
|
//~| HELP: a `match` with a single arm can preserve the drop order up to Edition 2021
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We want to keep the `if let`s below as direct descendents of match arms,
|
||||||
|
// so the formatting is suppressed.
|
||||||
|
#[rustfmt::skip]
|
||||||
|
match droppy().get() {
|
||||||
|
_ => if let Some(_value) = droppy().get() {},
|
||||||
|
// Should not lint
|
||||||
|
// There is implicitly a block surrounding the `if let`.
|
||||||
|
// Given that it is a tail expression, the temporaries are dropped duly before
|
||||||
|
// the execution is exiting the `match`.
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(_value) = droppy().get() {}
|
||||||
}
|
}
|
||||||
|
@ -112,27 +112,7 @@ LL | if let Some(1) = { match Droppy.get() { Some(_value) => { Some(1) } _ =
|
|||||||
| ~~~~~ +++++++++++++++++ ~~~~ +
|
| ~~~~~ +++++++++++++++++ ~~~~ +
|
||||||
|
|
||||||
error: `if let` assigns a shorter lifetime since Edition 2024
|
error: `if let` assigns a shorter lifetime since Edition 2024
|
||||||
--> $DIR/lint-if-let-rescope.rs:65:22
|
--> $DIR/lint-if-let-rescope.rs:72:12
|
||||||
|
|
|
||||||
LL | if let () = { if let Some(_value) = Droppy.get() {} } {
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^------^^^^^^
|
|
||||||
| |
|
|
||||||
| this value has a significant drop implementation which may observe a major change in drop order and requires your discretion
|
|
||||||
|
|
|
||||||
= warning: this changes meaning in Rust 2024
|
|
||||||
= note: for more information, see issue #124085 <https://github.com/rust-lang/rust/issues/124085>
|
|
||||||
help: the value is now dropped here in Edition 2024
|
|
||||||
--> $DIR/lint-if-let-rescope.rs:65:55
|
|
||||||
|
|
|
||||||
LL | if let () = { if let Some(_value) = Droppy.get() {} } {
|
|
||||||
| ^
|
|
||||||
help: a `match` with a single arm can preserve the drop order up to Edition 2021
|
|
||||||
|
|
|
||||||
LL | if let () = { match Droppy.get() { Some(_value) => {} _ => {}} } {
|
|
||||||
| ~~~~~ +++++++++++++++++ ++++++++
|
|
||||||
|
|
||||||
error: `if let` assigns a shorter lifetime since Edition 2024
|
|
||||||
--> $DIR/lint-if-let-rescope.rs:73:12
|
|
||||||
|
|
|
|
||||||
LL | if (if let Some(_value) = droppy().get() { true } else { false }) {
|
LL | if (if let Some(_value) = droppy().get() { true } else { false }) {
|
||||||
| ^^^^^^^^^^^^^^^^^^^--------^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^--------^^^^^^
|
||||||
@ -142,7 +122,7 @@ LL | if (if let Some(_value) = droppy().get() { true } else { false }) {
|
|||||||
= warning: this changes meaning in Rust 2024
|
= warning: this changes meaning in Rust 2024
|
||||||
= note: for more information, see issue #124085 <https://github.com/rust-lang/rust/issues/124085>
|
= note: for more information, see issue #124085 <https://github.com/rust-lang/rust/issues/124085>
|
||||||
help: the value is now dropped here in Edition 2024
|
help: the value is now dropped here in Edition 2024
|
||||||
--> $DIR/lint-if-let-rescope.rs:73:53
|
--> $DIR/lint-if-let-rescope.rs:72:53
|
||||||
|
|
|
|
||||||
LL | if (if let Some(_value) = droppy().get() { true } else { false }) {
|
LL | if (if let Some(_value) = droppy().get() { true } else { false }) {
|
||||||
| ^
|
| ^
|
||||||
@ -152,7 +132,7 @@ LL | if (match droppy().get() { Some(_value) => { true } _ => { false }}) {
|
|||||||
| ~~~~~ +++++++++++++++++ ~~~~ +
|
| ~~~~~ +++++++++++++++++ ~~~~ +
|
||||||
|
|
||||||
error: `if let` assigns a shorter lifetime since Edition 2024
|
error: `if let` assigns a shorter lifetime since Edition 2024
|
||||||
--> $DIR/lint-if-let-rescope.rs:79:21
|
--> $DIR/lint-if-let-rescope.rs:78:21
|
||||||
|
|
|
|
||||||
LL | } else if (((if let Some(_value) = droppy().get() { true } else { false }))) {
|
LL | } else if (((if let Some(_value) = droppy().get() { true } else { false }))) {
|
||||||
| ^^^^^^^^^^^^^^^^^^^--------^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^--------^^^^^^
|
||||||
@ -162,7 +142,7 @@ LL | } else if (((if let Some(_value) = droppy().get() { true } else { false
|
|||||||
= warning: this changes meaning in Rust 2024
|
= warning: this changes meaning in Rust 2024
|
||||||
= note: for more information, see issue #124085 <https://github.com/rust-lang/rust/issues/124085>
|
= note: for more information, see issue #124085 <https://github.com/rust-lang/rust/issues/124085>
|
||||||
help: the value is now dropped here in Edition 2024
|
help: the value is now dropped here in Edition 2024
|
||||||
--> $DIR/lint-if-let-rescope.rs:79:62
|
--> $DIR/lint-if-let-rescope.rs:78:62
|
||||||
|
|
|
|
||||||
LL | } else if (((if let Some(_value) = droppy().get() { true } else { false }))) {
|
LL | } else if (((if let Some(_value) = droppy().get() { true } else { false }))) {
|
||||||
| ^
|
| ^
|
||||||
@ -172,7 +152,7 @@ LL | } else if (((match droppy().get() { Some(_value) => { true } _ => { fal
|
|||||||
| ~~~~~ +++++++++++++++++ ~~~~ +
|
| ~~~~~ +++++++++++++++++ ~~~~ +
|
||||||
|
|
||||||
error: `if let` assigns a shorter lifetime since Edition 2024
|
error: `if let` assigns a shorter lifetime since Edition 2024
|
||||||
--> $DIR/lint-if-let-rescope.rs:91:15
|
--> $DIR/lint-if-let-rescope.rs:90:15
|
||||||
|
|
|
|
||||||
LL | while (if let Some(_value) = droppy().get() { false } else { true }) {
|
LL | while (if let Some(_value) = droppy().get() { false } else { true }) {
|
||||||
| ^^^^^^^^^^^^^^^^^^^--------^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^--------^^^^^^
|
||||||
@ -182,7 +162,7 @@ LL | while (if let Some(_value) = droppy().get() { false } else { true }) {
|
|||||||
= warning: this changes meaning in Rust 2024
|
= warning: this changes meaning in Rust 2024
|
||||||
= note: for more information, see issue #124085 <https://github.com/rust-lang/rust/issues/124085>
|
= note: for more information, see issue #124085 <https://github.com/rust-lang/rust/issues/124085>
|
||||||
help: the value is now dropped here in Edition 2024
|
help: the value is now dropped here in Edition 2024
|
||||||
--> $DIR/lint-if-let-rescope.rs:91:57
|
--> $DIR/lint-if-let-rescope.rs:90:57
|
||||||
|
|
|
|
||||||
LL | while (if let Some(_value) = droppy().get() { false } else { true }) {
|
LL | while (if let Some(_value) = droppy().get() { false } else { true }) {
|
||||||
| ^
|
| ^
|
||||||
@ -191,5 +171,5 @@ help: a `match` with a single arm can preserve the drop order up to Edition 2021
|
|||||||
LL | while (match droppy().get() { Some(_value) => { false } _ => { true }}) {
|
LL | while (match droppy().get() { Some(_value) => { false } _ => { true }}) {
|
||||||
| ~~~~~ +++++++++++++++++ ~~~~ +
|
| ~~~~~ +++++++++++++++++ ~~~~ +
|
||||||
|
|
||||||
error: aborting due to 8 previous errors
|
error: aborting due to 7 previous errors
|
||||||
|
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
//@ edition: 2021
|
||||||
|
|
||||||
|
fn test(_: impl async Fn()) {}
|
||||||
|
//~^ ERROR `async` trait bounds are unstable
|
||||||
|
//~| ERROR use of unstable library feature `async_closure`
|
||||||
|
|
||||||
|
fn main() {}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user