Skip to content

Commit 45b600c

Browse files
committed
Auto merge of rust-lang#90161 - JohnTitor:rollup-1j2qc8m, r=JohnTitor
Rollup of 14 pull requests Successful merges: - rust-lang#87537 (Clarify undefined behaviour in binary heap, btree and hashset docs) - rust-lang#88624 (Stabilize feature `saturating_div` for rust 1.58.0) - rust-lang#89257 (Give better error for `macro_rules name`) - rust-lang#89665 (Ensure that pushing empty path works as before on verbatim paths) - rust-lang#89895 (Don't mark for loop iter expression as desugared) - rust-lang#89922 (Update E0637 description to mention `&` w/o an explicit lifetime name) - rust-lang#89944 (Change `Duration::[try_]from_secs_{f32, f64}` underflow error) - rust-lang#89991 (rustc_ast: Turn `MutVisitor::token_visiting_enabled` into a constant) - rust-lang#90028 (Reject closures in patterns) - rust-lang#90069 (Fix const qualification when executed after promotion) - rust-lang#90078 (Add a regression test for issue-83479) - rust-lang#90114 (Add some tests for const_generics_defaults) - rust-lang#90115 (Add test for issue rust-lang#78561) - rust-lang#90129 (triagebot: Treat `I-*nominated` like `I-nominated`) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 68a698b + ea8a896 commit 45b600c

File tree

52 files changed

+692
-168
lines changed

Some content is hidden

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

52 files changed

+692
-168
lines changed

compiler/rustc_ast/src/mut_visit.rs

