Add UseCloned trait related code
This commit is contained in:
parent
57cb498989
commit
dcdfd551f0
16 changed files with 198 additions and 44 deletions
|
@ -171,6 +171,7 @@ language_item_table! {
|
||||||
Copy, sym::copy, copy_trait, Target::Trait, GenericRequirement::Exact(0);
|
Copy, sym::copy, copy_trait, Target::Trait, GenericRequirement::Exact(0);
|
||||||
Clone, sym::clone, clone_trait, Target::Trait, GenericRequirement::None;
|
Clone, sym::clone, clone_trait, Target::Trait, GenericRequirement::None;
|
||||||
CloneFn, sym::clone_fn, clone_fn, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::None;
|
CloneFn, sym::clone_fn, clone_fn, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::None;
|
||||||
|
UseCloned, sym::use_cloned, use_cloned_trait, Target::Trait, GenericRequirement::None;
|
||||||
Sync, sym::sync, sync_trait, Target::Trait, GenericRequirement::Exact(0);
|
Sync, sym::sync, sync_trait, Target::Trait, GenericRequirement::Exact(0);
|
||||||
DiscriminantKind, sym::discriminant_kind, discriminant_kind_trait, Target::Trait, GenericRequirement::None;
|
DiscriminantKind, sym::discriminant_kind, discriminant_kind_trait, Target::Trait, GenericRequirement::None;
|
||||||
/// The associated item of the `DiscriminantKind` trait.
|
/// The associated item of the `DiscriminantKind` trait.
|
||||||
|
|
|
@ -11,6 +11,7 @@ use rustc_middle::thir::*;
|
||||||
use rustc_middle::ty::{CanonicalUserTypeAnnotation, Ty};
|
use rustc_middle::ty::{CanonicalUserTypeAnnotation, Ty};
|
||||||
use rustc_span::DUMMY_SP;
|
use rustc_span::DUMMY_SP;
|
||||||
use rustc_span::source_map::Spanned;
|
use rustc_span::source_map::Spanned;
|
||||||
|
use rustc_trait_selection::infer::InferCtxtExt;
|
||||||
use tracing::{debug, instrument};
|
use tracing::{debug, instrument};
|
||||||
|
|
||||||
use crate::builder::expr::category::{Category, RvalueFunc};
|
use crate::builder::expr::category::{Category, RvalueFunc};
|
||||||
|
@ -295,33 +296,52 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
let place = unpack!(block = this.as_place(block, expr));
|
let place = unpack!(block = this.as_place(block, expr));
|
||||||
let ty = place.ty(&this.local_decls, this.tcx).ty;
|
let ty = place.ty(&this.local_decls, this.tcx).ty;
|
||||||
|
|
||||||
// Convert `expr.use` to a call like `Clone::clone(&expr)`
|
if this.tcx.type_is_copy_modulo_regions(this.infcx.typing_env(this.param_env), ty) {
|
||||||
let success = this.cfg.start_new_block();
|
this.cfg.push_assign(
|
||||||
let clone_trait = this.tcx.require_lang_item(LangItem::Clone, None);
|
block,
|
||||||
let clone_fn = this.tcx.associated_item_def_ids(clone_trait)[0];
|
source_info,
|
||||||
let func = Operand::function_handle(this.tcx, clone_fn, [ty.into()], expr_span);
|
|
||||||
let ref_ty = Ty::new_imm_ref(this.tcx, this.tcx.lifetimes.re_erased, ty);
|
|
||||||
let ref_place = this.temp(ref_ty, span);
|
|
||||||
this.cfg.push_assign(
|
|
||||||
block,
|
|
||||||
source_info,
|
|
||||||
ref_place,
|
|
||||||
Rvalue::Ref(this.tcx.lifetimes.re_erased, BorrowKind::Shared, place),
|
|
||||||
);
|
|
||||||
this.cfg.terminate(
|
|
||||||
block,
|
|
||||||
source_info,
|
|
||||||
TerminatorKind::Call {
|
|
||||||
func,
|
|
||||||
args: [Spanned { node: Operand::Move(ref_place), span: DUMMY_SP }].into(),
|
|
||||||
destination,
|
destination,
|
||||||
target: Some(success),
|
Rvalue::Use(Operand::Copy(place)),
|
||||||
unwind: UnwindAction::Unreachable,
|
);
|
||||||
call_source: CallSource::Misc,
|
block.unit()
|
||||||
fn_span: expr_span,
|
} else if this.infcx.type_is_use_cloned_modulo_regions(this.param_env, ty) {
|
||||||
},
|
// Convert `expr.use` to a call like `Clone::clone(&expr)`
|
||||||
);
|
let success = this.cfg.start_new_block();
|
||||||
success.unit()
|
let clone_trait = this.tcx.require_lang_item(LangItem::Clone, None);
|
||||||
|
let clone_fn = this.tcx.associated_item_def_ids(clone_trait)[0];
|
||||||
|
let func = Operand::function_handle(this.tcx, clone_fn, [ty.into()], expr_span);
|
||||||
|
let ref_ty = Ty::new_imm_ref(this.tcx, this.tcx.lifetimes.re_erased, ty);
|
||||||
|
let ref_place = this.temp(ref_ty, span);
|
||||||
|
this.cfg.push_assign(
|
||||||
|
block,
|
||||||
|
source_info,
|
||||||
|
ref_place,
|
||||||
|
Rvalue::Ref(this.tcx.lifetimes.re_erased, BorrowKind::Shared, place),
|
||||||
|
);
|
||||||
|
this.cfg.terminate(
|
||||||
|
block,
|
||||||
|
source_info,
|
||||||
|
TerminatorKind::Call {
|
||||||
|
func,
|
||||||
|
args: [Spanned { node: Operand::Move(ref_place), span: DUMMY_SP }]
|
||||||
|
.into(),
|
||||||
|
destination,
|
||||||
|
target: Some(success),
|
||||||
|
unwind: UnwindAction::Unreachable,
|
||||||
|
call_source: CallSource::Misc,
|
||||||
|
fn_span: expr_span,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
success.unit()
|
||||||
|
} else {
|
||||||
|
this.cfg.push_assign(
|
||||||
|
block,
|
||||||
|
source_info,
|
||||||
|
destination,
|
||||||
|
Rvalue::Use(Operand::Move(place)),
|
||||||
|
);
|
||||||
|
block.unit()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ExprKind::Use { source } => this.expr_into_dest(destination, block, source),
|
ExprKind::Use { source } => this.expr_into_dest(destination, block, source),
|
||||||
ExprKind::Borrow { arg, borrow_kind } => {
|
ExprKind::Borrow { arg, borrow_kind } => {
|
||||||
|
|
|
@ -2182,6 +2182,7 @@ symbols! {
|
||||||
unwrap,
|
unwrap,
|
||||||
unwrap_binder,
|
unwrap_binder,
|
||||||
unwrap_or,
|
unwrap_or,
|
||||||
|
use_cloned,
|
||||||
use_extern_macros,
|
use_extern_macros,
|
||||||
use_nested_groups,
|
use_nested_groups,
|
||||||
used,
|
used,
|
||||||
|
|
|
@ -53,6 +53,16 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||||
traits::type_known_to_meet_bound_modulo_regions(self, param_env, ty, clone_def_id)
|
traits::type_known_to_meet_bound_modulo_regions(self, param_env, ty, clone_def_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn type_is_use_cloned_modulo_regions(
|
||||||
|
&self,
|
||||||
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
|
ty: Ty<'tcx>,
|
||||||
|
) -> bool {
|
||||||
|
let ty = self.resolve_vars_if_possible(ty);
|
||||||
|
let use_cloned_def_id = self.tcx.require_lang_item(LangItem::UseCloned, None);
|
||||||
|
traits::type_known_to_meet_bound_modulo_regions(self, param_env, ty, use_cloned_def_id)
|
||||||
|
}
|
||||||
|
|
||||||
fn type_is_sized_modulo_regions(&self, param_env: ty::ParamEnv<'tcx>, ty: Ty<'tcx>) -> bool {
|
fn type_is_sized_modulo_regions(&self, param_env: ty::ParamEnv<'tcx>, ty: Ty<'tcx>) -> bool {
|
||||||
let lang_item = self.tcx.require_lang_item(LangItem::Sized, None);
|
let lang_item = self.tcx.require_lang_item(LangItem::Sized, None);
|
||||||
traits::type_known_to_meet_bound_modulo_regions(self, param_env, ty, lang_item)
|
traits::type_known_to_meet_bound_modulo_regions(self, param_env, ty, lang_item)
|
||||||
|
|
|
@ -113,6 +113,7 @@
|
||||||
#![feature(deprecated_suggestion)]
|
#![feature(deprecated_suggestion)]
|
||||||
#![feature(deref_pure_trait)]
|
#![feature(deref_pure_trait)]
|
||||||
#![feature(dispatch_from_dyn)]
|
#![feature(dispatch_from_dyn)]
|
||||||
|
#![feature(ergonomic_clones)]
|
||||||
#![feature(error_generic_member_access)]
|
#![feature(error_generic_member_access)]
|
||||||
#![feature(exact_size_is_empty)]
|
#![feature(exact_size_is_empty)]
|
||||||
#![feature(extend_one)]
|
#![feature(extend_one)]
|
||||||
|
|
|
@ -245,6 +245,7 @@ use core::any::Any;
|
||||||
use core::cell::Cell;
|
use core::cell::Cell;
|
||||||
#[cfg(not(no_global_oom_handling))]
|
#[cfg(not(no_global_oom_handling))]
|
||||||
use core::clone::CloneToUninit;
|
use core::clone::CloneToUninit;
|
||||||
|
use core::clone::UseCloned;
|
||||||
use core::cmp::Ordering;
|
use core::cmp::Ordering;
|
||||||
use core::hash::{Hash, Hasher};
|
use core::hash::{Hash, Hasher};
|
||||||
use core::intrinsics::abort;
|
use core::intrinsics::abort;
|
||||||
|
@ -2333,6 +2334,9 @@ impl<T: ?Sized, A: Allocator + Clone> Clone for Rc<T, A> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[unstable(feature = "ergonomic_clones", issue = "132290")]
|
||||||
|
impl<T: ?Sized, A: Allocator + Clone> UseCloned for Rc<T, A> {}
|
||||||
|
|
||||||
#[cfg(not(no_global_oom_handling))]
|
#[cfg(not(no_global_oom_handling))]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl<T: Default> Default for Rc<T> {
|
impl<T: Default> Default for Rc<T> {
|
||||||
|
@ -3496,6 +3500,9 @@ impl<T: ?Sized, A: Allocator + Clone> Clone for Weak<T, A> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[unstable(feature = "ergonomic_clones", issue = "132290")]
|
||||||
|
impl<T: ?Sized, A: Allocator + Clone> UseCloned for Weak<T, A> {}
|
||||||
|
|
||||||
#[stable(feature = "rc_weak", since = "1.4.0")]
|
#[stable(feature = "rc_weak", since = "1.4.0")]
|
||||||
impl<T: ?Sized, A: Allocator> fmt::Debug for Weak<T, A> {
|
impl<T: ?Sized, A: Allocator> fmt::Debug for Weak<T, A> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
use core::any::Any;
|
use core::any::Any;
|
||||||
#[cfg(not(no_global_oom_handling))]
|
#[cfg(not(no_global_oom_handling))]
|
||||||
use core::clone::CloneToUninit;
|
use core::clone::CloneToUninit;
|
||||||
|
use core::clone::UseCloned;
|
||||||
use core::cmp::Ordering;
|
use core::cmp::Ordering;
|
||||||
use core::hash::{Hash, Hasher};
|
use core::hash::{Hash, Hasher};
|
||||||
use core::intrinsics::abort;
|
use core::intrinsics::abort;
|
||||||
|
@ -2197,6 +2198,9 @@ impl<T: ?Sized, A: Allocator + Clone> Clone for Arc<T, A> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[unstable(feature = "ergonomic_clones", issue = "132290")]
|
||||||
|
impl<T: ?Sized, A: Allocator + Clone> UseCloned for Arc<T, A> {}
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl<T: ?Sized, A: Allocator> Deref for Arc<T, A> {
|
impl<T: ?Sized, A: Allocator> Deref for Arc<T, A> {
|
||||||
type Target = T;
|
type Target = T;
|
||||||
|
@ -3158,6 +3162,9 @@ impl<T: ?Sized, A: Allocator + Clone> Clone for Weak<T, A> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[unstable(feature = "ergonomic_clones", issue = "132290")]
|
||||||
|
impl<T: ?Sized, A: Allocator + Clone> UseCloned for Weak<T, A> {}
|
||||||
|
|
||||||
#[stable(feature = "downgraded_weak", since = "1.10.0")]
|
#[stable(feature = "downgraded_weak", since = "1.10.0")]
|
||||||
impl<T> Default for Weak<T> {
|
impl<T> Default for Weak<T> {
|
||||||
/// Constructs a new `Weak<T>`, without allocating memory.
|
/// Constructs a new `Weak<T>`, without allocating memory.
|
||||||
|
|
|
@ -184,6 +184,40 @@ pub macro Clone($item:item) {
|
||||||
/* compiler built-in */
|
/* compiler built-in */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Trait for objects whose [`Clone`] impl is lightweight (e.g. reference-counted)
|
||||||
|
///
|
||||||
|
/// Cloning an object implementing this trait should in general:
|
||||||
|
/// - be O(1) (constant) time regardless of the amount of data managed by the object,
|
||||||
|
/// - not require a memory allocation,
|
||||||
|
/// - not require copying more than roughly 64 bytes (a typical cache line size),
|
||||||
|
/// - not block the current thread,
|
||||||
|
/// - not have any semantic side effects (e.g. allocating a file descriptor), and
|
||||||
|
/// - not have overhead larger than a couple of atomic operations.
|
||||||
|
///
|
||||||
|
/// The `UseCloned` trait does not provide a method; instead, it indicates that
|
||||||
|
/// `Clone::clone` is lightweight, and allows the use of the `.use` syntax.
|
||||||
|
#[unstable(feature = "ergonomic_clones", issue = "132290")]
|
||||||
|
#[cfg_attr(not(bootstrap), lang = "use_cloned")]
|
||||||
|
pub trait UseCloned: Clone {
|
||||||
|
// Empty.
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! impl_use_cloned {
|
||||||
|
($($t:ty)*) => {
|
||||||
|
$(
|
||||||
|
#[unstable(feature = "ergonomic_clones", issue = "132290")]
|
||||||
|
impl UseCloned for $t {}
|
||||||
|
)*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl_use_cloned! {
|
||||||
|
usize u8 u16 u32 u64 u128
|
||||||
|
isize i8 i16 i32 i64 i128
|
||||||
|
f16 f32 f64 f128
|
||||||
|
bool char
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME(aburka): these structs are used solely by #[derive] to
|
// FIXME(aburka): these structs are used solely by #[derive] to
|
||||||
// assert that every component of a type implements Clone or Copy.
|
// assert that every component of a type implements Clone or Copy.
|
||||||
//
|
//
|
||||||
|
|
|
@ -405,6 +405,8 @@ macro_rules! define_bignum {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl crate::clone::UseCloned for $name {}
|
||||||
|
|
||||||
impl crate::fmt::Debug for $name {
|
impl crate::fmt::Debug for $name {
|
||||||
fn fmt(&self, f: &mut crate::fmt::Formatter<'_>) -> crate::fmt::Result {
|
fn fmt(&self, f: &mut crate::fmt::Formatter<'_>) -> crate::fmt::Result {
|
||||||
let sz = if self.size < 1 { 1 } else { self.size };
|
let sz = if self.size < 1 { 1 } else { self.size };
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
//! Definitions of integer that is known not to equal zero.
|
//! Definitions of integer that is known not to equal zero.
|
||||||
|
|
||||||
use super::{IntErrorKind, ParseIntError};
|
use super::{IntErrorKind, ParseIntError};
|
||||||
|
use crate::clone::UseCloned;
|
||||||
use crate::cmp::Ordering;
|
use crate::cmp::Ordering;
|
||||||
use crate::hash::{Hash, Hasher};
|
use crate::hash::{Hash, Hasher};
|
||||||
use crate::marker::{Freeze, StructuralPartialEq};
|
use crate::marker::{Freeze, StructuralPartialEq};
|
||||||
|
@ -183,6 +184,9 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[unstable(feature = "ergonomic_clones", issue = "132290")]
|
||||||
|
impl<T> UseCloned for NonZero<T> where T: ZeroablePrimitive {}
|
||||||
|
|
||||||
#[stable(feature = "nonzero", since = "1.28.0")]
|
#[stable(feature = "nonzero", since = "1.28.0")]
|
||||||
impl<T> Copy for NonZero<T> where T: ZeroablePrimitive {}
|
impl<T> Copy for NonZero<T> where T: ZeroablePrimitive {}
|
||||||
|
|
||||||
|
|
|
@ -2050,6 +2050,9 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[unstable(feature = "ergonomic_clones", issue = "132290")]
|
||||||
|
impl<T> crate::clone::UseCloned for Option<T> where T: crate::clone::UseCloned {}
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl<T> Default for Option<T> {
|
impl<T> Default for Option<T> {
|
||||||
/// Returns [`None`][Option::None].
|
/// Returns [`None`][Option::None].
|
||||||
|
|
|
@ -1744,6 +1744,14 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[unstable(feature = "ergonomic_clones", issue = "132290")]
|
||||||
|
impl<T, E> crate::clone::UseCloned for Result<T, E>
|
||||||
|
where
|
||||||
|
T: crate::clone::UseCloned,
|
||||||
|
E: crate::clone::UseCloned,
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl<T, E> IntoIterator for Result<T, E> {
|
impl<T, E> IntoIterator for Result<T, E> {
|
||||||
type Item = T;
|
type Item = T;
|
||||||
|
|
|
@ -3,6 +3,9 @@
|
||||||
|
|
||||||
#![feature(ergonomic_clones)]
|
#![feature(ergonomic_clones)]
|
||||||
|
|
||||||
|
use std::clone::UseCloned;
|
||||||
|
use std::future::Future;
|
||||||
|
|
||||||
fn ergonomic_clone_closure_no_captures() -> i32 {
|
fn ergonomic_clone_closure_no_captures() -> i32 {
|
||||||
let cl = use || {
|
let cl = use || {
|
||||||
1
|
1
|
||||||
|
@ -10,7 +13,7 @@ fn ergonomic_clone_closure_no_captures() -> i32 {
|
||||||
cl()
|
cl()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ergonomic_clone_closure_with_captures() -> String {
|
fn ergonomic_clone_closure_move() -> String {
|
||||||
let s = String::from("hi");
|
let s = String::from("hi");
|
||||||
|
|
||||||
let cl = use || {
|
let cl = use || {
|
||||||
|
@ -19,14 +22,31 @@ fn ergonomic_clone_closure_with_captures() -> String {
|
||||||
cl()
|
cl()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ergonomic_clone_async_closures() -> String {
|
#[derive(Clone)]
|
||||||
|
struct Foo;
|
||||||
|
|
||||||
|
impl UseCloned for Foo {}
|
||||||
|
|
||||||
|
fn ergonomic_clone_closure_use_cloned() -> Foo {
|
||||||
|
let f = Foo;
|
||||||
|
|
||||||
|
let f1 = use || {
|
||||||
|
f
|
||||||
|
};
|
||||||
|
|
||||||
|
let f2 = use || {
|
||||||
|
f
|
||||||
|
};
|
||||||
|
|
||||||
|
f
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ergonomic_clone_async_closures() -> impl Future<Output = String> {
|
||||||
let s = String::from("hi");
|
let s = String::from("hi");
|
||||||
|
|
||||||
async use {
|
async use {
|
||||||
s
|
s
|
||||||
};
|
}
|
||||||
|
|
||||||
s
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -2,11 +2,18 @@
|
||||||
|
|
||||||
#![feature(ergonomic_clones)]
|
#![feature(ergonomic_clones)]
|
||||||
|
|
||||||
|
use std::clone::UseCloned;
|
||||||
|
|
||||||
fn basic_test(x: i32) -> i32 {
|
fn basic_test(x: i32) -> i32 {
|
||||||
x.use.use.abs()
|
x.use.use.abs()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn do_not_move_test(x: String) -> String {
|
#[derive(Clone)]
|
||||||
|
struct Foo;
|
||||||
|
|
||||||
|
impl UseCloned for Foo {}
|
||||||
|
|
||||||
|
fn do_not_move_test(x: Foo) -> Foo {
|
||||||
let s = x.use;
|
let s = x.use;
|
||||||
x
|
x
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +1,28 @@
|
||||||
|
use std::clone::UseCloned;
|
||||||
|
//~^ ERROR use of unstable library feature `ergonomic_clones` [E0658]
|
||||||
|
|
||||||
fn ergonomic_clone(x: i32) -> i32 {
|
fn ergonomic_clone(x: i32) -> i32 {
|
||||||
x.use
|
x.use
|
||||||
//~^ ERROR `.use` calls are experimental [E0658]
|
//~^ ERROR `.use` calls are experimental [E0658]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ergonomic_closure_clone() {
|
#[derive(Clone)]
|
||||||
let s1 = String::from("hi!");
|
struct Foo;
|
||||||
|
|
||||||
let s2 = use || {
|
impl UseCloned for Foo {}
|
||||||
|
//~^ ERROR use of unstable library feature `ergonomic_clones` [E0658]
|
||||||
|
|
||||||
|
fn ergonomic_closure_clone() {
|
||||||
|
let f1 = Foo;
|
||||||
|
|
||||||
|
let f2 = use || {
|
||||||
//~^ ERROR `.use` calls are experimental [E0658]
|
//~^ ERROR `.use` calls are experimental [E0658]
|
||||||
s1
|
f1
|
||||||
};
|
};
|
||||||
|
|
||||||
let s3 = use || {
|
let f3 = use || {
|
||||||
//~^ ERROR `.use` calls are experimental [E0658]
|
//~^ ERROR `.use` calls are experimental [E0658]
|
||||||
s1
|
f1
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error[E0658]: `.use` calls are experimental
|
error[E0658]: `.use` calls are experimental
|
||||||
--> $DIR/feature-gate-ergonomic-clones.rs:2:7
|
--> $DIR/feature-gate-ergonomic-clones.rs:5:7
|
||||||
|
|
|
|
||||||
LL | x.use
|
LL | x.use
|
||||||
| ^^^
|
| ^^^
|
||||||
|
@ -9,9 +9,9 @@ LL | x.use
|
||||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||||
|
|
||||||
error[E0658]: `.use` calls are experimental
|
error[E0658]: `.use` calls are experimental
|
||||||
--> $DIR/feature-gate-ergonomic-clones.rs:9:14
|
--> $DIR/feature-gate-ergonomic-clones.rs:18:14
|
||||||
|
|
|
|
||||||
LL | let s2 = use || {
|
LL | let f2 = use || {
|
||||||
| ^^^
|
| ^^^
|
||||||
|
|
|
|
||||||
= note: see issue #132290 <https://github.com/rust-lang/rust/issues/132290> for more information
|
= note: see issue #132290 <https://github.com/rust-lang/rust/issues/132290> for more information
|
||||||
|
@ -19,15 +19,35 @@ LL | let s2 = use || {
|
||||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||||
|
|
||||||
error[E0658]: `.use` calls are experimental
|
error[E0658]: `.use` calls are experimental
|
||||||
--> $DIR/feature-gate-ergonomic-clones.rs:14:14
|
--> $DIR/feature-gate-ergonomic-clones.rs:23:14
|
||||||
|
|
|
|
||||||
LL | let s3 = use || {
|
LL | let f3 = use || {
|
||||||
| ^^^
|
| ^^^
|
||||||
|
|
|
|
||||||
= note: see issue #132290 <https://github.com/rust-lang/rust/issues/132290> for more information
|
= note: see issue #132290 <https://github.com/rust-lang/rust/issues/132290> for more information
|
||||||
= help: add `#![feature(ergonomic_clones)]` to the crate attributes to enable
|
= help: add `#![feature(ergonomic_clones)]` to the crate attributes to enable
|
||||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error[E0658]: use of unstable library feature `ergonomic_clones`
|
||||||
|
--> $DIR/feature-gate-ergonomic-clones.rs:1:5
|
||||||
|
|
|
||||||
|
LL | use std::clone::UseCloned;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: see issue #132290 <https://github.com/rust-lang/rust/issues/132290> for more information
|
||||||
|
= help: add `#![feature(ergonomic_clones)]` 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 `ergonomic_clones`
|
||||||
|
--> $DIR/feature-gate-ergonomic-clones.rs:12:6
|
||||||
|
|
|
||||||
|
LL | impl UseCloned for Foo {}
|
||||||
|
| ^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: see issue #132290 <https://github.com/rust-lang/rust/issues/132290> for more information
|
||||||
|
= help: add `#![feature(ergonomic_clones)]` 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 5 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0658`.
|
For more information about this error, try `rustc --explain E0658`.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue