Fix ICE when passing DefId-creating args to legacy_const_generics. by veluca93 · Pull Request #130443 · rust-lang/rust (original) (raw)

@veluca93

@rustbot rustbot added S-waiting-on-review

Status: Awaiting review from the assignee but also interested parties.

T-compiler

Relevant to the compiler team, which will review and decide on the PR/issue.

labels

Sep 16, 2024

compiler-errors

BoxyUwU

bors added a commit to rust-lang-ci/rust that referenced this pull request

Sep 16, 2024

@bors

…r=

Fix ICE when passing DefId-creating args to legacy_const_generics.

r? BoxyUwU

Fixes rust-lang#123077

bors added a commit to rust-lang-ci/rust that referenced this pull request

Sep 16, 2024

@bors

klensy

RalfJung

tmeijn pushed a commit to tmeijn/dotfiles that referenced this pull request

Jan 22, 2025

@tmeijn

This MR contains the following updates:

Package Update Change
rust minor 1.83.0 -> 1.84.0

MR created with the help of el-capitano/tools/renovate-bot.

Proposed changes to behavior should be submitted there as MRs.


Release Notes

rust-lang/rust (rust)

v1.84.0

Compare Source

==========================

Language

Compiler

Libraries

Stabilized APIs

These APIs are now stable in const contexts

Cargo

Rustdoc

Compatibility Notes


Configuration

📅 Schedule: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever MR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this MR and you won't be reminded about this update again.



This MR has been generated by Renovate Bot.

wip-sync pushed a commit to NetBSD/pkgsrc-wip that referenced this pull request

Feb 2, 2025

@he32

Pkgsrc changes:

Upstream changes:

Version 1.84.1 (2025-01-30)

Version 1.84.0 (2025-01-09)

Language

Compiler

Libraries

Stabilized APIs

These APIs are now stable in const contexts

Cargo

Rustdoc

Compatibility Notes

matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request

Feb 21, 2025

@matthiaskrgr

…-obk

Give global_asm a fake body to store typeck results, represent sym fn as a hir expr to fix sym fn operands with lifetimes

There are a few intertwined problems with sym fn operands in both inline and global asm macros.

Specifically, unlike other anon consts, they may evaluate to a type with free regions in them without actually having an item-level type annotation to give them a "proper" type. This is in contrast to named constants, which always have an item-level type annotation, or unnamed constants which are constrained by their position (e.g. a const arg in a turbofish, or a const array length).

Today, we infer the type of the operand by looking at the HIR typeck results; however, those results are region-erased, so during borrowck we ICE since we don't expect to encounter erased regions. We can't just fill this type with something like 'static, since we may want to use real (free) regions:

fn foo<'a>() {
  asm!("/* ... */", sym bar::<&'a ()>);
}

