Skip to content

Commit 66a7a93

Browse files
committed
Auto merge of rust-lang#120623 - matthiaskrgr:rollup-qoyrz7o, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - rust-lang#116284 (make matching on NaN a hard error, and remove the rest of illegal_floating_point_literal_pattern) - rust-lang#120060 (Use the same mir-opt bless targets on all platforms) - rust-lang#120214 (match lowering: consistently lower bindings deepest-first) - rust-lang#120326 (Actually abort in -Zpanic-abort-tests) - rust-lang#120396 (Account for unbounded type param receiver in suggestions) - rust-lang#120435 (Suggest name value cfg when only value is used for check-cfg) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 4d87c4a + 6677374 commit 66a7a93

File tree

88 files changed

+1181
-1083
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

88 files changed

+1181
-1083
lines changed

Cargo.lock

+1
Original file line numberDiff line numberDiff line change
@@ -5321,6 +5321,7 @@ version = "0.0.0"
53215321
dependencies = [
53225322
"core",
53235323
"getopts",
5324+
"libc",
53245325
"panic_abort",
53255326
"panic_unwind",
53265327
"std",

compiler/rustc_hir_typeck/src/method/suggest.rs

+27-14
Original file line numberDiff line numberDiff line change
@@ -554,6 +554,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
554554
"`count` is defined on `{iterator_trait}`, which `{rcvr_ty}` does not implement"
555555
));
556556
}
557+
} else if !unsatisfied_predicates.is_empty() && matches!(rcvr_ty.kind(), ty::Param(_)) {
558+
// We special case the situation where we are looking for `_` in
559+
// `<TypeParam as _>::method` because otherwise the machinery will look for blanket
560+
// implementations that have unsatisfied trait bounds to suggest, leading us to claim
561+
// things like "we're looking for a trait with method `cmp`, both `Iterator` and `Ord`
562+
// have one, in order to implement `Ord` you need to restrict `TypeParam: FnPtr` so
563+
// that `impl<T: FnPtr> Ord for T` can apply", which is not what we want. We have a type
564+
// parameter, we want to directly say "`Ord::cmp` and `Iterator::cmp` exist, restrict
565+
// `TypeParam: Ord` or `TypeParam: Iterator`"". That is done further down when calling
566+
// `self.suggest_traits_to_import`, so we ignore the `unsatisfied_predicates`
567+
// suggestions.
557568
} else if !unsatisfied_predicates.is_empty() {
558569
let mut type_params = FxIndexMap::default();
559570

@@ -1325,7 +1336,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13251336
}
13261337
}
13271338
self.note_derefed_ty_has_method(&mut err, source, rcvr_ty, item_name, expected);
1328-
return Some(err);
1339+
Some(err)
13291340
}
13301341

