Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 8 pull requests #82053

Merged
merged 18 commits into from
Feb 13, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
0488afd
Fix doc test for Vec::retain(), now passes clippy::eval_order_dependence
schteve Feb 5, 2021
0d96a79
Organize trait test files
vandenheuvel Feb 8, 2021
788e4bb
Fix suggestion to introduce explicit lifetime
0yoyoyo Feb 11, 2021
fcce998
Add nll test
0yoyoyo Feb 12, 2021
28347eb
Drop an unnecessary intermediate variable
LingMan Feb 12, 2021
715c19e
Refactor `get_word_attr` to return only `Option`
magurotuna Feb 12, 2021
681ccca
Rename to `inline_attr` and use if-let to extract `NestedMetaItem`
magurotuna Feb 12, 2021
95c984a
Add test to prevent src link regression
GuillaumeGomez Feb 12, 2021
7fafa4d
Add docs for shared_from_slice From impls
notriddle Feb 12, 2021
fa9af6a
Added tests to drain an empty vec
hbina Feb 13, 2021
4cb3810
Rollup merge of #81811 - schteve:fix_vec_retain_doc_test, r=m-ou-se
JohnTitor Feb 13, 2021
a390206
Rollup merge of #81900 - vandenheuvel:organize_trait_tests, r=Mark-Si…
JohnTitor Feb 13, 2021
14b217c
Rollup merge of #81995 - 0yoyoyo:fix-issue-81650-explicit-lifetime-er…
JohnTitor Feb 13, 2021
f6677b0
Rollup merge of #82031 - LingMan:unneeded_var, r=varkor
JohnTitor Feb 13, 2021
4c8e38a
Rollup merge of #82033 - magurotuna:issue82016, r=jyn514
JohnTitor Feb 13, 2021
3560ff3
Rollup merge of #82040 - GuillaumeGomez:ensure-src-link, r=CraftSpider
JohnTitor Feb 13, 2021
2673026
Rollup merge of #82041 - notriddle:shared-from-slice-docs, r=m-ou-se
JohnTitor Feb 13, 2021
0ca5fd7
Rollup merge of #82050 - hbina:fix/added-test-to-drain-empty-vec, r=d…
JohnTitor Feb 13, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion compiler/rustc_infer/src/infer/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2248,13 +2248,18 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
"...",
);
if let Some(infer::RelateParamBound(_, t)) = origin {
let return_impl_trait = self
.in_progress_typeck_results
.map(|typeck_results| typeck_results.borrow().hir_owner)
.and_then(|owner| self.tcx.return_type_impl_trait(owner))
.is_some();
let t = self.resolve_vars_if_possible(t);
match t.kind() {
// We've got:
// fn get_later<G, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
// suggest:
// fn get_later<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a
ty::Closure(_, _substs) | ty::Opaque(_, _substs) => {
ty::Closure(_, _substs) | ty::Opaque(_, _substs) if return_impl_trait => {
new_binding_suggestion(&mut err, type_param_span, bound_kind);
}
_ => {
Expand Down
4 changes: 1 addition & 3 deletions compiler/rustc_typeck/src/check/upvar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -260,8 +260,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// local crate or were inlined into it along with some function.
// This may change if abstract return types of some sort are
// implemented.
let tcx = self.tcx;

self.typeck_results
.borrow()
.closure_min_captures_flattened(closure_id)
Expand All @@ -276,7 +274,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {

match capture {
ty::UpvarCapture::ByValue(_) => upvar_ty,
ty::UpvarCapture::ByRef(borrow) => tcx.mk_ref(
ty::UpvarCapture::ByRef(borrow) => self.tcx.mk_ref(
borrow.region,
ty::TypeAndMut { ty: upvar_ty, mutbl: borrow.kind.to_mutbl_lossy() },
),
Expand Down
49 changes: 49 additions & 0 deletions library/alloc/src/rc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1652,6 +1652,16 @@ impl<T> From<T> for Rc<T> {

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

#[stable(feature = "shared_from_slice", since = "1.21.0")]
impl From<&str> for Rc<str> {
/// Allocate a reference-counted string slice and copy `v` into it.
///
/// # Example
///
/// ```
/// # use std::rc::Rc;
/// let shared: Rc<str> = Rc::from("statue");
/// assert_eq!("statue", &shared[..]);
/// ```
#[inline]
fn from(v: &str) -> Rc<str> {
let rc = Rc::<[u8]>::from(v.as_bytes());
Expand All @@ -1669,6 +1688,16 @@ impl From<&str> for Rc<str> {

#[stable(feature = "shared_from_slice", since = "1.21.0")]
impl From<String> for Rc<str> {
/// Allocate a reference-counted string slice and copy `v` into it.
///
/// # Example
///
/// ```
/// # use std::rc::Rc;
/// let original: String = "statue".to_owned();
/// let shared: Rc<str> = Rc::from(original);
/// assert_eq!("statue", &shared[..]);
/// ```
#[inline]
fn from(v: String) -> Rc<str> {
Rc::from(&v[..])
Expand All @@ -1677,6 +1706,16 @@ impl From<String> for Rc<str> {

#[stable(feature = "shared_from_slice", since = "1.21.0")]
impl<T: ?Sized> From<Box<T>> for Rc<T> {
/// Move a boxed object to a new, reference counted, allocation.
///
/// # Example
///
/// ```
/// # use std::rc::Rc;
/// let original: Box<i32> = Box::new(1);
/// let shared: Rc<i32> = Rc::from(original);
/// assert_eq!(1, *shared);
/// ```
#[inline]
fn from(v: Box<T>) -> Rc<T> {
Rc::from_box(v)
Expand All @@ -1685,6 +1724,16 @@ impl<T: ?Sized> From<Box<T>> for Rc<T> {

#[stable(feature = "shared_from_slice", since = "1.21.0")]
impl<T> From<Vec<T>> for Rc<[T]> {
/// Allocate a reference-counted slice and move `v`'s items into it.
///
/// # Example
///
/// ```
/// # use std::rc::Rc;
/// let original: Box<Vec<i32>> = Box::new(vec![1, 2, 3]);
/// let shared: Rc<Vec<i32>> = Rc::from(original);
/// assert_eq!(vec![1, 2, 3], *shared);
/// ```
#[inline]
fn from(mut v: Vec<T>) -> Rc<[T]> {
unsafe {
Expand Down
49 changes: 49 additions & 0 deletions library/alloc/src/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2285,6 +2285,16 @@ impl<T> From<T> for Arc<T> {

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

#[stable(feature = "shared_from_slice", since = "1.21.0")]
impl From<&str> for Arc<str> {
/// Allocate a reference-counted `str` and copy `v` into it.
///
/// # Example
///
/// ```
/// # use std::sync::Arc;
/// let shared: Arc<str> = Arc::from("eggplant");
/// assert_eq!("eggplant", &shared[..]);
/// ```
#[inline]
fn from(v: &str) -> Arc<str> {
let arc = Arc::<[u8]>::from(v.as_bytes());
Expand All @@ -2302,6 +2321,16 @@ impl From<&str> for Arc<str> {

#[stable(feature = "shared_from_slice", since = "1.21.0")]
impl From<String> for Arc<str> {
/// Allocate a reference-counted `str` and copy `v` into it.
///
/// # Example
///
/// ```
/// # use std::sync::Arc;
/// let unique: String = "eggplant".to_owned();
/// let shared: Arc<str> = Arc::from(unique);
/// assert_eq!("eggplant", &shared[..]);
/// ```
#[inline]
fn from(v: String) -> Arc<str> {
Arc::from(&v[..])
Expand All @@ -2310,6 +2339,16 @@ impl From<String> for Arc<str> {

#[stable(feature = "shared_from_slice", since = "1.21.0")]
impl<T: ?Sized> From<Box<T>> for Arc<T> {
/// Move a boxed object to a new, reference-counted allocation.
///
/// # Example
///
/// ```
/// # use std::sync::Arc;
/// let unique: Box<str> = Box::from("eggplant");
/// let shared: Arc<str> = Arc::from(unique);
/// assert_eq!("eggplant", &shared[..]);
/// ```
#[inline]
fn from(v: Box<T>) -> Arc<T> {
Arc::from_box(v)
Expand All @@ -2318,6 +2357,16 @@ impl<T: ?Sized> From<Box<T>> for Arc<T> {

#[stable(feature = "shared_from_slice", since = "1.21.0")]
impl<T> From<Vec<T>> for Arc<[T]> {
/// Allocate a reference-counted slice and move `v`'s items into it.
///
/// # Example
///
/// ```
/// # use std::sync::Arc;
/// let unique: Vec<i32> = vec![1, 2, 3];
/// let shared: Arc<[i32]> = Arc::from(unique);
/// assert_eq!(&[1, 2, 3], &shared[..]);
/// ```
#[inline]
fn from(mut v: Vec<T>) -> Arc<[T]> {
unsafe {
Expand Down
7 changes: 4 additions & 3 deletions library/alloc/src/vec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1385,13 +1385,14 @@ impl<T, A: Allocator> Vec<T, A> {
/// assert_eq!(vec, [2, 4]);
/// ```
///
/// The exact order may be useful for tracking external state, like an index.
/// Because the elements are visited exactly once in the original order,
/// external state may be used to decide which elements to keep.
///
/// ```
/// let mut vec = vec![1, 2, 3, 4, 5];
/// let keep = [false, true, true, false, true];
/// let mut i = 0;
/// vec.retain(|_| (keep[i], i += 1).0);
/// let mut iter = keep.iter();
/// vec.retain(|_| *iter.next().unwrap());
/// assert_eq!(vec, [2, 3, 5]);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
Expand Down
11 changes: 11 additions & 0 deletions library/alloc/tests/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -609,6 +609,17 @@ fn test_move_items_zero_sized() {
assert_eq!(vec2, [(), (), ()]);
}

#[test]
fn test_drain_empty_vec() {
let mut vec: Vec<i32> = vec![];
let mut vec2: Vec<i32> = vec![];
for i in vec.drain(..) {
vec2.push(i);
}
assert!(vec.is_empty());
assert!(vec2.is_empty());
}

#[test]
fn test_drain_items() {
let mut vec = vec![1, 2, 3];
Expand Down
24 changes: 13 additions & 11 deletions src/librustdoc/clean/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2161,18 +2161,20 @@ fn clean_use_statement(
return Vec::new();
}

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

if pub_underscore && please_inline {
rustc_errors::struct_span_err!(
cx.tcx.sess,
doc_meta_item.unwrap().span(),
E0780,
"anonymous imports cannot be inlined"
)
.span_label(import.span, "anonymous import")
.emit();
if pub_underscore {
if let Some(ref inline) = inline_attr {
rustc_errors::struct_span_err!(
cx.tcx.sess,
inline.span(),
E0780,
"anonymous imports cannot be inlined"
)
.span_label(import.span, "anonymous import")
.emit();
}
}

// We consider inlining the documentation of `pub use` statements, but we
Expand Down Expand Up @@ -2205,7 +2207,7 @@ fn clean_use_statement(
}
Import::new_glob(resolve_use_source(cx, path), true)
} else {
if !please_inline {
if inline_attr.is_none() {
if let Res::Def(DefKind::Mod, did) = path.res {
if !did.is_local() && did.index == CRATE_DEF_INDEX {
// if we're `pub use`ing an extern crate root, don't inline it unless we
Expand Down
9 changes: 3 additions & 6 deletions src/librustdoc/clean/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,7 @@ impl AttributesExt for [ast::Attribute] {
crate trait NestedAttributesExt {
/// Returns `true` if the attribute list contains a specific `Word`
fn has_word(self, word: Symbol) -> bool;
fn get_word_attr(self, word: Symbol) -> (Option<ast::NestedMetaItem>, bool);
fn get_word_attr(self, word: Symbol) -> Option<ast::NestedMetaItem>;
}

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

fn get_word_attr(mut self, word: Symbol) -> (Option<ast::NestedMetaItem>, bool) {
match self.find(|attr| attr.is_word() && attr.has_name(word)) {
Some(a) => (Some(a), true),
None => (None, false),
}
fn get_word_attr(mut self, word: Symbol) -> Option<ast::NestedMetaItem> {
self.find(|attr| attr.is_word() && attr.has_name(word))
}
}

Expand Down
6 changes: 6 additions & 0 deletions src/test/rustdoc/ensure-src-link.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#![crate_name = "foo"]

// This test ensures that the [src] link is present on traits items.

// @has foo/trait.Iterator.html '//h3[@id="method.zip"]/a[@class="srclink"]' "[src]"
pub use std::iter::Iterator;
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
error[E0311]: the parameter type `T` may not live long enough
--> $DIR/missing-lifetimes-in-signature-2.rs:20:5
|
LL | / foo.bar(move |_| {
LL | |
LL | | t.test();
LL | | });
| |______^
|
note: the parameter type `T` must be valid for the anonymous lifetime #2 defined on the function body at 19:1...
--> $DIR/missing-lifetimes-in-signature-2.rs:19:1
|
LL | fn func<T: Test>(foo: &Foo, t: T) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to previous error

Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Regression test for #81650

struct Foo<'a> {
x: &'a mut &'a i32,
}

impl<'a> Foo<'a> {
fn bar<F, T>(&self, f: F)
where
F: FnOnce(&Foo<'a>) -> T,
F: 'a,
{}
}

trait Test {
fn test(&self);
}

fn func<T: Test>(foo: &Foo, t: T) {
foo.bar(move |_| {
//~^ ERROR the parameter type `T` may not live long enough
t.test();
});
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
error[E0311]: the parameter type `T` may not live long enough
--> $DIR/missing-lifetimes-in-signature-2.rs:20:9
|
LL | fn func<T: Test>(foo: &Foo, t: T) {
| -- help: consider adding an explicit lifetime bound...: `T: 'a +`
LL | foo.bar(move |_| {
| ^^^
|
note: the parameter type `T` must be valid for the anonymous lifetime #2 defined on the function body at 19:1...
--> $DIR/missing-lifetimes-in-signature-2.rs:19:1
|
LL | fn func<T: Test>(foo: &Foo, t: T) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...so that the type `[closure@$DIR/missing-lifetimes-in-signature-2.rs:20:13: 23:6]` will meet its required lifetime bounds
--> $DIR/missing-lifetimes-in-signature-2.rs:20:9
|
LL | foo.bar(move |_| {
| ^^^

error: aborting due to previous error

Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
error[E0034]: multiple applicable items in scope
--> $DIR/trait-alias-ambiguous.rs:21:7
--> $DIR/ambiguous.rs:21:7
|
LL | t.foo();
| ^^^ multiple `foo` found
|
note: candidate #1 is defined in an impl of the trait `A` for the type `u8`
--> $DIR/trait-alias-ambiguous.rs:8:9
--> $DIR/ambiguous.rs:8:9
|
LL | fn foo(&self) {}
| ^^^^^^^^^^^^^
note: candidate #2 is defined in an impl of the trait `B` for the type `u8`
--> $DIR/trait-alias-ambiguous.rs:11:9
--> $DIR/ambiguous.rs:11:9
|
LL | fn foo(&self) {}
| ^^^^^^^^^^^^^
Expand Down
Loading