Skip to content

Commit 1f7fb64

Browse files
committedApr 10, 2022
Auto merge of rust-lang#95889 - Dylan-DPC:rollup-1cmywu4, r=Dylan-DPC
Rollup of 7 pull requests Successful merges: - rust-lang#95566 (Avoid duplication of doc comments in `std::char` constants and functions) - rust-lang#95784 (Suggest replacing `typeof(...)` with an actual type) - rust-lang#95807 (Suggest adding a local for vector to fix borrowck errors) - rust-lang#95849 (Check for git submodules in non-git source tree.) - rust-lang#95852 (Fix missing space in lossy provenance cast lint) - rust-lang#95857 (Allow multiple derefs to be splitted in deref_separator) - rust-lang#95868 (rustdoc: Reduce allocations in a `html::markdown` function) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 027a232 + fcfecab commit 1f7fb64

22 files changed

+333
-235
lines changed
 

‎compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs

+31-9
Original file line numberDiff line numberDiff line change
@@ -785,13 +785,22 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
785785
issued_borrow: &BorrowData<'tcx>,
786786
explanation: BorrowExplanation,
787787
) {
788-
let used_in_call =
789-
matches!(explanation, BorrowExplanation::UsedLater(LaterUseKind::Call, _call_span, _));
788+
let used_in_call = matches!(
789+
explanation,
790+
BorrowExplanation::UsedLater(LaterUseKind::Call | LaterUseKind::Other, _call_span, _)
791+
);
790792
if !used_in_call {
791793
debug!("not later used in call");
792794
return;
793795
}
794796

797+
let use_span =
798+
if let BorrowExplanation::UsedLater(LaterUseKind::Other, use_span, _) = explanation {
799+
Some(use_span)
800+
} else {
801+
None
802+
};
803+
795804
let outer_call_loc =
796805
if let TwoPhaseActivation::ActivatedAt(loc) = issued_borrow.activation_location {
797806
loc
@@ -835,7 +844,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
835844
debug!("===> outer_call_loc = {:?}, inner_call_loc = {:?}", outer_call_loc, inner_call_loc);
836845

837846
let inner_call_span = inner_call_term.source_info.span;
838-
let outer_call_span = outer_call_stmt.either(|s| s.source_info, |t| t.source_info).span;
847+
let outer_call_span = match use_span {
848+
Some(span) => span,
849+
None => outer_call_stmt.either(|s| s.source_info, |t| t.source_info).span,
850+
};
839851
if outer_call_span == inner_call_span || !outer_call_span.contains(inner_call_span) {
840852
// FIXME: This stops the suggestion in some cases where it should be emitted.
841853
// Fix the spans for those cases so it's emitted correctly.
@@ -845,8 +857,20 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
845857
);
846858
return;
847859
}
848-
err.span_help(inner_call_span, "try adding a local storing this argument...");
849-
err.span_help(outer_call_span, "...and then using that local as the argument to this call");
860+
err.span_help(
861+
inner_call_span,
862+
&format!(
863+
"try adding a local storing this{}...",
864+
if use_span.is_some() { "" } else { " argument" }
865+
),
866+
);
867+
err.span_help(
868+
outer_call_span,
869+
&format!(
870+
"...and then using that local {}",
871+
if use_span.is_some() { "here" } else { "as the argument to this call" }
872+
),
873+
);
850874
}
851875

