Auto merge of #91104 - matthiaskrgr:rollup-duk33o1, r=matthiaskrgr
Rollup of 4 pull requests Successful merges: - #91008 (Adds IEEE 754-2019 minimun and maximum functions for f32/f64) - #91070 (Make `LLVMRustGetOrInsertGlobal` always return a `GlobalVariable`) - #91097 (Add spaces in opaque `impl Trait` with more than one trait) - #91098 (Don't suggest certain fixups (`.field`, `.await`, etc) when reporting errors while matching on arrays ) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
3bfde2f1f4
@ -1695,11 +1695,23 @@ enum Mismatch<'a> {
|
|||||||
}
|
}
|
||||||
_ => exp_found,
|
_ => exp_found,
|
||||||
};
|
};
|
||||||
debug!("exp_found {:?} terr {:?}", exp_found, terr);
|
debug!("exp_found {:?} terr {:?} cause.code {:?}", exp_found, terr, cause.code);
|
||||||
if let Some(exp_found) = exp_found {
|
if let Some(exp_found) = exp_found {
|
||||||
self.suggest_as_ref_where_appropriate(span, &exp_found, diag);
|
let should_suggest_fixes = if let ObligationCauseCode::Pattern { root_ty, .. } =
|
||||||
self.suggest_accessing_field_where_appropriate(cause, &exp_found, diag);
|
&cause.code
|
||||||
self.suggest_await_on_expect_found(cause, span, &exp_found, diag);
|
{
|
||||||
|
// Skip if the root_ty of the pattern is not the same as the expected_ty.
|
||||||
|
// If these types aren't equal then we've probably peeled off a layer of arrays.
|
||||||
|
same_type_modulo_infer(self.resolve_vars_if_possible(*root_ty), exp_found.expected)
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
};
|
||||||
|
|
||||||
|
if should_suggest_fixes {
|
||||||
|
self.suggest_as_ref_where_appropriate(span, &exp_found, diag);
|
||||||
|
self.suggest_accessing_field_where_appropriate(cause, &exp_found, diag);
|
||||||
|
self.suggest_await_on_expect_found(cause, span, &exp_found, diag);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// In some (most?) cases cause.body_id points to actual body, but in some cases
|
// In some (most?) cases cause.body_id points to actual body, but in some cases
|
||||||
@ -1879,7 +1891,7 @@ fn suggest_accessing_field_where_appropriate(
|
|||||||
.iter()
|
.iter()
|
||||||
.filter(|field| field.vis.is_accessible_from(field.did, self.tcx))
|
.filter(|field| field.vis.is_accessible_from(field.did, self.tcx))
|
||||||
.map(|field| (field.ident.name, field.ty(self.tcx, expected_substs)))
|
.map(|field| (field.ident.name, field.ty(self.tcx, expected_substs)))
|
||||||
.find(|(_, ty)| ty::TyS::same_type(ty, exp_found.found))
|
.find(|(_, ty)| same_type_modulo_infer(ty, exp_found.found))
|
||||||
{
|
{
|
||||||
if let ObligationCauseCode::Pattern { span: Some(span), .. } = cause.code {
|
if let ObligationCauseCode::Pattern { span: Some(span), .. } = cause.code {
|
||||||
if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) {
|
if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) {
|
||||||
@ -1944,7 +1956,7 @@ fn suggest_as_ref_where_appropriate(
|
|||||||
| (_, ty::Infer(_))
|
| (_, ty::Infer(_))
|
||||||
| (ty::Param(_), _)
|
| (ty::Param(_), _)
|
||||||
| (ty::Infer(_), _) => {}
|
| (ty::Infer(_), _) => {}
|
||||||
_ if ty::TyS::same_type(exp_ty, found_ty) => {}
|
_ if same_type_modulo_infer(exp_ty, found_ty) => {}
|
||||||
_ => show_suggestion = false,
|
_ => show_suggestion = false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -124,8 +124,18 @@ extern "C" LLVMValueRef LLVMRustGetOrInsertFunction(LLVMModuleRef M,
|
|||||||
|
|
||||||
extern "C" LLVMValueRef
|
extern "C" LLVMValueRef
|
||||||
LLVMRustGetOrInsertGlobal(LLVMModuleRef M, const char *Name, size_t NameLen, LLVMTypeRef Ty) {
|
LLVMRustGetOrInsertGlobal(LLVMModuleRef M, const char *Name, size_t NameLen, LLVMTypeRef Ty) {
|
||||||
|
Module *Mod = unwrap(M);
|
||||||
StringRef NameRef(Name, NameLen);
|
StringRef NameRef(Name, NameLen);
|
||||||
return wrap(unwrap(M)->getOrInsertGlobal(NameRef, unwrap(Ty)));
|
|
||||||
|
// We don't use Module::getOrInsertGlobal because that returns a Constant*,
|
||||||
|
// which may either be the real GlobalVariable*, or a constant bitcast of it
|
||||||
|
// if our type doesn't match the original declaration. We always want the
|
||||||
|
// GlobalVariable* so we can access linkage, visibility, etc.
|
||||||
|
GlobalVariable *GV = Mod->getGlobalVariable(NameRef, true);
|
||||||
|
if (!GV)
|
||||||
|
GV = new GlobalVariable(*Mod, unwrap(Ty), false,
|
||||||
|
GlobalValue::ExternalLinkage, nullptr, NameRef);
|
||||||
|
return wrap(GV);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" LLVMValueRef
|
extern "C" LLVMValueRef
|
||||||
|
@ -688,7 +688,7 @@ fn pretty_print_type(mut self, ty: Ty<'tcx>) -> Result<Self::Type, Self::Error>
|
|||||||
}
|
}
|
||||||
|
|
||||||
p!(
|
p!(
|
||||||
write("{}", if first { " " } else { "+" }),
|
write("{}", if first { " " } else { " + " }),
|
||||||
print(trait_ref.print_only_trait_path())
|
print(trait_ref.print_only_trait_path())
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -699,7 +699,7 @@ fn pretty_print_type(mut self, ty: Ty<'tcx>) -> Result<Self::Type, Self::Error>
|
|||||||
}
|
}
|
||||||
|
|
||||||
if is_future {
|
if is_future {
|
||||||
p!(write("{}Future", if first { " " } else { "+" }));
|
p!(write("{}Future", if first { " " } else { " + " }));
|
||||||
first = false;
|
first = false;
|
||||||
|
|
||||||
if let Some(future_output_ty) = future_output_ty {
|
if let Some(future_output_ty) = future_output_ty {
|
||||||
@ -712,7 +712,7 @@ fn pretty_print_type(mut self, ty: Ty<'tcx>) -> Result<Self::Type, Self::Error>
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !is_sized {
|
if !is_sized {
|
||||||
p!(write("{}?Sized", if first { " " } else { "+" }));
|
p!(write("{}?Sized", if first { " " } else { " + " }));
|
||||||
} else if first {
|
} else if first {
|
||||||
p!(" Sized");
|
p!(" Sized");
|
||||||
}
|
}
|
||||||
|
@ -673,6 +673,9 @@ pub fn to_radians(self) -> f32 {
|
|||||||
|
|
||||||
/// Returns the maximum of the two numbers.
|
/// Returns the maximum of the two numbers.
|
||||||
///
|
///
|
||||||
|
/// Follows the IEEE-754 2008 semantics for maxNum, except for handling of signaling NaNs.
|
||||||
|
/// This matches the behavior of libm’s fmin.
|
||||||
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// let x = 1.0f32;
|
/// let x = 1.0f32;
|
||||||
/// let y = 2.0f32;
|
/// let y = 2.0f32;
|
||||||
@ -689,6 +692,9 @@ pub fn max(self, other: f32) -> f32 {
|
|||||||
|
|
||||||
/// Returns the minimum of the two numbers.
|
/// Returns the minimum of the two numbers.
|
||||||
///
|
///
|
||||||
|
/// Follows the IEEE-754 2008 semantics for minNum, except for handling of signaling NaNs.
|
||||||
|
/// This matches the behavior of libm’s fmin.
|
||||||
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// let x = 1.0f32;
|
/// let x = 1.0f32;
|
||||||
/// let y = 2.0f32;
|
/// let y = 2.0f32;
|
||||||
@ -703,6 +709,68 @@ pub fn min(self, other: f32) -> f32 {
|
|||||||
intrinsics::minnumf32(self, other)
|
intrinsics::minnumf32(self, other)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the maximum of the two numbers, propagating NaNs.
|
||||||
|
///
|
||||||
|
/// This returns NaN when *either* argument is NaN, as opposed to
|
||||||
|
/// [`f32::max`] which only returns NaN when *both* arguments are NaN.
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// #![feature(float_minimum_maximum)]
|
||||||
|
/// let x = 1.0f32;
|
||||||
|
/// let y = 2.0f32;
|
||||||
|
///
|
||||||
|
/// assert_eq!(x.maximum(y), y);
|
||||||
|
/// assert!(x.maximum(f32::NAN).is_nan());
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// If one of the arguments is NaN, then NaN is returned. Otherwise this returns the greater
|
||||||
|
/// of the two numbers. For this operation, -0.0 is considered to be less than +0.0.
|
||||||
|
/// Note that this follows the semantics specified in IEEE 754-2019.
|
||||||
|
#[unstable(feature = "float_minimum_maximum", issue = "91079")]
|
||||||
|
#[inline]
|
||||||
|
pub fn maximum(self, other: f32) -> f32 {
|
||||||
|
if self > other {
|
||||||
|
self
|
||||||
|
} else if other > self {
|
||||||
|
other
|
||||||
|
} else if self == other {
|
||||||
|
if self.is_sign_positive() && other.is_sign_negative() { self } else { other }
|
||||||
|
} else {
|
||||||
|
self + other
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the minimum of the two numbers, propagating NaNs.
|
||||||
|
///
|
||||||
|
/// This returns NaN when *either* argument is NaN, as opposed to
|
||||||
|
/// [`f32::min`] which only returns NaN when *both* arguments are NaN.
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// #![feature(float_minimum_maximum)]
|
||||||
|
/// let x = 1.0f32;
|
||||||
|
/// let y = 2.0f32;
|
||||||
|
///
|
||||||
|
/// assert_eq!(x.minimum(y), x);
|
||||||
|
/// assert!(x.minimum(f32::NAN).is_nan());
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// If one of the arguments is NaN, then NaN is returned. Otherwise this returns the lesser
|
||||||
|
/// of the two numbers. For this operation, -0.0 is considered to be less than +0.0.
|
||||||
|
/// Note that this follows the semantics specified in IEEE 754-2019.
|
||||||
|
#[unstable(feature = "float_minimum_maximum", issue = "91079")]
|
||||||
|
#[inline]
|
||||||
|
pub fn minimum(self, other: f32) -> f32 {
|
||||||
|
if self < other {
|
||||||
|
self
|
||||||
|
} else if other < self {
|
||||||
|
other
|
||||||
|
} else if self == other {
|
||||||
|
if self.is_sign_negative() && other.is_sign_positive() { self } else { other }
|
||||||
|
} else {
|
||||||
|
self + other
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Rounds toward zero and converts to any primitive integer type,
|
/// Rounds toward zero and converts to any primitive integer type,
|
||||||
/// assuming that the value is finite and fits in that type.
|
/// assuming that the value is finite and fits in that type.
|
||||||
///
|
///
|
||||||
|
@ -689,6 +689,9 @@ pub fn to_radians(self) -> f64 {
|
|||||||
|
|
||||||
/// Returns the maximum of the two numbers.
|
/// Returns the maximum of the two numbers.
|
||||||
///
|
///
|
||||||
|
/// Follows the IEEE-754 2008 semantics for maxNum, except for handling of signaling NaNs.
|
||||||
|
/// This matches the behavior of libm’s fmin.
|
||||||
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// let x = 1.0_f64;
|
/// let x = 1.0_f64;
|
||||||
/// let y = 2.0_f64;
|
/// let y = 2.0_f64;
|
||||||
@ -705,6 +708,9 @@ pub fn max(self, other: f64) -> f64 {
|
|||||||
|
|
||||||
/// Returns the minimum of the two numbers.
|
/// Returns the minimum of the two numbers.
|
||||||
///
|
///
|
||||||
|
/// Follows the IEEE-754 2008 semantics for minNum, except for handling of signaling NaNs.
|
||||||
|
/// This matches the behavior of libm’s fmin.
|
||||||
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// let x = 1.0_f64;
|
/// let x = 1.0_f64;
|
||||||
/// let y = 2.0_f64;
|
/// let y = 2.0_f64;
|
||||||
@ -719,6 +725,68 @@ pub fn min(self, other: f64) -> f64 {
|
|||||||
intrinsics::minnumf64(self, other)
|
intrinsics::minnumf64(self, other)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the maximum of the two numbers, propagating NaNs.
|
||||||
|
///
|
||||||
|
/// This returns NaN when *either* argument is NaN, as opposed to
|
||||||
|
/// [`f64::max`] which only returns NaN when *both* arguments are NaN.
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// #![feature(float_minimum_maximum)]
|
||||||
|
/// let x = 1.0_f64;
|
||||||
|
/// let y = 2.0_f64;
|
||||||
|
///
|
||||||
|
/// assert_eq!(x.maximum(y), y);
|
||||||
|
/// assert!(x.maximum(f64::NAN).is_nan());
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// If one of the arguments is NaN, then NaN is returned. Otherwise this returns the greater
|
||||||
|
/// of the two numbers. For this operation, -0.0 is considered to be less than +0.0.
|
||||||
|
/// Note that this follows the semantics specified in IEEE 754-2019.
|
||||||
|
#[unstable(feature = "float_minimum_maximum", issue = "91079")]
|
||||||
|
#[inline]
|
||||||
|
pub fn maximum(self, other: f64) -> f64 {
|
||||||
|
if self > other {
|
||||||
|
self
|
||||||
|
} else if other > self {
|
||||||
|
other
|
||||||
|
} else if self == other {
|
||||||
|
if self.is_sign_positive() && other.is_sign_negative() { self } else { other }
|
||||||
|
} else {
|
||||||
|
self + other
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the minimum of the two numbers, propagating NaNs.
|
||||||
|
///
|
||||||
|
/// This returns NaN when *either* argument is NaN, as opposed to
|
||||||
|
/// [`f64::min`] which only returns NaN when *both* arguments are NaN.
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// #![feature(float_minimum_maximum)]
|
||||||
|
/// let x = 1.0_f64;
|
||||||
|
/// let y = 2.0_f64;
|
||||||
|
///
|
||||||
|
/// assert_eq!(x.minimum(y), x);
|
||||||
|
/// assert!(x.minimum(f64::NAN).is_nan());
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// If one of the arguments is NaN, then NaN is returned. Otherwise this returns the lesser
|
||||||
|
/// of the two numbers. For this operation, -0.0 is considered to be less than +0.0.
|
||||||
|
/// Note that this follows the semantics specified in IEEE 754-2019.
|
||||||
|
#[unstable(feature = "float_minimum_maximum", issue = "91079")]
|
||||||
|
#[inline]
|
||||||
|
pub fn minimum(self, other: f64) -> f64 {
|
||||||
|
if self < other {
|
||||||
|
self
|
||||||
|
} else if other < self {
|
||||||
|
other
|
||||||
|
} else if self == other {
|
||||||
|
if self.is_sign_negative() && other.is_sign_positive() { self } else { other }
|
||||||
|
} else {
|
||||||
|
self + other
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Rounds toward zero and converts to any primitive integer type,
|
/// Rounds toward zero and converts to any primitive integer type,
|
||||||
/// assuming that the value is finite and fits in that type.
|
/// assuming that the value is finite and fits in that type.
|
||||||
///
|
///
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#![feature(extern_types)]
|
#![feature(extern_types)]
|
||||||
#![feature(flt2dec)]
|
#![feature(flt2dec)]
|
||||||
#![feature(fmt_internals)]
|
#![feature(fmt_internals)]
|
||||||
|
#![feature(float_minimum_maximum)]
|
||||||
#![feature(array_from_fn)]
|
#![feature(array_from_fn)]
|
||||||
#![feature(hashmap_internals)]
|
#![feature(hashmap_internals)]
|
||||||
#![feature(try_find)]
|
#![feature(try_find)]
|
||||||
|
@ -715,6 +715,67 @@ fn max() {
|
|||||||
assert!(($nan as $fty).max($nan).is_nan());
|
assert!(($nan as $fty).max($nan).is_nan());
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
|
fn minimum() {
|
||||||
|
assert_eq!((0.0 as $fty).minimum(0.0), 0.0);
|
||||||
|
assert!((0.0 as $fty).minimum(0.0).is_sign_positive());
|
||||||
|
assert_eq!((-0.0 as $fty).minimum(0.0), -0.0);
|
||||||
|
assert!((-0.0 as $fty).minimum(0.0).is_sign_negative());
|
||||||
|
assert_eq!((-0.0 as $fty).minimum(-0.0), -0.0);
|
||||||
|
assert!((-0.0 as $fty).minimum(-0.0).is_sign_negative());
|
||||||
|
assert_eq!((9.0 as $fty).minimum(9.0), 9.0);
|
||||||
|
assert_eq!((-9.0 as $fty).minimum(0.0), -9.0);
|
||||||
|
assert_eq!((0.0 as $fty).minimum(9.0), 0.0);
|
||||||
|
assert!((0.0 as $fty).minimum(9.0).is_sign_positive());
|
||||||
|
assert_eq!((-0.0 as $fty).minimum(9.0), -0.0);
|
||||||
|
assert!((-0.0 as $fty).minimum(9.0).is_sign_negative());
|
||||||
|
assert_eq!((-0.0 as $fty).minimum(-9.0), -9.0);
|
||||||
|
assert_eq!(($inf as $fty).minimum(9.0), 9.0);
|
||||||
|
assert_eq!((9.0 as $fty).minimum($inf), 9.0);
|
||||||
|
assert_eq!(($inf as $fty).minimum(-9.0), -9.0);
|
||||||
|
assert_eq!((-9.0 as $fty).minimum($inf), -9.0);
|
||||||
|
assert_eq!(($neginf as $fty).minimum(9.0), $neginf);
|
||||||
|
assert_eq!((9.0 as $fty).minimum($neginf), $neginf);
|
||||||
|
assert_eq!(($neginf as $fty).minimum(-9.0), $neginf);
|
||||||
|
assert_eq!((-9.0 as $fty).minimum($neginf), $neginf);
|
||||||
|
assert!(($nan as $fty).minimum(9.0).is_nan());
|
||||||
|
assert!(($nan as $fty).minimum(-9.0).is_nan());
|
||||||
|
assert!((9.0 as $fty).minimum($nan).is_nan());
|
||||||
|
assert!((-9.0 as $fty).minimum($nan).is_nan());
|
||||||
|
assert!(($nan as $fty).minimum($nan).is_nan());
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn maximum() {
|
||||||
|
assert_eq!((0.0 as $fty).maximum(0.0), 0.0);
|
||||||
|
assert!((0.0 as $fty).maximum(0.0).is_sign_positive());
|
||||||
|
assert_eq!((-0.0 as $fty).maximum(0.0), 0.0);
|
||||||
|
assert!((-0.0 as $fty).maximum(0.0).is_sign_positive());
|
||||||
|
assert_eq!((-0.0 as $fty).maximum(-0.0), -0.0);
|
||||||
|
assert!((-0.0 as $fty).maximum(-0.0).is_sign_negative());
|
||||||
|
assert_eq!((9.0 as $fty).maximum(9.0), 9.0);
|
||||||
|
assert_eq!((-9.0 as $fty).maximum(0.0), 0.0);
|
||||||
|
assert!((-9.0 as $fty).maximum(0.0).is_sign_positive());
|
||||||
|
assert_eq!((-9.0 as $fty).maximum(-0.0), -0.0);
|
||||||
|
assert!((-9.0 as $fty).maximum(-0.0).is_sign_negative());
|
||||||
|
assert_eq!((0.0 as $fty).maximum(9.0), 9.0);
|
||||||
|
assert_eq!((0.0 as $fty).maximum(-9.0), 0.0);
|
||||||
|
assert!((0.0 as $fty).maximum(-9.0).is_sign_positive());
|
||||||
|
assert_eq!((-0.0 as $fty).maximum(-9.0), -0.0);
|
||||||
|
assert!((-0.0 as $fty).maximum(-9.0).is_sign_negative());
|
||||||
|
assert_eq!(($inf as $fty).maximum(9.0), $inf);
|
||||||
|
assert_eq!((9.0 as $fty).maximum($inf), $inf);
|
||||||
|
assert_eq!(($inf as $fty).maximum(-9.0), $inf);
|
||||||
|
assert_eq!((-9.0 as $fty).maximum($inf), $inf);
|
||||||
|
assert_eq!(($neginf as $fty).maximum(9.0), 9.0);
|
||||||
|
assert_eq!((9.0 as $fty).maximum($neginf), 9.0);
|
||||||
|
assert_eq!(($neginf as $fty).maximum(-9.0), -9.0);
|
||||||
|
assert_eq!((-9.0 as $fty).maximum($neginf), -9.0);
|
||||||
|
assert!(($nan as $fty).maximum(9.0).is_nan());
|
||||||
|
assert!(($nan as $fty).maximum(-9.0).is_nan());
|
||||||
|
assert!((9.0 as $fty).maximum($nan).is_nan());
|
||||||
|
assert!((-9.0 as $fty).maximum($nan).is_nan());
|
||||||
|
assert!(($nan as $fty).maximum($nan).is_nan());
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
fn rem_euclid() {
|
fn rem_euclid() {
|
||||||
let a: $fty = 42.0;
|
let a: $fty = 42.0;
|
||||||
assert!($inf.rem_euclid(a).is_nan());
|
assert!($inf.rem_euclid(a).is_nan());
|
||||||
|
@ -19,6 +19,18 @@ fn test_max_nan() {
|
|||||||
assert_eq!(2.0f32.max(f32::NAN), 2.0);
|
assert_eq!(2.0f32.max(f32::NAN), 2.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_minimum() {
|
||||||
|
assert!(f32::NAN.minimum(2.0).is_nan());
|
||||||
|
assert!(2.0f32.minimum(f32::NAN).is_nan());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_maximum() {
|
||||||
|
assert!(f32::NAN.maximum(2.0).is_nan());
|
||||||
|
assert!(2.0f32.maximum(f32::NAN).is_nan());
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_nan() {
|
fn test_nan() {
|
||||||
let nan: f32 = f32::NAN;
|
let nan: f32 = f32::NAN;
|
||||||
|
@ -287,6 +287,7 @@
|
|||||||
#![feature(exhaustive_patterns)]
|
#![feature(exhaustive_patterns)]
|
||||||
#![feature(extend_one)]
|
#![feature(extend_one)]
|
||||||
#![feature(fn_traits)]
|
#![feature(fn_traits)]
|
||||||
|
#![feature(float_minimum_maximum)]
|
||||||
#![feature(format_args_nl)]
|
#![feature(format_args_nl)]
|
||||||
#![feature(gen_future)]
|
#![feature(gen_future)]
|
||||||
#![feature(generator_trait)]
|
#![feature(generator_trait)]
|
||||||
|
@ -83,17 +83,17 @@ fn main() {
|
|||||||
//~^ ERROR type mismatch resolving `<impl DerivedTrait as Trait>::Associated == ()`
|
//~^ ERROR type mismatch resolving `<impl DerivedTrait as Trait>::Associated == ()`
|
||||||
|
|
||||||
accepts_trait(returns_opaque_foo());
|
accepts_trait(returns_opaque_foo());
|
||||||
//~^ ERROR type mismatch resolving `<impl Trait+Foo as Trait>::Associated == ()`
|
//~^ ERROR type mismatch resolving `<impl Trait + Foo as Trait>::Associated == ()`
|
||||||
|
|
||||||
accepts_trait(returns_opaque_derived_foo());
|
accepts_trait(returns_opaque_derived_foo());
|
||||||
//~^ ERROR type mismatch resolving `<impl DerivedTrait+Foo as Trait>::Associated == ()`
|
//~^ ERROR type mismatch resolving `<impl DerivedTrait + Foo as Trait>::Associated == ()`
|
||||||
|
|
||||||
accepts_generic_trait(returns_opaque_generic());
|
accepts_generic_trait(returns_opaque_generic());
|
||||||
//~^ ERROR type mismatch resolving `<impl GenericTrait<()> as GenericTrait<()>>::Associated == ()`
|
//~^ ERROR type mismatch resolving `<impl GenericTrait<()> as GenericTrait<()>>::Associated == ()`
|
||||||
|
|
||||||
accepts_generic_trait(returns_opaque_generic_foo());
|
accepts_generic_trait(returns_opaque_generic_foo());
|
||||||
//~^ ERROR type mismatch resolving `<impl GenericTrait<()>+Foo as GenericTrait<()>>::Associated == ()`
|
//~^ ERROR type mismatch resolving `<impl GenericTrait<()> + Foo as GenericTrait<()>>::Associated == ()`
|
||||||
|
|
||||||
accepts_generic_trait(returns_opaque_generic_duplicate());
|
accepts_generic_trait(returns_opaque_generic_duplicate());
|
||||||
//~^ ERROR type mismatch resolving `<impl GenericTrait<()>+GenericTrait<u8> as GenericTrait<()>>::Associated == ()`
|
//~^ ERROR type mismatch resolving `<impl GenericTrait<()> + GenericTrait<u8> as GenericTrait<()>>::Associated == ()`
|
||||||
}
|
}
|
||||||
|
@ -160,7 +160,7 @@ help: consider constraining the associated type `<impl DerivedTrait as Trait>::A
|
|||||||
LL | fn returns_opaque_derived() -> impl DerivedTrait<Associated = ()> + 'static {
|
LL | fn returns_opaque_derived() -> impl DerivedTrait<Associated = ()> + 'static {
|
||||||
| +++++++++++++++++
|
| +++++++++++++++++
|
||||||
|
|
||||||
error[E0271]: type mismatch resolving `<impl Trait+Foo as Trait>::Associated == ()`
|
error[E0271]: type mismatch resolving `<impl Trait + Foo as Trait>::Associated == ()`
|
||||||
--> $DIR/issue-87261.rs:85:5
|
--> $DIR/issue-87261.rs:85:5
|
||||||
|
|
|
|
||||||
LL | fn returns_opaque_foo() -> impl Trait + Foo {
|
LL | fn returns_opaque_foo() -> impl Trait + Foo {
|
||||||
@ -170,18 +170,18 @@ LL | accepts_trait(returns_opaque_foo());
|
|||||||
| ^^^^^^^^^^^^^ expected `()`, found associated type
|
| ^^^^^^^^^^^^^ expected `()`, found associated type
|
||||||
|
|
|
|
||||||
= note: expected unit type `()`
|
= note: expected unit type `()`
|
||||||
found associated type `<impl Trait+Foo as Trait>::Associated`
|
found associated type `<impl Trait + Foo as Trait>::Associated`
|
||||||
note: required by a bound in `accepts_trait`
|
note: required by a bound in `accepts_trait`
|
||||||
--> $DIR/issue-87261.rs:43:27
|
--> $DIR/issue-87261.rs:43:27
|
||||||
|
|
|
|
||||||
LL | fn accepts_trait<T: Trait<Associated = ()>>(_: T) {}
|
LL | fn accepts_trait<T: Trait<Associated = ()>>(_: T) {}
|
||||||
| ^^^^^^^^^^^^^^^ required by this bound in `accepts_trait`
|
| ^^^^^^^^^^^^^^^ required by this bound in `accepts_trait`
|
||||||
help: consider constraining the associated type `<impl Trait+Foo as Trait>::Associated` to `()`
|
help: consider constraining the associated type `<impl Trait + Foo as Trait>::Associated` to `()`
|
||||||
|
|
|
|
||||||
LL | fn returns_opaque_foo() -> impl Trait<Associated = ()> + Foo {
|
LL | fn returns_opaque_foo() -> impl Trait<Associated = ()> + Foo {
|
||||||
| +++++++++++++++++
|
| +++++++++++++++++
|
||||||
|
|
||||||
error[E0271]: type mismatch resolving `<impl DerivedTrait+Foo as Trait>::Associated == ()`
|
error[E0271]: type mismatch resolving `<impl DerivedTrait + Foo as Trait>::Associated == ()`
|
||||||
--> $DIR/issue-87261.rs:88:5
|
--> $DIR/issue-87261.rs:88:5
|
||||||
|
|
|
|
||||||
LL | fn returns_opaque_derived_foo() -> impl DerivedTrait + Foo {
|
LL | fn returns_opaque_derived_foo() -> impl DerivedTrait + Foo {
|
||||||
@ -191,8 +191,8 @@ LL | accepts_trait(returns_opaque_derived_foo());
|
|||||||
| ^^^^^^^^^^^^^ expected `()`, found associated type
|
| ^^^^^^^^^^^^^ expected `()`, found associated type
|
||||||
|
|
|
|
||||||
= note: expected unit type `()`
|
= note: expected unit type `()`
|
||||||
found associated type `<impl DerivedTrait+Foo as Trait>::Associated`
|
found associated type `<impl DerivedTrait + Foo as Trait>::Associated`
|
||||||
= help: consider constraining the associated type `<impl DerivedTrait+Foo as Trait>::Associated` to `()`
|
= help: consider constraining the associated type `<impl DerivedTrait + Foo as Trait>::Associated` to `()`
|
||||||
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
|
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
|
||||||
note: required by a bound in `accepts_trait`
|
note: required by a bound in `accepts_trait`
|
||||||
--> $DIR/issue-87261.rs:43:27
|
--> $DIR/issue-87261.rs:43:27
|
||||||
@ -221,7 +221,7 @@ help: consider constraining the associated type `<impl GenericTrait<()> as Gener
|
|||||||
LL | fn returns_opaque_generic() -> impl GenericTrait<(), Associated = ()> + 'static {
|
LL | fn returns_opaque_generic() -> impl GenericTrait<(), Associated = ()> + 'static {
|
||||||
| +++++++++++++++++
|
| +++++++++++++++++
|
||||||
|
|
||||||
error[E0271]: type mismatch resolving `<impl GenericTrait<()>+Foo as GenericTrait<()>>::Associated == ()`
|
error[E0271]: type mismatch resolving `<impl GenericTrait<()> + Foo as GenericTrait<()>>::Associated == ()`
|
||||||
--> $DIR/issue-87261.rs:94:5
|
--> $DIR/issue-87261.rs:94:5
|
||||||
|
|
|
|
||||||
LL | fn returns_opaque_generic_foo() -> impl GenericTrait<()> + Foo {
|
LL | fn returns_opaque_generic_foo() -> impl GenericTrait<()> + Foo {
|
||||||
@ -231,18 +231,18 @@ LL | accepts_generic_trait(returns_opaque_generic_foo());
|
|||||||
| ^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type
|
| ^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type
|
||||||
|
|
|
|
||||||
= note: expected unit type `()`
|
= note: expected unit type `()`
|
||||||
found associated type `<impl GenericTrait<()>+Foo as GenericTrait<()>>::Associated`
|
found associated type `<impl GenericTrait<()> + Foo as GenericTrait<()>>::Associated`
|
||||||
note: required by a bound in `accepts_generic_trait`
|
note: required by a bound in `accepts_generic_trait`
|
||||||
--> $DIR/issue-87261.rs:44:46
|
--> $DIR/issue-87261.rs:44:46
|
||||||
|
|
|
|
||||||
LL | fn accepts_generic_trait<T: GenericTrait<(), Associated = ()>>(_: T) {}
|
LL | fn accepts_generic_trait<T: GenericTrait<(), Associated = ()>>(_: T) {}
|
||||||
| ^^^^^^^^^^^^^^^ required by this bound in `accepts_generic_trait`
|
| ^^^^^^^^^^^^^^^ required by this bound in `accepts_generic_trait`
|
||||||
help: consider constraining the associated type `<impl GenericTrait<()>+Foo as GenericTrait<()>>::Associated` to `()`
|
help: consider constraining the associated type `<impl GenericTrait<()> + Foo as GenericTrait<()>>::Associated` to `()`
|
||||||
|
|
|
|
||||||
LL | fn returns_opaque_generic_foo() -> impl GenericTrait<(), Associated = ()> + Foo {
|
LL | fn returns_opaque_generic_foo() -> impl GenericTrait<(), Associated = ()> + Foo {
|
||||||
| +++++++++++++++++
|
| +++++++++++++++++
|
||||||
|
|
||||||
error[E0271]: type mismatch resolving `<impl GenericTrait<()>+GenericTrait<u8> as GenericTrait<()>>::Associated == ()`
|
error[E0271]: type mismatch resolving `<impl GenericTrait<()> + GenericTrait<u8> as GenericTrait<()>>::Associated == ()`
|
||||||
--> $DIR/issue-87261.rs:97:5
|
--> $DIR/issue-87261.rs:97:5
|
||||||
|
|
|
|
||||||
LL | fn returns_opaque_generic_duplicate() -> impl GenericTrait<()> + GenericTrait<u8> {
|
LL | fn returns_opaque_generic_duplicate() -> impl GenericTrait<()> + GenericTrait<u8> {
|
||||||
@ -252,8 +252,8 @@ LL | accepts_generic_trait(returns_opaque_generic_duplicate());
|
|||||||
| ^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type
|
| ^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type
|
||||||
|
|
|
|
||||||
= note: expected unit type `()`
|
= note: expected unit type `()`
|
||||||
found associated type `<impl GenericTrait<()>+GenericTrait<u8> as GenericTrait<()>>::Associated`
|
found associated type `<impl GenericTrait<()> + GenericTrait<u8> as GenericTrait<()>>::Associated`
|
||||||
= help: consider constraining the associated type `<impl GenericTrait<()>+GenericTrait<u8> as GenericTrait<()>>::Associated` to `()`
|
= help: consider constraining the associated type `<impl GenericTrait<()> + GenericTrait<u8> as GenericTrait<()>>::Associated` to `()`
|
||||||
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
|
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
|
||||||
note: required by a bound in `accepts_generic_trait`
|
note: required by a bound in `accepts_generic_trait`
|
||||||
--> $DIR/issue-87261.rs:44:46
|
--> $DIR/issue-87261.rs:44:46
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
error[E0606]: casting `*mut impl Debug+?Sized` as `*mut impl Debug+?Sized` is invalid
|
error[E0606]: casting `*mut impl Debug + ?Sized` as `*mut impl Debug + ?Sized` is invalid
|
||||||
--> $DIR/casts-differing-anon.rs:21:13
|
--> $DIR/casts-differing-anon.rs:21:13
|
||||||
|
|
|
|
||||||
LL | b_raw = f_raw as *mut _;
|
LL | b_raw = f_raw as *mut _;
|
||||||
|
@ -8,6 +8,10 @@ LL | Either::Right(_) => {}
|
|||||||
|
|
|
|
||||||
= note: expected struct `S`
|
= note: expected struct `S`
|
||||||
found enum `Either<_, _>`
|
found enum `Either<_, _>`
|
||||||
|
help: you might have meant to use field `0` whose type is `Either<usize, usize>`
|
||||||
|
|
|
||||||
|
LL | match S(Either::Left(5)).0 {
|
||||||
|
| ~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
11
src/test/ui/match/issue-91058.rs
Normal file
11
src/test/ui/match/issue-91058.rs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
struct S(());
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let array = [S(())];
|
||||||
|
|
||||||
|
match array {
|
||||||
|
[()] => {}
|
||||||
|
//~^ ERROR mismatched types [E0308]
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
11
src/test/ui/match/issue-91058.stderr
Normal file
11
src/test/ui/match/issue-91058.stderr
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/issue-91058.rs:7:10
|
||||||
|
|
|
||||||
|
LL | match array {
|
||||||
|
| ----- this expression has type `[S; 1]`
|
||||||
|
LL | [()] => {}
|
||||||
|
| ^^ expected struct `S`, found `()`
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0308`.
|
34
src/test/ui/statics/issue-91050-1.rs
Normal file
34
src/test/ui/statics/issue-91050-1.rs
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
// build-pass
|
||||||
|
// compile-flags: --crate-type=rlib --emit=llvm-ir -Cno-prepopulate-passes
|
||||||
|
|
||||||
|
// This test declares globals by the same name with different types, which
|
||||||
|
// caused problems because Module::getOrInsertGlobal would return a Constant*
|
||||||
|
// bitcast instead of a GlobalVariable* that could access linkage/visibility.
|
||||||
|
// In alt builds with LLVM assertions this would fail:
|
||||||
|
//
|
||||||
|
// rustc: /checkout/src/llvm-project/llvm/include/llvm/Support/Casting.h:269:
|
||||||
|
// typename cast_retty<X, Y *>::ret_type llvm::cast(Y *) [X = llvm::GlobalValue, Y = llvm::Value]:
|
||||||
|
// Assertion `isa<X>(Val) && "cast<Ty>() argument of incompatible type!"' failed.
|
||||||
|
//
|
||||||
|
// In regular builds, the bad cast was UB, like "Invalid LLVMRustVisibility value!"
|
||||||
|
|
||||||
|
pub mod before {
|
||||||
|
#[no_mangle]
|
||||||
|
pub static GLOBAL1: [u8; 1] = [1];
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod inner {
|
||||||
|
extern "C" {
|
||||||
|
pub static GLOBAL1: u8;
|
||||||
|
pub static GLOBAL2: u8;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn call() {
|
||||||
|
drop(unsafe { (GLOBAL1, GLOBAL2) });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod after {
|
||||||
|
#[no_mangle]
|
||||||
|
pub static GLOBAL2: [u8; 1] = [2];
|
||||||
|
}
|
24
src/test/ui/statics/issue-91050-2.rs
Normal file
24
src/test/ui/statics/issue-91050-2.rs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
// build-pass
|
||||||
|
// compile-flags: --crate-type=rlib --emit=llvm-ir -Cno-prepopulate-passes
|
||||||
|
|
||||||
|
// This is a variant of issue-91050-1.rs -- see there for an explanation.
|
||||||
|
|
||||||
|
pub mod before {
|
||||||
|
extern "C" {
|
||||||
|
pub static GLOBAL1: [u8; 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn do_something_with_array() -> u8 {
|
||||||
|
GLOBAL1[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod inner {
|
||||||
|
extern "C" {
|
||||||
|
pub static GLOBAL1: u8;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn call() -> u8 {
|
||||||
|
GLOBAL1 + 42
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user