diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 61260dbd16c51..ddcd90a2a9da6 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -3394,7 +3394,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let Some(ty) = self.node_ty_opt(tail_expr.hir_id) else { return; }; - if self.can_eq(self.param_env, expected_ty, ty) { + if self.can_eq(self.param_env, expected_ty, ty) + // FIXME: this happens with macro calls. Need to figure out why the stmt + // `println!();` doesn't include the `;` in its `Span`. (#133845) + // We filter these out to avoid ICEs with debug assertions on caused by + // empty suggestions. + && stmt.span.hi() != tail_expr.span.hi() + { err.span_suggestion_short( stmt.span.with_lo(tail_expr.span.hi()), "remove this semicolon", diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index 2bb503f17b4ed..94682f501a8c4 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -3838,6 +3838,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { && self.predicate_must_hold_modulo_regions(&Obligation::misc( tcx, expr.span, body_id, param_env, pred, )) + && expr.span.hi() != rcvr.span.hi() { err.span_suggestion_verbose( expr.span.with_lo(rcvr.span.hi()), @@ -4115,6 +4116,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // the expected is a projection that we need to resolve. // && let Some(tail_ty) = typeck_results.expr_ty_opt(expr) && expected_found.found.is_unit() + // FIXME: this happens with macro calls. Need to figure out why the stmt + // `println!();` doesn't include the `;` in its `Span`. (#133845) + // We filter these out to avoid ICEs with debug assertions on caused by + // empty suggestions. + && expr.span.hi() != stmt.span.hi() { err.span_suggestion_verbose( expr.span.shrink_to_hi().with_hi(stmt.span.hi()), diff --git a/tests/ui/suggestions/semi-suggestion-when-stmt-and-expr-span-equal.rs b/tests/ui/suggestions/semi-suggestion-when-stmt-and-expr-span-equal.rs new file mode 100644 index 0000000000000..35612093aff04 --- /dev/null +++ b/tests/ui/suggestions/semi-suggestion-when-stmt-and-expr-span-equal.rs @@ -0,0 +1,26 @@ +//! Regression test for suggestions that were fired on empty spans +//! involving macro-call statements. For some reason the semicolon +//! is not included in the overall span of the macro-call statement. +//! +//! Issue 1: . +//! Issue 2: . +//! See also: . + +fn foo() -> String { + let mut list = { + println!(); + }; + list //~ ERROR mismatched types +} + +fn bar() { + String::new() + .chars() + .filter(|x| !x.is_whitespace()) + .map(|x| { + println!("Child spawned with the size: {}", x); + }) + .collect::(); //~ ERROR E0277 +} + +fn main() {} diff --git a/tests/ui/suggestions/semi-suggestion-when-stmt-and-expr-span-equal.stderr b/tests/ui/suggestions/semi-suggestion-when-stmt-and-expr-span-equal.stderr new file mode 100644 index 0000000000000..4b83bfff86333 --- /dev/null +++ b/tests/ui/suggestions/semi-suggestion-when-stmt-and-expr-span-equal.stderr @@ -0,0 +1,50 @@ +error[E0308]: mismatched types + --> $DIR/semi-suggestion-when-stmt-and-expr-span-equal.rs:13:5 + | +LL | fn foo() -> String { + | ------ expected `String` because of return type +LL | let mut list = { + | ____________________- +LL | | println!(); +LL | | }; + | |_____- this block is missing a tail expression +LL | list + | ^^^^ expected `String`, found `()` + +error[E0277]: a value of type `String` cannot be built from an iterator over elements of type `()` + --> $DIR/semi-suggestion-when-stmt-and-expr-span-equal.rs:23:20 + | +LL | .collect::(); + | ------- ^^^^^^ value of type `String` cannot be built from `std::iter::Iterator` + | | + | required by a bound introduced by this call + | + = help: the trait `FromIterator<()>` is not implemented for `String` + = help: the following other types implement trait `FromIterator`: + `String` implements `FromIterator<&char>` + `String` implements `FromIterator<&str>` + `String` implements `FromIterator>` + `String` implements `FromIterator>` + `String` implements `FromIterator` + `String` implements `FromIterator` +note: the method call chain might not have had the expected associated types + --> $DIR/semi-suggestion-when-stmt-and-expr-span-equal.rs:20:10 + | +LL | String::new() + | ------------- this expression has type `String` +LL | .chars() + | ------- `Iterator::Item` is `char` here +LL | .filter(|x| !x.is_whitespace()) + | ------------------------------ `Iterator::Item` remains `char` here +LL | .map(|x| { + | __________^ +LL | | println!("Child spawned with the size: {}", x); +LL | | }) + | |__________^ `Iterator::Item` changed to `()` here +note: required by a bound in `collect` + --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0277, E0308. +For more information about an error, try `rustc --explain E0277`.