Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 9 pull requests #109130

Merged
merged 23 commits into from
Mar 14, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
c0afabb
Support for Fuchsia RISC-V target
petrhosek Mar 2, 2023
8a5574b
Remove tests/ui/impl-trait/in-trait/new-lowering-strategy in favor of…
spastorino Mar 7, 2023
07e018d
Run existing async in traits tests using -Zlower-impl-trait-in-trait-…
spastorino Mar 7, 2023
b82d6a2
Run existing impl trait in traits tests using -Zlower-impl-trait-in-t…
spastorino Mar 8, 2023
b2f3198
Filter out RPITITs in astconv when checking for missing associated types
spastorino Mar 7, 2023
fa421ec
Filter out RPITITs in object_safety_violations_for_trait
spastorino Mar 7, 2023
8b9344a
Fix object safety checks for new RPITITs
spastorino Mar 8, 2023
0bb876e
Layout of `&dyn Trait<[type error]>` is still wide
compiler-errors Mar 13, 2023
8a53570
Don't ICE for late-bound consts across AnonConstBoundary
compiler-errors Mar 13, 2023
b535da6
Get impl defaultness using query
spastorino Mar 8, 2023
a4e4037
Make fns from other crates with RPITIT work
spastorino Mar 8, 2023
4824363
Remove some direct calls to local_def_id_to_hir_id on diagnostics
spastorino Mar 9, 2023
6a2a6fe
Emit "modifies receiver" diagnostic when no method is found
MaciejWas Mar 14, 2023
b36bbb0
Don't codegen impossible to satisfy impls
compiler-errors Mar 14, 2023
e006ee9
Rollup merge of #108722 - petrhosek:fuchsia-riscv, r=petrochenkov
matthiaskrgr Mar 14, 2023
5037836
Rollup merge of #108880 - spastorino:new-rpitit-6, r=compiler-errors
matthiaskrgr Mar 14, 2023
48934c4
Rollup merge of #108909 - spastorino:new-rpitit-7, r=compiler-errors
matthiaskrgr Mar 14, 2023
6e3a3de
Rollup merge of #108915 - spastorino:new-rpitit-8, r=compiler-errors
matthiaskrgr Mar 14, 2023
21d15db
Rollup merge of #108923 - spastorino:new-rpitit-9, r=compiler-errors
matthiaskrgr Mar 14, 2023
1f159b4
Rollup merge of #109101 - compiler-errors:layout-err, r=michaelwoerister
matthiaskrgr Mar 14, 2023
4c6b680
Rollup merge of #109105 - compiler-errors:late-ct-in-anon-ct, r=oli-obk
matthiaskrgr Mar 14, 2023
b88c675
Rollup merge of #109110 - compiler-errors:impossible-impl-mono, r=jac…
matthiaskrgr Mar 14, 2023
b17ee10
Rollup merge of #109116 - MaciejWas:add-modifies-receiver-diagn-when-…
matthiaskrgr Mar 14, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/demand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.annotate_expected_due_to_let_ty(err, expr, error);
self.emit_type_mismatch_suggestions(err, expr, expr_ty, expected, expected_ty_expr, error);
self.note_type_is_not_clone(err, expected, expr_ty, expr);
self.note_internal_mutation_in_method(err, expr, expected, expr_ty);
self.note_internal_mutation_in_method(err, expr, Some(expected), expr_ty);
self.check_for_range_as_method_call(err, expr, expr_ty, expected);
self.check_for_binding_assigned_block_without_tail_expression(err, expr, expr_ty, expected);
self.check_wrong_return_type_due_to_generic_arg(err, expr, expr_ty);
Expand Down
81 changes: 56 additions & 25 deletions compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -950,44 +950,75 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&self,
err: &mut Diagnostic,
expr: &hir::Expr<'_>,
expected: Ty<'tcx>,
expected: Option<Ty<'tcx>>,
found: Ty<'tcx>,
) {
if found != self.tcx.types.unit {
return;
}
if let ExprKind::MethodCall(path_segment, rcvr, ..) = expr.kind {
if self
.typeck_results

let ExprKind::MethodCall(path_segment, rcvr, ..) = expr.kind else {
return;
};

let rcvr_has_the_expected_type = self
.typeck_results
.borrow()
.expr_ty_adjusted_opt(rcvr)
.and_then(|ty| expected.map(|expected_ty| expected_ty.peel_refs() == ty.peel_refs()))
.unwrap_or(false);

let prev_call_mutates_and_returns_unit = || {
self.typeck_results
.borrow()
.expr_ty_adjusted_opt(rcvr)
.map_or(true, |ty| expected.peel_refs() != ty.peel_refs())
{
return;
}
let mut sp = MultiSpan::from_span(path_segment.ident.span);
sp.push_span_label(
path_segment.ident.span,
format!(
"this call modifies {} in-place",
match rcvr.kind {
ExprKind::Path(QPath::Resolved(
None,
hir::Path { segments: [segment], .. },
)) => format!("`{}`", segment.ident),
_ => "its receiver".to_string(),
}
),
);
.type_dependent_def_id(expr.hir_id)
.map(|def_id| self.tcx.fn_sig(def_id).skip_binder().skip_binder())
.and_then(|sig| sig.inputs_and_output.split_last())
.map(|(output, inputs)| {
output.is_unit()
&& inputs
.get(0)
.and_then(|self_ty| self_ty.ref_mutability())
.map_or(false, rustc_ast::Mutability::is_mut)
})
.unwrap_or(false)
};

if !(rcvr_has_the_expected_type || prev_call_mutates_and_returns_unit()) {
return;
}

let mut sp = MultiSpan::from_span(path_segment.ident.span);
sp.push_span_label(
path_segment.ident.span,
format!(
"this call modifies {} in-place",
match rcvr.kind {
ExprKind::Path(QPath::Resolved(
None,
hir::Path { segments: [segment], .. },
)) => format!("`{}`", segment.ident),
_ => "its receiver".to_string(),
}
),
);

let modifies_rcvr_note =
format!("method `{}` modifies its receiver in-place", path_segment.ident);
if rcvr_has_the_expected_type {
sp.push_span_label(
rcvr.span,
"you probably want to use this value after calling the method...",
);
err.span_note(sp, &modifies_rcvr_note);
err.note(&format!("...instead of the `()` output of method `{}`", path_segment.ident));
} else if let ExprKind::MethodCall(..) = rcvr.kind {
err.span_note(
sp,
&format!("method `{}` modifies its receiver in-place", path_segment.ident),
modifies_rcvr_note.clone() + ", it is not meant to be used in method chains.",
);
err.note(&format!("...instead of the `()` output of method `{}`", path_segment.ident));
} else {
err.span_note(sp, &modifies_rcvr_note);
}
}

Expand Down
7 changes: 7 additions & 0 deletions compiler/rustc_hir_typeck/src/method/suggest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
);
probe.is_ok()
});

