diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 1d16c3af7fb75..1adcd91cc3ee2 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -2106,14 +2106,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { )), ); - let (article, kind, variant, sugg_operator) = - if self.tcx.is_diagnostic_item(sym::Result, adt.did()) { - ("a", "Result", "Err", ret_ty_matches(sym::Result)) - } else if self.tcx.is_diagnostic_item(sym::Option, adt.did()) { - ("an", "Option", "None", ret_ty_matches(sym::Option)) - } else { - return false; - }; + let (article, kind, variant, sugg_operator) = if self.tcx.is_diagnostic_item(sym::Result, adt.did()) + // Do not suggest `.expect()` in const context where it's not available. rust-lang/rust#149316 + && !self.tcx.hir_is_inside_const_context(expr.hir_id) + { + ("a", "Result", "Err", ret_ty_matches(sym::Result)) + } else if self.tcx.is_diagnostic_item(sym::Option, adt.did()) { + ("an", "Option", "None", ret_ty_matches(sym::Option)) + } else { + return false; + }; if is_ctor || !self.may_coerce(args.type_at(0), expected) { return false; } diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 9a657ab159035..4b9ad345210dd 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -3041,14 +3041,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { tcx.def_span(pick.item.def_id), format!("the method `{item_name}` exists on the type `{self_ty}`"), ); - let (article, kind, variant, question) = - if tcx.is_diagnostic_item(sym::Result, kind.did()) { - ("a", "Result", "Err", ret_ty_matches(sym::Result)) - } else if tcx.is_diagnostic_item(sym::Option, kind.did()) { - ("an", "Option", "None", ret_ty_matches(sym::Option)) - } else { - return; - }; + let (article, kind, variant, question) = if tcx.is_diagnostic_item(sym::Result, kind.did()) + // Do not suggest `.expect()` in const context where it's not available. rust-lang/rust#149316 + && !tcx.hir_is_inside_const_context(expr.hir_id) + { + ("a", "Result", "Err", ret_ty_matches(sym::Result)) + } else if tcx.is_diagnostic_item(sym::Option, kind.did()) { + ("an", "Option", "None", ret_ty_matches(sym::Option)) + } else { + return; + }; if question { err.span_suggestion_verbose( expr.span.shrink_to_hi(), diff --git a/tests/ui/consts/const-result-no-expect-suggestion.rs b/tests/ui/consts/const-result-no-expect-suggestion.rs new file mode 100644 index 0000000000000..cd725d9cee0ec --- /dev/null +++ b/tests/ui/consts/const-result-no-expect-suggestion.rs @@ -0,0 +1,15 @@ +const fn f(value: u32) -> Result { + Ok(value) +} + +const TEST: u32 = f(2); +//~^ ERROR: mismatched types + +const fn g() -> Result { + Ok(String::new()) +} + +const TEST2: usize = g().len(); +//~^ ERROR: no method named `len` found for enum `Result` + +fn main() {} diff --git a/tests/ui/consts/const-result-no-expect-suggestion.stderr b/tests/ui/consts/const-result-no-expect-suggestion.stderr new file mode 100644 index 0000000000000..70aa306ae3c88 --- /dev/null +++ b/tests/ui/consts/const-result-no-expect-suggestion.stderr @@ -0,0 +1,24 @@ +error[E0308]: mismatched types + --> $DIR/const-result-no-expect-suggestion.rs:5:19 + | +LL | const TEST: u32 = f(2); + | ^^^^ expected `u32`, found `Result` + | + = note: expected type `u32` + found enum `Result` + +error[E0599]: no method named `len` found for enum `Result` in the current scope + --> $DIR/const-result-no-expect-suggestion.rs:12:26 + | +LL | const TEST2: usize = g().len(); + | ^^^ + | +note: the method `len` exists on the type `String` + --> $SRC_DIR/alloc/src/string.rs:LL:COL +help: there is a method `le` with a similar name, but with different arguments + --> $SRC_DIR/core/src/cmp.rs:LL:COL + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0308, E0599. +For more information about an error, try `rustc --explain E0308`.