Skip to content

Commit b478d2b

Browse files
committed
Stop skewing inference in ?'s desugaring
1 parent 92130a3 commit b478d2b

22 files changed

+80
-63
lines changed

compiler/rustc_ast_lowering/src/expr.rs

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1758,9 +1758,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
17581758
/// ControlFlow::Break(residual) =>
17591759
/// #[allow(unreachable_code)]
17601760
/// // If there is an enclosing `try {...}`:
1761-
/// break 'catch_target Try::from_residual(residual),
1761+
/// absurd(break 'catch_target Try::from_residual(residual)),
17621762
/// // Otherwise:
1763-
/// return Try::from_residual(residual),
1763+
/// absurd(return Try::from_residual(residual)),
17641764
/// }
17651765
/// ```
17661766
fn lower_expr_try(&mut self, span: Span, sub_expr: &Expr) -> hir::ExprKind<'hir> {
@@ -1769,6 +1769,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
17691769
span,
17701770
Some(self.allow_try_trait.clone()),
17711771
);
1772+
1773+
let absurd_allowed_span = self.mark_span_with_reason(
1774+
DesugaringKind::QuestionMark,
1775+
span,
1776+
Some(self.allow_convert_absurd.clone()),
1777+
);
1778+
17721779
let try_span = self.tcx.sess.source_map().end_point(span);
17731780
let try_span = self.mark_span_with_reason(
17741781
DesugaringKind::QuestionMark,
@@ -1810,7 +1817,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
18101817

18111818
// `ControlFlow::Break(residual) =>
18121819
// #[allow(unreachable_code)]
1813-
// return Try::from_residual(residual),`
1820+
// absurd(return Try::from_residual(residual)),`
18141821
let break_arm = {
18151822
let residual_ident = Ident::with_dummy_span(sym::residual);
18161823
let (residual_local, residual_local_nid) = self.pat_ident(try_span, residual_ident);
@@ -1823,20 +1830,27 @@ impl<'hir> LoweringContext<'_, 'hir> {
18231830
);
18241831
let ret_expr = if let Some(catch_node) = self.catch_scope {
18251832
let target_id = Ok(self.lower_node_id(catch_node));
1826-
self.arena.alloc(self.expr(
1833+
self.expr(
18271834
try_span,
18281835
hir::ExprKind::Break(
18291836
hir::Destination { label: None, target_id },
18301837
Some(from_residual_expr),
18311838
),
1832-
))
1839+
)
18331840
} else {
1834-
self.arena.alloc(self.expr(try_span, hir::ExprKind::Ret(Some(from_residual_expr))))
1841+
self.expr(try_span, hir::ExprKind::Ret(Some(from_residual_expr)))
18351842
};
1836-
self.lower_attrs(ret_expr.hir_id, &attrs);
1843+
1844+
let absurd_expr = self.expr_call_lang_item_fn(
1845+
absurd_allowed_span,
1846+
hir::LangItem::Absurd,
1847+
arena_vec![self; ret_expr],
1848+
);
1849+
1850+
self.lower_attrs(absurd_expr.hir_id, &attrs);
18371851

18381852
let break_pat = self.pat_cf_break(try_span, residual_local);
1839-
self.arm(break_pat, ret_expr)
1853+
self.arm(break_pat, absurd_expr)
18401854
};
18411855