The first idea may be to represent sym fn operands using inline consts instead of anon consts. This makes sense, since inline consts can reference regions from the parent body (like the 'a in the example above). However, this introduces a problem with global_asm!, which doesn't have a parent body; inline consts must be associated with a parent body since they are not a body owner of their own. In rust-lang#116087, I attempted to fix this by using two separate sym operands for global and inline asm. However, this led to a lot of confusion and also some unattractive code duplication.

In this PR, I adjust the lowering of global_asm! so that it's lowered in a "fake" HIR body. This body contains a single expression which is ExprKind::InlineAsm; we don't use this HIR body, but it's used in typeck and borrowck so that we can properly infer and validate the the lifetimes of sym fn operands.

I then adjust the lowering of sym fn to instead be represented with a HIR expression. This is both because it's no longer necessary to represent this operand as an anon const, since it's just a path expression, and also more importantly to sidestep yet another ICE (rust-lang#137179), which has to do with the existing code breaking an invariant of def-id creation and anon consts. Specifically, we are not allowed to synthesize a def-id for an anon const when that anon const contains expressions with def-ids whose parent is not that anon const. This is somewhat related to rust-lang#130443 (comment), which is also a place in the compiler where synthesizing anon consts leads to def-id parenting issue.

As a side-effect, this consolidates the type checking for inline and global asm, so it allows us to simplify InlineAsmCtxt a bit. It also allows us to delete a bit of hacky code from anon const type_of which was there to detect sym fn operands specifically. This also could be generalized to support const asm operands with types with lifetimes in them. Since we specifically reject these consts today, I'm not going to change the representation of those consts (but they'd just be turned into inline consts).

r? oli-obk -- mostly b/c you're patient and also understand the breadth of the code that this touches, please reassign if you don't want to review this.

Fixes rust-lang#111709 Fixes rust-lang#96304 Fixes rust-lang#137179

matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request

Feb 21, 2025

@matthiaskrgr

…-obk

Give global_asm a fake body to store typeck results, represent sym fn as a hir expr to fix sym fn operands with lifetimes

There are a few intertwined problems with sym fn operands in both inline and global asm macros.

Specifically, unlike other anon consts, they may evaluate to a type with free regions in them without actually having an item-level type annotation to give them a "proper" type. This is in contrast to named constants, which always have an item-level type annotation, or unnamed constants which are constrained by their position (e.g. a const arg in a turbofish, or a const array length).

Today, we infer the type of the operand by looking at the HIR typeck results; however, those results are region-erased, so during borrowck we ICE since we don't expect to encounter erased regions. We can't just fill this type with something like 'static, since we may want to use real (free) regions:

fn foo<'a>() {
  asm!("/* ... */", sym bar::<&'a ()>);
}

The first idea may be to represent sym fn operands using inline consts instead of anon consts. This makes sense, since inline consts can reference regions from the parent body (like the 'a in the example above). However, this introduces a problem with global_asm!, which doesn't have a parent body; inline consts must be associated with a parent body since they are not a body owner of their own. In rust-lang#116087, I attempted to fix this by using two separate sym operands for global and inline asm. However, this led to a lot of confusion and also some unattractive code duplication.

In this PR, I adjust the lowering of global_asm! so that it's lowered in a "fake" HIR body. This body contains a single expression which is ExprKind::InlineAsm; we don't use this HIR body, but it's used in typeck and borrowck so that we can properly infer and validate the the lifetimes of sym fn operands.

I then adjust the lowering of sym fn to instead be represented with a HIR expression. This is both because it's no longer necessary to represent this operand as an anon const, since it's just a path expression, and also more importantly to sidestep yet another ICE (rust-lang#137179), which has to do with the existing code breaking an invariant of def-id creation and anon consts. Specifically, we are not allowed to synthesize a def-id for an anon const when that anon const contains expressions with def-ids whose parent is not that anon const. This is somewhat related to rust-lang#130443 (comment), which is also a place in the compiler where synthesizing anon consts leads to def-id parenting issue.

As a side-effect, this consolidates the type checking for inline and global asm, so it allows us to simplify InlineAsmCtxt a bit. It also allows us to delete a bit of hacky code from anon const type_of which was there to detect sym fn operands specifically. This also could be generalized to support const asm operands with types with lifetimes in them. Since we specifically reject these consts today, I'm not going to change the representation of those consts (but they'd just be turned into inline consts).

r? oli-obk -- mostly b/c you're patient and also understand the breadth of the code that this touches, please reassign if you don't want to review this.

Fixes rust-lang#111709 Fixes rust-lang#96304 Fixes rust-lang#137179

matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request

Feb 22, 2025

@matthiaskrgr

…-obk

Give global_asm a fake body to store typeck results, represent sym fn as a hir expr to fix sym fn operands with lifetimes

There are a few intertwined problems with sym fn operands in both inline and global asm macros.

Specifically, unlike other anon consts, they may evaluate to a type with free regions in them without actually having an item-level type annotation to give them a "proper" type. This is in contrast to named constants, which always have an item-level type annotation, or unnamed constants which are constrained by their position (e.g. a const arg in a turbofish, or a const array length).

Today, we infer the type of the operand by looking at the HIR typeck results; however, those results are region-erased, so during borrowck we ICE since we don't expect to encounter erased regions. We can't just fill this type with something like 'static, since we may want to use real (free) regions:

fn foo<'a>() {
  asm!("/* ... */", sym bar::<&'a ()>);
}

The first idea may be to represent sym fn operands using inline consts instead of anon consts. This makes sense, since inline consts can reference regions from the parent body (like the 'a in the example above). However, this introduces a problem with global_asm!, which doesn't have a parent body; inline consts must be associated with a parent body since they are not a body owner of their own. In rust-lang#116087, I attempted to fix this by using two separate sym operands for global and inline asm. However, this led to a lot of confusion and also some unattractive code duplication.

In this PR, I adjust the lowering of global_asm! so that it's lowered in a "fake" HIR body. This body contains a single expression which is ExprKind::InlineAsm; we don't use this HIR body, but it's used in typeck and borrowck so that we can properly infer and validate the the lifetimes of sym fn operands.

I then adjust the lowering of sym fn to instead be represented with a HIR expression. This is both because it's no longer necessary to represent this operand as an anon const, since it's just a path expression, and also more importantly to sidestep yet another ICE (rust-lang#137179), which has to do with the existing code breaking an invariant of def-id creation and anon consts. Specifically, we are not allowed to synthesize a def-id for an anon const when that anon const contains expressions with def-ids whose parent is not that anon const. This is somewhat related to rust-lang#130443 (comment), which is also a place in the compiler where synthesizing anon consts leads to def-id parenting issue.

As a side-effect, this consolidates the type checking for inline and global asm, so it allows us to simplify InlineAsmCtxt a bit. It also allows us to delete a bit of hacky code from anon const type_of which was there to detect sym fn operands specifically. This also could be generalized to support const asm operands with types with lifetimes in them. Since we specifically reject these consts today, I'm not going to change the representation of those consts (but they'd just be turned into inline consts).

r? oli-obk -- mostly b/c you're patient and also understand the breadth of the code that this touches, please reassign if you don't want to review this.

Fixes rust-lang#111709 Fixes rust-lang#96304 Fixes rust-lang#137179

matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request

Feb 22, 2025

@matthiaskrgr

…-obk

Give global_asm a fake body to store typeck results, represent sym fn as a hir expr to fix sym fn operands with lifetimes

There are a few intertwined problems with sym fn operands in both inline and global asm macros.

Specifically, unlike other anon consts, they may evaluate to a type with free regions in them without actually having an item-level type annotation to give them a "proper" type. This is in contrast to named constants, which always have an item-level type annotation, or unnamed constants which are constrained by their position (e.g. a const arg in a turbofish, or a const array length).

Today, we infer the type of the operand by looking at the HIR typeck results; however, those results are region-erased, so during borrowck we ICE since we don't expect to encounter erased regions. We can't just fill this type with something like 'static, since we may want to use real (free) regions:

fn foo<'a>() {
  asm!("/* ... */", sym bar::<&'a ()>);
}

The first idea may be to represent sym fn operands using inline consts instead of anon consts. This makes sense, since inline consts can reference regions from the parent body (like the 'a in the example above). However, this introduces a problem with global_asm!, which doesn't have a parent body; inline consts must be associated with a parent body since they are not a body owner of their own. In rust-lang#116087, I attempted to fix this by using two separate sym operands for global and inline asm. However, this led to a lot of confusion and also some unattractive code duplication.

In this PR, I adjust the lowering of global_asm! so that it's lowered in a "fake" HIR body. This body contains a single expression which is ExprKind::InlineAsm; we don't use this HIR body, but it's used in typeck and borrowck so that we can properly infer and validate the the lifetimes of sym fn operands.

I then adjust the lowering of sym fn to instead be represented with a HIR expression. This is both because it's no longer necessary to represent this operand as an anon const, since it's just a path expression, and also more importantly to sidestep yet another ICE (rust-lang#137179), which has to do with the existing code breaking an invariant of def-id creation and anon consts. Specifically, we are not allowed to synthesize a def-id for an anon const when that anon const contains expressions with def-ids whose parent is not that anon const. This is somewhat related to rust-lang#130443 (comment), which is also a place in the compiler where synthesizing anon consts leads to def-id parenting issue.

As a side-effect, this consolidates the type checking for inline and global asm, so it allows us to simplify InlineAsmCtxt a bit. It also allows us to delete a bit of hacky code from anon const type_of which was there to detect sym fn operands specifically. This also could be generalized to support const asm operands with types with lifetimes in them. Since we specifically reject these consts today, I'm not going to change the representation of those consts (but they'd just be turned into inline consts).

r? oli-obk -- mostly b/c you're patient and also understand the breadth of the code that this touches, please reassign if you don't want to review this.

Fixes rust-lang#111709 Fixes rust-lang#96304 Fixes rust-lang#137179

matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request

Feb 22, 2025

@matthiaskrgr

…-obk

Give global_asm a fake body to store typeck results, represent sym fn as a hir expr to fix sym fn operands with lifetimes

There are a few intertwined problems with sym fn operands in both inline and global asm macros.

Specifically, unlike other anon consts, they may evaluate to a type with free regions in them without actually having an item-level type annotation to give them a "proper" type. This is in contrast to named constants, which always have an item-level type annotation, or unnamed constants which are constrained by their position (e.g. a const arg in a turbofish, or a const array length).

Today, we infer the type of the operand by looking at the HIR typeck results; however, those results are region-erased, so during borrowck we ICE since we don't expect to encounter erased regions. We can't just fill this type with something like 'static, since we may want to use real (free) regions:

fn foo<'a>() {
  asm!("/* ... */", sym bar::<&'a ()>);
}

The first idea may be to represent sym fn operands using inline consts instead of anon consts. This makes sense, since inline consts can reference regions from the parent body (like the 'a in the example above). However, this introduces a problem with global_asm!, which doesn't have a parent body; inline consts must be associated with a parent body since they are not a body owner of their own. In rust-lang#116087, I attempted to fix this by using two separate sym operands for global and inline asm. However, this led to a lot of confusion and also some unattractive code duplication.

In this PR, I adjust the lowering of global_asm! so that it's lowered in a "fake" HIR body. This body contains a single expression which is ExprKind::InlineAsm; we don't use this HIR body, but it's used in typeck and borrowck so that we can properly infer and validate the the lifetimes of sym fn operands.

I then adjust the lowering of sym fn to instead be represented with a HIR expression. This is both because it's no longer necessary to represent this operand as an anon const, since it's just a path expression, and also more importantly to sidestep yet another ICE (rust-lang#137179), which has to do with the existing code breaking an invariant of def-id creation and anon consts. Specifically, we are not allowed to synthesize a def-id for an anon const when that anon const contains expressions with def-ids whose parent is not that anon const. This is somewhat related to rust-lang#130443 (comment), which is also a place in the compiler where synthesizing anon consts leads to def-id parenting issue.

As a side-effect, this consolidates the type checking for inline and global asm, so it allows us to simplify InlineAsmCtxt a bit. It also allows us to delete a bit of hacky code from anon const type_of which was there to detect sym fn operands specifically. This also could be generalized to support const asm operands with types with lifetimes in them. Since we specifically reject these consts today, I'm not going to change the representation of those consts (but they'd just be turned into inline consts).

r? oli-obk -- mostly b/c you're patient and also understand the breadth of the code that this touches, please reassign if you don't want to review this.

Fixes rust-lang#111709 Fixes rust-lang#96304 Fixes rust-lang#137179

matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request

Feb 22, 2025

@matthiaskrgr

…-obk

Give global_asm a fake body to store typeck results, represent sym fn as a hir expr to fix sym fn operands with lifetimes

There are a few intertwined problems with sym fn operands in both inline and global asm macros.

Specifically, unlike other anon consts, they may evaluate to a type with free regions in them without actually having an item-level type annotation to give them a "proper" type. This is in contrast to named constants, which always have an item-level type annotation, or unnamed constants which are constrained by their position (e.g. a const arg in a turbofish, or a const array length).

Today, we infer the type of the operand by looking at the HIR typeck results; however, those results are region-erased, so during borrowck we ICE since we don't expect to encounter erased regions. We can't just fill this type with something like 'static, since we may want to use real (free) regions:

fn foo<'a>() {
  asm!("/* ... */", sym bar::<&'a ()>);
}

The first idea may be to represent sym fn operands using inline consts instead of anon consts. This makes sense, since inline consts can reference regions from the parent body (like the 'a in the example above). However, this introduces a problem with global_asm!, which doesn't have a parent body; inline consts must be associated with a parent body since they are not a body owner of their own. In rust-lang#116087, I attempted to fix this by using two separate sym operands for global and inline asm. However, this led to a lot of confusion and also some unattractive code duplication.

In this PR, I adjust the lowering of global_asm! so that it's lowered in a "fake" HIR body. This body contains a single expression which is ExprKind::InlineAsm; we don't use this HIR body, but it's used in typeck and borrowck so that we can properly infer and validate the the lifetimes of sym fn operands.

I then adjust the lowering of sym fn to instead be represented with a HIR expression. This is both because it's no longer necessary to represent this operand as an anon const, since it's just a path expression, and also more importantly to sidestep yet another ICE (rust-lang#137179), which has to do with the existing code breaking an invariant of def-id creation and anon consts. Specifically, we are not allowed to synthesize a def-id for an anon const when that anon const contains expressions with def-ids whose parent is not that anon const. This is somewhat related to rust-lang#130443 (comment), which is also a place in the compiler where synthesizing anon consts leads to def-id parenting issue.

As a side-effect, this consolidates the type checking for inline and global asm, so it allows us to simplify InlineAsmCtxt a bit. It also allows us to delete a bit of hacky code from anon const type_of which was there to detect sym fn operands specifically. This also could be generalized to support const asm operands with types with lifetimes in them. Since we specifically reject these consts today, I'm not going to change the representation of those consts (but they'd just be turned into inline consts).

r? oli-obk -- mostly b/c you're patient and also understand the breadth of the code that this touches, please reassign if you don't want to review this.

Fixes rust-lang#111709 Fixes rust-lang#96304 Fixes rust-lang#137179

rust-timer added a commit to rust-lang-ci/rust that referenced this pull request

Feb 23, 2025

@rust-timer

Rollup merge of rust-lang#137180 - compiler-errors:sym-regions, r=oli-obk

Give global_asm a fake body to store typeck results, represent sym fn as a hir expr to fix sym fn operands with lifetimes

There are a few intertwined problems with sym fn operands in both inline and global asm macros.

Specifically, unlike other anon consts, they may evaluate to a type with free regions in them without actually having an item-level type annotation to give them a "proper" type. This is in contrast to named constants, which always have an item-level type annotation, or unnamed constants which are constrained by their position (e.g. a const arg in a turbofish, or a const array length).

Today, we infer the type of the operand by looking at the HIR typeck results; however, those results are region-erased, so during borrowck we ICE since we don't expect to encounter erased regions. We can't just fill this type with something like 'static, since we may want to use real (free) regions:

fn foo<'a>() {
  asm!("/* ... */", sym bar::<&'a ()>);
}

The first idea may be to represent sym fn operands using inline consts instead of anon consts. This makes sense, since inline consts can reference regions from the parent body (like the 'a in the example above). However, this introduces a problem with global_asm!, which doesn't have a parent body; inline consts must be associated with a parent body since they are not a body owner of their own. In rust-lang#116087, I attempted to fix this by using two separate sym operands for global and inline asm. However, this led to a lot of confusion and also some unattractive code duplication.

In this PR, I adjust the lowering of global_asm! so that it's lowered in a "fake" HIR body. This body contains a single expression which is ExprKind::InlineAsm; we don't use this HIR body, but it's used in typeck and borrowck so that we can properly infer and validate the the lifetimes of sym fn operands.

I then adjust the lowering of sym fn to instead be represented with a HIR expression. This is both because it's no longer necessary to represent this operand as an anon const, since it's just a path expression, and also more importantly to sidestep yet another ICE (rust-lang#137179), which has to do with the existing code breaking an invariant of def-id creation and anon consts. Specifically, we are not allowed to synthesize a def-id for an anon const when that anon const contains expressions with def-ids whose parent is not that anon const. This is somewhat related to rust-lang#130443 (comment), which is also a place in the compiler where synthesizing anon consts leads to def-id parenting issue.

As a side-effect, this consolidates the type checking for inline and global asm, so it allows us to simplify InlineAsmCtxt a bit. It also allows us to delete a bit of hacky code from anon const type_of which was there to detect sym fn operands specifically. This also could be generalized to support const asm operands with types with lifetimes in them. Since we specifically reject these consts today, I'm not going to change the representation of those consts (but they'd just be turned into inline consts).

r? oli-obk -- mostly b/c you're patient and also understand the breadth of the code that this touches, please reassign if you don't want to review this.

Fixes rust-lang#111709 Fixes rust-lang#96304 Fixes rust-lang#137179

RalfJung pushed a commit to RalfJung/miri that referenced this pull request

Feb 24, 2025

@matthiaskrgr

Give global_asm a fake body to store typeck results, represent sym fn as a hir expr to fix sym fn operands with lifetimes

There are a few intertwined problems with sym fn operands in both inline and global asm macros.

Specifically, unlike other anon consts, they may evaluate to a type with free regions in them without actually having an item-level type annotation to give them a "proper" type. This is in contrast to named constants, which always have an item-level type annotation, or unnamed constants which are constrained by their position (e.g. a const arg in a turbofish, or a const array length).

Today, we infer the type of the operand by looking at the HIR typeck results; however, those results are region-erased, so during borrowck we ICE since we don't expect to encounter erased regions. We can't just fill this type with something like 'static, since we may want to use real (free) regions:

fn foo<'a>() {
  asm!("/* ... */", sym bar::<&'a ()>);
}

The first idea may be to represent sym fn operands using inline consts instead of anon consts. This makes sense, since inline consts can reference regions from the parent body (like the 'a in the example above). However, this introduces a problem with global_asm!, which doesn't have a parent body; inline consts must be associated with a parent body since they are not a body owner of their own. In #116087, I attempted to fix this by using two separate sym operands for global and inline asm. However, this led to a lot of confusion and also some unattractive code duplication.

In this PR, I adjust the lowering of global_asm! so that it's lowered in a "fake" HIR body. This body contains a single expression which is ExprKind::InlineAsm; we don't use this HIR body, but it's used in typeck and borrowck so that we can properly infer and validate the the lifetimes of sym fn operands.

I then adjust the lowering of sym fn to instead be represented with a HIR expression. This is both because it's no longer necessary to represent this operand as an anon const, since it's just a path expression, and also more importantly to sidestep yet another ICE (rust-lang/rust#137179), which has to do with the existing code breaking an invariant of def-id creation and anon consts. Specifically, we are not allowed to synthesize a def-id for an anon const when that anon const contains expressions with def-ids whose parent is not that anon const. This is somewhat related to rust-lang/rust#130443 (comment), which is also a place in the compiler where synthesizing anon consts leads to def-id parenting issue.

As a side-effect, this consolidates the type checking for inline and global asm, so it allows us to simplify InlineAsmCtxt a bit. It also allows us to delete a bit of hacky code from anon const type_of which was there to detect sym fn operands specifically. This also could be generalized to support const asm operands with types with lifetimes in them. Since we specifically reject these consts today, I'm not going to change the representation of those consts (but they'd just be turned into inline consts).

r? oli-obk -- mostly b/c you're patient and also understand the breadth of the code that this touches, please reassign if you don't want to review this.

Fixes #111709 Fixes #96304 Fixes #137179

bjorn3 pushed a commit to rust-lang/rustc_codegen_cranelift that referenced this pull request

Feb 24, 2025

@matthiaskrgr

Give global_asm a fake body to store typeck results, represent sym fn as a hir expr to fix sym fn operands with lifetimes

There are a few intertwined problems with sym fn operands in both inline and global asm macros.

Specifically, unlike other anon consts, they may evaluate to a type with free regions in them without actually having an item-level type annotation to give them a "proper" type. This is in contrast to named constants, which always have an item-level type annotation, or unnamed constants which are constrained by their position (e.g. a const arg in a turbofish, or a const array length).

Today, we infer the type of the operand by looking at the HIR typeck results; however, those results are region-erased, so during borrowck we ICE since we don't expect to encounter erased regions. We can't just fill this type with something like 'static, since we may want to use real (free) regions:

fn foo<'a>() {
  asm!("/* ... */", sym bar::<&'a ()>);
}

The first idea may be to represent sym fn operands using inline consts instead of anon consts. This makes sense, since inline consts can reference regions from the parent body (like the 'a in the example above). However, this introduces a problem with global_asm!, which doesn't have a parent body; inline consts must be associated with a parent body since they are not a body owner of their own. In #116087, I attempted to fix this by using two separate sym operands for global and inline asm. However, this led to a lot of confusion and also some unattractive code duplication.

In this PR, I adjust the lowering of global_asm! so that it's lowered in a "fake" HIR body. This body contains a single expression which is ExprKind::InlineAsm; we don't use this HIR body, but it's used in typeck and borrowck so that we can properly infer and validate the the lifetimes of sym fn operands.

I then adjust the lowering of sym fn to instead be represented with a HIR expression. This is both because it's no longer necessary to represent this operand as an anon const, since it's just a path expression, and also more importantly to sidestep yet another ICE (rust-lang/rust#137179), which has to do with the existing code breaking an invariant of def-id creation and anon consts. Specifically, we are not allowed to synthesize a def-id for an anon const when that anon const contains expressions with def-ids whose parent is not that anon const. This is somewhat related to rust-lang/rust#130443 (comment), which is also a place in the compiler where synthesizing anon consts leads to def-id parenting issue.

As a side-effect, this consolidates the type checking for inline and global asm, so it allows us to simplify InlineAsmCtxt a bit. It also allows us to delete a bit of hacky code from anon const type_of which was there to detect sym fn operands specifically. This also could be generalized to support const asm operands with types with lifetimes in them. Since we specifically reject these consts today, I'm not going to change the representation of those consts (but they'd just be turned into inline consts).

r? oli-obk -- mostly b/c you're patient and also understand the breadth of the code that this touches, please reassign if you don't want to review this.

Fixes #111709 Fixes #96304 Fixes #137179

flip1995 pushed a commit to flip1995/rust-clippy that referenced this pull request

Feb 26, 2025

@matthiaskrgr

Give global_asm a fake body to store typeck results, represent sym fn as a hir expr to fix sym fn operands with lifetimes

There are a few intertwined problems with sym fn operands in both inline and global asm macros.

Specifically, unlike other anon consts, they may evaluate to a type with free regions in them without actually having an item-level type annotation to give them a "proper" type. This is in contrast to named constants, which always have an item-level type annotation, or unnamed constants which are constrained by their position (e.g. a const arg in a turbofish, or a const array length).

Today, we infer the type of the operand by looking at the HIR typeck results; however, those results are region-erased, so during borrowck we ICE since we don't expect to encounter erased regions. We can't just fill this type with something like 'static, since we may want to use real (free) regions:

fn foo<'a>() {
  asm!("/* ... */", sym bar::<&'a ()>);
}

The first idea may be to represent sym fn operands using inline consts instead of anon consts. This makes sense, since inline consts can reference regions from the parent body (like the 'a in the example above). However, this introduces a problem with global_asm!, which doesn't have a parent body; inline consts must be associated with a parent body since they are not a body owner of their own. In #116087, I attempted to fix this by using two separate sym operands for global and inline asm. However, this led to a lot of confusion and also some unattractive code duplication.

In this PR, I adjust the lowering of global_asm! so that it's lowered in a "fake" HIR body. This body contains a single expression which is ExprKind::InlineAsm; we don't use this HIR body, but it's used in typeck and borrowck so that we can properly infer and validate the the lifetimes of sym fn operands.

I then adjust the lowering of sym fn to instead be represented with a HIR expression. This is both because it's no longer necessary to represent this operand as an anon const, since it's just a path expression, and also more importantly to sidestep yet another ICE (rust-lang/rust#137179), which has to do with the existing code breaking an invariant of def-id creation and anon consts. Specifically, we are not allowed to synthesize a def-id for an anon const when that anon const contains expressions with def-ids whose parent is not that anon const. This is somewhat related to rust-lang/rust#130443 (comment), which is also a place in the compiler where synthesizing anon consts leads to def-id parenting issue.

As a side-effect, this consolidates the type checking for inline and global asm, so it allows us to simplify InlineAsmCtxt a bit. It also allows us to delete a bit of hacky code from anon const type_of which was there to detect sym fn operands specifically. This also could be generalized to support const asm operands with types with lifetimes in them. Since we specifically reject these consts today, I'm not going to change the representation of those consts (but they'd just be turned into inline consts).

r? oli-obk -- mostly b/c you're patient and also understand the breadth of the code that this touches, please reassign if you don't want to review this.

Fixes #111709 Fixes #96304 Fixes #137179

workingjubilee added a commit to workingjubilee/rustc that referenced this pull request

Jun 17, 2025

@workingjubilee

…lds, r=jieyouxu

Make sure to propagate result from visit_expr_fields

We weren't propagating the ControlFlow::Break out of a struct field, which means that the solution implemented in rust-lang#130443 didn't work for nested fields.

Fixes rust-lang#142525.

workingjubilee added a commit to workingjubilee/rustc that referenced this pull request

Jun 17, 2025

@workingjubilee

…lds, r=jieyouxu

Make sure to propagate result from visit_expr_fields

We weren't propagating the ControlFlow::Break out of a struct field, which means that the solution implemented in rust-lang#130443 didn't work for nested fields.

Fixes rust-lang#142525.

workingjubilee added a commit to workingjubilee/rustc that referenced this pull request

Jun 17, 2025

@workingjubilee

…lds, r=jieyouxu

Make sure to propagate result from visit_expr_fields

We weren't propagating the ControlFlow::Break out of a struct field, which means that the solution implemented in rust-lang#130443 didn't work for nested fields.

Fixes rust-lang#142525.

rust-timer added a commit that referenced this pull request

Jun 17, 2025

@rust-timer

Rollup merge of #142587 - compiler-errors:try-visit-expr-fields, r=jieyouxu

Make sure to propagate result from visit_expr_fields

We weren't propagating the ControlFlow::Break out of a struct field, which means that the solution implemented in #130443 didn't work for nested fields.

Fixes #142525.

This was referenced

Sep 11, 2025