From 716d99c3ffa83eac948497ad88e586cb3b556032 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Fri, 8 Nov 2024 21:32:40 +0100 Subject: [PATCH 01/20] add some debug-assertion crash tests --- tests/crashes/116979.rs | 14 ++++++++++++++ tests/crashes/117808.rs | 27 +++++++++++++++++++++++++++ tests/crashes/117877.rs | 13 +++++++++++++ tests/crashes/118778.rs | 24 ++++++++++++++++++++++++ tests/crashes/118784.rs | 19 +++++++++++++++++++ tests/crashes/120175.rs | 11 +++++++++++ tests/crashes/121176.rs | 9 +++++++++ tests/crashes/123861.rs | 5 +++++ tests/crashes/123862.rs | 14 ++++++++++++++ tests/crashes/130395.rs | 10 ++++++++++ 10 files changed, 146 insertions(+) create mode 100644 tests/crashes/116979.rs create mode 100644 tests/crashes/117808.rs create mode 100644 tests/crashes/117877.rs create mode 100644 tests/crashes/118778.rs create mode 100644 tests/crashes/118784.rs create mode 100644 tests/crashes/120175.rs create mode 100644 tests/crashes/121176.rs create mode 100644 tests/crashes/123861.rs create mode 100644 tests/crashes/123862.rs create mode 100644 tests/crashes/130395.rs diff --git a/tests/crashes/116979.rs b/tests/crashes/116979.rs new file mode 100644 index 0000000000000..28bbc972ea340 --- /dev/null +++ b/tests/crashes/116979.rs @@ -0,0 +1,14 @@ +//@ known-bug: #116979 +//@ compile-flags: -Csymbol-mangling-version=v0 +//@ needs-rustc-debug-assertions + +#![feature(dyn_star)] +#![allow(incomplete_features)] + +use std::fmt::Display; + +pub fn require_dyn_star_display(_: dyn* Display) {} + +fn main() { + require_dyn_star_display(1usize); +} diff --git a/tests/crashes/117808.rs b/tests/crashes/117808.rs new file mode 100644 index 0000000000000..2c727986dd07f --- /dev/null +++ b/tests/crashes/117808.rs @@ -0,0 +1,27 @@ +//@ known-bug: #117808 +//@ edition:2021 +//@ needs-rustc-debug-assertions + +use std::future::Future; + +fn hrc AsyncClosure<'a, (), R>>(f: F) -> F { + f +} + +fn main() { + hrc(|x| async {}); +} + +trait AsyncClosure<'a, I, R> +where + I: 'a, +{ +} + +impl<'a, I, R, Fut, F> AsyncClosure<'a, I, R> for F +where + I: 'a, + F: Fn(&'a I) -> Fut, + Fut: Future + Send + 'a, +{ +} diff --git a/tests/crashes/117877.rs b/tests/crashes/117877.rs new file mode 100644 index 0000000000000..b1effc0cbcb1a --- /dev/null +++ b/tests/crashes/117877.rs @@ -0,0 +1,13 @@ +//@ known-bug: #117877 +//@ edition:2021 +//@ needs-rustc-debug-assertions +//@ only-x86_64 +#![feature(asm_const)] + +use std::arch::asm; + +async unsafe fn foo<'a>() { + asm!("/* {0} */", const N); +} + +fn main() {} diff --git a/tests/crashes/118778.rs b/tests/crashes/118778.rs new file mode 100644 index 0000000000000..9914e76022d76 --- /dev/null +++ b/tests/crashes/118778.rs @@ -0,0 +1,24 @@ +//@ known-bug: #118778 +//@ edition:2021 +//@ needs-rustc-debug-assertions + +#![feature(generic_const_exprs)] +#![allow(incomplete_features)] + +trait Owner { + type T; +} + +impl Owner for () { + type T = U32<{ N + 1 }> + where + U32<{ N + 1 }>:; +} + +struct U32; + +fn take1(_: impl Owner = U32<1>>) {} + +fn main() { + take1(()); +} diff --git a/tests/crashes/118784.rs b/tests/crashes/118784.rs new file mode 100644 index 0000000000000..7bf943c8177c1 --- /dev/null +++ b/tests/crashes/118784.rs @@ -0,0 +1,19 @@ +//@ known-bug: #118784 +//@ needs-rustc-debug-assertions + +use std::collections::HashMap; + +macro_rules! all_sync_send { + ($ctor:expr, $($iter:expr),+) => ({ + $( + let mut x = $ctor; + is_sync(x.$iter()); + let mut y = $ctor; + is_send(y.$iter()); + )+ + }) +} + +fn main() { + all_sync_send!(HashMap, HashMap); +} diff --git a/tests/crashes/120175.rs b/tests/crashes/120175.rs new file mode 100644 index 0000000000000..c6e7203ff9882 --- /dev/null +++ b/tests/crashes/120175.rs @@ -0,0 +1,11 @@ +//@ known-bug: #120175 +//@ needs-rustc-debug-assertions + +#![feature(extern_types)] + +#[link(name = "bar", import_name_type = "decorated", kind = "raw-dylib")] +extern "C" { + pub type CrossCrate; +} + +fn main() {} diff --git a/tests/crashes/121176.rs b/tests/crashes/121176.rs new file mode 100644 index 0000000000000..4d82e51de8f80 --- /dev/null +++ b/tests/crashes/121176.rs @@ -0,0 +1,9 @@ +//@ known-bug: #121176 +//@ needs-rustc-debug-assertions +use std::fmt::Debug; + +static STATIC_1: dyn Debug + Sync = *(); + +fn main() { + println!("{:?}", &STATIC_1); +} diff --git a/tests/crashes/123861.rs b/tests/crashes/123861.rs new file mode 100644 index 0000000000000..60245960af0d6 --- /dev/null +++ b/tests/crashes/123861.rs @@ -0,0 +1,5 @@ +//@ known-bug: #123861 +//@ needs-rustc-debug-assertions + +struct _; +fn mainIterator<_ = _> {} diff --git a/tests/crashes/123862.rs b/tests/crashes/123862.rs new file mode 100644 index 0000000000000..075e0e6fc8fc8 --- /dev/null +++ b/tests/crashes/123862.rs @@ -0,0 +1,14 @@ +//@ known-bug: #123862 +//@ needs-rustc-debug-assertions + +macro_rules! pos { + () => { + (file![$($pos,)* pos!()], line!()) + }; +} + +fn outer() { + inner_inlined(main_pos, pos!()); +} + +fn inner_inlined() {} diff --git a/tests/crashes/130395.rs b/tests/crashes/130395.rs new file mode 100644 index 0000000000000..c1d189c79badb --- /dev/null +++ b/tests/crashes/130395.rs @@ -0,0 +1,10 @@ +//@ known-bug: #130395 +//@ needs-rustc-debug-assertions + +enum U { + B(isize, usize), +} + +fn main() { + let x = T::A(U::C); +} From 87fc2e3a7ea7b1cc0b11ad4259acbd976b982356 Mon Sep 17 00:00:00 2001 From: Urgau Date: Mon, 9 Dec 2024 19:35:02 +0100 Subject: [PATCH 02/20] Use newly added exceptions to non default branch warning --- triagebot.toml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/triagebot.toml b/triagebot.toml index c5dbd538f6c22..b7939710cab06 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -984,12 +984,20 @@ cc = ["@Zalathar"] cc = ["@kobzol"] [assign] -warn_non_default_branch = true +warn_non_default_branch.enable = true contributing_url = "https://rustc-dev-guide.rust-lang.org/getting-started.html" users_on_vacation = [ "jyn514", ] +[[assign.warn_non_default_branch.exceptions]] +title = "[beta" +branch = "beta" + +[[assign.warn_non_default_branch.exceptions]] +title = "[stable" +branch = "stable" + [assign.adhoc_groups] compiler = [ "@BoxyUwU", From 3b057796264e637b31c28809322028a32d22ae6f Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 16 Nov 2024 20:18:02 +0000 Subject: [PATCH 03/20] Add feature gate, not working yet --- compiler/rustc_feature/src/unstable.rs | 2 + compiler/rustc_span/src/symbol.rs | 1 + .../src/traits/dyn_compatibility.rs | 59 +++++++++++++++---- .../feature-gate-async-fn-in-dyn-trait.rs | 14 +++++ .../feature-gate-async-fn-in-dyn-trait.stderr | 48 +++++++++++++++ 5 files changed, 113 insertions(+), 11 deletions(-) create mode 100644 tests/ui/feature-gates/feature-gate-async-fn-in-dyn-trait.rs create mode 100644 tests/ui/feature-gates/feature-gate-async-fn-in-dyn-trait.stderr diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 93a605e197ce9..0454d30787506 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -390,6 +390,8 @@ declare_features! ( (unstable, associated_type_defaults, "1.2.0", Some(29661)), /// Allows `async || body` closures. (unstable, async_closure, "1.37.0", Some(62290)), + /// Allows async functions to be called from `dyn Trait`. + (incomplete, async_fn_in_dyn_trait, "CURRENT_RUSTC_VERSION", Some(133119)), /// Allows `#[track_caller]` on async functions. (unstable, async_fn_track_caller, "1.73.0", Some(110011)), /// Allows `for await` loops. diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index d30b17c9cd8dd..9b499c716039b 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -461,6 +461,7 @@ symbols! { async_drop_slice, async_drop_surface_drop_in_place, async_fn, + async_fn_in_dyn_trait, async_fn_in_trait, async_fn_kind_helper, async_fn_kind_upvars, diff --git a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs index c9297027519d7..d2abd881c4591 100644 --- a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs +++ b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs @@ -11,6 +11,7 @@ use rustc_abi::BackendRepr; use rustc_errors::FatalError; use rustc_hir as hir; use rustc_hir::def_id::DefId; +use rustc_middle::bug; use rustc_middle::query::Providers; use rustc_middle::ty::{ self, EarlyBinder, ExistentialPredicateStableCmpExt as _, GenericArgs, Ty, TyCtxt, @@ -901,23 +902,59 @@ fn contains_illegal_impl_trait_in_trait<'tcx>( fn_def_id: DefId, ty: ty::Binder<'tcx, Ty<'tcx>>, ) -> Option { - // This would be caught below, but rendering the error as a separate - // `async-specific` message is better. + let ty = tcx.liberate_late_bound_regions(fn_def_id, ty); + if tcx.asyncness(fn_def_id).is_async() { - return Some(MethodViolationCode::AsyncFn); + // FIXME(async_fn_in_dyn_trait): Think of a better way to unify these code paths + // to issue an appropriate feature suggestion when users try to use AFIDT. + // Obviously we must only do this once AFIDT is finished enough to actually be usable. + if tcx.features().async_fn_in_dyn_trait() { + let ty::Alias(ty::Projection, proj) = *ty.kind() else { + bug!("expected async fn in trait to return an RPITIT"); + }; + assert!(tcx.is_impl_trait_in_trait(proj.def_id)); + + // FIXME(async_fn_in_dyn_trait): We should check that this bound is legal too, + // and stop relying on `async fn` in the definition. + for bound in tcx.item_bounds(proj.def_id).instantiate(tcx, proj.args) { + if let Some(violation) = bound + .visit_with(&mut IllegalRpititVisitor { tcx, allowed: Some(proj) }) + .break_value() + { + return Some(violation); + } + } + + None + } else { + // Rendering the error as a separate `async-specific` message is better. + Some(MethodViolationCode::AsyncFn) + } + } else { + ty.visit_with(&mut IllegalRpititVisitor { tcx, allowed: None }).break_value() } +} + +struct IllegalRpititVisitor<'tcx> { + tcx: TyCtxt<'tcx>, + allowed: Option>, +} + +impl<'tcx> TypeVisitor> for IllegalRpititVisitor<'tcx> { + type Result = ControlFlow; - // FIXME(RPITIT): Perhaps we should use a visitor here? - ty.skip_binder().walk().find_map(|arg| { - if let ty::GenericArgKind::Type(ty) = arg.unpack() - && let ty::Alias(ty::Projection, proj) = ty.kind() - && tcx.is_impl_trait_in_trait(proj.def_id) + fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result { + if let ty::Alias(ty::Projection, proj) = *ty.kind() + && Some(proj) != self.allowed + && self.tcx.is_impl_trait_in_trait(proj.def_id) { - Some(MethodViolationCode::ReferencesImplTraitInTrait(tcx.def_span(proj.def_id))) + ControlFlow::Break(MethodViolationCode::ReferencesImplTraitInTrait( + self.tcx.def_span(proj.def_id), + )) } else { - None + ty.super_visit_with(self) } - }) + } } pub(crate) fn provide(providers: &mut Providers) { diff --git a/tests/ui/feature-gates/feature-gate-async-fn-in-dyn-trait.rs b/tests/ui/feature-gates/feature-gate-async-fn-in-dyn-trait.rs new file mode 100644 index 0000000000000..d9ff45f57ecba --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-async-fn-in-dyn-trait.rs @@ -0,0 +1,14 @@ +//@ edition: 2021 + +trait Foo { + async fn bar(&self); +} + +async fn takes_dyn_trait(x: &dyn Foo) { + //~^ ERROR the trait `Foo` cannot be made into an object + x.bar().await; + //~^ ERROR the trait `Foo` cannot be made into an object + //~| ERROR the trait `Foo` cannot be made into an object +} + +fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-async-fn-in-dyn-trait.stderr b/tests/ui/feature-gates/feature-gate-async-fn-in-dyn-trait.stderr new file mode 100644 index 0000000000000..f78fc422410be --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-async-fn-in-dyn-trait.stderr @@ -0,0 +1,48 @@ +error[E0038]: the trait `Foo` cannot be made into an object + --> $DIR/feature-gate-async-fn-in-dyn-trait.rs:7:30 + | +LL | async fn takes_dyn_trait(x: &dyn Foo) { + | ^^^^^^^ `Foo` 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 + --> $DIR/feature-gate-async-fn-in-dyn-trait.rs:4:14 + | +LL | trait Foo { + | --- this trait cannot be made into an object... +LL | async fn bar(&self); + | ^^^ ...because method `bar` is `async` + = help: consider moving `bar` to another trait + +error[E0038]: the trait `Foo` cannot be made into an object + --> $DIR/feature-gate-async-fn-in-dyn-trait.rs:9:7 + | +LL | x.bar().await; + | ^^^ `Foo` 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 + --> $DIR/feature-gate-async-fn-in-dyn-trait.rs:4:14 + | +LL | trait Foo { + | --- this trait cannot be made into an object... +LL | async fn bar(&self); + | ^^^ ...because method `bar` is `async` + = help: consider moving `bar` to another trait + +error[E0038]: the trait `Foo` cannot be made into an object + --> $DIR/feature-gate-async-fn-in-dyn-trait.rs:9:5 + | +LL | x.bar().await; + | ^^^^^^^ `Foo` 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 + --> $DIR/feature-gate-async-fn-in-dyn-trait.rs:4:14 + | +LL | trait Foo { + | --- this trait cannot be made into an object... +LL | async fn bar(&self); + | ^^^ ...because method `bar` is `async` + = help: consider moving `bar` to another trait + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0038`. From a7fa4cbcb498b80b126a954b5944f19a11e28dec Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 16 Nov 2024 20:18:13 +0000 Subject: [PATCH 04/20] Implement projection and shim for AFIDT --- compiler/rustc_middle/src/ty/instance.rs | 37 ++++---- compiler/rustc_middle/src/ty/mod.rs | 1 + .../ty/return_position_impl_trait_in_trait.rs | 95 +++++++++++++++++++ compiler/rustc_mir_transform/src/shim.rs | 56 ++++++++++- compiler/rustc_monomorphize/src/lib.rs | 5 +- .../src/traits/project.rs | 58 ++++++++++- .../src/traits/select/confirmation.rs | 74 +++++++++++++++ compiler/rustc_ty_utils/src/abi.rs | 26 +++++ .../ui/async-await/dyn/auxiliary/block-on.rs | 20 ++++ .../ui/async-await/dyn/mut-is-pointer-like.rs | 40 ++++++++ .../dyn/mut-is-pointer-like.run.stdout | 1 + .../dyn/mut-is-pointer-like.stderr | 11 +++ tests/ui/async-await/dyn/works.rs | 32 +++++++ tests/ui/async-await/dyn/works.run.stdout | 1 + tests/ui/async-await/dyn/works.stderr | 11 +++ tests/ui/async-await/dyn/wrong-size.rs | 23 +++++ tests/ui/async-await/dyn/wrong-size.stderr | 21 ++++ 17 files changed, 490 insertions(+), 22 deletions(-) create mode 100644 compiler/rustc_middle/src/ty/return_position_impl_trait_in_trait.rs create mode 100644 tests/ui/async-await/dyn/auxiliary/block-on.rs create mode 100644 tests/ui/async-await/dyn/mut-is-pointer-like.rs create mode 100644 tests/ui/async-await/dyn/mut-is-pointer-like.run.stdout create mode 100644 tests/ui/async-await/dyn/mut-is-pointer-like.stderr create mode 100644 tests/ui/async-await/dyn/works.rs create mode 100644 tests/ui/async-await/dyn/works.run.stdout create mode 100644 tests/ui/async-await/dyn/works.stderr create mode 100644 tests/ui/async-await/dyn/wrong-size.rs create mode 100644 tests/ui/async-await/dyn/wrong-size.stderr diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index 65c909e70f626..1dd564d979859 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -677,23 +677,26 @@ impl<'tcx> Instance<'tcx> { // // 1) The underlying method expects a caller location parameter // in the ABI - if resolved.def.requires_caller_location(tcx) - // 2) The caller location parameter comes from having `#[track_caller]` - // on the implementation, and *not* on the trait method. - && !tcx.should_inherit_track_caller(def) - // If the method implementation comes from the trait definition itself - // (e.g. `trait Foo { #[track_caller] my_fn() { /* impl */ } }`), - // then we don't need to generate a shim. This check is needed because - // `should_inherit_track_caller` returns `false` if our method - // implementation comes from the trait block, and not an impl block - && !matches!( - tcx.opt_associated_item(def), - Some(ty::AssocItem { - container: ty::AssocItemContainer::Trait, - .. - }) - ) - { + let needs_track_caller_shim = resolved.def.requires_caller_location(tcx) + // 2) The caller location parameter comes from having `#[track_caller]` + // on the implementation, and *not* on the trait method. + && !tcx.should_inherit_track_caller(def) + // If the method implementation comes from the trait definition itself + // (e.g. `trait Foo { #[track_caller] my_fn() { /* impl */ } }`), + // then we don't need to generate a shim. This check is needed because + // `should_inherit_track_caller` returns `false` if our method + // implementation comes from the trait block, and not an impl block + && !matches!( + tcx.opt_associated_item(def), + Some(ty::AssocItem { + container: ty::AssocItemContainer::Trait, + .. + }) + ); + // We also need to generate a shim if this is an AFIT. + let needs_rpitit_shim = + tcx.return_position_impl_trait_in_trait_shim_data(def).is_some(); + if needs_track_caller_shim || needs_rpitit_shim { if tcx.is_closure_like(def) { debug!( " => vtable fn pointer created for closure with #[track_caller]: {:?} for method {:?} {:?}", diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 70e0568b2025b..80b11892a4281 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -146,6 +146,7 @@ mod opaque_types; mod parameterized; mod predicate; mod region; +mod return_position_impl_trait_in_trait; mod rvalue_scopes; mod structural_impls; #[allow(hidden_glob_reexports)] diff --git a/compiler/rustc_middle/src/ty/return_position_impl_trait_in_trait.rs b/compiler/rustc_middle/src/ty/return_position_impl_trait_in_trait.rs new file mode 100644 index 0000000000000..21c605f8296d1 --- /dev/null +++ b/compiler/rustc_middle/src/ty/return_position_impl_trait_in_trait.rs @@ -0,0 +1,95 @@ +use rustc_hir::def_id::DefId; + +use crate::ty::{self, ExistentialPredicateStableCmpExt, TyCtxt}; + +impl<'tcx> TyCtxt<'tcx> { + /// Given a `def_id` of a trait or impl method, compute whether that method needs to + /// have an RPITIT shim applied to it for it to be object safe. If so, return the + /// `def_id` of the RPITIT, and also the args of trait method that returns the RPITIT. + /// + /// NOTE that these args are not, in general, the same as than the RPITIT's args. They + /// are a subset of those args, since they do not include the late-bound lifetimes of + /// the RPITIT. Depending on the context, these will need to be dealt with in different + /// ways -- in codegen, it's okay to fill them with ReErased. + pub fn return_position_impl_trait_in_trait_shim_data( + self, + def_id: DefId, + ) -> Option<(DefId, ty::EarlyBinder<'tcx, ty::GenericArgsRef<'tcx>>)> { + let assoc_item = self.opt_associated_item(def_id)?; + + let (trait_item_def_id, opt_impl_def_id) = match assoc_item.container { + ty::AssocItemContainer::Impl => { + (assoc_item.trait_item_def_id?, Some(self.parent(def_id))) + } + ty::AssocItemContainer::Trait => (def_id, None), + }; + + let sig = self.fn_sig(trait_item_def_id); + + // Check if the trait returns an RPITIT. + let ty::Alias(ty::Projection, ty::AliasTy { def_id, .. }) = + *sig.skip_binder().skip_binder().output().kind() + else { + return None; + }; + if !self.is_impl_trait_in_trait(def_id) { + return None; + } + + let args = if let Some(impl_def_id) = opt_impl_def_id { + // Rebase the args from the RPITIT onto the impl trait ref, so we can later + // substitute them with the method args of the *impl* method, since that's + // the instance we're building a vtable shim for. + ty::GenericArgs::identity_for_item(self, trait_item_def_id).rebase_onto( + self, + self.parent(trait_item_def_id), + self.impl_trait_ref(impl_def_id) + .expect("expected impl trait ref from parent of impl item") + .instantiate_identity() + .args, + ) + } else { + // This is when we have a default trait implementation. + ty::GenericArgs::identity_for_item(self, trait_item_def_id) + }; + + Some((def_id, ty::EarlyBinder::bind(args))) + } + + /// Given a `DefId` of an RPITIT and its args, return the existential predicates + /// that corresponds to the RPITIT's bounds with the self type erased. + pub fn item_bounds_to_existential_predicates( + self, + def_id: DefId, + args: ty::GenericArgsRef<'tcx>, + ) -> &'tcx ty::List> { + let mut bounds: Vec<_> = self + .item_super_predicates(def_id) + .iter_instantiated(self, args) + .filter_map(|clause| { + clause + .kind() + .map_bound(|clause| match clause { + ty::ClauseKind::Trait(trait_pred) => Some(ty::ExistentialPredicate::Trait( + ty::ExistentialTraitRef::erase_self_ty(self, trait_pred.trait_ref), + )), + ty::ClauseKind::Projection(projection_pred) => { + Some(ty::ExistentialPredicate::Projection( + ty::ExistentialProjection::erase_self_ty(self, projection_pred), + )) + } + ty::ClauseKind::TypeOutlives(_) => { + // Type outlives bounds don't really turn into anything, + // since we must use an intersection region for the `dyn*`'s + // region anyways. + None + } + _ => unreachable!("unexpected clause in item bounds: {clause:?}"), + }) + .transpose() + }) + .collect(); + bounds.sort_by(|a, b| a.skip_binder().stable_cmp(self, &b.skip_binder())); + self.mk_poly_existential_predicates(&bounds) + } +} diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index b8383e734e2ba..722da3c420dc9 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -9,6 +9,7 @@ use rustc_index::{Idx, IndexVec}; use rustc_middle::mir::patch::MirPatch; use rustc_middle::mir::*; use rustc_middle::query::Providers; +use rustc_middle::ty::adjustment::PointerCoercion; use rustc_middle::ty::{ self, CoroutineArgs, CoroutineArgsExt, EarlyBinder, GenericArgs, Ty, TyCtxt, }; @@ -710,6 +711,13 @@ fn build_call_shim<'tcx>( }; let def_id = instance.def_id(); + + let rpitit_shim = if let ty::InstanceKind::ReifyShim(..) = instance { + tcx.return_position_impl_trait_in_trait_shim_data(def_id) + } else { + None + }; + let sig = tcx.fn_sig(def_id); let sig = sig.map_bound(|sig| tcx.instantiate_bound_regions_with_erased(sig)); @@ -765,9 +773,34 @@ fn build_call_shim<'tcx>( let mut local_decls = local_decls_for_sig(&sig, span); let source_info = SourceInfo::outermost(span); + let mut destination = Place::return_place(); + if let Some((rpitit_def_id, fn_args)) = rpitit_shim { + let rpitit_args = + fn_args.instantiate_identity().extend_to(tcx, rpitit_def_id, |param, _| { + match param.kind { + ty::GenericParamDefKind::Lifetime => tcx.lifetimes.re_erased.into(), + ty::GenericParamDefKind::Type { .. } + | ty::GenericParamDefKind::Const { .. } => { + unreachable!("rpitit should have no addition ty/ct") + } + } + }); + let dyn_star_ty = Ty::new_dynamic( + tcx, + tcx.item_bounds_to_existential_predicates(rpitit_def_id, rpitit_args), + tcx.lifetimes.re_erased, + ty::DynStar, + ); + destination = local_decls.push(local_decls[RETURN_PLACE].clone()).into(); + local_decls[RETURN_PLACE].ty = dyn_star_ty; + let mut inputs_and_output = sig.inputs_and_output.to_vec(); + *inputs_and_output.last_mut().unwrap() = dyn_star_ty; + sig.inputs_and_output = tcx.mk_type_list(&inputs_and_output); + } + let rcvr_place = || { assert!(rcvr_adjustment.is_some()); - Place::from(Local::new(1 + 0)) + Place::from(Local::new(1)) }; let mut statements = vec![]; @@ -854,7 +887,7 @@ fn build_call_shim<'tcx>( TerminatorKind::Call { func: callee, args, - destination: Place::return_place(), + destination, target: Some(BasicBlock::new(1)), unwind: if let Some(Adjustment::RefMut) = rcvr_adjustment { UnwindAction::Cleanup(BasicBlock::new(3)) @@ -882,7 +915,24 @@ fn build_call_shim<'tcx>( ); } // BB #1/#2 - return - block(&mut blocks, vec![], TerminatorKind::Return, false); + // NOTE: If this is an RPITIT in dyn, we also want to coerce + // the return type of the function into a `dyn*`. + let stmts = if rpitit_shim.is_some() { + vec![Statement { + source_info, + kind: StatementKind::Assign(Box::new(( + Place::return_place(), + Rvalue::Cast( + CastKind::PointerCoercion(PointerCoercion::DynStar, CoercionSource::Implicit), + Operand::Move(destination), + sig.output(), + ), + ))), + }] + } else { + vec![] + }; + block(&mut blocks, stmts, TerminatorKind::Return, false); if let Some(Adjustment::RefMut) = rcvr_adjustment { // BB #3 - drop if closure panics block( diff --git a/compiler/rustc_monomorphize/src/lib.rs b/compiler/rustc_monomorphize/src/lib.rs index caae54cd55914..714b64b3a231c 100644 --- a/compiler/rustc_monomorphize/src/lib.rs +++ b/compiler/rustc_monomorphize/src/lib.rs @@ -42,7 +42,10 @@ fn custom_coerce_unsize_info<'tcx>( .. })) => Ok(tcx.coerce_unsized_info(impl_def_id)?.custom_kind.unwrap()), impl_source => { - bug!("invalid `CoerceUnsized` impl_source: {:?}", impl_source); + bug!( + "invalid `CoerceUnsized` from {source_ty} to {target_ty}: impl_source: {:?}", + impl_source + ); } } } diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 49c34550f8e03..9b8317fda7569 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -7,8 +7,8 @@ use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_errors::ErrorGuaranteed; use rustc_hir::def::DefKind; use rustc_hir::lang_items::LangItem; -use rustc_infer::infer::DefineOpaqueTypes; use rustc_infer::infer::resolve::OpportunisticRegionResolver; +use rustc_infer::infer::{DefineOpaqueTypes, RegionVariableOrigin}; use rustc_infer::traits::{ObligationCauseCode, PredicateObligations}; use rustc_middle::traits::select::OverflowError; use rustc_middle::traits::{BuiltinImplSource, ImplSource, ImplSourceUserDefinedData}; @@ -18,6 +18,7 @@ use rustc_middle::ty::visit::TypeVisitableExt; use rustc_middle::ty::{self, Term, Ty, TyCtxt, TypingMode, Upcast}; use rustc_middle::{bug, span_bug}; use rustc_span::symbol::sym; +use thin_vec::thin_vec; use tracing::{debug, instrument}; use super::{ @@ -61,6 +62,9 @@ enum ProjectionCandidate<'tcx> { /// Bounds specified on an object type Object(ty::PolyProjectionPredicate<'tcx>), + /// Built-in bound for a dyn async fn in trait + ObjectRpitit, + /// From an "impl" (or a "pseudo-impl" returned by select) Select(Selection<'tcx>), } @@ -827,6 +831,17 @@ fn assemble_candidates_from_object_ty<'cx, 'tcx>( env_predicates, false, ); + + // `dyn Trait` automagically project their AFITs to `dyn* Future`. + if tcx.is_impl_trait_in_trait(obligation.predicate.def_id) + && let Some(out_trait_def_id) = data.principal_def_id() + && let rpitit_trait_def_id = tcx.parent(obligation.predicate.def_id) + && tcx + .supertrait_def_ids(out_trait_def_id) + .any(|trait_def_id| trait_def_id == rpitit_trait_def_id) + { + candidate_set.push_candidate(ProjectionCandidate::ObjectRpitit); + } } #[instrument( @@ -1247,6 +1262,8 @@ fn confirm_candidate<'cx, 'tcx>( ProjectionCandidate::Select(impl_source) => { confirm_select_candidate(selcx, obligation, impl_source) } + + ProjectionCandidate::ObjectRpitit => confirm_object_rpitit_candidate(selcx, obligation), }; // When checking for cycle during evaluation, we compare predicates with @@ -2034,6 +2051,45 @@ fn confirm_impl_candidate<'cx, 'tcx>( } } +fn confirm_object_rpitit_candidate<'cx, 'tcx>( + selcx: &mut SelectionContext<'cx, 'tcx>, + obligation: &ProjectionTermObligation<'tcx>, +) -> Progress<'tcx> { + let tcx = selcx.tcx(); + let mut obligations = thin_vec![]; + + // Compute an intersection lifetime for all the input components of this GAT. + let intersection = + selcx.infcx.next_region_var(RegionVariableOrigin::MiscVariable(obligation.cause.span)); + for component in obligation.predicate.args { + match component.unpack() { + ty::GenericArgKind::Lifetime(lt) => { + obligations.push(obligation.with(tcx, ty::OutlivesPredicate(lt, intersection))); + } + ty::GenericArgKind::Type(ty) => { + obligations.push(obligation.with(tcx, ty::OutlivesPredicate(ty, intersection))); + } + ty::GenericArgKind::Const(_ct) => { + // Consts have no outlives... + } + } + } + + Progress { + term: Ty::new_dynamic( + tcx, + tcx.item_bounds_to_existential_predicates( + obligation.predicate.def_id, + obligation.predicate.args, + ), + intersection, + ty::DynStar, + ) + .into(), + obligations, + } +} + // Get obligations corresponding to the predicates from the where-clause of the // associated type itself. fn assoc_ty_own_obligations<'cx, 'tcx>( diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 2fbe2e1e323be..3664121ac4b8c 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -19,6 +19,7 @@ use rustc_middle::traits::{BuiltinImplSource, SignatureMismatchData}; use rustc_middle::ty::{self, GenericArgsRef, ToPolyTraitRef, Ty, TyCtxt, Upcast}; use rustc_middle::{bug, span_bug}; use rustc_span::def_id::DefId; +use rustc_type_ir::elaborate; use tracing::{debug, instrument}; use super::SelectionCandidate::{self, *}; @@ -624,6 +625,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { for assoc_type in assoc_types { let defs: &ty::Generics = tcx.generics_of(assoc_type); + // When `async_fn_in_dyn_trait` is enabled, we don't need to check the + // RPITIT for compatibility, since it's not provided by the user. + if tcx.features().async_fn_in_dyn_trait() && tcx.is_impl_trait_in_trait(assoc_type) { + continue; + } + if !defs.own_params.is_empty() { tcx.dcx().span_delayed_bug( obligation.cause.span, @@ -1175,6 +1182,33 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ty::ClauseKind::TypeOutlives(outlives).upcast(tcx), )); + // Require that all AFIT will return something that can be coerced into `dyn*` + // -- a shim will be responsible for doing the actual coercion to `dyn*`. + if let Some(principal) = data.principal() { + for supertrait in + elaborate::supertraits(tcx, principal.with_self_ty(tcx, source)) + { + if tcx.is_trait_alias(supertrait.def_id()) { + continue; + } + + for &assoc_item in tcx.associated_item_def_ids(supertrait.def_id()) { + if !tcx.is_impl_trait_in_trait(assoc_item) { + continue; + } + + let pointer_like_goal = pointer_like_goal_for_rpitit( + tcx, + supertrait, + assoc_item, + &obligation.cause, + ); + + nested.push(predicate_to_obligation(pointer_like_goal.upcast(tcx))); + } + } + } + ImplSource::Builtin(BuiltinImplSource::Misc, nested) } @@ -1280,3 +1314,43 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { }) } } + +/// Compute a goal that some RPITIT (right now, only RPITITs corresponding to Futures) +/// implements the `PointerLike` trait, which is a requirement for the RPITIT to be +/// coercible to `dyn* Future`, which is itself a requirement for the RPITIT's parent +/// trait to be coercible to `dyn Trait`. +/// +/// We do this given a supertrait's substitutions, and then augment the substitutions +/// with bound variables to compute the goal universally. Given that `PointerLike` has +/// no region requirements (at least for the built-in pointer types), this shouldn't +/// *really* matter, but it is the best choice for soundness. +fn pointer_like_goal_for_rpitit<'tcx>( + tcx: TyCtxt<'tcx>, + supertrait: ty::PolyTraitRef<'tcx>, + rpitit_item: DefId, + cause: &ObligationCause<'tcx>, +) -> ty::PolyTraitRef<'tcx> { + let mut bound_vars = supertrait.bound_vars().to_vec(); + + let args = supertrait.skip_binder().args.extend_to(tcx, rpitit_item, |arg, _| match arg.kind { + ty::GenericParamDefKind::Lifetime => { + let kind = ty::BoundRegionKind::Named(arg.def_id, tcx.item_name(arg.def_id)); + bound_vars.push(ty::BoundVariableKind::Region(kind)); + ty::Region::new_bound(tcx, ty::INNERMOST, ty::BoundRegion { + var: ty::BoundVar::from_usize(bound_vars.len() - 1), + kind, + }) + .into() + } + ty::GenericParamDefKind::Type { .. } | ty::GenericParamDefKind::Const { .. } => { + unreachable!() + } + }); + + ty::Binder::bind_with_vars( + ty::TraitRef::new(tcx, tcx.require_lang_item(LangItem::PointerLike, Some(cause.span)), [ + Ty::new_projection_from_args(tcx, rpitit_item, args), + ]), + tcx.mk_bound_variable_kinds(&bound_vars), + ) +} diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index ae6d697794fe5..b63534880d1c4 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -48,12 +48,38 @@ fn fn_sig_for_fn_abi<'tcx>( let mut sig = tcx .instantiate_bound_regions_with_erased(tcx.fn_sig(def_id).instantiate(tcx, args)); + // Modify `fn(self, ...)` to `fn(self: *mut Self, ...)`. if let ty::InstanceKind::VTableShim(..) = instance.def { let mut inputs_and_output = sig.inputs_and_output.to_vec(); inputs_and_output[0] = Ty::new_mut_ptr(tcx, inputs_and_output[0]); sig.inputs_and_output = tcx.mk_type_list(&inputs_and_output); } + // Modify `fn() -> impl Future` to `fn() -> dyn* Future`. + if let ty::InstanceKind::ReifyShim(def_id, _) = instance.def + && let Some((rpitit_def_id, fn_args)) = + tcx.return_position_impl_trait_in_trait_shim_data(def_id) + { + let fn_args = fn_args.instantiate(tcx, args); + let rpitit_args = + fn_args.extend_to(tcx, rpitit_def_id, |param, _| match param.kind { + ty::GenericParamDefKind::Lifetime => tcx.lifetimes.re_erased.into(), + ty::GenericParamDefKind::Type { .. } + | ty::GenericParamDefKind::Const { .. } => { + unreachable!("rpitit should have no addition ty/ct") + } + }); + let dyn_star_ty = Ty::new_dynamic( + tcx, + tcx.item_bounds_to_existential_predicates(rpitit_def_id, rpitit_args), + tcx.lifetimes.re_erased, + ty::DynStar, + ); + let mut inputs_and_output = sig.inputs_and_output.to_vec(); + *inputs_and_output.last_mut().unwrap() = dyn_star_ty; + sig.inputs_and_output = tcx.mk_type_list(&inputs_and_output); + } + sig } ty::Closure(def_id, args) => { diff --git a/tests/ui/async-await/dyn/auxiliary/block-on.rs b/tests/ui/async-await/dyn/auxiliary/block-on.rs new file mode 100644 index 0000000000000..dcb710fc97c97 --- /dev/null +++ b/tests/ui/async-await/dyn/auxiliary/block-on.rs @@ -0,0 +1,20 @@ +//@ edition: 2021 + +#![feature(async_closure, noop_waker)] + +use std::future::Future; +use std::pin::pin; +use std::task::*; + +pub fn block_on(fut: impl Future) -> T { + let mut fut = pin!(fut); + // Poll loop, just to test the future... + let ctx = &mut Context::from_waker(Waker::noop()); + + loop { + match unsafe { fut.as_mut().poll(ctx) } { + Poll::Pending => {} + Poll::Ready(t) => break t, + } + } +} diff --git a/tests/ui/async-await/dyn/mut-is-pointer-like.rs b/tests/ui/async-await/dyn/mut-is-pointer-like.rs new file mode 100644 index 0000000000000..93e8281164ce9 --- /dev/null +++ b/tests/ui/async-await/dyn/mut-is-pointer-like.rs @@ -0,0 +1,40 @@ +//@ aux-build:block-on.rs +//@ edition: 2021 +//@ run-pass +//@ check-run-results + +#![allow(refining_impl_trait)] +#![feature(async_fn_in_dyn_trait)] +//~^ WARN the feature `async_fn_in_dyn_trait` is incomplete + +extern crate block_on; + +use std::future::Future; +use std::pin::Pin; + +trait AsyncTrait { + type Output; + + async fn async_dispatch(self: Pin<&mut Self>) -> Self::Output; +} + +impl AsyncTrait for F +where + F: Future, +{ + type Output = F::Output; + + fn async_dispatch(self: Pin<&mut Self>) -> Pin<&mut Self> { + self + } +} + +fn main() { + block_on::block_on(async { + let f = std::pin::pin!(async { + println!("hello, world"); + }); + let x: Pin<&mut dyn AsyncTrait> = f; + x.async_dispatch().await; + }); +} diff --git a/tests/ui/async-await/dyn/mut-is-pointer-like.run.stdout b/tests/ui/async-await/dyn/mut-is-pointer-like.run.stdout new file mode 100644 index 0000000000000..4b5fa63702dd9 --- /dev/null +++ b/tests/ui/async-await/dyn/mut-is-pointer-like.run.stdout @@ -0,0 +1 @@ +hello, world diff --git a/tests/ui/async-await/dyn/mut-is-pointer-like.stderr b/tests/ui/async-await/dyn/mut-is-pointer-like.stderr new file mode 100644 index 0000000000000..7c72ce43cf05a --- /dev/null +++ b/tests/ui/async-await/dyn/mut-is-pointer-like.stderr @@ -0,0 +1,11 @@ +warning: the feature `async_fn_in_dyn_trait` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/mut-is-pointer-like.rs:7:12 + | +LL | #![feature(async_fn_in_dyn_trait)] + | ^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #133119 for more information + = note: `#[warn(incomplete_features)]` on by default + +warning: 1 warning emitted + diff --git a/tests/ui/async-await/dyn/works.rs b/tests/ui/async-await/dyn/works.rs new file mode 100644 index 0000000000000..0732a3ee2f263 --- /dev/null +++ b/tests/ui/async-await/dyn/works.rs @@ -0,0 +1,32 @@ +//@ aux-build:block-on.rs +//@ edition: 2021 +//@ run-pass +//@ check-run-results + +#![allow(refining_impl_trait)] +#![feature(async_fn_in_dyn_trait)] +//~^ WARN the feature `async_fn_in_dyn_trait` is incomplete + +extern crate block_on; + +use std::pin::Pin; +use std::future::Future; + +trait AsyncTrait { + async fn async_dispatch(&self); +} + +impl AsyncTrait for &'static str { + fn async_dispatch(&self) -> Pin>> { + Box::pin(async move { + println!("message from the aether: {self}"); + }) + } +} + +fn main() { + block_on::block_on(async { + let x: &dyn AsyncTrait = &"hello, world!"; + x.async_dispatch().await; + }); +} diff --git a/tests/ui/async-await/dyn/works.run.stdout b/tests/ui/async-await/dyn/works.run.stdout new file mode 100644 index 0000000000000..7b45a504e60c7 --- /dev/null +++ b/tests/ui/async-await/dyn/works.run.stdout @@ -0,0 +1 @@ +message from the aether: hello, world! diff --git a/tests/ui/async-await/dyn/works.stderr b/tests/ui/async-await/dyn/works.stderr new file mode 100644 index 0000000000000..2c7db7c32f59f --- /dev/null +++ b/tests/ui/async-await/dyn/works.stderr @@ -0,0 +1,11 @@ +warning: the feature `async_fn_in_dyn_trait` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/works.rs:7:12 + | +LL | #![feature(async_fn_in_dyn_trait)] + | ^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #133119 for more information + = note: `#[warn(incomplete_features)]` on by default + +warning: 1 warning emitted + diff --git a/tests/ui/async-await/dyn/wrong-size.rs b/tests/ui/async-await/dyn/wrong-size.rs new file mode 100644 index 0000000000000..ac15dd2606767 --- /dev/null +++ b/tests/ui/async-await/dyn/wrong-size.rs @@ -0,0 +1,23 @@ +//@ edition: 2021 + +#![feature(async_fn_in_dyn_trait)] +//~^ WARN the feature `async_fn_in_dyn_trait` is incomplete + +use std::future::Future; + +trait AsyncTrait { + async fn async_dispatch(&self); +} + +impl AsyncTrait for &'static str { + fn async_dispatch(&self) -> impl Future { + async move { + // The implementor must box the future... + } + } +} + +fn main() { + let x: &dyn AsyncTrait = &"hello, world!"; + //~^ ERROR `impl Future` needs to have the same ABI as a pointer +} diff --git a/tests/ui/async-await/dyn/wrong-size.stderr b/tests/ui/async-await/dyn/wrong-size.stderr new file mode 100644 index 0000000000000..0202b5f240977 --- /dev/null +++ b/tests/ui/async-await/dyn/wrong-size.stderr @@ -0,0 +1,21 @@ +warning: the feature `async_fn_in_dyn_trait` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/wrong-size.rs:3:12 + | +LL | #![feature(async_fn_in_dyn_trait)] + | ^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #133119 for more information + = note: `#[warn(incomplete_features)]` on by default + +error[E0277]: `impl Future` needs to have the same ABI as a pointer + --> $DIR/wrong-size.rs:21:30 + | +LL | let x: &dyn AsyncTrait = &"hello, world!"; + | ^^^^^^^^^^^^^^^^ `impl Future` needs to be a pointer-like type + | + = help: the trait `for<'a> PointerLike` is not implemented for `impl Future` + = note: required for the cast from `&&'static str` to `&dyn AsyncTrait` + +error: aborting due to 1 previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0277`. From 57e8a1c9c3b753f3a96a124149ca1ba07f0db483 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 10 Dec 2024 17:20:54 +0000 Subject: [PATCH 05/20] Don't check RPITITs that are Self:Sized for PointerLike --- .../src/traits/select/confirmation.rs | 5 +++++ .../in-trait/sized-rpits-dont-need-pointer-like.rs | 13 +++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 tests/ui/impl-trait/in-trait/sized-rpits-dont-need-pointer-like.rs diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 3664121ac4b8c..962b6b94fa625 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -1197,6 +1197,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { continue; } + // RPITITs with `Self: Sized` don't need to be checked. + if tcx.generics_require_sized_self(assoc_item) { + continue; + } + let pointer_like_goal = pointer_like_goal_for_rpitit( tcx, supertrait, diff --git a/tests/ui/impl-trait/in-trait/sized-rpits-dont-need-pointer-like.rs b/tests/ui/impl-trait/in-trait/sized-rpits-dont-need-pointer-like.rs new file mode 100644 index 0000000000000..80850a2639fbd --- /dev/null +++ b/tests/ui/impl-trait/in-trait/sized-rpits-dont-need-pointer-like.rs @@ -0,0 +1,13 @@ +//@ check-pass + +// Make sure that we don't enforce that an RPIT that has `where Self: Sized` is pointer-like. + +trait Foo { + fn foo() -> impl Sized where Self: Sized {} +} + +impl Foo for () {} + +fn main() { + let x: &dyn Foo = &(); +} From 78f3946ffd44aff5c57baf4192d9adbd70c3f576 Mon Sep 17 00:00:00 2001 From: WANG Rui Date: Wed, 20 Nov 2024 22:03:20 +0800 Subject: [PATCH 06/20] ABI checks: add support for loongarch LoongArch psABI[^1] specifies that LSX vector types are passed via general-purpose registers, while LASX vector types are passed indirectly through the stack. This patch addresses the following warnings: ``` warning: this function call uses a SIMD vector type that is not currently supported with the chosen ABI --> .../library/core/src/../../stdarch/crates/core_arch/src/loongarch64/lsx/generated.rs:3695:5 | 3695 | __lsx_vreplgr2vr_b(a) | ^^^^^^^^^^^^^^^^^^^^^ function called here | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #116558 = note: `#[warn(abi_unsupported_vector_types)]` on by default ``` [^1]: https://github.com/loongson/la-abi-specs/blob/release/lapcs.adoc --- compiler/rustc_target/src/target_features.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs index 3a1306072658d..c89045c93e304 100644 --- a/compiler/rustc_target/src/target_features.rs +++ b/compiler/rustc_target/src/target_features.rs @@ -611,6 +611,8 @@ const HEXAGON_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[/*(512, "hvx-length64b"),*/ (1024, "hvx-length128b")]; const MIPS_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "msa")]; const CSKY_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "vdspv1")]; +const LOONGARCH_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = + &[(128, "lsx"), (256, "lasx")]; impl super::spec::Target { pub fn rust_target_features(&self) -> &'static [(&'static str, Stability, ImpliedFeatures)] { @@ -638,7 +640,7 @@ impl super::spec::Target { "aarch64" | "arm64ec" => AARCH64_FEATURES_FOR_CORRECT_VECTOR_ABI, "arm" => ARM_FEATURES_FOR_CORRECT_VECTOR_ABI, "powerpc" | "powerpc64" => POWERPC_FEATURES_FOR_CORRECT_VECTOR_ABI, - "loongarch64" => &[], // on-stack ABI, so we complain about all by-val vectors + "loongarch64" => LOONGARCH_FEATURES_FOR_CORRECT_VECTOR_ABI, "riscv32" | "riscv64" => RISCV_FEATURES_FOR_CORRECT_VECTOR_ABI, "wasm32" | "wasm64" => WASM_FEATURES_FOR_CORRECT_VECTOR_ABI, "s390x" => S390X_FEATURES_FOR_CORRECT_VECTOR_ABI, From e75660dad3827fab87d96e2c65a7836fd5511b69 Mon Sep 17 00:00:00 2001 From: Adrian Taylor Date: Fri, 25 Oct 2024 11:08:58 +0000 Subject: [PATCH 07/20] Arbitrary self types v2: use Receiver trait In this new version of Arbitrary Self Types, we no longer use the Deref trait exclusively when working out which self types are valid. Instead, we follow a chain of Receiver traits. This enables methods to be called on smart pointer types which fundamentally cannot support Deref (for instance because they are wrappers for pointers that don't follow Rust's aliasing rules). This includes: * Changes to tests appropriately * New tests for: * The basics of the feature * Ensuring lifetime elision works properly * Generic Receivers * A copy of the method subst test enhanced with Receiver This is really the heart of the 'arbitrary self types v2' feature, and is the most critical commit in the current PR. Subsequent commits are focused on: * Detecting "shadowing" problems, where a smart pointer type can hide methods in the pointee. * Diagnostics and cleanup. Naming: in this commit, the "Autoderef" type is modified so that it no longer solely focuses on the "Deref" trait, but can now consider the "Receiver" trait instead. Should it be renamed, to something like "TraitFollower"? This was considered, but rejected, because * even in the Receiver case, it still considers built-in derefs * the name Autoderef is short and snappy. --- .../src/error_codes/E0307.md | 6 +- compiler/rustc_hir_analysis/messages.ftl | 4 +- compiler/rustc_hir_analysis/src/autoderef.rs | 37 +++++-- .../rustc_hir_analysis/src/check/wfcheck.rs | 27 ++++-- compiler/rustc_hir_typeck/src/method/probe.rs | 97 ++++++++++++++----- compiler/rustc_middle/src/traits/query.rs | 12 ++- .../inference_var_self_argument.stderr | 4 +- tests/ui/async-await/issue-66312.stderr | 4 +- ...-gate-arbitrary-self-types-pointers.stderr | 6 +- .../feature-gate-arbitrary-self-types.stderr | 6 +- ...te-arbitrary_self_types-raw-pointer.stderr | 6 +- ...feature-gate-dispatch-from-dyn-cell.stderr | 4 +- tests/ui/issues/issue-56806.stderr | 4 +- .../could-not-resolve-issue-121503.stderr | 2 +- .../methods/call_method_unknown_referent.rs | 48 +++++++++ .../call_method_unknown_referent.stderr | 29 ++++++ .../methods/call_method_unknown_referent2.rs | 24 +++++ ...y-self-from-method-substs-with-receiver.rs | 64 ++++++++++++ ...lf-from-method-substs-with-receiver.stderr | 70 +++++++++++++ ...ary-self-from-method-substs.default.stderr | 4 +- tests/ui/self/arbitrary-self-opaque.stderr | 4 +- ...itrary_self_types_generic_over_receiver.rs | 23 +++++ ...ry_self_types_generic_over_receiver.stderr | 59 +++++++++++ .../arbitrary_self_types_lifetime_elision.rs | 27 ++++++ .../self/arbitrary_self_types_no_generics.rs | 32 ++++++ ...self_types_not_allow_call_with_no_deref.rs | 38 ++++++++ ..._types_not_allow_call_with_no_deref.stderr | 39 ++++++++ ...arbitrary_self_types_recursive_receiver.rs | 32 ++++++ ...itrary_self_types_struct_receiver_trait.rs | 31 ++++++ ...bitrary_self_types_trait_receiver_trait.rs | 25 +++++ tests/ui/span/issue-27522.stderr | 4 +- ...atible-trait-should-use-where-sized.stderr | 4 +- .../effects/auxiliary/minicore.rs | 10 ++ tests/ui/traits/issue-78372.stderr | 4 +- .../method_resolution3.current.stderr | 8 +- .../method_resolution3.next.stderr | 8 +- .../method_resolution4.current.stderr | 8 +- .../method_resolution4.next.stderr | 8 +- tests/ui/ufcs/ufcs-explicit-self-bad.stderr | 12 +-- 39 files changed, 737 insertions(+), 97 deletions(-) create mode 100644 tests/ui/methods/call_method_unknown_referent.rs create mode 100644 tests/ui/methods/call_method_unknown_referent.stderr create mode 100644 tests/ui/methods/call_method_unknown_referent2.rs create mode 100644 tests/ui/self/arbitrary-self-from-method-substs-with-receiver.rs create mode 100644 tests/ui/self/arbitrary-self-from-method-substs-with-receiver.stderr create mode 100644 tests/ui/self/arbitrary_self_types_generic_over_receiver.rs create mode 100644 tests/ui/self/arbitrary_self_types_generic_over_receiver.stderr create mode 100644 tests/ui/self/arbitrary_self_types_lifetime_elision.rs create mode 100644 tests/ui/self/arbitrary_self_types_no_generics.rs create mode 100644 tests/ui/self/arbitrary_self_types_not_allow_call_with_no_deref.rs create mode 100644 tests/ui/self/arbitrary_self_types_not_allow_call_with_no_deref.stderr create mode 100644 tests/ui/self/arbitrary_self_types_recursive_receiver.rs create mode 100644 tests/ui/self/arbitrary_self_types_struct_receiver_trait.rs create mode 100644 tests/ui/self/arbitrary_self_types_trait_receiver_trait.rs diff --git a/compiler/rustc_error_codes/src/error_codes/E0307.md b/compiler/rustc_error_codes/src/error_codes/E0307.md index 0d29d56ea1a75..b9c0493e8d6e6 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0307.md +++ b/compiler/rustc_error_codes/src/error_codes/E0307.md @@ -65,8 +65,10 @@ impl Trait for Foo { ``` The nightly feature [Arbitrary self types][AST] extends the accepted -set of receiver types to also include any type that can dereference to -`Self`: +set of receiver types to also include any type that implements the +`Receiver` trait and can follow its chain of `Target` types to `Self`. +There's a blanket implementation of `Receiver` for `T: Deref`, so any +type which dereferences to `Self` can be used. ``` #![feature(arbitrary_self_types)] diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index 32498d9c5ab5b..25feb95d5dfeb 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -241,10 +241,10 @@ hir_analysis_invalid_generic_receiver_ty_help = use a concrete type such as `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) hir_analysis_invalid_receiver_ty = invalid `self` parameter type: `{$receiver_ty}` - .note = type of `self` must be `Self` or a type that dereferences to it + .note = type of `self` must be `Self` or some type implementing `Receiver` hir_analysis_invalid_receiver_ty_help = - consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box`, `self: Rc`, or `self: Arc` hir_analysis_invalid_union_field = field must implement `Copy` or be wrapped in `ManuallyDrop<...>` to be used in a union diff --git a/compiler/rustc_hir_analysis/src/autoderef.rs b/compiler/rustc_hir_analysis/src/autoderef.rs index 5a66c31a0cc31..d8e9227a87c86 100644 --- a/compiler/rustc_hir_analysis/src/autoderef.rs +++ b/compiler/rustc_hir_analysis/src/autoderef.rs @@ -18,7 +18,6 @@ pub enum AutoderefKind { /// A type which must dispatch to a `Deref` implementation. Overloaded, } - struct AutoderefSnapshot<'tcx> { at_start: bool, reached_recursion_limit: bool, @@ -27,6 +26,10 @@ struct AutoderefSnapshot<'tcx> { obligations: PredicateObligations<'tcx>, } +/// Recursively dereference a type, considering both built-in +/// dereferences (`*`) and the `Deref` trait. +/// Although called `Autoderef` it can be configured to use the +/// `Receiver` trait instead of the `Deref` trait. pub struct Autoderef<'a, 'tcx> { // Meta infos: infcx: &'a InferCtxt<'tcx>, @@ -39,6 +42,7 @@ pub struct Autoderef<'a, 'tcx> { // Configurations: include_raw_pointers: bool, + use_receiver_trait: bool, silence_errors: bool, } @@ -69,6 +73,10 @@ impl<'a, 'tcx> Iterator for Autoderef<'a, 'tcx> { } // Otherwise, deref if type is derefable: + // NOTE: in the case of self.use_receiver_trait = true, you might think it would + // be better to skip this clause and use the Overloaded case only, since &T + // and &mut T implement Receiver. But built-in derefs apply equally to Receiver + // and Deref, and this has benefits for const and the emitted MIR. let (kind, new_ty) = if let Some(ty) = self.state.cur_ty.builtin_deref(self.include_raw_pointers) { debug_assert_eq!(ty, self.infcx.resolve_vars_if_possible(ty)); @@ -111,7 +119,7 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> { body_def_id: LocalDefId, span: Span, base_ty: Ty<'tcx>, - ) -> Autoderef<'a, 'tcx> { + ) -> Self { Autoderef { infcx, span, @@ -125,6 +133,7 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> { reached_recursion_limit: false, }, include_raw_pointers: false, + use_receiver_trait: false, silence_errors: false, } } @@ -137,8 +146,13 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> { return None; } - // - let trait_ref = ty::TraitRef::new(tcx, tcx.lang_items().deref_trait()?, [ty]); + // , or whatever the equivalent trait is that we've been asked to walk. + let (trait_def_id, trait_target_def_id) = if self.use_receiver_trait { + (tcx.lang_items().receiver_trait()?, tcx.lang_items().receiver_target()?) + } else { + (tcx.lang_items().deref_trait()?, tcx.lang_items().deref_target()?) + }; + let trait_ref = ty::TraitRef::new(tcx, trait_def_id, [ty]); let cause = traits::ObligationCause::misc(self.span, self.body_id); let obligation = traits::Obligation::new( tcx, @@ -151,11 +165,8 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> { return None; } - let (normalized_ty, obligations) = self.structurally_normalize(Ty::new_projection( - tcx, - tcx.lang_items().deref_target()?, - [ty], - ))?; + let (normalized_ty, obligations) = + self.structurally_normalize(Ty::new_projection(tcx, trait_target_def_id, [ty]))?; debug!("overloaded_deref_ty({:?}) = ({:?}, {:?})", ty, normalized_ty, obligations); self.state.obligations.extend(obligations); @@ -234,6 +245,14 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> { self } + /// Use `core::ops::Receiver` and `core::ops::Receiver::Target` as + /// the trait and associated type to iterate, instead of + /// `core::ops::Deref` and `core::ops::Deref::Target` + pub fn use_receiver_trait(mut self) -> Self { + self.use_receiver_trait = true; + self + } + pub fn silence_errors(mut self) -> Self { self.silence_errors = true; self diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index c9773972d9a24..57264d0bd2afc 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1821,13 +1821,18 @@ fn receiver_is_valid<'tcx>( let mut autoderef = Autoderef::new(infcx, wfcx.param_env, wfcx.body_def_id, span, receiver_ty); + // The `arbitrary_self_types` feature allows custom smart pointer + // types to be method receivers, as identified by following the Receiver + // chain. + if arbitrary_self_types_enabled.is_some() { + autoderef = autoderef.use_receiver_trait(); + } + // The `arbitrary_self_types_pointers` feature allows raw pointer receivers like `self: *const Self`. if arbitrary_self_types_enabled == Some(ArbitrarySelfTypesLevel::WithPointers) { autoderef = autoderef.include_raw_pointers(); } - let receiver_trait_def_id = tcx.require_lang_item(LangItem::LegacyReceiver, Some(span)); - // Keep dereferencing `receiver_ty` until we get to `self_ty`. while let Some((potential_self_ty, _)) = autoderef.next() { debug!( @@ -1849,11 +1854,13 @@ fn receiver_is_valid<'tcx>( } // Without `feature(arbitrary_self_types)`, we require that each step in the - // deref chain implement `receiver`. + // deref chain implement `LegacyReceiver`. if arbitrary_self_types_enabled.is_none() { - if !receiver_is_implemented( + let legacy_receiver_trait_def_id = + tcx.require_lang_item(LangItem::LegacyReceiver, Some(span)); + if !legacy_receiver_is_implemented( wfcx, - receiver_trait_def_id, + legacy_receiver_trait_def_id, cause.clone(), potential_self_ty, ) { @@ -1866,7 +1873,7 @@ fn receiver_is_valid<'tcx>( cause.clone(), wfcx.param_env, potential_self_ty, - receiver_trait_def_id, + legacy_receiver_trait_def_id, ); } } @@ -1875,14 +1882,14 @@ fn receiver_is_valid<'tcx>( Err(ReceiverValidityError::DoesNotDeref) } -fn receiver_is_implemented<'tcx>( +fn legacy_receiver_is_implemented<'tcx>( wfcx: &WfCheckingCtxt<'_, 'tcx>, - receiver_trait_def_id: DefId, + legacy_receiver_trait_def_id: DefId, cause: ObligationCause<'tcx>, receiver_ty: Ty<'tcx>, ) -> bool { let tcx = wfcx.tcx(); - let trait_ref = ty::TraitRef::new(tcx, receiver_trait_def_id, [receiver_ty]); + let trait_ref = ty::TraitRef::new(tcx, legacy_receiver_trait_def_id, [receiver_ty]); let obligation = Obligation::new(tcx, cause, wfcx.param_env, trait_ref); @@ -1890,7 +1897,7 @@ fn receiver_is_implemented<'tcx>( true } else { debug!( - "receiver_is_implemented: type `{:?}` does not implement `Receiver` trait", + "receiver_is_implemented: type `{:?}` does not implement `LegacyReceiver` trait", receiver_ty ); false diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 039c117c09995..91e65af8df954 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -366,6 +366,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { autoderefs: 0, from_unsafe_deref: false, unsize: false, + reachable_via_deref: true, }]), opt_bad_ty: None, reached_recursion_limit: false, @@ -516,47 +517,93 @@ fn method_autoderef_steps<'tcx>( let (ref infcx, goal, inference_vars) = tcx.infer_ctxt().build_with_canonical(DUMMY_SP, &goal); let ParamEnvAnd { param_env, value: self_ty } = goal; - let mut autoderef = + // If arbitrary self types is not enabled, we follow the chain of + // `Deref`. If arbitrary self types is enabled, we instead + // follow the chain of `Receiver`, but we also record whether + // such types are reachable by following the (potentially shorter) + // chain of `Deref`. We will use the first list when finding + // potentially relevant function implementations (e.g. relevant impl blocks) + // but the second list when determining types that the receiver may be + // converted to, in order to find out which of those methods might actually + // be callable. + let mut autoderef_via_deref = Autoderef::new(infcx, param_env, hir::def_id::CRATE_DEF_ID, DUMMY_SP, self_ty) .include_raw_pointers() .silence_errors(); - let mut reached_raw_pointer = false; - let mut steps: Vec<_> = autoderef - .by_ref() - .map(|(ty, d)| { - let step = CandidateStep { - self_ty: infcx.make_query_response_ignoring_pending_obligations(inference_vars, ty), - autoderefs: d, - from_unsafe_deref: reached_raw_pointer, - unsize: false, - }; - if let ty::RawPtr(_, _) = ty.kind() { - // all the subsequent steps will be from_unsafe_deref - reached_raw_pointer = true; - } - step - }) - .collect(); - let final_ty = autoderef.final_ty(true); + let mut reached_raw_pointer = false; + let arbitrary_self_types_enabled = + tcx.features().arbitrary_self_types() || tcx.features().arbitrary_self_types_pointers(); + let (mut steps, reached_recursion_limit): (Vec<_>, bool) = if arbitrary_self_types_enabled { + let reachable_via_deref = + autoderef_via_deref.by_ref().map(|_| true).chain(std::iter::repeat(false)); + + let mut autoderef_via_receiver = + Autoderef::new(infcx, param_env, hir::def_id::CRATE_DEF_ID, DUMMY_SP, self_ty) + .include_raw_pointers() + .use_receiver_trait() + .silence_errors(); + let steps = autoderef_via_receiver + .by_ref() + .zip(reachable_via_deref) + .map(|((ty, d), reachable_via_deref)| { + let step = CandidateStep { + self_ty: infcx + .make_query_response_ignoring_pending_obligations(inference_vars, ty), + autoderefs: d, + from_unsafe_deref: reached_raw_pointer, + unsize: false, + reachable_via_deref, + }; + if ty.is_unsafe_ptr() { + // all the subsequent steps will be from_unsafe_deref + reached_raw_pointer = true; + } + step + }) + .collect(); + (steps, autoderef_via_receiver.reached_recursion_limit()) + } else { + let steps = autoderef_via_deref + .by_ref() + .map(|(ty, d)| { + let step = CandidateStep { + self_ty: infcx + .make_query_response_ignoring_pending_obligations(inference_vars, ty), + autoderefs: d, + from_unsafe_deref: reached_raw_pointer, + unsize: false, + reachable_via_deref: true, + }; + if ty.is_unsafe_ptr() { + // all the subsequent steps will be from_unsafe_deref + reached_raw_pointer = true; + } + step + }) + .collect(); + (steps, autoderef_via_deref.reached_recursion_limit()) + }; + let final_ty = autoderef_via_deref.final_ty(true); let opt_bad_ty = match final_ty.kind() { ty::Infer(ty::TyVar(_)) | ty::Error(_) => Some(MethodAutoderefBadTy { reached_raw_pointer, ty: infcx.make_query_response_ignoring_pending_obligations(inference_vars, final_ty), }), ty::Array(elem_ty, _) => { - let dereferences = steps.len() - 1; - + let autoderefs = steps.iter().filter(|s| s.reachable_via_deref).count() - 1; steps.push(CandidateStep { self_ty: infcx.make_query_response_ignoring_pending_obligations( inference_vars, Ty::new_slice(infcx.tcx, *elem_ty), ), - autoderefs: dereferences, + autoderefs, // this could be from an unsafe deref if we had // a *mut/const [T; N] from_unsafe_deref: reached_raw_pointer, unsize: true, + reachable_via_deref: true, // this is always the final type from + // autoderef_via_deref }); None @@ -569,7 +616,7 @@ fn method_autoderef_steps<'tcx>( MethodAutoderefStepsResult { steps: tcx.arena.alloc_from_iter(steps), opt_bad_ty: opt_bad_ty.map(|ty| &*tcx.arena.alloc(ty)), - reached_recursion_limit: autoderef.reached_recursion_limit(), + reached_recursion_limit, } } @@ -1065,6 +1112,10 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { ) -> Option> { self.steps .iter() + // At this point we're considering the types to which the receiver can be converted, + // so we want to follow the `Deref` chain not the `Receiver` chain. Filter out + // steps which can only be reached by following the (longer) `Receiver` chain. + .filter(|step| step.reachable_via_deref) .filter(|step| { debug!("pick_all_method: step={:?}", step); // skip types that are from a type error or that would require dereferencing diff --git a/compiler/rustc_middle/src/traits/query.rs b/compiler/rustc_middle/src/traits/query.rs index eeed5118592bc..f049da95f29ae 100644 --- a/compiler/rustc_middle/src/traits/query.rs +++ b/compiler/rustc_middle/src/traits/query.rs @@ -149,11 +149,21 @@ pub struct CandidateStep<'tcx> { /// `foo.by_raw_ptr()` will work and `foo.by_ref()` won't. pub from_unsafe_deref: bool, pub unsize: bool, + /// We will generate CandidateSteps which are reachable via a chain + /// of following `Receiver`. The first 'n' of those will be reachable + /// by following a chain of 'Deref' instead (since there's a blanket + /// implementation of Receiver for Deref). + /// We use the entire set of steps when identifying method candidates + /// (e.g. identifying relevant `impl` blocks) but only those that are + /// reachable via Deref when examining what the receiver type can + /// be converted into by autodereffing. + pub reachable_via_deref: bool, } #[derive(Copy, Clone, Debug, HashStable)] pub struct MethodAutoderefStepsResult<'tcx> { - /// The valid autoderef steps that could be found. + /// The valid autoderef steps that could be found by following a chain + /// of `Receiver` or `Deref` trait implementations. pub steps: &'tcx [CandidateStep<'tcx>], /// If Some(T), a type autoderef reported an error on. pub opt_bad_ty: Option<&'tcx MethodAutoderefBadTy<'tcx>>, diff --git a/tests/ui/async-await/inference_var_self_argument.stderr b/tests/ui/async-await/inference_var_self_argument.stderr index 7b7b3dbc757f1..a33c5f7b07dca 100644 --- a/tests/ui/async-await/inference_var_self_argument.stderr +++ b/tests/ui/async-await/inference_var_self_argument.stderr @@ -4,8 +4,8 @@ error[E0307]: invalid `self` parameter type: `&dyn Foo` LL | async fn foo(self: &dyn Foo) { | ^^^^^^^^ | - = note: type of `self` must be `Self` or a type that dereferences to it - = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + = note: type of `self` must be `Self` or some type implementing `Receiver` + = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box`, `self: Rc`, or `self: Arc` error[E0038]: the trait `Foo` cannot be made into an object --> $DIR/inference_var_self_argument.rs:5:5 diff --git a/tests/ui/async-await/issue-66312.stderr b/tests/ui/async-await/issue-66312.stderr index c95ae1147df36..f4db949a5f430 100644 --- a/tests/ui/async-await/issue-66312.stderr +++ b/tests/ui/async-await/issue-66312.stderr @@ -4,8 +4,8 @@ error[E0307]: invalid `self` parameter type: `T` LL | fn is_some(self: T); | ^ | - = note: type of `self` must be `Self` or a type that dereferences to it - = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + = note: type of `self` must be `Self` or some type implementing `Receiver` + = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box`, `self: Rc`, or `self: Arc` error[E0308]: mismatched types --> $DIR/issue-66312.rs:9:8 diff --git a/tests/ui/feature-gates/feature-gate-arbitrary-self-types-pointers.stderr b/tests/ui/feature-gates/feature-gate-arbitrary-self-types-pointers.stderr index 3bb93cf2ea0b1..0c5b8a4d3b685 100644 --- a/tests/ui/feature-gates/feature-gate-arbitrary-self-types-pointers.stderr +++ b/tests/ui/feature-gates/feature-gate-arbitrary-self-types-pointers.stderr @@ -7,7 +7,7 @@ LL | fn foo(self: *const Self) {} = note: see issue #44874 for more information = help: add `#![feature(arbitrary_self_types_pointers)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box`, `self: Rc`, or `self: Arc` error[E0658]: `*mut Bar` cannot be used as the type of `self` without the `arbitrary_self_types_pointers` feature --> $DIR/feature-gate-arbitrary-self-types-pointers.rs:12:18 @@ -18,7 +18,7 @@ LL | fn bar(self: *mut Self) {} = note: see issue #44874 for more information = help: add `#![feature(arbitrary_self_types_pointers)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box`, `self: Rc`, or `self: Arc` error[E0658]: `*const Self` cannot be used as the type of `self` without the `arbitrary_self_types_pointers` feature --> $DIR/feature-gate-arbitrary-self-types-pointers.rs:2:18 @@ -29,7 +29,7 @@ LL | fn foo(self: *const Self); = note: see issue #44874 for more information = help: add `#![feature(arbitrary_self_types_pointers)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box`, `self: Rc`, or `self: Arc` error: aborting due to 3 previous errors diff --git a/tests/ui/feature-gates/feature-gate-arbitrary-self-types.stderr b/tests/ui/feature-gates/feature-gate-arbitrary-self-types.stderr index 7f0e02c91f8f8..3ffba533d63fc 100644 --- a/tests/ui/feature-gates/feature-gate-arbitrary-self-types.stderr +++ b/tests/ui/feature-gates/feature-gate-arbitrary-self-types.stderr @@ -7,7 +7,7 @@ LL | fn foo(self: Ptr) {} = note: see issue #44874 for more information = help: add `#![feature(arbitrary_self_types)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box`, `self: Rc`, or `self: Arc` error[E0658]: `Box>` cannot be used as the type of `self` without the `arbitrary_self_types` feature --> $DIR/feature-gate-arbitrary-self-types.rs:26:18 @@ -18,7 +18,7 @@ LL | fn bar(self: Box>) {} = note: see issue #44874 for more information = help: add `#![feature(arbitrary_self_types)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box`, `self: Rc`, or `self: Arc` error[E0658]: `Ptr` cannot be used as the type of `self` without the `arbitrary_self_types` feature --> $DIR/feature-gate-arbitrary-self-types.rs:16:18 @@ -29,7 +29,7 @@ LL | fn foo(self: Ptr); = note: see issue #44874 for more information = help: add `#![feature(arbitrary_self_types)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box`, `self: Rc`, or `self: Arc` error: aborting due to 3 previous errors diff --git a/tests/ui/feature-gates/feature-gate-arbitrary_self_types-raw-pointer.stderr b/tests/ui/feature-gates/feature-gate-arbitrary_self_types-raw-pointer.stderr index 856e059533139..3eb87adb33adc 100644 --- a/tests/ui/feature-gates/feature-gate-arbitrary_self_types-raw-pointer.stderr +++ b/tests/ui/feature-gates/feature-gate-arbitrary_self_types-raw-pointer.stderr @@ -7,7 +7,7 @@ LL | fn foo(self: *const Self) {} = note: see issue #44874 for more information = help: add `#![feature(arbitrary_self_types_pointers)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box`, `self: Rc`, or `self: Arc` error[E0658]: `*const ()` cannot be used as the type of `self` without the `arbitrary_self_types_pointers` feature --> $DIR/feature-gate-arbitrary_self_types-raw-pointer.rs:14:18 @@ -18,7 +18,7 @@ LL | fn bar(self: *const Self) {} = note: see issue #44874 for more information = help: add `#![feature(arbitrary_self_types_pointers)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box`, `self: Rc`, or `self: Arc` error[E0658]: `*const Self` cannot be used as the type of `self` without the `arbitrary_self_types_pointers` feature --> $DIR/feature-gate-arbitrary_self_types-raw-pointer.rs:9:18 @@ -29,7 +29,7 @@ LL | fn bar(self: *const Self); = note: see issue #44874 for more information = help: add `#![feature(arbitrary_self_types_pointers)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box`, `self: Rc`, or `self: Arc` error: aborting due to 3 previous errors diff --git a/tests/ui/feature-gates/feature-gate-dispatch-from-dyn-cell.stderr b/tests/ui/feature-gates/feature-gate-dispatch-from-dyn-cell.stderr index 2150effc3b74d..eb9e51a04c394 100644 --- a/tests/ui/feature-gates/feature-gate-dispatch-from-dyn-cell.stderr +++ b/tests/ui/feature-gates/feature-gate-dispatch-from-dyn-cell.stderr @@ -4,8 +4,8 @@ error[E0307]: invalid `self` parameter type: `Cell<&Self>` LL | fn cell(self: Cell<&Self>); | ^^^^^^^^^^^ | - = note: type of `self` must be `Self` or a type that dereferences to it - = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + = note: type of `self` must be `Self` or some type implementing `Receiver` + = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box`, `self: Rc`, or `self: Arc` error: aborting due to 1 previous error diff --git a/tests/ui/issues/issue-56806.stderr b/tests/ui/issues/issue-56806.stderr index ec50d863758db..4b0a59fe12def 100644 --- a/tests/ui/issues/issue-56806.stderr +++ b/tests/ui/issues/issue-56806.stderr @@ -4,8 +4,8 @@ error[E0307]: invalid `self` parameter type: `Box<(dyn Trait + 'static)>` LL | fn dyn_instead_of_self(self: Box); | ^^^^^^^^^^^^^^ | - = note: type of `self` must be `Self` or a type that dereferences to it - = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + = note: type of `self` must be `Self` or some type implementing `Receiver` + = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box`, `self: Rc`, or `self: Arc` error: aborting due to 1 previous error diff --git a/tests/ui/lifetimes/could-not-resolve-issue-121503.stderr b/tests/ui/lifetimes/could-not-resolve-issue-121503.stderr index 3babf63347c35..46804642af88e 100644 --- a/tests/ui/lifetimes/could-not-resolve-issue-121503.stderr +++ b/tests/ui/lifetimes/could-not-resolve-issue-121503.stderr @@ -7,7 +7,7 @@ LL | async fn box_ref_Struct(self: Box) -> &u32 = note: see issue #44874 for more information = help: add `#![feature(arbitrary_self_types)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box`, `self: Rc`, or `self: Arc` error: aborting due to 1 previous error diff --git a/tests/ui/methods/call_method_unknown_referent.rs b/tests/ui/methods/call_method_unknown_referent.rs new file mode 100644 index 0000000000000..b01e2d80f7f80 --- /dev/null +++ b/tests/ui/methods/call_method_unknown_referent.rs @@ -0,0 +1,48 @@ +//@ edition: 2018 + +#![feature(arbitrary_self_types)] + +// tests that the referent type of a reference must be known to call methods on it + +struct SmartPtr(T); + +impl core::ops::Receiver for SmartPtr { + type Target = T; +} + +impl SmartPtr { + fn foo(&self) {} +} + +fn main() { + let val = 1_u32; + let ptr = &val; + let _a: i32 = (ptr as &_).read(); + //~^ ERROR type annotations needed + + // Same again, but with a smart pointer type + let val2 = 1_u32; + let rc = std::rc::Rc::new(val2); + let _b = (rc as std::rc::Rc<_>).read(); + //~^ ERROR type annotations needed + + // Same again, but with a smart pointer type + let ptr = SmartPtr(val); + + // We can call unambiguous outer-type methods on this + (ptr as SmartPtr<_>).foo(); + // ... but we can't follow the Receiver chain to the inner type + // because we end up with _. + + // Because SmartPtr implements Receiver, it's arguable which of the + // following two diagnostics we'd want in this case: + // (a) "type annotations needed" (because the inner type is _) + // (b) "no method named `read` found for struct `SmartPtr`" + // (ignoring the fact that there might have been methods on the + // inner type, had it not been _) + // At present we produce error type (b), which is necessary because + // our resolution logic needs to be able to call methods such as foo() + // on the outer type even if the inner type is ambiguous. + let _c = (ptr as SmartPtr<_>).read(); + //~^ ERROR no method named `read` found for struct `SmartPtr` +} diff --git a/tests/ui/methods/call_method_unknown_referent.stderr b/tests/ui/methods/call_method_unknown_referent.stderr new file mode 100644 index 0000000000000..748b02b52b577 --- /dev/null +++ b/tests/ui/methods/call_method_unknown_referent.stderr @@ -0,0 +1,29 @@ +error[E0282]: type annotations needed + --> $DIR/call_method_unknown_referent.rs:20:31 + | +LL | let _a: i32 = (ptr as &_).read(); + | ^^^^ cannot infer type + +error[E0282]: type annotations needed + --> $DIR/call_method_unknown_referent.rs:26:37 + | +LL | let _b = (rc as std::rc::Rc<_>).read(); + | ^^^^ cannot infer type + +error[E0599]: no method named `read` found for struct `SmartPtr` in the current scope + --> $DIR/call_method_unknown_referent.rs:46:35 + | +LL | struct SmartPtr(T); + | ------------------ method `read` not found for this struct +... +LL | let _c = (ptr as SmartPtr<_>).read(); + | ^^^^ method not found in `SmartPtr<_>` + | + = help: items from traits can only be used if the trait is implemented and in scope + = note: the following trait defines an item `read`, perhaps you need to implement it: + candidate #1: `std::io::Read` + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0282, E0599. +For more information about an error, try `rustc --explain E0282`. diff --git a/tests/ui/methods/call_method_unknown_referent2.rs b/tests/ui/methods/call_method_unknown_referent2.rs new file mode 100644 index 0000000000000..b1615bd8d4414 --- /dev/null +++ b/tests/ui/methods/call_method_unknown_referent2.rs @@ -0,0 +1,24 @@ +//@ edition: 2018 +//@ run-pass + +#![feature(arbitrary_self_types)] + +// tests that the referent type of a reference must be known to call methods on it + +struct SmartPtr(T); + +impl core::ops::Receiver for SmartPtr { + type Target = T; +} + +impl SmartPtr { + fn foo(&self) -> usize { 3 } +} + +fn main() { + let val = 1_u32; + let ptr = SmartPtr(val); + // Ensure calls to outer methods work even if inner methods can't be + // resolved due to the type variable + assert_eq!((ptr as SmartPtr<_>).foo(), 3); +} diff --git a/tests/ui/self/arbitrary-self-from-method-substs-with-receiver.rs b/tests/ui/self/arbitrary-self-from-method-substs-with-receiver.rs new file mode 100644 index 0000000000000..495d261c549ca --- /dev/null +++ b/tests/ui/self/arbitrary-self-from-method-substs-with-receiver.rs @@ -0,0 +1,64 @@ +#![feature(arbitrary_self_types)] + +use std::ops::{Receiver, Deref}; + +struct SmartPtr<'a, T: ?Sized>(&'a T); + +impl<'a, T: ?Sized> Deref for SmartPtr<'a, T> { + type Target = T; + fn deref(&self) -> &Self::Target { + self.0 + } +} + +impl<'a, T: ?Sized> Clone for SmartPtr<'a, T> { + fn clone(&self) -> Self { + Self(self.0) + } +} + +impl<'a, T: ?Sized> Copy for SmartPtr<'a, T> { +} + +struct Foo(u32); +impl Foo { + fn a>(self: R) -> u32 { + //~^ ERROR invalid generic `self` parameter type: `R` + 2 + } + fn b>(self: R) -> u32 { + //~^ ERROR invalid generic `self` parameter type: `R` + self.0 + } + fn c(self: impl Receiver) -> u32 { + //~^ ERROR invalid generic `self` parameter type: `impl Receiver` + 3 + } + fn d(self: impl Deref) -> u32 { + //~^ ERROR invalid generic `self` parameter type: `impl Deref` + self.0 + } +} + +fn main() { + let foo = Foo(1); + assert_eq!((&foo).a::<&Foo>(), 2); + assert_eq!((&foo).b::<&Foo>(), 1); + assert_eq!((&foo).a(), 2); + assert_eq!((&foo).b(), 1); + assert_eq!((&foo).c(), 3); + assert_eq!((&foo).d(), 1); + assert_eq!(foo.a::<&Foo>(), 2); + //~^ ERROR mismatched types + assert_eq!(foo.b::<&Foo>(), 1); + //~^ ERROR mismatched types + let smart_ptr = SmartPtr(&foo); + assert_eq!(smart_ptr.a(), 2); + assert_eq!(smart_ptr.b(), 1); + assert_eq!(smart_ptr.c(), 3); + assert_eq!(smart_ptr.d(), 1); + assert_eq!(smart_ptr.a::<&Foo>(), 2); + //~^ ERROR mismatched types + assert_eq!(smart_ptr.b::<&Foo>(), 1); + //~^ ERROR mismatched types +} diff --git a/tests/ui/self/arbitrary-self-from-method-substs-with-receiver.stderr b/tests/ui/self/arbitrary-self-from-method-substs-with-receiver.stderr new file mode 100644 index 0000000000000..9af2a08f3712d --- /dev/null +++ b/tests/ui/self/arbitrary-self-from-method-substs-with-receiver.stderr @@ -0,0 +1,70 @@ +error[E0801]: invalid generic `self` parameter type: `R` + --> $DIR/arbitrary-self-from-method-substs-with-receiver.rs:25:42 + | +LL | fn a>(self: R) -> u32 { + | ^ + | + = note: type of `self` must not be a method generic parameter type + = help: use a concrete type such as `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + +error[E0801]: invalid generic `self` parameter type: `R` + --> $DIR/arbitrary-self-from-method-substs-with-receiver.rs:29:39 + | +LL | fn b>(self: R) -> u32 { + | ^ + | + = note: type of `self` must not be a method generic parameter type + = help: use a concrete type such as `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + +error[E0801]: invalid generic `self` parameter type: `impl Receiver` + --> $DIR/arbitrary-self-from-method-substs-with-receiver.rs:33:16 + | +LL | fn c(self: impl Receiver) -> u32 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: type of `self` must not be a method generic parameter type + = help: use a concrete type such as `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + +error[E0801]: invalid generic `self` parameter type: `impl Deref` + --> $DIR/arbitrary-self-from-method-substs-with-receiver.rs:37:16 + | +LL | fn d(self: impl Deref) -> u32 { + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: type of `self` must not be a method generic parameter type + = help: use a concrete type such as `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + +error[E0308]: mismatched types + --> $DIR/arbitrary-self-from-method-substs-with-receiver.rs:51:16 + | +LL | assert_eq!(foo.a::<&Foo>(), 2); + | ^^^ expected `&Foo`, found `Foo` + +error[E0308]: mismatched types + --> $DIR/arbitrary-self-from-method-substs-with-receiver.rs:53:16 + | +LL | assert_eq!(foo.b::<&Foo>(), 1); + | ^^^ expected `&Foo`, found `Foo` + +error[E0308]: mismatched types + --> $DIR/arbitrary-self-from-method-substs-with-receiver.rs:60:16 + | +LL | assert_eq!(smart_ptr.a::<&Foo>(), 2); + | ^^^^^^^^^ expected `&Foo`, found `SmartPtr<'_, Foo>` + | + = note: expected reference `&Foo` + found struct `SmartPtr<'_, Foo, >` + +error[E0308]: mismatched types + --> $DIR/arbitrary-self-from-method-substs-with-receiver.rs:62:16 + | +LL | assert_eq!(smart_ptr.b::<&Foo>(), 1); + | ^^^^^^^^^ expected `&Foo`, found `SmartPtr<'_, Foo>` + | + = note: expected reference `&Foo` + found struct `SmartPtr<'_, Foo, >` + +error: aborting due to 8 previous errors + +Some errors have detailed explanations: E0308, E0801. +For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/self/arbitrary-self-from-method-substs.default.stderr b/tests/ui/self/arbitrary-self-from-method-substs.default.stderr index 5dc3a0b023472..7cf9c9a3afd4d 100644 --- a/tests/ui/self/arbitrary-self-from-method-substs.default.stderr +++ b/tests/ui/self/arbitrary-self-from-method-substs.default.stderr @@ -61,7 +61,7 @@ LL | fn get6(self: FR::Receiver, other: FR) -> u32 { = note: see issue #44874 for more information = help: add `#![feature(arbitrary_self_types)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box`, `self: Rc`, or `self: Arc` error[E0658]: `R` cannot be used as the type of `self` without the `arbitrary_self_types` feature --> $DIR/arbitrary-self-from-method-substs.rs:61:18 @@ -72,7 +72,7 @@ LL | fn get(self: R) {} = note: see issue #44874 for more information = help: add `#![feature(arbitrary_self_types)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box`, `self: Rc`, or `self: Arc` error[E0271]: type mismatch resolving `::Receiver == Foo` --> $DIR/arbitrary-self-from-method-substs.rs:92:9 diff --git a/tests/ui/self/arbitrary-self-opaque.stderr b/tests/ui/self/arbitrary-self-opaque.stderr index c75165d9f8e27..0469aca27dc81 100644 --- a/tests/ui/self/arbitrary-self-opaque.stderr +++ b/tests/ui/self/arbitrary-self-opaque.stderr @@ -4,8 +4,8 @@ error[E0307]: invalid `self` parameter type: `Bar` LL | fn foo(self: Bar) {} | ^^^ | - = note: type of `self` must be `Self` or a type that dereferences to it - = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + = note: type of `self` must be `Self` or some type implementing `Receiver` + = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box`, `self: Rc`, or `self: Arc` error: item does not constrain `Bar::{opaque#0}`, but has it in its signature --> $DIR/arbitrary-self-opaque.rs:7:8 diff --git a/tests/ui/self/arbitrary_self_types_generic_over_receiver.rs b/tests/ui/self/arbitrary_self_types_generic_over_receiver.rs new file mode 100644 index 0000000000000..8ccda9368addf --- /dev/null +++ b/tests/ui/self/arbitrary_self_types_generic_over_receiver.rs @@ -0,0 +1,23 @@ +#![feature(arbitrary_self_types)] + +use std::ops::{Receiver, Deref}; + +struct Foo(u32); +impl Foo { + fn a(self: impl Receiver) -> u32 { + //~^ ERROR invalid generic `self` parameter type: `impl Receiver` + 3 + } + fn b(self: impl Deref) -> u32 { + //~^ ERROR invalid generic `self` parameter type: `impl Deref` + self.0 + } +} + +fn main() { + let foo = Foo(1); + foo.a(); + //~^ ERROR the trait bound + foo.b(); + //~^ ERROR the trait bound +} diff --git a/tests/ui/self/arbitrary_self_types_generic_over_receiver.stderr b/tests/ui/self/arbitrary_self_types_generic_over_receiver.stderr new file mode 100644 index 0000000000000..2da3925341e2f --- /dev/null +++ b/tests/ui/self/arbitrary_self_types_generic_over_receiver.stderr @@ -0,0 +1,59 @@ +error[E0801]: invalid generic `self` parameter type: `impl Receiver` + --> $DIR/arbitrary_self_types_generic_over_receiver.rs:7:16 + | +LL | fn a(self: impl Receiver) -> u32 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: type of `self` must not be a method generic parameter type + = help: use a concrete type such as `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + +error[E0801]: invalid generic `self` parameter type: `impl Deref` + --> $DIR/arbitrary_self_types_generic_over_receiver.rs:11:16 + | +LL | fn b(self: impl Deref) -> u32 { + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: type of `self` must not be a method generic parameter type + = help: use a concrete type such as `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + +error[E0277]: the trait bound `Foo: std::ops::Receiver` is not satisfied + --> $DIR/arbitrary_self_types_generic_over_receiver.rs:19:9 + | +LL | foo.a(); + | ^ the trait `std::ops::Receiver` is not implemented for `Foo` + | + = note: required for `Foo` to implement `std::ops::Receiver` +note: required by a bound in `Foo::a` + --> $DIR/arbitrary_self_types_generic_over_receiver.rs:7:21 + | +LL | fn a(self: impl Receiver) -> u32 { + | ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Foo::a` +help: consider borrowing here + | +LL | &foo.a(); + | + +LL | &mut foo.a(); + | ++++ + +error[E0277]: the trait bound `Foo: Deref` is not satisfied + --> $DIR/arbitrary_self_types_generic_over_receiver.rs:21:9 + | +LL | foo.b(); + | ^ the trait `Deref` is not implemented for `Foo` + | +note: required by a bound in `Foo::b` + --> $DIR/arbitrary_self_types_generic_over_receiver.rs:11:21 + | +LL | fn b(self: impl Deref) -> u32 { + | ^^^^^^^^^^^^^^^^^^ required by this bound in `Foo::b` +help: consider borrowing here + | +LL | &foo.b(); + | + +LL | &mut foo.b(); + | ++++ + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0277, E0801. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/self/arbitrary_self_types_lifetime_elision.rs b/tests/ui/self/arbitrary_self_types_lifetime_elision.rs new file mode 100644 index 0000000000000..fd645c1013b64 --- /dev/null +++ b/tests/ui/self/arbitrary_self_types_lifetime_elision.rs @@ -0,0 +1,27 @@ +//@ run-pass + +#![feature(arbitrary_self_types)] + +#[derive(Clone)] +struct SmartPtr<'a, T: ?Sized>(&'a T); + +impl<'a, T: ?Sized> std::ops::Receiver for SmartPtr<'a, T> { + type Target = T; +} + +#[derive(Clone)] +struct MyType; + +impl MyType { + fn m(self: SmartPtr) {} + fn n(self: SmartPtr<'_, Self>) {} + fn o<'a>(self: SmartPtr<'a, Self>) {} +} + +fn main() { + let a = MyType; + let ptr = SmartPtr(&a); + ptr.clone().m(); + ptr.clone().n(); + ptr.o(); +} diff --git a/tests/ui/self/arbitrary_self_types_no_generics.rs b/tests/ui/self/arbitrary_self_types_no_generics.rs new file mode 100644 index 0000000000000..8a6f57418829e --- /dev/null +++ b/tests/ui/self/arbitrary_self_types_no_generics.rs @@ -0,0 +1,32 @@ +//@ run-pass + +#![feature(arbitrary_self_types)] + +pub struct A; + +impl A { + pub fn f(self: B) -> i32 { 1 } +} + +pub struct B(A); + +impl core::ops::Receiver for B { + type Target = A; +} + +struct C; + +struct D; + +impl C { + fn weird(self: D) -> i32 { 3 } +} + +impl core::ops::Receiver for D { + type Target = C; +} + +fn main() { + assert_eq!(B(A).f(), 1); + assert_eq!(D.weird(), 3); +} diff --git a/tests/ui/self/arbitrary_self_types_not_allow_call_with_no_deref.rs b/tests/ui/self/arbitrary_self_types_not_allow_call_with_no_deref.rs new file mode 100644 index 0000000000000..26e48f69d23ea --- /dev/null +++ b/tests/ui/self/arbitrary_self_types_not_allow_call_with_no_deref.rs @@ -0,0 +1,38 @@ +#![feature(arbitrary_self_types)] + +use std::rc::Rc; + +struct Foo; + +struct CppRef(T); + +impl std::ops::Receiver for CppRef { + type Target = T; +} + +impl Foo{ + fn frobnicate_self(self) {} + fn frobnicate_ref(&self) {} + fn frobnicate_cpp_ref(self: CppRef) {} +} + +fn main() { + let foo_rc = Rc::new(Foo); + + // this compiles fine, and desugars to `Foo::frobnicate_ref(&*foo_rc)` + foo_rc.frobnicate_ref(); + + let foo_cpp_ref = CppRef(Foo); + + // should not compile because it would desugar to `Foo::frobnicate_ref(&*foo_cpp_ref)` + // and you can't deref a CppRef + foo_cpp_ref.frobnicate_ref(); + //~^ ERROR no method named + + foo_cpp_ref.frobnicate_self(); // would desugar to `Foo::frobnicate_self(*foo_cpp_ref)` + //~^ ERROR no method named + + // should compile, because we're not dereffing the CppRef + // desugars to `Foo::frobnicate_cpp_ref(foo_cpp_ref)` + foo_cpp_ref.frobnicate_cpp_ref(); +} diff --git a/tests/ui/self/arbitrary_self_types_not_allow_call_with_no_deref.stderr b/tests/ui/self/arbitrary_self_types_not_allow_call_with_no_deref.stderr new file mode 100644 index 0000000000000..4c0ab88493e94 --- /dev/null +++ b/tests/ui/self/arbitrary_self_types_not_allow_call_with_no_deref.stderr @@ -0,0 +1,39 @@ +error[E0599]: no method named `frobnicate_ref` found for struct `CppRef` in the current scope + --> $DIR/arbitrary_self_types_not_allow_call_with_no_deref.rs:29:17 + | +LL | struct CppRef(T); + | ---------------- method `frobnicate_ref` not found for this struct +... +LL | foo_cpp_ref.frobnicate_ref(); + | ^^^^^^^^^^^^^^ + | +help: one of the expressions' fields has a method of the same name + | +LL | foo_cpp_ref.0.frobnicate_ref(); + | ++ +help: there is a method `frobnicate_cpp_ref` with a similar name + | +LL | foo_cpp_ref.frobnicate_cpp_ref(); + | ~~~~~~~~~~~~~~~~~~ + +error[E0599]: no method named `frobnicate_self` found for struct `CppRef` in the current scope + --> $DIR/arbitrary_self_types_not_allow_call_with_no_deref.rs:32:17 + | +LL | struct CppRef(T); + | ---------------- method `frobnicate_self` not found for this struct +... +LL | foo_cpp_ref.frobnicate_self(); // would desugar to `Foo::frobnicate_self(*foo_cpp_ref)` + | ^^^^^^^^^^^^^^^ + | +help: one of the expressions' fields has a method of the same name + | +LL | foo_cpp_ref.0.frobnicate_self(); // would desugar to `Foo::frobnicate_self(*foo_cpp_ref)` + | ++ +help: there is a method `frobnicate_cpp_ref` with a similar name + | +LL | foo_cpp_ref.frobnicate_cpp_ref(); // would desugar to `Foo::frobnicate_self(*foo_cpp_ref)` + | ~~~~~~~~~~~~~~~~~~ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/self/arbitrary_self_types_recursive_receiver.rs b/tests/ui/self/arbitrary_self_types_recursive_receiver.rs new file mode 100644 index 0000000000000..f3e7f96d7c4de --- /dev/null +++ b/tests/ui/self/arbitrary_self_types_recursive_receiver.rs @@ -0,0 +1,32 @@ +//@ run-pass +#![feature(arbitrary_self_types)] + +struct MyNonNull(*const T); + +impl std::ops::Receiver for MyNonNull { + type Target = T; +} + +#[allow(dead_code)] +impl MyNonNull { + fn foo(&self) -> *const U { + self.cast::().bar() + } + fn cast(&self) -> MyNonNull { + MyNonNull(self.0 as *const U) + } + fn bar(&self) -> *const T { + self.0 + } +} + +#[repr(transparent)] +struct Foo(usize); +#[repr(transparent)] +struct Bar(usize); + +fn main() { + let a = Foo(3); + let ptr = MyNonNull(&a); + let _bar_ptr: *const Bar = ptr.foo(); +} diff --git a/tests/ui/self/arbitrary_self_types_struct_receiver_trait.rs b/tests/ui/self/arbitrary_self_types_struct_receiver_trait.rs new file mode 100644 index 0000000000000..cebf0ea7cba93 --- /dev/null +++ b/tests/ui/self/arbitrary_self_types_struct_receiver_trait.rs @@ -0,0 +1,31 @@ +//@ run-pass +#![feature(arbitrary_self_types)] + +use std::ops::Receiver; + +struct SmartPtr(T); + +impl Receiver for SmartPtr { + type Target = T; +} + +struct Foo { + x: i32, + y: i32, +} + +impl Foo { + fn x(self: &SmartPtr) -> i32 { + self.0.x + } + + fn y(self: SmartPtr) -> i32 { + self.0.y + } +} + +fn main() { + let foo = SmartPtr(Foo {x: 3, y: 4}); + assert_eq!(3, foo.x()); + assert_eq!(4, foo.y()); +} diff --git a/tests/ui/self/arbitrary_self_types_trait_receiver_trait.rs b/tests/ui/self/arbitrary_self_types_trait_receiver_trait.rs new file mode 100644 index 0000000000000..9c0402da0befe --- /dev/null +++ b/tests/ui/self/arbitrary_self_types_trait_receiver_trait.rs @@ -0,0 +1,25 @@ +//@ run-pass +#![feature(arbitrary_self_types)] +#![allow(unused_allocation)] + +struct SmartPtr(T); + +impl std::ops::Receiver for SmartPtr { + type Target = T; +} + +trait Trait { + fn trait_method<'a>(self: &'a Box>) -> &'a [i32]; +} + +impl Trait for Vec { + fn trait_method<'a>(self: &'a Box>) -> &'a [i32] { + &(**self).0 + } +} + +fn main() { + let v = vec![1, 2, 3]; + + assert_eq!(&[1, 2, 3], Box::new(SmartPtr(v)).trait_method()); +} diff --git a/tests/ui/span/issue-27522.stderr b/tests/ui/span/issue-27522.stderr index c57a100bbe227..04904b0ddc1c5 100644 --- a/tests/ui/span/issue-27522.stderr +++ b/tests/ui/span/issue-27522.stderr @@ -4,8 +4,8 @@ error[E0307]: invalid `self` parameter type: `&SomeType` LL | fn handler(self: &SomeType); | ^^^^^^^^^ | - = note: type of `self` must be `Self` or a type that dereferences to it - = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + = note: type of `self` must be `Self` or some type implementing `Receiver` + = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box`, `self: Rc`, or `self: Arc` error: aborting due to 1 previous error diff --git a/tests/ui/suggestions/dyn-incompatible-trait-should-use-where-sized.stderr b/tests/ui/suggestions/dyn-incompatible-trait-should-use-where-sized.stderr index beafd7c2ab00f..eb9f9196a7234 100644 --- a/tests/ui/suggestions/dyn-incompatible-trait-should-use-where-sized.stderr +++ b/tests/ui/suggestions/dyn-incompatible-trait-should-use-where-sized.stderr @@ -32,8 +32,8 @@ error[E0307]: invalid `self` parameter type: `()` LL | fn bar(self: ()) {} | ^^ | - = note: type of `self` must be `Self` or a type that dereferences to it - = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + = note: type of `self` must be `Self` or some type implementing `Receiver` + = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box`, `self: Rc`, or `self: Arc` error: aborting due to 2 previous errors diff --git a/tests/ui/traits/const-traits/effects/auxiliary/minicore.rs b/tests/ui/traits/const-traits/effects/auxiliary/minicore.rs index aaa61e21155f4..e606d896e93d0 100644 --- a/tests/ui/traits/const-traits/effects/auxiliary/minicore.rs +++ b/tests/ui/traits/const-traits/effects/auxiliary/minicore.rs @@ -110,6 +110,16 @@ impl LegacyReceiver for &T {} impl LegacyReceiver for &mut T {} +#[lang = "receiver"] +pub trait Receiver { + #[lang = "receiver_target"] + type Target: ?Sized; +} + +impl Receiver for T { + type Target = ::Target; +} + #[lang = "destruct"] #[const_trait] pub trait Destruct {} diff --git a/tests/ui/traits/issue-78372.stderr b/tests/ui/traits/issue-78372.stderr index 86234d15a5d4b..1c58915111f2c 100644 --- a/tests/ui/traits/issue-78372.stderr +++ b/tests/ui/traits/issue-78372.stderr @@ -61,8 +61,8 @@ error[E0307]: invalid `self` parameter type: `Smaht` LL | fn foo(self: Smaht); | ^^^^^^^^^^^^^^ | - = note: type of `self` must be `Self` or a type that dereferences to it - = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + = note: type of `self` must be `Self` or some type implementing `Receiver` + = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box`, `self: Rc`, or `self: Arc` error[E0378]: the trait `DispatchFromDyn` may only be implemented for a coercion between structures --> $DIR/issue-78372.rs:3:1 diff --git a/tests/ui/type-alias-impl-trait/method_resolution3.current.stderr b/tests/ui/type-alias-impl-trait/method_resolution3.current.stderr index 09efd7a9e7e2d..c6aa0e811f36c 100644 --- a/tests/ui/type-alias-impl-trait/method_resolution3.current.stderr +++ b/tests/ui/type-alias-impl-trait/method_resolution3.current.stderr @@ -4,8 +4,8 @@ error[E0307]: invalid `self` parameter type: `Bar` LL | fn bar(self: Bar) { | ^^^^^^^^ | - = note: type of `self` must be `Self` or a type that dereferences to it - = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + = note: type of `self` must be `Self` or some type implementing `Receiver` + = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box`, `self: Rc`, or `self: Arc` error[E0307]: invalid `self` parameter type: `&Bar` --> $DIR/method_resolution3.rs:20:18 @@ -13,8 +13,8 @@ error[E0307]: invalid `self` parameter type: `&Bar` LL | fn baz(self: &Bar) { | ^^^^^^^^^ | - = note: type of `self` must be `Self` or a type that dereferences to it - = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + = note: type of `self` must be `Self` or some type implementing `Receiver` + = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box`, `self: Rc`, or `self: Arc` error: aborting due to 2 previous errors diff --git a/tests/ui/type-alias-impl-trait/method_resolution3.next.stderr b/tests/ui/type-alias-impl-trait/method_resolution3.next.stderr index 09efd7a9e7e2d..c6aa0e811f36c 100644 --- a/tests/ui/type-alias-impl-trait/method_resolution3.next.stderr +++ b/tests/ui/type-alias-impl-trait/method_resolution3.next.stderr @@ -4,8 +4,8 @@ error[E0307]: invalid `self` parameter type: `Bar` LL | fn bar(self: Bar) { | ^^^^^^^^ | - = note: type of `self` must be `Self` or a type that dereferences to it - = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + = note: type of `self` must be `Self` or some type implementing `Receiver` + = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box`, `self: Rc`, or `self: Arc` error[E0307]: invalid `self` parameter type: `&Bar` --> $DIR/method_resolution3.rs:20:18 @@ -13,8 +13,8 @@ error[E0307]: invalid `self` parameter type: `&Bar` LL | fn baz(self: &Bar) { | ^^^^^^^^^ | - = note: type of `self` must be `Self` or a type that dereferences to it - = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + = note: type of `self` must be `Self` or some type implementing `Receiver` + = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box`, `self: Rc`, or `self: Arc` error: aborting due to 2 previous errors diff --git a/tests/ui/type-alias-impl-trait/method_resolution4.current.stderr b/tests/ui/type-alias-impl-trait/method_resolution4.current.stderr index 8ffdb21f2517b..e4c4d121733b6 100644 --- a/tests/ui/type-alias-impl-trait/method_resolution4.current.stderr +++ b/tests/ui/type-alias-impl-trait/method_resolution4.current.stderr @@ -4,8 +4,8 @@ error[E0307]: invalid `self` parameter type: `Bar` LL | fn foo(self: Bar) { | ^^^^^^^^ | - = note: type of `self` must be `Self` or a type that dereferences to it - = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + = note: type of `self` must be `Self` or some type implementing `Receiver` + = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box`, `self: Rc`, or `self: Arc` error[E0307]: invalid `self` parameter type: `&Bar` --> $DIR/method_resolution4.rs:31:20 @@ -13,8 +13,8 @@ error[E0307]: invalid `self` parameter type: `&Bar` LL | fn foomp(self: &Bar) { | ^^^^^^^^^ | - = note: type of `self` must be `Self` or a type that dereferences to it - = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + = note: type of `self` must be `Self` or some type implementing `Receiver` + = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box`, `self: Rc`, or `self: Arc` error: aborting due to 2 previous errors diff --git a/tests/ui/type-alias-impl-trait/method_resolution4.next.stderr b/tests/ui/type-alias-impl-trait/method_resolution4.next.stderr index 8ffdb21f2517b..e4c4d121733b6 100644 --- a/tests/ui/type-alias-impl-trait/method_resolution4.next.stderr +++ b/tests/ui/type-alias-impl-trait/method_resolution4.next.stderr @@ -4,8 +4,8 @@ error[E0307]: invalid `self` parameter type: `Bar` LL | fn foo(self: Bar) { | ^^^^^^^^ | - = note: type of `self` must be `Self` or a type that dereferences to it - = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + = note: type of `self` must be `Self` or some type implementing `Receiver` + = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box`, `self: Rc`, or `self: Arc` error[E0307]: invalid `self` parameter type: `&Bar` --> $DIR/method_resolution4.rs:31:20 @@ -13,8 +13,8 @@ error[E0307]: invalid `self` parameter type: `&Bar` LL | fn foomp(self: &Bar) { | ^^^^^^^^^ | - = note: type of `self` must be `Self` or a type that dereferences to it - = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + = note: type of `self` must be `Self` or some type implementing `Receiver` + = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box`, `self: Rc`, or `self: Arc` error: aborting due to 2 previous errors diff --git a/tests/ui/ufcs/ufcs-explicit-self-bad.stderr b/tests/ui/ufcs/ufcs-explicit-self-bad.stderr index 2a8c4edbdb5f3..36bdc714e050b 100644 --- a/tests/ui/ufcs/ufcs-explicit-self-bad.stderr +++ b/tests/ui/ufcs/ufcs-explicit-self-bad.stderr @@ -22,8 +22,8 @@ error[E0307]: invalid `self` parameter type: `isize` LL | fn foo(self: isize, x: isize) -> isize { | ^^^^^ | - = note: type of `self` must be `Self` or a type that dereferences to it - = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + = note: type of `self` must be `Self` or some type implementing `Receiver` + = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box`, `self: Rc`, or `self: Arc` error[E0307]: invalid `self` parameter type: `Bar` --> $DIR/ufcs-explicit-self-bad.rs:19:18 @@ -31,8 +31,8 @@ error[E0307]: invalid `self` parameter type: `Bar` LL | fn foo(self: Bar, x: isize) -> isize { | ^^^^^^^^^^ | - = note: type of `self` must be `Self` or a type that dereferences to it - = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + = note: type of `self` must be `Self` or some type implementing `Receiver` + = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box`, `self: Rc`, or `self: Arc` error[E0307]: invalid `self` parameter type: `&Bar` --> $DIR/ufcs-explicit-self-bad.rs:23:18 @@ -40,8 +40,8 @@ error[E0307]: invalid `self` parameter type: `&Bar` LL | fn bar(self: &Bar, x: isize) -> isize { | ^^^^^^^^^^^ | - = note: type of `self` must be `Self` or a type that dereferences to it - = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + = note: type of `self` must be `Self` or some type implementing `Receiver` + = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box`, `self: Rc`, or `self: Arc` error[E0308]: mismatched `self` parameter type --> $DIR/ufcs-explicit-self-bad.rs:37:21 From 7f7c964e475d36789de0ce1473f696b8b1fc5434 Mon Sep 17 00:00:00 2001 From: Adrian Taylor Date: Mon, 11 Nov 2024 16:37:56 +0000 Subject: [PATCH 08/20] Arbitrary self types v2: pick diags to stack. This commit makes no (intentional) functional change. Previously, the picking process maintained two lists of extra information useful for diagnostics: * any unstable candidates which might have been picked * any unsatisfied predicates Previously, these were dealt with quite differently - the former list was passed around as a function parameter; the latter lived in a RefCell in the ProbeCtxt. With this change we increase consistency by keeping them together in a new PickDiagHints structure, passed as a parameter, with no need for interior mutability. The lifecycle of each of these lists remains fairly complex, so it's explained with new comments in pick_core. A further cleanup here would be to package the widely-used tuple (ty::Predicate<'tcx>, Option>, Option>) into a named struct for UnsatisfiedPredicate. This seems worth doing but it turns out that this tuple is used in dozens of places, so if we're going to do this we should do it as a separate PR to avoid constant rebase trouble. --- compiler/rustc_hir_typeck/src/method/probe.rs | 162 +++++++++--------- 1 file changed, 85 insertions(+), 77 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 91e65af8df954..c92f00a54dd2b 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -79,12 +79,6 @@ pub(crate) struct ProbeContext<'a, 'tcx> { /// used for error reporting static_candidates: RefCell>, - /// Collects near misses when trait bounds for type parameters are unsatisfied and is only used - /// for error reporting - unsatisfied_predicates: RefCell< - Vec<(ty::Predicate<'tcx>, Option>, Option>)>, - >, - scope_expr_id: HirId, /// Is this probe being done for a diagnostic? This will skip some error reporting @@ -162,6 +156,21 @@ impl AutorefOrPtrAdjustment { } } +/// Extra information required only for error reporting. +#[derive(Debug)] +struct PickDiagHints<'a, 'tcx> { + /// Unstable candidates alongside the stable ones. + unstable_candidates: Option, Symbol)>>, + + /// Collects near misses when trait bounds for type parameters are unsatisfied and is only used + /// for error reporting + unsatisfied_predicates: &'a mut Vec<( + ty::Predicate<'tcx>, + Option>, + Option>, + )>, +} + #[derive(Debug, Clone)] pub(crate) struct Pick<'tcx> { pub item: ty::AssocItem, @@ -647,7 +656,6 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { private_candidates: Vec::new(), private_candidate: Cell::new(None), static_candidates: RefCell::new(Vec::new()), - unsatisfied_predicates: RefCell::new(Vec::new()), scope_expr_id, is_suggestion, } @@ -660,7 +668,6 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { self.private_candidates.clear(); self.private_candidate.set(None); self.static_candidates.borrow_mut().clear(); - self.unsatisfied_predicates.borrow_mut().clear(); } /// When we're looking up a method by path (UFCS), we relate the receiver @@ -1036,7 +1043,9 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { fn pick(mut self) -> PickResult<'tcx> { assert!(self.method_name.is_some()); - if let Some(r) = self.pick_core() { + let mut unsatisfied_predicates = Vec::new(); + + if let Some(r) = self.pick_core(&mut unsatisfied_predicates) { return r; } @@ -1056,7 +1065,6 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { let static_candidates = std::mem::take(self.static_candidates.get_mut()); let private_candidate = self.private_candidate.take(); - let unsatisfied_predicates = std::mem::take(self.unsatisfied_predicates.get_mut()); // things failed, so lets look at all traits, for diagnostic purposes now: self.reset(); @@ -1066,7 +1074,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { self.assemble_extension_candidates_for_all_traits(); - let out_of_scope_traits = match self.pick_core() { + let out_of_scope_traits = match self.pick_core(&mut Vec::new()) { Some(Ok(p)) => vec![p.item.container_id(self.tcx)], Some(Err(MethodError::Ambiguity(v))) => v .into_iter() @@ -1101,14 +1109,40 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { })) } - fn pick_core(&self) -> Option> { + fn pick_core( + &self, + unsatisfied_predicates: &mut Vec<( + ty::Predicate<'tcx>, + Option>, + Option>, + )>, + ) -> Option> { // Pick stable methods only first, and consider unstable candidates if not found. - self.pick_all_method(Some(&mut vec![])).or_else(|| self.pick_all_method(None)) + self.pick_all_method(&mut PickDiagHints { + // This first cycle, maintain a list of unstable candidates which + // we encounter. This will end up in the Pick for diagnostics. + unstable_candidates: Some(Vec::new()), + // Contribute to the list of unsatisfied predicates which may + // also be used for diagnostics. + unsatisfied_predicates, + }) + .or_else(|| { + self.pick_all_method(&mut PickDiagHints { + // On the second search, don't provide a special list of unstable + // candidates. This indicates to the picking code that it should + // in fact include such unstable candidates in the actual + // search. + unstable_candidates: None, + // And there's no need to duplicate ourselves in the + // unsatisifed predicates list. Provide a throwaway list. + unsatisfied_predicates: &mut Vec::new(), + }) + }) } - fn pick_all_method( + fn pick_all_method<'b>( &self, - mut unstable_candidates: Option<&mut Vec<(Candidate<'tcx>, Symbol)>>, + pick_diag_hints: &mut PickDiagHints<'b, 'tcx>, ) -> Option> { self.steps .iter() @@ -1133,37 +1167,19 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { .unwrap_or_else(|_| { span_bug!(self.span, "{:?} was applicable but now isn't?", step.self_ty) }); - self.pick_by_value_method(step, self_ty, unstable_candidates.as_deref_mut()) - .or_else(|| { - self.pick_autorefd_method( - step, - self_ty, - hir::Mutability::Not, - unstable_candidates.as_deref_mut(), - ) + self.pick_by_value_method(step, self_ty, pick_diag_hints).or_else(|| { + self.pick_autorefd_method(step, self_ty, hir::Mutability::Not, pick_diag_hints) .or_else(|| { self.pick_autorefd_method( step, self_ty, hir::Mutability::Mut, - unstable_candidates.as_deref_mut(), + pick_diag_hints, ) }) - .or_else(|| { - self.pick_const_ptr_method( - step, - self_ty, - unstable_candidates.as_deref_mut(), - ) - }) - .or_else(|| { - self.pick_reborrow_pin_method( - step, - self_ty, - unstable_candidates.as_deref_mut(), - ) - }) - }) + .or_else(|| self.pick_const_ptr_method(step, self_ty, pick_diag_hints)) + .or_else(|| self.pick_reborrow_pin_method(step, self_ty, pick_diag_hints)) + }) }) } @@ -1177,13 +1193,13 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { &self, step: &CandidateStep<'tcx>, self_ty: Ty<'tcx>, - unstable_candidates: Option<&mut Vec<(Candidate<'tcx>, Symbol)>>, + pick_diag_hints: &mut PickDiagHints<'_, 'tcx>, ) -> Option> { if step.unsize { return None; } - self.pick_method(self_ty, unstable_candidates).map(|r| { + self.pick_method(self_ty, pick_diag_hints).map(|r| { r.map(|mut pick| { pick.autoderefs = step.autoderefs; @@ -1221,7 +1237,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { step: &CandidateStep<'tcx>, self_ty: Ty<'tcx>, mutbl: hir::Mutability, - unstable_candidates: Option<&mut Vec<(Candidate<'tcx>, Symbol)>>, + pick_diag_hints: &mut PickDiagHints<'_, 'tcx>, ) -> Option> { let tcx = self.tcx; @@ -1229,7 +1245,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { let region = tcx.lifetimes.re_erased; let autoref_ty = Ty::new_ref(tcx, region, self_ty, mutbl); - self.pick_method(autoref_ty, unstable_candidates).map(|r| { + self.pick_method(autoref_ty, pick_diag_hints).map(|r| { r.map(|mut pick| { pick.autoderefs = step.autoderefs; pick.autoref_or_ptr_adjustment = @@ -1240,12 +1256,12 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } /// Looks for applicable methods if we reborrow a `Pin<&mut T>` as a `Pin<&T>`. - #[instrument(level = "debug", skip(self, step, unstable_candidates))] + #[instrument(level = "debug", skip(self, step, pick_diag_hints))] fn pick_reborrow_pin_method( &self, step: &CandidateStep<'tcx>, self_ty: Ty<'tcx>, - unstable_candidates: Option<&mut Vec<(Candidate<'tcx>, Symbol)>>, + pick_diag_hints: &mut PickDiagHints<'_, 'tcx>, ) -> Option> { if !self.tcx.features().pin_ergonomics() { return None; @@ -1266,7 +1282,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { let region = self.tcx.lifetimes.re_erased; let autopin_ty = Ty::new_pinned_ref(self.tcx, region, inner_ty, hir::Mutability::Not); - self.pick_method(autopin_ty, unstable_candidates).map(|r| { + self.pick_method(autopin_ty, pick_diag_hints).map(|r| { r.map(|mut pick| { pick.autoderefs = step.autoderefs; pick.autoref_or_ptr_adjustment = @@ -1283,7 +1299,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { &self, step: &CandidateStep<'tcx>, self_ty: Ty<'tcx>, - unstable_candidates: Option<&mut Vec<(Candidate<'tcx>, Symbol)>>, + pick_diag_hints: &mut PickDiagHints<'_, 'tcx>, ) -> Option> { // Don't convert an unsized reference to ptr if step.unsize { @@ -1295,7 +1311,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { }; let const_ptr_ty = Ty::new_imm_ptr(self.tcx, ty); - self.pick_method(const_ptr_ty, unstable_candidates).map(|r| { + self.pick_method(const_ptr_ty, pick_diag_hints).map(|r| { r.map(|mut pick| { pick.autoderefs = step.autoderefs; pick.autoref_or_ptr_adjustment = Some(AutorefOrPtrAdjustment::ToConstPtr); @@ -1307,22 +1323,15 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { fn pick_method( &self, self_ty: Ty<'tcx>, - mut unstable_candidates: Option<&mut Vec<(Candidate<'tcx>, Symbol)>>, + pick_diag_hints: &mut PickDiagHints<'_, 'tcx>, ) -> Option> { debug!("pick_method(self_ty={})", self.ty_to_string(self_ty)); - let mut possibly_unsatisfied_predicates = Vec::new(); - for (kind, candidates) in [("inherent", &self.inherent_candidates), ("extension", &self.extension_candidates)] { debug!("searching {} candidates", kind); - let res = self.consider_candidates( - self_ty, - candidates, - &mut possibly_unsatisfied_predicates, - unstable_candidates.as_deref_mut(), - ); + let res = self.consider_candidates(self_ty, candidates, pick_diag_hints); if let Some(pick) = res { return Some(pick); } @@ -1330,17 +1339,14 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { if self.private_candidate.get().is_none() { if let Some(Ok(pick)) = - self.consider_candidates(self_ty, &self.private_candidates, &mut vec![], None) + self.consider_candidates(self_ty, &self.private_candidates, &mut PickDiagHints { + unstable_candidates: None, + unsatisfied_predicates: &mut vec![], + }) { self.private_candidate.set(Some((pick.item.kind.as_def_kind(), pick.item.def_id))); } } - - // `pick_method` may be called twice for the same self_ty if no stable methods - // match. Only extend once. - if unstable_candidates.is_some() { - self.unsatisfied_predicates.borrow_mut().extend(possibly_unsatisfied_predicates); - } None } @@ -1348,17 +1354,19 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { &self, self_ty: Ty<'tcx>, candidates: &[Candidate<'tcx>], - possibly_unsatisfied_predicates: &mut Vec<( - ty::Predicate<'tcx>, - Option>, - Option>, - )>, - mut unstable_candidates: Option<&mut Vec<(Candidate<'tcx>, Symbol)>>, + pick_diag_hints: &mut PickDiagHints<'_, 'tcx>, ) -> Option> { let mut applicable_candidates: Vec<_> = candidates .iter() .map(|probe| { - (probe, self.consider_probe(self_ty, probe, possibly_unsatisfied_predicates)) + ( + probe, + self.consider_probe( + self_ty, + probe, + &mut pick_diag_hints.unsatisfied_predicates, + ), + ) }) .filter(|&(_, status)| status != ProbeResult::NoMatch) .collect(); @@ -1373,7 +1381,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } } - if let Some(uc) = &mut unstable_candidates { + if let Some(uc) = &mut pick_diag_hints.unstable_candidates { applicable_candidates.retain(|&(candidate, _)| { if let stability::EvalResult::Deny { feature, .. } = self.tcx.eval_stability(candidate.item.def_id, None, self.span, None) @@ -1391,10 +1399,10 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } applicable_candidates.pop().map(|(probe, status)| match status { - ProbeResult::Match => { - Ok(probe - .to_unadjusted_pick(self_ty, unstable_candidates.cloned().unwrap_or_default())) - } + ProbeResult::Match => Ok(probe.to_unadjusted_pick( + self_ty, + pick_diag_hints.unstable_candidates.clone().unwrap_or_default(), + )), ProbeResult::NoMatch | ProbeResult::BadReturnType => Err(MethodError::BadReturnType), }) } @@ -1859,7 +1867,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { pcx.method_name = Some(method_name); pcx.assemble_inherent_candidates(); pcx.assemble_extension_candidates_for_all_traits(); - pcx.pick_core().and_then(|pick| pick.ok()).map(|pick| pick.item) + pcx.pick_core(&mut Vec::new()).and_then(|pick| pick.ok()).map(|pick| pick.item) }) .collect(); From 2707f5578da273284770298be9202c0cdd6621b3 Mon Sep 17 00:00:00 2001 From: Adrian Taylor Date: Fri, 12 Jul 2024 14:26:35 +0000 Subject: [PATCH 09/20] Arbitrary self types v2: deshadowing probe This is the first part of a series of commits which impact the "deshadowing detection" in the arbitrary self types v2 RFC. This commit should not have any functional changes, but may impact performance. Subsequent commits add back the performance, and add error checking to this new code such that it has a functional effect. Rust prioritizes method candidates in this order: 1. By value; 2. By reference; 3. By mutable reference; 4. By const ptr. 5. By reborrowed pin. Previously, if a suitable candidate was found in one of these earlier categories, Rust wouldn't even move onto probing the other categories. As part of the arbitrary self types work, we're going to need to change that - even if we choose a method from one of the earlier categories, we will sometimes need to probe later categories to search for methods that we may be shadowing. This commit adds those extra searches for shadowing, but it does not yet produce an error when such shadowing problems are found. That will come in a subsequent commit, by filling out the 'check_for_shadowing' method. This commit contains a naive approach to detecting these shadowing problems, which shows what we've functionally looking to do. However, it's too slow. The performance of this approach was explored in this PR: https://github.com/rust-lang/rust/pull/127812#issuecomment-2236911900 Subsequent commits will improve the speed of the search. --- compiler/rustc_hir_typeck/src/method/probe.rs | 124 ++++++++++++++++-- 1 file changed, 114 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index c92f00a54dd2b..66ff71f729cbf 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -1144,6 +1144,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { &self, pick_diag_hints: &mut PickDiagHints<'b, 'tcx>, ) -> Option> { + let track_unstable_candidates = pick_diag_hints.unstable_candidates.is_some(); self.steps .iter() // At this point we're considering the types to which the receiver can be converted, @@ -1167,22 +1168,125 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { .unwrap_or_else(|_| { span_bug!(self.span, "{:?} was applicable but now isn't?", step.self_ty) }); - self.pick_by_value_method(step, self_ty, pick_diag_hints).or_else(|| { - self.pick_autorefd_method(step, self_ty, hir::Mutability::Not, pick_diag_hints) - .or_else(|| { - self.pick_autorefd_method( + + let by_value_pick = self.pick_by_value_method(step, self_ty, pick_diag_hints); + + // Check for shadowing of a by-reference method by a by-value method (see comments on check_for_shadowing) + if let Some(by_value_pick) = by_value_pick { + if let Ok(by_value_pick) = by_value_pick.as_ref() { + if by_value_pick.kind == PickKind::InherentImplPick { + if let Err(e) = self.check_for_shadowed_autorefd_method( + by_value_pick, + step, + self_ty, + hir::Mutability::Not, + track_unstable_candidates, + ) { + return Some(Err(e)); + } + if let Err(e) = self.check_for_shadowed_autorefd_method( + by_value_pick, step, self_ty, hir::Mutability::Mut, - pick_diag_hints, - ) - }) - .or_else(|| self.pick_const_ptr_method(step, self_ty, pick_diag_hints)) - .or_else(|| self.pick_reborrow_pin_method(step, self_ty, pick_diag_hints)) - }) + track_unstable_candidates, + ) { + return Some(Err(e)); + } + } + } + return Some(by_value_pick); + } + + let autoref_pick = + self.pick_autorefd_method(step, self_ty, hir::Mutability::Not, pick_diag_hints); + // Check for shadowing of a by-mut-ref method by a by-reference method (see comments on check_for_shadowing) + if let Some(autoref_pick) = autoref_pick { + if let Ok(autoref_pick) = autoref_pick.as_ref() { + // Check we're not shadowing others + if autoref_pick.kind == PickKind::InherentImplPick { + if let Err(e) = self.check_for_shadowed_autorefd_method( + autoref_pick, + step, + self_ty, + hir::Mutability::Mut, + track_unstable_candidates, + ) { + return Some(Err(e)); + } + } + } + return Some(autoref_pick); + } + + // Note that no shadowing errors are produced from here on, + // as we consider const ptr methods. + // We allow new methods that take *mut T to shadow + // methods which took *const T, so there is no entry in + // this list for the results of `pick_const_ptr_method`. + // The reason is that the standard pointer cast method + // (on a mutable pointer) always already shadows the + // cast method (on a const pointer). So, if we added + // `pick_const_ptr_method` to this method, the anti- + // shadowing algorithm would always complain about + // the conflict between *const::cast and *mut::cast. + // In practice therefore this does constrain us: + // we cannot add new + // self: *mut Self + // methods to types such as NonNull or anything else + // which implements Receiver, because this might in future + // shadow existing methods taking + // self: *const NonNull + // in the pointee. In practice, methods taking raw pointers + // are rare, and it seems that it should be easily possible + // to avoid such compatibility breaks. + // We also don't check for reborrowed pin methods which + // may be shadowed; these also seem unlikely to occur. + self.pick_autorefd_method(step, self_ty, hir::Mutability::Mut, pick_diag_hints) + .or_else(|| self.pick_const_ptr_method(step, self_ty, pick_diag_hints)) + .or_else(|| self.pick_reborrow_pin_method(step, self_ty, pick_diag_hints)) }) } + /// Check for cases where arbitrary self types allows shadowing + /// of methods that might be a compatibility break. Specifically, + /// we have something like: + /// ```ignore (illustrative) + /// struct A; + /// impl A { + /// fn foo(self: &NonNull) {} + /// // note this is by reference + /// } + /// ``` + /// then we've come along and added this method to `NonNull`: + /// ```ignore (illustrative) + /// fn foo(self) // note this is by value + /// ``` + /// Report an error in this case. + fn check_for_shadowed_autorefd_method( + &self, + _possible_shadower: &Pick<'tcx>, + step: &CandidateStep<'tcx>, + self_ty: Ty<'tcx>, + mutbl: hir::Mutability, + track_unstable_candidates: bool, + ) -> Result<(), MethodError<'tcx>> { + // We don't want to remember any of the diagnostic hints from this + // shadow search, but we do need to provide Some/None for the + // unstable_candidates in order to reflect the behavior of the + // main search. + let mut pick_diag_hints = PickDiagHints { + unstable_candidates: if track_unstable_candidates { Some(Vec::new()) } else { None }, + unsatisfied_predicates: &mut Vec::new(), + }; + let _potentially_shadowed_pick = + self.pick_autorefd_method(step, self_ty, mutbl, &mut pick_diag_hints); + + // At the moment, this function does no checks. A future + // commit will fill out the body here. + Ok(()) + } + /// For each type `T` in the step list, this attempts to find a method where /// the (transformed) self type is exactly `T`. We do however do one /// transformation on the adjustment: if we are passing a region pointer in, From 48e1df87e1422a845f05a8f6c5fc4773758cc9d9 Mon Sep 17 00:00:00 2001 From: Adrian Taylor Date: Mon, 11 Nov 2024 13:47:51 +0000 Subject: [PATCH 10/20] Arbitrary self types v2: deshadow quicker MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A previous commit added a search for certain types of "shadowing" situation where one method (in an outer smart pointer type, typically) might hide or shadow the method in the pointee. Performance investigation showed that the naïve approach is too slow - this commit speeds it up, while being functionally the same. This still does not actually cause the deshadowing check to emit any errors; that comes in a subsequent commit which is where all the tests live. --- compiler/rustc_hir_typeck/src/demand.rs | 2 +- compiler/rustc_hir_typeck/src/method/probe.rs | 210 +++++++++++++++--- 2 files changed, 174 insertions(+), 38 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index 3399a9fe88078..d0272651c0809 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -917,7 +917,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { [candidate] => format!( "the method of the same name on {} `{}`", match candidate.kind { - probe::CandidateKind::InherentImplCandidate(_) => "the inherent impl for", + probe::CandidateKind::InherentImplCandidate { .. } => "the inherent impl for", _ => "trait", }, self.tcx.def_path_str(candidate.item.container_id(self.tcx)) diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 66ff71f729cbf..7524a1faaa394 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -103,7 +103,7 @@ pub(crate) struct Candidate<'tcx> { #[derive(Debug, Clone)] pub(crate) enum CandidateKind<'tcx> { - InherentImplCandidate(DefId), + InherentImplCandidate { impl_def_id: DefId, receiver_steps: usize }, ObjectCandidate(ty::PolyTraitRef<'tcx>), TraitCandidate(ty::PolyTraitRef<'tcx>), WhereClauseCandidate(ty::PolyTraitRef<'tcx>), @@ -171,6 +171,37 @@ struct PickDiagHints<'a, 'tcx> { )>, } +/// Criteria to apply when searching for a given Pick. This is used during +/// the search for potentially shadowed methods to ensure we don't search +/// more candidates than strictly necessary. +#[derive(Debug)] +struct PickConstraintsForShadowed { + autoderefs: usize, + receiver_steps: Option, + def_id: DefId, +} + +impl PickConstraintsForShadowed { + fn may_shadow_based_on_autoderefs(&self, autoderefs: usize) -> bool { + autoderefs == self.autoderefs + } + + fn candidate_may_shadow(&self, candidate: &Candidate<'_>) -> bool { + // An item never shadows itself + candidate.item.def_id != self.def_id + // and we're only concerned about inherent impls doing the shadowing. + // Shadowing can only occur if the shadowed is further along + // the Receiver dereferencing chain than the shadowed. + && match candidate.kind { + CandidateKind::InherentImplCandidate { receiver_steps, .. } => match self.receiver_steps { + Some(shadowed_receiver_steps) => receiver_steps > shadowed_receiver_steps, + _ => false + }, + _ => false + } + } +} + #[derive(Debug, Clone)] pub(crate) struct Pick<'tcx> { pub item: ty::AssocItem, @@ -190,6 +221,11 @@ pub(crate) struct Pick<'tcx> { /// Unstable candidates alongside the stable ones. unstable_candidates: Vec<(Candidate<'tcx>, Symbol)>, + + /// Number of jumps along the `Receiver::Target` chain we followed + /// to identify this method. Used only for deshadowing errors. + /// Only applies for inherent impls. + pub receiver_steps: Option, } #[derive(Clone, Debug, PartialEq, Eq)] @@ -706,12 +742,16 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { fn assemble_inherent_candidates(&mut self) { for step in self.steps.iter() { - self.assemble_probe(&step.self_ty); + self.assemble_probe(&step.self_ty, step.autoderefs); } } #[instrument(level = "debug", skip(self))] - fn assemble_probe(&mut self, self_ty: &Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>) { + fn assemble_probe( + &mut self, + self_ty: &Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>, + receiver_steps: usize, + ) { let raw_self_ty = self_ty.value.value; match *raw_self_ty.kind() { ty::Dynamic(data, ..) if let Some(p) = data.principal() => { @@ -736,22 +776,31 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { self.fcx.instantiate_canonical(self.span, self_ty); self.assemble_inherent_candidates_from_object(generalized_self_ty); - self.assemble_inherent_impl_candidates_for_type(p.def_id()); + self.assemble_inherent_impl_candidates_for_type(p.def_id(), receiver_steps); if self.tcx.has_attr(p.def_id(), sym::rustc_has_incoherent_inherent_impls) { - self.assemble_inherent_candidates_for_incoherent_ty(raw_self_ty); + self.assemble_inherent_candidates_for_incoherent_ty( + raw_self_ty, + receiver_steps, + ); } } ty::Adt(def, _) => { let def_id = def.did(); - self.assemble_inherent_impl_candidates_for_type(def_id); + self.assemble_inherent_impl_candidates_for_type(def_id, receiver_steps); if self.tcx.has_attr(def_id, sym::rustc_has_incoherent_inherent_impls) { - self.assemble_inherent_candidates_for_incoherent_ty(raw_self_ty); + self.assemble_inherent_candidates_for_incoherent_ty( + raw_self_ty, + receiver_steps, + ); } } ty::Foreign(did) => { - self.assemble_inherent_impl_candidates_for_type(did); + self.assemble_inherent_impl_candidates_for_type(did, receiver_steps); if self.tcx.has_attr(did, sym::rustc_has_incoherent_inherent_impls) { - self.assemble_inherent_candidates_for_incoherent_ty(raw_self_ty); + self.assemble_inherent_candidates_for_incoherent_ty( + raw_self_ty, + receiver_steps, + ); } } ty::Param(p) => { @@ -768,29 +817,35 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { | ty::RawPtr(_, _) | ty::Ref(..) | ty::Never - | ty::Tuple(..) => self.assemble_inherent_candidates_for_incoherent_ty(raw_self_ty), + | ty::Tuple(..) => { + self.assemble_inherent_candidates_for_incoherent_ty(raw_self_ty, receiver_steps) + } _ => {} } } - fn assemble_inherent_candidates_for_incoherent_ty(&mut self, self_ty: Ty<'tcx>) { + fn assemble_inherent_candidates_for_incoherent_ty( + &mut self, + self_ty: Ty<'tcx>, + receiver_steps: usize, + ) { let Some(simp) = simplify_type(self.tcx, self_ty, TreatParams::InstantiateWithInfer) else { bug!("unexpected incoherent type: {:?}", self_ty) }; for &impl_def_id in self.tcx.incoherent_impls(simp).into_iter() { - self.assemble_inherent_impl_probe(impl_def_id); + self.assemble_inherent_impl_probe(impl_def_id, receiver_steps); } } - fn assemble_inherent_impl_candidates_for_type(&mut self, def_id: DefId) { + fn assemble_inherent_impl_candidates_for_type(&mut self, def_id: DefId, receiver_steps: usize) { let impl_def_ids = self.tcx.at(self.span).inherent_impls(def_id).into_iter(); for &impl_def_id in impl_def_ids { - self.assemble_inherent_impl_probe(impl_def_id); + self.assemble_inherent_impl_probe(impl_def_id, receiver_steps); } } #[instrument(level = "debug", skip(self))] - fn assemble_inherent_impl_probe(&mut self, impl_def_id: DefId) { + fn assemble_inherent_impl_probe(&mut self, impl_def_id: DefId, receiver_steps: usize) { if !self.impl_dups.insert(impl_def_id) { return; // already visited } @@ -804,7 +859,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { self.push_candidate( Candidate { item, - kind: InherentImplCandidate(impl_def_id), + kind: InherentImplCandidate { impl_def_id, receiver_steps }, import_ids: smallvec![], }, true, @@ -1198,8 +1253,13 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { return Some(by_value_pick); } - let autoref_pick = - self.pick_autorefd_method(step, self_ty, hir::Mutability::Not, pick_diag_hints); + let autoref_pick = self.pick_autorefd_method( + step, + self_ty, + hir::Mutability::Not, + pick_diag_hints, + None, + ); // Check for shadowing of a by-mut-ref method by a by-reference method (see comments on check_for_shadowing) if let Some(autoref_pick) = autoref_pick { if let Ok(autoref_pick) = autoref_pick.as_ref() { @@ -1242,9 +1302,15 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { // to avoid such compatibility breaks. // We also don't check for reborrowed pin methods which // may be shadowed; these also seem unlikely to occur. - self.pick_autorefd_method(step, self_ty, hir::Mutability::Mut, pick_diag_hints) - .or_else(|| self.pick_const_ptr_method(step, self_ty, pick_diag_hints)) - .or_else(|| self.pick_reborrow_pin_method(step, self_ty, pick_diag_hints)) + self.pick_autorefd_method( + step, + self_ty, + hir::Mutability::Mut, + pick_diag_hints, + None, + ) + .or_else(|| self.pick_const_ptr_method(step, self_ty, pick_diag_hints)) + .or_else(|| self.pick_reborrow_pin_method(step, self_ty, pick_diag_hints)) }) } @@ -1265,7 +1331,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { /// Report an error in this case. fn check_for_shadowed_autorefd_method( &self, - _possible_shadower: &Pick<'tcx>, + possible_shadower: &Pick<'tcx>, step: &CandidateStep<'tcx>, self_ty: Ty<'tcx>, mutbl: hir::Mutability, @@ -1279,8 +1345,54 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { unstable_candidates: if track_unstable_candidates { Some(Vec::new()) } else { None }, unsatisfied_predicates: &mut Vec::new(), }; - let _potentially_shadowed_pick = - self.pick_autorefd_method(step, self_ty, mutbl, &mut pick_diag_hints); + // Set criteria for how we find methods possibly shadowed by 'possible_shadower' + let pick_constraints = PickConstraintsForShadowed { + // It's the same `self` type... + autoderefs: possible_shadower.autoderefs, + // ... but the method was found in an impl block determined + // by searching further along the Receiver chain than the other, + // showing that it's a smart pointer type causing the problem... + receiver_steps: possible_shadower.receiver_steps, + // ... and they don't end up pointing to the same item in the + // first place (could happen with things like blanket impls for T) + def_id: possible_shadower.item.def_id, + }; + // A note on the autoderefs above. Within pick_by_value_method, an extra + // autoderef may be applied in order to reborrow a reference with + // a different lifetime. That seems as though it would break the + // logic of these constraints, since the number of autoderefs could + // no longer be used to identify the fundamental type of the receiver. + // However, this extra autoderef is applied only to by-value calls + // where the receiver is already a reference. So this situation would + // only occur in cases where the shadowing looks like this: + // ``` + // struct A; + // impl A { + // fn foo(self: &&NonNull) {} + // // note this is by DOUBLE reference + // } + // ``` + // then we've come along and added this method to `NonNull`: + // ``` + // fn foo(&self) // note this is by single reference + // ``` + // and the call is: + // ``` + // let bar = NonNull; + // let bar = &foo; + // bar.foo(); + // ``` + // In these circumstances, the logic is wrong, and we wouldn't spot + // the shadowing, because the autoderef-based maths wouldn't line up. + // This is a niche case and we can live without generating an error + // in the case of such shadowing. + let _potentially_shadowed_pick = self.pick_autorefd_method( + step, + self_ty, + mutbl, + &mut pick_diag_hints, + Some(&pick_constraints), + ); // At the moment, this function does no checks. A future // commit will fill out the body here. @@ -1303,7 +1415,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { return None; } - self.pick_method(self_ty, pick_diag_hints).map(|r| { + self.pick_method(self_ty, pick_diag_hints, None).map(|r| { r.map(|mut pick| { pick.autoderefs = step.autoderefs; @@ -1342,14 +1454,21 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { self_ty: Ty<'tcx>, mutbl: hir::Mutability, pick_diag_hints: &mut PickDiagHints<'_, 'tcx>, + pick_constraints: Option<&PickConstraintsForShadowed>, ) -> Option> { let tcx = self.tcx; + if let Some(pick_constraints) = pick_constraints { + if !pick_constraints.may_shadow_based_on_autoderefs(step.autoderefs) { + return None; + } + } + // In general, during probing we erase regions. let region = tcx.lifetimes.re_erased; let autoref_ty = Ty::new_ref(tcx, region, self_ty, mutbl); - self.pick_method(autoref_ty, pick_diag_hints).map(|r| { + self.pick_method(autoref_ty, pick_diag_hints, pick_constraints).map(|r| { r.map(|mut pick| { pick.autoderefs = step.autoderefs; pick.autoref_or_ptr_adjustment = @@ -1386,7 +1505,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { let region = self.tcx.lifetimes.re_erased; let autopin_ty = Ty::new_pinned_ref(self.tcx, region, inner_ty, hir::Mutability::Not); - self.pick_method(autopin_ty, pick_diag_hints).map(|r| { + self.pick_method(autopin_ty, pick_diag_hints, None).map(|r| { r.map(|mut pick| { pick.autoderefs = step.autoderefs; pick.autoref_or_ptr_adjustment = @@ -1415,7 +1534,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { }; let const_ptr_ty = Ty::new_imm_ptr(self.tcx, ty); - self.pick_method(const_ptr_ty, pick_diag_hints).map(|r| { + self.pick_method(const_ptr_ty, pick_diag_hints, None).map(|r| { r.map(|mut pick| { pick.autoderefs = step.autoderefs; pick.autoref_or_ptr_adjustment = Some(AutorefOrPtrAdjustment::ToConstPtr); @@ -1428,6 +1547,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { &self, self_ty: Ty<'tcx>, pick_diag_hints: &mut PickDiagHints<'_, 'tcx>, + pick_constraints: Option<&PickConstraintsForShadowed>, ) -> Option> { debug!("pick_method(self_ty={})", self.ty_to_string(self_ty)); @@ -1435,19 +1555,23 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { [("inherent", &self.inherent_candidates), ("extension", &self.extension_candidates)] { debug!("searching {} candidates", kind); - let res = self.consider_candidates(self_ty, candidates, pick_diag_hints); + let res = + self.consider_candidates(self_ty, candidates, pick_diag_hints, pick_constraints); if let Some(pick) = res { return Some(pick); } } if self.private_candidate.get().is_none() { - if let Some(Ok(pick)) = - self.consider_candidates(self_ty, &self.private_candidates, &mut PickDiagHints { + if let Some(Ok(pick)) = self.consider_candidates( + self_ty, + &self.private_candidates, + &mut PickDiagHints { unstable_candidates: None, unsatisfied_predicates: &mut vec![], - }) - { + }, + None, + ) { self.private_candidate.set(Some((pick.item.kind.as_def_kind(), pick.item.def_id))); } } @@ -1459,9 +1583,15 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { self_ty: Ty<'tcx>, candidates: &[Candidate<'tcx>], pick_diag_hints: &mut PickDiagHints<'_, 'tcx>, + pick_constraints: Option<&PickConstraintsForShadowed>, ) -> Option> { let mut applicable_candidates: Vec<_> = candidates .iter() + .filter(|candidate| { + pick_constraints + .map(|pick_constraints| pick_constraints.candidate_may_shadow(&candidate)) + .unwrap_or(true) + }) .map(|probe| { ( probe, @@ -1535,6 +1665,7 @@ impl<'tcx> Pick<'tcx> { autoref_or_ptr_adjustment: _, self_ty, unstable_candidates: _, + receiver_steps: _, } = *self; self_ty != other.self_ty || def_id != other.item.def_id } @@ -1610,7 +1741,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { /// so do not use to make a decision that may lead to a successful compilation. fn candidate_source(&self, candidate: &Candidate<'tcx>, self_ty: Ty<'tcx>) -> CandidateSource { match candidate.kind { - InherentImplCandidate(_) => { + InherentImplCandidate { .. } => { CandidateSource::Impl(candidate.item.container_id(self.tcx)) } ObjectCandidate(_) | WhereClauseCandidate(_) => { @@ -1664,7 +1795,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { let (mut xform_self_ty, mut xform_ret_ty); match probe.kind { - InherentImplCandidate(impl_def_id) => { + InherentImplCandidate { impl_def_id, .. } => { let impl_args = self.fresh_args_for_item(self.span, impl_def_id); let impl_ty = self.tcx.type_of(impl_def_id).instantiate(self.tcx, impl_args); (xform_self_ty, xform_ret_ty) = @@ -1856,7 +1987,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { // We don't normalize the other candidates for perf/backwards-compat reasons... // but `self.return_type` is only set on the diagnostic-path, so we // should be okay doing it here. - if !matches!(probe.kind, InherentImplCandidate(_)) { + if !matches!(probe.kind, InherentImplCandidate { .. }) { xform_ret_ty = ocx.normalize(&cause, self.param_env, xform_ret_ty); } @@ -1934,6 +2065,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { autoref_or_ptr_adjustment: None, self_ty, unstable_candidates: vec![], + receiver_steps: None, }) } @@ -2205,7 +2337,7 @@ impl<'tcx> Candidate<'tcx> { Pick { item: self.item, kind: match self.kind { - InherentImplCandidate(_) => InherentImplPick, + InherentImplCandidate { .. } => InherentImplPick, ObjectCandidate(_) => ObjectPick, TraitCandidate(_) => TraitPick, WhereClauseCandidate(trait_ref) => { @@ -2227,6 +2359,10 @@ impl<'tcx> Candidate<'tcx> { autoref_or_ptr_adjustment: None, self_ty, unstable_candidates, + receiver_steps: match self.kind { + InherentImplCandidate { receiver_steps, .. } => Some(receiver_steps), + _ => None, + }, } } } From a269b312314e5c3fb96188ff8e797603bc669f63 Mon Sep 17 00:00:00 2001 From: Adrian Taylor Date: Thu, 1 Aug 2024 16:56:04 +0000 Subject: [PATCH 11/20] Arbitrary self types v2: detect shadowing problems. This builds on the previous commits by actually adding checks for cases where a new method shadows an older method. --- compiler/rustc_hir_typeck/src/method/probe.rs | 23 +++- .../arbitrary_self_types_by_value_reborrow.rs | 69 ++++++++++ ...trary_self_types_shadowing_val_constptr.rs | 33 +++++ .../self/arbitrary_self_types_unshadowing.rs | 55 ++++++++ .../arbitrary_self_types_unshadowing.stderr | 105 +++++++++++++++ .../arbitrary_self_types_unshadowing_ptrs.rs | 61 +++++++++ ...bitrary_self_types_unshadowing_ptrs.stderr | 122 ++++++++++++++++++ tests/ui/self/conflicting_inner.rs | 38 ++++++ tests/ui/self/conflicting_inner2.rs | 63 +++++++++ 9 files changed, 565 insertions(+), 4 deletions(-) create mode 100644 tests/ui/self/arbitrary_self_types_by_value_reborrow.rs create mode 100644 tests/ui/self/arbitrary_self_types_shadowing_val_constptr.rs create mode 100644 tests/ui/self/arbitrary_self_types_unshadowing.rs create mode 100644 tests/ui/self/arbitrary_self_types_unshadowing.stderr create mode 100644 tests/ui/self/arbitrary_self_types_unshadowing_ptrs.rs create mode 100644 tests/ui/self/arbitrary_self_types_unshadowing_ptrs.stderr create mode 100644 tests/ui/self/conflicting_inner.rs create mode 100644 tests/ui/self/conflicting_inner2.rs diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 7524a1faaa394..3b377076545da 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -1386,16 +1386,22 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { // the shadowing, because the autoderef-based maths wouldn't line up. // This is a niche case and we can live without generating an error // in the case of such shadowing. - let _potentially_shadowed_pick = self.pick_autorefd_method( + let potentially_shadowed_pick = self.pick_autorefd_method( step, self_ty, mutbl, &mut pick_diag_hints, Some(&pick_constraints), ); - - // At the moment, this function does no checks. A future - // commit will fill out the body here. + // Look for actual pairs of shadower/shadowed which are + // the sort of shadowing case we want to avoid. Specifically... + if let Some(Ok(possible_shadowed)) = potentially_shadowed_pick.as_ref() { + let sources = [possible_shadower, possible_shadowed] + .into_iter() + .map(|p| self.candidate_source_from_pick(p)) + .collect(); + return Err(MethodError::Ambiguity(sources)); + } Ok(()) } @@ -1771,6 +1777,15 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } } + fn candidate_source_from_pick(&self, pick: &Pick<'tcx>) -> CandidateSource { + match pick.kind { + InherentImplPick => CandidateSource::Impl(pick.item.container_id(self.tcx)), + ObjectPick | WhereClausePick(_) | TraitPick => { + CandidateSource::Trait(pick.item.container_id(self.tcx)) + } + } + } + #[instrument(level = "trace", skip(self, possibly_unsatisfied_predicates), ret)] fn consider_probe( &self, diff --git a/tests/ui/self/arbitrary_self_types_by_value_reborrow.rs b/tests/ui/self/arbitrary_self_types_by_value_reborrow.rs new file mode 100644 index 0000000000000..de4db1b9afec7 --- /dev/null +++ b/tests/ui/self/arbitrary_self_types_by_value_reborrow.rs @@ -0,0 +1,69 @@ +//@ run-pass + +#![feature(arbitrary_self_types)] +#![allow(dead_code)] + +// With arbitrary self types v2, we show an error if there are +// multiple contenders for a method call in an inner and outer type. +// The goal is to avoid any possibility of confusion by a new +// 'shadowing' method calling a 'shadowed' method. +// However, there are niche circumstances where this +// algorithm doesn't quite work, due to reborrows to get a different +// lifetime. The test below explicitly tests those circumstances to ensure +// the behavior is as expected, even if it's not 100% desirable. They're +// very niche circumstances. + +#[derive(Debug, PartialEq)] +enum Callee { + INNER, + OUTER +} + +struct MyNonNull(T); + +impl std::ops::Receiver for MyNonNull { + type Target = T; +} + +struct A; +impl A { + fn foo(self: MyNonNull) -> Callee { + Callee::INNER + } + + fn bar(self: &MyNonNull) -> Callee { + Callee::INNER + } + + fn baz(self: &&MyNonNull) -> Callee { + // note this is by DOUBLE reference + Callee::INNER + } +} + +impl MyNonNull { + fn foo(&self) -> Callee{ + Callee::OUTER + } + + fn bar(&self) -> Callee{ + Callee::OUTER + } + + fn baz(&self) -> Callee{ + Callee::OUTER + } +} + +fn main() { + // The normal deshadowing case. Does not compile. + // assert_eq!(MyNonNull(A).foo(), Callee::INNER); + + // Similarly, does not compile. + //assert_eq!(MyNonNull(A).bar(), Callee::INNER); + + // The double-reference case. + // We call the newly-added outer type method. + // Not ideal but very niche so we accept it. + assert_eq!(MyNonNull(A).baz(), Callee::OUTER); +} diff --git a/tests/ui/self/arbitrary_self_types_shadowing_val_constptr.rs b/tests/ui/self/arbitrary_self_types_shadowing_val_constptr.rs new file mode 100644 index 0000000000000..2b718cb0454ce --- /dev/null +++ b/tests/ui/self/arbitrary_self_types_shadowing_val_constptr.rs @@ -0,0 +1,33 @@ +//@ run-pass + +#![feature(arbitrary_self_types)] +#![feature(arbitrary_self_types_pointers)] + +pub struct A; + +impl A { + pub fn f(self: *const MyNonNull) -> i32 { 1 } +} + +pub struct MyNonNull(T); + +impl core::ops::Receiver for MyNonNull { + type Target = T; +} + +impl MyNonNull { + // Imagine this a NEW method in B shadowing an EXISTING + // method in A. + pub fn f(self: *mut Self) -> i32 { + 2 + } +} + +fn main() { + let mut b = MyNonNull(A); + let b = &mut b; + let b = b as *mut MyNonNull; + // We actually allow the shadowing in the case of const vs mut raw + // pointer receivers. + assert_eq!(b.f(), 2); +} diff --git a/tests/ui/self/arbitrary_self_types_unshadowing.rs b/tests/ui/self/arbitrary_self_types_unshadowing.rs new file mode 100644 index 0000000000000..cd195654cc195 --- /dev/null +++ b/tests/ui/self/arbitrary_self_types_unshadowing.rs @@ -0,0 +1,55 @@ +#![feature(arbitrary_self_types)] + +pub struct A; + +// The receiver of the potentially shadowed method +// precisely matches that of the shadower +impl A { + pub fn f(self: Wrapper) -> i32 { 1 } + pub fn g(self: &Wrapper) -> i32 { 2 } + pub fn h(self: &mut Wrapper) -> i32 { 3 } +} + +// The receiver of the potentially shadowed method is a reference +pub struct B; + +impl B { + pub fn f(self: &Wrapper) -> i32 { 9 } +} + +// The receiver of the potentially shadowed method is a mut reference + +pub struct C; + +impl C { + pub fn f(self: &mut Wrapper) -> i32 { 10 } + pub fn g(self: &mut Wrapper) -> i32 { 11 } +} + +pub struct Wrapper(T); + +impl core::ops::Receiver for Wrapper { + type Target = T; +} + +impl Wrapper { + pub fn f(self) -> i32 { 5 } + pub fn g(&self) -> i32 { 6 } + pub fn h(&mut self) -> i32 { 7 } +} + +fn main() { + assert_eq!(Wrapper(A).f(), 1); + //~^ ERROR: multiple applicable items in scope + assert_eq!(Wrapper(A).g(), 2); + //~^ ERROR: multiple applicable items in scope + assert_eq!(Wrapper(A).h(), 3); + //~^ ERROR: multiple applicable items in scope + let a = Wrapper(A); + assert_eq!(Wrapper(B).f(), 9); + //~^ ERROR: multiple applicable items in scope + assert_eq!(Wrapper(C).f(), 10); + //~^ ERROR: multiple applicable items in scope + assert_eq!(Wrapper(C).g(), 11); + //~^ ERROR: multiple applicable items in scope +} diff --git a/tests/ui/self/arbitrary_self_types_unshadowing.stderr b/tests/ui/self/arbitrary_self_types_unshadowing.stderr new file mode 100644 index 0000000000000..3a126c495c94d --- /dev/null +++ b/tests/ui/self/arbitrary_self_types_unshadowing.stderr @@ -0,0 +1,105 @@ +error[E0034]: multiple applicable items in scope + --> $DIR/arbitrary_self_types_unshadowing.rs:42:27 + | +LL | assert_eq!(Wrapper(A).f(), 1); + | ^ multiple `f` found + | +note: candidate #1 is defined in an impl for the type `A` + --> $DIR/arbitrary_self_types_unshadowing.rs:8:5 + | +LL | pub fn f(self: Wrapper) -> i32 { 1 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: candidate #2 is defined in an impl for the type `Wrapper` + --> $DIR/arbitrary_self_types_unshadowing.rs:36:5 + | +LL | pub fn f(self) -> i32 { 5 } + | ^^^^^^^^^^^^^^^^^^^^^ + +error[E0034]: multiple applicable items in scope + --> $DIR/arbitrary_self_types_unshadowing.rs:44:27 + | +LL | assert_eq!(Wrapper(A).g(), 2); + | ^ multiple `g` found + | +note: candidate #1 is defined in an impl for the type `A` + --> $DIR/arbitrary_self_types_unshadowing.rs:9:5 + | +LL | pub fn g(self: &Wrapper) -> i32 { 2 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: candidate #2 is defined in an impl for the type `Wrapper` + --> $DIR/arbitrary_self_types_unshadowing.rs:37:5 + | +LL | pub fn g(&self) -> i32 { 6 } + | ^^^^^^^^^^^^^^^^^^^^^^ + +error[E0034]: multiple applicable items in scope + --> $DIR/arbitrary_self_types_unshadowing.rs:46:27 + | +LL | assert_eq!(Wrapper(A).h(), 3); + | ^ multiple `h` found + | +note: candidate #1 is defined in an impl for the type `A` + --> $DIR/arbitrary_self_types_unshadowing.rs:10:5 + | +LL | pub fn h(self: &mut Wrapper) -> i32 { 3 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: candidate #2 is defined in an impl for the type `Wrapper` + --> $DIR/arbitrary_self_types_unshadowing.rs:38:5 + | +LL | pub fn h(&mut self) -> i32 { 7 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0034]: multiple applicable items in scope + --> $DIR/arbitrary_self_types_unshadowing.rs:49:27 + | +LL | assert_eq!(Wrapper(B).f(), 9); + | ^ multiple `f` found + | +note: candidate #1 is defined in an impl for the type `B` + --> $DIR/arbitrary_self_types_unshadowing.rs:17:5 + | +LL | pub fn f(self: &Wrapper) -> i32 { 9 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: candidate #2 is defined in an impl for the type `Wrapper` + --> $DIR/arbitrary_self_types_unshadowing.rs:36:5 + | +LL | pub fn f(self) -> i32 { 5 } + | ^^^^^^^^^^^^^^^^^^^^^ + +error[E0034]: multiple applicable items in scope + --> $DIR/arbitrary_self_types_unshadowing.rs:51:27 + | +LL | assert_eq!(Wrapper(C).f(), 10); + | ^ multiple `f` found + | +note: candidate #1 is defined in an impl for the type `C` + --> $DIR/arbitrary_self_types_unshadowing.rs:25:5 + | +LL | pub fn f(self: &mut Wrapper) -> i32 { 10 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: candidate #2 is defined in an impl for the type `Wrapper` + --> $DIR/arbitrary_self_types_unshadowing.rs:36:5 + | +LL | pub fn f(self) -> i32 { 5 } + | ^^^^^^^^^^^^^^^^^^^^^ + +error[E0034]: multiple applicable items in scope + --> $DIR/arbitrary_self_types_unshadowing.rs:53:27 + | +LL | assert_eq!(Wrapper(C).g(), 11); + | ^ multiple `g` found + | +note: candidate #1 is defined in an impl for the type `C` + --> $DIR/arbitrary_self_types_unshadowing.rs:26:5 + | +LL | pub fn g(self: &mut Wrapper) -> i32 { 11 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: candidate #2 is defined in an impl for the type `Wrapper` + --> $DIR/arbitrary_self_types_unshadowing.rs:37:5 + | +LL | pub fn g(&self) -> i32 { 6 } + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0034`. diff --git a/tests/ui/self/arbitrary_self_types_unshadowing_ptrs.rs b/tests/ui/self/arbitrary_self_types_unshadowing_ptrs.rs new file mode 100644 index 0000000000000..62553c2622a7e --- /dev/null +++ b/tests/ui/self/arbitrary_self_types_unshadowing_ptrs.rs @@ -0,0 +1,61 @@ +#![feature(arbitrary_self_types_pointers)] +#![feature(arbitrary_self_types)] + +pub struct A; + +// The receiver of the potentially shadowed method +// precisely matches that of the shadower +impl A { + pub fn f(self: Wrapper) -> i32 { 1 } + pub fn g(self: &Wrapper) -> i32 { 2 } + pub fn h(self: &mut Wrapper) -> i32 { 3 } + pub fn i(self: *const Wrapper) -> i32 { 4 } +} + +// The receiver of the potentially shadowed method is a reference +pub struct B; + +impl B { + pub fn f(self: &Wrapper) -> i32 { 9 } +} + +// The receiver of the potentially shadowed method is a mut reference + +pub struct C; + +impl C { + pub fn f(self: &mut Wrapper) -> i32 { 10 } + pub fn g(self: &mut Wrapper) -> i32 { 11 } +} + +pub struct Wrapper(T); + +impl core::ops::Receiver for Wrapper { + type Target = T; +} + +impl Wrapper { + pub fn f(self) -> i32 { 5 } + pub fn g(&self) -> i32 { 6 } + pub fn h(&mut self) -> i32 { 7 } + pub fn i(self: *const Self) -> i32 { 8 } +} + +fn main() { + assert_eq!(Wrapper(A).f(), 1); + //~^ ERROR: multiple applicable items in scope + assert_eq!(Wrapper(A).g(), 2); + //~^ ERROR: multiple applicable items in scope + assert_eq!(Wrapper(A).h(), 3); + //~^ ERROR: multiple applicable items in scope + let a = Wrapper(A); + let a_ptr = &a as *const Wrapper; + assert_eq!(a_ptr.i(), 4); + //~^ ERROR: multiple applicable items in scope + assert_eq!(Wrapper(B).f(), 9); + //~^ ERROR: multiple applicable items in scope + assert_eq!(Wrapper(C).f(), 10); + //~^ ERROR: multiple applicable items in scope + assert_eq!(Wrapper(C).g(), 11); + //~^ ERROR: multiple applicable items in scope +} diff --git a/tests/ui/self/arbitrary_self_types_unshadowing_ptrs.stderr b/tests/ui/self/arbitrary_self_types_unshadowing_ptrs.stderr new file mode 100644 index 0000000000000..6d453aed0f06d --- /dev/null +++ b/tests/ui/self/arbitrary_self_types_unshadowing_ptrs.stderr @@ -0,0 +1,122 @@ +error[E0034]: multiple applicable items in scope + --> $DIR/arbitrary_self_types_unshadowing_ptrs.rs:45:27 + | +LL | assert_eq!(Wrapper(A).f(), 1); + | ^ multiple `f` found + | +note: candidate #1 is defined in an impl for the type `A` + --> $DIR/arbitrary_self_types_unshadowing_ptrs.rs:9:5 + | +LL | pub fn f(self: Wrapper) -> i32 { 1 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: candidate #2 is defined in an impl for the type `Wrapper` + --> $DIR/arbitrary_self_types_unshadowing_ptrs.rs:38:5 + | +LL | pub fn f(self) -> i32 { 5 } + | ^^^^^^^^^^^^^^^^^^^^^ + +error[E0034]: multiple applicable items in scope + --> $DIR/arbitrary_self_types_unshadowing_ptrs.rs:47:27 + | +LL | assert_eq!(Wrapper(A).g(), 2); + | ^ multiple `g` found + | +note: candidate #1 is defined in an impl for the type `A` + --> $DIR/arbitrary_self_types_unshadowing_ptrs.rs:10:5 + | +LL | pub fn g(self: &Wrapper) -> i32 { 2 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: candidate #2 is defined in an impl for the type `Wrapper` + --> $DIR/arbitrary_self_types_unshadowing_ptrs.rs:39:5 + | +LL | pub fn g(&self) -> i32 { 6 } + | ^^^^^^^^^^^^^^^^^^^^^^ + +error[E0034]: multiple applicable items in scope + --> $DIR/arbitrary_self_types_unshadowing_ptrs.rs:49:27 + | +LL | assert_eq!(Wrapper(A).h(), 3); + | ^ multiple `h` found + | +note: candidate #1 is defined in an impl for the type `A` + --> $DIR/arbitrary_self_types_unshadowing_ptrs.rs:11:5 + | +LL | pub fn h(self: &mut Wrapper) -> i32 { 3 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: candidate #2 is defined in an impl for the type `Wrapper` + --> $DIR/arbitrary_self_types_unshadowing_ptrs.rs:40:5 + | +LL | pub fn h(&mut self) -> i32 { 7 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0034]: multiple applicable items in scope + --> $DIR/arbitrary_self_types_unshadowing_ptrs.rs:53:22 + | +LL | assert_eq!(a_ptr.i(), 4); + | ^ multiple `i` found + | +note: candidate #1 is defined in an impl for the type `A` + --> $DIR/arbitrary_self_types_unshadowing_ptrs.rs:12:5 + | +LL | pub fn i(self: *const Wrapper) -> i32 { 4 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: candidate #2 is defined in an impl for the type `Wrapper` + --> $DIR/arbitrary_self_types_unshadowing_ptrs.rs:41:5 + | +LL | pub fn i(self: *const Self) -> i32 { 8 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0034]: multiple applicable items in scope + --> $DIR/arbitrary_self_types_unshadowing_ptrs.rs:55:27 + | +LL | assert_eq!(Wrapper(B).f(), 9); + | ^ multiple `f` found + | +note: candidate #1 is defined in an impl for the type `B` + --> $DIR/arbitrary_self_types_unshadowing_ptrs.rs:19:5 + | +LL | pub fn f(self: &Wrapper) -> i32 { 9 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: candidate #2 is defined in an impl for the type `Wrapper` + --> $DIR/arbitrary_self_types_unshadowing_ptrs.rs:38:5 + | +LL | pub fn f(self) -> i32 { 5 } + | ^^^^^^^^^^^^^^^^^^^^^ + +error[E0034]: multiple applicable items in scope + --> $DIR/arbitrary_self_types_unshadowing_ptrs.rs:57:27 + | +LL | assert_eq!(Wrapper(C).f(), 10); + | ^ multiple `f` found + | +note: candidate #1 is defined in an impl for the type `C` + --> $DIR/arbitrary_self_types_unshadowing_ptrs.rs:27:5 + | +LL | pub fn f(self: &mut Wrapper) -> i32 { 10 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: candidate #2 is defined in an impl for the type `Wrapper` + --> $DIR/arbitrary_self_types_unshadowing_ptrs.rs:38:5 + | +LL | pub fn f(self) -> i32 { 5 } + | ^^^^^^^^^^^^^^^^^^^^^ + +error[E0034]: multiple applicable items in scope + --> $DIR/arbitrary_self_types_unshadowing_ptrs.rs:59:27 + | +LL | assert_eq!(Wrapper(C).g(), 11); + | ^ multiple `g` found + | +note: candidate #1 is defined in an impl for the type `C` + --> $DIR/arbitrary_self_types_unshadowing_ptrs.rs:28:5 + | +LL | pub fn g(self: &mut Wrapper) -> i32 { 11 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: candidate #2 is defined in an impl for the type `Wrapper` + --> $DIR/arbitrary_self_types_unshadowing_ptrs.rs:39:5 + | +LL | pub fn g(&self) -> i32 { 6 } + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 7 previous errors + +For more information about this error, try `rustc --explain E0034`. diff --git a/tests/ui/self/conflicting_inner.rs b/tests/ui/self/conflicting_inner.rs new file mode 100644 index 0000000000000..1a7037dce7393 --- /dev/null +++ b/tests/ui/self/conflicting_inner.rs @@ -0,0 +1,38 @@ +//@ run-pass +//@ revisions: default feature +#![cfg_attr(feature, feature(arbitrary_self_types))] + +// This test aims to be like the IndexVec within rustc, and conflicts +// over its into_iter(). + +#[allow(dead_code)] +trait Foo { + fn foo(self) -> usize; +} + +struct IndexVec(T); + +impl std::ops::Deref for IndexVec { + type Target = T; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl<'a, T> Foo for &'a IndexVec { + fn foo(self) -> usize { + 2 + } +} + +impl IndexVec { + fn foo(self) -> usize { + 1 + } +} + +fn main() { + let ivec = IndexVec(0usize); + assert_eq!(ivec.foo(), 1); +} diff --git a/tests/ui/self/conflicting_inner2.rs b/tests/ui/self/conflicting_inner2.rs new file mode 100644 index 0000000000000..e6a6b5ef793e3 --- /dev/null +++ b/tests/ui/self/conflicting_inner2.rs @@ -0,0 +1,63 @@ +//@ run-pass +//@ revisions: default feature +#![cfg_attr(feature, feature(arbitrary_self_types))] + +use std::pin::Pin; +use std::ops::DerefMut; +use std::marker::Unpin; + +struct TryChunks; + +impl TryChunks { + #[allow(dead_code)] + fn take(self: std::pin::Pin<&mut Self>) -> usize { + 1 + } +} + +#[allow(dead_code)] +trait Stream { + fn poll_next(self: std::pin::Pin<&mut Self>); +} + +#[allow(dead_code)] +trait StreamExt: Stream { + #[allow(dead_code)] + fn take(self) -> usize where Self: Sized + { + 2 + } +} + +impl StreamExt for T where T: Stream {} + +impl Stream for TryChunks { + fn poll_next(self: std::pin::Pin<&mut Self>) { + assert_eq!(self.take(), 1); + } +} + +#[allow(dead_code)] +impl Stream for &mut S { + #[allow(dead_code)] + fn poll_next(mut self: Pin<&mut Self>) { + S::poll_next(Pin::new(&mut **self)) + } +} + +#[allow(dead_code)] +impl

Stream for Pin

+where + P: DerefMut + Unpin, + P::Target: Stream, +{ + #[allow(dead_code)] + fn poll_next(self: Pin<&mut Self>) { + self.get_mut().as_mut().poll_next() + } +} + +fn main() { + let mut item = Box::pin(TryChunks); + item.as_mut().poll_next(); +} From 337af8a37014a476d8deb081c3f209c7d56d5171 Mon Sep 17 00:00:00 2001 From: Adrian Taylor Date: Thu, 21 Dec 2023 16:19:40 +0000 Subject: [PATCH 12/20] Arbitrary self types v2: generics test. There's some discussion on the RFC about whether generic receivers should be allowed, but in the end the conclusion was that they should be blocked (at least for some definition of 'generic'). This blocking landed in an earlier PR; this commit adds additional tests to ensure the interaction with the rest of the Arbitrary Self Types v2 feature is as expected. This test may be a little duplicative but it seems better to land it than not. --- .../arbitrary_self_types_generic_receiver.rs | 50 +++++++++++++++++++ ...bitrary_self_types_generic_receiver.stderr | 48 ++++++++++++++++++ 2 files changed, 98 insertions(+) create mode 100644 tests/ui/self/arbitrary_self_types_generic_receiver.rs create mode 100644 tests/ui/self/arbitrary_self_types_generic_receiver.stderr diff --git a/tests/ui/self/arbitrary_self_types_generic_receiver.rs b/tests/ui/self/arbitrary_self_types_generic_receiver.rs new file mode 100644 index 0000000000000..0739fb778b605 --- /dev/null +++ b/tests/ui/self/arbitrary_self_types_generic_receiver.rs @@ -0,0 +1,50 @@ +#![feature(arbitrary_self_types)] + +struct PtrA(T); + +impl core::ops::Receiver for PtrA { + type Target = T; +} + +struct PtrB(T); + +trait SomePtr: core::ops::Receiver::SomeTarget> { + type SomeTarget; +} + +impl SomePtr for PtrB { + type SomeTarget = T; +} + +impl core::ops::Receiver for PtrB { + type Target = T; +} + +struct Content; + +impl Content { + fn a>(self: &R) {} + //~^ ERROR invalid generic + fn b>(self: &mut R) {} + //~^ ERROR invalid generic + fn c>(self: R) {} + //~^ ERROR invalid generic + fn d>(self: R) {} + //~^ ERROR invalid generic + fn e(self: impl SomePtr) {} + //~^ ERROR invalid generic +} + +fn main() { + PtrA(Content).a(); + PtrA(Content).b(); + PtrA(Content).c(); + std::rc::Rc::new(Content).a(); + std::rc::Rc::new(Content).b(); + std::rc::Rc::new(Content).c(); + PtrB(Content).a(); + PtrB(Content).b(); + PtrB(Content).c(); + PtrB(Content).d(); + PtrB(Content).e(); +} diff --git a/tests/ui/self/arbitrary_self_types_generic_receiver.stderr b/tests/ui/self/arbitrary_self_types_generic_receiver.stderr new file mode 100644 index 0000000000000..788c55ea2f1c3 --- /dev/null +++ b/tests/ui/self/arbitrary_self_types_generic_receiver.stderr @@ -0,0 +1,48 @@ +error[E0801]: invalid generic `self` parameter type: `&R` + --> $DIR/arbitrary_self_types_generic_receiver.rs:26:53 + | +LL | fn a>(self: &R) {} + | ^^ + | + = note: type of `self` must not be a method generic parameter type + = help: use a concrete type such as `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + +error[E0801]: invalid generic `self` parameter type: `&mut R` + --> $DIR/arbitrary_self_types_generic_receiver.rs:28:53 + | +LL | fn b>(self: &mut R) {} + | ^^^^^^ + | + = note: type of `self` must not be a method generic parameter type + = help: use a concrete type such as `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + +error[E0801]: invalid generic `self` parameter type: `R` + --> $DIR/arbitrary_self_types_generic_receiver.rs:30:53 + | +LL | fn c>(self: R) {} + | ^ + | + = note: type of `self` must not be a method generic parameter type + = help: use a concrete type such as `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + +error[E0801]: invalid generic `self` parameter type: `R` + --> $DIR/arbitrary_self_types_generic_receiver.rs:32:45 + | +LL | fn d>(self: R) {} + | ^ + | + = note: type of `self` must not be a method generic parameter type + = help: use a concrete type such as `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + +error[E0801]: invalid generic `self` parameter type: `impl SomePtr` + --> $DIR/arbitrary_self_types_generic_receiver.rs:34:16 + | +LL | fn e(self: impl SomePtr) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: type of `self` must not be a method generic parameter type + = help: use a concrete type such as `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0801`. From f39e813c0fa227d8e885011024a5daef943178e0 Mon Sep 17 00:00:00 2001 From: Steven Grady Date: Wed, 11 Dec 2024 16:35:43 -0800 Subject: [PATCH 13/20] Bump Fuchsia --- src/ci/docker/host-x86_64/x86_64-fuchsia/build-fuchsia.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ci/docker/host-x86_64/x86_64-fuchsia/build-fuchsia.sh b/src/ci/docker/host-x86_64/x86_64-fuchsia/build-fuchsia.sh index 969389f92f7d7..7027c93857c3c 100755 --- a/src/ci/docker/host-x86_64/x86_64-fuchsia/build-fuchsia.sh +++ b/src/ci/docker/host-x86_64/x86_64-fuchsia/build-fuchsia.sh @@ -35,7 +35,7 @@ PICK_REFS=() # commit hash of fuchsia.git and some other repos in the "monorepo" checkout, in # addition to versions of prebuilts. It should be bumped regularly by the # Fuchsia team – we aim for every 1-2 months. -INTEGRATION_SHA=9f632bb7446d5a6af2998f1a0ebdb4b8ea2f4511 +INTEGRATION_SHA=bb38af4e3d45e490531b71fc52a460003141d032 checkout=fuchsia jiri=.jiri_root/bin/jiri From f7c6a2cf11eb075ea56b54c48756ee55d0b2aeb1 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Thu, 12 Dec 2024 20:54:33 +1100 Subject: [PATCH 14/20] Fix our `llvm::Bool` typedef to be signed, to match `LLVMBool` In the LLVM-C API, boolean values are passed as `typedef int LLVMBool`, but our Rust-side typedef was using `c_uint` instead. Signed and unsigned integers have the same ABI on most platforms, but that isn't universally true, so we should prefer to be consistent with LLVM. --- compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 8b4523bd252b3..d62632d143168 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -17,7 +17,9 @@ use super::debuginfo::{ DebugEmissionKind, DebugNameTableKind, }; -pub type Bool = c_uint; +/// In the LLVM-C API, boolean values are passed as `typedef int LLVMBool`, +/// which has a different ABI from Rust or C++ `bool`. +pub type Bool = c_int; pub const True: Bool = 1 as Bool; pub const False: Bool = 0 as Bool; From 50fac072815e576ca955b0f53fb52236d2f671f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Thu, 12 Dec 2024 19:23:38 +0800 Subject: [PATCH 15/20] Revert "Rollup merge of #134123 - Zalathar:json-output, r=jieyouxu,clubby789" This reverts commit c42c248009747366e646a3ad1ce6e8f815ea7db2, reversing changes made to 0f1b827881d20ba08f72d692ccd3ff97a0e25851. --- src/bootstrap/src/core/build_steps/compile.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index 93f8091299fa4..4419b11ac1971 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -2261,7 +2261,7 @@ pub fn stream_cargo( Ok(msg) => { if builder.config.json_output { // Forward JSON to stdout. - println!("{line}"); + eprintln!("{line}"); } cb(msg) } From 3c3512cf8ceea2e0aed9c2bab32b3b8b0ed68c1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Thu, 12 Dec 2024 19:24:01 +0800 Subject: [PATCH 16/20] Revert "Rollup merge of #134040 - clubby789:bootstrap-eprintln, r=jieyouxu" This reverts commit b282774aaf0aa05b4a9855d973b67e7e424c2136, reversing changes made to e0f3db0056288a06b1ae36cdd70741a4e0b3584a. --- src/bootstrap/src/bin/main.rs | 20 +++---- src/bootstrap/src/bin/rustc.rs | 2 +- src/bootstrap/src/core/build_steps/check.rs | 2 +- src/bootstrap/src/core/build_steps/compile.rs | 10 ++-- src/bootstrap/src/core/build_steps/dist.rs | 2 +- src/bootstrap/src/core/build_steps/format.rs | 6 +- src/bootstrap/src/core/build_steps/setup.rs | 46 +++++++------- src/bootstrap/src/core/build_steps/suggest.rs | 2 +- src/bootstrap/src/core/build_steps/test.rs | 6 +- src/bootstrap/src/core/builder/cargo.rs | 2 +- src/bootstrap/src/core/builder/mod.rs | 14 ++--- src/bootstrap/src/core/config/config.rs | 60 +++++++++---------- src/bootstrap/src/core/config/flags.rs | 4 +- src/bootstrap/src/core/download.rs | 26 ++++---- src/bootstrap/src/core/sanity.rs | 4 +- src/bootstrap/src/lib.rs | 28 ++++----- src/bootstrap/src/utils/cc_detect.rs | 10 ++-- src/bootstrap/src/utils/helpers.rs | 6 +- src/bootstrap/src/utils/metrics.rs | 2 +- src/bootstrap/src/utils/render_tests.rs | 50 ++++++++-------- src/bootstrap/src/utils/tarball.rs | 2 +- src/tools/compiletest/src/compute_diff.rs | 2 +- src/tools/compiletest/src/debuggers.rs | 6 +- src/tools/compiletest/src/lib.rs | 10 ++-- src/tools/compiletest/src/runtest.rs | 52 ++++++++-------- .../compiletest/src/runtest/codegen_units.rs | 22 +++---- .../compiletest/src/runtest/debuginfo.rs | 10 ++-- .../compiletest/src/runtest/incremental.rs | 2 +- src/tools/compiletest/src/runtest/mir_opt.rs | 2 +- .../compiletest/src/runtest/rustdoc_json.rs | 2 +- src/tools/compiletest/src/runtest/ui.rs | 4 +- src/tools/compiletest/src/util.rs | 2 +- 32 files changed, 207 insertions(+), 211 deletions(-) diff --git a/src/bootstrap/src/bin/main.rs b/src/bootstrap/src/bin/main.rs index 74dfe2e7ec80f..ee813de1c9e26 100644 --- a/src/bootstrap/src/bin/main.rs +++ b/src/bootstrap/src/bin/main.rs @@ -48,9 +48,9 @@ fn main() { err => { drop(err); if let Ok(pid) = pid { - eprintln!("WARNING: build directory locked by process {pid}, waiting for lock"); + println!("WARNING: build directory locked by process {pid}, waiting for lock"); } else { - eprintln!("WARNING: build directory locked, waiting for lock"); + println!("WARNING: build directory locked, waiting for lock"); } let mut lock = t!(build_lock.write()); t!(lock.write(process::id().to_string().as_ref())); @@ -70,13 +70,13 @@ fn main() { // changelog warning, not the `x.py setup` message. let suggest_setup = config.config.is_none() && !matches!(config.cmd, Subcommand::Setup { .. }); if suggest_setup { - eprintln!("WARNING: you have not made a `config.toml`"); - eprintln!( + println!("WARNING: you have not made a `config.toml`"); + println!( "HELP: consider running `./x.py setup` or copying `config.example.toml` by running \ `cp config.example.toml config.toml`" ); } else if let Some(suggestion) = &changelog_suggestion { - eprintln!("{suggestion}"); + println!("{suggestion}"); } let pre_commit = config.src.join(".git").join("hooks").join("pre-commit"); @@ -86,13 +86,13 @@ fn main() { Build::new(config).build(); if suggest_setup { - eprintln!("WARNING: you have not made a `config.toml`"); - eprintln!( + println!("WARNING: you have not made a `config.toml`"); + println!( "HELP: consider running `./x.py setup` or copying `config.example.toml` by running \ `cp config.example.toml config.toml`" ); } else if let Some(suggestion) = &changelog_suggestion { - eprintln!("{suggestion}"); + println!("{suggestion}"); } // Give a warning if the pre-commit script is in pre-commit and not pre-push. @@ -102,14 +102,14 @@ fn main() { if fs::read_to_string(pre_commit).is_ok_and(|contents| { contents.contains("https://github.com/rust-lang/rust/issues/77620#issuecomment-705144570") }) { - eprintln!( + println!( "WARNING: You have the pre-push script installed to .git/hooks/pre-commit. \ Consider moving it to .git/hooks/pre-push instead, which runs less often." ); } if suggest_setup || changelog_suggestion.is_some() { - eprintln!("NOTE: this message was printed twice to make it more likely to be seen"); + println!("NOTE: this message was printed twice to make it more likely to be seen"); } if dump_bootstrap_shims { diff --git a/src/bootstrap/src/bin/rustc.rs b/src/bootstrap/src/bin/rustc.rs index e57ed488f973e..88595ff7e5198 100644 --- a/src/bootstrap/src/bin/rustc.rs +++ b/src/bootstrap/src/bin/rustc.rs @@ -306,7 +306,7 @@ fn main() { // should run on success, after this block. } if verbose > 0 { - eprintln!("\nDid not run successfully: {status}\n{cmd:?}\n-------------"); + println!("\nDid not run successfully: {status}\n{cmd:?}\n-------------"); } if let Some(mut on_fail) = on_fail { diff --git a/src/bootstrap/src/core/build_steps/check.rs b/src/bootstrap/src/core/build_steps/check.rs index 2af2e83db8f76..d46c0ab7fefcf 100644 --- a/src/bootstrap/src/core/build_steps/check.rs +++ b/src/bootstrap/src/core/build_steps/check.rs @@ -287,7 +287,7 @@ impl Step for CodegenBackend { fn run(self, builder: &Builder<'_>) { // FIXME: remove once https://github.com/rust-lang/rust/issues/112393 is resolved if builder.build.config.vendor && self.backend == "gcc" { - eprintln!("Skipping checking of `rustc_codegen_gcc` with vendoring enabled."); + println!("Skipping checking of `rustc_codegen_gcc` with vendoring enabled."); return; } diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index 4419b11ac1971..0cacd6e4f37ac 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -1611,7 +1611,7 @@ impl Step for Sysroot { let sysroot = sysroot_dir(compiler.stage); builder - .verbose(|| eprintln!("Removing sysroot {} to avoid caching bugs", sysroot.display())); + .verbose(|| println!("Removing sysroot {} to avoid caching bugs", sysroot.display())); let _ = fs::remove_dir_all(&sysroot); t!(fs::create_dir_all(&sysroot)); @@ -1681,7 +1681,7 @@ impl Step for Sysroot { return true; } if !filtered_files.iter().all(|f| f != path.file_name().unwrap()) { - builder.verbose_than(1, || eprintln!("ignoring {}", path.display())); + builder.verbose_than(1, || println!("ignoring {}", path.display())); false } else { true @@ -2240,7 +2240,7 @@ pub fn stream_cargo( cargo.arg(arg); } - builder.verbose(|| eprintln!("running: {cargo:?}")); + builder.verbose(|| println!("running: {cargo:?}")); if builder.config.dry_run() { return true; @@ -2261,12 +2261,12 @@ pub fn stream_cargo( Ok(msg) => { if builder.config.json_output { // Forward JSON to stdout. - eprintln!("{line}"); + println!("{line}"); } cb(msg) } // If this was informational, just print it out and continue - Err(_) => eprintln!("{line}"), + Err(_) => println!("{line}"), } } diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 57fce206f954b..0c739115165ec 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -2080,7 +2080,7 @@ fn maybe_install_llvm( { let mut cmd = command(llvm_config); cmd.arg("--libfiles"); - builder.verbose(|| eprintln!("running {cmd:?}")); + builder.verbose(|| println!("running {cmd:?}")); let files = cmd.run_capture_stdout(builder).stdout(); let build_llvm_out = &builder.llvm_out(builder.config.build); let target_llvm_out = &builder.llvm_out(target); diff --git a/src/bootstrap/src/core/build_steps/format.rs b/src/bootstrap/src/core/build_steps/format.rs index d32e06d8748ac..29a96f7767281 100644 --- a/src/bootstrap/src/core/build_steps/format.rs +++ b/src/bootstrap/src/core/build_steps/format.rs @@ -107,10 +107,10 @@ fn print_paths(verb: &str, adjective: Option<&str>, paths: &[String]) { if let Some(adjective) = adjective { format!("{adjective} ") } else { String::new() }; if len <= 10 { for path in paths { - eprintln!("fmt: {verb} {adjective}file {path}"); + println!("fmt: {verb} {adjective}file {path}"); } } else { - eprintln!("fmt: {verb} {len} {adjective}files"); + println!("fmt: {verb} {len} {adjective}files"); } } @@ -199,7 +199,7 @@ pub fn format(build: &Builder<'_>, check: bool, all: bool, paths: &[PathBuf]) { match get_modified_rs_files(build) { Ok(Some(files)) => { if files.is_empty() { - eprintln!("fmt info: No modified files detected for formatting."); + println!("fmt info: No modified files detected for formatting."); return; } diff --git a/src/bootstrap/src/core/build_steps/setup.rs b/src/bootstrap/src/core/build_steps/setup.rs index 175e9982cc14e..7ed01f25c94b2 100644 --- a/src/bootstrap/src/core/build_steps/setup.rs +++ b/src/bootstrap/src/core/build_steps/setup.rs @@ -134,7 +134,7 @@ impl Step for Profile { t!(fs::remove_file(path)); } _ => { - eprintln!("Exiting."); + println!("Exiting."); crate::exit!(1); } } @@ -184,15 +184,15 @@ pub fn setup(config: &Config, profile: Profile) { Profile::Dist => &["dist", "build"], }; - eprintln!(); + println!(); - eprintln!("To get started, try one of the following commands:"); + println!("To get started, try one of the following commands:"); for cmd in suggestions { - eprintln!("- `x.py {cmd}`"); + println!("- `x.py {cmd}`"); } if profile != Profile::Dist { - eprintln!( + println!( "For more suggestions, see https://rustc-dev-guide.rust-lang.org/building/suggested.html" ); } @@ -224,7 +224,7 @@ fn setup_config_toml(path: &PathBuf, profile: Profile, config: &Config) { t!(fs::write(path, settings)); let include_path = profile.include_path(&config.src); - eprintln!("`x.py` will now use the configuration at {}", include_path.display()); + println!("`x.py` will now use the configuration at {}", include_path.display()); } /// Creates a toolchain link for stage1 using `rustup` @@ -256,7 +256,7 @@ impl Step for Link { } if !rustup_installed(builder) { - eprintln!("WARNING: `rustup` is not installed; Skipping `stage1` toolchain linking."); + println!("WARNING: `rustup` is not installed; Skipping `stage1` toolchain linking."); return; } @@ -296,7 +296,7 @@ fn attempt_toolchain_link(builder: &Builder<'_>, stage_path: &str) { } if try_link_toolchain(builder, stage_path) { - eprintln!( + println!( "Added `stage1` rustup toolchain; try `cargo +stage1 build` on a separate rust project to run a newly-built toolchain" ); } else { @@ -321,14 +321,14 @@ fn toolchain_is_linked(builder: &Builder<'_>) -> bool { return false; } // The toolchain has already been linked. - eprintln!( + println!( "`stage1` toolchain already linked; not attempting to link `stage1` toolchain" ); } None => { // In this case, we don't know if the `stage1` toolchain has been linked; // but `rustup` failed, so let's not go any further. - eprintln!( + println!( "`rustup` failed to list current toolchains; not attempting to link `stage1` toolchain" ); } @@ -389,12 +389,12 @@ pub fn interactive_path() -> io::Result { input.parse() } - eprintln!("Welcome to the Rust project! What do you want to do with x.py?"); + println!("Welcome to the Rust project! What do you want to do with x.py?"); for ((letter, _), profile) in abbrev_all() { - eprintln!("{}) {}: {}", letter, profile, profile.purpose()); + println!("{}) {}: {}", letter, profile, profile.purpose()); } let template = loop { - eprint!( + print!( "Please choose one ({}): ", abbrev_all().map(|((l, _), _)| l).collect::>().join("/") ); @@ -428,7 +428,7 @@ enum PromptResult { fn prompt_user(prompt: &str) -> io::Result> { let mut input = String::new(); loop { - eprint!("{prompt} "); + print!("{prompt} "); io::stdout().flush()?; input.clear(); io::stdin().read_line(&mut input)?; @@ -490,7 +490,7 @@ fn install_git_hook_maybe(builder: &Builder<'_>, config: &Config) -> io::Result< return Ok(()); } - eprintln!( + println!( "\nRust's CI will automatically fail if it doesn't pass `tidy`, the internal tool for ensuring code quality. If you'd like, x.py can install a git hook for you that will automatically run `test tidy` before pushing your code to ensure your code is up to par. If you decide later that this behavior is @@ -498,7 +498,7 @@ undesirable, simply delete the `pre-push` file from .git/hooks." ); if prompt_user("Would you like to install the git hook?: [y/N]")? != Some(PromptResult::Yes) { - eprintln!("Ok, skipping installation!"); + println!("Ok, skipping installation!"); return Ok(()); } if !hooks_dir.exists() { @@ -515,7 +515,7 @@ undesirable, simply delete the `pre-push` file from .git/hooks." ); return Err(e); } - Ok(_) => eprintln!("Linked `src/etc/pre-push.sh` to `.git/hooks/pre-push`"), + Ok(_) => println!("Linked `src/etc/pre-push.sh` to `.git/hooks/pre-push`"), }; Ok(()) } @@ -541,7 +541,7 @@ Select which editor you would like to set up [default: None]: "; let mut input = String::new(); loop { - eprint!("{}", prompt_str); + print!("{}", prompt_str); io::stdout().flush()?; input.clear(); io::stdin().read_line(&mut input)?; @@ -656,7 +656,7 @@ impl Step for Editor { if let Some(editor_kind) = editor_kind { while !t!(create_editor_settings_maybe(config, editor_kind.clone())) {} } else { - eprintln!("Ok, skipping editor setup!"); + println!("Ok, skipping editor setup!"); } } Err(e) => eprintln!("Could not determine the editor: {e}"), @@ -689,7 +689,7 @@ fn create_editor_settings_maybe(config: &Config, editor: EditorKind) -> io::Resu mismatched_settings = Some(false); } } - eprintln!( + println!( "\nx.py can automatically install the recommended `{settings_filename}` file for rustc development" ); @@ -708,7 +708,7 @@ fn create_editor_settings_maybe(config: &Config, editor: EditorKind) -> io::Resu Some(PromptResult::Yes) => true, Some(PromptResult::Print) => false, _ => { - eprintln!("Ok, skipping settings!"); + println!("Ok, skipping settings!"); return Ok(true); } }; @@ -735,9 +735,9 @@ fn create_editor_settings_maybe(config: &Config, editor: EditorKind) -> io::Resu _ => "Created", }; fs::write(&settings_path, editor.settings_template())?; - eprintln!("{verb} `{}`", settings_filename); + println!("{verb} `{}`", settings_filename); } else { - eprintln!("\n{}", editor.settings_template()); + println!("\n{}", editor.settings_template()); } Ok(should_create) } diff --git a/src/bootstrap/src/core/build_steps/suggest.rs b/src/bootstrap/src/core/build_steps/suggest.rs index 7b2d9fff8f5f0..ba9b1b2fc3317 100644 --- a/src/bootstrap/src/core/build_steps/suggest.rs +++ b/src/bootstrap/src/core/build_steps/suggest.rs @@ -66,6 +66,6 @@ pub fn suggest(builder: &Builder<'_>, run: bool) { build.build(); } } else { - eprintln!("HELP: consider using the `--run` flag to automatically run suggested tests"); + println!("HELP: consider using the `--run` flag to automatically run suggested tests"); } } diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 380626952b25f..30fdea7e19e51 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -471,11 +471,11 @@ impl Miri { // We re-use the `cargo` from above. cargo.arg("--print-sysroot"); - builder.verbose(|| eprintln!("running: {cargo:?}")); + builder.verbose(|| println!("running: {cargo:?}")); let stdout = cargo.run_capture_stdout(builder).stdout(); // Output is "\n". let sysroot = stdout.trim_end(); - builder.verbose(|| eprintln!("`cargo miri setup --print-sysroot` said: {sysroot:?}")); + builder.verbose(|| println!("`cargo miri setup --print-sysroot` said: {sysroot:?}")); PathBuf::from(sysroot) } } @@ -2488,7 +2488,7 @@ fn markdown_test(builder: &Builder<'_>, compiler: Compiler, markdown: &Path) -> } } - builder.verbose(|| eprintln!("doc tests for: {}", markdown.display())); + builder.verbose(|| println!("doc tests for: {}", markdown.display())); let mut cmd = builder.rustdoc_cmd(compiler); builder.add_rust_test_threads(&mut cmd); // allow for unstable options such as new editions diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs index 38abca8b8da17..77f6edaabb248 100644 --- a/src/bootstrap/src/core/builder/cargo.rs +++ b/src/bootstrap/src/core/builder/cargo.rs @@ -523,7 +523,7 @@ impl Builder<'_> { let sysroot_str = sysroot.as_os_str().to_str().expect("sysroot should be UTF-8"); if self.is_verbose() && !matches!(self.config.dry_run, DryRun::SelfCheck) { - eprintln!("using sysroot {sysroot_str}"); + println!("using sysroot {sysroot_str}"); } let mut rustflags = Rustflags::new(target); diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs index ffe3e053e7247..026c26479d355 100644 --- a/src/bootstrap/src/core/builder/mod.rs +++ b/src/bootstrap/src/core/builder/mod.rs @@ -392,14 +392,14 @@ impl StepDescription { fn is_excluded(&self, builder: &Builder<'_>, pathset: &PathSet) -> bool { if builder.config.skip.iter().any(|e| pathset.has(e, builder.kind)) { if !matches!(builder.config.dry_run, DryRun::SelfCheck) { - eprintln!("Skipping {pathset:?} because it is excluded"); + println!("Skipping {pathset:?} because it is excluded"); } return true; } if !builder.config.skip.is_empty() && !matches!(builder.config.dry_run, DryRun::SelfCheck) { builder.verbose(|| { - eprintln!( + println!( "{:?} not skipped for {:?} -- not in {:?}", pathset, self.name, builder.config.skip ) @@ -1437,11 +1437,11 @@ impl<'a> Builder<'a> { panic!("{}", out); } if let Some(out) = self.cache.get(&step) { - self.verbose_than(1, || eprintln!("{}c {:?}", " ".repeat(stack.len()), step)); + self.verbose_than(1, || println!("{}c {:?}", " ".repeat(stack.len()), step)); return out; } - self.verbose_than(1, || eprintln!("{}> {:?}", " ".repeat(stack.len()), step)); + self.verbose_than(1, || println!("{}> {:?}", " ".repeat(stack.len()), step)); stack.push(Box::new(step.clone())); } @@ -1462,7 +1462,7 @@ impl<'a> Builder<'a> { let step_string = format!("{step:?}"); let brace_index = step_string.find('{').unwrap_or(0); let type_string = type_name::(); - eprintln!( + println!( "[TIMING] {} {} -- {}.{:03}", &type_string.strip_prefix("bootstrap::").unwrap_or(type_string), &step_string[brace_index..], @@ -1479,9 +1479,7 @@ impl<'a> Builder<'a> { let cur_step = stack.pop().expect("step stack empty"); assert_eq!(cur_step.downcast_ref(), Some(&step)); } - self.verbose_than(1, || { - eprintln!("{}< {:?}", " ".repeat(self.stack.borrow().len()), step) - }); + self.verbose_than(1, || println!("{}< {:?}", " ".repeat(self.stack.borrow().len()), step)); self.cache.put(step, out.clone()); out } diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 002b990bb5280..c6800aedca971 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -1299,7 +1299,7 @@ impl Config { .map(|change_id| change_id.inner.map(crate::find_recent_config_change_ids)) { if !changes.is_empty() { - eprintln!( + println!( "WARNING: There have been changes to x.py since you last updated:\n{}", crate::human_readable_changes(&changes) ); @@ -1565,7 +1565,7 @@ impl Config { } if cargo_clippy.is_some() && rustc.is_none() { - eprintln!( + println!( "WARNING: Using `build.cargo-clippy` without `build.rustc` usually fails due to toolchain conflict." ); } @@ -1852,7 +1852,7 @@ impl Config { // FIXME: Remove this option at the end of 2024. if parallel_compiler.is_some() { - eprintln!( + println!( "WARNING: The `rust.parallel-compiler` option is deprecated and does nothing. The parallel compiler (with one thread) is now the default" ); } @@ -1884,7 +1884,7 @@ impl Config { if available_backends.contains(&backend) { panic!("Invalid value '{s}' for 'rust.codegen-backends'. Instead, please use '{backend}'."); } else { - eprintln!("HELP: '{s}' for 'rust.codegen-backends' might fail. \ + println!("HELP: '{s}' for 'rust.codegen-backends' might fail. \ Codegen backends are mostly defined without the '{CODEGEN_BACKEND_PREFIX}' prefix. \ In this case, it would be referred to as '{backend}'."); } @@ -1913,7 +1913,7 @@ impl Config { // tests may fail due to using a different channel than the one used by the compiler during tests. if let Some(commit) = &config.download_rustc_commit { if is_user_configured_rust_channel { - eprintln!( + println!( "WARNING: `rust.download-rustc` is enabled. The `rust.channel` option will be overridden by the CI rustc's channel." ); @@ -2003,10 +2003,10 @@ impl Config { if config.llvm_from_ci { let warn = |option: &str| { - eprintln!( + println!( "WARNING: `{option}` will only be used on `compiler/rustc_llvm` build, not for the LLVM build." ); - eprintln!( + println!( "HELP: To use `{option}` for LLVM builds, set `download-ci-llvm` option to false." ); }; @@ -2025,12 +2025,12 @@ impl Config { // if they've chosen a different value. if libzstd.is_some() { - eprintln!( + println!( "WARNING: when using `download-ci-llvm`, the local `llvm.libzstd` option, \ like almost all `llvm.*` options, will be ignored and set by the LLVM CI \ artifacts builder config." ); - eprintln!( + println!( "HELP: To use `llvm.libzstd` for LLVM/LLD builds, set `download-ci-llvm` option to false." ); } @@ -2099,7 +2099,7 @@ impl Config { if available_backends.contains(&backend) { panic!("Invalid value '{s}' for 'target.{triple}.codegen-backends'. Instead, please use '{backend}'."); } else { - eprintln!("HELP: '{s}' for 'target.{triple}.codegen-backends' might fail. \ + println!("HELP: '{s}' for 'target.{triple}.codegen-backends' might fail. \ Codegen backends are mostly defined without the '{CODEGEN_BACKEND_PREFIX}' prefix. \ In this case, it would be referred to as '{backend}'."); } @@ -2315,7 +2315,7 @@ impl Config { if self.dry_run() { return Ok(()); } - self.verbose(|| eprintln!("running: {cmd:?}")); + self.verbose(|| println!("running: {cmd:?}")); build_helper::util::try_run(cmd, self.is_verbose()) } @@ -2490,7 +2490,7 @@ impl Config { // This happens when LLVM submodule is updated in CI, we should disable ci-rustc without an error // to not break CI. For non-CI environments, we should return an error. if CiEnv::is_ci() { - eprintln!("WARNING: LLVM submodule has changes, `download-rustc` will be disabled."); + println!("WARNING: LLVM submodule has changes, `download-rustc` will be disabled."); return None; } else { panic!("ERROR: LLVM submodule has changes, `download-rustc` can't be used."); @@ -2501,8 +2501,8 @@ impl Config { let ci_config_toml = match self.get_builder_toml("ci-rustc") { Ok(ci_config_toml) => ci_config_toml, Err(e) if e.to_string().contains("unknown field") => { - eprintln!("WARNING: CI rustc has some fields that are no longer supported in bootstrap; download-rustc will be disabled."); - eprintln!("HELP: Consider rebasing to a newer commit if available."); + println!("WARNING: CI rustc has some fields that are no longer supported in bootstrap; download-rustc will be disabled."); + println!("HELP: Consider rebasing to a newer commit if available."); return None; }, Err(e) => { @@ -2527,7 +2527,7 @@ impl Config { .is_some_and(|s| s == "1" || s == "true"); if disable_ci_rustc_if_incompatible && res.is_err() { - eprintln!("WARNING: download-rustc is disabled with `DISABLE_CI_RUSTC_IF_INCOMPATIBLE` env."); + println!("WARNING: download-rustc is disabled with `DISABLE_CI_RUSTC_IF_INCOMPATIBLE` env."); return None; } @@ -2712,7 +2712,7 @@ impl Config { return; } - eprintln!("Updating submodule {relative_path}"); + println!("Updating submodule {relative_path}"); self.check_run( helpers::git(Some(&self.src)) .run_always() @@ -2835,7 +2835,7 @@ impl Config { Some(StringOrBool::Bool(true)) => false, Some(StringOrBool::String(s)) if s == "if-unchanged" => { if !self.rust_info.is_managed_git_subrepository() { - eprintln!( + println!( "ERROR: `download-rustc=if-unchanged` is only compatible with Git managed sources." ); crate::exit!(1); @@ -2868,10 +2868,10 @@ impl Config { if if_unchanged { return None; } - eprintln!("ERROR: could not find commit hash for downloading rustc"); - eprintln!("HELP: maybe your repository history is too shallow?"); - eprintln!("HELP: consider setting `rust.download-rustc=false` in config.toml"); - eprintln!("HELP: or fetch enough history to include one upstream commit"); + println!("ERROR: could not find commit hash for downloading rustc"); + println!("HELP: maybe your repository history is too shallow?"); + println!("HELP: consider setting `rust.download-rustc=false` in config.toml"); + println!("HELP: or fetch enough history to include one upstream commit"); crate::exit!(1); } }; @@ -2910,7 +2910,7 @@ impl Config { let if_unchanged = || { if self.rust_info.is_from_tarball() { // Git is needed for running "if-unchanged" logic. - eprintln!( + println!( "WARNING: 'if-unchanged' has no effect on tarball sources; ignoring `download-ci-llvm`." ); return false; @@ -2959,10 +2959,10 @@ impl Config { // Only commits merged by bors will have CI artifacts. let commit = get_closest_merge_commit(Some(&self.src), &self.git_config(), &[]).unwrap(); if commit.is_empty() { - eprintln!("error: could not find commit hash for downloading components from CI"); - eprintln!("help: maybe your repository history is too shallow?"); - eprintln!("help: consider disabling `{option_name}`"); - eprintln!("help: or fetch enough history to include one upstream commit"); + println!("error: could not find commit hash for downloading components from CI"); + println!("help: maybe your repository history is too shallow?"); + println!("help: consider disabling `{option_name}`"); + println!("help: or fetch enough history to include one upstream commit"); crate::exit!(1); } @@ -2974,14 +2974,14 @@ impl Config { if has_changes { if if_unchanged { if self.is_verbose() { - eprintln!( + println!( "warning: saw changes to one of {modified_paths:?} since {commit}; \ ignoring `{option_name}`" ); } return None; } - eprintln!( + println!( "warning: `{option_name}` is enabled, but there are changes to one of {modified_paths:?}" ); } @@ -3018,7 +3018,7 @@ pub(crate) fn check_incompatible_options_for_ci_llvm( ($current:expr, $expected:expr) => { if let Some(current) = &$current { if Some(current) != $expected.as_ref() { - eprintln!( + println!( "WARNING: `llvm.{}` has no effect with `llvm.download-ci-llvm`. \ Current value: {:?}, Expected value(s): {}{:?}", stringify!($expected).replace("_", "-"), @@ -3123,7 +3123,7 @@ fn check_incompatible_options_for_ci_rustc( ($current:expr, $expected:expr, $config_section:expr) => { if let Some(current) = &$current { if Some(current) != $expected.as_ref() { - eprintln!( + println!( "WARNING: `{}` has no effect with `rust.download-rustc`. \ Current value: {:?}, Expected value(s): {}{:?}", format!("{}.{}", $config_section, stringify!($expected).replace("_", "-")), diff --git a/src/bootstrap/src/core/config/flags.rs b/src/bootstrap/src/core/config/flags.rs index 66b9f5ed84e64..bfeb811508c04 100644 --- a/src/bootstrap/src/core/config/flags.rs +++ b/src/bootstrap/src/core/config/flags.rs @@ -196,12 +196,12 @@ impl Flags { if let Ok(HelpVerboseOnly { help: true, verbose: 1.., cmd: subcommand }) = HelpVerboseOnly::try_parse_from(normalize_args(args)) { - eprintln!("NOTE: updating submodules before printing available paths"); + println!("NOTE: updating submodules before printing available paths"); let config = Config::parse(Self::parse(&[String::from("build")])); let build = Build::new(config); let paths = Builder::get_help(&build, subcommand); if let Some(s) = paths { - eprintln!("{s}"); + println!("{s}"); } else { panic!("No paths available for subcommand `{}`", subcommand.as_str()); } diff --git a/src/bootstrap/src/core/download.rs b/src/bootstrap/src/core/download.rs index 05b91c518cf4d..db35e6907e661 100644 --- a/src/bootstrap/src/core/download.rs +++ b/src/bootstrap/src/core/download.rs @@ -77,7 +77,7 @@ impl Config { if self.dry_run() && !cmd.run_always { return true; } - self.verbose(|| eprintln!("running: {cmd:?}")); + self.verbose(|| println!("running: {cmd:?}")); check_run(cmd, self.is_verbose()) } @@ -144,7 +144,7 @@ impl Config { /// Please see for more information fn fix_bin_or_dylib(&self, fname: &Path) { assert_eq!(SHOULD_FIX_BINS_AND_DYLIBS.get(), Some(&true)); - eprintln!("attempting to patch {}", fname.display()); + println!("attempting to patch {}", fname.display()); // Only build `.nix-deps` once. static NIX_DEPS_DIR: OnceLock = OnceLock::new(); @@ -206,7 +206,7 @@ impl Config { } fn download_file(&self, url: &str, dest_path: &Path, help_on_error: &str) { - self.verbose(|| eprintln!("download {url}")); + self.verbose(|| println!("download {url}")); // Use a temporary file in case we crash while downloading, to avoid a corrupt download in cache/. let tempfile = self.tempdir().join(dest_path.file_name().unwrap()); // While bootstrap itself only supports http and https downloads, downstream forks might @@ -226,7 +226,7 @@ impl Config { } fn download_http_with_retries(&self, tempfile: &Path, url: &str, help_on_error: &str) { - eprintln!("downloading {url}"); + println!("downloading {url}"); // Try curl. If that fails and we are on windows, fallback to PowerShell. // options should be kept in sync with // src/bootstrap/src/core/download.rs @@ -341,7 +341,7 @@ impl Config { short_path = short_path.strip_prefix(pattern).unwrap_or(short_path); let dst_path = dst.join(short_path); self.verbose(|| { - eprintln!("extracting {} to {}", original_path.display(), dst.display()) + println!("extracting {} to {}", original_path.display(), dst.display()) }); if !t!(member.unpack_in(dst)) { panic!("path traversal attack ??"); @@ -365,7 +365,7 @@ impl Config { pub(crate) fn verify(&self, path: &Path, expected: &str) -> bool { use sha2::Digest; - self.verbose(|| eprintln!("verifying {}", path.display())); + self.verbose(|| println!("verifying {}", path.display())); if self.dry_run() { return false; @@ -391,7 +391,7 @@ impl Config { let verified = checksum == expected; if !verified { - eprintln!( + println!( "invalid checksum: \n\ found: {checksum}\n\ expected: {expected}", @@ -421,7 +421,7 @@ enum DownloadSource { /// Functions that are only ever called once, but named for clarify and to avoid thousand-line functions. impl Config { pub(crate) fn download_clippy(&self) -> PathBuf { - self.verbose(|| eprintln!("downloading stage0 clippy artifacts")); + self.verbose(|| println!("downloading stage0 clippy artifacts")); let date = &self.stage0_metadata.compiler.date; let version = &self.stage0_metadata.compiler.version; @@ -518,7 +518,7 @@ impl Config { } pub(crate) fn download_ci_rustc(&self, commit: &str) { - self.verbose(|| eprintln!("using downloaded stage2 artifacts from CI (commit {commit})")); + self.verbose(|| println!("using downloaded stage2 artifacts from CI (commit {commit})")); let version = self.artifact_version_part(commit); // download-rustc doesn't need its own cargo, it can just use beta's. But it does need the @@ -539,7 +539,7 @@ impl Config { #[cfg(not(feature = "bootstrap-self-test"))] pub(crate) fn download_beta_toolchain(&self) { - self.verbose(|| eprintln!("downloading stage0 beta artifacts")); + self.verbose(|| println!("downloading stage0 beta artifacts")); let date = &self.stage0_metadata.compiler.date; let version = &self.stage0_metadata.compiler.version; @@ -677,7 +677,7 @@ impl Config { return; } else { self.verbose(|| { - eprintln!( + println!( "ignoring cached file {} due to failed verification", tarball.display() ) @@ -776,10 +776,10 @@ download-rustc = false t!(check_incompatible_options_for_ci_llvm(current_config_toml, ci_config_toml)); } Err(e) if e.to_string().contains("unknown field") => { - eprintln!( + println!( "WARNING: CI LLVM has some fields that are no longer supported in bootstrap; download-ci-llvm will be disabled." ); - eprintln!("HELP: Consider rebasing to a newer commit if available."); + println!("HELP: Consider rebasing to a newer commit if available."); } Err(e) => { eprintln!("ERROR: Failed to parse CI LLVM config.toml: {e}"); diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs index 71e7f40f0320a..dcf68cbeeda71 100644 --- a/src/bootstrap/src/core/sanity.rs +++ b/src/bootstrap/src/core/sanity.rs @@ -237,11 +237,11 @@ than building it. stage0_supported_target_list.intersection(&missing_targets_hashset).collect(); if !duplicated_targets.is_empty() { - eprintln!( + println!( "Following targets supported from the stage0 compiler, please remove them from STAGE0_MISSING_TARGETS list." ); for duplicated_target in duplicated_targets { - eprintln!(" {duplicated_target}"); + println!(" {duplicated_target}"); } std::process::exit(1); } diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index 5f778223d7dac..0ecf61ffcd903 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -406,11 +406,11 @@ impl Build { .unwrap() .trim(); if local_release.split('.').take(2).eq(version.split('.').take(2)) { - build.verbose(|| eprintln!("auto-detected local-rebuild {local_release}")); + build.verbose(|| println!("auto-detected local-rebuild {local_release}")); build.local_rebuild = true; } - build.verbose(|| eprintln!("finding compilers")); + build.verbose(|| println!("finding compilers")); utils::cc_detect::find(&build); // When running `setup`, the profile is about to change, so any requirements we have now may // be different on the next invocation. Don't check for them until the next time x.py is @@ -418,7 +418,7 @@ impl Build { // // Similarly, for `setup` we don't actually need submodules or cargo metadata. if !matches!(build.config.cmd, Subcommand::Setup { .. }) { - build.verbose(|| eprintln!("running sanity check")); + build.verbose(|| println!("running sanity check")); crate::core::sanity::check(&mut build); // Make sure we update these before gathering metadata so we don't get an error about missing @@ -436,7 +436,7 @@ impl Build { // Now, update all existing submodules. build.update_existing_submodules(); - build.verbose(|| eprintln!("learning about cargo")); + build.verbose(|| println!("learning about cargo")); crate::core::metadata::build(&mut build); } @@ -605,7 +605,7 @@ impl Build { let stamp = dir.join(".stamp"); let mut cleared = false; if mtime(&stamp) < mtime(input) { - self.verbose(|| eprintln!("Dirty - {}", dir.display())); + self.verbose(|| println!("Dirty - {}", dir.display())); let _ = fs::remove_dir_all(dir); cleared = true; } else if stamp.exists() { @@ -890,7 +890,7 @@ impl Build { let executed_at = std::panic::Location::caller(); self.verbose(|| { - eprintln!("running: {command:?} (created at {created_at}, executed at {executed_at})") + println!("running: {command:?} (created at {created_at}, executed at {executed_at})") }); let cmd = command.as_command_mut(); @@ -947,7 +947,7 @@ Executed at: {executed_at}"#, let fail = |message: &str, output: CommandOutput| -> ! { if self.is_verbose() { - eprintln!("{message}"); + println!("{message}"); } else { let (stdout, stderr) = (output.stdout_if_present(), output.stderr_if_present()); // If the command captures output, the user would not see any indication that @@ -957,16 +957,16 @@ Executed at: {executed_at}"#, if let Some(stdout) = output.stdout_if_present().take_if(|s| !s.trim().is_empty()) { - eprintln!("STDOUT:\n{stdout}\n"); + println!("STDOUT:\n{stdout}\n"); } if let Some(stderr) = output.stderr_if_present().take_if(|s| !s.trim().is_empty()) { - eprintln!("STDERR:\n{stderr}\n"); + println!("STDERR:\n{stderr}\n"); } - eprintln!("Command {command:?} has failed. Rerun with -v to see more details."); + println!("Command {command:?} has failed. Rerun with -v to see more details."); } else { - eprintln!("Command has failed. Rerun with -v to see more details."); + println!("Command has failed. Rerun with -v to see more details."); } } exit!(1); @@ -1011,7 +1011,7 @@ Executed at: {executed_at}"#, match self.config.dry_run { DryRun::SelfCheck => (), DryRun::Disabled | DryRun::UserSelected => { - eprintln!("{msg}"); + println!("{msg}"); } } } @@ -1666,7 +1666,7 @@ Executed at: {executed_at}"#, if self.config.dry_run() { return; } - self.verbose_than(1, || eprintln!("Copy/Link {src:?} to {dst:?}")); + self.verbose_than(1, || println!("Copy/Link {src:?} to {dst:?}")); if src == dst { return; } @@ -1775,7 +1775,7 @@ Executed at: {executed_at}"#, return; } let dst = dstdir.join(src.file_name().unwrap()); - self.verbose_than(1, || eprintln!("Install {src:?} to {dst:?}")); + self.verbose_than(1, || println!("Install {src:?} to {dst:?}")); t!(fs::create_dir_all(dstdir)); if !src.exists() { panic!("ERROR: File \"{}\" not found!", src.display()); diff --git a/src/bootstrap/src/utils/cc_detect.rs b/src/bootstrap/src/utils/cc_detect.rs index e8d5b60948aa8..0df0046945220 100644 --- a/src/bootstrap/src/utils/cc_detect.rs +++ b/src/bootstrap/src/utils/cc_detect.rs @@ -155,15 +155,15 @@ pub fn find_target(build: &Build, target: TargetSelection) { build.cxx.borrow_mut().insert(target, compiler); } - build.verbose(|| eprintln!("CC_{} = {:?}", target.triple, build.cc(target))); - build.verbose(|| eprintln!("CFLAGS_{} = {cflags:?}", target.triple)); + build.verbose(|| println!("CC_{} = {:?}", target.triple, build.cc(target))); + build.verbose(|| println!("CFLAGS_{} = {cflags:?}", target.triple)); if let Ok(cxx) = build.cxx(target) { let cxxflags = build.cflags(target, GitRepo::Rustc, CLang::Cxx); - build.verbose(|| eprintln!("CXX_{} = {cxx:?}", target.triple)); - build.verbose(|| eprintln!("CXXFLAGS_{} = {cxxflags:?}", target.triple)); + build.verbose(|| println!("CXX_{} = {cxx:?}", target.triple)); + build.verbose(|| println!("CXXFLAGS_{} = {cxxflags:?}", target.triple)); } if let Some(ar) = ar { - build.verbose(|| eprintln!("AR_{} = {ar:?}", target.triple)); + build.verbose(|| println!("AR_{} = {ar:?}", target.triple)); build.ar.borrow_mut().insert(target, ar); } diff --git a/src/bootstrap/src/utils/helpers.rs b/src/bootstrap/src/utils/helpers.rs index c0d52fd343059..923cc2dfc28ce 100644 --- a/src/bootstrap/src/utils/helpers.rs +++ b/src/bootstrap/src/utils/helpers.rs @@ -135,7 +135,7 @@ impl Drop for TimeIt { fn drop(&mut self) { let time = self.1.elapsed(); if !self.0 { - eprintln!("\tfinished in {}.{:03} seconds", time.as_secs(), time.subsec_millis()); + println!("\tfinished in {}.{:03} seconds", time.as_secs(), time.subsec_millis()); } } } @@ -267,12 +267,12 @@ pub fn check_run(cmd: &mut BootstrapCommand, print_cmd_on_fail: bool) -> bool { let status = match cmd.as_command_mut().status() { Ok(status) => status, Err(e) => { - eprintln!("failed to execute command: {cmd:?}\nERROR: {e}"); + println!("failed to execute command: {cmd:?}\nERROR: {e}"); return false; } }; if !status.success() && print_cmd_on_fail { - eprintln!( + println!( "\n\ncommand did not execute successfully: {cmd:?}\n\ expected success, got: {status}\n\n" ); diff --git a/src/bootstrap/src/utils/metrics.rs b/src/bootstrap/src/utils/metrics.rs index 06d3add6281f8..b51fd490535a3 100644 --- a/src/bootstrap/src/utils/metrics.rs +++ b/src/bootstrap/src/utils/metrics.rs @@ -185,7 +185,7 @@ impl BuildMetrics { if version.format_version == CURRENT_FORMAT_VERSION { t!(serde_json::from_slice::(&contents)).invocations } else { - eprintln!( + println!( "WARNING: overriding existing build/metrics.json, as it's not \ compatible with build metrics format version {CURRENT_FORMAT_VERSION}." ); diff --git a/src/bootstrap/src/utils/render_tests.rs b/src/bootstrap/src/utils/render_tests.rs index 7a3ec61c6da0a..eb2c8254dc0f4 100644 --- a/src/bootstrap/src/utils/render_tests.rs +++ b/src/bootstrap/src/utils/render_tests.rs @@ -56,7 +56,7 @@ fn run_tests(builder: &Builder<'_>, cmd: &mut BootstrapCommand, stream: bool) -> let cmd = cmd.as_command_mut(); cmd.stdout(Stdio::piped()); - builder.verbose(|| eprintln!("running: {cmd:?}")); + builder.verbose(|| println!("running: {cmd:?}")); let mut process = cmd.spawn().unwrap(); @@ -71,7 +71,7 @@ fn run_tests(builder: &Builder<'_>, cmd: &mut BootstrapCommand, stream: bool) -> let result = process.wait_with_output().unwrap(); if !result.status.success() && builder.is_verbose() { - eprintln!( + println!( "\n\ncommand did not execute successfully: {cmd:?}\n\ expected success, got: {}", result.status @@ -135,9 +135,7 @@ impl<'a> Renderer<'a> { if self.up_to_date_tests > 0 { let n = self.up_to_date_tests; let s = if n > 1 { "s" } else { "" }; - eprintln!( - "help: ignored {n} up-to-date test{s}; use `--force-rerun` to prevent this\n" - ); + println!("help: ignored {n} up-to-date test{s}; use `--force-rerun` to prevent this\n"); } } @@ -187,12 +185,12 @@ impl<'a> Renderer<'a> { } fn render_test_outcome_verbose(&self, outcome: Outcome<'_>, test: &TestOutcome) { - eprint!("test {} ... ", test.name); - self.builder.colored_stderr(|stdout| outcome.write_long(stdout)).unwrap(); + print!("test {} ... ", test.name); + self.builder.colored_stdout(|stdout| outcome.write_long(stdout)).unwrap(); if let Some(exec_time) = test.exec_time { - eprint!(" ({exec_time:.2?})"); + print!(" ({exec_time:.2?})"); } - eprintln!(); + println!(); } fn render_test_outcome_terse(&mut self, outcome: Outcome<'_>, test: &TestOutcome) { @@ -200,45 +198,45 @@ impl<'a> Renderer<'a> { if let Some(total) = self.tests_count { let total = total.to_string(); let executed = format!("{:>width$}", self.executed_tests - 1, width = total.len()); - eprint!(" {executed}/{total}"); + print!(" {executed}/{total}"); } - eprintln!(); + println!(); self.terse_tests_in_line = 0; } self.terse_tests_in_line += 1; - self.builder.colored_stderr(|stdout| outcome.write_short(stdout, &test.name)).unwrap(); + self.builder.colored_stdout(|stdout| outcome.write_short(stdout, &test.name)).unwrap(); let _ = std::io::stdout().flush(); } fn render_suite_outcome(&self, outcome: Outcome<'_>, suite: &SuiteOutcome) { // The terse output doesn't end with a newline, so we need to add it ourselves. if !self.builder.config.verbose_tests { - eprintln!(); + println!(); } if !self.failures.is_empty() { - eprintln!("\nfailures:\n"); + println!("\nfailures:\n"); for failure in &self.failures { if failure.stdout.is_some() || failure.message.is_some() { - eprintln!("---- {} stdout ----", failure.name); + println!("---- {} stdout ----", failure.name); if let Some(stdout) = &failure.stdout { - eprintln!("{stdout}"); + println!("{stdout}"); } if let Some(message) = &failure.message { - eprintln!("NOTE: {message}"); + println!("NOTE: {message}"); } } } - eprintln!("\nfailures:"); + println!("\nfailures:"); for failure in &self.failures { - eprintln!(" {}", failure.name); + println!(" {}", failure.name); } } if !self.benches.is_empty() { - eprintln!("\nbenchmarks:"); + println!("\nbenchmarks:"); let mut rows = Vec::new(); for bench in &self.benches { @@ -253,13 +251,13 @@ impl<'a> Renderer<'a> { let max_1 = rows.iter().map(|r| r.1.len()).max().unwrap_or(0); let max_2 = rows.iter().map(|r| r.2.len()).max().unwrap_or(0); for row in &rows { - eprintln!(" {:max_1$} {:>max_2$}", row.0, row.1, row.2); + println!(" {:max_1$} {:>max_2$}", row.0, row.1, row.2); } } - eprint!("\ntest result: "); - self.builder.colored_stderr(|stdout| outcome.write_long(stdout)).unwrap(); - eprintln!( + print!("\ntest result: "); + self.builder.colored_stdout(|stdout| outcome.write_long(stdout)).unwrap(); + println!( ". {} passed; {} failed; {} ignored; {} measured; {} filtered out{time}\n", suite.passed, suite.failed, @@ -276,7 +274,7 @@ impl<'a> Renderer<'a> { fn render_message(&mut self, message: Message) { match message { Message::Suite(SuiteMessage::Started { test_count }) => { - eprintln!("\nrunning {test_count} tests"); + println!("\nrunning {test_count} tests"); self.executed_tests = 0; self.terse_tests_in_line = 0; self.tests_count = Some(test_count); @@ -316,7 +314,7 @@ impl<'a> Renderer<'a> { self.failures.push(outcome); } Message::Test(TestMessage::Timeout { name }) => { - eprintln!("test {name} has been running for a long time"); + println!("test {name} has been running for a long time"); } Message::Test(TestMessage::Started) => {} // Not useful } diff --git a/src/bootstrap/src/utils/tarball.rs b/src/bootstrap/src/utils/tarball.rs index f60498a4872c4..3c6c7a7fa180a 100644 --- a/src/bootstrap/src/utils/tarball.rs +++ b/src/bootstrap/src/utils/tarball.rs @@ -344,7 +344,7 @@ impl<'a> Tarball<'a> { // For `x install` tarball files aren't needed, so we can speed up the process by not producing them. let compression_profile = if self.builder.kind == Kind::Install { self.builder.verbose(|| { - eprintln!("Forcing dist.compression-profile = 'no-op' for `x install`.") + println!("Forcing dist.compression-profile = 'no-op' for `x install`.") }); // "no-op" indicates that the rust-installer won't produce compressed tarball sources. "no-op" diff --git a/src/tools/compiletest/src/compute_diff.rs b/src/tools/compiletest/src/compute_diff.rs index 3ace6c5b6d717..92c80c27de03b 100644 --- a/src/tools/compiletest/src/compute_diff.rs +++ b/src/tools/compiletest/src/compute_diff.rs @@ -144,7 +144,7 @@ where } if !wrote_data { - eprintln!("note: diff is identical to nightly rustdoc"); + println!("note: diff is identical to nightly rustdoc"); assert!(diff_output.metadata().unwrap().len() == 0); return false; } else if verbose { diff --git a/src/tools/compiletest/src/debuggers.rs b/src/tools/compiletest/src/debuggers.rs index e75c8a5993e53..b605bc813f195 100644 --- a/src/tools/compiletest/src/debuggers.rs +++ b/src/tools/compiletest/src/debuggers.rs @@ -20,7 +20,7 @@ pub(crate) fn configure_gdb(config: &Config) -> Option> { } if config.remote_test_client.is_some() && !config.target.contains("android") { - eprintln!( + println!( "WARNING: debuginfo tests are not available when \ testing with remote" ); @@ -28,7 +28,7 @@ pub(crate) fn configure_gdb(config: &Config) -> Option> { } if config.target.contains("android") { - eprintln!( + println!( "{} debug-info test uses tcp 5039 port.\ please reserve it", config.target @@ -50,7 +50,7 @@ pub(crate) fn configure_lldb(config: &Config) -> Option> { config.lldb_python_dir.as_ref()?; if let Some(350) = config.lldb_version { - eprintln!( + println!( "WARNING: The used version of LLDB (350) has a \ known issue that breaks debuginfo tests. See \ issue #32520 for more information. Skipping all \ diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs index 9acb7d393b461..a5a166af33b6d 100644 --- a/src/tools/compiletest/src/lib.rs +++ b/src/tools/compiletest/src/lib.rs @@ -188,8 +188,8 @@ pub fn parse_config(args: Vec) -> Config { let (argv0, args_) = args.split_first().unwrap(); if args.len() == 1 || args[1] == "-h" || args[1] == "--help" { let message = format!("Usage: {} [OPTIONS] [TESTNAME...]", argv0); - eprintln!("{}", opts.usage(&message)); - eprintln!(); + println!("{}", opts.usage(&message)); + println!(); panic!() } @@ -200,8 +200,8 @@ pub fn parse_config(args: Vec) -> Config { if matches.opt_present("h") || matches.opt_present("help") { let message = format!("Usage: {} [OPTIONS] [TESTNAME...]", argv0); - eprintln!("{}", opts.usage(&message)); - eprintln!(); + println!("{}", opts.usage(&message)); + println!(); panic!() } @@ -508,7 +508,7 @@ pub fn run_tests(config: Arc) { // easy to miss which tests failed, and as such fail to reproduce // the failure locally. - eprintln!( + println!( "Some tests failed in compiletest suite={}{} mode={} host={} target={}", config.suite, config diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index ca746ed8c55c4..7b11bf3b1219c 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -131,7 +131,7 @@ pub fn run(config: Arc, testpaths: &TestPaths, revision: Option<&str>) { if config.verbose { // We're going to be dumping a lot of info. Start on a new line. - eprintln!("\n"); + print!("\n\n"); } debug!("running {:?}", testpaths.file.display()); let mut props = TestProps::from_file(&testpaths.file, revision, &config); @@ -353,7 +353,7 @@ impl<'test> TestCx<'test> { { self.error(&format!("{} test did not emit an error", self.config.mode)); if self.config.mode == crate::common::Mode::Ui { - eprintln!("note: by default, ui tests are expected not to compile"); + println!("note: by default, ui tests are expected not to compile"); } proc_res.fatal(None, || ()); }; @@ -774,20 +774,20 @@ impl<'test> TestCx<'test> { unexpected.len(), not_found.len() )); - eprintln!("status: {}\ncommand: {}\n", proc_res.status, proc_res.cmdline); + println!("status: {}\ncommand: {}\n", proc_res.status, proc_res.cmdline); if !unexpected.is_empty() { - eprintln!("{}", "--- unexpected errors (from JSON output) ---".green()); + println!("{}", "--- unexpected errors (from JSON output) ---".green()); for error in &unexpected { - eprintln!("{}", error.render_for_expected()); + println!("{}", error.render_for_expected()); } - eprintln!("{}", "---".green()); + println!("{}", "---".green()); } if !not_found.is_empty() { - eprintln!("{}", "--- not found errors (from test file) ---".red()); + println!("{}", "--- not found errors (from test file) ---".red()); for error in ¬_found { - eprintln!("{}", error.render_for_expected()); + println!("{}", error.render_for_expected()); } - eprintln!("{}", "---\n".red()); + println!("{}", "---\n".red()); } panic!("errors differ from expected"); } @@ -1876,18 +1876,18 @@ impl<'test> TestCx<'test> { fn maybe_dump_to_stdout(&self, out: &str, err: &str) { if self.config.verbose { - eprintln!("------stdout------------------------------"); - eprintln!("{}", out); - eprintln!("------stderr------------------------------"); - eprintln!("{}", err); - eprintln!("------------------------------------------"); + println!("------stdout------------------------------"); + println!("{}", out); + println!("------stderr------------------------------"); + println!("{}", err); + println!("------------------------------------------"); } } fn error(&self, err: &str) { match self.revision { - Some(rev) => eprintln!("\nerror in revision `{}`: {}", rev, err), - None => eprintln!("\nerror: {}", err), + Some(rev) => println!("\nerror in revision `{}`: {}", rev, err), + None => println!("\nerror: {}", err), } } @@ -1972,7 +1972,7 @@ impl<'test> TestCx<'test> { if !self.config.has_html_tidy { return; } - eprintln!("info: generating a diff against nightly rustdoc"); + println!("info: generating a diff against nightly rustdoc"); let suffix = self.safe_revision().map_or("nightly".into(), |path| path.to_owned() + "-nightly"); @@ -2082,7 +2082,7 @@ impl<'test> TestCx<'test> { .output() .unwrap(); assert!(output.status.success()); - eprintln!("{}", String::from_utf8_lossy(&output.stdout)); + println!("{}", String::from_utf8_lossy(&output.stdout)); eprintln!("{}", String::from_utf8_lossy(&output.stderr)); } else { use colored::Colorize; @@ -2496,7 +2496,7 @@ impl<'test> TestCx<'test> { )"# ) .replace_all(&output, |caps: &Captures<'_>| { - eprintln!("{}", &caps[0]); + println!("{}", &caps[0]); caps[0].replace(r"\", "/") }) .replace("\r\n", "\n") @@ -2601,14 +2601,14 @@ impl<'test> TestCx<'test> { if let Err(err) = fs::write(&actual_path, &actual) { self.fatal(&format!("failed to write {stream} to `{actual_path:?}`: {err}",)); } - eprintln!("Saved the actual {stream} to {actual_path:?}"); + println!("Saved the actual {stream} to {actual_path:?}"); let expected_path = expected_output_path(self.testpaths, self.revision, &self.config.compare_mode, stream); if !self.config.bless { if expected.is_empty() { - eprintln!("normalized {}:\n{}\n", stream, actual); + println!("normalized {}:\n{}\n", stream, actual); } else { self.show_diff( stream, @@ -2631,10 +2631,10 @@ impl<'test> TestCx<'test> { if let Err(err) = fs::write(&expected_path, &actual) { self.fatal(&format!("failed to write {stream} to `{expected_path:?}`: {err}")); } - eprintln!("Blessing the {stream} of {test_name} in {expected_path:?}"); + println!("Blessing the {stream} of {test_name} in {expected_path:?}"); } - eprintln!("\nThe actual {0} differed from the expected {0}.", stream); + println!("\nThe actual {0} differed from the expected {0}.", stream); if self.config.bless { 0 } else { 1 } } @@ -2783,7 +2783,7 @@ impl<'test> TestCx<'test> { fs::create_dir_all(&incremental_dir).unwrap(); if self.config.verbose { - eprintln!("init_incremental_test: incremental_dir={}", incremental_dir.display()); + println!("init_incremental_test: incremental_dir={}", incremental_dir.display()); } } @@ -2841,7 +2841,7 @@ impl ProcRes { } } - eprintln!( + println!( "status: {}\ncommand: {}\n{}\n{}\n", self.status, self.cmdline, @@ -2852,7 +2852,7 @@ impl ProcRes { pub fn fatal(&self, err: Option<&str>, on_failure: impl FnOnce()) -> ! { if let Some(e) = err { - eprintln!("\nerror: {}", e); + println!("\nerror: {}", e); } self.print_info(); on_failure(); diff --git a/src/tools/compiletest/src/runtest/codegen_units.rs b/src/tools/compiletest/src/runtest/codegen_units.rs index 6acd140183d47..6c866cbef21ab 100644 --- a/src/tools/compiletest/src/runtest/codegen_units.rs +++ b/src/tools/compiletest/src/runtest/codegen_units.rs @@ -64,13 +64,13 @@ impl TestCx<'_> { if !missing.is_empty() { missing.sort(); - eprintln!("\nThese items should have been contained but were not:\n"); + println!("\nThese items should have been contained but were not:\n"); for item in &missing { - eprintln!("{}", item); + println!("{}", item); } - eprintln!("\n"); + println!("\n"); } if !unexpected.is_empty() { @@ -80,24 +80,24 @@ impl TestCx<'_> { sorted }; - eprintln!("\nThese items were contained but should not have been:\n"); + println!("\nThese items were contained but should not have been:\n"); for item in sorted { - eprintln!("{}", item); + println!("{}", item); } - eprintln!("\n"); + println!("\n"); } if !wrong_cgus.is_empty() { wrong_cgus.sort_by_key(|pair| pair.0.name.clone()); - eprintln!("\nThe following items were assigned to wrong codegen units:\n"); + println!("\nThe following items were assigned to wrong codegen units:\n"); for &(ref expected_item, ref actual_item) in &wrong_cgus { - eprintln!("{}", expected_item.name); - eprintln!(" expected: {}", codegen_units_to_str(&expected_item.codegen_units)); - eprintln!(" actual: {}", codegen_units_to_str(&actual_item.codegen_units)); - eprintln!(); + println!("{}", expected_item.name); + println!(" expected: {}", codegen_units_to_str(&expected_item.codegen_units)); + println!(" actual: {}", codegen_units_to_str(&actual_item.codegen_units)); + println!(); } } diff --git a/src/tools/compiletest/src/runtest/debuginfo.rs b/src/tools/compiletest/src/runtest/debuginfo.rs index 7322e730e53f8..c621c22ac993c 100644 --- a/src/tools/compiletest/src/runtest/debuginfo.rs +++ b/src/tools/compiletest/src/runtest/debuginfo.rs @@ -260,7 +260,7 @@ impl TestCx<'_> { cmdline, }; if adb.kill().is_err() { - eprintln!("Adb process is already finished."); + println!("Adb process is already finished."); } } else { let rust_src_root = @@ -275,7 +275,7 @@ impl TestCx<'_> { match self.config.gdb_version { Some(version) => { - eprintln!("NOTE: compiletest thinks it is using GDB version {}", version); + println!("NOTE: compiletest thinks it is using GDB version {}", version); if version > extract_gdb_version("7.4").unwrap() { // Add the directory containing the pretty printers to @@ -297,7 +297,7 @@ impl TestCx<'_> { } } _ => { - eprintln!( + println!( "NOTE: compiletest does not know which version of \ GDB it is using" ); @@ -392,10 +392,10 @@ impl TestCx<'_> { match self.config.lldb_version { Some(ref version) => { - eprintln!("NOTE: compiletest thinks it is using LLDB version {}", version); + println!("NOTE: compiletest thinks it is using LLDB version {}", version); } _ => { - eprintln!( + println!( "NOTE: compiletest does not know which version of \ LLDB it is using" ); diff --git a/src/tools/compiletest/src/runtest/incremental.rs b/src/tools/compiletest/src/runtest/incremental.rs index 4f26786129bde..591aff0defeb0 100644 --- a/src/tools/compiletest/src/runtest/incremental.rs +++ b/src/tools/compiletest/src/runtest/incremental.rs @@ -30,7 +30,7 @@ impl TestCx<'_> { assert!(incremental_dir.exists(), "init_incremental_test failed to create incremental dir"); if self.config.verbose { - eprint!("revision={:?} props={:#?}", revision, self.props); + print!("revision={:?} props={:#?}", revision, self.props); } if revision.starts_with("cpass") { diff --git a/src/tools/compiletest/src/runtest/mir_opt.rs b/src/tools/compiletest/src/runtest/mir_opt.rs index 64a2addaa28d3..d1ec00357449d 100644 --- a/src/tools/compiletest/src/runtest/mir_opt.rs +++ b/src/tools/compiletest/src/runtest/mir_opt.rs @@ -89,7 +89,7 @@ impl TestCx<'_> { } let expected_string = fs::read_to_string(&expected_file).unwrap(); if dumped_string != expected_string { - eprint!("{}", write_diff(&expected_string, &dumped_string, 3)); + print!("{}", write_diff(&expected_string, &dumped_string, 3)); panic!( "Actual MIR output differs from expected MIR output {}", expected_file.display() diff --git a/src/tools/compiletest/src/runtest/rustdoc_json.rs b/src/tools/compiletest/src/runtest/rustdoc_json.rs index 84376d346af34..31fdb0a5d13bd 100644 --- a/src/tools/compiletest/src/runtest/rustdoc_json.rs +++ b/src/tools/compiletest/src/runtest/rustdoc_json.rs @@ -29,7 +29,7 @@ impl TestCx<'_> { if !res.status.success() { self.fatal_proc_rec_with_ctx("jsondocck failed!", &res, |_| { - eprintln!("Rustdoc Output:"); + println!("Rustdoc Output:"); proc_res.print_info(); }) } diff --git a/src/tools/compiletest/src/runtest/ui.rs b/src/tools/compiletest/src/runtest/ui.rs index bc860bf18c741..172b1e32aad3b 100644 --- a/src/tools/compiletest/src/runtest/ui.rs +++ b/src/tools/compiletest/src/runtest/ui.rs @@ -109,10 +109,10 @@ impl TestCx<'_> { } if errors > 0 { - eprintln!("To update references, rerun the tests and pass the `--bless` flag"); + println!("To update references, rerun the tests and pass the `--bless` flag"); let relative_path_to_file = self.testpaths.relative_dir.join(self.testpaths.file.file_name().unwrap()); - eprintln!( + println!( "To only update this specific test, also pass `--test-args {}`", relative_path_to_file.display(), ); diff --git a/src/tools/compiletest/src/util.rs b/src/tools/compiletest/src/util.rs index 7b50e62c29bb8..bff02f1db9f02 100644 --- a/src/tools/compiletest/src/util.rs +++ b/src/tools/compiletest/src/util.rs @@ -30,7 +30,7 @@ fn path_div() -> &'static str { pub fn logv(config: &Config, s: String) { debug!("{}", s); if config.verbose { - eprintln!("{}", s); + println!("{}", s); } } From 86a4a2786f285c5872d0eb9044386c00f7c12847 Mon Sep 17 00:00:00 2001 From: klensy Date: Thu, 12 Dec 2024 19:01:28 +0300 Subject: [PATCH 17/20] fix self shadowed self compare --- src/librustdoc/html/render/search_index.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustdoc/html/render/search_index.rs b/src/librustdoc/html/render/search_index.rs index cfb62c3ca1640..91b31f31ab192 100644 --- a/src/librustdoc/html/render/search_index.rs +++ b/src/librustdoc/html/render/search_index.rs @@ -201,7 +201,7 @@ pub(crate) fn build_index( // exported from this same module). It's also likely to Do // What I Mean, since if a re-export changes the name, it might // also be a change in semantic meaning. - .filter(|fqp| fqp.last() == fqp.last()); + .filter(|this_fqp| this_fqp.last() == fqp.last()); Some(insert_into_map( itemid_to_pathid, ItemId::DefId(defid), From 33e6be0c10a3ef56df1ea7b81ed284456b4893f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Thu, 21 Nov 2024 14:09:46 +0100 Subject: [PATCH 18/20] crashes: more tests --- tests/crashes/132765.rs | 12 ++++++++++++ tests/crashes/132766.rs | 9 +++++++++ tests/crashes/132882.rs | 13 +++++++++++++ tests/crashes/132981.rs | 7 +++++++ tests/crashes/133063.rs | 8 ++++++++ tests/crashes/133066.rs | 12 ++++++++++++ tests/crashes/133199.rs | 11 +++++++++++ tests/crashes/133275-1.rs | 13 +++++++++++++ tests/crashes/133275-2.rs | 15 +++++++++++++++ tests/crashes/auxiliary/aux133199.rs | 13 +++++++++++++ 10 files changed, 113 insertions(+) create mode 100644 tests/crashes/132765.rs create mode 100644 tests/crashes/132766.rs create mode 100644 tests/crashes/132882.rs create mode 100644 tests/crashes/132981.rs create mode 100644 tests/crashes/133063.rs create mode 100644 tests/crashes/133066.rs create mode 100644 tests/crashes/133199.rs create mode 100644 tests/crashes/133275-1.rs create mode 100644 tests/crashes/133275-2.rs create mode 100644 tests/crashes/auxiliary/aux133199.rs diff --git a/tests/crashes/132765.rs b/tests/crashes/132765.rs new file mode 100644 index 0000000000000..01e8fdaacff77 --- /dev/null +++ b/tests/crashes/132765.rs @@ -0,0 +1,12 @@ +//@ known-bug: #132765 + +trait LendingIterator { + type Item<'q>; + fn for_each(&self, _f: Box)>) {} +} + +fn f(_: ()) {} + +fn main() { + LendingIterator::for_each(&(), f); +} diff --git a/tests/crashes/132766.rs b/tests/crashes/132766.rs new file mode 100644 index 0000000000000..5f5117d77a521 --- /dev/null +++ b/tests/crashes/132766.rs @@ -0,0 +1,9 @@ +//@ known-bug: #132766 + +trait Trait {} +impl<'a> Trait for () { + fn pass2<'a>() -> impl Trait2 {} +} + +trait Trait2 {} +impl Trait2 for () {} diff --git a/tests/crashes/132882.rs b/tests/crashes/132882.rs new file mode 100644 index 0000000000000..6b5e4dba803b0 --- /dev/null +++ b/tests/crashes/132882.rs @@ -0,0 +1,13 @@ +//@ known-bug: #132882 + +use std::ops::Add; + +pub trait Numoid +where + for &'a Self: Add, +{ +} + +pub fn compute(a: N) -> N { + &a + a +} diff --git a/tests/crashes/132981.rs b/tests/crashes/132981.rs new file mode 100644 index 0000000000000..8ff4fa36fd071 --- /dev/null +++ b/tests/crashes/132981.rs @@ -0,0 +1,7 @@ +//@ known-bug: #132981 +//@compile-flags: -Clink-dead-code=true --crate-type lib +//@ only-x86_64 +//@ ignore-windows + +#![feature(rust_cold_cc)] +pub extern "rust-cold" fn foo(_: [usize; 3]) {} diff --git a/tests/crashes/133063.rs b/tests/crashes/133063.rs new file mode 100644 index 0000000000000..132b5486170a8 --- /dev/null +++ b/tests/crashes/133063.rs @@ -0,0 +1,8 @@ +//@ known-bug: #133063 + +fn foo(x: !) { + match x { + (! | !) if false => {} + _ => {} + } +} diff --git a/tests/crashes/133066.rs b/tests/crashes/133066.rs new file mode 100644 index 0000000000000..732ebb7079fd0 --- /dev/null +++ b/tests/crashes/133066.rs @@ -0,0 +1,12 @@ +//@ known-bug: #133066 +trait Owner { + const C: u32; +} + +impl Owner for () {;} + +fn take0(_: impl Owner = { N }>) {} + +fn main() { + take0::(()); +} diff --git a/tests/crashes/133199.rs b/tests/crashes/133199.rs new file mode 100644 index 0000000000000..76535fa83a6d0 --- /dev/null +++ b/tests/crashes/133199.rs @@ -0,0 +1,11 @@ +//@ known-bug: #133199 +//@ aux-build: aux133199.rs + +extern crate aux133199; + +use aux133199::FixedBitSet; + +fn main() { + FixedBitSet::<7>::new(); + //~^ ERROR +} diff --git a/tests/crashes/133275-1.rs b/tests/crashes/133275-1.rs new file mode 100644 index 0000000000000..73c04f5d6e410 --- /dev/null +++ b/tests/crashes/133275-1.rs @@ -0,0 +1,13 @@ +//@ known-bug: #133275 +#![feature(const_trait_impl)] +#![feature(associated_type_defaults)] + +#[const_trait] +trait Foo3 +where + Self::Baz: Clone, +{ + type Baz = T; +} + +pub fn main() {} diff --git a/tests/crashes/133275-2.rs b/tests/crashes/133275-2.rs new file mode 100644 index 0000000000000..a774b3cdb6905 --- /dev/null +++ b/tests/crashes/133275-2.rs @@ -0,0 +1,15 @@ +//@ known-bug: #133275 +#![feature(const_trait_impl)] +#[const_trait] +pub trait Owo::T> {} + +#[const_trait] +trait Foo3 +where + Self::Bar: Clone, + Self::Baz: Clone, +{ + type Bar = Vec; + type Baz = T; + //~^ ERROR the trait bound `T: Clone` is not satisfied +} diff --git a/tests/crashes/auxiliary/aux133199.rs b/tests/crashes/auxiliary/aux133199.rs new file mode 100644 index 0000000000000..40765d92fbfe9 --- /dev/null +++ b/tests/crashes/auxiliary/aux133199.rs @@ -0,0 +1,13 @@ +#![allow(incomplete_features)] +#![feature(generic_const_exprs)] + +pub struct FixedBitSet; + +impl FixedBitSet +where + [u8; N.div_ceil(8)]: Sized, +{ + pub fn new() -> Self { + todo!() + } +} From c605c84be8780e8f85379dc35f4567d6c64908d8 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 6 Nov 2024 17:53:59 +0000 Subject: [PATCH 19/20] Stabilize async closures --- compiler/rustc_ast_passes/src/feature_gate.rs | 5 -- .../src/error_codes/E0708.md | 4 -- compiler/rustc_feature/src/accepted.rs | 2 + compiler/rustc_feature/src/unstable.rs | 2 - compiler/rustc_hir_typeck/src/upvar.rs | 2 - compiler/rustc_lint/src/async_closures.rs | 4 -- .../src/coroutine/by_move_body.rs | 2 - compiler/rustc_parse/src/parser/expr.rs | 5 +- library/alloc/src/boxed.rs | 9 ++- library/alloc/src/lib.rs | 2 +- library/core/src/ops/async_function.rs | 24 +++++--- library/std/src/prelude/common.rs | 3 +- .../clippy/tests/ui/async_yields_async.fixed | 1 - .../clippy/tests/ui/async_yields_async.rs | 1 - .../clippy/tests/ui/async_yields_async.stderr | 12 ++-- src/tools/clippy/tests/ui/author/blocks.rs | 1 - src/tools/clippy/tests/ui/infinite_loops.rs | 1 - .../clippy/tests/ui/infinite_loops.stderr | 42 +++++++------- .../ui/redundant_closure_call_fixable.fixed | 1 - .../ui/redundant_closure_call_fixable.rs | 1 - .../ui/redundant_closure_call_fixable.stderr | 34 +++++------ src/tools/clippy/tests/ui/redundant_locals.rs | 2 +- .../miri/tests/pass/async-closure-captures.rs | 2 +- .../miri/tests/pass/async-closure-drop.rs | 2 +- src/tools/miri/tests/pass/async-closure.rs | 2 +- src/tools/miri/tests/pass/async-drop.rs | 2 +- tests/codegen/async-closure-debug.rs | 2 - tests/coverage/async_closure.cov-map | 24 ++++---- tests/coverage/async_closure.coverage | 1 - tests/coverage/async_closure.rs | 1 - ...0}-{closure#0}-{closure#0}.built.after.mir | 2 +- ...0}-{closure#0}-{closure#1}.built.after.mir | 2 +- ...closure#0}.coroutine_closure_by_move.0.mir | 6 +- ...0}-{closure#1}-{closure#0}.built.after.mir | 2 +- ...0}-{closure#1}-{closure#1}.built.after.mir | 2 +- ...closure#1}.coroutine_closure_by_move.0.mir | 6 +- ...{closure#1}.coroutine_closure_by_ref.0.mir | 6 +- tests/mir-opt/async_closure_shims.rs | 1 - .../auxiliary/assoc_item_trait_bounds.rs | 2 - .../async-borrowck-escaping-closure-error.rs | 1 - ...ync-borrowck-escaping-closure-error.stderr | 2 +- .../async-await/async-closure-matches-expr.rs | 2 - tests/ui/async-await/async-closure.rs | 2 - .../async-closures/ambiguous-arg.rs | 2 - .../async-closures/ambiguous-arg.stderr | 2 +- .../async-closures/arg-mismatch.rs | 2 - .../async-closures/arg-mismatch.stderr | 4 +- .../async-fn-mut-for-async-fn.rs | 2 - .../async-fn-once-for-async-fn.rs | 2 - .../async-closures/auxiliary/block-on.rs | 2 - .../async-closures/auxiliary/foreign.rs | 2 - .../await-inference-guidance.rs | 2 - .../async-closures/body-check-on-non-fnmut.rs | 2 - .../async-closures/box-deref-in-debuginfo.rs | 2 - tests/ui/async-await/async-closures/brand.rs | 2 - .../async-closures/call-once-deduction.rs | 2 +- .../ui/async-await/async-closures/captures.rs | 2 - .../async-closures/clone-closure.rs | 2 - .../closure-shim-borrowck-error.rs | 2 - .../closure-shim-borrowck-error.stderr | 4 +- .../constrained-but-no-upvars-yet.rs | 2 - .../async-closures/debuginfo-by-move-body.rs | 2 - .../ui/async-await/async-closures/def-path.rs | 2 - .../async-closures/def-path.stderr | 2 +- ...projection-lengths-for-different-upvars.rs | 2 - .../dont-ice-when-body-tainted-by-errors.rs | 2 - ...ont-ice-when-body-tainted-by-errors.stderr | 6 +- tests/ui/async-await/async-closures/drop.rs | 1 - .../fn-exception-target-features.rs | 2 +- .../async-closures/fn-exception.rs | 2 - .../async-closures/fn-exception.stderr | 8 +-- .../force-move-due-to-actually-fnonce.rs | 2 - .../force-move-due-to-inferred-kind.rs | 2 - .../ui/async-await/async-closures/foreign.rs | 2 - .../async-closures/higher-ranked-return.rs | 2 - .../higher-ranked-return.stderr | 4 +- .../async-closures/higher-ranked.rs | 2 - .../async-closures/implements-fnmut.rs | 2 - .../async-await/async-closures/inline-body.rs | 2 - tests/ui/async-await/async-closures/is-fn.rs | 2 - .../async-await/async-closures/is-not-fn.rs | 4 +- .../async-closures/is-not-fn.stderr | 8 +-- .../lint-closure-returning-async-block.rs | 1 - .../lint-closure-returning-async-block.stderr | 12 ++-- .../ui/async-await/async-closures/mac-body.rs | 2 - tests/ui/async-await/async-closures/mangle.rs | 2 - .../async-closures/moro-example.rs | 2 - .../async-closures/move-consuming-capture.rs | 2 - .../move-consuming-capture.stderr | 4 +- .../async-closures/move-is-async-fn.rs | 2 +- .../async-closures/move-out-of-ref.rs | 2 - .../async-closures/move-out-of-ref.stderr | 4 +- .../async-closures/mut-ref-reborrow.rs | 2 - tests/ui/async-await/async-closures/mutate.rs | 2 - .../async-closures/no-borrow-from-env.rs | 2 - .../non-copy-arg-does-not-force-inner-move.rs | 2 - .../async-closures/not-clone-closure.rs | 2 - .../async-closures/not-clone-closure.stderr | 8 +-- tests/ui/async-await/async-closures/not-fn.rs | 2 - .../async-await/async-closures/not-fn.stderr | 4 +- .../async-await/async-closures/not-lending.rs | 2 - .../async-closures/not-lending.stderr | 8 +-- tests/ui/async-await/async-closures/once.rs | 2 - .../async-closures/overlapping-projs.rs | 2 - .../async-closures/precise-captures.rs | 1 - .../async-closures/pretty-async-fn-opaque.rs | 4 -- .../pretty-async-fn-opaque.stderr | 2 +- tests/ui/async-await/async-closures/refd.rs | 2 - .../async-closures/return-type-mismatch.rs | 2 - .../return-type-mismatch.stderr | 2 +- .../async-closures/sig-from-bare-fn.rs | 2 - .../async-closures/signature-deduction.rs | 2 - ...signature-inference-from-two-part-bound.rs | 2 - .../async-closures/tainted-body-2.rs | 2 - .../async-closures/tainted-body-2.stderr | 2 +- .../async-closures/tainted-body.rs | 2 - .../async-closures/tainted-body.stderr | 2 +- .../truncated-fields-when-imm.rs | 2 - .../async-closures/validate-synthetic-body.rs | 2 - ...thout-precise-captures-we-are-powerless.rs | 2 - ...t-precise-captures-we-are-powerless.stderr | 20 +++---- .../async-closures/wrong-fn-kind.rs | 2 - .../async-closures/wrong-fn-kind.stderr | 6 +- tests/ui/async-await/async-drop.rs | 2 +- .../async-fn/auxiliary/block-on.rs | 2 - tests/ui/async-await/async-fn/dyn-pos.rs | 2 - tests/ui/async-await/async-fn/dyn-pos.stderr | 2 +- tests/ui/async-await/async-fn/edition-2015.rs | 2 - .../async-await/async-fn/edition-2015.stderr | 22 +------- .../async-fn/higher-ranked-async-fn.rs | 2 - tests/ui/async-await/async-fn/impl-trait.rs | 2 +- tests/ui/async-await/async-fn/project.rs | 2 +- tests/ui/async-await/async-fn/simple.rs | 2 - tests/ui/async-await/async-fn/sugar.rs | 2 +- tests/ui/async-await/coroutine-desc.rs | 1 - tests/ui/async-await/coroutine-desc.stderr | 20 +++---- tests/ui/async-await/feature-async-closure.rs | 8 --- .../async-await/feature-async-closure.stderr | 14 ----- .../issue-74072-lifetime-name-annotations.rs | 1 - ...sue-74072-lifetime-name-annotations.stderr | 20 +++---- tests/ui/async-await/issues/issue-62009-2.rs | 2 - .../async-await/issues/issue-62009-2.stderr | 2 +- .../no-params-non-move-async-closure.rs | 2 - .../suggest-missing-await-closure.fixed | 2 - .../suggest-missing-await-closure.rs | 2 - .../suggest-missing-await-closure.stderr | 6 +- .../track-caller/async-closure-gate.rs | 2 +- .../track-caller/panic-track-caller.rs | 2 +- .../ui/async-await/try-on-option-in-async.rs | 1 - .../async-await/try-on-option-in-async.stderr | 6 +- .../binder/async-closure-with-binder.rs | 1 - tests/ui/closures/local-type-mix.rs | 2 - tests/ui/closures/local-type-mix.stderr | 16 +++--- .../break-inside-coroutine-issue-124495.rs | 1 - ...break-inside-coroutine-issue-124495.stderr | 14 ++--- .../edition-keywords-2018-2015-parsing.rs | 2 - .../edition-keywords-2018-2015-parsing.stderr | 14 ++--- .../edition-keywords-2018-2018-parsing.rs | 2 - .../edition-keywords-2018-2018-parsing.stderr | 18 +++--- .../feature-gate-async-trait-bounds.rs | 1 - .../feature-gate-async-trait-bounds.stderr | 12 +--- tests/ui/issues/auxiliary/issue-111011.rs | 2 - tests/ui/layout/post-mono-layout-cycle-2.rs | 2 - .../ui/layout/post-mono-layout-cycle-2.stderr | 4 +- .../lint/unused/lint-unused-mut-variables.rs | 1 - .../unused/lint-unused-mut-variables.stderr | 56 +++++++++---------- tests/ui/lint/unused/lint-unused-variables.rs | 1 - .../lint/unused/lint-unused-variables.stderr | 24 ++++---- tests/ui/lint/unused/unused-closure.rs | 1 - tests/ui/lint/unused/unused-closure.stderr | 16 +++--- tests/ui/macros/stringify.rs | 1 - tests/ui/mir/issue-68841.rs | 2 - .../rfc-2565-param-attrs/param-attrs-cfg.rs | 1 - .../param-attrs-cfg.stderr | 40 ++++++------- tests/ui/sanitizer/cfi/async-closures.rs | 1 - ...as-arg-where-it-should-have-been-called.rs | 1 - ...rg-where-it-should-have-been-called.stderr | 14 ++--- .../suggest-boxed-empty-block.fixed | 2 - .../suggestions/suggest-boxed-empty-block.rs | 2 - .../suggest-boxed-empty-block.stderr | 4 +- .../suggest-on-bare-closure-call.rs | 2 - .../suggest-on-bare-closure-call.stderr | 4 +- tests/ui/unpretty/expanded-exhaustive.rs | 1 - tests/ui/unpretty/expanded-exhaustive.stdout | 1 - 184 files changed, 311 insertions(+), 553 deletions(-) delete mode 100644 tests/ui/async-await/feature-async-closure.rs delete mode 100644 tests/ui/async-await/feature-async-closure.stderr diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index aa3b772efb159..61a710517ea4c 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -511,11 +511,6 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) { "you can write `if matches!(, )` instead of `if let = `" ); gate_all!(let_chains, "`let` expressions in this position are unstable"); - gate_all!( - async_closure, - "async closures are unstable", - "to use an async block, remove the `||`: `async {`" - ); gate_all!( async_trait_bounds, "`async` trait bounds are unstable", diff --git a/compiler/rustc_error_codes/src/error_codes/E0708.md b/compiler/rustc_error_codes/src/error_codes/E0708.md index 61a853ac44606..f793470bafd81 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0708.md +++ b/compiler/rustc_error_codes/src/error_codes/E0708.md @@ -5,8 +5,6 @@ Erroneous code example: ```edition2018 -#![feature(async_closure)] - fn main() { let add_one = async |num: u8| { num + 1 @@ -18,8 +16,6 @@ fn main() { version, you can use successfully by using move: ```edition2018 -#![feature(async_closure)] - fn main() { let add_one = async move |num: u8| { // ok! num + 1 diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs index 53362cb252988..c5913ed27cf34 100644 --- a/compiler/rustc_feature/src/accepted.rs +++ b/compiler/rustc_feature/src/accepted.rs @@ -72,6 +72,8 @@ declare_features! ( (accepted, associated_types, "1.0.0", None), /// Allows free and inherent `async fn`s, `async` blocks, and `.await` expressions. (accepted, async_await, "1.39.0", Some(50547)), + /// Allows `async || body` closures. + (accepted, async_closure, "CURRENT_RUSTC_VERSION", Some(62290)), /// Allows async functions to be declared, implemented, and used in traits. (accepted, async_fn_in_trait, "1.75.0", Some(91611)), /// Allows all literals in attribute lists and values of key-value pairs. diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 0454d30787506..3c9115be7f592 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -388,8 +388,6 @@ declare_features! ( (unstable, associated_const_equality, "1.58.0", Some(92827)), /// Allows associated type defaults. (unstable, associated_type_defaults, "1.2.0", Some(29661)), - /// Allows `async || body` closures. - (unstable, async_closure, "1.37.0", Some(62290)), /// Allows async functions to be called from `dyn Trait`. (incomplete, async_fn_in_dyn_trait, "CURRENT_RUSTC_VERSION", Some(133119)), /// Allows `#[track_caller]` on async functions. diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs index b0c020dd7cbed..4f283644cbe1a 100644 --- a/compiler/rustc_hir_typeck/src/upvar.rs +++ b/compiler/rustc_hir_typeck/src/upvar.rs @@ -1840,7 +1840,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// captured by move. /// /// ```rust -/// #![feature(async_closure)] /// let x = &1i32; // Let's call this lifetime `'1`. /// let c = async move || { /// println!("{:?}", *x); @@ -1855,7 +1854,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// child capture with the lifetime of the parent coroutine-closure's env. /// /// ```rust -/// #![feature(async_closure)] /// let mut x = 1i32; /// let c = async || { /// x = 1; diff --git a/compiler/rustc_lint/src/async_closures.rs b/compiler/rustc_lint/src/async_closures.rs index 2a821b7110316..5d40b8ab2eedd 100644 --- a/compiler/rustc_lint/src/async_closures.rs +++ b/compiler/rustc_lint/src/async_closures.rs @@ -12,7 +12,6 @@ declare_lint! { /// ### Example /// /// ```rust - /// #![feature(async_closure)] /// #![warn(closure_returning_async_block)] /// let c = |x: &str| async {}; /// ``` @@ -40,8 +39,6 @@ declare_lint! { /// But it does work with async closures: /// /// ```rust - /// #![feature(async_closure)] - /// /// async fn callback(x: &str) {} /// /// let captured_str = String::new(); @@ -52,7 +49,6 @@ declare_lint! { pub CLOSURE_RETURNING_ASYNC_BLOCK, Allow, "closure that returns `async {}` could be rewritten as an async closure", - @feature_gate = async_closure; } declare_lint_pass!( diff --git a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs index 36eb435c63a10..ef61866e9025d 100644 --- a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs +++ b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs @@ -3,8 +3,6 @@ //! //! Consider an async closure like: //! ```rust -//! #![feature(async_closure)] -//! //! let x = vec![1, 2, 3]; //! //! let closure = async move || { diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 0904a42d8a431..44f42e5fbf285 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -2366,10 +2366,7 @@ impl<'a> Parser<'a> { }; match coroutine_kind { - Some(CoroutineKind::Async { span, .. }) => { - // Feature-gate `async ||` closures. - self.psess.gated_spans.gate(sym::async_closure, span); - } + Some(CoroutineKind::Async { .. }) => {} Some(CoroutineKind::Gen { span, .. }) | Some(CoroutineKind::AsyncGen { span, .. }) => { // Feature-gate `gen ||` and `async gen ||` closures. // FIXME(gen_blocks): This perhaps should be a different gate. diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index e0f94428cfa65..23b85fbd4ebc3 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -1985,7 +1985,8 @@ impl + ?Sized, A: Allocator> Fn for Box { } } -#[unstable(feature = "async_fn_traits", issue = "none")] +#[cfg_attr(bootstrap, unstable(feature = "async_closure", issue = "62290"))] +#[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "CURRENT_RUSTC_VERSION"))] impl + ?Sized, A: Allocator> AsyncFnOnce for Box { type Output = F::Output; type CallOnceFuture = F::CallOnceFuture; @@ -1995,7 +1996,8 @@ impl + ?Sized, A: Allocator> AsyncFnOnce } } -#[unstable(feature = "async_fn_traits", issue = "none")] +#[cfg_attr(bootstrap, unstable(feature = "async_closure", issue = "62290"))] +#[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "CURRENT_RUSTC_VERSION"))] impl + ?Sized, A: Allocator> AsyncFnMut for Box { type CallRefFuture<'a> = F::CallRefFuture<'a> @@ -2007,7 +2009,8 @@ impl + ?Sized, A: Allocator> AsyncFnMut f } } -#[unstable(feature = "async_fn_traits", issue = "none")] +#[cfg_attr(bootstrap, unstable(feature = "async_closure", issue = "62290"))] +#[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "CURRENT_RUSTC_VERSION"))] impl + ?Sized, A: Allocator> AsyncFn for Box { extern "rust-call" fn async_call(&self, args: Args) -> Self::CallRefFuture<'_> { F::async_call(self, args) diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 78cdeeb2866ef..40759cb0ba83c 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -91,6 +91,7 @@ // // Library features: // tidy-alphabetical-start +#![cfg_attr(bootstrap, feature(async_closure))] #![cfg_attr(test, feature(str_as_str))] #![feature(alloc_layout_extra)] #![feature(allocator_api)] @@ -99,7 +100,6 @@ #![feature(array_windows)] #![feature(ascii_char)] #![feature(assert_matches)] -#![feature(async_closure)] #![feature(async_fn_traits)] #![feature(async_iterator)] #![feature(box_uninit_write)] diff --git a/library/core/src/ops/async_function.rs b/library/core/src/ops/async_function.rs index 4b230b15a1e6f..0073afd496070 100644 --- a/library/core/src/ops/async_function.rs +++ b/library/core/src/ops/async_function.rs @@ -4,7 +4,8 @@ use crate::marker::Tuple; /// An async-aware version of the [`Fn`](crate::ops::Fn) trait. /// /// All `async fn` and functions returning futures implement this trait. -#[unstable(feature = "async_closure", issue = "62290")] +#[cfg_attr(bootstrap, unstable(feature = "async_closure", issue = "62290"))] +#[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "CURRENT_RUSTC_VERSION"))] #[rustc_paren_sugar] #[fundamental] #[must_use = "async closures are lazy and do nothing unless called"] @@ -18,7 +19,8 @@ pub trait AsyncFn: AsyncFnMut { /// An async-aware version of the [`FnMut`](crate::ops::FnMut) trait. /// /// All `async fn` and functions returning futures implement this trait. -#[unstable(feature = "async_closure", issue = "62290")] +#[cfg_attr(bootstrap, unstable(feature = "async_closure", issue = "62290"))] +#[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "CURRENT_RUSTC_VERSION"))] #[rustc_paren_sugar] #[fundamental] #[must_use = "async closures are lazy and do nothing unless called"] @@ -39,7 +41,8 @@ pub trait AsyncFnMut: AsyncFnOnce { /// An async-aware version of the [`FnOnce`](crate::ops::FnOnce) trait. /// /// All `async fn` and functions returning futures implement this trait. -#[unstable(feature = "async_closure", issue = "62290")] +#[cfg_attr(bootstrap, unstable(feature = "async_closure", issue = "62290"))] +#[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "CURRENT_RUSTC_VERSION"))] #[rustc_paren_sugar] #[fundamental] #[must_use = "async closures are lazy and do nothing unless called"] @@ -64,7 +67,8 @@ mod impls { use super::{AsyncFn, AsyncFnMut, AsyncFnOnce}; use crate::marker::Tuple; - #[unstable(feature = "async_fn_traits", issue = "none")] + #[cfg_attr(bootstrap, unstable(feature = "async_closure", issue = "62290"))] + #[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "CURRENT_RUSTC_VERSION"))] impl AsyncFn for &F where F: AsyncFn, @@ -74,7 +78,8 @@ mod impls { } } - #[unstable(feature = "async_fn_traits", issue = "none")] + #[cfg_attr(bootstrap, unstable(feature = "async_closure", issue = "62290"))] + #[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "CURRENT_RUSTC_VERSION"))] impl AsyncFnMut for &F where F: AsyncFn, @@ -89,7 +94,8 @@ mod impls { } } - #[unstable(feature = "async_fn_traits", issue = "none")] + #[cfg_attr(bootstrap, unstable(feature = "async_closure", issue = "62290"))] + #[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "CURRENT_RUSTC_VERSION"))] impl<'a, A: Tuple, F: ?Sized> AsyncFnOnce for &'a F where F: AsyncFn, @@ -102,7 +108,8 @@ mod impls { } } - #[unstable(feature = "async_fn_traits", issue = "none")] + #[cfg_attr(bootstrap, unstable(feature = "async_closure", issue = "62290"))] + #[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "CURRENT_RUSTC_VERSION"))] impl AsyncFnMut for &mut F where F: AsyncFnMut, @@ -117,7 +124,8 @@ mod impls { } } - #[unstable(feature = "async_fn_traits", issue = "none")] + #[cfg_attr(bootstrap, unstable(feature = "async_closure", issue = "62290"))] + #[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "CURRENT_RUSTC_VERSION"))] impl<'a, A: Tuple, F: ?Sized> AsyncFnOnce for &'a mut F where F: AsyncFnMut, diff --git a/library/std/src/prelude/common.rs b/library/std/src/prelude/common.rs index e4731280ffe35..22a364074c52d 100644 --- a/library/std/src/prelude/common.rs +++ b/library/std/src/prelude/common.rs @@ -12,7 +12,8 @@ pub use crate::marker::{Send, Sized, Sync, Unpin}; #[stable(feature = "rust1", since = "1.0.0")] #[doc(no_inline)] pub use crate::ops::{Drop, Fn, FnMut, FnOnce}; -#[unstable(feature = "async_closure", issue = "62290")] +#[cfg_attr(bootstrap, unstable(feature = "async_closure", issue = "62290"))] +#[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "CURRENT_RUSTC_VERSION"))] #[doc(no_inline)] pub use crate::ops::{AsyncFn, AsyncFnMut, AsyncFnOnce}; diff --git a/src/tools/clippy/tests/ui/async_yields_async.fixed b/src/tools/clippy/tests/ui/async_yields_async.fixed index 208651bab1fd1..48402164a827e 100644 --- a/src/tools/clippy/tests/ui/async_yields_async.fixed +++ b/src/tools/clippy/tests/ui/async_yields_async.fixed @@ -1,4 +1,3 @@ -#![feature(async_closure)] #![warn(clippy::async_yields_async)] #![allow(clippy::redundant_async_block)] diff --git a/src/tools/clippy/tests/ui/async_yields_async.rs b/src/tools/clippy/tests/ui/async_yields_async.rs index b124c994442ba..8ad016b6bb4e0 100644 --- a/src/tools/clippy/tests/ui/async_yields_async.rs +++ b/src/tools/clippy/tests/ui/async_yields_async.rs @@ -1,4 +1,3 @@ -#![feature(async_closure)] #![warn(clippy::async_yields_async)] #![allow(clippy::redundant_async_block)] diff --git a/src/tools/clippy/tests/ui/async_yields_async.stderr b/src/tools/clippy/tests/ui/async_yields_async.stderr index 861c3f2ce4a5f..c900a9d742164 100644 --- a/src/tools/clippy/tests/ui/async_yields_async.stderr +++ b/src/tools/clippy/tests/ui/async_yields_async.stderr @@ -1,5 +1,5 @@ error: an async construct yields a type which is itself awaitable - --> tests/ui/async_yields_async.rs:38:9 + --> tests/ui/async_yields_async.rs:37:9 | LL | let _h = async { | _____________________- @@ -20,7 +20,7 @@ LL + }.await | error: an async construct yields a type which is itself awaitable - --> tests/ui/async_yields_async.rs:43:9 + --> tests/ui/async_yields_async.rs:42:9 | LL | let _i = async { | ____________________- @@ -33,7 +33,7 @@ LL | | }; | |_____- outer async construct error: an async construct yields a type which is itself awaitable - --> tests/ui/async_yields_async.rs:49:9 + --> tests/ui/async_yields_async.rs:48:9 | LL | let _j = async || { | ________________________- @@ -52,7 +52,7 @@ LL + }.await | error: an async construct yields a type which is itself awaitable - --> tests/ui/async_yields_async.rs:54:9 + --> tests/ui/async_yields_async.rs:53:9 | LL | let _k = async || { | _______________________- @@ -65,7 +65,7 @@ LL | | }; | |_____- outer async construct error: an async construct yields a type which is itself awaitable - --> tests/ui/async_yields_async.rs:56:23 + --> tests/ui/async_yields_async.rs:55:23 | LL | let _l = async || CustomFutureType; | ^^^^^^^^^^^^^^^^ @@ -75,7 +75,7 @@ LL | let _l = async || CustomFutureType; | help: consider awaiting this value: `CustomFutureType.await` error: an async construct yields a type which is itself awaitable - --> tests/ui/async_yields_async.rs:62:9 + --> tests/ui/async_yields_async.rs:61:9 | LL | let _m = async || { | _______________________- diff --git a/src/tools/clippy/tests/ui/author/blocks.rs b/src/tools/clippy/tests/ui/author/blocks.rs index 164f7d0d9d6c5..e9db611a2aa90 100644 --- a/src/tools/clippy/tests/ui/author/blocks.rs +++ b/src/tools/clippy/tests/ui/author/blocks.rs @@ -2,7 +2,6 @@ #![allow(redundant_semicolons, clippy::no_effect)] #![feature(stmt_expr_attributes)] -#![feature(async_closure)] #[rustfmt::skip] fn main() { diff --git a/src/tools/clippy/tests/ui/infinite_loops.rs b/src/tools/clippy/tests/ui/infinite_loops.rs index 0613eddce2669..d7be6f9ce7e9d 100644 --- a/src/tools/clippy/tests/ui/infinite_loops.rs +++ b/src/tools/clippy/tests/ui/infinite_loops.rs @@ -3,7 +3,6 @@ #![allow(clippy::never_loop)] #![warn(clippy::infinite_loop)] -#![feature(async_closure)] extern crate proc_macros; use proc_macros::{external, with_span}; diff --git a/src/tools/clippy/tests/ui/infinite_loops.stderr b/src/tools/clippy/tests/ui/infinite_loops.stderr index 3a3ed7d0fe8f1..7635a7442f4a2 100644 --- a/src/tools/clippy/tests/ui/infinite_loops.stderr +++ b/src/tools/clippy/tests/ui/infinite_loops.stderr @@ -1,5 +1,5 @@ error: infinite loop detected - --> tests/ui/infinite_loops.rs:14:5 + --> tests/ui/infinite_loops.rs:13:5 | LL | / loop { LL | | @@ -15,7 +15,7 @@ LL | fn no_break() -> ! { | ++++ error: infinite loop detected - --> tests/ui/infinite_loops.rs:21:5 + --> tests/ui/infinite_loops.rs:20:5 | LL | / loop { LL | | @@ -32,7 +32,7 @@ LL | fn all_inf() -> ! { | ++++ error: infinite loop detected - --> tests/ui/infinite_loops.rs:23:9 + --> tests/ui/infinite_loops.rs:22:9 | LL | / loop { LL | | @@ -49,7 +49,7 @@ LL | fn all_inf() -> ! { | ++++ error: infinite loop detected - --> tests/ui/infinite_loops.rs:25:13 + --> tests/ui/infinite_loops.rs:24:13 | LL | / loop { LL | | @@ -63,7 +63,7 @@ LL | fn all_inf() -> ! { | ++++ error: infinite loop detected - --> tests/ui/infinite_loops.rs:39:5 + --> tests/ui/infinite_loops.rs:38:5 | LL | / loop { LL | | @@ -74,7 +74,7 @@ LL | | } = help: if this is not intended, try adding a `break` or `return` condition in the loop error: infinite loop detected - --> tests/ui/infinite_loops.rs:52:5 + --> tests/ui/infinite_loops.rs:51:5 | LL | / loop { LL | | fn inner_fn() -> ! { @@ -90,7 +90,7 @@ LL | fn no_break_never_ret_noise() -> ! { | ++++ error: infinite loop detected - --> tests/ui/infinite_loops.rs:95:5 + --> tests/ui/infinite_loops.rs:94:5 | LL | / loop { LL | | @@ -107,7 +107,7 @@ LL | fn break_inner_but_not_outer_1(cond: bool) -> ! { | ++++ error: infinite loop detected - --> tests/ui/infinite_loops.rs:106:5 + --> tests/ui/infinite_loops.rs:105:5 | LL | / loop { LL | | @@ -124,7 +124,7 @@ LL | fn break_inner_but_not_outer_2(cond: bool) -> ! { | ++++ error: infinite loop detected - --> tests/ui/infinite_loops.rs:120:9 + --> tests/ui/infinite_loops.rs:119:9 | LL | / loop { LL | | @@ -138,7 +138,7 @@ LL | fn break_outer_but_not_inner() -> ! { | ++++ error: infinite loop detected - --> tests/ui/infinite_loops.rs:143:9 + --> tests/ui/infinite_loops.rs:142:9 | LL | / loop { LL | | @@ -155,7 +155,7 @@ LL | fn break_wrong_loop(cond: bool) -> ! { | ++++ error: infinite loop detected - --> tests/ui/infinite_loops.rs:183:5 + --> tests/ui/infinite_loops.rs:182:5 | LL | / loop { LL | | @@ -172,7 +172,7 @@ LL | fn match_like() -> ! { | ++++ error: infinite loop detected - --> tests/ui/infinite_loops.rs:224:5 + --> tests/ui/infinite_loops.rs:223:5 | LL | / loop { LL | | @@ -186,7 +186,7 @@ LL | fn match_like() -> ! { | ++++ error: infinite loop detected - --> tests/ui/infinite_loops.rs:229:5 + --> tests/ui/infinite_loops.rs:228:5 | LL | / loop { LL | | @@ -203,7 +203,7 @@ LL | fn match_like() -> ! { | ++++ error: infinite loop detected - --> tests/ui/infinite_loops.rs:334:9 + --> tests/ui/infinite_loops.rs:333:9 | LL | / loop { LL | | @@ -217,7 +217,7 @@ LL | fn problematic_trait_method() -> ! { | ++++ error: infinite loop detected - --> tests/ui/infinite_loops.rs:344:9 + --> tests/ui/infinite_loops.rs:343:9 | LL | / loop { LL | | @@ -231,7 +231,7 @@ LL | fn could_be_problematic() -> ! { | ++++ error: infinite loop detected - --> tests/ui/infinite_loops.rs:353:9 + --> tests/ui/infinite_loops.rs:352:9 | LL | / loop { LL | | @@ -245,7 +245,7 @@ LL | let _loop_forever = || -> ! { | ++++ error: infinite loop detected - --> tests/ui/infinite_loops.rs:367:8 + --> tests/ui/infinite_loops.rs:366:8 | LL | Ok(loop { | ________^ @@ -256,7 +256,7 @@ LL | | }) = help: if this is not intended, try adding a `break` or `return` condition in the loop error: infinite loop detected - --> tests/ui/infinite_loops.rs:409:5 + --> tests/ui/infinite_loops.rs:408:5 | LL | / 'infinite: loop { LL | | @@ -272,7 +272,7 @@ LL | fn continue_outer() -> ! { | ++++ error: infinite loop detected - --> tests/ui/infinite_loops.rs:416:5 + --> tests/ui/infinite_loops.rs:415:5 | LL | / loop { LL | | @@ -289,7 +289,7 @@ LL | fn continue_outer() -> ! { | ++++ error: infinite loop detected - --> tests/ui/infinite_loops.rs:418:9 + --> tests/ui/infinite_loops.rs:417:9 | LL | / 'inner: loop { LL | | loop { @@ -304,7 +304,7 @@ LL | fn continue_outer() -> ! { | ++++ error: infinite loop detected - --> tests/ui/infinite_loops.rs:426:5 + --> tests/ui/infinite_loops.rs:425:5 | LL | / loop { LL | | diff --git a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.fixed b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.fixed index 191f7719904c1..9138a8bacfe17 100644 --- a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.fixed +++ b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.fixed @@ -1,4 +1,3 @@ -#![feature(async_closure)] #![warn(clippy::redundant_closure_call)] #![allow(clippy::redundant_async_block)] #![allow(clippy::type_complexity)] diff --git a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.rs b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.rs index 33a3b90f9cfb2..ede6fa27778be 100644 --- a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.rs +++ b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.rs @@ -1,4 +1,3 @@ -#![feature(async_closure)] #![warn(clippy::redundant_closure_call)] #![allow(clippy::redundant_async_block)] #![allow(clippy::type_complexity)] diff --git a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.stderr b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.stderr index 000d81f811f10..8e0d37df96b83 100644 --- a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.stderr +++ b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.stderr @@ -1,5 +1,5 @@ error: try not to call a closure in the expression where it is declared - --> tests/ui/redundant_closure_call_fixable.rs:16:13 + --> tests/ui/redundant_closure_call_fixable.rs:15:13 | LL | let a = (|| 42)(); | ^^^^^^^^^ help: try doing something like: `42` @@ -8,7 +8,7 @@ LL | let a = (|| 42)(); = help: to override `-D warnings` add `#[allow(clippy::redundant_closure_call)]` error: try not to call a closure in the expression where it is declared - --> tests/ui/redundant_closure_call_fixable.rs:17:13 + --> tests/ui/redundant_closure_call_fixable.rs:16:13 | LL | let b = (async || { | _____________^ @@ -28,7 +28,7 @@ LL ~ }; | error: try not to call a closure in the expression where it is declared - --> tests/ui/redundant_closure_call_fixable.rs:22:13 + --> tests/ui/redundant_closure_call_fixable.rs:21:13 | LL | let c = (|| { | _____________^ @@ -48,13 +48,13 @@ LL ~ }; | error: try not to call a closure in the expression where it is declared - --> tests/ui/redundant_closure_call_fixable.rs:27:13 + --> tests/ui/redundant_closure_call_fixable.rs:26:13 | LL | let d = (async || something().await)(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `async { something().await }` error: try not to call a closure in the expression where it is declared - --> tests/ui/redundant_closure_call_fixable.rs:36:13 + --> tests/ui/redundant_closure_call_fixable.rs:35:13 | LL | (|| m!())() | ^^^^^^^^^^^ help: try doing something like: `m!()` @@ -65,7 +65,7 @@ LL | m2!(); = note: this error originates in the macro `m2` (in Nightly builds, run with -Z macro-backtrace for more info) error: try not to call a closure in the expression where it is declared - --> tests/ui/redundant_closure_call_fixable.rs:31:13 + --> tests/ui/redundant_closure_call_fixable.rs:30:13 | LL | (|| 0)() | ^^^^^^^^ help: try doing something like: `0` @@ -76,67 +76,67 @@ LL | m2!(); = note: this error originates in the macro `m` which comes from the expansion of the macro `m2` (in Nightly builds, run with -Z macro-backtrace for more info) error: try not to call a closure in the expression where it is declared - --> tests/ui/redundant_closure_call_fixable.rs:44:16 + --> tests/ui/redundant_closure_call_fixable.rs:43:16 | LL | assert_eq!((|| || 43)()(), 42); | ^^^^^^^^^^^^^^ help: try doing something like: `43` error: try not to call a closure in the expression where it is declared - --> tests/ui/redundant_closure_call_fixable.rs:53:10 + --> tests/ui/redundant_closure_call_fixable.rs:52:10 | LL | dbg!((|| 42)()); | ^^^^^^^^^ help: try doing something like: `42` error: try not to call a closure in the expression where it is declared - --> tests/ui/redundant_closure_call_fixable.rs:56:13 + --> tests/ui/redundant_closure_call_fixable.rs:55:13 | LL | let a = (|| || || 123)(); | ^^^^^^^^^^^^^^^^ help: try doing something like: `(|| || 123)` error: try not to call a closure in the expression where it is declared - --> tests/ui/redundant_closure_call_fixable.rs:60:13 + --> tests/ui/redundant_closure_call_fixable.rs:59:13 | LL | let a = (|| || || || async || 1)()()()()(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `async { 1 }` error: try not to call a closure in the expression where it is declared - --> tests/ui/redundant_closure_call_fixable.rs:69:13 + --> tests/ui/redundant_closure_call_fixable.rs:68:13 | LL | let a = (|| echo!(|| echo!(|| 1)))()()(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `1` error: try not to call a closure in the expression where it is declared - --> tests/ui/redundant_closure_call_fixable.rs:71:13 + --> tests/ui/redundant_closure_call_fixable.rs:70:13 | LL | let a = (|| echo!((|| 123)))()(); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `123` error: try not to call a closure in the expression where it is declared - --> tests/ui/redundant_closure_call_fixable.rs:84:11 + --> tests/ui/redundant_closure_call_fixable.rs:83:11 | LL | bar()((|| || 42)()(), 5); | ^^^^^^^^^^^^^^ help: try doing something like: `42` error: try not to call a closure in the expression where it is declared - --> tests/ui/redundant_closure_call_fixable.rs:85:9 + --> tests/ui/redundant_closure_call_fixable.rs:84:9 | LL | foo((|| || 42)()(), 5); | ^^^^^^^^^^^^^^ help: try doing something like: `42` error: try not to call a closure in the expression where it is declared - --> tests/ui/redundant_closure_call_fixable.rs:89:5 + --> tests/ui/redundant_closure_call_fixable.rs:88:5 | LL | (|| async {})().await; | ^^^^^^^^^^^^^^^ help: try doing something like: `async {}` error: try not to call a closure in the expression where it is declared - --> tests/ui/redundant_closure_call_fixable.rs:98:18 + --> tests/ui/redundant_closure_call_fixable.rs:97:18 | LL | spawn_on((|| async move {})()); | ^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `async move {}` error: try not to call a closure in the expression where it is declared - --> tests/ui/redundant_closure_call_fixable.rs:103:28 + --> tests/ui/redundant_closure_call_fixable.rs:102:28 | LL | std::convert::identity((|| 13_i32 + 36_i32)()).leading_zeros(); | ^^^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `13_i32 + 36_i32` diff --git a/src/tools/clippy/tests/ui/redundant_locals.rs b/src/tools/clippy/tests/ui/redundant_locals.rs index d21aa240b2df9..3e7695106a7f1 100644 --- a/src/tools/clippy/tests/ui/redundant_locals.rs +++ b/src/tools/clippy/tests/ui/redundant_locals.rs @@ -1,7 +1,7 @@ //@aux-build:proc_macros.rs #![allow(unused, clippy::no_effect, clippy::needless_pass_by_ref_mut)] #![warn(clippy::redundant_locals)] -#![feature(async_closure, coroutines, stmt_expr_attributes)] +#![feature(coroutines, stmt_expr_attributes)] extern crate proc_macros; use proc_macros::{external, with_span}; diff --git a/src/tools/miri/tests/pass/async-closure-captures.rs b/src/tools/miri/tests/pass/async-closure-captures.rs index 979a6d1cbe0e0..ed6b7b205b540 100644 --- a/src/tools/miri/tests/pass/async-closure-captures.rs +++ b/src/tools/miri/tests/pass/async-closure-captures.rs @@ -1,6 +1,6 @@ // Same as rustc's `tests/ui/async-await/async-closures/captures.rs`, keep in sync -#![feature(async_closure, async_trait_bounds)] +#![feature(async_trait_bounds)] use std::future::Future; use std::pin::pin; diff --git a/src/tools/miri/tests/pass/async-closure-drop.rs b/src/tools/miri/tests/pass/async-closure-drop.rs index ad9822fa46d1a..105aa434b0ad9 100644 --- a/src/tools/miri/tests/pass/async-closure-drop.rs +++ b/src/tools/miri/tests/pass/async-closure-drop.rs @@ -1,4 +1,4 @@ -#![feature(async_closure, async_trait_bounds)] +#![feature(async_fn_traits, async_trait_bounds)] use std::future::Future; use std::pin::pin; diff --git a/src/tools/miri/tests/pass/async-closure.rs b/src/tools/miri/tests/pass/async-closure.rs index 979b83687e405..4c0fb356f9db7 100644 --- a/src/tools/miri/tests/pass/async-closure.rs +++ b/src/tools/miri/tests/pass/async-closure.rs @@ -1,4 +1,4 @@ -#![feature(async_closure, async_fn_traits)] +#![feature(async_fn_traits)] #![allow(unused)] use std::future::Future; diff --git a/src/tools/miri/tests/pass/async-drop.rs b/src/tools/miri/tests/pass/async-drop.rs index a455f377e8581..6d556b77795d9 100644 --- a/src/tools/miri/tests/pass/async-drop.rs +++ b/src/tools/miri/tests/pass/async-drop.rs @@ -6,7 +6,7 @@ // please consider modifying rustc's async drop test at // `tests/ui/async-await/async-drop.rs`. -#![feature(async_drop, impl_trait_in_assoc_type, async_closure)] +#![feature(async_drop, impl_trait_in_assoc_type)] #![allow(incomplete_features, dead_code)] // FIXME(zetanumbers): consider AsyncDestruct::async_drop cleanup tests diff --git a/tests/codegen/async-closure-debug.rs b/tests/codegen/async-closure-debug.rs index 644df169a368f..2d67e02eb9ca8 100644 --- a/tests/codegen/async-closure-debug.rs +++ b/tests/codegen/async-closure-debug.rs @@ -7,8 +7,6 @@ // CHECK-DAG: [[CLOSURE:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "{closure_env#0}", scope: [[GEN_FN]] // CHECK-DAG: [[UPVAR:!.*]] = !DIDerivedType(tag: DW_TAG_member, name: "upvar", scope: [[CLOSURE]] -#![feature(async_closure)] - fn async_closure_test(upvar: &str) -> impl AsyncFn() + '_ { async move || { let hello = String::from("hello"); diff --git a/tests/coverage/async_closure.cov-map b/tests/coverage/async_closure.cov-map index 9ff29af8e8ec3..04c05ba098b40 100644 --- a/tests/coverage/async_closure.cov-map +++ b/tests/coverage/async_closure.cov-map @@ -1,56 +1,56 @@ Function name: async_closure::call_once:: -Raw bytes (9): 0x[01, 01, 00, 01, 01, 07, 01, 00, 2b] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 06, 01, 00, 2b] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 7, 1) to (start + 0, 43) +- Code(Counter(0)) at (prev + 6, 1) to (start + 0, 43) Highest counter ID seen: c0 Function name: async_closure::call_once::::{closure#0} -Raw bytes (14): 0x[01, 01, 00, 02, 01, 07, 2b, 01, 0e, 05, 02, 01, 00, 02] +Raw bytes (14): 0x[01, 01, 00, 02, 01, 06, 2b, 01, 0e, 05, 02, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 2 -- Code(Counter(0)) at (prev + 7, 43) to (start + 1, 14) +- Code(Counter(0)) at (prev + 6, 43) to (start + 1, 14) - Code(Counter(1)) at (prev + 2, 1) to (start + 0, 2) Highest counter ID seen: c1 Function name: async_closure::main -Raw bytes (14): 0x[01, 01, 00, 02, 01, 0b, 01, 01, 16, 01, 02, 05, 02, 02] +Raw bytes (14): 0x[01, 01, 00, 02, 01, 0a, 01, 01, 16, 01, 02, 05, 02, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 2 -- Code(Counter(0)) at (prev + 11, 1) to (start + 1, 22) +- Code(Counter(0)) at (prev + 10, 1) to (start + 1, 22) - Code(Counter(0)) at (prev + 2, 5) to (start + 2, 2) Highest counter ID seen: c0 Function name: async_closure::main::{closure#0} -Raw bytes (9): 0x[01, 01, 00, 01, 01, 0c, 23, 00, 24] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 0b, 23, 00, 24] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 12, 35) to (start + 0, 36) +- Code(Counter(0)) at (prev + 11, 35) to (start + 0, 36) Highest counter ID seen: c0 Function name: async_closure::main::{closure#0}::{closure#0}:: -Raw bytes (9): 0x[01, 01, 00, 01, 01, 0c, 22, 00, 24] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 0b, 22, 00, 24] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 12, 34) to (start + 0, 36) +- Code(Counter(0)) at (prev + 11, 34) to (start + 0, 36) Highest counter ID seen: c0 Function name: async_closure::main::{closure#0}::{closure#1}:: -Raw bytes (9): 0x[01, 01, 00, 01, 01, 0c, 23, 00, 24] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 0b, 23, 00, 24] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 12, 35) to (start + 0, 36) +- Code(Counter(0)) at (prev + 11, 35) to (start + 0, 36) Highest counter ID seen: c0 diff --git a/tests/coverage/async_closure.coverage b/tests/coverage/async_closure.coverage index 75da1a01fc1db..7fbea26581258 100644 --- a/tests/coverage/async_closure.coverage +++ b/tests/coverage/async_closure.coverage @@ -1,4 +1,3 @@ - LL| |#![feature(async_closure)] LL| |//@ edition: 2021 LL| | LL| |//@ aux-build: executor.rs diff --git a/tests/coverage/async_closure.rs b/tests/coverage/async_closure.rs index cbac592d95778..85c5df1f1abb8 100644 --- a/tests/coverage/async_closure.rs +++ b/tests/coverage/async_closure.rs @@ -1,4 +1,3 @@ -#![feature(async_closure)] //@ edition: 2021 //@ aux-build: executor.rs diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.built.after.mir b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.built.after.mir index 7da33b8a094b3..8a584853e0009 100644 --- a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.built.after.mir +++ b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.built.after.mir @@ -1,6 +1,6 @@ // MIR for `main::{closure#0}::{closure#0}::{closure#0}` after built -fn main::{closure#0}::{closure#0}::{closure#0}(_1: {async closure body@$DIR/async_closure_shims.rs:54:53: 57:10}, _2: ResumeTy) -> () +fn main::{closure#0}::{closure#0}::{closure#0}(_1: {async closure body@$DIR/async_closure_shims.rs:53:53: 56:10}, _2: ResumeTy) -> () yields () { debug _task_context => _2; diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#1}.built.after.mir b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#1}.built.after.mir index a21e82ef5b633..a9e08d2e8f60f 100644 --- a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#1}.built.after.mir +++ b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#1}.built.after.mir @@ -1,6 +1,6 @@ // MIR for `main::{closure#0}::{closure#0}::{closure#1}` after built -fn main::{closure#0}::{closure#0}::{closure#1}(_1: {async closure body@$DIR/async_closure_shims.rs:54:53: 57:10}, _2: ResumeTy) -> () +fn main::{closure#0}::{closure#0}::{closure#1}(_1: {async closure body@$DIR/async_closure_shims.rs:53:53: 56:10}, _2: ResumeTy) -> () yields () { debug _task_context => _2; diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_move.0.mir b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_move.0.mir index c156636099519..a984845fd2c11 100644 --- a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_move.0.mir +++ b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_move.0.mir @@ -1,10 +1,10 @@ // MIR for `main::{closure#0}::{closure#0}` 0 coroutine_closure_by_move -fn main::{closure#0}::{closure#0}(_1: {async closure@$DIR/async_closure_shims.rs:54:33: 54:52}, _2: i32) -> {async closure body@$DIR/async_closure_shims.rs:54:53: 57:10} { - let mut _0: {async closure body@$DIR/async_closure_shims.rs:54:53: 57:10}; +fn main::{closure#0}::{closure#0}(_1: {async closure@$DIR/async_closure_shims.rs:53:33: 53:52}, _2: i32) -> {async closure body@$DIR/async_closure_shims.rs:53:53: 56:10} { + let mut _0: {async closure body@$DIR/async_closure_shims.rs:53:53: 56:10}; bb0: { - _0 = {coroutine@$DIR/async_closure_shims.rs:54:53: 57:10 (#0)} { a: move _2, b: move (_1.0: i32) }; + _0 = {coroutine@$DIR/async_closure_shims.rs:53:53: 56:10 (#0)} { a: move _2, b: move (_1.0: i32) }; return; } } diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{closure#0}.built.after.mir b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{closure#0}.built.after.mir index a4a6a535a2313..c6721085eb2e1 100644 --- a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{closure#0}.built.after.mir +++ b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{closure#0}.built.after.mir @@ -1,6 +1,6 @@ // MIR for `main::{closure#0}::{closure#1}::{closure#0}` after built -fn main::{closure#0}::{closure#1}::{closure#0}(_1: {async closure body@$DIR/async_closure_shims.rs:63:48: 66:10}, _2: ResumeTy) -> () +fn main::{closure#0}::{closure#1}::{closure#0}(_1: {async closure body@$DIR/async_closure_shims.rs:62:48: 65:10}, _2: ResumeTy) -> () yields () { debug _task_context => _2; diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{closure#1}.built.after.mir b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{closure#1}.built.after.mir index 69bba6f519414..4452ae7812e36 100644 --- a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{closure#1}.built.after.mir +++ b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{closure#1}.built.after.mir @@ -1,6 +1,6 @@ // MIR for `main::{closure#0}::{closure#1}::{closure#1}` after built -fn main::{closure#0}::{closure#1}::{closure#1}(_1: {async closure body@$DIR/async_closure_shims.rs:63:48: 66:10}, _2: ResumeTy) -> () +fn main::{closure#0}::{closure#1}::{closure#1}(_1: {async closure body@$DIR/async_closure_shims.rs:62:48: 65:10}, _2: ResumeTy) -> () yields () { debug _task_context => _2; diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_move.0.mir b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_move.0.mir index 134fe145baeee..aab9f7b03b9ab 100644 --- a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_move.0.mir +++ b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_move.0.mir @@ -1,10 +1,10 @@ // MIR for `main::{closure#0}::{closure#1}` 0 coroutine_closure_by_move -fn main::{closure#0}::{closure#1}(_1: {async closure@$DIR/async_closure_shims.rs:63:33: 63:47}, _2: i32) -> {async closure body@$DIR/async_closure_shims.rs:63:48: 66:10} { - let mut _0: {async closure body@$DIR/async_closure_shims.rs:63:48: 66:10}; +fn main::{closure#0}::{closure#1}(_1: {async closure@$DIR/async_closure_shims.rs:62:33: 62:47}, _2: i32) -> {async closure body@$DIR/async_closure_shims.rs:62:48: 65:10} { + let mut _0: {async closure body@$DIR/async_closure_shims.rs:62:48: 65:10}; bb0: { - _0 = {coroutine@$DIR/async_closure_shims.rs:63:48: 66:10 (#0)} { a: move _2, b: move (_1.0: &i32) }; + _0 = {coroutine@$DIR/async_closure_shims.rs:62:48: 65:10 (#0)} { a: move _2, b: move (_1.0: &i32) }; return; } } diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_ref.0.mir b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_ref.0.mir index f267d93bd606c..3fdc81791deef 100644 --- a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_ref.0.mir +++ b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_ref.0.mir @@ -1,10 +1,10 @@ // MIR for `main::{closure#0}::{closure#1}` 0 coroutine_closure_by_ref -fn main::{closure#0}::{closure#1}(_1: &{async closure@$DIR/async_closure_shims.rs:63:33: 63:47}, _2: i32) -> {async closure body@$DIR/async_closure_shims.rs:63:48: 66:10} { - let mut _0: {async closure body@$DIR/async_closure_shims.rs:63:48: 66:10}; +fn main::{closure#0}::{closure#1}(_1: &{async closure@$DIR/async_closure_shims.rs:62:33: 62:47}, _2: i32) -> {async closure body@$DIR/async_closure_shims.rs:62:48: 65:10} { + let mut _0: {async closure body@$DIR/async_closure_shims.rs:62:48: 65:10}; bb0: { - _0 = {coroutine@$DIR/async_closure_shims.rs:63:48: 66:10 (#0)} { a: move _2, b: copy ((*_1).0: &i32) }; + _0 = {coroutine@$DIR/async_closure_shims.rs:62:48: 65:10 (#0)} { a: move _2, b: copy ((*_1).0: &i32) }; return; } } diff --git a/tests/mir-opt/async_closure_shims.rs b/tests/mir-opt/async_closure_shims.rs index f28400e298f70..cd2e83e939abe 100644 --- a/tests/mir-opt/async_closure_shims.rs +++ b/tests/mir-opt/async_closure_shims.rs @@ -1,7 +1,6 @@ //@ edition:2021 // skip-filecheck -#![feature(async_closure, async_fn_traits)] #![allow(unused)] use std::future::Future; diff --git a/tests/rustdoc/inline_cross/auxiliary/assoc_item_trait_bounds.rs b/tests/rustdoc/inline_cross/auxiliary/assoc_item_trait_bounds.rs index 56708ec9310e8..6ab3cc6f6fe3a 100644 --- a/tests/rustdoc/inline_cross/auxiliary/assoc_item_trait_bounds.rs +++ b/tests/rustdoc/inline_cross/auxiliary/assoc_item_trait_bounds.rs @@ -1,5 +1,3 @@ -#![feature(async_closure)] - use std::ops::AsyncFnMut; pub trait Main { diff --git a/tests/ui/async-await/async-borrowck-escaping-closure-error.rs b/tests/ui/async-await/async-borrowck-escaping-closure-error.rs index ffb97ca04ac50..4489f344e6f2e 100644 --- a/tests/ui/async-await/async-borrowck-escaping-closure-error.rs +++ b/tests/ui/async-await/async-borrowck-escaping-closure-error.rs @@ -1,6 +1,5 @@ //@ edition:2018 -#![feature(async_closure)] fn foo() -> Box> { let x = 0u32; Box::new((async || x)()) diff --git a/tests/ui/async-await/async-borrowck-escaping-closure-error.stderr b/tests/ui/async-await/async-borrowck-escaping-closure-error.stderr index 4b1ce300b5692..967b3bf5a7707 100644 --- a/tests/ui/async-await/async-borrowck-escaping-closure-error.stderr +++ b/tests/ui/async-await/async-borrowck-escaping-closure-error.stderr @@ -1,5 +1,5 @@ error[E0515]: cannot return value referencing local variable `x` - --> $DIR/async-borrowck-escaping-closure-error.rs:6:5 + --> $DIR/async-borrowck-escaping-closure-error.rs:5:5 | LL | Box::new((async || x)()) | ^^^^^^^^^------------^^^ diff --git a/tests/ui/async-await/async-closure-matches-expr.rs b/tests/ui/async-await/async-closure-matches-expr.rs index 75ce14a4947c0..3f1c70e691c64 100644 --- a/tests/ui/async-await/async-closure-matches-expr.rs +++ b/tests/ui/async-await/async-closure-matches-expr.rs @@ -1,8 +1,6 @@ //@ build-pass //@ edition:2018 -#![feature(async_closure)] - macro_rules! match_expr { ($x:expr) => {} } diff --git a/tests/ui/async-await/async-closure.rs b/tests/ui/async-await/async-closure.rs index 77c00bbdc9f8d..3dd88fbf7393a 100644 --- a/tests/ui/async-await/async-closure.rs +++ b/tests/ui/async-await/async-closure.rs @@ -6,8 +6,6 @@ //@ edition:2018 //@ aux-build:arc_wake.rs -#![feature(async_closure)] - extern crate arc_wake; use std::pin::Pin; diff --git a/tests/ui/async-await/async-closures/ambiguous-arg.rs b/tests/ui/async-await/async-closures/ambiguous-arg.rs index d76a1cf953e46..e8e6ff6d97c83 100644 --- a/tests/ui/async-await/async-closures/ambiguous-arg.rs +++ b/tests/ui/async-await/async-closures/ambiguous-arg.rs @@ -3,8 +3,6 @@ // Regression test for #123901. We previously ICE'd as we silently // swallowed an in the `ExprUseVisitor`. -#![feature(async_closure)] - pub fn test(test: &u64, temp: &u64) { async |check, a, b| { //~^ ERROR type annotations needed diff --git a/tests/ui/async-await/async-closures/ambiguous-arg.stderr b/tests/ui/async-await/async-closures/ambiguous-arg.stderr index 01f72e94eccf7..adb71d676dc5a 100644 --- a/tests/ui/async-await/async-closures/ambiguous-arg.stderr +++ b/tests/ui/async-await/async-closures/ambiguous-arg.stderr @@ -1,5 +1,5 @@ error[E0282]: type annotations needed - --> $DIR/ambiguous-arg.rs:9:25 + --> $DIR/ambiguous-arg.rs:7:25 | LL | async |check, a, b| { | _________________________^ diff --git a/tests/ui/async-await/async-closures/arg-mismatch.rs b/tests/ui/async-await/async-closures/arg-mismatch.rs index c8dddee6275e5..f69c8122d1d7a 100644 --- a/tests/ui/async-await/async-closures/arg-mismatch.rs +++ b/tests/ui/async-await/async-closures/arg-mismatch.rs @@ -1,8 +1,6 @@ //@ aux-build:block-on.rs //@ edition:2021 -#![feature(async_closure)] - extern crate block_on; fn main() { diff --git a/tests/ui/async-await/async-closures/arg-mismatch.stderr b/tests/ui/async-await/async-closures/arg-mismatch.stderr index 70853ae28156f..5c8e665029381 100644 --- a/tests/ui/async-await/async-closures/arg-mismatch.stderr +++ b/tests/ui/async-await/async-closures/arg-mismatch.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/arg-mismatch.rs:12:11 + --> $DIR/arg-mismatch.rs:10:11 | LL | c(2usize).await; | - ^^^^^^ expected `i32`, found `usize` @@ -7,7 +7,7 @@ LL | c(2usize).await; | arguments to this function are incorrect | note: closure parameter defined here - --> $DIR/arg-mismatch.rs:10:24 + --> $DIR/arg-mismatch.rs:8:24 | LL | let c = async |x| {}; | ^ diff --git a/tests/ui/async-await/async-closures/async-fn-mut-for-async-fn.rs b/tests/ui/async-await/async-closures/async-fn-mut-for-async-fn.rs index 8309cfbd58f1a..e739230fd468e 100644 --- a/tests/ui/async-await/async-closures/async-fn-mut-for-async-fn.rs +++ b/tests/ui/async-await/async-closures/async-fn-mut-for-async-fn.rs @@ -2,8 +2,6 @@ //@ edition:2021 //@ run-pass -#![feature(async_closure)] - extern crate block_on; fn main() { diff --git a/tests/ui/async-await/async-closures/async-fn-once-for-async-fn.rs b/tests/ui/async-await/async-closures/async-fn-once-for-async-fn.rs index e7644e3dfe023..078348eb4e6f2 100644 --- a/tests/ui/async-await/async-closures/async-fn-once-for-async-fn.rs +++ b/tests/ui/async-await/async-closures/async-fn-once-for-async-fn.rs @@ -2,8 +2,6 @@ //@ edition:2021 //@ run-pass -#![feature(async_closure)] - extern crate block_on; fn main() { diff --git a/tests/ui/async-await/async-closures/auxiliary/block-on.rs b/tests/ui/async-await/async-closures/auxiliary/block-on.rs index 8b50c5571c145..4ec45ddf33359 100644 --- a/tests/ui/async-await/async-closures/auxiliary/block-on.rs +++ b/tests/ui/async-await/async-closures/auxiliary/block-on.rs @@ -1,7 +1,5 @@ //@ edition: 2021 -#![feature(async_closure)] - use std::future::Future; use std::pin::pin; use std::task::*; diff --git a/tests/ui/async-await/async-closures/auxiliary/foreign.rs b/tests/ui/async-await/async-closures/auxiliary/foreign.rs index 33548a1b30dd9..935b029a7c5ad 100644 --- a/tests/ui/async-await/async-closures/auxiliary/foreign.rs +++ b/tests/ui/async-await/async-closures/auxiliary/foreign.rs @@ -1,7 +1,5 @@ //@ edition:2021 -#![feature(async_closure)] - pub fn closure() -> impl AsyncFn() { async || { /* Don't really need to do anything here. */ } } diff --git a/tests/ui/async-await/async-closures/await-inference-guidance.rs b/tests/ui/async-await/async-closures/await-inference-guidance.rs index 1ddc1f8d1c5d3..f4f91e2e0735a 100644 --- a/tests/ui/async-await/async-closures/await-inference-guidance.rs +++ b/tests/ui/async-await/async-closures/await-inference-guidance.rs @@ -2,8 +2,6 @@ //@ edition:2021 //@ run-pass -#![feature(async_closure)] - extern crate block_on; fn main() { diff --git a/tests/ui/async-await/async-closures/body-check-on-non-fnmut.rs b/tests/ui/async-await/async-closures/body-check-on-non-fnmut.rs index a72ff8e5dce6e..0560d3b0867cf 100644 --- a/tests/ui/async-await/async-closures/body-check-on-non-fnmut.rs +++ b/tests/ui/async-await/async-closures/body-check-on-non-fnmut.rs @@ -2,8 +2,6 @@ //@ edition:2021 //@ build-pass -#![feature(async_closure)] - extern crate block_on; // Make sure that we don't call `coroutine_by_move_body_def_id` query diff --git a/tests/ui/async-await/async-closures/box-deref-in-debuginfo.rs b/tests/ui/async-await/async-closures/box-deref-in-debuginfo.rs index 5ec1c5ee50ea5..10f7636720cce 100644 --- a/tests/ui/async-await/async-closures/box-deref-in-debuginfo.rs +++ b/tests/ui/async-await/async-closures/box-deref-in-debuginfo.rs @@ -2,8 +2,6 @@ //@ edition:2021 //@ run-pass -#![feature(async_closure)] - extern crate block_on; pub trait Trait { diff --git a/tests/ui/async-await/async-closures/brand.rs b/tests/ui/async-await/async-closures/brand.rs index db1f5d271c6cf..3b13506cf0095 100644 --- a/tests/ui/async-await/async-closures/brand.rs +++ b/tests/ui/async-await/async-closures/brand.rs @@ -2,8 +2,6 @@ //@ edition:2021 //@ build-pass -#![feature(async_closure)] - extern crate block_on; use std::future::Future; diff --git a/tests/ui/async-await/async-closures/call-once-deduction.rs b/tests/ui/async-await/async-closures/call-once-deduction.rs index 41d92bc3d786c..ed2830a5e8297 100644 --- a/tests/ui/async-await/async-closures/call-once-deduction.rs +++ b/tests/ui/async-await/async-closures/call-once-deduction.rs @@ -1,7 +1,7 @@ //@ edition: 2021 //@ check-pass -#![feature(async_closure, async_fn_traits, unboxed_closures)] +#![feature(async_fn_traits, unboxed_closures)] fn bar(_: F) where diff --git a/tests/ui/async-await/async-closures/captures.rs b/tests/ui/async-await/async-closures/captures.rs index 2bd4b68599793..296fca6cb86fe 100644 --- a/tests/ui/async-await/async-closures/captures.rs +++ b/tests/ui/async-await/async-closures/captures.rs @@ -5,8 +5,6 @@ // Same as miri's `tests/pass/async-closure-captures.rs`, keep in sync -#![feature(async_closure)] - extern crate block_on; fn main() { diff --git a/tests/ui/async-await/async-closures/clone-closure.rs b/tests/ui/async-await/async-closures/clone-closure.rs index a9e1d6bccc772..b637ab45b9af9 100644 --- a/tests/ui/async-await/async-closures/clone-closure.rs +++ b/tests/ui/async-await/async-closures/clone-closure.rs @@ -3,8 +3,6 @@ //@ run-pass //@ check-run-results -#![feature(async_closure)] - extern crate block_on; async fn for_each(f: impl AsyncFnOnce(&str) + Clone) { diff --git a/tests/ui/async-await/async-closures/closure-shim-borrowck-error.rs b/tests/ui/async-await/async-closures/closure-shim-borrowck-error.rs index 4cbbefb0f5298..069744a3282df 100644 --- a/tests/ui/async-await/async-closures/closure-shim-borrowck-error.rs +++ b/tests/ui/async-await/async-closures/closure-shim-borrowck-error.rs @@ -1,7 +1,5 @@ //@ compile-flags: -Zvalidate-mir --edition=2018 --crate-type=lib -Copt-level=3 -#![feature(async_closure)] - fn main() {} fn needs_fn_mut(mut x: impl FnMut() -> T) { diff --git a/tests/ui/async-await/async-closures/closure-shim-borrowck-error.stderr b/tests/ui/async-await/async-closures/closure-shim-borrowck-error.stderr index bab26c1948217..52697bac50985 100644 --- a/tests/ui/async-await/async-closures/closure-shim-borrowck-error.stderr +++ b/tests/ui/async-await/async-closures/closure-shim-borrowck-error.stderr @@ -1,5 +1,5 @@ error[E0507]: cannot move out of `x` which is behind a mutable reference - --> $DIR/closure-shim-borrowck-error.rs:12:18 + --> $DIR/closure-shim-borrowck-error.rs:10:18 | LL | needs_fn_mut(async || { | ^^^^^^^^ `x` is moved here @@ -11,7 +11,7 @@ LL | x.hello(); | move occurs because `x` has type `Ty`, which does not implement the `Copy` trait | note: if `Ty` implemented `Clone`, you could clone the value - --> $DIR/closure-shim-borrowck-error.rs:18:1 + --> $DIR/closure-shim-borrowck-error.rs:16:1 | LL | x.hello(); | - you could clone this value diff --git a/tests/ui/async-await/async-closures/constrained-but-no-upvars-yet.rs b/tests/ui/async-await/async-closures/constrained-but-no-upvars-yet.rs index 1acbf0311b3aa..993f83784393f 100644 --- a/tests/ui/async-await/async-closures/constrained-but-no-upvars-yet.rs +++ b/tests/ui/async-await/async-closures/constrained-but-no-upvars-yet.rs @@ -4,8 +4,6 @@ //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver -#![feature(async_closure)] - fn constrain(t: T) -> T { t } diff --git a/tests/ui/async-await/async-closures/debuginfo-by-move-body.rs b/tests/ui/async-await/async-closures/debuginfo-by-move-body.rs index f71cc1ef537a8..a1d6ce259e231 100644 --- a/tests/ui/async-await/async-closures/debuginfo-by-move-body.rs +++ b/tests/ui/async-await/async-closures/debuginfo-by-move-body.rs @@ -3,8 +3,6 @@ //@ build-pass //@ compile-flags: -Cdebuginfo=2 -#![feature(async_closure)] - extern crate block_on; async fn call_once(f: impl AsyncFnOnce()) { diff --git a/tests/ui/async-await/async-closures/def-path.rs b/tests/ui/async-await/async-closures/def-path.rs index 70450697816fe..838556966e865 100644 --- a/tests/ui/async-await/async-closures/def-path.rs +++ b/tests/ui/async-await/async-closures/def-path.rs @@ -1,8 +1,6 @@ //@ compile-flags: -Zverbose-internals //@ edition:2021 -#![feature(async_closure)] - fn main() { let x = async || {}; //~^ NOTE the expected `async` closure body diff --git a/tests/ui/async-await/async-closures/def-path.stderr b/tests/ui/async-await/async-closures/def-path.stderr index 0a1e30c1253f3..cf25b2d2d2328 100644 --- a/tests/ui/async-await/async-closures/def-path.stderr +++ b/tests/ui/async-await/async-closures/def-path.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/def-path.rs:9:9 + --> $DIR/def-path.rs:7:9 | LL | let x = async || {}; | -- the expected `async` closure body diff --git a/tests/ui/async-await/async-closures/different-projection-lengths-for-different-upvars.rs b/tests/ui/async-await/async-closures/different-projection-lengths-for-different-upvars.rs index 2313db506bea3..d40c9548a3a8e 100644 --- a/tests/ui/async-await/async-closures/different-projection-lengths-for-different-upvars.rs +++ b/tests/ui/async-await/async-closures/different-projection-lengths-for-different-upvars.rs @@ -2,8 +2,6 @@ //@ edition: 2021 // issue: rust-lang/rust#123697 -#![feature(async_closure)] - struct S { t: i32 } fn test(s: &S, t: &i32) { diff --git a/tests/ui/async-await/async-closures/dont-ice-when-body-tainted-by-errors.rs b/tests/ui/async-await/async-closures/dont-ice-when-body-tainted-by-errors.rs index 8fc9924a12fb0..f90d10ebe854b 100644 --- a/tests/ui/async-await/async-closures/dont-ice-when-body-tainted-by-errors.rs +++ b/tests/ui/async-await/async-closures/dont-ice-when-body-tainted-by-errors.rs @@ -1,7 +1,5 @@ //@ edition: 2021 -#![feature(async_closure)] - struct DropMe; trait Impossible {} diff --git a/tests/ui/async-await/async-closures/dont-ice-when-body-tainted-by-errors.stderr b/tests/ui/async-await/async-closures/dont-ice-when-body-tainted-by-errors.stderr index b4dc3e268bdaf..c93c1732a2217 100644 --- a/tests/ui/async-await/async-closures/dont-ice-when-body-tainted-by-errors.stderr +++ b/tests/ui/async-await/async-closures/dont-ice-when-body-tainted-by-errors.stderr @@ -1,16 +1,16 @@ error[E0277]: the trait bound `(): Impossible` is not satisfied - --> $DIR/dont-ice-when-body-tainted-by-errors.rs:19:23 + --> $DIR/dont-ice-when-body-tainted-by-errors.rs:17:23 | LL | trait_error::<()>(); | ^^ the trait `Impossible` is not implemented for `()` | help: this trait has no implementations, consider adding one - --> $DIR/dont-ice-when-body-tainted-by-errors.rs:7:1 + --> $DIR/dont-ice-when-body-tainted-by-errors.rs:5:1 | LL | trait Impossible {} | ^^^^^^^^^^^^^^^^ note: required by a bound in `trait_error` - --> $DIR/dont-ice-when-body-tainted-by-errors.rs:8:19 + --> $DIR/dont-ice-when-body-tainted-by-errors.rs:6:19 | LL | fn trait_error() {} | ^^^^^^^^^^ required by this bound in `trait_error` diff --git a/tests/ui/async-await/async-closures/drop.rs b/tests/ui/async-await/async-closures/drop.rs index 9c99550e3b7b2..24c182d2c2db9 100644 --- a/tests/ui/async-await/async-closures/drop.rs +++ b/tests/ui/async-await/async-closures/drop.rs @@ -3,7 +3,6 @@ //@ run-pass //@ check-run-results -#![feature(async_closure)] #![allow(unused)] extern crate block_on; diff --git a/tests/ui/async-await/async-closures/fn-exception-target-features.rs b/tests/ui/async-await/async-closures/fn-exception-target-features.rs index eb554650b7c9f..82fc776fd2c72 100644 --- a/tests/ui/async-await/async-closures/fn-exception-target-features.rs +++ b/tests/ui/async-await/async-closures/fn-exception-target-features.rs @@ -1,7 +1,7 @@ //@ edition: 2021 //@ only-x86_64 -#![feature(async_closure, target_feature_11)] +#![feature(target_feature_11)] // `target_feature_11` just to test safe functions w/ target features. use std::pin::Pin; diff --git a/tests/ui/async-await/async-closures/fn-exception.rs b/tests/ui/async-await/async-closures/fn-exception.rs index 36cb955cd5ccc..8ff63983e7932 100644 --- a/tests/ui/async-await/async-closures/fn-exception.rs +++ b/tests/ui/async-await/async-closures/fn-exception.rs @@ -1,7 +1,5 @@ //@ edition: 2021 -#![feature(async_closure)] - use std::pin::Pin; use std::future::Future; diff --git a/tests/ui/async-await/async-closures/fn-exception.stderr b/tests/ui/async-await/async-closures/fn-exception.stderr index b3118664c15e6..aa74ed234df00 100644 --- a/tests/ui/async-await/async-closures/fn-exception.stderr +++ b/tests/ui/async-await/async-closures/fn-exception.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `unsafe fn() -> Pin + 'static)>> {unsafety}: AsyncFn()` is not satisfied - --> $DIR/fn-exception.rs:19:10 + --> $DIR/fn-exception.rs:17:10 | LL | test(unsafety); | ---- ^^^^^^^^ the trait `AsyncFn()` is not implemented for fn item `unsafe fn() -> Pin + 'static)>> {unsafety}` @@ -7,13 +7,13 @@ LL | test(unsafety); | required by a bound introduced by this call | note: required by a bound in `test` - --> $DIR/fn-exception.rs:16:17 + --> $DIR/fn-exception.rs:14:17 | LL | fn test(f: impl AsyncFn()) {} | ^^^^^^^^^ required by this bound in `test` error[E0277]: the trait bound `extern "C" fn() -> Pin + 'static)>> {abi}: AsyncFn()` is not satisfied - --> $DIR/fn-exception.rs:20:10 + --> $DIR/fn-exception.rs:18:10 | LL | test(abi); | ---- ^^^ the trait `AsyncFn()` is not implemented for fn item `extern "C" fn() -> Pin + 'static)>> {abi}` @@ -21,7 +21,7 @@ LL | test(abi); | required by a bound introduced by this call | note: required by a bound in `test` - --> $DIR/fn-exception.rs:16:17 + --> $DIR/fn-exception.rs:14:17 | LL | fn test(f: impl AsyncFn()) {} | ^^^^^^^^^ required by this bound in `test` diff --git a/tests/ui/async-await/async-closures/force-move-due-to-actually-fnonce.rs b/tests/ui/async-await/async-closures/force-move-due-to-actually-fnonce.rs index 7244a29673b98..1347a4b259b21 100644 --- a/tests/ui/async-await/async-closures/force-move-due-to-actually-fnonce.rs +++ b/tests/ui/async-await/async-closures/force-move-due-to-actually-fnonce.rs @@ -2,8 +2,6 @@ //@ edition:2021 //@ build-pass -#![feature(async_closure)] - extern crate block_on; fn consume(_: String) {} diff --git a/tests/ui/async-await/async-closures/force-move-due-to-inferred-kind.rs b/tests/ui/async-await/async-closures/force-move-due-to-inferred-kind.rs index c20e3664d8b07..c963d282c4e2f 100644 --- a/tests/ui/async-await/async-closures/force-move-due-to-inferred-kind.rs +++ b/tests/ui/async-await/async-closures/force-move-due-to-inferred-kind.rs @@ -2,8 +2,6 @@ //@ edition:2021 //@ build-pass -#![feature(async_closure)] - extern crate block_on; fn force_fnonce(t: T) -> T { t } diff --git a/tests/ui/async-await/async-closures/foreign.rs b/tests/ui/async-await/async-closures/foreign.rs index a244eef410291..b0580a8f09dc8 100644 --- a/tests/ui/async-await/async-closures/foreign.rs +++ b/tests/ui/async-await/async-closures/foreign.rs @@ -3,8 +3,6 @@ //@ edition:2021 //@ build-pass -#![feature(async_closure)] - use std::future::Future; extern crate block_on; diff --git a/tests/ui/async-await/async-closures/higher-ranked-return.rs b/tests/ui/async-await/async-closures/higher-ranked-return.rs index d6bea5dd103cd..328c733d42d4b 100644 --- a/tests/ui/async-await/async-closures/higher-ranked-return.rs +++ b/tests/ui/async-await/async-closures/higher-ranked-return.rs @@ -4,8 +4,6 @@ //@ known-bug: unknown // Borrow checking doesn't like that higher-ranked output... -#![feature(async_closure)] - extern crate block_on; fn main() { diff --git a/tests/ui/async-await/async-closures/higher-ranked-return.stderr b/tests/ui/async-await/async-closures/higher-ranked-return.stderr index 268631f67cddf..23ce3df661654 100644 --- a/tests/ui/async-await/async-closures/higher-ranked-return.stderr +++ b/tests/ui/async-await/async-closures/higher-ranked-return.stderr @@ -1,10 +1,10 @@ error: lifetime may not live long enough - --> $DIR/higher-ranked-return.rs:13:46 + --> $DIR/higher-ranked-return.rs:11:46 | LL | let x = async move |x: &str| -> &str { | ________________________________-________----_^ | | | | - | | | return type of async closure `{async closure body@$DIR/higher-ranked-return.rs:13:46: 15:10}` contains a lifetime `'2` + | | | return type of async closure `{async closure body@$DIR/higher-ranked-return.rs:11:46: 13:10}` contains a lifetime `'2` | | let's call the lifetime of this reference `'1` LL | | x LL | | }; diff --git a/tests/ui/async-await/async-closures/higher-ranked.rs b/tests/ui/async-await/async-closures/higher-ranked.rs index 5b34bfce96187..28f9df6013040 100644 --- a/tests/ui/async-await/async-closures/higher-ranked.rs +++ b/tests/ui/async-await/async-closures/higher-ranked.rs @@ -2,8 +2,6 @@ //@ edition:2021 //@ build-pass -#![feature(async_closure)] - extern crate block_on; fn main() { diff --git a/tests/ui/async-await/async-closures/implements-fnmut.rs b/tests/ui/async-await/async-closures/implements-fnmut.rs index f49d1423c404e..a2e31bb987038 100644 --- a/tests/ui/async-await/async-closures/implements-fnmut.rs +++ b/tests/ui/async-await/async-closures/implements-fnmut.rs @@ -7,8 +7,6 @@ // `should_reborrow_from_env_of_parent_coroutine_closure` for more detail for when we // must borrow from the closure env. -#![feature(async_closure)] - fn main() { hello(&Ty); } diff --git a/tests/ui/async-await/async-closures/inline-body.rs b/tests/ui/async-await/async-closures/inline-body.rs index b7d7102c28726..3f1b9c266016d 100644 --- a/tests/ui/async-await/async-closures/inline-body.rs +++ b/tests/ui/async-await/async-closures/inline-body.rs @@ -6,8 +6,6 @@ // `mir_inliner_callees` for the synthetic by-move coroutine body since // its def-id wasn't previously being considered. -#![feature(async_closure)] - use std::future::Future; use std::pin::pin; use std::task::*; diff --git a/tests/ui/async-await/async-closures/is-fn.rs b/tests/ui/async-await/async-closures/is-fn.rs index 89c3a96bbbe6a..45c2b6ae342b6 100644 --- a/tests/ui/async-await/async-closures/is-fn.rs +++ b/tests/ui/async-await/async-closures/is-fn.rs @@ -5,8 +5,6 @@ //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver -#![feature(async_closure)] - use std::future::Future; extern crate block_on; diff --git a/tests/ui/async-await/async-closures/is-not-fn.rs b/tests/ui/async-await/async-closures/is-not-fn.rs index f877513043db2..4acaa5d9809a1 100644 --- a/tests/ui/async-await/async-closures/is-not-fn.rs +++ b/tests/ui/async-await/async-closures/is-not-fn.rs @@ -1,9 +1,7 @@ //@ edition:2021 -#![feature(async_closure)] - fn main() { fn needs_fn(x: impl FnOnce()) {} needs_fn(async || {}); - //~^ ERROR expected `{async closure@is-not-fn.rs:7:14}` to be a closure that returns `()` + //~^ ERROR expected `{async closure@is-not-fn.rs:5:14}` to be a closure that returns `()` } diff --git a/tests/ui/async-await/async-closures/is-not-fn.stderr b/tests/ui/async-await/async-closures/is-not-fn.stderr index 130746ece675f..bc1d5e6e9d112 100644 --- a/tests/ui/async-await/async-closures/is-not-fn.stderr +++ b/tests/ui/async-await/async-closures/is-not-fn.stderr @@ -1,5 +1,5 @@ -error[E0271]: expected `{async closure@is-not-fn.rs:7:14}` to be a closure that returns `()`, but it returns `{async closure body@$DIR/is-not-fn.rs:7:23: 7:25}` - --> $DIR/is-not-fn.rs:7:14 +error[E0271]: expected `{async closure@is-not-fn.rs:5:14}` to be a closure that returns `()`, but it returns `{async closure body@$DIR/is-not-fn.rs:5:23: 5:25}` + --> $DIR/is-not-fn.rs:5:14 | LL | needs_fn(async || {}); | -------- ^^^^^^^^^^^ expected `()`, found `async` closure body @@ -7,9 +7,9 @@ LL | needs_fn(async || {}); | required by a bound introduced by this call | = note: expected unit type `()` - found `async` closure body `{async closure body@$DIR/is-not-fn.rs:7:23: 7:25}` + found `async` closure body `{async closure body@$DIR/is-not-fn.rs:5:23: 5:25}` note: required by a bound in `needs_fn` - --> $DIR/is-not-fn.rs:6:25 + --> $DIR/is-not-fn.rs:4:25 | LL | fn needs_fn(x: impl FnOnce()) {} | ^^^^^^^^ required by this bound in `needs_fn` diff --git a/tests/ui/async-await/async-closures/lint-closure-returning-async-block.rs b/tests/ui/async-await/async-closures/lint-closure-returning-async-block.rs index 3e2ab8321a890..f05d918aef289 100644 --- a/tests/ui/async-await/async-closures/lint-closure-returning-async-block.rs +++ b/tests/ui/async-await/async-closures/lint-closure-returning-async-block.rs @@ -1,6 +1,5 @@ //@ edition: 2021 -#![feature(async_closure)] #![deny(closure_returning_async_block)] fn main() { diff --git a/tests/ui/async-await/async-closures/lint-closure-returning-async-block.stderr b/tests/ui/async-await/async-closures/lint-closure-returning-async-block.stderr index 4c0c4d797d8ef..287dc52c59351 100644 --- a/tests/ui/async-await/async-closures/lint-closure-returning-async-block.stderr +++ b/tests/ui/async-await/async-closures/lint-closure-returning-async-block.stderr @@ -1,11 +1,11 @@ error: closure returning async block can be made into an async closure - --> $DIR/lint-closure-returning-async-block.rs:7:13 + --> $DIR/lint-closure-returning-async-block.rs:6:13 | LL | let x = || async {}; | ^^ ----- this async block can be removed, and the closure can be turned into an async closure | note: the lint level is defined here - --> $DIR/lint-closure-returning-async-block.rs:4:9 + --> $DIR/lint-closure-returning-async-block.rs:3:9 | LL | #![deny(closure_returning_async_block)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -16,7 +16,7 @@ LL + let x = async || {}; | error: closure returning async block can be made into an async closure - --> $DIR/lint-closure-returning-async-block.rs:10:13 + --> $DIR/lint-closure-returning-async-block.rs:9:13 | LL | let x = || async move {}; | ^^ ---------- this async block can be removed, and the closure can be turned into an async closure @@ -28,7 +28,7 @@ LL + let x = async || {}; | error: closure returning async block can be made into an async closure - --> $DIR/lint-closure-returning-async-block.rs:13:13 + --> $DIR/lint-closure-returning-async-block.rs:12:13 | LL | let x = move || async move {}; | ^^^^^^^ ---------- this async block can be removed, and the closure can be turned into an async closure @@ -40,7 +40,7 @@ LL + let x = async move || {}; | error: closure returning async block can be made into an async closure - --> $DIR/lint-closure-returning-async-block.rs:16:13 + --> $DIR/lint-closure-returning-async-block.rs:15:13 | LL | let x = move || async {}; | ^^^^^^^ ----- this async block can be removed, and the closure can be turned into an async closure @@ -52,7 +52,7 @@ LL + let x = async move || {}; | error: closure returning async block can be made into an async closure - --> $DIR/lint-closure-returning-async-block.rs:19:13 + --> $DIR/lint-closure-returning-async-block.rs:18:13 | LL | let x = || {{ async {} }}; | ^^ ----- this async block can be removed, and the closure can be turned into an async closure diff --git a/tests/ui/async-await/async-closures/mac-body.rs b/tests/ui/async-await/async-closures/mac-body.rs index a416227c3904f..51c077ba03fb8 100644 --- a/tests/ui/async-await/async-closures/mac-body.rs +++ b/tests/ui/async-await/async-closures/mac-body.rs @@ -1,8 +1,6 @@ //@ edition: 2021 //@ check-pass -#![feature(async_closure)] - // Make sure we don't ICE if an async closure has a macro body. // This happened because we were calling walk instead of visit // in the def collector, oops! diff --git a/tests/ui/async-await/async-closures/mangle.rs b/tests/ui/async-await/async-closures/mangle.rs index 1790f369c57e9..c8e5e52e1b209 100644 --- a/tests/ui/async-await/async-closures/mangle.rs +++ b/tests/ui/async-await/async-closures/mangle.rs @@ -5,8 +5,6 @@ //@[v0] compile-flags: -Csymbol-mangling-version=v0 //@[legacy] compile-flags: -Csymbol-mangling-version=legacy -Zunstable-options -#![feature(async_closure)] - extern crate block_on; use std::future::Future; diff --git a/tests/ui/async-await/async-closures/moro-example.rs b/tests/ui/async-await/async-closures/moro-example.rs index c331b8e5b5e91..502b3e1bbf8cb 100644 --- a/tests/ui/async-await/async-closures/moro-example.rs +++ b/tests/ui/async-await/async-closures/moro-example.rs @@ -1,8 +1,6 @@ //@ check-pass //@ edition: 2021 -#![feature(async_closure)] - use std::future::Future; use std::pin::Pin; use std::{marker::PhantomData, sync::Mutex}; diff --git a/tests/ui/async-await/async-closures/move-consuming-capture.rs b/tests/ui/async-await/async-closures/move-consuming-capture.rs index 17925fc89ba28..c833bc7e89595 100644 --- a/tests/ui/async-await/async-closures/move-consuming-capture.rs +++ b/tests/ui/async-await/async-closures/move-consuming-capture.rs @@ -1,8 +1,6 @@ //@ aux-build:block-on.rs //@ edition:2021 -#![feature(async_closure)] - extern crate block_on; struct NoCopy; diff --git a/tests/ui/async-await/async-closures/move-consuming-capture.stderr b/tests/ui/async-await/async-closures/move-consuming-capture.stderr index 4ce71ec49d612..e28716ca213b3 100644 --- a/tests/ui/async-await/async-closures/move-consuming-capture.stderr +++ b/tests/ui/async-await/async-closures/move-consuming-capture.stderr @@ -1,8 +1,8 @@ error[E0382]: use of moved value: `x` - --> $DIR/move-consuming-capture.rs:17:9 + --> $DIR/move-consuming-capture.rs:15:9 | LL | let x = async move || { - | - move occurs because `x` has type `{async closure@$DIR/move-consuming-capture.rs:13:17: 13:30}`, which does not implement the `Copy` trait + | - move occurs because `x` has type `{async closure@$DIR/move-consuming-capture.rs:11:17: 11:30}`, which does not implement the `Copy` trait ... LL | x().await; | --- `x` moved due to this method call diff --git a/tests/ui/async-await/async-closures/move-is-async-fn.rs b/tests/ui/async-await/async-closures/move-is-async-fn.rs index d0e2bc24b52e7..2cbad0faffcb0 100644 --- a/tests/ui/async-await/async-closures/move-is-async-fn.rs +++ b/tests/ui/async-await/async-closures/move-is-async-fn.rs @@ -2,7 +2,7 @@ //@ edition:2021 //@ build-pass -#![feature(async_closure, async_fn_traits)] +#![feature(async_fn_traits)] extern crate block_on; diff --git a/tests/ui/async-await/async-closures/move-out-of-ref.rs b/tests/ui/async-await/async-closures/move-out-of-ref.rs index a05447232f62b..34389d2d00a2c 100644 --- a/tests/ui/async-await/async-closures/move-out-of-ref.rs +++ b/tests/ui/async-await/async-closures/move-out-of-ref.rs @@ -1,8 +1,6 @@ //@ compile-flags: -Zvalidate-mir //@ edition: 2021 -#![feature(async_closure)] - // NOT copy. struct Ty; diff --git a/tests/ui/async-await/async-closures/move-out-of-ref.stderr b/tests/ui/async-await/async-closures/move-out-of-ref.stderr index 294905a481d65..8a63515a8a908 100644 --- a/tests/ui/async-await/async-closures/move-out-of-ref.stderr +++ b/tests/ui/async-await/async-closures/move-out-of-ref.stderr @@ -1,11 +1,11 @@ error[E0507]: cannot move out of `*x` which is behind a shared reference - --> $DIR/move-out-of-ref.rs:11:9 + --> $DIR/move-out-of-ref.rs:9:9 | LL | *x; | ^^ move occurs because `*x` has type `Ty`, which does not implement the `Copy` trait | note: if `Ty` implemented `Clone`, you could clone the value - --> $DIR/move-out-of-ref.rs:7:1 + --> $DIR/move-out-of-ref.rs:5:1 | LL | struct Ty; | ^^^^^^^^^ consider implementing `Clone` for this type diff --git a/tests/ui/async-await/async-closures/mut-ref-reborrow.rs b/tests/ui/async-await/async-closures/mut-ref-reborrow.rs index c37048398e97d..a1a90a1c9ad97 100644 --- a/tests/ui/async-await/async-closures/mut-ref-reborrow.rs +++ b/tests/ui/async-await/async-closures/mut-ref-reborrow.rs @@ -5,8 +5,6 @@ //@[e2018] edition:2018 //@[e2021] edition:2021 -#![feature(async_closure)] - extern crate block_on; async fn call_once(f: impl AsyncFnOnce()) { f().await; } diff --git a/tests/ui/async-await/async-closures/mutate.rs b/tests/ui/async-await/async-closures/mutate.rs index 562a7271c668a..7c1d8389eac72 100644 --- a/tests/ui/async-await/async-closures/mutate.rs +++ b/tests/ui/async-await/async-closures/mutate.rs @@ -2,8 +2,6 @@ //@ edition:2021 //@ run-pass -#![feature(async_closure)] - extern crate block_on; fn main() { diff --git a/tests/ui/async-await/async-closures/no-borrow-from-env.rs b/tests/ui/async-await/async-closures/no-borrow-from-env.rs index 36b10c06dcafa..ce18063138911 100644 --- a/tests/ui/async-await/async-closures/no-borrow-from-env.rs +++ b/tests/ui/async-await/async-closures/no-borrow-from-env.rs @@ -1,8 +1,6 @@ //@ edition: 2021 //@ check-pass -#![feature(async_closure)] - fn outlives<'a>(_: impl Sized + 'a) {} async fn call_once(f: impl AsyncFnOnce()) { diff --git a/tests/ui/async-await/async-closures/non-copy-arg-does-not-force-inner-move.rs b/tests/ui/async-await/async-closures/non-copy-arg-does-not-force-inner-move.rs index cfb50dd5574da..0c22ac97265bb 100644 --- a/tests/ui/async-await/async-closures/non-copy-arg-does-not-force-inner-move.rs +++ b/tests/ui/async-await/async-closures/non-copy-arg-does-not-force-inner-move.rs @@ -2,8 +2,6 @@ //@ edition:2021 //@ build-pass -#![feature(async_closure)] - extern crate block_on; fn wrapper(f: impl Fn(String)) -> impl AsyncFn(String) { diff --git a/tests/ui/async-await/async-closures/not-clone-closure.rs b/tests/ui/async-await/async-closures/not-clone-closure.rs index 2776ce4690fe2..c96c50e85d846 100644 --- a/tests/ui/async-await/async-closures/not-clone-closure.rs +++ b/tests/ui/async-await/async-closures/not-clone-closure.rs @@ -1,7 +1,5 @@ //@ edition: 2021 -#![feature(async_closure)] - struct NotClonableArg; #[derive(Default)] struct NotClonableReturnType; diff --git a/tests/ui/async-await/async-closures/not-clone-closure.stderr b/tests/ui/async-await/async-closures/not-clone-closure.stderr index c2f963f9b924d..a08ee45f97049 100644 --- a/tests/ui/async-await/async-closures/not-clone-closure.stderr +++ b/tests/ui/async-await/async-closures/not-clone-closure.stderr @@ -1,12 +1,12 @@ -error[E0277]: the trait bound `NotClonableUpvar: Clone` is not satisfied in `{async closure@$DIR/not-clone-closure.rs:29:21: 29:34}` - --> $DIR/not-clone-closure.rs:32:15 +error[E0277]: the trait bound `NotClonableUpvar: Clone` is not satisfied in `{async closure@$DIR/not-clone-closure.rs:27:21: 27:34}` + --> $DIR/not-clone-closure.rs:30:15 | LL | not_clone.clone(); | ^^^^^ unsatisfied trait bound | - = help: within `{async closure@$DIR/not-clone-closure.rs:29:21: 29:34}`, the trait `Clone` is not implemented for `NotClonableUpvar` + = help: within `{async closure@$DIR/not-clone-closure.rs:27:21: 27:34}`, the trait `Clone` is not implemented for `NotClonableUpvar` note: required because it's used within this closure - --> $DIR/not-clone-closure.rs:29:21 + --> $DIR/not-clone-closure.rs:27:21 | LL | let not_clone = async move || { | ^^^^^^^^^^^^^ diff --git a/tests/ui/async-await/async-closures/not-fn.rs b/tests/ui/async-await/async-closures/not-fn.rs index 5f2d047c3e982..34dd2a22bbb96 100644 --- a/tests/ui/async-await/async-closures/not-fn.rs +++ b/tests/ui/async-await/async-closures/not-fn.rs @@ -2,8 +2,6 @@ // FIXME(async_closures): This needs a better error message! -#![feature(async_closure)] - fn main() { fn needs_fn(_: impl FnMut() -> T) {} diff --git a/tests/ui/async-await/async-closures/not-fn.stderr b/tests/ui/async-await/async-closures/not-fn.stderr index 9c40613599a8e..4b9d2db9a2534 100644 --- a/tests/ui/async-await/async-closures/not-fn.stderr +++ b/tests/ui/async-await/async-closures/not-fn.stderr @@ -1,5 +1,5 @@ error: async closure does not implement `FnMut` because it captures state from its environment - --> $DIR/not-fn.rs:11:14 + --> $DIR/not-fn.rs:9:14 | LL | needs_fn(async || { | -------- ^^^^^^^^ @@ -7,7 +7,7 @@ LL | needs_fn(async || { | required by a bound introduced by this call | note: required by a bound in `needs_fn` - --> $DIR/not-fn.rs:8:28 + --> $DIR/not-fn.rs:6:28 | LL | fn needs_fn(_: impl FnMut() -> T) {} | ^^^^^^^^^^^^ required by this bound in `needs_fn` diff --git a/tests/ui/async-await/async-closures/not-lending.rs b/tests/ui/async-await/async-closures/not-lending.rs index 2e5542207cfb1..7bf2d3ead522c 100644 --- a/tests/ui/async-await/async-closures/not-lending.rs +++ b/tests/ui/async-await/async-closures/not-lending.rs @@ -1,8 +1,6 @@ //@ aux-build:block-on.rs //@ edition:2021 -#![feature(async_closure)] - extern crate block_on; // Make sure that we can't make an async closure that evaluates to a self-borrow. diff --git a/tests/ui/async-await/async-closures/not-lending.stderr b/tests/ui/async-await/async-closures/not-lending.stderr index 1713e49b551e6..f0028129caa02 100644 --- a/tests/ui/async-await/async-closures/not-lending.stderr +++ b/tests/ui/async-await/async-closures/not-lending.stderr @@ -1,21 +1,21 @@ error: lifetime may not live long enough - --> $DIR/not-lending.rs:14:42 + --> $DIR/not-lending.rs:12:42 | LL | let x = async move || -> &String { &s }; | ------------------------ ^^^^^^ returning this value requires that `'1` must outlive `'2` | | | - | | return type of async closure `{async closure body@$DIR/not-lending.rs:14:42: 14:48}` contains a lifetime `'2` + | | return type of async closure `{async closure body@$DIR/not-lending.rs:12:42: 12:48}` contains a lifetime `'2` | lifetime `'1` represents this closure's body | = note: closure implements `Fn`, so references to captured variables can't escape the closure error: lifetime may not live long enough - --> $DIR/not-lending.rs:18:31 + --> $DIR/not-lending.rs:16:31 | LL | let x = async move || { &s }; | ------------- ^^^^^^ returning this value requires that `'1` must outlive `'2` | | | - | | return type of async closure `{async closure body@$DIR/not-lending.rs:18:31: 18:37}` contains a lifetime `'2` + | | return type of async closure `{async closure body@$DIR/not-lending.rs:16:31: 16:37}` contains a lifetime `'2` | lifetime `'1` represents this closure's body | = note: closure implements `Fn`, so references to captured variables can't escape the closure diff --git a/tests/ui/async-await/async-closures/once.rs b/tests/ui/async-await/async-closures/once.rs index 7009e0d132f30..3cf70e16a12ba 100644 --- a/tests/ui/async-await/async-closures/once.rs +++ b/tests/ui/async-await/async-closures/once.rs @@ -5,8 +5,6 @@ //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver -#![feature(async_closure)] - use std::future::Future; extern crate block_on; diff --git a/tests/ui/async-await/async-closures/overlapping-projs.rs b/tests/ui/async-await/async-closures/overlapping-projs.rs index f778534cfe26e..c37f24b4ff2e1 100644 --- a/tests/ui/async-await/async-closures/overlapping-projs.rs +++ b/tests/ui/async-await/async-closures/overlapping-projs.rs @@ -3,8 +3,6 @@ //@ run-pass //@ check-run-results -#![feature(async_closure)] - extern crate block_on; async fn call_once(f: impl AsyncFnOnce()) { diff --git a/tests/ui/async-await/async-closures/precise-captures.rs b/tests/ui/async-await/async-closures/precise-captures.rs index 7dcbf2595f0df..638fb67c3a465 100644 --- a/tests/ui/async-await/async-closures/precise-captures.rs +++ b/tests/ui/async-await/async-closures/precise-captures.rs @@ -9,7 +9,6 @@ // force_once - Force the closure mode to `FnOnce`, so exercising what was fixed // in . -#![feature(async_closure)] #![allow(unused_mut)] extern crate block_on; diff --git a/tests/ui/async-await/async-closures/pretty-async-fn-opaque.rs b/tests/ui/async-await/async-closures/pretty-async-fn-opaque.rs index 2e7cf1b09fd00..deae1c9376a3e 100644 --- a/tests/ui/async-await/async-closures/pretty-async-fn-opaque.rs +++ b/tests/ui/async-await/async-closures/pretty-async-fn-opaque.rs @@ -1,9 +1,5 @@ //@ edition: 2021 -#![feature(async_closure)] - -use std::ops::AsyncFnMut; - fn produce() -> impl AsyncFnMut() -> &'static str { async || "" } diff --git a/tests/ui/async-await/async-closures/pretty-async-fn-opaque.stderr b/tests/ui/async-await/async-closures/pretty-async-fn-opaque.stderr index 863e61eb35ad4..8bbd9fbec3eb8 100644 --- a/tests/ui/async-await/async-closures/pretty-async-fn-opaque.stderr +++ b/tests/ui/async-await/async-closures/pretty-async-fn-opaque.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/pretty-async-fn-opaque.rs:12:18 + --> $DIR/pretty-async-fn-opaque.rs:8:18 | LL | fn produce() -> impl AsyncFnMut() -> &'static str { | --------------------------------- the found opaque type diff --git a/tests/ui/async-await/async-closures/refd.rs b/tests/ui/async-await/async-closures/refd.rs index 8c16ecb153130..ae8a10a530ae3 100644 --- a/tests/ui/async-await/async-closures/refd.rs +++ b/tests/ui/async-await/async-closures/refd.rs @@ -2,8 +2,6 @@ //@ edition:2021 //@ build-pass -#![feature(async_closure)] - extern crate block_on; struct NoCopy; diff --git a/tests/ui/async-await/async-closures/return-type-mismatch.rs b/tests/ui/async-await/async-closures/return-type-mismatch.rs index 992f033180e3a..d3b4cb61cdf91 100644 --- a/tests/ui/async-await/async-closures/return-type-mismatch.rs +++ b/tests/ui/async-await/async-closures/return-type-mismatch.rs @@ -1,8 +1,6 @@ //@ aux-build:block-on.rs //@ edition:2021 -#![feature(async_closure)] - extern crate block_on; fn main() { diff --git a/tests/ui/async-await/async-closures/return-type-mismatch.stderr b/tests/ui/async-await/async-closures/return-type-mismatch.stderr index 53841f62777e6..d7675aab9532a 100644 --- a/tests/ui/async-await/async-closures/return-type-mismatch.stderr +++ b/tests/ui/async-await/async-closures/return-type-mismatch.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/return-type-mismatch.rs:11:24 + --> $DIR/return-type-mismatch.rs:9:24 | LL | let y: usize = x().await; | ^^^^^^^^^ expected `usize`, found `i32` diff --git a/tests/ui/async-await/async-closures/sig-from-bare-fn.rs b/tests/ui/async-await/async-closures/sig-from-bare-fn.rs index a679471a3b3d0..72aac1402560a 100644 --- a/tests/ui/async-await/async-closures/sig-from-bare-fn.rs +++ b/tests/ui/async-await/async-closures/sig-from-bare-fn.rs @@ -5,8 +5,6 @@ // a function that requires the async closure implement `Fn*` but does *not* have // a `Future` bound on the return type. -#![feature(async_closure)] - use std::future::Future; trait TryStream { diff --git a/tests/ui/async-await/async-closures/signature-deduction.rs b/tests/ui/async-await/async-closures/signature-deduction.rs index 4e9a6747f1f3d..27ec54ba4f984 100644 --- a/tests/ui/async-await/async-closures/signature-deduction.rs +++ b/tests/ui/async-await/async-closures/signature-deduction.rs @@ -1,8 +1,6 @@ //@ build-pass //@ edition: 2021 -#![feature(async_closure)] - async fn foo(x: impl AsyncFn(&str) -> &str) {} fn main() { diff --git a/tests/ui/async-await/async-closures/signature-inference-from-two-part-bound.rs b/tests/ui/async-await/async-closures/signature-inference-from-two-part-bound.rs index 0e2d1ef12082b..f66787bd6fc29 100644 --- a/tests/ui/async-await/async-closures/signature-inference-from-two-part-bound.rs +++ b/tests/ui/async-await/async-closures/signature-inference-from-two-part-bound.rs @@ -4,8 +4,6 @@ //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver -#![feature(async_closure)] - use std::future::Future; use std::any::Any; diff --git a/tests/ui/async-await/async-closures/tainted-body-2.rs b/tests/ui/async-await/async-closures/tainted-body-2.rs index 73c6bdc30a02f..8314f7e7f96d2 100644 --- a/tests/ui/async-await/async-closures/tainted-body-2.rs +++ b/tests/ui/async-await/async-closures/tainted-body-2.rs @@ -1,7 +1,5 @@ //@ edition: 2021 -#![feature(async_closure)] - // Ensure that building a by-ref async closure body doesn't ICE when the parent // body is tainted. diff --git a/tests/ui/async-await/async-closures/tainted-body-2.stderr b/tests/ui/async-await/async-closures/tainted-body-2.stderr index 798d47064d990..cffd67b63615c 100644 --- a/tests/ui/async-await/async-closures/tainted-body-2.stderr +++ b/tests/ui/async-await/async-closures/tainted-body-2.stderr @@ -1,5 +1,5 @@ error[E0425]: cannot find value `missing` in this scope - --> $DIR/tainted-body-2.rs:9:5 + --> $DIR/tainted-body-2.rs:7:5 | LL | missing; | ^^^^^^^ not found in this scope diff --git a/tests/ui/async-await/async-closures/tainted-body.rs b/tests/ui/async-await/async-closures/tainted-body.rs index e42d9d6e36ade..118c08874699f 100644 --- a/tests/ui/async-await/async-closures/tainted-body.rs +++ b/tests/ui/async-await/async-closures/tainted-body.rs @@ -1,7 +1,5 @@ //@ edition:2021 -#![feature(async_closure)] - // Don't ICE in ByMove shim builder when MIR body is tainted by writeback errors fn main() { diff --git a/tests/ui/async-await/async-closures/tainted-body.stderr b/tests/ui/async-await/async-closures/tainted-body.stderr index b06a896b81f52..617d87e9df2f1 100644 --- a/tests/ui/async-await/async-closures/tainted-body.stderr +++ b/tests/ui/async-await/async-closures/tainted-body.stderr @@ -1,5 +1,5 @@ error[E0425]: cannot find function `used_fn` in this scope - --> $DIR/tainted-body.rs:9:9 + --> $DIR/tainted-body.rs:7:9 | LL | used_fn(); | ^^^^^^^ not found in this scope diff --git a/tests/ui/async-await/async-closures/truncated-fields-when-imm.rs b/tests/ui/async-await/async-closures/truncated-fields-when-imm.rs index 5c718638d8016..7d08cdb91e569 100644 --- a/tests/ui/async-await/async-closures/truncated-fields-when-imm.rs +++ b/tests/ui/async-await/async-closures/truncated-fields-when-imm.rs @@ -1,8 +1,6 @@ //@ edition: 2021 //@ check-pass -#![feature(async_closure)] - pub struct Struct { pub path: String, } diff --git a/tests/ui/async-await/async-closures/validate-synthetic-body.rs b/tests/ui/async-await/async-closures/validate-synthetic-body.rs index 67e683ac08a22..3fd7382f7f9b9 100644 --- a/tests/ui/async-await/async-closures/validate-synthetic-body.rs +++ b/tests/ui/async-await/async-closures/validate-synthetic-body.rs @@ -1,8 +1,6 @@ //@ check-pass //@ edition: 2021 -#![feature(async_closure)] - // Make sure that we don't hit a query cycle when validating // the by-move coroutine body for an async closure. diff --git a/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.rs b/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.rs index 19f366cc903cc..19a31d1889b84 100644 --- a/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.rs +++ b/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.rs @@ -4,8 +4,6 @@ // sure that we don't ICE or anything, even if precise closure captures means // that we can't actually borrowck successfully. -#![feature(async_closure)] - fn outlives<'a>(_: impl Sized + 'a) {} async fn call_once(f: impl AsyncFnOnce()) { diff --git a/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.stderr b/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.stderr index a70aece2dea5f..be39dbf313bf0 100644 --- a/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.stderr +++ b/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.stderr @@ -1,5 +1,5 @@ error[E0597]: `x` does not live long enough - --> $DIR/without-precise-captures-we-are-powerless.rs:16:13 + --> $DIR/without-precise-captures-we-are-powerless.rs:14:13 | LL | fn simple<'a>(x: &'a i32) { | -- lifetime `'a` defined here @@ -13,7 +13,7 @@ LL | } | - `x` dropped here while still borrowed error[E0597]: `c` does not live long enough - --> $DIR/without-precise-captures-we-are-powerless.rs:21:20 + --> $DIR/without-precise-captures-we-are-powerless.rs:19:20 | LL | fn simple<'a>(x: &'a i32) { | -- lifetime `'a` defined here @@ -30,7 +30,7 @@ LL | } | - `c` dropped here while still borrowed error[E0597]: `x` does not live long enough - --> $DIR/without-precise-captures-we-are-powerless.rs:28:13 + --> $DIR/without-precise-captures-we-are-powerless.rs:26:13 | LL | fn through_field<'a>(x: S<'a>) { | -- lifetime `'a` defined here @@ -44,7 +44,7 @@ LL | } | - `x` dropped here while still borrowed error[E0505]: cannot move out of `x` because it is borrowed - --> $DIR/without-precise-captures-we-are-powerless.rs:32:13 + --> $DIR/without-precise-captures-we-are-powerless.rs:30:13 | LL | fn through_field<'a>(x: S<'a>) { | -- lifetime `'a` defined here @@ -58,7 +58,7 @@ LL | let c = async move || { println!("{}", *x.0); }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ move out of `x` occurs here error[E0597]: `c` does not live long enough - --> $DIR/without-precise-captures-we-are-powerless.rs:33:20 + --> $DIR/without-precise-captures-we-are-powerless.rs:31:20 | LL | fn through_field<'a>(x: S<'a>) { | -- lifetime `'a` defined here @@ -75,7 +75,7 @@ LL | } | - `c` dropped here while still borrowed error[E0505]: cannot move out of `c` because it is borrowed - --> $DIR/without-precise-captures-we-are-powerless.rs:34:30 + --> $DIR/without-precise-captures-we-are-powerless.rs:32:30 | LL | fn through_field<'a>(x: S<'a>) { | -- lifetime `'a` defined here @@ -91,7 +91,7 @@ LL | outlives::<'a>(call_once(c)); | ^ move out of `c` occurs here error[E0597]: `x` does not live long enough - --> $DIR/without-precise-captures-we-are-powerless.rs:38:13 + --> $DIR/without-precise-captures-we-are-powerless.rs:36:13 | LL | fn through_field_and_ref<'a>(x: &S<'a>) { | -- lifetime `'a` defined here @@ -104,7 +104,7 @@ LL | } | - `x` dropped here while still borrowed error[E0621]: explicit lifetime required in the type of `x` - --> $DIR/without-precise-captures-we-are-powerless.rs:40:20 + --> $DIR/without-precise-captures-we-are-powerless.rs:38:20 | LL | fn through_field_and_ref<'a>(x: &S<'a>) { | ------ help: add explicit lifetime `'a` to the type of `x`: `&'a S<'a>` @@ -113,7 +113,7 @@ LL | outlives::<'a>(call_once(c)); | ^^^^^^^^^^^^ lifetime `'a` required error[E0597]: `c` does not live long enough - --> $DIR/without-precise-captures-we-are-powerless.rs:45:20 + --> $DIR/without-precise-captures-we-are-powerless.rs:43:20 | LL | fn through_field_and_ref_move<'a>(x: &S<'a>) { | -- lifetime `'a` defined here @@ -129,7 +129,7 @@ LL | } | - `c` dropped here while still borrowed error[E0621]: explicit lifetime required in the type of `x` - --> $DIR/without-precise-captures-we-are-powerless.rs:46:20 + --> $DIR/without-precise-captures-we-are-powerless.rs:44:20 | LL | fn through_field_and_ref_move<'a>(x: &S<'a>) { | ------ help: add explicit lifetime `'a` to the type of `x`: `&'a S<'a>` diff --git a/tests/ui/async-await/async-closures/wrong-fn-kind.rs b/tests/ui/async-await/async-closures/wrong-fn-kind.rs index a566b8aa66396..2aed6dc6d809f 100644 --- a/tests/ui/async-await/async-closures/wrong-fn-kind.rs +++ b/tests/ui/async-await/async-closures/wrong-fn-kind.rs @@ -1,7 +1,5 @@ //@ edition:2021 -#![feature(async_closure)] - fn needs_async_fn(_: impl AsyncFn()) {} fn a() { diff --git a/tests/ui/async-await/async-closures/wrong-fn-kind.stderr b/tests/ui/async-await/async-closures/wrong-fn-kind.stderr index d03b10ca2cc17..95f314214cc65 100644 --- a/tests/ui/async-await/async-closures/wrong-fn-kind.stderr +++ b/tests/ui/async-await/async-closures/wrong-fn-kind.stderr @@ -1,5 +1,5 @@ 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:15:20 | LL | needs_async_fn(move || async move { | -------------- -^^^^^^ @@ -14,13 +14,13 @@ LL | | }); | |_____- the requirement to implement `AsyncFn` derives from here | note: required by a bound in `needs_async_fn` - --> $DIR/wrong-fn-kind.rs:5:27 + --> $DIR/wrong-fn-kind.rs:3:27 | LL | fn needs_async_fn(_: impl AsyncFn()) {} | ^^^^^^^^^ 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 - --> $DIR/wrong-fn-kind.rs:9:20 + --> $DIR/wrong-fn-kind.rs:7:20 | LL | fn needs_async_fn(_: impl AsyncFn()) {} | -------------- change this to accept `FnMut` instead of `Fn` diff --git a/tests/ui/async-await/async-drop.rs b/tests/ui/async-await/async-drop.rs index d3884680e519f..b1af81423cea5 100644 --- a/tests/ui/async-await/async-drop.rs +++ b/tests/ui/async-await/async-drop.rs @@ -5,7 +5,7 @@ // please consider modifying miri's async drop test at // `src/tools/miri/tests/pass/async-drop.rs`. -#![feature(async_drop, impl_trait_in_assoc_type, async_closure)] +#![feature(async_drop, impl_trait_in_assoc_type)] #![allow(incomplete_features, dead_code)] //@ edition: 2021 diff --git a/tests/ui/async-await/async-fn/auxiliary/block-on.rs b/tests/ui/async-await/async-fn/auxiliary/block-on.rs index 8b50c5571c145..4ec45ddf33359 100644 --- a/tests/ui/async-await/async-fn/auxiliary/block-on.rs +++ b/tests/ui/async-await/async-fn/auxiliary/block-on.rs @@ -1,7 +1,5 @@ //@ edition: 2021 -#![feature(async_closure)] - use std::future::Future; use std::pin::pin; use std::task::*; diff --git a/tests/ui/async-await/async-fn/dyn-pos.rs b/tests/ui/async-await/async-fn/dyn-pos.rs index 129ea2829362c..d71af1bd53e2d 100644 --- a/tests/ui/async-await/async-fn/dyn-pos.rs +++ b/tests/ui/async-await/async-fn/dyn-pos.rs @@ -1,7 +1,5 @@ //@ edition:2018 -#![feature(async_closure)] - fn foo(x: &dyn AsyncFn()) {} //~^ ERROR the trait `AsyncFnMut` cannot be made into an object diff --git a/tests/ui/async-await/async-fn/dyn-pos.stderr b/tests/ui/async-await/async-fn/dyn-pos.stderr index aaa8eb2634d02..0c90184667198 100644 --- a/tests/ui/async-await/async-fn/dyn-pos.stderr +++ b/tests/ui/async-await/async-fn/dyn-pos.stderr @@ -1,5 +1,5 @@ error[E0038]: the trait `AsyncFnMut` cannot be made into an object - --> $DIR/dyn-pos.rs:5:16 + --> $DIR/dyn-pos.rs:3:16 | LL | fn foo(x: &dyn AsyncFn()) {} | ^^^^^^^^^ `AsyncFnMut` cannot be made into an object diff --git a/tests/ui/async-await/async-fn/edition-2015.rs b/tests/ui/async-await/async-fn/edition-2015.rs index 7fc62a8dd93db..341b9b10e6711 100644 --- a/tests/ui/async-await/async-fn/edition-2015.rs +++ b/tests/ui/async-await/async-fn/edition-2015.rs @@ -3,7 +3,5 @@ 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 unstable //~| ERROR `async` trait bounds are unstable -//~| ERROR use of unstable library feature `async_closure` -//~| ERROR use of unstable library feature `async_closure` fn main() {} diff --git a/tests/ui/async-await/async-fn/edition-2015.stderr b/tests/ui/async-await/async-fn/edition-2015.stderr index 96fb4c9e9791c..ca9e64cd1bb08 100644 --- a/tests/ui/async-await/async-fn/edition-2015.stderr +++ b/tests/ui/async-await/async-fn/edition-2015.stderr @@ -38,26 +38,6 @@ LL | fn foo(x: impl async Fn()) -> impl async Fn() { x } = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date = help: use the desugared name of the async trait, such as `AsyncFn` -error[E0658]: use of unstable library feature `async_closure` - --> $DIR/edition-2015.rs:1:42 - | -LL | fn foo(x: impl async Fn()) -> impl async Fn() { x } - | ^^^^ - | - = note: see issue #62290 for more information - = help: add `#![feature(async_closure)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: use of unstable library feature `async_closure` - --> $DIR/edition-2015.rs:1:22 - | -LL | fn foo(x: impl async Fn()) -> impl async Fn() { x } - | ^^^^ - | - = note: see issue #62290 for more information - = help: add `#![feature(async_closure)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error: aborting due to 6 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/async-await/async-fn/higher-ranked-async-fn.rs b/tests/ui/async-await/async-fn/higher-ranked-async-fn.rs index 5d6759210288a..ac8e0d7c63e0f 100644 --- a/tests/ui/async-await/async-fn/higher-ranked-async-fn.rs +++ b/tests/ui/async-await/async-fn/higher-ranked-async-fn.rs @@ -5,8 +5,6 @@ //@[next] compile-flags: -Znext-solver //@ build-pass (since it ICEs during mono) -#![feature(async_closure)] - extern crate block_on; use std::future::Future; diff --git a/tests/ui/async-await/async-fn/impl-trait.rs b/tests/ui/async-await/async-fn/impl-trait.rs index 11faf9ac98304..f284de8981ad8 100644 --- a/tests/ui/async-await/async-fn/impl-trait.rs +++ b/tests/ui/async-await/async-fn/impl-trait.rs @@ -1,7 +1,7 @@ //@ edition:2018 //@ check-pass -#![feature(async_closure, type_alias_impl_trait)] +#![feature(type_alias_impl_trait)] type Tait = impl AsyncFn(); fn tait() -> Tait { diff --git a/tests/ui/async-await/async-fn/project.rs b/tests/ui/async-await/async-fn/project.rs index b6068a916aeaf..8ee50724e4c2d 100644 --- a/tests/ui/async-await/async-fn/project.rs +++ b/tests/ui/async-await/async-fn/project.rs @@ -4,7 +4,7 @@ //@[next] compile-flags: -Znext-solver //@ check-pass -#![feature(async_closure, unboxed_closures, async_fn_traits)] +#![feature(unboxed_closures, async_fn_traits)] use std::ops::AsyncFn; diff --git a/tests/ui/async-await/async-fn/simple.rs b/tests/ui/async-await/async-fn/simple.rs index 3f15b08560af2..89b68e12435c9 100644 --- a/tests/ui/async-await/async-fn/simple.rs +++ b/tests/ui/async-await/async-fn/simple.rs @@ -2,8 +2,6 @@ //@ edition: 2021 //@ build-pass -#![feature(async_closure)] - extern crate block_on; use std::ops::AsyncFn; diff --git a/tests/ui/async-await/async-fn/sugar.rs b/tests/ui/async-await/async-fn/sugar.rs index 0225b666ac582..d00965ee64772 100644 --- a/tests/ui/async-await/async-fn/sugar.rs +++ b/tests/ui/async-await/async-fn/sugar.rs @@ -1,7 +1,7 @@ //@ edition: 2021 //@ check-pass -#![feature(async_closure, async_trait_bounds)] +#![feature(async_trait_bounds)] async fn foo() {} diff --git a/tests/ui/async-await/coroutine-desc.rs b/tests/ui/async-await/coroutine-desc.rs index 9a61c9719db84..9a58104910799 100644 --- a/tests/ui/async-await/coroutine-desc.rs +++ b/tests/ui/async-await/coroutine-desc.rs @@ -1,5 +1,4 @@ //@ edition:2018 -#![feature(async_closure)] use std::future::Future; async fn one() {} diff --git a/tests/ui/async-await/coroutine-desc.stderr b/tests/ui/async-await/coroutine-desc.stderr index 5434ff3d958f8..01482a9cb1fb6 100644 --- a/tests/ui/async-await/coroutine-desc.stderr +++ b/tests/ui/async-await/coroutine-desc.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/coroutine-desc.rs:10:19 + --> $DIR/coroutine-desc.rs:9:19 | LL | fun(async {}, async {}); | --- -------- ^^^^^^^^ expected `async` block, found a different `async` block @@ -8,12 +8,12 @@ LL | fun(async {}, async {}); | | expected all arguments to be this `async` block type because they need to match the type of this parameter | arguments to this function are incorrect | - = note: expected `async` block `{async block@$DIR/coroutine-desc.rs:10:9: 10:14}` - found `async` block `{async block@$DIR/coroutine-desc.rs:10:19: 10:24}` + = note: expected `async` block `{async block@$DIR/coroutine-desc.rs:9:9: 9:14}` + found `async` block `{async block@$DIR/coroutine-desc.rs:9:19: 9:24}` = note: no two async blocks, even if identical, have the same type = help: consider pinning your async block and casting it to a trait object note: function defined here - --> $DIR/coroutine-desc.rs:8:4 + --> $DIR/coroutine-desc.rs:7:4 | LL | fn fun>(f1: F, f2: F) {} | ^^^ - ----- ----- this parameter needs to match the `async` block type of `f1` @@ -22,7 +22,7 @@ LL | fn fun>(f1: F, f2: F) {} | `f1` and `f2` both reference this parameter `F` error[E0308]: mismatched types - --> $DIR/coroutine-desc.rs:12:16 + --> $DIR/coroutine-desc.rs:11:16 | LL | fun(one(), two()); | --- ----- ^^^^^ expected future, found a different future @@ -33,7 +33,7 @@ LL | fun(one(), two()); = help: consider `await`ing on both `Future`s = note: distinct uses of `impl Trait` result in different opaque types note: function defined here - --> $DIR/coroutine-desc.rs:8:4 + --> $DIR/coroutine-desc.rs:7:4 | LL | fn fun>(f1: F, f2: F) {} | ^^^ - ----- ----- this parameter needs to match the future type of `f1` @@ -42,7 +42,7 @@ LL | fn fun>(f1: F, f2: F) {} | `f1` and `f2` both reference this parameter `F` error[E0308]: mismatched types - --> $DIR/coroutine-desc.rs:14:26 + --> $DIR/coroutine-desc.rs:13:26 | LL | fun((async || {})(), (async || {})()); | --- --------------- ^^^^^^^^^^^^^^^ expected `async` closure body, found a different `async` closure body @@ -51,12 +51,12 @@ LL | fun((async || {})(), (async || {})()); | | expected all arguments to be this `async` closure body type because they need to match the type of this parameter | arguments to this function are incorrect | - = note: expected `async` closure body `{async closure body@$DIR/coroutine-desc.rs:14:19: 14:21}` - found `async` closure body `{async closure body@$DIR/coroutine-desc.rs:14:36: 14:38}` + = note: expected `async` closure body `{async closure body@$DIR/coroutine-desc.rs:13:19: 13:21}` + found `async` closure body `{async closure body@$DIR/coroutine-desc.rs:13:36: 13:38}` = note: no two async blocks, even if identical, have the same type = help: consider pinning your async block and casting it to a trait object note: function defined here - --> $DIR/coroutine-desc.rs:8:4 + --> $DIR/coroutine-desc.rs:7:4 | LL | fn fun>(f1: F, f2: F) {} | ^^^ - ----- ----- this parameter needs to match the `async` closure body type of `f1` diff --git a/tests/ui/async-await/feature-async-closure.rs b/tests/ui/async-await/feature-async-closure.rs deleted file mode 100644 index 15108aa5a33c1..0000000000000 --- a/tests/ui/async-await/feature-async-closure.rs +++ /dev/null @@ -1,8 +0,0 @@ -//@ edition:2018 -// gate-test-async_closure - -fn f() { - let _ = async || {}; //~ ERROR async closures are unstable -} - -fn main() {} diff --git a/tests/ui/async-await/feature-async-closure.stderr b/tests/ui/async-await/feature-async-closure.stderr deleted file mode 100644 index 650500b489034..0000000000000 --- a/tests/ui/async-await/feature-async-closure.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error[E0658]: async closures are unstable - --> $DIR/feature-async-closure.rs:5:13 - | -LL | let _ = async || {}; - | ^^^^^ - | - = note: see issue #62290 for more information - = help: add `#![feature(async_closure)]` to the crate attributes to enable - = 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 {` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/async-await/issue-74072-lifetime-name-annotations.rs b/tests/ui/async-await/issue-74072-lifetime-name-annotations.rs index 58509642b10bc..f6c9fdd6d6806 100644 --- a/tests/ui/async-await/issue-74072-lifetime-name-annotations.rs +++ b/tests/ui/async-await/issue-74072-lifetime-name-annotations.rs @@ -1,5 +1,4 @@ //@ edition:2018 -#![feature(async_closure)] use std::future::Future; // test the quality of annotations giving lifetimes names (`'1`) when async constructs are involved diff --git a/tests/ui/async-await/issue-74072-lifetime-name-annotations.stderr b/tests/ui/async-await/issue-74072-lifetime-name-annotations.stderr index 9d963686dea0e..e1f268116fc54 100644 --- a/tests/ui/async-await/issue-74072-lifetime-name-annotations.stderr +++ b/tests/ui/async-await/issue-74072-lifetime-name-annotations.stderr @@ -1,5 +1,5 @@ error[E0506]: cannot assign to `*x` because it is borrowed - --> $DIR/issue-74072-lifetime-name-annotations.rs:9:5 + --> $DIR/issue-74072-lifetime-name-annotations.rs:8:5 | LL | pub async fn async_fn(x: &mut i32) -> &i32 { | - let's call the lifetime of this reference `'1` @@ -11,7 +11,7 @@ LL | y | - returning this value requires that `*x` is borrowed for `'1` error[E0506]: cannot assign to `*x` because it is borrowed - --> $DIR/issue-74072-lifetime-name-annotations.rs:18:9 + --> $DIR/issue-74072-lifetime-name-annotations.rs:17:9 | LL | (async move || { | - return type of async closure is &'1 i32 @@ -24,12 +24,12 @@ LL | y | - returning this value requires that `*x` is borrowed for `'1` error: lifetime may not live long enough - --> $DIR/issue-74072-lifetime-name-annotations.rs:14:20 + --> $DIR/issue-74072-lifetime-name-annotations.rs:13:20 | LL | (async move || { | ______-------------_^ | | | | - | | | return type of async closure `{async closure body@$DIR/issue-74072-lifetime-name-annotations.rs:14:20: 20:6}` contains a lifetime `'2` + | | | return type of async closure `{async closure body@$DIR/issue-74072-lifetime-name-annotations.rs:13:20: 19:6}` contains a lifetime `'2` | | lifetime `'1` represents this closure's body LL | | LL | | @@ -42,7 +42,7 @@ LL | | })() = note: closure implements `FnMut`, so references to captured variables can't escape the closure error[E0716]: temporary value dropped while borrowed - --> $DIR/issue-74072-lifetime-name-annotations.rs:14:5 + --> $DIR/issue-74072-lifetime-name-annotations.rs:13:5 | LL | pub fn async_closure(x: &mut i32) -> impl Future { | - let's call the lifetime of this reference `'1` @@ -60,7 +60,7 @@ LL | } | - temporary value is freed at the end of this statement error[E0506]: cannot assign to `*x` because it is borrowed - --> $DIR/issue-74072-lifetime-name-annotations.rs:28:9 + --> $DIR/issue-74072-lifetime-name-annotations.rs:27:9 | LL | (async move || -> &i32 { | - return type of async closure is &'1 i32 @@ -73,12 +73,12 @@ LL | y | - returning this value requires that `*x` is borrowed for `'1` error: lifetime may not live long enough - --> $DIR/issue-74072-lifetime-name-annotations.rs:24:28 + --> $DIR/issue-74072-lifetime-name-annotations.rs:23:28 | LL | (async move || -> &i32 { | ______---------------------_^ | | | | - | | | return type of async closure `{async closure body@$DIR/issue-74072-lifetime-name-annotations.rs:24:28: 30:6}` contains a lifetime `'2` + | | | return type of async closure `{async closure body@$DIR/issue-74072-lifetime-name-annotations.rs:23:28: 29:6}` contains a lifetime `'2` | | lifetime `'1` represents this closure's body LL | | LL | | @@ -91,7 +91,7 @@ LL | | })() = note: closure implements `FnMut`, so references to captured variables can't escape the closure error[E0716]: temporary value dropped while borrowed - --> $DIR/issue-74072-lifetime-name-annotations.rs:24:5 + --> $DIR/issue-74072-lifetime-name-annotations.rs:23:5 | LL | pub fn async_closure_explicit_return_type(x: &mut i32) -> impl Future { | - let's call the lifetime of this reference `'1` @@ -109,7 +109,7 @@ LL | } | - temporary value is freed at the end of this statement error[E0506]: cannot assign to `*x` because it is borrowed - --> $DIR/issue-74072-lifetime-name-annotations.rs:36:9 + --> $DIR/issue-74072-lifetime-name-annotations.rs:35:9 | LL | async move { | - return type of async block is &'1 i32 diff --git a/tests/ui/async-await/issues/issue-62009-2.rs b/tests/ui/async-await/issues/issue-62009-2.rs index f7cba29a74708..b660d8a206ce5 100644 --- a/tests/ui/async-await/issues/issue-62009-2.rs +++ b/tests/ui/async-await/issues/issue-62009-2.rs @@ -1,7 +1,5 @@ //@ edition:2018 -#![feature(async_closure)] - async fn print_dur() {} fn main() { diff --git a/tests/ui/async-await/issues/issue-62009-2.stderr b/tests/ui/async-await/issues/issue-62009-2.stderr index 0004f99f9018d..9377a02612ba7 100644 --- a/tests/ui/async-await/issues/issue-62009-2.stderr +++ b/tests/ui/async-await/issues/issue-62009-2.stderr @@ -1,5 +1,5 @@ error[E0728]: `await` is only allowed inside `async` functions and blocks - --> $DIR/issue-62009-2.rs:8:23 + --> $DIR/issue-62009-2.rs:6:23 | LL | fn main() { | --------- this is not `async` diff --git a/tests/ui/async-await/no-params-non-move-async-closure.rs b/tests/ui/async-await/no-params-non-move-async-closure.rs index e9e43b3484aa0..48651396d2540 100644 --- a/tests/ui/async-await/no-params-non-move-async-closure.rs +++ b/tests/ui/async-await/no-params-non-move-async-closure.rs @@ -1,8 +1,6 @@ //@ edition:2018 //@ check-pass -#![feature(async_closure)] - fn main() { let _ = async |x: u8| {}; } diff --git a/tests/ui/async-await/suggest-missing-await-closure.fixed b/tests/ui/async-await/suggest-missing-await-closure.fixed index 1ec3456a2655a..9ab16d341752b 100644 --- a/tests/ui/async-await/suggest-missing-await-closure.fixed +++ b/tests/ui/async-await/suggest-missing-await-closure.fixed @@ -1,8 +1,6 @@ //@ edition:2018 //@ run-rustfix -#![feature(async_closure)] - fn take_u32(_x: u32) {} async fn make_u32() -> u32 { diff --git a/tests/ui/async-await/suggest-missing-await-closure.rs b/tests/ui/async-await/suggest-missing-await-closure.rs index 3a448ad411bba..172132fda338b 100644 --- a/tests/ui/async-await/suggest-missing-await-closure.rs +++ b/tests/ui/async-await/suggest-missing-await-closure.rs @@ -1,8 +1,6 @@ //@ edition:2018 //@ run-rustfix -#![feature(async_closure)] - fn take_u32(_x: u32) {} async fn make_u32() -> u32 { diff --git a/tests/ui/async-await/suggest-missing-await-closure.stderr b/tests/ui/async-await/suggest-missing-await-closure.stderr index 47af270a03a82..002c2024f213b 100644 --- a/tests/ui/async-await/suggest-missing-await-closure.stderr +++ b/tests/ui/async-await/suggest-missing-await-closure.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/suggest-missing-await-closure.rs:16:18 + --> $DIR/suggest-missing-await-closure.rs:14:18 | LL | take_u32(x) | -------- ^ expected `u32`, found future @@ -7,12 +7,12 @@ LL | take_u32(x) | arguments to this function are incorrect | note: calling an async function returns a future - --> $DIR/suggest-missing-await-closure.rs:16:18 + --> $DIR/suggest-missing-await-closure.rs:14:18 | LL | take_u32(x) | ^ note: function defined here - --> $DIR/suggest-missing-await-closure.rs:6:4 + --> $DIR/suggest-missing-await-closure.rs:4:4 | LL | fn take_u32(_x: u32) {} | ^^^^^^^^ ------- diff --git a/tests/ui/async-await/track-caller/async-closure-gate.rs b/tests/ui/async-await/track-caller/async-closure-gate.rs index 4b88255bc364c..e72ce2afa45fd 100644 --- a/tests/ui/async-await/track-caller/async-closure-gate.rs +++ b/tests/ui/async-await/track-caller/async-closure-gate.rs @@ -1,7 +1,7 @@ //@ edition:2021 //@ revisions: afn nofeat -#![feature(async_closure, stmt_expr_attributes)] +#![feature(stmt_expr_attributes)] #![cfg_attr(afn, feature(async_fn_track_caller))] fn main() { diff --git a/tests/ui/async-await/track-caller/panic-track-caller.rs b/tests/ui/async-await/track-caller/panic-track-caller.rs index c693a446eed47..bd12bf11d6c84 100644 --- a/tests/ui/async-await/track-caller/panic-track-caller.rs +++ b/tests/ui/async-await/track-caller/panic-track-caller.rs @@ -3,7 +3,7 @@ //@ revisions: afn cls nofeat //@ needs-unwind // gate-test-async_fn_track_caller -#![feature(async_closure, stmt_expr_attributes)] +#![feature(stmt_expr_attributes)] #![cfg_attr(afn, feature(async_fn_track_caller))] #![cfg_attr(cls, feature(closure_track_caller))] #![allow(unused)] diff --git a/tests/ui/async-await/try-on-option-in-async.rs b/tests/ui/async-await/try-on-option-in-async.rs index fda848141d347..4822197bf395e 100644 --- a/tests/ui/async-await/try-on-option-in-async.rs +++ b/tests/ui/async-await/try-on-option-in-async.rs @@ -1,4 +1,3 @@ -#![feature(async_closure)] //@ edition:2018 fn main() {} diff --git a/tests/ui/async-await/try-on-option-in-async.stderr b/tests/ui/async-await/try-on-option-in-async.stderr index 65f63093728dd..9e0bb42a697cc 100644 --- a/tests/ui/async-await/try-on-option-in-async.stderr +++ b/tests/ui/async-await/try-on-option-in-async.stderr @@ -1,5 +1,5 @@ error[E0277]: the `?` operator can only be used in an async block that returns `Result` or `Option` (or another type that implements `FromResidual`) - --> $DIR/try-on-option-in-async.rs:8:10 + --> $DIR/try-on-option-in-async.rs:7:10 | LL | async { | ----- this function should return `Result` or `Option` to accept `?` @@ -10,7 +10,7 @@ LL | x?; = help: the trait `FromResidual>` is not implemented for `{integer}` error[E0277]: the `?` operator can only be used in an async closure that returns `Result` or `Option` (or another type that implements `FromResidual`) - --> $DIR/try-on-option-in-async.rs:17:10 + --> $DIR/try-on-option-in-async.rs:16:10 | LL | let async_closure = async || { | __________________________________- @@ -24,7 +24,7 @@ LL | | }; = help: the trait `FromResidual>` is not implemented for `u32` error[E0277]: the `?` operator can only be used in an async function that returns `Result` or `Option` (or another type that implements `FromResidual`) - --> $DIR/try-on-option-in-async.rs:26:6 + --> $DIR/try-on-option-in-async.rs:25:6 | LL | async fn an_async_function() -> u32 { | _____________________________________- diff --git a/tests/ui/closures/binder/async-closure-with-binder.rs b/tests/ui/closures/binder/async-closure-with-binder.rs index 24f4e8e4175a6..8f84f3074cd53 100644 --- a/tests/ui/closures/binder/async-closure-with-binder.rs +++ b/tests/ui/closures/binder/async-closure-with-binder.rs @@ -2,7 +2,6 @@ //@ check-pass #![feature(closure_lifetime_binder)] -#![feature(async_closure)] fn main() { for<'a> async || -> () {}; diff --git a/tests/ui/closures/local-type-mix.rs b/tests/ui/closures/local-type-mix.rs index 823ceb211a362..edcdac2a61117 100644 --- a/tests/ui/closures/local-type-mix.rs +++ b/tests/ui/closures/local-type-mix.rs @@ -1,8 +1,6 @@ // Check that using the parameter name in its type does not ICE. //@ edition:2018 -#![feature(async_closure)] - fn main() { let _ = |x: x| x; //~ ERROR expected type let _ = |x: bool| -> x { x }; //~ ERROR expected type diff --git a/tests/ui/closures/local-type-mix.stderr b/tests/ui/closures/local-type-mix.stderr index 68c320a065d57..f3b6a73afd5ca 100644 --- a/tests/ui/closures/local-type-mix.stderr +++ b/tests/ui/closures/local-type-mix.stderr @@ -1,47 +1,47 @@ error[E0573]: expected type, found local variable `x` - --> $DIR/local-type-mix.rs:7:17 + --> $DIR/local-type-mix.rs:5:17 | LL | let _ = |x: x| x; | ^ not a type error[E0573]: expected type, found local variable `x` - --> $DIR/local-type-mix.rs:8:26 + --> $DIR/local-type-mix.rs:6:26 | LL | let _ = |x: bool| -> x { x }; | ^ not a type error[E0573]: expected type, found local variable `x` - --> $DIR/local-type-mix.rs:9:28 + --> $DIR/local-type-mix.rs:7:28 | LL | let _ = async move |x: x| x; | ^ not a type error[E0573]: expected type, found local variable `x` - --> $DIR/local-type-mix.rs:10:37 + --> $DIR/local-type-mix.rs:8:37 | LL | let _ = async move |x: bool| -> x { x }; | ^ not a type error[E0573]: expected type, found local variable `x` - --> $DIR/local-type-mix.rs:13:11 + --> $DIR/local-type-mix.rs:11:11 | LL | fn foo(x: x) {} | ^ not a type error[E0573]: expected type, found local variable `x` - --> $DIR/local-type-mix.rs:14:24 + --> $DIR/local-type-mix.rs:12:24 | LL | fn foo_ret(x: bool) -> x {} | ^ not a type error[E0573]: expected type, found local variable `x` - --> $DIR/local-type-mix.rs:16:23 + --> $DIR/local-type-mix.rs:14:23 | LL | async fn async_foo(x: x) {} | ^ not a type error[E0573]: expected type, found local variable `x` - --> $DIR/local-type-mix.rs:17:36 + --> $DIR/local-type-mix.rs:15:36 | LL | async fn async_foo_ret(x: bool) -> x {} | ^ not a type diff --git a/tests/ui/coroutine/break-inside-coroutine-issue-124495.rs b/tests/ui/coroutine/break-inside-coroutine-issue-124495.rs index d0597fdd8e19e..7d8b1a1156c30 100644 --- a/tests/ui/coroutine/break-inside-coroutine-issue-124495.rs +++ b/tests/ui/coroutine/break-inside-coroutine-issue-124495.rs @@ -1,7 +1,6 @@ //@ edition: 2024 #![feature(gen_blocks)] -#![feature(async_closure)] async fn async_fn() { break; //~ ERROR `break` inside `async` function diff --git a/tests/ui/coroutine/break-inside-coroutine-issue-124495.stderr b/tests/ui/coroutine/break-inside-coroutine-issue-124495.stderr index bdd26d39d82a0..ee838fbe694f0 100644 --- a/tests/ui/coroutine/break-inside-coroutine-issue-124495.stderr +++ b/tests/ui/coroutine/break-inside-coroutine-issue-124495.stderr @@ -1,5 +1,5 @@ error[E0267]: `break` inside `async` function - --> $DIR/break-inside-coroutine-issue-124495.rs:7:5 + --> $DIR/break-inside-coroutine-issue-124495.rs:6:5 | LL | async fn async_fn() { | ------------------- enclosing `async` function @@ -7,7 +7,7 @@ LL | break; | ^^^^^ cannot `break` inside `async` function error[E0267]: `break` inside `gen` function - --> $DIR/break-inside-coroutine-issue-124495.rs:11:5 + --> $DIR/break-inside-coroutine-issue-124495.rs:10:5 | LL | gen fn gen_fn() { | --------------- enclosing `gen` function @@ -15,7 +15,7 @@ LL | break; | ^^^^^ cannot `break` inside `gen` function error[E0267]: `break` inside `async gen` function - --> $DIR/break-inside-coroutine-issue-124495.rs:15:5 + --> $DIR/break-inside-coroutine-issue-124495.rs:14:5 | LL | async gen fn async_gen_fn() { | --------------------------- enclosing `async gen` function @@ -23,7 +23,7 @@ LL | break; | ^^^^^ cannot `break` inside `async gen` function error[E0267]: `break` inside `async` block - --> $DIR/break-inside-coroutine-issue-124495.rs:19:21 + --> $DIR/break-inside-coroutine-issue-124495.rs:18:21 | LL | let _ = async { break; }; | ----- ^^^^^ cannot `break` inside `async` block @@ -31,7 +31,7 @@ LL | let _ = async { break; }; | enclosing `async` block error[E0267]: `break` inside `async` closure - --> $DIR/break-inside-coroutine-issue-124495.rs:21:24 + --> $DIR/break-inside-coroutine-issue-124495.rs:20:24 | LL | let _ = async || { break; }; | -------- ^^^^^ cannot `break` inside `async` closure @@ -39,7 +39,7 @@ LL | let _ = async || { break; }; | enclosing `async` closure error[E0267]: `break` inside `gen` block - --> $DIR/break-inside-coroutine-issue-124495.rs:23:19 + --> $DIR/break-inside-coroutine-issue-124495.rs:22:19 | LL | let _ = gen { break; }; | --- ^^^^^ cannot `break` inside `gen` block @@ -47,7 +47,7 @@ LL | let _ = gen { break; }; | enclosing `gen` block error[E0267]: `break` inside `async gen` block - --> $DIR/break-inside-coroutine-issue-124495.rs:25:25 + --> $DIR/break-inside-coroutine-issue-124495.rs:24:25 | LL | let _ = async gen { break; }; | --------- ^^^^^ cannot `break` inside `async gen` block diff --git a/tests/ui/editions/edition-keywords-2018-2015-parsing.rs b/tests/ui/editions/edition-keywords-2018-2015-parsing.rs index c346be5085601..c3dfcfb19cb4b 100644 --- a/tests/ui/editions/edition-keywords-2018-2015-parsing.rs +++ b/tests/ui/editions/edition-keywords-2018-2015-parsing.rs @@ -1,8 +1,6 @@ //@ edition:2018 //@ aux-build:edition-kw-macro-2015.rs -#![feature(async_closure)] - fn main() {} #[macro_use] diff --git a/tests/ui/editions/edition-keywords-2018-2015-parsing.stderr b/tests/ui/editions/edition-keywords-2018-2015-parsing.stderr index aed5837abeafe..905e1249d972d 100644 --- a/tests/ui/editions/edition-keywords-2018-2015-parsing.stderr +++ b/tests/ui/editions/edition-keywords-2018-2015-parsing.stderr @@ -1,5 +1,5 @@ error: expected identifier, found keyword `async` - --> $DIR/edition-keywords-2018-2015-parsing.rs:16:13 + --> $DIR/edition-keywords-2018-2015-parsing.rs:14:13 | LL | let mut async = 1; | ^^^^^ expected identifier, found keyword @@ -10,7 +10,7 @@ LL | let mut r#async = 1; | ++ error: expected identifier, found keyword `async` - --> $DIR/edition-keywords-2018-2015-parsing.rs:28:13 + --> $DIR/edition-keywords-2018-2015-parsing.rs:26:13 | LL | module::async(); | ^^^^^ expected identifier, found keyword @@ -21,7 +21,7 @@ LL | module::r#async(); | ++ error: no rules expected `r#async` - --> $DIR/edition-keywords-2018-2015-parsing.rs:20:31 + --> $DIR/edition-keywords-2018-2015-parsing.rs:18:31 | LL | r#async = consumes_async!(r#async); | ^^^^^^^ no rules expected this token in macro call @@ -33,7 +33,7 @@ LL | (async) => (1) | ^^^^^ error: no rules expected keyword `async` - --> $DIR/edition-keywords-2018-2015-parsing.rs:21:35 + --> $DIR/edition-keywords-2018-2015-parsing.rs:19:35 | LL | r#async = consumes_async_raw!(async); | ^^^^^ no rules expected this token in macro call @@ -50,19 +50,19 @@ error: macro expansion ends with an incomplete expression: expected one of `move LL | ($i: ident) => ($i) | ^ expected one of `move`, `|`, or `||` | - ::: $DIR/edition-keywords-2018-2015-parsing.rs:24:8 + ::: $DIR/edition-keywords-2018-2015-parsing.rs:22:8 | LL | if passes_ident!(async) == 1 {} // FIXME: Edition hygiene bug, async here is 2018 and reserved | -------------------- in this macro invocation error: macro expansion ends with an incomplete expression: expected one of `move`, `|`, or `||` - --> $DIR/edition-keywords-2018-2015-parsing.rs:26:24 + --> $DIR/edition-keywords-2018-2015-parsing.rs:24:24 | LL | if passes_tt!(async) == 1 {} | ^ expected one of `move`, `|`, or `||` error[E0308]: mismatched types - --> $DIR/edition-keywords-2018-2015-parsing.rs:31:33 + --> $DIR/edition-keywords-2018-2015-parsing.rs:29:33 | LL | let _recovery_witness: () = 0; | -- ^ expected `()`, found integer diff --git a/tests/ui/editions/edition-keywords-2018-2018-parsing.rs b/tests/ui/editions/edition-keywords-2018-2018-parsing.rs index b75b68b3febbd..1447c49ef7173 100644 --- a/tests/ui/editions/edition-keywords-2018-2018-parsing.rs +++ b/tests/ui/editions/edition-keywords-2018-2018-parsing.rs @@ -1,8 +1,6 @@ //@ edition:2018 //@ aux-build:edition-kw-macro-2018.rs -#![feature(async_closure)] - fn main() {} #[macro_use] diff --git a/tests/ui/editions/edition-keywords-2018-2018-parsing.stderr b/tests/ui/editions/edition-keywords-2018-2018-parsing.stderr index 6503e9cc73cf1..af5cc515bb224 100644 --- a/tests/ui/editions/edition-keywords-2018-2018-parsing.stderr +++ b/tests/ui/editions/edition-keywords-2018-2018-parsing.stderr @@ -1,5 +1,5 @@ error: expected identifier, found keyword `async` - --> $DIR/edition-keywords-2018-2018-parsing.rs:23:13 + --> $DIR/edition-keywords-2018-2018-parsing.rs:21:13 | LL | let mut async = 1; | ^^^^^ expected identifier, found keyword @@ -10,7 +10,7 @@ LL | let mut r#async = 1; | ++ error: expected identifier, found keyword `async` - --> $DIR/edition-keywords-2018-2018-parsing.rs:39:13 + --> $DIR/edition-keywords-2018-2018-parsing.rs:37:13 | LL | module::async(); | ^^^^^ expected identifier, found keyword @@ -21,7 +21,7 @@ LL | module::r#async(); | ++ error: no rules expected `r#async` - --> $DIR/edition-keywords-2018-2018-parsing.rs:27:31 + --> $DIR/edition-keywords-2018-2018-parsing.rs:25:31 | LL | r#async = consumes_async!(r#async); | ^^^^^^^ no rules expected this token in macro call @@ -33,7 +33,7 @@ LL | (async) => (1) | ^^^^^ error: no rules expected keyword `async` - --> $DIR/edition-keywords-2018-2018-parsing.rs:28:35 + --> $DIR/edition-keywords-2018-2018-parsing.rs:26:35 | LL | r#async = consumes_async_raw!(async); | ^^^^^ no rules expected this token in macro call @@ -50,31 +50,31 @@ error: macro expansion ends with an incomplete expression: expected one of `move LL | ($i: ident) => ($i) | ^ expected one of `move`, `|`, or `||` | - ::: $DIR/edition-keywords-2018-2018-parsing.rs:31:8 + ::: $DIR/edition-keywords-2018-2018-parsing.rs:29:8 | LL | if passes_ident!(async) == 1 {} // FIXME: Edition hygiene bug, async here is 2018 and reserved | -------------------- in this macro invocation error: macro expansion ends with an incomplete expression: expected one of `move`, `|`, or `||` - --> $DIR/edition-keywords-2018-2018-parsing.rs:33:24 + --> $DIR/edition-keywords-2018-2018-parsing.rs:31:24 | LL | if passes_tt!(async) == 1 {} | ^ expected one of `move`, `|`, or `||` error: macro expansion ends with an incomplete expression: expected one of `move`, `|`, or `||` - --> $DIR/edition-keywords-2018-2018-parsing.rs:16:23 + --> $DIR/edition-keywords-2018-2018-parsing.rs:14:23 | LL | ($i: ident) => ($i) | ^ expected one of `move`, `|`, or `||` error: macro expansion ends with an incomplete expression: expected one of `move`, `|`, or `||` - --> $DIR/edition-keywords-2018-2018-parsing.rs:37:30 + --> $DIR/edition-keywords-2018-2018-parsing.rs:35:30 | LL | if local_passes_tt!(async) == 1 {} | ^ expected one of `move`, `|`, or `||` error[E0308]: mismatched types - --> $DIR/edition-keywords-2018-2018-parsing.rs:42:33 + --> $DIR/edition-keywords-2018-2018-parsing.rs:40:33 | LL | let _recovery_witness: () = 0; | -- ^ expected `()`, found integer diff --git a/tests/ui/feature-gates/feature-gate-async-trait-bounds.rs b/tests/ui/feature-gates/feature-gate-async-trait-bounds.rs index db5d7aa06d221..210ce60ef11b3 100644 --- a/tests/ui/feature-gates/feature-gate-async-trait-bounds.rs +++ b/tests/ui/feature-gates/feature-gate-async-trait-bounds.rs @@ -2,6 +2,5 @@ fn test(_: impl async Fn()) {} //~^ ERROR `async` trait bounds are unstable -//~| ERROR use of unstable library feature `async_closure` fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-async-trait-bounds.stderr b/tests/ui/feature-gates/feature-gate-async-trait-bounds.stderr index abc7e37c45f2c..34727aef975f3 100644 --- a/tests/ui/feature-gates/feature-gate-async-trait-bounds.stderr +++ b/tests/ui/feature-gates/feature-gate-async-trait-bounds.stderr @@ -9,16 +9,6 @@ LL | fn test(_: impl async Fn()) {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date = help: use the desugared name of the async trait, such as `AsyncFn` -error[E0658]: use of unstable library feature `async_closure` - --> $DIR/feature-gate-async-trait-bounds.rs:3:23 - | -LL | fn test(_: impl async Fn()) {} - | ^^^^ - | - = note: see issue #62290 for more information - = help: add `#![feature(async_closure)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/issues/auxiliary/issue-111011.rs b/tests/ui/issues/auxiliary/issue-111011.rs index 7130234f41e22..0c1a8ce1cf6e7 100644 --- a/tests/ui/issues/auxiliary/issue-111011.rs +++ b/tests/ui/issues/auxiliary/issue-111011.rs @@ -1,5 +1,3 @@ -#![feature(async_closure)] - //@ edition:2021 fn foo(x: impl FnOnce() -> Box) {} diff --git a/tests/ui/layout/post-mono-layout-cycle-2.rs b/tests/ui/layout/post-mono-layout-cycle-2.rs index 2159dee7463d7..2daac12d7ac93 100644 --- a/tests/ui/layout/post-mono-layout-cycle-2.rs +++ b/tests/ui/layout/post-mono-layout-cycle-2.rs @@ -1,8 +1,6 @@ //@ build-fail //@ edition: 2021 -#![feature(async_closure)] - use std::future::Future; use std::pin::pin; use std::task::*; diff --git a/tests/ui/layout/post-mono-layout-cycle-2.stderr b/tests/ui/layout/post-mono-layout-cycle-2.stderr index 2e8d237844e8e..d8c51deffe3b9 100644 --- a/tests/ui/layout/post-mono-layout-cycle-2.stderr +++ b/tests/ui/layout/post-mono-layout-cycle-2.stderr @@ -1,5 +1,5 @@ error[E0733]: recursion in an async fn requires boxing - --> $DIR/post-mono-layout-cycle-2.rs:30:5 + --> $DIR/post-mono-layout-cycle-2.rs:28:5 | LL | / async fn iter(&mut self, iterator: T) LL | | @@ -13,7 +13,7 @@ LL | Blah::iter(self, iterator).await = note: a recursive `async fn` call must introduce indirection such as `Box::pin` to avoid an infinitely sized future note: the above error was encountered while instantiating `fn Wrap::<()>::ice` - --> $DIR/post-mono-layout-cycle-2.rs:56:9 + --> $DIR/post-mono-layout-cycle-2.rs:54:9 | LL | t.ice(); | ^^^^^^^ diff --git a/tests/ui/lint/unused/lint-unused-mut-variables.rs b/tests/ui/lint/unused/lint-unused-mut-variables.rs index bc38af9867cd9..0467e87ce229b 100644 --- a/tests/ui/lint/unused/lint-unused-mut-variables.rs +++ b/tests/ui/lint/unused/lint-unused-mut-variables.rs @@ -3,7 +3,6 @@ // Exercise the unused_mut attribute in some positive and negative cases #![warn(unused_mut)] -#![feature(async_closure)] async fn baz_async( mut a: i32, diff --git a/tests/ui/lint/unused/lint-unused-mut-variables.stderr b/tests/ui/lint/unused/lint-unused-mut-variables.stderr index dcda1e5306f9e..a16b6a378e935 100644 --- a/tests/ui/lint/unused/lint-unused-mut-variables.stderr +++ b/tests/ui/lint/unused/lint-unused-mut-variables.stderr @@ -1,5 +1,5 @@ warning: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:9:5 + --> $DIR/lint-unused-mut-variables.rs:8:5 | LL | mut a: i32, | ----^ @@ -13,7 +13,7 @@ LL | #![warn(unused_mut)] | ^^^^^^^^^^ warning: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:23:9 + --> $DIR/lint-unused-mut-variables.rs:22:9 | LL | mut a: i32, | ----^ @@ -21,7 +21,7 @@ LL | mut a: i32, | help: remove this `mut` warning: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:14:5 + --> $DIR/lint-unused-mut-variables.rs:13:5 | LL | mut a: i32, | ----^ @@ -29,7 +29,7 @@ LL | mut a: i32, | help: remove this `mut` warning: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:29:9 + --> $DIR/lint-unused-mut-variables.rs:28:9 | LL | mut a: i32, | ----^ @@ -37,7 +37,7 @@ LL | mut a: i32, | help: remove this `mut` warning: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:39:9 + --> $DIR/lint-unused-mut-variables.rs:38:9 | LL | mut a: i32, | ----^ @@ -45,7 +45,7 @@ LL | mut a: i32, | help: remove this `mut` warning: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:48:9 + --> $DIR/lint-unused-mut-variables.rs:47:9 | LL | mut a: i32, | ----^ @@ -53,7 +53,7 @@ LL | mut a: i32, | help: remove this `mut` warning: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:57:9 + --> $DIR/lint-unused-mut-variables.rs:56:9 | LL | mut a: i32, | ----^ @@ -61,7 +61,7 @@ LL | mut a: i32, | help: remove this `mut` warning: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:62:9 + --> $DIR/lint-unused-mut-variables.rs:61:9 | LL | mut a: i32, | ----^ @@ -69,7 +69,7 @@ LL | mut a: i32, | help: remove this `mut` warning: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:107:14 + --> $DIR/lint-unused-mut-variables.rs:106:14 | LL | let x = |mut y: isize| 10; | ----^ @@ -77,7 +77,7 @@ LL | let x = |mut y: isize| 10; | help: remove this `mut` warning: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:69:9 + --> $DIR/lint-unused-mut-variables.rs:68:9 | LL | let mut a = 3; | ----^ @@ -85,7 +85,7 @@ LL | let mut a = 3; | help: remove this `mut` warning: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:71:9 + --> $DIR/lint-unused-mut-variables.rs:70:9 | LL | let mut a = 2; | ----^ @@ -93,7 +93,7 @@ LL | let mut a = 2; | help: remove this `mut` warning: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:73:9 + --> $DIR/lint-unused-mut-variables.rs:72:9 | LL | let mut b = 3; | ----^ @@ -101,7 +101,7 @@ LL | let mut b = 3; | help: remove this `mut` warning: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:75:9 + --> $DIR/lint-unused-mut-variables.rs:74:9 | LL | let mut a = vec![3]; | ----^ @@ -109,7 +109,7 @@ LL | let mut a = vec![3]; | help: remove this `mut` warning: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:77:10 + --> $DIR/lint-unused-mut-variables.rs:76:10 | LL | let (mut a, b) = (1, 2); | ----^ @@ -117,7 +117,7 @@ LL | let (mut a, b) = (1, 2); | help: remove this `mut` warning: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:79:9 + --> $DIR/lint-unused-mut-variables.rs:78:9 | LL | let mut a; | ----^ @@ -125,7 +125,7 @@ LL | let mut a; | help: remove this `mut` warning: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:83:9 + --> $DIR/lint-unused-mut-variables.rs:82:9 | LL | let mut b; | ----^ @@ -133,7 +133,7 @@ LL | let mut b; | help: remove this `mut` warning: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:92:9 + --> $DIR/lint-unused-mut-variables.rs:91:9 | LL | mut x => {} | ----^ @@ -141,7 +141,7 @@ LL | mut x => {} | help: remove this `mut` warning: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:99:10 + --> $DIR/lint-unused-mut-variables.rs:98:10 | LL | (mut x, 1) | | ----^ @@ -149,7 +149,7 @@ LL | (mut x, 1) | | help: remove this `mut` warning: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:112:9 + --> $DIR/lint-unused-mut-variables.rs:111:9 | LL | let mut a = &mut 5; | ----^ @@ -157,7 +157,7 @@ LL | let mut a = &mut 5; | help: remove this `mut` warning: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:117:9 + --> $DIR/lint-unused-mut-variables.rs:116:9 | LL | let mut b = (&mut a,); | ----^ @@ -165,7 +165,7 @@ LL | let mut b = (&mut a,); | help: remove this `mut` warning: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:120:9 + --> $DIR/lint-unused-mut-variables.rs:119:9 | LL | let mut x = &mut 1; | ----^ @@ -173,7 +173,7 @@ LL | let mut x = &mut 1; | help: remove this `mut` warning: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:132:9 + --> $DIR/lint-unused-mut-variables.rs:131:9 | LL | let mut v : &mut Vec<()> = &mut vec![]; | ----^ @@ -181,7 +181,7 @@ LL | let mut v : &mut Vec<()> = &mut vec![]; | help: remove this `mut` warning: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:187:9 + --> $DIR/lint-unused-mut-variables.rs:186:9 | LL | let mut raw_address_of_const = 1; | ----^^^^^^^^^^^^^^^^^^^^ @@ -189,7 +189,7 @@ LL | let mut raw_address_of_const = 1; | help: remove this `mut` warning: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:109:13 + --> $DIR/lint-unused-mut-variables.rs:108:13 | LL | fn what(mut foo: isize) {} | ----^^^ @@ -197,7 +197,7 @@ LL | fn what(mut foo: isize) {} | help: remove this `mut` warning: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:127:20 + --> $DIR/lint-unused-mut-variables.rs:126:20 | LL | fn mut_ref_arg(mut arg : &mut [u8]) -> &mut [u8] { | ----^^^ @@ -205,7 +205,7 @@ LL | fn mut_ref_arg(mut arg : &mut [u8]) -> &mut [u8] { | help: remove this `mut` error: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:205:9 + --> $DIR/lint-unused-mut-variables.rs:204:9 | LL | let mut b = vec![2]; | ----^ @@ -213,13 +213,13 @@ LL | let mut b = vec![2]; | help: remove this `mut` | note: the lint level is defined here - --> $DIR/lint-unused-mut-variables.rs:201:8 + --> $DIR/lint-unused-mut-variables.rs:200:8 | LL | #[deny(unused_mut)] | ^^^^^^^^^^ warning: variable does not need to be mutable - --> $DIR/lint-unused-mut-variables.rs:212:28 + --> $DIR/lint-unused-mut-variables.rs:211:28 | LL | fn write_through_reference(mut arg: &mut Arg) { | ----^^^ diff --git a/tests/ui/lint/unused/lint-unused-variables.rs b/tests/ui/lint/unused/lint-unused-variables.rs index 84c26c334f0ae..e0035d6d7252f 100644 --- a/tests/ui/lint/unused/lint-unused-variables.rs +++ b/tests/ui/lint/unused/lint-unused-variables.rs @@ -1,7 +1,6 @@ //@ compile-flags: --cfg something //@ edition:2018 -#![feature(async_closure)] #![deny(unused_variables)] async fn foo_async( diff --git a/tests/ui/lint/unused/lint-unused-variables.stderr b/tests/ui/lint/unused/lint-unused-variables.stderr index ef590d85aef78..6106d4cd1bfc9 100644 --- a/tests/ui/lint/unused/lint-unused-variables.stderr +++ b/tests/ui/lint/unused/lint-unused-variables.stderr @@ -1,71 +1,71 @@ error: unused variable: `a` - --> $DIR/lint-unused-variables.rs:8:5 + --> $DIR/lint-unused-variables.rs:7:5 | LL | a: i32, | ^ help: if this is intentional, prefix it with an underscore: `_a` | note: the lint level is defined here - --> $DIR/lint-unused-variables.rs:5:9 + --> $DIR/lint-unused-variables.rs:4:9 | LL | #![deny(unused_variables)] | ^^^^^^^^^^^^^^^^ error: unused variable: `a` - --> $DIR/lint-unused-variables.rs:22:9 + --> $DIR/lint-unused-variables.rs:21:9 | LL | a: i32, | ^ help: if this is intentional, prefix it with an underscore: `_a` error: unused variable: `a` - --> $DIR/lint-unused-variables.rs:68:9 + --> $DIR/lint-unused-variables.rs:67:9 | LL | a: i32, | ^ help: if this is intentional, prefix it with an underscore: `_a` error: unused variable: `b` - --> $DIR/lint-unused-variables.rs:14:5 + --> $DIR/lint-unused-variables.rs:13:5 | LL | b: i32, | ^ help: if this is intentional, prefix it with an underscore: `_b` error: unused variable: `b` - --> $DIR/lint-unused-variables.rs:29:9 + --> $DIR/lint-unused-variables.rs:28:9 | LL | b: i32, | ^ help: if this is intentional, prefix it with an underscore: `_b` error: unused variable: `b` - --> $DIR/lint-unused-variables.rs:34:9 + --> $DIR/lint-unused-variables.rs:33:9 | LL | b: i32, | ^ help: if this is intentional, prefix it with an underscore: `_b` error: unused variable: `b` - --> $DIR/lint-unused-variables.rs:42:9 + --> $DIR/lint-unused-variables.rs:41:9 | LL | b: i32, | ^ help: if this is intentional, prefix it with an underscore: `_b` error: unused variable: `b` - --> $DIR/lint-unused-variables.rs:47:9 + --> $DIR/lint-unused-variables.rs:46:9 | LL | b: i32, | ^ help: if this is intentional, prefix it with an underscore: `_b` error: unused variable: `b` - --> $DIR/lint-unused-variables.rs:55:9 + --> $DIR/lint-unused-variables.rs:54:9 | LL | b: i32, | ^ help: if this is intentional, prefix it with an underscore: `_b` error: unused variable: `b` - --> $DIR/lint-unused-variables.rs:60:9 + --> $DIR/lint-unused-variables.rs:59:9 | LL | b: i32, | ^ help: if this is intentional, prefix it with an underscore: `_b` error: unused variable: `b` - --> $DIR/lint-unused-variables.rs:74:9 + --> $DIR/lint-unused-variables.rs:73:9 | LL | b: i32, | ^ help: if this is intentional, prefix it with an underscore: `_b` diff --git a/tests/ui/lint/unused/unused-closure.rs b/tests/ui/lint/unused/unused-closure.rs index 4633038cc9bb3..1f98cdfb21f0f 100644 --- a/tests/ui/lint/unused/unused-closure.rs +++ b/tests/ui/lint/unused/unused-closure.rs @@ -1,7 +1,6 @@ // Test that closures and coroutines are "must use" types. //@ edition:2018 -#![feature(async_closure)] #![feature(coroutines, stmt_expr_attributes)] #![deny(unused_must_use)] diff --git a/tests/ui/lint/unused/unused-closure.stderr b/tests/ui/lint/unused/unused-closure.stderr index c3a82402e0a2e..bc0e5173c33ba 100644 --- a/tests/ui/lint/unused/unused-closure.stderr +++ b/tests/ui/lint/unused/unused-closure.stderr @@ -1,5 +1,5 @@ error: unused closure that must be used - --> $DIR/unused-closure.rs:9:5 + --> $DIR/unused-closure.rs:8:5 | LL | / || { LL | | println!("Hello!"); @@ -8,13 +8,13 @@ LL | | }; | = note: closures are lazy and do nothing unless called note: the lint level is defined here - --> $DIR/unused-closure.rs:6:9 + --> $DIR/unused-closure.rs:5:9 | LL | #![deny(unused_must_use)] | ^^^^^^^^^^^^^^^ error: unused implementer of `Future` that must be used - --> $DIR/unused-closure.rs:13:5 + --> $DIR/unused-closure.rs:12:5 | LL | async {}; | ^^^^^^^^ @@ -22,7 +22,7 @@ LL | async {}; = note: futures do nothing unless you `.await` or poll them error: unused closure that must be used - --> $DIR/unused-closure.rs:14:5 + --> $DIR/unused-closure.rs:13:5 | LL | || async {}; | ^^^^^^^^^^^ @@ -30,7 +30,7 @@ LL | || async {}; = note: closures are lazy and do nothing unless called error: unused closure that must be used - --> $DIR/unused-closure.rs:15:5 + --> $DIR/unused-closure.rs:14:5 | LL | async || {}; | ^^^^^^^^^^^ @@ -38,7 +38,7 @@ LL | async || {}; = note: closures are lazy and do nothing unless called error: unused array of boxed arrays of closures that must be used - --> $DIR/unused-closure.rs:18:5 + --> $DIR/unused-closure.rs:17:5 | LL | [Box::new([|| {}; 10]); 1]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -46,7 +46,7 @@ LL | [Box::new([|| {}; 10]); 1]; = note: closures are lazy and do nothing unless called error: unused closure that must be used - --> $DIR/unused-closure.rs:20:5 + --> $DIR/unused-closure.rs:19:5 | LL | vec![|| "a"].pop().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -54,7 +54,7 @@ LL | vec![|| "a"].pop().unwrap(); = note: closures are lazy and do nothing unless called error: unused closure that must be used - --> $DIR/unused-closure.rs:23:9 + --> $DIR/unused-closure.rs:22:9 | LL | || true; | ^^^^^^^ diff --git a/tests/ui/macros/stringify.rs b/tests/ui/macros/stringify.rs index f405cd253deb5..a560bf4c6ef43 100644 --- a/tests/ui/macros/stringify.rs +++ b/tests/ui/macros/stringify.rs @@ -3,7 +3,6 @@ //@ compile-flags: --test #![allow(incomplete_features)] -#![feature(async_closure)] #![feature(auto_traits)] #![feature(box_patterns)] #![feature(const_trait_impl)] diff --git a/tests/ui/mir/issue-68841.rs b/tests/ui/mir/issue-68841.rs index 5638449b684bc..0eed46eb6ca19 100644 --- a/tests/ui/mir/issue-68841.rs +++ b/tests/ui/mir/issue-68841.rs @@ -2,8 +2,6 @@ //@ edition:2018 //@ build-pass -#![feature(async_closure)] - use std::future::Future; fn async_closure() -> impl Future { diff --git a/tests/ui/rfcs/rfc-2565-param-attrs/param-attrs-cfg.rs b/tests/ui/rfcs/rfc-2565-param-attrs/param-attrs-cfg.rs index e7a5d59958b58..15d2a2f5ebcd0 100644 --- a/tests/ui/rfcs/rfc-2565-param-attrs/param-attrs-cfg.rs +++ b/tests/ui/rfcs/rfc-2565-param-attrs/param-attrs-cfg.rs @@ -1,7 +1,6 @@ //@ compile-flags: --cfg something --check-cfg=cfg(nothing,something) //@ edition:2018 -#![feature(async_closure)] #![deny(unused_variables)] extern "C" { diff --git a/tests/ui/rfcs/rfc-2565-param-attrs/param-attrs-cfg.stderr b/tests/ui/rfcs/rfc-2565-param-attrs/param-attrs-cfg.stderr index 9b92166bcb766..ba92bc4a71d85 100644 --- a/tests/ui/rfcs/rfc-2565-param-attrs/param-attrs-cfg.stderr +++ b/tests/ui/rfcs/rfc-2565-param-attrs/param-attrs-cfg.stderr @@ -1,119 +1,119 @@ error: unused variable: `a` - --> $DIR/param-attrs-cfg.rs:24:23 + --> $DIR/param-attrs-cfg.rs:23:23 | LL | #[cfg(something)] a: i32, | ^ help: if this is intentional, prefix it with an underscore: `_a` | note: the lint level is defined here - --> $DIR/param-attrs-cfg.rs:5:9 + --> $DIR/param-attrs-cfg.rs:4:9 | LL | #![deny(unused_variables)] | ^^^^^^^^^^^^^^^^ error: unused variable: `a` - --> $DIR/param-attrs-cfg.rs:41:27 + --> $DIR/param-attrs-cfg.rs:40:27 | LL | #[cfg(something)] a: i32, | ^ help: if this is intentional, prefix it with an underscore: `_a` error: unused variable: `a` - --> $DIR/param-attrs-cfg.rs:107:27 + --> $DIR/param-attrs-cfg.rs:106:27 | LL | #[cfg(something)] a: i32, | ^ help: if this is intentional, prefix it with an underscore: `_a` error: unused variable: `b` - --> $DIR/param-attrs-cfg.rs:30:23 + --> $DIR/param-attrs-cfg.rs:29:23 | LL | #[cfg(something)] b: i32, | ^ help: if this is intentional, prefix it with an underscore: `_b` error: unused variable: `c` - --> $DIR/param-attrs-cfg.rs:32:40 + --> $DIR/param-attrs-cfg.rs:31:40 | LL | #[cfg_attr(nothing, cfg(nothing))] c: i32, | ^ help: if this is intentional, prefix it with an underscore: `_c` error: unused variable: `b` - --> $DIR/param-attrs-cfg.rs:48:27 + --> $DIR/param-attrs-cfg.rs:47:27 | LL | #[cfg(something)] b: i32, | ^ help: if this is intentional, prefix it with an underscore: `_b` error: unused variable: `c` - --> $DIR/param-attrs-cfg.rs:50:44 + --> $DIR/param-attrs-cfg.rs:49:44 | LL | #[cfg_attr(nothing, cfg(nothing))] c: i32, | ^ help: if this is intentional, prefix it with an underscore: `_c` error: unused variable: `b` - --> $DIR/param-attrs-cfg.rs:56:27 + --> $DIR/param-attrs-cfg.rs:55:27 | LL | #[cfg(something)] b: i32, | ^ help: if this is intentional, prefix it with an underscore: `_b` error: unused variable: `c` - --> $DIR/param-attrs-cfg.rs:58:44 + --> $DIR/param-attrs-cfg.rs:57:44 | LL | #[cfg_attr(nothing, cfg(nothing))] c: i32, | ^ help: if this is intentional, prefix it with an underscore: `_c` error: unused variable: `b` - --> $DIR/param-attrs-cfg.rs:67:27 + --> $DIR/param-attrs-cfg.rs:66:27 | LL | #[cfg(something)] b: i32, | ^ help: if this is intentional, prefix it with an underscore: `_b` error: unused variable: `c` - --> $DIR/param-attrs-cfg.rs:69:44 + --> $DIR/param-attrs-cfg.rs:68:44 | LL | #[cfg_attr(nothing, cfg(nothing))] c: i32, | ^ help: if this is intentional, prefix it with an underscore: `_c` error: unused variable: `b` - --> $DIR/param-attrs-cfg.rs:75:27 + --> $DIR/param-attrs-cfg.rs:74:27 | LL | #[cfg(something)] b: i32, | ^ help: if this is intentional, prefix it with an underscore: `_b` error: unused variable: `c` - --> $DIR/param-attrs-cfg.rs:77:44 + --> $DIR/param-attrs-cfg.rs:76:44 | LL | #[cfg_attr(nothing, cfg(nothing))] c: i32, | ^ help: if this is intentional, prefix it with an underscore: `_c` error: unused variable: `b` - --> $DIR/param-attrs-cfg.rs:86:27 + --> $DIR/param-attrs-cfg.rs:85:27 | LL | #[cfg(something)] b: i32, | ^ help: if this is intentional, prefix it with an underscore: `_b` error: unused variable: `c` - --> $DIR/param-attrs-cfg.rs:88:44 + --> $DIR/param-attrs-cfg.rs:87:44 | LL | #[cfg_attr(nothing, cfg(nothing))] c: i32, | ^ help: if this is intentional, prefix it with an underscore: `_c` error: unused variable: `b` - --> $DIR/param-attrs-cfg.rs:94:27 + --> $DIR/param-attrs-cfg.rs:93:27 | LL | #[cfg(something)] b: i32, | ^ help: if this is intentional, prefix it with an underscore: `_b` error: unused variable: `c` - --> $DIR/param-attrs-cfg.rs:96:44 + --> $DIR/param-attrs-cfg.rs:95:44 | LL | #[cfg_attr(nothing, cfg(nothing))] c: i32, | ^ help: if this is intentional, prefix it with an underscore: `_c` error: unused variable: `b` - --> $DIR/param-attrs-cfg.rs:113:27 + --> $DIR/param-attrs-cfg.rs:112:27 | LL | #[cfg(something)] b: i32, | ^ help: if this is intentional, prefix it with an underscore: `_b` error: unused variable: `c` - --> $DIR/param-attrs-cfg.rs:115:44 + --> $DIR/param-attrs-cfg.rs:114:44 | LL | #[cfg_attr(nothing, cfg(nothing))] c: i32, | ^ help: if this is intentional, prefix it with an underscore: `_c` diff --git a/tests/ui/sanitizer/cfi/async-closures.rs b/tests/ui/sanitizer/cfi/async-closures.rs index 4eaa44cfa3f47..351853ab1a710 100644 --- a/tests/ui/sanitizer/cfi/async-closures.rs +++ b/tests/ui/sanitizer/cfi/async-closures.rs @@ -13,7 +13,6 @@ //@ [kcfi] compile-flags: -C panic=abort -Z panic-abort-tests -C prefer-dynamic=off //@ run-pass -#![feature(async_closure)] #![feature(async_fn_traits)] use std::ops::AsyncFn; diff --git a/tests/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs b/tests/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs index 11ed167b44abf..8e67f4e7398cd 100644 --- a/tests/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs +++ b/tests/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs @@ -1,5 +1,4 @@ //@ edition:2018 -#![feature(async_closure)] use std::future::Future; async fn foo() {} diff --git a/tests/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr b/tests/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr index a040e71cf3b22..696b156d5a5f0 100644 --- a/tests/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr +++ b/tests/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr @@ -1,5 +1,5 @@ error[E0277]: `fn() -> impl Future {foo}` is not a future - --> $DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:10:9 + --> $DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:9:9 | LL | bar(foo); | --- ^^^ `fn() -> impl Future {foo}` is not a future @@ -8,7 +8,7 @@ LL | bar(foo); | = help: the trait `Future` is not implemented for fn item `fn() -> impl Future {foo}` note: required by a bound in `bar` - --> $DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:7:16 + --> $DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:6:16 | LL | fn bar(f: impl Future) {} | ^^^^^^^^^^^^^^^^^ required by this bound in `bar` @@ -17,17 +17,17 @@ help: use parentheses to call this function LL | bar(foo()); | ++ -error[E0277]: `{async closure@$DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:11:25: 11:33}` is not a future - --> $DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:12:9 +error[E0277]: `{async closure@$DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:10:25: 10:33}` is not a future + --> $DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:11:9 | LL | bar(async_closure); - | --- ^^^^^^^^^^^^^ `{async closure@$DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:11:25: 11:33}` is not a future + | --- ^^^^^^^^^^^^^ `{async closure@$DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:10:25: 10:33}` is not a future | | | required by a bound introduced by this call | - = help: the trait `Future` is not implemented for `{async closure@$DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:11:25: 11:33}` + = help: the trait `Future` is not implemented for `{async closure@$DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:10:25: 10:33}` note: required by a bound in `bar` - --> $DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:7:16 + --> $DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:6:16 | LL | fn bar(f: impl Future) {} | ^^^^^^^^^^^^^^^^^ required by this bound in `bar` diff --git a/tests/ui/suggestions/suggest-boxed-empty-block.fixed b/tests/ui/suggestions/suggest-boxed-empty-block.fixed index 25cb4dc74b113..a43e4405a7616 100644 --- a/tests/ui/suggestions/suggest-boxed-empty-block.fixed +++ b/tests/ui/suggestions/suggest-boxed-empty-block.fixed @@ -1,5 +1,3 @@ -#![feature(async_closure)] - //@ edition:2021 //@ run-rustfix diff --git a/tests/ui/suggestions/suggest-boxed-empty-block.rs b/tests/ui/suggestions/suggest-boxed-empty-block.rs index 9a8d6498fb149..47fb08e4d11f5 100644 --- a/tests/ui/suggestions/suggest-boxed-empty-block.rs +++ b/tests/ui/suggestions/suggest-boxed-empty-block.rs @@ -1,5 +1,3 @@ -#![feature(async_closure)] - //@ edition:2021 //@ run-rustfix diff --git a/tests/ui/suggestions/suggest-boxed-empty-block.stderr b/tests/ui/suggestions/suggest-boxed-empty-block.stderr index 474a37b888f35..e4602341c1f6a 100644 --- a/tests/ui/suggestions/suggest-boxed-empty-block.stderr +++ b/tests/ui/suggestions/suggest-boxed-empty-block.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/suggest-boxed-empty-block.rs:10:9 + --> $DIR/suggest-boxed-empty-block.rs:8:9 | LL | foo({}); | ^^ expected `Box<_>`, found `()` @@ -14,7 +14,7 @@ LL + foo(Box::new(())); | error[E0308]: mismatched types - --> $DIR/suggest-boxed-empty-block.rs:11:12 + --> $DIR/suggest-boxed-empty-block.rs:9:12 | LL | bar(|| {}); | ^^ expected `Box<_>`, found `()` diff --git a/tests/ui/suggestions/suggest-on-bare-closure-call.rs b/tests/ui/suggestions/suggest-on-bare-closure-call.rs index 046fe4803eca8..1e6b422de5efb 100644 --- a/tests/ui/suggestions/suggest-on-bare-closure-call.rs +++ b/tests/ui/suggestions/suggest-on-bare-closure-call.rs @@ -1,7 +1,5 @@ //@ edition:2021 -#![feature(async_closure)] - fn main() { let _ = ||{}(); //~^ ERROR expected function, found `()` diff --git a/tests/ui/suggestions/suggest-on-bare-closure-call.stderr b/tests/ui/suggestions/suggest-on-bare-closure-call.stderr index e65a6eb4939d9..7bbb24aa6221d 100644 --- a/tests/ui/suggestions/suggest-on-bare-closure-call.stderr +++ b/tests/ui/suggestions/suggest-on-bare-closure-call.stderr @@ -1,5 +1,5 @@ error[E0618]: expected function, found `()` - --> $DIR/suggest-on-bare-closure-call.rs:6:15 + --> $DIR/suggest-on-bare-closure-call.rs:4:15 | LL | let _ = ||{}(); | ^^-- @@ -12,7 +12,7 @@ LL | let _ = (||{})(); | + + error[E0618]: expected function, found `()` - --> $DIR/suggest-on-bare-closure-call.rs:9:21 + --> $DIR/suggest-on-bare-closure-call.rs:7:21 | LL | let _ = async ||{}(); | ^^-- diff --git a/tests/ui/unpretty/expanded-exhaustive.rs b/tests/ui/unpretty/expanded-exhaustive.rs index 9af57fe4c3cd0..98fe05cf7c8b4 100644 --- a/tests/ui/unpretty/expanded-exhaustive.rs +++ b/tests/ui/unpretty/expanded-exhaustive.rs @@ -2,7 +2,6 @@ //@ edition:2024 //@ check-pass -#![feature(async_closure)] #![feature(auto_traits)] #![feature(box_patterns)] #![feature(builtin_syntax)] diff --git a/tests/ui/unpretty/expanded-exhaustive.stdout b/tests/ui/unpretty/expanded-exhaustive.stdout index 14a274415ca72..452c06dd7e4e7 100644 --- a/tests/ui/unpretty/expanded-exhaustive.stdout +++ b/tests/ui/unpretty/expanded-exhaustive.stdout @@ -3,7 +3,6 @@ //@ edition:2024 //@ check-pass -#![feature(async_closure)] #![feature(auto_traits)] #![feature(box_patterns)] #![feature(builtin_syntax)] From 5a1a5e8bb779dc426005aca5bbbc240d29f032ec Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 12 Dec 2024 23:22:02 +0000 Subject: [PATCH 20/20] Reword prelude for AsyncFn stabilization --- library/std/src/prelude/mod.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/library/std/src/prelude/mod.rs b/library/std/src/prelude/mod.rs index fffc1e9264e7c..64349987fcfb8 100644 --- a/library/std/src/prelude/mod.rs +++ b/library/std/src/prelude/mod.rs @@ -33,8 +33,9 @@ //! //! * [std::marker]::{[Copy], [Send], [Sized], [Sync], [Unpin]}, //! marker traits that indicate fundamental properties of types. -//! * [std::ops]::{[Drop], [Fn], [FnMut], [FnOnce]}, various -//! operations for both destructors and overloading `()`. +//! * [std::ops]::{[Fn], [FnMut], [FnOnce]}, and their analogous +//! async traits, [std::ops]::{[AsyncFn], [AsyncFnMut], [AsyncFnOnce]}. +//! * [std::ops]::[Drop], for implementing destructors. //! * [std::mem]::[drop], a convenience function for explicitly //! dropping a value. //! * [std::mem]::{[size_of], [size_of_val]}, to get the size of