13311342
fn note_candidates_on_method_error(
@@ -2918,19 +2929,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
29182929
// this isn't perfect (that is, there are cases when
29192930
// implementing a trait would be legal but is rejected
29202931
// here).
2921-
unsatisfied_predicates.iter().all(|(p, _, _)| {
2922-
match p.kind().skip_binder() {
2923-
// Hide traits if they are present in predicates as they can be fixed without
2924-
// having to implement them.
2925-
ty::PredicateKind::Clause(ty::ClauseKind::Trait(t)) => {
2926-
t.def_id() == info.def_id
2927-
}
2928-
ty::PredicateKind::Clause(ty::ClauseKind::Projection(p)) => {
2929-
p.projection_ty.def_id == info.def_id
2930-
}
2931-
_ => false,
2932-
}
2933-
}) && (type_is_local || info.def_id.is_local())
2932+
(type_is_local || info.def_id.is_local())
29342933
&& !self.tcx.trait_is_auto(info.def_id)
29352934
&& self
29362935
.associated_value(info.def_id, item_name)
@@ -2978,6 +2977,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
29782977
item.visibility(self.tcx).is_public() || info.def_id.is_local()
29792978
})
29802979
.is_some()
2980+
&& (matches!(rcvr_ty.kind(), ty::Param(_))
2981+
|| unsatisfied_predicates.iter().all(|(p, _, _)| {
2982+
match p.kind().skip_binder() {
2983+
// Hide traits if they are present in predicates as they can be fixed without
2984+
// having to implement them.
2985+
ty::PredicateKind::Clause(ty::ClauseKind::Trait(t)) => {
2986+
t.def_id() == info.def_id
2987+
}
2988+
ty::PredicateKind::Clause(ty::ClauseKind::Projection(p)) => {
2989+
p.projection_ty.def_id == info.def_id
2990+
}
2991+
_ => false,
2992+
}
2993+
}))
29812994
})
29822995
.collect::<Vec<_>>();
29832996
for span in &arbitrary_rcvr {

compiler/rustc_lint/src/context/diagnostics.rs

+40-10
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,23 @@ pub(super) fn builtin(
188188
#[allow(rustc::potential_query_instability)]
189189
let possibilities: Vec<Symbol> =
190190
sess.parse_sess.check_config.expecteds.keys().copied().collect();
191+
192+
let mut names_possibilities: Vec<_> = if value.is_none() {
193+
// We later sort and display all the possibilities, so the order here does not matter.
194+
#[allow(rustc::potential_query_instability)]
195+
sess.parse_sess
196+
.check_config
197+
.expecteds
198+
.iter()
199+
.filter_map(|(k, v)| match v {
200+
ExpectedValues::Some(v) if v.contains(&Some(name)) => Some(k),
201+
_ => None,
202+
})
203+
.collect()
204+
} else {
205+
Vec::new()
206+
};
207+
191208
let is_from_cargo = std::env::var_os("CARGO").is_some();
192209
let mut is_feature_cfg = name == sym::feature;
193210

@@ -262,17 +279,30 @@ pub(super) fn builtin(
262279
}
263280

264281
is_feature_cfg |= best_match == sym::feature;
265-
} else if !possibilities.is_empty() {
266-
let mut possibilities =
267-
possibilities.iter().map(Symbol::as_str).collect::<Vec<_>>();
268-
possibilities.sort();
269-
let possibilities = possibilities.join("`, `");
282+
} else {
283+
if !names_possibilities.is_empty() && names_possibilities.len() <= 3 {
284+
names_possibilities.sort();
285+
for cfg_name in names_possibilities.iter() {
286+
db.span_suggestion(
287+
name_span,
288+
"found config with similar value",
289+
format!("{cfg_name} = \"{name}\""),
290+
Applicability::MaybeIncorrect,
291+
);
292+
}
293+
}
294+
if !possibilities.is_empty() {
295+
let mut possibilities =
296+
possibilities.iter().map(Symbol::as_str).collect::<Vec<_>>();
297+
possibilities.sort();
298+
let possibilities = possibilities.join("`, `");
270299

271-
// The list of expected names can be long (even by default) and
272-
// so the diagnostic produced can take a lot of space. To avoid
273-
// cloging the user output we only want to print that diagnostic
274-
// once.
275-
db.help_once(format!("expected names are: `{possibilities}`"));
300+
// The list of expected names can be long (even by default) and
301+
// so the diagnostic produced can take a lot of space. To avoid
302+
// cloging the user output we only want to print that diagnostic
303+
// once.
304+
db.help_once(format!("expected names are: `{possibilities}`"));
305+
}
276306
}
277307

278308
let inst = if let Some((value, _value_span)) = value {

compiler/rustc_lint/src/lib.rs

+4
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,10 @@ fn register_builtins(store: &mut LintStore) {
516516
"converted into hard error, see PR #118649 \
517517
<https://github.com/rust-lang/rust/pull/118649> for more information",
518518
);
519+
store.register_removed(
520+
"illegal_floating_point_literal_pattern",
521+
"no longer a warning, float patterns behave the same as `==`",
522+
);
519523
}
520524

521525
fn register_internals(store: &mut LintStore) {

compiler/rustc_lint_defs/src/builtin.rs

-50
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ declare_lint_pass! {
4545
FUZZY_PROVENANCE_CASTS,
4646
HIDDEN_GLOB_REEXPORTS,
4747
ILL_FORMED_ATTRIBUTE_INPUT,
48-
ILLEGAL_FLOATING_POINT_LITERAL_PATTERN,
4948
INCOMPLETE_INCLUDE,
5049
INDIRECT_STRUCTURAL_MATCH,
5150
INEFFECTIVE_UNSTABLE_TRAIT_IMPL,
@@ -1873,55 +1872,6 @@ declare_lint! {
18731872
};
18741873
}
18751874

1876-
declare_lint! {
1877-
/// The `illegal_floating_point_literal_pattern` lint detects
1878-
/// floating-point literals used in patterns.
1879-
///
1880-
/// ### Example
1881-
///
1882-
/// ```rust
1883-
/// let x = 42.0;
1884-
///
1885-
/// match x {
1886-
/// 5.0 => {}
1887-
/// _ => {}
1888-
/// }
1889-
/// ```
1890-
///
1891-
/// {{produces}}
1892-
///
1893-
/// ### Explanation
1894-
///
1895-
/// Previous versions of the compiler accepted floating-point literals in
1896-
/// patterns, but it was later determined this was a mistake. The
1897-
/// semantics of comparing floating-point values may not be clear in a
1898-
/// pattern when contrasted with "structural equality". Typically you can
1899-
/// work around this by using a [match guard], such as:
1900-
///
1901-
/// ```rust
1902-
/// # let x = 42.0;
1903-
///
1904-
/// match x {
1905-
/// y if y == 5.0 => {}
1906-
/// _ => {}
1907-
/// }
1908-
/// ```
1909-
///
1910-
/// This is a [future-incompatible] lint to transition this to a hard
1911-
/// error in the future. See [issue #41620] for more details.
1912-
///
1913-
/// [issue #41620]: https://github.com/rust-lang/rust/issues/41620
1914-
/// [match guard]: https://doc.rust-lang.org/reference/expressions/match-expr.html#match-guards
1915-
/// [future-incompatible]: ../index.md#future-incompatible-lints
1916-
pub ILLEGAL_FLOATING_POINT_LITERAL_PATTERN,
1917-
Warn,
1918-
"floating-point literals cannot be used in patterns",
1919-
@future_incompatible = FutureIncompatibleInfo {
1920-
reason: FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps,
1921-
reference: "issue #41620 <https://github.com/rust-lang/rust/issues/41620>",
1922-
};
1923-
}
1924-
19251875
declare_lint! {
19261876
/// The `unstable_name_collisions` lint detects that you have used a name
19271877
/// that the standard library plans to add in the future.

compiler/rustc_middle/src/mir/interpret/value.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -418,8 +418,8 @@ impl<'tcx, Prov: Provenance> Scalar<Prov> {
418418

419419
#[inline]
420420
pub fn to_float<F: Float>(self) -> InterpResult<'tcx, F> {
421-
// Going through `to_uint` to check size and truncation.
422-
Ok(F::from_bits(self.to_uint(Size::from_bits(F::BITS))?))
421+
// Going through `to_bits` to check size and truncation.
422+
Ok(F::from_bits(self.to_bits(Size::from_bits(F::BITS))?))
423423
}
424424

425425
#[inline]

compiler/rustc_middle/src/ty/consts/int.rs

+44-27
Original file line numberDiff line numberDiff line change
@@ -249,11 +249,6 @@ impl ScalarInt {
249249
}
250250
}
251251

252-
#[inline]
253-
pub fn try_to_target_usize(&self, tcx: TyCtxt<'_>) -> Result<u64, Size> {
254-
Ok(self.to_bits(tcx.data_layout.pointer_size)? as u64)
255-
}
256-
257252
/// Tries to convert the `ScalarInt` to an unsigned integer of the given size.
258253
/// Fails if the size of the `ScalarInt` is not equal to `size` and returns the
259254
/// `ScalarInt`s size in that case.
@@ -262,56 +257,61 @@ impl ScalarInt {
262257
self.to_bits(size)
263258
}
264259

265-
// Tries to convert the `ScalarInt` to `bool`. Fails if the `size` of the `ScalarInt`
266-
// in not equal to `Size { raw: 1 }` or if the value is not 0 or 1 and returns the `size`
267-
// value of the `ScalarInt` in that case.
268-
#[inline]
269-
pub fn try_to_bool(self) -> Result<bool, Size> {
270-
match self.try_to_u8()? {
271-
0 => Ok(false),
272-
1 => Ok(true),
273-
_ => Err(self.size()),
274-
}
275-
}
276-
277260
// Tries to convert the `ScalarInt` to `u8`. Fails if the `size` of the `ScalarInt`
278261
// in not equal to `Size { raw: 1 }` and returns the `size` value of the `ScalarInt` in
279262
// that case.
280263
#[inline]
281264
pub fn try_to_u8(self) -> Result<u8, Size> {
282-
self.to_bits(Size::from_bits(8)).map(|v| u8::try_from(v).unwrap())
265+
self.try_to_uint(Size::from_bits(8)).map(|v| u8::try_from(v).unwrap())
283266
}
284267

285268
/// Tries to convert the `ScalarInt` to `u16`. Fails if the size of the `ScalarInt`
286269
/// in not equal to `Size { raw: 2 }` and returns the `size` value of the `ScalarInt` in
287270
/// that case.
288271
#[inline]
289272
pub fn try_to_u16(self) -> Result<u16, Size> {
290-
self.to_bits(Size::from_bits(16)).map(|v| u16::try_from(v).unwrap())
273+
self.try_to_uint(Size::from_bits(16)).map(|v| u16::try_from(v).unwrap())
291274
}
292275

293276
/// Tries to convert the `ScalarInt` to `u32`. Fails if the `size` of the `ScalarInt`
294277
/// in not equal to `Size { raw: 4 }` and returns the `size` value of the `ScalarInt` in
295278
/// that case.
296279
#[inline]
297280
pub fn try_to_u32(self) -> Result<u32, Size> {
298-
self.to_bits(Size::from_bits(32)).map(|v| u32::try_from(v).unwrap())
281+
self.try_to_uint(Size::from_bits(32)).map(|v| u32::try_from(v).unwrap())
299282
}
300283

301284
/// Tries to convert the `ScalarInt` to `u64`. Fails if the `size` of the `ScalarInt`
302285
/// in not equal to `Size { raw: 8 }` and returns the `size` value of the `ScalarInt` in
303286
/// that case.
304287
#[inline]
305288
pub fn try_to_u64(self) -> Result<u64, Size> {
306-
self.to_bits(Size::from_bits(64)).map(|v| u64::try_from(v).unwrap())
289+
self.try_to_uint(Size::from_bits(64)).map(|v| u64::try_from(v).unwrap())
307290
}
308291

309292
/// Tries to convert the `ScalarInt` to `u128`. Fails if the `size` of the `ScalarInt`
310293
/// in not equal to `Size { raw: 16 }` and returns the `size` value of the `ScalarInt` in
311294
/// that case.
312295
#[inline]
313296
pub fn try_to_u128(self) -> Result<u128, Size> {
314-
self.to_bits(Size::from_bits(128))
297+
self.try_to_uint(Size::from_bits(128))
298+
}
299+
300+
#[inline]
301+
pub fn try_to_target_usize(&self, tcx: TyCtxt<'_>) -> Result<u64, Size> {
302+
self.try_to_uint(tcx.data_layout.pointer_size).map(|v| u64::try_from(v).unwrap())
303+
}
304+
305+
// Tries to convert the `ScalarInt` to `bool`. Fails if the `size` of the `ScalarInt`
306+
// in not equal to `Size { raw: 1 }` or if the value is not 0 or 1 and returns the `size`
307+
// value of the `ScalarInt` in that case.
308+
#[inline]
309+
pub fn try_to_bool(self) -> Result<bool, Size> {
310+
match self.try_to_u8()? {
311+
0 => Ok(false),
312+
1 => Ok(true),
313+
_ => Err(self.size()),
314+
}
315315
}
316316

317317
/// Tries to convert the `ScalarInt` to a signed integer of the given size.
@@ -357,6 +357,27 @@ impl ScalarInt {
357357
pub fn try_to_i128(self) -> Result<i128, Size> {
358358
self.try_to_int(Size::from_bits(128))
359359
}
360+
361+
#[inline]
362+
pub fn try_to_target_isize(&self, tcx: TyCtxt<'_>) -> Result<i64, Size> {
363+
self.try_to_int(tcx.data_layout.pointer_size).map(|v| i64::try_from(v).unwrap())
364+
}
365+
366+
#[inline]
367+
pub fn try_to_float<F: Float>(self) -> Result<F, Size> {
368+
// Going through `to_uint` to check size and truncation.
369+
Ok(F::from_bits(self.to_bits(Size::from_bits(F::BITS))?))
370+
}
371+
372+
#[inline]
373+
pub fn try_to_f32(self) -> Result<Single, Size> {
374+
self.try_to_float()
375+
}
376+
377+
#[inline]
378+
pub fn try_to_f64(self) -> Result<Double, Size> {
379+
self.try_to_float()
380+
}
360381
}
361382

362383
macro_rules! from {
@@ -399,11 +420,7 @@ impl TryFrom<ScalarInt> for bool {
399420
type Error = Size;
400421
#[inline]
401422
fn try_from(int: ScalarInt) -> Result<Self, Size> {
402-
int.to_bits(Size::from_bytes(1)).and_then(|u| match u {
403-
0 => Ok(false),
404-
1 => Ok(true),
405-
_ => Err(Size::from_bytes(1)),
406-
})
423+
int.try_to_bool()
407424
}
408425
}
409426

compiler/rustc_mir_build/messages.ftl

+4-2
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,6 @@ mir_build_extern_static_requires_unsafe_unsafe_op_in_unsafe_fn_allowed =
107107
.note = extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior
108108
.label = use of extern static
109109
110-
mir_build_float_pattern = floating-point types cannot be used in patterns
111-
112110
mir_build_indirect_structural_match =
113111
to use a constant of type `{$non_sm_ty}` in a pattern, `{$non_sm_ty}` must be annotated with `#[derive(PartialEq)]`
114112
@@ -232,6 +230,10 @@ mir_build_mutation_of_layout_constrained_field_requires_unsafe_unsafe_op_in_unsa
232230
.note = mutating layout constrained fields cannot statically be checked for valid values
233231
.label = mutation of layout constrained field
234232
233+
mir_build_nan_pattern = cannot use NaN in patterns
234+
.note = NaNs compare inequal to everything, even themselves, so this pattern would never match
235+
.help = try using the `is_nan` method instead
236+
235237
mir_build_non_const_path = runtime values cannot be referenced in patterns
236238
237239
mir_build_non_empty_never_pattern =

0 commit comments

Comments
 (0)