diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index 5b06088c34814..6aeabc1bebb28 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -53,7 +53,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { || 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) diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs index 36096aa35d4cb..054d23c71d4a7 100644 --- a/compiler/rustc_hir_typeck/src/errors.rs +++ b/compiler/rustc_hir_typeck/src/errors.rs @@ -253,7 +253,7 @@ impl HelpUseLatestEdition { } #[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)] diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 48358e338dae1..d2a53ee8b5e10 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -1097,7 +1097,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { 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 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { 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 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { 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, diff --git a/tests/ui/associated-types/dont-suggest-cyclic-constraint.fixed b/tests/ui/associated-types/dont-suggest-cyclic-constraint.fixed deleted file mode 100644 index ec4165cc71e28..0000000000000 --- a/tests/ui/associated-types/dont-suggest-cyclic-constraint.fixed +++ /dev/null @@ -1,13 +0,0 @@ -// run-rustfix - -use std::fmt::Debug; - -pub fn foo(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() {} diff --git a/tests/ui/associated-types/dont-suggest-cyclic-constraint.rs b/tests/ui/associated-types/dont-suggest-cyclic-constraint.rs index 0b4df08783d63..0848b4c559b3a 100644 --- a/tests/ui/associated-types/dont-suggest-cyclic-constraint.rs +++ b/tests/ui/associated-types/dont-suggest-cyclic-constraint.rs @@ -1,5 +1,3 @@ -// run-rustfix - use std::fmt::Debug; pub fn foo(mut iter: I, value: &I::Item) diff --git a/tests/ui/associated-types/dont-suggest-cyclic-constraint.stderr b/tests/ui/associated-types/dont-suggest-cyclic-constraint.stderr index 65d18761b1874..3ecac9c83e571 100644 --- a/tests/ui/associated-types/dont-suggest-cyclic-constraint.stderr +++ b/tests/ui/associated-types/dont-suggest-cyclic-constraint.stderr @@ -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<::Item>`, found `Option<&::Item>` | = note: expected enum `Option<::Item>` found enum `Option<&::Item>` -help: use `Option::as_ref` to convert `Option<::Item>` to `Option<&::Item>` - | -LL | debug_assert_eq!(iter.next().as_ref(), Some(value)); - | +++++++++ error: aborting due to previous error diff --git a/tests/ui/suggestions/copied-and-cloned.fixed b/tests/ui/suggestions/copied-and-cloned.fixed index 77159d5075af7..4cecf9e26f9ee 100644 --- a/tests/ui/suggestions/copied-and-cloned.fixed +++ b/tests/ui/suggestions/copied-and-cloned.fixed @@ -2,6 +2,16 @@ fn expect(_: T) {} +struct Issue114925 { + x: Option, +} + +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::>(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` to `Option<&String>` - + //~| HELP use `Option::cloned` to clone the value inside the `Option` + //FIXME(#114050) ~| HELP use `Option::as_ref` to convert `Option` 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); } diff --git a/tests/ui/suggestions/copied-and-cloned.rs b/tests/ui/suggestions/copied-and-cloned.rs index c506494ee141c..a79928c50d565 100644 --- a/tests/ui/suggestions/copied-and-cloned.rs +++ b/tests/ui/suggestions/copied-and-cloned.rs @@ -2,6 +2,16 @@ fn expect(_: T) {} +struct Issue114925 { + x: Option, +} + +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::>(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` to `Option<&String>` - + //~| HELP use `Option::cloned` to clone the value inside the `Option` + //FIXME(#114050) ~| HELP use `Option::as_ref` to convert `Option` 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); } diff --git a/tests/ui/suggestions/copied-and-cloned.stderr b/tests/ui/suggestions/copied-and-cloned.stderr index f8712d0a39e17..87b0624d48be1 100644 --- a/tests/ui/suggestions/copied-and-cloned.stderr +++ b/tests/ui/suggestions/copied-and-cloned.stderr @@ -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`, found `Option<&String>` + | | + | expected due to the type of this binding + | + = note: expected enum `Option` + 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::>(x); | -------------------- ^ expected `Option<()>`, found `Option<&()>` @@ -19,7 +34,7 @@ LL | expect::>(x.copied()); | +++++++++ error[E0308]: mismatched types - --> $DIR/copied-and-cloned.rs:11:30 + --> $DIR/copied-and-cloned.rs:21:30 | LL | expect::>(x); | ------------------------ ^ expected `Result<(), ()>`, found `Result<&(), _>` @@ -39,7 +54,7 @@ LL | expect::>(x.copied()); | +++++++++ error[E0308]: mismatched types - --> $DIR/copied-and-cloned.rs:16:30 + --> $DIR/copied-and-cloned.rs:26:30 | LL | expect::>(x); | ------------------------ ^ expected `Option`, found `Option<&String>` @@ -59,7 +74,7 @@ LL | expect::>(x.cloned()); | +++++++++ error[E0308]: mismatched types - --> $DIR/copied-and-cloned.rs:20:34 + --> $DIR/copied-and-cloned.rs:30:34 | LL | expect::>(x); | ---------------------------- ^ expected `Result`, found `Result<&String, _>` @@ -79,20 +94,20 @@ LL | expect::>(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`, found `Option<&String>` | = note: expected enum `Option` found enum `Option<&String>` -help: use `Option::as_ref` to convert `Option` 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`, 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`.