Skip to content

Commit

Permalink
Rollup merge of #133843 - estebank:empty-semi-sugg, r=jieyouxu
Browse files Browse the repository at this point in the history
Do not emit empty suggestion

The `println!();` statement's span doesn't include the `;`, and the modified suggestions where trying to get the `;` by getting the differenece between the statement's and the expression's spans, which was an empty suggestion.

Fix #133833, fix #133834.
  • Loading branch information
fmease authored Dec 5, 2024
2 parents d692b1f + 1b449e1 commit ab16eeb
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 1 deletion.
8 changes: 7 additions & 1 deletion compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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()),
Expand Down Expand Up @@ -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()),
Expand Down
Original file line number Diff line number Diff line change
@@ -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: <https://github.com/rust-lang/rust/issues/133833>.
//! Issue 2: <https://github.com/rust-lang/rust/issues/133834>.
//! See also: <https://github.com/rust-lang/rust/issues/133845>.
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::<String>(); //~ ERROR E0277
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -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::<String>();
| ------- ^^^^^^ value of type `String` cannot be built from `std::iter::Iterator<Item=()>`
| |
| 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<A>`:
`String` implements `FromIterator<&char>`
`String` implements `FromIterator<&str>`
`String` implements `FromIterator<Box<str, A>>`
`String` implements `FromIterator<Cow<'_, str>>`
`String` implements `FromIterator<String>`
`String` implements `FromIterator<char>`
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`.

0 comments on commit ab16eeb

Please sign in to comment.