Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 1ec980d

Browse files
committedSep 27, 2020
Auto merge of #77247 - jonas-schievink:rollup-r6ehh8h, r=jonas-schievink
Rollup of 10 pull requests Successful merges: - #76917 (Add missing code examples on HashMap types) - #77107 (Enable const propagation into operands at mir_opt_level=2) - #77129 (Update cargo) - #77167 (Fix FIXME in core::num test: Check sign of zero in min/max tests.) - #77184 (Rust vec bench import specific rand::RngCore) - #77208 (Late link args order) - #77209 (Fix documentation highlighting in ty::BorrowKind) - #77231 (Move helper function for `missing_const_for_fn` out of rustc to clippy) - #77235 (pretty-print-reparse hack: Rename some variables for clarity) - #77243 (Test more attributes in test issue-75930-derive-cfg.rs) Failed merges: r? `@ghost`
2 parents 623fb90 + b7c05a3 commit 1ec980d

File tree

16 files changed

+1852
-157
lines changed

16 files changed

+1852
-157
lines changed
 

‎compiler/rustc_codegen_ssa/src/back/link.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1333,9 +1333,6 @@ fn add_late_link_args(
13331333
crate_type: CrateType,
13341334
codegen_results: &CodegenResults,
13351335
) {
1336-
if let Some(args) = sess.target.target.options.late_link_args.get(&flavor) {
1337-
cmd.args(args);
1338-
}
13391336
let any_dynamic_crate = crate_type == CrateType::Dylib
13401337
|| codegen_results.crate_info.dependency_formats.iter().any(|(ty, list)| {
13411338
*ty == crate_type && list.iter().any(|&linkage| linkage == Linkage::Dynamic)
@@ -1349,6 +1346,9 @@ fn add_late_link_args(
13491346
cmd.args(args);
13501347
}
13511348
}
1349+
if let Some(args) = sess.target.target.options.late_link_args.get(&flavor) {
1350+
cmd.args(args);
1351+
}
13521352
}
13531353

13541354
/// Add arbitrary "post-link" args defined by the target spec.

‎compiler/rustc_middle/src/ty/mod.rs

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -682,25 +682,31 @@ pub enum BorrowKind {
682682
/// implicit closure bindings. It is needed when the closure
683683
/// is borrowing or mutating a mutable referent, e.g.:
684684
///
685-
/// let x: &mut isize = ...;
686-
/// let y = || *x += 5;
685+
/// ```
686+
/// let x: &mut isize = ...;
687+
/// let y = || *x += 5;
688+
/// ```
687689
///
688690
/// If we were to try to translate this closure into a more explicit
689691
/// form, we'd encounter an error with the code as written:
690692
///
691-
/// struct Env { x: & &mut isize }
692-
/// let x: &mut isize = ...;
693-
/// let y = (&mut Env { &x }, fn_ptr); // Closure is pair of env and fn
694-
/// fn fn_ptr(env: &mut Env) { **env.x += 5; }
693+
/// ```
694+
/// struct Env { x: & &mut isize }
695+
/// let x: &mut isize = ...;
696+
/// let y = (&mut Env { &x }, fn_ptr); // Closure is pair of env and fn
697+
/// fn fn_ptr(env: &mut Env) { **env.x += 5; }
698+
/// ```
695699
///
696700
/// This is then illegal because you cannot mutate a `&mut` found
697701
/// in an aliasable location. To solve, you'd have to translate with
698702
/// an `&mut` borrow:
699703
///
700-
/// struct Env { x: & &mut isize }
701-
/// let x: &mut isize = ...;
702-
/// let y = (&mut Env { &mut x }, fn_ptr); // changed from &x to &mut x
703-
/// fn fn_ptr(env: &mut Env) { **env.x += 5; }
704+
/// ```
705+
/// struct Env { x: & &mut isize }
706+
/// let x: &mut isize = ...;
707+
/// let y = (&mut Env { &mut x }, fn_ptr); // changed from &x to &mut x
708+
/// fn fn_ptr(env: &mut Env) { **env.x += 5; }
709+
/// ```
704710
///
705711
/// Now the assignment to `**env.x` is legal, but creating a
706712
/// mutable pointer to `x` is not because `x` is not mutable. We

‎compiler/rustc_mir/src/transform/const_prop.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1046,9 +1046,9 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> {
10461046
fn visit_operand(&mut self, operand: &mut Operand<'tcx>, location: Location) {
10471047
self.super_operand(operand, location);
10481048

1049-
// Only const prop copies and moves on `mir_opt_level=3` as doing so
1050-
// currently increases compile time.
1051-
if self.tcx.sess.opts.debugging_opts.mir_opt_level >= 3 {
1049+
// Only const prop copies and moves on `mir_opt_level=2` as doing so
1050+
// currently slightly increases compile time in some cases.
1051+
if self.tcx.sess.opts.debugging_opts.mir_opt_level >= 2 {
10521052
self.propagate_operand(operand)
10531053
}
10541054
}
@@ -1246,8 +1246,8 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> {
12461246
| TerminatorKind::InlineAsm { .. } => {}
12471247
// Every argument in our function calls have already been propagated in `visit_operand`.
12481248
//
1249-
// NOTE: because LLVM codegen gives performance regressions with it, so this is gated
1250-
// on `mir_opt_level=3`.
1249+
// NOTE: because LLVM codegen gives slight performance regressions with it, so this is
1250+
// gated on `mir_opt_level=2`.
12511251
TerminatorKind::Call { .. } => {}
12521252
}
12531253

‎compiler/rustc_mir/src/transform/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ pub mod match_branches;
3636
pub mod no_landing_pads;
3737
pub mod nrvo;
3838
pub mod promote_consts;
39-
pub mod qualify_min_const_fn;
4039
pub mod remove_noop_landing_pads;
4140
pub mod remove_unneeded_drops;
4241
pub mod required_consts;

‎compiler/rustc_parse/src/lib.rs

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
#![feature(or_patterns)]
88

99
use rustc_ast as ast;
10-
use rustc_ast::token::{self, DelimToken, Nonterminal, Token, TokenKind};
10+
use rustc_ast::token::{self, Nonterminal, Token, TokenKind};
1111
use rustc_ast::tokenstream::{self, Spacing, TokenStream, TokenTree};
1212
use rustc_ast_pretty::pprust;
1313
use rustc_data_structures::sync::Lrc;
@@ -299,7 +299,7 @@ pub fn nt_to_tokenstream(nt: &Nonterminal, sess: &ParseSess, span: Span) -> Toke
299299
// FIXME(#43081): Avoid this pretty-print + reparse hack
300300
let source = pprust::nonterminal_to_string(nt);
301301
let filename = FileName::macro_expansion_source_code(&source);
302-
let tokens_for_real = parse_stream_from_source_str(filename, source, sess, Some(span));
302+
let reparsed_tokens = parse_stream_from_source_str(filename, source, sess, Some(span));
303303

304304
// During early phases of the compiler the AST could get modified
305305
// directly (e.g., attributes added or removed) and the internal cache
@@ -325,17 +325,17 @@ pub fn nt_to_tokenstream(nt: &Nonterminal, sess: &ParseSess, span: Span) -> Toke
325325
// modifications, including adding/removing typically non-semantic
326326
// tokens such as extra braces and commas, don't happen.
327327
if let Some(tokens) = tokens {
328-
if tokenstream_probably_equal_for_proc_macro(&tokens, &tokens_for_real, sess) {
328+
if tokenstream_probably_equal_for_proc_macro(&tokens, &reparsed_tokens, sess) {
329329
return tokens;
330330
}
331331
info!(
332332
"cached tokens found, but they're not \"probably equal\", \
333333
going with stringified version"
334334
);
335335
info!("cached tokens: {:?}", tokens);
336-
info!("reparsed tokens: {:?}", tokens_for_real);
336+
info!("reparsed tokens: {:?}", reparsed_tokens);
337337
}
338-
tokens_for_real
338+
reparsed_tokens
339339
}
340340

341341
// See comments in `Nonterminal::to_tokenstream` for why we care about
@@ -344,8 +344,8 @@ pub fn nt_to_tokenstream(nt: &Nonterminal, sess: &ParseSess, span: Span) -> Toke
344344
// This is otherwise the same as `eq_unspanned`, only recursing with a
345345
// different method.
346346
pub fn tokenstream_probably_equal_for_proc_macro(
347-
first: &TokenStream,
348-
other: &TokenStream,
347+
tokens: &TokenStream,
348+
reparsed_tokens: &TokenStream,
349349
sess: &ParseSess,
350350
) -> bool {
351351
// When checking for `probably_eq`, we ignore certain tokens that aren't
@@ -359,9 +359,6 @@ pub fn tokenstream_probably_equal_for_proc_macro(
359359
// The pretty printer tends to add trailing commas to
360360
// everything, and in particular, after struct fields.
361361
| token::Comma
362-
// The pretty printer emits `NoDelim` as whitespace.
363-
| token::OpenDelim(DelimToken::NoDelim)
364-
| token::CloseDelim(DelimToken::NoDelim)
365362
// The pretty printer collapses many semicolons into one.
366363
| token::Semi
367364
// We don't preserve leading `|` tokens in patterns, so
@@ -460,10 +457,11 @@ pub fn tokenstream_probably_equal_for_proc_macro(
460457

461458
// Break tokens after we expand any nonterminals, so that we break tokens
462459
// that are produced as a result of nonterminal expansion.
463-
let t1 = first.trees().filter(semantic_tree).flat_map(expand_nt).flat_map(break_tokens);
464-
let t2 = other.trees().filter(semantic_tree).flat_map(expand_nt).flat_map(break_tokens);
460+
let tokens = tokens.trees().filter(semantic_tree).flat_map(expand_nt).flat_map(break_tokens);
461+
let reparsed_tokens =
462+
reparsed_tokens.trees().filter(semantic_tree).flat_map(expand_nt).flat_map(break_tokens);
465463

466-
t1.eq_by(t2, |t1, t2| tokentree_probably_equal_for_proc_macro(&t1, &t2, sess))
464+
tokens.eq_by(reparsed_tokens, |t, rt| tokentree_probably_equal_for_proc_macro(&t, &rt, sess))
467465
}
468466

469467
// See comments in `Nonterminal::to_tokenstream` for why we care about
@@ -472,16 +470,20 @@ pub fn tokenstream_probably_equal_for_proc_macro(
472470
// This is otherwise the same as `eq_unspanned`, only recursing with a
473471
// different method.
474472
pub fn tokentree_probably_equal_for_proc_macro(
475-
first: &TokenTree,
476-
other: &TokenTree,
473+
token: &TokenTree,
474+
reparsed_token: &TokenTree,
477475
sess: &ParseSess,
478476
) -> bool {
479-
match (first, other) {
480-
(TokenTree::Token(token), TokenTree::Token(token2)) => {
481-
token_probably_equal_for_proc_macro(token, token2)
477+
match (token, reparsed_token) {
478+
(TokenTree::Token(token), TokenTree::Token(reparsed_token)) => {
479+
token_probably_equal_for_proc_macro(token, reparsed_token)
482480
}
483-
(TokenTree::Delimited(_, delim, tts), TokenTree::Delimited(_, delim2, tts2)) => {
484-
delim == delim2 && tokenstream_probably_equal_for_proc_macro(&tts, &tts2, sess)
481+
(
482+
TokenTree::Delimited(_, delim, tokens),
483+
TokenTree::Delimited(_, reparsed_delim, reparsed_tokens),
484+
) => {
485+
delim == reparsed_delim
486+
&& tokenstream_probably_equal_for_proc_macro(tokens, reparsed_tokens, sess)
485487
}
486488
_ => false,
487489
}

‎compiler/rustc_target/src/spec/windows_gnu_base.rs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ pub fn opts() -> TargetOptions {
2323
"-lmsvcrt".to_string(),
2424
"-lmingwex".to_string(),
2525
"-lmingw32".to_string(),
26+
"-lgcc".to_string(), // alas, mingw* libraries above depend on libgcc
2627
// mingw's msvcrt is a weird hybrid import library and static library.
2728
// And it seems that the linker fails to use import symbols from msvcrt
2829
// that are required from functions in msvcrt in certain cases. For example
@@ -41,8 +42,6 @@ pub fn opts() -> TargetOptions {
4142
// the shared libgcc_s-dw2-1.dll. This is required to support
4243
// unwinding across DLL boundaries.
4344
"-lgcc_s".to_string(),
44-
"-lgcc".to_string(),
45-
"-lkernel32".to_string(),
4645
];
4746
late_link_args_dynamic.insert(LinkerFlavor::Gcc, dynamic_unwind_libs.clone());
4847
late_link_args_dynamic.insert(LinkerFlavor::Lld(LldFlavor::Ld), dynamic_unwind_libs);
@@ -54,10 +53,6 @@ pub fn opts() -> TargetOptions {
5453
// boundaries when unwinding across FFI boundaries.
5554
"-lgcc_eh".to_string(),
5655
"-l:libpthread.a".to_string(),
57-
"-lgcc".to_string(),
58-
// libpthread depends on libmsvcrt, so we need to link it *again*.
59-
"-lmsvcrt".to_string(),
60-
"-lkernel32".to_string(),
6156
];
6257
late_link_args_static.insert(LinkerFlavor::Gcc, static_unwind_libs.clone());
6358
late_link_args_static.insert(LinkerFlavor::Lld(LldFlavor::Ld), static_unwind_libs);

‎library/alloc/benches/vec.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use rand::prelude::*;
1+
use rand::RngCore;
22
use std::iter::{repeat, FromIterator};
33
use test::{black_box, Bencher};
44

‎library/core/tests/num/mod.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -634,14 +634,18 @@ assume_usize_width! {
634634
macro_rules! test_float {
635635
($modname: ident, $fty: ty, $inf: expr, $neginf: expr, $nan: expr) => {
636636
mod $modname {
637-
// FIXME(nagisa): these tests should test for sign of -0.0
638637
#[test]
639638
fn min() {
640639
assert_eq!((0.0 as $fty).min(0.0), 0.0);
640+
assert!((0.0 as $fty).min(0.0).is_sign_positive());
641641
assert_eq!((-0.0 as $fty).min(-0.0), -0.0);
642+
assert!((-0.0 as $fty).min(-0.0).is_sign_negative());
642643
assert_eq!((9.0 as $fty).min(9.0), 9.0);
643644
assert_eq!((-9.0 as $fty).min(0.0), -9.0);
644645
assert_eq!((0.0 as $fty).min(9.0), 0.0);
646+
assert!((0.0 as $fty).min(9.0).is_sign_positive());
647+
assert_eq!((-0.0 as $fty).min(9.0), -0.0);
648+
assert!((-0.0 as $fty).min(9.0).is_sign_negative());
645649
assert_eq!((-0.0 as $fty).min(-9.0), -9.0);
646650
assert_eq!(($inf as $fty).min(9.0), 9.0);
647651
assert_eq!((9.0 as $fty).min($inf), 9.0);
@@ -660,11 +664,19 @@ macro_rules! test_float {
660664
#[test]
661665
fn max() {
662666
assert_eq!((0.0 as $fty).max(0.0), 0.0);
667+
assert!((0.0 as $fty).max(0.0).is_sign_positive());
663668
assert_eq!((-0.0 as $fty).max(-0.0), -0.0);
669+
assert!((-0.0 as $fty).max(-0.0).is_sign_negative());
664670
assert_eq!((9.0 as $fty).max(9.0), 9.0);
665671
assert_eq!((-9.0 as $fty).max(0.0), 0.0);
672+
assert!((-9.0 as $fty).max(0.0).is_sign_positive());
673+
assert_eq!((-9.0 as $fty).max(-0.0), -0.0);
674+
assert!((-9.0 as $fty).max(-0.0).is_sign_negative());
666675
assert_eq!((0.0 as $fty).max(9.0), 9.0);
676+
assert_eq!((0.0 as $fty).max(-9.0), 0.0);
677+
assert!((0.0 as $fty).max(-9.0).is_sign_positive());
667678
assert_eq!((-0.0 as $fty).max(-9.0), -0.0);
679+
assert!((-0.0 as $fty).max(-9.0).is_sign_negative());
668680
assert_eq!(($inf as $fty).max(9.0), $inf);
669681
assert_eq!((9.0 as $fty).max($inf), $inf);
670682
assert_eq!(($inf as $fty).max(-9.0), $inf);

‎library/std/src/collections/hash/map.rs

Lines changed: 106 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1102,6 +1102,16 @@ where
11021102
/// documentation for more.
11031103
///
11041104
/// [`iter`]: HashMap::iter
1105+
///
1106+
/// # Example
1107+
///
1108+
/// ```
1109+
/// use std::collections::HashMap;
1110+
///
1111+
/// let mut map = HashMap::new();
1112+
/// map.insert("a", 1);
1113+
/// let iter = map.iter();
1114+
/// ```
11051115
#[stable(feature = "rust1", since = "1.0.0")]
11061116
pub struct Iter<'a, K: 'a, V: 'a> {
11071117
base: base::Iter<'a, K, V>,
@@ -1129,6 +1139,16 @@ impl<K: Debug, V: Debug> fmt::Debug for Iter<'_, K, V> {
11291139
/// documentation for more.
11301140
///
11311141
/// [`iter_mut`]: HashMap::iter_mut
1142+
///
1143+
/// # Example
1144+
///
1145+
/// ```
1146+
/// use std::collections::HashMap;
1147+
///
1148+
/// let mut map = HashMap::new();
1149+
/// map.insert("a", 1);
1150+
/// let iter = map.iter_mut();
1151+
/// ```
11321152
#[stable(feature = "rust1", since = "1.0.0")]
11331153
pub struct IterMut<'a, K: 'a, V: 'a> {
11341154
base: base::IterMut<'a, K, V>,
@@ -1148,6 +1168,16 @@ impl<'a, K, V> IterMut<'a, K, V> {
11481168
/// (provided by the `IntoIterator` trait). See its documentation for more.
11491169
///
11501170
/// [`into_iter`]: IntoIterator::into_iter
1171+
///
1172+
/// # Example
1173+
///
1174+
/// ```
1175+
/// use std::collections::HashMap;
1176+
///
1177+
/// let mut map = HashMap::new();
1178+
/// map.insert("a", 1);
1179+
/// let iter = map.into_iter();
1180+
/// ```
11511181
#[stable(feature = "rust1", since = "1.0.0")]
11521182
pub struct IntoIter<K, V> {
11531183
base: base::IntoIter<K, V>,
@@ -1167,6 +1197,16 @@ impl<K, V> IntoIter<K, V> {
11671197
/// documentation for more.
11681198
///
11691199
/// [`keys`]: HashMap::keys
1200+
///
1201+
/// # Example
1202+
///
1203+
/// ```
1204+
/// use std::collections::HashMap;
1205+
///
1206+
/// let mut map = HashMap::new();
1207+
/// map.insert("a", 1);
1208+
/// let iter_keys = map.keys();
1209+
/// ```
11701210
#[stable(feature = "rust1", since = "1.0.0")]
11711211
pub struct Keys<'a, K: 'a, V: 'a> {
11721212
inner: Iter<'a, K, V>,
@@ -1194,6 +1234,16 @@ impl<K: Debug, V> fmt::Debug for Keys<'_, K, V> {
11941234
/// documentation for more.
11951235
///
11961236
/// [`values`]: HashMap::values
1237+
///
1238+
/// # Example
1239+
///
1240+
/// ```
1241+
/// use std::collections::HashMap;
1242+
///
1243+
/// let mut map = HashMap::new();
1244+
/// map.insert("a", 1);
1245+
/// let iter_values = map.values();
1246+
/// ```
11971247
#[stable(feature = "rust1", since = "1.0.0")]
11981248
pub struct Values<'a, K: 'a, V: 'a> {
11991249
inner: Iter<'a, K, V>,
@@ -1221,6 +1271,16 @@ impl<K, V: Debug> fmt::Debug for Values<'_, K, V> {
12211271
/// documentation for more.
12221272
///
12231273
/// [`drain`]: HashMap::drain
1274+
///
1275+
/// # Example
1276+
///
1277+
/// ```
1278+
/// use std::collections::HashMap;
1279+
///
1280+
/// let mut map = HashMap::new();
1281+
/// map.insert("a", 1);
1282+
/// let iter = map.drain();
1283+
/// ```
12241284
#[stable(feature = "drain", since = "1.6.0")]
12251285
pub struct Drain<'a, K: 'a, V: 'a> {
12261286
base: base::Drain<'a, K, V>,
@@ -1239,6 +1299,18 @@ impl<'a, K, V> Drain<'a, K, V> {
12391299
/// This `struct` is created by the [`drain_filter`] method on [`HashMap`].
12401300
///
12411301
/// [`drain_filter`]: HashMap::drain_filter
1302+
///
1303+
/// # Example
1304+
///
1305+
/// ```
1306+
/// #![feature(hash_drain_filter)]
1307+
///
1308+
/// use std::collections::HashMap;
1309+
///
1310+
/// let mut map = HashMap::new();
1311+
/// map.insert("a", 1);
1312+
/// let iter = map.drain_filter(|_k, v| *v % 2 == 0);
1313+
/// ```
12421314
#[unstable(feature = "hash_drain_filter", issue = "59618")]
12431315
pub struct DrainFilter<'a, K, V, F>
12441316
where
@@ -1253,6 +1325,16 @@ where
12531325
/// documentation for more.
12541326
///
12551327
/// [`values_mut`]: HashMap::values_mut
1328+
///
1329+
/// # Example
1330+
///
1331+
/// ```
1332+
/// use std::collections::HashMap;
1333+
///
1334+
/// let mut map = HashMap::new();
1335+
/// map.insert("a", 1);
1336+
/// let iter_values = map.values_mut();
1337+
/// ```
12561338
#[stable(feature = "map_values_mut", since = "1.10.0")]
12571339
pub struct ValuesMut<'a, K: 'a, V: 'a> {
12581340
inner: IterMut<'a, K, V>,
@@ -1264,6 +1346,18 @@ pub struct ValuesMut<'a, K: 'a, V: 'a> {
12641346
/// See its documentation for more.
12651347
///
12661348
/// [`into_keys`]: HashMap::into_keys
1349+
///
1350+
/// # Example
1351+
///
1352+
/// ```
1353+
/// #![feature(map_into_keys_values)]
1354+
///
1355+
/// use std::collections::HashMap;
1356+
///
1357+
/// let mut map = HashMap::new();
1358+
/// map.insert("a", 1);
1359+
/// let iter_keys = map.into_keys();
1360+
/// ```
12671361
#[unstable(feature = "map_into_keys_values", issue = "75294")]
12681362
pub struct IntoKeys<K, V> {
12691363
inner: IntoIter<K, V>,
@@ -1275,6 +1369,18 @@ pub struct IntoKeys<K, V> {
12751369
/// See its documentation for more.
12761370
///
12771371
/// [`into_values`]: HashMap::into_values
1372+
///
1373+
/// # Example
1374+
///
1375+
/// ```
1376+
/// #![feature(map_into_keys_values)]
1377+
///
1378+
/// use std::collections::HashMap;
1379+
///
1380+
/// let mut map = HashMap::new();
1381+
/// map.insert("a", 1);
1382+
/// let iter_keys = map.into_values();
1383+
/// ```
12781384
#[unstable(feature = "map_into_keys_values", issue = "75294")]
12791385
pub struct IntoValues<K, V> {
12801386
inner: IntoIter<K, V>,
@@ -1285,7 +1391,6 @@ pub struct IntoValues<K, V> {
12851391
/// See the [`HashMap::raw_entry_mut`] docs for usage examples.
12861392
///
12871393
/// [`HashMap::raw_entry_mut`]: HashMap::raw_entry_mut
1288-
12891394
#[unstable(feature = "hash_raw_entry", issue = "56167")]
12901395
pub struct RawEntryBuilderMut<'a, K: 'a, V: 'a, S: 'a> {
12911396
map: &'a mut HashMap<K, V, S>,

‎src/test/ui/proc-macro/issue-75930-derive-cfg.rs

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,65 @@
11
// check-pass
2-
// compile-flags: -Z span-debug
2+
// compile-flags: -Z span-debug --error-format human
33
// aux-build:test-macros.rs
44

55
// Regression test for issue #75930
66
// Tests that we cfg-strip all targets before invoking
77
// a derive macro
8+
// We need '--error-format human' to stop compiletest from
9+
// trying to interpret proc-macro output as JSON messages
10+
// (a pretty-printed struct may cause a line to start with '{' )
11+
// FIXME: We currently lose spans here (see issue #43081)
812

913
#[macro_use]
1014
extern crate test_macros;
1115

16+
#[print_helper(a)]
17+
#[cfg_attr(not(FALSE), allow(dead_code))]
18+
#[print_attr]
1219
#[derive(Print)]
20+
#[print_helper(b)]
1321
struct Foo<#[cfg(FALSE)] A, B> {
1422
#[cfg(FALSE)] first: String,
15-
second: bool,
23+
#[cfg_attr(FALSE, deny(warnings))] second: bool,
1624
third: [u8; {
1725
#[cfg(FALSE)] struct Bar;
1826
#[cfg(not(FALSE))] struct Inner;
1927
#[cfg(FALSE)] let a = 25;
2028
match true {
2129
#[cfg(FALSE)] true => {},
22-
false => {},
30+
#[cfg_attr(not(FALSE), allow(warnings))] false => {},
2331
_ => {}
2432
};
33+
34+
#[print_helper(should_be_removed)]
35+
fn removed_fn() {
36+
#![cfg(FALSE)]
37+
}
38+
39+
#[print_helper(c)] #[cfg(not(FALSE))] fn kept_fn() {
40+
#![cfg(not(FALSE))]
41+
let my_val = true;
42+
}
43+
44+
enum TupleEnum {
45+
Foo(
46+
#[cfg(FALSE)] u8,
47+
#[cfg(FALSE)] bool,
48+
#[cfg(not(FALSE))] i32,
49+
#[cfg(FALSE)] String, u8
50+
)
51+
}
52+
53+
struct TupleStruct(
54+
#[cfg(FALSE)] String,
55+
#[cfg(not(FALSE))] i32,
56+
#[cfg(FALSE)] bool,
57+
u8
58+
);
59+
2560
0
2661
}],
62+
#[print_helper(d)]
2763
fourth: B
2864
}
2965

‎src/test/ui/proc-macro/issue-75930-derive-cfg.stdout

Lines changed: 1613 additions & 3 deletions
Large diffs are not rendered by default.

‎src/tools/clippy/clippy_lints/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#![feature(concat_idents)]
77
#![feature(crate_visibility_modifier)]
88
#![feature(drain_filter)]
9+
#![feature(in_band_lifetimes)]
910
#![feature(or_patterns)]
1011
#![feature(rustc_private)]
1112
#![feature(stmt_expr_attributes)]

‎src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use rustc_hir::intravisit::FnKind;
44
use rustc_hir::{Body, Constness, FnDecl, GenericParamKind, HirId};
55
use rustc_lint::{LateContext, LateLintPass};
66
use rustc_middle::lint::in_external_macro;
7-
use rustc_mir::transform::qualify_min_const_fn::is_min_const_fn;
7+
use crate::utils::qualify_min_const_fn::is_min_const_fn;
88
use rustc_session::{declare_lint_pass, declare_tool_lint};
99
use rustc_span::Span;
1010
use rustc_typeck::hir_ty_to_ty;

‎src/tools/clippy/clippy_lints/src/utils/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ pub mod paths;
2020
pub mod ptr;
2121
pub mod sugg;
2222
pub mod usage;
23+
pub mod qualify_min_const_fn;
2324

2425
pub use self::attrs::*;
2526
pub use self::diagnostics::*;

‎compiler/rustc_mir/src/transform/qualify_min_const_fn.rs renamed to ‎src/tools/clippy/clippy_lints/src/utils/qualify_min_const_fn.rs

Lines changed: 29 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,14 @@ use rustc_hir::def_id::DefId;
33
use rustc_middle::mir::*;
44
use rustc_middle::ty::subst::GenericArgKind;
55
use rustc_middle::ty::{self, adjustment::PointerCast, Ty, TyCtxt};
6-
use rustc_span::symbol::{sym, Symbol};
6+
use rustc_span::symbol::{sym};
77
use rustc_span::Span;
88
use rustc_target::spec::abi::Abi::RustIntrinsic;
99
use std::borrow::Cow;
1010

1111
type McfResult = Result<(), (Span, Cow<'static, str>)>;
1212

1313
pub fn is_min_const_fn(tcx: TyCtxt<'tcx>, def_id: DefId, body: &'a Body<'tcx>) -> McfResult {
14-
// Prevent const trait methods from being annotated as `stable`.
15-
if tcx.features().staged_api {
16-
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
17-
if crate::const_eval::is_parent_const_impl_raw(tcx, hir_id) {
18-
return Err((body.span, "trait methods cannot be stable const fn".into()));
19-
}
20-
}
21-
2214
let mut current = def_id;
2315
loop {
2416
let predicates = tcx.predicates_of(current);
@@ -32,27 +24,20 @@ pub fn is_min_const_fn(tcx: TyCtxt<'tcx>, def_id: DefId, body: &'a Body<'tcx>) -
3224
| ty::PredicateAtom::ConstEquate(..)
3325
| ty::PredicateAtom::TypeWellFormedFromEnv(..) => continue,
3426
ty::PredicateAtom::ObjectSafe(_) => {
35-
bug!("object safe predicate on function: {:#?}", predicate)
27+
panic!("object safe predicate on function: {:#?}", predicate)
3628
}
3729
ty::PredicateAtom::ClosureKind(..) => {
38-
bug!("closure kind predicate on function: {:#?}", predicate)
30+
panic!("closure kind predicate on function: {:#?}", predicate)
3931
}
4032
ty::PredicateAtom::Subtype(_) => {
41-
bug!("subtype predicate on function: {:#?}", predicate)
33+
panic!("subtype predicate on function: {:#?}", predicate)
4234
}
43-
ty::PredicateAtom::Trait(pred, constness) => {
35+
ty::PredicateAtom::Trait(pred, _) => {
4436
if Some(pred.def_id()) == tcx.lang_items().sized_trait() {
4537
continue;
4638
}
4739
match pred.self_ty().kind() {
4840
ty::Param(ref p) => {
49-
// Allow `T: ?const Trait`
50-
if constness == hir::Constness::NotConst
51-
&& feature_allowed(tcx, def_id, sym::const_trait_bound_opt_out)
52-
{
53-
continue;
54-
}
55-
5641
let generics = tcx.generics_of(current);
5742
let def = generics.type_param(p, tcx);
5843
let span = tcx.def_span(def.def_id);
@@ -77,26 +62,25 @@ pub fn is_min_const_fn(tcx: TyCtxt<'tcx>, def_id: DefId, body: &'a Body<'tcx>) -
7762
}
7863

7964
for local in &body.local_decls {
80-
check_ty(tcx, local.ty, local.source_info.span, def_id)?;
65+
check_ty(tcx, local.ty, local.source_info.span)?;
8166
}
8267
// impl trait is gone in MIR, so check the return type manually
8368
check_ty(
8469
tcx,
8570
tcx.fn_sig(def_id).output().skip_binder(),
8671
body.local_decls.iter().next().unwrap().source_info.span,
87-
def_id,
8872
)?;
8973

9074
for bb in body.basic_blocks() {
91-
check_terminator(tcx, body, def_id, bb.terminator())?;
75+
check_terminator(tcx, body, bb.terminator())?;
9276
for stmt in &bb.statements {
9377
check_statement(tcx, body, def_id, stmt)?;
9478
}
9579
}
9680
Ok(())
9781
}
9882

99-
fn check_ty(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, span: Span, fn_def_id: DefId) -> McfResult {
83+
fn check_ty(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, span: Span) -> McfResult {
10084
for arg in ty.walk() {
10185
let ty = match arg.unpack() {
10286
GenericArgKind::Type(ty) => ty,
@@ -108,15 +92,11 @@ fn check_ty(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, span: Span, fn_def_id: DefId) -> Mc
10892

10993
match ty.kind() {
11094
ty::Ref(_, _, hir::Mutability::Mut) => {
111-
if !feature_allowed(tcx, fn_def_id, sym::const_mut_refs) {
11295
return Err((span, "mutable references in const fn are unstable".into()));
113-
}
11496
}
11597
ty::Opaque(..) => return Err((span, "`impl Trait` in const fn is unstable".into())),
11698
ty::FnPtr(..) => {
117-
if !tcx.const_fn_is_allowed_fn_ptr(fn_def_id) {
11899
return Err((span, "function pointers in const fn are unstable".into()));
119-
}
120100
}
121101
ty::Dynamic(preds, _) => {
122102
for pred in preds.iter() {
@@ -161,12 +141,12 @@ fn check_rvalue(
161141
Err((span, "cannot access thread local storage in const fn".into()))
162142
}
163143
Rvalue::Repeat(operand, _) | Rvalue::Use(operand) => {
164-
check_operand(tcx, operand, span, def_id, body)
144+
check_operand(tcx, operand, span, body)
165145
}
166146
Rvalue::Len(place)
167147
| Rvalue::Discriminant(place)
168148
| Rvalue::Ref(_, _, place)
169-
| Rvalue::AddressOf(_, place) => check_place(tcx, *place, span, def_id, body),
149+
| Rvalue::AddressOf(_, place) => check_place(tcx, *place, span, body),
170150
Rvalue::Cast(CastKind::Misc, operand, cast_ty) => {
171151
use rustc_middle::ty::cast::CastTy;
172152
let cast_in = CastTy::from_ty(operand.ty(body, tcx)).expect("bad input type for cast");
@@ -175,14 +155,14 @@ fn check_rvalue(
175155
(CastTy::Ptr(_) | CastTy::FnPtr, CastTy::Int(_)) => {
176156
Err((span, "casting pointers to ints is unstable in const fn".into()))
177157
}
178-
_ => check_operand(tcx, operand, span, def_id, body),
158+
_ => check_operand(tcx, operand, span, body),
179159
}
180160
}
181161
Rvalue::Cast(
182162
CastKind::Pointer(PointerCast::MutToConstPointer | PointerCast::ArrayToPointer),
183163
operand,
184164
_,
185-
) => check_operand(tcx, operand, span, def_id, body),
165+
) => check_operand(tcx, operand, span, body),
186166
Rvalue::Cast(
187167
CastKind::Pointer(
188168
PointerCast::UnsafeFnPointer
@@ -204,7 +184,7 @@ fn check_rvalue(
204184
};
205185
let unsized_ty = tcx.struct_tail_erasing_lifetimes(pointee_ty, tcx.param_env(def_id));
206186
if let ty::Slice(_) | ty::Str = unsized_ty.kind() {
207-
check_operand(tcx, op, span, def_id, body)?;
187+
check_operand(tcx, op, span, body)?;
208188
// Casting/coercing things to slices is fine.
209189
Ok(())
210190
} else {
@@ -214,8 +194,8 @@ fn check_rvalue(
214194
}
215195
// binops are fine on integers
216196
Rvalue::BinaryOp(_, lhs, rhs) | Rvalue::CheckedBinaryOp(_, lhs, rhs) => {
217-
check_operand(tcx, lhs, span, def_id, body)?;
218-
check_operand(tcx, rhs, span, def_id, body)?;
197+
check_operand(tcx, lhs, span, body)?;
198+
check_operand(tcx, rhs, span, body)?;
219199
let ty = lhs.ty(body, tcx);
220200
if ty.is_integral() || ty.is_bool() || ty.is_char() {
221201
Ok(())
@@ -230,14 +210,14 @@ fn check_rvalue(
230210
Rvalue::UnaryOp(_, operand) => {
231211
let ty = operand.ty(body, tcx);
232212
if ty.is_integral() || ty.is_bool() {
233-
check_operand(tcx, operand, span, def_id, body)
213+
check_operand(tcx, operand, span, body)
234214
} else {
235215
Err((span, "only int and `bool` operations are stable in const fn".into()))
236216
}
237217
}
238218
Rvalue::Aggregate(_, operands) => {
239219
for operand in operands {
240-
check_operand(tcx, operand, span, def_id, body)?;
220+
check_operand(tcx, operand, span, body)?;
241221
}
242222
Ok(())
243223
}
@@ -253,15 +233,15 @@ fn check_statement(
253233
let span = statement.source_info.span;
254234
match &statement.kind {
255235
StatementKind::Assign(box (place, rval)) => {
256-
check_place(tcx, *place, span, def_id, body)?;
236+
check_place(tcx, *place, span, body)?;
257237
check_rvalue(tcx, body, def_id, rval, span)
258238
}
259239

260-
StatementKind::FakeRead(_, place) => check_place(tcx, **place, span, def_id, body),
240+
StatementKind::FakeRead(_, place) => check_place(tcx, **place, span, body),
261241

262242
// just an assignment
263243
StatementKind::SetDiscriminant { place, .. } => {
264-
check_place(tcx, **place, span, def_id, body)
244+
check_place(tcx, **place, span, body)
265245
}
266246

267247
StatementKind::LlvmInlineAsm { .. } => {
@@ -282,11 +262,10 @@ fn check_operand(
282262
tcx: TyCtxt<'tcx>,
283263
operand: &Operand<'tcx>,
284264
span: Span,
285-
def_id: DefId,
286265
body: &Body<'tcx>,
287266
) -> McfResult {
288267
match operand {
289-
Operand::Move(place) | Operand::Copy(place) => check_place(tcx, *place, span, def_id, body),
268+
Operand::Move(place) | Operand::Copy(place) => check_place(tcx, *place, span, body),
290269
Operand::Constant(c) => match c.check_static_ptr(tcx) {
291270
Some(_) => Err((span, "cannot access `static` items in const fn".into())),
292271
None => Ok(()),
@@ -298,7 +277,6 @@ fn check_place(
298277
tcx: TyCtxt<'tcx>,
299278
place: Place<'tcx>,
300279
span: Span,
301-
def_id: DefId,
302280
body: &Body<'tcx>,
303281
) -> McfResult {
304282
let mut cursor = place.projection.as_ref();
@@ -310,9 +288,7 @@ fn check_place(
310288
if let Some(def) = base_ty.ty_adt_def() {
311289
// No union field accesses in `const fn`
312290
if def.is_union() {
313-
if !feature_allowed(tcx, def_id, sym::const_fn_union) {
314291
return Err((span, "accessing union fields is unstable".into()));
315-
}
316292
}
317293
}
318294
}
@@ -327,48 +303,9 @@ fn check_place(
327303
Ok(())
328304
}
329305

330-
/// Returns `true` if the given feature gate is allowed within the function with the given `DefId`.
331-
fn feature_allowed(tcx: TyCtxt<'tcx>, def_id: DefId, feature_gate: Symbol) -> bool {
332-
// All features require that the corresponding gate be enabled,
333-
// even if the function has `#[allow_internal_unstable(the_gate)]`.
334-
if !tcx.features().enabled(feature_gate) {
335-
return false;
336-
}
337-
338-
// If this crate is not using stability attributes, or this function is not claiming to be a
339-
// stable `const fn`, that is all that is required.
340-
if !tcx.features().staged_api || tcx.has_attr(def_id, sym::rustc_const_unstable) {
341-
return true;
342-
}
343-
344-
// However, we cannot allow stable `const fn`s to use unstable features without an explicit
345-
// opt-in via `allow_internal_unstable`.
346-
super::check_consts::allow_internal_unstable(tcx, def_id, feature_gate)
347-
}
348-
349-
/// Returns `true` if the given library feature gate is allowed within the function with the given `DefId`.
350-
pub fn lib_feature_allowed(tcx: TyCtxt<'tcx>, def_id: DefId, feature_gate: Symbol) -> bool {
351-
// All features require that the corresponding gate be enabled,
352-
// even if the function has `#[allow_internal_unstable(the_gate)]`.
353-
if !tcx.features().declared_lib_features.iter().any(|&(sym, _)| sym == feature_gate) {
354-
return false;
355-
}
356-
357-
// If this crate is not using stability attributes, or this function is not claiming to be a
358-
// stable `const fn`, that is all that is required.
359-
if !tcx.features().staged_api || tcx.has_attr(def_id, sym::rustc_const_unstable) {
360-
return true;
361-
}
362-
363-
// However, we cannot allow stable `const fn`s to use unstable features without an explicit
364-
// opt-in via `allow_internal_unstable`.
365-
super::check_consts::allow_internal_unstable(tcx, def_id, feature_gate)
366-
}
367-
368306
fn check_terminator(
369307
tcx: TyCtxt<'tcx>,
370308
body: &'a Body<'tcx>,
371-
def_id: DefId,
372309
terminator: &Terminator<'tcx>,
373310
) -> McfResult {
374311
let span = terminator.source_info.span;
@@ -380,14 +317,14 @@ fn check_terminator(
380317
| TerminatorKind::Resume
381318
| TerminatorKind::Unreachable => Ok(()),
382319

383-
TerminatorKind::Drop { place, .. } => check_place(tcx, *place, span, def_id, body),
320+
TerminatorKind::Drop { place, .. } => check_place(tcx, *place, span, body),
384321
TerminatorKind::DropAndReplace { place, value, .. } => {
385-
check_place(tcx, *place, span, def_id, body)?;
386-
check_operand(tcx, value, span, def_id, body)
322+
check_place(tcx, *place, span, body)?;
323+
check_operand(tcx, value, span, body)
387324
}
388325

389326
TerminatorKind::SwitchInt { discr, switch_ty: _, values: _, targets: _ } => {
390-
check_operand(tcx, discr, span, def_id, body)
327+
check_operand(tcx, discr, span, body)
391328
}
392329

393330
TerminatorKind::Abort => Err((span, "abort is not stable in const fn".into())),
@@ -405,15 +342,7 @@ fn check_terminator(
405342
} => {
406343
let fn_ty = func.ty(body, tcx);
407344
if let ty::FnDef(fn_def_id, _) = *fn_ty.kind() {
408-
// Allow unstable const if we opt in by using #[allow_internal_unstable]
409-
// on function or macro declaration.
410-
if !crate::const_eval::is_min_const_fn(tcx, fn_def_id)
411-
&& !crate::const_eval::is_unstable_const_fn(tcx, fn_def_id)
412-
.map(|feature| {
413-
span.allows_unstable(feature)
414-
|| lib_feature_allowed(tcx, def_id, feature)
415-
})
416-
.unwrap_or(false)
345+
if !rustc_mir::const_eval::is_min_const_fn(tcx, fn_def_id)
417346
{
418347
return Err((
419348
span,
@@ -432,18 +361,17 @@ fn check_terminator(
432361
// transmutes in const fn before we add more hacks to this.
433362
if tcx.fn_sig(fn_def_id).abi() == RustIntrinsic
434363
&& tcx.item_name(fn_def_id) == sym::transmute
435-
&& !feature_allowed(tcx, def_id, sym::const_fn_transmute)
436364
{
437365
return Err((
438366
span,
439367
"can only call `transmute` from const items, not `const fn`".into(),
440368
));
441369
}
442370

443-
check_operand(tcx, func, span, fn_def_id, body)?;
371+
check_operand(tcx, func, span, body)?;
444372

445373
for arg in args {
446-
check_operand(tcx, arg, span, fn_def_id, body)?;
374+
check_operand(tcx, arg, span, body)?;
447375
}
448376
Ok(())
449377
} else {
@@ -452,7 +380,7 @@ fn check_terminator(
452380
}
453381

454382
TerminatorKind::Assert { cond, expected: _, msg: _, target: _, cleanup: _ } => {
455-
check_operand(tcx, cond, span, def_id, body)
383+
check_operand(tcx, cond, span, body)
456384
}
457385

458386
TerminatorKind::InlineAsm { .. } => {

0 commit comments

Comments
 (0)
Please sign in to comment.