Skip to content

Commit de6f1b8

Browse files
committed
Do not consider using a semicolon inside of a different-crate macro
Fixes #81943
1 parent 0196107 commit de6f1b8

File tree

5 files changed

+83
-2
lines changed

5 files changed

+83
-2
lines changed

compiler/rustc_typeck/src/check/coercion.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ use rustc_hir as hir;
4242
use rustc_hir::def_id::DefId;
4343
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
4444
use rustc_infer::infer::{Coercion, InferOk, InferResult};
45+
use rustc_middle::lint::in_external_macro;
4546
use rustc_middle::ty::adjustment::{
4647
Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, PointerCast,
4748
};
@@ -1448,7 +1449,12 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
14481449
expected.is_unit(),
14491450
pointing_at_return_type,
14501451
) {
1451-
if cond_expr.span.desugaring_kind().is_none() {
1452+
// If the block is from an external macro, then do not suggest
1453+
// adding a semicolon, because there's nowhere to put it.
1454+
// See issue #81943.
1455+
if cond_expr.span.desugaring_kind().is_none()
1456+
&& !in_external_macro(fcx.tcx.sess, cond_expr.span)
1457+
{
14521458
err.span_label(cond_expr.span, "expected this to be `()`");
14531459
if expr.can_have_side_effects() {
14541460
fcx.suggest_semicolon_at_end(cond_expr.span, &mut err);

compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use rustc_hir::def::{CtorOf, DefKind};
1010
use rustc_hir::lang_items::LangItem;
1111
use rustc_hir::{ExprKind, ItemKind, Node};
1212
use rustc_infer::infer;
13+
use rustc_middle::lint::in_external_macro;
1314
use rustc_middle::ty::{self, Ty};
1415
use rustc_span::symbol::kw;
1516

@@ -44,7 +45,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
4445
blk_id: hir::HirId,
4546
) -> bool {
4647
let expr = expr.peel_drop_temps();
47-
if expr.can_have_side_effects() {
48+
// If the expression is from an external macro, then do not suggest
49+
// adding a semicolon, because there's nowhere to put it.
50+
// See issue #81943.
51+
if expr.can_have_side_effects() && !in_external_macro(self.tcx.sess, cause_span) {
4852
self.suggest_missing_semicolon(err, expr, expected, cause_span);
4953
}
5054
let mut pointing_at_return_type = false;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
pub fn g(t: i32) -> i32 { t }
2+
// This function imitates `dbg!` so that future changes
3+
// to its macro definition won't make this test a dud.
4+
#[macro_export]
5+
macro_rules! d {
6+
($e:expr) => { match $e { x => { $crate::g(x) } } }
7+
}

src/test/ui/typeck/issue-81943.rs

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// aux-build:issue-81943-lib.rs
2+
extern crate issue_81943_lib as lib;
3+
4+
fn f<F: Fn(i32)>(f: F) { f(0); }
5+
fn g(t: i32) -> i32 { t }
6+
fn main() {
7+
f(|x| lib::d!(x)); //~ERROR
8+
f(|x| match x { tmp => { g(tmp) } }); //~ERROR
9+
macro_rules! d {
10+
($e:expr) => { match $e { x => { g(x) } } } //~ERROR
11+
}
12+
f(|x| d!(x));
13+
}

src/test/ui/typeck/issue-81943.stderr

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/issue-81943.rs:7:9
3+
|
4+
LL | f(|x| lib::d!(x));
5+
| ^^^^^^^^^^ expected `()`, found `i32`
6+
|
7+
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
8+
9+
error[E0308]: mismatched types
10+
--> $DIR/issue-81943.rs:8:28
11+
|
12+
LL | f(|x| match x { tmp => { g(tmp) } });
13+
| -------------------^^^^^^----
14+
| | |
15+
| | expected `()`, found `i32`
16+
| expected this to be `()`
17+
|
18+
help: consider using a semicolon here
19+
|
20+
LL | f(|x| match x { tmp => { g(tmp); } });
21+
| ^
22+
help: consider using a semicolon here
23+
|
24+
LL | f(|x| match x { tmp => { g(tmp) } };);
25+
| ^
26+
27+
error[E0308]: mismatched types
28+
--> $DIR/issue-81943.rs:10:38
29+
|
30+
LL | ($e:expr) => { match $e { x => { g(x) } } }
31+
| ------------------^^^^----
32+
| | |
33+
| | expected `()`, found `i32`
34+
| expected this to be `()`
35+
LL | }
36+
LL | f(|x| d!(x));
37+
| ----- in this macro invocation
38+
|
39+
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
40+
help: consider using a semicolon here
41+
|
42+
LL | ($e:expr) => { match $e { x => { g(x); } } }
43+
| ^
44+
help: consider using a semicolon here
45+
|
46+
LL | ($e:expr) => { match $e { x => { g(x) } }; }
47+
| ^
48+
49+
error: aborting due to 3 previous errors
50+
51+
For more information about this error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)