+5-7
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,7 @@ pub trait MutVisitor: Sized {
3737
/// Mutable token visiting only exists for the `macro_rules` token marker and should not be
3838
/// used otherwise. Token visitor would be entirely separate from the regular visitor if
3939
/// the marker didn't have to visit AST fragments in nonterminal tokens.
40-
fn token_visiting_enabled(&self) -> bool {
41-
false
42-
}
40+
const VISIT_TOKENS: bool = false;
4341

4442
// Methods in this trait have one of three forms:
4543
//
@@ -363,7 +361,7 @@ pub fn visit_mac_args<T: MutVisitor>(args: &mut MacArgs, vis: &mut T) {
363361
}
364362
MacArgs::Eq(eq_span, token) => {
365363
vis.visit_span(eq_span);
366-
if vis.token_visiting_enabled() {
364+
if T::VISIT_TOKENS {
367365
visit_token(token, vis);
368366
} else {
369367
// The value in `#[key = VALUE]` must be visited as an expression for backward
@@ -682,7 +680,7 @@ pub fn visit_tt<T: MutVisitor>(tt: &mut TokenTree, vis: &mut T) {
682680

683681
// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
684682
pub fn visit_tts<T: MutVisitor>(TokenStream(tts): &mut TokenStream, vis: &mut T) {
685-
if vis.token_visiting_enabled() && !tts.is_empty() {
683+
if T::VISIT_TOKENS && !tts.is_empty() {
686684
let tts = Lrc::make_mut(tts);
687685
visit_vec(tts, |(tree, _is_joint)| visit_tt(tree, vis));
688686
}
@@ -692,14 +690,14 @@ pub fn visit_attr_annotated_tts<T: MutVisitor>(
692690
AttrAnnotatedTokenStream(tts): &mut AttrAnnotatedTokenStream,
693691
vis: &mut T,
694692
) {
695-
if vis.token_visiting_enabled() && !tts.is_empty() {
693+
if T::VISIT_TOKENS && !tts.is_empty() {
696694
let tts = Lrc::make_mut(tts);
697695
visit_vec(tts, |(tree, _is_joint)| visit_attr_annotated_tt(tree, vis));
698696
}
699697
}
700698

701699
pub fn visit_lazy_tts_opt_mut<T: MutVisitor>(lazy_tts: Option<&mut LazyTokenStream>, vis: &mut T) {
702-
if vis.token_visiting_enabled() {
700+
if T::VISIT_TOKENS {
703701
if let Some(lazy_tts) = lazy_tts {
704702
let mut tts = lazy_tts.create_token_stream();
705703
visit_attr_annotated_tts(&mut tts, vis);

compiler/rustc_ast_lowering/src/expr.rs

+18-21
Original file line numberDiff line numberDiff line change
@@ -1332,15 +1332,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
13321332
body: &Block,
13331333
opt_label: Option<Label>,
13341334
) -> hir::Expr<'hir> {
1335-
let orig_head_span = head.span;
13361335
// expand <head>
1337-
let mut head = self.lower_expr_mut(head);
1338-
let desugared_span = self.mark_span_with_reason(
1339-
DesugaringKind::ForLoop(ForLoopLoc::Head),
1340-
orig_head_span,
1341-
None,
1342-
);
1343-
head.span = self.lower_span(desugared_span);
1336+
let head = self.lower_expr_mut(head);
1337+
let desugared_span =
1338+
self.mark_span_with_reason(DesugaringKind::ForLoop(ForLoopLoc::Head), head.span, None);
1339+
let e_span = self.lower_span(e.span);
13441340

13451341
let iter = Ident::with_dummy_span(sym::iter);
13461342

@@ -1354,23 +1350,24 @@ impl<'hir> LoweringContext<'_, 'hir> {
13541350
// `::std::option::Option::Some(val) => __next = val`
13551351
let pat_arm = {
13561352
let val_ident = Ident::with_dummy_span(sym::val);
1357-
let (val_pat, val_pat_hid) = self.pat_ident(pat.span, val_ident);
1358-
let val_expr = self.expr_ident(pat.span, val_ident, val_pat_hid);
1359-
let next_expr = self.expr_ident(pat.span, next_ident, next_pat_hid);
1353+
let pat_span = self.lower_span(pat.span);
1354+
let (val_pat, val_pat_hid) = self.pat_ident(pat_span, val_ident);
1355+
let val_expr = self.expr_ident(pat_span, val_ident, val_pat_hid);
1356+
let next_expr = self.expr_ident(pat_span, next_ident, next_pat_hid);
13601357
let assign = self.arena.alloc(self.expr(
1361-
pat.span,
1362-
hir::ExprKind::Assign(next_expr, val_expr, self.lower_span(pat.span)),
1358+
pat_span,
1359+
hir::ExprKind::Assign(next_expr, val_expr, self.lower_span(pat_span)),
13631360
ThinVec::new(),
13641361
));
1365-
let some_pat = self.pat_some(pat.span, val_pat);
1362+
let some_pat = self.pat_some(pat_span, val_pat);
13661363
self.arm(some_pat, assign)
13671364
};
13681365

13691366
// `::std::option::Option::None => break`
13701367
let break_arm = {
13711368
let break_expr =
1372-
self.with_loop_scope(e.id, |this| this.expr_break_alloc(e.span, ThinVec::new()));
1373-
let pat = self.pat_none(e.span);
1369+
self.with_loop_scope(e.id, |this| this.expr_break_alloc(e_span, ThinVec::new()));
1370+
let pat = self.pat_none(e_span);
13741371
self.arm(pat, break_expr)
13751372
};
13761373

@@ -1416,10 +1413,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
14161413

14171414
let body_block = self.with_loop_scope(e.id, |this| this.lower_block(body, false));
14181415
let body_expr = self.expr_block(body_block, ThinVec::new());
1419-
let body_stmt = self.stmt_expr(body.span, body_expr);
1416+
let body_stmt = self.stmt_expr(body_block.span, body_expr);
14201417

14211418
let loop_block = self.block_all(
1422-
e.span,
1419+
e_span,
14231420
arena_vec![self; next_let, match_stmt, pat_let, body_stmt],
14241421
None,
14251422
);
@@ -1429,7 +1426,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
14291426
loop_block,
14301427
self.lower_label(opt_label),
14311428
hir::LoopSource::ForLoop,
1432-
self.lower_span(e.span.with_hi(orig_head_span.hi())),
1429+
self.lower_span(e_span.with_hi(head.span.hi())),
14331430
);
14341431
let loop_expr = self.arena.alloc(hir::Expr {
14351432
hir_id: self.lower_node_id(e.id),
@@ -1442,7 +1439,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
14421439

14431440
let into_iter_span = self.mark_span_with_reason(
14441441
DesugaringKind::ForLoop(ForLoopLoc::IntoIter),
1445-
orig_head_span,
1442+
head.span,
14461443
None,
14471444
);
14481445

@@ -1458,7 +1455,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
14581455
// #82462: to correctly diagnose borrow errors, the block that contains
14591456
// the iter expr needs to have a span that covers the loop body.
14601457
let desugared_full_span =
1461-
self.mark_span_with_reason(DesugaringKind::ForLoop(ForLoopLoc::Head), e.span, None);
1458+
self.mark_span_with_reason(DesugaringKind::ForLoop(ForLoopLoc::Head), e_span, None);
14621459

14631460
let match_expr = self.arena.alloc(self.expr_match(
14641461
desugared_full_span,

compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs

+30-30
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ use rustc_middle::mir::{
1111
};
1212
use rustc_middle::ty::{self, suggest_constraining_type_param, Ty};
1313
use rustc_mir_dataflow::move_paths::{InitKind, MoveOutIndex, MovePathIndex};
14-
use rustc_span::source_map::DesugaringKind;
1514
use rustc_span::symbol::sym;
1615
use rustc_span::{BytePos, MultiSpan, Span, DUMMY_SP};
1716
use rustc_trait_selection::infer::InferCtxtExt;
@@ -247,6 +246,36 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
247246
place_name, partially_str, loop_message
248247
),
249248
);
249+
let sess = self.infcx.tcx.sess;
250+
let ty = used_place.ty(self.body, self.infcx.tcx).ty;
251+
// If we have a `&mut` ref, we need to reborrow.
252+
if let ty::Ref(_, _, hir::Mutability::Mut) = ty.kind() {
253+
// If we are in a loop this will be suggested later.
254+
if !is_loop_move {
255+
err.span_suggestion_verbose(
256+
move_span.shrink_to_lo(),
257+
&format!(
258+
"consider creating a fresh reborrow of {} here",
259+
self.describe_place(moved_place.as_ref())
260+
.map(|n| format!("`{}`", n))
261+
.unwrap_or_else(
262+
|| "the mutable reference".to_string()
263+
),
264+
),
265+
"&mut *".to_string(),
266+
Applicability::MachineApplicable,
267+
);
268+
}
269+
} else if let Ok(snippet) =
270+
sess.source_map().span_to_snippet(move_span)
271+
{
272+
err.span_suggestion(
273+
move_span,
274+
"consider borrowing to avoid moving into the for loop",
275+
format!("&{}", snippet),
276+
Applicability::MaybeIncorrect,
277+
);
278+
}
250279
} else {
251280
err.span_label(
252281
fn_call_span,
@@ -315,35 +344,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
315344
in_pattern = true;
316345
}
317346
}
318-
319-
if let Some(DesugaringKind::ForLoop(_)) = move_span.desugaring_kind() {
320-
let sess = self.infcx.tcx.sess;
321-
let ty = used_place.ty(self.body, self.infcx.tcx).ty;
322-
// If we have a `&mut` ref, we need to reborrow.
323-
if let ty::Ref(_, _, hir::Mutability::Mut) = ty.kind() {
324-
// If we are in a loop this will be suggested later.
325-
if !is_loop_move {
326-
err.span_suggestion_verbose(
327-
move_span.shrink_to_lo(),
328-
&format!(
329-
"consider creating a fresh reborrow of {} here",
330-
self.describe_place(moved_place.as_ref())
331-
.map(|n| format!("`{}`", n))
332-
.unwrap_or_else(|| "the mutable reference".to_string()),
333-
),
334-
"&mut *".to_string(),
335-
Applicability::MachineApplicable,
336-
);
337-
}
338-
} else if let Ok(snippet) = sess.source_map().span_to_snippet(move_span) {
339-
err.span_suggestion(
340-
move_span,
341-
"consider borrowing to avoid moving into the for loop",
342-
format!("&{}", snippet),
343-
Applicability::MaybeIncorrect,
344-
);
345-
}
346-
}
347347
}
348348

349349
use_spans.var_span_label_path_only(

compiler/rustc_borrowck/src/diagnostics/move_errors.rs

+11-10
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,10 @@ use rustc_middle::ty;
55
use rustc_mir_dataflow::move_paths::{
66
IllegalMoveOrigin, IllegalMoveOriginKind, LookupResult, MoveError, MovePathIndex,
77
};
8-
use rustc_span::source_map::DesugaringKind;
98
use rustc_span::{sym, Span, DUMMY_SP};
109
use rustc_trait_selection::traits::type_known_to_meet_bound_modulo_regions;
1110

12-
use crate::diagnostics::UseSpans;
11+
use crate::diagnostics::{FnSelfUseKind, UseSpans};
1312
use crate::prefixes::PrefixSet;
1413
use crate::MirBorrowckCtxt;
1514

@@ -400,19 +399,21 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
400399
| ty::Opaque(def_id, _) => def_id,
401400
_ => return err,
402401
};
403-
let is_option = self.infcx.tcx.is_diagnostic_item(sym::Option, def_id);
404-
let is_result = self.infcx.tcx.is_diagnostic_item(sym::Result, def_id);
405-
if (is_option || is_result) && use_spans.map_or(true, |v| !v.for_closure()) {
402+
let diag_name = self.infcx.tcx.get_diagnostic_name(def_id);
403+
if matches!(diag_name, Some(sym::Option | sym::Result))
404+
&& use_spans.map_or(true, |v| !v.for_closure())
405+
{
406406
err.span_suggestion_verbose(
407407
span.shrink_to_hi(),
408-
&format!(
409-
"consider borrowing the `{}`'s content",
410-
if is_option { "Option" } else { "Result" }
411-
),
408+
&format!("consider borrowing the `{}`'s content", diag_name.unwrap()),
412409
".as_ref()".to_string(),
413410
Applicability::MaybeIncorrect,
414411
);
415-
} else if matches!(span.desugaring_kind(), Some(DesugaringKind::ForLoop(_))) {
412+
} else if let Some(UseSpans::FnSelfUse {
413+
kind: FnSelfUseKind::Normal { implicit_into_iter: true, .. },
414+
..
415+
}) = use_spans
416+
{
416417
let suggest = match self.infcx.tcx.get_diagnostic_item(sym::IntoIterator) {
417418
Some(def_id) => self.infcx.tcx.infer_ctxt().enter(|infcx| {
418419
type_known_to_meet_bound_modulo_regions(

compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs

+9-2
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ pub trait Qualif {
4646
/// Whether this `Qualif` is cleared when a local is moved from.
4747
const IS_CLEARED_ON_MOVE: bool = false;
4848

49+
/// Whether this `Qualif` might be evaluated after the promotion and can encounter a promoted.
50+
const ALLOW_PROMOTED: bool = false;
51+
4952
/// Extracts the field of `ConstQualifs` that corresponds to this `Qualif`.
5053
fn in_qualifs(qualifs: &ConstQualifs) -> bool;
5154

@@ -129,6 +132,7 @@ pub struct NeedsNonConstDrop;
129132
impl Qualif for NeedsNonConstDrop {
130133
const ANALYSIS_NAME: &'static str = "flow_needs_nonconst_drop";
131134
const IS_CLEARED_ON_MOVE: bool = true;
135+
const ALLOW_PROMOTED: bool = true;
132136

133137
fn in_qualifs(qualifs: &ConstQualifs) -> bool {
134138
qualifs.needs_non_const_drop
@@ -310,9 +314,12 @@ where
310314
// Check the qualifs of the value of `const` items.
311315
if let Some(ct) = constant.literal.const_for_ty() {
312316
if let ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs_: _, promoted }) = ct.val {
313-
assert!(promoted.is_none());
317+
// Use qualifs of the type for the promoted. Promoteds in MIR body should be possible
318+
// only for `NeedsNonConstDrop` with precise drop checking. This is the only const
319+
// check performed after the promotion. Verify that with an assertion.
320+
assert!(promoted.is_none() || Q::ALLOW_PROMOTED);
314321
// Don't peek inside trait associated constants.
315-
if cx.tcx.trait_of_item(def.did).is_none() {
322+
if promoted.is_none() && cx.tcx.trait_of_item(def.did).is_none() {
316323
let qualifs = if let Some((did, param_did)) = def.as_const_arg() {
317324
cx.tcx.at(constant.span).mir_const_qualif_const_arg((did, param_did))
318325
} else {
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,51 @@
1-
An underscore `_` character has been used as the identifier for a lifetime.
1+
`'_` lifetime name or `&T` without an explicit lifetime name has been used
2+
on illegal place.
23

34
Erroneous code example:
45

56
```compile_fail,E0106,E0637
6-
fn longest<'_>(str1: &'_ str, str2: &'_ str) -> &'_ str {
7-
//^^ `'_` is a reserved lifetime name
7+
fn underscore_lifetime<'_>(str1: &'_ str, str2: &'_ str) -> &'_ str {
8+
//^^ `'_` is a reserved lifetime name
89
if str1.len() > str2.len() {
910
str1
1011
} else {
1112
str2
1213
}
1314
}
15+
16+
fn and_without_explicit_lifetime<T>()
17+
where
18+
T: Into<&u32>,
19+
//^ `&` without an explicit lifetime name
20+
{
21+
}
1422
```
1523

16-
`'_`, cannot be used as a lifetime identifier because it is a reserved for the
17-
anonymous lifetime. To fix this, use a lowercase letter such as 'a, or a series
18-
of lowercase letters such as `'foo`. For more information, see [the
19-
book][bk-no]. For more information on using the anonymous lifetime in rust
20-
nightly, see [the nightly book][bk-al].
24+
First, `'_` cannot be used as a lifetime identifier in some places
25+
because it is a reserved for the anonymous lifetime. Second, `&T`
26+
without an explicit lifetime name cannot also be used in some places.
27+
To fix them, use a lowercase letter such as `'a`, or a series
28+
of lowercase letters such as `'foo`. For more information about lifetime
29+
identifier, see [the book][bk-no]. For more information on using
30+
the anonymous lifetime in Rust 2018, see [the Rust 2018 blog post][blog-al].
2131

2232
Corrected example:
2333

2434
```
25-
fn longest<'a>(str1: &'a str, str2: &'a str) -> &'a str {
35+
fn underscore_lifetime<'a>(str1: &'a str, str2: &'a str) -> &'a str {
2636
if str1.len() > str2.len() {
2737
str1
2838
} else {
2939
str2
3040
}
3141
}
42+
43+
fn and_without_explicit_lifetime<'foo, T>()
44+
where
45+
T: Into<&'foo u32>,
46+
{
47+
}
3248
```
3349

3450
[bk-no]: https://doc.rust-lang.org/book/appendix-02-operators.html#non-operator-symbols
35-
[bk-al]: https://doc.rust-lang.org/nightly/edition-guide/rust-2018/ownership-and-lifetimes/the-anonymous-lifetime.html
51+
[blog-al]: https://blog.rust-lang.org/2018/12/06/Rust-1.31-and-rust-2018.html#more-lifetime-elision-rules

compiler/rustc_expand/src/mbe/transcribe.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,7 @@ use std::mem;
1919
struct Marker(LocalExpnId, Transparency);
2020

2121
impl MutVisitor for Marker {
22-
fn token_visiting_enabled(&self) -> bool {
23-
true
24-
}
22+
const VISIT_TOKENS: bool = true;
2523

2624
fn visit_span(&mut self, span: &mut Span) {
2725
*span = span.apply_mark(self.0.to_expn_id(), self.1)

compiler/rustc_expand/src/mut_visit/tests.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,8 @@ fn print_crate_items(krate: &ast::Crate) -> String {
1515
struct ToZzIdentMutVisitor;
1616

1717
impl MutVisitor for ToZzIdentMutVisitor {
18-
fn token_visiting_enabled(&self) -> bool {
19-
true
20-
}
18+
const VISIT_TOKENS: bool = true;
19+
2120
fn visit_ident(&mut self, ident: &mut Ident) {
2221
*ident = Ident::from_str("zz");
2322
}

compiler/rustc_lint/src/array_into_iter.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -134,9 +134,8 @@ impl<'tcx> LateLintPass<'tcx> for ArrayIntoIter {
134134
Applicability::MachineApplicable,
135135
);
136136
if self.for_expr_span == expr.span {
137-
let expr_span = expr.span.ctxt().outer_expn_data().call_site;
138137
diag.span_suggestion(
139-
receiver_arg.span.shrink_to_hi().to(expr_span.shrink_to_hi()),
138+
receiver_arg.span.shrink_to_hi().to(expr.span.shrink_to_hi()),
140139
"or remove `.into_iter()` to iterate by value",
141140
String::new(),
142141
Applicability::MaybeIncorrect,

0 commit comments

Comments
 (0)