mirror of
https://git.proxmox.com/git/rustc
synced 2025-12-07 09:00:49 +00:00
New upstream version 1.67.1+dfsg1
This commit is contained in:
parent
2b03887add
commit
487cf647e7
@ -1,11 +1,5 @@
|
||||
|
||||
[source.crates-io]
|
||||
replace-with = "vendored-sources"
|
||||
|
||||
[source."https://github.com/bjorn3/rust-ar.git"]
|
||||
git = "https://github.com/bjorn3/rust-ar.git"
|
||||
branch = "do_not_remove_cg_clif_ranlib"
|
||||
replace-with = "vendored-sources"
|
||||
|
||||
[source.vendored-sources]
|
||||
directory = "vendor"
|
||||
|
||||
50
COPYRIGHT
50
COPYRIGHT
@ -339,3 +339,53 @@ their own copyright notices and license terms:
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
OF SUCH DAMAGE.
|
||||
|
||||
* Portions of internationalization code use code or data from Unicode, which
|
||||
carry the following license:
|
||||
|
||||
UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE
|
||||
|
||||
See Terms of Use <https://www.unicode.org/copyright.html>
|
||||
for definitions of Unicode Inc.’s Data Files and Software.
|
||||
|
||||
NOTICE TO USER: Carefully read the following legal agreement.
|
||||
BY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING UNICODE INC.'S
|
||||
DATA FILES ("DATA FILES"), AND/OR SOFTWARE ("SOFTWARE"),
|
||||
YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE
|
||||
TERMS AND CONDITIONS OF THIS AGREEMENT.
|
||||
IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE
|
||||
THE DATA FILES OR SOFTWARE.
|
||||
|
||||
COPYRIGHT AND PERMISSION NOTICE
|
||||
|
||||
Copyright © 1991-2022 Unicode, Inc. All rights reserved.
|
||||
Distributed under the Terms of Use in https://www.unicode.org/copyright.html.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Unicode data files and any associated documentation
|
||||
(the "Data Files") or Unicode software and any associated documentation
|
||||
(the "Software") to deal in the Data Files or Software
|
||||
without restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, and/or sell copies of
|
||||
the Data Files or Software, and to permit persons to whom the Data Files
|
||||
or Software are furnished to do so, provided that either
|
||||
(a) this copyright and permission notice appear with all copies
|
||||
of the Data Files or Software, or
|
||||
(b) this copyright and permission notice appear in associated
|
||||
Documentation.
|
||||
|
||||
THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF
|
||||
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT OF THIRD PARTY RIGHTS.
|
||||
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS
|
||||
NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL
|
||||
DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
PERFORMANCE OF THE DATA FILES OR SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of a copyright holder
|
||||
shall not be used in advertising or otherwise to promote the sale,
|
||||
use or other dealings in these Data Files or Software without prior
|
||||
written authorization of the copyright holder.
|
||||
|
||||
901
Cargo.lock
generated
901
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -11,6 +11,7 @@ members = [
|
||||
"src/tools/error_index_generator",
|
||||
"src/tools/linkchecker",
|
||||
"src/tools/lint-docs",
|
||||
"src/tools/miropt-test-tools",
|
||||
"src/tools/rustbook",
|
||||
"src/tools/unstable-book-gen",
|
||||
"src/tools/tidy",
|
||||
@ -38,6 +39,8 @@ members = [
|
||||
"src/tools/bump-stage0",
|
||||
"src/tools/replace-version-placeholder",
|
||||
"src/tools/lld-wrapper",
|
||||
"src/tools/collect-license-metadata",
|
||||
"src/tools/generate-copyright",
|
||||
]
|
||||
|
||||
exclude = [
|
||||
|
||||
117
RELEASES.md
117
RELEASES.md
@ -1,3 +1,118 @@
|
||||
Version 1.67.1 (2023-02-09)
|
||||
===========================
|
||||
|
||||
- [Fix interoperability with thin archives.](https://github.com/rust-lang/rust/pull/107360)
|
||||
- [Fix an internal error in the compiler build process.](https://github.com/rust-lang/rust/pull/105624)
|
||||
- [Downgrade `clippy::uninlined_format_args` to pedantic.](https://github.com/rust-lang/rust-clippy/pull/10265)
|
||||
|
||||
Version 1.67.0 (2023-01-26)
|
||||
==========================
|
||||
|
||||
<a id="1.67.0-Language"></a>
|
||||
|
||||
Language
|
||||
--------
|
||||
|
||||
- [Make `Sized` predicates coinductive, allowing cycles.](https://github.com/rust-lang/rust/pull/100386/)
|
||||
- [`#[must_use]` annotations on `async fn` also affect the `Future::Output`.](https://github.com/rust-lang/rust/pull/100633/)
|
||||
- [Elaborate supertrait obligations when deducing closure signatures.](https://github.com/rust-lang/rust/pull/101834/)
|
||||
- [Invalid literals are no longer an error under `cfg(FALSE)`.](https://github.com/rust-lang/rust/pull/102944/)
|
||||
- [Unreserve braced enum variants in value namespace.](https://github.com/rust-lang/rust/pull/103578/)
|
||||
|
||||
<a id="1.67.0-Compiler"></a>
|
||||
|
||||
Compiler
|
||||
--------
|
||||
|
||||
- [Enable varargs support for calling conventions other than `C` or `cdecl`.](https://github.com/rust-lang/rust/pull/97971/)
|
||||
- [Add new MIR constant propagation based on dataflow analysis.](https://github.com/rust-lang/rust/pull/101168/)
|
||||
- [Optimize field ordering by grouping m\*2^n-sized fields with equivalently aligned ones.](https://github.com/rust-lang/rust/pull/102750/)
|
||||
- [Stabilize native library modifier `verbatim`.](https://github.com/rust-lang/rust/pull/104360/)
|
||||
|
||||
Added and removed targets:
|
||||
|
||||
- [Add a tier 3 target for PowerPC on AIX](https://github.com/rust-lang/rust/pull/102293/), `powerpc64-ibm-aix`.
|
||||
- [Add a tier 3 target for the Sony PlayStation 1](https://github.com/rust-lang/rust/pull/102689/), `mipsel-sony-psx`.
|
||||
- [Add tier 3 `no_std` targets for the QNX Neutrino RTOS](https://github.com/rust-lang/rust/pull/102701/),
|
||||
`aarch64-unknown-nto-qnx710` and `x86_64-pc-nto-qnx710`.
|
||||
- [Remove tier 3 `linuxkernel` targets](https://github.com/rust-lang/rust/pull/104015/) (not used by the actual kernel).
|
||||
|
||||
Refer to Rust's [platform support page][platform-support-doc]
|
||||
for more information on Rust's tiered platform support.
|
||||
|
||||
<a id="1.67.0-Libraries"></a>
|
||||
|
||||
Libraries
|
||||
---------
|
||||
|
||||
- [Merge `crossbeam-channel` into `std::sync::mpsc`.](https://github.com/rust-lang/rust/pull/93563/)
|
||||
- [Fix inconsistent rounding of 0.5 when formatted to 0 decimal places.](https://github.com/rust-lang/rust/pull/102935/)
|
||||
- [Derive `Eq` and `Hash` for `ControlFlow`.](https://github.com/rust-lang/rust/pull/103084/)
|
||||
- [Don't build `compiler_builtins` with `-C panic=abort`.](https://github.com/rust-lang/rust/pull/103786/)
|
||||
|
||||
<a id="1.67.0-Stabilized-APIs"></a>
|
||||
|
||||
Stabilized APIs
|
||||
---------------
|
||||
|
||||
- [`{integer}::checked_ilog`](https://doc.rust-lang.org/stable/std/primitive.i32.html#method.checked_ilog)
|
||||
- [`{integer}::checked_ilog2`](https://doc.rust-lang.org/stable/std/primitive.i32.html#method.checked_ilog2)
|
||||
- [`{integer}::checked_ilog10`](https://doc.rust-lang.org/stable/std/primitive.i32.html#method.checked_ilog10)
|
||||
- [`{integer}::ilog`](https://doc.rust-lang.org/stable/std/primitive.i32.html#method.ilog)
|
||||
- [`{integer}::ilog2`](https://doc.rust-lang.org/stable/std/primitive.i32.html#method.ilog2)
|
||||
- [`{integer}::ilog10`](https://doc.rust-lang.org/stable/std/primitive.i32.html#method.ilog10)
|
||||
- [`NonZeroU*::ilog2`](https://doc.rust-lang.org/stable/std/num/struct.NonZeroU32.html#method.ilog2)
|
||||
- [`NonZeroU*::ilog10`](https://doc.rust-lang.org/stable/std/num/struct.NonZeroU32.html#method.ilog10)
|
||||
- [`NonZero*::BITS`](https://doc.rust-lang.org/stable/std/num/struct.NonZeroU32.html#associatedconstant.BITS)
|
||||
|
||||
These APIs are now stable in const contexts:
|
||||
|
||||
- [`char::from_u32`](https://doc.rust-lang.org/stable/std/primitive.char.html#method.from_u32)
|
||||
- [`char::from_digit`](https://doc.rust-lang.org/stable/std/primitive.char.html#method.from_digit)
|
||||
- [`char::to_digit`](https://doc.rust-lang.org/stable/std/primitive.char.html#method.to_digit)
|
||||
- [`core::char::from_u32`](https://doc.rust-lang.org/stable/core/char/fn.from_u32.html)
|
||||
- [`core::char::from_digit`](https://doc.rust-lang.org/stable/core/char/fn.from_digit.html)
|
||||
|
||||
<a id="1.67.0-Compatibility-Notes"></a>
|
||||
|
||||
Compatibility Notes
|
||||
-------------------
|
||||
|
||||
- [The layout of `repr(Rust)` types now groups m\*2^n-sized fields with
|
||||
equivalently aligned ones.](https://github.com/rust-lang/rust/pull/102750/)
|
||||
This is intended to be an optimization, but it is also known to increase type
|
||||
sizes in a few cases for the placement of enum tags. As a reminder, the layout
|
||||
of `repr(Rust)` types is an implementation detail, subject to change.
|
||||
- [0.5 now rounds to 0 when formatted to 0 decimal places.](https://github.com/rust-lang/rust/pull/102935/)
|
||||
This makes it consistent with the rest of floating point formatting that
|
||||
rounds ties toward even digits.
|
||||
- [Chains of `&&` and `||` will now drop temporaries from their sub-expressions in
|
||||
evaluation order, left-to-right.](https://github.com/rust-lang/rust/pull/103293/)
|
||||
Previously, it was "twisted" such that the _first_ expression dropped its
|
||||
temporaries _last_, after all of the other expressions dropped in order.
|
||||
- [Underscore suffixes on string literals are now a hard error.](https://github.com/rust-lang/rust/pull/103914/)
|
||||
This has been a future-compatibility warning since 1.20.0.
|
||||
- [Stop passing `-export-dynamic` to `wasm-ld`.](https://github.com/rust-lang/rust/pull/105405/)
|
||||
- [`main` is now mangled as `__main_void` on `wasm32-wasi`.](https://github.com/rust-lang/rust/pull/105468/)
|
||||
- [Cargo now emits an error if there are multiple registries in the configuration
|
||||
with the same index URL.](https://github.com/rust-lang/cargo/pull/10592)
|
||||
|
||||
<a id="1.67.0-Internal-Changes"></a>
|
||||
|
||||
Internal Changes
|
||||
----------------
|
||||
|
||||
These changes do not affect any public interfaces of Rust, but they represent
|
||||
significant improvements to the performance or internals of rustc and related
|
||||
tools.
|
||||
|
||||
- [Rewrite LLVM's archive writer in Rust.](https://github.com/rust-lang/rust/pull/97485/)
|
||||
|
||||
Version 1.66.1 (2023-01-10)
|
||||
===========================
|
||||
|
||||
- Added validation of SSH host keys for git URLs in Cargo ([CVE-2022-46176](https://www.cve.org/CVERecord?id=CVE-2022-46176))
|
||||
|
||||
Version 1.66.0 (2022-12-15)
|
||||
==========================
|
||||
|
||||
@ -16,7 +131,7 @@ Language
|
||||
- [Change constant evaluation errors from a deny-by-default lint to a hard error](https://github.com/rust-lang/rust/pull/102091/)
|
||||
- [Trigger `must_use` on `impl Trait` for supertraits](https://github.com/rust-lang/rust/pull/102287/)
|
||||
This makes `impl ExactSizeIterator` respect the existing `#[must_use]` annotation on `Iterator`.
|
||||
- [Allow `..X` and `..=X` in patterns](https://github.com/rust-lang/rust/pull/102275/)
|
||||
- [Allow `..=X` in patterns](https://github.com/rust-lang/rust/pull/102275/)
|
||||
- [Uplift `clippy::for_loops_over_fallibles` lint into rustc](https://github.com/rust-lang/rust/pull/99696/)
|
||||
- [Stabilize `sym` operands in inline assembly](https://github.com/rust-lang/rust/pull/103168/)
|
||||
- [Update to Unicode 15](https://github.com/rust-lang/rust/pull/101912/)
|
||||
|
||||
24
compiler/rustc_abi/Cargo.toml
Normal file
24
compiler/rustc_abi/Cargo.toml
Normal file
@ -0,0 +1,24 @@
|
||||
[package]
|
||||
name = "rustc_abi"
|
||||
version = "0.0.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
bitflags = "1.2.1"
|
||||
tracing = "0.1"
|
||||
rand = { version = "0.8.4", default-features = false, optional = true }
|
||||
rand_xoshiro = { version = "0.6.0", optional = true }
|
||||
rustc_data_structures = { path = "../rustc_data_structures", optional = true }
|
||||
rustc_index = { path = "../rustc_index", default-features = false }
|
||||
rustc_macros = { path = "../rustc_macros", optional = true }
|
||||
rustc_serialize = { path = "../rustc_serialize", optional = true }
|
||||
|
||||
[features]
|
||||
default = ["nightly", "randomize"]
|
||||
randomize = ["rand", "rand_xoshiro"]
|
||||
nightly = [
|
||||
"rustc_data_structures",
|
||||
"rustc_index/nightly",
|
||||
"rustc_macros",
|
||||
"rustc_serialize",
|
||||
]
|
||||
945
compiler/rustc_abi/src/layout.rs
Normal file
945
compiler/rustc_abi/src/layout.rs
Normal file
@ -0,0 +1,945 @@
|
||||
use super::*;
|
||||
use std::{
|
||||
borrow::Borrow,
|
||||
cmp,
|
||||
fmt::Debug,
|
||||
iter,
|
||||
ops::{Bound, Deref},
|
||||
};
|
||||
|
||||
#[cfg(feature = "randomize")]
|
||||
use rand::{seq::SliceRandom, SeedableRng};
|
||||
#[cfg(feature = "randomize")]
|
||||
use rand_xoshiro::Xoshiro128StarStar;
|
||||
|
||||
use tracing::debug;
|
||||
|
||||
// Invert a bijective mapping, i.e. `invert(map)[y] = x` if `map[x] = y`.
|
||||
// This is used to go between `memory_index` (source field order to memory order)
|
||||
// and `inverse_memory_index` (memory order to source field order).
|
||||
// See also `FieldsShape::Arbitrary::memory_index` for more details.
|
||||
// FIXME(eddyb) build a better abstraction for permutations, if possible.
|
||||
fn invert_mapping(map: &[u32]) -> Vec<u32> {
|
||||
let mut inverse = vec![0; map.len()];
|
||||
for i in 0..map.len() {
|
||||
inverse[map[i] as usize] = i as u32;
|
||||
}
|
||||
inverse
|
||||
}
|
||||
|
||||
pub trait LayoutCalculator {
|
||||
type TargetDataLayoutRef: Borrow<TargetDataLayout>;
|
||||
|
||||
fn delay_bug(&self, txt: &str);
|
||||
fn current_data_layout(&self) -> Self::TargetDataLayoutRef;
|
||||
|
||||
fn scalar_pair<V: Idx>(&self, a: Scalar, b: Scalar) -> LayoutS<V> {
|
||||
let dl = self.current_data_layout();
|
||||
let dl = dl.borrow();
|
||||
let b_align = b.align(dl);
|
||||
let align = a.align(dl).max(b_align).max(dl.aggregate_align);
|
||||
let b_offset = a.size(dl).align_to(b_align.abi);
|
||||
let size = (b_offset + b.size(dl)).align_to(align.abi);
|
||||
|
||||
// HACK(nox): We iter on `b` and then `a` because `max_by_key`
|
||||
// returns the last maximum.
|
||||
let largest_niche = Niche::from_scalar(dl, b_offset, b)
|
||||
.into_iter()
|
||||
.chain(Niche::from_scalar(dl, Size::ZERO, a))
|
||||
.max_by_key(|niche| niche.available(dl));
|
||||
|
||||
LayoutS {
|
||||
variants: Variants::Single { index: V::new(0) },
|
||||
fields: FieldsShape::Arbitrary {
|
||||
offsets: vec![Size::ZERO, b_offset],
|
||||
memory_index: vec![0, 1],
|
||||
},
|
||||
abi: Abi::ScalarPair(a, b),
|
||||
largest_niche,
|
||||
align,
|
||||
size,
|
||||
}
|
||||
}
|
||||
|
||||
fn univariant<'a, V: Idx, F: Deref<Target = &'a LayoutS<V>> + Debug>(
|
||||
&self,
|
||||
dl: &TargetDataLayout,
|
||||
fields: &[F],
|
||||
repr: &ReprOptions,
|
||||
kind: StructKind,
|
||||
) -> Option<LayoutS<V>> {
|
||||
let pack = repr.pack;
|
||||
let mut align = if pack.is_some() { dl.i8_align } else { dl.aggregate_align };
|
||||
let mut inverse_memory_index: Vec<u32> = (0..fields.len() as u32).collect();
|
||||
let optimize = !repr.inhibit_struct_field_reordering_opt();
|
||||
if optimize {
|
||||
let end =
|
||||
if let StructKind::MaybeUnsized = kind { fields.len() - 1 } else { fields.len() };
|
||||
let optimizing = &mut inverse_memory_index[..end];
|
||||
let effective_field_align = |f: &F| {
|
||||
if let Some(pack) = pack {
|
||||
// return the packed alignment in bytes
|
||||
f.align.abi.min(pack).bytes()
|
||||
} else {
|
||||
// returns log2(effective-align).
|
||||
// This is ok since `pack` applies to all fields equally.
|
||||
// The calculation assumes that size is an integer multiple of align, except for ZSTs.
|
||||
//
|
||||
// group [u8; 4] with align-4 or [u8; 6] with align-2 fields
|
||||
f.align.abi.bytes().max(f.size.bytes()).trailing_zeros() as u64
|
||||
}
|
||||
};
|
||||
|
||||
// If `-Z randomize-layout` was enabled for the type definition we can shuffle
|
||||
// the field ordering to try and catch some code making assumptions about layouts
|
||||
// we don't guarantee
|
||||
if repr.can_randomize_type_layout() && cfg!(feature = "randomize") {
|
||||
#[cfg(feature = "randomize")]
|
||||
{
|
||||
// `ReprOptions.layout_seed` is a deterministic seed that we can use to
|
||||
// randomize field ordering with
|
||||
let mut rng = Xoshiro128StarStar::seed_from_u64(repr.field_shuffle_seed);
|
||||
|
||||
// Shuffle the ordering of the fields
|
||||
optimizing.shuffle(&mut rng);
|
||||
}
|
||||
// Otherwise we just leave things alone and actually optimize the type's fields
|
||||
} else {
|
||||
match kind {
|
||||
StructKind::AlwaysSized | StructKind::MaybeUnsized => {
|
||||
optimizing.sort_by_key(|&x| {
|
||||
// Place ZSTs first to avoid "interesting offsets",
|
||||
// especially with only one or two non-ZST fields.
|
||||
// Then place largest alignments first, largest niches within an alignment group last
|
||||
let f = &fields[x as usize];
|
||||
let niche_size = f.largest_niche.map_or(0, |n| n.available(dl));
|
||||
(!f.is_zst(), cmp::Reverse(effective_field_align(f)), niche_size)
|
||||
});
|
||||
}
|
||||
|
||||
StructKind::Prefixed(..) => {
|
||||
// Sort in ascending alignment so that the layout stays optimal
|
||||
// regardless of the prefix.
|
||||
// And put the largest niche in an alignment group at the end
|
||||
// so it can be used as discriminant in jagged enums
|
||||
optimizing.sort_by_key(|&x| {
|
||||
let f = &fields[x as usize];
|
||||
let niche_size = f.largest_niche.map_or(0, |n| n.available(dl));
|
||||
(effective_field_align(f), niche_size)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME(Kixiron): We can always shuffle fields within a given alignment class
|
||||
// regardless of the status of `-Z randomize-layout`
|
||||
}
|
||||
}
|
||||
// inverse_memory_index holds field indices by increasing memory offset.
|
||||
// That is, if field 5 has offset 0, the first element of inverse_memory_index is 5.
|
||||
// We now write field offsets to the corresponding offset slot;
|
||||
// field 5 with offset 0 puts 0 in offsets[5].
|
||||
// At the bottom of this function, we invert `inverse_memory_index` to
|
||||
// produce `memory_index` (see `invert_mapping`).
|
||||
let mut sized = true;
|
||||
let mut offsets = vec![Size::ZERO; fields.len()];
|
||||
let mut offset = Size::ZERO;
|
||||
let mut largest_niche = None;
|
||||
let mut largest_niche_available = 0;
|
||||
if let StructKind::Prefixed(prefix_size, prefix_align) = kind {
|
||||
let prefix_align =
|
||||
if let Some(pack) = pack { prefix_align.min(pack) } else { prefix_align };
|
||||
align = align.max(AbiAndPrefAlign::new(prefix_align));
|
||||
offset = prefix_size.align_to(prefix_align);
|
||||
}
|
||||
for &i in &inverse_memory_index {
|
||||
let field = &fields[i as usize];
|
||||
if !sized {
|
||||
self.delay_bug(&format!(
|
||||
"univariant: field #{} comes after unsized field",
|
||||
offsets.len(),
|
||||
));
|
||||
}
|
||||
|
||||
if field.is_unsized() {
|
||||
sized = false;
|
||||
}
|
||||
|
||||
// Invariant: offset < dl.obj_size_bound() <= 1<<61
|
||||
let field_align = if let Some(pack) = pack {
|
||||
field.align.min(AbiAndPrefAlign::new(pack))
|
||||
} else {
|
||||
field.align
|
||||
};
|
||||
offset = offset.align_to(field_align.abi);
|
||||
align = align.max(field_align);
|
||||
|
||||
debug!("univariant offset: {:?} field: {:#?}", offset, field);
|
||||
offsets[i as usize] = offset;
|
||||
|
||||
if let Some(mut niche) = field.largest_niche {
|
||||
let available = niche.available(dl);
|
||||
if available > largest_niche_available {
|
||||
largest_niche_available = available;
|
||||
niche.offset += offset;
|
||||
largest_niche = Some(niche);
|
||||
}
|
||||
}
|
||||
|
||||
offset = offset.checked_add(field.size, dl)?;
|
||||
}
|
||||
if let Some(repr_align) = repr.align {
|
||||
align = align.max(AbiAndPrefAlign::new(repr_align));
|
||||
}
|
||||
debug!("univariant min_size: {:?}", offset);
|
||||
let min_size = offset;
|
||||
// As stated above, inverse_memory_index holds field indices by increasing offset.
|
||||
// This makes it an already-sorted view of the offsets vec.
|
||||
// To invert it, consider:
|
||||
// If field 5 has offset 0, offsets[0] is 5, and memory_index[5] should be 0.
|
||||
// Field 5 would be the first element, so memory_index is i:
|
||||
// Note: if we didn't optimize, it's already right.
|
||||
let memory_index =
|
||||
if optimize { invert_mapping(&inverse_memory_index) } else { inverse_memory_index };
|
||||
let size = min_size.align_to(align.abi);
|
||||
let mut abi = Abi::Aggregate { sized };
|
||||
// Unpack newtype ABIs and find scalar pairs.
|
||||
if sized && size.bytes() > 0 {
|
||||
// All other fields must be ZSTs.
|
||||
let mut non_zst_fields = fields.iter().enumerate().filter(|&(_, f)| !f.is_zst());
|
||||
|
||||
match (non_zst_fields.next(), non_zst_fields.next(), non_zst_fields.next()) {
|
||||
// We have exactly one non-ZST field.
|
||||
(Some((i, field)), None, None) => {
|
||||
// Field fills the struct and it has a scalar or scalar pair ABI.
|
||||
if offsets[i].bytes() == 0 && align.abi == field.align.abi && size == field.size
|
||||
{
|
||||
match field.abi {
|
||||
// For plain scalars, or vectors of them, we can't unpack
|
||||
// newtypes for `#[repr(C)]`, as that affects C ABIs.
|
||||
Abi::Scalar(_) | Abi::Vector { .. } if optimize => {
|
||||
abi = field.abi;
|
||||
}
|
||||
// But scalar pairs are Rust-specific and get
|
||||
// treated as aggregates by C ABIs anyway.
|
||||
Abi::ScalarPair(..) => {
|
||||
abi = field.abi;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Two non-ZST fields, and they're both scalars.
|
||||
(Some((i, a)), Some((j, b)), None) => {
|
||||
match (a.abi, b.abi) {
|
||||
(Abi::Scalar(a), Abi::Scalar(b)) => {
|
||||
// Order by the memory placement, not source order.
|
||||
let ((i, a), (j, b)) = if offsets[i] < offsets[j] {
|
||||
((i, a), (j, b))
|
||||
} else {
|
||||
((j, b), (i, a))
|
||||
};
|
||||
let pair = self.scalar_pair::<V>(a, b);
|
||||
let pair_offsets = match pair.fields {
|
||||
FieldsShape::Arbitrary { ref offsets, ref memory_index } => {
|
||||
assert_eq!(memory_index, &[0, 1]);
|
||||
offsets
|
||||
}
|
||||
_ => panic!(),
|
||||
};
|
||||
if offsets[i] == pair_offsets[0]
|
||||
&& offsets[j] == pair_offsets[1]
|
||||
&& align == pair.align
|
||||
&& size == pair.size
|
||||
{
|
||||
// We can use `ScalarPair` only when it matches our
|
||||
// already computed layout (including `#[repr(C)]`).
|
||||
abi = pair.abi;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
if fields.iter().any(|f| f.abi.is_uninhabited()) {
|
||||
abi = Abi::Uninhabited;
|
||||
}
|
||||
Some(LayoutS {
|
||||
variants: Variants::Single { index: V::new(0) },
|
||||
fields: FieldsShape::Arbitrary { offsets, memory_index },
|
||||
abi,
|
||||
largest_niche,
|
||||
align,
|
||||
size,
|
||||
})
|
||||
}
|
||||
|
||||
fn layout_of_never_type<V: Idx>(&self) -> LayoutS<V> {
|
||||
let dl = self.current_data_layout();
|
||||
let dl = dl.borrow();
|
||||
LayoutS {
|
||||
variants: Variants::Single { index: V::new(0) },
|
||||
fields: FieldsShape::Primitive,
|
||||
abi: Abi::Uninhabited,
|
||||
largest_niche: None,
|
||||
align: dl.i8_align,
|
||||
size: Size::ZERO,
|
||||
}
|
||||
}
|
||||
|
||||
fn layout_of_struct_or_enum<'a, V: Idx, F: Deref<Target = &'a LayoutS<V>> + Debug>(
|
||||
&self,
|
||||
repr: &ReprOptions,
|
||||
variants: &IndexVec<V, Vec<F>>,
|
||||
is_enum: bool,
|
||||
is_unsafe_cell: bool,
|
||||
scalar_valid_range: (Bound<u128>, Bound<u128>),
|
||||
discr_range_of_repr: impl Fn(i128, i128) -> (Integer, bool),
|
||||
discriminants: impl Iterator<Item = (V, i128)>,
|
||||
niche_optimize_enum: bool,
|
||||
always_sized: bool,
|
||||
) -> Option<LayoutS<V>> {
|
||||
let dl = self.current_data_layout();
|
||||
let dl = dl.borrow();
|
||||
|
||||
let scalar_unit = |value: Primitive| {
|
||||
let size = value.size(dl);
|
||||
assert!(size.bits() <= 128);
|
||||
Scalar::Initialized { value, valid_range: WrappingRange::full(size) }
|
||||
};
|
||||
|
||||
// A variant is absent if it's uninhabited and only has ZST fields.
|
||||
// Present uninhabited variants only require space for their fields,
|
||||
// but *not* an encoding of the discriminant (e.g., a tag value).
|
||||
// See issue #49298 for more details on the need to leave space
|
||||
// for non-ZST uninhabited data (mostly partial initialization).
|
||||
let absent = |fields: &[F]| {
|
||||
let uninhabited = fields.iter().any(|f| f.abi.is_uninhabited());
|
||||
let is_zst = fields.iter().all(|f| f.is_zst());
|
||||
uninhabited && is_zst
|
||||
};
|
||||
let (present_first, present_second) = {
|
||||
let mut present_variants = variants
|
||||
.iter_enumerated()
|
||||
.filter_map(|(i, v)| if absent(v) { None } else { Some(i) });
|
||||
(present_variants.next(), present_variants.next())
|
||||
};
|
||||
let present_first = match present_first {
|
||||
Some(present_first) => present_first,
|
||||
// Uninhabited because it has no variants, or only absent ones.
|
||||
None if is_enum => {
|
||||
return Some(self.layout_of_never_type());
|
||||
}
|
||||
// If it's a struct, still compute a layout so that we can still compute the
|
||||
// field offsets.
|
||||
None => V::new(0),
|
||||
};
|
||||
|
||||
let is_struct = !is_enum ||
|
||||
// Only one variant is present.
|
||||
(present_second.is_none() &&
|
||||
// Representation optimizations are allowed.
|
||||
!repr.inhibit_enum_layout_opt());
|
||||
if is_struct {
|
||||
// Struct, or univariant enum equivalent to a struct.
|
||||
// (Typechecking will reject discriminant-sizing attrs.)
|
||||
|
||||
let v = present_first;
|
||||
let kind = if is_enum || variants[v].is_empty() {
|
||||
StructKind::AlwaysSized
|
||||
} else {
|
||||
if !always_sized { StructKind::MaybeUnsized } else { StructKind::AlwaysSized }
|
||||
};
|
||||
|
||||
let mut st = self.univariant(dl, &variants[v], repr, kind)?;
|
||||
st.variants = Variants::Single { index: v };
|
||||
|
||||
if is_unsafe_cell {
|
||||
let hide_niches = |scalar: &mut _| match scalar {
|
||||
Scalar::Initialized { value, valid_range } => {
|
||||
*valid_range = WrappingRange::full(value.size(dl))
|
||||
}
|
||||
// Already doesn't have any niches
|
||||
Scalar::Union { .. } => {}
|
||||
};
|
||||
match &mut st.abi {
|
||||
Abi::Uninhabited => {}
|
||||
Abi::Scalar(scalar) => hide_niches(scalar),
|
||||
Abi::ScalarPair(a, b) => {
|
||||
hide_niches(a);
|
||||
hide_niches(b);
|
||||
}
|
||||
Abi::Vector { element, count: _ } => hide_niches(element),
|
||||
Abi::Aggregate { sized: _ } => {}
|
||||
}
|
||||
st.largest_niche = None;
|
||||
return Some(st);
|
||||
}
|
||||
|
||||
let (start, end) = scalar_valid_range;
|
||||
match st.abi {
|
||||
Abi::Scalar(ref mut scalar) | Abi::ScalarPair(ref mut scalar, _) => {
|
||||
// Enlarging validity ranges would result in missed
|
||||
// optimizations, *not* wrongly assuming the inner
|
||||
// value is valid. e.g. unions already enlarge validity ranges,
|
||||
// because the values may be uninitialized.
|
||||
//
|
||||
// Because of that we only check that the start and end
|
||||
// of the range is representable with this scalar type.
|
||||
|
||||
let max_value = scalar.size(dl).unsigned_int_max();
|
||||
if let Bound::Included(start) = start {
|
||||
// FIXME(eddyb) this might be incorrect - it doesn't
|
||||
// account for wrap-around (end < start) ranges.
|
||||
assert!(start <= max_value, "{start} > {max_value}");
|
||||
scalar.valid_range_mut().start = start;
|
||||
}
|
||||
if let Bound::Included(end) = end {
|
||||
// FIXME(eddyb) this might be incorrect - it doesn't
|
||||
// account for wrap-around (end < start) ranges.
|
||||
assert!(end <= max_value, "{end} > {max_value}");
|
||||
scalar.valid_range_mut().end = end;
|
||||
}
|
||||
|
||||
// Update `largest_niche` if we have introduced a larger niche.
|
||||
let niche = Niche::from_scalar(dl, Size::ZERO, *scalar);
|
||||
if let Some(niche) = niche {
|
||||
match st.largest_niche {
|
||||
Some(largest_niche) => {
|
||||
// Replace the existing niche even if they're equal,
|
||||
// because this one is at a lower offset.
|
||||
if largest_niche.available(dl) <= niche.available(dl) {
|
||||
st.largest_niche = Some(niche);
|
||||
}
|
||||
}
|
||||
None => st.largest_niche = Some(niche),
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => assert!(
|
||||
start == Bound::Unbounded && end == Bound::Unbounded,
|
||||
"nonscalar layout for layout_scalar_valid_range type: {:#?}",
|
||||
st,
|
||||
),
|
||||
}
|
||||
|
||||
return Some(st);
|
||||
}
|
||||
|
||||
// At this point, we have handled all unions and
|
||||
// structs. (We have also handled univariant enums
|
||||
// that allow representation optimization.)
|
||||
assert!(is_enum);
|
||||
|
||||
// Until we've decided whether to use the tagged or
|
||||
// niche filling LayoutS, we don't want to intern the
|
||||
// variant layouts, so we can't store them in the
|
||||
// overall LayoutS. Store the overall LayoutS
|
||||
// and the variant LayoutSs here until then.
|
||||
struct TmpLayout<V: Idx> {
|
||||
layout: LayoutS<V>,
|
||||
variants: IndexVec<V, LayoutS<V>>,
|
||||
}
|
||||
|
||||
let calculate_niche_filling_layout = || -> Option<TmpLayout<V>> {
|
||||
if niche_optimize_enum {
|
||||
return None;
|
||||
}
|
||||
|
||||
if variants.len() < 2 {
|
||||
return None;
|
||||
}
|
||||
|
||||
let mut align = dl.aggregate_align;
|
||||
let mut variant_layouts = variants
|
||||
.iter_enumerated()
|
||||
.map(|(j, v)| {
|
||||
let mut st = self.univariant(dl, v, repr, StructKind::AlwaysSized)?;
|
||||
st.variants = Variants::Single { index: j };
|
||||
|
||||
align = align.max(st.align);
|
||||
|
||||
Some(st)
|
||||
})
|
||||
.collect::<Option<IndexVec<V, _>>>()?;
|
||||
|
||||
let largest_variant_index = variant_layouts
|
||||
.iter_enumerated()
|
||||
.max_by_key(|(_i, layout)| layout.size.bytes())
|
||||
.map(|(i, _layout)| i)?;
|
||||
|
||||
let all_indices = (0..=variants.len() - 1).map(V::new);
|
||||
let needs_disc = |index: V| index != largest_variant_index && !absent(&variants[index]);
|
||||
let niche_variants = all_indices.clone().find(|v| needs_disc(*v)).unwrap().index()
|
||||
..=all_indices.rev().find(|v| needs_disc(*v)).unwrap().index();
|
||||
|
||||
let count = niche_variants.size_hint().1.unwrap() as u128;
|
||||
|
||||
// Find the field with the largest niche
|
||||
let (field_index, niche, (niche_start, niche_scalar)) = variants[largest_variant_index]
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter_map(|(j, field)| Some((j, field.largest_niche?)))
|
||||
.max_by_key(|(_, niche)| niche.available(dl))
|
||||
.and_then(|(j, niche)| Some((j, niche, niche.reserve(dl, count)?)))?;
|
||||
let niche_offset =
|
||||
niche.offset + variant_layouts[largest_variant_index].fields.offset(field_index);
|
||||
let niche_size = niche.value.size(dl);
|
||||
let size = variant_layouts[largest_variant_index].size.align_to(align.abi);
|
||||
|
||||
let all_variants_fit = variant_layouts.iter_enumerated_mut().all(|(i, layout)| {
|
||||
if i == largest_variant_index {
|
||||
return true;
|
||||
}
|
||||
|
||||
layout.largest_niche = None;
|
||||
|
||||
if layout.size <= niche_offset {
|
||||
// This variant will fit before the niche.
|
||||
return true;
|
||||
}
|
||||
|
||||
// Determine if it'll fit after the niche.
|
||||
let this_align = layout.align.abi;
|
||||
let this_offset = (niche_offset + niche_size).align_to(this_align);
|
||||
|
||||
if this_offset + layout.size > size {
|
||||
return false;
|
||||
}
|
||||
|
||||
// It'll fit, but we need to make some adjustments.
|
||||
match layout.fields {
|
||||
FieldsShape::Arbitrary { ref mut offsets, .. } => {
|
||||
for (j, offset) in offsets.iter_mut().enumerate() {
|
||||
if !variants[i][j].is_zst() {
|
||||
*offset += this_offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
panic!("Layout of fields should be Arbitrary for variants")
|
||||
}
|
||||
}
|
||||
|
||||
// It can't be a Scalar or ScalarPair because the offset isn't 0.
|
||||
if !layout.abi.is_uninhabited() {
|
||||
layout.abi = Abi::Aggregate { sized: true };
|
||||
}
|
||||
layout.size += this_offset;
|
||||
|
||||
true
|
||||
});
|
||||
|
||||
if !all_variants_fit {
|
||||
return None;
|
||||
}
|
||||
|
||||
let largest_niche = Niche::from_scalar(dl, niche_offset, niche_scalar);
|
||||
|
||||
let others_zst = variant_layouts
|
||||
.iter_enumerated()
|
||||
.all(|(i, layout)| i == largest_variant_index || layout.size == Size::ZERO);
|
||||
let same_size = size == variant_layouts[largest_variant_index].size;
|
||||
let same_align = align == variant_layouts[largest_variant_index].align;
|
||||
|
||||
let abi = if variant_layouts.iter().all(|v| v.abi.is_uninhabited()) {
|
||||
Abi::Uninhabited
|
||||
} else if same_size && same_align && others_zst {
|
||||
match variant_layouts[largest_variant_index].abi {
|
||||
// When the total alignment and size match, we can use the
|
||||
// same ABI as the scalar variant with the reserved niche.
|
||||
Abi::Scalar(_) => Abi::Scalar(niche_scalar),
|
||||
Abi::ScalarPair(first, second) => {
|
||||
// Only the niche is guaranteed to be initialised,
|
||||
// so use union layouts for the other primitive.
|
||||
if niche_offset == Size::ZERO {
|
||||
Abi::ScalarPair(niche_scalar, second.to_union())
|
||||
} else {
|
||||
Abi::ScalarPair(first.to_union(), niche_scalar)
|
||||
}
|
||||
}
|
||||
_ => Abi::Aggregate { sized: true },
|
||||
}
|
||||
} else {
|
||||
Abi::Aggregate { sized: true }
|
||||
};
|
||||
|
||||
let layout = LayoutS {
|
||||
variants: Variants::Multiple {
|
||||
tag: niche_scalar,
|
||||
tag_encoding: TagEncoding::Niche {
|
||||
untagged_variant: largest_variant_index,
|
||||
niche_variants: (V::new(*niche_variants.start())
|
||||
..=V::new(*niche_variants.end())),
|
||||
niche_start,
|
||||
},
|
||||
tag_field: 0,
|
||||
variants: IndexVec::new(),
|
||||
},
|
||||
fields: FieldsShape::Arbitrary {
|
||||
offsets: vec![niche_offset],
|
||||
memory_index: vec![0],
|
||||
},
|
||||
abi,
|
||||
largest_niche,
|
||||
size,
|
||||
align,
|
||||
};
|
||||
|
||||
Some(TmpLayout { layout, variants: variant_layouts })
|
||||
};
|
||||
|
||||
let niche_filling_layout = calculate_niche_filling_layout();
|
||||
|
||||
let (mut min, mut max) = (i128::MAX, i128::MIN);
|
||||
let discr_type = repr.discr_type();
|
||||
let bits = Integer::from_attr(dl, discr_type).size().bits();
|
||||
for (i, mut val) in discriminants {
|
||||
if variants[i].iter().any(|f| f.abi.is_uninhabited()) {
|
||||
continue;
|
||||
}
|
||||
if discr_type.is_signed() {
|
||||
// sign extend the raw representation to be an i128
|
||||
val = (val << (128 - bits)) >> (128 - bits);
|
||||
}
|
||||
if val < min {
|
||||
min = val;
|
||||
}
|
||||
if val > max {
|
||||
max = val;
|
||||
}
|
||||
}
|
||||
// We might have no inhabited variants, so pretend there's at least one.
|
||||
if (min, max) == (i128::MAX, i128::MIN) {
|
||||
min = 0;
|
||||
max = 0;
|
||||
}
|
||||
assert!(min <= max, "discriminant range is {}...{}", min, max);
|
||||
let (min_ity, signed) = discr_range_of_repr(min, max); //Integer::repr_discr(tcx, ty, &repr, min, max);
|
||||
|
||||
let mut align = dl.aggregate_align;
|
||||
let mut size = Size::ZERO;
|
||||
|
||||
// We're interested in the smallest alignment, so start large.
|
||||
let mut start_align = Align::from_bytes(256).unwrap();
|
||||
assert_eq!(Integer::for_align(dl, start_align), None);
|
||||
|
||||
// repr(C) on an enum tells us to make a (tag, union) layout,
|
||||
// so we need to grow the prefix alignment to be at least
|
||||
// the alignment of the union. (This value is used both for
|
||||
// determining the alignment of the overall enum, and the
|
||||
// determining the alignment of the payload after the tag.)
|
||||
let mut prefix_align = min_ity.align(dl).abi;
|
||||
if repr.c() {
|
||||
for fields in variants {
|
||||
for field in fields {
|
||||
prefix_align = prefix_align.max(field.align.abi);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create the set of structs that represent each variant.
|
||||
let mut layout_variants = variants
|
||||
.iter_enumerated()
|
||||
.map(|(i, field_layouts)| {
|
||||
let mut st = self.univariant(
|
||||
dl,
|
||||
field_layouts,
|
||||
repr,
|
||||
StructKind::Prefixed(min_ity.size(), prefix_align),
|
||||
)?;
|
||||
st.variants = Variants::Single { index: i };
|
||||
// Find the first field we can't move later
|
||||
// to make room for a larger discriminant.
|
||||
for field in st.fields.index_by_increasing_offset().map(|j| &field_layouts[j]) {
|
||||
if !field.is_zst() || field.align.abi.bytes() != 1 {
|
||||
start_align = start_align.min(field.align.abi);
|
||||
break;
|
||||
}
|
||||
}
|
||||
size = cmp::max(size, st.size);
|
||||
align = align.max(st.align);
|
||||
Some(st)
|
||||
})
|
||||
.collect::<Option<IndexVec<V, _>>>()?;
|
||||
|
||||
// Align the maximum variant size to the largest alignment.
|
||||
size = size.align_to(align.abi);
|
||||
|
||||
if size.bytes() >= dl.obj_size_bound() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let typeck_ity = Integer::from_attr(dl, repr.discr_type());
|
||||
if typeck_ity < min_ity {
|
||||
// It is a bug if Layout decided on a greater discriminant size than typeck for
|
||||
// some reason at this point (based on values discriminant can take on). Mostly
|
||||
// because this discriminant will be loaded, and then stored into variable of
|
||||
// type calculated by typeck. Consider such case (a bug): typeck decided on
|
||||
// byte-sized discriminant, but layout thinks we need a 16-bit to store all
|
||||
// discriminant values. That would be a bug, because then, in codegen, in order
|
||||
// to store this 16-bit discriminant into 8-bit sized temporary some of the
|
||||
// space necessary to represent would have to be discarded (or layout is wrong
|
||||
// on thinking it needs 16 bits)
|
||||
panic!(
|
||||
"layout decided on a larger discriminant type ({:?}) than typeck ({:?})",
|
||||
min_ity, typeck_ity
|
||||
);
|
||||
// However, it is fine to make discr type however large (as an optimisation)
|
||||
// after this point – we’ll just truncate the value we load in codegen.
|
||||
}
|
||||
|
||||
// Check to see if we should use a different type for the
|
||||
// discriminant. We can safely use a type with the same size
|
||||
// as the alignment of the first field of each variant.
|
||||
// We increase the size of the discriminant to avoid LLVM copying
|
||||
// padding when it doesn't need to. This normally causes unaligned
|
||||
// load/stores and excessive memcpy/memset operations. By using a
|
||||
// bigger integer size, LLVM can be sure about its contents and
|
||||
// won't be so conservative.
|
||||
|
||||
// Use the initial field alignment
|
||||
let mut ity = if repr.c() || repr.int.is_some() {
|
||||
min_ity
|
||||
} else {
|
||||
Integer::for_align(dl, start_align).unwrap_or(min_ity)
|
||||
};
|
||||
|
||||
// If the alignment is not larger than the chosen discriminant size,
|
||||
// don't use the alignment as the final size.
|
||||
if ity <= min_ity {
|
||||
ity = min_ity;
|
||||
} else {
|
||||
// Patch up the variants' first few fields.
|
||||
let old_ity_size = min_ity.size();
|
||||
let new_ity_size = ity.size();
|
||||
for variant in &mut layout_variants {
|
||||
match variant.fields {
|
||||
FieldsShape::Arbitrary { ref mut offsets, .. } => {
|
||||
for i in offsets {
|
||||
if *i <= old_ity_size {
|
||||
assert_eq!(*i, old_ity_size);
|
||||
*i = new_ity_size;
|
||||
}
|
||||
}
|
||||
// We might be making the struct larger.
|
||||
if variant.size <= old_ity_size {
|
||||
variant.size = new_ity_size;
|
||||
}
|
||||
}
|
||||
_ => panic!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let tag_mask = ity.size().unsigned_int_max();
|
||||
let tag = Scalar::Initialized {
|
||||
value: Int(ity, signed),
|
||||
valid_range: WrappingRange {
|
||||
start: (min as u128 & tag_mask),
|
||||
end: (max as u128 & tag_mask),
|
||||
},
|
||||
};
|
||||
let mut abi = Abi::Aggregate { sized: true };
|
||||
|
||||
if layout_variants.iter().all(|v| v.abi.is_uninhabited()) {
|
||||
abi = Abi::Uninhabited;
|
||||
} else if tag.size(dl) == size {
|
||||
// Make sure we only use scalar layout when the enum is entirely its
|
||||
// own tag (i.e. it has no padding nor any non-ZST variant fields).
|
||||
abi = Abi::Scalar(tag);
|
||||
} else {
|
||||
// Try to use a ScalarPair for all tagged enums.
|
||||
let mut common_prim = None;
|
||||
let mut common_prim_initialized_in_all_variants = true;
|
||||
for (field_layouts, layout_variant) in iter::zip(variants, &layout_variants) {
|
||||
let FieldsShape::Arbitrary { ref offsets, .. } = layout_variant.fields else {
|
||||
panic!();
|
||||
};
|
||||
let mut fields = iter::zip(field_layouts, offsets).filter(|p| !p.0.is_zst());
|
||||
let (field, offset) = match (fields.next(), fields.next()) {
|
||||
(None, None) => {
|
||||
common_prim_initialized_in_all_variants = false;
|
||||
continue;
|
||||
}
|
||||
(Some(pair), None) => pair,
|
||||
_ => {
|
||||
common_prim = None;
|
||||
break;
|
||||
}
|
||||
};
|
||||
let prim = match field.abi {
|
||||
Abi::Scalar(scalar) => {
|
||||
common_prim_initialized_in_all_variants &=
|
||||
matches!(scalar, Scalar::Initialized { .. });
|
||||
scalar.primitive()
|
||||
}
|
||||
_ => {
|
||||
common_prim = None;
|
||||
break;
|
||||
}
|
||||
};
|
||||
if let Some(pair) = common_prim {
|
||||
// This is pretty conservative. We could go fancier
|
||||
// by conflating things like i32 and u32, or even
|
||||
// realising that (u8, u8) could just cohabit with
|
||||
// u16 or even u32.
|
||||
if pair != (prim, offset) {
|
||||
common_prim = None;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
common_prim = Some((prim, offset));
|
||||
}
|
||||
}
|
||||
if let Some((prim, offset)) = common_prim {
|
||||
let prim_scalar = if common_prim_initialized_in_all_variants {
|
||||
scalar_unit(prim)
|
||||
} else {
|
||||
// Common prim might be uninit.
|
||||
Scalar::Union { value: prim }
|
||||
};
|
||||
let pair = self.scalar_pair::<V>(tag, prim_scalar);
|
||||
let pair_offsets = match pair.fields {
|
||||
FieldsShape::Arbitrary { ref offsets, ref memory_index } => {
|
||||
assert_eq!(memory_index, &[0, 1]);
|
||||
offsets
|
||||
}
|
||||
_ => panic!(),
|
||||
};
|
||||
if pair_offsets[0] == Size::ZERO
|
||||
&& pair_offsets[1] == *offset
|
||||
&& align == pair.align
|
||||
&& size == pair.size
|
||||
{
|
||||
// We can use `ScalarPair` only when it matches our
|
||||
// already computed layout (including `#[repr(C)]`).
|
||||
abi = pair.abi;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we pick a "clever" (by-value) ABI, we might have to adjust the ABI of the
|
||||
// variants to ensure they are consistent. This is because a downcast is
|
||||
// semantically a NOP, and thus should not affect layout.
|
||||
if matches!(abi, Abi::Scalar(..) | Abi::ScalarPair(..)) {
|
||||
for variant in &mut layout_variants {
|
||||
// We only do this for variants with fields; the others are not accessed anyway.
|
||||
// Also do not overwrite any already existing "clever" ABIs.
|
||||
if variant.fields.count() > 0 && matches!(variant.abi, Abi::Aggregate { .. }) {
|
||||
variant.abi = abi;
|
||||
// Also need to bump up the size and alignment, so that the entire value fits in here.
|
||||
variant.size = cmp::max(variant.size, size);
|
||||
variant.align.abi = cmp::max(variant.align.abi, align.abi);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let largest_niche = Niche::from_scalar(dl, Size::ZERO, tag);
|
||||
|
||||
let tagged_layout = LayoutS {
|
||||
variants: Variants::Multiple {
|
||||
tag,
|
||||
tag_encoding: TagEncoding::Direct,
|
||||
tag_field: 0,
|
||||
variants: IndexVec::new(),
|
||||
},
|
||||
fields: FieldsShape::Arbitrary { offsets: vec![Size::ZERO], memory_index: vec![0] },
|
||||
largest_niche,
|
||||
abi,
|
||||
align,
|
||||
size,
|
||||
};
|
||||
|
||||
let tagged_layout = TmpLayout { layout: tagged_layout, variants: layout_variants };
|
||||
|
||||
let mut best_layout = match (tagged_layout, niche_filling_layout) {
|
||||
(tl, Some(nl)) => {
|
||||
// Pick the smaller layout; otherwise,
|
||||
// pick the layout with the larger niche; otherwise,
|
||||
// pick tagged as it has simpler codegen.
|
||||
use cmp::Ordering::*;
|
||||
let niche_size = |tmp_l: &TmpLayout<V>| {
|
||||
tmp_l.layout.largest_niche.map_or(0, |n| n.available(dl))
|
||||
};
|
||||
match (tl.layout.size.cmp(&nl.layout.size), niche_size(&tl).cmp(&niche_size(&nl))) {
|
||||
(Greater, _) => nl,
|
||||
(Equal, Less) => nl,
|
||||
_ => tl,
|
||||
}
|
||||
}
|
||||
(tl, None) => tl,
|
||||
};
|
||||
|
||||
// Now we can intern the variant layouts and store them in the enum layout.
|
||||
best_layout.layout.variants = match best_layout.layout.variants {
|
||||
Variants::Multiple { tag, tag_encoding, tag_field, .. } => {
|
||||
Variants::Multiple { tag, tag_encoding, tag_field, variants: best_layout.variants }
|
||||
}
|
||||
_ => panic!(),
|
||||
};
|
||||
Some(best_layout.layout)
|
||||
}
|
||||
|
||||
fn layout_of_union<'a, V: Idx, F: Deref<Target = &'a LayoutS<V>> + Debug>(
|
||||
&self,
|
||||
repr: &ReprOptions,
|
||||
variants: &IndexVec<V, Vec<F>>,
|
||||
) -> Option<LayoutS<V>> {
|
||||
let dl = self.current_data_layout();
|
||||
let dl = dl.borrow();
|
||||
let mut align = if repr.pack.is_some() { dl.i8_align } else { dl.aggregate_align };
|
||||
|
||||
if let Some(repr_align) = repr.align {
|
||||
align = align.max(AbiAndPrefAlign::new(repr_align));
|
||||
}
|
||||
|
||||
let optimize = !repr.inhibit_union_abi_opt();
|
||||
let mut size = Size::ZERO;
|
||||
let mut abi = Abi::Aggregate { sized: true };
|
||||
let index = V::new(0);
|
||||
for field in &variants[index] {
|
||||
assert!(field.is_sized());
|
||||
align = align.max(field.align);
|
||||
|
||||
// If all non-ZST fields have the same ABI, forward this ABI
|
||||
if optimize && !field.is_zst() {
|
||||
// Discard valid range information and allow undef
|
||||
let field_abi = match field.abi {
|
||||
Abi::Scalar(x) => Abi::Scalar(x.to_union()),
|
||||
Abi::ScalarPair(x, y) => Abi::ScalarPair(x.to_union(), y.to_union()),
|
||||
Abi::Vector { element: x, count } => {
|
||||
Abi::Vector { element: x.to_union(), count }
|
||||
}
|
||||
Abi::Uninhabited | Abi::Aggregate { .. } => Abi::Aggregate { sized: true },
|
||||
};
|
||||
|
||||
if size == Size::ZERO {
|
||||
// first non ZST: initialize 'abi'
|
||||
abi = field_abi;
|
||||
} else if abi != field_abi {
|
||||
// different fields have different ABI: reset to Aggregate
|
||||
abi = Abi::Aggregate { sized: true };
|
||||
}
|
||||
}
|
||||
|
||||
size = cmp::max(size, field.size);
|
||||
}
|
||||
|
||||
if let Some(pack) = repr.pack {
|
||||
align = align.min(AbiAndPrefAlign::new(pack));
|
||||
}
|
||||
|
||||
Some(LayoutS {
|
||||
variants: Variants::Single { index },
|
||||
fields: FieldsShape::Union(NonZeroUsize::new(variants[index].len())?),
|
||||
abi,
|
||||
largest_niche: None,
|
||||
align,
|
||||
size: size.align_to(align.abi),
|
||||
})
|
||||
}
|
||||
}
|
||||
1502
compiler/rustc_abi/src/lib.rs
Normal file
1502
compiler/rustc_abi/src/lib.rs
Normal file
File diff suppressed because it is too large
Load Diff
@ -52,19 +52,15 @@ fn test_arena_alloc_nested() {
|
||||
|
||||
impl<'a> Wrap<'a> {
|
||||
fn alloc_inner<F: Fn() -> Inner>(&self, f: F) -> &Inner {
|
||||
let r: &EI<'_> = self.0.alloc(EI::I(f()));
|
||||
if let &EI::I(ref i) = r {
|
||||
i
|
||||
} else {
|
||||
panic!("mismatch");
|
||||
match self.0.alloc(EI::I(f())) {
|
||||
EI::I(i) => i,
|
||||
_ => panic!("mismatch"),
|
||||
}
|
||||
}
|
||||
fn alloc_outer<F: Fn() -> Outer<'a>>(&self, f: F) -> &Outer<'_> {
|
||||
let r: &EI<'_> = self.0.alloc(EI::O(f()));
|
||||
if let &EI::O(ref o) = r {
|
||||
o
|
||||
} else {
|
||||
panic!("mismatch");
|
||||
match self.0.alloc(EI::O(f())) {
|
||||
EI::O(o) => o,
|
||||
_ => panic!("mismatch"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -14,5 +14,5 @@ rustc_macros = { path = "../rustc_macros" }
|
||||
rustc_serialize = { path = "../rustc_serialize" }
|
||||
rustc_span = { path = "../rustc_span" }
|
||||
smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
|
||||
thin-vec = "0.2.8"
|
||||
thin-vec = "0.2.9"
|
||||
tracing = "0.1"
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
//! - [`FnDecl`], [`FnHeader`] and [`Param`]: Metadata associated with a function declaration.
|
||||
//! - [`Generics`], [`GenericParam`], [`WhereClause`]: Metadata associated with generic parameters.
|
||||
//! - [`EnumDef`] and [`Variant`]: Enum declaration.
|
||||
//! - [`Lit`] and [`LitKind`]: Literal expressions.
|
||||
//! - [`MetaItemLit`] and [`LitKind`]: Literal expressions.
|
||||
//! - [`MacroDef`], [`MacStmtStyle`], [`MacCall`], [`MacDelimiter`]: Macro definition and invocation.
|
||||
//! - [`Attribute`]: Metadata associated with item.
|
||||
//! - [`UnOp`], [`BinOp`], and [`BinOpKind`]: Unary and binary operators.
|
||||
@ -36,7 +36,7 @@ use rustc_span::{Span, DUMMY_SP};
|
||||
use std::convert::TryFrom;
|
||||
use std::fmt;
|
||||
use std::mem;
|
||||
use thin_vec::ThinVec;
|
||||
use thin_vec::{thin_vec, ThinVec};
|
||||
|
||||
/// A "Label" is an identifier of some point in sources,
|
||||
/// e.g. in the following code:
|
||||
@ -90,7 +90,7 @@ pub struct Path {
|
||||
pub span: Span,
|
||||
/// The segments in the path: the things separated by `::`.
|
||||
/// Global paths begin with `kw::PathRoot`.
|
||||
pub segments: Vec<PathSegment>,
|
||||
pub segments: ThinVec<PathSegment>,
|
||||
pub tokens: Option<LazyAttrTokenStream>,
|
||||
}
|
||||
|
||||
@ -111,10 +111,10 @@ impl<CTX: rustc_span::HashStableContext> HashStable<CTX> for Path {
|
||||
}
|
||||
|
||||
impl Path {
|
||||
// Convert a span and an identifier to the corresponding
|
||||
// one-segment path.
|
||||
/// Convert a span and an identifier to the corresponding
|
||||
/// one-segment path.
|
||||
pub fn from_ident(ident: Ident) -> Path {
|
||||
Path { segments: vec![PathSegment::from_ident(ident)], span: ident.span, tokens: None }
|
||||
Path { segments: thin_vec![PathSegment::from_ident(ident)], span: ident.span, tokens: None }
|
||||
}
|
||||
|
||||
pub fn is_global(&self) -> bool {
|
||||
@ -175,9 +175,9 @@ impl GenericArgs {
|
||||
}
|
||||
|
||||
pub fn span(&self) -> Span {
|
||||
match *self {
|
||||
AngleBracketed(ref data) => data.span,
|
||||
Parenthesized(ref data) => data.span,
|
||||
match self {
|
||||
AngleBracketed(data) => data.span,
|
||||
Parenthesized(data) => data.span,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -312,8 +312,8 @@ pub enum GenericBound {
|
||||
impl GenericBound {
|
||||
pub fn span(&self) -> Span {
|
||||
match self {
|
||||
GenericBound::Trait(ref t, ..) => t.span,
|
||||
GenericBound::Outlives(ref l) => l.ident.span,
|
||||
GenericBound::Trait(t, ..) => t.span,
|
||||
GenericBound::Outlives(l) => l.ident.span,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -392,15 +392,7 @@ pub struct Generics {
|
||||
impl Default for Generics {
|
||||
/// Creates an instance of `Generics`.
|
||||
fn default() -> Generics {
|
||||
Generics {
|
||||
params: Vec::new(),
|
||||
where_clause: WhereClause {
|
||||
has_where_token: false,
|
||||
predicates: Vec::new(),
|
||||
span: DUMMY_SP,
|
||||
},
|
||||
span: DUMMY_SP,
|
||||
}
|
||||
Generics { params: Vec::new(), where_clause: Default::default(), span: DUMMY_SP }
|
||||
}
|
||||
}
|
||||
|
||||
@ -415,6 +407,12 @@ pub struct WhereClause {
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
impl Default for WhereClause {
|
||||
fn default() -> WhereClause {
|
||||
WhereClause { has_where_token: false, predicates: Vec::new(), span: DUMMY_SP }
|
||||
}
|
||||
}
|
||||
|
||||
/// A single predicate in a where-clause.
|
||||
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||
pub enum WherePredicate {
|
||||
@ -481,20 +479,10 @@ pub struct Crate {
|
||||
pub is_placeholder: bool,
|
||||
}
|
||||
|
||||
/// Possible values inside of compile-time attribute lists.
|
||||
///
|
||||
/// E.g., the '..' in `#[name(..)]`.
|
||||
#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
|
||||
pub enum NestedMetaItem {
|
||||
/// A full MetaItem, for recursive meta items.
|
||||
MetaItem(MetaItem),
|
||||
/// A literal.
|
||||
///
|
||||
/// E.g., `"foo"`, `64`, `true`.
|
||||
Literal(Lit),
|
||||
}
|
||||
|
||||
/// A spanned compile-time attribute item.
|
||||
/// A semantic representation of a meta item. A meta item is a slightly
|
||||
/// restricted form of an attribute -- it can only contain expressions in
|
||||
/// certain leaf positions, rather than arbitrary token streams -- that is used
|
||||
/// for most built-in attributes.
|
||||
///
|
||||
/// E.g., `#[test]`, `#[derive(..)]`, `#[rustfmt::skip]` or `#[feature = "foo"]`.
|
||||
#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
|
||||
@ -504,23 +492,37 @@ pub struct MetaItem {
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
/// A compile-time attribute item.
|
||||
///
|
||||
/// E.g., `#[test]`, `#[derive(..)]` or `#[feature = "foo"]`.
|
||||
/// The meta item kind, containing the data after the initial path.
|
||||
#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
|
||||
pub enum MetaItemKind {
|
||||
/// Word meta item.
|
||||
///
|
||||
/// E.g., `test` as in `#[test]`.
|
||||
/// E.g., `#[test]`, which lacks any arguments after `test`.
|
||||
Word,
|
||||
|
||||
/// List meta item.
|
||||
///
|
||||
/// E.g., `derive(..)` as in `#[derive(..)]`.
|
||||
/// E.g., `#[derive(..)]`, where the field represents the `..`.
|
||||
List(Vec<NestedMetaItem>),
|
||||
|
||||
/// Name value meta item.
|
||||
///
|
||||
/// E.g., `feature = "foo"` as in `#[feature = "foo"]`.
|
||||
NameValue(Lit),
|
||||
/// E.g., `#[feature = "foo"]`, where the field represents the `"foo"`.
|
||||
NameValue(MetaItemLit),
|
||||
}
|
||||
|
||||
/// Values inside meta item lists.
|
||||
///
|
||||
/// E.g., each of `Clone`, `Copy` in `#[derive(Clone, Copy)]`.
|
||||
#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
|
||||
pub enum NestedMetaItem {
|
||||
/// A full MetaItem, for recursive meta items.
|
||||
MetaItem(MetaItem),
|
||||
|
||||
/// A literal.
|
||||
///
|
||||
/// E.g., `"foo"`, `64`, `true`.
|
||||
Lit(MetaItemLit),
|
||||
}
|
||||
|
||||
/// A block (`{ .. }`).
|
||||
@ -720,10 +722,10 @@ pub enum PatKind {
|
||||
|
||||
/// A struct or struct variant pattern (e.g., `Variant {x, y, ..}`).
|
||||
/// The `bool` is `true` in the presence of a `..`.
|
||||
Struct(Option<QSelf>, Path, Vec<PatField>, /* recovered */ bool),
|
||||
Struct(Option<P<QSelf>>, Path, Vec<PatField>, /* recovered */ bool),
|
||||
|
||||
/// A tuple struct/variant pattern (`Variant(x, y, .., z)`).
|
||||
TupleStruct(Option<QSelf>, Path, Vec<P<Pat>>),
|
||||
TupleStruct(Option<P<QSelf>>, Path, Vec<P<Pat>>),
|
||||
|
||||
/// An or-pattern `A | B | C`.
|
||||
/// Invariant: `pats.len() >= 2`.
|
||||
@ -733,7 +735,7 @@ pub enum PatKind {
|
||||
/// Unqualified path patterns `A::B::C` can legally refer to variants, structs, constants
|
||||
/// or associated constants. Qualified path patterns `<A>::B::C`/`<A as Trait>::B::C` can
|
||||
/// only legally refer to associated constants.
|
||||
Path(Option<QSelf>, Path),
|
||||
Path(Option<P<QSelf>>, Path),
|
||||
|
||||
/// A tuple pattern (`(a, b)`).
|
||||
Tuple(Vec<P<Pat>>),
|
||||
@ -777,8 +779,9 @@ pub enum PatKind {
|
||||
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Copy)]
|
||||
#[derive(HashStable_Generic, Encodable, Decodable)]
|
||||
pub enum Mutability {
|
||||
Mut,
|
||||
// N.B. Order is deliberate, so that Not < Mut
|
||||
Not,
|
||||
Mut,
|
||||
}
|
||||
|
||||
impl Mutability {
|
||||
@ -789,12 +792,39 @@ impl Mutability {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn prefix_str(&self) -> &'static str {
|
||||
/// Returns `""` (empty string) or `"mut "` depending on the mutability.
|
||||
pub fn prefix_str(self) -> &'static str {
|
||||
match self {
|
||||
Mutability::Mut => "mut ",
|
||||
Mutability::Not => "",
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `"&"` or `"&mut "` depending on the mutability.
|
||||
pub fn ref_prefix_str(self) -> &'static str {
|
||||
match self {
|
||||
Mutability::Not => "&",
|
||||
Mutability::Mut => "&mut ",
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `""` (empty string) or `"mutably "` depending on the mutability.
|
||||
pub fn mutably_str(self) -> &'static str {
|
||||
match self {
|
||||
Mutability::Not => "",
|
||||
Mutability::Mut => "mutably ",
|
||||
}
|
||||
}
|
||||
|
||||
/// Return `true` if self is mutable
|
||||
pub fn is_mut(self) -> bool {
|
||||
matches!(self, Self::Mut)
|
||||
}
|
||||
|
||||
/// Return `true` if self is **not** mutable
|
||||
pub fn is_not(self) -> bool {
|
||||
matches!(self, Self::Not)
|
||||
}
|
||||
}
|
||||
|
||||
/// The kind of borrow in an `AddrOf` expression,
|
||||
@ -1117,23 +1147,23 @@ impl Expr {
|
||||
/// If this is not the case, name resolution does not resolve `N` when using
|
||||
/// `min_const_generics` as more complex expressions are not supported.
|
||||
pub fn is_potential_trivial_const_param(&self) -> bool {
|
||||
let this = if let ExprKind::Block(ref block, None) = self.kind {
|
||||
if block.stmts.len() == 1 {
|
||||
if let StmtKind::Expr(ref expr) = block.stmts[0].kind { expr } else { self }
|
||||
} else {
|
||||
self
|
||||
}
|
||||
let this = if let ExprKind::Block(block, None) = &self.kind
|
||||
&& block.stmts.len() == 1
|
||||
&& let StmtKind::Expr(expr) = &block.stmts[0].kind
|
||||
{
|
||||
expr
|
||||
} else {
|
||||
self
|
||||
};
|
||||
|
||||
if let ExprKind::Path(None, ref path) = this.kind {
|
||||
if path.segments.len() == 1 && path.segments[0].args.is_none() {
|
||||
return true;
|
||||
}
|
||||
if let ExprKind::Path(None, path) = &this.kind
|
||||
&& path.segments.len() == 1
|
||||
&& path.segments[0].args.is_none()
|
||||
{
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
|
||||
pub fn to_bound(&self) -> Option<GenericBound> {
|
||||
@ -1149,7 +1179,7 @@ impl Expr {
|
||||
pub fn peel_parens(&self) -> &Expr {
|
||||
let mut expr = self;
|
||||
while let ExprKind::Paren(inner) = &expr.kind {
|
||||
expr = &inner;
|
||||
expr = inner;
|
||||
}
|
||||
expr
|
||||
}
|
||||
@ -1208,7 +1238,7 @@ impl Expr {
|
||||
ExprKind::Tup(_) => ExprPrecedence::Tup,
|
||||
ExprKind::Binary(op, ..) => ExprPrecedence::Binary(op.node),
|
||||
ExprKind::Unary(..) => ExprPrecedence::Unary,
|
||||
ExprKind::Lit(_) => ExprPrecedence::Lit,
|
||||
ExprKind::Lit(_) | ExprKind::IncludedBytes(..) => ExprPrecedence::Lit,
|
||||
ExprKind::Type(..) | ExprKind::Cast(..) => ExprPrecedence::Cast,
|
||||
ExprKind::Let(..) => ExprPrecedence::Let,
|
||||
ExprKind::If(..) => ExprPrecedence::If,
|
||||
@ -1257,7 +1287,7 @@ impl Expr {
|
||||
)
|
||||
}
|
||||
|
||||
// To a first-order approximation, is this a pattern
|
||||
/// To a first-order approximation, is this a pattern?
|
||||
pub fn is_approximately_pattern(&self) -> bool {
|
||||
match &self.peel_parens().kind {
|
||||
ExprKind::Box(_)
|
||||
@ -1274,6 +1304,20 @@ impl Expr {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||
pub struct Closure {
|
||||
pub binder: ClosureBinder,
|
||||
pub capture_clause: CaptureBy,
|
||||
pub asyncness: Async,
|
||||
pub movability: Movability,
|
||||
pub fn_decl: P<FnDecl>,
|
||||
pub body: P<Expr>,
|
||||
/// The span of the declaration block: 'move |...| -> ...'
|
||||
pub fn_decl_span: Span,
|
||||
/// The span of the argument block `|...|`
|
||||
pub fn_arg_span: Span,
|
||||
}
|
||||
|
||||
/// Limit types of a range (inclusive or exclusive)
|
||||
#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug)]
|
||||
pub enum RangeLimits {
|
||||
@ -1283,6 +1327,20 @@ pub enum RangeLimits {
|
||||
Closed,
|
||||
}
|
||||
|
||||
/// A method call (e.g. `x.foo::<Bar, Baz>(a, b, c)`).
|
||||
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||
pub struct MethodCall {
|
||||
/// The method name and its generic arguments, e.g. `foo::<Bar, Baz>`.
|
||||
pub seg: PathSegment,
|
||||
/// The receiver, e.g. `x`.
|
||||
pub receiver: P<Expr>,
|
||||
/// The arguments, e.g. `a, b, c`.
|
||||
pub args: Vec<P<Expr>>,
|
||||
/// The span of the function, without the dot and receiver e.g. `foo::<Bar,
|
||||
/// Baz>(a, b, c)`.
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||
pub enum StructRest {
|
||||
/// `..x`.
|
||||
@ -1295,7 +1353,7 @@ pub enum StructRest {
|
||||
|
||||
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||
pub struct StructExpr {
|
||||
pub qself: Option<QSelf>,
|
||||
pub qself: Option<P<QSelf>>,
|
||||
pub path: Path,
|
||||
pub fields: Vec<ExprField>,
|
||||
pub rest: StructRest,
|
||||
@ -1316,17 +1374,8 @@ pub enum ExprKind {
|
||||
/// This also represents calling the constructor of
|
||||
/// tuple-like ADTs such as tuple structs and enum variants.
|
||||
Call(P<Expr>, Vec<P<Expr>>),
|
||||
/// A method call (`x.foo::<'static, Bar, Baz>(a, b, c, d)`)
|
||||
///
|
||||
/// The `PathSegment` represents the method name and its generic arguments
|
||||
/// (within the angle brackets).
|
||||
/// The standalone `Expr` is the receiver expression.
|
||||
/// The vector of `Expr` is the arguments.
|
||||
/// `x.foo::<Bar, Baz>(a, b, c, d)` is represented as
|
||||
/// `ExprKind::MethodCall(PathSegment { foo, [Bar, Baz] }, x, [a, b, c, d])`.
|
||||
/// This `Span` is the span of the function, without the dot and receiver
|
||||
/// (e.g. `foo(a, b)` in `x.foo(a, b)`
|
||||
MethodCall(PathSegment, P<Expr>, Vec<P<Expr>>, Span),
|
||||
/// A method call (e.g. `x.foo::<Bar, Baz>(a, b, c)`).
|
||||
MethodCall(Box<MethodCall>),
|
||||
/// A tuple (e.g., `(a, b, c, d)`).
|
||||
Tup(Vec<P<Expr>>),
|
||||
/// A binary operation (e.g., `a + b`, `a * b`).
|
||||
@ -1334,7 +1383,7 @@ pub enum ExprKind {
|
||||
/// A unary operation (e.g., `!x`, `*x`).
|
||||
Unary(UnOp, P<Expr>),
|
||||
/// A literal (e.g., `1`, `"foo"`).
|
||||
Lit(Lit),
|
||||
Lit(token::Lit),
|
||||
/// A cast (e.g., `foo as f64`).
|
||||
Cast(P<Expr>, P<Ty>),
|
||||
/// A type ascription (e.g., `42: usize`).
|
||||
@ -1361,13 +1410,11 @@ pub enum ExprKind {
|
||||
/// Conditionless loop (can be exited with `break`, `continue`, or `return`).
|
||||
///
|
||||
/// `'label: loop { block }`
|
||||
Loop(P<Block>, Option<Label>),
|
||||
Loop(P<Block>, Option<Label>, Span),
|
||||
/// A `match` block.
|
||||
Match(P<Expr>, Vec<Arm>),
|
||||
/// A closure (e.g., `move |a, b, c| a + b + c`).
|
||||
///
|
||||
/// The final span is the span of the argument block `|...|`.
|
||||
Closure(ClosureBinder, CaptureBy, Async, Movability, P<FnDecl>, P<Expr>, Span),
|
||||
Closure(Box<Closure>),
|
||||
/// A block (`'label: { ... }`).
|
||||
Block(P<Block>, Option<Label>),
|
||||
/// An async block (`async move { ... }`).
|
||||
@ -1405,7 +1452,7 @@ pub enum ExprKind {
|
||||
/// parameters (e.g., `foo::bar::<baz>`).
|
||||
///
|
||||
/// Optionally "qualified" (e.g., `<Vec<T> as SomeTrait>::SomeType`).
|
||||
Path(Option<QSelf>, Path),
|
||||
Path(Option<P<QSelf>>, Path),
|
||||
|
||||
/// A referencing operation (`&a`, `&mut a`, `&raw const a` or `&raw mut a`).
|
||||
AddrOf(BorrowKind, Mutability, P<Expr>),
|
||||
@ -1446,6 +1493,12 @@ pub enum ExprKind {
|
||||
/// with an optional value to be returned.
|
||||
Yeet(Option<P<Expr>>),
|
||||
|
||||
/// Bytes included via `include_bytes!`
|
||||
/// Added for optimization purposes to avoid the need to escape
|
||||
/// large binary blobs - should always behave like [`ExprKind::Lit`]
|
||||
/// with a `ByteStr` literal.
|
||||
IncludedBytes(Lrc<[u8]>),
|
||||
|
||||
/// Placeholder for an expression that wasn't syntactically well formed in some way.
|
||||
Err,
|
||||
}
|
||||
@ -1525,55 +1578,48 @@ pub enum ClosureBinder {
|
||||
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||
pub struct MacCall {
|
||||
pub path: Path,
|
||||
pub args: P<MacArgs>,
|
||||
pub args: P<DelimArgs>,
|
||||
pub prior_type_ascription: Option<(Span, bool)>,
|
||||
}
|
||||
|
||||
impl MacCall {
|
||||
pub fn span(&self) -> Span {
|
||||
self.path.span.to(self.args.span().unwrap_or(self.path.span))
|
||||
self.path.span.to(self.args.dspan.entire())
|
||||
}
|
||||
}
|
||||
|
||||
/// Arguments passed to an attribute or a function-like macro.
|
||||
/// Arguments passed to an attribute macro.
|
||||
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||
pub enum MacArgs {
|
||||
/// No arguments - `#[attr]`.
|
||||
pub enum AttrArgs {
|
||||
/// No arguments: `#[attr]`.
|
||||
Empty,
|
||||
/// Delimited arguments - `#[attr()/[]/{}]` or `mac!()/[]/{}`.
|
||||
Delimited(DelimSpan, MacDelimiter, TokenStream),
|
||||
/// Arguments of a key-value attribute - `#[attr = "value"]`.
|
||||
/// Delimited arguments: `#[attr()/[]/{}]`.
|
||||
Delimited(DelimArgs),
|
||||
/// Arguments of a key-value attribute: `#[attr = "value"]`.
|
||||
Eq(
|
||||
/// Span of the `=` token.
|
||||
Span,
|
||||
/// The "value".
|
||||
MacArgsEq,
|
||||
AttrArgsEq,
|
||||
),
|
||||
}
|
||||
|
||||
// The RHS of a `MacArgs::Eq` starts out as an expression. Once macro expansion
|
||||
// is completed, all cases end up either as a literal, which is the form used
|
||||
// after lowering to HIR, or as an error.
|
||||
// The RHS of an `AttrArgs::Eq` starts out as an expression. Once macro
|
||||
// expansion is completed, all cases end up either as a meta item literal,
|
||||
// which is the form used after lowering to HIR, or as an error.
|
||||
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||
pub enum MacArgsEq {
|
||||
pub enum AttrArgsEq {
|
||||
Ast(P<Expr>),
|
||||
Hir(Lit),
|
||||
Hir(MetaItemLit),
|
||||
}
|
||||
|
||||
impl MacArgs {
|
||||
pub fn delim(&self) -> Option<Delimiter> {
|
||||
match self {
|
||||
MacArgs::Delimited(_, delim, _) => Some(delim.to_token()),
|
||||
MacArgs::Empty | MacArgs::Eq(..) => None,
|
||||
}
|
||||
}
|
||||
|
||||
impl AttrArgs {
|
||||
pub fn span(&self) -> Option<Span> {
|
||||
match self {
|
||||
MacArgs::Empty => None,
|
||||
MacArgs::Delimited(dspan, ..) => Some(dspan.entire()),
|
||||
MacArgs::Eq(eq_span, MacArgsEq::Ast(expr)) => Some(eq_span.to(expr.span)),
|
||||
MacArgs::Eq(_, MacArgsEq::Hir(lit)) => {
|
||||
AttrArgs::Empty => None,
|
||||
AttrArgs::Delimited(args) => Some(args.dspan.entire()),
|
||||
AttrArgs::Eq(eq_span, AttrArgsEq::Ast(expr)) => Some(eq_span.to(expr.span)),
|
||||
AttrArgs::Eq(_, AttrArgsEq::Hir(lit)) => {
|
||||
unreachable!("in literal form when getting span: {:?}", lit);
|
||||
}
|
||||
}
|
||||
@ -1583,39 +1629,29 @@ impl MacArgs {
|
||||
/// Proc macros see these tokens, for example.
|
||||
pub fn inner_tokens(&self) -> TokenStream {
|
||||
match self {
|
||||
MacArgs::Empty => TokenStream::default(),
|
||||
MacArgs::Delimited(.., tokens) => tokens.clone(),
|
||||
MacArgs::Eq(_, MacArgsEq::Ast(expr)) => TokenStream::from_ast(expr),
|
||||
MacArgs::Eq(_, MacArgsEq::Hir(lit)) => {
|
||||
AttrArgs::Empty => TokenStream::default(),
|
||||
AttrArgs::Delimited(args) => args.tokens.clone(),
|
||||
AttrArgs::Eq(_, AttrArgsEq::Ast(expr)) => TokenStream::from_ast(expr),
|
||||
AttrArgs::Eq(_, AttrArgsEq::Hir(lit)) => {
|
||||
unreachable!("in literal form when getting inner tokens: {:?}", lit)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether a macro with these arguments needs a semicolon
|
||||
/// when used as a standalone item or statement.
|
||||
pub fn need_semicolon(&self) -> bool {
|
||||
!matches!(self, MacArgs::Delimited(_, MacDelimiter::Brace, _))
|
||||
}
|
||||
}
|
||||
|
||||
impl<CTX> HashStable<CTX> for MacArgs
|
||||
impl<CTX> HashStable<CTX> for AttrArgs
|
||||
where
|
||||
CTX: crate::HashStableContext,
|
||||
{
|
||||
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
|
||||
mem::discriminant(self).hash_stable(ctx, hasher);
|
||||
match self {
|
||||
MacArgs::Empty => {}
|
||||
MacArgs::Delimited(dspan, delim, tokens) => {
|
||||
dspan.hash_stable(ctx, hasher);
|
||||
delim.hash_stable(ctx, hasher);
|
||||
tokens.hash_stable(ctx, hasher);
|
||||
}
|
||||
MacArgs::Eq(_eq_span, MacArgsEq::Ast(expr)) => {
|
||||
AttrArgs::Empty => {}
|
||||
AttrArgs::Delimited(args) => args.hash_stable(ctx, hasher),
|
||||
AttrArgs::Eq(_eq_span, AttrArgsEq::Ast(expr)) => {
|
||||
unreachable!("hash_stable {:?}", expr);
|
||||
}
|
||||
MacArgs::Eq(eq_span, MacArgsEq::Hir(lit)) => {
|
||||
AttrArgs::Eq(eq_span, AttrArgsEq::Hir(lit)) => {
|
||||
eq_span.hash_stable(ctx, hasher);
|
||||
lit.hash_stable(ctx, hasher);
|
||||
}
|
||||
@ -1623,6 +1659,34 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
/// Delimited arguments, as used in `#[attr()/[]/{}]` or `mac!()/[]/{}`.
|
||||
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||
pub struct DelimArgs {
|
||||
pub dspan: DelimSpan,
|
||||
pub delim: MacDelimiter,
|
||||
pub tokens: TokenStream,
|
||||
}
|
||||
|
||||
impl DelimArgs {
|
||||
/// Whether a macro with these arguments needs a semicolon
|
||||
/// when used as a standalone item or statement.
|
||||
pub fn need_semicolon(&self) -> bool {
|
||||
!matches!(self, DelimArgs { delim: MacDelimiter::Brace, .. })
|
||||
}
|
||||
}
|
||||
|
||||
impl<CTX> HashStable<CTX> for DelimArgs
|
||||
where
|
||||
CTX: crate::HashStableContext,
|
||||
{
|
||||
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
|
||||
let DelimArgs { dspan, delim, tokens } = self;
|
||||
dspan.hash_stable(ctx, hasher);
|
||||
delim.hash_stable(ctx, hasher);
|
||||
tokens.hash_stable(ctx, hasher);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)]
|
||||
pub enum MacDelimiter {
|
||||
Parenthesis,
|
||||
@ -1652,7 +1716,7 @@ impl MacDelimiter {
|
||||
/// Represents a macro definition.
|
||||
#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
|
||||
pub struct MacroDef {
|
||||
pub body: P<MacArgs>,
|
||||
pub body: P<DelimArgs>,
|
||||
/// `true` if macro was defined with `macro_rules`.
|
||||
pub macro_rules: bool,
|
||||
}
|
||||
@ -1668,19 +1732,18 @@ pub enum StrStyle {
|
||||
Raw(u8),
|
||||
}
|
||||
|
||||
/// An AST literal.
|
||||
/// A literal in a meta item.
|
||||
#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
|
||||
pub struct Lit {
|
||||
pub struct MetaItemLit {
|
||||
/// The original literal token as written in source code.
|
||||
pub token_lit: token::Lit,
|
||||
/// The "semantic" representation of the literal lowered from the original tokens.
|
||||
/// Strings are unescaped, hexadecimal forms are eliminated, etc.
|
||||
/// FIXME: Remove this and only create the semantic representation during lowering to HIR.
|
||||
pub kind: LitKind,
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
/// Same as `Lit`, but restricted to string literals.
|
||||
/// Similar to `MetaItemLit`, but restricted to string literals.
|
||||
#[derive(Clone, Copy, Encodable, Decodable, Debug)]
|
||||
pub struct StrLit {
|
||||
/// The original literal token as written in source code.
|
||||
@ -1689,21 +1752,16 @@ pub struct StrLit {
|
||||
pub suffix: Option<Symbol>,
|
||||
pub span: Span,
|
||||
/// The unescaped "semantic" representation of the literal lowered from the original token.
|
||||
/// FIXME: Remove this and only create the semantic representation during lowering to HIR.
|
||||
pub symbol_unescaped: Symbol,
|
||||
}
|
||||
|
||||
impl StrLit {
|
||||
pub fn as_lit(&self) -> Lit {
|
||||
pub fn as_token_lit(&self) -> token::Lit {
|
||||
let token_kind = match self.style {
|
||||
StrStyle::Cooked => token::Str,
|
||||
StrStyle::Raw(n) => token::StrRaw(n),
|
||||
};
|
||||
Lit {
|
||||
token_lit: token::Lit::new(token_kind, self.symbol, self.suffix),
|
||||
span: self.span,
|
||||
kind: LitKind::Str(self.symbol_unescaped, self.style),
|
||||
}
|
||||
token::Lit::new(token_kind, self.symbol, self.suffix)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1729,9 +1787,12 @@ pub enum LitFloatType {
|
||||
Unsuffixed,
|
||||
}
|
||||
|
||||
/// Literal kind.
|
||||
/// This type is used within both `ast::MetaItemLit` and `hir::Lit`.
|
||||
///
|
||||
/// E.g., `"foo"`, `42`, `12.34`, or `bool`.
|
||||
/// Note that the entire literal (including the suffix) is considered when
|
||||
/// deciding the `LitKind`. This means that float literals like `1f32` are
|
||||
/// classified by this type as `Float`. This is different to `token::LitKind`
|
||||
/// which does *not* consider the suffix.
|
||||
#[derive(Clone, Encodable, Decodable, Debug, Hash, Eq, PartialEq, HashStable_Generic)]
|
||||
pub enum LitKind {
|
||||
/// A string literal (`"foo"`). The symbol is unescaped, and so may differ
|
||||
@ -1745,10 +1806,11 @@ pub enum LitKind {
|
||||
Char(char),
|
||||
/// An integer literal (`1`).
|
||||
Int(u128, LitIntType),
|
||||
/// A float literal (`1f64` or `1E10f64`). Stored as a symbol rather than
|
||||
/// `f64` so that `LitKind` can impl `Eq` and `Hash`.
|
||||
/// A float literal (`1.0`, `1f64` or `1E10f64`). The pre-suffix part is
|
||||
/// stored as a symbol rather than `f64` so that `LitKind` can impl `Eq`
|
||||
/// and `Hash`.
|
||||
Float(Symbol, LitFloatType),
|
||||
/// A boolean literal.
|
||||
/// A boolean literal (`true`, `false`).
|
||||
Bool(bool),
|
||||
/// Placeholder for a literal that wasn't well-formed in some way.
|
||||
Err,
|
||||
@ -1967,7 +2029,7 @@ impl Ty {
|
||||
pub fn peel_refs(&self) -> &Self {
|
||||
let mut final_ty = self;
|
||||
while let TyKind::Rptr(_, MutTy { ty, .. }) = &final_ty.kind {
|
||||
final_ty = &ty;
|
||||
final_ty = ty;
|
||||
}
|
||||
final_ty
|
||||
}
|
||||
@ -2004,7 +2066,7 @@ pub enum TyKind {
|
||||
/// "qualified", e.g., `<Vec<T> as SomeTrait>::SomeType`.
|
||||
///
|
||||
/// Type parameters are stored in the `Path` itself.
|
||||
Path(Option<QSelf>, Path),
|
||||
Path(Option<P<QSelf>>, Path),
|
||||
/// A trait object type `Bound1 + Bound2 + Bound3`
|
||||
/// where `Bound` is a trait or a lifetime.
|
||||
TraitObject(GenericBounds, TraitObjectSyntax),
|
||||
@ -2136,7 +2198,7 @@ impl InlineAsmTemplatePiece {
|
||||
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||
pub struct InlineAsmSym {
|
||||
pub id: NodeId,
|
||||
pub qself: Option<QSelf>,
|
||||
pub qself: Option<P<QSelf>>,
|
||||
pub path: Path,
|
||||
}
|
||||
|
||||
@ -2376,9 +2438,9 @@ pub enum FnRetTy {
|
||||
|
||||
impl FnRetTy {
|
||||
pub fn span(&self) -> Span {
|
||||
match *self {
|
||||
FnRetTy::Default(span) => span,
|
||||
FnRetTy::Ty(ref ty) => ty.span,
|
||||
match self {
|
||||
&FnRetTy::Default(span) => span,
|
||||
FnRetTy::Ty(ty) => ty.span,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2457,10 +2519,7 @@ pub struct Variant {
|
||||
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||
pub enum UseTreeKind {
|
||||
/// `use prefix` or `use prefix as rename`
|
||||
///
|
||||
/// The extra `NodeId`s are for HIR lowering, when additional statements are created for each
|
||||
/// namespace.
|
||||
Simple(Option<Ident>, NodeId, NodeId),
|
||||
Simple(Option<Ident>),
|
||||
/// `use prefix::{...}`
|
||||
Nested(Vec<(UseTree, NodeId)>),
|
||||
/// `use prefix::*`
|
||||
@ -2479,8 +2538,8 @@ pub struct UseTree {
|
||||
impl UseTree {
|
||||
pub fn ident(&self) -> Ident {
|
||||
match self.kind {
|
||||
UseTreeKind::Simple(Some(rename), ..) => rename,
|
||||
UseTreeKind::Simple(None, ..) => {
|
||||
UseTreeKind::Simple(Some(rename)) => rename,
|
||||
UseTreeKind::Simple(None) => {
|
||||
self.prefix.segments.last().expect("empty prefix in a simple import").ident
|
||||
}
|
||||
_ => panic!("`UseTree::ident` can only be used on a simple import"),
|
||||
@ -2514,17 +2573,10 @@ impl<D: Decoder> Decodable<D> for AttrId {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
|
||||
pub struct AttrItem {
|
||||
pub path: Path,
|
||||
pub args: MacArgs,
|
||||
pub tokens: Option<LazyAttrTokenStream>,
|
||||
}
|
||||
|
||||
/// A list of attributes.
|
||||
pub type AttrVec = ThinVec<Attribute>;
|
||||
|
||||
/// Metadata associated with an item.
|
||||
/// A syntax-level representation of an attribute.
|
||||
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||
pub struct Attribute {
|
||||
pub kind: AttrKind,
|
||||
@ -2535,12 +2587,6 @@ pub struct Attribute {
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||
pub struct NormalAttr {
|
||||
pub item: AttrItem,
|
||||
pub tokens: Option<LazyAttrTokenStream>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||
pub enum AttrKind {
|
||||
/// A normal attribute.
|
||||
@ -2552,6 +2598,19 @@ pub enum AttrKind {
|
||||
DocComment(CommentKind, Symbol),
|
||||
}
|
||||
|
||||
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||
pub struct NormalAttr {
|
||||
pub item: AttrItem,
|
||||
pub tokens: Option<LazyAttrTokenStream>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
|
||||
pub struct AttrItem {
|
||||
pub path: Path,
|
||||
pub args: AttrArgs,
|
||||
pub tokens: Option<LazyAttrTokenStream>,
|
||||
}
|
||||
|
||||
/// `TraitRef`s appear in impls.
|
||||
///
|
||||
/// Resolution maps each `TraitRef`'s `ref_id` to its defining trait; that's all
|
||||
@ -2640,14 +2699,14 @@ pub enum VariantData {
|
||||
impl VariantData {
|
||||
/// Return the fields of this variant.
|
||||
pub fn fields(&self) -> &[FieldDef] {
|
||||
match *self {
|
||||
VariantData::Struct(ref fields, ..) | VariantData::Tuple(ref fields, _) => fields,
|
||||
match self {
|
||||
VariantData::Struct(fields, ..) | VariantData::Tuple(fields, _) => fields,
|
||||
_ => &[],
|
||||
}
|
||||
}
|
||||
|
||||
/// Return the `NodeId` of this variant's constructor, if it has one.
|
||||
pub fn ctor_id(&self) -> Option<NodeId> {
|
||||
pub fn ctor_node_id(&self) -> Option<NodeId> {
|
||||
match *self {
|
||||
VariantData::Struct(..) => None,
|
||||
VariantData::Tuple(_, id) | VariantData::Unit(id) => Some(id),
|
||||
@ -3029,28 +3088,28 @@ mod size_asserts {
|
||||
static_assert_size!(AssocItemKind, 32);
|
||||
static_assert_size!(Attribute, 32);
|
||||
static_assert_size!(Block, 48);
|
||||
static_assert_size!(Expr, 104);
|
||||
static_assert_size!(ExprKind, 72);
|
||||
static_assert_size!(Expr, 72);
|
||||
static_assert_size!(ExprKind, 40);
|
||||
static_assert_size!(Fn, 184);
|
||||
static_assert_size!(ForeignItem, 96);
|
||||
static_assert_size!(ForeignItemKind, 24);
|
||||
static_assert_size!(GenericArg, 24);
|
||||
static_assert_size!(GenericBound, 88);
|
||||
static_assert_size!(GenericBound, 72);
|
||||
static_assert_size!(Generics, 72);
|
||||
static_assert_size!(Impl, 200);
|
||||
static_assert_size!(Impl, 184);
|
||||
static_assert_size!(Item, 184);
|
||||
static_assert_size!(ItemKind, 112);
|
||||
static_assert_size!(Lit, 48);
|
||||
static_assert_size!(LitKind, 24);
|
||||
static_assert_size!(Local, 72);
|
||||
static_assert_size!(MetaItemLit, 48);
|
||||
static_assert_size!(Param, 40);
|
||||
static_assert_size!(Pat, 120);
|
||||
static_assert_size!(Path, 40);
|
||||
static_assert_size!(Pat, 88);
|
||||
static_assert_size!(Path, 24);
|
||||
static_assert_size!(PathSegment, 24);
|
||||
static_assert_size!(PatKind, 96);
|
||||
static_assert_size!(PatKind, 64);
|
||||
static_assert_size!(Stmt, 32);
|
||||
static_assert_size!(StmtKind, 16);
|
||||
static_assert_size!(Ty, 96);
|
||||
static_assert_size!(TyKind, 72);
|
||||
static_assert_size!(Ty, 64);
|
||||
static_assert_size!(TyKind, 40);
|
||||
// tidy-alphabetical-end
|
||||
}
|
||||
|
||||
@ -1,35 +1,33 @@
|
||||
//! Functions dealing with attributes and meta items.
|
||||
|
||||
use crate::ast;
|
||||
use crate::ast::{AttrId, AttrItem, AttrKind, AttrStyle, Attribute};
|
||||
use crate::ast::{Lit, LitKind};
|
||||
use crate::ast::{MacArgs, MacArgsEq, MacDelimiter, MetaItem, MetaItemKind, NestedMetaItem};
|
||||
use crate::ast::{Path, PathSegment};
|
||||
use crate::ast::{AttrArgs, AttrArgsEq, AttrId, AttrItem, AttrKind, AttrStyle, AttrVec, Attribute};
|
||||
use crate::ast::{DelimArgs, Expr, ExprKind, LitKind, MetaItemLit};
|
||||
use crate::ast::{MacDelimiter, MetaItem, MetaItemKind, NestedMetaItem, NormalAttr};
|
||||
use crate::ast::{Path, PathSegment, StrStyle, DUMMY_NODE_ID};
|
||||
use crate::ptr::P;
|
||||
use crate::token::{self, CommentKind, Delimiter, Token};
|
||||
use crate::tokenstream::{DelimSpan, Spacing, TokenTree};
|
||||
use crate::tokenstream::{LazyAttrTokenStream, TokenStream};
|
||||
use crate::util::comments;
|
||||
|
||||
use rustc_data_structures::sync::WorkerLocal;
|
||||
use rustc_index::bit_set::GrowableBitSet;
|
||||
use rustc_span::source_map::BytePos;
|
||||
use rustc_span::symbol::{sym, Ident, Symbol};
|
||||
use rustc_span::Span;
|
||||
|
||||
use std::cell::Cell;
|
||||
use std::iter;
|
||||
#[cfg(debug_assertions)]
|
||||
use std::ops::BitXor;
|
||||
#[cfg(debug_assertions)]
|
||||
use std::sync::atomic::{AtomicU32, Ordering};
|
||||
use thin_vec::thin_vec;
|
||||
|
||||
pub struct MarkedAttrs(GrowableBitSet<AttrId>);
|
||||
|
||||
impl MarkedAttrs {
|
||||
// We have no idea how many attributes there will be, so just
|
||||
// initiate the vectors with 0 bits. We'll grow them as necessary.
|
||||
pub fn new() -> Self {
|
||||
// We have no idea how many attributes there will be, so just
|
||||
// initiate the vectors with 0 bits. We'll grow them as necessary.
|
||||
MarkedAttrs(GrowableBitSet::new_empty())
|
||||
}
|
||||
|
||||
@ -45,16 +43,16 @@ impl MarkedAttrs {
|
||||
impl NestedMetaItem {
|
||||
/// Returns the `MetaItem` if `self` is a `NestedMetaItem::MetaItem`.
|
||||
pub fn meta_item(&self) -> Option<&MetaItem> {
|
||||
match *self {
|
||||
NestedMetaItem::MetaItem(ref item) => Some(item),
|
||||
match self {
|
||||
NestedMetaItem::MetaItem(item) => Some(item),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the `Lit` if `self` is a `NestedMetaItem::Literal`s.
|
||||
pub fn literal(&self) -> Option<&Lit> {
|
||||
match *self {
|
||||
NestedMetaItem::Literal(ref lit) => Some(lit),
|
||||
/// Returns the `MetaItemLit` if `self` is a `NestedMetaItem::Literal`s.
|
||||
pub fn lit(&self) -> Option<&MetaItemLit> {
|
||||
match self {
|
||||
NestedMetaItem::Lit(lit) => Some(lit),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
@ -79,12 +77,12 @@ impl NestedMetaItem {
|
||||
}
|
||||
|
||||
/// Returns a name and single literal value tuple of the `MetaItem`.
|
||||
pub fn name_value_literal(&self) -> Option<(Symbol, &Lit)> {
|
||||
pub fn name_value_literal(&self) -> Option<(Symbol, &MetaItemLit)> {
|
||||
self.meta_item().and_then(|meta_item| {
|
||||
meta_item.meta_item_list().and_then(|meta_item_list| {
|
||||
if meta_item_list.len() == 1
|
||||
&& let Some(ident) = meta_item.ident()
|
||||
&& let Some(lit) = meta_item_list[0].literal()
|
||||
&& let Some(lit) = meta_item_list[0].lit()
|
||||
{
|
||||
return Some((ident.name, lit));
|
||||
}
|
||||
@ -117,18 +115,18 @@ impl NestedMetaItem {
|
||||
impl Attribute {
|
||||
#[inline]
|
||||
pub fn has_name(&self, name: Symbol) -> bool {
|
||||
match self.kind {
|
||||
AttrKind::Normal(ref normal) => normal.item.path == name,
|
||||
match &self.kind {
|
||||
AttrKind::Normal(normal) => normal.item.path == name,
|
||||
AttrKind::DocComment(..) => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// For a single-segment attribute, returns its name; otherwise, returns `None`.
|
||||
pub fn ident(&self) -> Option<Ident> {
|
||||
match self.kind {
|
||||
AttrKind::Normal(ref normal) => {
|
||||
if normal.item.path.segments.len() == 1 {
|
||||
Some(normal.item.path.segments[0].ident)
|
||||
match &self.kind {
|
||||
AttrKind::Normal(normal) => {
|
||||
if let [ident] = &*normal.item.path.segments {
|
||||
Some(ident.ident)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
@ -141,17 +139,15 @@ impl Attribute {
|
||||
}
|
||||
|
||||
pub fn value_str(&self) -> Option<Symbol> {
|
||||
match self.kind {
|
||||
AttrKind::Normal(ref normal) => {
|
||||
normal.item.meta_kind().and_then(|kind| kind.value_str())
|
||||
}
|
||||
match &self.kind {
|
||||
AttrKind::Normal(normal) => normal.item.meta_kind().and_then(|kind| kind.value_str()),
|
||||
AttrKind::DocComment(..) => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn meta_item_list(&self) -> Option<Vec<NestedMetaItem>> {
|
||||
match self.kind {
|
||||
AttrKind::Normal(ref normal) => match normal.item.meta_kind() {
|
||||
match &self.kind {
|
||||
AttrKind::Normal(normal) => match normal.item.meta_kind() {
|
||||
Some(MetaItemKind::List(list)) => Some(list),
|
||||
_ => None,
|
||||
},
|
||||
@ -161,7 +157,7 @@ impl Attribute {
|
||||
|
||||
pub fn is_word(&self) -> bool {
|
||||
if let AttrKind::Normal(normal) = &self.kind {
|
||||
matches!(normal.item.args, MacArgs::Empty)
|
||||
matches!(normal.item.args, AttrArgs::Empty)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
@ -177,10 +173,12 @@ impl MetaItem {
|
||||
self.ident().unwrap_or_else(Ident::empty).name
|
||||
}
|
||||
|
||||
// Example:
|
||||
// #[attribute(name = "value")]
|
||||
// ^^^^^^^^^^^^^^
|
||||
pub fn name_value_literal(&self) -> Option<&Lit> {
|
||||
/// ```text
|
||||
/// Example:
|
||||
/// #[attribute(name = "value")]
|
||||
/// ^^^^^^^^^^^^^^
|
||||
/// ```
|
||||
pub fn name_value_literal(&self) -> Option<&MetaItemLit> {
|
||||
match &self.kind {
|
||||
MetaItemKind::NameValue(v) => Some(v),
|
||||
_ => None,
|
||||
@ -192,8 +190,8 @@ impl MetaItem {
|
||||
}
|
||||
|
||||
pub fn meta_item_list(&self) -> Option<&[NestedMetaItem]> {
|
||||
match self.kind {
|
||||
MetaItemKind::List(ref l) => Some(&l[..]),
|
||||
match &self.kind {
|
||||
MetaItemKind::List(l) => Some(&**l),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
@ -224,15 +222,11 @@ impl AttrItem {
|
||||
}
|
||||
|
||||
pub fn meta(&self, span: Span) -> Option<MetaItem> {
|
||||
Some(MetaItem {
|
||||
path: self.path.clone(),
|
||||
kind: MetaItemKind::from_mac_args(&self.args)?,
|
||||
span,
|
||||
})
|
||||
Some(MetaItem { path: self.path.clone(), kind: self.meta_kind()?, span })
|
||||
}
|
||||
|
||||
pub fn meta_kind(&self) -> Option<MetaItemKind> {
|
||||
MetaItemKind::from_mac_args(&self.args)
|
||||
MetaItemKind::from_attr_args(&self.args)
|
||||
}
|
||||
}
|
||||
|
||||
@ -269,9 +263,9 @@ impl Attribute {
|
||||
/// * `#[doc = "doc"]` returns `Some("doc")`.
|
||||
/// * `#[doc(...)]` returns `None`.
|
||||
pub fn doc_str(&self) -> Option<Symbol> {
|
||||
match self.kind {
|
||||
AttrKind::DocComment(.., data) => Some(data),
|
||||
AttrKind::Normal(ref normal) if normal.item.path == sym::doc => {
|
||||
match &self.kind {
|
||||
AttrKind::DocComment(.., data) => Some(*data),
|
||||
AttrKind::Normal(normal) if normal.item.path == sym::doc => {
|
||||
normal.item.meta_kind().and_then(|kind| kind.value_str())
|
||||
}
|
||||
_ => None,
|
||||
@ -283,8 +277,8 @@ impl Attribute {
|
||||
}
|
||||
|
||||
pub fn get_normal_item(&self) -> &AttrItem {
|
||||
match self.kind {
|
||||
AttrKind::Normal(ref normal) => &normal.item,
|
||||
match &self.kind {
|
||||
AttrKind::Normal(normal) => &normal.item,
|
||||
AttrKind::DocComment(..) => panic!("unexpected doc comment"),
|
||||
}
|
||||
}
|
||||
@ -298,28 +292,28 @@ impl Attribute {
|
||||
|
||||
/// Extracts the MetaItem from inside this Attribute.
|
||||
pub fn meta(&self) -> Option<MetaItem> {
|
||||
match self.kind {
|
||||
AttrKind::Normal(ref normal) => normal.item.meta(self.span),
|
||||
match &self.kind {
|
||||
AttrKind::Normal(normal) => normal.item.meta(self.span),
|
||||
AttrKind::DocComment(..) => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn meta_kind(&self) -> Option<MetaItemKind> {
|
||||
match self.kind {
|
||||
AttrKind::Normal(ref normal) => normal.item.meta_kind(),
|
||||
match &self.kind {
|
||||
AttrKind::Normal(normal) => normal.item.meta_kind(),
|
||||
AttrKind::DocComment(..) => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn tokens(&self) -> TokenStream {
|
||||
match self.kind {
|
||||
AttrKind::Normal(ref normal) => normal
|
||||
match &self.kind {
|
||||
AttrKind::Normal(normal) => normal
|
||||
.tokens
|
||||
.as_ref()
|
||||
.unwrap_or_else(|| panic!("attribute is missing tokens: {:?}", self))
|
||||
.to_attr_token_stream()
|
||||
.to_tokenstream(),
|
||||
AttrKind::DocComment(comment_kind, data) => TokenStream::new(vec![TokenTree::Token(
|
||||
&AttrKind::DocComment(comment_kind, data) => TokenStream::new(vec![TokenTree::Token(
|
||||
Token::new(token::DocComment(comment_kind, self.style, data), self.span),
|
||||
Spacing::Alone,
|
||||
)]),
|
||||
@ -330,26 +324,13 @@ impl Attribute {
|
||||
/* Constructors */
|
||||
|
||||
pub fn mk_name_value_item_str(ident: Ident, str: Symbol, str_span: Span) -> MetaItem {
|
||||
let lit_kind = LitKind::Str(str, ast::StrStyle::Cooked);
|
||||
mk_name_value_item(ident, lit_kind, str_span)
|
||||
mk_name_value_item(ident, LitKind::Str(str, ast::StrStyle::Cooked), str_span)
|
||||
}
|
||||
|
||||
pub fn mk_name_value_item(ident: Ident, lit_kind: LitKind, lit_span: Span) -> MetaItem {
|
||||
let lit = Lit::from_lit_kind(lit_kind, lit_span);
|
||||
pub fn mk_name_value_item(ident: Ident, kind: LitKind, lit_span: Span) -> MetaItem {
|
||||
let lit = MetaItemLit { token_lit: kind.to_token_lit(), kind, span: lit_span };
|
||||
let span = ident.span.to(lit_span);
|
||||
MetaItem { path: Path::from_ident(ident), span, kind: MetaItemKind::NameValue(lit) }
|
||||
}
|
||||
|
||||
pub fn mk_list_item(ident: Ident, items: Vec<NestedMetaItem>) -> MetaItem {
|
||||
MetaItem { path: Path::from_ident(ident), span: ident.span, kind: MetaItemKind::List(items) }
|
||||
}
|
||||
|
||||
pub fn mk_word_item(ident: Ident) -> MetaItem {
|
||||
MetaItem { path: Path::from_ident(ident), span: ident.span, kind: MetaItemKind::Word }
|
||||
}
|
||||
|
||||
pub fn mk_nested_word_item(ident: Ident) -> NestedMetaItem {
|
||||
NestedMetaItem::MetaItem(mk_word_item(ident))
|
||||
MetaItem { path: Path::from_ident(ident), kind: MetaItemKind::NameValue(lit), span }
|
||||
}
|
||||
|
||||
pub struct AttrIdGenerator(WorkerLocal<Cell<u32>>);
|
||||
@ -393,7 +374,7 @@ pub fn mk_attr(
|
||||
g: &AttrIdGenerator,
|
||||
style: AttrStyle,
|
||||
path: Path,
|
||||
args: MacArgs,
|
||||
args: AttrArgs,
|
||||
span: Span,
|
||||
) -> Attribute {
|
||||
mk_attr_from_item(g, AttrItem { path, args, tokens: None }, None, style, span)
|
||||
@ -407,21 +388,58 @@ pub fn mk_attr_from_item(
|
||||
span: Span,
|
||||
) -> Attribute {
|
||||
Attribute {
|
||||
kind: AttrKind::Normal(P(ast::NormalAttr { item, tokens })),
|
||||
kind: AttrKind::Normal(P(NormalAttr { item, tokens })),
|
||||
id: g.mk_attr_id(),
|
||||
style,
|
||||
span,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns an inner attribute with the given value and span.
|
||||
pub fn mk_attr_inner(g: &AttrIdGenerator, item: MetaItem) -> Attribute {
|
||||
mk_attr(g, AttrStyle::Inner, item.path, item.kind.mac_args(item.span), item.span)
|
||||
pub fn mk_attr_word(g: &AttrIdGenerator, style: AttrStyle, name: Symbol, span: Span) -> Attribute {
|
||||
let path = Path::from_ident(Ident::new(name, span));
|
||||
let args = AttrArgs::Empty;
|
||||
mk_attr(g, style, path, args, span)
|
||||
}
|
||||
|
||||
/// Returns an outer attribute with the given value and span.
|
||||
pub fn mk_attr_outer(g: &AttrIdGenerator, item: MetaItem) -> Attribute {
|
||||
mk_attr(g, AttrStyle::Outer, item.path, item.kind.mac_args(item.span), item.span)
|
||||
pub fn mk_attr_name_value_str(
|
||||
g: &AttrIdGenerator,
|
||||
style: AttrStyle,
|
||||
name: Symbol,
|
||||
val: Symbol,
|
||||
span: Span,
|
||||
) -> Attribute {
|
||||
let lit = LitKind::Str(val, StrStyle::Cooked).to_token_lit();
|
||||
let expr = P(Expr {
|
||||
id: DUMMY_NODE_ID,
|
||||
kind: ExprKind::Lit(lit),
|
||||
span,
|
||||
attrs: AttrVec::new(),
|
||||
tokens: None,
|
||||
});
|
||||
let path = Path::from_ident(Ident::new(name, span));
|
||||
let args = AttrArgs::Eq(span, AttrArgsEq::Ast(expr));
|
||||
mk_attr(g, style, path, args, span)
|
||||
}
|
||||
|
||||
pub fn mk_attr_nested_word(
|
||||
g: &AttrIdGenerator,
|
||||
style: AttrStyle,
|
||||
outer: Symbol,
|
||||
inner: Symbol,
|
||||
span: Span,
|
||||
) -> Attribute {
|
||||
let inner_tokens = TokenStream::new(vec![TokenTree::Token(
|
||||
Token::from_ast_ident(Ident::new(inner, span)),
|
||||
Spacing::Alone,
|
||||
)]);
|
||||
let outer_ident = Ident::new(outer, span);
|
||||
let path = Path::from_ident(outer_ident);
|
||||
let attr_args = AttrArgs::Delimited(DelimArgs {
|
||||
dspan: DelimSpan::from_single(span),
|
||||
delim: MacDelimiter::Parenthesis,
|
||||
tokens: inner_tokens,
|
||||
});
|
||||
mk_attr(g, style, path, attr_args, span)
|
||||
}
|
||||
|
||||
pub fn mk_doc_comment(
|
||||
@ -439,23 +457,6 @@ pub fn list_contains_name(items: &[NestedMetaItem], name: Symbol) -> bool {
|
||||
}
|
||||
|
||||
impl MetaItem {
|
||||
fn token_trees(&self) -> Vec<TokenTree> {
|
||||
let mut idents = vec![];
|
||||
let mut last_pos = BytePos(0_u32);
|
||||
for (i, segment) in self.path.segments.iter().enumerate() {
|
||||
let is_first = i == 0;
|
||||
if !is_first {
|
||||
let mod_sep_span =
|
||||
Span::new(last_pos, segment.ident.span.lo(), segment.ident.span.ctxt(), None);
|
||||
idents.push(TokenTree::token_alone(token::ModSep, mod_sep_span));
|
||||
}
|
||||
idents.push(TokenTree::Token(Token::from_ast_ident(segment.ident), Spacing::Alone));
|
||||
last_pos = segment.ident.span.hi();
|
||||
}
|
||||
idents.extend(self.kind.token_trees(self.span));
|
||||
idents
|
||||
}
|
||||
|
||||
fn from_tokens<I>(tokens: &mut iter::Peekable<I>) -> Option<MetaItem>
|
||||
where
|
||||
I: Iterator<Item = TokenTree>,
|
||||
@ -471,12 +472,12 @@ impl MetaItem {
|
||||
tokens.peek()
|
||||
{
|
||||
tokens.next();
|
||||
vec![PathSegment::from_ident(Ident::new(name, span))]
|
||||
thin_vec![PathSegment::from_ident(Ident::new(name, span))]
|
||||
} else {
|
||||
break 'arm Path::from_ident(Ident::new(name, span));
|
||||
}
|
||||
} else {
|
||||
vec![PathSegment::path_root(span)]
|
||||
thin_vec![PathSegment::path_root(span)]
|
||||
};
|
||||
loop {
|
||||
if let Some(TokenTree::Token(Token { kind: token::Ident(name, _), span }, _)) =
|
||||
@ -497,17 +498,17 @@ impl MetaItem {
|
||||
let span = span.with_hi(segments.last().unwrap().ident.span.hi());
|
||||
Path { span, segments, tokens: None }
|
||||
}
|
||||
Some(TokenTree::Token(Token { kind: token::Interpolated(nt), .. }, _)) => match *nt {
|
||||
token::Nonterminal::NtMeta(ref item) => return item.meta(item.path.span),
|
||||
token::Nonterminal::NtPath(ref path) => (**path).clone(),
|
||||
Some(TokenTree::Token(Token { kind: token::Interpolated(nt), .. }, _)) => match &*nt {
|
||||
token::Nonterminal::NtMeta(item) => return item.meta(item.path.span),
|
||||
token::Nonterminal::NtPath(path) => (**path).clone(),
|
||||
_ => return None,
|
||||
},
|
||||
_ => return None,
|
||||
};
|
||||
let list_closing_paren_pos = tokens.peek().map(|tt| tt.span().hi());
|
||||
let kind = MetaItemKind::from_tokens(tokens)?;
|
||||
let hi = match kind {
|
||||
MetaItemKind::NameValue(ref lit) => lit.span.hi(),
|
||||
let hi = match &kind {
|
||||
MetaItemKind::NameValue(lit) => lit.span.hi(),
|
||||
MetaItemKind::List(..) => list_closing_paren_pos.unwrap_or(path.span.hi()),
|
||||
_ => path.span.hi(),
|
||||
};
|
||||
@ -519,70 +520,14 @@ impl MetaItem {
|
||||
impl MetaItemKind {
|
||||
pub fn value_str(&self) -> Option<Symbol> {
|
||||
match self {
|
||||
MetaItemKind::NameValue(ref v) => match v.kind {
|
||||
LitKind::Str(ref s, _) => Some(*s),
|
||||
MetaItemKind::NameValue(v) => match v.kind {
|
||||
LitKind::Str(s, _) => Some(s),
|
||||
_ => None,
|
||||
},
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn mac_args(&self, span: Span) -> MacArgs {
|
||||
match self {
|
||||
MetaItemKind::Word => MacArgs::Empty,
|
||||
MetaItemKind::NameValue(lit) => {
|
||||
let expr = P(ast::Expr {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
kind: ast::ExprKind::Lit(lit.clone()),
|
||||
span: lit.span,
|
||||
attrs: ast::AttrVec::new(),
|
||||
tokens: None,
|
||||
});
|
||||
MacArgs::Eq(span, MacArgsEq::Ast(expr))
|
||||
}
|
||||
MetaItemKind::List(list) => {
|
||||
let mut tts = Vec::new();
|
||||
for (i, item) in list.iter().enumerate() {
|
||||
if i > 0 {
|
||||
tts.push(TokenTree::token_alone(token::Comma, span));
|
||||
}
|
||||
tts.extend(item.token_trees())
|
||||
}
|
||||
MacArgs::Delimited(
|
||||
DelimSpan::from_single(span),
|
||||
MacDelimiter::Parenthesis,
|
||||
TokenStream::new(tts),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn token_trees(&self, span: Span) -> Vec<TokenTree> {
|
||||
match *self {
|
||||
MetaItemKind::Word => vec![],
|
||||
MetaItemKind::NameValue(ref lit) => {
|
||||
vec![
|
||||
TokenTree::token_alone(token::Eq, span),
|
||||
TokenTree::Token(lit.to_token(), Spacing::Alone),
|
||||
]
|
||||
}
|
||||
MetaItemKind::List(ref list) => {
|
||||
let mut tokens = Vec::new();
|
||||
for (i, item) in list.iter().enumerate() {
|
||||
if i > 0 {
|
||||
tokens.push(TokenTree::token_alone(token::Comma, span));
|
||||
}
|
||||
tokens.extend(item.token_trees())
|
||||
}
|
||||
vec![TokenTree::Delimited(
|
||||
DelimSpan::from_single(span),
|
||||
Delimiter::Parenthesis,
|
||||
TokenStream::new(tokens),
|
||||
)]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn list_from_tokens(tokens: TokenStream) -> Option<MetaItemKind> {
|
||||
let mut tokens = tokens.into_trees().peekable();
|
||||
let mut result = Vec::new();
|
||||
@ -605,24 +550,31 @@ impl MetaItemKind {
|
||||
MetaItemKind::name_value_from_tokens(&mut inner_tokens.into_trees())
|
||||
}
|
||||
Some(TokenTree::Token(token, _)) => {
|
||||
Lit::from_token(&token).ok().map(MetaItemKind::NameValue)
|
||||
MetaItemLit::from_token(&token).map(MetaItemKind::NameValue)
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn from_mac_args(args: &MacArgs) -> Option<MetaItemKind> {
|
||||
fn from_attr_args(args: &AttrArgs) -> Option<MetaItemKind> {
|
||||
match args {
|
||||
MacArgs::Empty => Some(MetaItemKind::Word),
|
||||
MacArgs::Delimited(_, MacDelimiter::Parenthesis, tokens) => {
|
||||
MetaItemKind::list_from_tokens(tokens.clone())
|
||||
}
|
||||
MacArgs::Delimited(..) => None,
|
||||
MacArgs::Eq(_, MacArgsEq::Ast(expr)) => match &expr.kind {
|
||||
ast::ExprKind::Lit(lit) => Some(MetaItemKind::NameValue(lit.clone())),
|
||||
AttrArgs::Empty => Some(MetaItemKind::Word),
|
||||
AttrArgs::Delimited(DelimArgs {
|
||||
dspan: _,
|
||||
delim: MacDelimiter::Parenthesis,
|
||||
tokens,
|
||||
}) => MetaItemKind::list_from_tokens(tokens.clone()),
|
||||
AttrArgs::Delimited(..) => None,
|
||||
AttrArgs::Eq(_, AttrArgsEq::Ast(expr)) => match expr.kind {
|
||||
ExprKind::Lit(token_lit) => {
|
||||
// Turn failures to `None`, we'll get parse errors elsewhere.
|
||||
MetaItemLit::from_token_lit(token_lit, expr.span)
|
||||
.ok()
|
||||
.map(|lit| MetaItemKind::NameValue(lit))
|
||||
}
|
||||
_ => None,
|
||||
},
|
||||
MacArgs::Eq(_, MacArgsEq::Hir(lit)) => Some(MetaItemKind::NameValue(lit.clone())),
|
||||
AttrArgs::Eq(_, AttrArgsEq::Hir(lit)) => Some(MetaItemKind::NameValue(lit.clone())),
|
||||
}
|
||||
}
|
||||
|
||||
@ -647,18 +599,9 @@ impl MetaItemKind {
|
||||
|
||||
impl NestedMetaItem {
|
||||
pub fn span(&self) -> Span {
|
||||
match *self {
|
||||
NestedMetaItem::MetaItem(ref item) => item.span,
|
||||
NestedMetaItem::Literal(ref lit) => lit.span,
|
||||
}
|
||||
}
|
||||
|
||||
fn token_trees(&self) -> Vec<TokenTree> {
|
||||
match *self {
|
||||
NestedMetaItem::MetaItem(ref item) => item.token_trees(),
|
||||
NestedMetaItem::Literal(ref lit) => {
|
||||
vec![TokenTree::Token(lit.to_token(), Spacing::Alone)]
|
||||
}
|
||||
match self {
|
||||
NestedMetaItem::MetaItem(item) => item.span,
|
||||
NestedMetaItem::Lit(lit) => lit.span,
|
||||
}
|
||||
}
|
||||
|
||||
@ -668,10 +611,10 @@ impl NestedMetaItem {
|
||||
{
|
||||
match tokens.peek() {
|
||||
Some(TokenTree::Token(token, _))
|
||||
if let Ok(lit) = Lit::from_token(token) =>
|
||||
if let Some(lit) = MetaItemLit::from_token(token) =>
|
||||
{
|
||||
tokens.next();
|
||||
return Some(NestedMetaItem::Literal(lit));
|
||||
return Some(NestedMetaItem::Lit(lit));
|
||||
}
|
||||
Some(TokenTree::Delimited(_, Delimiter::Invisible, inner_tokens)) => {
|
||||
let inner_tokens = inner_tokens.clone();
|
||||
|
||||
@ -29,6 +29,7 @@ extern crate rustc_macros;
|
||||
extern crate tracing;
|
||||
|
||||
pub mod util {
|
||||
pub mod case;
|
||||
pub mod classify;
|
||||
pub mod comments;
|
||||
pub mod literal;
|
||||
|
||||
@ -194,7 +194,7 @@ pub trait MutVisitor: Sized {
|
||||
noop_visit_path(p, self);
|
||||
}
|
||||
|
||||
fn visit_qself(&mut self, qs: &mut Option<QSelf>) {
|
||||
fn visit_qself(&mut self, qs: &mut Option<P<QSelf>>) {
|
||||
noop_visit_qself(qs, self);
|
||||
}
|
||||
|
||||
@ -367,23 +367,27 @@ pub fn visit_fn_sig<T: MutVisitor>(FnSig { header, decl, span }: &mut FnSig, vis
|
||||
}
|
||||
|
||||
// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
|
||||
pub fn visit_mac_args<T: MutVisitor>(args: &mut MacArgs, vis: &mut T) {
|
||||
pub fn visit_attr_args<T: MutVisitor>(args: &mut AttrArgs, vis: &mut T) {
|
||||
match args {
|
||||
MacArgs::Empty => {}
|
||||
MacArgs::Delimited(dspan, _delim, tokens) => {
|
||||
visit_delim_span(dspan, vis);
|
||||
visit_tts(tokens, vis);
|
||||
}
|
||||
MacArgs::Eq(eq_span, MacArgsEq::Ast(expr)) => {
|
||||
AttrArgs::Empty => {}
|
||||
AttrArgs::Delimited(args) => visit_delim_args(args, vis),
|
||||
AttrArgs::Eq(eq_span, AttrArgsEq::Ast(expr)) => {
|
||||
vis.visit_span(eq_span);
|
||||
vis.visit_expr(expr);
|
||||
}
|
||||
MacArgs::Eq(_, MacArgsEq::Hir(lit)) => {
|
||||
AttrArgs::Eq(_, AttrArgsEq::Hir(lit)) => {
|
||||
unreachable!("in literal form when visiting mac args eq: {:?}", lit)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
|
||||
pub fn visit_delim_args<T: MutVisitor>(args: &mut DelimArgs, vis: &mut T) {
|
||||
let DelimArgs { dspan, delim: _, tokens } = args;
|
||||
visit_delim_span(dspan, vis);
|
||||
visit_tts(tokens, vis);
|
||||
}
|
||||
|
||||
pub fn visit_delim_span<T: MutVisitor>(dspan: &mut DelimSpan, vis: &mut T) {
|
||||
vis.visit_span(&mut dspan.open);
|
||||
vis.visit_span(&mut dspan.close);
|
||||
@ -406,11 +410,7 @@ pub fn noop_visit_use_tree<T: MutVisitor>(use_tree: &mut UseTree, vis: &mut T) {
|
||||
let UseTree { prefix, kind, span } = use_tree;
|
||||
vis.visit_path(prefix);
|
||||
match kind {
|
||||
UseTreeKind::Simple(rename, id1, id2) => {
|
||||
visit_opt(rename, |rename| vis.visit_ident(rename));
|
||||
vis.visit_id(id1);
|
||||
vis.visit_id(id2);
|
||||
}
|
||||
UseTreeKind::Simple(rename) => visit_opt(rename, |rename| vis.visit_ident(rename)),
|
||||
UseTreeKind::Nested(items) => {
|
||||
for (tree, id) in items {
|
||||
vis.visit_use_tree(tree);
|
||||
@ -439,15 +439,15 @@ pub fn noop_visit_constraint<T: MutVisitor>(
|
||||
) {
|
||||
vis.visit_id(id);
|
||||
vis.visit_ident(ident);
|
||||
if let Some(ref mut gen_args) = gen_args {
|
||||
if let Some(gen_args) = gen_args {
|
||||
vis.visit_generic_args(gen_args);
|
||||
}
|
||||
match kind {
|
||||
AssocConstraintKind::Equality { ref mut term } => match term {
|
||||
AssocConstraintKind::Equality { term } => match term {
|
||||
Term::Ty(ty) => vis.visit_ty(ty),
|
||||
Term::Const(c) => vis.visit_anon_const(c),
|
||||
},
|
||||
AssocConstraintKind::Bound { ref mut bounds } => visit_bounds(bounds, vis),
|
||||
AssocConstraintKind::Bound { bounds } => visit_bounds(bounds, vis),
|
||||
}
|
||||
vis.visit_span(span);
|
||||
}
|
||||
@ -529,8 +529,9 @@ pub fn noop_visit_path<T: MutVisitor>(Path { segments, span, tokens }: &mut Path
|
||||
visit_lazy_tts(tokens, vis);
|
||||
}
|
||||
|
||||
pub fn noop_visit_qself<T: MutVisitor>(qself: &mut Option<QSelf>, vis: &mut T) {
|
||||
visit_opt(qself, |QSelf { ty, path_span, position: _ }| {
|
||||
pub fn noop_visit_qself<T: MutVisitor>(qself: &mut Option<P<QSelf>>, vis: &mut T) {
|
||||
visit_opt(qself, |qself| {
|
||||
let QSelf { ty, path_span, position: _ } = &mut **qself;
|
||||
vis.visit_ty(ty);
|
||||
vis.visit_span(path_span);
|
||||
})
|
||||
@ -600,7 +601,7 @@ pub fn noop_visit_attribute<T: MutVisitor>(attr: &mut Attribute, vis: &mut T) {
|
||||
let NormalAttr { item: AttrItem { path, args, tokens }, tokens: attr_tokens } =
|
||||
&mut **normal;
|
||||
vis.visit_path(path);
|
||||
visit_mac_args(args, vis);
|
||||
visit_attr_args(args, vis);
|
||||
visit_lazy_tts(tokens, vis);
|
||||
visit_lazy_tts(attr_tokens, vis);
|
||||
}
|
||||
@ -612,18 +613,18 @@ pub fn noop_visit_attribute<T: MutVisitor>(attr: &mut Attribute, vis: &mut T) {
|
||||
pub fn noop_visit_mac<T: MutVisitor>(mac: &mut MacCall, vis: &mut T) {
|
||||
let MacCall { path, args, prior_type_ascription: _ } = mac;
|
||||
vis.visit_path(path);
|
||||
visit_mac_args(args, vis);
|
||||
visit_delim_args(args, vis);
|
||||
}
|
||||
|
||||
pub fn noop_visit_macro_def<T: MutVisitor>(macro_def: &mut MacroDef, vis: &mut T) {
|
||||
let MacroDef { body, macro_rules: _ } = macro_def;
|
||||
visit_mac_args(body, vis);
|
||||
visit_delim_args(body, vis);
|
||||
}
|
||||
|
||||
pub fn noop_visit_meta_list_item<T: MutVisitor>(li: &mut NestedMetaItem, vis: &mut T) {
|
||||
match li {
|
||||
NestedMetaItem::MetaItem(mi) => vis.visit_meta_item(mi),
|
||||
NestedMetaItem::Literal(_lit) => {}
|
||||
NestedMetaItem::Lit(_lit) => {}
|
||||
}
|
||||
}
|
||||
|
||||
@ -720,10 +721,10 @@ pub fn visit_lazy_tts<T: MutVisitor>(lazy_tts: &mut Option<LazyAttrTokenStream>,
|
||||
visit_lazy_tts_opt_mut(lazy_tts.as_mut(), vis);
|
||||
}
|
||||
|
||||
/// Applies ident visitor if it's an ident; applies other visits to interpolated nodes.
|
||||
/// In practice the ident part is not actually used by specific visitors right now,
|
||||
/// but there's a test below checking that it works.
|
||||
// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
|
||||
// Applies ident visitor if it's an ident; applies other visits to interpolated nodes.
|
||||
// In practice the ident part is not actually used by specific visitors right now,
|
||||
// but there's a test below checking that it works.
|
||||
pub fn visit_token<T: MutVisitor>(t: &mut Token, vis: &mut T) {
|
||||
let Token { kind, span } = t;
|
||||
match kind {
|
||||
@ -735,8 +736,7 @@ pub fn visit_token<T: MutVisitor>(t: &mut Token, vis: &mut T) {
|
||||
return; // Avoid visiting the span for the second time.
|
||||
}
|
||||
token::Interpolated(nt) => {
|
||||
let mut nt = Lrc::make_mut(nt);
|
||||
visit_nonterminal(&mut nt, vis);
|
||||
visit_nonterminal(Lrc::make_mut(nt), vis);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
@ -791,7 +791,7 @@ pub fn visit_nonterminal<T: MutVisitor>(nt: &mut token::Nonterminal, vis: &mut T
|
||||
token::NtMeta(item) => {
|
||||
let AttrItem { path, args, tokens } = item.deref_mut();
|
||||
vis.visit_path(path);
|
||||
visit_mac_args(args, vis);
|
||||
visit_attr_args(args, vis);
|
||||
visit_lazy_tts(tokens, vis);
|
||||
}
|
||||
token::NtPath(path) => vis.visit_path(path),
|
||||
@ -879,7 +879,7 @@ pub fn noop_flat_map_generic_param<T: MutVisitor>(
|
||||
let GenericParam { id, ident, attrs, bounds, kind, colon_span, is_placeholder: _ } = &mut param;
|
||||
vis.visit_id(id);
|
||||
vis.visit_ident(ident);
|
||||
if let Some(ref mut colon_span) = colon_span {
|
||||
if let Some(colon_span) = colon_span {
|
||||
vis.visit_span(colon_span);
|
||||
}
|
||||
visit_attrs(attrs, vis);
|
||||
@ -1303,12 +1303,17 @@ pub fn noop_visit_expr<T: MutVisitor>(
|
||||
vis.visit_expr(f);
|
||||
visit_exprs(args, vis);
|
||||
}
|
||||
ExprKind::MethodCall(PathSegment { ident, id, args }, receiver, exprs, span) => {
|
||||
ExprKind::MethodCall(box MethodCall {
|
||||
seg: PathSegment { ident, id, args: seg_args },
|
||||
receiver,
|
||||
args: call_args,
|
||||
span,
|
||||
}) => {
|
||||
vis.visit_ident(ident);
|
||||
vis.visit_id(id);
|
||||
visit_opt(args, |args| vis.visit_generic_args(args));
|
||||
visit_opt(seg_args, |args| vis.visit_generic_args(args));
|
||||
vis.visit_method_receiver_expr(receiver);
|
||||
visit_exprs(exprs, vis);
|
||||
visit_exprs(call_args, vis);
|
||||
vis.visit_span(span);
|
||||
}
|
||||
ExprKind::Binary(_binop, lhs, rhs) => {
|
||||
@ -1345,20 +1350,30 @@ pub fn noop_visit_expr<T: MutVisitor>(
|
||||
vis.visit_block(body);
|
||||
visit_opt(label, |label| vis.visit_label(label));
|
||||
}
|
||||
ExprKind::Loop(body, label) => {
|
||||
ExprKind::Loop(body, label, span) => {
|
||||
vis.visit_block(body);
|
||||
visit_opt(label, |label| vis.visit_label(label));
|
||||
vis.visit_span(span);
|
||||
}
|
||||
ExprKind::Match(expr, arms) => {
|
||||
vis.visit_expr(expr);
|
||||
arms.flat_map_in_place(|arm| vis.flat_map_arm(arm));
|
||||
}
|
||||
ExprKind::Closure(binder, _capture_by, asyncness, _movability, decl, body, span) => {
|
||||
ExprKind::Closure(box Closure {
|
||||
binder,
|
||||
capture_clause: _,
|
||||
asyncness,
|
||||
movability: _,
|
||||
fn_decl,
|
||||
body,
|
||||
fn_decl_span,
|
||||
fn_arg_span: _,
|
||||
}) => {
|
||||
vis.visit_closure_binder(binder);
|
||||
vis.visit_asyncness(asyncness);
|
||||
vis.visit_fn_decl(decl);
|
||||
vis.visit_fn_decl(fn_decl);
|
||||
vis.visit_expr(body);
|
||||
vis.visit_span(span);
|
||||
vis.visit_span(fn_decl_span);
|
||||
}
|
||||
ExprKind::Block(blk, label) => {
|
||||
vis.visit_block(blk);
|
||||
@ -1428,7 +1443,7 @@ pub fn noop_visit_expr<T: MutVisitor>(
|
||||
}
|
||||
ExprKind::Try(expr) => vis.visit_expr(expr),
|
||||
ExprKind::TryBlock(body) => vis.visit_block(body),
|
||||
ExprKind::Lit(_) | ExprKind::Err => {}
|
||||
ExprKind::Lit(_) | ExprKind::IncludedBytes(..) | ExprKind::Err => {}
|
||||
}
|
||||
vis.visit_id(id);
|
||||
vis.visit_span(span);
|
||||
|
||||
@ -5,6 +5,7 @@ pub use TokenKind::*;
|
||||
|
||||
use crate::ast;
|
||||
use crate::ptr::P;
|
||||
use crate::util::case::Case;
|
||||
|
||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
@ -58,13 +59,17 @@ pub enum Delimiter {
|
||||
Invisible,
|
||||
}
|
||||
|
||||
// Note that the suffix is *not* considered when deciding the `LitKind` in this
|
||||
// type. This means that float literals like `1f32` are classified by this type
|
||||
// as `Int`. Only upon conversion to `ast::LitKind` will such a literal be
|
||||
// given the `Float` kind.
|
||||
#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
|
||||
pub enum LitKind {
|
||||
Bool, // AST only, must never appear in a `Token`
|
||||
Byte,
|
||||
Char,
|
||||
Integer,
|
||||
Float,
|
||||
Integer, // e.g. `1`, `1u8`, `1f32`
|
||||
Float, // e.g. `1.`, `1.0`, `1e3f32`
|
||||
Str,
|
||||
StrRaw(u8), // raw string delimited by `n` hash symbols
|
||||
ByteStr,
|
||||
@ -80,6 +85,42 @@ pub struct Lit {
|
||||
pub suffix: Option<Symbol>,
|
||||
}
|
||||
|
||||
impl Lit {
|
||||
pub fn new(kind: LitKind, symbol: Symbol, suffix: Option<Symbol>) -> Lit {
|
||||
Lit { kind, symbol, suffix }
|
||||
}
|
||||
|
||||
/// Returns `true` if this is semantically a float literal. This includes
|
||||
/// ones like `1f32` that have an `Integer` kind but a float suffix.
|
||||
pub fn is_semantic_float(&self) -> bool {
|
||||
match self.kind {
|
||||
LitKind::Float => true,
|
||||
LitKind::Integer => match self.suffix {
|
||||
Some(sym) => sym == sym::f32 || sym == sym::f64,
|
||||
None => false,
|
||||
},
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Keep this in sync with `Token::can_begin_literal_or_bool` excluding unary negation.
|
||||
pub fn from_token(token: &Token) -> Option<Lit> {
|
||||
match token.uninterpolate().kind {
|
||||
Ident(name, false) if name.is_bool_lit() => {
|
||||
Some(Lit::new(Bool, name, None))
|
||||
}
|
||||
Literal(token_lit) => Some(token_lit),
|
||||
Interpolated(ref nt)
|
||||
if let NtExpr(expr) | NtLiteral(expr) = &**nt
|
||||
&& let ast::ExprKind::Lit(token_lit) = expr.kind =>
|
||||
{
|
||||
Some(token_lit.clone())
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Lit {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let Lit { kind, symbol, suffix } = *self;
|
||||
@ -138,12 +179,6 @@ impl LitKind {
|
||||
}
|
||||
}
|
||||
|
||||
impl Lit {
|
||||
pub fn new(kind: LitKind, symbol: Symbol, suffix: Option<Symbol>) -> Lit {
|
||||
Lit { kind, symbol, suffix }
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ident_can_begin_expr(name: Symbol, span: Span, is_raw: bool) -> bool {
|
||||
let ident_token = Token::new(Ident(name, is_raw), span);
|
||||
|
||||
@ -267,9 +302,9 @@ impl TokenKind {
|
||||
Literal(Lit::new(kind, symbol, suffix))
|
||||
}
|
||||
|
||||
// An approximation to proc-macro-style single-character operators used by rustc parser.
|
||||
// If the operator token can be broken into two tokens, the first of which is single-character,
|
||||
// then this function performs that operation, otherwise it returns `None`.
|
||||
/// An approximation to proc-macro-style single-character operators used by rustc parser.
|
||||
/// If the operator token can be broken into two tokens, the first of which is single-character,
|
||||
/// then this function performs that operation, otherwise it returns `None`.
|
||||
pub fn break_two_token_op(&self) -> Option<(TokenKind, TokenKind)> {
|
||||
Some(match *self {
|
||||
Le => (Lt, Eq),
|
||||
@ -503,10 +538,10 @@ impl Token {
|
||||
}
|
||||
}
|
||||
|
||||
// A convenience function for matching on identifiers during parsing.
|
||||
// Turns interpolated identifier (`$i: ident`) or lifetime (`$l: lifetime`) token
|
||||
// into the regular identifier or lifetime token it refers to,
|
||||
// otherwise returns the original token.
|
||||
/// A convenience function for matching on identifiers during parsing.
|
||||
/// Turns interpolated identifier (`$i: ident`) or lifetime (`$l: lifetime`) token
|
||||
/// into the regular identifier or lifetime token it refers to,
|
||||
/// otherwise returns the original token.
|
||||
pub fn uninterpolate(&self) -> Cow<'_, Token> {
|
||||
match &self.kind {
|
||||
Interpolated(nt) => match **nt {
|
||||
@ -566,9 +601,10 @@ impl Token {
|
||||
|
||||
/// Returns `true` if the token is an interpolated path.
|
||||
fn is_path(&self) -> bool {
|
||||
if let Interpolated(ref nt) = self.kind && let NtPath(..) = **nt {
|
||||
if let Interpolated(nt) = &self.kind && let NtPath(..) = **nt {
|
||||
return true;
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
|
||||
@ -576,7 +612,7 @@ impl Token {
|
||||
/// That is, is this a pre-parsed expression dropped into the token stream
|
||||
/// (which happens while parsing the result of macro expansion)?
|
||||
pub fn is_whole_expr(&self) -> bool {
|
||||
if let Interpolated(ref nt) = self.kind
|
||||
if let Interpolated(nt) = &self.kind
|
||||
&& let NtExpr(_) | NtLiteral(_) | NtPath(_) | NtBlock(_) = **nt
|
||||
{
|
||||
return true;
|
||||
@ -585,11 +621,12 @@ impl Token {
|
||||
false
|
||||
}
|
||||
|
||||
// Is the token an interpolated block (`$b:block`)?
|
||||
/// Is the token an interpolated block (`$b:block`)?
|
||||
pub fn is_whole_block(&self) -> bool {
|
||||
if let Interpolated(ref nt) = self.kind && let NtBlock(..) = **nt {
|
||||
if let Interpolated(nt) = &self.kind && let NtBlock(..) = **nt {
|
||||
return true;
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
|
||||
@ -615,12 +652,21 @@ impl Token {
|
||||
self.is_non_raw_ident_where(|id| id.name == kw)
|
||||
}
|
||||
|
||||
/// Returns `true` if the token is a given keyword, `kw` or if `case` is `Insensitive` and this token is an identifier equal to `kw` ignoring the case.
|
||||
pub fn is_keyword_case(&self, kw: Symbol, case: Case) -> bool {
|
||||
self.is_keyword(kw)
|
||||
|| (case == Case::Insensitive
|
||||
&& self.is_non_raw_ident_where(|id| {
|
||||
id.name.as_str().to_lowercase() == kw.as_str().to_lowercase()
|
||||
}))
|
||||
}
|
||||
|
||||
pub fn is_path_segment_keyword(&self) -> bool {
|
||||
self.is_non_raw_ident_where(Ident::is_path_segment_keyword)
|
||||
}
|
||||
|
||||
// Returns true for reserved identifiers used internally for elided lifetimes,
|
||||
// unnamed method parameters, crate root module, error recovery etc.
|
||||
/// Returns true for reserved identifiers used internally for elided lifetimes,
|
||||
/// unnamed method parameters, crate root module, error recovery etc.
|
||||
pub fn is_special_ident(&self) -> bool {
|
||||
self.is_non_raw_ident_where(Ident::is_special)
|
||||
}
|
||||
|
||||
@ -64,7 +64,7 @@ impl TokenTree {
|
||||
match (self, other) {
|
||||
(TokenTree::Token(token, _), TokenTree::Token(token2, _)) => token.kind == token2.kind,
|
||||
(TokenTree::Delimited(_, delim, tts), TokenTree::Delimited(_, delim2, tts2)) => {
|
||||
delim == delim2 && tts.eq_unspanned(&tts2)
|
||||
delim == delim2 && tts.eq_unspanned(tts2)
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
@ -86,12 +86,12 @@ impl TokenTree {
|
||||
}
|
||||
}
|
||||
|
||||
// Create a `TokenTree::Token` with alone spacing.
|
||||
/// Create a `TokenTree::Token` with alone spacing.
|
||||
pub fn token_alone(kind: TokenKind, span: Span) -> TokenTree {
|
||||
TokenTree::Token(Token::new(kind, span), Spacing::Alone)
|
||||
}
|
||||
|
||||
// Create a `TokenTree::Token` with joint spacing.
|
||||
/// Create a `TokenTree::Token` with joint spacing.
|
||||
pub fn token_joint(kind: TokenKind, span: Span) -> TokenTree {
|
||||
TokenTree::Token(Token::new(kind, span), Spacing::Joint)
|
||||
}
|
||||
@ -402,7 +402,7 @@ impl TokenStream {
|
||||
let mut t1 = self.trees();
|
||||
let mut t2 = other.trees();
|
||||
for (t1, t2) in iter::zip(&mut t1, &mut t2) {
|
||||
if !t1.eq_unspanned(&t2) {
|
||||
if !t1.eq_unspanned(t2) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -413,17 +413,17 @@ impl TokenStream {
|
||||
TokenStream(Lrc::new(self.0.iter().enumerate().map(|(i, tree)| f(i, tree)).collect()))
|
||||
}
|
||||
|
||||
// Create a token stream containing a single token with alone spacing.
|
||||
/// Create a token stream containing a single token with alone spacing.
|
||||
pub fn token_alone(kind: TokenKind, span: Span) -> TokenStream {
|
||||
TokenStream::new(vec![TokenTree::token_alone(kind, span)])
|
||||
}
|
||||
|
||||
// Create a token stream containing a single token with joint spacing.
|
||||
/// Create a token stream containing a single token with joint spacing.
|
||||
pub fn token_joint(kind: TokenKind, span: Span) -> TokenStream {
|
||||
TokenStream::new(vec![TokenTree::token_joint(kind, span)])
|
||||
}
|
||||
|
||||
// Create a token stream containing a single `Delimited`.
|
||||
/// Create a token stream containing a single `Delimited`.
|
||||
pub fn delimited(span: DelimSpan, delim: Delimiter, tts: TokenStream) -> TokenStream {
|
||||
TokenStream::new(vec![TokenTree::Delimited(span, delim, tts)])
|
||||
}
|
||||
@ -475,7 +475,7 @@ impl TokenStream {
|
||||
token::Interpolated(nt) => TokenTree::Delimited(
|
||||
DelimSpan::from_single(token.span),
|
||||
Delimiter::Invisible,
|
||||
TokenStream::from_nonterminal_ast(&nt).flattened(),
|
||||
TokenStream::from_nonterminal_ast(nt).flattened(),
|
||||
),
|
||||
_ => TokenTree::Token(token.clone(), spacing),
|
||||
}
|
||||
@ -511,7 +511,7 @@ impl TokenStream {
|
||||
fn try_glue_to_last(vec: &mut Vec<TokenTree>, tt: &TokenTree) -> bool {
|
||||
if let Some(TokenTree::Token(last_tok, Spacing::Joint)) = vec.last()
|
||||
&& let TokenTree::Token(tok, spacing) = tt
|
||||
&& let Some(glued_tok) = last_tok.glue(&tok)
|
||||
&& let Some(glued_tok) = last_tok.glue(tok)
|
||||
{
|
||||
// ...then overwrite the last token tree in `vec` with the
|
||||
// glued token, and skip the first token tree from `stream`.
|
||||
@ -522,8 +522,8 @@ impl TokenStream {
|
||||
}
|
||||
}
|
||||
|
||||
// Push `tt` onto the end of the stream, possibly gluing it to the last
|
||||
// token. Uses `make_mut` to maximize efficiency.
|
||||
/// Push `tt` onto the end of the stream, possibly gluing it to the last
|
||||
/// token. Uses `make_mut` to maximize efficiency.
|
||||
pub fn push_tree(&mut self, tt: TokenTree) {
|
||||
let vec_mut = Lrc::make_mut(&mut self.0);
|
||||
|
||||
@ -534,9 +534,9 @@ impl TokenStream {
|
||||
}
|
||||
}
|
||||
|
||||
// Push `stream` onto the end of the stream, possibly gluing the first
|
||||
// token tree to the last token. (No other token trees will be glued.)
|
||||
// Uses `make_mut` to maximize efficiency.
|
||||
/// Push `stream` onto the end of the stream, possibly gluing the first
|
||||
/// token tree to the last token. (No other token trees will be glued.)
|
||||
/// Uses `make_mut` to maximize efficiency.
|
||||
pub fn push_stream(&mut self, stream: TokenStream) {
|
||||
let vec_mut = Lrc::make_mut(&mut self.0);
|
||||
|
||||
|
||||
6
compiler/rustc_ast/src/util/case.rs
Normal file
6
compiler/rustc_ast/src/util/case.rs
Normal file
@ -0,0 +1,6 @@
|
||||
/// Whatever to ignore case (`fn` vs `Fn` vs `FN`) or not. Used for recovering.
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
pub enum Case {
|
||||
Sensitive,
|
||||
Insensitive,
|
||||
}
|
||||
@ -21,6 +21,7 @@ pub fn expr_requires_semi_to_be_stmt(e: &ast::Expr) -> bool {
|
||||
| ast::ExprKind::Loop(..)
|
||||
| ast::ExprKind::ForLoop(..)
|
||||
| ast::ExprKind::TryBlock(..)
|
||||
| ast::ExprKind::ConstBlock(..)
|
||||
)
|
||||
}
|
||||
|
||||
@ -36,7 +37,6 @@ pub fn expr_trailing_brace(mut expr: &ast::Expr) -> Option<&ast::Expr> {
|
||||
| Binary(_, _, e)
|
||||
| Box(e)
|
||||
| Break(_, Some(e))
|
||||
| Closure(.., e, _)
|
||||
| Let(_, e, _)
|
||||
| Range(_, Some(e), _)
|
||||
| Ret(Some(e))
|
||||
@ -44,6 +44,9 @@ pub fn expr_trailing_brace(mut expr: &ast::Expr) -> Option<&ast::Expr> {
|
||||
| Yield(Some(e)) => {
|
||||
expr = e;
|
||||
}
|
||||
Closure(closure) => {
|
||||
expr = &closure.body;
|
||||
}
|
||||
Async(..) | Block(..) | ForLoop(..) | If(..) | Loop(..) | Match(..) | Struct(..)
|
||||
| TryBlock(..) | While(..) => break Some(expr),
|
||||
_ => break None,
|
||||
|
||||
@ -110,7 +110,7 @@ pub fn beautify_doc_string(data: Symbol, kind: CommentKind) -> Symbol {
|
||||
} else {
|
||||
&mut lines
|
||||
};
|
||||
if let Some(horizontal) = get_horizontal_trim(&lines, kind) {
|
||||
if let Some(horizontal) = get_horizontal_trim(lines, kind) {
|
||||
changes = true;
|
||||
// remove a "[ \t]*\*" block from each line, if possible
|
||||
for line in lines.iter_mut() {
|
||||
@ -147,7 +147,7 @@ fn all_whitespace(s: &str, col: CharPos) -> Option<usize> {
|
||||
|
||||
fn trim_whitespace_prefix(s: &str, col: CharPos) -> &str {
|
||||
let len = s.len();
|
||||
match all_whitespace(&s, col) {
|
||||
match all_whitespace(s, col) {
|
||||
Some(col) => {
|
||||
if col < len {
|
||||
&s[col..]
|
||||
|
||||
@ -1,17 +1,14 @@
|
||||
//! Code related to parsing literals.
|
||||
|
||||
use crate::ast::{self, Lit, LitKind};
|
||||
use crate::ast::{self, LitKind, MetaItemLit};
|
||||
use crate::token::{self, Token};
|
||||
|
||||
use rustc_lexer::unescape::{unescape_byte, unescape_char};
|
||||
use rustc_lexer::unescape::{unescape_byte_literal, unescape_literal, Mode};
|
||||
use rustc_lexer::unescape::{byte_from_char, unescape_byte, unescape_char, unescape_literal, Mode};
|
||||
use rustc_span::symbol::{kw, sym, Symbol};
|
||||
use rustc_span::Span;
|
||||
|
||||
use std::ascii;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum LitError {
|
||||
NotLiteral,
|
||||
LexerError,
|
||||
InvalidSuffix,
|
||||
InvalidIntSuffix,
|
||||
@ -55,14 +52,14 @@ impl LitKind {
|
||||
// new symbol because the string in the LitKind is different to the
|
||||
// string in the token.
|
||||
let s = symbol.as_str();
|
||||
let symbol = if s.contains(&['\\', '\r']) {
|
||||
let symbol = if s.contains(['\\', '\r']) {
|
||||
let mut buf = String::with_capacity(s.len());
|
||||
let mut error = Ok(());
|
||||
// Force-inlining here is aggressive but the closure is
|
||||
// called on every char in the string, so it can be
|
||||
// hot in programs with many long strings.
|
||||
unescape_literal(
|
||||
&s,
|
||||
s,
|
||||
Mode::Str,
|
||||
&mut #[inline(always)]
|
||||
|_, unescaped_char| match unescaped_char {
|
||||
@ -88,7 +85,7 @@ impl LitKind {
|
||||
if s.contains('\r') {
|
||||
let mut buf = String::with_capacity(s.len());
|
||||
let mut error = Ok(());
|
||||
unescape_literal(&s, Mode::RawStr, &mut |_, unescaped_char| {
|
||||
unescape_literal(s, Mode::RawStr, &mut |_, unescaped_char| {
|
||||
match unescaped_char {
|
||||
Ok(c) => buf.push(c),
|
||||
Err(err) => {
|
||||
@ -109,13 +106,11 @@ impl LitKind {
|
||||
let s = symbol.as_str();
|
||||
let mut buf = Vec::with_capacity(s.len());
|
||||
let mut error = Ok(());
|
||||
unescape_byte_literal(&s, Mode::ByteStr, &mut |_, unescaped_byte| {
|
||||
match unescaped_byte {
|
||||
Ok(c) => buf.push(c),
|
||||
Err(err) => {
|
||||
if err.is_fatal() {
|
||||
error = Err(LitError::LexerError);
|
||||
}
|
||||
unescape_literal(s, Mode::ByteStr, &mut |_, c| match c {
|
||||
Ok(c) => buf.push(byte_from_char(c)),
|
||||
Err(err) => {
|
||||
if err.is_fatal() {
|
||||
error = Err(LitError::LexerError);
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -127,13 +122,11 @@ impl LitKind {
|
||||
let bytes = if s.contains('\r') {
|
||||
let mut buf = Vec::with_capacity(s.len());
|
||||
let mut error = Ok(());
|
||||
unescape_byte_literal(&s, Mode::RawByteStr, &mut |_, unescaped_byte| {
|
||||
match unescaped_byte {
|
||||
Ok(c) => buf.push(c),
|
||||
Err(err) => {
|
||||
if err.is_fatal() {
|
||||
error = Err(LitError::LexerError);
|
||||
}
|
||||
unescape_literal(s, Mode::RawByteStr, &mut |_, c| match c {
|
||||
Ok(c) => buf.push(byte_from_char(c)),
|
||||
Err(err) => {
|
||||
if err.is_fatal() {
|
||||
error = Err(LitError::LexerError);
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -202,49 +195,16 @@ impl LitKind {
|
||||
}
|
||||
}
|
||||
|
||||
impl Lit {
|
||||
/// Converts literal token into an AST literal.
|
||||
pub fn from_token_lit(token_lit: token::Lit, span: Span) -> Result<Lit, LitError> {
|
||||
Ok(Lit { token_lit, kind: LitKind::from_token_lit(token_lit)?, span })
|
||||
impl MetaItemLit {
|
||||
/// Converts token literal into a meta item literal.
|
||||
pub fn from_token_lit(token_lit: token::Lit, span: Span) -> Result<MetaItemLit, LitError> {
|
||||
Ok(MetaItemLit { token_lit, kind: LitKind::from_token_lit(token_lit)?, span })
|
||||
}
|
||||
|
||||
/// Converts arbitrary token into an AST literal.
|
||||
///
|
||||
/// Keep this in sync with `Token::can_begin_literal_or_bool` excluding unary negation.
|
||||
pub fn from_token(token: &Token) -> Result<Lit, LitError> {
|
||||
let lit = match token.uninterpolate().kind {
|
||||
token::Ident(name, false) if name.is_bool_lit() => {
|
||||
token::Lit::new(token::Bool, name, None)
|
||||
}
|
||||
token::Literal(lit) => lit,
|
||||
token::Interpolated(ref nt) => {
|
||||
if let token::NtExpr(expr) | token::NtLiteral(expr) = &**nt
|
||||
&& let ast::ExprKind::Lit(lit) = &expr.kind
|
||||
{
|
||||
return Ok(lit.clone());
|
||||
}
|
||||
return Err(LitError::NotLiteral);
|
||||
}
|
||||
_ => return Err(LitError::NotLiteral),
|
||||
};
|
||||
|
||||
Lit::from_token_lit(lit, token.span)
|
||||
}
|
||||
|
||||
/// Attempts to recover an AST literal from semantic literal.
|
||||
/// This function is used when the original token doesn't exist (e.g. the literal is created
|
||||
/// by an AST-based macro) or unavailable (e.g. from HIR pretty-printing).
|
||||
pub fn from_lit_kind(kind: LitKind, span: Span) -> Lit {
|
||||
Lit { token_lit: kind.to_token_lit(), kind, span }
|
||||
}
|
||||
|
||||
/// Losslessly convert an AST literal into a token.
|
||||
pub fn to_token(&self) -> Token {
|
||||
let kind = match self.token_lit.kind {
|
||||
token::Bool => token::Ident(self.token_lit.symbol, false),
|
||||
_ => token::Literal(self.token_lit),
|
||||
};
|
||||
Token::new(kind, self.span)
|
||||
/// Converts an arbitrary token into meta item literal.
|
||||
pub fn from_token(token: &Token) -> Option<MetaItemLit> {
|
||||
token::Lit::from_token(token)
|
||||
.and_then(|token_lit| MetaItemLit::from_token_lit(token_lit, token.span).ok())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -377,28 +377,28 @@ pub fn needs_par_as_let_scrutinee(order: i8) -> bool {
|
||||
/// parens or other delimiters, e.g., `X { y: 1 }`, `X { y: 1 }.method()`, `foo == X { y: 1 }` and
|
||||
/// `X { y: 1 } == foo` all do, but `(X { y: 1 }) == foo` does not.
|
||||
pub fn contains_exterior_struct_lit(value: &ast::Expr) -> bool {
|
||||
match value.kind {
|
||||
match &value.kind {
|
||||
ast::ExprKind::Struct(..) => true,
|
||||
|
||||
ast::ExprKind::Assign(ref lhs, ref rhs, _)
|
||||
| ast::ExprKind::AssignOp(_, ref lhs, ref rhs)
|
||||
| ast::ExprKind::Binary(_, ref lhs, ref rhs) => {
|
||||
ast::ExprKind::Assign(lhs, rhs, _)
|
||||
| ast::ExprKind::AssignOp(_, lhs, rhs)
|
||||
| ast::ExprKind::Binary(_, lhs, rhs) => {
|
||||
// X { y: 1 } + X { y: 2 }
|
||||
contains_exterior_struct_lit(&lhs) || contains_exterior_struct_lit(&rhs)
|
||||
contains_exterior_struct_lit(lhs) || contains_exterior_struct_lit(rhs)
|
||||
}
|
||||
ast::ExprKind::Await(ref x)
|
||||
| ast::ExprKind::Unary(_, ref x)
|
||||
| ast::ExprKind::Cast(ref x, _)
|
||||
| ast::ExprKind::Type(ref x, _)
|
||||
| ast::ExprKind::Field(ref x, _)
|
||||
| ast::ExprKind::Index(ref x, _) => {
|
||||
ast::ExprKind::Await(x)
|
||||
| ast::ExprKind::Unary(_, x)
|
||||
| ast::ExprKind::Cast(x, _)
|
||||
| ast::ExprKind::Type(x, _)
|
||||
| ast::ExprKind::Field(x, _)
|
||||
| ast::ExprKind::Index(x, _) => {
|
||||
// &X { y: 1 }, X { y: 1 }.y
|
||||
contains_exterior_struct_lit(&x)
|
||||
contains_exterior_struct_lit(x)
|
||||
}
|
||||
|
||||
ast::ExprKind::MethodCall(_, ref receiver, _, _) => {
|
||||
ast::ExprKind::MethodCall(box ast::MethodCall { receiver, .. }) => {
|
||||
// X { y: 1 }.bar(...)
|
||||
contains_exterior_struct_lit(&receiver)
|
||||
contains_exterior_struct_lit(receiver)
|
||||
}
|
||||
|
||||
_ => false,
|
||||
|
||||
@ -17,7 +17,7 @@ pub fn contains_text_flow_control_chars(s: &str) -> bool {
|
||||
// U+2069 - E2 81 A9
|
||||
let mut bytes = s.as_bytes();
|
||||
loop {
|
||||
match core::slice::memchr::memchr(0xE2, &bytes) {
|
||||
match core::slice::memchr::memchr(0xE2, bytes) {
|
||||
Some(idx) => {
|
||||
// bytes are valid UTF-8 -> E2 must be followed by two bytes
|
||||
let ch = &bytes[idx..idx + 3];
|
||||
|
||||
@ -251,7 +251,7 @@ pub trait Visitor<'ast>: Sized {
|
||||
macro_rules! walk_list {
|
||||
($visitor: expr, $method: ident, $list: expr $(, $($extra_args: expr),* )?) => {
|
||||
{
|
||||
#[cfg_attr(not(bootstrap), allow(for_loops_over_fallibles))]
|
||||
#[allow(for_loops_over_fallibles)]
|
||||
for elem in $list {
|
||||
$visitor.$method(elem $(, $($extra_args,)* )?)
|
||||
}
|
||||
@ -299,74 +299,68 @@ pub fn walk_trait_ref<'a, V: Visitor<'a>>(visitor: &mut V, trait_ref: &'a TraitR
|
||||
pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) {
|
||||
visitor.visit_vis(&item.vis);
|
||||
visitor.visit_ident(item.ident);
|
||||
match item.kind {
|
||||
match &item.kind {
|
||||
ItemKind::ExternCrate(_) => {}
|
||||
ItemKind::Use(ref use_tree) => visitor.visit_use_tree(use_tree, item.id, false),
|
||||
ItemKind::Static(ref typ, _, ref expr) | ItemKind::Const(_, ref typ, ref expr) => {
|
||||
ItemKind::Use(use_tree) => visitor.visit_use_tree(use_tree, item.id, false),
|
||||
ItemKind::Static(typ, _, expr) | ItemKind::Const(_, typ, expr) => {
|
||||
visitor.visit_ty(typ);
|
||||
walk_list!(visitor, visit_expr, expr);
|
||||
}
|
||||
ItemKind::Fn(box Fn { defaultness: _, ref generics, ref sig, ref body }) => {
|
||||
ItemKind::Fn(box Fn { defaultness: _, generics, sig, body }) => {
|
||||
let kind =
|
||||
FnKind::Fn(FnCtxt::Free, item.ident, sig, &item.vis, generics, body.as_deref());
|
||||
visitor.visit_fn(kind, item.span, item.id)
|
||||
}
|
||||
ItemKind::Mod(_unsafety, ref mod_kind) => match mod_kind {
|
||||
ItemKind::Mod(_unsafety, mod_kind) => match mod_kind {
|
||||
ModKind::Loaded(items, _inline, _inner_span) => {
|
||||
walk_list!(visitor, visit_item, items)
|
||||
}
|
||||
ModKind::Unloaded => {}
|
||||
},
|
||||
ItemKind::ForeignMod(ref foreign_module) => {
|
||||
ItemKind::ForeignMod(foreign_module) => {
|
||||
walk_list!(visitor, visit_foreign_item, &foreign_module.items);
|
||||
}
|
||||
ItemKind::GlobalAsm(ref asm) => visitor.visit_inline_asm(asm),
|
||||
ItemKind::TyAlias(box TyAlias { ref generics, ref bounds, ref ty, .. }) => {
|
||||
ItemKind::GlobalAsm(asm) => visitor.visit_inline_asm(asm),
|
||||
ItemKind::TyAlias(box TyAlias { generics, bounds, ty, .. }) => {
|
||||
visitor.visit_generics(generics);
|
||||
walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
|
||||
walk_list!(visitor, visit_ty, ty);
|
||||
}
|
||||
ItemKind::Enum(ref enum_definition, ref generics) => {
|
||||
ItemKind::Enum(enum_definition, generics) => {
|
||||
visitor.visit_generics(generics);
|
||||
visitor.visit_enum_def(enum_definition)
|
||||
}
|
||||
ItemKind::Impl(box Impl {
|
||||
defaultness: _,
|
||||
unsafety: _,
|
||||
ref generics,
|
||||
generics,
|
||||
constness: _,
|
||||
polarity: _,
|
||||
ref of_trait,
|
||||
ref self_ty,
|
||||
ref items,
|
||||
of_trait,
|
||||
self_ty,
|
||||
items,
|
||||
}) => {
|
||||
visitor.visit_generics(generics);
|
||||
walk_list!(visitor, visit_trait_ref, of_trait);
|
||||
visitor.visit_ty(self_ty);
|
||||
walk_list!(visitor, visit_assoc_item, items, AssocCtxt::Impl);
|
||||
}
|
||||
ItemKind::Struct(ref struct_definition, ref generics)
|
||||
| ItemKind::Union(ref struct_definition, ref generics) => {
|
||||
ItemKind::Struct(struct_definition, generics)
|
||||
| ItemKind::Union(struct_definition, generics) => {
|
||||
visitor.visit_generics(generics);
|
||||
visitor.visit_variant_data(struct_definition);
|
||||
}
|
||||
ItemKind::Trait(box Trait {
|
||||
unsafety: _,
|
||||
is_auto: _,
|
||||
ref generics,
|
||||
ref bounds,
|
||||
ref items,
|
||||
}) => {
|
||||
ItemKind::Trait(box Trait { unsafety: _, is_auto: _, generics, bounds, items }) => {
|
||||
visitor.visit_generics(generics);
|
||||
walk_list!(visitor, visit_param_bound, bounds, BoundKind::SuperTraits);
|
||||
walk_list!(visitor, visit_assoc_item, items, AssocCtxt::Trait);
|
||||
}
|
||||
ItemKind::TraitAlias(ref generics, ref bounds) => {
|
||||
ItemKind::TraitAlias(generics, bounds) => {
|
||||
visitor.visit_generics(generics);
|
||||
walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
|
||||
}
|
||||
ItemKind::MacCall(ref mac) => visitor.visit_mac_call(mac),
|
||||
ItemKind::MacroDef(ref ts) => visitor.visit_mac_def(ts, item.id),
|
||||
ItemKind::MacCall(mac) => visitor.visit_mac_call(mac),
|
||||
ItemKind::MacroDef(ts) => visitor.visit_mac_def(ts, item.id),
|
||||
}
|
||||
walk_list!(visitor, visit_attribute, &item.attrs);
|
||||
}
|
||||
@ -399,39 +393,39 @@ pub fn walk_pat_field<'a, V: Visitor<'a>>(visitor: &mut V, fp: &'a PatField) {
|
||||
}
|
||||
|
||||
pub fn walk_ty<'a, V: Visitor<'a>>(visitor: &mut V, typ: &'a Ty) {
|
||||
match typ.kind {
|
||||
TyKind::Slice(ref ty) | TyKind::Paren(ref ty) => visitor.visit_ty(ty),
|
||||
TyKind::Ptr(ref mutable_type) => visitor.visit_ty(&mutable_type.ty),
|
||||
TyKind::Rptr(ref opt_lifetime, ref mutable_type) => {
|
||||
match &typ.kind {
|
||||
TyKind::Slice(ty) | TyKind::Paren(ty) => visitor.visit_ty(ty),
|
||||
TyKind::Ptr(mutable_type) => visitor.visit_ty(&mutable_type.ty),
|
||||
TyKind::Rptr(opt_lifetime, mutable_type) => {
|
||||
walk_list!(visitor, visit_lifetime, opt_lifetime, LifetimeCtxt::Rptr);
|
||||
visitor.visit_ty(&mutable_type.ty)
|
||||
}
|
||||
TyKind::Tup(ref tuple_element_types) => {
|
||||
TyKind::Tup(tuple_element_types) => {
|
||||
walk_list!(visitor, visit_ty, tuple_element_types);
|
||||
}
|
||||
TyKind::BareFn(ref function_declaration) => {
|
||||
TyKind::BareFn(function_declaration) => {
|
||||
walk_list!(visitor, visit_generic_param, &function_declaration.generic_params);
|
||||
walk_fn_decl(visitor, &function_declaration.decl);
|
||||
}
|
||||
TyKind::Path(ref maybe_qself, ref path) => {
|
||||
if let Some(ref qself) = *maybe_qself {
|
||||
TyKind::Path(maybe_qself, path) => {
|
||||
if let Some(qself) = maybe_qself {
|
||||
visitor.visit_ty(&qself.ty);
|
||||
}
|
||||
visitor.visit_path(path, typ.id);
|
||||
}
|
||||
TyKind::Array(ref ty, ref length) => {
|
||||
TyKind::Array(ty, length) => {
|
||||
visitor.visit_ty(ty);
|
||||
visitor.visit_anon_const(length)
|
||||
}
|
||||
TyKind::TraitObject(ref bounds, ..) => {
|
||||
TyKind::TraitObject(bounds, ..) => {
|
||||
walk_list!(visitor, visit_param_bound, bounds, BoundKind::TraitObject);
|
||||
}
|
||||
TyKind::ImplTrait(_, ref bounds) => {
|
||||
TyKind::ImplTrait(_, bounds) => {
|
||||
walk_list!(visitor, visit_param_bound, bounds, BoundKind::Impl);
|
||||
}
|
||||
TyKind::Typeof(ref expression) => visitor.visit_anon_const(expression),
|
||||
TyKind::Typeof(expression) => visitor.visit_anon_const(expression),
|
||||
TyKind::Infer | TyKind::ImplicitSelf | TyKind::Err => {}
|
||||
TyKind::MacCall(ref mac) => visitor.visit_mac_call(mac),
|
||||
TyKind::MacCall(mac) => visitor.visit_mac_call(mac),
|
||||
TyKind::Never | TyKind::CVarArgs => {}
|
||||
}
|
||||
}
|
||||
@ -444,15 +438,15 @@ pub fn walk_path<'a, V: Visitor<'a>>(visitor: &mut V, path: &'a Path) {
|
||||
|
||||
pub fn walk_use_tree<'a, V: Visitor<'a>>(visitor: &mut V, use_tree: &'a UseTree, id: NodeId) {
|
||||
visitor.visit_path(&use_tree.prefix, id);
|
||||
match use_tree.kind {
|
||||
UseTreeKind::Simple(rename, ..) => {
|
||||
match &use_tree.kind {
|
||||
UseTreeKind::Simple(rename) => {
|
||||
// The extra IDs are handled during HIR lowering.
|
||||
if let Some(rename) = rename {
|
||||
if let &Some(rename) = rename {
|
||||
visitor.visit_ident(rename);
|
||||
}
|
||||
}
|
||||
UseTreeKind::Glob => {}
|
||||
UseTreeKind::Nested(ref use_trees) => {
|
||||
UseTreeKind::Nested(use_trees) => {
|
||||
for &(ref nested_tree, nested_id) in use_trees {
|
||||
visitor.visit_use_tree(nested_tree, nested_id, true);
|
||||
}
|
||||
@ -462,7 +456,7 @@ pub fn walk_use_tree<'a, V: Visitor<'a>>(visitor: &mut V, use_tree: &'a UseTree,
|
||||
|
||||
pub fn walk_path_segment<'a, V: Visitor<'a>>(visitor: &mut V, segment: &'a PathSegment) {
|
||||
visitor.visit_ident(segment.ident);
|
||||
if let Some(ref args) = segment.args {
|
||||
if let Some(args) = &segment.args {
|
||||
visitor.visit_generic_args(args);
|
||||
}
|
||||
}
|
||||
@ -471,8 +465,8 @@ pub fn walk_generic_args<'a, V>(visitor: &mut V, generic_args: &'a GenericArgs)
|
||||
where
|
||||
V: Visitor<'a>,
|
||||
{
|
||||
match *generic_args {
|
||||
GenericArgs::AngleBracketed(ref data) => {
|
||||
match generic_args {
|
||||
GenericArgs::AngleBracketed(data) => {
|
||||
for arg in &data.args {
|
||||
match arg {
|
||||
AngleBracketedArg::Arg(a) => visitor.visit_generic_arg(a),
|
||||
@ -480,7 +474,7 @@ where
|
||||
}
|
||||
}
|
||||
}
|
||||
GenericArgs::Parenthesized(ref data) => {
|
||||
GenericArgs::Parenthesized(data) => {
|
||||
walk_list!(visitor, visit_ty, &data.inputs);
|
||||
walk_fn_ret_ty(visitor, &data.output);
|
||||
}
|
||||
@ -500,64 +494,64 @@ where
|
||||
|
||||
pub fn walk_assoc_constraint<'a, V: Visitor<'a>>(visitor: &mut V, constraint: &'a AssocConstraint) {
|
||||
visitor.visit_ident(constraint.ident);
|
||||
if let Some(ref gen_args) = constraint.gen_args {
|
||||
if let Some(gen_args) = &constraint.gen_args {
|
||||
visitor.visit_generic_args(gen_args);
|
||||
}
|
||||
match constraint.kind {
|
||||
AssocConstraintKind::Equality { ref term } => match term {
|
||||
match &constraint.kind {
|
||||
AssocConstraintKind::Equality { term } => match term {
|
||||
Term::Ty(ty) => visitor.visit_ty(ty),
|
||||
Term::Const(c) => visitor.visit_anon_const(c),
|
||||
},
|
||||
AssocConstraintKind::Bound { ref bounds } => {
|
||||
AssocConstraintKind::Bound { bounds } => {
|
||||
walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn walk_pat<'a, V: Visitor<'a>>(visitor: &mut V, pattern: &'a Pat) {
|
||||
match pattern.kind {
|
||||
PatKind::TupleStruct(ref opt_qself, ref path, ref elems) => {
|
||||
if let Some(ref qself) = *opt_qself {
|
||||
match &pattern.kind {
|
||||
PatKind::TupleStruct(opt_qself, path, elems) => {
|
||||
if let Some(qself) = opt_qself {
|
||||
visitor.visit_ty(&qself.ty);
|
||||
}
|
||||
visitor.visit_path(path, pattern.id);
|
||||
walk_list!(visitor, visit_pat, elems);
|
||||
}
|
||||
PatKind::Path(ref opt_qself, ref path) => {
|
||||
if let Some(ref qself) = *opt_qself {
|
||||
PatKind::Path(opt_qself, path) => {
|
||||
if let Some(qself) = opt_qself {
|
||||
visitor.visit_ty(&qself.ty);
|
||||
}
|
||||
visitor.visit_path(path, pattern.id)
|
||||
}
|
||||
PatKind::Struct(ref opt_qself, ref path, ref fields, _) => {
|
||||
if let Some(ref qself) = *opt_qself {
|
||||
PatKind::Struct(opt_qself, path, fields, _) => {
|
||||
if let Some(qself) = opt_qself {
|
||||
visitor.visit_ty(&qself.ty);
|
||||
}
|
||||
visitor.visit_path(path, pattern.id);
|
||||
walk_list!(visitor, visit_pat_field, fields);
|
||||
}
|
||||
PatKind::Box(ref subpattern)
|
||||
| PatKind::Ref(ref subpattern, _)
|
||||
| PatKind::Paren(ref subpattern) => visitor.visit_pat(subpattern),
|
||||
PatKind::Ident(_, ident, ref optional_subpattern) => {
|
||||
visitor.visit_ident(ident);
|
||||
PatKind::Box(subpattern) | PatKind::Ref(subpattern, _) | PatKind::Paren(subpattern) => {
|
||||
visitor.visit_pat(subpattern)
|
||||
}
|
||||
PatKind::Ident(_, ident, optional_subpattern) => {
|
||||
visitor.visit_ident(*ident);
|
||||
walk_list!(visitor, visit_pat, optional_subpattern);
|
||||
}
|
||||
PatKind::Lit(ref expression) => visitor.visit_expr(expression),
|
||||
PatKind::Range(ref lower_bound, ref upper_bound, _) => {
|
||||
PatKind::Lit(expression) => visitor.visit_expr(expression),
|
||||
PatKind::Range(lower_bound, upper_bound, _) => {
|
||||
walk_list!(visitor, visit_expr, lower_bound);
|
||||
walk_list!(visitor, visit_expr, upper_bound);
|
||||
}
|
||||
PatKind::Wild | PatKind::Rest => {}
|
||||
PatKind::Tuple(ref elems) | PatKind::Slice(ref elems) | PatKind::Or(ref elems) => {
|
||||
PatKind::Tuple(elems) | PatKind::Slice(elems) | PatKind::Or(elems) => {
|
||||
walk_list!(visitor, visit_pat, elems);
|
||||
}
|
||||
PatKind::MacCall(ref mac) => visitor.visit_mac_call(mac),
|
||||
PatKind::MacCall(mac) => visitor.visit_mac_call(mac),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn walk_foreign_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a ForeignItem) {
|
||||
let Item { id, span, ident, ref vis, ref attrs, ref kind, tokens: _ } = *item;
|
||||
let &Item { id, span, ident, ref vis, ref attrs, ref kind, tokens: _ } = item;
|
||||
visitor.visit_vis(vis);
|
||||
visitor.visit_ident(ident);
|
||||
walk_list!(visitor, visit_attribute, attrs);
|
||||
@ -566,7 +560,7 @@ pub fn walk_foreign_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a ForeignI
|
||||
visitor.visit_ty(ty);
|
||||
walk_list!(visitor, visit_expr, expr);
|
||||
}
|
||||
ForeignItemKind::Fn(box Fn { defaultness: _, ref generics, ref sig, ref body }) => {
|
||||
ForeignItemKind::Fn(box Fn { defaultness: _, generics, sig, body }) => {
|
||||
let kind = FnKind::Fn(FnCtxt::Foreign, ident, sig, vis, generics, body.as_deref());
|
||||
visitor.visit_fn(kind, span, id);
|
||||
}
|
||||
@ -582,11 +576,9 @@ pub fn walk_foreign_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a ForeignI
|
||||
}
|
||||
|
||||
pub fn walk_param_bound<'a, V: Visitor<'a>>(visitor: &mut V, bound: &'a GenericBound) {
|
||||
match *bound {
|
||||
GenericBound::Trait(ref typ, ref _modifier) => visitor.visit_poly_trait_ref(typ),
|
||||
GenericBound::Outlives(ref lifetime) => {
|
||||
visitor.visit_lifetime(lifetime, LifetimeCtxt::Bound)
|
||||
}
|
||||
match bound {
|
||||
GenericBound::Trait(typ, _modifier) => visitor.visit_poly_trait_ref(typ),
|
||||
GenericBound::Outlives(lifetime) => visitor.visit_lifetime(lifetime, LifetimeCtxt::Bound),
|
||||
}
|
||||
}
|
||||
|
||||
@ -594,10 +586,10 @@ pub fn walk_generic_param<'a, V: Visitor<'a>>(visitor: &mut V, param: &'a Generi
|
||||
visitor.visit_ident(param.ident);
|
||||
walk_list!(visitor, visit_attribute, param.attrs.iter());
|
||||
walk_list!(visitor, visit_param_bound, ¶m.bounds, BoundKind::Bound);
|
||||
match param.kind {
|
||||
match ¶m.kind {
|
||||
GenericParamKind::Lifetime => (),
|
||||
GenericParamKind::Type { ref default } => walk_list!(visitor, visit_ty, default),
|
||||
GenericParamKind::Const { ref ty, ref default, .. } => {
|
||||
GenericParamKind::Type { default } => walk_list!(visitor, visit_ty, default),
|
||||
GenericParamKind::Const { ty, default, .. } => {
|
||||
visitor.visit_ty(ty);
|
||||
if let Some(default) = default {
|
||||
visitor.visit_anon_const(default);
|
||||
@ -621,24 +613,22 @@ pub fn walk_closure_binder<'a, V: Visitor<'a>>(visitor: &mut V, binder: &'a Clos
|
||||
}
|
||||
|
||||
pub fn walk_where_predicate<'a, V: Visitor<'a>>(visitor: &mut V, predicate: &'a WherePredicate) {
|
||||
match *predicate {
|
||||
match predicate {
|
||||
WherePredicate::BoundPredicate(WhereBoundPredicate {
|
||||
ref bounded_ty,
|
||||
ref bounds,
|
||||
ref bound_generic_params,
|
||||
bounded_ty,
|
||||
bounds,
|
||||
bound_generic_params,
|
||||
..
|
||||
}) => {
|
||||
visitor.visit_ty(bounded_ty);
|
||||
walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
|
||||
walk_list!(visitor, visit_generic_param, bound_generic_params);
|
||||
}
|
||||
WherePredicate::RegionPredicate(WhereRegionPredicate {
|
||||
ref lifetime, ref bounds, ..
|
||||
}) => {
|
||||
WherePredicate::RegionPredicate(WhereRegionPredicate { lifetime, bounds, .. }) => {
|
||||
visitor.visit_lifetime(lifetime, LifetimeCtxt::Bound);
|
||||
walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
|
||||
}
|
||||
WherePredicate::EqPredicate(WhereEqPredicate { ref lhs_ty, ref rhs_ty, .. }) => {
|
||||
WherePredicate::EqPredicate(WhereEqPredicate { lhs_ty, rhs_ty, .. }) => {
|
||||
visitor.visit_ty(lhs_ty);
|
||||
visitor.visit_ty(rhs_ty);
|
||||
}
|
||||
@ -646,7 +636,7 @@ pub fn walk_where_predicate<'a, V: Visitor<'a>>(visitor: &mut V, predicate: &'a
|
||||
}
|
||||
|
||||
pub fn walk_fn_ret_ty<'a, V: Visitor<'a>>(visitor: &mut V, ret_ty: &'a FnRetTy) {
|
||||
if let FnRetTy::Ty(ref output_ty) = *ret_ty {
|
||||
if let FnRetTy::Ty(output_ty) = ret_ty {
|
||||
visitor.visit_ty(output_ty)
|
||||
}
|
||||
}
|
||||
@ -675,7 +665,7 @@ pub fn walk_fn<'a, V: Visitor<'a>>(visitor: &mut V, kind: FnKind<'a>) {
|
||||
}
|
||||
|
||||
pub fn walk_assoc_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a AssocItem, ctxt: AssocCtxt) {
|
||||
let Item { id, span, ident, ref vis, ref attrs, ref kind, tokens: _ } = *item;
|
||||
let &Item { id, span, ident, ref vis, ref attrs, ref kind, tokens: _ } = item;
|
||||
visitor.visit_vis(vis);
|
||||
visitor.visit_ident(ident);
|
||||
walk_list!(visitor, visit_attribute, attrs);
|
||||
@ -684,7 +674,7 @@ pub fn walk_assoc_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a AssocItem,
|
||||
visitor.visit_ty(ty);
|
||||
walk_list!(visitor, visit_expr, expr);
|
||||
}
|
||||
AssocItemKind::Fn(box Fn { defaultness: _, ref generics, ref sig, ref body }) => {
|
||||
AssocItemKind::Fn(box Fn { defaultness: _, generics, sig, body }) => {
|
||||
let kind = FnKind::Fn(FnCtxt::Assoc(ctxt), ident, sig, vis, generics, body.as_deref());
|
||||
visitor.visit_fn(kind, span, id);
|
||||
}
|
||||
@ -717,13 +707,13 @@ pub fn walk_block<'a, V: Visitor<'a>>(visitor: &mut V, block: &'a Block) {
|
||||
}
|
||||
|
||||
pub fn walk_stmt<'a, V: Visitor<'a>>(visitor: &mut V, statement: &'a Stmt) {
|
||||
match statement.kind {
|
||||
StmtKind::Local(ref local) => visitor.visit_local(local),
|
||||
StmtKind::Item(ref item) => visitor.visit_item(item),
|
||||
StmtKind::Expr(ref expr) | StmtKind::Semi(ref expr) => visitor.visit_expr(expr),
|
||||
match &statement.kind {
|
||||
StmtKind::Local(local) => visitor.visit_local(local),
|
||||
StmtKind::Item(item) => visitor.visit_item(item),
|
||||
StmtKind::Expr(expr) | StmtKind::Semi(expr) => visitor.visit_expr(expr),
|
||||
StmtKind::Empty => {}
|
||||
StmtKind::MacCall(ref mac) => {
|
||||
let MacCallStmt { ref mac, style: _, ref attrs, tokens: _ } = **mac;
|
||||
StmtKind::MacCall(mac) => {
|
||||
let MacCallStmt { mac, attrs, style: _, tokens: _ } = &**mac;
|
||||
visitor.visit_mac_call(mac);
|
||||
for attr in attrs.iter() {
|
||||
visitor.visit_attribute(attr);
|
||||
@ -760,7 +750,7 @@ pub fn walk_inline_asm<'a, V: Visitor<'a>>(visitor: &mut V, asm: &'a InlineAsm)
|
||||
}
|
||||
|
||||
pub fn walk_inline_asm_sym<'a, V: Visitor<'a>>(visitor: &mut V, sym: &'a InlineAsmSym) {
|
||||
if let Some(ref qself) = sym.qself {
|
||||
if let Some(qself) = &sym.qself {
|
||||
visitor.visit_ty(&qself.ty);
|
||||
}
|
||||
visitor.visit_path(&sym.path, sym.id);
|
||||
@ -769,18 +759,18 @@ pub fn walk_inline_asm_sym<'a, V: Visitor<'a>>(visitor: &mut V, sym: &'a InlineA
|
||||
pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
|
||||
walk_list!(visitor, visit_attribute, expression.attrs.iter());
|
||||
|
||||
match expression.kind {
|
||||
ExprKind::Box(ref subexpression) => visitor.visit_expr(subexpression),
|
||||
ExprKind::Array(ref subexpressions) => {
|
||||
match &expression.kind {
|
||||
ExprKind::Box(subexpression) => visitor.visit_expr(subexpression),
|
||||
ExprKind::Array(subexpressions) => {
|
||||
walk_list!(visitor, visit_expr, subexpressions);
|
||||
}
|
||||
ExprKind::ConstBlock(ref anon_const) => visitor.visit_anon_const(anon_const),
|
||||
ExprKind::Repeat(ref element, ref count) => {
|
||||
ExprKind::ConstBlock(anon_const) => visitor.visit_anon_const(anon_const),
|
||||
ExprKind::Repeat(element, count) => {
|
||||
visitor.visit_expr(element);
|
||||
visitor.visit_anon_const(count)
|
||||
}
|
||||
ExprKind::Struct(ref se) => {
|
||||
if let Some(ref qself) = se.qself {
|
||||
ExprKind::Struct(se) => {
|
||||
if let Some(qself) = &se.qself {
|
||||
visitor.visit_ty(&qself.ty);
|
||||
}
|
||||
visitor.visit_path(&se.path, expression.id);
|
||||
@ -791,117 +781,126 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
|
||||
StructRest::None => {}
|
||||
}
|
||||
}
|
||||
ExprKind::Tup(ref subexpressions) => {
|
||||
ExprKind::Tup(subexpressions) => {
|
||||
walk_list!(visitor, visit_expr, subexpressions);
|
||||
}
|
||||
ExprKind::Call(ref callee_expression, ref arguments) => {
|
||||
ExprKind::Call(callee_expression, arguments) => {
|
||||
visitor.visit_expr(callee_expression);
|
||||
walk_list!(visitor, visit_expr, arguments);
|
||||
}
|
||||
ExprKind::MethodCall(ref segment, ref receiver, ref arguments, _span) => {
|
||||
visitor.visit_path_segment(segment);
|
||||
ExprKind::MethodCall(box MethodCall { seg, receiver, args, span: _ }) => {
|
||||
visitor.visit_path_segment(seg);
|
||||
visitor.visit_expr(receiver);
|
||||
walk_list!(visitor, visit_expr, arguments);
|
||||
walk_list!(visitor, visit_expr, args);
|
||||
}
|
||||
ExprKind::Binary(_, ref left_expression, ref right_expression) => {
|
||||
ExprKind::Binary(_, left_expression, right_expression) => {
|
||||
visitor.visit_expr(left_expression);
|
||||
visitor.visit_expr(right_expression)
|
||||
}
|
||||
ExprKind::AddrOf(_, _, ref subexpression) | ExprKind::Unary(_, ref subexpression) => {
|
||||
ExprKind::AddrOf(_, _, subexpression) | ExprKind::Unary(_, subexpression) => {
|
||||
visitor.visit_expr(subexpression)
|
||||
}
|
||||
ExprKind::Cast(ref subexpression, ref typ) | ExprKind::Type(ref subexpression, ref typ) => {
|
||||
ExprKind::Cast(subexpression, typ) | ExprKind::Type(subexpression, typ) => {
|
||||
visitor.visit_expr(subexpression);
|
||||
visitor.visit_ty(typ)
|
||||
}
|
||||
ExprKind::Let(ref pat, ref expr, _) => {
|
||||
ExprKind::Let(pat, expr, _) => {
|
||||
visitor.visit_pat(pat);
|
||||
visitor.visit_expr(expr);
|
||||
}
|
||||
ExprKind::If(ref head_expression, ref if_block, ref optional_else) => {
|
||||
ExprKind::If(head_expression, if_block, optional_else) => {
|
||||
visitor.visit_expr(head_expression);
|
||||
visitor.visit_block(if_block);
|
||||
walk_list!(visitor, visit_expr, optional_else);
|
||||
}
|
||||
ExprKind::While(ref subexpression, ref block, ref opt_label) => {
|
||||
ExprKind::While(subexpression, block, opt_label) => {
|
||||
walk_list!(visitor, visit_label, opt_label);
|
||||
visitor.visit_expr(subexpression);
|
||||
visitor.visit_block(block);
|
||||
}
|
||||
ExprKind::ForLoop(ref pattern, ref subexpression, ref block, ref opt_label) => {
|
||||
ExprKind::ForLoop(pattern, subexpression, block, opt_label) => {
|
||||
walk_list!(visitor, visit_label, opt_label);
|
||||
visitor.visit_pat(pattern);
|
||||
visitor.visit_expr(subexpression);
|
||||
visitor.visit_block(block);
|
||||
}
|
||||
ExprKind::Loop(ref block, ref opt_label) => {
|
||||
ExprKind::Loop(block, opt_label, _) => {
|
||||
walk_list!(visitor, visit_label, opt_label);
|
||||
visitor.visit_block(block);
|
||||
}
|
||||
ExprKind::Match(ref subexpression, ref arms) => {
|
||||
ExprKind::Match(subexpression, arms) => {
|
||||
visitor.visit_expr(subexpression);
|
||||
walk_list!(visitor, visit_arm, arms);
|
||||
}
|
||||
ExprKind::Closure(ref binder, _, _, _, ref decl, ref body, _decl_span) => {
|
||||
visitor.visit_fn(FnKind::Closure(binder, decl, body), expression.span, expression.id)
|
||||
ExprKind::Closure(box Closure {
|
||||
binder,
|
||||
capture_clause: _,
|
||||
asyncness: _,
|
||||
movability: _,
|
||||
fn_decl,
|
||||
body,
|
||||
fn_decl_span: _,
|
||||
fn_arg_span: _,
|
||||
}) => {
|
||||
visitor.visit_fn(FnKind::Closure(binder, fn_decl, body), expression.span, expression.id)
|
||||
}
|
||||
ExprKind::Block(ref block, ref opt_label) => {
|
||||
ExprKind::Block(block, opt_label) => {
|
||||
walk_list!(visitor, visit_label, opt_label);
|
||||
visitor.visit_block(block);
|
||||
}
|
||||
ExprKind::Async(_, _, ref body) => {
|
||||
ExprKind::Async(_, _, body) => {
|
||||
visitor.visit_block(body);
|
||||
}
|
||||
ExprKind::Await(ref expr) => visitor.visit_expr(expr),
|
||||
ExprKind::Assign(ref lhs, ref rhs, _) => {
|
||||
ExprKind::Await(expr) => visitor.visit_expr(expr),
|
||||
ExprKind::Assign(lhs, rhs, _) => {
|
||||
visitor.visit_expr(lhs);
|
||||
visitor.visit_expr(rhs);
|
||||
}
|
||||
ExprKind::AssignOp(_, ref left_expression, ref right_expression) => {
|
||||
ExprKind::AssignOp(_, left_expression, right_expression) => {
|
||||
visitor.visit_expr(left_expression);
|
||||
visitor.visit_expr(right_expression);
|
||||
}
|
||||
ExprKind::Field(ref subexpression, ident) => {
|
||||
ExprKind::Field(subexpression, ident) => {
|
||||
visitor.visit_expr(subexpression);
|
||||
visitor.visit_ident(ident);
|
||||
visitor.visit_ident(*ident);
|
||||
}
|
||||
ExprKind::Index(ref main_expression, ref index_expression) => {
|
||||
ExprKind::Index(main_expression, index_expression) => {
|
||||
visitor.visit_expr(main_expression);
|
||||
visitor.visit_expr(index_expression)
|
||||
}
|
||||
ExprKind::Range(ref start, ref end, _) => {
|
||||
ExprKind::Range(start, end, _) => {
|
||||
walk_list!(visitor, visit_expr, start);
|
||||
walk_list!(visitor, visit_expr, end);
|
||||
}
|
||||
ExprKind::Underscore => {}
|
||||
ExprKind::Path(ref maybe_qself, ref path) => {
|
||||
if let Some(ref qself) = *maybe_qself {
|
||||
ExprKind::Path(maybe_qself, path) => {
|
||||
if let Some(qself) = maybe_qself {
|
||||
visitor.visit_ty(&qself.ty);
|
||||
}
|
||||
visitor.visit_path(path, expression.id)
|
||||
}
|
||||
ExprKind::Break(ref opt_label, ref opt_expr) => {
|
||||
ExprKind::Break(opt_label, opt_expr) => {
|
||||
walk_list!(visitor, visit_label, opt_label);
|
||||
walk_list!(visitor, visit_expr, opt_expr);
|
||||
}
|
||||
ExprKind::Continue(ref opt_label) => {
|
||||
ExprKind::Continue(opt_label) => {
|
||||
walk_list!(visitor, visit_label, opt_label);
|
||||
}
|
||||
ExprKind::Ret(ref optional_expression) => {
|
||||
ExprKind::Ret(optional_expression) => {
|
||||
walk_list!(visitor, visit_expr, optional_expression);
|
||||
}
|
||||
ExprKind::Yeet(ref optional_expression) => {
|
||||
ExprKind::Yeet(optional_expression) => {
|
||||
walk_list!(visitor, visit_expr, optional_expression);
|
||||
}
|
||||
ExprKind::MacCall(ref mac) => visitor.visit_mac_call(mac),
|
||||
ExprKind::Paren(ref subexpression) => visitor.visit_expr(subexpression),
|
||||
ExprKind::InlineAsm(ref asm) => visitor.visit_inline_asm(asm),
|
||||
ExprKind::Yield(ref optional_expression) => {
|
||||
ExprKind::MacCall(mac) => visitor.visit_mac_call(mac),
|
||||
ExprKind::Paren(subexpression) => visitor.visit_expr(subexpression),
|
||||
ExprKind::InlineAsm(asm) => visitor.visit_inline_asm(asm),
|
||||
ExprKind::Yield(optional_expression) => {
|
||||
walk_list!(visitor, visit_expr, optional_expression);
|
||||
}
|
||||
ExprKind::Try(ref subexpression) => visitor.visit_expr(subexpression),
|
||||
ExprKind::TryBlock(ref body) => visitor.visit_block(body),
|
||||
ExprKind::Lit(_) | ExprKind::Err => {}
|
||||
ExprKind::Try(subexpression) => visitor.visit_expr(subexpression),
|
||||
ExprKind::TryBlock(body) => visitor.visit_block(body),
|
||||
ExprKind::Lit(_) | ExprKind::IncludedBytes(..) | ExprKind::Err => {}
|
||||
}
|
||||
|
||||
visitor.visit_expr_post(expression)
|
||||
@ -927,18 +926,18 @@ pub fn walk_vis<'a, V: Visitor<'a>>(visitor: &mut V, vis: &'a Visibility) {
|
||||
}
|
||||
|
||||
pub fn walk_attribute<'a, V: Visitor<'a>>(visitor: &mut V, attr: &'a Attribute) {
|
||||
match attr.kind {
|
||||
AttrKind::Normal(ref normal) => walk_mac_args(visitor, &normal.item.args),
|
||||
match &attr.kind {
|
||||
AttrKind::Normal(normal) => walk_attr_args(visitor, &normal.item.args),
|
||||
AttrKind::DocComment(..) => {}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn walk_mac_args<'a, V: Visitor<'a>>(visitor: &mut V, args: &'a MacArgs) {
|
||||
pub fn walk_attr_args<'a, V: Visitor<'a>>(visitor: &mut V, args: &'a AttrArgs) {
|
||||
match args {
|
||||
MacArgs::Empty => {}
|
||||
MacArgs::Delimited(_dspan, _delim, _tokens) => {}
|
||||
MacArgs::Eq(_eq_span, MacArgsEq::Ast(expr)) => visitor.visit_expr(expr),
|
||||
MacArgs::Eq(_, MacArgsEq::Hir(lit)) => {
|
||||
AttrArgs::Empty => {}
|
||||
AttrArgs::Delimited(_) => {}
|
||||
AttrArgs::Eq(_eq_span, AttrArgsEq::Ast(expr)) => visitor.visit_expr(expr),
|
||||
AttrArgs::Eq(_, AttrArgsEq::Hir(lit)) => {
|
||||
unreachable!("in literal form when walking mac args eq: {:?}", lit)
|
||||
}
|
||||
}
|
||||
|
||||
@ -21,5 +21,5 @@ rustc_session = { path = "../rustc_session" }
|
||||
rustc_span = { path = "../rustc_span" }
|
||||
rustc_target = { path = "../rustc_target" }
|
||||
smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
|
||||
thin-vec = "0.2.8"
|
||||
thin-vec = "0.2.9"
|
||||
tracing = "0.1"
|
||||
|
||||
@ -11,7 +11,7 @@ use super::LoweringContext;
|
||||
|
||||
use rustc_ast::ptr::P;
|
||||
use rustc_ast::*;
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::definitions::DefPathData;
|
||||
@ -71,7 +71,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
.emit();
|
||||
}
|
||||
|
||||
let mut clobber_abis = FxHashMap::default();
|
||||
let mut clobber_abis = FxIndexMap::default();
|
||||
if let Some(asm_arch) = asm_arch {
|
||||
for (abi_name, abi_span) in &asm.clobber_abis {
|
||||
match asm::InlineAsmClobberAbi::parse(asm_arch, &self.tcx.sess.target, *abi_name) {
|
||||
@ -123,7 +123,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
.operands
|
||||
.iter()
|
||||
.map(|(op, op_sp)| {
|
||||
let lower_reg = |reg| match reg {
|
||||
let lower_reg = |®: &_| match reg {
|
||||
InlineAsmRegOrRegClass::Reg(reg) => {
|
||||
asm::InlineAsmRegOrRegClass::Reg(if let Some(asm_arch) = asm_arch {
|
||||
asm::InlineAsmReg::parse(asm_arch, reg).unwrap_or_else(|error| {
|
||||
@ -152,32 +152,30 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
}
|
||||
};
|
||||
|
||||
let op = match *op {
|
||||
InlineAsmOperand::In { reg, ref expr } => hir::InlineAsmOperand::In {
|
||||
let op = match op {
|
||||
InlineAsmOperand::In { reg, expr } => hir::InlineAsmOperand::In {
|
||||
reg: lower_reg(reg),
|
||||
expr: self.lower_expr(expr),
|
||||
},
|
||||
InlineAsmOperand::Out { reg, late, ref expr } => hir::InlineAsmOperand::Out {
|
||||
InlineAsmOperand::Out { reg, late, expr } => hir::InlineAsmOperand::Out {
|
||||
reg: lower_reg(reg),
|
||||
late,
|
||||
late: *late,
|
||||
expr: expr.as_ref().map(|expr| self.lower_expr(expr)),
|
||||
},
|
||||
InlineAsmOperand::InOut { reg, late, ref expr } => {
|
||||
hir::InlineAsmOperand::InOut {
|
||||
reg: lower_reg(reg),
|
||||
late,
|
||||
expr: self.lower_expr(expr),
|
||||
}
|
||||
}
|
||||
InlineAsmOperand::SplitInOut { reg, late, ref in_expr, ref out_expr } => {
|
||||
InlineAsmOperand::InOut { reg, late, expr } => hir::InlineAsmOperand::InOut {
|
||||
reg: lower_reg(reg),
|
||||
late: *late,
|
||||
expr: self.lower_expr(expr),
|
||||
},
|
||||
InlineAsmOperand::SplitInOut { reg, late, in_expr, out_expr } => {
|
||||
hir::InlineAsmOperand::SplitInOut {
|
||||
reg: lower_reg(reg),
|
||||
late,
|
||||
late: *late,
|
||||
in_expr: self.lower_expr(in_expr),
|
||||
out_expr: out_expr.as_ref().map(|expr| self.lower_expr(expr)),
|
||||
}
|
||||
}
|
||||
InlineAsmOperand::Const { ref anon_const } => {
|
||||
InlineAsmOperand::Const { anon_const } => {
|
||||
if !self.tcx.features().asm_const {
|
||||
feature_err(
|
||||
&sess.parse_sess,
|
||||
@ -191,7 +189,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
anon_const: self.lower_anon_const(anon_const),
|
||||
}
|
||||
}
|
||||
InlineAsmOperand::Sym { ref sym } => {
|
||||
InlineAsmOperand::Sym { sym } => {
|
||||
let static_def_id = self
|
||||
.resolver
|
||||
.get_partial_res(sym.id)
|
||||
@ -224,7 +222,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
// Wrap the expression in an AnonConst.
|
||||
let parent_def_id = self.current_hir_id_owner;
|
||||
let node_id = self.next_node_id();
|
||||
self.create_def(parent_def_id.def_id, node_id, DefPathData::AnonConst);
|
||||
self.create_def(
|
||||
parent_def_id.def_id,
|
||||
node_id,
|
||||
DefPathData::AnonConst,
|
||||
*op_sp,
|
||||
);
|
||||
let anon_const = AnonConst { id: node_id, value: P(expr) };
|
||||
hir::InlineAsmOperand::SymFn {
|
||||
anon_const: self.lower_anon_const(&anon_const),
|
||||
@ -347,7 +350,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
skip = true;
|
||||
|
||||
let idx2 = *o.get();
|
||||
let &(ref op2, op_sp2) = &operands[idx2];
|
||||
let (ref op2, op_sp2) = operands[idx2];
|
||||
let Some(asm::InlineAsmRegOrRegClass::Reg(reg2)) = op2.reg() else {
|
||||
unreachable!();
|
||||
};
|
||||
|
||||
@ -31,8 +31,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
let mut stmts = SmallVec::<[hir::Stmt<'hir>; 8]>::new();
|
||||
let mut expr = None;
|
||||
while let [s, tail @ ..] = ast_stmts {
|
||||
match s.kind {
|
||||
StmtKind::Local(ref local) => {
|
||||
match &s.kind {
|
||||
StmtKind::Local(local) => {
|
||||
let hir_id = self.lower_node_id(s.id);
|
||||
let local = self.lower_local(local);
|
||||
self.alias_attrs(hir_id, local.hir_id);
|
||||
@ -40,7 +40,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
let span = self.lower_span(s.span);
|
||||
stmts.push(hir::Stmt { hir_id, kind, span });
|
||||
}
|
||||
StmtKind::Item(ref it) => {
|
||||
StmtKind::Item(it) => {
|
||||
stmts.extend(self.lower_item_ref(it).into_iter().enumerate().map(
|
||||
|(i, item_id)| {
|
||||
let hir_id = match i {
|
||||
@ -53,7 +53,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
},
|
||||
));
|
||||
}
|
||||
StmtKind::Expr(ref e) => {
|
||||
StmtKind::Expr(e) => {
|
||||
let e = self.lower_expr(e);
|
||||
if tail.is_empty() {
|
||||
expr = Some(e);
|
||||
@ -65,7 +65,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
stmts.push(hir::Stmt { hir_id, kind, span });
|
||||
}
|
||||
}
|
||||
StmtKind::Semi(ref e) => {
|
||||
StmtKind::Semi(e) => {
|
||||
let e = self.lower_expr(e);
|
||||
let hir_id = self.lower_node_id(s.id);
|
||||
self.alias_attrs(hir_id, e.hir_id);
|
||||
|
||||
@ -277,8 +277,9 @@ pub struct RegisterConflict<'a> {
|
||||
pub struct SubTupleBinding<'a> {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
#[suggestion_verbose(
|
||||
#[suggestion(
|
||||
ast_lowering_sub_tuple_binding_suggestion,
|
||||
style = "verbose",
|
||||
code = "..",
|
||||
applicability = "maybe-incorrect"
|
||||
)]
|
||||
|
||||
@ -14,6 +14,7 @@ use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::Res;
|
||||
use rustc_hir::definitions::DefPathData;
|
||||
use rustc_session::errors::report_lit_error;
|
||||
use rustc_span::source_map::{respan, DesugaringKind, Span, Spanned};
|
||||
use rustc_span::symbol::{sym, Ident};
|
||||
use rustc_span::DUMMY_SP;
|
||||
@ -30,20 +31,20 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
|
||||
pub(super) fn lower_expr_mut(&mut self, e: &Expr) -> hir::Expr<'hir> {
|
||||
ensure_sufficient_stack(|| {
|
||||
let kind = match e.kind {
|
||||
ExprKind::Box(ref inner) => hir::ExprKind::Box(self.lower_expr(inner)),
|
||||
ExprKind::Array(ref exprs) => hir::ExprKind::Array(self.lower_exprs(exprs)),
|
||||
ExprKind::ConstBlock(ref anon_const) => {
|
||||
let kind = match &e.kind {
|
||||
ExprKind::Box(inner) => hir::ExprKind::Box(self.lower_expr(inner)),
|
||||
ExprKind::Array(exprs) => hir::ExprKind::Array(self.lower_exprs(exprs)),
|
||||
ExprKind::ConstBlock(anon_const) => {
|
||||
let anon_const = self.lower_anon_const(anon_const);
|
||||
hir::ExprKind::ConstBlock(anon_const)
|
||||
}
|
||||
ExprKind::Repeat(ref expr, ref count) => {
|
||||
ExprKind::Repeat(expr, count) => {
|
||||
let expr = self.lower_expr(expr);
|
||||
let count = self.lower_array_length(count);
|
||||
hir::ExprKind::Repeat(expr, count)
|
||||
}
|
||||
ExprKind::Tup(ref elts) => hir::ExprKind::Tup(self.lower_exprs(elts)),
|
||||
ExprKind::Call(ref f, ref args) => {
|
||||
ExprKind::Tup(elts) => hir::ExprKind::Tup(self.lower_exprs(elts)),
|
||||
ExprKind::Call(f, args) => {
|
||||
if e.attrs.get(0).map_or(false, |a| a.has_name(sym::rustc_box)) {
|
||||
if let [inner] = &args[..] && e.attrs.len() == 1 {
|
||||
let kind = hir::ExprKind::Box(self.lower_expr(&inner));
|
||||
@ -60,7 +61,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
hir::ExprKind::Call(f, self.lower_exprs(args))
|
||||
}
|
||||
}
|
||||
ExprKind::MethodCall(ref seg, ref receiver, ref args, span) => {
|
||||
ExprKind::MethodCall(box MethodCall { seg, receiver, args, span }) => {
|
||||
let hir_seg = self.arena.alloc(self.lower_path_segment(
|
||||
e.span,
|
||||
seg,
|
||||
@ -71,81 +72,89 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
let receiver = self.lower_expr(receiver);
|
||||
let args =
|
||||
self.arena.alloc_from_iter(args.iter().map(|x| self.lower_expr_mut(x)));
|
||||
hir::ExprKind::MethodCall(hir_seg, receiver, args, self.lower_span(span))
|
||||
hir::ExprKind::MethodCall(hir_seg, receiver, args, self.lower_span(*span))
|
||||
}
|
||||
ExprKind::Binary(binop, ref lhs, ref rhs) => {
|
||||
let binop = self.lower_binop(binop);
|
||||
ExprKind::Binary(binop, lhs, rhs) => {
|
||||
let binop = self.lower_binop(*binop);
|
||||
let lhs = self.lower_expr(lhs);
|
||||
let rhs = self.lower_expr(rhs);
|
||||
hir::ExprKind::Binary(binop, lhs, rhs)
|
||||
}
|
||||
ExprKind::Unary(op, ref ohs) => {
|
||||
let op = self.lower_unop(op);
|
||||
ExprKind::Unary(op, ohs) => {
|
||||
let op = self.lower_unop(*op);
|
||||
let ohs = self.lower_expr(ohs);
|
||||
hir::ExprKind::Unary(op, ohs)
|
||||
}
|
||||
ExprKind::Lit(ref l) => {
|
||||
hir::ExprKind::Lit(respan(self.lower_span(l.span), l.kind.clone()))
|
||||
ExprKind::Lit(token_lit) => {
|
||||
let lit_kind = match LitKind::from_token_lit(*token_lit) {
|
||||
Ok(lit_kind) => lit_kind,
|
||||
Err(err) => {
|
||||
report_lit_error(&self.tcx.sess.parse_sess, err, *token_lit, e.span);
|
||||
LitKind::Err
|
||||
}
|
||||
};
|
||||
hir::ExprKind::Lit(respan(self.lower_span(e.span), lit_kind))
|
||||
}
|
||||
ExprKind::Cast(ref expr, ref ty) => {
|
||||
ExprKind::IncludedBytes(bytes) => hir::ExprKind::Lit(respan(
|
||||
self.lower_span(e.span),
|
||||
LitKind::ByteStr(bytes.clone()),
|
||||
)),
|
||||
ExprKind::Cast(expr, ty) => {
|
||||
let expr = self.lower_expr(expr);
|
||||
let ty =
|
||||
self.lower_ty(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Type));
|
||||
hir::ExprKind::Cast(expr, ty)
|
||||
}
|
||||
ExprKind::Type(ref expr, ref ty) => {
|
||||
ExprKind::Type(expr, ty) => {
|
||||
let expr = self.lower_expr(expr);
|
||||
let ty =
|
||||
self.lower_ty(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Type));
|
||||
hir::ExprKind::Type(expr, ty)
|
||||
}
|
||||
ExprKind::AddrOf(k, m, ref ohs) => {
|
||||
ExprKind::AddrOf(k, m, ohs) => {
|
||||
let ohs = self.lower_expr(ohs);
|
||||
hir::ExprKind::AddrOf(k, m, ohs)
|
||||
hir::ExprKind::AddrOf(*k, *m, ohs)
|
||||
}
|
||||
ExprKind::Let(ref pat, ref scrutinee, span) => {
|
||||
ExprKind::Let(pat, scrutinee, span) => {
|
||||
hir::ExprKind::Let(self.arena.alloc(hir::Let {
|
||||
hir_id: self.next_id(),
|
||||
span: self.lower_span(span),
|
||||
span: self.lower_span(*span),
|
||||
pat: self.lower_pat(pat),
|
||||
ty: None,
|
||||
init: self.lower_expr(scrutinee),
|
||||
}))
|
||||
}
|
||||
ExprKind::If(ref cond, ref then, ref else_opt) => {
|
||||
ExprKind::If(cond, then, else_opt) => {
|
||||
self.lower_expr_if(cond, then, else_opt.as_deref())
|
||||
}
|
||||
ExprKind::While(ref cond, ref body, opt_label) => {
|
||||
self.with_loop_scope(e.id, |this| {
|
||||
let span =
|
||||
this.mark_span_with_reason(DesugaringKind::WhileLoop, e.span, None);
|
||||
this.lower_expr_while_in_loop_scope(span, cond, body, opt_label)
|
||||
})
|
||||
}
|
||||
ExprKind::Loop(ref body, opt_label) => self.with_loop_scope(e.id, |this| {
|
||||
ExprKind::While(cond, body, opt_label) => self.with_loop_scope(e.id, |this| {
|
||||
let span = this.mark_span_with_reason(DesugaringKind::WhileLoop, e.span, None);
|
||||
this.lower_expr_while_in_loop_scope(span, cond, body, *opt_label)
|
||||
}),
|
||||
ExprKind::Loop(body, opt_label, span) => self.with_loop_scope(e.id, |this| {
|
||||
hir::ExprKind::Loop(
|
||||
this.lower_block(body, false),
|
||||
this.lower_label(opt_label),
|
||||
this.lower_label(*opt_label),
|
||||
hir::LoopSource::Loop,
|
||||
DUMMY_SP,
|
||||
this.lower_span(*span),
|
||||
)
|
||||
}),
|
||||
ExprKind::TryBlock(ref body) => self.lower_expr_try_block(body),
|
||||
ExprKind::Match(ref expr, ref arms) => hir::ExprKind::Match(
|
||||
ExprKind::TryBlock(body) => self.lower_expr_try_block(body),
|
||||
ExprKind::Match(expr, arms) => hir::ExprKind::Match(
|
||||
self.lower_expr(expr),
|
||||
self.arena.alloc_from_iter(arms.iter().map(|x| self.lower_arm(x))),
|
||||
hir::MatchSource::Normal,
|
||||
),
|
||||
ExprKind::Async(capture_clause, closure_node_id, ref block) => self
|
||||
.make_async_expr(
|
||||
capture_clause,
|
||||
closure_node_id,
|
||||
None,
|
||||
block.span,
|
||||
hir::AsyncGeneratorKind::Block,
|
||||
|this| this.with_new_scopes(|this| this.lower_block_expr(block)),
|
||||
),
|
||||
ExprKind::Await(ref expr) => {
|
||||
ExprKind::Async(capture_clause, closure_node_id, block) => self.make_async_expr(
|
||||
*capture_clause,
|
||||
None,
|
||||
*closure_node_id,
|
||||
None,
|
||||
e.span,
|
||||
hir::AsyncGeneratorKind::Block,
|
||||
|this| this.with_new_scopes(|this| this.lower_block_expr(block)),
|
||||
),
|
||||
ExprKind::Await(expr) => {
|
||||
let dot_await_span = if expr.span.hi() < e.span.hi() {
|
||||
let span_with_whitespace = self
|
||||
.tcx
|
||||
@ -160,66 +169,67 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
};
|
||||
self.lower_expr_await(dot_await_span, expr)
|
||||
}
|
||||
ExprKind::Closure(
|
||||
ref binder,
|
||||
ExprKind::Closure(box Closure {
|
||||
binder,
|
||||
capture_clause,
|
||||
asyncness,
|
||||
movability,
|
||||
ref decl,
|
||||
ref body,
|
||||
fn_decl,
|
||||
body,
|
||||
fn_decl_span,
|
||||
) => {
|
||||
fn_arg_span,
|
||||
}) => {
|
||||
if let Async::Yes { closure_id, .. } = asyncness {
|
||||
self.lower_expr_async_closure(
|
||||
binder,
|
||||
capture_clause,
|
||||
*capture_clause,
|
||||
e.id,
|
||||
closure_id,
|
||||
decl,
|
||||
*closure_id,
|
||||
fn_decl,
|
||||
body,
|
||||
fn_decl_span,
|
||||
*fn_decl_span,
|
||||
*fn_arg_span,
|
||||
)
|
||||
} else {
|
||||
self.lower_expr_closure(
|
||||
binder,
|
||||
capture_clause,
|
||||
*capture_clause,
|
||||
e.id,
|
||||
movability,
|
||||
decl,
|
||||
*movability,
|
||||
fn_decl,
|
||||
body,
|
||||
fn_decl_span,
|
||||
*fn_decl_span,
|
||||
*fn_arg_span,
|
||||
)
|
||||
}
|
||||
}
|
||||
ExprKind::Block(ref blk, opt_label) => {
|
||||
let opt_label = self.lower_label(opt_label);
|
||||
ExprKind::Block(blk, opt_label) => {
|
||||
let opt_label = self.lower_label(*opt_label);
|
||||
hir::ExprKind::Block(self.lower_block(blk, opt_label.is_some()), opt_label)
|
||||
}
|
||||
ExprKind::Assign(ref el, ref er, span) => {
|
||||
self.lower_expr_assign(el, er, span, e.span)
|
||||
}
|
||||
ExprKind::AssignOp(op, ref el, ref er) => hir::ExprKind::AssignOp(
|
||||
self.lower_binop(op),
|
||||
ExprKind::Assign(el, er, span) => self.lower_expr_assign(el, er, *span, e.span),
|
||||
ExprKind::AssignOp(op, el, er) => hir::ExprKind::AssignOp(
|
||||
self.lower_binop(*op),
|
||||
self.lower_expr(el),
|
||||
self.lower_expr(er),
|
||||
),
|
||||
ExprKind::Field(ref el, ident) => {
|
||||
hir::ExprKind::Field(self.lower_expr(el), self.lower_ident(ident))
|
||||
ExprKind::Field(el, ident) => {
|
||||
hir::ExprKind::Field(self.lower_expr(el), self.lower_ident(*ident))
|
||||
}
|
||||
ExprKind::Index(ref el, ref er) => {
|
||||
ExprKind::Index(el, er) => {
|
||||
hir::ExprKind::Index(self.lower_expr(el), self.lower_expr(er))
|
||||
}
|
||||
ExprKind::Range(Some(ref e1), Some(ref e2), RangeLimits::Closed) => {
|
||||
ExprKind::Range(Some(e1), Some(e2), RangeLimits::Closed) => {
|
||||
self.lower_expr_range_closed(e.span, e1, e2)
|
||||
}
|
||||
ExprKind::Range(ref e1, ref e2, lims) => {
|
||||
self.lower_expr_range(e.span, e1.as_deref(), e2.as_deref(), lims)
|
||||
ExprKind::Range(e1, e2, lims) => {
|
||||
self.lower_expr_range(e.span, e1.as_deref(), e2.as_deref(), *lims)
|
||||
}
|
||||
ExprKind::Underscore => {
|
||||
self.tcx.sess.emit_err(UnderscoreExprLhsAssign { span: e.span });
|
||||
hir::ExprKind::Err
|
||||
}
|
||||
ExprKind::Path(ref qself, ref path) => {
|
||||
ExprKind::Path(qself, path) => {
|
||||
let qpath = self.lower_qpath(
|
||||
e.id,
|
||||
qself,
|
||||
@ -229,22 +239,22 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
);
|
||||
hir::ExprKind::Path(qpath)
|
||||
}
|
||||
ExprKind::Break(opt_label, ref opt_expr) => {
|
||||
ExprKind::Break(opt_label, opt_expr) => {
|
||||
let opt_expr = opt_expr.as_ref().map(|x| self.lower_expr(x));
|
||||
hir::ExprKind::Break(self.lower_jump_destination(e.id, opt_label), opt_expr)
|
||||
hir::ExprKind::Break(self.lower_jump_destination(e.id, *opt_label), opt_expr)
|
||||
}
|
||||
ExprKind::Continue(opt_label) => {
|
||||
hir::ExprKind::Continue(self.lower_jump_destination(e.id, opt_label))
|
||||
hir::ExprKind::Continue(self.lower_jump_destination(e.id, *opt_label))
|
||||
}
|
||||
ExprKind::Ret(ref e) => {
|
||||
ExprKind::Ret(e) => {
|
||||
let e = e.as_ref().map(|x| self.lower_expr(x));
|
||||
hir::ExprKind::Ret(e)
|
||||
}
|
||||
ExprKind::Yeet(ref sub_expr) => self.lower_expr_yeet(e.span, sub_expr.as_deref()),
|
||||
ExprKind::InlineAsm(ref asm) => {
|
||||
ExprKind::Yeet(sub_expr) => self.lower_expr_yeet(e.span, sub_expr.as_deref()),
|
||||
ExprKind::InlineAsm(asm) => {
|
||||
hir::ExprKind::InlineAsm(self.lower_inline_asm(e.span, asm))
|
||||
}
|
||||
ExprKind::Struct(ref se) => {
|
||||
ExprKind::Struct(se) => {
|
||||
let rest = match &se.rest {
|
||||
StructRest::Base(e) => Some(self.lower_expr(e)),
|
||||
StructRest::Rest(sp) => {
|
||||
@ -266,10 +276,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
rest,
|
||||
)
|
||||
}
|
||||
ExprKind::Yield(ref opt_expr) => self.lower_expr_yield(e.span, opt_expr.as_deref()),
|
||||
ExprKind::Yield(opt_expr) => self.lower_expr_yield(e.span, opt_expr.as_deref()),
|
||||
ExprKind::Err => hir::ExprKind::Err,
|
||||
ExprKind::Try(ref sub_expr) => self.lower_expr_try(e.span, sub_expr),
|
||||
ExprKind::Paren(ref ex) => {
|
||||
ExprKind::Try(sub_expr) => self.lower_expr_try(e.span, sub_expr),
|
||||
ExprKind::Paren(ex) => {
|
||||
let mut ex = self.lower_expr_mut(ex);
|
||||
// Include parens in span, but only if it is a super-span.
|
||||
if e.span.contains(ex.span) {
|
||||
@ -294,8 +304,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
|
||||
// Desugar `ExprForLoop`
|
||||
// from: `[opt_ident]: for <pat> in <head> <body>`
|
||||
ExprKind::ForLoop(ref pat, ref head, ref body, opt_label) => {
|
||||
return self.lower_expr_for(e, pat, head, body, opt_label);
|
||||
ExprKind::ForLoop(pat, head, body, opt_label) => {
|
||||
return self.lower_expr_for(e, pat, head, body, *opt_label);
|
||||
}
|
||||
ExprKind::MacCall(_) => panic!("{:?} shouldn't exist here", e.span),
|
||||
};
|
||||
@ -346,7 +356,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
args: Vec<AstP<Expr>>,
|
||||
legacy_args_idx: &[usize],
|
||||
) -> hir::ExprKind<'hir> {
|
||||
let ExprKind::Path(None, ref mut path) = f.kind else {
|
||||
let ExprKind::Path(None, path) = &mut f.kind else {
|
||||
unreachable!();
|
||||
};
|
||||
|
||||
@ -359,7 +369,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
let node_id = self.next_node_id();
|
||||
|
||||
// Add a definition for the in-band const def.
|
||||
self.create_def(parent_def_id.def_id, node_id, DefPathData::AnonConst);
|
||||
self.create_def(parent_def_id.def_id, node_id, DefPathData::AnonConst, f.span);
|
||||
|
||||
let anon_const = AnonConst { id: node_id, value: arg };
|
||||
generic_args.push(AngleBracketedArg::Arg(GenericArg::Const(anon_const)));
|
||||
@ -426,18 +436,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
let lhs = self.lower_cond(lhs);
|
||||
let rhs = self.lower_cond(rhs);
|
||||
|
||||
self.arena.alloc(self.expr(
|
||||
cond.span,
|
||||
hir::ExprKind::Binary(op, lhs, rhs),
|
||||
AttrVec::new(),
|
||||
))
|
||||
self.arena.alloc(self.expr(cond.span, hir::ExprKind::Binary(op, lhs, rhs)))
|
||||
}
|
||||
ExprKind::Let(..) => self.lower_expr(cond),
|
||||
_ => {
|
||||
let cond = self.lower_expr(cond);
|
||||
let reason = DesugaringKind::CondTemporary;
|
||||
let span_block = self.mark_span_with_reason(reason, cond.span, None);
|
||||
self.expr_drop_temps(span_block, cond, AttrVec::new())
|
||||
self.expr_drop_temps(span_block, cond)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -467,12 +473,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
) -> hir::ExprKind<'hir> {
|
||||
let lowered_cond = self.with_loop_condition_scope(|t| t.lower_cond(cond));
|
||||
let then = self.lower_block_expr(body);
|
||||
let expr_break = self.expr_break(span, AttrVec::new());
|
||||
let expr_break = self.expr_break(span);
|
||||
let stmt_break = self.stmt_expr(span, expr_break);
|
||||
let else_blk = self.block_all(span, arena_vec![self; stmt_break], None);
|
||||
let else_expr = self.arena.alloc(self.expr_block(else_blk, AttrVec::new()));
|
||||
let else_expr = self.arena.alloc(self.expr_block(else_blk));
|
||||
let if_kind = hir::ExprKind::If(lowered_cond, self.arena.alloc(then), Some(else_expr));
|
||||
let if_expr = self.expr(span, if_kind, AttrVec::new());
|
||||
let if_expr = self.expr(span, if_kind);
|
||||
let block = self.block_expr(self.arena.alloc(if_expr));
|
||||
let span = self.lower_span(span.with_hi(cond.span.hi()));
|
||||
let opt_label = self.lower_label(opt_label);
|
||||
@ -528,22 +534,17 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
expr: &'hir hir::Expr<'hir>,
|
||||
overall_span: Span,
|
||||
) -> &'hir hir::Expr<'hir> {
|
||||
let constructor = self.arena.alloc(self.expr_lang_item_path(
|
||||
method_span,
|
||||
lang_item,
|
||||
AttrVec::new(),
|
||||
None,
|
||||
));
|
||||
let constructor = self.arena.alloc(self.expr_lang_item_path(method_span, lang_item, None));
|
||||
self.expr_call(overall_span, constructor, std::slice::from_ref(expr))
|
||||
}
|
||||
|
||||
fn lower_arm(&mut self, arm: &Arm) -> hir::Arm<'hir> {
|
||||
let pat = self.lower_pat(&arm.pat);
|
||||
let guard = arm.guard.as_ref().map(|cond| {
|
||||
if let ExprKind::Let(ref pat, ref scrutinee, span) = cond.kind {
|
||||
if let ExprKind::Let(pat, scrutinee, span) = &cond.kind {
|
||||
hir::Guard::IfLet(self.arena.alloc(hir::Let {
|
||||
hir_id: self.next_id(),
|
||||
span: self.lower_span(span),
|
||||
span: self.lower_span(*span),
|
||||
pat: self.lower_pat(pat),
|
||||
ty: None,
|
||||
init: self.lower_expr(scrutinee),
|
||||
@ -563,37 +564,35 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Lower an `async` construct to a generator that is then wrapped so it implements `Future`.
|
||||
/// Lower an `async` construct to a generator that implements `Future`.
|
||||
///
|
||||
/// This results in:
|
||||
///
|
||||
/// ```text
|
||||
/// std::future::from_generator(static move? |_task_context| -> <ret_ty> {
|
||||
/// std::future::identity_future(static move? |_task_context| -> <ret_ty> {
|
||||
/// <body>
|
||||
/// })
|
||||
/// ```
|
||||
pub(super) fn make_async_expr(
|
||||
&mut self,
|
||||
capture_clause: CaptureBy,
|
||||
outer_hir_id: Option<hir::HirId>,
|
||||
closure_node_id: NodeId,
|
||||
ret_ty: Option<AstP<Ty>>,
|
||||
ret_ty: Option<hir::FnRetTy<'hir>>,
|
||||
span: Span,
|
||||
async_gen_kind: hir::AsyncGeneratorKind,
|
||||
body: impl FnOnce(&mut Self) -> hir::Expr<'hir>,
|
||||
) -> hir::ExprKind<'hir> {
|
||||
let output = match ret_ty {
|
||||
Some(ty) => hir::FnRetTy::Return(
|
||||
self.lower_ty(&ty, &ImplTraitContext::Disallowed(ImplTraitPosition::AsyncBlock)),
|
||||
),
|
||||
None => hir::FnRetTy::DefaultReturn(self.lower_span(span)),
|
||||
};
|
||||
let output = ret_ty.unwrap_or_else(|| hir::FnRetTy::DefaultReturn(self.lower_span(span)));
|
||||
|
||||
// Resume argument type. We let the compiler infer this to simplify the lowering. It is
|
||||
// fully constrained by `future::from_generator`.
|
||||
// Resume argument type: `ResumeTy`
|
||||
let unstable_span =
|
||||
self.mark_span_with_reason(DesugaringKind::Async, span, self.allow_gen_future.clone());
|
||||
let resume_ty = hir::QPath::LangItem(hir::LangItem::ResumeTy, unstable_span, None);
|
||||
let input_ty = hir::Ty {
|
||||
hir_id: self.next_id(),
|
||||
kind: hir::TyKind::Infer,
|
||||
span: self.lower_span(span),
|
||||
kind: hir::TyKind::Path(resume_ty),
|
||||
span: unstable_span,
|
||||
};
|
||||
|
||||
// The closure/generator `FnDecl` takes a single (resume) argument of type `input_ty`.
|
||||
@ -602,6 +601,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
output,
|
||||
c_variadic: false,
|
||||
implicit_self: hir::ImplicitSelfKind::None,
|
||||
lifetime_elision_allowed: false,
|
||||
});
|
||||
|
||||
// Lower the argument pattern/ident. The ident is used again in the `.await` lowering.
|
||||
@ -631,35 +631,63 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
// `static |_task_context| -> <ret_ty> { body }`:
|
||||
let generator_kind = {
|
||||
let c = self.arena.alloc(hir::Closure {
|
||||
def_id: self.local_def_id(closure_node_id),
|
||||
binder: hir::ClosureBinder::Default,
|
||||
capture_clause,
|
||||
bound_generic_params: &[],
|
||||
fn_decl,
|
||||
body,
|
||||
fn_decl_span: self.lower_span(span),
|
||||
fn_arg_span: None,
|
||||
movability: Some(hir::Movability::Static),
|
||||
});
|
||||
|
||||
hir::ExprKind::Closure(c)
|
||||
};
|
||||
let generator = hir::Expr {
|
||||
hir_id: self.lower_node_id(closure_node_id),
|
||||
kind: generator_kind,
|
||||
span: self.lower_span(span),
|
||||
};
|
||||
|
||||
// `future::from_generator`:
|
||||
let hir_id = self.lower_node_id(closure_node_id);
|
||||
let unstable_span =
|
||||
self.mark_span_with_reason(DesugaringKind::Async, span, self.allow_gen_future.clone());
|
||||
let gen_future = self.expr_lang_item_path(
|
||||
unstable_span,
|
||||
hir::LangItem::FromGenerator,
|
||||
AttrVec::new(),
|
||||
None,
|
||||
);
|
||||
|
||||
// `future::from_generator(generator)`:
|
||||
hir::ExprKind::Call(self.arena.alloc(gen_future), arena_vec![self; generator])
|
||||
if self.tcx.features().closure_track_caller
|
||||
&& let Some(outer_hir_id) = outer_hir_id
|
||||
&& let Some(attrs) = self.attrs.get(&outer_hir_id.local_id)
|
||||
&& attrs.into_iter().any(|attr| attr.has_name(sym::track_caller))
|
||||
{
|
||||
self.lower_attrs(
|
||||
hir_id,
|
||||
&[Attribute {
|
||||
kind: AttrKind::Normal(ptr::P(NormalAttr {
|
||||
item: AttrItem {
|
||||
path: Path::from_ident(Ident::new(sym::track_caller, span)),
|
||||
args: AttrArgs::Empty,
|
||||
tokens: None,
|
||||
},
|
||||
tokens: None,
|
||||
})),
|
||||
id: self.tcx.sess.parse_sess.attr_id_generator.mk_attr_id(),
|
||||
style: AttrStyle::Outer,
|
||||
span: unstable_span,
|
||||
}],
|
||||
);
|
||||
}
|
||||
|
||||
let generator = hir::Expr { hir_id, kind: generator_kind, span: self.lower_span(span) };
|
||||
|
||||
// FIXME(swatinem):
|
||||
// For some reason, the async block needs to flow through *any*
|
||||
// call (like the identity function), as otherwise type and lifetime
|
||||
// inference have a hard time figuring things out.
|
||||
// Without this, we would get:
|
||||
// E0720 in src/test/ui/impl-trait/in-trait/default-body-with-rpit.rs
|
||||
// E0700 in src/test/ui/self/self_lifetime-async.rs
|
||||
|
||||
// `future::identity_future`:
|
||||
let identity_future =
|
||||
self.expr_lang_item_path(unstable_span, hir::LangItem::IdentityFuture, None);
|
||||
|
||||
// `future::identity_future(generator)`:
|
||||
hir::ExprKind::Call(self.arena.alloc(identity_future), arena_vec![self; generator])
|
||||
}
|
||||
|
||||
/// Desugar `<expr>.await` into:
|
||||
@ -759,7 +787,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
let break_x = self.with_loop_scope(loop_node_id, move |this| {
|
||||
let expr_break =
|
||||
hir::ExprKind::Break(this.lower_loop_destination(None), Some(x_expr));
|
||||
this.arena.alloc(this.expr(gen_future_span, expr_break, AttrVec::new()))
|
||||
this.arena.alloc(this.expr(gen_future_span, expr_break))
|
||||
});
|
||||
self.arm(ready_pat, break_x)
|
||||
};
|
||||
@ -792,17 +820,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
let yield_expr = self.expr(
|
||||
span,
|
||||
hir::ExprKind::Yield(unit, hir::YieldSource::Await { expr: Some(expr_hir_id) }),
|
||||
AttrVec::new(),
|
||||
);
|
||||
let yield_expr = self.arena.alloc(yield_expr);
|
||||
|
||||
if let Some(task_context_hid) = self.task_context {
|
||||
let lhs = self.expr_ident(span, task_context_ident, task_context_hid);
|
||||
let assign = self.expr(
|
||||
span,
|
||||
hir::ExprKind::Assign(lhs, yield_expr, self.lower_span(span)),
|
||||
AttrVec::new(),
|
||||
);
|
||||
let assign =
|
||||
self.expr(span, hir::ExprKind::Assign(lhs, yield_expr, self.lower_span(span)));
|
||||
self.stmt_expr(span, assign)
|
||||
} else {
|
||||
// Use of `await` outside of an async context. Return `yield_expr` so that we can
|
||||
@ -860,6 +884,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
decl: &FnDecl,
|
||||
body: &Expr,
|
||||
fn_decl_span: Span,
|
||||
fn_arg_span: Span,
|
||||
) -> hir::ExprKind<'hir> {
|
||||
let (binder_clause, generic_params) = self.lower_closure_binder(binder);
|
||||
|
||||
@ -880,15 +905,17 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
|
||||
let bound_generic_params = self.lower_lifetime_binder(closure_id, generic_params);
|
||||
// Lower outside new scope to preserve `is_in_loop_condition`.
|
||||
let fn_decl = self.lower_fn_decl(decl, None, fn_decl_span, FnDeclKind::Closure, None);
|
||||
let fn_decl = self.lower_fn_decl(decl, closure_id, fn_decl_span, FnDeclKind::Closure, None);
|
||||
|
||||
let c = self.arena.alloc(hir::Closure {
|
||||
def_id: self.local_def_id(closure_id),
|
||||
binder: binder_clause,
|
||||
capture_clause,
|
||||
bound_generic_params,
|
||||
fn_decl,
|
||||
body: body_id,
|
||||
fn_decl_span: self.lower_span(fn_decl_span),
|
||||
fn_arg_span: Some(self.lower_span(fn_arg_span)),
|
||||
movability: generator_option,
|
||||
});
|
||||
|
||||
@ -927,8 +954,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
) -> (hir::ClosureBinder, &'c [GenericParam]) {
|
||||
let (binder, params) = match binder {
|
||||
ClosureBinder::NotPresent => (hir::ClosureBinder::Default, &[][..]),
|
||||
&ClosureBinder::For { span, ref generic_params } => {
|
||||
let span = self.lower_span(span);
|
||||
ClosureBinder::For { span, generic_params } => {
|
||||
let span = self.lower_span(*span);
|
||||
(hir::ClosureBinder::For { span }, &**generic_params)
|
||||
}
|
||||
};
|
||||
@ -945,6 +972,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
decl: &FnDecl,
|
||||
body: &Expr,
|
||||
fn_decl_span: Span,
|
||||
fn_arg_span: Span,
|
||||
) -> hir::ExprKind<'hir> {
|
||||
if let &ClosureBinder::For { span, .. } = binder {
|
||||
self.tcx.sess.emit_err(NotSupportedForLifetimeBinderAsyncClosure { span });
|
||||
@ -962,19 +990,27 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
}
|
||||
|
||||
// Transform `async |x: u8| -> X { ... }` into
|
||||
// `|x: u8| future_from_generator(|| -> X { ... })`.
|
||||
// `|x: u8| identity_future(|| -> X { ... })`.
|
||||
let body_id = this.lower_fn_body(&outer_decl, |this| {
|
||||
let async_ret_ty =
|
||||
if let FnRetTy::Ty(ty) = &decl.output { Some(ty.clone()) } else { None };
|
||||
let async_ret_ty = if let FnRetTy::Ty(ty) = &decl.output {
|
||||
let itctx = ImplTraitContext::Disallowed(ImplTraitPosition::AsyncBlock);
|
||||
Some(hir::FnRetTy::Return(this.lower_ty(&ty, &itctx)))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let async_body = this.make_async_expr(
|
||||
capture_clause,
|
||||
// FIXME(nbdd0121): This should also use a proper HIR id so `#[track_caller]`
|
||||
// can be applied on async closures as well.
|
||||
None,
|
||||
inner_closure_id,
|
||||
async_ret_ty,
|
||||
body.span,
|
||||
hir::AsyncGeneratorKind::Closure,
|
||||
|this| this.with_new_scopes(|this| this.lower_expr_mut(body)),
|
||||
);
|
||||
this.expr(fn_decl_span, async_body, AttrVec::new())
|
||||
this.expr(fn_decl_span, async_body)
|
||||
});
|
||||
body_id
|
||||
});
|
||||
@ -984,15 +1020,17 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
// have to conserve the state of being inside a loop condition for the
|
||||
// closure argument types.
|
||||
let fn_decl =
|
||||
self.lower_fn_decl(&outer_decl, None, fn_decl_span, FnDeclKind::Closure, None);
|
||||
self.lower_fn_decl(&outer_decl, closure_id, fn_decl_span, FnDeclKind::Closure, None);
|
||||
|
||||
let c = self.arena.alloc(hir::Closure {
|
||||
def_id: self.local_def_id(closure_id),
|
||||
binder: binder_clause,
|
||||
capture_clause,
|
||||
bound_generic_params,
|
||||
fn_decl,
|
||||
body,
|
||||
fn_decl_span: self.lower_span(fn_decl_span),
|
||||
fn_arg_span: Some(self.lower_span(fn_arg_span)),
|
||||
movability: None,
|
||||
});
|
||||
hir::ExprKind::Closure(c)
|
||||
@ -1065,7 +1103,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
fn extract_tuple_struct_path<'a>(
|
||||
&mut self,
|
||||
expr: &'a Expr,
|
||||
) -> Option<(&'a Option<QSelf>, &'a Path)> {
|
||||
) -> Option<(&'a Option<AstP<QSelf>>, &'a Path)> {
|
||||
if let ExprKind::Path(qself, path) = &expr.kind {
|
||||
// Does the path resolve to something disallowed in a tuple struct/variant pattern?
|
||||
if let Some(partial_res) = self.resolver.get_partial_res(expr.id) {
|
||||
@ -1085,7 +1123,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
fn extract_unit_struct_path<'a>(
|
||||
&mut self,
|
||||
expr: &'a Expr,
|
||||
) -> Option<(&'a Option<QSelf>, &'a Path)> {
|
||||
) -> Option<(&'a Option<AstP<QSelf>>, &'a Path)> {
|
||||
if let ExprKind::Path(qself, path) = &expr.kind {
|
||||
// Does the path resolve to something disallowed in a unit struct/variant pattern?
|
||||
if let Some(partial_res) = self.resolver.get_partial_res(expr.id) {
|
||||
@ -1232,7 +1270,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
let ident = self.expr_ident(lhs.span, ident, binding);
|
||||
let assign =
|
||||
hir::ExprKind::Assign(self.lower_expr(lhs), ident, self.lower_span(eq_sign_span));
|
||||
let expr = self.expr(lhs.span, assign, AttrVec::new());
|
||||
let expr = self.expr(lhs.span, assign);
|
||||
assignments.push(self.stmt_expr(lhs.span, expr));
|
||||
pat
|
||||
}
|
||||
@ -1273,8 +1311,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
let e2 = self.lower_expr_mut(e2);
|
||||
let fn_path =
|
||||
hir::QPath::LangItem(hir::LangItem::RangeInclusiveNew, self.lower_span(span), None);
|
||||
let fn_expr =
|
||||
self.arena.alloc(self.expr(span, hir::ExprKind::Path(fn_path), AttrVec::new()));
|
||||
let fn_expr = self.arena.alloc(self.expr(span, hir::ExprKind::Path(fn_path)));
|
||||
hir::ExprKind::Call(fn_expr, arena_vec![self; e1, e2])
|
||||
}
|
||||
|
||||
@ -1446,8 +1483,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
|
||||
// `None => break`
|
||||
let none_arm = {
|
||||
let break_expr =
|
||||
self.with_loop_scope(e.id, |this| this.expr_break_alloc(for_span, AttrVec::new()));
|
||||
let break_expr = self.with_loop_scope(e.id, |this| this.expr_break_alloc(for_span));
|
||||
let pat = self.pat_none(for_span);
|
||||
self.arm(pat, break_expr)
|
||||
};
|
||||
@ -1456,7 +1492,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
let some_arm = {
|
||||
let some_pat = self.pat_some(pat_span, pat);
|
||||
let body_block = self.with_loop_scope(e.id, |this| this.lower_block(body, false));
|
||||
let body_expr = self.arena.alloc(self.expr_block(body_block, AttrVec::new()));
|
||||
let body_expr = self.arena.alloc(self.expr_block(body_block));
|
||||
self.arm(some_pat, body_expr)
|
||||
};
|
||||
|
||||
@ -1519,7 +1555,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
// surrounding scope of the `match` since the `match` is not a terminating scope.
|
||||
//
|
||||
// Also, add the attributes to the outer returned expr node.
|
||||
self.expr_drop_temps_mut(for_span, match_expr, e.attrs.clone())
|
||||
let expr = self.expr_drop_temps_mut(for_span, match_expr);
|
||||
self.lower_attrs(expr.hir_id, &e.attrs);
|
||||
expr
|
||||
}
|
||||
|
||||
/// Desugar `ExprKind::Try` from: `<expr>?` into:
|
||||
@ -1561,28 +1599,21 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
};
|
||||
|
||||
// `#[allow(unreachable_code)]`
|
||||
let attr = {
|
||||
// `allow(unreachable_code)`
|
||||
let allow = {
|
||||
let allow_ident = Ident::new(sym::allow, self.lower_span(span));
|
||||
let uc_ident = Ident::new(sym::unreachable_code, self.lower_span(span));
|
||||
let uc_nested = attr::mk_nested_word_item(uc_ident);
|
||||
attr::mk_list_item(allow_ident, vec![uc_nested])
|
||||
};
|
||||
attr::mk_attr_outer(&self.tcx.sess.parse_sess.attr_id_generator, allow)
|
||||
};
|
||||
let attr = attr::mk_attr_nested_word(
|
||||
&self.tcx.sess.parse_sess.attr_id_generator,
|
||||
AttrStyle::Outer,
|
||||
sym::allow,
|
||||
sym::unreachable_code,
|
||||
self.lower_span(span),
|
||||
);
|
||||
let attrs: AttrVec = thin_vec![attr];
|
||||
|
||||
// `ControlFlow::Continue(val) => #[allow(unreachable_code)] val,`
|
||||
let continue_arm = {
|
||||
let val_ident = Ident::with_dummy_span(sym::val);
|
||||
let (val_pat, val_pat_nid) = self.pat_ident(span, val_ident);
|
||||
let val_expr = self.arena.alloc(self.expr_ident_with_attrs(
|
||||
span,
|
||||
val_ident,
|
||||
val_pat_nid,
|
||||
attrs.clone(),
|
||||
));
|
||||
let val_expr = self.expr_ident(span, val_ident, val_pat_nid);
|
||||
self.lower_attrs(val_expr.hir_id, &attrs);
|
||||
let continue_pat = self.pat_cf_continue(unstable_span, val_pat);
|
||||
self.arm(continue_pat, val_expr)
|
||||
};
|
||||
@ -1608,15 +1639,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
hir::Destination { label: None, target_id },
|
||||
Some(from_residual_expr),
|
||||
),
|
||||
attrs,
|
||||
))
|
||||
} else {
|
||||
self.arena.alloc(self.expr(
|
||||
try_span,
|
||||
hir::ExprKind::Ret(Some(from_residual_expr)),
|
||||
attrs,
|
||||
))
|
||||
self.arena.alloc(self.expr(try_span, hir::ExprKind::Ret(Some(from_residual_expr))))
|
||||
};
|
||||
self.lower_attrs(ret_expr.hir_id, &attrs);
|
||||
|
||||
let break_pat = self.pat_cf_break(try_span, residual_local);
|
||||
self.arm(break_pat, ret_expr)
|
||||
@ -1681,18 +1708,16 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
&mut self,
|
||||
span: Span,
|
||||
expr: &'hir hir::Expr<'hir>,
|
||||
attrs: AttrVec,
|
||||
) -> &'hir hir::Expr<'hir> {
|
||||
self.arena.alloc(self.expr_drop_temps_mut(span, expr, attrs))
|
||||
self.arena.alloc(self.expr_drop_temps_mut(span, expr))
|
||||
}
|
||||
|
||||
pub(super) fn expr_drop_temps_mut(
|
||||
&mut self,
|
||||
span: Span,
|
||||
expr: &'hir hir::Expr<'hir>,
|
||||
attrs: AttrVec,
|
||||
) -> hir::Expr<'hir> {
|
||||
self.expr(span, hir::ExprKind::DropTemps(expr), attrs)
|
||||
self.expr(span, hir::ExprKind::DropTemps(expr))
|
||||
}
|
||||
|
||||
fn expr_match(
|
||||
@ -1702,29 +1727,25 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
arms: &'hir [hir::Arm<'hir>],
|
||||
source: hir::MatchSource,
|
||||
) -> hir::Expr<'hir> {
|
||||
self.expr(span, hir::ExprKind::Match(arg, arms, source), AttrVec::new())
|
||||
self.expr(span, hir::ExprKind::Match(arg, arms, source))
|
||||
}
|
||||
|
||||
fn expr_break(&mut self, span: Span, attrs: AttrVec) -> hir::Expr<'hir> {
|
||||
fn expr_break(&mut self, span: Span) -> hir::Expr<'hir> {
|
||||
let expr_break = hir::ExprKind::Break(self.lower_loop_destination(None), None);
|
||||
self.expr(span, expr_break, attrs)
|
||||
self.expr(span, expr_break)
|
||||
}
|
||||
|
||||
fn expr_break_alloc(&mut self, span: Span, attrs: AttrVec) -> &'hir hir::Expr<'hir> {
|
||||
let expr_break = self.expr_break(span, attrs);
|
||||
fn expr_break_alloc(&mut self, span: Span) -> &'hir hir::Expr<'hir> {
|
||||
let expr_break = self.expr_break(span);
|
||||
self.arena.alloc(expr_break)
|
||||
}
|
||||
|
||||
fn expr_mut_addr_of(&mut self, span: Span, e: &'hir hir::Expr<'hir>) -> hir::Expr<'hir> {
|
||||
self.expr(
|
||||
span,
|
||||
hir::ExprKind::AddrOf(hir::BorrowKind::Ref, hir::Mutability::Mut, e),
|
||||
AttrVec::new(),
|
||||
)
|
||||
self.expr(span, hir::ExprKind::AddrOf(hir::BorrowKind::Ref, hir::Mutability::Mut, e))
|
||||
}
|
||||
|
||||
fn expr_unit(&mut self, sp: Span) -> &'hir hir::Expr<'hir> {
|
||||
self.arena.alloc(self.expr(sp, hir::ExprKind::Tup(&[]), AttrVec::new()))
|
||||
self.arena.alloc(self.expr(sp, hir::ExprKind::Tup(&[])))
|
||||
}
|
||||
|
||||
fn expr_call_mut(
|
||||
@ -1733,7 +1754,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
e: &'hir hir::Expr<'hir>,
|
||||
args: &'hir [hir::Expr<'hir>],
|
||||
) -> hir::Expr<'hir> {
|
||||
self.expr(span, hir::ExprKind::Call(e, args), AttrVec::new())
|
||||
self.expr(span, hir::ExprKind::Call(e, args))
|
||||
}
|
||||
|
||||
fn expr_call(
|
||||
@ -1752,8 +1773,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
args: &'hir [hir::Expr<'hir>],
|
||||
hir_id: Option<hir::HirId>,
|
||||
) -> hir::Expr<'hir> {
|
||||
let path =
|
||||
self.arena.alloc(self.expr_lang_item_path(span, lang_item, AttrVec::new(), hir_id));
|
||||
let path = self.arena.alloc(self.expr_lang_item_path(span, lang_item, hir_id));
|
||||
self.expr_call_mut(span, path, args)
|
||||
}
|
||||
|
||||
@ -1771,13 +1791,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
&mut self,
|
||||
span: Span,
|
||||
lang_item: hir::LangItem,
|
||||
attrs: AttrVec,
|
||||
hir_id: Option<hir::HirId>,
|
||||
) -> hir::Expr<'hir> {
|
||||
self.expr(
|
||||
span,
|
||||
hir::ExprKind::Path(hir::QPath::LangItem(lang_item, self.lower_span(span), hir_id)),
|
||||
attrs,
|
||||
)
|
||||
}
|
||||
|
||||
@ -1791,20 +1809,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
}
|
||||
|
||||
pub(super) fn expr_ident_mut(
|
||||
&mut self,
|
||||
sp: Span,
|
||||
ident: Ident,
|
||||
binding: hir::HirId,
|
||||
) -> hir::Expr<'hir> {
|
||||
self.expr_ident_with_attrs(sp, ident, binding, AttrVec::new())
|
||||
}
|
||||
|
||||
fn expr_ident_with_attrs(
|
||||
&mut self,
|
||||
span: Span,
|
||||
ident: Ident,
|
||||
binding: hir::HirId,
|
||||
attrs: AttrVec,
|
||||
) -> hir::Expr<'hir> {
|
||||
let hir_id = self.next_id();
|
||||
let res = Res::Local(binding);
|
||||
@ -1817,7 +1825,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
}),
|
||||
));
|
||||
|
||||
self.expr(span, expr_path, attrs)
|
||||
self.expr(span, expr_path)
|
||||
}
|
||||
|
||||
fn expr_unsafe(&mut self, expr: &'hir hir::Expr<'hir>) -> hir::Expr<'hir> {
|
||||
@ -1836,32 +1844,21 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
}),
|
||||
None,
|
||||
),
|
||||
AttrVec::new(),
|
||||
)
|
||||
}
|
||||
|
||||
fn expr_block_empty(&mut self, span: Span) -> &'hir hir::Expr<'hir> {
|
||||
let blk = self.block_all(span, &[], None);
|
||||
let expr = self.expr_block(blk, AttrVec::new());
|
||||
let expr = self.expr_block(blk);
|
||||
self.arena.alloc(expr)
|
||||
}
|
||||
|
||||
pub(super) fn expr_block(
|
||||
&mut self,
|
||||
b: &'hir hir::Block<'hir>,
|
||||
attrs: AttrVec,
|
||||
) -> hir::Expr<'hir> {
|
||||
self.expr(b.span, hir::ExprKind::Block(b, None), attrs)
|
||||
pub(super) fn expr_block(&mut self, b: &'hir hir::Block<'hir>) -> hir::Expr<'hir> {
|
||||
self.expr(b.span, hir::ExprKind::Block(b, None))
|
||||
}
|
||||
|
||||
pub(super) fn expr(
|
||||
&mut self,
|
||||
span: Span,
|
||||
kind: hir::ExprKind<'hir>,
|
||||
attrs: AttrVec,
|
||||
) -> hir::Expr<'hir> {
|
||||
pub(super) fn expr(&mut self, span: Span, kind: hir::ExprKind<'hir>) -> hir::Expr<'hir> {
|
||||
let hir_id = self.next_id();
|
||||
self.lower_attrs(hir_id, &attrs);
|
||||
hir::Expr { hir_id, kind, span: self.lower_span(span) }
|
||||
}
|
||||
|
||||
|
||||
@ -77,7 +77,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
|
||||
if hir_id.owner != self.owner {
|
||||
span_bug!(
|
||||
span,
|
||||
"inconsistent DepNode at `{:?}` for `{:?}`: \
|
||||
"inconsistent HirId at `{:?}` for `{:?}`: \
|
||||
current_dep_node_owner={} ({:?}), hir_id.owner={} ({:?})",
|
||||
self.source_map.span_to_diagnostic_string(span),
|
||||
node,
|
||||
@ -145,7 +145,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
|
||||
fn visit_item(&mut self, i: &'hir Item<'hir>) {
|
||||
debug_assert_eq!(i.owner_id, self.owner);
|
||||
self.with_parent(i.hir_id(), |this| {
|
||||
if let ItemKind::Struct(ref struct_def, _) = i.kind {
|
||||
if let ItemKind::Struct(struct_def, _) = &i.kind {
|
||||
// If this is a tuple or unit-like struct, register the constructor.
|
||||
if let Some(ctor_hir_id) = struct_def.ctor_hir_id() {
|
||||
this.insert(i.span, ctor_hir_id, Node::Ctor(struct_def));
|
||||
@ -303,12 +303,12 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
|
||||
}
|
||||
|
||||
fn visit_lifetime(&mut self, lifetime: &'hir Lifetime) {
|
||||
self.insert(lifetime.span, lifetime.hir_id, Node::Lifetime(lifetime));
|
||||
self.insert(lifetime.ident.span, lifetime.hir_id, Node::Lifetime(lifetime));
|
||||
}
|
||||
|
||||
fn visit_variant(&mut self, v: &'hir Variant<'hir>) {
|
||||
self.insert(v.span, v.id, Node::Variant(v));
|
||||
self.with_parent(v.id, |this| {
|
||||
self.insert(v.span, v.hir_id, Node::Variant(v));
|
||||
self.with_parent(v.hir_id, |this| {
|
||||
// Register the constructor of this variant.
|
||||
if let Some(ctor_hir_id) = v.data.ctor_hir_id() {
|
||||
this.insert(v.span, ctor_hir_id, Node::Ctor(&v.data));
|
||||
|
||||
@ -6,7 +6,6 @@ use super::{FnDeclKind, LoweringContext, ParamMode};
|
||||
use rustc_ast::ptr::P;
|
||||
use rustc_ast::visit::AssocCtxt;
|
||||
use rustc_ast::*;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_data_structures::sorted_map::SortedMap;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
@ -20,8 +19,7 @@ use rustc_span::symbol::{kw, sym, Ident};
|
||||
use rustc_span::{Span, Symbol};
|
||||
use rustc_target::spec::abi;
|
||||
use smallvec::{smallvec, SmallVec};
|
||||
|
||||
use std::iter;
|
||||
use thin_vec::ThinVec;
|
||||
|
||||
pub(super) struct ItemLowerer<'a, 'hir> {
|
||||
pub(super) tcx: TyCtxt<'hir>,
|
||||
@ -67,7 +65,7 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
|
||||
// HirId handling.
|
||||
bodies: Vec::new(),
|
||||
attrs: SortedMap::default(),
|
||||
children: FxHashMap::default(),
|
||||
children: Vec::default(),
|
||||
current_hir_id_owner: hir::CRATE_OWNER_ID,
|
||||
item_local_id_counter: hir::ItemLocalId::new(0),
|
||||
node_id_to_local_id: Default::default(),
|
||||
@ -86,7 +84,7 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
|
||||
impl_trait_defs: Vec::new(),
|
||||
impl_trait_bounds: Vec::new(),
|
||||
allow_try_trait: Some([sym::try_trait_v2, sym::yeet_desugar_details][..].into()),
|
||||
allow_gen_future: Some([sym::gen_future][..].into()),
|
||||
allow_gen_future: Some([sym::gen_future, sym::closure_track_caller][..].into()),
|
||||
allow_into_future: Some([sym::into_future][..].into()),
|
||||
generics_def_id_map: Default::default(),
|
||||
};
|
||||
@ -143,7 +141,7 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
|
||||
// This is used to track which lifetimes have already been defined,
|
||||
// and which need to be replicated when lowering an async fn.
|
||||
match parent_hir.node().expect_item().kind {
|
||||
hir::ItemKind::Impl(hir::Impl { ref of_trait, .. }) => {
|
||||
hir::ItemKind::Impl(hir::Impl { of_trait, .. }) => {
|
||||
lctx.is_in_trait_impl = of_trait.is_some();
|
||||
}
|
||||
_ => {}
|
||||
@ -179,37 +177,23 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
pub(super) fn lower_item_ref(&mut self, i: &Item) -> SmallVec<[hir::ItemId; 1]> {
|
||||
let mut node_ids =
|
||||
smallvec![hir::ItemId { owner_id: hir::OwnerId { def_id: self.local_def_id(i.id) } }];
|
||||
if let ItemKind::Use(ref use_tree) = &i.kind {
|
||||
self.lower_item_id_use_tree(use_tree, i.id, &mut node_ids);
|
||||
if let ItemKind::Use(use_tree) = &i.kind {
|
||||
self.lower_item_id_use_tree(use_tree, &mut node_ids);
|
||||
}
|
||||
node_ids
|
||||
}
|
||||
|
||||
fn lower_item_id_use_tree(
|
||||
&mut self,
|
||||
tree: &UseTree,
|
||||
base_id: NodeId,
|
||||
vec: &mut SmallVec<[hir::ItemId; 1]>,
|
||||
) {
|
||||
match tree.kind {
|
||||
UseTreeKind::Nested(ref nested_vec) => {
|
||||
fn lower_item_id_use_tree(&mut self, tree: &UseTree, vec: &mut SmallVec<[hir::ItemId; 1]>) {
|
||||
match &tree.kind {
|
||||
UseTreeKind::Nested(nested_vec) => {
|
||||
for &(ref nested, id) in nested_vec {
|
||||
vec.push(hir::ItemId {
|
||||
owner_id: hir::OwnerId { def_id: self.local_def_id(id) },
|
||||
});
|
||||
self.lower_item_id_use_tree(nested, id, vec);
|
||||
}
|
||||
}
|
||||
UseTreeKind::Glob => {}
|
||||
UseTreeKind::Simple(_, id1, id2) => {
|
||||
for (_, &id) in
|
||||
iter::zip(self.expect_full_res_from_use(base_id).skip(1), &[id1, id2])
|
||||
{
|
||||
vec.push(hir::ItemId {
|
||||
owner_id: hir::OwnerId { def_id: self.local_def_id(id) },
|
||||
});
|
||||
self.lower_item_id_use_tree(nested, vec);
|
||||
}
|
||||
}
|
||||
UseTreeKind::Simple(..) | UseTreeKind::Glob => {}
|
||||
}
|
||||
}
|
||||
|
||||
@ -239,26 +223,26 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
vis_span: Span,
|
||||
i: &ItemKind,
|
||||
) -> hir::ItemKind<'hir> {
|
||||
match *i {
|
||||
ItemKind::ExternCrate(orig_name) => hir::ItemKind::ExternCrate(orig_name),
|
||||
ItemKind::Use(ref use_tree) => {
|
||||
match i {
|
||||
ItemKind::ExternCrate(orig_name) => hir::ItemKind::ExternCrate(*orig_name),
|
||||
ItemKind::Use(use_tree) => {
|
||||
// Start with an empty prefix.
|
||||
let prefix = Path { segments: vec![], span: use_tree.span, tokens: None };
|
||||
let prefix = Path { segments: ThinVec::new(), span: use_tree.span, tokens: None };
|
||||
|
||||
self.lower_use_tree(use_tree, &prefix, id, vis_span, ident, attrs)
|
||||
}
|
||||
ItemKind::Static(ref t, m, ref e) => {
|
||||
ItemKind::Static(t, m, e) => {
|
||||
let (ty, body_id) = self.lower_const_item(t, span, e.as_deref());
|
||||
hir::ItemKind::Static(ty, m, body_id)
|
||||
hir::ItemKind::Static(ty, *m, body_id)
|
||||
}
|
||||
ItemKind::Const(_, ref t, ref e) => {
|
||||
ItemKind::Const(_, t, e) => {
|
||||
let (ty, body_id) = self.lower_const_item(t, span, e.as_deref());
|
||||
hir::ItemKind::Const(ty, body_id)
|
||||
}
|
||||
ItemKind::Fn(box Fn {
|
||||
sig: FnSig { ref decl, header, span: fn_sig_span },
|
||||
ref generics,
|
||||
ref body,
|
||||
sig: FnSig { decl, header, span: fn_sig_span },
|
||||
generics,
|
||||
body,
|
||||
..
|
||||
}) => {
|
||||
self.with_new_scopes(|this| {
|
||||
@ -269,43 +253,41 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
// only cares about the input argument patterns in the function
|
||||
// declaration (decl), not the return types.
|
||||
let asyncness = header.asyncness;
|
||||
let body_id =
|
||||
this.lower_maybe_async_body(span, &decl, asyncness, body.as_deref());
|
||||
let body_id = this.lower_maybe_async_body(
|
||||
span,
|
||||
hir_id,
|
||||
&decl,
|
||||
asyncness,
|
||||
body.as_deref(),
|
||||
);
|
||||
|
||||
let mut itctx = ImplTraitContext::Universal;
|
||||
let (generics, decl) = this.lower_generics(generics, id, &mut itctx, |this| {
|
||||
let ret_id = asyncness.opt_return_id();
|
||||
this.lower_fn_decl(&decl, Some(id), fn_sig_span, FnDeclKind::Fn, ret_id)
|
||||
this.lower_fn_decl(&decl, id, *fn_sig_span, FnDeclKind::Fn, ret_id)
|
||||
});
|
||||
let sig = hir::FnSig {
|
||||
decl,
|
||||
header: this.lower_fn_header(header),
|
||||
span: this.lower_span(fn_sig_span),
|
||||
header: this.lower_fn_header(*header),
|
||||
span: this.lower_span(*fn_sig_span),
|
||||
};
|
||||
hir::ItemKind::Fn(sig, generics, body_id)
|
||||
})
|
||||
}
|
||||
ItemKind::Mod(_, ref mod_kind) => match mod_kind {
|
||||
ItemKind::Mod(_, mod_kind) => match mod_kind {
|
||||
ModKind::Loaded(items, _, spans) => {
|
||||
hir::ItemKind::Mod(self.lower_mod(items, spans))
|
||||
}
|
||||
ModKind::Unloaded => panic!("`mod` items should have been loaded by now"),
|
||||
},
|
||||
ItemKind::ForeignMod(ref fm) => hir::ItemKind::ForeignMod {
|
||||
ItemKind::ForeignMod(fm) => hir::ItemKind::ForeignMod {
|
||||
abi: fm.abi.map_or(abi::Abi::FALLBACK, |abi| self.lower_abi(abi)),
|
||||
items: self
|
||||
.arena
|
||||
.alloc_from_iter(fm.items.iter().map(|x| self.lower_foreign_item_ref(x))),
|
||||
},
|
||||
ItemKind::GlobalAsm(ref asm) => {
|
||||
hir::ItemKind::GlobalAsm(self.lower_inline_asm(span, asm))
|
||||
}
|
||||
ItemKind::TyAlias(box TyAlias {
|
||||
ref generics,
|
||||
where_clauses,
|
||||
ty: Some(ref ty),
|
||||
..
|
||||
}) => {
|
||||
ItemKind::GlobalAsm(asm) => hir::ItemKind::GlobalAsm(self.lower_inline_asm(span, asm)),
|
||||
ItemKind::TyAlias(box TyAlias { generics, where_clauses, ty: Some(ty), .. }) => {
|
||||
// We lower
|
||||
//
|
||||
// type Foo = impl Trait
|
||||
@ -315,7 +297,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
// type Foo = Foo1
|
||||
// opaque type Foo1: Trait
|
||||
let mut generics = generics.clone();
|
||||
add_ty_alias_where_clause(&mut generics, where_clauses, true);
|
||||
add_ty_alias_where_clause(&mut generics, *where_clauses, true);
|
||||
let (generics, ty) = self.lower_generics(
|
||||
&generics,
|
||||
id,
|
||||
@ -324,9 +306,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
);
|
||||
hir::ItemKind::TyAlias(ty, generics)
|
||||
}
|
||||
ItemKind::TyAlias(box TyAlias {
|
||||
ref generics, ref where_clauses, ty: None, ..
|
||||
}) => {
|
||||
ItemKind::TyAlias(box TyAlias { generics, where_clauses, ty: None, .. }) => {
|
||||
let mut generics = generics.clone();
|
||||
add_ty_alias_where_clause(&mut generics, *where_clauses, true);
|
||||
let (generics, ty) = self.lower_generics(
|
||||
@ -337,7 +317,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
);
|
||||
hir::ItemKind::TyAlias(ty, generics)
|
||||
}
|
||||
ItemKind::Enum(ref enum_definition, ref generics) => {
|
||||
ItemKind::Enum(enum_definition, generics) => {
|
||||
let (generics, variants) = self.lower_generics(
|
||||
generics,
|
||||
id,
|
||||
@ -350,7 +330,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
);
|
||||
hir::ItemKind::Enum(hir::EnumDef { variants }, generics)
|
||||
}
|
||||
ItemKind::Struct(ref struct_def, ref generics) => {
|
||||
ItemKind::Struct(struct_def, generics) => {
|
||||
let (generics, struct_def) = self.lower_generics(
|
||||
generics,
|
||||
id,
|
||||
@ -359,7 +339,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
);
|
||||
hir::ItemKind::Struct(struct_def, generics)
|
||||
}
|
||||
ItemKind::Union(ref vdata, ref generics) => {
|
||||
ItemKind::Union(vdata, generics) => {
|
||||
let (generics, vdata) = self.lower_generics(
|
||||
generics,
|
||||
id,
|
||||
@ -373,10 +353,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
polarity,
|
||||
defaultness,
|
||||
constness,
|
||||
generics: ref ast_generics,
|
||||
of_trait: ref trait_ref,
|
||||
self_ty: ref ty,
|
||||
items: ref impl_items,
|
||||
generics: ast_generics,
|
||||
of_trait: trait_ref,
|
||||
self_ty: ty,
|
||||
items: impl_items,
|
||||
}) => {
|
||||
// Lower the "impl header" first. This ordering is important
|
||||
// for in-band lifetimes! Consider `'a` here:
|
||||
@ -414,30 +394,24 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
// `defaultness.has_value()` is never called for an `impl`, always `true` in order
|
||||
// to not cause an assertion failure inside the `lower_defaultness` function.
|
||||
let has_val = true;
|
||||
let (defaultness, defaultness_span) = self.lower_defaultness(defaultness, has_val);
|
||||
let (defaultness, defaultness_span) = self.lower_defaultness(*defaultness, has_val);
|
||||
let polarity = match polarity {
|
||||
ImplPolarity::Positive => ImplPolarity::Positive,
|
||||
ImplPolarity::Negative(s) => ImplPolarity::Negative(self.lower_span(s)),
|
||||
ImplPolarity::Negative(s) => ImplPolarity::Negative(self.lower_span(*s)),
|
||||
};
|
||||
hir::ItemKind::Impl(self.arena.alloc(hir::Impl {
|
||||
unsafety: self.lower_unsafety(unsafety),
|
||||
unsafety: self.lower_unsafety(*unsafety),
|
||||
polarity,
|
||||
defaultness,
|
||||
defaultness_span,
|
||||
constness: self.lower_constness(constness),
|
||||
constness: self.lower_constness(*constness),
|
||||
generics,
|
||||
of_trait: trait_ref,
|
||||
self_ty: lowered_ty,
|
||||
items: new_impl_items,
|
||||
}))
|
||||
}
|
||||
ItemKind::Trait(box Trait {
|
||||
is_auto,
|
||||
unsafety,
|
||||
ref generics,
|
||||
ref bounds,
|
||||
ref items,
|
||||
}) => {
|
||||
ItemKind::Trait(box Trait { is_auto, unsafety, generics, bounds, items }) => {
|
||||
let (generics, (unsafety, items, bounds)) = self.lower_generics(
|
||||
generics,
|
||||
id,
|
||||
@ -450,13 +424,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
let items = this.arena.alloc_from_iter(
|
||||
items.iter().map(|item| this.lower_trait_item_ref(item)),
|
||||
);
|
||||
let unsafety = this.lower_unsafety(unsafety);
|
||||
let unsafety = this.lower_unsafety(*unsafety);
|
||||
(unsafety, items, bounds)
|
||||
},
|
||||
);
|
||||
hir::ItemKind::Trait(is_auto, unsafety, generics, bounds, items)
|
||||
hir::ItemKind::Trait(*is_auto, unsafety, generics, bounds, items)
|
||||
}
|
||||
ItemKind::TraitAlias(ref generics, ref bounds) => {
|
||||
ItemKind::TraitAlias(generics, bounds) => {
|
||||
let (generics, bounds) = self.lower_generics(
|
||||
generics,
|
||||
id,
|
||||
@ -470,10 +444,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
);
|
||||
hir::ItemKind::TraitAlias(generics, bounds)
|
||||
}
|
||||
ItemKind::MacroDef(MacroDef { ref body, macro_rules }) => {
|
||||
let body = P(self.lower_mac_args(body));
|
||||
ItemKind::MacroDef(MacroDef { body, macro_rules }) => {
|
||||
let body = P(self.lower_delim_args(body));
|
||||
let macro_kind = self.resolver.decl_macro_kind(self.local_def_id(id));
|
||||
hir::ItemKind::Macro(ast::MacroDef { body, macro_rules }, macro_kind)
|
||||
hir::ItemKind::Macro(ast::MacroDef { body, macro_rules: *macro_rules }, macro_kind)
|
||||
}
|
||||
ItemKind::MacCall(..) => {
|
||||
panic!("`TyMac` should have been expanded by now")
|
||||
@ -505,7 +479,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
let segments = prefix.segments.iter().chain(path.segments.iter()).cloned().collect();
|
||||
|
||||
match tree.kind {
|
||||
UseTreeKind::Simple(rename, id1, id2) => {
|
||||
UseTreeKind::Simple(rename) => {
|
||||
*ident = tree.ident();
|
||||
|
||||
// First, apply the prefix to the path.
|
||||
@ -521,66 +495,16 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
}
|
||||
}
|
||||
|
||||
let mut resolutions = self.expect_full_res_from_use(id).fuse();
|
||||
// We want to return *something* from this function, so hold onto the first item
|
||||
// for later.
|
||||
let ret_res = self.lower_res(resolutions.next().unwrap_or(Res::Err));
|
||||
|
||||
// Here, we are looping over namespaces, if they exist for the definition
|
||||
// being imported. We only handle type and value namespaces because we
|
||||
// won't be dealing with macros in the rest of the compiler.
|
||||
// Essentially a single `use` which imports two names is desugared into
|
||||
// two imports.
|
||||
for new_node_id in [id1, id2] {
|
||||
let new_id = self.local_def_id(new_node_id);
|
||||
let Some(res) = resolutions.next() else {
|
||||
// Associate an HirId to both ids even if there is no resolution.
|
||||
let _old = self.children.insert(
|
||||
new_id,
|
||||
hir::MaybeOwner::NonOwner(hir::HirId::make_owner(new_id)),
|
||||
);
|
||||
debug_assert!(_old.is_none());
|
||||
continue;
|
||||
};
|
||||
let ident = *ident;
|
||||
let mut path = path.clone();
|
||||
for seg in &mut path.segments {
|
||||
// Give the cloned segment the same resolution information
|
||||
// as the old one (this is needed for stability checking).
|
||||
let new_id = self.next_node_id();
|
||||
self.resolver.clone_res(seg.id, new_id);
|
||||
seg.id = new_id;
|
||||
}
|
||||
let span = path.span;
|
||||
|
||||
self.with_hir_id_owner(new_node_id, |this| {
|
||||
let res = this.lower_res(res);
|
||||
let path = this.lower_path_extra(res, &path, ParamMode::Explicit);
|
||||
let kind = hir::ItemKind::Use(path, hir::UseKind::Single);
|
||||
if let Some(attrs) = attrs {
|
||||
this.attrs.insert(hir::ItemLocalId::new(0), attrs);
|
||||
}
|
||||
|
||||
let item = hir::Item {
|
||||
owner_id: hir::OwnerId { def_id: new_id },
|
||||
ident: this.lower_ident(ident),
|
||||
kind,
|
||||
vis_span,
|
||||
span: this.lower_span(span),
|
||||
};
|
||||
hir::OwnerNode::Item(this.arena.alloc(item))
|
||||
});
|
||||
}
|
||||
|
||||
let path = self.lower_path_extra(ret_res, &path, ParamMode::Explicit);
|
||||
let res =
|
||||
self.expect_full_res_from_use(id).map(|res| self.lower_res(res)).collect();
|
||||
let path = self.lower_use_path(res, &path, ParamMode::Explicit);
|
||||
hir::ItemKind::Use(path, hir::UseKind::Single)
|
||||
}
|
||||
UseTreeKind::Glob => {
|
||||
let path = self.lower_path(
|
||||
id,
|
||||
&Path { segments, span: path.span, tokens: None },
|
||||
ParamMode::Explicit,
|
||||
);
|
||||
let res = self.expect_full_res(id);
|
||||
let res = smallvec![self.lower_res(res)];
|
||||
let path = Path { segments, span: path.span, tokens: None };
|
||||
let path = self.lower_use_path(res, &path, ParamMode::Explicit);
|
||||
hir::ItemKind::Use(path, hir::UseKind::Glob)
|
||||
}
|
||||
UseTreeKind::Nested(ref trees) => {
|
||||
@ -650,9 +574,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
});
|
||||
}
|
||||
|
||||
let res = self.expect_full_res_from_use(id).next().unwrap_or(Res::Err);
|
||||
let res = self.lower_res(res);
|
||||
let path = self.lower_path_extra(res, &prefix, ParamMode::Explicit);
|
||||
let res =
|
||||
self.expect_full_res_from_use(id).map(|res| self.lower_res(res)).collect();
|
||||
let path = self.lower_use_path(res, &prefix, ParamMode::Explicit);
|
||||
hir::ItemKind::Use(path, hir::UseKind::ListStem)
|
||||
}
|
||||
}
|
||||
@ -665,8 +589,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
let item = hir::ForeignItem {
|
||||
owner_id,
|
||||
ident: self.lower_ident(i.ident),
|
||||
kind: match i.kind {
|
||||
ForeignItemKind::Fn(box Fn { ref sig, ref generics, .. }) => {
|
||||
kind: match &i.kind {
|
||||
ForeignItemKind::Fn(box Fn { sig, generics, .. }) => {
|
||||
let fdec = &sig.decl;
|
||||
let mut itctx = ImplTraitContext::Universal;
|
||||
let (generics, (fn_dec, fn_args)) =
|
||||
@ -675,7 +599,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
// Disallow `impl Trait` in foreign items.
|
||||
this.lower_fn_decl(
|
||||
fdec,
|
||||
None,
|
||||
i.id,
|
||||
sig.span,
|
||||
FnDeclKind::ExternFn,
|
||||
None,
|
||||
@ -686,10 +610,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
|
||||
hir::ForeignItemKind::Fn(fn_dec, fn_args, generics)
|
||||
}
|
||||
ForeignItemKind::Static(ref t, m, _) => {
|
||||
ForeignItemKind::Static(t, m, _) => {
|
||||
let ty =
|
||||
self.lower_ty(t, &ImplTraitContext::Disallowed(ImplTraitPosition::Type));
|
||||
hir::ForeignItemKind::Static(ty, m)
|
||||
hir::ForeignItemKind::Static(ty, *m)
|
||||
}
|
||||
ForeignItemKind::TyAlias(..) => hir::ForeignItemKind::Type,
|
||||
ForeignItemKind::MacCall(_) => panic!("macro shouldn't exist here"),
|
||||
@ -709,11 +633,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
}
|
||||
|
||||
fn lower_variant(&mut self, v: &Variant) -> hir::Variant<'hir> {
|
||||
let id = self.lower_node_id(v.id);
|
||||
self.lower_attrs(id, &v.attrs);
|
||||
let hir_id = self.lower_node_id(v.id);
|
||||
self.lower_attrs(hir_id, &v.attrs);
|
||||
hir::Variant {
|
||||
id,
|
||||
data: self.lower_variant_data(id, &v.data),
|
||||
hir_id,
|
||||
def_id: self.local_def_id(v.id),
|
||||
data: self.lower_variant_data(hir_id, &v.data),
|
||||
disr_expr: v.disr_expr.as_ref().map(|e| self.lower_anon_const(e)),
|
||||
ident: self.lower_ident(v.ident),
|
||||
span: self.lower_span(v.span),
|
||||
@ -725,32 +650,33 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
parent_id: hir::HirId,
|
||||
vdata: &VariantData,
|
||||
) -> hir::VariantData<'hir> {
|
||||
match *vdata {
|
||||
VariantData::Struct(ref fields, recovered) => hir::VariantData::Struct(
|
||||
match vdata {
|
||||
VariantData::Struct(fields, recovered) => hir::VariantData::Struct(
|
||||
self.arena
|
||||
.alloc_from_iter(fields.iter().enumerate().map(|f| self.lower_field_def(f))),
|
||||
recovered,
|
||||
*recovered,
|
||||
),
|
||||
VariantData::Tuple(ref fields, id) => {
|
||||
let ctor_id = self.lower_node_id(id);
|
||||
VariantData::Tuple(fields, id) => {
|
||||
let ctor_id = self.lower_node_id(*id);
|
||||
self.alias_attrs(ctor_id, parent_id);
|
||||
hir::VariantData::Tuple(
|
||||
self.arena.alloc_from_iter(
|
||||
fields.iter().enumerate().map(|f| self.lower_field_def(f)),
|
||||
),
|
||||
ctor_id,
|
||||
self.local_def_id(*id),
|
||||
)
|
||||
}
|
||||
VariantData::Unit(id) => {
|
||||
let ctor_id = self.lower_node_id(id);
|
||||
let ctor_id = self.lower_node_id(*id);
|
||||
self.alias_attrs(ctor_id, parent_id);
|
||||
hir::VariantData::Unit(ctor_id)
|
||||
hir::VariantData::Unit(ctor_id, self.local_def_id(*id))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn lower_field_def(&mut self, (index, f): (usize, &FieldDef)) -> hir::FieldDef<'hir> {
|
||||
let ty = if let TyKind::Path(ref qself, ref path) = f.ty.kind {
|
||||
let ty = if let TyKind::Path(qself, path) = &f.ty.kind {
|
||||
let t = self.lower_path_ty(
|
||||
&f.ty,
|
||||
qself,
|
||||
@ -767,6 +693,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
hir::FieldDef {
|
||||
span: self.lower_span(f.span),
|
||||
hir_id,
|
||||
def_id: self.local_def_id(f.id),
|
||||
ident: match f.ident {
|
||||
Some(ident) => self.lower_ident(ident),
|
||||
// FIXME(jseyfried): positional field hygiene.
|
||||
@ -779,15 +706,16 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
|
||||
fn lower_trait_item(&mut self, i: &AssocItem) -> &'hir hir::TraitItem<'hir> {
|
||||
let hir_id = self.lower_node_id(i.id);
|
||||
self.lower_attrs(hir_id, &i.attrs);
|
||||
let trait_item_def_id = hir_id.expect_owner();
|
||||
|
||||
let (generics, kind, has_default) = match i.kind {
|
||||
AssocItemKind::Const(_, ref ty, ref default) => {
|
||||
let (generics, kind, has_default) = match &i.kind {
|
||||
AssocItemKind::Const(_, ty, default) => {
|
||||
let ty = self.lower_ty(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Type));
|
||||
let body = default.as_ref().map(|x| self.lower_const_body(i.span, Some(x)));
|
||||
(hir::Generics::empty(), hir::TraitItemKind::Const(ty, body), body.is_some())
|
||||
}
|
||||
AssocItemKind::Fn(box Fn { ref sig, ref generics, body: None, .. }) => {
|
||||
AssocItemKind::Fn(box Fn { sig, generics, body: None, .. }) => {
|
||||
let asyncness = sig.header.asyncness;
|
||||
let names = self.lower_fn_params_to_names(&sig.decl);
|
||||
let (generics, sig) = self.lower_method_sig(
|
||||
@ -799,10 +727,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
);
|
||||
(generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Required(names)), false)
|
||||
}
|
||||
AssocItemKind::Fn(box Fn { ref sig, ref generics, body: Some(ref body), .. }) => {
|
||||
AssocItemKind::Fn(box Fn { sig, generics, body: Some(body), .. }) => {
|
||||
let asyncness = sig.header.asyncness;
|
||||
let body_id =
|
||||
self.lower_maybe_async_body(i.span, &sig.decl, asyncness, Some(&body));
|
||||
self.lower_maybe_async_body(i.span, hir_id, &sig.decl, asyncness, Some(&body));
|
||||
let (generics, sig) = self.lower_method_sig(
|
||||
generics,
|
||||
sig,
|
||||
@ -812,15 +740,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
);
|
||||
(generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Provided(body_id)), true)
|
||||
}
|
||||
AssocItemKind::Type(box TyAlias {
|
||||
ref generics,
|
||||
where_clauses,
|
||||
ref bounds,
|
||||
ref ty,
|
||||
..
|
||||
}) => {
|
||||
AssocItemKind::Type(box TyAlias { generics, where_clauses, bounds, ty, .. }) => {
|
||||
let mut generics = generics.clone();
|
||||
add_ty_alias_where_clause(&mut generics, where_clauses, false);
|
||||
add_ty_alias_where_clause(&mut generics, *where_clauses, false);
|
||||
let (generics, kind) = self.lower_generics(
|
||||
&generics,
|
||||
i.id,
|
||||
@ -843,7 +765,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
AssocItemKind::MacCall(..) => panic!("macro item shouldn't exist at this point"),
|
||||
};
|
||||
|
||||
self.lower_attrs(hir_id, &i.attrs);
|
||||
let item = hir::TraitItem {
|
||||
owner_id: trait_item_def_id,
|
||||
ident: self.lower_ident(i.ident),
|
||||
@ -875,13 +796,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
|
||||
/// Construct `ExprKind::Err` for the given `span`.
|
||||
pub(crate) fn expr_err(&mut self, span: Span) -> hir::Expr<'hir> {
|
||||
self.expr(span, hir::ExprKind::Err, AttrVec::new())
|
||||
self.expr(span, hir::ExprKind::Err)
|
||||
}
|
||||
|
||||
fn lower_impl_item(&mut self, i: &AssocItem) -> &'hir hir::ImplItem<'hir> {
|
||||
// Since `default impl` is not yet implemented, this is always true in impls.
|
||||
let has_value = true;
|
||||
let (defaultness, _) = self.lower_defaultness(i.kind.defaultness(), has_value);
|
||||
let hir_id = self.lower_node_id(i.id);
|
||||
self.lower_attrs(hir_id, &i.attrs);
|
||||
|
||||
let (generics, kind) = match &i.kind {
|
||||
AssocItemKind::Const(_, ty, expr) => {
|
||||
@ -894,8 +817,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
AssocItemKind::Fn(box Fn { sig, generics, body, .. }) => {
|
||||
self.current_item = Some(i.span);
|
||||
let asyncness = sig.header.asyncness;
|
||||
let body_id =
|
||||
self.lower_maybe_async_body(i.span, &sig.decl, asyncness, body.as_deref());
|
||||
let body_id = self.lower_maybe_async_body(
|
||||
i.span,
|
||||
hir_id,
|
||||
&sig.decl,
|
||||
asyncness,
|
||||
body.as_deref(),
|
||||
);
|
||||
let (generics, sig) = self.lower_method_sig(
|
||||
generics,
|
||||
sig,
|
||||
@ -928,8 +856,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
AssocItemKind::MacCall(..) => panic!("`TyMac` should have been expanded by now"),
|
||||
};
|
||||
|
||||
let hir_id = self.lower_node_id(i.id);
|
||||
self.lower_attrs(hir_id, &i.attrs);
|
||||
let item = hir::ImplItem {
|
||||
owner_id: hir_id.expect_owner(),
|
||||
ident: self.lower_ident(i.ident),
|
||||
@ -1062,6 +988,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
fn lower_maybe_async_body(
|
||||
&mut self,
|
||||
span: Span,
|
||||
fn_id: hir::HirId,
|
||||
decl: &FnDecl,
|
||||
asyncness: Async,
|
||||
body: Option<&Block>,
|
||||
@ -1212,6 +1139,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
|
||||
let async_expr = this.make_async_expr(
|
||||
CaptureBy::Value,
|
||||
Some(fn_id),
|
||||
closure_id,
|
||||
None,
|
||||
body.span,
|
||||
@ -1223,11 +1151,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
// Transform into `drop-temps { <user-body> }`, an expression:
|
||||
let desugared_span =
|
||||
this.mark_span_with_reason(DesugaringKind::Async, user_body.span, None);
|
||||
let user_body = this.expr_drop_temps(
|
||||
desugared_span,
|
||||
this.arena.alloc(user_body),
|
||||
AttrVec::new(),
|
||||
);
|
||||
let user_body =
|
||||
this.expr_drop_temps(desugared_span, this.arena.alloc(user_body));
|
||||
|
||||
// As noted above, create the final block like
|
||||
//
|
||||
@ -1244,14 +1169,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
Some(user_body),
|
||||
);
|
||||
|
||||
this.expr_block(body, AttrVec::new())
|
||||
this.expr_block(body)
|
||||
},
|
||||
);
|
||||
|
||||
(
|
||||
this.arena.alloc_from_iter(parameters),
|
||||
this.expr(body.span, async_expr, AttrVec::new()),
|
||||
)
|
||||
(this.arena.alloc_from_iter(parameters), this.expr(body.span, async_expr))
|
||||
})
|
||||
}
|
||||
|
||||
@ -1266,7 +1188,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
let header = self.lower_fn_header(sig.header);
|
||||
let mut itctx = ImplTraitContext::Universal;
|
||||
let (generics, decl) = self.lower_generics(generics, id, &mut itctx, |this| {
|
||||
this.lower_fn_decl(&sig.decl, Some(id), sig.span, kind, is_async)
|
||||
this.lower_fn_decl(&sig.decl, id, sig.span, kind, is_async)
|
||||
});
|
||||
(generics, hir::FnSig { header, decl, span: self.lower_span(sig.span) })
|
||||
}
|
||||
@ -1352,7 +1274,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
// keep track of the Span info. Now, `add_implicitly_sized` in `AstConv` checks both param bounds and
|
||||
// where clauses for `?Sized`.
|
||||
for pred in &generics.where_clause.predicates {
|
||||
let WherePredicate::BoundPredicate(ref bound_pred) = *pred else {
|
||||
let WherePredicate::BoundPredicate(bound_pred) = pred else {
|
||||
continue;
|
||||
};
|
||||
let compute_is_param = || {
|
||||
@ -1498,10 +1420,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
}))
|
||||
}
|
||||
GenericParamKind::Lifetime => {
|
||||
let ident_span = self.lower_span(ident.span);
|
||||
let ident = self.lower_ident(ident);
|
||||
let lt_id = self.next_node_id();
|
||||
let lifetime = self.new_named_lifetime(id, lt_id, ident_span, ident);
|
||||
let lifetime = self.new_named_lifetime(id, lt_id, ident);
|
||||
Some(hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate {
|
||||
lifetime,
|
||||
span,
|
||||
@ -1513,11 +1434,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
}
|
||||
|
||||
fn lower_where_predicate(&mut self, pred: &WherePredicate) -> hir::WherePredicate<'hir> {
|
||||
match *pred {
|
||||
match pred {
|
||||
WherePredicate::BoundPredicate(WhereBoundPredicate {
|
||||
ref bound_generic_params,
|
||||
ref bounded_ty,
|
||||
ref bounds,
|
||||
bound_generic_params,
|
||||
bounded_ty,
|
||||
bounds,
|
||||
span,
|
||||
}) => hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate {
|
||||
hir_id: self.next_id(),
|
||||
@ -1530,29 +1451,27 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
&ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
|
||||
)
|
||||
})),
|
||||
span: self.lower_span(span),
|
||||
span: self.lower_span(*span),
|
||||
origin: PredicateOrigin::WhereClause,
|
||||
}),
|
||||
WherePredicate::RegionPredicate(WhereRegionPredicate {
|
||||
ref lifetime,
|
||||
ref bounds,
|
||||
span,
|
||||
}) => hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate {
|
||||
span: self.lower_span(span),
|
||||
lifetime: self.lower_lifetime(lifetime),
|
||||
bounds: self.lower_param_bounds(
|
||||
bounds,
|
||||
&ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
|
||||
),
|
||||
in_where_clause: true,
|
||||
}),
|
||||
WherePredicate::EqPredicate(WhereEqPredicate { ref lhs_ty, ref rhs_ty, span }) => {
|
||||
WherePredicate::RegionPredicate(WhereRegionPredicate { lifetime, bounds, span }) => {
|
||||
hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate {
|
||||
span: self.lower_span(*span),
|
||||
lifetime: self.lower_lifetime(lifetime),
|
||||
bounds: self.lower_param_bounds(
|
||||
bounds,
|
||||
&ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
|
||||
),
|
||||
in_where_clause: true,
|
||||
})
|
||||
}
|
||||
WherePredicate::EqPredicate(WhereEqPredicate { lhs_ty, rhs_ty, span }) => {
|
||||
hir::WherePredicate::EqPredicate(hir::WhereEqPredicate {
|
||||
lhs_ty: self
|
||||
.lower_ty(lhs_ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Type)),
|
||||
rhs_ty: self
|
||||
.lower_ty(rhs_ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Type)),
|
||||
span: self.lower_span(span),
|
||||
span: self.lower_span(*span),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -34,7 +34,6 @@
|
||||
#![feature(let_chains)]
|
||||
#![feature(never_type)]
|
||||
#![recursion_limit = "256"]
|
||||
#![allow(rustc::potential_query_instability)]
|
||||
#![deny(rustc::untranslatable_diagnostic)]
|
||||
#![deny(rustc::diagnostic_outside_of_impl)]
|
||||
|
||||
@ -61,8 +60,8 @@ use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID};
|
||||
use rustc_hir::definitions::DefPathData;
|
||||
use rustc_hir::{ConstArg, GenericArg, ItemLocalId, ParamName, TraitCandidate};
|
||||
use rustc_index::vec::{Idx, IndexVec};
|
||||
use rustc_middle::span_bug;
|
||||
use rustc_middle::ty::{ResolverAstLowering, TyCtxt};
|
||||
use rustc_middle::{bug, span_bug};
|
||||
use rustc_session::parse::feature_err;
|
||||
use rustc_span::hygiene::MacroKind;
|
||||
use rustc_span::source_map::DesugaringKind;
|
||||
@ -107,7 +106,7 @@ struct LoweringContext<'a, 'hir> {
|
||||
/// Attributes inside the owner being lowered.
|
||||
attrs: SortedMap<hir::ItemLocalId, &'hir [Attribute]>,
|
||||
/// Collect items that were created by lowering the current owner.
|
||||
children: FxHashMap<LocalDefId, hir::MaybeOwner<&'hir hir::OwnerInfo<'hir>>>,
|
||||
children: Vec<(LocalDefId, hir::MaybeOwner<&'hir hir::OwnerInfo<'hir>>)>,
|
||||
|
||||
generator_kind: Option<hir::GeneratorKind>,
|
||||
|
||||
@ -260,6 +259,8 @@ enum ImplTraitContext {
|
||||
},
|
||||
/// Impl trait in type aliases.
|
||||
TypeAliasesOpaqueTy,
|
||||
/// `impl Trait` is unstably accepted in this position.
|
||||
FeatureGated(ImplTraitPosition, Symbol),
|
||||
/// `impl Trait` is not accepted in this position.
|
||||
Disallowed(ImplTraitPosition),
|
||||
}
|
||||
@ -328,7 +329,14 @@ enum FnDeclKind {
|
||||
}
|
||||
|
||||
impl FnDeclKind {
|
||||
fn impl_trait_allowed(&self, tcx: TyCtxt<'_>) -> bool {
|
||||
fn param_impl_trait_allowed(&self) -> bool {
|
||||
match self {
|
||||
FnDeclKind::Fn | FnDeclKind::Inherent | FnDeclKind::Impl | FnDeclKind::Trait => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn return_impl_trait_allowed(&self, tcx: TyCtxt<'_>) -> bool {
|
||||
match self {
|
||||
FnDeclKind::Fn | FnDeclKind::Inherent => true,
|
||||
FnDeclKind::Impl if tcx.features().return_position_impl_trait_in_trait => true,
|
||||
@ -481,6 +489,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
parent: LocalDefId,
|
||||
node_id: ast::NodeId,
|
||||
data: DefPathData,
|
||||
span: Span,
|
||||
) -> LocalDefId {
|
||||
debug_assert_ne!(node_id, ast::DUMMY_NODE_ID);
|
||||
assert!(
|
||||
@ -491,7 +500,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
self.tcx.hir().def_key(self.local_def_id(node_id)),
|
||||
);
|
||||
|
||||
let def_id = self.tcx.create_def(parent, data);
|
||||
let def_id = self.tcx.at(span).create_def(parent, data).def_id();
|
||||
|
||||
debug!("create_def: def_id_to_node_id[{:?}] <-> {:?}", def_id, node_id);
|
||||
self.resolver.node_id_to_def_id.insert(node_id, def_id);
|
||||
@ -611,8 +620,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
self.impl_trait_defs = current_impl_trait_defs;
|
||||
self.impl_trait_bounds = current_impl_trait_bounds;
|
||||
|
||||
let _old = self.children.insert(def_id, hir::MaybeOwner::Owner(info));
|
||||
debug_assert!(_old.is_none())
|
||||
debug_assert!(self.children.iter().find(|(id, _)| id == &def_id).is_none());
|
||||
self.children.push((def_id, hir::MaybeOwner::Owner(info)));
|
||||
}
|
||||
|
||||
/// Installs the remapping `remap` in scope while `f` is being executed.
|
||||
@ -719,8 +728,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
|
||||
assert_ne!(local_id, hir::ItemLocalId::new(0));
|
||||
if let Some(def_id) = self.opt_local_def_id(ast_node_id) {
|
||||
// Do not override a `MaybeOwner::Owner` that may already here.
|
||||
self.children.entry(def_id).or_insert(hir::MaybeOwner::NonOwner(hir_id));
|
||||
self.children.push((def_id, hir::MaybeOwner::NonOwner(hir_id)));
|
||||
self.local_id_to_def_id.insert(local_id, def_id);
|
||||
}
|
||||
|
||||
@ -818,6 +826,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
self.current_hir_id_owner.def_id,
|
||||
param,
|
||||
DefPathData::LifetimeNs(kw::UnderscoreLifetime),
|
||||
ident.span,
|
||||
);
|
||||
debug!(?_def_id);
|
||||
|
||||
@ -830,8 +839,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
),
|
||||
};
|
||||
let hir_id = self.lower_node_id(node_id);
|
||||
let def_id = self.local_def_id(node_id);
|
||||
Some(hir::GenericParam {
|
||||
hir_id,
|
||||
def_id,
|
||||
name,
|
||||
span: self.lower_span(ident.span),
|
||||
pure_wrt_drop: false,
|
||||
@ -911,7 +922,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
AttrKind::Normal(ref normal) => AttrKind::Normal(P(NormalAttr {
|
||||
item: AttrItem {
|
||||
path: normal.item.path.clone(),
|
||||
args: self.lower_mac_args(&normal.item.args),
|
||||
args: self.lower_attr_args(&normal.item.args),
|
||||
tokens: None,
|
||||
},
|
||||
tokens: None,
|
||||
@ -931,51 +942,39 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
}
|
||||
}
|
||||
|
||||
fn lower_mac_args(&self, args: &MacArgs) -> MacArgs {
|
||||
match *args {
|
||||
MacArgs::Empty => MacArgs::Empty,
|
||||
MacArgs::Delimited(dspan, delim, ref tokens) => {
|
||||
// This is either a non-key-value attribute, or a `macro_rules!` body.
|
||||
// We either not have any nonterminals present (in the case of an attribute),
|
||||
// or have tokens available for all nonterminals in the case of a nested
|
||||
// `macro_rules`: e.g:
|
||||
//
|
||||
// ```rust
|
||||
// macro_rules! outer {
|
||||
// ($e:expr) => {
|
||||
// macro_rules! inner {
|
||||
// () => { $e }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// ```
|
||||
//
|
||||
// In both cases, we don't want to synthesize any tokens
|
||||
MacArgs::Delimited(dspan, delim, tokens.flattened())
|
||||
}
|
||||
fn lower_attr_args(&self, args: &AttrArgs) -> AttrArgs {
|
||||
match args {
|
||||
AttrArgs::Empty => AttrArgs::Empty,
|
||||
AttrArgs::Delimited(args) => AttrArgs::Delimited(self.lower_delim_args(args)),
|
||||
// This is an inert key-value attribute - it will never be visible to macros
|
||||
// after it gets lowered to HIR. Therefore, we can extract literals to handle
|
||||
// nonterminals in `#[doc]` (e.g. `#[doc = $e]`).
|
||||
MacArgs::Eq(eq_span, MacArgsEq::Ast(ref expr)) => {
|
||||
AttrArgs::Eq(eq_span, AttrArgsEq::Ast(expr)) => {
|
||||
// In valid code the value always ends up as a single literal. Otherwise, a dummy
|
||||
// literal suffices because the error is handled elsewhere.
|
||||
let lit = if let ExprKind::Lit(lit) = &expr.kind {
|
||||
lit.clone()
|
||||
let lit = if let ExprKind::Lit(token_lit) = expr.kind
|
||||
&& let Ok(lit) = MetaItemLit::from_token_lit(token_lit, expr.span)
|
||||
{
|
||||
lit
|
||||
} else {
|
||||
Lit {
|
||||
MetaItemLit {
|
||||
token_lit: token::Lit::new(token::LitKind::Err, kw::Empty, None),
|
||||
kind: LitKind::Err,
|
||||
span: DUMMY_SP,
|
||||
}
|
||||
};
|
||||
MacArgs::Eq(eq_span, MacArgsEq::Hir(lit))
|
||||
AttrArgs::Eq(*eq_span, AttrArgsEq::Hir(lit))
|
||||
}
|
||||
MacArgs::Eq(_, MacArgsEq::Hir(ref lit)) => {
|
||||
AttrArgs::Eq(_, AttrArgsEq::Hir(lit)) => {
|
||||
unreachable!("in literal form when lowering mac args eq: {:?}", lit)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn lower_delim_args(&self, args: &DelimArgs) -> DelimArgs {
|
||||
DelimArgs { dspan: args.dspan, delim: args.delim, tokens: args.tokens.flattened() }
|
||||
}
|
||||
|
||||
/// Given an associated type constraint like one of these:
|
||||
///
|
||||
/// ```ignore (illustrative)
|
||||
@ -994,12 +993,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
) -> hir::TypeBinding<'hir> {
|
||||
debug!("lower_assoc_ty_constraint(constraint={:?}, itctx={:?})", constraint, itctx);
|
||||
// lower generic arguments of identifier in constraint
|
||||
let gen_args = if let Some(ref gen_args) = constraint.gen_args {
|
||||
let gen_args = if let Some(gen_args) = &constraint.gen_args {
|
||||
let gen_args_ctor = match gen_args {
|
||||
GenericArgs::AngleBracketed(ref data) => {
|
||||
GenericArgs::AngleBracketed(data) => {
|
||||
self.lower_angle_bracketed_parameter_data(data, ParamMode::Explicit, itctx).0
|
||||
}
|
||||
GenericArgs::Parenthesized(ref data) => {
|
||||
GenericArgs::Parenthesized(data) => {
|
||||
self.emit_bad_parenthesized_trait_in_assoc_ty(data);
|
||||
let aba = self.ast_arena.aba.alloc(data.as_angle_bracketed_args());
|
||||
self.lower_angle_bracketed_parameter_data(aba, ParamMode::Explicit, itctx).0
|
||||
@ -1011,15 +1010,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
};
|
||||
let itctx_tait = &ImplTraitContext::TypeAliasesOpaqueTy;
|
||||
|
||||
let kind = match constraint.kind {
|
||||
AssocConstraintKind::Equality { ref term } => {
|
||||
let kind = match &constraint.kind {
|
||||
AssocConstraintKind::Equality { term } => {
|
||||
let term = match term {
|
||||
Term::Ty(ref ty) => self.lower_ty(ty, itctx).into(),
|
||||
Term::Const(ref c) => self.lower_anon_const(c).into(),
|
||||
Term::Ty(ty) => self.lower_ty(ty, itctx).into(),
|
||||
Term::Const(c) => self.lower_anon_const(c).into(),
|
||||
};
|
||||
hir::TypeBindingKind::Equality { term }
|
||||
}
|
||||
AssocConstraintKind::Bound { ref bounds } => {
|
||||
AssocConstraintKind::Bound { bounds } => {
|
||||
// Piggy-back on the `impl Trait` context to figure out the correct behavior.
|
||||
let (desugar_to_impl_trait, itctx) = match itctx {
|
||||
// We are in the return position:
|
||||
@ -1129,7 +1128,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
match arg {
|
||||
ast::GenericArg::Lifetime(lt) => GenericArg::Lifetime(self.lower_lifetime(<)),
|
||||
ast::GenericArg::Type(ty) => {
|
||||
match ty.kind {
|
||||
match &ty.kind {
|
||||
TyKind::Infer if self.tcx.features().generic_arg_infer => {
|
||||
return GenericArg::Infer(hir::InferArg {
|
||||
hir_id: self.lower_node_id(ty.id),
|
||||
@ -1140,7 +1139,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
// parsing. We try to resolve that ambiguity by attempting resolution in both the
|
||||
// type and value namespaces. If we resolved the path in the value namespace, we
|
||||
// transform it into a generic const argument.
|
||||
TyKind::Path(ref qself, ref path) => {
|
||||
TyKind::Path(qself, path) => {
|
||||
if let Some(res) = self
|
||||
.resolver
|
||||
.get_partial_res(ty.id)
|
||||
@ -1156,15 +1155,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
|
||||
let parent_def_id = self.current_hir_id_owner;
|
||||
let node_id = self.next_node_id();
|
||||
let span = self.lower_span(ty.span);
|
||||
|
||||
// Add a definition for the in-band const def.
|
||||
self.create_def(
|
||||
let def_id = self.create_def(
|
||||
parent_def_id.def_id,
|
||||
node_id,
|
||||
DefPathData::AnonConst,
|
||||
span,
|
||||
);
|
||||
|
||||
let span = self.lower_span(ty.span);
|
||||
let path_expr = Expr {
|
||||
id: ty.id,
|
||||
kind: ExprKind::Path(qself.clone(), path.clone()),
|
||||
@ -1174,6 +1174,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
};
|
||||
|
||||
let ct = self.with_new_scopes(|this| hir::AnonConst {
|
||||
def_id,
|
||||
hir_id: this.lower_node_id(node_id),
|
||||
body: this.lower_const_body(path_expr.span, Some(&path_expr)),
|
||||
});
|
||||
@ -1200,7 +1201,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
fn lower_path_ty(
|
||||
&mut self,
|
||||
t: &Ty,
|
||||
qself: &Option<QSelf>,
|
||||
qself: &Option<ptr::P<QSelf>>,
|
||||
path: &Path,
|
||||
param_mode: ParamMode,
|
||||
itctx: &ImplTraitContext,
|
||||
@ -1246,12 +1247,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
}
|
||||
|
||||
fn lower_ty_direct(&mut self, t: &Ty, itctx: &ImplTraitContext) -> hir::Ty<'hir> {
|
||||
let kind = match t.kind {
|
||||
let kind = match &t.kind {
|
||||
TyKind::Infer => hir::TyKind::Infer,
|
||||
TyKind::Err => hir::TyKind::Err,
|
||||
TyKind::Slice(ref ty) => hir::TyKind::Slice(self.lower_ty(ty, itctx)),
|
||||
TyKind::Ptr(ref mt) => hir::TyKind::Ptr(self.lower_mt(mt, itctx)),
|
||||
TyKind::Rptr(ref region, ref mt) => {
|
||||
TyKind::Slice(ty) => hir::TyKind::Slice(self.lower_ty(ty, itctx)),
|
||||
TyKind::Ptr(mt) => hir::TyKind::Ptr(self.lower_mt(mt, itctx)),
|
||||
TyKind::Rptr(region, mt) => {
|
||||
let region = region.unwrap_or_else(|| {
|
||||
let id = if let Some(LifetimeRes::ElidedAnchor { start, end }) =
|
||||
self.resolver.get_lifetime_res(t.id)
|
||||
@ -1261,30 +1262,30 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
} else {
|
||||
self.next_node_id()
|
||||
};
|
||||
let span = self.tcx.sess.source_map().start_point(t.span);
|
||||
let span = self.tcx.sess.source_map().start_point(t.span).shrink_to_hi();
|
||||
Lifetime { ident: Ident::new(kw::UnderscoreLifetime, span), id }
|
||||
});
|
||||
let lifetime = self.lower_lifetime(®ion);
|
||||
hir::TyKind::Rptr(lifetime, self.lower_mt(mt, itctx))
|
||||
}
|
||||
TyKind::BareFn(ref f) => {
|
||||
TyKind::BareFn(f) => {
|
||||
let generic_params = self.lower_lifetime_binder(t.id, &f.generic_params);
|
||||
hir::TyKind::BareFn(self.arena.alloc(hir::BareFnTy {
|
||||
generic_params,
|
||||
unsafety: self.lower_unsafety(f.unsafety),
|
||||
abi: self.lower_extern(f.ext),
|
||||
decl: self.lower_fn_decl(&f.decl, None, t.span, FnDeclKind::Pointer, None),
|
||||
decl: self.lower_fn_decl(&f.decl, t.id, t.span, FnDeclKind::Pointer, None),
|
||||
param_names: self.lower_fn_params_to_names(&f.decl),
|
||||
}))
|
||||
}
|
||||
TyKind::Never => hir::TyKind::Never,
|
||||
TyKind::Tup(ref tys) => hir::TyKind::Tup(
|
||||
TyKind::Tup(tys) => hir::TyKind::Tup(
|
||||
self.arena.alloc_from_iter(tys.iter().map(|ty| self.lower_ty_direct(ty, itctx))),
|
||||
),
|
||||
TyKind::Paren(ref ty) => {
|
||||
TyKind::Paren(ty) => {
|
||||
return self.lower_ty_direct(ty, itctx);
|
||||
}
|
||||
TyKind::Path(ref qself, ref path) => {
|
||||
TyKind::Path(qself, path) => {
|
||||
return self.lower_path_ty(t, qself, path, ParamMode::Explicit, itctx);
|
||||
}
|
||||
TyKind::ImplicitSelf => {
|
||||
@ -1304,48 +1305,46 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
}),
|
||||
))
|
||||
}
|
||||
TyKind::Array(ref ty, ref length) => {
|
||||
TyKind::Array(ty, length) => {
|
||||
hir::TyKind::Array(self.lower_ty(ty, itctx), self.lower_array_length(length))
|
||||
}
|
||||
TyKind::Typeof(ref expr) => hir::TyKind::Typeof(self.lower_anon_const(expr)),
|
||||
TyKind::TraitObject(ref bounds, kind) => {
|
||||
TyKind::Typeof(expr) => hir::TyKind::Typeof(self.lower_anon_const(expr)),
|
||||
TyKind::TraitObject(bounds, kind) => {
|
||||
let mut lifetime_bound = None;
|
||||
let (bounds, lifetime_bound) = self.with_dyn_type_scope(true, |this| {
|
||||
let bounds =
|
||||
this.arena.alloc_from_iter(bounds.iter().filter_map(
|
||||
|bound| match *bound {
|
||||
GenericBound::Trait(
|
||||
ref ty,
|
||||
TraitBoundModifier::None | TraitBoundModifier::MaybeConst,
|
||||
) => Some(this.lower_poly_trait_ref(ty, itctx)),
|
||||
// `~const ?Bound` will cause an error during AST validation
|
||||
// anyways, so treat it like `?Bound` as compilation proceeds.
|
||||
GenericBound::Trait(
|
||||
_,
|
||||
TraitBoundModifier::Maybe | TraitBoundModifier::MaybeConstMaybe,
|
||||
) => None,
|
||||
GenericBound::Outlives(ref lifetime) => {
|
||||
if lifetime_bound.is_none() {
|
||||
lifetime_bound = Some(this.lower_lifetime(lifetime));
|
||||
}
|
||||
None
|
||||
this.arena.alloc_from_iter(bounds.iter().filter_map(|bound| match bound {
|
||||
GenericBound::Trait(
|
||||
ty,
|
||||
TraitBoundModifier::None | TraitBoundModifier::MaybeConst,
|
||||
) => Some(this.lower_poly_trait_ref(ty, itctx)),
|
||||
// `~const ?Bound` will cause an error during AST validation
|
||||
// anyways, so treat it like `?Bound` as compilation proceeds.
|
||||
GenericBound::Trait(
|
||||
_,
|
||||
TraitBoundModifier::Maybe | TraitBoundModifier::MaybeConstMaybe,
|
||||
) => None,
|
||||
GenericBound::Outlives(lifetime) => {
|
||||
if lifetime_bound.is_none() {
|
||||
lifetime_bound = Some(this.lower_lifetime(lifetime));
|
||||
}
|
||||
},
|
||||
));
|
||||
None
|
||||
}
|
||||
}));
|
||||
let lifetime_bound =
|
||||
lifetime_bound.unwrap_or_else(|| this.elided_dyn_bound(t.span));
|
||||
(bounds, lifetime_bound)
|
||||
});
|
||||
hir::TyKind::TraitObject(bounds, lifetime_bound, kind)
|
||||
hir::TyKind::TraitObject(bounds, lifetime_bound, *kind)
|
||||
}
|
||||
TyKind::ImplTrait(def_node_id, ref bounds) => {
|
||||
TyKind::ImplTrait(def_node_id, bounds) => {
|
||||
let span = t.span;
|
||||
match itctx {
|
||||
ImplTraitContext::ReturnPositionOpaqueTy { origin, in_trait } => self
|
||||
.lower_opaque_impl_trait(
|
||||
span,
|
||||
*origin,
|
||||
def_node_id,
|
||||
*def_node_id,
|
||||
bounds,
|
||||
*in_trait,
|
||||
itctx,
|
||||
@ -1353,38 +1352,37 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
ImplTraitContext::TypeAliasesOpaqueTy => self.lower_opaque_impl_trait(
|
||||
span,
|
||||
hir::OpaqueTyOrigin::TyAlias,
|
||||
def_node_id,
|
||||
*def_node_id,
|
||||
bounds,
|
||||
false,
|
||||
itctx,
|
||||
),
|
||||
ImplTraitContext::Universal => {
|
||||
let span = t.span;
|
||||
self.create_def(
|
||||
self.current_hir_id_owner.def_id,
|
||||
def_node_id,
|
||||
*def_node_id,
|
||||
DefPathData::ImplTrait,
|
||||
span,
|
||||
);
|
||||
let span = t.span;
|
||||
let ident = Ident::from_str_and_span(&pprust::ty_to_string(t), span);
|
||||
let (param, bounds, path) =
|
||||
self.lower_generic_and_bounds(def_node_id, span, ident, bounds);
|
||||
self.lower_generic_and_bounds(*def_node_id, span, ident, bounds);
|
||||
self.impl_trait_defs.push(param);
|
||||
if let Some(bounds) = bounds {
|
||||
self.impl_trait_bounds.push(bounds);
|
||||
}
|
||||
path
|
||||
}
|
||||
ImplTraitContext::Disallowed(
|
||||
position @ (ImplTraitPosition::TraitReturn | ImplTraitPosition::ImplReturn),
|
||||
) => {
|
||||
ImplTraitContext::FeatureGated(position, feature) => {
|
||||
self.tcx
|
||||
.sess
|
||||
.create_feature_err(
|
||||
MisplacedImplTrait {
|
||||
span: t.span,
|
||||
position: DiagnosticArgFromDisplay(&position),
|
||||
position: DiagnosticArgFromDisplay(position),
|
||||
},
|
||||
sym::return_position_impl_trait_in_trait,
|
||||
*feature,
|
||||
)
|
||||
.emit();
|
||||
hir::TyKind::Err
|
||||
@ -1392,7 +1390,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
ImplTraitContext::Disallowed(position) => {
|
||||
self.tcx.sess.emit_err(MisplacedImplTrait {
|
||||
span: t.span,
|
||||
position: DiagnosticArgFromDisplay(&position),
|
||||
position: DiagnosticArgFromDisplay(position),
|
||||
});
|
||||
hir::TyKind::Err
|
||||
}
|
||||
@ -1457,17 +1455,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
// frequently opened issues show.
|
||||
let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::OpaqueTy, span, None);
|
||||
|
||||
let opaque_ty_def_id = match origin {
|
||||
hir::OpaqueTyOrigin::TyAlias => self.create_def(
|
||||
self.current_hir_id_owner.def_id,
|
||||
opaque_ty_node_id,
|
||||
DefPathData::ImplTrait,
|
||||
),
|
||||
hir::OpaqueTyOrigin::FnReturn(fn_def_id) => {
|
||||
self.create_def(fn_def_id, opaque_ty_node_id, DefPathData::ImplTrait)
|
||||
}
|
||||
hir::OpaqueTyOrigin::AsyncFn(..) => bug!("unreachable"),
|
||||
};
|
||||
let opaque_ty_def_id = self.create_def(
|
||||
self.current_hir_id_owner.def_id,
|
||||
opaque_ty_node_id,
|
||||
DefPathData::ImplTrait,
|
||||
opaque_ty_span,
|
||||
);
|
||||
debug!(?opaque_ty_def_id);
|
||||
|
||||
// Contains the new lifetime definitions created for the TAIT (if any).
|
||||
@ -1521,6 +1514,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
|
||||
hir::GenericParam {
|
||||
hir_id,
|
||||
def_id: lctx.local_def_id(new_node_id),
|
||||
name,
|
||||
span: lifetime.ident.span,
|
||||
pure_wrt_drop: false,
|
||||
@ -1559,15 +1553,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
let lifetimes =
|
||||
self.arena.alloc_from_iter(collected_lifetimes.into_iter().map(|(_, lifetime)| {
|
||||
let id = self.next_node_id();
|
||||
let span = lifetime.ident.span;
|
||||
|
||||
let ident = if lifetime.ident.name == kw::UnderscoreLifetime {
|
||||
Ident::with_dummy_span(kw::UnderscoreLifetime)
|
||||
} else {
|
||||
lifetime.ident
|
||||
};
|
||||
|
||||
let l = self.new_named_lifetime(lifetime.id, id, span, ident);
|
||||
let l = self.new_named_lifetime(lifetime.id, id, lifetime.ident);
|
||||
hir::GenericArg::Lifetime(l)
|
||||
}));
|
||||
debug!(?lifetimes);
|
||||
@ -1627,6 +1613,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
parent_def_id,
|
||||
node_id,
|
||||
DefPathData::LifetimeNs(lifetime.ident.name),
|
||||
lifetime.ident.span,
|
||||
);
|
||||
remapping.insert(old_def_id, new_def_id);
|
||||
|
||||
@ -1643,6 +1630,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
parent_def_id,
|
||||
node_id,
|
||||
DefPathData::LifetimeNs(kw::UnderscoreLifetime),
|
||||
lifetime.ident.span,
|
||||
);
|
||||
remapping.insert(old_def_id, new_def_id);
|
||||
|
||||
@ -1692,7 +1680,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
fn lower_fn_decl(
|
||||
&mut self,
|
||||
decl: &FnDecl,
|
||||
fn_node_id: Option<NodeId>,
|
||||
fn_node_id: NodeId,
|
||||
fn_span: Span,
|
||||
kind: FnDeclKind,
|
||||
make_ret_async: Option<(NodeId, Span)>,
|
||||
@ -1707,23 +1695,21 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
inputs = &inputs[..inputs.len() - 1];
|
||||
}
|
||||
let inputs = self.arena.alloc_from_iter(inputs.iter().map(|param| {
|
||||
if fn_node_id.is_some() {
|
||||
self.lower_ty_direct(¶m.ty, &ImplTraitContext::Universal)
|
||||
let itctx = if kind.param_impl_trait_allowed() {
|
||||
ImplTraitContext::Universal
|
||||
} else {
|
||||
self.lower_ty_direct(
|
||||
¶m.ty,
|
||||
&ImplTraitContext::Disallowed(match kind {
|
||||
FnDeclKind::Fn | FnDeclKind::Inherent => {
|
||||
unreachable!("fn should allow in-band lifetimes")
|
||||
}
|
||||
FnDeclKind::ExternFn => ImplTraitPosition::ExternFnParam,
|
||||
FnDeclKind::Closure => ImplTraitPosition::ClosureParam,
|
||||
FnDeclKind::Pointer => ImplTraitPosition::PointerParam,
|
||||
FnDeclKind::Trait => ImplTraitPosition::TraitParam,
|
||||
FnDeclKind::Impl => ImplTraitPosition::ImplParam,
|
||||
}),
|
||||
)
|
||||
}
|
||||
ImplTraitContext::Disallowed(match kind {
|
||||
FnDeclKind::Fn | FnDeclKind::Inherent => {
|
||||
unreachable!("fn should allow APIT")
|
||||
}
|
||||
FnDeclKind::ExternFn => ImplTraitPosition::ExternFnParam,
|
||||
FnDeclKind::Closure => ImplTraitPosition::ClosureParam,
|
||||
FnDeclKind::Pointer => ImplTraitPosition::PointerParam,
|
||||
FnDeclKind::Trait => ImplTraitPosition::TraitParam,
|
||||
FnDeclKind::Impl => ImplTraitPosition::ImplParam,
|
||||
})
|
||||
};
|
||||
self.lower_ty_direct(¶m.ty, &itctx)
|
||||
}));
|
||||
|
||||
let output = if let Some((ret_id, span)) = make_ret_async {
|
||||
@ -1746,22 +1732,21 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
|
||||
self.lower_async_fn_ret_ty(
|
||||
&decl.output,
|
||||
fn_node_id.expect("`make_ret_async` but no `fn_def_id`"),
|
||||
fn_node_id,
|
||||
ret_id,
|
||||
matches!(kind, FnDeclKind::Trait),
|
||||
)
|
||||
} else {
|
||||
match decl.output {
|
||||
FnRetTy::Ty(ref ty) => {
|
||||
let mut context = match fn_node_id {
|
||||
Some(fn_node_id) if kind.impl_trait_allowed(self.tcx) => {
|
||||
let fn_def_id = self.local_def_id(fn_node_id);
|
||||
ImplTraitContext::ReturnPositionOpaqueTy {
|
||||
origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id),
|
||||
in_trait: matches!(kind, FnDeclKind::Trait),
|
||||
}
|
||||
match &decl.output {
|
||||
FnRetTy::Ty(ty) => {
|
||||
let context = if kind.return_impl_trait_allowed(self.tcx) {
|
||||
let fn_def_id = self.local_def_id(fn_node_id);
|
||||
ImplTraitContext::ReturnPositionOpaqueTy {
|
||||
origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id),
|
||||
in_trait: matches!(kind, FnDeclKind::Trait),
|
||||
}
|
||||
_ => ImplTraitContext::Disallowed(match kind {
|
||||
} else {
|
||||
let position = match kind {
|
||||
FnDeclKind::Fn | FnDeclKind::Inherent => {
|
||||
unreachable!("fn should allow in-band lifetimes")
|
||||
}
|
||||
@ -1770,11 +1755,18 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
FnDeclKind::Pointer => ImplTraitPosition::PointerReturn,
|
||||
FnDeclKind::Trait => ImplTraitPosition::TraitReturn,
|
||||
FnDeclKind::Impl => ImplTraitPosition::ImplReturn,
|
||||
}),
|
||||
};
|
||||
match kind {
|
||||
FnDeclKind::Trait | FnDeclKind::Impl => ImplTraitContext::FeatureGated(
|
||||
position,
|
||||
sym::return_position_impl_trait_in_trait,
|
||||
),
|
||||
_ => ImplTraitContext::Disallowed(position),
|
||||
}
|
||||
};
|
||||
hir::FnRetTy::Return(self.lower_ty(ty, &mut context))
|
||||
hir::FnRetTy::Return(self.lower_ty(ty, &context))
|
||||
}
|
||||
FnRetTy::Default(span) => hir::FnRetTy::DefaultReturn(self.lower_span(span)),
|
||||
FnRetTy::Default(span) => hir::FnRetTy::DefaultReturn(self.lower_span(*span)),
|
||||
}
|
||||
};
|
||||
|
||||
@ -1782,26 +1774,23 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
inputs,
|
||||
output,
|
||||
c_variadic,
|
||||
lifetime_elision_allowed: self.resolver.lifetime_elision_allowed.contains(&fn_node_id),
|
||||
implicit_self: decl.inputs.get(0).map_or(hir::ImplicitSelfKind::None, |arg| {
|
||||
let is_mutable_pat = matches!(
|
||||
arg.pat.kind,
|
||||
PatKind::Ident(hir::BindingAnnotation(_, Mutability::Mut), ..)
|
||||
);
|
||||
|
||||
match arg.ty.kind {
|
||||
match &arg.ty.kind {
|
||||
TyKind::ImplicitSelf if is_mutable_pat => hir::ImplicitSelfKind::Mut,
|
||||
TyKind::ImplicitSelf => hir::ImplicitSelfKind::Imm,
|
||||
// Given we are only considering `ImplicitSelf` types, we needn't consider
|
||||
// the case where we have a mutable pattern to a reference as that would
|
||||
// no longer be an `ImplicitSelf`.
|
||||
TyKind::Rptr(_, ref mt)
|
||||
if mt.ty.kind.is_implicit_self() && mt.mutbl == ast::Mutability::Mut =>
|
||||
{
|
||||
hir::ImplicitSelfKind::MutRef
|
||||
}
|
||||
TyKind::Rptr(_, ref mt) if mt.ty.kind.is_implicit_self() => {
|
||||
hir::ImplicitSelfKind::ImmRef
|
||||
}
|
||||
TyKind::Rptr(_, mt) if mt.ty.kind.is_implicit_self() => match mt.mutbl {
|
||||
hir::Mutability::Not => hir::ImplicitSelfKind::ImmRef,
|
||||
hir::Mutability::Mut => hir::ImplicitSelfKind::MutRef,
|
||||
},
|
||||
_ => hir::ImplicitSelfKind::None,
|
||||
}
|
||||
}),
|
||||
@ -1828,9 +1817,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
|
||||
let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::Async, span, None);
|
||||
|
||||
let opaque_ty_def_id = self.local_def_id(opaque_ty_node_id);
|
||||
let fn_def_id = self.local_def_id(fn_node_id);
|
||||
|
||||
let opaque_ty_def_id =
|
||||
self.create_def(fn_def_id, opaque_ty_node_id, DefPathData::ImplTrait, opaque_ty_span);
|
||||
|
||||
// When we create the opaque type for this async fn, it is going to have
|
||||
// to capture all the lifetimes involved in the signature (including in the
|
||||
// return type). This is done by introducing lifetime parameters for:
|
||||
@ -1889,6 +1880,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
opaque_ty_def_id,
|
||||
inner_node_id,
|
||||
DefPathData::LifetimeNs(ident.name),
|
||||
ident.span,
|
||||
);
|
||||
new_remapping.insert(outer_def_id, inner_def_id);
|
||||
|
||||
@ -1953,7 +1945,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
output,
|
||||
span,
|
||||
if in_trait && !this.tcx.features().return_position_impl_trait_in_trait {
|
||||
ImplTraitContext::Disallowed(ImplTraitPosition::TraitReturn)
|
||||
ImplTraitContext::FeatureGated(
|
||||
ImplTraitPosition::TraitReturn,
|
||||
sym::return_position_impl_trait_in_trait,
|
||||
)
|
||||
} else {
|
||||
ImplTraitContext::ReturnPositionOpaqueTy {
|
||||
origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id),
|
||||
@ -1978,6 +1973,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
|
||||
hir::GenericParam {
|
||||
hir_id,
|
||||
def_id: this.local_def_id(new_node_id),
|
||||
name,
|
||||
span: lifetime.ident.span,
|
||||
pure_wrt_drop: false,
|
||||
@ -2024,18 +2020,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
let generic_args = self.arena.alloc_from_iter(collected_lifetimes.into_iter().map(
|
||||
|(_, lifetime, res)| {
|
||||
let id = self.next_node_id();
|
||||
let span = lifetime.ident.span;
|
||||
|
||||
let ident = if lifetime.ident.name == kw::UnderscoreLifetime {
|
||||
Ident::with_dummy_span(kw::UnderscoreLifetime)
|
||||
} else {
|
||||
lifetime.ident
|
||||
};
|
||||
|
||||
let res = res.unwrap_or(
|
||||
self.resolver.get_lifetime_res(lifetime.id).unwrap_or(LifetimeRes::Error),
|
||||
);
|
||||
hir::GenericArg::Lifetime(self.new_named_lifetime_with_res(id, span, ident, res))
|
||||
hir::GenericArg::Lifetime(self.new_named_lifetime_with_res(id, lifetime.ident, res))
|
||||
},
|
||||
));
|
||||
|
||||
@ -2105,43 +2093,40 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
}
|
||||
|
||||
fn lower_lifetime(&mut self, l: &Lifetime) -> &'hir hir::Lifetime {
|
||||
let span = self.lower_span(l.ident.span);
|
||||
let ident = self.lower_ident(l.ident);
|
||||
self.new_named_lifetime(l.id, l.id, span, ident)
|
||||
self.new_named_lifetime(l.id, l.id, ident)
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
fn new_named_lifetime_with_res(
|
||||
&mut self,
|
||||
id: NodeId,
|
||||
span: Span,
|
||||
ident: Ident,
|
||||
res: LifetimeRes,
|
||||
) -> &'hir hir::Lifetime {
|
||||
let name = match res {
|
||||
let res = match res {
|
||||
LifetimeRes::Param { param, .. } => {
|
||||
let p_name = ParamName::Plain(ident);
|
||||
let param = self.get_remapped_def_id(param);
|
||||
|
||||
hir::LifetimeName::Param(param, p_name)
|
||||
hir::LifetimeName::Param(param)
|
||||
}
|
||||
LifetimeRes::Fresh { param, .. } => {
|
||||
debug_assert_eq!(ident.name, kw::UnderscoreLifetime);
|
||||
let param = self.local_def_id(param);
|
||||
|
||||
hir::LifetimeName::Param(param, ParamName::Fresh)
|
||||
hir::LifetimeName::Param(param)
|
||||
}
|
||||
LifetimeRes::Infer => hir::LifetimeName::Infer,
|
||||
LifetimeRes::Static => hir::LifetimeName::Static,
|
||||
LifetimeRes::Error => hir::LifetimeName::Error,
|
||||
res => panic!("Unexpected lifetime resolution {:?} for {:?} at {:?}", res, ident, span),
|
||||
res => panic!(
|
||||
"Unexpected lifetime resolution {:?} for {:?} at {:?}",
|
||||
res, ident, ident.span
|
||||
),
|
||||
};
|
||||
|
||||
debug!(?name);
|
||||
debug!(?res);
|
||||
self.arena.alloc(hir::Lifetime {
|
||||
hir_id: self.lower_node_id(id),
|
||||
span: self.lower_span(span),
|
||||
name,
|
||||
ident: self.lower_ident(ident),
|
||||
res,
|
||||
})
|
||||
}
|
||||
|
||||
@ -2150,11 +2135,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
&mut self,
|
||||
id: NodeId,
|
||||
new_id: NodeId,
|
||||
span: Span,
|
||||
ident: Ident,
|
||||
) -> &'hir hir::Lifetime {
|
||||
let res = self.resolver.get_lifetime_res(id).unwrap_or(LifetimeRes::Error);
|
||||
self.new_named_lifetime_with_res(new_id, span, ident, res)
|
||||
self.new_named_lifetime_with_res(new_id, ident, res)
|
||||
}
|
||||
|
||||
fn lower_generic_params_mut<'s>(
|
||||
@ -2176,6 +2160,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
self.lower_attrs(hir_id, ¶m.attrs);
|
||||
hir::GenericParam {
|
||||
hir_id,
|
||||
def_id: self.local_def_id(param.id),
|
||||
name,
|
||||
span: self.lower_span(param.span()),
|
||||
pure_wrt_drop: self.tcx.sess.contains_name(¶m.attrs, sym::may_dangle),
|
||||
@ -2188,7 +2173,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
&mut self,
|
||||
param: &GenericParam,
|
||||
) -> (hir::ParamName, hir::GenericParamKind<'hir>) {
|
||||
match param.kind {
|
||||
match ¶m.kind {
|
||||
GenericParamKind::Lifetime => {
|
||||
// AST resolution emitted an error on those parameters, so we lower them using
|
||||
// `ParamName::Error`.
|
||||
@ -2204,7 +2189,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
|
||||
(param_name, kind)
|
||||
}
|
||||
GenericParamKind::Type { ref default, .. } => {
|
||||
GenericParamKind::Type { default, .. } => {
|
||||
let kind = hir::GenericParamKind::Type {
|
||||
default: default.as_ref().map(|x| {
|
||||
self.lower_ty(x, &ImplTraitContext::Disallowed(ImplTraitPosition::Type))
|
||||
@ -2214,7 +2199,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
|
||||
(hir::ParamName::Plain(self.lower_ident(param.ident)), kind)
|
||||
}
|
||||
GenericParamKind::Const { ref ty, kw_span: _, ref default } => {
|
||||
GenericParamKind::Const { ty, kw_span: _, default } => {
|
||||
let ty = self.lower_ty(&ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Type));
|
||||
let default = default.as_ref().map(|def| self.lower_anon_const(def));
|
||||
(
|
||||
@ -2280,6 +2265,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
// Set the name to `impl Bound1 + Bound2`.
|
||||
let param = hir::GenericParam {
|
||||
hir_id: self.lower_node_id(node_id),
|
||||
def_id,
|
||||
name: ParamName::Plain(self.lower_ident(ident)),
|
||||
pure_wrt_drop: false,
|
||||
span: self.lower_span(span),
|
||||
@ -2315,7 +2301,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
/// has no attributes and is not targeted by a `break`.
|
||||
fn lower_block_expr(&mut self, b: &Block) -> hir::Expr<'hir> {
|
||||
let block = self.lower_block(b, false);
|
||||
self.expr_block(block, AttrVec::new())
|
||||
self.expr_block(block)
|
||||
}
|
||||
|
||||
fn lower_array_length(&mut self, c: &AnonConst) -> hir::ArrayLen {
|
||||
@ -2340,6 +2326,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
|
||||
fn lower_anon_const(&mut self, c: &AnonConst) -> hir::AnonConst {
|
||||
self.with_new_scopes(|this| hir::AnonConst {
|
||||
def_id: this.local_def_id(c.id),
|
||||
hir_id: this.lower_node_id(c.id),
|
||||
body: this.lower_const_body(c.value.span, Some(&c.value)),
|
||||
})
|
||||
@ -2563,8 +2550,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
fn elided_dyn_bound(&mut self, span: Span) -> &'hir hir::Lifetime {
|
||||
let r = hir::Lifetime {
|
||||
hir_id: self.next_id(),
|
||||
span: self.lower_span(span),
|
||||
name: hir::LifetimeName::ImplicitObjectLifetimeDefault,
|
||||
ident: Ident::new(kw::Empty, self.lower_span(span)),
|
||||
res: hir::LifetimeName::ImplicitObjectLifetimeDefault,
|
||||
};
|
||||
debug!("elided_dyn_bound: r={:?}", r);
|
||||
self.arena.alloc(r)
|
||||
|
||||
@ -22,16 +22,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
ensure_sufficient_stack(|| {
|
||||
// loop here to avoid recursion
|
||||
let node = loop {
|
||||
match pattern.kind {
|
||||
match &pattern.kind {
|
||||
PatKind::Wild => break hir::PatKind::Wild,
|
||||
PatKind::Ident(binding_mode, ident, ref sub) => {
|
||||
let lower_sub = |this: &mut Self| sub.as_ref().map(|s| this.lower_pat(&*s));
|
||||
break self.lower_pat_ident(pattern, binding_mode, ident, lower_sub);
|
||||
PatKind::Ident(binding_mode, ident, sub) => {
|
||||
let lower_sub = |this: &mut Self| sub.as_ref().map(|s| this.lower_pat(s));
|
||||
break self.lower_pat_ident(pattern, *binding_mode, *ident, lower_sub);
|
||||
}
|
||||
PatKind::Lit(ref e) => {
|
||||
PatKind::Lit(e) => {
|
||||
break hir::PatKind::Lit(self.lower_expr_within_pat(e, false));
|
||||
}
|
||||
PatKind::TupleStruct(ref qself, ref path, ref pats) => {
|
||||
PatKind::TupleStruct(qself, path, pats) => {
|
||||
let qpath = self.lower_qpath(
|
||||
pattern.id,
|
||||
qself,
|
||||
@ -42,12 +42,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
let (pats, ddpos) = self.lower_pat_tuple(pats, "tuple struct");
|
||||
break hir::PatKind::TupleStruct(qpath, pats, ddpos);
|
||||
}
|
||||
PatKind::Or(ref pats) => {
|
||||
PatKind::Or(pats) => {
|
||||
break hir::PatKind::Or(
|
||||
self.arena.alloc_from_iter(pats.iter().map(|x| self.lower_pat_mut(x))),
|
||||
);
|
||||
}
|
||||
PatKind::Path(ref qself, ref path) => {
|
||||
PatKind::Path(qself, path) => {
|
||||
let qpath = self.lower_qpath(
|
||||
pattern.id,
|
||||
qself,
|
||||
@ -57,7 +57,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
);
|
||||
break hir::PatKind::Path(qpath);
|
||||
}
|
||||
PatKind::Struct(ref qself, ref path, ref fields, etc) => {
|
||||
PatKind::Struct(qself, path, fields, etc) => {
|
||||
let qpath = self.lower_qpath(
|
||||
pattern.id,
|
||||
qself,
|
||||
@ -78,32 +78,32 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
span: self.lower_span(f.span),
|
||||
}
|
||||
}));
|
||||
break hir::PatKind::Struct(qpath, fs, etc);
|
||||
break hir::PatKind::Struct(qpath, fs, *etc);
|
||||
}
|
||||
PatKind::Tuple(ref pats) => {
|
||||
PatKind::Tuple(pats) => {
|
||||
let (pats, ddpos) = self.lower_pat_tuple(pats, "tuple");
|
||||
break hir::PatKind::Tuple(pats, ddpos);
|
||||
}
|
||||
PatKind::Box(ref inner) => {
|
||||
PatKind::Box(inner) => {
|
||||
break hir::PatKind::Box(self.lower_pat(inner));
|
||||
}
|
||||
PatKind::Ref(ref inner, mutbl) => {
|
||||
break hir::PatKind::Ref(self.lower_pat(inner), mutbl);
|
||||
PatKind::Ref(inner, mutbl) => {
|
||||
break hir::PatKind::Ref(self.lower_pat(inner), *mutbl);
|
||||
}
|
||||
PatKind::Range(ref e1, ref e2, Spanned { node: ref end, .. }) => {
|
||||
PatKind::Range(e1, e2, Spanned { node: end, .. }) => {
|
||||
break hir::PatKind::Range(
|
||||
e1.as_deref().map(|e| self.lower_expr_within_pat(e, true)),
|
||||
e2.as_deref().map(|e| self.lower_expr_within_pat(e, true)),
|
||||
self.lower_range_end(end, e2.is_some()),
|
||||
);
|
||||
}
|
||||
PatKind::Slice(ref pats) => break self.lower_pat_slice(pats),
|
||||
PatKind::Slice(pats) => break self.lower_pat_slice(pats),
|
||||
PatKind::Rest => {
|
||||
// If we reach here the `..` pattern is not semantically allowed.
|
||||
break self.ban_illegal_rest_pat(pattern.span);
|
||||
}
|
||||
// return inner to be processed in next loop
|
||||
PatKind::Paren(ref inner) => pattern = inner,
|
||||
PatKind::Paren(inner) => pattern = inner,
|
||||
PatKind::MacCall(_) => panic!("{:?} shouldn't exist here", pattern.span),
|
||||
}
|
||||
};
|
||||
@ -126,7 +126,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
// Note that unlike for slice patterns,
|
||||
// where `xs @ ..` is a legal sub-slice pattern,
|
||||
// it is not a legal sub-tuple pattern.
|
||||
match pat.kind {
|
||||
match &pat.kind {
|
||||
// Found a sub-tuple rest pattern
|
||||
PatKind::Rest => {
|
||||
rest = Some((idx, pat.span));
|
||||
@ -134,12 +134,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
}
|
||||
// Found a sub-tuple pattern `$binding_mode $ident @ ..`.
|
||||
// This is not allowed as a sub-tuple pattern
|
||||
PatKind::Ident(ref _bm, ident, Some(ref sub)) if sub.is_rest() => {
|
||||
PatKind::Ident(_, ident, Some(sub)) if sub.is_rest() => {
|
||||
let sp = pat.span;
|
||||
self.tcx.sess.emit_err(SubTupleBinding {
|
||||
span: sp,
|
||||
ident_name: ident.name,
|
||||
ident,
|
||||
ident: *ident,
|
||||
ctx,
|
||||
});
|
||||
}
|
||||
@ -176,7 +176,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
let mut prev_rest_span = None;
|
||||
|
||||
// Lowers `$bm $ident @ ..` to `$bm $ident @ _`.
|
||||
let lower_rest_sub = |this: &mut Self, pat, ann, ident, sub| {
|
||||
let lower_rest_sub = |this: &mut Self, pat, &ann, &ident, sub| {
|
||||
let lower_sub = |this: &mut Self| Some(this.pat_wild_with_node_id_of(sub));
|
||||
let node = this.lower_pat_ident(pat, ann, ident, lower_sub);
|
||||
this.pat_with_node_id_of(pat, node)
|
||||
@ -185,7 +185,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
let mut iter = pats.iter();
|
||||
// Lower all the patterns until the first occurrence of a sub-slice pattern.
|
||||
for pat in iter.by_ref() {
|
||||
match pat.kind {
|
||||
match &pat.kind {
|
||||
// Found a sub-slice pattern `..`. Record, lower it to `_`, and stop here.
|
||||
PatKind::Rest => {
|
||||
prev_rest_span = Some(pat.span);
|
||||
@ -194,7 +194,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
}
|
||||
// Found a sub-slice pattern `$binding_mode $ident @ ..`.
|
||||
// Record, lower it to `$binding_mode $ident @ _`, and stop here.
|
||||
PatKind::Ident(ann, ident, Some(ref sub)) if sub.is_rest() => {
|
||||
PatKind::Ident(ann, ident, Some(sub)) if sub.is_rest() => {
|
||||
prev_rest_span = Some(sub.span);
|
||||
slice = Some(self.arena.alloc(lower_rest_sub(self, pat, ann, ident, sub)));
|
||||
break;
|
||||
@ -207,9 +207,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
// Lower all the patterns after the first sub-slice pattern.
|
||||
for pat in iter {
|
||||
// There was a previous subslice pattern; make sure we don't allow more.
|
||||
let rest_span = match pat.kind {
|
||||
let rest_span = match &pat.kind {
|
||||
PatKind::Rest => Some(pat.span),
|
||||
PatKind::Ident(ann, ident, Some(ref sub)) if sub.is_rest() => {
|
||||
PatKind::Ident(ann, ident, Some(sub)) if sub.is_rest() => {
|
||||
// #69103: Lower into `binding @ _` as above to avoid ICEs.
|
||||
after.push(lower_rest_sub(self, pat, ann, ident, sub));
|
||||
Some(sub.span)
|
||||
@ -322,10 +322,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
// m!(S);
|
||||
// ```
|
||||
fn lower_expr_within_pat(&mut self, expr: &Expr, allow_paths: bool) -> &'hir hir::Expr<'hir> {
|
||||
match expr.kind {
|
||||
ExprKind::Lit(..) | ExprKind::ConstBlock(..) | ExprKind::Err => {}
|
||||
match &expr.kind {
|
||||
ExprKind::Lit(..)
|
||||
| ExprKind::ConstBlock(..)
|
||||
| ExprKind::IncludedBytes(..)
|
||||
| ExprKind::Err => {}
|
||||
ExprKind::Path(..) if allow_paths => {}
|
||||
ExprKind::Unary(UnOp::Neg, ref inner) if matches!(inner.kind, ExprKind::Lit(_)) => {}
|
||||
ExprKind::Unary(UnOp::Neg, inner) if matches!(inner.kind, ExprKind::Lit(_)) => {}
|
||||
_ => {
|
||||
self.tcx.sess.emit_err(ArbitraryExpressionInPattern { span: expr.span });
|
||||
return self.arena.alloc(self.expr_err(expr.span));
|
||||
|
||||
@ -9,17 +9,17 @@ use rustc_ast::{self as ast, *};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{DefKind, PartialRes, Res};
|
||||
use rustc_hir::GenericArg;
|
||||
use rustc_span::symbol::{kw, Ident};
|
||||
use rustc_span::symbol::{kw, sym, Ident};
|
||||
use rustc_span::{BytePos, Span, DUMMY_SP};
|
||||
|
||||
use smallvec::smallvec;
|
||||
use smallvec::{smallvec, SmallVec};
|
||||
|
||||
impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
#[instrument(level = "trace", skip(self))]
|
||||
pub(crate) fn lower_qpath(
|
||||
&mut self,
|
||||
id: NodeId,
|
||||
qself: &Option<QSelf>,
|
||||
qself: &Option<ptr::P<QSelf>>,
|
||||
p: &Path,
|
||||
param_mode: ParamMode,
|
||||
itctx: &ImplTraitContext,
|
||||
@ -144,13 +144,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
);
|
||||
}
|
||||
|
||||
pub(crate) fn lower_path_extra(
|
||||
pub(crate) fn lower_use_path(
|
||||
&mut self,
|
||||
res: Res,
|
||||
res: SmallVec<[Res; 3]>,
|
||||
p: &Path,
|
||||
param_mode: ParamMode,
|
||||
) -> &'hir hir::Path<'hir> {
|
||||
self.arena.alloc(hir::Path {
|
||||
) -> &'hir hir::UsePath<'hir> {
|
||||
self.arena.alloc(hir::UsePath {
|
||||
res,
|
||||
segments: self.arena.alloc_from_iter(p.segments.iter().map(|segment| {
|
||||
self.lower_path_segment(
|
||||
@ -165,17 +165,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn lower_path(
|
||||
&mut self,
|
||||
id: NodeId,
|
||||
p: &Path,
|
||||
param_mode: ParamMode,
|
||||
) -> &'hir hir::Path<'hir> {
|
||||
let res = self.expect_full_res(id);
|
||||
let res = self.lower_res(res);
|
||||
self.lower_path_extra(res, p, param_mode)
|
||||
}
|
||||
|
||||
pub(crate) fn lower_path_segment(
|
||||
&mut self,
|
||||
path_span: Span,
|
||||
@ -185,13 +174,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
itctx: &ImplTraitContext,
|
||||
) -> hir::PathSegment<'hir> {
|
||||
debug!("path_span: {:?}, lower_path_segment(segment: {:?})", path_span, segment,);
|
||||
let (mut generic_args, infer_args) = if let Some(ref generic_args) = segment.args {
|
||||
match **generic_args {
|
||||
GenericArgs::AngleBracketed(ref data) => {
|
||||
let (mut generic_args, infer_args) = if let Some(generic_args) = segment.args.as_deref() {
|
||||
match generic_args {
|
||||
GenericArgs::AngleBracketed(data) => {
|
||||
self.lower_angle_bracketed_parameter_data(data, param_mode, itctx)
|
||||
}
|
||||
GenericArgs::Parenthesized(ref data) => match parenthesized_generic_args {
|
||||
ParenthesizedGenericArgs::Ok => self.lower_parenthesized_parameter_data(data),
|
||||
GenericArgs::Parenthesized(data) => match parenthesized_generic_args {
|
||||
ParenthesizedGenericArgs::Ok => {
|
||||
self.lower_parenthesized_parameter_data(data, itctx)
|
||||
}
|
||||
ParenthesizedGenericArgs::Err => {
|
||||
// Suggest replacing parentheses with angle brackets `Trait(params...)` to `Trait<params...>`
|
||||
let sub = if !data.inputs.is_empty() {
|
||||
@ -307,7 +298,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
let id = NodeId::from_u32(i);
|
||||
let l = self.lower_lifetime(&Lifetime {
|
||||
id,
|
||||
ident: Ident::new(kw::UnderscoreLifetime, elided_lifetime_span),
|
||||
ident: Ident::new(kw::Empty, elided_lifetime_span),
|
||||
});
|
||||
GenericArg::Lifetime(l)
|
||||
}),
|
||||
@ -344,6 +335,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
fn lower_parenthesized_parameter_data(
|
||||
&mut self,
|
||||
data: &ParenthesizedArgs,
|
||||
itctx: &ImplTraitContext,
|
||||
) -> (GenericArgsCtor<'hir>, bool) {
|
||||
// Switch to `PassThrough` mode for anonymous lifetimes; this
|
||||
// means that we permit things like `&Ref<T>`, where `Ref` has
|
||||
@ -355,6 +347,24 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
self.lower_ty_direct(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::FnTraitParam))
|
||||
}));
|
||||
let output_ty = match output {
|
||||
// Only allow `impl Trait` in return position. i.e.:
|
||||
// ```rust
|
||||
// fn f(_: impl Fn() -> impl Debug) -> impl Fn() -> impl Debug
|
||||
// // disallowed --^^^^^^^^^^ allowed --^^^^^^^^^^
|
||||
// ```
|
||||
FnRetTy::Ty(ty) if matches!(itctx, ImplTraitContext::ReturnPositionOpaqueTy { .. }) => {
|
||||
if self.tcx.features().impl_trait_in_fn_trait_return {
|
||||
self.lower_ty(&ty, itctx)
|
||||
} else {
|
||||
self.lower_ty(
|
||||
&ty,
|
||||
&ImplTraitContext::FeatureGated(
|
||||
ImplTraitPosition::FnTraitReturn,
|
||||
sym::impl_trait_in_fn_trait_return,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
FnRetTy::Ty(ty) => {
|
||||
self.lower_ty(&ty, &ImplTraitContext::Disallowed(ImplTraitPosition::FnTraitReturn))
|
||||
}
|
||||
|
||||
@ -209,7 +209,7 @@ impl<'a> AstValidator<'a> {
|
||||
|
||||
// Mirrors `visit::walk_ty`, but tracks relevant state.
|
||||
fn walk_ty(&mut self, t: &'a Ty) {
|
||||
match t.kind {
|
||||
match &t.kind {
|
||||
TyKind::ImplTrait(..) => {
|
||||
self.with_impl_trait(Some(t.span), |this| visit::walk_ty(this, t))
|
||||
}
|
||||
@ -217,7 +217,7 @@ impl<'a> AstValidator<'a> {
|
||||
.with_banned_tilde_const(DisallowTildeConstContext::TraitObject, |this| {
|
||||
visit::walk_ty(this, t)
|
||||
}),
|
||||
TyKind::Path(ref qself, ref path) => {
|
||||
TyKind::Path(qself, path) => {
|
||||
// We allow these:
|
||||
// - `Option<impl Trait>`
|
||||
// - `option::Option<impl Trait>`
|
||||
@ -231,7 +231,7 @@ impl<'a> AstValidator<'a> {
|
||||
// (for cases like `<impl Trait>::Foo>`)
|
||||
// but we allow `impl Trait` in `GenericArgs`
|
||||
// iff there are no more PathSegments.
|
||||
if let Some(ref qself) = *qself {
|
||||
if let Some(qself) = qself {
|
||||
// `impl Trait` in `qself` is always illegal
|
||||
self.with_banned_impl_trait(|this| this.visit_ty(&qself.ty));
|
||||
}
|
||||
@ -738,8 +738,8 @@ impl<'a> AstValidator<'a> {
|
||||
}
|
||||
|
||||
fn visit_ty_common(&mut self, ty: &'a Ty) {
|
||||
match ty.kind {
|
||||
TyKind::BareFn(ref bfty) => {
|
||||
match &ty.kind {
|
||||
TyKind::BareFn(bfty) => {
|
||||
self.check_fn_decl(&bfty.decl, SelfSemantic::No);
|
||||
Self::check_decl_no_pat(&bfty.decl, |span, _, _| {
|
||||
struct_span_err!(
|
||||
@ -756,10 +756,10 @@ impl<'a> AstValidator<'a> {
|
||||
self.maybe_lint_missing_abi(sig_span, ty.id);
|
||||
}
|
||||
}
|
||||
TyKind::TraitObject(ref bounds, ..) => {
|
||||
TyKind::TraitObject(bounds, ..) => {
|
||||
let mut any_lifetime_bounds = false;
|
||||
for bound in bounds {
|
||||
if let GenericBound::Outlives(ref lifetime) = *bound {
|
||||
if let GenericBound::Outlives(lifetime) = bound {
|
||||
if any_lifetime_bounds {
|
||||
struct_span_err!(
|
||||
self.session,
|
||||
@ -774,7 +774,7 @@ impl<'a> AstValidator<'a> {
|
||||
}
|
||||
}
|
||||
}
|
||||
TyKind::ImplTrait(_, ref bounds) => {
|
||||
TyKind::ImplTrait(_, bounds) => {
|
||||
if self.is_impl_trait_banned {
|
||||
struct_span_err!(
|
||||
self.session,
|
||||
@ -842,8 +842,8 @@ fn validate_generic_param_order(
|
||||
let (kind, bounds, span) = (¶m.kind, ¶m.bounds, ident.span);
|
||||
let (ord_kind, ident) = match ¶m.kind {
|
||||
GenericParamKind::Lifetime => (ParamKindOrd::Lifetime, ident.to_string()),
|
||||
GenericParamKind::Type { default: _ } => (ParamKindOrd::TypeOrConst, ident.to_string()),
|
||||
GenericParamKind::Const { ref ty, kw_span: _, default: _ } => {
|
||||
GenericParamKind::Type { .. } => (ParamKindOrd::TypeOrConst, ident.to_string()),
|
||||
GenericParamKind::Const { ty, .. } => {
|
||||
let ty = pprust::ty_to_string(ty);
|
||||
(ParamKindOrd::TypeOrConst, format!("const {}: {}", ident, ty))
|
||||
}
|
||||
@ -912,7 +912,7 @@ fn validate_generic_param_order(
|
||||
|
||||
impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
fn visit_attribute(&mut self, attr: &Attribute) {
|
||||
validate_attr::check_meta(&self.session.parse_sess, attr);
|
||||
validate_attr::check_attr(&self.session.parse_sess, attr);
|
||||
}
|
||||
|
||||
fn visit_expr(&mut self, expr: &'a Expr) {
|
||||
@ -948,8 +948,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
}
|
||||
ExprKind::Paren(local_expr) => {
|
||||
fn has_let_expr(expr: &Expr) -> bool {
|
||||
match expr.kind {
|
||||
ExprKind::Binary(_, ref lhs, ref rhs) => has_let_expr(lhs) || has_let_expr(rhs),
|
||||
match &expr.kind {
|
||||
ExprKind::Binary(_, lhs, rhs) => has_let_expr(lhs) || has_let_expr(rhs),
|
||||
ExprKind::Let(..) => true,
|
||||
_ => false,
|
||||
}
|
||||
@ -1005,18 +1005,18 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
self.check_nomangle_item_asciionly(item.ident, item.span);
|
||||
}
|
||||
|
||||
match item.kind {
|
||||
match &item.kind {
|
||||
ItemKind::Impl(box Impl {
|
||||
unsafety,
|
||||
polarity,
|
||||
defaultness: _,
|
||||
constness,
|
||||
ref generics,
|
||||
of_trait: Some(ref t),
|
||||
ref self_ty,
|
||||
ref items,
|
||||
generics,
|
||||
of_trait: Some(t),
|
||||
self_ty,
|
||||
items,
|
||||
}) => {
|
||||
self.with_in_trait_impl(true, Some(constness), |this| {
|
||||
self.with_in_trait_impl(true, Some(*constness), |this| {
|
||||
this.invalid_visibility(&item.vis, None);
|
||||
if let TyKind::Err = self_ty.kind {
|
||||
this.err_handler()
|
||||
@ -1027,7 +1027,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
.help("use `auto trait Trait {}` instead")
|
||||
.emit();
|
||||
}
|
||||
if let (Unsafe::Yes(span), ImplPolarity::Negative(sp)) = (unsafety, polarity) {
|
||||
if let (&Unsafe::Yes(span), &ImplPolarity::Negative(sp)) = (unsafety, polarity)
|
||||
{
|
||||
struct_span_err!(
|
||||
this.session,
|
||||
sp.to(t.path.span),
|
||||
@ -1051,6 +1052,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
|
||||
walk_list!(this, visit_assoc_item, items, AssocCtxt::Impl);
|
||||
});
|
||||
walk_list!(self, visit_attribute, &item.attrs);
|
||||
return; // Avoid visiting again.
|
||||
}
|
||||
ItemKind::Impl(box Impl {
|
||||
@ -1060,7 +1062,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
constness,
|
||||
generics: _,
|
||||
of_trait: None,
|
||||
ref self_ty,
|
||||
self_ty,
|
||||
items: _,
|
||||
}) => {
|
||||
let error = |annotation_span, annotation| {
|
||||
@ -1077,25 +1079,25 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
&item.vis,
|
||||
Some(InvalidVisibilityNote::IndividualImplItems),
|
||||
);
|
||||
if let Unsafe::Yes(span) = unsafety {
|
||||
if let &Unsafe::Yes(span) = unsafety {
|
||||
error(span, "unsafe").code(error_code!(E0197)).emit();
|
||||
}
|
||||
if let ImplPolarity::Negative(span) = polarity {
|
||||
if let &ImplPolarity::Negative(span) = polarity {
|
||||
error(span, "negative").emit();
|
||||
}
|
||||
if let Defaultness::Default(def_span) = defaultness {
|
||||
if let &Defaultness::Default(def_span) = defaultness {
|
||||
error(def_span, "`default`")
|
||||
.note("only trait implementations may be annotated with `default`")
|
||||
.emit();
|
||||
}
|
||||
if let Const::Yes(span) = constness {
|
||||
if let &Const::Yes(span) = constness {
|
||||
error(span, "`const`")
|
||||
.note("only trait implementations may be annotated with `const`")
|
||||
.emit();
|
||||
}
|
||||
}
|
||||
ItemKind::Fn(box Fn { defaultness, ref sig, ref generics, ref body }) => {
|
||||
self.check_defaultness(item.span, defaultness);
|
||||
ItemKind::Fn(box Fn { defaultness, sig, generics, body }) => {
|
||||
self.check_defaultness(item.span, *defaultness);
|
||||
|
||||
if body.is_none() {
|
||||
self.session.emit_err(FnWithoutBody {
|
||||
@ -1131,7 +1133,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
&item.vis,
|
||||
Some(InvalidVisibilityNote::IndividualForeignItems),
|
||||
);
|
||||
if let Unsafe::Yes(span) = unsafety {
|
||||
if let &Unsafe::Yes(span) = unsafety {
|
||||
self.err_handler().span_err(span, "extern block cannot be declared unsafe");
|
||||
}
|
||||
if abi.is_none() {
|
||||
@ -1141,7 +1143,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
self.extern_mod = old_item;
|
||||
return; // Avoid visiting again.
|
||||
}
|
||||
ItemKind::Enum(ref def, _) => {
|
||||
ItemKind::Enum(def, _) => {
|
||||
for variant in &def.variants {
|
||||
self.invalid_visibility(&variant.vis, None);
|
||||
for field in variant.data.fields() {
|
||||
@ -1149,8 +1151,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
}
|
||||
}
|
||||
}
|
||||
ItemKind::Trait(box Trait { is_auto, ref generics, ref bounds, ref items, .. }) => {
|
||||
if is_auto == IsAuto::Yes {
|
||||
ItemKind::Trait(box Trait { is_auto, generics, bounds, items, .. }) => {
|
||||
if *is_auto == IsAuto::Yes {
|
||||
// Auto traits cannot have generics, super traits nor contain items.
|
||||
self.deny_generic_params(generics, item.ident.span);
|
||||
self.deny_super_traits(bounds, item.ident.span);
|
||||
@ -1168,10 +1170,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
});
|
||||
walk_list!(self, visit_assoc_item, items, AssocCtxt::Trait);
|
||||
walk_list!(self, visit_attribute, &item.attrs);
|
||||
return;
|
||||
return; // Avoid visiting again
|
||||
}
|
||||
ItemKind::Mod(unsafety, ref mod_kind) => {
|
||||
if let Unsafe::Yes(span) = unsafety {
|
||||
ItemKind::Mod(unsafety, mod_kind) => {
|
||||
if let &Unsafe::Yes(span) = unsafety {
|
||||
self.err_handler().span_err(span, "module cannot be declared unsafe");
|
||||
}
|
||||
// Ensure that `path` attributes on modules are recorded as used (cf. issue #35584).
|
||||
@ -1181,13 +1183,13 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
self.check_mod_file_item_asciionly(item.ident);
|
||||
}
|
||||
}
|
||||
ItemKind::Union(ref vdata, ..) => {
|
||||
ItemKind::Union(vdata, ..) => {
|
||||
if vdata.fields().is_empty() {
|
||||
self.err_handler().span_err(item.span, "unions cannot have zero fields");
|
||||
}
|
||||
}
|
||||
ItemKind::Const(def, .., None) => {
|
||||
self.check_defaultness(item.span, def);
|
||||
self.check_defaultness(item.span, *def);
|
||||
self.session.emit_err(ConstWithoutBody {
|
||||
span: item.span,
|
||||
replace_span: self.ending_semi_or_hi(item.span),
|
||||
@ -1199,14 +1201,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
replace_span: self.ending_semi_or_hi(item.span),
|
||||
});
|
||||
}
|
||||
ItemKind::TyAlias(box TyAlias {
|
||||
defaultness,
|
||||
where_clauses,
|
||||
ref bounds,
|
||||
ref ty,
|
||||
..
|
||||
}) => {
|
||||
self.check_defaultness(item.span, defaultness);
|
||||
ItemKind::TyAlias(box TyAlias { defaultness, where_clauses, bounds, ty, .. }) => {
|
||||
self.check_defaultness(item.span, *defaultness);
|
||||
if ty.is_none() {
|
||||
self.session.emit_err(TyAliasWithoutBody {
|
||||
span: item.span,
|
||||
@ -1265,8 +1261,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
|
||||
// Mirrors `visit::walk_generic_args`, but tracks relevant state.
|
||||
fn visit_generic_args(&mut self, generic_args: &'a GenericArgs) {
|
||||
match *generic_args {
|
||||
GenericArgs::AngleBracketed(ref data) => {
|
||||
match generic_args {
|
||||
GenericArgs::AngleBracketed(data) => {
|
||||
self.check_generic_args_before_constraints(data);
|
||||
|
||||
for arg in &data.args {
|
||||
@ -1282,7 +1278,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
}
|
||||
}
|
||||
}
|
||||
GenericArgs::Parenthesized(ref data) => {
|
||||
GenericArgs::Parenthesized(data) => {
|
||||
walk_list!(self, visit_ty, &data.inputs);
|
||||
if let FnRetTy::Ty(ty) = &data.output {
|
||||
// `-> Foo` syntax is essentially an associated type binding,
|
||||
@ -1318,7 +1314,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
validate_generic_param_order(self.err_handler(), &generics.params, generics.span);
|
||||
|
||||
for predicate in &generics.where_clause.predicates {
|
||||
if let WherePredicate::EqPredicate(ref predicate) = *predicate {
|
||||
if let WherePredicate::EqPredicate(predicate) = predicate {
|
||||
deny_equality_constraints(self, predicate, generics);
|
||||
}
|
||||
}
|
||||
@ -1367,7 +1363,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
}
|
||||
|
||||
fn visit_param_bound(&mut self, bound: &'a GenericBound, ctxt: BoundKind) {
|
||||
if let GenericBound::Trait(ref poly, modify) = *bound {
|
||||
if let GenericBound::Trait(poly, modify) = bound {
|
||||
match (ctxt, modify) {
|
||||
(BoundKind::SuperTraits, TraitBoundModifier::Maybe) => {
|
||||
let mut err = self
|
||||
@ -1572,8 +1568,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
self.check_item_named(item.ident, "const");
|
||||
}
|
||||
|
||||
match item.kind {
|
||||
AssocItemKind::Type(box TyAlias { ref generics, ref bounds, ref ty, .. })
|
||||
match &item.kind {
|
||||
AssocItemKind::Type(box TyAlias { generics, bounds, ty, .. })
|
||||
if ctxt == AssocCtxt::Trait =>
|
||||
{
|
||||
self.visit_vis(&item.vis);
|
||||
@ -1585,7 +1581,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
});
|
||||
walk_list!(self, visit_ty, ty);
|
||||
}
|
||||
AssocItemKind::Fn(box Fn { ref sig, ref generics, ref body, .. })
|
||||
AssocItemKind::Fn(box Fn { sig, generics, body, .. })
|
||||
if self.in_const_trait_impl
|
||||
|| ctxt == AssocCtxt::Trait
|
||||
|| matches!(sig.header.constness, Const::Yes(_)) =>
|
||||
@ -1636,7 +1632,7 @@ fn deny_equality_constraints(
|
||||
// Remove `Bar` from `Foo::Bar`.
|
||||
assoc_path.segments.pop();
|
||||
let len = assoc_path.segments.len() - 1;
|
||||
let gen_args = args.as_ref().map(|p| (**p).clone());
|
||||
let gen_args = args.as_deref().cloned();
|
||||
// Build `<Bar = RhsTy>`.
|
||||
let arg = AngleBracketedArg::Constraint(AssocConstraint {
|
||||
id: rustc_ast::node_id::DUMMY_NODE_ID,
|
||||
|
||||
@ -198,8 +198,8 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
|
||||
}
|
||||
|
||||
fn visit_item(&mut self, i: &'a ast::Item) {
|
||||
match i.kind {
|
||||
ast::ItemKind::ForeignMod(ref foreign_module) => {
|
||||
match &i.kind {
|
||||
ast::ItemKind::ForeignMod(foreign_module) => {
|
||||
if let Some(abi) = foreign_module.abi {
|
||||
self.check_abi(abi, ast::Const::No);
|
||||
}
|
||||
@ -233,8 +233,8 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
ast::ItemKind::Impl(box ast::Impl { polarity, defaultness, ref of_trait, .. }) => {
|
||||
if let ast::ImplPolarity::Negative(span) = polarity {
|
||||
ast::ItemKind::Impl(box ast::Impl { polarity, defaultness, of_trait, .. }) => {
|
||||
if let &ast::ImplPolarity::Negative(span) = polarity {
|
||||
gate_feature_post!(
|
||||
&self,
|
||||
negative_impls,
|
||||
@ -267,7 +267,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
|
||||
gate_feature_post!(&self, decl_macro, i.span, msg);
|
||||
}
|
||||
|
||||
ast::ItemKind::TyAlias(box ast::TyAlias { ty: Some(ref ty), .. }) => {
|
||||
ast::ItemKind::TyAlias(box ast::TyAlias { ty: Some(ty), .. }) => {
|
||||
self.check_impl_trait(&ty)
|
||||
}
|
||||
|
||||
@ -302,8 +302,8 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
|
||||
}
|
||||
|
||||
fn visit_ty(&mut self, ty: &'a ast::Ty) {
|
||||
match ty.kind {
|
||||
ast::TyKind::BareFn(ref bare_fn_ty) => {
|
||||
match &ty.kind {
|
||||
ast::TyKind::BareFn(bare_fn_ty) => {
|
||||
// Function pointers cannot be `const`
|
||||
self.check_extern(bare_fn_ty.ext, ast::Const::No);
|
||||
}
|
||||
@ -319,7 +319,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
|
||||
}
|
||||
|
||||
fn visit_fn_ret_ty(&mut self, ret_ty: &'a ast::FnRetTy) {
|
||||
if let ast::FnRetTy::Ty(ref output_ty) = *ret_ty {
|
||||
if let ast::FnRetTy::Ty(output_ty) = ret_ty {
|
||||
if let ast::TyKind::Never = output_ty.kind {
|
||||
// Do nothing.
|
||||
} else {
|
||||
@ -455,9 +455,9 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
|
||||
}
|
||||
|
||||
fn visit_assoc_item(&mut self, i: &'a ast::AssocItem, ctxt: AssocCtxt) {
|
||||
let is_fn = match i.kind {
|
||||
let is_fn = match &i.kind {
|
||||
ast::AssocItemKind::Fn(_) => true,
|
||||
ast::AssocItemKind::Type(box ast::TyAlias { ref ty, .. }) => {
|
||||
ast::AssocItemKind::Type(box ast::TyAlias { ty, .. }) => {
|
||||
if let (Some(_), AssocCtxt::Trait) = (ty, ctxt) {
|
||||
gate_feature_post!(
|
||||
&self,
|
||||
|
||||
@ -36,8 +36,8 @@ impl Printer {
|
||||
self.nbsp()
|
||||
}
|
||||
|
||||
// Synthesizes a comment that was not textually present in the original
|
||||
// source file.
|
||||
/// Synthesizes a comment that was not textually present in the original
|
||||
/// source file.
|
||||
pub fn synth_comment(&mut self, text: impl Into<Cow<'static, str>>) {
|
||||
self.word("/*");
|
||||
self.space();
|
||||
|
||||
@ -11,16 +11,15 @@ use rustc_ast::tokenstream::{TokenStream, TokenTree};
|
||||
use rustc_ast::util::classify;
|
||||
use rustc_ast::util::comments::{gather_comments, Comment, CommentStyle};
|
||||
use rustc_ast::util::parser;
|
||||
use rustc_ast::{self as ast, BlockCheckMode, Mutability, PatKind, RangeEnd, RangeSyntax};
|
||||
use rustc_ast::{attr, BindingAnnotation, ByRef, Term};
|
||||
use rustc_ast::{GenericArg, MacArgs, MacArgsEq};
|
||||
use rustc_ast::{GenericBound, SelfKind, TraitBoundModifier};
|
||||
use rustc_ast::{self as ast, AttrArgs, AttrArgsEq, BlockCheckMode, PatKind};
|
||||
use rustc_ast::{attr, BindingAnnotation, ByRef, DelimArgs, RangeEnd, RangeSyntax, Term};
|
||||
use rustc_ast::{GenericArg, GenericBound, SelfKind, TraitBoundModifier};
|
||||
use rustc_ast::{InlineAsmOperand, InlineAsmRegOrRegClass};
|
||||
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
|
||||
use rustc_span::edition::Edition;
|
||||
use rustc_span::source_map::{SourceMap, Spanned};
|
||||
use rustc_span::symbol::{kw, sym, Ident, IdentPrinter, Symbol};
|
||||
use rustc_span::{BytePos, FileName, Span};
|
||||
use rustc_span::{BytePos, FileName, Span, DUMMY_SP};
|
||||
|
||||
use rustc_ast::attr::AttrIdGenerator;
|
||||
use std::borrow::Cow;
|
||||
@ -65,6 +64,7 @@ impl<'a> Comments<'a> {
|
||||
Comments { sm, comments, current: 0 }
|
||||
}
|
||||
|
||||
// FIXME: This shouldn't probably clone lmao
|
||||
pub fn next(&self) -> Option<Comment> {
|
||||
self.comments.get(self.current).cloned()
|
||||
}
|
||||
@ -120,17 +120,20 @@ pub fn print_crate<'a>(
|
||||
// of the feature gate, so we fake them up here.
|
||||
|
||||
// `#![feature(prelude_import)]`
|
||||
let pi_nested = attr::mk_nested_word_item(Ident::with_dummy_span(sym::prelude_import));
|
||||
let list = attr::mk_list_item(Ident::with_dummy_span(sym::feature), vec![pi_nested]);
|
||||
let fake_attr = attr::mk_attr_inner(g, list);
|
||||
let fake_attr = attr::mk_attr_nested_word(
|
||||
g,
|
||||
ast::AttrStyle::Inner,
|
||||
sym::feature,
|
||||
sym::prelude_import,
|
||||
DUMMY_SP,
|
||||
);
|
||||
s.print_attribute(&fake_attr);
|
||||
|
||||
// Currently, in Rust 2018 we don't have `extern crate std;` at the crate
|
||||
// root, so this is not needed, and actually breaks things.
|
||||
if edition == Edition::Edition2015 {
|
||||
// `#![no_std]`
|
||||
let no_std_meta = attr::mk_word_item(Ident::with_dummy_span(sym::no_std));
|
||||
let fake_attr = attr::mk_attr_inner(g, no_std_meta);
|
||||
let fake_attr = attr::mk_attr_word(g, ast::AttrStyle::Inner, sym::no_std, DUMMY_SP);
|
||||
s.print_attribute(&fake_attr);
|
||||
}
|
||||
}
|
||||
@ -269,10 +272,10 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
|
||||
|
||||
fn maybe_print_comment(&mut self, pos: BytePos) -> bool {
|
||||
let mut has_comment = false;
|
||||
while let Some(ref cmnt) = self.next_comment() {
|
||||
while let Some(cmnt) = self.next_comment() {
|
||||
if cmnt.pos < pos {
|
||||
has_comment = true;
|
||||
self.print_comment(cmnt);
|
||||
self.print_comment(&cmnt);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
@ -367,14 +370,18 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
|
||||
if self.next_comment().is_none() {
|
||||
self.hardbreak();
|
||||
}
|
||||
while let Some(ref cmnt) = self.next_comment() {
|
||||
self.print_comment(cmnt)
|
||||
while let Some(cmnt) = self.next_comment() {
|
||||
self.print_comment(&cmnt)
|
||||
}
|
||||
}
|
||||
|
||||
fn print_literal(&mut self, lit: &ast::Lit) {
|
||||
self.maybe_print_comment(lit.span.lo());
|
||||
self.word(lit.token_lit.to_string())
|
||||
fn print_meta_item_lit(&mut self, lit: &ast::MetaItemLit) {
|
||||
self.print_token_literal(lit.token_lit, lit.span)
|
||||
}
|
||||
|
||||
fn print_token_literal(&mut self, token_lit: token::Lit, span: Span) {
|
||||
self.maybe_print_comment(span.lo());
|
||||
self.word(token_lit.to_string())
|
||||
}
|
||||
|
||||
fn print_string(&mut self, st: &str, style: ast::StrStyle) {
|
||||
@ -443,8 +450,8 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
|
||||
self.hardbreak_if_not_bol();
|
||||
}
|
||||
self.maybe_print_comment(attr.span.lo());
|
||||
match attr.kind {
|
||||
ast::AttrKind::Normal(ref normal) => {
|
||||
match &attr.kind {
|
||||
ast::AttrKind::Normal(normal) => {
|
||||
match attr.style {
|
||||
ast::AttrStyle::Inner => self.word("#!["),
|
||||
ast::AttrStyle::Outer => self.word("#["),
|
||||
@ -453,7 +460,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
|
||||
self.word("]");
|
||||
}
|
||||
ast::AttrKind::DocComment(comment_kind, data) => {
|
||||
self.word(doc_comment_to_string(comment_kind, attr.style, data));
|
||||
self.word(doc_comment_to_string(*comment_kind, attr.style, *data));
|
||||
self.hardbreak()
|
||||
}
|
||||
}
|
||||
@ -462,30 +469,30 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
|
||||
fn print_attr_item(&mut self, item: &ast::AttrItem, span: Span) {
|
||||
self.ibox(0);
|
||||
match &item.args {
|
||||
MacArgs::Delimited(_, delim, tokens) => self.print_mac_common(
|
||||
AttrArgs::Delimited(DelimArgs { dspan: _, delim, tokens }) => self.print_mac_common(
|
||||
Some(MacHeader::Path(&item.path)),
|
||||
false,
|
||||
None,
|
||||
Some(delim.to_token()),
|
||||
delim.to_token(),
|
||||
tokens,
|
||||
true,
|
||||
span,
|
||||
),
|
||||
MacArgs::Empty => {
|
||||
AttrArgs::Empty => {
|
||||
self.print_path(&item.path, false, 0);
|
||||
}
|
||||
MacArgs::Eq(_, MacArgsEq::Ast(expr)) => {
|
||||
AttrArgs::Eq(_, AttrArgsEq::Ast(expr)) => {
|
||||
self.print_path(&item.path, false, 0);
|
||||
self.space();
|
||||
self.word_space("=");
|
||||
let token_str = self.expr_to_string(expr);
|
||||
self.word(token_str);
|
||||
}
|
||||
MacArgs::Eq(_, MacArgsEq::Hir(lit)) => {
|
||||
AttrArgs::Eq(_, AttrArgsEq::Hir(lit)) => {
|
||||
self.print_path(&item.path, false, 0);
|
||||
self.space();
|
||||
self.word_space("=");
|
||||
let token_str = self.literal_to_string(lit);
|
||||
let token_str = self.meta_item_lit_to_string(lit);
|
||||
self.word(token_str);
|
||||
}
|
||||
}
|
||||
@ -494,25 +501,25 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
|
||||
|
||||
fn print_meta_list_item(&mut self, item: &ast::NestedMetaItem) {
|
||||
match item {
|
||||
ast::NestedMetaItem::MetaItem(ref mi) => self.print_meta_item(mi),
|
||||
ast::NestedMetaItem::Literal(ref lit) => self.print_literal(lit),
|
||||
ast::NestedMetaItem::MetaItem(mi) => self.print_meta_item(mi),
|
||||
ast::NestedMetaItem::Lit(lit) => self.print_meta_item_lit(lit),
|
||||
}
|
||||
}
|
||||
|
||||
fn print_meta_item(&mut self, item: &ast::MetaItem) {
|
||||
self.ibox(INDENT_UNIT);
|
||||
match item.kind {
|
||||
match &item.kind {
|
||||
ast::MetaItemKind::Word => self.print_path(&item.path, false, 0),
|
||||
ast::MetaItemKind::NameValue(ref value) => {
|
||||
ast::MetaItemKind::NameValue(value) => {
|
||||
self.print_path(&item.path, false, 0);
|
||||
self.space();
|
||||
self.word_space("=");
|
||||
self.print_literal(value);
|
||||
self.print_meta_item_lit(value);
|
||||
}
|
||||
ast::MetaItemKind::List(ref items) => {
|
||||
ast::MetaItemKind::List(items) => {
|
||||
self.print_path(&item.path, false, 0);
|
||||
self.popen();
|
||||
self.commasep(Consistent, &items, |s, i| s.print_meta_list_item(i));
|
||||
self.commasep(Consistent, items, |s, i| s.print_meta_list_item(i));
|
||||
self.pclose();
|
||||
}
|
||||
}
|
||||
@ -529,7 +536,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
|
||||
fn print_tt(&mut self, tt: &TokenTree, convert_dollar_crate: bool) {
|
||||
match tt {
|
||||
TokenTree::Token(token, _) => {
|
||||
let token_str = self.token_to_string_ext(&token, convert_dollar_crate);
|
||||
let token_str = self.token_to_string_ext(token, convert_dollar_crate);
|
||||
self.word(token_str);
|
||||
if let token::DocComment(..) = token.kind {
|
||||
self.hardbreak()
|
||||
@ -540,7 +547,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
|
||||
None,
|
||||
false,
|
||||
None,
|
||||
Some(*delim),
|
||||
*delim,
|
||||
tts,
|
||||
convert_dollar_crate,
|
||||
dspan.entire(),
|
||||
@ -566,12 +573,12 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
|
||||
header: Option<MacHeader<'_>>,
|
||||
has_bang: bool,
|
||||
ident: Option<Ident>,
|
||||
delim: Option<Delimiter>,
|
||||
delim: Delimiter,
|
||||
tts: &TokenStream,
|
||||
convert_dollar_crate: bool,
|
||||
span: Span,
|
||||
) {
|
||||
if delim == Some(Delimiter::Brace) {
|
||||
if delim == Delimiter::Brace {
|
||||
self.cbox(INDENT_UNIT);
|
||||
}
|
||||
match header {
|
||||
@ -587,7 +594,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
|
||||
self.print_ident(ident);
|
||||
}
|
||||
match delim {
|
||||
Some(Delimiter::Brace) => {
|
||||
Delimiter::Brace => {
|
||||
if header.is_some() || has_bang || ident.is_some() {
|
||||
self.nbsp();
|
||||
}
|
||||
@ -601,7 +608,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
|
||||
let empty = tts.is_empty();
|
||||
self.bclose(span, empty);
|
||||
}
|
||||
Some(delim) => {
|
||||
delim => {
|
||||
let token_str = self.token_kind_to_string(&token::OpenDelim(delim));
|
||||
self.word(token_str);
|
||||
self.ibox(0);
|
||||
@ -610,11 +617,6 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
|
||||
let token_str = self.token_kind_to_string(&token::CloseDelim(delim));
|
||||
self.word(token_str);
|
||||
}
|
||||
None => {
|
||||
self.ibox(0);
|
||||
self.print_tts(tts, convert_dollar_crate);
|
||||
self.end();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -635,8 +637,8 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
|
||||
Some(MacHeader::Keyword(kw)),
|
||||
has_bang,
|
||||
Some(*ident),
|
||||
macro_def.body.delim(),
|
||||
¯o_def.body.inner_tokens(),
|
||||
macro_def.body.delim.to_token(),
|
||||
¯o_def.body.tokens.clone(),
|
||||
true,
|
||||
sp,
|
||||
);
|
||||
@ -659,7 +661,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
|
||||
fn print_path_segment(&mut self, segment: &ast::PathSegment, colons_before_params: bool) {
|
||||
if segment.ident.name != kw::PathRoot {
|
||||
self.print_ident(segment.ident);
|
||||
if let Some(ref args) = segment.args {
|
||||
if let Some(args) = &segment.args {
|
||||
self.print_generic_args(args, colons_before_params);
|
||||
}
|
||||
}
|
||||
@ -714,19 +716,19 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
|
||||
}
|
||||
|
||||
fn nonterminal_to_string(&self, nt: &Nonterminal) -> String {
|
||||
match *nt {
|
||||
token::NtExpr(ref e) => self.expr_to_string(e),
|
||||
token::NtMeta(ref e) => self.attr_item_to_string(e),
|
||||
token::NtTy(ref e) => self.ty_to_string(e),
|
||||
token::NtPath(ref e) => self.path_to_string(e),
|
||||
token::NtItem(ref e) => self.item_to_string(e),
|
||||
token::NtBlock(ref e) => self.block_to_string(e),
|
||||
token::NtStmt(ref e) => self.stmt_to_string(e),
|
||||
token::NtPat(ref e) => self.pat_to_string(e),
|
||||
token::NtIdent(e, is_raw) => IdentPrinter::for_ast_ident(e, is_raw).to_string(),
|
||||
match nt {
|
||||
token::NtExpr(e) => self.expr_to_string(e),
|
||||
token::NtMeta(e) => self.attr_item_to_string(e),
|
||||
token::NtTy(e) => self.ty_to_string(e),
|
||||
token::NtPath(e) => self.path_to_string(e),
|
||||
token::NtItem(e) => self.item_to_string(e),
|
||||
token::NtBlock(e) => self.block_to_string(e),
|
||||
token::NtStmt(e) => self.stmt_to_string(e),
|
||||
token::NtPat(e) => self.pat_to_string(e),
|
||||
token::NtIdent(e, is_raw) => IdentPrinter::for_ast_ident(*e, *is_raw).to_string(),
|
||||
token::NtLifetime(e) => e.to_string(),
|
||||
token::NtLiteral(ref e) => self.expr_to_string(e),
|
||||
token::NtVis(ref e) => self.vis_to_string(e),
|
||||
token::NtLiteral(e) => self.expr_to_string(e),
|
||||
token::NtVis(e) => self.vis_to_string(e),
|
||||
}
|
||||
}
|
||||
|
||||
@ -827,8 +829,8 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
|
||||
Self::to_string(|s| s.print_expr(e))
|
||||
}
|
||||
|
||||
fn literal_to_string(&self, lit: &ast::Lit) -> String {
|
||||
Self::to_string(|s| s.print_literal(lit))
|
||||
fn meta_item_lit_to_string(&self, lit: &ast::MetaItemLit) -> String {
|
||||
Self::to_string(|s| s.print_meta_item_lit(lit))
|
||||
}
|
||||
|
||||
fn tt_to_string(&self, tt: &TokenTree) -> String {
|
||||
@ -919,8 +921,8 @@ impl<'a> PrintState<'a> for State<'a> {
|
||||
self.word("::")
|
||||
}
|
||||
|
||||
match *args {
|
||||
ast::GenericArgs::AngleBracketed(ref data) => {
|
||||
match args {
|
||||
ast::GenericArgs::AngleBracketed(data) => {
|
||||
self.word("<");
|
||||
self.commasep(Inconsistent, &data.args, |s, arg| match arg {
|
||||
ast::AngleBracketedArg::Arg(a) => s.print_generic_arg(a),
|
||||
@ -929,7 +931,7 @@ impl<'a> PrintState<'a> for State<'a> {
|
||||
self.word(">")
|
||||
}
|
||||
|
||||
ast::GenericArgs::Parenthesized(ref data) => {
|
||||
ast::GenericArgs::Parenthesized(data) => {
|
||||
self.word("(");
|
||||
self.commasep(Inconsistent, &data.inputs, |s, ty| s.print_type(ty));
|
||||
self.word(")");
|
||||
@ -996,7 +998,7 @@ impl<'a> State<'a> {
|
||||
ast::AssocConstraintKind::Bound { bounds } => {
|
||||
if !bounds.is_empty() {
|
||||
self.word_nbsp(":");
|
||||
self.print_type_bounds(&bounds);
|
||||
self.print_type_bounds(bounds);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1013,17 +1015,17 @@ impl<'a> State<'a> {
|
||||
pub fn print_type(&mut self, ty: &ast::Ty) {
|
||||
self.maybe_print_comment(ty.span.lo());
|
||||
self.ibox(0);
|
||||
match ty.kind {
|
||||
ast::TyKind::Slice(ref ty) => {
|
||||
match &ty.kind {
|
||||
ast::TyKind::Slice(ty) => {
|
||||
self.word("[");
|
||||
self.print_type(ty);
|
||||
self.word("]");
|
||||
}
|
||||
ast::TyKind::Ptr(ref mt) => {
|
||||
ast::TyKind::Ptr(mt) => {
|
||||
self.word("*");
|
||||
self.print_mt(mt, true);
|
||||
}
|
||||
ast::TyKind::Rptr(ref lifetime, ref mt) => {
|
||||
ast::TyKind::Rptr(lifetime, mt) => {
|
||||
self.word("&");
|
||||
self.print_opt_lifetime(lifetime);
|
||||
self.print_mt(mt, false);
|
||||
@ -1031,44 +1033,44 @@ impl<'a> State<'a> {
|
||||
ast::TyKind::Never => {
|
||||
self.word("!");
|
||||
}
|
||||
ast::TyKind::Tup(ref elts) => {
|
||||
ast::TyKind::Tup(elts) => {
|
||||
self.popen();
|
||||
self.commasep(Inconsistent, &elts, |s, ty| s.print_type(ty));
|
||||
self.commasep(Inconsistent, elts, |s, ty| s.print_type(ty));
|
||||
if elts.len() == 1 {
|
||||
self.word(",");
|
||||
}
|
||||
self.pclose();
|
||||
}
|
||||
ast::TyKind::Paren(ref typ) => {
|
||||
ast::TyKind::Paren(typ) => {
|
||||
self.popen();
|
||||
self.print_type(typ);
|
||||
self.pclose();
|
||||
}
|
||||
ast::TyKind::BareFn(ref f) => {
|
||||
ast::TyKind::BareFn(f) => {
|
||||
self.print_ty_fn(f.ext, f.unsafety, &f.decl, None, &f.generic_params);
|
||||
}
|
||||
ast::TyKind::Path(None, ref path) => {
|
||||
ast::TyKind::Path(None, path) => {
|
||||
self.print_path(path, false, 0);
|
||||
}
|
||||
ast::TyKind::Path(Some(ref qself), ref path) => self.print_qpath(path, qself, false),
|
||||
ast::TyKind::TraitObject(ref bounds, syntax) => {
|
||||
if syntax == ast::TraitObjectSyntax::Dyn {
|
||||
ast::TyKind::Path(Some(qself), path) => self.print_qpath(path, qself, false),
|
||||
ast::TyKind::TraitObject(bounds, syntax) => {
|
||||
if *syntax == ast::TraitObjectSyntax::Dyn {
|
||||
self.word_nbsp("dyn");
|
||||
}
|
||||
self.print_type_bounds(bounds);
|
||||
}
|
||||
ast::TyKind::ImplTrait(_, ref bounds) => {
|
||||
ast::TyKind::ImplTrait(_, bounds) => {
|
||||
self.word_nbsp("impl");
|
||||
self.print_type_bounds(bounds);
|
||||
}
|
||||
ast::TyKind::Array(ref ty, ref length) => {
|
||||
ast::TyKind::Array(ty, length) => {
|
||||
self.word("[");
|
||||
self.print_type(ty);
|
||||
self.word("; ");
|
||||
self.print_expr(&length.value);
|
||||
self.word("]");
|
||||
}
|
||||
ast::TyKind::Typeof(ref e) => {
|
||||
ast::TyKind::Typeof(e) => {
|
||||
self.word("typeof(");
|
||||
self.print_expr(&e.value);
|
||||
self.word(")");
|
||||
@ -1084,7 +1086,7 @@ impl<'a> State<'a> {
|
||||
ast::TyKind::ImplicitSelf => {
|
||||
self.word("Self");
|
||||
}
|
||||
ast::TyKind::MacCall(ref m) => {
|
||||
ast::TyKind::MacCall(m) => {
|
||||
self.print_mac(m);
|
||||
}
|
||||
ast::TyKind::CVarArgs => {
|
||||
@ -1113,8 +1115,8 @@ impl<'a> State<'a> {
|
||||
|
||||
pub(crate) fn print_stmt(&mut self, st: &ast::Stmt) {
|
||||
self.maybe_print_comment(st.span.lo());
|
||||
match st.kind {
|
||||
ast::StmtKind::Local(ref loc) => {
|
||||
match &st.kind {
|
||||
ast::StmtKind::Local(loc) => {
|
||||
self.print_outer_attributes(&loc.attrs);
|
||||
self.space_if_not_bol();
|
||||
self.ibox(INDENT_UNIT);
|
||||
@ -1137,15 +1139,15 @@ impl<'a> State<'a> {
|
||||
self.word(";");
|
||||
self.end(); // `let` ibox
|
||||
}
|
||||
ast::StmtKind::Item(ref item) => self.print_item(item),
|
||||
ast::StmtKind::Expr(ref expr) => {
|
||||
ast::StmtKind::Item(item) => self.print_item(item),
|
||||
ast::StmtKind::Expr(expr) => {
|
||||
self.space_if_not_bol();
|
||||
self.print_expr_outer_attr_style(expr, false);
|
||||
if classify::expr_requires_semi_to_be_stmt(expr) {
|
||||
self.word(";");
|
||||
}
|
||||
}
|
||||
ast::StmtKind::Semi(ref expr) => {
|
||||
ast::StmtKind::Semi(expr) => {
|
||||
self.space_if_not_bol();
|
||||
self.print_expr_outer_attr_style(expr, false);
|
||||
self.word(";");
|
||||
@ -1154,7 +1156,7 @@ impl<'a> State<'a> {
|
||||
self.space_if_not_bol();
|
||||
self.word(";");
|
||||
}
|
||||
ast::StmtKind::MacCall(ref mac) => {
|
||||
ast::StmtKind::MacCall(mac) => {
|
||||
self.space_if_not_bol();
|
||||
self.print_outer_attributes(&mac.attrs);
|
||||
self.print_mac(&mac.mac);
|
||||
@ -1195,8 +1197,8 @@ impl<'a> State<'a> {
|
||||
let has_attrs = self.print_inner_attributes(attrs);
|
||||
|
||||
for (i, st) in blk.stmts.iter().enumerate() {
|
||||
match st.kind {
|
||||
ast::StmtKind::Expr(ref expr) if i == blk.stmts.len() - 1 => {
|
||||
match &st.kind {
|
||||
ast::StmtKind::Expr(expr) if i == blk.stmts.len() - 1 => {
|
||||
self.maybe_print_comment(st.span.lo());
|
||||
self.space_if_not_bol();
|
||||
self.print_expr_outer_attr_style(expr, false);
|
||||
@ -1226,8 +1228,8 @@ impl<'a> State<'a> {
|
||||
Some(MacHeader::Path(&m.path)),
|
||||
true,
|
||||
None,
|
||||
m.args.delim(),
|
||||
&m.args.inner_tokens(),
|
||||
m.args.delim.to_token(),
|
||||
&m.args.tokens.clone(),
|
||||
true,
|
||||
m.span(),
|
||||
);
|
||||
@ -1252,7 +1254,7 @@ impl<'a> State<'a> {
|
||||
|
||||
self.popen();
|
||||
self.commasep(Consistent, &args, |s, arg| match arg {
|
||||
AsmArg::Template(template) => s.print_string(&template, ast::StrStyle::Cooked),
|
||||
AsmArg::Template(template) => s.print_string(template, ast::StrStyle::Cooked),
|
||||
AsmArg::Operand(op) => {
|
||||
let print_reg_or_class = |s: &mut Self, r: &InlineAsmRegOrRegClass| match r {
|
||||
InlineAsmRegOrRegClass::Reg(r) => s.print_symbol(*r, ast::StrStyle::Cooked),
|
||||
@ -1364,7 +1366,7 @@ impl<'a> State<'a> {
|
||||
|
||||
pub(crate) fn print_local_decl(&mut self, loc: &ast::Local) {
|
||||
self.print_pat(&loc.pat);
|
||||
if let Some(ref ty) = loc.ty {
|
||||
if let Some(ty) = &loc.ty {
|
||||
self.word_space(":");
|
||||
self.print_type(ty);
|
||||
}
|
||||
@ -1388,7 +1390,7 @@ impl<'a> State<'a> {
|
||||
for item_segment in &path.segments[qself.position..] {
|
||||
self.word("::");
|
||||
self.print_ident(item_segment.ident);
|
||||
if let Some(ref args) = item_segment.args {
|
||||
if let Some(args) = &item_segment.args {
|
||||
self.print_generic_args(args, colons_before_params)
|
||||
}
|
||||
}
|
||||
@ -1399,42 +1401,42 @@ impl<'a> State<'a> {
|
||||
self.ann.pre(self, AnnNode::Pat(pat));
|
||||
/* Pat isn't normalized, but the beauty of it
|
||||
is that it doesn't matter */
|
||||
match pat.kind {
|
||||
match &pat.kind {
|
||||
PatKind::Wild => self.word("_"),
|
||||
PatKind::Ident(BindingAnnotation(by_ref, mutbl), ident, ref sub) => {
|
||||
if by_ref == ByRef::Yes {
|
||||
PatKind::Ident(BindingAnnotation(by_ref, mutbl), ident, sub) => {
|
||||
if *by_ref == ByRef::Yes {
|
||||
self.word_nbsp("ref");
|
||||
}
|
||||
if mutbl == Mutability::Mut {
|
||||
if mutbl.is_mut() {
|
||||
self.word_nbsp("mut");
|
||||
}
|
||||
self.print_ident(ident);
|
||||
if let Some(ref p) = *sub {
|
||||
self.print_ident(*ident);
|
||||
if let Some(p) = sub {
|
||||
self.space();
|
||||
self.word_space("@");
|
||||
self.print_pat(p);
|
||||
}
|
||||
}
|
||||
PatKind::TupleStruct(ref qself, ref path, ref elts) => {
|
||||
PatKind::TupleStruct(qself, path, elts) => {
|
||||
if let Some(qself) = qself {
|
||||
self.print_qpath(path, qself, true);
|
||||
} else {
|
||||
self.print_path(path, true, 0);
|
||||
}
|
||||
self.popen();
|
||||
self.commasep(Inconsistent, &elts, |s, p| s.print_pat(p));
|
||||
self.commasep(Inconsistent, elts, |s, p| s.print_pat(p));
|
||||
self.pclose();
|
||||
}
|
||||
PatKind::Or(ref pats) => {
|
||||
self.strsep("|", true, Inconsistent, &pats, |s, p| s.print_pat(p));
|
||||
PatKind::Or(pats) => {
|
||||
self.strsep("|", true, Inconsistent, pats, |s, p| s.print_pat(p));
|
||||
}
|
||||
PatKind::Path(None, ref path) => {
|
||||
PatKind::Path(None, path) => {
|
||||
self.print_path(path, true, 0);
|
||||
}
|
||||
PatKind::Path(Some(ref qself), ref path) => {
|
||||
PatKind::Path(Some(qself), path) => {
|
||||
self.print_qpath(path, qself, false);
|
||||
}
|
||||
PatKind::Struct(ref qself, ref path, ref fields, etc) => {
|
||||
PatKind::Struct(qself, path, fields, etc) => {
|
||||
if let Some(qself) = qself {
|
||||
self.print_qpath(path, qself, true);
|
||||
} else {
|
||||
@ -1448,7 +1450,7 @@ impl<'a> State<'a> {
|
||||
}
|
||||
self.commasep_cmnt(
|
||||
Consistent,
|
||||
&fields,
|
||||
fields,
|
||||
|s, f| {
|
||||
s.cbox(INDENT_UNIT);
|
||||
if !f.is_shorthand {
|
||||
@ -1460,7 +1462,7 @@ impl<'a> State<'a> {
|
||||
},
|
||||
|f| f.pat.span,
|
||||
);
|
||||
if etc {
|
||||
if *etc {
|
||||
if !fields.is_empty() {
|
||||
self.word_space(",");
|
||||
}
|
||||
@ -1471,21 +1473,21 @@ impl<'a> State<'a> {
|
||||
}
|
||||
self.word("}");
|
||||
}
|
||||
PatKind::Tuple(ref elts) => {
|
||||
PatKind::Tuple(elts) => {
|
||||
self.popen();
|
||||
self.commasep(Inconsistent, &elts, |s, p| s.print_pat(p));
|
||||
self.commasep(Inconsistent, elts, |s, p| s.print_pat(p));
|
||||
if elts.len() == 1 {
|
||||
self.word(",");
|
||||
}
|
||||
self.pclose();
|
||||
}
|
||||
PatKind::Box(ref inner) => {
|
||||
PatKind::Box(inner) => {
|
||||
self.word("box ");
|
||||
self.print_pat(inner);
|
||||
}
|
||||
PatKind::Ref(ref inner, mutbl) => {
|
||||
PatKind::Ref(inner, mutbl) => {
|
||||
self.word("&");
|
||||
if mutbl == Mutability::Mut {
|
||||
if mutbl.is_mut() {
|
||||
self.word("mut ");
|
||||
}
|
||||
if let PatKind::Ident(ast::BindingAnnotation::MUT, ..) = inner.kind {
|
||||
@ -1496,12 +1498,12 @@ impl<'a> State<'a> {
|
||||
self.print_pat(inner);
|
||||
}
|
||||
}
|
||||
PatKind::Lit(ref e) => self.print_expr(&**e),
|
||||
PatKind::Range(ref begin, ref end, Spanned { node: ref end_kind, .. }) => {
|
||||
PatKind::Lit(e) => self.print_expr(e),
|
||||
PatKind::Range(begin, end, Spanned { node: end_kind, .. }) => {
|
||||
if let Some(e) = begin {
|
||||
self.print_expr(e);
|
||||
}
|
||||
match *end_kind {
|
||||
match end_kind {
|
||||
RangeEnd::Included(RangeSyntax::DotDotDot) => self.word("..."),
|
||||
RangeEnd::Included(RangeSyntax::DotDotEq) => self.word("..="),
|
||||
RangeEnd::Excluded => self.word(".."),
|
||||
@ -1510,36 +1512,36 @@ impl<'a> State<'a> {
|
||||
self.print_expr(e);
|
||||
}
|
||||
}
|
||||
PatKind::Slice(ref elts) => {
|
||||
PatKind::Slice(elts) => {
|
||||
self.word("[");
|
||||
self.commasep(Inconsistent, &elts, |s, p| s.print_pat(p));
|
||||
self.commasep(Inconsistent, elts, |s, p| s.print_pat(p));
|
||||
self.word("]");
|
||||
}
|
||||
PatKind::Rest => self.word(".."),
|
||||
PatKind::Paren(ref inner) => {
|
||||
PatKind::Paren(inner) => {
|
||||
self.popen();
|
||||
self.print_pat(inner);
|
||||
self.pclose();
|
||||
}
|
||||
PatKind::MacCall(ref m) => self.print_mac(m),
|
||||
PatKind::MacCall(m) => self.print_mac(m),
|
||||
}
|
||||
self.ann.post(self, AnnNode::Pat(pat))
|
||||
}
|
||||
|
||||
fn print_explicit_self(&mut self, explicit_self: &ast::ExplicitSelf) {
|
||||
match explicit_self.node {
|
||||
match &explicit_self.node {
|
||||
SelfKind::Value(m) => {
|
||||
self.print_mutability(m, false);
|
||||
self.print_mutability(*m, false);
|
||||
self.word("self")
|
||||
}
|
||||
SelfKind::Region(ref lt, m) => {
|
||||
SelfKind::Region(lt, m) => {
|
||||
self.word("&");
|
||||
self.print_opt_lifetime(lt);
|
||||
self.print_mutability(m, false);
|
||||
self.print_mutability(*m, false);
|
||||
self.word("self")
|
||||
}
|
||||
SelfKind::Explicit(ref typ, m) => {
|
||||
self.print_mutability(m, false);
|
||||
SelfKind::Explicit(typ, m) => {
|
||||
self.print_mutability(*m, false);
|
||||
self.word("self");
|
||||
self.word_space(":");
|
||||
self.print_type(typ)
|
||||
@ -1598,10 +1600,10 @@ impl<'a> State<'a> {
|
||||
|
||||
self.word("<");
|
||||
|
||||
self.commasep(Inconsistent, &generic_params, |s, param| {
|
||||
self.commasep(Inconsistent, generic_params, |s, param| {
|
||||
s.print_outer_attributes_inline(¶m.attrs);
|
||||
|
||||
match param.kind {
|
||||
match ¶m.kind {
|
||||
ast::GenericParamKind::Lifetime => {
|
||||
let lt = ast::Lifetime { id: param.id, ident: param.ident };
|
||||
s.print_lifetime(lt);
|
||||
@ -1610,19 +1612,19 @@ impl<'a> State<'a> {
|
||||
s.print_lifetime_bounds(¶m.bounds)
|
||||
}
|
||||
}
|
||||
ast::GenericParamKind::Type { ref default } => {
|
||||
ast::GenericParamKind::Type { default } => {
|
||||
s.print_ident(param.ident);
|
||||
if !param.bounds.is_empty() {
|
||||
s.word_nbsp(":");
|
||||
s.print_type_bounds(¶m.bounds);
|
||||
}
|
||||
if let Some(ref default) = default {
|
||||
if let Some(default) = default {
|
||||
s.space();
|
||||
s.word_space("=");
|
||||
s.print_type(default)
|
||||
}
|
||||
}
|
||||
ast::GenericParamKind::Const { ref ty, kw_span: _, ref default } => {
|
||||
ast::GenericParamKind::Const { ty, default, .. } => {
|
||||
s.word_space("const");
|
||||
s.print_ident(param.ident);
|
||||
s.space();
|
||||
@ -1632,7 +1634,7 @@ impl<'a> State<'a> {
|
||||
s.word_nbsp(":");
|
||||
s.print_type_bounds(¶m.bounds);
|
||||
}
|
||||
if let Some(ref default) = default {
|
||||
if let Some(default) = default {
|
||||
s.space();
|
||||
s.word_space("=");
|
||||
s.print_expr(&default.value);
|
||||
@ -1714,9 +1716,9 @@ impl<'a> State<'a> {
|
||||
where_clause: ast::WhereClause {
|
||||
has_where_token: false,
|
||||
predicates: Vec::new(),
|
||||
span: rustc_span::DUMMY_SP,
|
||||
span: DUMMY_SP,
|
||||
},
|
||||
span: rustc_span::DUMMY_SP,
|
||||
span: DUMMY_SP,
|
||||
};
|
||||
let header = ast::FnHeader { unsafety, ext, ..ast::FnHeader::default() };
|
||||
self.print_fn(decl, header, name, &generics);
|
||||
@ -1735,7 +1737,7 @@ impl<'a> State<'a> {
|
||||
}
|
||||
ast::Extern::Explicit(abi, _) => {
|
||||
self.word_nbsp("extern");
|
||||
self.print_literal(&abi.as_lit());
|
||||
self.print_token_literal(abi.as_token_lit(), abi.span);
|
||||
self.nbsp();
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,9 +8,9 @@ use rustc_ast::{self as ast, BlockCheckMode};
|
||||
impl<'a> State<'a> {
|
||||
fn print_else(&mut self, els: Option<&ast::Expr>) {
|
||||
if let Some(_else) = els {
|
||||
match _else.kind {
|
||||
match &_else.kind {
|
||||
// Another `else if` block.
|
||||
ast::ExprKind::If(ref i, ref then, ref e) => {
|
||||
ast::ExprKind::If(i, then, e) => {
|
||||
self.cbox(INDENT_UNIT - 1);
|
||||
self.ibox(0);
|
||||
self.word(" else if ");
|
||||
@ -20,7 +20,7 @@ impl<'a> State<'a> {
|
||||
self.print_else(e.as_deref())
|
||||
}
|
||||
// Final `else` block.
|
||||
ast::ExprKind::Block(ref b, _) => {
|
||||
ast::ExprKind::Block(b, _) => {
|
||||
self.cbox(INDENT_UNIT - 1);
|
||||
self.ibox(0);
|
||||
self.word(" else ");
|
||||
@ -58,10 +58,10 @@ impl<'a> State<'a> {
|
||||
self.print_expr_cond_paren(expr, Self::cond_needs_par(expr))
|
||||
}
|
||||
|
||||
// Does `expr` need parentheses when printed in a condition position?
|
||||
//
|
||||
// These cases need parens due to the parse error observed in #26461: `if return {}`
|
||||
// parses as the erroneous construct `if (return {})`, not `if (return) {}`.
|
||||
/// Does `expr` need parentheses when printed in a condition position?
|
||||
///
|
||||
/// These cases need parens due to the parse error observed in #26461: `if return {}`
|
||||
/// parses as the erroneous construct `if (return {})`, not `if (return) {}`.
|
||||
pub(super) fn cond_needs_par(expr: &ast::Expr) -> bool {
|
||||
match expr.kind {
|
||||
ast::ExprKind::Break(..)
|
||||
@ -121,7 +121,7 @@ impl<'a> State<'a> {
|
||||
|
||||
fn print_expr_struct(
|
||||
&mut self,
|
||||
qself: &Option<ast::QSelf>,
|
||||
qself: &Option<P<ast::QSelf>>,
|
||||
path: &ast::Path,
|
||||
fields: &[ast::ExprField],
|
||||
rest: &ast::StructRest,
|
||||
@ -202,7 +202,7 @@ impl<'a> State<'a> {
|
||||
self.print_expr_maybe_paren(receiver, parser::PREC_POSTFIX);
|
||||
self.word(".");
|
||||
self.print_ident(segment.ident);
|
||||
if let Some(ref args) = segment.args {
|
||||
if let Some(args) = &segment.args {
|
||||
self.print_generic_args(args, true);
|
||||
}
|
||||
self.print_call_post(base_args)
|
||||
@ -284,64 +284,66 @@ impl<'a> State<'a> {
|
||||
|
||||
self.ibox(INDENT_UNIT);
|
||||
self.ann.pre(self, AnnNode::Expr(expr));
|
||||
match expr.kind {
|
||||
ast::ExprKind::Box(ref expr) => {
|
||||
match &expr.kind {
|
||||
ast::ExprKind::Box(expr) => {
|
||||
self.word_space("box");
|
||||
self.print_expr_maybe_paren(expr, parser::PREC_PREFIX);
|
||||
}
|
||||
ast::ExprKind::Array(ref exprs) => {
|
||||
ast::ExprKind::Array(exprs) => {
|
||||
self.print_expr_vec(exprs);
|
||||
}
|
||||
ast::ExprKind::ConstBlock(ref anon_const) => {
|
||||
ast::ExprKind::ConstBlock(anon_const) => {
|
||||
self.print_expr_anon_const(anon_const, attrs);
|
||||
}
|
||||
ast::ExprKind::Repeat(ref element, ref count) => {
|
||||
ast::ExprKind::Repeat(element, count) => {
|
||||
self.print_expr_repeat(element, count);
|
||||
}
|
||||
ast::ExprKind::Struct(ref se) => {
|
||||
ast::ExprKind::Struct(se) => {
|
||||
self.print_expr_struct(&se.qself, &se.path, &se.fields, &se.rest);
|
||||
}
|
||||
ast::ExprKind::Tup(ref exprs) => {
|
||||
ast::ExprKind::Tup(exprs) => {
|
||||
self.print_expr_tup(exprs);
|
||||
}
|
||||
ast::ExprKind::Call(ref func, ref args) => {
|
||||
self.print_expr_call(func, &args);
|
||||
ast::ExprKind::Call(func, args) => {
|
||||
self.print_expr_call(func, args);
|
||||
}
|
||||
ast::ExprKind::MethodCall(ref segment, ref receiver, ref args, _) => {
|
||||
self.print_expr_method_call(segment, &receiver, &args);
|
||||
ast::ExprKind::MethodCall(box ast::MethodCall { seg, receiver, args, .. }) => {
|
||||
self.print_expr_method_call(seg, receiver, args);
|
||||
}
|
||||
ast::ExprKind::Binary(op, ref lhs, ref rhs) => {
|
||||
self.print_expr_binary(op, lhs, rhs);
|
||||
ast::ExprKind::Binary(op, lhs, rhs) => {
|
||||
self.print_expr_binary(*op, lhs, rhs);
|
||||
}
|
||||
ast::ExprKind::Unary(op, ref expr) => {
|
||||
self.print_expr_unary(op, expr);
|
||||
ast::ExprKind::Unary(op, expr) => {
|
||||
self.print_expr_unary(*op, expr);
|
||||
}
|
||||
ast::ExprKind::AddrOf(k, m, ref expr) => {
|
||||
self.print_expr_addr_of(k, m, expr);
|
||||
ast::ExprKind::AddrOf(k, m, expr) => {
|
||||
self.print_expr_addr_of(*k, *m, expr);
|
||||
}
|
||||
ast::ExprKind::Lit(ref lit) => {
|
||||
self.print_literal(lit);
|
||||
ast::ExprKind::Lit(token_lit) => {
|
||||
self.print_token_literal(*token_lit, expr.span);
|
||||
}
|
||||
ast::ExprKind::Cast(ref expr, ref ty) => {
|
||||
ast::ExprKind::IncludedBytes(bytes) => {
|
||||
let lit = ast::LitKind::ByteStr(bytes.clone()).to_token_lit();
|
||||
self.print_token_literal(lit, expr.span)
|
||||
}
|
||||
ast::ExprKind::Cast(expr, ty) => {
|
||||
let prec = AssocOp::As.precedence() as i8;
|
||||
self.print_expr_maybe_paren(expr, prec);
|
||||
self.space();
|
||||
self.word_space("as");
|
||||
self.print_type(ty);
|
||||
}
|
||||
ast::ExprKind::Type(ref expr, ref ty) => {
|
||||
ast::ExprKind::Type(expr, ty) => {
|
||||
let prec = AssocOp::Colon.precedence() as i8;
|
||||
self.print_expr_maybe_paren(expr, prec);
|
||||
self.word_space(":");
|
||||
self.print_type(ty);
|
||||
}
|
||||
ast::ExprKind::Let(ref pat, ref scrutinee, _) => {
|
||||
ast::ExprKind::Let(pat, scrutinee, _) => {
|
||||
self.print_let(pat, scrutinee);
|
||||
}
|
||||
ast::ExprKind::If(ref test, ref blk, ref elseopt) => {
|
||||
self.print_if(test, blk, elseopt.as_deref())
|
||||
}
|
||||
ast::ExprKind::While(ref test, ref blk, opt_label) => {
|
||||
ast::ExprKind::If(test, blk, elseopt) => self.print_if(test, blk, elseopt.as_deref()),
|
||||
ast::ExprKind::While(test, blk, opt_label) => {
|
||||
if let Some(label) = opt_label {
|
||||
self.print_ident(label.ident);
|
||||
self.word_space(":");
|
||||
@ -353,7 +355,7 @@ impl<'a> State<'a> {
|
||||
self.space();
|
||||
self.print_block_with_attrs(blk, attrs);
|
||||
}
|
||||
ast::ExprKind::ForLoop(ref pat, ref iter, ref blk, opt_label) => {
|
||||
ast::ExprKind::ForLoop(pat, iter, blk, opt_label) => {
|
||||
if let Some(label) = opt_label {
|
||||
self.print_ident(label.ident);
|
||||
self.word_space(":");
|
||||
@ -368,7 +370,7 @@ impl<'a> State<'a> {
|
||||
self.space();
|
||||
self.print_block_with_attrs(blk, attrs);
|
||||
}
|
||||
ast::ExprKind::Loop(ref blk, opt_label) => {
|
||||
ast::ExprKind::Loop(blk, opt_label, _) => {
|
||||
if let Some(label) = opt_label {
|
||||
self.print_ident(label.ident);
|
||||
self.word_space(":");
|
||||
@ -378,7 +380,7 @@ impl<'a> State<'a> {
|
||||
self.word_nbsp("loop");
|
||||
self.print_block_with_attrs(blk, attrs);
|
||||
}
|
||||
ast::ExprKind::Match(ref expr, ref arms) => {
|
||||
ast::ExprKind::Match(expr, arms) => {
|
||||
self.cbox(0);
|
||||
self.ibox(0);
|
||||
self.word_nbsp("match");
|
||||
@ -392,21 +394,22 @@ impl<'a> State<'a> {
|
||||
let empty = attrs.is_empty() && arms.is_empty();
|
||||
self.bclose(expr.span, empty);
|
||||
}
|
||||
ast::ExprKind::Closure(
|
||||
ref binder,
|
||||
ast::ExprKind::Closure(box ast::Closure {
|
||||
binder,
|
||||
capture_clause,
|
||||
asyncness,
|
||||
movability,
|
||||
ref decl,
|
||||
ref body,
|
||||
_,
|
||||
) => {
|
||||
fn_decl,
|
||||
body,
|
||||
fn_decl_span: _,
|
||||
fn_arg_span: _,
|
||||
}) => {
|
||||
self.print_closure_binder(binder);
|
||||
self.print_movability(movability);
|
||||
self.print_asyncness(asyncness);
|
||||
self.print_capture_clause(capture_clause);
|
||||
self.print_movability(*movability);
|
||||
self.print_asyncness(*asyncness);
|
||||
self.print_capture_clause(*capture_clause);
|
||||
|
||||
self.print_fn_params_and_ret(decl, true);
|
||||
self.print_fn_params_and_ret(fn_decl, true);
|
||||
self.space();
|
||||
self.print_expr(body);
|
||||
self.end(); // need to close a box
|
||||
@ -416,7 +419,7 @@ impl<'a> State<'a> {
|
||||
// empty box to satisfy the close.
|
||||
self.ibox(0);
|
||||
}
|
||||
ast::ExprKind::Block(ref blk, opt_label) => {
|
||||
ast::ExprKind::Block(blk, opt_label) => {
|
||||
if let Some(label) = opt_label {
|
||||
self.print_ident(label.ident);
|
||||
self.word_space(":");
|
||||
@ -427,26 +430,26 @@ impl<'a> State<'a> {
|
||||
self.ibox(0);
|
||||
self.print_block_with_attrs(blk, attrs);
|
||||
}
|
||||
ast::ExprKind::Async(capture_clause, _, ref blk) => {
|
||||
ast::ExprKind::Async(capture_clause, _, blk) => {
|
||||
self.word_nbsp("async");
|
||||
self.print_capture_clause(capture_clause);
|
||||
self.print_capture_clause(*capture_clause);
|
||||
// cbox/ibox in analogy to the `ExprKind::Block` arm above
|
||||
self.cbox(0);
|
||||
self.ibox(0);
|
||||
self.print_block_with_attrs(blk, attrs);
|
||||
}
|
||||
ast::ExprKind::Await(ref expr) => {
|
||||
ast::ExprKind::Await(expr) => {
|
||||
self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX);
|
||||
self.word(".await");
|
||||
}
|
||||
ast::ExprKind::Assign(ref lhs, ref rhs, _) => {
|
||||
ast::ExprKind::Assign(lhs, rhs, _) => {
|
||||
let prec = AssocOp::Assign.precedence() as i8;
|
||||
self.print_expr_maybe_paren(lhs, prec + 1);
|
||||
self.space();
|
||||
self.word_space("=");
|
||||
self.print_expr_maybe_paren(rhs, prec);
|
||||
}
|
||||
ast::ExprKind::AssignOp(op, ref lhs, ref rhs) => {
|
||||
ast::ExprKind::AssignOp(op, lhs, rhs) => {
|
||||
let prec = AssocOp::Assign.precedence() as i8;
|
||||
self.print_expr_maybe_paren(lhs, prec + 1);
|
||||
self.space();
|
||||
@ -454,45 +457,44 @@ impl<'a> State<'a> {
|
||||
self.word_space("=");
|
||||
self.print_expr_maybe_paren(rhs, prec);
|
||||
}
|
||||
ast::ExprKind::Field(ref expr, ident) => {
|
||||
ast::ExprKind::Field(expr, ident) => {
|
||||
self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX);
|
||||
self.word(".");
|
||||
self.print_ident(ident);
|
||||
self.print_ident(*ident);
|
||||
}
|
||||
ast::ExprKind::Index(ref expr, ref index) => {
|
||||
ast::ExprKind::Index(expr, index) => {
|
||||
self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX);
|
||||
self.word("[");
|
||||
self.print_expr(index);
|
||||
self.word("]");
|
||||
}
|
||||
ast::ExprKind::Range(ref start, ref end, limits) => {
|
||||
ast::ExprKind::Range(start, end, limits) => {
|
||||
// Special case for `Range`. `AssocOp` claims that `Range` has higher precedence
|
||||
// than `Assign`, but `x .. x = x` gives a parse error instead of `x .. (x = x)`.
|
||||
// Here we use a fake precedence value so that any child with lower precedence than
|
||||
// a "normal" binop gets parenthesized. (`LOr` is the lowest-precedence binop.)
|
||||
let fake_prec = AssocOp::LOr.precedence() as i8;
|
||||
if let Some(ref e) = *start {
|
||||
if let Some(e) = start {
|
||||
self.print_expr_maybe_paren(e, fake_prec);
|
||||
}
|
||||
if limits == ast::RangeLimits::HalfOpen {
|
||||
self.word("..");
|
||||
} else {
|
||||
self.word("..=");
|
||||
match limits {
|
||||
ast::RangeLimits::HalfOpen => self.word(".."),
|
||||
ast::RangeLimits::Closed => self.word("..="),
|
||||
}
|
||||
if let Some(ref e) = *end {
|
||||
if let Some(e) = end {
|
||||
self.print_expr_maybe_paren(e, fake_prec);
|
||||
}
|
||||
}
|
||||
ast::ExprKind::Underscore => self.word("_"),
|
||||
ast::ExprKind::Path(None, ref path) => self.print_path(path, true, 0),
|
||||
ast::ExprKind::Path(Some(ref qself), ref path) => self.print_qpath(path, qself, true),
|
||||
ast::ExprKind::Break(opt_label, ref opt_expr) => {
|
||||
ast::ExprKind::Path(None, path) => self.print_path(path, true, 0),
|
||||
ast::ExprKind::Path(Some(qself), path) => self.print_qpath(path, qself, true),
|
||||
ast::ExprKind::Break(opt_label, opt_expr) => {
|
||||
self.word("break");
|
||||
if let Some(label) = opt_label {
|
||||
self.space();
|
||||
self.print_ident(label.ident);
|
||||
}
|
||||
if let Some(ref expr) = *opt_expr {
|
||||
if let Some(expr) = opt_expr {
|
||||
self.space();
|
||||
self.print_expr_maybe_paren(expr, parser::PREC_JUMP);
|
||||
}
|
||||
@ -504,45 +506,45 @@ impl<'a> State<'a> {
|
||||
self.print_ident(label.ident);
|
||||
}
|
||||
}
|
||||
ast::ExprKind::Ret(ref result) => {
|
||||
ast::ExprKind::Ret(result) => {
|
||||
self.word("return");
|
||||
if let Some(ref expr) = *result {
|
||||
if let Some(expr) = result {
|
||||
self.word(" ");
|
||||
self.print_expr_maybe_paren(expr, parser::PREC_JUMP);
|
||||
}
|
||||
}
|
||||
ast::ExprKind::Yeet(ref result) => {
|
||||
ast::ExprKind::Yeet(result) => {
|
||||
self.word("do");
|
||||
self.word(" ");
|
||||
self.word("yeet");
|
||||
if let Some(ref expr) = *result {
|
||||
if let Some(expr) = result {
|
||||
self.word(" ");
|
||||
self.print_expr_maybe_paren(expr, parser::PREC_JUMP);
|
||||
}
|
||||
}
|
||||
ast::ExprKind::InlineAsm(ref a) => {
|
||||
ast::ExprKind::InlineAsm(a) => {
|
||||
self.word("asm!");
|
||||
self.print_inline_asm(a);
|
||||
}
|
||||
ast::ExprKind::MacCall(ref m) => self.print_mac(m),
|
||||
ast::ExprKind::Paren(ref e) => {
|
||||
ast::ExprKind::MacCall(m) => self.print_mac(m),
|
||||
ast::ExprKind::Paren(e) => {
|
||||
self.popen();
|
||||
self.print_expr(e);
|
||||
self.pclose();
|
||||
}
|
||||
ast::ExprKind::Yield(ref e) => {
|
||||
ast::ExprKind::Yield(e) => {
|
||||
self.word("yield");
|
||||
|
||||
if let Some(ref expr) = *e {
|
||||
if let Some(expr) = e {
|
||||
self.space();
|
||||
self.print_expr_maybe_paren(expr, parser::PREC_JUMP);
|
||||
}
|
||||
}
|
||||
ast::ExprKind::Try(ref e) => {
|
||||
ast::ExprKind::Try(e) => {
|
||||
self.print_expr_maybe_paren(e, parser::PREC_POSTFIX);
|
||||
self.word("?")
|
||||
}
|
||||
ast::ExprKind::TryBlock(ref blk) => {
|
||||
ast::ExprKind::TryBlock(blk) => {
|
||||
self.cbox(0);
|
||||
self.ibox(0);
|
||||
self.word_nbsp("try");
|
||||
@ -569,15 +571,15 @@ impl<'a> State<'a> {
|
||||
self.print_outer_attributes(&arm.attrs);
|
||||
self.print_pat(&arm.pat);
|
||||
self.space();
|
||||
if let Some(ref e) = arm.guard {
|
||||
if let Some(e) = &arm.guard {
|
||||
self.word_space("if");
|
||||
self.print_expr(e);
|
||||
self.space();
|
||||
}
|
||||
self.word_space("=>");
|
||||
|
||||
match arm.body.kind {
|
||||
ast::ExprKind::Block(ref blk, opt_label) => {
|
||||
match &arm.body.kind {
|
||||
ast::ExprKind::Block(blk, opt_label) => {
|
||||
if let Some(label) = opt_label {
|
||||
self.print_ident(label.ident);
|
||||
self.word_space(":");
|
||||
@ -604,7 +606,7 @@ impl<'a> State<'a> {
|
||||
match binder {
|
||||
ast::ClosureBinder::NotPresent => {}
|
||||
ast::ClosureBinder::For { generic_params, .. } => {
|
||||
self.print_formal_generic_params(&generic_params)
|
||||
self.print_formal_generic_params(generic_params)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -136,10 +136,10 @@ impl<'a> State<'a> {
|
||||
self.maybe_print_comment(item.span.lo());
|
||||
self.print_outer_attributes(&item.attrs);
|
||||
self.ann.pre(self, AnnNode::Item(item));
|
||||
match item.kind {
|
||||
match &item.kind {
|
||||
ast::ItemKind::ExternCrate(orig_name) => {
|
||||
self.head(visibility_qualified(&item.vis, "extern crate"));
|
||||
if let Some(orig_name) = orig_name {
|
||||
if let &Some(orig_name) = orig_name {
|
||||
self.print_name(orig_name);
|
||||
self.space();
|
||||
self.word("as");
|
||||
@ -150,35 +150,41 @@ impl<'a> State<'a> {
|
||||
self.end(); // end inner head-block
|
||||
self.end(); // end outer head-block
|
||||
}
|
||||
ast::ItemKind::Use(ref tree) => {
|
||||
ast::ItemKind::Use(tree) => {
|
||||
self.print_visibility(&item.vis);
|
||||
self.word_nbsp("use");
|
||||
self.print_use_tree(tree);
|
||||
self.word(";");
|
||||
}
|
||||
ast::ItemKind::Static(ref ty, mutbl, ref body) => {
|
||||
ast::ItemKind::Static(ty, mutbl, body) => {
|
||||
let def = ast::Defaultness::Final;
|
||||
self.print_item_const(item.ident, Some(mutbl), ty, body.as_deref(), &item.vis, def);
|
||||
self.print_item_const(
|
||||
item.ident,
|
||||
Some(*mutbl),
|
||||
ty,
|
||||
body.as_deref(),
|
||||
&item.vis,
|
||||
def,
|
||||
);
|
||||
}
|
||||
ast::ItemKind::Const(def, ref ty, ref body) => {
|
||||
self.print_item_const(item.ident, None, ty, body.as_deref(), &item.vis, def);
|
||||
ast::ItemKind::Const(def, ty, body) => {
|
||||
self.print_item_const(item.ident, None, ty, body.as_deref(), &item.vis, *def);
|
||||
}
|
||||
ast::ItemKind::Fn(box ast::Fn { defaultness, ref sig, ref generics, ref body }) => {
|
||||
let body = body.as_deref();
|
||||
ast::ItemKind::Fn(box ast::Fn { defaultness, sig, generics, body }) => {
|
||||
self.print_fn_full(
|
||||
sig,
|
||||
item.ident,
|
||||
generics,
|
||||
&item.vis,
|
||||
defaultness,
|
||||
body,
|
||||
*defaultness,
|
||||
body.as_deref(),
|
||||
&item.attrs,
|
||||
);
|
||||
}
|
||||
ast::ItemKind::Mod(unsafety, ref mod_kind) => {
|
||||
ast::ItemKind::Mod(unsafety, mod_kind) => {
|
||||
self.head(Self::to_string(|s| {
|
||||
s.print_visibility(&item.vis);
|
||||
s.print_unsafety(unsafety);
|
||||
s.print_unsafety(*unsafety);
|
||||
s.word("mod");
|
||||
}));
|
||||
self.print_ident(item.ident);
|
||||
@ -201,13 +207,13 @@ impl<'a> State<'a> {
|
||||
}
|
||||
}
|
||||
}
|
||||
ast::ItemKind::ForeignMod(ref nmod) => {
|
||||
ast::ItemKind::ForeignMod(nmod) => {
|
||||
self.head(Self::to_string(|s| {
|
||||
s.print_unsafety(nmod.unsafety);
|
||||
s.word("extern");
|
||||
}));
|
||||
if let Some(abi) = nmod.abi {
|
||||
self.print_literal(&abi.as_lit());
|
||||
self.print_token_literal(abi.as_token_lit(), abi.span);
|
||||
self.nbsp();
|
||||
}
|
||||
self.bopen();
|
||||
@ -215,7 +221,7 @@ impl<'a> State<'a> {
|
||||
let empty = item.attrs.is_empty() && nmod.items.is_empty();
|
||||
self.bclose(item.span, empty);
|
||||
}
|
||||
ast::ItemKind::GlobalAsm(ref asm) => {
|
||||
ast::ItemKind::GlobalAsm(asm) => {
|
||||
self.head(visibility_qualified(&item.vis, "global_asm!"));
|
||||
self.print_inline_asm(asm);
|
||||
self.word(";");
|
||||
@ -224,32 +230,31 @@ impl<'a> State<'a> {
|
||||
}
|
||||
ast::ItemKind::TyAlias(box ast::TyAlias {
|
||||
defaultness,
|
||||
ref generics,
|
||||
generics,
|
||||
where_clauses,
|
||||
where_predicates_split,
|
||||
ref bounds,
|
||||
ref ty,
|
||||
bounds,
|
||||
ty,
|
||||
}) => {
|
||||
let ty = ty.as_deref();
|
||||
self.print_associated_type(
|
||||
item.ident,
|
||||
generics,
|
||||
where_clauses,
|
||||
where_predicates_split,
|
||||
*where_clauses,
|
||||
*where_predicates_split,
|
||||
bounds,
|
||||
ty,
|
||||
ty.as_deref(),
|
||||
&item.vis,
|
||||
defaultness,
|
||||
*defaultness,
|
||||
);
|
||||
}
|
||||
ast::ItemKind::Enum(ref enum_definition, ref params) => {
|
||||
ast::ItemKind::Enum(enum_definition, params) => {
|
||||
self.print_enum_def(enum_definition, params, item.ident, item.span, &item.vis);
|
||||
}
|
||||
ast::ItemKind::Struct(ref struct_def, ref generics) => {
|
||||
ast::ItemKind::Struct(struct_def, generics) => {
|
||||
self.head(visibility_qualified(&item.vis, "struct"));
|
||||
self.print_struct(struct_def, generics, item.ident, item.span, true);
|
||||
}
|
||||
ast::ItemKind::Union(ref struct_def, ref generics) => {
|
||||
ast::ItemKind::Union(struct_def, generics) => {
|
||||
self.head(visibility_qualified(&item.vis, "union"));
|
||||
self.print_struct(struct_def, generics, item.ident, item.span, true);
|
||||
}
|
||||
@ -258,15 +263,15 @@ impl<'a> State<'a> {
|
||||
polarity,
|
||||
defaultness,
|
||||
constness,
|
||||
ref generics,
|
||||
ref of_trait,
|
||||
ref self_ty,
|
||||
ref items,
|
||||
generics,
|
||||
of_trait,
|
||||
self_ty,
|
||||
items,
|
||||
}) => {
|
||||
self.head("");
|
||||
self.print_visibility(&item.vis);
|
||||
self.print_defaultness(defaultness);
|
||||
self.print_unsafety(unsafety);
|
||||
self.print_defaultness(*defaultness);
|
||||
self.print_unsafety(*unsafety);
|
||||
self.word("impl");
|
||||
|
||||
if generics.params.is_empty() {
|
||||
@ -276,13 +281,13 @@ impl<'a> State<'a> {
|
||||
self.space();
|
||||
}
|
||||
|
||||
self.print_constness(constness);
|
||||
self.print_constness(*constness);
|
||||
|
||||
if let ast::ImplPolarity::Negative(_) = polarity {
|
||||
self.word("!");
|
||||
}
|
||||
|
||||
if let Some(ref t) = *of_trait {
|
||||
if let Some(t) = of_trait {
|
||||
self.print_trait_ref(t);
|
||||
self.space();
|
||||
self.word_space("for");
|
||||
@ -303,21 +308,21 @@ impl<'a> State<'a> {
|
||||
ast::ItemKind::Trait(box ast::Trait {
|
||||
is_auto,
|
||||
unsafety,
|
||||
ref generics,
|
||||
ref bounds,
|
||||
ref items,
|
||||
generics,
|
||||
bounds,
|
||||
items,
|
||||
..
|
||||
}) => {
|
||||
self.head("");
|
||||
self.print_visibility(&item.vis);
|
||||
self.print_unsafety(unsafety);
|
||||
self.print_is_auto(is_auto);
|
||||
self.print_unsafety(*unsafety);
|
||||
self.print_is_auto(*is_auto);
|
||||
self.word_nbsp("trait");
|
||||
self.print_ident(item.ident);
|
||||
self.print_generic_params(&generics.params);
|
||||
let mut real_bounds = Vec::with_capacity(bounds.len());
|
||||
for b in bounds.iter() {
|
||||
if let GenericBound::Trait(ref ptr, ast::TraitBoundModifier::Maybe) = *b {
|
||||
if let GenericBound::Trait(ptr, ast::TraitBoundModifier::Maybe) = b {
|
||||
self.space();
|
||||
self.word_space("for ?");
|
||||
self.print_trait_ref(&ptr.trait_ref);
|
||||
@ -339,38 +344,27 @@ impl<'a> State<'a> {
|
||||
let empty = item.attrs.is_empty() && items.is_empty();
|
||||
self.bclose(item.span, empty);
|
||||
}
|
||||
ast::ItemKind::TraitAlias(ref generics, ref bounds) => {
|
||||
ast::ItemKind::TraitAlias(generics, bounds) => {
|
||||
self.head(visibility_qualified(&item.vis, "trait"));
|
||||
self.print_ident(item.ident);
|
||||
self.print_generic_params(&generics.params);
|
||||
let mut real_bounds = Vec::with_capacity(bounds.len());
|
||||
// FIXME(durka) this seems to be some quite outdated syntax
|
||||
for b in bounds.iter() {
|
||||
if let GenericBound::Trait(ref ptr, ast::TraitBoundModifier::Maybe) = *b {
|
||||
self.space();
|
||||
self.word_space("for ?");
|
||||
self.print_trait_ref(&ptr.trait_ref);
|
||||
} else {
|
||||
real_bounds.push(b.clone());
|
||||
}
|
||||
}
|
||||
self.nbsp();
|
||||
if !real_bounds.is_empty() {
|
||||
if !bounds.is_empty() {
|
||||
self.word_nbsp("=");
|
||||
self.print_type_bounds(&real_bounds);
|
||||
self.print_type_bounds(&bounds);
|
||||
}
|
||||
self.print_where_clause(&generics.where_clause);
|
||||
self.word(";");
|
||||
self.end(); // end inner head-block
|
||||
self.end(); // end outer head-block
|
||||
}
|
||||
ast::ItemKind::MacCall(ref mac) => {
|
||||
ast::ItemKind::MacCall(mac) => {
|
||||
self.print_mac(mac);
|
||||
if mac.args.need_semicolon() {
|
||||
self.word(";");
|
||||
}
|
||||
}
|
||||
ast::ItemKind::MacroDef(ref macro_def) => {
|
||||
ast::ItemKind::MacroDef(macro_def) => {
|
||||
self.print_mac_def(macro_def, &item.ident, item.span, |state| {
|
||||
state.print_visibility(&item.vis)
|
||||
});
|
||||
@ -412,11 +406,11 @@ impl<'a> State<'a> {
|
||||
}
|
||||
|
||||
pub(crate) fn print_visibility(&mut self, vis: &ast::Visibility) {
|
||||
match vis.kind {
|
||||
match &vis.kind {
|
||||
ast::VisibilityKind::Public => self.word_nbsp("pub"),
|
||||
ast::VisibilityKind::Restricted { ref path, id: _, shorthand } => {
|
||||
ast::VisibilityKind::Restricted { path, shorthand, .. } => {
|
||||
let path = Self::to_string(|s| s.print_path(path, false, 0));
|
||||
if shorthand && (path == "crate" || path == "self" || path == "super") {
|
||||
if *shorthand && (path == "crate" || path == "self" || path == "super") {
|
||||
self.word_nbsp(format!("pub({})", path))
|
||||
} else {
|
||||
self.word_nbsp(format!("pub(in {})", path))
|
||||
@ -465,7 +459,7 @@ impl<'a> State<'a> {
|
||||
) {
|
||||
self.print_ident(ident);
|
||||
self.print_generic_params(&generics.params);
|
||||
match struct_def {
|
||||
match &struct_def {
|
||||
ast::VariantData::Tuple(..) | ast::VariantData::Unit(..) => {
|
||||
if let ast::VariantData::Tuple(..) = struct_def {
|
||||
self.popen();
|
||||
@ -484,7 +478,7 @@ impl<'a> State<'a> {
|
||||
self.end();
|
||||
self.end(); // Close the outer-box.
|
||||
}
|
||||
ast::VariantData::Struct(ref fields, ..) => {
|
||||
ast::VariantData::Struct(fields, ..) => {
|
||||
self.print_where_clause(&generics.where_clause);
|
||||
self.print_record_struct_body(fields, span);
|
||||
}
|
||||
@ -496,7 +490,7 @@ impl<'a> State<'a> {
|
||||
self.print_visibility(&v.vis);
|
||||
let generics = ast::Generics::default();
|
||||
self.print_struct(&v.data, &generics, v.ident, v.span, false);
|
||||
if let Some(ref d) = v.disr_expr {
|
||||
if let Some(d) = &v.disr_expr {
|
||||
self.space();
|
||||
self.word_space("=");
|
||||
self.print_expr(&d.value)
|
||||
@ -657,10 +651,10 @@ impl<'a> State<'a> {
|
||||
}
|
||||
|
||||
fn print_use_tree(&mut self, tree: &ast::UseTree) {
|
||||
match tree.kind {
|
||||
ast::UseTreeKind::Simple(rename, ..) => {
|
||||
match &tree.kind {
|
||||
ast::UseTreeKind::Simple(rename) => {
|
||||
self.print_path(&tree.prefix, false, 0);
|
||||
if let Some(rename) = rename {
|
||||
if let &Some(rename) = rename {
|
||||
self.nbsp();
|
||||
self.word_nbsp("as");
|
||||
self.print_ident(rename);
|
||||
@ -673,7 +667,7 @@ impl<'a> State<'a> {
|
||||
}
|
||||
self.word("*");
|
||||
}
|
||||
ast::UseTreeKind::Nested(ref items) => {
|
||||
ast::UseTreeKind::Nested(items) => {
|
||||
if !tree.prefix.segments.is_empty() {
|
||||
self.print_path(&tree.prefix, false, 0);
|
||||
self.word("::");
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
//! Parsing and validation of builtin attributes
|
||||
|
||||
use rustc_ast as ast;
|
||||
use rustc_ast::{Attribute, Lit, LitKind, MetaItem, MetaItemKind, NestedMetaItem, NodeId};
|
||||
use rustc_ast::{Attribute, LitKind, MetaItem, MetaItemKind, MetaItemLit, NestedMetaItem, NodeId};
|
||||
use rustc_ast_pretty::pprust;
|
||||
use rustc_feature::{find_gated_cfg, is_builtin_attr_name, Features, GatedCfg};
|
||||
use rustc_macros::HashStable_Generic;
|
||||
@ -277,8 +277,7 @@ where
|
||||
allowed_through_unstable_modules = true;
|
||||
}
|
||||
// attributes with data
|
||||
else if let Some(MetaItem { kind: MetaItemKind::List(ref metas), .. }) = meta {
|
||||
let meta = meta.as_ref().unwrap();
|
||||
else if let Some(meta @ MetaItem { kind: MetaItemKind::List(metas), .. }) = &meta {
|
||||
let get = |meta: &MetaItem, item: &mut Option<Symbol>| {
|
||||
if item.is_some() {
|
||||
handle_errors(
|
||||
@ -486,7 +485,7 @@ where
|
||||
continue 'outer;
|
||||
}
|
||||
},
|
||||
NestedMetaItem::Literal(lit) => {
|
||||
NestedMetaItem::Lit(lit) => {
|
||||
handle_errors(
|
||||
&sess.parse_sess,
|
||||
lit.span,
|
||||
@ -533,25 +532,24 @@ where
|
||||
|
||||
// Merge the const-unstable info into the stability info
|
||||
if promotable {
|
||||
if let Some((ref mut stab, _)) = const_stab {
|
||||
stab.promotable = promotable;
|
||||
} else {
|
||||
sess.emit_err(session_diagnostics::RustcPromotablePairing { span: item_sp });
|
||||
match &mut const_stab {
|
||||
Some((stab, _)) => stab.promotable = promotable,
|
||||
_ => _ = sess.emit_err(session_diagnostics::RustcPromotablePairing { span: item_sp }),
|
||||
}
|
||||
}
|
||||
|
||||
if allowed_through_unstable_modules {
|
||||
if let Some((
|
||||
Stability {
|
||||
level: StabilityLevel::Stable { ref mut allowed_through_unstable_modules, .. },
|
||||
..
|
||||
},
|
||||
_,
|
||||
)) = stab
|
||||
{
|
||||
*allowed_through_unstable_modules = true;
|
||||
} else {
|
||||
sess.emit_err(session_diagnostics::RustcAllowedUnstablePairing { span: item_sp });
|
||||
match &mut stab {
|
||||
Some((
|
||||
Stability {
|
||||
level: StabilityLevel::Stable { allowed_through_unstable_modules, .. },
|
||||
..
|
||||
},
|
||||
_,
|
||||
)) => *allowed_through_unstable_modules = true,
|
||||
_ => {
|
||||
sess.emit_err(session_diagnostics::RustcAllowedUnstablePairing { span: item_sp });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -654,15 +652,15 @@ pub fn eval_condition(
|
||||
features: Option<&Features>,
|
||||
eval: &mut impl FnMut(Condition) -> bool,
|
||||
) -> bool {
|
||||
match cfg.kind {
|
||||
ast::MetaItemKind::List(ref mis) if cfg.name_or_empty() == sym::version => {
|
||||
match &cfg.kind {
|
||||
ast::MetaItemKind::List(mis) if cfg.name_or_empty() == sym::version => {
|
||||
try_gate_cfg(sym::version, cfg.span, sess, features);
|
||||
let (min_version, span) = match &mis[..] {
|
||||
[NestedMetaItem::Literal(Lit { kind: LitKind::Str(sym, ..), span, .. })] => {
|
||||
[NestedMetaItem::Lit(MetaItemLit { kind: LitKind::Str(sym, ..), span, .. })] => {
|
||||
(sym, span)
|
||||
}
|
||||
[
|
||||
NestedMetaItem::Literal(Lit { span, .. })
|
||||
NestedMetaItem::Lit(MetaItemLit { span, .. })
|
||||
| NestedMetaItem::MetaItem(MetaItem { span, .. }),
|
||||
] => {
|
||||
sess.emit_err(session_diagnostics::ExpectedVersionLiteral { span: *span });
|
||||
@ -688,7 +686,7 @@ pub fn eval_condition(
|
||||
rustc_version >= min_version
|
||||
}
|
||||
}
|
||||
ast::MetaItemKind::List(ref mis) => {
|
||||
ast::MetaItemKind::List(mis) => {
|
||||
for mi in mis.iter() {
|
||||
if !mi.is_meta_item() {
|
||||
handle_errors(
|
||||
@ -759,7 +757,7 @@ pub fn eval_condition(
|
||||
sess.emit_err(session_diagnostics::CfgPredicateIdentifier { span: cfg.path.span });
|
||||
true
|
||||
}
|
||||
MetaItemKind::NameValue(ref lit) if !lit.kind.is_str() => {
|
||||
MetaItemKind::NameValue(lit) if !lit.kind.is_str() => {
|
||||
handle_errors(
|
||||
sess,
|
||||
lit.span,
|
||||
@ -899,7 +897,7 @@ where
|
||||
continue 'outer;
|
||||
}
|
||||
},
|
||||
NestedMetaItem::Literal(lit) => {
|
||||
NestedMetaItem::Lit(lit) => {
|
||||
handle_errors(
|
||||
&sess.parse_sess,
|
||||
lit.span,
|
||||
@ -1036,52 +1034,58 @@ pub fn parse_repr_attr(sess: &Session, attr: &Attribute) -> Vec<ReprAttr> {
|
||||
});
|
||||
}
|
||||
} else if let Some(meta_item) = item.meta_item() {
|
||||
if let MetaItemKind::NameValue(ref value) = meta_item.kind {
|
||||
if meta_item.has_name(sym::align) || meta_item.has_name(sym::packed) {
|
||||
let name = meta_item.name_or_empty().to_ident_string();
|
||||
recognised = true;
|
||||
sess.emit_err(session_diagnostics::IncorrectReprFormatGeneric {
|
||||
span: item.span(),
|
||||
repr_arg: &name,
|
||||
cause: IncorrectReprFormatGenericCause::from_lit_kind(
|
||||
item.span(),
|
||||
&value.kind,
|
||||
&name,
|
||||
),
|
||||
});
|
||||
} else if matches!(
|
||||
meta_item.name_or_empty(),
|
||||
sym::C | sym::simd | sym::transparent
|
||||
) || int_type_of_word(meta_item.name_or_empty()).is_some()
|
||||
{
|
||||
recognised = true;
|
||||
sess.emit_err(session_diagnostics::InvalidReprHintNoValue {
|
||||
span: meta_item.span,
|
||||
name: meta_item.name_or_empty().to_ident_string(),
|
||||
});
|
||||
match &meta_item.kind {
|
||||
MetaItemKind::NameValue(value) => {
|
||||
if meta_item.has_name(sym::align) || meta_item.has_name(sym::packed) {
|
||||
let name = meta_item.name_or_empty().to_ident_string();
|
||||
recognised = true;
|
||||
sess.emit_err(session_diagnostics::IncorrectReprFormatGeneric {
|
||||
span: item.span(),
|
||||
repr_arg: &name,
|
||||
cause: IncorrectReprFormatGenericCause::from_lit_kind(
|
||||
item.span(),
|
||||
&value.kind,
|
||||
&name,
|
||||
),
|
||||
});
|
||||
} else if matches!(
|
||||
meta_item.name_or_empty(),
|
||||
sym::C | sym::simd | sym::transparent
|
||||
) || int_type_of_word(meta_item.name_or_empty()).is_some()
|
||||
{
|
||||
recognised = true;
|
||||
sess.emit_err(session_diagnostics::InvalidReprHintNoValue {
|
||||
span: meta_item.span,
|
||||
name: meta_item.name_or_empty().to_ident_string(),
|
||||
});
|
||||
}
|
||||
}
|
||||
} else if let MetaItemKind::List(_) = meta_item.kind {
|
||||
if meta_item.has_name(sym::align) {
|
||||
recognised = true;
|
||||
sess.emit_err(session_diagnostics::IncorrectReprFormatAlignOneArg {
|
||||
span: meta_item.span,
|
||||
});
|
||||
} else if meta_item.has_name(sym::packed) {
|
||||
recognised = true;
|
||||
sess.emit_err(session_diagnostics::IncorrectReprFormatPackedOneOrZeroArg {
|
||||
span: meta_item.span,
|
||||
});
|
||||
} else if matches!(
|
||||
meta_item.name_or_empty(),
|
||||
sym::C | sym::simd | sym::transparent
|
||||
) || int_type_of_word(meta_item.name_or_empty()).is_some()
|
||||
{
|
||||
recognised = true;
|
||||
sess.emit_err(session_diagnostics::InvalidReprHintNoParen {
|
||||
span: meta_item.span,
|
||||
name: meta_item.name_or_empty().to_ident_string(),
|
||||
});
|
||||
MetaItemKind::List(_) => {
|
||||
if meta_item.has_name(sym::align) {
|
||||
recognised = true;
|
||||
sess.emit_err(session_diagnostics::IncorrectReprFormatAlignOneArg {
|
||||
span: meta_item.span,
|
||||
});
|
||||
} else if meta_item.has_name(sym::packed) {
|
||||
recognised = true;
|
||||
sess.emit_err(
|
||||
session_diagnostics::IncorrectReprFormatPackedOneOrZeroArg {
|
||||
span: meta_item.span,
|
||||
},
|
||||
);
|
||||
} else if matches!(
|
||||
meta_item.name_or_empty(),
|
||||
sym::C | sym::simd | sym::transparent
|
||||
) || int_type_of_word(meta_item.name_or_empty()).is_some()
|
||||
{
|
||||
recognised = true;
|
||||
sess.emit_err(session_diagnostics::InvalidReprHintNoParen {
|
||||
span: meta_item.span,
|
||||
name: meta_item.name_or_empty().to_ident_string(),
|
||||
});
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
if !recognised {
|
||||
|
||||
@ -41,7 +41,7 @@ pub(crate) struct IncorrectMetaItem {
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
// Error code: E0541
|
||||
/// Error code: E0541
|
||||
pub(crate) struct UnknownMetaItem<'a> {
|
||||
pub span: Span,
|
||||
pub item: String,
|
||||
@ -200,7 +200,7 @@ pub(crate) struct InvalidReprHintNoValue {
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
// Error code: E0565
|
||||
/// Error code: E0565
|
||||
pub(crate) struct UnsupportedLiteral {
|
||||
pub span: Span,
|
||||
pub reason: UnsupportedLiteralReason,
|
||||
|
||||
15
compiler/rustc_baked_icu_data/Cargo.toml
Normal file
15
compiler/rustc_baked_icu_data/Cargo.toml
Normal file
@ -0,0 +1,15 @@
|
||||
[package]
|
||||
name = "rustc_baked_icu_data"
|
||||
version = "0.0.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
icu_list = "1.0.0"
|
||||
icu_locid = "1.0.0"
|
||||
icu_provider = "1.0.1"
|
||||
icu_provider_adapters = "1.0.0"
|
||||
litemap = "0.6.0"
|
||||
zerovec = "0.9.0"
|
||||
|
||||
[features]
|
||||
rustc_use_parallel_compiler = ['icu_provider/sync']
|
||||
42
compiler/rustc_baked_icu_data/src/data/any.rs
Normal file
42
compiler/rustc_baked_icu_data/src/data/any.rs
Normal file
@ -0,0 +1,42 @@
|
||||
// @generated
|
||||
impl AnyProvider for BakedDataProvider {
|
||||
fn load_any(&self, key: DataKey, req: DataRequest) -> Result<AnyResponse, DataError> {
|
||||
const ANDLISTV1MARKER: ::icu_provider::DataKeyHash =
|
||||
::icu_list::provider::AndListV1Marker::KEY.hashed();
|
||||
const COLLATIONFALLBACKSUPPLEMENTV1MARKER: ::icu_provider::DataKeyHash =
|
||||
::icu_provider_adapters::fallback::provider::CollationFallbackSupplementV1Marker::KEY
|
||||
.hashed();
|
||||
const LOCALEFALLBACKLIKELYSUBTAGSV1MARKER: ::icu_provider::DataKeyHash =
|
||||
::icu_provider_adapters::fallback::provider::LocaleFallbackLikelySubtagsV1Marker::KEY
|
||||
.hashed();
|
||||
const LOCALEFALLBACKPARENTSV1MARKER: ::icu_provider::DataKeyHash =
|
||||
::icu_provider_adapters::fallback::provider::LocaleFallbackParentsV1Marker::KEY
|
||||
.hashed();
|
||||
#[allow(clippy::match_single_binding)]
|
||||
match key.hashed() {
|
||||
ANDLISTV1MARKER => list::and_v1::DATA
|
||||
.get_by(|k| req.locale.strict_cmp(k.as_bytes()).reverse())
|
||||
.copied()
|
||||
.map(AnyPayload::from_static_ref)
|
||||
.ok_or(DataErrorKind::MissingLocale),
|
||||
COLLATIONFALLBACKSUPPLEMENTV1MARKER => fallback::supplement::co_v1::DATA
|
||||
.get_by(|k| req.locale.strict_cmp(k.as_bytes()).reverse())
|
||||
.copied()
|
||||
.map(AnyPayload::from_static_ref)
|
||||
.ok_or(DataErrorKind::MissingLocale),
|
||||
LOCALEFALLBACKLIKELYSUBTAGSV1MARKER => fallback::likelysubtags_v1::DATA
|
||||
.get_by(|k| req.locale.strict_cmp(k.as_bytes()).reverse())
|
||||
.copied()
|
||||
.map(AnyPayload::from_static_ref)
|
||||
.ok_or(DataErrorKind::MissingLocale),
|
||||
LOCALEFALLBACKPARENTSV1MARKER => fallback::parents_v1::DATA
|
||||
.get_by(|k| req.locale.strict_cmp(k.as_bytes()).reverse())
|
||||
.copied()
|
||||
.map(AnyPayload::from_static_ref)
|
||||
.ok_or(DataErrorKind::MissingLocale),
|
||||
_ => Err(DataErrorKind::MissingDataKey),
|
||||
}
|
||||
.map_err(|e| e.with_req(key, req))
|
||||
.map(|payload| AnyResponse { payload: Some(payload), metadata: Default::default() })
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,733 @@
|
||||
// @generated
|
||||
type DataStruct = < :: icu_provider_adapters :: fallback :: provider :: LocaleFallbackLikelySubtagsV1Marker as :: icu_provider :: DataMarker > :: Yokeable ;
|
||||
pub static DATA: litemap::LiteMap<&str, &DataStruct, &[(&str, &DataStruct)]> =
|
||||
litemap::LiteMap::from_sorted_store_unchecked(&[("und", UND)]);
|
||||
static UND: &DataStruct =
|
||||
&::icu_provider_adapters::fallback::provider::LocaleFallbackLikelySubtagsV1 {
|
||||
l2s: unsafe {
|
||||
#[allow(unused_unsafe)]
|
||||
::zerovec::ZeroMap::from_parts_unchecked(
|
||||
unsafe {
|
||||
::zerovec::ZeroVec::from_bytes_unchecked(&[
|
||||
97u8, 98u8, 0u8, 97u8, 98u8, 113u8, 97u8, 100u8, 112u8, 97u8, 100u8, 121u8,
|
||||
97u8, 101u8, 0u8, 97u8, 101u8, 98u8, 97u8, 104u8, 111u8, 97u8, 106u8,
|
||||
116u8, 97u8, 107u8, 107u8, 97u8, 108u8, 116u8, 97u8, 109u8, 0u8, 97u8,
|
||||
112u8, 99u8, 97u8, 112u8, 100u8, 97u8, 114u8, 0u8, 97u8, 114u8, 99u8, 97u8,
|
||||
114u8, 113u8, 97u8, 114u8, 115u8, 97u8, 114u8, 121u8, 97u8, 114u8, 122u8,
|
||||
97u8, 115u8, 0u8, 97u8, 115u8, 101u8, 97u8, 118u8, 0u8, 97u8, 118u8, 108u8,
|
||||
97u8, 119u8, 97u8, 98u8, 97u8, 0u8, 98u8, 97u8, 108u8, 98u8, 97u8, 112u8,
|
||||
98u8, 97u8, 120u8, 98u8, 99u8, 113u8, 98u8, 101u8, 0u8, 98u8, 101u8, 106u8,
|
||||
98u8, 102u8, 113u8, 98u8, 102u8, 116u8, 98u8, 102u8, 121u8, 98u8, 103u8,
|
||||
0u8, 98u8, 103u8, 99u8, 98u8, 103u8, 110u8, 98u8, 103u8, 120u8, 98u8,
|
||||
104u8, 98u8, 98u8, 104u8, 105u8, 98u8, 104u8, 111u8, 98u8, 106u8, 105u8,
|
||||
98u8, 106u8, 106u8, 98u8, 108u8, 116u8, 98u8, 110u8, 0u8, 98u8, 111u8, 0u8,
|
||||
98u8, 112u8, 121u8, 98u8, 113u8, 105u8, 98u8, 114u8, 97u8, 98u8, 114u8,
|
||||
104u8, 98u8, 114u8, 120u8, 98u8, 115u8, 113u8, 98u8, 115u8, 116u8, 98u8,
|
||||
116u8, 118u8, 98u8, 117u8, 97u8, 98u8, 121u8, 110u8, 99u8, 99u8, 112u8,
|
||||
99u8, 101u8, 0u8, 99u8, 104u8, 109u8, 99u8, 104u8, 114u8, 99u8, 106u8,
|
||||
97u8, 99u8, 106u8, 109u8, 99u8, 107u8, 98u8, 99u8, 109u8, 103u8, 99u8,
|
||||
111u8, 112u8, 99u8, 114u8, 0u8, 99u8, 114u8, 104u8, 99u8, 114u8, 107u8,
|
||||
99u8, 114u8, 108u8, 99u8, 115u8, 119u8, 99u8, 116u8, 100u8, 99u8, 117u8,
|
||||
0u8, 99u8, 118u8, 0u8, 100u8, 97u8, 114u8, 100u8, 99u8, 99u8, 100u8, 103u8,
|
||||
108u8, 100u8, 109u8, 102u8, 100u8, 111u8, 105u8, 100u8, 114u8, 104u8,
|
||||
100u8, 114u8, 115u8, 100u8, 116u8, 121u8, 100u8, 118u8, 0u8, 100u8, 122u8,
|
||||
0u8, 101u8, 103u8, 121u8, 101u8, 107u8, 121u8, 101u8, 108u8, 0u8, 101u8,
|
||||
115u8, 103u8, 101u8, 116u8, 116u8, 102u8, 97u8, 0u8, 102u8, 105u8, 97u8,
|
||||
102u8, 117u8, 98u8, 103u8, 97u8, 110u8, 103u8, 98u8, 109u8, 103u8, 98u8,
|
||||
122u8, 103u8, 101u8, 122u8, 103u8, 103u8, 110u8, 103u8, 106u8, 107u8,
|
||||
103u8, 106u8, 117u8, 103u8, 108u8, 107u8, 103u8, 109u8, 118u8, 103u8,
|
||||
111u8, 102u8, 103u8, 111u8, 109u8, 103u8, 111u8, 110u8, 103u8, 111u8,
|
||||
116u8, 103u8, 114u8, 99u8, 103u8, 114u8, 116u8, 103u8, 117u8, 0u8, 103u8,
|
||||
118u8, 114u8, 103u8, 119u8, 99u8, 103u8, 119u8, 116u8, 104u8, 97u8, 107u8,
|
||||
104u8, 97u8, 122u8, 104u8, 100u8, 121u8, 104u8, 101u8, 0u8, 104u8, 105u8,
|
||||
0u8, 104u8, 108u8, 117u8, 104u8, 109u8, 100u8, 104u8, 110u8, 100u8, 104u8,
|
||||
110u8, 101u8, 104u8, 110u8, 106u8, 104u8, 110u8, 111u8, 104u8, 111u8, 99u8,
|
||||
104u8, 111u8, 106u8, 104u8, 115u8, 110u8, 104u8, 121u8, 0u8, 105u8, 105u8,
|
||||
0u8, 105u8, 110u8, 104u8, 105u8, 117u8, 0u8, 105u8, 119u8, 0u8, 106u8,
|
||||
97u8, 0u8, 106u8, 105u8, 0u8, 106u8, 109u8, 108u8, 107u8, 97u8, 0u8, 107u8,
|
||||
97u8, 97u8, 107u8, 97u8, 119u8, 107u8, 98u8, 100u8, 107u8, 98u8, 121u8,
|
||||
107u8, 100u8, 116u8, 107u8, 102u8, 114u8, 107u8, 102u8, 121u8, 107u8,
|
||||
104u8, 98u8, 107u8, 104u8, 110u8, 107u8, 104u8, 116u8, 107u8, 104u8, 119u8,
|
||||
107u8, 106u8, 103u8, 107u8, 107u8, 0u8, 107u8, 109u8, 0u8, 107u8, 110u8,
|
||||
0u8, 107u8, 111u8, 0u8, 107u8, 111u8, 105u8, 107u8, 111u8, 107u8, 107u8,
|
||||
113u8, 121u8, 107u8, 114u8, 99u8, 107u8, 114u8, 117u8, 107u8, 115u8, 0u8,
|
||||
107u8, 116u8, 98u8, 107u8, 117u8, 109u8, 107u8, 118u8, 0u8, 107u8, 118u8,
|
||||
120u8, 107u8, 120u8, 99u8, 107u8, 120u8, 108u8, 107u8, 120u8, 109u8, 107u8,
|
||||
120u8, 112u8, 107u8, 121u8, 0u8, 107u8, 122u8, 104u8, 108u8, 97u8, 98u8,
|
||||
108u8, 97u8, 100u8, 108u8, 97u8, 104u8, 108u8, 98u8, 101u8, 108u8, 99u8,
|
||||
112u8, 108u8, 101u8, 112u8, 108u8, 101u8, 122u8, 108u8, 105u8, 102u8,
|
||||
108u8, 105u8, 115u8, 108u8, 107u8, 105u8, 108u8, 109u8, 110u8, 108u8,
|
||||
111u8, 0u8, 108u8, 114u8, 99u8, 108u8, 117u8, 122u8, 108u8, 119u8, 108u8,
|
||||
108u8, 122u8, 104u8, 109u8, 97u8, 103u8, 109u8, 97u8, 105u8, 109u8, 100u8,
|
||||
101u8, 109u8, 100u8, 102u8, 109u8, 100u8, 120u8, 109u8, 102u8, 97u8, 109u8,
|
||||
103u8, 112u8, 109u8, 107u8, 0u8, 109u8, 107u8, 105u8, 109u8, 108u8, 0u8,
|
||||
109u8, 110u8, 0u8, 109u8, 110u8, 105u8, 109u8, 110u8, 119u8, 109u8, 114u8,
|
||||
0u8, 109u8, 114u8, 100u8, 109u8, 114u8, 106u8, 109u8, 114u8, 111u8, 109u8,
|
||||
116u8, 114u8, 109u8, 118u8, 121u8, 109u8, 119u8, 114u8, 109u8, 119u8,
|
||||
119u8, 109u8, 121u8, 0u8, 109u8, 121u8, 109u8, 109u8, 121u8, 118u8, 109u8,
|
||||
121u8, 122u8, 109u8, 122u8, 110u8, 110u8, 97u8, 110u8, 110u8, 101u8, 0u8,
|
||||
110u8, 101u8, 119u8, 110u8, 110u8, 112u8, 110u8, 111u8, 100u8, 110u8,
|
||||
111u8, 101u8, 110u8, 111u8, 110u8, 110u8, 113u8, 111u8, 110u8, 115u8,
|
||||
107u8, 110u8, 115u8, 116u8, 111u8, 106u8, 0u8, 111u8, 106u8, 115u8, 111u8,
|
||||
114u8, 0u8, 111u8, 114u8, 117u8, 111u8, 115u8, 0u8, 111u8, 115u8, 97u8,
|
||||
111u8, 116u8, 97u8, 111u8, 116u8, 107u8, 111u8, 117u8, 105u8, 112u8, 97u8,
|
||||
0u8, 112u8, 97u8, 108u8, 112u8, 101u8, 111u8, 112u8, 104u8, 108u8, 112u8,
|
||||
104u8, 110u8, 112u8, 107u8, 97u8, 112u8, 110u8, 116u8, 112u8, 112u8, 97u8,
|
||||
112u8, 114u8, 97u8, 112u8, 114u8, 100u8, 112u8, 115u8, 0u8, 114u8, 97u8,
|
||||
106u8, 114u8, 104u8, 103u8, 114u8, 105u8, 102u8, 114u8, 106u8, 115u8,
|
||||
114u8, 107u8, 116u8, 114u8, 109u8, 116u8, 114u8, 117u8, 0u8, 114u8, 117u8,
|
||||
101u8, 114u8, 121u8, 117u8, 115u8, 97u8, 0u8, 115u8, 97u8, 104u8, 115u8,
|
||||
97u8, 116u8, 115u8, 97u8, 122u8, 115u8, 99u8, 107u8, 115u8, 99u8, 108u8,
|
||||
115u8, 100u8, 0u8, 115u8, 100u8, 104u8, 115u8, 103u8, 97u8, 115u8, 103u8,
|
||||
119u8, 115u8, 104u8, 105u8, 115u8, 104u8, 110u8, 115u8, 104u8, 117u8,
|
||||
115u8, 105u8, 0u8, 115u8, 107u8, 114u8, 115u8, 109u8, 112u8, 115u8, 111u8,
|
||||
103u8, 115u8, 111u8, 117u8, 115u8, 114u8, 0u8, 115u8, 114u8, 98u8, 115u8,
|
||||
114u8, 120u8, 115u8, 119u8, 98u8, 115u8, 119u8, 118u8, 115u8, 121u8, 108u8,
|
||||
115u8, 121u8, 114u8, 116u8, 97u8, 0u8, 116u8, 97u8, 106u8, 116u8, 99u8,
|
||||
121u8, 116u8, 100u8, 100u8, 116u8, 100u8, 103u8, 116u8, 100u8, 104u8,
|
||||
116u8, 101u8, 0u8, 116u8, 103u8, 0u8, 116u8, 104u8, 0u8, 116u8, 104u8,
|
||||
108u8, 116u8, 104u8, 113u8, 116u8, 104u8, 114u8, 116u8, 105u8, 0u8, 116u8,
|
||||
105u8, 103u8, 116u8, 107u8, 116u8, 116u8, 114u8, 119u8, 116u8, 115u8,
|
||||
100u8, 116u8, 115u8, 102u8, 116u8, 115u8, 106u8, 116u8, 116u8, 0u8, 116u8,
|
||||
116u8, 115u8, 116u8, 120u8, 103u8, 116u8, 120u8, 111u8, 116u8, 121u8,
|
||||
118u8, 117u8, 100u8, 105u8, 117u8, 100u8, 109u8, 117u8, 103u8, 0u8, 117u8,
|
||||
103u8, 97u8, 117u8, 107u8, 0u8, 117u8, 110u8, 114u8, 117u8, 110u8, 120u8,
|
||||
117u8, 114u8, 0u8, 118u8, 97u8, 105u8, 119u8, 97u8, 108u8, 119u8, 98u8,
|
||||
113u8, 119u8, 98u8, 114u8, 119u8, 110u8, 105u8, 119u8, 115u8, 103u8, 119u8,
|
||||
116u8, 109u8, 119u8, 117u8, 117u8, 120u8, 99u8, 111u8, 120u8, 99u8, 114u8,
|
||||
120u8, 108u8, 99u8, 120u8, 108u8, 100u8, 120u8, 109u8, 102u8, 120u8, 109u8,
|
||||
110u8, 120u8, 109u8, 114u8, 120u8, 110u8, 97u8, 120u8, 110u8, 114u8, 120u8,
|
||||
112u8, 114u8, 120u8, 115u8, 97u8, 120u8, 115u8, 114u8, 121u8, 105u8, 0u8,
|
||||
121u8, 117u8, 101u8, 122u8, 100u8, 106u8, 122u8, 103u8, 104u8, 122u8,
|
||||
104u8, 0u8, 122u8, 104u8, 120u8, 122u8, 107u8, 116u8,
|
||||
])
|
||||
},
|
||||
unsafe {
|
||||
::zerovec::ZeroVec::from_bytes_unchecked(&[
|
||||
67u8, 121u8, 114u8, 108u8, 67u8, 121u8, 114u8, 108u8, 84u8, 105u8, 98u8,
|
||||
116u8, 67u8, 121u8, 114u8, 108u8, 65u8, 118u8, 115u8, 116u8, 65u8, 114u8,
|
||||
97u8, 98u8, 65u8, 104u8, 111u8, 109u8, 65u8, 114u8, 97u8, 98u8, 88u8,
|
||||
115u8, 117u8, 120u8, 67u8, 121u8, 114u8, 108u8, 69u8, 116u8, 104u8, 105u8,
|
||||
65u8, 114u8, 97u8, 98u8, 65u8, 114u8, 97u8, 98u8, 65u8, 114u8, 97u8, 98u8,
|
||||
65u8, 114u8, 109u8, 105u8, 65u8, 114u8, 97u8, 98u8, 65u8, 114u8, 97u8,
|
||||
98u8, 65u8, 114u8, 97u8, 98u8, 65u8, 114u8, 97u8, 98u8, 66u8, 101u8, 110u8,
|
||||
103u8, 83u8, 103u8, 110u8, 119u8, 67u8, 121u8, 114u8, 108u8, 65u8, 114u8,
|
||||
97u8, 98u8, 68u8, 101u8, 118u8, 97u8, 67u8, 121u8, 114u8, 108u8, 65u8,
|
||||
114u8, 97u8, 98u8, 68u8, 101u8, 118u8, 97u8, 66u8, 97u8, 109u8, 117u8,
|
||||
69u8, 116u8, 104u8, 105u8, 67u8, 121u8, 114u8, 108u8, 65u8, 114u8, 97u8,
|
||||
98u8, 84u8, 97u8, 109u8, 108u8, 65u8, 114u8, 97u8, 98u8, 68u8, 101u8,
|
||||
118u8, 97u8, 67u8, 121u8, 114u8, 108u8, 68u8, 101u8, 118u8, 97u8, 65u8,
|
||||
114u8, 97u8, 98u8, 71u8, 114u8, 101u8, 107u8, 68u8, 101u8, 118u8, 97u8,
|
||||
68u8, 101u8, 118u8, 97u8, 68u8, 101u8, 118u8, 97u8, 69u8, 116u8, 104u8,
|
||||
105u8, 68u8, 101u8, 118u8, 97u8, 84u8, 97u8, 118u8, 116u8, 66u8, 101u8,
|
||||
110u8, 103u8, 84u8, 105u8, 98u8, 116u8, 66u8, 101u8, 110u8, 103u8, 65u8,
|
||||
114u8, 97u8, 98u8, 68u8, 101u8, 118u8, 97u8, 65u8, 114u8, 97u8, 98u8, 68u8,
|
||||
101u8, 118u8, 97u8, 66u8, 97u8, 115u8, 115u8, 69u8, 116u8, 104u8, 105u8,
|
||||
68u8, 101u8, 118u8, 97u8, 67u8, 121u8, 114u8, 108u8, 69u8, 116u8, 104u8,
|
||||
105u8, 67u8, 97u8, 107u8, 109u8, 67u8, 121u8, 114u8, 108u8, 67u8, 121u8,
|
||||
114u8, 108u8, 67u8, 104u8, 101u8, 114u8, 65u8, 114u8, 97u8, 98u8, 67u8,
|
||||
104u8, 97u8, 109u8, 65u8, 114u8, 97u8, 98u8, 83u8, 111u8, 121u8, 111u8,
|
||||
67u8, 111u8, 112u8, 116u8, 67u8, 97u8, 110u8, 115u8, 67u8, 121u8, 114u8,
|
||||
108u8, 67u8, 97u8, 110u8, 115u8, 67u8, 97u8, 110u8, 115u8, 67u8, 97u8,
|
||||
110u8, 115u8, 80u8, 97u8, 117u8, 99u8, 67u8, 121u8, 114u8, 108u8, 67u8,
|
||||
121u8, 114u8, 108u8, 67u8, 121u8, 114u8, 108u8, 65u8, 114u8, 97u8, 98u8,
|
||||
65u8, 114u8, 97u8, 98u8, 77u8, 101u8, 100u8, 102u8, 68u8, 101u8, 118u8,
|
||||
97u8, 77u8, 111u8, 110u8, 103u8, 69u8, 116u8, 104u8, 105u8, 68u8, 101u8,
|
||||
118u8, 97u8, 84u8, 104u8, 97u8, 97u8, 84u8, 105u8, 98u8, 116u8, 69u8,
|
||||
103u8, 121u8, 112u8, 75u8, 97u8, 108u8, 105u8, 71u8, 114u8, 101u8, 107u8,
|
||||
71u8, 111u8, 110u8, 109u8, 73u8, 116u8, 97u8, 108u8, 65u8, 114u8, 97u8,
|
||||
98u8, 65u8, 114u8, 97u8, 98u8, 65u8, 114u8, 97u8, 98u8, 72u8, 97u8, 110u8,
|
||||
115u8, 68u8, 101u8, 118u8, 97u8, 65u8, 114u8, 97u8, 98u8, 69u8, 116u8,
|
||||
104u8, 105u8, 68u8, 101u8, 118u8, 97u8, 65u8, 114u8, 97u8, 98u8, 65u8,
|
||||
114u8, 97u8, 98u8, 65u8, 114u8, 97u8, 98u8, 69u8, 116u8, 104u8, 105u8,
|
||||
69u8, 116u8, 104u8, 105u8, 68u8, 101u8, 118u8, 97u8, 84u8, 101u8, 108u8,
|
||||
117u8, 71u8, 111u8, 116u8, 104u8, 67u8, 112u8, 114u8, 116u8, 66u8, 101u8,
|
||||
110u8, 103u8, 71u8, 117u8, 106u8, 114u8, 68u8, 101u8, 118u8, 97u8, 65u8,
|
||||
114u8, 97u8, 98u8, 65u8, 114u8, 97u8, 98u8, 72u8, 97u8, 110u8, 115u8, 65u8,
|
||||
114u8, 97u8, 98u8, 69u8, 116u8, 104u8, 105u8, 72u8, 101u8, 98u8, 114u8,
|
||||
68u8, 101u8, 118u8, 97u8, 72u8, 108u8, 117u8, 119u8, 80u8, 108u8, 114u8,
|
||||
100u8, 65u8, 114u8, 97u8, 98u8, 68u8, 101u8, 118u8, 97u8, 72u8, 109u8,
|
||||
110u8, 112u8, 65u8, 114u8, 97u8, 98u8, 68u8, 101u8, 118u8, 97u8, 68u8,
|
||||
101u8, 118u8, 97u8, 72u8, 97u8, 110u8, 115u8, 65u8, 114u8, 109u8, 110u8,
|
||||
89u8, 105u8, 105u8, 105u8, 67u8, 121u8, 114u8, 108u8, 67u8, 97u8, 110u8,
|
||||
115u8, 72u8, 101u8, 98u8, 114u8, 74u8, 112u8, 97u8, 110u8, 72u8, 101u8,
|
||||
98u8, 114u8, 68u8, 101u8, 118u8, 97u8, 71u8, 101u8, 111u8, 114u8, 67u8,
|
||||
121u8, 114u8, 108u8, 75u8, 97u8, 119u8, 105u8, 67u8, 121u8, 114u8, 108u8,
|
||||
65u8, 114u8, 97u8, 98u8, 84u8, 104u8, 97u8, 105u8, 68u8, 101u8, 118u8,
|
||||
97u8, 68u8, 101u8, 118u8, 97u8, 84u8, 97u8, 108u8, 117u8, 68u8, 101u8,
|
||||
118u8, 97u8, 77u8, 121u8, 109u8, 114u8, 65u8, 114u8, 97u8, 98u8, 76u8,
|
||||
97u8, 111u8, 111u8, 67u8, 121u8, 114u8, 108u8, 75u8, 104u8, 109u8, 114u8,
|
||||
75u8, 110u8, 100u8, 97u8, 75u8, 111u8, 114u8, 101u8, 67u8, 121u8, 114u8,
|
||||
108u8, 68u8, 101u8, 118u8, 97u8, 69u8, 116u8, 104u8, 105u8, 67u8, 121u8,
|
||||
114u8, 108u8, 68u8, 101u8, 118u8, 97u8, 65u8, 114u8, 97u8, 98u8, 69u8,
|
||||
116u8, 104u8, 105u8, 67u8, 121u8, 114u8, 108u8, 67u8, 121u8, 114u8, 108u8,
|
||||
65u8, 114u8, 97u8, 98u8, 69u8, 116u8, 104u8, 105u8, 68u8, 101u8, 118u8,
|
||||
97u8, 84u8, 104u8, 97u8, 105u8, 65u8, 114u8, 97u8, 98u8, 67u8, 121u8,
|
||||
114u8, 108u8, 65u8, 114u8, 97u8, 98u8, 76u8, 105u8, 110u8, 97u8, 72u8,
|
||||
101u8, 98u8, 114u8, 65u8, 114u8, 97u8, 98u8, 67u8, 121u8, 114u8, 108u8,
|
||||
84u8, 104u8, 97u8, 105u8, 76u8, 101u8, 112u8, 99u8, 67u8, 121u8, 114u8,
|
||||
108u8, 68u8, 101u8, 118u8, 97u8, 76u8, 105u8, 115u8, 117u8, 65u8, 114u8,
|
||||
97u8, 98u8, 84u8, 101u8, 108u8, 117u8, 76u8, 97u8, 111u8, 111u8, 65u8,
|
||||
114u8, 97u8, 98u8, 65u8, 114u8, 97u8, 98u8, 84u8, 104u8, 97u8, 105u8, 72u8,
|
||||
97u8, 110u8, 115u8, 68u8, 101u8, 118u8, 97u8, 68u8, 101u8, 118u8, 97u8,
|
||||
65u8, 114u8, 97u8, 98u8, 67u8, 121u8, 114u8, 108u8, 69u8, 116u8, 104u8,
|
||||
105u8, 65u8, 114u8, 97u8, 98u8, 68u8, 101u8, 118u8, 97u8, 67u8, 121u8,
|
||||
114u8, 108u8, 65u8, 114u8, 97u8, 98u8, 77u8, 108u8, 121u8, 109u8, 67u8,
|
||||
121u8, 114u8, 108u8, 66u8, 101u8, 110u8, 103u8, 77u8, 121u8, 109u8, 114u8,
|
||||
68u8, 101u8, 118u8, 97u8, 68u8, 101u8, 118u8, 97u8, 67u8, 121u8, 114u8,
|
||||
108u8, 77u8, 114u8, 111u8, 111u8, 68u8, 101u8, 118u8, 97u8, 65u8, 114u8,
|
||||
97u8, 98u8, 68u8, 101u8, 118u8, 97u8, 72u8, 109u8, 110u8, 112u8, 77u8,
|
||||
121u8, 109u8, 114u8, 69u8, 116u8, 104u8, 105u8, 67u8, 121u8, 114u8, 108u8,
|
||||
77u8, 97u8, 110u8, 100u8, 65u8, 114u8, 97u8, 98u8, 72u8, 97u8, 110u8,
|
||||
115u8, 68u8, 101u8, 118u8, 97u8, 68u8, 101u8, 118u8, 97u8, 87u8, 99u8,
|
||||
104u8, 111u8, 76u8, 97u8, 110u8, 97u8, 68u8, 101u8, 118u8, 97u8, 82u8,
|
||||
117u8, 110u8, 114u8, 78u8, 107u8, 111u8, 111u8, 67u8, 97u8, 110u8, 115u8,
|
||||
84u8, 110u8, 115u8, 97u8, 67u8, 97u8, 110u8, 115u8, 67u8, 97u8, 110u8,
|
||||
115u8, 79u8, 114u8, 121u8, 97u8, 65u8, 114u8, 97u8, 98u8, 67u8, 121u8,
|
||||
114u8, 108u8, 79u8, 115u8, 103u8, 101u8, 65u8, 114u8, 97u8, 98u8, 79u8,
|
||||
114u8, 107u8, 104u8, 79u8, 117u8, 103u8, 114u8, 71u8, 117u8, 114u8, 117u8,
|
||||
80u8, 104u8, 108u8, 105u8, 88u8, 112u8, 101u8, 111u8, 65u8, 114u8, 97u8,
|
||||
98u8, 80u8, 104u8, 110u8, 120u8, 66u8, 114u8, 97u8, 104u8, 71u8, 114u8,
|
||||
101u8, 107u8, 68u8, 101u8, 118u8, 97u8, 75u8, 104u8, 97u8, 114u8, 65u8,
|
||||
114u8, 97u8, 98u8, 65u8, 114u8, 97u8, 98u8, 68u8, 101u8, 118u8, 97u8, 82u8,
|
||||
111u8, 104u8, 103u8, 84u8, 102u8, 110u8, 103u8, 68u8, 101u8, 118u8, 97u8,
|
||||
66u8, 101u8, 110u8, 103u8, 65u8, 114u8, 97u8, 98u8, 67u8, 121u8, 114u8,
|
||||
108u8, 67u8, 121u8, 114u8, 108u8, 75u8, 97u8, 110u8, 97u8, 68u8, 101u8,
|
||||
118u8, 97u8, 67u8, 121u8, 114u8, 108u8, 79u8, 108u8, 99u8, 107u8, 83u8,
|
||||
97u8, 117u8, 114u8, 68u8, 101u8, 118u8, 97u8, 65u8, 114u8, 97u8, 98u8,
|
||||
65u8, 114u8, 97u8, 98u8, 65u8, 114u8, 97u8, 98u8, 79u8, 103u8, 97u8, 109u8,
|
||||
69u8, 116u8, 104u8, 105u8, 84u8, 102u8, 110u8, 103u8, 77u8, 121u8, 109u8,
|
||||
114u8, 65u8, 114u8, 97u8, 98u8, 83u8, 105u8, 110u8, 104u8, 65u8, 114u8,
|
||||
97u8, 98u8, 83u8, 97u8, 109u8, 114u8, 83u8, 111u8, 103u8, 100u8, 84u8,
|
||||
104u8, 97u8, 105u8, 67u8, 121u8, 114u8, 108u8, 83u8, 111u8, 114u8, 97u8,
|
||||
68u8, 101u8, 118u8, 97u8, 65u8, 114u8, 97u8, 98u8, 68u8, 101u8, 118u8,
|
||||
97u8, 66u8, 101u8, 110u8, 103u8, 83u8, 121u8, 114u8, 99u8, 84u8, 97u8,
|
||||
109u8, 108u8, 68u8, 101u8, 118u8, 97u8, 75u8, 110u8, 100u8, 97u8, 84u8,
|
||||
97u8, 108u8, 101u8, 68u8, 101u8, 118u8, 97u8, 68u8, 101u8, 118u8, 97u8,
|
||||
84u8, 101u8, 108u8, 117u8, 67u8, 121u8, 114u8, 108u8, 84u8, 104u8, 97u8,
|
||||
105u8, 68u8, 101u8, 118u8, 97u8, 68u8, 101u8, 118u8, 97u8, 68u8, 101u8,
|
||||
118u8, 97u8, 69u8, 116u8, 104u8, 105u8, 69u8, 116u8, 104u8, 105u8, 68u8,
|
||||
101u8, 118u8, 97u8, 65u8, 114u8, 97u8, 98u8, 71u8, 114u8, 101u8, 107u8,
|
||||
68u8, 101u8, 118u8, 97u8, 84u8, 105u8, 98u8, 116u8, 67u8, 121u8, 114u8,
|
||||
108u8, 84u8, 104u8, 97u8, 105u8, 84u8, 97u8, 110u8, 103u8, 84u8, 111u8,
|
||||
116u8, 111u8, 67u8, 121u8, 114u8, 108u8, 65u8, 103u8, 104u8, 98u8, 67u8,
|
||||
121u8, 114u8, 108u8, 65u8, 114u8, 97u8, 98u8, 85u8, 103u8, 97u8, 114u8,
|
||||
67u8, 121u8, 114u8, 108u8, 66u8, 101u8, 110u8, 103u8, 66u8, 101u8, 110u8,
|
||||
103u8, 65u8, 114u8, 97u8, 98u8, 86u8, 97u8, 105u8, 105u8, 69u8, 116u8,
|
||||
104u8, 105u8, 84u8, 101u8, 108u8, 117u8, 68u8, 101u8, 118u8, 97u8, 65u8,
|
||||
114u8, 97u8, 98u8, 71u8, 111u8, 110u8, 103u8, 68u8, 101u8, 118u8, 97u8,
|
||||
72u8, 97u8, 110u8, 115u8, 67u8, 104u8, 114u8, 115u8, 67u8, 97u8, 114u8,
|
||||
105u8, 76u8, 121u8, 99u8, 105u8, 76u8, 121u8, 100u8, 105u8, 71u8, 101u8,
|
||||
111u8, 114u8, 77u8, 97u8, 110u8, 105u8, 77u8, 101u8, 114u8, 99u8, 78u8,
|
||||
97u8, 114u8, 98u8, 68u8, 101u8, 118u8, 97u8, 80u8, 114u8, 116u8, 105u8,
|
||||
83u8, 97u8, 114u8, 98u8, 68u8, 101u8, 118u8, 97u8, 72u8, 101u8, 98u8,
|
||||
114u8, 72u8, 97u8, 110u8, 116u8, 65u8, 114u8, 97u8, 98u8, 84u8, 102u8,
|
||||
110u8, 103u8, 72u8, 97u8, 110u8, 115u8, 78u8, 115u8, 104u8, 117u8, 75u8,
|
||||
105u8, 116u8, 115u8,
|
||||
])
|
||||
},
|
||||
)
|
||||
},
|
||||
lr2s: unsafe {
|
||||
#[allow(unused_unsafe)]
|
||||
::zerovec::ZeroMap2d::from_parts_unchecked(
|
||||
unsafe {
|
||||
::zerovec::ZeroVec::from_bytes_unchecked(&[
|
||||
97u8, 122u8, 0u8, 104u8, 97u8, 0u8, 107u8, 107u8, 0u8, 107u8, 117u8, 0u8,
|
||||
107u8, 121u8, 0u8, 109u8, 97u8, 110u8, 109u8, 110u8, 0u8, 109u8, 115u8,
|
||||
0u8, 112u8, 97u8, 0u8, 114u8, 105u8, 102u8, 115u8, 100u8, 0u8, 115u8,
|
||||
114u8, 0u8, 116u8, 103u8, 0u8, 117u8, 103u8, 0u8, 117u8, 110u8, 114u8,
|
||||
117u8, 122u8, 0u8, 121u8, 117u8, 101u8, 122u8, 104u8, 0u8,
|
||||
])
|
||||
},
|
||||
unsafe {
|
||||
::zerovec::ZeroVec::from_bytes_unchecked(&[
|
||||
3u8, 0u8, 0u8, 0u8, 5u8, 0u8, 0u8, 0u8, 9u8, 0u8, 0u8, 0u8, 10u8, 0u8, 0u8,
|
||||
0u8, 12u8, 0u8, 0u8, 0u8, 13u8, 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8, 15u8,
|
||||
0u8, 0u8, 0u8, 16u8, 0u8, 0u8, 0u8, 17u8, 0u8, 0u8, 0u8, 18u8, 0u8, 0u8,
|
||||
0u8, 22u8, 0u8, 0u8, 0u8, 23u8, 0u8, 0u8, 0u8, 25u8, 0u8, 0u8, 0u8, 26u8,
|
||||
0u8, 0u8, 0u8, 28u8, 0u8, 0u8, 0u8, 29u8, 0u8, 0u8, 0u8, 44u8, 0u8, 0u8,
|
||||
0u8,
|
||||
])
|
||||
},
|
||||
unsafe {
|
||||
::zerovec::ZeroVec::from_bytes_unchecked(&[
|
||||
73u8, 81u8, 0u8, 73u8, 82u8, 0u8, 82u8, 85u8, 0u8, 67u8, 77u8, 0u8, 83u8,
|
||||
68u8, 0u8, 65u8, 70u8, 0u8, 67u8, 78u8, 0u8, 73u8, 82u8, 0u8, 77u8, 78u8,
|
||||
0u8, 76u8, 66u8, 0u8, 67u8, 78u8, 0u8, 84u8, 82u8, 0u8, 71u8, 78u8, 0u8,
|
||||
67u8, 78u8, 0u8, 67u8, 67u8, 0u8, 80u8, 75u8, 0u8, 78u8, 76u8, 0u8, 73u8,
|
||||
78u8, 0u8, 77u8, 69u8, 0u8, 82u8, 79u8, 0u8, 82u8, 85u8, 0u8, 84u8, 82u8,
|
||||
0u8, 80u8, 75u8, 0u8, 75u8, 90u8, 0u8, 77u8, 78u8, 0u8, 78u8, 80u8, 0u8,
|
||||
65u8, 70u8, 0u8, 67u8, 78u8, 0u8, 67u8, 78u8, 0u8, 65u8, 85u8, 0u8, 66u8,
|
||||
78u8, 0u8, 71u8, 66u8, 0u8, 71u8, 70u8, 0u8, 72u8, 75u8, 0u8, 73u8, 68u8,
|
||||
0u8, 77u8, 79u8, 0u8, 80u8, 65u8, 0u8, 80u8, 70u8, 0u8, 80u8, 72u8, 0u8,
|
||||
83u8, 82u8, 0u8, 84u8, 72u8, 0u8, 84u8, 87u8, 0u8, 85u8, 83u8, 0u8, 86u8,
|
||||
78u8, 0u8,
|
||||
])
|
||||
},
|
||||
unsafe {
|
||||
::zerovec::ZeroVec::from_bytes_unchecked(&[
|
||||
65u8, 114u8, 97u8, 98u8, 65u8, 114u8, 97u8, 98u8, 67u8, 121u8, 114u8,
|
||||
108u8, 65u8, 114u8, 97u8, 98u8, 65u8, 114u8, 97u8, 98u8, 65u8, 114u8, 97u8,
|
||||
98u8, 65u8, 114u8, 97u8, 98u8, 65u8, 114u8, 97u8, 98u8, 65u8, 114u8, 97u8,
|
||||
98u8, 65u8, 114u8, 97u8, 98u8, 65u8, 114u8, 97u8, 98u8, 76u8, 97u8, 116u8,
|
||||
110u8, 78u8, 107u8, 111u8, 111u8, 77u8, 111u8, 110u8, 103u8, 65u8, 114u8,
|
||||
97u8, 98u8, 65u8, 114u8, 97u8, 98u8, 76u8, 97u8, 116u8, 110u8, 68u8, 101u8,
|
||||
118u8, 97u8, 76u8, 97u8, 116u8, 110u8, 76u8, 97u8, 116u8, 110u8, 76u8,
|
||||
97u8, 116u8, 110u8, 76u8, 97u8, 116u8, 110u8, 65u8, 114u8, 97u8, 98u8,
|
||||
67u8, 121u8, 114u8, 108u8, 67u8, 121u8, 114u8, 108u8, 68u8, 101u8, 118u8,
|
||||
97u8, 65u8, 114u8, 97u8, 98u8, 67u8, 121u8, 114u8, 108u8, 72u8, 97u8,
|
||||
110u8, 115u8, 72u8, 97u8, 110u8, 116u8, 72u8, 97u8, 110u8, 116u8, 72u8,
|
||||
97u8, 110u8, 116u8, 72u8, 97u8, 110u8, 116u8, 72u8, 97u8, 110u8, 116u8,
|
||||
72u8, 97u8, 110u8, 116u8, 72u8, 97u8, 110u8, 116u8, 72u8, 97u8, 110u8,
|
||||
116u8, 72u8, 97u8, 110u8, 116u8, 72u8, 97u8, 110u8, 116u8, 72u8, 97u8,
|
||||
110u8, 116u8, 72u8, 97u8, 110u8, 116u8, 72u8, 97u8, 110u8, 116u8, 72u8,
|
||||
97u8, 110u8, 116u8, 72u8, 97u8, 110u8, 116u8,
|
||||
])
|
||||
},
|
||||
)
|
||||
},
|
||||
l2r: unsafe {
|
||||
#[allow(unused_unsafe)]
|
||||
::zerovec::ZeroMap::from_parts_unchecked(
|
||||
unsafe {
|
||||
::zerovec::ZeroVec::from_bytes_unchecked(&[
|
||||
97u8, 97u8, 0u8, 97u8, 98u8, 0u8, 97u8, 98u8, 114u8, 97u8, 99u8, 101u8,
|
||||
97u8, 99u8, 104u8, 97u8, 100u8, 97u8, 97u8, 100u8, 112u8, 97u8, 100u8,
|
||||
121u8, 97u8, 101u8, 0u8, 97u8, 101u8, 98u8, 97u8, 102u8, 0u8, 97u8, 103u8,
|
||||
113u8, 97u8, 104u8, 111u8, 97u8, 106u8, 116u8, 97u8, 107u8, 0u8, 97u8,
|
||||
107u8, 107u8, 97u8, 108u8, 110u8, 97u8, 108u8, 116u8, 97u8, 109u8, 0u8,
|
||||
97u8, 109u8, 111u8, 97u8, 110u8, 0u8, 97u8, 110u8, 110u8, 97u8, 111u8,
|
||||
122u8, 97u8, 112u8, 100u8, 97u8, 114u8, 0u8, 97u8, 114u8, 99u8, 97u8,
|
||||
114u8, 110u8, 97u8, 114u8, 111u8, 97u8, 114u8, 113u8, 97u8, 114u8, 115u8,
|
||||
97u8, 114u8, 121u8, 97u8, 114u8, 122u8, 97u8, 115u8, 0u8, 97u8, 115u8,
|
||||
97u8, 97u8, 115u8, 101u8, 97u8, 115u8, 116u8, 97u8, 116u8, 106u8, 97u8,
|
||||
118u8, 0u8, 97u8, 119u8, 97u8, 97u8, 121u8, 0u8, 97u8, 122u8, 0u8, 98u8,
|
||||
97u8, 0u8, 98u8, 97u8, 108u8, 98u8, 97u8, 110u8, 98u8, 97u8, 112u8, 98u8,
|
||||
97u8, 114u8, 98u8, 97u8, 115u8, 98u8, 97u8, 120u8, 98u8, 98u8, 99u8, 98u8,
|
||||
98u8, 106u8, 98u8, 99u8, 105u8, 98u8, 101u8, 0u8, 98u8, 101u8, 106u8, 98u8,
|
||||
101u8, 109u8, 98u8, 101u8, 119u8, 98u8, 101u8, 122u8, 98u8, 102u8, 100u8,
|
||||
98u8, 102u8, 113u8, 98u8, 102u8, 116u8, 98u8, 102u8, 121u8, 98u8, 103u8,
|
||||
0u8, 98u8, 103u8, 99u8, 98u8, 103u8, 110u8, 98u8, 103u8, 120u8, 98u8,
|
||||
104u8, 98u8, 98u8, 104u8, 105u8, 98u8, 104u8, 111u8, 98u8, 105u8, 0u8,
|
||||
98u8, 105u8, 107u8, 98u8, 105u8, 110u8, 98u8, 106u8, 106u8, 98u8, 106u8,
|
||||
110u8, 98u8, 106u8, 116u8, 98u8, 107u8, 109u8, 98u8, 107u8, 117u8, 98u8,
|
||||
108u8, 97u8, 98u8, 108u8, 103u8, 98u8, 108u8, 116u8, 98u8, 109u8, 0u8,
|
||||
98u8, 109u8, 113u8, 98u8, 110u8, 0u8, 98u8, 111u8, 0u8, 98u8, 112u8, 121u8,
|
||||
98u8, 113u8, 105u8, 98u8, 113u8, 118u8, 98u8, 114u8, 0u8, 98u8, 114u8,
|
||||
97u8, 98u8, 114u8, 104u8, 98u8, 114u8, 120u8, 98u8, 115u8, 0u8, 98u8,
|
||||
115u8, 113u8, 98u8, 115u8, 115u8, 98u8, 116u8, 111u8, 98u8, 116u8, 118u8,
|
||||
98u8, 117u8, 97u8, 98u8, 117u8, 99u8, 98u8, 117u8, 103u8, 98u8, 117u8,
|
||||
109u8, 98u8, 118u8, 98u8, 98u8, 121u8, 110u8, 98u8, 121u8, 118u8, 98u8,
|
||||
122u8, 101u8, 99u8, 97u8, 0u8, 99u8, 97u8, 100u8, 99u8, 99u8, 104u8, 99u8,
|
||||
99u8, 112u8, 99u8, 101u8, 0u8, 99u8, 101u8, 98u8, 99u8, 103u8, 103u8, 99u8,
|
||||
104u8, 0u8, 99u8, 104u8, 107u8, 99u8, 104u8, 109u8, 99u8, 104u8, 111u8,
|
||||
99u8, 104u8, 112u8, 99u8, 104u8, 114u8, 99u8, 105u8, 99u8, 99u8, 106u8,
|
||||
97u8, 99u8, 106u8, 109u8, 99u8, 107u8, 98u8, 99u8, 108u8, 99u8, 99u8,
|
||||
109u8, 103u8, 99u8, 111u8, 0u8, 99u8, 111u8, 112u8, 99u8, 112u8, 115u8,
|
||||
99u8, 114u8, 0u8, 99u8, 114u8, 103u8, 99u8, 114u8, 104u8, 99u8, 114u8,
|
||||
107u8, 99u8, 114u8, 108u8, 99u8, 114u8, 115u8, 99u8, 115u8, 0u8, 99u8,
|
||||
115u8, 98u8, 99u8, 115u8, 119u8, 99u8, 116u8, 100u8, 99u8, 117u8, 0u8,
|
||||
99u8, 118u8, 0u8, 99u8, 121u8, 0u8, 100u8, 97u8, 0u8, 100u8, 97u8, 102u8,
|
||||
100u8, 97u8, 107u8, 100u8, 97u8, 114u8, 100u8, 97u8, 118u8, 100u8, 99u8,
|
||||
99u8, 100u8, 101u8, 0u8, 100u8, 101u8, 110u8, 100u8, 103u8, 114u8, 100u8,
|
||||
106u8, 101u8, 100u8, 109u8, 102u8, 100u8, 110u8, 106u8, 100u8, 111u8,
|
||||
105u8, 100u8, 114u8, 104u8, 100u8, 115u8, 98u8, 100u8, 116u8, 109u8, 100u8,
|
||||
116u8, 112u8, 100u8, 116u8, 121u8, 100u8, 117u8, 97u8, 100u8, 118u8, 0u8,
|
||||
100u8, 121u8, 111u8, 100u8, 121u8, 117u8, 100u8, 122u8, 0u8, 101u8, 98u8,
|
||||
117u8, 101u8, 101u8, 0u8, 101u8, 102u8, 105u8, 101u8, 103u8, 108u8, 101u8,
|
||||
103u8, 121u8, 101u8, 107u8, 121u8, 101u8, 108u8, 0u8, 101u8, 110u8, 0u8,
|
||||
101u8, 111u8, 0u8, 101u8, 115u8, 0u8, 101u8, 115u8, 103u8, 101u8, 115u8,
|
||||
117u8, 101u8, 116u8, 0u8, 101u8, 116u8, 116u8, 101u8, 117u8, 0u8, 101u8,
|
||||
119u8, 111u8, 101u8, 120u8, 116u8, 102u8, 97u8, 0u8, 102u8, 97u8, 110u8,
|
||||
102u8, 102u8, 0u8, 102u8, 102u8, 109u8, 102u8, 105u8, 0u8, 102u8, 105u8,
|
||||
97u8, 102u8, 105u8, 108u8, 102u8, 105u8, 116u8, 102u8, 106u8, 0u8, 102u8,
|
||||
111u8, 0u8, 102u8, 111u8, 110u8, 102u8, 114u8, 0u8, 102u8, 114u8, 99u8,
|
||||
102u8, 114u8, 112u8, 102u8, 114u8, 114u8, 102u8, 114u8, 115u8, 102u8,
|
||||
117u8, 98u8, 102u8, 117u8, 100u8, 102u8, 117u8, 102u8, 102u8, 117u8, 113u8,
|
||||
102u8, 117u8, 114u8, 102u8, 117u8, 118u8, 102u8, 118u8, 114u8, 102u8,
|
||||
121u8, 0u8, 103u8, 97u8, 0u8, 103u8, 97u8, 97u8, 103u8, 97u8, 103u8, 103u8,
|
||||
97u8, 110u8, 103u8, 97u8, 121u8, 103u8, 98u8, 109u8, 103u8, 98u8, 122u8,
|
||||
103u8, 99u8, 114u8, 103u8, 100u8, 0u8, 103u8, 101u8, 122u8, 103u8, 103u8,
|
||||
110u8, 103u8, 105u8, 108u8, 103u8, 106u8, 107u8, 103u8, 106u8, 117u8,
|
||||
103u8, 108u8, 0u8, 103u8, 108u8, 107u8, 103u8, 110u8, 0u8, 103u8, 111u8,
|
||||
109u8, 103u8, 111u8, 110u8, 103u8, 111u8, 114u8, 103u8, 111u8, 115u8,
|
||||
103u8, 111u8, 116u8, 103u8, 114u8, 99u8, 103u8, 114u8, 116u8, 103u8, 115u8,
|
||||
119u8, 103u8, 117u8, 0u8, 103u8, 117u8, 98u8, 103u8, 117u8, 99u8, 103u8,
|
||||
117u8, 114u8, 103u8, 117u8, 122u8, 103u8, 118u8, 0u8, 103u8, 118u8, 114u8,
|
||||
103u8, 119u8, 105u8, 104u8, 97u8, 0u8, 104u8, 97u8, 107u8, 104u8, 97u8,
|
||||
119u8, 104u8, 97u8, 122u8, 104u8, 101u8, 0u8, 104u8, 105u8, 0u8, 104u8,
|
||||
105u8, 102u8, 104u8, 105u8, 108u8, 104u8, 108u8, 117u8, 104u8, 109u8,
|
||||
100u8, 104u8, 110u8, 100u8, 104u8, 110u8, 101u8, 104u8, 110u8, 106u8,
|
||||
104u8, 110u8, 110u8, 104u8, 110u8, 111u8, 104u8, 111u8, 0u8, 104u8, 111u8,
|
||||
99u8, 104u8, 111u8, 106u8, 104u8, 114u8, 0u8, 104u8, 115u8, 98u8, 104u8,
|
||||
115u8, 110u8, 104u8, 116u8, 0u8, 104u8, 117u8, 0u8, 104u8, 117u8, 114u8,
|
||||
104u8, 121u8, 0u8, 104u8, 122u8, 0u8, 105u8, 97u8, 0u8, 105u8, 98u8, 97u8,
|
||||
105u8, 98u8, 98u8, 105u8, 100u8, 0u8, 105u8, 102u8, 101u8, 105u8, 103u8,
|
||||
0u8, 105u8, 105u8, 0u8, 105u8, 107u8, 0u8, 105u8, 108u8, 111u8, 105u8,
|
||||
110u8, 0u8, 105u8, 110u8, 104u8, 105u8, 111u8, 0u8, 105u8, 115u8, 0u8,
|
||||
105u8, 116u8, 0u8, 105u8, 117u8, 0u8, 105u8, 119u8, 0u8, 105u8, 122u8,
|
||||
104u8, 106u8, 97u8, 0u8, 106u8, 97u8, 109u8, 106u8, 98u8, 111u8, 106u8,
|
||||
103u8, 111u8, 106u8, 105u8, 0u8, 106u8, 109u8, 99u8, 106u8, 109u8, 108u8,
|
||||
106u8, 117u8, 116u8, 106u8, 118u8, 0u8, 106u8, 119u8, 0u8, 107u8, 97u8,
|
||||
0u8, 107u8, 97u8, 97u8, 107u8, 97u8, 98u8, 107u8, 97u8, 99u8, 107u8, 97u8,
|
||||
106u8, 107u8, 97u8, 109u8, 107u8, 97u8, 111u8, 107u8, 97u8, 119u8, 107u8,
|
||||
98u8, 100u8, 107u8, 98u8, 121u8, 107u8, 99u8, 103u8, 107u8, 99u8, 107u8,
|
||||
107u8, 100u8, 101u8, 107u8, 100u8, 104u8, 107u8, 100u8, 116u8, 107u8,
|
||||
101u8, 97u8, 107u8, 101u8, 110u8, 107u8, 102u8, 111u8, 107u8, 102u8, 114u8,
|
||||
107u8, 102u8, 121u8, 107u8, 103u8, 0u8, 107u8, 103u8, 101u8, 107u8, 103u8,
|
||||
112u8, 107u8, 104u8, 97u8, 107u8, 104u8, 98u8, 107u8, 104u8, 110u8, 107u8,
|
||||
104u8, 113u8, 107u8, 104u8, 116u8, 107u8, 104u8, 119u8, 107u8, 105u8, 0u8,
|
||||
107u8, 105u8, 117u8, 107u8, 106u8, 0u8, 107u8, 106u8, 103u8, 107u8, 107u8,
|
||||
0u8, 107u8, 107u8, 106u8, 107u8, 108u8, 0u8, 107u8, 108u8, 110u8, 107u8,
|
||||
109u8, 0u8, 107u8, 109u8, 98u8, 107u8, 110u8, 0u8, 107u8, 110u8, 102u8,
|
||||
107u8, 111u8, 0u8, 107u8, 111u8, 105u8, 107u8, 111u8, 107u8, 107u8, 111u8,
|
||||
115u8, 107u8, 112u8, 101u8, 107u8, 114u8, 99u8, 107u8, 114u8, 105u8, 107u8,
|
||||
114u8, 106u8, 107u8, 114u8, 108u8, 107u8, 114u8, 117u8, 107u8, 115u8, 0u8,
|
||||
107u8, 115u8, 98u8, 107u8, 115u8, 102u8, 107u8, 115u8, 104u8, 107u8, 116u8,
|
||||
114u8, 107u8, 117u8, 0u8, 107u8, 117u8, 109u8, 107u8, 118u8, 0u8, 107u8,
|
||||
118u8, 114u8, 107u8, 118u8, 120u8, 107u8, 119u8, 0u8, 107u8, 119u8, 107u8,
|
||||
107u8, 120u8, 108u8, 107u8, 120u8, 109u8, 107u8, 120u8, 112u8, 107u8,
|
||||
121u8, 0u8, 107u8, 122u8, 106u8, 107u8, 122u8, 116u8, 108u8, 97u8, 0u8,
|
||||
108u8, 97u8, 98u8, 108u8, 97u8, 100u8, 108u8, 97u8, 103u8, 108u8, 97u8,
|
||||
104u8, 108u8, 97u8, 106u8, 108u8, 98u8, 0u8, 108u8, 98u8, 101u8, 108u8,
|
||||
98u8, 119u8, 108u8, 99u8, 112u8, 108u8, 101u8, 112u8, 108u8, 101u8, 122u8,
|
||||
108u8, 103u8, 0u8, 108u8, 105u8, 0u8, 108u8, 105u8, 102u8, 108u8, 105u8,
|
||||
106u8, 108u8, 105u8, 108u8, 108u8, 105u8, 115u8, 108u8, 106u8, 112u8,
|
||||
108u8, 107u8, 105u8, 108u8, 107u8, 116u8, 108u8, 109u8, 110u8, 108u8,
|
||||
109u8, 111u8, 108u8, 110u8, 0u8, 108u8, 111u8, 0u8, 108u8, 111u8, 108u8,
|
||||
108u8, 111u8, 122u8, 108u8, 114u8, 99u8, 108u8, 116u8, 0u8, 108u8, 116u8,
|
||||
103u8, 108u8, 117u8, 0u8, 108u8, 117u8, 97u8, 108u8, 117u8, 111u8, 108u8,
|
||||
117u8, 121u8, 108u8, 117u8, 122u8, 108u8, 118u8, 0u8, 108u8, 119u8, 108u8,
|
||||
108u8, 122u8, 104u8, 108u8, 122u8, 122u8, 109u8, 97u8, 100u8, 109u8, 97u8,
|
||||
102u8, 109u8, 97u8, 103u8, 109u8, 97u8, 105u8, 109u8, 97u8, 107u8, 109u8,
|
||||
97u8, 110u8, 109u8, 97u8, 115u8, 109u8, 97u8, 122u8, 109u8, 100u8, 102u8,
|
||||
109u8, 100u8, 104u8, 109u8, 100u8, 114u8, 109u8, 101u8, 110u8, 109u8,
|
||||
101u8, 114u8, 109u8, 102u8, 97u8, 109u8, 102u8, 101u8, 109u8, 103u8, 0u8,
|
||||
109u8, 103u8, 104u8, 109u8, 103u8, 111u8, 109u8, 103u8, 112u8, 109u8,
|
||||
103u8, 121u8, 109u8, 104u8, 0u8, 109u8, 105u8, 0u8, 109u8, 105u8, 99u8,
|
||||
109u8, 105u8, 110u8, 109u8, 107u8, 0u8, 109u8, 108u8, 0u8, 109u8, 108u8,
|
||||
115u8, 109u8, 110u8, 0u8, 109u8, 110u8, 105u8, 109u8, 110u8, 119u8, 109u8,
|
||||
111u8, 0u8, 109u8, 111u8, 101u8, 109u8, 111u8, 104u8, 109u8, 111u8, 115u8,
|
||||
109u8, 114u8, 0u8, 109u8, 114u8, 100u8, 109u8, 114u8, 106u8, 109u8, 114u8,
|
||||
111u8, 109u8, 115u8, 0u8, 109u8, 116u8, 0u8, 109u8, 116u8, 114u8, 109u8,
|
||||
117u8, 97u8, 109u8, 117u8, 115u8, 109u8, 118u8, 121u8, 109u8, 119u8, 107u8,
|
||||
109u8, 119u8, 114u8, 109u8, 119u8, 118u8, 109u8, 119u8, 119u8, 109u8,
|
||||
120u8, 99u8, 109u8, 121u8, 0u8, 109u8, 121u8, 118u8, 109u8, 121u8, 120u8,
|
||||
109u8, 121u8, 122u8, 109u8, 122u8, 110u8, 110u8, 97u8, 0u8, 110u8, 97u8,
|
||||
110u8, 110u8, 97u8, 112u8, 110u8, 97u8, 113u8, 110u8, 98u8, 0u8, 110u8,
|
||||
99u8, 104u8, 110u8, 100u8, 0u8, 110u8, 100u8, 99u8, 110u8, 100u8, 115u8,
|
||||
110u8, 101u8, 0u8, 110u8, 101u8, 119u8, 110u8, 103u8, 0u8, 110u8, 103u8,
|
||||
108u8, 110u8, 104u8, 101u8, 110u8, 104u8, 119u8, 110u8, 105u8, 106u8,
|
||||
110u8, 105u8, 117u8, 110u8, 106u8, 111u8, 110u8, 108u8, 0u8, 110u8, 109u8,
|
||||
103u8, 110u8, 110u8, 0u8, 110u8, 110u8, 104u8, 110u8, 110u8, 112u8, 110u8,
|
||||
111u8, 0u8, 110u8, 111u8, 100u8, 110u8, 111u8, 101u8, 110u8, 111u8, 110u8,
|
||||
110u8, 113u8, 111u8, 110u8, 114u8, 0u8, 110u8, 115u8, 107u8, 110u8, 115u8,
|
||||
111u8, 110u8, 115u8, 116u8, 110u8, 117u8, 115u8, 110u8, 118u8, 0u8, 110u8,
|
||||
120u8, 113u8, 110u8, 121u8, 0u8, 110u8, 121u8, 109u8, 110u8, 121u8, 110u8,
|
||||
110u8, 122u8, 105u8, 111u8, 99u8, 0u8, 111u8, 106u8, 0u8, 111u8, 106u8,
|
||||
115u8, 111u8, 107u8, 97u8, 111u8, 109u8, 0u8, 111u8, 114u8, 0u8, 111u8,
|
||||
115u8, 0u8, 111u8, 115u8, 97u8, 111u8, 116u8, 107u8, 111u8, 117u8, 105u8,
|
||||
112u8, 97u8, 0u8, 112u8, 97u8, 103u8, 112u8, 97u8, 108u8, 112u8, 97u8,
|
||||
109u8, 112u8, 97u8, 112u8, 112u8, 97u8, 117u8, 112u8, 99u8, 100u8, 112u8,
|
||||
99u8, 109u8, 112u8, 100u8, 99u8, 112u8, 100u8, 116u8, 112u8, 101u8, 111u8,
|
||||
112u8, 102u8, 108u8, 112u8, 104u8, 110u8, 112u8, 105u8, 115u8, 112u8,
|
||||
107u8, 97u8, 112u8, 107u8, 111u8, 112u8, 108u8, 0u8, 112u8, 109u8, 115u8,
|
||||
112u8, 110u8, 116u8, 112u8, 111u8, 110u8, 112u8, 112u8, 97u8, 112u8, 113u8,
|
||||
109u8, 112u8, 114u8, 97u8, 112u8, 114u8, 100u8, 112u8, 114u8, 103u8, 112u8,
|
||||
115u8, 0u8, 112u8, 116u8, 0u8, 112u8, 117u8, 117u8, 113u8, 117u8, 0u8,
|
||||
113u8, 117u8, 99u8, 113u8, 117u8, 103u8, 114u8, 97u8, 106u8, 114u8, 99u8,
|
||||
102u8, 114u8, 101u8, 106u8, 114u8, 103u8, 110u8, 114u8, 104u8, 103u8,
|
||||
114u8, 105u8, 97u8, 114u8, 105u8, 102u8, 114u8, 106u8, 115u8, 114u8, 107u8,
|
||||
116u8, 114u8, 109u8, 0u8, 114u8, 109u8, 102u8, 114u8, 109u8, 111u8, 114u8,
|
||||
109u8, 116u8, 114u8, 109u8, 117u8, 114u8, 110u8, 0u8, 114u8, 110u8, 103u8,
|
||||
114u8, 111u8, 0u8, 114u8, 111u8, 98u8, 114u8, 111u8, 102u8, 114u8, 116u8,
|
||||
109u8, 114u8, 117u8, 0u8, 114u8, 117u8, 101u8, 114u8, 117u8, 103u8, 114u8,
|
||||
119u8, 0u8, 114u8, 119u8, 107u8, 114u8, 121u8, 117u8, 115u8, 97u8, 0u8,
|
||||
115u8, 97u8, 102u8, 115u8, 97u8, 104u8, 115u8, 97u8, 113u8, 115u8, 97u8,
|
||||
115u8, 115u8, 97u8, 116u8, 115u8, 97u8, 118u8, 115u8, 97u8, 122u8, 115u8,
|
||||
98u8, 112u8, 115u8, 99u8, 0u8, 115u8, 99u8, 107u8, 115u8, 99u8, 110u8,
|
||||
115u8, 99u8, 111u8, 115u8, 100u8, 0u8, 115u8, 100u8, 99u8, 115u8, 100u8,
|
||||
104u8, 115u8, 101u8, 0u8, 115u8, 101u8, 102u8, 115u8, 101u8, 104u8, 115u8,
|
||||
101u8, 105u8, 115u8, 101u8, 115u8, 115u8, 103u8, 0u8, 115u8, 103u8, 97u8,
|
||||
115u8, 103u8, 115u8, 115u8, 104u8, 105u8, 115u8, 104u8, 110u8, 115u8,
|
||||
105u8, 0u8, 115u8, 105u8, 100u8, 115u8, 107u8, 0u8, 115u8, 107u8, 114u8,
|
||||
115u8, 108u8, 0u8, 115u8, 108u8, 105u8, 115u8, 108u8, 121u8, 115u8, 109u8,
|
||||
0u8, 115u8, 109u8, 97u8, 115u8, 109u8, 100u8, 115u8, 109u8, 106u8, 115u8,
|
||||
109u8, 110u8, 115u8, 109u8, 112u8, 115u8, 109u8, 115u8, 115u8, 110u8, 0u8,
|
||||
115u8, 110u8, 98u8, 115u8, 110u8, 107u8, 115u8, 111u8, 0u8, 115u8, 111u8,
|
||||
103u8, 115u8, 111u8, 117u8, 115u8, 113u8, 0u8, 115u8, 114u8, 0u8, 115u8,
|
||||
114u8, 98u8, 115u8, 114u8, 110u8, 115u8, 114u8, 114u8, 115u8, 114u8, 120u8,
|
||||
115u8, 115u8, 0u8, 115u8, 115u8, 121u8, 115u8, 116u8, 0u8, 115u8, 116u8,
|
||||
113u8, 115u8, 117u8, 0u8, 115u8, 117u8, 107u8, 115u8, 117u8, 115u8, 115u8,
|
||||
118u8, 0u8, 115u8, 119u8, 0u8, 115u8, 119u8, 98u8, 115u8, 119u8, 99u8,
|
||||
115u8, 119u8, 103u8, 115u8, 119u8, 118u8, 115u8, 120u8, 110u8, 115u8,
|
||||
121u8, 108u8, 115u8, 121u8, 114u8, 115u8, 122u8, 108u8, 116u8, 97u8, 0u8,
|
||||
116u8, 97u8, 106u8, 116u8, 98u8, 119u8, 116u8, 99u8, 121u8, 116u8, 100u8,
|
||||
100u8, 116u8, 100u8, 103u8, 116u8, 100u8, 104u8, 116u8, 100u8, 117u8,
|
||||
116u8, 101u8, 0u8, 116u8, 101u8, 109u8, 116u8, 101u8, 111u8, 116u8, 101u8,
|
||||
116u8, 116u8, 103u8, 0u8, 116u8, 104u8, 0u8, 116u8, 104u8, 108u8, 116u8,
|
||||
104u8, 113u8, 116u8, 104u8, 114u8, 116u8, 105u8, 0u8, 116u8, 105u8, 103u8,
|
||||
116u8, 105u8, 118u8, 116u8, 107u8, 0u8, 116u8, 107u8, 108u8, 116u8, 107u8,
|
||||
114u8, 116u8, 107u8, 116u8, 116u8, 108u8, 0u8, 116u8, 108u8, 121u8, 116u8,
|
||||
109u8, 104u8, 116u8, 110u8, 0u8, 116u8, 111u8, 0u8, 116u8, 111u8, 103u8,
|
||||
116u8, 111u8, 107u8, 116u8, 112u8, 105u8, 116u8, 114u8, 0u8, 116u8, 114u8,
|
||||
117u8, 116u8, 114u8, 118u8, 116u8, 114u8, 119u8, 116u8, 115u8, 0u8, 116u8,
|
||||
115u8, 100u8, 116u8, 115u8, 102u8, 116u8, 115u8, 103u8, 116u8, 115u8,
|
||||
106u8, 116u8, 116u8, 0u8, 116u8, 116u8, 106u8, 116u8, 116u8, 115u8, 116u8,
|
||||
116u8, 116u8, 116u8, 117u8, 109u8, 116u8, 118u8, 108u8, 116u8, 119u8,
|
||||
113u8, 116u8, 120u8, 103u8, 116u8, 120u8, 111u8, 116u8, 121u8, 0u8, 116u8,
|
||||
121u8, 118u8, 116u8, 122u8, 109u8, 117u8, 100u8, 105u8, 117u8, 100u8,
|
||||
109u8, 117u8, 103u8, 0u8, 117u8, 103u8, 97u8, 117u8, 107u8, 0u8, 117u8,
|
||||
108u8, 105u8, 117u8, 109u8, 98u8, 117u8, 110u8, 114u8, 117u8, 110u8, 120u8,
|
||||
117u8, 114u8, 0u8, 117u8, 122u8, 0u8, 118u8, 97u8, 105u8, 118u8, 101u8,
|
||||
0u8, 118u8, 101u8, 99u8, 118u8, 101u8, 112u8, 118u8, 105u8, 0u8, 118u8,
|
||||
105u8, 99u8, 118u8, 108u8, 115u8, 118u8, 109u8, 102u8, 118u8, 109u8, 119u8,
|
||||
118u8, 111u8, 0u8, 118u8, 111u8, 116u8, 118u8, 114u8, 111u8, 118u8, 117u8,
|
||||
110u8, 119u8, 97u8, 0u8, 119u8, 97u8, 101u8, 119u8, 97u8, 108u8, 119u8,
|
||||
97u8, 114u8, 119u8, 98u8, 112u8, 119u8, 98u8, 113u8, 119u8, 98u8, 114u8,
|
||||
119u8, 108u8, 115u8, 119u8, 110u8, 105u8, 119u8, 111u8, 0u8, 119u8, 115u8,
|
||||
103u8, 119u8, 116u8, 109u8, 119u8, 117u8, 117u8, 120u8, 97u8, 118u8, 120u8,
|
||||
99u8, 111u8, 120u8, 99u8, 114u8, 120u8, 104u8, 0u8, 120u8, 108u8, 99u8,
|
||||
120u8, 108u8, 100u8, 120u8, 109u8, 102u8, 120u8, 109u8, 110u8, 120u8,
|
||||
109u8, 114u8, 120u8, 110u8, 97u8, 120u8, 110u8, 114u8, 120u8, 111u8, 103u8,
|
||||
120u8, 112u8, 114u8, 120u8, 115u8, 97u8, 120u8, 115u8, 114u8, 121u8, 97u8,
|
||||
111u8, 121u8, 97u8, 112u8, 121u8, 97u8, 118u8, 121u8, 98u8, 98u8, 121u8,
|
||||
105u8, 0u8, 121u8, 111u8, 0u8, 121u8, 114u8, 108u8, 121u8, 117u8, 97u8,
|
||||
121u8, 117u8, 101u8, 122u8, 97u8, 0u8, 122u8, 97u8, 103u8, 122u8, 100u8,
|
||||
106u8, 122u8, 101u8, 97u8, 122u8, 103u8, 104u8, 122u8, 104u8, 0u8, 122u8,
|
||||
104u8, 120u8, 122u8, 107u8, 116u8, 122u8, 108u8, 109u8, 122u8, 109u8,
|
||||
105u8, 122u8, 117u8, 0u8, 122u8, 122u8, 97u8,
|
||||
])
|
||||
},
|
||||
unsafe {
|
||||
::zerovec::ZeroVec::from_bytes_unchecked(&[
|
||||
69u8, 84u8, 0u8, 71u8, 69u8, 0u8, 71u8, 72u8, 0u8, 73u8, 68u8, 0u8, 85u8,
|
||||
71u8, 0u8, 71u8, 72u8, 0u8, 66u8, 84u8, 0u8, 82u8, 85u8, 0u8, 73u8, 82u8,
|
||||
0u8, 84u8, 78u8, 0u8, 90u8, 65u8, 0u8, 67u8, 77u8, 0u8, 73u8, 78u8, 0u8,
|
||||
84u8, 78u8, 0u8, 71u8, 72u8, 0u8, 73u8, 81u8, 0u8, 88u8, 75u8, 0u8, 82u8,
|
||||
85u8, 0u8, 69u8, 84u8, 0u8, 78u8, 71u8, 0u8, 69u8, 83u8, 0u8, 78u8, 71u8,
|
||||
0u8, 73u8, 68u8, 0u8, 84u8, 71u8, 0u8, 69u8, 71u8, 0u8, 73u8, 82u8, 0u8,
|
||||
67u8, 76u8, 0u8, 66u8, 79u8, 0u8, 68u8, 90u8, 0u8, 83u8, 65u8, 0u8, 77u8,
|
||||
65u8, 0u8, 69u8, 71u8, 0u8, 73u8, 78u8, 0u8, 84u8, 90u8, 0u8, 85u8, 83u8,
|
||||
0u8, 69u8, 83u8, 0u8, 67u8, 65u8, 0u8, 82u8, 85u8, 0u8, 73u8, 78u8, 0u8,
|
||||
66u8, 79u8, 0u8, 65u8, 90u8, 0u8, 82u8, 85u8, 0u8, 80u8, 75u8, 0u8, 73u8,
|
||||
68u8, 0u8, 78u8, 80u8, 0u8, 65u8, 84u8, 0u8, 67u8, 77u8, 0u8, 67u8, 77u8,
|
||||
0u8, 73u8, 68u8, 0u8, 67u8, 77u8, 0u8, 67u8, 73u8, 0u8, 66u8, 89u8, 0u8,
|
||||
83u8, 68u8, 0u8, 90u8, 77u8, 0u8, 73u8, 68u8, 0u8, 84u8, 90u8, 0u8, 67u8,
|
||||
77u8, 0u8, 73u8, 78u8, 0u8, 80u8, 75u8, 0u8, 73u8, 78u8, 0u8, 66u8, 71u8,
|
||||
0u8, 73u8, 78u8, 0u8, 80u8, 75u8, 0u8, 84u8, 82u8, 0u8, 73u8, 78u8, 0u8,
|
||||
73u8, 78u8, 0u8, 73u8, 78u8, 0u8, 86u8, 85u8, 0u8, 80u8, 72u8, 0u8, 78u8,
|
||||
71u8, 0u8, 73u8, 78u8, 0u8, 73u8, 68u8, 0u8, 83u8, 78u8, 0u8, 67u8, 77u8,
|
||||
0u8, 80u8, 72u8, 0u8, 67u8, 65u8, 0u8, 77u8, 89u8, 0u8, 86u8, 78u8, 0u8,
|
||||
77u8, 76u8, 0u8, 77u8, 76u8, 0u8, 66u8, 68u8, 0u8, 67u8, 78u8, 0u8, 73u8,
|
||||
78u8, 0u8, 73u8, 82u8, 0u8, 67u8, 73u8, 0u8, 70u8, 82u8, 0u8, 73u8, 78u8,
|
||||
0u8, 80u8, 75u8, 0u8, 73u8, 78u8, 0u8, 66u8, 65u8, 0u8, 76u8, 82u8, 0u8,
|
||||
67u8, 77u8, 0u8, 80u8, 72u8, 0u8, 80u8, 75u8, 0u8, 82u8, 85u8, 0u8, 89u8,
|
||||
84u8, 0u8, 73u8, 68u8, 0u8, 67u8, 77u8, 0u8, 71u8, 81u8, 0u8, 69u8, 82u8,
|
||||
0u8, 67u8, 77u8, 0u8, 77u8, 76u8, 0u8, 69u8, 83u8, 0u8, 85u8, 83u8, 0u8,
|
||||
78u8, 71u8, 0u8, 66u8, 68u8, 0u8, 82u8, 85u8, 0u8, 80u8, 72u8, 0u8, 85u8,
|
||||
71u8, 0u8, 71u8, 85u8, 0u8, 70u8, 77u8, 0u8, 82u8, 85u8, 0u8, 85u8, 83u8,
|
||||
0u8, 67u8, 65u8, 0u8, 85u8, 83u8, 0u8, 85u8, 83u8, 0u8, 75u8, 72u8, 0u8,
|
||||
86u8, 78u8, 0u8, 73u8, 81u8, 0u8, 67u8, 65u8, 0u8, 77u8, 78u8, 0u8, 70u8,
|
||||
82u8, 0u8, 69u8, 71u8, 0u8, 80u8, 72u8, 0u8, 67u8, 65u8, 0u8, 67u8, 65u8,
|
||||
0u8, 85u8, 65u8, 0u8, 67u8, 65u8, 0u8, 67u8, 65u8, 0u8, 83u8, 67u8, 0u8,
|
||||
67u8, 90u8, 0u8, 80u8, 76u8, 0u8, 67u8, 65u8, 0u8, 77u8, 77u8, 0u8, 82u8,
|
||||
85u8, 0u8, 82u8, 85u8, 0u8, 71u8, 66u8, 0u8, 68u8, 75u8, 0u8, 67u8, 73u8,
|
||||
0u8, 85u8, 83u8, 0u8, 82u8, 85u8, 0u8, 75u8, 69u8, 0u8, 73u8, 78u8, 0u8,
|
||||
68u8, 69u8, 0u8, 67u8, 65u8, 0u8, 67u8, 65u8, 0u8, 78u8, 69u8, 0u8, 78u8,
|
||||
71u8, 0u8, 67u8, 73u8, 0u8, 73u8, 78u8, 0u8, 67u8, 78u8, 0u8, 68u8, 69u8,
|
||||
0u8, 77u8, 76u8, 0u8, 77u8, 89u8, 0u8, 78u8, 80u8, 0u8, 67u8, 77u8, 0u8,
|
||||
77u8, 86u8, 0u8, 83u8, 78u8, 0u8, 66u8, 70u8, 0u8, 66u8, 84u8, 0u8, 75u8,
|
||||
69u8, 0u8, 71u8, 72u8, 0u8, 78u8, 71u8, 0u8, 73u8, 84u8, 0u8, 69u8, 71u8,
|
||||
0u8, 77u8, 77u8, 0u8, 71u8, 82u8, 0u8, 85u8, 83u8, 0u8, 48u8, 48u8, 49u8,
|
||||
69u8, 83u8, 0u8, 73u8, 78u8, 0u8, 85u8, 83u8, 0u8, 69u8, 69u8, 0u8, 73u8,
|
||||
84u8, 0u8, 69u8, 83u8, 0u8, 67u8, 77u8, 0u8, 69u8, 83u8, 0u8, 73u8, 82u8,
|
||||
0u8, 71u8, 81u8, 0u8, 83u8, 78u8, 0u8, 77u8, 76u8, 0u8, 70u8, 73u8, 0u8,
|
||||
83u8, 68u8, 0u8, 80u8, 72u8, 0u8, 83u8, 69u8, 0u8, 70u8, 74u8, 0u8, 70u8,
|
||||
79u8, 0u8, 66u8, 74u8, 0u8, 70u8, 82u8, 0u8, 85u8, 83u8, 0u8, 70u8, 82u8,
|
||||
0u8, 68u8, 69u8, 0u8, 68u8, 69u8, 0u8, 67u8, 77u8, 0u8, 87u8, 70u8, 0u8,
|
||||
71u8, 78u8, 0u8, 78u8, 69u8, 0u8, 73u8, 84u8, 0u8, 78u8, 71u8, 0u8, 83u8,
|
||||
68u8, 0u8, 78u8, 76u8, 0u8, 73u8, 69u8, 0u8, 71u8, 72u8, 0u8, 77u8, 68u8,
|
||||
0u8, 67u8, 78u8, 0u8, 73u8, 68u8, 0u8, 73u8, 78u8, 0u8, 73u8, 82u8, 0u8,
|
||||
71u8, 70u8, 0u8, 71u8, 66u8, 0u8, 69u8, 84u8, 0u8, 78u8, 80u8, 0u8, 75u8,
|
||||
73u8, 0u8, 80u8, 75u8, 0u8, 80u8, 75u8, 0u8, 69u8, 83u8, 0u8, 73u8, 82u8,
|
||||
0u8, 80u8, 89u8, 0u8, 73u8, 78u8, 0u8, 73u8, 78u8, 0u8, 73u8, 68u8, 0u8,
|
||||
78u8, 76u8, 0u8, 85u8, 65u8, 0u8, 67u8, 89u8, 0u8, 73u8, 78u8, 0u8, 67u8,
|
||||
72u8, 0u8, 73u8, 78u8, 0u8, 66u8, 82u8, 0u8, 67u8, 79u8, 0u8, 71u8, 72u8,
|
||||
0u8, 75u8, 69u8, 0u8, 73u8, 77u8, 0u8, 78u8, 80u8, 0u8, 67u8, 65u8, 0u8,
|
||||
78u8, 71u8, 0u8, 67u8, 78u8, 0u8, 85u8, 83u8, 0u8, 65u8, 70u8, 0u8, 73u8,
|
||||
76u8, 0u8, 73u8, 78u8, 0u8, 70u8, 74u8, 0u8, 80u8, 72u8, 0u8, 84u8, 82u8,
|
||||
0u8, 67u8, 78u8, 0u8, 80u8, 75u8, 0u8, 73u8, 78u8, 0u8, 85u8, 83u8, 0u8,
|
||||
80u8, 72u8, 0u8, 80u8, 75u8, 0u8, 80u8, 71u8, 0u8, 73u8, 78u8, 0u8, 73u8,
|
||||
78u8, 0u8, 72u8, 82u8, 0u8, 68u8, 69u8, 0u8, 67u8, 78u8, 0u8, 72u8, 84u8,
|
||||
0u8, 72u8, 85u8, 0u8, 67u8, 65u8, 0u8, 65u8, 77u8, 0u8, 78u8, 65u8, 0u8,
|
||||
48u8, 48u8, 49u8, 77u8, 89u8, 0u8, 78u8, 71u8, 0u8, 73u8, 68u8, 0u8, 84u8,
|
||||
71u8, 0u8, 78u8, 71u8, 0u8, 67u8, 78u8, 0u8, 85u8, 83u8, 0u8, 80u8, 72u8,
|
||||
0u8, 73u8, 68u8, 0u8, 82u8, 85u8, 0u8, 48u8, 48u8, 49u8, 73u8, 83u8, 0u8,
|
||||
73u8, 84u8, 0u8, 67u8, 65u8, 0u8, 73u8, 76u8, 0u8, 82u8, 85u8, 0u8, 74u8,
|
||||
80u8, 0u8, 74u8, 77u8, 0u8, 48u8, 48u8, 49u8, 67u8, 77u8, 0u8, 85u8, 65u8,
|
||||
0u8, 84u8, 90u8, 0u8, 78u8, 80u8, 0u8, 68u8, 75u8, 0u8, 73u8, 68u8, 0u8,
|
||||
73u8, 68u8, 0u8, 71u8, 69u8, 0u8, 85u8, 90u8, 0u8, 68u8, 90u8, 0u8, 77u8,
|
||||
77u8, 0u8, 78u8, 71u8, 0u8, 75u8, 69u8, 0u8, 77u8, 76u8, 0u8, 73u8, 68u8,
|
||||
0u8, 82u8, 85u8, 0u8, 78u8, 69u8, 0u8, 78u8, 71u8, 0u8, 90u8, 87u8, 0u8,
|
||||
84u8, 90u8, 0u8, 84u8, 71u8, 0u8, 84u8, 72u8, 0u8, 67u8, 86u8, 0u8, 67u8,
|
||||
77u8, 0u8, 67u8, 73u8, 0u8, 73u8, 78u8, 0u8, 73u8, 78u8, 0u8, 67u8, 68u8,
|
||||
0u8, 73u8, 68u8, 0u8, 66u8, 82u8, 0u8, 73u8, 78u8, 0u8, 67u8, 78u8, 0u8,
|
||||
73u8, 78u8, 0u8, 77u8, 76u8, 0u8, 73u8, 78u8, 0u8, 80u8, 75u8, 0u8, 75u8,
|
||||
69u8, 0u8, 84u8, 82u8, 0u8, 78u8, 65u8, 0u8, 76u8, 65u8, 0u8, 75u8, 90u8,
|
||||
0u8, 67u8, 77u8, 0u8, 71u8, 76u8, 0u8, 75u8, 69u8, 0u8, 75u8, 72u8, 0u8,
|
||||
65u8, 79u8, 0u8, 73u8, 78u8, 0u8, 71u8, 87u8, 0u8, 75u8, 82u8, 0u8, 82u8,
|
||||
85u8, 0u8, 73u8, 78u8, 0u8, 70u8, 77u8, 0u8, 76u8, 82u8, 0u8, 82u8, 85u8,
|
||||
0u8, 83u8, 76u8, 0u8, 80u8, 72u8, 0u8, 82u8, 85u8, 0u8, 73u8, 78u8, 0u8,
|
||||
73u8, 78u8, 0u8, 84u8, 90u8, 0u8, 67u8, 77u8, 0u8, 68u8, 69u8, 0u8, 77u8,
|
||||
89u8, 0u8, 84u8, 82u8, 0u8, 82u8, 85u8, 0u8, 82u8, 85u8, 0u8, 73u8, 68u8,
|
||||
0u8, 80u8, 75u8, 0u8, 71u8, 66u8, 0u8, 67u8, 65u8, 0u8, 73u8, 78u8, 0u8,
|
||||
84u8, 72u8, 0u8, 80u8, 75u8, 0u8, 75u8, 71u8, 0u8, 77u8, 89u8, 0u8, 77u8,
|
||||
89u8, 0u8, 86u8, 65u8, 0u8, 71u8, 82u8, 0u8, 73u8, 76u8, 0u8, 84u8, 90u8,
|
||||
0u8, 80u8, 75u8, 0u8, 85u8, 71u8, 0u8, 76u8, 85u8, 0u8, 82u8, 85u8, 0u8,
|
||||
73u8, 68u8, 0u8, 67u8, 78u8, 0u8, 73u8, 78u8, 0u8, 82u8, 85u8, 0u8, 85u8,
|
||||
71u8, 0u8, 78u8, 76u8, 0u8, 78u8, 80u8, 0u8, 73u8, 84u8, 0u8, 67u8, 65u8,
|
||||
0u8, 67u8, 78u8, 0u8, 73u8, 68u8, 0u8, 73u8, 82u8, 0u8, 85u8, 83u8, 0u8,
|
||||
73u8, 78u8, 0u8, 73u8, 84u8, 0u8, 67u8, 68u8, 0u8, 76u8, 65u8, 0u8, 67u8,
|
||||
68u8, 0u8, 90u8, 77u8, 0u8, 73u8, 82u8, 0u8, 76u8, 84u8, 0u8, 76u8, 86u8,
|
||||
0u8, 67u8, 68u8, 0u8, 67u8, 68u8, 0u8, 75u8, 69u8, 0u8, 75u8, 69u8, 0u8,
|
||||
73u8, 82u8, 0u8, 76u8, 86u8, 0u8, 84u8, 72u8, 0u8, 67u8, 78u8, 0u8, 84u8,
|
||||
82u8, 0u8, 73u8, 68u8, 0u8, 67u8, 77u8, 0u8, 73u8, 78u8, 0u8, 73u8, 78u8,
|
||||
0u8, 73u8, 68u8, 0u8, 71u8, 77u8, 0u8, 75u8, 69u8, 0u8, 77u8, 88u8, 0u8,
|
||||
82u8, 85u8, 0u8, 80u8, 72u8, 0u8, 73u8, 68u8, 0u8, 83u8, 76u8, 0u8, 75u8,
|
||||
69u8, 0u8, 84u8, 72u8, 0u8, 77u8, 85u8, 0u8, 77u8, 71u8, 0u8, 77u8, 90u8,
|
||||
0u8, 67u8, 77u8, 0u8, 78u8, 80u8, 0u8, 84u8, 90u8, 0u8, 77u8, 72u8, 0u8,
|
||||
78u8, 90u8, 0u8, 67u8, 65u8, 0u8, 73u8, 68u8, 0u8, 77u8, 75u8, 0u8, 73u8,
|
||||
78u8, 0u8, 83u8, 68u8, 0u8, 77u8, 78u8, 0u8, 73u8, 78u8, 0u8, 77u8, 77u8,
|
||||
0u8, 82u8, 79u8, 0u8, 67u8, 65u8, 0u8, 67u8, 65u8, 0u8, 66u8, 70u8, 0u8,
|
||||
73u8, 78u8, 0u8, 78u8, 80u8, 0u8, 82u8, 85u8, 0u8, 66u8, 68u8, 0u8, 77u8,
|
||||
89u8, 0u8, 77u8, 84u8, 0u8, 73u8, 78u8, 0u8, 67u8, 77u8, 0u8, 85u8, 83u8,
|
||||
0u8, 80u8, 75u8, 0u8, 77u8, 76u8, 0u8, 73u8, 78u8, 0u8, 73u8, 68u8, 0u8,
|
||||
85u8, 83u8, 0u8, 90u8, 87u8, 0u8, 77u8, 77u8, 0u8, 82u8, 85u8, 0u8, 85u8,
|
||||
71u8, 0u8, 73u8, 82u8, 0u8, 73u8, 82u8, 0u8, 78u8, 82u8, 0u8, 67u8, 78u8,
|
||||
0u8, 73u8, 84u8, 0u8, 78u8, 65u8, 0u8, 78u8, 79u8, 0u8, 77u8, 88u8, 0u8,
|
||||
90u8, 87u8, 0u8, 77u8, 90u8, 0u8, 68u8, 69u8, 0u8, 78u8, 80u8, 0u8, 78u8,
|
||||
80u8, 0u8, 78u8, 65u8, 0u8, 77u8, 90u8, 0u8, 77u8, 88u8, 0u8, 77u8, 88u8,
|
||||
0u8, 73u8, 68u8, 0u8, 78u8, 85u8, 0u8, 73u8, 78u8, 0u8, 78u8, 76u8, 0u8,
|
||||
67u8, 77u8, 0u8, 78u8, 79u8, 0u8, 67u8, 77u8, 0u8, 73u8, 78u8, 0u8, 78u8,
|
||||
79u8, 0u8, 84u8, 72u8, 0u8, 73u8, 78u8, 0u8, 83u8, 69u8, 0u8, 71u8, 78u8,
|
||||
0u8, 90u8, 65u8, 0u8, 67u8, 65u8, 0u8, 90u8, 65u8, 0u8, 73u8, 78u8, 0u8,
|
||||
83u8, 83u8, 0u8, 85u8, 83u8, 0u8, 67u8, 78u8, 0u8, 77u8, 87u8, 0u8, 84u8,
|
||||
90u8, 0u8, 85u8, 71u8, 0u8, 71u8, 72u8, 0u8, 70u8, 82u8, 0u8, 67u8, 65u8,
|
||||
0u8, 67u8, 65u8, 0u8, 67u8, 65u8, 0u8, 69u8, 84u8, 0u8, 73u8, 78u8, 0u8,
|
||||
71u8, 69u8, 0u8, 85u8, 83u8, 0u8, 77u8, 78u8, 0u8, 49u8, 52u8, 51u8, 73u8,
|
||||
78u8, 0u8, 80u8, 72u8, 0u8, 73u8, 82u8, 0u8, 80u8, 72u8, 0u8, 65u8, 87u8,
|
||||
0u8, 80u8, 87u8, 0u8, 70u8, 82u8, 0u8, 78u8, 71u8, 0u8, 85u8, 83u8, 0u8,
|
||||
67u8, 65u8, 0u8, 73u8, 82u8, 0u8, 68u8, 69u8, 0u8, 76u8, 66u8, 0u8, 83u8,
|
||||
66u8, 0u8, 73u8, 78u8, 0u8, 75u8, 69u8, 0u8, 80u8, 76u8, 0u8, 73u8, 84u8,
|
||||
0u8, 71u8, 82u8, 0u8, 70u8, 77u8, 0u8, 73u8, 78u8, 0u8, 67u8, 65u8, 0u8,
|
||||
80u8, 75u8, 0u8, 73u8, 82u8, 0u8, 48u8, 48u8, 49u8, 65u8, 70u8, 0u8, 66u8,
|
||||
82u8, 0u8, 71u8, 65u8, 0u8, 80u8, 69u8, 0u8, 71u8, 84u8, 0u8, 69u8, 67u8,
|
||||
0u8, 73u8, 78u8, 0u8, 82u8, 69u8, 0u8, 73u8, 68u8, 0u8, 73u8, 84u8, 0u8,
|
||||
77u8, 77u8, 0u8, 73u8, 78u8, 0u8, 77u8, 65u8, 0u8, 78u8, 80u8, 0u8, 66u8,
|
||||
68u8, 0u8, 67u8, 72u8, 0u8, 70u8, 73u8, 0u8, 67u8, 72u8, 0u8, 73u8, 82u8,
|
||||
0u8, 83u8, 69u8, 0u8, 66u8, 73u8, 0u8, 77u8, 90u8, 0u8, 82u8, 79u8, 0u8,
|
||||
73u8, 68u8, 0u8, 84u8, 90u8, 0u8, 70u8, 74u8, 0u8, 82u8, 85u8, 0u8, 85u8,
|
||||
65u8, 0u8, 83u8, 66u8, 0u8, 82u8, 87u8, 0u8, 84u8, 90u8, 0u8, 74u8, 80u8,
|
||||
0u8, 73u8, 78u8, 0u8, 71u8, 72u8, 0u8, 82u8, 85u8, 0u8, 75u8, 69u8, 0u8,
|
||||
73u8, 68u8, 0u8, 73u8, 78u8, 0u8, 83u8, 78u8, 0u8, 73u8, 78u8, 0u8, 84u8,
|
||||
90u8, 0u8, 73u8, 84u8, 0u8, 73u8, 78u8, 0u8, 73u8, 84u8, 0u8, 71u8, 66u8,
|
||||
0u8, 80u8, 75u8, 0u8, 73u8, 84u8, 0u8, 73u8, 82u8, 0u8, 78u8, 79u8, 0u8,
|
||||
67u8, 73u8, 0u8, 77u8, 90u8, 0u8, 77u8, 88u8, 0u8, 77u8, 76u8, 0u8, 67u8,
|
||||
70u8, 0u8, 73u8, 69u8, 0u8, 76u8, 84u8, 0u8, 77u8, 65u8, 0u8, 77u8, 77u8,
|
||||
0u8, 76u8, 75u8, 0u8, 69u8, 84u8, 0u8, 83u8, 75u8, 0u8, 80u8, 75u8, 0u8,
|
||||
83u8, 73u8, 0u8, 80u8, 76u8, 0u8, 73u8, 68u8, 0u8, 87u8, 83u8, 0u8, 83u8,
|
||||
69u8, 0u8, 65u8, 79u8, 0u8, 83u8, 69u8, 0u8, 70u8, 73u8, 0u8, 73u8, 76u8,
|
||||
0u8, 70u8, 73u8, 0u8, 90u8, 87u8, 0u8, 77u8, 89u8, 0u8, 77u8, 76u8, 0u8,
|
||||
83u8, 79u8, 0u8, 85u8, 90u8, 0u8, 84u8, 72u8, 0u8, 65u8, 76u8, 0u8, 82u8,
|
||||
83u8, 0u8, 73u8, 78u8, 0u8, 83u8, 82u8, 0u8, 83u8, 78u8, 0u8, 73u8, 78u8,
|
||||
0u8, 90u8, 65u8, 0u8, 69u8, 82u8, 0u8, 90u8, 65u8, 0u8, 68u8, 69u8, 0u8,
|
||||
73u8, 68u8, 0u8, 84u8, 90u8, 0u8, 71u8, 78u8, 0u8, 83u8, 69u8, 0u8, 84u8,
|
||||
90u8, 0u8, 89u8, 84u8, 0u8, 67u8, 68u8, 0u8, 68u8, 69u8, 0u8, 73u8, 78u8,
|
||||
0u8, 73u8, 68u8, 0u8, 66u8, 68u8, 0u8, 73u8, 81u8, 0u8, 80u8, 76u8, 0u8,
|
||||
73u8, 78u8, 0u8, 78u8, 80u8, 0u8, 80u8, 72u8, 0u8, 73u8, 78u8, 0u8, 67u8,
|
||||
78u8, 0u8, 78u8, 80u8, 0u8, 78u8, 80u8, 0u8, 77u8, 89u8, 0u8, 73u8, 78u8,
|
||||
0u8, 83u8, 76u8, 0u8, 85u8, 71u8, 0u8, 84u8, 76u8, 0u8, 84u8, 74u8, 0u8,
|
||||
84u8, 72u8, 0u8, 78u8, 80u8, 0u8, 78u8, 80u8, 0u8, 78u8, 80u8, 0u8, 69u8,
|
||||
84u8, 0u8, 69u8, 82u8, 0u8, 78u8, 71u8, 0u8, 84u8, 77u8, 0u8, 84u8, 75u8,
|
||||
0u8, 65u8, 90u8, 0u8, 78u8, 80u8, 0u8, 80u8, 72u8, 0u8, 65u8, 90u8, 0u8,
|
||||
78u8, 69u8, 0u8, 90u8, 65u8, 0u8, 84u8, 79u8, 0u8, 77u8, 87u8, 0u8, 48u8,
|
||||
48u8, 49u8, 80u8, 71u8, 0u8, 84u8, 82u8, 0u8, 84u8, 82u8, 0u8, 84u8, 87u8,
|
||||
0u8, 80u8, 75u8, 0u8, 90u8, 65u8, 0u8, 71u8, 82u8, 0u8, 78u8, 80u8, 0u8,
|
||||
80u8, 72u8, 0u8, 66u8, 84u8, 0u8, 82u8, 85u8, 0u8, 85u8, 71u8, 0u8, 84u8,
|
||||
72u8, 0u8, 65u8, 90u8, 0u8, 77u8, 87u8, 0u8, 84u8, 86u8, 0u8, 78u8, 69u8,
|
||||
0u8, 67u8, 78u8, 0u8, 73u8, 78u8, 0u8, 80u8, 70u8, 0u8, 82u8, 85u8, 0u8,
|
||||
77u8, 65u8, 0u8, 82u8, 85u8, 0u8, 82u8, 85u8, 0u8, 67u8, 78u8, 0u8, 83u8,
|
||||
89u8, 0u8, 85u8, 65u8, 0u8, 70u8, 77u8, 0u8, 65u8, 79u8, 0u8, 73u8, 78u8,
|
||||
0u8, 73u8, 78u8, 0u8, 80u8, 75u8, 0u8, 85u8, 90u8, 0u8, 76u8, 82u8, 0u8,
|
||||
90u8, 65u8, 0u8, 73u8, 84u8, 0u8, 82u8, 85u8, 0u8, 86u8, 78u8, 0u8, 83u8,
|
||||
88u8, 0u8, 66u8, 69u8, 0u8, 68u8, 69u8, 0u8, 77u8, 90u8, 0u8, 48u8, 48u8,
|
||||
49u8, 82u8, 85u8, 0u8, 69u8, 69u8, 0u8, 84u8, 90u8, 0u8, 66u8, 69u8, 0u8,
|
||||
67u8, 72u8, 0u8, 69u8, 84u8, 0u8, 80u8, 72u8, 0u8, 65u8, 85u8, 0u8, 73u8,
|
||||
78u8, 0u8, 73u8, 78u8, 0u8, 87u8, 70u8, 0u8, 75u8, 77u8, 0u8, 83u8, 78u8,
|
||||
0u8, 73u8, 78u8, 0u8, 73u8, 78u8, 0u8, 67u8, 78u8, 0u8, 66u8, 82u8, 0u8,
|
||||
85u8, 90u8, 0u8, 84u8, 82u8, 0u8, 90u8, 65u8, 0u8, 84u8, 82u8, 0u8, 84u8,
|
||||
82u8, 0u8, 71u8, 69u8, 0u8, 67u8, 78u8, 0u8, 83u8, 68u8, 0u8, 83u8, 65u8,
|
||||
0u8, 73u8, 78u8, 0u8, 85u8, 71u8, 0u8, 73u8, 82u8, 0u8, 89u8, 69u8, 0u8,
|
||||
78u8, 80u8, 0u8, 77u8, 90u8, 0u8, 70u8, 77u8, 0u8, 67u8, 77u8, 0u8, 67u8,
|
||||
77u8, 0u8, 48u8, 48u8, 49u8, 78u8, 71u8, 0u8, 66u8, 82u8, 0u8, 77u8, 88u8,
|
||||
0u8, 72u8, 75u8, 0u8, 67u8, 78u8, 0u8, 83u8, 68u8, 0u8, 75u8, 77u8, 0u8,
|
||||
78u8, 76u8, 0u8, 77u8, 65u8, 0u8, 67u8, 78u8, 0u8, 67u8, 78u8, 0u8, 67u8,
|
||||
78u8, 0u8, 84u8, 71u8, 0u8, 77u8, 89u8, 0u8, 90u8, 65u8, 0u8, 84u8, 82u8,
|
||||
0u8,
|
||||
])
|
||||
},
|
||||
)
|
||||
},
|
||||
ls2r: unsafe {
|
||||
#[allow(unused_unsafe)]
|
||||
::zerovec::ZeroMap2d::from_parts_unchecked(
|
||||
unsafe {
|
||||
::zerovec::ZeroVec::from_bytes_unchecked(&[
|
||||
97u8, 114u8, 99u8, 97u8, 122u8, 0u8, 99u8, 117u8, 0u8, 101u8, 110u8, 0u8,
|
||||
102u8, 102u8, 0u8, 103u8, 114u8, 99u8, 107u8, 107u8, 0u8, 107u8, 117u8,
|
||||
0u8, 107u8, 121u8, 0u8, 108u8, 105u8, 102u8, 109u8, 97u8, 110u8, 109u8,
|
||||
110u8, 0u8, 112u8, 97u8, 0u8, 112u8, 97u8, 108u8, 115u8, 100u8, 0u8, 116u8,
|
||||
103u8, 0u8, 117u8, 103u8, 0u8, 117u8, 110u8, 114u8, 117u8, 122u8, 0u8,
|
||||
121u8, 117u8, 101u8, 122u8, 104u8, 0u8,
|
||||
])
|
||||
},
|
||||
unsafe {
|
||||
::zerovec::ZeroVec::from_bytes_unchecked(&[
|
||||
2u8, 0u8, 0u8, 0u8, 3u8, 0u8, 0u8, 0u8, 4u8, 0u8, 0u8, 0u8, 5u8, 0u8, 0u8,
|
||||
0u8, 6u8, 0u8, 0u8, 0u8, 7u8, 0u8, 0u8, 0u8, 8u8, 0u8, 0u8, 0u8, 10u8, 0u8,
|
||||
0u8, 0u8, 12u8, 0u8, 0u8, 0u8, 13u8, 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8,
|
||||
15u8, 0u8, 0u8, 0u8, 16u8, 0u8, 0u8, 0u8, 17u8, 0u8, 0u8, 0u8, 20u8, 0u8,
|
||||
0u8, 0u8, 21u8, 0u8, 0u8, 0u8, 22u8, 0u8, 0u8, 0u8, 23u8, 0u8, 0u8, 0u8,
|
||||
24u8, 0u8, 0u8, 0u8, 25u8, 0u8, 0u8, 0u8, 28u8, 0u8, 0u8, 0u8,
|
||||
])
|
||||
},
|
||||
unsafe {
|
||||
::zerovec::ZeroVec::from_bytes_unchecked(&[
|
||||
78u8, 98u8, 97u8, 116u8, 80u8, 97u8, 108u8, 109u8, 65u8, 114u8, 97u8, 98u8,
|
||||
71u8, 108u8, 97u8, 103u8, 83u8, 104u8, 97u8, 119u8, 65u8, 100u8, 108u8,
|
||||
109u8, 76u8, 105u8, 110u8, 98u8, 65u8, 114u8, 97u8, 98u8, 65u8, 114u8,
|
||||
97u8, 98u8, 89u8, 101u8, 122u8, 105u8, 65u8, 114u8, 97u8, 98u8, 76u8, 97u8,
|
||||
116u8, 110u8, 76u8, 105u8, 109u8, 98u8, 78u8, 107u8, 111u8, 111u8, 77u8,
|
||||
111u8, 110u8, 103u8, 65u8, 114u8, 97u8, 98u8, 80u8, 104u8, 108u8, 112u8,
|
||||
68u8, 101u8, 118u8, 97u8, 75u8, 104u8, 111u8, 106u8, 83u8, 105u8, 110u8,
|
||||
100u8, 65u8, 114u8, 97u8, 98u8, 67u8, 121u8, 114u8, 108u8, 68u8, 101u8,
|
||||
118u8, 97u8, 65u8, 114u8, 97u8, 98u8, 72u8, 97u8, 110u8, 115u8, 66u8,
|
||||
111u8, 112u8, 111u8, 72u8, 97u8, 110u8, 98u8, 72u8, 97u8, 110u8, 116u8,
|
||||
])
|
||||
},
|
||||
unsafe {
|
||||
::zerovec::ZeroVec::from_bytes_unchecked(&[
|
||||
74u8, 79u8, 0u8, 83u8, 89u8, 0u8, 73u8, 82u8, 0u8, 66u8, 71u8, 0u8, 71u8,
|
||||
66u8, 0u8, 71u8, 78u8, 0u8, 71u8, 82u8, 0u8, 67u8, 78u8, 0u8, 73u8, 81u8,
|
||||
0u8, 71u8, 69u8, 0u8, 67u8, 78u8, 0u8, 84u8, 82u8, 0u8, 73u8, 78u8, 0u8,
|
||||
71u8, 78u8, 0u8, 67u8, 78u8, 0u8, 80u8, 75u8, 0u8, 67u8, 78u8, 0u8, 73u8,
|
||||
78u8, 0u8, 73u8, 78u8, 0u8, 73u8, 78u8, 0u8, 80u8, 75u8, 0u8, 75u8, 90u8,
|
||||
0u8, 78u8, 80u8, 0u8, 65u8, 70u8, 0u8, 67u8, 78u8, 0u8, 84u8, 87u8, 0u8,
|
||||
84u8, 87u8, 0u8, 84u8, 87u8, 0u8,
|
||||
])
|
||||
},
|
||||
)
|
||||
},
|
||||
};
|
||||
4
compiler/rustc_baked_icu_data/src/data/fallback/mod.rs
Normal file
4
compiler/rustc_baked_icu_data/src/data/fallback/mod.rs
Normal file
@ -0,0 +1,4 @@
|
||||
// @generated
|
||||
pub mod likelysubtags_v1;
|
||||
pub mod parents_v1;
|
||||
pub mod supplement;
|
||||
207
compiler/rustc_baked_icu_data/src/data/fallback/parents_v1.rs
Normal file
207
compiler/rustc_baked_icu_data/src/data/fallback/parents_v1.rs
Normal file
@ -0,0 +1,207 @@
|
||||
// @generated
|
||||
type DataStruct = < :: icu_provider_adapters :: fallback :: provider :: LocaleFallbackParentsV1Marker as :: icu_provider :: DataMarker > :: Yokeable ;
|
||||
pub static DATA: litemap::LiteMap<&str, &DataStruct, &[(&str, &DataStruct)]> =
|
||||
litemap::LiteMap::from_sorted_store_unchecked(&[("und", UND)]);
|
||||
static UND: &DataStruct = &::icu_provider_adapters::fallback::provider::LocaleFallbackParentsV1 {
|
||||
parents: unsafe {
|
||||
#[allow(unused_unsafe)]
|
||||
::zerovec::ZeroMap::from_parts_unchecked(
|
||||
unsafe {
|
||||
::zerovec::VarZeroVec::from_bytes_unchecked(&[
|
||||
131u8, 0u8, 0u8, 0u8, 0u8, 0u8, 6u8, 0u8, 11u8, 0u8, 16u8, 0u8, 21u8, 0u8,
|
||||
26u8, 0u8, 31u8, 0u8, 36u8, 0u8, 41u8, 0u8, 46u8, 0u8, 51u8, 0u8, 56u8, 0u8,
|
||||
61u8, 0u8, 66u8, 0u8, 71u8, 0u8, 76u8, 0u8, 81u8, 0u8, 86u8, 0u8, 91u8, 0u8,
|
||||
96u8, 0u8, 101u8, 0u8, 106u8, 0u8, 111u8, 0u8, 116u8, 0u8, 121u8, 0u8, 126u8,
|
||||
0u8, 131u8, 0u8, 136u8, 0u8, 141u8, 0u8, 146u8, 0u8, 151u8, 0u8, 156u8, 0u8,
|
||||
161u8, 0u8, 166u8, 0u8, 171u8, 0u8, 176u8, 0u8, 181u8, 0u8, 186u8, 0u8, 191u8,
|
||||
0u8, 196u8, 0u8, 201u8, 0u8, 206u8, 0u8, 211u8, 0u8, 216u8, 0u8, 221u8, 0u8,
|
||||
226u8, 0u8, 231u8, 0u8, 236u8, 0u8, 241u8, 0u8, 246u8, 0u8, 251u8, 0u8, 0u8,
|
||||
1u8, 5u8, 1u8, 10u8, 1u8, 15u8, 1u8, 20u8, 1u8, 25u8, 1u8, 30u8, 1u8, 35u8,
|
||||
1u8, 40u8, 1u8, 45u8, 1u8, 50u8, 1u8, 55u8, 1u8, 60u8, 1u8, 65u8, 1u8, 70u8,
|
||||
1u8, 75u8, 1u8, 80u8, 1u8, 85u8, 1u8, 90u8, 1u8, 95u8, 1u8, 100u8, 1u8, 105u8,
|
||||
1u8, 110u8, 1u8, 115u8, 1u8, 120u8, 1u8, 125u8, 1u8, 130u8, 1u8, 135u8, 1u8,
|
||||
140u8, 1u8, 145u8, 1u8, 150u8, 1u8, 155u8, 1u8, 160u8, 1u8, 165u8, 1u8, 170u8,
|
||||
1u8, 175u8, 1u8, 180u8, 1u8, 185u8, 1u8, 190u8, 1u8, 195u8, 1u8, 200u8, 1u8,
|
||||
205u8, 1u8, 210u8, 1u8, 215u8, 1u8, 220u8, 1u8, 225u8, 1u8, 230u8, 1u8, 235u8,
|
||||
1u8, 240u8, 1u8, 245u8, 1u8, 250u8, 1u8, 255u8, 1u8, 4u8, 2u8, 9u8, 2u8, 14u8,
|
||||
2u8, 19u8, 2u8, 24u8, 2u8, 29u8, 2u8, 34u8, 2u8, 39u8, 2u8, 44u8, 2u8, 49u8,
|
||||
2u8, 54u8, 2u8, 59u8, 2u8, 64u8, 2u8, 71u8, 2u8, 73u8, 2u8, 75u8, 2u8, 77u8,
|
||||
2u8, 82u8, 2u8, 87u8, 2u8, 92u8, 2u8, 97u8, 2u8, 102u8, 2u8, 107u8, 2u8, 112u8,
|
||||
2u8, 117u8, 2u8, 122u8, 2u8, 127u8, 2u8, 132u8, 2u8, 101u8, 110u8, 45u8, 49u8,
|
||||
53u8, 48u8, 101u8, 110u8, 45u8, 65u8, 71u8, 101u8, 110u8, 45u8, 65u8, 73u8,
|
||||
101u8, 110u8, 45u8, 65u8, 84u8, 101u8, 110u8, 45u8, 65u8, 85u8, 101u8, 110u8,
|
||||
45u8, 66u8, 66u8, 101u8, 110u8, 45u8, 66u8, 69u8, 101u8, 110u8, 45u8, 66u8,
|
||||
77u8, 101u8, 110u8, 45u8, 66u8, 83u8, 101u8, 110u8, 45u8, 66u8, 87u8, 101u8,
|
||||
110u8, 45u8, 66u8, 90u8, 101u8, 110u8, 45u8, 67u8, 67u8, 101u8, 110u8, 45u8,
|
||||
67u8, 72u8, 101u8, 110u8, 45u8, 67u8, 75u8, 101u8, 110u8, 45u8, 67u8, 77u8,
|
||||
101u8, 110u8, 45u8, 67u8, 88u8, 101u8, 110u8, 45u8, 67u8, 89u8, 101u8, 110u8,
|
||||
45u8, 68u8, 69u8, 101u8, 110u8, 45u8, 68u8, 71u8, 101u8, 110u8, 45u8, 68u8,
|
||||
75u8, 101u8, 110u8, 45u8, 68u8, 77u8, 101u8, 110u8, 45u8, 69u8, 82u8, 101u8,
|
||||
110u8, 45u8, 70u8, 73u8, 101u8, 110u8, 45u8, 70u8, 74u8, 101u8, 110u8, 45u8,
|
||||
70u8, 75u8, 101u8, 110u8, 45u8, 70u8, 77u8, 101u8, 110u8, 45u8, 71u8, 66u8,
|
||||
101u8, 110u8, 45u8, 71u8, 68u8, 101u8, 110u8, 45u8, 71u8, 71u8, 101u8, 110u8,
|
||||
45u8, 71u8, 72u8, 101u8, 110u8, 45u8, 71u8, 73u8, 101u8, 110u8, 45u8, 71u8,
|
||||
77u8, 101u8, 110u8, 45u8, 71u8, 89u8, 101u8, 110u8, 45u8, 72u8, 75u8, 101u8,
|
||||
110u8, 45u8, 73u8, 69u8, 101u8, 110u8, 45u8, 73u8, 76u8, 101u8, 110u8, 45u8,
|
||||
73u8, 77u8, 101u8, 110u8, 45u8, 73u8, 78u8, 101u8, 110u8, 45u8, 73u8, 79u8,
|
||||
101u8, 110u8, 45u8, 74u8, 69u8, 101u8, 110u8, 45u8, 74u8, 77u8, 101u8, 110u8,
|
||||
45u8, 75u8, 69u8, 101u8, 110u8, 45u8, 75u8, 73u8, 101u8, 110u8, 45u8, 75u8,
|
||||
78u8, 101u8, 110u8, 45u8, 75u8, 89u8, 101u8, 110u8, 45u8, 76u8, 67u8, 101u8,
|
||||
110u8, 45u8, 76u8, 82u8, 101u8, 110u8, 45u8, 76u8, 83u8, 101u8, 110u8, 45u8,
|
||||
77u8, 71u8, 101u8, 110u8, 45u8, 77u8, 79u8, 101u8, 110u8, 45u8, 77u8, 83u8,
|
||||
101u8, 110u8, 45u8, 77u8, 84u8, 101u8, 110u8, 45u8, 77u8, 85u8, 101u8, 110u8,
|
||||
45u8, 77u8, 86u8, 101u8, 110u8, 45u8, 77u8, 87u8, 101u8, 110u8, 45u8, 77u8,
|
||||
89u8, 101u8, 110u8, 45u8, 78u8, 65u8, 101u8, 110u8, 45u8, 78u8, 70u8, 101u8,
|
||||
110u8, 45u8, 78u8, 71u8, 101u8, 110u8, 45u8, 78u8, 76u8, 101u8, 110u8, 45u8,
|
||||
78u8, 82u8, 101u8, 110u8, 45u8, 78u8, 85u8, 101u8, 110u8, 45u8, 78u8, 90u8,
|
||||
101u8, 110u8, 45u8, 80u8, 71u8, 101u8, 110u8, 45u8, 80u8, 75u8, 101u8, 110u8,
|
||||
45u8, 80u8, 78u8, 101u8, 110u8, 45u8, 80u8, 87u8, 101u8, 110u8, 45u8, 82u8,
|
||||
87u8, 101u8, 110u8, 45u8, 83u8, 66u8, 101u8, 110u8, 45u8, 83u8, 67u8, 101u8,
|
||||
110u8, 45u8, 83u8, 68u8, 101u8, 110u8, 45u8, 83u8, 69u8, 101u8, 110u8, 45u8,
|
||||
83u8, 71u8, 101u8, 110u8, 45u8, 83u8, 72u8, 101u8, 110u8, 45u8, 83u8, 73u8,
|
||||
101u8, 110u8, 45u8, 83u8, 76u8, 101u8, 110u8, 45u8, 83u8, 83u8, 101u8, 110u8,
|
||||
45u8, 83u8, 88u8, 101u8, 110u8, 45u8, 83u8, 90u8, 101u8, 110u8, 45u8, 84u8,
|
||||
67u8, 101u8, 110u8, 45u8, 84u8, 75u8, 101u8, 110u8, 45u8, 84u8, 79u8, 101u8,
|
||||
110u8, 45u8, 84u8, 84u8, 101u8, 110u8, 45u8, 84u8, 86u8, 101u8, 110u8, 45u8,
|
||||
84u8, 90u8, 101u8, 110u8, 45u8, 85u8, 71u8, 101u8, 110u8, 45u8, 86u8, 67u8,
|
||||
101u8, 110u8, 45u8, 86u8, 71u8, 101u8, 110u8, 45u8, 86u8, 85u8, 101u8, 110u8,
|
||||
45u8, 87u8, 83u8, 101u8, 110u8, 45u8, 90u8, 65u8, 101u8, 110u8, 45u8, 90u8,
|
||||
77u8, 101u8, 110u8, 45u8, 90u8, 87u8, 101u8, 115u8, 45u8, 65u8, 82u8, 101u8,
|
||||
115u8, 45u8, 66u8, 79u8, 101u8, 115u8, 45u8, 66u8, 82u8, 101u8, 115u8, 45u8,
|
||||
66u8, 90u8, 101u8, 115u8, 45u8, 67u8, 76u8, 101u8, 115u8, 45u8, 67u8, 79u8,
|
||||
101u8, 115u8, 45u8, 67u8, 82u8, 101u8, 115u8, 45u8, 67u8, 85u8, 101u8, 115u8,
|
||||
45u8, 68u8, 79u8, 101u8, 115u8, 45u8, 69u8, 67u8, 101u8, 115u8, 45u8, 71u8,
|
||||
84u8, 101u8, 115u8, 45u8, 72u8, 78u8, 101u8, 115u8, 45u8, 77u8, 88u8, 101u8,
|
||||
115u8, 45u8, 78u8, 73u8, 101u8, 115u8, 45u8, 80u8, 65u8, 101u8, 115u8, 45u8,
|
||||
80u8, 69u8, 101u8, 115u8, 45u8, 80u8, 82u8, 101u8, 115u8, 45u8, 80u8, 89u8,
|
||||
101u8, 115u8, 45u8, 83u8, 86u8, 101u8, 115u8, 45u8, 85u8, 83u8, 101u8, 115u8,
|
||||
45u8, 85u8, 89u8, 101u8, 115u8, 45u8, 86u8, 69u8, 104u8, 105u8, 45u8, 76u8,
|
||||
97u8, 116u8, 110u8, 104u8, 116u8, 110u8, 98u8, 110u8, 110u8, 112u8, 116u8,
|
||||
45u8, 65u8, 79u8, 112u8, 116u8, 45u8, 67u8, 72u8, 112u8, 116u8, 45u8, 67u8,
|
||||
86u8, 112u8, 116u8, 45u8, 70u8, 82u8, 112u8, 116u8, 45u8, 71u8, 81u8, 112u8,
|
||||
116u8, 45u8, 71u8, 87u8, 112u8, 116u8, 45u8, 76u8, 85u8, 112u8, 116u8, 45u8,
|
||||
77u8, 79u8, 112u8, 116u8, 45u8, 77u8, 90u8, 112u8, 116u8, 45u8, 83u8, 84u8,
|
||||
112u8, 116u8, 45u8, 84u8, 76u8, 122u8, 104u8, 45u8, 72u8, 97u8, 110u8, 116u8,
|
||||
45u8, 77u8, 79u8,
|
||||
])
|
||||
},
|
||||
unsafe {
|
||||
::zerovec::ZeroVec::from_bytes_unchecked(&[
|
||||
101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8,
|
||||
110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8,
|
||||
0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8,
|
||||
0u8, 0u8, 0u8, 1u8, 49u8, 53u8, 48u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8,
|
||||
0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8,
|
||||
48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 49u8, 53u8,
|
||||
48u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8,
|
||||
110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8,
|
||||
0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8,
|
||||
0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8,
|
||||
0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8,
|
||||
49u8, 53u8, 48u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8,
|
||||
49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8,
|
||||
110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8,
|
||||
0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8,
|
||||
0u8, 0u8, 0u8, 1u8, 49u8, 53u8, 48u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8,
|
||||
0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8,
|
||||
49u8, 53u8, 48u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8,
|
||||
49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8,
|
||||
110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 49u8, 53u8, 48u8, 101u8, 110u8, 0u8,
|
||||
0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8,
|
||||
0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8,
|
||||
0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8,
|
||||
48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8,
|
||||
49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8,
|
||||
110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8,
|
||||
0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8,
|
||||
0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8,
|
||||
0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8,
|
||||
48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8,
|
||||
49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8,
|
||||
110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8,
|
||||
0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8,
|
||||
0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8,
|
||||
0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8,
|
||||
48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8,
|
||||
49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8,
|
||||
110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8,
|
||||
0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8,
|
||||
0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8,
|
||||
0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8,
|
||||
48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8,
|
||||
49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8,
|
||||
110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8,
|
||||
0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8,
|
||||
0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8,
|
||||
0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8,
|
||||
48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8,
|
||||
49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8,
|
||||
110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8,
|
||||
0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8,
|
||||
0u8, 0u8, 0u8, 1u8, 49u8, 53u8, 48u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8,
|
||||
0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8,
|
||||
48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8,
|
||||
49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8,
|
||||
110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8,
|
||||
0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8,
|
||||
0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8,
|
||||
0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8,
|
||||
48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8,
|
||||
49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8,
|
||||
110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 49u8, 53u8, 48u8, 101u8, 110u8, 0u8,
|
||||
0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8,
|
||||
0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8,
|
||||
0u8, 1u8, 49u8, 53u8, 48u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8,
|
||||
48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8,
|
||||
49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8,
|
||||
110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8,
|
||||
0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8,
|
||||
0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8,
|
||||
0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8,
|
||||
48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8,
|
||||
49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8,
|
||||
110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8,
|
||||
0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8,
|
||||
0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8,
|
||||
0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8,
|
||||
48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8,
|
||||
49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8,
|
||||
110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 115u8, 0u8,
|
||||
0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 52u8, 49u8, 57u8, 101u8, 115u8, 0u8, 0u8, 0u8,
|
||||
0u8, 0u8, 0u8, 1u8, 52u8, 49u8, 57u8, 101u8, 115u8, 0u8, 0u8, 0u8, 0u8, 0u8,
|
||||
0u8, 1u8, 52u8, 49u8, 57u8, 101u8, 115u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8,
|
||||
52u8, 49u8, 57u8, 101u8, 115u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 52u8, 49u8,
|
||||
57u8, 101u8, 115u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 52u8, 49u8, 57u8, 101u8,
|
||||
115u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 52u8, 49u8, 57u8, 101u8, 115u8, 0u8,
|
||||
0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 52u8, 49u8, 57u8, 101u8, 115u8, 0u8, 0u8, 0u8,
|
||||
0u8, 0u8, 0u8, 1u8, 52u8, 49u8, 57u8, 101u8, 115u8, 0u8, 0u8, 0u8, 0u8, 0u8,
|
||||
0u8, 1u8, 52u8, 49u8, 57u8, 101u8, 115u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8,
|
||||
52u8, 49u8, 57u8, 101u8, 115u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 52u8, 49u8,
|
||||
57u8, 101u8, 115u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 52u8, 49u8, 57u8, 101u8,
|
||||
115u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 52u8, 49u8, 57u8, 101u8, 115u8, 0u8,
|
||||
0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 52u8, 49u8, 57u8, 101u8, 115u8, 0u8, 0u8, 0u8,
|
||||
0u8, 0u8, 0u8, 1u8, 52u8, 49u8, 57u8, 101u8, 115u8, 0u8, 0u8, 0u8, 0u8, 0u8,
|
||||
0u8, 1u8, 52u8, 49u8, 57u8, 101u8, 115u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8,
|
||||
52u8, 49u8, 57u8, 101u8, 115u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 52u8, 49u8,
|
||||
57u8, 101u8, 115u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 52u8, 49u8, 57u8, 101u8,
|
||||
115u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 52u8, 49u8, 57u8, 101u8, 115u8, 0u8,
|
||||
0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 52u8, 49u8, 57u8, 101u8, 110u8, 0u8, 0u8, 0u8,
|
||||
0u8, 0u8, 0u8, 1u8, 73u8, 78u8, 0u8, 102u8, 114u8, 0u8, 0u8, 0u8, 0u8, 0u8,
|
||||
0u8, 1u8, 72u8, 84u8, 0u8, 110u8, 111u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
|
||||
0u8, 0u8, 0u8, 110u8, 111u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
|
||||
112u8, 116u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 80u8, 84u8, 0u8, 112u8, 116u8,
|
||||
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 80u8, 84u8, 0u8, 112u8, 116u8, 0u8, 0u8,
|
||||
0u8, 0u8, 0u8, 0u8, 1u8, 80u8, 84u8, 0u8, 112u8, 116u8, 0u8, 0u8, 0u8, 0u8,
|
||||
0u8, 0u8, 1u8, 80u8, 84u8, 0u8, 112u8, 116u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
|
||||
1u8, 80u8, 84u8, 0u8, 112u8, 116u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 80u8,
|
||||
84u8, 0u8, 112u8, 116u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 80u8, 84u8, 0u8,
|
||||
112u8, 116u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 80u8, 84u8, 0u8, 112u8, 116u8,
|
||||
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 80u8, 84u8, 0u8, 112u8, 116u8, 0u8, 0u8,
|
||||
0u8, 0u8, 0u8, 0u8, 1u8, 80u8, 84u8, 0u8, 112u8, 116u8, 0u8, 0u8, 0u8, 0u8,
|
||||
0u8, 0u8, 1u8, 80u8, 84u8, 0u8, 122u8, 104u8, 0u8, 1u8, 72u8, 97u8, 110u8,
|
||||
116u8, 1u8, 72u8, 75u8, 0u8,
|
||||
])
|
||||
},
|
||||
)
|
||||
},
|
||||
};
|
||||
@ -0,0 +1,41 @@
|
||||
// @generated
|
||||
type DataStruct = < :: icu_provider_adapters :: fallback :: provider :: CollationFallbackSupplementV1Marker as :: icu_provider :: DataMarker > :: Yokeable ;
|
||||
pub static DATA: litemap::LiteMap<&str, &DataStruct, &[(&str, &DataStruct)]> =
|
||||
litemap::LiteMap::from_sorted_store_unchecked(&[("und", UND)]);
|
||||
static UND: &DataStruct =
|
||||
&::icu_provider_adapters::fallback::provider::LocaleFallbackSupplementV1 {
|
||||
parents: unsafe {
|
||||
#[allow(unused_unsafe)]
|
||||
::zerovec::ZeroMap::from_parts_unchecked(
|
||||
unsafe {
|
||||
::zerovec::VarZeroVec::from_bytes_unchecked(&[
|
||||
1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 121u8, 117u8, 101u8,
|
||||
])
|
||||
},
|
||||
unsafe {
|
||||
::zerovec::ZeroVec::from_bytes_unchecked(&[
|
||||
122u8, 104u8, 0u8, 1u8, 72u8, 97u8, 110u8, 116u8, 0u8, 0u8, 0u8, 0u8,
|
||||
])
|
||||
},
|
||||
)
|
||||
},
|
||||
unicode_extension_defaults: unsafe {
|
||||
#[allow(unused_unsafe)]
|
||||
::zerovec::ZeroMap2d::from_parts_unchecked(
|
||||
unsafe { ::zerovec::ZeroVec::from_bytes_unchecked(&[99u8, 111u8]) },
|
||||
unsafe { ::zerovec::ZeroVec::from_bytes_unchecked(&[2u8, 0u8, 0u8, 0u8]) },
|
||||
unsafe {
|
||||
::zerovec::VarZeroVec::from_bytes_unchecked(&[
|
||||
2u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 122u8, 104u8, 122u8, 104u8, 45u8,
|
||||
72u8, 97u8, 110u8, 116u8,
|
||||
])
|
||||
},
|
||||
unsafe {
|
||||
::zerovec::VarZeroVec::from_bytes_unchecked(&[
|
||||
2u8, 0u8, 0u8, 0u8, 0u8, 0u8, 6u8, 0u8, 112u8, 105u8, 110u8, 121u8, 105u8,
|
||||
110u8, 115u8, 116u8, 114u8, 111u8, 107u8, 101u8,
|
||||
])
|
||||
},
|
||||
)
|
||||
},
|
||||
};
|
||||
@ -0,0 +1,2 @@
|
||||
// @generated
|
||||
pub mod co_v1;
|
||||
1161
compiler/rustc_baked_icu_data/src/data/list/and_v1.rs
Normal file
1161
compiler/rustc_baked_icu_data/src/data/list/and_v1.rs
Normal file
File diff suppressed because it is too large
Load Diff
2
compiler/rustc_baked_icu_data/src/data/list/mod.rs
Normal file
2
compiler/rustc_baked_icu_data/src/data/list/mod.rs
Normal file
@ -0,0 +1,2 @@
|
||||
// @generated
|
||||
pub mod and_v1;
|
||||
90
compiler/rustc_baked_icu_data/src/data/mod.rs
Normal file
90
compiler/rustc_baked_icu_data/src/data/mod.rs
Normal file
@ -0,0 +1,90 @@
|
||||
// @generated
|
||||
mod fallback;
|
||||
mod list;
|
||||
/// This data provider was programmatically generated by [`icu_datagen`](
|
||||
/// https://unicode-org.github.io/icu4x-docs/doc/icu_datagen/enum.Out.html#variant.Module).
|
||||
#[non_exhaustive]
|
||||
pub struct BakedDataProvider;
|
||||
use ::icu_provider::prelude::*;
|
||||
impl DataProvider<::icu_list::provider::AndListV1Marker> for BakedDataProvider {
|
||||
fn load(
|
||||
&self,
|
||||
req: DataRequest,
|
||||
) -> Result<DataResponse<::icu_list::provider::AndListV1Marker>, DataError> {
|
||||
Ok(DataResponse {
|
||||
metadata: Default::default(),
|
||||
payload: Some(DataPayload::from_owned(zerofrom::ZeroFrom::zero_from(
|
||||
*list::and_v1::DATA
|
||||
.get_by(|k| req.locale.strict_cmp(k.as_bytes()).reverse())
|
||||
.ok_or_else(|| {
|
||||
DataErrorKind::MissingLocale
|
||||
.with_req(::icu_list::provider::AndListV1Marker::KEY, req)
|
||||
})?,
|
||||
))),
|
||||
})
|
||||
}
|
||||
}
|
||||
impl DataProvider<::icu_provider_adapters::fallback::provider::CollationFallbackSupplementV1Marker>
|
||||
for BakedDataProvider
|
||||
{
|
||||
fn load(
|
||||
&self,
|
||||
req: DataRequest,
|
||||
) -> Result<
|
||||
DataResponse<
|
||||
::icu_provider_adapters::fallback::provider::CollationFallbackSupplementV1Marker,
|
||||
>,
|
||||
DataError,
|
||||
> {
|
||||
Ok(DataResponse {
|
||||
metadata: Default::default(),
|
||||
payload: Some(DataPayload::from_owned(zerofrom::ZeroFrom::zero_from(
|
||||
*fallback::supplement::co_v1::DATA.get_by(|k| req.locale.strict_cmp(k.as_bytes()).reverse()).ok_or_else(|| {
|
||||
DataErrorKind::MissingLocale.with_req(::icu_provider_adapters::fallback::provider::CollationFallbackSupplementV1Marker::KEY, req)
|
||||
})?,
|
||||
))),
|
||||
})
|
||||
}
|
||||
}
|
||||
impl DataProvider<::icu_provider_adapters::fallback::provider::LocaleFallbackLikelySubtagsV1Marker>
|
||||
for BakedDataProvider
|
||||
{
|
||||
fn load(
|
||||
&self,
|
||||
req: DataRequest,
|
||||
) -> Result<
|
||||
DataResponse<
|
||||
::icu_provider_adapters::fallback::provider::LocaleFallbackLikelySubtagsV1Marker,
|
||||
>,
|
||||
DataError,
|
||||
> {
|
||||
Ok(DataResponse {
|
||||
metadata: Default::default(),
|
||||
payload: Some(DataPayload::from_owned(zerofrom::ZeroFrom::zero_from(
|
||||
*fallback::likelysubtags_v1::DATA.get_by(|k| req.locale.strict_cmp(k.as_bytes()).reverse()).ok_or_else(|| {
|
||||
DataErrorKind::MissingLocale.with_req(::icu_provider_adapters::fallback::provider::LocaleFallbackLikelySubtagsV1Marker::KEY, req)
|
||||
})?,
|
||||
))),
|
||||
})
|
||||
}
|
||||
}
|
||||
impl DataProvider<::icu_provider_adapters::fallback::provider::LocaleFallbackParentsV1Marker>
|
||||
for BakedDataProvider
|
||||
{
|
||||
fn load(
|
||||
&self,
|
||||
req: DataRequest,
|
||||
) -> Result<
|
||||
DataResponse<::icu_provider_adapters::fallback::provider::LocaleFallbackParentsV1Marker>,
|
||||
DataError,
|
||||
> {
|
||||
Ok(DataResponse {
|
||||
metadata: Default::default(),
|
||||
payload: Some(DataPayload::from_owned(zerofrom::ZeroFrom::zero_from(
|
||||
*fallback::parents_v1::DATA.get_by(|k| req.locale.strict_cmp(k.as_bytes()).reverse()).ok_or_else(|| {
|
||||
DataErrorKind::MissingLocale.with_req(::icu_provider_adapters::fallback::provider::LocaleFallbackParentsV1Marker::KEY, req)
|
||||
})?,
|
||||
))),
|
||||
})
|
||||
}
|
||||
}
|
||||
46
compiler/rustc_baked_icu_data/src/lib.rs
Normal file
46
compiler/rustc_baked_icu_data/src/lib.rs
Normal file
@ -0,0 +1,46 @@
|
||||
//! This crate contains pre-baked ICU4X data, generated by `icu4x-datagen`. The tool
|
||||
//! fetches locale data from CLDR and transforms them into const code in statics that
|
||||
//! ICU4X can load, via databake. `lib.rs` in this crate is manually written, but all
|
||||
//! other code is generated.
|
||||
//!
|
||||
//! This crate can be regenerated when there's a new CLDR version, though that is unlikely
|
||||
//! to result in changes in most cases (currently this only covers list formatting data, which
|
||||
//! is rather stable). It may need to be regenerated when updating ICU4X versions, especially
|
||||
//! across major versions, in case it fails to compile after an update.
|
||||
//!
|
||||
//! It must be regenerated when adding new locales to Rust, or if Rust's usage of ICU4X
|
||||
//! grows to need more kinds of data.
|
||||
//!
|
||||
//! To regenerate the data, run this command:
|
||||
//!
|
||||
//! ```text
|
||||
//! icu4x-datagen -W --pretty --fingerprint --use-separate-crates \
|
||||
//! --format mod -l en es fr it ja pt ru tr zh zh-Hans zh-Hant \
|
||||
//! -k list/and@1 fallback/likelysubtags@1 fallback/parents@1 fallback/supplement/co@1 \
|
||||
//! --cldr-tag latest --icuexport-tag latest -o src/data
|
||||
//! ```
|
||||
#![allow(elided_lifetimes_in_paths)]
|
||||
|
||||
mod data {
|
||||
include!("data/mod.rs");
|
||||
include!("data/any.rs");
|
||||
}
|
||||
|
||||
pub use data::BakedDataProvider;
|
||||
|
||||
pub const fn baked_data_provider() -> BakedDataProvider {
|
||||
data::BakedDataProvider
|
||||
}
|
||||
|
||||
pub mod supported_locales {
|
||||
pub const EN: icu_locid::Locale = icu_locid::locale!("en");
|
||||
pub const ES: icu_locid::Locale = icu_locid::locale!("es");
|
||||
pub const FR: icu_locid::Locale = icu_locid::locale!("fr");
|
||||
pub const IT: icu_locid::Locale = icu_locid::locale!("it");
|
||||
pub const JA: icu_locid::Locale = icu_locid::locale!("ja");
|
||||
pub const PT: icu_locid::Locale = icu_locid::locale!("pt");
|
||||
pub const RU: icu_locid::Locale = icu_locid::locale!("ru");
|
||||
pub const TR: icu_locid::Locale = icu_locid::locale!("tr");
|
||||
pub const ZH_HANS: icu_locid::Locale = icu_locid::locale!("zh-Hans");
|
||||
pub const ZH_HANT: icu_locid::Locale = icu_locid::locale!("zh-Hant");
|
||||
}
|
||||
@ -1,3 +1,5 @@
|
||||
#![deny(rustc::untranslatable_diagnostic)]
|
||||
#![deny(rustc::diagnostic_outside_of_impl)]
|
||||
use crate::nll::ToRegionVid;
|
||||
use crate::path_utils::allow_two_phase_borrow;
|
||||
use crate::place_ext::PlaceExt;
|
||||
@ -196,7 +198,7 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherBorrows<'a, 'tcx> {
|
||||
rvalue: &mir::Rvalue<'tcx>,
|
||||
location: mir::Location,
|
||||
) {
|
||||
if let mir::Rvalue::Ref(region, kind, ref borrowed_place) = *rvalue {
|
||||
if let &mir::Rvalue::Ref(region, kind, borrowed_place) = rvalue {
|
||||
if borrowed_place.ignore_borrow(self.tcx, self.body, &self.locals_state_at_exit) {
|
||||
debug!("ignoring_borrow of {:?}", borrowed_place);
|
||||
return;
|
||||
@ -209,7 +211,7 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherBorrows<'a, 'tcx> {
|
||||
region,
|
||||
reserve_location: location,
|
||||
activation_location: TwoPhaseActivation::NotTwoPhase,
|
||||
borrowed_place: *borrowed_place,
|
||||
borrowed_place,
|
||||
assigned_place: *assigned_place,
|
||||
};
|
||||
let (idx, _) = self.location_map.insert_full(location, borrow);
|
||||
@ -271,14 +273,14 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherBorrows<'a, 'tcx> {
|
||||
}
|
||||
|
||||
fn visit_rvalue(&mut self, rvalue: &mir::Rvalue<'tcx>, location: mir::Location) {
|
||||
if let mir::Rvalue::Ref(region, kind, ref place) = *rvalue {
|
||||
if let &mir::Rvalue::Ref(region, kind, place) = rvalue {
|
||||
// double-check that we already registered a BorrowData for this
|
||||
|
||||
let borrow_data = &self.location_map[&location];
|
||||
assert_eq!(borrow_data.reserve_location, location);
|
||||
assert_eq!(borrow_data.kind, kind);
|
||||
assert_eq!(borrow_data.region, region.to_region_vid());
|
||||
assert_eq!(borrow_data.borrowed_place, *place);
|
||||
assert_eq!(borrow_data.borrowed_place, place);
|
||||
}
|
||||
|
||||
self.super_rvalue(rvalue, location)
|
||||
|
||||
@ -8,9 +8,18 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
|
||||
pub(crate) fn cannot_move_when_borrowed(
|
||||
&self,
|
||||
span: Span,
|
||||
desc: &str,
|
||||
borrow_span: Span,
|
||||
place: &str,
|
||||
borrow_place: &str,
|
||||
value_place: &str,
|
||||
) -> DiagnosticBuilder<'cx, ErrorGuaranteed> {
|
||||
struct_span_err!(self, span, E0505, "cannot move out of {} because it is borrowed", desc,)
|
||||
self.infcx.tcx.sess.create_err(crate::session_diagnostics::MoveBorrow {
|
||||
place,
|
||||
span,
|
||||
borrow_place,
|
||||
value_place,
|
||||
borrow_span,
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn cannot_use_when_mutably_borrowed(
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
#![deny(rustc::untranslatable_diagnostic)]
|
||||
#![deny(rustc::diagnostic_outside_of_impl)]
|
||||
use rustc_infer::infer::InferCtxt;
|
||||
use rustc_middle::mir::visit::TyContext;
|
||||
use rustc_middle::mir::visit::Visitor;
|
||||
|
||||
@ -163,6 +163,7 @@ impl<'s, 'tcx, D: ConstraintGraphDirecton> Iterator for Edges<'s, 'tcx, D> {
|
||||
span: DUMMY_SP,
|
||||
category: ConstraintCategory::Internal,
|
||||
variance_info: VarianceDiagInfo::default(),
|
||||
from_closure: false,
|
||||
})
|
||||
} else {
|
||||
None
|
||||
|
||||
@ -1,3 +1,6 @@
|
||||
#![deny(rustc::untranslatable_diagnostic)]
|
||||
#![deny(rustc::diagnostic_outside_of_impl)]
|
||||
|
||||
use rustc_data_structures::graph::scc::Sccs;
|
||||
use rustc_index::vec::IndexVec;
|
||||
use rustc_middle::mir::ConstraintCategory;
|
||||
@ -96,6 +99,9 @@ pub struct OutlivesConstraint<'tcx> {
|
||||
|
||||
/// Variance diagnostic information
|
||||
pub variance_info: VarianceDiagInfo<'tcx>,
|
||||
|
||||
/// If this constraint is promoted from closure requirements.
|
||||
pub from_closure: bool,
|
||||
}
|
||||
|
||||
impl<'tcx> fmt::Debug for OutlivesConstraint<'tcx> {
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
#![deny(rustc::untranslatable_diagnostic)]
|
||||
#![deny(rustc::diagnostic_outside_of_impl)]
|
||||
//! This file provides API for compiler consumers.
|
||||
|
||||
use rustc_hir::def_id::LocalDefId;
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
#![deny(rustc::untranslatable_diagnostic)]
|
||||
#![deny(rustc::diagnostic_outside_of_impl)]
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_index::bit_set::BitSet;
|
||||
use rustc_middle::mir::{self, BasicBlock, Body, Location, Place};
|
||||
@ -356,9 +358,9 @@ impl<'tcx> rustc_mir_dataflow::GenKillAnalysis<'tcx> for Borrows<'_, 'tcx> {
|
||||
stmt: &mir::Statement<'tcx>,
|
||||
location: Location,
|
||||
) {
|
||||
match stmt.kind {
|
||||
mir::StatementKind::Assign(box (lhs, ref rhs)) => {
|
||||
if let mir::Rvalue::Ref(_, _, place) = *rhs {
|
||||
match &stmt.kind {
|
||||
mir::StatementKind::Assign(box (lhs, rhs)) => {
|
||||
if let mir::Rvalue::Ref(_, _, place) = rhs {
|
||||
if place.ignore_borrow(
|
||||
self.tcx,
|
||||
self.body,
|
||||
@ -375,13 +377,13 @@ impl<'tcx> rustc_mir_dataflow::GenKillAnalysis<'tcx> for Borrows<'_, 'tcx> {
|
||||
|
||||
// Make sure there are no remaining borrows for variables
|
||||
// that are assigned over.
|
||||
self.kill_borrows_on_place(trans, lhs);
|
||||
self.kill_borrows_on_place(trans, *lhs);
|
||||
}
|
||||
|
||||
mir::StatementKind::StorageDead(local) => {
|
||||
// Make sure there are no remaining borrows for locals that
|
||||
// are gone out of scope.
|
||||
self.kill_borrows_on_place(trans, Place::from(local));
|
||||
self.kill_borrows_on_place(trans, Place::from(*local));
|
||||
}
|
||||
|
||||
mir::StatementKind::FakeRead(..)
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
#![deny(rustc::untranslatable_diagnostic)]
|
||||
#![deny(rustc::diagnostic_outside_of_impl)]
|
||||
use rustc_middle::mir::visit::{
|
||||
MutatingUseContext, NonMutatingUseContext, NonUseContext, PlaceContext,
|
||||
};
|
||||
|
||||
@ -1,3 +1,6 @@
|
||||
#![deny(rustc::untranslatable_diagnostic)]
|
||||
#![deny(rustc::diagnostic_outside_of_impl)]
|
||||
|
||||
use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed};
|
||||
use rustc_infer::infer::canonical::Canonical;
|
||||
use rustc_infer::infer::error_reporting::nice_region_error::NiceRegionError;
|
||||
@ -5,14 +8,14 @@ use rustc_infer::infer::region_constraints::Constraint;
|
||||
use rustc_infer::infer::region_constraints::RegionConstraintData;
|
||||
use rustc_infer::infer::RegionVariableOrigin;
|
||||
use rustc_infer::infer::{InferCtxt, RegionResolutionError, SubregionOrigin, TyCtxtInferExt as _};
|
||||
use rustc_infer::traits::{Normalized, ObligationCause, TraitEngine, TraitEngineExt};
|
||||
use rustc_infer::traits::ObligationCause;
|
||||
use rustc_middle::ty::error::TypeError;
|
||||
use rustc_middle::ty::RegionVid;
|
||||
use rustc_middle::ty::UniverseIndex;
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable};
|
||||
use rustc_span::Span;
|
||||
use rustc_trait_selection::traits::query::type_op;
|
||||
use rustc_trait_selection::traits::{SelectionContext, TraitEngineExt as _};
|
||||
use rustc_trait_selection::traits::ObligationCtxt;
|
||||
use rustc_traits::{type_op_ascribe_user_type_with_span, type_op_prove_predicate_with_cause};
|
||||
|
||||
use std::fmt;
|
||||
@ -158,6 +161,7 @@ trait TypeOpInfo<'tcx> {
|
||||
error_region: Option<ty::Region<'tcx>>,
|
||||
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>>;
|
||||
|
||||
#[instrument(level = "debug", skip(self, mbcx))]
|
||||
fn report_error(
|
||||
&self,
|
||||
mbcx: &mut MirBorrowckCtxt<'_, 'tcx>,
|
||||
@ -167,6 +171,7 @@ trait TypeOpInfo<'tcx> {
|
||||
) {
|
||||
let tcx = mbcx.infcx.tcx;
|
||||
let base_universe = self.base_universe();
|
||||
debug!(?base_universe);
|
||||
|
||||
let Some(adjusted_universe) =
|
||||
placeholder.universe.as_u32().checked_sub(base_universe.as_u32())
|
||||
@ -238,11 +243,11 @@ impl<'tcx> TypeOpInfo<'tcx> for PredicateQuery<'tcx> {
|
||||
placeholder_region: ty::Region<'tcx>,
|
||||
error_region: Option<ty::Region<'tcx>>,
|
||||
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> {
|
||||
let (ref infcx, key, _) =
|
||||
let (infcx, key, _) =
|
||||
mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query);
|
||||
let mut fulfill_cx = <dyn TraitEngine<'_>>::new(infcx.tcx);
|
||||
type_op_prove_predicate_with_cause(infcx, &mut *fulfill_cx, key, cause);
|
||||
try_extract_error_from_fulfill_cx(fulfill_cx, infcx, placeholder_region, error_region)
|
||||
let ocx = ObligationCtxt::new(&infcx);
|
||||
type_op_prove_predicate_with_cause(&ocx, key, cause);
|
||||
try_extract_error_from_fulfill_cx(&ocx, placeholder_region, error_region)
|
||||
}
|
||||
}
|
||||
|
||||
@ -279,24 +284,20 @@ where
|
||||
placeholder_region: ty::Region<'tcx>,
|
||||
error_region: Option<ty::Region<'tcx>>,
|
||||
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> {
|
||||
let (ref infcx, key, _) =
|
||||
let (infcx, key, _) =
|
||||
mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query);
|
||||
let mut fulfill_cx = <dyn TraitEngine<'_>>::new(infcx.tcx);
|
||||
|
||||
let mut selcx = SelectionContext::new(infcx);
|
||||
let ocx = ObligationCtxt::new(&infcx);
|
||||
|
||||
// FIXME(lqd): Unify and de-duplicate the following with the actual
|
||||
// `rustc_traits::type_op::type_op_normalize` query to allow the span we need in the
|
||||
// `ObligationCause`. The normalization results are currently different between
|
||||
// `AtExt::normalize` used in the query and `normalize` called below: the former fails
|
||||
// to normalize the `nll/relate_tys/impl-fn-ignore-binder-via-bottom.rs` test. Check
|
||||
// after #85499 lands to see if its fixes have erased this difference.
|
||||
// `QueryNormalizeExt::query_normalize` used in the query and `normalize` called below:
|
||||
// the former fails to normalize the `nll/relate_tys/impl-fn-ignore-binder-via-bottom.rs` test.
|
||||
// Check after #85499 lands to see if its fixes have erased this difference.
|
||||
let (param_env, value) = key.into_parts();
|
||||
let Normalized { value: _, obligations } =
|
||||
rustc_trait_selection::traits::normalize(&mut selcx, param_env, cause, value.value);
|
||||
fulfill_cx.register_predicate_obligations(infcx, obligations);
|
||||
let _ = ocx.normalize(&cause, param_env, value.value);
|
||||
|
||||
try_extract_error_from_fulfill_cx(fulfill_cx, infcx, placeholder_region, error_region)
|
||||
try_extract_error_from_fulfill_cx(&ocx, placeholder_region, error_region)
|
||||
}
|
||||
}
|
||||
|
||||
@ -327,11 +328,11 @@ impl<'tcx> TypeOpInfo<'tcx> for AscribeUserTypeQuery<'tcx> {
|
||||
placeholder_region: ty::Region<'tcx>,
|
||||
error_region: Option<ty::Region<'tcx>>,
|
||||
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> {
|
||||
let (ref infcx, key, _) =
|
||||
let (infcx, key, _) =
|
||||
mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query);
|
||||
let mut fulfill_cx = <dyn TraitEngine<'_>>::new(infcx.tcx);
|
||||
type_op_ascribe_user_type_with_span(infcx, &mut *fulfill_cx, key, Some(cause.span)).ok()?;
|
||||
try_extract_error_from_fulfill_cx(fulfill_cx, infcx, placeholder_region, error_region)
|
||||
let ocx = ObligationCtxt::new(&infcx);
|
||||
type_op_ascribe_user_type_with_span(&ocx, key, Some(cause.span)).ok()?;
|
||||
try_extract_error_from_fulfill_cx(&ocx, placeholder_region, error_region)
|
||||
}
|
||||
}
|
||||
|
||||
@ -372,28 +373,28 @@ impl<'tcx> TypeOpInfo<'tcx> for crate::type_check::InstantiateOpaqueType<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(skip(fulfill_cx, infcx), level = "debug")]
|
||||
#[instrument(skip(ocx), level = "debug")]
|
||||
fn try_extract_error_from_fulfill_cx<'tcx>(
|
||||
mut fulfill_cx: Box<dyn TraitEngine<'tcx> + 'tcx>,
|
||||
infcx: &InferCtxt<'tcx>,
|
||||
ocx: &ObligationCtxt<'_, 'tcx>,
|
||||
placeholder_region: ty::Region<'tcx>,
|
||||
error_region: Option<ty::Region<'tcx>>,
|
||||
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> {
|
||||
// We generally shouldn't have errors here because the query was
|
||||
// already run, but there's no point using `delay_span_bug`
|
||||
// when we're going to emit an error here anyway.
|
||||
let _errors = fulfill_cx.select_all_or_error(infcx);
|
||||
let region_constraints = infcx.with_region_constraints(|r| r.clone());
|
||||
let _errors = ocx.select_all_or_error();
|
||||
let region_constraints = ocx.infcx.with_region_constraints(|r| r.clone());
|
||||
try_extract_error_from_region_constraints(
|
||||
infcx,
|
||||
ocx.infcx,
|
||||
placeholder_region,
|
||||
error_region,
|
||||
®ion_constraints,
|
||||
|vid| infcx.region_var_origin(vid),
|
||||
|vid| infcx.universe_of_region(infcx.tcx.mk_region(ty::ReVar(vid))),
|
||||
|vid| ocx.infcx.region_var_origin(vid),
|
||||
|vid| ocx.infcx.universe_of_region(ocx.infcx.tcx.mk_region(ty::ReVar(vid))),
|
||||
)
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(infcx, region_var_origin, universe_of_region))]
|
||||
fn try_extract_error_from_region_constraints<'tcx>(
|
||||
infcx: &InferCtxt<'tcx>,
|
||||
placeholder_region: ty::Region<'tcx>,
|
||||
|
||||
@ -7,7 +7,7 @@ use rustc_errors::{
|
||||
};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::intravisit::{walk_block, walk_expr, Visitor};
|
||||
use rustc_hir::{AsyncGeneratorKind, GeneratorKind};
|
||||
use rustc_hir::{AsyncGeneratorKind, GeneratorKind, LangItem};
|
||||
use rustc_infer::infer::TyCtxtInferExt;
|
||||
use rustc_infer::traits::ObligationCause;
|
||||
use rustc_middle::mir::tcx::PlaceTy;
|
||||
@ -23,7 +23,6 @@ use rustc_span::hygiene::DesugaringKind;
|
||||
use rustc_span::symbol::sym;
|
||||
use rustc_span::{BytePos, Span, Symbol};
|
||||
use rustc_trait_selection::infer::InferCtxtExt;
|
||||
use rustc_trait_selection::traits::TraitEngineExt as _;
|
||||
|
||||
use crate::borrow_set::TwoPhaseActivation;
|
||||
use crate::borrowck_errors;
|
||||
@ -168,10 +167,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
);
|
||||
}
|
||||
|
||||
self.add_moved_or_invoked_closure_note(location, used_place, &mut err);
|
||||
let closure = self.add_moved_or_invoked_closure_note(location, used_place, &mut err);
|
||||
|
||||
let mut is_loop_move = false;
|
||||
let mut in_pattern = false;
|
||||
let mut seen_spans = FxHashSet::default();
|
||||
|
||||
for move_site in &move_site_vec {
|
||||
let move_out = self.move_data.moves[(*move_site).moi];
|
||||
@ -192,43 +192,28 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
is_loop_move = true;
|
||||
}
|
||||
|
||||
self.explain_captures(
|
||||
&mut err,
|
||||
span,
|
||||
move_span,
|
||||
move_spans,
|
||||
*moved_place,
|
||||
partially_str,
|
||||
loop_message,
|
||||
move_msg,
|
||||
is_loop_move,
|
||||
maybe_reinitialized_locations.is_empty(),
|
||||
);
|
||||
|
||||
if let (UseSpans::PatUse(span), []) =
|
||||
(move_spans, &maybe_reinitialized_locations[..])
|
||||
{
|
||||
if maybe_reinitialized_locations.is_empty() {
|
||||
err.span_suggestion_verbose(
|
||||
span.shrink_to_lo(),
|
||||
&format!(
|
||||
"borrow this field in the pattern to avoid moving {}",
|
||||
self.describe_place(moved_place.as_ref())
|
||||
.map(|n| format!("`{}`", n))
|
||||
.unwrap_or_else(|| "the value".to_string())
|
||||
),
|
||||
"ref ",
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
in_pattern = true;
|
||||
if !seen_spans.contains(&move_span) {
|
||||
if !closure {
|
||||
self.suggest_ref_or_clone(mpi, move_span, &mut err, &mut in_pattern);
|
||||
}
|
||||
|
||||
self.explain_captures(
|
||||
&mut err,
|
||||
span,
|
||||
move_span,
|
||||
move_spans,
|
||||
*moved_place,
|
||||
partially_str,
|
||||
loop_message,
|
||||
move_msg,
|
||||
is_loop_move,
|
||||
maybe_reinitialized_locations.is_empty(),
|
||||
);
|
||||
}
|
||||
seen_spans.insert(move_span);
|
||||
}
|
||||
|
||||
use_spans.var_span_label_path_only(
|
||||
&mut err,
|
||||
format!("{} occurs due to use{}", desired_action.as_noun(), use_spans.describe()),
|
||||
);
|
||||
use_spans.var_path_only_subdiag(&mut err, desired_action);
|
||||
|
||||
if !is_loop_move {
|
||||
err.span_label(
|
||||
@ -280,7 +265,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
DescribePlaceOpt { including_downcast: true, including_tuple_field: true },
|
||||
);
|
||||
let note_msg = match opt_name {
|
||||
Some(ref name) => format!("`{}`", name),
|
||||
Some(name) => format!("`{}`", name),
|
||||
None => "value".to_owned(),
|
||||
};
|
||||
if self.suggest_borrow_fn_like(&mut err, ty, &move_site_vec, ¬e_msg) {
|
||||
@ -321,6 +306,160 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn suggest_ref_or_clone(
|
||||
&mut self,
|
||||
mpi: MovePathIndex,
|
||||
move_span: Span,
|
||||
err: &mut DiagnosticBuilder<'_, ErrorGuaranteed>,
|
||||
in_pattern: &mut bool,
|
||||
) {
|
||||
struct ExpressionFinder<'hir> {
|
||||
expr_span: Span,
|
||||
expr: Option<&'hir hir::Expr<'hir>>,
|
||||
pat: Option<&'hir hir::Pat<'hir>>,
|
||||
parent_pat: Option<&'hir hir::Pat<'hir>>,
|
||||
}
|
||||
impl<'hir> Visitor<'hir> for ExpressionFinder<'hir> {
|
||||
fn visit_expr(&mut self, e: &'hir hir::Expr<'hir>) {
|
||||
if e.span == self.expr_span {
|
||||
self.expr = Some(e);
|
||||
}
|
||||
hir::intravisit::walk_expr(self, e);
|
||||
}
|
||||
fn visit_pat(&mut self, p: &'hir hir::Pat<'hir>) {
|
||||
if p.span == self.expr_span {
|
||||
self.pat = Some(p);
|
||||
}
|
||||
if let hir::PatKind::Binding(hir::BindingAnnotation::NONE, _, i, sub) = p.kind {
|
||||
if i.span == self.expr_span || p.span == self.expr_span {
|
||||
self.pat = Some(p);
|
||||
}
|
||||
// Check if we are in a situation of `ident @ ident` where we want to suggest
|
||||
// `ref ident @ ref ident` or `ref ident @ Struct { ref ident }`.
|
||||
if let Some(subpat) = sub && self.pat.is_none() {
|
||||
self.visit_pat(subpat);
|
||||
if self.pat.is_some() {
|
||||
self.parent_pat = Some(p);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
hir::intravisit::walk_pat(self, p);
|
||||
}
|
||||
}
|
||||
let hir = self.infcx.tcx.hir();
|
||||
if let Some(hir::Node::Item(hir::Item {
|
||||
kind: hir::ItemKind::Fn(_, _, body_id),
|
||||
..
|
||||
})) = hir.find(hir.local_def_id_to_hir_id(self.mir_def_id()))
|
||||
&& let Some(hir::Node::Expr(expr)) = hir.find(body_id.hir_id)
|
||||
{
|
||||
let place = &self.move_data.move_paths[mpi].place;
|
||||
let span = place.as_local()
|
||||
.map(|local| self.body.local_decls[local].source_info.span);
|
||||
let mut finder = ExpressionFinder {
|
||||
expr_span: move_span,
|
||||
expr: None,
|
||||
pat: None,
|
||||
parent_pat: None,
|
||||
};
|
||||
finder.visit_expr(expr);
|
||||
if let Some(span) = span && let Some(expr) = finder.expr {
|
||||
for (_, expr) in hir.parent_iter(expr.hir_id) {
|
||||
if let hir::Node::Expr(expr) = expr {
|
||||
if expr.span.contains(span) {
|
||||
// If the let binding occurs within the same loop, then that
|
||||
// loop isn't relevant, like in the following, the outermost `loop`
|
||||
// doesn't play into `x` being moved.
|
||||
// ```
|
||||
// loop {
|
||||
// let x = String::new();
|
||||
// loop {
|
||||
// foo(x);
|
||||
// }
|
||||
// }
|
||||
// ```
|
||||
break;
|
||||
}
|
||||
if let hir::ExprKind::Loop(.., loop_span) = expr.kind {
|
||||
err.span_label(loop_span, "inside of this loop");
|
||||
}
|
||||
}
|
||||
}
|
||||
let typeck = self.infcx.tcx.typeck(self.mir_def_id());
|
||||
let hir_id = hir.get_parent_node(expr.hir_id);
|
||||
if let Some(parent) = hir.find(hir_id) {
|
||||
let (def_id, args, offset) = if let hir::Node::Expr(parent_expr) = parent
|
||||
&& let hir::ExprKind::MethodCall(_, _, args, _) = parent_expr.kind
|
||||
&& let Some(def_id) = typeck.type_dependent_def_id(parent_expr.hir_id)
|
||||
{
|
||||
(def_id.as_local(), args, 1)
|
||||
} else if let hir::Node::Expr(parent_expr) = parent
|
||||
&& let hir::ExprKind::Call(call, args) = parent_expr.kind
|
||||
&& let ty::FnDef(def_id, _) = typeck.node_type(call.hir_id).kind()
|
||||
{
|
||||
(def_id.as_local(), args, 0)
|
||||
} else {
|
||||
(None, &[][..], 0)
|
||||
};
|
||||
if let Some(def_id) = def_id
|
||||
&& let Some(node) = hir.find(hir.local_def_id_to_hir_id(def_id))
|
||||
&& let Some(fn_sig) = node.fn_sig()
|
||||
&& let Some(ident) = node.ident()
|
||||
&& let Some(pos) = args.iter().position(|arg| arg.hir_id == expr.hir_id)
|
||||
&& let Some(arg) = fn_sig.decl.inputs.get(pos + offset)
|
||||
{
|
||||
let mut span: MultiSpan = arg.span.into();
|
||||
span.push_span_label(
|
||||
arg.span,
|
||||
"this parameter takes ownership of the value".to_string(),
|
||||
);
|
||||
let descr = match node.fn_kind() {
|
||||
Some(hir::intravisit::FnKind::ItemFn(..)) | None => "function",
|
||||
Some(hir::intravisit::FnKind::Method(..)) => "method",
|
||||
Some(hir::intravisit::FnKind::Closure) => "closure",
|
||||
};
|
||||
span.push_span_label(
|
||||
ident.span,
|
||||
format!("in this {descr}"),
|
||||
);
|
||||
err.span_note(
|
||||
span,
|
||||
format!(
|
||||
"consider changing this parameter type in {descr} `{ident}` to \
|
||||
borrow instead if owning the value isn't necessary",
|
||||
),
|
||||
);
|
||||
}
|
||||
let place = &self.move_data.move_paths[mpi].place;
|
||||
let ty = place.ty(self.body, self.infcx.tcx).ty;
|
||||
if let hir::Node::Expr(parent_expr) = parent
|
||||
&& let hir::ExprKind::Call(call_expr, _) = parent_expr.kind
|
||||
&& let hir::ExprKind::Path(
|
||||
hir::QPath::LangItem(LangItem::IntoIterIntoIter, _, _)
|
||||
) = call_expr.kind
|
||||
{
|
||||
// Do not suggest `.clone()` in a `for` loop, we already suggest borrowing.
|
||||
} else {
|
||||
self.suggest_cloning(err, ty, move_span);
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(pat) = finder.pat {
|
||||
*in_pattern = true;
|
||||
let mut sugg = vec![(pat.span.shrink_to_lo(), "ref ".to_string())];
|
||||
if let Some(pat) = finder.parent_pat {
|
||||
sugg.insert(0, (pat.span.shrink_to_lo(), "ref ".to_string()));
|
||||
}
|
||||
err.multipart_suggestion_verbose(
|
||||
"borrow this binding in the pattern to avoid moving the value",
|
||||
sugg,
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn report_use_of_uninitialized(
|
||||
&self,
|
||||
mpi: MovePathIndex,
|
||||
@ -405,10 +544,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
let used = desired_action.as_general_verb_in_past_tense();
|
||||
let mut err =
|
||||
struct_span_err!(self, span, E0381, "{used} binding {desc}{isnt_initialized}");
|
||||
use_spans.var_span_label_path_only(
|
||||
&mut err,
|
||||
format!("{} occurs due to use{}", desired_action.as_noun(), use_spans.describe()),
|
||||
);
|
||||
use_spans.var_path_only_subdiag(&mut err, desired_action);
|
||||
|
||||
if let InitializationRequiringAction::PartialAssignment
|
||||
| InitializationRequiringAction::Assignment = desired_action
|
||||
@ -496,12 +632,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
// but the type has region variables, so erase those.
|
||||
tcx.infer_ctxt()
|
||||
.build()
|
||||
.type_implements_trait(
|
||||
default_trait,
|
||||
tcx.erase_regions(ty),
|
||||
ty::List::empty(),
|
||||
param_env,
|
||||
)
|
||||
.type_implements_trait(default_trait, [tcx.erase_regions(ty)], param_env)
|
||||
.must_apply_modulo_regions()
|
||||
};
|
||||
|
||||
@ -535,15 +666,17 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
let tcx = self.infcx.tcx;
|
||||
|
||||
// Find out if the predicates show that the type is a Fn or FnMut
|
||||
let find_fn_kind_from_did =
|
||||
|predicates: ty::EarlyBinder<&[(ty::Predicate<'tcx>, Span)]>, substs| {
|
||||
predicates.0.iter().find_map(|(pred, _)| {
|
||||
let find_fn_kind_from_did = |predicates: ty::EarlyBinder<
|
||||
&[(ty::Predicate<'tcx>, Span)],
|
||||
>,
|
||||
substs| {
|
||||
predicates.0.iter().find_map(|(pred, _)| {
|
||||
let pred = if let Some(substs) = substs {
|
||||
predicates.rebind(*pred).subst(tcx, substs).kind().skip_binder()
|
||||
} else {
|
||||
pred.kind().skip_binder()
|
||||
};
|
||||
if let ty::PredicateKind::Trait(pred) = pred && pred.self_ty() == ty {
|
||||
if let ty::PredicateKind::Clause(ty::Clause::Trait(pred)) = pred && pred.self_ty() == ty {
|
||||
if Some(pred.def_id()) == tcx.lang_items().fn_trait() {
|
||||
return Some(hir::Mutability::Not);
|
||||
} else if Some(pred.def_id()) == tcx.lang_items().fn_mut_trait() {
|
||||
@ -552,7 +685,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
}
|
||||
None
|
||||
})
|
||||
};
|
||||
};
|
||||
|
||||
// If the type is opaque/param/closure, and it is Fn or FnMut, let's suggest (mutably)
|
||||
// borrowing the type, since `&mut F: FnMut` iff `F: FnMut` and similarly for `Fn`.
|
||||
@ -583,25 +716,41 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
let moved_place = &self.move_data.move_paths[move_out.path].place;
|
||||
let move_spans = self.move_spans(moved_place.as_ref(), move_out.source);
|
||||
let move_span = move_spans.args_or_use();
|
||||
let suggestion = if borrow_level == hir::Mutability::Mut {
|
||||
"&mut ".to_string()
|
||||
} else {
|
||||
"&".to_string()
|
||||
};
|
||||
let suggestion = borrow_level.ref_prefix_str().to_owned();
|
||||
(move_span.shrink_to_lo(), suggestion)
|
||||
})
|
||||
.collect();
|
||||
err.multipart_suggestion_verbose(
|
||||
&format!(
|
||||
"consider {}borrowing {value_name}",
|
||||
if borrow_level == hir::Mutability::Mut { "mutably " } else { "" }
|
||||
),
|
||||
format!("consider {}borrowing {value_name}", borrow_level.mutably_str()),
|
||||
sugg,
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
true
|
||||
}
|
||||
|
||||
fn suggest_cloning(&self, err: &mut Diagnostic, ty: Ty<'tcx>, span: Span) {
|
||||
let tcx = self.infcx.tcx;
|
||||
// Try to find predicates on *generic params* that would allow copying `ty`
|
||||
let infcx = tcx.infer_ctxt().build();
|
||||
|
||||
if let Some(clone_trait_def) = tcx.lang_items().clone_trait()
|
||||
&& infcx
|
||||
.type_implements_trait(
|
||||
clone_trait_def,
|
||||
[tcx.erase_regions(ty)],
|
||||
self.param_env,
|
||||
)
|
||||
.must_apply_modulo_regions()
|
||||
{
|
||||
err.span_suggestion_verbose(
|
||||
span.shrink_to_hi(),
|
||||
"consider cloning the value if the performance cost is acceptable",
|
||||
".clone()".to_string(),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn suggest_adding_copy_bounds(&self, err: &mut Diagnostic, ty: Ty<'tcx>, span: Span) {
|
||||
let tcx = self.infcx.tcx;
|
||||
let generics = tcx.generics_of(self.mir_def_id());
|
||||
@ -613,36 +762,34 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
else { return; };
|
||||
// Try to find predicates on *generic params* that would allow copying `ty`
|
||||
let infcx = tcx.infer_ctxt().build();
|
||||
let mut fulfill_cx = <dyn rustc_infer::traits::TraitEngine<'_>>::new(infcx.tcx);
|
||||
|
||||
let copy_did = infcx.tcx.lang_items().copy_trait().unwrap();
|
||||
let copy_did = infcx.tcx.require_lang_item(LangItem::Copy, Some(span));
|
||||
let cause = ObligationCause::new(
|
||||
span,
|
||||
self.mir_hir_id(),
|
||||
rustc_infer::traits::ObligationCauseCode::MiscObligation,
|
||||
);
|
||||
fulfill_cx.register_bound(
|
||||
let errors = rustc_trait_selection::traits::fully_solve_bound(
|
||||
&infcx,
|
||||
cause,
|
||||
self.param_env,
|
||||
// Erase any region vids from the type, which may not be resolved
|
||||
infcx.tcx.erase_regions(ty),
|
||||
copy_did,
|
||||
cause,
|
||||
);
|
||||
// Select all, including ambiguous predicates
|
||||
let errors = fulfill_cx.select_all_or_error(&infcx);
|
||||
|
||||
// Only emit suggestion if all required predicates are on generic
|
||||
let predicates: Result<Vec<_>, _> = errors
|
||||
.into_iter()
|
||||
.map(|err| match err.obligation.predicate.kind().skip_binder() {
|
||||
PredicateKind::Trait(predicate) => match predicate.self_ty().kind() {
|
||||
ty::Param(param_ty) => Ok((
|
||||
generics.type_param(param_ty, tcx),
|
||||
predicate.trait_ref.print_only_trait_path().to_string(),
|
||||
)),
|
||||
_ => Err(()),
|
||||
},
|
||||
PredicateKind::Clause(ty::Clause::Trait(predicate)) => {
|
||||
match predicate.self_ty().kind() {
|
||||
ty::Param(param_ty) => Ok((
|
||||
generics.type_param(param_ty, tcx),
|
||||
predicate.trait_ref.print_only_trait_path().to_string(),
|
||||
)),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
_ => Err(()),
|
||||
})
|
||||
.collect();
|
||||
@ -678,16 +825,16 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
let move_spans = self.move_spans(place.as_ref(), location);
|
||||
let span = move_spans.args_or_use();
|
||||
|
||||
let mut err =
|
||||
self.cannot_move_when_borrowed(span, &self.describe_any_place(place.as_ref()));
|
||||
err.span_label(borrow_span, format!("borrow of {} occurs here", borrow_msg));
|
||||
err.span_label(span, format!("move out of {} occurs here", value_msg));
|
||||
|
||||
borrow_spans.var_span_label_path_only(
|
||||
&mut err,
|
||||
format!("borrow occurs due to use{}", borrow_spans.describe()),
|
||||
let mut err = self.cannot_move_when_borrowed(
|
||||
span,
|
||||
borrow_span,
|
||||
&self.describe_any_place(place.as_ref()),
|
||||
&borrow_msg,
|
||||
&value_msg,
|
||||
);
|
||||
|
||||
borrow_spans.var_path_only_subdiag(&mut err, crate::InitializationRequiringAction::Borrow);
|
||||
|
||||
move_spans.var_span_label(
|
||||
&mut err,
|
||||
format!("move occurs due to use{}", move_spans.describe()),
|
||||
@ -729,16 +876,15 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
borrow_span,
|
||||
&self.describe_any_place(borrow.borrowed_place.as_ref()),
|
||||
);
|
||||
|
||||
borrow_spans.var_span_label(
|
||||
&mut err,
|
||||
{
|
||||
let place = &borrow.borrowed_place;
|
||||
let desc_place = self.describe_any_place(place.as_ref());
|
||||
format!("borrow occurs due to use of {}{}", desc_place, borrow_spans.describe())
|
||||
},
|
||||
"mutable",
|
||||
);
|
||||
borrow_spans.var_subdiag(&mut err, Some(borrow.kind), |kind, var_span| {
|
||||
use crate::session_diagnostics::CaptureVarCause::*;
|
||||
let place = &borrow.borrowed_place;
|
||||
let desc_place = self.describe_any_place(place.as_ref());
|
||||
match kind {
|
||||
Some(_) => BorrowUsePlaceGenerator { place: desc_place, var_span },
|
||||
None => BorrowUsePlaceClosure { place: desc_place, var_span },
|
||||
}
|
||||
});
|
||||
|
||||
self.explain_why_borrow_contains_point(location, borrow, None)
|
||||
.add_explanation_to_diagnostic(
|
||||
@ -1271,7 +1417,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
// then just use the normal error. The closure isn't escaping
|
||||
// and `move` will not help here.
|
||||
(
|
||||
Some(ref name),
|
||||
Some(name),
|
||||
BorrowExplanation::MustBeValidFor {
|
||||
category:
|
||||
category @ (ConstraintCategory::Return(_)
|
||||
@ -1292,7 +1438,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
&format!("`{}`", name),
|
||||
),
|
||||
(
|
||||
ref name,
|
||||
name,
|
||||
BorrowExplanation::MustBeValidFor {
|
||||
category: ConstraintCategory::Assignment,
|
||||
from_closure: false,
|
||||
@ -1304,7 +1450,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
span,
|
||||
..
|
||||
},
|
||||
) => self.report_escaping_data(borrow_span, name, upvar_span, upvar_name, span),
|
||||
) => self.report_escaping_data(borrow_span, &name, upvar_span, upvar_name, span),
|
||||
(Some(name), explanation) => self.report_local_value_does_not_live_long_enough(
|
||||
location,
|
||||
&name,
|
||||
@ -1556,7 +1702,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
}
|
||||
|
||||
let mut err = self.temporary_value_borrowed_for_too_long(proper_span);
|
||||
err.span_label(proper_span, "creates a temporary which is freed while still in use");
|
||||
err.span_label(proper_span, "creates a temporary value which is freed while still in use");
|
||||
err.span_label(drop_span, "temporary value is freed at the end of this statement");
|
||||
|
||||
match explanation {
|
||||
@ -1719,7 +1865,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
err.span_label(borrow_span, note);
|
||||
|
||||
let tcx = self.infcx.tcx;
|
||||
let ty_params = ty::List::empty();
|
||||
|
||||
let return_ty = self.regioncx.universal_regions().unnormalized_output_ty;
|
||||
let return_ty = tcx.erase_regions(return_ty);
|
||||
@ -1728,7 +1873,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
if let Some(iter_trait) = tcx.get_diagnostic_item(sym::Iterator)
|
||||
&& self
|
||||
.infcx
|
||||
.type_implements_trait(iter_trait, return_ty, ty_params, self.param_env)
|
||||
.type_implements_trait(iter_trait, [return_ty], self.param_env)
|
||||
.must_apply_modulo_regions()
|
||||
{
|
||||
err.span_suggestion_hidden(
|
||||
@ -2307,7 +2452,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
// and it'll make sense.
|
||||
let location = borrow.reserve_location;
|
||||
debug!("annotate_argument_and_return_for_borrow: location={:?}", location);
|
||||
if let Some(&Statement { kind: StatementKind::Assign(box (ref reservation, _)), .. }) =
|
||||
if let Some(Statement { kind: StatementKind::Assign(box (reservation, _)), .. }) =
|
||||
&self.body[location.block].statements.get(location.statement_index)
|
||||
{
|
||||
debug!("annotate_argument_and_return_for_borrow: reservation={:?}", reservation);
|
||||
@ -2335,8 +2480,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
// Check if our `target` was captured by a closure.
|
||||
if let Rvalue::Aggregate(
|
||||
box AggregateKind::Closure(def_id, substs),
|
||||
ref operands,
|
||||
) = *rvalue
|
||||
operands,
|
||||
) = rvalue
|
||||
{
|
||||
for operand in operands {
|
||||
let (Operand::Copy(assigned_from) | Operand::Move(assigned_from)) = operand else {
|
||||
@ -2360,7 +2505,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
// into a place then we should annotate the closure in
|
||||
// case it ends up being assigned into the return place.
|
||||
annotated_closure =
|
||||
self.annotate_fn_sig(def_id, substs.as_closure().sig());
|
||||
self.annotate_fn_sig(*def_id, substs.as_closure().sig());
|
||||
debug!(
|
||||
"annotate_argument_and_return_for_borrow: \
|
||||
annotated_closure={:?} assigned_from_local={:?} \
|
||||
@ -2527,7 +2672,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
if let hir::TyKind::Rptr(lifetime, _) = &fn_decl.inputs[index].kind {
|
||||
// With access to the lifetime, we can get
|
||||
// the span of it.
|
||||
arguments.push((*argument, lifetime.span));
|
||||
arguments.push((*argument, lifetime.ident.span));
|
||||
} else {
|
||||
bug!("ty type is a ref but hir type is not");
|
||||
}
|
||||
@ -2546,7 +2691,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
let mut return_span = fn_decl.output.span();
|
||||
if let hir::FnRetTy::Return(ty) = &fn_decl.output {
|
||||
if let hir::TyKind::Rptr(lifetime, _) = ty.kind {
|
||||
return_span = lifetime.span;
|
||||
return_span = lifetime.ident.span;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -469,8 +469,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
} else if self.was_captured_by_trait_object(borrow) {
|
||||
LaterUseKind::TraitCapture
|
||||
} else if location.statement_index == block.statements.len() {
|
||||
if let TerminatorKind::Call { ref func, from_hir_call: true, .. } =
|
||||
block.terminator().kind
|
||||
if let TerminatorKind::Call { func, from_hir_call: true, .. } =
|
||||
&block.terminator().kind
|
||||
{
|
||||
// Just point to the function, to reduce the chance of overlapping spans.
|
||||
let function_span = match func {
|
||||
@ -515,19 +515,16 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
// will only ever have one item at any given time, but by using a vector, we can pop from
|
||||
// it which simplifies the termination logic.
|
||||
let mut queue = vec![location];
|
||||
let mut target = if let Some(&Statement {
|
||||
kind: StatementKind::Assign(box (ref place, _)),
|
||||
..
|
||||
}) = stmt
|
||||
{
|
||||
if let Some(local) = place.as_local() {
|
||||
local
|
||||
let mut target =
|
||||
if let Some(Statement { kind: StatementKind::Assign(box (place, _)), .. }) = stmt {
|
||||
if let Some(local) = place.as_local() {
|
||||
local
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
};
|
||||
};
|
||||
|
||||
debug!("was_captured_by_trait: target={:?} queue={:?}", target, queue);
|
||||
while let Some(current_location) = queue.pop() {
|
||||
|
||||
@ -1,3 +1,6 @@
|
||||
#![deny(rustc::untranslatable_diagnostic)]
|
||||
#![deny(rustc::diagnostic_outside_of_impl)]
|
||||
|
||||
use std::collections::BTreeSet;
|
||||
|
||||
use rustc_middle::mir::visit::{PlaceContext, Visitor};
|
||||
|
||||
@ -1,3 +1,6 @@
|
||||
#![deny(rustc::untranslatable_diagnostic)]
|
||||
#![deny(rustc::diagnostic_outside_of_impl)]
|
||||
|
||||
use std::collections::VecDeque;
|
||||
use std::rc::Rc;
|
||||
|
||||
|
||||
@ -70,7 +70,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
location: Location,
|
||||
place: PlaceRef<'tcx>,
|
||||
diag: &mut Diagnostic,
|
||||
) {
|
||||
) -> bool {
|
||||
debug!("add_moved_or_invoked_closure_note: location={:?} place={:?}", location, place);
|
||||
let mut target = place.local_or_deref_local();
|
||||
for stmt in &self.body[location.block].statements[location.statement_index..] {
|
||||
@ -78,7 +78,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
if let StatementKind::Assign(box (into, Rvalue::Use(from))) = &stmt.kind {
|
||||
debug!("add_fnonce_closure_note: into={:?} from={:?}", into, from);
|
||||
match from {
|
||||
Operand::Copy(ref place) | Operand::Move(ref place)
|
||||
Operand::Copy(place) | Operand::Move(place)
|
||||
if target == place.local_or_deref_local() =>
|
||||
{
|
||||
target = into.local_or_deref_local()
|
||||
@ -101,12 +101,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
debug!("add_moved_or_invoked_closure_note: id={:?}", id);
|
||||
if Some(self.infcx.tcx.parent(id)) == self.infcx.tcx.lang_items().fn_once_trait() {
|
||||
let closure = match args.first() {
|
||||
Some(Operand::Copy(ref place)) | Some(Operand::Move(ref place))
|
||||
Some(Operand::Copy(place) | Operand::Move(place))
|
||||
if target == place.local_or_deref_local() =>
|
||||
{
|
||||
place.local_or_deref_local().unwrap()
|
||||
}
|
||||
_ => return,
|
||||
_ => return false,
|
||||
};
|
||||
|
||||
debug!("add_moved_or_invoked_closure_note: closure={:?}", closure);
|
||||
@ -125,7 +125,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
ty::place_to_string_for_capture(self.infcx.tcx, hir_place)
|
||||
),
|
||||
);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -149,9 +149,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
ty::place_to_string_for_capture(self.infcx.tcx, hir_place)
|
||||
),
|
||||
);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
/// End-user visible description of `place` if one can be found.
|
||||
@ -350,7 +352,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
} else {
|
||||
def.non_enum_variant()
|
||||
};
|
||||
if !including_tuple_field.0 && variant.ctor_kind == CtorKind::Fn {
|
||||
if !including_tuple_field.0 && variant.ctor_kind() == Some(CtorKind::Fn) {
|
||||
return None;
|
||||
}
|
||||
Some(variant.fields[field.index()].name.to_string())
|
||||
@ -437,9 +439,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
if !is_terminator {
|
||||
continue;
|
||||
} else if let Some(Terminator {
|
||||
kind: TerminatorKind::Call { ref func, from_hir_call: false, .. },
|
||||
kind: TerminatorKind::Call { func, from_hir_call: false, .. },
|
||||
..
|
||||
}) = bbd.terminator
|
||||
}) = &bbd.terminator
|
||||
{
|
||||
if let Some(source) =
|
||||
BorrowedContentSource::from_call(func.ty(self.body, tcx), tcx)
|
||||
@ -588,22 +590,45 @@ impl UseSpans<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
// Add a span label to the arguments of the closure, if it exists.
|
||||
/// Add a span label to the arguments of the closure, if it exists.
|
||||
pub(super) fn args_span_label(self, err: &mut Diagnostic, message: impl Into<String>) {
|
||||
if let UseSpans::ClosureUse { args_span, .. } = self {
|
||||
err.span_label(args_span, message);
|
||||
}
|
||||
}
|
||||
|
||||
// Add a span label to the use of the captured variable, if it exists.
|
||||
// only adds label to the `path_span`
|
||||
pub(super) fn var_span_label_path_only(self, err: &mut Diagnostic, message: impl Into<String>) {
|
||||
if let UseSpans::ClosureUse { path_span, .. } = self {
|
||||
err.span_label(path_span, message);
|
||||
/// Add a span label to the use of the captured variable, if it exists.
|
||||
/// only adds label to the `path_span`
|
||||
pub(super) fn var_path_only_subdiag(
|
||||
self,
|
||||
err: &mut Diagnostic,
|
||||
action: crate::InitializationRequiringAction,
|
||||
) {
|
||||
use crate::session_diagnostics::CaptureVarPathUseCause::*;
|
||||
use crate::InitializationRequiringAction::*;
|
||||
if let UseSpans::ClosureUse { generator_kind, path_span, .. } = self {
|
||||
match generator_kind {
|
||||
Some(_) => {
|
||||
err.subdiagnostic(match action {
|
||||
Borrow => BorrowInGenerator { path_span },
|
||||
MatchOn | Use => UseInGenerator { path_span },
|
||||
Assignment => AssignInGenerator { path_span },
|
||||
PartialAssignment => AssignPartInGenerator { path_span },
|
||||
});
|
||||
}
|
||||
None => {
|
||||
err.subdiagnostic(match action {
|
||||
Borrow => BorrowInClosure { path_span },
|
||||
MatchOn | Use => UseInClosure { path_span },
|
||||
Assignment => AssignInClosure { path_span },
|
||||
PartialAssignment => AssignPartInClosure { path_span },
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add a span label to the use of the captured variable, if it exists.
|
||||
/// Add a span label to the use of the captured variable, if it exists.
|
||||
pub(super) fn var_span_label(
|
||||
self,
|
||||
err: &mut Diagnostic,
|
||||
@ -623,6 +648,35 @@ impl UseSpans<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Add a subdiagnostic to the use of the captured variable, if it exists.
|
||||
pub(super) fn var_subdiag(
|
||||
self,
|
||||
err: &mut Diagnostic,
|
||||
kind: Option<rustc_middle::mir::BorrowKind>,
|
||||
f: impl Fn(Option<GeneratorKind>, Span) -> crate::session_diagnostics::CaptureVarCause,
|
||||
) {
|
||||
use crate::session_diagnostics::CaptureVarKind::*;
|
||||
if let UseSpans::ClosureUse { generator_kind, capture_kind_span, path_span, .. } = self {
|
||||
if capture_kind_span != path_span {
|
||||
err.subdiagnostic(match kind {
|
||||
Some(kd) => match kd {
|
||||
rustc_middle::mir::BorrowKind::Shared
|
||||
| rustc_middle::mir::BorrowKind::Shallow
|
||||
| rustc_middle::mir::BorrowKind::Unique => {
|
||||
Immute { kind_span: capture_kind_span }
|
||||
}
|
||||
|
||||
rustc_middle::mir::BorrowKind::Mut { .. } => {
|
||||
Mut { kind_span: capture_kind_span }
|
||||
}
|
||||
},
|
||||
None => Move { kind_span: capture_kind_span },
|
||||
});
|
||||
};
|
||||
err.subdiagnostic(f(generator_kind, path_span));
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `false` if this place is not used in a closure.
|
||||
pub(super) fn for_closure(&self) -> bool {
|
||||
match *self {
|
||||
@ -757,33 +811,30 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
};
|
||||
|
||||
debug!("move_spans: moved_place={:?} location={:?} stmt={:?}", moved_place, location, stmt);
|
||||
if let StatementKind::Assign(box (_, Rvalue::Aggregate(ref kind, ref places))) = stmt.kind {
|
||||
match **kind {
|
||||
AggregateKind::Closure(def_id, _) | AggregateKind::Generator(def_id, _, _) => {
|
||||
debug!("move_spans: def_id={:?} places={:?}", def_id, places);
|
||||
if let Some((args_span, generator_kind, capture_kind_span, path_span)) =
|
||||
self.closure_span(def_id, moved_place, places)
|
||||
{
|
||||
return ClosureUse {
|
||||
generator_kind,
|
||||
args_span,
|
||||
capture_kind_span,
|
||||
path_span,
|
||||
};
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
if let StatementKind::Assign(box (_, Rvalue::Aggregate(kind, places))) = &stmt.kind
|
||||
&& let AggregateKind::Closure(def_id, _) | AggregateKind::Generator(def_id, _, _) = **kind
|
||||
{
|
||||
debug!("move_spans: def_id={:?} places={:?}", def_id, places);
|
||||
if let Some((args_span, generator_kind, capture_kind_span, path_span)) =
|
||||
self.closure_span(def_id, moved_place, places)
|
||||
{
|
||||
return ClosureUse {
|
||||
generator_kind,
|
||||
args_span,
|
||||
capture_kind_span,
|
||||
path_span,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// StatementKind::FakeRead only contains a def_id if they are introduced as a result
|
||||
// of pattern matching within a closure.
|
||||
if let StatementKind::FakeRead(box (cause, ref place)) = stmt.kind {
|
||||
if let StatementKind::FakeRead(box (cause, place)) = stmt.kind {
|
||||
match cause {
|
||||
FakeReadCause::ForMatchedPlace(Some(closure_def_id))
|
||||
| FakeReadCause::ForLet(Some(closure_def_id)) => {
|
||||
debug!("move_spans: def_id={:?} place={:?}", closure_def_id, place);
|
||||
let places = &[Operand::Move(*place)];
|
||||
let places = &[Operand::Move(place)];
|
||||
if let Some((args_span, generator_kind, capture_kind_span, path_span)) =
|
||||
self.closure_span(closure_def_id, moved_place, places)
|
||||
{
|
||||
@ -870,7 +921,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
debug!("borrow_spans: use_span={:?} location={:?}", use_span, location);
|
||||
|
||||
let target = match self.body[location.block].statements.get(location.statement_index) {
|
||||
Some(&Statement { kind: StatementKind::Assign(box (ref place, _)), .. }) => {
|
||||
Some(Statement { kind: StatementKind::Assign(box (place, _)), .. }) => {
|
||||
if let Some(local) = place.as_local() {
|
||||
local
|
||||
} else {
|
||||
@ -886,9 +937,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
}
|
||||
|
||||
for stmt in &self.body[location.block].statements[location.statement_index + 1..] {
|
||||
if let StatementKind::Assign(box (_, Rvalue::Aggregate(ref kind, ref places))) =
|
||||
stmt.kind
|
||||
{
|
||||
if let StatementKind::Assign(box (_, Rvalue::Aggregate(kind, places))) = &stmt.kind {
|
||||
let (&def_id, is_generator) = match kind {
|
||||
box AggregateKind::Closure(def_id, _) => (def_id, false),
|
||||
box AggregateKind::Generator(def_id, _, _) => (def_id, true),
|
||||
|
||||
@ -1,6 +1,4 @@
|
||||
use rustc_errors::{
|
||||
Applicability, Diagnostic, DiagnosticBuilder, EmissionGuarantee, ErrorGuaranteed,
|
||||
};
|
||||
use rustc_errors::{Applicability, Diagnostic};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::intravisit::Visitor;
|
||||
use rustc_hir::Node;
|
||||
@ -221,8 +219,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
PlaceRef {
|
||||
local,
|
||||
projection:
|
||||
&[
|
||||
ref proj_base @ ..,
|
||||
[
|
||||
proj_base @ ..,
|
||||
ProjectionElem::Deref,
|
||||
ProjectionElem::Field(field, _),
|
||||
ProjectionElem::Deref,
|
||||
@ -233,7 +231,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
if let Some(span) = get_mut_span_in_struct_field(
|
||||
self.infcx.tcx,
|
||||
Place::ty_from(local, proj_base, self.body, self.infcx.tcx).ty,
|
||||
field,
|
||||
*field,
|
||||
) {
|
||||
err.span_suggestion_verbose(
|
||||
span,
|
||||
@ -391,13 +389,13 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
// diagnostic: if the span starts with a mutable borrow of
|
||||
// a local variable, then just suggest the user remove it.
|
||||
PlaceRef { local: _, projection: [] }
|
||||
if {
|
||||
if let Ok(snippet) = self.infcx.tcx.sess.source_map().span_to_snippet(span) {
|
||||
snippet.starts_with("&mut ")
|
||||
} else {
|
||||
false
|
||||
}
|
||||
} =>
|
||||
if self
|
||||
.infcx
|
||||
.tcx
|
||||
.sess
|
||||
.source_map()
|
||||
.span_to_snippet(span)
|
||||
.map_or(false, |snippet| snippet.starts_with("&mut ")) =>
|
||||
{
|
||||
err.span_label(span, format!("cannot {ACT}", ACT = act));
|
||||
err.span_suggestion(
|
||||
@ -629,25 +627,20 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
self.buffer_error(err);
|
||||
}
|
||||
|
||||
fn suggest_map_index_mut_alternatives(
|
||||
&self,
|
||||
ty: Ty<'_>,
|
||||
err: &mut DiagnosticBuilder<'_, ErrorGuaranteed>,
|
||||
span: Span,
|
||||
) {
|
||||
fn suggest_map_index_mut_alternatives(&self, ty: Ty<'tcx>, err: &mut Diagnostic, span: Span) {
|
||||
let Some(adt) = ty.ty_adt_def() else { return };
|
||||
let did = adt.did();
|
||||
if self.infcx.tcx.is_diagnostic_item(sym::HashMap, did)
|
||||
|| self.infcx.tcx.is_diagnostic_item(sym::BTreeMap, did)
|
||||
{
|
||||
struct V<'a, 'b, 'tcx, G: EmissionGuarantee> {
|
||||
struct V<'a, 'tcx> {
|
||||
assign_span: Span,
|
||||
err: &'a mut DiagnosticBuilder<'b, G>,
|
||||
err: &'a mut Diagnostic,
|
||||
ty: Ty<'tcx>,
|
||||
suggested: bool,
|
||||
}
|
||||
impl<'a, 'b: 'a, 'hir, 'tcx, G: EmissionGuarantee> Visitor<'hir> for V<'a, 'b, 'tcx, G> {
|
||||
fn visit_stmt(&mut self, stmt: &'hir hir::Stmt<'hir>) {
|
||||
impl<'a, 'tcx> Visitor<'tcx> for V<'a, 'tcx> {
|
||||
fn visit_stmt(&mut self, stmt: &'tcx hir::Stmt<'tcx>) {
|
||||
hir::intravisit::walk_stmt(self, stmt);
|
||||
let expr = match stmt.kind {
|
||||
hir::StmtKind::Semi(expr) | hir::StmtKind::Expr(expr) => expr,
|
||||
@ -705,7 +698,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
),
|
||||
(rv.span.shrink_to_hi(), ")".to_string()),
|
||||
],
|
||||
].into_iter(),
|
||||
],
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
self.suggested = true;
|
||||
@ -1218,7 +1211,7 @@ fn get_mut_span_in_struct_field<'tcx>(
|
||||
&& let hir::Node::Field(field) = node
|
||||
&& let hir::TyKind::Rptr(lt, hir::MutTy { mutbl: hir::Mutability::Not, ty }) = field.ty.kind
|
||||
{
|
||||
return Some(lt.span.between(ty.span));
|
||||
return Some(lt.ident.span.between(ty.span));
|
||||
}
|
||||
|
||||
None
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
#![deny(rustc::diagnostic_outside_of_impl)]
|
||||
//! Error reporting machinery for lifetime errors.
|
||||
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_data_structures::fx::FxIndexSet;
|
||||
use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, MultiSpan};
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::intravisit::Visitor;
|
||||
@ -21,7 +21,7 @@ use rustc_middle::ty::subst::InternalSubsts;
|
||||
use rustc_middle::ty::Region;
|
||||
use rustc_middle::ty::TypeVisitor;
|
||||
use rustc_middle::ty::{self, RegionVid, Ty};
|
||||
use rustc_span::symbol::{kw, sym, Ident};
|
||||
use rustc_span::symbol::{kw, Ident};
|
||||
use rustc_span::Span;
|
||||
|
||||
use crate::borrowck_errors;
|
||||
@ -181,7 +181,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
// Try to convert the lower-bound region into something named we can print for the user.
|
||||
let lower_bound_region = self.to_error_region(type_test.lower_bound);
|
||||
|
||||
let type_test_span = type_test.locations.span(&self.body);
|
||||
let type_test_span = type_test.span;
|
||||
|
||||
if let Some(lower_bound_region) = lower_bound_region {
|
||||
let generic_ty = type_test.generic_kind.to_ty(self.infcx.tcx);
|
||||
@ -276,7 +276,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
fn get_impl_ident_and_self_ty_from_trait(
|
||||
&self,
|
||||
def_id: DefId,
|
||||
trait_objects: &FxHashSet<DefId>,
|
||||
trait_objects: &FxIndexSet<DefId>,
|
||||
) -> Option<(Ident, &'tcx hir::Ty<'tcx>)> {
|
||||
let tcx = self.infcx.tcx;
|
||||
match tcx.hir().get_if_local(def_id) {
|
||||
@ -514,9 +514,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
span: *span,
|
||||
ty_err: match output_ty.kind() {
|
||||
ty::Closure(_, _) => FnMutReturnTypeErr::ReturnClosure { span: *span },
|
||||
ty::Adt(def, _)
|
||||
if self.infcx.tcx.is_diagnostic_item(sym::gen_future, def.did()) =>
|
||||
{
|
||||
ty::Generator(def, ..) if self.infcx.tcx.generator_is_async(*def) => {
|
||||
FnMutReturnTypeErr::ReturnAsyncBlock { span: *span }
|
||||
}
|
||||
_ => FnMutReturnTypeErr::ReturnRef { span: *span },
|
||||
@ -830,7 +828,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
};
|
||||
debug!(?param);
|
||||
|
||||
let mut visitor = TraitObjectVisitor(FxHashSet::default());
|
||||
let mut visitor = TraitObjectVisitor(FxIndexSet::default());
|
||||
visitor.visit_ty(param.param_ty);
|
||||
|
||||
let Some((ident, self_ty)) =
|
||||
@ -843,7 +841,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
fn suggest_constrain_dyn_trait_in_impl(
|
||||
&self,
|
||||
err: &mut Diagnostic,
|
||||
found_dids: &FxHashSet<DefId>,
|
||||
found_dids: &FxIndexSet<DefId>,
|
||||
ident: Ident,
|
||||
self_ty: &hir::Ty<'_>,
|
||||
) -> bool {
|
||||
@ -923,14 +921,18 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
hir::ExprKind::Block(blk, _) => {
|
||||
if let Some(ref expr) = blk.expr {
|
||||
if let Some(expr) = blk.expr {
|
||||
// only when the block is a closure
|
||||
if let hir::ExprKind::Closure(hir::Closure {
|
||||
capture_clause: hir::CaptureBy::Ref,
|
||||
body,
|
||||
..
|
||||
}) = expr.kind
|
||||
{
|
||||
closure_span = Some(expr.span.shrink_to_lo());
|
||||
let body = map.body(*body);
|
||||
if !matches!(body.generator_kind, Some(hir::GeneratorKind::Async(..))) {
|
||||
closure_span = Some(expr.span.shrink_to_lo());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -254,7 +254,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
|
||||
.or_else(|| self.give_name_if_anonymous_region_appears_in_impl_signature(fr))
|
||||
.or_else(|| self.give_name_if_anonymous_region_appears_in_arg_position_impl_trait(fr));
|
||||
|
||||
if let Some(ref value) = value {
|
||||
if let Some(value) = &value {
|
||||
self.region_names.try_borrow_mut().unwrap().insert(fr, value.clone());
|
||||
}
|
||||
|
||||
@ -355,7 +355,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
|
||||
})
|
||||
}
|
||||
|
||||
ty::BoundRegionKind::BrAnon(_) => None,
|
||||
ty::BoundRegionKind::BrAnon(..) => None,
|
||||
},
|
||||
|
||||
ty::ReLateBound(..) | ty::ReVar(..) | ty::RePlaceholder(..) | ty::ReErased => None,
|
||||
@ -576,30 +576,10 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
|
||||
let args = last_segment.args.as_ref()?;
|
||||
let lifetime =
|
||||
self.try_match_adt_and_generic_args(substs, needle_fr, args, search_stack)?;
|
||||
match lifetime.name {
|
||||
hir::LifetimeName::Param(_, hir::ParamName::Plain(_) | hir::ParamName::Error)
|
||||
| hir::LifetimeName::Error
|
||||
| hir::LifetimeName::Static => {
|
||||
let lifetime_span = lifetime.span;
|
||||
Some(RegionNameHighlight::MatchedAdtAndSegment(lifetime_span))
|
||||
}
|
||||
|
||||
hir::LifetimeName::Param(_, hir::ParamName::Fresh)
|
||||
| hir::LifetimeName::ImplicitObjectLifetimeDefault
|
||||
| hir::LifetimeName::Infer => {
|
||||
// In this case, the user left off the lifetime; so
|
||||
// they wrote something like:
|
||||
//
|
||||
// ```
|
||||
// x: Foo<T>
|
||||
// ```
|
||||
//
|
||||
// where the fully elaborated form is `Foo<'_, '1,
|
||||
// T>`. We don't consider this a match; instead we let
|
||||
// the "fully elaborated" type fallback above handle
|
||||
// it.
|
||||
None
|
||||
}
|
||||
if lifetime.is_anonymous() {
|
||||
None
|
||||
} else {
|
||||
Some(RegionNameHighlight::MatchedAdtAndSegment(lifetime.ident.span))
|
||||
}
|
||||
}
|
||||
|
||||
@ -959,8 +939,8 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
|
||||
{
|
||||
predicates.iter().any(|pred| {
|
||||
match pred.kind().skip_binder() {
|
||||
ty::PredicateKind::Trait(data) if data.self_ty() == ty => {}
|
||||
ty::PredicateKind::Projection(data) if data.projection_ty.self_ty() == ty => {}
|
||||
ty::PredicateKind::Clause(ty::Clause::Trait(data)) if data.self_ty() == ty => {}
|
||||
ty::PredicateKind::Clause(ty::Clause::Projection(data)) if data.projection_ty.self_ty() == ty => {}
|
||||
_ => return false,
|
||||
}
|
||||
tcx.any_free_region_meets(pred, |r| {
|
||||
|
||||
@ -1,3 +1,6 @@
|
||||
#![deny(rustc::untranslatable_diagnostic)]
|
||||
#![deny(rustc::diagnostic_outside_of_impl)]
|
||||
|
||||
use crate::Upvar;
|
||||
use crate::{nll::ToRegionVid, region_infer::RegionInferenceContext};
|
||||
use rustc_index::vec::{Idx, IndexVec};
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
#![deny(rustc::untranslatable_diagnostic)]
|
||||
#![deny(rustc::diagnostic_outside_of_impl)]
|
||||
use crate::location::{LocationIndex, LocationTable};
|
||||
use crate::BorrowIndex;
|
||||
use polonius_engine::AllFacts as PoloniusFacts;
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
#![deny(rustc::untranslatable_diagnostic)]
|
||||
#![deny(rustc::diagnostic_outside_of_impl)]
|
||||
use rustc_data_structures::graph::dominators::Dominators;
|
||||
use rustc_middle::mir::visit::Visitor;
|
||||
use rustc_middle::mir::{self, BasicBlock, Body, Location, NonDivergingIntrinsic, Place, Rvalue};
|
||||
@ -67,9 +69,9 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
|
||||
self.consume_operand(location, op);
|
||||
}
|
||||
StatementKind::Intrinsic(box NonDivergingIntrinsic::CopyNonOverlapping(mir::CopyNonOverlapping {
|
||||
ref src,
|
||||
ref dst,
|
||||
ref count,
|
||||
src,
|
||||
dst,
|
||||
count,
|
||||
})) => {
|
||||
self.consume_operand(location, src);
|
||||
self.consume_operand(location, dst);
|
||||
@ -104,7 +106,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
|
||||
self.check_activations(location);
|
||||
|
||||
match &terminator.kind {
|
||||
TerminatorKind::SwitchInt { ref discr, switch_ty: _, targets: _ } => {
|
||||
TerminatorKind::SwitchInt { discr, switch_ty: _, targets: _ } => {
|
||||
self.consume_operand(location, discr);
|
||||
}
|
||||
TerminatorKind::Drop { place: drop_place, target: _, unwind: _ } => {
|
||||
@ -117,7 +119,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
|
||||
}
|
||||
TerminatorKind::DropAndReplace {
|
||||
place: drop_place,
|
||||
value: ref new_value,
|
||||
value: new_value,
|
||||
target: _,
|
||||
unwind: _,
|
||||
} => {
|
||||
@ -125,8 +127,8 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
|
||||
self.consume_operand(location, new_value);
|
||||
}
|
||||
TerminatorKind::Call {
|
||||
ref func,
|
||||
ref args,
|
||||
func,
|
||||
args,
|
||||
destination,
|
||||
target: _,
|
||||
cleanup: _,
|
||||
@ -139,15 +141,15 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
|
||||
}
|
||||
self.mutate_place(location, *destination, Deep);
|
||||
}
|
||||
TerminatorKind::Assert { ref cond, expected: _, ref msg, target: _, cleanup: _ } => {
|
||||
TerminatorKind::Assert { cond, expected: _, msg, target: _, cleanup: _ } => {
|
||||
self.consume_operand(location, cond);
|
||||
use rustc_middle::mir::AssertKind;
|
||||
if let AssertKind::BoundsCheck { ref len, ref index } = *msg {
|
||||
if let AssertKind::BoundsCheck { len, index } = msg {
|
||||
self.consume_operand(location, len);
|
||||
self.consume_operand(location, index);
|
||||
}
|
||||
}
|
||||
TerminatorKind::Yield { ref value, resume, resume_arg, drop: _ } => {
|
||||
TerminatorKind::Yield { value, resume, resume_arg, drop: _ } => {
|
||||
self.consume_operand(location, value);
|
||||
|
||||
// Invalidate all borrows of local places
|
||||
@ -173,25 +175,25 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
|
||||
}
|
||||
TerminatorKind::InlineAsm {
|
||||
template: _,
|
||||
ref operands,
|
||||
operands,
|
||||
options: _,
|
||||
line_spans: _,
|
||||
destination: _,
|
||||
cleanup: _,
|
||||
} => {
|
||||
for op in operands {
|
||||
match *op {
|
||||
InlineAsmOperand::In { reg: _, ref value } => {
|
||||
match op {
|
||||
InlineAsmOperand::In { reg: _, value } => {
|
||||
self.consume_operand(location, value);
|
||||
}
|
||||
InlineAsmOperand::Out { reg: _, late: _, place, .. } => {
|
||||
if let Some(place) = place {
|
||||
if let &Some(place) = place {
|
||||
self.mutate_place(location, place, Shallow(None));
|
||||
}
|
||||
}
|
||||
InlineAsmOperand::InOut { reg: _, late: _, ref in_value, out_place } => {
|
||||
InlineAsmOperand::InOut { reg: _, late: _, in_value, out_place } => {
|
||||
self.consume_operand(location, in_value);
|
||||
if let Some(out_place) = out_place {
|
||||
if let &Some(out_place) = out_place {
|
||||
self.mutate_place(location, out_place, Shallow(None));
|
||||
}
|
||||
}
|
||||
@ -250,8 +252,8 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> {
|
||||
|
||||
// Simulates consumption of an rvalue
|
||||
fn consume_rvalue(&mut self, location: Location, rvalue: &Rvalue<'tcx>) {
|
||||
match *rvalue {
|
||||
Rvalue::Ref(_ /*rgn*/, bk, place) => {
|
||||
match rvalue {
|
||||
&Rvalue::Ref(_ /*rgn*/, bk, place) => {
|
||||
let access_kind = match bk {
|
||||
BorrowKind::Shallow => {
|
||||
(Shallow(Some(ArtificialField::ShallowBorrow)), Read(ReadKind::Borrow(bk)))
|
||||
@ -270,7 +272,7 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> {
|
||||
self.access_place(location, place, access_kind, LocalMutationIsAllowed::No);
|
||||
}
|
||||
|
||||
Rvalue::AddressOf(mutability, place) => {
|
||||
&Rvalue::AddressOf(mutability, place) => {
|
||||
let access_kind = match mutability {
|
||||
Mutability::Mut => (
|
||||
Deep,
|
||||
@ -286,20 +288,19 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> {
|
||||
|
||||
Rvalue::ThreadLocalRef(_) => {}
|
||||
|
||||
Rvalue::Use(ref operand)
|
||||
| Rvalue::Repeat(ref operand, _)
|
||||
| Rvalue::UnaryOp(_ /*un_op*/, ref operand)
|
||||
| Rvalue::Cast(_ /*cast_kind*/, ref operand, _ /*ty*/)
|
||||
| Rvalue::ShallowInitBox(ref operand, _ /*ty*/) => {
|
||||
self.consume_operand(location, operand)
|
||||
}
|
||||
Rvalue::CopyForDeref(ref place) => {
|
||||
let op = &Operand::Copy(*place);
|
||||
Rvalue::Use(operand)
|
||||
| Rvalue::Repeat(operand, _)
|
||||
| Rvalue::UnaryOp(_ /*un_op*/, operand)
|
||||
| Rvalue::Cast(_ /*cast_kind*/, operand, _ /*ty*/)
|
||||
| Rvalue::ShallowInitBox(operand, _ /*ty*/) => self.consume_operand(location, operand),
|
||||
|
||||
&Rvalue::CopyForDeref(place) => {
|
||||
let op = &Operand::Copy(place);
|
||||
self.consume_operand(location, op);
|
||||
}
|
||||
|
||||
Rvalue::Len(place) | Rvalue::Discriminant(place) => {
|
||||
let af = match *rvalue {
|
||||
&(Rvalue::Len(place) | Rvalue::Discriminant(place)) => {
|
||||
let af = match rvalue {
|
||||
Rvalue::Len(..) => Some(ArtificialField::ArrayLength),
|
||||
Rvalue::Discriminant(..) => None,
|
||||
_ => unreachable!(),
|
||||
@ -312,15 +313,15 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> {
|
||||
);
|
||||
}
|
||||
|
||||
Rvalue::BinaryOp(_bin_op, box (ref operand1, ref operand2))
|
||||
| Rvalue::CheckedBinaryOp(_bin_op, box (ref operand1, ref operand2)) => {
|
||||
Rvalue::BinaryOp(_bin_op, box (operand1, operand2))
|
||||
| Rvalue::CheckedBinaryOp(_bin_op, box (operand1, operand2)) => {
|
||||
self.consume_operand(location, operand1);
|
||||
self.consume_operand(location, operand2);
|
||||
}
|
||||
|
||||
Rvalue::NullaryOp(_op, _ty) => {}
|
||||
|
||||
Rvalue::Aggregate(_, ref operands) => {
|
||||
Rvalue::Aggregate(_, operands) => {
|
||||
for operand in operands {
|
||||
self.consume_operand(location, operand);
|
||||
}
|
||||
|
||||
@ -18,7 +18,8 @@ extern crate tracing;
|
||||
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_data_structures::graph::dominators::Dominators;
|
||||
use rustc_errors::{Diagnostic, DiagnosticBuilder, ErrorGuaranteed};
|
||||
use rustc_data_structures::vec_map::VecMap;
|
||||
use rustc_errors::{Diagnostic, DiagnosticBuilder};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::LocalDefId;
|
||||
use rustc_index::bit_set::ChunkedBitSet;
|
||||
@ -82,7 +83,7 @@ mod type_check;
|
||||
mod universal_regions;
|
||||
mod used_muts;
|
||||
|
||||
// A public API provided for the Rust compiler consumers.
|
||||
/// A public API provided for the Rust compiler consumers.
|
||||
pub mod consumers;
|
||||
|
||||
use borrow_set::{BorrowData, BorrowSet};
|
||||
@ -129,6 +130,19 @@ fn mir_borrowck<'tcx>(
|
||||
) -> &'tcx BorrowCheckResult<'tcx> {
|
||||
let (input_body, promoted) = tcx.mir_promoted(def);
|
||||
debug!("run query mir_borrowck: {}", tcx.def_path_str(def.did.to_def_id()));
|
||||
|
||||
if input_body.borrow().should_skip() {
|
||||
debug!("Skipping borrowck because of injected body");
|
||||
// Let's make up a borrowck result! Fun times!
|
||||
let result = BorrowCheckResult {
|
||||
concrete_opaque_types: VecMap::new(),
|
||||
closure_requirements: None,
|
||||
used_mut_upvars: SmallVec::new(),
|
||||
tainted_by_errors: None,
|
||||
};
|
||||
return tcx.arena.alloc(result);
|
||||
}
|
||||
|
||||
let hir_owner = tcx.hir().local_def_id_to_hir_id(def.did).owner;
|
||||
|
||||
let infcx =
|
||||
@ -178,13 +192,13 @@ fn do_mir_borrowck<'tcx>(
|
||||
}
|
||||
}
|
||||
|
||||
let mut errors = error::BorrowckErrors::new();
|
||||
let mut errors = error::BorrowckErrors::new(infcx.tcx);
|
||||
|
||||
// Gather the upvars of a closure, if any.
|
||||
let tables = tcx.typeck_opt_const_arg(def);
|
||||
if let Some(ErrorGuaranteed { .. }) = tables.tainted_by_errors {
|
||||
infcx.set_tainted_by_errors();
|
||||
errors.set_tainted_by_errors();
|
||||
if let Some(e) = tables.tainted_by_errors {
|
||||
infcx.set_tainted_by_errors(e);
|
||||
errors.set_tainted_by_errors(e);
|
||||
}
|
||||
let upvars: Vec<_> = tables
|
||||
.closure_min_captures_flattened(def.did)
|
||||
@ -564,12 +578,12 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx
|
||||
self.check_activations(location, span, flow_state);
|
||||
|
||||
match &stmt.kind {
|
||||
StatementKind::Assign(box (lhs, ref rhs)) => {
|
||||
StatementKind::Assign(box (lhs, rhs)) => {
|
||||
self.consume_rvalue(location, (rhs, span), flow_state);
|
||||
|
||||
self.mutate_place(location, (*lhs, span), Shallow(None), flow_state);
|
||||
}
|
||||
StatementKind::FakeRead(box (_, ref place)) => {
|
||||
StatementKind::FakeRead(box (_, place)) => {
|
||||
// Read for match doesn't access any memory and is used to
|
||||
// assert that a place is safe and live. So we don't have to
|
||||
// do any checks here.
|
||||
@ -587,7 +601,7 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx
|
||||
flow_state,
|
||||
);
|
||||
}
|
||||
StatementKind::Intrinsic(box ref kind) => match kind {
|
||||
StatementKind::Intrinsic(box kind) => match kind {
|
||||
NonDivergingIntrinsic::Assume(op) => self.consume_operand(location, (op, span), flow_state),
|
||||
NonDivergingIntrinsic::CopyNonOverlapping(..) => span_bug!(
|
||||
span,
|
||||
@ -629,8 +643,8 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx
|
||||
|
||||
self.check_activations(loc, span, flow_state);
|
||||
|
||||
match term.kind {
|
||||
TerminatorKind::SwitchInt { ref discr, switch_ty: _, targets: _ } => {
|
||||
match &term.kind {
|
||||
TerminatorKind::SwitchInt { discr, switch_ty: _, targets: _ } => {
|
||||
self.consume_operand(loc, (discr, span), flow_state);
|
||||
}
|
||||
TerminatorKind::Drop { place, target: _, unwind: _ } => {
|
||||
@ -642,7 +656,7 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx
|
||||
|
||||
self.access_place(
|
||||
loc,
|
||||
(place, span),
|
||||
(*place, span),
|
||||
(AccessDepth::Drop, Write(WriteKind::StorageDeadOrDrop)),
|
||||
LocalMutationIsAllowed::Yes,
|
||||
flow_state,
|
||||
@ -650,16 +664,16 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx
|
||||
}
|
||||
TerminatorKind::DropAndReplace {
|
||||
place: drop_place,
|
||||
value: ref new_value,
|
||||
value: new_value,
|
||||
target: _,
|
||||
unwind: _,
|
||||
} => {
|
||||
self.mutate_place(loc, (drop_place, span), Deep, flow_state);
|
||||
self.mutate_place(loc, (*drop_place, span), Deep, flow_state);
|
||||
self.consume_operand(loc, (new_value, span), flow_state);
|
||||
}
|
||||
TerminatorKind::Call {
|
||||
ref func,
|
||||
ref args,
|
||||
func,
|
||||
args,
|
||||
destination,
|
||||
target: _,
|
||||
cleanup: _,
|
||||
@ -670,43 +684,43 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx
|
||||
for arg in args {
|
||||
self.consume_operand(loc, (arg, span), flow_state);
|
||||
}
|
||||
self.mutate_place(loc, (destination, span), Deep, flow_state);
|
||||
self.mutate_place(loc, (*destination, span), Deep, flow_state);
|
||||
}
|
||||
TerminatorKind::Assert { ref cond, expected: _, ref msg, target: _, cleanup: _ } => {
|
||||
TerminatorKind::Assert { cond, expected: _, msg, target: _, cleanup: _ } => {
|
||||
self.consume_operand(loc, (cond, span), flow_state);
|
||||
use rustc_middle::mir::AssertKind;
|
||||
if let AssertKind::BoundsCheck { ref len, ref index } = *msg {
|
||||
if let AssertKind::BoundsCheck { len, index } = msg {
|
||||
self.consume_operand(loc, (len, span), flow_state);
|
||||
self.consume_operand(loc, (index, span), flow_state);
|
||||
}
|
||||
}
|
||||
|
||||
TerminatorKind::Yield { ref value, resume: _, resume_arg, drop: _ } => {
|
||||
TerminatorKind::Yield { value, resume: _, resume_arg, drop: _ } => {
|
||||
self.consume_operand(loc, (value, span), flow_state);
|
||||
self.mutate_place(loc, (resume_arg, span), Deep, flow_state);
|
||||
self.mutate_place(loc, (*resume_arg, span), Deep, flow_state);
|
||||
}
|
||||
|
||||
TerminatorKind::InlineAsm {
|
||||
template: _,
|
||||
ref operands,
|
||||
operands,
|
||||
options: _,
|
||||
line_spans: _,
|
||||
destination: _,
|
||||
cleanup: _,
|
||||
} => {
|
||||
for op in operands {
|
||||
match *op {
|
||||
InlineAsmOperand::In { reg: _, ref value } => {
|
||||
match op {
|
||||
InlineAsmOperand::In { reg: _, value } => {
|
||||
self.consume_operand(loc, (value, span), flow_state);
|
||||
}
|
||||
InlineAsmOperand::Out { reg: _, late: _, place, .. } => {
|
||||
if let Some(place) = place {
|
||||
self.mutate_place(loc, (place, span), Shallow(None), flow_state);
|
||||
self.mutate_place(loc, (*place, span), Shallow(None), flow_state);
|
||||
}
|
||||
}
|
||||
InlineAsmOperand::InOut { reg: _, late: _, ref in_value, out_place } => {
|
||||
InlineAsmOperand::InOut { reg: _, late: _, in_value, out_place } => {
|
||||
self.consume_operand(loc, (in_value, span), flow_state);
|
||||
if let Some(out_place) = out_place {
|
||||
if let &Some(out_place) = out_place {
|
||||
self.mutate_place(
|
||||
loc,
|
||||
(out_place, span),
|
||||
@ -1150,8 +1164,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
(rvalue, span): (&'cx Rvalue<'tcx>, Span),
|
||||
flow_state: &Flows<'cx, 'tcx>,
|
||||
) {
|
||||
match *rvalue {
|
||||
Rvalue::Ref(_ /*rgn*/, bk, place) => {
|
||||
match rvalue {
|
||||
&Rvalue::Ref(_ /*rgn*/, bk, place) => {
|
||||
let access_kind = match bk {
|
||||
BorrowKind::Shallow => {
|
||||
(Shallow(Some(ArtificialField::ShallowBorrow)), Read(ReadKind::Borrow(bk)))
|
||||
@ -1189,7 +1203,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
);
|
||||
}
|
||||
|
||||
Rvalue::AddressOf(mutability, place) => {
|
||||
&Rvalue::AddressOf(mutability, place) => {
|
||||
let access_kind = match mutability {
|
||||
Mutability::Mut => (
|
||||
Deep,
|
||||
@ -1218,14 +1232,15 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
|
||||
Rvalue::ThreadLocalRef(_) => {}
|
||||
|
||||
Rvalue::Use(ref operand)
|
||||
| Rvalue::Repeat(ref operand, _)
|
||||
| Rvalue::UnaryOp(_ /*un_op*/, ref operand)
|
||||
| Rvalue::Cast(_ /*cast_kind*/, ref operand, _ /*ty*/)
|
||||
| Rvalue::ShallowInitBox(ref operand, _ /*ty*/) => {
|
||||
Rvalue::Use(operand)
|
||||
| Rvalue::Repeat(operand, _)
|
||||
| Rvalue::UnaryOp(_ /*un_op*/, operand)
|
||||
| Rvalue::Cast(_ /*cast_kind*/, operand, _ /*ty*/)
|
||||
| Rvalue::ShallowInitBox(operand, _ /*ty*/) => {
|
||||
self.consume_operand(location, (operand, span), flow_state)
|
||||
}
|
||||
Rvalue::CopyForDeref(place) => {
|
||||
|
||||
&Rvalue::CopyForDeref(place) => {
|
||||
self.access_place(
|
||||
location,
|
||||
(place, span),
|
||||
@ -1243,7 +1258,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
);
|
||||
}
|
||||
|
||||
Rvalue::Len(place) | Rvalue::Discriminant(place) => {
|
||||
&(Rvalue::Len(place) | Rvalue::Discriminant(place)) => {
|
||||
let af = match *rvalue {
|
||||
Rvalue::Len(..) => Some(ArtificialField::ArrayLength),
|
||||
Rvalue::Discriminant(..) => None,
|
||||
@ -1264,8 +1279,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
);
|
||||
}
|
||||
|
||||
Rvalue::BinaryOp(_bin_op, box (ref operand1, ref operand2))
|
||||
| Rvalue::CheckedBinaryOp(_bin_op, box (ref operand1, ref operand2)) => {
|
||||
Rvalue::BinaryOp(_bin_op, box (operand1, operand2))
|
||||
| Rvalue::CheckedBinaryOp(_bin_op, box (operand1, operand2)) => {
|
||||
self.consume_operand(location, (operand1, span), flow_state);
|
||||
self.consume_operand(location, (operand2, span), flow_state);
|
||||
}
|
||||
@ -1274,7 +1289,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
// nullary ops take no dynamic input; no borrowck effect.
|
||||
}
|
||||
|
||||
Rvalue::Aggregate(ref aggregate_kind, ref operands) => {
|
||||
Rvalue::Aggregate(aggregate_kind, operands) => {
|
||||
// We need to report back the list of mutable upvars that were
|
||||
// moved into the closure and subsequently used by the closure,
|
||||
// in order to populate our used_mut set.
|
||||
@ -2246,6 +2261,7 @@ mod error {
|
||||
use super::*;
|
||||
|
||||
pub struct BorrowckErrors<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
/// 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 #53807)
|
||||
@ -2268,19 +2284,24 @@ mod error {
|
||||
tainted_by_errors: Option<ErrorGuaranteed>,
|
||||
}
|
||||
|
||||
impl BorrowckErrors<'_> {
|
||||
pub fn new() -> Self {
|
||||
impl<'tcx> BorrowckErrors<'tcx> {
|
||||
pub fn new(tcx: TyCtxt<'tcx>) -> Self {
|
||||
BorrowckErrors {
|
||||
tcx,
|
||||
buffered_move_errors: BTreeMap::new(),
|
||||
buffered: Default::default(),
|
||||
tainted_by_errors: None,
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME(eddyb) this is a suboptimal API because `tainted_by_errors` is
|
||||
// set before any emission actually happens (weakening the guarantee).
|
||||
pub fn buffer_error(&mut self, t: DiagnosticBuilder<'_, ErrorGuaranteed>) {
|
||||
self.tainted_by_errors = Some(ErrorGuaranteed::unchecked_claim_error_was_emitted());
|
||||
if let None = self.tainted_by_errors {
|
||||
self.tainted_by_errors = Some(
|
||||
self.tcx
|
||||
.sess
|
||||
.delay_span_bug(t.span.clone(), "diagnostic buffered but not emitted"),
|
||||
)
|
||||
}
|
||||
t.buffer(&mut self.buffered);
|
||||
}
|
||||
|
||||
@ -2288,8 +2309,8 @@ mod error {
|
||||
t.buffer(&mut self.buffered);
|
||||
}
|
||||
|
||||
pub fn set_tainted_by_errors(&mut self) {
|
||||
self.tainted_by_errors = Some(ErrorGuaranteed::unchecked_claim_error_was_emitted());
|
||||
pub fn set_tainted_by_errors(&mut self, e: ErrorGuaranteed) {
|
||||
self.tainted_by_errors = Some(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
#![deny(rustc::untranslatable_diagnostic)]
|
||||
#![deny(rustc::diagnostic_outside_of_impl)]
|
||||
use rustc_index::vec::{Idx, IndexVec};
|
||||
use rustc_middle::mir::{BasicBlock, Body, Location};
|
||||
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
#![deny(rustc::untranslatable_diagnostic)]
|
||||
#![deny(rustc::diagnostic_outside_of_impl)]
|
||||
use rustc_data_structures::captures::Captures;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_index::vec::IndexVec;
|
||||
@ -9,6 +11,7 @@ use std::ops::Index;
|
||||
|
||||
/// Compactly stores a set of `R0 member of [R1...Rn]` constraints,
|
||||
/// indexed by the region `R0`.
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct MemberConstraintSet<'tcx, R>
|
||||
where
|
||||
R: Copy + Eq,
|
||||
@ -29,6 +32,7 @@ where
|
||||
}
|
||||
|
||||
/// Represents a `R0 member of [R1..Rn]` constraint
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct NllMemberConstraint<'tcx> {
|
||||
next_constraint: Option<NllMemberConstraintIndex>,
|
||||
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
#![deny(rustc::untranslatable_diagnostic)]
|
||||
#![deny(rustc::diagnostic_outside_of_impl)]
|
||||
//! The entry point of the NLL borrow checker.
|
||||
|
||||
use rustc_data_structures::vec_map::VecMap;
|
||||
@ -71,7 +73,7 @@ pub(crate) fn replace_regions_in_mir<'tcx>(
|
||||
// Replace all remaining regions with fresh inference variables.
|
||||
renumber::renumber_mir(infcx, body, promoted);
|
||||
|
||||
dump_mir(infcx.tcx, None, "renumber", &0, body, |_, _| Ok(()));
|
||||
dump_mir(infcx.tcx, false, "renumber", &0, body, |_, _| Ok(()));
|
||||
|
||||
universal_regions
|
||||
}
|
||||
@ -242,7 +244,6 @@ pub(crate) fn compute_regions<'cx, 'tcx>(
|
||||
mut liveness_constraints,
|
||||
outlives_constraints,
|
||||
member_constraints,
|
||||
closure_bounds_mapping,
|
||||
universe_causes,
|
||||
type_tests,
|
||||
} = constraints;
|
||||
@ -264,7 +265,6 @@ pub(crate) fn compute_regions<'cx, 'tcx>(
|
||||
universal_region_relations,
|
||||
outlives_constraints,
|
||||
member_constraints,
|
||||
closure_bounds_mapping,
|
||||
universe_causes,
|
||||
type_tests,
|
||||
liveness_constraints,
|
||||
@ -303,7 +303,10 @@ pub(crate) fn compute_regions<'cx, 'tcx>(
|
||||
|
||||
if !nll_errors.is_empty() {
|
||||
// Suppress unhelpful extra errors in `infer_opaque_types`.
|
||||
infcx.set_tainted_by_errors();
|
||||
infcx.set_tainted_by_errors(infcx.tcx.sess.delay_span_bug(
|
||||
body.span,
|
||||
"`compute_regions` tainted `infcx` with errors but did not emit any errors",
|
||||
));
|
||||
}
|
||||
|
||||
let remapped_opaque_tys = regioncx.infer_opaque_types(&infcx, opaque_type_values);
|
||||
@ -328,7 +331,7 @@ pub(super) fn dump_mir_results<'tcx>(
|
||||
return;
|
||||
}
|
||||
|
||||
dump_mir(infcx.tcx, None, "nll", &0, body, |pass_where, out| {
|
||||
dump_mir(infcx.tcx, false, "nll", &0, body, |pass_where, out| {
|
||||
match pass_where {
|
||||
// Before the CFG, dump out the values for each region variable.
|
||||
PassWhere::BeforeCFG => {
|
||||
@ -355,15 +358,13 @@ pub(super) fn dump_mir_results<'tcx>(
|
||||
|
||||
// Also dump the inference graph constraints as a graphviz file.
|
||||
let _: io::Result<()> = try {
|
||||
let mut file =
|
||||
create_dump_file(infcx.tcx, "regioncx.all.dot", None, "nll", &0, body.source)?;
|
||||
let mut file = create_dump_file(infcx.tcx, "regioncx.all.dot", false, "nll", &0, body)?;
|
||||
regioncx.dump_graphviz_raw_constraints(&mut file)?;
|
||||
};
|
||||
|
||||
// Also dump the inference graph constraints as a graphviz file.
|
||||
let _: io::Result<()> = try {
|
||||
let mut file =
|
||||
create_dump_file(infcx.tcx, "regioncx.scc.dot", None, "nll", &0, body.source)?;
|
||||
let mut file = create_dump_file(infcx.tcx, "regioncx.scc.dot", false, "nll", &0, body)?;
|
||||
regioncx.dump_graphviz_scc_constraints(&mut file)?;
|
||||
};
|
||||
}
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
#![deny(rustc::untranslatable_diagnostic)]
|
||||
#![deny(rustc::diagnostic_outside_of_impl)]
|
||||
use crate::borrow_set::{BorrowData, BorrowSet, TwoPhaseActivation};
|
||||
use crate::places_conflict;
|
||||
use crate::AccessDepth;
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
#![deny(rustc::untranslatable_diagnostic)]
|
||||
#![deny(rustc::diagnostic_outside_of_impl)]
|
||||
use crate::borrow_set::LocalsStateAtExit;
|
||||
use rustc_hir as hir;
|
||||
use rustc_middle::mir::ProjectionElem;
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
#![deny(rustc::untranslatable_diagnostic)]
|
||||
#![deny(rustc::diagnostic_outside_of_impl)]
|
||||
use crate::ArtificialField;
|
||||
use crate::Overlap;
|
||||
use crate::{AccessDepth, Deep, Shallow};
|
||||
@ -318,16 +320,10 @@ fn place_projection_conflict<'tcx>(
|
||||
debug!("place_element_conflict: DISJOINT-OR-EQ-DEREF");
|
||||
Overlap::EqualOrDisjoint
|
||||
}
|
||||
(ProjectionElem::OpaqueCast(v1), ProjectionElem::OpaqueCast(v2)) => {
|
||||
if v1 == v2 {
|
||||
// same type - recur.
|
||||
debug!("place_element_conflict: DISJOINT-OR-EQ-OPAQUE");
|
||||
Overlap::EqualOrDisjoint
|
||||
} else {
|
||||
// Different types. Disjoint!
|
||||
debug!("place_element_conflict: DISJOINT-OPAQUE");
|
||||
Overlap::Disjoint
|
||||
}
|
||||
(ProjectionElem::OpaqueCast(_), ProjectionElem::OpaqueCast(_)) => {
|
||||
// casts to other types may always conflict irrespective of the type being cast to.
|
||||
debug!("place_element_conflict: DISJOINT-OR-EQ-OPAQUE");
|
||||
Overlap::EqualOrDisjoint
|
||||
}
|
||||
(ProjectionElem::Field(f1, _), ProjectionElem::Field(f2, _)) => {
|
||||
if f1 == f2 {
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
#![deny(rustc::untranslatable_diagnostic)]
|
||||
#![deny(rustc::diagnostic_outside_of_impl)]
|
||||
//! From the NLL RFC: "The deep [aka 'supporting'] prefixes for an
|
||||
//! place are formed by stripping away fields and derefs, except that
|
||||
//! we stop when we reach the deref of a shared reference. [...] "
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
#![deny(rustc::untranslatable_diagnostic)]
|
||||
#![deny(rustc::diagnostic_outside_of_impl)]
|
||||
//! As part of generating the regions, if you enable `-Zdump-mir=nll`,
|
||||
//! we will generate an annotated copy of the MIR that includes the
|
||||
//! state of region inference. This code handles emitting the region
|
||||
@ -74,8 +76,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||
let mut constraints: Vec<_> = self.constraints.outlives().iter().collect();
|
||||
constraints.sort_by_key(|c| (c.sup, c.sub));
|
||||
for constraint in &constraints {
|
||||
let OutlivesConstraint { sup, sub, locations, category, span, variance_info: _ } =
|
||||
constraint;
|
||||
let OutlivesConstraint { sup, sub, locations, category, span, .. } = constraint;
|
||||
let (name, arg) = match locations {
|
||||
Locations::All(span) => {
|
||||
("All", tcx.sess.source_map().span_to_embeddable_string(*span))
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
#![deny(rustc::untranslatable_diagnostic)]
|
||||
#![deny(rustc::diagnostic_outside_of_impl)]
|
||||
//! This module provides linkage between RegionInferenceContext and
|
||||
//! `rustc_graphviz` traits, specialized to attaching borrowck analysis
|
||||
//! data to rendered labels.
|
||||
|
||||
@ -6,10 +6,9 @@ use rustc_data_structures::frozen::Frozen;
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_data_structures::graph::scc::Sccs;
|
||||
use rustc_errors::Diagnostic;
|
||||
use rustc_hir::def_id::{DefId, CRATE_DEF_ID};
|
||||
use rustc_hir::def_id::CRATE_DEF_ID;
|
||||
use rustc_hir::CRATE_HIR_ID;
|
||||
use rustc_index::vec::IndexVec;
|
||||
use rustc_infer::infer::canonical::QueryOutlivesConstraint;
|
||||
use rustc_infer::infer::outlives::test_type_match;
|
||||
use rustc_infer::infer::region_constraints::{GenericKind, VarInfos, VerifyBound, VerifyIfEq};
|
||||
use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin, RegionVariableOrigin};
|
||||
@ -19,9 +18,7 @@ use rustc_middle::mir::{
|
||||
};
|
||||
use rustc_middle::traits::ObligationCause;
|
||||
use rustc_middle::traits::ObligationCauseCode;
|
||||
use rustc_middle::ty::{
|
||||
self, subst::SubstsRef, RegionVid, Ty, TyCtxt, TypeFoldable, TypeVisitable,
|
||||
};
|
||||
use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt, TypeFoldable, TypeVisitable};
|
||||
use rustc_span::Span;
|
||||
|
||||
use crate::{
|
||||
@ -89,10 +86,6 @@ pub struct RegionInferenceContext<'tcx> {
|
||||
/// `member_region_scc`.
|
||||
member_constraints_applied: Vec<AppliedMemberConstraint>,
|
||||
|
||||
/// Map closure bounds to a `Span` that should be used for error reporting.
|
||||
closure_bounds_mapping:
|
||||
FxHashMap<Location, FxHashMap<(RegionVid, RegionVid), (ConstraintCategory<'tcx>, Span)>>,
|
||||
|
||||
/// Map universe indexes to information on why we created it.
|
||||
universe_causes: FxHashMap<ty::UniverseIndex, UniverseInfo<'tcx>>,
|
||||
|
||||
@ -135,6 +128,7 @@ pub struct RegionInferenceContext<'tcx> {
|
||||
/// adds a new lower bound to the SCC it is analyzing: so you wind up
|
||||
/// with `'R: 'O` where `'R` is the pick-region and `'O` is the
|
||||
/// minimal viable option.
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct AppliedMemberConstraint {
|
||||
/// The SCC that was affected. (The "member region".)
|
||||
///
|
||||
@ -221,8 +215,8 @@ pub struct TypeTest<'tcx> {
|
||||
/// The region `'x` that the type must outlive.
|
||||
pub lower_bound: RegionVid,
|
||||
|
||||
/// Where did this constraint arise and why?
|
||||
pub locations: Locations,
|
||||
/// The span to blame.
|
||||
pub span: Span,
|
||||
|
||||
/// A test which, if met by the region `'x`, proves that this type
|
||||
/// constraint is satisfied.
|
||||
@ -265,10 +259,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||
universal_region_relations: Frozen<UniversalRegionRelations<'tcx>>,
|
||||
outlives_constraints: OutlivesConstraintSet<'tcx>,
|
||||
member_constraints_in: MemberConstraintSet<'tcx, RegionVid>,
|
||||
closure_bounds_mapping: FxHashMap<
|
||||
Location,
|
||||
FxHashMap<(RegionVid, RegionVid), (ConstraintCategory<'tcx>, Span)>,
|
||||
>,
|
||||
universe_causes: FxHashMap<ty::UniverseIndex, UniverseInfo<'tcx>>,
|
||||
type_tests: Vec<TypeTest<'tcx>>,
|
||||
liveness_constraints: LivenessValues<RegionVid>,
|
||||
@ -310,7 +300,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||
rev_scc_graph: None,
|
||||
member_constraints,
|
||||
member_constraints_applied: Vec::new(),
|
||||
closure_bounds_mapping,
|
||||
universe_causes,
|
||||
scc_universes,
|
||||
scc_representatives,
|
||||
@ -882,13 +871,13 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||
if deduplicate_errors.insert((
|
||||
erased_generic_kind,
|
||||
type_test.lower_bound,
|
||||
type_test.locations,
|
||||
type_test.span,
|
||||
)) {
|
||||
debug!(
|
||||
"check_type_test: reporting error for erased_generic_kind={:?}, \
|
||||
lower_bound_region={:?}, \
|
||||
type_test.locations={:?}",
|
||||
erased_generic_kind, type_test.lower_bound, type_test.locations,
|
||||
type_test.span={:?}",
|
||||
erased_generic_kind, type_test.lower_bound, type_test.span,
|
||||
);
|
||||
|
||||
errors_buffer.push(RegionErrorKind::TypeTestError { type_test: type_test.clone() });
|
||||
@ -931,7 +920,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||
) -> bool {
|
||||
let tcx = infcx.tcx;
|
||||
|
||||
let TypeTest { generic_kind, lower_bound, locations, verify_bound: _ } = type_test;
|
||||
let TypeTest { generic_kind, lower_bound, span: _, verify_bound: _ } = type_test;
|
||||
|
||||
let generic_ty = generic_kind.to_ty(tcx);
|
||||
let Some(subject) = self.try_promote_type_test_subject(infcx, generic_ty) else {
|
||||
@ -959,7 +948,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||
propagated_outlives_requirements.push(ClosureOutlivesRequirement {
|
||||
subject,
|
||||
outlived_free_region: static_r,
|
||||
blame_span: locations.span(body),
|
||||
blame_span: type_test.span,
|
||||
category: ConstraintCategory::Boring,
|
||||
});
|
||||
|
||||
@ -1011,7 +1000,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||
let requirement = ClosureOutlivesRequirement {
|
||||
subject,
|
||||
outlived_free_region: upper_bound,
|
||||
blame_span: locations.span(body),
|
||||
blame_span: type_test.span,
|
||||
category: ConstraintCategory::Boring,
|
||||
};
|
||||
debug!("try_promote_type_test: pushing {:#?}", requirement);
|
||||
@ -1716,6 +1705,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||
});
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self, infcx, errors_buffer))]
|
||||
fn check_member_constraints(
|
||||
&self,
|
||||
infcx: &InferCtxt<'tcx>,
|
||||
@ -1723,22 +1713,21 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||
) {
|
||||
let member_constraints = self.member_constraints.clone();
|
||||
for m_c_i in member_constraints.all_indices() {
|
||||
debug!("check_member_constraint(m_c_i={:?})", m_c_i);
|
||||
debug!(?m_c_i);
|
||||
let m_c = &member_constraints[m_c_i];
|
||||
let member_region_vid = m_c.member_region_vid;
|
||||
debug!(
|
||||
"check_member_constraint: member_region_vid={:?} with value {}",
|
||||
member_region_vid,
|
||||
self.region_value_str(member_region_vid),
|
||||
?member_region_vid,
|
||||
value = ?self.region_value_str(member_region_vid),
|
||||
);
|
||||
let choice_regions = member_constraints.choice_regions(m_c_i);
|
||||
debug!("check_member_constraint: choice_regions={:?}", choice_regions);
|
||||
debug!(?choice_regions);
|
||||
|
||||
// Did the member region wind up equal to any of the option regions?
|
||||
if let Some(o) =
|
||||
choice_regions.iter().find(|&&o_r| self.eval_equal(o_r, m_c.member_region_vid))
|
||||
{
|
||||
debug!("check_member_constraint: evaluated as equal to {:?}", o);
|
||||
debug!("evaluated as equal to {:?}", o);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1804,18 +1793,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn retrieve_closure_constraint_info(
|
||||
&self,
|
||||
constraint: OutlivesConstraint<'tcx>,
|
||||
) -> Option<(ConstraintCategory<'tcx>, Span)> {
|
||||
match constraint.locations {
|
||||
Locations::All(_) => None,
|
||||
Locations::Single(loc) => {
|
||||
self.closure_bounds_mapping[&loc].get(&(constraint.sup, constraint.sub)).copied()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Finds a good `ObligationCause` to blame for the fact that `fr1` outlives `fr2`.
|
||||
pub(crate) fn find_outlives_blame_span(
|
||||
&self,
|
||||
@ -1921,6 +1898,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||
span: p_c.definition_span,
|
||||
category: ConstraintCategory::OpaqueType,
|
||||
variance_info: ty::VarianceDiagInfo::default(),
|
||||
from_closure: false,
|
||||
};
|
||||
handle_constraint(constraint);
|
||||
}
|
||||
@ -2066,31 +2044,12 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||
// Classify each of the constraints along the path.
|
||||
let mut categorized_path: Vec<BlameConstraint<'tcx>> = path
|
||||
.iter()
|
||||
.map(|constraint| {
|
||||
let (category, span, from_closure, cause_code) =
|
||||
if constraint.category == ConstraintCategory::ClosureBounds {
|
||||
if let Some((category, span)) =
|
||||
self.retrieve_closure_constraint_info(*constraint)
|
||||
{
|
||||
(category, span, true, ObligationCauseCode::MiscObligation)
|
||||
} else {
|
||||
(
|
||||
constraint.category,
|
||||
constraint.span,
|
||||
false,
|
||||
ObligationCauseCode::MiscObligation,
|
||||
)
|
||||
}
|
||||
} else {
|
||||
(constraint.category, constraint.span, false, cause_code.clone())
|
||||
};
|
||||
BlameConstraint {
|
||||
category,
|
||||
from_closure,
|
||||
cause: ObligationCause::new(span, CRATE_HIR_ID, cause_code),
|
||||
variance_info: constraint.variance_info,
|
||||
outlives_constraint: *constraint,
|
||||
}
|
||||
.map(|constraint| BlameConstraint {
|
||||
category: constraint.category,
|
||||
from_closure: constraint.from_closure,
|
||||
cause: ObligationCause::new(constraint.span, CRATE_HIR_ID, cause_code.clone()),
|
||||
variance_info: constraint.variance_info,
|
||||
outlives_constraint: *constraint,
|
||||
})
|
||||
.collect();
|
||||
debug!("categorized_path={:#?}", categorized_path);
|
||||
@ -2274,92 +2233,6 @@ impl<'tcx> RegionDefinition<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
pub trait ClosureRegionRequirementsExt<'tcx> {
|
||||
fn apply_requirements(
|
||||
&self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
closure_def_id: DefId,
|
||||
closure_substs: SubstsRef<'tcx>,
|
||||
) -> Vec<QueryOutlivesConstraint<'tcx>>;
|
||||
}
|
||||
|
||||
impl<'tcx> ClosureRegionRequirementsExt<'tcx> for ClosureRegionRequirements<'tcx> {
|
||||
/// Given an instance T of the closure type, this method
|
||||
/// instantiates the "extra" requirements that we computed for the
|
||||
/// closure into the inference context. This has the effect of
|
||||
/// adding new outlives obligations to existing variables.
|
||||
///
|
||||
/// As described on `ClosureRegionRequirements`, the extra
|
||||
/// requirements are expressed in terms of regionvids that index
|
||||
/// into the free regions that appear on the closure type. So, to
|
||||
/// do this, we first copy those regions out from the type T into
|
||||
/// a vector. Then we can just index into that vector to extract
|
||||
/// out the corresponding region from T and apply the
|
||||
/// requirements.
|
||||
fn apply_requirements(
|
||||
&self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
closure_def_id: DefId,
|
||||
closure_substs: SubstsRef<'tcx>,
|
||||
) -> Vec<QueryOutlivesConstraint<'tcx>> {
|
||||
debug!(
|
||||
"apply_requirements(closure_def_id={:?}, closure_substs={:?})",
|
||||
closure_def_id, closure_substs
|
||||
);
|
||||
|
||||
// Extract the values of the free regions in `closure_substs`
|
||||
// into a vector. These are the regions that we will be
|
||||
// relating to one another.
|
||||
let closure_mapping = &UniversalRegions::closure_mapping(
|
||||
tcx,
|
||||
closure_substs,
|
||||
self.num_external_vids,
|
||||
tcx.typeck_root_def_id(closure_def_id),
|
||||
);
|
||||
debug!("apply_requirements: closure_mapping={:?}", closure_mapping);
|
||||
|
||||
// Create the predicates.
|
||||
self.outlives_requirements
|
||||
.iter()
|
||||
.map(|outlives_requirement| {
|
||||
let outlived_region = closure_mapping[outlives_requirement.outlived_free_region];
|
||||
|
||||
match outlives_requirement.subject {
|
||||
ClosureOutlivesSubject::Region(region) => {
|
||||
let region = closure_mapping[region];
|
||||
debug!(
|
||||
"apply_requirements: region={:?} \
|
||||
outlived_region={:?} \
|
||||
outlives_requirement={:?}",
|
||||
region, outlived_region, outlives_requirement,
|
||||
);
|
||||
(
|
||||
ty::Binder::dummy(ty::OutlivesPredicate(
|
||||
region.into(),
|
||||
outlived_region,
|
||||
)),
|
||||
ConstraintCategory::BoringNoLocation,
|
||||
)
|
||||
}
|
||||
|
||||
ClosureOutlivesSubject::Ty(ty) => {
|
||||
debug!(
|
||||
"apply_requirements: ty={:?} \
|
||||
outlived_region={:?} \
|
||||
outlives_requirement={:?}",
|
||||
ty, outlived_region, outlives_requirement,
|
||||
);
|
||||
(
|
||||
ty::Binder::dummy(ty::OutlivesPredicate(ty.into(), outlived_region)),
|
||||
ConstraintCategory::BoringNoLocation,
|
||||
)
|
||||
}
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct BlameConstraint<'tcx> {
|
||||
pub category: ConstraintCategory<'tcx>,
|
||||
|
||||
@ -1,18 +1,16 @@
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
|
||||
use rustc_data_structures::vec_map::VecMap;
|
||||
use rustc_hir::def_id::LocalDefId;
|
||||
use rustc_hir::OpaqueTyOrigin;
|
||||
use rustc_infer::infer::TyCtxtInferExt as _;
|
||||
use rustc_infer::infer::{DefiningAnchor, InferCtxt};
|
||||
use rustc_infer::traits::{Obligation, ObligationCause, TraitEngine};
|
||||
use rustc_infer::traits::{Obligation, ObligationCause};
|
||||
use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts};
|
||||
use rustc_middle::ty::visit::TypeVisitable;
|
||||
use rustc_middle::ty::{
|
||||
self, OpaqueHiddenType, OpaqueTypeKey, ToPredicate, Ty, TyCtxt, TypeFoldable,
|
||||
};
|
||||
use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable};
|
||||
use rustc_span::Span;
|
||||
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _;
|
||||
use rustc_trait_selection::traits::TraitEngineExt as _;
|
||||
use rustc_trait_selection::traits::ObligationCtxt;
|
||||
|
||||
use super::RegionInferenceContext;
|
||||
|
||||
@ -63,17 +61,21 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||
opaque_ty_decls: VecMap<OpaqueTypeKey<'tcx>, (OpaqueHiddenType<'tcx>, OpaqueTyOrigin)>,
|
||||
) -> VecMap<LocalDefId, OpaqueHiddenType<'tcx>> {
|
||||
let mut result: VecMap<LocalDefId, OpaqueHiddenType<'tcx>> = VecMap::new();
|
||||
|
||||
let member_constraints: FxHashMap<_, _> = self
|
||||
.member_constraints
|
||||
.all_indices()
|
||||
.map(|ci| (self.member_constraints[ci].key, ci))
|
||||
.collect();
|
||||
debug!(?member_constraints);
|
||||
|
||||
for (opaque_type_key, (concrete_type, origin)) in opaque_ty_decls {
|
||||
let substs = opaque_type_key.substs;
|
||||
debug!(?concrete_type, ?substs);
|
||||
|
||||
let mut subst_regions = vec![self.universal_regions.fr_static];
|
||||
let universal_substs = infcx.tcx.fold_regions(substs, |region, _| {
|
||||
if let ty::RePlaceholder(..) = region.kind() {
|
||||
// Higher kinded regions don't need remapping, they don't refer to anything outside of this the substs.
|
||||
return region;
|
||||
}
|
||||
let vid = self.to_region_vid(region);
|
||||
|
||||
let to_universal_region = |vid, subst_regions: &mut Vec<_>| {
|
||||
trace!(?vid);
|
||||
let scc = self.constraint_sccs.scc(vid);
|
||||
trace!(?scc);
|
||||
@ -94,10 +96,33 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||
infcx.tcx.lifetimes.re_static
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
subst_regions.sort();
|
||||
subst_regions.dedup();
|
||||
// Start by inserting universal regions from the member_constraint choice regions.
|
||||
// This will ensure they get precedence when folding the regions in the concrete type.
|
||||
if let Some(&ci) = member_constraints.get(&opaque_type_key) {
|
||||
for &vid in self.member_constraints.choice_regions(ci) {
|
||||
to_universal_region(vid, &mut subst_regions);
|
||||
}
|
||||
}
|
||||
debug!(?subst_regions);
|
||||
|
||||
// Next, insert universal regions from substs, so we can translate regions that appear
|
||||
// in them but are not subject to member constraints, for instance closure substs.
|
||||
let universal_substs = infcx.tcx.fold_regions(substs, |region, _| {
|
||||
if let ty::RePlaceholder(..) = region.kind() {
|
||||
// Higher kinded regions don't need remapping, they don't refer to anything outside of this the substs.
|
||||
return region;
|
||||
}
|
||||
let vid = self.to_region_vid(region);
|
||||
to_universal_region(vid, &mut subst_regions)
|
||||
});
|
||||
debug!(?universal_substs);
|
||||
debug!(?subst_regions);
|
||||
|
||||
// Deduplicate the set of regions while keeping the chosen order.
|
||||
let subst_regions = subst_regions.into_iter().collect::<FxIndexSet<_>>();
|
||||
debug!(?subst_regions);
|
||||
|
||||
let universal_concrete_type =
|
||||
infcx.tcx.fold_regions(concrete_type, |region, _| match *region {
|
||||
@ -108,8 +133,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||
.unwrap_or(infcx.tcx.lifetimes.re_erased),
|
||||
_ => region,
|
||||
});
|
||||
|
||||
debug!(?universal_concrete_type, ?universal_substs);
|
||||
debug!(?universal_concrete_type);
|
||||
|
||||
let opaque_type_key =
|
||||
OpaqueTypeKey { def_id: opaque_type_key.def_id, substs: universal_substs };
|
||||
@ -221,12 +245,12 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
|
||||
instantiated_ty: OpaqueHiddenType<'tcx>,
|
||||
origin: OpaqueTyOrigin,
|
||||
) -> Ty<'tcx> {
|
||||
if self.is_tainted_by_errors() {
|
||||
return self.tcx.ty_error();
|
||||
if let Some(e) = self.tainted_by_errors() {
|
||||
return self.tcx.ty_error_with_guaranteed(e);
|
||||
}
|
||||
|
||||
let definition_ty = instantiated_ty
|
||||
.remap_generic_params_to_declaration_params(opaque_type_key, self.tcx, false, origin)
|
||||
.remap_generic_params_to_declaration_params(opaque_type_key, self.tcx, false)
|
||||
.ty;
|
||||
|
||||
if !check_opaque_type_parameter_valid(
|
||||
@ -252,48 +276,45 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
|
||||
// type-alias-impl-trait/issue-67844-nested-opaque.rs
|
||||
let infcx =
|
||||
self.tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bubble).build();
|
||||
let ocx = ObligationCtxt::new(&infcx);
|
||||
// Require the hidden type to be well-formed with only the generics of the opaque type.
|
||||
// Defining use functions may have more bounds than the opaque type, which is ok, as long as the
|
||||
// hidden type is well formed even without those bounds.
|
||||
let predicate = ty::Binder::dummy(ty::PredicateKind::WellFormed(definition_ty.into()))
|
||||
.to_predicate(infcx.tcx);
|
||||
let mut fulfillment_cx = <dyn TraitEngine<'tcx>>::new(infcx.tcx);
|
||||
let predicate = ty::Binder::dummy(ty::PredicateKind::WellFormed(definition_ty.into()));
|
||||
|
||||
let id_substs = InternalSubsts::identity_for_item(self.tcx, def_id.to_def_id());
|
||||
|
||||
// Require that the hidden type actually fulfills all the bounds of the opaque type, even without
|
||||
// the bounds that the function supplies.
|
||||
let opaque_ty = self.tcx.mk_opaque(def_id.to_def_id(), id_substs);
|
||||
match infcx
|
||||
.at(&ObligationCause::misc(instantiated_ty.span, body_id), param_env)
|
||||
.eq(opaque_ty, definition_ty)
|
||||
{
|
||||
Ok(infer_ok) => {
|
||||
for obligation in infer_ok.obligations {
|
||||
fulfillment_cx.register_predicate_obligation(&infcx, obligation);
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
infcx
|
||||
.err_ctxt()
|
||||
.report_mismatched_types(
|
||||
&ObligationCause::misc(instantiated_ty.span, body_id),
|
||||
opaque_ty,
|
||||
definition_ty,
|
||||
err,
|
||||
)
|
||||
.emit();
|
||||
}
|
||||
if let Err(err) = ocx.eq(
|
||||
&ObligationCause::misc(instantiated_ty.span, body_id),
|
||||
param_env,
|
||||
opaque_ty,
|
||||
definition_ty,
|
||||
) {
|
||||
infcx
|
||||
.err_ctxt()
|
||||
.report_mismatched_types(
|
||||
&ObligationCause::misc(instantiated_ty.span, body_id),
|
||||
opaque_ty,
|
||||
definition_ty,
|
||||
err,
|
||||
)
|
||||
.emit();
|
||||
}
|
||||
|
||||
fulfillment_cx.register_predicate_obligation(
|
||||
&infcx,
|
||||
Obligation::misc(instantiated_ty.span, body_id, param_env, predicate),
|
||||
);
|
||||
ocx.register_obligation(Obligation::misc(
|
||||
infcx.tcx,
|
||||
instantiated_ty.span,
|
||||
body_id,
|
||||
param_env,
|
||||
predicate,
|
||||
));
|
||||
|
||||
// Check that all obligations are satisfied by the implementation's
|
||||
// version.
|
||||
let errors = fulfillment_cx.select_all_or_error(&infcx);
|
||||
let errors = ocx.select_all_or_error();
|
||||
|
||||
// This is still required for many(half of the tests in ui/type-alias-impl-trait)
|
||||
// tests to pass
|
||||
@ -302,8 +323,8 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
|
||||
if errors.is_empty() {
|
||||
definition_ty
|
||||
} else {
|
||||
infcx.err_ctxt().report_fulfillment_errors(&errors, None, false);
|
||||
self.tcx.ty_error()
|
||||
let reported = infcx.err_ctxt().report_fulfillment_errors(&errors, None);
|
||||
self.tcx.ty_error_with_guaranteed(reported)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
#![deny(rustc::untranslatable_diagnostic)]
|
||||
#![deny(rustc::diagnostic_outside_of_impl)]
|
||||
use crate::constraints::ConstraintSccIndex;
|
||||
use crate::RegionInferenceContext;
|
||||
use itertools::Itertools;
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
#![deny(rustc::untranslatable_diagnostic)]
|
||||
#![deny(rustc::diagnostic_outside_of_impl)]
|
||||
use rustc_data_structures::fx::FxIndexSet;
|
||||
use rustc_index::bit_set::SparseBitMatrix;
|
||||
use rustc_index::interval::IntervalSet;
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
#![deny(rustc::untranslatable_diagnostic)]
|
||||
#![deny(rustc::diagnostic_outside_of_impl)]
|
||||
use rustc_index::vec::IndexVec;
|
||||
use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin};
|
||||
use rustc_middle::mir::visit::{MutVisitor, TyContext};
|
||||
|
||||
@ -49,7 +49,7 @@ pub(crate) struct GenericDoesNotLiveLongEnough {
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag(borrowck_var_does_not_need_mut)]
|
||||
pub(crate) struct VarNeedNotMut {
|
||||
#[suggestion_short(applicability = "machine-applicable", code = "")]
|
||||
#[suggestion(style = "short", applicability = "machine-applicable", code = "")]
|
||||
pub span: Span,
|
||||
}
|
||||
#[derive(Diagnostic)]
|
||||
@ -148,3 +148,95 @@ pub(crate) enum RequireStaticErr {
|
||||
multi_span: MultiSpan,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
pub(crate) enum CaptureVarPathUseCause {
|
||||
#[label(borrowck_borrow_due_to_use_generator)]
|
||||
BorrowInGenerator {
|
||||
#[primary_span]
|
||||
path_span: Span,
|
||||
},
|
||||
#[label(borrowck_use_due_to_use_generator)]
|
||||
UseInGenerator {
|
||||
#[primary_span]
|
||||
path_span: Span,
|
||||
},
|
||||
#[label(borrowck_assign_due_to_use_generator)]
|
||||
AssignInGenerator {
|
||||
#[primary_span]
|
||||
path_span: Span,
|
||||
},
|
||||
#[label(borrowck_assign_part_due_to_use_generator)]
|
||||
AssignPartInGenerator {
|
||||
#[primary_span]
|
||||
path_span: Span,
|
||||
},
|
||||
#[label(borrowck_borrow_due_to_use_closure)]
|
||||
BorrowInClosure {
|
||||
#[primary_span]
|
||||
path_span: Span,
|
||||
},
|
||||
#[label(borrowck_use_due_to_use_closure)]
|
||||
UseInClosure {
|
||||
#[primary_span]
|
||||
path_span: Span,
|
||||
},
|
||||
#[label(borrowck_assign_due_to_use_closure)]
|
||||
AssignInClosure {
|
||||
#[primary_span]
|
||||
path_span: Span,
|
||||
},
|
||||
#[label(borrowck_assign_part_due_to_use_closure)]
|
||||
AssignPartInClosure {
|
||||
#[primary_span]
|
||||
path_span: Span,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
pub(crate) enum CaptureVarKind {
|
||||
#[label(borrowck_capture_immute)]
|
||||
Immute {
|
||||
#[primary_span]
|
||||
kind_span: Span,
|
||||
},
|
||||
#[label(borrowck_capture_mut)]
|
||||
Mut {
|
||||
#[primary_span]
|
||||
kind_span: Span,
|
||||
},
|
||||
#[label(borrowck_capture_move)]
|
||||
Move {
|
||||
#[primary_span]
|
||||
kind_span: Span,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
pub(crate) enum CaptureVarCause {
|
||||
#[label(borrowck_var_borrow_by_use_place_in_generator)]
|
||||
BorrowUsePlaceGenerator {
|
||||
place: String,
|
||||
#[primary_span]
|
||||
var_span: Span,
|
||||
},
|
||||
#[label(borrowck_var_borrow_by_use_place_in_closure)]
|
||||
BorrowUsePlaceClosure {
|
||||
place: String,
|
||||
#[primary_span]
|
||||
var_span: Span,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(borrowck_cannot_move_when_borrowed, code = "E0505")]
|
||||
pub(crate) struct MoveBorrow<'a> {
|
||||
pub place: &'a str,
|
||||
pub borrow_place: &'a str,
|
||||
pub value_place: &'a str,
|
||||
#[primary_span]
|
||||
#[label(move_label)]
|
||||
pub span: Span,
|
||||
#[label]
|
||||
pub borrow_span: Span,
|
||||
}
|
||||
|
||||
@ -88,12 +88,11 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
category: ConstraintCategory<'tcx>,
|
||||
) {
|
||||
self.prove_predicate(
|
||||
ty::Binder::dummy(ty::PredicateKind::Trait(ty::TraitPredicate {
|
||||
ty::Binder::dummy(ty::PredicateKind::Clause(ty::Clause::Trait(ty::TraitPredicate {
|
||||
trait_ref,
|
||||
constness: ty::BoundConstness::NotConst,
|
||||
polarity: ty::ImplPolarity::Positive,
|
||||
}))
|
||||
.to_predicate(self.tcx()),
|
||||
}))),
|
||||
locations,
|
||||
category,
|
||||
);
|
||||
@ -122,14 +121,11 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
|
||||
pub(super) fn prove_predicates(
|
||||
&mut self,
|
||||
predicates: impl IntoIterator<Item = impl ToPredicate<'tcx>>,
|
||||
predicates: impl IntoIterator<Item = impl ToPredicate<'tcx> + std::fmt::Debug>,
|
||||
locations: Locations,
|
||||
category: ConstraintCategory<'tcx>,
|
||||
) {
|
||||
for predicate in predicates {
|
||||
let predicate = predicate.to_predicate(self.tcx());
|
||||
debug!("prove_predicates(predicate={:?}, locations={:?})", predicate, locations,);
|
||||
|
||||
self.prove_predicate(predicate, locations, category);
|
||||
}
|
||||
}
|
||||
@ -137,11 +133,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
pub(super) fn prove_predicate(
|
||||
&mut self,
|
||||
predicate: ty::Predicate<'tcx>,
|
||||
predicate: impl ToPredicate<'tcx> + std::fmt::Debug,
|
||||
locations: Locations,
|
||||
category: ConstraintCategory<'tcx>,
|
||||
) {
|
||||
let param_env = self.param_env;
|
||||
let predicate = predicate.to_predicate(self.tcx());
|
||||
self.fully_perform_op(
|
||||
locations,
|
||||
category,
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
use rustc_infer::infer::canonical::QueryOutlivesConstraint;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_infer::infer::canonical::QueryRegionConstraints;
|
||||
use rustc_infer::infer::outlives::env::RegionBoundPairs;
|
||||
use rustc_infer::infer::outlives::obligations::{TypeOutlives, TypeOutlivesDelegate};
|
||||
use rustc_infer::infer::region_constraints::{GenericKind, VerifyBound};
|
||||
use rustc_infer::infer::{self, InferCtxt, SubregionOrigin};
|
||||
use rustc_middle::mir::ConstraintCategory;
|
||||
use rustc_middle::mir::{ClosureOutlivesSubject, ClosureRegionRequirements, ConstraintCategory};
|
||||
use rustc_middle::ty::subst::GenericArgKind;
|
||||
use rustc_middle::ty::TypeFoldable;
|
||||
use rustc_middle::ty::{self, TyCtxt};
|
||||
@ -38,6 +38,7 @@ pub(crate) struct ConstraintConversion<'a, 'tcx> {
|
||||
locations: Locations,
|
||||
span: Span,
|
||||
category: ConstraintCategory<'tcx>,
|
||||
from_closure: bool,
|
||||
constraints: &'a mut MirTypeckRegionConstraints<'tcx>,
|
||||
}
|
||||
|
||||
@ -64,6 +65,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
|
||||
span,
|
||||
category,
|
||||
constraints,
|
||||
from_closure: false,
|
||||
}
|
||||
}
|
||||
|
||||
@ -81,12 +83,62 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
|
||||
}
|
||||
self.constraints.member_constraints = tmp;
|
||||
|
||||
for query_constraint in outlives {
|
||||
self.convert(query_constraint);
|
||||
for (predicate, constraint_category) in outlives {
|
||||
// At the moment, we never generate any "higher-ranked"
|
||||
// region constraints like `for<'a> 'a: 'b`. At some point
|
||||
// when we move to universes, we will, and this assertion
|
||||
// will start to fail.
|
||||
let predicate = predicate.no_bound_vars().unwrap_or_else(|| {
|
||||
bug!("query_constraint {:?} contained bound vars", predicate,);
|
||||
});
|
||||
|
||||
self.convert(predicate, *constraint_category);
|
||||
}
|
||||
}
|
||||
|
||||
fn convert(&mut self, query_constraint: &QueryOutlivesConstraint<'tcx>) {
|
||||
/// Given an instance of the closure type, this method instantiates the "extra" requirements
|
||||
/// that we computed for the closure. This has the effect of adding new outlives obligations
|
||||
/// to existing region variables in `closure_substs`.
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
pub fn apply_closure_requirements(
|
||||
&mut self,
|
||||
closure_requirements: &ClosureRegionRequirements<'tcx>,
|
||||
closure_def_id: DefId,
|
||||
closure_substs: ty::SubstsRef<'tcx>,
|
||||
) {
|
||||
// Extract the values of the free regions in `closure_substs`
|
||||
// into a vector. These are the regions that we will be
|
||||
// relating to one another.
|
||||
let closure_mapping = &UniversalRegions::closure_mapping(
|
||||
self.tcx,
|
||||
closure_substs,
|
||||
closure_requirements.num_external_vids,
|
||||
closure_def_id.expect_local(),
|
||||
);
|
||||
debug!(?closure_mapping);
|
||||
|
||||
// Create the predicates.
|
||||
let backup = (self.category, self.span, self.from_closure);
|
||||
self.from_closure = true;
|
||||
for outlives_requirement in &closure_requirements.outlives_requirements {
|
||||
let outlived_region = closure_mapping[outlives_requirement.outlived_free_region];
|
||||
let subject = match outlives_requirement.subject {
|
||||
ClosureOutlivesSubject::Region(re) => closure_mapping[re].into(),
|
||||
ClosureOutlivesSubject::Ty(ty) => ty.into(),
|
||||
};
|
||||
|
||||
self.category = outlives_requirement.category;
|
||||
self.span = outlives_requirement.blame_span;
|
||||
self.convert(ty::OutlivesPredicate(subject, outlived_region), self.category);
|
||||
}
|
||||
(self.category, self.span, self.from_closure) = backup;
|
||||
}
|
||||
|
||||
fn convert(
|
||||
&mut self,
|
||||
predicate: ty::OutlivesPredicate<ty::GenericArg<'tcx>, ty::Region<'tcx>>,
|
||||
constraint_category: ConstraintCategory<'tcx>,
|
||||
) {
|
||||
debug!("generate: constraints at: {:#?}", self.locations);
|
||||
|
||||
// Extract out various useful fields we'll need below.
|
||||
@ -94,17 +146,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
|
||||
tcx, region_bound_pairs, implicit_region_bound, param_env, ..
|
||||
} = *self;
|
||||
|
||||
// At the moment, we never generate any "higher-ranked"
|
||||
// region constraints like `for<'a> 'a: 'b`. At some point
|
||||
// when we move to universes, we will, and this assertion
|
||||
// will start to fail.
|
||||
let ty::OutlivesPredicate(k1, r2) =
|
||||
query_constraint.0.no_bound_vars().unwrap_or_else(|| {
|
||||
bug!("query_constraint {:?} contained bound vars", query_constraint,);
|
||||
});
|
||||
|
||||
let constraint_category = query_constraint.1;
|
||||
|
||||
let ty::OutlivesPredicate(k1, r2) = predicate;
|
||||
match k1.unpack() {
|
||||
GenericArgKind::Lifetime(r1) => {
|
||||
let r1_vid = self.to_region_vid(r1);
|
||||
@ -127,10 +169,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
|
||||
.type_must_outlive(origin, t1, r2, constraint_category);
|
||||
}
|
||||
|
||||
GenericArgKind::Const(_) => {
|
||||
// Consts cannot outlive one another, so we
|
||||
// don't need to handle any relations here.
|
||||
}
|
||||
GenericArgKind::Const(_) => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -160,7 +199,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
|
||||
verify_bound: VerifyBound<'tcx>,
|
||||
) -> TypeTest<'tcx> {
|
||||
let lower_bound = self.to_region_vid(region);
|
||||
TypeTest { generic_kind, lower_bound, locations: self.locations, verify_bound }
|
||||
TypeTest { generic_kind, lower_bound, span: self.span, verify_bound }
|
||||
}
|
||||
|
||||
fn to_region_vid(&mut self, r: ty::Region<'tcx>) -> ty::RegionVid {
|
||||
@ -188,6 +227,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
|
||||
sub,
|
||||
sup,
|
||||
variance_info: ty::VarianceDiagInfo::default(),
|
||||
from_closure: self.from_closure,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -247,12 +247,13 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
|
||||
.and(type_op::normalize::Normalize::new(ty))
|
||||
.fully_perform(self.infcx)
|
||||
.unwrap_or_else(|_| {
|
||||
self.infcx
|
||||
let reported = self
|
||||
.infcx
|
||||
.tcx
|
||||
.sess
|
||||
.delay_span_bug(span, &format!("failed to normalize {:?}", ty));
|
||||
TypeOpOutput {
|
||||
output: self.infcx.tcx.ty_error(),
|
||||
output: self.infcx.tcx.ty_error_with_guaranteed(reported),
|
||||
constraints: None,
|
||||
error_info: None,
|
||||
}
|
||||
|
||||
@ -42,8 +42,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
user_provided_sig = None;
|
||||
} else {
|
||||
let typeck_results = self.tcx().typeck(mir_def_id);
|
||||
user_provided_sig = typeck_results.user_provided_sigs.get(&mir_def_id.to_def_id()).map(
|
||||
|user_provided_poly_sig| {
|
||||
user_provided_sig =
|
||||
typeck_results.user_provided_sigs.get(&mir_def_id).map(|user_provided_poly_sig| {
|
||||
// Instantiate the canonicalized variables from
|
||||
// user-provided signature (e.g., the `_` in the code
|
||||
// above) with fresh variables.
|
||||
@ -60,8 +60,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
LateBoundRegionConversionTime::FnCall,
|
||||
poly_sig,
|
||||
)
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
debug!(?normalized_input_tys, ?body.local_decls);
|
||||
|
||||
@ -121,8 +121,8 @@ pub(super) fn populate_access_facts<'a, 'tcx>(
|
||||
}
|
||||
}
|
||||
|
||||
// For every potentially drop()-touched region `region` in `local`'s type
|
||||
// (`kind`), emit a Polonius `use_of_var_derefs_origin(local, origin)` fact.
|
||||
/// For every potentially drop()-touched region `region` in `local`'s type
|
||||
/// (`kind`), emit a Polonius `use_of_var_derefs_origin(local, origin)` fact.
|
||||
pub(super) fn add_drop_of_var_derefs_origin<'tcx>(
|
||||
typeck: &mut TypeChecker<'_, 'tcx>,
|
||||
local: Local,
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
#![deny(rustc::untranslatable_diagnostic)]
|
||||
#![deny(rustc::diagnostic_outside_of_impl)]
|
||||
//! This pass type-checks the MIR to ensure it is not broken.
|
||||
|
||||
use std::rc::Rc;
|
||||
@ -27,12 +29,11 @@ use rustc_middle::mir::AssertKind;
|
||||
use rustc_middle::mir::*;
|
||||
use rustc_middle::ty::adjustment::PointerCast;
|
||||
use rustc_middle::ty::cast::CastTy;
|
||||
use rustc_middle::ty::subst::{GenericArgKind, SubstsRef, UserSubsts};
|
||||
use rustc_middle::ty::subst::{SubstsRef, UserSubsts};
|
||||
use rustc_middle::ty::visit::TypeVisitable;
|
||||
use rustc_middle::ty::{
|
||||
self, Binder, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, Dynamic,
|
||||
OpaqueHiddenType, OpaqueTypeKey, RegionVid, ToPredicate, Ty, TyCtxt, UserType,
|
||||
UserTypeAnnotationIndex,
|
||||
OpaqueHiddenType, OpaqueTypeKey, RegionVid, Ty, TyCtxt, UserType, UserTypeAnnotationIndex,
|
||||
};
|
||||
use rustc_span::def_id::CRATE_DEF_ID;
|
||||
use rustc_span::{Span, DUMMY_SP};
|
||||
@ -61,7 +62,7 @@ use crate::{
|
||||
region_infer::values::{
|
||||
LivenessValues, PlaceholderIndex, PlaceholderIndices, RegionValueElements,
|
||||
},
|
||||
region_infer::{ClosureRegionRequirementsExt, TypeTest},
|
||||
region_infer::TypeTest,
|
||||
type_check::free_region_relations::{CreateResult, UniversalRegionRelations},
|
||||
universal_regions::{DefiningTy, UniversalRegions},
|
||||
Upvar,
|
||||
@ -144,7 +145,6 @@ pub(crate) fn type_check<'mir, 'tcx>(
|
||||
liveness_constraints: LivenessValues::new(elements.clone()),
|
||||
outlives_constraints: OutlivesConstraintSet::default(),
|
||||
member_constraints: MemberConstraintSet::default(),
|
||||
closure_bounds_mapping: Default::default(),
|
||||
type_tests: Vec::default(),
|
||||
universe_causes: FxHashMap::default(),
|
||||
};
|
||||
@ -234,11 +234,11 @@ pub(crate) fn type_check<'mir, 'tcx>(
|
||||
let mut hidden_type = infcx.resolve_vars_if_possible(decl.hidden_type);
|
||||
trace!("finalized opaque type {:?} to {:#?}", opaque_type_key, hidden_type.ty.kind());
|
||||
if hidden_type.has_non_region_infer() {
|
||||
infcx.tcx.sess.delay_span_bug(
|
||||
let reported = infcx.tcx.sess.delay_span_bug(
|
||||
decl.hidden_type.span,
|
||||
&format!("could not resolve {:#?}", hidden_type.ty.kind()),
|
||||
);
|
||||
hidden_type.ty = infcx.tcx.ty_error();
|
||||
hidden_type.ty = infcx.tcx.ty_error_with_guaranteed(reported);
|
||||
}
|
||||
|
||||
(opaque_type_key, (hidden_type, decl.origin))
|
||||
@ -547,10 +547,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
|
||||
|
||||
if let PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) = context {
|
||||
let tcx = self.tcx();
|
||||
let trait_ref = ty::TraitRef {
|
||||
def_id: tcx.require_lang_item(LangItem::Copy, Some(self.last_span)),
|
||||
substs: tcx.mk_substs_trait(place_ty.ty, &[]),
|
||||
};
|
||||
let trait_ref = tcx.at(self.last_span).mk_trait_ref(LangItem::Copy, [place_ty.ty]);
|
||||
|
||||
// To have a `Copy` operand, the type `T` of the
|
||||
// value must be `Copy`. Note that we prove that `T: Copy`,
|
||||
@ -584,8 +581,6 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
|
||||
// modify their locations.
|
||||
let all_facts = &mut None;
|
||||
let mut constraints = Default::default();
|
||||
let mut type_tests = Default::default();
|
||||
let mut closure_bounds = Default::default();
|
||||
let mut liveness_constraints =
|
||||
LivenessValues::new(Rc::new(RegionValueElements::new(&promoted_body)));
|
||||
// Don't try to add borrow_region facts for the promoted MIR
|
||||
@ -596,11 +591,6 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
|
||||
&mut this.cx.borrowck_context.constraints.outlives_constraints,
|
||||
&mut constraints,
|
||||
);
|
||||
mem::swap(&mut this.cx.borrowck_context.constraints.type_tests, &mut type_tests);
|
||||
mem::swap(
|
||||
&mut this.cx.borrowck_context.constraints.closure_bounds_mapping,
|
||||
&mut closure_bounds,
|
||||
);
|
||||
mem::swap(
|
||||
&mut this.cx.borrowck_context.constraints.liveness_constraints,
|
||||
&mut liveness_constraints,
|
||||
@ -621,13 +611,6 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
|
||||
swap_constraints(self);
|
||||
|
||||
let locations = location.to_locations();
|
||||
|
||||
// Use location of promoted const in collected constraints
|
||||
for type_test in type_tests.iter() {
|
||||
let mut type_test = type_test.clone();
|
||||
type_test.locations = locations;
|
||||
self.cx.borrowck_context.constraints.type_tests.push(type_test)
|
||||
}
|
||||
for constraint in constraints.outlives().iter() {
|
||||
let mut constraint = constraint.clone();
|
||||
constraint.locations = locations;
|
||||
@ -653,18 +636,6 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
|
||||
.add_element(region, location);
|
||||
}
|
||||
}
|
||||
|
||||
if !closure_bounds.is_empty() {
|
||||
let combined_bounds_mapping =
|
||||
closure_bounds.into_iter().flat_map(|(_, value)| value).collect();
|
||||
let existing = self
|
||||
.cx
|
||||
.borrowck_context
|
||||
.constraints
|
||||
.closure_bounds_mapping
|
||||
.insert(location, combined_bounds_mapping);
|
||||
assert!(existing.is_none(), "Multiple promoteds/closures at the same location.");
|
||||
}
|
||||
}
|
||||
|
||||
fn sanitize_projection(
|
||||
@ -941,9 +912,6 @@ pub(crate) struct MirTypeckRegionConstraints<'tcx> {
|
||||
|
||||
pub(crate) member_constraints: MemberConstraintSet<'tcx, RegionVid>,
|
||||
|
||||
pub(crate) closure_bounds_mapping:
|
||||
FxHashMap<Location, FxHashMap<(RegionVid, RegionVid), (ConstraintCategory<'tcx>, Span)>>,
|
||||
|
||||
pub(crate) universe_causes: FxHashMap<ty::UniverseIndex, UniverseInfo<'tcx>>,
|
||||
|
||||
pub(crate) type_tests: Vec<TypeTest<'tcx>>,
|
||||
@ -1097,8 +1065,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
}
|
||||
|
||||
self.prove_predicate(
|
||||
ty::Binder::dummy(ty::PredicateKind::WellFormed(inferred_ty.into()))
|
||||
.to_predicate(self.tcx()),
|
||||
ty::Binder::dummy(ty::PredicateKind::WellFormed(inferred_ty.into())),
|
||||
Locations::All(span),
|
||||
ConstraintCategory::TypeAnnotation,
|
||||
);
|
||||
@ -1222,8 +1189,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
fn check_stmt(&mut self, body: &Body<'tcx>, stmt: &Statement<'tcx>, location: Location) {
|
||||
let tcx = self.tcx();
|
||||
debug!("stmt kind: {:?}", stmt.kind);
|
||||
match stmt.kind {
|
||||
StatementKind::Assign(box (ref place, ref rv)) => {
|
||||
match &stmt.kind {
|
||||
StatementKind::Assign(box (place, rv)) => {
|
||||
// Assignments to temporaries are not "interesting";
|
||||
// they are not caused by the user, but rather artifacts
|
||||
// of lowering. Assignments to other sorts of places *are* interesting
|
||||
@ -1303,10 +1270,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
|
||||
self.check_rvalue(body, rv, location);
|
||||
if !self.unsized_feature_enabled() {
|
||||
let trait_ref = ty::TraitRef {
|
||||
def_id: tcx.require_lang_item(LangItem::Sized, Some(self.last_span)),
|
||||
substs: tcx.mk_substs_trait(place_ty, &[]),
|
||||
};
|
||||
let trait_ref =
|
||||
tcx.at(self.last_span).mk_trait_ref(LangItem::Sized, [place_ty]);
|
||||
self.prove_trait_ref(
|
||||
trait_ref,
|
||||
location.to_locations(),
|
||||
@ -1314,11 +1279,11 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
);
|
||||
}
|
||||
}
|
||||
StatementKind::AscribeUserType(box (ref place, ref projection), variance) => {
|
||||
StatementKind::AscribeUserType(box (place, projection), variance) => {
|
||||
let place_ty = place.ty(body, tcx).ty;
|
||||
if let Err(terr) = self.relate_type_and_user_type(
|
||||
place_ty,
|
||||
variance,
|
||||
*variance,
|
||||
projection,
|
||||
Locations::All(stmt.source_info.span),
|
||||
ConstraintCategory::TypeAnnotation,
|
||||
@ -1335,7 +1300,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
);
|
||||
}
|
||||
}
|
||||
StatementKind::Intrinsic(box ref kind) => match kind {
|
||||
StatementKind::Intrinsic(box kind) => match kind {
|
||||
NonDivergingIntrinsic::Assume(op) => self.check_operand(op, location),
|
||||
NonDivergingIntrinsic::CopyNonOverlapping(..) => span_bug!(
|
||||
stmt.source_info.span,
|
||||
@ -1363,7 +1328,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
) {
|
||||
let tcx = self.tcx();
|
||||
debug!("terminator kind: {:?}", term.kind);
|
||||
match term.kind {
|
||||
match &term.kind {
|
||||
TerminatorKind::Goto { .. }
|
||||
| TerminatorKind::Resume
|
||||
| TerminatorKind::Abort
|
||||
@ -1377,7 +1342,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
// no checks needed for these
|
||||
}
|
||||
|
||||
TerminatorKind::DropAndReplace { ref place, ref value, target: _, unwind: _ } => {
|
||||
TerminatorKind::DropAndReplace { place, value, target: _, unwind: _ } => {
|
||||
let place_ty = place.ty(body, tcx).ty;
|
||||
let rv_ty = value.ty(body, tcx);
|
||||
|
||||
@ -1395,13 +1360,13 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
);
|
||||
}
|
||||
}
|
||||
TerminatorKind::SwitchInt { ref discr, switch_ty, .. } => {
|
||||
TerminatorKind::SwitchInt { discr, switch_ty, .. } => {
|
||||
self.check_operand(discr, term_location);
|
||||
|
||||
let discr_ty = discr.ty(body, tcx);
|
||||
if let Err(terr) = self.sub_types(
|
||||
discr_ty,
|
||||
switch_ty,
|
||||
*switch_ty,
|
||||
term_location.to_locations(),
|
||||
ConstraintCategory::Assignment,
|
||||
) {
|
||||
@ -1419,14 +1384,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
}
|
||||
// FIXME: check the values
|
||||
}
|
||||
TerminatorKind::Call {
|
||||
ref func,
|
||||
ref args,
|
||||
ref destination,
|
||||
from_hir_call,
|
||||
target,
|
||||
..
|
||||
} => {
|
||||
TerminatorKind::Call { func, args, destination, from_hir_call, target, .. } => {
|
||||
self.check_operand(func, term_location);
|
||||
for arg in args {
|
||||
self.check_operand(arg, term_location);
|
||||
@ -1466,7 +1424,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
ConstraintCategory::Boring,
|
||||
);
|
||||
let sig = self.normalize(sig, term_location);
|
||||
self.check_call_dest(body, term, &sig, *destination, target, term_location);
|
||||
self.check_call_dest(body, term, &sig, *destination, *target, term_location);
|
||||
|
||||
// The ordinary liveness rules will ensure that all
|
||||
// regions in the type of the callee are live here. We
|
||||
@ -1484,9 +1442,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
.add_element(region_vid, term_location);
|
||||
}
|
||||
|
||||
self.check_call_inputs(body, term, &sig, args, term_location, from_hir_call);
|
||||
self.check_call_inputs(body, term, &sig, args, term_location, *from_hir_call);
|
||||
}
|
||||
TerminatorKind::Assert { ref cond, ref msg, .. } => {
|
||||
TerminatorKind::Assert { cond, msg, .. } => {
|
||||
self.check_operand(cond, term_location);
|
||||
|
||||
let cond_ty = cond.ty(body, tcx);
|
||||
@ -1494,7 +1452,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
span_mirbug!(self, term, "bad Assert ({:?}, not bool", cond_ty);
|
||||
}
|
||||
|
||||
if let AssertKind::BoundsCheck { ref len, ref index } = *msg {
|
||||
if let AssertKind::BoundsCheck { len, index } = msg {
|
||||
if len.ty(body, tcx) != tcx.types.usize {
|
||||
span_mirbug!(self, len, "bounds-check length non-usize {:?}", len)
|
||||
}
|
||||
@ -1503,7 +1461,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
}
|
||||
TerminatorKind::Yield { ref value, .. } => {
|
||||
TerminatorKind::Yield { value, .. } => {
|
||||
self.check_operand(value, term_location);
|
||||
|
||||
let value_ty = value.ty(body, tcx);
|
||||
@ -1594,10 +1552,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
None => {
|
||||
if !self
|
||||
.tcx()
|
||||
.conservative_is_privately_uninhabited(self.param_env.and(sig.output()))
|
||||
{
|
||||
if !sig.output().is_privately_uninhabited(self.tcx(), self.param_env) {
|
||||
span_mirbug!(self, term, "call to converging function {:?} w/o dest", sig);
|
||||
}
|
||||
}
|
||||
@ -1873,6 +1828,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
#[instrument(skip(self, body), level = "debug")]
|
||||
fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: Location) {
|
||||
let tcx = self.tcx();
|
||||
let span = body.source_info(location).span;
|
||||
|
||||
match rvalue {
|
||||
Rvalue::Aggregate(ak, ops) => {
|
||||
@ -1896,12 +1852,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
}
|
||||
Operand::Move(place) => {
|
||||
// Make sure that repeated elements implement `Copy`.
|
||||
let span = body.source_info(location).span;
|
||||
let ty = place.ty(body, tcx).ty;
|
||||
let trait_ref = ty::TraitRef::new(
|
||||
tcx.require_lang_item(LangItem::Copy, Some(span)),
|
||||
tcx.mk_substs_trait(ty, &[]),
|
||||
);
|
||||
let trait_ref = tcx.at(span).mk_trait_ref(LangItem::Copy, [ty]);
|
||||
|
||||
self.prove_trait_ref(
|
||||
trait_ref,
|
||||
@ -1914,10 +1866,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
}
|
||||
|
||||
&Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, ty) => {
|
||||
let trait_ref = ty::TraitRef {
|
||||
def_id: tcx.require_lang_item(LangItem::Sized, Some(self.last_span)),
|
||||
substs: tcx.mk_substs_trait(ty, &[]),
|
||||
};
|
||||
let trait_ref = tcx.at(span).mk_trait_ref(LangItem::Sized, [ty]);
|
||||
|
||||
self.prove_trait_ref(
|
||||
trait_ref,
|
||||
@ -1929,10 +1878,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
Rvalue::ShallowInitBox(operand, ty) => {
|
||||
self.check_operand(operand, location);
|
||||
|
||||
let trait_ref = ty::TraitRef {
|
||||
def_id: tcx.require_lang_item(LangItem::Sized, Some(self.last_span)),
|
||||
substs: tcx.mk_substs_trait(*ty, &[]),
|
||||
};
|
||||
let trait_ref = tcx.at(span).mk_trait_ref(LangItem::Sized, [*ty]);
|
||||
|
||||
self.prove_trait_ref(
|
||||
trait_ref,
|
||||
@ -2029,11 +1975,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
|
||||
CastKind::Pointer(PointerCast::Unsize) => {
|
||||
let &ty = ty;
|
||||
let trait_ref = ty::TraitRef {
|
||||
def_id: tcx
|
||||
.require_lang_item(LangItem::CoerceUnsized, Some(self.last_span)),
|
||||
substs: tcx.mk_substs_trait(op.ty(body, tcx), &[ty.into()]),
|
||||
};
|
||||
let trait_ref = tcx
|
||||
.at(span)
|
||||
.mk_trait_ref(LangItem::CoerceUnsized, [op.ty(body, tcx), ty]);
|
||||
|
||||
self.prove_trait_ref(
|
||||
trait_ref,
|
||||
@ -2062,8 +2006,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
);
|
||||
|
||||
let outlives_predicate =
|
||||
tcx.mk_predicate(Binder::dummy(ty::PredicateKind::TypeOutlives(
|
||||
ty::OutlivesPredicate(self_ty, *region),
|
||||
tcx.mk_predicate(Binder::dummy(ty::PredicateKind::Clause(
|
||||
ty::Clause::TypeOutlives(ty::OutlivesPredicate(self_ty, *region)),
|
||||
)));
|
||||
self.prove_predicate(
|
||||
outlives_predicate,
|
||||
@ -2562,6 +2506,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
span: location.to_locations().span(body),
|
||||
category,
|
||||
variance_info: ty::VarianceDiagInfo::default(),
|
||||
from_closure: false,
|
||||
});
|
||||
|
||||
match mutbl {
|
||||
@ -2636,7 +2581,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
}
|
||||
|
||||
// For closures, we have some **extra requirements** we
|
||||
//
|
||||
// have to check. In particular, in their upvars and
|
||||
// signatures, closures often reference various regions
|
||||
// from the surrounding function -- we call those the
|
||||
@ -2679,62 +2623,22 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
substs: SubstsRef<'tcx>,
|
||||
location: Location,
|
||||
) -> ty::InstantiatedPredicates<'tcx> {
|
||||
if let Some(ref closure_region_requirements) = tcx.mir_borrowck(def_id).closure_requirements
|
||||
{
|
||||
let closure_constraints = QueryRegionConstraints {
|
||||
outlives: closure_region_requirements.apply_requirements(
|
||||
tcx,
|
||||
def_id.to_def_id(),
|
||||
substs,
|
||||
),
|
||||
|
||||
// Presently, closures never propagate member
|
||||
// constraints to their parents -- they are enforced
|
||||
// locally. This is largely a non-issue as member
|
||||
// constraints only come from `-> impl Trait` and
|
||||
// friends which don't appear (thus far...) in
|
||||
// closures.
|
||||
member_constraints: vec![],
|
||||
};
|
||||
|
||||
let bounds_mapping = closure_constraints
|
||||
.outlives
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter_map(|(idx, constraint)| {
|
||||
let ty::OutlivesPredicate(k1, r2) =
|
||||
constraint.0.no_bound_vars().unwrap_or_else(|| {
|
||||
bug!("query_constraint {:?} contained bound vars", constraint,);
|
||||
});
|
||||
|
||||
match k1.unpack() {
|
||||
GenericArgKind::Lifetime(r1) => {
|
||||
// constraint is r1: r2
|
||||
let r1_vid = self.borrowck_context.universal_regions.to_region_vid(r1);
|
||||
let r2_vid = self.borrowck_context.universal_regions.to_region_vid(r2);
|
||||
let outlives_requirements =
|
||||
&closure_region_requirements.outlives_requirements[idx];
|
||||
Some((
|
||||
(r1_vid, r2_vid),
|
||||
(outlives_requirements.category, outlives_requirements.blame_span),
|
||||
))
|
||||
}
|
||||
GenericArgKind::Type(_) | GenericArgKind::Const(_) => None,
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
let existing = self
|
||||
.borrowck_context
|
||||
.constraints
|
||||
.closure_bounds_mapping
|
||||
.insert(location, bounds_mapping);
|
||||
assert!(existing.is_none(), "Multiple closures at the same location.");
|
||||
|
||||
self.push_region_constraints(
|
||||
if let Some(closure_requirements) = &tcx.mir_borrowck(def_id).closure_requirements {
|
||||
constraint_conversion::ConstraintConversion::new(
|
||||
self.infcx,
|
||||
self.borrowck_context.universal_regions,
|
||||
self.region_bound_pairs,
|
||||
self.implicit_region_bound,
|
||||
self.param_env,
|
||||
location.to_locations(),
|
||||
ConstraintCategory::ClosureBounds,
|
||||
&closure_constraints,
|
||||
DUMMY_SP, // irrelevant; will be overrided.
|
||||
ConstraintCategory::Boring, // same as above.
|
||||
&mut self.borrowck_context.constraints,
|
||||
)
|
||||
.apply_closure_requirements(
|
||||
&closure_requirements,
|
||||
def_id.to_def_id(),
|
||||
substs,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -2,9 +2,8 @@ use rustc_infer::infer::nll_relate::{NormalizationStrategy, TypeRelating, TypeRe
|
||||
use rustc_infer::infer::NllRegionVariableOrigin;
|
||||
use rustc_infer::traits::PredicateObligations;
|
||||
use rustc_middle::mir::ConstraintCategory;
|
||||
use rustc_middle::ty::error::TypeError;
|
||||
use rustc_middle::ty::relate::TypeRelation;
|
||||
use rustc_middle::ty::{self, Const, Ty};
|
||||
use rustc_middle::ty::{self, Ty};
|
||||
use rustc_span::Span;
|
||||
use rustc_trait_selection::traits::query::Fallible;
|
||||
|
||||
@ -136,17 +135,11 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx>
|
||||
span: self.locations.span(self.type_checker.body),
|
||||
category: self.category,
|
||||
variance_info: info,
|
||||
from_closure: false,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
// We don't have to worry about the equality of consts during borrow checking
|
||||
// as consts always have a static lifetime.
|
||||
// FIXME(oli-obk): is this really true? We can at least have HKL and with
|
||||
// inline consts we may have further lifetimes that may be unsound to treat as
|
||||
// 'static.
|
||||
fn const_equate(&mut self, _a: Const<'tcx>, _b: Const<'tcx>) {}
|
||||
|
||||
fn normalization() -> NormalizationStrategy {
|
||||
NormalizationStrategy::Eager
|
||||
}
|
||||
@ -155,10 +148,7 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx>
|
||||
true
|
||||
}
|
||||
|
||||
fn register_opaque_type_obligations(
|
||||
&mut self,
|
||||
obligations: PredicateObligations<'tcx>,
|
||||
) -> Result<(), TypeError<'tcx>> {
|
||||
fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) {
|
||||
self.type_checker
|
||||
.fully_perform_op(
|
||||
self.locations,
|
||||
@ -171,6 +161,5 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx>
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@ -22,7 +22,9 @@ use rustc_hir::{BodyOwnerKind, HirId};
|
||||
use rustc_index::vec::{Idx, IndexVec};
|
||||
use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin};
|
||||
use rustc_middle::ty::fold::TypeFoldable;
|
||||
use rustc_middle::ty::{self, InlineConstSubsts, InlineConstSubstsParts, RegionVid, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{
|
||||
self, DefIdTree, InlineConstSubsts, InlineConstSubstsParts, RegionVid, Ty, TyCtxt,
|
||||
};
|
||||
use rustc_middle::ty::{InternalSubsts, SubstsRef};
|
||||
use std::iter;
|
||||
|
||||
@ -241,7 +243,7 @@ impl<'tcx> UniversalRegions<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
closure_substs: SubstsRef<'tcx>,
|
||||
expected_num_vars: usize,
|
||||
typeck_root_def_id: DefId,
|
||||
closure_def_id: LocalDefId,
|
||||
) -> IndexVec<RegionVid, ty::Region<'tcx>> {
|
||||
let mut region_mapping = IndexVec::with_capacity(expected_num_vars);
|
||||
region_mapping.push(tcx.lifetimes.re_static);
|
||||
@ -249,7 +251,7 @@ impl<'tcx> UniversalRegions<'tcx> {
|
||||
region_mapping.push(fr);
|
||||
});
|
||||
|
||||
for_each_late_bound_region_defined_on(tcx, typeck_root_def_id, |r| {
|
||||
for_each_late_bound_region_in_recursive_scope(tcx, tcx.local_parent(closure_def_id), |r| {
|
||||
region_mapping.push(r);
|
||||
});
|
||||
|
||||
@ -339,9 +341,8 @@ impl<'tcx> UniversalRegions<'tcx> {
|
||||
// tests, and the resulting print-outs include def-ids
|
||||
// and other things that are not stable across tests!
|
||||
// So we just include the region-vid. Annoying.
|
||||
let typeck_root_def_id = tcx.typeck_root_def_id(def_id);
|
||||
for_each_late_bound_region_defined_on(tcx, typeck_root_def_id, |r| {
|
||||
err.note(&format!("late-bound region is {:?}", self.to_region_vid(r),));
|
||||
for_each_late_bound_region_in_recursive_scope(tcx, def_id.expect_local(), |r| {
|
||||
err.note(&format!("late-bound region is {:?}", self.to_region_vid(r)));
|
||||
});
|
||||
}
|
||||
DefiningTy::Generator(def_id, substs, _) => {
|
||||
@ -354,9 +355,8 @@ impl<'tcx> UniversalRegions<'tcx> {
|
||||
// FIXME: As above, we'd like to print out the region
|
||||
// `r` but doing so is not stable across architectures
|
||||
// and so forth.
|
||||
let typeck_root_def_id = tcx.typeck_root_def_id(def_id);
|
||||
for_each_late_bound_region_defined_on(tcx, typeck_root_def_id, |r| {
|
||||
err.note(&format!("late-bound region is {:?}", self.to_region_vid(r),));
|
||||
for_each_late_bound_region_in_recursive_scope(tcx, def_id.expect_local(), |r| {
|
||||
err.note(&format!("late-bound region is {:?}", self.to_region_vid(r)));
|
||||
});
|
||||
}
|
||||
DefiningTy::FnDef(def_id, substs) => {
|
||||
@ -421,13 +421,24 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
||||
first_extern_index
|
||||
} else {
|
||||
// If this is a closure, generator, or inline-const, then the late-bound regions from the enclosing
|
||||
// function are actually external regions to us. For example, here, 'a is not local
|
||||
// function/closures are actually external regions to us. For example, here, 'a is not local
|
||||
// to the closure c (although it is local to the fn foo):
|
||||
// fn foo<'a>() {
|
||||
// let c = || { let x: &'a u32 = ...; }
|
||||
// }
|
||||
self.infcx
|
||||
.replace_late_bound_regions_with_nll_infer_vars(self.mir_def.did, &mut indices);
|
||||
for_each_late_bound_region_in_recursive_scope(
|
||||
self.infcx.tcx,
|
||||
self.infcx.tcx.local_parent(self.mir_def.did),
|
||||
|r| {
|
||||
debug!(?r);
|
||||
if !indices.indices.contains_key(&r) {
|
||||
let region_vid = self.infcx.next_nll_region_var(FR);
|
||||
debug!(?region_vid);
|
||||
indices.insert_late_bound_region(r, region_vid.to_region_vid());
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
// Any regions created during the execution of `defining_ty` or during the above
|
||||
// late-bound region replacement are all considered 'extern' regions
|
||||
self.infcx.num_region_vars()
|
||||
@ -444,12 +455,16 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
||||
bound_inputs_and_output,
|
||||
&mut indices,
|
||||
);
|
||||
// Converse of above, if this is a function then the late-bound regions declared on its
|
||||
// signature are local to the fn.
|
||||
if self.mir_def.did.to_def_id() == typeck_root_def_id {
|
||||
self.infcx
|
||||
.replace_late_bound_regions_with_nll_infer_vars(self.mir_def.did, &mut indices);
|
||||
}
|
||||
// Converse of above, if this is a function/closure then the late-bound regions declared on its
|
||||
// signature are local.
|
||||
for_each_late_bound_region_in_item(self.infcx.tcx, self.mir_def.did, |r| {
|
||||
debug!(?r);
|
||||
if !indices.indices.contains_key(&r) {
|
||||
let region_vid = self.infcx.next_nll_region_var(FR);
|
||||
debug!(?region_vid);
|
||||
indices.insert_late_bound_region(r, region_vid.to_region_vid());
|
||||
}
|
||||
});
|
||||
|
||||
let (unnormalized_output_ty, mut unnormalized_input_tys) =
|
||||
inputs_and_output.split_last().unwrap();
|
||||
@ -572,9 +587,9 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
||||
let typeck_root_def_id = tcx.typeck_root_def_id(self.mir_def.did.to_def_id());
|
||||
let identity_substs = InternalSubsts::identity_for_item(tcx, typeck_root_def_id);
|
||||
let fr_substs = match defining_ty {
|
||||
DefiningTy::Closure(_, ref substs)
|
||||
| DefiningTy::Generator(_, ref substs, _)
|
||||
| DefiningTy::InlineConst(_, ref substs) => {
|
||||
DefiningTy::Closure(_, substs)
|
||||
| DefiningTy::Generator(_, substs, _)
|
||||
| DefiningTy::InlineConst(_, substs) => {
|
||||
// In the case of closures, we rely on the fact that
|
||||
// the first N elements in the ClosureSubsts are
|
||||
// inherited from the `typeck_root_def_id`.
|
||||
@ -692,7 +707,13 @@ trait InferCtxtExt<'tcx> {
|
||||
where
|
||||
T: TypeFoldable<'tcx>;
|
||||
|
||||
fn replace_late_bound_regions_with_nll_infer_vars(
|
||||
fn replace_late_bound_regions_with_nll_infer_vars_in_recursive_scope(
|
||||
&self,
|
||||
mir_def_id: LocalDefId,
|
||||
indices: &mut UniversalRegionIndices<'tcx>,
|
||||
);
|
||||
|
||||
fn replace_late_bound_regions_with_nll_infer_vars_in_item(
|
||||
&self,
|
||||
mir_def_id: LocalDefId,
|
||||
indices: &mut UniversalRegionIndices<'tcx>,
|
||||
@ -746,13 +767,28 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
|
||||
/// set of late-bound regions and checks for any that we have not yet seen, adding them to the
|
||||
/// inputs vector.
|
||||
#[instrument(skip(self, indices))]
|
||||
fn replace_late_bound_regions_with_nll_infer_vars(
|
||||
fn replace_late_bound_regions_with_nll_infer_vars_in_recursive_scope(
|
||||
&self,
|
||||
mir_def_id: LocalDefId,
|
||||
indices: &mut UniversalRegionIndices<'tcx>,
|
||||
) {
|
||||
let typeck_root_def_id = self.tcx.typeck_root_def_id(mir_def_id.to_def_id());
|
||||
for_each_late_bound_region_defined_on(self.tcx, typeck_root_def_id, |r| {
|
||||
for_each_late_bound_region_in_recursive_scope(self.tcx, mir_def_id, |r| {
|
||||
debug!(?r);
|
||||
if !indices.indices.contains_key(&r) {
|
||||
let region_vid = self.next_nll_region_var(FR);
|
||||
debug!(?region_vid);
|
||||
indices.insert_late_bound_region(r, region_vid.to_region_vid());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#[instrument(skip(self, indices))]
|
||||
fn replace_late_bound_regions_with_nll_infer_vars_in_item(
|
||||
&self,
|
||||
mir_def_id: LocalDefId,
|
||||
indices: &mut UniversalRegionIndices<'tcx>,
|
||||
) {
|
||||
for_each_late_bound_region_in_item(self.tcx, mir_def_id, |r| {
|
||||
debug!(?r);
|
||||
if !indices.indices.contains_key(&r) {
|
||||
let region_vid = self.next_nll_region_var(FR);
|
||||
@ -803,21 +839,44 @@ impl<'tcx> UniversalRegionIndices<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Iterates over the late-bound regions defined on fn_def_id and
|
||||
/// invokes `f` with the liberated form of each one.
|
||||
fn for_each_late_bound_region_defined_on<'tcx>(
|
||||
/// Iterates over the late-bound regions defined on `mir_def_id` and all of its
|
||||
/// parents, up to the typeck root, and invokes `f` with the liberated form
|
||||
/// of each one.
|
||||
fn for_each_late_bound_region_in_recursive_scope<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
fn_def_id: DefId,
|
||||
mut mir_def_id: LocalDefId,
|
||||
mut f: impl FnMut(ty::Region<'tcx>),
|
||||
) {
|
||||
if let Some(late_bounds) = tcx.is_late_bound_map(fn_def_id.expect_local()) {
|
||||
for ®ion_def_id in late_bounds.iter() {
|
||||
let name = tcx.item_name(region_def_id.to_def_id());
|
||||
let liberated_region = tcx.mk_region(ty::ReFree(ty::FreeRegion {
|
||||
scope: fn_def_id,
|
||||
bound_region: ty::BoundRegionKind::BrNamed(region_def_id.to_def_id(), name),
|
||||
}));
|
||||
f(liberated_region);
|
||||
let typeck_root_def_id = tcx.typeck_root_def_id(mir_def_id.to_def_id());
|
||||
|
||||
// Walk up the tree, collecting late-bound regions until we hit the typeck root
|
||||
loop {
|
||||
for_each_late_bound_region_in_item(tcx, mir_def_id, &mut f);
|
||||
|
||||
if mir_def_id.to_def_id() == typeck_root_def_id {
|
||||
break;
|
||||
} else {
|
||||
mir_def_id = tcx.local_parent(mir_def_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Iterates over the late-bound regions defined on `mir_def_id` and all of its
|
||||
/// parents, up to the typeck root, and invokes `f` with the liberated form
|
||||
/// of each one.
|
||||
fn for_each_late_bound_region_in_item<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
mir_def_id: LocalDefId,
|
||||
mut f: impl FnMut(ty::Region<'tcx>),
|
||||
) {
|
||||
if !tcx.def_kind(mir_def_id).is_fn_like() {
|
||||
return;
|
||||
}
|
||||
|
||||
for bound_var in tcx.late_bound_vars(tcx.hir().local_def_id_to_hir_id(mir_def_id)) {
|
||||
let ty::BoundVariableKind::Region(bound_region) = bound_var else { continue; };
|
||||
let liberated_region = tcx
|
||||
.mk_region(ty::ReFree(ty::FreeRegion { scope: mir_def_id.to_def_id(), bound_region }));
|
||||
f(liberated_region);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
#![deny(rustc::untranslatable_diagnostic)]
|
||||
#![deny(rustc::diagnostic_outside_of_impl)]
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_middle::mir::visit::{PlaceContext, Visitor};
|
||||
use rustc_middle::mir::{
|
||||
|
||||
@ -23,5 +23,5 @@ rustc_session = { path = "../rustc_session" }
|
||||
rustc_span = { path = "../rustc_span" }
|
||||
rustc_target = { path = "../rustc_target" }
|
||||
smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
|
||||
thin-vec = "0.2.8"
|
||||
thin-vec = "0.2.9"
|
||||
tracing = "0.1"
|
||||
|
||||
93
compiler/rustc_builtin_macros/src/alloc_error_handler.rs
Normal file
93
compiler/rustc_builtin_macros/src/alloc_error_handler.rs
Normal file
@ -0,0 +1,93 @@
|
||||
use crate::util::check_builtin_macro_attribute;
|
||||
|
||||
use rustc_ast::ptr::P;
|
||||
use rustc_ast::{self as ast, FnHeader, FnSig, Generics, StmtKind};
|
||||
use rustc_ast::{Fn, ItemKind, Stmt, TyKind, Unsafe};
|
||||
use rustc_expand::base::{Annotatable, ExtCtxt};
|
||||
use rustc_span::symbol::{kw, sym, Ident};
|
||||
use rustc_span::Span;
|
||||
use thin_vec::thin_vec;
|
||||
|
||||
pub fn expand(
|
||||
ecx: &mut ExtCtxt<'_>,
|
||||
_span: Span,
|
||||
meta_item: &ast::MetaItem,
|
||||
item: Annotatable,
|
||||
) -> Vec<Annotatable> {
|
||||
check_builtin_macro_attribute(ecx, meta_item, sym::alloc_error_handler);
|
||||
|
||||
let orig_item = item.clone();
|
||||
|
||||
// Allow using `#[alloc_error_handler]` on an item statement
|
||||
// FIXME - if we get deref patterns, use them to reduce duplication here
|
||||
let (item, is_stmt, sig_span) =
|
||||
if let Annotatable::Item(item) = &item
|
||||
&& let ItemKind::Fn(fn_kind) = &item.kind
|
||||
{
|
||||
(item, false, ecx.with_def_site_ctxt(fn_kind.sig.span))
|
||||
} else if let Annotatable::Stmt(stmt) = &item
|
||||
&& let StmtKind::Item(item) = &stmt.kind
|
||||
&& let ItemKind::Fn(fn_kind) = &item.kind
|
||||
{
|
||||
(item, true, ecx.with_def_site_ctxt(fn_kind.sig.span))
|
||||
} else {
|
||||
ecx.sess.parse_sess.span_diagnostic.span_err(item.span(), "alloc_error_handler must be a function");
|
||||
return vec![orig_item.clone()];
|
||||
};
|
||||
|
||||
// Generate a bunch of new items using the AllocFnFactory
|
||||
let span = ecx.with_def_site_ctxt(item.span);
|
||||
|
||||
// Generate item statements for the allocator methods.
|
||||
let stmts = vec![generate_handler(ecx, item.ident, span, sig_span)];
|
||||
|
||||
// Generate anonymous constant serving as container for the allocator methods.
|
||||
let const_ty = ecx.ty(sig_span, TyKind::Tup(Vec::new()));
|
||||
let const_body = ecx.expr_block(ecx.block(span, stmts));
|
||||
let const_item = ecx.item_const(span, Ident::new(kw::Underscore, span), const_ty, const_body);
|
||||
let const_item = if is_stmt {
|
||||
Annotatable::Stmt(P(ecx.stmt_item(span, const_item)))
|
||||
} else {
|
||||
Annotatable::Item(const_item)
|
||||
};
|
||||
|
||||
// Return the original item and the new methods.
|
||||
vec![orig_item, const_item]
|
||||
}
|
||||
|
||||
// #[rustc_std_internal_symbol]
|
||||
// unsafe fn __rg_oom(size: usize, align: usize) -> ! {
|
||||
// handler(core::alloc::Layout::from_size_align_unchecked(size, align))
|
||||
// }
|
||||
fn generate_handler(cx: &ExtCtxt<'_>, handler: Ident, span: Span, sig_span: Span) -> Stmt {
|
||||
let usize = cx.path_ident(span, Ident::new(sym::usize, span));
|
||||
let ty_usize = cx.ty_path(usize);
|
||||
let size = Ident::from_str_and_span("size", span);
|
||||
let align = Ident::from_str_and_span("align", span);
|
||||
|
||||
let layout_new = cx.std_path(&[sym::alloc, sym::Layout, sym::from_size_align_unchecked]);
|
||||
let layout_new = cx.expr_path(cx.path(span, layout_new));
|
||||
let layout =
|
||||
cx.expr_call(span, layout_new, vec![cx.expr_ident(span, size), cx.expr_ident(span, align)]);
|
||||
|
||||
let call = cx.expr_call_ident(sig_span, handler, vec![layout]);
|
||||
|
||||
let never = ast::FnRetTy::Ty(cx.ty(span, TyKind::Never));
|
||||
let params = vec![cx.param(span, size, ty_usize.clone()), cx.param(span, align, ty_usize)];
|
||||
let decl = cx.fn_decl(params, never);
|
||||
let header = FnHeader { unsafety: Unsafe::Yes(span), ..FnHeader::default() };
|
||||
let sig = FnSig { decl, header, span: span };
|
||||
|
||||
let body = Some(cx.block_expr(call));
|
||||
let kind = ItemKind::Fn(Box::new(Fn {
|
||||
defaultness: ast::Defaultness::Final,
|
||||
sig,
|
||||
generics: Generics::default(),
|
||||
body,
|
||||
}));
|
||||
|
||||
let attrs = thin_vec![cx.attr_word(sym::rustc_std_internal_symbol, span)];
|
||||
|
||||
let item = cx.item(span, Ident::from_str_and_span("__rg_oom", span), attrs, kind);
|
||||
cx.stmt_item(sig_span, item)
|
||||
}
|
||||
@ -172,7 +172,11 @@ pub fn parse_asm_args<'a>(
|
||||
// If it can't possibly expand to a string, provide diagnostics here to include other
|
||||
// things it could have been.
|
||||
match template.kind {
|
||||
ast::ExprKind::Lit(ast::Lit { kind: ast::LitKind::Str(..), .. }) => {}
|
||||
ast::ExprKind::Lit(token_lit)
|
||||
if matches!(
|
||||
token_lit.kind,
|
||||
token::LitKind::Str | token::LitKind::StrRaw(_)
|
||||
) => {}
|
||||
ast::ExprKind::MacCall(..) => {}
|
||||
_ => {
|
||||
let errstr = if is_global_asm {
|
||||
@ -560,7 +564,7 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, args: AsmArgs) -> Option<ast::Inl
|
||||
let template_snippet = ecx.source_map().span_to_snippet(template_sp).ok();
|
||||
template_strs.push((
|
||||
template_str,
|
||||
template_snippet.as_ref().map(|s| Symbol::intern(s)),
|
||||
template_snippet.as_deref().map(Symbol::intern),
|
||||
template_sp,
|
||||
));
|
||||
let template_str = template_str.as_str();
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user