From de8660ab610f046bbdeb1a90f2c94cba1d3d3185 Mon Sep 17 00:00:00 2001 From: David Wood Date: Mon, 24 Jun 2019 09:15:07 +0100 Subject: [PATCH 1/3] typeck: merge opaque type inference logic This commit merges the logic used for opaque type type inference for impl Trait and non-impl Trait cases. This fixes an ICE where existential types used in the return types of functions would be allowed to have an out-of-scope generic type parameter. --- src/librustc/infer/opaque_types/mod.rs | 76 +++++++++- src/librustc_typeck/check/writeback.rs | 153 ++------------------ src/test/ui/impl-trait/issue-55872-1.rs | 22 +++ src/test/ui/impl-trait/issue-55872-1.stderr | 33 +++++ src/test/ui/impl-trait/issue-55872-2.rs | 20 +++ src/test/ui/impl-trait/issue-55872-2.stderr | 21 +++ src/test/ui/impl-trait/issue-55872.rs | 19 +++ src/test/ui/impl-trait/issue-55872.stderr | 12 ++ 8 files changed, 217 insertions(+), 139 deletions(-) create mode 100644 src/test/ui/impl-trait/issue-55872-1.rs create mode 100644 src/test/ui/impl-trait/issue-55872-1.stderr create mode 100644 src/test/ui/impl-trait/issue-55872-2.rs create mode 100644 src/test/ui/impl-trait/issue-55872-2.stderr create mode 100644 src/test/ui/impl-trait/issue-55872.rs create mode 100644 src/test/ui/impl-trait/issue-55872.stderr diff --git a/src/librustc/infer/opaque_types/mod.rs b/src/librustc/infer/opaque_types/mod.rs index f43e3fa0b7787..9c105b6b891f9 100644 --- a/src/librustc/infer/opaque_types/mod.rs +++ b/src/librustc/infer/opaque_types/mod.rs @@ -4,6 +4,7 @@ use crate::hir::Node; use crate::infer::outlives::free_region_map::FreeRegionRelations; use crate::infer::{self, InferCtxt, InferOk, TypeVariableOrigin, TypeVariableOriginKind}; use crate::middle::region; +use crate::mir::interpret::ConstValue; use crate::traits::{self, PredicateObligation}; use crate::ty::fold::{BottomUpFolder, TypeFoldable, TypeFolder, TypeVisitor}; use crate::ty::subst::{InternalSubsts, Kind, SubstsRef, UnpackedKind}; @@ -553,6 +554,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { def_id: DefId, opaque_defn: &OpaqueTypeDecl<'tcx>, instantiated_ty: Ty<'tcx>, + span: Span, ) -> Ty<'tcx> { debug!( "infer_opaque_definition_from_instantiation(def_id={:?}, instantiated_ty={:?})", @@ -584,6 +586,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { def_id, map, instantiated_ty, + span, )); debug!("infer_opaque_definition_from_instantiation: definition_ty={:?}", definition_ty); @@ -761,6 +764,9 @@ struct ReverseMapper<'tcx> { /// initially `Some`, set to `None` once error has been reported hidden_ty: Option>, + + /// Span of function being checked. + span: Span, } impl ReverseMapper<'tcx> { @@ -770,6 +776,7 @@ impl ReverseMapper<'tcx> { opaque_type_def_id: DefId, map: FxHashMap, Kind<'tcx>>, hidden_ty: Ty<'tcx>, + span: Span, ) -> Self { Self { tcx, @@ -778,6 +785,7 @@ impl ReverseMapper<'tcx> { map, map_missing_regions_to_empty: false, hidden_ty: Some(hidden_ty), + span, } } @@ -812,10 +820,11 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> { _ => { } } + let generics = self.tcx().generics_of(self.opaque_type_def_id); match self.map.get(&r.into()).map(|k| k.unpack()) { Some(UnpackedKind::Lifetime(r1)) => r1, Some(u) => panic!("region mapped to unexpected kind: {:?}", u), - None => { + None if generics.parent.is_some() => { if !self.map_missing_regions_to_empty && !self.tainted_by_errors { if let Some(hidden_ty) = self.hidden_ty.take() { unexpected_hidden_region_diagnostic( @@ -829,6 +838,21 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> { } self.tcx.lifetimes.re_empty } + None => { + self.tcx.sess + .struct_span_err( + self.span, + "non-defining existential type use in defining scope" + ) + .span_label( + self.span, + format!("lifetime `{}` is part of concrete type but not used in \ + parameter list of existential type", r), + ) + .emit(); + + self.tcx().global_tcx().mk_region(ty::ReStatic) + }, } } @@ -890,9 +914,59 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> { self.tcx.mk_generator(def_id, ty::GeneratorSubsts { substs }, movability) } + ty::Param(..) => { + // Look it up in the substitution list. + match self.map.get(&ty.into()).map(|k| k.unpack()) { + // Found it in the substitution list; replace with the parameter from the + // existential type. + Some(UnpackedKind::Type(t1)) => t1, + Some(u) => panic!("type mapped to unexpected kind: {:?}", u), + None => { + self.tcx.sess + .struct_span_err( + self.span, + &format!("type parameter `{}` is part of concrete type but not \ + used in parameter list for existential type", ty), + ) + .emit(); + + self.tcx().types.err + } + } + } + _ => ty.super_fold_with(self), } } + + fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> { + trace!("checking const {:?}", ct); + // Find a const parameter + match ct.val { + ConstValue::Param(..) => { + // Look it up in the substitution list. + match self.map.get(&ct.into()).map(|k| k.unpack()) { + // Found it in the substitution list, replace with the parameter from the + // existential type. + Some(UnpackedKind::Const(c1)) => c1, + Some(u) => panic!("const mapped to unexpected kind: {:?}", u), + None => { + self.tcx.sess + .struct_span_err( + self.span, + &format!("const parameter `{}` is part of concrete type but not \ + used in parameter list for existential type", ct) + ) + .emit(); + + self.tcx().consts.err + } + } + } + + _ => ct, + } + } } struct Instantiator<'a, 'tcx> { diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index 28711e32a4c51..2a33b47c93a61 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -9,10 +9,8 @@ use rustc::hir::def_id::{DefId, DefIndex}; use rustc::hir::intravisit::{self, NestedVisitorMap, Visitor}; use rustc::infer::InferCtxt; use rustc::ty::adjustment::{Adjust, Adjustment, PointerCast}; -use rustc::ty::fold::{BottomUpFolder, TypeFoldable, TypeFolder}; -use rustc::ty::subst::UnpackedKind; +use rustc::ty::fold::{TypeFoldable, TypeFolder}; use rustc::ty::{self, Ty, TyCtxt}; -use rustc::mir::interpret::ConstValue; use rustc::util::nodemap::DefIdSet; use rustc_data_structures::sync::Lrc; use std::mem; @@ -440,141 +438,20 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { debug_assert!(!instantiated_ty.has_escaping_bound_vars()); - let generics = self.tcx().generics_of(def_id); - - let definition_ty = if generics.parent.is_some() { - // `impl Trait` - self.fcx.infer_opaque_definition_from_instantiation( - def_id, - opaque_defn, - instantiated_ty, - ) - } else { - // Prevent: - // * `fn foo() -> Foo` - // * `fn foo() -> Foo` - // from being defining. - - // Also replace all generic params with the ones from the existential type - // definition so that - // ```rust - // existential type Foo: 'static; - // fn foo() -> Foo { .. } - // ``` - // figures out the concrete type with `U`, but the stored type is with `T`. - instantiated_ty.fold_with(&mut BottomUpFolder { - tcx: self.tcx().global_tcx(), - ty_op: |ty| { - trace!("checking type {:?}", ty); - // Find a type parameter. - if let ty::Param(..) = ty.sty { - // Look it up in the substitution list. - assert_eq!(opaque_defn.substs.len(), generics.params.len()); - for (subst, param) in opaque_defn.substs.iter().zip(&generics.params) { - if let UnpackedKind::Type(subst) = subst.unpack() { - if subst == ty { - // Found it in the substitution list; replace with the - // parameter from the existential type. - return self.tcx() - .global_tcx() - .mk_ty_param(param.index, param.name); - } - } - } - self.tcx() - .sess - .struct_span_err( - span, - &format!( - "type parameter `{}` is part of concrete type but not used \ - in parameter list for existential type", - ty, - ), - ) - .emit(); - return self.tcx().types.err; - } - ty - }, - lt_op: |region| { - match region { - // Skip static and bound regions: they don't require substitution. - ty::ReStatic | ty::ReLateBound(..) => region, - _ => { - trace!("checking {:?}", region); - for (subst, p) in opaque_defn.substs.iter().zip(&generics.params) { - if let UnpackedKind::Lifetime(subst) = subst.unpack() { - if subst == region { - // Found it in the substitution list; replace with the - // parameter from the existential type. - let reg = ty::EarlyBoundRegion { - def_id: p.def_id, - index: p.index, - name: p.name, - }; - trace!("replace {:?} with {:?}", region, reg); - return self.tcx() - .global_tcx() - .mk_region(ty::ReEarlyBound(reg)); - } - } - } - trace!("opaque_defn: {:#?}", opaque_defn); - trace!("generics: {:#?}", generics); - self.tcx() - .sess - .struct_span_err( - span, - "non-defining existential type use in defining scope", - ) - .span_label( - span, - format!( - "lifetime `{}` is part of concrete type but not used \ - in parameter list of existential type", - region, - ), - ) - .emit(); - self.tcx().global_tcx().mk_region(ty::ReStatic) - } - } - }, - ct_op: |ct| { - trace!("checking const {:?}", ct); - // Find a const parameter - if let ConstValue::Param(..) = ct.val { - // look it up in the substitution list - assert_eq!(opaque_defn.substs.len(), generics.params.len()); - for (subst, param) in opaque_defn.substs.iter() - .zip(&generics.params) { - if let UnpackedKind::Const(subst) = subst.unpack() { - if subst == ct { - // found it in the substitution list, replace with the - // parameter from the existential type - return self.tcx() - .global_tcx() - .mk_const_param(param.index, param.name, ct.ty); - } - } - } - self.tcx() - .sess - .struct_span_err( - span, - &format!( - "const parameter `{}` is part of concrete type but not \ - used in parameter list for existential type", - ct, - ), - ) - .emit(); - return self.tcx().consts.err; - } - ct - } - }) - }; + // Prevent: + // * `fn foo() -> Foo` + // * `fn foo() -> Foo` + // from being defining. + + // Also replace all generic params with the ones from the existential type + // definition so that + // ```rust + // existential type Foo: 'static; + // fn foo() -> Foo { .. } + // ``` + // figures out the concrete type with `U`, but the stored type is with `T`. + let definition_ty = self.fcx.infer_opaque_definition_from_instantiation( + def_id, opaque_defn, instantiated_ty, span); if let ty::Opaque(defin_ty_def_id, _substs) = definition_ty.sty { if def_id == defin_ty_def_id { diff --git a/src/test/ui/impl-trait/issue-55872-1.rs b/src/test/ui/impl-trait/issue-55872-1.rs new file mode 100644 index 0000000000000..5095b26f8a4e0 --- /dev/null +++ b/src/test/ui/impl-trait/issue-55872-1.rs @@ -0,0 +1,22 @@ +// ignore-tidy-linelength +#![feature(existential_type)] + +pub trait Bar +{ + type E: Copy; + + fn foo() -> Self::E; +} + +impl Bar for S { + existential type E: Copy; + //~^ ERROR the trait bound `S: std::marker::Copy` is not satisfied in `(S, T)` [E0277] + //~^^ ERROR the trait bound `T: std::marker::Copy` is not satisfied in `(S, T)` [E0277] + + fn foo() -> Self::E { + //~^ ERROR type parameter `T` is part of concrete type but not used in parameter list for existential type + (S::default(), T::default()) + } +} + +fn main() {} diff --git a/src/test/ui/impl-trait/issue-55872-1.stderr b/src/test/ui/impl-trait/issue-55872-1.stderr new file mode 100644 index 0000000000000..04b4d2d4a50a5 --- /dev/null +++ b/src/test/ui/impl-trait/issue-55872-1.stderr @@ -0,0 +1,33 @@ +error[E0277]: the trait bound `S: std::marker::Copy` is not satisfied in `(S, T)` + --> $DIR/issue-55872-1.rs:12:5 + | +LL | existential type E: Copy; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ within `(S, T)`, the trait `std::marker::Copy` is not implemented for `S` + | + = help: consider adding a `where S: std::marker::Copy` bound + = note: required because it appears within the type `(S, T)` + = note: the return type of a function must have a statically known size + +error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied in `(S, T)` + --> $DIR/issue-55872-1.rs:12:5 + | +LL | existential type E: Copy; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ within `(S, T)`, the trait `std::marker::Copy` is not implemented for `T` + | + = help: consider adding a `where T: std::marker::Copy` bound + = note: required because it appears within the type `(S, T)` + = note: the return type of a function must have a statically known size + +error: type parameter `T` is part of concrete type but not used in parameter list for existential type + --> $DIR/issue-55872-1.rs:16:37 + | +LL | fn foo() -> Self::E { + | _____________________________________^ +LL | | +LL | | (S::default(), T::default()) +LL | | } + | |_____^ + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/impl-trait/issue-55872-2.rs b/src/test/ui/impl-trait/issue-55872-2.rs new file mode 100644 index 0000000000000..2bdeb14bdc3e6 --- /dev/null +++ b/src/test/ui/impl-trait/issue-55872-2.rs @@ -0,0 +1,20 @@ +// edition:2018 +// ignore-tidy-linelength +#![feature(async_await, existential_type)] + +pub trait Bar { + type E: Copy; + + fn foo() -> Self::E; +} + +impl Bar for S { + existential type E: Copy; + //~^ ERROR the trait bound `impl std::future::Future: std::marker::Copy` is not satisfied [E0277] + fn foo() -> Self::E { + //~^ ERROR type parameter `T` is part of concrete type but not used in parameter list for existential type + async {} + } +} + +fn main() {} diff --git a/src/test/ui/impl-trait/issue-55872-2.stderr b/src/test/ui/impl-trait/issue-55872-2.stderr new file mode 100644 index 0000000000000..2505a82ee23cb --- /dev/null +++ b/src/test/ui/impl-trait/issue-55872-2.stderr @@ -0,0 +1,21 @@ +error[E0277]: the trait bound `impl std::future::Future: std::marker::Copy` is not satisfied + --> $DIR/issue-55872-2.rs:12:5 + | +LL | existential type E: Copy; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `impl std::future::Future` + | + = note: the return type of a function must have a statically known size + +error: type parameter `T` is part of concrete type but not used in parameter list for existential type + --> $DIR/issue-55872-2.rs:14:28 + | +LL | fn foo() -> Self::E { + | ____________________________^ +LL | | +LL | | async {} +LL | | } + | |_____^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/impl-trait/issue-55872.rs b/src/test/ui/impl-trait/issue-55872.rs new file mode 100644 index 0000000000000..95604545c37f1 --- /dev/null +++ b/src/test/ui/impl-trait/issue-55872.rs @@ -0,0 +1,19 @@ +// ignore-tidy-linelength +#![feature(existential_type)] + +pub trait Bar { + type E: Copy; + + fn foo() -> Self::E; +} + +impl Bar for S { + existential type E: Copy; + + fn foo() -> Self::E { + //~^ ERROR type parameter `T` is part of concrete type but not used in parameter list for existential type + || () + } +} + +fn main() {} diff --git a/src/test/ui/impl-trait/issue-55872.stderr b/src/test/ui/impl-trait/issue-55872.stderr new file mode 100644 index 0000000000000..487f276e317e9 --- /dev/null +++ b/src/test/ui/impl-trait/issue-55872.stderr @@ -0,0 +1,12 @@ +error: type parameter `T` is part of concrete type but not used in parameter list for existential type + --> $DIR/issue-55872.rs:13:28 + | +LL | fn foo() -> Self::E { + | ____________________________^ +LL | | +LL | | || () +LL | | } + | |_____^ + +error: aborting due to previous error + From e808d921ddc0ad81a200934fc4caabc34094afe5 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Fri, 5 Jul 2019 11:38:40 +0200 Subject: [PATCH 2/3] Replace SliceConcatExt trait with inherent methods and SliceConcat helper trait Before this change `SliceConcatExt` was an unstable extension trait with stable methods. It was in the libstd prelude, so that its methods could be used on the stable channel. This replaces it with inherent methods, which can be used without any addition to the prelude. Since the methods are stable and very generic (with for example a return type that depends on the types of parameters), an helper trait is still needed. But now that trait does not need to be in scope for the methods to be used. Removing this depedency on the libstd prelude allows the methods to be used in `#![no_std]` crate that use liballoc, which does not have its own implicitly-imported prelude. --- src/liballoc/prelude/v1.rs | 1 - src/liballoc/slice.rs | 129 ++++++++++++++++++++----------------- src/liballoc/str.rs | 14 ++-- src/libstd/prelude/mod.rs | 3 - src/libstd/prelude/v1.rs | 3 - 5 files changed, 76 insertions(+), 74 deletions(-) diff --git a/src/liballoc/prelude/v1.rs b/src/liballoc/prelude/v1.rs index b6b01395ad632..3cb285bf0492f 100644 --- a/src/liballoc/prelude/v1.rs +++ b/src/liballoc/prelude/v1.rs @@ -6,6 +6,5 @@ #[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::borrow::ToOwned; #[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::boxed::Box; -#[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::slice::SliceConcatExt; #[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::string::{String, ToString}; #[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::vec::Vec; diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index f7b0a5e703cc3..bc4ae16798478 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -484,6 +484,56 @@ impl [T] { } buf } + + /// Flattens a slice of `T` into a single value `Self::Output`. + /// + /// # Examples + /// + /// ``` + /// assert_eq!(["hello", "world"].concat(), "helloworld"); + /// assert_eq!([[1, 2], [3, 4]].concat(), [1, 2, 3, 4]); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn concat(&self) -> T::Output + where T: SliceConcat + { + SliceConcat::concat(self) + } + + /// Flattens a slice of `T` into a single value `Self::Output`, placing a + /// given separator between each. + /// + /// # Examples + /// + /// ``` + /// assert_eq!(["hello", "world"].join(" "), "hello world"); + /// assert_eq!([[1, 2], [3, 4]].join(&0), [1, 2, 0, 3, 4]); + /// ``` + #[stable(feature = "rename_connect_to_join", since = "1.3.0")] + pub fn join(&self, sep: &Separator) -> T::Output + where T: SliceConcat + { + SliceConcat::join(self, sep) + } + + /// Flattens a slice of `T` into a single value `Self::Output`, placing a + /// given separator between each. + /// + /// # Examples + /// + /// ``` + /// # #![allow(deprecated)] + /// assert_eq!(["hello", "world"].connect(" "), "hello world"); + /// assert_eq!([[1, 2], [3, 4]].connect(&0), [1, 2, 0, 3, 4]); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_deprecated(since = "1.3.0", reason = "renamed to join")] + pub fn connect(&self, sep: &Separator) -> T::Output + where T: SliceConcat + { + SliceConcat::join(self, sep) + } + } #[lang = "slice_u8_alloc"] @@ -527,87 +577,46 @@ impl [u8] { //////////////////////////////////////////////////////////////////////////////// // Extension traits for slices over specific kinds of data //////////////////////////////////////////////////////////////////////////////// -#[unstable(feature = "slice_concat_ext", - reason = "trait should not have to exist", - issue = "27747")] -/// An extension trait for concatenating slices -/// -/// While this trait is unstable, the methods are stable. `SliceConcatExt` is -/// included in the [standard library prelude], so you can use [`join()`] and -/// [`concat()`] as if they existed on `[T]` itself. -/// -/// [standard library prelude]: ../../std/prelude/index.html -/// [`join()`]: #tymethod.join -/// [`concat()`]: #tymethod.concat -pub trait SliceConcatExt { - #[unstable(feature = "slice_concat_ext", - reason = "trait should not have to exist", - issue = "27747")] + +/// Helper trait for [`[T]::concat`](../../std/primitive.slice.html#method.concat) +/// and [`[T]::join`](../../std/primitive.slice.html#method.join) +#[unstable(feature = "slice_concat_trait", issue = "27747")] +pub trait SliceConcat: Sized { + #[unstable(feature = "slice_concat_trait", issue = "27747")] /// The resulting type after concatenation type Output; - /// Flattens a slice of `T` into a single value `Self::Output`. - /// - /// # Examples - /// - /// ``` - /// assert_eq!(["hello", "world"].concat(), "helloworld"); - /// assert_eq!([[1, 2], [3, 4]].concat(), [1, 2, 3, 4]); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - fn concat(&self) -> Self::Output; - - /// Flattens a slice of `T` into a single value `Self::Output`, placing a - /// given separator between each. - /// - /// # Examples - /// - /// ``` - /// assert_eq!(["hello", "world"].join(" "), "hello world"); - /// assert_eq!([[1, 2], [3, 4]].join(&0), [1, 2, 0, 3, 4]); - /// ``` - #[stable(feature = "rename_connect_to_join", since = "1.3.0")] - fn join(&self, sep: &T) -> Self::Output; + /// Implementation of [`[T]::concat`](../../std/primitive.slice.html#method.concat) + #[unstable(feature = "slice_concat_trait", issue = "27747")] + fn concat(slice: &[Self]) -> Self::Output; - /// Flattens a slice of `T` into a single value `Self::Output`, placing a - /// given separator between each. - /// - /// # Examples - /// - /// ``` - /// # #![allow(deprecated)] - /// assert_eq!(["hello", "world"].connect(" "), "hello world"); - /// assert_eq!([[1, 2], [3, 4]].connect(&0), [1, 2, 0, 3, 4]); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_deprecated(since = "1.3.0", reason = "renamed to join")] - fn connect(&self, sep: &T) -> Self::Output { - self.join(sep) - } + /// Implementation of [`[T]::join`](../../std/primitive.slice.html#method.join) + #[unstable(feature = "slice_concat_trait", issue = "27747")] + fn join(slice: &[Self], sep: &Separator) -> Self::Output; } #[unstable(feature = "slice_concat_ext", reason = "trait should not have to exist", issue = "27747")] -impl> SliceConcatExt for [V] { +impl> SliceConcat for V { type Output = Vec; - fn concat(&self) -> Vec { - let size = self.iter().map(|slice| slice.borrow().len()).sum(); + fn concat(slice: &[Self]) -> Vec { + let size = slice.iter().map(|slice| slice.borrow().len()).sum(); let mut result = Vec::with_capacity(size); - for v in self { + for v in slice { result.extend_from_slice(v.borrow()) } result } - fn join(&self, sep: &T) -> Vec { - let mut iter = self.iter(); + fn join(slice: &[Self], sep: &T) -> Vec { + let mut iter = slice.iter(); let first = match iter.next() { Some(first) => first, None => return vec![], }; - let size = self.iter().map(|slice| slice.borrow().len()).sum::() + self.len() - 1; + let size = slice.iter().map(|slice| slice.borrow().len()).sum::() + slice.len() - 1; let mut result = Vec::with_capacity(size); result.extend_from_slice(first.borrow()); diff --git a/src/liballoc/str.rs b/src/liballoc/str.rs index 70a93157c9ee2..37a1046d0942d 100644 --- a/src/liballoc/str.rs +++ b/src/liballoc/str.rs @@ -37,7 +37,7 @@ use core::unicode::conversions; use crate::borrow::ToOwned; use crate::boxed::Box; -use crate::slice::{SliceConcatExt, SliceIndex}; +use crate::slice::{SliceConcat, SliceIndex}; use crate::string::String; use crate::vec::Vec; @@ -74,16 +74,16 @@ pub use core::str::{EscapeDebug, EscapeDefault, EscapeUnicode}; #[unstable(feature = "slice_concat_ext", reason = "trait should not have to exist", issue = "27747")] -impl> SliceConcatExt for [S] { +impl> SliceConcat for S { type Output = String; - fn concat(&self) -> String { - self.join("") + fn concat(slice: &[Self]) -> String { + Self::join(slice, "") } - fn join(&self, sep: &str) -> String { + fn join(slice: &[Self], sep: &str) -> String { unsafe { - String::from_utf8_unchecked( join_generic_copy(self, sep.as_bytes()) ) + String::from_utf8_unchecked( join_generic_copy(slice, sep.as_bytes()) ) } } } @@ -126,7 +126,7 @@ macro_rules! copy_slice_and_advance { // Optimized join implementation that works for both Vec (T: Copy) and String's inner vec // Currently (2018-05-13) there is a bug with type inference and specialization (see issue #36262) -// For this reason SliceConcatExt is not specialized for T: Copy and SliceConcatExt is the +// For this reason SliceConcat is not specialized for T: Copy and SliceConcat is the // only user of this function. It is left in place for the time when that is fixed. // // the bounds for String-join are S: Borrow and for Vec-join Borrow<[T]> diff --git a/src/libstd/prelude/mod.rs b/src/libstd/prelude/mod.rs index 551e982a3c685..3085c3d829653 100644 --- a/src/libstd/prelude/mod.rs +++ b/src/libstd/prelude/mod.rs @@ -71,9 +71,6 @@ //! * [`std::result`]::[`Result`]::{`self`, `Ok`, `Err`}. A type for functions //! that may succeed or fail. Like [`Option`], its variants are exported as //! well. -//! * [`std::slice`]::[`SliceConcatExt`], a trait that exists for technical -//! reasons, but shouldn't have to exist. It provides a few useful methods on -//! slices. //! * [`std::string`]::{[`String`], [`ToString`]}, heap allocated strings. //! * [`std::vec`]::[`Vec`](../vec/struct.Vec.html), a growable, heap-allocated //! vector. diff --git a/src/libstd/prelude/v1.rs b/src/libstd/prelude/v1.rs index ce1e8e3319cf8..a863bebf4a264 100644 --- a/src/libstd/prelude/v1.rs +++ b/src/libstd/prelude/v1.rs @@ -60,9 +60,6 @@ pub use crate::boxed::Box; pub use crate::borrow::ToOwned; #[stable(feature = "rust1", since = "1.0.0")] #[doc(no_inline)] -pub use crate::slice::SliceConcatExt; -#[stable(feature = "rust1", since = "1.0.0")] -#[doc(no_inline)] pub use crate::string::{String, ToString}; #[stable(feature = "rust1", since = "1.0.0")] #[doc(no_inline)] From ad2633777e07d367bb0fdaeda293f9a3eb8ee54b Mon Sep 17 00:00:00 2001 From: topecongiro Date: Sat, 6 Jul 2019 14:32:56 +0900 Subject: [PATCH 3/3] Update rustfmt to 1.3.2 --- Cargo.lock | 48 +++++++++++++++++------------------------------ src/tools/rustfmt | 2 +- 2 files changed, 18 insertions(+), 32 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6b5499ec6f351..1287441448349 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -336,18 +336,6 @@ dependencies = [ "syn 0.15.35 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "cargo_metadata" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "cargo_metadata" version = "0.8.0" @@ -811,12 +799,11 @@ dependencies = [ [[package]] name = "dirs" -version = "1.0.5" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_users 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "dirs-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1749,7 +1736,7 @@ dependencies = [ "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", - "structopt 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", + "structopt 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2594,7 +2581,7 @@ dependencies = [ "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-workspace-hack 1.0.0", "rustc_tools_util 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustfmt-nightly 1.3.0", + "rustfmt-nightly 1.3.2", "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", "serde_ignored 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3408,7 +3395,7 @@ dependencies = [ [[package]] name = "rustfmt-config_proc_macro" -version = "0.1.0" +version = "0.1.2" dependencies = [ "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3418,15 +3405,15 @@ dependencies = [ [[package]] name = "rustfmt-nightly" -version = "1.3.0" +version = "1.3.2" dependencies = [ "annotate-snippets 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "bytecount 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "cargo_metadata 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "cargo_metadata 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "derive-new 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", "diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", - "dirs 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "dirs 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "getopts 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3439,10 +3426,10 @@ dependencies = [ "rustc-ap-syntax 491.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-ap-syntax_pos 491.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-workspace-hack 1.0.0", - "rustfmt-config_proc_macro 0.1.0", + "rustfmt-config_proc_macro 0.1.2", "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", - "structopt 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", + "structopt 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "term 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3723,16 +3710,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "structopt" -version = "0.2.16" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", - "structopt-derive 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", + "structopt-derive 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "structopt-derive" -version = "0.2.16" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "heck 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4518,7 +4505,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "94f88df23a25417badc922ab0f5716cc1330e87f71ddd9203b3a3ccd9cedf75d" "checksum bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "40ade3d27603c2cb345eb0912aec461a6dec7e06a4ae48589904e808335c7afa" "checksum bytesize 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "716960a18f978640f25101b5cbf1c6f6b0d3192fab36a2d98ca96f0ecbe41010" -"checksum cargo_metadata 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "585784cac9b05c93a53b17a0b24a5cdd1dfdda5256f030e089b549d2390cc720" "checksum cargo_metadata 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "929766d993a2fde7a0ae962ee82429069cd7b68839cd9375b98efd719df65d3a" "checksum cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)" = "5e5f3fee5eeb60324c2781f1e41286bdee933850fff9b3c672587fed5ec58c83" "checksum cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "89431bba4e6b7092fb5fcd00a6f6ca596c55cc26b2f1e6dcdd08a1f4933f66b2" @@ -4559,7 +4545,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" "checksum digest 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "03b072242a8cbaf9c145665af9d250c59af3b958f83ed6824e13533cf76d5b90" "checksum directories 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2ccc83e029c3cebb4c8155c644d34e3a070ccdb4ff90d369c74cd73f7cb3c984" -"checksum dirs 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3fd78930633bd1c6e35c4b42b1df7b0cbc6bc191146e512bb3bedf243fcc3901" +"checksum dirs 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1c4ef5a8b902d393339e2a2c7fe573af92ce7e0ee5a3ff827b4c9ad7e07e4fa1" "checksum dirs-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "937756392ec77d1f2dd9dc3ac9d69867d109a2121479d72c364e42f4cab21e2d" "checksum dlmalloc 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f283302e035e61c23f2b86b3093e8c6273a4c3125742d6087e96ade001ca5e63" "checksum dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ea57b42383d091c85abcc2706240b94ab2a8fa1fc81c10ff23c4de06e2a90b5e" @@ -4789,8 +4775,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b1884d1bc09741d466d9b14e6d37ac89d6909cbcac41dd9ae982d4d063bbedfc" "checksum strip-ansi-escapes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9d63676e2abafa709460982ddc02a3bb586b6d15a49b75c212e06edd3933acee" "checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550" -"checksum structopt 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)" = "fa19a5a708e22bb5be31c1b6108a2a902f909c4b9ba85cba44c06632386bc0ff" -"checksum structopt-derive 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)" = "c6d59d0ae8ef8de16e49e3ca7afa16024a3e0dfd974a75ef93fdc5464e34523f" +"checksum structopt 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "16c2cdbf9cc375f15d1b4141bc48aeef444806655cd0e904207edc8d68d86ed7" +"checksum structopt-derive 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "53010261a84b37689f9ed7d395165029f9cc7abb9f56bbfe86bee2597ed25107" "checksum strum 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f6c3a2071519ab6a48f465808c4c1ffdd00dfc8e93111d02b4fc5abab177676e" "checksum strum_macros 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8baacebd7b7c9b864d83a6ba7a246232983e277b86fa5cdec77f565715a4b136" "checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" diff --git a/src/tools/rustfmt b/src/tools/rustfmt index d33450247b17d..679c8d5f106e8 160000 --- a/src/tools/rustfmt +++ b/src/tools/rustfmt @@ -1 +1 @@ -Subproject commit d33450247b17d92a951d9663822c5a3635a37dde +Subproject commit 679c8d5f106e8442bf8c4a54609a63df9eb3863c