self.note_internal_mutation_in_method(
&mut err,
rcvr_expr,
expected.to_option(&self),
rcvr_ty,
);
}

let mut custom_span_label = false;
Expand Down
6 changes: 5 additions & 1 deletion tests/ui/suggestions/chain-method-call-mutation-in-place.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
fn main() {}
fn main() {
let x: Vec<i32> = vec![1, 2, 3].into_iter().collect::<Vec<i32>>().sort_by_key(|i| i); //~ ERROR mismatched types
vec![1, 2, 3].into_iter().collect::<Vec<i32>>().sort_by_key(|i| i).sort(); //~ ERROR no method named `sort` found for unit type `()` in the current scope
}

fn foo(mut s: String) -> String {
s.push_str("asdf") //~ ERROR mismatched types
}
37 changes: 33 additions & 4 deletions tests/ui/suggestions/chain-method-call-mutation-in-place.stderr
Original file line number Diff line number Diff line change
@@ -1,20 +1,49 @@
error[E0308]: mismatched types
--> $DIR/chain-method-call-mutation-in-place.rs:3:5
--> $DIR/chain-method-call-mutation-in-place.rs:2:23
|
LL | let x: Vec<i32> = vec![1, 2, 3].into_iter().collect::<Vec<i32>>().sort_by_key(|i| i);
| -------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Vec<i32>`, found `()`
| |
| expected due to this
|
= note: expected struct `Vec<i32>`
found unit type `()`
note: method `sort_by_key` modifies its receiver in-place, it is not meant to be used in method chains.
--> $DIR/chain-method-call-mutation-in-place.rs:2:71
|
LL | let x: Vec<i32> = vec![1, 2, 3].into_iter().collect::<Vec<i32>>().sort_by_key(|i| i);
| ^^^^^^^^^^^ this call modifies its receiver in-place

error[E0599]: no method named `sort` found for unit type `()` in the current scope
--> $DIR/chain-method-call-mutation-in-place.rs:3:72
|
LL | vec![1, 2, 3].into_iter().collect::<Vec<i32>>().sort_by_key(|i| i).sort();
| ^^^^ method not found in `()`
|
note: method `sort_by_key` modifies its receiver in-place, it is not meant to be used in method chains.
--> $DIR/chain-method-call-mutation-in-place.rs:3:53
|
LL | vec![1, 2, 3].into_iter().collect::<Vec<i32>>().sort_by_key(|i| i).sort();
| ^^^^^^^^^^^ this call modifies its receiver in-place

error[E0308]: mismatched types
--> $DIR/chain-method-call-mutation-in-place.rs:7:5
|
LL | fn foo(mut s: String) -> String {
| ------ expected `String` because of return type
LL | s.push_str("asdf")
| ^^^^^^^^^^^^^^^^^^ expected `String`, found `()`
|
note: method `push_str` modifies its receiver in-place
--> $DIR/chain-method-call-mutation-in-place.rs:3:7
--> $DIR/chain-method-call-mutation-in-place.rs:7:7
|
LL | s.push_str("asdf")
| - ^^^^^^^^ this call modifies `s` in-place
| |
| you probably want to use this value after calling the method...
= note: ...instead of the `()` output of method `push_str`

error: aborting due to previous error
error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0308`.
Some errors have detailed explanations: E0308, E0599.
For more information about an error, try `rustc --explain E0308`.