Skip to content

Commit

Permalink
Do not emit empty suggestion
Browse files Browse the repository at this point in the history
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
estebank committed Dec 4, 2024
1 parent 490b2cc commit a7cc69e
Show file tree
Hide file tree
Showing 4 changed files with 81 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`.
// 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`.
// 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,18 @@
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:5: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:15: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:12: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 a7cc69e

Please sign in to comment.