about summary refs log tree commit diff
diff options
context:
space:
mode:
authorThe8472 <git@infinite-source.de>2019-11-21 13:40:49 +0100
committerThe8472 <git@infinite-source.de>2020-09-03 20:59:15 +0200
commitdac0edfaaaa5a8c668f70a1cd58468c700a04627 (patch)
treebc7fd409bf8f27f8a68338f2bf46c6b949766fc6
parent582fbb1d62420d8d85f364d06669038f12b7e423 (diff)
downloadrust-dac0edfaaaa5a8c668f70a1cd58468c700a04627.tar.gz
rust-dac0edfaaaa5a8c668f70a1cd58468c700a04627.zip
restore SpecFrom<T, TrustedLen<Item=T>> specialization by nesting
specializations
-rw-r--r--library/alloc/src/vec.rs30
1 files changed, 29 insertions, 1 deletions
diff --git a/library/alloc/src/vec.rs b/library/alloc/src/vec.rs
index ffd6f5b31d4..272ad748bc7 100644
--- a/library/alloc/src/vec.rs
+++ b/library/alloc/src/vec.rs
@@ -2108,7 +2108,13 @@ trait SpecFrom<T, I> {
     fn from_iter(iter: I) -> Self;
 }
 
-impl<T, I> SpecFrom<T, I> for Vec<T>
+// Another specialization trait for Vec::from_iter
+// necessary to manually prioritize overlapping specializations
+trait SpecFromNested<T, I> {
+    fn from_iter(iter: I) -> Self;
+}
+
+impl<T, I> SpecFromNested<T, I> for Vec<T>
 where
     I: Iterator<Item = T>,
 {
@@ -2137,6 +2143,28 @@ where
     }
 }
 
+impl<T, I> SpecFromNested<T, I> for Vec<T>
+where
+    I: TrustedLen<Item = T>,
+{
+    fn from_iter(iterator: I) -> Self {
+        let mut vector = Vec::new();
+        // must delegate to spec_extend() since extend() itself delegates
+        // to spec_from for empty Vecs
+        vector.spec_extend(iterator);
+        vector
+    }
+}
+
+impl<T, I> SpecFrom<T, I> for Vec<T>
+where
+    I: Iterator<Item = T>,
+{
+    default fn from_iter(iterator: I) -> Self {
+        SpecFromNested::from_iter(iterator)
+    }
+}
+
 struct InPlaceDrop<T> {
     inner: *mut T,
     dst: *mut T,