Don't suggest unwrap for Result in const

This commit is contained in:
lapla 2025-12-01 09:32:06 +09:00
parent 80d8f292d8
commit 97f93df9c7
No known key found for this signature in database
GPG key ID: B39C71D9F127FF9F
4 changed files with 59 additions and 16 deletions

View file

@ -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;
}

View file

@ -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(),

View file

@ -0,0 +1,15 @@
const fn f(value: u32) -> Result<u32, ()> {
Ok(value)
}
const TEST: u32 = f(2);
//~^ ERROR: mismatched types
const fn g() -> Result<String, ()> {
Ok(String::new())
}
const TEST2: usize = g().len();
//~^ ERROR: no method named `len` found for enum `Result<T, E>`
fn main() {}

View file

@ -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<u32, ()>`
|
= note: expected type `u32`
found enum `Result<u32, ()>`
error[E0599]: no method named `len` found for enum `Result<T, E>` 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`.