New upstream version 1.67.1+dfsg1

This commit is contained in:
Fabian Grünbichler 2023-07-05 13:41:24 +02:00
parent 2b03887add
commit 487cf647e7
7875 changed files with 513371 additions and 976793 deletions

View File

@ -1,11 +1,5 @@
[source.crates-io] [source.crates-io]
replace-with = "vendored-sources" 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] [source.vendored-sources]
directory = "vendor" directory = "vendor"

View File

@ -339,3 +339,53 @@ their own copyright notices and license terms:
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
OF SUCH DAMAGE. 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

File diff suppressed because it is too large Load Diff

View File

@ -11,6 +11,7 @@ members = [
"src/tools/error_index_generator", "src/tools/error_index_generator",
"src/tools/linkchecker", "src/tools/linkchecker",
"src/tools/lint-docs", "src/tools/lint-docs",
"src/tools/miropt-test-tools",
"src/tools/rustbook", "src/tools/rustbook",
"src/tools/unstable-book-gen", "src/tools/unstable-book-gen",
"src/tools/tidy", "src/tools/tidy",
@ -38,6 +39,8 @@ members = [
"src/tools/bump-stage0", "src/tools/bump-stage0",
"src/tools/replace-version-placeholder", "src/tools/replace-version-placeholder",
"src/tools/lld-wrapper", "src/tools/lld-wrapper",
"src/tools/collect-license-metadata",
"src/tools/generate-copyright",
] ]
exclude = [ exclude = [

View File

@ -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) 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/) - [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/) - [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`. 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/) - [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/) - [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/) - [Update to Unicode 15](https://github.com/rust-lang/rust/pull/101912/)

View 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",
]

View 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 well 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),
})
}
}

File diff suppressed because it is too large Load Diff

View File

@ -52,19 +52,15 @@ fn test_arena_alloc_nested() {
impl<'a> Wrap<'a> { impl<'a> Wrap<'a> {
fn alloc_inner<F: Fn() -> Inner>(&self, f: F) -> &Inner { fn alloc_inner<F: Fn() -> Inner>(&self, f: F) -> &Inner {
let r: &EI<'_> = self.0.alloc(EI::I(f())); match self.0.alloc(EI::I(f())) {
if let &EI::I(ref i) = r { EI::I(i) => i,
i _ => panic!("mismatch"),
} else {
panic!("mismatch");
} }
} }
fn alloc_outer<F: Fn() -> Outer<'a>>(&self, f: F) -> &Outer<'_> { fn alloc_outer<F: Fn() -> Outer<'a>>(&self, f: F) -> &Outer<'_> {
let r: &EI<'_> = self.0.alloc(EI::O(f())); match self.0.alloc(EI::O(f())) {
if let &EI::O(ref o) = r { EI::O(o) => o,
o _ => panic!("mismatch"),
} else {
panic!("mismatch");
} }
} }
} }

View File

@ -14,5 +14,5 @@ rustc_macros = { path = "../rustc_macros" }
rustc_serialize = { path = "../rustc_serialize" } rustc_serialize = { path = "../rustc_serialize" }
rustc_span = { path = "../rustc_span" } rustc_span = { path = "../rustc_span" }
smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
thin-vec = "0.2.8" thin-vec = "0.2.9"
tracing = "0.1" tracing = "0.1"

View File

@ -13,7 +13,7 @@
//! - [`FnDecl`], [`FnHeader`] and [`Param`]: Metadata associated with a function declaration. //! - [`FnDecl`], [`FnHeader`] and [`Param`]: Metadata associated with a function declaration.
//! - [`Generics`], [`GenericParam`], [`WhereClause`]: Metadata associated with generic parameters. //! - [`Generics`], [`GenericParam`], [`WhereClause`]: Metadata associated with generic parameters.
//! - [`EnumDef`] and [`Variant`]: Enum declaration. //! - [`EnumDef`] and [`Variant`]: Enum declaration.
//! - [`Lit`] and [`LitKind`]: Literal expressions. //! - [`MetaItemLit`] and [`LitKind`]: Literal expressions.
//! - [`MacroDef`], [`MacStmtStyle`], [`MacCall`], [`MacDelimiter`]: Macro definition and invocation. //! - [`MacroDef`], [`MacStmtStyle`], [`MacCall`], [`MacDelimiter`]: Macro definition and invocation.
//! - [`Attribute`]: Metadata associated with item. //! - [`Attribute`]: Metadata associated with item.
//! - [`UnOp`], [`BinOp`], and [`BinOpKind`]: Unary and binary operators. //! - [`UnOp`], [`BinOp`], and [`BinOpKind`]: Unary and binary operators.
@ -36,7 +36,7 @@ use rustc_span::{Span, DUMMY_SP};
use std::convert::TryFrom; use std::convert::TryFrom;
use std::fmt; use std::fmt;
use std::mem; use std::mem;
use thin_vec::ThinVec; use thin_vec::{thin_vec, ThinVec};
/// A "Label" is an identifier of some point in sources, /// A "Label" is an identifier of some point in sources,
/// e.g. in the following code: /// e.g. in the following code:
@ -90,7 +90,7 @@ pub struct Path {
pub span: Span, pub span: Span,
/// The segments in the path: the things separated by `::`. /// The segments in the path: the things separated by `::`.
/// Global paths begin with `kw::PathRoot`. /// Global paths begin with `kw::PathRoot`.
pub segments: Vec<PathSegment>, pub segments: ThinVec<PathSegment>,
pub tokens: Option<LazyAttrTokenStream>, pub tokens: Option<LazyAttrTokenStream>,
} }
@ -111,10 +111,10 @@ impl<CTX: rustc_span::HashStableContext> HashStable<CTX> for Path {
} }
impl Path { impl Path {
// Convert a span and an identifier to the corresponding /// Convert a span and an identifier to the corresponding
// one-segment path. /// one-segment path.
pub fn from_ident(ident: Ident) -> 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 { pub fn is_global(&self) -> bool {
@ -175,9 +175,9 @@ impl GenericArgs {
} }
pub fn span(&self) -> Span { pub fn span(&self) -> Span {
match *self { match self {
AngleBracketed(ref data) => data.span, AngleBracketed(data) => data.span,
Parenthesized(ref data) => data.span, Parenthesized(data) => data.span,
} }
} }
} }
@ -312,8 +312,8 @@ pub enum GenericBound {
impl GenericBound { impl GenericBound {
pub fn span(&self) -> Span { pub fn span(&self) -> Span {
match self { match self {
GenericBound::Trait(ref t, ..) => t.span, GenericBound::Trait(t, ..) => t.span,
GenericBound::Outlives(ref l) => l.ident.span, GenericBound::Outlives(l) => l.ident.span,
} }
} }
} }
@ -392,15 +392,7 @@ pub struct Generics {
impl Default for Generics { impl Default for Generics {
/// Creates an instance of `Generics`. /// Creates an instance of `Generics`.
fn default() -> Generics { fn default() -> Generics {
Generics { Generics { params: Vec::new(), where_clause: Default::default(), span: DUMMY_SP }
params: Vec::new(),
where_clause: WhereClause {
has_where_token: false,
predicates: Vec::new(),
span: DUMMY_SP,
},
span: DUMMY_SP,
}
} }
} }
@ -415,6 +407,12 @@ pub struct WhereClause {
pub span: Span, 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. /// A single predicate in a where-clause.
#[derive(Clone, Encodable, Decodable, Debug)] #[derive(Clone, Encodable, Decodable, Debug)]
pub enum WherePredicate { pub enum WherePredicate {
@ -481,20 +479,10 @@ pub struct Crate {
pub is_placeholder: bool, pub is_placeholder: bool,
} }
/// Possible values inside of compile-time attribute lists. /// A semantic representation of a meta item. A meta item is a slightly
/// /// restricted form of an attribute -- it can only contain expressions in
/// E.g., the '..' in `#[name(..)]`. /// certain leaf positions, rather than arbitrary token streams -- that is used
#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)] /// for most built-in attributes.
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.
/// ///
/// E.g., `#[test]`, `#[derive(..)]`, `#[rustfmt::skip]` or `#[feature = "foo"]`. /// E.g., `#[test]`, `#[derive(..)]`, `#[rustfmt::skip]` or `#[feature = "foo"]`.
#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)] #[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
@ -504,23 +492,37 @@ pub struct MetaItem {
pub span: Span, pub span: Span,
} }
/// A compile-time attribute item. /// The meta item kind, containing the data after the initial path.
///
/// E.g., `#[test]`, `#[derive(..)]` or `#[feature = "foo"]`.
#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)] #[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
pub enum MetaItemKind { pub enum MetaItemKind {
/// Word meta item. /// Word meta item.
/// ///
/// E.g., `test` as in `#[test]`. /// E.g., `#[test]`, which lacks any arguments after `test`.
Word, Word,
/// List meta item. /// List meta item.
/// ///
/// E.g., `derive(..)` as in `#[derive(..)]`. /// E.g., `#[derive(..)]`, where the field represents the `..`.
List(Vec<NestedMetaItem>), List(Vec<NestedMetaItem>),
/// Name value meta item. /// Name value meta item.
/// ///
/// E.g., `feature = "foo"` as in `#[feature = "foo"]`. /// E.g., `#[feature = "foo"]`, where the field represents the `"foo"`.
NameValue(Lit), 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 (`{ .. }`). /// A block (`{ .. }`).
@ -720,10 +722,10 @@ pub enum PatKind {
/// A struct or struct variant pattern (e.g., `Variant {x, y, ..}`). /// A struct or struct variant pattern (e.g., `Variant {x, y, ..}`).
/// The `bool` is `true` in the presence of a `..`. /// 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)`). /// 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`. /// An or-pattern `A | B | C`.
/// Invariant: `pats.len() >= 2`. /// Invariant: `pats.len() >= 2`.
@ -733,7 +735,7 @@ pub enum PatKind {
/// Unqualified path patterns `A::B::C` can legally refer to variants, structs, constants /// 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 /// or associated constants. Qualified path patterns `<A>::B::C`/`<A as Trait>::B::C` can
/// only legally refer to associated constants. /// only legally refer to associated constants.
Path(Option<QSelf>, Path), Path(Option<P<QSelf>>, Path),
/// A tuple pattern (`(a, b)`). /// A tuple pattern (`(a, b)`).
Tuple(Vec<P<Pat>>), Tuple(Vec<P<Pat>>),
@ -777,8 +779,9 @@ pub enum PatKind {
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Copy)] #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Copy)]
#[derive(HashStable_Generic, Encodable, Decodable)] #[derive(HashStable_Generic, Encodable, Decodable)]
pub enum Mutability { pub enum Mutability {
Mut, // N.B. Order is deliberate, so that Not < Mut
Not, Not,
Mut,
} }
impl Mutability { 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 { match self {
Mutability::Mut => "mut ", Mutability::Mut => "mut ",
Mutability::Not => "", 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, /// 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 /// If this is not the case, name resolution does not resolve `N` when using
/// `min_const_generics` as more complex expressions are not supported. /// `min_const_generics` as more complex expressions are not supported.
pub fn is_potential_trivial_const_param(&self) -> bool { pub fn is_potential_trivial_const_param(&self) -> bool {
let this = if let ExprKind::Block(ref block, None) = self.kind { let this = if let ExprKind::Block(block, None) = &self.kind
if block.stmts.len() == 1 { && block.stmts.len() == 1
if let StmtKind::Expr(ref expr) = block.stmts[0].kind { expr } else { self } && let StmtKind::Expr(expr) = &block.stmts[0].kind
} else { {
self expr
}
} else { } else {
self self
}; };
if let ExprKind::Path(None, ref path) = this.kind { if let ExprKind::Path(None, path) = &this.kind
if path.segments.len() == 1 && path.segments[0].args.is_none() { && path.segments.len() == 1
return true; && path.segments[0].args.is_none()
} {
true
} else {
false
} }
false
} }
pub fn to_bound(&self) -> Option<GenericBound> { pub fn to_bound(&self) -> Option<GenericBound> {
@ -1149,7 +1179,7 @@ impl Expr {
pub fn peel_parens(&self) -> &Expr { pub fn peel_parens(&self) -> &Expr {
let mut expr = self; let mut expr = self;
while let ExprKind::Paren(inner) = &expr.kind { while let ExprKind::Paren(inner) = &expr.kind {
expr = &inner; expr = inner;
} }
expr expr
} }
@ -1208,7 +1238,7 @@ impl Expr {
ExprKind::Tup(_) => ExprPrecedence::Tup, ExprKind::Tup(_) => ExprPrecedence::Tup,
ExprKind::Binary(op, ..) => ExprPrecedence::Binary(op.node), ExprKind::Binary(op, ..) => ExprPrecedence::Binary(op.node),
ExprKind::Unary(..) => ExprPrecedence::Unary, ExprKind::Unary(..) => ExprPrecedence::Unary,
ExprKind::Lit(_) => ExprPrecedence::Lit, ExprKind::Lit(_) | ExprKind::IncludedBytes(..) => ExprPrecedence::Lit,
ExprKind::Type(..) | ExprKind::Cast(..) => ExprPrecedence::Cast, ExprKind::Type(..) | ExprKind::Cast(..) => ExprPrecedence::Cast,
ExprKind::Let(..) => ExprPrecedence::Let, ExprKind::Let(..) => ExprPrecedence::Let,
ExprKind::If(..) => ExprPrecedence::If, 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 { pub fn is_approximately_pattern(&self) -> bool {
match &self.peel_parens().kind { match &self.peel_parens().kind {
ExprKind::Box(_) 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) /// Limit types of a range (inclusive or exclusive)
#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug)] #[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug)]
pub enum RangeLimits { pub enum RangeLimits {
@ -1283,6 +1327,20 @@ pub enum RangeLimits {
Closed, 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)] #[derive(Clone, Encodable, Decodable, Debug)]
pub enum StructRest { pub enum StructRest {
/// `..x`. /// `..x`.
@ -1295,7 +1353,7 @@ pub enum StructRest {
#[derive(Clone, Encodable, Decodable, Debug)] #[derive(Clone, Encodable, Decodable, Debug)]
pub struct StructExpr { pub struct StructExpr {
pub qself: Option<QSelf>, pub qself: Option<P<QSelf>>,
pub path: Path, pub path: Path,
pub fields: Vec<ExprField>, pub fields: Vec<ExprField>,
pub rest: StructRest, pub rest: StructRest,
@ -1316,17 +1374,8 @@ pub enum ExprKind {
/// This also represents calling the constructor of /// This also represents calling the constructor of
/// tuple-like ADTs such as tuple structs and enum variants. /// tuple-like ADTs such as tuple structs and enum variants.
Call(P<Expr>, Vec<P<Expr>>), Call(P<Expr>, Vec<P<Expr>>),
/// A method call (`x.foo::<'static, Bar, Baz>(a, b, c, d)`) /// A method call (e.g. `x.foo::<Bar, Baz>(a, b, c)`).
/// MethodCall(Box<MethodCall>),
/// 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 tuple (e.g., `(a, b, c, d)`). /// A tuple (e.g., `(a, b, c, d)`).
Tup(Vec<P<Expr>>), Tup(Vec<P<Expr>>),
/// A binary operation (e.g., `a + b`, `a * b`). /// A binary operation (e.g., `a + b`, `a * b`).
@ -1334,7 +1383,7 @@ pub enum ExprKind {
/// A unary operation (e.g., `!x`, `*x`). /// A unary operation (e.g., `!x`, `*x`).
Unary(UnOp, P<Expr>), Unary(UnOp, P<Expr>),
/// A literal (e.g., `1`, `"foo"`). /// A literal (e.g., `1`, `"foo"`).
Lit(Lit), Lit(token::Lit),
/// A cast (e.g., `foo as f64`). /// A cast (e.g., `foo as f64`).
Cast(P<Expr>, P<Ty>), Cast(P<Expr>, P<Ty>),
/// A type ascription (e.g., `42: usize`). /// A type ascription (e.g., `42: usize`).
@ -1361,13 +1410,11 @@ pub enum ExprKind {
/// Conditionless loop (can be exited with `break`, `continue`, or `return`). /// Conditionless loop (can be exited with `break`, `continue`, or `return`).
/// ///
/// `'label: loop { block }` /// `'label: loop { block }`
Loop(P<Block>, Option<Label>), Loop(P<Block>, Option<Label>, Span),
/// A `match` block. /// A `match` block.
Match(P<Expr>, Vec<Arm>), Match(P<Expr>, Vec<Arm>),
/// A closure (e.g., `move |a, b, c| a + b + c`). /// A closure (e.g., `move |a, b, c| a + b + c`).
/// Closure(Box<Closure>),
/// The final span is the span of the argument block `|...|`.
Closure(ClosureBinder, CaptureBy, Async, Movability, P<FnDecl>, P<Expr>, Span),
/// A block (`'label: { ... }`). /// A block (`'label: { ... }`).
Block(P<Block>, Option<Label>), Block(P<Block>, Option<Label>),
/// An async block (`async move { ... }`). /// An async block (`async move { ... }`).
@ -1405,7 +1452,7 @@ pub enum ExprKind {
/// parameters (e.g., `foo::bar::<baz>`). /// parameters (e.g., `foo::bar::<baz>`).
/// ///
/// Optionally "qualified" (e.g., `<Vec<T> as SomeTrait>::SomeType`). /// 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`). /// A referencing operation (`&a`, `&mut a`, `&raw const a` or `&raw mut a`).
AddrOf(BorrowKind, Mutability, P<Expr>), AddrOf(BorrowKind, Mutability, P<Expr>),
@ -1446,6 +1493,12 @@ pub enum ExprKind {
/// with an optional value to be returned. /// with an optional value to be returned.
Yeet(Option<P<Expr>>), 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. /// Placeholder for an expression that wasn't syntactically well formed in some way.
Err, Err,
} }
@ -1525,55 +1578,48 @@ pub enum ClosureBinder {
#[derive(Clone, Encodable, Decodable, Debug)] #[derive(Clone, Encodable, Decodable, Debug)]
pub struct MacCall { pub struct MacCall {
pub path: Path, pub path: Path,
pub args: P<MacArgs>, pub args: P<DelimArgs>,
pub prior_type_ascription: Option<(Span, bool)>, pub prior_type_ascription: Option<(Span, bool)>,
} }
impl MacCall { impl MacCall {
pub fn span(&self) -> Span { 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)] #[derive(Clone, Encodable, Decodable, Debug)]
pub enum MacArgs { pub enum AttrArgs {
/// No arguments - `#[attr]`. /// No arguments: `#[attr]`.
Empty, Empty,
/// Delimited arguments - `#[attr()/[]/{}]` or `mac!()/[]/{}`. /// Delimited arguments: `#[attr()/[]/{}]`.
Delimited(DelimSpan, MacDelimiter, TokenStream), Delimited(DelimArgs),
/// Arguments of a key-value attribute - `#[attr = "value"]`. /// Arguments of a key-value attribute: `#[attr = "value"]`.
Eq( Eq(
/// Span of the `=` token. /// Span of the `=` token.
Span, Span,
/// The "value". /// The "value".
MacArgsEq, AttrArgsEq,
), ),
} }
// The RHS of a `MacArgs::Eq` starts out as an expression. Once macro expansion // The RHS of an `AttrArgs::Eq` starts out as an expression. Once macro
// is completed, all cases end up either as a literal, which is the form used // expansion is completed, all cases end up either as a meta item literal,
// after lowering to HIR, or as an error. // which is the form used after lowering to HIR, or as an error.
#[derive(Clone, Encodable, Decodable, Debug)] #[derive(Clone, Encodable, Decodable, Debug)]
pub enum MacArgsEq { pub enum AttrArgsEq {
Ast(P<Expr>), Ast(P<Expr>),
Hir(Lit), Hir(MetaItemLit),
} }
impl MacArgs { impl AttrArgs {
pub fn delim(&self) -> Option<Delimiter> {
match self {
MacArgs::Delimited(_, delim, _) => Some(delim.to_token()),
MacArgs::Empty | MacArgs::Eq(..) => None,
}
}
pub fn span(&self) -> Option<Span> { pub fn span(&self) -> Option<Span> {
match self { match self {
MacArgs::Empty => None, AttrArgs::Empty => None,
MacArgs::Delimited(dspan, ..) => Some(dspan.entire()), AttrArgs::Delimited(args) => Some(args.dspan.entire()),
MacArgs::Eq(eq_span, MacArgsEq::Ast(expr)) => Some(eq_span.to(expr.span)), AttrArgs::Eq(eq_span, AttrArgsEq::Ast(expr)) => Some(eq_span.to(expr.span)),
MacArgs::Eq(_, MacArgsEq::Hir(lit)) => { AttrArgs::Eq(_, AttrArgsEq::Hir(lit)) => {
unreachable!("in literal form when getting span: {:?}", lit); unreachable!("in literal form when getting span: {:?}", lit);
} }
} }
@ -1583,39 +1629,29 @@ impl MacArgs {
/// Proc macros see these tokens, for example. /// Proc macros see these tokens, for example.
pub fn inner_tokens(&self) -> TokenStream { pub fn inner_tokens(&self) -> TokenStream {
match self { match self {
MacArgs::Empty => TokenStream::default(), AttrArgs::Empty => TokenStream::default(),
MacArgs::Delimited(.., tokens) => tokens.clone(), AttrArgs::Delimited(args) => args.tokens.clone(),
MacArgs::Eq(_, MacArgsEq::Ast(expr)) => TokenStream::from_ast(expr), AttrArgs::Eq(_, AttrArgsEq::Ast(expr)) => TokenStream::from_ast(expr),
MacArgs::Eq(_, MacArgsEq::Hir(lit)) => { AttrArgs::Eq(_, AttrArgsEq::Hir(lit)) => {
unreachable!("in literal form when getting inner tokens: {:?}", 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 where
CTX: crate::HashStableContext, CTX: crate::HashStableContext,
{ {
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
mem::discriminant(self).hash_stable(ctx, hasher); mem::discriminant(self).hash_stable(ctx, hasher);
match self { match self {
MacArgs::Empty => {} AttrArgs::Empty => {}
MacArgs::Delimited(dspan, delim, tokens) => { AttrArgs::Delimited(args) => args.hash_stable(ctx, hasher),
dspan.hash_stable(ctx, hasher); AttrArgs::Eq(_eq_span, AttrArgsEq::Ast(expr)) => {
delim.hash_stable(ctx, hasher);
tokens.hash_stable(ctx, hasher);
}
MacArgs::Eq(_eq_span, MacArgsEq::Ast(expr)) => {
unreachable!("hash_stable {:?}", 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); eq_span.hash_stable(ctx, hasher);
lit.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)] #[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)]
pub enum MacDelimiter { pub enum MacDelimiter {
Parenthesis, Parenthesis,
@ -1652,7 +1716,7 @@ impl MacDelimiter {
/// Represents a macro definition. /// Represents a macro definition.
#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)] #[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
pub struct MacroDef { pub struct MacroDef {
pub body: P<MacArgs>, pub body: P<DelimArgs>,
/// `true` if macro was defined with `macro_rules`. /// `true` if macro was defined with `macro_rules`.
pub macro_rules: bool, pub macro_rules: bool,
} }
@ -1668,19 +1732,18 @@ pub enum StrStyle {
Raw(u8), Raw(u8),
} }
/// An AST literal. /// A literal in a meta item.
#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)] #[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
pub struct Lit { pub struct MetaItemLit {
/// The original literal token as written in source code. /// The original literal token as written in source code.
pub token_lit: token::Lit, pub token_lit: token::Lit,
/// The "semantic" representation of the literal lowered from the original tokens. /// The "semantic" representation of the literal lowered from the original tokens.
/// Strings are unescaped, hexadecimal forms are eliminated, etc. /// 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 kind: LitKind,
pub span: Span, 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)] #[derive(Clone, Copy, Encodable, Decodable, Debug)]
pub struct StrLit { pub struct StrLit {
/// The original literal token as written in source code. /// The original literal token as written in source code.
@ -1689,21 +1752,16 @@ pub struct StrLit {
pub suffix: Option<Symbol>, pub suffix: Option<Symbol>,
pub span: Span, pub span: Span,
/// The unescaped "semantic" representation of the literal lowered from the original token. /// 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, pub symbol_unescaped: Symbol,
} }
impl StrLit { impl StrLit {
pub fn as_lit(&self) -> Lit { pub fn as_token_lit(&self) -> token::Lit {
let token_kind = match self.style { let token_kind = match self.style {
StrStyle::Cooked => token::Str, StrStyle::Cooked => token::Str,
StrStyle::Raw(n) => token::StrRaw(n), StrStyle::Raw(n) => token::StrRaw(n),
}; };
Lit { token::Lit::new(token_kind, self.symbol, self.suffix)
token_lit: token::Lit::new(token_kind, self.symbol, self.suffix),
span: self.span,
kind: LitKind::Str(self.symbol_unescaped, self.style),
}
} }
} }
@ -1729,9 +1787,12 @@ pub enum LitFloatType {
Unsuffixed, 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)] #[derive(Clone, Encodable, Decodable, Debug, Hash, Eq, PartialEq, HashStable_Generic)]
pub enum LitKind { pub enum LitKind {
/// A string literal (`"foo"`). The symbol is unescaped, and so may differ /// A string literal (`"foo"`). The symbol is unescaped, and so may differ
@ -1745,10 +1806,11 @@ pub enum LitKind {
Char(char), Char(char),
/// An integer literal (`1`). /// An integer literal (`1`).
Int(u128, LitIntType), Int(u128, LitIntType),
/// A float literal (`1f64` or `1E10f64`). Stored as a symbol rather than /// A float literal (`1.0`, `1f64` or `1E10f64`). The pre-suffix part is
/// `f64` so that `LitKind` can impl `Eq` and `Hash`. /// stored as a symbol rather than `f64` so that `LitKind` can impl `Eq`
/// and `Hash`.
Float(Symbol, LitFloatType), Float(Symbol, LitFloatType),
/// A boolean literal. /// A boolean literal (`true`, `false`).
Bool(bool), Bool(bool),
/// Placeholder for a literal that wasn't well-formed in some way. /// Placeholder for a literal that wasn't well-formed in some way.
Err, Err,
@ -1967,7 +2029,7 @@ impl Ty {
pub fn peel_refs(&self) -> &Self { pub fn peel_refs(&self) -> &Self {
let mut final_ty = self; let mut final_ty = self;
while let TyKind::Rptr(_, MutTy { ty, .. }) = &final_ty.kind { while let TyKind::Rptr(_, MutTy { ty, .. }) = &final_ty.kind {
final_ty = &ty; final_ty = ty;
} }
final_ty final_ty
} }
@ -2004,7 +2066,7 @@ pub enum TyKind {
/// "qualified", e.g., `<Vec<T> as SomeTrait>::SomeType`. /// "qualified", e.g., `<Vec<T> as SomeTrait>::SomeType`.
/// ///
/// Type parameters are stored in the `Path` itself. /// Type parameters are stored in the `Path` itself.
Path(Option<QSelf>, Path), Path(Option<P<QSelf>>, Path),
/// A trait object type `Bound1 + Bound2 + Bound3` /// A trait object type `Bound1 + Bound2 + Bound3`
/// where `Bound` is a trait or a lifetime. /// where `Bound` is a trait or a lifetime.
TraitObject(GenericBounds, TraitObjectSyntax), TraitObject(GenericBounds, TraitObjectSyntax),
@ -2136,7 +2198,7 @@ impl InlineAsmTemplatePiece {
#[derive(Clone, Encodable, Decodable, Debug)] #[derive(Clone, Encodable, Decodable, Debug)]
pub struct InlineAsmSym { pub struct InlineAsmSym {
pub id: NodeId, pub id: NodeId,
pub qself: Option<QSelf>, pub qself: Option<P<QSelf>>,
pub path: Path, pub path: Path,
} }
@ -2376,9 +2438,9 @@ pub enum FnRetTy {
impl FnRetTy { impl FnRetTy {
pub fn span(&self) -> Span { pub fn span(&self) -> Span {
match *self { match self {
FnRetTy::Default(span) => span, &FnRetTy::Default(span) => span,
FnRetTy::Ty(ref ty) => ty.span, FnRetTy::Ty(ty) => ty.span,
} }
} }
} }
@ -2457,10 +2519,7 @@ pub struct Variant {
#[derive(Clone, Encodable, Decodable, Debug)] #[derive(Clone, Encodable, Decodable, Debug)]
pub enum UseTreeKind { pub enum UseTreeKind {
/// `use prefix` or `use prefix as rename` /// `use prefix` or `use prefix as rename`
/// Simple(Option<Ident>),
/// The extra `NodeId`s are for HIR lowering, when additional statements are created for each
/// namespace.
Simple(Option<Ident>, NodeId, NodeId),
/// `use prefix::{...}` /// `use prefix::{...}`
Nested(Vec<(UseTree, NodeId)>), Nested(Vec<(UseTree, NodeId)>),
/// `use prefix::*` /// `use prefix::*`
@ -2479,8 +2538,8 @@ pub struct UseTree {
impl UseTree { impl UseTree {
pub fn ident(&self) -> Ident { pub fn ident(&self) -> Ident {
match self.kind { match self.kind {
UseTreeKind::Simple(Some(rename), ..) => rename, UseTreeKind::Simple(Some(rename)) => rename,
UseTreeKind::Simple(None, ..) => { UseTreeKind::Simple(None) => {
self.prefix.segments.last().expect("empty prefix in a simple import").ident self.prefix.segments.last().expect("empty prefix in a simple import").ident
} }
_ => panic!("`UseTree::ident` can only be used on a simple import"), _ => 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. /// A list of attributes.
pub type AttrVec = ThinVec<Attribute>; pub type AttrVec = ThinVec<Attribute>;
/// Metadata associated with an item. /// A syntax-level representation of an attribute.
#[derive(Clone, Encodable, Decodable, Debug)] #[derive(Clone, Encodable, Decodable, Debug)]
pub struct Attribute { pub struct Attribute {
pub kind: AttrKind, pub kind: AttrKind,
@ -2535,12 +2587,6 @@ pub struct Attribute {
pub span: Span, pub span: Span,
} }
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct NormalAttr {
pub item: AttrItem,
pub tokens: Option<LazyAttrTokenStream>,
}
#[derive(Clone, Encodable, Decodable, Debug)] #[derive(Clone, Encodable, Decodable, Debug)]
pub enum AttrKind { pub enum AttrKind {
/// A normal attribute. /// A normal attribute.
@ -2552,6 +2598,19 @@ pub enum AttrKind {
DocComment(CommentKind, Symbol), 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. /// `TraitRef`s appear in impls.
/// ///
/// Resolution maps each `TraitRef`'s `ref_id` to its defining trait; that's all /// Resolution maps each `TraitRef`'s `ref_id` to its defining trait; that's all
@ -2640,14 +2699,14 @@ pub enum VariantData {
impl VariantData { impl VariantData {
/// Return the fields of this variant. /// Return the fields of this variant.
pub fn fields(&self) -> &[FieldDef] { pub fn fields(&self) -> &[FieldDef] {
match *self { match self {
VariantData::Struct(ref fields, ..) | VariantData::Tuple(ref fields, _) => fields, VariantData::Struct(fields, ..) | VariantData::Tuple(fields, _) => fields,
_ => &[], _ => &[],
} }
} }
/// Return the `NodeId` of this variant's constructor, if it has one. /// 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 { match *self {
VariantData::Struct(..) => None, VariantData::Struct(..) => None,
VariantData::Tuple(_, id) | VariantData::Unit(id) => Some(id), VariantData::Tuple(_, id) | VariantData::Unit(id) => Some(id),
@ -3029,28 +3088,28 @@ mod size_asserts {
static_assert_size!(AssocItemKind, 32); static_assert_size!(AssocItemKind, 32);
static_assert_size!(Attribute, 32); static_assert_size!(Attribute, 32);
static_assert_size!(Block, 48); static_assert_size!(Block, 48);
static_assert_size!(Expr, 104); static_assert_size!(Expr, 72);
static_assert_size!(ExprKind, 72); static_assert_size!(ExprKind, 40);
static_assert_size!(Fn, 184); static_assert_size!(Fn, 184);
static_assert_size!(ForeignItem, 96); static_assert_size!(ForeignItem, 96);
static_assert_size!(ForeignItemKind, 24); static_assert_size!(ForeignItemKind, 24);
static_assert_size!(GenericArg, 24); static_assert_size!(GenericArg, 24);
static_assert_size!(GenericBound, 88); static_assert_size!(GenericBound, 72);
static_assert_size!(Generics, 72); static_assert_size!(Generics, 72);
static_assert_size!(Impl, 200); static_assert_size!(Impl, 184);
static_assert_size!(Item, 184); static_assert_size!(Item, 184);
static_assert_size!(ItemKind, 112); static_assert_size!(ItemKind, 112);
static_assert_size!(Lit, 48);
static_assert_size!(LitKind, 24); static_assert_size!(LitKind, 24);
static_assert_size!(Local, 72); static_assert_size!(Local, 72);
static_assert_size!(MetaItemLit, 48);
static_assert_size!(Param, 40); static_assert_size!(Param, 40);
static_assert_size!(Pat, 120); static_assert_size!(Pat, 88);
static_assert_size!(Path, 40); static_assert_size!(Path, 24);
static_assert_size!(PathSegment, 24); static_assert_size!(PathSegment, 24);
static_assert_size!(PatKind, 96); static_assert_size!(PatKind, 64);
static_assert_size!(Stmt, 32); static_assert_size!(Stmt, 32);
static_assert_size!(StmtKind, 16); static_assert_size!(StmtKind, 16);
static_assert_size!(Ty, 96); static_assert_size!(Ty, 64);
static_assert_size!(TyKind, 72); static_assert_size!(TyKind, 40);
// tidy-alphabetical-end // tidy-alphabetical-end
} }

View File

@ -1,35 +1,33 @@
//! Functions dealing with attributes and meta items. //! Functions dealing with attributes and meta items.
use crate::ast; use crate::ast;
use crate::ast::{AttrId, AttrItem, AttrKind, AttrStyle, Attribute}; use crate::ast::{AttrArgs, AttrArgsEq, AttrId, AttrItem, AttrKind, AttrStyle, AttrVec, Attribute};
use crate::ast::{Lit, LitKind}; use crate::ast::{DelimArgs, Expr, ExprKind, LitKind, MetaItemLit};
use crate::ast::{MacArgs, MacArgsEq, MacDelimiter, MetaItem, MetaItemKind, NestedMetaItem}; use crate::ast::{MacDelimiter, MetaItem, MetaItemKind, NestedMetaItem, NormalAttr};
use crate::ast::{Path, PathSegment}; use crate::ast::{Path, PathSegment, StrStyle, DUMMY_NODE_ID};
use crate::ptr::P; use crate::ptr::P;
use crate::token::{self, CommentKind, Delimiter, Token}; use crate::token::{self, CommentKind, Delimiter, Token};
use crate::tokenstream::{DelimSpan, Spacing, TokenTree}; use crate::tokenstream::{DelimSpan, Spacing, TokenTree};
use crate::tokenstream::{LazyAttrTokenStream, TokenStream}; use crate::tokenstream::{LazyAttrTokenStream, TokenStream};
use crate::util::comments; use crate::util::comments;
use rustc_data_structures::sync::WorkerLocal; use rustc_data_structures::sync::WorkerLocal;
use rustc_index::bit_set::GrowableBitSet; use rustc_index::bit_set::GrowableBitSet;
use rustc_span::source_map::BytePos;
use rustc_span::symbol::{sym, Ident, Symbol}; use rustc_span::symbol::{sym, Ident, Symbol};
use rustc_span::Span; use rustc_span::Span;
use std::cell::Cell; use std::cell::Cell;
use std::iter; use std::iter;
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
use std::ops::BitXor; use std::ops::BitXor;
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
use std::sync::atomic::{AtomicU32, Ordering}; use std::sync::atomic::{AtomicU32, Ordering};
use thin_vec::thin_vec;
pub struct MarkedAttrs(GrowableBitSet<AttrId>); pub struct MarkedAttrs(GrowableBitSet<AttrId>);
impl MarkedAttrs { 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 { 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()) MarkedAttrs(GrowableBitSet::new_empty())
} }
@ -45,16 +43,16 @@ impl MarkedAttrs {
impl NestedMetaItem { impl NestedMetaItem {
/// Returns the `MetaItem` if `self` is a `NestedMetaItem::MetaItem`. /// Returns the `MetaItem` if `self` is a `NestedMetaItem::MetaItem`.
pub fn meta_item(&self) -> Option<&MetaItem> { pub fn meta_item(&self) -> Option<&MetaItem> {
match *self { match self {
NestedMetaItem::MetaItem(ref item) => Some(item), NestedMetaItem::MetaItem(item) => Some(item),
_ => None, _ => None,
} }
} }
/// Returns the `Lit` if `self` is a `NestedMetaItem::Literal`s. /// Returns the `MetaItemLit` if `self` is a `NestedMetaItem::Literal`s.
pub fn literal(&self) -> Option<&Lit> { pub fn lit(&self) -> Option<&MetaItemLit> {
match *self { match self {
NestedMetaItem::Literal(ref lit) => Some(lit), NestedMetaItem::Lit(lit) => Some(lit),
_ => None, _ => None,
} }
} }
@ -79,12 +77,12 @@ impl NestedMetaItem {
} }
/// Returns a name and single literal value tuple of the `MetaItem`. /// 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| { self.meta_item().and_then(|meta_item| {
meta_item.meta_item_list().and_then(|meta_item_list| { meta_item.meta_item_list().and_then(|meta_item_list| {
if meta_item_list.len() == 1 if meta_item_list.len() == 1
&& let Some(ident) = meta_item.ident() && 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)); return Some((ident.name, lit));
} }
@ -117,18 +115,18 @@ impl NestedMetaItem {
impl Attribute { impl Attribute {
#[inline] #[inline]
pub fn has_name(&self, name: Symbol) -> bool { pub fn has_name(&self, name: Symbol) -> bool {
match self.kind { match &self.kind {
AttrKind::Normal(ref normal) => normal.item.path == name, AttrKind::Normal(normal) => normal.item.path == name,
AttrKind::DocComment(..) => false, AttrKind::DocComment(..) => false,
} }
} }
/// For a single-segment attribute, returns its name; otherwise, returns `None`. /// For a single-segment attribute, returns its name; otherwise, returns `None`.
pub fn ident(&self) -> Option<Ident> { pub fn ident(&self) -> Option<Ident> {
match self.kind { match &self.kind {
AttrKind::Normal(ref normal) => { AttrKind::Normal(normal) => {
if normal.item.path.segments.len() == 1 { if let [ident] = &*normal.item.path.segments {
Some(normal.item.path.segments[0].ident) Some(ident.ident)
} else { } else {
None None
} }
@ -141,17 +139,15 @@ impl Attribute {
} }
pub fn value_str(&self) -> Option<Symbol> { pub fn value_str(&self) -> Option<Symbol> {
match self.kind { match &self.kind {
AttrKind::Normal(ref normal) => { AttrKind::Normal(normal) => normal.item.meta_kind().and_then(|kind| kind.value_str()),
normal.item.meta_kind().and_then(|kind| kind.value_str())
}
AttrKind::DocComment(..) => None, AttrKind::DocComment(..) => None,
} }
} }
pub fn meta_item_list(&self) -> Option<Vec<NestedMetaItem>> { pub fn meta_item_list(&self) -> Option<Vec<NestedMetaItem>> {
match self.kind { match &self.kind {
AttrKind::Normal(ref normal) => match normal.item.meta_kind() { AttrKind::Normal(normal) => match normal.item.meta_kind() {
Some(MetaItemKind::List(list)) => Some(list), Some(MetaItemKind::List(list)) => Some(list),
_ => None, _ => None,
}, },
@ -161,7 +157,7 @@ impl Attribute {
pub fn is_word(&self) -> bool { pub fn is_word(&self) -> bool {
if let AttrKind::Normal(normal) = &self.kind { if let AttrKind::Normal(normal) = &self.kind {
matches!(normal.item.args, MacArgs::Empty) matches!(normal.item.args, AttrArgs::Empty)
} else { } else {
false false
} }
@ -177,10 +173,12 @@ impl MetaItem {
self.ident().unwrap_or_else(Ident::empty).name self.ident().unwrap_or_else(Ident::empty).name
} }
// Example: /// ```text
// #[attribute(name = "value")] /// Example:
// ^^^^^^^^^^^^^^ /// #[attribute(name = "value")]
pub fn name_value_literal(&self) -> Option<&Lit> { /// ^^^^^^^^^^^^^^
/// ```
pub fn name_value_literal(&self) -> Option<&MetaItemLit> {
match &self.kind { match &self.kind {
MetaItemKind::NameValue(v) => Some(v), MetaItemKind::NameValue(v) => Some(v),
_ => None, _ => None,
@ -192,8 +190,8 @@ impl MetaItem {
} }
pub fn meta_item_list(&self) -> Option<&[NestedMetaItem]> { pub fn meta_item_list(&self) -> Option<&[NestedMetaItem]> {
match self.kind { match &self.kind {
MetaItemKind::List(ref l) => Some(&l[..]), MetaItemKind::List(l) => Some(&**l),
_ => None, _ => None,
} }
} }
@ -224,15 +222,11 @@ impl AttrItem {
} }
pub fn meta(&self, span: Span) -> Option<MetaItem> { pub fn meta(&self, span: Span) -> Option<MetaItem> {
Some(MetaItem { Some(MetaItem { path: self.path.clone(), kind: self.meta_kind()?, span })
path: self.path.clone(),
kind: MetaItemKind::from_mac_args(&self.args)?,
span,
})
} }
pub fn meta_kind(&self) -> Option<MetaItemKind> { 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 = "doc"]` returns `Some("doc")`.
/// * `#[doc(...)]` returns `None`. /// * `#[doc(...)]` returns `None`.
pub fn doc_str(&self) -> Option<Symbol> { pub fn doc_str(&self) -> Option<Symbol> {
match self.kind { match &self.kind {
AttrKind::DocComment(.., data) => Some(data), AttrKind::DocComment(.., data) => Some(*data),
AttrKind::Normal(ref normal) if normal.item.path == sym::doc => { AttrKind::Normal(normal) if normal.item.path == sym::doc => {
normal.item.meta_kind().and_then(|kind| kind.value_str()) normal.item.meta_kind().and_then(|kind| kind.value_str())
} }
_ => None, _ => None,
@ -283,8 +277,8 @@ impl Attribute {
} }
pub fn get_normal_item(&self) -> &AttrItem { pub fn get_normal_item(&self) -> &AttrItem {
match self.kind { match &self.kind {
AttrKind::Normal(ref normal) => &normal.item, AttrKind::Normal(normal) => &normal.item,
AttrKind::DocComment(..) => panic!("unexpected doc comment"), AttrKind::DocComment(..) => panic!("unexpected doc comment"),
} }
} }
@ -298,28 +292,28 @@ impl Attribute {
/// Extracts the MetaItem from inside this Attribute. /// Extracts the MetaItem from inside this Attribute.
pub fn meta(&self) -> Option<MetaItem> { pub fn meta(&self) -> Option<MetaItem> {
match self.kind { match &self.kind {
AttrKind::Normal(ref normal) => normal.item.meta(self.span), AttrKind::Normal(normal) => normal.item.meta(self.span),
AttrKind::DocComment(..) => None, AttrKind::DocComment(..) => None,
} }
} }
pub fn meta_kind(&self) -> Option<MetaItemKind> { pub fn meta_kind(&self) -> Option<MetaItemKind> {
match self.kind { match &self.kind {
AttrKind::Normal(ref normal) => normal.item.meta_kind(), AttrKind::Normal(normal) => normal.item.meta_kind(),
AttrKind::DocComment(..) => None, AttrKind::DocComment(..) => None,
} }
} }
pub fn tokens(&self) -> TokenStream { pub fn tokens(&self) -> TokenStream {
match self.kind { match &self.kind {
AttrKind::Normal(ref normal) => normal AttrKind::Normal(normal) => normal
.tokens .tokens
.as_ref() .as_ref()
.unwrap_or_else(|| panic!("attribute is missing tokens: {:?}", self)) .unwrap_or_else(|| panic!("attribute is missing tokens: {:?}", self))
.to_attr_token_stream() .to_attr_token_stream()
.to_tokenstream(), .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), Token::new(token::DocComment(comment_kind, self.style, data), self.span),
Spacing::Alone, Spacing::Alone,
)]), )]),
@ -330,26 +324,13 @@ impl Attribute {
/* Constructors */ /* Constructors */
pub fn mk_name_value_item_str(ident: Ident, str: Symbol, str_span: Span) -> MetaItem { 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, LitKind::Str(str, ast::StrStyle::Cooked), str_span)
mk_name_value_item(ident, lit_kind, str_span)
} }
pub fn mk_name_value_item(ident: Ident, lit_kind: LitKind, lit_span: Span) -> MetaItem { pub fn mk_name_value_item(ident: Ident, kind: LitKind, lit_span: Span) -> MetaItem {
let lit = Lit::from_lit_kind(lit_kind, lit_span); let lit = MetaItemLit { token_lit: kind.to_token_lit(), kind, span: lit_span };
let span = ident.span.to(lit_span); let span = ident.span.to(lit_span);
MetaItem { path: Path::from_ident(ident), span, kind: MetaItemKind::NameValue(lit) } MetaItem { path: Path::from_ident(ident), kind: MetaItemKind::NameValue(lit), span }
}
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))
} }
pub struct AttrIdGenerator(WorkerLocal<Cell<u32>>); pub struct AttrIdGenerator(WorkerLocal<Cell<u32>>);
@ -393,7 +374,7 @@ pub fn mk_attr(
g: &AttrIdGenerator, g: &AttrIdGenerator,
style: AttrStyle, style: AttrStyle,
path: Path, path: Path,
args: MacArgs, args: AttrArgs,
span: Span, span: Span,
) -> Attribute { ) -> Attribute {
mk_attr_from_item(g, AttrItem { path, args, tokens: None }, None, style, span) 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, span: Span,
) -> Attribute { ) -> Attribute {
Attribute { Attribute {
kind: AttrKind::Normal(P(ast::NormalAttr { item, tokens })), kind: AttrKind::Normal(P(NormalAttr { item, tokens })),
id: g.mk_attr_id(), id: g.mk_attr_id(),
style, style,
span, span,
} }
} }
/// Returns an inner attribute with the given value and span. pub fn mk_attr_word(g: &AttrIdGenerator, style: AttrStyle, name: Symbol, span: Span) -> Attribute {
pub fn mk_attr_inner(g: &AttrIdGenerator, item: MetaItem) -> Attribute { let path = Path::from_ident(Ident::new(name, span));
mk_attr(g, AttrStyle::Inner, item.path, item.kind.mac_args(item.span), item.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_name_value_str(
pub fn mk_attr_outer(g: &AttrIdGenerator, item: MetaItem) -> Attribute { g: &AttrIdGenerator,
mk_attr(g, AttrStyle::Outer, item.path, item.kind.mac_args(item.span), item.span) 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( pub fn mk_doc_comment(
@ -439,23 +457,6 @@ pub fn list_contains_name(items: &[NestedMetaItem], name: Symbol) -> bool {
} }
impl MetaItem { 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> fn from_tokens<I>(tokens: &mut iter::Peekable<I>) -> Option<MetaItem>
where where
I: Iterator<Item = TokenTree>, I: Iterator<Item = TokenTree>,
@ -471,12 +472,12 @@ impl MetaItem {
tokens.peek() tokens.peek()
{ {
tokens.next(); tokens.next();
vec![PathSegment::from_ident(Ident::new(name, span))] thin_vec![PathSegment::from_ident(Ident::new(name, span))]
} else { } else {
break 'arm Path::from_ident(Ident::new(name, span)); break 'arm Path::from_ident(Ident::new(name, span));
} }
} else { } else {
vec![PathSegment::path_root(span)] thin_vec![PathSegment::path_root(span)]
}; };
loop { loop {
if let Some(TokenTree::Token(Token { kind: token::Ident(name, _), span }, _)) = 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()); let span = span.with_hi(segments.last().unwrap().ident.span.hi());
Path { span, segments, tokens: None } Path { span, segments, tokens: None }
} }
Some(TokenTree::Token(Token { kind: token::Interpolated(nt), .. }, _)) => match *nt { Some(TokenTree::Token(Token { kind: token::Interpolated(nt), .. }, _)) => match &*nt {
token::Nonterminal::NtMeta(ref item) => return item.meta(item.path.span), token::Nonterminal::NtMeta(item) => return item.meta(item.path.span),
token::Nonterminal::NtPath(ref path) => (**path).clone(), token::Nonterminal::NtPath(path) => (**path).clone(),
_ => return None, _ => return None,
}, },
_ => return None, _ => return None,
}; };
let list_closing_paren_pos = tokens.peek().map(|tt| tt.span().hi()); let list_closing_paren_pos = tokens.peek().map(|tt| tt.span().hi());
let kind = MetaItemKind::from_tokens(tokens)?; let kind = MetaItemKind::from_tokens(tokens)?;
let hi = match kind { let hi = match &kind {
MetaItemKind::NameValue(ref lit) => lit.span.hi(), MetaItemKind::NameValue(lit) => lit.span.hi(),
MetaItemKind::List(..) => list_closing_paren_pos.unwrap_or(path.span.hi()), MetaItemKind::List(..) => list_closing_paren_pos.unwrap_or(path.span.hi()),
_ => path.span.hi(), _ => path.span.hi(),
}; };
@ -519,70 +520,14 @@ impl MetaItem {
impl MetaItemKind { impl MetaItemKind {
pub fn value_str(&self) -> Option<Symbol> { pub fn value_str(&self) -> Option<Symbol> {
match self { match self {
MetaItemKind::NameValue(ref v) => match v.kind { MetaItemKind::NameValue(v) => match v.kind {
LitKind::Str(ref s, _) => Some(*s), LitKind::Str(s, _) => Some(s),
_ => None, _ => None,
}, },
_ => 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> { fn list_from_tokens(tokens: TokenStream) -> Option<MetaItemKind> {
let mut tokens = tokens.into_trees().peekable(); let mut tokens = tokens.into_trees().peekable();
let mut result = Vec::new(); let mut result = Vec::new();
@ -605,24 +550,31 @@ impl MetaItemKind {
MetaItemKind::name_value_from_tokens(&mut inner_tokens.into_trees()) MetaItemKind::name_value_from_tokens(&mut inner_tokens.into_trees())
} }
Some(TokenTree::Token(token, _)) => { Some(TokenTree::Token(token, _)) => {
Lit::from_token(&token).ok().map(MetaItemKind::NameValue) MetaItemLit::from_token(&token).map(MetaItemKind::NameValue)
} }
_ => None, _ => None,
} }
} }
fn from_mac_args(args: &MacArgs) -> Option<MetaItemKind> { fn from_attr_args(args: &AttrArgs) -> Option<MetaItemKind> {
match args { match args {
MacArgs::Empty => Some(MetaItemKind::Word), AttrArgs::Empty => Some(MetaItemKind::Word),
MacArgs::Delimited(_, MacDelimiter::Parenthesis, tokens) => { AttrArgs::Delimited(DelimArgs {
MetaItemKind::list_from_tokens(tokens.clone()) dspan: _,
} delim: MacDelimiter::Parenthesis,
MacArgs::Delimited(..) => None, tokens,
MacArgs::Eq(_, MacArgsEq::Ast(expr)) => match &expr.kind { }) => MetaItemKind::list_from_tokens(tokens.clone()),
ast::ExprKind::Lit(lit) => Some(MetaItemKind::NameValue(lit.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, _ => 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 { impl NestedMetaItem {
pub fn span(&self) -> Span { pub fn span(&self) -> Span {
match *self { match self {
NestedMetaItem::MetaItem(ref item) => item.span, NestedMetaItem::MetaItem(item) => item.span,
NestedMetaItem::Literal(ref lit) => lit.span, NestedMetaItem::Lit(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)]
}
} }
} }
@ -668,10 +611,10 @@ impl NestedMetaItem {
{ {
match tokens.peek() { match tokens.peek() {
Some(TokenTree::Token(token, _)) Some(TokenTree::Token(token, _))
if let Ok(lit) = Lit::from_token(token) => if let Some(lit) = MetaItemLit::from_token(token) =>
{ {
tokens.next(); tokens.next();
return Some(NestedMetaItem::Literal(lit)); return Some(NestedMetaItem::Lit(lit));
} }
Some(TokenTree::Delimited(_, Delimiter::Invisible, inner_tokens)) => { Some(TokenTree::Delimited(_, Delimiter::Invisible, inner_tokens)) => {
let inner_tokens = inner_tokens.clone(); let inner_tokens = inner_tokens.clone();

View File

@ -29,6 +29,7 @@ extern crate rustc_macros;
extern crate tracing; extern crate tracing;
pub mod util { pub mod util {
pub mod case;
pub mod classify; pub mod classify;
pub mod comments; pub mod comments;
pub mod literal; pub mod literal;

View File

@ -194,7 +194,7 @@ pub trait MutVisitor: Sized {
noop_visit_path(p, self); 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); 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`. // 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 { match args {
MacArgs::Empty => {} AttrArgs::Empty => {}
MacArgs::Delimited(dspan, _delim, tokens) => { AttrArgs::Delimited(args) => visit_delim_args(args, vis),
visit_delim_span(dspan, vis); AttrArgs::Eq(eq_span, AttrArgsEq::Ast(expr)) => {
visit_tts(tokens, vis);
}
MacArgs::Eq(eq_span, MacArgsEq::Ast(expr)) => {
vis.visit_span(eq_span); vis.visit_span(eq_span);
vis.visit_expr(expr); vis.visit_expr(expr);
} }
MacArgs::Eq(_, MacArgsEq::Hir(lit)) => { AttrArgs::Eq(_, AttrArgsEq::Hir(lit)) => {
unreachable!("in literal form when visiting mac args eq: {:?}", 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) { pub fn visit_delim_span<T: MutVisitor>(dspan: &mut DelimSpan, vis: &mut T) {
vis.visit_span(&mut dspan.open); vis.visit_span(&mut dspan.open);
vis.visit_span(&mut dspan.close); 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; let UseTree { prefix, kind, span } = use_tree;
vis.visit_path(prefix); vis.visit_path(prefix);
match kind { match kind {
UseTreeKind::Simple(rename, id1, id2) => { UseTreeKind::Simple(rename) => visit_opt(rename, |rename| vis.visit_ident(rename)),
visit_opt(rename, |rename| vis.visit_ident(rename));
vis.visit_id(id1);
vis.visit_id(id2);
}
UseTreeKind::Nested(items) => { UseTreeKind::Nested(items) => {
for (tree, id) in items { for (tree, id) in items {
vis.visit_use_tree(tree); vis.visit_use_tree(tree);
@ -439,15 +439,15 @@ pub fn noop_visit_constraint<T: MutVisitor>(
) { ) {
vis.visit_id(id); vis.visit_id(id);
vis.visit_ident(ident); 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); vis.visit_generic_args(gen_args);
} }
match kind { match kind {
AssocConstraintKind::Equality { ref mut term } => match term { AssocConstraintKind::Equality { term } => match term {
Term::Ty(ty) => vis.visit_ty(ty), Term::Ty(ty) => vis.visit_ty(ty),
Term::Const(c) => vis.visit_anon_const(c), 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); 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); visit_lazy_tts(tokens, vis);
} }
pub fn noop_visit_qself<T: MutVisitor>(qself: &mut Option<QSelf>, vis: &mut T) { pub fn noop_visit_qself<T: MutVisitor>(qself: &mut Option<P<QSelf>>, vis: &mut T) {
visit_opt(qself, |QSelf { ty, path_span, position: _ }| { visit_opt(qself, |qself| {
let QSelf { ty, path_span, position: _ } = &mut **qself;
vis.visit_ty(ty); vis.visit_ty(ty);
vis.visit_span(path_span); 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 } = let NormalAttr { item: AttrItem { path, args, tokens }, tokens: attr_tokens } =
&mut **normal; &mut **normal;
vis.visit_path(path); vis.visit_path(path);
visit_mac_args(args, vis); visit_attr_args(args, vis);
visit_lazy_tts(tokens, vis); visit_lazy_tts(tokens, vis);
visit_lazy_tts(attr_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) { pub fn noop_visit_mac<T: MutVisitor>(mac: &mut MacCall, vis: &mut T) {
let MacCall { path, args, prior_type_ascription: _ } = mac; let MacCall { path, args, prior_type_ascription: _ } = mac;
vis.visit_path(path); 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) { pub fn noop_visit_macro_def<T: MutVisitor>(macro_def: &mut MacroDef, vis: &mut T) {
let MacroDef { body, macro_rules: _ } = macro_def; 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) { pub fn noop_visit_meta_list_item<T: MutVisitor>(li: &mut NestedMetaItem, vis: &mut T) {
match li { match li {
NestedMetaItem::MetaItem(mi) => vis.visit_meta_item(mi), 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); 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`. // 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) { pub fn visit_token<T: MutVisitor>(t: &mut Token, vis: &mut T) {
let Token { kind, span } = t; let Token { kind, span } = t;
match kind { 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. return; // Avoid visiting the span for the second time.
} }
token::Interpolated(nt) => { token::Interpolated(nt) => {
let mut nt = Lrc::make_mut(nt); visit_nonterminal(Lrc::make_mut(nt), vis);
visit_nonterminal(&mut nt, vis);
} }
_ => {} _ => {}
} }
@ -791,7 +791,7 @@ pub fn visit_nonterminal<T: MutVisitor>(nt: &mut token::Nonterminal, vis: &mut T
token::NtMeta(item) => { token::NtMeta(item) => {
let AttrItem { path, args, tokens } = item.deref_mut(); let AttrItem { path, args, tokens } = item.deref_mut();
vis.visit_path(path); vis.visit_path(path);
visit_mac_args(args, vis); visit_attr_args(args, vis);
visit_lazy_tts(tokens, vis); visit_lazy_tts(tokens, vis);
} }
token::NtPath(path) => vis.visit_path(path), 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; let GenericParam { id, ident, attrs, bounds, kind, colon_span, is_placeholder: _ } = &mut param;
vis.visit_id(id); vis.visit_id(id);
vis.visit_ident(ident); 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); vis.visit_span(colon_span);
} }
visit_attrs(attrs, vis); visit_attrs(attrs, vis);
@ -1303,12 +1303,17 @@ pub fn noop_visit_expr<T: MutVisitor>(
vis.visit_expr(f); vis.visit_expr(f);
visit_exprs(args, vis); 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_ident(ident);
vis.visit_id(id); 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); vis.visit_method_receiver_expr(receiver);
visit_exprs(exprs, vis); visit_exprs(call_args, vis);
vis.visit_span(span); vis.visit_span(span);
} }
ExprKind::Binary(_binop, lhs, rhs) => { ExprKind::Binary(_binop, lhs, rhs) => {
@ -1345,20 +1350,30 @@ pub fn noop_visit_expr<T: MutVisitor>(
vis.visit_block(body); vis.visit_block(body);
visit_opt(label, |label| vis.visit_label(label)); visit_opt(label, |label| vis.visit_label(label));
} }
ExprKind::Loop(body, label) => { ExprKind::Loop(body, label, span) => {
vis.visit_block(body); vis.visit_block(body);
visit_opt(label, |label| vis.visit_label(label)); visit_opt(label, |label| vis.visit_label(label));
vis.visit_span(span);
} }
ExprKind::Match(expr, arms) => { ExprKind::Match(expr, arms) => {
vis.visit_expr(expr); vis.visit_expr(expr);
arms.flat_map_in_place(|arm| vis.flat_map_arm(arm)); 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_closure_binder(binder);
vis.visit_asyncness(asyncness); vis.visit_asyncness(asyncness);
vis.visit_fn_decl(decl); vis.visit_fn_decl(fn_decl);
vis.visit_expr(body); vis.visit_expr(body);
vis.visit_span(span); vis.visit_span(fn_decl_span);
} }
ExprKind::Block(blk, label) => { ExprKind::Block(blk, label) => {
vis.visit_block(blk); vis.visit_block(blk);
@ -1428,7 +1443,7 @@ pub fn noop_visit_expr<T: MutVisitor>(
} }
ExprKind::Try(expr) => vis.visit_expr(expr), ExprKind::Try(expr) => vis.visit_expr(expr),
ExprKind::TryBlock(body) => vis.visit_block(body), ExprKind::TryBlock(body) => vis.visit_block(body),
ExprKind::Lit(_) | ExprKind::Err => {} ExprKind::Lit(_) | ExprKind::IncludedBytes(..) | ExprKind::Err => {}
} }
vis.visit_id(id); vis.visit_id(id);
vis.visit_span(span); vis.visit_span(span);

View File

@ -5,6 +5,7 @@ pub use TokenKind::*;
use crate::ast; use crate::ast;
use crate::ptr::P; use crate::ptr::P;
use crate::util::case::Case;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::sync::Lrc; use rustc_data_structures::sync::Lrc;
@ -58,13 +59,17 @@ pub enum Delimiter {
Invisible, 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)] #[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
pub enum LitKind { pub enum LitKind {
Bool, // AST only, must never appear in a `Token` Bool, // AST only, must never appear in a `Token`
Byte, Byte,
Char, Char,
Integer, Integer, // e.g. `1`, `1u8`, `1f32`
Float, Float, // e.g. `1.`, `1.0`, `1e3f32`
Str, Str,
StrRaw(u8), // raw string delimited by `n` hash symbols StrRaw(u8), // raw string delimited by `n` hash symbols
ByteStr, ByteStr,
@ -80,6 +85,42 @@ pub struct Lit {
pub suffix: Option<Symbol>, 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 { impl fmt::Display for Lit {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let Lit { kind, symbol, suffix } = *self; 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 { pub fn ident_can_begin_expr(name: Symbol, span: Span, is_raw: bool) -> bool {
let ident_token = Token::new(Ident(name, is_raw), span); let ident_token = Token::new(Ident(name, is_raw), span);
@ -267,9 +302,9 @@ impl TokenKind {
Literal(Lit::new(kind, symbol, suffix)) Literal(Lit::new(kind, symbol, suffix))
} }
// An approximation to proc-macro-style single-character operators used by rustc parser. /// 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, /// 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`. /// then this function performs that operation, otherwise it returns `None`.
pub fn break_two_token_op(&self) -> Option<(TokenKind, TokenKind)> { pub fn break_two_token_op(&self) -> Option<(TokenKind, TokenKind)> {
Some(match *self { Some(match *self {
Le => (Lt, Eq), Le => (Lt, Eq),
@ -503,10 +538,10 @@ impl Token {
} }
} }
// A convenience function for matching on identifiers during parsing. /// A convenience function for matching on identifiers during parsing.
// Turns interpolated identifier (`$i: ident`) or lifetime (`$l: lifetime`) token /// Turns interpolated identifier (`$i: ident`) or lifetime (`$l: lifetime`) token
// into the regular identifier or lifetime token it refers to, /// into the regular identifier or lifetime token it refers to,
// otherwise returns the original token. /// otherwise returns the original token.
pub fn uninterpolate(&self) -> Cow<'_, Token> { pub fn uninterpolate(&self) -> Cow<'_, Token> {
match &self.kind { match &self.kind {
Interpolated(nt) => match **nt { Interpolated(nt) => match **nt {
@ -566,9 +601,10 @@ impl Token {
/// Returns `true` if the token is an interpolated path. /// Returns `true` if the token is an interpolated path.
fn is_path(&self) -> bool { 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; return true;
} }
false false
} }
@ -576,7 +612,7 @@ impl Token {
/// That is, is this a pre-parsed expression dropped into the token stream /// That is, is this a pre-parsed expression dropped into the token stream
/// (which happens while parsing the result of macro expansion)? /// (which happens while parsing the result of macro expansion)?
pub fn is_whole_expr(&self) -> bool { 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 && let NtExpr(_) | NtLiteral(_) | NtPath(_) | NtBlock(_) = **nt
{ {
return true; return true;
@ -585,11 +621,12 @@ impl Token {
false false
} }
// Is the token an interpolated block (`$b:block`)? /// Is the token an interpolated block (`$b:block`)?
pub fn is_whole_block(&self) -> bool { 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; return true;
} }
false false
} }
@ -615,12 +652,21 @@ impl Token {
self.is_non_raw_ident_where(|id| id.name == kw) 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 { pub fn is_path_segment_keyword(&self) -> bool {
self.is_non_raw_ident_where(Ident::is_path_segment_keyword) self.is_non_raw_ident_where(Ident::is_path_segment_keyword)
} }
// Returns true for reserved identifiers used internally for elided lifetimes, /// Returns true for reserved identifiers used internally for elided lifetimes,
// unnamed method parameters, crate root module, error recovery etc. /// unnamed method parameters, crate root module, error recovery etc.
pub fn is_special_ident(&self) -> bool { pub fn is_special_ident(&self) -> bool {
self.is_non_raw_ident_where(Ident::is_special) self.is_non_raw_ident_where(Ident::is_special)
} }

View File

@ -64,7 +64,7 @@ impl TokenTree {
match (self, other) { match (self, other) {
(TokenTree::Token(token, _), TokenTree::Token(token2, _)) => token.kind == token2.kind, (TokenTree::Token(token, _), TokenTree::Token(token2, _)) => token.kind == token2.kind,
(TokenTree::Delimited(_, delim, tts), TokenTree::Delimited(_, delim2, tts2)) => { (TokenTree::Delimited(_, delim, tts), TokenTree::Delimited(_, delim2, tts2)) => {
delim == delim2 && tts.eq_unspanned(&tts2) delim == delim2 && tts.eq_unspanned(tts2)
} }
_ => false, _ => 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 { pub fn token_alone(kind: TokenKind, span: Span) -> TokenTree {
TokenTree::Token(Token::new(kind, span), Spacing::Alone) 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 { pub fn token_joint(kind: TokenKind, span: Span) -> TokenTree {
TokenTree::Token(Token::new(kind, span), Spacing::Joint) TokenTree::Token(Token::new(kind, span), Spacing::Joint)
} }
@ -402,7 +402,7 @@ impl TokenStream {
let mut t1 = self.trees(); let mut t1 = self.trees();
let mut t2 = other.trees(); let mut t2 = other.trees();
for (t1, t2) in iter::zip(&mut t1, &mut t2) { for (t1, t2) in iter::zip(&mut t1, &mut t2) {
if !t1.eq_unspanned(&t2) { if !t1.eq_unspanned(t2) {
return false; return false;
} }
} }
@ -413,17 +413,17 @@ impl TokenStream {
TokenStream(Lrc::new(self.0.iter().enumerate().map(|(i, tree)| f(i, tree)).collect())) 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 { pub fn token_alone(kind: TokenKind, span: Span) -> TokenStream {
TokenStream::new(vec![TokenTree::token_alone(kind, span)]) 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 { pub fn token_joint(kind: TokenKind, span: Span) -> TokenStream {
TokenStream::new(vec![TokenTree::token_joint(kind, span)]) 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 { pub fn delimited(span: DelimSpan, delim: Delimiter, tts: TokenStream) -> TokenStream {
TokenStream::new(vec![TokenTree::Delimited(span, delim, tts)]) TokenStream::new(vec![TokenTree::Delimited(span, delim, tts)])
} }
@ -475,7 +475,7 @@ impl TokenStream {
token::Interpolated(nt) => TokenTree::Delimited( token::Interpolated(nt) => TokenTree::Delimited(
DelimSpan::from_single(token.span), DelimSpan::from_single(token.span),
Delimiter::Invisible, Delimiter::Invisible,
TokenStream::from_nonterminal_ast(&nt).flattened(), TokenStream::from_nonterminal_ast(nt).flattened(),
), ),
_ => TokenTree::Token(token.clone(), spacing), _ => TokenTree::Token(token.clone(), spacing),
} }
@ -511,7 +511,7 @@ impl TokenStream {
fn try_glue_to_last(vec: &mut Vec<TokenTree>, tt: &TokenTree) -> bool { fn try_glue_to_last(vec: &mut Vec<TokenTree>, tt: &TokenTree) -> bool {
if let Some(TokenTree::Token(last_tok, Spacing::Joint)) = vec.last() if let Some(TokenTree::Token(last_tok, Spacing::Joint)) = vec.last()
&& let TokenTree::Token(tok, spacing) = tt && 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 // ...then overwrite the last token tree in `vec` with the
// glued token, and skip the first token tree from `stream`. // 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 /// Push `tt` onto the end of the stream, possibly gluing it to the last
// token. Uses `make_mut` to maximize efficiency. /// token. Uses `make_mut` to maximize efficiency.
pub fn push_tree(&mut self, tt: TokenTree) { pub fn push_tree(&mut self, tt: TokenTree) {
let vec_mut = Lrc::make_mut(&mut self.0); 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 /// 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.) /// token tree to the last token. (No other token trees will be glued.)
// Uses `make_mut` to maximize efficiency. /// Uses `make_mut` to maximize efficiency.
pub fn push_stream(&mut self, stream: TokenStream) { pub fn push_stream(&mut self, stream: TokenStream) {
let vec_mut = Lrc::make_mut(&mut self.0); let vec_mut = Lrc::make_mut(&mut self.0);

View 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,
}

View File

@ -21,6 +21,7 @@ pub fn expr_requires_semi_to_be_stmt(e: &ast::Expr) -> bool {
| ast::ExprKind::Loop(..) | ast::ExprKind::Loop(..)
| ast::ExprKind::ForLoop(..) | ast::ExprKind::ForLoop(..)
| ast::ExprKind::TryBlock(..) | ast::ExprKind::TryBlock(..)
| ast::ExprKind::ConstBlock(..)
) )
} }
@ -36,7 +37,6 @@ pub fn expr_trailing_brace(mut expr: &ast::Expr) -> Option<&ast::Expr> {
| Binary(_, _, e) | Binary(_, _, e)
| Box(e) | Box(e)
| Break(_, Some(e)) | Break(_, Some(e))
| Closure(.., e, _)
| Let(_, e, _) | Let(_, e, _)
| Range(_, Some(e), _) | Range(_, Some(e), _)
| Ret(Some(e)) | Ret(Some(e))
@ -44,6 +44,9 @@ pub fn expr_trailing_brace(mut expr: &ast::Expr) -> Option<&ast::Expr> {
| Yield(Some(e)) => { | Yield(Some(e)) => {
expr = e; expr = e;
} }
Closure(closure) => {
expr = &closure.body;
}
Async(..) | Block(..) | ForLoop(..) | If(..) | Loop(..) | Match(..) | Struct(..) Async(..) | Block(..) | ForLoop(..) | If(..) | Loop(..) | Match(..) | Struct(..)
| TryBlock(..) | While(..) => break Some(expr), | TryBlock(..) | While(..) => break Some(expr),
_ => break None, _ => break None,

View File

@ -110,7 +110,7 @@ pub fn beautify_doc_string(data: Symbol, kind: CommentKind) -> Symbol {
} else { } else {
&mut lines &mut lines
}; };
if let Some(horizontal) = get_horizontal_trim(&lines, kind) { if let Some(horizontal) = get_horizontal_trim(lines, kind) {
changes = true; changes = true;
// remove a "[ \t]*\*" block from each line, if possible // remove a "[ \t]*\*" block from each line, if possible
for line in lines.iter_mut() { 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 { fn trim_whitespace_prefix(s: &str, col: CharPos) -> &str {
let len = s.len(); let len = s.len();
match all_whitespace(&s, col) { match all_whitespace(s, col) {
Some(col) => { Some(col) => {
if col < len { if col < len {
&s[col..] &s[col..]

View File

@ -1,17 +1,14 @@
//! Code related to parsing literals. //! Code related to parsing literals.
use crate::ast::{self, Lit, LitKind}; use crate::ast::{self, LitKind, MetaItemLit};
use crate::token::{self, Token}; use crate::token::{self, Token};
use rustc_lexer::unescape::{byte_from_char, unescape_byte, unescape_char, unescape_literal, Mode};
use rustc_lexer::unescape::{unescape_byte, unescape_char};
use rustc_lexer::unescape::{unescape_byte_literal, unescape_literal, Mode};
use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::symbol::{kw, sym, Symbol};
use rustc_span::Span; use rustc_span::Span;
use std::ascii; use std::ascii;
#[derive(Debug)]
pub enum LitError { pub enum LitError {
NotLiteral,
LexerError, LexerError,
InvalidSuffix, InvalidSuffix,
InvalidIntSuffix, InvalidIntSuffix,
@ -55,14 +52,14 @@ impl LitKind {
// new symbol because the string in the LitKind is different to the // new symbol because the string in the LitKind is different to the
// string in the token. // string in the token.
let s = symbol.as_str(); 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 buf = String::with_capacity(s.len());
let mut error = Ok(()); let mut error = Ok(());
// Force-inlining here is aggressive but the closure is // Force-inlining here is aggressive but the closure is
// called on every char in the string, so it can be // called on every char in the string, so it can be
// hot in programs with many long strings. // hot in programs with many long strings.
unescape_literal( unescape_literal(
&s, s,
Mode::Str, Mode::Str,
&mut #[inline(always)] &mut #[inline(always)]
|_, unescaped_char| match unescaped_char { |_, unescaped_char| match unescaped_char {
@ -88,7 +85,7 @@ impl LitKind {
if s.contains('\r') { if s.contains('\r') {
let mut buf = String::with_capacity(s.len()); let mut buf = String::with_capacity(s.len());
let mut error = Ok(()); let mut error = Ok(());
unescape_literal(&s, Mode::RawStr, &mut |_, unescaped_char| { unescape_literal(s, Mode::RawStr, &mut |_, unescaped_char| {
match unescaped_char { match unescaped_char {
Ok(c) => buf.push(c), Ok(c) => buf.push(c),
Err(err) => { Err(err) => {
@ -109,13 +106,11 @@ impl LitKind {
let s = symbol.as_str(); let s = symbol.as_str();
let mut buf = Vec::with_capacity(s.len()); let mut buf = Vec::with_capacity(s.len());
let mut error = Ok(()); let mut error = Ok(());
unescape_byte_literal(&s, Mode::ByteStr, &mut |_, unescaped_byte| { unescape_literal(s, Mode::ByteStr, &mut |_, c| match c {
match unescaped_byte { Ok(c) => buf.push(byte_from_char(c)),
Ok(c) => buf.push(c), Err(err) => {
Err(err) => { if err.is_fatal() {
if err.is_fatal() { error = Err(LitError::LexerError);
error = Err(LitError::LexerError);
}
} }
} }
}); });
@ -127,13 +122,11 @@ impl LitKind {
let bytes = if s.contains('\r') { let bytes = if s.contains('\r') {
let mut buf = Vec::with_capacity(s.len()); let mut buf = Vec::with_capacity(s.len());
let mut error = Ok(()); let mut error = Ok(());
unescape_byte_literal(&s, Mode::RawByteStr, &mut |_, unescaped_byte| { unescape_literal(s, Mode::RawByteStr, &mut |_, c| match c {
match unescaped_byte { Ok(c) => buf.push(byte_from_char(c)),
Ok(c) => buf.push(c), Err(err) => {
Err(err) => { if err.is_fatal() {
if err.is_fatal() { error = Err(LitError::LexerError);
error = Err(LitError::LexerError);
}
} }
} }
}); });
@ -202,49 +195,16 @@ impl LitKind {
} }
} }
impl Lit { impl MetaItemLit {
/// Converts literal token into an AST literal. /// Converts token literal into a meta item literal.
pub fn from_token_lit(token_lit: token::Lit, span: Span) -> Result<Lit, LitError> { pub fn from_token_lit(token_lit: token::Lit, span: Span) -> Result<MetaItemLit, LitError> {
Ok(Lit { token_lit, kind: LitKind::from_token_lit(token_lit)?, span }) Ok(MetaItemLit { token_lit, kind: LitKind::from_token_lit(token_lit)?, span })
} }
/// Converts arbitrary token into an AST literal. /// Converts an arbitrary token into meta item literal.
/// pub fn from_token(token: &Token) -> Option<MetaItemLit> {
/// Keep this in sync with `Token::can_begin_literal_or_bool` excluding unary negation. token::Lit::from_token(token)
pub fn from_token(token: &Token) -> Result<Lit, LitError> { .and_then(|token_lit| MetaItemLit::from_token_lit(token_lit, token.span).ok())
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)
} }
} }

View File

@ -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 /// 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. /// `X { y: 1 } == foo` all do, but `(X { y: 1 }) == foo` does not.
pub fn contains_exterior_struct_lit(value: &ast::Expr) -> bool { pub fn contains_exterior_struct_lit(value: &ast::Expr) -> bool {
match value.kind { match &value.kind {
ast::ExprKind::Struct(..) => true, ast::ExprKind::Struct(..) => true,
ast::ExprKind::Assign(ref lhs, ref rhs, _) ast::ExprKind::Assign(lhs, rhs, _)
| ast::ExprKind::AssignOp(_, ref lhs, ref rhs) | ast::ExprKind::AssignOp(_, lhs, rhs)
| ast::ExprKind::Binary(_, ref lhs, ref rhs) => { | ast::ExprKind::Binary(_, lhs, rhs) => {
// X { y: 1 } + X { y: 2 } // 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::Await(x)
| ast::ExprKind::Unary(_, ref x) | ast::ExprKind::Unary(_, x)
| ast::ExprKind::Cast(ref x, _) | ast::ExprKind::Cast(x, _)
| ast::ExprKind::Type(ref x, _) | ast::ExprKind::Type(x, _)
| ast::ExprKind::Field(ref x, _) | ast::ExprKind::Field(x, _)
| ast::ExprKind::Index(ref x, _) => { | ast::ExprKind::Index(x, _) => {
// &X { y: 1 }, X { y: 1 }.y // &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(...) // X { y: 1 }.bar(...)
contains_exterior_struct_lit(&receiver) contains_exterior_struct_lit(receiver)
} }
_ => false, _ => false,

View File

@ -17,7 +17,7 @@ pub fn contains_text_flow_control_chars(s: &str) -> bool {
// U+2069 - E2 81 A9 // U+2069 - E2 81 A9
let mut bytes = s.as_bytes(); let mut bytes = s.as_bytes();
loop { loop {
match core::slice::memchr::memchr(0xE2, &bytes) { match core::slice::memchr::memchr(0xE2, bytes) {
Some(idx) => { Some(idx) => {
// bytes are valid UTF-8 -> E2 must be followed by two bytes // bytes are valid UTF-8 -> E2 must be followed by two bytes
let ch = &bytes[idx..idx + 3]; let ch = &bytes[idx..idx + 3];

View File

@ -251,7 +251,7 @@ pub trait Visitor<'ast>: Sized {
macro_rules! walk_list { macro_rules! walk_list {
($visitor: expr, $method: ident, $list: expr $(, $($extra_args: expr),* )?) => { ($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 { for elem in $list {
$visitor.$method(elem $(, $($extra_args,)* )?) $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) { pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) {
visitor.visit_vis(&item.vis); visitor.visit_vis(&item.vis);
visitor.visit_ident(item.ident); visitor.visit_ident(item.ident);
match item.kind { match &item.kind {
ItemKind::ExternCrate(_) => {} ItemKind::ExternCrate(_) => {}
ItemKind::Use(ref use_tree) => visitor.visit_use_tree(use_tree, item.id, false), ItemKind::Use(use_tree) => visitor.visit_use_tree(use_tree, item.id, false),
ItemKind::Static(ref typ, _, ref expr) | ItemKind::Const(_, ref typ, ref expr) => { ItemKind::Static(typ, _, expr) | ItemKind::Const(_, typ, expr) => {
visitor.visit_ty(typ); visitor.visit_ty(typ);
walk_list!(visitor, visit_expr, expr); 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 = let kind =
FnKind::Fn(FnCtxt::Free, item.ident, sig, &item.vis, generics, body.as_deref()); FnKind::Fn(FnCtxt::Free, item.ident, sig, &item.vis, generics, body.as_deref());
visitor.visit_fn(kind, item.span, item.id) 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) => { ModKind::Loaded(items, _inline, _inner_span) => {
walk_list!(visitor, visit_item, items) walk_list!(visitor, visit_item, items)
} }
ModKind::Unloaded => {} ModKind::Unloaded => {}
}, },
ItemKind::ForeignMod(ref foreign_module) => { ItemKind::ForeignMod(foreign_module) => {
walk_list!(visitor, visit_foreign_item, &foreign_module.items); walk_list!(visitor, visit_foreign_item, &foreign_module.items);
} }
ItemKind::GlobalAsm(ref asm) => visitor.visit_inline_asm(asm), ItemKind::GlobalAsm(asm) => visitor.visit_inline_asm(asm),
ItemKind::TyAlias(box TyAlias { ref generics, ref bounds, ref ty, .. }) => { ItemKind::TyAlias(box TyAlias { generics, bounds, ty, .. }) => {
visitor.visit_generics(generics); visitor.visit_generics(generics);
walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound); walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
walk_list!(visitor, visit_ty, ty); walk_list!(visitor, visit_ty, ty);
} }
ItemKind::Enum(ref enum_definition, ref generics) => { ItemKind::Enum(enum_definition, generics) => {
visitor.visit_generics(generics); visitor.visit_generics(generics);
visitor.visit_enum_def(enum_definition) visitor.visit_enum_def(enum_definition)
} }
ItemKind::Impl(box Impl { ItemKind::Impl(box Impl {
defaultness: _, defaultness: _,
unsafety: _, unsafety: _,
ref generics, generics,
constness: _, constness: _,
polarity: _, polarity: _,
ref of_trait, of_trait,
ref self_ty, self_ty,
ref items, items,
}) => { }) => {
visitor.visit_generics(generics); visitor.visit_generics(generics);
walk_list!(visitor, visit_trait_ref, of_trait); walk_list!(visitor, visit_trait_ref, of_trait);
visitor.visit_ty(self_ty); visitor.visit_ty(self_ty);
walk_list!(visitor, visit_assoc_item, items, AssocCtxt::Impl); walk_list!(visitor, visit_assoc_item, items, AssocCtxt::Impl);
} }
ItemKind::Struct(ref struct_definition, ref generics) ItemKind::Struct(struct_definition, generics)
| ItemKind::Union(ref struct_definition, ref generics) => { | ItemKind::Union(struct_definition, generics) => {
visitor.visit_generics(generics); visitor.visit_generics(generics);
visitor.visit_variant_data(struct_definition); visitor.visit_variant_data(struct_definition);
} }
ItemKind::Trait(box Trait { ItemKind::Trait(box Trait { unsafety: _, is_auto: _, generics, bounds, items }) => {
unsafety: _,
is_auto: _,
ref generics,
ref bounds,
ref items,
}) => {
visitor.visit_generics(generics); visitor.visit_generics(generics);
walk_list!(visitor, visit_param_bound, bounds, BoundKind::SuperTraits); walk_list!(visitor, visit_param_bound, bounds, BoundKind::SuperTraits);
walk_list!(visitor, visit_assoc_item, items, AssocCtxt::Trait); walk_list!(visitor, visit_assoc_item, items, AssocCtxt::Trait);
} }
ItemKind::TraitAlias(ref generics, ref bounds) => { ItemKind::TraitAlias(generics, bounds) => {
visitor.visit_generics(generics); visitor.visit_generics(generics);
walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound); walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
} }
ItemKind::MacCall(ref mac) => visitor.visit_mac_call(mac), ItemKind::MacCall(mac) => visitor.visit_mac_call(mac),
ItemKind::MacroDef(ref ts) => visitor.visit_mac_def(ts, item.id), ItemKind::MacroDef(ts) => visitor.visit_mac_def(ts, item.id),
} }
walk_list!(visitor, visit_attribute, &item.attrs); 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) { pub fn walk_ty<'a, V: Visitor<'a>>(visitor: &mut V, typ: &'a Ty) {
match typ.kind { match &typ.kind {
TyKind::Slice(ref ty) | TyKind::Paren(ref ty) => visitor.visit_ty(ty), TyKind::Slice(ty) | TyKind::Paren(ty) => visitor.visit_ty(ty),
TyKind::Ptr(ref mutable_type) => visitor.visit_ty(&mutable_type.ty), TyKind::Ptr(mutable_type) => visitor.visit_ty(&mutable_type.ty),
TyKind::Rptr(ref opt_lifetime, ref mutable_type) => { TyKind::Rptr(opt_lifetime, mutable_type) => {
walk_list!(visitor, visit_lifetime, opt_lifetime, LifetimeCtxt::Rptr); walk_list!(visitor, visit_lifetime, opt_lifetime, LifetimeCtxt::Rptr);
visitor.visit_ty(&mutable_type.ty) 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); 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_list!(visitor, visit_generic_param, &function_declaration.generic_params);
walk_fn_decl(visitor, &function_declaration.decl); walk_fn_decl(visitor, &function_declaration.decl);
} }
TyKind::Path(ref maybe_qself, ref path) => { TyKind::Path(maybe_qself, path) => {
if let Some(ref qself) = *maybe_qself { if let Some(qself) = maybe_qself {
visitor.visit_ty(&qself.ty); visitor.visit_ty(&qself.ty);
} }
visitor.visit_path(path, typ.id); visitor.visit_path(path, typ.id);
} }
TyKind::Array(ref ty, ref length) => { TyKind::Array(ty, length) => {
visitor.visit_ty(ty); visitor.visit_ty(ty);
visitor.visit_anon_const(length) visitor.visit_anon_const(length)
} }
TyKind::TraitObject(ref bounds, ..) => { TyKind::TraitObject(bounds, ..) => {
walk_list!(visitor, visit_param_bound, bounds, BoundKind::TraitObject); 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); 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::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 => {} 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) { 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); visitor.visit_path(&use_tree.prefix, id);
match use_tree.kind { match &use_tree.kind {
UseTreeKind::Simple(rename, ..) => { UseTreeKind::Simple(rename) => {
// The extra IDs are handled during HIR lowering. // The extra IDs are handled during HIR lowering.
if let Some(rename) = rename { if let &Some(rename) = rename {
visitor.visit_ident(rename); visitor.visit_ident(rename);
} }
} }
UseTreeKind::Glob => {} UseTreeKind::Glob => {}
UseTreeKind::Nested(ref use_trees) => { UseTreeKind::Nested(use_trees) => {
for &(ref nested_tree, nested_id) in use_trees { for &(ref nested_tree, nested_id) in use_trees {
visitor.visit_use_tree(nested_tree, nested_id, true); 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) { pub fn walk_path_segment<'a, V: Visitor<'a>>(visitor: &mut V, segment: &'a PathSegment) {
visitor.visit_ident(segment.ident); visitor.visit_ident(segment.ident);
if let Some(ref args) = segment.args { if let Some(args) = &segment.args {
visitor.visit_generic_args(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 where
V: Visitor<'a>, V: Visitor<'a>,
{ {
match *generic_args { match generic_args {
GenericArgs::AngleBracketed(ref data) => { GenericArgs::AngleBracketed(data) => {
for arg in &data.args { for arg in &data.args {
match arg { match arg {
AngleBracketedArg::Arg(a) => visitor.visit_generic_arg(a), 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_list!(visitor, visit_ty, &data.inputs);
walk_fn_ret_ty(visitor, &data.output); 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) { pub fn walk_assoc_constraint<'a, V: Visitor<'a>>(visitor: &mut V, constraint: &'a AssocConstraint) {
visitor.visit_ident(constraint.ident); 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); visitor.visit_generic_args(gen_args);
} }
match constraint.kind { match &constraint.kind {
AssocConstraintKind::Equality { ref term } => match term { AssocConstraintKind::Equality { term } => match term {
Term::Ty(ty) => visitor.visit_ty(ty), Term::Ty(ty) => visitor.visit_ty(ty),
Term::Const(c) => visitor.visit_anon_const(c), Term::Const(c) => visitor.visit_anon_const(c),
}, },
AssocConstraintKind::Bound { ref bounds } => { AssocConstraintKind::Bound { bounds } => {
walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound); walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
} }
} }
} }
pub fn walk_pat<'a, V: Visitor<'a>>(visitor: &mut V, pattern: &'a Pat) { pub fn walk_pat<'a, V: Visitor<'a>>(visitor: &mut V, pattern: &'a Pat) {
match pattern.kind { match &pattern.kind {
PatKind::TupleStruct(ref opt_qself, ref path, ref elems) => { PatKind::TupleStruct(opt_qself, path, elems) => {
if let Some(ref qself) = *opt_qself { if let Some(qself) = opt_qself {
visitor.visit_ty(&qself.ty); visitor.visit_ty(&qself.ty);
} }
visitor.visit_path(path, pattern.id); visitor.visit_path(path, pattern.id);
walk_list!(visitor, visit_pat, elems); walk_list!(visitor, visit_pat, elems);
} }
PatKind::Path(ref opt_qself, ref path) => { PatKind::Path(opt_qself, path) => {
if let Some(ref qself) = *opt_qself { if let Some(qself) = opt_qself {
visitor.visit_ty(&qself.ty); visitor.visit_ty(&qself.ty);
} }
visitor.visit_path(path, pattern.id) visitor.visit_path(path, pattern.id)
} }
PatKind::Struct(ref opt_qself, ref path, ref fields, _) => { PatKind::Struct(opt_qself, path, fields, _) => {
if let Some(ref qself) = *opt_qself { if let Some(qself) = opt_qself {
visitor.visit_ty(&qself.ty); visitor.visit_ty(&qself.ty);
} }
visitor.visit_path(path, pattern.id); visitor.visit_path(path, pattern.id);
walk_list!(visitor, visit_pat_field, fields); walk_list!(visitor, visit_pat_field, fields);
} }
PatKind::Box(ref subpattern) PatKind::Box(subpattern) | PatKind::Ref(subpattern, _) | PatKind::Paren(subpattern) => {
| PatKind::Ref(ref subpattern, _) visitor.visit_pat(subpattern)
| PatKind::Paren(ref subpattern) => visitor.visit_pat(subpattern), }
PatKind::Ident(_, ident, ref optional_subpattern) => { PatKind::Ident(_, ident, optional_subpattern) => {
visitor.visit_ident(ident); visitor.visit_ident(*ident);
walk_list!(visitor, visit_pat, optional_subpattern); walk_list!(visitor, visit_pat, optional_subpattern);
} }
PatKind::Lit(ref expression) => visitor.visit_expr(expression), PatKind::Lit(expression) => visitor.visit_expr(expression),
PatKind::Range(ref lower_bound, ref upper_bound, _) => { PatKind::Range(lower_bound, upper_bound, _) => {
walk_list!(visitor, visit_expr, lower_bound); walk_list!(visitor, visit_expr, lower_bound);
walk_list!(visitor, visit_expr, upper_bound); walk_list!(visitor, visit_expr, upper_bound);
} }
PatKind::Wild | PatKind::Rest => {} 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); 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) { 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_vis(vis);
visitor.visit_ident(ident); visitor.visit_ident(ident);
walk_list!(visitor, visit_attribute, attrs); 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); visitor.visit_ty(ty);
walk_list!(visitor, visit_expr, expr); 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()); let kind = FnKind::Fn(FnCtxt::Foreign, ident, sig, vis, generics, body.as_deref());
visitor.visit_fn(kind, span, id); 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) { pub fn walk_param_bound<'a, V: Visitor<'a>>(visitor: &mut V, bound: &'a GenericBound) {
match *bound { match bound {
GenericBound::Trait(ref typ, ref _modifier) => visitor.visit_poly_trait_ref(typ), GenericBound::Trait(typ, _modifier) => visitor.visit_poly_trait_ref(typ),
GenericBound::Outlives(ref lifetime) => { GenericBound::Outlives(lifetime) => visitor.visit_lifetime(lifetime, LifetimeCtxt::Bound),
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); visitor.visit_ident(param.ident);
walk_list!(visitor, visit_attribute, param.attrs.iter()); walk_list!(visitor, visit_attribute, param.attrs.iter());
walk_list!(visitor, visit_param_bound, &param.bounds, BoundKind::Bound); walk_list!(visitor, visit_param_bound, &param.bounds, BoundKind::Bound);
match param.kind { match &param.kind {
GenericParamKind::Lifetime => (), GenericParamKind::Lifetime => (),
GenericParamKind::Type { ref default } => walk_list!(visitor, visit_ty, default), GenericParamKind::Type { default } => walk_list!(visitor, visit_ty, default),
GenericParamKind::Const { ref ty, ref default, .. } => { GenericParamKind::Const { ty, default, .. } => {
visitor.visit_ty(ty); visitor.visit_ty(ty);
if let Some(default) = default { if let Some(default) = default {
visitor.visit_anon_const(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) { pub fn walk_where_predicate<'a, V: Visitor<'a>>(visitor: &mut V, predicate: &'a WherePredicate) {
match *predicate { match predicate {
WherePredicate::BoundPredicate(WhereBoundPredicate { WherePredicate::BoundPredicate(WhereBoundPredicate {
ref bounded_ty, bounded_ty,
ref bounds, bounds,
ref bound_generic_params, bound_generic_params,
.. ..
}) => { }) => {
visitor.visit_ty(bounded_ty); visitor.visit_ty(bounded_ty);
walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound); walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
walk_list!(visitor, visit_generic_param, bound_generic_params); walk_list!(visitor, visit_generic_param, bound_generic_params);
} }
WherePredicate::RegionPredicate(WhereRegionPredicate { WherePredicate::RegionPredicate(WhereRegionPredicate { lifetime, bounds, .. }) => {
ref lifetime, ref bounds, ..
}) => {
visitor.visit_lifetime(lifetime, LifetimeCtxt::Bound); visitor.visit_lifetime(lifetime, LifetimeCtxt::Bound);
walk_list!(visitor, visit_param_bound, bounds, BoundKind::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(lhs_ty);
visitor.visit_ty(rhs_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) { 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) 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) { 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_vis(vis);
visitor.visit_ident(ident); visitor.visit_ident(ident);
walk_list!(visitor, visit_attribute, attrs); 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); visitor.visit_ty(ty);
walk_list!(visitor, visit_expr, expr); 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()); let kind = FnKind::Fn(FnCtxt::Assoc(ctxt), ident, sig, vis, generics, body.as_deref());
visitor.visit_fn(kind, span, id); 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) { pub fn walk_stmt<'a, V: Visitor<'a>>(visitor: &mut V, statement: &'a Stmt) {
match statement.kind { match &statement.kind {
StmtKind::Local(ref local) => visitor.visit_local(local), StmtKind::Local(local) => visitor.visit_local(local),
StmtKind::Item(ref item) => visitor.visit_item(item), StmtKind::Item(item) => visitor.visit_item(item),
StmtKind::Expr(ref expr) | StmtKind::Semi(ref expr) => visitor.visit_expr(expr), StmtKind::Expr(expr) | StmtKind::Semi(expr) => visitor.visit_expr(expr),
StmtKind::Empty => {} StmtKind::Empty => {}
StmtKind::MacCall(ref mac) => { StmtKind::MacCall(mac) => {
let MacCallStmt { ref mac, style: _, ref attrs, tokens: _ } = **mac; let MacCallStmt { mac, attrs, style: _, tokens: _ } = &**mac;
visitor.visit_mac_call(mac); visitor.visit_mac_call(mac);
for attr in attrs.iter() { for attr in attrs.iter() {
visitor.visit_attribute(attr); 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) { 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_ty(&qself.ty);
} }
visitor.visit_path(&sym.path, sym.id); 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) { pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
walk_list!(visitor, visit_attribute, expression.attrs.iter()); walk_list!(visitor, visit_attribute, expression.attrs.iter());
match expression.kind { match &expression.kind {
ExprKind::Box(ref subexpression) => visitor.visit_expr(subexpression), ExprKind::Box(subexpression) => visitor.visit_expr(subexpression),
ExprKind::Array(ref subexpressions) => { ExprKind::Array(subexpressions) => {
walk_list!(visitor, visit_expr, subexpressions); walk_list!(visitor, visit_expr, subexpressions);
} }
ExprKind::ConstBlock(ref anon_const) => visitor.visit_anon_const(anon_const), ExprKind::ConstBlock(anon_const) => visitor.visit_anon_const(anon_const),
ExprKind::Repeat(ref element, ref count) => { ExprKind::Repeat(element, count) => {
visitor.visit_expr(element); visitor.visit_expr(element);
visitor.visit_anon_const(count) visitor.visit_anon_const(count)
} }
ExprKind::Struct(ref se) => { ExprKind::Struct(se) => {
if let Some(ref qself) = se.qself { if let Some(qself) = &se.qself {
visitor.visit_ty(&qself.ty); visitor.visit_ty(&qself.ty);
} }
visitor.visit_path(&se.path, expression.id); 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 => {} StructRest::None => {}
} }
} }
ExprKind::Tup(ref subexpressions) => { ExprKind::Tup(subexpressions) => {
walk_list!(visitor, visit_expr, subexpressions); walk_list!(visitor, visit_expr, subexpressions);
} }
ExprKind::Call(ref callee_expression, ref arguments) => { ExprKind::Call(callee_expression, arguments) => {
visitor.visit_expr(callee_expression); visitor.visit_expr(callee_expression);
walk_list!(visitor, visit_expr, arguments); walk_list!(visitor, visit_expr, arguments);
} }
ExprKind::MethodCall(ref segment, ref receiver, ref arguments, _span) => { ExprKind::MethodCall(box MethodCall { seg, receiver, args, span: _ }) => {
visitor.visit_path_segment(segment); visitor.visit_path_segment(seg);
visitor.visit_expr(receiver); 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(left_expression);
visitor.visit_expr(right_expression) visitor.visit_expr(right_expression)
} }
ExprKind::AddrOf(_, _, ref subexpression) | ExprKind::Unary(_, ref subexpression) => { ExprKind::AddrOf(_, _, subexpression) | ExprKind::Unary(_, subexpression) => {
visitor.visit_expr(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_expr(subexpression);
visitor.visit_ty(typ) visitor.visit_ty(typ)
} }
ExprKind::Let(ref pat, ref expr, _) => { ExprKind::Let(pat, expr, _) => {
visitor.visit_pat(pat); visitor.visit_pat(pat);
visitor.visit_expr(expr); 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_expr(head_expression);
visitor.visit_block(if_block); visitor.visit_block(if_block);
walk_list!(visitor, visit_expr, optional_else); 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); walk_list!(visitor, visit_label, opt_label);
visitor.visit_expr(subexpression); visitor.visit_expr(subexpression);
visitor.visit_block(block); 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); walk_list!(visitor, visit_label, opt_label);
visitor.visit_pat(pattern); visitor.visit_pat(pattern);
visitor.visit_expr(subexpression); visitor.visit_expr(subexpression);
visitor.visit_block(block); visitor.visit_block(block);
} }
ExprKind::Loop(ref block, ref opt_label) => { ExprKind::Loop(block, opt_label, _) => {
walk_list!(visitor, visit_label, opt_label); walk_list!(visitor, visit_label, opt_label);
visitor.visit_block(block); visitor.visit_block(block);
} }
ExprKind::Match(ref subexpression, ref arms) => { ExprKind::Match(subexpression, arms) => {
visitor.visit_expr(subexpression); visitor.visit_expr(subexpression);
walk_list!(visitor, visit_arm, arms); walk_list!(visitor, visit_arm, arms);
} }
ExprKind::Closure(ref binder, _, _, _, ref decl, ref body, _decl_span) => { ExprKind::Closure(box Closure {
visitor.visit_fn(FnKind::Closure(binder, decl, body), expression.span, expression.id) 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); walk_list!(visitor, visit_label, opt_label);
visitor.visit_block(block); visitor.visit_block(block);
} }
ExprKind::Async(_, _, ref body) => { ExprKind::Async(_, _, body) => {
visitor.visit_block(body); visitor.visit_block(body);
} }
ExprKind::Await(ref expr) => visitor.visit_expr(expr), ExprKind::Await(expr) => visitor.visit_expr(expr),
ExprKind::Assign(ref lhs, ref rhs, _) => { ExprKind::Assign(lhs, rhs, _) => {
visitor.visit_expr(lhs); visitor.visit_expr(lhs);
visitor.visit_expr(rhs); 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(left_expression);
visitor.visit_expr(right_expression); visitor.visit_expr(right_expression);
} }
ExprKind::Field(ref subexpression, ident) => { ExprKind::Field(subexpression, ident) => {
visitor.visit_expr(subexpression); 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(main_expression);
visitor.visit_expr(index_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, start);
walk_list!(visitor, visit_expr, end); walk_list!(visitor, visit_expr, end);
} }
ExprKind::Underscore => {} ExprKind::Underscore => {}
ExprKind::Path(ref maybe_qself, ref path) => { ExprKind::Path(maybe_qself, path) => {
if let Some(ref qself) = *maybe_qself { if let Some(qself) = maybe_qself {
visitor.visit_ty(&qself.ty); visitor.visit_ty(&qself.ty);
} }
visitor.visit_path(path, expression.id) 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_label, opt_label);
walk_list!(visitor, visit_expr, opt_expr); walk_list!(visitor, visit_expr, opt_expr);
} }
ExprKind::Continue(ref opt_label) => { ExprKind::Continue(opt_label) => {
walk_list!(visitor, visit_label, 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); walk_list!(visitor, visit_expr, optional_expression);
} }
ExprKind::Yeet(ref optional_expression) => { ExprKind::Yeet(optional_expression) => {
walk_list!(visitor, visit_expr, optional_expression); walk_list!(visitor, visit_expr, optional_expression);
} }
ExprKind::MacCall(ref mac) => visitor.visit_mac_call(mac), ExprKind::MacCall(mac) => visitor.visit_mac_call(mac),
ExprKind::Paren(ref subexpression) => visitor.visit_expr(subexpression), ExprKind::Paren(subexpression) => visitor.visit_expr(subexpression),
ExprKind::InlineAsm(ref asm) => visitor.visit_inline_asm(asm), ExprKind::InlineAsm(asm) => visitor.visit_inline_asm(asm),
ExprKind::Yield(ref optional_expression) => { ExprKind::Yield(optional_expression) => {
walk_list!(visitor, visit_expr, optional_expression); walk_list!(visitor, visit_expr, optional_expression);
} }
ExprKind::Try(ref subexpression) => visitor.visit_expr(subexpression), ExprKind::Try(subexpression) => visitor.visit_expr(subexpression),
ExprKind::TryBlock(ref body) => visitor.visit_block(body), ExprKind::TryBlock(body) => visitor.visit_block(body),
ExprKind::Lit(_) | ExprKind::Err => {} ExprKind::Lit(_) | ExprKind::IncludedBytes(..) | ExprKind::Err => {}
} }
visitor.visit_expr_post(expression) 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) { pub fn walk_attribute<'a, V: Visitor<'a>>(visitor: &mut V, attr: &'a Attribute) {
match attr.kind { match &attr.kind {
AttrKind::Normal(ref normal) => walk_mac_args(visitor, &normal.item.args), AttrKind::Normal(normal) => walk_attr_args(visitor, &normal.item.args),
AttrKind::DocComment(..) => {} 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 { match args {
MacArgs::Empty => {} AttrArgs::Empty => {}
MacArgs::Delimited(_dspan, _delim, _tokens) => {} AttrArgs::Delimited(_) => {}
MacArgs::Eq(_eq_span, MacArgsEq::Ast(expr)) => visitor.visit_expr(expr), AttrArgs::Eq(_eq_span, AttrArgsEq::Ast(expr)) => visitor.visit_expr(expr),
MacArgs::Eq(_, MacArgsEq::Hir(lit)) => { AttrArgs::Eq(_, AttrArgsEq::Hir(lit)) => {
unreachable!("in literal form when walking mac args eq: {:?}", lit) unreachable!("in literal form when walking mac args eq: {:?}", lit)
} }
} }

View File

@ -21,5 +21,5 @@ rustc_session = { path = "../rustc_session" }
rustc_span = { path = "../rustc_span" } rustc_span = { path = "../rustc_span" }
rustc_target = { path = "../rustc_target" } rustc_target = { path = "../rustc_target" }
smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
thin-vec = "0.2.8" thin-vec = "0.2.9"
tracing = "0.1" tracing = "0.1"

View File

@ -11,7 +11,7 @@ use super::LoweringContext;
use rustc_ast::ptr::P; use rustc_ast::ptr::P;
use rustc_ast::*; 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 as hir;
use rustc_hir::def::{DefKind, Res}; use rustc_hir::def::{DefKind, Res};
use rustc_hir::definitions::DefPathData; use rustc_hir::definitions::DefPathData;
@ -71,7 +71,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
.emit(); .emit();
} }
let mut clobber_abis = FxHashMap::default(); let mut clobber_abis = FxIndexMap::default();
if let Some(asm_arch) = asm_arch { if let Some(asm_arch) = asm_arch {
for (abi_name, abi_span) in &asm.clobber_abis { for (abi_name, abi_span) in &asm.clobber_abis {
match asm::InlineAsmClobberAbi::parse(asm_arch, &self.tcx.sess.target, *abi_name) { match asm::InlineAsmClobberAbi::parse(asm_arch, &self.tcx.sess.target, *abi_name) {
@ -123,7 +123,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
.operands .operands
.iter() .iter()
.map(|(op, op_sp)| { .map(|(op, op_sp)| {
let lower_reg = |reg| match reg { let lower_reg = |&reg: &_| match reg {
InlineAsmRegOrRegClass::Reg(reg) => { InlineAsmRegOrRegClass::Reg(reg) => {
asm::InlineAsmRegOrRegClass::Reg(if let Some(asm_arch) = asm_arch { asm::InlineAsmRegOrRegClass::Reg(if let Some(asm_arch) = asm_arch {
asm::InlineAsmReg::parse(asm_arch, reg).unwrap_or_else(|error| { asm::InlineAsmReg::parse(asm_arch, reg).unwrap_or_else(|error| {
@ -152,32 +152,30 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
} }
}; };
let op = match *op { let op = match op {
InlineAsmOperand::In { reg, ref expr } => hir::InlineAsmOperand::In { InlineAsmOperand::In { reg, expr } => hir::InlineAsmOperand::In {
reg: lower_reg(reg), reg: lower_reg(reg),
expr: self.lower_expr(expr), 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), reg: lower_reg(reg),
late, late: *late,
expr: expr.as_ref().map(|expr| self.lower_expr(expr)), expr: expr.as_ref().map(|expr| self.lower_expr(expr)),
}, },
InlineAsmOperand::InOut { reg, late, ref expr } => { InlineAsmOperand::InOut { reg, late, expr } => hir::InlineAsmOperand::InOut {
hir::InlineAsmOperand::InOut { reg: lower_reg(reg),
reg: lower_reg(reg), late: *late,
late, expr: self.lower_expr(expr),
expr: self.lower_expr(expr), },
} InlineAsmOperand::SplitInOut { reg, late, in_expr, out_expr } => {
}
InlineAsmOperand::SplitInOut { reg, late, ref in_expr, ref out_expr } => {
hir::InlineAsmOperand::SplitInOut { hir::InlineAsmOperand::SplitInOut {
reg: lower_reg(reg), reg: lower_reg(reg),
late, late: *late,
in_expr: self.lower_expr(in_expr), in_expr: self.lower_expr(in_expr),
out_expr: out_expr.as_ref().map(|expr| self.lower_expr(expr)), out_expr: out_expr.as_ref().map(|expr| self.lower_expr(expr)),
} }
} }
InlineAsmOperand::Const { ref anon_const } => { InlineAsmOperand::Const { anon_const } => {
if !self.tcx.features().asm_const { if !self.tcx.features().asm_const {
feature_err( feature_err(
&sess.parse_sess, &sess.parse_sess,
@ -191,7 +189,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
anon_const: self.lower_anon_const(anon_const), anon_const: self.lower_anon_const(anon_const),
} }
} }
InlineAsmOperand::Sym { ref sym } => { InlineAsmOperand::Sym { sym } => {
let static_def_id = self let static_def_id = self
.resolver .resolver
.get_partial_res(sym.id) .get_partial_res(sym.id)
@ -224,7 +222,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// Wrap the expression in an AnonConst. // Wrap the expression in an AnonConst.
let parent_def_id = self.current_hir_id_owner; let parent_def_id = self.current_hir_id_owner;
let node_id = self.next_node_id(); 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) }; let anon_const = AnonConst { id: node_id, value: P(expr) };
hir::InlineAsmOperand::SymFn { hir::InlineAsmOperand::SymFn {
anon_const: self.lower_anon_const(&anon_const), anon_const: self.lower_anon_const(&anon_const),
@ -347,7 +350,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
skip = true; skip = true;
let idx2 = *o.get(); 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 { let Some(asm::InlineAsmRegOrRegClass::Reg(reg2)) = op2.reg() else {
unreachable!(); unreachable!();
}; };

View File

@ -31,8 +31,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let mut stmts = SmallVec::<[hir::Stmt<'hir>; 8]>::new(); let mut stmts = SmallVec::<[hir::Stmt<'hir>; 8]>::new();
let mut expr = None; let mut expr = None;
while let [s, tail @ ..] = ast_stmts { while let [s, tail @ ..] = ast_stmts {
match s.kind { match &s.kind {
StmtKind::Local(ref local) => { StmtKind::Local(local) => {
let hir_id = self.lower_node_id(s.id); let hir_id = self.lower_node_id(s.id);
let local = self.lower_local(local); let local = self.lower_local(local);
self.alias_attrs(hir_id, local.hir_id); 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); let span = self.lower_span(s.span);
stmts.push(hir::Stmt { hir_id, kind, 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( stmts.extend(self.lower_item_ref(it).into_iter().enumerate().map(
|(i, item_id)| { |(i, item_id)| {
let hir_id = match i { 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); let e = self.lower_expr(e);
if tail.is_empty() { if tail.is_empty() {
expr = Some(e); expr = Some(e);
@ -65,7 +65,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
stmts.push(hir::Stmt { hir_id, kind, span }); stmts.push(hir::Stmt { hir_id, kind, span });
} }
} }
StmtKind::Semi(ref e) => { StmtKind::Semi(e) => {
let e = self.lower_expr(e); let e = self.lower_expr(e);
let hir_id = self.lower_node_id(s.id); let hir_id = self.lower_node_id(s.id);
self.alias_attrs(hir_id, e.hir_id); self.alias_attrs(hir_id, e.hir_id);

View File

@ -277,8 +277,9 @@ pub struct RegisterConflict<'a> {
pub struct SubTupleBinding<'a> { pub struct SubTupleBinding<'a> {
#[primary_span] #[primary_span]
#[label] #[label]
#[suggestion_verbose( #[suggestion(
ast_lowering_sub_tuple_binding_suggestion, ast_lowering_sub_tuple_binding_suggestion,
style = "verbose",
code = "..", code = "..",
applicability = "maybe-incorrect" applicability = "maybe-incorrect"
)] )]

View File

@ -14,6 +14,7 @@ use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::Res; use rustc_hir::def::Res;
use rustc_hir::definitions::DefPathData; use rustc_hir::definitions::DefPathData;
use rustc_session::errors::report_lit_error;
use rustc_span::source_map::{respan, DesugaringKind, Span, Spanned}; use rustc_span::source_map::{respan, DesugaringKind, Span, Spanned};
use rustc_span::symbol::{sym, Ident}; use rustc_span::symbol::{sym, Ident};
use rustc_span::DUMMY_SP; 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> { pub(super) fn lower_expr_mut(&mut self, e: &Expr) -> hir::Expr<'hir> {
ensure_sufficient_stack(|| { ensure_sufficient_stack(|| {
let kind = match e.kind { let kind = match &e.kind {
ExprKind::Box(ref inner) => hir::ExprKind::Box(self.lower_expr(inner)), ExprKind::Box(inner) => hir::ExprKind::Box(self.lower_expr(inner)),
ExprKind::Array(ref exprs) => hir::ExprKind::Array(self.lower_exprs(exprs)), ExprKind::Array(exprs) => hir::ExprKind::Array(self.lower_exprs(exprs)),
ExprKind::ConstBlock(ref anon_const) => { ExprKind::ConstBlock(anon_const) => {
let anon_const = self.lower_anon_const(anon_const); let anon_const = self.lower_anon_const(anon_const);
hir::ExprKind::ConstBlock(anon_const) hir::ExprKind::ConstBlock(anon_const)
} }
ExprKind::Repeat(ref expr, ref count) => { ExprKind::Repeat(expr, count) => {
let expr = self.lower_expr(expr); let expr = self.lower_expr(expr);
let count = self.lower_array_length(count); let count = self.lower_array_length(count);
hir::ExprKind::Repeat(expr, count) hir::ExprKind::Repeat(expr, count)
} }
ExprKind::Tup(ref elts) => hir::ExprKind::Tup(self.lower_exprs(elts)), ExprKind::Tup(elts) => hir::ExprKind::Tup(self.lower_exprs(elts)),
ExprKind::Call(ref f, ref args) => { ExprKind::Call(f, args) => {
if e.attrs.get(0).map_or(false, |a| a.has_name(sym::rustc_box)) { if e.attrs.get(0).map_or(false, |a| a.has_name(sym::rustc_box)) {
if let [inner] = &args[..] && e.attrs.len() == 1 { if let [inner] = &args[..] && e.attrs.len() == 1 {
let kind = hir::ExprKind::Box(self.lower_expr(&inner)); 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)) 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( let hir_seg = self.arena.alloc(self.lower_path_segment(
e.span, e.span,
seg, seg,
@ -71,81 +72,89 @@ impl<'hir> LoweringContext<'_, 'hir> {
let receiver = self.lower_expr(receiver); let receiver = self.lower_expr(receiver);
let args = let args =
self.arena.alloc_from_iter(args.iter().map(|x| self.lower_expr_mut(x))); 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) => { ExprKind::Binary(binop, lhs, rhs) => {
let binop = self.lower_binop(binop); let binop = self.lower_binop(*binop);
let lhs = self.lower_expr(lhs); let lhs = self.lower_expr(lhs);
let rhs = self.lower_expr(rhs); let rhs = self.lower_expr(rhs);
hir::ExprKind::Binary(binop, lhs, rhs) hir::ExprKind::Binary(binop, lhs, rhs)
} }
ExprKind::Unary(op, ref ohs) => { ExprKind::Unary(op, ohs) => {
let op = self.lower_unop(op); let op = self.lower_unop(*op);
let ohs = self.lower_expr(ohs); let ohs = self.lower_expr(ohs);
hir::ExprKind::Unary(op, ohs) hir::ExprKind::Unary(op, ohs)
} }
ExprKind::Lit(ref l) => { ExprKind::Lit(token_lit) => {
hir::ExprKind::Lit(respan(self.lower_span(l.span), l.kind.clone())) 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 expr = self.lower_expr(expr);
let ty = let ty =
self.lower_ty(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Type)); self.lower_ty(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Type));
hir::ExprKind::Cast(expr, ty) hir::ExprKind::Cast(expr, ty)
} }
ExprKind::Type(ref expr, ref ty) => { ExprKind::Type(expr, ty) => {
let expr = self.lower_expr(expr); let expr = self.lower_expr(expr);
let ty = let ty =
self.lower_ty(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Type)); self.lower_ty(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Type));
hir::ExprKind::Type(expr, ty) hir::ExprKind::Type(expr, ty)
} }
ExprKind::AddrOf(k, m, ref ohs) => { ExprKind::AddrOf(k, m, ohs) => {
let ohs = self.lower_expr(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::ExprKind::Let(self.arena.alloc(hir::Let {
hir_id: self.next_id(), hir_id: self.next_id(),
span: self.lower_span(span), span: self.lower_span(*span),
pat: self.lower_pat(pat), pat: self.lower_pat(pat),
ty: None, ty: None,
init: self.lower_expr(scrutinee), 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()) self.lower_expr_if(cond, then, else_opt.as_deref())
} }
ExprKind::While(ref cond, ref body, opt_label) => { ExprKind::While(cond, body, opt_label) => self.with_loop_scope(e.id, |this| {
self.with_loop_scope(e.id, |this| { let span = this.mark_span_with_reason(DesugaringKind::WhileLoop, e.span, None);
let span = this.lower_expr_while_in_loop_scope(span, cond, body, *opt_label)
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| {
})
}
ExprKind::Loop(ref body, opt_label) => self.with_loop_scope(e.id, |this| {
hir::ExprKind::Loop( hir::ExprKind::Loop(
this.lower_block(body, false), this.lower_block(body, false),
this.lower_label(opt_label), this.lower_label(*opt_label),
hir::LoopSource::Loop, hir::LoopSource::Loop,
DUMMY_SP, this.lower_span(*span),
) )
}), }),
ExprKind::TryBlock(ref body) => self.lower_expr_try_block(body), ExprKind::TryBlock(body) => self.lower_expr_try_block(body),
ExprKind::Match(ref expr, ref arms) => hir::ExprKind::Match( ExprKind::Match(expr, arms) => hir::ExprKind::Match(
self.lower_expr(expr), self.lower_expr(expr),
self.arena.alloc_from_iter(arms.iter().map(|x| self.lower_arm(x))), self.arena.alloc_from_iter(arms.iter().map(|x| self.lower_arm(x))),
hir::MatchSource::Normal, hir::MatchSource::Normal,
), ),
ExprKind::Async(capture_clause, closure_node_id, ref block) => self ExprKind::Async(capture_clause, closure_node_id, block) => self.make_async_expr(
.make_async_expr( *capture_clause,
capture_clause, None,
closure_node_id, *closure_node_id,
None, None,
block.span, e.span,
hir::AsyncGeneratorKind::Block, hir::AsyncGeneratorKind::Block,
|this| this.with_new_scopes(|this| this.lower_block_expr(block)), |this| this.with_new_scopes(|this| this.lower_block_expr(block)),
), ),
ExprKind::Await(ref expr) => { ExprKind::Await(expr) => {
let dot_await_span = if expr.span.hi() < e.span.hi() { let dot_await_span = if expr.span.hi() < e.span.hi() {
let span_with_whitespace = self let span_with_whitespace = self
.tcx .tcx
@ -160,66 +169,67 @@ impl<'hir> LoweringContext<'_, 'hir> {
}; };
self.lower_expr_await(dot_await_span, expr) self.lower_expr_await(dot_await_span, expr)
} }
ExprKind::Closure( ExprKind::Closure(box Closure {
ref binder, binder,
capture_clause, capture_clause,
asyncness, asyncness,
movability, movability,
ref decl, fn_decl,
ref body, body,
fn_decl_span, fn_decl_span,
) => { fn_arg_span,
}) => {
if let Async::Yes { closure_id, .. } = asyncness { if let Async::Yes { closure_id, .. } = asyncness {
self.lower_expr_async_closure( self.lower_expr_async_closure(
binder, binder,
capture_clause, *capture_clause,
e.id, e.id,
closure_id, *closure_id,
decl, fn_decl,
body, body,
fn_decl_span, *fn_decl_span,
*fn_arg_span,
) )
} else { } else {
self.lower_expr_closure( self.lower_expr_closure(
binder, binder,
capture_clause, *capture_clause,
e.id, e.id,
movability, *movability,
decl, fn_decl,
body, body,
fn_decl_span, *fn_decl_span,
*fn_arg_span,
) )
} }
} }
ExprKind::Block(ref blk, opt_label) => { ExprKind::Block(blk, opt_label) => {
let opt_label = self.lower_label(opt_label); let opt_label = self.lower_label(*opt_label);
hir::ExprKind::Block(self.lower_block(blk, opt_label.is_some()), opt_label) hir::ExprKind::Block(self.lower_block(blk, opt_label.is_some()), opt_label)
} }
ExprKind::Assign(ref el, ref er, span) => { ExprKind::Assign(el, er, span) => self.lower_expr_assign(el, er, *span, e.span),
self.lower_expr_assign(el, er, span, e.span) ExprKind::AssignOp(op, el, er) => hir::ExprKind::AssignOp(
} self.lower_binop(*op),
ExprKind::AssignOp(op, ref el, ref er) => hir::ExprKind::AssignOp(
self.lower_binop(op),
self.lower_expr(el), self.lower_expr(el),
self.lower_expr(er), self.lower_expr(er),
), ),
ExprKind::Field(ref el, ident) => { ExprKind::Field(el, ident) => {
hir::ExprKind::Field(self.lower_expr(el), self.lower_ident(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)) 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) self.lower_expr_range_closed(e.span, e1, e2)
} }
ExprKind::Range(ref e1, ref e2, lims) => { ExprKind::Range(e1, e2, lims) => {
self.lower_expr_range(e.span, e1.as_deref(), e2.as_deref(), lims) self.lower_expr_range(e.span, e1.as_deref(), e2.as_deref(), *lims)
} }
ExprKind::Underscore => { ExprKind::Underscore => {
self.tcx.sess.emit_err(UnderscoreExprLhsAssign { span: e.span }); self.tcx.sess.emit_err(UnderscoreExprLhsAssign { span: e.span });
hir::ExprKind::Err hir::ExprKind::Err
} }
ExprKind::Path(ref qself, ref path) => { ExprKind::Path(qself, path) => {
let qpath = self.lower_qpath( let qpath = self.lower_qpath(
e.id, e.id,
qself, qself,
@ -229,22 +239,22 @@ impl<'hir> LoweringContext<'_, 'hir> {
); );
hir::ExprKind::Path(qpath) 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)); 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) => { 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)); let e = e.as_ref().map(|x| self.lower_expr(x));
hir::ExprKind::Ret(e) hir::ExprKind::Ret(e)
} }
ExprKind::Yeet(ref sub_expr) => self.lower_expr_yeet(e.span, sub_expr.as_deref()), ExprKind::Yeet(sub_expr) => self.lower_expr_yeet(e.span, sub_expr.as_deref()),
ExprKind::InlineAsm(ref asm) => { ExprKind::InlineAsm(asm) => {
hir::ExprKind::InlineAsm(self.lower_inline_asm(e.span, asm)) hir::ExprKind::InlineAsm(self.lower_inline_asm(e.span, asm))
} }
ExprKind::Struct(ref se) => { ExprKind::Struct(se) => {
let rest = match &se.rest { let rest = match &se.rest {
StructRest::Base(e) => Some(self.lower_expr(e)), StructRest::Base(e) => Some(self.lower_expr(e)),
StructRest::Rest(sp) => { StructRest::Rest(sp) => {
@ -266,10 +276,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
rest, 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::Err => hir::ExprKind::Err,
ExprKind::Try(ref sub_expr) => self.lower_expr_try(e.span, sub_expr), ExprKind::Try(sub_expr) => self.lower_expr_try(e.span, sub_expr),
ExprKind::Paren(ref ex) => { ExprKind::Paren(ex) => {
let mut ex = self.lower_expr_mut(ex); let mut ex = self.lower_expr_mut(ex);
// Include parens in span, but only if it is a super-span. // Include parens in span, but only if it is a super-span.
if e.span.contains(ex.span) { if e.span.contains(ex.span) {
@ -294,8 +304,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
// Desugar `ExprForLoop` // Desugar `ExprForLoop`
// from: `[opt_ident]: for <pat> in <head> <body>` // from: `[opt_ident]: for <pat> in <head> <body>`
ExprKind::ForLoop(ref pat, ref head, ref body, opt_label) => { ExprKind::ForLoop(pat, head, body, opt_label) => {
return self.lower_expr_for(e, 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), ExprKind::MacCall(_) => panic!("{:?} shouldn't exist here", e.span),
}; };
@ -346,7 +356,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
args: Vec<AstP<Expr>>, args: Vec<AstP<Expr>>,
legacy_args_idx: &[usize], legacy_args_idx: &[usize],
) -> hir::ExprKind<'hir> { ) -> hir::ExprKind<'hir> {
let ExprKind::Path(None, ref mut path) = f.kind else { let ExprKind::Path(None, path) = &mut f.kind else {
unreachable!(); unreachable!();
}; };
@ -359,7 +369,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let node_id = self.next_node_id(); let node_id = self.next_node_id();
// Add a definition for the in-band const def. // 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 }; let anon_const = AnonConst { id: node_id, value: arg };
generic_args.push(AngleBracketedArg::Arg(GenericArg::Const(anon_const))); generic_args.push(AngleBracketedArg::Arg(GenericArg::Const(anon_const)));
@ -426,18 +436,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
let lhs = self.lower_cond(lhs); let lhs = self.lower_cond(lhs);
let rhs = self.lower_cond(rhs); let rhs = self.lower_cond(rhs);
self.arena.alloc(self.expr( self.arena.alloc(self.expr(cond.span, hir::ExprKind::Binary(op, lhs, rhs)))
cond.span,
hir::ExprKind::Binary(op, lhs, rhs),
AttrVec::new(),
))
} }
ExprKind::Let(..) => self.lower_expr(cond), ExprKind::Let(..) => self.lower_expr(cond),
_ => { _ => {
let cond = self.lower_expr(cond); let cond = self.lower_expr(cond);
let reason = DesugaringKind::CondTemporary; let reason = DesugaringKind::CondTemporary;
let span_block = self.mark_span_with_reason(reason, cond.span, None); 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> { ) -> hir::ExprKind<'hir> {
let lowered_cond = self.with_loop_condition_scope(|t| t.lower_cond(cond)); let lowered_cond = self.with_loop_condition_scope(|t| t.lower_cond(cond));
let then = self.lower_block_expr(body); 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 stmt_break = self.stmt_expr(span, expr_break);
let else_blk = self.block_all(span, arena_vec![self; stmt_break], None); 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_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 block = self.block_expr(self.arena.alloc(if_expr));
let span = self.lower_span(span.with_hi(cond.span.hi())); let span = self.lower_span(span.with_hi(cond.span.hi()));
let opt_label = self.lower_label(opt_label); let opt_label = self.lower_label(opt_label);
@ -528,22 +534,17 @@ impl<'hir> LoweringContext<'_, 'hir> {
expr: &'hir hir::Expr<'hir>, expr: &'hir hir::Expr<'hir>,
overall_span: Span, overall_span: Span,
) -> &'hir hir::Expr<'hir> { ) -> &'hir hir::Expr<'hir> {
let constructor = self.arena.alloc(self.expr_lang_item_path( let constructor = self.arena.alloc(self.expr_lang_item_path(method_span, lang_item, None));
method_span,
lang_item,
AttrVec::new(),
None,
));
self.expr_call(overall_span, constructor, std::slice::from_ref(expr)) self.expr_call(overall_span, constructor, std::slice::from_ref(expr))
} }
fn lower_arm(&mut self, arm: &Arm) -> hir::Arm<'hir> { fn lower_arm(&mut self, arm: &Arm) -> hir::Arm<'hir> {
let pat = self.lower_pat(&arm.pat); let pat = self.lower_pat(&arm.pat);
let guard = arm.guard.as_ref().map(|cond| { 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::Guard::IfLet(self.arena.alloc(hir::Let {
hir_id: self.next_id(), hir_id: self.next_id(),
span: self.lower_span(span), span: self.lower_span(*span),
pat: self.lower_pat(pat), pat: self.lower_pat(pat),
ty: None, ty: None,
init: self.lower_expr(scrutinee), 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: /// This results in:
/// ///
/// ```text /// ```text
/// std::future::from_generator(static move? |_task_context| -> <ret_ty> { /// std::future::identity_future(static move? |_task_context| -> <ret_ty> {
/// <body> /// <body>
/// }) /// })
/// ``` /// ```
pub(super) fn make_async_expr( pub(super) fn make_async_expr(
&mut self, &mut self,
capture_clause: CaptureBy, capture_clause: CaptureBy,
outer_hir_id: Option<hir::HirId>,
closure_node_id: NodeId, closure_node_id: NodeId,
ret_ty: Option<AstP<Ty>>, ret_ty: Option<hir::FnRetTy<'hir>>,
span: Span, span: Span,
async_gen_kind: hir::AsyncGeneratorKind, async_gen_kind: hir::AsyncGeneratorKind,
body: impl FnOnce(&mut Self) -> hir::Expr<'hir>, body: impl FnOnce(&mut Self) -> hir::Expr<'hir>,
) -> hir::ExprKind<'hir> { ) -> hir::ExprKind<'hir> {
let output = match ret_ty { let output = ret_ty.unwrap_or_else(|| hir::FnRetTy::DefaultReturn(self.lower_span(span)));
Some(ty) => hir::FnRetTy::Return(
self.lower_ty(&ty, &ImplTraitContext::Disallowed(ImplTraitPosition::AsyncBlock)),
),
None => hir::FnRetTy::DefaultReturn(self.lower_span(span)),
};
// Resume argument type. We let the compiler infer this to simplify the lowering. It is // Resume argument type: `ResumeTy`
// fully constrained by `future::from_generator`. 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 { let input_ty = hir::Ty {
hir_id: self.next_id(), hir_id: self.next_id(),
kind: hir::TyKind::Infer, kind: hir::TyKind::Path(resume_ty),
span: self.lower_span(span), span: unstable_span,
}; };
// The closure/generator `FnDecl` takes a single (resume) argument of type `input_ty`. // The closure/generator `FnDecl` takes a single (resume) argument of type `input_ty`.
@ -602,6 +601,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
output, output,
c_variadic: false, c_variadic: false,
implicit_self: hir::ImplicitSelfKind::None, implicit_self: hir::ImplicitSelfKind::None,
lifetime_elision_allowed: false,
}); });
// Lower the argument pattern/ident. The ident is used again in the `.await` lowering. // 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 }`: // `static |_task_context| -> <ret_ty> { body }`:
let generator_kind = { let generator_kind = {
let c = self.arena.alloc(hir::Closure { let c = self.arena.alloc(hir::Closure {
def_id: self.local_def_id(closure_node_id),
binder: hir::ClosureBinder::Default, binder: hir::ClosureBinder::Default,
capture_clause, capture_clause,
bound_generic_params: &[], bound_generic_params: &[],
fn_decl, fn_decl,
body, body,
fn_decl_span: self.lower_span(span), fn_decl_span: self.lower_span(span),
fn_arg_span: None,
movability: Some(hir::Movability::Static), movability: Some(hir::Movability::Static),
}); });
hir::ExprKind::Closure(c) 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 = let unstable_span =
self.mark_span_with_reason(DesugaringKind::Async, span, self.allow_gen_future.clone()); 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)`: if self.tcx.features().closure_track_caller
hir::ExprKind::Call(self.arena.alloc(gen_future), arena_vec![self; generator]) && 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: /// 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 break_x = self.with_loop_scope(loop_node_id, move |this| {
let expr_break = let expr_break =
hir::ExprKind::Break(this.lower_loop_destination(None), Some(x_expr)); 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) self.arm(ready_pat, break_x)
}; };
@ -792,17 +820,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
let yield_expr = self.expr( let yield_expr = self.expr(
span, span,
hir::ExprKind::Yield(unit, hir::YieldSource::Await { expr: Some(expr_hir_id) }), hir::ExprKind::Yield(unit, hir::YieldSource::Await { expr: Some(expr_hir_id) }),
AttrVec::new(),
); );
let yield_expr = self.arena.alloc(yield_expr); let yield_expr = self.arena.alloc(yield_expr);
if let Some(task_context_hid) = self.task_context { if let Some(task_context_hid) = self.task_context {
let lhs = self.expr_ident(span, task_context_ident, task_context_hid); let lhs = self.expr_ident(span, task_context_ident, task_context_hid);
let assign = self.expr( let assign =
span, self.expr(span, hir::ExprKind::Assign(lhs, yield_expr, self.lower_span(span)));
hir::ExprKind::Assign(lhs, yield_expr, self.lower_span(span)),
AttrVec::new(),
);
self.stmt_expr(span, assign) self.stmt_expr(span, assign)
} else { } else {
// Use of `await` outside of an async context. Return `yield_expr` so that we can // 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, decl: &FnDecl,
body: &Expr, body: &Expr,
fn_decl_span: Span, fn_decl_span: Span,
fn_arg_span: Span,
) -> hir::ExprKind<'hir> { ) -> hir::ExprKind<'hir> {
let (binder_clause, generic_params) = self.lower_closure_binder(binder); 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); let bound_generic_params = self.lower_lifetime_binder(closure_id, generic_params);
// Lower outside new scope to preserve `is_in_loop_condition`. // 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 { let c = self.arena.alloc(hir::Closure {
def_id: self.local_def_id(closure_id),
binder: binder_clause, binder: binder_clause,
capture_clause, capture_clause,
bound_generic_params, bound_generic_params,
fn_decl, fn_decl,
body: body_id, body: body_id,
fn_decl_span: self.lower_span(fn_decl_span), fn_decl_span: self.lower_span(fn_decl_span),
fn_arg_span: Some(self.lower_span(fn_arg_span)),
movability: generator_option, movability: generator_option,
}); });
@ -927,8 +954,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
) -> (hir::ClosureBinder, &'c [GenericParam]) { ) -> (hir::ClosureBinder, &'c [GenericParam]) {
let (binder, params) = match binder { let (binder, params) = match binder {
ClosureBinder::NotPresent => (hir::ClosureBinder::Default, &[][..]), ClosureBinder::NotPresent => (hir::ClosureBinder::Default, &[][..]),
&ClosureBinder::For { span, ref generic_params } => { ClosureBinder::For { span, generic_params } => {
let span = self.lower_span(span); let span = self.lower_span(*span);
(hir::ClosureBinder::For { span }, &**generic_params) (hir::ClosureBinder::For { span }, &**generic_params)
} }
}; };
@ -945,6 +972,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
decl: &FnDecl, decl: &FnDecl,
body: &Expr, body: &Expr,
fn_decl_span: Span, fn_decl_span: Span,
fn_arg_span: Span,
) -> hir::ExprKind<'hir> { ) -> hir::ExprKind<'hir> {
if let &ClosureBinder::For { span, .. } = binder { if let &ClosureBinder::For { span, .. } = binder {
self.tcx.sess.emit_err(NotSupportedForLifetimeBinderAsyncClosure { span }); self.tcx.sess.emit_err(NotSupportedForLifetimeBinderAsyncClosure { span });
@ -962,19 +990,27 @@ impl<'hir> LoweringContext<'_, 'hir> {
} }
// Transform `async |x: u8| -> X { ... }` into // 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 body_id = this.lower_fn_body(&outer_decl, |this| {
let async_ret_ty = let async_ret_ty = if let FnRetTy::Ty(ty) = &decl.output {
if let FnRetTy::Ty(ty) = &decl.output { Some(ty.clone()) } else { None }; let itctx = ImplTraitContext::Disallowed(ImplTraitPosition::AsyncBlock);
Some(hir::FnRetTy::Return(this.lower_ty(&ty, &itctx)))
} else {
None
};
let async_body = this.make_async_expr( let async_body = this.make_async_expr(
capture_clause, 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, inner_closure_id,
async_ret_ty, async_ret_ty,
body.span, body.span,
hir::AsyncGeneratorKind::Closure, hir::AsyncGeneratorKind::Closure,
|this| this.with_new_scopes(|this| this.lower_expr_mut(body)), |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 body_id
}); });
@ -984,15 +1020,17 @@ impl<'hir> LoweringContext<'_, 'hir> {
// have to conserve the state of being inside a loop condition for the // have to conserve the state of being inside a loop condition for the
// closure argument types. // closure argument types.
let fn_decl = 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 { let c = self.arena.alloc(hir::Closure {
def_id: self.local_def_id(closure_id),
binder: binder_clause, binder: binder_clause,
capture_clause, capture_clause,
bound_generic_params, bound_generic_params,
fn_decl, fn_decl,
body, body,
fn_decl_span: self.lower_span(fn_decl_span), fn_decl_span: self.lower_span(fn_decl_span),
fn_arg_span: Some(self.lower_span(fn_arg_span)),
movability: None, movability: None,
}); });
hir::ExprKind::Closure(c) hir::ExprKind::Closure(c)
@ -1065,7 +1103,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
fn extract_tuple_struct_path<'a>( fn extract_tuple_struct_path<'a>(
&mut self, &mut self,
expr: &'a Expr, expr: &'a Expr,
) -> Option<(&'a Option<QSelf>, &'a Path)> { ) -> Option<(&'a Option<AstP<QSelf>>, &'a Path)> {
if let ExprKind::Path(qself, path) = &expr.kind { if let ExprKind::Path(qself, path) = &expr.kind {
// Does the path resolve to something disallowed in a tuple struct/variant pattern? // 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) { 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>( fn extract_unit_struct_path<'a>(
&mut self, &mut self,
expr: &'a Expr, expr: &'a Expr,
) -> Option<(&'a Option<QSelf>, &'a Path)> { ) -> Option<(&'a Option<AstP<QSelf>>, &'a Path)> {
if let ExprKind::Path(qself, path) = &expr.kind { if let ExprKind::Path(qself, path) = &expr.kind {
// Does the path resolve to something disallowed in a unit struct/variant pattern? // 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) { 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 ident = self.expr_ident(lhs.span, ident, binding);
let assign = let assign =
hir::ExprKind::Assign(self.lower_expr(lhs), ident, self.lower_span(eq_sign_span)); 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)); assignments.push(self.stmt_expr(lhs.span, expr));
pat pat
} }
@ -1273,8 +1311,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let e2 = self.lower_expr_mut(e2); let e2 = self.lower_expr_mut(e2);
let fn_path = let fn_path =
hir::QPath::LangItem(hir::LangItem::RangeInclusiveNew, self.lower_span(span), None); hir::QPath::LangItem(hir::LangItem::RangeInclusiveNew, self.lower_span(span), None);
let fn_expr = let fn_expr = self.arena.alloc(self.expr(span, hir::ExprKind::Path(fn_path)));
self.arena.alloc(self.expr(span, hir::ExprKind::Path(fn_path), AttrVec::new()));
hir::ExprKind::Call(fn_expr, arena_vec![self; e1, e2]) hir::ExprKind::Call(fn_expr, arena_vec![self; e1, e2])
} }
@ -1446,8 +1483,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
// `None => break` // `None => break`
let none_arm = { let none_arm = {
let break_expr = let break_expr = self.with_loop_scope(e.id, |this| this.expr_break_alloc(for_span));
self.with_loop_scope(e.id, |this| this.expr_break_alloc(for_span, AttrVec::new()));
let pat = self.pat_none(for_span); let pat = self.pat_none(for_span);
self.arm(pat, break_expr) self.arm(pat, break_expr)
}; };
@ -1456,7 +1492,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let some_arm = { let some_arm = {
let some_pat = self.pat_some(pat_span, pat); 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_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) 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. // surrounding scope of the `match` since the `match` is not a terminating scope.
// //
// Also, add the attributes to the outer returned expr node. // 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: /// Desugar `ExprKind::Try` from: `<expr>?` into:
@ -1561,28 +1599,21 @@ impl<'hir> LoweringContext<'_, 'hir> {
}; };
// `#[allow(unreachable_code)]` // `#[allow(unreachable_code)]`
let attr = { let attr = attr::mk_attr_nested_word(
// `allow(unreachable_code)` &self.tcx.sess.parse_sess.attr_id_generator,
let allow = { AttrStyle::Outer,
let allow_ident = Ident::new(sym::allow, self.lower_span(span)); sym::allow,
let uc_ident = Ident::new(sym::unreachable_code, self.lower_span(span)); sym::unreachable_code,
let uc_nested = attr::mk_nested_word_item(uc_ident); self.lower_span(span),
attr::mk_list_item(allow_ident, vec![uc_nested]) );
};
attr::mk_attr_outer(&self.tcx.sess.parse_sess.attr_id_generator, allow)
};
let attrs: AttrVec = thin_vec![attr]; let attrs: AttrVec = thin_vec![attr];
// `ControlFlow::Continue(val) => #[allow(unreachable_code)] val,` // `ControlFlow::Continue(val) => #[allow(unreachable_code)] val,`
let continue_arm = { let continue_arm = {
let val_ident = Ident::with_dummy_span(sym::val); let val_ident = Ident::with_dummy_span(sym::val);
let (val_pat, val_pat_nid) = self.pat_ident(span, val_ident); let (val_pat, val_pat_nid) = self.pat_ident(span, val_ident);
let val_expr = self.arena.alloc(self.expr_ident_with_attrs( let val_expr = self.expr_ident(span, val_ident, val_pat_nid);
span, self.lower_attrs(val_expr.hir_id, &attrs);
val_ident,
val_pat_nid,
attrs.clone(),
));
let continue_pat = self.pat_cf_continue(unstable_span, val_pat); let continue_pat = self.pat_cf_continue(unstable_span, val_pat);
self.arm(continue_pat, val_expr) self.arm(continue_pat, val_expr)
}; };
@ -1608,15 +1639,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
hir::Destination { label: None, target_id }, hir::Destination { label: None, target_id },
Some(from_residual_expr), Some(from_residual_expr),
), ),
attrs,
)) ))
} else { } else {
self.arena.alloc(self.expr( self.arena.alloc(self.expr(try_span, hir::ExprKind::Ret(Some(from_residual_expr))))
try_span,
hir::ExprKind::Ret(Some(from_residual_expr)),
attrs,
))
}; };
self.lower_attrs(ret_expr.hir_id, &attrs);
let break_pat = self.pat_cf_break(try_span, residual_local); let break_pat = self.pat_cf_break(try_span, residual_local);
self.arm(break_pat, ret_expr) self.arm(break_pat, ret_expr)
@ -1681,18 +1708,16 @@ impl<'hir> LoweringContext<'_, 'hir> {
&mut self, &mut self,
span: Span, span: Span,
expr: &'hir hir::Expr<'hir>, expr: &'hir hir::Expr<'hir>,
attrs: AttrVec,
) -> &'hir hir::Expr<'hir> { ) -> &'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( pub(super) fn expr_drop_temps_mut(
&mut self, &mut self,
span: Span, span: Span,
expr: &'hir hir::Expr<'hir>, expr: &'hir hir::Expr<'hir>,
attrs: AttrVec,
) -> hir::Expr<'hir> { ) -> hir::Expr<'hir> {
self.expr(span, hir::ExprKind::DropTemps(expr), attrs) self.expr(span, hir::ExprKind::DropTemps(expr))
} }
fn expr_match( fn expr_match(
@ -1702,29 +1727,25 @@ impl<'hir> LoweringContext<'_, 'hir> {
arms: &'hir [hir::Arm<'hir>], arms: &'hir [hir::Arm<'hir>],
source: hir::MatchSource, source: hir::MatchSource,
) -> hir::Expr<'hir> { ) -> 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); 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> { fn expr_break_alloc(&mut self, span: Span) -> &'hir hir::Expr<'hir> {
let expr_break = self.expr_break(span, attrs); let expr_break = self.expr_break(span);
self.arena.alloc(expr_break) self.arena.alloc(expr_break)
} }
fn expr_mut_addr_of(&mut self, span: Span, e: &'hir hir::Expr<'hir>) -> hir::Expr<'hir> { fn expr_mut_addr_of(&mut self, span: Span, e: &'hir hir::Expr<'hir>) -> hir::Expr<'hir> {
self.expr( self.expr(span, hir::ExprKind::AddrOf(hir::BorrowKind::Ref, hir::Mutability::Mut, e))
span,
hir::ExprKind::AddrOf(hir::BorrowKind::Ref, hir::Mutability::Mut, e),
AttrVec::new(),
)
} }
fn expr_unit(&mut self, sp: Span) -> &'hir hir::Expr<'hir> { 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( fn expr_call_mut(
@ -1733,7 +1754,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
e: &'hir hir::Expr<'hir>, e: &'hir hir::Expr<'hir>,
args: &'hir [hir::Expr<'hir>], args: &'hir [hir::Expr<'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( fn expr_call(
@ -1752,8 +1773,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
args: &'hir [hir::Expr<'hir>], args: &'hir [hir::Expr<'hir>],
hir_id: Option<hir::HirId>, hir_id: Option<hir::HirId>,
) -> hir::Expr<'hir> { ) -> hir::Expr<'hir> {
let path = let path = self.arena.alloc(self.expr_lang_item_path(span, lang_item, hir_id));
self.arena.alloc(self.expr_lang_item_path(span, lang_item, AttrVec::new(), hir_id));
self.expr_call_mut(span, path, args) self.expr_call_mut(span, path, args)
} }
@ -1771,13 +1791,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
&mut self, &mut self,
span: Span, span: Span,
lang_item: hir::LangItem, lang_item: hir::LangItem,
attrs: AttrVec,
hir_id: Option<hir::HirId>, hir_id: Option<hir::HirId>,
) -> hir::Expr<'hir> { ) -> hir::Expr<'hir> {
self.expr( self.expr(
span, span,
hir::ExprKind::Path(hir::QPath::LangItem(lang_item, self.lower_span(span), hir_id)), 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( 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, &mut self,
span: Span, span: Span,
ident: Ident, ident: Ident,
binding: hir::HirId, binding: hir::HirId,
attrs: AttrVec,
) -> hir::Expr<'hir> { ) -> hir::Expr<'hir> {
let hir_id = self.next_id(); let hir_id = self.next_id();
let res = Res::Local(binding); 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> { fn expr_unsafe(&mut self, expr: &'hir hir::Expr<'hir>) -> hir::Expr<'hir> {
@ -1836,32 +1844,21 @@ impl<'hir> LoweringContext<'_, 'hir> {
}), }),
None, None,
), ),
AttrVec::new(),
) )
} }
fn expr_block_empty(&mut self, span: Span) -> &'hir hir::Expr<'hir> { fn expr_block_empty(&mut self, span: Span) -> &'hir hir::Expr<'hir> {
let blk = self.block_all(span, &[], None); 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) self.arena.alloc(expr)
} }
pub(super) fn expr_block( pub(super) fn expr_block(&mut self, b: &'hir hir::Block<'hir>) -> hir::Expr<'hir> {
&mut self, self.expr(b.span, hir::ExprKind::Block(b, None))
b: &'hir hir::Block<'hir>,
attrs: AttrVec,
) -> hir::Expr<'hir> {
self.expr(b.span, hir::ExprKind::Block(b, None), attrs)
} }
pub(super) fn expr( pub(super) fn expr(&mut self, span: Span, kind: hir::ExprKind<'hir>) -> hir::Expr<'hir> {
&mut self,
span: Span,
kind: hir::ExprKind<'hir>,
attrs: AttrVec,
) -> hir::Expr<'hir> {
let hir_id = self.next_id(); let hir_id = self.next_id();
self.lower_attrs(hir_id, &attrs);
hir::Expr { hir_id, kind, span: self.lower_span(span) } hir::Expr { hir_id, kind, span: self.lower_span(span) }
} }

View File

@ -77,7 +77,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
if hir_id.owner != self.owner { if hir_id.owner != self.owner {
span_bug!( span_bug!(
span, span,
"inconsistent DepNode at `{:?}` for `{:?}`: \ "inconsistent HirId at `{:?}` for `{:?}`: \
current_dep_node_owner={} ({:?}), hir_id.owner={} ({:?})", current_dep_node_owner={} ({:?}), hir_id.owner={} ({:?})",
self.source_map.span_to_diagnostic_string(span), self.source_map.span_to_diagnostic_string(span),
node, node,
@ -145,7 +145,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
fn visit_item(&mut self, i: &'hir Item<'hir>) { fn visit_item(&mut self, i: &'hir Item<'hir>) {
debug_assert_eq!(i.owner_id, self.owner); debug_assert_eq!(i.owner_id, self.owner);
self.with_parent(i.hir_id(), |this| { 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 this is a tuple or unit-like struct, register the constructor.
if let Some(ctor_hir_id) = struct_def.ctor_hir_id() { if let Some(ctor_hir_id) = struct_def.ctor_hir_id() {
this.insert(i.span, ctor_hir_id, Node::Ctor(struct_def)); 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) { 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>) { fn visit_variant(&mut self, v: &'hir Variant<'hir>) {
self.insert(v.span, v.id, Node::Variant(v)); self.insert(v.span, v.hir_id, Node::Variant(v));
self.with_parent(v.id, |this| { self.with_parent(v.hir_id, |this| {
// Register the constructor of this variant. // Register the constructor of this variant.
if let Some(ctor_hir_id) = v.data.ctor_hir_id() { if let Some(ctor_hir_id) = v.data.ctor_hir_id() {
this.insert(v.span, ctor_hir_id, Node::Ctor(&v.data)); this.insert(v.span, ctor_hir_id, Node::Ctor(&v.data));

View File

@ -6,7 +6,6 @@ use super::{FnDeclKind, LoweringContext, ParamMode};
use rustc_ast::ptr::P; use rustc_ast::ptr::P;
use rustc_ast::visit::AssocCtxt; use rustc_ast::visit::AssocCtxt;
use rustc_ast::*; use rustc_ast::*;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::sorted_map::SortedMap; use rustc_data_structures::sorted_map::SortedMap;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res}; use rustc_hir::def::{DefKind, Res};
@ -20,8 +19,7 @@ use rustc_span::symbol::{kw, sym, Ident};
use rustc_span::{Span, Symbol}; use rustc_span::{Span, Symbol};
use rustc_target::spec::abi; use rustc_target::spec::abi;
use smallvec::{smallvec, SmallVec}; use smallvec::{smallvec, SmallVec};
use thin_vec::ThinVec;
use std::iter;
pub(super) struct ItemLowerer<'a, 'hir> { pub(super) struct ItemLowerer<'a, 'hir> {
pub(super) tcx: TyCtxt<'hir>, pub(super) tcx: TyCtxt<'hir>,
@ -67,7 +65,7 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
// HirId handling. // HirId handling.
bodies: Vec::new(), bodies: Vec::new(),
attrs: SortedMap::default(), attrs: SortedMap::default(),
children: FxHashMap::default(), children: Vec::default(),
current_hir_id_owner: hir::CRATE_OWNER_ID, current_hir_id_owner: hir::CRATE_OWNER_ID,
item_local_id_counter: hir::ItemLocalId::new(0), item_local_id_counter: hir::ItemLocalId::new(0),
node_id_to_local_id: Default::default(), node_id_to_local_id: Default::default(),
@ -86,7 +84,7 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
impl_trait_defs: Vec::new(), impl_trait_defs: Vec::new(),
impl_trait_bounds: Vec::new(), impl_trait_bounds: Vec::new(),
allow_try_trait: Some([sym::try_trait_v2, sym::yeet_desugar_details][..].into()), 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()), allow_into_future: Some([sym::into_future][..].into()),
generics_def_id_map: Default::default(), 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, // This is used to track which lifetimes have already been defined,
// and which need to be replicated when lowering an async fn. // and which need to be replicated when lowering an async fn.
match parent_hir.node().expect_item().kind { 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(); 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]> { pub(super) fn lower_item_ref(&mut self, i: &Item) -> SmallVec<[hir::ItemId; 1]> {
let mut node_ids = let mut node_ids =
smallvec![hir::ItemId { owner_id: hir::OwnerId { def_id: self.local_def_id(i.id) } }]; smallvec![hir::ItemId { owner_id: hir::OwnerId { def_id: self.local_def_id(i.id) } }];
if let ItemKind::Use(ref use_tree) = &i.kind { if let ItemKind::Use(use_tree) = &i.kind {
self.lower_item_id_use_tree(use_tree, i.id, &mut node_ids); self.lower_item_id_use_tree(use_tree, &mut node_ids);
} }
node_ids node_ids
} }
fn lower_item_id_use_tree( fn lower_item_id_use_tree(&mut self, tree: &UseTree, vec: &mut SmallVec<[hir::ItemId; 1]>) {
&mut self, match &tree.kind {
tree: &UseTree, UseTreeKind::Nested(nested_vec) => {
base_id: NodeId,
vec: &mut SmallVec<[hir::ItemId; 1]>,
) {
match tree.kind {
UseTreeKind::Nested(ref nested_vec) => {
for &(ref nested, id) in nested_vec { for &(ref nested, id) in nested_vec {
vec.push(hir::ItemId { vec.push(hir::ItemId {
owner_id: hir::OwnerId { def_id: self.local_def_id(id) }, owner_id: hir::OwnerId { def_id: self.local_def_id(id) },
}); });
self.lower_item_id_use_tree(nested, id, vec); self.lower_item_id_use_tree(nested, 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) },
});
} }
} }
UseTreeKind::Simple(..) | UseTreeKind::Glob => {}
} }
} }
@ -239,26 +223,26 @@ impl<'hir> LoweringContext<'_, 'hir> {
vis_span: Span, vis_span: Span,
i: &ItemKind, i: &ItemKind,
) -> hir::ItemKind<'hir> { ) -> hir::ItemKind<'hir> {
match *i { match i {
ItemKind::ExternCrate(orig_name) => hir::ItemKind::ExternCrate(orig_name), ItemKind::ExternCrate(orig_name) => hir::ItemKind::ExternCrate(*orig_name),
ItemKind::Use(ref use_tree) => { ItemKind::Use(use_tree) => {
// Start with an empty prefix. // 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) 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()); 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()); let (ty, body_id) = self.lower_const_item(t, span, e.as_deref());
hir::ItemKind::Const(ty, body_id) hir::ItemKind::Const(ty, body_id)
} }
ItemKind::Fn(box Fn { ItemKind::Fn(box Fn {
sig: FnSig { ref decl, header, span: fn_sig_span }, sig: FnSig { decl, header, span: fn_sig_span },
ref generics, generics,
ref body, body,
.. ..
}) => { }) => {
self.with_new_scopes(|this| { self.with_new_scopes(|this| {
@ -269,43 +253,41 @@ impl<'hir> LoweringContext<'_, 'hir> {
// only cares about the input argument patterns in the function // only cares about the input argument patterns in the function
// declaration (decl), not the return types. // declaration (decl), not the return types.
let asyncness = header.asyncness; let asyncness = header.asyncness;
let body_id = let body_id = this.lower_maybe_async_body(
this.lower_maybe_async_body(span, &decl, asyncness, body.as_deref()); span,
hir_id,
&decl,
asyncness,
body.as_deref(),
);
let mut itctx = ImplTraitContext::Universal; let mut itctx = ImplTraitContext::Universal;
let (generics, decl) = this.lower_generics(generics, id, &mut itctx, |this| { let (generics, decl) = this.lower_generics(generics, id, &mut itctx, |this| {
let ret_id = asyncness.opt_return_id(); 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 { let sig = hir::FnSig {
decl, decl,
header: this.lower_fn_header(header), header: this.lower_fn_header(*header),
span: this.lower_span(fn_sig_span), span: this.lower_span(*fn_sig_span),
}; };
hir::ItemKind::Fn(sig, generics, body_id) hir::ItemKind::Fn(sig, generics, body_id)
}) })
} }
ItemKind::Mod(_, ref mod_kind) => match mod_kind { ItemKind::Mod(_, mod_kind) => match mod_kind {
ModKind::Loaded(items, _, spans) => { ModKind::Loaded(items, _, spans) => {
hir::ItemKind::Mod(self.lower_mod(items, spans)) hir::ItemKind::Mod(self.lower_mod(items, spans))
} }
ModKind::Unloaded => panic!("`mod` items should have been loaded by now"), 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)), abi: fm.abi.map_or(abi::Abi::FALLBACK, |abi| self.lower_abi(abi)),
items: self items: self
.arena .arena
.alloc_from_iter(fm.items.iter().map(|x| self.lower_foreign_item_ref(x))), .alloc_from_iter(fm.items.iter().map(|x| self.lower_foreign_item_ref(x))),
}, },
ItemKind::GlobalAsm(ref asm) => { ItemKind::GlobalAsm(asm) => hir::ItemKind::GlobalAsm(self.lower_inline_asm(span, asm)),
hir::ItemKind::GlobalAsm(self.lower_inline_asm(span, asm)) ItemKind::TyAlias(box TyAlias { generics, where_clauses, ty: Some(ty), .. }) => {
}
ItemKind::TyAlias(box TyAlias {
ref generics,
where_clauses,
ty: Some(ref ty),
..
}) => {
// We lower // We lower
// //
// type Foo = impl Trait // type Foo = impl Trait
@ -315,7 +297,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
// type Foo = Foo1 // type Foo = Foo1
// opaque type Foo1: Trait // opaque type Foo1: Trait
let mut generics = generics.clone(); 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( let (generics, ty) = self.lower_generics(
&generics, &generics,
id, id,
@ -324,9 +306,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
); );
hir::ItemKind::TyAlias(ty, generics) hir::ItemKind::TyAlias(ty, generics)
} }
ItemKind::TyAlias(box TyAlias { ItemKind::TyAlias(box TyAlias { generics, where_clauses, ty: None, .. }) => {
ref generics, ref where_clauses, ty: None, ..
}) => {
let mut generics = generics.clone(); 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( let (generics, ty) = self.lower_generics(
@ -337,7 +317,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
); );
hir::ItemKind::TyAlias(ty, generics) hir::ItemKind::TyAlias(ty, generics)
} }
ItemKind::Enum(ref enum_definition, ref generics) => { ItemKind::Enum(enum_definition, generics) => {
let (generics, variants) = self.lower_generics( let (generics, variants) = self.lower_generics(
generics, generics,
id, id,
@ -350,7 +330,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
); );
hir::ItemKind::Enum(hir::EnumDef { variants }, generics) 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( let (generics, struct_def) = self.lower_generics(
generics, generics,
id, id,
@ -359,7 +339,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
); );
hir::ItemKind::Struct(struct_def, generics) hir::ItemKind::Struct(struct_def, generics)
} }
ItemKind::Union(ref vdata, ref generics) => { ItemKind::Union(vdata, generics) => {
let (generics, vdata) = self.lower_generics( let (generics, vdata) = self.lower_generics(
generics, generics,
id, id,
@ -373,10 +353,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
polarity, polarity,
defaultness, defaultness,
constness, constness,
generics: ref ast_generics, generics: ast_generics,
of_trait: ref trait_ref, of_trait: trait_ref,
self_ty: ref ty, self_ty: ty,
items: ref impl_items, items: impl_items,
}) => { }) => {
// Lower the "impl header" first. This ordering is important // Lower the "impl header" first. This ordering is important
// for in-band lifetimes! Consider `'a` here: // 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 // `defaultness.has_value()` is never called for an `impl`, always `true` in order
// to not cause an assertion failure inside the `lower_defaultness` function. // to not cause an assertion failure inside the `lower_defaultness` function.
let has_val = true; 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 { let polarity = match polarity {
ImplPolarity::Positive => ImplPolarity::Positive, 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 { hir::ItemKind::Impl(self.arena.alloc(hir::Impl {
unsafety: self.lower_unsafety(unsafety), unsafety: self.lower_unsafety(*unsafety),
polarity, polarity,
defaultness, defaultness,
defaultness_span, defaultness_span,
constness: self.lower_constness(constness), constness: self.lower_constness(*constness),
generics, generics,
of_trait: trait_ref, of_trait: trait_ref,
self_ty: lowered_ty, self_ty: lowered_ty,
items: new_impl_items, items: new_impl_items,
})) }))
} }
ItemKind::Trait(box Trait { ItemKind::Trait(box Trait { is_auto, unsafety, generics, bounds, items }) => {
is_auto,
unsafety,
ref generics,
ref bounds,
ref items,
}) => {
let (generics, (unsafety, items, bounds)) = self.lower_generics( let (generics, (unsafety, items, bounds)) = self.lower_generics(
generics, generics,
id, id,
@ -450,13 +424,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
let items = this.arena.alloc_from_iter( let items = this.arena.alloc_from_iter(
items.iter().map(|item| this.lower_trait_item_ref(item)), 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) (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( let (generics, bounds) = self.lower_generics(
generics, generics,
id, id,
@ -470,10 +444,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
); );
hir::ItemKind::TraitAlias(generics, bounds) hir::ItemKind::TraitAlias(generics, bounds)
} }
ItemKind::MacroDef(MacroDef { ref body, macro_rules }) => { ItemKind::MacroDef(MacroDef { body, macro_rules }) => {
let body = P(self.lower_mac_args(body)); let body = P(self.lower_delim_args(body));
let macro_kind = self.resolver.decl_macro_kind(self.local_def_id(id)); 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(..) => { ItemKind::MacCall(..) => {
panic!("`TyMac` should have been expanded by now") 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(); let segments = prefix.segments.iter().chain(path.segments.iter()).cloned().collect();
match tree.kind { match tree.kind {
UseTreeKind::Simple(rename, id1, id2) => { UseTreeKind::Simple(rename) => {
*ident = tree.ident(); *ident = tree.ident();
// First, apply the prefix to the path. // 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(); let res =
// We want to return *something* from this function, so hold onto the first item self.expect_full_res_from_use(id).map(|res| self.lower_res(res)).collect();
// for later. let path = self.lower_use_path(res, &path, ParamMode::Explicit);
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);
hir::ItemKind::Use(path, hir::UseKind::Single) hir::ItemKind::Use(path, hir::UseKind::Single)
} }
UseTreeKind::Glob => { UseTreeKind::Glob => {
let path = self.lower_path( let res = self.expect_full_res(id);
id, let res = smallvec![self.lower_res(res)];
&Path { segments, span: path.span, tokens: None }, let path = Path { segments, span: path.span, tokens: None };
ParamMode::Explicit, let path = self.lower_use_path(res, &path, ParamMode::Explicit);
);
hir::ItemKind::Use(path, hir::UseKind::Glob) hir::ItemKind::Use(path, hir::UseKind::Glob)
} }
UseTreeKind::Nested(ref trees) => { 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 =
let res = self.lower_res(res); self.expect_full_res_from_use(id).map(|res| self.lower_res(res)).collect();
let path = self.lower_path_extra(res, &prefix, ParamMode::Explicit); let path = self.lower_use_path(res, &prefix, ParamMode::Explicit);
hir::ItemKind::Use(path, hir::UseKind::ListStem) hir::ItemKind::Use(path, hir::UseKind::ListStem)
} }
} }
@ -665,8 +589,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
let item = hir::ForeignItem { let item = hir::ForeignItem {
owner_id, owner_id,
ident: self.lower_ident(i.ident), ident: self.lower_ident(i.ident),
kind: match i.kind { kind: match &i.kind {
ForeignItemKind::Fn(box Fn { ref sig, ref generics, .. }) => { ForeignItemKind::Fn(box Fn { sig, generics, .. }) => {
let fdec = &sig.decl; let fdec = &sig.decl;
let mut itctx = ImplTraitContext::Universal; let mut itctx = ImplTraitContext::Universal;
let (generics, (fn_dec, fn_args)) = let (generics, (fn_dec, fn_args)) =
@ -675,7 +599,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
// Disallow `impl Trait` in foreign items. // Disallow `impl Trait` in foreign items.
this.lower_fn_decl( this.lower_fn_decl(
fdec, fdec,
None, i.id,
sig.span, sig.span,
FnDeclKind::ExternFn, FnDeclKind::ExternFn,
None, None,
@ -686,10 +610,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
hir::ForeignItemKind::Fn(fn_dec, fn_args, generics) hir::ForeignItemKind::Fn(fn_dec, fn_args, generics)
} }
ForeignItemKind::Static(ref t, m, _) => { ForeignItemKind::Static(t, m, _) => {
let ty = let ty =
self.lower_ty(t, &ImplTraitContext::Disallowed(ImplTraitPosition::Type)); self.lower_ty(t, &ImplTraitContext::Disallowed(ImplTraitPosition::Type));
hir::ForeignItemKind::Static(ty, m) hir::ForeignItemKind::Static(ty, *m)
} }
ForeignItemKind::TyAlias(..) => hir::ForeignItemKind::Type, ForeignItemKind::TyAlias(..) => hir::ForeignItemKind::Type,
ForeignItemKind::MacCall(_) => panic!("macro shouldn't exist here"), 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> { fn lower_variant(&mut self, v: &Variant) -> hir::Variant<'hir> {
let id = self.lower_node_id(v.id); let hir_id = self.lower_node_id(v.id);
self.lower_attrs(id, &v.attrs); self.lower_attrs(hir_id, &v.attrs);
hir::Variant { hir::Variant {
id, hir_id,
data: self.lower_variant_data(id, &v.data), 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)), disr_expr: v.disr_expr.as_ref().map(|e| self.lower_anon_const(e)),
ident: self.lower_ident(v.ident), ident: self.lower_ident(v.ident),
span: self.lower_span(v.span), span: self.lower_span(v.span),
@ -725,32 +650,33 @@ impl<'hir> LoweringContext<'_, 'hir> {
parent_id: hir::HirId, parent_id: hir::HirId,
vdata: &VariantData, vdata: &VariantData,
) -> hir::VariantData<'hir> { ) -> hir::VariantData<'hir> {
match *vdata { match vdata {
VariantData::Struct(ref fields, recovered) => hir::VariantData::Struct( VariantData::Struct(fields, recovered) => hir::VariantData::Struct(
self.arena self.arena
.alloc_from_iter(fields.iter().enumerate().map(|f| self.lower_field_def(f))), .alloc_from_iter(fields.iter().enumerate().map(|f| self.lower_field_def(f))),
recovered, *recovered,
), ),
VariantData::Tuple(ref fields, id) => { VariantData::Tuple(fields, id) => {
let ctor_id = self.lower_node_id(id); let ctor_id = self.lower_node_id(*id);
self.alias_attrs(ctor_id, parent_id); self.alias_attrs(ctor_id, parent_id);
hir::VariantData::Tuple( hir::VariantData::Tuple(
self.arena.alloc_from_iter( self.arena.alloc_from_iter(
fields.iter().enumerate().map(|f| self.lower_field_def(f)), fields.iter().enumerate().map(|f| self.lower_field_def(f)),
), ),
ctor_id, ctor_id,
self.local_def_id(*id),
) )
} }
VariantData::Unit(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); 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> { 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( let t = self.lower_path_ty(
&f.ty, &f.ty,
qself, qself,
@ -767,6 +693,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
hir::FieldDef { hir::FieldDef {
span: self.lower_span(f.span), span: self.lower_span(f.span),
hir_id, hir_id,
def_id: self.local_def_id(f.id),
ident: match f.ident { ident: match f.ident {
Some(ident) => self.lower_ident(ident), Some(ident) => self.lower_ident(ident),
// FIXME(jseyfried): positional field hygiene. // 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> { fn lower_trait_item(&mut self, i: &AssocItem) -> &'hir hir::TraitItem<'hir> {
let hir_id = self.lower_node_id(i.id); 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 trait_item_def_id = hir_id.expect_owner();
let (generics, kind, has_default) = match i.kind { let (generics, kind, has_default) = match &i.kind {
AssocItemKind::Const(_, ref ty, ref default) => { AssocItemKind::Const(_, ty, default) => {
let ty = self.lower_ty(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Type)); 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))); 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()) (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 asyncness = sig.header.asyncness;
let names = self.lower_fn_params_to_names(&sig.decl); let names = self.lower_fn_params_to_names(&sig.decl);
let (generics, sig) = self.lower_method_sig( 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) (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 asyncness = sig.header.asyncness;
let body_id = 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( let (generics, sig) = self.lower_method_sig(
generics, generics,
sig, sig,
@ -812,15 +740,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
); );
(generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Provided(body_id)), true) (generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Provided(body_id)), true)
} }
AssocItemKind::Type(box TyAlias { AssocItemKind::Type(box TyAlias { generics, where_clauses, bounds, ty, .. }) => {
ref generics,
where_clauses,
ref bounds,
ref ty,
..
}) => {
let mut generics = generics.clone(); 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( let (generics, kind) = self.lower_generics(
&generics, &generics,
i.id, i.id,
@ -843,7 +765,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
AssocItemKind::MacCall(..) => panic!("macro item shouldn't exist at this point"), AssocItemKind::MacCall(..) => panic!("macro item shouldn't exist at this point"),
}; };
self.lower_attrs(hir_id, &i.attrs);
let item = hir::TraitItem { let item = hir::TraitItem {
owner_id: trait_item_def_id, owner_id: trait_item_def_id,
ident: self.lower_ident(i.ident), ident: self.lower_ident(i.ident),
@ -875,13 +796,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
/// Construct `ExprKind::Err` for the given `span`. /// Construct `ExprKind::Err` for the given `span`.
pub(crate) fn expr_err(&mut self, span: Span) -> hir::Expr<'hir> { 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> { 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. // Since `default impl` is not yet implemented, this is always true in impls.
let has_value = true; let has_value = true;
let (defaultness, _) = self.lower_defaultness(i.kind.defaultness(), has_value); 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 { let (generics, kind) = match &i.kind {
AssocItemKind::Const(_, ty, expr) => { AssocItemKind::Const(_, ty, expr) => {
@ -894,8 +817,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
AssocItemKind::Fn(box Fn { sig, generics, body, .. }) => { AssocItemKind::Fn(box Fn { sig, generics, body, .. }) => {
self.current_item = Some(i.span); self.current_item = Some(i.span);
let asyncness = sig.header.asyncness; let asyncness = sig.header.asyncness;
let body_id = let body_id = self.lower_maybe_async_body(
self.lower_maybe_async_body(i.span, &sig.decl, asyncness, body.as_deref()); i.span,
hir_id,
&sig.decl,
asyncness,
body.as_deref(),
);
let (generics, sig) = self.lower_method_sig( let (generics, sig) = self.lower_method_sig(
generics, generics,
sig, sig,
@ -928,8 +856,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
AssocItemKind::MacCall(..) => panic!("`TyMac` should have been expanded by now"), 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 { let item = hir::ImplItem {
owner_id: hir_id.expect_owner(), owner_id: hir_id.expect_owner(),
ident: self.lower_ident(i.ident), ident: self.lower_ident(i.ident),
@ -1062,6 +988,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
fn lower_maybe_async_body( fn lower_maybe_async_body(
&mut self, &mut self,
span: Span, span: Span,
fn_id: hir::HirId,
decl: &FnDecl, decl: &FnDecl,
asyncness: Async, asyncness: Async,
body: Option<&Block>, body: Option<&Block>,
@ -1212,6 +1139,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let async_expr = this.make_async_expr( let async_expr = this.make_async_expr(
CaptureBy::Value, CaptureBy::Value,
Some(fn_id),
closure_id, closure_id,
None, None,
body.span, body.span,
@ -1223,11 +1151,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
// Transform into `drop-temps { <user-body> }`, an expression: // Transform into `drop-temps { <user-body> }`, an expression:
let desugared_span = let desugared_span =
this.mark_span_with_reason(DesugaringKind::Async, user_body.span, None); this.mark_span_with_reason(DesugaringKind::Async, user_body.span, None);
let user_body = this.expr_drop_temps( let user_body =
desugared_span, this.expr_drop_temps(desugared_span, this.arena.alloc(user_body));
this.arena.alloc(user_body),
AttrVec::new(),
);
// As noted above, create the final block like // As noted above, create the final block like
// //
@ -1244,14 +1169,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
Some(user_body), 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))
this.arena.alloc_from_iter(parameters),
this.expr(body.span, async_expr, AttrVec::new()),
)
}) })
} }
@ -1266,7 +1188,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let header = self.lower_fn_header(sig.header); let header = self.lower_fn_header(sig.header);
let mut itctx = ImplTraitContext::Universal; let mut itctx = ImplTraitContext::Universal;
let (generics, decl) = self.lower_generics(generics, id, &mut itctx, |this| { 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) }) (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 // keep track of the Span info. Now, `add_implicitly_sized` in `AstConv` checks both param bounds and
// where clauses for `?Sized`. // where clauses for `?Sized`.
for pred in &generics.where_clause.predicates { for pred in &generics.where_clause.predicates {
let WherePredicate::BoundPredicate(ref bound_pred) = *pred else { let WherePredicate::BoundPredicate(bound_pred) = pred else {
continue; continue;
}; };
let compute_is_param = || { let compute_is_param = || {
@ -1498,10 +1420,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
})) }))
} }
GenericParamKind::Lifetime => { GenericParamKind::Lifetime => {
let ident_span = self.lower_span(ident.span);
let ident = self.lower_ident(ident); let ident = self.lower_ident(ident);
let lt_id = self.next_node_id(); 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 { Some(hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate {
lifetime, lifetime,
span, span,
@ -1513,11 +1434,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
} }
fn lower_where_predicate(&mut self, pred: &WherePredicate) -> hir::WherePredicate<'hir> { fn lower_where_predicate(&mut self, pred: &WherePredicate) -> hir::WherePredicate<'hir> {
match *pred { match pred {
WherePredicate::BoundPredicate(WhereBoundPredicate { WherePredicate::BoundPredicate(WhereBoundPredicate {
ref bound_generic_params, bound_generic_params,
ref bounded_ty, bounded_ty,
ref bounds, bounds,
span, span,
}) => hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate { }) => hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate {
hir_id: self.next_id(), hir_id: self.next_id(),
@ -1530,29 +1451,27 @@ impl<'hir> LoweringContext<'_, 'hir> {
&ImplTraitContext::Disallowed(ImplTraitPosition::Bound), &ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
) )
})), })),
span: self.lower_span(span), span: self.lower_span(*span),
origin: PredicateOrigin::WhereClause, origin: PredicateOrigin::WhereClause,
}), }),
WherePredicate::RegionPredicate(WhereRegionPredicate { WherePredicate::RegionPredicate(WhereRegionPredicate { lifetime, bounds, span }) => {
ref lifetime, hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate {
ref bounds, span: self.lower_span(*span),
span, lifetime: self.lower_lifetime(lifetime),
}) => hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate { bounds: self.lower_param_bounds(
span: self.lower_span(span), bounds,
lifetime: self.lower_lifetime(lifetime), &ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
bounds: self.lower_param_bounds( ),
bounds, in_where_clause: true,
&ImplTraitContext::Disallowed(ImplTraitPosition::Bound), })
), }
in_where_clause: true, WherePredicate::EqPredicate(WhereEqPredicate { lhs_ty, rhs_ty, span }) => {
}),
WherePredicate::EqPredicate(WhereEqPredicate { ref lhs_ty, ref rhs_ty, span }) => {
hir::WherePredicate::EqPredicate(hir::WhereEqPredicate { hir::WherePredicate::EqPredicate(hir::WhereEqPredicate {
lhs_ty: self lhs_ty: self
.lower_ty(lhs_ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Type)), .lower_ty(lhs_ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Type)),
rhs_ty: self rhs_ty: self
.lower_ty(rhs_ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Type)), .lower_ty(rhs_ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Type)),
span: self.lower_span(span), span: self.lower_span(*span),
}) })
} }
} }

View File

@ -34,7 +34,6 @@
#![feature(let_chains)] #![feature(let_chains)]
#![feature(never_type)] #![feature(never_type)]
#![recursion_limit = "256"] #![recursion_limit = "256"]
#![allow(rustc::potential_query_instability)]
#![deny(rustc::untranslatable_diagnostic)] #![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)] #![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::definitions::DefPathData;
use rustc_hir::{ConstArg, GenericArg, ItemLocalId, ParamName, TraitCandidate}; use rustc_hir::{ConstArg, GenericArg, ItemLocalId, ParamName, TraitCandidate};
use rustc_index::vec::{Idx, IndexVec}; use rustc_index::vec::{Idx, IndexVec};
use rustc_middle::span_bug;
use rustc_middle::ty::{ResolverAstLowering, TyCtxt}; use rustc_middle::ty::{ResolverAstLowering, TyCtxt};
use rustc_middle::{bug, span_bug};
use rustc_session::parse::feature_err; use rustc_session::parse::feature_err;
use rustc_span::hygiene::MacroKind; use rustc_span::hygiene::MacroKind;
use rustc_span::source_map::DesugaringKind; use rustc_span::source_map::DesugaringKind;
@ -107,7 +106,7 @@ struct LoweringContext<'a, 'hir> {
/// Attributes inside the owner being lowered. /// Attributes inside the owner being lowered.
attrs: SortedMap<hir::ItemLocalId, &'hir [Attribute]>, attrs: SortedMap<hir::ItemLocalId, &'hir [Attribute]>,
/// Collect items that were created by lowering the current owner. /// 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>, generator_kind: Option<hir::GeneratorKind>,
@ -260,6 +259,8 @@ enum ImplTraitContext {
}, },
/// Impl trait in type aliases. /// Impl trait in type aliases.
TypeAliasesOpaqueTy, TypeAliasesOpaqueTy,
/// `impl Trait` is unstably accepted in this position.
FeatureGated(ImplTraitPosition, Symbol),
/// `impl Trait` is not accepted in this position. /// `impl Trait` is not accepted in this position.
Disallowed(ImplTraitPosition), Disallowed(ImplTraitPosition),
} }
@ -328,7 +329,14 @@ enum FnDeclKind {
} }
impl 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 { match self {
FnDeclKind::Fn | FnDeclKind::Inherent => true, FnDeclKind::Fn | FnDeclKind::Inherent => true,
FnDeclKind::Impl if tcx.features().return_position_impl_trait_in_trait => 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, parent: LocalDefId,
node_id: ast::NodeId, node_id: ast::NodeId,
data: DefPathData, data: DefPathData,
span: Span,
) -> LocalDefId { ) -> LocalDefId {
debug_assert_ne!(node_id, ast::DUMMY_NODE_ID); debug_assert_ne!(node_id, ast::DUMMY_NODE_ID);
assert!( assert!(
@ -491,7 +500,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
self.tcx.hir().def_key(self.local_def_id(node_id)), 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); debug!("create_def: def_id_to_node_id[{:?}] <-> {:?}", def_id, node_id);
self.resolver.node_id_to_def_id.insert(node_id, def_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_defs = current_impl_trait_defs;
self.impl_trait_bounds = current_impl_trait_bounds; self.impl_trait_bounds = current_impl_trait_bounds;
let _old = self.children.insert(def_id, hir::MaybeOwner::Owner(info)); debug_assert!(self.children.iter().find(|(id, _)| id == &def_id).is_none());
debug_assert!(_old.is_none()) self.children.push((def_id, hir::MaybeOwner::Owner(info)));
} }
/// Installs the remapping `remap` in scope while `f` is being executed. /// 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)); assert_ne!(local_id, hir::ItemLocalId::new(0));
if let Some(def_id) = self.opt_local_def_id(ast_node_id) { 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.push((def_id, hir::MaybeOwner::NonOwner(hir_id)));
self.children.entry(def_id).or_insert(hir::MaybeOwner::NonOwner(hir_id));
self.local_id_to_def_id.insert(local_id, def_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, self.current_hir_id_owner.def_id,
param, param,
DefPathData::LifetimeNs(kw::UnderscoreLifetime), DefPathData::LifetimeNs(kw::UnderscoreLifetime),
ident.span,
); );
debug!(?_def_id); debug!(?_def_id);
@ -830,8 +839,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
), ),
}; };
let hir_id = self.lower_node_id(node_id); let hir_id = self.lower_node_id(node_id);
let def_id = self.local_def_id(node_id);
Some(hir::GenericParam { Some(hir::GenericParam {
hir_id, hir_id,
def_id,
name, name,
span: self.lower_span(ident.span), span: self.lower_span(ident.span),
pure_wrt_drop: false, pure_wrt_drop: false,
@ -911,7 +922,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
AttrKind::Normal(ref normal) => AttrKind::Normal(P(NormalAttr { AttrKind::Normal(ref normal) => AttrKind::Normal(P(NormalAttr {
item: AttrItem { item: AttrItem {
path: normal.item.path.clone(), 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,
}, },
tokens: None, tokens: None,
@ -931,51 +942,39 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
} }
} }
fn lower_mac_args(&self, args: &MacArgs) -> MacArgs { fn lower_attr_args(&self, args: &AttrArgs) -> AttrArgs {
match *args { match args {
MacArgs::Empty => MacArgs::Empty, AttrArgs::Empty => AttrArgs::Empty,
MacArgs::Delimited(dspan, delim, ref tokens) => { AttrArgs::Delimited(args) => AttrArgs::Delimited(self.lower_delim_args(args)),
// 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())
}
// This is an inert key-value attribute - it will never be visible to macros // 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 // after it gets lowered to HIR. Therefore, we can extract literals to handle
// nonterminals in `#[doc]` (e.g. `#[doc = $e]`). // 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 // In valid code the value always ends up as a single literal. Otherwise, a dummy
// literal suffices because the error is handled elsewhere. // literal suffices because the error is handled elsewhere.
let lit = if let ExprKind::Lit(lit) = &expr.kind { let lit = if let ExprKind::Lit(token_lit) = expr.kind
lit.clone() && let Ok(lit) = MetaItemLit::from_token_lit(token_lit, expr.span)
{
lit
} else { } else {
Lit { MetaItemLit {
token_lit: token::Lit::new(token::LitKind::Err, kw::Empty, None), token_lit: token::Lit::new(token::LitKind::Err, kw::Empty, None),
kind: LitKind::Err, kind: LitKind::Err,
span: DUMMY_SP, 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) 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: /// Given an associated type constraint like one of these:
/// ///
/// ```ignore (illustrative) /// ```ignore (illustrative)
@ -994,12 +993,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
) -> hir::TypeBinding<'hir> { ) -> hir::TypeBinding<'hir> {
debug!("lower_assoc_ty_constraint(constraint={:?}, itctx={:?})", constraint, itctx); debug!("lower_assoc_ty_constraint(constraint={:?}, itctx={:?})", constraint, itctx);
// lower generic arguments of identifier in constraint // 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 { 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 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); self.emit_bad_parenthesized_trait_in_assoc_ty(data);
let aba = self.ast_arena.aba.alloc(data.as_angle_bracketed_args()); let aba = self.ast_arena.aba.alloc(data.as_angle_bracketed_args());
self.lower_angle_bracketed_parameter_data(aba, ParamMode::Explicit, itctx).0 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 itctx_tait = &ImplTraitContext::TypeAliasesOpaqueTy;
let kind = match constraint.kind { let kind = match &constraint.kind {
AssocConstraintKind::Equality { ref term } => { AssocConstraintKind::Equality { term } => {
let term = match term { let term = match term {
Term::Ty(ref ty) => self.lower_ty(ty, itctx).into(), Term::Ty(ty) => self.lower_ty(ty, itctx).into(),
Term::Const(ref c) => self.lower_anon_const(c).into(), Term::Const(c) => self.lower_anon_const(c).into(),
}; };
hir::TypeBindingKind::Equality { term } hir::TypeBindingKind::Equality { term }
} }
AssocConstraintKind::Bound { ref bounds } => { AssocConstraintKind::Bound { bounds } => {
// Piggy-back on the `impl Trait` context to figure out the correct behavior. // Piggy-back on the `impl Trait` context to figure out the correct behavior.
let (desugar_to_impl_trait, itctx) = match itctx { let (desugar_to_impl_trait, itctx) = match itctx {
// We are in the return position: // We are in the return position:
@ -1129,7 +1128,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
match arg { match arg {
ast::GenericArg::Lifetime(lt) => GenericArg::Lifetime(self.lower_lifetime(&lt)), ast::GenericArg::Lifetime(lt) => GenericArg::Lifetime(self.lower_lifetime(&lt)),
ast::GenericArg::Type(ty) => { ast::GenericArg::Type(ty) => {
match ty.kind { match &ty.kind {
TyKind::Infer if self.tcx.features().generic_arg_infer => { TyKind::Infer if self.tcx.features().generic_arg_infer => {
return GenericArg::Infer(hir::InferArg { return GenericArg::Infer(hir::InferArg {
hir_id: self.lower_node_id(ty.id), 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 // 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 // type and value namespaces. If we resolved the path in the value namespace, we
// transform it into a generic const argument. // transform it into a generic const argument.
TyKind::Path(ref qself, ref path) => { TyKind::Path(qself, path) => {
if let Some(res) = self if let Some(res) = self
.resolver .resolver
.get_partial_res(ty.id) .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 parent_def_id = self.current_hir_id_owner;
let node_id = self.next_node_id(); let node_id = self.next_node_id();
let span = self.lower_span(ty.span);
// Add a definition for the in-band const def. // Add a definition for the in-band const def.
self.create_def( let def_id = self.create_def(
parent_def_id.def_id, parent_def_id.def_id,
node_id, node_id,
DefPathData::AnonConst, DefPathData::AnonConst,
span,
); );
let span = self.lower_span(ty.span);
let path_expr = Expr { let path_expr = Expr {
id: ty.id, id: ty.id,
kind: ExprKind::Path(qself.clone(), path.clone()), 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 { let ct = self.with_new_scopes(|this| hir::AnonConst {
def_id,
hir_id: this.lower_node_id(node_id), hir_id: this.lower_node_id(node_id),
body: this.lower_const_body(path_expr.span, Some(&path_expr)), 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( fn lower_path_ty(
&mut self, &mut self,
t: &Ty, t: &Ty,
qself: &Option<QSelf>, qself: &Option<ptr::P<QSelf>>,
path: &Path, path: &Path,
param_mode: ParamMode, param_mode: ParamMode,
itctx: &ImplTraitContext, 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> { 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::Infer => hir::TyKind::Infer,
TyKind::Err => hir::TyKind::Err, TyKind::Err => hir::TyKind::Err,
TyKind::Slice(ref ty) => hir::TyKind::Slice(self.lower_ty(ty, itctx)), TyKind::Slice(ty) => hir::TyKind::Slice(self.lower_ty(ty, itctx)),
TyKind::Ptr(ref mt) => hir::TyKind::Ptr(self.lower_mt(mt, itctx)), TyKind::Ptr(mt) => hir::TyKind::Ptr(self.lower_mt(mt, itctx)),
TyKind::Rptr(ref region, ref mt) => { TyKind::Rptr(region, mt) => {
let region = region.unwrap_or_else(|| { let region = region.unwrap_or_else(|| {
let id = if let Some(LifetimeRes::ElidedAnchor { start, end }) = let id = if let Some(LifetimeRes::ElidedAnchor { start, end }) =
self.resolver.get_lifetime_res(t.id) self.resolver.get_lifetime_res(t.id)
@ -1261,30 +1262,30 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
} else { } else {
self.next_node_id() 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 } Lifetime { ident: Ident::new(kw::UnderscoreLifetime, span), id }
}); });
let lifetime = self.lower_lifetime(&region); let lifetime = self.lower_lifetime(&region);
hir::TyKind::Rptr(lifetime, self.lower_mt(mt, itctx)) 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); let generic_params = self.lower_lifetime_binder(t.id, &f.generic_params);
hir::TyKind::BareFn(self.arena.alloc(hir::BareFnTy { hir::TyKind::BareFn(self.arena.alloc(hir::BareFnTy {
generic_params, generic_params,
unsafety: self.lower_unsafety(f.unsafety), unsafety: self.lower_unsafety(f.unsafety),
abi: self.lower_extern(f.ext), 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), param_names: self.lower_fn_params_to_names(&f.decl),
})) }))
} }
TyKind::Never => hir::TyKind::Never, 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))), 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); 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); return self.lower_path_ty(t, qself, path, ParamMode::Explicit, itctx);
} }
TyKind::ImplicitSelf => { 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)) 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::Typeof(expr) => hir::TyKind::Typeof(self.lower_anon_const(expr)),
TyKind::TraitObject(ref bounds, kind) => { TyKind::TraitObject(bounds, kind) => {
let mut lifetime_bound = None; let mut lifetime_bound = None;
let (bounds, lifetime_bound) = self.with_dyn_type_scope(true, |this| { let (bounds, lifetime_bound) = self.with_dyn_type_scope(true, |this| {
let bounds = let bounds =
this.arena.alloc_from_iter(bounds.iter().filter_map( this.arena.alloc_from_iter(bounds.iter().filter_map(|bound| match bound {
|bound| match *bound { GenericBound::Trait(
GenericBound::Trait( ty,
ref ty, TraitBoundModifier::None | TraitBoundModifier::MaybeConst,
TraitBoundModifier::None | TraitBoundModifier::MaybeConst, ) => Some(this.lower_poly_trait_ref(ty, itctx)),
) => Some(this.lower_poly_trait_ref(ty, itctx)), // `~const ?Bound` will cause an error during AST validation
// `~const ?Bound` will cause an error during AST validation // anyways, so treat it like `?Bound` as compilation proceeds.
// anyways, so treat it like `?Bound` as compilation proceeds. GenericBound::Trait(
GenericBound::Trait( _,
_, TraitBoundModifier::Maybe | TraitBoundModifier::MaybeConstMaybe,
TraitBoundModifier::Maybe | TraitBoundModifier::MaybeConstMaybe, ) => None,
) => None, GenericBound::Outlives(lifetime) => {
GenericBound::Outlives(ref lifetime) => { if lifetime_bound.is_none() {
if lifetime_bound.is_none() { lifetime_bound = Some(this.lower_lifetime(lifetime));
lifetime_bound = Some(this.lower_lifetime(lifetime));
}
None
} }
}, None
)); }
}));
let lifetime_bound = let lifetime_bound =
lifetime_bound.unwrap_or_else(|| this.elided_dyn_bound(t.span)); lifetime_bound.unwrap_or_else(|| this.elided_dyn_bound(t.span));
(bounds, lifetime_bound) (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; let span = t.span;
match itctx { match itctx {
ImplTraitContext::ReturnPositionOpaqueTy { origin, in_trait } => self ImplTraitContext::ReturnPositionOpaqueTy { origin, in_trait } => self
.lower_opaque_impl_trait( .lower_opaque_impl_trait(
span, span,
*origin, *origin,
def_node_id, *def_node_id,
bounds, bounds,
*in_trait, *in_trait,
itctx, itctx,
@ -1353,38 +1352,37 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
ImplTraitContext::TypeAliasesOpaqueTy => self.lower_opaque_impl_trait( ImplTraitContext::TypeAliasesOpaqueTy => self.lower_opaque_impl_trait(
span, span,
hir::OpaqueTyOrigin::TyAlias, hir::OpaqueTyOrigin::TyAlias,
def_node_id, *def_node_id,
bounds, bounds,
false, false,
itctx, itctx,
), ),
ImplTraitContext::Universal => { ImplTraitContext::Universal => {
let span = t.span;
self.create_def( self.create_def(
self.current_hir_id_owner.def_id, self.current_hir_id_owner.def_id,
def_node_id, *def_node_id,
DefPathData::ImplTrait, DefPathData::ImplTrait,
span,
); );
let span = t.span;
let ident = Ident::from_str_and_span(&pprust::ty_to_string(t), span); let ident = Ident::from_str_and_span(&pprust::ty_to_string(t), span);
let (param, bounds, path) = 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); self.impl_trait_defs.push(param);
if let Some(bounds) = bounds { if let Some(bounds) = bounds {
self.impl_trait_bounds.push(bounds); self.impl_trait_bounds.push(bounds);
} }
path path
} }
ImplTraitContext::Disallowed( ImplTraitContext::FeatureGated(position, feature) => {
position @ (ImplTraitPosition::TraitReturn | ImplTraitPosition::ImplReturn),
) => {
self.tcx self.tcx
.sess .sess
.create_feature_err( .create_feature_err(
MisplacedImplTrait { MisplacedImplTrait {
span: t.span, span: t.span,
position: DiagnosticArgFromDisplay(&position), position: DiagnosticArgFromDisplay(position),
}, },
sym::return_position_impl_trait_in_trait, *feature,
) )
.emit(); .emit();
hir::TyKind::Err hir::TyKind::Err
@ -1392,7 +1390,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
ImplTraitContext::Disallowed(position) => { ImplTraitContext::Disallowed(position) => {
self.tcx.sess.emit_err(MisplacedImplTrait { self.tcx.sess.emit_err(MisplacedImplTrait {
span: t.span, span: t.span,
position: DiagnosticArgFromDisplay(&position), position: DiagnosticArgFromDisplay(position),
}); });
hir::TyKind::Err hir::TyKind::Err
} }
@ -1457,17 +1455,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// frequently opened issues show. // frequently opened issues show.
let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::OpaqueTy, span, None); let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::OpaqueTy, span, None);
let opaque_ty_def_id = match origin { let opaque_ty_def_id = self.create_def(
hir::OpaqueTyOrigin::TyAlias => self.create_def( self.current_hir_id_owner.def_id,
self.current_hir_id_owner.def_id, opaque_ty_node_id,
opaque_ty_node_id, DefPathData::ImplTrait,
DefPathData::ImplTrait, opaque_ty_span,
), );
hir::OpaqueTyOrigin::FnReturn(fn_def_id) => {
self.create_def(fn_def_id, opaque_ty_node_id, DefPathData::ImplTrait)
}
hir::OpaqueTyOrigin::AsyncFn(..) => bug!("unreachable"),
};
debug!(?opaque_ty_def_id); debug!(?opaque_ty_def_id);
// Contains the new lifetime definitions created for the TAIT (if any). // Contains the new lifetime definitions created for the TAIT (if any).
@ -1521,6 +1514,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
hir::GenericParam { hir::GenericParam {
hir_id, hir_id,
def_id: lctx.local_def_id(new_node_id),
name, name,
span: lifetime.ident.span, span: lifetime.ident.span,
pure_wrt_drop: false, pure_wrt_drop: false,
@ -1559,15 +1553,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let lifetimes = let lifetimes =
self.arena.alloc_from_iter(collected_lifetimes.into_iter().map(|(_, lifetime)| { self.arena.alloc_from_iter(collected_lifetimes.into_iter().map(|(_, lifetime)| {
let id = self.next_node_id(); let id = self.next_node_id();
let span = lifetime.ident.span; let l = self.new_named_lifetime(lifetime.id, id, lifetime.ident);
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);
hir::GenericArg::Lifetime(l) hir::GenericArg::Lifetime(l)
})); }));
debug!(?lifetimes); debug!(?lifetimes);
@ -1627,6 +1613,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
parent_def_id, parent_def_id,
node_id, node_id,
DefPathData::LifetimeNs(lifetime.ident.name), DefPathData::LifetimeNs(lifetime.ident.name),
lifetime.ident.span,
); );
remapping.insert(old_def_id, new_def_id); remapping.insert(old_def_id, new_def_id);
@ -1643,6 +1630,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
parent_def_id, parent_def_id,
node_id, node_id,
DefPathData::LifetimeNs(kw::UnderscoreLifetime), DefPathData::LifetimeNs(kw::UnderscoreLifetime),
lifetime.ident.span,
); );
remapping.insert(old_def_id, new_def_id); remapping.insert(old_def_id, new_def_id);
@ -1692,7 +1680,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
fn lower_fn_decl( fn lower_fn_decl(
&mut self, &mut self,
decl: &FnDecl, decl: &FnDecl,
fn_node_id: Option<NodeId>, fn_node_id: NodeId,
fn_span: Span, fn_span: Span,
kind: FnDeclKind, kind: FnDeclKind,
make_ret_async: Option<(NodeId, Span)>, make_ret_async: Option<(NodeId, Span)>,
@ -1707,23 +1695,21 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
inputs = &inputs[..inputs.len() - 1]; inputs = &inputs[..inputs.len() - 1];
} }
let inputs = self.arena.alloc_from_iter(inputs.iter().map(|param| { let inputs = self.arena.alloc_from_iter(inputs.iter().map(|param| {
if fn_node_id.is_some() { let itctx = if kind.param_impl_trait_allowed() {
self.lower_ty_direct(&param.ty, &ImplTraitContext::Universal) ImplTraitContext::Universal
} else { } else {
self.lower_ty_direct( ImplTraitContext::Disallowed(match kind {
&param.ty, FnDeclKind::Fn | FnDeclKind::Inherent => {
&ImplTraitContext::Disallowed(match kind { unreachable!("fn should allow APIT")
FnDeclKind::Fn | FnDeclKind::Inherent => { }
unreachable!("fn should allow in-band lifetimes") FnDeclKind::ExternFn => ImplTraitPosition::ExternFnParam,
} FnDeclKind::Closure => ImplTraitPosition::ClosureParam,
FnDeclKind::ExternFn => ImplTraitPosition::ExternFnParam, FnDeclKind::Pointer => ImplTraitPosition::PointerParam,
FnDeclKind::Closure => ImplTraitPosition::ClosureParam, FnDeclKind::Trait => ImplTraitPosition::TraitParam,
FnDeclKind::Pointer => ImplTraitPosition::PointerParam, FnDeclKind::Impl => ImplTraitPosition::ImplParam,
FnDeclKind::Trait => ImplTraitPosition::TraitParam, })
FnDeclKind::Impl => ImplTraitPosition::ImplParam, };
}), self.lower_ty_direct(&param.ty, &itctx)
)
}
})); }));
let output = if let Some((ret_id, span)) = make_ret_async { 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( self.lower_async_fn_ret_ty(
&decl.output, &decl.output,
fn_node_id.expect("`make_ret_async` but no `fn_def_id`"), fn_node_id,
ret_id, ret_id,
matches!(kind, FnDeclKind::Trait), matches!(kind, FnDeclKind::Trait),
) )
} else { } else {
match decl.output { match &decl.output {
FnRetTy::Ty(ref ty) => { FnRetTy::Ty(ty) => {
let mut context = match fn_node_id { let context = if kind.return_impl_trait_allowed(self.tcx) {
Some(fn_node_id) if kind.impl_trait_allowed(self.tcx) => { let fn_def_id = self.local_def_id(fn_node_id);
let fn_def_id = self.local_def_id(fn_node_id); ImplTraitContext::ReturnPositionOpaqueTy {
ImplTraitContext::ReturnPositionOpaqueTy { origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id),
origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id), in_trait: matches!(kind, FnDeclKind::Trait),
in_trait: matches!(kind, FnDeclKind::Trait),
}
} }
_ => ImplTraitContext::Disallowed(match kind { } else {
let position = match kind {
FnDeclKind::Fn | FnDeclKind::Inherent => { FnDeclKind::Fn | FnDeclKind::Inherent => {
unreachable!("fn should allow in-band lifetimes") unreachable!("fn should allow in-band lifetimes")
} }
@ -1770,11 +1755,18 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
FnDeclKind::Pointer => ImplTraitPosition::PointerReturn, FnDeclKind::Pointer => ImplTraitPosition::PointerReturn,
FnDeclKind::Trait => ImplTraitPosition::TraitReturn, FnDeclKind::Trait => ImplTraitPosition::TraitReturn,
FnDeclKind::Impl => ImplTraitPosition::ImplReturn, 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, inputs,
output, output,
c_variadic, 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| { implicit_self: decl.inputs.get(0).map_or(hir::ImplicitSelfKind::None, |arg| {
let is_mutable_pat = matches!( let is_mutable_pat = matches!(
arg.pat.kind, arg.pat.kind,
PatKind::Ident(hir::BindingAnnotation(_, Mutability::Mut), ..) 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 if is_mutable_pat => hir::ImplicitSelfKind::Mut,
TyKind::ImplicitSelf => hir::ImplicitSelfKind::Imm, TyKind::ImplicitSelf => hir::ImplicitSelfKind::Imm,
// Given we are only considering `ImplicitSelf` types, we needn't consider // 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 // the case where we have a mutable pattern to a reference as that would
// no longer be an `ImplicitSelf`. // no longer be an `ImplicitSelf`.
TyKind::Rptr(_, ref mt) TyKind::Rptr(_, mt) if mt.ty.kind.is_implicit_self() => match mt.mutbl {
if mt.ty.kind.is_implicit_self() && mt.mutbl == ast::Mutability::Mut => hir::Mutability::Not => hir::ImplicitSelfKind::ImmRef,
{ hir::Mutability::Mut => hir::ImplicitSelfKind::MutRef,
hir::ImplicitSelfKind::MutRef },
}
TyKind::Rptr(_, ref mt) if mt.ty.kind.is_implicit_self() => {
hir::ImplicitSelfKind::ImmRef
}
_ => hir::ImplicitSelfKind::None, _ => 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_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 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 // 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 // to capture all the lifetimes involved in the signature (including in the
// return type). This is done by introducing lifetime parameters for: // return type). This is done by introducing lifetime parameters for:
@ -1889,6 +1880,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
opaque_ty_def_id, opaque_ty_def_id,
inner_node_id, inner_node_id,
DefPathData::LifetimeNs(ident.name), DefPathData::LifetimeNs(ident.name),
ident.span,
); );
new_remapping.insert(outer_def_id, inner_def_id); new_remapping.insert(outer_def_id, inner_def_id);
@ -1953,7 +1945,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
output, output,
span, span,
if in_trait && !this.tcx.features().return_position_impl_trait_in_trait { 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 { } else {
ImplTraitContext::ReturnPositionOpaqueTy { ImplTraitContext::ReturnPositionOpaqueTy {
origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id), origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id),
@ -1978,6 +1973,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
hir::GenericParam { hir::GenericParam {
hir_id, hir_id,
def_id: this.local_def_id(new_node_id),
name, name,
span: lifetime.ident.span, span: lifetime.ident.span,
pure_wrt_drop: false, 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( let generic_args = self.arena.alloc_from_iter(collected_lifetimes.into_iter().map(
|(_, lifetime, res)| { |(_, lifetime, res)| {
let id = self.next_node_id(); 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( let res = res.unwrap_or(
self.resolver.get_lifetime_res(lifetime.id).unwrap_or(LifetimeRes::Error), 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 { 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); 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))] #[instrument(level = "debug", skip(self))]
fn new_named_lifetime_with_res( fn new_named_lifetime_with_res(
&mut self, &mut self,
id: NodeId, id: NodeId,
span: Span,
ident: Ident, ident: Ident,
res: LifetimeRes, res: LifetimeRes,
) -> &'hir hir::Lifetime { ) -> &'hir hir::Lifetime {
let name = match res { let res = match res {
LifetimeRes::Param { param, .. } => { LifetimeRes::Param { param, .. } => {
let p_name = ParamName::Plain(ident);
let param = self.get_remapped_def_id(param); let param = self.get_remapped_def_id(param);
hir::LifetimeName::Param(param)
hir::LifetimeName::Param(param, p_name)
} }
LifetimeRes::Fresh { param, .. } => { LifetimeRes::Fresh { param, .. } => {
debug_assert_eq!(ident.name, kw::UnderscoreLifetime);
let param = self.local_def_id(param); let param = self.local_def_id(param);
hir::LifetimeName::Param(param)
hir::LifetimeName::Param(param, ParamName::Fresh)
} }
LifetimeRes::Infer => hir::LifetimeName::Infer, LifetimeRes::Infer => hir::LifetimeName::Infer,
LifetimeRes::Static => hir::LifetimeName::Static, LifetimeRes::Static => hir::LifetimeName::Static,
LifetimeRes::Error => hir::LifetimeName::Error, 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 { self.arena.alloc(hir::Lifetime {
hir_id: self.lower_node_id(id), hir_id: self.lower_node_id(id),
span: self.lower_span(span), ident: self.lower_ident(ident),
name, res,
}) })
} }
@ -2150,11 +2135,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
&mut self, &mut self,
id: NodeId, id: NodeId,
new_id: NodeId, new_id: NodeId,
span: Span,
ident: Ident, ident: Ident,
) -> &'hir hir::Lifetime { ) -> &'hir hir::Lifetime {
let res = self.resolver.get_lifetime_res(id).unwrap_or(LifetimeRes::Error); 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>( fn lower_generic_params_mut<'s>(
@ -2176,6 +2160,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
self.lower_attrs(hir_id, &param.attrs); self.lower_attrs(hir_id, &param.attrs);
hir::GenericParam { hir::GenericParam {
hir_id, hir_id,
def_id: self.local_def_id(param.id),
name, name,
span: self.lower_span(param.span()), span: self.lower_span(param.span()),
pure_wrt_drop: self.tcx.sess.contains_name(&param.attrs, sym::may_dangle), pure_wrt_drop: self.tcx.sess.contains_name(&param.attrs, sym::may_dangle),
@ -2188,7 +2173,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
&mut self, &mut self,
param: &GenericParam, param: &GenericParam,
) -> (hir::ParamName, hir::GenericParamKind<'hir>) { ) -> (hir::ParamName, hir::GenericParamKind<'hir>) {
match param.kind { match &param.kind {
GenericParamKind::Lifetime => { GenericParamKind::Lifetime => {
// AST resolution emitted an error on those parameters, so we lower them using // AST resolution emitted an error on those parameters, so we lower them using
// `ParamName::Error`. // `ParamName::Error`.
@ -2204,7 +2189,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
(param_name, kind) (param_name, kind)
} }
GenericParamKind::Type { ref default, .. } => { GenericParamKind::Type { default, .. } => {
let kind = hir::GenericParamKind::Type { let kind = hir::GenericParamKind::Type {
default: default.as_ref().map(|x| { default: default.as_ref().map(|x| {
self.lower_ty(x, &ImplTraitContext::Disallowed(ImplTraitPosition::Type)) 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) (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 ty = self.lower_ty(&ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Type));
let default = default.as_ref().map(|def| self.lower_anon_const(def)); 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`. // Set the name to `impl Bound1 + Bound2`.
let param = hir::GenericParam { let param = hir::GenericParam {
hir_id: self.lower_node_id(node_id), hir_id: self.lower_node_id(node_id),
def_id,
name: ParamName::Plain(self.lower_ident(ident)), name: ParamName::Plain(self.lower_ident(ident)),
pure_wrt_drop: false, pure_wrt_drop: false,
span: self.lower_span(span), 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`. /// has no attributes and is not targeted by a `break`.
fn lower_block_expr(&mut self, b: &Block) -> hir::Expr<'hir> { fn lower_block_expr(&mut self, b: &Block) -> hir::Expr<'hir> {
let block = self.lower_block(b, false); 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 { 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 { fn lower_anon_const(&mut self, c: &AnonConst) -> hir::AnonConst {
self.with_new_scopes(|this| 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), hir_id: this.lower_node_id(c.id),
body: this.lower_const_body(c.value.span, Some(&c.value)), 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 { fn elided_dyn_bound(&mut self, span: Span) -> &'hir hir::Lifetime {
let r = hir::Lifetime { let r = hir::Lifetime {
hir_id: self.next_id(), hir_id: self.next_id(),
span: self.lower_span(span), ident: Ident::new(kw::Empty, self.lower_span(span)),
name: hir::LifetimeName::ImplicitObjectLifetimeDefault, res: hir::LifetimeName::ImplicitObjectLifetimeDefault,
}; };
debug!("elided_dyn_bound: r={:?}", r); debug!("elided_dyn_bound: r={:?}", r);
self.arena.alloc(r) self.arena.alloc(r)

View File

@ -22,16 +22,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
ensure_sufficient_stack(|| { ensure_sufficient_stack(|| {
// loop here to avoid recursion // loop here to avoid recursion
let node = loop { let node = loop {
match pattern.kind { match &pattern.kind {
PatKind::Wild => break hir::PatKind::Wild, PatKind::Wild => break hir::PatKind::Wild,
PatKind::Ident(binding_mode, ident, ref sub) => { PatKind::Ident(binding_mode, ident, sub) => {
let lower_sub = |this: &mut Self| sub.as_ref().map(|s| this.lower_pat(&*s)); 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); 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)); 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( let qpath = self.lower_qpath(
pattern.id, pattern.id,
qself, qself,
@ -42,12 +42,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let (pats, ddpos) = self.lower_pat_tuple(pats, "tuple struct"); let (pats, ddpos) = self.lower_pat_tuple(pats, "tuple struct");
break hir::PatKind::TupleStruct(qpath, pats, ddpos); break hir::PatKind::TupleStruct(qpath, pats, ddpos);
} }
PatKind::Or(ref pats) => { PatKind::Or(pats) => {
break hir::PatKind::Or( break hir::PatKind::Or(
self.arena.alloc_from_iter(pats.iter().map(|x| self.lower_pat_mut(x))), 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( let qpath = self.lower_qpath(
pattern.id, pattern.id,
qself, qself,
@ -57,7 +57,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
); );
break hir::PatKind::Path(qpath); 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( let qpath = self.lower_qpath(
pattern.id, pattern.id,
qself, qself,
@ -78,32 +78,32 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
span: self.lower_span(f.span), 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"); let (pats, ddpos) = self.lower_pat_tuple(pats, "tuple");
break hir::PatKind::Tuple(pats, ddpos); break hir::PatKind::Tuple(pats, ddpos);
} }
PatKind::Box(ref inner) => { PatKind::Box(inner) => {
break hir::PatKind::Box(self.lower_pat(inner)); break hir::PatKind::Box(self.lower_pat(inner));
} }
PatKind::Ref(ref inner, mutbl) => { PatKind::Ref(inner, mutbl) => {
break hir::PatKind::Ref(self.lower_pat(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( break hir::PatKind::Range(
e1.as_deref().map(|e| self.lower_expr_within_pat(e, true)), e1.as_deref().map(|e| self.lower_expr_within_pat(e, true)),
e2.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()), 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 => { PatKind::Rest => {
// If we reach here the `..` pattern is not semantically allowed. // If we reach here the `..` pattern is not semantically allowed.
break self.ban_illegal_rest_pat(pattern.span); break self.ban_illegal_rest_pat(pattern.span);
} }
// return inner to be processed in next loop // 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), 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, // Note that unlike for slice patterns,
// where `xs @ ..` is a legal sub-slice pattern, // where `xs @ ..` is a legal sub-slice pattern,
// it is not a legal sub-tuple pattern. // it is not a legal sub-tuple pattern.
match pat.kind { match &pat.kind {
// Found a sub-tuple rest pattern // Found a sub-tuple rest pattern
PatKind::Rest => { PatKind::Rest => {
rest = Some((idx, pat.span)); rest = Some((idx, pat.span));
@ -134,12 +134,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
} }
// Found a sub-tuple pattern `$binding_mode $ident @ ..`. // Found a sub-tuple pattern `$binding_mode $ident @ ..`.
// This is not allowed as a sub-tuple pattern // 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; let sp = pat.span;
self.tcx.sess.emit_err(SubTupleBinding { self.tcx.sess.emit_err(SubTupleBinding {
span: sp, span: sp,
ident_name: ident.name, ident_name: ident.name,
ident, ident: *ident,
ctx, ctx,
}); });
} }
@ -176,7 +176,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let mut prev_rest_span = None; let mut prev_rest_span = None;
// Lowers `$bm $ident @ ..` to `$bm $ident @ _`. // 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 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); let node = this.lower_pat_ident(pat, ann, ident, lower_sub);
this.pat_with_node_id_of(pat, node) this.pat_with_node_id_of(pat, node)
@ -185,7 +185,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let mut iter = pats.iter(); let mut iter = pats.iter();
// Lower all the patterns until the first occurrence of a sub-slice pattern. // Lower all the patterns until the first occurrence of a sub-slice pattern.
for pat in iter.by_ref() { for pat in iter.by_ref() {
match pat.kind { match &pat.kind {
// Found a sub-slice pattern `..`. Record, lower it to `_`, and stop here. // Found a sub-slice pattern `..`. Record, lower it to `_`, and stop here.
PatKind::Rest => { PatKind::Rest => {
prev_rest_span = Some(pat.span); prev_rest_span = Some(pat.span);
@ -194,7 +194,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
} }
// Found a sub-slice pattern `$binding_mode $ident @ ..`. // Found a sub-slice pattern `$binding_mode $ident @ ..`.
// Record, lower it to `$binding_mode $ident @ _`, and stop here. // 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); prev_rest_span = Some(sub.span);
slice = Some(self.arena.alloc(lower_rest_sub(self, pat, ann, ident, sub))); slice = Some(self.arena.alloc(lower_rest_sub(self, pat, ann, ident, sub)));
break; break;
@ -207,9 +207,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// Lower all the patterns after the first sub-slice pattern. // Lower all the patterns after the first sub-slice pattern.
for pat in iter { for pat in iter {
// There was a previous subslice pattern; make sure we don't allow more. // 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::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. // #69103: Lower into `binding @ _` as above to avoid ICEs.
after.push(lower_rest_sub(self, pat, ann, ident, sub)); after.push(lower_rest_sub(self, pat, ann, ident, sub));
Some(sub.span) Some(sub.span)
@ -322,10 +322,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// m!(S); // m!(S);
// ``` // ```
fn lower_expr_within_pat(&mut self, expr: &Expr, allow_paths: bool) -> &'hir hir::Expr<'hir> { fn lower_expr_within_pat(&mut self, expr: &Expr, allow_paths: bool) -> &'hir hir::Expr<'hir> {
match expr.kind { match &expr.kind {
ExprKind::Lit(..) | ExprKind::ConstBlock(..) | ExprKind::Err => {} ExprKind::Lit(..)
| ExprKind::ConstBlock(..)
| ExprKind::IncludedBytes(..)
| ExprKind::Err => {}
ExprKind::Path(..) if allow_paths => {} 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 }); self.tcx.sess.emit_err(ArbitraryExpressionInPattern { span: expr.span });
return self.arena.alloc(self.expr_err(expr.span)); return self.arena.alloc(self.expr_err(expr.span));

View File

@ -9,17 +9,17 @@ use rustc_ast::{self as ast, *};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::{DefKind, PartialRes, Res}; use rustc_hir::def::{DefKind, PartialRes, Res};
use rustc_hir::GenericArg; 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 rustc_span::{BytePos, Span, DUMMY_SP};
use smallvec::smallvec; use smallvec::{smallvec, SmallVec};
impl<'a, 'hir> LoweringContext<'a, 'hir> { impl<'a, 'hir> LoweringContext<'a, 'hir> {
#[instrument(level = "trace", skip(self))] #[instrument(level = "trace", skip(self))]
pub(crate) fn lower_qpath( pub(crate) fn lower_qpath(
&mut self, &mut self,
id: NodeId, id: NodeId,
qself: &Option<QSelf>, qself: &Option<ptr::P<QSelf>>,
p: &Path, p: &Path,
param_mode: ParamMode, param_mode: ParamMode,
itctx: &ImplTraitContext, 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, &mut self,
res: Res, res: SmallVec<[Res; 3]>,
p: &Path, p: &Path,
param_mode: ParamMode, param_mode: ParamMode,
) -> &'hir hir::Path<'hir> { ) -> &'hir hir::UsePath<'hir> {
self.arena.alloc(hir::Path { self.arena.alloc(hir::UsePath {
res, res,
segments: self.arena.alloc_from_iter(p.segments.iter().map(|segment| { segments: self.arena.alloc_from_iter(p.segments.iter().map(|segment| {
self.lower_path_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( pub(crate) fn lower_path_segment(
&mut self, &mut self,
path_span: Span, path_span: Span,
@ -185,13 +174,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
itctx: &ImplTraitContext, itctx: &ImplTraitContext,
) -> hir::PathSegment<'hir> { ) -> hir::PathSegment<'hir> {
debug!("path_span: {:?}, lower_path_segment(segment: {:?})", path_span, segment,); debug!("path_span: {:?}, lower_path_segment(segment: {:?})", path_span, segment,);
let (mut generic_args, infer_args) = if let Some(ref generic_args) = segment.args { let (mut generic_args, infer_args) = if let Some(generic_args) = segment.args.as_deref() {
match **generic_args { match generic_args {
GenericArgs::AngleBracketed(ref data) => { GenericArgs::AngleBracketed(data) => {
self.lower_angle_bracketed_parameter_data(data, param_mode, itctx) self.lower_angle_bracketed_parameter_data(data, param_mode, itctx)
} }
GenericArgs::Parenthesized(ref data) => match parenthesized_generic_args { GenericArgs::Parenthesized(data) => match parenthesized_generic_args {
ParenthesizedGenericArgs::Ok => self.lower_parenthesized_parameter_data(data), ParenthesizedGenericArgs::Ok => {
self.lower_parenthesized_parameter_data(data, itctx)
}
ParenthesizedGenericArgs::Err => { ParenthesizedGenericArgs::Err => {
// Suggest replacing parentheses with angle brackets `Trait(params...)` to `Trait<params...>` // Suggest replacing parentheses with angle brackets `Trait(params...)` to `Trait<params...>`
let sub = if !data.inputs.is_empty() { let sub = if !data.inputs.is_empty() {
@ -307,7 +298,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let id = NodeId::from_u32(i); let id = NodeId::from_u32(i);
let l = self.lower_lifetime(&Lifetime { let l = self.lower_lifetime(&Lifetime {
id, id,
ident: Ident::new(kw::UnderscoreLifetime, elided_lifetime_span), ident: Ident::new(kw::Empty, elided_lifetime_span),
}); });
GenericArg::Lifetime(l) GenericArg::Lifetime(l)
}), }),
@ -344,6 +335,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
fn lower_parenthesized_parameter_data( fn lower_parenthesized_parameter_data(
&mut self, &mut self,
data: &ParenthesizedArgs, data: &ParenthesizedArgs,
itctx: &ImplTraitContext,
) -> (GenericArgsCtor<'hir>, bool) { ) -> (GenericArgsCtor<'hir>, bool) {
// Switch to `PassThrough` mode for anonymous lifetimes; this // Switch to `PassThrough` mode for anonymous lifetimes; this
// means that we permit things like `&Ref<T>`, where `Ref` has // 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)) self.lower_ty_direct(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::FnTraitParam))
})); }));
let output_ty = match output { 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) => { FnRetTy::Ty(ty) => {
self.lower_ty(&ty, &ImplTraitContext::Disallowed(ImplTraitPosition::FnTraitReturn)) self.lower_ty(&ty, &ImplTraitContext::Disallowed(ImplTraitPosition::FnTraitReturn))
} }

View File

@ -209,7 +209,7 @@ impl<'a> AstValidator<'a> {
// Mirrors `visit::walk_ty`, but tracks relevant state. // Mirrors `visit::walk_ty`, but tracks relevant state.
fn walk_ty(&mut self, t: &'a Ty) { fn walk_ty(&mut self, t: &'a Ty) {
match t.kind { match &t.kind {
TyKind::ImplTrait(..) => { TyKind::ImplTrait(..) => {
self.with_impl_trait(Some(t.span), |this| visit::walk_ty(this, t)) 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| { .with_banned_tilde_const(DisallowTildeConstContext::TraitObject, |this| {
visit::walk_ty(this, t) visit::walk_ty(this, t)
}), }),
TyKind::Path(ref qself, ref path) => { TyKind::Path(qself, path) => {
// We allow these: // We allow these:
// - `Option<impl Trait>` // - `Option<impl Trait>`
// - `option::Option<impl Trait>` // - `option::Option<impl Trait>`
@ -231,7 +231,7 @@ impl<'a> AstValidator<'a> {
// (for cases like `<impl Trait>::Foo>`) // (for cases like `<impl Trait>::Foo>`)
// but we allow `impl Trait` in `GenericArgs` // but we allow `impl Trait` in `GenericArgs`
// iff there are no more PathSegments. // iff there are no more PathSegments.
if let Some(ref qself) = *qself { if let Some(qself) = qself {
// `impl Trait` in `qself` is always illegal // `impl Trait` in `qself` is always illegal
self.with_banned_impl_trait(|this| this.visit_ty(&qself.ty)); 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) { fn visit_ty_common(&mut self, ty: &'a Ty) {
match ty.kind { match &ty.kind {
TyKind::BareFn(ref bfty) => { TyKind::BareFn(bfty) => {
self.check_fn_decl(&bfty.decl, SelfSemantic::No); self.check_fn_decl(&bfty.decl, SelfSemantic::No);
Self::check_decl_no_pat(&bfty.decl, |span, _, _| { Self::check_decl_no_pat(&bfty.decl, |span, _, _| {
struct_span_err!( struct_span_err!(
@ -756,10 +756,10 @@ impl<'a> AstValidator<'a> {
self.maybe_lint_missing_abi(sig_span, ty.id); self.maybe_lint_missing_abi(sig_span, ty.id);
} }
} }
TyKind::TraitObject(ref bounds, ..) => { TyKind::TraitObject(bounds, ..) => {
let mut any_lifetime_bounds = false; let mut any_lifetime_bounds = false;
for bound in bounds { for bound in bounds {
if let GenericBound::Outlives(ref lifetime) = *bound { if let GenericBound::Outlives(lifetime) = bound {
if any_lifetime_bounds { if any_lifetime_bounds {
struct_span_err!( struct_span_err!(
self.session, self.session,
@ -774,7 +774,7 @@ impl<'a> AstValidator<'a> {
} }
} }
} }
TyKind::ImplTrait(_, ref bounds) => { TyKind::ImplTrait(_, bounds) => {
if self.is_impl_trait_banned { if self.is_impl_trait_banned {
struct_span_err!( struct_span_err!(
self.session, self.session,
@ -842,8 +842,8 @@ fn validate_generic_param_order(
let (kind, bounds, span) = (&param.kind, &param.bounds, ident.span); let (kind, bounds, span) = (&param.kind, &param.bounds, ident.span);
let (ord_kind, ident) = match &param.kind { let (ord_kind, ident) = match &param.kind {
GenericParamKind::Lifetime => (ParamKindOrd::Lifetime, ident.to_string()), GenericParamKind::Lifetime => (ParamKindOrd::Lifetime, ident.to_string()),
GenericParamKind::Type { default: _ } => (ParamKindOrd::TypeOrConst, ident.to_string()), GenericParamKind::Type { .. } => (ParamKindOrd::TypeOrConst, ident.to_string()),
GenericParamKind::Const { ref ty, kw_span: _, default: _ } => { GenericParamKind::Const { ty, .. } => {
let ty = pprust::ty_to_string(ty); let ty = pprust::ty_to_string(ty);
(ParamKindOrd::TypeOrConst, format!("const {}: {}", ident, ty)) (ParamKindOrd::TypeOrConst, format!("const {}: {}", ident, ty))
} }
@ -912,7 +912,7 @@ fn validate_generic_param_order(
impl<'a> Visitor<'a> for AstValidator<'a> { impl<'a> Visitor<'a> for AstValidator<'a> {
fn visit_attribute(&mut self, attr: &Attribute) { fn visit_attribute(&mut self, attr: &Attribute) {
validate_attr::check_meta(&self.session.parse_sess, attr); validate_attr::check_attr(&self.session.parse_sess, attr);
} }
fn visit_expr(&mut self, expr: &'a Expr) { fn visit_expr(&mut self, expr: &'a Expr) {
@ -948,8 +948,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
} }
ExprKind::Paren(local_expr) => { ExprKind::Paren(local_expr) => {
fn has_let_expr(expr: &Expr) -> bool { fn has_let_expr(expr: &Expr) -> bool {
match expr.kind { match &expr.kind {
ExprKind::Binary(_, ref lhs, ref rhs) => has_let_expr(lhs) || has_let_expr(rhs), ExprKind::Binary(_, lhs, rhs) => has_let_expr(lhs) || has_let_expr(rhs),
ExprKind::Let(..) => true, ExprKind::Let(..) => true,
_ => false, _ => false,
} }
@ -1005,18 +1005,18 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
self.check_nomangle_item_asciionly(item.ident, item.span); self.check_nomangle_item_asciionly(item.ident, item.span);
} }
match item.kind { match &item.kind {
ItemKind::Impl(box Impl { ItemKind::Impl(box Impl {
unsafety, unsafety,
polarity, polarity,
defaultness: _, defaultness: _,
constness, constness,
ref generics, generics,
of_trait: Some(ref t), of_trait: Some(t),
ref self_ty, self_ty,
ref items, 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); this.invalid_visibility(&item.vis, None);
if let TyKind::Err = self_ty.kind { if let TyKind::Err = self_ty.kind {
this.err_handler() this.err_handler()
@ -1027,7 +1027,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
.help("use `auto trait Trait {}` instead") .help("use `auto trait Trait {}` instead")
.emit(); .emit();
} }
if let (Unsafe::Yes(span), ImplPolarity::Negative(sp)) = (unsafety, polarity) { if let (&Unsafe::Yes(span), &ImplPolarity::Negative(sp)) = (unsafety, polarity)
{
struct_span_err!( struct_span_err!(
this.session, this.session,
sp.to(t.path.span), 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!(this, visit_assoc_item, items, AssocCtxt::Impl);
}); });
walk_list!(self, visit_attribute, &item.attrs);
return; // Avoid visiting again. return; // Avoid visiting again.
} }
ItemKind::Impl(box Impl { ItemKind::Impl(box Impl {
@ -1060,7 +1062,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
constness, constness,
generics: _, generics: _,
of_trait: None, of_trait: None,
ref self_ty, self_ty,
items: _, items: _,
}) => { }) => {
let error = |annotation_span, annotation| { let error = |annotation_span, annotation| {
@ -1077,25 +1079,25 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
&item.vis, &item.vis,
Some(InvalidVisibilityNote::IndividualImplItems), Some(InvalidVisibilityNote::IndividualImplItems),
); );
if let Unsafe::Yes(span) = unsafety { if let &Unsafe::Yes(span) = unsafety {
error(span, "unsafe").code(error_code!(E0197)).emit(); error(span, "unsafe").code(error_code!(E0197)).emit();
} }
if let ImplPolarity::Negative(span) = polarity { if let &ImplPolarity::Negative(span) = polarity {
error(span, "negative").emit(); error(span, "negative").emit();
} }
if let Defaultness::Default(def_span) = defaultness { if let &Defaultness::Default(def_span) = defaultness {
error(def_span, "`default`") error(def_span, "`default`")
.note("only trait implementations may be annotated with `default`") .note("only trait implementations may be annotated with `default`")
.emit(); .emit();
} }
if let Const::Yes(span) = constness { if let &Const::Yes(span) = constness {
error(span, "`const`") error(span, "`const`")
.note("only trait implementations may be annotated with `const`") .note("only trait implementations may be annotated with `const`")
.emit(); .emit();
} }
} }
ItemKind::Fn(box Fn { defaultness, ref sig, ref generics, ref body }) => { ItemKind::Fn(box Fn { defaultness, sig, generics, body }) => {
self.check_defaultness(item.span, defaultness); self.check_defaultness(item.span, *defaultness);
if body.is_none() { if body.is_none() {
self.session.emit_err(FnWithoutBody { self.session.emit_err(FnWithoutBody {
@ -1131,7 +1133,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
&item.vis, &item.vis,
Some(InvalidVisibilityNote::IndividualForeignItems), 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"); self.err_handler().span_err(span, "extern block cannot be declared unsafe");
} }
if abi.is_none() { if abi.is_none() {
@ -1141,7 +1143,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
self.extern_mod = old_item; self.extern_mod = old_item;
return; // Avoid visiting again. return; // Avoid visiting again.
} }
ItemKind::Enum(ref def, _) => { ItemKind::Enum(def, _) => {
for variant in &def.variants { for variant in &def.variants {
self.invalid_visibility(&variant.vis, None); self.invalid_visibility(&variant.vis, None);
for field in variant.data.fields() { 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, .. }) => { ItemKind::Trait(box Trait { is_auto, generics, bounds, items, .. }) => {
if is_auto == IsAuto::Yes { if *is_auto == IsAuto::Yes {
// Auto traits cannot have generics, super traits nor contain items. // Auto traits cannot have generics, super traits nor contain items.
self.deny_generic_params(generics, item.ident.span); self.deny_generic_params(generics, item.ident.span);
self.deny_super_traits(bounds, 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_assoc_item, items, AssocCtxt::Trait);
walk_list!(self, visit_attribute, &item.attrs); walk_list!(self, visit_attribute, &item.attrs);
return; return; // Avoid visiting again
} }
ItemKind::Mod(unsafety, ref mod_kind) => { ItemKind::Mod(unsafety, mod_kind) => {
if let Unsafe::Yes(span) = unsafety { if let &Unsafe::Yes(span) = unsafety {
self.err_handler().span_err(span, "module cannot be declared unsafe"); self.err_handler().span_err(span, "module cannot be declared unsafe");
} }
// Ensure that `path` attributes on modules are recorded as used (cf. issue #35584). // 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); self.check_mod_file_item_asciionly(item.ident);
} }
} }
ItemKind::Union(ref vdata, ..) => { ItemKind::Union(vdata, ..) => {
if vdata.fields().is_empty() { if vdata.fields().is_empty() {
self.err_handler().span_err(item.span, "unions cannot have zero fields"); self.err_handler().span_err(item.span, "unions cannot have zero fields");
} }
} }
ItemKind::Const(def, .., None) => { ItemKind::Const(def, .., None) => {
self.check_defaultness(item.span, def); self.check_defaultness(item.span, *def);
self.session.emit_err(ConstWithoutBody { self.session.emit_err(ConstWithoutBody {
span: item.span, span: item.span,
replace_span: self.ending_semi_or_hi(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), replace_span: self.ending_semi_or_hi(item.span),
}); });
} }
ItemKind::TyAlias(box TyAlias { ItemKind::TyAlias(box TyAlias { defaultness, where_clauses, bounds, ty, .. }) => {
defaultness, self.check_defaultness(item.span, *defaultness);
where_clauses,
ref bounds,
ref ty,
..
}) => {
self.check_defaultness(item.span, defaultness);
if ty.is_none() { if ty.is_none() {
self.session.emit_err(TyAliasWithoutBody { self.session.emit_err(TyAliasWithoutBody {
span: item.span, span: item.span,
@ -1265,8 +1261,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
// Mirrors `visit::walk_generic_args`, but tracks relevant state. // Mirrors `visit::walk_generic_args`, but tracks relevant state.
fn visit_generic_args(&mut self, generic_args: &'a GenericArgs) { fn visit_generic_args(&mut self, generic_args: &'a GenericArgs) {
match *generic_args { match generic_args {
GenericArgs::AngleBracketed(ref data) => { GenericArgs::AngleBracketed(data) => {
self.check_generic_args_before_constraints(data); self.check_generic_args_before_constraints(data);
for arg in &data.args { 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); walk_list!(self, visit_ty, &data.inputs);
if let FnRetTy::Ty(ty) = &data.output { if let FnRetTy::Ty(ty) = &data.output {
// `-> Foo` syntax is essentially an associated type binding, // `-> 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); validate_generic_param_order(self.err_handler(), &generics.params, generics.span);
for predicate in &generics.where_clause.predicates { 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); 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) { 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) { match (ctxt, modify) {
(BoundKind::SuperTraits, TraitBoundModifier::Maybe) => { (BoundKind::SuperTraits, TraitBoundModifier::Maybe) => {
let mut err = self let mut err = self
@ -1572,8 +1568,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
self.check_item_named(item.ident, "const"); self.check_item_named(item.ident, "const");
} }
match item.kind { match &item.kind {
AssocItemKind::Type(box TyAlias { ref generics, ref bounds, ref ty, .. }) AssocItemKind::Type(box TyAlias { generics, bounds, ty, .. })
if ctxt == AssocCtxt::Trait => if ctxt == AssocCtxt::Trait =>
{ {
self.visit_vis(&item.vis); self.visit_vis(&item.vis);
@ -1585,7 +1581,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
}); });
walk_list!(self, visit_ty, ty); 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 if self.in_const_trait_impl
|| ctxt == AssocCtxt::Trait || ctxt == AssocCtxt::Trait
|| matches!(sig.header.constness, Const::Yes(_)) => || matches!(sig.header.constness, Const::Yes(_)) =>
@ -1636,7 +1632,7 @@ fn deny_equality_constraints(
// Remove `Bar` from `Foo::Bar`. // Remove `Bar` from `Foo::Bar`.
assoc_path.segments.pop(); assoc_path.segments.pop();
let len = assoc_path.segments.len() - 1; 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>`. // Build `<Bar = RhsTy>`.
let arg = AngleBracketedArg::Constraint(AssocConstraint { let arg = AngleBracketedArg::Constraint(AssocConstraint {
id: rustc_ast::node_id::DUMMY_NODE_ID, id: rustc_ast::node_id::DUMMY_NODE_ID,

View File

@ -198,8 +198,8 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
} }
fn visit_item(&mut self, i: &'a ast::Item) { fn visit_item(&mut self, i: &'a ast::Item) {
match i.kind { match &i.kind {
ast::ItemKind::ForeignMod(ref foreign_module) => { ast::ItemKind::ForeignMod(foreign_module) => {
if let Some(abi) = foreign_module.abi { if let Some(abi) = foreign_module.abi {
self.check_abi(abi, ast::Const::No); 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, .. }) => { ast::ItemKind::Impl(box ast::Impl { polarity, defaultness, of_trait, .. }) => {
if let ast::ImplPolarity::Negative(span) = polarity { if let &ast::ImplPolarity::Negative(span) = polarity {
gate_feature_post!( gate_feature_post!(
&self, &self,
negative_impls, negative_impls,
@ -267,7 +267,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
gate_feature_post!(&self, decl_macro, i.span, msg); 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) 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) { fn visit_ty(&mut self, ty: &'a ast::Ty) {
match ty.kind { match &ty.kind {
ast::TyKind::BareFn(ref bare_fn_ty) => { ast::TyKind::BareFn(bare_fn_ty) => {
// Function pointers cannot be `const` // Function pointers cannot be `const`
self.check_extern(bare_fn_ty.ext, ast::Const::No); 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) { 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 { if let ast::TyKind::Never = output_ty.kind {
// Do nothing. // Do nothing.
} else { } else {
@ -455,9 +455,9 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
} }
fn visit_assoc_item(&mut self, i: &'a ast::AssocItem, ctxt: AssocCtxt) { 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::Fn(_) => true,
ast::AssocItemKind::Type(box ast::TyAlias { ref ty, .. }) => { ast::AssocItemKind::Type(box ast::TyAlias { ty, .. }) => {
if let (Some(_), AssocCtxt::Trait) = (ty, ctxt) { if let (Some(_), AssocCtxt::Trait) = (ty, ctxt) {
gate_feature_post!( gate_feature_post!(
&self, &self,

View File

@ -36,8 +36,8 @@ impl Printer {
self.nbsp() self.nbsp()
} }
// Synthesizes a comment that was not textually present in the original /// Synthesizes a comment that was not textually present in the original
// source file. /// source file.
pub fn synth_comment(&mut self, text: impl Into<Cow<'static, str>>) { pub fn synth_comment(&mut self, text: impl Into<Cow<'static, str>>) {
self.word("/*"); self.word("/*");
self.space(); self.space();

View File

@ -11,16 +11,15 @@ use rustc_ast::tokenstream::{TokenStream, TokenTree};
use rustc_ast::util::classify; use rustc_ast::util::classify;
use rustc_ast::util::comments::{gather_comments, Comment, CommentStyle}; use rustc_ast::util::comments::{gather_comments, Comment, CommentStyle};
use rustc_ast::util::parser; use rustc_ast::util::parser;
use rustc_ast::{self as ast, BlockCheckMode, Mutability, PatKind, RangeEnd, RangeSyntax}; use rustc_ast::{self as ast, AttrArgs, AttrArgsEq, BlockCheckMode, PatKind};
use rustc_ast::{attr, BindingAnnotation, ByRef, Term}; use rustc_ast::{attr, BindingAnnotation, ByRef, DelimArgs, RangeEnd, RangeSyntax, Term};
use rustc_ast::{GenericArg, MacArgs, MacArgsEq}; use rustc_ast::{GenericArg, GenericBound, SelfKind, TraitBoundModifier};
use rustc_ast::{GenericBound, SelfKind, TraitBoundModifier};
use rustc_ast::{InlineAsmOperand, InlineAsmRegOrRegClass}; use rustc_ast::{InlineAsmOperand, InlineAsmRegOrRegClass};
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece}; use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
use rustc_span::edition::Edition; use rustc_span::edition::Edition;
use rustc_span::source_map::{SourceMap, Spanned}; use rustc_span::source_map::{SourceMap, Spanned};
use rustc_span::symbol::{kw, sym, Ident, IdentPrinter, Symbol}; 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 rustc_ast::attr::AttrIdGenerator;
use std::borrow::Cow; use std::borrow::Cow;
@ -65,6 +64,7 @@ impl<'a> Comments<'a> {
Comments { sm, comments, current: 0 } Comments { sm, comments, current: 0 }
} }
// FIXME: This shouldn't probably clone lmao
pub fn next(&self) -> Option<Comment> { pub fn next(&self) -> Option<Comment> {
self.comments.get(self.current).cloned() 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. // of the feature gate, so we fake them up here.
// `#![feature(prelude_import)]` // `#![feature(prelude_import)]`
let pi_nested = attr::mk_nested_word_item(Ident::with_dummy_span(sym::prelude_import)); let fake_attr = attr::mk_attr_nested_word(
let list = attr::mk_list_item(Ident::with_dummy_span(sym::feature), vec![pi_nested]); g,
let fake_attr = attr::mk_attr_inner(g, list); ast::AttrStyle::Inner,
sym::feature,
sym::prelude_import,
DUMMY_SP,
);
s.print_attribute(&fake_attr); s.print_attribute(&fake_attr);
// Currently, in Rust 2018 we don't have `extern crate std;` at the crate // Currently, in Rust 2018 we don't have `extern crate std;` at the crate
// root, so this is not needed, and actually breaks things. // root, so this is not needed, and actually breaks things.
if edition == Edition::Edition2015 { if edition == Edition::Edition2015 {
// `#![no_std]` // `#![no_std]`
let no_std_meta = attr::mk_word_item(Ident::with_dummy_span(sym::no_std)); let fake_attr = attr::mk_attr_word(g, ast::AttrStyle::Inner, sym::no_std, DUMMY_SP);
let fake_attr = attr::mk_attr_inner(g, no_std_meta);
s.print_attribute(&fake_attr); 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 { fn maybe_print_comment(&mut self, pos: BytePos) -> bool {
let mut has_comment = false; let mut has_comment = false;
while let Some(ref cmnt) = self.next_comment() { while let Some(cmnt) = self.next_comment() {
if cmnt.pos < pos { if cmnt.pos < pos {
has_comment = true; has_comment = true;
self.print_comment(cmnt); self.print_comment(&cmnt);
} else { } else {
break; break;
} }
@ -367,14 +370,18 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
if self.next_comment().is_none() { if self.next_comment().is_none() {
self.hardbreak(); self.hardbreak();
} }
while let Some(ref cmnt) = self.next_comment() { while let Some(cmnt) = self.next_comment() {
self.print_comment(cmnt) self.print_comment(&cmnt)
} }
} }
fn print_literal(&mut self, lit: &ast::Lit) { fn print_meta_item_lit(&mut self, lit: &ast::MetaItemLit) {
self.maybe_print_comment(lit.span.lo()); self.print_token_literal(lit.token_lit, lit.span)
self.word(lit.token_lit.to_string()) }
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) { 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.hardbreak_if_not_bol();
} }
self.maybe_print_comment(attr.span.lo()); self.maybe_print_comment(attr.span.lo());
match attr.kind { match &attr.kind {
ast::AttrKind::Normal(ref normal) => { ast::AttrKind::Normal(normal) => {
match attr.style { match attr.style {
ast::AttrStyle::Inner => self.word("#!["), ast::AttrStyle::Inner => self.word("#!["),
ast::AttrStyle::Outer => 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("]"); self.word("]");
} }
ast::AttrKind::DocComment(comment_kind, data) => { 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() 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) { fn print_attr_item(&mut self, item: &ast::AttrItem, span: Span) {
self.ibox(0); self.ibox(0);
match &item.args { 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)), Some(MacHeader::Path(&item.path)),
false, false,
None, None,
Some(delim.to_token()), delim.to_token(),
tokens, tokens,
true, true,
span, span,
), ),
MacArgs::Empty => { AttrArgs::Empty => {
self.print_path(&item.path, false, 0); 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.print_path(&item.path, false, 0);
self.space(); self.space();
self.word_space("="); self.word_space("=");
let token_str = self.expr_to_string(expr); let token_str = self.expr_to_string(expr);
self.word(token_str); self.word(token_str);
} }
MacArgs::Eq(_, MacArgsEq::Hir(lit)) => { AttrArgs::Eq(_, AttrArgsEq::Hir(lit)) => {
self.print_path(&item.path, false, 0); self.print_path(&item.path, false, 0);
self.space(); self.space();
self.word_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); 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) { fn print_meta_list_item(&mut self, item: &ast::NestedMetaItem) {
match item { match item {
ast::NestedMetaItem::MetaItem(ref mi) => self.print_meta_item(mi), ast::NestedMetaItem::MetaItem(mi) => self.print_meta_item(mi),
ast::NestedMetaItem::Literal(ref lit) => self.print_literal(lit), ast::NestedMetaItem::Lit(lit) => self.print_meta_item_lit(lit),
} }
} }
fn print_meta_item(&mut self, item: &ast::MetaItem) { fn print_meta_item(&mut self, item: &ast::MetaItem) {
self.ibox(INDENT_UNIT); self.ibox(INDENT_UNIT);
match item.kind { match &item.kind {
ast::MetaItemKind::Word => self.print_path(&item.path, false, 0), 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.print_path(&item.path, false, 0);
self.space(); self.space();
self.word_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.print_path(&item.path, false, 0);
self.popen(); 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(); 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) { fn print_tt(&mut self, tt: &TokenTree, convert_dollar_crate: bool) {
match tt { match tt {
TokenTree::Token(token, _) => { 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); self.word(token_str);
if let token::DocComment(..) = token.kind { if let token::DocComment(..) = token.kind {
self.hardbreak() self.hardbreak()
@ -540,7 +547,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
None, None,
false, false,
None, None,
Some(*delim), *delim,
tts, tts,
convert_dollar_crate, convert_dollar_crate,
dspan.entire(), dspan.entire(),
@ -566,12 +573,12 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
header: Option<MacHeader<'_>>, header: Option<MacHeader<'_>>,
has_bang: bool, has_bang: bool,
ident: Option<Ident>, ident: Option<Ident>,
delim: Option<Delimiter>, delim: Delimiter,
tts: &TokenStream, tts: &TokenStream,
convert_dollar_crate: bool, convert_dollar_crate: bool,
span: Span, span: Span,
) { ) {
if delim == Some(Delimiter::Brace) { if delim == Delimiter::Brace {
self.cbox(INDENT_UNIT); self.cbox(INDENT_UNIT);
} }
match header { match header {
@ -587,7 +594,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
self.print_ident(ident); self.print_ident(ident);
} }
match delim { match delim {
Some(Delimiter::Brace) => { Delimiter::Brace => {
if header.is_some() || has_bang || ident.is_some() { if header.is_some() || has_bang || ident.is_some() {
self.nbsp(); self.nbsp();
} }
@ -601,7 +608,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
let empty = tts.is_empty(); let empty = tts.is_empty();
self.bclose(span, empty); self.bclose(span, empty);
} }
Some(delim) => { delim => {
let token_str = self.token_kind_to_string(&token::OpenDelim(delim)); let token_str = self.token_kind_to_string(&token::OpenDelim(delim));
self.word(token_str); self.word(token_str);
self.ibox(0); 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)); let token_str = self.token_kind_to_string(&token::CloseDelim(delim));
self.word(token_str); 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)), Some(MacHeader::Keyword(kw)),
has_bang, has_bang,
Some(*ident), Some(*ident),
macro_def.body.delim(), macro_def.body.delim.to_token(),
&macro_def.body.inner_tokens(), &macro_def.body.tokens.clone(),
true, true,
sp, 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) { fn print_path_segment(&mut self, segment: &ast::PathSegment, colons_before_params: bool) {
if segment.ident.name != kw::PathRoot { if segment.ident.name != kw::PathRoot {
self.print_ident(segment.ident); 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); 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 { fn nonterminal_to_string(&self, nt: &Nonterminal) -> String {
match *nt { match nt {
token::NtExpr(ref e) => self.expr_to_string(e), token::NtExpr(e) => self.expr_to_string(e),
token::NtMeta(ref e) => self.attr_item_to_string(e), token::NtMeta(e) => self.attr_item_to_string(e),
token::NtTy(ref e) => self.ty_to_string(e), token::NtTy(e) => self.ty_to_string(e),
token::NtPath(ref e) => self.path_to_string(e), token::NtPath(e) => self.path_to_string(e),
token::NtItem(ref e) => self.item_to_string(e), token::NtItem(e) => self.item_to_string(e),
token::NtBlock(ref e) => self.block_to_string(e), token::NtBlock(e) => self.block_to_string(e),
token::NtStmt(ref e) => self.stmt_to_string(e), token::NtStmt(e) => self.stmt_to_string(e),
token::NtPat(ref e) => self.pat_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::NtIdent(e, is_raw) => IdentPrinter::for_ast_ident(*e, *is_raw).to_string(),
token::NtLifetime(e) => e.to_string(), token::NtLifetime(e) => e.to_string(),
token::NtLiteral(ref e) => self.expr_to_string(e), token::NtLiteral(e) => self.expr_to_string(e),
token::NtVis(ref e) => self.vis_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)) Self::to_string(|s| s.print_expr(e))
} }
fn literal_to_string(&self, lit: &ast::Lit) -> String { fn meta_item_lit_to_string(&self, lit: &ast::MetaItemLit) -> String {
Self::to_string(|s| s.print_literal(lit)) Self::to_string(|s| s.print_meta_item_lit(lit))
} }
fn tt_to_string(&self, tt: &TokenTree) -> String { fn tt_to_string(&self, tt: &TokenTree) -> String {
@ -919,8 +921,8 @@ impl<'a> PrintState<'a> for State<'a> {
self.word("::") self.word("::")
} }
match *args { match args {
ast::GenericArgs::AngleBracketed(ref data) => { ast::GenericArgs::AngleBracketed(data) => {
self.word("<"); self.word("<");
self.commasep(Inconsistent, &data.args, |s, arg| match arg { self.commasep(Inconsistent, &data.args, |s, arg| match arg {
ast::AngleBracketedArg::Arg(a) => s.print_generic_arg(a), ast::AngleBracketedArg::Arg(a) => s.print_generic_arg(a),
@ -929,7 +931,7 @@ impl<'a> PrintState<'a> for State<'a> {
self.word(">") self.word(">")
} }
ast::GenericArgs::Parenthesized(ref data) => { ast::GenericArgs::Parenthesized(data) => {
self.word("("); self.word("(");
self.commasep(Inconsistent, &data.inputs, |s, ty| s.print_type(ty)); self.commasep(Inconsistent, &data.inputs, |s, ty| s.print_type(ty));
self.word(")"); self.word(")");
@ -996,7 +998,7 @@ impl<'a> State<'a> {
ast::AssocConstraintKind::Bound { bounds } => { ast::AssocConstraintKind::Bound { bounds } => {
if !bounds.is_empty() { if !bounds.is_empty() {
self.word_nbsp(":"); 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) { pub fn print_type(&mut self, ty: &ast::Ty) {
self.maybe_print_comment(ty.span.lo()); self.maybe_print_comment(ty.span.lo());
self.ibox(0); self.ibox(0);
match ty.kind { match &ty.kind {
ast::TyKind::Slice(ref ty) => { ast::TyKind::Slice(ty) => {
self.word("["); self.word("[");
self.print_type(ty); self.print_type(ty);
self.word("]"); self.word("]");
} }
ast::TyKind::Ptr(ref mt) => { ast::TyKind::Ptr(mt) => {
self.word("*"); self.word("*");
self.print_mt(mt, true); self.print_mt(mt, true);
} }
ast::TyKind::Rptr(ref lifetime, ref mt) => { ast::TyKind::Rptr(lifetime, mt) => {
self.word("&"); self.word("&");
self.print_opt_lifetime(lifetime); self.print_opt_lifetime(lifetime);
self.print_mt(mt, false); self.print_mt(mt, false);
@ -1031,44 +1033,44 @@ impl<'a> State<'a> {
ast::TyKind::Never => { ast::TyKind::Never => {
self.word("!"); self.word("!");
} }
ast::TyKind::Tup(ref elts) => { ast::TyKind::Tup(elts) => {
self.popen(); 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 { if elts.len() == 1 {
self.word(","); self.word(",");
} }
self.pclose(); self.pclose();
} }
ast::TyKind::Paren(ref typ) => { ast::TyKind::Paren(typ) => {
self.popen(); self.popen();
self.print_type(typ); self.print_type(typ);
self.pclose(); 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); 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); self.print_path(path, false, 0);
} }
ast::TyKind::Path(Some(ref qself), ref path) => self.print_qpath(path, qself, false), ast::TyKind::Path(Some(qself), path) => self.print_qpath(path, qself, false),
ast::TyKind::TraitObject(ref bounds, syntax) => { ast::TyKind::TraitObject(bounds, syntax) => {
if syntax == ast::TraitObjectSyntax::Dyn { if *syntax == ast::TraitObjectSyntax::Dyn {
self.word_nbsp("dyn"); self.word_nbsp("dyn");
} }
self.print_type_bounds(bounds); self.print_type_bounds(bounds);
} }
ast::TyKind::ImplTrait(_, ref bounds) => { ast::TyKind::ImplTrait(_, bounds) => {
self.word_nbsp("impl"); self.word_nbsp("impl");
self.print_type_bounds(bounds); self.print_type_bounds(bounds);
} }
ast::TyKind::Array(ref ty, ref length) => { ast::TyKind::Array(ty, length) => {
self.word("["); self.word("[");
self.print_type(ty); self.print_type(ty);
self.word("; "); self.word("; ");
self.print_expr(&length.value); self.print_expr(&length.value);
self.word("]"); self.word("]");
} }
ast::TyKind::Typeof(ref e) => { ast::TyKind::Typeof(e) => {
self.word("typeof("); self.word("typeof(");
self.print_expr(&e.value); self.print_expr(&e.value);
self.word(")"); self.word(")");
@ -1084,7 +1086,7 @@ impl<'a> State<'a> {
ast::TyKind::ImplicitSelf => { ast::TyKind::ImplicitSelf => {
self.word("Self"); self.word("Self");
} }
ast::TyKind::MacCall(ref m) => { ast::TyKind::MacCall(m) => {
self.print_mac(m); self.print_mac(m);
} }
ast::TyKind::CVarArgs => { ast::TyKind::CVarArgs => {
@ -1113,8 +1115,8 @@ impl<'a> State<'a> {
pub(crate) fn print_stmt(&mut self, st: &ast::Stmt) { pub(crate) fn print_stmt(&mut self, st: &ast::Stmt) {
self.maybe_print_comment(st.span.lo()); self.maybe_print_comment(st.span.lo());
match st.kind { match &st.kind {
ast::StmtKind::Local(ref loc) => { ast::StmtKind::Local(loc) => {
self.print_outer_attributes(&loc.attrs); self.print_outer_attributes(&loc.attrs);
self.space_if_not_bol(); self.space_if_not_bol();
self.ibox(INDENT_UNIT); self.ibox(INDENT_UNIT);
@ -1137,15 +1139,15 @@ impl<'a> State<'a> {
self.word(";"); self.word(";");
self.end(); // `let` ibox self.end(); // `let` ibox
} }
ast::StmtKind::Item(ref item) => self.print_item(item), ast::StmtKind::Item(item) => self.print_item(item),
ast::StmtKind::Expr(ref expr) => { ast::StmtKind::Expr(expr) => {
self.space_if_not_bol(); self.space_if_not_bol();
self.print_expr_outer_attr_style(expr, false); self.print_expr_outer_attr_style(expr, false);
if classify::expr_requires_semi_to_be_stmt(expr) { if classify::expr_requires_semi_to_be_stmt(expr) {
self.word(";"); self.word(";");
} }
} }
ast::StmtKind::Semi(ref expr) => { ast::StmtKind::Semi(expr) => {
self.space_if_not_bol(); self.space_if_not_bol();
self.print_expr_outer_attr_style(expr, false); self.print_expr_outer_attr_style(expr, false);
self.word(";"); self.word(";");
@ -1154,7 +1156,7 @@ impl<'a> State<'a> {
self.space_if_not_bol(); self.space_if_not_bol();
self.word(";"); self.word(";");
} }
ast::StmtKind::MacCall(ref mac) => { ast::StmtKind::MacCall(mac) => {
self.space_if_not_bol(); self.space_if_not_bol();
self.print_outer_attributes(&mac.attrs); self.print_outer_attributes(&mac.attrs);
self.print_mac(&mac.mac); self.print_mac(&mac.mac);
@ -1195,8 +1197,8 @@ impl<'a> State<'a> {
let has_attrs = self.print_inner_attributes(attrs); let has_attrs = self.print_inner_attributes(attrs);
for (i, st) in blk.stmts.iter().enumerate() { for (i, st) in blk.stmts.iter().enumerate() {
match st.kind { match &st.kind {
ast::StmtKind::Expr(ref expr) if i == blk.stmts.len() - 1 => { ast::StmtKind::Expr(expr) if i == blk.stmts.len() - 1 => {
self.maybe_print_comment(st.span.lo()); self.maybe_print_comment(st.span.lo());
self.space_if_not_bol(); self.space_if_not_bol();
self.print_expr_outer_attr_style(expr, false); self.print_expr_outer_attr_style(expr, false);
@ -1226,8 +1228,8 @@ impl<'a> State<'a> {
Some(MacHeader::Path(&m.path)), Some(MacHeader::Path(&m.path)),
true, true,
None, None,
m.args.delim(), m.args.delim.to_token(),
&m.args.inner_tokens(), &m.args.tokens.clone(),
true, true,
m.span(), m.span(),
); );
@ -1252,7 +1254,7 @@ impl<'a> State<'a> {
self.popen(); self.popen();
self.commasep(Consistent, &args, |s, arg| match arg { 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) => { AsmArg::Operand(op) => {
let print_reg_or_class = |s: &mut Self, r: &InlineAsmRegOrRegClass| match r { let print_reg_or_class = |s: &mut Self, r: &InlineAsmRegOrRegClass| match r {
InlineAsmRegOrRegClass::Reg(r) => s.print_symbol(*r, ast::StrStyle::Cooked), 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) { pub(crate) fn print_local_decl(&mut self, loc: &ast::Local) {
self.print_pat(&loc.pat); self.print_pat(&loc.pat);
if let Some(ref ty) = loc.ty { if let Some(ty) = &loc.ty {
self.word_space(":"); self.word_space(":");
self.print_type(ty); self.print_type(ty);
} }
@ -1388,7 +1390,7 @@ impl<'a> State<'a> {
for item_segment in &path.segments[qself.position..] { for item_segment in &path.segments[qself.position..] {
self.word("::"); self.word("::");
self.print_ident(item_segment.ident); 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) self.print_generic_args(args, colons_before_params)
} }
} }
@ -1399,42 +1401,42 @@ impl<'a> State<'a> {
self.ann.pre(self, AnnNode::Pat(pat)); self.ann.pre(self, AnnNode::Pat(pat));
/* Pat isn't normalized, but the beauty of it /* Pat isn't normalized, but the beauty of it
is that it doesn't matter */ is that it doesn't matter */
match pat.kind { match &pat.kind {
PatKind::Wild => self.word("_"), PatKind::Wild => self.word("_"),
PatKind::Ident(BindingAnnotation(by_ref, mutbl), ident, ref sub) => { PatKind::Ident(BindingAnnotation(by_ref, mutbl), ident, sub) => {
if by_ref == ByRef::Yes { if *by_ref == ByRef::Yes {
self.word_nbsp("ref"); self.word_nbsp("ref");
} }
if mutbl == Mutability::Mut { if mutbl.is_mut() {
self.word_nbsp("mut"); self.word_nbsp("mut");
} }
self.print_ident(ident); self.print_ident(*ident);
if let Some(ref p) = *sub { if let Some(p) = sub {
self.space(); self.space();
self.word_space("@"); self.word_space("@");
self.print_pat(p); self.print_pat(p);
} }
} }
PatKind::TupleStruct(ref qself, ref path, ref elts) => { PatKind::TupleStruct(qself, path, elts) => {
if let Some(qself) = qself { if let Some(qself) = qself {
self.print_qpath(path, qself, true); self.print_qpath(path, qself, true);
} else { } else {
self.print_path(path, true, 0); self.print_path(path, true, 0);
} }
self.popen(); self.popen();
self.commasep(Inconsistent, &elts, |s, p| s.print_pat(p)); self.commasep(Inconsistent, elts, |s, p| s.print_pat(p));
self.pclose(); self.pclose();
} }
PatKind::Or(ref pats) => { PatKind::Or(pats) => {
self.strsep("|", true, Inconsistent, &pats, |s, p| s.print_pat(p)); 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); self.print_path(path, true, 0);
} }
PatKind::Path(Some(ref qself), ref path) => { PatKind::Path(Some(qself), path) => {
self.print_qpath(path, qself, false); 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 { if let Some(qself) = qself {
self.print_qpath(path, qself, true); self.print_qpath(path, qself, true);
} else { } else {
@ -1448,7 +1450,7 @@ impl<'a> State<'a> {
} }
self.commasep_cmnt( self.commasep_cmnt(
Consistent, Consistent,
&fields, fields,
|s, f| { |s, f| {
s.cbox(INDENT_UNIT); s.cbox(INDENT_UNIT);
if !f.is_shorthand { if !f.is_shorthand {
@ -1460,7 +1462,7 @@ impl<'a> State<'a> {
}, },
|f| f.pat.span, |f| f.pat.span,
); );
if etc { if *etc {
if !fields.is_empty() { if !fields.is_empty() {
self.word_space(","); self.word_space(",");
} }
@ -1471,21 +1473,21 @@ impl<'a> State<'a> {
} }
self.word("}"); self.word("}");
} }
PatKind::Tuple(ref elts) => { PatKind::Tuple(elts) => {
self.popen(); 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 { if elts.len() == 1 {
self.word(","); self.word(",");
} }
self.pclose(); self.pclose();
} }
PatKind::Box(ref inner) => { PatKind::Box(inner) => {
self.word("box "); self.word("box ");
self.print_pat(inner); self.print_pat(inner);
} }
PatKind::Ref(ref inner, mutbl) => { PatKind::Ref(inner, mutbl) => {
self.word("&"); self.word("&");
if mutbl == Mutability::Mut { if mutbl.is_mut() {
self.word("mut "); self.word("mut ");
} }
if let PatKind::Ident(ast::BindingAnnotation::MUT, ..) = inner.kind { if let PatKind::Ident(ast::BindingAnnotation::MUT, ..) = inner.kind {
@ -1496,12 +1498,12 @@ impl<'a> State<'a> {
self.print_pat(inner); self.print_pat(inner);
} }
} }
PatKind::Lit(ref e) => self.print_expr(&**e), PatKind::Lit(e) => self.print_expr(e),
PatKind::Range(ref begin, ref end, Spanned { node: ref end_kind, .. }) => { PatKind::Range(begin, end, Spanned { node: end_kind, .. }) => {
if let Some(e) = begin { if let Some(e) = begin {
self.print_expr(e); self.print_expr(e);
} }
match *end_kind { match end_kind {
RangeEnd::Included(RangeSyntax::DotDotDot) => self.word("..."), RangeEnd::Included(RangeSyntax::DotDotDot) => self.word("..."),
RangeEnd::Included(RangeSyntax::DotDotEq) => self.word("..="), RangeEnd::Included(RangeSyntax::DotDotEq) => self.word("..="),
RangeEnd::Excluded => self.word(".."), RangeEnd::Excluded => self.word(".."),
@ -1510,36 +1512,36 @@ impl<'a> State<'a> {
self.print_expr(e); self.print_expr(e);
} }
} }
PatKind::Slice(ref elts) => { PatKind::Slice(elts) => {
self.word("["); self.word("[");
self.commasep(Inconsistent, &elts, |s, p| s.print_pat(p)); self.commasep(Inconsistent, elts, |s, p| s.print_pat(p));
self.word("]"); self.word("]");
} }
PatKind::Rest => self.word(".."), PatKind::Rest => self.word(".."),
PatKind::Paren(ref inner) => { PatKind::Paren(inner) => {
self.popen(); self.popen();
self.print_pat(inner); self.print_pat(inner);
self.pclose(); self.pclose();
} }
PatKind::MacCall(ref m) => self.print_mac(m), PatKind::MacCall(m) => self.print_mac(m),
} }
self.ann.post(self, AnnNode::Pat(pat)) self.ann.post(self, AnnNode::Pat(pat))
} }
fn print_explicit_self(&mut self, explicit_self: &ast::ExplicitSelf) { fn print_explicit_self(&mut self, explicit_self: &ast::ExplicitSelf) {
match explicit_self.node { match &explicit_self.node {
SelfKind::Value(m) => { SelfKind::Value(m) => {
self.print_mutability(m, false); self.print_mutability(*m, false);
self.word("self") self.word("self")
} }
SelfKind::Region(ref lt, m) => { SelfKind::Region(lt, m) => {
self.word("&"); self.word("&");
self.print_opt_lifetime(lt); self.print_opt_lifetime(lt);
self.print_mutability(m, false); self.print_mutability(*m, false);
self.word("self") self.word("self")
} }
SelfKind::Explicit(ref typ, m) => { SelfKind::Explicit(typ, m) => {
self.print_mutability(m, false); self.print_mutability(*m, false);
self.word("self"); self.word("self");
self.word_space(":"); self.word_space(":");
self.print_type(typ) self.print_type(typ)
@ -1598,10 +1600,10 @@ impl<'a> State<'a> {
self.word("<"); self.word("<");
self.commasep(Inconsistent, &generic_params, |s, param| { self.commasep(Inconsistent, generic_params, |s, param| {
s.print_outer_attributes_inline(&param.attrs); s.print_outer_attributes_inline(&param.attrs);
match param.kind { match &param.kind {
ast::GenericParamKind::Lifetime => { ast::GenericParamKind::Lifetime => {
let lt = ast::Lifetime { id: param.id, ident: param.ident }; let lt = ast::Lifetime { id: param.id, ident: param.ident };
s.print_lifetime(lt); s.print_lifetime(lt);
@ -1610,19 +1612,19 @@ impl<'a> State<'a> {
s.print_lifetime_bounds(&param.bounds) s.print_lifetime_bounds(&param.bounds)
} }
} }
ast::GenericParamKind::Type { ref default } => { ast::GenericParamKind::Type { default } => {
s.print_ident(param.ident); s.print_ident(param.ident);
if !param.bounds.is_empty() { if !param.bounds.is_empty() {
s.word_nbsp(":"); s.word_nbsp(":");
s.print_type_bounds(&param.bounds); s.print_type_bounds(&param.bounds);
} }
if let Some(ref default) = default { if let Some(default) = default {
s.space(); s.space();
s.word_space("="); s.word_space("=");
s.print_type(default) s.print_type(default)
} }
} }
ast::GenericParamKind::Const { ref ty, kw_span: _, ref default } => { ast::GenericParamKind::Const { ty, default, .. } => {
s.word_space("const"); s.word_space("const");
s.print_ident(param.ident); s.print_ident(param.ident);
s.space(); s.space();
@ -1632,7 +1634,7 @@ impl<'a> State<'a> {
s.word_nbsp(":"); s.word_nbsp(":");
s.print_type_bounds(&param.bounds); s.print_type_bounds(&param.bounds);
} }
if let Some(ref default) = default { if let Some(default) = default {
s.space(); s.space();
s.word_space("="); s.word_space("=");
s.print_expr(&default.value); s.print_expr(&default.value);
@ -1714,9 +1716,9 @@ impl<'a> State<'a> {
where_clause: ast::WhereClause { where_clause: ast::WhereClause {
has_where_token: false, has_where_token: false,
predicates: Vec::new(), 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() }; let header = ast::FnHeader { unsafety, ext, ..ast::FnHeader::default() };
self.print_fn(decl, header, name, &generics); self.print_fn(decl, header, name, &generics);
@ -1735,7 +1737,7 @@ impl<'a> State<'a> {
} }
ast::Extern::Explicit(abi, _) => { ast::Extern::Explicit(abi, _) => {
self.word_nbsp("extern"); self.word_nbsp("extern");
self.print_literal(&abi.as_lit()); self.print_token_literal(abi.as_token_lit(), abi.span);
self.nbsp(); self.nbsp();
} }
} }

View File

@ -8,9 +8,9 @@ use rustc_ast::{self as ast, BlockCheckMode};
impl<'a> State<'a> { impl<'a> State<'a> {
fn print_else(&mut self, els: Option<&ast::Expr>) { fn print_else(&mut self, els: Option<&ast::Expr>) {
if let Some(_else) = els { if let Some(_else) = els {
match _else.kind { match &_else.kind {
// Another `else if` block. // 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.cbox(INDENT_UNIT - 1);
self.ibox(0); self.ibox(0);
self.word(" else if "); self.word(" else if ");
@ -20,7 +20,7 @@ impl<'a> State<'a> {
self.print_else(e.as_deref()) self.print_else(e.as_deref())
} }
// Final `else` block. // Final `else` block.
ast::ExprKind::Block(ref b, _) => { ast::ExprKind::Block(b, _) => {
self.cbox(INDENT_UNIT - 1); self.cbox(INDENT_UNIT - 1);
self.ibox(0); self.ibox(0);
self.word(" else "); self.word(" else ");
@ -58,10 +58,10 @@ impl<'a> State<'a> {
self.print_expr_cond_paren(expr, Self::cond_needs_par(expr)) self.print_expr_cond_paren(expr, Self::cond_needs_par(expr))
} }
// Does `expr` need parentheses when printed in a condition position? /// Does `expr` need parentheses when printed in a condition position?
// ///
// These cases need parens due to the parse error observed in #26461: `if return {}` /// These cases need parens due to the parse error observed in #26461: `if return {}`
// parses as the erroneous construct `if (return {})`, not `if (return) {}`. /// parses as the erroneous construct `if (return {})`, not `if (return) {}`.
pub(super) fn cond_needs_par(expr: &ast::Expr) -> bool { pub(super) fn cond_needs_par(expr: &ast::Expr) -> bool {
match expr.kind { match expr.kind {
ast::ExprKind::Break(..) ast::ExprKind::Break(..)
@ -121,7 +121,7 @@ impl<'a> State<'a> {
fn print_expr_struct( fn print_expr_struct(
&mut self, &mut self,
qself: &Option<ast::QSelf>, qself: &Option<P<ast::QSelf>>,
path: &ast::Path, path: &ast::Path,
fields: &[ast::ExprField], fields: &[ast::ExprField],
rest: &ast::StructRest, rest: &ast::StructRest,
@ -202,7 +202,7 @@ impl<'a> State<'a> {
self.print_expr_maybe_paren(receiver, parser::PREC_POSTFIX); self.print_expr_maybe_paren(receiver, parser::PREC_POSTFIX);
self.word("."); self.word(".");
self.print_ident(segment.ident); 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_generic_args(args, true);
} }
self.print_call_post(base_args) self.print_call_post(base_args)
@ -284,64 +284,66 @@ impl<'a> State<'a> {
self.ibox(INDENT_UNIT); self.ibox(INDENT_UNIT);
self.ann.pre(self, AnnNode::Expr(expr)); self.ann.pre(self, AnnNode::Expr(expr));
match expr.kind { match &expr.kind {
ast::ExprKind::Box(ref expr) => { ast::ExprKind::Box(expr) => {
self.word_space("box"); self.word_space("box");
self.print_expr_maybe_paren(expr, parser::PREC_PREFIX); self.print_expr_maybe_paren(expr, parser::PREC_PREFIX);
} }
ast::ExprKind::Array(ref exprs) => { ast::ExprKind::Array(exprs) => {
self.print_expr_vec(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); 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); 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); 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); self.print_expr_tup(exprs);
} }
ast::ExprKind::Call(ref func, ref args) => { ast::ExprKind::Call(func, args) => {
self.print_expr_call(func, &args); self.print_expr_call(func, args);
} }
ast::ExprKind::MethodCall(ref segment, ref receiver, ref args, _) => { ast::ExprKind::MethodCall(box ast::MethodCall { seg, receiver, args, .. }) => {
self.print_expr_method_call(segment, &receiver, &args); self.print_expr_method_call(seg, receiver, args);
} }
ast::ExprKind::Binary(op, ref lhs, ref rhs) => { ast::ExprKind::Binary(op, lhs, rhs) => {
self.print_expr_binary(op, lhs, rhs); self.print_expr_binary(*op, lhs, rhs);
} }
ast::ExprKind::Unary(op, ref expr) => { ast::ExprKind::Unary(op, expr) => {
self.print_expr_unary(op, expr); self.print_expr_unary(*op, expr);
} }
ast::ExprKind::AddrOf(k, m, ref expr) => { ast::ExprKind::AddrOf(k, m, expr) => {
self.print_expr_addr_of(k, m, expr); self.print_expr_addr_of(*k, *m, expr);
} }
ast::ExprKind::Lit(ref lit) => { ast::ExprKind::Lit(token_lit) => {
self.print_literal(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; let prec = AssocOp::As.precedence() as i8;
self.print_expr_maybe_paren(expr, prec); self.print_expr_maybe_paren(expr, prec);
self.space(); self.space();
self.word_space("as"); self.word_space("as");
self.print_type(ty); self.print_type(ty);
} }
ast::ExprKind::Type(ref expr, ref ty) => { ast::ExprKind::Type(expr, ty) => {
let prec = AssocOp::Colon.precedence() as i8; let prec = AssocOp::Colon.precedence() as i8;
self.print_expr_maybe_paren(expr, prec); self.print_expr_maybe_paren(expr, prec);
self.word_space(":"); self.word_space(":");
self.print_type(ty); self.print_type(ty);
} }
ast::ExprKind::Let(ref pat, ref scrutinee, _) => { ast::ExprKind::Let(pat, scrutinee, _) => {
self.print_let(pat, scrutinee); self.print_let(pat, scrutinee);
} }
ast::ExprKind::If(ref test, ref blk, ref elseopt) => { ast::ExprKind::If(test, blk, elseopt) => self.print_if(test, blk, elseopt.as_deref()),
self.print_if(test, blk, elseopt.as_deref()) ast::ExprKind::While(test, blk, opt_label) => {
}
ast::ExprKind::While(ref test, ref blk, opt_label) => {
if let Some(label) = opt_label { if let Some(label) = opt_label {
self.print_ident(label.ident); self.print_ident(label.ident);
self.word_space(":"); self.word_space(":");
@ -353,7 +355,7 @@ impl<'a> State<'a> {
self.space(); self.space();
self.print_block_with_attrs(blk, attrs); 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 { if let Some(label) = opt_label {
self.print_ident(label.ident); self.print_ident(label.ident);
self.word_space(":"); self.word_space(":");
@ -368,7 +370,7 @@ impl<'a> State<'a> {
self.space(); self.space();
self.print_block_with_attrs(blk, attrs); 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 { if let Some(label) = opt_label {
self.print_ident(label.ident); self.print_ident(label.ident);
self.word_space(":"); self.word_space(":");
@ -378,7 +380,7 @@ impl<'a> State<'a> {
self.word_nbsp("loop"); self.word_nbsp("loop");
self.print_block_with_attrs(blk, attrs); self.print_block_with_attrs(blk, attrs);
} }
ast::ExprKind::Match(ref expr, ref arms) => { ast::ExprKind::Match(expr, arms) => {
self.cbox(0); self.cbox(0);
self.ibox(0); self.ibox(0);
self.word_nbsp("match"); self.word_nbsp("match");
@ -392,21 +394,22 @@ impl<'a> State<'a> {
let empty = attrs.is_empty() && arms.is_empty(); let empty = attrs.is_empty() && arms.is_empty();
self.bclose(expr.span, empty); self.bclose(expr.span, empty);
} }
ast::ExprKind::Closure( ast::ExprKind::Closure(box ast::Closure {
ref binder, binder,
capture_clause, capture_clause,
asyncness, asyncness,
movability, movability,
ref decl, fn_decl,
ref body, body,
_, fn_decl_span: _,
) => { fn_arg_span: _,
}) => {
self.print_closure_binder(binder); self.print_closure_binder(binder);
self.print_movability(movability); self.print_movability(*movability);
self.print_asyncness(asyncness); self.print_asyncness(*asyncness);
self.print_capture_clause(capture_clause); 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.space();
self.print_expr(body); self.print_expr(body);
self.end(); // need to close a box self.end(); // need to close a box
@ -416,7 +419,7 @@ impl<'a> State<'a> {
// empty box to satisfy the close. // empty box to satisfy the close.
self.ibox(0); self.ibox(0);
} }
ast::ExprKind::Block(ref blk, opt_label) => { ast::ExprKind::Block(blk, opt_label) => {
if let Some(label) = opt_label { if let Some(label) = opt_label {
self.print_ident(label.ident); self.print_ident(label.ident);
self.word_space(":"); self.word_space(":");
@ -427,26 +430,26 @@ impl<'a> State<'a> {
self.ibox(0); self.ibox(0);
self.print_block_with_attrs(blk, attrs); 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.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 // cbox/ibox in analogy to the `ExprKind::Block` arm above
self.cbox(0); self.cbox(0);
self.ibox(0); self.ibox(0);
self.print_block_with_attrs(blk, attrs); 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.print_expr_maybe_paren(expr, parser::PREC_POSTFIX);
self.word(".await"); self.word(".await");
} }
ast::ExprKind::Assign(ref lhs, ref rhs, _) => { ast::ExprKind::Assign(lhs, rhs, _) => {
let prec = AssocOp::Assign.precedence() as i8; let prec = AssocOp::Assign.precedence() as i8;
self.print_expr_maybe_paren(lhs, prec + 1); self.print_expr_maybe_paren(lhs, prec + 1);
self.space(); self.space();
self.word_space("="); self.word_space("=");
self.print_expr_maybe_paren(rhs, prec); 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; let prec = AssocOp::Assign.precedence() as i8;
self.print_expr_maybe_paren(lhs, prec + 1); self.print_expr_maybe_paren(lhs, prec + 1);
self.space(); self.space();
@ -454,45 +457,44 @@ impl<'a> State<'a> {
self.word_space("="); self.word_space("=");
self.print_expr_maybe_paren(rhs, prec); 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.print_expr_maybe_paren(expr, parser::PREC_POSTFIX);
self.word("."); 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.print_expr_maybe_paren(expr, parser::PREC_POSTFIX);
self.word("["); self.word("[");
self.print_expr(index); self.print_expr(index);
self.word("]"); 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 // 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)`. // 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 // 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.) // a "normal" binop gets parenthesized. (`LOr` is the lowest-precedence binop.)
let fake_prec = AssocOp::LOr.precedence() as i8; 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); self.print_expr_maybe_paren(e, fake_prec);
} }
if limits == ast::RangeLimits::HalfOpen { match limits {
self.word(".."); ast::RangeLimits::HalfOpen => self.word(".."),
} else { ast::RangeLimits::Closed => self.word("..="),
self.word("..=");
} }
if let Some(ref e) = *end { if let Some(e) = end {
self.print_expr_maybe_paren(e, fake_prec); self.print_expr_maybe_paren(e, fake_prec);
} }
} }
ast::ExprKind::Underscore => self.word("_"), ast::ExprKind::Underscore => self.word("_"),
ast::ExprKind::Path(None, ref path) => self.print_path(path, true, 0), ast::ExprKind::Path(None, path) => self.print_path(path, true, 0),
ast::ExprKind::Path(Some(ref qself), ref path) => self.print_qpath(path, qself, true), ast::ExprKind::Path(Some(qself), path) => self.print_qpath(path, qself, true),
ast::ExprKind::Break(opt_label, ref opt_expr) => { ast::ExprKind::Break(opt_label, opt_expr) => {
self.word("break"); self.word("break");
if let Some(label) = opt_label { if let Some(label) = opt_label {
self.space(); self.space();
self.print_ident(label.ident); self.print_ident(label.ident);
} }
if let Some(ref expr) = *opt_expr { if let Some(expr) = opt_expr {
self.space(); self.space();
self.print_expr_maybe_paren(expr, parser::PREC_JUMP); self.print_expr_maybe_paren(expr, parser::PREC_JUMP);
} }
@ -504,45 +506,45 @@ impl<'a> State<'a> {
self.print_ident(label.ident); self.print_ident(label.ident);
} }
} }
ast::ExprKind::Ret(ref result) => { ast::ExprKind::Ret(result) => {
self.word("return"); self.word("return");
if let Some(ref expr) = *result { if let Some(expr) = result {
self.word(" "); self.word(" ");
self.print_expr_maybe_paren(expr, parser::PREC_JUMP); self.print_expr_maybe_paren(expr, parser::PREC_JUMP);
} }
} }
ast::ExprKind::Yeet(ref result) => { ast::ExprKind::Yeet(result) => {
self.word("do"); self.word("do");
self.word(" "); self.word(" ");
self.word("yeet"); self.word("yeet");
if let Some(ref expr) = *result { if let Some(expr) = result {
self.word(" "); self.word(" ");
self.print_expr_maybe_paren(expr, parser::PREC_JUMP); self.print_expr_maybe_paren(expr, parser::PREC_JUMP);
} }
} }
ast::ExprKind::InlineAsm(ref a) => { ast::ExprKind::InlineAsm(a) => {
self.word("asm!"); self.word("asm!");
self.print_inline_asm(a); self.print_inline_asm(a);
} }
ast::ExprKind::MacCall(ref m) => self.print_mac(m), ast::ExprKind::MacCall(m) => self.print_mac(m),
ast::ExprKind::Paren(ref e) => { ast::ExprKind::Paren(e) => {
self.popen(); self.popen();
self.print_expr(e); self.print_expr(e);
self.pclose(); self.pclose();
} }
ast::ExprKind::Yield(ref e) => { ast::ExprKind::Yield(e) => {
self.word("yield"); self.word("yield");
if let Some(ref expr) = *e { if let Some(expr) = e {
self.space(); self.space();
self.print_expr_maybe_paren(expr, parser::PREC_JUMP); 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.print_expr_maybe_paren(e, parser::PREC_POSTFIX);
self.word("?") self.word("?")
} }
ast::ExprKind::TryBlock(ref blk) => { ast::ExprKind::TryBlock(blk) => {
self.cbox(0); self.cbox(0);
self.ibox(0); self.ibox(0);
self.word_nbsp("try"); self.word_nbsp("try");
@ -569,15 +571,15 @@ impl<'a> State<'a> {
self.print_outer_attributes(&arm.attrs); self.print_outer_attributes(&arm.attrs);
self.print_pat(&arm.pat); self.print_pat(&arm.pat);
self.space(); self.space();
if let Some(ref e) = arm.guard { if let Some(e) = &arm.guard {
self.word_space("if"); self.word_space("if");
self.print_expr(e); self.print_expr(e);
self.space(); self.space();
} }
self.word_space("=>"); self.word_space("=>");
match arm.body.kind { match &arm.body.kind {
ast::ExprKind::Block(ref blk, opt_label) => { ast::ExprKind::Block(blk, opt_label) => {
if let Some(label) = opt_label { if let Some(label) = opt_label {
self.print_ident(label.ident); self.print_ident(label.ident);
self.word_space(":"); self.word_space(":");
@ -604,7 +606,7 @@ impl<'a> State<'a> {
match binder { match binder {
ast::ClosureBinder::NotPresent => {} ast::ClosureBinder::NotPresent => {}
ast::ClosureBinder::For { generic_params, .. } => { ast::ClosureBinder::For { generic_params, .. } => {
self.print_formal_generic_params(&generic_params) self.print_formal_generic_params(generic_params)
} }
} }
} }

View File

@ -136,10 +136,10 @@ impl<'a> State<'a> {
self.maybe_print_comment(item.span.lo()); self.maybe_print_comment(item.span.lo());
self.print_outer_attributes(&item.attrs); self.print_outer_attributes(&item.attrs);
self.ann.pre(self, AnnNode::Item(item)); self.ann.pre(self, AnnNode::Item(item));
match item.kind { match &item.kind {
ast::ItemKind::ExternCrate(orig_name) => { ast::ItemKind::ExternCrate(orig_name) => {
self.head(visibility_qualified(&item.vis, "extern crate")); 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.print_name(orig_name);
self.space(); self.space();
self.word("as"); self.word("as");
@ -150,35 +150,41 @@ impl<'a> State<'a> {
self.end(); // end inner head-block self.end(); // end inner head-block
self.end(); // end outer head-block self.end(); // end outer head-block
} }
ast::ItemKind::Use(ref tree) => { ast::ItemKind::Use(tree) => {
self.print_visibility(&item.vis); self.print_visibility(&item.vis);
self.word_nbsp("use"); self.word_nbsp("use");
self.print_use_tree(tree); self.print_use_tree(tree);
self.word(";"); self.word(";");
} }
ast::ItemKind::Static(ref ty, mutbl, ref body) => { ast::ItemKind::Static(ty, mutbl, body) => {
let def = ast::Defaultness::Final; 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) => { ast::ItemKind::Const(def, ty, body) => {
self.print_item_const(item.ident, None, ty, body.as_deref(), &item.vis, def); 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 }) => { ast::ItemKind::Fn(box ast::Fn { defaultness, sig, generics, body }) => {
let body = body.as_deref();
self.print_fn_full( self.print_fn_full(
sig, sig,
item.ident, item.ident,
generics, generics,
&item.vis, &item.vis,
defaultness, *defaultness,
body, body.as_deref(),
&item.attrs, &item.attrs,
); );
} }
ast::ItemKind::Mod(unsafety, ref mod_kind) => { ast::ItemKind::Mod(unsafety, mod_kind) => {
self.head(Self::to_string(|s| { self.head(Self::to_string(|s| {
s.print_visibility(&item.vis); s.print_visibility(&item.vis);
s.print_unsafety(unsafety); s.print_unsafety(*unsafety);
s.word("mod"); s.word("mod");
})); }));
self.print_ident(item.ident); 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| { self.head(Self::to_string(|s| {
s.print_unsafety(nmod.unsafety); s.print_unsafety(nmod.unsafety);
s.word("extern"); s.word("extern");
})); }));
if let Some(abi) = nmod.abi { 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.nbsp();
} }
self.bopen(); self.bopen();
@ -215,7 +221,7 @@ impl<'a> State<'a> {
let empty = item.attrs.is_empty() && nmod.items.is_empty(); let empty = item.attrs.is_empty() && nmod.items.is_empty();
self.bclose(item.span, empty); self.bclose(item.span, empty);
} }
ast::ItemKind::GlobalAsm(ref asm) => { ast::ItemKind::GlobalAsm(asm) => {
self.head(visibility_qualified(&item.vis, "global_asm!")); self.head(visibility_qualified(&item.vis, "global_asm!"));
self.print_inline_asm(asm); self.print_inline_asm(asm);
self.word(";"); self.word(";");
@ -224,32 +230,31 @@ impl<'a> State<'a> {
} }
ast::ItemKind::TyAlias(box ast::TyAlias { ast::ItemKind::TyAlias(box ast::TyAlias {
defaultness, defaultness,
ref generics, generics,
where_clauses, where_clauses,
where_predicates_split, where_predicates_split,
ref bounds, bounds,
ref ty, ty,
}) => { }) => {
let ty = ty.as_deref();
self.print_associated_type( self.print_associated_type(
item.ident, item.ident,
generics, generics,
where_clauses, *where_clauses,
where_predicates_split, *where_predicates_split,
bounds, bounds,
ty, ty.as_deref(),
&item.vis, &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); 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.head(visibility_qualified(&item.vis, "struct"));
self.print_struct(struct_def, generics, item.ident, item.span, true); 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.head(visibility_qualified(&item.vis, "union"));
self.print_struct(struct_def, generics, item.ident, item.span, true); self.print_struct(struct_def, generics, item.ident, item.span, true);
} }
@ -258,15 +263,15 @@ impl<'a> State<'a> {
polarity, polarity,
defaultness, defaultness,
constness, constness,
ref generics, generics,
ref of_trait, of_trait,
ref self_ty, self_ty,
ref items, items,
}) => { }) => {
self.head(""); self.head("");
self.print_visibility(&item.vis); self.print_visibility(&item.vis);
self.print_defaultness(defaultness); self.print_defaultness(*defaultness);
self.print_unsafety(unsafety); self.print_unsafety(*unsafety);
self.word("impl"); self.word("impl");
if generics.params.is_empty() { if generics.params.is_empty() {
@ -276,13 +281,13 @@ impl<'a> State<'a> {
self.space(); self.space();
} }
self.print_constness(constness); self.print_constness(*constness);
if let ast::ImplPolarity::Negative(_) = polarity { if let ast::ImplPolarity::Negative(_) = polarity {
self.word("!"); self.word("!");
} }
if let Some(ref t) = *of_trait { if let Some(t) = of_trait {
self.print_trait_ref(t); self.print_trait_ref(t);
self.space(); self.space();
self.word_space("for"); self.word_space("for");
@ -303,21 +308,21 @@ impl<'a> State<'a> {
ast::ItemKind::Trait(box ast::Trait { ast::ItemKind::Trait(box ast::Trait {
is_auto, is_auto,
unsafety, unsafety,
ref generics, generics,
ref bounds, bounds,
ref items, items,
.. ..
}) => { }) => {
self.head(""); self.head("");
self.print_visibility(&item.vis); self.print_visibility(&item.vis);
self.print_unsafety(unsafety); self.print_unsafety(*unsafety);
self.print_is_auto(is_auto); self.print_is_auto(*is_auto);
self.word_nbsp("trait"); self.word_nbsp("trait");
self.print_ident(item.ident); self.print_ident(item.ident);
self.print_generic_params(&generics.params); self.print_generic_params(&generics.params);
let mut real_bounds = Vec::with_capacity(bounds.len()); let mut real_bounds = Vec::with_capacity(bounds.len());
for b in bounds.iter() { 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.space();
self.word_space("for ?"); self.word_space("for ?");
self.print_trait_ref(&ptr.trait_ref); self.print_trait_ref(&ptr.trait_ref);
@ -339,38 +344,27 @@ impl<'a> State<'a> {
let empty = item.attrs.is_empty() && items.is_empty(); let empty = item.attrs.is_empty() && items.is_empty();
self.bclose(item.span, 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.head(visibility_qualified(&item.vis, "trait"));
self.print_ident(item.ident); self.print_ident(item.ident);
self.print_generic_params(&generics.params); 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(); self.nbsp();
if !real_bounds.is_empty() { if !bounds.is_empty() {
self.word_nbsp("="); self.word_nbsp("=");
self.print_type_bounds(&real_bounds); self.print_type_bounds(&bounds);
} }
self.print_where_clause(&generics.where_clause); self.print_where_clause(&generics.where_clause);
self.word(";"); self.word(";");
self.end(); // end inner head-block self.end(); // end inner head-block
self.end(); // end outer head-block self.end(); // end outer head-block
} }
ast::ItemKind::MacCall(ref mac) => { ast::ItemKind::MacCall(mac) => {
self.print_mac(mac); self.print_mac(mac);
if mac.args.need_semicolon() { if mac.args.need_semicolon() {
self.word(";"); self.word(";");
} }
} }
ast::ItemKind::MacroDef(ref macro_def) => { ast::ItemKind::MacroDef(macro_def) => {
self.print_mac_def(macro_def, &item.ident, item.span, |state| { self.print_mac_def(macro_def, &item.ident, item.span, |state| {
state.print_visibility(&item.vis) state.print_visibility(&item.vis)
}); });
@ -412,11 +406,11 @@ impl<'a> State<'a> {
} }
pub(crate) fn print_visibility(&mut self, vis: &ast::Visibility) { 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::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)); 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)) self.word_nbsp(format!("pub({})", path))
} else { } else {
self.word_nbsp(format!("pub(in {})", path)) self.word_nbsp(format!("pub(in {})", path))
@ -465,7 +459,7 @@ impl<'a> State<'a> {
) { ) {
self.print_ident(ident); self.print_ident(ident);
self.print_generic_params(&generics.params); self.print_generic_params(&generics.params);
match struct_def { match &struct_def {
ast::VariantData::Tuple(..) | ast::VariantData::Unit(..) => { ast::VariantData::Tuple(..) | ast::VariantData::Unit(..) => {
if let ast::VariantData::Tuple(..) = struct_def { if let ast::VariantData::Tuple(..) = struct_def {
self.popen(); self.popen();
@ -484,7 +478,7 @@ impl<'a> State<'a> {
self.end(); self.end();
self.end(); // Close the outer-box. self.end(); // Close the outer-box.
} }
ast::VariantData::Struct(ref fields, ..) => { ast::VariantData::Struct(fields, ..) => {
self.print_where_clause(&generics.where_clause); self.print_where_clause(&generics.where_clause);
self.print_record_struct_body(fields, span); self.print_record_struct_body(fields, span);
} }
@ -496,7 +490,7 @@ impl<'a> State<'a> {
self.print_visibility(&v.vis); self.print_visibility(&v.vis);
let generics = ast::Generics::default(); let generics = ast::Generics::default();
self.print_struct(&v.data, &generics, v.ident, v.span, false); 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.space();
self.word_space("="); self.word_space("=");
self.print_expr(&d.value) self.print_expr(&d.value)
@ -657,10 +651,10 @@ impl<'a> State<'a> {
} }
fn print_use_tree(&mut self, tree: &ast::UseTree) { fn print_use_tree(&mut self, tree: &ast::UseTree) {
match tree.kind { match &tree.kind {
ast::UseTreeKind::Simple(rename, ..) => { ast::UseTreeKind::Simple(rename) => {
self.print_path(&tree.prefix, false, 0); self.print_path(&tree.prefix, false, 0);
if let Some(rename) = rename { if let &Some(rename) = rename {
self.nbsp(); self.nbsp();
self.word_nbsp("as"); self.word_nbsp("as");
self.print_ident(rename); self.print_ident(rename);
@ -673,7 +667,7 @@ impl<'a> State<'a> {
} }
self.word("*"); self.word("*");
} }
ast::UseTreeKind::Nested(ref items) => { ast::UseTreeKind::Nested(items) => {
if !tree.prefix.segments.is_empty() { if !tree.prefix.segments.is_empty() {
self.print_path(&tree.prefix, false, 0); self.print_path(&tree.prefix, false, 0);
self.word("::"); self.word("::");

View File

@ -1,7 +1,7 @@
//! Parsing and validation of builtin attributes //! Parsing and validation of builtin attributes
use rustc_ast as ast; 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_ast_pretty::pprust;
use rustc_feature::{find_gated_cfg, is_builtin_attr_name, Features, GatedCfg}; use rustc_feature::{find_gated_cfg, is_builtin_attr_name, Features, GatedCfg};
use rustc_macros::HashStable_Generic; use rustc_macros::HashStable_Generic;
@ -277,8 +277,7 @@ where
allowed_through_unstable_modules = true; allowed_through_unstable_modules = true;
} }
// attributes with data // attributes with data
else if let Some(MetaItem { kind: MetaItemKind::List(ref metas), .. }) = meta { else if let Some(meta @ MetaItem { kind: MetaItemKind::List(metas), .. }) = &meta {
let meta = meta.as_ref().unwrap();
let get = |meta: &MetaItem, item: &mut Option<Symbol>| { let get = |meta: &MetaItem, item: &mut Option<Symbol>| {
if item.is_some() { if item.is_some() {
handle_errors( handle_errors(
@ -486,7 +485,7 @@ where
continue 'outer; continue 'outer;
} }
}, },
NestedMetaItem::Literal(lit) => { NestedMetaItem::Lit(lit) => {
handle_errors( handle_errors(
&sess.parse_sess, &sess.parse_sess,
lit.span, lit.span,
@ -533,25 +532,24 @@ where
// Merge the const-unstable info into the stability info // Merge the const-unstable info into the stability info
if promotable { if promotable {
if let Some((ref mut stab, _)) = const_stab { match &mut const_stab {
stab.promotable = promotable; Some((stab, _)) => stab.promotable = promotable,
} else { _ => _ = sess.emit_err(session_diagnostics::RustcPromotablePairing { span: item_sp }),
sess.emit_err(session_diagnostics::RustcPromotablePairing { span: item_sp });
} }
} }
if allowed_through_unstable_modules { if allowed_through_unstable_modules {
if let Some(( match &mut stab {
Stability { Some((
level: StabilityLevel::Stable { ref mut allowed_through_unstable_modules, .. }, Stability {
.. level: StabilityLevel::Stable { allowed_through_unstable_modules, .. },
}, ..
_, },
)) = stab _,
{ )) => *allowed_through_unstable_modules = true,
*allowed_through_unstable_modules = true; _ => {
} else { sess.emit_err(session_diagnostics::RustcAllowedUnstablePairing { span: item_sp });
sess.emit_err(session_diagnostics::RustcAllowedUnstablePairing { span: item_sp }); }
} }
} }
@ -654,15 +652,15 @@ pub fn eval_condition(
features: Option<&Features>, features: Option<&Features>,
eval: &mut impl FnMut(Condition) -> bool, eval: &mut impl FnMut(Condition) -> bool,
) -> bool { ) -> bool {
match cfg.kind { match &cfg.kind {
ast::MetaItemKind::List(ref mis) if cfg.name_or_empty() == sym::version => { ast::MetaItemKind::List(mis) if cfg.name_or_empty() == sym::version => {
try_gate_cfg(sym::version, cfg.span, sess, features); try_gate_cfg(sym::version, cfg.span, sess, features);
let (min_version, span) = match &mis[..] { let (min_version, span) = match &mis[..] {
[NestedMetaItem::Literal(Lit { kind: LitKind::Str(sym, ..), span, .. })] => { [NestedMetaItem::Lit(MetaItemLit { kind: LitKind::Str(sym, ..), span, .. })] => {
(sym, span) (sym, span)
} }
[ [
NestedMetaItem::Literal(Lit { span, .. }) NestedMetaItem::Lit(MetaItemLit { span, .. })
| NestedMetaItem::MetaItem(MetaItem { span, .. }), | NestedMetaItem::MetaItem(MetaItem { span, .. }),
] => { ] => {
sess.emit_err(session_diagnostics::ExpectedVersionLiteral { span: *span }); sess.emit_err(session_diagnostics::ExpectedVersionLiteral { span: *span });
@ -688,7 +686,7 @@ pub fn eval_condition(
rustc_version >= min_version rustc_version >= min_version
} }
} }
ast::MetaItemKind::List(ref mis) => { ast::MetaItemKind::List(mis) => {
for mi in mis.iter() { for mi in mis.iter() {
if !mi.is_meta_item() { if !mi.is_meta_item() {
handle_errors( handle_errors(
@ -759,7 +757,7 @@ pub fn eval_condition(
sess.emit_err(session_diagnostics::CfgPredicateIdentifier { span: cfg.path.span }); sess.emit_err(session_diagnostics::CfgPredicateIdentifier { span: cfg.path.span });
true true
} }
MetaItemKind::NameValue(ref lit) if !lit.kind.is_str() => { MetaItemKind::NameValue(lit) if !lit.kind.is_str() => {
handle_errors( handle_errors(
sess, sess,
lit.span, lit.span,
@ -899,7 +897,7 @@ where
continue 'outer; continue 'outer;
} }
}, },
NestedMetaItem::Literal(lit) => { NestedMetaItem::Lit(lit) => {
handle_errors( handle_errors(
&sess.parse_sess, &sess.parse_sess,
lit.span, 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() { } else if let Some(meta_item) = item.meta_item() {
if let MetaItemKind::NameValue(ref value) = meta_item.kind { match &meta_item.kind {
if meta_item.has_name(sym::align) || meta_item.has_name(sym::packed) { MetaItemKind::NameValue(value) => {
let name = meta_item.name_or_empty().to_ident_string(); if meta_item.has_name(sym::align) || meta_item.has_name(sym::packed) {
recognised = true; let name = meta_item.name_or_empty().to_ident_string();
sess.emit_err(session_diagnostics::IncorrectReprFormatGeneric { recognised = true;
span: item.span(), sess.emit_err(session_diagnostics::IncorrectReprFormatGeneric {
repr_arg: &name, span: item.span(),
cause: IncorrectReprFormatGenericCause::from_lit_kind( repr_arg: &name,
item.span(), cause: IncorrectReprFormatGenericCause::from_lit_kind(
&value.kind, item.span(),
&name, &value.kind,
), &name,
}); ),
} else if matches!( });
meta_item.name_or_empty(), } else if matches!(
sym::C | sym::simd | sym::transparent meta_item.name_or_empty(),
) || int_type_of_word(meta_item.name_or_empty()).is_some() 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 { recognised = true;
span: meta_item.span, sess.emit_err(session_diagnostics::InvalidReprHintNoValue {
name: meta_item.name_or_empty().to_ident_string(), span: meta_item.span,
}); name: meta_item.name_or_empty().to_ident_string(),
});
}
} }
} else if let MetaItemKind::List(_) = meta_item.kind { MetaItemKind::List(_) => {
if meta_item.has_name(sym::align) { if meta_item.has_name(sym::align) {
recognised = true; recognised = true;
sess.emit_err(session_diagnostics::IncorrectReprFormatAlignOneArg { sess.emit_err(session_diagnostics::IncorrectReprFormatAlignOneArg {
span: meta_item.span, span: meta_item.span,
}); });
} else if meta_item.has_name(sym::packed) { } else if meta_item.has_name(sym::packed) {
recognised = true; recognised = true;
sess.emit_err(session_diagnostics::IncorrectReprFormatPackedOneOrZeroArg { sess.emit_err(
span: meta_item.span, session_diagnostics::IncorrectReprFormatPackedOneOrZeroArg {
}); span: meta_item.span,
} else if matches!( },
meta_item.name_or_empty(), );
sym::C | sym::simd | sym::transparent } else if matches!(
) || int_type_of_word(meta_item.name_or_empty()).is_some() meta_item.name_or_empty(),
{ sym::C | sym::simd | sym::transparent
recognised = true; ) || int_type_of_word(meta_item.name_or_empty()).is_some()
sess.emit_err(session_diagnostics::InvalidReprHintNoParen { {
span: meta_item.span, recognised = true;
name: meta_item.name_or_empty().to_ident_string(), sess.emit_err(session_diagnostics::InvalidReprHintNoParen {
}); span: meta_item.span,
name: meta_item.name_or_empty().to_ident_string(),
});
}
} }
_ => (),
} }
} }
if !recognised { if !recognised {

View File

@ -41,7 +41,7 @@ pub(crate) struct IncorrectMetaItem {
pub span: Span, pub span: Span,
} }
// Error code: E0541 /// Error code: E0541
pub(crate) struct UnknownMetaItem<'a> { pub(crate) struct UnknownMetaItem<'a> {
pub span: Span, pub span: Span,
pub item: String, pub item: String,
@ -200,7 +200,7 @@ pub(crate) struct InvalidReprHintNoValue {
pub name: String, pub name: String,
} }
// Error code: E0565 /// Error code: E0565
pub(crate) struct UnsupportedLiteral { pub(crate) struct UnsupportedLiteral {
pub span: Span, pub span: Span,
pub reason: UnsupportedLiteralReason, pub reason: UnsupportedLiteralReason,

View 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']

View 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() })
}
}

View File

@ -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,
])
},
)
},
};

View File

@ -0,0 +1,4 @@
// @generated
pub mod likelysubtags_v1;
pub mod parents_v1;
pub mod supplement;

View 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,
])
},
)
},
};

View File

@ -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,
])
},
)
},
};

View File

@ -0,0 +1,2 @@
// @generated
pub mod co_v1;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,2 @@
// @generated
pub mod and_v1;

View 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)
})?,
))),
})
}
}

View 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");
}

View File

@ -1,3 +1,5 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
use crate::nll::ToRegionVid; use crate::nll::ToRegionVid;
use crate::path_utils::allow_two_phase_borrow; use crate::path_utils::allow_two_phase_borrow;
use crate::place_ext::PlaceExt; use crate::place_ext::PlaceExt;
@ -196,7 +198,7 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherBorrows<'a, 'tcx> {
rvalue: &mir::Rvalue<'tcx>, rvalue: &mir::Rvalue<'tcx>,
location: mir::Location, 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) { if borrowed_place.ignore_borrow(self.tcx, self.body, &self.locals_state_at_exit) {
debug!("ignoring_borrow of {:?}", borrowed_place); debug!("ignoring_borrow of {:?}", borrowed_place);
return; return;
@ -209,7 +211,7 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherBorrows<'a, 'tcx> {
region, region,
reserve_location: location, reserve_location: location,
activation_location: TwoPhaseActivation::NotTwoPhase, activation_location: TwoPhaseActivation::NotTwoPhase,
borrowed_place: *borrowed_place, borrowed_place,
assigned_place: *assigned_place, assigned_place: *assigned_place,
}; };
let (idx, _) = self.location_map.insert_full(location, borrow); 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) { 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 // double-check that we already registered a BorrowData for this
let borrow_data = &self.location_map[&location]; let borrow_data = &self.location_map[&location];
assert_eq!(borrow_data.reserve_location, location); assert_eq!(borrow_data.reserve_location, location);
assert_eq!(borrow_data.kind, kind); assert_eq!(borrow_data.kind, kind);
assert_eq!(borrow_data.region, region.to_region_vid()); 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) self.super_rvalue(rvalue, location)

View File

@ -8,9 +8,18 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
pub(crate) fn cannot_move_when_borrowed( pub(crate) fn cannot_move_when_borrowed(
&self, &self,
span: Span, span: Span,
desc: &str, borrow_span: Span,
place: &str,
borrow_place: &str,
value_place: &str,
) -> DiagnosticBuilder<'cx, ErrorGuaranteed> { ) -> 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( pub(crate) fn cannot_use_when_mutably_borrowed(

View File

@ -1,3 +1,5 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
use rustc_infer::infer::InferCtxt; use rustc_infer::infer::InferCtxt;
use rustc_middle::mir::visit::TyContext; use rustc_middle::mir::visit::TyContext;
use rustc_middle::mir::visit::Visitor; use rustc_middle::mir::visit::Visitor;

View File

@ -163,6 +163,7 @@ impl<'s, 'tcx, D: ConstraintGraphDirecton> Iterator for Edges<'s, 'tcx, D> {
span: DUMMY_SP, span: DUMMY_SP,
category: ConstraintCategory::Internal, category: ConstraintCategory::Internal,
variance_info: VarianceDiagInfo::default(), variance_info: VarianceDiagInfo::default(),
from_closure: false,
}) })
} else { } else {
None None

View File

@ -1,3 +1,6 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
use rustc_data_structures::graph::scc::Sccs; use rustc_data_structures::graph::scc::Sccs;
use rustc_index::vec::IndexVec; use rustc_index::vec::IndexVec;
use rustc_middle::mir::ConstraintCategory; use rustc_middle::mir::ConstraintCategory;
@ -96,6 +99,9 @@ pub struct OutlivesConstraint<'tcx> {
/// Variance diagnostic information /// Variance diagnostic information
pub variance_info: VarianceDiagInfo<'tcx>, pub variance_info: VarianceDiagInfo<'tcx>,
/// If this constraint is promoted from closure requirements.
pub from_closure: bool,
} }
impl<'tcx> fmt::Debug for OutlivesConstraint<'tcx> { impl<'tcx> fmt::Debug for OutlivesConstraint<'tcx> {

View File

@ -1,3 +1,5 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
//! This file provides API for compiler consumers. //! This file provides API for compiler consumers.
use rustc_hir::def_id::LocalDefId; use rustc_hir::def_id::LocalDefId;

View File

@ -1,3 +1,5 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxHashMap;
use rustc_index::bit_set::BitSet; use rustc_index::bit_set::BitSet;
use rustc_middle::mir::{self, BasicBlock, Body, Location, Place}; 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>, stmt: &mir::Statement<'tcx>,
location: Location, location: Location,
) { ) {
match stmt.kind { match &stmt.kind {
mir::StatementKind::Assign(box (lhs, ref rhs)) => { mir::StatementKind::Assign(box (lhs, rhs)) => {
if let mir::Rvalue::Ref(_, _, place) = *rhs { if let mir::Rvalue::Ref(_, _, place) = rhs {
if place.ignore_borrow( if place.ignore_borrow(
self.tcx, self.tcx,
self.body, 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 // Make sure there are no remaining borrows for variables
// that are assigned over. // that are assigned over.
self.kill_borrows_on_place(trans, lhs); self.kill_borrows_on_place(trans, *lhs);
} }
mir::StatementKind::StorageDead(local) => { mir::StatementKind::StorageDead(local) => {
// Make sure there are no remaining borrows for locals that // Make sure there are no remaining borrows for locals that
// are gone out of scope. // 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(..) mir::StatementKind::FakeRead(..)

View File

@ -1,3 +1,5 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
use rustc_middle::mir::visit::{ use rustc_middle::mir::visit::{
MutatingUseContext, NonMutatingUseContext, NonUseContext, PlaceContext, MutatingUseContext, NonMutatingUseContext, NonUseContext, PlaceContext,
}; };

View File

@ -1,3 +1,6 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed}; use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed};
use rustc_infer::infer::canonical::Canonical; use rustc_infer::infer::canonical::Canonical;
use rustc_infer::infer::error_reporting::nice_region_error::NiceRegionError; 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::region_constraints::RegionConstraintData;
use rustc_infer::infer::RegionVariableOrigin; use rustc_infer::infer::RegionVariableOrigin;
use rustc_infer::infer::{InferCtxt, RegionResolutionError, SubregionOrigin, TyCtxtInferExt as _}; 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::error::TypeError;
use rustc_middle::ty::RegionVid; use rustc_middle::ty::RegionVid;
use rustc_middle::ty::UniverseIndex; use rustc_middle::ty::UniverseIndex;
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable}; use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable};
use rustc_span::Span; use rustc_span::Span;
use rustc_trait_selection::traits::query::type_op; 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 rustc_traits::{type_op_ascribe_user_type_with_span, type_op_prove_predicate_with_cause};
use std::fmt; use std::fmt;
@ -158,6 +161,7 @@ trait TypeOpInfo<'tcx> {
error_region: Option<ty::Region<'tcx>>, error_region: Option<ty::Region<'tcx>>,
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>>; ) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>>;
#[instrument(level = "debug", skip(self, mbcx))]
fn report_error( fn report_error(
&self, &self,
mbcx: &mut MirBorrowckCtxt<'_, 'tcx>, mbcx: &mut MirBorrowckCtxt<'_, 'tcx>,
@ -167,6 +171,7 @@ trait TypeOpInfo<'tcx> {
) { ) {
let tcx = mbcx.infcx.tcx; let tcx = mbcx.infcx.tcx;
let base_universe = self.base_universe(); let base_universe = self.base_universe();
debug!(?base_universe);
let Some(adjusted_universe) = let Some(adjusted_universe) =
placeholder.universe.as_u32().checked_sub(base_universe.as_u32()) 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>, placeholder_region: ty::Region<'tcx>,
error_region: Option<ty::Region<'tcx>>, error_region: Option<ty::Region<'tcx>>,
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> { ) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> {
let (ref infcx, key, _) = let (infcx, key, _) =
mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query); mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query);
let mut fulfill_cx = <dyn TraitEngine<'_>>::new(infcx.tcx); let ocx = ObligationCtxt::new(&infcx);
type_op_prove_predicate_with_cause(infcx, &mut *fulfill_cx, key, cause); type_op_prove_predicate_with_cause(&ocx, key, cause);
try_extract_error_from_fulfill_cx(fulfill_cx, infcx, placeholder_region, error_region) try_extract_error_from_fulfill_cx(&ocx, placeholder_region, error_region)
} }
} }
@ -279,24 +284,20 @@ where
placeholder_region: ty::Region<'tcx>, placeholder_region: ty::Region<'tcx>,
error_region: Option<ty::Region<'tcx>>, error_region: Option<ty::Region<'tcx>>,
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> { ) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> {
let (ref infcx, key, _) = let (infcx, key, _) =
mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query); mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query);
let mut fulfill_cx = <dyn TraitEngine<'_>>::new(infcx.tcx); let ocx = ObligationCtxt::new(&infcx);
let mut selcx = SelectionContext::new(infcx);
// FIXME(lqd): Unify and de-duplicate the following with the actual // 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 // `rustc_traits::type_op::type_op_normalize` query to allow the span we need in the
// `ObligationCause`. The normalization results are currently different between // `ObligationCause`. The normalization results are currently different between
// `AtExt::normalize` used in the query and `normalize` called below: the former fails // `QueryNormalizeExt::query_normalize` used in the query and `normalize` called below:
// to normalize the `nll/relate_tys/impl-fn-ignore-binder-via-bottom.rs` test. Check // the former fails to normalize the `nll/relate_tys/impl-fn-ignore-binder-via-bottom.rs` test.
// after #85499 lands to see if its fixes have erased this difference. // Check after #85499 lands to see if its fixes have erased this difference.
let (param_env, value) = key.into_parts(); let (param_env, value) = key.into_parts();
let Normalized { value: _, obligations } = let _ = ocx.normalize(&cause, param_env, value.value);
rustc_trait_selection::traits::normalize(&mut selcx, param_env, cause, value.value);
fulfill_cx.register_predicate_obligations(infcx, obligations);
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>, placeholder_region: ty::Region<'tcx>,
error_region: Option<ty::Region<'tcx>>, error_region: Option<ty::Region<'tcx>>,
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> { ) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> {
let (ref infcx, key, _) = let (infcx, key, _) =
mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query); mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query);
let mut fulfill_cx = <dyn TraitEngine<'_>>::new(infcx.tcx); let ocx = ObligationCtxt::new(&infcx);
type_op_ascribe_user_type_with_span(infcx, &mut *fulfill_cx, key, Some(cause.span)).ok()?; type_op_ascribe_user_type_with_span(&ocx, key, Some(cause.span)).ok()?;
try_extract_error_from_fulfill_cx(fulfill_cx, infcx, placeholder_region, error_region) 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>( fn try_extract_error_from_fulfill_cx<'tcx>(
mut fulfill_cx: Box<dyn TraitEngine<'tcx> + 'tcx>, ocx: &ObligationCtxt<'_, 'tcx>,
infcx: &InferCtxt<'tcx>,
placeholder_region: ty::Region<'tcx>, placeholder_region: ty::Region<'tcx>,
error_region: Option<ty::Region<'tcx>>, error_region: Option<ty::Region<'tcx>>,
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> { ) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> {
// We generally shouldn't have errors here because the query was // We generally shouldn't have errors here because the query was
// already run, but there's no point using `delay_span_bug` // already run, but there's no point using `delay_span_bug`
// when we're going to emit an error here anyway. // when we're going to emit an error here anyway.
let _errors = fulfill_cx.select_all_or_error(infcx); let _errors = ocx.select_all_or_error();
let region_constraints = infcx.with_region_constraints(|r| r.clone()); let region_constraints = ocx.infcx.with_region_constraints(|r| r.clone());
try_extract_error_from_region_constraints( try_extract_error_from_region_constraints(
infcx, ocx.infcx,
placeholder_region, placeholder_region,
error_region, error_region,
&region_constraints, &region_constraints,
|vid| infcx.region_var_origin(vid), |vid| ocx.infcx.region_var_origin(vid),
|vid| infcx.universe_of_region(infcx.tcx.mk_region(ty::ReVar(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>( fn try_extract_error_from_region_constraints<'tcx>(
infcx: &InferCtxt<'tcx>, infcx: &InferCtxt<'tcx>,
placeholder_region: ty::Region<'tcx>, placeholder_region: ty::Region<'tcx>,

View File

@ -7,7 +7,7 @@ use rustc_errors::{
}; };
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::intravisit::{walk_block, walk_expr, Visitor}; 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::infer::TyCtxtInferExt;
use rustc_infer::traits::ObligationCause; use rustc_infer::traits::ObligationCause;
use rustc_middle::mir::tcx::PlaceTy; use rustc_middle::mir::tcx::PlaceTy;
@ -23,7 +23,6 @@ use rustc_span::hygiene::DesugaringKind;
use rustc_span::symbol::sym; use rustc_span::symbol::sym;
use rustc_span::{BytePos, Span, Symbol}; use rustc_span::{BytePos, Span, Symbol};
use rustc_trait_selection::infer::InferCtxtExt; use rustc_trait_selection::infer::InferCtxtExt;
use rustc_trait_selection::traits::TraitEngineExt as _;
use crate::borrow_set::TwoPhaseActivation; use crate::borrow_set::TwoPhaseActivation;
use crate::borrowck_errors; 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 is_loop_move = false;
let mut in_pattern = false; let mut in_pattern = false;
let mut seen_spans = FxHashSet::default();
for move_site in &move_site_vec { for move_site in &move_site_vec {
let move_out = self.move_data.moves[(*move_site).moi]; let move_out = self.move_data.moves[(*move_site).moi];
@ -192,43 +192,28 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
is_loop_move = true; is_loop_move = true;
} }
self.explain_captures( if !seen_spans.contains(&move_span) {
&mut err, if !closure {
span, self.suggest_ref_or_clone(mpi, move_span, &mut err, &mut in_pattern);
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;
} }
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( use_spans.var_path_only_subdiag(&mut err, desired_action);
&mut err,
format!("{} occurs due to use{}", desired_action.as_noun(), use_spans.describe()),
);
if !is_loop_move { if !is_loop_move {
err.span_label( err.span_label(
@ -280,7 +265,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
DescribePlaceOpt { including_downcast: true, including_tuple_field: true }, DescribePlaceOpt { including_downcast: true, including_tuple_field: true },
); );
let note_msg = match opt_name { let note_msg = match opt_name {
Some(ref name) => format!("`{}`", name), Some(name) => format!("`{}`", name),
None => "value".to_owned(), None => "value".to_owned(),
}; };
if self.suggest_borrow_fn_like(&mut err, ty, &move_site_vec, &note_msg) { if self.suggest_borrow_fn_like(&mut err, ty, &move_site_vec, &note_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( fn report_use_of_uninitialized(
&self, &self,
mpi: MovePathIndex, mpi: MovePathIndex,
@ -405,10 +544,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
let used = desired_action.as_general_verb_in_past_tense(); let used = desired_action.as_general_verb_in_past_tense();
let mut err = let mut err =
struct_span_err!(self, span, E0381, "{used} binding {desc}{isnt_initialized}"); struct_span_err!(self, span, E0381, "{used} binding {desc}{isnt_initialized}");
use_spans.var_span_label_path_only( use_spans.var_path_only_subdiag(&mut err, desired_action);
&mut err,
format!("{} occurs due to use{}", desired_action.as_noun(), use_spans.describe()),
);
if let InitializationRequiringAction::PartialAssignment if let InitializationRequiringAction::PartialAssignment
| InitializationRequiringAction::Assignment = desired_action | InitializationRequiringAction::Assignment = desired_action
@ -496,12 +632,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
// but the type has region variables, so erase those. // but the type has region variables, so erase those.
tcx.infer_ctxt() tcx.infer_ctxt()
.build() .build()
.type_implements_trait( .type_implements_trait(default_trait, [tcx.erase_regions(ty)], param_env)
default_trait,
tcx.erase_regions(ty),
ty::List::empty(),
param_env,
)
.must_apply_modulo_regions() .must_apply_modulo_regions()
}; };
@ -535,15 +666,17 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
let tcx = self.infcx.tcx; let tcx = self.infcx.tcx;
// Find out if the predicates show that the type is a Fn or FnMut // Find out if the predicates show that the type is a Fn or FnMut
let find_fn_kind_from_did = let find_fn_kind_from_did = |predicates: ty::EarlyBinder<
|predicates: ty::EarlyBinder<&[(ty::Predicate<'tcx>, Span)]>, substs| { &[(ty::Predicate<'tcx>, Span)],
predicates.0.iter().find_map(|(pred, _)| { >,
substs| {
predicates.0.iter().find_map(|(pred, _)| {
let pred = if let Some(substs) = substs { let pred = if let Some(substs) = substs {
predicates.rebind(*pred).subst(tcx, substs).kind().skip_binder() predicates.rebind(*pred).subst(tcx, substs).kind().skip_binder()
} else { } else {
pred.kind().skip_binder() 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() { if Some(pred.def_id()) == tcx.lang_items().fn_trait() {
return Some(hir::Mutability::Not); return Some(hir::Mutability::Not);
} else if Some(pred.def_id()) == tcx.lang_items().fn_mut_trait() { } else if Some(pred.def_id()) == tcx.lang_items().fn_mut_trait() {
@ -552,7 +685,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
} }
None None
}) })
}; };
// If the type is opaque/param/closure, and it is Fn or FnMut, let's suggest (mutably) // 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`. // 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 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_spans = self.move_spans(moved_place.as_ref(), move_out.source);
let move_span = move_spans.args_or_use(); let move_span = move_spans.args_or_use();
let suggestion = if borrow_level == hir::Mutability::Mut { let suggestion = borrow_level.ref_prefix_str().to_owned();
"&mut ".to_string()
} else {
"&".to_string()
};
(move_span.shrink_to_lo(), suggestion) (move_span.shrink_to_lo(), suggestion)
}) })
.collect(); .collect();
err.multipart_suggestion_verbose( err.multipart_suggestion_verbose(
&format!( format!("consider {}borrowing {value_name}", borrow_level.mutably_str()),
"consider {}borrowing {value_name}",
if borrow_level == hir::Mutability::Mut { "mutably " } else { "" }
),
sugg, sugg,
Applicability::MaybeIncorrect, Applicability::MaybeIncorrect,
); );
true 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) { fn suggest_adding_copy_bounds(&self, err: &mut Diagnostic, ty: Ty<'tcx>, span: Span) {
let tcx = self.infcx.tcx; let tcx = self.infcx.tcx;
let generics = tcx.generics_of(self.mir_def_id()); let generics = tcx.generics_of(self.mir_def_id());
@ -613,36 +762,34 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
else { return; }; else { return; };
// Try to find predicates on *generic params* that would allow copying `ty` // Try to find predicates on *generic params* that would allow copying `ty`
let infcx = tcx.infer_ctxt().build(); let infcx = tcx.infer_ctxt().build();
let mut fulfill_cx = <dyn rustc_infer::traits::TraitEngine<'_>>::new(infcx.tcx); let copy_did = infcx.tcx.require_lang_item(LangItem::Copy, Some(span));
let copy_did = infcx.tcx.lang_items().copy_trait().unwrap();
let cause = ObligationCause::new( let cause = ObligationCause::new(
span, span,
self.mir_hir_id(), self.mir_hir_id(),
rustc_infer::traits::ObligationCauseCode::MiscObligation, rustc_infer::traits::ObligationCauseCode::MiscObligation,
); );
fulfill_cx.register_bound( let errors = rustc_trait_selection::traits::fully_solve_bound(
&infcx, &infcx,
cause,
self.param_env, self.param_env,
// Erase any region vids from the type, which may not be resolved // Erase any region vids from the type, which may not be resolved
infcx.tcx.erase_regions(ty), infcx.tcx.erase_regions(ty),
copy_did, 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 // Only emit suggestion if all required predicates are on generic
let predicates: Result<Vec<_>, _> = errors let predicates: Result<Vec<_>, _> = errors
.into_iter() .into_iter()
.map(|err| match err.obligation.predicate.kind().skip_binder() { .map(|err| match err.obligation.predicate.kind().skip_binder() {
PredicateKind::Trait(predicate) => match predicate.self_ty().kind() { PredicateKind::Clause(ty::Clause::Trait(predicate)) => {
ty::Param(param_ty) => Ok(( match predicate.self_ty().kind() {
generics.type_param(param_ty, tcx), ty::Param(param_ty) => Ok((
predicate.trait_ref.print_only_trait_path().to_string(), generics.type_param(param_ty, tcx),
)), predicate.trait_ref.print_only_trait_path().to_string(),
_ => Err(()), )),
}, _ => Err(()),
}
}
_ => Err(()), _ => Err(()),
}) })
.collect(); .collect();
@ -678,16 +825,16 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
let move_spans = self.move_spans(place.as_ref(), location); let move_spans = self.move_spans(place.as_ref(), location);
let span = move_spans.args_or_use(); let span = move_spans.args_or_use();
let mut err = let mut err = self.cannot_move_when_borrowed(
self.cannot_move_when_borrowed(span, &self.describe_any_place(place.as_ref())); span,
err.span_label(borrow_span, format!("borrow of {} occurs here", borrow_msg)); borrow_span,
err.span_label(span, format!("move out of {} occurs here", value_msg)); &self.describe_any_place(place.as_ref()),
&borrow_msg,
borrow_spans.var_span_label_path_only( &value_msg,
&mut err,
format!("borrow occurs due to use{}", borrow_spans.describe()),
); );
borrow_spans.var_path_only_subdiag(&mut err, crate::InitializationRequiringAction::Borrow);
move_spans.var_span_label( move_spans.var_span_label(
&mut err, &mut err,
format!("move occurs due to use{}", move_spans.describe()), format!("move occurs due to use{}", move_spans.describe()),
@ -729,16 +876,15 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
borrow_span, borrow_span,
&self.describe_any_place(borrow.borrowed_place.as_ref()), &self.describe_any_place(borrow.borrowed_place.as_ref()),
); );
borrow_spans.var_subdiag(&mut err, Some(borrow.kind), |kind, var_span| {
borrow_spans.var_span_label( use crate::session_diagnostics::CaptureVarCause::*;
&mut err, let place = &borrow.borrowed_place;
{ let desc_place = self.describe_any_place(place.as_ref());
let place = &borrow.borrowed_place; match kind {
let desc_place = self.describe_any_place(place.as_ref()); Some(_) => BorrowUsePlaceGenerator { place: desc_place, var_span },
format!("borrow occurs due to use of {}{}", desc_place, borrow_spans.describe()) None => BorrowUsePlaceClosure { place: desc_place, var_span },
}, }
"mutable", });
);
self.explain_why_borrow_contains_point(location, borrow, None) self.explain_why_borrow_contains_point(location, borrow, None)
.add_explanation_to_diagnostic( .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 // then just use the normal error. The closure isn't escaping
// and `move` will not help here. // and `move` will not help here.
( (
Some(ref name), Some(name),
BorrowExplanation::MustBeValidFor { BorrowExplanation::MustBeValidFor {
category: category:
category @ (ConstraintCategory::Return(_) category @ (ConstraintCategory::Return(_)
@ -1292,7 +1438,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
&format!("`{}`", name), &format!("`{}`", name),
), ),
( (
ref name, name,
BorrowExplanation::MustBeValidFor { BorrowExplanation::MustBeValidFor {
category: ConstraintCategory::Assignment, category: ConstraintCategory::Assignment,
from_closure: false, from_closure: false,
@ -1304,7 +1450,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
span, 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( (Some(name), explanation) => self.report_local_value_does_not_live_long_enough(
location, location,
&name, &name,
@ -1556,7 +1702,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
} }
let mut err = self.temporary_value_borrowed_for_too_long(proper_span); 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"); err.span_label(drop_span, "temporary value is freed at the end of this statement");
match explanation { match explanation {
@ -1719,7 +1865,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
err.span_label(borrow_span, note); err.span_label(borrow_span, note);
let tcx = self.infcx.tcx; let tcx = self.infcx.tcx;
let ty_params = ty::List::empty();
let return_ty = self.regioncx.universal_regions().unnormalized_output_ty; let return_ty = self.regioncx.universal_regions().unnormalized_output_ty;
let return_ty = tcx.erase_regions(return_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) if let Some(iter_trait) = tcx.get_diagnostic_item(sym::Iterator)
&& self && self
.infcx .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() .must_apply_modulo_regions()
{ {
err.span_suggestion_hidden( err.span_suggestion_hidden(
@ -2307,7 +2452,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
// and it'll make sense. // and it'll make sense.
let location = borrow.reserve_location; let location = borrow.reserve_location;
debug!("annotate_argument_and_return_for_borrow: location={:?}", 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) &self.body[location.block].statements.get(location.statement_index)
{ {
debug!("annotate_argument_and_return_for_borrow: reservation={:?}", reservation); 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. // Check if our `target` was captured by a closure.
if let Rvalue::Aggregate( if let Rvalue::Aggregate(
box AggregateKind::Closure(def_id, substs), box AggregateKind::Closure(def_id, substs),
ref operands, operands,
) = *rvalue ) = rvalue
{ {
for operand in operands { for operand in operands {
let (Operand::Copy(assigned_from) | Operand::Move(assigned_from)) = operand else { 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 // into a place then we should annotate the closure in
// case it ends up being assigned into the return place. // case it ends up being assigned into the return place.
annotated_closure = annotated_closure =
self.annotate_fn_sig(def_id, substs.as_closure().sig()); self.annotate_fn_sig(*def_id, substs.as_closure().sig());
debug!( debug!(
"annotate_argument_and_return_for_borrow: \ "annotate_argument_and_return_for_borrow: \
annotated_closure={:?} assigned_from_local={:?} \ 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 { if let hir::TyKind::Rptr(lifetime, _) = &fn_decl.inputs[index].kind {
// With access to the lifetime, we can get // With access to the lifetime, we can get
// the span of it. // the span of it.
arguments.push((*argument, lifetime.span)); arguments.push((*argument, lifetime.ident.span));
} else { } else {
bug!("ty type is a ref but hir type is not"); 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(); let mut return_span = fn_decl.output.span();
if let hir::FnRetTy::Return(ty) = &fn_decl.output { if let hir::FnRetTy::Return(ty) = &fn_decl.output {
if let hir::TyKind::Rptr(lifetime, _) = ty.kind { if let hir::TyKind::Rptr(lifetime, _) = ty.kind {
return_span = lifetime.span; return_span = lifetime.ident.span;
} }
} }

View File

@ -469,8 +469,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
} else if self.was_captured_by_trait_object(borrow) { } else if self.was_captured_by_trait_object(borrow) {
LaterUseKind::TraitCapture LaterUseKind::TraitCapture
} else if location.statement_index == block.statements.len() { } else if location.statement_index == block.statements.len() {
if let TerminatorKind::Call { ref func, from_hir_call: true, .. } = if let TerminatorKind::Call { func, from_hir_call: true, .. } =
block.terminator().kind &block.terminator().kind
{ {
// Just point to the function, to reduce the chance of overlapping spans. // Just point to the function, to reduce the chance of overlapping spans.
let function_span = match func { 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 // 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. // it which simplifies the termination logic.
let mut queue = vec![location]; let mut queue = vec![location];
let mut target = if let Some(&Statement { let mut target =
kind: StatementKind::Assign(box (ref place, _)), if let Some(Statement { kind: StatementKind::Assign(box (place, _)), .. }) = stmt {
.. if let Some(local) = place.as_local() {
}) = stmt local
{ } else {
if let Some(local) = place.as_local() { return false;
local }
} else { } else {
return false; return false;
} };
} else {
return false;
};
debug!("was_captured_by_trait: target={:?} queue={:?}", target, queue); debug!("was_captured_by_trait: target={:?} queue={:?}", target, queue);
while let Some(current_location) = queue.pop() { while let Some(current_location) = queue.pop() {

View File

@ -1,3 +1,6 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
use std::collections::BTreeSet; use std::collections::BTreeSet;
use rustc_middle::mir::visit::{PlaceContext, Visitor}; use rustc_middle::mir::visit::{PlaceContext, Visitor};

View File

@ -1,3 +1,6 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
use std::collections::VecDeque; use std::collections::VecDeque;
use std::rc::Rc; use std::rc::Rc;

View File

@ -70,7 +70,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
location: Location, location: Location,
place: PlaceRef<'tcx>, place: PlaceRef<'tcx>,
diag: &mut Diagnostic, diag: &mut Diagnostic,
) { ) -> bool {
debug!("add_moved_or_invoked_closure_note: location={:?} place={:?}", location, place); debug!("add_moved_or_invoked_closure_note: location={:?} place={:?}", location, place);
let mut target = place.local_or_deref_local(); let mut target = place.local_or_deref_local();
for stmt in &self.body[location.block].statements[location.statement_index..] { 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 { if let StatementKind::Assign(box (into, Rvalue::Use(from))) = &stmt.kind {
debug!("add_fnonce_closure_note: into={:?} from={:?}", into, from); debug!("add_fnonce_closure_note: into={:?} from={:?}", into, from);
match from { match from {
Operand::Copy(ref place) | Operand::Move(ref place) Operand::Copy(place) | Operand::Move(place)
if target == place.local_or_deref_local() => if target == place.local_or_deref_local() =>
{ {
target = into.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); debug!("add_moved_or_invoked_closure_note: id={:?}", id);
if Some(self.infcx.tcx.parent(id)) == self.infcx.tcx.lang_items().fn_once_trait() { if Some(self.infcx.tcx.parent(id)) == self.infcx.tcx.lang_items().fn_once_trait() {
let closure = match args.first() { 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() => if target == place.local_or_deref_local() =>
{ {
place.local_or_deref_local().unwrap() place.local_or_deref_local().unwrap()
} }
_ => return, _ => return false,
}; };
debug!("add_moved_or_invoked_closure_note: closure={:?}", closure); 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) 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) 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. /// End-user visible description of `place` if one can be found.
@ -350,7 +352,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
} else { } else {
def.non_enum_variant() 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; return None;
} }
Some(variant.fields[field.index()].name.to_string()) Some(variant.fields[field.index()].name.to_string())
@ -437,9 +439,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
if !is_terminator { if !is_terminator {
continue; continue;
} else if let Some(Terminator { } 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) = if let Some(source) =
BorrowedContentSource::from_call(func.ty(self.body, tcx), tcx) 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>) { pub(super) fn args_span_label(self, err: &mut Diagnostic, message: impl Into<String>) {
if let UseSpans::ClosureUse { args_span, .. } = self { if let UseSpans::ClosureUse { args_span, .. } = self {
err.span_label(args_span, message); err.span_label(args_span, message);
} }
} }
// 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.
// only adds label to the `path_span` /// only adds label to the `path_span`
pub(super) fn var_span_label_path_only(self, err: &mut Diagnostic, message: impl Into<String>) { pub(super) fn var_path_only_subdiag(
if let UseSpans::ClosureUse { path_span, .. } = self { self,
err.span_label(path_span, message); 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( pub(super) fn var_span_label(
self, self,
err: &mut Diagnostic, 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. /// Returns `false` if this place is not used in a closure.
pub(super) fn for_closure(&self) -> bool { pub(super) fn for_closure(&self) -> bool {
match *self { match *self {
@ -757,33 +811,30 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
}; };
debug!("move_spans: moved_place={:?} location={:?} stmt={:?}", moved_place, location, stmt); debug!("move_spans: moved_place={:?} location={:?} stmt={:?}", moved_place, location, stmt);
if let StatementKind::Assign(box (_, Rvalue::Aggregate(ref kind, ref places))) = stmt.kind { if let StatementKind::Assign(box (_, Rvalue::Aggregate(kind, places))) = &stmt.kind
match **kind { && let AggregateKind::Closure(def_id, _) | AggregateKind::Generator(def_id, _, _) = **kind
AggregateKind::Closure(def_id, _) | AggregateKind::Generator(def_id, _, _) => { {
debug!("move_spans: def_id={:?} places={:?}", def_id, places); debug!("move_spans: def_id={:?} places={:?}", def_id, places);
if let Some((args_span, generator_kind, capture_kind_span, path_span)) = if let Some((args_span, generator_kind, capture_kind_span, path_span)) =
self.closure_span(def_id, moved_place, places) self.closure_span(def_id, moved_place, places)
{ {
return ClosureUse { return ClosureUse {
generator_kind, generator_kind,
args_span, args_span,
capture_kind_span, capture_kind_span,
path_span, path_span,
}; };
}
}
_ => {}
} }
} }
// StatementKind::FakeRead only contains a def_id if they are introduced as a result // StatementKind::FakeRead only contains a def_id if they are introduced as a result
// of pattern matching within a closure. // 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 { match cause {
FakeReadCause::ForMatchedPlace(Some(closure_def_id)) FakeReadCause::ForMatchedPlace(Some(closure_def_id))
| FakeReadCause::ForLet(Some(closure_def_id)) => { | FakeReadCause::ForLet(Some(closure_def_id)) => {
debug!("move_spans: def_id={:?} place={:?}", closure_def_id, place); 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)) = if let Some((args_span, generator_kind, capture_kind_span, path_span)) =
self.closure_span(closure_def_id, moved_place, places) 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); debug!("borrow_spans: use_span={:?} location={:?}", use_span, location);
let target = match self.body[location.block].statements.get(location.statement_index) { 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() { if let Some(local) = place.as_local() {
local local
} else { } else {
@ -886,9 +937,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
} }
for stmt in &self.body[location.block].statements[location.statement_index + 1..] { for stmt in &self.body[location.block].statements[location.statement_index + 1..] {
if let StatementKind::Assign(box (_, Rvalue::Aggregate(ref kind, ref places))) = if let StatementKind::Assign(box (_, Rvalue::Aggregate(kind, places))) = &stmt.kind {
stmt.kind
{
let (&def_id, is_generator) = match kind { let (&def_id, is_generator) = match kind {
box AggregateKind::Closure(def_id, _) => (def_id, false), box AggregateKind::Closure(def_id, _) => (def_id, false),
box AggregateKind::Generator(def_id, _, _) => (def_id, true), box AggregateKind::Generator(def_id, _, _) => (def_id, true),

View File

@ -1,6 +1,4 @@
use rustc_errors::{ use rustc_errors::{Applicability, Diagnostic};
Applicability, Diagnostic, DiagnosticBuilder, EmissionGuarantee, ErrorGuaranteed,
};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::intravisit::Visitor; use rustc_hir::intravisit::Visitor;
use rustc_hir::Node; use rustc_hir::Node;
@ -221,8 +219,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
PlaceRef { PlaceRef {
local, local,
projection: projection:
&[ [
ref proj_base @ .., proj_base @ ..,
ProjectionElem::Deref, ProjectionElem::Deref,
ProjectionElem::Field(field, _), ProjectionElem::Field(field, _),
ProjectionElem::Deref, ProjectionElem::Deref,
@ -233,7 +231,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
if let Some(span) = get_mut_span_in_struct_field( if let Some(span) = get_mut_span_in_struct_field(
self.infcx.tcx, self.infcx.tcx,
Place::ty_from(local, proj_base, self.body, self.infcx.tcx).ty, Place::ty_from(local, proj_base, self.body, self.infcx.tcx).ty,
field, *field,
) { ) {
err.span_suggestion_verbose( err.span_suggestion_verbose(
span, span,
@ -391,13 +389,13 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
// diagnostic: if the span starts with a mutable borrow of // diagnostic: if the span starts with a mutable borrow of
// a local variable, then just suggest the user remove it. // a local variable, then just suggest the user remove it.
PlaceRef { local: _, projection: [] } PlaceRef { local: _, projection: [] }
if { if self
if let Ok(snippet) = self.infcx.tcx.sess.source_map().span_to_snippet(span) { .infcx
snippet.starts_with("&mut ") .tcx
} else { .sess
false .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_label(span, format!("cannot {ACT}", ACT = act));
err.span_suggestion( err.span_suggestion(
@ -629,25 +627,20 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
self.buffer_error(err); self.buffer_error(err);
} }
fn suggest_map_index_mut_alternatives( fn suggest_map_index_mut_alternatives(&self, ty: Ty<'tcx>, err: &mut Diagnostic, span: Span) {
&self,
ty: Ty<'_>,
err: &mut DiagnosticBuilder<'_, ErrorGuaranteed>,
span: Span,
) {
let Some(adt) = ty.ty_adt_def() else { return }; let Some(adt) = ty.ty_adt_def() else { return };
let did = adt.did(); let did = adt.did();
if self.infcx.tcx.is_diagnostic_item(sym::HashMap, did) if self.infcx.tcx.is_diagnostic_item(sym::HashMap, did)
|| self.infcx.tcx.is_diagnostic_item(sym::BTreeMap, did) || self.infcx.tcx.is_diagnostic_item(sym::BTreeMap, did)
{ {
struct V<'a, 'b, 'tcx, G: EmissionGuarantee> { struct V<'a, 'tcx> {
assign_span: Span, assign_span: Span,
err: &'a mut DiagnosticBuilder<'b, G>, err: &'a mut Diagnostic,
ty: Ty<'tcx>, ty: Ty<'tcx>,
suggested: bool, suggested: bool,
} }
impl<'a, 'b: 'a, 'hir, 'tcx, G: EmissionGuarantee> Visitor<'hir> for V<'a, 'b, 'tcx, G> { impl<'a, 'tcx> Visitor<'tcx> for V<'a, 'tcx> {
fn visit_stmt(&mut self, stmt: &'hir hir::Stmt<'hir>) { fn visit_stmt(&mut self, stmt: &'tcx hir::Stmt<'tcx>) {
hir::intravisit::walk_stmt(self, stmt); hir::intravisit::walk_stmt(self, stmt);
let expr = match stmt.kind { let expr = match stmt.kind {
hir::StmtKind::Semi(expr) | hir::StmtKind::Expr(expr) => expr, 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()), (rv.span.shrink_to_hi(), ")".to_string()),
], ],
].into_iter(), ],
Applicability::MachineApplicable, Applicability::MachineApplicable,
); );
self.suggested = true; self.suggested = true;
@ -1218,7 +1211,7 @@ fn get_mut_span_in_struct_field<'tcx>(
&& let hir::Node::Field(field) = node && let hir::Node::Field(field) = node
&& let hir::TyKind::Rptr(lt, hir::MutTy { mutbl: hir::Mutability::Not, ty }) = field.ty.kind && 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 None

View File

@ -2,7 +2,7 @@
#![deny(rustc::diagnostic_outside_of_impl)] #![deny(rustc::diagnostic_outside_of_impl)]
//! Error reporting machinery for lifetime errors. //! 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_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, MultiSpan};
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_hir::intravisit::Visitor; use rustc_hir::intravisit::Visitor;
@ -21,7 +21,7 @@ use rustc_middle::ty::subst::InternalSubsts;
use rustc_middle::ty::Region; use rustc_middle::ty::Region;
use rustc_middle::ty::TypeVisitor; use rustc_middle::ty::TypeVisitor;
use rustc_middle::ty::{self, RegionVid, Ty}; 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 rustc_span::Span;
use crate::borrowck_errors; 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. // 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 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 { if let Some(lower_bound_region) = lower_bound_region {
let generic_ty = type_test.generic_kind.to_ty(self.infcx.tcx); 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( fn get_impl_ident_and_self_ty_from_trait(
&self, &self,
def_id: DefId, def_id: DefId,
trait_objects: &FxHashSet<DefId>, trait_objects: &FxIndexSet<DefId>,
) -> Option<(Ident, &'tcx hir::Ty<'tcx>)> { ) -> Option<(Ident, &'tcx hir::Ty<'tcx>)> {
let tcx = self.infcx.tcx; let tcx = self.infcx.tcx;
match tcx.hir().get_if_local(def_id) { match tcx.hir().get_if_local(def_id) {
@ -514,9 +514,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
span: *span, span: *span,
ty_err: match output_ty.kind() { ty_err: match output_ty.kind() {
ty::Closure(_, _) => FnMutReturnTypeErr::ReturnClosure { span: *span }, ty::Closure(_, _) => FnMutReturnTypeErr::ReturnClosure { span: *span },
ty::Adt(def, _) ty::Generator(def, ..) if self.infcx.tcx.generator_is_async(*def) => {
if self.infcx.tcx.is_diagnostic_item(sym::gen_future, def.did()) =>
{
FnMutReturnTypeErr::ReturnAsyncBlock { span: *span } FnMutReturnTypeErr::ReturnAsyncBlock { span: *span }
} }
_ => FnMutReturnTypeErr::ReturnRef { span: *span }, _ => FnMutReturnTypeErr::ReturnRef { span: *span },
@ -830,7 +828,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
}; };
debug!(?param); debug!(?param);
let mut visitor = TraitObjectVisitor(FxHashSet::default()); let mut visitor = TraitObjectVisitor(FxIndexSet::default());
visitor.visit_ty(param.param_ty); visitor.visit_ty(param.param_ty);
let Some((ident, self_ty)) = let Some((ident, self_ty)) =
@ -843,7 +841,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
fn suggest_constrain_dyn_trait_in_impl( fn suggest_constrain_dyn_trait_in_impl(
&self, &self,
err: &mut Diagnostic, err: &mut Diagnostic,
found_dids: &FxHashSet<DefId>, found_dids: &FxIndexSet<DefId>,
ident: Ident, ident: Ident,
self_ty: &hir::Ty<'_>, self_ty: &hir::Ty<'_>,
) -> bool { ) -> bool {
@ -923,14 +921,18 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
} }
} }
hir::ExprKind::Block(blk, _) => { hir::ExprKind::Block(blk, _) => {
if let Some(ref expr) = blk.expr { if let Some(expr) = blk.expr {
// only when the block is a closure // only when the block is a closure
if let hir::ExprKind::Closure(hir::Closure { if let hir::ExprKind::Closure(hir::Closure {
capture_clause: hir::CaptureBy::Ref, capture_clause: hir::CaptureBy::Ref,
body,
.. ..
}) = expr.kind }) = 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());
}
} }
} }
} }

View File

@ -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_impl_signature(fr))
.or_else(|| self.give_name_if_anonymous_region_appears_in_arg_position_impl_trait(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()); 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, 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 args = last_segment.args.as_ref()?;
let lifetime = let lifetime =
self.try_match_adt_and_generic_args(substs, needle_fr, args, search_stack)?; self.try_match_adt_and_generic_args(substs, needle_fr, args, search_stack)?;
match lifetime.name { if lifetime.is_anonymous() {
hir::LifetimeName::Param(_, hir::ParamName::Plain(_) | hir::ParamName::Error) None
| hir::LifetimeName::Error } else {
| hir::LifetimeName::Static => { Some(RegionNameHighlight::MatchedAdtAndSegment(lifetime.ident.span))
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
}
} }
} }
@ -959,8 +939,8 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
{ {
predicates.iter().any(|pred| { predicates.iter().any(|pred| {
match pred.kind().skip_binder() { match pred.kind().skip_binder() {
ty::PredicateKind::Trait(data) if data.self_ty() == ty => {} ty::PredicateKind::Clause(ty::Clause::Trait(data)) if data.self_ty() == ty => {}
ty::PredicateKind::Projection(data) if data.projection_ty.self_ty() == ty => {} ty::PredicateKind::Clause(ty::Clause::Projection(data)) if data.projection_ty.self_ty() == ty => {}
_ => return false, _ => return false,
} }
tcx.any_free_region_meets(pred, |r| { tcx.any_free_region_meets(pred, |r| {

View File

@ -1,3 +1,6 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
use crate::Upvar; use crate::Upvar;
use crate::{nll::ToRegionVid, region_infer::RegionInferenceContext}; use crate::{nll::ToRegionVid, region_infer::RegionInferenceContext};
use rustc_index::vec::{Idx, IndexVec}; use rustc_index::vec::{Idx, IndexVec};

View File

@ -1,3 +1,5 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
use crate::location::{LocationIndex, LocationTable}; use crate::location::{LocationIndex, LocationTable};
use crate::BorrowIndex; use crate::BorrowIndex;
use polonius_engine::AllFacts as PoloniusFacts; use polonius_engine::AllFacts as PoloniusFacts;

View File

@ -1,3 +1,5 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
use rustc_data_structures::graph::dominators::Dominators; use rustc_data_structures::graph::dominators::Dominators;
use rustc_middle::mir::visit::Visitor; use rustc_middle::mir::visit::Visitor;
use rustc_middle::mir::{self, BasicBlock, Body, Location, NonDivergingIntrinsic, Place, Rvalue}; 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); self.consume_operand(location, op);
} }
StatementKind::Intrinsic(box NonDivergingIntrinsic::CopyNonOverlapping(mir::CopyNonOverlapping { StatementKind::Intrinsic(box NonDivergingIntrinsic::CopyNonOverlapping(mir::CopyNonOverlapping {
ref src, src,
ref dst, dst,
ref count, count,
})) => { })) => {
self.consume_operand(location, src); self.consume_operand(location, src);
self.consume_operand(location, dst); self.consume_operand(location, dst);
@ -104,7 +106,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
self.check_activations(location); self.check_activations(location);
match &terminator.kind { match &terminator.kind {
TerminatorKind::SwitchInt { ref discr, switch_ty: _, targets: _ } => { TerminatorKind::SwitchInt { discr, switch_ty: _, targets: _ } => {
self.consume_operand(location, discr); self.consume_operand(location, discr);
} }
TerminatorKind::Drop { place: drop_place, target: _, unwind: _ } => { TerminatorKind::Drop { place: drop_place, target: _, unwind: _ } => {
@ -117,7 +119,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
} }
TerminatorKind::DropAndReplace { TerminatorKind::DropAndReplace {
place: drop_place, place: drop_place,
value: ref new_value, value: new_value,
target: _, target: _,
unwind: _, unwind: _,
} => { } => {
@ -125,8 +127,8 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
self.consume_operand(location, new_value); self.consume_operand(location, new_value);
} }
TerminatorKind::Call { TerminatorKind::Call {
ref func, func,
ref args, args,
destination, destination,
target: _, target: _,
cleanup: _, cleanup: _,
@ -139,15 +141,15 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
} }
self.mutate_place(location, *destination, Deep); 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); self.consume_operand(location, cond);
use rustc_middle::mir::AssertKind; 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, len);
self.consume_operand(location, index); 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); self.consume_operand(location, value);
// Invalidate all borrows of local places // Invalidate all borrows of local places
@ -173,25 +175,25 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
} }
TerminatorKind::InlineAsm { TerminatorKind::InlineAsm {
template: _, template: _,
ref operands, operands,
options: _, options: _,
line_spans: _, line_spans: _,
destination: _, destination: _,
cleanup: _, cleanup: _,
} => { } => {
for op in operands { for op in operands {
match *op { match op {
InlineAsmOperand::In { reg: _, ref value } => { InlineAsmOperand::In { reg: _, value } => {
self.consume_operand(location, value); self.consume_operand(location, value);
} }
InlineAsmOperand::Out { reg: _, late: _, place, .. } => { InlineAsmOperand::Out { reg: _, late: _, place, .. } => {
if let Some(place) = place { if let &Some(place) = place {
self.mutate_place(location, place, Shallow(None)); 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); 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)); self.mutate_place(location, out_place, Shallow(None));
} }
} }
@ -250,8 +252,8 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> {
// Simulates consumption of an rvalue // Simulates consumption of an rvalue
fn consume_rvalue(&mut self, location: Location, rvalue: &Rvalue<'tcx>) { fn consume_rvalue(&mut self, location: Location, rvalue: &Rvalue<'tcx>) {
match *rvalue { match rvalue {
Rvalue::Ref(_ /*rgn*/, bk, place) => { &Rvalue::Ref(_ /*rgn*/, bk, place) => {
let access_kind = match bk { let access_kind = match bk {
BorrowKind::Shallow => { BorrowKind::Shallow => {
(Shallow(Some(ArtificialField::ShallowBorrow)), Read(ReadKind::Borrow(bk))) (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); self.access_place(location, place, access_kind, LocalMutationIsAllowed::No);
} }
Rvalue::AddressOf(mutability, place) => { &Rvalue::AddressOf(mutability, place) => {
let access_kind = match mutability { let access_kind = match mutability {
Mutability::Mut => ( Mutability::Mut => (
Deep, Deep,
@ -286,20 +288,19 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> {
Rvalue::ThreadLocalRef(_) => {} Rvalue::ThreadLocalRef(_) => {}
Rvalue::Use(ref operand) Rvalue::Use(operand)
| Rvalue::Repeat(ref operand, _) | Rvalue::Repeat(operand, _)
| Rvalue::UnaryOp(_ /*un_op*/, ref operand) | Rvalue::UnaryOp(_ /*un_op*/, operand)
| Rvalue::Cast(_ /*cast_kind*/, ref operand, _ /*ty*/) | Rvalue::Cast(_ /*cast_kind*/, operand, _ /*ty*/)
| Rvalue::ShallowInitBox(ref operand, _ /*ty*/) => { | Rvalue::ShallowInitBox(operand, _ /*ty*/) => self.consume_operand(location, operand),
self.consume_operand(location, operand)
} &Rvalue::CopyForDeref(place) => {
Rvalue::CopyForDeref(ref place) => { let op = &Operand::Copy(place);
let op = &Operand::Copy(*place);
self.consume_operand(location, op); self.consume_operand(location, op);
} }
Rvalue::Len(place) | Rvalue::Discriminant(place) => { &(Rvalue::Len(place) | Rvalue::Discriminant(place)) => {
let af = match *rvalue { let af = match rvalue {
Rvalue::Len(..) => Some(ArtificialField::ArrayLength), Rvalue::Len(..) => Some(ArtificialField::ArrayLength),
Rvalue::Discriminant(..) => None, Rvalue::Discriminant(..) => None,
_ => unreachable!(), _ => unreachable!(),
@ -312,15 +313,15 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> {
); );
} }
Rvalue::BinaryOp(_bin_op, box (ref operand1, ref operand2)) Rvalue::BinaryOp(_bin_op, box (operand1, operand2))
| Rvalue::CheckedBinaryOp(_bin_op, box (ref operand1, ref operand2)) => { | Rvalue::CheckedBinaryOp(_bin_op, box (operand1, operand2)) => {
self.consume_operand(location, operand1); self.consume_operand(location, operand1);
self.consume_operand(location, operand2); self.consume_operand(location, operand2);
} }
Rvalue::NullaryOp(_op, _ty) => {} Rvalue::NullaryOp(_op, _ty) => {}
Rvalue::Aggregate(_, ref operands) => { Rvalue::Aggregate(_, operands) => {
for operand in operands { for operand in operands {
self.consume_operand(location, operand); self.consume_operand(location, operand);
} }

View File

@ -18,7 +18,8 @@ extern crate tracing;
use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::graph::dominators::Dominators; 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 as hir;
use rustc_hir::def_id::LocalDefId; use rustc_hir::def_id::LocalDefId;
use rustc_index::bit_set::ChunkedBitSet; use rustc_index::bit_set::ChunkedBitSet;
@ -82,7 +83,7 @@ mod type_check;
mod universal_regions; mod universal_regions;
mod used_muts; mod used_muts;
// A public API provided for the Rust compiler consumers. /// A public API provided for the Rust compiler consumers.
pub mod consumers; pub mod consumers;
use borrow_set::{BorrowData, BorrowSet}; use borrow_set::{BorrowData, BorrowSet};
@ -129,6 +130,19 @@ fn mir_borrowck<'tcx>(
) -> &'tcx BorrowCheckResult<'tcx> { ) -> &'tcx BorrowCheckResult<'tcx> {
let (input_body, promoted) = tcx.mir_promoted(def); let (input_body, promoted) = tcx.mir_promoted(def);
debug!("run query mir_borrowck: {}", tcx.def_path_str(def.did.to_def_id())); 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 hir_owner = tcx.hir().local_def_id_to_hir_id(def.did).owner;
let infcx = 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. // Gather the upvars of a closure, if any.
let tables = tcx.typeck_opt_const_arg(def); let tables = tcx.typeck_opt_const_arg(def);
if let Some(ErrorGuaranteed { .. }) = tables.tainted_by_errors { if let Some(e) = tables.tainted_by_errors {
infcx.set_tainted_by_errors(); infcx.set_tainted_by_errors(e);
errors.set_tainted_by_errors(); errors.set_tainted_by_errors(e);
} }
let upvars: Vec<_> = tables let upvars: Vec<_> = tables
.closure_min_captures_flattened(def.did) .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); self.check_activations(location, span, flow_state);
match &stmt.kind { match &stmt.kind {
StatementKind::Assign(box (lhs, ref rhs)) => { StatementKind::Assign(box (lhs, rhs)) => {
self.consume_rvalue(location, (rhs, span), flow_state); self.consume_rvalue(location, (rhs, span), flow_state);
self.mutate_place(location, (*lhs, span), Shallow(None), 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 // 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 // assert that a place is safe and live. So we don't have to
// do any checks here. // do any checks here.
@ -587,7 +601,7 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx
flow_state, 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::Assume(op) => self.consume_operand(location, (op, span), flow_state),
NonDivergingIntrinsic::CopyNonOverlapping(..) => span_bug!( NonDivergingIntrinsic::CopyNonOverlapping(..) => span_bug!(
span, span,
@ -629,8 +643,8 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx
self.check_activations(loc, span, flow_state); self.check_activations(loc, span, flow_state);
match term.kind { match &term.kind {
TerminatorKind::SwitchInt { ref discr, switch_ty: _, targets: _ } => { TerminatorKind::SwitchInt { discr, switch_ty: _, targets: _ } => {
self.consume_operand(loc, (discr, span), flow_state); self.consume_operand(loc, (discr, span), flow_state);
} }
TerminatorKind::Drop { place, target: _, unwind: _ } => { TerminatorKind::Drop { place, target: _, unwind: _ } => {
@ -642,7 +656,7 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx
self.access_place( self.access_place(
loc, loc,
(place, span), (*place, span),
(AccessDepth::Drop, Write(WriteKind::StorageDeadOrDrop)), (AccessDepth::Drop, Write(WriteKind::StorageDeadOrDrop)),
LocalMutationIsAllowed::Yes, LocalMutationIsAllowed::Yes,
flow_state, flow_state,
@ -650,16 +664,16 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx
} }
TerminatorKind::DropAndReplace { TerminatorKind::DropAndReplace {
place: drop_place, place: drop_place,
value: ref new_value, value: new_value,
target: _, target: _,
unwind: _, 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); self.consume_operand(loc, (new_value, span), flow_state);
} }
TerminatorKind::Call { TerminatorKind::Call {
ref func, func,
ref args, args,
destination, destination,
target: _, target: _,
cleanup: _, cleanup: _,
@ -670,43 +684,43 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx
for arg in args { for arg in args {
self.consume_operand(loc, (arg, span), flow_state); 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); self.consume_operand(loc, (cond, span), flow_state);
use rustc_middle::mir::AssertKind; 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, (len, span), flow_state);
self.consume_operand(loc, (index, 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.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 { TerminatorKind::InlineAsm {
template: _, template: _,
ref operands, operands,
options: _, options: _,
line_spans: _, line_spans: _,
destination: _, destination: _,
cleanup: _, cleanup: _,
} => { } => {
for op in operands { for op in operands {
match *op { match op {
InlineAsmOperand::In { reg: _, ref value } => { InlineAsmOperand::In { reg: _, value } => {
self.consume_operand(loc, (value, span), flow_state); self.consume_operand(loc, (value, span), flow_state);
} }
InlineAsmOperand::Out { reg: _, late: _, place, .. } => { InlineAsmOperand::Out { reg: _, late: _, place, .. } => {
if let Some(place) = 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); 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( self.mutate_place(
loc, loc,
(out_place, span), (out_place, span),
@ -1150,8 +1164,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
(rvalue, span): (&'cx Rvalue<'tcx>, Span), (rvalue, span): (&'cx Rvalue<'tcx>, Span),
flow_state: &Flows<'cx, 'tcx>, flow_state: &Flows<'cx, 'tcx>,
) { ) {
match *rvalue { match rvalue {
Rvalue::Ref(_ /*rgn*/, bk, place) => { &Rvalue::Ref(_ /*rgn*/, bk, place) => {
let access_kind = match bk { let access_kind = match bk {
BorrowKind::Shallow => { BorrowKind::Shallow => {
(Shallow(Some(ArtificialField::ShallowBorrow)), Read(ReadKind::Borrow(bk))) (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 { let access_kind = match mutability {
Mutability::Mut => ( Mutability::Mut => (
Deep, Deep,
@ -1218,14 +1232,15 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
Rvalue::ThreadLocalRef(_) => {} Rvalue::ThreadLocalRef(_) => {}
Rvalue::Use(ref operand) Rvalue::Use(operand)
| Rvalue::Repeat(ref operand, _) | Rvalue::Repeat(operand, _)
| Rvalue::UnaryOp(_ /*un_op*/, ref operand) | Rvalue::UnaryOp(_ /*un_op*/, operand)
| Rvalue::Cast(_ /*cast_kind*/, ref operand, _ /*ty*/) | Rvalue::Cast(_ /*cast_kind*/, operand, _ /*ty*/)
| Rvalue::ShallowInitBox(ref operand, _ /*ty*/) => { | Rvalue::ShallowInitBox(operand, _ /*ty*/) => {
self.consume_operand(location, (operand, span), flow_state) self.consume_operand(location, (operand, span), flow_state)
} }
Rvalue::CopyForDeref(place) => {
&Rvalue::CopyForDeref(place) => {
self.access_place( self.access_place(
location, location,
(place, span), (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 { let af = match *rvalue {
Rvalue::Len(..) => Some(ArtificialField::ArrayLength), Rvalue::Len(..) => Some(ArtificialField::ArrayLength),
Rvalue::Discriminant(..) => None, Rvalue::Discriminant(..) => None,
@ -1264,8 +1279,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
); );
} }
Rvalue::BinaryOp(_bin_op, box (ref operand1, ref operand2)) Rvalue::BinaryOp(_bin_op, box (operand1, operand2))
| Rvalue::CheckedBinaryOp(_bin_op, box (ref operand1, ref operand2)) => { | Rvalue::CheckedBinaryOp(_bin_op, box (operand1, operand2)) => {
self.consume_operand(location, (operand1, span), flow_state); self.consume_operand(location, (operand1, span), flow_state);
self.consume_operand(location, (operand2, 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. // 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 // We need to report back the list of mutable upvars that were
// moved into the closure and subsequently used by the closure, // moved into the closure and subsequently used by the closure,
// in order to populate our used_mut set. // in order to populate our used_mut set.
@ -2246,6 +2261,7 @@ mod error {
use super::*; use super::*;
pub struct BorrowckErrors<'tcx> { pub struct BorrowckErrors<'tcx> {
tcx: TyCtxt<'tcx>,
/// This field keeps track of move errors that are to be reported for given move indices. /// This field keeps track of move errors that are to be reported for given move indices.
/// ///
/// There are situations where many errors can be reported for a single move out (see #53807) /// 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>, tainted_by_errors: Option<ErrorGuaranteed>,
} }
impl BorrowckErrors<'_> { impl<'tcx> BorrowckErrors<'tcx> {
pub fn new() -> Self { pub fn new(tcx: TyCtxt<'tcx>) -> Self {
BorrowckErrors { BorrowckErrors {
tcx,
buffered_move_errors: BTreeMap::new(), buffered_move_errors: BTreeMap::new(),
buffered: Default::default(), buffered: Default::default(),
tainted_by_errors: None, 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>) { 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); t.buffer(&mut self.buffered);
} }
@ -2288,8 +2309,8 @@ mod error {
t.buffer(&mut self.buffered); t.buffer(&mut self.buffered);
} }
pub fn set_tainted_by_errors(&mut self) { pub fn set_tainted_by_errors(&mut self, e: ErrorGuaranteed) {
self.tainted_by_errors = Some(ErrorGuaranteed::unchecked_claim_error_was_emitted()); self.tainted_by_errors = Some(e);
} }
} }

View File

@ -1,3 +1,5 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
use rustc_index::vec::{Idx, IndexVec}; use rustc_index::vec::{Idx, IndexVec};
use rustc_middle::mir::{BasicBlock, Body, Location}; use rustc_middle::mir::{BasicBlock, Body, Location};

View File

@ -1,3 +1,5 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
use rustc_data_structures::captures::Captures; use rustc_data_structures::captures::Captures;
use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxHashMap;
use rustc_index::vec::IndexVec; use rustc_index::vec::IndexVec;
@ -9,6 +11,7 @@ use std::ops::Index;
/// Compactly stores a set of `R0 member of [R1...Rn]` constraints, /// Compactly stores a set of `R0 member of [R1...Rn]` constraints,
/// indexed by the region `R0`. /// indexed by the region `R0`.
#[derive(Debug)]
pub(crate) struct MemberConstraintSet<'tcx, R> pub(crate) struct MemberConstraintSet<'tcx, R>
where where
R: Copy + Eq, R: Copy + Eq,
@ -29,6 +32,7 @@ where
} }
/// Represents a `R0 member of [R1..Rn]` constraint /// Represents a `R0 member of [R1..Rn]` constraint
#[derive(Debug)]
pub(crate) struct NllMemberConstraint<'tcx> { pub(crate) struct NllMemberConstraint<'tcx> {
next_constraint: Option<NllMemberConstraintIndex>, next_constraint: Option<NllMemberConstraintIndex>,

View File

@ -1,3 +1,5 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
//! The entry point of the NLL borrow checker. //! The entry point of the NLL borrow checker.
use rustc_data_structures::vec_map::VecMap; 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. // Replace all remaining regions with fresh inference variables.
renumber::renumber_mir(infcx, body, promoted); 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 universal_regions
} }
@ -242,7 +244,6 @@ pub(crate) fn compute_regions<'cx, 'tcx>(
mut liveness_constraints, mut liveness_constraints,
outlives_constraints, outlives_constraints,
member_constraints, member_constraints,
closure_bounds_mapping,
universe_causes, universe_causes,
type_tests, type_tests,
} = constraints; } = constraints;
@ -264,7 +265,6 @@ pub(crate) fn compute_regions<'cx, 'tcx>(
universal_region_relations, universal_region_relations,
outlives_constraints, outlives_constraints,
member_constraints, member_constraints,
closure_bounds_mapping,
universe_causes, universe_causes,
type_tests, type_tests,
liveness_constraints, liveness_constraints,
@ -303,7 +303,10 @@ pub(crate) fn compute_regions<'cx, 'tcx>(
if !nll_errors.is_empty() { if !nll_errors.is_empty() {
// Suppress unhelpful extra errors in `infer_opaque_types`. // 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); let remapped_opaque_tys = regioncx.infer_opaque_types(&infcx, opaque_type_values);
@ -328,7 +331,7 @@ pub(super) fn dump_mir_results<'tcx>(
return; 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 { match pass_where {
// Before the CFG, dump out the values for each region variable. // Before the CFG, dump out the values for each region variable.
PassWhere::BeforeCFG => { PassWhere::BeforeCFG => {
@ -355,15 +358,13 @@ pub(super) fn dump_mir_results<'tcx>(
// Also dump the inference graph constraints as a graphviz file. // Also dump the inference graph constraints as a graphviz file.
let _: io::Result<()> = try { let _: io::Result<()> = try {
let mut file = let mut file = create_dump_file(infcx.tcx, "regioncx.all.dot", false, "nll", &0, body)?;
create_dump_file(infcx.tcx, "regioncx.all.dot", None, "nll", &0, body.source)?;
regioncx.dump_graphviz_raw_constraints(&mut file)?; regioncx.dump_graphviz_raw_constraints(&mut file)?;
}; };
// Also dump the inference graph constraints as a graphviz file. // Also dump the inference graph constraints as a graphviz file.
let _: io::Result<()> = try { let _: io::Result<()> = try {
let mut file = let mut file = create_dump_file(infcx.tcx, "regioncx.scc.dot", false, "nll", &0, body)?;
create_dump_file(infcx.tcx, "regioncx.scc.dot", None, "nll", &0, body.source)?;
regioncx.dump_graphviz_scc_constraints(&mut file)?; regioncx.dump_graphviz_scc_constraints(&mut file)?;
}; };
} }

View File

@ -1,3 +1,5 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
use crate::borrow_set::{BorrowData, BorrowSet, TwoPhaseActivation}; use crate::borrow_set::{BorrowData, BorrowSet, TwoPhaseActivation};
use crate::places_conflict; use crate::places_conflict;
use crate::AccessDepth; use crate::AccessDepth;

View File

@ -1,3 +1,5 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
use crate::borrow_set::LocalsStateAtExit; use crate::borrow_set::LocalsStateAtExit;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_middle::mir::ProjectionElem; use rustc_middle::mir::ProjectionElem;

View File

@ -1,3 +1,5 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
use crate::ArtificialField; use crate::ArtificialField;
use crate::Overlap; use crate::Overlap;
use crate::{AccessDepth, Deep, Shallow}; use crate::{AccessDepth, Deep, Shallow};
@ -318,16 +320,10 @@ fn place_projection_conflict<'tcx>(
debug!("place_element_conflict: DISJOINT-OR-EQ-DEREF"); debug!("place_element_conflict: DISJOINT-OR-EQ-DEREF");
Overlap::EqualOrDisjoint Overlap::EqualOrDisjoint
} }
(ProjectionElem::OpaqueCast(v1), ProjectionElem::OpaqueCast(v2)) => { (ProjectionElem::OpaqueCast(_), ProjectionElem::OpaqueCast(_)) => {
if v1 == v2 { // casts to other types may always conflict irrespective of the type being cast to.
// same type - recur. debug!("place_element_conflict: DISJOINT-OR-EQ-OPAQUE");
debug!("place_element_conflict: DISJOINT-OR-EQ-OPAQUE"); Overlap::EqualOrDisjoint
Overlap::EqualOrDisjoint
} else {
// Different types. Disjoint!
debug!("place_element_conflict: DISJOINT-OPAQUE");
Overlap::Disjoint
}
} }
(ProjectionElem::Field(f1, _), ProjectionElem::Field(f2, _)) => { (ProjectionElem::Field(f1, _), ProjectionElem::Field(f2, _)) => {
if f1 == f2 { if f1 == f2 {

View File

@ -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 //! From the NLL RFC: "The deep [aka 'supporting'] prefixes for an
//! place are formed by stripping away fields and derefs, except that //! place are formed by stripping away fields and derefs, except that
//! we stop when we reach the deref of a shared reference. [...] " //! we stop when we reach the deref of a shared reference. [...] "

View File

@ -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`, //! As part of generating the regions, if you enable `-Zdump-mir=nll`,
//! we will generate an annotated copy of the MIR that includes the //! we will generate an annotated copy of the MIR that includes the
//! state of region inference. This code handles emitting the region //! 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(); let mut constraints: Vec<_> = self.constraints.outlives().iter().collect();
constraints.sort_by_key(|c| (c.sup, c.sub)); constraints.sort_by_key(|c| (c.sup, c.sub));
for constraint in &constraints { for constraint in &constraints {
let OutlivesConstraint { sup, sub, locations, category, span, variance_info: _ } = let OutlivesConstraint { sup, sub, locations, category, span, .. } = constraint;
constraint;
let (name, arg) = match locations { let (name, arg) = match locations {
Locations::All(span) => { Locations::All(span) => {
("All", tcx.sess.source_map().span_to_embeddable_string(*span)) ("All", tcx.sess.source_map().span_to_embeddable_string(*span))

View File

@ -1,3 +1,5 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
//! This module provides linkage between RegionInferenceContext and //! This module provides linkage between RegionInferenceContext and
//! `rustc_graphviz` traits, specialized to attaching borrowck analysis //! `rustc_graphviz` traits, specialized to attaching borrowck analysis
//! data to rendered labels. //! data to rendered labels.

View File

@ -6,10 +6,9 @@ use rustc_data_structures::frozen::Frozen;
use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::graph::scc::Sccs; use rustc_data_structures::graph::scc::Sccs;
use rustc_errors::Diagnostic; 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_hir::CRATE_HIR_ID;
use rustc_index::vec::IndexVec; use rustc_index::vec::IndexVec;
use rustc_infer::infer::canonical::QueryOutlivesConstraint;
use rustc_infer::infer::outlives::test_type_match; use rustc_infer::infer::outlives::test_type_match;
use rustc_infer::infer::region_constraints::{GenericKind, VarInfos, VerifyBound, VerifyIfEq}; use rustc_infer::infer::region_constraints::{GenericKind, VarInfos, VerifyBound, VerifyIfEq};
use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin, RegionVariableOrigin}; use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin, RegionVariableOrigin};
@ -19,9 +18,7 @@ use rustc_middle::mir::{
}; };
use rustc_middle::traits::ObligationCause; use rustc_middle::traits::ObligationCause;
use rustc_middle::traits::ObligationCauseCode; use rustc_middle::traits::ObligationCauseCode;
use rustc_middle::ty::{ use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt, TypeFoldable, TypeVisitable};
self, subst::SubstsRef, RegionVid, Ty, TyCtxt, TypeFoldable, TypeVisitable,
};
use rustc_span::Span; use rustc_span::Span;
use crate::{ use crate::{
@ -89,10 +86,6 @@ pub struct RegionInferenceContext<'tcx> {
/// `member_region_scc`. /// `member_region_scc`.
member_constraints_applied: Vec<AppliedMemberConstraint>, 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. /// Map universe indexes to information on why we created it.
universe_causes: FxHashMap<ty::UniverseIndex, UniverseInfo<'tcx>>, 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 /// 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 /// with `'R: 'O` where `'R` is the pick-region and `'O` is the
/// minimal viable option. /// minimal viable option.
#[derive(Debug)]
pub(crate) struct AppliedMemberConstraint { pub(crate) struct AppliedMemberConstraint {
/// The SCC that was affected. (The "member region".) /// The SCC that was affected. (The "member region".)
/// ///
@ -221,8 +215,8 @@ pub struct TypeTest<'tcx> {
/// The region `'x` that the type must outlive. /// The region `'x` that the type must outlive.
pub lower_bound: RegionVid, pub lower_bound: RegionVid,
/// Where did this constraint arise and why? /// The span to blame.
pub locations: Locations, pub span: Span,
/// A test which, if met by the region `'x`, proves that this type /// A test which, if met by the region `'x`, proves that this type
/// constraint is satisfied. /// constraint is satisfied.
@ -265,10 +259,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
universal_region_relations: Frozen<UniversalRegionRelations<'tcx>>, universal_region_relations: Frozen<UniversalRegionRelations<'tcx>>,
outlives_constraints: OutlivesConstraintSet<'tcx>, outlives_constraints: OutlivesConstraintSet<'tcx>,
member_constraints_in: MemberConstraintSet<'tcx, RegionVid>, member_constraints_in: MemberConstraintSet<'tcx, RegionVid>,
closure_bounds_mapping: FxHashMap<
Location,
FxHashMap<(RegionVid, RegionVid), (ConstraintCategory<'tcx>, Span)>,
>,
universe_causes: FxHashMap<ty::UniverseIndex, UniverseInfo<'tcx>>, universe_causes: FxHashMap<ty::UniverseIndex, UniverseInfo<'tcx>>,
type_tests: Vec<TypeTest<'tcx>>, type_tests: Vec<TypeTest<'tcx>>,
liveness_constraints: LivenessValues<RegionVid>, liveness_constraints: LivenessValues<RegionVid>,
@ -310,7 +300,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
rev_scc_graph: None, rev_scc_graph: None,
member_constraints, member_constraints,
member_constraints_applied: Vec::new(), member_constraints_applied: Vec::new(),
closure_bounds_mapping,
universe_causes, universe_causes,
scc_universes, scc_universes,
scc_representatives, scc_representatives,
@ -882,13 +871,13 @@ impl<'tcx> RegionInferenceContext<'tcx> {
if deduplicate_errors.insert(( if deduplicate_errors.insert((
erased_generic_kind, erased_generic_kind,
type_test.lower_bound, type_test.lower_bound,
type_test.locations, type_test.span,
)) { )) {
debug!( debug!(
"check_type_test: reporting error for erased_generic_kind={:?}, \ "check_type_test: reporting error for erased_generic_kind={:?}, \
lower_bound_region={:?}, \ lower_bound_region={:?}, \
type_test.locations={:?}", type_test.span={:?}",
erased_generic_kind, type_test.lower_bound, type_test.locations, erased_generic_kind, type_test.lower_bound, type_test.span,
); );
errors_buffer.push(RegionErrorKind::TypeTestError { type_test: type_test.clone() }); errors_buffer.push(RegionErrorKind::TypeTestError { type_test: type_test.clone() });
@ -931,7 +920,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
) -> bool { ) -> bool {
let tcx = infcx.tcx; 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 generic_ty = generic_kind.to_ty(tcx);
let Some(subject) = self.try_promote_type_test_subject(infcx, generic_ty) else { 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 { propagated_outlives_requirements.push(ClosureOutlivesRequirement {
subject, subject,
outlived_free_region: static_r, outlived_free_region: static_r,
blame_span: locations.span(body), blame_span: type_test.span,
category: ConstraintCategory::Boring, category: ConstraintCategory::Boring,
}); });
@ -1011,7 +1000,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
let requirement = ClosureOutlivesRequirement { let requirement = ClosureOutlivesRequirement {
subject, subject,
outlived_free_region: upper_bound, outlived_free_region: upper_bound,
blame_span: locations.span(body), blame_span: type_test.span,
category: ConstraintCategory::Boring, category: ConstraintCategory::Boring,
}; };
debug!("try_promote_type_test: pushing {:#?}", requirement); 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( fn check_member_constraints(
&self, &self,
infcx: &InferCtxt<'tcx>, infcx: &InferCtxt<'tcx>,
@ -1723,22 +1713,21 @@ impl<'tcx> RegionInferenceContext<'tcx> {
) { ) {
let member_constraints = self.member_constraints.clone(); let member_constraints = self.member_constraints.clone();
for m_c_i in member_constraints.all_indices() { 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 m_c = &member_constraints[m_c_i];
let member_region_vid = m_c.member_region_vid; let member_region_vid = m_c.member_region_vid;
debug!( debug!(
"check_member_constraint: member_region_vid={:?} with value {}", ?member_region_vid,
member_region_vid, value = ?self.region_value_str(member_region_vid),
self.region_value_str(member_region_vid),
); );
let choice_regions = member_constraints.choice_regions(m_c_i); 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? // Did the member region wind up equal to any of the option regions?
if let Some(o) = if let Some(o) =
choice_regions.iter().find(|&&o_r| self.eval_equal(o_r, m_c.member_region_vid)) 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; 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`. /// Finds a good `ObligationCause` to blame for the fact that `fr1` outlives `fr2`.
pub(crate) fn find_outlives_blame_span( pub(crate) fn find_outlives_blame_span(
&self, &self,
@ -1921,6 +1898,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
span: p_c.definition_span, span: p_c.definition_span,
category: ConstraintCategory::OpaqueType, category: ConstraintCategory::OpaqueType,
variance_info: ty::VarianceDiagInfo::default(), variance_info: ty::VarianceDiagInfo::default(),
from_closure: false,
}; };
handle_constraint(constraint); handle_constraint(constraint);
} }
@ -2066,31 +2044,12 @@ impl<'tcx> RegionInferenceContext<'tcx> {
// Classify each of the constraints along the path. // Classify each of the constraints along the path.
let mut categorized_path: Vec<BlameConstraint<'tcx>> = path let mut categorized_path: Vec<BlameConstraint<'tcx>> = path
.iter() .iter()
.map(|constraint| { .map(|constraint| BlameConstraint {
let (category, span, from_closure, cause_code) = category: constraint.category,
if constraint.category == ConstraintCategory::ClosureBounds { from_closure: constraint.from_closure,
if let Some((category, span)) = cause: ObligationCause::new(constraint.span, CRATE_HIR_ID, cause_code.clone()),
self.retrieve_closure_constraint_info(*constraint) variance_info: constraint.variance_info,
{ outlives_constraint: *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,
}
}) })
.collect(); .collect();
debug!("categorized_path={:#?}", categorized_path); 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)] #[derive(Clone, Debug)]
pub struct BlameConstraint<'tcx> { pub struct BlameConstraint<'tcx> {
pub category: ConstraintCategory<'tcx>, pub category: ConstraintCategory<'tcx>,

View File

@ -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_data_structures::vec_map::VecMap;
use rustc_hir::def_id::LocalDefId; use rustc_hir::def_id::LocalDefId;
use rustc_hir::OpaqueTyOrigin; use rustc_hir::OpaqueTyOrigin;
use rustc_infer::infer::TyCtxtInferExt as _; use rustc_infer::infer::TyCtxtInferExt as _;
use rustc_infer::infer::{DefiningAnchor, InferCtxt}; 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::subst::{GenericArgKind, InternalSubsts};
use rustc_middle::ty::visit::TypeVisitable; use rustc_middle::ty::visit::TypeVisitable;
use rustc_middle::ty::{ use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable};
self, OpaqueHiddenType, OpaqueTypeKey, ToPredicate, Ty, TyCtxt, TypeFoldable,
};
use rustc_span::Span; use rustc_span::Span;
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _; 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; use super::RegionInferenceContext;
@ -63,17 +61,21 @@ impl<'tcx> RegionInferenceContext<'tcx> {
opaque_ty_decls: VecMap<OpaqueTypeKey<'tcx>, (OpaqueHiddenType<'tcx>, OpaqueTyOrigin)>, opaque_ty_decls: VecMap<OpaqueTypeKey<'tcx>, (OpaqueHiddenType<'tcx>, OpaqueTyOrigin)>,
) -> VecMap<LocalDefId, OpaqueHiddenType<'tcx>> { ) -> VecMap<LocalDefId, OpaqueHiddenType<'tcx>> {
let mut result: VecMap<LocalDefId, OpaqueHiddenType<'tcx>> = VecMap::new(); 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 { for (opaque_type_key, (concrete_type, origin)) in opaque_ty_decls {
let substs = opaque_type_key.substs; let substs = opaque_type_key.substs;
debug!(?concrete_type, ?substs); debug!(?concrete_type, ?substs);
let mut subst_regions = vec![self.universal_regions.fr_static]; 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() { let to_universal_region = |vid, subst_regions: &mut Vec<_>| {
// 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);
trace!(?vid); trace!(?vid);
let scc = self.constraint_sccs.scc(vid); let scc = self.constraint_sccs.scc(vid);
trace!(?scc); trace!(?scc);
@ -94,10 +96,33 @@ impl<'tcx> RegionInferenceContext<'tcx> {
infcx.tcx.lifetimes.re_static infcx.tcx.lifetimes.re_static
} }
} }
}); };
subst_regions.sort(); // Start by inserting universal regions from the member_constraint choice regions.
subst_regions.dedup(); // 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 = let universal_concrete_type =
infcx.tcx.fold_regions(concrete_type, |region, _| match *region { infcx.tcx.fold_regions(concrete_type, |region, _| match *region {
@ -108,8 +133,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
.unwrap_or(infcx.tcx.lifetimes.re_erased), .unwrap_or(infcx.tcx.lifetimes.re_erased),
_ => region, _ => region,
}); });
debug!(?universal_concrete_type);
debug!(?universal_concrete_type, ?universal_substs);
let opaque_type_key = let opaque_type_key =
OpaqueTypeKey { def_id: opaque_type_key.def_id, substs: universal_substs }; 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>, instantiated_ty: OpaqueHiddenType<'tcx>,
origin: OpaqueTyOrigin, origin: OpaqueTyOrigin,
) -> Ty<'tcx> { ) -> Ty<'tcx> {
if self.is_tainted_by_errors() { if let Some(e) = self.tainted_by_errors() {
return self.tcx.ty_error(); return self.tcx.ty_error_with_guaranteed(e);
} }
let definition_ty = instantiated_ty 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; .ty;
if !check_opaque_type_parameter_valid( 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 // type-alias-impl-trait/issue-67844-nested-opaque.rs
let infcx = let infcx =
self.tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bubble).build(); 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. // 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 // 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. // hidden type is well formed even without those bounds.
let predicate = ty::Binder::dummy(ty::PredicateKind::WellFormed(definition_ty.into())) 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 id_substs = InternalSubsts::identity_for_item(self.tcx, def_id.to_def_id()); 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 // Require that the hidden type actually fulfills all the bounds of the opaque type, even without
// the bounds that the function supplies. // the bounds that the function supplies.
let opaque_ty = self.tcx.mk_opaque(def_id.to_def_id(), id_substs); let opaque_ty = self.tcx.mk_opaque(def_id.to_def_id(), id_substs);
match infcx if let Err(err) = ocx.eq(
.at(&ObligationCause::misc(instantiated_ty.span, body_id), param_env) &ObligationCause::misc(instantiated_ty.span, body_id),
.eq(opaque_ty, definition_ty) param_env,
{ opaque_ty,
Ok(infer_ok) => { definition_ty,
for obligation in infer_ok.obligations { ) {
fulfillment_cx.register_predicate_obligation(&infcx, obligation); infcx
} .err_ctxt()
} .report_mismatched_types(
Err(err) => { &ObligationCause::misc(instantiated_ty.span, body_id),
infcx opaque_ty,
.err_ctxt() definition_ty,
.report_mismatched_types( err,
&ObligationCause::misc(instantiated_ty.span, body_id), )
opaque_ty, .emit();
definition_ty,
err,
)
.emit();
}
} }
fulfillment_cx.register_predicate_obligation( ocx.register_obligation(Obligation::misc(
&infcx, infcx.tcx,
Obligation::misc(instantiated_ty.span, body_id, param_env, predicate), instantiated_ty.span,
); body_id,
param_env,
predicate,
));
// Check that all obligations are satisfied by the implementation's // Check that all obligations are satisfied by the implementation's
// version. // 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) // This is still required for many(half of the tests in ui/type-alias-impl-trait)
// tests to pass // tests to pass
@ -302,8 +323,8 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
if errors.is_empty() { if errors.is_empty() {
definition_ty definition_ty
} else { } else {
infcx.err_ctxt().report_fulfillment_errors(&errors, None, false); let reported = infcx.err_ctxt().report_fulfillment_errors(&errors, None);
self.tcx.ty_error() self.tcx.ty_error_with_guaranteed(reported)
} }
} }
} }

View File

@ -1,3 +1,5 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
use crate::constraints::ConstraintSccIndex; use crate::constraints::ConstraintSccIndex;
use crate::RegionInferenceContext; use crate::RegionInferenceContext;
use itertools::Itertools; use itertools::Itertools;

View File

@ -1,3 +1,5 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
use rustc_data_structures::fx::FxIndexSet; use rustc_data_structures::fx::FxIndexSet;
use rustc_index::bit_set::SparseBitMatrix; use rustc_index::bit_set::SparseBitMatrix;
use rustc_index::interval::IntervalSet; use rustc_index::interval::IntervalSet;

View File

@ -1,3 +1,5 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
use rustc_index::vec::IndexVec; use rustc_index::vec::IndexVec;
use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin}; use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin};
use rustc_middle::mir::visit::{MutVisitor, TyContext}; use rustc_middle::mir::visit::{MutVisitor, TyContext};

View File

@ -49,7 +49,7 @@ pub(crate) struct GenericDoesNotLiveLongEnough {
#[derive(LintDiagnostic)] #[derive(LintDiagnostic)]
#[diag(borrowck_var_does_not_need_mut)] #[diag(borrowck_var_does_not_need_mut)]
pub(crate) struct VarNeedNotMut { pub(crate) struct VarNeedNotMut {
#[suggestion_short(applicability = "machine-applicable", code = "")] #[suggestion(style = "short", applicability = "machine-applicable", code = "")]
pub span: Span, pub span: Span,
} }
#[derive(Diagnostic)] #[derive(Diagnostic)]
@ -148,3 +148,95 @@ pub(crate) enum RequireStaticErr {
multi_span: MultiSpan, 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,
}

View File

@ -88,12 +88,11 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
category: ConstraintCategory<'tcx>, category: ConstraintCategory<'tcx>,
) { ) {
self.prove_predicate( self.prove_predicate(
ty::Binder::dummy(ty::PredicateKind::Trait(ty::TraitPredicate { ty::Binder::dummy(ty::PredicateKind::Clause(ty::Clause::Trait(ty::TraitPredicate {
trait_ref, trait_ref,
constness: ty::BoundConstness::NotConst, constness: ty::BoundConstness::NotConst,
polarity: ty::ImplPolarity::Positive, polarity: ty::ImplPolarity::Positive,
})) }))),
.to_predicate(self.tcx()),
locations, locations,
category, category,
); );
@ -122,14 +121,11 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
pub(super) fn prove_predicates( pub(super) fn prove_predicates(
&mut self, &mut self,
predicates: impl IntoIterator<Item = impl ToPredicate<'tcx>>, predicates: impl IntoIterator<Item = impl ToPredicate<'tcx> + std::fmt::Debug>,
locations: Locations, locations: Locations,
category: ConstraintCategory<'tcx>, category: ConstraintCategory<'tcx>,
) { ) {
for predicate in predicates { for predicate in predicates {
let predicate = predicate.to_predicate(self.tcx());
debug!("prove_predicates(predicate={:?}, locations={:?})", predicate, locations,);
self.prove_predicate(predicate, locations, category); self.prove_predicate(predicate, locations, category);
} }
} }
@ -137,11 +133,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
#[instrument(skip(self), level = "debug")] #[instrument(skip(self), level = "debug")]
pub(super) fn prove_predicate( pub(super) fn prove_predicate(
&mut self, &mut self,
predicate: ty::Predicate<'tcx>, predicate: impl ToPredicate<'tcx> + std::fmt::Debug,
locations: Locations, locations: Locations,
category: ConstraintCategory<'tcx>, category: ConstraintCategory<'tcx>,
) { ) {
let param_env = self.param_env; let param_env = self.param_env;
let predicate = predicate.to_predicate(self.tcx());
self.fully_perform_op( self.fully_perform_op(
locations, locations,
category, category,

View File

@ -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::canonical::QueryRegionConstraints;
use rustc_infer::infer::outlives::env::RegionBoundPairs; use rustc_infer::infer::outlives::env::RegionBoundPairs;
use rustc_infer::infer::outlives::obligations::{TypeOutlives, TypeOutlivesDelegate}; use rustc_infer::infer::outlives::obligations::{TypeOutlives, TypeOutlivesDelegate};
use rustc_infer::infer::region_constraints::{GenericKind, VerifyBound}; use rustc_infer::infer::region_constraints::{GenericKind, VerifyBound};
use rustc_infer::infer::{self, InferCtxt, SubregionOrigin}; 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::subst::GenericArgKind;
use rustc_middle::ty::TypeFoldable; use rustc_middle::ty::TypeFoldable;
use rustc_middle::ty::{self, TyCtxt}; use rustc_middle::ty::{self, TyCtxt};
@ -38,6 +38,7 @@ pub(crate) struct ConstraintConversion<'a, 'tcx> {
locations: Locations, locations: Locations,
span: Span, span: Span,
category: ConstraintCategory<'tcx>, category: ConstraintCategory<'tcx>,
from_closure: bool,
constraints: &'a mut MirTypeckRegionConstraints<'tcx>, constraints: &'a mut MirTypeckRegionConstraints<'tcx>,
} }
@ -64,6 +65,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
span, span,
category, category,
constraints, constraints,
from_closure: false,
} }
} }
@ -81,12 +83,62 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
} }
self.constraints.member_constraints = tmp; self.constraints.member_constraints = tmp;
for query_constraint in outlives { for (predicate, constraint_category) in outlives {
self.convert(query_constraint); // 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); debug!("generate: constraints at: {:#?}", self.locations);
// Extract out various useful fields we'll need below. // 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, .. tcx, region_bound_pairs, implicit_region_bound, param_env, ..
} = *self; } = *self;
// At the moment, we never generate any "higher-ranked" let ty::OutlivesPredicate(k1, r2) = predicate;
// 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;
match k1.unpack() { match k1.unpack() {
GenericArgKind::Lifetime(r1) => { GenericArgKind::Lifetime(r1) => {
let r1_vid = self.to_region_vid(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); .type_must_outlive(origin, t1, r2, constraint_category);
} }
GenericArgKind::Const(_) => { GenericArgKind::Const(_) => unreachable!(),
// Consts cannot outlive one another, so we
// don't need to handle any relations here.
}
} }
} }
@ -160,7 +199,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
verify_bound: VerifyBound<'tcx>, verify_bound: VerifyBound<'tcx>,
) -> TypeTest<'tcx> { ) -> TypeTest<'tcx> {
let lower_bound = self.to_region_vid(region); 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 { fn to_region_vid(&mut self, r: ty::Region<'tcx>) -> ty::RegionVid {
@ -188,6 +227,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
sub, sub,
sup, sup,
variance_info: ty::VarianceDiagInfo::default(), variance_info: ty::VarianceDiagInfo::default(),
from_closure: self.from_closure,
}); });
} }

View File

@ -247,12 +247,13 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
.and(type_op::normalize::Normalize::new(ty)) .and(type_op::normalize::Normalize::new(ty))
.fully_perform(self.infcx) .fully_perform(self.infcx)
.unwrap_or_else(|_| { .unwrap_or_else(|_| {
self.infcx let reported = self
.infcx
.tcx .tcx
.sess .sess
.delay_span_bug(span, &format!("failed to normalize {:?}", ty)); .delay_span_bug(span, &format!("failed to normalize {:?}", ty));
TypeOpOutput { TypeOpOutput {
output: self.infcx.tcx.ty_error(), output: self.infcx.tcx.ty_error_with_guaranteed(reported),
constraints: None, constraints: None,
error_info: None, error_info: None,
} }

View File

@ -42,8 +42,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
user_provided_sig = None; user_provided_sig = None;
} else { } else {
let typeck_results = self.tcx().typeck(mir_def_id); 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_sig =
|user_provided_poly_sig| { typeck_results.user_provided_sigs.get(&mir_def_id).map(|user_provided_poly_sig| {
// Instantiate the canonicalized variables from // Instantiate the canonicalized variables from
// user-provided signature (e.g., the `_` in the code // user-provided signature (e.g., the `_` in the code
// above) with fresh variables. // above) with fresh variables.
@ -60,8 +60,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
LateBoundRegionConversionTime::FnCall, LateBoundRegionConversionTime::FnCall,
poly_sig, poly_sig,
) )
}, });
);
} }
debug!(?normalized_input_tys, ?body.local_decls); debug!(?normalized_input_tys, ?body.local_decls);

View File

@ -121,8 +121,8 @@ pub(super) fn populate_access_facts<'a, 'tcx>(
} }
} }
// For every potentially drop()-touched region `region` in `local`'s type /// For every potentially drop()-touched region `region` in `local`'s type
// (`kind`), emit a Polonius `use_of_var_derefs_origin(local, origin)` fact. /// (`kind`), emit a Polonius `use_of_var_derefs_origin(local, origin)` fact.
pub(super) fn add_drop_of_var_derefs_origin<'tcx>( pub(super) fn add_drop_of_var_derefs_origin<'tcx>(
typeck: &mut TypeChecker<'_, 'tcx>, typeck: &mut TypeChecker<'_, 'tcx>,
local: Local, local: Local,

View File

@ -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. //! This pass type-checks the MIR to ensure it is not broken.
use std::rc::Rc; use std::rc::Rc;
@ -27,12 +29,11 @@ use rustc_middle::mir::AssertKind;
use rustc_middle::mir::*; use rustc_middle::mir::*;
use rustc_middle::ty::adjustment::PointerCast; use rustc_middle::ty::adjustment::PointerCast;
use rustc_middle::ty::cast::CastTy; 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::visit::TypeVisitable;
use rustc_middle::ty::{ use rustc_middle::ty::{
self, Binder, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, Dynamic, self, Binder, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, Dynamic,
OpaqueHiddenType, OpaqueTypeKey, RegionVid, ToPredicate, Ty, TyCtxt, UserType, OpaqueHiddenType, OpaqueTypeKey, RegionVid, Ty, TyCtxt, UserType, UserTypeAnnotationIndex,
UserTypeAnnotationIndex,
}; };
use rustc_span::def_id::CRATE_DEF_ID; use rustc_span::def_id::CRATE_DEF_ID;
use rustc_span::{Span, DUMMY_SP}; use rustc_span::{Span, DUMMY_SP};
@ -61,7 +62,7 @@ use crate::{
region_infer::values::{ region_infer::values::{
LivenessValues, PlaceholderIndex, PlaceholderIndices, RegionValueElements, LivenessValues, PlaceholderIndex, PlaceholderIndices, RegionValueElements,
}, },
region_infer::{ClosureRegionRequirementsExt, TypeTest}, region_infer::TypeTest,
type_check::free_region_relations::{CreateResult, UniversalRegionRelations}, type_check::free_region_relations::{CreateResult, UniversalRegionRelations},
universal_regions::{DefiningTy, UniversalRegions}, universal_regions::{DefiningTy, UniversalRegions},
Upvar, Upvar,
@ -144,7 +145,6 @@ pub(crate) fn type_check<'mir, 'tcx>(
liveness_constraints: LivenessValues::new(elements.clone()), liveness_constraints: LivenessValues::new(elements.clone()),
outlives_constraints: OutlivesConstraintSet::default(), outlives_constraints: OutlivesConstraintSet::default(),
member_constraints: MemberConstraintSet::default(), member_constraints: MemberConstraintSet::default(),
closure_bounds_mapping: Default::default(),
type_tests: Vec::default(), type_tests: Vec::default(),
universe_causes: FxHashMap::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); let mut hidden_type = infcx.resolve_vars_if_possible(decl.hidden_type);
trace!("finalized opaque type {:?} to {:#?}", opaque_type_key, hidden_type.ty.kind()); trace!("finalized opaque type {:?} to {:#?}", opaque_type_key, hidden_type.ty.kind());
if hidden_type.has_non_region_infer() { 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, decl.hidden_type.span,
&format!("could not resolve {:#?}", hidden_type.ty.kind()), &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)) (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 { if let PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) = context {
let tcx = self.tcx(); let tcx = self.tcx();
let trait_ref = ty::TraitRef { let trait_ref = tcx.at(self.last_span).mk_trait_ref(LangItem::Copy, [place_ty.ty]);
def_id: tcx.require_lang_item(LangItem::Copy, Some(self.last_span)),
substs: tcx.mk_substs_trait(place_ty.ty, &[]),
};
// To have a `Copy` operand, the type `T` of the // To have a `Copy` operand, the type `T` of the
// value must be `Copy`. Note that we prove that `T: Copy`, // 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. // modify their locations.
let all_facts = &mut None; let all_facts = &mut None;
let mut constraints = Default::default(); let mut constraints = Default::default();
let mut type_tests = Default::default();
let mut closure_bounds = Default::default();
let mut liveness_constraints = let mut liveness_constraints =
LivenessValues::new(Rc::new(RegionValueElements::new(&promoted_body))); LivenessValues::new(Rc::new(RegionValueElements::new(&promoted_body)));
// Don't try to add borrow_region facts for the promoted MIR // 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 this.cx.borrowck_context.constraints.outlives_constraints,
&mut 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( mem::swap(
&mut this.cx.borrowck_context.constraints.liveness_constraints, &mut this.cx.borrowck_context.constraints.liveness_constraints,
&mut liveness_constraints, &mut liveness_constraints,
@ -621,13 +611,6 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
swap_constraints(self); swap_constraints(self);
let locations = location.to_locations(); 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() { for constraint in constraints.outlives().iter() {
let mut constraint = constraint.clone(); let mut constraint = constraint.clone();
constraint.locations = locations; constraint.locations = locations;
@ -653,18 +636,6 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
.add_element(region, location); .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( fn sanitize_projection(
@ -941,9 +912,6 @@ pub(crate) struct MirTypeckRegionConstraints<'tcx> {
pub(crate) member_constraints: MemberConstraintSet<'tcx, RegionVid>, 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) universe_causes: FxHashMap<ty::UniverseIndex, UniverseInfo<'tcx>>,
pub(crate) type_tests: Vec<TypeTest<'tcx>>, pub(crate) type_tests: Vec<TypeTest<'tcx>>,
@ -1097,8 +1065,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
} }
self.prove_predicate( self.prove_predicate(
ty::Binder::dummy(ty::PredicateKind::WellFormed(inferred_ty.into())) ty::Binder::dummy(ty::PredicateKind::WellFormed(inferred_ty.into())),
.to_predicate(self.tcx()),
Locations::All(span), Locations::All(span),
ConstraintCategory::TypeAnnotation, 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) { fn check_stmt(&mut self, body: &Body<'tcx>, stmt: &Statement<'tcx>, location: Location) {
let tcx = self.tcx(); let tcx = self.tcx();
debug!("stmt kind: {:?}", stmt.kind); debug!("stmt kind: {:?}", stmt.kind);
match stmt.kind { match &stmt.kind {
StatementKind::Assign(box (ref place, ref rv)) => { StatementKind::Assign(box (place, rv)) => {
// Assignments to temporaries are not "interesting"; // Assignments to temporaries are not "interesting";
// they are not caused by the user, but rather artifacts // they are not caused by the user, but rather artifacts
// of lowering. Assignments to other sorts of places *are* interesting // 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); self.check_rvalue(body, rv, location);
if !self.unsized_feature_enabled() { if !self.unsized_feature_enabled() {
let trait_ref = ty::TraitRef { let trait_ref =
def_id: tcx.require_lang_item(LangItem::Sized, Some(self.last_span)), tcx.at(self.last_span).mk_trait_ref(LangItem::Sized, [place_ty]);
substs: tcx.mk_substs_trait(place_ty, &[]),
};
self.prove_trait_ref( self.prove_trait_ref(
trait_ref, trait_ref,
location.to_locations(), 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; let place_ty = place.ty(body, tcx).ty;
if let Err(terr) = self.relate_type_and_user_type( if let Err(terr) = self.relate_type_and_user_type(
place_ty, place_ty,
variance, *variance,
projection, projection,
Locations::All(stmt.source_info.span), Locations::All(stmt.source_info.span),
ConstraintCategory::TypeAnnotation, 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::Assume(op) => self.check_operand(op, location),
NonDivergingIntrinsic::CopyNonOverlapping(..) => span_bug!( NonDivergingIntrinsic::CopyNonOverlapping(..) => span_bug!(
stmt.source_info.span, stmt.source_info.span,
@ -1363,7 +1328,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
) { ) {
let tcx = self.tcx(); let tcx = self.tcx();
debug!("terminator kind: {:?}", term.kind); debug!("terminator kind: {:?}", term.kind);
match term.kind { match &term.kind {
TerminatorKind::Goto { .. } TerminatorKind::Goto { .. }
| TerminatorKind::Resume | TerminatorKind::Resume
| TerminatorKind::Abort | TerminatorKind::Abort
@ -1377,7 +1342,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
// no checks needed for these // 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 place_ty = place.ty(body, tcx).ty;
let rv_ty = value.ty(body, tcx); 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); self.check_operand(discr, term_location);
let discr_ty = discr.ty(body, tcx); let discr_ty = discr.ty(body, tcx);
if let Err(terr) = self.sub_types( if let Err(terr) = self.sub_types(
discr_ty, discr_ty,
switch_ty, *switch_ty,
term_location.to_locations(), term_location.to_locations(),
ConstraintCategory::Assignment, ConstraintCategory::Assignment,
) { ) {
@ -1419,14 +1384,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
} }
// FIXME: check the values // FIXME: check the values
} }
TerminatorKind::Call { TerminatorKind::Call { func, args, destination, from_hir_call, target, .. } => {
ref func,
ref args,
ref destination,
from_hir_call,
target,
..
} => {
self.check_operand(func, term_location); self.check_operand(func, term_location);
for arg in args { for arg in args {
self.check_operand(arg, term_location); self.check_operand(arg, term_location);
@ -1466,7 +1424,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
ConstraintCategory::Boring, ConstraintCategory::Boring,
); );
let sig = self.normalize(sig, term_location); 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 // The ordinary liveness rules will ensure that all
// regions in the type of the callee are live here. We // 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); .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); self.check_operand(cond, term_location);
let cond_ty = cond.ty(body, tcx); 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); 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 { if len.ty(body, tcx) != tcx.types.usize {
span_mirbug!(self, len, "bounds-check length non-usize {:?}", len) 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); self.check_operand(value, term_location);
let value_ty = value.ty(body, tcx); let value_ty = value.ty(body, tcx);
@ -1594,10 +1552,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
} }
} }
None => { None => {
if !self if !sig.output().is_privately_uninhabited(self.tcx(), self.param_env) {
.tcx()
.conservative_is_privately_uninhabited(self.param_env.and(sig.output()))
{
span_mirbug!(self, term, "call to converging function {:?} w/o dest", sig); 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")] #[instrument(skip(self, body), level = "debug")]
fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: Location) { fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: Location) {
let tcx = self.tcx(); let tcx = self.tcx();
let span = body.source_info(location).span;
match rvalue { match rvalue {
Rvalue::Aggregate(ak, ops) => { Rvalue::Aggregate(ak, ops) => {
@ -1896,12 +1852,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
} }
Operand::Move(place) => { Operand::Move(place) => {
// Make sure that repeated elements implement `Copy`. // Make sure that repeated elements implement `Copy`.
let span = body.source_info(location).span;
let ty = place.ty(body, tcx).ty; let ty = place.ty(body, tcx).ty;
let trait_ref = ty::TraitRef::new( let trait_ref = tcx.at(span).mk_trait_ref(LangItem::Copy, [ty]);
tcx.require_lang_item(LangItem::Copy, Some(span)),
tcx.mk_substs_trait(ty, &[]),
);
self.prove_trait_ref( self.prove_trait_ref(
trait_ref, trait_ref,
@ -1914,10 +1866,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
} }
&Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, ty) => { &Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, ty) => {
let trait_ref = ty::TraitRef { let trait_ref = tcx.at(span).mk_trait_ref(LangItem::Sized, [ty]);
def_id: tcx.require_lang_item(LangItem::Sized, Some(self.last_span)),
substs: tcx.mk_substs_trait(ty, &[]),
};
self.prove_trait_ref( self.prove_trait_ref(
trait_ref, trait_ref,
@ -1929,10 +1878,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
Rvalue::ShallowInitBox(operand, ty) => { Rvalue::ShallowInitBox(operand, ty) => {
self.check_operand(operand, location); self.check_operand(operand, location);
let trait_ref = ty::TraitRef { let trait_ref = tcx.at(span).mk_trait_ref(LangItem::Sized, [*ty]);
def_id: tcx.require_lang_item(LangItem::Sized, Some(self.last_span)),
substs: tcx.mk_substs_trait(*ty, &[]),
};
self.prove_trait_ref( self.prove_trait_ref(
trait_ref, trait_ref,
@ -2029,11 +1975,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
CastKind::Pointer(PointerCast::Unsize) => { CastKind::Pointer(PointerCast::Unsize) => {
let &ty = ty; let &ty = ty;
let trait_ref = ty::TraitRef { let trait_ref = tcx
def_id: tcx .at(span)
.require_lang_item(LangItem::CoerceUnsized, Some(self.last_span)), .mk_trait_ref(LangItem::CoerceUnsized, [op.ty(body, tcx), ty]);
substs: tcx.mk_substs_trait(op.ty(body, tcx), &[ty.into()]),
};
self.prove_trait_ref( self.prove_trait_ref(
trait_ref, trait_ref,
@ -2062,8 +2006,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
); );
let outlives_predicate = let outlives_predicate =
tcx.mk_predicate(Binder::dummy(ty::PredicateKind::TypeOutlives( tcx.mk_predicate(Binder::dummy(ty::PredicateKind::Clause(
ty::OutlivesPredicate(self_ty, *region), ty::Clause::TypeOutlives(ty::OutlivesPredicate(self_ty, *region)),
))); )));
self.prove_predicate( self.prove_predicate(
outlives_predicate, outlives_predicate,
@ -2562,6 +2506,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
span: location.to_locations().span(body), span: location.to_locations().span(body),
category, category,
variance_info: ty::VarianceDiagInfo::default(), variance_info: ty::VarianceDiagInfo::default(),
from_closure: false,
}); });
match mutbl { match mutbl {
@ -2636,7 +2581,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
} }
// For closures, we have some **extra requirements** we // For closures, we have some **extra requirements** we
//
// have to check. In particular, in their upvars and // have to check. In particular, in their upvars and
// signatures, closures often reference various regions // signatures, closures often reference various regions
// from the surrounding function -- we call those the // from the surrounding function -- we call those the
@ -2679,62 +2623,22 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
substs: SubstsRef<'tcx>, substs: SubstsRef<'tcx>,
location: Location, location: Location,
) -> ty::InstantiatedPredicates<'tcx> { ) -> ty::InstantiatedPredicates<'tcx> {
if let Some(ref closure_region_requirements) = tcx.mir_borrowck(def_id).closure_requirements if let Some(closure_requirements) = &tcx.mir_borrowck(def_id).closure_requirements {
{ constraint_conversion::ConstraintConversion::new(
let closure_constraints = QueryRegionConstraints { self.infcx,
outlives: closure_region_requirements.apply_requirements( self.borrowck_context.universal_regions,
tcx, self.region_bound_pairs,
def_id.to_def_id(), self.implicit_region_bound,
substs, self.param_env,
),
// 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(
location.to_locations(), location.to_locations(),
ConstraintCategory::ClosureBounds, DUMMY_SP, // irrelevant; will be overrided.
&closure_constraints, ConstraintCategory::Boring, // same as above.
&mut self.borrowck_context.constraints,
)
.apply_closure_requirements(
&closure_requirements,
def_id.to_def_id(),
substs,
); );
} }

View File

@ -2,9 +2,8 @@ use rustc_infer::infer::nll_relate::{NormalizationStrategy, TypeRelating, TypeRe
use rustc_infer::infer::NllRegionVariableOrigin; use rustc_infer::infer::NllRegionVariableOrigin;
use rustc_infer::traits::PredicateObligations; use rustc_infer::traits::PredicateObligations;
use rustc_middle::mir::ConstraintCategory; use rustc_middle::mir::ConstraintCategory;
use rustc_middle::ty::error::TypeError;
use rustc_middle::ty::relate::TypeRelation; 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_span::Span;
use rustc_trait_selection::traits::query::Fallible; 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), span: self.locations.span(self.type_checker.body),
category: self.category, category: self.category,
variance_info: info, 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 { fn normalization() -> NormalizationStrategy {
NormalizationStrategy::Eager NormalizationStrategy::Eager
} }
@ -155,10 +148,7 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx>
true true
} }
fn register_opaque_type_obligations( fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) {
&mut self,
obligations: PredicateObligations<'tcx>,
) -> Result<(), TypeError<'tcx>> {
self.type_checker self.type_checker
.fully_perform_op( .fully_perform_op(
self.locations, self.locations,
@ -171,6 +161,5 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx>
}, },
) )
.unwrap(); .unwrap();
Ok(())
} }
} }

View File

@ -22,7 +22,9 @@ use rustc_hir::{BodyOwnerKind, HirId};
use rustc_index::vec::{Idx, IndexVec}; use rustc_index::vec::{Idx, IndexVec};
use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin}; use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin};
use rustc_middle::ty::fold::TypeFoldable; 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 rustc_middle::ty::{InternalSubsts, SubstsRef};
use std::iter; use std::iter;
@ -241,7 +243,7 @@ impl<'tcx> UniversalRegions<'tcx> {
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
closure_substs: SubstsRef<'tcx>, closure_substs: SubstsRef<'tcx>,
expected_num_vars: usize, expected_num_vars: usize,
typeck_root_def_id: DefId, closure_def_id: LocalDefId,
) -> IndexVec<RegionVid, ty::Region<'tcx>> { ) -> IndexVec<RegionVid, ty::Region<'tcx>> {
let mut region_mapping = IndexVec::with_capacity(expected_num_vars); let mut region_mapping = IndexVec::with_capacity(expected_num_vars);
region_mapping.push(tcx.lifetimes.re_static); region_mapping.push(tcx.lifetimes.re_static);
@ -249,7 +251,7 @@ impl<'tcx> UniversalRegions<'tcx> {
region_mapping.push(fr); 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); region_mapping.push(r);
}); });
@ -339,9 +341,8 @@ impl<'tcx> UniversalRegions<'tcx> {
// tests, and the resulting print-outs include def-ids // tests, and the resulting print-outs include def-ids
// and other things that are not stable across tests! // and other things that are not stable across tests!
// So we just include the region-vid. Annoying. // 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_in_recursive_scope(tcx, def_id.expect_local(), |r| {
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)));
err.note(&format!("late-bound region is {:?}", self.to_region_vid(r),));
}); });
} }
DefiningTy::Generator(def_id, substs, _) => { DefiningTy::Generator(def_id, substs, _) => {
@ -354,9 +355,8 @@ impl<'tcx> UniversalRegions<'tcx> {
// FIXME: As above, we'd like to print out the region // FIXME: As above, we'd like to print out the region
// `r` but doing so is not stable across architectures // `r` but doing so is not stable across architectures
// and so forth. // and so forth.
let typeck_root_def_id = tcx.typeck_root_def_id(def_id); for_each_late_bound_region_in_recursive_scope(tcx, def_id.expect_local(), |r| {
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)));
err.note(&format!("late-bound region is {:?}", self.to_region_vid(r),));
}); });
} }
DefiningTy::FnDef(def_id, substs) => { DefiningTy::FnDef(def_id, substs) => {
@ -421,13 +421,24 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
first_extern_index first_extern_index
} else { } else {
// If this is a closure, generator, or inline-const, then the late-bound regions from the enclosing // 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): // to the closure c (although it is local to the fn foo):
// fn foo<'a>() { // fn foo<'a>() {
// let c = || { let x: &'a u32 = ...; } // let c = || { let x: &'a u32 = ...; }
// } // }
self.infcx for_each_late_bound_region_in_recursive_scope(
.replace_late_bound_regions_with_nll_infer_vars(self.mir_def.did, &mut indices); 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 // Any regions created during the execution of `defining_ty` or during the above
// late-bound region replacement are all considered 'extern' regions // late-bound region replacement are all considered 'extern' regions
self.infcx.num_region_vars() self.infcx.num_region_vars()
@ -444,12 +455,16 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
bound_inputs_and_output, bound_inputs_and_output,
&mut indices, &mut indices,
); );
// Converse of above, if this is a function then the late-bound regions declared on its // Converse of above, if this is a function/closure then the late-bound regions declared on its
// signature are local to the fn. // signature are local.
if self.mir_def.did.to_def_id() == typeck_root_def_id { for_each_late_bound_region_in_item(self.infcx.tcx, self.mir_def.did, |r| {
self.infcx debug!(?r);
.replace_late_bound_regions_with_nll_infer_vars(self.mir_def.did, &mut indices); 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) = let (unnormalized_output_ty, mut unnormalized_input_tys) =
inputs_and_output.split_last().unwrap(); 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 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 identity_substs = InternalSubsts::identity_for_item(tcx, typeck_root_def_id);
let fr_substs = match defining_ty { let fr_substs = match defining_ty {
DefiningTy::Closure(_, ref substs) DefiningTy::Closure(_, substs)
| DefiningTy::Generator(_, ref substs, _) | DefiningTy::Generator(_, substs, _)
| DefiningTy::InlineConst(_, ref substs) => { | DefiningTy::InlineConst(_, substs) => {
// In the case of closures, we rely on the fact that // In the case of closures, we rely on the fact that
// the first N elements in the ClosureSubsts are // the first N elements in the ClosureSubsts are
// inherited from the `typeck_root_def_id`. // inherited from the `typeck_root_def_id`.
@ -692,7 +707,13 @@ trait InferCtxtExt<'tcx> {
where where
T: TypeFoldable<'tcx>; 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, &self,
mir_def_id: LocalDefId, mir_def_id: LocalDefId,
indices: &mut UniversalRegionIndices<'tcx>, 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 /// set of late-bound regions and checks for any that we have not yet seen, adding them to the
/// inputs vector. /// inputs vector.
#[instrument(skip(self, indices))] #[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, &self,
mir_def_id: LocalDefId, mir_def_id: LocalDefId,
indices: &mut UniversalRegionIndices<'tcx>, 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_in_recursive_scope(self.tcx, mir_def_id, |r| {
for_each_late_bound_region_defined_on(self.tcx, typeck_root_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); debug!(?r);
if !indices.indices.contains_key(&r) { if !indices.indices.contains_key(&r) {
let region_vid = self.next_nll_region_var(FR); 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 /// Iterates over the late-bound regions defined on `mir_def_id` and all of its
/// invokes `f` with the liberated form of each one. /// parents, up to the typeck root, and invokes `f` with the liberated form
fn for_each_late_bound_region_defined_on<'tcx>( /// of each one.
fn for_each_late_bound_region_in_recursive_scope<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
fn_def_id: DefId, mut mir_def_id: LocalDefId,
mut f: impl FnMut(ty::Region<'tcx>), mut f: impl FnMut(ty::Region<'tcx>),
) { ) {
if let Some(late_bounds) = tcx.is_late_bound_map(fn_def_id.expect_local()) { let typeck_root_def_id = tcx.typeck_root_def_id(mir_def_id.to_def_id());
for &region_def_id in late_bounds.iter() {
let name = tcx.item_name(region_def_id.to_def_id()); // Walk up the tree, collecting late-bound regions until we hit the typeck root
let liberated_region = tcx.mk_region(ty::ReFree(ty::FreeRegion { loop {
scope: fn_def_id, for_each_late_bound_region_in_item(tcx, mir_def_id, &mut f);
bound_region: ty::BoundRegionKind::BrNamed(region_def_id.to_def_id(), name),
})); if mir_def_id.to_def_id() == typeck_root_def_id {
f(liberated_region); 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);
}
}

View File

@ -1,3 +1,5 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::fx::FxHashSet;
use rustc_middle::mir::visit::{PlaceContext, Visitor}; use rustc_middle::mir::visit::{PlaceContext, Visitor};
use rustc_middle::mir::{ use rustc_middle::mir::{

View File

@ -23,5 +23,5 @@ rustc_session = { path = "../rustc_session" }
rustc_span = { path = "../rustc_span" } rustc_span = { path = "../rustc_span" }
rustc_target = { path = "../rustc_target" } rustc_target = { path = "../rustc_target" }
smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
thin-vec = "0.2.8" thin-vec = "0.2.9"
tracing = "0.1" tracing = "0.1"

View 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)
}

View File

@ -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 // If it can't possibly expand to a string, provide diagnostics here to include other
// things it could have been. // things it could have been.
match template.kind { 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(..) => {} ast::ExprKind::MacCall(..) => {}
_ => { _ => {
let errstr = if is_global_asm { 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(); let template_snippet = ecx.source_map().span_to_snippet(template_sp).ok();
template_strs.push(( template_strs.push((
template_str, template_str,
template_snippet.as_ref().map(|s| Symbol::intern(s)), template_snippet.as_deref().map(Symbol::intern),
template_sp, template_sp,
)); ));
let template_str = template_str.as_str(); let template_str = template_str.as_str();

Some files were not shown because too many files have changed in this diff Show More