mirror of https://github.com/rust-lang/rust.git
Merge from rust-lang/rust
This commit is contained in:
commit
26888c31cf
|
@ -25,3 +25,5 @@ b2d2184edea578109a48ec3d8decbee5948e8f35
|
||||||
ec2cc761bc7067712ecc7734502f703fe3b024c8
|
ec2cc761bc7067712ecc7734502f703fe3b024c8
|
||||||
# format use declarations
|
# format use declarations
|
||||||
84ac80f1921afc243d71fd0caaa4f2838c294102
|
84ac80f1921afc243d71fd0caaa4f2838c294102
|
||||||
|
# bless mir-opt tests to add `copy`
|
||||||
|
99cb0c6bc399fb94a0ddde7e9b38e9c00d523bad
|
||||||
|
|
|
@ -64,16 +64,21 @@ jobs:
|
||||||
- name: cargo update
|
- name: cargo update
|
||||||
# Remove first line that always just says "Updating crates.io index"
|
# Remove first line that always just says "Updating crates.io index"
|
||||||
run: cargo update 2>&1 | sed '/crates.io index/d' | tee -a cargo_update.log
|
run: cargo update 2>&1 | sed '/crates.io index/d' | tee -a cargo_update.log
|
||||||
|
- name: cargo update library
|
||||||
|
run: |
|
||||||
|
echo -e "\nlibrary dependencies:" >> cargo_update.log
|
||||||
|
cargo update --manifest-path library/Cargo.toml 2>&1 | sed '/crates.io index/d' | tee -a cargo_update.log
|
||||||
- name: cargo update rustbook
|
- name: cargo update rustbook
|
||||||
run: |
|
run: |
|
||||||
echo -e "\nrustbook dependencies:" >> cargo_update.log
|
echo -e "\nrustbook dependencies:" >> cargo_update.log
|
||||||
cargo update --manifest-path src/tools/rustbook 2>&1 | sed '/crates.io index/d' | tee -a cargo_update.log
|
cargo update --manifest-path src/tools/rustbook/Cargo.toml 2>&1 | sed '/crates.io index/d' | tee -a cargo_update.log
|
||||||
- name: upload Cargo.lock artifact for use in PR
|
- name: upload Cargo.lock artifact for use in PR
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: Cargo-lock
|
name: Cargo-lock
|
||||||
path: |
|
path: |
|
||||||
Cargo.lock
|
Cargo.lock
|
||||||
|
library/Cargo.lock
|
||||||
src/tools/rustbook/Cargo.lock
|
src/tools/rustbook/Cargo.lock
|
||||||
retention-days: 1
|
retention-days: 1
|
||||||
- name: upload cargo-update log artifact for use in PR
|
- name: upload cargo-update log artifact for use in PR
|
||||||
|
@ -119,7 +124,7 @@ jobs:
|
||||||
git config user.name github-actions
|
git config user.name github-actions
|
||||||
git config user.email github-actions@github.com
|
git config user.email github-actions@github.com
|
||||||
git switch --force-create cargo_update
|
git switch --force-create cargo_update
|
||||||
git add ./Cargo.lock ./src/tools/rustbook/Cargo.lock
|
git add ./Cargo.lock ./library/Cargo.lock ./src/tools/rustbook/Cargo.lock
|
||||||
git commit --no-verify --file=commit.txt
|
git commit --no-verify --file=commit.txt
|
||||||
|
|
||||||
- name: push
|
- name: push
|
||||||
|
|
|
@ -56,7 +56,9 @@ build/
|
||||||
/src/tools/x/target
|
/src/tools/x/target
|
||||||
# Created by default with `src/ci/docker/run.sh`
|
# Created by default with `src/ci/docker/run.sh`
|
||||||
/obj/
|
/obj/
|
||||||
/rustc-ice*
|
|
||||||
|
## ICE reports
|
||||||
|
rustc-ice-*.txt
|
||||||
|
|
||||||
## Temporary files
|
## Temporary files
|
||||||
*~
|
*~
|
||||||
|
|
699
Cargo.lock
699
Cargo.lock
File diff suppressed because it is too large
Load Diff
|
@ -1,5 +1,5 @@
|
||||||
[workspace]
|
[workspace]
|
||||||
resolver = "1"
|
resolver = "2"
|
||||||
members = [
|
members = [
|
||||||
"compiler/rustc",
|
"compiler/rustc",
|
||||||
"src/etc/test-float-parse",
|
"src/etc/test-float-parse",
|
||||||
|
|
|
@ -143,6 +143,8 @@ Compatibility Notes
|
||||||
- [Turn `proc_macro_back_compat` lint into a hard error.](https://github.com/rust-lang/rust/pull/125596/)
|
- [Turn `proc_macro_back_compat` lint into a hard error.](https://github.com/rust-lang/rust/pull/125596/)
|
||||||
- [Detect unused structs even when implementing private traits](https://github.com/rust-lang/rust/pull/122382/)
|
- [Detect unused structs even when implementing private traits](https://github.com/rust-lang/rust/pull/122382/)
|
||||||
- [`std::sync::ReentrantLockGuard<T>` is no longer `Sync` if `T: !Sync`](https://github.com/rust-lang/rust/pull/125527) which means [`std::io::StdoutLock` and `std::io::StderrLock` are no longer Sync](https://github.com/rust-lang/rust/issues/127340)
|
- [`std::sync::ReentrantLockGuard<T>` is no longer `Sync` if `T: !Sync`](https://github.com/rust-lang/rust/pull/125527) which means [`std::io::StdoutLock` and `std::io::StderrLock` are no longer Sync](https://github.com/rust-lang/rust/issues/127340)
|
||||||
|
- [Type inference will fail in some cases due to new implementations of `FromIterator for Box<str>`.](https://github.com/rust-lang/rust/pull/99969/)
|
||||||
|
Notably, this breaks versions of the `time` crate before 0.3.35, due to no longer inferring the implementation for `Box<[_]>`.
|
||||||
|
|
||||||
<a id="1.80-Internal-Changes"></a>
|
<a id="1.80-Internal-Changes"></a>
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#![cfg_attr(feature = "nightly", doc(rust_logo))]
|
#![cfg_attr(feature = "nightly", doc(rust_logo))]
|
||||||
#![cfg_attr(feature = "nightly", feature(rustdoc_internals))]
|
#![cfg_attr(feature = "nightly", feature(rustdoc_internals))]
|
||||||
#![cfg_attr(feature = "nightly", feature(step_trait))]
|
#![cfg_attr(feature = "nightly", feature(step_trait))]
|
||||||
|
#![warn(unreachable_pub)]
|
||||||
// tidy-alphabetical-end
|
// tidy-alphabetical-end
|
||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
@ -1699,7 +1700,9 @@ impl<FieldIdx: Idx, VariantIdx: Idx> LayoutS<FieldIdx, VariantIdx> {
|
||||||
|
|
||||||
/// Checks if these two `Layout` are equal enough to be considered "the same for all function
|
/// Checks if these two `Layout` are equal enough to be considered "the same for all function
|
||||||
/// call ABIs". Note however that real ABIs depend on more details that are not reflected in the
|
/// call ABIs". Note however that real ABIs depend on more details that are not reflected in the
|
||||||
/// `Layout`; the `PassMode` need to be compared as well.
|
/// `Layout`; the `PassMode` need to be compared as well. Also note that we assume
|
||||||
|
/// aggregates are passed via `PassMode::Indirect` or `PassMode::Cast`; more strict
|
||||||
|
/// checks would otherwise be required.
|
||||||
pub fn eq_abi(&self, other: &Self) -> bool {
|
pub fn eq_abi(&self, other: &Self) -> bool {
|
||||||
// The one thing that we are not capturing here is that for unsized types, the metadata must
|
// The one thing that we are not capturing here is that for unsized types, the metadata must
|
||||||
// also have the same ABI, and moreover that the same metadata leads to the same size. The
|
// also have the same ABI, and moreover that the same metadata leads to the same size. The
|
||||||
|
|
|
@ -21,10 +21,10 @@
|
||||||
#![feature(decl_macro)]
|
#![feature(decl_macro)]
|
||||||
#![feature(dropck_eyepatch)]
|
#![feature(dropck_eyepatch)]
|
||||||
#![feature(maybe_uninit_slice)]
|
#![feature(maybe_uninit_slice)]
|
||||||
#![feature(new_uninit)]
|
|
||||||
#![feature(rustc_attrs)]
|
#![feature(rustc_attrs)]
|
||||||
#![feature(rustdoc_internals)]
|
#![feature(rustdoc_internals)]
|
||||||
#![feature(strict_provenance)]
|
#![feature(strict_provenance)]
|
||||||
|
#![warn(unreachable_pub)]
|
||||||
// tidy-alphabetical-end
|
// tidy-alphabetical-end
|
||||||
|
|
||||||
use std::alloc::Layout;
|
use std::alloc::Layout;
|
||||||
|
|
|
@ -32,7 +32,7 @@ impl<T> TypedArena<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
pub fn test_unused() {
|
fn test_unused() {
|
||||||
let arena: TypedArena<Point> = TypedArena::default();
|
let arena: TypedArena<Point> = TypedArena::default();
|
||||||
assert!(arena.chunks.borrow().is_empty());
|
assert!(arena.chunks.borrow().is_empty());
|
||||||
}
|
}
|
||||||
|
@ -75,7 +75,7 @@ fn test_arena_alloc_nested() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
pub fn test_copy() {
|
fn test_copy() {
|
||||||
let arena = TypedArena::default();
|
let arena = TypedArena::default();
|
||||||
#[cfg(not(miri))]
|
#[cfg(not(miri))]
|
||||||
const N: usize = 100000;
|
const N: usize = 100000;
|
||||||
|
@ -87,13 +87,13 @@ pub fn test_copy() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
pub fn bench_copy(b: &mut Bencher) {
|
fn bench_copy(b: &mut Bencher) {
|
||||||
let arena = TypedArena::default();
|
let arena = TypedArena::default();
|
||||||
b.iter(|| arena.alloc(Point { x: 1, y: 2, z: 3 }))
|
b.iter(|| arena.alloc(Point { x: 1, y: 2, z: 3 }))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
pub fn bench_copy_nonarena(b: &mut Bencher) {
|
fn bench_copy_nonarena(b: &mut Bencher) {
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
let _: Box<_> = Box::new(Point { x: 1, y: 2, z: 3 });
|
let _: Box<_> = Box::new(Point { x: 1, y: 2, z: 3 });
|
||||||
})
|
})
|
||||||
|
@ -106,7 +106,7 @@ struct Noncopy {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
pub fn test_noncopy() {
|
fn test_noncopy() {
|
||||||
let arena = TypedArena::default();
|
let arena = TypedArena::default();
|
||||||
#[cfg(not(miri))]
|
#[cfg(not(miri))]
|
||||||
const N: usize = 100000;
|
const N: usize = 100000;
|
||||||
|
@ -118,7 +118,7 @@ pub fn test_noncopy() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
pub fn test_typed_arena_zero_sized() {
|
fn test_typed_arena_zero_sized() {
|
||||||
let arena = TypedArena::default();
|
let arena = TypedArena::default();
|
||||||
#[cfg(not(miri))]
|
#[cfg(not(miri))]
|
||||||
const N: usize = 100000;
|
const N: usize = 100000;
|
||||||
|
@ -130,7 +130,7 @@ pub fn test_typed_arena_zero_sized() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
pub fn test_typed_arena_clear() {
|
fn test_typed_arena_clear() {
|
||||||
let mut arena = TypedArena::default();
|
let mut arena = TypedArena::default();
|
||||||
for _ in 0..10 {
|
for _ in 0..10 {
|
||||||
arena.clear();
|
arena.clear();
|
||||||
|
@ -145,7 +145,7 @@ pub fn test_typed_arena_clear() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
pub fn bench_typed_arena_clear(b: &mut Bencher) {
|
fn bench_typed_arena_clear(b: &mut Bencher) {
|
||||||
let mut arena = TypedArena::default();
|
let mut arena = TypedArena::default();
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
arena.alloc(Point { x: 1, y: 2, z: 3 });
|
arena.alloc(Point { x: 1, y: 2, z: 3 });
|
||||||
|
@ -154,7 +154,7 @@ pub fn bench_typed_arena_clear(b: &mut Bencher) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
pub fn bench_typed_arena_clear_100(b: &mut Bencher) {
|
fn bench_typed_arena_clear_100(b: &mut Bencher) {
|
||||||
let mut arena = TypedArena::default();
|
let mut arena = TypedArena::default();
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
for _ in 0..100 {
|
for _ in 0..100 {
|
||||||
|
@ -230,7 +230,7 @@ fn test_typed_arena_drop_small_count() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
pub fn bench_noncopy(b: &mut Bencher) {
|
fn bench_noncopy(b: &mut Bencher) {
|
||||||
let arena = TypedArena::default();
|
let arena = TypedArena::default();
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
arena.alloc(Noncopy { string: "hello world".to_string(), array: vec![1, 2, 3, 4, 5] })
|
arena.alloc(Noncopy { string: "hello world".to_string(), array: vec![1, 2, 3, 4, 5] })
|
||||||
|
@ -238,7 +238,7 @@ pub fn bench_noncopy(b: &mut Bencher) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
pub fn bench_noncopy_nonarena(b: &mut Bencher) {
|
fn bench_noncopy_nonarena(b: &mut Bencher) {
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
let _: Box<_> =
|
let _: Box<_> =
|
||||||
Box::new(Noncopy { string: "hello world".to_string(), array: vec![1, 2, 3, 4, 5] });
|
Box::new(Noncopy { string: "hello world".to_string(), array: vec![1, 2, 3, 4, 5] });
|
||||||
|
|
|
@ -2902,6 +2902,17 @@ pub struct AttrItem {
|
||||||
pub tokens: Option<LazyAttrTokenStream>,
|
pub tokens: Option<LazyAttrTokenStream>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl AttrItem {
|
||||||
|
pub fn is_valid_for_outer_style(&self) -> bool {
|
||||||
|
self.path == sym::cfg_attr
|
||||||
|
|| self.path == sym::cfg
|
||||||
|
|| self.path == sym::forbid
|
||||||
|
|| self.path == sym::warn
|
||||||
|
|| self.path == sym::allow
|
||||||
|
|| self.path == sym::deny
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// `TraitRef`s appear in impls.
|
/// `TraitRef`s appear in impls.
|
||||||
///
|
///
|
||||||
/// Resolution maps each `TraitRef`'s `ref_id` to its defining trait; that's all
|
/// Resolution maps each `TraitRef`'s `ref_id` to its defining trait; that's all
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#![feature(never_type)]
|
#![feature(never_type)]
|
||||||
#![feature(rustdoc_internals)]
|
#![feature(rustdoc_internals)]
|
||||||
#![feature(stmt_expr_attributes)]
|
#![feature(stmt_expr_attributes)]
|
||||||
|
#![warn(unreachable_pub)]
|
||||||
// tidy-alphabetical-end
|
// tidy-alphabetical-end
|
||||||
|
|
||||||
pub mod util {
|
pub mod util {
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#![cfg_attr(feature = "nightly", allow(internal_features))]
|
#![cfg_attr(feature = "nightly", allow(internal_features))]
|
||||||
#![cfg_attr(feature = "nightly", feature(never_type))]
|
#![cfg_attr(feature = "nightly", feature(never_type))]
|
||||||
#![cfg_attr(feature = "nightly", feature(rustc_attrs))]
|
#![cfg_attr(feature = "nightly", feature(rustc_attrs))]
|
||||||
|
#![warn(unreachable_pub)]
|
||||||
// tidy-alphabetical-end
|
// tidy-alphabetical-end
|
||||||
|
|
||||||
#[cfg(feature = "nightly")]
|
#[cfg(feature = "nightly")]
|
||||||
|
|
|
@ -175,8 +175,6 @@ ast_lowering_underscore_expr_lhs_assign =
|
||||||
.label = `_` not allowed here
|
.label = `_` not allowed here
|
||||||
|
|
||||||
ast_lowering_unstable_inline_assembly = inline assembly is not stable yet on this architecture
|
ast_lowering_unstable_inline_assembly = inline assembly is not stable yet on this architecture
|
||||||
ast_lowering_unstable_inline_assembly_const_operands =
|
|
||||||
const operands for inline assembly are unstable
|
|
||||||
ast_lowering_unstable_inline_assembly_label_operands =
|
ast_lowering_unstable_inline_assembly_label_operands =
|
||||||
label operands for inline assembly are unstable
|
label operands for inline assembly are unstable
|
||||||
ast_lowering_unstable_may_unwind = the `may_unwind` option is unstable
|
ast_lowering_unstable_may_unwind = the `may_unwind` option is unstable
|
||||||
|
|
|
@ -86,9 +86,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
// Multiple different abi names may actually be the same ABI
|
// Multiple different abi names may actually be the same ABI
|
||||||
// If the specified ABIs are not the same name, alert the user that they resolve to the same ABI
|
// If the specified ABIs are not the same name, alert the user that they resolve to the same ABI
|
||||||
let source_map = self.tcx.sess.source_map();
|
let source_map = self.tcx.sess.source_map();
|
||||||
let equivalent = (source_map.span_to_snippet(*prev_sp)
|
let equivalent = source_map.span_to_snippet(*prev_sp)
|
||||||
!= source_map.span_to_snippet(*abi_span))
|
!= source_map.span_to_snippet(*abi_span);
|
||||||
.then_some(());
|
|
||||||
|
|
||||||
self.dcx().emit_err(AbiSpecifiedMultipleTimes {
|
self.dcx().emit_err(AbiSpecifiedMultipleTimes {
|
||||||
abi_span: *abi_span,
|
abi_span: *abi_span,
|
||||||
|
@ -183,20 +182,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
out_expr: out_expr.as_ref().map(|expr| self.lower_expr(expr)),
|
out_expr: out_expr.as_ref().map(|expr| self.lower_expr(expr)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
InlineAsmOperand::Const { anon_const } => {
|
InlineAsmOperand::Const { anon_const } => hir::InlineAsmOperand::Const {
|
||||||
if !self.tcx.features().asm_const {
|
anon_const: self.lower_anon_const_to_anon_const(anon_const),
|
||||||
feature_err(
|
},
|
||||||
sess,
|
|
||||||
sym::asm_const,
|
|
||||||
*op_sp,
|
|
||||||
fluent::ast_lowering_unstable_inline_assembly_const_operands,
|
|
||||||
)
|
|
||||||
.emit();
|
|
||||||
}
|
|
||||||
hir::InlineAsmOperand::Const {
|
|
||||||
anon_const: self.lower_anon_const_to_anon_const(anon_const),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
InlineAsmOperand::Sym { sym } => {
|
InlineAsmOperand::Sym { sym } => {
|
||||||
let static_def_id = self
|
let static_def_id = self
|
||||||
.resolver
|
.resolver
|
||||||
|
@ -232,7 +220,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
let parent_def_id = self.current_def_id_parent;
|
let parent_def_id = self.current_def_id_parent;
|
||||||
let node_id = self.next_node_id();
|
let node_id = self.next_node_id();
|
||||||
// HACK(min_generic_const_args): see lower_anon_const
|
// HACK(min_generic_const_args): see lower_anon_const
|
||||||
if !expr.is_potential_trivial_const_arg() {
|
if !self.tcx.features().const_arg_path
|
||||||
|
|| !expr.is_potential_trivial_const_arg()
|
||||||
|
{
|
||||||
self.create_def(
|
self.create_def(
|
||||||
parent_def_id,
|
parent_def_id,
|
||||||
node_id,
|
node_id,
|
||||||
|
|
|
@ -51,7 +51,7 @@ use rustc_span::Span;
|
||||||
use rustc_target::spec::abi;
|
use rustc_target::spec::abi;
|
||||||
use {rustc_ast as ast, rustc_hir as hir};
|
use {rustc_ast as ast, rustc_hir as hir};
|
||||||
|
|
||||||
use super::{ImplTraitContext, LoweringContext, ParamMode, ParenthesizedGenericArgs};
|
use super::{GenericArgsMode, ImplTraitContext, LoweringContext, ParamMode};
|
||||||
use crate::{ImplTraitPosition, ResolverAstLoweringExt};
|
use crate::{ImplTraitPosition, ResolverAstLoweringExt};
|
||||||
|
|
||||||
pub(crate) struct DelegationResults<'hir> {
|
pub(crate) struct DelegationResults<'hir> {
|
||||||
|
@ -189,7 +189,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
) -> hir::FnSig<'hir> {
|
) -> hir::FnSig<'hir> {
|
||||||
let header = if let Some(local_sig_id) = sig_id.as_local() {
|
let header = if let Some(local_sig_id) = sig_id.as_local() {
|
||||||
match self.resolver.delegation_fn_sigs.get(&local_sig_id) {
|
match self.resolver.delegation_fn_sigs.get(&local_sig_id) {
|
||||||
Some(sig) => self.lower_fn_header(sig.header),
|
Some(sig) => self.lower_fn_header(sig.header, hir::Safety::Safe),
|
||||||
None => self.generate_header_error(),
|
None => self.generate_header_error(),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -323,7 +323,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
delegation.path.span,
|
delegation.path.span,
|
||||||
ast_segment,
|
ast_segment,
|
||||||
ParamMode::Optional,
|
ParamMode::Optional,
|
||||||
ParenthesizedGenericArgs::Err,
|
GenericArgsMode::Err,
|
||||||
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
|
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
|
|
|
@ -6,7 +6,7 @@ use rustc_span::{Span, Symbol};
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_lowering_generic_type_with_parentheses, code = E0214)]
|
#[diag(ast_lowering_generic_type_with_parentheses, code = E0214)]
|
||||||
pub struct GenericTypeWithParentheses {
|
pub(crate) struct GenericTypeWithParentheses {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
#[label]
|
#[label]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
|
@ -16,7 +16,7 @@ pub struct GenericTypeWithParentheses {
|
||||||
|
|
||||||
#[derive(Subdiagnostic)]
|
#[derive(Subdiagnostic)]
|
||||||
#[multipart_suggestion(ast_lowering_use_angle_brackets, applicability = "maybe-incorrect")]
|
#[multipart_suggestion(ast_lowering_use_angle_brackets, applicability = "maybe-incorrect")]
|
||||||
pub struct UseAngleBrackets {
|
pub(crate) struct UseAngleBrackets {
|
||||||
#[suggestion_part(code = "<")]
|
#[suggestion_part(code = "<")]
|
||||||
pub open_param: Span,
|
pub open_param: Span,
|
||||||
#[suggestion_part(code = ">")]
|
#[suggestion_part(code = ">")]
|
||||||
|
@ -26,7 +26,7 @@ pub struct UseAngleBrackets {
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_lowering_invalid_abi, code = E0703)]
|
#[diag(ast_lowering_invalid_abi, code = E0703)]
|
||||||
#[note]
|
#[note]
|
||||||
pub struct InvalidAbi {
|
pub(crate) struct InvalidAbi {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
#[label]
|
#[label]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
|
@ -38,7 +38,7 @@ pub struct InvalidAbi {
|
||||||
pub suggestion: Option<InvalidAbiSuggestion>,
|
pub suggestion: Option<InvalidAbiSuggestion>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct InvalidAbiReason(pub &'static str);
|
pub(crate) struct InvalidAbiReason(pub &'static str);
|
||||||
|
|
||||||
impl Subdiagnostic for InvalidAbiReason {
|
impl Subdiagnostic for InvalidAbiReason {
|
||||||
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
|
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
|
||||||
|
@ -57,7 +57,7 @@ impl Subdiagnostic for InvalidAbiReason {
|
||||||
code = "{suggestion}",
|
code = "{suggestion}",
|
||||||
applicability = "maybe-incorrect"
|
applicability = "maybe-incorrect"
|
||||||
)]
|
)]
|
||||||
pub struct InvalidAbiSuggestion {
|
pub(crate) struct InvalidAbiSuggestion {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
pub suggestion: String,
|
pub suggestion: String,
|
||||||
|
@ -65,7 +65,7 @@ pub struct InvalidAbiSuggestion {
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_lowering_assoc_ty_parentheses)]
|
#[diag(ast_lowering_assoc_ty_parentheses)]
|
||||||
pub struct AssocTyParentheses {
|
pub(crate) struct AssocTyParentheses {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
#[subdiagnostic]
|
#[subdiagnostic]
|
||||||
|
@ -73,7 +73,7 @@ pub struct AssocTyParentheses {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Subdiagnostic)]
|
#[derive(Subdiagnostic)]
|
||||||
pub enum AssocTyParenthesesSub {
|
pub(crate) enum AssocTyParenthesesSub {
|
||||||
#[multipart_suggestion(ast_lowering_remove_parentheses)]
|
#[multipart_suggestion(ast_lowering_remove_parentheses)]
|
||||||
Empty {
|
Empty {
|
||||||
#[suggestion_part(code = "")]
|
#[suggestion_part(code = "")]
|
||||||
|
@ -91,7 +91,7 @@ pub enum AssocTyParenthesesSub {
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_lowering_misplaced_impl_trait, code = E0562)]
|
#[diag(ast_lowering_misplaced_impl_trait, code = E0562)]
|
||||||
#[note]
|
#[note]
|
||||||
pub struct MisplacedImplTrait<'a> {
|
pub(crate) struct MisplacedImplTrait<'a> {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
pub position: DiagArgFromDisplay<'a>,
|
pub position: DiagArgFromDisplay<'a>,
|
||||||
|
@ -99,7 +99,7 @@ pub struct MisplacedImplTrait<'a> {
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_lowering_assoc_ty_binding_in_dyn)]
|
#[diag(ast_lowering_assoc_ty_binding_in_dyn)]
|
||||||
pub struct MisplacedAssocTyBinding {
|
pub(crate) struct MisplacedAssocTyBinding {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
#[suggestion(code = " = impl", applicability = "maybe-incorrect", style = "verbose")]
|
#[suggestion(code = " = impl", applicability = "maybe-incorrect", style = "verbose")]
|
||||||
|
@ -108,7 +108,7 @@ pub struct MisplacedAssocTyBinding {
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_lowering_underscore_expr_lhs_assign)]
|
#[diag(ast_lowering_underscore_expr_lhs_assign)]
|
||||||
pub struct UnderscoreExprLhsAssign {
|
pub(crate) struct UnderscoreExprLhsAssign {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
#[label]
|
#[label]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
|
@ -116,7 +116,7 @@ pub struct UnderscoreExprLhsAssign {
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_lowering_base_expression_double_dot, code = E0797)]
|
#[diag(ast_lowering_base_expression_double_dot, code = E0797)]
|
||||||
pub struct BaseExpressionDoubleDot {
|
pub(crate) struct BaseExpressionDoubleDot {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
#[suggestion(code = "/* expr */", applicability = "has-placeholders", style = "verbose")]
|
#[suggestion(code = "/* expr */", applicability = "has-placeholders", style = "verbose")]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
|
@ -124,7 +124,7 @@ pub struct BaseExpressionDoubleDot {
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_lowering_await_only_in_async_fn_and_blocks, code = E0728)]
|
#[diag(ast_lowering_await_only_in_async_fn_and_blocks, code = E0728)]
|
||||||
pub struct AwaitOnlyInAsyncFnAndBlocks {
|
pub(crate) struct AwaitOnlyInAsyncFnAndBlocks {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
#[label]
|
#[label]
|
||||||
pub await_kw_span: Span,
|
pub await_kw_span: Span,
|
||||||
|
@ -134,21 +134,21 @@ pub struct AwaitOnlyInAsyncFnAndBlocks {
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_lowering_coroutine_too_many_parameters, code = E0628)]
|
#[diag(ast_lowering_coroutine_too_many_parameters, code = E0628)]
|
||||||
pub struct CoroutineTooManyParameters {
|
pub(crate) struct CoroutineTooManyParameters {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub fn_decl_span: Span,
|
pub fn_decl_span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_lowering_closure_cannot_be_static, code = E0697)]
|
#[diag(ast_lowering_closure_cannot_be_static, code = E0697)]
|
||||||
pub struct ClosureCannotBeStatic {
|
pub(crate) struct ClosureCannotBeStatic {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub fn_decl_span: Span,
|
pub fn_decl_span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_lowering_functional_record_update_destructuring_assignment)]
|
#[diag(ast_lowering_functional_record_update_destructuring_assignment)]
|
||||||
pub struct FunctionalRecordUpdateDestructuringAssignment {
|
pub(crate) struct FunctionalRecordUpdateDestructuringAssignment {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
#[suggestion(code = "", applicability = "machine-applicable")]
|
#[suggestion(code = "", applicability = "machine-applicable")]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
|
@ -156,40 +156,40 @@ pub struct FunctionalRecordUpdateDestructuringAssignment {
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_lowering_async_coroutines_not_supported, code = E0727)]
|
#[diag(ast_lowering_async_coroutines_not_supported, code = E0727)]
|
||||||
pub struct AsyncCoroutinesNotSupported {
|
pub(crate) struct AsyncCoroutinesNotSupported {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_lowering_inline_asm_unsupported_target, code = E0472)]
|
#[diag(ast_lowering_inline_asm_unsupported_target, code = E0472)]
|
||||||
pub struct InlineAsmUnsupportedTarget {
|
pub(crate) struct InlineAsmUnsupportedTarget {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_lowering_att_syntax_only_x86)]
|
#[diag(ast_lowering_att_syntax_only_x86)]
|
||||||
pub struct AttSyntaxOnlyX86 {
|
pub(crate) struct AttSyntaxOnlyX86 {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_lowering_abi_specified_multiple_times)]
|
#[diag(ast_lowering_abi_specified_multiple_times)]
|
||||||
pub struct AbiSpecifiedMultipleTimes {
|
pub(crate) struct AbiSpecifiedMultipleTimes {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub abi_span: Span,
|
pub abi_span: Span,
|
||||||
pub prev_name: Symbol,
|
pub prev_name: Symbol,
|
||||||
#[label]
|
#[label]
|
||||||
pub prev_span: Span,
|
pub prev_span: Span,
|
||||||
#[note]
|
#[note]
|
||||||
pub equivalent: Option<()>,
|
pub equivalent: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_lowering_clobber_abi_not_supported)]
|
#[diag(ast_lowering_clobber_abi_not_supported)]
|
||||||
pub struct ClobberAbiNotSupported {
|
pub(crate) struct ClobberAbiNotSupported {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub abi_span: Span,
|
pub abi_span: Span,
|
||||||
}
|
}
|
||||||
|
@ -197,7 +197,7 @@ pub struct ClobberAbiNotSupported {
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[note]
|
#[note]
|
||||||
#[diag(ast_lowering_invalid_abi_clobber_abi)]
|
#[diag(ast_lowering_invalid_abi_clobber_abi)]
|
||||||
pub struct InvalidAbiClobberAbi {
|
pub(crate) struct InvalidAbiClobberAbi {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub abi_span: Span,
|
pub abi_span: Span,
|
||||||
pub supported_abis: String,
|
pub supported_abis: String,
|
||||||
|
@ -205,7 +205,7 @@ pub struct InvalidAbiClobberAbi {
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_lowering_invalid_register)]
|
#[diag(ast_lowering_invalid_register)]
|
||||||
pub struct InvalidRegister<'a> {
|
pub(crate) struct InvalidRegister<'a> {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub op_span: Span,
|
pub op_span: Span,
|
||||||
pub reg: Symbol,
|
pub reg: Symbol,
|
||||||
|
@ -214,7 +214,7 @@ pub struct InvalidRegister<'a> {
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_lowering_invalid_register_class)]
|
#[diag(ast_lowering_invalid_register_class)]
|
||||||
pub struct InvalidRegisterClass<'a> {
|
pub(crate) struct InvalidRegisterClass<'a> {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub op_span: Span,
|
pub op_span: Span,
|
||||||
pub reg_class: Symbol,
|
pub reg_class: Symbol,
|
||||||
|
@ -223,7 +223,7 @@ pub struct InvalidRegisterClass<'a> {
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_lowering_invalid_asm_template_modifier_reg_class)]
|
#[diag(ast_lowering_invalid_asm_template_modifier_reg_class)]
|
||||||
pub struct InvalidAsmTemplateModifierRegClass {
|
pub(crate) struct InvalidAsmTemplateModifierRegClass {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
#[label(ast_lowering_template_modifier)]
|
#[label(ast_lowering_template_modifier)]
|
||||||
pub placeholder_span: Span,
|
pub placeholder_span: Span,
|
||||||
|
@ -234,7 +234,7 @@ pub struct InvalidAsmTemplateModifierRegClass {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Subdiagnostic)]
|
#[derive(Subdiagnostic)]
|
||||||
pub enum InvalidAsmTemplateModifierRegClassSub {
|
pub(crate) enum InvalidAsmTemplateModifierRegClassSub {
|
||||||
#[note(ast_lowering_support_modifiers)]
|
#[note(ast_lowering_support_modifiers)]
|
||||||
SupportModifier { class_name: Symbol, modifiers: String },
|
SupportModifier { class_name: Symbol, modifiers: String },
|
||||||
#[note(ast_lowering_does_not_support_modifiers)]
|
#[note(ast_lowering_does_not_support_modifiers)]
|
||||||
|
@ -243,7 +243,7 @@ pub enum InvalidAsmTemplateModifierRegClassSub {
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_lowering_invalid_asm_template_modifier_const)]
|
#[diag(ast_lowering_invalid_asm_template_modifier_const)]
|
||||||
pub struct InvalidAsmTemplateModifierConst {
|
pub(crate) struct InvalidAsmTemplateModifierConst {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
#[label(ast_lowering_template_modifier)]
|
#[label(ast_lowering_template_modifier)]
|
||||||
pub placeholder_span: Span,
|
pub placeholder_span: Span,
|
||||||
|
@ -253,7 +253,7 @@ pub struct InvalidAsmTemplateModifierConst {
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_lowering_invalid_asm_template_modifier_sym)]
|
#[diag(ast_lowering_invalid_asm_template_modifier_sym)]
|
||||||
pub struct InvalidAsmTemplateModifierSym {
|
pub(crate) struct InvalidAsmTemplateModifierSym {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
#[label(ast_lowering_template_modifier)]
|
#[label(ast_lowering_template_modifier)]
|
||||||
pub placeholder_span: Span,
|
pub placeholder_span: Span,
|
||||||
|
@ -263,7 +263,7 @@ pub struct InvalidAsmTemplateModifierSym {
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_lowering_invalid_asm_template_modifier_label)]
|
#[diag(ast_lowering_invalid_asm_template_modifier_label)]
|
||||||
pub struct InvalidAsmTemplateModifierLabel {
|
pub(crate) struct InvalidAsmTemplateModifierLabel {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
#[label(ast_lowering_template_modifier)]
|
#[label(ast_lowering_template_modifier)]
|
||||||
pub placeholder_span: Span,
|
pub placeholder_span: Span,
|
||||||
|
@ -273,7 +273,7 @@ pub struct InvalidAsmTemplateModifierLabel {
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_lowering_register_class_only_clobber)]
|
#[diag(ast_lowering_register_class_only_clobber)]
|
||||||
pub struct RegisterClassOnlyClobber {
|
pub(crate) struct RegisterClassOnlyClobber {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub op_span: Span,
|
pub op_span: Span,
|
||||||
pub reg_class_name: Symbol,
|
pub reg_class_name: Symbol,
|
||||||
|
@ -281,7 +281,7 @@ pub struct RegisterClassOnlyClobber {
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_lowering_register_conflict)]
|
#[diag(ast_lowering_register_conflict)]
|
||||||
pub struct RegisterConflict<'a> {
|
pub(crate) struct RegisterConflict<'a> {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
#[label(ast_lowering_register1)]
|
#[label(ast_lowering_register1)]
|
||||||
pub op_span1: Span,
|
pub op_span1: Span,
|
||||||
|
@ -296,7 +296,7 @@ pub struct RegisterConflict<'a> {
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[help]
|
#[help]
|
||||||
#[diag(ast_lowering_sub_tuple_binding)]
|
#[diag(ast_lowering_sub_tuple_binding)]
|
||||||
pub struct SubTupleBinding<'a> {
|
pub(crate) struct SubTupleBinding<'a> {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
#[label]
|
#[label]
|
||||||
#[suggestion(
|
#[suggestion(
|
||||||
|
@ -313,7 +313,7 @@ pub struct SubTupleBinding<'a> {
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_lowering_extra_double_dot)]
|
#[diag(ast_lowering_extra_double_dot)]
|
||||||
pub struct ExtraDoubleDot<'a> {
|
pub(crate) struct ExtraDoubleDot<'a> {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
#[label]
|
#[label]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
|
@ -325,21 +325,21 @@ pub struct ExtraDoubleDot<'a> {
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[note]
|
#[note]
|
||||||
#[diag(ast_lowering_misplaced_double_dot)]
|
#[diag(ast_lowering_misplaced_double_dot)]
|
||||||
pub struct MisplacedDoubleDot {
|
pub(crate) struct MisplacedDoubleDot {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_lowering_misplaced_relax_trait_bound)]
|
#[diag(ast_lowering_misplaced_relax_trait_bound)]
|
||||||
pub struct MisplacedRelaxTraitBound {
|
pub(crate) struct MisplacedRelaxTraitBound {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_lowering_match_arm_with_no_body)]
|
#[diag(ast_lowering_match_arm_with_no_body)]
|
||||||
pub struct MatchArmWithNoBody {
|
pub(crate) struct MatchArmWithNoBody {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
#[suggestion(code = " => todo!(),", applicability = "has-placeholders")]
|
#[suggestion(code = " => todo!(),", applicability = "has-placeholders")]
|
||||||
|
@ -348,7 +348,7 @@ pub struct MatchArmWithNoBody {
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_lowering_never_pattern_with_body)]
|
#[diag(ast_lowering_never_pattern_with_body)]
|
||||||
pub struct NeverPatternWithBody {
|
pub(crate) struct NeverPatternWithBody {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
#[label]
|
#[label]
|
||||||
#[suggestion(code = "", applicability = "maybe-incorrect")]
|
#[suggestion(code = "", applicability = "maybe-incorrect")]
|
||||||
|
@ -357,7 +357,7 @@ pub struct NeverPatternWithBody {
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_lowering_never_pattern_with_guard)]
|
#[diag(ast_lowering_never_pattern_with_guard)]
|
||||||
pub struct NeverPatternWithGuard {
|
pub(crate) struct NeverPatternWithGuard {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
#[suggestion(code = "", applicability = "maybe-incorrect")]
|
#[suggestion(code = "", applicability = "maybe-incorrect")]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
|
@ -365,7 +365,7 @@ pub struct NeverPatternWithGuard {
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_lowering_arbitrary_expression_in_pattern)]
|
#[diag(ast_lowering_arbitrary_expression_in_pattern)]
|
||||||
pub struct ArbitraryExpressionInPattern {
|
pub(crate) struct ArbitraryExpressionInPattern {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
#[note(ast_lowering_pattern_from_macro_note)]
|
#[note(ast_lowering_pattern_from_macro_note)]
|
||||||
|
@ -374,13 +374,13 @@ pub struct ArbitraryExpressionInPattern {
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_lowering_inclusive_range_with_no_end)]
|
#[diag(ast_lowering_inclusive_range_with_no_end)]
|
||||||
pub struct InclusiveRangeWithNoEnd {
|
pub(crate) struct InclusiveRangeWithNoEnd {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
pub enum BadReturnTypeNotation {
|
pub(crate) enum BadReturnTypeNotation {
|
||||||
#[diag(ast_lowering_bad_return_type_notation_inputs)]
|
#[diag(ast_lowering_bad_return_type_notation_inputs)]
|
||||||
Inputs {
|
Inputs {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
|
|
|
@ -20,7 +20,7 @@ use super::errors::{
|
||||||
NeverPatternWithBody, NeverPatternWithGuard, UnderscoreExprLhsAssign,
|
NeverPatternWithBody, NeverPatternWithGuard, UnderscoreExprLhsAssign,
|
||||||
};
|
};
|
||||||
use super::{
|
use super::{
|
||||||
ImplTraitContext, LoweringContext, ParamMode, ParenthesizedGenericArgs, ResolverAstLoweringExt,
|
GenericArgsMode, ImplTraitContext, LoweringContext, ParamMode, ResolverAstLoweringExt,
|
||||||
};
|
};
|
||||||
use crate::errors::YieldInClosure;
|
use crate::errors::YieldInClosure;
|
||||||
use crate::{fluent_generated, FnDeclKind, ImplTraitPosition};
|
use crate::{fluent_generated, FnDeclKind, ImplTraitPosition};
|
||||||
|
@ -107,7 +107,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
e.span,
|
e.span,
|
||||||
seg,
|
seg,
|
||||||
ParamMode::Optional,
|
ParamMode::Optional,
|
||||||
ParenthesizedGenericArgs::Err,
|
GenericArgsMode::Err,
|
||||||
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
|
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
|
||||||
// Method calls can't have bound modifiers
|
// Method calls can't have bound modifiers
|
||||||
None,
|
None,
|
||||||
|
@ -387,7 +387,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
let node_id = self.next_node_id();
|
let node_id = self.next_node_id();
|
||||||
|
|
||||||
// HACK(min_generic_const_args): see lower_anon_const
|
// HACK(min_generic_const_args): see lower_anon_const
|
||||||
if !arg.is_potential_trivial_const_arg() {
|
if !self.tcx.features().const_arg_path || !arg.is_potential_trivial_const_arg() {
|
||||||
// Add a definition for the in-band const def.
|
// Add a definition for the in-band const def.
|
||||||
self.create_def(parent_def_id, node_id, kw::Empty, DefKind::AnonConst, f.span);
|
self.create_def(parent_def_id, node_id, kw::Empty, DefKind::AnonConst, f.span);
|
||||||
}
|
}
|
||||||
|
|
|
@ -237,7 +237,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
});
|
});
|
||||||
let sig = hir::FnSig {
|
let sig = hir::FnSig {
|
||||||
decl,
|
decl,
|
||||||
header: this.lower_fn_header(*header),
|
header: this.lower_fn_header(*header, hir::Safety::Safe),
|
||||||
span: this.lower_span(*fn_sig_span),
|
span: this.lower_span(*fn_sig_span),
|
||||||
};
|
};
|
||||||
hir::ItemKind::Fn(sig, generics, body_id)
|
hir::ItemKind::Fn(sig, generics, body_id)
|
||||||
|
@ -668,7 +668,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
ForeignItemKind::Fn(box Fn { sig, generics, .. }) => {
|
ForeignItemKind::Fn(box Fn { sig, generics, .. }) => {
|
||||||
let fdec = &sig.decl;
|
let fdec = &sig.decl;
|
||||||
let itctx = ImplTraitContext::Universal;
|
let itctx = ImplTraitContext::Universal;
|
||||||
let (generics, (fn_dec, fn_args)) =
|
let (generics, (decl, fn_args)) =
|
||||||
self.lower_generics(generics, Const::No, false, i.id, itctx, |this| {
|
self.lower_generics(generics, Const::No, false, i.id, itctx, |this| {
|
||||||
(
|
(
|
||||||
// Disallow `impl Trait` in foreign items.
|
// Disallow `impl Trait` in foreign items.
|
||||||
|
@ -682,9 +682,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
this.lower_fn_params_to_names(fdec),
|
this.lower_fn_params_to_names(fdec),
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
let safety = self.lower_safety(sig.header.safety, hir::Safety::Unsafe);
|
|
||||||
|
|
||||||
hir::ForeignItemKind::Fn(fn_dec, fn_args, generics, safety)
|
// Unmarked safety in unsafe block defaults to unsafe.
|
||||||
|
let header = self.lower_fn_header(sig.header, hir::Safety::Unsafe);
|
||||||
|
|
||||||
|
hir::ForeignItemKind::Fn(
|
||||||
|
hir::FnSig { header, decl, span: self.lower_span(sig.span) },
|
||||||
|
fn_args,
|
||||||
|
generics,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
ForeignItemKind::Static(box StaticItem { ty, mutability, expr: _, safety }) => {
|
ForeignItemKind::Static(box StaticItem { ty, mutability, expr: _, safety }) => {
|
||||||
let ty = self
|
let ty = self
|
||||||
|
@ -758,18 +764,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
&mut self,
|
&mut self,
|
||||||
(index, f): (usize, &FieldDef),
|
(index, f): (usize, &FieldDef),
|
||||||
) -> hir::FieldDef<'hir> {
|
) -> hir::FieldDef<'hir> {
|
||||||
let ty = if let TyKind::Path(qself, path) = &f.ty.kind {
|
let ty = self.lower_ty(&f.ty, ImplTraitContext::Disallowed(ImplTraitPosition::FieldTy));
|
||||||
let t = self.lower_path_ty(
|
|
||||||
&f.ty,
|
|
||||||
qself,
|
|
||||||
path,
|
|
||||||
ParamMode::ExplicitNamed, // no `'_` in declarations (Issue #61124)
|
|
||||||
ImplTraitContext::Disallowed(ImplTraitPosition::FieldTy),
|
|
||||||
);
|
|
||||||
self.arena.alloc(t)
|
|
||||||
} else {
|
|
||||||
self.lower_ty(&f.ty, ImplTraitContext::Disallowed(ImplTraitPosition::FieldTy))
|
|
||||||
};
|
|
||||||
let hir_id = self.lower_node_id(f.id);
|
let hir_id = self.lower_node_id(f.id);
|
||||||
self.lower_attrs(hir_id, &f.attrs);
|
self.lower_attrs(hir_id, &f.attrs);
|
||||||
hir::FieldDef {
|
hir::FieldDef {
|
||||||
|
@ -1182,7 +1177,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
/// into the body. This is to make sure that the future actually owns the
|
/// into the body. This is to make sure that the future actually owns the
|
||||||
/// arguments that are passed to the function, and to ensure things like
|
/// arguments that are passed to the function, and to ensure things like
|
||||||
/// drop order are stable.
|
/// drop order are stable.
|
||||||
pub fn lower_coroutine_body_with_moved_arguments(
|
pub(crate) fn lower_coroutine_body_with_moved_arguments(
|
||||||
&mut self,
|
&mut self,
|
||||||
decl: &FnDecl,
|
decl: &FnDecl,
|
||||||
lower_body: impl FnOnce(&mut LoweringContext<'_, 'hir>) -> hir::Expr<'hir>,
|
lower_body: impl FnOnce(&mut LoweringContext<'_, 'hir>) -> hir::Expr<'hir>,
|
||||||
|
@ -1390,7 +1385,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
coroutine_kind: Option<CoroutineKind>,
|
coroutine_kind: Option<CoroutineKind>,
|
||||||
parent_constness: Const,
|
parent_constness: Const,
|
||||||
) -> (&'hir hir::Generics<'hir>, hir::FnSig<'hir>) {
|
) -> (&'hir hir::Generics<'hir>, hir::FnSig<'hir>) {
|
||||||
let header = self.lower_fn_header(sig.header);
|
let header = self.lower_fn_header(sig.header, hir::Safety::Safe);
|
||||||
// Don't pass along the user-provided constness of trait associated functions; we don't want to
|
// Don't pass along the user-provided constness of trait associated functions; we don't want to
|
||||||
// synthesize a host effect param for them. We reject `const` on them during AST validation.
|
// synthesize a host effect param for them. We reject `const` on them during AST validation.
|
||||||
let constness =
|
let constness =
|
||||||
|
@ -1403,15 +1398,19 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
(generics, hir::FnSig { header, decl, span: self.lower_span(sig.span) })
|
(generics, hir::FnSig { header, decl, span: self.lower_span(sig.span) })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn lower_fn_header(&mut self, h: FnHeader) -> hir::FnHeader {
|
pub(super) fn lower_fn_header(
|
||||||
|
&mut self,
|
||||||
|
h: FnHeader,
|
||||||
|
default_safety: hir::Safety,
|
||||||
|
) -> hir::FnHeader {
|
||||||
let asyncness = if let Some(CoroutineKind::Async { span, .. }) = h.coroutine_kind {
|
let asyncness = if let Some(CoroutineKind::Async { span, .. }) = h.coroutine_kind {
|
||||||
hir::IsAsync::Async(span)
|
hir::IsAsync::Async(span)
|
||||||
} else {
|
} else {
|
||||||
hir::IsAsync::NotAsync
|
hir::IsAsync::NotAsync
|
||||||
};
|
};
|
||||||
hir::FnHeader {
|
hir::FnHeader {
|
||||||
safety: self.lower_safety(h.safety, hir::Safety::Safe),
|
safety: self.lower_safety(h.safety, default_safety),
|
||||||
asyncness: asyncness,
|
asyncness,
|
||||||
constness: self.lower_constness(h.constness),
|
constness: self.lower_constness(h.constness),
|
||||||
abi: self.lower_extern(h.ext),
|
abi: self.lower_extern(h.ext),
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
#![feature(box_patterns)]
|
#![feature(box_patterns)]
|
||||||
#![feature(let_chains)]
|
#![feature(let_chains)]
|
||||||
#![feature(rustdoc_internals)]
|
#![feature(rustdoc_internals)]
|
||||||
|
#![warn(unreachable_pub)]
|
||||||
// tidy-alphabetical-end
|
// tidy-alphabetical-end
|
||||||
|
|
||||||
use std::collections::hash_map::Entry;
|
use std::collections::hash_map::Entry;
|
||||||
|
@ -481,13 +482,11 @@ pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> hir::Crate<'_> {
|
||||||
enum ParamMode {
|
enum ParamMode {
|
||||||
/// Any path in a type context.
|
/// Any path in a type context.
|
||||||
Explicit,
|
Explicit,
|
||||||
/// Path in a type definition, where the anonymous lifetime `'_` is not allowed.
|
|
||||||
ExplicitNamed,
|
|
||||||
/// The `module::Type` in `module::Type::method` in an expression.
|
/// The `module::Type` in `module::Type::method` in an expression.
|
||||||
Optional,
|
Optional,
|
||||||
}
|
}
|
||||||
|
|
||||||
enum ParenthesizedGenericArgs {
|
enum GenericArgsMode {
|
||||||
ParenSugar,
|
ParenSugar,
|
||||||
Err,
|
Err,
|
||||||
}
|
}
|
||||||
|
@ -2358,7 +2357,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
span: Span,
|
span: Span,
|
||||||
) -> &'hir hir::ConstArg<'hir> {
|
) -> &'hir hir::ConstArg<'hir> {
|
||||||
let ct_kind = match res {
|
let ct_kind = match res {
|
||||||
Res::Def(DefKind::ConstParam, _) => {
|
Res::Def(DefKind::ConstParam, _) if self.tcx.features().const_arg_path => {
|
||||||
let qpath = self.lower_qpath(
|
let qpath = self.lower_qpath(
|
||||||
ty_id,
|
ty_id,
|
||||||
&None,
|
&None,
|
||||||
|
@ -2433,7 +2432,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
self.resolver.get_partial_res(expr.id).and_then(|partial_res| partial_res.full_res());
|
self.resolver.get_partial_res(expr.id).and_then(|partial_res| partial_res.full_res());
|
||||||
debug!("res={:?}", maybe_res);
|
debug!("res={:?}", maybe_res);
|
||||||
// FIXME(min_generic_const_args): for now we only lower params to ConstArgKind::Path
|
// FIXME(min_generic_const_args): for now we only lower params to ConstArgKind::Path
|
||||||
if let Some(res) = maybe_res
|
if self.tcx.features().const_arg_path
|
||||||
|
&& let Some(res) = maybe_res
|
||||||
&& let Res::Def(DefKind::ConstParam, _) = res
|
&& let Res::Def(DefKind::ConstParam, _) = res
|
||||||
&& let ExprKind::Path(qself, path) = &expr.kind
|
&& let ExprKind::Path(qself, path) = &expr.kind
|
||||||
{
|
{
|
||||||
|
@ -2464,7 +2464,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
/// See [`hir::ConstArg`] for when to use this function vs
|
/// See [`hir::ConstArg`] for when to use this function vs
|
||||||
/// [`Self::lower_anon_const_to_const_arg`].
|
/// [`Self::lower_anon_const_to_const_arg`].
|
||||||
fn lower_anon_const_to_anon_const(&mut self, c: &AnonConst) -> &'hir hir::AnonConst {
|
fn lower_anon_const_to_anon_const(&mut self, c: &AnonConst) -> &'hir hir::AnonConst {
|
||||||
if c.value.is_potential_trivial_const_arg() {
|
if self.tcx.features().const_arg_path && c.value.is_potential_trivial_const_arg() {
|
||||||
// HACK(min_generic_const_args): see DefCollector::visit_anon_const
|
// HACK(min_generic_const_args): see DefCollector::visit_anon_const
|
||||||
// Over there, we guess if this is a bare param and only create a def if
|
// Over there, we guess if this is a bare param and only create a def if
|
||||||
// we think it's not. However we may can guess wrong (see there for example)
|
// we think it's not. However we may can guess wrong (see there for example)
|
||||||
|
|
|
@ -15,8 +15,8 @@ use super::errors::{
|
||||||
GenericTypeWithParentheses, UseAngleBrackets,
|
GenericTypeWithParentheses, UseAngleBrackets,
|
||||||
};
|
};
|
||||||
use super::{
|
use super::{
|
||||||
GenericArgsCtor, ImplTraitContext, LifetimeRes, LoweringContext, ParamMode,
|
GenericArgsCtor, GenericArgsMode, ImplTraitContext, LifetimeRes, LoweringContext, ParamMode,
|
||||||
ParenthesizedGenericArgs, ResolverAstLoweringExt,
|
ResolverAstLoweringExt,
|
||||||
};
|
};
|
||||||
use crate::ImplTraitPosition;
|
use crate::ImplTraitPosition;
|
||||||
|
|
||||||
|
@ -90,10 +90,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
_ => param_mode,
|
_ => param_mode,
|
||||||
};
|
};
|
||||||
|
|
||||||
let parenthesized_generic_args = match base_res {
|
let generic_args_mode = match base_res {
|
||||||
// `a::b::Trait(Args)`
|
// `a::b::Trait(Args)`
|
||||||
Res::Def(DefKind::Trait, _) if i + 1 == proj_start => {
|
Res::Def(DefKind::Trait, _) if i + 1 == proj_start => {
|
||||||
ParenthesizedGenericArgs::ParenSugar
|
GenericArgsMode::ParenSugar
|
||||||
}
|
}
|
||||||
// `a::b::Trait(Args)::TraitItem`
|
// `a::b::Trait(Args)::TraitItem`
|
||||||
Res::Def(DefKind::AssocFn, _)
|
Res::Def(DefKind::AssocFn, _)
|
||||||
|
@ -101,19 +101,19 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
| Res::Def(DefKind::AssocTy, _)
|
| Res::Def(DefKind::AssocTy, _)
|
||||||
if i + 2 == proj_start =>
|
if i + 2 == proj_start =>
|
||||||
{
|
{
|
||||||
ParenthesizedGenericArgs::ParenSugar
|
GenericArgsMode::ParenSugar
|
||||||
}
|
}
|
||||||
// Avoid duplicated errors.
|
// Avoid duplicated errors.
|
||||||
Res::Err => ParenthesizedGenericArgs::ParenSugar,
|
Res::Err => GenericArgsMode::ParenSugar,
|
||||||
// An error
|
// An error
|
||||||
_ => ParenthesizedGenericArgs::Err,
|
_ => GenericArgsMode::Err,
|
||||||
};
|
};
|
||||||
|
|
||||||
self.lower_path_segment(
|
self.lower_path_segment(
|
||||||
p.span,
|
p.span,
|
||||||
segment,
|
segment,
|
||||||
param_mode,
|
param_mode,
|
||||||
parenthesized_generic_args,
|
generic_args_mode,
|
||||||
itctx,
|
itctx,
|
||||||
bound_modifier_allowed_features.clone(),
|
bound_modifier_allowed_features.clone(),
|
||||||
)
|
)
|
||||||
|
@ -168,7 +168,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
p.span,
|
p.span,
|
||||||
segment,
|
segment,
|
||||||
param_mode,
|
param_mode,
|
||||||
ParenthesizedGenericArgs::Err,
|
GenericArgsMode::Err,
|
||||||
itctx,
|
itctx,
|
||||||
None,
|
None,
|
||||||
));
|
));
|
||||||
|
@ -210,7 +210,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
p.span,
|
p.span,
|
||||||
segment,
|
segment,
|
||||||
param_mode,
|
param_mode,
|
||||||
ParenthesizedGenericArgs::Err,
|
GenericArgsMode::Err,
|
||||||
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
|
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
|
||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
|
@ -224,7 +224,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
path_span: Span,
|
path_span: Span,
|
||||||
segment: &PathSegment,
|
segment: &PathSegment,
|
||||||
param_mode: ParamMode,
|
param_mode: ParamMode,
|
||||||
parenthesized_generic_args: ParenthesizedGenericArgs,
|
generic_args_mode: GenericArgsMode,
|
||||||
itctx: ImplTraitContext,
|
itctx: ImplTraitContext,
|
||||||
// Additional features ungated with a bound modifier like `async`.
|
// Additional features ungated with a bound modifier like `async`.
|
||||||
// This is passed down to the implicit associated type binding in
|
// This is passed down to the implicit associated type binding in
|
||||||
|
@ -237,14 +237,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
GenericArgs::AngleBracketed(data) => {
|
GenericArgs::AngleBracketed(data) => {
|
||||||
self.lower_angle_bracketed_parameter_data(data, param_mode, itctx)
|
self.lower_angle_bracketed_parameter_data(data, param_mode, itctx)
|
||||||
}
|
}
|
||||||
GenericArgs::Parenthesized(data) => match parenthesized_generic_args {
|
GenericArgs::Parenthesized(data) => match generic_args_mode {
|
||||||
ParenthesizedGenericArgs::ParenSugar => self
|
GenericArgsMode::ParenSugar => self.lower_parenthesized_parameter_data(
|
||||||
.lower_parenthesized_parameter_data(
|
data,
|
||||||
data,
|
itctx,
|
||||||
itctx,
|
bound_modifier_allowed_features,
|
||||||
bound_modifier_allowed_features,
|
),
|
||||||
),
|
GenericArgsMode::Err => {
|
||||||
ParenthesizedGenericArgs::Err => {
|
|
||||||
// Suggest replacing parentheses with angle brackets `Trait(params...)` to `Trait<params...>`
|
// Suggest replacing parentheses with angle brackets `Trait(params...)` to `Trait<params...>`
|
||||||
let sub = if !data.inputs.is_empty() {
|
let sub = if !data.inputs.is_empty() {
|
||||||
// Start of the span to the 1st character of 1st argument
|
// Start of the span to the 1st character of 1st argument
|
||||||
|
|
|
@ -562,10 +562,8 @@ impl<'a> AstValidator<'a> {
|
||||||
FnHeader { safety: _, coroutine_kind, constness, ext }: FnHeader,
|
FnHeader { safety: _, coroutine_kind, constness, ext }: FnHeader,
|
||||||
) {
|
) {
|
||||||
let report_err = |span| {
|
let report_err = |span| {
|
||||||
self.dcx().emit_err(errors::FnQualifierInExtern {
|
self.dcx()
|
||||||
span: span,
|
.emit_err(errors::FnQualifierInExtern { span, block: self.current_extern_span() });
|
||||||
block: self.current_extern_span(),
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
match coroutine_kind {
|
match coroutine_kind {
|
||||||
Some(knd) => report_err(knd.span()),
|
Some(knd) => report_err(knd.span()),
|
||||||
|
@ -887,7 +885,7 @@ fn validate_generic_param_order(dcx: DiagCtxtHandle<'_>, generics: &[GenericPara
|
||||||
|
|
||||||
impl<'a> Visitor<'a> for AstValidator<'a> {
|
impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||||
fn visit_attribute(&mut self, attr: &Attribute) {
|
fn visit_attribute(&mut self, attr: &Attribute) {
|
||||||
validate_attr::check_attr(&self.features, &self.session.psess, attr);
|
validate_attr::check_attr(&self.session.psess, attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_ty(&mut self, ty: &'a Ty) {
|
fn visit_ty(&mut self, ty: &'a Ty) {
|
||||||
|
@ -963,14 +961,13 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||||
self_ty,
|
self_ty,
|
||||||
items,
|
items,
|
||||||
}) => {
|
}) => {
|
||||||
let error =
|
let error = |annotation_span, annotation, only_trait| errors::InherentImplCannot {
|
||||||
|annotation_span, annotation, only_trait: bool| errors::InherentImplCannot {
|
span: self_ty.span,
|
||||||
span: self_ty.span,
|
annotation_span,
|
||||||
annotation_span,
|
annotation,
|
||||||
annotation,
|
self_ty: self_ty.span,
|
||||||
self_ty: self_ty.span,
|
only_trait,
|
||||||
only_trait: only_trait.then_some(()),
|
};
|
||||||
};
|
|
||||||
|
|
||||||
self.with_in_trait_impl(None, |this| {
|
self.with_in_trait_impl(None, |this| {
|
||||||
this.visibility_not_permitted(
|
this.visibility_not_permitted(
|
||||||
|
@ -1195,7 +1192,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||||
} else if where_clauses.after.has_where_token {
|
} else if where_clauses.after.has_where_token {
|
||||||
self.dcx().emit_err(errors::WhereClauseAfterTypeAlias {
|
self.dcx().emit_err(errors::WhereClauseAfterTypeAlias {
|
||||||
span: where_clauses.after.span,
|
span: where_clauses.after.span,
|
||||||
help: self.session.is_nightly_build().then_some(()),
|
help: self.session.is_nightly_build(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ use crate::fluent_generated as fluent;
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_visibility_not_permitted, code = E0449)]
|
#[diag(ast_passes_visibility_not_permitted, code = E0449)]
|
||||||
pub struct VisibilityNotPermitted {
|
pub(crate) struct VisibilityNotPermitted {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
#[subdiagnostic]
|
#[subdiagnostic]
|
||||||
|
@ -25,7 +25,7 @@ pub struct VisibilityNotPermitted {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Subdiagnostic)]
|
#[derive(Subdiagnostic)]
|
||||||
pub enum VisibilityNotPermittedNote {
|
pub(crate) enum VisibilityNotPermittedNote {
|
||||||
#[note(ast_passes_enum_variant)]
|
#[note(ast_passes_enum_variant)]
|
||||||
EnumVariant,
|
EnumVariant,
|
||||||
#[note(ast_passes_trait_impl)]
|
#[note(ast_passes_trait_impl)]
|
||||||
|
@ -38,7 +38,7 @@ pub enum VisibilityNotPermittedNote {
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_trait_fn_const, code = E0379)]
|
#[diag(ast_passes_trait_fn_const, code = E0379)]
|
||||||
pub struct TraitFnConst {
|
pub(crate) struct TraitFnConst {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
#[label]
|
#[label]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
|
@ -64,21 +64,21 @@ pub struct TraitFnConst {
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_forbidden_bound)]
|
#[diag(ast_passes_forbidden_bound)]
|
||||||
pub struct ForbiddenBound {
|
pub(crate) struct ForbiddenBound {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub spans: Vec<Span>,
|
pub spans: Vec<Span>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_forbidden_const_param)]
|
#[diag(ast_passes_forbidden_const_param)]
|
||||||
pub struct ForbiddenConstParam {
|
pub(crate) struct ForbiddenConstParam {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub const_param_spans: Vec<Span>,
|
pub const_param_spans: Vec<Span>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_fn_param_too_many)]
|
#[diag(ast_passes_fn_param_too_many)]
|
||||||
pub struct FnParamTooMany {
|
pub(crate) struct FnParamTooMany {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
pub max_num_args: usize,
|
pub max_num_args: usize,
|
||||||
|
@ -86,14 +86,14 @@ pub struct FnParamTooMany {
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_fn_param_c_var_args_not_last)]
|
#[diag(ast_passes_fn_param_c_var_args_not_last)]
|
||||||
pub struct FnParamCVarArgsNotLast {
|
pub(crate) struct FnParamCVarArgsNotLast {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_fn_param_doc_comment)]
|
#[diag(ast_passes_fn_param_doc_comment)]
|
||||||
pub struct FnParamDocComment {
|
pub(crate) struct FnParamDocComment {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
#[label]
|
#[label]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
|
@ -101,7 +101,7 @@ pub struct FnParamDocComment {
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_fn_param_forbidden_attr)]
|
#[diag(ast_passes_fn_param_forbidden_attr)]
|
||||||
pub struct FnParamForbiddenAttr {
|
pub(crate) struct FnParamForbiddenAttr {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
@ -109,7 +109,7 @@ pub struct FnParamForbiddenAttr {
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_fn_param_forbidden_self)]
|
#[diag(ast_passes_fn_param_forbidden_self)]
|
||||||
#[note]
|
#[note]
|
||||||
pub struct FnParamForbiddenSelf {
|
pub(crate) struct FnParamForbiddenSelf {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
#[label]
|
#[label]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
|
@ -117,7 +117,7 @@ pub struct FnParamForbiddenSelf {
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_forbidden_default)]
|
#[diag(ast_passes_forbidden_default)]
|
||||||
pub struct ForbiddenDefault {
|
pub(crate) struct ForbiddenDefault {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
#[label]
|
#[label]
|
||||||
|
@ -126,7 +126,7 @@ pub struct ForbiddenDefault {
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_assoc_const_without_body)]
|
#[diag(ast_passes_assoc_const_without_body)]
|
||||||
pub struct AssocConstWithoutBody {
|
pub(crate) struct AssocConstWithoutBody {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
#[suggestion(code = " = <expr>;", applicability = "has-placeholders")]
|
#[suggestion(code = " = <expr>;", applicability = "has-placeholders")]
|
||||||
|
@ -135,7 +135,7 @@ pub struct AssocConstWithoutBody {
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_assoc_fn_without_body)]
|
#[diag(ast_passes_assoc_fn_without_body)]
|
||||||
pub struct AssocFnWithoutBody {
|
pub(crate) struct AssocFnWithoutBody {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
#[suggestion(code = " {{ <body> }}", applicability = "has-placeholders")]
|
#[suggestion(code = " {{ <body> }}", applicability = "has-placeholders")]
|
||||||
|
@ -144,7 +144,7 @@ pub struct AssocFnWithoutBody {
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_assoc_type_without_body)]
|
#[diag(ast_passes_assoc_type_without_body)]
|
||||||
pub struct AssocTypeWithoutBody {
|
pub(crate) struct AssocTypeWithoutBody {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
#[suggestion(code = " = <type>;", applicability = "has-placeholders")]
|
#[suggestion(code = " = <type>;", applicability = "has-placeholders")]
|
||||||
|
@ -153,7 +153,7 @@ pub struct AssocTypeWithoutBody {
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_const_without_body)]
|
#[diag(ast_passes_const_without_body)]
|
||||||
pub struct ConstWithoutBody {
|
pub(crate) struct ConstWithoutBody {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
#[suggestion(code = " = <expr>;", applicability = "has-placeholders")]
|
#[suggestion(code = " = <expr>;", applicability = "has-placeholders")]
|
||||||
|
@ -162,7 +162,7 @@ pub struct ConstWithoutBody {
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_static_without_body)]
|
#[diag(ast_passes_static_without_body)]
|
||||||
pub struct StaticWithoutBody {
|
pub(crate) struct StaticWithoutBody {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
#[suggestion(code = " = <expr>;", applicability = "has-placeholders")]
|
#[suggestion(code = " = <expr>;", applicability = "has-placeholders")]
|
||||||
|
@ -171,7 +171,7 @@ pub struct StaticWithoutBody {
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_ty_alias_without_body)]
|
#[diag(ast_passes_ty_alias_without_body)]
|
||||||
pub struct TyAliasWithoutBody {
|
pub(crate) struct TyAliasWithoutBody {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
#[suggestion(code = " = <type>;", applicability = "has-placeholders")]
|
#[suggestion(code = " = <type>;", applicability = "has-placeholders")]
|
||||||
|
@ -180,7 +180,7 @@ pub struct TyAliasWithoutBody {
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_fn_without_body)]
|
#[diag(ast_passes_fn_without_body)]
|
||||||
pub struct FnWithoutBody {
|
pub(crate) struct FnWithoutBody {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
#[suggestion(code = " {{ <body> }}", applicability = "has-placeholders")]
|
#[suggestion(code = " {{ <body> }}", applicability = "has-placeholders")]
|
||||||
|
@ -190,7 +190,7 @@ pub struct FnWithoutBody {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Subdiagnostic)]
|
#[derive(Subdiagnostic)]
|
||||||
pub enum ExternBlockSuggestion {
|
pub(crate) enum ExternBlockSuggestion {
|
||||||
#[multipart_suggestion(ast_passes_extern_block_suggestion, applicability = "maybe-incorrect")]
|
#[multipart_suggestion(ast_passes_extern_block_suggestion, applicability = "maybe-incorrect")]
|
||||||
Implicit {
|
Implicit {
|
||||||
#[suggestion_part(code = "extern {{")]
|
#[suggestion_part(code = "extern {{")]
|
||||||
|
@ -210,7 +210,7 @@ pub enum ExternBlockSuggestion {
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_extern_invalid_safety)]
|
#[diag(ast_passes_extern_invalid_safety)]
|
||||||
pub struct InvalidSafetyOnExtern {
|
pub(crate) struct InvalidSafetyOnExtern {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub item_span: Span,
|
pub item_span: Span,
|
||||||
#[suggestion(code = "unsafe ", applicability = "machine-applicable", style = "verbose")]
|
#[suggestion(code = "unsafe ", applicability = "machine-applicable", style = "verbose")]
|
||||||
|
@ -219,28 +219,28 @@ pub struct InvalidSafetyOnExtern {
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_item_invalid_safety)]
|
#[diag(ast_passes_item_invalid_safety)]
|
||||||
pub struct InvalidSafetyOnItem {
|
pub(crate) struct InvalidSafetyOnItem {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_bare_fn_invalid_safety)]
|
#[diag(ast_passes_bare_fn_invalid_safety)]
|
||||||
pub struct InvalidSafetyOnBareFn {
|
pub(crate) struct InvalidSafetyOnBareFn {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_unsafe_static)]
|
#[diag(ast_passes_unsafe_static)]
|
||||||
pub struct UnsafeStatic {
|
pub(crate) struct UnsafeStatic {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_bound_in_context)]
|
#[diag(ast_passes_bound_in_context)]
|
||||||
pub struct BoundInContext<'a> {
|
pub(crate) struct BoundInContext<'a> {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
pub ctx: &'a str,
|
pub ctx: &'a str,
|
||||||
|
@ -249,7 +249,7 @@ pub struct BoundInContext<'a> {
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_extern_types_cannot)]
|
#[diag(ast_passes_extern_types_cannot)]
|
||||||
#[note(ast_passes_extern_keyword_link)]
|
#[note(ast_passes_extern_keyword_link)]
|
||||||
pub struct ExternTypesCannotHave<'a> {
|
pub(crate) struct ExternTypesCannotHave<'a> {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
#[suggestion(code = "", applicability = "maybe-incorrect")]
|
#[suggestion(code = "", applicability = "maybe-incorrect")]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
|
@ -262,7 +262,7 @@ pub struct ExternTypesCannotHave<'a> {
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_body_in_extern)]
|
#[diag(ast_passes_body_in_extern)]
|
||||||
#[note(ast_passes_extern_keyword_link)]
|
#[note(ast_passes_extern_keyword_link)]
|
||||||
pub struct BodyInExtern<'a> {
|
pub(crate) struct BodyInExtern<'a> {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
#[label(ast_passes_cannot_have)]
|
#[label(ast_passes_cannot_have)]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
|
@ -277,7 +277,7 @@ pub struct BodyInExtern<'a> {
|
||||||
#[diag(ast_passes_fn_body_extern)]
|
#[diag(ast_passes_fn_body_extern)]
|
||||||
#[help]
|
#[help]
|
||||||
#[note(ast_passes_extern_keyword_link)]
|
#[note(ast_passes_extern_keyword_link)]
|
||||||
pub struct FnBodyInExtern {
|
pub(crate) struct FnBodyInExtern {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
#[label(ast_passes_cannot_have)]
|
#[label(ast_passes_cannot_have)]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
|
@ -289,7 +289,7 @@ pub struct FnBodyInExtern {
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_extern_fn_qualifiers)]
|
#[diag(ast_passes_extern_fn_qualifiers)]
|
||||||
pub struct FnQualifierInExtern {
|
pub(crate) struct FnQualifierInExtern {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
#[suggestion(code = "", applicability = "maybe-incorrect")]
|
#[suggestion(code = "", applicability = "maybe-incorrect")]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
|
@ -300,7 +300,7 @@ pub struct FnQualifierInExtern {
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_extern_item_ascii)]
|
#[diag(ast_passes_extern_item_ascii)]
|
||||||
#[note]
|
#[note]
|
||||||
pub struct ExternItemAscii {
|
pub(crate) struct ExternItemAscii {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
#[label]
|
#[label]
|
||||||
|
@ -309,14 +309,14 @@ pub struct ExternItemAscii {
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_bad_c_variadic)]
|
#[diag(ast_passes_bad_c_variadic)]
|
||||||
pub struct BadCVariadic {
|
pub(crate) struct BadCVariadic {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Vec<Span>,
|
pub span: Vec<Span>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_item_underscore)]
|
#[diag(ast_passes_item_underscore)]
|
||||||
pub struct ItemUnderscore<'a> {
|
pub(crate) struct ItemUnderscore<'a> {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
#[label]
|
#[label]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
|
@ -325,7 +325,7 @@ pub struct ItemUnderscore<'a> {
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_nomangle_ascii, code = E0754)]
|
#[diag(ast_passes_nomangle_ascii, code = E0754)]
|
||||||
pub struct NoMangleAscii {
|
pub(crate) struct NoMangleAscii {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
@ -333,7 +333,7 @@ pub struct NoMangleAscii {
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_module_nonascii, code = E0754)]
|
#[diag(ast_passes_module_nonascii, code = E0754)]
|
||||||
#[help]
|
#[help]
|
||||||
pub struct ModuleNonAscii {
|
pub(crate) struct ModuleNonAscii {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
pub name: Symbol,
|
pub name: Symbol,
|
||||||
|
@ -341,7 +341,7 @@ pub struct ModuleNonAscii {
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_auto_generic, code = E0567)]
|
#[diag(ast_passes_auto_generic, code = E0567)]
|
||||||
pub struct AutoTraitGeneric {
|
pub(crate) struct AutoTraitGeneric {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
#[suggestion(code = "", applicability = "machine-applicable")]
|
#[suggestion(code = "", applicability = "machine-applicable")]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
|
@ -351,7 +351,7 @@ pub struct AutoTraitGeneric {
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_auto_super_lifetime, code = E0568)]
|
#[diag(ast_passes_auto_super_lifetime, code = E0568)]
|
||||||
pub struct AutoTraitBounds {
|
pub(crate) struct AutoTraitBounds {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
#[suggestion(code = "", applicability = "machine-applicable")]
|
#[suggestion(code = "", applicability = "machine-applicable")]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
|
@ -361,7 +361,7 @@ pub struct AutoTraitBounds {
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_auto_items, code = E0380)]
|
#[diag(ast_passes_auto_items, code = E0380)]
|
||||||
pub struct AutoTraitItems {
|
pub(crate) struct AutoTraitItems {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub spans: Vec<Span>,
|
pub spans: Vec<Span>,
|
||||||
#[suggestion(code = "", applicability = "machine-applicable")]
|
#[suggestion(code = "", applicability = "machine-applicable")]
|
||||||
|
@ -372,7 +372,7 @@ pub struct AutoTraitItems {
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_generic_before_constraints)]
|
#[diag(ast_passes_generic_before_constraints)]
|
||||||
pub struct ArgsBeforeConstraint {
|
pub(crate) struct ArgsBeforeConstraint {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub arg_spans: Vec<Span>,
|
pub arg_spans: Vec<Span>,
|
||||||
#[label(ast_passes_constraints)]
|
#[label(ast_passes_constraints)]
|
||||||
|
@ -390,7 +390,7 @@ pub struct ArgsBeforeConstraint {
|
||||||
pub arg_spans2: EmptyLabelManySpans,
|
pub arg_spans2: EmptyLabelManySpans,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct EmptyLabelManySpans(pub Vec<Span>);
|
pub(crate) struct EmptyLabelManySpans(pub Vec<Span>);
|
||||||
|
|
||||||
// The derive for `Vec<Span>` does multiple calls to `span_label`, adding commas between each
|
// The derive for `Vec<Span>` does multiple calls to `span_label`, adding commas between each
|
||||||
impl Subdiagnostic for EmptyLabelManySpans {
|
impl Subdiagnostic for EmptyLabelManySpans {
|
||||||
|
@ -405,28 +405,28 @@ impl Subdiagnostic for EmptyLabelManySpans {
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_pattern_in_fn_pointer, code = E0561)]
|
#[diag(ast_passes_pattern_in_fn_pointer, code = E0561)]
|
||||||
pub struct PatternFnPointer {
|
pub(crate) struct PatternFnPointer {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_trait_object_single_bound, code = E0226)]
|
#[diag(ast_passes_trait_object_single_bound, code = E0226)]
|
||||||
pub struct TraitObjectBound {
|
pub(crate) struct TraitObjectBound {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_impl_trait_path, code = E0667)]
|
#[diag(ast_passes_impl_trait_path, code = E0667)]
|
||||||
pub struct ImplTraitPath {
|
pub(crate) struct ImplTraitPath {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_nested_impl_trait, code = E0666)]
|
#[diag(ast_passes_nested_impl_trait, code = E0666)]
|
||||||
pub struct NestedImplTrait {
|
pub(crate) struct NestedImplTrait {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
#[label(ast_passes_outer)]
|
#[label(ast_passes_outer)]
|
||||||
|
@ -437,14 +437,14 @@ pub struct NestedImplTrait {
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_at_least_one_trait)]
|
#[diag(ast_passes_at_least_one_trait)]
|
||||||
pub struct AtLeastOneTrait {
|
pub(crate) struct AtLeastOneTrait {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_out_of_order_params)]
|
#[diag(ast_passes_out_of_order_params)]
|
||||||
pub struct OutOfOrderParams<'a> {
|
pub(crate) struct OutOfOrderParams<'a> {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub spans: Vec<Span>,
|
pub spans: Vec<Span>,
|
||||||
#[suggestion(code = "{ordered_params}", applicability = "machine-applicable")]
|
#[suggestion(code = "{ordered_params}", applicability = "machine-applicable")]
|
||||||
|
@ -457,14 +457,14 @@ pub struct OutOfOrderParams<'a> {
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_obsolete_auto)]
|
#[diag(ast_passes_obsolete_auto)]
|
||||||
#[help]
|
#[help]
|
||||||
pub struct ObsoleteAuto {
|
pub(crate) struct ObsoleteAuto {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_unsafe_negative_impl, code = E0198)]
|
#[diag(ast_passes_unsafe_negative_impl, code = E0198)]
|
||||||
pub struct UnsafeNegativeImpl {
|
pub(crate) struct UnsafeNegativeImpl {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
#[label(ast_passes_negative)]
|
#[label(ast_passes_negative)]
|
||||||
|
@ -475,7 +475,7 @@ pub struct UnsafeNegativeImpl {
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_inherent_cannot_be)]
|
#[diag(ast_passes_inherent_cannot_be)]
|
||||||
pub struct InherentImplCannot<'a> {
|
pub(crate) struct InherentImplCannot<'a> {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
#[label(ast_passes_because)]
|
#[label(ast_passes_because)]
|
||||||
|
@ -484,12 +484,12 @@ pub struct InherentImplCannot<'a> {
|
||||||
#[label(ast_passes_type)]
|
#[label(ast_passes_type)]
|
||||||
pub self_ty: Span,
|
pub self_ty: Span,
|
||||||
#[note(ast_passes_only_trait)]
|
#[note(ast_passes_only_trait)]
|
||||||
pub only_trait: Option<()>,
|
pub only_trait: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_inherent_cannot_be, code = E0197)]
|
#[diag(ast_passes_inherent_cannot_be, code = E0197)]
|
||||||
pub struct InherentImplCannotUnsafe<'a> {
|
pub(crate) struct InherentImplCannotUnsafe<'a> {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
#[label(ast_passes_because)]
|
#[label(ast_passes_because)]
|
||||||
|
@ -501,7 +501,7 @@ pub struct InherentImplCannotUnsafe<'a> {
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_unsafe_item)]
|
#[diag(ast_passes_unsafe_item)]
|
||||||
pub struct UnsafeItem {
|
pub(crate) struct UnsafeItem {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
pub kind: &'static str,
|
pub kind: &'static str,
|
||||||
|
@ -509,14 +509,14 @@ pub struct UnsafeItem {
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_missing_unsafe_on_extern)]
|
#[diag(ast_passes_missing_unsafe_on_extern)]
|
||||||
pub struct MissingUnsafeOnExtern {
|
pub(crate) struct MissingUnsafeOnExtern {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_fieldless_union)]
|
#[diag(ast_passes_fieldless_union)]
|
||||||
pub struct FieldlessUnion {
|
pub(crate) struct FieldlessUnion {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
@ -524,17 +524,17 @@ pub struct FieldlessUnion {
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_where_clause_after_type_alias)]
|
#[diag(ast_passes_where_clause_after_type_alias)]
|
||||||
#[note]
|
#[note]
|
||||||
pub struct WhereClauseAfterTypeAlias {
|
pub(crate) struct WhereClauseAfterTypeAlias {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
#[help]
|
#[help]
|
||||||
pub help: Option<()>,
|
pub help: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_where_clause_before_type_alias)]
|
#[diag(ast_passes_where_clause_before_type_alias)]
|
||||||
#[note]
|
#[note]
|
||||||
pub struct WhereClauseBeforeTypeAlias {
|
pub(crate) struct WhereClauseBeforeTypeAlias {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
#[subdiagnostic]
|
#[subdiagnostic]
|
||||||
|
@ -543,7 +543,7 @@ pub struct WhereClauseBeforeTypeAlias {
|
||||||
|
|
||||||
#[derive(Subdiagnostic)]
|
#[derive(Subdiagnostic)]
|
||||||
|
|
||||||
pub enum WhereClauseBeforeTypeAliasSugg {
|
pub(crate) enum WhereClauseBeforeTypeAliasSugg {
|
||||||
#[suggestion(ast_passes_remove_suggestion, applicability = "machine-applicable", code = "")]
|
#[suggestion(ast_passes_remove_suggestion, applicability = "machine-applicable", code = "")]
|
||||||
Remove {
|
Remove {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
|
@ -565,14 +565,14 @@ pub enum WhereClauseBeforeTypeAliasSugg {
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_generic_default_trailing)]
|
#[diag(ast_passes_generic_default_trailing)]
|
||||||
pub struct GenericDefaultTrailing {
|
pub(crate) struct GenericDefaultTrailing {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_nested_lifetimes, code = E0316)]
|
#[diag(ast_passes_nested_lifetimes, code = E0316)]
|
||||||
pub struct NestedLifetimes {
|
pub(crate) struct NestedLifetimes {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
@ -580,7 +580,7 @@ pub struct NestedLifetimes {
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_optional_trait_supertrait)]
|
#[diag(ast_passes_optional_trait_supertrait)]
|
||||||
#[note]
|
#[note]
|
||||||
pub struct OptionalTraitSupertrait {
|
pub(crate) struct OptionalTraitSupertrait {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
pub path_str: String,
|
pub path_str: String,
|
||||||
|
@ -588,14 +588,14 @@ pub struct OptionalTraitSupertrait {
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_optional_trait_object)]
|
#[diag(ast_passes_optional_trait_object)]
|
||||||
pub struct OptionalTraitObject {
|
pub(crate) struct OptionalTraitObject {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_const_bound_trait_object)]
|
#[diag(ast_passes_const_bound_trait_object)]
|
||||||
pub struct ConstBoundTraitObject {
|
pub(crate) struct ConstBoundTraitObject {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
@ -604,7 +604,7 @@ pub struct ConstBoundTraitObject {
|
||||||
// FIXME(effects): Provide structured suggestions (e.g., add `const` / `#[const_trait]` here).
|
// FIXME(effects): Provide structured suggestions (e.g., add `const` / `#[const_trait]` here).
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_tilde_const_disallowed)]
|
#[diag(ast_passes_tilde_const_disallowed)]
|
||||||
pub struct TildeConstDisallowed {
|
pub(crate) struct TildeConstDisallowed {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
#[subdiagnostic]
|
#[subdiagnostic]
|
||||||
|
@ -612,7 +612,7 @@ pub struct TildeConstDisallowed {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Subdiagnostic, Copy, Clone)]
|
#[derive(Subdiagnostic, Copy, Clone)]
|
||||||
pub enum TildeConstReason {
|
pub(crate) enum TildeConstReason {
|
||||||
#[note(ast_passes_closure)]
|
#[note(ast_passes_closure)]
|
||||||
Closure,
|
Closure,
|
||||||
#[note(ast_passes_function)]
|
#[note(ast_passes_function)]
|
||||||
|
@ -658,7 +658,7 @@ pub enum TildeConstReason {
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_const_and_async)]
|
#[diag(ast_passes_const_and_async)]
|
||||||
pub struct ConstAndAsync {
|
pub(crate) struct ConstAndAsync {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub spans: Vec<Span>,
|
pub spans: Vec<Span>,
|
||||||
#[label(ast_passes_const)]
|
#[label(ast_passes_const)]
|
||||||
|
@ -671,7 +671,7 @@ pub struct ConstAndAsync {
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_const_and_c_variadic)]
|
#[diag(ast_passes_const_and_c_variadic)]
|
||||||
pub struct ConstAndCVariadic {
|
pub(crate) struct ConstAndCVariadic {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub spans: Vec<Span>,
|
pub spans: Vec<Span>,
|
||||||
#[label(ast_passes_const)]
|
#[label(ast_passes_const)]
|
||||||
|
@ -683,7 +683,7 @@ pub struct ConstAndCVariadic {
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_pattern_in_foreign, code = E0130)]
|
#[diag(ast_passes_pattern_in_foreign, code = E0130)]
|
||||||
// FIXME: deduplicate with rustc_lint (`BuiltinLintDiag::PatternsInFnsWithoutBody`)
|
// FIXME: deduplicate with rustc_lint (`BuiltinLintDiag::PatternsInFnsWithoutBody`)
|
||||||
pub struct PatternInForeign {
|
pub(crate) struct PatternInForeign {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
#[label]
|
#[label]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
|
@ -692,7 +692,7 @@ pub struct PatternInForeign {
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_pattern_in_bodiless, code = E0642)]
|
#[diag(ast_passes_pattern_in_bodiless, code = E0642)]
|
||||||
// FIXME: deduplicate with rustc_lint (`BuiltinLintDiag::PatternsInFnsWithoutBody`)
|
// FIXME: deduplicate with rustc_lint (`BuiltinLintDiag::PatternsInFnsWithoutBody`)
|
||||||
pub struct PatternInBodiless {
|
pub(crate) struct PatternInBodiless {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
#[label]
|
#[label]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
|
@ -701,7 +701,7 @@ pub struct PatternInBodiless {
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_equality_in_where)]
|
#[diag(ast_passes_equality_in_where)]
|
||||||
#[note]
|
#[note]
|
||||||
pub struct EqualityInWhere {
|
pub(crate) struct EqualityInWhere {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
#[label]
|
#[label]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
|
@ -718,7 +718,7 @@ pub struct EqualityInWhere {
|
||||||
style = "verbose",
|
style = "verbose",
|
||||||
applicability = "maybe-incorrect"
|
applicability = "maybe-incorrect"
|
||||||
)]
|
)]
|
||||||
pub struct AssociatedSuggestion {
|
pub(crate) struct AssociatedSuggestion {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
pub ident: Ident,
|
pub ident: Ident,
|
||||||
|
@ -728,7 +728,7 @@ pub struct AssociatedSuggestion {
|
||||||
|
|
||||||
#[derive(Subdiagnostic)]
|
#[derive(Subdiagnostic)]
|
||||||
#[multipart_suggestion(ast_passes_suggestion_path, applicability = "maybe-incorrect")]
|
#[multipart_suggestion(ast_passes_suggestion_path, applicability = "maybe-incorrect")]
|
||||||
pub struct AssociatedSuggestion2 {
|
pub(crate) struct AssociatedSuggestion2 {
|
||||||
#[suggestion_part(code = "{args}")]
|
#[suggestion_part(code = "{args}")]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
pub args: String,
|
pub args: String,
|
||||||
|
@ -740,14 +740,14 @@ pub struct AssociatedSuggestion2 {
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_stability_outside_std, code = E0734)]
|
#[diag(ast_passes_stability_outside_std, code = E0734)]
|
||||||
pub struct StabilityOutsideStd {
|
pub(crate) struct StabilityOutsideStd {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_feature_on_non_nightly, code = E0554)]
|
#[diag(ast_passes_feature_on_non_nightly, code = E0554)]
|
||||||
pub struct FeatureOnNonNightly {
|
pub(crate) struct FeatureOnNonNightly {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
pub channel: &'static str,
|
pub channel: &'static str,
|
||||||
|
@ -757,7 +757,7 @@ pub struct FeatureOnNonNightly {
|
||||||
pub sugg: Option<Span>,
|
pub sugg: Option<Span>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct StableFeature {
|
pub(crate) struct StableFeature {
|
||||||
pub name: Symbol,
|
pub name: Symbol,
|
||||||
pub since: Symbol,
|
pub since: Symbol,
|
||||||
}
|
}
|
||||||
|
@ -777,7 +777,7 @@ impl Subdiagnostic for StableFeature {
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_incompatible_features)]
|
#[diag(ast_passes_incompatible_features)]
|
||||||
#[help]
|
#[help]
|
||||||
pub struct IncompatibleFeatures {
|
pub(crate) struct IncompatibleFeatures {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub spans: Vec<Span>,
|
pub spans: Vec<Span>,
|
||||||
pub f1: Symbol,
|
pub f1: Symbol,
|
||||||
|
@ -786,7 +786,7 @@ pub struct IncompatibleFeatures {
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_show_span)]
|
#[diag(ast_passes_show_span)]
|
||||||
pub struct ShowSpan {
|
pub(crate) struct ShowSpan {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
pub msg: &'static str,
|
pub msg: &'static str,
|
||||||
|
@ -794,28 +794,28 @@ pub struct ShowSpan {
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_negative_bound_not_supported)]
|
#[diag(ast_passes_negative_bound_not_supported)]
|
||||||
pub struct NegativeBoundUnsupported {
|
pub(crate) struct NegativeBoundUnsupported {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_constraint_on_negative_bound)]
|
#[diag(ast_passes_constraint_on_negative_bound)]
|
||||||
pub struct ConstraintOnNegativeBound {
|
pub(crate) struct ConstraintOnNegativeBound {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_negative_bound_with_parenthetical_notation)]
|
#[diag(ast_passes_negative_bound_with_parenthetical_notation)]
|
||||||
pub struct NegativeBoundWithParentheticalNotation {
|
pub(crate) struct NegativeBoundWithParentheticalNotation {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_invalid_unnamed_field_ty)]
|
#[diag(ast_passes_invalid_unnamed_field_ty)]
|
||||||
pub struct InvalidUnnamedFieldTy {
|
pub(crate) struct InvalidUnnamedFieldTy {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
#[label]
|
#[label]
|
||||||
|
@ -824,7 +824,7 @@ pub struct InvalidUnnamedFieldTy {
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_invalid_unnamed_field)]
|
#[diag(ast_passes_invalid_unnamed_field)]
|
||||||
pub struct InvalidUnnamedField {
|
pub(crate) struct InvalidUnnamedField {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
#[label]
|
#[label]
|
||||||
|
@ -833,7 +833,7 @@ pub struct InvalidUnnamedField {
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_anon_struct_or_union_not_allowed)]
|
#[diag(ast_passes_anon_struct_or_union_not_allowed)]
|
||||||
pub struct AnonStructOrUnionNotAllowed {
|
pub(crate) struct AnonStructOrUnionNotAllowed {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
#[label]
|
#[label]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
|
@ -842,7 +842,7 @@ pub struct AnonStructOrUnionNotAllowed {
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_match_arm_with_no_body)]
|
#[diag(ast_passes_match_arm_with_no_body)]
|
||||||
pub struct MatchArmWithNoBody {
|
pub(crate) struct MatchArmWithNoBody {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
#[suggestion(code = " => todo!(),", applicability = "has-placeholders")]
|
#[suggestion(code = " => todo!(),", applicability = "has-placeholders")]
|
||||||
|
@ -851,7 +851,7 @@ pub struct MatchArmWithNoBody {
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_precise_capturing_not_allowed_here)]
|
#[diag(ast_passes_precise_capturing_not_allowed_here)]
|
||||||
pub struct PreciseCapturingNotAllowedHere {
|
pub(crate) struct PreciseCapturingNotAllowedHere {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
pub loc: &'static str,
|
pub loc: &'static str,
|
||||||
|
@ -859,7 +859,7 @@ pub struct PreciseCapturingNotAllowedHere {
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_precise_capturing_duplicated)]
|
#[diag(ast_passes_precise_capturing_duplicated)]
|
||||||
pub struct DuplicatePreciseCapturing {
|
pub(crate) struct DuplicatePreciseCapturing {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub bound1: Span,
|
pub bound1: Span,
|
||||||
#[label]
|
#[label]
|
||||||
|
|
|
@ -539,7 +539,6 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gate_all!(gen_blocks, "gen blocks are experimental");
|
gate_all!(gen_blocks, "gen blocks are experimental");
|
||||||
gate_all!(raw_ref_op, "raw address of syntax is experimental");
|
|
||||||
gate_all!(const_trait_impl, "const trait impls are experimental");
|
gate_all!(const_trait_impl, "const trait impls are experimental");
|
||||||
gate_all!(
|
gate_all!(
|
||||||
half_open_range_patterns_in_slices,
|
half_open_range_patterns_in_slices,
|
||||||
|
@ -557,9 +556,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
|
||||||
gate_all!(fn_delegation, "functions delegation is not yet fully implemented");
|
gate_all!(fn_delegation, "functions delegation is not yet fully implemented");
|
||||||
gate_all!(postfix_match, "postfix match is experimental");
|
gate_all!(postfix_match, "postfix match is experimental");
|
||||||
gate_all!(mut_ref, "mutable by-reference bindings are experimental");
|
gate_all!(mut_ref, "mutable by-reference bindings are experimental");
|
||||||
gate_all!(precise_capturing, "precise captures on `impl Trait` are experimental");
|
|
||||||
gate_all!(global_registration, "global registration is experimental");
|
gate_all!(global_registration, "global registration is experimental");
|
||||||
gate_all!(unsafe_attributes, "`#[unsafe()]` markers for attributes are experimental");
|
|
||||||
gate_all!(return_type_notation, "return type notation is experimental");
|
gate_all!(return_type_notation, "return type notation is experimental");
|
||||||
|
|
||||||
if !visitor.features.never_patterns {
|
if !visitor.features.never_patterns {
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#![feature(iter_is_partitioned)]
|
#![feature(iter_is_partitioned)]
|
||||||
#![feature(let_chains)]
|
#![feature(let_chains)]
|
||||||
#![feature(rustdoc_internals)]
|
#![feature(rustdoc_internals)]
|
||||||
|
#![warn(unreachable_pub)]
|
||||||
// tidy-alphabetical-end
|
// tidy-alphabetical-end
|
||||||
|
|
||||||
pub mod ast_validation;
|
pub mod ast_validation;
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#![doc(rust_logo)]
|
#![doc(rust_logo)]
|
||||||
#![feature(box_patterns)]
|
#![feature(box_patterns)]
|
||||||
#![feature(rustdoc_internals)]
|
#![feature(rustdoc_internals)]
|
||||||
|
#![warn(unreachable_pub)]
|
||||||
// tidy-alphabetical-end
|
// tidy-alphabetical-end
|
||||||
|
|
||||||
mod helpers;
|
mod helpers;
|
||||||
|
|
|
@ -89,7 +89,7 @@ impl Printer {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Token {
|
impl Token {
|
||||||
pub fn is_hardbreak_tok(&self) -> bool {
|
pub(crate) fn is_hardbreak_tok(&self) -> bool {
|
||||||
*self == Printer::hardbreak_tok_offset(0)
|
*self == Printer::hardbreak_tok_offset(0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,54 +11,54 @@ use std::ops::{Index, IndexMut};
|
||||||
/// Holding a RingBuffer whose view is elements left..right gives the ability to
|
/// Holding a RingBuffer whose view is elements left..right gives the ability to
|
||||||
/// use Index and IndexMut to access elements i in the infinitely long queue for
|
/// use Index and IndexMut to access elements i in the infinitely long queue for
|
||||||
/// which left <= i < right.
|
/// which left <= i < right.
|
||||||
pub struct RingBuffer<T> {
|
pub(super) struct RingBuffer<T> {
|
||||||
data: VecDeque<T>,
|
data: VecDeque<T>,
|
||||||
// Abstract index of data[0] in the infinitely sized queue.
|
// Abstract index of data[0] in the infinitely sized queue.
|
||||||
offset: usize,
|
offset: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> RingBuffer<T> {
|
impl<T> RingBuffer<T> {
|
||||||
pub fn new() -> Self {
|
pub(super) fn new() -> Self {
|
||||||
RingBuffer { data: VecDeque::new(), offset: 0 }
|
RingBuffer { data: VecDeque::new(), offset: 0 }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_empty(&self) -> bool {
|
pub(super) fn is_empty(&self) -> bool {
|
||||||
self.data.is_empty()
|
self.data.is_empty()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn push(&mut self, value: T) -> usize {
|
pub(super) fn push(&mut self, value: T) -> usize {
|
||||||
let index = self.offset + self.data.len();
|
let index = self.offset + self.data.len();
|
||||||
self.data.push_back(value);
|
self.data.push_back(value);
|
||||||
index
|
index
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clear(&mut self) {
|
pub(super) fn clear(&mut self) {
|
||||||
self.data.clear();
|
self.data.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn index_of_first(&self) -> usize {
|
pub(super) fn index_of_first(&self) -> usize {
|
||||||
self.offset
|
self.offset
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn first(&self) -> Option<&T> {
|
pub(super) fn first(&self) -> Option<&T> {
|
||||||
self.data.front()
|
self.data.front()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn first_mut(&mut self) -> Option<&mut T> {
|
pub(super) fn first_mut(&mut self) -> Option<&mut T> {
|
||||||
self.data.front_mut()
|
self.data.front_mut()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pop_first(&mut self) -> Option<T> {
|
pub(super) fn pop_first(&mut self) -> Option<T> {
|
||||||
let first = self.data.pop_front()?;
|
let first = self.data.pop_front()?;
|
||||||
self.offset += 1;
|
self.offset += 1;
|
||||||
Some(first)
|
Some(first)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn last(&self) -> Option<&T> {
|
pub(super) fn last(&self) -> Option<&T> {
|
||||||
self.data.back()
|
self.data.back()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn last_mut(&mut self) -> Option<&mut T> {
|
pub(super) fn last_mut(&mut self) -> Option<&mut T> {
|
||||||
self.data.back_mut()
|
self.data.back_mut()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -110,13 +110,13 @@ impl Default for FixupContext {
|
||||||
impl FixupContext {
|
impl FixupContext {
|
||||||
/// Create the initial fixup for printing an expression in statement
|
/// Create the initial fixup for printing an expression in statement
|
||||||
/// position.
|
/// position.
|
||||||
pub fn new_stmt() -> Self {
|
pub(crate) fn new_stmt() -> Self {
|
||||||
FixupContext { stmt: true, ..FixupContext::default() }
|
FixupContext { stmt: true, ..FixupContext::default() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create the initial fixup for printing an expression as the right-hand
|
/// Create the initial fixup for printing an expression as the right-hand
|
||||||
/// side of a match arm.
|
/// side of a match arm.
|
||||||
pub fn new_match_arm() -> Self {
|
pub(crate) fn new_match_arm() -> Self {
|
||||||
FixupContext { match_arm: true, ..FixupContext::default() }
|
FixupContext { match_arm: true, ..FixupContext::default() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,7 +124,7 @@ impl FixupContext {
|
||||||
/// of an `if` or `while`. There are a few other positions which are
|
/// of an `if` or `while`. There are a few other positions which are
|
||||||
/// grammatically equivalent and also use this, such as the iterator
|
/// grammatically equivalent and also use this, such as the iterator
|
||||||
/// expression in `for` and the scrutinee in `match`.
|
/// expression in `for` and the scrutinee in `match`.
|
||||||
pub fn new_cond() -> Self {
|
pub(crate) fn new_cond() -> Self {
|
||||||
FixupContext { parenthesize_exterior_struct_lit: true, ..FixupContext::default() }
|
FixupContext { parenthesize_exterior_struct_lit: true, ..FixupContext::default() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,7 +139,7 @@ impl FixupContext {
|
||||||
///
|
///
|
||||||
/// Not every expression has a leftmost subexpression. For example neither
|
/// Not every expression has a leftmost subexpression. For example neither
|
||||||
/// `-$a` nor `[$a]` have one.
|
/// `-$a` nor `[$a]` have one.
|
||||||
pub fn leftmost_subexpression(self) -> Self {
|
pub(crate) fn leftmost_subexpression(self) -> Self {
|
||||||
FixupContext {
|
FixupContext {
|
||||||
stmt: false,
|
stmt: false,
|
||||||
leftmost_subexpression_in_stmt: self.stmt || self.leftmost_subexpression_in_stmt,
|
leftmost_subexpression_in_stmt: self.stmt || self.leftmost_subexpression_in_stmt,
|
||||||
|
@ -158,7 +158,7 @@ impl FixupContext {
|
||||||
/// current expression, and is not surrounded by a paren/bracket/brace. For
|
/// current expression, and is not surrounded by a paren/bracket/brace. For
|
||||||
/// example the `$b` in `$a + $b` and `-$b`, but not the one in `[$b]` or
|
/// example the `$b` in `$a + $b` and `-$b`, but not the one in `[$b]` or
|
||||||
/// `$a.f($b)`.
|
/// `$a.f($b)`.
|
||||||
pub fn subsequent_subexpression(self) -> Self {
|
pub(crate) fn subsequent_subexpression(self) -> Self {
|
||||||
FixupContext {
|
FixupContext {
|
||||||
stmt: false,
|
stmt: false,
|
||||||
leftmost_subexpression_in_stmt: false,
|
leftmost_subexpression_in_stmt: false,
|
||||||
|
@ -173,7 +173,7 @@ impl FixupContext {
|
||||||
///
|
///
|
||||||
/// The documentation on `FixupContext::leftmost_subexpression_in_stmt` has
|
/// The documentation on `FixupContext::leftmost_subexpression_in_stmt` has
|
||||||
/// examples.
|
/// examples.
|
||||||
pub fn would_cause_statement_boundary(self, expr: &Expr) -> bool {
|
pub(crate) fn would_cause_statement_boundary(self, expr: &Expr) -> bool {
|
||||||
(self.leftmost_subexpression_in_stmt && !classify::expr_requires_semi_to_be_stmt(expr))
|
(self.leftmost_subexpression_in_stmt && !classify::expr_requires_semi_to_be_stmt(expr))
|
||||||
|| (self.leftmost_subexpression_in_match_arm && classify::expr_is_complete(expr))
|
|| (self.leftmost_subexpression_in_match_arm && classify::expr_is_complete(expr))
|
||||||
}
|
}
|
||||||
|
@ -189,7 +189,7 @@ impl FixupContext {
|
||||||
///
|
///
|
||||||
/// - `true && false`, because otherwise this would be misinterpreted as a
|
/// - `true && false`, because otherwise this would be misinterpreted as a
|
||||||
/// "let chain".
|
/// "let chain".
|
||||||
pub fn needs_par_as_let_scrutinee(self, expr: &Expr) -> bool {
|
pub(crate) fn needs_par_as_let_scrutinee(self, expr: &Expr) -> bool {
|
||||||
self.parenthesize_exterior_struct_lit && parser::contains_exterior_struct_lit(expr)
|
self.parenthesize_exterior_struct_lit && parser::contains_exterior_struct_lit(expr)
|
||||||
|| parser::needs_par_as_let_scrutinee(expr.precedence().order())
|
|| parser::needs_par_as_let_scrutinee(expr.precedence().order())
|
||||||
}
|
}
|
||||||
|
|
|
@ -846,7 +846,7 @@ pub fn find_deprecation(
|
||||||
sess.dcx().emit_err(
|
sess.dcx().emit_err(
|
||||||
session_diagnostics::DeprecatedItemSuggestion {
|
session_diagnostics::DeprecatedItemSuggestion {
|
||||||
span: mi.span,
|
span: mi.span,
|
||||||
is_nightly: sess.is_nightly_build().then_some(()),
|
is_nightly: sess.is_nightly_build(),
|
||||||
details: (),
|
details: (),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#![doc(rust_logo)]
|
#![doc(rust_logo)]
|
||||||
#![feature(let_chains)]
|
#![feature(let_chains)]
|
||||||
#![feature(rustdoc_internals)]
|
#![feature(rustdoc_internals)]
|
||||||
|
#![warn(unreachable_pub)]
|
||||||
// tidy-alphabetical-end
|
// tidy-alphabetical-end
|
||||||
|
|
||||||
mod builtin;
|
mod builtin;
|
||||||
|
|
|
@ -127,7 +127,7 @@ pub(crate) enum InvalidIssueStringCause {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InvalidIssueStringCause {
|
impl InvalidIssueStringCause {
|
||||||
pub fn from_int_error_kind(span: Span, kind: &IntErrorKind) -> Option<Self> {
|
pub(crate) fn from_int_error_kind(span: Span, kind: &IntErrorKind) -> Option<Self> {
|
||||||
match kind {
|
match kind {
|
||||||
IntErrorKind::Empty => Some(Self::Empty { span }),
|
IntErrorKind::Empty => Some(Self::Empty { span }),
|
||||||
IntErrorKind::InvalidDigit => Some(Self::InvalidDigit { span }),
|
IntErrorKind::InvalidDigit => Some(Self::InvalidDigit { span }),
|
||||||
|
@ -303,7 +303,7 @@ pub(crate) enum IncorrectReprFormatGenericCause<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> IncorrectReprFormatGenericCause<'a> {
|
impl<'a> IncorrectReprFormatGenericCause<'a> {
|
||||||
pub fn from_lit_kind(span: Span, kind: &ast::LitKind, name: &'a str) -> Option<Self> {
|
pub(crate) fn from_lit_kind(span: Span, kind: &ast::LitKind, name: &'a str) -> Option<Self> {
|
||||||
match kind {
|
match kind {
|
||||||
ast::LitKind::Int(int, ast::LitIntType::Unsuffixed) => {
|
ast::LitKind::Int(int, ast::LitIntType::Unsuffixed) => {
|
||||||
Some(Self::Int { span, name, int: int.get() })
|
Some(Self::Int { span, name, int: int.get() })
|
||||||
|
@ -342,7 +342,7 @@ pub(crate) struct DeprecatedItemSuggestion {
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
|
|
||||||
#[help]
|
#[help]
|
||||||
pub is_nightly: Option<()>,
|
pub is_nightly: bool,
|
||||||
|
|
||||||
#[note]
|
#[note]
|
||||||
pub details: (),
|
pub details: (),
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#![allow(internal_features)]
|
#![allow(internal_features)]
|
||||||
#![doc(rust_logo)]
|
#![doc(rust_logo)]
|
||||||
#![feature(rustdoc_internals)]
|
#![feature(rustdoc_internals)]
|
||||||
|
// #![warn(unreachable_pub)] // don't use because this crate is mostly generated code
|
||||||
// tidy-alphabetical-end
|
// tidy-alphabetical-end
|
||||||
|
|
||||||
mod data {
|
mod data {
|
||||||
|
|
|
@ -9,7 +9,7 @@ use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
|
||||||
impl<'infcx, 'tcx> crate::MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
|
impl<'infcx, 'tcx> crate::MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
|
||||||
pub fn dcx(&self) -> DiagCtxtHandle<'infcx> {
|
pub(crate) fn dcx(&self) -> DiagCtxtHandle<'infcx> {
|
||||||
self.infcx.dcx()
|
self.infcx.dcx()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -290,7 +290,7 @@ impl<'infcx, 'tcx> crate::MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
|
||||||
ty: Ty<'_>,
|
ty: Ty<'_>,
|
||||||
is_index: Option<bool>,
|
is_index: Option<bool>,
|
||||||
) -> Diag<'infcx> {
|
) -> Diag<'infcx> {
|
||||||
let type_name = match (&ty.kind(), is_index) {
|
let type_name = match (ty.kind(), is_index) {
|
||||||
(&ty::Array(_, _), Some(true)) | (&ty::Array(_, _), None) => "array",
|
(&ty::Array(_, _), Some(true)) | (&ty::Array(_, _), None) => "array",
|
||||||
(&ty::Slice(_), _) => "slice",
|
(&ty::Slice(_), _) => "slice",
|
||||||
_ => span_bug!(move_from_span, "this path should not cause illegal move"),
|
_ => span_bug!(move_from_span, "this path should not cause illegal move"),
|
||||||
|
|
|
@ -14,7 +14,7 @@ use rustc_mir_dataflow::{Analysis, AnalysisDomain, GenKill, Results, ResultsVisi
|
||||||
use crate::{places_conflict, BorrowSet, PlaceConflictBias, PlaceExt, RegionInferenceContext};
|
use crate::{places_conflict, BorrowSet, PlaceConflictBias, PlaceExt, RegionInferenceContext};
|
||||||
|
|
||||||
/// The results of the dataflow analyses used by the borrow checker.
|
/// The results of the dataflow analyses used by the borrow checker.
|
||||||
pub struct BorrowckResults<'a, 'mir, 'tcx> {
|
pub(crate) struct BorrowckResults<'a, 'mir, 'tcx> {
|
||||||
pub(crate) borrows: Results<'tcx, Borrows<'a, 'mir, 'tcx>>,
|
pub(crate) borrows: Results<'tcx, Borrows<'a, 'mir, 'tcx>>,
|
||||||
pub(crate) uninits: Results<'tcx, MaybeUninitializedPlaces<'a, 'mir, 'tcx>>,
|
pub(crate) uninits: Results<'tcx, MaybeUninitializedPlaces<'a, 'mir, 'tcx>>,
|
||||||
pub(crate) ever_inits: Results<'tcx, EverInitializedPlaces<'a, 'mir, 'tcx>>,
|
pub(crate) ever_inits: Results<'tcx, EverInitializedPlaces<'a, 'mir, 'tcx>>,
|
||||||
|
@ -22,7 +22,7 @@ pub struct BorrowckResults<'a, 'mir, 'tcx> {
|
||||||
|
|
||||||
/// The transient state of the dataflow analyses used by the borrow checker.
|
/// The transient state of the dataflow analyses used by the borrow checker.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct BorrowckFlowState<'a, 'mir, 'tcx> {
|
pub(crate) struct BorrowckFlowState<'a, 'mir, 'tcx> {
|
||||||
pub(crate) borrows: <Borrows<'a, 'mir, 'tcx> as AnalysisDomain<'tcx>>::Domain,
|
pub(crate) borrows: <Borrows<'a, 'mir, 'tcx> as AnalysisDomain<'tcx>>::Domain,
|
||||||
pub(crate) uninits: <MaybeUninitializedPlaces<'a, 'mir, 'tcx> as AnalysisDomain<'tcx>>::Domain,
|
pub(crate) uninits: <MaybeUninitializedPlaces<'a, 'mir, 'tcx> as AnalysisDomain<'tcx>>::Domain,
|
||||||
pub(crate) ever_inits: <EverInitializedPlaces<'a, 'mir, 'tcx> as AnalysisDomain<'tcx>>::Domain,
|
pub(crate) ever_inits: <EverInitializedPlaces<'a, 'mir, 'tcx> as AnalysisDomain<'tcx>>::Domain,
|
||||||
|
|
|
@ -4,13 +4,13 @@ use rustc_middle::mir::visit::{
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Eq, PartialEq, Clone)]
|
#[derive(Eq, PartialEq, Clone)]
|
||||||
pub enum DefUse {
|
pub(crate) enum DefUse {
|
||||||
Def,
|
Def,
|
||||||
Use,
|
Use,
|
||||||
Drop,
|
Drop,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn categorize(context: PlaceContext) -> Option<DefUse> {
|
pub(crate) fn categorize(context: PlaceContext) -> Option<DefUse> {
|
||||||
match context {
|
match context {
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// DEFS
|
// DEFS
|
||||||
|
@ -55,8 +55,8 @@ pub fn categorize(context: PlaceContext) -> Option<DefUse> {
|
||||||
PlaceContext::NonMutatingUse(NonMutatingUseContext::PlaceMention) |
|
PlaceContext::NonMutatingUse(NonMutatingUseContext::PlaceMention) |
|
||||||
PlaceContext::NonUse(NonUseContext::AscribeUserTy(_)) |
|
PlaceContext::NonUse(NonUseContext::AscribeUserTy(_)) |
|
||||||
|
|
||||||
PlaceContext::MutatingUse(MutatingUseContext::AddressOf) |
|
PlaceContext::MutatingUse(MutatingUseContext::RawBorrow) |
|
||||||
PlaceContext::NonMutatingUse(NonMutatingUseContext::AddressOf) |
|
PlaceContext::NonMutatingUse(NonMutatingUseContext::RawBorrow) |
|
||||||
PlaceContext::NonMutatingUse(NonMutatingUseContext::Inspect) |
|
PlaceContext::NonMutatingUse(NonMutatingUseContext::Inspect) |
|
||||||
PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) |
|
PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) |
|
||||||
PlaceContext::NonMutatingUse(NonMutatingUseContext::Move) |
|
PlaceContext::NonMutatingUse(NonMutatingUseContext::Move) |
|
||||||
|
|
|
@ -645,7 +645,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn suggest_reborrow(
|
pub(crate) fn suggest_reborrow(
|
||||||
&self,
|
&self,
|
||||||
err: &mut Diag<'infcx>,
|
err: &mut Diag<'infcx>,
|
||||||
span: Span,
|
span: Span,
|
||||||
|
@ -678,14 +678,15 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
|
||||||
let inits = &self.move_data.init_path_map[mpi];
|
let inits = &self.move_data.init_path_map[mpi];
|
||||||
let move_path = &self.move_data.move_paths[mpi];
|
let move_path = &self.move_data.move_paths[mpi];
|
||||||
let decl_span = self.body.local_decls[move_path.place.local].source_info.span;
|
let decl_span = self.body.local_decls[move_path.place.local].source_info.span;
|
||||||
let mut spans = vec![];
|
let mut spans_set = FxIndexSet::default();
|
||||||
for init_idx in inits {
|
for init_idx in inits {
|
||||||
let init = &self.move_data.inits[*init_idx];
|
let init = &self.move_data.inits[*init_idx];
|
||||||
let span = init.span(self.body);
|
let span = init.span(self.body);
|
||||||
if !span.is_dummy() {
|
if !span.is_dummy() {
|
||||||
spans.push(span);
|
spans_set.insert(span);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
let spans: Vec<_> = spans_set.into_iter().collect();
|
||||||
|
|
||||||
let (name, desc) = match self.describe_place_with_options(
|
let (name, desc) = match self.describe_place_with_options(
|
||||||
moved_place,
|
moved_place,
|
||||||
|
@ -1891,10 +1892,10 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
|
||||||
struct FindUselessClone<'tcx> {
|
struct FindUselessClone<'tcx> {
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
typeck_results: &'tcx ty::TypeckResults<'tcx>,
|
typeck_results: &'tcx ty::TypeckResults<'tcx>,
|
||||||
pub clones: Vec<&'tcx hir::Expr<'tcx>>,
|
clones: Vec<&'tcx hir::Expr<'tcx>>,
|
||||||
}
|
}
|
||||||
impl<'tcx> FindUselessClone<'tcx> {
|
impl<'tcx> FindUselessClone<'tcx> {
|
||||||
pub fn new(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Self {
|
fn new(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Self {
|
||||||
Self { tcx, typeck_results: tcx.typeck(def_id), clones: vec![] }
|
Self { tcx, typeck_results: tcx.typeck(def_id), clones: vec![] }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1916,7 +1917,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
|
||||||
let body = hir.body(body_id).value;
|
let body = hir.body(body_id).value;
|
||||||
expr_finder.visit_expr(body);
|
expr_finder.visit_expr(body);
|
||||||
|
|
||||||
pub struct Holds<'tcx> {
|
struct Holds<'tcx> {
|
||||||
ty: Ty<'tcx>,
|
ty: Ty<'tcx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3989,7 +3990,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
|
||||||
} else {
|
} else {
|
||||||
let ty = self.infcx.tcx.type_of(self.mir_def_id()).instantiate_identity();
|
let ty = self.infcx.tcx.type_of(self.mir_def_id()).instantiate_identity();
|
||||||
match ty.kind() {
|
match ty.kind() {
|
||||||
ty::FnDef(_, _) | ty::FnPtr(_) => self.annotate_fn_sig(
|
ty::FnDef(_, _) | ty::FnPtr(..) => self.annotate_fn_sig(
|
||||||
self.mir_def_id(),
|
self.mir_def_id(),
|
||||||
self.infcx.tcx.fn_sig(self.mir_def_id()).instantiate_identity(),
|
self.infcx.tcx.fn_sig(self.mir_def_id()).instantiate_identity(),
|
||||||
),
|
),
|
||||||
|
|
|
@ -58,11 +58,11 @@ pub(crate) use region_name::{RegionName, RegionNameSource};
|
||||||
pub(crate) use rustc_middle::util::CallKind;
|
pub(crate) use rustc_middle::util::CallKind;
|
||||||
|
|
||||||
pub(super) struct DescribePlaceOpt {
|
pub(super) struct DescribePlaceOpt {
|
||||||
pub including_downcast: bool,
|
including_downcast: bool,
|
||||||
|
|
||||||
/// Enable/Disable tuple fields.
|
/// Enable/Disable tuple fields.
|
||||||
/// For example `x` tuple. if it's `true` `x.0`. Otherwise `x`
|
/// For example `x` tuple. if it's `true` `x.0`. Otherwise `x`
|
||||||
pub including_tuple_field: bool,
|
including_tuple_field: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) struct IncludingTupleField(pub(super) bool);
|
pub(super) struct IncludingTupleField(pub(super) bool);
|
||||||
|
|
|
@ -16,7 +16,7 @@ use crate::prefixes::PrefixSet;
|
||||||
use crate::MirBorrowckCtxt;
|
use crate::MirBorrowckCtxt;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum IllegalMoveOriginKind<'tcx> {
|
pub(crate) enum IllegalMoveOriginKind<'tcx> {
|
||||||
/// Illegal move due to attempt to move from behind a reference.
|
/// Illegal move due to attempt to move from behind a reference.
|
||||||
BorrowedContent {
|
BorrowedContent {
|
||||||
/// The place the reference refers to: if erroneous code was trying to
|
/// The place the reference refers to: if erroneous code was trying to
|
||||||
|
|
|
@ -1374,7 +1374,7 @@ impl<'tcx> Visitor<'tcx> for BindingFinder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mut_borrow_of_mutable_ref(local_decl: &LocalDecl<'_>, local_name: Option<Symbol>) -> bool {
|
fn mut_borrow_of_mutable_ref(local_decl: &LocalDecl<'_>, local_name: Option<Symbol>) -> bool {
|
||||||
debug!("local_info: {:?}, ty.kind(): {:?}", local_decl.local_info, local_decl.ty.kind());
|
debug!("local_info: {:?}, ty.kind(): {:?}", local_decl.local_info, local_decl.ty.kind());
|
||||||
|
|
||||||
match *local_decl.local_info() {
|
match *local_decl.local_info() {
|
||||||
|
|
|
@ -31,7 +31,7 @@ enum SuggestedConstraint {
|
||||||
///
|
///
|
||||||
/// Adds a help note suggesting adding a where clause with the needed constraints.
|
/// Adds a help note suggesting adding a where clause with the needed constraints.
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct OutlivesSuggestionBuilder {
|
pub(crate) struct OutlivesSuggestionBuilder {
|
||||||
/// The list of outlives constraints that need to be added. Specifically, we map each free
|
/// The list of outlives constraints that need to be added. Specifically, we map each free
|
||||||
/// region to all other regions that it must outlive. I will use the shorthand `fr:
|
/// region to all other regions that it must outlive. I will use the shorthand `fr:
|
||||||
/// outlived_frs`. Not all of these regions will already have names necessarily. Some could be
|
/// outlived_frs`. Not all of these regions will already have names necessarily. Some could be
|
||||||
|
|
|
@ -72,22 +72,24 @@ impl<'tcx> ConstraintDescription for ConstraintCategory<'tcx> {
|
||||||
pub(crate) struct RegionErrors<'tcx>(Vec<(RegionErrorKind<'tcx>, ErrorGuaranteed)>, TyCtxt<'tcx>);
|
pub(crate) struct RegionErrors<'tcx>(Vec<(RegionErrorKind<'tcx>, ErrorGuaranteed)>, TyCtxt<'tcx>);
|
||||||
|
|
||||||
impl<'tcx> RegionErrors<'tcx> {
|
impl<'tcx> RegionErrors<'tcx> {
|
||||||
pub fn new(tcx: TyCtxt<'tcx>) -> Self {
|
pub(crate) fn new(tcx: TyCtxt<'tcx>) -> Self {
|
||||||
Self(vec![], tcx)
|
Self(vec![], tcx)
|
||||||
}
|
}
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
pub fn push(&mut self, val: impl Into<RegionErrorKind<'tcx>>) {
|
pub(crate) fn push(&mut self, val: impl Into<RegionErrorKind<'tcx>>) {
|
||||||
let val = val.into();
|
let val = val.into();
|
||||||
let guar = self.1.sess.dcx().delayed_bug(format!("{val:?}"));
|
let guar = self.1.sess.dcx().delayed_bug(format!("{val:?}"));
|
||||||
self.0.push((val, guar));
|
self.0.push((val, guar));
|
||||||
}
|
}
|
||||||
pub fn is_empty(&self) -> bool {
|
pub(crate) fn is_empty(&self) -> bool {
|
||||||
self.0.is_empty()
|
self.0.is_empty()
|
||||||
}
|
}
|
||||||
pub fn into_iter(self) -> impl Iterator<Item = (RegionErrorKind<'tcx>, ErrorGuaranteed)> {
|
pub(crate) fn into_iter(
|
||||||
|
self,
|
||||||
|
) -> impl Iterator<Item = (RegionErrorKind<'tcx>, ErrorGuaranteed)> {
|
||||||
self.0.into_iter()
|
self.0.into_iter()
|
||||||
}
|
}
|
||||||
pub fn has_errors(&self) -> Option<ErrorGuaranteed> {
|
pub(crate) fn has_errors(&self) -> Option<ErrorGuaranteed> {
|
||||||
self.0.get(0).map(|x| x.1)
|
self.0.get(0).map(|x| x.1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -141,7 +143,7 @@ pub(crate) enum RegionErrorKind<'tcx> {
|
||||||
|
|
||||||
/// Information about the various region constraints involved in a borrow checker error.
|
/// Information about the various region constraints involved in a borrow checker error.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct ErrorConstraintInfo<'tcx> {
|
pub(crate) struct ErrorConstraintInfo<'tcx> {
|
||||||
// fr: outlived_fr
|
// fr: outlived_fr
|
||||||
pub(super) fr: RegionVid,
|
pub(super) fr: RegionVid,
|
||||||
pub(super) fr_is_local: bool,
|
pub(super) fr_is_local: bool,
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#![feature(rustdoc_internals)]
|
#![feature(rustdoc_internals)]
|
||||||
#![feature(stmt_expr_attributes)]
|
#![feature(stmt_expr_attributes)]
|
||||||
#![feature(try_blocks)]
|
#![feature(try_blocks)]
|
||||||
|
#![warn(unreachable_pub)]
|
||||||
// tidy-alphabetical-end
|
// tidy-alphabetical-end
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
|
@ -1242,7 +1243,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
&Rvalue::AddressOf(mutability, place) => {
|
&Rvalue::RawPtr(mutability, place) => {
|
||||||
let access_kind = match mutability {
|
let access_kind = match mutability {
|
||||||
Mutability::Mut => (
|
Mutability::Mut => (
|
||||||
Deep,
|
Deep,
|
||||||
|
@ -1644,7 +1645,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
|
||||||
| ty::Pat(_, _)
|
| ty::Pat(_, _)
|
||||||
| ty::Slice(_)
|
| ty::Slice(_)
|
||||||
| ty::FnDef(_, _)
|
| ty::FnDef(_, _)
|
||||||
| ty::FnPtr(_)
|
| ty::FnPtr(..)
|
||||||
| ty::Dynamic(_, _, _)
|
| ty::Dynamic(_, _, _)
|
||||||
| ty::Closure(_, _)
|
| ty::Closure(_, _)
|
||||||
| ty::CoroutineClosure(_, _)
|
| ty::CoroutineClosure(_, _)
|
||||||
|
@ -1689,7 +1690,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
|
||||||
| ty::RawPtr(_, _)
|
| ty::RawPtr(_, _)
|
||||||
| ty::Ref(_, _, _)
|
| ty::Ref(_, _, _)
|
||||||
| ty::FnDef(_, _)
|
| ty::FnDef(_, _)
|
||||||
| ty::FnPtr(_)
|
| ty::FnPtr(..)
|
||||||
| ty::Dynamic(_, _, _)
|
| ty::Dynamic(_, _, _)
|
||||||
| ty::CoroutineWitness(..)
|
| ty::CoroutineWitness(..)
|
||||||
| ty::Never
|
| ty::Never
|
||||||
|
@ -2444,7 +2445,7 @@ mod diags {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct BorrowckDiags<'infcx, 'tcx> {
|
pub(crate) struct BorrowckDiags<'infcx, 'tcx> {
|
||||||
/// This field keeps track of move errors that are to be reported for given move indices.
|
/// This field keeps track of move errors that are to be reported for given move indices.
|
||||||
///
|
///
|
||||||
/// There are situations where many errors can be reported for a single move out (see
|
/// There are situations where many errors can be reported for a single move out (see
|
||||||
|
@ -2468,7 +2469,7 @@ mod diags {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'infcx, 'tcx> BorrowckDiags<'infcx, 'tcx> {
|
impl<'infcx, 'tcx> BorrowckDiags<'infcx, 'tcx> {
|
||||||
pub fn new() -> Self {
|
pub(crate) fn new() -> Self {
|
||||||
BorrowckDiags {
|
BorrowckDiags {
|
||||||
buffered_move_errors: BTreeMap::new(),
|
buffered_move_errors: BTreeMap::new(),
|
||||||
buffered_mut_errors: Default::default(),
|
buffered_mut_errors: Default::default(),
|
||||||
|
@ -2476,25 +2477,25 @@ mod diags {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn buffer_error(&mut self, diag: Diag<'infcx>) {
|
pub(crate) fn buffer_error(&mut self, diag: Diag<'infcx>) {
|
||||||
self.buffered_diags.push(BufferedDiag::Error(diag));
|
self.buffered_diags.push(BufferedDiag::Error(diag));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn buffer_non_error(&mut self, diag: Diag<'infcx, ()>) {
|
pub(crate) fn buffer_non_error(&mut self, diag: Diag<'infcx, ()>) {
|
||||||
self.buffered_diags.push(BufferedDiag::NonError(diag));
|
self.buffered_diags.push(BufferedDiag::NonError(diag));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
|
impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
|
||||||
pub fn buffer_error(&mut self, diag: Diag<'infcx>) {
|
pub(crate) fn buffer_error(&mut self, diag: Diag<'infcx>) {
|
||||||
self.diags.buffer_error(diag);
|
self.diags.buffer_error(diag);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn buffer_non_error(&mut self, diag: Diag<'infcx, ()>) {
|
pub(crate) fn buffer_non_error(&mut self, diag: Diag<'infcx, ()>) {
|
||||||
self.diags.buffer_non_error(diag);
|
self.diags.buffer_non_error(diag);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn buffer_move_error(
|
pub(crate) fn buffer_move_error(
|
||||||
&mut self,
|
&mut self,
|
||||||
move_out_indices: Vec<MoveOutIndex>,
|
move_out_indices: Vec<MoveOutIndex>,
|
||||||
place_and_err: (PlaceRef<'tcx>, Diag<'infcx>),
|
place_and_err: (PlaceRef<'tcx>, Diag<'infcx>),
|
||||||
|
@ -2510,16 +2511,19 @@ mod diags {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_buffered_mut_error(&mut self, span: Span) -> Option<(Diag<'infcx>, usize)> {
|
pub(crate) fn get_buffered_mut_error(
|
||||||
|
&mut self,
|
||||||
|
span: Span,
|
||||||
|
) -> Option<(Diag<'infcx>, usize)> {
|
||||||
// FIXME(#120456) - is `swap_remove` correct?
|
// FIXME(#120456) - is `swap_remove` correct?
|
||||||
self.diags.buffered_mut_errors.swap_remove(&span)
|
self.diags.buffered_mut_errors.swap_remove(&span)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn buffer_mut_error(&mut self, span: Span, diag: Diag<'infcx>, count: usize) {
|
pub(crate) fn buffer_mut_error(&mut self, span: Span, diag: Diag<'infcx>, count: usize) {
|
||||||
self.diags.buffered_mut_errors.insert(span, (diag, count));
|
self.diags.buffered_mut_errors.insert(span, (diag, count));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn emit_errors(&mut self) -> Option<ErrorGuaranteed> {
|
pub(crate) fn emit_errors(&mut self) -> Option<ErrorGuaranteed> {
|
||||||
let mut res = None;
|
let mut res = None;
|
||||||
|
|
||||||
// Buffer any move errors that we collected and de-duplicated.
|
// Buffer any move errors that we collected and de-duplicated.
|
||||||
|
@ -2553,7 +2557,7 @@ mod diags {
|
||||||
self.diags.buffered_diags.is_empty()
|
self.diags.buffered_diags.is_empty()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn has_move_error(
|
pub(crate) fn has_move_error(
|
||||||
&self,
|
&self,
|
||||||
move_out_indices: &[MoveOutIndex],
|
move_out_indices: &[MoveOutIndex],
|
||||||
) -> Option<&(PlaceRef<'tcx>, Diag<'infcx>)> {
|
) -> Option<&(PlaceRef<'tcx>, Diag<'infcx>)> {
|
||||||
|
|
|
@ -201,7 +201,7 @@ fn place_components_conflict<'tcx>(
|
||||||
|
|
||||||
let base_ty = base.ty(body, tcx).ty;
|
let base_ty = base.ty(body, tcx).ty;
|
||||||
|
|
||||||
match (elem, &base_ty.kind(), access) {
|
match (elem, base_ty.kind(), access) {
|
||||||
(_, _, Shallow(Some(ArtificialField::ArrayLength)))
|
(_, _, Shallow(Some(ArtificialField::ArrayLength)))
|
||||||
| (_, _, Shallow(Some(ArtificialField::FakeBorrow))) => {
|
| (_, _, Shallow(Some(ArtificialField::FakeBorrow))) => {
|
||||||
// The array length is like additional fields on the
|
// The array length is like additional fields on the
|
||||||
|
|
|
@ -269,7 +269,7 @@ impl<'cx, 'tcx> LoanInvalidationsGenerator<'cx, 'tcx> {
|
||||||
self.access_place(location, place, access_kind, LocalMutationIsAllowed::No);
|
self.access_place(location, place, access_kind, LocalMutationIsAllowed::No);
|
||||||
}
|
}
|
||||||
|
|
||||||
&Rvalue::AddressOf(mutability, place) => {
|
&Rvalue::RawPtr(mutability, place) => {
|
||||||
let access_kind = match mutability {
|
let access_kind = match mutability {
|
||||||
Mutability::Mut => (
|
Mutability::Mut => (
|
||||||
Deep,
|
Deep,
|
||||||
|
|
|
@ -8,7 +8,7 @@ use rustc_middle::mir::{PlaceRef, ProjectionElem};
|
||||||
|
|
||||||
use super::MirBorrowckCtxt;
|
use super::MirBorrowckCtxt;
|
||||||
|
|
||||||
pub trait IsPrefixOf<'tcx> {
|
pub(crate) trait IsPrefixOf<'tcx> {
|
||||||
fn is_prefix_of(&self, other: PlaceRef<'tcx>) -> bool;
|
fn is_prefix_of(&self, other: PlaceRef<'tcx>) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,9 +42,9 @@ mod graphviz;
|
||||||
mod opaque_types;
|
mod opaque_types;
|
||||||
mod reverse_sccs;
|
mod reverse_sccs;
|
||||||
|
|
||||||
pub mod values;
|
pub(crate) mod values;
|
||||||
|
|
||||||
pub type ConstraintSccs = Sccs<RegionVid, ConstraintSccIndex, RegionTracker>;
|
pub(crate) type ConstraintSccs = Sccs<RegionVid, ConstraintSccIndex, RegionTracker>;
|
||||||
|
|
||||||
/// An annotation for region graph SCCs that tracks
|
/// An annotation for region graph SCCs that tracks
|
||||||
/// the values of its elements.
|
/// the values of its elements.
|
||||||
|
@ -226,7 +226,7 @@ pub(crate) struct AppliedMemberConstraint {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct RegionDefinition<'tcx> {
|
pub(crate) struct RegionDefinition<'tcx> {
|
||||||
/// What kind of variable is this -- a free region? existential
|
/// What kind of variable is this -- a free region? existential
|
||||||
/// variable? etc. (See the `NllRegionVariableOrigin` for more
|
/// variable? etc. (See the `NllRegionVariableOrigin` for more
|
||||||
/// info.)
|
/// info.)
|
||||||
|
@ -288,7 +288,7 @@ pub(crate) enum Cause {
|
||||||
/// `InferCtxt::process_registered_region_obligations` and
|
/// `InferCtxt::process_registered_region_obligations` and
|
||||||
/// `InferCtxt::type_must_outlive` in `rustc_infer::infer::InferCtxt`.
|
/// `InferCtxt::type_must_outlive` in `rustc_infer::infer::InferCtxt`.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct TypeTest<'tcx> {
|
pub(crate) struct TypeTest<'tcx> {
|
||||||
/// The type `T` that must outlive the region.
|
/// The type `T` that must outlive the region.
|
||||||
pub generic_kind: GenericKind<'tcx>,
|
pub generic_kind: GenericKind<'tcx>,
|
||||||
|
|
||||||
|
@ -320,7 +320,7 @@ enum Trace<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||||
pub enum ExtraConstraintInfo {
|
pub(crate) enum ExtraConstraintInfo {
|
||||||
PlaceholderFromPredicate(Span),
|
PlaceholderFromPredicate(Span),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2259,7 +2259,7 @@ impl<'tcx> RegionDefinition<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct BlameConstraint<'tcx> {
|
pub(crate) struct BlameConstraint<'tcx> {
|
||||||
pub category: ConstraintCategory<'tcx>,
|
pub category: ConstraintCategory<'tcx>,
|
||||||
pub from_closure: bool,
|
pub from_closure: bool,
|
||||||
pub cause: ObligationCause<'tcx>,
|
pub cause: ObligationCause<'tcx>,
|
||||||
|
|
|
@ -473,20 +473,20 @@ struct LazyOpaqueTyEnv<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> LazyOpaqueTyEnv<'tcx> {
|
impl<'tcx> LazyOpaqueTyEnv<'tcx> {
|
||||||
pub fn new(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Self {
|
fn new(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Self {
|
||||||
Self { tcx, def_id, canonical_args: std::cell::OnceCell::new() }
|
Self { tcx, def_id, canonical_args: std::cell::OnceCell::new() }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn param_equal_static(&self, param_index: usize) -> bool {
|
fn param_equal_static(&self, param_index: usize) -> bool {
|
||||||
self.get_canonical_args()[param_index].expect_region().is_static()
|
self.get_canonical_args()[param_index].expect_region().is_static()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn params_equal(&self, param1: usize, param2: usize) -> bool {
|
fn params_equal(&self, param1: usize, param2: usize) -> bool {
|
||||||
let canonical_args = self.get_canonical_args();
|
let canonical_args = self.get_canonical_args();
|
||||||
canonical_args[param1] == canonical_args[param2]
|
canonical_args[param1] == canonical_args[param2]
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn param_is_error(&self, param_index: usize) -> Result<(), ErrorGuaranteed> {
|
fn param_is_error(&self, param_index: usize) -> Result<(), ErrorGuaranteed> {
|
||||||
self.get_canonical_args()[param_index].error_reported()
|
self.get_canonical_args()[param_index].error_reported()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -86,7 +86,7 @@ macro_rules! span_mirbug_and_err {
|
||||||
|
|
||||||
mod canonical;
|
mod canonical;
|
||||||
mod constraint_conversion;
|
mod constraint_conversion;
|
||||||
pub mod free_region_relations;
|
pub(crate) mod free_region_relations;
|
||||||
mod input_output;
|
mod input_output;
|
||||||
pub(crate) mod liveness;
|
pub(crate) mod liveness;
|
||||||
mod relate_tys;
|
mod relate_tys;
|
||||||
|
@ -756,7 +756,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
|
||||||
PlaceContext::MutatingUse(_) => ty::Invariant,
|
PlaceContext::MutatingUse(_) => ty::Invariant,
|
||||||
PlaceContext::NonUse(StorageDead | StorageLive | VarDebugInfo) => ty::Invariant,
|
PlaceContext::NonUse(StorageDead | StorageLive | VarDebugInfo) => ty::Invariant,
|
||||||
PlaceContext::NonMutatingUse(
|
PlaceContext::NonMutatingUse(
|
||||||
Inspect | Copy | Move | PlaceMention | SharedBorrow | FakeBorrow | AddressOf
|
Inspect | Copy | Move | PlaceMention | SharedBorrow | FakeBorrow | RawBorrow
|
||||||
| Projection,
|
| Projection,
|
||||||
) => ty::Covariant,
|
) => ty::Covariant,
|
||||||
PlaceContext::NonUse(AscribeUserTy(variance)) => variance,
|
PlaceContext::NonUse(AscribeUserTy(variance)) => variance,
|
||||||
|
@ -1364,7 +1364,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
debug!("func_ty.kind: {:?}", func_ty.kind());
|
debug!("func_ty.kind: {:?}", func_ty.kind());
|
||||||
|
|
||||||
let sig = match func_ty.kind() {
|
let sig = match func_ty.kind() {
|
||||||
ty::FnDef(..) | ty::FnPtr(_) => func_ty.fn_sig(tcx),
|
ty::FnDef(..) | ty::FnPtr(..) => func_ty.fn_sig(tcx),
|
||||||
_ => {
|
_ => {
|
||||||
span_mirbug!(self, term, "call to non-function {:?}", func_ty);
|
span_mirbug!(self, term, "call to non-function {:?}", func_ty);
|
||||||
return;
|
return;
|
||||||
|
@ -1989,9 +1989,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
|
|
||||||
let ty_fn_ptr_from = Ty::new_fn_ptr(tcx, fn_sig);
|
let ty_fn_ptr_from = Ty::new_fn_ptr(tcx, fn_sig);
|
||||||
|
|
||||||
if let Err(terr) = self.eq_types(
|
if let Err(terr) = self.sub_types(
|
||||||
*ty,
|
|
||||||
ty_fn_ptr_from,
|
ty_fn_ptr_from,
|
||||||
|
*ty,
|
||||||
location.to_locations(),
|
location.to_locations(),
|
||||||
ConstraintCategory::Cast { unsize_to: None },
|
ConstraintCategory::Cast { unsize_to: None },
|
||||||
) {
|
) {
|
||||||
|
@ -2014,9 +2014,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
let ty_fn_ptr_from =
|
let ty_fn_ptr_from =
|
||||||
Ty::new_fn_ptr(tcx, tcx.signature_unclosure(sig, *safety));
|
Ty::new_fn_ptr(tcx, tcx.signature_unclosure(sig, *safety));
|
||||||
|
|
||||||
if let Err(terr) = self.eq_types(
|
if let Err(terr) = self.sub_types(
|
||||||
*ty,
|
|
||||||
ty_fn_ptr_from,
|
ty_fn_ptr_from,
|
||||||
|
*ty,
|
||||||
location.to_locations(),
|
location.to_locations(),
|
||||||
ConstraintCategory::Cast { unsize_to: None },
|
ConstraintCategory::Cast { unsize_to: None },
|
||||||
) {
|
) {
|
||||||
|
@ -2043,9 +2043,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
|
|
||||||
let ty_fn_ptr_from = tcx.safe_to_unsafe_fn_ty(fn_sig);
|
let ty_fn_ptr_from = tcx.safe_to_unsafe_fn_ty(fn_sig);
|
||||||
|
|
||||||
if let Err(terr) = self.eq_types(
|
if let Err(terr) = self.sub_types(
|
||||||
*ty,
|
|
||||||
ty_fn_ptr_from,
|
ty_fn_ptr_from,
|
||||||
|
*ty,
|
||||||
location.to_locations(),
|
location.to_locations(),
|
||||||
ConstraintCategory::Cast { unsize_to: None },
|
ConstraintCategory::Cast { unsize_to: None },
|
||||||
) {
|
) {
|
||||||
|
@ -2411,7 +2411,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
let ty_left = left.ty(body, tcx);
|
let ty_left = left.ty(body, tcx);
|
||||||
match ty_left.kind() {
|
match ty_left.kind() {
|
||||||
// Types with regions are comparable if they have a common super-type.
|
// Types with regions are comparable if they have a common super-type.
|
||||||
ty::RawPtr(_, _) | ty::FnPtr(_) => {
|
ty::RawPtr(_, _) | ty::FnPtr(..) => {
|
||||||
let ty_right = right.ty(body, tcx);
|
let ty_right = right.ty(body, tcx);
|
||||||
let common_ty = self.infcx.next_ty_var(body.source_info(location).span);
|
let common_ty = self.infcx.next_ty_var(body.source_info(location).span);
|
||||||
self.sub_types(
|
self.sub_types(
|
||||||
|
@ -2468,7 +2468,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
self.check_operand(right, location);
|
self.check_operand(right, location);
|
||||||
}
|
}
|
||||||
|
|
||||||
Rvalue::AddressOf(..)
|
Rvalue::RawPtr(..)
|
||||||
| Rvalue::ThreadLocalRef(..)
|
| Rvalue::ThreadLocalRef(..)
|
||||||
| Rvalue::Len(..)
|
| Rvalue::Len(..)
|
||||||
| Rvalue::Discriminant(..)
|
| Rvalue::Discriminant(..)
|
||||||
|
@ -2485,7 +2485,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
| Rvalue::ThreadLocalRef(_)
|
| Rvalue::ThreadLocalRef(_)
|
||||||
| Rvalue::Repeat(..)
|
| Rvalue::Repeat(..)
|
||||||
| Rvalue::Ref(..)
|
| Rvalue::Ref(..)
|
||||||
| Rvalue::AddressOf(..)
|
| Rvalue::RawPtr(..)
|
||||||
| Rvalue::Len(..)
|
| Rvalue::Len(..)
|
||||||
| Rvalue::Cast(..)
|
| Rvalue::Cast(..)
|
||||||
| Rvalue::ShallowInitBox(..)
|
| Rvalue::ShallowInitBox(..)
|
||||||
|
|
|
@ -57,7 +57,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct NllTypeRelating<'me, 'bccx, 'tcx> {
|
struct NllTypeRelating<'me, 'bccx, 'tcx> {
|
||||||
type_checker: &'me mut TypeChecker<'bccx, 'tcx>,
|
type_checker: &'me mut TypeChecker<'bccx, 'tcx>,
|
||||||
|
|
||||||
/// Where (and why) is this relation taking place?
|
/// Where (and why) is this relation taking place?
|
||||||
|
@ -82,7 +82,7 @@ pub struct NllTypeRelating<'me, 'bccx, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'me, 'bccx, 'tcx> NllTypeRelating<'me, 'bccx, 'tcx> {
|
impl<'me, 'bccx, 'tcx> NllTypeRelating<'me, 'bccx, 'tcx> {
|
||||||
pub fn new(
|
fn new(
|
||||||
type_checker: &'me mut TypeChecker<'bccx, 'tcx>,
|
type_checker: &'me mut TypeChecker<'bccx, 'tcx>,
|
||||||
locations: Locations,
|
locations: Locations,
|
||||||
category: ConstraintCategory<'tcx>,
|
category: ConstraintCategory<'tcx>,
|
||||||
|
|
|
@ -39,7 +39,7 @@ use crate::renumber::RegionCtxt;
|
||||||
use crate::BorrowckInferCtxt;
|
use crate::BorrowckInferCtxt;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct UniversalRegions<'tcx> {
|
pub(crate) struct UniversalRegions<'tcx> {
|
||||||
indices: UniversalRegionIndices<'tcx>,
|
indices: UniversalRegionIndices<'tcx>,
|
||||||
|
|
||||||
/// The vid assigned to `'static`
|
/// The vid assigned to `'static`
|
||||||
|
@ -95,7 +95,7 @@ pub struct UniversalRegions<'tcx> {
|
||||||
/// regions appear free in the defining type and late-bound regions
|
/// regions appear free in the defining type and late-bound regions
|
||||||
/// appear bound in the signature.
|
/// appear bound in the signature.
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
pub enum DefiningTy<'tcx> {
|
pub(crate) enum DefiningTy<'tcx> {
|
||||||
/// The MIR is a closure. The signature is found via
|
/// The MIR is a closure. The signature is found via
|
||||||
/// `ClosureArgs::closure_sig_ty`.
|
/// `ClosureArgs::closure_sig_ty`.
|
||||||
Closure(DefId, GenericArgsRef<'tcx>),
|
Closure(DefId, GenericArgsRef<'tcx>),
|
||||||
|
@ -131,7 +131,7 @@ impl<'tcx> DefiningTy<'tcx> {
|
||||||
/// not a closure or coroutine, there are no upvars, and hence it
|
/// not a closure or coroutine, there are no upvars, and hence it
|
||||||
/// will be an empty list. The order of types in this list will
|
/// will be an empty list. The order of types in this list will
|
||||||
/// match up with the upvar order in the HIR, typesystem, and MIR.
|
/// match up with the upvar order in the HIR, typesystem, and MIR.
|
||||||
pub fn upvar_tys(self) -> &'tcx ty::List<Ty<'tcx>> {
|
pub(crate) fn upvar_tys(self) -> &'tcx ty::List<Ty<'tcx>> {
|
||||||
match self {
|
match self {
|
||||||
DefiningTy::Closure(_, args) => args.as_closure().upvar_tys(),
|
DefiningTy::Closure(_, args) => args.as_closure().upvar_tys(),
|
||||||
DefiningTy::CoroutineClosure(_, args) => args.as_coroutine_closure().upvar_tys(),
|
DefiningTy::CoroutineClosure(_, args) => args.as_coroutine_closure().upvar_tys(),
|
||||||
|
@ -145,7 +145,7 @@ impl<'tcx> DefiningTy<'tcx> {
|
||||||
/// Number of implicit inputs -- notably the "environment"
|
/// Number of implicit inputs -- notably the "environment"
|
||||||
/// parameter for closures -- that appear in MIR but not in the
|
/// parameter for closures -- that appear in MIR but not in the
|
||||||
/// user's code.
|
/// user's code.
|
||||||
pub fn implicit_inputs(self) -> usize {
|
pub(crate) fn implicit_inputs(self) -> usize {
|
||||||
match self {
|
match self {
|
||||||
DefiningTy::Closure(..)
|
DefiningTy::Closure(..)
|
||||||
| DefiningTy::CoroutineClosure(..)
|
| DefiningTy::CoroutineClosure(..)
|
||||||
|
@ -154,15 +154,15 @@ impl<'tcx> DefiningTy<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_fn_def(&self) -> bool {
|
pub(crate) fn is_fn_def(&self) -> bool {
|
||||||
matches!(*self, DefiningTy::FnDef(..))
|
matches!(*self, DefiningTy::FnDef(..))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_const(&self) -> bool {
|
pub(crate) fn is_const(&self) -> bool {
|
||||||
matches!(*self, DefiningTy::Const(..) | DefiningTy::InlineConst(..))
|
matches!(*self, DefiningTy::Const(..) | DefiningTy::InlineConst(..))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn def_id(&self) -> DefId {
|
pub(crate) fn def_id(&self) -> DefId {
|
||||||
match *self {
|
match *self {
|
||||||
DefiningTy::Closure(def_id, ..)
|
DefiningTy::Closure(def_id, ..)
|
||||||
| DefiningTy::CoroutineClosure(def_id, ..)
|
| DefiningTy::CoroutineClosure(def_id, ..)
|
||||||
|
@ -196,7 +196,7 @@ struct UniversalRegionIndices<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub enum RegionClassification {
|
pub(crate) enum RegionClassification {
|
||||||
/// A **global** region is one that can be named from
|
/// A **global** region is one that can be named from
|
||||||
/// anywhere. There is only one, `'static`.
|
/// anywhere. There is only one, `'static`.
|
||||||
Global,
|
Global,
|
||||||
|
@ -246,7 +246,7 @@ impl<'tcx> UniversalRegions<'tcx> {
|
||||||
/// MIR -- that is, all the regions that appear in the function's
|
/// MIR -- that is, all the regions that appear in the function's
|
||||||
/// signature. This will also compute the relationships that are
|
/// signature. This will also compute the relationships that are
|
||||||
/// known between those regions.
|
/// known between those regions.
|
||||||
pub fn new(
|
pub(crate) fn new(
|
||||||
infcx: &BorrowckInferCtxt<'tcx>,
|
infcx: &BorrowckInferCtxt<'tcx>,
|
||||||
mir_def: LocalDefId,
|
mir_def: LocalDefId,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
|
@ -263,7 +263,7 @@ impl<'tcx> UniversalRegions<'tcx> {
|
||||||
/// if the `ClosureRegionRequirements` contains something like
|
/// if the `ClosureRegionRequirements` contains something like
|
||||||
/// `'1: '2`, then the caller would impose the constraint that
|
/// `'1: '2`, then the caller would impose the constraint that
|
||||||
/// `V[1]: V[2]`.
|
/// `V[1]: V[2]`.
|
||||||
pub fn closure_mapping(
|
pub(crate) fn closure_mapping(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
closure_args: GenericArgsRef<'tcx>,
|
closure_args: GenericArgsRef<'tcx>,
|
||||||
expected_num_vars: usize,
|
expected_num_vars: usize,
|
||||||
|
@ -289,13 +289,13 @@ impl<'tcx> UniversalRegions<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `true` if `r` is a member of this set of universal regions.
|
/// Returns `true` if `r` is a member of this set of universal regions.
|
||||||
pub fn is_universal_region(&self, r: RegionVid) -> bool {
|
pub(crate) fn is_universal_region(&self, r: RegionVid) -> bool {
|
||||||
(FIRST_GLOBAL_INDEX..self.num_universals).contains(&r.index())
|
(FIRST_GLOBAL_INDEX..self.num_universals).contains(&r.index())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Classifies `r` as a universal region, returning `None` if this
|
/// Classifies `r` as a universal region, returning `None` if this
|
||||||
/// is not a member of this set of universal regions.
|
/// is not a member of this set of universal regions.
|
||||||
pub fn region_classification(&self, r: RegionVid) -> Option<RegionClassification> {
|
pub(crate) fn region_classification(&self, r: RegionVid) -> Option<RegionClassification> {
|
||||||
let index = r.index();
|
let index = r.index();
|
||||||
if (FIRST_GLOBAL_INDEX..self.first_extern_index).contains(&index) {
|
if (FIRST_GLOBAL_INDEX..self.first_extern_index).contains(&index) {
|
||||||
Some(RegionClassification::Global)
|
Some(RegionClassification::Global)
|
||||||
|
@ -310,17 +310,17 @@ impl<'tcx> UniversalRegions<'tcx> {
|
||||||
|
|
||||||
/// Returns an iterator over all the RegionVids corresponding to
|
/// Returns an iterator over all the RegionVids corresponding to
|
||||||
/// universally quantified free regions.
|
/// universally quantified free regions.
|
||||||
pub fn universal_regions(&self) -> impl Iterator<Item = RegionVid> {
|
pub(crate) fn universal_regions(&self) -> impl Iterator<Item = RegionVid> {
|
||||||
(FIRST_GLOBAL_INDEX..self.num_universals).map(RegionVid::from_usize)
|
(FIRST_GLOBAL_INDEX..self.num_universals).map(RegionVid::from_usize)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `true` if `r` is classified as a local region.
|
/// Returns `true` if `r` is classified as a local region.
|
||||||
pub fn is_local_free_region(&self, r: RegionVid) -> bool {
|
pub(crate) fn is_local_free_region(&self, r: RegionVid) -> bool {
|
||||||
self.region_classification(r) == Some(RegionClassification::Local)
|
self.region_classification(r) == Some(RegionClassification::Local)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the number of universal regions created in any category.
|
/// Returns the number of universal regions created in any category.
|
||||||
pub fn len(&self) -> usize {
|
pub(crate) fn len(&self) -> usize {
|
||||||
self.num_universals
|
self.num_universals
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -329,19 +329,19 @@ impl<'tcx> UniversalRegions<'tcx> {
|
||||||
/// closure type (versus those bound in the closure
|
/// closure type (versus those bound in the closure
|
||||||
/// signature). They are therefore the regions between which the
|
/// signature). They are therefore the regions between which the
|
||||||
/// closure may impose constraints that its creator must verify.
|
/// closure may impose constraints that its creator must verify.
|
||||||
pub fn num_global_and_external_regions(&self) -> usize {
|
pub(crate) fn num_global_and_external_regions(&self) -> usize {
|
||||||
self.first_local_index
|
self.first_local_index
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets an iterator over all the early-bound regions that have names.
|
/// Gets an iterator over all the early-bound regions that have names.
|
||||||
pub fn named_universal_regions<'s>(
|
pub(crate) fn named_universal_regions<'s>(
|
||||||
&'s self,
|
&'s self,
|
||||||
) -> impl Iterator<Item = (ty::Region<'tcx>, ty::RegionVid)> + 's {
|
) -> impl Iterator<Item = (ty::Region<'tcx>, ty::RegionVid)> + 's {
|
||||||
self.indices.indices.iter().map(|(&r, &v)| (r, v))
|
self.indices.indices.iter().map(|(&r, &v)| (r, v))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// See `UniversalRegionIndices::to_region_vid`.
|
/// See `UniversalRegionIndices::to_region_vid`.
|
||||||
pub fn to_region_vid(&self, r: ty::Region<'tcx>) -> RegionVid {
|
pub(crate) fn to_region_vid(&self, r: ty::Region<'tcx>) -> RegionVid {
|
||||||
self.indices.to_region_vid(r)
|
self.indices.to_region_vid(r)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -416,7 +416,7 @@ impl<'tcx> UniversalRegions<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tainted_by_errors(&self) -> Option<ErrorGuaranteed> {
|
pub(crate) fn tainted_by_errors(&self) -> Option<ErrorGuaranteed> {
|
||||||
self.indices.tainted_by_errors.get()
|
self.indices.tainted_by_errors.get()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -880,7 +880,7 @@ impl<'tcx> UniversalRegionIndices<'tcx> {
|
||||||
/// reference those regions from the `ParamEnv`. It is also used
|
/// reference those regions from the `ParamEnv`. It is also used
|
||||||
/// during initialization. Relies on the `indices` map having been
|
/// during initialization. Relies on the `indices` map having been
|
||||||
/// fully initialized.
|
/// fully initialized.
|
||||||
pub fn to_region_vid(&self, r: ty::Region<'tcx>) -> RegionVid {
|
fn to_region_vid(&self, r: ty::Region<'tcx>) -> RegionVid {
|
||||||
if let ty::ReVar(..) = *r {
|
if let ty::ReVar(..) = *r {
|
||||||
r.as_var()
|
r.as_var()
|
||||||
} else if let ty::ReError(guar) = *r {
|
} else if let ty::ReError(guar) = *r {
|
||||||
|
@ -899,7 +899,7 @@ impl<'tcx> UniversalRegionIndices<'tcx> {
|
||||||
|
|
||||||
/// Replaces all free regions in `value` with region vids, as
|
/// Replaces all free regions in `value` with region vids, as
|
||||||
/// returned by `to_region_vid`.
|
/// returned by `to_region_vid`.
|
||||||
pub fn fold_to_region_vids<T>(&self, tcx: TyCtxt<'tcx>, value: T) -> T
|
fn fold_to_region_vids<T>(&self, tcx: TyCtxt<'tcx>, value: T) -> T
|
||||||
where
|
where
|
||||||
T: TypeFoldable<TyCtxt<'tcx>>,
|
T: TypeFoldable<TyCtxt<'tcx>>,
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use rustc_middle::mir::visit::{PlaceContext, Visitor};
|
use rustc_middle::mir::visit::{PlaceContext, Visitor};
|
||||||
use rustc_middle::mir::{Body, Local, Location};
|
use rustc_middle::mir::{Body, Local, Location};
|
||||||
|
|
||||||
pub trait FindAssignments {
|
pub(crate) trait FindAssignments {
|
||||||
// Finds all statements that assign directly to local (i.e., X = ...)
|
// Finds all statements that assign directly to local (i.e., X = ...)
|
||||||
// and returns their locations.
|
// and returns their locations.
|
||||||
fn find_assignments(&self, local: Local) -> Vec<Location>;
|
fn find_assignments(&self, local: Local) -> Vec<Location>;
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
mod collect_writes;
|
mod collect_writes;
|
||||||
|
|
||||||
pub use collect_writes::FindAssignments;
|
pub(crate) use collect_writes::FindAssignments;
|
||||||
|
|
|
@ -328,7 +328,7 @@ pub fn parse_asm_args<'a>(
|
||||||
/// Otherwise, the suggestion will be incorrect.
|
/// Otherwise, the suggestion will be incorrect.
|
||||||
fn err_duplicate_option(p: &Parser<'_>, symbol: Symbol, span: Span) {
|
fn err_duplicate_option(p: &Parser<'_>, symbol: Symbol, span: Span) {
|
||||||
// Tool-only output
|
// Tool-only output
|
||||||
let full_span = if p.token.kind == token::Comma { span.to(p.token.span) } else { span };
|
let full_span = if p.token == token::Comma { span.to(p.token.span) } else { span };
|
||||||
p.dcx().emit_err(errors::AsmOptAlreadyprovided { span, symbol, full_span });
|
p.dcx().emit_err(errors::AsmOptAlreadyprovided { span, symbol, full_span });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -338,7 +338,7 @@ fn err_duplicate_option(p: &Parser<'_>, symbol: Symbol, span: Span) {
|
||||||
/// Otherwise, the suggestion will be incorrect.
|
/// Otherwise, the suggestion will be incorrect.
|
||||||
fn err_unsupported_option(p: &Parser<'_>, symbol: Symbol, span: Span) {
|
fn err_unsupported_option(p: &Parser<'_>, symbol: Symbol, span: Span) {
|
||||||
// Tool-only output
|
// Tool-only output
|
||||||
let full_span = if p.token.kind == token::Comma { span.to(p.token.span) } else { span };
|
let full_span = if p.token == token::Comma { span.to(p.token.span) } else { span };
|
||||||
p.dcx().emit_err(errors::GlobalAsmUnsupportedOption { span, symbol, full_span });
|
p.dcx().emit_err(errors::GlobalAsmUnsupportedOption { span, symbol, full_span });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,6 @@ impl MultiItemModifier for Expander {
|
||||||
) -> ExpandResult<Vec<Annotatable>, Annotatable> {
|
) -> ExpandResult<Vec<Annotatable>, Annotatable> {
|
||||||
let template = AttributeTemplate { list: Some("path"), ..Default::default() };
|
let template = AttributeTemplate { list: Some("path"), ..Default::default() };
|
||||||
validate_attr::check_builtin_meta_item(
|
validate_attr::check_builtin_meta_item(
|
||||||
&ecx.ecfg.features,
|
|
||||||
&ecx.sess.psess,
|
&ecx.sess.psess,
|
||||||
meta_item,
|
meta_item,
|
||||||
ast::AttrStyle::Outer,
|
ast::AttrStyle::Outer,
|
||||||
|
|
|
@ -38,7 +38,6 @@ impl MultiItemModifier for Expander {
|
||||||
let template =
|
let template =
|
||||||
AttributeTemplate { list: Some("Trait1, Trait2, ..."), ..Default::default() };
|
AttributeTemplate { list: Some("Trait1, Trait2, ..."), ..Default::default() };
|
||||||
validate_attr::check_builtin_meta_item(
|
validate_attr::check_builtin_meta_item(
|
||||||
features,
|
|
||||||
&sess.psess,
|
&sess.psess,
|
||||||
meta_item,
|
meta_item,
|
||||||
ast::AttrStyle::Outer,
|
ast::AttrStyle::Outer,
|
||||||
|
|
|
@ -351,15 +351,15 @@ struct TypeParameter {
|
||||||
pub(crate) struct BlockOrExpr(ThinVec<ast::Stmt>, Option<P<Expr>>);
|
pub(crate) struct BlockOrExpr(ThinVec<ast::Stmt>, Option<P<Expr>>);
|
||||||
|
|
||||||
impl BlockOrExpr {
|
impl BlockOrExpr {
|
||||||
pub fn new_stmts(stmts: ThinVec<ast::Stmt>) -> BlockOrExpr {
|
pub(crate) fn new_stmts(stmts: ThinVec<ast::Stmt>) -> BlockOrExpr {
|
||||||
BlockOrExpr(stmts, None)
|
BlockOrExpr(stmts, None)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_expr(expr: P<Expr>) -> BlockOrExpr {
|
pub(crate) fn new_expr(expr: P<Expr>) -> BlockOrExpr {
|
||||||
BlockOrExpr(ThinVec::new(), Some(expr))
|
BlockOrExpr(ThinVec::new(), Some(expr))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_mixed(stmts: ThinVec<ast::Stmt>, expr: Option<P<Expr>>) -> BlockOrExpr {
|
pub(crate) fn new_mixed(stmts: ThinVec<ast::Stmt>, expr: Option<P<Expr>>) -> BlockOrExpr {
|
||||||
BlockOrExpr(stmts, expr)
|
BlockOrExpr(stmts, expr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -461,7 +461,7 @@ fn find_type_parameters(
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> TraitDef<'a> {
|
impl<'a> TraitDef<'a> {
|
||||||
pub fn expand(
|
pub(crate) fn expand(
|
||||||
self,
|
self,
|
||||||
cx: &ExtCtxt<'_>,
|
cx: &ExtCtxt<'_>,
|
||||||
mitem: &ast::MetaItem,
|
mitem: &ast::MetaItem,
|
||||||
|
@ -471,7 +471,7 @@ impl<'a> TraitDef<'a> {
|
||||||
self.expand_ext(cx, mitem, item, push, false);
|
self.expand_ext(cx, mitem, item, push, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn expand_ext(
|
pub(crate) fn expand_ext(
|
||||||
self,
|
self,
|
||||||
cx: &ExtCtxt<'_>,
|
cx: &ExtCtxt<'_>,
|
||||||
mitem: &ast::MetaItem,
|
mitem: &ast::MetaItem,
|
||||||
|
|
|
@ -27,17 +27,17 @@ pub(crate) enum PathKind {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Path {
|
impl Path {
|
||||||
pub fn new(path: Vec<Symbol>) -> Path {
|
pub(crate) fn new(path: Vec<Symbol>) -> Path {
|
||||||
Path::new_(path, Vec::new(), PathKind::Std)
|
Path::new_(path, Vec::new(), PathKind::Std)
|
||||||
}
|
}
|
||||||
pub fn new_local(path: Symbol) -> Path {
|
pub(crate) fn new_local(path: Symbol) -> Path {
|
||||||
Path::new_(vec![path], Vec::new(), PathKind::Local)
|
Path::new_(vec![path], Vec::new(), PathKind::Local)
|
||||||
}
|
}
|
||||||
pub fn new_(path: Vec<Symbol>, params: Vec<Box<Ty>>, kind: PathKind) -> Path {
|
pub(crate) fn new_(path: Vec<Symbol>, params: Vec<Box<Ty>>, kind: PathKind) -> Path {
|
||||||
Path { path, params, kind }
|
Path { path, params, kind }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_ty(
|
pub(crate) fn to_ty(
|
||||||
&self,
|
&self,
|
||||||
cx: &ExtCtxt<'_>,
|
cx: &ExtCtxt<'_>,
|
||||||
span: Span,
|
span: Span,
|
||||||
|
@ -46,7 +46,7 @@ impl Path {
|
||||||
) -> P<ast::Ty> {
|
) -> P<ast::Ty> {
|
||||||
cx.ty_path(self.to_path(cx, span, self_ty, self_generics))
|
cx.ty_path(self.to_path(cx, span, self_ty, self_generics))
|
||||||
}
|
}
|
||||||
pub fn to_path(
|
pub(crate) fn to_path(
|
||||||
&self,
|
&self,
|
||||||
cx: &ExtCtxt<'_>,
|
cx: &ExtCtxt<'_>,
|
||||||
span: Span,
|
span: Span,
|
||||||
|
@ -87,7 +87,7 @@ pub(crate) fn self_ref() -> Ty {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Ty {
|
impl Ty {
|
||||||
pub fn to_ty(
|
pub(crate) fn to_ty(
|
||||||
&self,
|
&self,
|
||||||
cx: &ExtCtxt<'_>,
|
cx: &ExtCtxt<'_>,
|
||||||
span: Span,
|
span: Span,
|
||||||
|
@ -108,7 +108,7 @@ impl Ty {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_path(
|
pub(crate) fn to_path(
|
||||||
&self,
|
&self,
|
||||||
cx: &ExtCtxt<'_>,
|
cx: &ExtCtxt<'_>,
|
||||||
span: Span,
|
span: Span,
|
||||||
|
@ -167,10 +167,10 @@ pub(crate) struct Bounds {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Bounds {
|
impl Bounds {
|
||||||
pub fn empty() -> Bounds {
|
pub(crate) fn empty() -> Bounds {
|
||||||
Bounds { bounds: Vec::new() }
|
Bounds { bounds: Vec::new() }
|
||||||
}
|
}
|
||||||
pub fn to_generics(
|
pub(crate) fn to_generics(
|
||||||
&self,
|
&self,
|
||||||
cx: &ExtCtxt<'_>,
|
cx: &ExtCtxt<'_>,
|
||||||
span: Span,
|
span: Span,
|
||||||
|
|
|
@ -11,14 +11,13 @@ use rustc_data_structures::flat_map_in_place::FlatMapInPlace;
|
||||||
use rustc_expand::base::{Annotatable, ExtCtxt};
|
use rustc_expand::base::{Annotatable, ExtCtxt};
|
||||||
use rustc_span::symbol::{sym, Ident};
|
use rustc_span::symbol::{sym, Ident};
|
||||||
use rustc_span::{Span, Symbol};
|
use rustc_span::{Span, Symbol};
|
||||||
use smallvec::{smallvec, SmallVec};
|
|
||||||
use thin_vec::{thin_vec, ThinVec};
|
use thin_vec::{thin_vec, ThinVec};
|
||||||
|
|
||||||
macro_rules! path {
|
macro_rules! path {
|
||||||
($span:expr, $($part:ident)::*) => { vec![$(Ident::new(sym::$part, $span),)*] }
|
($span:expr, $($part:ident)::*) => { vec![$(Ident::new(sym::$part, $span),)*] }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn expand_deriving_smart_ptr(
|
pub(crate) fn expand_deriving_smart_ptr(
|
||||||
cx: &ExtCtxt<'_>,
|
cx: &ExtCtxt<'_>,
|
||||||
span: Span,
|
span: Span,
|
||||||
_mitem: &MetaItem,
|
_mitem: &MetaItem,
|
||||||
|
@ -68,43 +67,63 @@ pub fn expand_deriving_smart_ptr(
|
||||||
};
|
};
|
||||||
|
|
||||||
// Convert generic parameters (from the struct) into generic args.
|
// Convert generic parameters (from the struct) into generic args.
|
||||||
let mut pointee_param = None;
|
let self_params: Vec<_> = generics
|
||||||
let mut multiple_pointee_diag: SmallVec<[_; 2]> = smallvec![];
|
.params
|
||||||
let self_params = generics
|
.iter()
|
||||||
|
.map(|p| match p.kind {
|
||||||
|
GenericParamKind::Lifetime => GenericArg::Lifetime(cx.lifetime(p.span(), p.ident)),
|
||||||
|
GenericParamKind::Type { .. } => GenericArg::Type(cx.ty_ident(p.span(), p.ident)),
|
||||||
|
GenericParamKind::Const { .. } => GenericArg::Const(cx.const_ident(p.span(), p.ident)),
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
let type_params: Vec<_> = generics
|
||||||
.params
|
.params
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(idx, p)| match p.kind {
|
.filter_map(|(idx, p)| {
|
||||||
GenericParamKind::Lifetime => GenericArg::Lifetime(cx.lifetime(p.span(), p.ident)),
|
if let GenericParamKind::Type { .. } = p.kind {
|
||||||
GenericParamKind::Type { .. } => {
|
Some((idx, p.span(), p.attrs().iter().any(|attr| attr.has_name(sym::pointee))))
|
||||||
if p.attrs().iter().any(|attr| attr.has_name(sym::pointee)) {
|
} else {
|
||||||
if pointee_param.is_some() {
|
None
|
||||||
multiple_pointee_diag.push(cx.dcx().struct_span_err(
|
|
||||||
p.span(),
|
|
||||||
"`SmartPointer` can only admit one type as pointee",
|
|
||||||
));
|
|
||||||
} else {
|
|
||||||
pointee_param = Some(idx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
GenericArg::Type(cx.ty_ident(p.span(), p.ident))
|
|
||||||
}
|
}
|
||||||
GenericParamKind::Const { .. } => GenericArg::Const(cx.const_ident(p.span(), p.ident)),
|
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect();
|
||||||
let Some(pointee_param_idx) = pointee_param else {
|
|
||||||
|
let pointee_param_idx = if type_params.is_empty() {
|
||||||
|
// `#[derive(SmartPointer)]` requires at least one generic type on the target `struct`
|
||||||
cx.dcx().struct_span_err(
|
cx.dcx().struct_span_err(
|
||||||
span,
|
span,
|
||||||
"At least one generic type should be designated as `#[pointee]` in order to derive `SmartPointer` traits",
|
"`SmartPointer` can only be derived on `struct`s that are generic over at least one type",
|
||||||
).emit();
|
).emit();
|
||||||
return;
|
return;
|
||||||
};
|
} else if type_params.len() == 1 {
|
||||||
if !multiple_pointee_diag.is_empty() {
|
// Regardless of the only type param being designed as `#[pointee]` or not, we can just use it as such
|
||||||
for diag in multiple_pointee_diag {
|
type_params[0].0
|
||||||
diag.emit();
|
} else {
|
||||||
|
let mut pointees = type_params
|
||||||
|
.iter()
|
||||||
|
.filter_map(|&(idx, span, is_pointee)| is_pointee.then_some((idx, span)))
|
||||||
|
.fuse();
|
||||||
|
match (pointees.next(), pointees.next()) {
|
||||||
|
(Some((idx, _span)), None) => idx,
|
||||||
|
(None, _) => {
|
||||||
|
cx.dcx().struct_span_err(
|
||||||
|
span,
|
||||||
|
"exactly one generic type parameter must be marked as #[pointee] to derive SmartPointer traits",
|
||||||
|
).emit();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
(Some((_, one)), Some((_, another))) => {
|
||||||
|
cx.dcx()
|
||||||
|
.struct_span_err(
|
||||||
|
vec![one, another],
|
||||||
|
"only one type parameter can be marked as `#[pointee]` when deriving SmartPointer traits",
|
||||||
|
)
|
||||||
|
.emit();
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return;
|
};
|
||||||
}
|
|
||||||
|
|
||||||
// Create the type of `self`.
|
// Create the type of `self`.
|
||||||
let path = cx.path_all(span, false, vec![name_ident], self_params.clone());
|
let path = cx.path_all(span, false, vec![name_ident], self_params.clone());
|
||||||
|
|
|
@ -930,7 +930,7 @@ pub(crate) struct ExpectedItem<'a> {
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(builtin_macros_naked_functions_testing_attribute, code = E0736)]
|
#[diag(builtin_macros_naked_functions_testing_attribute, code = E0736)]
|
||||||
pub struct NakedFunctionTestingAttribute {
|
pub(crate) struct NakedFunctionTestingAttribute {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
#[label(builtin_macros_naked_attribute)]
|
#[label(builtin_macros_naked_attribute)]
|
||||||
pub naked_span: Span,
|
pub naked_span: Span,
|
||||||
|
|
|
@ -5,7 +5,7 @@ pub(crate) mod printf {
|
||||||
|
|
||||||
/// Represents a single `printf`-style substitution.
|
/// Represents a single `printf`-style substitution.
|
||||||
#[derive(Clone, PartialEq, Debug)]
|
#[derive(Clone, PartialEq, Debug)]
|
||||||
pub enum Substitution<'a> {
|
pub(crate) enum Substitution<'a> {
|
||||||
/// A formatted output substitution with its internal byte offset.
|
/// A formatted output substitution with its internal byte offset.
|
||||||
Format(Format<'a>),
|
Format(Format<'a>),
|
||||||
/// A literal `%%` escape, with its start and end indices.
|
/// A literal `%%` escape, with its start and end indices.
|
||||||
|
@ -13,21 +13,21 @@ pub(crate) mod printf {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Substitution<'a> {
|
impl<'a> Substitution<'a> {
|
||||||
pub fn as_str(&self) -> &str {
|
pub(crate) fn as_str(&self) -> &str {
|
||||||
match self {
|
match self {
|
||||||
Substitution::Format(fmt) => fmt.span,
|
Substitution::Format(fmt) => fmt.span,
|
||||||
Substitution::Escape(_) => "%%",
|
Substitution::Escape(_) => "%%",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn position(&self) -> InnerSpan {
|
pub(crate) fn position(&self) -> InnerSpan {
|
||||||
match self {
|
match self {
|
||||||
Substitution::Format(fmt) => fmt.position,
|
Substitution::Format(fmt) => fmt.position,
|
||||||
&Substitution::Escape((start, end)) => InnerSpan::new(start, end),
|
&Substitution::Escape((start, end)) => InnerSpan::new(start, end),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_position(&mut self, start: usize, end: usize) {
|
pub(crate) fn set_position(&mut self, start: usize, end: usize) {
|
||||||
match self {
|
match self {
|
||||||
Substitution::Format(fmt) => fmt.position = InnerSpan::new(start, end),
|
Substitution::Format(fmt) => fmt.position = InnerSpan::new(start, end),
|
||||||
Substitution::Escape(pos) => *pos = (start, end),
|
Substitution::Escape(pos) => *pos = (start, end),
|
||||||
|
@ -38,7 +38,7 @@ pub(crate) mod printf {
|
||||||
///
|
///
|
||||||
/// This ignores cases where the substitution does not have an exact equivalent, or where
|
/// This ignores cases where the substitution does not have an exact equivalent, or where
|
||||||
/// the substitution would be unnecessary.
|
/// the substitution would be unnecessary.
|
||||||
pub fn translate(&self) -> Result<String, Option<String>> {
|
pub(crate) fn translate(&self) -> Result<String, Option<String>> {
|
||||||
match self {
|
match self {
|
||||||
Substitution::Format(fmt) => fmt.translate(),
|
Substitution::Format(fmt) => fmt.translate(),
|
||||||
Substitution::Escape(_) => Err(None),
|
Substitution::Escape(_) => Err(None),
|
||||||
|
@ -48,23 +48,23 @@ pub(crate) mod printf {
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug)]
|
#[derive(Clone, PartialEq, Debug)]
|
||||||
/// A single `printf`-style formatting directive.
|
/// A single `printf`-style formatting directive.
|
||||||
pub struct Format<'a> {
|
pub(crate) struct Format<'a> {
|
||||||
/// The entire original formatting directive.
|
/// The entire original formatting directive.
|
||||||
pub span: &'a str,
|
span: &'a str,
|
||||||
/// The (1-based) parameter to be converted.
|
/// The (1-based) parameter to be converted.
|
||||||
pub parameter: Option<u16>,
|
parameter: Option<u16>,
|
||||||
/// Formatting flags.
|
/// Formatting flags.
|
||||||
pub flags: &'a str,
|
flags: &'a str,
|
||||||
/// Minimum width of the output.
|
/// Minimum width of the output.
|
||||||
pub width: Option<Num>,
|
width: Option<Num>,
|
||||||
/// Precision of the conversion.
|
/// Precision of the conversion.
|
||||||
pub precision: Option<Num>,
|
precision: Option<Num>,
|
||||||
/// Length modifier for the conversion.
|
/// Length modifier for the conversion.
|
||||||
pub length: Option<&'a str>,
|
length: Option<&'a str>,
|
||||||
/// Type of parameter being converted.
|
/// Type of parameter being converted.
|
||||||
pub type_: &'a str,
|
type_: &'a str,
|
||||||
/// Byte offset for the start and end of this formatting directive.
|
/// Byte offset for the start and end of this formatting directive.
|
||||||
pub position: InnerSpan,
|
position: InnerSpan,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Format<'_> {
|
impl Format<'_> {
|
||||||
|
@ -72,7 +72,7 @@ pub(crate) mod printf {
|
||||||
///
|
///
|
||||||
/// Returns `Err` in cases where the `printf` directive does not have an exact Rust
|
/// Returns `Err` in cases where the `printf` directive does not have an exact Rust
|
||||||
/// equivalent, rather than guessing.
|
/// equivalent, rather than guessing.
|
||||||
pub fn translate(&self) -> Result<String, Option<String>> {
|
pub(crate) fn translate(&self) -> Result<String, Option<String>> {
|
||||||
use std::fmt::Write;
|
use std::fmt::Write;
|
||||||
|
|
||||||
let (c_alt, c_zero, c_left, c_plus) = {
|
let (c_alt, c_zero, c_left, c_plus) = {
|
||||||
|
@ -249,7 +249,7 @@ pub(crate) mod printf {
|
||||||
|
|
||||||
/// A general number used in a `printf` formatting directive.
|
/// A general number used in a `printf` formatting directive.
|
||||||
#[derive(Copy, Clone, PartialEq, Debug)]
|
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||||
pub enum Num {
|
enum Num {
|
||||||
// The range of these values is technically bounded by `NL_ARGMAX`... but, at least for GNU
|
// The range of these values is technically bounded by `NL_ARGMAX`... but, at least for GNU
|
||||||
// libc, it apparently has no real fixed limit. A `u16` is used here on the basis that it
|
// libc, it apparently has no real fixed limit. A `u16` is used here on the basis that it
|
||||||
// is *vanishingly* unlikely that *anyone* is going to try formatting something wider, or
|
// is *vanishingly* unlikely that *anyone* is going to try formatting something wider, or
|
||||||
|
@ -288,12 +288,12 @@ pub(crate) mod printf {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns an iterator over all substitutions in a given string.
|
/// Returns an iterator over all substitutions in a given string.
|
||||||
pub fn iter_subs(s: &str, start_pos: usize) -> Substitutions<'_> {
|
pub(crate) fn iter_subs(s: &str, start_pos: usize) -> Substitutions<'_> {
|
||||||
Substitutions { s, pos: start_pos }
|
Substitutions { s, pos: start_pos }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Iterator over substitutions in a string.
|
/// Iterator over substitutions in a string.
|
||||||
pub struct Substitutions<'a> {
|
pub(crate) struct Substitutions<'a> {
|
||||||
s: &'a str,
|
s: &'a str,
|
||||||
pos: usize,
|
pos: usize,
|
||||||
}
|
}
|
||||||
|
@ -327,7 +327,7 @@ pub(crate) mod printf {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse the next substitution from the input string.
|
/// Parse the next substitution from the input string.
|
||||||
pub fn parse_next_substitution(s: &str) -> Option<(Substitution<'_>, &str)> {
|
fn parse_next_substitution(s: &str) -> Option<(Substitution<'_>, &str)> {
|
||||||
use self::State::*;
|
use self::State::*;
|
||||||
|
|
||||||
let at = {
|
let at = {
|
||||||
|
@ -615,20 +615,20 @@ pub(crate) mod printf {
|
||||||
mod tests;
|
mod tests;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod shell {
|
pub(crate) mod shell {
|
||||||
use rustc_span::InnerSpan;
|
use rustc_span::InnerSpan;
|
||||||
|
|
||||||
use super::strcursor::StrCursor as Cur;
|
use super::strcursor::StrCursor as Cur;
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug)]
|
#[derive(Clone, PartialEq, Debug)]
|
||||||
pub enum Substitution<'a> {
|
pub(crate) enum Substitution<'a> {
|
||||||
Ordinal(u8, (usize, usize)),
|
Ordinal(u8, (usize, usize)),
|
||||||
Name(&'a str, (usize, usize)),
|
Name(&'a str, (usize, usize)),
|
||||||
Escape((usize, usize)),
|
Escape((usize, usize)),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Substitution<'_> {
|
impl Substitution<'_> {
|
||||||
pub fn as_str(&self) -> String {
|
pub(crate) fn as_str(&self) -> String {
|
||||||
match self {
|
match self {
|
||||||
Substitution::Ordinal(n, _) => format!("${n}"),
|
Substitution::Ordinal(n, _) => format!("${n}"),
|
||||||
Substitution::Name(n, _) => format!("${n}"),
|
Substitution::Name(n, _) => format!("${n}"),
|
||||||
|
@ -636,17 +636,17 @@ pub mod shell {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn position(&self) -> InnerSpan {
|
pub(crate) fn position(&self) -> InnerSpan {
|
||||||
let (Self::Ordinal(_, pos) | Self::Name(_, pos) | Self::Escape(pos)) = self;
|
let (Self::Ordinal(_, pos) | Self::Name(_, pos) | Self::Escape(pos)) = self;
|
||||||
InnerSpan::new(pos.0, pos.1)
|
InnerSpan::new(pos.0, pos.1)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_position(&mut self, start: usize, end: usize) {
|
fn set_position(&mut self, start: usize, end: usize) {
|
||||||
let (Self::Ordinal(_, pos) | Self::Name(_, pos) | Self::Escape(pos)) = self;
|
let (Self::Ordinal(_, pos) | Self::Name(_, pos) | Self::Escape(pos)) = self;
|
||||||
*pos = (start, end);
|
*pos = (start, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn translate(&self) -> Result<String, Option<String>> {
|
pub(crate) fn translate(&self) -> Result<String, Option<String>> {
|
||||||
match self {
|
match self {
|
||||||
Substitution::Ordinal(n, _) => Ok(format!("{{{}}}", n)),
|
Substitution::Ordinal(n, _) => Ok(format!("{{{}}}", n)),
|
||||||
Substitution::Name(n, _) => Ok(format!("{{{}}}", n)),
|
Substitution::Name(n, _) => Ok(format!("{{{}}}", n)),
|
||||||
|
@ -656,12 +656,12 @@ pub mod shell {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns an iterator over all substitutions in a given string.
|
/// Returns an iterator over all substitutions in a given string.
|
||||||
pub fn iter_subs(s: &str, start_pos: usize) -> Substitutions<'_> {
|
pub(crate) fn iter_subs(s: &str, start_pos: usize) -> Substitutions<'_> {
|
||||||
Substitutions { s, pos: start_pos }
|
Substitutions { s, pos: start_pos }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Iterator over substitutions in a string.
|
/// Iterator over substitutions in a string.
|
||||||
pub struct Substitutions<'a> {
|
pub(crate) struct Substitutions<'a> {
|
||||||
s: &'a str,
|
s: &'a str,
|
||||||
pos: usize,
|
pos: usize,
|
||||||
}
|
}
|
||||||
|
@ -683,7 +683,7 @@ pub mod shell {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse the next substitution from the input string.
|
/// Parse the next substitution from the input string.
|
||||||
pub fn parse_next_substitution(s: &str) -> Option<(Substitution<'_>, &str)> {
|
fn parse_next_substitution(s: &str) -> Option<(Substitution<'_>, &str)> {
|
||||||
let at = {
|
let at = {
|
||||||
let start = s.find('$')?;
|
let start = s.find('$')?;
|
||||||
match s[start + 1..].chars().next()? {
|
match s[start + 1..].chars().next()? {
|
||||||
|
@ -743,24 +743,24 @@ pub mod shell {
|
||||||
}
|
}
|
||||||
|
|
||||||
mod strcursor {
|
mod strcursor {
|
||||||
pub struct StrCursor<'a> {
|
pub(crate) struct StrCursor<'a> {
|
||||||
s: &'a str,
|
s: &'a str,
|
||||||
pub at: usize,
|
pub at: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> StrCursor<'a> {
|
impl<'a> StrCursor<'a> {
|
||||||
pub fn new_at(s: &'a str, at: usize) -> StrCursor<'a> {
|
pub(crate) fn new_at(s: &'a str, at: usize) -> StrCursor<'a> {
|
||||||
StrCursor { s, at }
|
StrCursor { s, at }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn at_next_cp(mut self) -> Option<StrCursor<'a>> {
|
pub(crate) fn at_next_cp(mut self) -> Option<StrCursor<'a>> {
|
||||||
match self.try_seek_right_cp() {
|
match self.try_seek_right_cp() {
|
||||||
true => Some(self),
|
true => Some(self),
|
||||||
false => None,
|
false => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn next_cp(mut self) -> Option<(char, StrCursor<'a>)> {
|
pub(crate) fn next_cp(mut self) -> Option<(char, StrCursor<'a>)> {
|
||||||
let cp = self.cp_after()?;
|
let cp = self.cp_after()?;
|
||||||
self.seek_right(cp.len_utf8());
|
self.seek_right(cp.len_utf8());
|
||||||
Some((cp, self))
|
Some((cp, self))
|
||||||
|
@ -770,11 +770,11 @@ mod strcursor {
|
||||||
&self.s[0..self.at]
|
&self.s[0..self.at]
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn slice_after(&self) -> &'a str {
|
pub(crate) fn slice_after(&self) -> &'a str {
|
||||||
&self.s[self.at..]
|
&self.s[self.at..]
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn slice_between(&self, until: StrCursor<'a>) -> Option<&'a str> {
|
pub(crate) fn slice_between(&self, until: StrCursor<'a>) -> Option<&'a str> {
|
||||||
if !str_eq_literal(self.s, until.s) {
|
if !str_eq_literal(self.s, until.s) {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#![feature(proc_macro_quote)]
|
#![feature(proc_macro_quote)]
|
||||||
#![feature(rustdoc_internals)]
|
#![feature(rustdoc_internals)]
|
||||||
#![feature(try_blocks)]
|
#![feature(try_blocks)]
|
||||||
|
#![warn(unreachable_pub)]
|
||||||
// tidy-alphabetical-end
|
// tidy-alphabetical-end
|
||||||
|
|
||||||
extern crate proc_macro;
|
extern crate proc_macro;
|
||||||
|
|
|
@ -17,7 +17,6 @@ pub(crate) fn check_builtin_macro_attribute(ecx: &ExtCtxt<'_>, meta_item: &MetaI
|
||||||
// All the built-in macro attributes are "words" at the moment.
|
// All the built-in macro attributes are "words" at the moment.
|
||||||
let template = AttributeTemplate { word: true, ..Default::default() };
|
let template = AttributeTemplate { word: true, ..Default::default() };
|
||||||
validate_attr::check_builtin_meta_item(
|
validate_attr::check_builtin_meta_item(
|
||||||
&ecx.ecfg.features,
|
|
||||||
&ecx.sess.psess,
|
&ecx.sess.psess,
|
||||||
meta_item,
|
meta_item,
|
||||||
AttrStyle::Outer,
|
AttrStyle::Outer,
|
||||||
|
|
|
@ -6,8 +6,7 @@
|
||||||
extern_types,
|
extern_types,
|
||||||
naked_functions,
|
naked_functions,
|
||||||
thread_local,
|
thread_local,
|
||||||
repr_simd,
|
repr_simd
|
||||||
raw_ref_op
|
|
||||||
)]
|
)]
|
||||||
#![no_core]
|
#![no_core]
|
||||||
#![allow(dead_code, non_camel_case_types, internal_features)]
|
#![allow(dead_code, non_camel_case_types, internal_features)]
|
||||||
|
|
|
@ -25,7 +25,7 @@ pub(crate) fn analyze(fx: &FunctionCx<'_, '_, '_>) -> IndexVec<Local, SsaKind> {
|
||||||
for stmt in bb.statements.iter() {
|
for stmt in bb.statements.iter() {
|
||||||
match &stmt.kind {
|
match &stmt.kind {
|
||||||
Assign(place_and_rval) => match &place_and_rval.1 {
|
Assign(place_and_rval) => match &place_and_rval.1 {
|
||||||
Rvalue::Ref(_, _, place) | Rvalue::AddressOf(_, place) => {
|
Rvalue::Ref(_, _, place) | Rvalue::RawPtr(_, place) => {
|
||||||
flag_map[place.local] = SsaKind::NotSsa;
|
flag_map[place.local] = SsaKind::NotSsa;
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
|
|
@ -1,13 +1,6 @@
|
||||||
use std::borrow::Borrow;
|
|
||||||
use std::fs;
|
|
||||||
use std::path::Path;
|
|
||||||
|
|
||||||
use ar_archive_writer::{COFFShortExport, MachineTypes};
|
|
||||||
use rustc_codegen_ssa::back::archive::{
|
use rustc_codegen_ssa::back::archive::{
|
||||||
create_mingw_dll_import_lib, ArArchiveBuilder, ArchiveBuilder, ArchiveBuilderBuilder,
|
ArArchiveBuilder, ArchiveBuilder, ArchiveBuilderBuilder, DEFAULT_OBJECT_READER,
|
||||||
DEFAULT_OBJECT_READER,
|
|
||||||
};
|
};
|
||||||
use rustc_codegen_ssa::common::is_mingw_gnu_toolchain;
|
|
||||||
use rustc_session::Session;
|
use rustc_session::Session;
|
||||||
|
|
||||||
pub(crate) struct ArArchiveBuilderBuilder;
|
pub(crate) struct ArArchiveBuilderBuilder;
|
||||||
|
@ -16,78 +9,4 @@ impl ArchiveBuilderBuilder for ArArchiveBuilderBuilder {
|
||||||
fn new_archive_builder<'a>(&self, sess: &'a Session) -> Box<dyn ArchiveBuilder + 'a> {
|
fn new_archive_builder<'a>(&self, sess: &'a Session) -> Box<dyn ArchiveBuilder + 'a> {
|
||||||
Box::new(ArArchiveBuilder::new(sess, &DEFAULT_OBJECT_READER))
|
Box::new(ArArchiveBuilder::new(sess, &DEFAULT_OBJECT_READER))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_dll_import_lib(
|
|
||||||
&self,
|
|
||||||
sess: &Session,
|
|
||||||
lib_name: &str,
|
|
||||||
import_name_and_ordinal_vector: Vec<(String, Option<u16>)>,
|
|
||||||
output_path: &Path,
|
|
||||||
) {
|
|
||||||
if is_mingw_gnu_toolchain(&sess.target) {
|
|
||||||
// The binutils linker used on -windows-gnu targets cannot read the import
|
|
||||||
// libraries generated by LLVM: in our attempts, the linker produced an .EXE
|
|
||||||
// that loaded but crashed with an AV upon calling one of the imported
|
|
||||||
// functions. Therefore, use binutils to create the import library instead,
|
|
||||||
// by writing a .DEF file to the temp dir and calling binutils's dlltool.
|
|
||||||
create_mingw_dll_import_lib(
|
|
||||||
sess,
|
|
||||||
lib_name,
|
|
||||||
import_name_and_ordinal_vector,
|
|
||||||
output_path,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
let mut file =
|
|
||||||
match fs::OpenOptions::new().write(true).create_new(true).open(&output_path) {
|
|
||||||
Ok(file) => file,
|
|
||||||
Err(error) => {
|
|
||||||
sess.dcx().fatal(format!(
|
|
||||||
"failed to create import library file `{path}`: {error}",
|
|
||||||
path = output_path.display(),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let machine = match sess.target.arch.borrow() {
|
|
||||||
"x86" => MachineTypes::I386,
|
|
||||||
"x86_64" => MachineTypes::AMD64,
|
|
||||||
"arm" => MachineTypes::ARMNT,
|
|
||||||
"aarch64" => MachineTypes::ARM64,
|
|
||||||
_ => {
|
|
||||||
sess.dcx().fatal(format!(
|
|
||||||
"unsupported target architecture `{arch}`",
|
|
||||||
arch = sess.target.arch,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let exports = import_name_and_ordinal_vector
|
|
||||||
.iter()
|
|
||||||
.map(|(name, ordinal)| COFFShortExport {
|
|
||||||
name: name.to_string(),
|
|
||||||
ext_name: None,
|
|
||||||
symbol_name: None,
|
|
||||||
alias_target: None,
|
|
||||||
ordinal: ordinal.unwrap_or(0),
|
|
||||||
noname: ordinal.is_some(),
|
|
||||||
data: false,
|
|
||||||
private: false,
|
|
||||||
constant: false,
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
if let Err(error) = ar_archive_writer::write_import_library(
|
|
||||||
&mut file,
|
|
||||||
lib_name,
|
|
||||||
&exports,
|
|
||||||
machine,
|
|
||||||
!sess.target.is_like_msvc,
|
|
||||||
) {
|
|
||||||
sess.dcx().fatal(format!(
|
|
||||||
"failed to create import library `{path}`: `{error}`",
|
|
||||||
path = output_path.display(),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -595,7 +595,7 @@ fn codegen_stmt<'tcx>(
|
||||||
let val = cplace.to_cvalue(fx);
|
let val = cplace.to_cvalue(fx);
|
||||||
lval.write_cvalue(fx, val)
|
lval.write_cvalue(fx, val)
|
||||||
}
|
}
|
||||||
Rvalue::Ref(_, _, place) | Rvalue::AddressOf(_, place) => {
|
Rvalue::Ref(_, _, place) | Rvalue::RawPtr(_, place) => {
|
||||||
let place = codegen_place(fx, place);
|
let place = codegen_place(fx, place);
|
||||||
let ref_ = place.place_ref(fx, lval.layout());
|
let ref_ = place.place_ref(fx, lval.layout());
|
||||||
lval.write_cvalue(fx, ref_);
|
lval.write_cvalue(fx, ref_);
|
||||||
|
|
|
@ -69,7 +69,7 @@ fn clif_type_from_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option<types::Typ
|
||||||
FloatTy::F64 => types::F64,
|
FloatTy::F64 => types::F64,
|
||||||
FloatTy::F128 => unimplemented!("f16_f128"),
|
FloatTy::F128 => unimplemented!("f16_f128"),
|
||||||
},
|
},
|
||||||
ty::FnPtr(_) => pointer_ty(tcx),
|
ty::FnPtr(..) => pointer_ty(tcx),
|
||||||
ty::RawPtr(pointee_ty, _) | ty::Ref(_, pointee_ty, _) => {
|
ty::RawPtr(pointee_ty, _) | ty::Ref(_, pointee_ty, _) => {
|
||||||
if has_ptr_meta(tcx, *pointee_ty) {
|
if has_ptr_meta(tcx, *pointee_ty) {
|
||||||
return None;
|
return None;
|
||||||
|
|
|
@ -191,6 +191,14 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
|
||||||
})
|
})
|
||||||
.try_into()
|
.try_into()
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
|
_ if idx_ty.is_simd()
|
||||||
|
&& matches!(
|
||||||
|
idx_ty.simd_size_and_type(fx.tcx).1.kind(),
|
||||||
|
ty::Uint(ty::UintTy::U32)
|
||||||
|
) =>
|
||||||
|
{
|
||||||
|
idx_ty.simd_size_and_type(fx.tcx).0.try_into().unwrap()
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
fx.tcx.dcx().span_err(
|
fx.tcx.dcx().span_err(
|
||||||
span,
|
span,
|
||||||
|
@ -213,6 +221,8 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
|
||||||
|
|
||||||
let total_len = lane_count * 2;
|
let total_len = lane_count * 2;
|
||||||
|
|
||||||
|
// FIXME: this is a terrible abstraction-breaking hack.
|
||||||
|
// Find a way to reuse `immediate_const_vector` from `codegen_ssa` instead.
|
||||||
let indexes = {
|
let indexes = {
|
||||||
use rustc_middle::mir::interpret::*;
|
use rustc_middle::mir::interpret::*;
|
||||||
let idx_const = match &idx.node {
|
let idx_const = match &idx.node {
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
#![warn(unused_lifetimes)]
|
#![warn(unused_lifetimes)]
|
||||||
// tidy-alphabetical-end
|
// tidy-alphabetical-end
|
||||||
|
|
||||||
extern crate ar_archive_writer;
|
|
||||||
extern crate jobserver;
|
extern crate jobserver;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate rustc_middle;
|
extern crate rustc_middle;
|
||||||
|
|
|
@ -874,7 +874,7 @@ pub(crate) fn assert_assignable<'tcx>(
|
||||||
(ty::Ref(_, a, _), ty::RawPtr(b, _)) | (ty::RawPtr(a, _), ty::Ref(_, b, _)) => {
|
(ty::Ref(_, a, _), ty::RawPtr(b, _)) | (ty::RawPtr(a, _), ty::Ref(_, b, _)) => {
|
||||||
assert_assignable(fx, *a, *b, limit - 1);
|
assert_assignable(fx, *a, *b, limit - 1);
|
||||||
}
|
}
|
||||||
(ty::FnPtr(_), ty::FnPtr(_)) => {
|
(ty::FnPtr(..), ty::FnPtr(..)) => {
|
||||||
let from_sig = fx.tcx.normalize_erasing_late_bound_regions(
|
let from_sig = fx.tcx.normalize_erasing_late_bound_regions(
|
||||||
ParamEnv::reveal_all(),
|
ParamEnv::reveal_all(),
|
||||||
from_ty.fn_sig(fx.tcx),
|
from_ty.fn_sig(fx.tcx),
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
#![feature(
|
#![feature(
|
||||||
no_core, unboxed_closures, start, lang_items, never_type, linkage,
|
no_core, unboxed_closures, start, lang_items, never_type, linkage,
|
||||||
extern_types, thread_local, raw_ref_op
|
extern_types, thread_local
|
||||||
)]
|
)]
|
||||||
#![no_core]
|
#![no_core]
|
||||||
#![allow(dead_code, internal_features, non_camel_case_types)]
|
#![allow(dead_code, internal_features, non_camel_case_types)]
|
||||||
|
|
|
@ -1923,15 +1923,11 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
|
||||||
v2: RValue<'gcc>,
|
v2: RValue<'gcc>,
|
||||||
mask: RValue<'gcc>,
|
mask: RValue<'gcc>,
|
||||||
) -> RValue<'gcc> {
|
) -> RValue<'gcc> {
|
||||||
let struct_type = mask.get_type().is_struct().expect("mask should be of struct type");
|
|
||||||
|
|
||||||
// TODO(antoyo): use a recursive unqualified() here.
|
// TODO(antoyo): use a recursive unqualified() here.
|
||||||
let vector_type = v1.get_type().unqualified().dyncast_vector().expect("vector type");
|
let vector_type = v1.get_type().unqualified().dyncast_vector().expect("vector type");
|
||||||
let element_type = vector_type.get_element_type();
|
let element_type = vector_type.get_element_type();
|
||||||
let vec_num_units = vector_type.get_num_units();
|
let vec_num_units = vector_type.get_num_units();
|
||||||
|
|
||||||
let mask_num_units = struct_type.get_field_count();
|
|
||||||
let mut vector_elements = vec![];
|
|
||||||
let mask_element_type = if element_type.is_integral() {
|
let mask_element_type = if element_type.is_integral() {
|
||||||
element_type
|
element_type
|
||||||
} else {
|
} else {
|
||||||
|
@ -1942,19 +1938,39 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
|
||||||
#[cfg(not(feature = "master"))]
|
#[cfg(not(feature = "master"))]
|
||||||
self.int_type
|
self.int_type
|
||||||
};
|
};
|
||||||
for i in 0..mask_num_units {
|
|
||||||
let field = struct_type.get_field(i as i32);
|
let mut mask_elements = if let Some(vector_type) = mask.get_type().dyncast_vector() {
|
||||||
vector_elements.push(self.context.new_cast(
|
let mask_num_units = vector_type.get_num_units();
|
||||||
self.location,
|
let mut mask_elements = vec![];
|
||||||
mask.access_field(self.location, field).to_rvalue(),
|
for i in 0..mask_num_units {
|
||||||
mask_element_type,
|
let index = self.context.new_rvalue_from_long(self.cx.type_u32(), i as _);
|
||||||
));
|
mask_elements.push(self.context.new_cast(
|
||||||
}
|
self.location,
|
||||||
|
self.extract_element(mask, index).to_rvalue(),
|
||||||
|
mask_element_type,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
mask_elements
|
||||||
|
} else {
|
||||||
|
let struct_type = mask.get_type().is_struct().expect("mask should be of struct type");
|
||||||
|
let mask_num_units = struct_type.get_field_count();
|
||||||
|
let mut mask_elements = vec![];
|
||||||
|
for i in 0..mask_num_units {
|
||||||
|
let field = struct_type.get_field(i as i32);
|
||||||
|
mask_elements.push(self.context.new_cast(
|
||||||
|
self.location,
|
||||||
|
mask.access_field(self.location, field).to_rvalue(),
|
||||||
|
mask_element_type,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
mask_elements
|
||||||
|
};
|
||||||
|
let mask_num_units = mask_elements.len();
|
||||||
|
|
||||||
// NOTE: the mask needs to be the same length as the input vectors, so add the missing
|
// NOTE: the mask needs to be the same length as the input vectors, so add the missing
|
||||||
// elements in the mask if needed.
|
// elements in the mask if needed.
|
||||||
for _ in mask_num_units..vec_num_units {
|
for _ in mask_num_units..vec_num_units {
|
||||||
vector_elements.push(self.context.new_rvalue_zero(mask_element_type));
|
mask_elements.push(self.context.new_rvalue_zero(mask_element_type));
|
||||||
}
|
}
|
||||||
|
|
||||||
let result_type = self.context.new_vector_type(element_type, mask_num_units as u64);
|
let result_type = self.context.new_vector_type(element_type, mask_num_units as u64);
|
||||||
|
@ -1998,7 +2014,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
|
||||||
|
|
||||||
let new_mask_num_units = std::cmp::max(mask_num_units, vec_num_units);
|
let new_mask_num_units = std::cmp::max(mask_num_units, vec_num_units);
|
||||||
let mask_type = self.context.new_vector_type(mask_element_type, new_mask_num_units as u64);
|
let mask_type = self.context.new_vector_type(mask_element_type, new_mask_num_units as u64);
|
||||||
let mask = self.context.new_rvalue_from_vector(self.location, mask_type, &vector_elements);
|
let mask = self.context.new_rvalue_from_vector(self.location, mask_type, &mask_elements);
|
||||||
let result = self.context.new_rvalue_vector_perm(self.location, v1, v2, mask);
|
let result = self.context.new_rvalue_vector_perm(self.location, v1, v2, mask);
|
||||||
|
|
||||||
if vec_num_units != mask_num_units {
|
if vec_num_units != mask_num_units {
|
||||||
|
|
|
@ -353,19 +353,24 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
|
||||||
}
|
}
|
||||||
|
|
||||||
if name == sym::simd_shuffle {
|
if name == sym::simd_shuffle {
|
||||||
// Make sure this is actually an array, since typeck only checks the length-suffixed
|
// Make sure this is actually an array or SIMD vector, since typeck only checks the length-suffixed
|
||||||
// version of this intrinsic.
|
// version of this intrinsic.
|
||||||
let n: u64 = match *args[2].layout.ty.kind() {
|
let idx_ty = args[2].layout.ty;
|
||||||
|
let n: u64 = match idx_ty.kind() {
|
||||||
ty::Array(ty, len) if matches!(*ty.kind(), ty::Uint(ty::UintTy::U32)) => {
|
ty::Array(ty, len) if matches!(*ty.kind(), ty::Uint(ty::UintTy::U32)) => {
|
||||||
len.try_eval_target_usize(bx.cx.tcx, ty::ParamEnv::reveal_all()).unwrap_or_else(
|
len.try_eval_target_usize(bx.cx.tcx, ty::ParamEnv::reveal_all()).unwrap_or_else(
|
||||||
|| span_bug!(span, "could not evaluate shuffle index array length"),
|
|| span_bug!(span, "could not evaluate shuffle index array length"),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
_ => return_error!(InvalidMonomorphization::SimdShuffle {
|
_ if idx_ty.is_simd()
|
||||||
span,
|
&& matches!(
|
||||||
name,
|
idx_ty.simd_size_and_type(bx.cx.tcx).1.kind(),
|
||||||
ty: args[2].layout.ty
|
ty::Uint(ty::UintTy::U32)
|
||||||
}),
|
) =>
|
||||||
|
{
|
||||||
|
idx_ty.simd_size_and_type(bx.cx.tcx).0
|
||||||
|
}
|
||||||
|
_ => return_error!(InvalidMonomorphization::SimdShuffle { span, name, ty: idx_ty }),
|
||||||
};
|
};
|
||||||
require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty });
|
require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty });
|
||||||
|
|
||||||
|
|
|
@ -213,9 +213,8 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> {
|
||||||
// NOTE: we cannot remove this match like in the LLVM codegen because the call
|
// NOTE: we cannot remove this match like in the LLVM codegen because the call
|
||||||
// to fn_ptr_backend_type handle the on-stack attribute.
|
// to fn_ptr_backend_type handle the on-stack attribute.
|
||||||
// TODO(antoyo): find a less hackish way to hande the on-stack attribute.
|
// TODO(antoyo): find a less hackish way to hande the on-stack attribute.
|
||||||
ty::FnPtr(sig) => {
|
ty::FnPtr(sig_tys, hdr) => cx
|
||||||
cx.fn_ptr_backend_type(cx.fn_abi_of_fn_ptr(sig, ty::List::empty()))
|
.fn_ptr_backend_type(cx.fn_abi_of_fn_ptr(sig_tys.with(hdr), ty::List::empty())),
|
||||||
}
|
|
||||||
_ => self.scalar_gcc_type_at(cx, scalar, Size::ZERO),
|
_ => self.scalar_gcc_type_at(cx, scalar, Size::ZERO),
|
||||||
};
|
};
|
||||||
cx.scalar_types.borrow_mut().insert(self.ty, ty);
|
cx.scalar_types.borrow_mut().insert(self.ty, ty);
|
||||||
|
|
|
@ -3,12 +3,10 @@
|
||||||
// Run-time:
|
// Run-time:
|
||||||
// status: 0
|
// status: 0
|
||||||
|
|
||||||
#![feature(asm_const)]
|
#[cfg(target_arch = "x86_64")]
|
||||||
|
|
||||||
#[cfg(target_arch="x86_64")]
|
|
||||||
use std::arch::{asm, global_asm};
|
use std::arch::{asm, global_asm};
|
||||||
|
|
||||||
#[cfg(target_arch="x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
global_asm!(
|
global_asm!(
|
||||||
"
|
"
|
||||||
.global add_asm
|
.global add_asm
|
||||||
|
@ -22,7 +20,7 @@ extern "C" {
|
||||||
fn add_asm(a: i64, b: i64) -> i64;
|
fn add_asm(a: i64, b: i64) -> i64;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_arch="x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
pub unsafe fn mem_cpy(dst: *mut u8, src: *const u8, len: usize) {
|
pub unsafe fn mem_cpy(dst: *mut u8, src: *const u8, len: usize) {
|
||||||
asm!(
|
asm!(
|
||||||
"rep movsb",
|
"rep movsb",
|
||||||
|
@ -33,7 +31,7 @@ pub unsafe fn mem_cpy(dst: *mut u8, src: *const u8, len: usize) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_arch="x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
fn asm() {
|
fn asm() {
|
||||||
unsafe {
|
unsafe {
|
||||||
asm!("nop");
|
asm!("nop");
|
||||||
|
@ -178,9 +176,8 @@ fn asm() {
|
||||||
assert_eq!(array1, array2);
|
assert_eq!(array1, array2);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(target_arch="x86_64"))]
|
#[cfg(not(target_arch = "x86_64"))]
|
||||||
fn asm() {
|
fn asm() {}
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
asm();
|
asm();
|
||||||
|
|
|
@ -12,7 +12,7 @@ bitflags = "2.4.1"
|
||||||
itertools = "0.12"
|
itertools = "0.12"
|
||||||
libc = "0.2"
|
libc = "0.2"
|
||||||
measureme = "11"
|
measureme = "11"
|
||||||
object = { version = "0.36.2", default-features = false, features = ["std", "read"] }
|
object = { version = "0.36.3", default-features = false, features = ["std", "read"] }
|
||||||
rustc-demangle = "0.1.21"
|
rustc-demangle = "0.1.21"
|
||||||
rustc_ast = { path = "../rustc_ast" }
|
rustc_ast = { path = "../rustc_ast" }
|
||||||
rustc_attr = { path = "../rustc_attr" }
|
rustc_attr = { path = "../rustc_attr" }
|
||||||
|
|
|
@ -5,9 +5,6 @@ codegen_llvm_dynamic_linking_with_lto =
|
||||||
.note = only 'staticlib', 'bin', and 'cdylib' outputs are supported with LTO
|
.note = only 'staticlib', 'bin', and 'cdylib' outputs are supported with LTO
|
||||||
|
|
||||||
|
|
||||||
codegen_llvm_error_creating_import_library =
|
|
||||||
Error creating import library for {$lib_name}: {$error}
|
|
||||||
|
|
||||||
codegen_llvm_fixed_x18_invalid_arch = the `-Zfixed-x18` flag is not supported on the `{$arch}` architecture
|
codegen_llvm_fixed_x18_invalid_arch = the `-Zfixed-x18` flag is not supported on the `{$arch}` architecture
|
||||||
|
|
||||||
codegen_llvm_from_llvm_diag = {$message}
|
codegen_llvm_from_llvm_diag = {$message}
|
||||||
|
|
|
@ -6,13 +6,13 @@ use rustc_codegen_ssa::mir::place::{PlaceRef, PlaceValue};
|
||||||
use rustc_codegen_ssa::traits::*;
|
use rustc_codegen_ssa::traits::*;
|
||||||
use rustc_codegen_ssa::MemFlags;
|
use rustc_codegen_ssa::MemFlags;
|
||||||
use rustc_middle::ty::layout::LayoutOf;
|
use rustc_middle::ty::layout::LayoutOf;
|
||||||
pub use rustc_middle::ty::layout::{FAT_PTR_ADDR, FAT_PTR_EXTRA};
|
pub(crate) use rustc_middle::ty::layout::{FAT_PTR_ADDR, FAT_PTR_EXTRA};
|
||||||
use rustc_middle::ty::Ty;
|
use rustc_middle::ty::Ty;
|
||||||
use rustc_middle::{bug, ty};
|
use rustc_middle::{bug, ty};
|
||||||
use rustc_session::config;
|
use rustc_session::config;
|
||||||
pub use rustc_target::abi::call::*;
|
pub(crate) use rustc_target::abi::call::*;
|
||||||
use rustc_target::abi::{self, HasDataLayout, Int, Size};
|
use rustc_target::abi::{self, HasDataLayout, Int, Size};
|
||||||
pub use rustc_target::spec::abi::Abi;
|
pub(crate) use rustc_target::spec::abi::Abi;
|
||||||
use rustc_target::spec::SanitizerSet;
|
use rustc_target::spec::SanitizerSet;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ use crate::type_of::LayoutLlvmExt;
|
||||||
use crate::value::Value;
|
use crate::value::Value;
|
||||||
use crate::{attributes, llvm_util};
|
use crate::{attributes, llvm_util};
|
||||||
|
|
||||||
pub trait ArgAttributesExt {
|
trait ArgAttributesExt {
|
||||||
fn apply_attrs_to_llfn(&self, idx: AttributePlace, cx: &CodegenCx<'_, '_>, llfn: &Value);
|
fn apply_attrs_to_llfn(&self, idx: AttributePlace, cx: &CodegenCx<'_, '_>, llfn: &Value);
|
||||||
fn apply_attrs_to_callsite(
|
fn apply_attrs_to_callsite(
|
||||||
&self,
|
&self,
|
||||||
|
@ -111,7 +111,7 @@ impl ArgAttributesExt for ArgAttributes {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait LlvmType {
|
pub(crate) trait LlvmType {
|
||||||
fn llvm_type<'ll>(&self, cx: &CodegenCx<'ll, '_>) -> &'ll Type;
|
fn llvm_type<'ll>(&self, cx: &CodegenCx<'ll, '_>) -> &'ll Type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,7 +171,7 @@ impl LlvmType for CastTarget {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ArgAbiExt<'ll, 'tcx> {
|
trait ArgAbiExt<'ll, 'tcx> {
|
||||||
fn memory_ty(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type;
|
fn memory_ty(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type;
|
||||||
fn store(
|
fn store(
|
||||||
&self,
|
&self,
|
||||||
|
@ -307,7 +307,7 @@ impl<'ll, 'tcx> ArgAbiMethods<'tcx> for Builder<'_, 'll, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait FnAbiLlvmExt<'ll, 'tcx> {
|
pub(crate) trait FnAbiLlvmExt<'ll, 'tcx> {
|
||||||
fn llvm_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type;
|
fn llvm_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type;
|
||||||
fn ptr_to_llvm_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type;
|
fn ptr_to_llvm_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type;
|
||||||
fn llvm_cconv(&self) -> llvm::CallConv;
|
fn llvm_cconv(&self) -> llvm::CallConv;
|
||||||
|
|
|
@ -149,7 +149,7 @@ fn create_wrapper_function(
|
||||||
}
|
}
|
||||||
llvm::LLVMRustSetVisibility(callee, llvm::Visibility::Hidden);
|
llvm::LLVMRustSetVisibility(callee, llvm::Visibility::Hidden);
|
||||||
|
|
||||||
let llbb = llvm::LLVMAppendBasicBlockInContext(llcx, llfn, c"entry".as_ptr().cast());
|
let llbb = llvm::LLVMAppendBasicBlockInContext(llcx, llfn, c"entry".as_ptr());
|
||||||
|
|
||||||
let llbuilder = llvm::LLVMCreateBuilderInContext(llcx);
|
let llbuilder = llvm::LLVMCreateBuilderInContext(llcx);
|
||||||
llvm::LLVMPositionBuilderAtEnd(llbuilder, llbb);
|
llvm::LLVMPositionBuilderAtEnd(llbuilder, llbb);
|
||||||
|
|
|
@ -913,8 +913,10 @@ fn llvm_asm_scalar_type<'ll>(cx: &CodegenCx<'ll, '_>, scalar: Scalar) -> &'ll Ty
|
||||||
Primitive::Int(Integer::I16, _) => cx.type_i16(),
|
Primitive::Int(Integer::I16, _) => cx.type_i16(),
|
||||||
Primitive::Int(Integer::I32, _) => cx.type_i32(),
|
Primitive::Int(Integer::I32, _) => cx.type_i32(),
|
||||||
Primitive::Int(Integer::I64, _) => cx.type_i64(),
|
Primitive::Int(Integer::I64, _) => cx.type_i64(),
|
||||||
|
Primitive::Float(Float::F16) => cx.type_f16(),
|
||||||
Primitive::Float(Float::F32) => cx.type_f32(),
|
Primitive::Float(Float::F32) => cx.type_f32(),
|
||||||
Primitive::Float(Float::F64) => cx.type_f64(),
|
Primitive::Float(Float::F64) => cx.type_f64(),
|
||||||
|
Primitive::Float(Float::F128) => cx.type_f128(),
|
||||||
// FIXME(erikdesjardins): handle non-default addrspace ptr sizes
|
// FIXME(erikdesjardins): handle non-default addrspace ptr sizes
|
||||||
Primitive::Pointer(_) => cx.type_from_integer(dl.ptr_sized_integer()),
|
Primitive::Pointer(_) => cx.type_from_integer(dl.ptr_sized_integer()),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
|
@ -948,7 +950,9 @@ fn llvm_fixup_input<'ll, 'tcx>(
|
||||||
value
|
value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16), Abi::Scalar(s)) => {
|
(InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16), Abi::Scalar(s))
|
||||||
|
if s.primitive() != Primitive::Float(Float::F128) =>
|
||||||
|
{
|
||||||
let elem_ty = llvm_asm_scalar_type(bx.cx, s);
|
let elem_ty = llvm_asm_scalar_type(bx.cx, s);
|
||||||
let count = 16 / layout.size.bytes();
|
let count = 16 / layout.size.bytes();
|
||||||
let vec_ty = bx.cx.type_vector(elem_ty, count);
|
let vec_ty = bx.cx.type_vector(elem_ty, count);
|
||||||
|
@ -1090,7 +1094,9 @@ fn llvm_fixup_output<'ll, 'tcx>(
|
||||||
value
|
value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16), Abi::Scalar(s)) => {
|
(InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16), Abi::Scalar(s))
|
||||||
|
if s.primitive() != Primitive::Float(Float::F128) =>
|
||||||
|
{
|
||||||
value = bx.extract_element(value, bx.const_i32(0));
|
value = bx.extract_element(value, bx.const_i32(0));
|
||||||
if let Primitive::Pointer(_) = s.primitive() {
|
if let Primitive::Pointer(_) = s.primitive() {
|
||||||
value = bx.inttoptr(value, layout.llvm_type(bx.cx));
|
value = bx.inttoptr(value, layout.llvm_type(bx.cx));
|
||||||
|
@ -1222,7 +1228,9 @@ fn llvm_fixup_output_type<'ll, 'tcx>(
|
||||||
layout.llvm_type(cx)
|
layout.llvm_type(cx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16), Abi::Scalar(s)) => {
|
(InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16), Abi::Scalar(s))
|
||||||
|
if s.primitive() != Primitive::Float(Float::F128) =>
|
||||||
|
{
|
||||||
let elem_ty = llvm_asm_scalar_type(cx, s);
|
let elem_ty = llvm_asm_scalar_type(cx, s);
|
||||||
let count = 16 / layout.size.bytes();
|
let count = 16 / layout.size.bytes();
|
||||||
cx.type_vector(elem_ty, count)
|
cx.type_vector(elem_ty, count)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//! Set and unset common attributes on LLVM values.
|
//! Set and unset common attributes on LLVM values.
|
||||||
|
|
||||||
pub use rustc_attr::{InlineAttr, InstructionSetAttr, OptimizeAttr};
|
use rustc_attr::{InlineAttr, InstructionSetAttr, OptimizeAttr};
|
||||||
use rustc_codegen_ssa::traits::*;
|
use rustc_codegen_ssa::traits::*;
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, PatchableFunctionEntry};
|
use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, PatchableFunctionEntry};
|
||||||
|
@ -17,13 +17,13 @@ use crate::llvm::{self, AllocKindFlags, Attribute, AttributeKind, AttributePlace
|
||||||
use crate::value::Value;
|
use crate::value::Value;
|
||||||
use crate::{attributes, llvm_util};
|
use crate::{attributes, llvm_util};
|
||||||
|
|
||||||
pub fn apply_to_llfn(llfn: &Value, idx: AttributePlace, attrs: &[&Attribute]) {
|
pub(crate) fn apply_to_llfn(llfn: &Value, idx: AttributePlace, attrs: &[&Attribute]) {
|
||||||
if !attrs.is_empty() {
|
if !attrs.is_empty() {
|
||||||
llvm::AddFunctionAttributes(llfn, idx, attrs);
|
llvm::AddFunctionAttributes(llfn, idx, attrs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn apply_to_callsite(callsite: &Value, idx: AttributePlace, attrs: &[&Attribute]) {
|
pub(crate) fn apply_to_callsite(callsite: &Value, idx: AttributePlace, attrs: &[&Attribute]) {
|
||||||
if !attrs.is_empty() {
|
if !attrs.is_empty() {
|
||||||
llvm::AddCallSiteAttributes(callsite, idx, attrs);
|
llvm::AddCallSiteAttributes(callsite, idx, attrs);
|
||||||
}
|
}
|
||||||
|
@ -80,7 +80,7 @@ fn patchable_function_entry_attrs<'ll>(
|
||||||
|
|
||||||
/// Get LLVM sanitize attributes.
|
/// Get LLVM sanitize attributes.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn sanitize_attrs<'ll>(
|
pub(crate) fn sanitize_attrs<'ll>(
|
||||||
cx: &CodegenCx<'ll, '_>,
|
cx: &CodegenCx<'ll, '_>,
|
||||||
no_sanitize: SanitizerSet,
|
no_sanitize: SanitizerSet,
|
||||||
) -> SmallVec<[&'ll Attribute; 4]> {
|
) -> SmallVec<[&'ll Attribute; 4]> {
|
||||||
|
@ -120,7 +120,7 @@ pub fn sanitize_attrs<'ll>(
|
||||||
|
|
||||||
/// Tell LLVM to emit or not emit the information necessary to unwind the stack for the function.
|
/// Tell LLVM to emit or not emit the information necessary to unwind the stack for the function.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn uwtable_attr(llcx: &llvm::Context, use_sync_unwind: Option<bool>) -> &Attribute {
|
pub(crate) fn uwtable_attr(llcx: &llvm::Context, use_sync_unwind: Option<bool>) -> &Attribute {
|
||||||
// NOTE: We should determine if we even need async unwind tables, as they
|
// NOTE: We should determine if we even need async unwind tables, as they
|
||||||
// take have more overhead and if we can use sync unwind tables we
|
// take have more overhead and if we can use sync unwind tables we
|
||||||
// probably should.
|
// probably should.
|
||||||
|
@ -128,7 +128,7 @@ pub fn uwtable_attr(llcx: &llvm::Context, use_sync_unwind: Option<bool>) -> &Att
|
||||||
llvm::CreateUWTableAttr(llcx, async_unwind)
|
llvm::CreateUWTableAttr(llcx, async_unwind)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn frame_pointer_type_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> {
|
pub(crate) fn frame_pointer_type_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> {
|
||||||
let mut fp = cx.sess().target.frame_pointer;
|
let mut fp = cx.sess().target.frame_pointer;
|
||||||
let opts = &cx.sess().opts;
|
let opts = &cx.sess().opts;
|
||||||
// "mcount" function relies on stack pointer.
|
// "mcount" function relies on stack pointer.
|
||||||
|
@ -280,19 +280,19 @@ fn backchain_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> {
|
||||||
if found_positive { Some(llvm::CreateAttrString(cx.llcx, "backchain")) } else { None }
|
if found_positive { Some(llvm::CreateAttrString(cx.llcx, "backchain")) } else { None }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn target_cpu_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> &'ll Attribute {
|
pub(crate) fn target_cpu_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> &'ll Attribute {
|
||||||
let target_cpu = llvm_util::target_cpu(cx.tcx.sess);
|
let target_cpu = llvm_util::target_cpu(cx.tcx.sess);
|
||||||
llvm::CreateAttrStringValue(cx.llcx, "target-cpu", target_cpu)
|
llvm::CreateAttrStringValue(cx.llcx, "target-cpu", target_cpu)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tune_cpu_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> {
|
pub(crate) fn tune_cpu_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> {
|
||||||
llvm_util::tune_cpu(cx.tcx.sess)
|
llvm_util::tune_cpu(cx.tcx.sess)
|
||||||
.map(|tune_cpu| llvm::CreateAttrStringValue(cx.llcx, "tune-cpu", tune_cpu))
|
.map(|tune_cpu| llvm::CreateAttrStringValue(cx.llcx, "tune-cpu", tune_cpu))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the `NonLazyBind` LLVM attribute,
|
/// Get the `NonLazyBind` LLVM attribute,
|
||||||
/// if the codegen options allow skipping the PLT.
|
/// if the codegen options allow skipping the PLT.
|
||||||
pub fn non_lazy_bind_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> {
|
pub(crate) fn non_lazy_bind_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> {
|
||||||
// Don't generate calls through PLT if it's not necessary
|
// Don't generate calls through PLT if it's not necessary
|
||||||
if !cx.sess().needs_plt() {
|
if !cx.sess().needs_plt() {
|
||||||
Some(AttributeKind::NonLazyBind.create_attr(cx.llcx))
|
Some(AttributeKind::NonLazyBind.create_attr(cx.llcx))
|
||||||
|
@ -327,7 +327,7 @@ fn create_alloc_family_attr(llcx: &llvm::Context) -> &llvm::Attribute {
|
||||||
/// Helper for `FnAbi::apply_attrs_llfn`:
|
/// Helper for `FnAbi::apply_attrs_llfn`:
|
||||||
/// Composite function which sets LLVM attributes for function depending on its AST (`#[attribute]`)
|
/// Composite function which sets LLVM attributes for function depending on its AST (`#[attribute]`)
|
||||||
/// attributes.
|
/// attributes.
|
||||||
pub fn llfn_attrs_from_instance<'ll, 'tcx>(
|
pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>(
|
||||||
cx: &CodegenCx<'ll, 'tcx>,
|
cx: &CodegenCx<'ll, 'tcx>,
|
||||||
llfn: &'ll Value,
|
llfn: &'ll Value,
|
||||||
instance: ty::Instance<'tcx>,
|
instance: ty::Instance<'tcx>,
|
||||||
|
@ -521,13 +521,20 @@ pub fn llfn_attrs_from_instance<'ll, 'tcx>(
|
||||||
|
|
||||||
let function_features = function_features
|
let function_features = function_features
|
||||||
.iter()
|
.iter()
|
||||||
.flat_map(|feat| {
|
// Convert to LLVMFeatures and filter out unavailable ones
|
||||||
llvm_util::to_llvm_features(cx.tcx.sess, feat).into_iter().map(|f| format!("+{f}"))
|
.flat_map(|feat| llvm_util::to_llvm_features(cx.tcx.sess, feat))
|
||||||
})
|
// Convert LLVMFeatures & dependencies to +<feats>s
|
||||||
|
.flat_map(|feat| feat.into_iter().map(|f| format!("+{f}")))
|
||||||
.chain(codegen_fn_attrs.instruction_set.iter().map(|x| match x {
|
.chain(codegen_fn_attrs.instruction_set.iter().map(|x| match x {
|
||||||
InstructionSetAttr::ArmA32 => "-thumb-mode".to_string(),
|
InstructionSetAttr::ArmA32 => "-thumb-mode".to_string(),
|
||||||
InstructionSetAttr::ArmT32 => "+thumb-mode".to_string(),
|
InstructionSetAttr::ArmT32 => "+thumb-mode".to_string(),
|
||||||
}))
|
}))
|
||||||
|
// HACK: LLVM versions 19+ do not have the FPMR feature and treat it as always enabled
|
||||||
|
// It only exists as a feature in LLVM 18, cannot be passed down for any other version
|
||||||
|
.chain(match &*cx.tcx.sess.target.arch {
|
||||||
|
"aarch64" if llvm_util::get_version().0 == 18 => vec!["+fpmr".to_string()],
|
||||||
|
_ => vec![],
|
||||||
|
})
|
||||||
.collect::<Vec<String>>();
|
.collect::<Vec<String>>();
|
||||||
|
|
||||||
if cx.tcx.sess.target.is_like_wasm {
|
if cx.tcx.sess.target.is_like_wasm {
|
||||||
|
|
|
@ -5,17 +5,13 @@ use std::path::{Path, PathBuf};
|
||||||
use std::{io, mem, ptr, str};
|
use std::{io, mem, ptr, str};
|
||||||
|
|
||||||
use rustc_codegen_ssa::back::archive::{
|
use rustc_codegen_ssa::back::archive::{
|
||||||
create_mingw_dll_import_lib, try_extract_macho_fat_archive, ArArchiveBuilder,
|
try_extract_macho_fat_archive, ArArchiveBuilder, ArchiveBuildFailure, ArchiveBuilder,
|
||||||
ArchiveBuildFailure, ArchiveBuilder, ArchiveBuilderBuilder, ObjectReader, UnknownArchiveKind,
|
ArchiveBuilderBuilder, ObjectReader, UnknownArchiveKind, DEFAULT_OBJECT_READER,
|
||||||
DEFAULT_OBJECT_READER,
|
|
||||||
};
|
};
|
||||||
use rustc_codegen_ssa::common;
|
|
||||||
use rustc_session::Session;
|
use rustc_session::Session;
|
||||||
use tracing::trace;
|
|
||||||
|
|
||||||
use crate::errors::ErrorCreatingImportLibrary;
|
|
||||||
use crate::llvm::archive_ro::{ArchiveRO, Child};
|
use crate::llvm::archive_ro::{ArchiveRO, Child};
|
||||||
use crate::llvm::{self, ArchiveKind, LLVMMachineType, LLVMRustCOFFShortExport};
|
use crate::llvm::{self, ArchiveKind};
|
||||||
|
|
||||||
/// Helper for adding many files to an archive.
|
/// Helper for adding many files to an archive.
|
||||||
#[must_use = "must call build() to finish building the archive"]
|
#[must_use = "must call build() to finish building the archive"]
|
||||||
|
@ -44,18 +40,6 @@ fn is_relevant_child(c: &Child<'_>) -> bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Map machine type strings to values of LLVM's MachineTypes enum.
|
|
||||||
fn llvm_machine_type(cpu: &str) -> LLVMMachineType {
|
|
||||||
match cpu {
|
|
||||||
"x86_64" => LLVMMachineType::AMD64,
|
|
||||||
"x86" => LLVMMachineType::I386,
|
|
||||||
"aarch64" => LLVMMachineType::ARM64,
|
|
||||||
"arm64ec" => LLVMMachineType::ARM64EC,
|
|
||||||
"arm" => LLVMMachineType::ARM,
|
|
||||||
_ => panic!("unsupported cpu type {cpu}"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> ArchiveBuilder for LlvmArchiveBuilder<'a> {
|
impl<'a> ArchiveBuilder for LlvmArchiveBuilder<'a> {
|
||||||
fn add_archive(
|
fn add_archive(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
@ -102,90 +86,20 @@ impl<'a> ArchiveBuilder for LlvmArchiveBuilder<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct LlvmArchiveBuilderBuilder;
|
pub(crate) struct LlvmArchiveBuilderBuilder;
|
||||||
|
|
||||||
impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder {
|
impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder {
|
||||||
fn new_archive_builder<'a>(&self, sess: &'a Session) -> Box<dyn ArchiveBuilder + 'a> {
|
fn new_archive_builder<'a>(&self, sess: &'a Session) -> Box<dyn ArchiveBuilder + 'a> {
|
||||||
// FIXME use ArArchiveBuilder on most targets again once reading thin archives is
|
// Keeping LlvmArchiveBuilder around in case of a regression caused by using
|
||||||
// implemented
|
// ArArchiveBuilder.
|
||||||
if true {
|
// FIXME(#128955) remove a couple of months after #128936 gets merged in case
|
||||||
|
// no regression is found.
|
||||||
|
if false {
|
||||||
Box::new(LlvmArchiveBuilder { sess, additions: Vec::new() })
|
Box::new(LlvmArchiveBuilder { sess, additions: Vec::new() })
|
||||||
} else {
|
} else {
|
||||||
Box::new(ArArchiveBuilder::new(sess, &LLVM_OBJECT_READER))
|
Box::new(ArArchiveBuilder::new(sess, &LLVM_OBJECT_READER))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_dll_import_lib(
|
|
||||||
&self,
|
|
||||||
sess: &Session,
|
|
||||||
lib_name: &str,
|
|
||||||
import_name_and_ordinal_vector: Vec<(String, Option<u16>)>,
|
|
||||||
output_path: &Path,
|
|
||||||
) {
|
|
||||||
if common::is_mingw_gnu_toolchain(&sess.target) {
|
|
||||||
// The binutils linker used on -windows-gnu targets cannot read the import
|
|
||||||
// libraries generated by LLVM: in our attempts, the linker produced an .EXE
|
|
||||||
// that loaded but crashed with an AV upon calling one of the imported
|
|
||||||
// functions. Therefore, use binutils to create the import library instead,
|
|
||||||
// by writing a .DEF file to the temp dir and calling binutils's dlltool.
|
|
||||||
create_mingw_dll_import_lib(
|
|
||||||
sess,
|
|
||||||
lib_name,
|
|
||||||
import_name_and_ordinal_vector,
|
|
||||||
output_path,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
// we've checked for \0 characters in the library name already
|
|
||||||
let dll_name_z = CString::new(lib_name).unwrap();
|
|
||||||
|
|
||||||
let output_path_z = rustc_fs_util::path_to_c_string(&output_path);
|
|
||||||
|
|
||||||
trace!("invoking LLVMRustWriteImportLibrary");
|
|
||||||
trace!(" dll_name {:#?}", dll_name_z);
|
|
||||||
trace!(" output_path {}", output_path.display());
|
|
||||||
trace!(
|
|
||||||
" import names: {}",
|
|
||||||
import_name_and_ordinal_vector
|
|
||||||
.iter()
|
|
||||||
.map(|(name, _ordinal)| name.clone())
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
.join(", "),
|
|
||||||
);
|
|
||||||
|
|
||||||
// All import names are Rust identifiers and therefore cannot contain \0 characters.
|
|
||||||
// FIXME: when support for #[link_name] is implemented, ensure that the import names
|
|
||||||
// still don't contain any \0 characters. Also need to check that the names don't
|
|
||||||
// contain substrings like " @" or "NONAME" that are keywords or otherwise reserved
|
|
||||||
// in definition files.
|
|
||||||
let cstring_import_name_and_ordinal_vector: Vec<(CString, Option<u16>)> =
|
|
||||||
import_name_and_ordinal_vector
|
|
||||||
.into_iter()
|
|
||||||
.map(|(name, ordinal)| (CString::new(name).unwrap(), ordinal))
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
let ffi_exports: Vec<LLVMRustCOFFShortExport> = cstring_import_name_and_ordinal_vector
|
|
||||||
.iter()
|
|
||||||
.map(|(name_z, ordinal)| LLVMRustCOFFShortExport::new(name_z.as_ptr(), *ordinal))
|
|
||||||
.collect();
|
|
||||||
let result = unsafe {
|
|
||||||
crate::llvm::LLVMRustWriteImportLibrary(
|
|
||||||
dll_name_z.as_ptr(),
|
|
||||||
output_path_z.as_ptr(),
|
|
||||||
ffi_exports.as_ptr(),
|
|
||||||
ffi_exports.len(),
|
|
||||||
llvm_machine_type(&sess.target.arch) as u16,
|
|
||||||
!sess.target.is_like_msvc,
|
|
||||||
)
|
|
||||||
};
|
|
||||||
|
|
||||||
if result == crate::llvm::LLVMRustResult::Failure {
|
|
||||||
sess.dcx().emit_fatal(ErrorCreatingImportLibrary {
|
|
||||||
lib_name,
|
|
||||||
error: llvm::last_error().unwrap_or("unknown LLVM error".to_string()),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The object crate doesn't know how to get symbols for LLVM bitcode and COFF bigobj files.
|
// The object crate doesn't know how to get symbols for LLVM bitcode and COFF bigobj files.
|
||||||
|
@ -198,25 +112,11 @@ static LLVM_OBJECT_READER: ObjectReader = ObjectReader {
|
||||||
get_xcoff_member_alignment: DEFAULT_OBJECT_READER.get_xcoff_member_alignment,
|
get_xcoff_member_alignment: DEFAULT_OBJECT_READER.get_xcoff_member_alignment,
|
||||||
};
|
};
|
||||||
|
|
||||||
fn should_use_llvm_reader(buf: &[u8]) -> bool {
|
|
||||||
let is_bitcode = unsafe { llvm::LLVMRustIsBitcode(buf.as_ptr(), buf.len()) };
|
|
||||||
|
|
||||||
// COFF bigobj file, msvc LTO file or import library. See
|
|
||||||
// https://github.com/llvm/llvm-project/blob/453f27bc9/llvm/lib/BinaryFormat/Magic.cpp#L38-L51
|
|
||||||
let is_unsupported_windows_obj_file = buf.get(0..4) == Some(b"\0\0\xFF\xFF");
|
|
||||||
|
|
||||||
is_bitcode || is_unsupported_windows_obj_file
|
|
||||||
}
|
|
||||||
|
|
||||||
#[deny(unsafe_op_in_unsafe_fn)]
|
#[deny(unsafe_op_in_unsafe_fn)]
|
||||||
fn get_llvm_object_symbols(
|
fn get_llvm_object_symbols(
|
||||||
buf: &[u8],
|
buf: &[u8],
|
||||||
f: &mut dyn FnMut(&[u8]) -> io::Result<()>,
|
f: &mut dyn FnMut(&[u8]) -> io::Result<()>,
|
||||||
) -> io::Result<bool> {
|
) -> io::Result<bool> {
|
||||||
if !should_use_llvm_reader(buf) {
|
|
||||||
return (DEFAULT_OBJECT_READER.get_symbols)(buf, f);
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut state = Box::new(f);
|
let mut state = Box::new(f);
|
||||||
|
|
||||||
let err = unsafe {
|
let err = unsafe {
|
||||||
|
@ -253,18 +153,10 @@ fn get_llvm_object_symbols(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn llvm_is_64_bit_object_file(buf: &[u8]) -> bool {
|
fn llvm_is_64_bit_object_file(buf: &[u8]) -> bool {
|
||||||
if !should_use_llvm_reader(buf) {
|
|
||||||
return (DEFAULT_OBJECT_READER.is_64_bit_object_file)(buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe { llvm::LLVMRustIs64BitSymbolicFile(buf.as_ptr(), buf.len()) }
|
unsafe { llvm::LLVMRustIs64BitSymbolicFile(buf.as_ptr(), buf.len()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn llvm_is_ec_object_file(buf: &[u8]) -> bool {
|
fn llvm_is_ec_object_file(buf: &[u8]) -> bool {
|
||||||
if !should_use_llvm_reader(buf) {
|
|
||||||
return (DEFAULT_OBJECT_READER.is_ec_object_file)(buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe { llvm::LLVMRustIsECObject(buf.as_ptr(), buf.len()) }
|
unsafe { llvm::LLVMRustIsECObject(buf.as_ptr(), buf.len()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,9 +33,9 @@ use crate::{LlvmCodegenBackend, ModuleLlvm};
|
||||||
|
|
||||||
/// We keep track of the computed LTO cache keys from the previous
|
/// We keep track of the computed LTO cache keys from the previous
|
||||||
/// session to determine which CGUs we can reuse.
|
/// session to determine which CGUs we can reuse.
|
||||||
pub const THIN_LTO_KEYS_INCR_COMP_FILE_NAME: &str = "thin-lto-past-keys.bin";
|
const THIN_LTO_KEYS_INCR_COMP_FILE_NAME: &str = "thin-lto-past-keys.bin";
|
||||||
|
|
||||||
pub fn crate_type_allows_lto(crate_type: CrateType) -> bool {
|
fn crate_type_allows_lto(crate_type: CrateType) -> bool {
|
||||||
match crate_type {
|
match crate_type {
|
||||||
CrateType::Executable
|
CrateType::Executable
|
||||||
| CrateType::Dylib
|
| CrateType::Dylib
|
||||||
|
@ -616,7 +616,7 @@ pub(crate) fn run_pass_manager(
|
||||||
llvm::LLVMRustAddModuleFlagU32(
|
llvm::LLVMRustAddModuleFlagU32(
|
||||||
module.module_llvm.llmod(),
|
module.module_llvm.llmod(),
|
||||||
llvm::LLVMModFlagBehavior::Error,
|
llvm::LLVMModFlagBehavior::Error,
|
||||||
c"LTOPostLink".as_ptr().cast(),
|
c"LTOPostLink".as_ptr(),
|
||||||
1,
|
1,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -710,7 +710,7 @@ impl Drop for ThinBuffer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn optimize_thin_module(
|
pub(crate) unsafe fn optimize_thin_module(
|
||||||
thin_module: ThinModule<LlvmCodegenBackend>,
|
thin_module: ThinModule<LlvmCodegenBackend>,
|
||||||
cgcx: &CodegenContext<LlvmCodegenBackend>,
|
cgcx: &CodegenContext<LlvmCodegenBackend>,
|
||||||
) -> Result<ModuleCodegen<ModuleLlvm>, FatalError> {
|
) -> Result<ModuleCodegen<ModuleLlvm>, FatalError> {
|
||||||
|
@ -806,7 +806,7 @@ pub unsafe fn optimize_thin_module(
|
||||||
|
|
||||||
/// Maps LLVM module identifiers to their corresponding LLVM LTO cache keys
|
/// Maps LLVM module identifiers to their corresponding LLVM LTO cache keys
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct ThinLTOKeysMap {
|
struct ThinLTOKeysMap {
|
||||||
// key = llvm name of importing module, value = LLVM cache key
|
// key = llvm name of importing module, value = LLVM cache key
|
||||||
keys: BTreeMap<String, String>,
|
keys: BTreeMap<String, String>,
|
||||||
}
|
}
|
||||||
|
@ -863,7 +863,7 @@ fn module_name_to_str(c_str: &CStr) -> &str {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_module<'a>(
|
pub(crate) fn parse_module<'a>(
|
||||||
cx: &'a llvm::Context,
|
cx: &'a llvm::Context,
|
||||||
name: &CStr,
|
name: &CStr,
|
||||||
data: &[u8],
|
data: &[u8],
|
||||||
|
|
|
@ -21,14 +21,14 @@ fn llvm_args_to_string_id(profiler: &SelfProfiler, pass_name: &str, ir_name: &st
|
||||||
EventId::from_label(profiler.alloc_string(components.as_slice()))
|
EventId::from_label(profiler.alloc_string(components.as_slice()))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct LlvmSelfProfiler<'a> {
|
pub(crate) struct LlvmSelfProfiler<'a> {
|
||||||
profiler: Arc<SelfProfiler>,
|
profiler: Arc<SelfProfiler>,
|
||||||
stack: Vec<TimingGuard<'a>>,
|
stack: Vec<TimingGuard<'a>>,
|
||||||
llvm_pass_event_kind: StringId,
|
llvm_pass_event_kind: StringId,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> LlvmSelfProfiler<'a> {
|
impl<'a> LlvmSelfProfiler<'a> {
|
||||||
pub fn new(profiler: Arc<SelfProfiler>) -> Self {
|
pub(crate) fn new(profiler: Arc<SelfProfiler>) -> Self {
|
||||||
let llvm_pass_event_kind = profiler.alloc_string("LLVM Pass");
|
let llvm_pass_event_kind = profiler.alloc_string("LLVM Pass");
|
||||||
Self { profiler, stack: Vec::default(), llvm_pass_event_kind }
|
Self { profiler, stack: Vec::default(), llvm_pass_event_kind }
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ impl<'a> LlvmSelfProfiler<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe extern "C" fn selfprofile_before_pass_callback(
|
pub(crate) unsafe extern "C" fn selfprofile_before_pass_callback(
|
||||||
llvm_self_profiler: *mut c_void,
|
llvm_self_profiler: *mut c_void,
|
||||||
pass_name: *const c_char,
|
pass_name: *const c_char,
|
||||||
ir_name: *const c_char,
|
ir_name: *const c_char,
|
||||||
|
@ -56,7 +56,7 @@ pub unsafe extern "C" fn selfprofile_before_pass_callback(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe extern "C" fn selfprofile_after_pass_callback(llvm_self_profiler: *mut c_void) {
|
pub(crate) unsafe extern "C" fn selfprofile_after_pass_callback(llvm_self_profiler: *mut c_void) {
|
||||||
let llvm_self_profiler = unsafe { &mut *(llvm_self_profiler as *mut LlvmSelfProfiler<'_>) };
|
let llvm_self_profiler = unsafe { &mut *(llvm_self_profiler as *mut LlvmSelfProfiler<'_>) };
|
||||||
llvm_self_profiler.after_pass_callback();
|
llvm_self_profiler.after_pass_callback();
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,14 +43,14 @@ use crate::llvm::{self, DiagnosticInfo, PassManager};
|
||||||
use crate::type_::Type;
|
use crate::type_::Type;
|
||||||
use crate::{base, common, llvm_util, LlvmCodegenBackend, ModuleLlvm};
|
use crate::{base, common, llvm_util, LlvmCodegenBackend, ModuleLlvm};
|
||||||
|
|
||||||
pub fn llvm_err<'a>(dcx: DiagCtxtHandle<'_>, err: LlvmError<'a>) -> FatalError {
|
pub(crate) fn llvm_err<'a>(dcx: DiagCtxtHandle<'_>, err: LlvmError<'a>) -> FatalError {
|
||||||
match llvm::last_error() {
|
match llvm::last_error() {
|
||||||
Some(llvm_err) => dcx.emit_almost_fatal(WithLlvmError(err, llvm_err)),
|
Some(llvm_err) => dcx.emit_almost_fatal(WithLlvmError(err, llvm_err)),
|
||||||
None => dcx.emit_almost_fatal(err),
|
None => dcx.emit_almost_fatal(err),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_output_file<'ll>(
|
fn write_output_file<'ll>(
|
||||||
dcx: DiagCtxtHandle<'_>,
|
dcx: DiagCtxtHandle<'_>,
|
||||||
target: &'ll llvm::TargetMachine,
|
target: &'ll llvm::TargetMachine,
|
||||||
pm: &llvm::PassManager<'ll>,
|
pm: &llvm::PassManager<'ll>,
|
||||||
|
@ -95,7 +95,7 @@ pub fn write_output_file<'ll>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_informational_target_machine(
|
pub(crate) fn create_informational_target_machine(
|
||||||
sess: &Session,
|
sess: &Session,
|
||||||
only_base_features: bool,
|
only_base_features: bool,
|
||||||
) -> OwnedTargetMachine {
|
) -> OwnedTargetMachine {
|
||||||
|
@ -107,7 +107,7 @@ pub fn create_informational_target_machine(
|
||||||
.unwrap_or_else(|err| llvm_err(sess.dcx(), err).raise())
|
.unwrap_or_else(|err| llvm_err(sess.dcx(), err).raise())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_target_machine(tcx: TyCtxt<'_>, mod_name: &str) -> OwnedTargetMachine {
|
pub(crate) fn create_target_machine(tcx: TyCtxt<'_>, mod_name: &str) -> OwnedTargetMachine {
|
||||||
let split_dwarf_file = if tcx.sess.target_can_use_split_dwarf() {
|
let split_dwarf_file = if tcx.sess.target_can_use_split_dwarf() {
|
||||||
tcx.output_filenames(()).split_dwarf_path(
|
tcx.output_filenames(()).split_dwarf_path(
|
||||||
tcx.sess.split_debuginfo(),
|
tcx.sess.split_debuginfo(),
|
||||||
|
@ -130,9 +130,7 @@ pub fn create_target_machine(tcx: TyCtxt<'_>, mod_name: &str) -> OwnedTargetMach
|
||||||
.unwrap_or_else(|err| llvm_err(tcx.dcx(), err).raise())
|
.unwrap_or_else(|err| llvm_err(tcx.dcx(), err).raise())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_llvm_opt_settings(
|
fn to_llvm_opt_settings(cfg: config::OptLevel) -> (llvm::CodeGenOptLevel, llvm::CodeGenOptSize) {
|
||||||
cfg: config::OptLevel,
|
|
||||||
) -> (llvm::CodeGenOptLevel, llvm::CodeGenOptSize) {
|
|
||||||
use self::config::OptLevel::*;
|
use self::config::OptLevel::*;
|
||||||
match cfg {
|
match cfg {
|
||||||
No => (llvm::CodeGenOptLevel::None, llvm::CodeGenOptSizeNone),
|
No => (llvm::CodeGenOptLevel::None, llvm::CodeGenOptSizeNone),
|
||||||
|
@ -179,7 +177,7 @@ pub(crate) fn to_llvm_code_model(code_model: Option<CodeModel>) -> llvm::CodeMod
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn target_machine_factory(
|
pub(crate) fn target_machine_factory(
|
||||||
sess: &Session,
|
sess: &Session,
|
||||||
optlvl: config::OptLevel,
|
optlvl: config::OptLevel,
|
||||||
target_features: &[String],
|
target_features: &[String],
|
||||||
|
@ -320,7 +318,7 @@ pub(crate) fn save_temp_bitcode(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// In what context is a dignostic handler being attached to a codegen unit?
|
/// In what context is a dignostic handler being attached to a codegen unit?
|
||||||
pub enum CodegenDiagnosticsStage {
|
pub(crate) enum CodegenDiagnosticsStage {
|
||||||
/// Prelink optimization stage.
|
/// Prelink optimization stage.
|
||||||
Opt,
|
Opt,
|
||||||
/// LTO/ThinLTO postlink optimization stage.
|
/// LTO/ThinLTO postlink optimization stage.
|
||||||
|
@ -329,14 +327,14 @@ pub enum CodegenDiagnosticsStage {
|
||||||
Codegen,
|
Codegen,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct DiagnosticHandlers<'a> {
|
pub(crate) struct DiagnosticHandlers<'a> {
|
||||||
data: *mut (&'a CodegenContext<LlvmCodegenBackend>, DiagCtxtHandle<'a>),
|
data: *mut (&'a CodegenContext<LlvmCodegenBackend>, DiagCtxtHandle<'a>),
|
||||||
llcx: &'a llvm::Context,
|
llcx: &'a llvm::Context,
|
||||||
old_handler: Option<&'a llvm::DiagnosticHandler>,
|
old_handler: Option<&'a llvm::DiagnosticHandler>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> DiagnosticHandlers<'a> {
|
impl<'a> DiagnosticHandlers<'a> {
|
||||||
pub fn new(
|
pub(crate) fn new(
|
||||||
cgcx: &'a CodegenContext<LlvmCodegenBackend>,
|
cgcx: &'a CodegenContext<LlvmCodegenBackend>,
|
||||||
dcx: DiagCtxtHandle<'a>,
|
dcx: DiagCtxtHandle<'a>,
|
||||||
llcx: &'a llvm::Context,
|
llcx: &'a llvm::Context,
|
||||||
|
@ -1031,7 +1029,7 @@ unsafe fn embed_bitcode(
|
||||||
let llglobal = llvm::LLVMAddGlobal(
|
let llglobal = llvm::LLVMAddGlobal(
|
||||||
llmod,
|
llmod,
|
||||||
common::val_ty(llconst),
|
common::val_ty(llconst),
|
||||||
c"rustc.embedded.module".as_ptr().cast(),
|
c"rustc.embedded.module".as_ptr(),
|
||||||
);
|
);
|
||||||
llvm::LLVMSetInitializer(llglobal, llconst);
|
llvm::LLVMSetInitializer(llglobal, llconst);
|
||||||
|
|
||||||
|
@ -1044,7 +1042,7 @@ unsafe fn embed_bitcode(
|
||||||
let llglobal = llvm::LLVMAddGlobal(
|
let llglobal = llvm::LLVMAddGlobal(
|
||||||
llmod,
|
llmod,
|
||||||
common::val_ty(llconst),
|
common::val_ty(llconst),
|
||||||
c"rustc.embedded.cmdline".as_ptr().cast(),
|
c"rustc.embedded.cmdline".as_ptr(),
|
||||||
);
|
);
|
||||||
llvm::LLVMSetInitializer(llglobal, llconst);
|
llvm::LLVMSetInitializer(llglobal, llconst);
|
||||||
let section = if is_apple {
|
let section = if is_apple {
|
||||||
|
@ -1054,7 +1052,7 @@ unsafe fn embed_bitcode(
|
||||||
} else {
|
} else {
|
||||||
c".llvmcmd"
|
c".llvmcmd"
|
||||||
};
|
};
|
||||||
llvm::LLVMSetSection(llglobal, section.as_ptr().cast());
|
llvm::LLVMSetSection(llglobal, section.as_ptr());
|
||||||
llvm::LLVMRustSetLinkage(llglobal, llvm::Linkage::PrivateLinkage);
|
llvm::LLVMRustSetLinkage(llglobal, llvm::Linkage::PrivateLinkage);
|
||||||
} else {
|
} else {
|
||||||
// We need custom section flags, so emit module-level inline assembly.
|
// We need custom section flags, so emit module-level inline assembly.
|
||||||
|
@ -1107,7 +1105,7 @@ fn create_msvc_imps(
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
for (imp_name, val) in globals {
|
for (imp_name, val) in globals {
|
||||||
let imp = llvm::LLVMAddGlobal(llmod, ptr_ty, imp_name.as_ptr().cast());
|
let imp = llvm::LLVMAddGlobal(llmod, ptr_ty, imp_name.as_ptr());
|
||||||
llvm::LLVMSetInitializer(imp, val);
|
llvm::LLVMSetInitializer(imp, val);
|
||||||
llvm::LLVMRustSetLinkage(imp, llvm::Linkage::ExternalLinkage);
|
llvm::LLVMRustSetLinkage(imp, llvm::Linkage::ExternalLinkage);
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,7 @@ use crate::context::CodegenCx;
|
||||||
use crate::value::Value;
|
use crate::value::Value;
|
||||||
use crate::{attributes, llvm};
|
use crate::{attributes, llvm};
|
||||||
|
|
||||||
pub struct ValueIter<'ll> {
|
pub(crate) struct ValueIter<'ll> {
|
||||||
cur: Option<&'ll Value>,
|
cur: Option<&'ll Value>,
|
||||||
step: unsafe extern "C" fn(&'ll Value) -> Option<&'ll Value>,
|
step: unsafe extern "C" fn(&'ll Value) -> Option<&'ll Value>,
|
||||||
}
|
}
|
||||||
|
@ -49,11 +49,14 @@ impl<'ll> Iterator for ValueIter<'ll> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn iter_globals(llmod: &llvm::Module) -> ValueIter<'_> {
|
pub(crate) fn iter_globals(llmod: &llvm::Module) -> ValueIter<'_> {
|
||||||
unsafe { ValueIter { cur: llvm::LLVMGetFirstGlobal(llmod), step: llvm::LLVMGetNextGlobal } }
|
unsafe { ValueIter { cur: llvm::LLVMGetFirstGlobal(llmod), step: llvm::LLVMGetNextGlobal } }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn compile_codegen_unit(tcx: TyCtxt<'_>, cgu_name: Symbol) -> (ModuleCodegen<ModuleLlvm>, u64) {
|
pub(crate) fn compile_codegen_unit(
|
||||||
|
tcx: TyCtxt<'_>,
|
||||||
|
cgu_name: Symbol,
|
||||||
|
) -> (ModuleCodegen<ModuleLlvm>, u64) {
|
||||||
let start_time = Instant::now();
|
let start_time = Instant::now();
|
||||||
|
|
||||||
let dep_node = tcx.codegen_unit(cgu_name).codegen_dep_node(tcx);
|
let dep_node = tcx.codegen_unit(cgu_name).codegen_dep_node(tcx);
|
||||||
|
@ -140,7 +143,7 @@ pub fn compile_codegen_unit(tcx: TyCtxt<'_>, cgu_name: Symbol) -> (ModuleCodegen
|
||||||
(module, cost)
|
(module, cost)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_link_section(llval: &Value, attrs: &CodegenFnAttrs) {
|
pub(crate) fn set_link_section(llval: &Value, attrs: &CodegenFnAttrs) {
|
||||||
let Some(sect) = attrs.link_section else { return };
|
let Some(sect) = attrs.link_section else { return };
|
||||||
unsafe {
|
unsafe {
|
||||||
let buf = SmallCStr::new(sect.as_str());
|
let buf = SmallCStr::new(sect.as_str());
|
||||||
|
@ -148,7 +151,7 @@ pub fn set_link_section(llval: &Value, attrs: &CodegenFnAttrs) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn linkage_to_llvm(linkage: Linkage) -> llvm::Linkage {
|
pub(crate) fn linkage_to_llvm(linkage: Linkage) -> llvm::Linkage {
|
||||||
match linkage {
|
match linkage {
|
||||||
Linkage::External => llvm::Linkage::ExternalLinkage,
|
Linkage::External => llvm::Linkage::ExternalLinkage,
|
||||||
Linkage::AvailableExternally => llvm::Linkage::AvailableExternallyLinkage,
|
Linkage::AvailableExternally => llvm::Linkage::AvailableExternallyLinkage,
|
||||||
|
@ -164,7 +167,7 @@ pub fn linkage_to_llvm(linkage: Linkage) -> llvm::Linkage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn visibility_to_llvm(linkage: Visibility) -> llvm::Visibility {
|
pub(crate) fn visibility_to_llvm(linkage: Visibility) -> llvm::Visibility {
|
||||||
match linkage {
|
match linkage {
|
||||||
Visibility::Default => llvm::Visibility::Default,
|
Visibility::Default => llvm::Visibility::Default,
|
||||||
Visibility::Hidden => llvm::Visibility::Hidden,
|
Visibility::Hidden => llvm::Visibility::Hidden,
|
||||||
|
|
|
@ -36,7 +36,7 @@ use crate::{attributes, llvm_util};
|
||||||
|
|
||||||
// All Builders must have an llfn associated with them
|
// All Builders must have an llfn associated with them
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub struct Builder<'a, 'll, 'tcx> {
|
pub(crate) struct Builder<'a, 'll, 'tcx> {
|
||||||
pub llbuilder: &'ll mut llvm::Builder<'ll>,
|
pub llbuilder: &'ll mut llvm::Builder<'ll>,
|
||||||
pub cx: &'a CodegenCx<'ll, 'tcx>,
|
pub cx: &'a CodegenCx<'ll, 'tcx>,
|
||||||
}
|
}
|
||||||
|
@ -1343,7 +1343,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
|
||||||
Builder { llbuilder, cx }
|
Builder { llbuilder, cx }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn llfn(&self) -> &'ll Value {
|
pub(crate) fn llfn(&self) -> &'ll Value {
|
||||||
unsafe { llvm::LLVMGetBasicBlockParent(self.llbb()) }
|
unsafe { llvm::LLVMGetBasicBlockParent(self.llbb()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1375,7 +1375,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_unpredictable(&mut self, inst: &'ll Value) {
|
pub(crate) fn set_unpredictable(&mut self, inst: &'ll Value) {
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMSetMetadata(
|
llvm::LLVMSetMetadata(
|
||||||
inst,
|
inst,
|
||||||
|
@ -1385,15 +1385,15 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn minnum(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
|
pub(crate) fn minnum(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
|
||||||
unsafe { llvm::LLVMRustBuildMinNum(self.llbuilder, lhs, rhs) }
|
unsafe { llvm::LLVMRustBuildMinNum(self.llbuilder, lhs, rhs) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn maxnum(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
|
pub(crate) fn maxnum(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
|
||||||
unsafe { llvm::LLVMRustBuildMaxNum(self.llbuilder, lhs, rhs) }
|
unsafe { llvm::LLVMRustBuildMaxNum(self.llbuilder, lhs, rhs) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert_element(
|
pub(crate) fn insert_element(
|
||||||
&mut self,
|
&mut self,
|
||||||
vec: &'ll Value,
|
vec: &'ll Value,
|
||||||
elt: &'ll Value,
|
elt: &'ll Value,
|
||||||
|
@ -1402,7 +1402,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
|
||||||
unsafe { llvm::LLVMBuildInsertElement(self.llbuilder, vec, elt, idx, UNNAMED) }
|
unsafe { llvm::LLVMBuildInsertElement(self.llbuilder, vec, elt, idx, UNNAMED) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn shuffle_vector(
|
pub(crate) fn shuffle_vector(
|
||||||
&mut self,
|
&mut self,
|
||||||
v1: &'ll Value,
|
v1: &'ll Value,
|
||||||
v2: &'ll Value,
|
v2: &'ll Value,
|
||||||
|
@ -1411,65 +1411,77 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
|
||||||
unsafe { llvm::LLVMBuildShuffleVector(self.llbuilder, v1, v2, mask, UNNAMED) }
|
unsafe { llvm::LLVMBuildShuffleVector(self.llbuilder, v1, v2, mask, UNNAMED) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn vector_reduce_fadd(&mut self, acc: &'ll Value, src: &'ll Value) -> &'ll Value {
|
pub(crate) fn vector_reduce_fadd(&mut self, acc: &'ll Value, src: &'ll Value) -> &'ll Value {
|
||||||
unsafe { llvm::LLVMRustBuildVectorReduceFAdd(self.llbuilder, acc, src) }
|
unsafe { llvm::LLVMRustBuildVectorReduceFAdd(self.llbuilder, acc, src) }
|
||||||
}
|
}
|
||||||
pub fn vector_reduce_fmul(&mut self, acc: &'ll Value, src: &'ll Value) -> &'ll Value {
|
pub(crate) fn vector_reduce_fmul(&mut self, acc: &'ll Value, src: &'ll Value) -> &'ll Value {
|
||||||
unsafe { llvm::LLVMRustBuildVectorReduceFMul(self.llbuilder, acc, src) }
|
unsafe { llvm::LLVMRustBuildVectorReduceFMul(self.llbuilder, acc, src) }
|
||||||
}
|
}
|
||||||
pub fn vector_reduce_fadd_reassoc(&mut self, acc: &'ll Value, src: &'ll Value) -> &'ll Value {
|
pub(crate) fn vector_reduce_fadd_reassoc(
|
||||||
|
&mut self,
|
||||||
|
acc: &'ll Value,
|
||||||
|
src: &'ll Value,
|
||||||
|
) -> &'ll Value {
|
||||||
unsafe {
|
unsafe {
|
||||||
let instr = llvm::LLVMRustBuildVectorReduceFAdd(self.llbuilder, acc, src);
|
let instr = llvm::LLVMRustBuildVectorReduceFAdd(self.llbuilder, acc, src);
|
||||||
llvm::LLVMRustSetAllowReassoc(instr);
|
llvm::LLVMRustSetAllowReassoc(instr);
|
||||||
instr
|
instr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn vector_reduce_fmul_reassoc(&mut self, acc: &'ll Value, src: &'ll Value) -> &'ll Value {
|
pub(crate) fn vector_reduce_fmul_reassoc(
|
||||||
|
&mut self,
|
||||||
|
acc: &'ll Value,
|
||||||
|
src: &'ll Value,
|
||||||
|
) -> &'ll Value {
|
||||||
unsafe {
|
unsafe {
|
||||||
let instr = llvm::LLVMRustBuildVectorReduceFMul(self.llbuilder, acc, src);
|
let instr = llvm::LLVMRustBuildVectorReduceFMul(self.llbuilder, acc, src);
|
||||||
llvm::LLVMRustSetAllowReassoc(instr);
|
llvm::LLVMRustSetAllowReassoc(instr);
|
||||||
instr
|
instr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn vector_reduce_add(&mut self, src: &'ll Value) -> &'ll Value {
|
pub(crate) fn vector_reduce_add(&mut self, src: &'ll Value) -> &'ll Value {
|
||||||
unsafe { llvm::LLVMRustBuildVectorReduceAdd(self.llbuilder, src) }
|
unsafe { llvm::LLVMRustBuildVectorReduceAdd(self.llbuilder, src) }
|
||||||
}
|
}
|
||||||
pub fn vector_reduce_mul(&mut self, src: &'ll Value) -> &'ll Value {
|
pub(crate) fn vector_reduce_mul(&mut self, src: &'ll Value) -> &'ll Value {
|
||||||
unsafe { llvm::LLVMRustBuildVectorReduceMul(self.llbuilder, src) }
|
unsafe { llvm::LLVMRustBuildVectorReduceMul(self.llbuilder, src) }
|
||||||
}
|
}
|
||||||
pub fn vector_reduce_and(&mut self, src: &'ll Value) -> &'ll Value {
|
pub(crate) fn vector_reduce_and(&mut self, src: &'ll Value) -> &'ll Value {
|
||||||
unsafe { llvm::LLVMRustBuildVectorReduceAnd(self.llbuilder, src) }
|
unsafe { llvm::LLVMRustBuildVectorReduceAnd(self.llbuilder, src) }
|
||||||
}
|
}
|
||||||
pub fn vector_reduce_or(&mut self, src: &'ll Value) -> &'ll Value {
|
pub(crate) fn vector_reduce_or(&mut self, src: &'ll Value) -> &'ll Value {
|
||||||
unsafe { llvm::LLVMRustBuildVectorReduceOr(self.llbuilder, src) }
|
unsafe { llvm::LLVMRustBuildVectorReduceOr(self.llbuilder, src) }
|
||||||
}
|
}
|
||||||
pub fn vector_reduce_xor(&mut self, src: &'ll Value) -> &'ll Value {
|
pub(crate) fn vector_reduce_xor(&mut self, src: &'ll Value) -> &'ll Value {
|
||||||
unsafe { llvm::LLVMRustBuildVectorReduceXor(self.llbuilder, src) }
|
unsafe { llvm::LLVMRustBuildVectorReduceXor(self.llbuilder, src) }
|
||||||
}
|
}
|
||||||
pub fn vector_reduce_fmin(&mut self, src: &'ll Value) -> &'ll Value {
|
pub(crate) fn vector_reduce_fmin(&mut self, src: &'ll Value) -> &'ll Value {
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMRustBuildVectorReduceFMin(self.llbuilder, src, /*NoNaNs:*/ false)
|
llvm::LLVMRustBuildVectorReduceFMin(self.llbuilder, src, /*NoNaNs:*/ false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn vector_reduce_fmax(&mut self, src: &'ll Value) -> &'ll Value {
|
pub(crate) fn vector_reduce_fmax(&mut self, src: &'ll Value) -> &'ll Value {
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMRustBuildVectorReduceFMax(self.llbuilder, src, /*NoNaNs:*/ false)
|
llvm::LLVMRustBuildVectorReduceFMax(self.llbuilder, src, /*NoNaNs:*/ false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn vector_reduce_min(&mut self, src: &'ll Value, is_signed: bool) -> &'ll Value {
|
pub(crate) fn vector_reduce_min(&mut self, src: &'ll Value, is_signed: bool) -> &'ll Value {
|
||||||
unsafe { llvm::LLVMRustBuildVectorReduceMin(self.llbuilder, src, is_signed) }
|
unsafe { llvm::LLVMRustBuildVectorReduceMin(self.llbuilder, src, is_signed) }
|
||||||
}
|
}
|
||||||
pub fn vector_reduce_max(&mut self, src: &'ll Value, is_signed: bool) -> &'ll Value {
|
pub(crate) fn vector_reduce_max(&mut self, src: &'ll Value, is_signed: bool) -> &'ll Value {
|
||||||
unsafe { llvm::LLVMRustBuildVectorReduceMax(self.llbuilder, src, is_signed) }
|
unsafe { llvm::LLVMRustBuildVectorReduceMax(self.llbuilder, src, is_signed) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_clause(&mut self, landing_pad: &'ll Value, clause: &'ll Value) {
|
pub(crate) fn add_clause(&mut self, landing_pad: &'ll Value, clause: &'ll Value) {
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMAddClause(landing_pad, clause);
|
llvm::LLVMAddClause(landing_pad, clause);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn catch_ret(&mut self, funclet: &Funclet<'ll>, unwind: &'ll BasicBlock) -> &'ll Value {
|
pub(crate) fn catch_ret(
|
||||||
|
&mut self,
|
||||||
|
funclet: &Funclet<'ll>,
|
||||||
|
unwind: &'ll BasicBlock,
|
||||||
|
) -> &'ll Value {
|
||||||
let ret = unsafe { llvm::LLVMBuildCatchRet(self.llbuilder, funclet.cleanuppad(), unwind) };
|
let ret = unsafe { llvm::LLVMBuildCatchRet(self.llbuilder, funclet.cleanuppad(), unwind) };
|
||||||
ret.expect("LLVM does not have support for catchret")
|
ret.expect("LLVM does not have support for catchret")
|
||||||
}
|
}
|
||||||
|
@ -1515,7 +1527,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
|
||||||
Cow::Owned(casted_args)
|
Cow::Owned(casted_args)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn va_arg(&mut self, list: &'ll Value, ty: &'ll Type) -> &'ll Value {
|
pub(crate) fn va_arg(&mut self, list: &'ll Value, ty: &'ll Type) -> &'ll Value {
|
||||||
unsafe { llvm::LLVMBuildVAArg(self.llbuilder, list, ty, UNNAMED) }
|
unsafe { llvm::LLVMBuildVAArg(self.llbuilder, list, ty, UNNAMED) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ use crate::value::Value;
|
||||||
///
|
///
|
||||||
/// - `cx`: the crate context
|
/// - `cx`: the crate context
|
||||||
/// - `instance`: the instance to be instantiated
|
/// - `instance`: the instance to be instantiated
|
||||||
pub fn get_fn<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>) -> &'ll Value {
|
pub(crate) fn get_fn<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>) -> &'ll Value {
|
||||||
let tcx = cx.tcx();
|
let tcx = cx.tcx();
|
||||||
|
|
||||||
debug!("get_fn(instance={:?})", instance);
|
debug!("get_fn(instance={:?})", instance);
|
||||||
|
|
|
@ -13,7 +13,7 @@ use rustc_target::abi::{self, AddressSpace, HasDataLayout, Pointer};
|
||||||
use tracing::debug;
|
use tracing::debug;
|
||||||
|
|
||||||
use crate::consts::const_alloc_to_llvm;
|
use crate::consts::const_alloc_to_llvm;
|
||||||
pub use crate::context::CodegenCx;
|
pub(crate) use crate::context::CodegenCx;
|
||||||
use crate::llvm::{self, BasicBlock, Bool, ConstantInt, False, OperandBundleDef, True};
|
use crate::llvm::{self, BasicBlock, Bool, ConstantInt, False, OperandBundleDef, True};
|
||||||
use crate::type_::Type;
|
use crate::type_::Type;
|
||||||
use crate::value::Value;
|
use crate::value::Value;
|
||||||
|
@ -58,21 +58,21 @@ use crate::value::Value;
|
||||||
/// When inside of a landing pad, each function call in LLVM IR needs to be
|
/// When inside of a landing pad, each function call in LLVM IR needs to be
|
||||||
/// annotated with which landing pad it's a part of. This is accomplished via
|
/// annotated with which landing pad it's a part of. This is accomplished via
|
||||||
/// the `OperandBundleDef` value created for MSVC landing pads.
|
/// the `OperandBundleDef` value created for MSVC landing pads.
|
||||||
pub struct Funclet<'ll> {
|
pub(crate) struct Funclet<'ll> {
|
||||||
cleanuppad: &'ll Value,
|
cleanuppad: &'ll Value,
|
||||||
operand: OperandBundleDef<'ll>,
|
operand: OperandBundleDef<'ll>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ll> Funclet<'ll> {
|
impl<'ll> Funclet<'ll> {
|
||||||
pub fn new(cleanuppad: &'ll Value) -> Self {
|
pub(crate) fn new(cleanuppad: &'ll Value) -> Self {
|
||||||
Funclet { cleanuppad, operand: OperandBundleDef::new("funclet", &[cleanuppad]) }
|
Funclet { cleanuppad, operand: OperandBundleDef::new("funclet", &[cleanuppad]) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cleanuppad(&self) -> &'ll Value {
|
pub(crate) fn cleanuppad(&self) -> &'ll Value {
|
||||||
self.cleanuppad
|
self.cleanuppad
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bundle(&self) -> &OperandBundleDef<'ll> {
|
pub(crate) fn bundle(&self) -> &OperandBundleDef<'ll> {
|
||||||
&self.operand
|
&self.operand
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -92,16 +92,16 @@ impl<'ll> BackendTypes for CodegenCx<'ll, '_> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ll> CodegenCx<'ll, '_> {
|
impl<'ll> CodegenCx<'ll, '_> {
|
||||||
pub fn const_array(&self, ty: &'ll Type, elts: &[&'ll Value]) -> &'ll Value {
|
pub(crate) fn const_array(&self, ty: &'ll Type, elts: &[&'ll Value]) -> &'ll Value {
|
||||||
let len = u64::try_from(elts.len()).expect("LLVMConstArray2 elements len overflow");
|
let len = u64::try_from(elts.len()).expect("LLVMConstArray2 elements len overflow");
|
||||||
unsafe { llvm::LLVMConstArray2(ty, elts.as_ptr(), len) }
|
unsafe { llvm::LLVMConstArray2(ty, elts.as_ptr(), len) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn const_bytes(&self, bytes: &[u8]) -> &'ll Value {
|
pub(crate) fn const_bytes(&self, bytes: &[u8]) -> &'ll Value {
|
||||||
bytes_in_context(self.llcx, bytes)
|
bytes_in_context(self.llcx, bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn const_get_elt(&self, v: &'ll Value, idx: u64) -> &'ll Value {
|
pub(crate) fn const_get_elt(&self, v: &'ll Value, idx: u64) -> &'ll Value {
|
||||||
unsafe {
|
unsafe {
|
||||||
let idx = c_uint::try_from(idx).expect("LLVMGetAggregateElement index overflow");
|
let idx = c_uint::try_from(idx).expect("LLVMGetAggregateElement index overflow");
|
||||||
let r = llvm::LLVMGetAggregateElement(v, idx).unwrap();
|
let r = llvm::LLVMGetAggregateElement(v, idx).unwrap();
|
||||||
|
@ -339,18 +339,18 @@ impl<'ll, 'tcx> ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the [LLVM type][Type] of a [`Value`].
|
/// Get the [LLVM type][Type] of a [`Value`].
|
||||||
pub fn val_ty(v: &Value) -> &Type {
|
pub(crate) fn val_ty(v: &Value) -> &Type {
|
||||||
unsafe { llvm::LLVMTypeOf(v) }
|
unsafe { llvm::LLVMTypeOf(v) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bytes_in_context<'ll>(llcx: &'ll llvm::Context, bytes: &[u8]) -> &'ll Value {
|
pub(crate) fn bytes_in_context<'ll>(llcx: &'ll llvm::Context, bytes: &[u8]) -> &'ll Value {
|
||||||
unsafe {
|
unsafe {
|
||||||
let ptr = bytes.as_ptr() as *const c_char;
|
let ptr = bytes.as_ptr() as *const c_char;
|
||||||
llvm::LLVMConstStringInContext2(llcx, ptr, bytes.len(), True)
|
llvm::LLVMConstStringInContext2(llcx, ptr, bytes.len(), True)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn struct_in_context<'ll>(
|
fn struct_in_context<'ll>(
|
||||||
llcx: &'ll llvm::Context,
|
llcx: &'ll llvm::Context,
|
||||||
elts: &[&'ll Value],
|
elts: &[&'ll Value],
|
||||||
packed: bool,
|
packed: bool,
|
||||||
|
|
|
@ -29,7 +29,7 @@ use crate::type_of::LayoutLlvmExt;
|
||||||
use crate::value::Value;
|
use crate::value::Value;
|
||||||
use crate::{base, debuginfo};
|
use crate::{base, debuginfo};
|
||||||
|
|
||||||
pub fn const_alloc_to_llvm<'ll>(
|
pub(crate) fn const_alloc_to_llvm<'ll>(
|
||||||
cx: &CodegenCx<'ll, '_>,
|
cx: &CodegenCx<'ll, '_>,
|
||||||
alloc: ConstAllocation<'_>,
|
alloc: ConstAllocation<'_>,
|
||||||
is_static: bool,
|
is_static: bool,
|
||||||
|
@ -525,7 +525,7 @@ impl<'ll> CodegenCx<'ll, '_> {
|
||||||
let val = llvm::LLVMMetadataAsValue(self.llcx, meta);
|
let val = llvm::LLVMMetadataAsValue(self.llcx, meta);
|
||||||
llvm::LLVMAddNamedMetadataOperand(
|
llvm::LLVMAddNamedMetadataOperand(
|
||||||
self.llmod,
|
self.llmod,
|
||||||
c"wasm.custom_sections".as_ptr().cast(),
|
c"wasm.custom_sections".as_ptr(),
|
||||||
val,
|
val,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ use rustc_data_structures::base_n::{ToBaseN, ALPHANUMERIC_ONLY};
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
use rustc_data_structures::small_c_str::SmallCStr;
|
use rustc_data_structures::small_c_str::SmallCStr;
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
|
use rustc_middle::middle::codegen_fn_attrs::PatchableFunctionEntry;
|
||||||
use rustc_middle::mir::mono::CodegenUnit;
|
use rustc_middle::mir::mono::CodegenUnit;
|
||||||
use rustc_middle::ty::layout::{
|
use rustc_middle::ty::layout::{
|
||||||
FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasParamEnv, LayoutError, LayoutOfHelpers,
|
FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasParamEnv, LayoutError, LayoutOfHelpers,
|
||||||
|
@ -39,7 +40,7 @@ use crate::{attributes, coverageinfo, debuginfo, llvm, llvm_util};
|
||||||
/// There is one `CodegenCx` per compilation unit. Each one has its own LLVM
|
/// There is one `CodegenCx` per compilation unit. Each one has its own LLVM
|
||||||
/// `llvm::Context` so that several compilation units may be optimized in parallel.
|
/// `llvm::Context` so that several compilation units may be optimized in parallel.
|
||||||
/// All other LLVM data structures in the `CodegenCx` are tied to that `llvm::Context`.
|
/// All other LLVM data structures in the `CodegenCx` are tied to that `llvm::Context`.
|
||||||
pub struct CodegenCx<'ll, 'tcx> {
|
pub(crate) struct CodegenCx<'ll, 'tcx> {
|
||||||
pub tcx: TyCtxt<'tcx>,
|
pub tcx: TyCtxt<'tcx>,
|
||||||
pub use_dll_storage_attrs: bool,
|
pub use_dll_storage_attrs: bool,
|
||||||
pub tls_model: llvm::ThreadLocalMode,
|
pub tls_model: llvm::ThreadLocalMode,
|
||||||
|
@ -110,7 +111,7 @@ fn to_llvm_tls_model(tls_model: TlsModel) -> llvm::ThreadLocalMode {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn create_module<'ll>(
|
pub(crate) unsafe fn create_module<'ll>(
|
||||||
tcx: TyCtxt<'_>,
|
tcx: TyCtxt<'_>,
|
||||||
llcx: &'ll llvm::Context,
|
llcx: &'ll llvm::Context,
|
||||||
mod_name: &str,
|
mod_name: &str,
|
||||||
|
@ -207,7 +208,7 @@ pub unsafe fn create_module<'ll>(
|
||||||
// If skipping the PLT is enabled, we need to add some module metadata
|
// If skipping the PLT is enabled, we need to add some module metadata
|
||||||
// to ensure intrinsic calls don't use it.
|
// to ensure intrinsic calls don't use it.
|
||||||
if !sess.needs_plt() {
|
if !sess.needs_plt() {
|
||||||
let avoid_plt = c"RtLibUseGOT".as_ptr().cast();
|
let avoid_plt = c"RtLibUseGOT".as_ptr();
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMRustAddModuleFlagU32(llmod, llvm::LLVMModFlagBehavior::Warning, avoid_plt, 1);
|
llvm::LLVMRustAddModuleFlagU32(llmod, llvm::LLVMModFlagBehavior::Warning, avoid_plt, 1);
|
||||||
}
|
}
|
||||||
|
@ -215,7 +216,7 @@ pub unsafe fn create_module<'ll>(
|
||||||
|
|
||||||
// Enable canonical jump tables if CFI is enabled. (See https://reviews.llvm.org/D65629.)
|
// Enable canonical jump tables if CFI is enabled. (See https://reviews.llvm.org/D65629.)
|
||||||
if sess.is_sanitizer_cfi_canonical_jump_tables_enabled() && sess.is_sanitizer_cfi_enabled() {
|
if sess.is_sanitizer_cfi_canonical_jump_tables_enabled() && sess.is_sanitizer_cfi_enabled() {
|
||||||
let canonical_jump_tables = c"CFI Canonical Jump Tables".as_ptr().cast();
|
let canonical_jump_tables = c"CFI Canonical Jump Tables".as_ptr();
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMRustAddModuleFlagU32(
|
llvm::LLVMRustAddModuleFlagU32(
|
||||||
llmod,
|
llmod,
|
||||||
|
@ -226,9 +227,23 @@ pub unsafe fn create_module<'ll>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If we're normalizing integers with CFI, ensure LLVM generated functions do the same.
|
||||||
|
// See https://github.com/llvm/llvm-project/pull/104826
|
||||||
|
if sess.is_sanitizer_cfi_normalize_integers_enabled() {
|
||||||
|
let cfi_normalize_integers = c"cfi-normalize-integers".as_ptr().cast();
|
||||||
|
unsafe {
|
||||||
|
llvm::LLVMRustAddModuleFlagU32(
|
||||||
|
llmod,
|
||||||
|
llvm::LLVMModFlagBehavior::Override,
|
||||||
|
cfi_normalize_integers,
|
||||||
|
1,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Enable LTO unit splitting if specified or if CFI is enabled. (See https://reviews.llvm.org/D53891.)
|
// Enable LTO unit splitting if specified or if CFI is enabled. (See https://reviews.llvm.org/D53891.)
|
||||||
if sess.is_split_lto_unit_enabled() || sess.is_sanitizer_cfi_enabled() {
|
if sess.is_split_lto_unit_enabled() || sess.is_sanitizer_cfi_enabled() {
|
||||||
let enable_split_lto_unit = c"EnableSplitLTOUnit".as_ptr().cast();
|
let enable_split_lto_unit = c"EnableSplitLTOUnit".as_ptr();
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMRustAddModuleFlagU32(
|
llvm::LLVMRustAddModuleFlagU32(
|
||||||
llmod,
|
llmod,
|
||||||
|
@ -241,10 +256,26 @@ pub unsafe fn create_module<'ll>(
|
||||||
|
|
||||||
// Add "kcfi" module flag if KCFI is enabled. (See https://reviews.llvm.org/D119296.)
|
// Add "kcfi" module flag if KCFI is enabled. (See https://reviews.llvm.org/D119296.)
|
||||||
if sess.is_sanitizer_kcfi_enabled() {
|
if sess.is_sanitizer_kcfi_enabled() {
|
||||||
let kcfi = c"kcfi".as_ptr().cast();
|
let kcfi = c"kcfi".as_ptr();
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMRustAddModuleFlagU32(llmod, llvm::LLVMModFlagBehavior::Override, kcfi, 1);
|
llvm::LLVMRustAddModuleFlagU32(llmod, llvm::LLVMModFlagBehavior::Override, kcfi, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add "kcfi-offset" module flag with -Z patchable-function-entry (See
|
||||||
|
// https://reviews.llvm.org/D141172).
|
||||||
|
let pfe =
|
||||||
|
PatchableFunctionEntry::from_config(sess.opts.unstable_opts.patchable_function_entry);
|
||||||
|
if pfe.prefix() > 0 {
|
||||||
|
let kcfi_offset = c"kcfi-offset".as_ptr().cast();
|
||||||
|
unsafe {
|
||||||
|
llvm::LLVMRustAddModuleFlagU32(
|
||||||
|
llmod,
|
||||||
|
llvm::LLVMModFlagBehavior::Override,
|
||||||
|
kcfi_offset,
|
||||||
|
pfe.prefix().into(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Control Flow Guard is currently only supported by the MSVC linker on Windows.
|
// Control Flow Guard is currently only supported by the MSVC linker on Windows.
|
||||||
|
@ -280,26 +311,26 @@ pub unsafe fn create_module<'ll>(
|
||||||
llvm::LLVMRustAddModuleFlagU32(
|
llvm::LLVMRustAddModuleFlagU32(
|
||||||
llmod,
|
llmod,
|
||||||
llvm::LLVMModFlagBehavior::Min,
|
llvm::LLVMModFlagBehavior::Min,
|
||||||
c"branch-target-enforcement".as_ptr().cast(),
|
c"branch-target-enforcement".as_ptr(),
|
||||||
bti.into(),
|
bti.into(),
|
||||||
);
|
);
|
||||||
llvm::LLVMRustAddModuleFlagU32(
|
llvm::LLVMRustAddModuleFlagU32(
|
||||||
llmod,
|
llmod,
|
||||||
llvm::LLVMModFlagBehavior::Min,
|
llvm::LLVMModFlagBehavior::Min,
|
||||||
c"sign-return-address".as_ptr().cast(),
|
c"sign-return-address".as_ptr(),
|
||||||
pac_ret.is_some().into(),
|
pac_ret.is_some().into(),
|
||||||
);
|
);
|
||||||
let pac_opts = pac_ret.unwrap_or(PacRet { leaf: false, key: PAuthKey::A });
|
let pac_opts = pac_ret.unwrap_or(PacRet { leaf: false, key: PAuthKey::A });
|
||||||
llvm::LLVMRustAddModuleFlagU32(
|
llvm::LLVMRustAddModuleFlagU32(
|
||||||
llmod,
|
llmod,
|
||||||
llvm::LLVMModFlagBehavior::Min,
|
llvm::LLVMModFlagBehavior::Min,
|
||||||
c"sign-return-address-all".as_ptr().cast(),
|
c"sign-return-address-all".as_ptr(),
|
||||||
pac_opts.leaf.into(),
|
pac_opts.leaf.into(),
|
||||||
);
|
);
|
||||||
llvm::LLVMRustAddModuleFlagU32(
|
llvm::LLVMRustAddModuleFlagU32(
|
||||||
llmod,
|
llmod,
|
||||||
llvm::LLVMModFlagBehavior::Min,
|
llvm::LLVMModFlagBehavior::Min,
|
||||||
c"sign-return-address-with-bkey".as_ptr().cast(),
|
c"sign-return-address-with-bkey".as_ptr(),
|
||||||
u32::from(pac_opts.key == PAuthKey::B),
|
u32::from(pac_opts.key == PAuthKey::B),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -317,7 +348,7 @@ pub unsafe fn create_module<'ll>(
|
||||||
llvm::LLVMRustAddModuleFlagU32(
|
llvm::LLVMRustAddModuleFlagU32(
|
||||||
llmod,
|
llmod,
|
||||||
llvm::LLVMModFlagBehavior::Override,
|
llvm::LLVMModFlagBehavior::Override,
|
||||||
c"cf-protection-branch".as_ptr().cast(),
|
c"cf-protection-branch".as_ptr(),
|
||||||
1,
|
1,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -327,7 +358,7 @@ pub unsafe fn create_module<'ll>(
|
||||||
llvm::LLVMRustAddModuleFlagU32(
|
llvm::LLVMRustAddModuleFlagU32(
|
||||||
llmod,
|
llmod,
|
||||||
llvm::LLVMModFlagBehavior::Override,
|
llvm::LLVMModFlagBehavior::Override,
|
||||||
c"cf-protection-return".as_ptr().cast(),
|
c"cf-protection-return".as_ptr(),
|
||||||
1,
|
1,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -338,7 +369,7 @@ pub unsafe fn create_module<'ll>(
|
||||||
llvm::LLVMRustAddModuleFlagU32(
|
llvm::LLVMRustAddModuleFlagU32(
|
||||||
llmod,
|
llmod,
|
||||||
llvm::LLVMModFlagBehavior::Error,
|
llvm::LLVMModFlagBehavior::Error,
|
||||||
c"Virtual Function Elim".as_ptr().cast(),
|
c"Virtual Function Elim".as_ptr(),
|
||||||
1,
|
1,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -531,7 +562,9 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn coverage_context(&self) -> Option<&coverageinfo::CrateCoverageContext<'ll, 'tcx>> {
|
pub(crate) fn coverage_context(
|
||||||
|
&self,
|
||||||
|
) -> Option<&coverageinfo::CrateCoverageContext<'ll, 'tcx>> {
|
||||||
self.coverage_cx.as_ref()
|
self.coverage_cx.as_ref()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1000,8 +1033,10 @@ impl<'ll> CodegenCx<'ll, '_> {
|
||||||
ifn!("llvm.is.constant.i64", fn(t_i64) -> i1);
|
ifn!("llvm.is.constant.i64", fn(t_i64) -> i1);
|
||||||
ifn!("llvm.is.constant.i128", fn(t_i128) -> i1);
|
ifn!("llvm.is.constant.i128", fn(t_i128) -> i1);
|
||||||
ifn!("llvm.is.constant.isize", fn(t_isize) -> i1);
|
ifn!("llvm.is.constant.isize", fn(t_isize) -> i1);
|
||||||
|
ifn!("llvm.is.constant.f16", fn(t_f16) -> i1);
|
||||||
ifn!("llvm.is.constant.f32", fn(t_f32) -> i1);
|
ifn!("llvm.is.constant.f32", fn(t_f32) -> i1);
|
||||||
ifn!("llvm.is.constant.f64", fn(t_f64) -> i1);
|
ifn!("llvm.is.constant.f64", fn(t_f64) -> i1);
|
||||||
|
ifn!("llvm.is.constant.f128", fn(t_f128) -> i1);
|
||||||
ifn!("llvm.is.constant.ptr", fn(ptr) -> i1);
|
ifn!("llvm.is.constant.ptr", fn(ptr) -> i1);
|
||||||
|
|
||||||
ifn!("llvm.expect.i1", fn(i1, i1) -> i1);
|
ifn!("llvm.expect.i1", fn(i1, i1) -> i1);
|
||||||
|
@ -1064,7 +1099,7 @@ impl<'ll> CodegenCx<'ll, '_> {
|
||||||
impl CodegenCx<'_, '_> {
|
impl CodegenCx<'_, '_> {
|
||||||
/// Generates a new symbol name with the given prefix. This symbol name must
|
/// Generates a new symbol name with the given prefix. This symbol name must
|
||||||
/// only be used for definitions with `internal` or `private` linkage.
|
/// only be used for definitions with `internal` or `private` linkage.
|
||||||
pub fn generate_local_symbol_name(&self, prefix: &str) -> String {
|
pub(crate) fn generate_local_symbol_name(&self, prefix: &str) -> String {
|
||||||
let idx = self.local_gen_sym_counter.get();
|
let idx = self.local_gen_sym_counter.get();
|
||||||
self.local_gen_sym_counter.set(idx + 1);
|
self.local_gen_sym_counter.set(idx + 1);
|
||||||
// Include a '.' character, so there can be no accidental conflicts with
|
// Include a '.' character, so there can be no accidental conflicts with
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use rustc_middle::mir::coverage::{
|
use rustc_middle::mir::coverage::{
|
||||||
CodeRegion, ConditionInfo, CounterId, CovTerm, DecisionInfo, ExpressionId, MappingKind,
|
ConditionInfo, CounterId, CovTerm, DecisionInfo, ExpressionId, MappingKind, SourceRegion,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Must match the layout of `LLVMRustCounterKind`.
|
/// Must match the layout of `LLVMRustCounterKind`.
|
||||||
|
@ -80,7 +80,7 @@ pub struct CounterExpression {
|
||||||
/// Must match the layout of `LLVMRustCounterMappingRegionKind`.
|
/// Must match the layout of `LLVMRustCounterMappingRegionKind`.
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub enum RegionKind {
|
enum RegionKind {
|
||||||
/// A CodeRegion associates some code with a counter
|
/// A CodeRegion associates some code with a counter
|
||||||
CodeRegion = 0,
|
CodeRegion = 0,
|
||||||
|
|
||||||
|
@ -110,13 +110,13 @@ pub enum RegionKind {
|
||||||
MCDCBranchRegion = 6,
|
MCDCBranchRegion = 6,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod mcdc {
|
mod mcdc {
|
||||||
use rustc_middle::mir::coverage::{ConditionInfo, DecisionInfo};
|
use rustc_middle::mir::coverage::{ConditionInfo, DecisionInfo};
|
||||||
|
|
||||||
/// Must match the layout of `LLVMRustMCDCDecisionParameters`.
|
/// Must match the layout of `LLVMRustMCDCDecisionParameters`.
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Clone, Copy, Debug, Default)]
|
#[derive(Clone, Copy, Debug, Default)]
|
||||||
pub struct DecisionParameters {
|
pub(crate) struct DecisionParameters {
|
||||||
bitmap_idx: u32,
|
bitmap_idx: u32,
|
||||||
num_conditions: u16,
|
num_conditions: u16,
|
||||||
}
|
}
|
||||||
|
@ -127,14 +127,14 @@ pub mod mcdc {
|
||||||
/// Must match the layout of `LLVMRustMCDCBranchParameters`.
|
/// Must match the layout of `LLVMRustMCDCBranchParameters`.
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Clone, Copy, Debug, Default)]
|
#[derive(Clone, Copy, Debug, Default)]
|
||||||
pub struct BranchParameters {
|
pub(crate) struct BranchParameters {
|
||||||
condition_id: LLVMConditionId,
|
condition_id: LLVMConditionId,
|
||||||
condition_ids: [LLVMConditionId; 2],
|
condition_ids: [LLVMConditionId; 2],
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
pub enum ParameterTag {
|
enum ParameterTag {
|
||||||
None = 0,
|
None = 0,
|
||||||
Decision = 1,
|
Decision = 1,
|
||||||
Branch = 2,
|
Branch = 2,
|
||||||
|
@ -142,24 +142,24 @@ pub mod mcdc {
|
||||||
/// Same layout with `LLVMRustMCDCParameters`
|
/// Same layout with `LLVMRustMCDCParameters`
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
pub struct Parameters {
|
pub(crate) struct Parameters {
|
||||||
tag: ParameterTag,
|
tag: ParameterTag,
|
||||||
decision_params: DecisionParameters,
|
decision_params: DecisionParameters,
|
||||||
branch_params: BranchParameters,
|
branch_params: BranchParameters,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Parameters {
|
impl Parameters {
|
||||||
pub fn none() -> Self {
|
pub(crate) fn none() -> Self {
|
||||||
Self {
|
Self {
|
||||||
tag: ParameterTag::None,
|
tag: ParameterTag::None,
|
||||||
decision_params: Default::default(),
|
decision_params: Default::default(),
|
||||||
branch_params: Default::default(),
|
branch_params: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn decision(decision_params: DecisionParameters) -> Self {
|
pub(crate) fn decision(decision_params: DecisionParameters) -> Self {
|
||||||
Self { tag: ParameterTag::Decision, decision_params, branch_params: Default::default() }
|
Self { tag: ParameterTag::Decision, decision_params, branch_params: Default::default() }
|
||||||
}
|
}
|
||||||
pub fn branch(branch_params: BranchParameters) -> Self {
|
pub(crate) fn branch(branch_params: BranchParameters) -> Self {
|
||||||
Self { tag: ParameterTag::Branch, decision_params: Default::default(), branch_params }
|
Self { tag: ParameterTag::Branch, decision_params: Default::default(), branch_params }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -236,9 +236,10 @@ impl CounterMappingRegion {
|
||||||
pub(crate) fn from_mapping(
|
pub(crate) fn from_mapping(
|
||||||
mapping_kind: &MappingKind,
|
mapping_kind: &MappingKind,
|
||||||
local_file_id: u32,
|
local_file_id: u32,
|
||||||
code_region: &CodeRegion,
|
source_region: &SourceRegion,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let &CodeRegion { file_name: _, start_line, start_col, end_line, end_col } = code_region;
|
let &SourceRegion { file_name: _, start_line, start_col, end_line, end_col } =
|
||||||
|
source_region;
|
||||||
match *mapping_kind {
|
match *mapping_kind {
|
||||||
MappingKind::Code(term) => Self::code_region(
|
MappingKind::Code(term) => Self::code_region(
|
||||||
Counter::from_term(term),
|
Counter::from_term(term),
|
||||||
|
|
|
@ -2,8 +2,8 @@ use rustc_data_structures::captures::Captures;
|
||||||
use rustc_data_structures::fx::FxIndexSet;
|
use rustc_data_structures::fx::FxIndexSet;
|
||||||
use rustc_index::bit_set::BitSet;
|
use rustc_index::bit_set::BitSet;
|
||||||
use rustc_middle::mir::coverage::{
|
use rustc_middle::mir::coverage::{
|
||||||
CodeRegion, CounterId, CovTerm, Expression, ExpressionId, FunctionCoverageInfo, Mapping,
|
CounterId, CovTerm, Expression, ExpressionId, FunctionCoverageInfo, Mapping, MappingKind, Op,
|
||||||
MappingKind, Op,
|
SourceRegion,
|
||||||
};
|
};
|
||||||
use rustc_middle::ty::Instance;
|
use rustc_middle::ty::Instance;
|
||||||
use rustc_span::Symbol;
|
use rustc_span::Symbol;
|
||||||
|
@ -14,7 +14,7 @@ use crate::coverageinfo::ffi::{Counter, CounterExpression, ExprKind};
|
||||||
/// Holds all of the coverage mapping data associated with a function instance,
|
/// Holds all of the coverage mapping data associated with a function instance,
|
||||||
/// collected during traversal of `Coverage` statements in the function's MIR.
|
/// collected during traversal of `Coverage` statements in the function's MIR.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct FunctionCoverageCollector<'tcx> {
|
pub(crate) struct FunctionCoverageCollector<'tcx> {
|
||||||
/// Coverage info that was attached to this function by the instrumentor.
|
/// Coverage info that was attached to this function by the instrumentor.
|
||||||
function_coverage_info: &'tcx FunctionCoverageInfo,
|
function_coverage_info: &'tcx FunctionCoverageInfo,
|
||||||
is_used: bool,
|
is_used: bool,
|
||||||
|
@ -32,7 +32,7 @@ pub struct FunctionCoverageCollector<'tcx> {
|
||||||
|
|
||||||
impl<'tcx> FunctionCoverageCollector<'tcx> {
|
impl<'tcx> FunctionCoverageCollector<'tcx> {
|
||||||
/// Creates a new set of coverage data for a used (called) function.
|
/// Creates a new set of coverage data for a used (called) function.
|
||||||
pub fn new(
|
pub(crate) fn new(
|
||||||
instance: Instance<'tcx>,
|
instance: Instance<'tcx>,
|
||||||
function_coverage_info: &'tcx FunctionCoverageInfo,
|
function_coverage_info: &'tcx FunctionCoverageInfo,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
@ -40,7 +40,7 @@ impl<'tcx> FunctionCoverageCollector<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new set of coverage data for an unused (never called) function.
|
/// Creates a new set of coverage data for an unused (never called) function.
|
||||||
pub fn unused(
|
pub(crate) fn unused(
|
||||||
instance: Instance<'tcx>,
|
instance: Instance<'tcx>,
|
||||||
function_coverage_info: &'tcx FunctionCoverageInfo,
|
function_coverage_info: &'tcx FunctionCoverageInfo,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
@ -195,13 +195,13 @@ impl<'tcx> FunctionCoverage<'tcx> {
|
||||||
|
|
||||||
/// Return the source hash, generated from the HIR node structure, and used to indicate whether
|
/// Return the source hash, generated from the HIR node structure, and used to indicate whether
|
||||||
/// or not the source code structure changed between different compilations.
|
/// or not the source code structure changed between different compilations.
|
||||||
pub fn source_hash(&self) -> u64 {
|
pub(crate) fn source_hash(&self) -> u64 {
|
||||||
if self.is_used { self.function_coverage_info.function_source_hash } else { 0 }
|
if self.is_used { self.function_coverage_info.function_source_hash } else { 0 }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns an iterator over all filenames used by this function's mappings.
|
/// Returns an iterator over all filenames used by this function's mappings.
|
||||||
pub(crate) fn all_file_names(&self) -> impl Iterator<Item = Symbol> + Captures<'_> {
|
pub(crate) fn all_file_names(&self) -> impl Iterator<Item = Symbol> + Captures<'_> {
|
||||||
self.function_coverage_info.mappings.iter().map(|mapping| mapping.code_region.file_name)
|
self.function_coverage_info.mappings.iter().map(|mapping| mapping.source_region.file_name)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert this function's coverage expression data into a form that can be
|
/// Convert this function's coverage expression data into a form that can be
|
||||||
|
@ -230,12 +230,12 @@ impl<'tcx> FunctionCoverage<'tcx> {
|
||||||
/// that will be used by `mapgen` when preparing for FFI.
|
/// that will be used by `mapgen` when preparing for FFI.
|
||||||
pub(crate) fn counter_regions(
|
pub(crate) fn counter_regions(
|
||||||
&self,
|
&self,
|
||||||
) -> impl Iterator<Item = (MappingKind, &CodeRegion)> + ExactSizeIterator {
|
) -> impl Iterator<Item = (MappingKind, &SourceRegion)> + ExactSizeIterator {
|
||||||
self.function_coverage_info.mappings.iter().map(move |mapping| {
|
self.function_coverage_info.mappings.iter().map(move |mapping| {
|
||||||
let Mapping { kind, code_region } = mapping;
|
let Mapping { kind, source_region } = mapping;
|
||||||
let kind =
|
let kind =
|
||||||
kind.map_terms(|term| if self.is_zero_term(term) { CovTerm::Zero } else { term });
|
kind.map_terms(|term| if self.is_zero_term(term) { CovTerm::Zero } else { term });
|
||||||
(kind, code_region)
|
(kind, source_region)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ use crate::{coverageinfo, llvm};
|
||||||
/// implementing this Rust version, and though the format documentation is very explicit and
|
/// implementing this Rust version, and though the format documentation is very explicit and
|
||||||
/// detailed, some undocumented details in Clang's implementation (that may or may not be important)
|
/// detailed, some undocumented details in Clang's implementation (that may or may not be important)
|
||||||
/// were also replicated for Rust's Coverage Map.
|
/// were also replicated for Rust's Coverage Map.
|
||||||
pub fn finalize(cx: &CodegenCx<'_, '_>) {
|
pub(crate) fn finalize(cx: &CodegenCx<'_, '_>) {
|
||||||
let tcx = cx.tcx;
|
let tcx = cx.tcx;
|
||||||
|
|
||||||
// Ensure that LLVM is using a version of the coverage mapping format that
|
// Ensure that LLVM is using a version of the coverage mapping format that
|
||||||
|
|
|
@ -22,10 +22,10 @@ use crate::llvm;
|
||||||
|
|
||||||
pub(crate) mod ffi;
|
pub(crate) mod ffi;
|
||||||
pub(crate) mod map_data;
|
pub(crate) mod map_data;
|
||||||
pub mod mapgen;
|
mod mapgen;
|
||||||
|
|
||||||
/// A context object for maintaining all state needed by the coverageinfo module.
|
/// A context object for maintaining all state needed by the coverageinfo module.
|
||||||
pub struct CrateCoverageContext<'ll, 'tcx> {
|
pub(crate) struct CrateCoverageContext<'ll, 'tcx> {
|
||||||
/// Coverage data for each instrumented function identified by DefId.
|
/// Coverage data for each instrumented function identified by DefId.
|
||||||
pub(crate) function_coverage_map:
|
pub(crate) function_coverage_map:
|
||||||
RefCell<FxIndexMap<Instance<'tcx>, FunctionCoverageCollector<'tcx>>>,
|
RefCell<FxIndexMap<Instance<'tcx>, FunctionCoverageCollector<'tcx>>>,
|
||||||
|
@ -34,7 +34,7 @@ pub struct CrateCoverageContext<'ll, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ll, 'tcx> CrateCoverageContext<'ll, 'tcx> {
|
impl<'ll, 'tcx> CrateCoverageContext<'ll, 'tcx> {
|
||||||
pub fn new() -> Self {
|
pub(crate) fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
function_coverage_map: Default::default(),
|
function_coverage_map: Default::default(),
|
||||||
pgo_func_name_var_map: Default::default(),
|
pgo_func_name_var_map: Default::default(),
|
||||||
|
@ -42,7 +42,7 @@ impl<'ll, 'tcx> CrateCoverageContext<'ll, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn take_function_coverage_map(
|
fn take_function_coverage_map(
|
||||||
&self,
|
&self,
|
||||||
) -> FxIndexMap<Instance<'tcx>, FunctionCoverageCollector<'tcx>> {
|
) -> FxIndexMap<Instance<'tcx>, FunctionCoverageCollector<'tcx>> {
|
||||||
self.function_coverage_map.replace(FxIndexMap::default())
|
self.function_coverage_map.replace(FxIndexMap::default())
|
||||||
|
|
|
@ -15,7 +15,7 @@ use crate::llvm::debuginfo::{DILocation, DIScope};
|
||||||
|
|
||||||
/// Produces DIScope DIEs for each MIR Scope which has variables defined in it.
|
/// Produces DIScope DIEs for each MIR Scope which has variables defined in it.
|
||||||
// FIXME(eddyb) almost all of this should be in `rustc_codegen_ssa::mir::debuginfo`.
|
// FIXME(eddyb) almost all of this should be in `rustc_codegen_ssa::mir::debuginfo`.
|
||||||
pub fn compute_mir_scopes<'ll, 'tcx>(
|
pub(crate) fn compute_mir_scopes<'ll, 'tcx>(
|
||||||
cx: &CodegenCx<'ll, 'tcx>,
|
cx: &CodegenCx<'ll, 'tcx>,
|
||||||
instance: Instance<'tcx>,
|
instance: Instance<'tcx>,
|
||||||
mir: &Body<'tcx>,
|
mir: &Body<'tcx>,
|
||||||
|
@ -88,7 +88,7 @@ fn make_mir_scope<'ll, 'tcx>(
|
||||||
let loc = cx.lookup_debug_loc(scope_data.span.lo());
|
let loc = cx.lookup_debug_loc(scope_data.span.lo());
|
||||||
let file_metadata = file_metadata(cx, &loc.file);
|
let file_metadata = file_metadata(cx, &loc.file);
|
||||||
|
|
||||||
let parent_dbg_scope = match scope_data.inlined {
|
let dbg_scope = match scope_data.inlined {
|
||||||
Some((callee, _)) => {
|
Some((callee, _)) => {
|
||||||
// FIXME(eddyb) this would be `self.monomorphize(&callee)`
|
// FIXME(eddyb) this would be `self.monomorphize(&callee)`
|
||||||
// if this is moved to `rustc_codegen_ssa::mir::debuginfo`.
|
// if this is moved to `rustc_codegen_ssa::mir::debuginfo`.
|
||||||
|
@ -102,17 +102,15 @@ fn make_mir_scope<'ll, 'tcx>(
|
||||||
cx.dbg_scope_fn(callee, callee_fn_abi, None)
|
cx.dbg_scope_fn(callee, callee_fn_abi, None)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
None => parent_scope.dbg_scope,
|
None => unsafe {
|
||||||
};
|
llvm::LLVMRustDIBuilderCreateLexicalBlock(
|
||||||
|
DIB(cx),
|
||||||
let dbg_scope = unsafe {
|
parent_scope.dbg_scope,
|
||||||
llvm::LLVMRustDIBuilderCreateLexicalBlock(
|
file_metadata,
|
||||||
DIB(cx),
|
loc.line,
|
||||||
parent_dbg_scope,
|
loc.col,
|
||||||
file_metadata,
|
)
|
||||||
loc.line,
|
},
|
||||||
loc.col,
|
|
||||||
)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let inlined_at = scope_data.inlined.map(|(_, callsite_span)| {
|
let inlined_at = scope_data.inlined.map(|(_, callsite_span)| {
|
||||||
|
|
|
@ -16,7 +16,7 @@ use crate::value::Value;
|
||||||
|
|
||||||
/// Inserts a side-effect free instruction sequence that makes sure that the
|
/// Inserts a side-effect free instruction sequence that makes sure that the
|
||||||
/// .debug_gdb_scripts global is referenced, so it isn't removed by the linker.
|
/// .debug_gdb_scripts global is referenced, so it isn't removed by the linker.
|
||||||
pub fn insert_reference_to_gdb_debug_scripts_section_global(bx: &mut Builder<'_, '_, '_>) {
|
pub(crate) fn insert_reference_to_gdb_debug_scripts_section_global(bx: &mut Builder<'_, '_, '_>) {
|
||||||
if needs_gdb_debug_scripts_section(bx) {
|
if needs_gdb_debug_scripts_section(bx) {
|
||||||
let gdb_debug_scripts_section = get_or_insert_gdb_debug_scripts_section_global(bx);
|
let gdb_debug_scripts_section = get_or_insert_gdb_debug_scripts_section_global(bx);
|
||||||
// Load just the first byte as that's all that's necessary to force
|
// Load just the first byte as that's all that's necessary to force
|
||||||
|
@ -30,12 +30,13 @@ pub fn insert_reference_to_gdb_debug_scripts_section_global(bx: &mut Builder<'_,
|
||||||
|
|
||||||
/// Allocates the global variable responsible for the .debug_gdb_scripts binary
|
/// Allocates the global variable responsible for the .debug_gdb_scripts binary
|
||||||
/// section.
|
/// section.
|
||||||
pub fn get_or_insert_gdb_debug_scripts_section_global<'ll>(cx: &CodegenCx<'ll, '_>) -> &'ll Value {
|
pub(crate) fn get_or_insert_gdb_debug_scripts_section_global<'ll>(
|
||||||
|
cx: &CodegenCx<'ll, '_>,
|
||||||
|
) -> &'ll Value {
|
||||||
let c_section_var_name = c"__rustc_debug_gdb_scripts_section__";
|
let c_section_var_name = c"__rustc_debug_gdb_scripts_section__";
|
||||||
let section_var_name = c_section_var_name.to_str().unwrap();
|
let section_var_name = c_section_var_name.to_str().unwrap();
|
||||||
|
|
||||||
let section_var =
|
let section_var = unsafe { llvm::LLVMGetNamedGlobal(cx.llmod, c_section_var_name.as_ptr()) };
|
||||||
unsafe { llvm::LLVMGetNamedGlobal(cx.llmod, c_section_var_name.as_ptr().cast()) };
|
|
||||||
|
|
||||||
section_var.unwrap_or_else(|| {
|
section_var.unwrap_or_else(|| {
|
||||||
let mut section_contents = Vec::new();
|
let mut section_contents = Vec::new();
|
||||||
|
@ -70,7 +71,7 @@ pub fn get_or_insert_gdb_debug_scripts_section_global<'ll>(cx: &CodegenCx<'ll, '
|
||||||
let section_var = cx
|
let section_var = cx
|
||||||
.define_global(section_var_name, llvm_type)
|
.define_global(section_var_name, llvm_type)
|
||||||
.unwrap_or_else(|| bug!("symbol `{}` is already defined", section_var_name));
|
.unwrap_or_else(|| bug!("symbol `{}` is already defined", section_var_name));
|
||||||
llvm::LLVMSetSection(section_var, c".debug_gdb_scripts".as_ptr().cast());
|
llvm::LLVMSetSection(section_var, c".debug_gdb_scripts".as_ptr());
|
||||||
llvm::LLVMSetInitializer(section_var, cx.const_bytes(section_contents));
|
llvm::LLVMSetInitializer(section_var, cx.const_bytes(section_contents));
|
||||||
llvm::LLVMSetGlobalConstant(section_var, llvm::True);
|
llvm::LLVMSetGlobalConstant(section_var, llvm::True);
|
||||||
llvm::LLVMSetUnnamedAddress(section_var, llvm::UnnamedAddr::Global);
|
llvm::LLVMSetUnnamedAddress(section_var, llvm::UnnamedAddr::Global);
|
||||||
|
@ -83,7 +84,7 @@ pub fn get_or_insert_gdb_debug_scripts_section_global<'ll>(cx: &CodegenCx<'ll, '
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn needs_gdb_debug_scripts_section(cx: &CodegenCx<'_, '_>) -> bool {
|
pub(crate) fn needs_gdb_debug_scripts_section(cx: &CodegenCx<'_, '_>) -> bool {
|
||||||
let omit_gdb_pretty_printer_section =
|
let omit_gdb_pretty_printer_section =
|
||||||
attr::contains_name(cx.tcx.hir().krate_attrs(), sym::omit_gdb_pretty_printer_section);
|
attr::contains_name(cx.tcx.hir().krate_attrs(), sym::omit_gdb_pretty_printer_section);
|
||||||
|
|
||||||
|
|
|
@ -85,7 +85,7 @@ const NO_GENERICS: for<'ll> fn(&CodegenCx<'ll, '_>) -> SmallVec<&'ll DIType> = |
|
||||||
|
|
||||||
// SmallVec is used quite a bit in this module, so create a shorthand.
|
// SmallVec is used quite a bit in this module, so create a shorthand.
|
||||||
// The actual number of elements is not so important.
|
// The actual number of elements is not so important.
|
||||||
pub type SmallVec<T> = smallvec::SmallVec<[T; 16]>;
|
type SmallVec<T> = smallvec::SmallVec<[T; 16]>;
|
||||||
|
|
||||||
mod enums;
|
mod enums;
|
||||||
mod type_map;
|
mod type_map;
|
||||||
|
@ -425,7 +425,7 @@ fn build_slice_type_di_node<'ll, 'tcx>(
|
||||||
///
|
///
|
||||||
/// This function will look up the debuginfo node in the TypeMap. If it can't find it, it
|
/// This function will look up the debuginfo node in the TypeMap. If it can't find it, it
|
||||||
/// will create the node by dispatching to the corresponding `build_*_di_node()` function.
|
/// will create the node by dispatching to the corresponding `build_*_di_node()` function.
|
||||||
pub fn type_di_node<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -> &'ll DIType {
|
pub(crate) fn type_di_node<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -> &'ll DIType {
|
||||||
let unique_type_id = UniqueTypeId::for_ty(cx.tcx, t);
|
let unique_type_id = UniqueTypeId::for_ty(cx.tcx, t);
|
||||||
|
|
||||||
if let Some(existing_di_node) = debug_context(cx).type_map.di_node_for_unique_id(unique_type_id)
|
if let Some(existing_di_node) = debug_context(cx).type_map.di_node_for_unique_id(unique_type_id)
|
||||||
|
@ -456,7 +456,7 @@ pub fn type_di_node<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -> &'ll D
|
||||||
{
|
{
|
||||||
build_pointer_or_reference_di_node(cx, t, t.boxed_ty(), unique_type_id)
|
build_pointer_or_reference_di_node(cx, t, t.boxed_ty(), unique_type_id)
|
||||||
}
|
}
|
||||||
ty::FnDef(..) | ty::FnPtr(_) => build_subroutine_type_di_node(cx, unique_type_id),
|
ty::FnDef(..) | ty::FnPtr(..) => build_subroutine_type_di_node(cx, unique_type_id),
|
||||||
ty::Closure(..) => build_closure_env_di_node(cx, unique_type_id),
|
ty::Closure(..) => build_closure_env_di_node(cx, unique_type_id),
|
||||||
ty::CoroutineClosure(..) => build_closure_env_di_node(cx, unique_type_id),
|
ty::CoroutineClosure(..) => build_closure_env_di_node(cx, unique_type_id),
|
||||||
ty::Coroutine(..) => enums::build_coroutine_di_node(cx, unique_type_id),
|
ty::Coroutine(..) => enums::build_coroutine_di_node(cx, unique_type_id),
|
||||||
|
@ -531,7 +531,7 @@ fn hex_encode(data: &[u8]) -> String {
|
||||||
hex_string
|
hex_string
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn file_metadata<'ll>(cx: &CodegenCx<'ll, '_>, source_file: &SourceFile) -> &'ll DIFile {
|
pub(crate) fn file_metadata<'ll>(cx: &CodegenCx<'ll, '_>, source_file: &SourceFile) -> &'ll DIFile {
|
||||||
let cache_key = Some((source_file.stable_id, source_file.src_hash));
|
let cache_key = Some((source_file.stable_id, source_file.src_hash));
|
||||||
return debug_context(cx)
|
return debug_context(cx)
|
||||||
.created_files
|
.created_files
|
||||||
|
@ -629,6 +629,9 @@ pub fn file_metadata<'ll>(cx: &CodegenCx<'ll, '_>, source_file: &SourceFile) ->
|
||||||
};
|
};
|
||||||
let hash_value = hex_encode(source_file.src_hash.hash_bytes());
|
let hash_value = hex_encode(source_file.src_hash.hash_bytes());
|
||||||
|
|
||||||
|
let source =
|
||||||
|
cx.sess().opts.unstable_opts.embed_source.then_some(()).and(source_file.src.as_ref());
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMRustDIBuilderCreateFile(
|
llvm::LLVMRustDIBuilderCreateFile(
|
||||||
DIB(cx),
|
DIB(cx),
|
||||||
|
@ -639,12 +642,14 @@ pub fn file_metadata<'ll>(cx: &CodegenCx<'ll, '_>, source_file: &SourceFile) ->
|
||||||
hash_kind,
|
hash_kind,
|
||||||
hash_value.as_ptr().cast(),
|
hash_value.as_ptr().cast(),
|
||||||
hash_value.len(),
|
hash_value.len(),
|
||||||
|
source.map_or(ptr::null(), |x| x.as_ptr().cast()),
|
||||||
|
source.map_or(0, |x| x.len()),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unknown_file_metadata<'ll>(cx: &CodegenCx<'ll, '_>) -> &'ll DIFile {
|
fn unknown_file_metadata<'ll>(cx: &CodegenCx<'ll, '_>) -> &'ll DIFile {
|
||||||
debug_context(cx).created_files.borrow_mut().entry(None).or_insert_with(|| unsafe {
|
debug_context(cx).created_files.borrow_mut().entry(None).or_insert_with(|| unsafe {
|
||||||
let file_name = "<unknown>";
|
let file_name = "<unknown>";
|
||||||
let directory = "";
|
let directory = "";
|
||||||
|
@ -659,6 +664,8 @@ pub fn unknown_file_metadata<'ll>(cx: &CodegenCx<'ll, '_>) -> &'ll DIFile {
|
||||||
llvm::ChecksumKind::None,
|
llvm::ChecksumKind::None,
|
||||||
hash_value.as_ptr().cast(),
|
hash_value.as_ptr().cast(),
|
||||||
hash_value.len(),
|
hash_value.len(),
|
||||||
|
ptr::null(),
|
||||||
|
0,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -859,7 +866,7 @@ fn build_param_type_di_node<'ll, 'tcx>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build_compile_unit_di_node<'ll, 'tcx>(
|
pub(crate) fn build_compile_unit_di_node<'ll, 'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
codegen_unit_name: &str,
|
codegen_unit_name: &str,
|
||||||
debug_context: &CodegenUnitDebugContext<'ll, 'tcx>,
|
debug_context: &CodegenUnitDebugContext<'ll, 'tcx>,
|
||||||
|
@ -943,6 +950,8 @@ pub fn build_compile_unit_di_node<'ll, 'tcx>(
|
||||||
llvm::ChecksumKind::None,
|
llvm::ChecksumKind::None,
|
||||||
ptr::null(),
|
ptr::null(),
|
||||||
0,
|
0,
|
||||||
|
ptr::null(),
|
||||||
|
0,
|
||||||
);
|
);
|
||||||
|
|
||||||
let unit_metadata = llvm::LLVMRustDIBuilderCreateCompileUnit(
|
let unit_metadata = llvm::LLVMRustDIBuilderCreateCompileUnit(
|
||||||
|
@ -952,7 +961,7 @@ pub fn build_compile_unit_di_node<'ll, 'tcx>(
|
||||||
producer.as_ptr().cast(),
|
producer.as_ptr().cast(),
|
||||||
producer.len(),
|
producer.len(),
|
||||||
tcx.sess.opts.optimize != config::OptLevel::No,
|
tcx.sess.opts.optimize != config::OptLevel::No,
|
||||||
c"".as_ptr().cast(),
|
c"".as_ptr(),
|
||||||
0,
|
0,
|
||||||
// NB: this doesn't actually have any perceptible effect, it seems. LLVM will instead
|
// NB: this doesn't actually have any perceptible effect, it seems. LLVM will instead
|
||||||
// put the path supplied to `MCSplitDwarfFile` into the debug info of the final
|
// put the path supplied to `MCSplitDwarfFile` into the debug info of the final
|
||||||
|
@ -1319,7 +1328,11 @@ fn build_generic_type_param_di_nodes<'ll, 'tcx>(
|
||||||
/// Creates debug information for the given global variable.
|
/// Creates debug information for the given global variable.
|
||||||
///
|
///
|
||||||
/// Adds the created debuginfo nodes directly to the crate's IR.
|
/// Adds the created debuginfo nodes directly to the crate's IR.
|
||||||
pub fn build_global_var_di_node<'ll>(cx: &CodegenCx<'ll, '_>, def_id: DefId, global: &'ll Value) {
|
pub(crate) fn build_global_var_di_node<'ll>(
|
||||||
|
cx: &CodegenCx<'ll, '_>,
|
||||||
|
def_id: DefId,
|
||||||
|
global: &'ll Value,
|
||||||
|
) {
|
||||||
if cx.dbg_cx.is_none() {
|
if cx.dbg_cx.is_none() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1559,7 +1572,7 @@ pub(crate) fn apply_vcall_visibility_metadata<'ll, 'tcx>(
|
||||||
/// given type.
|
/// given type.
|
||||||
///
|
///
|
||||||
/// Adds the created metadata nodes directly to the crate's IR.
|
/// Adds the created metadata nodes directly to the crate's IR.
|
||||||
pub fn create_vtable_di_node<'ll, 'tcx>(
|
pub(crate) fn create_vtable_di_node<'ll, 'tcx>(
|
||||||
cx: &CodegenCx<'ll, 'tcx>,
|
cx: &CodegenCx<'ll, 'tcx>,
|
||||||
ty: Ty<'tcx>,
|
ty: Ty<'tcx>,
|
||||||
poly_trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,
|
poly_trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,
|
||||||
|
@ -1604,7 +1617,7 @@ pub fn create_vtable_di_node<'ll, 'tcx>(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates an "extension" of an existing `DIScope` into another file.
|
/// Creates an "extension" of an existing `DIScope` into another file.
|
||||||
pub fn extend_scope_to_file<'ll>(
|
pub(crate) fn extend_scope_to_file<'ll>(
|
||||||
cx: &CodegenCx<'ll, '_>,
|
cx: &CodegenCx<'ll, '_>,
|
||||||
scope_metadata: &'ll DIScope,
|
scope_metadata: &'ll DIScope,
|
||||||
file: &SourceFile,
|
file: &SourceFile,
|
||||||
|
@ -1613,7 +1626,7 @@ pub fn extend_scope_to_file<'ll>(
|
||||||
unsafe { llvm::LLVMRustDIBuilderCreateLexicalBlockFile(DIB(cx), scope_metadata, file_metadata) }
|
unsafe { llvm::LLVMRustDIBuilderCreateLexicalBlockFile(DIB(cx), scope_metadata, file_metadata) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tuple_field_name(field_index: usize) -> Cow<'static, str> {
|
fn tuple_field_name(field_index: usize) -> Cow<'static, str> {
|
||||||
const TUPLE_FIELD_NAMES: [&'static str; 16] = [
|
const TUPLE_FIELD_NAMES: [&'static str; 16] = [
|
||||||
"__0", "__1", "__2", "__3", "__4", "__5", "__6", "__7", "__8", "__9", "__10", "__11",
|
"__0", "__1", "__2", "__3", "__4", "__5", "__6", "__7", "__8", "__9", "__10", "__11",
|
||||||
"__12", "__13", "__14", "__15",
|
"__12", "__13", "__14", "__15",
|
||||||
|
|
|
@ -2,7 +2,7 @@ use std::borrow::Cow;
|
||||||
|
|
||||||
use libc::c_uint;
|
use libc::c_uint;
|
||||||
use rustc_codegen_ssa::debuginfo::type_names::compute_debuginfo_type_name;
|
use rustc_codegen_ssa::debuginfo::type_names::compute_debuginfo_type_name;
|
||||||
use rustc_codegen_ssa::debuginfo::wants_c_like_enum_debuginfo;
|
use rustc_codegen_ssa::debuginfo::{tag_base_type, wants_c_like_enum_debuginfo};
|
||||||
use rustc_codegen_ssa::traits::ConstMethods;
|
use rustc_codegen_ssa::traits::ConstMethods;
|
||||||
use rustc_index::IndexVec;
|
use rustc_index::IndexVec;
|
||||||
use rustc_middle::bug;
|
use rustc_middle::bug;
|
||||||
|
@ -12,7 +12,7 @@ use rustc_target::abi::{Align, Endian, Size, TagEncoding, VariantIdx, Variants};
|
||||||
use smallvec::smallvec;
|
use smallvec::smallvec;
|
||||||
|
|
||||||
use crate::common::CodegenCx;
|
use crate::common::CodegenCx;
|
||||||
use crate::debuginfo::metadata::enums::{tag_base_type, DiscrResult};
|
use crate::debuginfo::metadata::enums::DiscrResult;
|
||||||
use crate::debuginfo::metadata::type_map::{self, Stub, UniqueTypeId};
|
use crate::debuginfo::metadata::type_map::{self, Stub, UniqueTypeId};
|
||||||
use crate::debuginfo::metadata::{
|
use crate::debuginfo::metadata::{
|
||||||
build_field_di_node, file_metadata, size_and_align_of, type_di_node, unknown_file_metadata,
|
build_field_di_node, file_metadata, size_and_align_of, type_di_node, unknown_file_metadata,
|
||||||
|
@ -190,7 +190,7 @@ pub(super) fn build_enum_type_di_node<'ll, 'tcx>(
|
||||||
let enum_type_and_layout = cx.layout_of(enum_type);
|
let enum_type_and_layout = cx.layout_of(enum_type);
|
||||||
let enum_type_name = compute_debuginfo_type_name(cx.tcx, enum_type, false);
|
let enum_type_name = compute_debuginfo_type_name(cx.tcx, enum_type, false);
|
||||||
|
|
||||||
assert!(!wants_c_like_enum_debuginfo(enum_type_and_layout));
|
assert!(!wants_c_like_enum_debuginfo(cx.tcx, enum_type_and_layout));
|
||||||
|
|
||||||
type_map::build_type_with_children(
|
type_map::build_type_with_children(
|
||||||
cx,
|
cx,
|
||||||
|
@ -265,7 +265,7 @@ pub(super) fn build_coroutine_di_node<'ll, 'tcx>(
|
||||||
let coroutine_type_and_layout = cx.layout_of(coroutine_type);
|
let coroutine_type_and_layout = cx.layout_of(coroutine_type);
|
||||||
let coroutine_type_name = compute_debuginfo_type_name(cx.tcx, coroutine_type, false);
|
let coroutine_type_name = compute_debuginfo_type_name(cx.tcx, coroutine_type, false);
|
||||||
|
|
||||||
assert!(!wants_c_like_enum_debuginfo(coroutine_type_and_layout));
|
assert!(!wants_c_like_enum_debuginfo(cx.tcx, coroutine_type_and_layout));
|
||||||
|
|
||||||
type_map::build_type_with_children(
|
type_map::build_type_with_children(
|
||||||
cx,
|
cx,
|
||||||
|
@ -381,7 +381,7 @@ fn build_union_fields_for_enum<'ll, 'tcx>(
|
||||||
tag_field: usize,
|
tag_field: usize,
|
||||||
untagged_variant_index: Option<VariantIdx>,
|
untagged_variant_index: Option<VariantIdx>,
|
||||||
) -> SmallVec<&'ll DIType> {
|
) -> SmallVec<&'ll DIType> {
|
||||||
let tag_base_type = super::tag_base_type(cx, enum_type_and_layout);
|
let tag_base_type = tag_base_type(cx.tcx, enum_type_and_layout);
|
||||||
|
|
||||||
let variant_names_type_di_node = build_variant_names_type_di_node(
|
let variant_names_type_di_node = build_variant_names_type_di_node(
|
||||||
cx,
|
cx,
|
||||||
|
@ -676,7 +676,7 @@ fn build_union_fields_for_direct_tag_coroutine<'ll, 'tcx>(
|
||||||
let variant_range = coroutine_args.variant_range(coroutine_def_id, cx.tcx);
|
let variant_range = coroutine_args.variant_range(coroutine_def_id, cx.tcx);
|
||||||
let variant_count = (variant_range.start.as_u32()..variant_range.end.as_u32()).len();
|
let variant_count = (variant_range.start.as_u32()..variant_range.end.as_u32()).len();
|
||||||
|
|
||||||
let tag_base_type = tag_base_type(cx, coroutine_type_and_layout);
|
let tag_base_type = tag_base_type(cx.tcx, coroutine_type_and_layout);
|
||||||
|
|
||||||
let variant_names_type_di_node = build_variant_names_type_di_node(
|
let variant_names_type_di_node = build_variant_names_type_di_node(
|
||||||
cx,
|
cx,
|
||||||
|
@ -803,7 +803,7 @@ fn build_union_fields_for_direct_tag_enum_or_coroutine<'ll, 'tcx>(
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
cx.size_and_align_of(enum_type_and_layout.field(cx, tag_field).ty),
|
cx.size_and_align_of(enum_type_and_layout.field(cx, tag_field).ty),
|
||||||
cx.size_and_align_of(super::tag_base_type(cx, enum_type_and_layout))
|
cx.size_and_align_of(self::tag_base_type(cx.tcx, enum_type_and_layout))
|
||||||
);
|
);
|
||||||
|
|
||||||
// ... and a field for the tag. If the tag is 128 bits wide, this will actually
|
// ... and a field for the tag. If the tag is 128 bits wide, this will actually
|
||||||
|
|
|
@ -1,17 +1,15 @@
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
use rustc_codegen_ssa::debuginfo::type_names::{compute_debuginfo_type_name, cpp_like_debuginfo};
|
use rustc_codegen_ssa::debuginfo::type_names::{compute_debuginfo_type_name, cpp_like_debuginfo};
|
||||||
use rustc_codegen_ssa::debuginfo::wants_c_like_enum_debuginfo;
|
use rustc_codegen_ssa::debuginfo::{tag_base_type, wants_c_like_enum_debuginfo};
|
||||||
use rustc_hir::def::CtorKind;
|
use rustc_hir::def::CtorKind;
|
||||||
use rustc_index::IndexSlice;
|
use rustc_index::IndexSlice;
|
||||||
use rustc_middle::bug;
|
use rustc_middle::bug;
|
||||||
use rustc_middle::mir::CoroutineLayout;
|
use rustc_middle::mir::CoroutineLayout;
|
||||||
use rustc_middle::ty::layout::{IntegerExt, LayoutOf, PrimitiveExt, TyAndLayout};
|
use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
|
||||||
use rustc_middle::ty::{self, AdtDef, CoroutineArgs, CoroutineArgsExt, Ty, VariantDef};
|
use rustc_middle::ty::{self, AdtDef, CoroutineArgs, CoroutineArgsExt, Ty, VariantDef};
|
||||||
use rustc_span::Symbol;
|
use rustc_span::Symbol;
|
||||||
use rustc_target::abi::{
|
use rustc_target::abi::{FieldIdx, TagEncoding, VariantIdx, Variants};
|
||||||
FieldIdx, HasDataLayout, Integer, Primitive, TagEncoding, VariantIdx, Variants,
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::type_map::{DINodeCreationResult, UniqueTypeId};
|
use super::type_map::{DINodeCreationResult, UniqueTypeId};
|
||||||
use super::{size_and_align_of, SmallVec};
|
use super::{size_and_align_of, SmallVec};
|
||||||
|
@ -39,7 +37,7 @@ pub(super) fn build_enum_type_di_node<'ll, 'tcx>(
|
||||||
|
|
||||||
let enum_type_and_layout = cx.layout_of(enum_type);
|
let enum_type_and_layout = cx.layout_of(enum_type);
|
||||||
|
|
||||||
if wants_c_like_enum_debuginfo(enum_type_and_layout) {
|
if wants_c_like_enum_debuginfo(cx.tcx, enum_type_and_layout) {
|
||||||
return build_c_style_enum_di_node(cx, enum_adt_def, enum_type_and_layout);
|
return build_c_style_enum_di_node(cx, enum_adt_def, enum_type_and_layout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,7 +72,7 @@ fn build_c_style_enum_di_node<'ll, 'tcx>(
|
||||||
di_node: build_enumeration_type_di_node(
|
di_node: build_enumeration_type_di_node(
|
||||||
cx,
|
cx,
|
||||||
&compute_debuginfo_type_name(cx.tcx, enum_type_and_layout.ty, false),
|
&compute_debuginfo_type_name(cx.tcx, enum_type_and_layout.ty, false),
|
||||||
tag_base_type(cx, enum_type_and_layout),
|
tag_base_type(cx.tcx, enum_type_and_layout),
|
||||||
enum_adt_def.discriminants(cx.tcx).map(|(variant_index, discr)| {
|
enum_adt_def.discriminants(cx.tcx).map(|(variant_index, discr)| {
|
||||||
let name = Cow::from(enum_adt_def.variant(variant_index).name.as_str());
|
let name = Cow::from(enum_adt_def.variant(variant_index).name.as_str());
|
||||||
(name, discr.val)
|
(name, discr.val)
|
||||||
|
@ -85,48 +83,6 @@ fn build_c_style_enum_di_node<'ll, 'tcx>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extract the type with which we want to describe the tag of the given enum or coroutine.
|
|
||||||
fn tag_base_type<'ll, 'tcx>(
|
|
||||||
cx: &CodegenCx<'ll, 'tcx>,
|
|
||||||
enum_type_and_layout: TyAndLayout<'tcx>,
|
|
||||||
) -> Ty<'tcx> {
|
|
||||||
assert!(match enum_type_and_layout.ty.kind() {
|
|
||||||
ty::Coroutine(..) => true,
|
|
||||||
ty::Adt(adt_def, _) => adt_def.is_enum(),
|
|
||||||
_ => false,
|
|
||||||
});
|
|
||||||
|
|
||||||
match enum_type_and_layout.layout.variants() {
|
|
||||||
// A single-variant enum has no discriminant.
|
|
||||||
Variants::Single { .. } => {
|
|
||||||
bug!("tag_base_type() called for enum without tag: {:?}", enum_type_and_layout)
|
|
||||||
}
|
|
||||||
|
|
||||||
Variants::Multiple { tag_encoding: TagEncoding::Niche { .. }, tag, .. } => {
|
|
||||||
// Niche tags are always normalized to unsized integers of the correct size.
|
|
||||||
match tag.primitive() {
|
|
||||||
Primitive::Int(t, _) => t,
|
|
||||||
Primitive::Float(f) => Integer::from_size(f.size()).unwrap(),
|
|
||||||
// FIXME(erikdesjardins): handle non-default addrspace ptr sizes
|
|
||||||
Primitive::Pointer(_) => {
|
|
||||||
// If the niche is the NULL value of a reference, then `discr_enum_ty` will be
|
|
||||||
// a RawPtr. CodeView doesn't know what to do with enums whose base type is a
|
|
||||||
// pointer so we fix this up to just be `usize`.
|
|
||||||
// DWARF might be able to deal with this but with an integer type we are on
|
|
||||||
// the safe side there too.
|
|
||||||
cx.data_layout().ptr_sized_integer()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.to_ty(cx.tcx, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
Variants::Multiple { tag_encoding: TagEncoding::Direct, tag, .. } => {
|
|
||||||
// Direct tags preserve the sign.
|
|
||||||
tag.primitive().to_ty(cx.tcx)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Build a DW_TAG_enumeration_type debuginfo node, with the given base type and variants.
|
/// Build a DW_TAG_enumeration_type debuginfo node, with the given base type and variants.
|
||||||
/// This is a helper function and does not register anything in the type map by itself.
|
/// This is a helper function and does not register anything in the type map by itself.
|
||||||
///
|
///
|
||||||
|
@ -301,7 +257,7 @@ fn build_enum_variant_struct_type_di_node<'ll, 'tcx>(
|
||||||
/// ---> DW_TAG_structure_type (type of variant 3)
|
/// ---> DW_TAG_structure_type (type of variant 3)
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
pub fn build_coroutine_variant_struct_type_di_node<'ll, 'tcx>(
|
fn build_coroutine_variant_struct_type_di_node<'ll, 'tcx>(
|
||||||
cx: &CodegenCx<'ll, 'tcx>,
|
cx: &CodegenCx<'ll, 'tcx>,
|
||||||
variant_index: VariantIdx,
|
variant_index: VariantIdx,
|
||||||
coroutine_type_and_layout: TyAndLayout<'tcx>,
|
coroutine_type_and_layout: TyAndLayout<'tcx>,
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue