Skip to content

Commit 15d2667

Browse files
authored
Unrolled build for #149344
Rollup merge of #149344 - lapla-cogito:const_unwrap_sugg, r=Kivooeo Don't suggest unwrap for Result in const close #149316 Regarding `const fn` that returns `Result`, we should avoid suggesting unwrapping. The original issue reported cases where types didn't match, but in practice, such suggestions may also appear when methods are not found, so this PR includes a fix for that case as well.
2 parents 2fb8053 + 97f93df commit 15d2667

File tree

4 files changed

+59
-16
lines changed

4 files changed

+59
-16
lines changed

compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2106,14 +2106,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
21062106
)),
21072107
);
21082108

2109-
let (article, kind, variant, sugg_operator) =
2110-
if self.tcx.is_diagnostic_item(sym::Result, adt.did()) {
2111-
("a", "Result", "Err", ret_ty_matches(sym::Result))
2112-
} else if self.tcx.is_diagnostic_item(sym::Option, adt.did()) {
2113-
("an", "Option", "None", ret_ty_matches(sym::Option))
2114-
} else {
2115-
return false;
2116-
};
2109+
let (article, kind, variant, sugg_operator) = if self.tcx.is_diagnostic_item(sym::Result, adt.did())
2110+
// Do not suggest `.expect()` in const context where it's not available. rust-lang/rust#149316
2111+
&& !self.tcx.hir_is_inside_const_context(expr.hir_id)
2112+
{
2113+
("a", "Result", "Err", ret_ty_matches(sym::Result))
2114+
} else if self.tcx.is_diagnostic_item(sym::Option, adt.did()) {
2115+
("an", "Option", "None", ret_ty_matches(sym::Option))
2116+
} else {
2117+
return false;
2118+
};
21172119
if is_ctor || !self.may_coerce(args.type_at(0), expected) {
21182120
return false;
21192121
}

compiler/rustc_hir_typeck/src/method/suggest.rs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3041,14 +3041,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
30413041
tcx.def_span(pick.item.def_id),
30423042
format!("the method `{item_name}` exists on the type `{self_ty}`"),
30433043
);
3044-
let (article, kind, variant, question) =
3045-
if tcx.is_diagnostic_item(sym::Result, kind.did()) {
3046-
("a", "Result", "Err", ret_ty_matches(sym::Result))
3047-
} else if tcx.is_diagnostic_item(sym::Option, kind.did()) {
3048-
("an", "Option", "None", ret_ty_matches(sym::Option))
3049-
} else {
3050-
return;
3051-
};
3044+
let (article, kind, variant, question) = if tcx.is_diagnostic_item(sym::Result, kind.did())
3045+
// Do not suggest `.expect()` in const context where it's not available. rust-lang/rust#149316
3046+
&& !tcx.hir_is_inside_const_context(expr.hir_id)
3047+
{
3048+
("a", "Result", "Err", ret_ty_matches(sym::Result))
3049+
} else if tcx.is_diagnostic_item(sym::Option, kind.did()) {
3050+
("an", "Option", "None", ret_ty_matches(sym::Option))
3051+
} else {
3052+
return;
3053+
};
30523054
if question {
30533055
err.span_suggestion_verbose(
30543056
expr.span.shrink_to_hi(),
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
const fn f(value: u32) -> Result<u32, ()> {
2+
Ok(value)
3+
}
4+
5+
const TEST: u32 = f(2);
6+
//~^ ERROR: mismatched types
7+
8+
const fn g() -> Result<String, ()> {
9+
Ok(String::new())
10+
}
11+
12+
const TEST2: usize = g().len();
13+
//~^ ERROR: no method named `len` found for enum `Result<T, E>`
14+
15+
fn main() {}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/const-result-no-expect-suggestion.rs:5:19
3+
|
4+
LL | const TEST: u32 = f(2);
5+
| ^^^^ expected `u32`, found `Result<u32, ()>`
6+
|
7+
= note: expected type `u32`
8+
found enum `Result<u32, ()>`
9+
10+
error[E0599]: no method named `len` found for enum `Result<T, E>` in the current scope
11+
--> $DIR/const-result-no-expect-suggestion.rs:12:26
12+
|
13+
LL | const TEST2: usize = g().len();
14+
| ^^^
15+
|
16+
note: the method `len` exists on the type `String`
17+
--> $SRC_DIR/alloc/src/string.rs:LL:COL
18+
help: there is a method `le` with a similar name, but with different arguments
19+
--> $SRC_DIR/core/src/cmp.rs:LL:COL
20+
21+
error: aborting due to 2 previous errors
22+
23+
Some errors have detailed explanations: E0308, E0599.
24+
For more information about an error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)