diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 54d8306936dd6..84ee80bdac48a 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -2313,7 +2313,10 @@ impl<'a, 'b, 'tcx> FnCallDiagCtxt<'a, 'b, 'tcx> { .get(ProvidedIdx::from_usize(arg_idx.index() - 1)) { // Include previous comma - span = prev.shrink_to_hi().to(span); + let prev_comma = prev.shrink_to_hi(); + if prev_comma.eq_ctxt(span) { + span = prev_comma.to(span); + } } // Is last argument for deletion in a row starting from the 0-th argument? @@ -2345,24 +2348,32 @@ impl<'a, 'b, 'tcx> FnCallDiagCtxt<'a, 'b, 'tcx> { }; if trim_next_comma { - let next = self - .provided_arg_tys - .get(*arg_idx + 1) - .map(|&(_, sp)| sp) - .unwrap_or_else(|| { - // Try to move before `)`. Note that `)` here is not necessarily - // the latin right paren, it could be a Unicode-confusable that - // looks like a `)`, so we must not use `- BytePos(1)` - // manipulations here. - self.arg_matching_ctxt - .tcx() - .sess - .source_map() - .end_point(self.call_expr.span) - }); - - // Include next comma - span = span.until(next); + let next = + self.provided_arg_tys.get(*arg_idx + 1).map(|&(_, sp)| sp).or_else( + || { + // Try to move before `)`. Note that `)` here is not necessarily + // the latin right paren, it could be a Unicode-confusable that + // looks like a `)`, so we must not use `- BytePos(1)` + // manipulations here. + self.call_expr.span.find_ancestor_in_same_ctxt(span).map( + |call_span| { + self.arg_matching_ctxt + .tcx() + .sess + .source_map() + .end_point(call_span) + }, + ) + }, + ); + + if let Some(next) = next + // Avoid `Span::until` context fallback producing unrelated spans. + && span.eq_ctxt(next) + { + // Include next comma + span = span.until(next); + } } suggestions.push((span, String::new())); diff --git a/tests/crashes/131762.rs b/tests/crashes/131762.rs deleted file mode 100644 index 4080272226d94..0000000000000 --- a/tests/crashes/131762.rs +++ /dev/null @@ -1,10 +0,0 @@ -//@ needs-rustc-debug-assertions -//@ known-bug: #131762 -// ignore-tidy-linelength - -#![feature(generic_assert)] -struct FloatWrapper(f64); - -fn main() { - assert!((0.0 / 0.0 >= 0.0) == (FloatWrapper(0.0 / 0.0) >= FloatWrapper(size_of::, size_of::, size_of:: as fn() -> usize))) -} diff --git a/tests/ui/typeck/generic-assert-extra-args-empty-span-suggestion.rs b/tests/ui/typeck/generic-assert-extra-args-empty-span-suggestion.rs new file mode 100644 index 0000000000000..677c29ebb7fe9 --- /dev/null +++ b/tests/ui/typeck/generic-assert-extra-args-empty-span-suggestion.rs @@ -0,0 +1,19 @@ +// Regression test for issue #131762. + +#![feature(generic_assert)] + +struct FloatWrapper(f64); + +fn main() { + assert!( + (0.0 / 0.0 >= 0.0) + == (FloatWrapper(0.0 / 0.0) + >= FloatWrapper( //~ ERROR binary operation `>=` cannot be applied to type `FloatWrapper` + //~| ERROR this struct takes 1 argument but 3 arguments were supplied + //~| ERROR this struct takes 1 argument but 3 arguments were supplied + size_of::, + size_of::, + size_of:: as fn() -> usize, + )) + ); +} diff --git a/tests/ui/typeck/generic-assert-extra-args-empty-span-suggestion.stderr b/tests/ui/typeck/generic-assert-extra-args-empty-span-suggestion.stderr new file mode 100644 index 0000000000000..b158344e1674d --- /dev/null +++ b/tests/ui/typeck/generic-assert-extra-args-empty-span-suggestion.stderr @@ -0,0 +1,103 @@ +error[E0061]: this struct takes 1 argument but 3 arguments were supplied + --> $DIR/generic-assert-extra-args-empty-span-suggestion.rs:11:20 + | +LL | >= FloatWrapper( + | ^^^^^^^^^^^^ +... +LL | size_of::, + | -------------- unexpected argument #2 of type `fn() -> usize {std::mem::size_of::}` +LL | size_of:: as fn() -> usize, + | --------------------------------- unexpected argument #3 of type `fn() -> usize` + | +note: expected `f64`, found fn item + --> $DIR/generic-assert-extra-args-empty-span-suggestion.rs:8:5 + | +LL | / assert!( +LL | | (0.0 / 0.0 >= 0.0) +LL | | == (FloatWrapper(0.0 / 0.0) +LL | | >= FloatWrapper( +... | +LL | | )) +LL | | ); + | |_____^ + = note: expected type `f64` + found fn item `fn() -> usize {std::mem::size_of::}` +note: tuple struct defined here + --> $DIR/generic-assert-extra-args-empty-span-suggestion.rs:5:8 + | +LL | struct FloatWrapper(f64); + | ^^^^^^^^^^^^ +help: remove the extra arguments + | +LL - size_of::, +LL - size_of:: as fn() -> usize, +LL + , + | + +error[E0061]: this struct takes 1 argument but 3 arguments were supplied + --> $DIR/generic-assert-extra-args-empty-span-suggestion.rs:11:20 + | +LL | >= FloatWrapper( + | ^^^^^^^^^^^^ +... +LL | size_of::, + | -------------- unexpected argument #2 of type `fn() -> usize {std::mem::size_of::}` +LL | size_of:: as fn() -> usize, + | --------------------------------- unexpected argument #3 of type `fn() -> usize` + | +note: expected `f64`, found fn item + --> $DIR/generic-assert-extra-args-empty-span-suggestion.rs:8:5 + | +LL | / assert!( +LL | | (0.0 / 0.0 >= 0.0) +LL | | == (FloatWrapper(0.0 / 0.0) +LL | | >= FloatWrapper( +... | +LL | | )) +LL | | ); + | |_____^ + = note: expected type `f64` + found fn item `fn() -> usize {std::mem::size_of::}` +note: tuple struct defined here + --> $DIR/generic-assert-extra-args-empty-span-suggestion.rs:5:8 + | +LL | struct FloatWrapper(f64); + | ^^^^^^^^^^^^ + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: remove the extra arguments + | +LL - size_of::, +LL - size_of:: as fn() -> usize, +LL + , + | + +error[E0369]: binary operation `>=` cannot be applied to type `FloatWrapper` + --> $DIR/generic-assert-extra-args-empty-span-suggestion.rs:11:17 + | +LL | == (FloatWrapper(0.0 / 0.0) + | ----------------------- FloatWrapper +LL | >= FloatWrapper( + | _________________^^_- +LL | | +LL | | +LL | | size_of::, +LL | | size_of::, +LL | | size_of:: as fn() -> usize, +LL | | )) + | |_________________- FloatWrapper + | +note: an implementation of `PartialOrd` might be missing for `FloatWrapper` + --> $DIR/generic-assert-extra-args-empty-span-suggestion.rs:5:1 + | +LL | struct FloatWrapper(f64); + | ^^^^^^^^^^^^^^^^^^^ must implement `PartialOrd` +help: consider annotating `FloatWrapper` with `#[derive(PartialEq, PartialOrd)]` + | +LL + #[derive(PartialEq, PartialOrd)] +LL | struct FloatWrapper(f64); + | + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0061, E0369. +For more information about an error, try `rustc --explain E0061`. diff --git a/tests/ui/typeck/suggestions/suggest-extra-arg-empty-span-ice.rs b/tests/ui/typeck/suggestions/suggest-extra-arg-empty-span-ice.rs new file mode 100644 index 0000000000000..956c50cf3d51f --- /dev/null +++ b/tests/ui/typeck/suggestions/suggest-extra-arg-empty-span-ice.rs @@ -0,0 +1,14 @@ +// Regression test for https://github.com/rust-lang/rust/issues/152414 + +#![feature(generic_assert)] +pub const fn make_1u8_bag() -> BagOfBits<_> { + //~^ ERROR cannot find type `BagOfBits` in this scope + //~| ERROR the placeholder `_` is not allowed within types on item signatures for return types + assert!(core::mem::size_of::(val, 1) >= 1); + //~^ ERROR cannot find value `val` in this scope + //~| ERROR this function takes 0 arguments but 2 arguments were supplied + bag + //~^ ERROR cannot find value `bag` in this scope +} + +fn main() {} diff --git a/tests/ui/typeck/suggestions/suggest-extra-arg-empty-span-ice.stderr b/tests/ui/typeck/suggestions/suggest-extra-arg-empty-span-ice.stderr new file mode 100644 index 0000000000000..8918e33514ef3 --- /dev/null +++ b/tests/ui/typeck/suggestions/suggest-extra-arg-empty-span-ice.stderr @@ -0,0 +1,45 @@ +error[E0425]: cannot find type `BagOfBits` in this scope + --> $DIR/suggest-extra-arg-empty-span-ice.rs:4:41 + | +LL | pub const fn make_1u8_bag() -> BagOfBits<_> { + | ^^^^^^^^^ not found in this scope + +error[E0425]: cannot find value `val` in this scope + --> $DIR/suggest-extra-arg-empty-span-ice.rs:7:37 + | +LL | assert!(core::mem::size_of::(val, 1) >= 1); + | ^^^ not found in this scope + +error[E0425]: cannot find value `bag` in this scope + --> $DIR/suggest-extra-arg-empty-span-ice.rs:10:5 + | +LL | bag + | ^^^ not found in this scope + +error[E0061]: this function takes 0 arguments but 2 arguments were supplied + --> $DIR/suggest-extra-arg-empty-span-ice.rs:7:13 + | +LL | assert!(core::mem::size_of::(val, 1) >= 1); + | --------^^^^^^^^^^^^^^^^^^^^^^^-------------- + | | | + | | unexpected argument #2 of type `{integer}` + | unexpected argument #1 + | +note: function defined here + --> $SRC_DIR/core/src/mem/mod.rs:LL:COL +help: remove the extra argument + | +LL - assert!(core::mem::size_of::(val, 1) >= 1); +LL + assert!(core::mem::size_of::(val, ) >= 1); + | + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/suggest-extra-arg-empty-span-ice.rs:4:51 + | +LL | pub const fn make_1u8_bag() -> BagOfBits<_> { + | ^ not allowed in type signatures + +error: aborting due to 5 previous errors + +Some errors have detailed explanations: E0061, E0121, E0425. +For more information about an error, try `rustc --explain E0061`.