852876
fn suggest_split_at_mut_if_applicable(
@@ -1912,10 +1936,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
19121936
} else {
19131937
"cannot assign twice to immutable variable"
19141938
};
1915-
if span != assigned_span {
1916-
if !from_arg {
1917-
err.span_label(assigned_span, format!("first assignment to {}", place_description));
1918-
}
1939+
if span != assigned_span && !from_arg {
1940+
err.span_label(assigned_span, format!("first assignment to {}", place_description));
19191941
}
19201942
if let Some(decl) = local_decl
19211943
&& let Some(name) = local_name

‎compiler/rustc_error_messages/locales/en-US/diagnostics.ftl

+1
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ typeck-functional-record-update-on-non-struct =
6262
6363
typeck-typeof-reserved-keyword-used =
6464
`typeof` is a reserved keyword but unimplemented
65+
.suggestion = consider replacing `typeof(...)` with an actual type
6566
.label = reserved keyword
6667
6768
typeck-return-stmt-outside-of-fn-body =

‎compiler/rustc_mir_transform/src/deref_separator.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ pub fn deref_finder<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
1111
for (i, stmt) in data.statements.iter_mut().enumerate() {
1212
match stmt.kind {
1313
StatementKind::Assign(box (og_place, Rvalue::Ref(region, borrow_knd, place))) => {
14+
let mut place_local = place.local;
15+
let mut last_len = 0;
1416
for (idx, (p_ref, p_elem)) in place.iter_projections().enumerate() {
1517
if p_elem == ProjectionElem::Deref && !p_ref.projection.is_empty() {
1618
// The type that we are derefing.
@@ -23,15 +25,18 @@ pub fn deref_finder<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
2325
patch.add_statement(loc, StatementKind::StorageLive(temp));
2426

2527
// We are adding current p_ref's projections to our
26-
// temp value.
27-
let deref_place =
28-
Place::from(p_ref.local).project_deeper(p_ref.projection, tcx);
28+
// temp value, excluding projections we already covered.
29+
let deref_place = Place::from(place_local)
30+
.project_deeper(&p_ref.projection[last_len..], tcx);
2931
patch.add_assign(
3032
loc,
3133
Place::from(temp),
3234
Rvalue::Use(Operand::Move(deref_place)),
3335
);
3436

37+
place_local = temp;
38+
last_len = p_ref.projection.len();
39+
3540
// We are creating a place by using our temp value's location
3641
// and copying derefed values which we need to create new statement.
3742
let temp_place =
@@ -50,11 +55,6 @@ pub fn deref_finder<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
5055
// Since our job with the temp is done it should be gone
5156
let loc = Location { block: block, statement_index: i + 1 };
5257
patch.add_statement(loc, StatementKind::StorageDead(temp));
53-
54-
// As all projections are off the base projection, if there are
55-
// multiple derefs in the middle of projection, it might cause
56-
// unsoundness, to not let that happen we break the loop.
57-
break;
5858
}
5959
}
6060
}

‎compiler/rustc_typeck/src/astconv/mod.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -2460,8 +2460,16 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
24602460
self.normalize_ty(ast_ty.span, array_ty)
24612461
}
24622462
hir::TyKind::Typeof(ref e) => {
2463-
tcx.sess.emit_err(TypeofReservedKeywordUsed { span: ast_ty.span });
2464-
tcx.type_of(tcx.hir().local_def_id(e.hir_id))
2463+
let ty = tcx.type_of(tcx.hir().local_def_id(e.hir_id));
2464+
let span = ast_ty.span;
2465+
tcx.sess.emit_err(TypeofReservedKeywordUsed {
2466+
span,
2467+
ty,
2468+
opt_sugg: Some((span, Applicability::MachineApplicable))
2469+
.filter(|_| ty.is_suggestable()),
2470+
});
2471+
2472+
ty
24652473
}
24662474
hir::TyKind::Infer => {
24672475
// Infer also appears as the type of arguments or return

‎compiler/rustc_typeck/src/check/cast.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1012,7 +1012,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
10121012
err.help(msg);
10131013
}
10141014
err.help(
1015-
"if you can't comply with strict provenance and need to expose the pointer\
1015+
"if you can't comply with strict provenance and need to expose the pointer \
10161016
provenance you can use `.expose_addr()` instead"
10171017
);
10181018

‎compiler/rustc_typeck/src/errors.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
//! Errors emitted by typeck.
2+
use rustc_errors::Applicability;
23
use rustc_macros::SessionDiagnostic;
4+
use rustc_middle::ty::Ty;
35
use rustc_span::{symbol::Ident, Span, Symbol};
46

57
#[derive(SessionDiagnostic)]
@@ -127,10 +129,13 @@ pub struct FunctionalRecordUpdateOnNonStruct {
127129

128130
#[derive(SessionDiagnostic)]
129131
#[error(code = "E0516", slug = "typeck-typeof-reserved-keyword-used")]
130-
pub struct TypeofReservedKeywordUsed {
132+
pub struct TypeofReservedKeywordUsed<'tcx> {
133+
pub ty: Ty<'tcx>,
131134
#[primary_span]
132135
#[label]
133136
pub span: Span,
137+
#[suggestion_verbose(message = "suggestion", code = "{ty}")]
138+
pub opt_sugg: Option<(Span, Applicability)>,
134139
}
135140

136141
#[derive(SessionDiagnostic)]

‎library/core/src/char/convert.rs

+7-132
Original file line numberDiff line numberDiff line change
@@ -6,97 +6,22 @@ use crate::fmt;
66
use crate::mem::transmute;
77
use crate::str::FromStr;
88

9-
/// Converts a `u32` to a `char`.
10-
///
11-
/// Note that all [`char`]s are valid [`u32`]s, and can be cast to one with
12-
/// `as`:
13-
///
14-
/// ```
15-
/// let c = '💯';
16-
/// let i = c as u32;
17-
///
18-
/// assert_eq!(128175, i);
19-
/// ```
20-
///
21-
/// However, the reverse is not true: not all valid [`u32`]s are valid
22-
/// [`char`]s. `from_u32()` will return `None` if the input is not a valid value
23-
/// for a [`char`].
24-
///
25-
/// For an unsafe version of this function which ignores these checks, see
26-
/// [`from_u32_unchecked`].
27-
///
28-
/// # Examples
29-
///
30-
/// Basic usage:
31-
///
32-
/// ```
33-
/// use std::char;
34-
///
35-
/// let c = char::from_u32(0x2764);
36-
///
37-
/// assert_eq!(Some('❤'), c);
38-
/// ```
39-
///
40-
/// Returning `None` when the input is not a valid [`char`]:
41-
///
42-
/// ```
43-
/// use std::char;
44-
///
45-
/// let c = char::from_u32(0x110000);
46-
///
47-
/// assert_eq!(None, c);
48-
/// ```
49-
#[doc(alias = "chr")]
9+
/// Converts a `u32` to a `char`. See [`char::from_u32`].
5010
#[must_use]
5111
#[inline]
52-
#[stable(feature = "rust1", since = "1.0.0")]
53-
#[rustc_const_unstable(feature = "const_char_convert", issue = "89259")]
54-
pub const fn from_u32(i: u32) -> Option<char> {
12+
pub(super) const fn from_u32(i: u32) -> Option<char> {
5513
// FIXME: once Result::ok is const fn, use it here
5614
match char_try_from_u32(i) {
5715
Ok(c) => Some(c),
5816
Err(_) => None,
5917
}
6018
}
6119

62-
/// Converts a `u32` to a `char`, ignoring validity.
63-
///
64-
/// Note that all [`char`]s are valid [`u32`]s, and can be cast to one with
65-
/// `as`:
66-
///
67-
/// ```
68-
/// let c = '💯';
69-
/// let i = c as u32;
70-
///
71-
/// assert_eq!(128175, i);
72-
/// ```
73-
///
74-
/// However, the reverse is not true: not all valid [`u32`]s are valid
75-
/// [`char`]s. `from_u32_unchecked()` will ignore this, and blindly cast to
76-
/// [`char`], possibly creating an invalid one.
77-
///
78-
/// # Safety
79-
///
80-
/// This function is unsafe, as it may construct invalid `char` values.
81-
///
82-
/// For a safe version of this function, see the [`from_u32`] function.
83-
///
84-
/// # Examples
85-
///
86-
/// Basic usage:
87-
///
88-
/// ```
89-
/// use std::char;
90-
///
91-
/// let c = unsafe { char::from_u32_unchecked(0x2764) };
92-
///
93-
/// assert_eq!('❤', c);
94-
/// ```
20+
/// Converts a `u32` to a `char`, ignoring validity. See [`char::from_u32_unchecked`].
21+
#[rustc_const_unstable(feature = "const_char_convert", issue = "89259")]
9522
#[inline]
9623
#[must_use]
97-
#[stable(feature = "char_from_unchecked", since = "1.5.0")]
98-
#[rustc_const_unstable(feature = "const_char_convert", issue = "89259")]
99-
pub const unsafe fn from_u32_unchecked(i: u32) -> char {
24+
pub(super) const unsafe fn from_u32_unchecked(i: u32) -> char {
10025
// SAFETY: the caller must guarantee that `i` is a valid char value.
10126
if cfg!(debug_assertions) { char::from_u32(i).unwrap() } else { unsafe { transmute(i) } }
10227
}
@@ -317,60 +242,10 @@ impl fmt::Display for CharTryFromError {
317242
}
318243
}
319244

320-
/// Converts a digit in the given radix to a `char`.
321-
///
322-
/// A 'radix' here is sometimes also called a 'base'. A radix of two
323-
/// indicates a binary number, a radix of ten, decimal, and a radix of
324-
/// sixteen, hexadecimal, to give some common values. Arbitrary
325-
/// radices are supported.
326-
///
327-
/// `from_digit()` will return `None` if the input is not a digit in
328-
/// the given radix.
329-
///
330-
/// # Panics
331-
///
332-
/// Panics if given a radix larger than 36.
333-
///
334-
/// # Examples
335-
///
336-
/// Basic usage:
337-
///
338-
/// ```
339-
/// use std::char;
340-
///
341-
/// let c = char::from_digit(4, 10);
342-
///
343-
/// assert_eq!(Some('4'), c);
344-
///
345-
/// // Decimal 11 is a single digit in base 16
346-
/// let c = char::from_digit(11, 16);
347-
///
348-
/// assert_eq!(Some('b'), c);
349-
/// ```
350-
///
351-
/// Returning `None` when the input is not a digit:
352-
///
353-
/// ```
354-
/// use std::char;
355-
///
356-
/// let c = char::from_digit(20, 10);
357-
///
358-
/// assert_eq!(None, c);
359-
/// ```
360-
///
361-
/// Passing a large radix, causing a panic:
362-
///
363-
/// ```should_panic
364-
/// use std::char;
365-
///
366-
/// // this panics
367-
/// let c = char::from_digit(1, 37);
368-
/// ```
245+
/// Converts a digit in the given radix to a `char`. See [`char::from_digit`].
369246
#[inline]
370247
#[must_use]
371-
#[stable(feature = "rust1", since = "1.0.0")]
372-
#[rustc_const_unstable(feature = "const_char_convert", issue = "89259")]
373-
pub const fn from_digit(num: u32, radix: u32) -> Option<char> {
248+
pub(super) const fn from_digit(num: u32, radix: u32) -> Option<char> {
374249
if radix > 36 {
375250
panic!("from_digit: radix is too high (maximum 36)");
376251
}

‎library/core/src/char/decode.rs

+2-47
Original file line numberDiff line numberDiff line change
@@ -30,54 +30,9 @@ pub struct DecodeUtf16Error {
3030
}
3131

3232
/// Creates an iterator over the UTF-16 encoded code points in `iter`,
33-
/// returning unpaired surrogates as `Err`s.
34-
///
35-
/// # Examples
36-
///
37-
/// Basic usage:
38-
///
39-
/// ```
40-
/// use std::char::decode_utf16;
41-
///
42-
/// // 𝄞mus<invalid>ic<invalid>
43-
/// let v = [
44-
/// 0xD834, 0xDD1E, 0x006d, 0x0075, 0x0073, 0xDD1E, 0x0069, 0x0063, 0xD834,
45-
/// ];
46-
///
47-
/// assert_eq!(
48-
/// decode_utf16(v.iter().cloned())
49-
/// .map(|r| r.map_err(|e| e.unpaired_surrogate()))
50-
/// .collect::<Vec<_>>(),
51-
/// vec![
52-
/// Ok('𝄞'),
53-
/// Ok('m'), Ok('u'), Ok('s'),
54-
/// Err(0xDD1E),
55-
/// Ok('i'), Ok('c'),
56-
/// Err(0xD834)
57-
/// ]
58-
/// );
59-
/// ```
60-
///
61-
/// A lossy decoder can be obtained by replacing `Err` results with the replacement character:
62-
///
63-
/// ```
64-
/// use std::char::{decode_utf16, REPLACEMENT_CHARACTER};
65-
///
66-
/// // 𝄞mus<invalid>ic<invalid>
67-
/// let v = [
68-
/// 0xD834, 0xDD1E, 0x006d, 0x0075, 0x0073, 0xDD1E, 0x0069, 0x0063, 0xD834,
69-
/// ];
70-
///
71-
/// assert_eq!(
72-
/// decode_utf16(v.iter().cloned())
73-
/// .map(|r| r.unwrap_or(REPLACEMENT_CHARACTER))
74-
/// .collect::<String>(),
75-
/// "𝄞mus�ic�"
76-
/// );
77-
/// ```
78-
#[stable(feature = "decode_utf16", since = "1.9.0")]
33+
/// returning unpaired surrogates as `Err`s. See [`char::decode_utf16`].
7934
#[inline]
80-
pub fn decode_utf16<I: IntoIterator<Item = u16>>(iter: I) -> DecodeUtf16<I::IntoIter> {
35+
pub(super) fn decode_utf16<I: IntoIterator<Item = u16>>(iter: I) -> DecodeUtf16<I::IntoIter> {
8136
DecodeUtf16 { iter: iter.into_iter(), buf: None }
8237
}
8338

‎library/core/src/char/mod.rs

+45-24
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,12 @@ mod decode;
2323
mod methods;
2424

2525
// stable re-exports
26-
#[stable(feature = "char_from_unchecked", since = "1.5.0")]
27-
pub use self::convert::from_u32_unchecked;
2826
#[stable(feature = "try_from", since = "1.34.0")]
2927
pub use self::convert::CharTryFromError;
3028
#[stable(feature = "char_from_str", since = "1.20.0")]
3129
pub use self::convert::ParseCharError;
32-
#[stable(feature = "rust1", since = "1.0.0")]
33-
pub use self::convert::{from_digit, from_u32};
3430
#[stable(feature = "decode_utf16", since = "1.9.0")]
35-
pub use self::decode::{decode_utf16, DecodeUtf16, DecodeUtf16Error};
36-
#[stable(feature = "unicode_version", since = "1.45.0")]
37-
pub use crate::unicode::UNICODE_VERSION;
31+
pub use self::decode::{DecodeUtf16, DecodeUtf16Error};
3832

3933
// perma-unstable re-exports
4034
#[unstable(feature = "char_internals", reason = "exposed only for libstd", issue = "none")]
@@ -89,30 +83,57 @@ const MAX_THREE_B: u32 = 0x10000;
8983
Cn Unassigned a reserved unassigned code point or a noncharacter
9084
*/
9185

92-
/// The highest valid code point a `char` can have, `'\u{10FFFF}'`.
93-
///
94-
/// # Examples
95-
///
96-
/// ```
97-
/// # fn something_which_returns_char() -> char { 'a' }
98-
/// let c: char = something_which_returns_char();
99-
/// assert!(c <= char::MAX);
100-
///
101-
/// let value_at_max = char::MAX as u32;
102-
/// assert_eq!(char::from_u32(value_at_max), Some('\u{10FFFF}'));
103-
/// assert_eq!(char::from_u32(value_at_max + 1), None);
104-
/// ```
86+
/// The highest valid code point a `char` can have, `'\u{10FFFF}'`. Use [`char::MAX`] instead.
10587
#[stable(feature = "rust1", since = "1.0.0")]
10688
pub const MAX: char = char::MAX;
10789

10890
/// `U+FFFD REPLACEMENT CHARACTER` (�) is used in Unicode to represent a
109-
/// decoding error.
110-
///
111-
/// It can occur, for example, when giving ill-formed UTF-8 bytes to
112-
/// [`String::from_utf8_lossy`](../../std/string/struct.String.html#method.from_utf8_lossy).
91+
/// decoding error. Use [`char::REPLACEMENT_CHARACTER`] instead.
11392
#[stable(feature = "decode_utf16", since = "1.9.0")]
11493
pub const REPLACEMENT_CHARACTER: char = char::REPLACEMENT_CHARACTER;
11594

95+
/// The version of [Unicode](https://www.unicode.org/) that the Unicode parts of
96+
/// `char` and `str` methods are based on. Use [`char::UNICODE_VERSION`] instead.
97+
#[stable(feature = "unicode_version", since = "1.45.0")]
98+
pub const UNICODE_VERSION: (u8, u8, u8) = char::UNICODE_VERSION;
99+
100+
/// Creates an iterator over the UTF-16 encoded code points in `iter`, returning
101+
/// unpaired surrogates as `Err`s. Use [`char::decode_utf16`] instead.
102+
#[stable(feature = "decode_utf16", since = "1.9.0")]
103+
#[inline]
104+
pub fn decode_utf16<I: IntoIterator<Item = u16>>(iter: I) -> DecodeUtf16<I::IntoIter> {
105+
self::decode::decode_utf16(iter)
106+
}
107+
108+
/// Converts a `u32` to a `char`. Use [`char::from_u32`] instead.
109+
#[stable(feature = "rust1", since = "1.0.0")]
110+
#[rustc_const_unstable(feature = "const_char_convert", issue = "89259")]
111+
#[must_use]
112+
#[inline]
113+
pub const fn from_u32(i: u32) -> Option<char> {
114+
self::convert::from_u32(i)
115+
}
116+
117+
/// Converts a `u32` to a `char`, ignoring validity. Use [`char::from_u32_unchecked`].
118+
/// instead.
119+
#[stable(feature = "char_from_unchecked", since = "1.5.0")]
120+
#[rustc_const_unstable(feature = "const_char_convert", issue = "89259")]
121+
#[must_use]
122+
#[inline]
123+
pub const unsafe fn from_u32_unchecked(i: u32) -> char {
124+
// SAFETY: the safety contract must be upheld by the caller.
125+
unsafe { self::convert::from_u32_unchecked(i) }
126+
}
127+
128+
/// Converts a digit in the given radix to a `char`. Use [`char::from_digit`] instead.
129+
#[stable(feature = "rust1", since = "1.0.0")]
130+
#[rustc_const_unstable(feature = "const_char_convert", issue = "89259")]
131+
#[must_use]
132+
#[inline]
133+
pub const fn from_digit(num: u32, radix: u32) -> Option<char> {
134+
self::convert::from_digit(num, radix)
135+
}
136+
116137
/// Returns an iterator that yields the hexadecimal Unicode escape of a
117138
/// character, as `char`s.
118139
///

‎src/bootstrap/bootstrap.py

+13-2
Original file line numberDiff line numberDiff line change
@@ -1097,8 +1097,19 @@ def update_submodule(self, module, checked_out, recorded_submodules):
10971097

10981098
def update_submodules(self):
10991099
"""Update submodules"""
1100-
if (not os.path.exists(os.path.join(self.rust_root, ".git"))) or \
1101-
self.get_toml('submodules') == "false":
1100+
has_git = os.path.exists(os.path.join(self.rust_root, ".git"))
1101+
# This just arbitrarily checks for cargo, but any workspace member in
1102+
# a submodule would work.
1103+
has_submodules = os.path.exists(os.path.join(self.rust_root, "src/tools/cargo/Cargo.toml"))
1104+
if not has_git and not has_submodules:
1105+
print("This is not a git repository, and the requisite git submodules were not found.")
1106+
print("If you downloaded the source from https://github.com/rust-lang/rust/releases,")
1107+
print("those sources will not work. Instead, consider downloading from the source")
1108+
print("releases linked at")
1109+
print("https://forge.rust-lang.org/infra/other-installation-methods.html#source-code")
1110+
print("or clone the repository at https://github.com/rust-lang/rust/.")
1111+
raise SystemExit(1)
1112+
if not has_git or self.get_toml('submodules') == "false":
11021113
return
11031114

11041115
default_encoding = sys.getdefaultencoding()

‎src/librustdoc/html/markdown.rs

+5-7
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> {
251251
}
252252
}
253253
let lines = origtext.lines().filter_map(|l| map_line(l).for_html());
254-
let text = lines.collect::<Vec<Cow<'_, str>>>().join("\n");
254+
let text = lines.intersperse("\n".into()).collect::<String>();
255255

256256
let parse_result = match kind {
257257
CodeBlockKind::Fenced(ref lang) => {
@@ -291,15 +291,13 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> {
291291
let test = origtext
292292
.lines()
293293
.map(|l| map_line(l).for_code())
294-
.collect::<Vec<Cow<'_, str>>>()
295-
.join("\n");
294+
.intersperse("\n".into())
295+
.collect::<String>();
296296
let krate = krate.as_ref().map(|s| &**s);
297297
let (test, _, _) =
298298
doctest::make_test(&test, krate, false, &Default::default(), edition, None);
299299
let channel = if test.contains("#![feature(") { "&amp;version=nightly" } else { "" };
300300

301-
let edition_string = format!("&amp;edition={}", edition);
302-
303301
// These characters don't need to be escaped in a URI.
304302
// FIXME: use a library function for percent encoding.
305303
fn dont_escape(c: u8) -> bool {
@@ -325,8 +323,8 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> {
325323
}
326324
}
327325
Some(format!(
328-
r#"<a class="test-arrow" target="_blank" href="{}?code={}{}{}">Run</a>"#,
329-
url, test_escaped, channel, edition_string
326+
r#"<a class="test-arrow" target="_blank" href="{}?code={}{}&amp;edition={}">Run</a>"#,
327+
url, test_escaped, channel, edition,
330328
))
331329
});
332330

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
- // MIR for `main` before Derefer
2+
+ // MIR for `main` after Derefer
3+
4+
fn main() -> () {
5+
let mut _0: (); // return place in scope 0 at $DIR/derefer_test_multiple.rs:2:12: 2:12
6+
let mut _1: (i32, i32); // in scope 0 at $DIR/derefer_test_multiple.rs:3:9: 3:14
7+
let mut _3: &mut (i32, i32); // in scope 0 at $DIR/derefer_test_multiple.rs:4:22: 4:28
8+
let mut _5: &mut (i32, &mut (i32, i32)); // in scope 0 at $DIR/derefer_test_multiple.rs:5:22: 5:28
9+
let mut _7: &mut (i32, &mut (i32, &mut (i32, i32))); // in scope 0 at $DIR/derefer_test_multiple.rs:6:22: 6:28
10+
+ let mut _10: &mut (i32, &mut (i32, &mut (i32, i32))); // in scope 0 at $DIR/derefer_test_multiple.rs:7:13: 7:30
11+
+ let mut _11: &mut (i32, &mut (i32, i32)); // in scope 0 at $DIR/derefer_test_multiple.rs:7:13: 7:30
12+
+ let mut _12: &mut (i32, i32); // in scope 0 at $DIR/derefer_test_multiple.rs:7:13: 7:30
13+
+ let mut _13: &mut (i32, &mut (i32, &mut (i32, i32))); // in scope 0 at $DIR/derefer_test_multiple.rs:8:13: 8:30
14+
+ let mut _14: &mut (i32, &mut (i32, i32)); // in scope 0 at $DIR/derefer_test_multiple.rs:8:13: 8:30
15+
+ let mut _15: &mut (i32, i32); // in scope 0 at $DIR/derefer_test_multiple.rs:8:13: 8:30
16+
scope 1 {
17+
debug a => _1; // in scope 1 at $DIR/derefer_test_multiple.rs:3:9: 3:14
18+
let mut _2: (i32, &mut (i32, i32)); // in scope 1 at $DIR/derefer_test_multiple.rs:4:9: 4:14
19+
scope 2 {
20+
debug b => _2; // in scope 2 at $DIR/derefer_test_multiple.rs:4:9: 4:14
21+
let mut _4: (i32, &mut (i32, &mut (i32, i32))); // in scope 2 at $DIR/derefer_test_multiple.rs:5:9: 5:14
22+
scope 3 {
23+
debug c => _4; // in scope 3 at $DIR/derefer_test_multiple.rs:5:9: 5:14
24+
let mut _6: (i32, &mut (i32, &mut (i32, &mut (i32, i32)))); // in scope 3 at $DIR/derefer_test_multiple.rs:6:9: 6:14
25+
scope 4 {
26+
debug d => _6; // in scope 4 at $DIR/derefer_test_multiple.rs:6:9: 6:14
27+
let _8: &mut i32; // in scope 4 at $DIR/derefer_test_multiple.rs:7:9: 7:10
28+
scope 5 {
29+
debug x => _8; // in scope 5 at $DIR/derefer_test_multiple.rs:7:9: 7:10
30+
let _9: &mut i32; // in scope 5 at $DIR/derefer_test_multiple.rs:8:9: 8:10
31+
scope 6 {
32+
debug y => _9; // in scope 6 at $DIR/derefer_test_multiple.rs:8:9: 8:10
33+
}
34+
}
35+
}
36+
}
37+
}
38+
}
39+
40+
bb0: {
41+
StorageLive(_1); // scope 0 at $DIR/derefer_test_multiple.rs:3:9: 3:14
42+
(_1.0: i32) = const 42_i32; // scope 0 at $DIR/derefer_test_multiple.rs:3:17: 3:25
43+
(_1.1: i32) = const 43_i32; // scope 0 at $DIR/derefer_test_multiple.rs:3:17: 3:25
44+
StorageLive(_2); // scope 1 at $DIR/derefer_test_multiple.rs:4:9: 4:14
45+
StorageLive(_3); // scope 1 at $DIR/derefer_test_multiple.rs:4:22: 4:28
46+
_3 = &mut _1; // scope 1 at $DIR/derefer_test_multiple.rs:4:22: 4:28
47+
(_2.0: i32) = const 99_i32; // scope 1 at $DIR/derefer_test_multiple.rs:4:17: 4:29
48+
(_2.1: &mut (i32, i32)) = move _3; // scope 1 at $DIR/derefer_test_multiple.rs:4:17: 4:29
49+
StorageDead(_3); // scope 1 at $DIR/derefer_test_multiple.rs:4:28: 4:29
50+
StorageLive(_4); // scope 2 at $DIR/derefer_test_multiple.rs:5:9: 5:14
51+
StorageLive(_5); // scope 2 at $DIR/derefer_test_multiple.rs:5:22: 5:28
52+
_5 = &mut _2; // scope 2 at $DIR/derefer_test_multiple.rs:5:22: 5:28
53+
(_4.0: i32) = const 11_i32; // scope 2 at $DIR/derefer_test_multiple.rs:5:17: 5:29
54+
(_4.1: &mut (i32, &mut (i32, i32))) = move _5; // scope 2 at $DIR/derefer_test_multiple.rs:5:17: 5:29
55+
StorageDead(_5); // scope 2 at $DIR/derefer_test_multiple.rs:5:28: 5:29
56+
StorageLive(_6); // scope 3 at $DIR/derefer_test_multiple.rs:6:9: 6:14
57+
StorageLive(_7); // scope 3 at $DIR/derefer_test_multiple.rs:6:22: 6:28
58+
_7 = &mut _4; // scope 3 at $DIR/derefer_test_multiple.rs:6:22: 6:28
59+
(_6.0: i32) = const 13_i32; // scope 3 at $DIR/derefer_test_multiple.rs:6:17: 6:29
60+
(_6.1: &mut (i32, &mut (i32, &mut (i32, i32)))) = move _7; // scope 3 at $DIR/derefer_test_multiple.rs:6:17: 6:29
61+
StorageDead(_7); // scope 3 at $DIR/derefer_test_multiple.rs:6:28: 6:29
62+
StorageLive(_8); // scope 4 at $DIR/derefer_test_multiple.rs:7:9: 7:10
63+
- _8 = &mut ((*((*((*(_6.1: &mut (i32, &mut (i32, &mut (i32, i32))))).1: &mut (i32, &mut (i32, i32)))).1: &mut (i32, i32))).1: i32); // scope 4 at $DIR/derefer_test_multiple.rs:7:13: 7:30
64+
+ StorageLive(_10); // scope 4 at $DIR/derefer_test_multiple.rs:7:13: 7:30
65+
+ _10 = move (_6.1: &mut (i32, &mut (i32, &mut (i32, i32)))); // scope 4 at $DIR/derefer_test_multiple.rs:7:13: 7:30
66+
+ StorageLive(_11); // scope 4 at $DIR/derefer_test_multiple.rs:7:13: 7:30
67+
+ _11 = move ((*_10).1: &mut (i32, &mut (i32, i32))); // scope 4 at $DIR/derefer_test_multiple.rs:7:13: 7:30
68+
+ StorageLive(_12); // scope 4 at $DIR/derefer_test_multiple.rs:7:13: 7:30
69+
+ _12 = move ((*_11).1: &mut (i32, i32)); // scope 4 at $DIR/derefer_test_multiple.rs:7:13: 7:30
70+
+ _8 = &mut ((*_12).1: i32); // scope 4 at $DIR/derefer_test_multiple.rs:7:13: 7:30
71+
+ StorageDead(_10); // scope 5 at $DIR/derefer_test_multiple.rs:8:9: 8:10
72+
+ StorageDead(_11); // scope 5 at $DIR/derefer_test_multiple.rs:8:9: 8:10
73+
+ StorageDead(_12); // scope 5 at $DIR/derefer_test_multiple.rs:8:9: 8:10
74+
StorageLive(_9); // scope 5 at $DIR/derefer_test_multiple.rs:8:9: 8:10
75+
- _9 = &mut ((*((*((*(_6.1: &mut (i32, &mut (i32, &mut (i32, i32))))).1: &mut (i32, &mut (i32, i32)))).1: &mut (i32, i32))).1: i32); // scope 5 at $DIR/derefer_test_multiple.rs:8:13: 8:30
76+
+ StorageLive(_13); // scope 5 at $DIR/derefer_test_multiple.rs:8:13: 8:30
77+
+ _13 = move (_6.1: &mut (i32, &mut (i32, &mut (i32, i32)))); // scope 5 at $DIR/derefer_test_multiple.rs:8:13: 8:30
78+
+ StorageLive(_14); // scope 5 at $DIR/derefer_test_multiple.rs:8:13: 8:30
79+
+ _14 = move ((*_13).1: &mut (i32, &mut (i32, i32))); // scope 5 at $DIR/derefer_test_multiple.rs:8:13: 8:30
80+
+ StorageLive(_15); // scope 5 at $DIR/derefer_test_multiple.rs:8:13: 8:30
81+
+ _15 = move ((*_14).1: &mut (i32, i32)); // scope 5 at $DIR/derefer_test_multiple.rs:8:13: 8:30
82+
+ _9 = &mut ((*_15).1: i32); // scope 5 at $DIR/derefer_test_multiple.rs:8:13: 8:30
83+
+ StorageDead(_13); // scope 0 at $DIR/derefer_test_multiple.rs:2:12: 9:2
84+
+ StorageDead(_14); // scope 0 at $DIR/derefer_test_multiple.rs:2:12: 9:2
85+
+ StorageDead(_15); // scope 0 at $DIR/derefer_test_multiple.rs:2:12: 9:2
86+
_0 = const (); // scope 0 at $DIR/derefer_test_multiple.rs:2:12: 9:2
87+
StorageDead(_9); // scope 5 at $DIR/derefer_test_multiple.rs:9:1: 9:2
88+
StorageDead(_8); // scope 4 at $DIR/derefer_test_multiple.rs:9:1: 9:2
89+
StorageDead(_6); // scope 3 at $DIR/derefer_test_multiple.rs:9:1: 9:2
90+
StorageDead(_4); // scope 2 at $DIR/derefer_test_multiple.rs:9:1: 9:2
91+
StorageDead(_2); // scope 1 at $DIR/derefer_test_multiple.rs:9:1: 9:2
92+
StorageDead(_1); // scope 0 at $DIR/derefer_test_multiple.rs:9:1: 9:2
93+
return; // scope 0 at $DIR/derefer_test_multiple.rs:9:2: 9:2
94+
+ }
95+
+
96+
+ bb1 (cleanup): {
97+
+ resume; // scope 0 at $DIR/derefer_test_multiple.rs:2:1: 9:2
98+
}
99+
}
100+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// EMIT_MIR derefer_test_multiple.main.Derefer.diff
2+
fn main () {
3+
let mut a = (42, 43);
4+
let mut b = (99, &mut a);
5+
let mut c = (11, &mut b);
6+
let mut d = (13, &mut c);
7+
let x = &mut (*d.1).1.1.1;
8+
let y = &mut (*d.1).1.1.1;
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
fn main() {
2+
let mut vec = vec![0u32; 420];
3+
vec[vec.len() - 1] = 123; //~ ERROR cannot borrow `vec` as immutable because it is also borrowed as mutable
4+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
error[E0502]: cannot borrow `vec` as immutable because it is also borrowed as mutable
2+
--> $DIR/suggest-local-var-for-vector.rs:3:9
3+
|
4+
LL | vec[vec.len() - 1] = 123;
5+
| ----^^^^^^^^^-----
6+
| | |
7+
| | immutable borrow occurs here
8+
| mutable borrow occurs here
9+
| mutable borrow later used here
10+
|
11+
help: try adding a local storing this...
12+
--> $DIR/suggest-local-var-for-vector.rs:3:9
13+
|
14+
LL | vec[vec.len() - 1] = 123;
15+
| ^^^^^^^^^
16+
help: ...and then using that local here
17+
--> $DIR/suggest-local-var-for-vector.rs:3:5
18+
|
19+
LL | vec[vec.len() - 1] = 123;
20+
| ^^^^^^^^^^^^^^^^^^
21+
22+
error: aborting due to previous error
23+
24+
For more information about this error, try `rustc --explain E0502`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
fn main() {
2+
let mut vec = vec![0u32; 420];
3+
vec[vec.len() - 1] = 123; //~ ERROR cannot borrow `vec` as immutable because it is also borrowed as mutable
4+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
error[E0502]: cannot borrow `vec` as immutable because it is also borrowed as mutable
2+
--> $DIR/suggest-storing-local-var-for-vector.rs:3:9
3+
|
4+
LL | vec[vec.len() - 1] = 123;
5+
| ----^^^^^^^^^-----
6+
| | |
7+
| | immutable borrow occurs here
8+
| mutable borrow occurs here
9+
| mutable borrow later used here
10+
|
11+
help: try adding a local storing this...
12+
--> $DIR/suggest-storing-local-var-for-vector.rs:3:9
13+
|
14+
LL | vec[vec.len() - 1] = 123;
15+
| ^^^^^^^^^
16+
help: ...and then using that local here
17+
--> $DIR/suggest-storing-local-var-for-vector.rs:3:5
18+
|
19+
LL | vec[vec.len() - 1] = 123;
20+
| ^^^^^^^^^^^^^^^^^^
21+
22+
error: aborting due to previous error
23+
24+
For more information about this error, try `rustc --explain E0502`.

‎src/test/ui/borrowck/two-phase-nonrecv-autoref.nll.stderr

+22
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,17 @@ LL | i[i[3]] = 4;
5454
| | immutable borrow occurs here
5555
| mutable borrow occurs here
5656
| mutable borrow later used here
57+
|
58+
help: try adding a local storing this...
59+
--> $DIR/two-phase-nonrecv-autoref.rs:138:7
60+
|
61+
LL | i[i[3]] = 4;
62+
| ^^^^
63+
help: ...and then using that local here
64+
--> $DIR/two-phase-nonrecv-autoref.rs:138:5
65+
|
66+
LL | i[i[3]] = 4;
67+
| ^^^^^^^
5768

5869
error[E0502]: cannot borrow `i` as immutable because it is also borrowed as mutable
5970
--> $DIR/two-phase-nonrecv-autoref.rs:143:7
@@ -64,6 +75,17 @@ LL | i[i[3]] = i[4];
6475
| | immutable borrow occurs here
6576
| mutable borrow occurs here
6677
| mutable borrow later used here
78+
|
79+
help: try adding a local storing this...
80+
--> $DIR/two-phase-nonrecv-autoref.rs:143:7
81+
|
82+
LL | i[i[3]] = i[4];
83+
| ^^^^
84+
help: ...and then using that local here
85+
--> $DIR/two-phase-nonrecv-autoref.rs:143:5
86+
|
87+
LL | i[i[3]] = i[4];
88+
| ^^^^^^^
6789

6890
error: aborting due to 7 previous errors
6991

‎src/test/ui/error-codes/E0516.stderr

+5
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@ error[E0516]: `typeof` is a reserved keyword but unimplemented
33
|
44
LL | let x: typeof(92) = 92;
55
| ^^^^^^^^^^ reserved keyword
6+
|
7+
help: consider replacing `typeof(...)` with an actual type
8+
|
9+
LL | let x: i32 = 92;
10+
| ~~~
611

712
error: aborting due to previous error
813

‎src/test/ui/issues/issue-29184.stderr

+5
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@ error[E0516]: `typeof` is a reserved keyword but unimplemented
33
|
44
LL | let x: typeof(92) = 92;
55
| ^^^^^^^^^^ reserved keyword
6+
|
7+
help: consider replacing `typeof(...)` with an actual type
8+
|
9+
LL | let x: i32 = 92;
10+
| ~~~
611

712
error: aborting due to previous error
813

‎src/test/ui/lint/lint-strict-provenance-lossy-casts.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,15 @@ note: the lint level is defined here
99
|
1010
LL | #![deny(lossy_provenance_casts)]
1111
| ^^^^^^^^^^^^^^^^^^^^^^
12-
= help: if you can't comply with strict provenance and need to expose the pointerprovenance you can use `.expose_addr()` instead
12+
= help: if you can't comply with strict provenance and need to expose the pointer provenance you can use `.expose_addr()` instead
1313

1414
error: under strict provenance it is considered bad style to cast pointer `*const u8` to integer `u32`
1515
--> $DIR/lint-strict-provenance-lossy-casts.rs:9:22
1616
|
1717
LL | let addr_32bit = &x as *const u8 as u32;
1818
| ^^^^^^^^^^^^^^^^^^^^^^ help: use `.addr()` to obtain the address of a pointer: `(&x as *const u8).addr() as u32`
1919
|
20-
= help: if you can't comply with strict provenance and need to expose the pointerprovenance you can use `.expose_addr()` instead
20+
= help: if you can't comply with strict provenance and need to expose the pointer provenance you can use `.expose_addr()` instead
2121

2222
error: aborting due to 2 previous errors
2323

‎src/test/ui/typeof/type_mismatch.stderr

+5
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@ error[E0516]: `typeof` is a reserved keyword but unimplemented
33
|
44
LL | let b: typeof(a) = 1i8;
55
| ^^^^^^^^^ reserved keyword
6+
|
7+
help: consider replacing `typeof(...)` with an actual type
8+
|
9+
LL | let b: u8 = 1i8;
10+
| ~~
611

712
error[E0308]: mismatched types
813
--> $DIR/type_mismatch.rs:5:24

0 commit comments

Comments
 (0)
Please sign in to comment.