Skip to content

Commit f6419b1

Browse files
committed
Auto merge of #49620 - kennytm:rollup, r=kennytm
Rollup of 14 pull requests Successful merges: - #49179 (Handle future deprecation annotations ) - #49512 (Add support for variant and types fields for intra links) - #49516 (Add missing anchor for union type fields) - #49532 (Add test for rustdoc ignore test) - #49533 (Add #[must_use] to a few standard library methods) - #49570 (avoid IdxSets containing garbage above the universe length) - #49594 (Add some performance guidance to std::fs and std::io docs) - #49599 (Fix typo) - #49603 (Fix url for intra link provided method) - #49609 (run-pass/attr-stmt-expr: expand test cases) - #49612 (Fix "since" version for getpid feature.) - #49618 (Fix build error when compiling libcore for 16bit targets) - #49619 (tweak core::fmt docs) - #49623 (update mdbook) Failed merges:
2 parents 637ac17 + fa5d2e2 commit f6419b1

File tree

25 files changed

+541
-30
lines changed

25 files changed

+541
-30
lines changed

src/Cargo.lock

+211
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/liballoc/borrow.rs

+1
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ pub trait ToOwned {
5959
/// let vv: Vec<i32> = v.to_owned();
6060
/// ```
6161
#[stable(feature = "rust1", since = "1.0.0")]
62+
#[must_use = "cloning is often expensive and is not expected to have side effects"]
6263
fn to_owned(&self) -> Self::Owned;
6364

6465
/// Uses borrowed data to replace owned data, usually by cloning.

src/libcore/clone.rs

+1
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ pub trait Clone : Sized {
105105
/// assert_eq!("Hello", hello.clone());
106106
/// ```
107107
#[stable(feature = "rust1", since = "1.0.0")]
108+
#[must_use = "cloning is often expensive and is not expected to have side effects"]
108109
fn clone(&self) -> Self;
109110

110111
/// Performs copy-assignment from `source`.

src/libcore/fmt/mod.rs

+5-6
Original file line numberDiff line numberDiff line change
@@ -401,19 +401,18 @@ impl<'a> Arguments<'a> {
401401
/// safely be done, so no constructors are given and the fields are private
402402
/// to prevent modification.
403403
///
404-
/// The [`format_args!`] macro will safely create an instance of this structure
405-
/// and pass it to a function or closure, passed as the first argument. The
406-
/// macro validates the format string at compile-time so usage of the [`write`]
407-
/// and [`format`] functions can be safely performed.
404+
/// The [`format_args!`] macro will safely create an instance of this structure.
405+
/// The macro validates the format string at compile-time so usage of the
406+
/// [`write`] and [`format`] functions can be safely performed.
408407
///
409408
/// You can use the `Arguments<'a>` that [`format_args!`] returns in `Debug`
410409
/// and `Display` contexts as seen below. The example also shows that `Debug`
411410
/// and `Display` format to the same thing: the interpolated format string
412411
/// in `format_args!`.
413412
///
414413
/// ```rust
415-
/// let display = format!("{:?}", format_args!("{} foo {:?}", 1, 2));
416-
/// let debug = format!("{}", format_args!("{} foo {:?}", 1, 2));
414+
/// let debug = format!("{:?}", format_args!("{} foo {:?}", 1, 2));
415+
/// let display = format!("{}", format_args!("{} foo {:?}", 1, 2));
417416
/// assert_eq!("1 foo 2", display);
418417
/// assert_eq!(display, debug);
419418
/// ```

src/libcore/iter/iterator.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1368,6 +1368,7 @@ pub trait Iterator {
13681368
/// [`Result`]: ../../std/result/enum.Result.html
13691369
#[inline]
13701370
#[stable(feature = "rust1", since = "1.0.0")]
1371+
#[must_use = "if you really need to exhaust the iterator, consider `.for_each(drop)` instead"]
13711372
fn collect<B: FromIterator<Self::Item>>(self) -> B where Self: Sized {
13721373
FromIterator::from_iter(self)
13731374
}

src/libcore/iter/range.rs

+1
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,7 @@ macro_rules! try_from_unbounded {
488488
}
489489

490490
// unsigned to signed (only positive bound)
491+
#[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))]
491492
macro_rules! try_from_upper_bounded {
492493
($($target:ty),*) => {$(
493494
impl PrivateTryFromUsize for $target {

src/librustc/middle/stability.rs

+36-2
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,30 @@ pub fn check_unstable_api_usage<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
470470
tcx.hir.krate().visit_all_item_likes(&mut checker.as_deep_visitor());
471471
}
472472

473+
/// Check whether an item marked with `deprecated(since="X")` is currently
474+
/// deprecated (i.e. whether X is not greater than the current rustc version).
475+
pub fn deprecation_in_effect(since: &str) -> bool {
476+
fn parse_version(ver: &str) -> Vec<u32> {
477+
// We ignore non-integer components of the version (e.g. "nightly").
478+
ver.split(|c| c == '.' || c == '-').flat_map(|s| s.parse()).collect()
479+
}
480+
481+
if let Some(rustc) = option_env!("CFG_RELEASE") {
482+
let since: Vec<u32> = parse_version(since);
483+
let rustc: Vec<u32> = parse_version(rustc);
484+
// We simply treat invalid `since` attributes as relating to a previous
485+
// Rust version, thus always displaying the warning.
486+
if since.len() != 3 {
487+
return true;
488+
}
489+
since <= rustc
490+
} else {
491+
// By default, a deprecation warning applies to
492+
// the current version of the compiler.
493+
true
494+
}
495+
}
496+
473497
struct Checker<'a, 'tcx: 'a> {
474498
tcx: TyCtxt<'a, 'tcx, 'tcx>,
475499
}
@@ -559,9 +583,19 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
559583
// Deprecated attributes apply in-crate and cross-crate.
560584
if let Some(id) = id {
561585
if let Some(depr_entry) = self.lookup_deprecation_entry(def_id) {
586+
// If the deprecation is scheduled for a future Rust
587+
// version, then we should display no warning message.
588+
let deprecated_in_future_version = if let Some(sym) = depr_entry.attr.since {
589+
let since = sym.as_str();
590+
!deprecation_in_effect(&since)
591+
} else {
592+
false
593+
};
594+
562595
let parent_def_id = self.hir.local_def_id(self.hir.get_parent(id));
563-
let skip = self.lookup_deprecation_entry(parent_def_id)
564-
.map_or(false, |parent_depr| parent_depr.same_origin(&depr_entry));
596+
let skip = deprecated_in_future_version ||
597+
self.lookup_deprecation_entry(parent_def_id)
598+
.map_or(false, |parent_depr| parent_depr.same_origin(&depr_entry));
565599
if !skip {
566600
lint_deprecated(def_id, id, depr_entry.attr.note);
567601
}

src/librustc_data_structures/indexed_set.rs

+73-1
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,9 @@ impl<T: Idx> IdxSetBuf<T> {
121121

122122
/// Creates set holding every element whose index falls in range 0..universe_size.
123123
pub fn new_filled(universe_size: usize) -> Self {
124-
Self::new(!0, universe_size)
124+
let mut result = Self::new(!0, universe_size);
125+
result.trim_to(universe_size);
126+
result
125127
}
126128

127129
/// Creates set holding no elements.
@@ -168,6 +170,36 @@ impl<T: Idx> IdxSet<T> {
168170
}
169171
}
170172

173+
/// Sets all elements up to `universe_size`
174+
pub fn set_up_to(&mut self, universe_size: usize) {
175+
for b in &mut self.bits {
176+
*b = !0;
177+
}
178+
self.trim_to(universe_size);
179+
}
180+
181+
/// Clear all elements above `universe_size`.
182+
fn trim_to(&mut self, universe_size: usize) {
183+
let word_bits = mem::size_of::<Word>() * 8;
184+
185+
// `trim_block` is the first block where some bits have
186+
// to be cleared.
187+
let trim_block = universe_size / word_bits;
188+
189+
// all the blocks above it have to be completely cleared.
190+
if trim_block < self.bits.len() {
191+
for b in &mut self.bits[trim_block+1..] {
192+
*b = 0;
193+
}
194+
195+
// at that block, the `universe_size % word_bits` lsbs
196+
// should remain.
197+
let remaining_bits = universe_size % word_bits;
198+
let mask = (1<<remaining_bits)-1;
199+
self.bits[trim_block] &= mask;
200+
}
201+
}
202+
171203
/// Removes `elem` from the set `self`; returns true iff this changed `self`.
172204
pub fn remove(&mut self, elem: &T) -> bool {
173205
self.bits.clear_bit(elem.index())
@@ -252,3 +284,43 @@ impl<'a, T: Idx> Iterator for Iter<'a, T> {
252284
}
253285
}
254286
}
287+
288+
#[test]
289+
fn test_trim_to() {
290+
use std::cmp;
291+
292+
for i in 0..256 {
293+
let mut idx_buf: IdxSetBuf<usize> = IdxSetBuf::new_filled(128);
294+
idx_buf.trim_to(i);
295+
296+
let elems: Vec<usize> = idx_buf.iter().collect();
297+
let expected: Vec<usize> = (0..cmp::min(i, 128)).collect();
298+
assert_eq!(elems, expected);
299+
}
300+
}
301+
302+
#[test]
303+
fn test_set_up_to() {
304+
for i in 0..128 {
305+
for mut idx_buf in
306+
vec![IdxSetBuf::new_empty(128), IdxSetBuf::new_filled(128)]
307+
.into_iter()
308+
{
309+
idx_buf.set_up_to(i);
310+
311+
let elems: Vec<usize> = idx_buf.iter().collect();
312+
let expected: Vec<usize> = (0..i).collect();
313+
assert_eq!(elems, expected);
314+
}
315+
}
316+
}
317+
318+
#[test]
319+
fn test_new_filled() {
320+
for i in 0..128 {
321+
let mut idx_buf = IdxSetBuf::new_filled(i);
322+
let elems: Vec<usize> = idx_buf.iter().collect();
323+
let expected: Vec<usize> = (0..i).collect();
324+
assert_eq!(elems, expected);
325+
}
326+
}

src/librustc_mir/build/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ newtype_index!(ScopeId);
317317
/// macro (and methods below) makes working with `BlockAnd` much more
318318
/// convenient.
319319
320-
#[must_use] // if you don't use one of these results, you're leaving a dangling edge
320+
#[must_use = "if you don't use one of these results, you're leaving a dangling edge"]
321321
struct BlockAnd<T>(BasicBlock, T);
322322

323323
trait BlockAndExtension {

src/librustc_mir/dataflow/impls/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,7 @@ impl<'a, 'gcx, 'tcx> BitDenotation for MaybeUninitializedPlaces<'a, 'gcx, 'tcx>
389389
// sets on_entry bits for Arg places
390390
fn start_block_effect(&self, entry_set: &mut IdxSet<MovePathIndex>) {
391391
// set all bits to 1 (uninit) before gathering counterevidence
392-
for e in entry_set.words_mut() { *e = !0; }
392+
entry_set.set_up_to(self.bits_per_block());
393393

394394
drop_flag_effects_for_function_entry(
395395
self.tcx, self.mir, self.mdpe,
@@ -443,7 +443,7 @@ impl<'a, 'gcx, 'tcx> BitDenotation for DefinitelyInitializedPlaces<'a, 'gcx, 'tc
443443

444444
// sets on_entry bits for Arg places
445445
fn start_block_effect(&self, entry_set: &mut IdxSet<MovePathIndex>) {
446-
for e in entry_set.words_mut() { *e = 0; }
446+
entry_set.clear();
447447

448448
drop_flag_effects_for_function_entry(
449449
self.tcx, self.mir, self.mdpe,

src/librustdoc/clean/mod.rs

+29-4
Original file line numberDiff line numberDiff line change
@@ -1074,8 +1074,7 @@ fn resolve(cx: &DocContext, path_str: &str, is_val: bool) -> Result<(Def, Option
10741074
let ty = cx.resolver.borrow_mut()
10751075
.with_scope(*id,
10761076
|resolver| {
1077-
resolver.resolve_str_path_error(DUMMY_SP,
1078-
&path, false)
1077+
resolver.resolve_str_path_error(DUMMY_SP, &path, false)
10791078
})?;
10801079
match ty.def {
10811080
Def::Struct(did) | Def::Union(did) | Def::Enum(did) | Def::TyAlias(did) => {
@@ -1090,7 +1089,27 @@ fn resolve(cx: &DocContext, path_str: &str, is_val: bool) -> Result<(Def, Option
10901089
};
10911090
Ok((ty.def, Some(format!("{}.{}", out, item_name))))
10921091
} else {
1093-
Err(())
1092+
let is_enum = match ty.def {
1093+
Def::Enum(_) => true,
1094+
_ => false,
1095+
};
1096+
let elem = if is_enum {
1097+
cx.tcx.adt_def(did).all_fields().find(|item| item.name == item_name)
1098+
} else {
1099+
cx.tcx.adt_def(did)
1100+
.non_enum_variant()
1101+
.fields
1102+
.iter()
1103+
.find(|item| item.name == item_name)
1104+
};
1105+
if let Some(item) = elem {
1106+
Ok((ty.def,
1107+
Some(format!("{}.{}",
1108+
if is_enum { "variant" } else { "structfield" },
1109+
item.name))))
1110+
} else {
1111+
Err(())
1112+
}
10941113
}
10951114
}
10961115
Def::Trait(did) => {
@@ -1101,7 +1120,13 @@ fn resolve(cx: &DocContext, path_str: &str, is_val: bool) -> Result<(Def, Option
11011120
let kind = match item.kind {
11021121
ty::AssociatedKind::Const if is_val => "associatedconstant",
11031122
ty::AssociatedKind::Type if !is_val => "associatedtype",
1104-
ty::AssociatedKind::Method if is_val => "tymethod",
1123+
ty::AssociatedKind::Method if is_val => {
1124+
if item.defaultness.has_value() {
1125+
"method"
1126+
} else {
1127+
"tymethod"
1128+
}
1129+
}
11051130
_ => return Err(())
11061131
};
11071132

src/librustdoc/html/render.rs

+25-6
Original file line numberDiff line numberDiff line change
@@ -2113,9 +2113,15 @@ fn short_stability(item: &clean::Item, cx: &Context, show_reason: bool) -> Vec<S
21132113
} else {
21142114
String::new()
21152115
};
2116-
let text = format!("Deprecated{}{}",
2117-
since,
2118-
MarkdownHtml(&deprecated_reason));
2116+
let text = if stability::deprecation_in_effect(&stab.deprecated_since) {
2117+
format!("Deprecated{}{}",
2118+
since,
2119+
MarkdownHtml(&deprecated_reason))
2120+
} else {
2121+
format!("Deprecating in {}{}",
2122+
Escape(&stab.deprecated_since),
2123+
MarkdownHtml(&deprecated_reason))
2124+
};
21192125
stability.push(format!("<div class='stab deprecated'>{}</div>", text))
21202126
};
21212127

@@ -2165,7 +2171,15 @@ fn short_stability(item: &clean::Item, cx: &Context, show_reason: bool) -> Vec<S
21652171
String::new()
21662172
};
21672173

2168-
let text = format!("Deprecated{}{}", since, MarkdownHtml(&note));
2174+
let text = if stability::deprecation_in_effect(&depr.since) {
2175+
format!("Deprecated{}{}",
2176+
since,
2177+
MarkdownHtml(&note))
2178+
} else {
2179+
format!("Deprecating in {}{}",
2180+
Escape(&depr.since),
2181+
MarkdownHtml(&note))
2182+
};
21692183
stability.push(format!("<div class='stab deprecated'>{}</div>", text))
21702184
}
21712185

@@ -2801,10 +2815,15 @@ fn item_union(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
28012815
write!(w, "<h2 id='fields' class='fields small-section-header'>
28022816
Fields<a href='#fields' class='anchor'></a></h2>")?;
28032817
for (field, ty) in fields {
2804-
write!(w, "<span id='{shortty}.{name}' class=\"{shortty}\"><code>{name}: {ty}</code>
2818+
let name = field.name.as_ref().expect("union field name");
2819+
let id = format!("{}.{}", ItemType::StructField, name);
2820+
write!(w, "<span id=\"{id}\" class=\"{shortty} small-section-header\">\
2821+
<a href=\"#{id}\" class=\"anchor field\"></a>\
2822+
<span class='invisible'><code>{name}: {ty}</code></span>\
28052823
</span>",
2824+
id = id,
2825+
name = name,
28062826
shortty = ItemType::StructField,
2807-
name = field.name.as_ref().unwrap(),
28082827
ty = ty)?;
28092828
if let Some(stability_class) = field.stability_class() {
28102829
write!(w, "<span class='stab {stab}'></span>",

src/libstd/fs.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,9 @@ fn initial_buffer_size(file: &File) -> usize {
231231
/// Read the entire contents of a file into a bytes vector.
232232
///
233233
/// This is a convenience function for using [`File::open`] and [`read_to_end`]
234-
/// with fewer imports and without an intermediate variable.
234+
/// with fewer imports and without an intermediate variable. It pre-allocates a
235+
/// buffer based on the file size when available, so it is generally faster than
236+
/// reading into a vector created with `Vec::new()`.
235237
///
236238
/// [`File::open`]: struct.File.html#method.open
237239
/// [`read_to_end`]: ../io/trait.Read.html#method.read_to_end
@@ -270,7 +272,9 @@ pub fn read<P: AsRef<Path>>(path: P) -> io::Result<Vec<u8>> {
270272
/// Read the entire contents of a file into a string.
271273
///
272274
/// This is a convenience function for using [`File::open`] and [`read_to_string`]
273-
/// with fewer imports and without an intermediate variable.
275+
/// with fewer imports and without an intermediate variable. It pre-allocates a
276+
/// buffer based on the file size when available, so it is generally faster than
277+
/// reading into a string created with `String::new()`.
274278
///
275279
/// [`File::open`]: struct.File.html#method.open
276280
/// [`read_to_string`]: ../io/trait.Read.html#method.read_to_string

src/libstd/io/buffered.rs

+13-1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,12 @@ use memchr;
2525
/// results in a system call. A `BufReader` performs large, infrequent reads on
2626
/// the underlying [`Read`] and maintains an in-memory buffer of the results.
2727
///
28+
/// `BufReader` can improve the speed of programs that make *small* and
29+
/// *repeated* read calls to the same file or network socket. It does not
30+
/// help when reading very large amounts at once, or reading just one or a few
31+
/// times. It also provides no advantage when reading from a source that is
32+
/// already in memory, like a `Vec<u8>`.
33+
///
2834
/// [`Read`]: ../../std/io/trait.Read.html
2935
/// [`TcpStream::read`]: ../../std/net/struct.TcpStream.html#method.read
3036
/// [`TcpStream`]: ../../std/net/struct.TcpStream.html
@@ -180,7 +186,7 @@ impl<R: Read> BufReader<R> {
180186
///
181187
/// # Examples
182188
///
183-
/// ```no_ru
189+
/// ```no_run
184190
/// # #![feature(bufreader_buffer)]
185191
/// use std::io::{BufReader, BufRead};
186192
/// use std::fs::File;
@@ -359,6 +365,12 @@ impl<R: Seek> Seek for BufReader<R> {
359365
/// `BufWriter` keeps an in-memory buffer of data and writes it to an underlying
360366
/// writer in large, infrequent batches.
361367
///
368+
/// `BufWriter` can improve the speed of programs that make *small* and
369+
/// *repeated* write calls to the same file or network socket. It does not
370+
/// help when writing very large amounts at once, or writing just one or a few
371+
/// times. It also provides no advantage when writing to a destination that is
372+
/// in memory, like a `Vec<u8>`.
373+
///
362374
/// When the `BufWriter` is dropped, the contents of its buffer will be written
363375
/// out. However, any errors that happen in the process of flushing the buffer
364376
/// when the writer is dropped will be ignored. Code that wishes to handle such

0 commit comments

Comments
 (0)