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

+22-8
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

+2
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

+1
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

+1-1
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

+2-2
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

+2-2
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

+8-8
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

-2
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

+5-5
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

+1-1
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
};

tests/ui/issues/issue-51632-try-desugar-incompatible-types.stderr

-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
error[E0308]: `?` operator has incompatible types
22
--> $DIR/issue-51632-try-desugar-incompatible-types.rs:8:5
33
|
4-
LL | fn forbidden_narratives() -> Result<isize, ()> {
5-
| ----------------- expected `Result<isize, ()>` because of return type
64
LL | missing_discourses()?
75
| ^^^^^^^^^^^^^^^^^^^^^ expected `Result<isize, ()>`, found `isize`
86
|

tests/ui/label/label_break_value_desugared_break.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@
55
fn main() {
66
let _: Result<(), ()> = try {
77
'foo: {
8-
Err(())?;
8+
Err::<(), _>(())?;
99
break 'foo;
1010
}
1111
};
1212

1313
'foo: {
1414
let _: Result<(), ()> = try {
15-
Err(())?;
15+
Err::<(), _>(())?;
1616
break 'foo;
1717
};
1818
}

tests/ui/parser/try-with-nonterminal-block.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ macro_rules! create_try {
1111

1212
fn main() {
1313
let x: Option<&str> = create_try! {{
14-
None?;
14+
None::<()>?;
1515
"Hello world"
1616
}};
1717

tests/ui/suggestions/remove-question-symbol-with-paren.stderr

-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
error[E0308]: `?` operator has incompatible types
22
--> $DIR/remove-question-symbol-with-paren.rs:5:6
33
|
4-
LL | fn foo() -> Option<()> {
5-
| ---------- expected `Option<()>` because of return type
6-
LL | let x = Some(());
74
LL | (x?)
85
| ^^ expected `Option<()>`, found `()`
96
|

tests/ui/suggestions/suggest-box.fixed

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
fn main() {
44
let _x: Box<dyn Fn() -> Result<(), ()>> = Box::new(|| { //~ ERROR mismatched types
5-
Err(())?;
5+
Err::<(), _>(())?;
66
Ok(())
77
});
88
}

tests/ui/suggestions/suggest-box.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
fn main() {
44
let _x: Box<dyn Fn() -> Result<(), ()>> = || { //~ ERROR mismatched types
5-
Err(())?;
5+
Err::<(), _>(())?;
66
Ok(())
77
};
88
}

tests/ui/suggestions/suggest-box.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ LL | let _x: Box<dyn Fn() -> Result<(), ()>> = || {
55
| _____________-------------------------------___^
66
| | |
77
| | expected due to this
8-
LL | | Err(())?;
8+
LL | | Err::<(), _>(())?;
99
LL | | Ok(())
1010
LL | | };
1111
| |_____^ expected `Box<dyn Fn() -> Result<(), ()>>`, found closure
@@ -16,7 +16,7 @@ LL | | };
1616
help: store this in the heap by calling `Box::new`
1717
|
1818
LL ~ let _x: Box<dyn Fn() -> Result<(), ()>> = Box::new(|| {
19-
LL | Err(())?;
19+
LL | Err::<(), _>(())?;
2020
LL | Ok(())
2121
LL ~ });
2222
|

tests/ui/try-block/try-block-bad-lifetime.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ pub fn main() {
1212
// result variable
1313
let result: Result<(), &str> = try {
1414
let my_string = String::from("");
15-
let my_str: & str = & my_string;
15+
let my_str: &str = &my_string;
1616
//~^ ERROR `my_string` does not live long enough
17-
Err(my_str) ?;
18-
Err("") ?;
17+
Err::<(), _>(my_str)?;
18+
Err::<(), _>("")?;
1919
};
2020
do_something_with(result);
2121
}
@@ -25,13 +25,13 @@ pub fn main() {
2525
let mut i = 5;
2626
let k = &mut i;
2727
let mut j: Result<(), &mut i32> = try {
28-
Err(k) ?;
28+
Err::<(), _>(k)?;
2929
i = 10; //~ ERROR cannot assign to `i` because it is borrowed
3030
};
3131
::std::mem::drop(k); //~ ERROR use of moved value: `k`
3232
i = 40; //~ ERROR cannot assign to `i` because it is borrowed
3333

34-
let i_ptr = if let Err(i_ptr) = j { i_ptr } else { panic ! ("") };
34+
let i_ptr = if let Err(i_ptr) = j { i_ptr } else { panic!("") };
3535
*i_ptr = 50;
3636
}
3737
}

tests/ui/try-block/try-block-bad-lifetime.stderr

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
error[E0597]: `my_string` does not live long enough
2-
--> $DIR/try-block-bad-lifetime.rs:15:33
2+
--> $DIR/try-block-bad-lifetime.rs:15:32
33
|
44
LL | let result: Result<(), &str> = try {
55
| ------ borrow later stored here
66
LL | let my_string = String::from("");
77
| --------- binding `my_string` declared here
8-
LL | let my_str: & str = & my_string;
9-
| ^^^^^^^^^^^ borrowed value does not live long enough
8+
LL | let my_str: &str = &my_string;
9+
| ^^^^^^^^^^ borrowed value does not live long enough
1010
...
1111
LL | };
1212
| - `my_string` dropped here while still borrowed
@@ -29,8 +29,8 @@ error[E0382]: use of moved value: `k`
2929
LL | let k = &mut i;
3030
| - move occurs because `k` has type `&mut i32`, which does not implement the `Copy` trait
3131
LL | let mut j: Result<(), &mut i32> = try {
32-
LL | Err(k) ?;
33-
| - value moved here
32+
LL | Err::<(), _>(k)?;
33+
| - value moved here
3434
...
3535
LL | ::std::mem::drop(k);
3636
| ^ value used here after move
@@ -44,7 +44,7 @@ LL | let k = &mut i;
4444
LL | i = 40;
4545
| ^^^^^^ `i` is assigned to here but it was already borrowed
4646
LL |
47-
LL | let i_ptr = if let Err(i_ptr) = j { i_ptr } else { panic ! ("") };
47+
LL | let i_ptr = if let Err(i_ptr) = j { i_ptr } else { panic!("") };
4848
| - borrow later used here
4949

5050
error: aborting due to 4 previous errors

0 commit comments

Comments
 (0)