18421856
hir::ExprKind::Match(

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ struct LoweringContext<'a, 'hir> {
130130
node_id_to_local_id: NodeMap<hir::ItemLocalId>,
131131

132132
allow_try_trait: Lrc<[Symbol]>,
133+
allow_convert_absurd: Lrc<[Symbol]>,
133134
allow_gen_future: Lrc<[Symbol]>,
134135
allow_async_iterator: Lrc<[Symbol]>,
135136
allow_for_await: Lrc<[Symbol]>,
@@ -173,6 +174,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
173174
impl_trait_defs: Vec::new(),
174175
impl_trait_bounds: Vec::new(),
175176
allow_try_trait: [sym::try_trait_v2, sym::yeet_desugar_details].into(),
177+
allow_convert_absurd: [sym::convert_absurd].into(),
176178
allow_gen_future: if tcx.features().async_fn_track_caller {
177179
[sym::gen_future, sym::closure_track_caller].into()
178180
} else {

compiler/rustc_span/src/symbol.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -602,6 +602,7 @@ symbols! {
602602
const_try,
603603
constant,
604604
constructor,
605+
convert_absurd,
605606
convert_identity,
606607
copy,
607608
copy_closures,

tests/ui/async-await/issue-67765-async-diagnostic.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ async fn func<'a>() -> Result<(), &'a str> {
1010

1111
let b = &s[..];
1212

13-
Err(b)?; //~ ERROR cannot return value referencing local variable `s`
13+
Err::<(), _>(b)?; //~ ERROR cannot return value referencing local variable `s`
1414

1515
Ok(())
1616
}

tests/ui/async-await/issue-67765-async-diagnostic.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ error[E0515]: cannot return value referencing local variable `s`
44
LL | let b = &s[..];
55
| - `s` is borrowed here
66
LL |
7-
LL | Err(b)?;
8-
| ^^^^^^^ returns a value referencing data owned by the current function
7+
LL | Err::<(), _>(b)?;
8+
| ^^^^^^^^^^^^^^^^ returns a value referencing data owned by the current function
99

1010
error: aborting due to 1 previous error
1111

tests/ui/consts/try-operator.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,15 @@
77

88
fn main() {
99
const fn result() -> Result<bool, ()> {
10-
Err(())?;
10+
Err::<(), _>(())?;
1111
Ok(true)
1212
}
1313

1414
const FOO: Result<bool, ()> = result();
1515
assert_eq!(Err(()), FOO);
1616

1717
const fn option() -> Option<()> {
18-
None?;
18+
None::<()>?;
1919
Some(())
2020
}
2121
const BAR: Option<()> = option();

tests/ui/consts/try-operator.stderr

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ LL | #![feature(const_convert)]
77
error[E0015]: `?` cannot determine the branch of `Result<(), ()>` in constant functions
88
--> $DIR/try-operator.rs:10:9
99
|
10-
LL | Err(())?;
11-
| ^^^^^^^^
10+
LL | Err::<(), _>(())?;
11+
| ^^^^^^^^^^^^^^^^^
1212
|
1313
note: impl defined here, but it is not `const`
1414
--> $SRC_DIR/core/src/result.rs:LL:COL
@@ -21,8 +21,8 @@ LL + #![feature(effects)]
2121
error[E0015]: `?` cannot convert from residual of `Result<bool, ()>` in constant functions
2222
--> $DIR/try-operator.rs:10:9
2323
|
24-
LL | Err(())?;
25-
| ^^^^^^^^
24+
LL | Err::<(), _>(())?;
25+
| ^^^^^^^^^^^^^^^^^
2626
|
2727
note: impl defined here, but it is not `const`
2828
--> $SRC_DIR/core/src/result.rs:LL:COL
@@ -35,8 +35,8 @@ LL + #![feature(effects)]
3535
error[E0015]: `?` cannot determine the branch of `Option<()>` in constant functions
3636
--> $DIR/try-operator.rs:18:9
3737
|
38-
LL | None?;
39-
| ^^^^^
38+
LL | None::<()>?;
39+
| ^^^^^^^^^^^
4040
|
4141
note: impl defined here, but it is not `const`
4242
--> $SRC_DIR/core/src/option.rs:LL:COL
@@ -49,8 +49,8 @@ LL + #![feature(effects)]
4949
error[E0015]: `?` cannot convert from residual of `Option<()>` in constant functions
5050
--> $DIR/try-operator.rs:18:9
5151
|
52-
LL | None?;
53-
| ^^^^^
52+
LL | None::<()>?;
53+
| ^^^^^^^^^^^
5454
|
5555
note: impl defined here, but it is not `const`
5656
--> $SRC_DIR/core/src/option.rs:LL:COL

tests/ui/did_you_mean/compatible-variants.stderr

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,6 @@ LL + Some(())
6161
error[E0308]: `?` operator has incompatible types
6262
--> $DIR/compatible-variants.rs:35:5
6363
|
64-
LL | fn d() -> Option<()> {
65-
| ---------- expected `Option<()>` because of return type
6664
LL | c()?
6765
| ^^^^ expected `Option<()>`, found `()`
6866
|

tests/ui/impl-trait/cross-return-site-inference.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,34 +2,34 @@
22

33
fn foo(b: bool) -> impl std::fmt::Debug {
44
if b {
5-
return vec![42]
5+
return vec![42];
66
}
77
[].into_iter().collect()
88
}
99

1010
fn bar(b: bool) -> impl std::fmt::Debug {
1111
if b {
12-
return [].into_iter().collect()
12+
return [].into_iter().collect();
1313
}
1414
vec![42]
1515
}
1616

1717
fn bak(b: bool) -> impl std::fmt::Debug {
1818
if b {
19-
return std::iter::empty().collect()
19+
return std::iter::empty().collect();
2020
}
2121
vec![42]
2222
}
2323

2424
fn baa(b: bool) -> impl std::fmt::Debug {
2525
if b {
26-
return [42].into_iter().collect()
26+
return [42].into_iter().collect();
2727
}
2828
vec![]
2929
}
3030

3131
fn muh() -> Result<(), impl std::fmt::Debug> {
32-
Err("whoops")?;
32+
Err::<(), _>("whoops")?;
3333
Ok(())
3434
//~^ ERROR type annotations needed
3535
}

tests/ui/inference/cannot-infer-closure.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
fn main() {
22
let x = |a: (), b: ()| {
3-
Err(a)?;
3+
Err::<(), _>(a)?;
44
Ok(b)
55
//~^ ERROR type annotations needed
66
};

0 commit comments

Comments
 (0)