Rollup merge of #114931 - Urgau:revert-114052, r=compiler-errors

Revert PR #114052 to fix invalid suggestion

This PR reverts https://github.com/rust-lang/rust/pull/114052 to fix the invalid suggestion produced by the PR.

Unfortunately the invalid suggestion cannot be improved from the current position where it's emitted since we lack enough information (is an assignment?, left or right?, ...) to be able to fix it here. Furthermore the previous wasn't wrong, just suboptimal, contrary to the current one which is just wrong.

Added a regression test and commented out some code instead of removing it so we can use it later.

Reopens https://github.com/rust-lang/rust/issues/114050
Fixes https://github.com/rust-lang/rust/issues/114925
This commit is contained in:
Josh Stone 2023-08-17 15:40:09 -07:00 committed by GitHub
commit 5861815559
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 73 additions and 61 deletions

View File

@ -53,7 +53,7 @@ pub fn emit_type_mismatch_suggestions(
|| self.suggest_no_capture_closure(err, expected, expr_ty)
|| self.suggest_boxing_when_appropriate(err, expr.span, expr.hir_id, expected, expr_ty)
|| self.suggest_block_to_brackets_peeling_refs(err, expr, expr_ty, expected)
|| self.suggest_copied_cloned_or_as_ref(err, expr, expr_ty, expected, expected_ty_expr)
|| self.suggest_copied_cloned_or_as_ref(err, expr, expr_ty, expected)
|| self.suggest_clone_for_ref(err, expr, expr_ty, expected)
|| self.suggest_into(err, expr, expr_ty, expected)
|| self.suggest_floating_point_literal(err, expr, expected)

View File

@ -253,7 +253,7 @@ pub fn new() -> Self {
}
#[derive(Subdiagnostic)]
pub enum OptionResultRefMismatch<'tcx> {
pub enum OptionResultRefMismatch {
#[suggestion(
hir_typeck_option_result_copied,
code = ".copied()",
@ -276,19 +276,20 @@ pub enum OptionResultRefMismatch<'tcx> {
span: Span,
def_path: String,
},
#[suggestion(
hir_typeck_option_result_asref,
code = ".as_ref()",
style = "verbose",
applicability = "machine-applicable"
)]
AsRef {
#[primary_span]
span: Span,
def_path: String,
expected_ty: Ty<'tcx>,
expr_ty: Ty<'tcx>,
},
// FIXME: #114050
// #[suggestion(
// hir_typeck_option_result_asref,
// code = ".as_ref()",
// style = "verbose",
// applicability = "machine-applicable"
// )]
// AsRef {
// #[primary_span]
// span: Span,
// def_path: String,
// expected_ty: Ty<'tcx>,
// expr_ty: Ty<'tcx>,
// },
}
#[derive(Diagnostic)]

View File

