Auto merge of #104655 - matthiaskrgr:rollup-r5kfffy, r=matthiaskrgr

Rollup of 9 pull requests

Successful merges:

 - #101310 (Clarify and restrict when `{Arc,Rc}::get_unchecked_mut` is allowed.)
 - #104461 (Fix building of `aarch64-pc-windows-gnullvm`)
 - #104487 (update ntapi dep to remove future-incompat warning)
 - #104504 (Add a detailed note for missing comma typo w/ FRU syntax)
 - #104581 (rustdoc: remove unused JS IIFE from main.js)
 - #104632 (avoid non-strict-provenance casts in libcore tests)
 - #104634 (move core::arch into separate file)
 - #104641 (replace unusual grammar)
 - #104643 (add examples to chunks remainder methods. )

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2022-11-20 23:03:20 +00:00
commit a102dc806d
26 changed files with 310 additions and 88 deletions

View File

@ -0,0 +1,8 @@
hir_typeck_fru_note = this expression may have been misinterpreted as a `..` range expression
hir_typeck_fru_expr = this expression does not end in a comma...
hir_typeck_fru_expr2 = ... so this is interpreted as a `..` range expression, instead of functional record update syntax
hir_typeck_fru_suggestion =
to set the remaining fields{$expr ->
[NONE]{""}
*[other] {" "}from `{$expr}`
}, separate the last named field with a comma

View File

@ -51,6 +51,7 @@ fluent_messages! {
errors => "../locales/en-US/errors.ftl",
expand => "../locales/en-US/expand.ftl",
hir_analysis => "../locales/en-US/hir_analysis.ftl",
hir_typeck => "../locales/en-US/hir_typeck.ftl",
infer => "../locales/en-US/infer.ftl",
interface => "../locales/en-US/interface.ftl",
lint => "../locales/en-US/lint.ftl",

View File

@ -467,6 +467,9 @@ pub enum StashKey {
/// When an invalid lifetime e.g. `'2` should be reinterpreted
/// as a char literal in the parser
LifetimeIsChar,
/// Maybe there was a typo where a comma was forgotten before
/// FRU syntax
MaybeFruTypo,
}
fn default_track_diagnostic(_: &Diagnostic) {}

View File

@ -1,4 +1,5 @@
//! Errors emitted by `rustc_hir_analysis`.
use rustc_errors::{AddToDiagnostic, Applicability, Diagnostic, MultiSpan, SubdiagnosticMessage};
use rustc_macros::{Diagnostic, Subdiagnostic};
use rustc_middle::ty::Ty;
use rustc_span::{symbol::Ident, Span};
@ -133,3 +134,41 @@ pub struct OpMethodGenericParams {
pub span: Span,
pub method_name: String,
}
pub struct TypeMismatchFruTypo {
/// Span of the LHS of the range
pub expr_span: Span,
/// Span of the `..RHS` part of the range
pub fru_span: Span,
/// Rendered expression of the RHS of the range
pub expr: Option<String>,
}
impl AddToDiagnostic for TypeMismatchFruTypo {
fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F)
where
F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
{
diag.set_arg("expr", self.expr.as_deref().unwrap_or("NONE"));
// Only explain that `a ..b` is a range if it's split up
if self.expr_span.between(self.fru_span).is_empty() {
diag.span_note(
self.expr_span.to(self.fru_span),
rustc_errors::fluent::hir_typeck_fru_note,
);
} else {
let mut multispan: MultiSpan = vec![self.expr_span, self.fru_span].into();
multispan.push_span_label(self.expr_span, rustc_errors::fluent::hir_typeck_fru_expr);
multispan.push_span_label(self.fru_span, rustc_errors::fluent::hir_typeck_fru_expr2);
diag.span_note(multispan, rustc_errors::fluent::hir_typeck_fru_note);
}
diag.span_suggestion(
self.expr_span.shrink_to_hi(),
rustc_errors::fluent::hir_typeck_fru_suggestion,
", ",
Applicability::MaybeIncorrect,
);
}
}

