Skip to content

Commit dd4851d

Browse files
committed
Auto merge of #82053 - JohnTitor:rollup-ymi9q0g, r=JohnTitor
Rollup of 8 pull requests Successful merges: - #81811 (Fix doc test for Vec::retain(), now passes clippy::eval_order_dependence) - #81900 (Organize trait test files) - #81995 (Fix suggestion to introduce explicit lifetime) - #82031 (Drop an unnecessary intermediate variable) - #82033 (Refactor `get_word_attr` to return only `Option`) - #82040 (Add test to prevent src link regression) - #82041 (Add docs for shared_from_slice From impls) - #82050 (Added tests to drain an empty vec) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 21cbbdc + 0ca5fd7 commit dd4851d

File tree

300 files changed

+491
-309
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

300 files changed

+491
-309
lines changed

Diff for: compiler/rustc_infer/src/infer/error_reporting/mod.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -2248,13 +2248,18 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
22482248
"...",
22492249
);
22502250
if let Some(infer::RelateParamBound(_, t)) = origin {
2251+
let return_impl_trait = self
2252+
.in_progress_typeck_results
2253+
.map(|typeck_results| typeck_results.borrow().hir_owner)
2254+
.and_then(|owner| self.tcx.return_type_impl_trait(owner))
2255+
.is_some();
22512256
let t = self.resolve_vars_if_possible(t);
22522257
match t.kind() {
22532258
// We've got:
22542259
// fn get_later<G, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
22552260
// suggest:
22562261
// fn get_later<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a
2257-
ty::Closure(_, _substs) | ty::Opaque(_, _substs) => {
2262+
ty::Closure(_, _substs) | ty::Opaque(_, _substs) if return_impl_trait => {
22582263
new_binding_suggestion(&mut err, type_param_span, bound_kind);
22592264
}
22602265
_ => {

Diff for: compiler/rustc_typeck/src/check/upvar.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -260,8 +260,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
260260
// local crate or were inlined into it along with some function.
261261
// This may change if abstract return types of some sort are
262262
// implemented.
263-
let tcx = self.tcx;
264-
265263
self.typeck_results
266264
.borrow()
267265
.closure_min_captures_flattened(closure_id)
@@ -276,7 +274,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
276274

277275
match capture {
278276
ty::UpvarCapture::ByValue(_) => upvar_ty,
279-
ty::UpvarCapture::ByRef(borrow) => tcx.mk_ref(
277+
ty::UpvarCapture::ByRef(borrow) => self.tcx.mk_ref(
280278
borrow.region,
281279
ty::TypeAndMut { ty: upvar_ty, mutbl: borrow.kind.to_mutbl_lossy() },
282280
),

Diff for: library/alloc/src/rc.rs

+49
Original file line numberDiff line numberDiff line change
@@ -1652,6 +1652,16 @@ impl<T> From<T> for Rc<T> {
16521652

16531653
#[stable(feature = "shared_from_slice", since = "1.21.0")]
16541654
impl<T: Clone> From<&[T]> for Rc<[T]> {
1655+
/// Allocate a reference-counted slice and fill it by cloning `v`'s items.
1656+
///
1657+
/// # Example
1658+
///
1659+
/// ```
1660+
/// # use std::rc::Rc;
1661+
/// let original: &[i32] = &[1, 2, 3];
1662+
/// let shared: Rc<[i32]> = Rc::from(original);
1663+
/// assert_eq!(&[1, 2, 3], &shared[..]);
1664+
/// ```
16551665
#[inline]
16561666
fn from(v: &[T]) -> Rc<[T]> {
16571667
<Self as RcFromSlice<T>>::from_slice(v)
@@ -1660,6 +1670,15 @@ impl<T: Clone> From<&[T]> for Rc<[T]> {
16601670

16611671
#[stable(feature = "shared_from_slice", since = "1.21.0")]
16621672
impl From<&str> for Rc<str> {
1673+
/// Allocate a reference-counted string slice and copy `v` into it.
1674+
///
1675+
/// # Example
1676+
///
1677+
/// ```
1678+
/// # use std::rc::Rc;
1679+
/// let shared: Rc<str> = Rc::from("statue");
1680+
/// assert_eq!("statue", &shared[..]);
1681+
/// ```
16631682
#[inline]
16641683
fn from(v: &str) -> Rc<str> {
16651684
let rc = Rc::<[u8]>::from(v.as_bytes());
@@ -1669,6 +1688,16 @@ impl From<&str> for Rc<str> {
16691688

16701689
#[stable(feature = "shared_from_slice", since = "1.21.0")]
16711690
impl From<String> for Rc<str> {
1691+
/// Allocate a reference-counted string slice and copy `v` into it.
1692+
///
1693+
/// # Example
1694+
///
1695+
/// ```
1696+
/// # use std::rc::Rc;
1697+
/// let original: String = "statue".to_owned();
1698+
/// let shared: Rc<str> = Rc::from(original);
1699+
/// assert_eq!("statue", &shared[..]);
1700+
/// ```
16721701
#[inline]
16731702
fn from(v: String) -> Rc<str> {
16741703
Rc::from(&v[..])
@@ -1677,6 +1706,16 @@ impl From<String> for Rc<str> {
16771706

16781707
#[stable(feature = "shared_from_slice", since = "1.21.0")]
16791708
impl<T: ?Sized> From<Box<T>> for Rc<T> {
1709+
/// Move a boxed object to a new, reference counted, allocation.
1710+
///
1711+
/// # Example
1712+
///
1713+
/// ```
1714+
/// # use std::rc::Rc;
1715+
/// let original: Box<i32> = Box::new(1);
1716+
/// let shared: Rc<i32> = Rc::from(original);
1717+
/// assert_eq!(1, *shared);
1718+
/// ```
16801719
#[inline]
16811720
fn from(v: Box<T>) -> Rc<T> {
16821721
Rc::from_box(v)
@@ -1685,6 +1724,16 @@ impl<T: ?Sized> From<Box<T>> for Rc<T> {
16851724

16861725
#[stable(feature = "shared_from_slice", since = "1.21.0")]
16871726
impl<T> From<Vec<T>> for Rc<[T]> {
1727+
/// Allocate a reference-counted slice and move `v`'s items into it.
1728+
///
1729+
/// # Example
1730+
///
1731+
/// ```
1732+
/// # use std::rc::Rc;
1733+
/// let original: Box<Vec<i32>> = Box::new(vec![1, 2, 3]);
1734+
/// let shared: Rc<Vec<i32>> = Rc::from(original);
1735+
/// assert_eq!(vec![1, 2, 3], *shared);
1736+
/// ```
16881737
#[inline]
16891738
fn from(mut v: Vec<T>) -> Rc<[T]> {
16901739
unsafe {

Diff for: library/alloc/src/sync.rs

+49
Original file line numberDiff line numberDiff line change
@@ -2285,6 +2285,16 @@ impl<T> From<T> for Arc<T> {
22852285

22862286
#[stable(feature = "shared_from_slice", since = "1.21.0")]
22872287
impl<T: Clone> From<&[T]> for Arc<[T]> {
2288+
/// Allocate a reference-counted slice and fill it by cloning `v`'s items.
2289+
///
2290+
/// # Example
2291+
///
2292+
/// ```
2293+
/// # use std::sync::Arc;
2294+
/// let original: &[i32] = &[1, 2, 3];
2295+
/// let shared: Arc<[i32]> = Arc::from(original);
2296+
/// assert_eq!(&[1, 2, 3], &shared[..]);
2297+
/// ```
22882298
#[inline]
22892299
fn from(v: &[T]) -> Arc<[T]> {
22902300
<Self as ArcFromSlice<T>>::from_slice(v)
@@ -2293,6 +2303,15 @@ impl<T: Clone> From<&[T]> for Arc<[T]> {
22932303

22942304
#[stable(feature = "shared_from_slice", since = "1.21.0")]
22952305
impl From<&str> for Arc<str> {
2306+
/// Allocate a reference-counted `str` and copy `v` into it.
2307+
///
2308+
/// # Example
2309+
///
2310+
/// ```
2311+
/// # use std::sync::Arc;
2312+
/// let shared: Arc<str> = Arc::from("eggplant");
2313+
/// assert_eq!("eggplant", &shared[..]);
2314+
/// ```
22962315
#[inline]
22972316
fn from(v: &str) -> Arc<str> {
22982317
let arc = Arc::<[u8]>::from(v.as_bytes());
@@ -2302,6 +2321,16 @@ impl From<&str> for Arc<str> {
23022321

23032322
#[stable(feature = "shared_from_slice", since = "1.21.0")]
23042323
impl From<String> for Arc<str> {
2324+
/// Allocate a reference-counted `str` and copy `v` into it.
2325+
///
2326+
/// # Example
2327+
///
2328+
/// ```
2329+
/// # use std::sync::Arc;
2330+
/// let unique: String = "eggplant".to_owned();
2331+
/// let shared: Arc<str> = Arc::from(unique);
2332+
/// assert_eq!("eggplant", &shared[..]);
2333+
/// ```
23052334
#[inline]
23062335
fn from(v: String) -> Arc<str> {
23072336
Arc::from(&v[..])
@@ -2310,6 +2339,16 @@ impl From<String> for Arc<str> {
23102339

23112340
#[stable(feature = "shared_from_slice", since = "1.21.0")]
23122341
impl<T: ?Sized> From<Box<T>> for Arc<T> {
2342+
/// Move a boxed object to a new, reference-counted allocation.
2343+
///
2344+
/// # Example
2345+
///
2346+
/// ```
2347+
/// # use std::sync::Arc;
2348+
/// let unique: Box<str> = Box::from("eggplant");
2349+
/// let shared: Arc<str> = Arc::from(unique);
2350+
/// assert_eq!("eggplant", &shared[..]);
2351+
/// ```
23132352
#[inline]
23142353
fn from(v: Box<T>) -> Arc<T> {
23152354
Arc::from_box(v)
@@ -2318,6 +2357,16 @@ impl<T: ?Sized> From<Box<T>> for Arc<T> {
23182357

23192358
#[stable(feature = "shared_from_slice", since = "1.21.0")]
23202359
impl<T> From<Vec<T>> for Arc<[T]> {
2360+
/// Allocate a reference-counted slice and move `v`'s items into it.
2361+
///
2362+
/// # Example
2363+
///
2364+
/// ```
2365+
/// # use std::sync::Arc;
2366+
/// let unique: Vec<i32> = vec![1, 2, 3];
2367+
/// let shared: Arc<[i32]> = Arc::from(unique);
2368+
/// assert_eq!(&[1, 2, 3], &shared[..]);
2369+
/// ```
23212370
#[inline]
23222371
fn from(mut v: Vec<T>) -> Arc<[T]> {
23232372
unsafe {

Diff for: library/alloc/src/vec/mod.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -1385,13 +1385,14 @@ impl<T, A: Allocator> Vec<T, A> {
13851385
/// assert_eq!(vec, [2, 4]);
13861386
/// ```
13871387
///
1388-
/// The exact order may be useful for tracking external state, like an index.
1388+
/// Because the elements are visited exactly once in the original order,
1389+
/// external state may be used to decide which elements to keep.
13891390
///
13901391
/// ```
13911392
/// let mut vec = vec![1, 2, 3, 4, 5];
13921393
/// let keep = [false, true, true, false, true];
1393-
/// let mut i = 0;
1394-
/// vec.retain(|_| (keep[i], i += 1).0);
1394+
/// let mut iter = keep.iter();
1395+
/// vec.retain(|_| *iter.next().unwrap());
13951396
/// assert_eq!(vec, [2, 3, 5]);
13961397
/// ```
13971398
#[stable(feature = "rust1", since = "1.0.0")]

Diff for: library/alloc/tests/vec.rs

+11
Original file line numberDiff line numberDiff line change
@@ -609,6 +609,17 @@ fn test_move_items_zero_sized() {
609609
assert_eq!(vec2, [(), (), ()]);
610610
}
611611

612+
#[test]
613+
fn test_drain_empty_vec() {
614+
let mut vec: Vec<i32> = vec![];
615+
let mut vec2: Vec<i32> = vec![];
616+
for i in vec.drain(..) {
617+
vec2.push(i);
618+
}
619+
assert!(vec.is_empty());
620+
assert!(vec2.is_empty());
621+
}
622+
612623
#[test]
613624
fn test_drain_items() {
614625
let mut vec = vec![1, 2, 3];

Diff for: src/librustdoc/clean/mod.rs

+13-11
Original file line numberDiff line numberDiff line change
@@ -2161,18 +2161,20 @@ fn clean_use_statement(
21612161
return Vec::new();
21622162
}
21632163

2164-
let (doc_meta_item, please_inline) = import.attrs.lists(sym::doc).get_word_attr(sym::inline);
2164+
let inline_attr = import.attrs.lists(sym::doc).get_word_attr(sym::inline);
21652165
let pub_underscore = import.vis.node.is_pub() && name == kw::Underscore;
21662166

2167-
if pub_underscore && please_inline {
2168-
rustc_errors::struct_span_err!(
2169-
cx.tcx.sess,
2170-
doc_meta_item.unwrap().span(),
2171-
E0780,
2172-
"anonymous imports cannot be inlined"
2173-
)
2174-
.span_label(import.span, "anonymous import")
2175-
.emit();
2167+
if pub_underscore {
2168+
if let Some(ref inline) = inline_attr {
2169+
rustc_errors::struct_span_err!(
2170+
cx.tcx.sess,
2171+
inline.span(),
2172+
E0780,
2173+
"anonymous imports cannot be inlined"
2174+
)
2175+
.span_label(import.span, "anonymous import")
2176+
.emit();
2177+
}
21762178
}
21772179

21782180
// We consider inlining the documentation of `pub use` statements, but we
@@ -2205,7 +2207,7 @@ fn clean_use_statement(
22052207
}
22062208
Import::new_glob(resolve_use_source(cx, path), true)
22072209
} else {
2208-
if !please_inline {
2210+
if inline_attr.is_none() {
22092211
if let Res::Def(DefKind::Mod, did) = path.res {
22102212
if !did.is_local() && did.index == CRATE_DEF_INDEX {
22112213
// if we're `pub use`ing an extern crate root, don't inline it unless we

Diff for: src/librustdoc/clean/types.rs

+3-6
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,7 @@ impl AttributesExt for [ast::Attribute] {
438438
crate trait NestedAttributesExt {
439439
/// Returns `true` if the attribute list contains a specific `Word`
440440
fn has_word(self, word: Symbol) -> bool;
441-
fn get_word_attr(self, word: Symbol) -> (Option<ast::NestedMetaItem>, bool);
441+
fn get_word_attr(self, word: Symbol) -> Option<ast::NestedMetaItem>;
442442
}
443443

444444
impl<I: Iterator<Item = ast::NestedMetaItem> + IntoIterator<Item = ast::NestedMetaItem>>
@@ -448,11 +448,8 @@ impl<I: Iterator<Item = ast::NestedMetaItem> + IntoIterator<Item = ast::NestedMe
448448
self.into_iter().any(|attr| attr.is_word() && attr.has_name(word))
449449
}
450450

451-
fn get_word_attr(mut self, word: Symbol) -> (Option<ast::NestedMetaItem>, bool) {
452-
match self.find(|attr| attr.is_word() && attr.has_name(word)) {
453-
Some(a) => (Some(a), true),
454-
None => (None, false),
455-
}
451+
fn get_word_attr(mut self, word: Symbol) -> Option<ast::NestedMetaItem> {
452+
self.find(|attr| attr.is_word() && attr.has_name(word))
456453
}
457454
}
458455

Diff for: src/test/rustdoc/ensure-src-link.rs

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#![crate_name = "foo"]
2+
3+
// This test ensures that the [src] link is present on traits items.
4+
5+
// @has foo/trait.Iterator.html '//h3[@id="method.zip"]/a[@class="srclink"]' "[src]"
6+
pub use std::iter::Iterator;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
error[E0311]: the parameter type `T` may not live long enough
2+
--> $DIR/missing-lifetimes-in-signature-2.rs:20:5
3+
|
4+
LL | / foo.bar(move |_| {
5+
LL | |
6+
LL | | t.test();
7+
LL | | });
8+
| |______^
9+
|
10+
note: the parameter type `T` must be valid for the anonymous lifetime #2 defined on the function body at 19:1...
11+
--> $DIR/missing-lifetimes-in-signature-2.rs:19:1
12+
|
13+
LL | fn func<T: Test>(foo: &Foo, t: T) {
14+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
15+
16+
error: aborting due to previous error
17+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Regression test for #81650
2+
3+
struct Foo<'a> {
4+
x: &'a mut &'a i32,
5+
}
6+
7+
impl<'a> Foo<'a> {
8+
fn bar<F, T>(&self, f: F)
9+
where
10+
F: FnOnce(&Foo<'a>) -> T,
11+
F: 'a,
12+
{}
13+
}
14+
15+
trait Test {
16+
fn test(&self);
17+
}
18+
19+
fn func<T: Test>(foo: &Foo, t: T) {
20+
foo.bar(move |_| {
21+
//~^ ERROR the parameter type `T` may not live long enough
22+
t.test();
23+
});
24+
}
25+
26+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
error[E0311]: the parameter type `T` may not live long enough
2+
--> $DIR/missing-lifetimes-in-signature-2.rs:20:9
3+
|
4+
LL | fn func<T: Test>(foo: &Foo, t: T) {
5+
| -- help: consider adding an explicit lifetime bound...: `T: 'a +`
6+
LL | foo.bar(move |_| {
7+
| ^^^
8+
|
9+
note: the parameter type `T` must be valid for the anonymous lifetime #2 defined on the function body at 19:1...
10+
--> $DIR/missing-lifetimes-in-signature-2.rs:19:1
11+
|
12+
LL | fn func<T: Test>(foo: &Foo, t: T) {
13+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
14+
note: ...so that the type `[closure@$DIR/missing-lifetimes-in-signature-2.rs:20:13: 23:6]` will meet its required lifetime bounds
15+
--> $DIR/missing-lifetimes-in-signature-2.rs:20:9
16+
|
17+
LL | foo.bar(move |_| {
18+
| ^^^
19+
20+
error: aborting due to previous error
21+
File renamed without changes.

Diff for: src/test/ui/traits/trait-alias-ambiguous.stderr renamed to src/test/ui/traits/alias/ambiguous.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
error[E0034]: multiple applicable items in scope
2-
--> $DIR/trait-alias-ambiguous.rs:21:7
2+
--> $DIR/ambiguous.rs:21:7
33
|
44
LL | t.foo();
55
| ^^^ multiple `foo` found
66
|
77
note: candidate #1 is defined in an impl of the trait `A` for the type `u8`
8-
--> $DIR/trait-alias-ambiguous.rs:8:9
8+
--> $DIR/ambiguous.rs:8:9
99
|
1010
LL | fn foo(&self) {}
1111
| ^^^^^^^^^^^^^
1212
note: candidate #2 is defined in an impl of the trait `B` for the type `u8`
13-
--> $DIR/trait-alias-ambiguous.rs:11:9
13+
--> $DIR/ambiguous.rs:11:9
1414
|
1515
LL | fn foo(&self) {}
1616
| ^^^^^^^^^^^^^
File renamed without changes.

0 commit comments

Comments
 (0)