@ -1097,7 +1097,6 @@ pub(crate) fn suggest_copied_cloned_or_as_ref(
expr: &hir::Expr<'_>,
expr_ty: Ty<'tcx>,
expected_ty: Ty<'tcx>,
expected_ty_expr: Option<&'tcx hir::Expr<'tcx>>,
) -> bool {
let ty::Adt(adt_def, args) = expr_ty.kind() else {
return false;
@ -1115,7 +1114,7 @@ pub(crate) fn suggest_copied_cloned_or_as_ref(
{
let expr_inner_ty = args.type_at(0);
let expected_inner_ty = expected_args.type_at(0);
if let &ty::Ref(_, ty, mutability) = expr_inner_ty.kind()
if let &ty::Ref(_, ty, _mutability) = expr_inner_ty.kind()
&& self.can_eq(self.param_env, ty, expected_inner_ty)
{
let def_path = self.tcx.def_path_str(adt_def.did());
@ -1124,14 +1123,6 @@ pub(crate) fn suggest_copied_cloned_or_as_ref(
errors::OptionResultRefMismatch::Copied {
span, def_path
}
} else if let Some(expected_ty_expr) = expected_ty_expr
// FIXME: suggest changes to both expressions to convert both to
// Option/Result<&T>
&& mutability.is_not()
{
errors::OptionResultRefMismatch::AsRef {
span: expected_ty_expr.span.shrink_to_hi(), expected_ty, expr_ty, def_path
}
} else if let Some(clone_did) = self.tcx.lang_items().clone_trait()
&& rustc_trait_selection::traits::type_known_to_meet_bound_modulo_regions(
self,

View File

@ -1,13 +0,0 @@
// run-rustfix
use std::fmt::Debug;
pub fn foo<I: Iterator>(mut iter: I, value: &I::Item)
where
I::Item: Eq + Debug,
{
debug_assert_eq!(iter.next().as_ref(), Some(value));
//~^ ERROR mismatched types
}
fn main() {}

View File

@ -1,5 +1,3 @@
// run-rustfix
use std::fmt::Debug;
pub fn foo<I: Iterator>(mut iter: I, value: &I::Item)

View File

@ -1,15 +1,11 @@
error[E0308]: mismatched types
--> $DIR/dont-suggest-cyclic-constraint.rs:9:35
--> $DIR/dont-suggest-cyclic-constraint.rs:7:35
|
LL | debug_assert_eq!(iter.next(), Some(value));
| ^^^^^^^^^^^ expected `Option<<I as Iterator>::Item>`, found `Option<&<I as Iterator>::Item>`
|
= note: expected enum `Option<<I as Iterator>::Item>`
found enum `Option<&<I as Iterator>::Item>`
help: use `Option::as_ref` to convert `Option<<I as Iterator>::Item>` to `Option<&<I as Iterator>::Item>`
|
LL | debug_assert_eq!(iter.next().as_ref(), Some(value));
| +++++++++
error: aborting due to previous error

View File

@ -2,6 +2,16 @@
fn expect<T>(_: T) {}
struct Issue114925 {
x: Option<String>,
}
fn issue_114925(lol: &mut Issue114925, x: Option<&String>) {
lol.x = x.clone().cloned();
//~^ ERROR mismatched types
//~| HELP use `Option::cloned` to clone the value inside the `Option`
}
fn main() {
let x = Some(&());
expect::<Option<()>>(x.copied());
@ -24,10 +34,10 @@ fn main() {
let s = String::new();
let x = Some(s.clone());
let y = Some(&s);
println!("{}", x.as_ref() == y);
println!("{}", x == y.cloned());
//~^ ERROR mismatched types
//~| HELP use `Option::as_ref` to convert `Option<String>` to `Option<&String>`
//~| HELP use `Option::cloned` to clone the value inside the `Option`
//FIXME(#114050) ~| HELP use `Option::as_ref` to convert `Option<String>` to `Option<&String>`
let mut s = ();
let x = Some(s);
@ -42,4 +52,6 @@ fn main() {
println!("{}", x == y.cloned());
//~^ ERROR mismatched types
//~| HELP use `Option::cloned` to clone the value inside the `Option`
issue_114925(&mut Issue114925 { x: None }, None);
}

View File

@ -2,6 +2,16 @@
fn expect<T>(_: T) {}
struct Issue114925 {
x: Option<String>,
}
fn issue_114925(lol: &mut Issue114925, x: Option<&String>) {
lol.x = x.clone();
//~^ ERROR mismatched types
//~| HELP use `Option::cloned` to clone the value inside the `Option`
}
fn main() {
let x = Some(&());
expect::<Option<()>>(x);
@ -26,8 +36,8 @@ fn main() {
let y = Some(&s);
println!("{}", x == y);
//~^ ERROR mismatched types
//~| HELP use `Option::as_ref` to convert `Option<String>` to `Option<&String>`
//~| HELP use `Option::cloned` to clone the value inside the `Option`
//FIXME(#114050) ~| HELP use `Option::as_ref` to convert `Option<String>` to `Option<&String>`
let mut s = ();
let x = Some(s);
@ -42,4 +52,6 @@ fn main() {
println!("{}", x == y);
//~^ ERROR mismatched types
//~| HELP use `Option::cloned` to clone the value inside the `Option`
issue_114925(&mut Issue114925 { x: None }, None);
}

View File

@ -1,5 +1,20 @@
error[E0308]: mismatched types
--> $DIR/copied-and-cloned.rs:7:26
--> $DIR/copied-and-cloned.rs:10:13
|
LL | lol.x = x.clone();
| ----- ^^^^^^^^^ expected `Option<String>`, found `Option<&String>`
| |
| expected due to the type of this binding
|
= note: expected enum `Option<String>`
found enum `Option<&String>`
help: use `Option::cloned` to clone the value inside the `Option`
|
LL | lol.x = x.clone().cloned();
| +++++++++
error[E0308]: mismatched types
--> $DIR/copied-and-cloned.rs:17:26
|
LL | expect::<Option<()>>(x);
| -------------------- ^ expected `Option<()>`, found `Option<&()>`
@ -19,7 +34,7 @@ LL | expect::<Option<()>>(x.copied());
| +++++++++
error[E0308]: mismatched types
--> $DIR/copied-and-cloned.rs:11:30
--> $DIR/copied-and-cloned.rs:21:30
|
LL | expect::<Result<(), ()>>(x);
| ------------------------ ^ expected `Result<(), ()>`, found `Result<&(), _>`
@ -39,7 +54,7 @@ LL | expect::<Result<(), ()>>(x.copied());
| +++++++++
error[E0308]: mismatched types
--> $DIR/copied-and-cloned.rs:16:30
--> $DIR/copied-and-cloned.rs:26:30
|
LL | expect::<Option<String>>(x);
| ------------------------ ^ expected `Option<String>`, found `Option<&String>`
@ -59,7 +74,7 @@ LL | expect::<Option<String>>(x.cloned());
| +++++++++
error[E0308]: mismatched types
--> $DIR/copied-and-cloned.rs:20:34
--> $DIR/copied-and-cloned.rs:30:34
|
LL | expect::<Result<String, ()>>(x);
| ---------------------------- ^ expected `Result<String, ()>`, found `Result<&String, _>`
@ -79,20 +94,20 @@ LL | expect::<Result<String, ()>>(x.cloned());
| +++++++++
error[E0308]: mismatched types
--> $DIR/copied-and-cloned.rs:27:25
--> $DIR/copied-and-cloned.rs:37:25
|
LL | println!("{}", x == y);
| ^ expected `Option<String>`, found `Option<&String>`
|
= note: expected enum `Option<String>`
found enum `Option<&String>`
help: use `Option::as_ref` to convert `Option<String>` to `Option<&String>`
help: use `Option::cloned` to clone the value inside the `Option`
|
LL | println!("{}", x.as_ref() == y);
LL | println!("{}", x == y.cloned());
| +++++++++
error[E0308]: mismatched types
--> $DIR/copied-and-cloned.rs:35:25
--> $DIR/copied-and-cloned.rs:45:25
|
LL | println!("{}", x == y);
| ^ expected `Option<()>`, found `Option<&mut ()>`
@ -105,7 +120,7 @@ LL | println!("{}", x == y.copied());
| +++++++++
error[E0308]: mismatched types
--> $DIR/copied-and-cloned.rs:42:25
--> $DIR/copied-and-cloned.rs:52:25
|
LL | println!("{}", x == y);
| ^ expected `Option<String>`, found `Option<&mut String>`
@ -117,6 +132,6 @@ help: use `Option::cloned` to clone the value inside the `Option`
LL | println!("{}", x == y.cloned());
| +++++++++
error: aborting due to 7 previous errors
error: aborting due to 8 previous errors
For more information about this error, try `rustc --explain E0308`.