diff options
| author | bors <bors@rust-lang.org> | 2019-02-22 21:32:15 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2019-02-22 21:32:15 +0000 |
| commit | 082c86175fcf72c355e6a889956fbea59e65bcdb (patch) | |
| tree | 1b8297e021423bd2069bb1654985bf52602e9ef1 | |
| parent | e1c6d00574494499f63c1e460ef886768643e7db (diff) | |
| parent | a8a343a78706a1d90ebd451046b76d176bab937d (diff) | |
| download | rust-082c86175fcf72c355e6a889956fbea59e65bcdb.tar.gz rust-082c86175fcf72c355e6a889956fbea59e65bcdb.zip | |
Auto merge of #58644 - Centril:rollup, r=Centril
Rollup of 17 pull requests
Successful merges:
- #57656 (Deprecate the unstable Vec::resize_default)
- #58059 (deprecate before_exec in favor of unsafe pre_exec)
- #58064 (override `VecDeque::try_rfold`, also update iterator)
- #58198 (Suggest removing parentheses surrounding lifetimes)
- #58431 (fix overlapping references in BTree)
- #58555 (Add a note about 2018e if someone uses `try {` in 2015e)
- #58588 (remove a bit of dead code)
- #58589 (cleanup macro after 2018 transition)
- #58591 (Dedup a rustdoc diagnostic construction)
- #58600 (fix small documentation typo)
- #58601 (Search for target_triple.json only if builtin target not found)
- #58606 (Docs: put Future trait into spotlight)
- #58607 (Fixes #58586: Make E0505 erronous example fail for the 2018 edition)
- #58615 (miri: explain why we use static alignment in ref-to-place conversion)
- #58620 (introduce benchmarks of BTreeSet.intersection)
- #58621 (Update miri links)
- #58632 (Make std feature list sorted)
Failed merges:
r? @ghost
29 files changed, 542 insertions, 210 deletions
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9924055ca45..e785f03d7de 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -161,10 +161,10 @@ it can be found [here][rctd]. Currently building Rust will also build the following external projects: -* [clippy](https://github.com/rust-lang-nursery/rust-clippy) -* [miri](https://github.com/solson/miri) -* [rustfmt](https://github.com/rust-lang-nursery/rustfmt) -* [rls](https://github.com/rust-lang-nursery/rls/) +* [clippy](https://github.com/rust-lang/rust-clippy) +* [miri](https://github.com/rust-lang/miri) +* [rustfmt](https://github.com/rust-lang/rustfmt) +* [rls](https://github.com/rust-lang/rls/) We allow breakage of these tools in the nightly channel. Maintainers of these projects will be notified of the breakages and should fix them as soon as @@ -191,9 +191,9 @@ before the PR is merged. Rust's build system builds a number of tools that make use of the internals of the compiler. This includes -[Clippy](https://github.com/rust-lang-nursery/rust-clippy), -[RLS](https://github.com/rust-lang-nursery/rls) and -[rustfmt](https://github.com/rust-lang-nursery/rustfmt). If these tools +[Clippy](https://github.com/rust-lang/rust-clippy), +[RLS](https://github.com/rust-lang/rls) and +[rustfmt](https://github.com/rust-lang/rustfmt). If these tools break because of your changes, you may run into a sort of "chicken and egg" problem. These tools rely on the latest compiler to be built so you can't update them to reflect your changes to the compiler until those changes are merged into @@ -253,10 +253,10 @@ to complete a few more steps which are outlined with their rationale below. *(This error may change in the future to include more information.)* ``` -error: failed to resolve patches for `https://github.com/rust-lang-nursery/rustfmt` +error: failed to resolve patches for `https://github.com/rust-lang/rustfmt` Caused by: - patch for `rustfmt-nightly` in `https://github.com/rust-lang-nursery/rustfmt` did not resolve to any crates + patch for `rustfmt-nightly` in `https://github.com/rust-lang/rustfmt` did not resolve to any crates failed to run: ~/rust/build/x86_64-unknown-linux-gnu/stage0/bin/cargo build --manifest-path ~/rust/src/bootstrap/Cargo.toml ``` diff --git a/src/doc/rustdoc/src/documentation-tests.md b/src/doc/rustdoc/src/documentation-tests.md index 242167aa917..c9acd3c307b 100644 --- a/src/doc/rustdoc/src/documentation-tests.md +++ b/src/doc/rustdoc/src/documentation-tests.md @@ -244,7 +244,7 @@ disambiguate the error type: /// use std::io; /// let mut input = String::new(); /// io::stdin().read_line(&mut input)?; -/// # Ok::<(), io:Error>(()) +/// # Ok::<(), io::Error>(()) /// ``` ``` diff --git a/src/liballoc/benches/btree/mod.rs b/src/liballoc/benches/btree/mod.rs index 4dc2dfd9153..095ca5dd2e2 100644 --- a/src/liballoc/benches/btree/mod.rs +++ b/src/liballoc/benches/btree/mod.rs @@ -1 +1,2 @@ mod map; +mod set; diff --git a/src/liballoc/benches/btree/set.rs b/src/liballoc/benches/btree/set.rs new file mode 100644 index 00000000000..08e1db5fbb7 --- /dev/null +++ b/src/liballoc/benches/btree/set.rs @@ -0,0 +1,88 @@ +use std::collections::BTreeSet; + +use rand::{thread_rng, Rng}; +use test::{black_box, Bencher}; + +fn random(n1: u32, n2: u32) -> [BTreeSet<usize>; 2] { + let mut rng = thread_rng(); + let mut set1 = BTreeSet::new(); + let mut set2 = BTreeSet::new(); + for _ in 0..n1 { + let i = rng.gen::<usize>(); + set1.insert(i); + } + for _ in 0..n2 { + let i = rng.gen::<usize>(); + set2.insert(i); + } + [set1, set2] +} + +fn staggered(n1: u32, n2: u32) -> [BTreeSet<u32>; 2] { + let mut even = BTreeSet::new(); + let mut odd = BTreeSet::new(); + for i in 0..n1 { + even.insert(i * 2); + } + for i in 0..n2 { + odd.insert(i * 2 + 1); + } + [even, odd] +} + +fn neg_vs_pos(n1: u32, n2: u32) -> [BTreeSet<i32>; 2] { + let mut neg = BTreeSet::new(); + let mut pos = BTreeSet::new(); + for i in -(n1 as i32)..=-1 { + neg.insert(i); + } + for i in 1..=(n2 as i32) { + pos.insert(i); + } + [neg, pos] +} + +fn pos_vs_neg(n1: u32, n2: u32) -> [BTreeSet<i32>; 2] { + let mut neg = BTreeSet::new(); + let mut pos = BTreeSet::new(); + for i in -(n1 as i32)..=-1 { + neg.insert(i); + } + for i in 1..=(n2 as i32) { + pos.insert(i); + } + [pos, neg] +} + +macro_rules! set_intersection_bench { + ($name: ident, $sets: expr) => { + #[bench] + pub fn $name(b: &mut Bencher) { + // setup + let sets = $sets; + + // measure + b.iter(|| { + let x = sets[0].intersection(&sets[1]).count(); + black_box(x); + }) + } + }; +} + +set_intersection_bench! {intersect_random_100, random(100, 100)} +set_intersection_bench! {intersect_random_10k, random(10_000, 10_000)} +set_intersection_bench! {intersect_random_10_vs_10k, random(10, 10_000)} +set_intersection_bench! {intersect_random_10k_vs_10, random(10_000, 10)} +set_intersection_bench! {intersect_staggered_100, staggered(100, 100)} +set_intersection_bench! {intersect_staggered_10k, staggered(10_000, 10_000)} +set_intersection_bench! {intersect_staggered_10_vs_10k, staggered(10, 10_000)} +set_intersection_bench! {intersect_staggered_10k_vs_10, staggered(10_000, 10)} +set_intersection_bench! {intersect_neg_vs_pos_100, neg_vs_pos(100, 100)} +set_intersection_bench! {intersect_neg_vs_pos_10k, neg_vs_pos(10_000, 10_000)} +set_intersection_bench! {intersect_neg_vs_pos_10_vs_10k,neg_vs_pos(10, 10_000)} +set_intersection_bench! {intersect_neg_vs_pos_10k_vs_10,neg_vs_pos(10_000, 10)} +set_intersection_bench! {intersect_pos_vs_neg_100, pos_vs_neg(100, 100)} +set_intersection_bench! {intersect_pos_vs_neg_10k, pos_vs_neg(10_000, 10_000)} +set_intersection_bench! {intersect_pos_vs_neg_10_vs_10k,pos_vs_neg(10, 10_000)} +set_intersection_bench! {intersect_pos_vs_neg_10k_vs_10,pos_vs_neg(10_000, 10)} diff --git a/src/liballoc/benches/vec_deque.rs b/src/liballoc/benches/vec_deque.rs index f7aadbdbd82..7d2d3cfa612 100644 --- a/src/liballoc/benches/vec_deque.rs +++ b/src/liballoc/benches/vec_deque.rs @@ -45,3 +45,10 @@ fn bench_mut_iter_1000(b: &mut Bencher) { black_box(sum); }) } + +#[bench] +fn bench_try_fold(b: &mut Bencher) { + let ring: VecDeque<_> = (0..1000).collect(); + + b.iter(|| black_box(ring.iter().try_fold(0, |a, b| Some(a + b)))) +} diff --git a/src/liballoc/collections/btree/map.rs b/src/liballoc/collections/btree/map.rs index 250927138b3..ce29978856f 100644 --- a/src/liballoc/collections/btree/map.rs +++ b/src/liballoc/collections/btree/map.rs @@ -1634,9 +1634,11 @@ impl<'a, K, V> RangeMut<'a, K, V> { let mut cur_handle = match handle.right_kv() { Ok(kv) => { - let (k, v) = ptr::read(&kv).into_kv_mut(); - self.front = kv.right_edge(); - return (k, v); + self.front = ptr::read(&kv).right_edge(); + // Doing the descend invalidates the references returned by `into_kv_mut`, + // so we have to do this last. + let (k, v) = kv.into_kv_mut(); + return (k, v); // coerce k from `&mut K` to `&K` } Err(last_edge) => { let next_level = last_edge.into_node().ascend().ok(); @@ -1647,9 +1649,11 @@ impl<'a, K, V> RangeMut<'a, K, V> { loop { match cur_handle.right_kv() { Ok(kv) => { - let (k, v) = ptr::read(&kv).into_kv_mut(); - self.front = first_leaf_edge(kv.right_edge().descend()); - return (k, v); + self.front = first_leaf_edge(ptr::read(&kv).right_edge().descend()); + // Doing the descend invalidates the references returned by `into_kv_mut`, + // so we have to do this last. + let (k, v) = kv.into_kv_mut(); + return (k, v); // coerce k from `&mut K` to `&K` } Err(last_edge) => { let next_level = last_edge.into_node().ascend().ok(); @@ -1680,9 +1684,11 @@ impl<'a, K, V> RangeMut<'a, K, V> { let mut cur_handle = match handle.left_kv() { Ok(kv) => { - let (k, v) = ptr::read(&kv).into_kv_mut(); - self.back = kv.left_edge(); - return (k, v); + self.back = ptr::read(&kv).left_edge(); + // Doing the descend invalidates the references returned by `into_kv_mut`, + // so we have to do this last. + let (k, v) = kv.into_kv_mut(); + return (k, v); // coerce k from `&mut K` to `&K` } Err(last_edge) => { let next_level = last_edge.into_node().ascend().ok(); @@ -1693,9 +1699,11 @@ impl<'a, K, V> RangeMut<'a, K, V> { loop { match cur_handle.left_kv() { Ok(kv) => { - let (k, v) = ptr::read(&kv).into_kv_mut(); - self.back = last_leaf_edge(kv.left_edge().descend()); - return (k, v); + self.back = last_leaf_edge(ptr::read(&kv).left_edge().descend()); + // Doing the descend invalidates the references returned by `into_kv_mut`, + // so we have to do this last. + let (k, v) = kv.into_kv_mut(); + return (k, v); // coerce k from `&mut K` to `&K` } Err(last_edge) => { let next_level = last_edge.into_node().ascend().ok(); diff --git a/src/liballoc/collections/btree/node.rs b/src/liballoc/collections/btree/node.rs index fc1c1878924..66d619b1298 100644 --- a/src/liballoc/collections/btree/node.rs +++ b/src/liballoc/collections/btree/node.rs @@ -645,6 +645,8 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Mut<'a>, K, V, Type> { } fn into_key_slice_mut(mut self) -> &'a mut [K] { + // Same as for `into_key_slice` above, we try to avoid a run-time check + // (the alignment comparison will usually be performed at compile-time). if mem::align_of::<K>() > mem::align_of::<LeafNode<(), ()>>() && self.is_shared_root() { &mut [] } else { @@ -667,9 +669,26 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Mut<'a>, K, V, Type> { } } - fn into_slices_mut(self) -> (&'a mut [K], &'a mut [V]) { - let k = unsafe { ptr::read(&self) }; - (k.into_key_slice_mut(), self.into_val_slice_mut()) + fn into_slices_mut(mut self) -> (&'a mut [K], &'a mut [V]) { + debug_assert!(!self.is_shared_root()); + // We cannot use the getters here, because calling the second one + // invalidates the reference returned by the first. + // More precisely, it is the call to `len` that is the culprit, + // because that creates a shared reference to the header, which *can* + // overlap with the keys (and even the values, for ZST keys). + unsafe { + let len = self.len(); + let leaf = self.as_leaf_mut(); + let keys = slice::from_raw_parts_mut( + MaybeUninit::first_ptr_mut(&mut (*leaf).keys), + len + ); + let vals = slice::from_raw_parts_mut( + MaybeUninit::first_ptr_mut(&mut (*leaf).vals), + len + ); + (keys, vals) + } } } diff --git a/src/liballoc/collections/vec_deque.rs b/src/liballoc/collections/vec_deque.rs index f778c4cbfde..4e90f783ec6 100644 --- a/src/liballoc/collections/vec_deque.rs +++ b/src/liballoc/collections/vec_deque.rs @@ -2170,12 +2170,29 @@ impl<'a, T> Iterator for Iter<'a, T> { back.iter().fold(accum, &mut f) } - fn try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R where - Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try<Ok=B> + fn try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R + where + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Ok = B>, { - let (front, back) = RingSlices::ring_slices(self.ring, self.head, self.tail); - let accum = front.iter().try_fold(init, &mut f)?; - back.iter().try_fold(accum, &mut f) + let (mut iter, final_res); + if self.tail <= self.head { + // single slice self.ring[self.tail..self.head] + iter = self.ring[self.tail..self.head].iter(); + final_res = iter.try_fold(init, &mut f); + } else { + // two slices: self.ring[self.tail..], self.ring[..self.head] + let (front, back) = self.ring.split_at(self.tail); + let mut back_iter = back.iter(); + let res = back_iter.try_fold(init, &mut f); + let len = self.ring.len(); + self.tail = (self.ring.len() - back_iter.len()) & (len - 1); + iter = front[..self.head].iter(); + final_res = iter.try_fold(res?, &mut f); + } + self.tail = self.head - iter.len(); + final_res } } @@ -2197,6 +2214,30 @@ impl<'a, T> DoubleEndedIterator for Iter<'a, T> { accum = back.iter().rfold(accum, &mut f); front.iter().rfold(accum, &mut f) } + + fn try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R + where + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Ok = B>, + { + let (mut iter, final_res); + if self.tail <= self.head { + // single slice self.ring[self.tail..self.head] + iter = self.ring[self.tail..self.head].iter(); + final_res = iter.try_rfold(init, &mut f); + } else { + // two slices: self.ring[self.tail..], self.ring[..self.head] + let (front, back) = self.ring.split_at(self.tail); + let mut front_iter = front[..self.head].iter(); + let res = front_iter.try_rfold(init, &mut f); + self.head = front_iter.len(); + iter = back.iter(); + final_res = iter.try_rfold(res?, &mut f); + } + self.head = self.tail + iter.len(); + final_res + } } #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/liballoc/tests/vec_deque.rs b/src/liballoc/tests/vec_deque.rs index e0cb0e7a9e7..16ddc1444fc 100644 --- a/src/liballoc/tests/vec_deque.rs +++ b/src/liballoc/tests/vec_deque.rs @@ -1465,6 +1465,15 @@ fn test_try_fold_unit() { assert_eq!(Some(()), v.into_iter().try_fold((), |(), ()| Some(()))); } + +#[test] +fn test_try_fold_unit_none() { + let v: std::collections::VecDeque<()> = [(); 10].iter().cloned().collect(); + let mut iter = v.into_iter(); + assert!(iter.try_fold((), |_, _| None).is_none()); + assert_eq!(iter.len(), 9); +} + #[test] fn test_try_fold_rotated() { let mut v: VecDeque<_> = (0..12).collect(); @@ -1477,3 +1486,58 @@ fn test_try_fold_rotated() { assert_eq!(Ok::<_, ()>(66), v.iter().try_fold(0, |a, b| Ok(a + b))); } } + +#[test] +fn test_try_fold_moves_iter() { + let v: VecDeque<_> = [10, 20, 30, 40, 100, 60, 70, 80, 90].iter().collect(); + let mut iter = v.into_iter(); + assert_eq!(iter.try_fold(0_i8, |acc, &x| acc.checked_add(x)), None); + assert_eq!(iter.next(), Some(&60)); +} + +#[test] +fn test_try_fold_exhaust_wrap() { + let mut v = VecDeque::with_capacity(7); + v.push_back(1); + v.push_back(1); + v.push_back(1); + v.pop_front(); + v.pop_front(); + let mut iter = v.iter(); + let _ = iter.try_fold(0, |_, _| Some(1)); + assert!(iter.is_empty()); +} + +#[test] +fn test_try_fold_wraparound() { + let mut v = VecDeque::with_capacity(8); + v.push_back(7); + v.push_back(8); + v.push_back(9); + v.push_front(2); + v.push_front(1); + let mut iter = v.iter(); + let _ = iter.find(|&&x| x == 2); + assert_eq!(Some(&7), iter.next()); +} + +#[test] +fn test_try_rfold_rotated() { + let mut v: VecDeque<_> = (0..12).collect(); + for n in 0..10 { + if n & 1 == 0 { + v.rotate_left(n); + } else { + v.rotate_right(n); + } + assert_eq!(Ok::<_, ()>(66), v.iter().try_rfold(0, |a, b| Ok(a + b))); + } +} + +#[test] +fn test_try_rfold_moves_iter() { + let v : VecDeque<_> = [10, 20, 30, 40, 100, 60, 70, 80, 90].iter().collect(); + let mut iter = v.into_iter(); + assert_eq!(iter.try_rfold(0_i8, |acc, &x| acc.checked_add(x)), None); + assert_eq!(iter.next_back(), Some(&70)); +} diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index a351d482fed..dddfa3f158e 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -1365,6 +1365,7 @@ impl<T: Default> Vec<T> { /// # Examples /// /// ``` + /// # #![allow(deprecated)] /// #![feature(vec_resize_default)] /// /// let mut vec = vec![1, 2, 3]; @@ -1381,6 +1382,9 @@ impl<T: Default> Vec<T> { /// [`Default`]: ../../std/default/trait.Default.html /// [`Clone`]: ../../std/clone/trait.Clone.html #[unstable(feature = "vec_resize_default", issue = "41758")] + #[rustc_deprecated(reason = "This is moving towards being removed in favor \ + of `.resize_with(Default::default)`. If you disagree, please comment \ + in the tracking issue.", since = "1.33.0")] pub fn resize_default(&mut self, new_len: usize) { let len = self.len(); diff --git a/src/libcore/future/future.rs b/src/libcore/future/future.rs index 84e7147153e..a143b54a61f 100644 --- a/src/libcore/future/future.rs +++ b/src/libcore/future/future.rs @@ -24,6 +24,7 @@ use task::{Poll, Waker}; /// /// When using a future, you generally won't call `poll` directly, but instead /// `await!` the value. +#[doc(spotlight)] #[must_use = "futures do nothing unless polled"] pub trait Future { /// The type of value produced on completion. diff --git a/src/librustc_mir/diagnostics.rs b/src/librustc_mir/diagnostics.rs index 4df3004a9ad..f369324157a 100644 --- a/src/librustc_mir/diagnostics.rs +++ b/src/librustc_mir/diagnostics.rs @@ -1545,20 +1545,22 @@ Erroneous code example: ```compile_fail,E0505 struct Value {} +fn borrow(val: &Value) {} + fn eat(val: Value) {} fn main() { let x = Value{}; - { - let _ref_to_val: &Value = &x; - eat(x); - } + let _ref_to_val: &Value = &x; + eat(x); + borrow(_ref_to_val); } ``` -Here, the function `eat` takes the ownership of `x`. However, -`x` cannot be moved because it was borrowed to `_ref_to_val`. -To fix that you can do few different things: +Here, the function `eat` takes ownership of `x`. However, +`x` cannot be moved because the borrow to `_ref_to_val` +needs to last till the function `borrow`. +To fix that you can do a few different things: * Try to avoid moving the variable. * Release borrow before move. @@ -1569,14 +1571,15 @@ Examples: ``` struct Value {} +fn borrow(val: &Value) {} + fn eat(val: &Value) {} fn main() { let x = Value{}; - { - let _ref_to_val: &Value = &x; - eat(&x); // pass by reference, if it's possible - } + let _ref_to_val: &Value = &x; + eat(&x); // pass by reference, if it's possible + borrow(_ref_to_val); } ``` @@ -1585,12 +1588,15 @@ Or: ``` struct Value {} +fn borrow(val: &Value) {} + fn eat(val: Value) {} fn main() { let x = Value{}; { let _ref_to_val: &Value = &x; + borrow(_ref_to_val); } eat(x); // release borrow and then move it. } @@ -1602,14 +1608,15 @@ Or: #[derive(Clone, Copy)] // implement Copy trait struct Value {} +fn borrow(val: &Value) {} + fn eat(val: Value) {} fn main() { let x = Value{}; - { - let _ref_to_val: &Value = &x; - eat(x); // it will be copied here. - } + let _ref_to_val: &Value = &x; + eat(x); // it will be copied here. + borrow(_ref_to_val); } ``` diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index b29e09900f6..ec701a939f2 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -326,6 +326,10 @@ where let mplace = MemPlace { ptr: val.to_scalar_ptr()?, + // We could use the run-time alignment here. For now, we do not, because + // the point of tracking the alignment here is to make sure that the *static* + // alignment information emitted with the loads is correct. The run-time + // alignment can only be more restrictive. align: layout.align.abi, meta: val.to_meta()?, }; @@ -385,9 +389,11 @@ where // above). In that case, all fields are equal. let field_layout = base.layout.field(self, usize::try_from(field).unwrap_or(0))?; - // Offset may need adjustment for unsized fields + // Offset may need adjustment for unsized fields. let (meta, offset) = if field_layout.is_unsized() { - // re-use parent metadata to determine dynamic field layout + // Re-use parent metadata to determine dynamic field layout. + // With custom DSTS, this *will* execute user-defined code, but the same + // happens at run-time so that's okay. let align = match self.size_and_align_of(base.meta, field_layout)? { Some((_, align)) => align, None if offset == Size::ZERO => diff --git a/src/librustc_resolve/error_reporting.rs b/src/librustc_resolve/error_reporting.rs index c8b3e2f4e4c..cd771d93e00 100644 --- a/src/librustc_resolve/error_reporting.rs +++ b/src/librustc_resolve/error_reporting.rs @@ -259,6 +259,10 @@ impl<'a> Resolver<'a> { format!("{}!", path_str), Applicability::MaybeIncorrect, ); + if path_str == "try" && span.rust_2015() { + err.note("if you want the `try` keyword, \ + you need to be in the 2018 edition"); + } } (Def::TyAlias(..), PathSource::Trait(_)) => { err.span_label(span, "type aliases cannot be used as traits"); diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index 7cbf24402d7..bef2afc7b62 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -259,6 +259,11 @@ impl ToJson for MergeFunctions { } } +pub enum LoadTargetError { + BuiltinTargetNotFound(String), + Other(String), +} + pub type LinkArgs = BTreeMap<LinkerFlavor, Vec<String>>; pub type TargetResult = Result<Target, String>; @@ -269,21 +274,24 @@ macro_rules! supported_targets { /// List of supported targets const TARGETS: &[&str] = &[$($triple),*]; - fn load_specific(target: &str) -> TargetResult { + fn load_specific(target: &str) -> Result<Target, LoadTargetError> { match target { $( $triple => { - let mut t = $module::target()?; + let mut t = $module::target() + .map_err(LoadTargetError::Other)?; t.options.is_builtin = true; // round-trip through the JSON parser to ensure at // run-time that the parser works correctly - t = Target::from_json(t.to_json())?; + t = Target::from_json(t.to_json()) + .map_err(LoadTargetError::Other)?; debug!("Got builtin target: {:?}", t); Ok(t) }, )+ - _ => Err(format!("Unable to find target: {}", target)) + _ => Err(LoadTargetError::BuiltinTargetNotFound( + format!("Unable to find target: {}", target))) } } @@ -1176,8 +1184,10 @@ impl Target { match *target_triple { TargetTriple::TargetTriple(ref target_triple) => { // check if triple is in list of supported targets - if let Ok(t) = load_specific(target_triple) { - return Ok(t) + match load_specific(target_triple) { + Ok(t) => return Ok(t), + Err(LoadTargetError::BuiltinTargetNotFound(_)) => (), + Err(LoadTargetError::Other(e)) => return Err(e), } // search for a file named `target_triple`.json in RUST_TARGET_PATH diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 62b79646f6b..7f7fffbba10 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -458,26 +458,18 @@ fn resolution_failure( link_range: Option<Range<usize>>, ) { let sp = span_of_attrs(attrs); - let msg = format!("`[{}]` cannot be resolved, ignoring it...", path_str); - let mut diag = if let Some(link_range) = link_range { + let mut diag = cx.tcx.struct_span_lint_node( + lint::builtin::INTRA_DOC_LINK_RESOLUTION_FAILURE, + NodeId::from_u32(0), + sp, + &format!("`[{}]` cannot be resolved, ignoring it...", path_str), + ); + if let Some(link_range) = link_range { if let Some(sp) = super::source_span_for_markdown_range(cx, dox, &link_range, attrs) { - let mut diag = cx.tcx.struct_span_lint_node( - lint::builtin::INTRA_DOC_LINK_RESOLUTION_FAILURE, - NodeId::from_u32(0), - sp, - &msg, - ); + diag.set_span(sp); diag.span_label(sp, "cannot be resolved, ignoring"); - diag } else { - let mut diag = cx.tcx.struct_span_lint_node( - lint::builtin::INTRA_DOC_LINK_RESOLUTION_FAILURE, - NodeId::from_u32(0), - sp, - &msg, - ); - // blah blah blah\nblah\nblah [blah] blah blah\nblah blah // ^ ~~~~ // | link_range @@ -494,13 +486,7 @@ fn resolution_failure( before=link_range.start - last_new_line_offset, found=link_range.len(), )); - diag } - } else { - cx.tcx.struct_span_lint_node(lint::builtin::INTRA_DOC_LINK_RESOLUTION_FAILURE, - NodeId::from_u32(0), - sp, - &msg) }; diag.help("to escape `[` and `]` characters, just add '\\' before them like \ `\\[` or `\\]`"); diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index f849daf2079..6dd3a6cc0fd 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -215,16 +215,22 @@ // std may use features in a platform-specific way #![allow(unused_features)] +#![cfg_attr(test, feature(test, update_panic_count))] +#![cfg_attr(all(target_vendor = "fortanix", target_env = "sgx"), + feature(global_asm, range_contains, slice_index_methods, + decl_macro, coerce_unsized, sgx_platform, ptr_wrapping_offset_from))] + // std is implemented with unstable features, many of which are internal // compiler details that will never be stable -#![cfg_attr(test, feature(test, update_panic_count))] -#![feature(alloc)] +// NB: the following list is sorted to minimize merge conflicts. +#![feature(align_offset)] #![feature(alloc_error_handler)] +#![feature(alloc_layout_extra)] +#![feature(alloc)] #![feature(allocator_api)] #![feature(allocator_internals)] #![feature(allow_internal_unsafe)] #![feature(allow_internal_unstable)] -#![feature(align_offset)] #![feature(arbitrary_self_types)] #![feature(array_error_internals)] #![feature(asm)] @@ -233,20 +239,28 @@ #![feature(cfg_target_has_atomic)] #![feature(cfg_target_thread_local)] #![feature(char_error_internals)] +#![feature(checked_duration_since)] #![feature(compiler_builtins_lib)] #![feature(concat_idents)] -#![feature(const_raw_ptr_deref)] #![feature(const_cstr_unchecked)] +#![feature(const_raw_ptr_deref)] #![feature(core_intrinsics)] +#![feature(doc_alias)] +#![feature(doc_cfg)] +#![feature(doc_keyword)] +#![feature(doc_masked)] +#![feature(doc_spotlight)] #![feature(dropck_eyepatch)] #![feature(duration_constants)] #![feature(exact_size_is_empty)] +#![feature(exhaustive_patterns)] #![feature(external_doc)] #![feature(fixed_size_array)] #![feature(fn_traits)] #![feature(fnbox)] #![feature(futures_api)] #![feature(generator_trait)] +#![feature(hash_raw_entry)] #![feature(hashmap_internals)] #![feature(int_error_internals)] #![feature(integer_atomics)] @@ -254,31 +268,32 @@ #![feature(libc)] #![feature(link_args)] #![feature(linkage)] +#![feature(maybe_uninit)] #![feature(needs_panic_runtime)] #![feature(never_type)] #![feature(nll)] -#![feature(exhaustive_patterns)] +#![feature(non_exhaustive)] #![feature(on_unimplemented)] #![feature(optin_builtin_traits)] +#![feature(panic_info_message)] #![feature(panic_internals)] #![feature(panic_unwind)] #![feature(prelude_import)] #![feature(ptr_internals)] #![feature(raw)] -#![feature(hash_raw_entry)] +#![feature(renamed_spin_loop)] #![feature(rustc_attrs)] #![feature(rustc_const_unstable)] -#![feature(std_internals)] -#![feature(stdsimd)] +#![feature(rustc_private)] #![feature(shrink_to)] #![feature(slice_concat_ext)] #![feature(slice_internals)] #![feature(slice_patterns)] #![feature(staged_api)] +#![feature(std_internals)] +#![feature(stdsimd)] #![feature(stmt_expr_attributes)] #![feature(str_internals)] -#![feature(renamed_spin_loop)] -#![feature(rustc_private)] #![feature(thread_local)] #![feature(toowned_clone_into)] #![feature(try_from)] @@ -286,19 +301,7 @@ #![feature(unboxed_closures)] #![feature(untagged_unions)] #![feature(unwind_attributes)] -#![feature(doc_cfg)] -#![feature(doc_masked)] -#![feature(doc_spotlight)] -#![feature(doc_alias)] -#![feature(doc_keyword)] -#![feature(panic_info_message)] -#![feature(non_exhaustive)] -#![feature(alloc_layout_extra)] -#![feature(maybe_uninit)] -#![feature(checked_duration_since)] -#![cfg_attr(all(target_vendor = "fortanix", target_env = "sgx"), - feature(global_asm, range_contains, slice_index_methods, - decl_macro, coerce_unsized, sgx_platform, ptr_wrapping_offset_from))] +// NB: the above list is sorted to minimize merge conflicts. #![default_lib_allocator] diff --git a/src/libstd/sys/redox/ext/process.rs b/src/libstd/sys/redox/ext/process.rs index 1dcc1169510..020075531dd 100644 --- a/src/libstd/sys/redox/ext/process.rs +++ b/src/libstd/sys/redox/ext/process.rs @@ -36,7 +36,7 @@ pub trait CommandExt { /// will be called and the spawn operation will immediately return with a /// failure. /// - /// # Notes + /// # Notes and Safety /// /// This closure will be run in the context of the child process after a /// `fork`. This primarily means that any modifications made to memory on @@ -45,12 +45,32 @@ pub trait CommandExt { /// like `malloc` or acquiring a mutex are not guaranteed to work (due to /// other threads perhaps still running when the `fork` was run). /// + /// This also means that all resources such as file descriptors and + /// memory-mapped regions got duplicated. It is your responsibility to make + /// sure that the closure does not violate library invariants by making + /// invalid use of these duplicates. + /// /// When this closure is run, aspects such as the stdio file descriptors and /// working directory have successfully been changed, so output to these /// locations may not appear where intended. + #[stable(feature = "process_pre_exec", since = "1.34.0")] + unsafe fn pre_exec<F>(&mut self, f: F) -> &mut process::Command + where F: FnMut() -> io::Result<()> + Send + Sync + 'static; + + /// Schedules a closure to be run just before the `exec` function is + /// invoked. + /// + /// This method is stable and usable, but it should be unsafe. To fix + /// that, it got deprecated in favor of the unsafe [`pre_exec`]. + /// + /// [`pre_exec`]: #tymethod.pre_exec #[stable(feature = "process_exec", since = "1.15.0")] + #[rustc_deprecated(since = "1.37.0", reason = "should be unsafe, use `pre_exec` instead")] fn before_exec<F>(&mut self, f: F) -> &mut process::Command - where F: FnMut() -> io::Result<()> + Send + Sync + 'static; + where F: FnMut() -> io::Result<()> + Send + Sync + 'static + { + unsafe { self.pre_exec(f) } + } /// Performs all the required setup by this `Command`, followed by calling /// the `execvp` syscall. @@ -87,10 +107,10 @@ impl CommandExt for process::Command { self } - fn before_exec<F>(&mut self, f: F) -> &mut process::Command + unsafe fn pre_exec<F>(&mut self, f: F) -> &mut process::Command where F: FnMut() -> io::Result<()> + Send + Sync + 'static { - self.as_inner_mut().before_exec(Box::new(f)); + self.as_inner_mut().pre_exec(Box::new(f)); self } diff --git a/src/libstd/sys/redox/process.rs b/src/libstd/sys/redox/process.rs index 9e23c537f22..81af8eb553d 100644 --- a/src/libstd/sys/redox/process.rs +++ b/src/libstd/sys/redox/process.rs @@ -116,8 +116,10 @@ impl Command { self.gid = Some(id); } - pub fn before_exec(&mut self, - f: Box<dyn FnMut() -> io::Result<()> + Send + Sync>) { + pub unsafe fn pre_exec( + &mut self, + f: Box<dyn FnMut() -> io::Result<()> + Send + Sync>, + ) { self.closures.push(f); } diff --git a/src/libstd/sys/unix/ext/process.rs b/src/libstd/sys/unix/ext/process.rs index 2c5943fdac3..b487bb889ba 100644 --- a/src/libstd/sys/unix/ext/process.rs +++ b/src/libstd/sys/unix/ext/process.rs @@ -36,7 +36,7 @@ pub trait CommandExt { /// will be called and the spawn operation will immediately return with a /// failure. /// - /// # Notes + /// # Notes and Safety /// /// This closure will be run in the context of the child process after a /// `fork`. This primarily means that any modifications made to memory on @@ -45,12 +45,32 @@ pub trait CommandExt { /// like `malloc` or acquiring a mutex are not guaranteed to work (due to /// other threads perhaps still running when the `fork` was run). /// + /// This also means that all resources such as file descriptors and + /// memory-mapped regions got duplicated. It is your responsibility to make + /// sure that the closure does not violate library invariants by making + /// invalid use of these duplicates. + /// /// When this closure is run, aspects such as the stdio file descriptors and /// working directory have successfully been changed, so output to these /// locations may not appear where intended. + #[stable(feature = "process_pre_exec", since = "1.34.0")] + unsafe fn pre_exec<F>(&mut self, f: F) -> &mut process::Command + where F: FnMut() -> io::Result<()> + Send + Sync + 'static; + + /// Schedules a closure to be run just before the `exec` function is + /// invoked. + /// + /// This method is stable and usable, but it should be unsafe. To fix + /// that, it got deprecated in favor of the unsafe [`pre_exec`]. + /// + /// [`pre_exec`]: #tymethod.pre_exec #[stable(feature = "process_exec", since = "1.15.0")] + #[rustc_deprecated(since = "1.37.0", reason = "should be unsafe, use `pre_exec` instead")] fn before_exec<F>(&mut self, f: F) -> &mut process::Command - where F: FnMut() -> io::Result<()> + Send + Sync + 'static; + where F: FnMut() -> io::Result<()> + Send + Sync + 'static + { + unsafe { self.pre_exec(f) } + } /// Performs all the required setup by this `Command`, followed by calling /// the `execvp` syscall. @@ -97,10 +117,10 @@ impl CommandExt for process::Command { self } - fn before_exec<F>(&mut self, f: F) -> &mut process::Command + unsafe fn pre_exec<F>(&mut self, f: F) -> &mut process::Command where F: FnMut() -> io::Result<()> + Send + Sync + 'static { - self.as_inner_mut().before_exec(Box::new(f)); + self.as_inner_mut().pre_exec(Box::new(f)); self } diff --git a/src/libstd/sys/unix/process/process_common.rs b/src/libstd/sys/unix/process/process_common.rs index 2c55813c5cd..7fa256e59b2 100644 --- a/src/libstd/sys/unix/process/process_common.rs +++ b/src/libstd/sys/unix/process/process_common.rs @@ -149,8 +149,10 @@ impl Command { &mut self.closures } - pub fn before_exec(&mut self, - f: Box<dyn FnMut() -> io::Result<()> + Send + Sync>) { + pub unsafe fn pre_exec( + &mut self, + f: Box<dyn FnMut() -> io::Result<()> + Send + Sync>, + ) { self.closures.push(f); } diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 48f6e4c0c82..27b0cfb1630 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -9,12 +9,6 @@ use crate::ThinVec; use rustc_target::spec::abi::Abi; use syntax_pos::{Pos, Span, DUMMY_SP}; -// Transitional re-exports so qquote can find the paths it is looking for -mod syntax { - pub use crate::ext; - pub use crate::parse; -} - pub trait AstBuilder { // paths fn path(&self, span: Span, strs: Vec<ast::Ident> ) -> ast::Path; diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index d398437d7af..f50663f9785 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -36,10 +36,8 @@ macro_rules! ast_fragments { ( $($Kind:ident($AstTy:ty) { $kind_name:expr; - // FIXME: HACK: this should be `$(one ...)?` and `$(many ...)?` but `?` macro - // repetition was removed from 2015 edition in #51587 because of ambiguities. - $(one fn $mut_visit_ast:ident; fn $visit_ast:ident;)* - $(many fn $flat_map_ast_elt:ident; fn $visit_ast_elt:ident;)* + $(one fn $mut_visit_ast:ident; fn $visit_ast:ident;)? + $(many fn $flat_map_ast_elt:ident; fn $visit_ast_elt:ident;)? fn $make_ast:ident; })* ) => { diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index b1fb38d8eaf..e6a48912c48 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -5503,6 +5503,7 @@ impl<'a> Parser<'a> { if is_bound_start { let lo = self.span; let has_parens = self.eat(&token::OpenDelim(token::Paren)); + let inner_lo = self.span; let question = if self.eat(&token::Question) { Some(self.prev_span) } else { None }; if self.token.is_lifetime() { if let Some(question_span) = question { @@ -5511,9 +5512,21 @@ impl<'a> Parser<'a> { } bounds.push(GenericBound::Outlives(self.expect_lifetime())); if has_parens { + let inner_span = inner_lo.to(self.prev_span); self.expect(&token::CloseDelim(token::Paren))?; - self.span_err(self.prev_span, - "parenthesized lifetime bounds are not supported"); + let mut err = self.struct_span_err( + lo.to(self.prev_span), + "parenthesized lifetime bounds are not supported" + ); + if let Ok(snippet) = self.sess.source_map().span_to_snippet(inner_span) { + err.span_suggestion_short( + lo.to(self.prev_span), + "remove the parentheses", + snippet.to_owned(), + Applicability::MachineApplicable + ); + } + err.emit(); } } else { let lifetime_defs = self.parse_late_bound_lifetime_defs()?; diff --git a/src/test/run-pass/command-before-exec.rs b/src/test/run-pass/command-before-exec.rs deleted file mode 100644 index 91d2636b2ae..00000000000 --- a/src/test/run-pass/command-before-exec.rs +++ /dev/null @@ -1,83 +0,0 @@ -#![allow(stable_features)] -// ignore-windows - this is a unix-specific test -// ignore-cloudabi no processes -// ignore-emscripten no processes - -#![feature(process_exec, rustc_private)] - -extern crate libc; - -use std::env; -use std::io::Error; -use std::os::unix::process::CommandExt; -use std::process::Command; -use std::sync::Arc; -use std::sync::atomic::{AtomicUsize, Ordering}; - -fn main() { - if let Some(arg) = env::args().nth(1) { - match &arg[..] { - "test1" => println!("hello2"), - "test2" => assert_eq!(env::var("FOO").unwrap(), "BAR"), - "test3" => assert_eq!(env::current_dir().unwrap() - .to_str().unwrap(), "/"), - "empty" => {} - _ => panic!("unknown argument: {}", arg), - } - return - } - - let me = env::current_exe().unwrap(); - - let output = Command::new(&me).arg("test1").before_exec(|| { - println!("hello"); - Ok(()) - }).output().unwrap(); - assert!(output.status.success()); - assert!(output.stderr.is_empty()); - assert_eq!(output.stdout, b"hello\nhello2\n"); - - let output = Command::new(&me).arg("test2").before_exec(|| { - env::set_var("FOO", "BAR"); - Ok(()) - }).output().unwrap(); - assert!(output.status.success()); - assert!(output.stderr.is_empty()); - assert!(output.stdout.is_empty()); - - let output = Command::new(&me).arg("test3").before_exec(|| { - env::set_current_dir("/").unwrap(); - Ok(()) - }).output().unwrap(); - assert!(output.status.success()); - assert!(output.stderr.is_empty()); - assert!(output.stdout.is_empty()); - - let output = Command::new(&me).arg("bad").before_exec(|| { - Err(Error::from_raw_os_error(102)) - }).output().unwrap_err(); - assert_eq!(output.raw_os_error(), Some(102)); - - let pid = unsafe { libc::getpid() }; - assert!(pid >= 0); - let output = Command::new(&me).arg("empty").before_exec(move || { - let child = unsafe { libc::getpid() }; - assert!(child >= 0); - assert!(pid != child); - Ok(()) - }).output().unwrap(); - assert!(output.status.success()); - assert!(output.stderr.is_empty()); - assert!(output.stdout.is_empty()); - - let mem = Arc::new(AtomicUsize::new(0)); - let mem2 = mem.clone(); - let output = Command::new(&me).arg("empty").before_exec(move || { - assert_eq!(mem2.fetch_add(1, Ordering::SeqCst), 0); - Ok(()) - }).output().unwrap(); - assert!(output.status.success()); - assert!(output.stderr.is_empty()); - assert!(output.stdout.is_empty()); - assert_eq!(mem.load(Ordering::SeqCst), 0); -} diff --git a/src/test/run-pass/command-pre-exec.rs b/src/test/run-pass/command-pre-exec.rs new file mode 100644 index 00000000000..21783fedd39 --- /dev/null +++ b/src/test/run-pass/command-pre-exec.rs @@ -0,0 +1,115 @@ +#![allow(stable_features)] +// ignore-windows - this is a unix-specific test +// ignore-cloudabi no processes +// ignore-emscripten no processes +#![feature(process_exec, rustc_private)] + +extern crate libc; + +use std::env; +use std::io::Error; +use std::os::unix::process::CommandExt; +use std::process::Command; +use std::sync::atomic::{AtomicUsize, Ordering}; +use std::sync::Arc; + +fn main() { + if let Some(arg) = env::args().nth(1) { + match &arg[..] { + "test1" => println!("hello2"), + "test2" => assert_eq!(env::var("FOO").unwrap(), "BAR"), + "test3" => assert_eq!(env::current_dir().unwrap().to_str().unwrap(), "/"), + "empty" => {} + _ => panic!("unknown argument: {}", arg), + } + return; + } + + let me = env::current_exe().unwrap(); + + let output = unsafe { + Command::new(&me) + .arg("test1") + .pre_exec(|| { + println!("hello"); + Ok(()) + }) + .output() + .unwrap() + }; + assert!(output.status.success()); + assert!(output.stderr.is_empty()); + assert_eq!(output.stdout, b"hello\nhello2\n"); + + let output = unsafe { + Command::new(&me) + .arg("test2") + .pre_exec(|| { + env::set_var("FOO", "BAR"); + Ok(()) + }) + .output() + .unwrap() + }; + assert!(output.status.success()); + assert!(output.stderr.is_empty()); + assert!(output.stdout.is_empty()); + + let output = unsafe { + Command::new(&me) + .arg("test3") + .pre_exec(|| { + env::set_current_dir("/").unwrap(); + Ok(()) + }) + .output() + .unwrap() + }; + assert!(output.status.success()); + assert!(output.stderr.is_empty()); + assert!(output.stdout.is_empty()); + + let output = unsafe { + Command::new(&me) + .arg("bad") + .pre_exec(|| Err(Error::from_raw_os_error(102))) + .output() + .unwrap_err() + }; + assert_eq!(output.raw_os_error(), Some(102)); + + let pid = unsafe { libc::getpid() }; + assert!(pid >= 0); + let output = unsafe { + Command::new(&me) + .arg("empty") + .pre_exec(move || { + let child = libc::getpid(); + assert!(child >= 0); + assert!(pid != child); + Ok(()) + }) + .output() + .unwrap() + }; + assert!(output.status.success()); + assert!(output.stderr.is_empty()); + assert!(output.stdout.is_empty()); + + let mem = Arc::new(AtomicUsize::new(0)); + let mem2 = mem.clone(); + let output = unsafe { + Command::new(&me) + .arg("empty") + .pre_exec(move || { + assert_eq!(mem2.fetch_add(1, Ordering::SeqCst), 0); + Ok(()) + }) + .output() + .unwrap() + }; + assert!(output.status.success()); + assert!(output.stderr.is_empty()); + assert!(output.stdout.is_empty()); + assert_eq!(mem.load(Ordering::SeqCst), 0); +} diff --git a/src/test/ui/parser/trait-object-lifetime-parens.stderr b/src/test/ui/parser/trait-object-lifetime-parens.stderr index a9b542ddcc4..94ca66aef72 100644 --- a/src/test/ui/parser/trait-object-lifetime-parens.stderr +++ b/src/test/ui/parser/trait-object-lifetime-parens.stderr @@ -1,14 +1,14 @@ error: parenthesized lifetime bounds are not supported - --> $DIR/trait-object-lifetime-parens.rs:5:24 + --> $DIR/trait-object-lifetime-parens.rs:5:21 | LL | fn f<'a, T: Trait + ('a)>() {} //~ ERROR parenthesized lifetime bounds are not supported - | ^ + | ^^^^ help: remove the parentheses error: parenthesized lifetime bounds are not supported - --> $DIR/trait-object-lifetime-parens.rs:8:27 + --> $DIR/trait-object-lifetime-parens.rs:8:24 | LL | let _: Box<Trait + ('a)>; //~ ERROR parenthesized lifetime bounds are not supported - | ^ + | ^^^^ help: remove the parentheses error: expected type, found `'a` --> $DIR/trait-object-lifetime-parens.rs:9:17 diff --git a/src/test/ui/try-block/try-block-in-edition2015.stderr b/src/test/ui/try-block/try-block-in-edition2015.stderr index a7b81060d3d..7394fec6f36 100644 --- a/src/test/ui/try-block/try-block-in-edition2015.stderr +++ b/src/test/ui/try-block/try-block-in-edition2015.stderr @@ -16,6 +16,8 @@ error[E0574]: expected struct, variant or union type, found macro `try` | LL | let try_result: Option<_> = try { | ^^^ help: use `!` to invoke the macro: `try!` + | + = note: if you want the `try` keyword, you need to be in the 2018 edition error: aborting due to 2 previous errors diff --git a/src/tools/publish_toolstate.py b/src/tools/publish_toolstate.py index abcf14d90be..fb6132a5358 100755 --- a/src/tools/publish_toolstate.py +++ b/src/tools/publish_toolstate.py @@ -25,7 +25,7 @@ MAINTAINERS = { } REPOS = { - 'miri': 'https://github.com/solson/miri', + 'miri': 'https://github.com/rust-lang/miri', 'clippy-driver': 'https://github.com/rust-lang/rust-clippy', 'rls': 'https://github.com/rust-lang/rls', 'rustfmt': 'https://github.com/rust-lang/rustfmt', |
