Auto merge of #55009 - oli-obk:const_safety, r=RalfJung
Make raw ptr ops unsafe in const contexts
r? @RalfJung
cc @Centril
diff --git a/src/doc/unstable-book/src/library-features/is-sorted.md b/src/doc/unstable-book/src/library-features/is-sorted.md
new file mode 100644
index 0000000..e3b7dc3
--- /dev/null
+++ b/src/doc/unstable-book/src/library-features/is-sorted.md
@@ -0,0 +1,11 @@
+# `is_sorted`
+
+The tracking issue for this feature is: [#53485]
+
+[#53485]: https://github.com/rust-lang/rust/issues/53485
+
+------------------------
+
+Add the methods `is_sorted`, `is_sorted_by` and `is_sorted_by_key` to `[T]`;
+add the methods `is_sorted`, `is_sorted_by` and `is_sorted_by_key` to
+`Iterator`.
diff --git a/src/libcore/convert.rs b/src/libcore/convert.rs
index 08b5ac0..203be54 100644
--- a/src/libcore/convert.rs
+++ b/src/libcore/convert.rs
@@ -463,11 +463,11 @@
// Infallible conversions are semantically equivalent to fallible conversions
// with an uninhabited error type.
#[unstable(feature = "try_from", issue = "33417")]
-impl<T, U> TryFrom<U> for T where T: From<U> {
+impl<T, U> TryFrom<U> for T where U: Into<T> {
type Error = !;
fn try_from(value: U) -> Result<Self, Self::Error> {
- Ok(T::from(value))
+ Ok(U::into(value))
}
}
diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs
index 0ad29af..ac21586 100644
--- a/src/libcore/iter/iterator.rs
+++ b/src/libcore/iter/iterator.rs
@@ -2605,6 +2605,95 @@
}
}
}
+
+ /// Checks if the elements of this iterator are sorted.
+ ///
+ /// That is, for each element `a` and its following element `b`, `a <= b` must hold. If the
+ /// iterator yields exactly zero or one element, `true` is returned.
+ ///
+ /// Note that if `Self::Item` is only `PartialOrd`, but not `Ord`, the above definition
+ /// implies that this function returns `false` if any two consecutive items are not
+ /// comparable.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(is_sorted)]
+ ///
+ /// assert!([1, 2, 2, 9].iter().is_sorted());
+ /// assert!(![1, 3, 2, 4].iter().is_sorted());
+ /// assert!([0].iter().is_sorted());
+ /// assert!(std::iter::empty::<i32>().is_sorted());
+ /// assert!(![0.0, 1.0, std::f32::NAN].iter().is_sorted());
+ /// ```
+ #[inline]
+ #[unstable(feature = "is_sorted", reason = "new API", issue = "53485")]
+ fn is_sorted(self) -> bool
+ where
+ Self: Sized,
+ Self::Item: PartialOrd,
+ {
+ self.is_sorted_by(|a, b| a.partial_cmp(b))
+ }
+
+ /// Checks if the elements of this iterator are sorted using the given comparator function.
+ ///
+ /// Instead of using `PartialOrd::partial_cmp`, this function uses the given `compare`
+ /// function to determine the ordering of two elements. Apart from that, it's equivalent to
+ /// [`is_sorted`]; see its documentation for more information.
+ ///
+ /// [`is_sorted`]: trait.Iterator.html#method.is_sorted
+ #[unstable(feature = "is_sorted", reason = "new API", issue = "53485")]
+ fn is_sorted_by<F>(mut self, mut compare: F) -> bool
+ where
+ Self: Sized,
+ F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>
+ {
+ let mut last = match self.next() {
+ Some(e) => e,
+ None => return true,
+ };
+
+ while let Some(curr) = self.next() {
+ if compare(&last, &curr)
+ .map(|o| o == Ordering::Greater)
+ .unwrap_or(true)
+ {
+ return false;
+ }
+ last = curr;
+ }
+
+ true
+ }
+
+ /// Checks if the elements of this iterator are sorted using the given key extraction
+ /// function.
+ ///
+ /// Instead of comparing the iterator's elements directly, this function compares the keys of
+ /// the elements, as determined by `f`. Apart from that, it's equivalent to [`is_sorted`]; see
+ /// its documentation for more information.
+ ///
+ /// [`is_sorted`]: trait.Iterator.html#method.is_sorted
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(is_sorted)]
+ ///
+ /// assert!(["c", "bb", "aaa"].iter().is_sorted_by_key(|s| s.len()));
+ /// assert!(![-2i32, -1, 0, 3].iter().is_sorted_by_key(|n| n.abs()));
+ /// ```
+ #[inline]
+ #[unstable(feature = "is_sorted", reason = "new API", issue = "53485")]
+ fn is_sorted_by_key<F, K>(self, mut f: F) -> bool
+ where
+ Self: Sized,
+ F: FnMut(&Self::Item) -> K,
+ K: PartialOrd
+ {
+ self.is_sorted_by(|a, b| f(a).partial_cmp(&f(b)))
+ }
}
/// Select an element from an iterator based on the given "projection"
diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs
index 33c0da8..df32cfa 100644
--- a/src/libcore/lib.rs
+++ b/src/libcore/lib.rs
@@ -79,6 +79,7 @@
#![feature(extern_types)]
#![feature(fundamental)]
#![feature(intrinsics)]
+#![feature(is_sorted)]
#![feature(iter_once_with)]
#![feature(lang_items)]
#![feature(link_llvm_intrinsics)]
diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs
index 7fdc2ac..df4d97e 100644
--- a/src/libcore/slice/mod.rs
+++ b/src/libcore/slice/mod.rs
@@ -1783,7 +1783,7 @@
/// let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
/// a[1..5].rotate_left(1);
/// assert_eq!(a, ['a', 'c', 'd', 'e', 'b', 'f']);
- /// ```
+ /// ```
#[stable(feature = "slice_rotate", since = "1.26.0")]
pub fn rotate_left(&mut self, mid: usize) {
assert!(mid <= self.len());
@@ -2250,6 +2250,77 @@
from_raw_parts_mut(mut_ptr.add(rest.len() - ts_len), ts_len))
}
}
+
+ /// Checks if the elements of this slice are sorted.
+ ///
+ /// That is, for each element `a` and its following element `b`, `a <= b` must hold. If the
+ /// slice yields exactly zero or one element, `true` is returned.
+ ///
+ /// Note that if `Self::Item` is only `PartialOrd`, but not `Ord`, the above definition
+ /// implies that this function returns `false` if any two consecutive items are not
+ /// comparable.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(is_sorted)]
+ /// let empty: [i32; 0] = [];
+ ///
+ /// assert!([1, 2, 2, 9].is_sorted());
+ /// assert!(![1, 3, 2, 4].is_sorted());
+ /// assert!([0].is_sorted());
+ /// assert!(empty.is_sorted());
+ /// assert!(![0.0, 1.0, std::f32::NAN].is_sorted());
+ /// ```
+ #[inline]
+ #[unstable(feature = "is_sorted", reason = "new API", issue = "53485")]
+ pub fn is_sorted(&self) -> bool
+ where
+ T: PartialOrd,
+ {
+ self.is_sorted_by(|a, b| a.partial_cmp(b))
+ }
+
+ /// Checks if the elements of this slice are sorted using the given comparator function.
+ ///
+ /// Instead of using `PartialOrd::partial_cmp`, this function uses the given `compare`
+ /// function to determine the ordering of two elements. Apart from that, it's equivalent to
+ /// [`is_sorted`]; see its documentation for more information.
+ ///
+ /// [`is_sorted`]: #method.is_sorted
+ #[unstable(feature = "is_sorted", reason = "new API", issue = "53485")]
+ pub fn is_sorted_by<F>(&self, mut compare: F) -> bool
+ where
+ F: FnMut(&T, &T) -> Option<Ordering>
+ {
+ self.iter().is_sorted_by(|a, b| compare(*a, *b))
+ }
+
+ /// Checks if the elements of this slice are sorted using the given key extraction function.
+ ///
+ /// Instead of comparing the slice's elements directly, this function compares the keys of the
+ /// elements, as determined by `f`. Apart from that, it's equivalent to [`is_sorted`]; see its
+ /// documentation for more information.
+ ///
+ /// [`is_sorted`]: #method.is_sorted
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(is_sorted)]
+ ///
+ /// assert!(["c", "bb", "aaa"].is_sorted_by_key(|s| s.len()));
+ /// assert!(![-2i32, -1, 0, 3].is_sorted_by_key(|n| n.abs()));
+ /// ```
+ #[inline]
+ #[unstable(feature = "is_sorted", reason = "new API", issue = "53485")]
+ pub fn is_sorted_by_key<F, K>(&self, mut f: F) -> bool
+ where
+ F: FnMut(&T) -> K,
+ K: PartialOrd
+ {
+ self.is_sorted_by(|a, b| f(a).partial_cmp(&f(b)))
+ }
}
#[lang = "slice_u8"]
@@ -2773,7 +2844,13 @@
// The shared definition of the `Iter` and `IterMut` iterators
macro_rules! iterator {
- (struct $name:ident -> $ptr:ty, $elem:ty, $raw_mut:tt, $( $mut_:tt )*) => {
+ (
+ struct $name:ident -> $ptr:ty,
+ $elem:ty,
+ $raw_mut:tt,
+ {$( $mut_:tt )*},
+ {$($extra:tt)*}
+ ) => {
impl<'a, T> $name<'a, T> {
// Helper function for creating a slice from the iterator.
#[inline(always)]
@@ -2950,6 +3027,8 @@
i
})
}
+
+ $($extra)*
}
#[stable(feature = "rust1", since = "1.0.0")]
@@ -3087,7 +3166,17 @@
}
}
-iterator!{struct Iter -> *const T, &'a T, const, /* no mut */}
+iterator!{struct Iter -> *const T, &'a T, const, {/* no mut */}, {
+ fn is_sorted_by<F>(self, mut compare: F) -> bool
+ where
+ Self: Sized,
+ F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>,
+ {
+ self.as_slice().windows(2).all(|w| {
+ compare(&&w[0], &&w[1]).map(|o| o != Ordering::Greater).unwrap_or(false)
+ })
+ }
+}}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> Clone for Iter<'_, T> {
@@ -3188,7 +3277,7 @@
}
}
-iterator!{struct IterMut -> *mut T, &'a mut T, mut, mut}
+iterator!{struct IterMut -> *mut T, &'a mut T, mut, {mut}, {}}
/// An internal abstraction over the splitting iterators, so that
/// splitn, splitn_mut etc can be implemented once.
diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs
index 3944bc7..0fa9974 100644
--- a/src/libcore/tests/iter.rs
+++ b/src/libcore/tests/iter.rs
@@ -2235,3 +2235,16 @@
assert_eq!((0..10).flat_map(f).flat_map(g).sum::<usize>(),
(0..10).flat_map(|x| f(x).flat_map(g)).sum::<usize>());
}
+
+#[test]
+fn test_is_sorted() {
+ assert!([1, 2, 2, 9].iter().is_sorted());
+ assert!(![1, 3, 2].iter().is_sorted());
+ assert!([0].iter().is_sorted());
+ assert!(std::iter::empty::<i32>().is_sorted());
+ assert!(![0.0, 1.0, std::f32::NAN].iter().is_sorted());
+ assert!([-2, -1, 0, 3].iter().is_sorted());
+ assert!(![-2i32, -1, 0, 3].iter().is_sorted_by_key(|n| n.abs()));
+ assert!(!["c", "bb", "aaa"].iter().is_sorted());
+ assert!(["c", "bb", "aaa"].iter().is_sorted_by_key(|s| s.len()));
+}
diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs
index a9b8dec..3e8549f 100644
--- a/src/libcore/tests/lib.rs
+++ b/src/libcore/tests/lib.rs
@@ -10,6 +10,7 @@
#![feature(flt2dec)]
#![feature(fmt_internals)]
#![feature(hashmap_internals)]
+#![feature(is_sorted)]
#![feature(iter_copied)]
#![feature(iter_nth_back)]
#![feature(iter_once_with)]
diff --git a/src/libcore/tests/slice.rs b/src/libcore/tests/slice.rs
index 2c96efb..e210e83 100644
--- a/src/libcore/tests/slice.rs
+++ b/src/libcore/tests/slice.rs
@@ -1317,3 +1317,18 @@
// 2 is greater than 1, so this range is invalid.
bytes.copy_within(2..1, 0);
}
+
+#[test]
+fn test_is_sorted() {
+ let empty: [i32; 0] = [];
+
+ assert!([1, 2, 2, 9].is_sorted());
+ assert!(![1, 3, 2].is_sorted());
+ assert!([0].is_sorted());
+ assert!(empty.is_sorted());
+ assert!(![0.0, 1.0, std::f32::NAN].is_sorted());
+ assert!([-2, -1, 0, 3].is_sorted());
+ assert!(![-2i32, -1, 0, 3].is_sorted_by_key(|n| n.abs()));
+ assert!(!["c", "bb", "aaa"].is_sorted());
+ assert!(["c", "bb", "aaa"].is_sorted_by_key(|s| s.len()));
+}
diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index 2f7d8f0..f7af135 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -31,6 +31,7 @@
//! in the HIR, especially for multiple identifiers.
use dep_graph::DepGraph;
+use errors::Applicability;
use hir::{self, ParamName};
use hir::HirVec;
use hir::map::{DefKey, DefPathData, Definitions};
@@ -1806,7 +1807,7 @@
explicit_owner: Option<NodeId>,
) -> hir::PathSegment {
let (mut generic_args, infer_types) = if let Some(ref generic_args) = segment.args {
- let msg = "parenthesized parameters may only be used with a trait";
+ let msg = "parenthesized type parameters may only be used with a `Fn` trait";
match **generic_args {
GenericArgs::AngleBracketed(ref data) => {
self.lower_angle_bracketed_parameter_data(data, param_mode, itctx)
@@ -1823,10 +1824,25 @@
(hir::GenericArgs::none(), true)
}
ParenthesizedGenericArgs::Err => {
- struct_span_err!(self.sess, data.span, E0214, "{}", msg)
- .span_label(data.span, "only traits may use parentheses")
- .emit();
- (hir::GenericArgs::none(), true)
+ let mut err = struct_span_err!(self.sess, data.span, E0214, "{}", msg);
+ err.span_label(data.span, "only `Fn` traits may use parentheses");
+ if let Ok(snippet) = self.sess.source_map().span_to_snippet(data.span) {
+ // Do not suggest going from `Trait()` to `Trait<>`
+ if data.inputs.len() > 0 {
+ err.span_suggestion_with_applicability(
+ data.span,
+ "use angle brackets instead",
+ format!("<{}>", &snippet[1..snippet.len() - 1]),
+ Applicability::MaybeIncorrect,
+ );
+ }
+ };
+ err.emit();
+ (self.lower_angle_bracketed_parameter_data(
+ &data.as_angle_bracketed_args(),
+ param_mode,
+ itctx).0,
+ false)
}
},
}
diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs
index 2995b25..35f6e6a 100644
--- a/src/librustc/infer/error_reporting/mod.rs
+++ b/src/librustc/infer/error_reporting/mod.rs
@@ -485,12 +485,29 @@
}
}
- fn note_error_origin(&self, err: &mut DiagnosticBuilder<'tcx>, cause: &ObligationCause<'tcx>) {
+ fn note_error_origin(
+ &self,
+ err: &mut DiagnosticBuilder<'tcx>,
+ cause: &ObligationCause<'tcx>,
+ exp_found: Option<ty::error::ExpectedFound<Ty<'tcx>>>,
+ ) {
match cause.code {
ObligationCauseCode::MatchExpressionArmPattern { span, ty } => {
if ty.is_suggestable() { // don't show type `_`
err.span_label(span, format!("this match expression has type `{}`", ty));
}
+ if let Some(ty::error::ExpectedFound { found, .. }) = exp_found {
+ if ty.is_box() && ty.boxed_ty() == found {
+ if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) {
+ err.span_suggestion_with_applicability(
+ span,
+ "consider dereferencing the boxed value",
+ format!("*{}", snippet),
+ Applicability::MachineApplicable,
+ );
+ }
+ }
+ }
}
ObligationCauseCode::MatchExpressionArm { arm_span, source } => match source {
hir::MatchSource::IfLetDesugar { .. } => {
@@ -1013,7 +1030,7 @@
// It reads better to have the error origin as the final
// thing.
- self.note_error_origin(diag, &cause);
+ self.note_error_origin(diag, &cause, exp_found);
}
/// When encountering a case where `.as_ref()` on a `Result` or `Option` would be appropriate,
diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs
index c0cedd7..d985bda 100644
--- a/src/librustc_typeck/check/demand.rs
+++ b/src/librustc_typeck/check/demand.rs
@@ -454,12 +454,13 @@
false
}
- pub fn check_for_cast(&self,
- err: &mut DiagnosticBuilder<'tcx>,
- expr: &hir::Expr,
- checked_ty: Ty<'tcx>,
- expected_ty: Ty<'tcx>)
- -> bool {
+ pub fn check_for_cast(
+ &self,
+ err: &mut DiagnosticBuilder<'tcx>,
+ expr: &hir::Expr,
+ checked_ty: Ty<'tcx>,
+ expected_ty: Ty<'tcx>,
+ ) -> bool {
let parent_id = self.tcx.hir().get_parent_node(expr.id);
if let Some(parent) = self.tcx.hir().find(parent_id) {
// Shouldn't suggest `.into()` on `const`s.
@@ -487,17 +488,40 @@
// For now, don't suggest casting with `as`.
let can_cast = false;
+ let mut prefix = String::new();
+ if let Some(hir::Node::Expr(hir::Expr {
+ node: hir::ExprKind::Struct(_, fields, _),
+ ..
+ })) = self.tcx.hir().find(self.tcx.hir().get_parent_node(expr.id)) {
+ // `expr` is a literal field for a struct, only suggest if appropriate
+ for field in fields {
+ if field.expr.id == expr.id && field.is_shorthand {
+ // This is a field literal
+ prefix = format!("{}: ", field.ident);
+ break;
+ }
+ }
+ if &prefix == "" {
+ // Likely a field was meant, but this field wasn't found. Do not suggest anything.
+ return false;
+ }
+ }
+
let needs_paren = expr.precedence().order() < (PREC_POSTFIX as i8);
if let Ok(src) = self.tcx.sess.source_map().span_to_snippet(expr.span) {
let msg = format!("you can cast an `{}` to `{}`", checked_ty, expected_ty);
- let cast_suggestion = format!("{}{}{} as {}",
- if needs_paren { "(" } else { "" },
- src,
- if needs_paren { ")" } else { "" },
- expected_ty);
+ let cast_suggestion = format!(
+ "{}{}{}{} as {}",
+ prefix,
+ if needs_paren { "(" } else { "" },
+ src,
+ if needs_paren { ")" } else { "" },
+ expected_ty,
+ );
let into_suggestion = format!(
- "{}{}{}.into()",
+ "{}{}{}{}.into()",
+ prefix,
if needs_paren { "(" } else { "" },
src,
if needs_paren { ")" } else { "" },
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index f411e40..405cf61 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -192,6 +192,16 @@
pub output: Option<P<Ty>>,
}
+impl ParenthesisedArgs {
+ pub fn as_angle_bracketed_args(&self) -> AngleBracketedArgs {
+ AngleBracketedArgs {
+ span: self.span,
+ args: self.inputs.iter().cloned().map(|input| GenericArg::Type(input)).collect(),
+ bindings: vec![],
+ }
+ }
+}
+
// hack to ensure that we don't try to access the private parts of `NodeId` in this module
mod node_id_inner {
use rustc_data_structures::indexed_vec::Idx;
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 7e15b231..439eec5 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -2176,11 +2176,11 @@
style != PathStyle::Mod && self.check(&token::ModSep)
&& self.look_ahead(1, |t| is_args_start(t)) {
// Generic arguments are found - `<`, `(`, `::<` or `::(`.
- let lo = self.span;
if self.eat(&token::ModSep) && style == PathStyle::Type && enable_warning {
self.diagnostic().struct_span_warn(self.prev_span, "unnecessary path disambiguator")
.span_label(self.prev_span, "try removing `::`").emit();
}
+ let lo = self.span;
let args = if self.eat_lt() {
// `<'a, T, A = U>`
@@ -4483,13 +4483,17 @@
}
/// Emit an expected item after attributes error.
- fn expected_item_err(&self, attrs: &[Attribute]) {
+ fn expected_item_err(&mut self, attrs: &[Attribute]) -> PResult<'a, ()> {
let message = match attrs.last() {
Some(&Attribute { is_sugared_doc: true, .. }) => "expected item after doc comment",
_ => "expected item after attributes",
};
- self.span_err(self.prev_span, message);
+ let mut err = self.diagnostic().struct_span_err(self.prev_span, message);
+ if attrs.last().unwrap().is_sugared_doc {
+ err.span_label(self.prev_span, "this doc comment doesn't document anything");
+ }
+ Err(err)
}
/// Parse a statement. This stops just before trailing semicolons on everything but items.
@@ -7636,7 +7640,7 @@
}
None => {
if !attrs.is_empty() {
- self.expected_item_err(&attrs);
+ self.expected_item_err(&attrs)?;
}
self.unexpected()
@@ -7699,7 +7703,7 @@
}
if !attributes_allowed && !attrs.is_empty() {
- self.expected_item_err(&attrs);
+ self.expected_item_err(&attrs)?;
}
Ok(None)
}
diff --git a/src/test/run-pass/try_from.rs b/src/test/run-pass/try_from.rs
new file mode 100644
index 0000000..4522ce3
--- /dev/null
+++ b/src/test/run-pass/try_from.rs
@@ -0,0 +1,37 @@
+// This test relies on `TryFrom` being blanket impl for all `T: Into`
+// and `TryInto` being blanket impl for all `U: TryFrom`
+
+// This test was added to show the motivation for doing this
+// over `TryFrom` being blanket impl for all `T: From`
+
+#![feature(try_from, never_type)]
+
+use std::convert::TryInto;
+
+struct Foo<T> {
+ t: T,
+}
+
+// This fails to compile due to coherence restrictions
+// as of Rust version 1.32.x, therefore it could not be used
+// instead of the `Into` version of the impl, and serves as
+// motivation for a blanket impl for all `T: Into`, instead
+// of a blanket impl for all `T: From`
+/*
+impl<T> From<Foo<T>> for Box<T> {
+ fn from(foo: Foo<T>) -> Box<T> {
+ Box::new(foo.t)
+ }
+}
+*/
+
+impl<T> Into<Vec<T>> for Foo<T> {
+ fn into(self) -> Vec<T> {
+ vec![self.t]
+ }
+}
+
+pub fn main() {
+ let _: Result<Vec<i32>, !> = Foo { t: 10 }.try_into();
+}
+
diff --git a/src/test/ui/e0119/conflict-with-std.stderr b/src/test/ui/e0119/conflict-with-std.stderr
index d94e4dc..c2ae321 100644
--- a/src/test/ui/e0119/conflict-with-std.stderr
+++ b/src/test/ui/e0119/conflict-with-std.stderr
@@ -25,7 +25,7 @@
|
= note: conflicting implementation in crate `core`:
- impl<T, U> std::convert::TryFrom<U> for T
- where T: std::convert::From<U>;
+ where U: std::convert::Into<T>;
error: aborting due to 3 previous errors
diff --git a/src/test/ui/error-codes/E0214.stderr b/src/test/ui/error-codes/E0214.stderr
index 08a98b1..a10f2c0 100644
--- a/src/test/ui/error-codes/E0214.stderr
+++ b/src/test/ui/error-codes/E0214.stderr
@@ -1,8 +1,11 @@
-error[E0214]: parenthesized parameters may only be used with a trait
+error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
--> $DIR/E0214.rs:2:15
|
LL | let v: Vec(&str) = vec!["foo"];
- | ^^^^^^ only traits may use parentheses
+ | ^^^^^^
+ | |
+ | only `Fn` traits may use parentheses
+ | help: use angle brackets instead: `<&str>`
error: aborting due to previous error
diff --git a/src/test/ui/feature-gates/feature-gate-is_sorted.rs b/src/test/ui/feature-gates/feature-gate-is_sorted.rs
new file mode 100644
index 0000000..078ecc5
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-is_sorted.rs
@@ -0,0 +1,13 @@
+fn main() {
+ // Assert `Iterator` methods are feature gated
+ assert!([1, 2, 2, 9].iter().is_sorted());
+ //~^ ERROR: use of unstable library feature 'is_sorted': new API
+ assert!(![-2i32, -1, 0, 3].iter().is_sorted_by_key(|n| n.abs()));
+ //~^ ERROR: use of unstable library feature 'is_sorted': new API
+
+ // Assert `[T]` methods are feature gated
+ assert!([1, 2, 2, 9].is_sorted());
+ //~^ ERROR: use of unstable library feature 'is_sorted': new API
+ assert!(![-2i32, -1, 0, 3].is_sorted_by_key(|n| n.abs()));
+ //~^ ERROR: use of unstable library feature 'is_sorted': new API
+}
diff --git a/src/test/ui/feature-gates/feature-gate-is_sorted.stderr b/src/test/ui/feature-gates/feature-gate-is_sorted.stderr
new file mode 100644
index 0000000..8230c1e
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-is_sorted.stderr
@@ -0,0 +1,35 @@
+error[E0658]: use of unstable library feature 'is_sorted': new API (see issue #53485)
+ --> $DIR/feature-gate-is_sorted.rs:3:33
+ |
+LL | assert!([1, 2, 2, 9].iter().is_sorted());
+ | ^^^^^^^^^
+ |
+ = help: add #![feature(is_sorted)] to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'is_sorted': new API (see issue #53485)
+ --> $DIR/feature-gate-is_sorted.rs:5:39
+ |
+LL | assert!(![-2i32, -1, 0, 3].iter().is_sorted_by_key(|n| n.abs()));
+ | ^^^^^^^^^^^^^^^^
+ |
+ = help: add #![feature(is_sorted)] to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'is_sorted': new API (see issue #53485)
+ --> $DIR/feature-gate-is_sorted.rs:9:26
+ |
+LL | assert!([1, 2, 2, 9].is_sorted());
+ | ^^^^^^^^^
+ |
+ = help: add #![feature(is_sorted)] to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'is_sorted': new API (see issue #53485)
+ --> $DIR/feature-gate-is_sorted.rs:11:32
+ |
+LL | assert!(![-2i32, -1, 0, 3].is_sorted_by_key(|n| n.abs()));
+ | ^^^^^^^^^^^^^^^^
+ |
+ = help: add #![feature(is_sorted)] to the crate attributes to enable
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/issues/issue-23589.rs b/src/test/ui/issues/issue-23589.rs
index a59710a..1c640af 100644
--- a/src/test/ui/issues/issue-23589.rs
+++ b/src/test/ui/issues/issue-23589.rs
@@ -1,4 +1,5 @@
fn main() {
let v: Vec(&str) = vec!['1', '2'];
- //~^ ERROR parenthesized parameters may only be used with a trait
+ //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait
+ //~| ERROR mismatched types
}
diff --git a/src/test/ui/issues/issue-23589.stderr b/src/test/ui/issues/issue-23589.stderr
index e6e07c1..bc2007b 100644
--- a/src/test/ui/issues/issue-23589.stderr
+++ b/src/test/ui/issues/issue-23589.stderr
@@ -1,9 +1,22 @@
-error[E0214]: parenthesized parameters may only be used with a trait
+error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
--> $DIR/issue-23589.rs:2:15
|
LL | let v: Vec(&str) = vec!['1', '2'];
- | ^^^^^^ only traits may use parentheses
+ | ^^^^^^
+ | |
+ | only `Fn` traits may use parentheses
+ | help: use angle brackets instead: `<&str>`
-error: aborting due to previous error
+error[E0308]: mismatched types
+ --> $DIR/issue-23589.rs:2:29
+ |
+LL | let v: Vec(&str) = vec!['1', '2'];
+ | ^^^ expected &str, found char
+ |
+ = note: expected type `&str`
+ found type `char`
-For more information about this error, try `rustc --explain E0214`.
+error: aborting due to 2 previous errors
+
+Some errors occurred: E0214, E0308.
+For more information about an error, try `rustc --explain E0214`.
diff --git a/src/test/ui/issues/issue-32995-2.rs b/src/test/ui/issues/issue-32995-2.rs
index a4e333e..2234f68 100644
--- a/src/test/ui/issues/issue-32995-2.rs
+++ b/src/test/ui/issues/issue-32995-2.rs
@@ -2,11 +2,11 @@
fn main() {
{ fn f<X: ::std::marker()::Send>() {} }
- //~^ ERROR parenthesized parameters may only be used with a trait
+ //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait
//~| WARN previously accepted
{ fn f() -> impl ::std::marker()::Send { } }
- //~^ ERROR parenthesized parameters may only be used with a trait
+ //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait
//~| WARN previously accepted
}
@@ -14,5 +14,5 @@
struct X;
impl ::std::marker()::Copy for X {}
-//~^ ERROR parenthesized parameters may only be used with a trait
+//~^ ERROR parenthesized type parameters may only be used with a `Fn` trait
//~| WARN previously accepted
diff --git a/src/test/ui/issues/issue-32995-2.stderr b/src/test/ui/issues/issue-32995-2.stderr
index 0ac12b7..104b76c 100644
--- a/src/test/ui/issues/issue-32995-2.stderr
+++ b/src/test/ui/issues/issue-32995-2.stderr
@@ -1,4 +1,4 @@
-error: parenthesized parameters may only be used with a trait
+error: parenthesized type parameters may only be used with a `Fn` trait
--> $DIR/issue-32995-2.rs:4:28
|
LL | { fn f<X: ::std::marker()::Send>() {} }
@@ -8,7 +8,7 @@
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #42238 <https://github.com/rust-lang/rust/issues/42238>
-error: parenthesized parameters may only be used with a trait
+error: parenthesized type parameters may only be used with a `Fn` trait
--> $DIR/issue-32995-2.rs:8:35
|
LL | { fn f() -> impl ::std::marker()::Send { } }
@@ -17,7 +17,7 @@
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #42238 <https://github.com/rust-lang/rust/issues/42238>
-error: parenthesized parameters may only be used with a trait
+error: parenthesized type parameters may only be used with a `Fn` trait
--> $DIR/issue-32995-2.rs:16:19
|
LL | impl ::std::marker()::Copy for X {}
diff --git a/src/test/ui/issues/issue-32995.rs b/src/test/ui/issues/issue-32995.rs
index 726cc85..c32fb63 100644
--- a/src/test/ui/issues/issue-32995.rs
+++ b/src/test/ui/issues/issue-32995.rs
@@ -2,32 +2,32 @@
fn main() {
let x: usize() = 1;
- //~^ ERROR parenthesized parameters may only be used with a trait
+ //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait
//~| WARN previously accepted
let b: ::std::boxed()::Box<_> = Box::new(1);
- //~^ ERROR parenthesized parameters may only be used with a trait
+ //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait
//~| WARN previously accepted
let p = ::std::str::()::from_utf8(b"foo").unwrap();
- //~^ ERROR parenthesized parameters may only be used with a trait
+ //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait
//~| WARN previously accepted
let p = ::std::str::from_utf8::()(b"foo").unwrap();
- //~^ ERROR parenthesized parameters may only be used with a trait
+ //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait
//~| WARN previously accepted
let o : Box<::std::marker()::Send> = Box::new(1);
- //~^ ERROR parenthesized parameters may only be used with a trait
+ //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait
//~| WARN previously accepted
let o : Box<Send + ::std::marker()::Sync> = Box::new(1);
- //~^ ERROR parenthesized parameters may only be used with a trait
+ //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait
//~| WARN previously accepted
}
fn foo<X:Default>() {
let d : X() = Default::default();
- //~^ ERROR parenthesized parameters may only be used with a trait
+ //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait
//~| WARN previously accepted
}
diff --git a/src/test/ui/issues/issue-32995.stderr b/src/test/ui/issues/issue-32995.stderr
index 12551bb..97b4b7fa 100644
--- a/src/test/ui/issues/issue-32995.stderr
+++ b/src/test/ui/issues/issue-32995.stderr
@@ -1,4 +1,4 @@
-error: parenthesized parameters may only be used with a trait
+error: parenthesized type parameters may only be used with a `Fn` trait
--> $DIR/issue-32995.rs:4:17
|
LL | let x: usize() = 1;
@@ -8,7 +8,7 @@
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #42238 <https://github.com/rust-lang/rust/issues/42238>
-error: parenthesized parameters may only be used with a trait
+error: parenthesized type parameters may only be used with a `Fn` trait
--> $DIR/issue-32995.rs:8:24
|
LL | let b: ::std::boxed()::Box<_> = Box::new(1);
@@ -17,25 +17,25 @@
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #42238 <https://github.com/rust-lang/rust/issues/42238>
-error: parenthesized parameters may only be used with a trait
- --> $DIR/issue-32995.rs:12:23
+error: parenthesized type parameters may only be used with a `Fn` trait
+ --> $DIR/issue-32995.rs:12:25
|
LL | let p = ::std::str::()::from_utf8(b"foo").unwrap();
- | ^^^^
+ | ^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #42238 <https://github.com/rust-lang/rust/issues/42238>
-error: parenthesized parameters may only be used with a trait
- --> $DIR/issue-32995.rs:16:34
+error: parenthesized type parameters may only be used with a `Fn` trait
+ --> $DIR/issue-32995.rs:16:36
|
LL | let p = ::std::str::from_utf8::()(b"foo").unwrap();
- | ^^^^
+ | ^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #42238 <https://github.com/rust-lang/rust/issues/42238>
-error: parenthesized parameters may only be used with a trait
+error: parenthesized type parameters may only be used with a `Fn` trait
--> $DIR/issue-32995.rs:20:30
|
LL | let o : Box<::std::marker()::Send> = Box::new(1);
@@ -44,7 +44,7 @@
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #42238 <https://github.com/rust-lang/rust/issues/42238>
-error: parenthesized parameters may only be used with a trait
+error: parenthesized type parameters may only be used with a `Fn` trait
--> $DIR/issue-32995.rs:24:37
|
LL | let o : Box<Send + ::std::marker()::Sync> = Box::new(1);
@@ -53,7 +53,7 @@
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #42238 <https://github.com/rust-lang/rust/issues/42238>
-error: parenthesized parameters may only be used with a trait
+error: parenthesized type parameters may only be used with a `Fn` trait
--> $DIR/issue-32995.rs:30:14
|
LL | let d : X() = Default::default();
diff --git a/src/test/ui/issues/issue-57741-1.rs b/src/test/ui/issues/issue-57741-1.rs
new file mode 100644
index 0000000..d0aae23
--- /dev/null
+++ b/src/test/ui/issues/issue-57741-1.rs
@@ -0,0 +1,18 @@
+#![allow(warnings)]
+
+// This tests that the `help: consider dereferencing the boxed value` suggestion isn't made
+// because the box doesn't deref to the type of the arm.
+
+enum S {
+ A { a: usize },
+ B { b: usize },
+}
+
+fn main() {
+ let x = Box::new(3u32);
+ let y = match x {
+ S::A { a } | S::B { b: a } => a,
+ //~^ ERROR mismatched types [E0308]
+ //~^^ ERROR mismatched types [E0308]
+ };
+}
diff --git a/src/test/ui/issues/issue-57741-1.stderr b/src/test/ui/issues/issue-57741-1.stderr
new file mode 100644
index 0000000..d36424b
--- /dev/null
+++ b/src/test/ui/issues/issue-57741-1.stderr
@@ -0,0 +1,25 @@
+error[E0308]: mismatched types
+ --> $DIR/issue-57741-1.rs:14:9
+ |
+LL | let y = match x {
+ | - this match expression has type `std::boxed::Box<u32>`
+LL | S::A { a } | S::B { b: a } => a,
+ | ^^^^^^^^^^ expected struct `std::boxed::Box`, found enum `S`
+ |
+ = note: expected type `std::boxed::Box<u32>`
+ found type `S`
+
+error[E0308]: mismatched types
+ --> $DIR/issue-57741-1.rs:14:22
+ |
+LL | let y = match x {
+ | - this match expression has type `std::boxed::Box<u32>`
+LL | S::A { a } | S::B { b: a } => a,
+ | ^^^^^^^^^^^^^ expected struct `std::boxed::Box`, found enum `S`
+ |
+ = note: expected type `std::boxed::Box<u32>`
+ found type `S`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/issues/issue-57741.fixed b/src/test/ui/issues/issue-57741.fixed
new file mode 100644
index 0000000..4cae080
--- /dev/null
+++ b/src/test/ui/issues/issue-57741.fixed
@@ -0,0 +1,31 @@
+// run-rustfix
+
+#![allow(warnings)]
+
+// This tests that the `help: consider dereferencing the boxed value` suggestion is made and works.
+
+enum S {
+ A { a: usize },
+ B { b: usize },
+}
+
+enum T {
+ A(usize),
+ B(usize),
+}
+
+fn main() {
+ let x = Box::new(T::A(3));
+ let y = match *x {
+ T::A(a) | T::B(a) => a,
+ //~^ ERROR mismatched types [E0308]
+ //~^^ ERROR mismatched types [E0308]
+ };
+
+ let x = Box::new(S::A { a: 3 });
+ let y = match *x {
+ S::A { a } | S::B { b: a } => a,
+ //~^ ERROR mismatched types [E0308]
+ //~^^ ERROR mismatched types [E0308]
+ };
+}
diff --git a/src/test/ui/issues/issue-57741.rs b/src/test/ui/issues/issue-57741.rs
new file mode 100644
index 0000000..e265829
--- /dev/null
+++ b/src/test/ui/issues/issue-57741.rs
@@ -0,0 +1,31 @@
+// run-rustfix
+
+#![allow(warnings)]
+
+// This tests that the `help: consider dereferencing the boxed value` suggestion is made and works.
+
+enum S {
+ A { a: usize },
+ B { b: usize },
+}
+
+enum T {
+ A(usize),
+ B(usize),
+}
+
+fn main() {
+ let x = Box::new(T::A(3));
+ let y = match x {
+ T::A(a) | T::B(a) => a,
+ //~^ ERROR mismatched types [E0308]
+ //~^^ ERROR mismatched types [E0308]
+ };
+
+ let x = Box::new(S::A { a: 3 });
+ let y = match x {
+ S::A { a } | S::B { b: a } => a,
+ //~^ ERROR mismatched types [E0308]
+ //~^^ ERROR mismatched types [E0308]
+ };
+}
diff --git a/src/test/ui/issues/issue-57741.stderr b/src/test/ui/issues/issue-57741.stderr
new file mode 100644
index 0000000..a26b1d20
--- /dev/null
+++ b/src/test/ui/issues/issue-57741.stderr
@@ -0,0 +1,59 @@
+error[E0308]: mismatched types
+ --> $DIR/issue-57741.rs:20:9
+ |
+LL | let y = match x {
+ | -
+ | |
+ | this match expression has type `std::boxed::Box<T>`
+ | help: consider dereferencing the boxed value: `*x`
+LL | T::A(a) | T::B(a) => a,
+ | ^^^^^^^ expected struct `std::boxed::Box`, found enum `T`
+ |
+ = note: expected type `std::boxed::Box<T>`
+ found type `T`
+
+error[E0308]: mismatched types
+ --> $DIR/issue-57741.rs:20:19
+ |
+LL | let y = match x {
+ | -
+ | |
+ | this match expression has type `std::boxed::Box<T>`
+ | help: consider dereferencing the boxed value: `*x`
+LL | T::A(a) | T::B(a) => a,
+ | ^^^^^^^ expected struct `std::boxed::Box`, found enum `T`
+ |
+ = note: expected type `std::boxed::Box<T>`
+ found type `T`
+
+error[E0308]: mismatched types
+ --> $DIR/issue-57741.rs:27:9
+ |
+LL | let y = match x {
+ | -
+ | |
+ | this match expression has type `std::boxed::Box<S>`
+ | help: consider dereferencing the boxed value: `*x`
+LL | S::A { a } | S::B { b: a } => a,
+ | ^^^^^^^^^^ expected struct `std::boxed::Box`, found enum `S`
+ |
+ = note: expected type `std::boxed::Box<S>`
+ found type `S`
+
+error[E0308]: mismatched types
+ --> $DIR/issue-57741.rs:27:22
+ |
+LL | let y = match x {
+ | -
+ | |
+ | this match expression has type `std::boxed::Box<S>`
+ | help: consider dereferencing the boxed value: `*x`
+LL | S::A { a } | S::B { b: a } => a,
+ | ^^^^^^^^^^^^^ expected struct `std::boxed::Box`, found enum `S`
+ |
+ = note: expected type `std::boxed::Box<S>`
+ found type `S`
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/parser/doc-before-eof.stderr b/src/test/ui/parser/doc-before-eof.stderr
index b764e9f..5809d64 100644
--- a/src/test/ui/parser/doc-before-eof.stderr
+++ b/src/test/ui/parser/doc-before-eof.stderr
@@ -2,7 +2,7 @@
--> $DIR/doc-before-eof.rs:3:1
|
LL | /// hi //~ERROR expected item after doc comment
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this doc comment doesn't document anything
error: aborting due to previous error
diff --git a/src/test/ui/parser/doc-before-extern-rbrace.stderr b/src/test/ui/parser/doc-before-extern-rbrace.stderr
index 47fab7b..8cc9c91 100644
--- a/src/test/ui/parser/doc-before-extern-rbrace.stderr
+++ b/src/test/ui/parser/doc-before-extern-rbrace.stderr
@@ -2,7 +2,7 @@
--> $DIR/doc-before-extern-rbrace.rs:2:5
|
LL | /// hi
- | ^^^^^^
+ | ^^^^^^ this doc comment doesn't document anything
error: aborting due to previous error
diff --git a/src/test/ui/parser/doc-before-mod-rbrace.stderr b/src/test/ui/parser/doc-before-mod-rbrace.stderr
index 41c1d70..4eaf351 100644
--- a/src/test/ui/parser/doc-before-mod-rbrace.stderr
+++ b/src/test/ui/parser/doc-before-mod-rbrace.stderr
@@ -2,7 +2,7 @@
--> $DIR/doc-before-mod-rbrace.rs:4:5
|
LL | /// document
- | ^^^^^^^^^^^^
+ | ^^^^^^^^^^^^ this doc comment doesn't document anything
error: aborting due to previous error
diff --git a/src/test/ui/parser/type-parameters-in-field-exprs.stderr b/src/test/ui/parser/type-parameters-in-field-exprs.stderr
index e68e1f3..2183c74 100644
--- a/src/test/ui/parser/type-parameters-in-field-exprs.stderr
+++ b/src/test/ui/parser/type-parameters-in-field-exprs.stderr
@@ -1,20 +1,20 @@
error: field expressions may not have generic arguments
- --> $DIR/type-parameters-in-field-exprs.rs:13:8
+ --> $DIR/type-parameters-in-field-exprs.rs:13:10
|
LL | f.x::<isize>;
- | ^^^^^^^^^
+ | ^^^^^^^
error: field expressions may not have generic arguments
- --> $DIR/type-parameters-in-field-exprs.rs:15:8
+ --> $DIR/type-parameters-in-field-exprs.rs:15:10
|
LL | f.x::<>;
- | ^^^^
+ | ^^
error: field expressions may not have generic arguments
- --> $DIR/type-parameters-in-field-exprs.rs:17:8
+ --> $DIR/type-parameters-in-field-exprs.rs:17:10
|
LL | f.x::();
- | ^^^^
+ | ^^
error: aborting due to 3 previous errors
diff --git a/src/test/ui/span/macro-ty-params.stderr b/src/test/ui/span/macro-ty-params.stderr
index 23fdde0..965ca70 100644
--- a/src/test/ui/span/macro-ty-params.stderr
+++ b/src/test/ui/span/macro-ty-params.stderr
@@ -1,14 +1,14 @@
error: generic arguments in macro path
- --> $DIR/macro-ty-params.rs:10:8
+ --> $DIR/macro-ty-params.rs:10:10
|
LL | foo::<T>!(); //~ ERROR generic arguments in macro path
- | ^^^^^
+ | ^^^
error: generic arguments in macro path
- --> $DIR/macro-ty-params.rs:11:8
+ --> $DIR/macro-ty-params.rs:11:10
|
LL | foo::<>!(); //~ ERROR generic arguments in macro path
- | ^^^^
+ | ^^
error: unexpected generic arguments in path
--> $DIR/macro-ty-params.rs:12:8
diff --git a/src/test/ui/suggestions/type-mismatch-struct-field-shorthand-2.rs b/src/test/ui/suggestions/type-mismatch-struct-field-shorthand-2.rs
new file mode 100644
index 0000000..2ce1222
--- /dev/null
+++ b/src/test/ui/suggestions/type-mismatch-struct-field-shorthand-2.rs
@@ -0,0 +1,9 @@
+struct RGB { r: f64, g: f64, b: f64 }
+
+fn main() {
+ let (r, g, c): (f32, f32, f32) = (0., 0., 0.);
+ let _ = RGB { r, g, c };
+ //~^ ERROR mismatched types
+ //~| ERROR mismatched types
+ //~| ERROR struct `RGB` has no field named `c`
+}
diff --git a/src/test/ui/suggestions/type-mismatch-struct-field-shorthand-2.stderr b/src/test/ui/suggestions/type-mismatch-struct-field-shorthand-2.stderr
new file mode 100644
index 0000000..d0f9e1f
--- /dev/null
+++ b/src/test/ui/suggestions/type-mismatch-struct-field-shorthand-2.stderr
@@ -0,0 +1,30 @@
+error[E0308]: mismatched types
+ --> $DIR/type-mismatch-struct-field-shorthand-2.rs:5:19
+ |
+LL | let _ = RGB { r, g, c };
+ | ^ expected f64, found f32
+help: you can cast an `f32` to `f64` in a lossless way
+ |
+LL | let _ = RGB { r: r.into(), g, c };
+ | ^^^^^^^^^^^
+
+error[E0308]: mismatched types
+ --> $DIR/type-mismatch-struct-field-shorthand-2.rs:5:22
+ |
+LL | let _ = RGB { r, g, c };
+ | ^ expected f64, found f32
+help: you can cast an `f32` to `f64` in a lossless way
+ |
+LL | let _ = RGB { r, g: g.into(), c };
+ | ^^^^^^^^^^^
+
+error[E0560]: struct `RGB` has no field named `c`
+ --> $DIR/type-mismatch-struct-field-shorthand-2.rs:5:25
+ |
+LL | let _ = RGB { r, g, c };
+ | ^ help: a field with a similar name exists: `b`
+
+error: aborting due to 3 previous errors
+
+Some errors occurred: E0308, E0560.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/suggestions/type-mismatch-struct-field-shorthand.fixed b/src/test/ui/suggestions/type-mismatch-struct-field-shorthand.fixed
new file mode 100644
index 0000000..91758c0
--- /dev/null
+++ b/src/test/ui/suggestions/type-mismatch-struct-field-shorthand.fixed
@@ -0,0 +1,12 @@
+// run-rustfix
+#![allow(dead_code)]
+
+struct RGB { r: f64, g: f64, b: f64 }
+
+fn main() {
+ let (r, g, b): (f32, f32, f32) = (0., 0., 0.);
+ let _ = RGB { r: r.into(), g: g.into(), b: b.into() };
+ //~^ ERROR mismatched types
+ //~| ERROR mismatched types
+ //~| ERROR mismatched types
+}
diff --git a/src/test/ui/suggestions/type-mismatch-struct-field-shorthand.rs b/src/test/ui/suggestions/type-mismatch-struct-field-shorthand.rs
new file mode 100644
index 0000000..9d3a17a
--- /dev/null
+++ b/src/test/ui/suggestions/type-mismatch-struct-field-shorthand.rs
@@ -0,0 +1,12 @@
+// run-rustfix
+#![allow(dead_code)]
+
+struct RGB { r: f64, g: f64, b: f64 }
+
+fn main() {
+ let (r, g, b): (f32, f32, f32) = (0., 0., 0.);
+ let _ = RGB { r, g, b };
+ //~^ ERROR mismatched types
+ //~| ERROR mismatched types
+ //~| ERROR mismatched types
+}
diff --git a/src/test/ui/suggestions/type-mismatch-struct-field-shorthand.stderr b/src/test/ui/suggestions/type-mismatch-struct-field-shorthand.stderr
new file mode 100644
index 0000000..6bc16ba
--- /dev/null
+++ b/src/test/ui/suggestions/type-mismatch-struct-field-shorthand.stderr
@@ -0,0 +1,33 @@
+error[E0308]: mismatched types
+ --> $DIR/type-mismatch-struct-field-shorthand.rs:8:19
+ |
+LL | let _ = RGB { r, g, b };
+ | ^ expected f64, found f32
+help: you can cast an `f32` to `f64` in a lossless way
+ |
+LL | let _ = RGB { r: r.into(), g, b };
+ | ^^^^^^^^^^^
+
+error[E0308]: mismatched types
+ --> $DIR/type-mismatch-struct-field-shorthand.rs:8:22
+ |
+LL | let _ = RGB { r, g, b };
+ | ^ expected f64, found f32
+help: you can cast an `f32` to `f64` in a lossless way
+ |
+LL | let _ = RGB { r, g: g.into(), b };
+ | ^^^^^^^^^^^
+
+error[E0308]: mismatched types
+ --> $DIR/type-mismatch-struct-field-shorthand.rs:8:25
+ |
+LL | let _ = RGB { r, g, b };
+ | ^ expected f64, found f32
+help: you can cast an `f32` to `f64` in a lossless way
+ |
+LL | let _ = RGB { r, g, b: b.into() };
+ | ^^^^^^^^^^^
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.rs b/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.rs
index 5387dcb..c96a6fa 100644
--- a/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.rs
+++ b/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.rs
@@ -6,7 +6,8 @@
fn bar() {
let x: Box<Bar()> = panic!();
- //~^ ERROR parenthesized parameters may only be used with a trait
+ //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait
+ //~| ERROR wrong number of type arguments: expected 1, found 0
}
fn main() { }
diff --git a/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.stderr b/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.stderr
index 3f1b37c..fa52e66 100644
--- a/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.stderr
+++ b/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.stderr
@@ -1,9 +1,16 @@
-error[E0214]: parenthesized parameters may only be used with a trait
+error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
--> $DIR/unboxed-closure-sugar-used-on-struct-1.rs:8:19
|
LL | let x: Box<Bar()> = panic!();
- | ^^ only traits may use parentheses
+ | ^^ only `Fn` traits may use parentheses
-error: aborting due to previous error
+error[E0107]: wrong number of type arguments: expected 1, found 0
+ --> $DIR/unboxed-closure-sugar-used-on-struct-1.rs:8:16
+ |
+LL | let x: Box<Bar()> = panic!();
+ | ^^^^^ expected 1 type argument
-For more information about this error, try `rustc --explain E0214`.
+error: aborting due to 2 previous errors
+
+Some errors occurred: E0107, E0214.
+For more information about an error, try `rustc --explain E0107`.
diff --git a/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-3.rs b/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-3.rs
index 3cada32..79ced1e 100644
--- a/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-3.rs
+++ b/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-3.rs
@@ -12,7 +12,7 @@
let b = Bar::<isize, usize>::new(); // OK
let b = Bar::(isize, usize)::new(); // OK too (for the parser)
- //~^ ERROR parenthesized parameters may only be used with a trait
+ //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait
}
fn main() {}
diff --git a/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-3.stderr b/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-3.stderr
index 395f659..7d05ca5 100644
--- a/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-3.stderr
+++ b/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-3.stderr
@@ -1,8 +1,11 @@
-error[E0214]: parenthesized parameters may only be used with a trait
- --> $DIR/unboxed-closure-sugar-used-on-struct-3.rs:14:16
+error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
+ --> $DIR/unboxed-closure-sugar-used-on-struct-3.rs:14:18
|
LL | let b = Bar::(isize, usize)::new(); // OK too (for the parser)
- | ^^^^^^^^^^^^^^^^ only traits may use parentheses
+ | ^^^^^^^^^^^^^^
+ | |
+ | only `Fn` traits may use parentheses
+ | help: use angle brackets instead: `<isize, usize>`
error: aborting due to previous error
diff --git a/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.rs b/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.rs
index e795650..1af7f55 100644
--- a/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.rs
+++ b/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.rs
@@ -5,8 +5,8 @@
}
fn foo(b: Box<Bar()>) {
- //~^ ERROR parenthesized parameters may only be used with a trait
- //~| ERROR the type placeholder `_` is not allowed within types on item signatures
+ //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait
+ //~| ERROR wrong number of type arguments: expected 1, found 0
}
fn main() { }
diff --git a/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.stderr b/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.stderr
index d026709..b342379 100644
--- a/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.stderr
+++ b/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.stderr
@@ -1,16 +1,16 @@
-error[E0214]: parenthesized parameters may only be used with a trait
+error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
--> $DIR/unboxed-closure-sugar-used-on-struct.rs:7:18
|
LL | fn foo(b: Box<Bar()>) {
- | ^^ only traits may use parentheses
+ | ^^ only `Fn` traits may use parentheses
-error[E0121]: the type placeholder `_` is not allowed within types on item signatures
+error[E0107]: wrong number of type arguments: expected 1, found 0
--> $DIR/unboxed-closure-sugar-used-on-struct.rs:7:15
|
LL | fn foo(b: Box<Bar()>) {
- | ^^^^^ not allowed in type signatures
+ | ^^^^^ expected 1 type argument
error: aborting due to 2 previous errors
-Some errors occurred: E0121, E0214.
-For more information about an error, try `rustc --explain E0121`.
+Some errors occurred: E0107, E0214.
+For more information about an error, try `rustc --explain E0107`.
diff --git a/src/tools/clippy b/src/tools/clippy
index 1b89724..1838bfe 160000
--- a/src/tools/clippy
+++ b/src/tools/clippy
@@ -1 +1 @@
-Subproject commit 1b89724b4889aef631b40d52c0943bdc28e04d1d
+Subproject commit 1838bfe5a9ff951ffd716e4632156113d95d14a4