Auto merge of #95889 - Dylan-DPC:rollup-1cmywu4, r=Dylan-DPC
Rollup of 7 pull requests Successful merges: - #95566 (Avoid duplication of doc comments in `std::char` constants and functions) - #95784 (Suggest replacing `typeof(...)` with an actual type) - #95807 (Suggest adding a local for vector to fix borrowck errors) - #95849 (Check for git submodules in non-git source tree.) - #95852 (Fix missing space in lossy provenance cast lint) - #95857 (Allow multiple derefs to be splitted in deref_separator) - #95868 (rustdoc: Reduce allocations in a `html::markdown` function) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
1f7fb6413d
22 changed files with 333 additions and 235 deletions
|
@ -785,13 +785,22 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
issued_borrow: &BorrowData<'tcx>,
|
issued_borrow: &BorrowData<'tcx>,
|
||||||
explanation: BorrowExplanation,
|
explanation: BorrowExplanation,
|
||||||
) {
|
) {
|
||||||
let used_in_call =
|
let used_in_call = matches!(
|
||||||
matches!(explanation, BorrowExplanation::UsedLater(LaterUseKind::Call, _call_span, _));
|
explanation,
|
||||||
|
BorrowExplanation::UsedLater(LaterUseKind::Call | LaterUseKind::Other, _call_span, _)
|
||||||
|
);
|
||||||
if !used_in_call {
|
if !used_in_call {
|
||||||
debug!("not later used in call");
|
debug!("not later used in call");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let use_span =
|
||||||
|
if let BorrowExplanation::UsedLater(LaterUseKind::Other, use_span, _) = explanation {
|
||||||
|
Some(use_span)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
let outer_call_loc =
|
let outer_call_loc =
|
||||||
if let TwoPhaseActivation::ActivatedAt(loc) = issued_borrow.activation_location {
|
if let TwoPhaseActivation::ActivatedAt(loc) = issued_borrow.activation_location {
|
||||||
loc
|
loc
|
||||||
|
@ -835,7 +844,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
debug!("===> outer_call_loc = {:?}, inner_call_loc = {:?}", outer_call_loc, inner_call_loc);
|
debug!("===> outer_call_loc = {:?}, inner_call_loc = {:?}", outer_call_loc, inner_call_loc);
|
||||||
|
|
||||||
let inner_call_span = inner_call_term.source_info.span;
|
let inner_call_span = inner_call_term.source_info.span;
|
||||||
let outer_call_span = outer_call_stmt.either(|s| s.source_info, |t| t.source_info).span;
|
let outer_call_span = match use_span {
|
||||||
|
Some(span) => span,
|
||||||
|
None => outer_call_stmt.either(|s| s.source_info, |t| t.source_info).span,
|
||||||
|
};
|
||||||
if outer_call_span == inner_call_span || !outer_call_span.contains(inner_call_span) {
|
if outer_call_span == inner_call_span || !outer_call_span.contains(inner_call_span) {
|
||||||
// FIXME: This stops the suggestion in some cases where it should be emitted.
|
// FIXME: This stops the suggestion in some cases where it should be emitted.
|
||||||
// Fix the spans for those cases so it's emitted correctly.
|
// Fix the spans for those cases so it's emitted correctly.
|
||||||
|
@ -845,8 +857,20 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
err.span_help(inner_call_span, "try adding a local storing this argument...");
|
err.span_help(
|
||||||
err.span_help(outer_call_span, "...and then using that local as the argument to this call");
|
inner_call_span,
|
||||||
|
&format!(
|
||||||
|
"try adding a local storing this{}...",
|
||||||
|
if use_span.is_some() { "" } else { " argument" }
|
||||||
|
),
|
||||||
|
);
|
||||||
|
err.span_help(
|
||||||
|
outer_call_span,
|
||||||
|
&format!(
|
||||||
|
"...and then using that local {}",
|
||||||
|
if use_span.is_some() { "here" } else { "as the argument to this call" }
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn suggest_split_at_mut_if_applicable(
|
fn suggest_split_at_mut_if_applicable(
|
||||||
|
@ -1912,10 +1936,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
} else {
|
} else {
|
||||||
"cannot assign twice to immutable variable"
|
"cannot assign twice to immutable variable"
|
||||||
};
|
};
|
||||||
if span != assigned_span {
|
if span != assigned_span && !from_arg {
|
||||||
if !from_arg {
|
err.span_label(assigned_span, format!("first assignment to {}", place_description));
|
||||||
err.span_label(assigned_span, format!("first assignment to {}", place_description));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if let Some(decl) = local_decl
|
if let Some(decl) = local_decl
|
||||||
&& let Some(name) = local_name
|
&& let Some(name) = local_name
|
||||||
|
|
|
@ -62,6 +62,7 @@ typeck-functional-record-update-on-non-struct =
|
||||||
|
|
||||||
typeck-typeof-reserved-keyword-used =
|
typeck-typeof-reserved-keyword-used =
|
||||||
`typeof` is a reserved keyword but unimplemented
|
`typeof` is a reserved keyword but unimplemented
|
||||||
|
.suggestion = consider replacing `typeof(...)` with an actual type
|
||||||
.label = reserved keyword
|
.label = reserved keyword
|
||||||
|
|
||||||
typeck-return-stmt-outside-of-fn-body =
|
typeck-return-stmt-outside-of-fn-body =
|
||||||
|
|
|
@ -11,6 +11,8 @@ pub fn deref_finder<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||||
for (i, stmt) in data.statements.iter_mut().enumerate() {
|
for (i, stmt) in data.statements.iter_mut().enumerate() {
|
||||||
match stmt.kind {
|
match stmt.kind {
|
||||||
StatementKind::Assign(box (og_place, Rvalue::Ref(region, borrow_knd, place))) => {
|
StatementKind::Assign(box (og_place, Rvalue::Ref(region, borrow_knd, place))) => {
|
||||||
|
let mut place_local = place.local;
|
||||||
|
let mut last_len = 0;
|
||||||
for (idx, (p_ref, p_elem)) in place.iter_projections().enumerate() {
|
for (idx, (p_ref, p_elem)) in place.iter_projections().enumerate() {
|
||||||
if p_elem == ProjectionElem::Deref && !p_ref.projection.is_empty() {
|
if p_elem == ProjectionElem::Deref && !p_ref.projection.is_empty() {
|
||||||
// The type that we are derefing.
|
// The type that we are derefing.
|
||||||
|
@ -23,15 +25,18 @@ pub fn deref_finder<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||||
patch.add_statement(loc, StatementKind::StorageLive(temp));
|
patch.add_statement(loc, StatementKind::StorageLive(temp));
|
||||||
|
|
||||||
// We are adding current p_ref's projections to our
|
// We are adding current p_ref's projections to our
|
||||||
// temp value.
|
// temp value, excluding projections we already covered.
|
||||||
let deref_place =
|
let deref_place = Place::from(place_local)
|
||||||
Place::from(p_ref.local).project_deeper(p_ref.projection, tcx);
|
.project_deeper(&p_ref.projection[last_len..], tcx);
|
||||||
patch.add_assign(
|
patch.add_assign(
|
||||||
loc,
|
loc,
|
||||||
Place::from(temp),
|
Place::from(temp),
|
||||||
Rvalue::Use(Operand::Move(deref_place)),
|
Rvalue::Use(Operand::Move(deref_place)),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
place_local = temp;
|
||||||
|
last_len = p_ref.projection.len();
|
||||||
|
|
||||||
// We are creating a place by using our temp value's location
|
// We are creating a place by using our temp value's location
|
||||||
// and copying derefed values which we need to create new statement.
|
// and copying derefed values which we need to create new statement.
|
||||||
let temp_place =
|
let temp_place =
|
||||||
|
@ -50,11 +55,6 @@ pub fn deref_finder<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||||
// Since our job with the temp is done it should be gone
|
// Since our job with the temp is done it should be gone
|
||||||
let loc = Location { block: block, statement_index: i + 1 };
|
let loc = Location { block: block, statement_index: i + 1 };
|
||||||
patch.add_statement(loc, StatementKind::StorageDead(temp));
|
patch.add_statement(loc, StatementKind::StorageDead(temp));
|
||||||
|
|
||||||
// As all projections are off the base projection, if there are
|
|
||||||
// multiple derefs in the middle of projection, it might cause
|
|
||||||
// unsoundness, to not let that happen we break the loop.
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2460,8 +2460,16 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
self.normalize_ty(ast_ty.span, array_ty)
|
self.normalize_ty(ast_ty.span, array_ty)
|
||||||
}
|
}
|
||||||
hir::TyKind::Typeof(ref e) => {
|
hir::TyKind::Typeof(ref e) => {
|
||||||
tcx.sess.emit_err(TypeofReservedKeywordUsed { span: ast_ty.span });
|
let ty = tcx.type_of(tcx.hir().local_def_id(e.hir_id));
|
||||||
tcx.type_of(tcx.hir().local_def_id(e.hir_id))
|
let span = ast_ty.span;
|
||||||
|
tcx.sess.emit_err(TypeofReservedKeywordUsed {
|
||||||
|
span,
|
||||||
|
ty,
|
||||||
|
opt_sugg: Some((span, Applicability::MachineApplicable))
|
||||||
|
.filter(|_| ty.is_suggestable()),
|
||||||
|
});
|
||||||
|
|
||||||
|
ty
|
||||||
}
|
}
|
||||||
hir::TyKind::Infer => {
|
hir::TyKind::Infer => {
|
||||||
// Infer also appears as the type of arguments or return
|
// Infer also appears as the type of arguments or return
|
||||||
|
|
|
@ -1012,7 +1012,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
|
||||||
err.help(msg);
|
err.help(msg);
|
||||||
}
|
}
|
||||||
err.help(
|
err.help(
|
||||||
"if you can't comply with strict provenance and need to expose the pointer\
|
"if you can't comply with strict provenance and need to expose the pointer \
|
||||||
provenance you can use `.expose_addr()` instead"
|
provenance you can use `.expose_addr()` instead"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
//! Errors emitted by typeck.
|
//! Errors emitted by typeck.
|
||||||
|
use rustc_errors::Applicability;
|
||||||
use rustc_macros::SessionDiagnostic;
|
use rustc_macros::SessionDiagnostic;
|
||||||
|
use rustc_middle::ty::Ty;
|
||||||
use rustc_span::{symbol::Ident, Span, Symbol};
|
use rustc_span::{symbol::Ident, Span, Symbol};
|
||||||
|
|
||||||
#[derive(SessionDiagnostic)]
|
#[derive(SessionDiagnostic)]
|
||||||
|
@ -127,10 +129,13 @@ pub struct FunctionalRecordUpdateOnNonStruct {
|
||||||
|
|
||||||
#[derive(SessionDiagnostic)]
|
#[derive(SessionDiagnostic)]
|
||||||
#[error(code = "E0516", slug = "typeck-typeof-reserved-keyword-used")]
|
#[error(code = "E0516", slug = "typeck-typeof-reserved-keyword-used")]
|
||||||
pub struct TypeofReservedKeywordUsed {
|
pub struct TypeofReservedKeywordUsed<'tcx> {
|
||||||
|
pub ty: Ty<'tcx>,
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
#[label]
|
#[label]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
|
#[suggestion_verbose(message = "suggestion", code = "{ty}")]
|
||||||
|
pub opt_sugg: Option<(Span, Applicability)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(SessionDiagnostic)]
|
#[derive(SessionDiagnostic)]
|
||||||
|
|
|
@ -6,52 +6,10 @@ use crate::fmt;
|
||||||
use crate::mem::transmute;
|
use crate::mem::transmute;
|
||||||
use crate::str::FromStr;
|
use crate::str::FromStr;
|
||||||
|
|
||||||
/// Converts a `u32` to a `char`.
|
/// Converts a `u32` to a `char`. See [`char::from_u32`].
|
||||||
///
|
|
||||||
/// Note that all [`char`]s are valid [`u32`]s, and can be cast to one with
|
|
||||||
/// `as`:
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// let c = '💯';
|
|
||||||
/// let i = c as u32;
|
|
||||||
///
|
|
||||||
/// assert_eq!(128175, i);
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// However, the reverse is not true: not all valid [`u32`]s are valid
|
|
||||||
/// [`char`]s. `from_u32()` will return `None` if the input is not a valid value
|
|
||||||
/// for a [`char`].
|
|
||||||
///
|
|
||||||
/// For an unsafe version of this function which ignores these checks, see
|
|
||||||
/// [`from_u32_unchecked`].
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// Basic usage:
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use std::char;
|
|
||||||
///
|
|
||||||
/// let c = char::from_u32(0x2764);
|
|
||||||
///
|
|
||||||
/// assert_eq!(Some('❤'), c);
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// Returning `None` when the input is not a valid [`char`]:
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use std::char;
|
|
||||||
///
|
|
||||||
/// let c = char::from_u32(0x110000);
|
|
||||||
///
|
|
||||||
/// assert_eq!(None, c);
|
|
||||||
/// ```
|
|
||||||
#[doc(alias = "chr")]
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[inline]
|
#[inline]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
pub(super) const fn from_u32(i: u32) -> Option<char> {
|
||||||
#[rustc_const_unstable(feature = "const_char_convert", issue = "89259")]
|
|
||||||
pub const fn from_u32(i: u32) -> Option<char> {
|
|
||||||
// FIXME: once Result::ok is const fn, use it here
|
// FIXME: once Result::ok is const fn, use it here
|
||||||
match char_try_from_u32(i) {
|
match char_try_from_u32(i) {
|
||||||
Ok(c) => Some(c),
|
Ok(c) => Some(c),
|
||||||
|
@ -59,44 +17,11 @@ pub const fn from_u32(i: u32) -> Option<char> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts a `u32` to a `char`, ignoring validity.
|
/// Converts a `u32` to a `char`, ignoring validity. See [`char::from_u32_unchecked`].
|
||||||
///
|
#[rustc_const_unstable(feature = "const_char_convert", issue = "89259")]
|
||||||
/// Note that all [`char`]s are valid [`u32`]s, and can be cast to one with
|
|
||||||
/// `as`:
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// let c = '💯';
|
|
||||||
/// let i = c as u32;
|
|
||||||
///
|
|
||||||
/// assert_eq!(128175, i);
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// However, the reverse is not true: not all valid [`u32`]s are valid
|
|
||||||
/// [`char`]s. `from_u32_unchecked()` will ignore this, and blindly cast to
|
|
||||||
/// [`char`], possibly creating an invalid one.
|
|
||||||
///
|
|
||||||
/// # Safety
|
|
||||||
///
|
|
||||||
/// This function is unsafe, as it may construct invalid `char` values.
|
|
||||||
///
|
|
||||||
/// For a safe version of this function, see the [`from_u32`] function.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// Basic usage:
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use std::char;
|
|
||||||
///
|
|
||||||
/// let c = unsafe { char::from_u32_unchecked(0x2764) };
|
|
||||||
///
|
|
||||||
/// assert_eq!('❤', c);
|
|
||||||
/// ```
|
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[stable(feature = "char_from_unchecked", since = "1.5.0")]
|
pub(super) const unsafe fn from_u32_unchecked(i: u32) -> char {
|
||||||
#[rustc_const_unstable(feature = "const_char_convert", issue = "89259")]
|
|
||||||
pub const unsafe fn from_u32_unchecked(i: u32) -> char {
|
|
||||||
// SAFETY: the caller must guarantee that `i` is a valid char value.
|
// SAFETY: the caller must guarantee that `i` is a valid char value.
|
||||||
if cfg!(debug_assertions) { char::from_u32(i).unwrap() } else { unsafe { transmute(i) } }
|
if cfg!(debug_assertions) { char::from_u32(i).unwrap() } else { unsafe { transmute(i) } }
|
||||||
}
|
}
|
||||||
|
@ -317,60 +242,10 @@ impl fmt::Display for CharTryFromError {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts a digit in the given radix to a `char`.
|
/// Converts a digit in the given radix to a `char`. See [`char::from_digit`].
|
||||||
///
|
|
||||||
/// A 'radix' here is sometimes also called a 'base'. A radix of two
|
|
||||||
/// indicates a binary number, a radix of ten, decimal, and a radix of
|
|
||||||
/// sixteen, hexadecimal, to give some common values. Arbitrary
|
|
||||||
/// radices are supported.
|
|
||||||
///
|
|
||||||
/// `from_digit()` will return `None` if the input is not a digit in
|
|
||||||
/// the given radix.
|
|
||||||
///
|
|
||||||
/// # Panics
|
|
||||||
///
|
|
||||||
/// Panics if given a radix larger than 36.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// Basic usage:
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use std::char;
|
|
||||||
///
|
|
||||||
/// let c = char::from_digit(4, 10);
|
|
||||||
///
|
|
||||||
/// assert_eq!(Some('4'), c);
|
|
||||||
///
|
|
||||||
/// // Decimal 11 is a single digit in base 16
|
|
||||||
/// let c = char::from_digit(11, 16);
|
|
||||||
///
|
|
||||||
/// assert_eq!(Some('b'), c);
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// Returning `None` when the input is not a digit:
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use std::char;
|
|
||||||
///
|
|
||||||
/// let c = char::from_digit(20, 10);
|
|
||||||
///
|
|
||||||
/// assert_eq!(None, c);
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// Passing a large radix, causing a panic:
|
|
||||||
///
|
|
||||||
/// ```should_panic
|
|
||||||
/// use std::char;
|
|
||||||
///
|
|
||||||
/// // this panics
|
|
||||||
/// let c = char::from_digit(1, 37);
|
|
||||||
/// ```
|
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
pub(super) const fn from_digit(num: u32, radix: u32) -> Option<char> {
|
||||||
#[rustc_const_unstable(feature = "const_char_convert", issue = "89259")]
|
|
||||||
pub const fn from_digit(num: u32, radix: u32) -> Option<char> {
|
|
||||||
if radix > 36 {
|
if radix > 36 {
|
||||||
panic!("from_digit: radix is too high (maximum 36)");
|
panic!("from_digit: radix is too high (maximum 36)");
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,54 +30,9 @@ pub struct DecodeUtf16Error {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates an iterator over the UTF-16 encoded code points in `iter`,
|
/// Creates an iterator over the UTF-16 encoded code points in `iter`,
|
||||||
/// returning unpaired surrogates as `Err`s.
|
/// returning unpaired surrogates as `Err`s. See [`char::decode_utf16`].
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// Basic usage:
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use std::char::decode_utf16;
|
|
||||||
///
|
|
||||||
/// // 𝄞mus<invalid>ic<invalid>
|
|
||||||
/// let v = [
|
|
||||||
/// 0xD834, 0xDD1E, 0x006d, 0x0075, 0x0073, 0xDD1E, 0x0069, 0x0063, 0xD834,
|
|
||||||
/// ];
|
|
||||||
///
|
|
||||||
/// assert_eq!(
|
|
||||||
/// decode_utf16(v.iter().cloned())
|
|
||||||
/// .map(|r| r.map_err(|e| e.unpaired_surrogate()))
|
|
||||||
/// .collect::<Vec<_>>(),
|
|
||||||
/// vec![
|
|
||||||
/// Ok('𝄞'),
|
|
||||||
/// Ok('m'), Ok('u'), Ok('s'),
|
|
||||||
/// Err(0xDD1E),
|
|
||||||
/// Ok('i'), Ok('c'),
|
|
||||||
/// Err(0xD834)
|
|
||||||
/// ]
|
|
||||||
/// );
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// A lossy decoder can be obtained by replacing `Err` results with the replacement character:
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use std::char::{decode_utf16, REPLACEMENT_CHARACTER};
|
|
||||||
///
|
|
||||||
/// // 𝄞mus<invalid>ic<invalid>
|
|
||||||
/// let v = [
|
|
||||||
/// 0xD834, 0xDD1E, 0x006d, 0x0075, 0x0073, 0xDD1E, 0x0069, 0x0063, 0xD834,
|
|
||||||
/// ];
|
|
||||||
///
|
|
||||||
/// assert_eq!(
|
|
||||||
/// decode_utf16(v.iter().cloned())
|
|
||||||
/// .map(|r| r.unwrap_or(REPLACEMENT_CHARACTER))
|
|
||||||
/// .collect::<String>(),
|
|
||||||
/// "𝄞mus<75>ic<69>"
|
|
||||||
/// );
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "decode_utf16", since = "1.9.0")]
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn decode_utf16<I: IntoIterator<Item = u16>>(iter: I) -> DecodeUtf16<I::IntoIter> {
|
pub(super) fn decode_utf16<I: IntoIterator<Item = u16>>(iter: I) -> DecodeUtf16<I::IntoIter> {
|
||||||
DecodeUtf16 { iter: iter.into_iter(), buf: None }
|
DecodeUtf16 { iter: iter.into_iter(), buf: None }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,18 +23,12 @@ mod decode;
|
||||||
mod methods;
|
mod methods;
|
||||||
|
|
||||||
// stable re-exports
|
// stable re-exports
|
||||||
#[stable(feature = "char_from_unchecked", since = "1.5.0")]
|
|
||||||
pub use self::convert::from_u32_unchecked;
|
|
||||||
#[stable(feature = "try_from", since = "1.34.0")]
|
#[stable(feature = "try_from", since = "1.34.0")]
|
||||||
pub use self::convert::CharTryFromError;
|
pub use self::convert::CharTryFromError;
|
||||||
#[stable(feature = "char_from_str", since = "1.20.0")]
|
#[stable(feature = "char_from_str", since = "1.20.0")]
|
||||||
pub use self::convert::ParseCharError;
|
pub use self::convert::ParseCharError;
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
|
||||||
pub use self::convert::{from_digit, from_u32};
|
|
||||||
#[stable(feature = "decode_utf16", since = "1.9.0")]
|
#[stable(feature = "decode_utf16", since = "1.9.0")]
|
||||||
pub use self::decode::{decode_utf16, DecodeUtf16, DecodeUtf16Error};
|
pub use self::decode::{DecodeUtf16, DecodeUtf16Error};
|
||||||
#[stable(feature = "unicode_version", since = "1.45.0")]
|
|
||||||
pub use crate::unicode::UNICODE_VERSION;
|
|
||||||
|
|
||||||
// perma-unstable re-exports
|
// perma-unstable re-exports
|
||||||
#[unstable(feature = "char_internals", reason = "exposed only for libstd", issue = "none")]
|
#[unstable(feature = "char_internals", reason = "exposed only for libstd", issue = "none")]
|
||||||
|
@ -89,30 +83,57 @@ const MAX_THREE_B: u32 = 0x10000;
|
||||||
Cn Unassigned a reserved unassigned code point or a noncharacter
|
Cn Unassigned a reserved unassigned code point or a noncharacter
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/// The highest valid code point a `char` can have, `'\u{10FFFF}'`.
|
/// The highest valid code point a `char` can have, `'\u{10FFFF}'`. Use [`char::MAX`] instead.
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// # fn something_which_returns_char() -> char { 'a' }
|
|
||||||
/// let c: char = something_which_returns_char();
|
|
||||||
/// assert!(c <= char::MAX);
|
|
||||||
///
|
|
||||||
/// let value_at_max = char::MAX as u32;
|
|
||||||
/// assert_eq!(char::from_u32(value_at_max), Some('\u{10FFFF}'));
|
|
||||||
/// assert_eq!(char::from_u32(value_at_max + 1), None);
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub const MAX: char = char::MAX;
|
pub const MAX: char = char::MAX;
|
||||||
|
|
||||||
/// `U+FFFD REPLACEMENT CHARACTER` (<28>) is used in Unicode to represent a
|
/// `U+FFFD REPLACEMENT CHARACTER` (<28>) is used in Unicode to represent a
|
||||||
/// decoding error.
|
/// decoding error. Use [`char::REPLACEMENT_CHARACTER`] instead.
|
||||||
///
|
|
||||||
/// It can occur, for example, when giving ill-formed UTF-8 bytes to
|
|
||||||
/// [`String::from_utf8_lossy`](../../std/string/struct.String.html#method.from_utf8_lossy).
|
|
||||||
#[stable(feature = "decode_utf16", since = "1.9.0")]
|
#[stable(feature = "decode_utf16", since = "1.9.0")]
|
||||||
pub const REPLACEMENT_CHARACTER: char = char::REPLACEMENT_CHARACTER;
|
pub const REPLACEMENT_CHARACTER: char = char::REPLACEMENT_CHARACTER;
|
||||||
|
|
||||||
|
/// The version of [Unicode](https://www.unicode.org/) that the Unicode parts of
|
||||||
|
/// `char` and `str` methods are based on. Use [`char::UNICODE_VERSION`] instead.
|
||||||
|
#[stable(feature = "unicode_version", since = "1.45.0")]
|
||||||
|
pub const UNICODE_VERSION: (u8, u8, u8) = char::UNICODE_VERSION;
|
||||||
|
|
||||||
|
/// Creates an iterator over the UTF-16 encoded code points in `iter`, returning
|
||||||
|
/// unpaired surrogates as `Err`s. Use [`char::decode_utf16`] instead.
|
||||||
|
#[stable(feature = "decode_utf16", since = "1.9.0")]
|
||||||
|
#[inline]
|
||||||
|
pub fn decode_utf16<I: IntoIterator<Item = u16>>(iter: I) -> DecodeUtf16<I::IntoIter> {
|
||||||
|
self::decode::decode_utf16(iter)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Converts a `u32` to a `char`. Use [`char::from_u32`] instead.
|
||||||
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
#[rustc_const_unstable(feature = "const_char_convert", issue = "89259")]
|
||||||
|
#[must_use]
|
||||||
|
#[inline]
|
||||||
|
pub const fn from_u32(i: u32) -> Option<char> {
|
||||||
|
self::convert::from_u32(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Converts a `u32` to a `char`, ignoring validity. Use [`char::from_u32_unchecked`].
|
||||||
|
/// instead.
|
||||||
|
#[stable(feature = "char_from_unchecked", since = "1.5.0")]
|
||||||
|
#[rustc_const_unstable(feature = "const_char_convert", issue = "89259")]
|
||||||
|
#[must_use]
|
||||||
|
#[inline]
|
||||||
|
pub const unsafe fn from_u32_unchecked(i: u32) -> char {
|
||||||
|
// SAFETY: the safety contract must be upheld by the caller.
|
||||||
|
unsafe { self::convert::from_u32_unchecked(i) }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Converts a digit in the given radix to a `char`. Use [`char::from_digit`] instead.
|
||||||
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
#[rustc_const_unstable(feature = "const_char_convert", issue = "89259")]
|
||||||
|
#[must_use]
|
||||||
|
#[inline]
|
||||||
|
pub const fn from_digit(num: u32, radix: u32) -> Option<char> {
|
||||||
|
self::convert::from_digit(num, radix)
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns an iterator that yields the hexadecimal Unicode escape of a
|
/// Returns an iterator that yields the hexadecimal Unicode escape of a
|
||||||
/// character, as `char`s.
|
/// character, as `char`s.
|
||||||
///
|
///
|
||||||
|
|
|
@ -1097,8 +1097,19 @@ class RustBuild(object):
|
||||||
|
|
||||||
def update_submodules(self):
|
def update_submodules(self):
|
||||||
"""Update submodules"""
|
"""Update submodules"""
|
||||||
if (not os.path.exists(os.path.join(self.rust_root, ".git"))) or \
|
has_git = os.path.exists(os.path.join(self.rust_root, ".git"))
|
||||||
self.get_toml('submodules') == "false":
|
# This just arbitrarily checks for cargo, but any workspace member in
|
||||||
|
# a submodule would work.
|
||||||
|
has_submodules = os.path.exists(os.path.join(self.rust_root, "src/tools/cargo/Cargo.toml"))
|
||||||
|
if not has_git and not has_submodules:
|
||||||
|
print("This is not a git repository, and the requisite git submodules were not found.")
|
||||||
|
print("If you downloaded the source from https://github.com/rust-lang/rust/releases,")
|
||||||
|
print("those sources will not work. Instead, consider downloading from the source")
|
||||||
|
print("releases linked at")
|
||||||
|
print("https://forge.rust-lang.org/infra/other-installation-methods.html#source-code")
|
||||||
|
print("or clone the repository at https://github.com/rust-lang/rust/.")
|
||||||
|
raise SystemExit(1)
|
||||||
|
if not has_git or self.get_toml('submodules') == "false":
|
||||||
return
|
return
|
||||||
|
|
||||||
default_encoding = sys.getdefaultencoding()
|
default_encoding = sys.getdefaultencoding()
|
||||||
|
|
|
@ -251,7 +251,7 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let lines = origtext.lines().filter_map(|l| map_line(l).for_html());
|
let lines = origtext.lines().filter_map(|l| map_line(l).for_html());
|
||||||
let text = lines.collect::<Vec<Cow<'_, str>>>().join("\n");
|
let text = lines.intersperse("\n".into()).collect::<String>();
|
||||||
|
|
||||||
let parse_result = match kind {
|
let parse_result = match kind {
|
||||||
CodeBlockKind::Fenced(ref lang) => {
|
CodeBlockKind::Fenced(ref lang) => {
|
||||||
|
@ -291,15 +291,13 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> {
|
||||||
let test = origtext
|
let test = origtext
|
||||||
.lines()
|
.lines()
|
||||||
.map(|l| map_line(l).for_code())
|
.map(|l| map_line(l).for_code())
|
||||||
.collect::<Vec<Cow<'_, str>>>()
|
.intersperse("\n".into())
|
||||||
.join("\n");
|
.collect::<String>();
|
||||||
let krate = krate.as_ref().map(|s| &**s);
|
let krate = krate.as_ref().map(|s| &**s);
|
||||||
let (test, _, _) =
|
let (test, _, _) =
|
||||||
doctest::make_test(&test, krate, false, &Default::default(), edition, None);
|
doctest::make_test(&test, krate, false, &Default::default(), edition, None);
|
||||||
let channel = if test.contains("#![feature(") { "&version=nightly" } else { "" };
|
let channel = if test.contains("#![feature(") { "&version=nightly" } else { "" };
|
||||||
|
|
||||||
let edition_string = format!("&edition={}", edition);
|
|
||||||
|
|
||||||
// These characters don't need to be escaped in a URI.
|
// These characters don't need to be escaped in a URI.
|
||||||
// FIXME: use a library function for percent encoding.
|
// FIXME: use a library function for percent encoding.
|
||||||
fn dont_escape(c: u8) -> bool {
|
fn dont_escape(c: u8) -> bool {
|
||||||
|
@ -325,8 +323,8 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(format!(
|
Some(format!(
|
||||||
r#"<a class="test-arrow" target="_blank" href="{}?code={}{}{}">Run</a>"#,
|
r#"<a class="test-arrow" target="_blank" href="{}?code={}{}&edition={}">Run</a>"#,
|
||||||
url, test_escaped, channel, edition_string
|
url, test_escaped, channel, edition,
|
||||||
))
|
))
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
100
src/test/mir-opt/derefer_test_multiple.main.Derefer.diff
Normal file
100
src/test/mir-opt/derefer_test_multiple.main.Derefer.diff
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
- // MIR for `main` before Derefer
|
||||||
|
+ // MIR for `main` after Derefer
|
||||||
|
|
||||||
|
fn main() -> () {
|
||||||
|
let mut _0: (); // return place in scope 0 at $DIR/derefer_test_multiple.rs:2:12: 2:12
|
||||||
|
let mut _1: (i32, i32); // in scope 0 at $DIR/derefer_test_multiple.rs:3:9: 3:14
|
||||||
|
let mut _3: &mut (i32, i32); // in scope 0 at $DIR/derefer_test_multiple.rs:4:22: 4:28
|
||||||
|
let mut _5: &mut (i32, &mut (i32, i32)); // in scope 0 at $DIR/derefer_test_multiple.rs:5:22: 5:28
|
||||||
|
let mut _7: &mut (i32, &mut (i32, &mut (i32, i32))); // in scope 0 at $DIR/derefer_test_multiple.rs:6:22: 6:28
|
||||||
|
+ let mut _10: &mut (i32, &mut (i32, &mut (i32, i32))); // in scope 0 at $DIR/derefer_test_multiple.rs:7:13: 7:30
|
||||||
|
+ let mut _11: &mut (i32, &mut (i32, i32)); // in scope 0 at $DIR/derefer_test_multiple.rs:7:13: 7:30
|
||||||
|
+ let mut _12: &mut (i32, i32); // in scope 0 at $DIR/derefer_test_multiple.rs:7:13: 7:30
|
||||||
|
+ let mut _13: &mut (i32, &mut (i32, &mut (i32, i32))); // in scope 0 at $DIR/derefer_test_multiple.rs:8:13: 8:30
|
||||||
|
+ let mut _14: &mut (i32, &mut (i32, i32)); // in scope 0 at $DIR/derefer_test_multiple.rs:8:13: 8:30
|
||||||
|
+ let mut _15: &mut (i32, i32); // in scope 0 at $DIR/derefer_test_multiple.rs:8:13: 8:30
|
||||||
|
scope 1 {
|
||||||
|
debug a => _1; // in scope 1 at $DIR/derefer_test_multiple.rs:3:9: 3:14
|
||||||
|
let mut _2: (i32, &mut (i32, i32)); // in scope 1 at $DIR/derefer_test_multiple.rs:4:9: 4:14
|
||||||
|
scope 2 {
|
||||||
|
debug b => _2; // in scope 2 at $DIR/derefer_test_multiple.rs:4:9: 4:14
|
||||||
|
let mut _4: (i32, &mut (i32, &mut (i32, i32))); // in scope 2 at $DIR/derefer_test_multiple.rs:5:9: 5:14
|
||||||
|
scope 3 {
|
||||||
|
debug c => _4; // in scope 3 at $DIR/derefer_test_multiple.rs:5:9: 5:14
|
||||||
|
let mut _6: (i32, &mut (i32, &mut (i32, &mut (i32, i32)))); // in scope 3 at $DIR/derefer_test_multiple.rs:6:9: 6:14
|
||||||
|
scope 4 {
|
||||||
|
debug d => _6; // in scope 4 at $DIR/derefer_test_multiple.rs:6:9: 6:14
|
||||||
|
let _8: &mut i32; // in scope 4 at $DIR/derefer_test_multiple.rs:7:9: 7:10
|
||||||
|
scope 5 {
|
||||||
|
debug x => _8; // in scope 5 at $DIR/derefer_test_multiple.rs:7:9: 7:10
|
||||||
|
let _9: &mut i32; // in scope 5 at $DIR/derefer_test_multiple.rs:8:9: 8:10
|
||||||
|
scope 6 {
|
||||||
|
debug y => _9; // in scope 6 at $DIR/derefer_test_multiple.rs:8:9: 8:10
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bb0: {
|
||||||
|
StorageLive(_1); // scope 0 at $DIR/derefer_test_multiple.rs:3:9: 3:14
|
||||||
|
(_1.0: i32) = const 42_i32; // scope 0 at $DIR/derefer_test_multiple.rs:3:17: 3:25
|
||||||
|
(_1.1: i32) = const 43_i32; // scope 0 at $DIR/derefer_test_multiple.rs:3:17: 3:25
|
||||||
|
StorageLive(_2); // scope 1 at $DIR/derefer_test_multiple.rs:4:9: 4:14
|
||||||
|
StorageLive(_3); // scope 1 at $DIR/derefer_test_multiple.rs:4:22: 4:28
|
||||||
|
_3 = &mut _1; // scope 1 at $DIR/derefer_test_multiple.rs:4:22: 4:28
|
||||||
|
(_2.0: i32) = const 99_i32; // scope 1 at $DIR/derefer_test_multiple.rs:4:17: 4:29
|
||||||
|
(_2.1: &mut (i32, i32)) = move _3; // scope 1 at $DIR/derefer_test_multiple.rs:4:17: 4:29
|
||||||
|
StorageDead(_3); // scope 1 at $DIR/derefer_test_multiple.rs:4:28: 4:29
|
||||||
|
StorageLive(_4); // scope 2 at $DIR/derefer_test_multiple.rs:5:9: 5:14
|
||||||
|
StorageLive(_5); // scope 2 at $DIR/derefer_test_multiple.rs:5:22: 5:28
|
||||||
|
_5 = &mut _2; // scope 2 at $DIR/derefer_test_multiple.rs:5:22: 5:28
|
||||||
|
(_4.0: i32) = const 11_i32; // scope 2 at $DIR/derefer_test_multiple.rs:5:17: 5:29
|
||||||
|
(_4.1: &mut (i32, &mut (i32, i32))) = move _5; // scope 2 at $DIR/derefer_test_multiple.rs:5:17: 5:29
|
||||||
|
StorageDead(_5); // scope 2 at $DIR/derefer_test_multiple.rs:5:28: 5:29
|
||||||
|
StorageLive(_6); // scope 3 at $DIR/derefer_test_multiple.rs:6:9: 6:14
|
||||||
|
StorageLive(_7); // scope 3 at $DIR/derefer_test_multiple.rs:6:22: 6:28
|
||||||
|
_7 = &mut _4; // scope 3 at $DIR/derefer_test_multiple.rs:6:22: 6:28
|
||||||
|
(_6.0: i32) = const 13_i32; // scope 3 at $DIR/derefer_test_multiple.rs:6:17: 6:29
|
||||||
|
(_6.1: &mut (i32, &mut (i32, &mut (i32, i32)))) = move _7; // scope 3 at $DIR/derefer_test_multiple.rs:6:17: 6:29
|
||||||
|
StorageDead(_7); // scope 3 at $DIR/derefer_test_multiple.rs:6:28: 6:29
|
||||||
|
StorageLive(_8); // scope 4 at $DIR/derefer_test_multiple.rs:7:9: 7:10
|
||||||
|
- _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
|
||||||
|
+ StorageLive(_10); // scope 4 at $DIR/derefer_test_multiple.rs:7:13: 7:30
|
||||||
|
+ _10 = move (_6.1: &mut (i32, &mut (i32, &mut (i32, i32)))); // scope 4 at $DIR/derefer_test_multiple.rs:7:13: 7:30
|
||||||
|
+ StorageLive(_11); // scope 4 at $DIR/derefer_test_multiple.rs:7:13: 7:30
|
||||||
|
+ _11 = move ((*_10).1: &mut (i32, &mut (i32, i32))); // scope 4 at $DIR/derefer_test_multiple.rs:7:13: 7:30
|
||||||
|
+ StorageLive(_12); // scope 4 at $DIR/derefer_test_multiple.rs:7:13: 7:30
|
||||||
|
+ _12 = move ((*_11).1: &mut (i32, i32)); // scope 4 at $DIR/derefer_test_multiple.rs:7:13: 7:30
|
||||||
|
+ _8 = &mut ((*_12).1: i32); // scope 4 at $DIR/derefer_test_multiple.rs:7:13: 7:30
|
||||||
|
+ StorageDead(_10); // scope 5 at $DIR/derefer_test_multiple.rs:8:9: 8:10
|
||||||
|
+ StorageDead(_11); // scope 5 at $DIR/derefer_test_multiple.rs:8:9: 8:10
|
||||||
|
+ StorageDead(_12); // scope 5 at $DIR/derefer_test_multiple.rs:8:9: 8:10
|
||||||
|
StorageLive(_9); // scope 5 at $DIR/derefer_test_multiple.rs:8:9: 8:10
|
||||||
|
- _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
|
||||||
|
+ StorageLive(_13); // scope 5 at $DIR/derefer_test_multiple.rs:8:13: 8:30
|
||||||
|
+ _13 = move (_6.1: &mut (i32, &mut (i32, &mut (i32, i32)))); // scope 5 at $DIR/derefer_test_multiple.rs:8:13: 8:30
|
||||||
|
+ StorageLive(_14); // scope 5 at $DIR/derefer_test_multiple.rs:8:13: 8:30
|
||||||
|
+ _14 = move ((*_13).1: &mut (i32, &mut (i32, i32))); // scope 5 at $DIR/derefer_test_multiple.rs:8:13: 8:30
|
||||||
|
+ StorageLive(_15); // scope 5 at $DIR/derefer_test_multiple.rs:8:13: 8:30
|
||||||
|
+ _15 = move ((*_14).1: &mut (i32, i32)); // scope 5 at $DIR/derefer_test_multiple.rs:8:13: 8:30
|
||||||
|
+ _9 = &mut ((*_15).1: i32); // scope 5 at $DIR/derefer_test_multiple.rs:8:13: 8:30
|
||||||
|
+ StorageDead(_13); // scope 0 at $DIR/derefer_test_multiple.rs:2:12: 9:2
|
||||||
|
+ StorageDead(_14); // scope 0 at $DIR/derefer_test_multiple.rs:2:12: 9:2
|
||||||
|
+ StorageDead(_15); // scope 0 at $DIR/derefer_test_multiple.rs:2:12: 9:2
|
||||||
|
_0 = const (); // scope 0 at $DIR/derefer_test_multiple.rs:2:12: 9:2
|
||||||
|
StorageDead(_9); // scope 5 at $DIR/derefer_test_multiple.rs:9:1: 9:2
|
||||||
|
StorageDead(_8); // scope 4 at $DIR/derefer_test_multiple.rs:9:1: 9:2
|
||||||
|
StorageDead(_6); // scope 3 at $DIR/derefer_test_multiple.rs:9:1: 9:2
|
||||||
|
StorageDead(_4); // scope 2 at $DIR/derefer_test_multiple.rs:9:1: 9:2
|
||||||
|
StorageDead(_2); // scope 1 at $DIR/derefer_test_multiple.rs:9:1: 9:2
|
||||||
|
StorageDead(_1); // scope 0 at $DIR/derefer_test_multiple.rs:9:1: 9:2
|
||||||
|
return; // scope 0 at $DIR/derefer_test_multiple.rs:9:2: 9:2
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ bb1 (cleanup): {
|
||||||
|
+ resume; // scope 0 at $DIR/derefer_test_multiple.rs:2:1: 9:2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
9
src/test/mir-opt/derefer_test_multiple.rs
Normal file
9
src/test/mir-opt/derefer_test_multiple.rs
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
// EMIT_MIR derefer_test_multiple.main.Derefer.diff
|
||||||
|
fn main () {
|
||||||
|
let mut a = (42, 43);
|
||||||
|
let mut b = (99, &mut a);
|
||||||
|
let mut c = (11, &mut b);
|
||||||
|
let mut d = (13, &mut c);
|
||||||
|
let x = &mut (*d.1).1.1.1;
|
||||||
|
let y = &mut (*d.1).1.1.1;
|
||||||
|
}
|
4
src/test/ui/borrowck/suggest-local-var-for-vector.rs
Normal file
4
src/test/ui/borrowck/suggest-local-var-for-vector.rs
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
fn main() {
|
||||||
|
let mut vec = vec![0u32; 420];
|
||||||
|
vec[vec.len() - 1] = 123; //~ ERROR cannot borrow `vec` as immutable because it is also borrowed as mutable
|
||||||
|
}
|
24
src/test/ui/borrowck/suggest-local-var-for-vector.stderr
Normal file
24
src/test/ui/borrowck/suggest-local-var-for-vector.stderr
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
error[E0502]: cannot borrow `vec` as immutable because it is also borrowed as mutable
|
||||||
|
--> $DIR/suggest-local-var-for-vector.rs:3:9
|
||||||
|
|
|
||||||
|
LL | vec[vec.len() - 1] = 123;
|
||||||
|
| ----^^^^^^^^^-----
|
||||||
|
| | |
|
||||||
|
| | immutable borrow occurs here
|
||||||
|
| mutable borrow occurs here
|
||||||
|
| mutable borrow later used here
|
||||||
|
|
|
||||||
|
help: try adding a local storing this...
|
||||||
|
--> $DIR/suggest-local-var-for-vector.rs:3:9
|
||||||
|
|
|
||||||
|
LL | vec[vec.len() - 1] = 123;
|
||||||
|
| ^^^^^^^^^
|
||||||
|
help: ...and then using that local here
|
||||||
|
--> $DIR/suggest-local-var-for-vector.rs:3:5
|
||||||
|
|
|
||||||
|
LL | vec[vec.len() - 1] = 123;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0502`.
|
|
@ -0,0 +1,4 @@
|
||||||
|
fn main() {
|
||||||
|
let mut vec = vec![0u32; 420];
|
||||||
|
vec[vec.len() - 1] = 123; //~ ERROR cannot borrow `vec` as immutable because it is also borrowed as mutable
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
error[E0502]: cannot borrow `vec` as immutable because it is also borrowed as mutable
|
||||||
|
--> $DIR/suggest-storing-local-var-for-vector.rs:3:9
|
||||||
|
|
|
||||||
|
LL | vec[vec.len() - 1] = 123;
|
||||||
|
| ----^^^^^^^^^-----
|
||||||
|
| | |
|
||||||
|
| | immutable borrow occurs here
|
||||||
|
| mutable borrow occurs here
|
||||||
|
| mutable borrow later used here
|
||||||
|
|
|
||||||
|
help: try adding a local storing this...
|
||||||
|
--> $DIR/suggest-storing-local-var-for-vector.rs:3:9
|
||||||
|
|
|
||||||
|
LL | vec[vec.len() - 1] = 123;
|
||||||
|
| ^^^^^^^^^
|
||||||
|
help: ...and then using that local here
|
||||||
|
--> $DIR/suggest-storing-local-var-for-vector.rs:3:5
|
||||||
|
|
|
||||||
|
LL | vec[vec.len() - 1] = 123;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0502`.
|
|
@ -54,6 +54,17 @@ LL | i[i[3]] = 4;
|
||||||
| | immutable borrow occurs here
|
| | immutable borrow occurs here
|
||||||
| mutable borrow occurs here
|
| mutable borrow occurs here
|
||||||
| mutable borrow later used here
|
| mutable borrow later used here
|
||||||
|
|
|
||||||
|
help: try adding a local storing this...
|
||||||
|
--> $DIR/two-phase-nonrecv-autoref.rs:138:7
|
||||||
|
|
|
||||||
|
LL | i[i[3]] = 4;
|
||||||
|
| ^^^^
|
||||||
|
help: ...and then using that local here
|
||||||
|
--> $DIR/two-phase-nonrecv-autoref.rs:138:5
|
||||||
|
|
|
||||||
|
LL | i[i[3]] = 4;
|
||||||
|
| ^^^^^^^
|
||||||
|
|
||||||
error[E0502]: cannot borrow `i` as immutable because it is also borrowed as mutable
|
error[E0502]: cannot borrow `i` as immutable because it is also borrowed as mutable
|
||||||
--> $DIR/two-phase-nonrecv-autoref.rs:143:7
|
--> $DIR/two-phase-nonrecv-autoref.rs:143:7
|
||||||
|
@ -64,6 +75,17 @@ LL | i[i[3]] = i[4];
|
||||||
| | immutable borrow occurs here
|
| | immutable borrow occurs here
|
||||||
| mutable borrow occurs here
|
| mutable borrow occurs here
|
||||||
| mutable borrow later used here
|
| mutable borrow later used here
|
||||||
|
|
|
||||||
|
help: try adding a local storing this...
|
||||||
|
--> $DIR/two-phase-nonrecv-autoref.rs:143:7
|
||||||
|
|
|
||||||
|
LL | i[i[3]] = i[4];
|
||||||
|
| ^^^^
|
||||||
|
help: ...and then using that local here
|
||||||
|
--> $DIR/two-phase-nonrecv-autoref.rs:143:5
|
||||||
|
|
|
||||||
|
LL | i[i[3]] = i[4];
|
||||||
|
| ^^^^^^^
|
||||||
|
|
||||||
error: aborting due to 7 previous errors
|
error: aborting due to 7 previous errors
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,11 @@ error[E0516]: `typeof` is a reserved keyword but unimplemented
|
||||||
|
|
|
|
||||||
LL | let x: typeof(92) = 92;
|
LL | let x: typeof(92) = 92;
|
||||||
| ^^^^^^^^^^ reserved keyword
|
| ^^^^^^^^^^ reserved keyword
|
||||||
|
|
|
||||||
|
help: consider replacing `typeof(...)` with an actual type
|
||||||
|
|
|
||||||
|
LL | let x: i32 = 92;
|
||||||
|
| ~~~
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,11 @@ error[E0516]: `typeof` is a reserved keyword but unimplemented
|
||||||
|
|
|
|
||||||
LL | let x: typeof(92) = 92;
|
LL | let x: typeof(92) = 92;
|
||||||
| ^^^^^^^^^^ reserved keyword
|
| ^^^^^^^^^^ reserved keyword
|
||||||
|
|
|
||||||
|
help: consider replacing `typeof(...)` with an actual type
|
||||||
|
|
|
||||||
|
LL | let x: i32 = 92;
|
||||||
|
| ~~~
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ note: the lint level is defined here
|
||||||
|
|
|
|
||||||
LL | #![deny(lossy_provenance_casts)]
|
LL | #![deny(lossy_provenance_casts)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||||
= help: if you can't comply with strict provenance and need to expose the pointerprovenance you can use `.expose_addr()` instead
|
= help: if you can't comply with strict provenance and need to expose the pointer provenance you can use `.expose_addr()` instead
|
||||||
|
|
||||||
error: under strict provenance it is considered bad style to cast pointer `*const u8` to integer `u32`
|
error: under strict provenance it is considered bad style to cast pointer `*const u8` to integer `u32`
|
||||||
--> $DIR/lint-strict-provenance-lossy-casts.rs:9:22
|
--> $DIR/lint-strict-provenance-lossy-casts.rs:9:22
|
||||||
|
@ -17,7 +17,7 @@ error: under strict provenance it is considered bad style to cast pointer `*cons
|
||||||
LL | let addr_32bit = &x as *const u8 as u32;
|
LL | let addr_32bit = &x as *const u8 as u32;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^ help: use `.addr()` to obtain the address of a pointer: `(&x as *const u8).addr() as u32`
|
| ^^^^^^^^^^^^^^^^^^^^^^ help: use `.addr()` to obtain the address of a pointer: `(&x as *const u8).addr() as u32`
|
||||||
|
|
|
|
||||||
= help: if you can't comply with strict provenance and need to expose the pointerprovenance you can use `.expose_addr()` instead
|
= help: if you can't comply with strict provenance and need to expose the pointer provenance you can use `.expose_addr()` instead
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,11 @@ error[E0516]: `typeof` is a reserved keyword but unimplemented
|
||||||
|
|
|
|
||||||
LL | let b: typeof(a) = 1i8;
|
LL | let b: typeof(a) = 1i8;
|
||||||
| ^^^^^^^^^ reserved keyword
|
| ^^^^^^^^^ reserved keyword
|
||||||
|
|
|
||||||
|
help: consider replacing `typeof(...)` with an actual type
|
||||||
|
|
|
||||||
|
LL | let b: u8 = 1i8;
|
||||||
|
| ~~
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/type_mismatch.rs:5:24
|
--> $DIR/type_mismatch.rs:5:24
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue