From 3aac9a37a5ff306eccb63872a7d6f4ef6f90a577 Mon Sep 17 00:00:00 2001 From: beetrees Date: Sun, 6 Apr 2025 02:31:52 +0100 Subject: [PATCH 1/8] Remove LLVM 18 inline ASM span fallback --- compiler/rustc_codegen_llvm/src/back/write.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index bf6138142b649..76d431a497561 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -439,12 +439,9 @@ fn report_inline_asm( let span = if cookie == 0 || matches!(cgcx.lto, Lto::Fat | Lto::Thin) { SpanData::default() } else { - let lo = BytePos::from_u32(cookie as u32); - let hi = BytePos::from_u32((cookie >> 32) as u32); SpanData { - lo, - // LLVM version < 19 silently truncates the cookie to 32 bits in some situations. - hi: if hi.to_u32() != 0 { hi } else { lo }, + lo: BytePos::from_u32(cookie as u32), + hi: BytePos::from_u32((cookie >> 32) as u32), ctxt: SyntaxContext::root(), parent: None, } From cd4453fdbadec9d9a3b0b40a069c63e01ad52ebf Mon Sep 17 00:00:00 2001 From: jackh726 Date: Sat, 5 Apr 2025 18:21:22 +0000 Subject: [PATCH 2/8] Explicitly depend on ena in rustc_type_ir and make the UnifyKey and UnifyValue imports non-nightly --- Cargo.lock | 1 + compiler/rustc_type_ir/Cargo.toml | 1 + compiler/rustc_type_ir/src/data_structures/mod.rs | 1 + compiler/rustc_type_ir/src/ty_kind.rs | 8 +------- 4 files changed, 4 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 96526f7e9e7da..ce8efe631ce61 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4581,6 +4581,7 @@ version = "0.0.0" dependencies = [ "bitflags", "derive-where", + "ena", "indexmap", "rustc-hash 1.1.0", "rustc_ast_ir", diff --git a/compiler/rustc_type_ir/Cargo.toml b/compiler/rustc_type_ir/Cargo.toml index 4adf715792666..83d3d78298e60 100644 --- a/compiler/rustc_type_ir/Cargo.toml +++ b/compiler/rustc_type_ir/Cargo.toml @@ -7,6 +7,7 @@ edition = "2024" # tidy-alphabetical-start bitflags = "2.4.1" derive-where = "1.2.7" +ena = "0.14.3" indexmap = "2.0.0" rustc-hash = "1.1.0" rustc_ast_ir = { path = "../rustc_ast_ir", default-features = false } diff --git a/compiler/rustc_type_ir/src/data_structures/mod.rs b/compiler/rustc_type_ir/src/data_structures/mod.rs index 30c67d10d0e86..a72669cbd189b 100644 --- a/compiler/rustc_type_ir/src/data_structures/mod.rs +++ b/compiler/rustc_type_ir/src/data_structures/mod.rs @@ -1,5 +1,6 @@ use std::hash::BuildHasherDefault; +pub use ena::unify::{NoError, UnifyKey, UnifyValue}; use rustc_hash::FxHasher; pub use rustc_hash::{FxHashMap as HashMap, FxHashSet as HashSet}; diff --git a/compiler/rustc_type_ir/src/ty_kind.rs b/compiler/rustc_type_ir/src/ty_kind.rs index d35b22d517c52..753a72a051ad8 100644 --- a/compiler/rustc_type_ir/src/ty_kind.rs +++ b/compiler/rustc_type_ir/src/ty_kind.rs @@ -6,9 +6,8 @@ use rustc_ast_ir::Mutability; #[cfg(feature = "nightly")] use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; #[cfg(feature = "nightly")] -use rustc_data_structures::unify::{NoError, UnifyKey, UnifyValue}; -#[cfg(feature = "nightly")] use rustc_macros::{Decodable_NoContext, Encodable_NoContext, HashStable_NoContext}; +use rustc_type_ir::data_structures::{NoError, UnifyKey, UnifyValue}; use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic}; use self::TyKind::*; @@ -796,7 +795,6 @@ pub enum InferTy { /// Raw `TyVid` are used as the unification key for `sub_relations`; /// they carry no values. -#[cfg(feature = "nightly")] impl UnifyKey for TyVid { type Value = (); #[inline] @@ -812,7 +810,6 @@ impl UnifyKey for TyVid { } } -#[cfg(feature = "nightly")] impl UnifyValue for IntVarValue { type Error = NoError; @@ -832,7 +829,6 @@ impl UnifyValue for IntVarValue { } } -#[cfg(feature = "nightly")] impl UnifyKey for IntVid { type Value = IntVarValue; #[inline] // make this function eligible for inlining - it is quite hot. @@ -848,7 +844,6 @@ impl UnifyKey for IntVid { } } -#[cfg(feature = "nightly")] impl UnifyValue for FloatVarValue { type Error = NoError; @@ -866,7 +861,6 @@ impl UnifyValue for FloatVarValue { } } -#[cfg(feature = "nightly")] impl UnifyKey for FloatVid { type Value = FloatVarValue; #[inline] From 13bf79cd879023ae4434ed4c6b287159bef32b48 Mon Sep 17 00:00:00 2001 From: HaeNoe Date: Sun, 9 Mar 2025 22:55:07 +0100 Subject: [PATCH 3/8] fix usage of `autodiff` macro with inner functions - fix errors caused by the move of `ast::Item::ident` (see #138740) - move the logic of getting `sig`, `vis`, and `ident` from two seperate `match` statements into one (less repetition especially with the nested `match`) --- compiler/rustc_builtin_macros/src/autodiff.rs | 108 ++++++++++++------ 1 file changed, 76 insertions(+), 32 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/autodiff.rs b/compiler/rustc_builtin_macros/src/autodiff.rs index 7f99f75b2b9df..287f0fdc516b6 100644 --- a/compiler/rustc_builtin_macros/src/autodiff.rs +++ b/compiler/rustc_builtin_macros/src/autodiff.rs @@ -199,27 +199,46 @@ mod llvm_enzyme { return vec![item]; } let dcx = ecx.sess.dcx(); - // first get the annotable item: - let (primal, sig, is_impl): (Ident, FnSig, bool) = match &item { + + // first get information about the annotable item: + let (sig, vis, primal) = match &item { Annotatable::Item(iitem) => { - let (ident, sig) = match &iitem.kind { - ItemKind::Fn(box ast::Fn { ident, sig, .. }) => (ident, sig), + let (sig, ident) = match &iitem.kind { + ItemKind::Fn(box ast::Fn { sig, ident, .. }) => (sig, ident), _ => { dcx.emit_err(errors::AutoDiffInvalidApplication { span: item.span() }); return vec![item]; } }; - (*ident, sig.clone(), false) + (sig.clone(), iitem.vis.clone(), ident.clone()) } Annotatable::AssocItem(assoc_item, Impl { of_trait: false }) => { - let (ident, sig) = match &assoc_item.kind { - ast::AssocItemKind::Fn(box ast::Fn { ident, sig, .. }) => (ident, sig), + let (sig, ident) = match &assoc_item.kind { + ast::AssocItemKind::Fn(box ast::Fn { sig, ident, .. }) => (sig, ident), + _ => { + dcx.emit_err(errors::AutoDiffInvalidApplication { span: item.span() }); + return vec![item]; + } + }; + (sig.clone(), assoc_item.vis.clone(), ident.clone()) + } + Annotatable::Stmt(stmt) => { + let (sig, vis, ident) = match &stmt.kind { + ast::StmtKind::Item(iitem) => match &iitem.kind { + ast::ItemKind::Fn(box ast::Fn { sig, ident, .. }) => { + (sig.clone(), iitem.vis.clone(), ident.clone()) + } + _ => { + dcx.emit_err(errors::AutoDiffInvalidApplication { span: item.span() }); + return vec![item]; + } + }, _ => { dcx.emit_err(errors::AutoDiffInvalidApplication { span: item.span() }); return vec![item]; } }; - (*ident, sig.clone(), true) + (sig, vis, ident) } _ => { dcx.emit_err(errors::AutoDiffInvalidApplication { span: item.span() }); @@ -238,15 +257,6 @@ mod llvm_enzyme { let has_ret = has_ret(&sig.decl.output); let sig_span = ecx.with_call_site_ctxt(sig.span); - let vis = match &item { - Annotatable::Item(iitem) => iitem.vis.clone(), - Annotatable::AssocItem(assoc_item, _) => assoc_item.vis.clone(), - _ => { - dcx.emit_err(errors::AutoDiffInvalidApplication { span: item.span() }); - return vec![item]; - } - }; - // create TokenStream from vec elemtents: // meta_item doesn't have a .tokens field let mut ts: Vec = vec![]; @@ -379,6 +389,22 @@ mod llvm_enzyme { } Annotatable::AssocItem(assoc_item.clone(), i) } + Annotatable::Stmt(ref mut stmt) => { + match stmt.kind { + ast::StmtKind::Item(ref mut iitem) => { + if !iitem.attrs.iter().any(|a| same_attribute(&a.kind, &attr.kind)) { + iitem.attrs.push(attr); + } + if !iitem.attrs.iter().any(|a| same_attribute(&a.kind, &inline_never.kind)) + { + iitem.attrs.push(inline_never.clone()); + } + } + _ => unreachable!("stmt kind checked previously"), + }; + + Annotatable::Stmt(stmt.clone()) + } _ => { unreachable!("annotatable kind checked previously") } @@ -389,22 +415,40 @@ mod llvm_enzyme { delim: rustc_ast::token::Delimiter::Parenthesis, tokens: ts, }); + let d_attr = outer_normal_attr(&rustc_ad_attr, new_id, span); - let d_annotatable = if is_impl { - let assoc_item: AssocItemKind = ast::AssocItemKind::Fn(asdf); - let d_fn = P(ast::AssocItem { - attrs: thin_vec![d_attr, inline_never], - id: ast::DUMMY_NODE_ID, - span, - vis, - kind: assoc_item, - tokens: None, - }); - Annotatable::AssocItem(d_fn, Impl { of_trait: false }) - } else { - let mut d_fn = ecx.item(span, thin_vec![d_attr, inline_never], ItemKind::Fn(asdf)); - d_fn.vis = vis; - Annotatable::Item(d_fn) + let d_annotatable = match &item { + Annotatable::AssocItem(_, _) => { + let assoc_item: AssocItemKind = ast::AssocItemKind::Fn(asdf); + let d_fn = P(ast::AssocItem { + attrs: thin_vec![d_attr, inline_never], + id: ast::DUMMY_NODE_ID, + span, + vis, + kind: assoc_item, + tokens: None, + }); + Annotatable::AssocItem(d_fn, Impl { of_trait: false }) + } + Annotatable::Item(_) => { + let mut d_fn = ecx.item(span, thin_vec![d_attr, inline_never], ItemKind::Fn(asdf)); + d_fn.vis = vis; + + Annotatable::Item(d_fn) + } + Annotatable::Stmt(_) => { + let mut d_fn = ecx.item(span, thin_vec![d_attr, inline_never], ItemKind::Fn(asdf)); + d_fn.vis = vis; + + Annotatable::Stmt(P(ast::Stmt { + id: ast::DUMMY_NODE_ID, + kind: ast::StmtKind::Item(d_fn), + span, + })) + } + _ => { + unreachable!("item kind checked previously") + } }; return vec![orig_annotatable, d_annotatable]; From 72091edcc46601b0fc10c8d71349449d86718d5e Mon Sep 17 00:00:00 2001 From: HaeNoe Date: Sat, 22 Mar 2025 00:26:11 +0100 Subject: [PATCH 4/8] feat: add test to validate autodiff macro expansion --- tests/pretty/autodiff_forward.pp | 15 +++++++++++++++ tests/pretty/autodiff_forward.rs | 8 ++++++++ 2 files changed, 23 insertions(+) diff --git a/tests/pretty/autodiff_forward.pp b/tests/pretty/autodiff_forward.pp index 4b2fb6166ff7e..a62ced56dc41d 100644 --- a/tests/pretty/autodiff_forward.pp +++ b/tests/pretty/autodiff_forward.pp @@ -29,6 +29,8 @@ // Make sure, that we add the None for the default return. + // We want to make sure that we can use the macro for functions defined inside of functions + ::core::panicking::panic("not implemented") } #[rustc_autodiff(Forward, 1, Dual, Const, Dual)] @@ -158,4 +160,17 @@ ::core::hint::black_box((bx_0,)); ::core::hint::black_box(::default()) } +pub fn f9() { + #[rustc_autodiff] + #[inline(never)] + fn inner(x: f32) -> f32 { x * x } + #[rustc_autodiff(Forward, 1, Dual, DualOnly)] + #[inline(never)] + fn d_inner(x: f32, bx_0: f32) -> f32 { + unsafe { asm!("NOP", options(pure, nomem)); }; + ::core::hint::black_box(inner(x)); + ::core::hint::black_box((bx_0,)); + ::core::hint::black_box(::default()) + } +} fn main() {} diff --git a/tests/pretty/autodiff_forward.rs b/tests/pretty/autodiff_forward.rs index a765738c2a815..e61d1ec361723 100644 --- a/tests/pretty/autodiff_forward.rs +++ b/tests/pretty/autodiff_forward.rs @@ -54,4 +54,12 @@ fn f8(x: &f32) -> f32 { unimplemented!() } +// We want to make sure that we can use the macro for functions defined inside of functions +pub fn f9() { + #[autodiff(d_inner, Forward, Dual, DualOnly)] + fn inner(x: f32) -> f32 { + x * x + } +} + fn main() {} From 63e825e52a1961f1270bed5075c52f2c9921ef08 Mon Sep 17 00:00:00 2001 From: HaeNoe Date: Tue, 1 Apr 2025 07:25:04 +0200 Subject: [PATCH 5/8] feat: apply autodiff macro twice to inner function Verify that the expanded `inline` and `rustc_autodiff` macros are not duplicated. --- tests/pretty/autodiff_forward.pp | 10 +++++++++- tests/pretty/autodiff_forward.rs | 3 ++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/tests/pretty/autodiff_forward.pp b/tests/pretty/autodiff_forward.pp index a62ced56dc41d..713b8f541ae0d 100644 --- a/tests/pretty/autodiff_forward.pp +++ b/tests/pretty/autodiff_forward.pp @@ -164,9 +164,17 @@ #[rustc_autodiff] #[inline(never)] fn inner(x: f32) -> f32 { x * x } + #[rustc_autodiff(Forward, 1, Dual, Dual)] + #[inline(never)] + fn d_inner_2(x: f32, bx_0: f32) -> (f32, f32) { + unsafe { asm!("NOP", options(pure, nomem)); }; + ::core::hint::black_box(inner(x)); + ::core::hint::black_box((bx_0,)); + ::core::hint::black_box(<(f32, f32)>::default()) + } #[rustc_autodiff(Forward, 1, Dual, DualOnly)] #[inline(never)] - fn d_inner(x: f32, bx_0: f32) -> f32 { + fn d_inner_1(x: f32, bx_0: f32) -> f32 { unsafe { asm!("NOP", options(pure, nomem)); }; ::core::hint::black_box(inner(x)); ::core::hint::black_box((bx_0,)); diff --git a/tests/pretty/autodiff_forward.rs b/tests/pretty/autodiff_forward.rs index e61d1ec361723..5a0660a08e526 100644 --- a/tests/pretty/autodiff_forward.rs +++ b/tests/pretty/autodiff_forward.rs @@ -56,7 +56,8 @@ fn f8(x: &f32) -> f32 { // We want to make sure that we can use the macro for functions defined inside of functions pub fn f9() { - #[autodiff(d_inner, Forward, Dual, DualOnly)] + #[autodiff(d_inner_1, Forward, Dual, DualOnly)] + #[autodiff(d_inner_2, Forward, Dual, Dual)] fn inner(x: f32) -> f32 { x * x } From bf69443a9f0fa9b44aaec36c1c470ad22a325c2a Mon Sep 17 00:00:00 2001 From: HaeNoe Date: Thu, 3 Apr 2025 22:47:30 +0200 Subject: [PATCH 6/8] refactor: simplify function-info gathering --- compiler/rustc_builtin_macros/src/autodiff.rs | 67 +++++++------------ 1 file changed, 26 insertions(+), 41 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/autodiff.rs b/compiler/rustc_builtin_macros/src/autodiff.rs index 287f0fdc516b6..351413dea493c 100644 --- a/compiler/rustc_builtin_macros/src/autodiff.rs +++ b/compiler/rustc_builtin_macros/src/autodiff.rs @@ -17,7 +17,7 @@ mod llvm_enzyme { use rustc_ast::visit::AssocCtxt::*; use rustc_ast::{ self as ast, AssocItemKind, BindingMode, ExprKind, FnRetTy, FnSig, Generics, ItemKind, - MetaItemInner, PatKind, QSelf, TyKind, + MetaItemInner, PatKind, QSelf, TyKind, Visibility, }; use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_span::{Ident, Span, Symbol, kw, sym}; @@ -72,6 +72,16 @@ mod llvm_enzyme { } } + // Get information about the function the macro is applied to + fn extract_item_info(iitem: &P) -> Option<(Visibility, FnSig, Ident)> { + match &iitem.kind { + ItemKind::Fn(box ast::Fn { sig, ident, .. }) => { + Some((iitem.vis.clone(), sig.clone(), ident.clone())) + } + _ => None, + } + } + pub(crate) fn from_ast( ecx: &mut ExtCtxt<'_>, meta_item: &ThinVec, @@ -201,49 +211,24 @@ mod llvm_enzyme { let dcx = ecx.sess.dcx(); // first get information about the annotable item: - let (sig, vis, primal) = match &item { - Annotatable::Item(iitem) => { - let (sig, ident) = match &iitem.kind { - ItemKind::Fn(box ast::Fn { sig, ident, .. }) => (sig, ident), - _ => { - dcx.emit_err(errors::AutoDiffInvalidApplication { span: item.span() }); - return vec![item]; - } - }; - (sig.clone(), iitem.vis.clone(), ident.clone()) - } + let Some((vis, sig, primal)) = (match &item { + Annotatable::Item(iitem) => extract_item_info(iitem), + Annotatable::Stmt(stmt) => match &stmt.kind { + ast::StmtKind::Item(iitem) => extract_item_info(iitem), + _ => None, + }, Annotatable::AssocItem(assoc_item, Impl { of_trait: false }) => { - let (sig, ident) = match &assoc_item.kind { - ast::AssocItemKind::Fn(box ast::Fn { sig, ident, .. }) => (sig, ident), - _ => { - dcx.emit_err(errors::AutoDiffInvalidApplication { span: item.span() }); - return vec![item]; - } - }; - (sig.clone(), assoc_item.vis.clone(), ident.clone()) - } - Annotatable::Stmt(stmt) => { - let (sig, vis, ident) = match &stmt.kind { - ast::StmtKind::Item(iitem) => match &iitem.kind { - ast::ItemKind::Fn(box ast::Fn { sig, ident, .. }) => { - (sig.clone(), iitem.vis.clone(), ident.clone()) - } - _ => { - dcx.emit_err(errors::AutoDiffInvalidApplication { span: item.span() }); - return vec![item]; - } - }, - _ => { - dcx.emit_err(errors::AutoDiffInvalidApplication { span: item.span() }); - return vec![item]; + match &assoc_item.kind { + ast::AssocItemKind::Fn(box ast::Fn { sig, ident, .. }) => { + Some((assoc_item.vis.clone(), sig.clone(), ident.clone())) } - }; - (sig, vis, ident) - } - _ => { - dcx.emit_err(errors::AutoDiffInvalidApplication { span: item.span() }); - return vec![item]; + _ => None, + } } + _ => None, + }) else { + dcx.emit_err(errors::AutoDiffInvalidApplication { span: item.span() }); + return vec![item]; }; let meta_item_vec: ThinVec = match meta_item.kind { From ee07e3f83f5c2e87c1ce19f2472bc7c622ecebcf Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Sun, 6 Apr 2025 14:45:48 -0500 Subject: [PATCH 7/8] doc(style): add let-chain rules --- src/doc/style-guide/src/expressions.md | 78 ++++++++++++++++++++++++-- 1 file changed, 72 insertions(+), 6 deletions(-) diff --git a/src/doc/style-guide/src/expressions.md b/src/doc/style-guide/src/expressions.md index 12037b5992ec0..031e59d86e1da 100644 --- a/src/doc/style-guide/src/expressions.md +++ b/src/doc/style-guide/src/expressions.md @@ -521,8 +521,11 @@ self.pre_comment.as_ref().map_or( ## Control flow expressions -This section covers `if`, `if let`, `loop`, `while`, `while let`, and `for` -expressions. +This section covers `for` and `loop` expressions, as well as `if` and `while` +expressions with their sub-expression variants. This includes those with a +single `let` sub-expression (i.e. `if let` and `while let`) +as well as "let-chains": those with one or more `let` sub-expressions and +one or more bool-type conditions (i.e. `if a && let Some(b) = c`). Put the keyword, any initial clauses, and the opening brace of the block all on a single line, if they fit. Apply the usual rules for [block @@ -548,10 +551,11 @@ if let ... { } ``` -If the control line needs to be broken, prefer to break before the `=` in `* -let` expressions and before `in` in a `for` expression; block-indent the -following line. If the control line is broken for any reason, put the opening -brace on its own line, not indented. Examples: +If the control line needs to be broken, then prefer breaking after the `=` for any +`let` sub-expression in an `if` or `while` expression that does not fit, +and before `in` in a `for` expression; the following line should be block indented. +If the control line is broken for any reason, then the opening brace should be on its +own line and not indented. Examples: ```rust while let Some(foo) @@ -572,6 +576,68 @@ if a_long_expression { ... } + +if let Some(a) = b + && another_long_expression + && a_third_long_expression +{ + // ... +} + +if let Some(relatively_long_thing) + = a_long_expression + && another_long_expression + && a_third_long_expression +{ + // ... +} + +if some_expr + && another_long_expression + && let Some(relatively_long_thing) = + a_long_long_long_long_long_long_really_reallllllllllyyyyyyy_long_expression + && a_third_long_expression +{ + // ... +} +``` + +A let-chain control line is allowed to be formatted on a single line provided +it only consists of two clauses, with the first, left-hand side operand being a literal or an +`ident` (which can optionally be preceded by any number of unary prefix operators), +and the second, right-hand side operand being a single-line `let` clause. Otherwise, +the control line must be broken and formatted according to the above rules. For example: + +```rust +if a && let Some(b) = foo() { + // ... +} + +if true && let Some(b) = foo() { + // ... +} + +let operator = if !from_hir_call && let Some(p) = parent { + // ... +}; + +if let Some(b) = foo() + && a +{ + // .. +} + +if foo() + && let Some(b) = bar +{ + // ... +} + +if gen_pos != GenericArgPosition::Type + && let Some(b) = gen_args.bindings.first() +{ + // .. +} ``` Where the initial clause spans multiple lines and ends with one or more closing From c51c448fae5123b0dfb56fcd7c69251f85f2a73b Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 7 Apr 2025 05:07:02 +0000 Subject: [PATCH 8/8] More trivial tweaks --- compiler/rustc_hir_analysis/src/check/region.rs | 11 ++++------- compiler/rustc_hir_typeck/src/demand.rs | 5 +---- compiler/rustc_passes/src/liveness.rs | 2 +- 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/region.rs b/compiler/rustc_hir_analysis/src/check/region.rs index cf66ab708bb9e..6b504c0d67257 100644 --- a/compiler/rustc_hir_analysis/src/check/region.rs +++ b/compiler/rustc_hir_analysis/src/check/region.rs @@ -446,14 +446,11 @@ fn resolve_expr<'tcx>( // Mark this expr's scope and all parent scopes as containing `yield`. let mut scope = Scope { local_id: expr.hir_id.local_id, data: ScopeData::Node }; loop { - let span = match expr.kind { - hir::ExprKind::Yield(expr, hir::YieldSource::Await { .. }) => { - expr.span.shrink_to_hi().to(expr.span) - } - _ => expr.span, + let data = YieldData { + span: expr.span, + expr_and_pat_count: visitor.expr_and_pat_count, + source: *source, }; - let data = - YieldData { span, expr_and_pat_count: visitor.expr_and_pat_count, source: *source }; match visitor.scope_tree.yield_in_scope.get_mut(&scope) { Some(yields) => yields.push(data), None => { diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index b845e2190ef02..fec459954107e 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -865,10 +865,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // `&'name Ty` -> `&'name mut Ty` or `&Ty` -> `&mut Ty` vec![( ty_ref.1.ty.span.shrink_to_lo(), - format!( - "{}mut ", - if ty_ref.0.ident.span.lo() == ty_ref.0.ident.span.hi() { "" } else { " " }, - ), + format!("{}mut ", if ty_ref.0.ident.span.is_empty() { "" } else { " " },), )] }; sugg.extend([ diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs index ed70d9ee91f5a..d79e9263f6131 100644 --- a/compiler/rustc_passes/src/liveness.rs +++ b/compiler/rustc_passes/src/liveness.rs @@ -1655,7 +1655,7 @@ impl<'tcx> Liveness<'_, 'tcx> { // `&'name Ty` -> `&'name mut Ty` or `&Ty` -> `&mut Ty` Some(mut_ty.ty.span.shrink_to_lo()) }; - let pre = if lt.ident.span.lo() == lt.ident.span.hi() { "" } else { " " }; + let pre = if lt.ident.span.is_empty() { "" } else { " " }; Some(errors::UnusedAssignSuggestion { ty_span, pre,