View File

@ -5,6 +5,7 @@
use crate::cast;
use crate::coercion::CoerceMany;
use crate::coercion::DynamicCoerceMany;
use crate::errors::TypeMismatchFruTypo;
use crate::errors::{AddressOfTemporaryTaken, ReturnStmtOutsideOfFnBody, StructExprNonExhaustive};
use crate::errors::{
FieldMultiplySpecifiedInInitializer, FunctionalRecordUpdateOnNonStruct,
@ -1616,10 +1617,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.demand_coerce_diag(&field.expr, ty, field_type, None, AllowTwoPhase::No);
if let Some(mut diag) = diag {
if idx == ast_fields.len() - 1 && remaining_fields.is_empty() {
self.suggest_fru_from_range(field, variant, substs, &mut diag);
if idx == ast_fields.len() - 1 {
if remaining_fields.is_empty() {
self.suggest_fru_from_range(field, variant, substs, &mut diag);
diag.emit();
} else {
diag.stash(field.span, StashKey::MaybeFruTypo);
}
} else {
diag.emit();
}
diag.emit();
}
}
@ -1877,19 +1884,39 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.map(|adt| adt.did())
!= range_def_id
{
let instead = self
// Suppress any range expr type mismatches
if let Some(mut diag) = self
.tcx
.sess
.diagnostic()
.steal_diagnostic(last_expr_field.span, StashKey::MaybeFruTypo)
{
diag.delay_as_bug();
}
// Use a (somewhat arbitrary) filtering heuristic to avoid printing
// expressions that are either too long, or have control character
//such as newlines in them.
let expr = self
.tcx
.sess
.source_map()
.span_to_snippet(range_end.expr.span)
.map(|s| format!(" from `{s}`"))
.unwrap_or_default();
err.span_suggestion(
range_start.span.shrink_to_hi(),
&format!("to set the remaining fields{instead}, separate the last named field with a comma"),
",",
Applicability::MaybeIncorrect,
);
.ok()
.filter(|s| s.len() < 25 && !s.contains(|c: char| c.is_control()));
let fru_span = self
.tcx
.sess
.source_map()
.span_extend_while(range_start.span, |c| c.is_whitespace())
.unwrap_or(range_start.span).shrink_to_hi().to(range_end.span);
err.subdiagnostic(TypeMismatchFruTypo {
expr_span: range_start.span,
fru_span,
expr,
});
}
}

View File

@ -46,8 +46,8 @@ pub(super) const MIN_LEN: usize = node::MIN_LEN_AFTER_SPLIT;
/// is done is *very* inefficient for modern computer architectures. In particular, every element
/// is stored in its own individually heap-allocated node. This means that every single insertion
/// triggers a heap-allocation, and every single comparison should be a cache-miss. Since these
/// are both notably expensive things to do in practice, we are forced to at very least reconsider
/// the BST strategy.
/// are both notably expensive things to do in practice, we are forced to, at the very least,
/// reconsider the BST strategy.
///
/// A B-Tree instead makes each node contain B-1 to 2B-1 elements in a contiguous array. By doing
/// this, we reduce the number of allocations by a factor of B, and improve cache efficiency in

View File

@ -1091,10 +1091,11 @@ impl<T: ?Sized> Rc<T> {
///
/// # Safety
///
/// Any other `Rc` or [`Weak`] pointers to the same allocation must not be dereferenced
/// for the duration of the returned borrow.
/// This is trivially the case if no such pointers exist,
/// for example immediately after `Rc::new`.
/// If any other `Rc` or [`Weak`] pointers to the same allocation exist, then
/// they must be must not be dereferenced or have active borrows for the duration
/// of the returned borrow, and their inner type must be exactly the same as the
/// inner type of this Rc (including lifetimes). This is trivially the case if no
/// such pointers exist, for example immediately after `Rc::new`.
///
/// # Examples
///
@ -1109,6 +1110,38 @@ impl<T: ?Sized> Rc<T> {
/// }
/// assert_eq!(*x, "foo");
/// ```
/// Other `Rc` pointers to the same allocation must be to the same type.
/// ```no_run
/// #![feature(get_mut_unchecked)]
///
/// use std::rc::Rc;
///
/// let x: Rc<str> = Rc::from("Hello, world!");
/// let mut y: Rc<[u8]> = x.clone().into();
/// unsafe {
/// // this is Undefined Behavior, because x's inner type is str, not [u8]
/// Rc::get_mut_unchecked(&mut y).fill(0xff); // 0xff is invalid in UTF-8
/// }
/// println!("{}", &*x); // Invalid UTF-8 in a str
/// ```
/// Other `Rc` pointers to the same allocation must be to the exact same type, including lifetimes.
/// ```no_run
/// #![feature(get_mut_unchecked)]
///
/// use std::rc::Rc;
///
/// let x: Rc<&str> = Rc::new("Hello, world!");
/// {
/// let s = String::from("Oh, no!");
/// let mut y: Rc<&str> = x.clone().into();
/// unsafe {
/// // this is Undefined Behavior, because x's inner type
/// // is &'long str, not &'short str
/// *Rc::get_mut_unchecked(&mut y) = &s;
/// }
/// }
/// println!("{}", &*x); // Use-after-free
/// ```
#[inline]
#[unstable(feature = "get_mut_unchecked", issue = "63292")]
pub unsafe fn get_mut_unchecked(this: &mut Self) -> &mut T {

View File

@ -1587,10 +1587,11 @@ impl<T: ?Sized> Arc<T> {
///
/// # Safety
///
/// Any other `Arc` or [`Weak`] pointers to the same allocation must not be dereferenced
/// for the duration of the returned borrow.
/// This is trivially the case if no such pointers exist,
/// for example immediately after `Arc::new`.
/// If any other `Arc` or [`Weak`] pointers to the same allocation exist, then
/// they must be must not be dereferenced or have active borrows for the duration
/// of the returned borrow, and their inner type must be exactly the same as the
/// inner type of this Rc (including lifetimes). This is trivially the case if no
/// such pointers exist, for example immediately after `Arc::new`.
///
/// # Examples
///
@ -1605,6 +1606,38 @@ impl<T: ?Sized> Arc<T> {
/// }
/// assert_eq!(*x, "foo");
/// ```
/// Other `Arc` pointers to the same allocation must be to the same type.
/// ```no_run
/// #![feature(get_mut_unchecked)]
///
/// use std::sync::Arc;
///
/// let x: Arc<str> = Arc::from("Hello, world!");
/// let mut y: Arc<[u8]> = x.clone().into();
/// unsafe {
/// // this is Undefined Behavior, because x's inner type is str, not [u8]
/// Arc::get_mut_unchecked(&mut y).fill(0xff); // 0xff is invalid in UTF-8
/// }
/// println!("{}", &*x); // Invalid UTF-8 in a str
/// ```
/// Other `Arc` pointers to the same allocation must be to the exact same type, including lifetimes.
/// ```no_run
/// #![feature(get_mut_unchecked)]
///
/// use std::sync::Arc;
///
/// let x: Arc<&str> = Arc::new("Hello, world!");
/// {
/// let s = String::from("Oh, no!");
/// let mut y: Arc<&str> = x.clone().into();
/// unsafe {
/// // this is Undefined Behavior, because x's inner type
/// // is &'long str, not &'short str
/// *Arc::get_mut_unchecked(&mut y) = &s;
/// }
/// }
/// println!("{}", &*x); // Use-after-free
/// ```
#[inline]
#[unstable(feature = "get_mut_unchecked", issue = "63292")]
pub unsafe fn get_mut_unchecked(this: &mut Self) -> &mut T {

30
library/core/src/arch.rs Normal file
View File

@ -0,0 +1,30 @@
#![doc = include_str!("../../stdarch/crates/core_arch/src/core_arch_docs.md")]
#[stable(feature = "simd_arch", since = "1.27.0")]
pub use crate::core_arch::arch::*;
/// Inline assembly.
///
/// Refer to [rust by example] for a usage guide and the [reference] for
/// detailed information about the syntax and available options.
///
/// [rust by example]: https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html
/// [reference]: https://doc.rust-lang.org/nightly/reference/inline-assembly.html
#[stable(feature = "asm", since = "1.59.0")]
#[rustc_builtin_macro]
pub macro asm("assembly template", $(operands,)* $(options($(option),*))?) {
/* compiler built-in */
}
/// Module-level inline assembly.
///
/// Refer to [rust by example] for a usage guide and the [reference] for
/// detailed information about the syntax and available options.
///
/// [rust by example]: https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html
/// [reference]: https://doc.rust-lang.org/nightly/reference/inline-assembly.html
#[stable(feature = "global_asm", since = "1.59.0")]
#[rustc_builtin_macro]
pub macro global_asm("assembly template", $(operands,)* $(options($(option),*))?) {
/* compiler built-in */
}

View File

@ -89,6 +89,7 @@
// Lints:
#![deny(rust_2021_incompatible_or_patterns)]
#![deny(unsafe_op_in_unsafe_fn)]
#![deny(fuzzy_provenance_casts)]
#![warn(deprecated_in_future)]
#![warn(missing_debug_implementations)]
#![warn(missing_docs)]
@ -162,6 +163,7 @@
#![feature(slice_ptr_get)]
#![feature(slice_split_at_unchecked)]
#![feature(str_internals)]
#![feature(strict_provenance)]
#![feature(utf16_extra)]
#![feature(utf16_extra_const)]
#![feature(variant_count)]
@ -392,38 +394,8 @@ pub mod primitive;
#[unstable(feature = "stdsimd", issue = "48556")]
mod core_arch;
#[doc = include_str!("../../stdarch/crates/core_arch/src/core_arch_docs.md")]
#[stable(feature = "simd_arch", since = "1.27.0")]
pub mod arch {
#[stable(feature = "simd_arch", since = "1.27.0")]
pub use crate::core_arch::arch::*;
/// Inline assembly.
///
/// Refer to [rust by example] for a usage guide and the [reference] for
/// detailed information about the syntax and available options.
///
/// [rust by example]: https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html
/// [reference]: https://doc.rust-lang.org/nightly/reference/inline-assembly.html
#[stable(feature = "asm", since = "1.59.0")]
#[rustc_builtin_macro]
pub macro asm("assembly template", $(operands,)* $(options($(option),*))?) {
/* compiler built-in */
}
/// Module-level inline assembly.
///
/// Refer to [rust by example] for a usage guide and the [reference] for
/// detailed information about the syntax and available options.
///
/// [rust by example]: https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html
/// [reference]: https://doc.rust-lang.org/nightly/reference/inline-assembly.html
#[stable(feature = "global_asm", since = "1.59.0")]
#[rustc_builtin_macro]
pub macro global_asm("assembly template", $(operands,)* $(options($(option),*))?) {
/* compiler built-in */
}
}
pub mod arch;
// Pull in the `core_simd` crate directly into libcore. The contents of
// `core_simd` are in a different repository: rust-lang/portable-simd.

View File

@ -140,6 +140,7 @@ impl<T: ?Sized> *const T {
/// assert_eq!(<*const u8>::from_bits(1), dangling);
/// ```
#[unstable(feature = "ptr_to_from_bits", issue = "91126")]
#[allow(fuzzy_provenance_casts)] // this is an unstable and semi-deprecated cast function
pub fn from_bits(bits: usize) -> Self
where
T: Sized,

View File

@ -616,6 +616,7 @@ pub const fn invalid_mut<T>(addr: usize) -> *mut T {
#[inline]
#[unstable(feature = "strict_provenance", issue = "95228")]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
#[allow(fuzzy_provenance_casts)] // this *is* the strict provenance API one should use instead
pub fn from_exposed_addr<T>(addr: usize) -> *const T
where
T: Sized,
@ -653,6 +654,7 @@ where
#[inline]
#[unstable(feature = "strict_provenance", issue = "95228")]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
#[allow(fuzzy_provenance_casts)] // this *is* the strict provenance API one should use instead
pub fn from_exposed_addr_mut<T>(addr: usize) -> *mut T
where
T: Sized,

View File

@ -146,6 +146,7 @@ impl<T: ?Sized> *mut T {
/// assert_eq!(<*mut u8>::from_bits(1), dangling);
/// ```
#[unstable(feature = "ptr_to_from_bits", issue = "91126")]
#[allow(fuzzy_provenance_casts)] // this is an unstable and semi-deprecated cast function
pub fn from_bits(bits: usize) -> Self
where
T: Sized,

View File

@ -1834,6 +1834,20 @@ impl<'a, T> ChunksExact<'a, T> {
/// Returns the remainder of the original slice that is not going to be
/// returned by the iterator. The returned slice has at most `chunk_size-1`
/// elements.
///
/// # Example
///
/// ```
/// let slice = ['l', 'o', 'r', 'e', 'm'];
/// let mut iter = slice.chunks_exact(2);
/// assert_eq!(iter.remainder(), &['m'][..]);
/// assert_eq!(iter.next(), Some(&['l', 'o'][..]));
/// assert_eq!(iter.remainder(), &['m'][..]);
/// assert_eq!(iter.next(), Some(&['r', 'e'][..]));
/// assert_eq!(iter.remainder(), &['m'][..]);
/// assert_eq!(iter.next(), None);
/// assert_eq!(iter.remainder(), &['m'][..]);
/// ```
#[must_use]
#[stable(feature = "chunks_exact", since = "1.31.0")]
pub fn remainder(&self) -> &'a [T] {
@ -2869,7 +2883,7 @@ unsafe impl<T> Sync for RChunksMut<'_, T> where T: Sync {}
/// ```
///
/// [`rchunks_exact`]: slice::rchunks_exact
/// [`remainder`]: ChunksExact::remainder
/// [`remainder`]: RChunksExact::remainder
/// [slices]: slice
#[derive(Debug)]
#[stable(feature = "rchunks", since = "1.31.0")]
@ -2892,6 +2906,20 @@ impl<'a, T> RChunksExact<'a, T> {
/// Returns the remainder of the original slice that is not going to be
/// returned by the iterator. The returned slice has at most `chunk_size-1`
/// elements.
///
/// # Example
///
/// ```
/// let slice = ['l', 'o', 'r', 'e', 'm'];
/// let mut iter = slice.rchunks_exact(2);
/// assert_eq!(iter.remainder(), &['l'][..]);
/// assert_eq!(iter.next(), Some(&['e', 'm'][..]));
/// assert_eq!(iter.remainder(), &['l'][..]);
/// assert_eq!(iter.next(), Some(&['o', 'r'][..]));
/// assert_eq!(iter.remainder(), &['l'][..]);
/// assert_eq!(iter.next(), None);
/// assert_eq!(iter.remainder(), &['l'][..]);
/// ```
#[must_use]
#[stable(feature = "rchunks", since = "1.31.0")]
pub fn remainder(&self) -> &'a [T] {
@ -3031,7 +3059,7 @@ unsafe impl<'a, T> TrustedRandomAccessNoCoerce for RChunksExact<'a, T> {
/// ```
///
/// [`rchunks_exact_mut`]: slice::rchunks_exact_mut
/// [`into_remainder`]: ChunksExactMut::into_remainder
/// [`into_remainder`]: RChunksExactMut::into_remainder
/// [slices]: slice
#[derive(Debug)]
#[stable(feature = "rchunks", since = "1.31.0")]

View File

@ -109,6 +109,7 @@
#![feature(utf8_chunks)]
#![feature(is_ascii_octdigit)]
#![deny(unsafe_op_in_unsafe_fn)]
#![deny(fuzzy_provenance_casts)]
extern crate test;

View File

@ -677,7 +677,7 @@ fn align_offset_issue_103361() {
#[cfg(target_pointer_width = "16")]
const SIZE: usize = 1 << 13;
struct HugeSize([u8; SIZE - 1]);
let _ = (SIZE as *const HugeSize).align_offset(SIZE);
let _ = ptr::invalid::<HugeSize>(SIZE).align_offset(SIZE);
}
#[test]

View File

@ -275,7 +275,7 @@ if #[cfg(not(all(target_os = "ios", target_arch = "arm")))] {
} // cfg_if!
cfg_if::cfg_if! {
if #[cfg(all(windows, target_arch = "x86_64", target_env = "gnu"))] {
if #[cfg(all(windows, any(target_arch = "aarch64", target_arch = "x86_64"), target_env = "gnu"))] {
// We declare these as opaque types. This is fine since you just need to
// pass them to _GCC_specific_handler and forget about them.
pub enum EXCEPTION_RECORD {}

View File

@ -383,9 +383,9 @@ dependencies = [
[[package]]
name = "ntapi"
version = "0.3.7"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c28774a7fd2fbb4f0babd8237ce554b73af68021b5f695a3cebd6c59bac0980f"
checksum = "bc51db7b362b205941f71232e56c625156eb9a929f8cf74a428fd5bc094a4afc"
dependencies = [
"winapi",
]
@ -607,9 +607,9 @@ dependencies = [
[[package]]
name = "sysinfo"
version = "0.24.2"
version = "0.26.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a2809487b962344ca55d9aea565f9ffbcb6929780802217acc82561f6746770"
checksum = "c375d5fd899e32847b8566e10598d6e9f1d9b55ec6de3cdf9e7da4bdc51371bc"
dependencies = [
"cfg-if",
"core-foundation-sys",

View File

@ -54,7 +54,7 @@ xz2 = "0.1"
walkdir = "2"
# Dependencies needed by the build-metrics feature
sysinfo = { version = "0.24.1", optional = true }
sysinfo = { version = "0.26.0", optional = true }
[target.'cfg(windows)'.dependencies.winapi]
version = "0.3"

View File

@ -97,7 +97,7 @@ impl BuildMetrics {
cpu_threads_count: system.cpus().len(),
cpu_model: system.cpus()[0].brand().into(),
memory_total_bytes: system.total_memory() * 1024,
memory_total_bytes: system.total_memory(),
};
let steps = std::mem::take(&mut state.finished_steps);

View File

@ -723,12 +723,9 @@ function loadCss(cssUrl) {
});
};
(function() {
// To avoid checking on "rustdoc-line-numbers" value on every loop...
if (getSettingValue("line-numbers") === "true") {
window.rustdoc_add_line_numbers_to_examples();
}
}());
if (getSettingValue("line-numbers") === "true") {
window.rustdoc_add_line_numbers_to_examples();
}
let oldSidebarScrollPosition = null;

View File

@ -0,0 +1,22 @@
#[derive(Default)]
struct Inner {
a: u8,
b: u8,
}
#[derive(Default)]
struct Outer {
inner: Inner,
defaulted: u8,
}
fn main(){
Outer {
//~^ ERROR missing field `defaulted` in initializer of `Outer`
inner: Inner {
a: 1,
b: 2,
}
..Default::default()
};
}

View File

@ -0,0 +1,25 @@
error[E0063]: missing field `defaulted` in initializer of `Outer`
--> $DIR/multi-line-fru-suggestion.rs:14:5
|
LL | Outer {
| ^^^^^ missing `defaulted`
|
note: this expression may have been misinterpreted as a `..` range expression
--> $DIR/multi-line-fru-suggestion.rs:16:16
|
LL | inner: Inner {
| ________________^
LL | | a: 1,
LL | | b: 2,
LL | | }
| |_________^ this expression does not end in a comma...
LL | ..Default::default()
| ^^^^^^^^^^^^^^^^^^^^ ... so this is interpreted as a `..` range expression, instead of functional record update syntax
help: to set the remaining fields from `Default::default()`, separate the last named field with a comma
|
LL | },
| +
error: aborting due to previous error
For more information about this error, try `rustc --explain E0063`.

View File

@ -7,9 +7,8 @@ struct A {
}
fn a() {
let q = A { c: 5,..Default::default() };
//~^ ERROR mismatched types
//~| ERROR missing fields
let q = A { c: 5, ..Default::default() };
//~^ ERROR missing fields
//~| HELP separate the last named field with a comma
let r = A { c: 5, ..Default::default() };
assert_eq!(q, r);
@ -21,7 +20,7 @@ struct B {
}
fn b() {
let q = B { b: 1,..Default::default() };
let q = B { b: 1, ..Default::default() };
//~^ ERROR mismatched types
//~| HELP separate the last named field with a comma
let r = B { b: 1 };

View File

@ -8,8 +8,7 @@ struct A {
fn a() {
let q = A { c: 5..Default::default() };
//~^ ERROR mismatched types
//~| ERROR missing fields
//~^ ERROR missing fields
//~| HELP separate the last named field with a comma
let r = A { c: 5, ..Default::default() };
assert_eq!(q, r);

View File

@ -1,37 +1,38 @@
error[E0308]: mismatched types
--> $DIR/struct-record-suggestion.rs:10:20
|
LL | let q = A { c: 5..Default::default() };
| ^^^^^^^^^^^^^^^^^^^^^ expected `u64`, found struct `std::ops::Range`
|
= note: expected type `u64`
found struct `std::ops::Range<{integer}>`
error[E0063]: missing fields `b` and `d` in initializer of `A`
--> $DIR/struct-record-suggestion.rs:10:13
|
LL | let q = A { c: 5..Default::default() };
| ^ missing `b` and `d`
|
note: this expression may have been misinterpreted as a `..` range expression
--> $DIR/struct-record-suggestion.rs:10:20
|
LL | let q = A { c: 5..Default::default() };
| ^^^^^^^^^^^^^^^^^^^^^
help: to set the remaining fields from `Default::default()`, separate the last named field with a comma
|
LL | let q = A { c: 5,..Default::default() };
LL | let q = A { c: 5, ..Default::default() };
| +
error[E0308]: mismatched types
--> $DIR/struct-record-suggestion.rs:24:20
--> $DIR/struct-record-suggestion.rs:23:20
|
LL | let q = B { b: 1..Default::default() };
| ^^^^^^^^^^^^^^^^^^^^^ expected `u32`, found struct `std::ops::Range`
|
= note: expected type `u32`
found struct `std::ops::Range<{integer}>`
note: this expression may have been misinterpreted as a `..` range expression
--> $DIR/struct-record-suggestion.rs:23:20
|
LL | let q = B { b: 1..Default::default() };
| ^^^^^^^^^^^^^^^^^^^^^
help: to set the remaining fields from `Default::default()`, separate the last named field with a comma
|
LL | let q = B { b: 1,..Default::default() };
LL | let q = B { b: 1, ..Default::default() };
| +
error: aborting due to 3 previous errors
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0063, E0308.
For more information about an error, try `rustc --explain E0063`.