-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Wrong type mismatch with cfg_if!
in function body
#12940
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Labels
A-macro
macro expansion
A-ty
type system / type inference / traits / method resolution
C-bug
Category: bug
S-actionable
Someone could pick this issue up and work on it right now
Comments
bors
added a commit
that referenced
this issue
Aug 15, 2022
internal: Add an HIR pretty-printer This improves the "View HIR" command by pretty-printing the HIR to make it much more readable. Example function: ```rust fn newline(&mut self) { match self.buf.chars().rev().skip_while(|ch| *ch == ' ').next() { Some('\n') | None => {} _ => writeln!(self).unwrap(), } } ``` Previous output: ``` HIR expressions in the body of `newline`: Idx::<Expr>(0): Path(Path { type_anchor: None, mod_path: ModPath { kind: Super(0), segments: [] }, generic_args: [] }) Idx::<Expr>(1): Field { expr: Idx::<Expr>(0), name: Name(Text("buf")) } Idx::<Expr>(2): MethodCall { receiver: Idx::<Expr>(1), method_name: Name(Text("chars")), args: [], generic_args: None } Idx::<Expr>(3): MethodCall { receiver: Idx::<Expr>(2), method_name: Name(Text("rev")), args: [], generic_args: None } Idx::<Expr>(4): Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("ch"))] }, generic_args: [None] }) Idx::<Expr>(5): UnaryOp { expr: Idx::<Expr>(4), op: Deref } Idx::<Expr>(6): Literal(Char(' ')) Idx::<Expr>(7): BinaryOp { lhs: Idx::<Expr>(5), rhs: Idx::<Expr>(6), op: Some(CmpOp(Eq { negated: false })) } Idx::<Expr>(8): Closure { args: [Idx::<Pat>(1)], arg_types: [None], ret_type: None, body: Idx::<Expr>(7) } Idx::<Expr>(9): MethodCall { receiver: Idx::<Expr>(3), method_name: Name(Text("skip_while")), args: [Idx::<Expr>(8)], generic_args: None } Idx::<Expr>(10): MethodCall { receiver: Idx::<Expr>(9), method_name: Name(Text("next")), args: [], generic_args: None } Idx::<Expr>(11): Literal(Char('\n')) Idx::<Expr>(12): Block { id: BlockId(37), statements: [], tail: None, label: None } Idx::<Expr>(13): Path(Path { type_anchor: None, mod_path: ModPath { kind: Super(0), segments: [] }, generic_args: [] }) Idx::<Expr>(14): Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("std")), Name(Text("fmt")), Name(Text("Arguments")), Name(Text("new_v1"))] }, generic_args: [None, None, None, None] }) Idx::<Expr>(15): Array(ElementList { elements: [], is_assignee_expr: false }) Idx::<Expr>(16): Ref { expr: Idx::<Expr>(15), rawness: Ref, mutability: Shared } Idx::<Expr>(17): Array(ElementList { elements: [], is_assignee_expr: false }) Idx::<Expr>(18): Ref { expr: Idx::<Expr>(17), rawness: Ref, mutability: Shared } Idx::<Expr>(19): Call { callee: Idx::<Expr>(14), args: [Idx::<Expr>(16), Idx::<Expr>(18)], is_assignee_expr: false } Idx::<Expr>(20): MethodCall { receiver: Idx::<Expr>(13), method_name: Name(Text("write_fmt")), args: [Idx::<Expr>(19)], generic_args: None } Idx::<Expr>(21): MacroStmts { statements: [], tail: Some(Idx::<Expr>(20)) } Idx::<Expr>(22): MethodCall { receiver: Idx::<Expr>(21), method_name: Name(Text("unwrap")), args: [], generic_args: None } Idx::<Expr>(23): Match { expr: Idx::<Expr>(10), arms: [MatchArm { pat: Idx::<Pat>(5), guard: None, expr: Idx::<Expr>(12) }, MatchArm { pat: Idx::<Pat>(6), guard: None, expr: Idx::<Expr>(22) }] } Idx::<Expr>(24): Block { id: BlockId(36), statements: [], tail: Some(Idx::<Expr>(23)), label: None } ``` Output after this PR: ```rust fn newline(…) { match self.buf.chars().rev().skip_while( |ch| (*ch) == (' '), ).next() { Some('\n') | None => {}, _ => { // macro statements self.write_fmt( std::fmt::Arguments::new_v1( &[], &[], ), ) }.unwrap(), } } ``` It also works for consts and statics now. This should make debugging HIR-lowering related issues like #12940 much easier.
Reduced to: macro_rules! m2 {
($($t:tt)*) => {$($t)*};
}
pub fn macrostmts() -> u8 {
m2! { 0 }
m2! {}
} The HIR looks like this:
so it seems that an empty |
Might've regressed in #12668 |
MemoryUsage::now()
cfg_if!
in function body
bors
added a commit
that referenced
this issue
Aug 15, 2022
…ty-macro, r=jonas-schievink fix: Fix incorrect type mismatch with `cfg_if!` and other macros in expression position Fixes #12940 This is a bit of a hack, ideally `MacroStmts` would not exist at all after HIR lowering, but that requires changing how the lowering code works.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Labels
A-macro
macro expansion
A-ty
type system / type inference / traits / method resolution
C-bug
Category: bug
S-actionable
Someone could pick this issue up and work on it right now
This code reports an incorrect "expected
MemoryUsage
, found()
" type mismatch error:rust-analyzer/crates/profile/src/memory_usage.rs
Lines 28 to 55 in 0fe3bcf
Might be due to incorrect handling of macros in block tail position.
The text was updated successfully, but these errors were encountered: