Skip to content

Rollup of 5 pull requests #139473

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

Merged
merged 13 commits into from
Apr 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4589,6 +4589,7 @@ version = "0.0.0"
dependencies = [
"bitflags",
"derive-where",
"ena",
"indexmap",
"rustc-hash 1.1.0",
"rustc_ast_ir",
Expand Down
125 changes: 77 additions & 48 deletions compiler/rustc_builtin_macros/src/autodiff.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -72,6 +72,16 @@ mod llvm_enzyme {
}
}

// Get information about the function the macro is applied to
fn extract_item_info(iitem: &P<ast::Item>) -> 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<MetaItemInner>,
Expand Down Expand Up @@ -199,32 +209,26 @@ 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 {
Annotatable::Item(iitem) => {
let (ident, sig) = match &iitem.kind {
ItemKind::Fn(box ast::Fn { ident, sig, .. }) => (ident, sig),
_ => {
dcx.emit_err(errors::AutoDiffInvalidApplication { span: item.span() });
return vec![item];
}
};
(*ident, sig.clone(), false)
}

// first get information about the annotable item:
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 (ident, sig) = match &assoc_item.kind {
ast::AssocItemKind::Fn(box ast::Fn { ident, sig, .. }) => (ident, sig),
_ => {
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()))
}
};
(*ident, sig.clone(), true)
}
_ => {
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<MetaItemInner> = match meta_item.kind {
Expand All @@ -238,15 +242,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<TokenTree> = vec![];
Expand Down Expand Up @@ -379,6 +374,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")
}
Expand All @@ -389,22 +400,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];
Expand Down
7 changes: 2 additions & 5 deletions compiler/rustc_codegen_llvm/src/back/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}
Expand Down
11 changes: 4 additions & 7 deletions compiler/rustc_hir_analysis/src/check/region.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 => {
Expand Down
5 changes: 1 addition & 4 deletions compiler/rustc_hir_typeck/src/demand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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([
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_passes/src/liveness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_type_ir/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_type_ir/src/data_structures/mod.rs
Original file line number Diff line number Diff line change
@@ -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};

Expand Down
8 changes: 1 addition & 7 deletions compiler/rustc_type_ir/src/ty_kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::*;
Expand Down Expand Up @@ -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]
Expand All @@ -812,7 +810,6 @@ impl UnifyKey for TyVid {
}
}

#[cfg(feature = "nightly")]
impl UnifyValue for IntVarValue {
type Error = NoError;

Expand All @@ -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.
Expand All @@ -848,7 +844,6 @@ impl UnifyKey for IntVid {
}
}

#[cfg(feature = "nightly")]
impl UnifyValue for FloatVarValue {
type Error = NoError;

Expand All @@ -866,7 +861,6 @@ impl UnifyValue for FloatVarValue {
}
}

#[cfg(feature = "nightly")]
impl UnifyKey for FloatVid {
type Value = FloatVarValue;
#[inline]
Expand Down
78 changes: 72 additions & 6 deletions src/doc/style-guide/src/expressions.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
Expand All @@ -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
Expand Down
Loading
Loading