dependencies = [
"lazy_static",
"memchr",
- "regex-automata",
+ "regex-automata 0.1.10",
]
[[package]]
dependencies = [
"memchr",
"once_cell",
- "regex-automata",
+ "regex-automata 0.1.10",
"serde",
]
"glob",
"hex 0.4.2",
"home",
+ "http-auth",
"humantime 2.0.1",
"ignore",
"im-rc",
[[package]]
name = "cargo-credential"
-version = "0.1.0"
+version = "0.2.0"
[[package]]
name = "cargo-credential-1password"
-version = "0.1.0"
+version = "0.2.0"
dependencies = [
"cargo-credential",
"serde",
[[package]]
name = "cargo-credential-macos-keychain"
-version = "0.1.0"
+version = "0.2.0"
dependencies = [
"cargo-credential",
"security-framework",
[[package]]
name = "cargo-credential-wincred"
-version = "0.1.0"
+version = "0.2.0"
dependencies = [
"cargo-credential",
"winapi",
"syn",
]
+[[package]]
+name = "http-auth"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c0b40b39d66c28829a0cf4d09f7e139ff8201f7500a5083732848ed3b4b4d850"
+dependencies = [
+ "memchr",
+]
+
[[package]]
name = "humantime"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c1ad908cc71012b7bea4d0c53ba96a8cba9962f048fa68d143376143d863b7a"
+[[package]]
+name = "icu_list"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c40218275f081c4493f190357c5395647b06734c2dc3dcb41cc099a0f60168b1"
+dependencies = [
+ "displaydoc",
+ "icu_locid",
+ "icu_provider",
+ "regex-automata 0.2.0",
+ "writeable",
+ "zerovec",
+]
+
+[[package]]
+name = "icu_locid"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "34b3de5d99a0e275fe6193b9586dbf37364daebc0d39c89b5cf8376a53b789e8"
+dependencies = [
+ "displaydoc",
+ "litemap",
+ "tinystr",
+ "writeable",
+ "zerovec",
+]
+
+[[package]]
+name = "icu_provider"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2f911086e3c521a8a824d4f8bfd87769645ced2f07ff913b521c0d793be07100"
+dependencies = [
+ "displaydoc",
+ "icu_locid",
+ "icu_provider_macros",
+ "stable_deref_trait",
+ "writeable",
+ "yoke",
+ "zerofrom",
+ "zerovec",
+]
+
+[[package]]
+name = "icu_provider_adapters"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "980c71d8a91b246ebbb97847178a4b816eea39d1d550c70ee566384555bb6545"
+dependencies = [
+ "icu_locid",
+ "icu_provider",
+ "tinystr",
+ "yoke",
+ "zerovec",
+]
+
+[[package]]
+name = "icu_provider_macros"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "38cf6f5b65cf81f0b4298da647101acbfe6ae0e25263f92bd7a22597e9d6d606"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
[[package]]
name = "idna"
version = "0.2.0"
"walkdir",
]
+[[package]]
+name = "litemap"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f34a3f4798fac63fb48cf277eefa38f94d3443baff555bb98e4f56bc9092368e"
+
[[package]]
name = "lld-wrapper"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558"
dependencies = [
- "regex-automata",
+ "regex-automata 0.1.10",
]
[[package]]
"regex",
"rustc-workspace-hack",
"rustc_version",
- "shell-escape",
"smallvec",
"ui_test",
]
"regex-syntax",
]
+[[package]]
+name = "regex-automata"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e9368763f5a9b804326f3af749e16f9abf378d227bcdee7634b13d8f17793782"
+dependencies = [
+ "memchr",
+]
+
[[package]]
name = "regex-syntax"
version = "0.6.26"
"rustc_span",
]
+[[package]]
+name = "rustc_baked_icu_data"
+version = "0.0.0"
+dependencies = [
+ "icu_list",
+ "icu_locid",
+ "icu_provider",
+ "icu_provider_adapters",
+ "litemap",
+ "zerovec",
+]
+
[[package]]
name = "rustc_borrowck"
version = "0.0.0"
name = "rustc_const_eval"
version = "0.0.0"
dependencies = [
+ "either",
"rustc_apfloat",
"rustc_ast",
"rustc_attr",
dependencies = [
"fluent-bundle",
"fluent-syntax",
+ "icu_list",
+ "icu_locid",
+ "icu_provider_adapters",
"intl-memoizer",
+ "rustc_baked_icu_data",
"rustc_data_structures",
"rustc_macros",
"rustc_serialize",
"rustc_span",
"tracing",
"unic-langid",
+ "writeable",
]
[[package]]
version = "0.0.0"
dependencies = [
"annotate-snippets",
- "atty",
"rustc_ast",
"rustc_ast_pretty",
"rustc_data_structures",
"rustc_session",
"rustc_span",
"smallvec",
+ "thin-vec",
"tracing",
]
name = "rustc_log"
version = "0.0.0"
dependencies = [
- "atty",
"rustc_span",
"tracing",
"tracing-subscriber",
name = "rustc_mir_build"
version = "0.0.0"
dependencies = [
+ "either",
"rustc_apfloat",
"rustc_arena",
"rustc_ast",
version = "0.0.0"
dependencies = [
"coverage_test_macros",
+ "either",
"itertools",
"rustc_ast",
"rustc_attr",
"rustc_macros",
"rustc_session",
"rustc_span",
+ "thin-vec",
"tracing",
"unicode-normalization",
"unicode-width",
"rustc_feature",
"rustc_hir",
"rustc_index",
+ "rustc_macros",
"rustc_metadata",
"rustc_middle",
"rustc_query_system",
"rustc_session",
"rustc_span",
"smallvec",
+ "thin-vec",
"tracing",
]
dependencies = [
"arrayvec",
"askama",
- "atty",
"expect-test",
"itertools",
"minifier",
checksum = "f8aeafdfd935e4a7fe16a91ab711fa52d54df84f9c8f7ca5837a9d1d902ef4c2"
dependencies = [
"displaydoc",
+ "zerovec",
]
[[package]]
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5"
+[[package]]
+name = "writeable"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f8e6ab4f5da1b24daf2c590cfac801bacb27b15b4f050e84eb60149ea726f06b"
+
[[package]]
name = "xattr"
version = "0.2.2"
dependencies = [
"winapi",
]
+
+[[package]]
+name = "yoke"
+version = "0.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1fe1d55ca72c32d573bfbd5cb2f0ca65a497854c44762957a6d3da96041a5184"
+dependencies = [
+ "serde",
+ "stable_deref_trait",
+ "yoke-derive",
+ "zerofrom",
+]
+
+[[package]]
+name = "yoke-derive"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1346e4cd025ae818b88566eac7eb65ab33a994ea55f355c86889af2e7e56b14e"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ "synstructure",
+]
+
+[[package]]
+name = "zerofrom"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "79e9355fccf72b04b7deaa99ce7a0f6630530acf34045391b74460fcd714de54"
+dependencies = [
+ "zerofrom-derive",
+]
+
+[[package]]
+name = "zerofrom-derive"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2e8aa86add9ddbd2409c1ed01e033cd457d79b1b1229b64922c25095c595e829"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ "synstructure",
+]
+
+[[package]]
+name = "zerovec"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b9d919a74c17749ccb17beaf6405562e413cd94e98ba52ca1e64bbe7eefbd8b8"
+dependencies = [
+ "yoke",
+ "zerofrom",
+ "zerovec-derive",
+]
+
+[[package]]
+name = "zerovec-derive"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "490e5f878c2856225e884c35927e7ea6db3c24cdb7229b72542c7526ad7ed49e"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ "synstructure",
+]
use std::convert::TryFrom;
use std::fmt;
use std::mem;
-use thin_vec::ThinVec;
+use thin_vec::{thin_vec, ThinVec};
/// A "Label" is an identifier of some point in sources,
/// e.g. in the following code:
pub span: Span,
/// The segments in the path: the things separated by `::`.
/// Global paths begin with `kw::PathRoot`.
- pub segments: Vec<PathSegment>,
+ pub segments: ThinVec<PathSegment>,
pub tokens: Option<LazyAttrTokenStream>,
}
// Convert a span and an identifier to the corresponding
// one-segment path.
pub fn from_ident(ident: Ident) -> Path {
- Path { segments: vec![PathSegment::from_ident(ident)], span: ident.span, tokens: None }
+ Path { segments: thin_vec![PathSegment::from_ident(ident)], span: ident.span, tokens: None }
}
pub fn is_global(&self) -> bool {
/// A struct or struct variant pattern (e.g., `Variant {x, y, ..}`).
/// The `bool` is `true` in the presence of a `..`.
- Struct(Option<QSelf>, Path, Vec<PatField>, /* recovered */ bool),
+ Struct(Option<P<QSelf>>, Path, Vec<PatField>, /* recovered */ bool),
/// A tuple struct/variant pattern (`Variant(x, y, .., z)`).
- TupleStruct(Option<QSelf>, Path, Vec<P<Pat>>),
+ TupleStruct(Option<P<QSelf>>, Path, Vec<P<Pat>>),
/// An or-pattern `A | B | C`.
/// Invariant: `pats.len() >= 2`.
/// Unqualified path patterns `A::B::C` can legally refer to variants, structs, constants
/// or associated constants. Qualified path patterns `<A>::B::C`/`<A as Trait>::B::C` can
/// only legally refer to associated constants.
- Path(Option<QSelf>, Path),
+ Path(Option<P<QSelf>>, Path),
/// A tuple pattern (`(a, b)`).
Tuple(Vec<P<Pat>>),
}
}
+#[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 argument block `|...|`.
+ pub fn_decl_span: Span,
+}
+
/// Limit types of a range (inclusive or exclusive)
#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug)]
pub enum RangeLimits {
Closed,
}
+/// A method call (e.g. `x.foo::<Bar, Baz>(a, b, c)`).
+#[derive(Clone, Encodable, Decodable, Debug)]
+pub struct MethodCall {
+ /// The method name and its generic arguments, e.g. `foo::<Bar, Baz>`.
+ pub seg: PathSegment,
+ /// The receiver, e.g. `x`.
+ pub receiver: P<Expr>,
+ /// The arguments, e.g. `a, b, c`.
+ pub args: Vec<P<Expr>>,
+ /// The span of the function, without the dot and receiver e.g. `foo::<Bar,
+ /// Baz>(a, b, c)`.
+ pub span: Span,
+}
+
#[derive(Clone, Encodable, Decodable, Debug)]
pub enum StructRest {
/// `..x`.
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct StructExpr {
- pub qself: Option<QSelf>,
+ pub qself: Option<P<QSelf>>,
pub path: Path,
pub fields: Vec<ExprField>,
pub rest: StructRest,
/// This also represents calling the constructor of
/// tuple-like ADTs such as tuple structs and enum variants.
Call(P<Expr>, Vec<P<Expr>>),
- /// A method call (`x.foo::<'static, Bar, Baz>(a, b, c, d)`)
- ///
- /// The `PathSegment` represents the method name and its generic arguments
- /// (within the angle brackets).
- /// The standalone `Expr` is the receiver expression.
- /// The vector of `Expr` is the arguments.
- /// `x.foo::<Bar, Baz>(a, b, c, d)` is represented as
- /// `ExprKind::MethodCall(PathSegment { foo, [Bar, Baz] }, x, [a, b, c, d])`.
- /// This `Span` is the span of the function, without the dot and receiver
- /// (e.g. `foo(a, b)` in `x.foo(a, b)`
- MethodCall(PathSegment, P<Expr>, Vec<P<Expr>>, Span),
+ /// A method call (e.g. `x.foo::<Bar, Baz>(a, b, c)`).
+ MethodCall(Box<MethodCall>),
/// A tuple (e.g., `(a, b, c, d)`).
Tup(Vec<P<Expr>>),
/// A binary operation (e.g., `a + b`, `a * b`).
/// A `match` block.
Match(P<Expr>, Vec<Arm>),
/// A closure (e.g., `move |a, b, c| a + b + c`).
- ///
- /// The final span is the span of the argument block `|...|`.
- Closure(ClosureBinder, CaptureBy, Async, Movability, P<FnDecl>, P<Expr>, Span),
+ Closure(Box<Closure>),
/// A block (`'label: { ... }`).
Block(P<Block>, Option<Label>),
/// An async block (`async move { ... }`).
/// parameters (e.g., `foo::bar::<baz>`).
///
/// Optionally "qualified" (e.g., `<Vec<T> as SomeTrait>::SomeType`).
- Path(Option<QSelf>, Path),
+ Path(Option<P<QSelf>>, Path),
/// A referencing operation (`&a`, `&mut a`, `&raw const a` or `&raw mut a`).
AddrOf(BorrowKind, Mutability, P<Expr>),
/// "qualified", e.g., `<Vec<T> as SomeTrait>::SomeType`.
///
/// Type parameters are stored in the `Path` itself.
- Path(Option<QSelf>, Path),
+ Path(Option<P<QSelf>>, Path),
/// A trait object type `Bound1 + Bound2 + Bound3`
/// where `Bound` is a trait or a lifetime.
TraitObject(GenericBounds, TraitObjectSyntax),
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct InlineAsmSym {
pub id: NodeId,
- pub qself: Option<QSelf>,
+ pub qself: Option<P<QSelf>>,
pub path: Path,
}
static_assert_size!(AssocItemKind, 32);
static_assert_size!(Attribute, 32);
static_assert_size!(Block, 48);
- static_assert_size!(Expr, 104);
- static_assert_size!(ExprKind, 72);
+ static_assert_size!(Expr, 72);
+ static_assert_size!(ExprKind, 40);
static_assert_size!(Fn, 184);
static_assert_size!(ForeignItem, 96);
static_assert_size!(ForeignItemKind, 24);
static_assert_size!(GenericArg, 24);
- static_assert_size!(GenericBound, 88);
+ static_assert_size!(GenericBound, 72);
static_assert_size!(Generics, 72);
- static_assert_size!(Impl, 200);
+ static_assert_size!(Impl, 184);
static_assert_size!(Item, 184);
static_assert_size!(ItemKind, 112);
static_assert_size!(Lit, 48);
static_assert_size!(LitKind, 24);
static_assert_size!(Local, 72);
static_assert_size!(Param, 40);
- static_assert_size!(Pat, 120);
- static_assert_size!(Path, 40);
+ static_assert_size!(Pat, 88);
+ static_assert_size!(Path, 24);
static_assert_size!(PathSegment, 24);
- static_assert_size!(PatKind, 96);
+ static_assert_size!(PatKind, 64);
static_assert_size!(Stmt, 32);
static_assert_size!(StmtKind, 16);
- static_assert_size!(Ty, 96);
- static_assert_size!(TyKind, 72);
+ static_assert_size!(Ty, 64);
+ static_assert_size!(TyKind, 40);
// tidy-alphabetical-end
}
use crate::tokenstream::{DelimSpan, Spacing, TokenTree};
use crate::tokenstream::{LazyAttrTokenStream, TokenStream};
use crate::util::comments;
-
use rustc_data_structures::sync::WorkerLocal;
use rustc_index::bit_set::GrowableBitSet;
use rustc_span::source_map::BytePos;
use rustc_span::symbol::{sym, Ident, Symbol};
use rustc_span::Span;
-
use std::cell::Cell;
use std::iter;
#[cfg(debug_assertions)]
use std::ops::BitXor;
#[cfg(debug_assertions)]
use std::sync::atomic::{AtomicU32, Ordering};
+use thin_vec::thin_vec;
pub struct MarkedAttrs(GrowableBitSet<AttrId>);
tokens.peek()
{
tokens.next();
- vec![PathSegment::from_ident(Ident::new(name, span))]
+ thin_vec![PathSegment::from_ident(Ident::new(name, span))]
} else {
break 'arm Path::from_ident(Ident::new(name, span));
}
} else {
- vec![PathSegment::path_root(span)]
+ thin_vec![PathSegment::path_root(span)]
};
loop {
if let Some(TokenTree::Token(Token { kind: token::Ident(name, _), span }, _)) =
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);
}
visit_lazy_tts(tokens, vis);
}
-pub fn noop_visit_qself<T: MutVisitor>(qself: &mut Option<QSelf>, vis: &mut T) {
- visit_opt(qself, |QSelf { ty, path_span, position: _ }| {
+pub fn noop_visit_qself<T: MutVisitor>(qself: &mut Option<P<QSelf>>, vis: &mut T) {
+ visit_opt(qself, |qself| {
+ let QSelf { ty, path_span, position: _ } = &mut **qself;
vis.visit_ty(ty);
vis.visit_span(path_span);
})
vis.visit_expr(f);
visit_exprs(args, vis);
}
- ExprKind::MethodCall(PathSegment { ident, id, args }, receiver, exprs, span) => {
+ ExprKind::MethodCall(box MethodCall {
+ seg: PathSegment { ident, id, args: seg_args },
+ receiver,
+ args: call_args,
+ span,
+ }) => {
vis.visit_ident(ident);
vis.visit_id(id);
- visit_opt(args, |args| vis.visit_generic_args(args));
+ visit_opt(seg_args, |args| vis.visit_generic_args(args));
vis.visit_method_receiver_expr(receiver);
- visit_exprs(exprs, vis);
+ visit_exprs(call_args, vis);
vis.visit_span(span);
}
ExprKind::Binary(_binop, lhs, rhs) => {
vis.visit_expr(expr);
arms.flat_map_in_place(|arm| vis.flat_map_arm(arm));
}
- ExprKind::Closure(binder, _capture_by, asyncness, _movability, decl, body, span) => {
+ ExprKind::Closure(box Closure {
+ binder,
+ capture_clause: _,
+ asyncness,
+ movability: _,
+ fn_decl,
+ body,
+ fn_decl_span,
+ }) => {
vis.visit_closure_binder(binder);
vis.visit_asyncness(asyncness);
- vis.visit_fn_decl(decl);
+ vis.visit_fn_decl(fn_decl);
vis.visit_expr(body);
- vis.visit_span(span);
+ vis.visit_span(fn_decl_span);
}
ExprKind::Block(blk, label) => {
vis.visit_block(blk);
| Binary(_, _, e)
| Box(e)
| Break(_, Some(e))
- | Closure(.., e, _)
| Let(_, e, _)
| Range(_, Some(e), _)
| Ret(Some(e))
| Yield(Some(e)) => {
expr = e;
}
+ Closure(closure) => {
+ expr = &closure.body;
+ }
Async(..) | Block(..) | ForLoop(..) | If(..) | Loop(..) | Match(..) | Struct(..)
| TryBlock(..) | While(..) => break Some(expr),
_ => break None,
contains_exterior_struct_lit(&x)
}
- ast::ExprKind::MethodCall(_, ref receiver, _, _) => {
+ ast::ExprKind::MethodCall(box ast::MethodCall { ref receiver, .. }) => {
// X { y: 1 }.bar(...)
contains_exterior_struct_lit(&receiver)
}
visitor.visit_expr(callee_expression);
walk_list!(visitor, visit_expr, arguments);
}
- ExprKind::MethodCall(ref segment, ref receiver, ref arguments, _span) => {
- visitor.visit_path_segment(segment);
+ ExprKind::MethodCall(box MethodCall { ref seg, ref receiver, ref args, span: _ }) => {
+ visitor.visit_path_segment(seg);
visitor.visit_expr(receiver);
- walk_list!(visitor, visit_expr, arguments);
+ walk_list!(visitor, visit_expr, args);
}
ExprKind::Binary(_, ref left_expression, ref right_expression) => {
visitor.visit_expr(left_expression);
visitor.visit_expr(subexpression);
walk_list!(visitor, visit_arm, arms);
}
- ExprKind::Closure(ref binder, _, _, _, ref decl, ref body, _decl_span) => {
- visitor.visit_fn(FnKind::Closure(binder, decl, body), expression.span, expression.id)
+ ExprKind::Closure(box Closure {
+ ref binder,
+ capture_clause: _,
+ asyncness: _,
+ movability: _,
+ ref fn_decl,
+ ref body,
+ fn_decl_span: _,
+ }) => {
+ visitor.visit_fn(FnKind::Closure(binder, fn_decl, body), expression.span, expression.id)
}
ExprKind::Block(ref block, ref opt_label) => {
walk_list!(visitor, visit_label, opt_label);
hir::ExprKind::Call(f, self.lower_exprs(args))
}
}
- ExprKind::MethodCall(ref seg, ref receiver, ref args, span) => {
+ ExprKind::MethodCall(box MethodCall { ref seg, ref receiver, ref args, span }) => {
let hir_seg = self.arena.alloc(self.lower_path_segment(
e.span,
seg,
};
self.lower_expr_await(dot_await_span, expr)
}
- ExprKind::Closure(
+ ExprKind::Closure(box Closure {
ref binder,
capture_clause,
asyncness,
movability,
- ref decl,
+ ref fn_decl,
ref body,
fn_decl_span,
- ) => {
+ }) => {
if let Async::Yes { closure_id, .. } = asyncness {
self.lower_expr_async_closure(
binder,
capture_clause,
e.id,
closure_id,
- decl,
+ fn_decl,
body,
fn_decl_span,
)
capture_clause,
e.id,
movability,
- decl,
+ fn_decl,
body,
fn_decl_span,
)
fn extract_tuple_struct_path<'a>(
&mut self,
expr: &'a Expr,
- ) -> Option<(&'a Option<QSelf>, &'a Path)> {
+ ) -> Option<(&'a Option<AstP<QSelf>>, &'a Path)> {
if let ExprKind::Path(qself, path) = &expr.kind {
// Does the path resolve to something disallowed in a tuple struct/variant pattern?
if let Some(partial_res) = self.resolver.get_partial_res(expr.id) {
fn extract_unit_struct_path<'a>(
&mut self,
expr: &'a Expr,
- ) -> Option<(&'a Option<QSelf>, &'a Path)> {
+ ) -> Option<(&'a Option<AstP<QSelf>>, &'a Path)> {
if let ExprKind::Path(qself, path) = &expr.kind {
// Does the path resolve to something disallowed in a unit struct/variant pattern?
if let Some(partial_res) = self.resolver.get_partial_res(expr.id) {
use rustc_span::{Span, Symbol};
use rustc_target::spec::abi;
use smallvec::{smallvec, SmallVec};
-
use std::iter;
+use thin_vec::ThinVec;
pub(super) struct ItemLowerer<'a, 'hir> {
pub(super) tcx: TyCtxt<'hir>,
ItemKind::ExternCrate(orig_name) => hir::ItemKind::ExternCrate(orig_name),
ItemKind::Use(ref use_tree) => {
// Start with an empty prefix.
- let prefix = Path { segments: vec![], span: use_tree.span, tokens: None };
+ let prefix = Path { segments: ThinVec::new(), span: use_tree.span, tokens: None };
self.lower_use_tree(use_tree, &prefix, id, vis_span, ident, attrs)
}
fn lower_path_ty(
&mut self,
t: &Ty,
- qself: &Option<QSelf>,
+ qself: &Option<ptr::P<QSelf>>,
path: &Path,
param_mode: ParamMode,
itctx: &ImplTraitContext,
pub(crate) fn lower_qpath(
&mut self,
id: NodeId,
- qself: &Option<QSelf>,
+ qself: &Option<ptr::P<QSelf>>,
p: &Path,
param_mode: ParamMode,
itctx: &ImplTraitContext,
fn print_expr_struct(
&mut self,
- qself: &Option<ast::QSelf>,
+ qself: &Option<P<ast::QSelf>>,
path: &ast::Path,
fields: &[ast::ExprField],
rest: &ast::StructRest,
ast::ExprKind::Call(ref func, ref args) => {
self.print_expr_call(func, &args);
}
- ast::ExprKind::MethodCall(ref segment, ref receiver, ref args, _) => {
- self.print_expr_method_call(segment, &receiver, &args);
+ ast::ExprKind::MethodCall(box ast::MethodCall {
+ ref seg,
+ ref receiver,
+ ref args,
+ ..
+ }) => {
+ self.print_expr_method_call(seg, &receiver, &args);
}
ast::ExprKind::Binary(op, ref lhs, ref rhs) => {
self.print_expr_binary(op, lhs, rhs);
let empty = attrs.is_empty() && arms.is_empty();
self.bclose(expr.span, empty);
}
- ast::ExprKind::Closure(
+ ast::ExprKind::Closure(box ast::Closure {
ref binder,
capture_clause,
asyncness,
movability,
- ref decl,
+ ref fn_decl,
ref body,
- _,
- ) => {
+ fn_decl_span: _,
+ }) => {
self.print_closure_binder(binder);
self.print_movability(movability);
self.print_asyncness(asyncness);
self.print_capture_clause(capture_clause);
- self.print_fn_params_and_ret(decl, true);
+ self.print_fn_params_and_ret(fn_decl, true);
self.space();
self.print_expr(body);
self.end(); // need to close a box
--- /dev/null
+[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']
--- /dev/null
+// @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() })
+ }
+}
--- /dev/null
+// @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,
+ ])
+ },
+ )
+ },
+ };
--- /dev/null
+// @generated
+pub mod likelysubtags_v1;
+pub mod parents_v1;
+pub mod supplement;
--- /dev/null
+// @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,
+ ])
+ },
+ )
+ },
+};
--- /dev/null
+// @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,
+ ])
+ },
+ )
+ },
+ };
--- /dev/null
+// @generated
+pub mod co_v1;
--- /dev/null
+// @generated
+type DataStruct = <::icu_list::provider::AndListV1Marker as ::icu_provider::DataMarker>::Yokeable;
+pub static DATA: litemap::LiteMap<&str, &DataStruct, &[(&str, &DataStruct)]> =
+ litemap::LiteMap::from_sorted_store_unchecked(&[
+ ("en", EN),
+ ("es", ES),
+ ("fr", FR),
+ ("it", IT),
+ ("ja", JA),
+ ("pt", PT),
+ ("ru", RU),
+ ("tr", TR),
+ ("und", UND),
+ ("zh", ZH_ZH_HANS),
+ ("zh-Hans", ZH_ZH_HANS),
+ ("zh-Hant", ZH_HANT),
+ ]);
+static EN: &DataStruct = &::icu_list::provider::ListFormatterPatternsV1([
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", and ", 6u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" and ", 5u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", & ", 4u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" & ", 3u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+ },
+ special_case: None,
+ },
+]);
+static ES: &DataStruct = &::icu_list::provider::ListFormatterPatternsV1([
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" y ", 3u8)
+ },
+ special_case: Some(::icu_list::provider::SpecialCasePattern {
+ condition: unsafe {
+ ::icu_list::provider::StringMatcher::from_dfa_bytes_unchecked(&[
+ 114u8, 117u8, 115u8, 116u8, 45u8, 114u8, 101u8, 103u8, 101u8, 120u8, 45u8,
+ 97u8, 117u8, 116u8, 111u8, 109u8, 97u8, 116u8, 97u8, 45u8, 100u8, 102u8, 97u8,
+ 45u8, 115u8, 112u8, 97u8, 114u8, 115u8, 101u8, 0u8, 0u8, 255u8, 254u8, 0u8,
+ 0u8, 2u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8, 1u8, 0u8,
+ 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+ 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+ 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+ 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+ 0u8, 0u8, 0u8, 1u8, 2u8, 2u8, 2u8, 3u8, 4u8, 4u8, 5u8, 6u8, 7u8, 7u8, 7u8, 7u8,
+ 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8,
+ 7u8, 7u8, 7u8, 8u8, 9u8, 9u8, 9u8, 10u8, 11u8, 11u8, 12u8, 13u8, 14u8, 14u8,
+ 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8,
+ 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8,
+ 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 16u8, 16u8, 16u8,
+ 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8,
+ 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8,
+ 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8,
+ 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 18u8, 18u8, 19u8, 19u8, 19u8, 19u8, 19u8,
+ 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8,
+ 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 20u8,
+ 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 22u8,
+ 23u8, 23u8, 24u8, 25u8, 25u8, 25u8, 26u8, 27u8, 27u8, 27u8, 27u8, 27u8, 27u8,
+ 27u8, 27u8, 27u8, 27u8, 27u8, 40u8, 1u8, 0u8, 0u8, 1u8, 0u8, 0u8, 0u8, 0u8,
+ 0u8, 0u8, 0u8, 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 128u8,
+ 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 5u8,
+ 0u8, 5u8, 5u8, 6u8, 6u8, 12u8, 12u8, 13u8, 13u8, 0u8, 0u8, 83u8, 0u8, 0u8, 0u8,
+ 68u8, 0u8, 0u8, 0u8, 83u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+ 0u8, 0u8, 2u8, 0u8, 0u8, 27u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, 18u8, 0u8, 0u8,
+ 0u8, 0u8, 3u8, 0u8, 6u8, 6u8, 13u8, 13u8, 0u8, 0u8, 104u8, 0u8, 0u8, 0u8,
+ 104u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8, 2u8, 2u8,
+ 4u8, 7u8, 9u8, 9u8, 11u8, 14u8, 19u8, 19u8, 20u8, 20u8, 21u8, 21u8, 22u8, 22u8,
+ 23u8, 23u8, 24u8, 24u8, 25u8, 25u8, 26u8, 26u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8,
+ 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8,
+ 0u8, 191u8, 0u8, 0u8, 0u8, 206u8, 0u8, 0u8, 0u8, 221u8, 0u8, 0u8, 0u8, 236u8,
+ 0u8, 0u8, 0u8, 221u8, 0u8, 0u8, 0u8, 251u8, 0u8, 0u8, 0u8, 10u8, 1u8, 0u8, 0u8,
+ 25u8, 1u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8,
+ 68u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 17u8, 17u8, 0u8, 0u8,
+ 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8,
+ 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 16u8, 0u8, 0u8,
+ 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 16u8, 17u8, 0u8, 0u8,
+ 221u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8,
+ 221u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 15u8, 0u8, 0u8,
+ 221u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 4u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+ 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8,
+ 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 9u8, 0u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8,
+ 18u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8,
+ 0u8, 35u8, 0u8, 0u8, 0u8,
+ ])
+ },
+ pattern: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" e ", 3u8)
+ },
+ }),
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" y ", 3u8)
+ },
+ special_case: Some(::icu_list::provider::SpecialCasePattern {
+ condition: unsafe {
+ ::icu_list::provider::StringMatcher::from_dfa_bytes_unchecked(&[
+ 114u8, 117u8, 115u8, 116u8, 45u8, 114u8, 101u8, 103u8, 101u8, 120u8, 45u8,
+ 97u8, 117u8, 116u8, 111u8, 109u8, 97u8, 116u8, 97u8, 45u8, 100u8, 102u8, 97u8,
+ 45u8, 115u8, 112u8, 97u8, 114u8, 115u8, 101u8, 0u8, 0u8, 255u8, 254u8, 0u8,
+ 0u8, 2u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8, 1u8, 0u8,
+ 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+ 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+ 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+ 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+ 0u8, 0u8, 0u8, 1u8, 2u8, 2u8, 2u8, 3u8, 4u8, 4u8, 5u8, 6u8, 7u8, 7u8, 7u8, 7u8,
+ 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8,
+ 7u8, 7u8, 7u8, 8u8, 9u8, 9u8, 9u8, 10u8, 11u8, 11u8, 12u8, 13u8, 14u8, 14u8,
+ 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8,
+ 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8,
+ 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 16u8, 16u8, 16u8,
+ 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8,
+ 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8,
+ 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8,
+ 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 18u8, 18u8, 19u8, 19u8, 19u8, 19u8, 19u8,
+ 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8,
+ 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 20u8,
+ 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 22u8,
+ 23u8, 23u8, 24u8, 25u8, 25u8, 25u8, 26u8, 27u8, 27u8, 27u8, 27u8, 27u8, 27u8,
+ 27u8, 27u8, 27u8, 27u8, 27u8, 40u8, 1u8, 0u8, 0u8, 1u8, 0u8, 0u8, 0u8, 0u8,
+ 0u8, 0u8, 0u8, 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 128u8,
+ 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 5u8,
+ 0u8, 5u8, 5u8, 6u8, 6u8, 12u8, 12u8, 13u8, 13u8, 0u8, 0u8, 83u8, 0u8, 0u8, 0u8,
+ 68u8, 0u8, 0u8, 0u8, 83u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+ 0u8, 0u8, 2u8, 0u8, 0u8, 27u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, 18u8, 0u8, 0u8,
+ 0u8, 0u8, 3u8, 0u8, 6u8, 6u8, 13u8, 13u8, 0u8, 0u8, 104u8, 0u8, 0u8, 0u8,
+ 104u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8, 2u8, 2u8,
+ 4u8, 7u8, 9u8, 9u8, 11u8, 14u8, 19u8, 19u8, 20u8, 20u8, 21u8, 21u8, 22u8, 22u8,
+ 23u8, 23u8, 24u8, 24u8, 25u8, 25u8, 26u8, 26u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8,
+ 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8,
+ 0u8, 191u8, 0u8, 0u8, 0u8, 206u8, 0u8, 0u8, 0u8, 221u8, 0u8, 0u8, 0u8, 236u8,
+ 0u8, 0u8, 0u8, 221u8, 0u8, 0u8, 0u8, 251u8, 0u8, 0u8, 0u8, 10u8, 1u8, 0u8, 0u8,
+ 25u8, 1u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8,
+ 68u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 17u8, 17u8, 0u8, 0u8,
+ 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8,
+ 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 16u8, 0u8, 0u8,
+ 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 16u8, 17u8, 0u8, 0u8,
+ 221u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8,
+ 221u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 15u8, 0u8, 0u8,
+ 221u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 4u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+ 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8,
+ 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 9u8, 0u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8,
+ 18u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8,
+ 0u8, 35u8, 0u8, 0u8, 0u8,
+ ])
+ },
+ pattern: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" e ", 3u8)
+ },
+ }),
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" y ", 3u8)
+ },
+ special_case: Some(::icu_list::provider::SpecialCasePattern {
+ condition: unsafe {
+ ::icu_list::provider::StringMatcher::from_dfa_bytes_unchecked(&[
+ 114u8, 117u8, 115u8, 116u8, 45u8, 114u8, 101u8, 103u8, 101u8, 120u8, 45u8,
+ 97u8, 117u8, 116u8, 111u8, 109u8, 97u8, 116u8, 97u8, 45u8, 100u8, 102u8, 97u8,
+ 45u8, 115u8, 112u8, 97u8, 114u8, 115u8, 101u8, 0u8, 0u8, 255u8, 254u8, 0u8,
+ 0u8, 2u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8, 1u8, 0u8,
+ 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+ 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+ 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+ 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+ 0u8, 0u8, 0u8, 1u8, 2u8, 2u8, 2u8, 3u8, 4u8, 4u8, 5u8, 6u8, 7u8, 7u8, 7u8, 7u8,
+ 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8,
+ 7u8, 7u8, 7u8, 8u8, 9u8, 9u8, 9u8, 10u8, 11u8, 11u8, 12u8, 13u8, 14u8, 14u8,
+ 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8,
+ 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8,
+ 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 16u8, 16u8, 16u8,
+ 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8,
+ 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8,
+ 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8,
+ 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 18u8, 18u8, 19u8, 19u8, 19u8, 19u8, 19u8,
+ 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8,
+ 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 20u8,
+ 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 22u8,
+ 23u8, 23u8, 24u8, 25u8, 25u8, 25u8, 26u8, 27u8, 27u8, 27u8, 27u8, 27u8, 27u8,
+ 27u8, 27u8, 27u8, 27u8, 27u8, 40u8, 1u8, 0u8, 0u8, 1u8, 0u8, 0u8, 0u8, 0u8,
+ 0u8, 0u8, 0u8, 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 128u8,
+ 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 5u8,
+ 0u8, 5u8, 5u8, 6u8, 6u8, 12u8, 12u8, 13u8, 13u8, 0u8, 0u8, 83u8, 0u8, 0u8, 0u8,
+ 68u8, 0u8, 0u8, 0u8, 83u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+ 0u8, 0u8, 2u8, 0u8, 0u8, 27u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, 18u8, 0u8, 0u8,
+ 0u8, 0u8, 3u8, 0u8, 6u8, 6u8, 13u8, 13u8, 0u8, 0u8, 104u8, 0u8, 0u8, 0u8,
+ 104u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8, 2u8, 2u8,
+ 4u8, 7u8, 9u8, 9u8, 11u8, 14u8, 19u8, 19u8, 20u8, 20u8, 21u8, 21u8, 22u8, 22u8,
+ 23u8, 23u8, 24u8, 24u8, 25u8, 25u8, 26u8, 26u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8,
+ 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8,
+ 0u8, 191u8, 0u8, 0u8, 0u8, 206u8, 0u8, 0u8, 0u8, 221u8, 0u8, 0u8, 0u8, 236u8,
+ 0u8, 0u8, 0u8, 221u8, 0u8, 0u8, 0u8, 251u8, 0u8, 0u8, 0u8, 10u8, 1u8, 0u8, 0u8,
+ 25u8, 1u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8,
+ 68u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 17u8, 17u8, 0u8, 0u8,
+ 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8,
+ 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 16u8, 0u8, 0u8,
+ 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 16u8, 17u8, 0u8, 0u8,
+ 221u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8,
+ 221u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 15u8, 0u8, 0u8,
+ 221u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 4u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+ 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8,
+ 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 9u8, 0u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8,
+ 18u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8,
+ 0u8, 35u8, 0u8, 0u8, 0u8,
+ ])
+ },
+ pattern: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" e ", 3u8)
+ },
+ }),
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" y ", 3u8)
+ },
+ special_case: Some(::icu_list::provider::SpecialCasePattern {
+ condition: unsafe {
+ ::icu_list::provider::StringMatcher::from_dfa_bytes_unchecked(&[
+ 114u8, 117u8, 115u8, 116u8, 45u8, 114u8, 101u8, 103u8, 101u8, 120u8, 45u8,
+ 97u8, 117u8, 116u8, 111u8, 109u8, 97u8, 116u8, 97u8, 45u8, 100u8, 102u8, 97u8,
+ 45u8, 115u8, 112u8, 97u8, 114u8, 115u8, 101u8, 0u8, 0u8, 255u8, 254u8, 0u8,
+ 0u8, 2u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8, 1u8, 0u8,
+ 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+ 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+ 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+ 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+ 0u8, 0u8, 0u8, 1u8, 2u8, 2u8, 2u8, 3u8, 4u8, 4u8, 5u8, 6u8, 7u8, 7u8, 7u8, 7u8,
+ 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8,
+ 7u8, 7u8, 7u8, 8u8, 9u8, 9u8, 9u8, 10u8, 11u8, 11u8, 12u8, 13u8, 14u8, 14u8,
+ 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8,
+ 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8,
+ 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 16u8, 16u8, 16u8,
+ 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8,
+ 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8,
+ 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8,
+ 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 18u8, 18u8, 19u8, 19u8, 19u8, 19u8, 19u8,
+ 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8,
+ 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 20u8,
+ 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 22u8,
+ 23u8, 23u8, 24u8, 25u8, 25u8, 25u8, 26u8, 27u8, 27u8, 27u8, 27u8, 27u8, 27u8,
+ 27u8, 27u8, 27u8, 27u8, 27u8, 40u8, 1u8, 0u8, 0u8, 1u8, 0u8, 0u8, 0u8, 0u8,
+ 0u8, 0u8, 0u8, 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 128u8,
+ 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 5u8,
+ 0u8, 5u8, 5u8, 6u8, 6u8, 12u8, 12u8, 13u8, 13u8, 0u8, 0u8, 83u8, 0u8, 0u8, 0u8,
+ 68u8, 0u8, 0u8, 0u8, 83u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+ 0u8, 0u8, 2u8, 0u8, 0u8, 27u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, 18u8, 0u8, 0u8,
+ 0u8, 0u8, 3u8, 0u8, 6u8, 6u8, 13u8, 13u8, 0u8, 0u8, 104u8, 0u8, 0u8, 0u8,
+ 104u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8, 2u8, 2u8,
+ 4u8, 7u8, 9u8, 9u8, 11u8, 14u8, 19u8, 19u8, 20u8, 20u8, 21u8, 21u8, 22u8, 22u8,
+ 23u8, 23u8, 24u8, 24u8, 25u8, 25u8, 26u8, 26u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8,
+ 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8,
+ 0u8, 191u8, 0u8, 0u8, 0u8, 206u8, 0u8, 0u8, 0u8, 221u8, 0u8, 0u8, 0u8, 236u8,
+ 0u8, 0u8, 0u8, 221u8, 0u8, 0u8, 0u8, 251u8, 0u8, 0u8, 0u8, 10u8, 1u8, 0u8, 0u8,
+ 25u8, 1u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8,
+ 68u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 17u8, 17u8, 0u8, 0u8,
+ 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8,
+ 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 16u8, 0u8, 0u8,
+ 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 16u8, 17u8, 0u8, 0u8,
+ 221u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8,
+ 221u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 15u8, 0u8, 0u8,
+ 221u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 4u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+ 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8,
+ 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 9u8, 0u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8,
+ 18u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8,
+ 0u8, 35u8, 0u8, 0u8, 0u8,
+ ])
+ },
+ pattern: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" e ", 3u8)
+ },
+ }),
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" y ", 3u8)
+ },
+ special_case: Some(::icu_list::provider::SpecialCasePattern {
+ condition: unsafe {
+ ::icu_list::provider::StringMatcher::from_dfa_bytes_unchecked(&[
+ 114u8, 117u8, 115u8, 116u8, 45u8, 114u8, 101u8, 103u8, 101u8, 120u8, 45u8,
+ 97u8, 117u8, 116u8, 111u8, 109u8, 97u8, 116u8, 97u8, 45u8, 100u8, 102u8, 97u8,
+ 45u8, 115u8, 112u8, 97u8, 114u8, 115u8, 101u8, 0u8, 0u8, 255u8, 254u8, 0u8,
+ 0u8, 2u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8, 1u8, 0u8,
+ 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+ 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+ 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+ 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+ 0u8, 0u8, 0u8, 1u8, 2u8, 2u8, 2u8, 3u8, 4u8, 4u8, 5u8, 6u8, 7u8, 7u8, 7u8, 7u8,
+ 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8,
+ 7u8, 7u8, 7u8, 8u8, 9u8, 9u8, 9u8, 10u8, 11u8, 11u8, 12u8, 13u8, 14u8, 14u8,
+ 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8,
+ 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8,
+ 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 16u8, 16u8, 16u8,
+ 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8,
+ 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8,
+ 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8,
+ 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 18u8, 18u8, 19u8, 19u8, 19u8, 19u8, 19u8,
+ 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8,
+ 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 20u8,
+ 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 22u8,
+ 23u8, 23u8, 24u8, 25u8, 25u8, 25u8, 26u8, 27u8, 27u8, 27u8, 27u8, 27u8, 27u8,
+ 27u8, 27u8, 27u8, 27u8, 27u8, 40u8, 1u8, 0u8, 0u8, 1u8, 0u8, 0u8, 0u8, 0u8,
+ 0u8, 0u8, 0u8, 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 128u8,
+ 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 5u8,
+ 0u8, 5u8, 5u8, 6u8, 6u8, 12u8, 12u8, 13u8, 13u8, 0u8, 0u8, 83u8, 0u8, 0u8, 0u8,
+ 68u8, 0u8, 0u8, 0u8, 83u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+ 0u8, 0u8, 2u8, 0u8, 0u8, 27u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, 18u8, 0u8, 0u8,
+ 0u8, 0u8, 3u8, 0u8, 6u8, 6u8, 13u8, 13u8, 0u8, 0u8, 104u8, 0u8, 0u8, 0u8,
+ 104u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8, 2u8, 2u8,
+ 4u8, 7u8, 9u8, 9u8, 11u8, 14u8, 19u8, 19u8, 20u8, 20u8, 21u8, 21u8, 22u8, 22u8,
+ 23u8, 23u8, 24u8, 24u8, 25u8, 25u8, 26u8, 26u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8,
+ 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8,
+ 0u8, 191u8, 0u8, 0u8, 0u8, 206u8, 0u8, 0u8, 0u8, 221u8, 0u8, 0u8, 0u8, 236u8,
+ 0u8, 0u8, 0u8, 221u8, 0u8, 0u8, 0u8, 251u8, 0u8, 0u8, 0u8, 10u8, 1u8, 0u8, 0u8,
+ 25u8, 1u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8,
+ 68u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 17u8, 17u8, 0u8, 0u8,
+ 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8,
+ 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 16u8, 0u8, 0u8,
+ 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 16u8, 17u8, 0u8, 0u8,
+ 221u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8,
+ 221u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 15u8, 0u8, 0u8,
+ 221u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 4u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+ 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8,
+ 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 9u8, 0u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8,
+ 18u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8,
+ 0u8, 35u8, 0u8, 0u8, 0u8,
+ ])
+ },
+ pattern: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" e ", 3u8)
+ },
+ }),
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" y ", 3u8)
+ },
+ special_case: Some(::icu_list::provider::SpecialCasePattern {
+ condition: unsafe {
+ ::icu_list::provider::StringMatcher::from_dfa_bytes_unchecked(&[
+ 114u8, 117u8, 115u8, 116u8, 45u8, 114u8, 101u8, 103u8, 101u8, 120u8, 45u8,
+ 97u8, 117u8, 116u8, 111u8, 109u8, 97u8, 116u8, 97u8, 45u8, 100u8, 102u8, 97u8,
+ 45u8, 115u8, 112u8, 97u8, 114u8, 115u8, 101u8, 0u8, 0u8, 255u8, 254u8, 0u8,
+ 0u8, 2u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8, 1u8, 0u8,
+ 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+ 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+ 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+ 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+ 0u8, 0u8, 0u8, 1u8, 2u8, 2u8, 2u8, 3u8, 4u8, 4u8, 5u8, 6u8, 7u8, 7u8, 7u8, 7u8,
+ 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8,
+ 7u8, 7u8, 7u8, 8u8, 9u8, 9u8, 9u8, 10u8, 11u8, 11u8, 12u8, 13u8, 14u8, 14u8,
+ 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8,
+ 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8,
+ 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 16u8, 16u8, 16u8,
+ 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8,
+ 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8,
+ 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8,
+ 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 18u8, 18u8, 19u8, 19u8, 19u8, 19u8, 19u8,
+ 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8,
+ 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 20u8,
+ 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 22u8,
+ 23u8, 23u8, 24u8, 25u8, 25u8, 25u8, 26u8, 27u8, 27u8, 27u8, 27u8, 27u8, 27u8,
+ 27u8, 27u8, 27u8, 27u8, 27u8, 40u8, 1u8, 0u8, 0u8, 1u8, 0u8, 0u8, 0u8, 0u8,
+ 0u8, 0u8, 0u8, 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 128u8,
+ 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 5u8,
+ 0u8, 5u8, 5u8, 6u8, 6u8, 12u8, 12u8, 13u8, 13u8, 0u8, 0u8, 83u8, 0u8, 0u8, 0u8,
+ 68u8, 0u8, 0u8, 0u8, 83u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+ 0u8, 0u8, 2u8, 0u8, 0u8, 27u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, 18u8, 0u8, 0u8,
+ 0u8, 0u8, 3u8, 0u8, 6u8, 6u8, 13u8, 13u8, 0u8, 0u8, 104u8, 0u8, 0u8, 0u8,
+ 104u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8, 2u8, 2u8,
+ 4u8, 7u8, 9u8, 9u8, 11u8, 14u8, 19u8, 19u8, 20u8, 20u8, 21u8, 21u8, 22u8, 22u8,
+ 23u8, 23u8, 24u8, 24u8, 25u8, 25u8, 26u8, 26u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8,
+ 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8,
+ 0u8, 191u8, 0u8, 0u8, 0u8, 206u8, 0u8, 0u8, 0u8, 221u8, 0u8, 0u8, 0u8, 236u8,
+ 0u8, 0u8, 0u8, 221u8, 0u8, 0u8, 0u8, 251u8, 0u8, 0u8, 0u8, 10u8, 1u8, 0u8, 0u8,
+ 25u8, 1u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8,
+ 68u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 17u8, 17u8, 0u8, 0u8,
+ 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8,
+ 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 16u8, 0u8, 0u8,
+ 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 16u8, 17u8, 0u8, 0u8,
+ 221u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8,
+ 221u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 15u8, 0u8, 0u8,
+ 221u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 4u8, 0u8, 0u8, 0u8, 0u8, 0u8,
+ 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8,
+ 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 9u8, 0u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8,
+ 18u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8,
+ 0u8, 35u8, 0u8, 0u8, 0u8,
+ ])
+ },
+ pattern: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" e ", 3u8)
+ },
+ }),
+ },
+]);
+static FR: &DataStruct = &::icu_list::provider::ListFormatterPatternsV1([
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" et ", 4u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" et ", 4u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" et ", 4u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" et ", 4u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+ },
+ special_case: None,
+ },
+]);
+static IT: &DataStruct = &::icu_list::provider::ListFormatterPatternsV1([
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" e ", 3u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" e ", 3u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" e ", 3u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" e ", 3u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" e ", 3u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" e ", 3u8)
+ },
+ special_case: None,
+ },
+]);
+static JA: &DataStruct = &::icu_list::provider::ListFormatterPatternsV1([
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8)
+ },
+ special_case: None,
+ },
+]);
+static PT: &DataStruct = &::icu_list::provider::ListFormatterPatternsV1([
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" e ", 3u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" e ", 3u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" e ", 3u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" e ", 3u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+ },
+ special_case: None,
+ },
+]);
+static RU: &DataStruct = &::icu_list::provider::ListFormatterPatternsV1([
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" и ", 4u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" и ", 4u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" и ", 4u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" и ", 4u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+ },
+ special_case: None,
+ },
+]);
+static TR: &DataStruct = &::icu_list::provider::ListFormatterPatternsV1([
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" ve ", 4u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" ve ", 4u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" ve ", 4u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" ve ", 4u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+ },
+ special_case: None,
+ },
+]);
+static UND: &DataStruct = &::icu_list::provider::ListFormatterPatternsV1([
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8)
+ },
+ special_case: None,
+ },
+]);
+static ZH_HANT: &DataStruct = &::icu_list::provider::ListFormatterPatternsV1([
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("和", 3u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("和", 3u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("和", 3u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("和", 3u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("和", 3u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("和", 3u8)
+ },
+ special_case: None,
+ },
+]);
+static ZH_ZH_HANS: &DataStruct = &::icu_list::provider::ListFormatterPatternsV1([
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("和", 3u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("和", 3u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("和", 3u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("和", 3u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8)
+ },
+ special_case: None,
+ },
+ ::icu_list::provider::ConditionalListJoinerPattern {
+ default: unsafe {
+ ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8)
+ },
+ special_case: None,
+ },
+]);
--- /dev/null
+// @generated
+pub mod and_v1;
--- /dev/null
+// @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)
+ })?,
+ ))),
+ })
+ }
+}
--- /dev/null
+//! 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");
+}
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::graph::dominators::Dominators;
use rustc_data_structures::vec_map::VecMap;
-use rustc_errors::{Diagnostic, DiagnosticBuilder, ErrorGuaranteed};
+use rustc_errors::{Diagnostic, DiagnosticBuilder};
use rustc_hir as hir;
use rustc_hir::def_id::LocalDefId;
use rustc_index::bit_set::ChunkedBitSet;
}
}
- let mut errors = error::BorrowckErrors::new();
+ let mut errors = error::BorrowckErrors::new(infcx.tcx);
// Gather the upvars of a closure, if any.
let tables = tcx.typeck_opt_const_arg(def);
- if let Some(ErrorGuaranteed { .. }) = tables.tainted_by_errors {
- infcx.set_tainted_by_errors();
- errors.set_tainted_by_errors();
+ if let Some(e) = tables.tainted_by_errors {
+ infcx.set_tainted_by_errors(e);
+ errors.set_tainted_by_errors(e);
}
let upvars: Vec<_> = tables
.closure_min_captures_flattened(def.did)
use super::*;
pub struct BorrowckErrors<'tcx> {
+ tcx: TyCtxt<'tcx>,
/// This field keeps track of move errors that are to be reported for given move indices.
///
/// There are situations where many errors can be reported for a single move out (see #53807)
tainted_by_errors: Option<ErrorGuaranteed>,
}
- impl BorrowckErrors<'_> {
- pub fn new() -> Self {
+ impl<'tcx> BorrowckErrors<'tcx> {
+ pub fn new(tcx: TyCtxt<'tcx>) -> Self {
BorrowckErrors {
+ tcx,
buffered_move_errors: BTreeMap::new(),
buffered: Default::default(),
tainted_by_errors: None,
}
}
- // FIXME(eddyb) this is a suboptimal API because `tainted_by_errors` is
- // set before any emission actually happens (weakening the guarantee).
pub fn buffer_error(&mut self, t: DiagnosticBuilder<'_, ErrorGuaranteed>) {
- self.tainted_by_errors = Some(ErrorGuaranteed::unchecked_claim_error_was_emitted());
+ if let None = self.tainted_by_errors {
+ self.tainted_by_errors = Some(
+ self.tcx
+ .sess
+ .delay_span_bug(t.span.clone(), "diagnostic buffered but not emitted"),
+ )
+ }
t.buffer(&mut self.buffered);
}
t.buffer(&mut self.buffered);
}
- pub fn set_tainted_by_errors(&mut self) {
- self.tainted_by_errors = Some(ErrorGuaranteed::unchecked_claim_error_was_emitted());
+ pub fn set_tainted_by_errors(&mut self, e: ErrorGuaranteed) {
+ self.tainted_by_errors = Some(e);
}
}
if !nll_errors.is_empty() {
// Suppress unhelpful extra errors in `infer_opaque_types`.
- infcx.set_tainted_by_errors();
+ infcx.set_tainted_by_errors(infcx.tcx.sess.delay_span_bug(
+ body.span,
+ "`compute_regions` tainted `infcx` with errors but did not emit any errors",
+ ));
}
let remapped_opaque_tys = regioncx.infer_opaque_types(&infcx, opaque_type_values);
instantiated_ty: OpaqueHiddenType<'tcx>,
origin: OpaqueTyOrigin,
) -> Ty<'tcx> {
- if self.is_tainted_by_errors() {
- return self.tcx.ty_error();
+ if let Some(e) = self.tainted_by_errors() {
+ return self.tcx.ty_error_with_guaranteed(e);
}
let definition_ty = instantiated_ty
ptr::P,
token,
tokenstream::{DelimSpan, TokenStream, TokenTree},
- BinOpKind, BorrowKind, Expr, ExprKind, ItemKind, MacArgs, MacCall, MacDelimiter, Mutability,
- Path, PathSegment, Stmt, StructRest, UnOp, UseTree, UseTreeKind, DUMMY_NODE_ID,
+ BinOpKind, BorrowKind, Expr, ExprKind, ItemKind, MacArgs, MacCall, MacDelimiter, MethodCall,
+ Mutability, Path, PathSegment, Stmt, StructRest, UnOp, UseTree, UseTreeKind, DUMMY_NODE_ID,
};
use rustc_ast_pretty::pprust;
use rustc_data_structures::fx::FxHashSet;
self.manage_cond_expr(prefix);
self.manage_cond_expr(suffix);
}
- ExprKind::MethodCall(_, _,ref mut local_exprs, _) => {
- for local_expr in local_exprs.iter_mut() {
- self.manage_cond_expr(local_expr);
+ ExprKind::MethodCall(ref mut call) => {
+ for arg in call.args.iter_mut() {
+ self.manage_cond_expr(arg);
}
}
ExprKind::Path(_, Path { ref segments, .. }) if let &[ref path_segment] = &segments[..] => {
| ExprKind::Block(_, _)
| ExprKind::Box(_)
| ExprKind::Break(_, _)
- | ExprKind::Closure(_, _, _, _, _, _, _)
+ | ExprKind::Closure(_)
| ExprKind::ConstBlock(_)
| ExprKind::Continue(_)
| ExprKind::Err
fn expr_method_call(
cx: &ExtCtxt<'_>,
- path: PathSegment,
+ seg: PathSegment,
receiver: P<Expr>,
args: Vec<P<Expr>>,
span: Span,
) -> P<Expr> {
- cx.expr(span, ExprKind::MethodCall(path, receiver, args, span))
+ cx.expr(span, ExprKind::MethodCall(Box::new(MethodCall { seg, receiver, args, span })))
}
fn expr_paren(cx: &ExtCtxt<'_>, sp: Span, e: P<Expr>) -> P<Expr> {
default_call_conv: CallConv,
fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
) -> Signature {
- let call_conv = match fn_abi.conv {
+ let call_conv = conv_to_call_conv(fn_abi.conv, default_call_conv);
+
+ let inputs = fn_abi.args.iter().map(|arg_abi| arg_abi.get_abi_param(tcx).into_iter()).flatten();
+
+ let (return_ptr, returns) = fn_abi.ret.get_abi_return(tcx);
+ // Sometimes the first param is an pointer to the place where the return value needs to be stored.
+ let params: Vec<_> = return_ptr.into_iter().chain(inputs).collect();
+
+ Signature { params, returns, call_conv }
+}
+
+pub(crate) fn conv_to_call_conv(c: Conv, default_call_conv: CallConv) -> CallConv {
+ match c {
Conv::Rust | Conv::C => default_call_conv,
Conv::RustCold => CallConv::Cold,
Conv::X86_64SysV => CallConv::SystemV,
| Conv::X86VectorCall
| Conv::AmdGpuKernel
| Conv::AvrInterrupt
- | Conv::AvrNonBlockingInterrupt => todo!("{:?}", fn_abi.conv),
- };
- let inputs = fn_abi.args.iter().map(|arg_abi| arg_abi.get_abi_param(tcx).into_iter()).flatten();
-
- let (return_ptr, returns) = fn_abi.ret.get_abi_return(tcx);
- // Sometimes the first param is an pointer to the place where the return value needs to be stored.
- let params: Vec<_> = return_ptr.into_iter().chain(inputs).collect();
-
- Signature { params, returns, call_conv }
+ | Conv::AvrNonBlockingInterrupt => todo!("{:?}", c),
+ }
}
pub(crate) fn get_function_sig<'tcx>(
AbiParam::new(m.target_config().pointer_type()),
],
returns: vec![AbiParam::new(m.target_config().pointer_type() /*isize*/)],
- call_conv: CallConv::triple_default(m.isa().triple()),
+ call_conv: crate::conv_to_call_conv(
+ tcx.sess.target.options.entry_abi,
+ CallConv::triple_default(m.isa().triple()),
+ ),
};
- let cmain_func_id = m.declare_function("main", Linkage::Export, &cmain_sig).unwrap();
+ let entry_name = tcx.sess.target.options.entry_name.as_ref();
+ let cmain_func_id = m.declare_function(entry_name, Linkage::Export, &cmain_sig).unwrap();
let instance = Instance::mono(tcx, rust_main_def_id).polymorphize(tcx);
}
fn declare_c_main(&self, fn_type: Self::Type) -> Option<Self::Function> {
- if self.get_declared_value("main").is_none() {
- Some(self.declare_cfn("main", fn_type))
+ let entry_name = self.sess().target.entry_name.as_ref();
+ if self.get_declared_value(entry_name).is_none() {
+ Some(self.declare_entry_fn(entry_name, fn_type, ()))
}
else {
// If the symbol already exists, it is an error: for example, the user wrote
global
}
- pub fn declare_cfn(&self, name: &str, _fn_type: Type<'gcc>) -> RValue<'gcc> {
+ pub fn declare_entry_fn(&self, name: &str, _fn_type: Type<'gcc>, callconv: () /*llvm::CCallConv*/) -> RValue<'gcc> {
// TODO(antoyo): use the fn_type parameter.
let const_string = self.context.new_type::<u8>().make_pointer().make_pointer();
let return_type = self.type_i32();
let variadic = false;
self.linkage.set(FunctionType::Exported);
- let func = declare_raw_fn(self, name, () /*llvm::CCallConv*/, return_type, &[self.type_i32(), const_string], variadic);
+ let func = declare_raw_fn(self, name, callconv, return_type, &[self.type_i32(), const_string], variadic);
// NOTE: it is needed to set the current_func here as well, because get_fn() is not called
// for the main function.
*self.current_func.borrow_mut() = Some(func);
}
fn llvm_cconv(&self) -> llvm::CallConv {
- match self.conv {
- Conv::C | Conv::Rust | Conv::CCmseNonSecureCall => llvm::CCallConv,
- Conv::RustCold => llvm::ColdCallConv,
- Conv::AmdGpuKernel => llvm::AmdGpuKernel,
- Conv::AvrInterrupt => llvm::AvrInterrupt,
- Conv::AvrNonBlockingInterrupt => llvm::AvrNonBlockingInterrupt,
- Conv::ArmAapcs => llvm::ArmAapcsCallConv,
- Conv::Msp430Intr => llvm::Msp430Intr,
- Conv::PtxKernel => llvm::PtxKernel,
- Conv::X86Fastcall => llvm::X86FastcallCallConv,
- Conv::X86Intr => llvm::X86_Intr,
- Conv::X86Stdcall => llvm::X86StdcallCallConv,
- Conv::X86ThisCall => llvm::X86_ThisCall,
- Conv::X86VectorCall => llvm::X86_VectorCall,
- Conv::X86_64SysV => llvm::X86_64_SysV,
- Conv::X86_64Win64 => llvm::X86_64_Win64,
- }
+ self.conv.into()
}
fn apply_attrs_llfn(&self, cx: &CodegenCx<'ll, 'tcx>, llfn: &'ll Value) {
llvm::get_param(self.llfn(), index as c_uint)
}
}
+
+impl From<Conv> for llvm::CallConv {
+ fn from(conv: Conv) -> Self {
+ match conv {
+ Conv::C | Conv::Rust | Conv::CCmseNonSecureCall => llvm::CCallConv,
+ Conv::RustCold => llvm::ColdCallConv,
+ Conv::AmdGpuKernel => llvm::AmdGpuKernel,
+ Conv::AvrInterrupt => llvm::AvrInterrupt,
+ Conv::AvrNonBlockingInterrupt => llvm::AvrNonBlockingInterrupt,
+ Conv::ArmAapcs => llvm::ArmAapcsCallConv,
+ Conv::Msp430Intr => llvm::Msp430Intr,
+ Conv::PtxKernel => llvm::PtxKernel,
+ Conv::X86Fastcall => llvm::X86FastcallCallConv,
+ Conv::X86Intr => llvm::X86_Intr,
+ Conv::X86Stdcall => llvm::X86StdcallCallConv,
+ Conv::X86ThisCall => llvm::X86_ThisCall,
+ Conv::X86VectorCall => llvm::X86_VectorCall,
+ Conv::X86_64SysV => llvm::X86_64_SysV,
+ Conv::X86_64Win64 => llvm::X86_64_Win64,
+ }
+ }
+}
}
fn declare_c_main(&self, fn_type: Self::Type) -> Option<Self::Function> {
- if self.get_declared_value("main").is_none() {
- Some(self.declare_cfn("main", llvm::UnnamedAddr::Global, fn_type))
+ let entry_name = self.sess().target.entry_name.as_ref();
+ if self.get_declared_value(entry_name).is_none() {
+ Some(self.declare_entry_fn(
+ entry_name,
+ self.sess().target.entry_abi.into(),
+ llvm::UnnamedAddr::Global,
+ fn_type,
+ ))
} else {
// If the symbol already exists, it is an error: for example, the user wrote
// #[no_mangle] extern "C" fn main(..) {..}
declare_raw_fn(self, name, llvm::CCallConv, unnamed, visibility, fn_type)
}
+ /// Declare an entry Function
+ ///
+ /// The ABI of this function can change depending on the target (although for now the same as
+ /// `declare_cfn`)
+ ///
+ /// If there’s a value with the same name already declared, the function will
+ /// update the declaration and return existing Value instead.
+ pub fn declare_entry_fn(
+ &self,
+ name: &str,
+ callconv: llvm::CallConv,
+ unnamed: llvm::UnnamedAddr,
+ fn_type: &'ll Type,
+ ) -> &'ll Value {
+ let visibility = if self.tcx.sess.target.default_hidden_visibility {
+ llvm::Visibility::Hidden
+ } else {
+ llvm::Visibility::Default
+ };
+ declare_raw_fn(self, name, callconv, unnamed, visibility, fn_type)
+ }
+
/// Declare a Rust function.
///
/// If there’s a value with the same name already declared, the function will
.collect();
if tcx.entry_fn(()).is_some() {
- let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, "main"));
+ let exported_symbol =
+ ExportedSymbol::NoDefId(SymbolName::new(tcx, tcx.sess.target.entry_name.as_ref()));
symbols.push((
exported_symbol,
[dependencies]
tracing = "0.1"
+either = "1"
rustc_apfloat = { path = "../rustc_apfloat" }
rustc_ast = { path = "../rustc_ast" }
rustc_attr = { path = "../rustc_attr" }
-use super::{CompileTimeEvalContext, CompileTimeInterpreter, ConstEvalErr};
-use crate::interpret::eval_nullary_intrinsic;
-use crate::interpret::{
- intern_const_alloc_recursive, Allocation, ConstAlloc, ConstValue, CtfeValidationMode, GlobalId,
- Immediate, InternKind, InterpCx, InterpError, InterpResult, MPlaceTy, MemoryKind, OpTy,
- RefTracking, StackPopCleanup,
-};
+use std::borrow::Cow;
+use std::convert::TryInto;
+
+use either::{Left, Right};
use rustc_hir::def::DefKind;
use rustc_middle::mir;
use rustc_middle::ty::{self, TyCtxt};
use rustc_span::source_map::Span;
use rustc_target::abi::{self, Abi};
-use std::borrow::Cow;
-use std::convert::TryInto;
+
+use super::{CompileTimeEvalContext, CompileTimeInterpreter, ConstEvalErr};
+use crate::interpret::eval_nullary_intrinsic;
+use crate::interpret::{
+ intern_const_alloc_recursive, Allocation, ConstAlloc, ConstValue, CtfeValidationMode, GlobalId,
+ Immediate, InternKind, InterpCx, InterpError, InterpResult, MPlaceTy, MemoryKind, OpTy,
+ RefTracking, StackPopCleanup,
+};
const NOTE_ON_UNDEFINED_BEHAVIOR_ERROR: &str = "The rules on what exactly is undefined behavior aren't clear, \
so this check might be overzealous. Please open an issue on the rustc \
_ => false,
};
let immediate = if try_as_immediate {
- Err(ecx.read_immediate(op).expect("normalization works on validated constants"))
+ Right(ecx.read_immediate(op).expect("normalization works on validated constants"))
} else {
// It is guaranteed that any non-slice scalar pair is actually ByRef here.
// When we come back from raw const eval, we are always by-ref. The only way our op here is
// by-val is if we are in destructure_mir_constant, i.e., if this is (a field of) something that we
// "tried to make immediate" before. We wouldn't do that for non-slice scalar pairs or
// structs containing such.
- op.try_as_mplace()
+ op.as_mplace_or_imm()
};
debug!(?immediate);
}
};
match immediate {
- Ok(ref mplace) => to_const_value(mplace),
+ Left(ref mplace) => to_const_value(mplace),
// see comment on `let try_as_immediate` above
- Err(imm) => match *imm {
+ Right(imm) => match *imm {
_ if imm.layout.is_zst() => ConstValue::ZeroSized,
Immediate::Scalar(x) => ConstValue::Scalar(x),
Immediate::ScalarPair(a, b) => {
use rustc_hir::def::DefKind;
+use rustc_hir::LangItem;
use rustc_middle::mir;
+use rustc_middle::mir::interpret::PointerArithmetic;
+use rustc_middle::ty::layout::FnAbiOf;
use rustc_middle::ty::{self, Ty, TyCtxt};
use std::borrow::Borrow;
use std::hash::Hash;
+use std::ops::ControlFlow;
use rustc_data_structures::fx::FxIndexMap;
use rustc_data_structures::fx::IndexEntry;
use rustc_target::spec::abi::Abi as CallAbi;
use crate::interpret::{
- self, compile_time_machine, AllocId, ConstAllocation, Frame, ImmTy, InterpCx, InterpResult,
- OpTy, PlaceTy, Pointer, Scalar, StackPopUnwind,
+ self, compile_time_machine, AllocId, ConstAllocation, FnVal, Frame, ImmTy, InterpCx,
+ InterpResult, OpTy, PlaceTy, Pointer, Scalar, StackPopUnwind,
};
use super::error::*;
-impl<'mir, 'tcx> InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>> {
- /// "Intercept" a function call to a panic-related function
- /// because we have something special to do for it.
- /// If this returns successfully (`Ok`), the function should just be evaluated normally.
- fn hook_special_const_fn(
- &mut self,
- instance: ty::Instance<'tcx>,
- args: &[OpTy<'tcx>],
- ) -> InterpResult<'tcx, Option<ty::Instance<'tcx>>> {
- // All `#[rustc_do_not_const_check]` functions should be hooked here.
- let def_id = instance.def_id();
-
- if Some(def_id) == self.tcx.lang_items().panic_display()
- || Some(def_id) == self.tcx.lang_items().begin_panic_fn()
- {
- // &str or &&str
- assert!(args.len() == 1);
-
- let mut msg_place = self.deref_operand(&args[0])?;
- while msg_place.layout.ty.is_ref() {
- msg_place = self.deref_operand(&msg_place.into())?;
- }
-
- let msg = Symbol::intern(self.read_str(&msg_place)?);
- let span = self.find_closest_untracked_caller_location();
- let (file, line, col) = self.location_triple_for_span(span);
- return Err(ConstEvalErrKind::Panic { msg, file, line, col }.into());
- } else if Some(def_id) == self.tcx.lang_items().panic_fmt() {
- // For panic_fmt, call const_panic_fmt instead.
- if let Some(const_panic_fmt) = self.tcx.lang_items().const_panic_fmt() {
- return Ok(Some(
- ty::Instance::resolve(
- *self.tcx,
- ty::ParamEnv::reveal_all(),
- const_panic_fmt,
- self.tcx.intern_substs(&[]),
- )
- .unwrap()
- .unwrap(),
- ));
- }
- }
- Ok(None)
- }
-}
-
/// Extra machine state for CTFE, and the Machine instance
pub struct CompileTimeInterpreter<'mir, 'tcx> {
/// For now, the number of terminators that can be evaluated before we throw a resource
}
impl<'mir, 'tcx: 'mir> CompileTimeEvalContext<'mir, 'tcx> {
+ /// "Intercept" a function call, because we have something special to do for it.
+ /// All `#[rustc_do_not_const_check]` functions should be hooked here.
+ /// If this returns `Some` function, which may be `instance` or a different function with
+ /// compatible arguments, then evaluation should continue with that function.
+ /// If this returns `None`, the function call has been handled and the function has returned.
+ fn hook_special_const_fn(
+ &mut self,
+ instance: ty::Instance<'tcx>,
+ args: &[OpTy<'tcx>],
+ dest: &PlaceTy<'tcx>,
+ ret: Option<mir::BasicBlock>,
+ ) -> InterpResult<'tcx, Option<ty::Instance<'tcx>>> {
+ let def_id = instance.def_id();
+
+ if Some(def_id) == self.tcx.lang_items().panic_display()
+ || Some(def_id) == self.tcx.lang_items().begin_panic_fn()
+ {
+ // &str or &&str
+ assert!(args.len() == 1);
+
+ let mut msg_place = self.deref_operand(&args[0])?;
+ while msg_place.layout.ty.is_ref() {
+ msg_place = self.deref_operand(&msg_place.into())?;
+ }
+
+ let msg = Symbol::intern(self.read_str(&msg_place)?);
+ let span = self.find_closest_untracked_caller_location();
+ let (file, line, col) = self.location_triple_for_span(span);
+ return Err(ConstEvalErrKind::Panic { msg, file, line, col }.into());
+ } else if Some(def_id) == self.tcx.lang_items().panic_fmt() {
+ // For panic_fmt, call const_panic_fmt instead.
+ let const_def_id = self.tcx.require_lang_item(LangItem::ConstPanicFmt, None);
+ let new_instance = ty::Instance::resolve(
+ *self.tcx,
+ ty::ParamEnv::reveal_all(),
+ const_def_id,
+ instance.substs,
+ )
+ .unwrap()
+ .unwrap();
+
+ return Ok(Some(new_instance));
+ } else if Some(def_id) == self.tcx.lang_items().align_offset_fn() {
+ // For align_offset, we replace the function call if the pointer has no address.
+ match self.align_offset(instance, args, dest, ret)? {
+ ControlFlow::Continue(()) => return Ok(Some(instance)),
+ ControlFlow::Break(()) => return Ok(None),
+ }
+ }
+ Ok(Some(instance))
+ }
+
+ /// `align_offset(ptr, target_align)` needs special handling in const eval, because the pointer
+ /// may not have an address.
+ ///
+ /// If `ptr` does have a known address, then we return `CONTINUE` and the function call should
+ /// proceed as normal.
+ ///
+ /// If `ptr` doesn't have an address, but its underlying allocation's alignment is at most
+ /// `target_align`, then we call the function again with an dummy address relative to the
+ /// allocation.
+ ///
+ /// If `ptr` doesn't have an address and `target_align` is stricter than the underlying
+ /// allocation's alignment, then we return `usize::MAX` immediately.
+ fn align_offset(
+ &mut self,
+ instance: ty::Instance<'tcx>,
+ args: &[OpTy<'tcx>],
+ dest: &PlaceTy<'tcx>,
+ ret: Option<mir::BasicBlock>,
+ ) -> InterpResult<'tcx, ControlFlow<()>> {
+ assert_eq!(args.len(), 2);
+
+ let ptr = self.read_pointer(&args[0])?;
+ let target_align = self.read_scalar(&args[1])?.to_machine_usize(self)?;
+
+ if !target_align.is_power_of_two() {
+ throw_ub_format!("`align_offset` called with non-power-of-two align: {}", target_align);
+ }
+
+ match self.ptr_try_get_alloc_id(ptr) {
+ Ok((alloc_id, offset, _extra)) => {
+ let (_size, alloc_align, _kind) = self.get_alloc_info(alloc_id);
+
+ if target_align <= alloc_align.bytes() {
+ // Extract the address relative to the allocation base that is definitely
+ // sufficiently aligned and call `align_offset` again.
+ let addr = ImmTy::from_uint(offset.bytes(), args[0].layout).into();
+ let align = ImmTy::from_uint(target_align, args[1].layout).into();
+ let fn_abi = self.fn_abi_of_instance(instance, ty::List::empty())?;
+
+ // We replace the entire entire function call with a "tail call".
+ // Note that this happens before the frame of the original function
+ // is pushed on the stack.
+ self.eval_fn_call(
+ FnVal::Instance(instance),
+ (CallAbi::Rust, fn_abi),
+ &[addr, align],
+ /* with_caller_location = */ false,
+ dest,
+ ret,
+ StackPopUnwind::NotAllowed,
+ )?;
+ Ok(ControlFlow::BREAK)
+ } else {
+ // Not alignable in const, return `usize::MAX`.
+ let usize_max = Scalar::from_machine_usize(self.machine_usize_max(), self);
+ self.write_scalar(usize_max, dest)?;
+ self.return_to_block(ret)?;
+ Ok(ControlFlow::BREAK)
+ }
+ }
+ Err(_addr) => {
+ // The pointer has an address, continue with function call.
+ Ok(ControlFlow::CONTINUE)
+ }
+ }
+ }
+
/// See documentation on the `ptr_guaranteed_cmp` intrinsic.
fn guaranteed_cmp(&mut self, a: Scalar, b: Scalar) -> InterpResult<'tcx, u8> {
Ok(match (a, b) {
instance: ty::Instance<'tcx>,
_abi: CallAbi,
args: &[OpTy<'tcx>],
- _dest: &PlaceTy<'tcx>,
- _ret: Option<mir::BasicBlock>,
+ dest: &PlaceTy<'tcx>,
+ ret: Option<mir::BasicBlock>,
_unwind: StackPopUnwind, // unwinding is not supported in consts
) -> InterpResult<'tcx, Option<(&'mir mir::Body<'tcx>, ty::Instance<'tcx>)>> {
debug!("find_mir_or_eval_fn: {:?}", instance);
}
}
- if let Some(new_instance) = ecx.hook_special_const_fn(instance, args)? {
+ let Some(new_instance) = ecx.hook_special_const_fn(instance, args, dest, ret)? else {
+ return Ok(None);
+ };
+
+ if new_instance != instance {
// We call another const fn instead.
// However, we return the *original* instance to make backtraces work out
// (and we hope this does not confuse the FnAbi checks too much).
new_instance,
_abi,
args,
- _dest,
- _ret,
+ dest,
+ ret,
_unwind,
)?
.map(|(body, _instance)| (body, instance)));
}
}
+
// This is a const fn. Call it.
Ok(Some((ecx.load_mir(instance.def, None)?, instance)))
}
use std::fmt;
use std::mem;
+use either::{Either, Left, Right};
+
use rustc_hir::{self as hir, def_id::DefId, definitions::DefPathData};
use rustc_index::vec::IndexVec;
use rustc_middle::mir;
MemPlaceMeta, Memory, MemoryKind, Operand, Place, PlaceTy, PointerArithmetic, Provenance,
Scalar, StackPopJump,
};
-use crate::transform::validate::equal_up_to_regions;
+use crate::util;
pub struct InterpCx<'mir, 'tcx, M: Machine<'mir, 'tcx>> {
/// Stores the `Machine` instance.
////////////////////////////////////////////////////////////////////////////////
// Current position within the function
////////////////////////////////////////////////////////////////////////////////
- /// If this is `Err`, we are not currently executing any particular statement in
+ /// If this is `Right`, we are not currently executing any particular statement in
/// this frame (can happen e.g. during frame initialization, and during unwinding on
/// frames without cleanup code).
- /// We basically abuse `Result` as `Either`.
///
/// Needs to be public because ConstProp does unspeakable things to it.
- pub loc: Result<mir::Location, Span>,
+ pub loc: Either<mir::Location, Span>,
}
/// What we store about a frame in an interpreter backtrace.
impl<'mir, 'tcx, Prov: Provenance, Extra> Frame<'mir, 'tcx, Prov, Extra> {
/// Get the current location within the Frame.
///
- /// If this is `Err`, we are not currently executing any particular statement in
+ /// If this is `Left`, we are not currently executing any particular statement in
/// this frame (can happen e.g. during frame initialization, and during unwinding on
/// frames without cleanup code).
- /// We basically abuse `Result` as `Either`.
///
/// Used by priroda.
- pub fn current_loc(&self) -> Result<mir::Location, Span> {
+ pub fn current_loc(&self) -> Either<mir::Location, Span> {
self.loc
}
/// Return the `SourceInfo` of the current instruction.
pub fn current_source_info(&self) -> Option<&mir::SourceInfo> {
- self.loc.ok().map(|loc| self.body.source_info(loc))
+ self.loc.left().map(|loc| self.body.source_info(loc))
}
pub fn current_span(&self) -> Span {
match self.loc {
- Ok(loc) => self.body.source_info(loc).span,
- Err(span) => span,
+ Left(loc) => self.body.source_info(loc).span,
+ Right(span) => span,
}
}
}
// Type-changing assignments can happen when subtyping is used. While
// all normal lifetimes are erased, higher-ranked types with their
// late-bound lifetimes are still around and can lead to type
- // differences. So we compare ignoring lifetimes.
- if equal_up_to_regions(tcx, param_env, src.ty, dest.ty) {
+ // differences.
+ if util::is_subtype(tcx, param_env, src.ty, dest.ty) {
// Make sure the layout is equal, too -- just to be safe. Miri really
// needs layout equality. For performance reason we skip this check when
// the types are equal. Equal types *can* have different layouts when
// first push a stack frame so we have access to the local substs
let pre_frame = Frame {
body,
- loc: Err(body.span), // Span used for errors caused during preamble.
+ loc: Right(body.span), // Span used for errors caused during preamble.
return_to_block,
return_place: return_place.clone(),
// empty local array, we fill it in below, after we are inside the stack frame and
// done
self.frame_mut().locals = locals;
M::after_stack_push(self)?;
- self.frame_mut().loc = Ok(mir::Location::START);
+ self.frame_mut().loc = Left(mir::Location::START);
let span = info_span!("frame", "{}", instance);
self.frame_mut().tracing_span.enter(span);
/// Jump to the given block.
#[inline]
pub fn go_to_block(&mut self, target: mir::BasicBlock) {
- self.frame_mut().loc = Ok(mir::Location { block: target, statement_index: 0 });
+ self.frame_mut().loc = Left(mir::Location { block: target, statement_index: 0 });
}
/// *Return* to the given `target` basic block.
/// unwinding, and doing so is UB.
pub fn unwind_to_block(&mut self, target: StackPopUnwind) -> InterpResult<'tcx> {
self.frame_mut().loc = match target {
- StackPopUnwind::Cleanup(block) => Ok(mir::Location { block, statement_index: 0 }),
- StackPopUnwind::Skip => Err(self.frame_mut().body.span),
+ StackPopUnwind::Cleanup(block) => Left(mir::Location { block, statement_index: 0 }),
+ StackPopUnwind::Skip => Right(self.frame_mut().body.span),
StackPopUnwind::NotAllowed => {
throw_ub_format!("unwinding past a stack frame that does not allow unwinding")
}
assert_eq!(
unwinding,
match self.frame().loc {
- Ok(loc) => self.body().basic_blocks[loc.block].is_cleanup,
- Err(_) => true,
+ Left(loc) => self.body().basic_blocks[loc.block].is_cleanup,
+ Right(_) => true,
}
);
if unwinding && self.frame_idx() == 0 {
let discr_val = self.read_discriminant(&place.into())?.0;
self.write_scalar(discr_val, dest)?;
}
+ sym::exact_div => {
+ let l = self.read_immediate(&args[0])?;
+ let r = self.read_immediate(&args[1])?;
+ self.exact_div(&l, &r, dest)?;
+ }
sym::unchecked_shl
| sym::unchecked_shr
| sym::unchecked_add
debug!("find_closest_untracked_caller_location: checking frame {:?}", frame.instance);
// Assert that the frame we look at is actually executing code currently
- // (`loc` is `Err` when we are unwinding and the frame does not require cleanup).
- let loc = frame.loc.unwrap();
+ // (`loc` is `Right` when we are unwinding and the frame does not require cleanup).
+ let loc = frame.loc.left().unwrap();
// This could be a non-`Call` terminator (such as `Drop`), or not a terminator at all
// (such as `box`). Use the normal span by default.
//! Functions concerning immediate values and operands, and reading from operands.
//! All high-level functions to read from memory work on operands as sources.
+use either::{Either, Left, Right};
+
use rustc_hir::def::Namespace;
use rustc_middle::ty::layout::{LayoutOf, PrimitiveExt, TyAndLayout};
use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter};
layout: TyAndLayout<'tcx>,
cx: &impl HasDataLayout,
) -> InterpResult<'tcx, Self> {
- match self.try_as_mplace() {
- Ok(mplace) => Ok(mplace.offset_with_meta(offset, meta, layout, cx)?.into()),
- Err(imm) => {
+ match self.as_mplace_or_imm() {
+ Left(mplace) => Ok(mplace.offset_with_meta(offset, meta, layout, cx)?.into()),
+ Right(imm) => {
assert!(
matches!(*imm, Immediate::Uninit),
"Scalar/ScalarPair cannot be offset into"
/// Try returning an immediate for the operand. If the layout does not permit loading this as an
/// immediate, return where in memory we can find the data.
- /// Note that for a given layout, this operation will either always fail or always
- /// succeed! Whether it succeeds depends on whether the layout can be represented
+ /// Note that for a given layout, this operation will either always return Left or Right!
+ /// succeed! Whether it returns Left depends on whether the layout can be represented
/// in an `Immediate`, not on which data is stored there currently.
///
/// This is an internal function that should not usually be used; call `read_immediate` instead.
pub fn read_immediate_raw(
&self,
src: &OpTy<'tcx, M::Provenance>,
- ) -> InterpResult<'tcx, Result<ImmTy<'tcx, M::Provenance>, MPlaceTy<'tcx, M::Provenance>>> {
- Ok(match src.try_as_mplace() {
- Ok(ref mplace) => {
+ ) -> InterpResult<'tcx, Either<MPlaceTy<'tcx, M::Provenance>, ImmTy<'tcx, M::Provenance>>> {
+ Ok(match src.as_mplace_or_imm() {
+ Left(ref mplace) => {
if let Some(val) = self.read_immediate_from_mplace_raw(mplace)? {
- Ok(val)
+ Right(val)
} else {
- Err(*mplace)
+ Left(*mplace)
}
}
- Err(val) => Ok(val),
+ Right(val) => Right(val),
})
}
) {
span_bug!(self.cur_span(), "primitive read not possible for type: {:?}", op.layout.ty);
}
- let imm = self.read_immediate_raw(op)?.unwrap();
+ let imm = self.read_immediate_raw(op)?.right().unwrap();
if matches!(*imm, Immediate::Uninit) {
throw_ub!(InvalidUninitBytes(None));
}
// Basically we just transmute this place into an array following simd_size_and_type.
// This only works in memory, but repr(simd) types should never be immediates anyway.
assert!(op.layout.ty.is_simd());
- match op.try_as_mplace() {
- Ok(mplace) => self.mplace_to_simd(&mplace),
- Err(imm) => match *imm {
+ match op.as_mplace_or_imm() {
+ Left(mplace) => self.mplace_to_simd(&mplace),
+ Right(imm) => match *imm {
Immediate::Uninit => {
throw_ub!(InvalidUninitBytes(None))
}
//! into a place.
//! All high-level functions to write to memory work on places as destinations.
+use either::{Either, Left, Right};
+
use rustc_ast::Mutability;
use rustc_middle::mir;
use rustc_middle::ty;
// These are defined here because they produce a place.
impl<'tcx, Prov: Provenance> OpTy<'tcx, Prov> {
#[inline(always)]
- pub fn try_as_mplace(&self) -> Result<MPlaceTy<'tcx, Prov>, ImmTy<'tcx, Prov>> {
+ pub fn as_mplace_or_imm(&self) -> Either<MPlaceTy<'tcx, Prov>, ImmTy<'tcx, Prov>> {
match **self {
Operand::Indirect(mplace) => {
- Ok(MPlaceTy { mplace, layout: self.layout, align: self.align.unwrap() })
+ Left(MPlaceTy { mplace, layout: self.layout, align: self.align.unwrap() })
}
- Operand::Immediate(imm) => Err(ImmTy::from_immediate(imm, self.layout)),
+ Operand::Immediate(imm) => Right(ImmTy::from_immediate(imm, self.layout)),
}
}
#[inline(always)]
#[cfg_attr(debug_assertions, track_caller)] // only in debug builds due to perf (see #98980)
pub fn assert_mem_place(&self) -> MPlaceTy<'tcx, Prov> {
- self.try_as_mplace().unwrap()
+ self.as_mplace_or_imm().left().unwrap()
}
}
impl<'tcx, Prov: Provenance> PlaceTy<'tcx, Prov> {
/// A place is either an mplace or some local.
#[inline]
- pub fn try_as_mplace(&self) -> Result<MPlaceTy<'tcx, Prov>, (usize, mir::Local)> {
+ pub fn as_mplace_or_local(&self) -> Either<MPlaceTy<'tcx, Prov>, (usize, mir::Local)> {
match **self {
- Place::Ptr(mplace) => Ok(MPlaceTy { mplace, layout: self.layout, align: self.align }),
- Place::Local { frame, local } => Err((frame, local)),
+ Place::Ptr(mplace) => Left(MPlaceTy { mplace, layout: self.layout, align: self.align }),
+ Place::Local { frame, local } => Right((frame, local)),
}
}
#[inline(always)]
#[cfg_attr(debug_assertions, track_caller)] // only in debug builds due to perf (see #98980)
pub fn assert_mem_place(&self) -> MPlaceTy<'tcx, Prov> {
- self.try_as_mplace().unwrap()
+ self.as_mplace_or_local().left().unwrap()
}
}
}
pub fn write_uninit(&mut self, dest: &PlaceTy<'tcx, M::Provenance>) -> InterpResult<'tcx> {
- let mplace = match dest.try_as_mplace() {
- Ok(mplace) => mplace,
- Err((frame, local)) => {
+ let mplace = match dest.as_mplace_or_local() {
+ Left(mplace) => mplace,
+ Right((frame, local)) => {
match M::access_local_mut(self, frame, local)? {
Operand::Immediate(local) => {
*local = Immediate::Uninit;
// Let us see if the layout is simple so we take a shortcut,
// avoid force_allocation.
let src = match self.read_immediate_raw(src)? {
- Ok(src_val) => {
+ Right(src_val) => {
// FIXME(const_prop): Const-prop can possibly evaluate an
// unsized copy operation when it thinks that the type is
// actually sized, due to a trivially false where-clause
)
};
}
- Err(mplace) => mplace,
+ Left(mplace) => mplace,
};
// Slow path, this does not fit into an immediate. Just memcpy.
trace!("copy_op: {:?} <- {:?}: {}", *dest, src, dest.layout.ty);
//! but we still need to do bounds checking and adjust the layout. To not duplicate that with MPlaceTy, we actually
//! implement the logic on OpTy, and MPlaceTy calls that.
+use either::{Left, Right};
+
use rustc_middle::mir;
use rustc_middle::ty;
use rustc_middle::ty::layout::LayoutOf;
base: &OpTy<'tcx, M::Provenance>,
field: usize,
) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> {
- let base = match base.try_as_mplace() {
- Ok(ref mplace) => {
+ let base = match base.as_mplace_or_imm() {
+ Left(ref mplace) => {
// We can reuse the mplace field computation logic for indirect operands.
let field = self.mplace_field(mplace, field)?;
return Ok(field.into());
}
- Err(value) => value,
+ Right(value) => value,
};
let field_layout = base.layout.field(self, field);
//!
//! The main entry point is the `step` method.
+use either::Either;
+
use rustc_middle::mir;
use rustc_middle::mir::interpret::{InterpResult, Scalar};
use rustc_middle::ty::layout::LayoutOf;
return Ok(false);
}
- let Ok(loc) = self.frame().loc else {
+ let Either::Left(loc) = self.frame().loc else {
// We are unwinding and this fn has no cleanup code.
// Just go on unwinding.
trace!("unwinding: skipping frame");
// Make sure we are not updating `statement_index` of the wrong frame.
assert_eq!(old_frames, self.frame_idx());
// Advance the program counter.
- self.frame_mut().loc.as_mut().unwrap().statement_index += 1;
+ self.frame_mut().loc.as_mut().left().unwrap().statement_index += 1;
return Ok(true);
}
self.eval_terminator(terminator)?;
if !self.stack().is_empty() {
- if let Ok(loc) = self.frame().loc {
+ if let Either::Left(loc) = self.frame().loc {
info!("// executing {:?}", loc.block);
}
}
use std::fmt::{Display, Write};
use std::num::NonZeroUsize;
+use either::{Left, Right};
+
use rustc_ast::Mutability;
use rustc_data_structures::fx::FxHashSet;
use rustc_hir as hir;
return Ok(());
}
// Now that we definitely have a non-ZST array, we know it lives in memory.
- let mplace = match op.try_as_mplace() {
- Ok(mplace) => mplace,
- Err(imm) => match *imm {
+ let mplace = match op.as_mplace_or_imm() {
+ Left(mplace) => mplace,
+ Right(imm) => match *imm {
Immediate::Uninit =>
throw_validation_failure!(self.path, { "uninitialized bytes" }),
Immediate::Scalar(..) | Immediate::ScalarPair(..) =>
}
fn is_async(&self) -> bool {
- self.tcx.asyncness(self.def_id()) == hir::IsAsync::Async
+ self.tcx.asyncness(self.def_id()).is_async()
}
}
use rustc_data_structures::fx::FxHashSet;
use rustc_index::bit_set::BitSet;
-use rustc_infer::infer::TyCtxtInferExt;
use rustc_middle::mir::interpret::Scalar;
use rustc_middle::mir::visit::NonUseContext::VarDebugInfo;
use rustc_middle::mir::visit::{PlaceContext, Visitor};
ProjectionElem, RuntimePhase, Rvalue, SourceScope, Statement, StatementKind, Terminator,
TerminatorKind, UnOp, START_BLOCK,
};
-use rustc_middle::ty::fold::BottomUpFolder;
-use rustc_middle::ty::{self, InstanceDef, ParamEnv, Ty, TyCtxt, TypeFoldable, TypeVisitable};
+use rustc_middle::ty::{self, InstanceDef, ParamEnv, Ty, TyCtxt, TypeVisitable};
use rustc_mir_dataflow::impls::MaybeStorageLive;
use rustc_mir_dataflow::storage::always_storage_live_locals;
use rustc_mir_dataflow::{Analysis, ResultsCursor};
}
}
-/// Returns whether the two types are equal up to lifetimes.
-/// All lifetimes, including higher-ranked ones, get ignored for this comparison.
-/// (This is unlike the `erasing_regions` methods, which keep higher-ranked lifetimes for soundness reasons.)
-///
-/// The point of this function is to approximate "equal up to subtyping". However,
-/// the approximation is incorrect as variance is ignored.
-pub fn equal_up_to_regions<'tcx>(
- tcx: TyCtxt<'tcx>,
- param_env: ParamEnv<'tcx>,
- src: Ty<'tcx>,
- dest: Ty<'tcx>,
-) -> bool {
- // Fast path.
- if src == dest {
- return true;
- }
-
- // Normalize lifetimes away on both sides, then compare.
- let normalize = |ty: Ty<'tcx>| {
- tcx.try_normalize_erasing_regions(param_env, ty).unwrap_or(ty).fold_with(
- &mut BottomUpFolder {
- tcx,
- // FIXME: We erase all late-bound lifetimes, but this is not fully correct.
- // If you have a type like `<for<'a> fn(&'a u32) as SomeTrait>::Assoc`,
- // this is not necessarily equivalent to `<fn(&'static u32) as SomeTrait>::Assoc`,
- // since one may have an `impl SomeTrait for fn(&32)` and
- // `impl SomeTrait for fn(&'static u32)` at the same time which
- // specify distinct values for Assoc. (See also #56105)
- lt_op: |_| tcx.lifetimes.re_erased,
- // Leave consts and types unchanged.
- ct_op: |ct| ct,
- ty_op: |ty| ty,
- },
- )
- };
- tcx.infer_ctxt().build().can_eq(param_env, normalize(src), normalize(dest)).is_ok()
-}
-
struct TypeChecker<'a, 'tcx> {
when: &'a str,
body: &'a Body<'tcx>,
return true;
}
- // Normalize projections and things like that.
- // Type-changing assignments can happen when subtyping is used. While
- // all normal lifetimes are erased, higher-ranked types with their
- // late-bound lifetimes are still around and can lead to type
- // differences. So we compare ignoring lifetimes.
-
- // First, try with reveal_all. This might not work in some cases, as the predicates
- // can be cleared in reveal_all mode. We try the reveal first anyways as it is used
- // by some other passes like inlining as well.
- let param_env = self.param_env.with_reveal_all_normalized(self.tcx);
- if equal_up_to_regions(self.tcx, param_env, src, dest) {
- return true;
- }
-
- // If this fails, we can try it without the reveal.
- equal_up_to_regions(self.tcx, self.param_env, src, dest)
+ crate::util::is_subtype(self.tcx, self.param_env, src, dest)
}
}
--- /dev/null
+//! Routines to check for relations between fully inferred types.
+//!
+//! FIXME: Move this to a more general place. The utility of this extends to
+//! other areas of the compiler as well.
+
+use rustc_infer::infer::{DefiningAnchor, TyCtxtInferExt};
+use rustc_infer::traits::ObligationCause;
+use rustc_middle::ty::{ParamEnv, Ty, TyCtxt};
+use rustc_trait_selection::traits::ObligationCtxt;
+
+/// Returns whether the two types are equal up to subtyping.
+///
+/// This is used in case we don't know the expected subtyping direction
+/// and still want to check whether anything is broken.
+pub fn is_equal_up_to_subtyping<'tcx>(
+ tcx: TyCtxt<'tcx>,
+ param_env: ParamEnv<'tcx>,
+ src: Ty<'tcx>,
+ dest: Ty<'tcx>,
+) -> bool {
+ // Fast path.
+ if src == dest {
+ return true;
+ }
+
+ // Check for subtyping in either direction.
+ is_subtype(tcx, param_env, src, dest) || is_subtype(tcx, param_env, dest, src)
+}
+
+/// Returns whether `src` is a subtype of `dest`, i.e. `src <: dest`.
+///
+/// This mostly ignores opaque types as it can be used in constraining contexts
+/// while still computing the final underlying type.
+pub fn is_subtype<'tcx>(
+ tcx: TyCtxt<'tcx>,
+ param_env: ParamEnv<'tcx>,
+ src: Ty<'tcx>,
+ dest: Ty<'tcx>,
+) -> bool {
+ if src == dest {
+ return true;
+ }
+
+ let mut builder =
+ tcx.infer_ctxt().ignoring_regions().with_opaque_type_inference(DefiningAnchor::Bubble);
+ let infcx = builder.build();
+ let ocx = ObligationCtxt::new(&infcx);
+ let cause = ObligationCause::dummy();
+ let src = ocx.normalize(cause.clone(), param_env, src);
+ let dest = ocx.normalize(cause.clone(), param_env, dest);
+ match ocx.sub(&cause, param_env, src, dest) {
+ Ok(()) => {}
+ Err(_) => return false,
+ };
+ let errors = ocx.select_all_or_error();
+ // With `Reveal::All`, opaque types get normalized away, with `Reveal::UserFacing`
+ // we would get unification errors because we're unable to look into opaque types,
+ // even if they're constrained in our current function.
+ //
+ // It seems very unlikely that this hides any bugs.
+ let _ = infcx.inner.borrow_mut().opaque_type_storage.take_opaque_types();
+ errors.is_empty()
+}
mod alignment;
mod call_kind;
pub mod collect_writes;
+mod compare_types;
mod find_self_call;
mod might_permit_raw_init;
mod type_name;
pub use self::aggregate::expand_aggregate;
pub use self::alignment::is_disaligned;
pub use self::call_kind::{call_kind, CallDesugaringKind, CallKind};
+pub use self::compare_types::{is_equal_up_to_subtyping, is_subtype};
pub use self::find_self_call::find_self_call;
pub use self::might_permit_raw_init::might_permit_raw_init;
pub use self::type_name::type_name;
type Inner = T;
#[inline]
- fn try_map_id<F, E>(self, mut f: F) -> Result<Self, E>
+ fn try_map_id<F, E>(self, f: F) -> Result<Self, E>
where
F: FnMut(Self::Inner) -> Result<Self::Inner, E>,
{
- struct HoleVec<T> {
- vec: Vec<mem::ManuallyDrop<T>>,
- hole: Option<usize>,
- }
-
- impl<T> Drop for HoleVec<T> {
- fn drop(&mut self) {
- unsafe {
- for (index, slot) in self.vec.iter_mut().enumerate() {
- if self.hole != Some(index) {
- mem::ManuallyDrop::drop(slot);
- }
- }
- }
- }
- }
-
- unsafe {
- let (ptr, length, capacity) = self.into_raw_parts();
- let vec = Vec::from_raw_parts(ptr.cast(), length, capacity);
- let mut hole_vec = HoleVec { vec, hole: None };
-
- for (index, slot) in hole_vec.vec.iter_mut().enumerate() {
- hole_vec.hole = Some(index);
- let original = mem::ManuallyDrop::take(slot);
- let mapped = f(original)?;
- *slot = mem::ManuallyDrop::new(mapped);
- hole_vec.hole = None;
- }
-
- mem::forget(hole_vec);
- Ok(Vec::from_raw_parts(ptr, length, capacity))
- }
+ self.into_iter().map(f).collect()
}
}
//! This API is completely unstable and subject to change.
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
+#![feature(is_terminal)]
#![feature(once_cell)]
#![feature(decl_macro)]
#![recursion_limit = "256"]
use rustc_interface::util::{self, collect_crate_types, get_codegen_backend};
use rustc_interface::{interface, Queries};
use rustc_lint::LintStore;
-use rustc_log::stdout_isatty;
use rustc_metadata::locator;
use rustc_save_analysis as save;
use rustc_save_analysis::DumpHandler;
use std::env;
use std::ffi::OsString;
use std::fs;
-use std::io::{self, Read, Write};
+use std::io::{self, IsTerminal, Read, Write};
use std::panic::{self, catch_unwind};
use std::path::PathBuf;
use std::process::{self, Command, Stdio};
}
text.push('\n');
}
- if stdout_isatty() {
+ if io::stdout().is_terminal() {
show_content_with_pager(&text);
} else {
print!("{}", text);
fluent-bundle = "0.15.2"
fluent-syntax = "0.11"
intl-memoizer = "0.5.1"
+rustc_baked_icu_data = { path = "../rustc_baked_icu_data" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_serialize = { path = "../rustc_serialize" }
rustc_span = { path = "../rustc_span" }
rustc_macros = { path = "../rustc_macros" }
tracing = "0.1"
unic-langid = { version = "0.9.0", features = ["macros"] }
+icu_list = "1.0.0"
+writeable = "0.5.0"
+icu_locid = "1.0.0"
+icu_provider_adapters = "1.0.0"
+
+[features]
+rustc_use_parallel_compiler = ['rustc_baked_icu_data/rustc_use_parallel_compiler']
--- /dev/null
+hir_typeck_fru_note = this expression may have been misinterpreted as a `..` range expression
+hir_typeck_fru_expr = this expression does not end in a comma...
+hir_typeck_fru_expr2 = ... so this is interpreted as a `..` range expression, instead of functional record update syntax
+hir_typeck_fru_suggestion =
+ to set the remaining fields{$expr ->
+ [NONE]{""}
+ *[other] {" "}from `{$expr}`
+ }, separate the last named field with a comma
parser_tilde_is_not_unary_operator = `~` cannot be used as a unary operator
.suggestion = use `!` to perform bitwise not
+parser_unexpected_if_with_if = unexpected `if` in the condition expression
+ .suggestion = remove the `if`
+
parser_unexpected_token_after_not = unexpected {$negated_desc} after identifier
parser_unexpected_token_after_not_bitwise = use `!` to perform bitwise not
parser_unexpected_token_after_not_logical = use `!` to perform logical negation
--- /dev/null
+resolve_parent_module_reset_for_binding =
+ parent module is reset for binding
+
+resolve_ampersand_used_without_explicit_lifetime_name =
+ `&` without an explicit lifetime name cannot be used here
+ .note = explicit lifetime name needed here
+
+resolve_underscore_lifetime_name_cannot_be_used_here =
+ `'_` cannot be used here
+ .note = `'_` is a reserved lifetime name
+
+resolve_crate_may_not_be_imported =
+ `$crate` may not be imported
+
+resolve_crate_root_imports_must_be_named_explicitly =
+ crate root imports need to be explicitly named: `use crate as name;`
+
+resolve_generic_params_from_outer_function =
+ can't use generic parameters from outer function
+ .label = use of generic parameter from outer function
+ .suggestion = try using a local generic parameter instead
+
+resolve_self_type_implicitly_declared_by_impl =
+ `Self` type implicitly declared here, by this `impl`
+
+resolve_cannot_use_self_type_here =
+ can't use `Self` here
+
+resolve_use_a_type_here_instead =
+ use a type here instead
+
+resolve_type_param_from_outer_fn =
+ type parameter from outer function
+
+resolve_const_param_from_outer_fn =
+ const parameter from outer function
+
+resolve_try_using_local_generic_parameter =
+ try using a local generic parameter instead
+
+resolve_try_adding_local_generic_param_on_method =
+ try adding a local generic parameter in this method instead
+
+resolve_help_try_using_local_generic_param =
+ try using a local generic paramter instead
+
+resolve_name_is_already_used_as_generic_parameter =
+ the name `{$name}` is already used for a generic parameter in this item's generic parameters
+ .label = already used
+ .first_use_of_name = first use of `{$name}`
+
+resolve_method_not_member_of_trait =
+ method `{$method}` is not a member of trait `{$trait_}`
+ .label = not a member of trait `{$trait_}`
+
+resolve_associated_fn_with_similar_name_exists =
+ there is an associated function with a similar name
+
+resolve_type_not_member_of_trait =
+ type `{$type_}` is not a member of trait `{$trait_}`
+ .label = not a member of trait `{$trait_}`
+
+resolve_associated_type_with_similar_name_exists =
+ there is an associated type with a similar name
+
+resolve_const_not_member_of_trait =
+ const `{$const_}` is not a member of trait `{$trait_}`
+ .label = not a member of trait `{$trait_}`
+
+resolve_associated_const_with_similar_name_exists =
+ there is an associated constant with a similar name
+
+resolve_variable_bound_with_different_mode =
+ variable `{$variable_name}` is bound inconsistently across alternatives separated by `|`
+ .label = bound in different ways
+ .first_binding_span = first binding
+
+resolve_ident_bound_more_than_once_in_parameter_list =
+ identifier `{$identifier}` is bound more than once in this parameter list
+ .label = used as parameter more than once
+
+resolve_ident_bound_more_than_once_in_same_pattern =
+ identifier `{$identifier}` is bound more than once in the same pattern
+ .label = used in a pattern more than once
+
+resolve_undeclared_label =
+ use of undeclared label `{$name}`
+ .label = undeclared label `{$name}`
+
+resolve_label_with_similar_name_reachable =
+ a label with a similar name is reachable
+
+resolve_try_using_similarly_named_label =
+ try using similarly named label
+
+resolve_unreachable_label_with_similar_name_exists =
+ a label with a similar name exists but is unreachable
+
+resolve_self_import_can_only_appear_once_in_the_list =
+ `self` import can only appear once in an import list
+ .label = can only appear once in an import list
+
+resolve_self_import_only_in_import_list_with_non_empty_prefix =
+ `self` import can only appear in an import list with a non-empty prefix
+ .label = can only appear in an import list with a non-empty prefix
+
+resolve_cannot_capture_dynamic_environment_in_fn_item =
+ can't capture dynamic environment in a fn item
+ .help = use the `|| {"{"} ... {"}"}` closure form instead
+
+resolve_attempt_to_use_non_constant_value_in_constant =
+ attempt to use a non-constant value in a constant
+
+resolve_attempt_to_use_non_constant_value_in_constant_with_suggestion =
+ consider using `{$suggestion}` instead of `{$current}`
+
+resolve_attempt_to_use_non_constant_value_in_constant_label_with_suggestion =
+ non-constant value
+
+resolve_attempt_to_use_non_constant_value_in_constant_without_suggestion =
+ this would need to be a `{$suggestion}`
+
+resolve_self_imports_only_allowed_within =
+ `self` imports are only allowed within a {"{"} {"}"} list
+
+resolve_self_imports_only_allowed_within_suggestion =
+ consider importing the module directly
+
+resolve_self_imports_only_allowed_within_multipart_suggestion =
+ alternatively, use the multi-path `use` syntax to import `self`
+
+resolve_binding_shadows_something_unacceptable =
+ {$shadowing_binding}s cannot shadow {$shadowed_binding}s
+ .label = cannot be named the same as {$article} {$shadowed_binding}
+ .label_shadowed_binding = the {$shadowed_binding} `{$name}` is {$participle} here
+
+resolve_binding_shadows_something_unacceptable_suggestion =
+ try specify the pattern arguments
+
+resolve_forward_declared_generic_param =
+ generic parameters with a default cannot use forward declared identifiers
+ .label = defaulted generic parameters cannot be forward declared
+
+resolve_param_in_ty_of_const_param =
+ the type of const parameters must not depend on other generic parameters
+ .label = the type must not depend on the parameter `{$name}`
+
+resolve_self_in_generic_param_default =
+ generic parameters cannot use `Self` in their defaults
+ .label = `Self` in generic parameter default
+
+resolve_param_in_non_trivial_anon_const =
+ generic parameters may not be used in const operations
+ .label = cannot perform const operation using `{$name}`
+
+resolve_param_in_non_trivial_anon_const_help =
+ use `#![feature(generic_const_exprs)]` to allow generic const expressions
+
+resolve_param_in_non_trivial_anon_const_sub_type =
+ type parameters may not be used in const expressions
+
+resolve_param_in_non_trivial_anon_const_sub_non_type =
+ const parameters may only be used as standalone arguments, i.e. `{$name}`
+
+resolve_unreachable_label =
+ use of unreachable label `{$name}`
+ .label = unreachable label `{$name}`
+ .label_definition_span = unreachable label defined here
+ .note = labels are unreachable through functions, closures, async blocks and modules
+
+resolve_unreachable_label_suggestion_use_similarly_named =
+ try using similarly named label
+
+resolve_unreachable_label_similar_name_reachable =
+ a label with a similar name is reachable
+
+resolve_unreachable_label_similar_name_unreachable =
+ a label with a similar name exists but is also unreachable
+
+resolve_trait_impl_mismatch =
+ item `{$name}` is an associated {$kind}, which doesn't match its trait `{$trait_path}`
+ .label = does not match trait
+ .label_trait_item = item in trait
+
+resolve_invalid_asm_sym =
+ invalid `sym` operand
+ .label = is a local variable
+ .help = `sym` operands must refer to either a function or a static
+
+resolve_trait_impl_duplicate =
+ duplicate definitions with name `{$name}`:
+ .label = duplicate definition
+ .old_span_label = previous definition here
+ .trait_item_span = item in trait
+
+resolve_relative_2018 =
+ relative paths are not supported in visibilities in 2018 edition or later
+ .suggestion = try
+
+resolve_ancestor_only =
+ visibilities can only be restricted to ancestor modules
+
+resolve_expected_found =
+ expected module, found {$res} `{$path_str}`
+ .label = not a module
+
+resolve_indeterminate =
+ cannot determine resolution for the visibility
+
+resolve_module_only =
+ visibility must resolve to a module
use fluent_bundle::FluentResource;
use fluent_syntax::parser::ParserError;
+use icu_provider_adapters::fallback::{LocaleFallbackProvider, LocaleFallbacker};
use rustc_data_structures::sync::Lrc;
use rustc_macros::{fluent_messages, Decodable, Encodable};
use rustc_span::Span;
#[cfg(not(parallel_compiler))]
use intl_memoizer::IntlLangMemoizer;
-pub use fluent_bundle::{self, FluentArgs, FluentError, FluentValue};
-
+pub use fluent_bundle::{self, types::FluentType, FluentArgs, FluentError, FluentValue};
pub use unic_langid::{langid, LanguageIdentifier};
// Generates `DEFAULT_LOCALE_RESOURCES` static and `fluent_generated` module.
errors => "../locales/en-US/errors.ftl",
expand => "../locales/en-US/expand.ftl",
hir_analysis => "../locales/en-US/hir_analysis.ftl",
+ hir_typeck => "../locales/en-US/hir_typeck.ftl",
infer => "../locales/en-US/infer.ftl",
interface => "../locales/en-US/interface.ftl",
lint => "../locales/en-US/lint.ftl",
plugin_impl => "../locales/en-US/plugin_impl.ftl",
privacy => "../locales/en-US/privacy.ftl",
query_system => "../locales/en-US/query_system.ftl",
+ resolve => "../locales/en-US/resolve.ftl",
save_analysis => "../locales/en-US/save_analysis.ftl",
session => "../locales/en-US/session.ftl",
symbol_mangling => "../locales/en-US/symbol_mangling.ftl",
MultiSpan::from_spans(spans)
}
}
+
+fn icu_locale_from_unic_langid(lang: LanguageIdentifier) -> Option<icu_locid::Locale> {
+ icu_locid::Locale::try_from_bytes(lang.to_string().as_bytes()).ok()
+}
+
+pub fn fluent_value_from_str_list_sep_by_and<'source>(
+ l: Vec<Cow<'source, str>>,
+) -> FluentValue<'source> {
+ // Fluent requires 'static value here for its AnyEq usages.
+ #[derive(Clone, PartialEq, Debug)]
+ struct FluentStrListSepByAnd(Vec<String>);
+
+ impl FluentType for FluentStrListSepByAnd {
+ fn duplicate(&self) -> Box<dyn FluentType + Send> {
+ Box::new(self.clone())
+ }
+
+ fn as_string(&self, intls: &intl_memoizer::IntlLangMemoizer) -> Cow<'static, str> {
+ let result = intls
+ .with_try_get::<MemoizableListFormatter, _, _>((), |list_formatter| {
+ list_formatter.format_to_string(self.0.iter())
+ })
+ .unwrap();
+ Cow::Owned(result)
+ }
+
+ #[cfg(not(parallel_compiler))]
+ fn as_string_threadsafe(
+ &self,
+ _intls: &intl_memoizer::concurrent::IntlLangMemoizer,
+ ) -> Cow<'static, str> {
+ unreachable!("`as_string_threadsafe` is not used in non-parallel rustc")
+ }
+
+ #[cfg(parallel_compiler)]
+ fn as_string_threadsafe(
+ &self,
+ intls: &intl_memoizer::concurrent::IntlLangMemoizer,
+ ) -> Cow<'static, str> {
+ let result = intls
+ .with_try_get::<MemoizableListFormatter, _, _>((), |list_formatter| {
+ list_formatter.format_to_string(self.0.iter())
+ })
+ .unwrap();
+ Cow::Owned(result)
+ }
+ }
+
+ struct MemoizableListFormatter(icu_list::ListFormatter);
+
+ impl std::ops::Deref for MemoizableListFormatter {
+ type Target = icu_list::ListFormatter;
+ fn deref(&self) -> &Self::Target {
+ &self.0
+ }
+ }
+
+ impl intl_memoizer::Memoizable for MemoizableListFormatter {
+ type Args = ();
+ type Error = ();
+
+ fn construct(lang: LanguageIdentifier, _args: Self::Args) -> Result<Self, Self::Error>
+ where
+ Self: Sized,
+ {
+ let baked_data_provider = rustc_baked_icu_data::baked_data_provider();
+ let locale_fallbacker =
+ LocaleFallbacker::try_new_with_any_provider(&baked_data_provider)
+ .expect("Failed to create fallback provider");
+ let data_provider =
+ LocaleFallbackProvider::new_with_fallbacker(baked_data_provider, locale_fallbacker);
+ let locale = icu_locale_from_unic_langid(lang)
+ .unwrap_or_else(|| rustc_baked_icu_data::supported_locales::EN);
+ let list_formatter =
+ icu_list::ListFormatter::try_new_and_with_length_with_any_provider(
+ &data_provider,
+ &locale.into(),
+ icu_list::ListLength::Wide,
+ )
+ .expect("Failed to create list formatter");
+
+ Ok(MemoizableListFormatter(list_formatter))
+ }
+ }
+
+ let l = l.into_iter().map(|x| x.into_owned()).collect();
+
+ FluentValue::Custom(Box::new(FluentStrListSepByAnd(l)))
+}
rustc_hir = { path = "../rustc_hir" }
rustc_lint_defs = { path = "../rustc_lint_defs" }
unicode-width = "0.1.4"
-atty = "0.2"
termcolor = "1.0"
annotate-snippets = "0.9"
termize = "0.1.1"
[target.'cfg(windows)'.dependencies]
winapi = { version = "0.3", features = [ "handleapi", "synchapi", "winbase" ] }
+
+[features]
+rustc_use_parallel_compiler = ['rustc_error_messages/rustc_use_parallel_compiler']
SubdiagnosticMessage, Substitution, SubstitutionPart, SuggestionStyle,
};
use rustc_data_structures::fx::FxHashMap;
+use rustc_error_messages::fluent_value_from_str_list_sep_by_and;
use rustc_error_messages::FluentValue;
use rustc_lint_defs::{Applicability, LintExpectationId};
use rustc_span::edition::LATEST_STABLE_EDITION;
pub enum DiagnosticArgValue<'source> {
Str(Cow<'source, str>),
Number(usize),
+ StrListSepByAnd(Vec<Cow<'source, str>>),
}
/// Converts a value of a type into a `DiagnosticArg` (typically a field of an `IntoDiagnostic`
match self {
DiagnosticArgValue::Str(s) => DiagnosticArgValue::Str(Cow::Owned(s.into_owned())),
DiagnosticArgValue::Number(n) => DiagnosticArgValue::Number(n),
+ DiagnosticArgValue::StrListSepByAnd(l) => DiagnosticArgValue::StrListSepByAnd(
+ l.into_iter().map(|s| Cow::Owned(s.into_owned())).collect(),
+ ),
}
}
}
match self {
DiagnosticArgValue::Str(s) => From::from(s),
DiagnosticArgValue::Number(n) => From::from(n),
+ DiagnosticArgValue::StrListSepByAnd(l) => fluent_value_from_str_list_sep_by_and(l),
}
}
}
use rustc_target::spec::{PanicStrategy, SplitDebuginfo, StackProtector, TargetTriple};
use std::borrow::Cow;
use std::fmt;
-use std::fmt::Write;
use std::num::ParseIntError;
use std::path::{Path, PathBuf};
use std::process::ExitStatus;
impl IntoDiagnosticArg for DiagnosticSymbolList {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
- // FIXME: replace the logic here with a real list formatter
- let symbols = match &self.0[..] {
- [symbol] => format!("`{symbol}`"),
- [symbol, last] => {
- format!("`{symbol}` and `{last}`",)
- }
- [symbols @ .., last] => {
- let mut result = String::new();
- for symbol in symbols {
- write!(result, "`{symbol}`, ").unwrap();
- }
- write!(result, "and `{last}`").unwrap();
- result
- }
- [] => unreachable!(),
- };
- DiagnosticArgValue::Str(Cow::Owned(symbols))
+ DiagnosticArgValue::StrListSepByAnd(
+ self.0.into_iter().map(|sym| Cow::Owned(format!("`{sym}`"))).collect(),
+ )
+ }
+}
+
+impl<Id> IntoDiagnosticArg for hir::def::Res<Id> {
+ fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+ DiagnosticArgValue::Str(Cow::Borrowed(self.descr()))
}
}
use rustc_span::hygiene::{ExpnKind, MacroKind};
use std::borrow::Cow;
use std::cmp::{max, min, Reverse};
-use std::io;
use std::io::prelude::*;
+use std::io::{self, IsTerminal};
use std::iter;
use std::path::Path;
use termcolor::{Ansi, BufferWriter, ColorChoice, ColorSpec, StandardStream};
fn to_color_choice(self) -> ColorChoice {
match self {
ColorConfig::Always => {
- if atty::is(atty::Stream::Stderr) {
+ if io::stderr().is_terminal() {
ColorChoice::Always
} else {
ColorChoice::AlwaysAnsi
}
}
ColorConfig::Never => ColorChoice::Never,
- ColorConfig::Auto if atty::is(atty::Stream::Stderr) => ColorChoice::Auto,
+ ColorConfig::Auto if io::stderr().is_terminal() => ColorChoice::Auto,
ColorConfig::Auto => ColorChoice::Never,
}
}
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![feature(drain_filter)]
#![feature(if_let_guard)]
+#![feature(is_terminal)]
#![feature(adt_const_params)]
#![feature(let_chains)]
#![feature(never_type)]
/// When an invalid lifetime e.g. `'2` should be reinterpreted
/// as a char literal in the parser
LifetimeIsChar,
+ /// Maybe there was a typo where a comma was forgotten before
+ /// FRU syntax
+ MaybeFruTypo,
}
fn default_track_diagnostic(_: &Diagnostic) {}
inner.stashed_diagnostics = Default::default();
}
- /// Stash a given diagnostic with the given `Span` and `StashKey` as the key for later stealing.
+ /// Stash a given diagnostic with the given `Span` and [`StashKey`] as the key.
+ /// Retrieve a stashed diagnostic with `steal_diagnostic`.
pub fn stash_diagnostic(&self, span: Span, key: StashKey, diag: Diagnostic) {
let mut inner = self.inner.borrow_mut();
inner.stash((span, key), diag);
}
- /// Steal a previously stashed diagnostic with the given `Span` and `StashKey` as the key.
+ /// Steal a previously stashed diagnostic with the given `Span` and [`StashKey`] as the key.
pub fn steal_diagnostic(&self, span: Span, key: StashKey) -> Option<DiagnosticBuilder<'_, ()>> {
let mut inner = self.inner.borrow_mut();
inner.steal((span, key)).map(|diag| DiagnosticBuilder::new_diagnostic(self, diag))
doctest = false
[dependencies]
-rustc_serialize = { path = "../rustc_serialize" }
-tracing = "0.1"
-rustc_span = { path = "../rustc_span" }
-rustc_ast_pretty = { path = "../rustc_ast_pretty" }
+crossbeam-channel = "0.5.0"
rustc_ast_passes = { path = "../rustc_ast_passes" }
+rustc_ast = { path = "../rustc_ast" }
+rustc_ast_pretty = { path = "../rustc_ast_pretty" }
rustc_attr = { path = "../rustc_attr" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }
rustc_feature = { path = "../rustc_feature" }
+rustc_lexer = { path = "../rustc_lexer" }
rustc_lint_defs = { path = "../rustc_lint_defs" }
rustc_macros = { path = "../rustc_macros" }
-rustc_lexer = { path = "../rustc_lexer" }
rustc_parse = { path = "../rustc_parse" }
+rustc_serialize = { path = "../rustc_serialize" }
rustc_session = { path = "../rustc_session" }
+rustc_span = { path = "../rustc_span" }
smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
-rustc_ast = { path = "../rustc_ast" }
-crossbeam-channel = "0.5.0"
+thin-vec = "0.2.8"
+tracing = "0.1"
let crate_matches = if c.starts_with("allsorts-rental") {
true
} else {
- let mut version = c.trim_start_matches("rental-").split(".");
+ let mut version = c.trim_start_matches("rental-").split('.');
version.next() == Some("0")
&& version.next() == Some("5")
&& version
use crate::base::ExtCtxt;
-
use rustc_ast::attr;
use rustc_ast::ptr::P;
use rustc_ast::{self as ast, AttrVec, BlockCheckMode, Expr, LocalKind, PatKind, UnOp};
use rustc_data_structures::sync::Lrc;
use rustc_span::source_map::Spanned;
use rustc_span::symbol::{kw, sym, Ident, Symbol};
-
use rustc_span::Span;
+use thin_vec::ThinVec;
impl<'a> ExtCtxt<'a> {
pub fn path(&self, span: Span, strs: Vec<Ident>) -> ast::Path {
) -> ast::Path {
assert!(!idents.is_empty());
let add_root = global && !idents[0].is_path_segment_keyword();
- let mut segments = Vec::with_capacity(idents.len() + add_root as usize);
+ let mut segments = ThinVec::with_capacity(idents.len() + add_root as usize);
if add_root {
segments.push(ast::PathSegment::path_root(span));
}
// here, but that's not entirely clear.
self.expr(
span,
- ast::ExprKind::Closure(
- ast::ClosureBinder::NotPresent,
- ast::CaptureBy::Ref,
- ast::Async::No,
- ast::Movability::Movable,
+ ast::ExprKind::Closure(Box::new(ast::Closure {
+ binder: ast::ClosureBinder::NotPresent,
+ capture_clause: ast::CaptureBy::Ref,
+ asyncness: ast::Async::No,
+ movability: ast::Movability::Movable,
fn_decl,
body,
- span,
- ),
+ fn_decl_span: span,
+ })),
)
}
// hacky, but speeds up the `html5ever` benchmark significantly. (Issue
// 68836 suggests a more comprehensive but more complex change to deal with
// this situation.)
- // FIXME(Nilstrieb): Stop recovery from happening on this parser and retry later with recovery if the macro failed to match.
let parser = parser_from_cx(sess, arg.clone(), T::recovery());
// Try each arm's matchers.
let mut tt_parser = TtParser::new(name);
use crate::expand::{AstFragment, AstFragmentKind};
-
use rustc_ast as ast;
use rustc_ast::mut_visit::*;
use rustc_ast::ptr::P;
+use rustc_data_structures::fx::FxHashMap;
use rustc_span::source_map::DUMMY_SP;
use rustc_span::symbol::Ident;
-
use smallvec::{smallvec, SmallVec};
-
-use rustc_data_structures::fx::FxHashMap;
+use thin_vec::ThinVec;
pub fn placeholder(
kind: AstFragmentKind,
) -> AstFragment {
fn mac_placeholder() -> P<ast::MacCall> {
P(ast::MacCall {
- path: ast::Path { span: DUMMY_SP, segments: Vec::new(), tokens: None },
+ path: ast::Path { span: DUMMY_SP, segments: ThinVec::new(), tokens: None },
args: P(ast::MacArgs::Empty),
prior_type_ascription: None,
})
(active, stmt_expr_attributes, "1.6.0", Some(15701), None),
/// Allows lints part of the strict provenance effort.
(active, strict_provenance, "1.61.0", Some(95228), None),
+ /// Allows string patterns to dereference values to match them.
+ (active, string_deref_patterns, "CURRENT_RUSTC_VERSION", Some(87121), None),
/// Allows the use of `#[target_feature]` on safe functions.
(active, target_feature_11, "1.45.0", Some(69098), None),
/// Allows using `#[thread_local]` on `static` items.
NotAsync,
}
+impl IsAsync {
+ pub fn is_async(self) -> bool {
+ self == IsAsync::Async
+ }
+}
+
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, Encodable, Decodable, HashStable_Generic)]
pub enum Defaultness {
Default { has_value: bool },
}
}
+ /// Returns the name of the `LangItem` enum variant.
+ // This method is used by Clippy for internal lints.
+ pub fn variant_name(self) -> &'static str {
+ match self {
+ $( LangItem::$variant => stringify!($variant), )*
+ }
+ }
+
pub fn target(self) -> Target {
match self {
$( LangItem::$variant => $target, )*
TryTraitBranch, sym::branch, branch_fn, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::None;
TryTraitFromYeet, sym::from_yeet, from_yeet_fn, Target::Fn, GenericRequirement::None;
+ PointerSized, sym::pointer_sized, pointer_sized, Target::Trait, GenericRequirement::Exact(0);
+
PollReady, sym::Ready, poll_ready_variant, Target::Variant, GenericRequirement::None;
PollPending, sym::Pending, poll_pending_variant, Target::Variant, GenericRequirement::None;
Range, sym::Range, range_struct, Target::Struct, GenericRequirement::None;
RangeToInclusive, sym::RangeToInclusive, range_to_inclusive_struct, Target::Struct, GenericRequirement::None;
RangeTo, sym::RangeTo, range_to_struct, Target::Struct, GenericRequirement::None;
+
+ String, sym::String, string, Target::Struct, GenericRequirement::None;
}
pub enum GenericRequirement {
/// (e.g., resolve) that is translated into a ty-error. This is
/// used to help suppress derived errors typeck might otherwise
/// report.
- fn set_tainted_by_errors(&self);
+ fn set_tainted_by_errors(&self, e: ErrorGuaranteed);
fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, span: Span);
}
}
}
Res::Err => {
- self.set_tainted_by_errors();
- self.tcx().ty_error()
+ let e = self
+ .tcx()
+ .sess
+ .delay_span_bug(path.span, "path with `Res:Err` but no error emitted");
+ self.set_tainted_by_errors(e);
+ self.tcx().ty_error_with_guaranteed(e)
}
_ => span_bug!(span, "unexpected resolution: {:?}", path.res),
}
let misc_cause = traits::ObligationCause::misc(span, hir_id);
- match infcx.at(&misc_cause, param_env).eq(opaque_ty, hidden_ty) {
- Ok(infer_ok) => ocx.register_infer_ok_obligations(infer_ok),
+ match ocx.eq(&misc_cause, param_env, opaque_ty, hidden_ty) {
+ Ok(()) => {}
Err(ty_err) => {
tcx.sess.delay_span_bug(
span,
unnormalized_trait_sig.inputs_and_output.iter().chain(trait_sig.inputs_and_output.iter()),
);
- match infcx.at(&cause, param_env).eq(trait_return_ty, impl_return_ty) {
- Ok(infer::InferOk { value: (), obligations }) => {
- ocx.register_obligations(obligations);
- }
+ match ocx.eq(&cause, param_env, trait_return_ty, impl_return_ty) {
+ Ok(()) => {}
Err(terr) => {
let mut diag = struct_span_err!(
tcx.sess,
// the lifetimes of the return type, but do this after unifying just the
// return types, since we want to avoid duplicating errors from
// `compare_predicate_entailment`.
- match infcx.at(&cause, param_env).eq(trait_fty, impl_fty) {
- Ok(infer::InferOk { value: (), obligations }) => {
- ocx.register_obligations(obligations);
- }
+ match ocx.eq(&cause, param_env, trait_fty, impl_fty) {
+ Ok(()) => {}
Err(terr) => {
// This function gets called during `compare_predicate_entailment` when normalizing a
// signature that contains RPITIT. When the method signatures don't match, we have to
// Suggestion to change output type. We do not suggest in `async` functions
// to avoid complex logic or incorrect output.
match tcx.hir().expect_impl_item(impl_m.def_id.expect_local()).kind {
- ImplItemKind::Fn(ref sig, _)
- if sig.header.asyncness == hir::IsAsync::NotAsync =>
- {
+ ImplItemKind::Fn(ref sig, _) if !sig.header.asyncness.is_async() => {
let msg = "change the output type to match the trait";
let ap = Applicability::MachineApplicable;
match sig.decl.output {
ty
}
- fn set_tainted_by_errors(&self) {
+ fn set_tainted_by_errors(&self, _: ErrorGuaranteed) {
// There's no obvious place to track this, so just let it go.
}
&& let Some(trait_path_segment) = path.segments.get(0) {
let num_generic_args_supplied_to_trait = trait_path_segment.args().num_generic_params();
- if num_assoc_fn_excess_args == num_trait_generics_except_self - num_generic_args_supplied_to_trait {
+ if num_generic_args_supplied_to_trait + num_assoc_fn_excess_args == num_trait_generics_except_self
+ {
if let Some(span) = self.gen_args.span_ext()
&& let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) {
let sugg = vec![
use crate::type_error_struct;
use rustc_errors::{struct_span_err, Applicability, DelayDm, DiagnosticBuilder, ErrorGuaranteed};
use rustc_hir as hir;
+use rustc_macros::{TypeFoldable, TypeVisitable};
use rustc_middle::mir::Mutability;
use rustc_middle::ty::adjustment::AllowTwoPhase;
use rustc_middle::ty::cast::{CastKind, CastTy};
/// The kind of pointer and associated metadata (thin, length or vtable) - we
/// only allow casts between fat pointers if their metadata have the same
/// kind.
-#[derive(Copy, Clone, PartialEq, Eq)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, TypeVisitable, TypeFoldable)]
enum PointerKind<'tcx> {
/// No metadata attached, ie pointer to sized type or foreign type
Thin,
/// Slice
Length,
/// The unsize info of this projection
- OfProjection(&'tcx ty::ProjectionTy<'tcx>),
+ OfProjection(ty::ProjectionTy<'tcx>),
/// The unsize info of this opaque ty
OfOpaque(DefId, SubstsRef<'tcx>),
/// The unsize info of this parameter
- OfParam(&'tcx ty::ParamTy),
+ OfParam(ty::ParamTy),
}
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Pointers to foreign types are thin, despite being unsized
ty::Foreign(..) => Some(PointerKind::Thin),
// We should really try to normalize here.
- ty::Projection(ref pi) => Some(PointerKind::OfProjection(pi)),
+ ty::Projection(pi) => Some(PointerKind::OfProjection(pi)),
ty::Opaque(def_id, substs) => Some(PointerKind::OfOpaque(def_id, substs)),
- ty::Param(ref p) => Some(PointerKind::OfParam(p)),
+ ty::Param(p) => Some(PointerKind::OfParam(p)),
// Insufficient type information.
ty::Placeholder(..) | ty::Bound(..) | ty::Infer(_) => None,
}
// vtable kinds must match
- if cast_kind == expr_kind {
+ if fcx.tcx.erase_regions(cast_kind) == fcx.tcx.erase_regions(expr_kind) {
Ok(CastKind::PtrPtrCast)
} else {
Err(CastError::DifferingKinds)
// Check the obligations of the cast -- for example, when casting
// `usize` to `dyn* Clone + 'static`:
- let obligations = predicates
+ let mut obligations: Vec<_> = predicates
.iter()
.map(|predicate| {
// For each existential predicate (e.g., `?Self: Clone`) substitute
let predicate = predicate.with_self_ty(self.tcx, a);
Obligation::new(self.tcx, self.cause.clone(), self.param_env, predicate)
})
- // Enforce the region bound (e.g., `usize: 'static`, in our example).
- .chain([Obligation::new(
+ .chain([
+ // Enforce the region bound (e.g., `usize: 'static`, in our example).
+ Obligation::new(
+ self.tcx,
+ self.cause.clone(),
+ self.param_env,
+ ty::Binder::dummy(ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(
+ a, b_region,
+ ))),
+ ),
+ ])
+ .collect();
+
+ // Enforce that the type is `usize`/pointer-sized. For now, only those
+ // can be coerced to `dyn*`, except for `dyn* -> dyn*` upcasts.
+ if !a.is_dyn_star() {
+ obligations.push(Obligation::new(
self.tcx,
self.cause.clone(),
self.param_env,
- self.tcx.mk_predicate(ty::Binder::dummy(ty::PredicateKind::TypeOutlives(
- ty::OutlivesPredicate(a, b_region),
- ))),
- )])
- .collect();
+ ty::Binder::dummy(ty::TraitRef::new(
+ self.tcx.require_lang_item(hir::LangItem::PointerSized, Some(self.cause.span)),
+ self.tcx.mk_substs_trait(a, &[]),
+ ))
+ .to_poly_trait_predicate(),
+ ));
+ }
Ok(InferOk {
value: (vec![Adjustment { kind: Adjust::DynStar, target: b }], b),
// Mark that we've failed to coerce the types here to suppress
// any superfluous errors we might encounter while trying to
// emit or provide suggestions on how to fix the initial error.
- fcx.set_tainted_by_errors();
+ fcx.set_tainted_by_errors(
+ fcx.tcx.sess.delay_span_bug(cause.span, "coercion error but no error emitted"),
+ );
let (expected, found) = if label_expression_as_expected {
// In the case where this is a "forced unit", like
// `break`, we want to call the `()` "expected"
Err(e) => e,
};
- self.set_tainted_by_errors();
+ self.set_tainted_by_errors(self.tcx.sess.delay_span_bug(
+ expr.span,
+ "`TypeError` when attempting coercion but no error emitted",
+ ));
let expr = expr.peel_drop_temps();
let cause = self.misc(expr.span);
let expr_ty = self.resolve_vars_with_obligations(checked_ty);
//! Errors emitted by `rustc_hir_analysis`.
+use rustc_errors::{AddToDiagnostic, Applicability, Diagnostic, MultiSpan, SubdiagnosticMessage};
use rustc_macros::{Diagnostic, Subdiagnostic};
use rustc_middle::ty::Ty;
use rustc_span::{symbol::Ident, Span};
pub span: Span,
pub method_name: String,
}
+
+pub struct TypeMismatchFruTypo {
+ /// Span of the LHS of the range
+ pub expr_span: Span,
+ /// Span of the `..RHS` part of the range
+ pub fru_span: Span,
+ /// Rendered expression of the RHS of the range
+ pub expr: Option<String>,
+}
+
+impl AddToDiagnostic for TypeMismatchFruTypo {
+ fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F)
+ where
+ F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
+ {
+ diag.set_arg("expr", self.expr.as_deref().unwrap_or("NONE"));
+
+ // Only explain that `a ..b` is a range if it's split up
+ if self.expr_span.between(self.fru_span).is_empty() {
+ diag.span_note(
+ self.expr_span.to(self.fru_span),
+ rustc_errors::fluent::hir_typeck_fru_note,
+ );
+ } else {
+ let mut multispan: MultiSpan = vec![self.expr_span, self.fru_span].into();
+ multispan.push_span_label(self.expr_span, rustc_errors::fluent::hir_typeck_fru_expr);
+ multispan.push_span_label(self.fru_span, rustc_errors::fluent::hir_typeck_fru_expr2);
+ diag.span_note(multispan, rustc_errors::fluent::hir_typeck_fru_note);
+ }
+
+ diag.span_suggestion(
+ self.expr_span.shrink_to_hi(),
+ rustc_errors::fluent::hir_typeck_fru_suggestion,
+ ", ",
+ Applicability::MaybeIncorrect,
+ );
+ }
+}
use crate::cast;
use crate::coercion::CoerceMany;
use crate::coercion::DynamicCoerceMany;
+use crate::errors::TypeMismatchFruTypo;
use crate::errors::{AddressOfTemporaryTaken, ReturnStmtOutsideOfFnBody, StructExprNonExhaustive};
use crate::errors::{
FieldMultiplySpecifiedInInitializer, FunctionalRecordUpdateOnNonStruct,
self.resolve_ty_and_res_fully_qualified_call(qpath, expr.hir_id, expr.span);
let ty = match res {
Res::Err => {
- self.set_tainted_by_errors();
- tcx.ty_error()
+ let e =
+ self.tcx.sess.delay_span_bug(qpath.span(), "`Res::Err` but no error emitted");
+ self.set_tainted_by_errors(e);
+ tcx.ty_error_with_guaranteed(e)
}
Res::Def(DefKind::Ctor(_, CtorKind::Fictive), _) => {
- report_unexpected_variant_res(tcx, res, qpath, expr.span);
- tcx.ty_error()
+ let e = report_unexpected_variant_res(tcx, res, qpath, expr.span);
+ tcx.ty_error_with_guaranteed(e)
}
_ => self.instantiate_value_path(segs, opt_ty, res, expr.span, expr.hir_id).0,
};
self.demand_coerce_diag(&field.expr, ty, field_type, None, AllowTwoPhase::No);
if let Some(mut diag) = diag {
- if idx == ast_fields.len() - 1 && remaining_fields.is_empty() {
- self.suggest_fru_from_range(field, variant, substs, &mut diag);
+ if idx == ast_fields.len() - 1 {
+ if remaining_fields.is_empty() {
+ self.suggest_fru_from_range(field, variant, substs, &mut diag);
+ diag.emit();
+ } else {
+ diag.stash(field.span, StashKey::MaybeFruTypo);
+ }
+ } else {
+ diag.emit();
}
- diag.emit();
}
}
.map(|adt| adt.did())
!= range_def_id
{
- let instead = self
+ // Suppress any range expr type mismatches
+ if let Some(mut diag) = self
+ .tcx
+ .sess
+ .diagnostic()
+ .steal_diagnostic(last_expr_field.span, StashKey::MaybeFruTypo)
+ {
+ diag.delay_as_bug();
+ }
+
+ // Use a (somewhat arbitrary) filtering heuristic to avoid printing
+ // expressions that are either too long, or have control character
+ //such as newlines in them.
+ let expr = self
.tcx
.sess
.source_map()
.span_to_snippet(range_end.expr.span)
- .map(|s| format!(" from `{s}`"))
- .unwrap_or_default();
- err.span_suggestion(
- range_start.span.shrink_to_hi(),
- &format!("to set the remaining fields{instead}, separate the last named field with a comma"),
- ",",
- Applicability::MaybeIncorrect,
- );
+ .ok()
+ .filter(|s| s.len() < 25 && !s.contains(|c: char| c.is_control()));
+
+ let fru_span = self
+ .tcx
+ .sess
+ .source_map()
+ .span_extend_while(range_start.span, |c| c.is_whitespace())
+ .unwrap_or(range_start.span).shrink_to_hi().to(range_end.span);
+
+ err.subdiagnostic(TypeMismatchFruTypo {
+ expr_span: range_start.span,
+ fru_span,
+ expr,
+ });
}
}
expr_span: Span,
) {
if variant.is_recovered() {
- self.set_tainted_by_errors();
+ self.set_tainted_by_errors(
+ self.tcx
+ .sess
+ .delay_span_bug(expr_span, "parser recovered but no error was emitted"),
+ );
return;
}
let mut err = self.err_ctxt().type_error_struct_with_diag(
// type, `?T` is not considered unsolved, but `?I` is. The
// same is true for float variables.)
let fallback = match ty.kind() {
- _ if self.is_tainted_by_errors() => self.tcx.ty_error(),
+ _ if let Some(e) = self.tainted_by_errors() => self.tcx.ty_error_with_guaranteed(e),
ty::Infer(ty::IntVar(_)) => self.tcx.types.i32,
ty::Infer(ty::FloatVar(_)) => self.tcx.types.f64,
_ => match diverging_fallback.get(&ty) {
debug!("write_ty({:?}, {:?}) in fcx {}", id, self.resolve_vars_if_possible(ty), self.tag());
self.typeck_results.borrow_mut().node_types_mut().insert(id, ty);
- if ty.references_error() {
- self.set_tainted_by_errors();
+ if let Err(e) = ty.error_reported() {
+ self.set_tainted_by_errors(e);
}
}
pub fn node_ty(&self, id: hir::HirId) -> Ty<'tcx> {
match self.typeck_results.borrow().node_types().get(id) {
Some(&t) => t,
- None if self.is_tainted_by_errors() => self.tcx.ty_error(),
+ None if let Some(e) = self.tainted_by_errors() => self.tcx.ty_error_with_guaranteed(e),
None => {
bug!(
"no type for node {}: {} in fcx {}",
pub fn node_ty_opt(&self, id: hir::HirId) -> Option<Ty<'tcx>> {
match self.typeck_results.borrow().node_types().get(id) {
Some(&t) => Some(t),
- None if self.is_tainted_by_errors() => Some(self.tcx.ty_error()),
+ None if let Some(e) = self.tainted_by_errors() => Some(self.tcx.ty_error_with_guaranteed(e)),
None => None,
}
}
explicit_late_bound = ExplicitLateBound::Yes;
}
- if let Err(GenericArgCountMismatch { reported: Some(_), .. }) = arg_count.correct {
+ if let Err(GenericArgCountMismatch { reported: Some(e), .. }) = arg_count.correct {
infer_args_for_err.insert(index);
- self.set_tainted_by_errors(); // See issue #53251.
+ self.set_tainted_by_errors(e); // See issue #53251.
}
}
if !ty.is_ty_var() {
ty
} else {
- if !self.is_tainted_by_errors() {
+ let e = self.tainted_by_errors().unwrap_or_else(|| {
self.err_ctxt()
.emit_inference_failure_err((**self).body_id, sp, ty.into(), E0282, true)
- .emit();
- }
- let err = self.tcx.ty_error();
+ .emit()
+ });
+ let err = self.tcx.ty_error_with_guaranteed(e);
self.demand_suptype(sp, err, ty);
err
}
tys.into_iter().any(|ty| ty.references_error() || ty.is_ty_var())
}
- self.set_tainted_by_errors();
let tcx = self.tcx;
+ // FIXME: taint after emitting errors and pass through an `ErrorGuaranteed`
+ self.set_tainted_by_errors(
+ tcx.sess.delay_span_bug(call_span, "no errors reported for args"),
+ );
// Get the argument span in the context of the call span so that
// suggestions and labels are (more) correct when an arg is a
let (def, ty) = self.finish_resolving_struct_path(qpath, path_span, hir_id);
let variant = match def {
Res::Err => {
- self.set_tainted_by_errors();
+ self.set_tainted_by_errors(
+ self.tcx.sess.delay_span_bug(path_span, "`Res::Err` but no error emitted"),
+ );
return None;
}
Res::Def(DefKind::Variant, _) => match ty.kind() {
mod suggestions;
pub use _impl::*;
+use rustc_errors::ErrorGuaranteed;
pub use suggestions::*;
use crate::coercion::DynamicCoerceMany;
}
}
- fn set_tainted_by_errors(&self) {
- self.infcx.set_tainted_by_errors()
+ fn set_tainted_by_errors(&self, e: ErrorGuaranteed) {
+ self.infcx.set_tainted_by_errors(e)
}
fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, _span: Span) {
ref_cnt += 1;
}
if let ty::Adt(adt, _) = peeled.kind()
- && self.tcx.is_diagnostic_item(sym::String, adt.did())
+ && Some(adt.did()) == self.tcx.lang_items().string()
{
err.span_suggestion_verbose(
expr.span.shrink_to_hi(),
use crate::coercion::DynamicCoerceMany;
use crate::gather_locals::GatherLocalsVisitor;
use rustc_data_structures::unord::UnordSet;
-use rustc_errors::{struct_span_err, MultiSpan};
+use rustc_errors::{struct_span_err, ErrorGuaranteed, MultiSpan};
use rustc_hir as hir;
use rustc_hir::def::Res;
use rustc_hir::intravisit::Visitor;
fcx.select_all_obligations_or_error();
- if !fcx.infcx.is_tainted_by_errors() {
+ if let None = fcx.infcx.tainted_by_errors() {
fcx.check_transmutes();
}
}
}
-fn report_unexpected_variant_res(tcx: TyCtxt<'_>, res: Res, qpath: &hir::QPath<'_>, span: Span) {
+fn report_unexpected_variant_res(
+ tcx: TyCtxt<'_>,
+ res: Res,
+ qpath: &hir::QPath<'_>,
+ span: Span,
+) -> ErrorGuaranteed {
struct_span_err!(
tcx.sess,
span,
res.descr(),
rustc_hir_pretty::qpath_to_string(qpath),
)
- .emit();
+ .emit()
}
/// Controls whether the arguments are tupled. This is used for the call
}
fn is_tainted_by_errors(&self) -> bool {
- self.infcx.is_tainted_by_errors()
+ self.infcx.tainted_by_errors().is_some()
}
fn resolve_type_vars_or_error(
let report_candidates = |span: Span,
err: &mut Diagnostic,
sources: &mut Vec<CandidateSource>,
- sugg_span: Span| {
+ sugg_span: Option<Span>| {
sources.sort();
sources.dedup();
// Dynamic limit to avoid hiding just one candidate, which is silly.
} else {
err.note(¬e_str);
}
- if let Some(trait_ref) = self.tcx.impl_trait_ref(impl_did) {
+ if let Some(sugg_span) = sugg_span
+ && let Some(trait_ref) = self.tcx.impl_trait_ref(impl_did) {
let path = self.tcx.def_path_str(trait_ref.def_id);
let ty = match item.kind {
err.span_note(item_span, msg);
None
};
- let path = self.tcx.def_path_str(trait_did);
- print_disambiguation_help(
- item_name,
- args,
- err,
- path,
- rcvr_ty,
- item.kind,
- item.def_id,
- sugg_span,
- idx,
- self.tcx.sess.source_map(),
- item.fn_has_self_parameter,
- );
+ if let Some(sugg_span) = sugg_span {
+ let path = self.tcx.def_path_str(trait_did);
+ print_disambiguation_help(
+ item_name,
+ args,
+ err,
+ path,
+ rcvr_ty,
+ item.kind,
+ item.def_id,
+ sugg_span,
+ idx,
+ self.tcx.sess.source_map(),
+ item.fn_has_self_parameter,
+ );
+ }
}
}
}
sugg_span,
);
- report_candidates(span, &mut err, &mut static_candidates, sugg_span);
+ report_candidates(span, &mut err, &mut static_candidates, None);
} else if static_candidates.len() > 1 {
- report_candidates(span, &mut err, &mut static_candidates, sugg_span);
+ report_candidates(span, &mut err, &mut static_candidates, Some(sugg_span));
}
let mut bound_spans = vec![];
ty.is_str()
|| matches!(
ty.kind(),
- ty::Adt(adt, _) if self.tcx.is_diagnostic_item(sym::String, adt.did())
+ ty::Adt(adt, _) if Some(adt.did()) == self.tcx.lang_items().string()
)
}
- ty::Adt(adt, _) => self.tcx.is_diagnostic_item(sym::String, adt.did()),
+ ty::Adt(adt, _) => Some(adt.did()) == self.tcx.lang_items().string(),
_ => false,
};
if is_string_or_ref_str && item_name.name == sym::iter {
);
err.span_label(item_name.span, format!("multiple `{}` found", item_name));
- report_candidates(span, &mut err, &mut sources, sugg_span);
+ report_candidates(span, &mut err, &mut sources, Some(sugg_span));
err.emit();
}
| ty::Str
| ty::Projection(_)
| ty::Param(_) => format!("{deref_ty}"),
- // we need to test something like <&[_]>::len
+ // we need to test something like <&[_]>::len or <(&[u32])>::len
// and Vec::function();
- // <&[_]>::len doesn't need an extra "<>" between
+ // <&[_]>::len or <&[u32]>::len doesn't need an extra "<>" between
// but for Adt type like Vec::function()
// we would suggest <[_]>::function();
- _ if self.tcx.sess.source_map().span_wrapped_by_angle_bracket(ty.span) => format!("{deref_ty}"),
+ _ if self.tcx.sess.source_map().span_wrapped_by_angle_or_parentheses(ty.span) => format!("{deref_ty}"),
_ => format!("<{deref_ty}>"),
};
err.span_suggestion_verbose(
let rm_borrow_msg = "remove the borrow to obtain an owned `String`";
let to_owned_msg = "create an owned `String` from a string reference";
+ let string_type = self.tcx.lang_items().string();
let is_std_string = |ty: Ty<'tcx>| {
- ty.ty_adt_def()
- .map_or(false, |ty_def| self.tcx.is_diagnostic_item(sym::String, ty_def.did()))
+ ty.ty_adt_def().map_or(false, |ty_def| Some(ty_def.did()) == string_type)
};
match (lhs_ty.kind(), rhs_ty.kind()) {
}
}
+ if self.tcx.features().string_deref_patterns && let hir::ExprKind::Lit(Spanned { node: ast::LitKind::Str(..), .. }) = lt.kind {
+ let tcx = self.tcx;
+ let expected = self.resolve_vars_if_possible(expected);
+ pat_ty = match expected.kind() {
+ ty::Adt(def, _) if Some(def.did()) == tcx.lang_items().string() => expected,
+ ty::Str => tcx.mk_static_str(),
+ _ => pat_ty,
+ };
+ }
+
// Somewhat surprising: in this case, the subtyping relation goes the
// opposite way as the other cases. Actually what we really want is not
// a subtyping relation at all but rather that there exists a LUB
let (res, opt_ty, segments) = path_resolution;
match res {
Res::Err => {
- self.set_tainted_by_errors();
- return tcx.ty_error();
+ let e = tcx.sess.delay_span_bug(qpath.span(), "`Res::Err` but no error emitted");
+ self.set_tainted_by_errors(e);
+ return tcx.ty_error_with_guaranteed(e);
}
Res::Def(DefKind::AssocFn | DefKind::Ctor(_, CtorKind::Fictive | CtorKind::Fn), _) => {
- report_unexpected_variant_res(tcx, res, qpath, pat.span);
- return tcx.ty_error();
+ let e = report_unexpected_variant_res(tcx, res, qpath, pat.span);
+ return tcx.ty_error_with_guaranteed(e);
}
Res::SelfCtor(..)
| Res::Def(
ti: TopInfo<'tcx>,
) -> Ty<'tcx> {
let tcx = self.tcx;
- let on_error = || {
+ let on_error = |e| {
for pat in subpats {
- self.check_pat(pat, tcx.ty_error(), def_bm, ti);
+ self.check_pat(pat, tcx.ty_error_with_guaranteed(e), def_bm, ti);
}
};
let report_unexpected_res = |res: Res| {
err.span_label(pat.span, "not a tuple variant or struct");
}
}
- err.emit();
- on_error();
+ let e = err.emit();
+ on_error(e);
+ e
};
// Resolve the path and check the definition for errors.
let (res, opt_ty, segments) =
self.resolve_ty_and_res_fully_qualified_call(qpath, pat.hir_id, pat.span);
if res == Res::Err {
- self.set_tainted_by_errors();
- on_error();
- return self.tcx.ty_error();
+ let e = tcx.sess.delay_span_bug(pat.span, "`Res:Err` but no error emitted");
+ self.set_tainted_by_errors(e);
+ on_error(e);
+ return tcx.ty_error_with_guaranteed(e);
}
// Type-check the path.
let (pat_ty, res) =
self.instantiate_value_path(segments, opt_ty, res, pat.span, pat.hir_id);
if !pat_ty.is_fn() {
- report_unexpected_res(res);
- return tcx.ty_error();
+ let e = report_unexpected_res(res);
+ return tcx.ty_error_with_guaranteed(e);
}
let variant = match res {
Res::Err => {
- self.set_tainted_by_errors();
- on_error();
- return tcx.ty_error();
+ let e = tcx.sess.delay_span_bug(pat.span, "`Res::Err` but no error emitted");
+ self.set_tainted_by_errors(e);
+ on_error(e);
+ return tcx.ty_error_with_guaranteed(e);
}
Res::Def(DefKind::AssocConst | DefKind::AssocFn, _) => {
- report_unexpected_res(res);
- return tcx.ty_error();
+ let e = report_unexpected_res(res);
+ return tcx.ty_error_with_guaranteed(e);
}
Res::Def(DefKind::Ctor(_, CtorKind::Fn), _) => tcx.expect_variant_res(res),
_ => bug!("unexpected pattern resolution: {:?}", res),
}
} else {
// Pattern has wrong number of fields.
- self.e0023(pat.span, res, qpath, subpats, &variant.fields, expected, had_err);
- on_error();
- return tcx.ty_error();
+ let e = self.e0023(pat.span, res, qpath, subpats, &variant.fields, expected, had_err);
+ on_error(e);
+ return tcx.ty_error_with_guaranteed(e);
}
pat_ty
}
fields: &'tcx [ty::FieldDef],
expected: Ty<'tcx>,
had_err: bool,
- ) {
+ ) -> ErrorGuaranteed {
let subpats_ending = pluralize!(subpats.len());
let fields_ending = pluralize!(fields.len());
}
}
- err.emit();
+ err.emit()
}
fn check_pat_tuple(
wbcx.typeck_results.treat_byte_string_as_slice =
mem::take(&mut self.typeck_results.borrow_mut().treat_byte_string_as_slice);
- if self.is_tainted_by_errors() {
- // FIXME(eddyb) keep track of `ErrorGuaranteed` from where the error was emitted.
- wbcx.typeck_results.tainted_by_errors =
- Some(ErrorGuaranteed::unchecked_claim_error_was_emitted());
+ if let Some(e) = self.tainted_by_errors() {
+ wbcx.typeck_results.tainted_by_errors = Some(e);
}
debug!("writeback: typeck results for {:?} are {:#?}", item_def_id, wbcx.typeck_results);
// We may have introduced e.g. `ty::Error`, if inference failed, make sure
// to mark the `TypeckResults` as tainted in that case, so that downstream
// users of the typeck results don't produce extra errors, or worse, ICEs.
- if resolver.replaced_with_error {
- // FIXME(eddyb) keep track of `ErrorGuaranteed` from where the error was emitted.
- self.typeck_results.tainted_by_errors =
- Some(ErrorGuaranteed::unchecked_claim_error_was_emitted());
+ if let Some(e) = resolver.replaced_with_error {
+ self.typeck_results.tainted_by_errors = Some(e);
}
x
span: &'cx dyn Locatable,
body: &'tcx hir::Body<'tcx>,
- /// Set to `true` if any `Ty` or `ty::Const` had to be replaced with an `Error`.
- replaced_with_error: bool,
+ /// Set to `Some` if any `Ty` or `ty::Const` had to be replaced with an `Error`.
+ replaced_with_error: Option<ErrorGuaranteed>,
}
impl<'cx, 'tcx> Resolver<'cx, 'tcx> {
span: &'cx dyn Locatable,
body: &'tcx hir::Body<'tcx>,
) -> Resolver<'cx, 'tcx> {
- Resolver { tcx: fcx.tcx, infcx: fcx, span, body, replaced_with_error: false }
+ Resolver { tcx: fcx.tcx, infcx: fcx, span, body, replaced_with_error: None }
}
- fn report_error(&self, p: impl Into<ty::GenericArg<'tcx>>) {
- if !self.tcx.sess.has_errors().is_some() {
- self.infcx
+ fn report_error(&self, p: impl Into<ty::GenericArg<'tcx>>) -> ErrorGuaranteed {
+ match self.tcx.sess.has_errors() {
+ Some(e) => e,
+ None => self
+ .infcx
.err_ctxt()
.emit_inference_failure_err(
Some(self.body.id()),
E0282,
false,
)
- .emit();
+ .emit(),
}
}
}
}
Err(_) => {
debug!("Resolver::fold_ty: input type `{:?}` not fully resolvable", t);
- self.report_error(t);
- self.replaced_with_error = true;
- self.tcx().ty_error()
+ let e = self.report_error(t);
+ self.replaced_with_error = Some(e);
+ self.tcx().ty_error_with_guaranteed(e)
}
}
}
Ok(ct) => self.tcx.erase_regions(ct),
Err(_) => {
debug!("Resolver::fold_const: input const `{:?}` not fully resolvable", ct);
- self.report_error(ct);
- self.replaced_with_error = true;
- self.tcx().const_error(ct.ty())
+ let e = self.report_error(ct);
+ self.replaced_with_error = Some(e);
+ self.tcx().const_error_with_guaranteed(ct.ty(), e)
}
}
}
use rustc_middle::ty::{self, GenericParamDefKind, InferConst, Ty, TyCtxt};
use rustc_middle::ty::{ConstVid, FloatVid, IntVid, TyVid};
use rustc_span::symbol::Symbol;
-use rustc_span::{Span, DUMMY_SP};
+use rustc_span::Span;
use std::cell::{Cell, RefCell};
use std::fmt;
/// reporting errors that often occur as a result of earlier
/// errors, but where it's hard to be 100% sure (e.g., unresolved
/// inference variables, regionck errors).
- pub fn is_tainted_by_errors(&self) -> bool {
+ #[must_use = "this method does not have any side effects"]
+ pub fn tainted_by_errors(&self) -> Option<ErrorGuaranteed> {
debug!(
"is_tainted_by_errors(err_count={}, err_count_on_creation={}, \
tainted_by_errors={})",
self.tainted_by_errors.get().is_some()
);
+ if let Some(e) = self.tainted_by_errors.get() {
+ return Some(e);
+ }
+
if self.tcx.sess.err_count() > self.err_count_on_creation {
- return true; // errors reported since this infcx was made
+ // errors reported since this infcx was made
+ let e = self.tcx.sess.has_errors().unwrap();
+ self.set_tainted_by_errors(e);
+ return Some(e);
}
- self.tainted_by_errors.get().is_some()
+
+ None
}
/// Set the "tainted by errors" flag to true. We call this when we
/// observe an error from a prior pass.
- pub fn set_tainted_by_errors(&self) {
- debug!("set_tainted_by_errors()");
- self.tainted_by_errors.set(Some(
- self.tcx.sess.delay_span_bug(DUMMY_SP, "`InferCtxt` incorrectly tainted by errors"),
- ));
+ pub fn set_tainted_by_errors(&self, e: ErrorGuaranteed) {
+ debug!("set_tainted_by_errors(ErrorGuaranteed)");
+ self.tainted_by_errors.set(Some(e));
}
pub fn skip_region_resolution(&self) {
let mut inner = self.inner.borrow_mut();
let inner = &mut *inner;
assert!(
- self.is_tainted_by_errors() || inner.region_obligations.is_empty(),
+ self.tainted_by_errors().is_some() || inner.region_obligations.is_empty(),
"region_obligations not empty: {:#?}",
inner.region_obligations
);
) {
let errors = self.resolve_regions(outlives_env);
- if !self.is_tainted_by_errors() {
+ if let None = self.tainted_by_errors() {
// As a heuristic, just skip reporting region errors
// altogether if other errors have been reported while
// this infcx was in use. This is totally hokey but
self.ambient_variance_info = self.ambient_variance_info.xform(info);
debug!(?self.ambient_variance);
-
- let r = self.relate(a, b)?;
+ // In a bivariant context this always succeeds.
+ let r =
+ if self.ambient_variance == ty::Variance::Bivariant { a } else { self.relate(a, b)? };
self.ambient_variance = old_ambient_variance;
Ok(a)
}
- (&ty::Error(_), _) | (_, &ty::Error(_)) => {
- infcx.set_tainted_by_errors();
- Ok(self.tcx().ty_error())
+ (&ty::Error(e), _) | (_, &ty::Error(e)) => {
+ infcx.set_tainted_by_errors(e);
+ Ok(self.tcx().ty_error_with_guaranteed(e))
}
(&ty::Opaque(a_def_id, _), &ty::Opaque(b_def_id, _)) if a_def_id == b_def_id => {
[features]
llvm = ['rustc_codegen_llvm']
-rustc_use_parallel_compiler = ['rayon', 'rustc-rayon-core', 'rustc_query_impl/rustc_use_parallel_compiler']
+rustc_use_parallel_compiler = ['rayon', 'rustc-rayon-core', 'rustc_query_impl/rustc_use_parallel_compiler', 'rustc_errors/rustc_use_parallel_compiler']
// Explicitly check for lints associated with 'closure_id', since
// it does not have a corresponding AST node
match e.kind {
- ast::ExprKind::Closure(_, _, ast::Async::Yes { closure_id, .. }, ..)
+ ast::ExprKind::Closure(box ast::Closure {
+ asyncness: ast::Async::Yes { closure_id, .. },
+ ..
+ })
| ast::ExprKind::Async(_, closure_id, ..) => self.check_id(closure_id),
_ => {}
}
ty::Ref(_, r, _) if *r.kind() == ty::Str,
) || matches!(
ty.ty_adt_def(),
- Some(ty_def) if cx.tcx.is_diagnostic_item(sym::String, ty_def.did()),
+ Some(ty_def) if Some(ty_def.did()) == cx.tcx.lang_items().string(),
);
let infcx = cx.tcx.infer_ctxt().build();
let sm = cx.sess().source_map();
let lo_replace =
if keep_space.0 &&
- let Ok(snip) = sm.span_to_prev_source(lo) && !snip.ends_with(" ") {
+ let Ok(snip) = sm.span_to_prev_source(lo) && !snip.ends_with(' ') {
" ".to_string()
} else {
"".to_string()
let hi_replace =
if keep_space.1 &&
- let Ok(snip) = sm.span_to_next_source(hi) && !snip.starts_with(" ") {
+ let Ok(snip) = sm.span_to_next_source(hi) && !snip.starts_with(' ') {
" ".to_string()
} else {
"".to_string()
ref call_or_other => {
let (args_to_check, ctx) = match *call_or_other {
Call(_, ref args) => (&args[..], UnusedDelimsCtx::FunctionArg),
- MethodCall(_, _, ref args, _) => (&args[..], UnusedDelimsCtx::MethodArg),
+ MethodCall(ref call) => (&call.args[..], UnusedDelimsCtx::MethodArg),
// actual catch-all arm
_ => {
return;
edition = "2021"
[dependencies]
-atty = "0.2"
tracing = "0.1.28"
tracing-subscriber = { version = "0.3.3", default-features = false, features = ["fmt", "env-filter", "smallvec", "parking_lot", "ansi"] }
tracing-tree = "0.2.0"
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
+#![feature(is_terminal)]
use std::env::{self, VarError};
use std::fmt::{self, Display};
-use std::io;
+use std::io::{self, IsTerminal};
use tracing_subscriber::filter::{Directive, EnvFilter, LevelFilter};
use tracing_subscriber::layer::SubscriberExt;
}
pub fn stdout_isatty() -> bool {
- atty::is(atty::Stream::Stdout)
+ io::stdout().is_terminal()
}
pub fn stderr_isatty() -> bool {
- atty::is(atty::Stream::Stderr)
+ io::stderr().is_terminal()
}
#[derive(Debug)]
}
pub(super) fn is_doc_comment(attr: &Attribute) -> bool {
- attr.path.segments.last().unwrap().ident.to_string() == "doc"
+ attr.path.segments.last().unwrap().ident == "doc"
}
edition = "2021"
[lib]
-doctest = false
[dependencies]
bitflags = "1.2.1"
use std::ops::Range;
use std::ptr;
+use either::{Left, Right};
+
use rustc_ast::Mutability;
use rustc_data_structures::intern::Interned;
use rustc_span::DUMMY_SP;
// `to_bits_or_ptr_internal` is the right method because we just want to store this data
// as-is into memory.
let (bytes, provenance) = match val.to_bits_or_ptr_internal(range.size)? {
- Err(val) => {
- let (provenance, offset) = val.into_parts();
+ Right(ptr) => {
+ let (provenance, offset) = ptr.into_parts();
(u128::from(offset.bytes()), Some(provenance))
}
- Ok(data) => (data, None),
+ Left(data) => (data, None),
};
let endian = cx.data_layout().endian;
AlreadyReported(ErrorGuaranteed { .. }) => {
write!(
f,
- "an error has already been reported elsewhere (this sould not usually be printed)"
+ "an error has already been reported elsewhere (this should not usually be printed)"
)
}
Layout(ref err) => write!(f, "{err}"),
use std::convert::{TryFrom, TryInto};
use std::fmt;
+use either::{Either, Left, Right};
+
use rustc_apfloat::{
ieee::{Double, Single},
Float,
pub fn to_bits_or_ptr_internal(
self,
target_size: Size,
- ) -> Result<Result<u128, Pointer<Prov>>, ScalarSizeMismatch> {
+ ) -> Result<Either<u128, Pointer<Prov>>, ScalarSizeMismatch> {
assert_ne!(target_size.bytes(), 0, "you should never look at the bits of a ZST");
Ok(match self {
- Scalar::Int(int) => Ok(int.to_bits(target_size).map_err(|size| {
+ Scalar::Int(int) => Left(int.to_bits(target_size).map_err(|size| {
ScalarSizeMismatch { target_size: target_size.bytes(), data_size: size.bytes() }
})?),
Scalar::Ptr(ptr, sz) => {
data_size: sz.into(),
});
}
- Err(ptr)
+ Right(ptr)
}
})
}
.to_bits_or_ptr_internal(cx.pointer_size())
.map_err(|s| err_ub!(ScalarSizeMismatch(s)))?
{
- Err(ptr) => Ok(ptr.into()),
- Ok(bits) => {
+ Right(ptr) => Ok(ptr.into()),
+ Left(bits) => {
let addr = u64::try_from(bits).unwrap();
Ok(Pointer::from_addr(addr))
}
/// a generic type parameter will panic if you call this method on it:
///
/// ```
+ /// use std::fmt::Debug;
+ ///
/// pub trait Foo<T: Debug> {}
/// ```
///
}
ObjectSafetyViolation::Method(
name,
- MethodViolationCode::ReferencesImplTraitInTrait,
+ MethodViolationCode::ReferencesImplTraitInTrait(_),
_,
) => format!("method `{}` references an `impl Trait` type in its return type", name)
.into(),
+ ObjectSafetyViolation::Method(name, MethodViolationCode::AsyncFn, _) => {
+ format!("method `{}` is `async`", name).into()
+ }
ObjectSafetyViolation::Method(
name,
MethodViolationCode::WhereClauseReferencesSelf,
ReferencesSelfOutput,
/// e.g., `fn foo(&self) -> impl Sized`
- ReferencesImplTraitInTrait,
+ ReferencesImplTraitInTrait(Span),
+
+ /// e.g., `async fn foo(&self)`
+ AsyncFn,
/// e.g., `fn foo(&self) where Self: Clone`
WhereClauseReferencesSelf,
use rustc_target::spec::abi;
use std::borrow::Cow;
+use std::collections::hash_map::DefaultHasher;
use std::fmt;
+use std::hash::{Hash, Hasher};
+use std::path::PathBuf;
+
+use super::print::PrettyPrinter;
#[derive(Clone, Copy, Debug, PartialEq, Eq, TypeFoldable, TypeVisitable, Lift)]
pub struct ExpectedFound<T> {
false
}
+ pub fn short_ty_string(self, ty: Ty<'tcx>) -> (String, Option<PathBuf>) {
+ let length_limit = 50;
+ let type_limit = 4;
+ let regular = FmtPrinter::new(self, hir::def::Namespace::TypeNS)
+ .pretty_print_type(ty)
+ .expect("could not write to `String`")
+ .into_buffer();
+ if regular.len() <= length_limit {
+ return (regular, None);
+ }
+ let short = FmtPrinter::new_with_limit(
+ self,
+ hir::def::Namespace::TypeNS,
+ rustc_session::Limit(type_limit),
+ )
+ .pretty_print_type(ty)
+ .expect("could not write to `String`")
+ .into_buffer();
+ if regular == short {
+ return (regular, None);
+ }
+ // Multiple types might be shortened in a single error, ensure we create a file for each.
+ let mut s = DefaultHasher::new();
+ ty.hash(&mut s);
+ let hash = s.finish();
+ let path = self.output_filenames(()).temp_path_ext(&format!("long-type-{hash}.txt"), None);
+ match std::fs::write(&path, ®ular) {
+ Ok(_) => (short, Some(path)),
+ Err(_) => (regular, None),
+ }
+ }
+
fn format_generic_args(self, args: &[ty::GenericArg<'tcx>]) -> String {
FmtPrinter::new(self, hir::def::Namespace::TypeNS)
.path_generic_args(Ok, args)
//!
//! # Example
//! ```rust
-//! enum Void {}
+//! #![feature(never_type)]
//! mod a {
//! pub mod b {
//! pub struct SecretlyUninhabited {
//! }
//!
//! mod c {
+//! enum Void {}
//! pub struct AlsoSecretlyUninhabited {
//! _priv: Void,
//! }
//! `Foo`.
//!
//! # Example
-//! ```rust
+//! ```ignore(illustrative)
//! let foo_result: Result<T, Foo> = ... ;
//! let Ok(t) = foo_result;
//! ```
}
}
-impl<'tcx> fmt::Display for Instance<'tcx> {
+fn fmt_instance(
+ f: &mut fmt::Formatter<'_>,
+ instance: &Instance<'_>,
+ type_length: rustc_session::Limit,
+) -> fmt::Result {
+ ty::tls::with(|tcx| {
+ let substs = tcx.lift(instance.substs).expect("could not lift for printing");
+
+ let s = FmtPrinter::new_with_limit(tcx, Namespace::ValueNS, type_length)
+ .print_def_path(instance.def_id(), substs)?
+ .into_buffer();
+ f.write_str(&s)
+ })?;
+
+ match instance.def {
+ InstanceDef::Item(_) => Ok(()),
+ InstanceDef::VTableShim(_) => write!(f, " - shim(vtable)"),
+ InstanceDef::ReifyShim(_) => write!(f, " - shim(reify)"),
+ InstanceDef::Intrinsic(_) => write!(f, " - intrinsic"),
+ InstanceDef::Virtual(_, num) => write!(f, " - virtual#{}", num),
+ InstanceDef::FnPtrShim(_, ty) => write!(f, " - shim({})", ty),
+ InstanceDef::ClosureOnceShim { .. } => write!(f, " - shim"),
+ InstanceDef::DropGlue(_, None) => write!(f, " - shim(None)"),
+ InstanceDef::DropGlue(_, Some(ty)) => write!(f, " - shim(Some({}))", ty),
+ InstanceDef::CloneShim(_, ty) => write!(f, " - shim({})", ty),
+ }
+}
+
+pub struct ShortInstance<'a, 'tcx>(pub &'a Instance<'tcx>, pub usize);
+
+impl<'a, 'tcx> fmt::Display for ShortInstance<'a, 'tcx> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- ty::tls::with(|tcx| {
- let substs = tcx.lift(self.substs).expect("could not lift for printing");
- let s = FmtPrinter::new(tcx, Namespace::ValueNS)
- .print_def_path(self.def_id(), substs)?
- .into_buffer();
- f.write_str(&s)
- })?;
+ fmt_instance(f, self.0, rustc_session::Limit(self.1))
+ }
+}
- match self.def {
- InstanceDef::Item(_) => Ok(()),
- InstanceDef::VTableShim(_) => write!(f, " - shim(vtable)"),
- InstanceDef::ReifyShim(_) => write!(f, " - shim(reify)"),
- InstanceDef::Intrinsic(_) => write!(f, " - intrinsic"),
- InstanceDef::Virtual(_, num) => write!(f, " - virtual#{}", num),
- InstanceDef::FnPtrShim(_, ty) => write!(f, " - shim({})", ty),
- InstanceDef::ClosureOnceShim { .. } => write!(f, " - shim"),
- InstanceDef::DropGlue(_, None) => write!(f, " - shim(None)"),
- InstanceDef::DropGlue(_, Some(ty)) => write!(f, " - shim(Some({}))", ty),
- InstanceDef::CloneShim(_, ty) => write!(f, " - shim({})", ty),
- }
+impl<'tcx> fmt::Display for Instance<'tcx> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ ty::tls::with(|tcx| fmt_instance(f, self, tcx.type_length_limit()))
}
}
GeneratorInteriorTypeCause, GlobalCtxt, Lift, OnDiskCache, TyCtxt, TypeckResults, UserType,
UserTypeAnnotationIndex,
};
-pub use self::instance::{Instance, InstanceDef};
+pub use self::instance::{Instance, InstanceDef, ShortInstance};
pub use self::list::List;
pub use self::parameterized::ParameterizedOverTcx;
pub use self::rvalue_scopes::RvalueScopes;
use rustc_hir::definitions::{DefPathData, DefPathDataName, DisambiguatedDefPathData};
use rustc_session::config::TrimmedDefPaths;
use rustc_session::cstore::{ExternCrate, ExternCrateSource};
+use rustc_session::Limit;
use rustc_span::symbol::{kw, Ident, Symbol};
use rustc_target::abi::Size;
use rustc_target::spec::abi::Abi;
region_index: usize,
binder_depth: usize,
printed_type_count: usize,
+ type_length_limit: Limit,
+ truncated: bool,
pub region_highlight_mode: RegionHighlightMode<'tcx>,
impl<'a, 'tcx> FmtPrinter<'a, 'tcx> {
pub fn new(tcx: TyCtxt<'tcx>, ns: Namespace) -> Self {
+ Self::new_with_limit(tcx, ns, tcx.type_length_limit())
+ }
+
+ pub fn new_with_limit(tcx: TyCtxt<'tcx>, ns: Namespace, type_length_limit: Limit) -> Self {
FmtPrinter(Box::new(FmtPrinterData {
tcx,
// Estimated reasonable capacity to allocate upfront based on a few
region_index: 0,
binder_depth: 0,
printed_type_count: 0,
+ type_length_limit,
+ truncated: false,
region_highlight_mode: RegionHighlightMode::new(tcx),
ty_infer_name_resolver: None,
const_infer_name_resolver: None,
}
fn print_type(mut self, ty: Ty<'tcx>) -> Result<Self::Type, Self::Error> {
- let type_length_limit = self.tcx.type_length_limit();
- if type_length_limit.value_within_limit(self.printed_type_count) {
+ if self.type_length_limit.value_within_limit(self.printed_type_count) {
self.printed_type_count += 1;
self.pretty_print_type(ty)
} else {
+ self.truncated = true;
write!(self, "...")?;
Ok(self)
}
define_scoped_cx!(self);
- let possible_names =
- ('a'..='z').rev().map(|s| Symbol::intern(&format!("'{s}"))).collect::<Vec<_>>();
+ let possible_names = ('a'..='z').rev().map(|s| Symbol::intern(&format!("'{s}")));
let mut available_names = possible_names
- .into_iter()
.filter(|name| !self.used_region_names.contains(&name))
.collect::<Vec<_>>();
debug!(?available_names);
[dependencies]
rustc_arena = { path = "../rustc_arena" }
tracing = "0.1"
+either = "1"
rustc_middle = { path = "../rustc_middle" }
rustc_apfloat = { path = "../rustc_apfloat" }
rustc_attr = { path = "../rustc_attr" }
}
TestKind::Eq { value, ty } => {
+ let tcx = self.tcx;
+ if let ty::Adt(def, _) = ty.kind() && Some(def.did()) == tcx.lang_items().string() {
+ if !tcx.features().string_deref_patterns {
+ bug!("matching on `String` went through without enabling string_deref_patterns");
+ }
+ let re_erased = tcx.lifetimes.re_erased;
+ let ref_string = self.temp(tcx.mk_imm_ref(re_erased, ty), test.span);
+ let ref_str_ty = tcx.mk_imm_ref(re_erased, tcx.types.str_);
+ let ref_str = self.temp(ref_str_ty, test.span);
+ let deref = tcx.require_lang_item(LangItem::Deref, None);
+ let method = trait_method(tcx, deref, sym::deref, ty, &[]);
+ let eq_block = self.cfg.start_new_block();
+ self.cfg.push_assign(block, source_info, ref_string, Rvalue::Ref(re_erased, BorrowKind::Shared, place));
+ self.cfg.terminate(
+ block,
+ source_info,
+ TerminatorKind::Call {
+ func: Operand::Constant(Box::new(Constant {
+ span: test.span,
+ user_ty: None,
+ literal: method,
+ })),
+ args: vec![Operand::Move(ref_string)],
+ destination: ref_str,
+ target: Some(eq_block),
+ cleanup: None,
+ from_hir_call: false,
+ fn_span: source_info.span
+ }
+ );
+ self.non_scalar_compare(eq_block, make_target_blocks, source_info, value, ref_str, ref_str_ty);
+ return;
+ }
if !ty.is_scalar() {
// Use `PartialEq::eq` instead of `BinOp::Eq`
// (the binop can only handle primitives)
//! wildcards, see [`SplitWildcard`]; for integer ranges, see [`SplitIntRange`]; for slices, see
//! [`SplitVarLenSlice`].
-use self::Constructor::*;
-use self::SliceKind::*;
+use std::cell::Cell;
+use std::cmp::{self, max, min, Ordering};
+use std::fmt;
+use std::iter::{once, IntoIterator};
+use std::ops::RangeInclusive;
-use super::compare_const_vals;
-use super::usefulness::{MatchCheckCtxt, PatCtxt};
+use smallvec::{smallvec, SmallVec};
use rustc_data_structures::captures::Captures;
-use rustc_index::vec::Idx;
-
use rustc_hir::{HirId, RangeEnd};
+use rustc_index::vec::Idx;
use rustc_middle::mir::{self, Field};
use rustc_middle::thir::{FieldPat, Pat, PatKind, PatRange};
use rustc_middle::ty::layout::IntegerExt;
use rustc_span::{Span, DUMMY_SP};
use rustc_target::abi::{Integer, Size, VariantIdx};
-use smallvec::{smallvec, SmallVec};
-use std::cell::Cell;
-use std::cmp::{self, max, min, Ordering};
-use std::fmt;
-use std::iter::{once, IntoIterator};
-use std::ops::RangeInclusive;
+use self::Constructor::*;
+use self::SliceKind::*;
+
+use super::compare_const_vals;
+use super::usefulness::{MatchCheckCtxt, PatCtxt};
/// Recursively expand this pattern into its subpatterns. Only useful for or-patterns.
fn expand_or_pat<'p, 'tcx>(pat: &'p Pat<'tcx>) -> Vec<&'p Pat<'tcx>> {
// straight to the result, after doing a bit of checking. (We
// could remove this branch and just fall through, which
// is more general but much slower.)
- if let Ok(Ok(bits)) = scalar.to_bits_or_ptr_internal(target_size) {
- return Some(bits);
- } else {
- return None;
- }
+ return scalar.to_bits_or_ptr_internal(target_size).unwrap().left();
}
mir::ConstantKind::Ty(c) => match c.kind() {
ty::ConstKind::Value(_) => bug!(
let info_elem = map.places[child].proj_elem.unwrap();
let child_place_str = match info_elem {
TrackElem::Field(field) => {
- if place_str.starts_with("*") {
+ if place_str.starts_with('*') {
format!("({}).{}", place_str, field.index())
} else {
format!("{}.{}", place_str, field.index())
itertools = "0.10.1"
smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
tracing = "0.1"
+either = "1"
rustc_ast = { path = "../rustc_ast" }
rustc_attr = { path = "../rustc_attr" }
rustc_data_structures = { path = "../rustc_data_structures" }
use std::cell::Cell;
+use either::Right;
+
use rustc_ast::Mutability;
use rustc_data_structures::fx::FxHashSet;
use rustc_hir::def::DefKind;
// Try to read the local as an immediate so that if it is representable as a scalar, we can
// handle it as such, but otherwise, just return the value as is.
Some(match self.ecx.read_immediate_raw(&op) {
- Ok(Ok(imm)) => imm.into(),
+ Ok(Right(imm)) => imm.into(),
_ => op,
})
}
// FIXME> figure out what to do when read_immediate_raw fails
let imm = self.use_ecx(|this| this.ecx.read_immediate_raw(value));
- if let Some(Ok(imm)) = imm {
+ if let Some(Right(imm)) = imm {
match *imm {
interpret::Immediate::Scalar(scalar) => {
*rval = Rvalue::Use(self.operand_from_scalar(
//! Propagates constants for early reporting of statically known
//! assertion failures
-use crate::const_prop::CanConstProp;
-use crate::const_prop::ConstPropMachine;
-use crate::const_prop::ConstPropMode;
-use crate::MirLint;
+use std::cell::Cell;
+
+use either::{Left, Right};
+
use rustc_const_eval::interpret::Immediate;
use rustc_const_eval::interpret::{
self, InterpCx, InterpResult, LocalState, LocalValue, MemoryKind, OpTy, Scalar, StackPopCleanup,
use rustc_span::Span;
use rustc_target::abi::{HasDataLayout, Size, TargetDataLayout};
use rustc_trait_selection::traits;
-use std::cell::Cell;
+
+use crate::const_prop::CanConstProp;
+use crate::const_prop::ConstPropMachine;
+use crate::const_prop::ConstPropMode;
+use crate::MirLint;
/// The maximum number of bytes that we'll allocate space for a local or the return value.
/// Needed for #66397, because otherwise we eval into large places and that can cause OOM or just
/// Severely regress performance.
const MAX_ALLOC_LIMIT: u64 = 1024;
+
pub struct ConstProp;
impl<'tcx> MirLint<'tcx> for ConstProp {
// Try to read the local as an immediate so that if it is representable as a scalar, we can
// handle it as such, but otherwise, just return the value as is.
Some(match self.ecx.read_immediate_raw(&op) {
- Ok(Ok(imm)) => imm.into(),
+ Ok(Left(imm)) => imm.into(),
_ => op,
})
}
F: FnOnce(&mut Self) -> InterpResult<'tcx, T>,
{
// Overwrite the PC -- whatever the interpreter does to it does not make any sense anyway.
- self.ecx.frame_mut().loc = Err(source_info.span);
+ self.ecx.frame_mut().loc = Right(source_info.span);
match f(self) {
Ok(val) => Some(val),
Err(error) => {
//! Inlining pass for MIR functions
use crate::deref_separator::deref_finder;
use rustc_attr::InlineAttr;
-use rustc_const_eval::transform::validate::equal_up_to_regions;
use rustc_index::bit_set::BitSet;
use rustc_index::vec::Idx;
use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
use rustc_target::abi::VariantIdx;
use rustc_target::spec::abi::Abi;
-use super::simplify::{remove_dead_blocks, CfgSimplifier};
+use crate::simplify::{remove_dead_blocks, CfgSimplifier};
+use crate::util;
use crate::MirPass;
use std::iter;
use std::ops::{Range, RangeFrom};
let TerminatorKind::Call { args, destination, .. } = &terminator.kind else { bug!() };
let destination_ty = destination.ty(&caller_body.local_decls, self.tcx).ty;
let output_type = callee_body.return_ty();
- if !equal_up_to_regions(self.tcx, self.param_env, output_type, destination_ty) {
+ if !util::is_subtype(self.tcx, self.param_env, output_type, destination_ty) {
trace!(?output_type, ?destination_ty);
return Err("failed to normalize return type");
}
arg_tuple_tys.iter().zip(callee_body.args_iter().skip(skipped_args))
{
let input_type = callee_body.local_decls[input].ty;
- if !equal_up_to_regions(self.tcx, self.param_env, arg_ty, input_type) {
+ if !util::is_subtype(self.tcx, self.param_env, input_type, arg_ty) {
trace!(?arg_ty, ?input_type);
return Err("failed to normalize tuple argument type");
}
for (arg, input) in args.iter().zip(callee_body.args_iter()) {
let input_type = callee_body.local_decls[input].ty;
let arg_ty = arg.ty(&caller_body.local_decls, self.tcx);
- if !equal_up_to_regions(self.tcx, self.param_env, arg_ty, input_type) {
+ if !util::is_subtype(self.tcx, self.param_env, input_type, arg_ty) {
trace!(?arg_ty, ?input_type);
return Err("failed to normalize argument type");
}
let parent = Place { local, projection: self.tcx.intern_place_elems(proj_base) };
let parent_ty = parent.ty(&self.callee_body.local_decls, self.tcx);
let check_equal = |this: &mut Self, f_ty| {
- if !equal_up_to_regions(this.tcx, this.param_env, ty, f_ty) {
+ if !util::is_equal_up_to_subtyping(this.tcx, this.param_env, ty, f_ty) {
trace!(?ty, ?f_ty);
this.validation = Err("failed to normalize projection type");
return;
use rustc_session::Limit;
use rustc_span::source_map::{dummy_spanned, respan, Span, Spanned, DUMMY_SP};
use rustc_target::abi::Size;
-use std::iter;
use std::ops::Range;
use std::path::PathBuf;
}
/// Format instance name that is already known to be too long for rustc.
-/// Show only the first and last 32 characters to avoid blasting
+/// Show only the first 2 types if it is longer than 32 characters to avoid blasting
/// the user's terminal with thousands of lines of type-name.
///
/// If the type name is longer than before+after, it will be written to a file.
fn shrunk_instance_name<'tcx>(
tcx: TyCtxt<'tcx>,
instance: &Instance<'tcx>,
- before: usize,
- after: usize,
) -> (String, Option<PathBuf>) {
let s = instance.to_string();
// Only use the shrunk version if it's really shorter.
// This also avoids the case where before and after slices overlap.
- if s.chars().nth(before + after + 1).is_some() {
- // An iterator of all byte positions including the end of the string.
- let positions = || s.char_indices().map(|(i, _)| i).chain(iter::once(s.len()));
-
- let shrunk = format!(
- "{before}...{after}",
- before = &s[..positions().nth(before).unwrap_or(s.len())],
- after = &s[positions().rev().nth(after).unwrap_or(0)..],
- );
+ if s.chars().nth(33).is_some() {
+ let shrunk = format!("{}", ty::ShortInstance(instance, 4));
+ if shrunk == s {
+ return (s, None);
+ }
let path = tcx.output_filenames(()).temp_path_ext("long-type.txt", None);
let written_to_path = std::fs::write(&path, s).ok().map(|_| path);
if !recursion_limit.value_within_limit(adjusted_recursion_depth) {
let def_span = tcx.def_span(def_id);
let def_path_str = tcx.def_path_str(def_id);
- let (shrunk, written_to_path) = shrunk_instance_name(tcx, &instance, 32, 32);
+ let (shrunk, written_to_path) = shrunk_instance_name(tcx, &instance);
let mut path = PathBuf::new();
let was_written = if written_to_path.is_some() {
path = written_to_path.unwrap();
//
// Bail out in these cases to avoid that bad user experience.
if !tcx.type_length_limit().value_within_limit(type_length) {
- let (shrunk, written_to_path) = shrunk_instance_name(tcx, &instance, 32, 32);
+ let (shrunk, written_to_path) = shrunk_instance_name(tcx, &instance);
let span = tcx.def_span(instance.def_id());
let mut path = PathBuf::new();
let was_written = if written_to_path.is_some() {
[dependencies]
bitflags = "1.0"
-tracing = "0.1"
+rustc_ast = { path = "../rustc_ast" }
rustc_ast_pretty = { path = "../rustc_ast_pretty" }
rustc_data_structures = { path = "../rustc_data_structures" }
+rustc_errors = { path = "../rustc_errors" }
rustc_feature = { path = "../rustc_feature" }
rustc_lexer = { path = "../rustc_lexer" }
rustc_macros = { path = "../rustc_macros" }
-rustc_errors = { path = "../rustc_errors" }
rustc_session = { path = "../rustc_session" }
rustc_span = { path = "../rustc_span" }
-rustc_ast = { path = "../rustc_ast" }
+thin-vec = "0.2.8"
+tracing = "0.1"
unicode-normalization = "0.1.11"
unicode-width = "0.1.4"
pub arity: usize,
pub for_param_list_exists: bool,
}
+
+#[derive(Diagnostic)]
+#[diag(parser_unexpected_if_with_if)]
+pub(crate) struct UnexpectedIfWithIf(
+ #[primary_span]
+ #[suggestion(applicability = "machine-applicable", code = " ", style = "verbose")]
+ pub Span,
+);
};
use crate::lexer::UnmatchedBrace;
+use crate::parser;
use rustc_ast as ast;
use rustc_ast::ptr::P;
use rustc_ast::token::{self, Delimiter, Lit, LitKind, TokenKind};
use rustc_span::source_map::Spanned;
use rustc_span::symbol::{kw, sym, Ident};
use rustc_span::{Span, SpanSnippetError, DUMMY_SP};
-use std::ops::{Deref, DerefMut};
-
use std::mem::take;
-
-use crate::parser;
+use std::ops::{Deref, DerefMut};
+use thin_vec::{thin_vec, ThinVec};
+use tracing::{debug, trace};
/// Creates a placeholder argument.
pub(super) fn dummy_arg(ident: Ident) -> Param {
pub(super) trait RecoverQPath: Sized + 'static {
const PATH_STYLE: PathStyle = PathStyle::Expr;
fn to_ty(&self) -> Option<P<Ty>>;
- fn recovered(qself: Option<QSelf>, path: ast::Path) -> Self;
+ fn recovered(qself: Option<P<QSelf>>, path: ast::Path) -> Self;
}
impl RecoverQPath for Ty {
fn to_ty(&self) -> Option<P<Ty>> {
Some(P(self.clone()))
}
- fn recovered(qself: Option<QSelf>, path: ast::Path) -> Self {
+ fn recovered(qself: Option<P<QSelf>>, path: ast::Path) -> Self {
Self {
span: path.span,
kind: TyKind::Path(qself, path),
fn to_ty(&self) -> Option<P<Ty>> {
self.to_ty()
}
- fn recovered(qself: Option<QSelf>, path: ast::Path) -> Self {
+ fn recovered(qself: Option<P<QSelf>>, path: ast::Path) -> Self {
Self {
span: path.span,
kind: PatKind::Path(qself, path),
fn to_ty(&self) -> Option<P<Ty>> {
self.to_ty()
}
- fn recovered(qself: Option<QSelf>, path: ast::Path) -> Self {
+ fn recovered(qself: Option<P<QSelf>>, path: ast::Path) -> Self {
Self {
span: path.span,
kind: ExprKind::Path(qself, path),
// field: value,
// }
let mut snapshot = self.create_snapshot_for_diagnostic();
- let path =
- Path { segments: vec![], span: self.prev_token.span.shrink_to_lo(), tokens: None };
+ let path = Path {
+ segments: ThinVec::new(),
+ span: self.prev_token.span.shrink_to_lo(),
+ tokens: None,
+ };
let struct_expr = snapshot.parse_struct_expr(None, path, false);
let block_tail = self.parse_block_tail(lo, s, AttemptLocalParseRecovery::No);
return Some(match (struct_expr, block_tail) {
) -> PResult<'a, P<T>> {
self.expect(&token::ModSep)?;
- let mut path = ast::Path { segments: Vec::new(), span: DUMMY_SP, tokens: None };
+ let mut path = ast::Path { segments: ThinVec::new(), span: DUMMY_SP, tokens: None };
self.parse_path_segments(&mut path.segments, T::PATH_STYLE, None)?;
path.span = ty_span.to(self.prev_token.span);
});
let path_span = ty_span.shrink_to_hi(); // Use an empty path since `position == 0`.
- Ok(P(T::recovered(Some(QSelf { ty, path_span, position: 0 }), path)))
+ Ok(P(T::recovered(Some(P(QSelf { ty, path_span, position: 0 })), path)))
}
pub fn maybe_consume_incorrect_semicolon(&mut self, items: &[P<Item>]) -> bool {
let left = begin_par_sp;
let right = self.prev_token.span;
let left_snippet = if let Ok(snip) = sm.span_to_prev_source(left) &&
- !snip.ends_with(" ") {
+ !snip.ends_with(' ') {
" ".to_string()
} else {
"".to_string()
};
let right_snippet = if let Ok(snip) = sm.span_to_next_source(right) &&
- !snip.starts_with(" ") {
+ !snip.starts_with(' ') {
" ".to_string()
} else {
"".to_string()
None,
Path {
span: new_span,
- segments: vec![
+ segments: thin_vec![
PathSegment::from_ident(*old_ident),
PathSegment::from_ident(*ident),
],
NoFieldsForFnCall, NotAsNegationOperator, NotAsNegationOperatorSub,
OuterAttributeNotAllowedOnIfElse, ParenthesesWithStructFields,
RequireColonAfterLabeledExpression, ShiftInterpretedAsGeneric, StructLiteralNotAllowedHere,
- StructLiteralNotAllowedHereSugg, TildeAsUnaryOperator, UnexpectedTokenAfterLabel,
- UnexpectedTokenAfterLabelSugg, WrapExpressionInParentheses,
+ StructLiteralNotAllowedHereSugg, TildeAsUnaryOperator, UnexpectedIfWithIf,
+ UnexpectedTokenAfterLabel, UnexpectedTokenAfterLabelSugg, WrapExpressionInParentheses,
};
use crate::maybe_recover_from_interpolated_ty_qpath;
use core::mem;
ExprKind::Index(_, _) => "indexing",
ExprKind::Try(_) => "`?`",
ExprKind::Field(_, _) => "a field access",
- ExprKind::MethodCall(_, _, _, _) => "a method call",
+ ExprKind::MethodCall(_) => "a method call",
ExprKind::Call(_, _) => "a function call",
ExprKind::Await(_) => "`.await`",
ExprKind::Err => return Ok(with_postfix),
}
let fn_span_lo = self.token.span;
- let mut segment = self.parse_path_segment(PathStyle::Expr, None)?;
- self.check_trailing_angle_brackets(&segment, &[&token::OpenDelim(Delimiter::Parenthesis)]);
- self.check_turbofish_missing_angle_brackets(&mut segment);
+ let mut seg = self.parse_path_segment(PathStyle::Expr, None)?;
+ self.check_trailing_angle_brackets(&seg, &[&token::OpenDelim(Delimiter::Parenthesis)]);
+ self.check_turbofish_missing_angle_brackets(&mut seg);
if self.check(&token::OpenDelim(Delimiter::Parenthesis)) {
// Method call `expr.f()`
let args = self.parse_paren_expr_seq()?;
let fn_span = fn_span_lo.to(self.prev_token.span);
let span = lo.to(self.prev_token.span);
- Ok(self.mk_expr(span, ExprKind::MethodCall(segment, self_arg, args, fn_span)))
+ Ok(self.mk_expr(
+ span,
+ ExprKind::MethodCall(Box::new(ast::MethodCall {
+ seg,
+ receiver: self_arg,
+ args,
+ span: fn_span,
+ })),
+ ))
} else {
// Field access `expr.f`
- if let Some(args) = segment.args {
+ if let Some(args) = seg.args {
self.sess.emit_err(FieldExpressionWithGeneric(args.span()));
}
let span = lo.to(self.prev_token.span);
- Ok(self.mk_expr(span, ExprKind::Field(self_arg, segment.ident)))
+ Ok(self.mk_expr(span, ExprKind::Field(self_arg, seg.ident)))
}
}
});
(lo.to(self.prev_token.span), ExprKind::MacCall(mac))
} else if self.check(&token::OpenDelim(Delimiter::Brace)) &&
- let Some(expr) = self.maybe_parse_struct_expr(qself.as_ref(), &path) {
+ let Some(expr) = self.maybe_parse_struct_expr(&qself, &path) {
if qself.is_some() {
self.sess.gated_spans.gate(sym::more_qualified_paths, path.span);
}
};
let capture_clause = self.parse_capture_clause()?;
- let decl = self.parse_fn_block_decl()?;
+ let fn_decl = self.parse_fn_block_decl()?;
let decl_hi = self.prev_token.span;
- let mut body = match decl.output {
+ let mut body = match fn_decl.output {
FnRetTy::Default(_) => {
let restrictions = self.restrictions - Restrictions::STMT_EXPR;
self.parse_expr_res(restrictions, None)?
if self.token.kind == TokenKind::Semi
&& matches!(self.token_cursor.frame.delim_sp, Some((Delimiter::Parenthesis, _)))
- // HACK: This is needed so we can detect whether we're inside a macro,
- // where regular assumptions about what tokens can follow other tokens
- // don't necessarily apply.
&& self.may_recover()
- // FIXME(Nilstrieb): Remove this check once `may_recover` actually stops recovery
- && self.subparser_name.is_none()
{
// It is likely that the closure body is a block but where the
// braces have been removed. We will recover and eat the next
let closure = self.mk_expr(
lo.to(body.span),
- ExprKind::Closure(
+ ExprKind::Closure(Box::new(ast::Closure {
binder,
capture_clause,
asyncness,
movability,
- decl,
+ fn_decl,
body,
- lo.to(decl_hi),
- ),
+ fn_decl_span: lo.to(decl_hi),
+ })),
);
// Disable recovery for closure body
if let Some(block) = recover_block_from_condition(self) {
block
} else {
+ self.error_on_extra_if(&cond)?;
// Parse block, which will always fail, but we can add a nice note to the error
self.parse_block().map_err(|mut err| {
err.span_note(
});
}
+ fn error_on_extra_if(&mut self, cond: &P<Expr>) -> PResult<'a, ()> {
+ if let ExprKind::Binary(Spanned { span: binop_span, node: binop}, _, right) = &cond.kind &&
+ let BinOpKind::And = binop &&
+ let ExprKind::If(cond, ..) = &right.kind {
+ Err(self.sess.create_err(UnexpectedIfWithIf(binop_span.shrink_to_hi().to(cond.span.shrink_to_lo()))))
+ } else {
+ Ok(())
+ }
+ }
+
/// Parses `for <src_pat> in <src_expr> <src_loop_block>` (`for` token already eaten).
fn parse_for_expr(&mut self, opt_label: Option<Label>, lo: Span) -> PResult<'a, P<Expr>> {
// Record whether we are about to parse `for (`.
fn maybe_parse_struct_expr(
&mut self,
- qself: Option<&ast::QSelf>,
+ qself: &Option<P<ast::QSelf>>,
path: &ast::Path,
) -> Option<PResult<'a, P<Expr>>> {
let struct_allowed = !self.restrictions.contains(Restrictions::NO_STRUCT_LITERAL);
if let Err(err) = self.expect(&token::OpenDelim(Delimiter::Brace)) {
return Some(Err(err));
}
- let expr = self.parse_struct_expr(qself.cloned(), path.clone(), true);
+ let expr = self.parse_struct_expr(qself.clone(), path.clone(), true);
if let (Ok(expr), false) = (&expr, struct_allowed) {
// This is a struct literal, but we don't can't accept them here.
self.sess.emit_err(StructLiteralNotAllowedHere {
/// Precondition: already parsed the '{'.
pub(super) fn parse_struct_expr(
&mut self,
- qself: Option<ast::QSelf>,
+ qself: Option<P<ast::QSelf>>,
pth: ast::Path,
recover: bool,
) -> PResult<'a, P<Expr>> {
use super::diagnostics::{dummy_arg, ConsumeClosingDelim};
use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign};
use super::{AttrWrapper, FollowedByType, ForceCollect, Parser, PathStyle, TrailingToken};
-
use rustc_ast::ast::*;
use rustc_ast::ptr::P;
use rustc_ast::token::{self, Delimiter, TokenKind};
use rustc_span::source_map::{self, Span};
use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::DUMMY_SP;
-
use std::convert::TryFrom;
use std::mem;
+use thin_vec::ThinVec;
+use tracing::debug;
impl<'a> Parser<'a> {
/// Parses a source module as a crate. This is the main entry point for the parser.
fn parse_use_tree(&mut self) -> PResult<'a, UseTree> {
let lo = self.token.span;
- let mut prefix = ast::Path { segments: Vec::new(), span: lo.shrink_to_lo(), tokens: None };
+ let mut prefix =
+ ast::Path { segments: ThinVec::new(), span: lo.shrink_to_lo(), tokens: None };
let kind = if self.check(&token::OpenDelim(Delimiter::Brace))
|| self.check(&token::BinOp(token::Star))
|| self.is_import_coupler()
}
/// Parse a struct ("record") pattern (e.g. `Foo { ... }` or `Foo::Bar { ... }`).
- fn parse_pat_struct(&mut self, qself: Option<QSelf>, path: Path) -> PResult<'a, PatKind> {
+ fn parse_pat_struct(&mut self, qself: Option<P<QSelf>>, path: Path) -> PResult<'a, PatKind> {
if qself.is_some() {
// Feature gate the use of qualified paths in patterns
self.sess.gated_spans.gate(sym::more_qualified_paths, path.span);
}
/// Parse tuple struct or tuple variant pattern (e.g. `Foo(...)` or `Foo::Bar(...)`).
- fn parse_pat_tuple_struct(&mut self, qself: Option<QSelf>, path: Path) -> PResult<'a, PatKind> {
+ fn parse_pat_tuple_struct(
+ &mut self,
+ qself: Option<P<QSelf>>,
+ path: Path,
+ ) -> PResult<'a, PatKind> {
let (fields, _) = self.parse_paren_comma_seq(|p| {
p.parse_pat_allow_top_alt(
None,
use rustc_errors::{pluralize, Applicability, PResult};
use rustc_span::source_map::{BytePos, Span};
use rustc_span::symbol::{kw, sym, Ident};
-
use std::mem;
+use thin_vec::ThinVec;
+use tracing::debug;
/// Specifies how to parse a path.
#[derive(Copy, Clone, PartialEq)]
/// `<T as U>::a`
/// `<T as U>::F::a<S>` (without disambiguator)
/// `<T as U>::F::a::<S>` (with disambiguator)
- pub(super) fn parse_qpath(&mut self, style: PathStyle) -> PResult<'a, (QSelf, Path)> {
+ pub(super) fn parse_qpath(&mut self, style: PathStyle) -> PResult<'a, (P<QSelf>, Path)> {
let lo = self.prev_token.span;
let ty = self.parse_ty()?;
path_span = path_lo.to(self.prev_token.span);
} else {
path_span = self.token.span.to(self.token.span);
- path = ast::Path { segments: Vec::new(), span: path_span, tokens: None };
+ path = ast::Path { segments: ThinVec::new(), span: path_span, tokens: None };
}
// See doc comment for `unmatched_angle_bracket_count`.
self.expect(&token::ModSep)?;
}
- let qself = QSelf { ty, path_span, position: path.segments.len() };
+ let qself = P(QSelf { ty, path_span, position: path.segments.len() });
self.parse_path_segments(&mut path.segments, style, None)?;
Ok((
}
let lo = self.token.span;
- let mut segments = Vec::new();
+ let mut segments = ThinVec::new();
let mod_sep_ctxt = self.token.span.ctxt();
if self.eat(&token::ModSep) {
segments.push(PathSegment::path_root(lo.shrink_to_lo().with_ctxt(mod_sep_ctxt)));
pub(super) fn parse_path_segments(
&mut self,
- segments: &mut Vec<PathSegment>,
+ segments: &mut ThinVec<PathSegment>,
style: PathStyle,
ty_generics: Option<&Generics>,
) -> PResult<'a, ()> {
attr.span,
OnlyHasEffectOn {
attr_name: attr.name_or_empty(),
- target_name: allowed_target.name().replace(" ", "_"),
+ target_name: allowed_target.name().replace(' ', "_"),
},
);
}
self.tcx.emit_spanned_lint(
lint,
tcx.hir().local_def_id_to_hir_id(first_id),
- MultiSpan::from_spans(spans.clone()),
+ MultiSpan::from_spans(spans),
diag,
);
}
[dependencies]
bitflags = "1.2.1"
-tracing = "0.1"
-rustc_ast = { path = "../rustc_ast" }
rustc_arena = { path = "../rustc_arena" }
-rustc_middle = { path = "../rustc_middle" }
+rustc_ast = { path = "../rustc_ast" }
rustc_ast_pretty = { path = "../rustc_ast_pretty" }
rustc_attr = { path = "../rustc_attr" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_feature = { path = "../rustc_feature" }
rustc_hir = { path = "../rustc_hir" }
rustc_index = { path = "../rustc_index" }
+rustc_macros = { path = "../rustc_macros" }
rustc_metadata = { path = "../rustc_metadata" }
+rustc_middle = { path = "../rustc_middle" }
rustc_query_system = { path = "../rustc_query_system" }
rustc_session = { path = "../rustc_session" }
rustc_span = { path = "../rustc_span" }
smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
+thin-vec = "0.2.8"
+tracing = "0.1"
fn visit_expr(&mut self, expr: &'a Expr) {
let parent_def = match expr.kind {
ExprKind::MacCall(..) => return self.visit_macro_invoc(expr.id),
- ExprKind::Closure(_, _, asyncness, ..) => {
+ ExprKind::Closure(ref closure) => {
// Async closures desugar to closures inside of closures, so
// we must create two defs.
let closure_def = self.create_def(expr.id, DefPathData::ClosureExpr, expr.span);
- match asyncness {
+ match closure.asyncness {
Async::Yes { closure_id, .. } => {
self.create_def(closure_id, DefPathData::ClosureExpr, expr.span)
}
use rustc_span::source_map::SourceMap;
use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::{BytePos, Span, SyntaxContext};
+use thin_vec::ThinVec;
+use crate::errors as errs;
use crate::imports::{Import, ImportKind, ImportResolver};
use crate::late::{PatternSource, Rib};
use crate::path_names_to_string;
err
}
- ResolutionError::NameAlreadyUsedInParameterList(name, first_use_span) => {
- let mut err = struct_span_err!(
- self.session,
- span,
- E0403,
- "the name `{}` is already used for a generic \
- parameter in this item's generic parameters",
- name,
- );
- err.span_label(span, "already used");
- err.span_label(first_use_span, format!("first use of `{}`", name));
- err
- }
+ ResolutionError::NameAlreadyUsedInParameterList(name, first_use_span) => self
+ .session
+ .create_err(errs::NameAlreadyUsedInParameterList { span, first_use_span, name }),
ResolutionError::MethodNotMemberOfTrait(method, trait_, candidate) => {
- let mut err = struct_span_err!(
- self.session,
+ self.session.create_err(errs::MethodNotMemberOfTrait {
span,
- E0407,
- "method `{}` is not a member of trait `{}`",
method,
- trait_
- );
- err.span_label(span, format!("not a member of trait `{}`", trait_));
- if let Some(candidate) = candidate {
- err.span_suggestion(
- method.span,
- "there is an associated function with a similar name",
- candidate.to_ident_string(),
- Applicability::MaybeIncorrect,
- );
- }
- err
+ trait_,
+ sub: candidate.map(|c| errs::AssociatedFnWithSimilarNameExists {
+ span: method.span,
+ candidate: c,
+ }),
+ })
}
ResolutionError::TypeNotMemberOfTrait(type_, trait_, candidate) => {
- let mut err = struct_span_err!(
- self.session,
+ self.session.create_err(errs::TypeNotMemberOfTrait {
span,
- E0437,
- "type `{}` is not a member of trait `{}`",
type_,
- trait_
- );
- err.span_label(span, format!("not a member of trait `{}`", trait_));
- if let Some(candidate) = candidate {
- err.span_suggestion(
- type_.span,
- "there is an associated type with a similar name",
- candidate.to_ident_string(),
- Applicability::MaybeIncorrect,
- );
- }
- err
+ trait_,
+ sub: candidate.map(|c| errs::AssociatedTypeWithSimilarNameExists {
+ span: type_.span,
+ candidate: c,
+ }),
+ })
}
ResolutionError::ConstNotMemberOfTrait(const_, trait_, candidate) => {
- let mut err = struct_span_err!(
- self.session,
+ self.session.create_err(errs::ConstNotMemberOfTrait {
span,
- E0438,
- "const `{}` is not a member of trait `{}`",
const_,
- trait_
- );
- err.span_label(span, format!("not a member of trait `{}`", trait_));
- if let Some(candidate) = candidate {
- err.span_suggestion(
- const_.span,
- "there is an associated constant with a similar name",
- candidate.to_ident_string(),
- Applicability::MaybeIncorrect,
- );
- }
- err
+ trait_,
+ sub: candidate.map(|c| errs::AssociatedConstWithSimilarNameExists {
+ span: const_.span,
+ candidate: c,
+ }),
+ })
}
ResolutionError::VariableNotBoundInPattern(binding_error, parent_scope) => {
let BindingError { name, target, origin, could_be_path } = binding_error;
err
}
ResolutionError::VariableBoundWithDifferentMode(variable_name, first_binding_span) => {
- let mut err = struct_span_err!(
- self.session,
- span,
- E0409,
- "variable `{}` is bound inconsistently across alternatives separated by `|`",
- variable_name
- );
- err.span_label(span, "bound in different ways");
- err.span_label(first_binding_span, "first binding");
- err
- }
- ResolutionError::IdentifierBoundMoreThanOnceInParameterList(identifier) => {
- let mut err = struct_span_err!(
- self.session,
- span,
- E0415,
- "identifier `{}` is bound more than once in this parameter list",
- identifier
- );
- err.span_label(span, "used as parameter more than once");
- err
- }
- ResolutionError::IdentifierBoundMoreThanOnceInSamePattern(identifier) => {
- let mut err = struct_span_err!(
- self.session,
+ self.session.create_err(errs::VariableBoundWithDifferentMode {
span,
- E0416,
- "identifier `{}` is bound more than once in the same pattern",
- identifier
- );
- err.span_label(span, "used in a pattern more than once");
- err
- }
+ first_binding_span,
+ variable_name,
+ })
+ }
+ ResolutionError::IdentifierBoundMoreThanOnceInParameterList(identifier) => self
+ .session
+ .create_err(errs::IdentifierBoundMoreThanOnceInParameterList { span, identifier }),
+ ResolutionError::IdentifierBoundMoreThanOnceInSamePattern(identifier) => self
+ .session
+ .create_err(errs::IdentifierBoundMoreThanOnceInSamePattern { span, identifier }),
ResolutionError::UndeclaredLabel { name, suggestion } => {
- let mut err = struct_span_err!(
- self.session,
- span,
- E0426,
- "use of undeclared label `{}`",
- name
- );
-
- err.span_label(span, format!("undeclared label `{}`", name));
-
- match suggestion {
+ let ((sub_reachable, sub_reachable_suggestion), sub_unreachable) = match suggestion
+ {
// A reachable label with a similar name exists.
- Some((ident, true)) => {
- err.span_label(ident.span, "a label with a similar name is reachable");
- err.span_suggestion(
- span,
- "try using similarly named label",
- ident.name,
- Applicability::MaybeIncorrect,
- );
- }
+ Some((ident, true)) => (
+ (
+ Some(errs::LabelWithSimilarNameReachable(ident.span)),
+ Some(errs::TryUsingSimilarlyNamedLabel {
+ span,
+ ident_name: ident.name,
+ }),
+ ),
+ None,
+ ),
// An unreachable label with a similar name exists.
- Some((ident, false)) => {
- err.span_label(
- ident.span,
- "a label with a similar name exists but is unreachable",
- );
- }
+ Some((ident, false)) => (
+ (None, None),
+ Some(errs::UnreachableLabelWithSimilarNameExists {
+ ident_span: ident.span,
+ }),
+ ),
// No similarly-named labels exist.
- None => (),
- }
-
- err
+ None => ((None, None), None),
+ };
+ self.session.create_err(errs::UndeclaredLabel {
+ span,
+ name,
+ sub_reachable,
+ sub_reachable_suggestion,
+ sub_unreachable,
+ })
}
ResolutionError::SelfImportsOnlyAllowedWithin { root, span_with_rename } => {
- let mut err = struct_span_err!(
- self.session,
- span,
- E0429,
- "{}",
- "`self` imports are only allowed within a { } list"
- );
-
// None of the suggestions below would help with a case like `use self`.
- if !root {
+ let (suggestion, mpart_suggestion) = if root {
+ (None, None)
+ } else {
// use foo::bar::self -> foo::bar
// use foo::bar::self as abc -> foo::bar as abc
- err.span_suggestion(
- span,
- "consider importing the module directly",
- "",
- Applicability::MachineApplicable,
- );
+ let suggestion = errs::SelfImportsOnlyAllowedWithinSuggestion { span };
// use foo::bar::self -> foo::bar::{self}
// use foo::bar::self as abc -> foo::bar::{self as abc}
- let braces = vec![
- (span_with_rename.shrink_to_lo(), "{".to_string()),
- (span_with_rename.shrink_to_hi(), "}".to_string()),
- ];
- err.multipart_suggestion(
- "alternatively, use the multi-path `use` syntax to import `self`",
- braces,
- Applicability::MachineApplicable,
- );
- }
- err
+ let mpart_suggestion = errs::SelfImportsOnlyAllowedWithinMultipartSuggestion {
+ multipart_start: span_with_rename.shrink_to_lo(),
+ multipart_end: span_with_rename.shrink_to_hi(),
+ };
+ (Some(suggestion), Some(mpart_suggestion))
+ };
+ self.session.create_err(errs::SelfImportsOnlyAllowedWithin {
+ span,
+ suggestion,
+ mpart_suggestion,
+ })
}
ResolutionError::SelfImportCanOnlyAppearOnceInTheList => {
- let mut err = struct_span_err!(
- self.session,
- span,
- E0430,
- "`self` import can only appear once in an import list"
- );
- err.span_label(span, "can only appear once in an import list");
- err
+ self.session.create_err(errs::SelfImportCanOnlyAppearOnceInTheList { span })
}
ResolutionError::SelfImportOnlyInImportListWithNonEmptyPrefix => {
- let mut err = struct_span_err!(
- self.session,
- span,
- E0431,
- "`self` import can only appear in an import list with \
- a non-empty prefix"
- );
- err.span_label(span, "can only appear in an import list with a non-empty prefix");
- err
+ self.session.create_err(errs::SelfImportOnlyInImportListWithNonEmptyPrefix { span })
}
ResolutionError::FailedToResolve { label, suggestion } => {
let mut err =
err
}
ResolutionError::CannotCaptureDynamicEnvironmentInFnItem => {
- let mut err = struct_span_err!(
- self.session,
- span,
- E0434,
- "{}",
- "can't capture dynamic environment in a fn item"
- );
- err.help("use the `|| { ... }` closure form instead");
- err
+ self.session.create_err(errs::CannotCaptureDynamicEnvironmentInFnItem { span })
}
- ResolutionError::AttemptToUseNonConstantValueInConstant(ident, sugg, current) => {
- let mut err = struct_span_err!(
- self.session,
- span,
- E0435,
- "attempt to use a non-constant value in a constant"
- );
+ ResolutionError::AttemptToUseNonConstantValueInConstant(ident, suggestion, current) => {
// let foo =...
// ^^^ given this Span
// ------- get this Span to have an applicable suggestion
.source_map()
.span_extend_to_prev_str(ident.span, current, true, false);
- match sp {
+ let ((with, with_label), without) = match sp {
Some(sp) if !self.session.source_map().is_multiline(sp) => {
let sp = sp.with_lo(BytePos(sp.lo().0 - (current.len() as u32)));
- err.span_suggestion(
- sp,
- &format!("consider using `{}` instead of `{}`", sugg, current),
- format!("{} {}", sugg, ident),
- Applicability::MaybeIncorrect,
- );
- err.span_label(span, "non-constant value");
- }
- _ => {
- err.span_label(ident.span, &format!("this would need to be a `{}`", sugg));
+ (
+ (Some(errs::AttemptToUseNonConstantValueInConstantWithSuggestion {
+ span: sp,
+ ident,
+ suggestion,
+ current,
+ }), Some(errs::AttemptToUseNonConstantValueInConstantLabelWithSuggestion {span})),
+ None,
+ )
}
- }
+ _ => (
+ (None, None),
+ Some(errs::AttemptToUseNonConstantValueInConstantWithoutSuggestion {
+ ident_span: ident.span,
+ suggestion,
+ }),
+ ),
+ };
- err
+ self.session.create_err(errs::AttemptToUseNonConstantValueInConstant {
+ span,
+ with,
+ with_label,
+ without,
+ })
}
ResolutionError::BindingShadowsSomethingUnacceptable {
shadowing_binding,
article,
shadowed_binding,
shadowed_binding_span,
- } => {
- let shadowed_binding_descr = shadowed_binding.descr();
- let mut err = struct_span_err!(
- self.session,
- span,
- E0530,
- "{}s cannot shadow {}s",
- shadowing_binding.descr(),
- shadowed_binding_descr,
- );
- err.span_label(
- span,
- format!("cannot be named the same as {} {}", article, shadowed_binding_descr),
- );
- match (shadowing_binding, shadowed_binding) {
+ } => self.session.create_err(errs::BindingShadowsSomethingUnacceptable {
+ span,
+ shadowing_binding,
+ shadowed_binding,
+ article,
+ sub_suggestion: match (shadowing_binding, shadowed_binding) {
(
PatternSource::Match,
Res::Def(DefKind::Ctor(CtorOf::Variant | CtorOf::Struct, CtorKind::Fn), _),
- ) => {
- err.span_suggestion(
- span,
- "try specify the pattern arguments",
- format!("{}(..)", name),
- Applicability::Unspecified,
- );
- }
- _ => (),
- }
- let msg =
- format!("the {} `{}` is {} here", shadowed_binding_descr, name, participle);
- err.span_label(shadowed_binding_span, msg);
- err
- }
+ ) => Some(errs::BindingShadowsSomethingUnacceptableSuggestion { span, name }),
+ _ => None,
+ },
+ shadowed_binding_span,
+ participle,
+ name,
+ }),
ResolutionError::ForwardDeclaredGenericParam => {
- let mut err = struct_span_err!(
- self.session,
- span,
- E0128,
- "generic parameters with a default cannot use \
- forward declared identifiers"
- );
- err.span_label(span, "defaulted generic parameters cannot be forward declared");
- err
+ self.session.create_err(errs::ForwardDeclaredGenericParam { span })
}
ResolutionError::ParamInTyOfConstParam(name) => {
- let mut err = struct_span_err!(
- self.session,
- span,
- E0770,
- "the type of const parameters must not depend on other generic parameters"
- );
- err.span_label(
- span,
- format!("the type must not depend on the parameter `{}`", name),
- );
- err
+ self.session.create_err(errs::ParamInTyOfConstParam { span, name })
}
ResolutionError::ParamInNonTrivialAnonConst { name, is_type } => {
- let mut err = self.session.struct_span_err(
+ self.session.create_err(errs::ParamInNonTrivialAnonConst {
span,
- "generic parameters may not be used in const operations",
- );
- err.span_label(span, &format!("cannot perform const operation using `{}`", name));
-
- if is_type {
- err.note("type parameters may not be used in const expressions");
- } else {
- err.help(&format!(
- "const parameters may only be used as standalone arguments, i.e. `{}`",
- name
- ));
- }
-
- if self.session.is_nightly_build() {
- err.help(
- "use `#![feature(generic_const_exprs)]` to allow generic const expressions",
- );
- }
-
- err
+ name,
+ sub_is_type: if is_type {
+ errs::ParamInNonTrivialAnonConstIsType::AType
+ } else {
+ errs::ParamInNonTrivialAnonConstIsType::NotAType { name }
+ },
+ help: self
+ .session
+ .is_nightly_build()
+ .then_some(errs::ParamInNonTrivialAnonConstHelp),
+ })
}
ResolutionError::SelfInGenericParamDefault => {
- let mut err = struct_span_err!(
- self.session,
- span,
- E0735,
- "generic parameters cannot use `Self` in their defaults"
- );
- err.span_label(span, "`Self` in generic parameter default");
- err
+ self.session.create_err(errs::SelfInGenericParamDefault { span })
}
ResolutionError::UnreachableLabel { name, definition_span, suggestion } => {
- let mut err = struct_span_err!(
- self.session,
+ let ((sub_suggestion_label, sub_suggestion), sub_unreachable_label) =
+ match suggestion {
+ // A reachable label with a similar name exists.
+ Some((ident, true)) => (
+ (
+ Some(errs::UnreachableLabelSubLabel { ident_span: ident.span }),
+ Some(errs::UnreachableLabelSubSuggestion {
+ span,
+ // intentionally taking 'ident.name' instead of 'ident' itself, as this
+ // could be used in suggestion context
+ ident_name: ident.name,
+ }),
+ ),
+ None,
+ ),
+ // An unreachable label with a similar name exists.
+ Some((ident, false)) => (
+ (None, None),
+ Some(errs::UnreachableLabelSubLabelUnreachable {
+ ident_span: ident.span,
+ }),
+ ),
+ // No similarly-named labels exist.
+ None => ((None, None), None),
+ };
+ self.session.create_err(errs::UnreachableLabel {
span,
- E0767,
- "use of unreachable label `{}`",
name,
- );
-
- err.span_label(definition_span, "unreachable label defined here");
- err.span_label(span, format!("unreachable label `{}`", name));
- err.note(
- "labels are unreachable through functions, closures, async blocks and modules",
- );
-
- match suggestion {
- // A reachable label with a similar name exists.
- Some((ident, true)) => {
- err.span_label(ident.span, "a label with a similar name is reachable");
- err.span_suggestion(
- span,
- "try using similarly named label",
- ident.name,
- Applicability::MaybeIncorrect,
- );
- }
- // An unreachable label with a similar name exists.
- Some((ident, false)) => {
- err.span_label(
- ident.span,
- "a label with a similar name exists but is also unreachable",
- );
- }
- // No similarly-named labels exist.
- None => (),
- }
-
- err
+ definition_span,
+ sub_suggestion,
+ sub_suggestion_label,
+ sub_unreachable_label,
+ })
}
ResolutionError::TraitImplMismatch {
name,
err.span_label(trait_item_span, "item in trait");
err
}
- ResolutionError::TraitImplDuplicate { name, trait_item_span, old_span } => {
- let mut err = struct_span_err!(
- self.session,
- span,
- E0201,
- "duplicate definitions with name `{}`:",
- name,
- );
- err.span_label(old_span, "previous definition here");
- err.span_label(trait_item_span, "item in trait");
- err.span_label(span, "duplicate definition");
- err
- }
- ResolutionError::InvalidAsmSym => {
- let mut err = self.session.struct_span_err(span, "invalid `sym` operand");
- err.span_label(span, "is a local variable");
- err.help("`sym` operands must refer to either a function or a static");
- err
- }
+ ResolutionError::TraitImplDuplicate { name, trait_item_span, old_span } => self
+ .session
+ .create_err(errs::TraitImplDuplicate { span, name, trait_item_span, old_span }),
+ ResolutionError::InvalidAsmSym => self.session.create_err(errs::InvalidAsmSym { span }),
}
}
) -> ErrorGuaranteed {
match vis_resolution_error {
VisResolutionError::Relative2018(span, path) => {
- let mut err = self.session.struct_span_err(
+ self.session.create_err(errs::Relative2018 {
span,
- "relative paths are not supported in visibilities in 2018 edition or later",
- );
- err.span_suggestion(
- path.span,
- "try",
- format!("crate::{}", pprust::path_to_string(&path)),
- Applicability::MaybeIncorrect,
- );
- err
+ path_span: path.span,
+ // intentionally converting to String, as the text would also be used as
+ // in suggestion context
+ path_str: pprust::path_to_string(&path),
+ })
+ }
+ VisResolutionError::AncestorOnly(span) => {
+ self.session.create_err(errs::AncestorOnly(span))
}
- VisResolutionError::AncestorOnly(span) => struct_span_err!(
- self.session,
- span,
- E0742,
- "visibilities can only be restricted to ancestor modules"
- ),
VisResolutionError::FailedToResolve(span, label, suggestion) => {
self.into_struct_error(span, ResolutionError::FailedToResolve { label, suggestion })
}
VisResolutionError::ExpectedFound(span, path_str, res) => {
- let mut err = struct_span_err!(
- self.session,
- span,
- E0577,
- "expected module, found {} `{}`",
- res.descr(),
- path_str
- );
- err.span_label(span, "not a module");
- err
+ self.session.create_err(errs::ExpectedFound { span, res, path_str })
}
- VisResolutionError::Indeterminate(span) => struct_span_err!(
- self.session,
- span,
- E0578,
- "cannot determine resolution for the visibility"
- ),
- VisResolutionError::ModuleOnly(span) => {
- self.session.struct_span_err(span, "visibility must resolve to a module")
+ VisResolutionError::Indeterminate(span) => {
+ self.session.create_err(errs::Indeterminate(span))
}
+ VisResolutionError::ModuleOnly(span) => self.session.create_err(errs::ModuleOnly(span)),
}
.emit()
}
{
let mut candidates = Vec::new();
let mut seen_modules = FxHashSet::default();
- let mut worklist = vec![(start_module, Vec::<ast::PathSegment>::new(), true)];
+ let mut worklist = vec![(start_module, ThinVec::<ast::PathSegment>::new(), true)];
let mut worklist_via_import = vec![];
while let Some((in_module, path_segments, accessible)) = match worklist.pop() {
--- /dev/null
+use rustc_macros::{Diagnostic, Subdiagnostic};
+use rustc_span::{
+ symbol::{Ident, Symbol},
+ Span,
+};
+
+use crate::{late::PatternSource, Res};
+
+#[derive(Diagnostic)]
+#[diag(resolve_parent_module_reset_for_binding, code = "E0637")]
+pub(crate) struct ParentModuleResetForBinding;
+
+#[derive(Diagnostic)]
+#[diag(resolve_ampersand_used_without_explicit_lifetime_name, code = "E0637")]
+#[note]
+pub(crate) struct AmpersandUsedWithoutExplicitLifetimeName(#[primary_span] pub(crate) Span);
+
+#[derive(Diagnostic)]
+#[diag(resolve_underscore_lifetime_name_cannot_be_used_here, code = "E0637")]
+#[note]
+pub(crate) struct UnderscoreLifetimeNameCannotBeUsedHere(#[primary_span] pub(crate) Span);
+
+#[derive(Diagnostic)]
+#[diag(resolve_crate_may_not_be_imported)]
+pub(crate) struct CrateMayNotBeImprted(#[primary_span] pub(crate) Span);
+
+#[derive(Diagnostic)]
+#[diag(resolve_crate_root_imports_must_be_named_explicitly)]
+pub(crate) struct CrateRootNamesMustBeNamedExplicitly(#[primary_span] pub(crate) Span);
+
+#[derive(Diagnostic)]
+#[diag(resolve_crate_root_imports_must_be_named_explicitly)]
+pub(crate) struct ResolutionError(#[primary_span] pub(crate) Span);
+
+#[derive(Diagnostic)]
+#[diag(resolve_name_is_already_used_as_generic_parameter, code = "E0403")]
+pub(crate) struct NameAlreadyUsedInParameterList {
+ #[primary_span]
+ #[label]
+ pub(crate) span: Span,
+ #[label(first_use_of_name)]
+ pub(crate) first_use_span: Span,
+ pub(crate) name: Symbol,
+}
+
+#[derive(Diagnostic)]
+#[diag(resolve_method_not_member_of_trait, code = "E0407")]
+pub(crate) struct MethodNotMemberOfTrait {
+ #[primary_span]
+ #[label]
+ pub(crate) span: Span,
+ pub(crate) method: Ident,
+ pub(crate) trait_: String,
+ #[subdiagnostic]
+ pub(crate) sub: Option<AssociatedFnWithSimilarNameExists>,
+}
+
+#[derive(Subdiagnostic)]
+#[suggestion(
+ resolve_associated_fn_with_similar_name_exists,
+ code = "{candidate}",
+ applicability = "maybe-incorrect"
+)]
+pub(crate) struct AssociatedFnWithSimilarNameExists {
+ #[primary_span]
+ pub(crate) span: Span,
+ pub(crate) candidate: Symbol,
+}
+
+#[derive(Diagnostic)]
+#[diag(resolve_type_not_member_of_trait, code = "E0437")]
+pub(crate) struct TypeNotMemberOfTrait {
+ #[primary_span]
+ #[label]
+ pub(crate) span: Span,
+ pub(crate) type_: Ident,
+ pub(crate) trait_: String,
+ #[subdiagnostic]
+ pub(crate) sub: Option<AssociatedTypeWithSimilarNameExists>,
+}
+
+#[derive(Subdiagnostic)]
+#[suggestion(
+ resolve_associated_type_with_similar_name_exists,
+ code = "{candidate}",
+ applicability = "maybe-incorrect"
+)]
+pub(crate) struct AssociatedTypeWithSimilarNameExists {
+ #[primary_span]
+ pub(crate) span: Span,
+ pub(crate) candidate: Symbol,
+}
+
+#[derive(Diagnostic)]
+#[diag(resolve_const_not_member_of_trait, code = "E0438")]
+pub(crate) struct ConstNotMemberOfTrait {
+ #[primary_span]
+ #[label]
+ pub(crate) span: Span,
+ pub(crate) const_: Ident,
+ pub(crate) trait_: String,
+ #[subdiagnostic]
+ pub(crate) sub: Option<AssociatedConstWithSimilarNameExists>,
+}
+
+#[derive(Subdiagnostic)]
+#[suggestion(
+ resolve_associated_const_with_similar_name_exists,
+ code = "{candidate}",
+ applicability = "maybe-incorrect"
+)]
+pub(crate) struct AssociatedConstWithSimilarNameExists {
+ #[primary_span]
+ pub(crate) span: Span,
+ pub(crate) candidate: Symbol,
+}
+
+#[derive(Diagnostic)]
+#[diag(resolve_variable_bound_with_different_mode, code = "E0409")]
+pub(crate) struct VariableBoundWithDifferentMode {
+ #[primary_span]
+ #[label]
+ pub(crate) span: Span,
+ #[label(first_binding_span)]
+ pub(crate) first_binding_span: Span,
+ pub(crate) variable_name: Symbol,
+}
+
+#[derive(Diagnostic)]
+#[diag(resolve_ident_bound_more_than_once_in_parameter_list, code = "E0415")]
+pub(crate) struct IdentifierBoundMoreThanOnceInParameterList {
+ #[primary_span]
+ #[label]
+ pub(crate) span: Span,
+ pub(crate) identifier: Symbol,
+}
+
+#[derive(Diagnostic)]
+#[diag(resolve_ident_bound_more_than_once_in_same_pattern, code = "E0416")]
+pub(crate) struct IdentifierBoundMoreThanOnceInSamePattern {
+ #[primary_span]
+ #[label]
+ pub(crate) span: Span,
+ pub(crate) identifier: Symbol,
+}
+
+#[derive(Diagnostic)]
+#[diag(resolve_undeclared_label, code = "E0426")]
+pub(crate) struct UndeclaredLabel {
+ #[primary_span]
+ #[label]
+ pub(crate) span: Span,
+ pub(crate) name: Symbol,
+ #[subdiagnostic]
+ pub(crate) sub_reachable: Option<LabelWithSimilarNameReachable>,
+ #[subdiagnostic]
+ pub(crate) sub_reachable_suggestion: Option<TryUsingSimilarlyNamedLabel>,
+ #[subdiagnostic]
+ pub(crate) sub_unreachable: Option<UnreachableLabelWithSimilarNameExists>,
+}
+
+#[derive(Subdiagnostic)]
+#[label(resolve_label_with_similar_name_reachable)]
+pub(crate) struct LabelWithSimilarNameReachable(#[primary_span] pub(crate) Span);
+
+#[derive(Subdiagnostic)]
+#[suggestion(
+ resolve_try_using_similarly_named_label,
+ code = "{ident_name}",
+ applicability = "maybe-incorrect"
+)]
+pub(crate) struct TryUsingSimilarlyNamedLabel {
+ #[primary_span]
+ pub(crate) span: Span,
+ pub(crate) ident_name: Symbol,
+}
+
+#[derive(Subdiagnostic)]
+#[label(resolve_unreachable_label_with_similar_name_exists)]
+pub(crate) struct UnreachableLabelWithSimilarNameExists {
+ #[primary_span]
+ pub(crate) ident_span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(resolve_self_import_can_only_appear_once_in_the_list, code = "E0430")]
+pub(crate) struct SelfImportCanOnlyAppearOnceInTheList {
+ #[primary_span]
+ #[label]
+ pub(crate) span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(resolve_self_import_only_in_import_list_with_non_empty_prefix, code = "E0431")]
+pub(crate) struct SelfImportOnlyInImportListWithNonEmptyPrefix {
+ #[primary_span]
+ #[label]
+ pub(crate) span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(resolve_cannot_capture_dynamic_environment_in_fn_item, code = "E0434")]
+#[help]
+pub(crate) struct CannotCaptureDynamicEnvironmentInFnItem {
+ #[primary_span]
+ pub(crate) span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(resolve_attempt_to_use_non_constant_value_in_constant, code = "E0435")]
+pub(crate) struct AttemptToUseNonConstantValueInConstant<'a> {
+ #[primary_span]
+ pub(crate) span: Span,
+ #[subdiagnostic]
+ pub(crate) with: Option<AttemptToUseNonConstantValueInConstantWithSuggestion<'a>>,
+ #[subdiagnostic]
+ pub(crate) with_label: Option<AttemptToUseNonConstantValueInConstantLabelWithSuggestion>,
+ #[subdiagnostic]
+ pub(crate) without: Option<AttemptToUseNonConstantValueInConstantWithoutSuggestion<'a>>,
+}
+
+#[derive(Subdiagnostic)]
+#[suggestion(
+ resolve_attempt_to_use_non_constant_value_in_constant_with_suggestion,
+ code = "{suggestion} {ident}",
+ applicability = "maybe-incorrect"
+)]
+pub(crate) struct AttemptToUseNonConstantValueInConstantWithSuggestion<'a> {
+ #[primary_span]
+ pub(crate) span: Span,
+ pub(crate) ident: Ident,
+ pub(crate) suggestion: &'a str,
+ pub(crate) current: &'a str,
+}
+
+#[derive(Subdiagnostic)]
+#[label(resolve_attempt_to_use_non_constant_value_in_constant_label_with_suggestion)]
+pub(crate) struct AttemptToUseNonConstantValueInConstantLabelWithSuggestion {
+ #[primary_span]
+ pub(crate) span: Span,
+}
+
+#[derive(Subdiagnostic)]
+#[label(resolve_attempt_to_use_non_constant_value_in_constant_without_suggestion)]
+pub(crate) struct AttemptToUseNonConstantValueInConstantWithoutSuggestion<'a> {
+ #[primary_span]
+ pub(crate) ident_span: Span,
+ pub(crate) suggestion: &'a str,
+}
+
+#[derive(Diagnostic)]
+#[diag(resolve_self_imports_only_allowed_within, code = "E0429")]
+pub(crate) struct SelfImportsOnlyAllowedWithin {
+ #[primary_span]
+ pub(crate) span: Span,
+ #[subdiagnostic]
+ pub(crate) suggestion: Option<SelfImportsOnlyAllowedWithinSuggestion>,
+ #[subdiagnostic]
+ pub(crate) mpart_suggestion: Option<SelfImportsOnlyAllowedWithinMultipartSuggestion>,
+}
+
+#[derive(Subdiagnostic)]
+#[suggestion(
+ resolve_self_imports_only_allowed_within_suggestion,
+ code = "",
+ applicability = "machine-applicable"
+)]
+pub(crate) struct SelfImportsOnlyAllowedWithinSuggestion {
+ #[primary_span]
+ pub(crate) span: Span,
+}
+
+#[derive(Subdiagnostic)]
+#[multipart_suggestion(
+ resolve_self_imports_only_allowed_within_multipart_suggestion,
+ applicability = "machine-applicable"
+)]
+pub(crate) struct SelfImportsOnlyAllowedWithinMultipartSuggestion {
+ #[suggestion_part(code = "{{")]
+ pub(crate) multipart_start: Span,
+ #[suggestion_part(code = "}}")]
+ pub(crate) multipart_end: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(resolve_binding_shadows_something_unacceptable, code = "E0530")]
+pub(crate) struct BindingShadowsSomethingUnacceptable<'a> {
+ #[primary_span]
+ #[label]
+ pub(crate) span: Span,
+ pub(crate) shadowing_binding: PatternSource,
+ pub(crate) shadowed_binding: Res,
+ pub(crate) article: &'a str,
+ #[subdiagnostic]
+ pub(crate) sub_suggestion: Option<BindingShadowsSomethingUnacceptableSuggestion>,
+ #[label(label_shadowed_binding)]
+ pub(crate) shadowed_binding_span: Span,
+ pub(crate) participle: &'a str,
+ pub(crate) name: Symbol,
+}
+
+#[derive(Subdiagnostic)]
+#[suggestion(
+ resolve_binding_shadows_something_unacceptable_suggestion,
+ code = "{name}(..)",
+ applicability = "unspecified"
+)]
+pub(crate) struct BindingShadowsSomethingUnacceptableSuggestion {
+ #[primary_span]
+ pub(crate) span: Span,
+ pub(crate) name: Symbol,
+}
+
+#[derive(Diagnostic)]
+#[diag(resolve_forward_declared_generic_param, code = "E0128")]
+pub(crate) struct ForwardDeclaredGenericParam {
+ #[primary_span]
+ #[label]
+ pub(crate) span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(resolve_param_in_ty_of_const_param, code = "E0770")]
+pub(crate) struct ParamInTyOfConstParam {
+ #[primary_span]
+ #[label]
+ pub(crate) span: Span,
+ pub(crate) name: Symbol,
+}
+
+#[derive(Diagnostic)]
+#[diag(resolve_self_in_generic_param_default, code = "E0735")]
+pub(crate) struct SelfInGenericParamDefault {
+ #[primary_span]
+ #[label]
+ pub(crate) span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(resolve_param_in_non_trivial_anon_const)]
+pub(crate) struct ParamInNonTrivialAnonConst {
+ #[primary_span]
+ #[label]
+ pub(crate) span: Span,
+ pub(crate) name: Symbol,
+ #[subdiagnostic]
+ pub(crate) sub_is_type: ParamInNonTrivialAnonConstIsType,
+ #[subdiagnostic]
+ pub(crate) help: Option<ParamInNonTrivialAnonConstHelp>,
+}
+
+#[derive(Subdiagnostic)]
+#[help(resolve_param_in_non_trivial_anon_const_help)]
+pub(crate) struct ParamInNonTrivialAnonConstHelp;
+
+#[derive(Subdiagnostic)]
+pub(crate) enum ParamInNonTrivialAnonConstIsType {
+ #[note(resolve_param_in_non_trivial_anon_const_sub_type)]
+ AType,
+ #[help(resolve_param_in_non_trivial_anon_const_sub_non_type)]
+ NotAType { name: Symbol },
+}
+
+#[derive(Diagnostic)]
+#[diag(resolve_unreachable_label, code = "E0767")]
+#[note]
+pub(crate) struct UnreachableLabel {
+ #[primary_span]
+ #[label]
+ pub(crate) span: Span,
+ pub(crate) name: Symbol,
+ #[label(label_definition_span)]
+ pub(crate) definition_span: Span,
+ #[subdiagnostic]
+ pub(crate) sub_suggestion: Option<UnreachableLabelSubSuggestion>,
+ #[subdiagnostic]
+ pub(crate) sub_suggestion_label: Option<UnreachableLabelSubLabel>,
+ #[subdiagnostic]
+ pub(crate) sub_unreachable_label: Option<UnreachableLabelSubLabelUnreachable>,
+}
+
+#[derive(Subdiagnostic)]
+#[suggestion(
+ resolve_unreachable_label_suggestion_use_similarly_named,
+ code = "{ident_name}",
+ applicability = "maybe-incorrect"
+)]
+pub(crate) struct UnreachableLabelSubSuggestion {
+ #[primary_span]
+ pub(crate) span: Span,
+ pub(crate) ident_name: Symbol,
+}
+
+#[derive(Subdiagnostic)]
+#[label(resolve_unreachable_label_similar_name_reachable)]
+pub(crate) struct UnreachableLabelSubLabel {
+ #[primary_span]
+ pub(crate) ident_span: Span,
+}
+
+#[derive(Subdiagnostic)]
+#[label(resolve_unreachable_label_similar_name_unreachable)]
+pub(crate) struct UnreachableLabelSubLabelUnreachable {
+ #[primary_span]
+ pub(crate) ident_span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(resolve_trait_impl_mismatch, code = "{code}")]
+pub(crate) struct TraitImplMismatch {
+ #[primary_span]
+ #[label]
+ pub(crate) span: Span,
+ pub(crate) name: Symbol,
+ pub(crate) kind: String,
+ #[label(label_trait_item)]
+ pub(crate) trait_item_span: Span,
+ pub(crate) trait_path: String,
+ pub(crate) code: String,
+}
+
+#[derive(Diagnostic)]
+#[diag(resolve_invalid_asm_sym)]
+#[help]
+pub(crate) struct InvalidAsmSym {
+ #[primary_span]
+ #[label]
+ pub(crate) span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(resolve_trait_impl_duplicate, code = "E0201")]
+pub(crate) struct TraitImplDuplicate {
+ #[primary_span]
+ #[label]
+ pub(crate) span: Span,
+ #[label(old_span_label)]
+ pub(crate) old_span: Span,
+ #[label(trait_item_span)]
+ pub(crate) trait_item_span: Span,
+ pub(crate) name: Symbol,
+}
+
+#[derive(Diagnostic)]
+#[diag(resolve_relative_2018)]
+pub(crate) struct Relative2018 {
+ #[primary_span]
+ pub(crate) span: Span,
+ #[suggestion(code = "crate::{path_str}", applicability = "maybe-incorrect")]
+ pub(crate) path_span: Span,
+ pub(crate) path_str: String,
+}
+
+#[derive(Diagnostic)]
+#[diag(resolve_ancestor_only, code = "E0742")]
+pub(crate) struct AncestorOnly(#[primary_span] pub(crate) Span);
+
+#[derive(Diagnostic)]
+#[diag(resolve_expected_found, code = "E0577")]
+pub(crate) struct ExpectedFound {
+ #[primary_span]
+ #[label]
+ pub(crate) span: Span,
+ pub(crate) res: Res,
+ pub(crate) path_str: String,
+}
+
+#[derive(Diagnostic)]
+#[diag(resolve_indeterminate, code = "E0578")]
+pub(crate) struct Indeterminate(#[primary_span] pub(crate) Span);
+
+#[derive(Diagnostic)]
+#[diag(resolve_module_only)]
+pub(crate) struct ModuleOnly(#[primary_span] pub(crate) Span);
use rustc_ast::visit::{self, AssocCtxt, BoundKind, FnCtxt, FnKind, Visitor};
use rustc_ast::*;
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
-use rustc_errors::DiagnosticId;
+use rustc_errors::{DiagnosticArgValue, DiagnosticId, IntoDiagnosticArg};
use rustc_hir::def::Namespace::{self, *};
use rustc_hir::def::{self, CtorKind, DefKind, LifetimeRes, PartialRes, PerNS};
use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID, LOCAL_CRATE};
use rustc_span::source_map::{respan, Spanned};
use std::assert_matches::debug_assert_matches;
+use std::borrow::Cow;
use std::collections::{hash_map::Entry, BTreeSet};
use std::mem::{replace, swap, take};
}
}
+impl IntoDiagnosticArg for PatternSource {
+ fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+ DiagnosticArgValue::Str(Cow::Borrowed(self.descr()))
+ }
+}
+
/// Denotes whether the context for the set of already bound bindings is a `Product`
/// or `Or` context. This is used in e.g., `fresh_binding` and `resolve_pattern_inner`.
/// See those functions for more information.
}
TyKind::Path(ref qself, ref path) => {
self.diagnostic_metadata.current_type_path = Some(ty);
- self.smart_resolve_path(ty.id, qself.as_ref(), path, PathSource::Type);
+ self.smart_resolve_path(ty.id, &qself, path, PathSource::Type);
// Check whether we should interpret this as a bare trait object.
if qself.is_none()
this.visit_generic_params(&tref.bound_generic_params, false);
this.smart_resolve_path(
tref.trait_ref.ref_id,
- None,
+ &None,
&tref.trait_ref.path,
PathSource::Trait(AliasPossibility::Maybe),
);
|this| {
this.smart_resolve_path(
ty.id,
- qself.as_ref(),
+ qself,
path,
PathSource::Expr(None),
);
self.with_rib(ValueNS, InlineAsmSymRibKind, |this| {
this.with_rib(TypeNS, InlineAsmSymRibKind, |this| {
this.with_label_rib(InlineAsmSymRibKind, |this| {
- this.smart_resolve_path(
- sym.id,
- sym.qself.as_ref(),
- &sym.path,
- PathSource::Expr(None),
- );
+ this.smart_resolve_path(sym.id, &sym.qself, &sym.path, PathSource::Expr(None));
visit::walk_inline_asm_sym(this, sym);
});
})
self.diagnostic_metadata.currently_processing_impl_trait =
Some((trait_ref.clone(), self_type.clone()));
let res = self.smart_resolve_path_fragment(
- None,
+ &None,
&path,
PathSource::Trait(AliasPossibility::No),
Finalize::new(trait_ref.ref_id, trait_ref.path.span),
PatKind::TupleStruct(ref qself, ref path, ref sub_patterns) => {
self.smart_resolve_path(
pat.id,
- qself.as_ref(),
+ qself,
path,
PathSource::TupleStruct(
pat.span,
);
}
PatKind::Path(ref qself, ref path) => {
- self.smart_resolve_path(pat.id, qself.as_ref(), path, PathSource::Pat);
+ self.smart_resolve_path(pat.id, qself, path, PathSource::Pat);
}
PatKind::Struct(ref qself, ref path, ..) => {
- self.smart_resolve_path(pat.id, qself.as_ref(), path, PathSource::Struct);
+ self.smart_resolve_path(pat.id, qself, path, PathSource::Struct);
}
PatKind::Or(ref ps) => {
// Add a new set of bindings to the stack. `Or` here records that when a
fn smart_resolve_path(
&mut self,
id: NodeId,
- qself: Option<&QSelf>,
+ qself: &Option<P<QSelf>>,
path: &Path,
source: PathSource<'ast>,
) {
fn smart_resolve_path_fragment(
&mut self,
- qself: Option<&QSelf>,
+ qself: &Option<P<QSelf>>,
path: &[Segment],
source: PathSource<'ast>,
finalize: Finalize,
// Resolve in alternative namespaces if resolution in the primary namespace fails.
fn resolve_qpath_anywhere(
&mut self,
- qself: Option<&QSelf>,
+ qself: &Option<P<QSelf>>,
path: &[Segment],
primary_ns: Namespace,
span: Span,
/// Handles paths that may refer to associated items.
fn resolve_qpath(
&mut self,
- qself: Option<&QSelf>,
+ qself: &Option<P<QSelf>>,
path: &[Segment],
ns: Namespace,
finalize: Finalize,
// but with `qself` set to `None`.
let ns = if qself.position + 1 == path.len() { ns } else { TypeNS };
let partial_res = self.smart_resolve_path_fragment(
- None,
+ &None,
&path[..=qself.position],
PathSource::TraitItem(ns),
Finalize::with_root_span(finalize.node_id, finalize.path_span, qself.path_span),
// Next, resolve the node.
match expr.kind {
ExprKind::Path(ref qself, ref path) => {
- self.smart_resolve_path(expr.id, qself.as_ref(), path, PathSource::Expr(parent));
+ self.smart_resolve_path(expr.id, qself, path, PathSource::Expr(parent));
visit::walk_expr(self, expr);
}
ExprKind::Struct(ref se) => {
- self.smart_resolve_path(expr.id, se.qself.as_ref(), &se.path, PathSource::Struct);
+ self.smart_resolve_path(expr.id, &se.qself, &se.path, PathSource::Struct);
visit::walk_expr(self, expr);
}
ExprKind::Field(ref subexpression, _) => {
self.resolve_expr(subexpression, Some(expr));
}
- ExprKind::MethodCall(ref segment, ref receiver, ref arguments, _) => {
+ ExprKind::MethodCall(box MethodCall { ref seg, ref receiver, ref args, .. }) => {
self.resolve_expr(receiver, Some(expr));
- for argument in arguments {
- self.resolve_expr(argument, None);
+ for arg in args {
+ self.resolve_expr(arg, None);
}
- self.visit_path_segment(segment);
+ self.visit_path_segment(seg);
}
ExprKind::Call(ref callee, ref arguments) => {
// `async |x| ...` gets desugared to `|x| future_from_generator(|| ...)`, so we need to
// resolve the arguments within the proper scopes so that usages of them inside the
// closure are detected as upvars rather than normal closure arg usages.
- ExprKind::Closure(_, _, Async::Yes { .. }, _, ref fn_decl, ref body, _span) => {
+ ExprKind::Closure(box ast::Closure {
+ asyncness: Async::Yes { .. },
+ ref fn_decl,
+ ref body,
+ ..
+ }) => {
self.with_rib(ValueNS, NormalRibKind, |this| {
this.with_label_rib(ClosureOrAsyncRibKind, |this| {
// Resolve arguments:
});
}
// For closures, ClosureOrAsyncRibKind is added in visit_fn
- ExprKind::Closure(ClosureBinder::For { ref generic_params, span }, ..) => {
+ ExprKind::Closure(box ast::Closure {
+ binder: ClosureBinder::For { ref generic_params, span },
+ ..
+ }) => {
self.with_generic_param_rib(
&generic_params,
NormalRibKind,
let traits = self.traits_in_scope(ident, ValueNS);
self.r.trait_map.insert(expr.id, traits);
}
- ExprKind::MethodCall(ref segment, ..) => {
+ ExprKind::MethodCall(ref call) => {
debug!("(recording candidate traits for expr) recording traits for {}", expr.id);
- let traits = self.traits_in_scope(segment.ident, ValueNS);
+ let traits = self.traits_in_scope(call.seg.ident, ValueNS);
self.r.trait_map.insert(expr.id, traits);
}
_ => {
use rustc_ast::visit::{FnCtxt, FnKind, LifetimeCtxt};
use rustc_ast::{
self as ast, AssocItemKind, Expr, ExprKind, GenericParam, GenericParamKind, Item, ItemKind,
- NodeId, Path, Ty, TyKind, DUMMY_NODE_ID,
+ MethodCall, NodeId, Path, Ty, TyKind, DUMMY_NODE_ID,
};
use rustc_ast_pretty::pprust::path_segment_to_string;
use rustc_data_structures::fx::FxHashSet;
use std::iter;
use std::ops::Deref;
+use thin_vec::ThinVec;
+
type Res = def::Res<ast::NodeId>;
/// A field or associated item from self type suggested in case of resolution failure.
let path_len = suggestion.path.segments.len();
let enum_path = ast::Path {
span: suggestion.path.span,
- segments: suggestion.path.segments[0..path_len - 1].to_vec(),
+ segments: suggestion.path.segments[0..path_len - 1].iter().cloned().collect(),
tokens: None,
};
let enum_path_string = path_names_to_string(&enum_path);
};
// Confirm that the target is an associated type.
- let (ty, position, path) = if let ast::TyKind::Path(
- Some(ast::QSelf { ty, position, .. }),
- path,
- ) = &bounded_ty.kind
- {
+ let (ty, position, path) = if let ast::TyKind::Path(Some(qself), path) = &bounded_ty.kind {
// use this to verify that ident is a type param.
let Some(partial_res) = self.r.partial_res_map.get(&bounded_ty.id) else {
return false;
) {
return false;
}
- (ty, position, path)
+ (&qself.ty, qself.position, path)
} else {
return false;
};
.source_map()
.span_to_snippet(ty.span) // Account for `<&'a T as Foo>::Bar`.
.unwrap_or_else(|_| constrain_ident.to_string()),
- path.segments[..*position]
+ path.segments[..position]
.iter()
.map(|segment| path_segment_to_string(segment))
.collect::<Vec<_>>()
.join("::"),
- path.segments[*position..]
+ path.segments[position..]
.iter()
.map(|segment| path_segment_to_string(segment))
.collect::<Vec<_>>()
let (lhs_span, rhs_span) = match &expr.kind {
ExprKind::Field(base, ident) => (base.span, ident.span),
- ExprKind::MethodCall(_, receiver, _, span) => (receiver.span, *span),
+ ExprKind::MethodCall(box MethodCall { receiver, span, .. }) => {
+ (receiver.span, *span)
+ }
_ => return false,
};
fn find_module(&mut self, def_id: DefId) -> Option<(Module<'a>, ImportSuggestion)> {
let mut result = None;
let mut seen_modules = FxHashSet::default();
- let mut worklist = vec![(self.r.graph_root, Vec::new())];
+ let mut worklist = vec![(self.r.graph_root, ThinVec::new())];
while let Some((in_module, path_segments)) = worklist.pop() {
// abort if the module is already found
mod def_collector;
mod diagnostics;
mod effective_visibilities;
+mod errors;
mod ident;
mod imports;
mod late;
if self.err_count() == old_count {
Ok(result)
} else {
- Err(ErrorGuaranteed::unchecked_claim_error_was_emitted())
+ Err(self.delay_span_bug(
+ rustc_span::DUMMY_SP,
+ "`self.err_count()` changed but an error was not emitted",
+ ))
}
}
#[allow(rustc::untranslatable_diagnostic)]
}
}
- /// Given a 'Span', tries to tell if the next character is '>'
- /// and the previous charactoer is '<' after skipping white space
- /// return true if wrapped by '<>'
- pub fn span_wrapped_by_angle_bracket(&self, span: Span) -> bool {
+ /// Given a 'Span', tries to tell if it's wrapped by "<>" or "()"
+ /// the algorithm searches if the next character is '>' or ')' after skipping white space
+ /// then searches the previous charactoer to match '<' or '(' after skipping white space
+ /// return true if wrapped by '<>' or '()'
+ pub fn span_wrapped_by_angle_or_parentheses(&self, span: Span) -> bool {
self.span_to_source(span, |src, start_index, end_index| {
if src.get(start_index..end_index).is_none() {
return Ok(false);
// test the right side to match '>' after skipping white space
let end_src = &src[end_index..];
let mut i = 0;
+ let mut found_right_parentheses = false;
+ let mut found_right_angle = false;
while let Some(cc) = end_src.chars().nth(i) {
if cc == ' ' {
i = i + 1;
} else if cc == '>' {
// found > in the right;
+ found_right_angle = true;
+ break;
+ } else if cc == ')' {
+ found_right_parentheses = true;
break;
} else {
// failed to find '>' return false immediately
i = i - 1;
} else if cc == '<' {
// found < in the left
+ if !found_right_angle {
+ // skip something like "(< )>"
+ return Ok(false);
+ }
+ break;
+ } else if cc == '(' {
+ if !found_right_parentheses {
+ // skip something like "<(>)"
+ return Ok(false);
+ }
break;
} else {
// failed to find '<' return false immediately
plugins,
pointee_trait,
pointer,
+ pointer_sized,
poll,
position,
post_dash_lto: "post-lto",
str_trim_end,
str_trim_start,
strict_provenance,
+ string_deref_patterns,
stringify,
struct_field_attributes,
struct_inherit,
use crate::spec::{self, HasTargetSpec};
use rustc_span::Symbol;
use std::fmt;
+use std::str::FromStr;
mod aarch64;
mod amdgpu;
}
}
+impl FromStr for Conv {
+ type Err = String;
+
+ fn from_str(s: &str) -> Result<Self, Self::Err> {
+ match s {
+ "C" => Ok(Conv::C),
+ "Rust" => Ok(Conv::Rust),
+ "RustCold" => Ok(Conv::Rust),
+ "ArmAapcs" => Ok(Conv::ArmAapcs),
+ "CCmseNonSecureCall" => Ok(Conv::CCmseNonSecureCall),
+ "Msp430Intr" => Ok(Conv::Msp430Intr),
+ "PtxKernel" => Ok(Conv::PtxKernel),
+ "X86Fastcall" => Ok(Conv::X86Fastcall),
+ "X86Intr" => Ok(Conv::X86Intr),
+ "X86Stdcall" => Ok(Conv::X86Stdcall),
+ "X86ThisCall" => Ok(Conv::X86ThisCall),
+ "X86VectorCall" => Ok(Conv::X86VectorCall),
+ "X86_64SysV" => Ok(Conv::X86_64SysV),
+ "X86_64Win64" => Ok(Conv::X86_64Win64),
+ "AmdGpuKernel" => Ok(Conv::AmdGpuKernel),
+ "AvrInterrupt" => Ok(Conv::AvrInterrupt),
+ "AvrNonBlockingInterrupt" => Ok(Conv::AvrNonBlockingInterrupt),
+ _ => Err(format!("'{}' is not a valid value for entry function call convetion.", s)),
+ }
+ }
+}
+
// Some types are used a lot. Make sure they don't unintentionally get bigger.
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
mod size_asserts {
}
}
}
+
+impl ToJson for crate::abi::call::Conv {
+ fn to_json(&self) -> Json {
+ let s = match self {
+ Self::C => "C",
+ Self::Rust => "Rust",
+ Self::RustCold => "RustCold",
+ Self::ArmAapcs => "ArmAapcs",
+ Self::CCmseNonSecureCall => "CCmseNonSecureCall",
+ Self::Msp430Intr => "Msp430Intr",
+ Self::PtxKernel => "PtxKernel",
+ Self::X86Fastcall => "X86Fastcall",
+ Self::X86Intr => "X86Intr",
+ Self::X86Stdcall => "X86Stdcall",
+ Self::X86ThisCall => "X86ThisCall",
+ Self::X86VectorCall => "X86VectorCall",
+ Self::X86_64SysV => "X86_64SysV",
+ Self::X86_64Win64 => "X86_64Win64",
+ Self::AmdGpuKernel => "AmdGpuKernel",
+ Self::AvrInterrupt => "AvrInterrupt",
+ Self::AvrNonBlockingInterrupt => "AvrNonBlockingInterrupt",
+ };
+ Json::String(s.to_owned())
+ }
+}
//! the target's settings, though `target-feature` and `link-args` will *add*
//! to the list specified by the target, rather than replace.
+use crate::abi::call::Conv;
use crate::abi::Endian;
use crate::json::{Json, ToJson};
use crate::spec::abi::{lookup as lookup_abi, Abi};
/// Whether the target supports stack canary checks. `true` by default,
/// since this is most common among tier 1 and tier 2 targets.
pub supports_stack_protector: bool,
+
+ // The name of entry function.
+ // Default value is "main"
+ pub entry_name: StaticCow<str>,
+
+ // The ABI of entry function.
+ // Default value is `Conv::C`, i.e. C call convention
+ pub entry_abi: Conv,
}
/// Add arguments for the given flavor and also for its "twin" flavors
c_enum_min_bits: 32,
generate_arange_section: true,
supports_stack_protector: true,
+ entry_name: "main".into(),
+ entry_abi: Conv::C,
}
}
}
}
}
} );
+ ($key_name:ident, Conv) => ( {
+ let name = (stringify!($key_name)).replace("_", "-");
+ obj.remove(&name).and_then(|o| o.as_str().and_then(|s| {
+ match Conv::from_str(s) {
+ Ok(c) => {
+ base.$key_name = c;
+ Some(Ok(()))
+ }
+ Err(e) => Some(Err(e))
+ }
+ })).unwrap_or(Ok(()))
+ } );
}
if let Some(j) = obj.remove("target-endian") {
key!(c_enum_min_bits, u64);
key!(generate_arange_section, bool);
key!(supports_stack_protector, bool);
+ key!(entry_name);
+ key!(entry_abi, Conv)?;
if base.is_builtin {
// This can cause unfortunate ICEs later down the line.
target_option_val!(c_enum_min_bits);
target_option_val!(generate_arange_section);
target_option_val!(supports_stack_protector);
+ target_option_val!(entry_name);
+ target_option_val!(entry_abi);
if let Some(abi) = self.default_adjusted_cabi {
d.insert("default-adjusted-cabi".into(), Abi::name(abi).to_json());
.map(|infer_ok| self.register_infer_ok_obligations(infer_ok))
}
+ /// Checks whether `expected` is a subtype of `actual`: `expected <: actual`.
+ pub fn sub<T: ToTrace<'tcx>>(
+ &self,
+ cause: &ObligationCause<'tcx>,
+ param_env: ty::ParamEnv<'tcx>,
+ expected: T,
+ actual: T,
+ ) -> Result<(), TypeError<'tcx>> {
+ self.infcx
+ .at(cause, param_env)
+ .sup(expected, actual)
+ .map(|infer_ok| self.register_infer_ok_obligations(infer_ok))
+ }
+
+ /// Checks whether `expected` is a supertype of `actual`: `expected :> actual`.
pub fn sup<T: ToTrace<'tcx>>(
&self,
cause: &ObligationCause<'tcx>,
expected: T,
actual: T,
) -> Result<(), TypeError<'tcx>> {
- match self.infcx.at(cause, param_env).sup(expected, actual) {
- Ok(InferOk { obligations, value: () }) => {
- self.register_obligations(obligations);
- Ok(())
- }
- Err(e) => Err(e),
- }
+ self.infcx
+ .at(cause, param_env)
+ .sup(expected, actual)
+ .map(|infer_ok| self.register_infer_ok_obligations(infer_ok))
}
pub fn select_where_possible(&self) -> Vec<FulfillmentError<'tcx>> {
MultiSpan, Style,
};
use rustc_hir as hir;
+use rustc_hir::def::Namespace;
use rustc_hir::def_id::DefId;
use rustc_hir::intravisit::Visitor;
use rustc_hir::GenericParam;
use rustc_middle::ty::abstract_const::NotConstEvaluatable;
use rustc_middle::ty::error::ExpectedFound;
use rustc_middle::ty::fold::{TypeFolder, TypeSuperFoldable};
+use rustc_middle::ty::print::{FmtPrinter, Print};
use rustc_middle::ty::{
self, SubtypePredicate, ToPolyTraitRef, ToPredicate, TraitRef, Ty, TyCtxt, TypeFoldable,
TypeVisitable,
suggest_increasing_limit: bool,
) -> !
where
- T: fmt::Display + TypeFoldable<'tcx>;
+ T: fmt::Display
+ + TypeFoldable<'tcx>
+ + Print<'tcx, FmtPrinter<'tcx, 'tcx>, Output = FmtPrinter<'tcx, 'tcx>>,
+ <T as Print<'tcx, FmtPrinter<'tcx, 'tcx>>>::Error: std::fmt::Debug;
fn suggest_new_overflow_limit(&self, err: &mut Diagnostic);
suggest_increasing_limit: bool,
) -> !
where
- T: fmt::Display + TypeFoldable<'tcx>,
+ T: fmt::Display
+ + TypeFoldable<'tcx>
+ + Print<'tcx, FmtPrinter<'tcx, 'tcx>, Output = FmtPrinter<'tcx, 'tcx>>,
+ <T as Print<'tcx, FmtPrinter<'tcx, 'tcx>>>::Error: std::fmt::Debug,
{
let predicate = self.resolve_vars_if_possible(obligation.predicate.clone());
+ let mut pred_str = predicate.to_string();
+ if pred_str.len() > 50 {
+ // We don't need to save the type to a file, we will be talking about this type already
+ // in a separate note when we explain the obligation, so it will be available that way.
+ pred_str = predicate
+ .print(FmtPrinter::new_with_limit(
+ self.tcx,
+ Namespace::TypeNS,
+ rustc_session::Limit(6),
+ ))
+ .unwrap()
+ .into_buffer();
+ }
let mut err = struct_span_err!(
self.tcx.sess,
obligation.cause.span,
E0275,
"overflow evaluating the requirement `{}`",
- predicate
+ pred_str,
);
if suggest_increasing_limit {
root_obligation: &PredicateObligation<'tcx>,
error: &SelectionError<'tcx>,
) {
- self.set_tainted_by_errors();
let tcx = self.tcx;
let mut span = obligation.cause.span;
+ // FIXME: statically guarantee this by tainting after the diagnostic is emitted
+ self.set_tainted_by_errors(
+ tcx.sess.delay_span_bug(span, "`report_selection_error` did not emit an error"),
+ );
let mut err = match *error {
SelectionError::Unimplemented => {
ty::Bool => Some(0),
ty::Char => Some(1),
ty::Str => Some(2),
- ty::Adt(def, _) if tcx.is_diagnostic_item(sym::String, def.did()) => Some(2),
+ ty::Adt(def, _) if Some(def.did()) == tcx.lang_items().string() => Some(2),
ty::Int(..)
| ty::Uint(..)
| ty::Float(..)
// check upstream for type errors and don't add the obligations to
// begin with in those cases.
if self.tcx.lang_items().sized_trait() == Some(trait_ref.def_id()) {
- if !self.is_tainted_by_errors() {
+ if let None = self.tainted_by_errors() {
self.emit_inference_failure_err(
body_id,
span,
if impls.len() > 1 && impls.len() < 5 && has_non_region_infer {
self.annotate_source_of_ambiguity(&mut err, &impls, predicate);
} else {
- if self.is_tainted_by_errors() {
- err.delay_as_bug();
+ if self.tainted_by_errors().is_some() {
+ err.cancel();
return;
}
err.note(&format!("cannot satisfy `{}`", predicate));
}
}
_ => {
- if self.is_tainted_by_errors() {
- err.delay_as_bug();
+ if self.tainted_by_errors().is_some() {
+ err.cancel();
return;
}
err.note(&format!("cannot satisfy `{}`", predicate));
] = path.segments
&& data.trait_ref.def_id == *trait_id
&& self.tcx.trait_of_item(*item_id) == Some(*trait_id)
- && !self.is_tainted_by_errors()
+ && let None = self.tainted_by_errors()
{
let (verb, noun) = match self.tcx.associated_item(item_id).kind {
ty::AssocKind::Const => ("refer to the", "constant"),
// with error messages.
if arg.references_error()
|| self.tcx.sess.has_errors().is_some()
- || self.is_tainted_by_errors()
+ || self.tainted_by_errors().is_some()
{
return;
}
ty::PredicateKind::Subtype(data) => {
if data.references_error()
|| self.tcx.sess.has_errors().is_some()
- || self.is_tainted_by_errors()
+ || self.tainted_by_errors().is_some()
{
// no need to overload user in such cases
return;
self.emit_inference_failure_err(body_id, span, a.into(), ErrorCode::E0282, true)
}
ty::PredicateKind::Projection(data) => {
- if predicate.references_error() || self.is_tainted_by_errors() {
+ if predicate.references_error() || self.tainted_by_errors().is_some() {
return;
}
let subst = data
}
ty::PredicateKind::ConstEvaluatable(data) => {
- if predicate.references_error() || self.is_tainted_by_errors() {
+ if predicate.references_error() || self.tainted_by_errors().is_some() {
return;
}
let subst = data.walk().find(|g| g.is_non_region_infer());
}
}
_ => {
- if self.tcx.sess.has_errors().is_some() || self.is_tainted_by_errors() {
+ if self.tcx.sess.has_errors().is_some() || self.tainted_by_errors().is_some() {
return;
}
let mut err = struct_span_err!(
post.sort();
post.dedup();
- if self.is_tainted_by_errors()
+ if self.tainted_by_errors().is_some()
&& (crate_names.len() == 1
&& spans.len() == 0
&& ["`core`", "`alloc`", "`std`"].contains(&crate_names[0].as_str())
self.resolve_vars_if_possible(data.derived.parent_trait_pred);
parent_trait_pred.remap_constness_diag(param_env);
let parent_def_id = parent_trait_pred.def_id();
+ let (self_ty, file) =
+ self.tcx.short_ty_string(parent_trait_pred.skip_binder().self_ty());
let msg = format!(
- "required for `{}` to implement `{}`",
- parent_trait_pred.skip_binder().self_ty(),
+ "required for `{self_ty}` to implement `{}`",
parent_trait_pred.print_modifiers_and_trait_path()
);
let mut is_auto_trait = false;
_ => err.note(&msg),
};
+ if let Some(file) = file {
+ err.note(&format!(
+ "the full type name has been written to '{}'",
+ file.display(),
+ ));
+ }
let mut parent_predicate = parent_trait_pred;
let mut data = &data.derived;
let mut count = 0;
count,
pluralize!(count)
));
+ let (self_ty, file) =
+ self.tcx.short_ty_string(parent_trait_pred.skip_binder().self_ty());
err.note(&format!(
- "required for `{}` to implement `{}`",
- parent_trait_pred.skip_binder().self_ty(),
+ "required for `{self_ty}` to implement `{}`",
parent_trait_pred.print_modifiers_and_trait_path()
));
+ if let Some(file) = file {
+ err.note(&format!(
+ "the full type name has been written to '{}'",
+ file.display(),
+ ));
+ }
}
// #74711: avoid a stack overflow
ensure_sufficient_stack(|| {
let span = match (&v, node) {
(MethodViolationCode::ReferencesSelfInput(Some(span)), _) => *span,
(MethodViolationCode::UndispatchableReceiver(Some(span)), _) => *span,
+ (MethodViolationCode::ReferencesImplTraitInTrait(span), _) => *span,
(MethodViolationCode::ReferencesSelfOutput, Some(node)) => {
node.fn_decl().map_or(method.ident(tcx).span, |decl| decl.output.span())
}
if contains_illegal_self_type_reference(tcx, trait_def_id, sig.output()) {
return Some(MethodViolationCode::ReferencesSelfOutput);
}
- if contains_illegal_impl_trait_in_trait(tcx, sig.output()) {
- return Some(MethodViolationCode::ReferencesImplTraitInTrait);
+ if let Some(code) = contains_illegal_impl_trait_in_trait(tcx, method.def_id, sig.output()) {
+ return Some(code);
}
// We can't monomorphize things like `fn foo<A>(...)`.
pub fn contains_illegal_impl_trait_in_trait<'tcx>(
tcx: TyCtxt<'tcx>,
+ fn_def_id: DefId,
ty: ty::Binder<'tcx, Ty<'tcx>>,
-) -> bool {
+) -> Option<MethodViolationCode> {
+ // This would be caught below, but rendering the error as a separate
+ // `async-specific` message is better.
+ if tcx.asyncness(fn_def_id).is_async() {
+ return Some(MethodViolationCode::AsyncFn);
+ }
+
// FIXME(RPITIT): Perhaps we should use a visitor here?
- ty.skip_binder().walk().any(|arg| {
+ ty.skip_binder().walk().find_map(|arg| {
if let ty::GenericArgKind::Type(ty) = arg.unpack()
&& let ty::Projection(proj) = ty.kind()
+ && tcx.def_kind(proj.item_def_id) == DefKind::ImplTraitPlaceholder
{
- tcx.def_kind(proj.item_def_id) == DefKind::ImplTraitPlaceholder
+ Some(MethodViolationCode::ReferencesImplTraitInTrait(tcx.def_span(proj.item_def_id)))
} else {
- false
+ None
}
})
}
// This is really important. While we *can* handle this, this has
// severe performance implications for large opaque types with
// late-bound regions. See `issue-88862` benchmark.
- ty::Opaque(def_id, substs) => {
+ ty::Opaque(def_id, substs) if !substs.has_escaping_bound_vars() => {
// Only normalize `impl Trait` outside of type inference, usually in codegen.
match self.param_env.reveal() {
Reveal::UserFacing => ty.super_fold_with(self),
// This is really important. While we *can* handle this, this has
// severe performance implications for large opaque types with
// late-bound regions. See `issue-88862` benchmark.
- ty::Opaque(def_id, substs) => {
+ ty::Opaque(def_id, substs) if !substs.has_escaping_bound_vars() => {
// Only normalize `impl Trait` outside of type inference, usually in codegen.
match self.param_env.reveal() {
Reveal::UserFacing => ty.try_super_fold_with(self),
self.assemble_candidates_for_transmutability(obligation, &mut candidates);
} else if lang_items.tuple_trait() == Some(def_id) {
self.assemble_candidate_for_tuple(obligation, &mut candidates);
+ } else if lang_items.pointer_sized() == Some(def_id) {
+ self.assemble_candidate_for_ptr_sized(obligation, &mut candidates);
} else {
if lang_items.clone_trait() == Some(def_id) {
// Same builtin conditions as `Copy`, i.e., every type which has builtin support
match (source.kind(), target.kind()) {
// Trait+Kx+'a -> Trait+Ky+'b (upcasts).
- (&ty::Dynamic(ref data_a, ..), &ty::Dynamic(ref data_b, ..)) => {
+ (&ty::Dynamic(ref data_a, _, dyn_a), &ty::Dynamic(ref data_b, _, dyn_b))
+ if dyn_a == dyn_b =>
+ {
// Upcast coercions permit several things:
//
// 1. Dropping auto traits, e.g., `Foo + Send` to `Foo`
}
// `T` -> `Trait`
- (_, &ty::Dynamic(..)) => {
+ (_, &ty::Dynamic(_, _, ty::Dyn)) => {
candidates.vec.push(BuiltinUnsizeCandidate);
}
| ty::Placeholder(_) => {}
}
}
+
+ fn assemble_candidate_for_ptr_sized(
+ &mut self,
+ obligation: &TraitObligation<'tcx>,
+ candidates: &mut SelectionCandidateSet<'tcx>,
+ ) {
+ // The regions of a type don't affect the size of the type
+ let self_ty = self
+ .tcx()
+ .erase_regions(self.tcx().erase_late_bound_regions(obligation.predicate.self_ty()));
+
+ // But if there are inference variables, we have to wait until it's resolved.
+ if self_ty.has_non_region_infer() {
+ candidates.ambiguous = true;
+ return;
+ }
+
+ let usize_layout =
+ self.tcx().layout_of(ty::ParamEnv::empty().and(self.tcx().types.usize)).unwrap().layout;
+ if let Ok(layout) = self.tcx().layout_of(obligation.param_env.and(self_ty))
+ && layout.layout.size() == usize_layout.size()
+ && layout.layout.align().abi == usize_layout.align().abi
+ {
+ candidates.vec.push(BuiltinCandidate { has_nested: false });
+ }
+ }
}
let mut nested = vec![];
match (source.kind(), target.kind()) {
// Trait+Kx+'a -> Trait+Ky+'b (auto traits and lifetime subtyping).
- (&ty::Dynamic(ref data_a, r_a, ty::Dyn), &ty::Dynamic(ref data_b, r_b, ty::Dyn)) => {
+ (&ty::Dynamic(ref data_a, r_a, dyn_a), &ty::Dynamic(ref data_b, r_b, dyn_b))
+ if dyn_a == dyn_b =>
+ {
// See `assemble_candidates_for_unsizing` for more info.
// We already checked the compatibility of auto traits within `assemble_candidates_for_unsizing`.
let iter = data_a
.map(ty::Binder::dummy),
);
let existential_predicates = tcx.mk_poly_existential_predicates(iter);
- let source_trait = tcx.mk_dynamic(existential_predicates, r_b, ty::Dyn);
+ let source_trait = tcx.mk_dynamic(existential_predicates, r_b, dyn_a);
// Require that the traits involved in this upcast are **equal**;
// only the **lifetime bound** is changed.
}));
}
- _ => bug!(),
+ _ => bug!("source: {source}, target: {target}"),
};
Ok(ImplSourceBuiltinData { nested })
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
use rustc_data_structures::stack::ensure_sufficient_stack;
-use rustc_errors::{Diagnostic, ErrorGuaranteed};
+use rustc_errors::Diagnostic;
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_infer::infer::LateBoundRegionConversionTime;
use rustc_middle::ty::abstract_const::NotConstEvaluatable;
use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
use rustc_middle::ty::fold::BottomUpFolder;
+use rustc_middle::ty::print::{FmtPrinter, Print};
use rustc_middle::ty::relate::TypeRelation;
use rustc_middle::ty::SubstsRef;
use rustc_middle::ty::{self, EarlyBinder, PolyProjectionPredicate, ToPolyTraitRef, ToPredicate};
it.for_each(|o| o.recursion_depth = cmp::max(min_depth, o.recursion_depth) + 1);
}
- fn check_recursion_depth<T: Display + TypeFoldable<'tcx>>(
+ fn check_recursion_depth<T>(
&self,
depth: usize,
error_obligation: &Obligation<'tcx, T>,
- ) -> Result<(), OverflowError> {
+ ) -> Result<(), OverflowError>
+ where
+ T: fmt::Display
+ + TypeFoldable<'tcx>
+ + Print<'tcx, FmtPrinter<'tcx, 'tcx>, Output = FmtPrinter<'tcx, 'tcx>>,
+ <T as Print<'tcx, FmtPrinter<'tcx, 'tcx>>>::Error: std::fmt::Debug,
+ {
if !self.infcx.tcx.recursion_limit().value_within_limit(depth) {
match self.query_mode {
TraitQueryMode::Standard => {
- if self.infcx.is_tainted_by_errors() {
- return Err(OverflowError::Error(
- ErrorGuaranteed::unchecked_claim_error_was_emitted(),
- ));
+ if let Some(e) = self.infcx.tainted_by_errors() {
+ return Err(OverflowError::Error(e));
}
self.infcx.err_ctxt().report_overflow_error(error_obligation, true);
}
/// The weird return type of this function allows it to be used with the `try` (`?`)
/// operator within certain functions.
#[inline(always)]
- fn check_recursion_limit<T: Display + TypeFoldable<'tcx>, V: Display + TypeFoldable<'tcx>>(
+ fn check_recursion_limit<T: Display + TypeFoldable<'tcx>, V>(
&self,
obligation: &Obligation<'tcx, T>,
error_obligation: &Obligation<'tcx, V>,
- ) -> Result<(), OverflowError> {
+ ) -> Result<(), OverflowError>
+ where
+ V: fmt::Display
+ + TypeFoldable<'tcx>
+ + Print<'tcx, FmtPrinter<'tcx, 'tcx>, Output = FmtPrinter<'tcx, 'tcx>>,
+ <V as Print<'tcx, FmtPrinter<'tcx, 'tcx>>>::Error: std::fmt::Debug,
+ {
self.check_recursion_depth(obligation.recursion_depth, error_obligation)
}
// We don't care about the `obligations`; they are
// always only region relations, and we are about to
// erase those anyway:
- debug_assert_eq!(
+ // This has been seen to fail in RL, so making it a non-debug assertion to better catch
+ // those cases.
+ assert_eq!(
normalized_obligations.iter().find(|p| not_outlives_predicate(p.predicate)),
None,
);
use core::cmp::{self, Ordering};
use core::fmt;
use core::hash::{Hash, Hasher};
-use core::iter::{repeat_with, FromIterator};
+use core::iter::{repeat_n, repeat_with, FromIterator};
use core::marker::PhantomData;
use core::mem::{ManuallyDrop, MaybeUninit, SizedTypeProperties};
use core::ops::{Index, IndexMut, Range, RangeBounds};
/// ```
#[stable(feature = "deque_extras", since = "1.16.0")]
pub fn resize(&mut self, new_len: usize, value: T) {
- self.resize_with(new_len, || value.clone());
+ if new_len > self.len() {
+ let extra = new_len - self.len();
+ self.extend(repeat_n(value, extra))
+ } else {
+ self.truncate(new_len);
+ }
}
}
#![feature(inplace_iteration)]
#![feature(iter_advance_by)]
#![feature(iter_next_chunk)]
+#![feature(iter_repeat_n)]
#![feature(layout_for_ptr)]
#![feature(maybe_uninit_slice)]
#![feature(maybe_uninit_uninit_array)]
///
/// # Safety
///
- /// Any other `Rc` or [`Weak`] pointers to the same allocation must not be dereferenced
- /// for the duration of the returned borrow.
- /// This is trivially the case if no such pointers exist,
- /// for example immediately after `Rc::new`.
+ /// If any other `Rc` or [`Weak`] pointers to the same allocation exist, then
+ /// they must be must not be dereferenced or have active borrows for the duration
+ /// of the returned borrow, and their inner type must be exactly the same as the
+ /// inner type of this Rc (including lifetimes). This is trivially the case if no
+ /// such pointers exist, for example immediately after `Rc::new`.
///
/// # Examples
///
/// }
/// assert_eq!(*x, "foo");
/// ```
+ /// Other `Rc` pointers to the same allocation must be to the same type.
+ /// ```no_run
+ /// #![feature(get_mut_unchecked)]
+ ///
+ /// use std::rc::Rc;
+ ///
+ /// let x: Rc<str> = Rc::from("Hello, world!");
+ /// let mut y: Rc<[u8]> = x.clone().into();
+ /// unsafe {
+ /// // this is Undefined Behavior, because x's inner type is str, not [u8]
+ /// Rc::get_mut_unchecked(&mut y).fill(0xff); // 0xff is invalid in UTF-8
+ /// }
+ /// println!("{}", &*x); // Invalid UTF-8 in a str
+ /// ```
+ /// Other `Rc` pointers to the same allocation must be to the exact same type, including lifetimes.
+ /// ```no_run
+ /// #![feature(get_mut_unchecked)]
+ ///
+ /// use std::rc::Rc;
+ ///
+ /// let x: Rc<&str> = Rc::new("Hello, world!");
+ /// {
+ /// let s = String::from("Oh, no!");
+ /// let mut y: Rc<&str> = x.clone().into();
+ /// unsafe {
+ /// // this is Undefined Behavior, because x's inner type
+ /// // is &'long str, not &'short str
+ /// *Rc::get_mut_unchecked(&mut y) = &s;
+ /// }
+ /// }
+ /// println!("{}", &*x); // Use-after-free
+ /// ```
#[inline]
#[unstable(feature = "get_mut_unchecked", issue = "63292")]
pub unsafe fn get_mut_unchecked(this: &mut Self) -> &mut T {
}
}
- /// Create an `Rc<[T]>` by reusing the underlying memory
- /// of a `Vec<T>`. This will return the vector if the existing allocation
- /// is not large enough.
- #[cfg(not(no_global_oom_handling))]
- fn try_from_vec_in_place(mut v: Vec<T>) -> Result<Rc<[T]>, Vec<T>> {
- let layout_elements = Layout::array::<T>(v.len()).unwrap();
- let layout_allocation = Layout::array::<T>(v.capacity()).unwrap();
- let layout_rcbox = rcbox_layout_for_value_layout(layout_elements);
- let mut ptr = NonNull::new(v.as_mut_ptr()).expect("`Vec<T>` stores `NonNull<T>`");
- if layout_rcbox.size() > layout_allocation.size()
- || layout_rcbox.align() > layout_allocation.align()
- {
- // Can't fit - calling `grow` would involve `realloc`
- // (which copies the elements), followed by copying again.
- return Err(v);
- }
- if layout_rcbox.size() < layout_allocation.size()
- || layout_rcbox.align() < layout_allocation.align()
- {
- // We need to shrink the allocation so that it fits
- // https://doc.rust-lang.org/nightly/std/alloc/trait.Allocator.html#memory-fitting
- // SAFETY:
- // - Vec allocates by requesting `Layout::array::<T>(capacity)`, so this capacity matches
- // - `layout_rcbox` is smaller
- // If this fails, the ownership has not been transferred
- if let Ok(p) = unsafe { Global.shrink(ptr.cast(), layout_allocation, layout_rcbox) } {
- ptr = p.cast();
- } else {
- return Err(v);
- }
- }
- // Make sure the vec's memory isn't deallocated now
- let v = mem::ManuallyDrop::new(v);
- let ptr: *mut RcBox<[T]> = ptr::slice_from_raw_parts_mut(ptr.as_ptr(), v.len()) as _;
- unsafe {
- ptr::copy(ptr.cast::<T>(), &mut (*ptr).value as *mut [T] as *mut T, v.len());
- ptr::write(&mut (*ptr).strong, Cell::new(1));
- ptr::write(&mut (*ptr).weak, Cell::new(1));
- Ok(Self::from_ptr(ptr))
- }
- }
-
/// Constructs an `Rc<[T]>` from an iterator known to be of a certain size.
///
/// Behavior is undefined should the size be wrong.
/// assert_eq!(vec![1, 2, 3], *shared);
/// ```
#[inline]
- fn from(v: Vec<T>) -> Rc<[T]> {
- match Rc::try_from_vec_in_place(v) {
- Ok(rc) => rc,
- Err(mut v) => {
- unsafe {
- let rc = Rc::copy_from_slice(&v);
- // Allow the Vec to free its memory, but not destroy its contents
- v.set_len(0);
- rc
- }
- }
+ fn from(mut v: Vec<T>) -> Rc<[T]> {
+ unsafe {
+ let rc = Rc::copy_from_slice(&v);
+ // Allow the Vec to free its memory, but not destroy its contents
+ v.set_len(0);
+ rc
}
}
}
hack::into_vec(self)
}
- /// Creates a vector by repeating a slice `n` times.
+ /// Creates a vector by copying a slice `n` times.
///
/// # Panics
///
/// [`Deref`]: core::ops::Deref "ops::Deref"
/// [`as_str()`]: String::as_str
#[derive(PartialOrd, Eq, Ord)]
-#[cfg_attr(not(test), rustc_diagnostic_item = "String")]
#[stable(feature = "rust1", since = "1.0.0")]
+#[cfg_attr(all(not(bootstrap), not(test)), lang = "String")]
pub struct String {
vec: Vec<u8>,
}
}
}
- /// Create an `Arc<[T]>` by reusing the underlying memory
- /// of a `Vec<T>`. This will return the vector if the existing allocation
- /// is not large enough.
- #[cfg(not(no_global_oom_handling))]
- fn try_from_vec_in_place(mut v: Vec<T>) -> Result<Arc<[T]>, Vec<T>> {
- let layout_elements = Layout::array::<T>(v.len()).unwrap();
- let layout_allocation = Layout::array::<T>(v.capacity()).unwrap();
- let layout_arcinner = arcinner_layout_for_value_layout(layout_elements);
- let mut ptr = NonNull::new(v.as_mut_ptr()).expect("`Vec<T>` stores `NonNull<T>`");
- if layout_arcinner.size() > layout_allocation.size()
- || layout_arcinner.align() > layout_allocation.align()
- {
- // Can't fit - calling `grow` would involve `realloc`
- // (which copies the elements), followed by copying again.
- return Err(v);
- }
- if layout_arcinner.size() < layout_allocation.size()
- || layout_arcinner.align() < layout_allocation.align()
- {
- // We need to shrink the allocation so that it fits
- // https://doc.rust-lang.org/nightly/std/alloc/trait.Allocator.html#memory-fitting
- // SAFETY:
- // - Vec allocates by requesting `Layout::array::<T>(capacity)`, so this capacity matches
- // - `layout_arcinner` is smaller
- // If this fails, the ownership has not been transferred
- if let Ok(p) = unsafe { Global.shrink(ptr.cast(), layout_allocation, layout_arcinner) }
- {
- ptr = p.cast();
- } else {
- return Err(v);
- }
- }
- // Make sure the vec's memory isn't deallocated now
- let v = mem::ManuallyDrop::new(v);
- let ptr: *mut ArcInner<[T]> = ptr::slice_from_raw_parts_mut(ptr.as_ptr(), v.len()) as _;
- unsafe {
- ptr::copy(ptr.cast::<T>(), &mut (*ptr).data as *mut [T] as *mut T, v.len());
- ptr::write(&mut (*ptr).strong, atomic::AtomicUsize::new(1));
- ptr::write(&mut (*ptr).weak, atomic::AtomicUsize::new(1));
- Ok(Self::from_ptr(ptr))
- }
- }
-
/// Constructs an `Arc<[T]>` from an iterator known to be of a certain size.
///
/// Behavior is undefined should the size be wrong.
///
/// # Safety
///
- /// Any other `Arc` or [`Weak`] pointers to the same allocation must not be dereferenced
- /// for the duration of the returned borrow.
- /// This is trivially the case if no such pointers exist,
- /// for example immediately after `Arc::new`.
+ /// If any other `Arc` or [`Weak`] pointers to the same allocation exist, then
+ /// they must be must not be dereferenced or have active borrows for the duration
+ /// of the returned borrow, and their inner type must be exactly the same as the
+ /// inner type of this Rc (including lifetimes). This is trivially the case if no
+ /// such pointers exist, for example immediately after `Arc::new`.
///
/// # Examples
///
/// }
/// assert_eq!(*x, "foo");
/// ```
+ /// Other `Arc` pointers to the same allocation must be to the same type.
+ /// ```no_run
+ /// #![feature(get_mut_unchecked)]
+ ///
+ /// use std::sync::Arc;
+ ///
+ /// let x: Arc<str> = Arc::from("Hello, world!");
+ /// let mut y: Arc<[u8]> = x.clone().into();
+ /// unsafe {
+ /// // this is Undefined Behavior, because x's inner type is str, not [u8]
+ /// Arc::get_mut_unchecked(&mut y).fill(0xff); // 0xff is invalid in UTF-8
+ /// }
+ /// println!("{}", &*x); // Invalid UTF-8 in a str
+ /// ```
+ /// Other `Arc` pointers to the same allocation must be to the exact same type, including lifetimes.
+ /// ```no_run
+ /// #![feature(get_mut_unchecked)]
+ ///
+ /// use std::sync::Arc;
+ ///
+ /// let x: Arc<&str> = Arc::new("Hello, world!");
+ /// {
+ /// let s = String::from("Oh, no!");
+ /// let mut y: Arc<&str> = x.clone().into();
+ /// unsafe {
+ /// // this is Undefined Behavior, because x's inner type
+ /// // is &'long str, not &'short str
+ /// *Arc::get_mut_unchecked(&mut y) = &s;
+ /// }
+ /// }
+ /// println!("{}", &*x); // Use-after-free
+ /// ```
#[inline]
#[unstable(feature = "get_mut_unchecked", issue = "63292")]
pub unsafe fn get_mut_unchecked(this: &mut Self) -> &mut T {
/// assert_eq!(&[1, 2, 3], &shared[..]);
/// ```
#[inline]
- fn from(v: Vec<T>) -> Arc<[T]> {
- match Arc::try_from_vec_in_place(v) {
- Ok(rc) => rc,
- Err(mut v) => {
- unsafe {
- let rc = Arc::copy_from_slice(&v);
- // Allow the Vec to free its memory, but not destroy its contents
- v.set_len(0);
- rc
- }
- }
+ fn from(mut v: Vec<T>) -> Arc<[T]> {
+ unsafe {
+ let rc = Arc::copy_from_slice(&v);
+ // Allow the Vec to free its memory, but not destroy its contents
+ v.set_len(0);
+ rc
}
}
}
// `val` dropped here while still borrowed
// borrow might be used here, when `val` is dropped and runs the `Drop` code for type `std::sync::Weak`
}
-
-#[test]
-fn arc_from_vec_opt() {
- let mut v = Vec::with_capacity(64);
- v.push(0usize);
- let addr = v.as_ptr().cast::<u8>();
- let arc: Arc<[_]> = v.into();
- unsafe {
- assert_eq!(
- arc.as_ptr().cast::<u8>().offset_from(addr),
- (std::mem::size_of::<usize>() * 2) as isize,
- "Vector allocation not reused"
- );
- }
-}
// `val` dropped here while still borrowed
// borrow might be used here, when `val` is dropped and runs the `Drop` code for type `std::rc::Weak`
}
-
-#[test]
-fn rc_from_vec_opt() {
- let mut v = Vec::with_capacity(64);
- v.push(0usize);
- let addr = v.as_ptr().cast::<u8>();
- let rc: Rc<[_]> = v.into();
- unsafe {
- assert_eq!(
- rc.as_ptr().cast::<u8>().offset_from(addr),
- (std::mem::size_of::<usize>() * 2) as isize,
- "Vector allocation not reused"
- );
- }
-}
let queue = VecDeque::from(v);
assert_eq!(queue.len(), 100);
}
+
+#[test]
+fn test_resize_keeps_reserved_space_from_item() {
+ let v = Vec::<i32>::with_capacity(1234);
+ let mut d = VecDeque::new();
+ d.resize(1, v);
+ assert_eq!(d[0].capacity(), 1234);
+}
///
/// If this returns a non-null pointer, then ownership of the memory block
/// referenced by `ptr` has been transferred to this allocator.
- /// The memory may or may not have been deallocated, and should be
- /// considered unusable. The new memory block is allocated with `layout`,
- /// but with the `size` updated to `new_size`. This new layout should be
+ /// Any access to the old `ptr` is Undefined Behavior, even if the
+ /// allocation remained in-place. The newly returned pointer is the only valid pointer
+ /// for accessing this memory now.
+ /// The new memory block is allocated with `layout`,
+ /// but with the `size` updated to `new_size`. This new layout must be
/// used when deallocating the new memory block with `dealloc`. The range
/// `0..min(layout.size(), new_size)` of the new memory block is
/// guaranteed to have the same values as the original block.
/// this, the allocator may extend the allocation referenced by `ptr` to fit the new layout.
///
/// If this returns `Ok`, then ownership of the memory block referenced by `ptr` has been
- /// transferred to this allocator. The memory may or may not have been freed, and should be
- /// considered unusable.
+ /// transferred to this allocator. Any access to the old `ptr` is Undefined Behavior, even if the
+ /// allocation was grown in-place. The newly returned pointer is the only valid pointer
+ /// for accessing this memory now.
///
/// If this method returns `Err`, then ownership of the memory block has not been transferred to
/// this allocator, and the contents of the memory block are unaltered.
/// this, the allocator may shrink the allocation referenced by `ptr` to fit the new layout.
///
/// If this returns `Ok`, then ownership of the memory block referenced by `ptr` has been
- /// transferred to this allocator. The memory may or may not have been freed, and should be
- /// considered unusable.
+ /// transferred to this allocator. Any access to the old `ptr` is Undefined Behavior, even if the
+ /// allocation was shrunk in-place. The newly returned pointer is the only valid pointer
+ /// for accessing this memory now.
///
/// If this method returns `Err`, then ownership of the memory block has not been transferred to
/// this allocator, and the contents of the memory block are unaltered.
/// A value which is initialized on the first access.
///
+/// For a thread-safe version of this struct, see [`std::sync::LazyLock`].
+///
+/// [`std::sync::LazyLock`]: ../../std/sync/struct.LazyLock.html
+///
/// # Examples
///
/// ```
/// A cell which can be written to only once.
///
-/// Unlike `RefCell`, a `OnceCell` only provides shared `&T` references to its value.
-/// Unlike `Cell`, a `OnceCell` doesn't require copying or replacing the value to access it.
+/// Unlike [`RefCell`], a `OnceCell` only provides shared `&T` references to its value.
+/// Unlike [`Cell`], a `OnceCell` doesn't require copying or replacing the value to access it.
+///
+/// For a thread-safe version of this struct, see [`std::sync::OnceLock`].
+///
+/// [`RefCell`]: crate::cell::RefCell
+/// [`Cell`]: crate::cell::Cell
+/// [`std::sync::OnceLock`]: ../../std/sync/struct.OnceLock.html
///
/// # Examples
///
/// assert_eq!(format_args!("{}", 1).as_str(), None);
/// ```
#[stable(feature = "fmt_as_str", since = "1.52.0")]
- #[rustc_const_unstable(feature = "const_arguments_as_str", issue = "none")]
+ #[rustc_const_unstable(feature = "const_arguments_as_str", issue = "103900")]
#[must_use]
#[inline]
pub const fn as_str(&self) -> Option<&'static str> {
/// `x % y != 0` or `y == 0` or `x == T::MIN && y == -1`
///
/// This intrinsic does not have a stable counterpart.
+ #[rustc_const_unstable(feature = "const_exact_div", issue = "none")]
pub fn exact_div<T: Copy>(x: T, y: T) -> T;
/// Performs an unchecked division, resulting in undefined behavior
pub use self::sources::{once_with, OnceWith};
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::sources::{repeat, Repeat};
+#[unstable(feature = "iter_repeat_n", issue = "104434")]
+pub use self::sources::{repeat_n, RepeatN};
#[stable(feature = "iterator_repeat_with", since = "1.28.0")]
pub use self::sources::{repeat_with, RepeatWith};
#[stable(feature = "iter_successors", since = "1.34.0")]
mod once;
mod once_with;
mod repeat;
+mod repeat_n;
mod repeat_with;
mod successors;
#[stable(feature = "iter_once", since = "1.2.0")]
pub use self::once::{once, Once};
+#[unstable(feature = "iter_repeat_n", issue = "104434")]
+pub use self::repeat_n::{repeat_n, RepeatN};
+
#[stable(feature = "iterator_repeat_with", since = "1.28.0")]
pub use self::repeat_with::{repeat_with, RepeatWith};
--- /dev/null
+use crate::iter::{FusedIterator, TrustedLen};
+use crate::mem::ManuallyDrop;
+
+/// Creates a new iterator that repeats a single element a given number of times.
+///
+/// The `repeat_n()` function repeats a single value exactly `n` times.
+///
+/// This is very similar to using [`repeat()`] with [`Iterator::take()`],
+/// but there are two differences:
+/// - `repeat_n()` can return the original value, rather than always cloning.
+/// - `repeat_n()` produces an [`ExactSizeIterator`].
+///
+/// [`repeat()`]: crate::iter::repeat
+///
+/// # Examples
+///
+/// Basic usage:
+///
+/// ```
+/// #![feature(iter_repeat_n)]
+/// use std::iter;
+///
+/// // four of the the number four:
+/// let mut four_fours = iter::repeat_n(4, 4);
+///
+/// assert_eq!(Some(4), four_fours.next());
+/// assert_eq!(Some(4), four_fours.next());
+/// assert_eq!(Some(4), four_fours.next());
+/// assert_eq!(Some(4), four_fours.next());
+///
+/// // no more fours
+/// assert_eq!(None, four_fours.next());
+/// ```
+///
+/// For non-`Copy` types,
+///
+/// ```
+/// #![feature(iter_repeat_n)]
+/// use std::iter;
+///
+/// let v: Vec<i32> = Vec::with_capacity(123);
+/// let mut it = iter::repeat_n(v, 5);
+///
+/// for i in 0..4 {
+/// // It starts by cloning things
+/// let cloned = it.next().unwrap();
+/// assert_eq!(cloned.len(), 0);
+/// assert_eq!(cloned.capacity(), 0);
+/// }
+///
+/// // ... but the last item is the original one
+/// let last = it.next().unwrap();
+/// assert_eq!(last.len(), 0);
+/// assert_eq!(last.capacity(), 123);
+///
+/// // ... and now we're done
+/// assert_eq!(None, it.next());
+/// ```
+#[inline]
+#[unstable(feature = "iter_repeat_n", issue = "104434")]
+#[doc(hidden)] // waiting on ACP#120 to decide whether to expose publicly
+pub fn repeat_n<T: Clone>(element: T, count: usize) -> RepeatN<T> {
+ let mut element = ManuallyDrop::new(element);
+
+ if count == 0 {
+ // SAFETY: we definitely haven't dropped it yet, since we only just got
+ // passed it in, and because the count is zero the instance we're about
+ // to create won't drop it, so to avoid leaking we need to now.
+ unsafe { ManuallyDrop::drop(&mut element) };
+ }
+
+ RepeatN { element, count }
+}
+
+/// An iterator that repeats an element an exact number of times.
+///
+/// This `struct` is created by the [`repeat_n()`] function.
+/// See its documentation for more.
+#[derive(Clone, Debug)]
+#[unstable(feature = "iter_repeat_n", issue = "104434")]
+#[doc(hidden)] // waiting on ACP#120 to decide whether to expose publicly
+pub struct RepeatN<A> {
+ count: usize,
+ // Invariant: has been dropped iff count == 0.
+ element: ManuallyDrop<A>,
+}
+
+impl<A> RepeatN<A> {
+ /// If we haven't already dropped the element, return it in an option.
+ ///
+ /// Clears the count so it won't be dropped again later.
+ #[inline]
+ fn take_element(&mut self) -> Option<A> {
+ if self.count > 0 {
+ self.count = 0;
+ // SAFETY: We just set count to zero so it won't be dropped again,
+ // and it used to be non-zero so it hasn't already been dropped.
+ unsafe { Some(ManuallyDrop::take(&mut self.element)) }
+ } else {
+ None
+ }
+ }
+}
+
+#[unstable(feature = "iter_repeat_n", issue = "104434")]
+impl<A> Drop for RepeatN<A> {
+ fn drop(&mut self) {
+ self.take_element();
+ }
+}
+
+#[unstable(feature = "iter_repeat_n", issue = "104434")]
+impl<A: Clone> Iterator for RepeatN<A> {
+ type Item = A;
+
+ #[inline]
+ fn next(&mut self) -> Option<A> {
+ if self.count == 0 {
+ return None;
+ }
+
+ self.count -= 1;
+ Some(if self.count == 0 {
+ // SAFETY: the check above ensured that the count used to be non-zero,
+ // so element hasn't been dropped yet, and we just lowered the count to
+ // zero so it won't be dropped later, and thus it's okay to take it here.
+ unsafe { ManuallyDrop::take(&mut self.element) }
+ } else {
+ A::clone(&mut self.element)
+ })
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ let len = self.len();
+ (len, Some(len))
+ }
+
+ #[inline]
+ fn advance_by(&mut self, skip: usize) -> Result<(), usize> {
+ let len = self.count;
+
+ if skip >= len {
+ self.take_element();
+ }
+
+ if skip > len {
+ Err(len)
+ } else {
+ self.count = len - skip;
+ Ok(())
+ }
+ }
+
+ #[inline]
+ fn last(mut self) -> Option<A> {
+ self.take_element()
+ }
+
+ #[inline]
+ fn count(self) -> usize {
+ self.len()
+ }
+}
+
+#[unstable(feature = "iter_repeat_n", issue = "104434")]
+impl<A: Clone> ExactSizeIterator for RepeatN<A> {
+ fn len(&self) -> usize {
+ self.count
+ }
+}
+
+#[unstable(feature = "iter_repeat_n", issue = "104434")]
+impl<A: Clone> DoubleEndedIterator for RepeatN<A> {
+ #[inline]
+ fn next_back(&mut self) -> Option<A> {
+ self.next()
+ }
+
+ #[inline]
+ fn advance_back_by(&mut self, n: usize) -> Result<(), usize> {
+ self.advance_by(n)
+ }
+
+ #[inline]
+ fn nth_back(&mut self, n: usize) -> Option<A> {
+ self.nth(n)
+ }
+}
+
+#[unstable(feature = "iter_repeat_n", issue = "104434")]
+impl<A: Clone> FusedIterator for RepeatN<A> {}
+
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl<A: Clone> TrustedLen for RepeatN<A> {}
#![feature(const_cmp)]
#![feature(const_discriminant)]
#![feature(const_eval_select)]
+#![feature(const_exact_div)]
#![feature(const_float_bits_conv)]
#![feature(const_float_classify)]
#![feature(const_fmt_arguments_new)]
#![feature(const_option)]
#![feature(const_option_ext)]
#![feature(const_pin)]
+#![feature(const_pointer_is_aligned)]
#![feature(const_ptr_sub_ptr)]
#![feature(const_replace)]
+#![feature(const_result_drop)]
#![feature(const_ptr_as_ref)]
#![feature(const_ptr_is_null)]
#![feature(const_ptr_read)]
#![feature(maybe_uninit_uninit_array)]
#![feature(ptr_alignment_type)]
#![feature(ptr_metadata)]
+#![feature(set_ptr_value)]
#![feature(slice_ptr_get)]
#![feature(slice_split_at_unchecked)]
#![feature(str_internals)]
#[cfg_attr(not(bootstrap), rustc_deny_explicit_impl)]
pub trait Tuple {}
+/// A marker for things
+#[unstable(feature = "pointer_sized_trait", issue = "none")]
+#[cfg_attr(not(bootstrap), lang = "pointer_sized")]
+#[rustc_on_unimplemented(
+ message = "`{Self}` needs to be a pointer-sized type",
+ label = "`{Self}` needs to be a pointer-sized type"
+)]
+pub trait PointerSized {}
+
/// Implementations of `Copy` for primitive types.
///
/// Implementations that cannot be described in Rust
#[rustc_const_unstable(feature = "const_inherent_unchecked_arith", issue = "85122")]
#[inline(always)]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
- pub const unsafe fn unchecked_shl(self, rhs: Self) -> Self {
+ pub const unsafe fn unchecked_shl(self, rhs: u32) -> Self {
// SAFETY: the caller must uphold the safety contract for
// `unchecked_shl`.
- unsafe { intrinsics::unchecked_shl(self, rhs) }
+ // Any legal shift amount is losslessly representable in the self type.
+ unsafe { intrinsics::unchecked_shl(self, rhs.try_into().ok().unwrap_unchecked()) }
}
/// Checked shift right. Computes `self >> rhs`, returning `None` if `rhs` is
#[rustc_const_unstable(feature = "const_inherent_unchecked_arith", issue = "85122")]
#[inline(always)]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
- pub const unsafe fn unchecked_shr(self, rhs: Self) -> Self {
+ pub const unsafe fn unchecked_shr(self, rhs: u32) -> Self {
// SAFETY: the caller must uphold the safety contract for
// `unchecked_shr`.
- unsafe { intrinsics::unchecked_shr(self, rhs) }
+ // Any legal shift amount is losslessly representable in the self type.
+ unsafe { intrinsics::unchecked_shr(self, rhs.try_into().ok().unwrap_unchecked()) }
}
/// Checked absolute value. Computes `self.abs()`, returning `None` if
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline(always)]
+ #[rustc_allow_const_fn_unstable(const_inherent_unchecked_arith)]
pub const fn wrapping_shl(self, rhs: u32) -> Self {
// SAFETY: the masking by the bitsize of the type ensures that we do not shift
// out of bounds
unsafe {
- intrinsics::unchecked_shl(self, (rhs & ($BITS - 1)) as $SelfT)
+ self.unchecked_shl(rhs & ($BITS - 1))
}
}
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline(always)]
+ #[rustc_allow_const_fn_unstable(const_inherent_unchecked_arith)]
pub const fn wrapping_shr(self, rhs: u32) -> Self {
// SAFETY: the masking by the bitsize of the type ensures that we do not shift
// out of bounds
unsafe {
- intrinsics::unchecked_shr(self, (rhs & ($BITS - 1)) as $SelfT)
+ self.unchecked_shr(rhs & ($BITS - 1))
}
}
#![stable(feature = "rust1", since = "1.0.0")]
use crate::ascii;
+use crate::convert::TryInto;
use crate::error::Error;
use crate::intrinsics;
use crate::mem;
#[rustc_const_unstable(feature = "const_inherent_unchecked_arith", issue = "85122")]
#[inline(always)]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
- pub const unsafe fn unchecked_shl(self, rhs: Self) -> Self {
+ pub const unsafe fn unchecked_shl(self, rhs: u32) -> Self {
// SAFETY: the caller must uphold the safety contract for
// `unchecked_shl`.
- unsafe { intrinsics::unchecked_shl(self, rhs) }
+ // Any legal shift amount is losslessly representable in the self type.
+ unsafe { intrinsics::unchecked_shl(self, rhs.try_into().ok().unwrap_unchecked()) }
}
/// Checked shift right. Computes `self >> rhs`, returning `None`
#[rustc_const_unstable(feature = "const_inherent_unchecked_arith", issue = "85122")]
#[inline(always)]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
- pub const unsafe fn unchecked_shr(self, rhs: Self) -> Self {
+ pub const unsafe fn unchecked_shr(self, rhs: u32) -> Self {
// SAFETY: the caller must uphold the safety contract for
// `unchecked_shr`.
- unsafe { intrinsics::unchecked_shr(self, rhs) }
+ // Any legal shift amount is losslessly representable in the self type.
+ unsafe { intrinsics::unchecked_shr(self, rhs.try_into().ok().unwrap_unchecked()) }
}
/// Checked exponentiation. Computes `self.pow(exp)`, returning `None` if
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline(always)]
+ #[rustc_allow_const_fn_unstable(const_inherent_unchecked_arith)]
pub const fn wrapping_shl(self, rhs: u32) -> Self {
// SAFETY: the masking by the bitsize of the type ensures that we do not shift
// out of bounds
unsafe {
- intrinsics::unchecked_shl(self, (rhs & ($BITS - 1)) as $SelfT)
+ self.unchecked_shl(rhs & ($BITS - 1))
}
}
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline(always)]
+ #[rustc_allow_const_fn_unstable(const_inherent_unchecked_arith)]
pub const fn wrapping_shr(self, rhs: u32) -> Self {
// SAFETY: the masking by the bitsize of the type ensures that we do not shift
// out of bounds
unsafe {
- intrinsics::unchecked_shr(self, (rhs & ($BITS - 1)) as $SelfT)
+ self.unchecked_shr(rhs & ($BITS - 1))
}
}
/// }
/// ```
#[unstable(feature = "set_ptr_value", issue = "75091")]
+ #[rustc_const_unstable(feature = "set_ptr_value", issue = "75091")]
#[must_use = "returns a new pointer rather than modifying its argument"]
#[inline]
- pub fn with_metadata_of<U>(self, mut val: *const U) -> *const U
+ pub const fn with_metadata_of<U>(self, meta: *const U) -> *const U
where
U: ?Sized,
{
- let target = &mut val as *mut *const U as *mut *const u8;
- // SAFETY: In case of a thin pointer, this operations is identical
- // to a simple assignment. In case of a fat pointer, with the current
- // fat pointer layout implementation, the first field of such a
- // pointer is always the data pointer, which is likewise assigned.
- unsafe { *target = self as *const u8 };
- val
+ from_raw_parts::<U>(self as *const (), metadata(meta))
}
/// Changes constness without changing the type.
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
pub const unsafe fn byte_offset(self, count: isize) -> Self {
// SAFETY: the caller must uphold the safety contract for `offset`.
- let this = unsafe { self.cast::<u8>().offset(count).cast::<()>() };
- from_raw_parts::<T>(this, metadata(self))
+ unsafe { self.cast::<u8>().offset(count).with_metadata_of(self) }
}
/// Calculates the offset from a pointer using wrapping arithmetic.
#[unstable(feature = "pointer_byte_offsets", issue = "96283")]
#[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "96283")]
pub const fn wrapping_byte_offset(self, count: isize) -> Self {
- from_raw_parts::<T>(self.cast::<u8>().wrapping_offset(count).cast::<()>(), metadata(self))
+ self.cast::<u8>().wrapping_offset(count).with_metadata_of(self)
}
/// Masks out bits of the pointer according to a mask.
#[must_use = "returns a new pointer rather than modifying its argument"]
#[inline(always)]
pub fn mask(self, mask: usize) -> *const T {
- let this = intrinsics::ptr_mask(self.cast::<()>(), mask);
- from_raw_parts::<T>(this, metadata(self))
+ intrinsics::ptr_mask(self.cast::<()>(), mask).with_metadata_of(self)
}
/// Calculates the distance between two pointers. The returned value is in
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
pub const unsafe fn byte_add(self, count: usize) -> Self {
// SAFETY: the caller must uphold the safety contract for `add`.
- let this = unsafe { self.cast::<u8>().add(count).cast::<()>() };
- from_raw_parts::<T>(this, metadata(self))
+ unsafe { self.cast::<u8>().add(count).with_metadata_of(self) }
}
/// Calculates the offset from a pointer (convenience for
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
pub const unsafe fn byte_sub(self, count: usize) -> Self {
// SAFETY: the caller must uphold the safety contract for `sub`.
- let this = unsafe { self.cast::<u8>().sub(count).cast::<()>() };
- from_raw_parts::<T>(this, metadata(self))
+ unsafe { self.cast::<u8>().sub(count).with_metadata_of(self) }
}
/// Calculates the offset from a pointer using wrapping arithmetic.
#[unstable(feature = "pointer_byte_offsets", issue = "96283")]
#[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "96283")]
pub const fn wrapping_byte_add(self, count: usize) -> Self {
- from_raw_parts::<T>(self.cast::<u8>().wrapping_add(count).cast::<()>(), metadata(self))
+ self.cast::<u8>().wrapping_add(count).with_metadata_of(self)
}
/// Calculates the offset from a pointer using wrapping arithmetic.
#[unstable(feature = "pointer_byte_offsets", issue = "96283")]
#[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "96283")]
pub const fn wrapping_byte_sub(self, count: usize) -> Self {
- from_raw_parts::<T>(self.cast::<u8>().wrapping_sub(count).cast::<()>(), metadata(self))
+ self.cast::<u8>().wrapping_sub(count).with_metadata_of(self)
}
/// Reads the value from `self` without moving it. This leaves the
/// }
/// # }
/// ```
+ #[must_use]
+ #[inline]
#[stable(feature = "align_offset", since = "1.36.0")]
#[rustc_const_unstable(feature = "const_align_offset", issue = "90962")]
pub const fn align_offset(self, align: usize) -> usize
panic!("align_offset: align is not a power-of-two");
}
- fn rt_impl<T>(p: *const T, align: usize) -> usize {
- // SAFETY: `align` has been checked to be a power of 2 above
- unsafe { align_offset(p, align) }
- }
+ #[cfg(bootstrap)]
+ {
+ fn rt_impl<T>(p: *const T, align: usize) -> usize {
+ // SAFETY: `align` has been checked to be a power of 2 above
+ unsafe { align_offset(p, align) }
+ }
+
+ const fn ctfe_impl<T>(_: *const T, _: usize) -> usize {
+ usize::MAX
+ }
- const fn ctfe_impl<T>(_: *const T, _: usize) -> usize {
- usize::MAX
+ // SAFETY:
+ // It is permissible for `align_offset` to always return `usize::MAX`,
+ // algorithm correctness can not depend on `align_offset` returning non-max values.
+ //
+ // As such the behaviour can't change after replacing `align_offset` with `usize::MAX`, only performance can.
+ unsafe { intrinsics::const_eval_select((self, align), ctfe_impl, rt_impl) }
}
- // SAFETY:
- // It is permissible for `align_offset` to always return `usize::MAX`,
- // algorithm correctness can not depend on `align_offset` returning non-max values.
- //
- // As such the behaviour can't change after replacing `align_offset` with `usize::MAX`, only performance can.
- unsafe { intrinsics::const_eval_select((self, align), ctfe_impl, rt_impl) }
+ #[cfg(not(bootstrap))]
+ {
+ // SAFETY: `align` has been checked to be a power of 2 above
+ unsafe { align_offset(self, align) }
+ }
}
/// Returns whether the pointer is properly aligned for `T`.
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ /// ```
+ /// #![feature(pointer_is_aligned)]
+ /// #![feature(pointer_byte_offsets)]
+ ///
+ /// // On some platforms, the alignment of i32 is less than 4.
+ /// #[repr(align(4))]
+ /// struct AlignedI32(i32);
+ ///
+ /// let data = AlignedI32(42);
+ /// let ptr = &data as *const AlignedI32;
+ ///
+ /// assert!(ptr.is_aligned());
+ /// assert!(!ptr.wrapping_byte_add(1).is_aligned());
+ /// ```
+ ///
+ /// # At compiletime
+ /// **Note: Alignment at compiletime is experimental and subject to change. See the
+ /// [tracking issue] for details.**
+ ///
+ /// At compiletime, the compiler may not know where a value will end up in memory.
+ /// Calling this function on a pointer created from a reference at compiletime will only
+ /// return `true` if the pointer is guaranteed to be aligned. This means that the pointer
+ /// is never aligned if cast to a type with a stricter alignment than the reference's
+ /// underlying allocation.
+ ///
+ #[cfg_attr(bootstrap, doc = "```ignore")]
+ #[cfg_attr(not(bootstrap), doc = "```")]
+ /// #![feature(pointer_is_aligned)]
+ /// #![feature(const_pointer_is_aligned)]
+ ///
+ /// // On some platforms, the alignment of primitives is less than their size.
+ /// #[repr(align(4))]
+ /// struct AlignedI32(i32);
+ /// #[repr(align(8))]
+ /// struct AlignedI64(i64);
+ ///
+ /// const _: () = {
+ /// let data = AlignedI32(42);
+ /// let ptr = &data as *const AlignedI32;
+ /// assert!(ptr.is_aligned());
+ ///
+ /// // At runtime either `ptr1` or `ptr2` would be aligned, but at compiletime neither is aligned.
+ /// let ptr1 = ptr.cast::<AlignedI64>();
+ /// let ptr2 = ptr.wrapping_add(1).cast::<AlignedI64>();
+ /// assert!(!ptr1.is_aligned());
+ /// assert!(!ptr2.is_aligned());
+ /// };
+ /// ```
+ ///
+ /// Due to this behavior, it is possible that a runtime pointer derived from a compiletime
+ /// pointer is aligned, even if the compiletime pointer wasn't aligned.
+ ///
+ #[cfg_attr(bootstrap, doc = "```ignore")]
+ #[cfg_attr(not(bootstrap), doc = "```")]
+ /// #![feature(pointer_is_aligned)]
+ /// #![feature(const_pointer_is_aligned)]
+ ///
+ /// // On some platforms, the alignment of primitives is less than their size.
+ /// #[repr(align(4))]
+ /// struct AlignedI32(i32);
+ /// #[repr(align(8))]
+ /// struct AlignedI64(i64);
+ ///
+ /// // At compiletime, neither `COMPTIME_PTR` nor `COMPTIME_PTR + 1` is aligned.
+ /// const COMPTIME_PTR: *const AlignedI32 = &AlignedI32(42);
+ /// const _: () = assert!(!COMPTIME_PTR.cast::<AlignedI64>().is_aligned());
+ /// const _: () = assert!(!COMPTIME_PTR.wrapping_add(1).cast::<AlignedI64>().is_aligned());
+ ///
+ /// // At runtime, either `runtime_ptr` or `runtime_ptr + 1` is aligned.
+ /// let runtime_ptr = COMPTIME_PTR;
+ /// assert_ne!(
+ /// runtime_ptr.cast::<AlignedI64>().is_aligned(),
+ /// runtime_ptr.wrapping_add(1).cast::<AlignedI64>().is_aligned(),
+ /// );
+ /// ```
+ ///
+ /// If a pointer is created from a fixed address, this function behaves the same during
+ /// runtime and compiletime.
+ ///
+ #[cfg_attr(bootstrap, doc = "```ignore")]
+ #[cfg_attr(not(bootstrap), doc = "```")]
+ /// #![feature(pointer_is_aligned)]
+ /// #![feature(const_pointer_is_aligned)]
+ ///
+ /// // On some platforms, the alignment of primitives is less than their size.
+ /// #[repr(align(4))]
+ /// struct AlignedI32(i32);
+ /// #[repr(align(8))]
+ /// struct AlignedI64(i64);
+ ///
+ /// const _: () = {
+ /// let ptr = 40 as *const AlignedI32;
+ /// assert!(ptr.is_aligned());
+ ///
+ /// // For pointers with a known address, runtime and compiletime behavior are identical.
+ /// let ptr1 = ptr.cast::<AlignedI64>();
+ /// let ptr2 = ptr.wrapping_add(1).cast::<AlignedI64>();
+ /// assert!(ptr1.is_aligned());
+ /// assert!(!ptr2.is_aligned());
+ /// };
+ /// ```
+ ///
+ /// [tracking issue]: https://github.com/rust-lang/rust/issues/104203
#[must_use]
#[inline]
#[unstable(feature = "pointer_is_aligned", issue = "96284")]
- pub fn is_aligned(self) -> bool
+ #[rustc_const_unstable(feature = "const_pointer_is_aligned", issue = "104203")]
+ pub const fn is_aligned(self) -> bool
where
T: Sized,
{
- self.is_aligned_to(core::mem::align_of::<T>())
+ self.is_aligned_to(mem::align_of::<T>())
}
/// Returns whether the pointer is aligned to `align`.
/// # Panics
///
/// The function panics if `align` is not a power-of-two (this includes 0).
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ /// ```
+ /// #![feature(pointer_is_aligned)]
+ /// #![feature(pointer_byte_offsets)]
+ ///
+ /// // On some platforms, the alignment of i32 is less than 4.
+ /// #[repr(align(4))]
+ /// struct AlignedI32(i32);
+ ///
+ /// let data = AlignedI32(42);
+ /// let ptr = &data as *const AlignedI32;
+ ///
+ /// assert!(ptr.is_aligned_to(1));
+ /// assert!(ptr.is_aligned_to(2));
+ /// assert!(ptr.is_aligned_to(4));
+ ///
+ /// assert!(ptr.wrapping_byte_add(2).is_aligned_to(2));
+ /// assert!(!ptr.wrapping_byte_add(2).is_aligned_to(4));
+ ///
+ /// assert_ne!(ptr.is_aligned_to(8), ptr.wrapping_add(1).is_aligned_to(8));
+ /// ```
+ ///
+ /// # At compiletime
+ /// **Note: Alignment at compiletime is experimental and subject to change. See the
+ /// [tracking issue] for details.**
+ ///
+ /// At compiletime, the compiler may not know where a value will end up in memory.
+ /// Calling this function on a pointer created from a reference at compiletime will only
+ /// return `true` if the pointer is guaranteed to be aligned. This means that the pointer
+ /// cannot be stricter aligned than the reference's underlying allocation.
+ ///
+ #[cfg_attr(bootstrap, doc = "```ignore")]
+ #[cfg_attr(not(bootstrap), doc = "```")]
+ /// #![feature(pointer_is_aligned)]
+ /// #![feature(const_pointer_is_aligned)]
+ ///
+ /// // On some platforms, the alignment of i32 is less than 4.
+ /// #[repr(align(4))]
+ /// struct AlignedI32(i32);
+ ///
+ /// const _: () = {
+ /// let data = AlignedI32(42);
+ /// let ptr = &data as *const AlignedI32;
+ ///
+ /// assert!(ptr.is_aligned_to(1));
+ /// assert!(ptr.is_aligned_to(2));
+ /// assert!(ptr.is_aligned_to(4));
+ ///
+ /// // At compiletime, we know for sure that the pointer isn't aligned to 8.
+ /// assert!(!ptr.is_aligned_to(8));
+ /// assert!(!ptr.wrapping_add(1).is_aligned_to(8));
+ /// };
+ /// ```
+ ///
+ /// Due to this behavior, it is possible that a runtime pointer derived from a compiletime
+ /// pointer is aligned, even if the compiletime pointer wasn't aligned.
+ ///
+ #[cfg_attr(bootstrap, doc = "```ignore")]
+ #[cfg_attr(not(bootstrap), doc = "```")]
+ /// #![feature(pointer_is_aligned)]
+ /// #![feature(const_pointer_is_aligned)]
+ ///
+ /// // On some platforms, the alignment of i32 is less than 4.
+ /// #[repr(align(4))]
+ /// struct AlignedI32(i32);
+ ///
+ /// // At compiletime, neither `COMPTIME_PTR` nor `COMPTIME_PTR + 1` is aligned.
+ /// const COMPTIME_PTR: *const AlignedI32 = &AlignedI32(42);
+ /// const _: () = assert!(!COMPTIME_PTR.is_aligned_to(8));
+ /// const _: () = assert!(!COMPTIME_PTR.wrapping_add(1).is_aligned_to(8));
+ ///
+ /// // At runtime, either `runtime_ptr` or `runtime_ptr + 1` is aligned.
+ /// let runtime_ptr = COMPTIME_PTR;
+ /// assert_ne!(
+ /// runtime_ptr.is_aligned_to(8),
+ /// runtime_ptr.wrapping_add(1).is_aligned_to(8),
+ /// );
+ /// ```
+ ///
+ /// If a pointer is created from a fixed address, this function behaves the same during
+ /// runtime and compiletime.
+ ///
+ #[cfg_attr(bootstrap, doc = "```ignore")]
+ #[cfg_attr(not(bootstrap), doc = "```")]
+ /// #![feature(pointer_is_aligned)]
+ /// #![feature(const_pointer_is_aligned)]
+ ///
+ /// const _: () = {
+ /// let ptr = 40 as *const u8;
+ /// assert!(ptr.is_aligned_to(1));
+ /// assert!(ptr.is_aligned_to(2));
+ /// assert!(ptr.is_aligned_to(4));
+ /// assert!(ptr.is_aligned_to(8));
+ /// assert!(!ptr.is_aligned_to(16));
+ /// };
+ /// ```
+ ///
+ /// [tracking issue]: https://github.com/rust-lang/rust/issues/104203
#[must_use]
#[inline]
#[unstable(feature = "pointer_is_aligned", issue = "96284")]
- pub fn is_aligned_to(self, align: usize) -> bool {
+ #[rustc_const_unstable(feature = "const_pointer_is_aligned", issue = "104203")]
+ pub const fn is_aligned_to(self, align: usize) -> bool {
if !align.is_power_of_two() {
panic!("is_aligned_to: align is not a power-of-two");
}
- // Cast is needed for `T: !Sized`
- self.cast::<u8>().addr() & align - 1 == 0
+ // We can't use the address of `self` in a `const fn`, so we use `align_offset` instead.
+ // The cast to `()` is used to
+ // 1. deal with fat pointers; and
+ // 2. ensure that `align_offset` doesn't actually try to compute an offset.
+ self.cast::<()>().align_offset(align) == 0
}
}
/// Align pointer `p`.
///
-/// Calculate offset (in terms of elements of `stride` stride) that has to be applied
+/// Calculate offset (in terms of elements of `size_of::<T>()` stride) that has to be applied
/// to pointer `p` so that pointer `p` would get aligned to `a`.
///
-/// Note: This implementation has been carefully tailored to not panic. It is UB for this to panic.
+/// # Safety
+/// `a` must be a power of two.
+///
+/// # Notes
+/// This implementation has been carefully tailored to not panic. It is UB for this to panic.
/// The only real change that can be made here is change of `INV_TABLE_MOD_16` and associated
/// constants.
///
///
/// Any questions go to @nagisa.
#[lang = "align_offset"]
-pub(crate) unsafe fn align_offset<T: Sized>(p: *const T, a: usize) -> usize {
+pub(crate) const unsafe fn align_offset<T: Sized>(p: *const T, a: usize) -> usize {
// FIXME(#75598): Direct use of these intrinsics improves codegen significantly at opt-level <=
// 1, where the method versions of these operations are not inlined.
use intrinsics::{
- cttz_nonzero, exact_div, unchecked_rem, unchecked_shl, unchecked_shr, unchecked_sub,
- wrapping_add, wrapping_mul, wrapping_sub,
+ cttz_nonzero, exact_div, mul_with_overflow, unchecked_rem, unchecked_shl, unchecked_shr,
+ unchecked_sub, wrapping_add, wrapping_mul, wrapping_sub,
};
/// Calculate multiplicative modular inverse of `x` modulo `m`.
///
/// Implementation of this function shall not panic. Ever.
#[inline]
- unsafe fn mod_inv(x: usize, m: usize) -> usize {
+ const unsafe fn mod_inv(x: usize, m: usize) -> usize {
/// Multiplicative modular inverse table modulo 2⁴ = 16.
///
/// Note, that this table does not contain values where inverse does not exist (i.e., for
const INV_TABLE_MOD_16: [u8; 8] = [1, 11, 13, 7, 9, 3, 5, 15];
/// Modulo for which the `INV_TABLE_MOD_16` is intended.
const INV_TABLE_MOD: usize = 16;
- /// INV_TABLE_MOD²
- const INV_TABLE_MOD_SQUARED: usize = INV_TABLE_MOD * INV_TABLE_MOD;
- let table_inverse = INV_TABLE_MOD_16[(x & (INV_TABLE_MOD - 1)) >> 1] as usize;
// SAFETY: `m` is required to be a power-of-two, hence non-zero.
let m_minus_one = unsafe { unchecked_sub(m, 1) };
- if m <= INV_TABLE_MOD {
- table_inverse & m_minus_one
- } else {
- // We iterate "up" using the following formula:
- //
- // $$ xy ≡ 1 (mod 2ⁿ) → xy (2 - xy) ≡ 1 (mod 2²ⁿ) $$
+ let mut inverse = INV_TABLE_MOD_16[(x & (INV_TABLE_MOD - 1)) >> 1] as usize;
+ let mut mod_gate = INV_TABLE_MOD;
+ // We iterate "up" using the following formula:
+ //
+ // $$ xy ≡ 1 (mod 2ⁿ) → xy (2 - xy) ≡ 1 (mod 2²ⁿ) $$
+ //
+ // This application needs to be applied at least until `2²ⁿ ≥ m`, at which point we can
+ // finally reduce the computation to our desired `m` by taking `inverse mod m`.
+ //
+ // This computation is `O(log log m)`, which is to say, that on 64-bit machines this loop
+ // will always finish in at most 4 iterations.
+ loop {
+ // y = y * (2 - xy) mod n
//
- // until 2²ⁿ ≥ m. Then we can reduce to our desired `m` by taking the result `mod m`.
- let mut inverse = table_inverse;
- let mut going_mod = INV_TABLE_MOD_SQUARED;
- loop {
- // y = y * (2 - xy) mod n
- //
- // Note, that we use wrapping operations here intentionally – the original formula
- // uses e.g., subtraction `mod n`. It is entirely fine to do them `mod
- // usize::MAX` instead, because we take the result `mod n` at the end
- // anyway.
- inverse = wrapping_mul(inverse, wrapping_sub(2usize, wrapping_mul(x, inverse)));
- if going_mod >= m {
- return inverse & m_minus_one;
- }
- going_mod = wrapping_mul(going_mod, going_mod);
+ // Note, that we use wrapping operations here intentionally – the original formula
+ // uses e.g., subtraction `mod n`. It is entirely fine to do them `mod
+ // usize::MAX` instead, because we take the result `mod n` at the end
+ // anyway.
+ if mod_gate >= m {
+ break;
}
+ inverse = wrapping_mul(inverse, wrapping_sub(2usize, wrapping_mul(x, inverse)));
+ let (new_gate, overflow) = mul_with_overflow(mod_gate, mod_gate);
+ if overflow {
+ break;
+ }
+ mod_gate = new_gate;
}
+ inverse & m_minus_one
}
- let addr = p.addr();
let stride = mem::size_of::<T>();
+
+ // SAFETY: This is just an inlined `p.addr()` (which is not
+ // a `const fn` so we cannot call it).
+ // During const eval, we hook this function to ensure that the pointer never
+ // has provenance, making this sound.
+ let addr: usize = unsafe { mem::transmute(p) };
+
// SAFETY: `a` is a power-of-two, therefore non-zero.
let a_minus_one = unsafe { unchecked_sub(a, 1) };
/// }
/// ```
#[unstable(feature = "set_ptr_value", issue = "75091")]
+ #[rustc_const_unstable(feature = "set_ptr_value", issue = "75091")]
#[must_use = "returns a new pointer rather than modifying its argument"]
#[inline]
- pub fn with_metadata_of<U>(self, val: *const U) -> *mut U
+ pub const fn with_metadata_of<U>(self, meta: *const U) -> *mut U
where
U: ?Sized,
{
- // Prepare in the type system that we will replace the pointer value with a mutable
- // pointer, taking the mutable provenance from the `self` pointer.
- let mut val = val as *mut U;
- // Pointer to the pointer value within the value.
- let target = &mut val as *mut *mut U as *mut *mut u8;
- // SAFETY: In case of a thin pointer, this operations is identical
- // to a simple assignment. In case of a fat pointer, with the current
- // fat pointer layout implementation, the first field of such a
- // pointer is always the data pointer, which is likewise assigned.
- unsafe { *target = self as *mut u8 };
- val
+ from_raw_parts_mut::<U>(self as *mut (), metadata(meta))
}
/// Changes constness without changing the type.
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
pub const unsafe fn byte_offset(self, count: isize) -> Self {
// SAFETY: the caller must uphold the safety contract for `offset`.
- let this = unsafe { self.cast::<u8>().offset(count).cast::<()>() };
- from_raw_parts_mut::<T>(this, metadata(self))
+ unsafe { self.cast::<u8>().offset(count).with_metadata_of(self) }
}
/// Calculates the offset from a pointer using wrapping arithmetic.
#[unstable(feature = "pointer_byte_offsets", issue = "96283")]
#[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "96283")]
pub const fn wrapping_byte_offset(self, count: isize) -> Self {
- from_raw_parts_mut::<T>(
- self.cast::<u8>().wrapping_offset(count).cast::<()>(),
- metadata(self),
- )
+ self.cast::<u8>().wrapping_offset(count).with_metadata_of(self)
}
/// Masks out bits of the pointer according to a mask.
#[must_use = "returns a new pointer rather than modifying its argument"]
#[inline(always)]
pub fn mask(self, mask: usize) -> *mut T {
- let this = intrinsics::ptr_mask(self.cast::<()>(), mask) as *mut ();
- from_raw_parts_mut::<T>(this, metadata(self))
+ intrinsics::ptr_mask(self.cast::<()>(), mask).cast_mut().with_metadata_of(self)
}
/// Returns `None` if the pointer is null, or else returns a unique reference to
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
pub const unsafe fn byte_add(self, count: usize) -> Self {
// SAFETY: the caller must uphold the safety contract for `add`.
- let this = unsafe { self.cast::<u8>().add(count).cast::<()>() };
- from_raw_parts_mut::<T>(this, metadata(self))
+ unsafe { self.cast::<u8>().add(count).with_metadata_of(self) }
}
/// Calculates the offset from a pointer (convenience for
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
pub const unsafe fn byte_sub(self, count: usize) -> Self {
// SAFETY: the caller must uphold the safety contract for `sub`.
- let this = unsafe { self.cast::<u8>().sub(count).cast::<()>() };
- from_raw_parts_mut::<T>(this, metadata(self))
+ unsafe { self.cast::<u8>().sub(count).with_metadata_of(self) }
}
/// Calculates the offset from a pointer using wrapping arithmetic.
#[unstable(feature = "pointer_byte_offsets", issue = "96283")]
#[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "96283")]
pub const fn wrapping_byte_add(self, count: usize) -> Self {
- from_raw_parts_mut::<T>(self.cast::<u8>().wrapping_add(count).cast::<()>(), metadata(self))
+ self.cast::<u8>().wrapping_add(count).with_metadata_of(self)
}
/// Calculates the offset from a pointer using wrapping arithmetic.
#[unstable(feature = "pointer_byte_offsets", issue = "96283")]
#[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "96283")]
pub const fn wrapping_byte_sub(self, count: usize) -> Self {
- from_raw_parts_mut::<T>(self.cast::<u8>().wrapping_sub(count).cast::<()>(), metadata(self))
+ self.cast::<u8>().wrapping_sub(count).with_metadata_of(self)
}
/// Reads the value from `self` without moving it. This leaves the
/// }
/// # }
/// ```
+ #[must_use]
+ #[inline]
#[stable(feature = "align_offset", since = "1.36.0")]
#[rustc_const_unstable(feature = "const_align_offset", issue = "90962")]
pub const fn align_offset(self, align: usize) -> usize
panic!("align_offset: align is not a power-of-two");
}
- fn rt_impl<T>(p: *mut T, align: usize) -> usize {
- // SAFETY: `align` has been checked to be a power of 2 above
- unsafe { align_offset(p, align) }
+ #[cfg(bootstrap)]
+ {
+ fn rt_impl<T>(p: *mut T, align: usize) -> usize {
+ // SAFETY: `align` has been checked to be a power of 2 above
+ unsafe { align_offset(p, align) }
+ }
+
+ const fn ctfe_impl<T>(_: *mut T, _: usize) -> usize {
+ usize::MAX
+ }
+
+ // SAFETY:
+ // It is permissible for `align_offset` to always return `usize::MAX`,
+ // algorithm correctness can not depend on `align_offset` returning non-max values.
+ //
+ // As such the behaviour can't change after replacing `align_offset` with `usize::MAX`, only performance can.
+ unsafe { intrinsics::const_eval_select((self, align), ctfe_impl, rt_impl) }
}
- const fn ctfe_impl<T>(_: *mut T, _: usize) -> usize {
- usize::MAX
+ #[cfg(not(bootstrap))]
+ {
+ // SAFETY: `align` has been checked to be a power of 2 above
+ unsafe { align_offset(self, align) }
}
-
- // SAFETY:
- // It is permissible for `align_offset` to always return `usize::MAX`,
- // algorithm correctness can not depend on `align_offset` returning non-max values.
- //
- // As such the behaviour can't change after replacing `align_offset` with `usize::MAX`, only performance can.
- unsafe { intrinsics::const_eval_select((self, align), ctfe_impl, rt_impl) }
}
/// Returns whether the pointer is properly aligned for `T`.
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ /// ```
+ /// #![feature(pointer_is_aligned)]
+ /// #![feature(pointer_byte_offsets)]
+ ///
+ /// // On some platforms, the alignment of i32 is less than 4.
+ /// #[repr(align(4))]
+ /// struct AlignedI32(i32);
+ ///
+ /// let mut data = AlignedI32(42);
+ /// let ptr = &mut data as *mut AlignedI32;
+ ///
+ /// assert!(ptr.is_aligned());
+ /// assert!(!ptr.wrapping_byte_add(1).is_aligned());
+ /// ```
+ ///
+ /// # At compiletime
+ /// **Note: Alignment at compiletime is experimental and subject to change. See the
+ /// [tracking issue] for details.**
+ ///
+ /// At compiletime, the compiler may not know where a value will end up in memory.
+ /// Calling this function on a pointer created from a reference at compiletime will only
+ /// return `true` if the pointer is guaranteed to be aligned. This means that the pointer
+ /// is never aligned if cast to a type with a stricter alignment than the reference's
+ /// underlying allocation.
+ ///
+ #[cfg_attr(bootstrap, doc = "```ignore")]
+ #[cfg_attr(not(bootstrap), doc = "```")]
+ /// #![feature(pointer_is_aligned)]
+ /// #![feature(const_pointer_is_aligned)]
+ /// #![feature(const_mut_refs)]
+ ///
+ /// // On some platforms, the alignment of primitives is less than their size.
+ /// #[repr(align(4))]
+ /// struct AlignedI32(i32);
+ /// #[repr(align(8))]
+ /// struct AlignedI64(i64);
+ ///
+ /// const _: () = {
+ /// let mut data = AlignedI32(42);
+ /// let ptr = &mut data as *mut AlignedI32;
+ /// assert!(ptr.is_aligned());
+ ///
+ /// // At runtime either `ptr1` or `ptr2` would be aligned, but at compiletime neither is aligned.
+ /// let ptr1 = ptr.cast::<AlignedI64>();
+ /// let ptr2 = ptr.wrapping_add(1).cast::<AlignedI64>();
+ /// assert!(!ptr1.is_aligned());
+ /// assert!(!ptr2.is_aligned());
+ /// };
+ /// ```
+ ///
+ /// Due to this behavior, it is possible that a runtime pointer derived from a compiletime
+ /// pointer is aligned, even if the compiletime pointer wasn't aligned.
+ ///
+ #[cfg_attr(bootstrap, doc = "```ignore")]
+ #[cfg_attr(not(bootstrap), doc = "```")]
+ /// #![feature(pointer_is_aligned)]
+ /// #![feature(const_pointer_is_aligned)]
+ ///
+ /// // On some platforms, the alignment of primitives is less than their size.
+ /// #[repr(align(4))]
+ /// struct AlignedI32(i32);
+ /// #[repr(align(8))]
+ /// struct AlignedI64(i64);
+ ///
+ /// // At compiletime, neither `COMPTIME_PTR` nor `COMPTIME_PTR + 1` is aligned.
+ /// // Also, note that mutable references are not allowed in the final value of constants.
+ /// const COMPTIME_PTR: *mut AlignedI32 = (&AlignedI32(42) as *const AlignedI32).cast_mut();
+ /// const _: () = assert!(!COMPTIME_PTR.cast::<AlignedI64>().is_aligned());
+ /// const _: () = assert!(!COMPTIME_PTR.wrapping_add(1).cast::<AlignedI64>().is_aligned());
+ ///
+ /// // At runtime, either `runtime_ptr` or `runtime_ptr + 1` is aligned.
+ /// let runtime_ptr = COMPTIME_PTR;
+ /// assert_ne!(
+ /// runtime_ptr.cast::<AlignedI64>().is_aligned(),
+ /// runtime_ptr.wrapping_add(1).cast::<AlignedI64>().is_aligned(),
+ /// );
+ /// ```
+ ///
+ /// If a pointer is created from a fixed address, this function behaves the same during
+ /// runtime and compiletime.
+ ///
+ #[cfg_attr(bootstrap, doc = "```ignore")]
+ #[cfg_attr(not(bootstrap), doc = "```")]
+ /// #![feature(pointer_is_aligned)]
+ /// #![feature(const_pointer_is_aligned)]
+ ///
+ /// // On some platforms, the alignment of primitives is less than their size.
+ /// #[repr(align(4))]
+ /// struct AlignedI32(i32);
+ /// #[repr(align(8))]
+ /// struct AlignedI64(i64);
+ ///
+ /// const _: () = {
+ /// let ptr = 40 as *mut AlignedI32;
+ /// assert!(ptr.is_aligned());
+ ///
+ /// // For pointers with a known address, runtime and compiletime behavior are identical.
+ /// let ptr1 = ptr.cast::<AlignedI64>();
+ /// let ptr2 = ptr.wrapping_add(1).cast::<AlignedI64>();
+ /// assert!(ptr1.is_aligned());
+ /// assert!(!ptr2.is_aligned());
+ /// };
+ /// ```
+ ///
+ /// [tracking issue]: https://github.com/rust-lang/rust/issues/104203
#[must_use]
#[inline]
#[unstable(feature = "pointer_is_aligned", issue = "96284")]
- pub fn is_aligned(self) -> bool
+ #[rustc_const_unstable(feature = "const_pointer_is_aligned", issue = "104203")]
+ pub const fn is_aligned(self) -> bool
where
T: Sized,
{
- self.is_aligned_to(core::mem::align_of::<T>())
+ self.is_aligned_to(mem::align_of::<T>())
}
/// Returns whether the pointer is aligned to `align`.
/// # Panics
///
/// The function panics if `align` is not a power-of-two (this includes 0).
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ /// ```
+ /// #![feature(pointer_is_aligned)]
+ /// #![feature(pointer_byte_offsets)]
+ ///
+ /// // On some platforms, the alignment of i32 is less than 4.
+ /// #[repr(align(4))]
+ /// struct AlignedI32(i32);
+ ///
+ /// let mut data = AlignedI32(42);
+ /// let ptr = &mut data as *mut AlignedI32;
+ ///
+ /// assert!(ptr.is_aligned_to(1));
+ /// assert!(ptr.is_aligned_to(2));
+ /// assert!(ptr.is_aligned_to(4));
+ ///
+ /// assert!(ptr.wrapping_byte_add(2).is_aligned_to(2));
+ /// assert!(!ptr.wrapping_byte_add(2).is_aligned_to(4));
+ ///
+ /// assert_ne!(ptr.is_aligned_to(8), ptr.wrapping_add(1).is_aligned_to(8));
+ /// ```
+ ///
+ /// # At compiletime
+ /// **Note: Alignment at compiletime is experimental and subject to change. See the
+ /// [tracking issue] for details.**
+ ///
+ /// At compiletime, the compiler may not know where a value will end up in memory.
+ /// Calling this function on a pointer created from a reference at compiletime will only
+ /// return `true` if the pointer is guaranteed to be aligned. This means that the pointer
+ /// cannot be stricter aligned than the reference's underlying allocation.
+ ///
+ #[cfg_attr(bootstrap, doc = "```ignore")]
+ #[cfg_attr(not(bootstrap), doc = "```")]
+ /// #![feature(pointer_is_aligned)]
+ /// #![feature(const_pointer_is_aligned)]
+ /// #![feature(const_mut_refs)]
+ ///
+ /// // On some platforms, the alignment of i32 is less than 4.
+ /// #[repr(align(4))]
+ /// struct AlignedI32(i32);
+ ///
+ /// const _: () = {
+ /// let mut data = AlignedI32(42);
+ /// let ptr = &mut data as *mut AlignedI32;
+ ///
+ /// assert!(ptr.is_aligned_to(1));
+ /// assert!(ptr.is_aligned_to(2));
+ /// assert!(ptr.is_aligned_to(4));
+ ///
+ /// // At compiletime, we know for sure that the pointer isn't aligned to 8.
+ /// assert!(!ptr.is_aligned_to(8));
+ /// assert!(!ptr.wrapping_add(1).is_aligned_to(8));
+ /// };
+ /// ```
+ ///
+ /// Due to this behavior, it is possible that a runtime pointer derived from a compiletime
+ /// pointer is aligned, even if the compiletime pointer wasn't aligned.
+ ///
+ #[cfg_attr(bootstrap, doc = "```ignore")]
+ #[cfg_attr(not(bootstrap), doc = "```")]
+ /// #![feature(pointer_is_aligned)]
+ /// #![feature(const_pointer_is_aligned)]
+ ///
+ /// // On some platforms, the alignment of i32 is less than 4.
+ /// #[repr(align(4))]
+ /// struct AlignedI32(i32);
+ ///
+ /// // At compiletime, neither `COMPTIME_PTR` nor `COMPTIME_PTR + 1` is aligned.
+ /// // Also, note that mutable references are not allowed in the final value of constants.
+ /// const COMPTIME_PTR: *mut AlignedI32 = (&AlignedI32(42) as *const AlignedI32).cast_mut();
+ /// const _: () = assert!(!COMPTIME_PTR.is_aligned_to(8));
+ /// const _: () = assert!(!COMPTIME_PTR.wrapping_add(1).is_aligned_to(8));
+ ///
+ /// // At runtime, either `runtime_ptr` or `runtime_ptr + 1` is aligned.
+ /// let runtime_ptr = COMPTIME_PTR;
+ /// assert_ne!(
+ /// runtime_ptr.is_aligned_to(8),
+ /// runtime_ptr.wrapping_add(1).is_aligned_to(8),
+ /// );
+ /// ```
+ ///
+ /// If a pointer is created from a fixed address, this function behaves the same during
+ /// runtime and compiletime.
+ ///
+ #[cfg_attr(bootstrap, doc = "```ignore")]
+ #[cfg_attr(not(bootstrap), doc = "```")]
+ /// #![feature(pointer_is_aligned)]
+ /// #![feature(const_pointer_is_aligned)]
+ ///
+ /// const _: () = {
+ /// let ptr = 40 as *mut u8;
+ /// assert!(ptr.is_aligned_to(1));
+ /// assert!(ptr.is_aligned_to(2));
+ /// assert!(ptr.is_aligned_to(4));
+ /// assert!(ptr.is_aligned_to(8));
+ /// assert!(!ptr.is_aligned_to(16));
+ /// };
+ /// ```
+ ///
+ /// [tracking issue]: https://github.com/rust-lang/rust/issues/104203
#[must_use]
#[inline]
#[unstable(feature = "pointer_is_aligned", issue = "96284")]
- pub fn is_aligned_to(self, align: usize) -> bool {
+ #[rustc_const_unstable(feature = "const_pointer_is_aligned", issue = "104203")]
+ pub const fn is_aligned_to(self, align: usize) -> bool {
if !align.is_power_of_two() {
panic!("is_aligned_to: align is not a power-of-two");
}
- // Cast is needed for `T: !Sized`
- self.cast::<u8>().addr() & align - 1 == 0
+ // We can't use the address of `self` in a `const fn`, so we use `align_offset` instead.
+ // The cast to `()` is used to
+ // 1. deal with fat pointers; and
+ // 2. ensure that `align_offset` doesn't actually try to compute an offset.
+ self.cast::<()>().align_offset(align) == 0
}
}
/// [`is_sorted`]: slice::is_sorted
#[unstable(feature = "is_sorted", reason = "new API", issue = "53485")]
#[must_use]
- pub fn is_sorted_by<F>(&self, mut compare: F) -> bool
+ pub fn is_sorted_by<'a, F>(&'a self, mut compare: F) -> bool
where
- F: FnMut(&T, &T) -> Option<Ordering>,
+ F: FnMut(&'a T, &'a T) -> Option<Ordering>,
{
self.iter().is_sorted_by(|a, b| compare(*a, *b))
}
#[inline]
#[unstable(feature = "is_sorted", reason = "new API", issue = "53485")]
#[must_use]
- pub fn is_sorted_by_key<F, K>(&self, f: F) -> bool
+ pub fn is_sorted_by_key<'a, F, K>(&'a self, f: F) -> bool
where
- F: FnMut(&T) -> K,
+ F: FnMut(&'a T) -> K,
K: PartialOrd,
{
self.iter().is_sorted_by_key(f)
let mut it = empty::<i32>();
assert_eq!(it.next(), None);
}
+
+#[test]
+fn test_repeat_n_drop() {
+ #[derive(Clone, Debug)]
+ struct DropCounter<'a>(&'a Cell<usize>);
+ impl Drop for DropCounter<'_> {
+ fn drop(&mut self) {
+ self.0.set(self.0.get() + 1);
+ }
+ }
+
+ // `repeat_n(x, 0)` drops `x` immediately
+ let count = Cell::new(0);
+ let item = DropCounter(&count);
+ let mut it = repeat_n(item, 0);
+ assert_eq!(count.get(), 1);
+ assert!(it.next().is_none());
+ assert_eq!(count.get(), 1);
+ drop(it);
+ assert_eq!(count.get(), 1);
+
+ // Dropping the iterator needs to drop the item if it's non-empty
+ let count = Cell::new(0);
+ let item = DropCounter(&count);
+ let it = repeat_n(item, 3);
+ assert_eq!(count.get(), 0);
+ drop(it);
+ assert_eq!(count.get(), 1);
+
+ // Dropping the iterator doesn't drop the item if it was exhausted
+ let count = Cell::new(0);
+ let item = DropCounter(&count);
+ let mut it = repeat_n(item, 3);
+ assert_eq!(count.get(), 0);
+ let x0 = it.next().unwrap();
+ assert_eq!(count.get(), 0);
+ let x1 = it.next().unwrap();
+ assert_eq!(count.get(), 0);
+ let x2 = it.next().unwrap();
+ assert_eq!(count.get(), 0);
+ assert!(it.next().is_none());
+ assert_eq!(count.get(), 0);
+ assert!(it.next().is_none());
+ assert_eq!(count.get(), 0);
+ drop(it);
+ assert_eq!(count.get(), 0);
+ drop((x0, x1, x2));
+ assert_eq!(count.get(), 3);
+}
#![feature(array_windows)]
#![feature(bigint_helper_methods)]
#![feature(cell_update)]
+#![feature(const_align_offset)]
#![feature(const_assume)]
#![feature(const_align_of_val_raw)]
#![feature(const_black_box)]
#![feature(const_nonnull_new)]
#![feature(const_num_from_num)]
#![feature(const_pointer_byte_offsets)]
+#![feature(const_pointer_is_aligned)]
#![feature(const_ptr_as_ref)]
#![feature(const_ptr_read)]
#![feature(const_ptr_write)]
#![feature(iter_is_partitioned)]
#![feature(iter_next_chunk)]
#![feature(iter_order_by)]
+#![feature(iter_repeat_n)]
#![feature(iterator_try_collect)]
#![feature(iterator_try_reduce)]
#![feature(const_mut_refs)]
#![feature(never_type)]
#![feature(unwrap_infallible)]
#![feature(pointer_byte_offsets)]
+#![feature(pointer_is_aligned)]
#![feature(portable_simd)]
#![feature(ptr_metadata)]
#![feature(once_cell)]
}
}
+#[test]
+#[cfg(not(bootstrap))]
+fn align_offset_zst_const() {
+ const {
+ // For pointers of stride = 0, the pointer is already aligned or it cannot be aligned at
+ // all, because no amount of elements will align the pointer.
+ let mut p = 1;
+ while p < 1024 {
+ assert!(ptr::invalid::<()>(p).align_offset(p) == 0);
+ if p != 1 {
+ assert!(ptr::invalid::<()>(p + 1).align_offset(p) == !0);
+ }
+ p = (p + 1).next_power_of_two();
+ }
+ }
+}
+
#[test]
fn align_offset_stride_one() {
// For pointers of stride = 1, the pointer can always be aligned. The offset is equal to
}
}
+#[test]
+#[cfg(not(bootstrap))]
+fn align_offset_stride_one_const() {
+ const {
+ // For pointers of stride = 1, the pointer can always be aligned. The offset is equal to
+ // number of bytes.
+ let mut align = 1;
+ while align < 1024 {
+ let mut ptr = 1;
+ while ptr < 2 * align {
+ let expected = ptr % align;
+ let offset = if expected == 0 { 0 } else { align - expected };
+ assert!(ptr::invalid::<u8>(ptr).align_offset(align) == offset);
+ ptr += 1;
+ }
+ align = (align + 1).next_power_of_two();
+ }
+ }
+}
+
#[test]
fn align_offset_various_strides() {
unsafe fn test_stride<T>(ptr: *const T, align: usize) -> bool {
assert!(!x);
}
+#[test]
+#[cfg(not(bootstrap))]
+fn align_offset_various_strides_const() {
+ const unsafe fn test_stride<T>(ptr: *const T, numptr: usize, align: usize) {
+ let mut expected = usize::MAX;
+ // Naive but definitely correct way to find the *first* aligned element of stride::<T>.
+ let mut el = 0;
+ while el < align {
+ if (numptr + el * ::std::mem::size_of::<T>()) % align == 0 {
+ expected = el;
+ break;
+ }
+ el += 1;
+ }
+ let got = ptr.align_offset(align);
+ assert!(got == expected);
+ }
+
+ const {
+ // For pointers of stride != 1, we verify the algorithm against the naivest possible
+ // implementation
+ let mut align = 1;
+ let limit = 32;
+ while align < limit {
+ let mut ptr = 1;
+ while ptr < 4 * align {
+ unsafe {
+ #[repr(packed)]
+ struct A3(u16, u8);
+ test_stride::<A3>(ptr::invalid::<A3>(ptr), ptr, align);
+
+ struct A4(u32);
+ test_stride::<A4>(ptr::invalid::<A4>(ptr), ptr, align);
+
+ #[repr(packed)]
+ struct A5(u32, u8);
+ test_stride::<A5>(ptr::invalid::<A5>(ptr), ptr, align);
+
+ #[repr(packed)]
+ struct A6(u32, u16);
+ test_stride::<A6>(ptr::invalid::<A6>(ptr), ptr, align);
+
+ #[repr(packed)]
+ struct A7(u32, u16, u8);
+ test_stride::<A7>(ptr::invalid::<A7>(ptr), ptr, align);
+
+ #[repr(packed)]
+ struct A8(u32, u32);
+ test_stride::<A8>(ptr::invalid::<A8>(ptr), ptr, align);
+
+ #[repr(packed)]
+ struct A9(u32, u32, u8);
+ test_stride::<A9>(ptr::invalid::<A9>(ptr), ptr, align);
+
+ #[repr(packed)]
+ struct A10(u32, u32, u16);
+ test_stride::<A10>(ptr::invalid::<A10>(ptr), ptr, align);
+
+ test_stride::<u32>(ptr::invalid::<u32>(ptr), ptr, align);
+ test_stride::<u128>(ptr::invalid::<u128>(ptr), ptr, align);
+ }
+ ptr += 1;
+ }
+ align = (align + 1).next_power_of_two();
+ }
+ }
+}
+
+#[test]
+#[cfg(not(bootstrap))]
+fn align_offset_with_provenance_const() {
+ const {
+ // On some platforms (e.g. msp430-none-elf), the alignment of `i32` is less than 4.
+ #[repr(align(4))]
+ struct AlignedI32(i32);
+
+ let data = AlignedI32(42);
+
+ // `stride % align == 0` (usual case)
+
+ let ptr: *const i32 = &data.0;
+ assert!(ptr.align_offset(1) == 0);
+ assert!(ptr.align_offset(2) == 0);
+ assert!(ptr.align_offset(4) == 0);
+ assert!(ptr.align_offset(8) == usize::MAX);
+ assert!(ptr.wrapping_byte_add(1).align_offset(1) == 0);
+ assert!(ptr.wrapping_byte_add(1).align_offset(2) == usize::MAX);
+ assert!(ptr.wrapping_byte_add(2).align_offset(1) == 0);
+ assert!(ptr.wrapping_byte_add(2).align_offset(2) == 0);
+ assert!(ptr.wrapping_byte_add(2).align_offset(4) == usize::MAX);
+ assert!(ptr.wrapping_byte_add(3).align_offset(1) == 0);
+ assert!(ptr.wrapping_byte_add(3).align_offset(2) == usize::MAX);
+
+ assert!(ptr.wrapping_add(42).align_offset(4) == 0);
+ assert!(ptr.wrapping_add(42).align_offset(8) == usize::MAX);
+
+ let ptr1: *const i8 = ptr.cast();
+ assert!(ptr1.align_offset(1) == 0);
+ assert!(ptr1.align_offset(2) == 0);
+ assert!(ptr1.align_offset(4) == 0);
+ assert!(ptr1.align_offset(8) == usize::MAX);
+ assert!(ptr1.wrapping_byte_add(1).align_offset(1) == 0);
+ assert!(ptr1.wrapping_byte_add(1).align_offset(2) == 1);
+ assert!(ptr1.wrapping_byte_add(1).align_offset(4) == 3);
+ assert!(ptr1.wrapping_byte_add(1).align_offset(8) == usize::MAX);
+ assert!(ptr1.wrapping_byte_add(2).align_offset(1) == 0);
+ assert!(ptr1.wrapping_byte_add(2).align_offset(2) == 0);
+ assert!(ptr1.wrapping_byte_add(2).align_offset(4) == 2);
+ assert!(ptr1.wrapping_byte_add(2).align_offset(8) == usize::MAX);
+ assert!(ptr1.wrapping_byte_add(3).align_offset(1) == 0);
+ assert!(ptr1.wrapping_byte_add(3).align_offset(2) == 1);
+ assert!(ptr1.wrapping_byte_add(3).align_offset(4) == 1);
+ assert!(ptr1.wrapping_byte_add(3).align_offset(8) == usize::MAX);
+
+ let ptr2: *const i16 = ptr.cast();
+ assert!(ptr2.align_offset(1) == 0);
+ assert!(ptr2.align_offset(2) == 0);
+ assert!(ptr2.align_offset(4) == 0);
+ assert!(ptr2.align_offset(8) == usize::MAX);
+ assert!(ptr2.wrapping_byte_add(1).align_offset(1) == 0);
+ assert!(ptr2.wrapping_byte_add(1).align_offset(2) == usize::MAX);
+ assert!(ptr2.wrapping_byte_add(2).align_offset(1) == 0);
+ assert!(ptr2.wrapping_byte_add(2).align_offset(2) == 0);
+ assert!(ptr2.wrapping_byte_add(2).align_offset(4) == 1);
+ assert!(ptr2.wrapping_byte_add(2).align_offset(8) == usize::MAX);
+ assert!(ptr2.wrapping_byte_add(3).align_offset(1) == 0);
+ assert!(ptr2.wrapping_byte_add(3).align_offset(2) == usize::MAX);
+
+ let ptr3: *const i64 = ptr.cast();
+ assert!(ptr3.align_offset(1) == 0);
+ assert!(ptr3.align_offset(2) == 0);
+ assert!(ptr3.align_offset(4) == 0);
+ assert!(ptr3.align_offset(8) == usize::MAX);
+ assert!(ptr3.wrapping_byte_add(1).align_offset(1) == 0);
+ assert!(ptr3.wrapping_byte_add(1).align_offset(2) == usize::MAX);
+
+ // `stride % align != 0` (edge case)
+
+ let ptr4: *const [u8; 3] = ptr.cast();
+ assert!(ptr4.align_offset(1) == 0);
+ assert!(ptr4.align_offset(2) == 0);
+ assert!(ptr4.align_offset(4) == 0);
+ assert!(ptr4.align_offset(8) == usize::MAX);
+ assert!(ptr4.wrapping_byte_add(1).align_offset(1) == 0);
+ assert!(ptr4.wrapping_byte_add(1).align_offset(2) == 1);
+ assert!(ptr4.wrapping_byte_add(1).align_offset(4) == 1);
+ assert!(ptr4.wrapping_byte_add(1).align_offset(8) == usize::MAX);
+ assert!(ptr4.wrapping_byte_add(2).align_offset(1) == 0);
+ assert!(ptr4.wrapping_byte_add(2).align_offset(2) == 0);
+ assert!(ptr4.wrapping_byte_add(2).align_offset(4) == 2);
+ assert!(ptr4.wrapping_byte_add(2).align_offset(8) == usize::MAX);
+ assert!(ptr4.wrapping_byte_add(3).align_offset(1) == 0);
+ assert!(ptr4.wrapping_byte_add(3).align_offset(2) == 1);
+ assert!(ptr4.wrapping_byte_add(3).align_offset(4) == 3);
+ assert!(ptr4.wrapping_byte_add(3).align_offset(8) == usize::MAX);
+
+ let ptr5: *const [u8; 5] = ptr.cast();
+ assert!(ptr5.align_offset(1) == 0);
+ assert!(ptr5.align_offset(2) == 0);
+ assert!(ptr5.align_offset(4) == 0);
+ assert!(ptr5.align_offset(8) == usize::MAX);
+ assert!(ptr5.wrapping_byte_add(1).align_offset(1) == 0);
+ assert!(ptr5.wrapping_byte_add(1).align_offset(2) == 1);
+ assert!(ptr5.wrapping_byte_add(1).align_offset(4) == 3);
+ assert!(ptr5.wrapping_byte_add(1).align_offset(8) == usize::MAX);
+ assert!(ptr5.wrapping_byte_add(2).align_offset(1) == 0);
+ assert!(ptr5.wrapping_byte_add(2).align_offset(2) == 0);
+ assert!(ptr5.wrapping_byte_add(2).align_offset(4) == 2);
+ assert!(ptr5.wrapping_byte_add(2).align_offset(8) == usize::MAX);
+ assert!(ptr5.wrapping_byte_add(3).align_offset(1) == 0);
+ assert!(ptr5.wrapping_byte_add(3).align_offset(2) == 1);
+ assert!(ptr5.wrapping_byte_add(3).align_offset(4) == 1);
+ assert!(ptr5.wrapping_byte_add(3).align_offset(8) == usize::MAX);
+ }
+}
+
+#[test]
+fn align_offset_issue_103361() {
+ #[cfg(target_pointer_width = "64")]
+ const SIZE: usize = 1 << 47;
+ #[cfg(target_pointer_width = "32")]
+ const SIZE: usize = 1 << 30;
+ #[cfg(target_pointer_width = "16")]
+ const SIZE: usize = 1 << 13;
+ struct HugeSize([u8; SIZE - 1]);
+ let _ = (SIZE as *const HugeSize).align_offset(SIZE);
+}
+
+#[test]
+#[cfg(not(bootstrap))]
+fn align_offset_issue_103361_const() {
+ #[cfg(target_pointer_width = "64")]
+ const SIZE: usize = 1 << 47;
+ #[cfg(target_pointer_width = "32")]
+ const SIZE: usize = 1 << 30;
+ #[cfg(target_pointer_width = "16")]
+ const SIZE: usize = 1 << 13;
+ struct HugeSize([u8; SIZE - 1]);
+
+ const {
+ assert!(ptr::invalid::<HugeSize>(SIZE - 1).align_offset(SIZE) == SIZE - 1);
+ assert!(ptr::invalid::<HugeSize>(SIZE).align_offset(SIZE) == 0);
+ assert!(ptr::invalid::<HugeSize>(SIZE + 1).align_offset(SIZE) == 1);
+ }
+}
+
+#[test]
+fn is_aligned() {
+ let data = 42;
+ let ptr: *const i32 = &data;
+ assert!(ptr.is_aligned());
+ assert!(ptr.is_aligned_to(1));
+ assert!(ptr.is_aligned_to(2));
+ assert!(ptr.is_aligned_to(4));
+ assert!(ptr.wrapping_byte_add(2).is_aligned_to(1));
+ assert!(ptr.wrapping_byte_add(2).is_aligned_to(2));
+ assert!(!ptr.wrapping_byte_add(2).is_aligned_to(4));
+
+ // At runtime either `ptr` or `ptr+1` is aligned to 8.
+ assert_ne!(ptr.is_aligned_to(8), ptr.wrapping_add(1).is_aligned_to(8));
+}
+
+#[test]
+#[cfg(not(bootstrap))]
+fn is_aligned_const() {
+ const {
+ let data = 42;
+ let ptr: *const i32 = &data;
+ assert!(ptr.is_aligned());
+ assert!(ptr.is_aligned_to(1));
+ assert!(ptr.is_aligned_to(2));
+ assert!(ptr.is_aligned_to(4));
+ assert!(ptr.wrapping_byte_add(2).is_aligned_to(1));
+ assert!(ptr.wrapping_byte_add(2).is_aligned_to(2));
+ assert!(!ptr.wrapping_byte_add(2).is_aligned_to(4));
+
+ // At comptime neither `ptr` nor `ptr+1` is aligned to 8.
+ assert!(!ptr.is_aligned_to(8));
+ assert!(!ptr.wrapping_add(1).is_aligned_to(8));
+ }
+}
+
+#[test]
+#[cfg(bootstrap)]
+fn is_aligned_const() {
+ const {
+ let data = 42;
+ let ptr: *const i32 = &data;
+ // The bootstrap compiler always returns false for is_aligned.
+ assert!(!ptr.is_aligned());
+ assert!(!ptr.is_aligned_to(1));
+ }
+}
+
#[test]
fn offset_from() {
let mut a = [0; 5];
// L4Re is unix family but does not yet support unwinding.
#[path = "dummy.rs"]
mod real_imp;
- } else if #[cfg(target_env = "msvc")] {
+ } else if #[cfg(all(target_env = "msvc", not(target_arch = "arm")))] {
+ // LLVM does not support unwinding on 32 bit ARM msvc (thumbv7a-pc-windows-msvc)
#[path = "seh.rs"]
mod real_imp;
} else if #[cfg(any(
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn asinh(self) -> f32 {
- (self.abs() + ((self * self) + 1.0).sqrt()).ln().copysign(self)
+ let ax = self.abs();
+ let ix = 1.0 / ax;
+ (ax + (ax / (Self::hypot(1.0, ix) + ix))).ln_1p().copysign(self)
}
/// Inverse hyperbolic cosine function.
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn acosh(self) -> f32 {
- if self < 1.0 { Self::NAN } else { (self + ((self * self) - 1.0).sqrt()).ln() }
+ if self < 1.0 {
+ Self::NAN
+ } else {
+ (self + ((self - 1.0).sqrt() * (self + 1.0).sqrt())).ln()
+ }
}
/// Inverse hyperbolic tangent function.
assert_approx_eq!((-2.0f32).asinh(), -1.443635475178810342493276740273105f32);
// regression test for the catastrophic cancellation fixed in 72486
assert_approx_eq!((-3000.0f32).asinh(), -8.699514775987968673236893537700647f32);
+
+ // test for low accuracy from issue 104548
+ assert_approx_eq!(60.0f32, 60.0f32.sinh().asinh());
+ // mul needed for approximate comparison to be meaningful
+ assert_approx_eq!(1.0f32, 1e-15f32.sinh().asinh() * 1e15f32);
}
#[test]
assert!(nan.acosh().is_nan());
assert_approx_eq!(2.0f32.acosh(), 1.31695789692481670862504634730796844f32);
assert_approx_eq!(3.0f32.acosh(), 1.76274717403908605046521864995958461f32);
+
+ // test for low accuracy from issue 104548
+ assert_approx_eq!(60.0f32, 60.0f32.cosh().acosh());
}
#[test]
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn asinh(self) -> f64 {
- (self.abs() + ((self * self) + 1.0).sqrt()).ln().copysign(self)
+ let ax = self.abs();
+ let ix = 1.0 / ax;
+ (ax + (ax / (Self::hypot(1.0, ix) + ix))).ln_1p().copysign(self)
}
/// Inverse hyperbolic cosine function.
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn acosh(self) -> f64 {
- if self < 1.0 { Self::NAN } else { (self + ((self * self) - 1.0).sqrt()).ln() }
+ if self < 1.0 {
+ Self::NAN
+ } else {
+ (self + ((self - 1.0).sqrt() * (self + 1.0).sqrt())).ln()
+ }
}
/// Inverse hyperbolic tangent function.
assert_approx_eq!((-2.0f64).asinh(), -1.443635475178810342493276740273105f64);
// regression test for the catastrophic cancellation fixed in 72486
assert_approx_eq!((-67452098.07139316f64).asinh(), -18.72007542627454439398548429400083);
+
+ // test for low accuracy from issue 104548
+ assert_approx_eq!(60.0f64, 60.0f64.sinh().asinh());
+ // mul needed for approximate comparison to be meaningful
+ assert_approx_eq!(1.0f64, 1e-15f64.sinh().asinh() * 1e15f64);
}
#[test]
assert!(nan.acosh().is_nan());
assert_approx_eq!(2.0f64.acosh(), 1.31695789692481670862504634730796844f64);
assert_approx_eq!(3.0f64.acosh(), 1.76274717403908605046521864995958461f64);
+
+ // test for low accuracy from issue 104548
+ assert_approx_eq!(60.0f64, 60.0f64.cosh().acosh());
}
#[test]
/// A value which is initialized on the first access.
///
-/// This type is a thread-safe `Lazy`, and can be used in statics.
+/// This type is a thread-safe [`LazyCell`], and can be used in statics.
+///
+/// [`LazyCell`]: crate::cell::LazyCell
///
/// # Examples
///
/// A synchronization primitive which can be written to only once.
///
-/// This type is a thread-safe `OnceCell`.
+/// This type is a thread-safe [`OnceCell`], and can be used in statics.
+///
+/// [`OnceCell`]: crate::cell::OnceCell
///
/// # Examples
///
#[unstable(feature = "once_cell", issue = "74465")]
pub struct OnceLock<T> {
once: Once,
- // Whether or not the value is initialized is tracked by `state_and_queue`.
+ // Whether or not the value is initialized is tracked by `once.is_completed()`.
value: UnsafeCell<MaybeUninit<T>>,
/// `PhantomData` to make sure dropck understands we're dropping T in our Drop impl.
///
}
}
-#[cfg(any(target_os = "macos", target_os = "ios", target_os = "watchos"))]
+#[cfg(any(
+ all(target_os = "macos", any(not(target_arch = "aarch64"))),
+ target_os = "ios",
+ target_os = "watchos"
+))]
mod inner {
use crate::sync::atomic::{AtomicU64, Ordering};
use crate::sys::cvt;
}
}
-#[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "watchos")))]
+#[cfg(not(any(
+ all(target_os = "macos", any(not(target_arch = "aarch64"))),
+ target_os = "ios",
+ target_os = "watchos"
+)))]
mod inner {
use crate::fmt;
use crate::mem::MaybeUninit;
impl Instant {
pub fn now() -> Instant {
- Instant { t: Timespec::now(libc::CLOCK_MONOTONIC) }
+ #[cfg(target_os = "macos")]
+ const clock_id: libc::clockid_t = libc::CLOCK_UPTIME_RAW;
+ #[cfg(not(target_os = "macos"))]
+ const clock_id: libc::clockid_t = libc::CLOCK_MONOTONIC;
+ Instant { t: Timespec::now(clock_id) }
}
pub fn checked_sub_instant(&self, other: &Instant) -> Option<Duration> {
}
}
- #[cfg(not(any(target_os = "dragonfly", target_os = "espidf", target_os = "horizon")))]
- pub type clock_t = libc::c_int;
- #[cfg(any(target_os = "dragonfly", target_os = "espidf", target_os = "horizon"))]
- pub type clock_t = libc::c_ulong;
-
impl Timespec {
- pub fn now(clock: clock_t) -> Timespec {
+ pub fn now(clock: libc::clockid_t) -> Timespec {
// Try to use 64-bit time in preparation for Y2038.
#[cfg(all(target_os = "linux", target_env = "gnu", target_pointer_width = "32"))]
{
use crate::os::windows::prelude::*;
+use crate::borrow::Cow;
use crate::ffi::OsString;
use crate::fmt;
use crate::io::{self, BorrowedCursor, Error, IoSlice, IoSliceMut, SeekFrom};
}
}
impl<'a> Iterator for DirBuffIter<'a> {
- type Item = (&'a [u16], bool);
+ type Item = (Cow<'a, [u16]>, bool);
fn next(&mut self) -> Option<Self::Item> {
use crate::mem::size_of;
let buffer = &self.buffer?[self.cursor..];
// `FileNameLength` bytes)
let (name, is_directory, next_entry) = unsafe {
let info = buffer.as_ptr().cast::<c::FILE_ID_BOTH_DIR_INFO>();
- // Guaranteed to be aligned in documentation for
+ // While this is guaranteed to be aligned in documentation for
// https://docs.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-file_id_both_dir_info
- assert!(info.is_aligned());
- let next_entry = (*info).NextEntryOffset as usize;
- let name = crate::slice::from_raw_parts(
+ // it does not seem that reality is so kind, and assuming this
+ // caused crashes in some cases (https://github.com/rust-lang/rust/issues/104530)
+ // presumably, this can be blamed on buggy filesystem drivers, but who knows.
+ let next_entry = ptr::addr_of!((*info).NextEntryOffset).read_unaligned() as usize;
+ let length = ptr::addr_of!((*info).FileNameLength).read_unaligned() as usize;
+ let attrs = ptr::addr_of!((*info).FileAttributes).read_unaligned();
+ let name = from_maybe_unaligned(
ptr::addr_of!((*info).FileName).cast::<u16>(),
- (*info).FileNameLength as usize / size_of::<u16>(),
+ length / size_of::<u16>(),
);
- let is_directory = ((*info).FileAttributes & c::FILE_ATTRIBUTE_DIRECTORY) != 0;
+ let is_directory = (attrs & c::FILE_ATTRIBUTE_DIRECTORY) != 0;
(name, is_directory, next_entry)
};
// Skip `.` and `..` pseudo entries.
const DOT: u16 = b'.' as u16;
- match name {
+ match &name[..] {
[DOT] | [DOT, DOT] => self.next(),
_ => Some((name, is_directory)),
}
}
}
+unsafe fn from_maybe_unaligned<'a>(p: *const u16, len: usize) -> Cow<'a, [u16]> {
+ if p.is_aligned() {
+ Cow::Borrowed(crate::slice::from_raw_parts(p, len))
+ } else {
+ Cow::Owned((0..len).map(|i| p.add(i).read_unaligned()).collect())
+ }
+}
+
/// Open a link relative to the parent directory, ensure no symlinks are followed.
fn open_link_no_reparse(parent: &File, name: &[u16], access: u32) -> io::Result<File> {
// This is implemented using the lower level `NtCreateFile` function as
if is_directory {
let child_dir = open_link_no_reparse(
&dir,
- name,
+ &name,
c::SYNCHRONIZE | c::DELETE | c::FILE_LIST_DIRECTORY,
)?;
dirlist.push(child_dir);
} else {
for i in 1..=MAX_RETRIES {
- let result = open_link_no_reparse(&dir, name, c::SYNCHRONIZE | c::DELETE);
+ let result = open_link_no_reparse(&dir, &name, c::SYNCHRONIZE | c::DELETE);
match result {
Ok(f) => delete(&f)?,
// Already deleted, so skip.
//!
//! ## Stack size
//!
-//! The default stack size for spawned threads is 2 MiB, though this particular stack size is
-//! subject to change in the future. There are two ways to manually specify the stack size for
-//! spawned threads:
+//! The default stack size is platform-dependent and subject to change. Currently it is 2MB on all
+//! Tier-1 platforms. There are two ways to manually specify the stack size for spawned threads:
//!
//! * Build the thread with [`Builder`] and pass the desired stack size to [`Builder::stack_size`].
//! * Set the `RUST_MIN_STACK` environment variable to an integer representing the desired stack
// Changing the order of instant math shouldn't change the results,
// especially when the expression reduces to X + identity.
assert_eq!((now + offset) - now, (now - now) + offset);
+
+ // On any platform, `Instant` should have the same resolution as `Duration` (e.g. 1 nanosecond)
+ // or better. Otherwise, math will be non-associative (see #91417).
+ let now = Instant::now();
+ let provided_offset = Duration::from_nanos(1);
+ let later = now + provided_offset;
+ let measured_offset = later - now;
+ assert_eq!(measured_offset, provided_offset);
}
#[test]
} // cfg_if!
cfg_if::cfg_if! {
-if #[cfg(all(windows, target_arch = "x86_64", target_env = "gnu"))] {
+if #[cfg(all(windows, any(target_arch = "aarch64", target_arch = "x86_64"), target_env = "gnu"))] {
// We declare these as opaque types. This is fine since you just need to
// pass them to _GCC_specific_handler and forget about them.
pub enum EXCEPTION_RECORD {}
[[package]]
name = "ntapi"
-version = "0.3.7"
+version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c28774a7fd2fbb4f0babd8237ce554b73af68021b5f695a3cebd6c59bac0980f"
+checksum = "bc51db7b362b205941f71232e56c625156eb9a929f8cf74a428fd5bc094a4afc"
dependencies = [
"winapi",
]
[[package]]
name = "sysinfo"
-version = "0.24.2"
+version = "0.26.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9a2809487b962344ca55d9aea565f9ffbcb6929780802217acc82561f6746770"
+checksum = "c375d5fd899e32847b8566e10598d6e9f1d9b55ec6de3cdf9e7da4bdc51371bc"
dependencies = [
"cfg-if",
"core-foundation-sys",
walkdir = "2"
# Dependencies needed by the build-metrics feature
-sysinfo = { version = "0.24.1", optional = true }
+sysinfo = { version = "0.26.0", optional = true }
[target.'cfg(windows)'.dependencies.winapi]
version = "0.3"
fn run(self, builder: &Builder<'_>) -> Interned<PathBuf> {
let compiler = self.compiler;
let host_dir = builder.out.join(&compiler.host.triple);
- let sysroot = if compiler.stage == 0 {
- host_dir.join("stage0-sysroot")
- } else if builder.download_rustc() {
- host_dir.join("ci-rustc-sysroot")
- } else {
- host_dir.join(format!("stage{}", compiler.stage))
+
+ let sysroot_dir = |stage| {
+ if stage == 0 {
+ host_dir.join("stage0-sysroot")
+ } else if builder.download_rustc() && compiler.stage != builder.top_stage {
+ host_dir.join("ci-rustc-sysroot")
+ } else {
+ host_dir.join(format!("stage{}", stage))
+ }
};
+ let sysroot = sysroot_dir(compiler.stage);
+
let _ = fs::remove_dir_all(&sysroot);
t!(fs::create_dir_all(&sysroot));
"Cross-compiling is not yet supported with `download-rustc`",
);
- // #102002, cleanup stage1 and stage0-sysroot folders when using download-rustc so people don't use old versions of the toolchain by accident.
- let _ = fs::remove_dir_all(host_dir.join("stage1"));
- let _ = fs::remove_dir_all(host_dir.join("stage0-sysroot"));
+ // #102002, cleanup old toolchain folders when using download-rustc so people don't use them by accident.
+ for stage in 0..=2 {
+ if stage != compiler.stage {
+ let dir = sysroot_dir(stage);
+ if !dir.ends_with("ci-rustc-sysroot") {
+ let _ = fs::remove_dir_all(dir);
+ }
+ }
+ }
// Copy the compiler into the correct sysroot.
let ci_rustc_dir =
/// Return whether we will use a downloaded, pre-compiled version of rustc, or just build from source.
pub(crate) fn download_rustc(&self) -> bool {
- static DOWNLOAD_RUSTC: OnceCell<bool> = OnceCell::new();
+ self.download_rustc_commit().is_some()
+ }
+
+ pub(crate) fn download_rustc_commit(&self) -> Option<&'static str> {
+ static DOWNLOAD_RUSTC: OnceCell<Option<String>> = OnceCell::new();
if self.dry_run() && DOWNLOAD_RUSTC.get().is_none() {
// avoid trying to actually download the commit
- return false;
+ return None;
}
- *DOWNLOAD_RUSTC.get_or_init(|| match &self.download_rustc_commit {
- None => false,
- Some(commit) => {
- self.download_ci_rustc(commit);
- true
- }
- })
+ DOWNLOAD_RUSTC
+ .get_or_init(|| match &self.download_rustc_commit {
+ None => None,
+ Some(commit) => {
+ self.download_ci_rustc(commit);
+ Some(commit.clone())
+ }
+ })
+ .as_deref()
}
pub(crate) fn initial_rustfmt(&self) -> Option<PathBuf> {
cpu_threads_count: system.cpus().len(),
cpu_model: system.cpus()[0].brand().into(),
- memory_total_bytes: system.total_memory() * 1024,
+ memory_total_bytes: system.total_memory(),
};
let steps = std::mem::take(&mut state.finished_steps);
// instead of hard-coding this test
if entry.file_name() == "link_to_definition" {
cargo.env("RUSTDOCFLAGS", "-Zunstable-options --generate-link-to-definition");
+ } else if entry.file_name() == "scrape_examples" {
+ cargo.arg("-Zrustdoc-scrape-examples=examples");
}
builder.run(&mut cargo);
}
cmd.arg("--src-base").arg(builder.src.join("src/test").join(suite));
cmd.arg("--build-base").arg(testdir(builder, compiler.host).join(suite));
+ cmd.arg("--sysroot-base").arg(builder.sysroot(compiler));
cmd.arg("--stage-id").arg(format!("stage{}-{}", compiler.stage, target));
cmd.arg("--suite").arg(suite);
cmd.arg("--mode").arg(mode);
cmd.arg("--channel").arg(&builder.config.channel);
+ if let Some(commit) = builder.config.download_rustc_commit() {
+ cmd.env("FAKE_DOWNLOAD_RUSTC_PREFIX", format!("/rustc/{commit}"));
+ }
+
builder.ci_env.force_coloring_in_ci(&mut cmd);
builder.info(&format!(
-0.13.1
\ No newline at end of file
+0.13.2
\ No newline at end of file
[dependencies]
arrayvec = { version = "0.7", default-features = false }
askama = { version = "0.11", default-features = false, features = ["config"] }
-atty = "0.2"
itertools = "0.10.1"
minifier = "0.2.2"
once_cell = "1.10.0"
) {
Ok(p) => p,
Err(e) => {
- diag.struct_err(&e.to_string()).emit();
+ diag.struct_err(e).emit();
return Err(1);
}
};
) {
Ok(p) => p,
Err(e) => {
- diag.struct_err(&e.to_string()).emit();
+ diag.struct_err(e).emit();
return Err(1);
}
};
);
if line_ranges.len() > 1 {
- write!(w, r#"<span class="prev">≺</span> <span class="next">≻</span>"#);
+ write!(w, r#"<button class="prev">≺</button> <button class="next">≻</button>"#);
}
// Look for the example file in the source map if it exists, otherwise return a dummy span
collect_paths_for_type, document, ensure_trailing_slash, get_filtered_impls_for_reference,
item_ty_to_section, notable_traits_button, notable_traits_json, render_all_impls,
render_assoc_item, render_assoc_items, render_attributes_in_code, render_attributes_in_pre,
- render_impl, render_rightside, render_stability_since_raw, AssocItemLink, Context,
- ImplRenderingParameters,
+ render_impl, render_rightside, render_stability_since_raw,
+ render_stability_since_raw_with_extra, AssocItemLink, Context, ImplRenderingParameters,
};
use crate::clean;
use crate::config::ModuleSorting;
document_non_exhaustive_header(it)
);
document_non_exhaustive(w, it);
+ write!(w, "<div class=\"variants\">");
for variant in e.variants() {
let id = cx.derive_id(format!("{}.{}", ItemType::Variant, variant.name.unwrap()));
write!(
w,
- "<h3 id=\"{id}\" class=\"variant small-section-header\">\
- <a href=\"#{id}\" class=\"anchor field\"></a>\
- <code>{name}",
+ "<section id=\"{id}\" class=\"variant\">\
+ <a href=\"#{id}\" class=\"anchor\"></a>",
id = id,
- name = variant.name.unwrap()
);
- if let clean::VariantItem(clean::Variant::Tuple(ref s)) = *variant.kind {
- w.write_str("(");
- print_tuple_struct_fields(w, cx, s);
- w.write_str(")");
- }
- w.write_str("</code>");
- render_stability_since_raw(
+ render_stability_since_raw_with_extra(
w,
variant.stable_since(tcx),
variant.const_stability(tcx),
it.stable_since(tcx),
it.const_stable_since(tcx),
+ " rightside",
);
- w.write_str("</h3>");
+ write!(w, "<h3 class=\"code-header\">{name}", name = variant.name.unwrap());
+ if let clean::VariantItem(clean::Variant::Tuple(ref s)) = *variant.kind {
+ w.write_str("(");
+ print_tuple_struct_fields(w, cx, s);
+ w.write_str(")");
+ }
+ w.write_str("</h3></section>");
use crate::clean::Variant;
write!(
w,
"<div class=\"sub-variant-field\">\
- <span id=\"{id}\" class=\"variant small-section-header\">\
+ <span id=\"{id}\" class=\"small-section-header\">\
<a href=\"#{id}\" class=\"anchor field\"></a>\
<code>{f}: {t}</code>\
</span>",
document(w, cx, variant, Some(it), HeadingOffset::H4);
}
+ write!(w, "</div>");
}
let def_id = it.item_id.expect_def_id();
render_assoc_items(w, cx, it, def_id, AssocItemRender::All);
}
}
SourceContext::Embedded { offset, needs_expansion } => {
- extra =
- if needs_expansion { Some(r#"<span class="expand">↕</span>"#) } else { None };
+ extra = if needs_expansion {
+ Some(r#"<button class="expand">↕</button>"#)
+ } else {
+ None
+ };
for line_number in 1..=lines {
let line = line_number + offset;
writeln!(line_numbers, "<span>{line}</span>")
.sidebar {
font-size: 0.875rem;
- width: 200px;
- min-width: 200px;
+ flex: 0 0 200px;
overflow-y: scroll;
position: sticky;
height: 100vh;
}
.rustdoc.source .sidebar {
- width: 50px;
- min-width: 0px;
- max-width: 300px;
- flex-grow: 0;
- flex-shrink: 0;
- flex-basis: auto;
+ flex-basis: 50px;
border-right: 1px solid;
overflow-x: hidden;
/* The sidebar is by default hidden */
.source-sidebar-expanded .source .sidebar {
overflow-y: auto;
- width: 300px;
+ flex-basis: 300px;
}
.source-sidebar-expanded .source .sidebar > *:not(#sidebar-toggle) {
}
.small-section-header {
- display: flex;
- justify-content: space-between;
position: relative;
}
display: initial;
}
-.impl:hover > .anchor, .trait-impl:hover > .anchor {
+.impl:hover > .anchor, .trait-impl:hover > .anchor, .variant:hover > .anchor {
display: inline-block;
position: absolute;
}
font-size: 1.25rem;
}
-h3.variant {
- font-weight: 600;
- font-size: 1.125rem;
- margin-bottom: 10px;
-}
-
.sub-variant h4 {
font-size: 1rem;
font-weight: 400;
background-color: var(--button-background-color);
border: 1px solid var(--border-color);
border-radius: 2px;
+ color: var(--settings-button-color);
+}
+
+#settings-menu > a:hover, #settings-menu > a:focus,
+#help-button > a:hover, #help-button > a:focus {
+ border-color: var(--settings-button-border-focus);
}
#copy-path {
border: solid 1px var(--border-color);
border-radius: 3px;
cursor: default;
+ color: var(--kbd--color);
+ background-color: var(--kbd-background);
+ box-shadow: inset 0 -1px 0 var(--kbd-box-shadow-color);
}
ul.all-items > li {
z-index: 11;
/* Reduce height slightly to account for mobile topbar. */
height: calc(100vh - 45px);
+ width: 200px;
}
/* The source view uses a different design for the sidebar toggle, and doesn't have a topbar,
}
}
+.variant,
.implementors-toggle > summary,
.impl,
#implementors-list > .docblock,
margin-bottom: 0.75em;
}
+.variants > .docblock,
.impl-items > .rustdoc-toggle[open]:not(:last-child),
.methods > .rustdoc-toggle[open]:not(:last-child),
.implementors-toggle[open]:not(:last-child) {
top: 0.25em;
z-index: 1;
cursor: pointer;
+ padding: 0;
+ background: none;
+ border: none;
+ /* iOS button gradient: https://stackoverflow.com/q/5438567 */
+ -webkit-appearance: none;
+ opacity: 1;
}
.scraped-example .code-wrapper .prev {
right: 2.25em;
--main-background-color: #0f1419;
--main-color: #c5c5c5;
--settings-input-color: #ffb454;
+ --settings-button-color: #fff;
+ --settings-button-border-focus: #e0e0e0;
--sidebar-background-color: #14191f;
--sidebar-background-color-hover: rgba(70, 70, 70, 0.33);
--code-block-background-color: #191f26;
--target-border-color: rgba(255, 180, 76, 0.85);
--tooltip-background-color: #314559;
--tooltip-color: #c5c5c5;
+ --kbd-color: #c5c5c5;
+ --kbd-background: #314559;
+ --kbd-box-shadow-color: #5c6773;
--rust-logo-filter: drop-shadow(1px 0 0px #fff)
drop-shadow(0 1px 0 #fff)
drop-shadow(-1px 0 0 #fff)
pre.rust .self, pre.rust .bool-val, pre.rust .prelude-val, pre.rust .attribute {}
pre.rust .kw-2, pre.rust .prelude-ty {}
-kbd {
- color: #c5c5c5;
- background-color: #314559;
- box-shadow: inset 0 -1px 0 #5c6773;
-}
-
-#settings-menu > a, #help-button > a {
- color: #fff;
-}
-
#settings-menu > a img {
filter: invert(100);
}
-#settings-menu > a:hover, #settings-menu > a:focus,
-#help-button > a:hover, #help-button > a:focus {
- border-color: #e0e0e0;
-}
-
.search-results .result-name span.alias {
color: #c5c5c5;
}
--main-background-color: #353535;
--main-color: #ddd;
--settings-input-color: #2196f3;
+ --settings-button-color: #000;
+ --settings-button-border-focus: #ffb900;
--sidebar-background-color: #505050;
--sidebar-background-color-hover: #676767;
--code-block-background-color: #2A2A2A;
--target-border-color: #bb7410;
--tooltip-background-color: #000;
--tooltip-color: #fff;
+ --kbd-color: #000;
+ --kbd-background: #fafbfc;
+ --kbd-box-shadow-color: #c6cbd1;
--rust-logo-filter: drop-shadow(1px 0 0px #fff)
drop-shadow(0 1px 0 #fff)
drop-shadow(-1px 0 0 #fff)
color: #888;
}
-kbd {
- color: #000;
- background-color: #fafbfc;
- box-shadow: inset 0 -1px 0 #c6cbd1;
-}
-
-#settings-menu > a, #help-button > a {
- color: #000;
-}
-
-#settings-menu > a:hover, #settings-menu > a:focus,
-#help-button > a:hover, #help-button > a:focus {
- border-color: #ffb900;
-}
-
.search-results .result-name span.alias {
color: #fff;
}
--main-background-color: white;
--main-color: black;
--settings-input-color: #2196f3;
+ --settings-button-color: #000;
+ --settings-button-border-focus: #717171;
--sidebar-background-color: #F5F5F5;
--sidebar-background-color-hover: #E0E0E0;
--code-block-background-color: #F5F5F5;
--target-border-color: #ad7c37;
--tooltip-background-color: #fdffd3;
--tooltip-color: #fff;
+ --kbd-color: #000;
+ --kbd-background: #fafbfc;
+ --kbd-box-shadow-color: #c6cbd1;
--rust-logo-filter: initial;
/* match border-color; uses https://codepen.io/sosuke/pen/Pjoqqp */
--crate-search-div-filter: invert(100%) sepia(0%) saturate(4223%) hue-rotate(289deg)
color: #888;
}
-kbd {
- color: #000;
- background-color: #fafbfc;
- box-shadow: inset 0 -1px 0 #c6cbd1;
-}
-
-#settings-menu > a, #help-button > a {
- color: #000;
-}
-
-#settings-menu > a:hover, #settings-menu > a:focus,
-#help-button > a:hover, #help-button > a:focus {
- border-color: #717171;
-}
-
.search-results .result-name span.alias {
color: #000;
}
// This means when the window is resized, we need to redo the layout.
const base = window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE;
const force_visible = base.NOTABLE_FORCE_VISIBLE;
- hideNotable();
+ hideNotable(false);
if (force_visible) {
showNotable(base);
base.NOTABLE_FORCE_VISIBLE = true;
// Make this function idempotent.
return;
}
- hideNotable();
+ hideNotable(false);
const ty = e.getAttribute("data-ty");
const wrapper = document.createElement("div");
wrapper.innerHTML = "<div class=\"docblock\">" + window.NOTABLE_TRAITS[ty] + "</div>";
return;
}
if (!e.NOTABLE_FORCE_VISIBLE && !elemIsInParent(event.relatedTarget, e)) {
- hideNotable();
+ hideNotable(true);
}
};
}
// To work around this, make sure the click finishes being dispatched before
// hiding the popover. Since `hideNotable()` is idempotent, this makes Safari behave
// consistently with the other two.
- setTimeout(hideNotable, 0);
+ setTimeout(() => hideNotable(false), 0);
}
}
- function hideNotable() {
+ function hideNotable(focus) {
if (window.CURRENT_NOTABLE_ELEMENT) {
if (window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE.NOTABLE_FORCE_VISIBLE) {
- window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE.focus();
+ if (focus) {
+ window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE.focus();
+ }
window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE.NOTABLE_FORCE_VISIBLE = false;
}
const body = document.getElementsByTagName("body")[0];
e.onclick = function() {
this.NOTABLE_FORCE_VISIBLE = this.NOTABLE_FORCE_VISIBLE ? false : true;
if (window.CURRENT_NOTABLE_ELEMENT && !this.NOTABLE_FORCE_VISIBLE) {
- hideNotable();
+ hideNotable(true);
} else {
showNotable(this);
window.CURRENT_NOTABLE_ELEMENT.setAttribute("tabindex", "0");
}
if (!this.NOTABLE_FORCE_VISIBLE &&
!elemIsInParent(event.relatedTarget, window.CURRENT_NOTABLE_ELEMENT)) {
- hideNotable();
+ hideNotable(true);
}
};
});
onEachLazy(document.querySelectorAll(".search-form .popover"), elem => {
elem.style.display = "none";
});
- hideNotable();
+ hideNotable(false);
};
/**
}
pub(crate) fn static_filename(filename: &str, contents: &[u8]) -> PathBuf {
- let filename = filename.rsplit("/").next().unwrap();
+ let filename = filename.rsplit('/').next().unwrap();
suffix_path(filename, &static_suffix(contents))
}
{%- endif -%}
<script defer src="{{static_root_path|safe}}{{files.main_js}}"></script> {#- -#}
{%- if layout.scrape_examples_extension -%}
- <script defer src="{{page.root_path|safe}}{{files.scrape_examples_js}}"></script> {#- -#}
+ <script defer src="{{static_root_path|safe}}{{files.scrape_examples_js}}"></script> {#- -#}
{%- endif -%}
<noscript> {#- -#}
<link rel="stylesheet" {# -#}
#![feature(box_patterns)]
#![feature(control_flow_enum)]
#![feature(drain_filter)]
+#![feature(is_terminal)]
#![feature(let_chains)]
#![feature(test)]
#![feature(never_type)]
use std::default::Default;
use std::env::{self, VarError};
-use std::io;
+use std::io::{self, IsTerminal};
use std::process;
use rustc_driver::abort_on_err;
let color_logs = match std::env::var("RUSTDOC_LOG_COLOR").as_deref() {
Ok("always") => true,
Ok("never") => false,
- Ok("auto") | Err(VarError::NotPresent) => atty::is(atty::Stream::Stdout),
+ Ok("auto") | Err(VarError::NotPresent) => io::stdout().is_terminal(),
Ok(value) => early_error(
ErrorOutputType::default(),
&format!("invalid log color value '{}': expected one of always, never, or auto", value),
--- /dev/null
+// assembly-output: emit-asm
+// min-llvm-version: 14.0
+// only-x86_64
+// revisions: opt-speed opt-size
+// [opt-speed] compile-flags: -Copt-level=1
+// [opt-size] compile-flags: -Copt-level=s
+#![crate_type="rlib"]
+
+#![feature(core_intrinsics)]
+#![feature(pointer_is_aligned)]
+
+// CHECK-LABEL: is_aligned_to_unchecked
+// CHECK: decq
+// CHECK-NEXT: testq
+// CHECK-NEXT: sete
+// CHECK: retq
+#[no_mangle]
+pub unsafe fn is_aligned_to_unchecked(ptr: *const u8, align: usize) -> bool {
+ unsafe {
+ std::intrinsics::assume(align.is_power_of_two())
+ }
+ ptr.is_aligned_to(align)
+}
+
+// CHECK-LABEL: is_aligned_1
+// CHECK: movb $1
+// CHECK: retq
+#[no_mangle]
+pub fn is_aligned_1(ptr: *const u8) -> bool {
+ ptr.is_aligned()
+}
+
+// CHECK-LABEL: is_aligned_2
+// CHECK: testb $1
+// CHECK-NEXT: sete
+// CHECK: retq
+#[no_mangle]
+pub fn is_aligned_2(ptr: *const u16) -> bool {
+ ptr.is_aligned()
+}
+
+// CHECK-LABEL: is_aligned_4
+// CHECK: testb $3
+// CHECK-NEXT: sete
+// CHECK: retq
+#[no_mangle]
+pub fn is_aligned_4(ptr: *const u32) -> bool {
+ ptr.is_aligned()
+}
+
+// CHECK-LABEL: is_aligned_8
+// CHECK: testb $7
+// CHECK-NEXT: sete
+// CHECK: retq
+#[no_mangle]
+pub fn is_aligned_8(ptr: *const u64) -> bool {
+ ptr.is_aligned()
+}
--- /dev/null
+// compile-flags: -O
+// only-x86_64
+// ignore-debug: the debug assertions get in the way
+
+#![crate_type = "lib"]
+#![feature(iter_repeat_n)]
+
+#[derive(Clone)]
+pub struct NotCopy(u16);
+
+impl Drop for NotCopy {
+ fn drop(&mut self) {}
+}
+
+// For a type where `Drop::drop` doesn't do anything observable and a clone is the
+// same as a move, make sure that the extra case for the last item disappears.
+
+#[no_mangle]
+// CHECK-LABEL: @iter_repeat_n_next
+pub fn iter_repeat_n_next(it: &mut std::iter::RepeatN<NotCopy>) -> Option<NotCopy> {
+ // CHECK-NEXT: start:
+ // CHECK-NOT: br
+ // CHECK: %[[COUNT:.+]] = load i64
+ // CHECK-NEXT: %[[COUNT_ZERO:.+]] = icmp eq i64 %[[COUNT]], 0
+ // CHECK-NEXT: br i1 %[[COUNT_ZERO]], label %[[EMPTY:.+]], label %[[NOT_EMPTY:.+]]
+
+ // CHECK: [[NOT_EMPTY]]:
+ // CHECK-NEXT: %[[DEC:.+]] = add i64 %[[COUNT]], -1
+ // CHECK-NEXT: store i64 %[[DEC]]
+ // CHECK-NOT: br
+ // CHECK: %[[VAL:.+]] = load i16
+ // CHECK-NEXT: br label %[[EMPTY]]
+
+ // CHECK: [[EMPTY]]:
+ // CHECK-NOT: br
+ // CHECK: phi i16 [ undef, %start ], [ %[[VAL]], %[[NOT_EMPTY]] ]
+ // CHECK-NOT: br
+ // CHECK: ret
+
+ it.next()
+}
+
+// And as a result, using the iterator can optimize without special cases for
+// the last iteration, like `memset`ing all the items in one call.
+
+#[no_mangle]
+// CHECK-LABEL: @vec_extend_via_iter_repeat_n
+pub fn vec_extend_via_iter_repeat_n() -> Vec<u8> {
+ // CHECK: %[[ADDR:.+]] = tail call dereferenceable_or_null(1234) ptr @__rust_alloc(i64 1234, i64 1)
+ // CHECK: tail call void @llvm.memset.p0.i64(ptr noundef nonnull align 1 dereferenceable(1234) %[[ADDR]], i8 42, i64 1234,
+
+ let n = 1234_usize;
+ let mut v = Vec::with_capacity(n);
+ v.extend(std::iter::repeat_n(42_u8, n));
+ v
+}
--- /dev/null
+// compile-flags: -O
+// min-llvm-version: 15.0 (LLVM 13 in CI does this differently from submodule LLVM)
+// ignore-debug (because unchecked is checked in debug)
+
+#![crate_type = "lib"]
+#![feature(unchecked_math)]
+
+// CHECK-LABEL: @unchecked_shl_unsigned_same
+#[no_mangle]
+pub unsafe fn unchecked_shl_unsigned_same(a: u32, b: u32) -> u32 {
+ // CHECK-NOT: and i32
+ // CHECK: shl i32 %a, %b
+ // CHECK-NOT: and i32
+ a.unchecked_shl(b)
+}
+
+// CHECK-LABEL: @unchecked_shl_unsigned_smaller
+#[no_mangle]
+pub unsafe fn unchecked_shl_unsigned_smaller(a: u16, b: u32) -> u16 {
+ // This uses -DAG to avoid failing on irrelevant reorderings,
+ // like emitting the truncation earlier.
+
+ // CHECK-DAG: %[[INRANGE:.+]] = icmp ult i32 %b, 65536
+ // CHECK-DAG: tail call void @llvm.assume(i1 %[[INRANGE]])
+ // CHECK-DAG: %[[TRUNC:.+]] = trunc i32 %b to i16
+ // CHECK-DAG: shl i16 %a, %[[TRUNC]]
+ a.unchecked_shl(b)
+}
+
+// CHECK-LABEL: @unchecked_shl_unsigned_bigger
+#[no_mangle]
+pub unsafe fn unchecked_shl_unsigned_bigger(a: u64, b: u32) -> u64 {
+ // CHECK: %[[EXT:.+]] = zext i32 %b to i64
+ // CHECK: shl i64 %a, %[[EXT]]
+ a.unchecked_shl(b)
+}
+
+// CHECK-LABEL: @unchecked_shr_signed_same
+#[no_mangle]
+pub unsafe fn unchecked_shr_signed_same(a: i32, b: u32) -> i32 {
+ // CHECK-NOT: and i32
+ // CHECK: ashr i32 %a, %b
+ // CHECK-NOT: and i32
+ a.unchecked_shr(b)
+}
+
+// CHECK-LABEL: @unchecked_shr_signed_smaller
+#[no_mangle]
+pub unsafe fn unchecked_shr_signed_smaller(a: i16, b: u32) -> i16 {
+ // This uses -DAG to avoid failing on irrelevant reorderings,
+ // like emitting the truncation earlier.
+
+ // CHECK-DAG: %[[INRANGE:.+]] = icmp ult i32 %b, 32768
+ // CHECK-DAG: tail call void @llvm.assume(i1 %[[INRANGE]])
+ // CHECK-DAG: %[[TRUNC:.+]] = trunc i32 %b to i16
+ // CHECK-DAG: ashr i16 %a, %[[TRUNC]]
+ a.unchecked_shr(b)
+}
+
+// CHECK-LABEL: @unchecked_shr_signed_bigger
+#[no_mangle]
+pub unsafe fn unchecked_shr_signed_bigger(a: i64, b: u32) -> i64 {
+ // CHECK: %[[EXT:.+]] = zext i32 %b to i64
+ // CHECK: ashr i64 %a, %[[EXT]]
+ a.unchecked_shr(b)
+}
// Const generic parameter
// cdb-command:x a!function_names::const_generic_fn*
// cdb-check:[...] a!function_names::const_generic_fn_bool<false> (void)
-// cdb-check:[...] a!function_names::const_generic_fn_non_int<CONST$6348c650c7b26618> (void)
// cdb-check:[...] a!function_names::const_generic_fn_unsigned_int<14> (void)
// cdb-check:[...] a!function_names::const_generic_fn_signed_int<-7> (void)
+// cdb-check:[...] a!function_names::const_generic_fn_non_int<CONST$6348c650c7b26618> (void)
#![allow(unused_variables)]
#![feature(omit_gdb_pretty_printer_section)]
--- /dev/null
+// MIR for `foo` after PreCodegen
+
+fn foo(_1: Option<String>) -> i32 {
+ debug s => _1; // in scope 0 at $DIR/string.rs:+0:12: +0:13
+ let mut _0: i32; // return place in scope 0 at $DIR/string.rs:+0:34: +0:37
+ let mut _2: &std::string::String; // in scope 0 at $DIR/string.rs:+2:14: +2:17
+ let mut _3: &str; // in scope 0 at $DIR/string.rs:+2:14: +2:17
+ let mut _4: bool; // in scope 0 at $DIR/string.rs:+2:14: +2:17
+ let mut _5: isize; // in scope 0 at $DIR/string.rs:+2:9: +2:18
+ let _6: std::option::Option<std::string::String>; // in scope 0 at $DIR/string.rs:+3:9: +3:10
+ let mut _7: bool; // in scope 0 at $DIR/string.rs:+5:1: +5:2
+ scope 1 {
+ debug s => _6; // in scope 1 at $DIR/string.rs:+3:9: +3:10
+ }
+
+ bb0: {
+ _7 = const false; // scope 0 at $DIR/string.rs:+1:11: +1:12
+ _7 = const true; // scope 0 at $DIR/string.rs:+1:11: +1:12
+ _5 = discriminant(_1); // scope 0 at $DIR/string.rs:+1:11: +1:12
+ switchInt(move _5) -> [1_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/string.rs:+1:5: +1:12
+ }
+
+ bb1: {
+ StorageLive(_6); // scope 0 at $DIR/string.rs:+3:9: +3:10
+ _7 = const false; // scope 0 at $DIR/string.rs:+3:9: +3:10
+ _6 = move _1; // scope 0 at $DIR/string.rs:+3:9: +3:10
+ _0 = const 4321_i32; // scope 1 at $DIR/string.rs:+3:14: +3:18
+ drop(_6) -> bb6; // scope 0 at $DIR/string.rs:+3:17: +3:18
+ }
+
+ bb2: {
+ _2 = &((_1 as Some).0: std::string::String); // scope 0 at $DIR/string.rs:+2:14: +2:17
+ _3 = <String as Deref>::deref(move _2) -> bb3; // scope 0 at $DIR/string.rs:+2:14: +2:17
+ // mir::Constant
+ // + span: $DIR/string.rs:9:14: 9:17
+ // + literal: Const { ty: for<'a> fn(&'a String) -> &'a <String as Deref>::Target {<String as Deref>::deref}, val: Value(<ZST>) }
+ }
+
+ bb3: {
+ _4 = <str as PartialEq>::eq(_3, const "a") -> bb4; // scope 0 at $DIR/string.rs:+2:14: +2:17
+ // mir::Constant
+ // + span: $DIR/string.rs:9:14: 9:17
+ // + literal: Const { ty: for<'a, 'b> fn(&'a str, &'b str) -> bool {<str as PartialEq>::eq}, val: Value(<ZST>) }
+ // mir::Constant
+ // + span: $DIR/string.rs:9:14: 9:17
+ // + literal: Const { ty: &str, val: Value(Slice(..)) }
+ }
+
+ bb4: {
+ switchInt(move _4) -> [false: bb1, otherwise: bb5]; // scope 0 at $DIR/string.rs:+2:14: +2:17
+ }
+
+ bb5: {
+ _0 = const 1234_i32; // scope 0 at $DIR/string.rs:+2:22: +2:26
+ goto -> bb9; // scope 0 at $DIR/string.rs:+2:22: +2:26
+ }
+
+ bb6: {
+ StorageDead(_6); // scope 0 at $DIR/string.rs:+3:17: +3:18
+ goto -> bb9; // scope 0 at $DIR/string.rs:+3:17: +3:18
+ }
+
+ bb7: {
+ return; // scope 0 at $DIR/string.rs:+5:2: +5:2
+ }
+
+ bb8: {
+ drop(_1) -> bb7; // scope 0 at $DIR/string.rs:+5:1: +5:2
+ }
+
+ bb9: {
+ switchInt(_7) -> [false: bb7, otherwise: bb8]; // scope 0 at $DIR/string.rs:+5:1: +5:2
+ }
+}
--- /dev/null
+// compile-flags: -Z mir-opt-level=0 -C panic=abort
+
+#![feature(string_deref_patterns)]
+#![crate_type = "lib"]
+
+// EMIT_MIR string.foo.PreCodegen.after.mir
+pub fn foo(s: Option<String>) -> i32 {
+ match s {
+ Some("a") => 1234,
+ s => 4321,
+ }
+}
--- /dev/null
+// Verifies that there is non-zero margin on variants and their docblocks.
+goto: "file://" + |DOC_PATH| + "/test_docs/enum.WhoLetTheDogOut.html"
+
+assert-css: (".variants > .variant", {"margin": "0px 0px 12px"})
+assert-css: (".variants > .docblock", {"margin": "0px 0px 32px 24px"})
compare-elements-property: (".sub", "#help", ["offsetWidth"])
compare-elements-position: (".sub", "#help", ("x"))
+// Checking the color of the elements of the help menu.
+show-text: true
+define-function: (
+ "check-colors",
+ (theme, color, background, box_shadow),
+ [
+ // Setting the theme.
+ ("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}),
+ // We reload the page so the local storage settings are being used.
+ ("reload"),
+ ("assert-css", ("#help kbd", {
+ "color": |color|,
+ "background-color": |background|,
+ "box-shadow": |box_shadow| + " 0px -1px 0px 0px inset",
+ "cursor": "default",
+ }, ALL)),
+ ],
+)
+
+call-function: ("check-colors", {
+ "theme": "ayu",
+ "color": "rgb(197, 197, 197)",
+ "background": "rgb(49, 69, 89)",
+ "box_shadow": "rgb(92, 103, 115)",
+})
+call-function: ("check-colors", {
+ "theme": "dark",
+ "color": "rgb(221, 221, 221)",
+ "background": "rgb(250, 251, 252)",
+ "box_shadow": "rgb(198, 203, 209)",
+})
+call-function: ("check-colors", {
+ "theme": "light",
+ "color": "rgb(0, 0, 0)",
+ "background": "rgb(250, 251, 252)",
+ "box_shadow": "rgb(198, 203, 209)",
+})
+
// This test ensures that opening the help popover without switching pages works.
goto: "file://" + |DOC_PATH| + "/test_docs/index.html"
size: (1000, 1000) // Only supported on desktop.
press-key: "Tab"
press-key: "Tab"
assert-count: ("//*[@class='notable popover']", 0)
+assert: "#method\.create_an_iterator_from_read .notable-traits:focus"
+
+// Now we check that the focus isn't given back to the wrong item when opening
+// another popover.
+store-window-property: (scroll, "scrollY")
+click: "#method\.create_an_iterator_from_read .fnname"
+// We ensure that the scroll position changed.
+assert-window-property-false: {"scrollY": |scroll|}
+// Store the new position.
+store-window-property: (scroll, "scrollY")
+click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']"
+wait-for: "//*[@class='notable popover']"
+click: "#settings-menu a"
+click: ".search-input"
+// We ensure we didn't come back to the previous focused item.
+assert-window-property-false: {"scrollY": |scroll|}
+
+// Same but with Escape handling.
+store-window-property: (scroll, "scrollY")
+click: "#method\.create_an_iterator_from_read .fnname"
+// We ensure that the scroll position changed.
+assert-window-property-false: {"scrollY": |scroll|}
+// Store the new position.
+store-window-property: (scroll, "scrollY")
+click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']"
+wait-for: "//*[@class='notable popover']"
+click: "#settings-menu a"
+press-key: "Escape"
+// We ensure we didn't come back to the previous focused item.
+assert-window-property-false: {"scrollY": |scroll|}
--- /dev/null
+goto: "file://" + |DOC_PATH| + "/scrape_examples/fn.test.html"
+store-property: (smallOffsetHeight, ".scraped-example-list > .scraped-example pre", "offsetHeight")
+assert-property-false: (".scraped-example-list > .scraped-example pre", {
+ "scrollHeight": |smallOffsetHeight|
+})
+focus: ".scraped-example-list > .scraped-example .expand"
+press-key: "Enter"
+assert-property-false: (".scraped-example-list > .scraped-example pre", {
+ "offsetHeight": |smallOffsetHeight|
+})
+store-property: (fullOffsetHeight, ".scraped-example-list > .scraped-example pre", "offsetHeight")
+assert-property: (".scraped-example-list > .scraped-example pre", {
+ "scrollHeight": |fullOffsetHeight|
+})
// Now we check the display of the sidebar items.
show-text: true
-// First we start with the light theme.
-local-storage: {"rustdoc-theme": "light", "rustdoc-use-system-theme": "false"}
-reload:
-// Waiting for the sidebar to be displayed...
-wait-for-css: ("#sidebar-toggle", {"visibility": "visible"})
-assert-css: (
- "#source-sidebar details[open] > .files a.selected",
- {"color": "rgb(0, 0, 0)", "background-color": "rgb(255, 255, 255)"},
-)
-// Without hover or focus.
-assert-css: ("#sidebar-toggle > button", {"background-color": "rgba(0, 0, 0, 0)"})
-// With focus.
-focus: "#sidebar-toggle > button"
-assert-css: ("#sidebar-toggle > button", {"background-color": "rgb(224, 224, 224)"})
-focus: ".search-input"
-// With hover.
-move-cursor-to: "#sidebar-toggle > button"
-assert-css: ("#sidebar-toggle > button", {"background-color": "rgb(224, 224, 224)"})
-// Without hover.
-assert-css: (
- "#source-sidebar details[open] > .files a:not(.selected)",
- {"color": "rgb(0, 0, 0)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-// With focus.
-focus: "#source-sidebar details[open] > .files a:not(.selected)"
-wait-for-css: (
- "#source-sidebar details[open] > .files a:not(.selected)",
- {"color": "rgb(0, 0, 0)", "background-color": "rgb(224, 224, 224)"},
-)
-focus: ".search-input"
-// With hover.
-move-cursor-to: "#source-sidebar details[open] > .files a:not(.selected)"
-assert-css: (
- "#source-sidebar details[open] > .files a:not(.selected)",
- {"color": "rgb(0, 0, 0)", "background-color": "rgb(224, 224, 224)"},
-)
-// Without hover.
-assert-css: (
- "#source-sidebar details[open] > .folders > details > summary",
- {"color": "rgb(0, 0, 0)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-// With focus.
-focus: "#source-sidebar details[open] > .folders > details > summary"
-wait-for-css: (
- "#source-sidebar details[open] > .folders > details > summary",
- {"color": "rgb(0, 0, 0)", "background-color": "rgb(224, 224, 224)"},
-)
-focus: ".search-input"
-// With hover.
-move-cursor-to: "#source-sidebar details[open] > .folders > details > summary"
-assert-css: (
- "#source-sidebar details[open] > .folders > details > summary",
- {"color": "rgb(0, 0, 0)", "background-color": "rgb(224, 224, 224)"},
+define-function: (
+ "check-colors",
+ (
+ theme, color, color_hover, background, background_hover, background_toggle,
+ background_toggle_hover,
+ ),
+ [
+ ("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}),
+ ("reload"),
+ ("wait-for-css", ("#sidebar-toggle", {"visibility": "visible"})),
+ ("assert-css", (
+ "#source-sidebar details[open] > .files a.selected",
+ {"color": |color_hover|, "background-color": |background|},
+ )),
+ // Without hover or focus.
+ ("assert-css", ("#sidebar-toggle > button", {"background-color": |background_toggle|})),
+ // With focus.
+ ("focus", "#sidebar-toggle > button"),
+ ("assert-css", ("#sidebar-toggle > button", {"background-color": |background_toggle_hover|})),
+ ("focus", ".search-input"),
+ // With hover.
+ ("move-cursor-to", "#sidebar-toggle > button"),
+ ("assert-css", ("#sidebar-toggle > button", {"background-color": |background_toggle_hover|})),
+ // Without hover.
+ ("assert-css", (
+ "#source-sidebar details[open] > .files a:not(.selected)",
+ {"color": |color|, "background-color": |background_toggle|},
+ )),
+ // With focus.
+ ("focus", "#source-sidebar details[open] > .files a:not(.selected)"),
+ ("wait-for-css", (
+ "#source-sidebar details[open] > .files a:not(.selected)",
+ {"color": |color_hover|, "background-color": |background_hover|},
+ )),
+ ("focus", ".search-input"),
+ // With hover.
+ ("move-cursor-to", "#source-sidebar details[open] > .files a:not(.selected)"),
+ ("assert-css", (
+ "#source-sidebar details[open] > .files a:not(.selected)",
+ {"color": |color_hover|, "background-color": |background_hover|},
+ )),
+ // Without hover.
+ ("assert-css", (
+ "#source-sidebar details[open] > .folders > details > summary",
+ {"color": |color|, "background-color": |background_toggle|},
+ )),
+ // With focus.
+ ("focus", "#source-sidebar details[open] > .folders > details > summary"),
+ ("wait-for-css", (
+ "#source-sidebar details[open] > .folders > details > summary",
+ {"color": |color_hover|, "background-color": |background_hover|},
+ )),
+ ("focus", ".search-input"),
+ // With hover.
+ ("move-cursor-to", "#source-sidebar details[open] > .folders > details > summary"),
+ ("assert-css", (
+ "#source-sidebar details[open] > .folders > details > summary",
+ {"color": |color_hover|, "background-color": |background_hover|},
+ )),
+ ],
)
-// Now with the dark theme.
-local-storage: {"rustdoc-theme": "dark", "rustdoc-use-system-theme": "false"}
-reload:
-// Waiting for the sidebar to be displayed...
-wait-for-css: ("#sidebar-toggle", {"visibility": "visible"})
-assert-css: (
- "#source-sidebar details[open] > .files > a.selected",
- {"color": "rgb(221, 221, 221)", "background-color": "rgb(51, 51, 51)"},
-)
-// Without hover or focus.
-assert-css: ("#sidebar-toggle > button", {"background-color": "rgba(0, 0, 0, 0)"})
-// With focus.
-focus: "#sidebar-toggle > button"
-assert-css: ("#sidebar-toggle > button", {"background-color": "rgb(103, 103, 103)"})
-focus: ".search-input"
-// With hover.
-move-cursor-to: "#sidebar-toggle > button"
-assert-css: ("#sidebar-toggle > button", {"background-color": "rgb(103, 103, 103)"})
-// Without hover.
-assert-css: (
- "#source-sidebar details[open] > .files > a:not(.selected)",
- {"color": "rgb(221, 221, 221)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-// With focus.
-focus: "#source-sidebar details[open] > .files a:not(.selected)"
-wait-for-css: (
- "#source-sidebar details[open] > .files a:not(.selected)",
- {"color": "rgb(221, 221, 221)", "background-color": "rgb(68, 68, 68)"},
-)
-focus: ".search-input"
-// With hover.
-move-cursor-to: "#source-sidebar details[open] > .files a:not(.selected)"
-assert-css: (
- "#source-sidebar details[open] > .files a:not(.selected)",
- {"color": "rgb(221, 221, 221)", "background-color": "rgb(68, 68, 68)"},
-)
-// Without hover.
-assert-css: (
- "#source-sidebar details[open] > .folders > details > summary",
- {"color": "rgb(221, 221, 221)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-// With focus.
-focus: "#source-sidebar details[open] > .folders > details > summary"
-wait-for-css: (
- "#source-sidebar details[open] > .folders > details > summary",
- {"color": "rgb(221, 221, 221)", "background-color": "rgb(68, 68, 68)"},
-)
-focus: ".search-input"
-// With hover.
-move-cursor-to: "#source-sidebar details[open] > .folders > details > summary"
-assert-css: (
- "#source-sidebar details[open] > .folders > details > summary",
- {"color": "rgb(221, 221, 221)", "background-color": "rgb(68, 68, 68)"},
-)
-
-// And finally with the ayu theme.
-local-storage: {"rustdoc-theme": "ayu", "rustdoc-use-system-theme": "false"}
-reload:
-// Waiting for the sidebar to be displayed...
-wait-for-css: ("#sidebar-toggle", {"visibility": "visible"})
-assert-css: (
- "#source-sidebar details[open] > .files a.selected",
- {"color": "rgb(255, 180, 76)", "background-color": "rgb(20, 25, 31)"},
-)
-// Without hover or focus.
-assert-css: ("#sidebar-toggle > button", {"background-color": "rgba(0, 0, 0, 0)"})
-// With focus.
-focus: "#sidebar-toggle > button"
-assert-css: ("#sidebar-toggle > button", {"background-color": "rgba(70, 70, 70, 0.33)"})
-focus: ".search-input"
-// With hover.
-move-cursor-to: "#sidebar-toggle > button"
-assert-css: ("#sidebar-toggle > button", {"background-color": "rgba(70, 70, 70, 0.33)"})
-// Without hover.
-assert-css: (
- "#source-sidebar details[open] > .files a:not(.selected)",
- {"color": "rgb(197, 197, 197)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-// With focus.
-focus: "#source-sidebar details[open] > .files a:not(.selected)"
-wait-for-css: (
- "#source-sidebar details[open] > .files a:not(.selected)",
- {"color": "rgb(255, 180, 76)", "background-color": "rgb(20, 25, 31)"},
-)
-focus: ".search-input"
-// With hover.
-move-cursor-to: "#source-sidebar details[open] > .files a:not(.selected)"
-assert-css: (
- "#source-sidebar details[open] > .files a:not(.selected)",
- {"color": "rgb(255, 180, 76)", "background-color": "rgb(20, 25, 31)"},
-)
-// Without hover.
-assert-css: (
- "#source-sidebar details[open] > .folders > details > summary",
- {"color": "rgb(197, 197, 197)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-// With focus.
-focus: "#source-sidebar details[open] > .folders > details > summary"
-wait-for-css: (
- "#source-sidebar details[open] > .folders > details > summary",
- {"color": "rgb(255, 180, 76)", "background-color": "rgb(20, 25, 31)"},
-)
-focus: ".search-input"
-// With hover.
-move-cursor-to: "#source-sidebar details[open] > .folders > details > summary"
-assert-css: (
- "#source-sidebar details[open] > .folders > details > summary",
- {"color": "rgb(255, 180, 76)", "background-color": "rgb(20, 25, 31)"},
-)
+call-function: ("check-colors", {
+ "theme": "light",
+ "color": "rgb(0, 0, 0)",
+ "color_hover": "rgb(0, 0, 0)",
+ "background": "rgb(255, 255, 255)",
+ "background_hover": "rgb(224, 224, 224)",
+ "background_toggle": "rgba(0, 0, 0, 0)",
+ "background_toggle_hover": "rgb(224, 224, 224)",
+})
+call-function: ("check-colors", {
+ "theme": "dark",
+ "color": "rgb(221, 221, 221)",
+ "color_hover": "rgb(221, 221, 221)",
+ "background": "rgb(51, 51, 51)",
+ "background_hover": "rgb(68, 68, 68)",
+ "background_toggle": "rgba(0, 0, 0, 0)",
+ "background_toggle_hover": "rgb(103, 103, 103)",
+})
+call-function: ("check-colors", {
+ "theme": "ayu",
+ "color": "rgb(197, 197, 197)",
+ "color_hover": "rgb(255, 180, 76)",
+ "background": "rgb(20, 25, 31)",
+ "background_hover": "rgb(20, 25, 31)",
+ "background_toggle": "rgba(0, 0, 0, 0)",
+ "background_toggle_hover": "rgba(70, 70, 70, 0.33)",
+})
// Now checking on mobile devices.
size: (500, 700)
// Only "another_folder" should be "open" in "lib2".
assert: "//*[@class='dir-entry' and not(@open)]/*[text()='another_mod']"
// All other trees should be collapsed.
-assert-count: ("//*[@id='source-sidebar']/details[not(text()='lib2') and not(@open)]", 6)
+assert-count: ("//*[@id='source-sidebar']/details[not(text()='lib2') and not(@open)]", 7)
// We now switch to mobile mode.
size: (600, 600)
--- /dev/null
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "scrape_examples"
+version = "0.1.0"
--- /dev/null
+[package]
+name = "scrape_examples"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
--- /dev/null
+fn main() {
+ for i in 0..9 {
+ println!("hello world!");
+ println!("hello world!");
+ println!("hello world!");
+ println!("hello world!");
+ println!("hello world!");
+ println!("hello world!");
+ println!("hello world!");
+ println!("hello world!");
+ println!("hello world!");
+ }
+ scrape_examples::test();
+ for i in 0..9 {
+ println!("hello world!");
+ println!("hello world!");
+ println!("hello world!");
+ println!("hello world!");
+ println!("hello world!");
+ println!("hello world!");
+ println!("hello world!");
+ println!("hello world!");
+ println!("hello world!");
+ }
+}
--- /dev/null
+/// # Examples
+///
+/// ```
+/// test();
+/// test();
+/// ```
+pub fn test() {}
// @has issue_88600/enum.FooEnum.html
pub enum FooEnum {
- // @has - '//*[@id="variant.HiddenTupleItem"]//code' 'HiddenTupleItem(_)'
+ // @has - '//*[@id="variant.HiddenTupleItem"]//h3' 'HiddenTupleItem(_)'
// @count - '//*[@id="variant.HiddenTupleItem.field.0"]' 0
HiddenTupleItem(#[doc(hidden)] H),
- // @has - '//*[@id="variant.MultipleHidden"]//code' 'MultipleHidden(_, _)'
+ // @has - '//*[@id="variant.MultipleHidden"]//h3' 'MultipleHidden(_, _)'
// @count - '//*[@id="variant.MultipleHidden.field.0"]' 0
// @count - '//*[@id="variant.MultipleHidden.field.1"]' 0
MultipleHidden(#[doc(hidden)] H, #[doc(hidden)] H),
- // @has - '//*[@id="variant.MixedHiddenFirst"]//code' 'MixedHiddenFirst(_, S)'
+ // @has - '//*[@id="variant.MixedHiddenFirst"]//h3' 'MixedHiddenFirst(_, S)'
// @count - '//*[@id="variant.MixedHiddenFirst.field.0"]' 0
// @has - '//*[@id="variant.MixedHiddenFirst.field.1"]' '1: S'
MixedHiddenFirst(#[doc(hidden)] H, /** dox */ S),
- // @has - '//*[@id="variant.MixedHiddenLast"]//code' 'MixedHiddenLast(S, _)'
+ // @has - '//*[@id="variant.MixedHiddenLast"]//h3' 'MixedHiddenLast(S, _)'
// @has - '//*[@id="variant.MixedHiddenLast.field.0"]' '0: S'
// @count - '//*[@id="variant.MixedHiddenLast.field.1"]' 0
MixedHiddenLast(/** dox */ S, #[doc(hidden)] H),
- // @has - '//*[@id="variant.HiddenStruct"]//code' 'HiddenStruct'
+ // @has - '//*[@id="variant.HiddenStruct"]//h3' 'HiddenStruct'
// @count - '//*[@id="variant.HiddenStruct.field.h"]' 0
// @has - '//*[@id="variant.HiddenStruct.field.s"]' 's: S'
HiddenStruct {
extern crate rustc_parse;
extern crate rustc_session;
extern crate rustc_span;
+extern crate thin_vec;
use rustc_ast::mut_visit::{self, visit_clobber, MutVisitor};
use rustc_ast::ptr::P;
use rustc_span::source_map::FilePathMapping;
use rustc_span::source_map::{FileName, Spanned, DUMMY_SP};
use rustc_span::symbol::Ident;
+use thin_vec::thin_vec;
fn parse_expr(ps: &ParseSess, src: &str) -> Option<P<Expr>> {
let src_as_string = src.to_string();
fn make_x() -> P<Expr> {
let seg = PathSegment::from_ident(Ident::from_str("x"));
- let path = Path { segments: vec![seg], span: DUMMY_SP, tokens: None };
+ let path = Path { segments: thin_vec![seg], span: DUMMY_SP, tokens: None };
expr(ExprKind::Path(None, path))
}
2 => {
let seg = PathSegment::from_ident(Ident::from_str("x"));
iter_exprs(depth - 1, &mut |e| {
- g(ExprKind::MethodCall(seg.clone(), e, vec![make_x()], DUMMY_SP))
- });
+ g(ExprKind::MethodCall(Box::new(MethodCall {
+ seg: seg.clone(), receiver: e, args: vec![make_x()], span: DUMMY_SP
+ }))
+ )});
iter_exprs(depth - 1, &mut |e| {
- g(ExprKind::MethodCall(seg.clone(), make_x(), vec![e], DUMMY_SP))
- });
+ g(ExprKind::MethodCall(Box::new(MethodCall {
+ seg: seg.clone(), receiver: make_x(), args: vec![e], span: DUMMY_SP
+ }))
+ )});
}
3..=8 => {
let op = Spanned {
11 => {
let decl = P(FnDecl { inputs: vec![], output: FnRetTy::Default(DUMMY_SP) });
iter_exprs(depth - 1, &mut |e| {
- g(ExprKind::Closure(
- ClosureBinder::NotPresent,
- CaptureBy::Value,
- Async::No,
- Movability::Movable,
- decl.clone(),
- e,
- DUMMY_SP,
- ))
+ g(ExprKind::Closure(Box::new(Closure {
+ binder: ClosureBinder::NotPresent,
+ capture_clause: CaptureBy::Value,
+ asyncness: Async::No,
+ movability: Movability::Movable,
+ fn_decl: decl.clone(),
+ body: e,
+ fn_decl_span: DUMMY_SP,
+ })))
});
}
12 => {
--- /dev/null
+// check-pass
+// regression test for https://github.com/rust-lang/rust/issues/53485#issuecomment-885393452
+
+#![feature(is_sorted)]
+
+struct A {
+ name: String,
+}
+
+fn main() {
+ let a = &[
+ A {
+ name: "1".to_string(),
+ },
+ A {
+ name: "2".to_string(),
+ },
+ ];
+ assert!(a.is_sorted_by_key(|a| a.name.as_str()));
+}
--- /dev/null
+// edition:2021
+
+#![feature(async_fn_in_trait)]
+//~^ WARN the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes
+
+trait Foo {
+ async fn foo(&self);
+}
+
+fn main() {
+ let x: &dyn Foo = todo!();
+ //~^ ERROR the trait `Foo` cannot be made into an object
+}
--- /dev/null
+warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/object-safety.rs:3:12
+ |
+LL | #![feature(async_fn_in_trait)]
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
+ = note: `#[warn(incomplete_features)]` on by default
+
+error[E0038]: the trait `Foo` cannot be made into an object
+ --> $DIR/object-safety.rs:11:12
+ |
+LL | let x: &dyn Foo = todo!();
+ | ^^^^^^^^ `Foo` cannot be made into an object
+ |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+ --> $DIR/object-safety.rs:7:14
+ |
+LL | trait Foo {
+ | --- this trait cannot be made into an object...
+LL | async fn foo(&self);
+ | ^^^ ...because method `foo` is `async`
+ = help: consider moving `foo` to another trait
+
+error: aborting due to previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0038`.
+++ /dev/null
-// run-pass
-
-#![allow(dead_code)]
-#![allow(unused_imports)]
-mod bar {
- pub fn foo() -> bool { true }
-}
-
-fn main() {
- let foo = || false;
- use bar::foo;
- assert_eq!(foo(), false);
-}
--- /dev/null
+// check-pass
+
+trait Tag<'a> {
+ type Type: ?Sized;
+}
+
+trait IntoRaw: for<'a> Tag<'a> {
+ fn into_raw(this: *const <Self as Tag<'_>>::Type) -> *mut <Self as Tag<'_>>::Type;
+}
+
+impl<T: for<'a> Tag<'a>> IntoRaw for T {
+ fn into_raw(this: *const <Self as Tag<'_>>::Type) -> *mut <Self as Tag<'_>>::Type {
+ this as *mut T::Type
+ }
+}
+
+fn main() {}
+++ /dev/null
-//~ ERROR overflow evaluating the requirement `T: Trait<_>`
-
-#![feature(specialization, with_negative_coherence)]
-#![allow(incomplete_features)]
-
-pub trait Trait<T> {}
-
-default impl<T, U> Trait<T> for U {}
-
-impl<T> Trait<<T as Iterator>::Item> for T {}
-
-fn main() {}
+++ /dev/null
-error[E0275]: overflow evaluating the requirement `T: Trait<_>`
- |
- = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_100191_2`)
-note: required for `T` to implement `Trait<_>`
- --> $DIR/issue-100191-2.rs:8:20
- |
-LL | default impl<T, U> Trait<T> for U {}
- | ^^^^^^^^ ^
- = note: 128 redundant requirements hidden
- = note: required for `T` to implement `Trait<_>`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0275`.
+++ /dev/null
-#![crate_type = "lib"]
-#![feature(specialization, with_negative_coherence)]
-#![allow(incomplete_features)]
-
-trait X {}
-trait Y: X {}
-trait Z {
- type Assoc: Y;
-}
-struct A<T>(T);
-
-impl<T> Y for T where T: X {}
-impl<T: X> Z for A<T> {
- type Assoc = T;
-}
-
-// this impl is invalid, but causes an ICE anyway
-impl<T> From<<A<T> as Z>::Assoc> for T {}
-//~^ ERROR type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
-
-fn main() {}
+++ /dev/null
-error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
- --> $DIR/issue-100191.rs:18:6
- |
-LL | impl<T> From<<A<T> as Z>::Assoc> for T {}
- | ^ type parameter `T` must be used as the type parameter for some local type
- |
- = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local
- = note: only traits defined in the current crate can be implemented for a type parameter
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0210`.
--- /dev/null
+// run-pass
+// check-run-results
+#![feature(string_deref_patterns)]
+
+fn main() {
+ test(Some(String::from("42")));
+ test(Some(String::new()));
+ test(None);
+}
+
+fn test(o: Option<String>) {
+ match o {
+ Some("42") => println!("the answer"),
+ Some(_) => println!("something else?"),
+ None => println!("nil"),
+ }
+}
--- /dev/null
+the answer
+something else?
+nil
--- /dev/null
+// check-pass
+#![feature(string_deref_patterns)]
+
+fn main() {
+ match <_ as Default>::default() {
+ "" => (),
+ _ => unreachable!(),
+ }
+}
--- /dev/null
+// gate-test-string_deref_patterns
+fn main() {
+ match String::new() {
+ "" | _ => {}
+ //~^ mismatched types
+ }
+}
--- /dev/null
+error[E0308]: mismatched types
+ --> $DIR/gate.rs:4:9
+ |
+LL | match String::new() {
+ | ------------- this expression has type `String`
+LL | "" | _ => {}
+ | ^^ expected struct `String`, found `&str`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
--- /dev/null
+// check-pass
+#![feature(string_deref_patterns)]
+
+fn foo(s: &String) -> i32 {
+ match *s {
+ "a" => 42,
+ _ => -1,
+ }
+}
+
+fn bar(s: Option<&&&&String>) -> i32 {
+ match s {
+ Some(&&&&"&&&&") => 1,
+ _ => -1,
+ }
+}
+
+fn main() {}
--- /dev/null
+warning: the feature `dyn_star` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/align.rs:4:12
+ |
+LL | #![feature(dyn_star)]
+ | ^^^^^^^^
+ |
+ = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
+ = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
--- /dev/null
+warning: the feature `dyn_star` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/align.rs:4:12
+ |
+LL | #![feature(dyn_star)]
+ | ^^^^^^^^
+ |
+ = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
+ = note: `#[warn(incomplete_features)]` on by default
+
+error[E0277]: `AlignedUsize` needs to be a pointer-sized type
+ --> $DIR/align.rs:15:13
+ |
+LL | let x = AlignedUsize(12) as dyn* Debug;
+ | ^^^^^^^^^^^^^^^^ `AlignedUsize` needs to be a pointer-sized type
+ |
+ = help: the trait `PointerSized` is not implemented for `AlignedUsize`
+
+error: aborting due to previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0277`.
--- /dev/null
+// revisions: normal over_aligned
+//[normal] check-pass
+
+#![feature(dyn_star)]
+//~^ WARN the feature `dyn_star` is incomplete and may not be safe to use and/or cause compiler crashes
+
+use std::fmt::Debug;
+
+#[cfg_attr(over_aligned, repr(C, align(1024)))]
+#[cfg_attr(not(over_aligned), repr(C))]
+#[derive(Debug)]
+struct AlignedUsize(usize);
+
+fn main() {
+ let x = AlignedUsize(12) as dyn* Debug;
+ //[over_aligned]~^ ERROR `AlignedUsize` needs to be a pointer-sized type
+}
--- /dev/null
+#![feature(dyn_star)]
+#![allow(incomplete_features)]
+
+use std::fmt::Debug;
+
+fn dyn_debug(_: (dyn* Debug + '_)) {
+
+}
+
+fn polymorphic<T: Debug + ?Sized>(t: &T) {
+ dyn_debug(t);
+ //~^ ERROR `&T` needs to be a pointer-sized type
+}
+
+fn main() {}
--- /dev/null
+error[E0277]: `&T` needs to be a pointer-sized type
+ --> $DIR/check-size-at-cast-polymorphic-bad.rs:11:15
+ |
+LL | dyn_debug(t);
+ | ^ `&T` needs to be a pointer-sized type
+ |
+ = help: the trait `PointerSized` is not implemented for `&T`
+help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
+ |
+LL | fn polymorphic<T: Debug + ?Sized>(t: &T) where &T: PointerSized {
+ | ++++++++++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
--- /dev/null
+// check-pass
+
+#![feature(dyn_star)]
+#![allow(incomplete_features)]
+
+use std::fmt::Debug;
+
+fn dyn_debug(_: (dyn* Debug + '_)) {
+
+}
+
+fn polymorphic<T: Debug>(t: &T) {
+ dyn_debug(t);
+}
+
+fn main() {}
--- /dev/null
+#![feature(dyn_star)]
+#![allow(incomplete_features)]
+
+use std::fmt::Debug;
+
+fn main() {
+ let i = [1, 2, 3, 4] as dyn* Debug;
+ //~^ ERROR `[i32; 4]` needs to be a pointer-sized type
+ dbg!(i);
+}
--- /dev/null
+error[E0277]: `[i32; 4]` needs to be a pointer-sized type
+ --> $DIR/check-size-at-cast.rs:7:13
+ |
+LL | let i = [1, 2, 3, 4] as dyn* Debug;
+ | ^^^^^^^^^^^^ `[i32; 4]` needs to be a pointer-sized type
+ |
+ = help: the trait `PointerSized` is not implemented for `[i32; 4]`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
--- /dev/null
+// check-pass
+
+#![feature(dyn_star)]
+#![allow(incomplete_features)]
+
+trait AddOne {
+ fn add1(&mut self) -> usize;
+}
+
+impl AddOne for usize {
+ fn add1(&mut self) -> usize {
+ *self += 1;
+ *self
+ }
+}
+
+fn add_one(i: &mut (dyn* AddOne + '_)) -> usize {
+ i.add1()
+}
+
+fn main() {
+ let mut x = 42usize as dyn* AddOne;
+
+ println!("{}", add_one(&mut x));
+ println!("{}", add_one(&mut x));
+}
--- /dev/null
+#![feature(dyn_star)]
+#![allow(incomplete_features)]
+
+use std::fmt::Debug;
+
+fn main() {
+ let i = 42 as &dyn* Debug;
+ //~^ ERROR non-primitive cast: `i32` as `&dyn* Debug`
+}
--- /dev/null
+error[E0605]: non-primitive cast: `i32` as `&dyn* Debug`
+ --> $DIR/unsize-into-ref-dyn-star.rs:7:13
+ |
+LL | let i = 42 as &dyn* Debug;
+ | ^^^^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0605`.
+// normalize-stderr-test: "long-type-\d+" -> "long-type-hash"
trait Foo {}
struct Bar<T>(T);
-error[E0275]: overflow evaluating the requirement `Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>: Foo`
- --> $DIR/E0275.rs:5:33
+error[E0275]: overflow evaluating the requirement `Bar<Bar<Bar<Bar<Bar<Bar<Bar<...>>>>>>>: Foo`
+ --> $DIR/E0275.rs:6:33
|
LL | impl<T> Foo for T where Bar<T>: Foo {}
| ^^^
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`E0275`)
-note: required for `Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` to implement `Foo`
- --> $DIR/E0275.rs:5:9
+note: required for `Bar<Bar<Bar<Bar<Bar<Bar<...>>>>>>` to implement `Foo`
+ --> $DIR/E0275.rs:6:9
|
LL | impl<T> Foo for T where Bar<T>: Foo {}
| ^^^ ^
+ = note: the full type name has been written to '$TEST_BUILD_DIR/error-codes/E0275/E0275.long-type-hash.txt'
= note: 127 redundant requirements hidden
= note: required for `Bar<T>` to implement `Foo`
| ^^^^^^^^^^^^ `Foo` cannot be made into an object
|
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
- --> $DIR/object-safety.rs:7:8
+ --> $DIR/object-safety.rs:7:22
|
LL | trait Foo {
| --- this trait cannot be made into an object...
LL | fn baz(&self) -> impl Debug;
- | ^^^ ...because method `baz` references an `impl Trait` type in its return type
+ | ^^^^^^^^^^ ...because method `baz` references an `impl Trait` type in its return type
= help: consider moving `baz` to another trait
error[E0038]: the trait `Foo` cannot be made into an object
| ^^^^^^^ `Foo` cannot be made into an object
|
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
- --> $DIR/object-safety.rs:7:8
+ --> $DIR/object-safety.rs:7:22
|
LL | trait Foo {
| --- this trait cannot be made into an object...
LL | fn baz(&self) -> impl Debug;
- | ^^^ ...because method `baz` references an `impl Trait` type in its return type
+ | ^^^^^^^^^^ ...because method `baz` references an `impl Trait` type in its return type
= help: consider moving `baz` to another trait
error[E0038]: the trait `Foo` cannot be made into an object
| ^^^^^^^^^^^^^^^^ `Foo` cannot be made into an object
|
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
- --> $DIR/object-safety.rs:7:8
+ --> $DIR/object-safety.rs:7:22
|
LL | trait Foo {
| --- this trait cannot be made into an object...
LL | fn baz(&self) -> impl Debug;
- | ^^^ ...because method `baz` references an `impl Trait` type in its return type
+ | ^^^^^^^^^^ ...because method `baz` references an `impl Trait` type in its return type
= help: consider moving `baz` to another trait
= note: required for `Box<u32>` to implement `CoerceUnsized<Box<dyn Foo>>`
= note: required by cast to type `Box<dyn Foo>`
--- /dev/null
+// known-bug: #103507
+// failure-status: 101
+// normalize-stderr-test "note: .*\n\n" -> ""
+// normalize-stderr-test "thread 'rustc' panicked.*\n" -> ""
+// rustc-env:RUST_BACKTRACE=0
+
+#![feature(type_alias_impl_trait)]
+#![feature(const_trait_impl)]
+#![feature(const_refs_to_cell)]
+#![feature(inline_const)]
+
+use std::marker::Destruct;
+
+trait T {
+ type Item;
+}
+
+type Alias<'a> = impl T<Item = &'a ()>;
+
+struct S;
+impl<'a> T for &'a S {
+ type Item = &'a ();
+}
+
+const fn filter_positive<'a>() -> &'a Alias<'a> {
+ &&S
+}
+
+const fn with_positive<F: ~const for<'a> Fn(&'a Alias<'a>) + ~const Destruct>(fun: F) {
+ fun(filter_positive());
+}
+
+const fn foo(_: &Alias<'_>) {}
+
+const BAR: () = {
+ with_positive(foo);
+};
+
+fn main() {}
--- /dev/null
+error: internal compiler error: compiler/rustc_middle/src/ty/normalize_erasing_regions.rs:198:90: Failed to normalize <for<'a, 'b> fn(&'a Alias<'b>) {foo} as std::ops::FnOnce<(&&S,)>>::Output, maybe try to call `try_normalize_erasing_regions` instead
+
+query stack during panic:
+#0 [eval_to_allocation_raw] const-evaluating + checking `BAR`
+#1 [eval_to_const_value_raw] simplifying constant for the type system `BAR`
+end of query stack
+error: aborting due to previous error
+
-error: reached the recursion limit while instantiating `function::<Option<Option<Option<...>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
+error: reached the recursion limit while instantiating `function::<Option<Option<Option<Option<Option<...>>>>>>`
--> $DIR/infinite-instantiation.rs:22:9
|
LL | function(counter - 1, t.to_option());
+// normalize-stderr-test: "long-type-\d+" -> "long-type-hash"
trait Foo {
fn answer(self);
}
error[E0392]: parameter `T` is never used
- --> $DIR/issue-20413.rs:5:15
+ --> $DIR/issue-20413.rs:6:15
|
LL | struct NoData<T>;
| ^ unused parameter
= help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
= help: if you intended `T` to be a const parameter, use `const T: usize` instead
-error[E0275]: overflow evaluating the requirement `NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>: Foo`
- --> $DIR/issue-20413.rs:8:36
+error[E0275]: overflow evaluating the requirement `NoData<NoData<NoData<NoData<NoData<NoData<NoData<...>>>>>>>: Foo`
+ --> $DIR/issue-20413.rs:9:36
|
LL | impl<T> Foo for T where NoData<T>: Foo {
| ^^^
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_20413`)
-note: required for `NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` to implement `Foo`
- --> $DIR/issue-20413.rs:8:9
+note: required for `NoData<NoData<NoData<NoData<NoData<NoData<...>>>>>>` to implement `Foo`
+ --> $DIR/issue-20413.rs:9:9
|
LL | impl<T> Foo for T where NoData<T>: Foo {
| ^^^ ^
+ = note: the full type name has been written to '$TEST_BUILD_DIR/issues/issue-20413/issue-20413.long-type-hash.txt'
= note: 127 redundant requirements hidden
= note: required for `NoData<T>` to implement `Foo`
-error[E0275]: overflow evaluating the requirement `EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>: Baz`
- --> $DIR/issue-20413.rs:27:42
+error[E0275]: overflow evaluating the requirement `EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<...>>>>>>>: Baz`
+ --> $DIR/issue-20413.rs:28:42
|
LL | impl<T> Bar for T where EvenLessData<T>: Baz {
| ^^^
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_20413`)
-note: required for `AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` to implement `Bar`
- --> $DIR/issue-20413.rs:27:9
+note: required for `AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<...>>>>>>` to implement `Bar`
+ --> $DIR/issue-20413.rs:28:9
|
LL | impl<T> Bar for T where EvenLessData<T>: Baz {
| ^^^ ^
-note: required for `EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` to implement `Baz`
- --> $DIR/issue-20413.rs:34:9
+ = note: the full type name has been written to '$TEST_BUILD_DIR/issues/issue-20413/issue-20413.long-type-hash.txt'
+note: required for `EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<...>>>>>>` to implement `Baz`
+ --> $DIR/issue-20413.rs:35:9
|
LL | impl<T> Baz for T where AlmostNoData<T>: Bar {
| ^^^ ^
+ = note: the full type name has been written to '$TEST_BUILD_DIR/issues/issue-20413/issue-20413.long-type-hash.txt'
= note: 126 redundant requirements hidden
= note: required for `EvenLessData<T>` to implement `Baz`
-error[E0275]: overflow evaluating the requirement `AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>: Bar`
- --> $DIR/issue-20413.rs:34:42
+error[E0275]: overflow evaluating the requirement `AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<...>>>>>>>: Bar`
+ --> $DIR/issue-20413.rs:35:42
|
LL | impl<T> Baz for T where AlmostNoData<T>: Bar {
| ^^^
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_20413`)
-note: required for `EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` to implement `Baz`
- --> $DIR/issue-20413.rs:34:9
+note: required for `EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<...>>>>>>` to implement `Baz`
+ --> $DIR/issue-20413.rs:35:9
|
LL | impl<T> Baz for T where AlmostNoData<T>: Bar {
| ^^^ ^
-note: required for `AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` to implement `Bar`
- --> $DIR/issue-20413.rs:27:9
+ = note: the full type name has been written to '$TEST_BUILD_DIR/issues/issue-20413/issue-20413.long-type-hash.txt'
+note: required for `AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<...>>>>>>` to implement `Bar`
+ --> $DIR/issue-20413.rs:28:9
|
LL | impl<T> Bar for T where EvenLessData<T>: Baz {
| ^^^ ^
+ = note: the full type name has been written to '$TEST_BUILD_DIR/issues/issue-20413/issue-20413.long-type-hash.txt'
= note: 126 redundant requirements hidden
= note: required for `AlmostNoData<T>` to implement `Bar`
|
LL | pub fn matches<F: Fn()>(&self, f: &F) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- = note: the full type name has been written to '$TEST_BUILD_DIR/issues/issue-22638/issue-22638.long-type.txt'
error: aborting due to previous error
-error: reached the recursion limit while instantiating `<(&(&(&(&(&(&(&(&(&(&(&(&(&(&(&(.....), ...), ...) as Foo>::recurse`
+error: reached the recursion limit while instantiating `<(&(&(..., ...), ...), ...) as Foo>::recurse`
--> $DIR/issue-37311.rs:17:9
|
LL | (self, self).recurse();
-// compile-flags:-Ztreat-err-as-bug=5
#[derive(Debug)]
enum MyError {
NotFound { key: Vec<u8> },
error[E0507]: cannot move out of `*key` which is behind a shared reference
- --> $DIR/issue-52262.rs:16:35
+ --> $DIR/issue-52262.rs:15:35
|
LL | String::from_utf8(*key).unwrap()
| ^^^^ move occurs because `*key` has type `Vec<u8>`, which does not implement the `Copy` trait
-error: reached the recursion limit while instantiating `rec::<&mut &mut &mut &mut &mut &... &mut &mut &mut &mut &mut Empty>`
+error: reached the recursion limit while instantiating `rec::<&mut &mut &mut &mut &mut ...>`
--> $DIR/issue-67552.rs:29:9
|
LL | rec(identity(&mut it))
= help: a `loop` may express intention better if this is on purpose
= note: `#[warn(unconditional_recursion)]` on by default
-error: reached the recursion limit while instantiating `generic::<Option<Option<Option<O...>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
+error: reached the recursion limit while instantiating `generic::<Option<Option<Option<Option<Option<...>>>>>>`
--> $DIR/issue-8727.rs:8:5
|
LL | generic::<Option<T>>();
--- /dev/null
+// check-pass
+// compile-flags: -Zvalidate-mir
+
+// This test checks that bivariant parameters are handled correctly
+// in the mir.
+#![allow(coherence_leak_check)]
+trait Trait {
+ type Assoc;
+}
+
+struct Foo<T, U>(T)
+where
+ T: Trait<Assoc = U>;
+
+impl Trait for for<'a> fn(&'a ()) {
+ type Assoc = u32;
+}
+impl Trait for fn(&'static ()) {
+ type Assoc = String;
+}
+
+fn foo(x: Foo<for<'a> fn(&'a ()), u32>) -> Foo<fn(&'static ()), String> {
+ x
+}
+
+fn main() {}
--- /dev/null
+// run-rustfix
+
+#![feature(let_chains)]
+#![allow(unused_variables)]
+#![allow(dead_code)]
+#![allow(irrefutable_let_patterns)]
+
+fn err_some(b: bool, x: Option<u32>) {
+ if b && let Some(x) = x {}
+ //~^ ERROR unexpected `if` in the condition expression
+}
+
+fn err_none(b: bool, x: Option<u32>) {
+ if b && let None = x {}
+ //~^ ERROR unexpected `if` in the condition expression
+}
+
+fn err_bool_1() {
+ if true && true { true } else { false };
+ //~^ ERROR unexpected `if` in the condition expression
+}
+
+fn err_bool_2() {
+ if true && false { true } else { false };
+ //~^ ERROR unexpected `if` in the condition expression
+}
+
+fn should_ok_1() {
+ if true && if let x = 1 { true } else { true } {}
+}
+
+fn should_ok_2() {
+ if true && if let 1 = 1 { true } else { true } {}
+}
+
+fn should_ok_3() {
+ if true && if true { true } else { false } {}
+}
+
+fn shoule_match_ok() {
+ #[cfg(feature = "full")]
+ {
+ let a = 1;
+ let b = 2;
+ if match a {
+ 1 if b == 1 => true,
+ _ => false,
+ } && if a > 1 { true } else { false }
+ {
+ true
+ }
+ }
+}
+
+fn should_ok_in_nested() {
+ if true && if true { true } else { false } { true } else { false };
+}
+
+fn main() {}
--- /dev/null
+// run-rustfix
+
+#![feature(let_chains)]
+#![allow(unused_variables)]
+#![allow(dead_code)]
+#![allow(irrefutable_let_patterns)]
+
+fn err_some(b: bool, x: Option<u32>) {
+ if b && if let Some(x) = x {}
+ //~^ ERROR unexpected `if` in the condition expression
+}
+
+fn err_none(b: bool, x: Option<u32>) {
+ if b && if let None = x {}
+ //~^ ERROR unexpected `if` in the condition expression
+}
+
+fn err_bool_1() {
+ if true && if true { true } else { false };
+ //~^ ERROR unexpected `if` in the condition expression
+}
+
+fn err_bool_2() {
+ if true && if false { true } else { false };
+ //~^ ERROR unexpected `if` in the condition expression
+}
+
+fn should_ok_1() {
+ if true && if let x = 1 { true } else { true } {}
+}
+
+fn should_ok_2() {
+ if true && if let 1 = 1 { true } else { true } {}
+}
+
+fn should_ok_3() {
+ if true && if true { true } else { false } {}
+}
+
+fn shoule_match_ok() {
+ #[cfg(feature = "full")]
+ {
+ let a = 1;
+ let b = 2;
+ if match a {
+ 1 if b == 1 => true,
+ _ => false,
+ } && if a > 1 { true } else { false }
+ {
+ true
+ }
+ }
+}
+
+fn should_ok_in_nested() {
+ if true && if true { true } else { false } { true } else { false };
+}
+
+fn main() {}
--- /dev/null
+error: unexpected `if` in the condition expression
+ --> $DIR/issue-103381.rs:9:12
+ |
+LL | if b && if let Some(x) = x {}
+ | ^^^^
+ |
+help: remove the `if`
+ |
+LL - if b && if let Some(x) = x {}
+LL + if b && let Some(x) = x {}
+ |
+
+error: unexpected `if` in the condition expression
+ --> $DIR/issue-103381.rs:14:12
+ |
+LL | if b && if let None = x {}
+ | ^^^^
+ |
+help: remove the `if`
+ |
+LL - if b && if let None = x {}
+LL + if b && let None = x {}
+ |
+
+error: unexpected `if` in the condition expression
+ --> $DIR/issue-103381.rs:19:15
+ |
+LL | if true && if true { true } else { false };
+ | ^^^^
+ |
+help: remove the `if`
+ |
+LL - if true && if true { true } else { false };
+LL + if true && true { true } else { false };
+ |
+
+error: unexpected `if` in the condition expression
+ --> $DIR/issue-103381.rs:24:15
+ |
+LL | if true && if false { true } else { false };
+ | ^^^^
+ |
+help: remove the `if`
+ |
+LL - if true && if false { true } else { false };
+LL + if true && false { true } else { false };
+ |
+
+error: aborting due to 4 previous errors
+
// build-fail
// compile-flags: -Copt-level=0
-//~^^ ERROR overflow evaluating the requirement
+// normalize-stderr-test: "long-type-\d+" -> "long-type-hash"
+//~^^^ ERROR overflow evaluating the requirement
fn main() {
let mut iter = 0u8..1;
warning: function cannot return without recursing
- --> $DIR/issue-83150.rs:10:1
+ --> $DIR/issue-83150.rs:11:1
|
LL | fn func<T: Iterator<Item = u8>>(iter: &mut T) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
error[E0275]: overflow evaluating the requirement `<std::ops::Range<u8> as Iterator>::Item`
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_83150`)
- = note: required for `Map<&mut std::ops::Range<u8>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>` to implement `Iterator`
+ = note: required for `Map<&mut std::ops::Range<u8>, [closure@$DIR/issue-83150.rs:12:24: 12:27]>` to implement `Iterator`
= note: 64 redundant requirements hidden
- = note: required for `&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut std::ops::Range<u8>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>` to implement `Iterator`
+ = note: required for `&mut Map<&mut Map<&mut Map<..., ...>, ...>, ...>` to implement `Iterator`
+ = note: the full type name has been written to '$TEST_BUILD_DIR/recursion/issue-83150/issue-83150.long-type-hash.txt'
error: aborting due to previous error; 1 warning emitted
-error: reached the recursion limit while instantiating `test::<Cons<Cons<Cons<Cons<Cons<...>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
+error: reached the recursion limit while instantiating `test::<Cons<Cons<Cons<Cons<Cons<...>>>>>>`
--> $DIR/recursion.rs:18:11
|
LL | _ => {test (n-1, i+1, Cons {head:2*i+1, tail:first}, Cons{head:i*i, tail:second})}
--- /dev/null
+// run-pass
+
+#![allow(dead_code)]
+#![allow(unused_imports)]
+mod bar {
+ pub fn foo() -> bool { true }
+}
+
+fn main() {
+ let foo = || false;
+ use bar::foo;
+ assert_eq!(foo(), false);
+}
--- /dev/null
+error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
+ --> $DIR/issue-43037.rs:19:6
+ |
+LL | impl<T> From<<A<T> as Z>::Assoc> for T {}
+ | ^ type parameter `T` must be used as the type parameter for some local type
+ |
+ = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local
+ = note: only traits defined in the current crate can be implemented for a type parameter
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0210`.
--- /dev/null
+error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
+ --> $DIR/issue-43037.rs:19:6
+ |
+LL | impl<T> From<<A<T> as Z>::Assoc> for T {}
+ | ^ type parameter `T` must be used as the type parameter for some local type
+ |
+ = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local
+ = note: only traits defined in the current crate can be implemented for a type parameter
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0210`.
+// revisions: current negative
#![feature(specialization)]
+#![cfg_attr(negative, feature(with_negative_coherence))]
#![allow(incomplete_features)]
trait X {}
+++ /dev/null
-error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
- --> $DIR/issue-43037.rs:17:6
- |
-LL | impl<T> From<<A<T> as Z>::Assoc> for T {}
- | ^ type parameter `T` must be used as the type parameter for some local type
- |
- = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local
- = note: only traits defined in the current crate can be implemented for a type parameter
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0210`.
--- /dev/null
+error[E0275]: overflow evaluating the requirement `T: Trait<_>`
+ |
+ = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_45814`)
+note: required for `T` to implement `Trait<_>`
+ --> $DIR/issue-45814.rs:9:20
+ |
+LL | default impl<T, U> Trait<T> for U {}
+ | ^^^^^^^^ ^
+ = note: 128 redundant requirements hidden
+ = note: required for `T` to implement `Trait<_>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0275`.
--- /dev/null
+error[E0275]: overflow evaluating the requirement `T: Trait<_>`
+ |
+ = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_45814`)
+note: required for `T` to implement `Trait<_>`
+ --> $DIR/issue-45814.rs:9:20
+ |
+LL | default impl<T, U> Trait<T> for U {}
+ | ^^^^^^^^ ^
+ = note: 128 redundant requirements hidden
+ = note: required for `T` to implement `Trait<_>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0275`.
//~ ERROR overflow evaluating the requirement `T: Trait<_>`
-
+// revisions: current negative
#![feature(specialization)]
+#![cfg_attr(negative, feature(with_negative_coherence))]
#![allow(incomplete_features)]
pub trait Trait<T> {}
+++ /dev/null
-error[E0275]: overflow evaluating the requirement `T: Trait<_>`
- |
- = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_45814`)
-note: required for `T` to implement `Trait<_>`
- --> $DIR/issue-45814.rs:8:20
- |
-LL | default impl<T, U> Trait<T> for U {}
- | ^^^^^^^^ ^
- = note: 128 redundant requirements hidden
- = note: required for `T` to implement `Trait<_>`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0275`.
ast-stats-1 Name Accumulated Size Count Item Size
ast-stats-1 ----------------------------------------------------------------
ast-stats-1 ExprField 48 ( 0.6%) 1 48
-ast-stats-1 Crate 56 ( 0.7%) 1 56
-ast-stats-1 Attribute 64 ( 0.8%) 2 32
+ast-stats-1 Crate 56 ( 0.8%) 1 56
+ast-stats-1 Attribute 64 ( 0.9%) 2 32
ast-stats-1 - Normal 32 ( 0.4%) 1
ast-stats-1 - DocComment 32 ( 0.4%) 1
-ast-stats-1 GenericArgs 64 ( 0.8%) 1 64
-ast-stats-1 - AngleBracketed 64 ( 0.8%) 1
-ast-stats-1 Local 72 ( 0.9%) 1 72
-ast-stats-1 WherePredicate 72 ( 0.9%) 1 72
-ast-stats-1 - BoundPredicate 72 ( 0.9%) 1
-ast-stats-1 Arm 96 ( 1.1%) 2 48
-ast-stats-1 ForeignItem 96 ( 1.1%) 1 96
-ast-stats-1 - Fn 96 ( 1.1%) 1
-ast-stats-1 FieldDef 160 ( 1.9%) 2 80
-ast-stats-1 Stmt 160 ( 1.9%) 5 32
+ast-stats-1 GenericArgs 64 ( 0.9%) 1 64
+ast-stats-1 - AngleBracketed 64 ( 0.9%) 1
+ast-stats-1 Local 72 ( 1.0%) 1 72
+ast-stats-1 WherePredicate 72 ( 1.0%) 1 72
+ast-stats-1 - BoundPredicate 72 ( 1.0%) 1
+ast-stats-1 Arm 96 ( 1.3%) 2 48
+ast-stats-1 ForeignItem 96 ( 1.3%) 1 96
+ast-stats-1 - Fn 96 ( 1.3%) 1
+ast-stats-1 FieldDef 160 ( 2.2%) 2 80
+ast-stats-1 Stmt 160 ( 2.2%) 5 32
ast-stats-1 - Local 32 ( 0.4%) 1
ast-stats-1 - MacCall 32 ( 0.4%) 1
-ast-stats-1 - Expr 96 ( 1.1%) 3
-ast-stats-1 Param 160 ( 1.9%) 4 40
-ast-stats-1 FnDecl 200 ( 2.4%) 5 40
-ast-stats-1 Variant 240 ( 2.9%) 2 120
-ast-stats-1 Block 288 ( 3.4%) 6 48
-ast-stats-1 GenericBound 352 ( 4.2%) 4 88
-ast-stats-1 - Trait 352 ( 4.2%) 4
-ast-stats-1 AssocItem 416 ( 4.9%) 4 104
-ast-stats-1 - Type 208 ( 2.5%) 2
-ast-stats-1 - Fn 208 ( 2.5%) 2
-ast-stats-1 GenericParam 480 ( 5.7%) 5 96
-ast-stats-1 PathSegment 720 ( 8.6%) 30 24
-ast-stats-1 Expr 832 ( 9.9%) 8 104
-ast-stats-1 - Path 104 ( 1.2%) 1
-ast-stats-1 - Match 104 ( 1.2%) 1
-ast-stats-1 - Struct 104 ( 1.2%) 1
-ast-stats-1 - Lit 208 ( 2.5%) 2
-ast-stats-1 - Block 312 ( 3.7%) 3
-ast-stats-1 Pat 840 (10.0%) 7 120
-ast-stats-1 - Struct 120 ( 1.4%) 1
-ast-stats-1 - Wild 120 ( 1.4%) 1
-ast-stats-1 - Ident 600 ( 7.1%) 5
-ast-stats-1 Ty 1_344 (16.0%) 14 96
-ast-stats-1 - Rptr 96 ( 1.1%) 1
-ast-stats-1 - Ptr 96 ( 1.1%) 1
-ast-stats-1 - ImplicitSelf 192 ( 2.3%) 2
-ast-stats-1 - Path 960 (11.4%) 10
-ast-stats-1 Item 1_656 (19.7%) 9 184
-ast-stats-1 - Trait 184 ( 2.2%) 1
-ast-stats-1 - Enum 184 ( 2.2%) 1
-ast-stats-1 - ForeignMod 184 ( 2.2%) 1
-ast-stats-1 - Impl 184 ( 2.2%) 1
-ast-stats-1 - Fn 368 ( 4.4%) 2
-ast-stats-1 - Use 552 ( 6.6%) 3
+ast-stats-1 - Expr 96 ( 1.3%) 3
+ast-stats-1 Param 160 ( 2.2%) 4 40
+ast-stats-1 FnDecl 200 ( 2.7%) 5 40
+ast-stats-1 Variant 240 ( 3.2%) 2 120
+ast-stats-1 GenericBound 288 ( 3.9%) 4 72
+ast-stats-1 - Trait 288 ( 3.9%) 4
+ast-stats-1 Block 288 ( 3.9%) 6 48
+ast-stats-1 AssocItem 416 ( 5.6%) 4 104
+ast-stats-1 - Type 208 ( 2.8%) 2
+ast-stats-1 - Fn 208 ( 2.8%) 2
+ast-stats-1 GenericParam 480 ( 6.5%) 5 96
+ast-stats-1 Expr 576 ( 7.8%) 8 72
+ast-stats-1 - Path 72 ( 1.0%) 1
+ast-stats-1 - Match 72 ( 1.0%) 1
+ast-stats-1 - Struct 72 ( 1.0%) 1
+ast-stats-1 - Lit 144 ( 1.9%) 2
+ast-stats-1 - Block 216 ( 2.9%) 3
+ast-stats-1 Pat 616 ( 8.3%) 7 88
+ast-stats-1 - Struct 88 ( 1.2%) 1
+ast-stats-1 - Wild 88 ( 1.2%) 1
+ast-stats-1 - Ident 440 ( 5.9%) 5
+ast-stats-1 PathSegment 720 ( 9.7%) 30 24
+ast-stats-1 Ty 896 (12.1%) 14 64
+ast-stats-1 - Rptr 64 ( 0.9%) 1
+ast-stats-1 - Ptr 64 ( 0.9%) 1
+ast-stats-1 - ImplicitSelf 128 ( 1.7%) 2
+ast-stats-1 - Path 640 ( 8.6%) 10
+ast-stats-1 Item 1_656 (22.3%) 9 184
+ast-stats-1 - Trait 184 ( 2.5%) 1
+ast-stats-1 - Enum 184 ( 2.5%) 1
+ast-stats-1 - ForeignMod 184 ( 2.5%) 1
+ast-stats-1 - Impl 184 ( 2.5%) 1
+ast-stats-1 - Fn 368 ( 5.0%) 2
+ast-stats-1 - Use 552 ( 7.4%) 3
ast-stats-1 ----------------------------------------------------------------
-ast-stats-1 Total 8_416
+ast-stats-1 Total 7_424
ast-stats-1
ast-stats-2 POST EXPANSION AST STATS
ast-stats-2 Name Accumulated Size Count Item Size
ast-stats-2 ----------------------------------------------------------------
-ast-stats-2 ExprField 48 ( 0.5%) 1 48
-ast-stats-2 Crate 56 ( 0.6%) 1 56
-ast-stats-2 GenericArgs 64 ( 0.7%) 1 64
-ast-stats-2 - AngleBracketed 64 ( 0.7%) 1
-ast-stats-2 Local 72 ( 0.8%) 1 72
-ast-stats-2 WherePredicate 72 ( 0.8%) 1 72
-ast-stats-2 - BoundPredicate 72 ( 0.8%) 1
-ast-stats-2 Arm 96 ( 1.0%) 2 48
-ast-stats-2 ForeignItem 96 ( 1.0%) 1 96
-ast-stats-2 - Fn 96 ( 1.0%) 1
-ast-stats-2 InlineAsm 120 ( 1.3%) 1 120
-ast-stats-2 Attribute 128 ( 1.4%) 4 32
-ast-stats-2 - DocComment 32 ( 0.3%) 1
-ast-stats-2 - Normal 96 ( 1.0%) 3
-ast-stats-2 FieldDef 160 ( 1.7%) 2 80
-ast-stats-2 Stmt 160 ( 1.7%) 5 32
-ast-stats-2 - Local 32 ( 0.3%) 1
-ast-stats-2 - Semi 32 ( 0.3%) 1
-ast-stats-2 - Expr 96 ( 1.0%) 3
-ast-stats-2 Param 160 ( 1.7%) 4 40
-ast-stats-2 FnDecl 200 ( 2.2%) 5 40
-ast-stats-2 Variant 240 ( 2.6%) 2 120
-ast-stats-2 Block 288 ( 3.1%) 6 48
-ast-stats-2 GenericBound 352 ( 3.8%) 4 88
-ast-stats-2 - Trait 352 ( 3.8%) 4
-ast-stats-2 AssocItem 416 ( 4.5%) 4 104
-ast-stats-2 - Type 208 ( 2.3%) 2
-ast-stats-2 - Fn 208 ( 2.3%) 2
-ast-stats-2 GenericParam 480 ( 5.2%) 5 96
-ast-stats-2 PathSegment 792 ( 8.7%) 33 24
-ast-stats-2 Pat 840 ( 9.2%) 7 120
-ast-stats-2 - Struct 120 ( 1.3%) 1
-ast-stats-2 - Wild 120 ( 1.3%) 1
-ast-stats-2 - Ident 600 ( 6.6%) 5
-ast-stats-2 Expr 936 (10.2%) 9 104
-ast-stats-2 - Path 104 ( 1.1%) 1
-ast-stats-2 - Match 104 ( 1.1%) 1
-ast-stats-2 - Struct 104 ( 1.1%) 1
-ast-stats-2 - InlineAsm 104 ( 1.1%) 1
-ast-stats-2 - Lit 208 ( 2.3%) 2
-ast-stats-2 - Block 312 ( 3.4%) 3
-ast-stats-2 Ty 1_344 (14.7%) 14 96
-ast-stats-2 - Rptr 96 ( 1.0%) 1
-ast-stats-2 - Ptr 96 ( 1.0%) 1
-ast-stats-2 - ImplicitSelf 192 ( 2.1%) 2
-ast-stats-2 - Path 960 (10.5%) 10
-ast-stats-2 Item 2_024 (22.1%) 11 184
-ast-stats-2 - Trait 184 ( 2.0%) 1
-ast-stats-2 - Enum 184 ( 2.0%) 1
-ast-stats-2 - ExternCrate 184 ( 2.0%) 1
-ast-stats-2 - ForeignMod 184 ( 2.0%) 1
-ast-stats-2 - Impl 184 ( 2.0%) 1
-ast-stats-2 - Fn 368 ( 4.0%) 2
-ast-stats-2 - Use 736 ( 8.0%) 4
+ast-stats-2 ExprField 48 ( 0.6%) 1 48
+ast-stats-2 Crate 56 ( 0.7%) 1 56
+ast-stats-2 GenericArgs 64 ( 0.8%) 1 64
+ast-stats-2 - AngleBracketed 64 ( 0.8%) 1
+ast-stats-2 Local 72 ( 0.9%) 1 72
+ast-stats-2 WherePredicate 72 ( 0.9%) 1 72
+ast-stats-2 - BoundPredicate 72 ( 0.9%) 1
+ast-stats-2 Arm 96 ( 1.2%) 2 48
+ast-stats-2 ForeignItem 96 ( 1.2%) 1 96
+ast-stats-2 - Fn 96 ( 1.2%) 1
+ast-stats-2 InlineAsm 120 ( 1.5%) 1 120
+ast-stats-2 Attribute 128 ( 1.6%) 4 32
+ast-stats-2 - DocComment 32 ( 0.4%) 1
+ast-stats-2 - Normal 96 ( 1.2%) 3
+ast-stats-2 FieldDef 160 ( 2.0%) 2 80
+ast-stats-2 Stmt 160 ( 2.0%) 5 32
+ast-stats-2 - Local 32 ( 0.4%) 1
+ast-stats-2 - Semi 32 ( 0.4%) 1
+ast-stats-2 - Expr 96 ( 1.2%) 3
+ast-stats-2 Param 160 ( 2.0%) 4 40
+ast-stats-2 FnDecl 200 ( 2.5%) 5 40
+ast-stats-2 Variant 240 ( 3.0%) 2 120
+ast-stats-2 GenericBound 288 ( 3.5%) 4 72
+ast-stats-2 - Trait 288 ( 3.5%) 4
+ast-stats-2 Block 288 ( 3.5%) 6 48
+ast-stats-2 AssocItem 416 ( 5.1%) 4 104
+ast-stats-2 - Type 208 ( 2.6%) 2
+ast-stats-2 - Fn 208 ( 2.6%) 2
+ast-stats-2 GenericParam 480 ( 5.9%) 5 96
+ast-stats-2 Pat 616 ( 7.6%) 7 88
+ast-stats-2 - Struct 88 ( 1.1%) 1
+ast-stats-2 - Wild 88 ( 1.1%) 1
+ast-stats-2 - Ident 440 ( 5.4%) 5
+ast-stats-2 Expr 648 ( 8.0%) 9 72
+ast-stats-2 - Path 72 ( 0.9%) 1
+ast-stats-2 - Match 72 ( 0.9%) 1
+ast-stats-2 - Struct 72 ( 0.9%) 1
+ast-stats-2 - InlineAsm 72 ( 0.9%) 1
+ast-stats-2 - Lit 144 ( 1.8%) 2
+ast-stats-2 - Block 216 ( 2.7%) 3
+ast-stats-2 PathSegment 792 ( 9.8%) 33 24
+ast-stats-2 Ty 896 (11.0%) 14 64
+ast-stats-2 - Rptr 64 ( 0.8%) 1
+ast-stats-2 - Ptr 64 ( 0.8%) 1
+ast-stats-2 - ImplicitSelf 128 ( 1.6%) 2
+ast-stats-2 - Path 640 ( 7.9%) 10
+ast-stats-2 Item 2_024 (24.9%) 11 184
+ast-stats-2 - Trait 184 ( 2.3%) 1
+ast-stats-2 - Enum 184 ( 2.3%) 1
+ast-stats-2 - ExternCrate 184 ( 2.3%) 1
+ast-stats-2 - ForeignMod 184 ( 2.3%) 1
+ast-stats-2 - Impl 184 ( 2.3%) 1
+ast-stats-2 - Fn 368 ( 4.5%) 2
+ast-stats-2 - Use 736 ( 9.1%) 4
ast-stats-2 ----------------------------------------------------------------
-ast-stats-2 Total 9_144
+ast-stats-2 Total 8_120
ast-stats-2
hir-stats HIR STATS
hir-stats Name Accumulated Size Count Item Size
--- /dev/null
+#[derive(Default)]
+struct Inner {
+ a: u8,
+ b: u8,
+}
+
+#[derive(Default)]
+struct Outer {
+ inner: Inner,
+ defaulted: u8,
+}
+
+fn main(){
+ Outer {
+ //~^ ERROR missing field `defaulted` in initializer of `Outer`
+ inner: Inner {
+ a: 1,
+ b: 2,
+ }
+ ..Default::default()
+ };
+}
--- /dev/null
+error[E0063]: missing field `defaulted` in initializer of `Outer`
+ --> $DIR/multi-line-fru-suggestion.rs:14:5
+ |
+LL | Outer {
+ | ^^^^^ missing `defaulted`
+ |
+note: this expression may have been misinterpreted as a `..` range expression
+ --> $DIR/multi-line-fru-suggestion.rs:16:16
+ |
+LL | inner: Inner {
+ | ________________^
+LL | | a: 1,
+LL | | b: 2,
+LL | | }
+ | |_________^ this expression does not end in a comma...
+LL | ..Default::default()
+ | ^^^^^^^^^^^^^^^^^^^^ ... so this is interpreted as a `..` range expression, instead of functional record update syntax
+help: to set the remaining fields from `Default::default()`, separate the last named field with a comma
+ |
+LL | },
+ | +
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0063`.
}
fn a() {
- let q = A { c: 5,..Default::default() };
- //~^ ERROR mismatched types
- //~| ERROR missing fields
+ let q = A { c: 5, ..Default::default() };
+ //~^ ERROR missing fields
//~| HELP separate the last named field with a comma
let r = A { c: 5, ..Default::default() };
assert_eq!(q, r);
}
fn b() {
- let q = B { b: 1,..Default::default() };
+ let q = B { b: 1, ..Default::default() };
//~^ ERROR mismatched types
//~| HELP separate the last named field with a comma
let r = B { b: 1 };
fn a() {
let q = A { c: 5..Default::default() };
- //~^ ERROR mismatched types
- //~| ERROR missing fields
+ //~^ ERROR missing fields
//~| HELP separate the last named field with a comma
let r = A { c: 5, ..Default::default() };
assert_eq!(q, r);
-error[E0308]: mismatched types
- --> $DIR/struct-record-suggestion.rs:10:20
- |
-LL | let q = A { c: 5..Default::default() };
- | ^^^^^^^^^^^^^^^^^^^^^ expected `u64`, found struct `std::ops::Range`
- |
- = note: expected type `u64`
- found struct `std::ops::Range<{integer}>`
-
error[E0063]: missing fields `b` and `d` in initializer of `A`
--> $DIR/struct-record-suggestion.rs:10:13
|
LL | let q = A { c: 5..Default::default() };
| ^ missing `b` and `d`
|
+note: this expression may have been misinterpreted as a `..` range expression
+ --> $DIR/struct-record-suggestion.rs:10:20
+ |
+LL | let q = A { c: 5..Default::default() };
+ | ^^^^^^^^^^^^^^^^^^^^^
help: to set the remaining fields from `Default::default()`, separate the last named field with a comma
|
-LL | let q = A { c: 5,..Default::default() };
+LL | let q = A { c: 5, ..Default::default() };
| +
error[E0308]: mismatched types
- --> $DIR/struct-record-suggestion.rs:24:20
+ --> $DIR/struct-record-suggestion.rs:23:20
|
LL | let q = B { b: 1..Default::default() };
| ^^^^^^^^^^^^^^^^^^^^^ expected `u32`, found struct `std::ops::Range`
|
= note: expected type `u32`
found struct `std::ops::Range<{integer}>`
+note: this expression may have been misinterpreted as a `..` range expression
+ --> $DIR/struct-record-suggestion.rs:23:20
+ |
+LL | let q = B { b: 1..Default::default() };
+ | ^^^^^^^^^^^^^^^^^^^^^
help: to set the remaining fields from `Default::default()`, separate the last named field with a comma
|
-LL | let q = B { b: 1,..Default::default() };
+LL | let q = B { b: 1, ..Default::default() };
| +
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
Some errors have detailed explanations: E0063, E0308.
For more information about an error, try `rustc --explain E0063`.
--> $DIR/issue-102354.rs:9:7
|
LL | x.func();
- | ^^^^ this is an associated function, not a method
+ | --^^^^--
+ | | |
+ | | this is an associated function, not a method
+ | help: use associated function syntax instead: `i32::func()`
|
= note: found the following associated functions; to be used as methods, functions must have a `self` parameter
note: the candidate is defined in the trait `Trait`
|
LL | fn func() {}
| ^^^^^^^^^
-help: use associated function syntax instead
- |
-LL | i32::func();
- | ~~~~~~~~~~~
-help: disambiguate the associated function for the candidate
- |
-LL | <i32 as Trait>::func(x);
- | ~~~~~~~~~~~~~~~~~~~~~~~
error: aborting due to previous error
--- /dev/null
+// The purpose of this test is not to validate the output of the compiler.
+// Instead, it ensures the suggestion is generated without performing an arithmetic overflow.
+
+fn main() {
+ let x = not_found; //~ ERROR cannot find value `not_found` in this scope
+ simd_gt::<()>(x);
+ //~^ ERROR this associated function takes 0 generic arguments but 1 generic argument was supplied
+ //~| ERROR cannot find function `simd_gt` in this scope
+}
--- /dev/null
+error[E0425]: cannot find value `not_found` in this scope
+ --> $DIR/issue-104287.rs:5:13
+ |
+LL | let x = not_found;
+ | ^^^^^^^^^ not found in this scope
+
+error[E0107]: this associated function takes 0 generic arguments but 1 generic argument was supplied
+ --> $DIR/issue-104287.rs:6:5
+ |
+LL | simd_gt::<()>(x);
+ | ^^^^^^^------ help: remove these generics
+ | |
+ | expected 0 generic arguments
+ |
+note: associated function defined here, with 0 generic parameters
+ --> $SRC_DIR/core/src/../../portable-simd/crates/core_simd/src/ord.rs:LL:COL
+ |
+LL | fn simd_gt(self, other: Self) -> Self::Mask;
+ | ^^^^^^^
+
+error[E0425]: cannot find function `simd_gt` in this scope
+ --> $DIR/issue-104287.rs:6:5
+ |
+LL | simd_gt::<()>(x);
+ | ^^^^^^^ not found in this scope
+ |
+help: use the `.` operator to call the method `SimdPartialOrd::simd_gt` on `[type error]`
+ |
+LL - simd_gt::<()>(x);
+LL + x.simd_gt();
+ |
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0107, E0425.
+For more information about an error, try `rustc --explain E0107`.
// compile-flags: -Zinline-mir=no
// error-pattern: overflow evaluating the requirement `(): Sized`
// error-pattern: function cannot return without recursing
+// normalize-stderr-test: "long-type-\d+" -> "long-type-hash"
// Regression test for #91949.
// This hanged *forever* on 1.56, fixed by #90423.
warning: function cannot return without recursing
- --> $DIR/issue-91949-hangs-on-recursion.rs:22:1
+ --> $DIR/issue-91949-hangs-on-recursion.rs:23:1
|
LL | / fn recurse<T>(elements: T) -> Vec<char>
LL | | where
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "512"]` attribute to your crate (`issue_91949_hangs_on_recursion`)
= note: required for `std::iter::Empty<()>` to implement `Iterator`
= note: 171 redundant requirements hidden
- = note: required for `IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), std::iter::Empty<()>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>` to implement `Iterator`
+ = note: required for `IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<..., ...>>, ...>>` to implement `Iterator`
+ = note: the full type name has been written to '$TEST_BUILD_DIR/traits/issue-91949-hangs-on-recursion/issue-91949-hangs-on-recursion.long-type-hash.txt'
error: aborting due to previous error; 1 warning emitted
let x: &u32 = item;
assert_eq!(x, &1);
}
+ let iter_fun2 = <(&[u32])>::iter;
+ //~^ no function or associated item named `iter` found for reference `&[u32]` in the current scope [E0599]
+ //~| function or associated item not found in `&[u32]`
+ //~| HELP the function `iter` is implemented on `[u32]`
+ for item2 in iter_fun2(&[1,1]) {
+ let x: &u32 = item2;
+ assert_eq!(x, &1);
+ }
}
LL | let iter_fun = <[u32]>::iter;
| ~~~~~
-error: aborting due to previous error
+error[E0599]: no function or associated item named `iter` found for reference `&[u32]` in the current scope
+ --> $DIR/issue-103271.rs:10:33
+ |
+LL | let iter_fun2 = <(&[u32])>::iter;
+ | ^^^^ function or associated item not found in `&[u32]`
+ |
+help: the function `iter` is implemented on `[u32]`
+ |
+LL | let iter_fun2 = <([u32])>::iter;
+ | ~~~~~
+
+error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0599`.
// The exact type depends on optimizations, so disable them.
#![allow(dead_code)]
-#![type_length_limit="4"]
+#![type_length_limit="8"]
macro_rules! link {
($id:ident, $t:ty) => {
}
}
+link! { A1, B1 }
+link! { B1, C1 }
+link! { C1, D1 }
+link! { D1, E1 }
+link! { E1, A }
link! { A, B }
link! { B, C }
link! { C, D }
link! { D, E }
link! { E, F }
-link! { F, G }
+link! { F, G<Option<i32>, Option<i32>> }
-pub struct G;
+pub struct G<T, K>(std::marker::PhantomData::<(T, K)>);
fn main() {
drop::<Option<A>>(None);
-error: reached the type-length limit while instantiating `std::mem::drop::<Option<((((...,....., ...), ..., ...), ..., ...)>>`
+error: reached the type-length limit while instantiating `std::mem::drop::<Option<((((..., ..., ...), ..., ...), ..., ...), ..., ...)>>`
--> $SRC_DIR/core/src/mem/mod.rs:LL:COL
|
LL | pub fn drop<T>(_x: T) {}
| ^^^^^^^^^^^^^^^^^^^^^
|
- = help: consider adding a `#![type_length_limit="8"]` attribute to your crate
+ = help: consider adding a `#![type_length_limit="10"]` attribute to your crate
= note: the full type name has been written to '$TEST_BUILD_DIR/type_length_limit/type_length_limit.long-type.txt'
-error: reached the type-length limit while instantiating `<[closure@std::rt::lang_start<()...e<()>>::call_once - shim(vtable)`
- --> $SRC_DIR/core/src/ops/function.rs:LL:COL
- |
-LL | extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- |
- = help: consider adding a `#![type_length_limit="8"]` attribute to your crate
- = note: the full type name has been written to '$TEST_BUILD_DIR/type_length_limit/type_length_limit.long-type.txt'
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
-Subproject commit 16b097879b6f117c8ae698aab054c87f26ff325e
+Subproject commit eb5d35917b2395194593c9ca70c3778f60c1573b
}
}
},
- ExprKind::MethodCall(_, _, ref params, _) => {
- if let [ref param] = params[..] {
- if let ExprKind::Paren(_) = param.kind {
- span_lint(cx, DOUBLE_PARENS, param.span, msg);
+ ExprKind::MethodCall(ref call) => {
+ if let [ref arg] = call.args[..] {
+ if let ExprKind::Paren(_) = arg.kind {
+ span_lint(cx, DOUBLE_PARENS, arg.span, msg);
}
}
},
if format_args.format_string.parts == [kw::Empty];
if arg.format.is_default();
if match cx.typeck_results().expr_ty(value).peel_refs().kind() {
- ty::Adt(adt, _) => cx.tcx.is_diagnostic_item(sym::String, adt.did()),
+ ty::Adt(adt, _) => Some(adt.did()) == cx.tcx.lang_items().string(),
ty::Str => true,
_ => false,
};
use clippy_utils::diagnostics::span_lint_and_help;
-use clippy_utils::ty::is_type_diagnostic_item;
+use clippy_utils::ty::is_type_lang_item;
use clippy_utils::{match_def_path, paths, peel_hir_expr_refs};
-use rustc_hir::{BinOpKind, Expr, ExprKind};
+use rustc_hir::{BinOpKind, Expr, ExprKind, LangItem};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::sym;
declare_lint_pass!(FormatPushString => [FORMAT_PUSH_STRING]);
fn is_string(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
- is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(e).peel_refs(), sym::String)
+ is_type_lang_item(cx, cx.typeck_results().expr_ty(e).peel_refs(), LangItem::String)
}
fn is_format(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
if let Some(macro_def_id) = e.span.ctxt().outer_expn_data().macro_def_id {
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::is_integer_literal;
use clippy_utils::sugg::Sugg;
-use clippy_utils::ty::is_type_diagnostic_item;
+use clippy_utils::ty::{is_type_diagnostic_item, is_type_lang_item};
use if_chain::if_chain;
use rustc_errors::Applicability;
-use rustc_hir::{def, Expr, ExprKind, PrimTy, QPath, TyKind};
+use rustc_hir::{def, Expr, ExprKind, LangItem, PrimTy, QPath, TyKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::Ty;
use rustc_session::{declare_lint_pass, declare_tool_lint};
/// Checks if a Ty is `String` or `&str`
fn is_ty_stringish(cx: &LateContext<'_>, ty: Ty<'_>) -> bool {
- is_type_diagnostic_item(cx, ty, sym::String) || is_type_diagnostic_item(cx, ty, sym::str)
+ is_type_lang_item(cx, ty, LangItem::String) || is_type_diagnostic_item(cx, ty, sym::str)
}
use clippy_utils::diagnostics::span_lint_and_help;
-use clippy_utils::ty::{implements_trait, is_type_diagnostic_item};
+use clippy_utils::ty::{implements_trait, is_type_lang_item};
use clippy_utils::{return_ty, trait_ref_of_method};
use if_chain::if_chain;
-use rustc_hir::{GenericParamKind, ImplItem, ImplItemKind};
+use rustc_hir::{GenericParamKind, ImplItem, ImplItemKind, LangItem};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::sym;
if impl_item.generics.params.iter().all(|p| matches!(p.kind, GenericParamKind::Lifetime { .. }));
// Check if return type is String
- if is_type_diagnostic_item(cx, return_ty(cx, impl_item.hir_id()), sym::String);
+ if is_type_lang_item(cx, return_ty(cx, impl_item.hir_id()), LangItem::String);
// Filters instances of to_string which are required by a trait
if trait_ref_of_method(cx, impl_item.owner_id.def_id).is_none();
use rustc_hir::intravisit::FnKind;
use rustc_hir::{
AsyncGeneratorKind, Block, Body, Closure, Expr, ExprKind, FnDecl, FnRetTy, GeneratorKind, GenericArg, GenericBound,
- HirId, IsAsync, ItemKind, LifetimeName, Term, TraitRef, Ty, TyKind, TypeBindingKind,
+ HirId, ItemKind, LifetimeName, Term, TraitRef, Ty, TyKind, TypeBindingKind,
};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};
) {
if_chain! {
if let Some(header) = kind.header();
- if header.asyncness == IsAsync::NotAsync;
+ if !header.asyncness.is_async();
// Check that this function returns `impl Future`
if let FnRetTy::Return(ret_ty) = decl.output;
if let Some((trait_ref, output_lifetimes)) = future_trait_ref(cx, ret_ty);
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::snippet;
-use clippy_utils::ty::is_type_diagnostic_item;
+use clippy_utils::ty::{is_type_diagnostic_item, is_type_lang_item};
use clippy_utils::{get_parent_expr, match_def_path, paths, SpanlessEq};
use clippy_utils::{meets_msrv, msrvs};
use rustc_errors::Applicability;
&& let Some(chars_expr_def_id) = cx.typeck_results().type_dependent_def_id(chars_expr.hir_id)
&& match_def_path(cx, chars_expr_def_id, &paths::STR_CHARS)
&& let ty = cx.typeck_results().expr_ty(str_expr).peel_refs()
- && is_type_diagnostic_item(cx, ty, sym::String)
+ && is_type_lang_item(cx, ty, hir::LangItem::String)
&& SpanlessEq::new(cx).eq_expr(left_expr, str_expr) {
suggest(cx, parent_expr, left_expr, filter_expr);
}
let ty = cx.typeck_results().expr_ty(expr);
match ty.kind() {
ty::Adt(adt_def, _) if adt_def.is_struct() => {
- if !cx.tcx.is_diagnostic_item(sym::String, adt_def.did()) {
+ if cx.tcx.lang_items().string() != Some(adt_def.did()) {
return;
}
},
use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::ty::is_type_diagnostic_item;
+use clippy_utils::ty::is_type_lang_item;
use rustc_ast::ast::LitKind;
use rustc_errors::Applicability;
use rustc_hir::intravisit::{walk_expr, Visitor};
-use rustc_hir::{Arm, Expr, ExprKind, PatKind};
+use rustc_hir::{Arm, Expr, ExprKind, LangItem, PatKind};
use rustc_lint::LateContext;
use rustc_middle::ty;
use rustc_span::symbol::Symbol;
-use rustc_span::{sym, Span};
+use rustc_span::Span;
use super::MATCH_STR_CASE_MISMATCH;
if let Some(case_method) = get_case_method(segment_ident) {
let ty = self.cx.typeck_results().expr_ty(receiver).peel_refs();
- if is_type_diagnostic_item(self.cx, ty, sym::String) || ty.kind() == &ty::Str {
+ if is_type_lang_item(self.cx, ty, LangItem::String) || ty.kind() == &ty::Str {
self.case_method = Some(case_method);
return true;
}
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::snippet_with_applicability;
-use clippy_utils::ty::is_type_diagnostic_item;
+use clippy_utils::ty::is_type_lang_item;
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_lint::LateContext;
-use rustc_span::sym;
use super::BYTES_COUNT_TO_LEN;
if let Some(impl_id) = cx.tcx.impl_of_method(bytes_id);
if cx.tcx.type_of(impl_id).is_str();
let ty = cx.typeck_results().expr_ty(bytes_recv).peel_refs();
- if ty.is_str() || is_type_diagnostic_item(cx, ty, sym::String);
+ if ty.is_str() || is_type_lang_item(cx, ty, hir::LangItem::String);
then {
let mut applicability = Applicability::MachineApplicable;
span_lint_and_sugg(
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::snippet_with_applicability;
-use clippy_utils::ty::is_type_diagnostic_item;
+use clippy_utils::ty::is_type_lang_item;
use rustc_errors::Applicability;
-use rustc_hir::Expr;
+use rustc_hir::{Expr, LangItem};
use rustc_lint::LateContext;
-use rustc_span::sym;
use super::BYTES_NTH;
let ty = cx.typeck_results().expr_ty(recv).peel_refs();
let caller_type = if ty.is_str() {
"str"
- } else if is_type_diagnostic_item(cx, ty, sym::String) {
+ } else if is_type_lang_item(cx, ty, LangItem::String) {
"String"
} else {
return;
use clippy_utils::diagnostics::span_lint_and_help;
-use clippy_utils::ty::is_type_diagnostic_item;
+use clippy_utils::ty::is_type_lang_item;
use if_chain::if_chain;
use rustc_ast::ast::LitKind;
-use rustc_hir::{Expr, ExprKind};
+use rustc_hir::{Expr, ExprKind, LangItem};
use rustc_lint::LateContext;
-use rustc_span::{source_map::Spanned, symbol::sym, Span};
+use rustc_span::{source_map::Spanned, Span};
use super::CASE_SENSITIVE_FILE_EXTENSION_COMPARISONS;
if ext_str.chars().skip(1).all(|c| c.is_uppercase() || c.is_ascii_digit())
|| ext_str.chars().skip(1).all(|c| c.is_lowercase() || c.is_ascii_digit());
let recv_ty = cx.typeck_results().expr_ty(recv).peel_refs();
- if recv_ty.is_str() || is_type_diagnostic_item(cx, recv_ty, sym::String);
+ if recv_ty.is_str() || is_type_lang_item(cx, recv_ty, LangItem::String);
then {
span_lint_and_help(
cx,
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::macros::{root_macro_call_first_node, FormatArgsExpn};
use clippy_utils::source::snippet_with_applicability;
-use clippy_utils::ty::is_type_diagnostic_item;
+use clippy_utils::ty::{is_type_diagnostic_item, is_type_lang_item};
use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_lint::LateContext;
if (method_name.ident.name == sym::as_str || method_name.ident.name == sym::as_ref) && {
let arg_type = cx.typeck_results().expr_ty(receiver);
let base_type = arg_type.peel_refs();
- *base_type.kind() == ty::Str || is_type_diagnostic_item(cx, base_type, sym::String)
+ *base_type.kind() == ty::Str || is_type_lang_item(cx, base_type, hir::LangItem::String)
} {
receiver
} else {
// converted to string.
fn requires_to_string(cx: &LateContext<'_>, arg: &hir::Expr<'_>) -> bool {
let arg_ty = cx.typeck_results().expr_ty(arg);
- if is_type_diagnostic_item(cx, arg_ty, sym::String) {
+ if is_type_lang_item(cx, arg_ty, hir::LangItem::String) {
return false;
}
if let ty::Ref(_, ty, ..) = arg_ty.kind() {
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::source::snippet_with_applicability;
-use clippy_utils::ty::{is_type_diagnostic_item, walk_ptrs_ty_depth};
+use clippy_utils::ty::{is_type_lang_item, walk_ptrs_ty_depth};
use clippy_utils::{match_def_path, paths};
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_lint::LateContext;
use rustc_middle::ty::{self, Ty};
-use rustc_span::symbol::{sym, Symbol};
+use rustc_span::symbol::{Symbol, sym};
use super::INEFFICIENT_TO_STRING;
return true;
}
- if is_type_diagnostic_item(cx, ty, sym::String) {
+ if is_type_lang_item(cx, ty, hir::LangItem::String) {
return true;
}
}
} else {
let ty = cx.typeck_results().expr_ty(e);
- if is_type_diagnostic_item(cx, ty, sym::String)
+ if is_type_lang_item(cx, ty, LangItem::String)
|| (is_type_lang_item(cx, ty, LangItem::OwnedBox) && get_ty_param(ty).map_or(false, Ty::is_str))
|| (is_type_diagnostic_item(cx, ty, sym::Cow) && get_ty_param(ty).map_or(false, Ty::is_str))
{
Some(RepeatKind::String)
} else {
let ty = ty.peel_refs();
- (ty.is_str() || is_type_diagnostic_item(cx, ty, sym::String)).then_some(RepeatKind::String)
+ (ty.is_str() || is_type_lang_item(cx, ty, LangItem::String)).then_some(RepeatKind::String)
}
}
}
if_chain! {
if let ExprKind::Call(repeat_fn, [repeat_arg]) = take_self_arg.kind;
if is_path_diagnostic_item(cx, repeat_fn, sym::iter_repeat);
- if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(collect_expr), sym::String);
+ if is_type_lang_item(cx, cx.typeck_results().expr_ty(collect_expr), LangItem::String);
if let Some(collect_id) = cx.typeck_results().type_dependent_def_id(collect_expr.hir_id);
if let Some(take_id) = cx.typeck_results().type_dependent_def_id(take_expr.hir_id);
if let Some(iter_trait_id) = cx.tcx.get_diagnostic_item(sym::Iterator);
use clippy_utils::diagnostics::span_lint;
-use clippy_utils::ty::is_type_diagnostic_item;
+use clippy_utils::ty::is_type_lang_item;
use clippy_utils::SpanlessEq;
use if_chain::if_chain;
use rustc_ast::LitKind;
-use rustc_hir::ExprKind;
+use rustc_hir::{ExprKind, LangItem};
use rustc_lint::LateContext;
-use rustc_span::sym;
use super::NO_EFFECT_REPLACE;
arg2: &'tcx rustc_hir::Expr<'_>,
) {
let ty = cx.typeck_results().expr_ty(expr).peel_refs();
- if !(ty.is_str() || is_type_diagnostic_item(cx, ty, sym::String)) {
+ if !(ty.is_str() || is_type_lang_item(cx, ty, LangItem::String)) {
return;
}
use clippy_utils::consts::{constant_context, Constant};
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::snippet;
-use clippy_utils::ty::is_type_diagnostic_item;
+use clippy_utils::ty::is_type_lang_item;
use rustc_errors::Applicability;
-use rustc_hir::Expr;
+use rustc_hir::{Expr, LangItem};
use rustc_lint::LateContext;
-use rustc_span::sym;
use super::REPEAT_ONCE;
format!("{}.to_vec()", snippet(cx, recv.span, r#""...""#)),
Applicability::MachineApplicable,
);
- } else if is_type_diagnostic_item(cx, ty, sym::String) {
+ } else if is_type_lang_item(cx, ty, LangItem::String) {
span_lint_and_sugg(
cx,
REPEAT_ONCE,
use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg};
use clippy_utils::source::{snippet, snippet_with_applicability};
use clippy_utils::sugg::deref_closure_args;
-use clippy_utils::ty::is_type_diagnostic_item;
+use clippy_utils::ty::is_type_lang_item;
use clippy_utils::{is_trait_method, strip_pat_refs};
use if_chain::if_chain;
use rustc_errors::Applicability;
else if search_method == "find" {
let is_string_or_str_slice = |e| {
let self_ty = cx.typeck_results().expr_ty(e).peel_refs();
- if is_type_diagnostic_item(cx, self_ty, sym::String) {
+ if is_type_lang_item(cx, self_ty, hir::LangItem::String) {
true
} else {
*self_ty.kind() == ty::Str
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::method_chain_args;
use clippy_utils::source::snippet_with_applicability;
-use clippy_utils::ty::is_type_diagnostic_item;
+use clippy_utils::ty::is_type_lang_item;
use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_lint::LateContext;
use rustc_middle::ty;
-use rustc_span::symbol::sym;
use super::STRING_EXTEND_CHARS;
pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>, arg: &hir::Expr<'_>) {
let obj_ty = cx.typeck_results().expr_ty(recv).peel_refs();
- if !is_type_diagnostic_item(cx, obj_ty, sym::String) {
+ if !is_type_lang_item(cx, obj_ty, hir::LangItem::String) {
return;
}
if let Some(arglists) = method_chain_args(arg, &["chars"]) {
let self_ty = cx.typeck_results().expr_ty(target).peel_refs();
let ref_str = if *self_ty.kind() == ty::Str {
""
- } else if is_type_diagnostic_item(cx, self_ty, sym::String) {
+ } else if is_type_lang_item(cx, self_ty, hir::LangItem::String) {
"&"
} else {
return;
-use clippy_utils::{diagnostics::span_lint_and_sugg, ty::is_type_diagnostic_item};
+use clippy_utils::{diagnostics::span_lint_and_sugg, ty::is_type_lang_item};
use rustc_ast::ast::LitKind;
use rustc_errors::Applicability;
-use rustc_hir::{Expr, ExprKind};
+use rustc_hir::{Expr, ExprKind, LangItem};
use rustc_lint::LateContext;
use rustc_middle::ty::{Ref, Slice};
-use rustc_span::{sym, Span};
+use rustc_span::Span;
use super::UNNECESSARY_JOIN;
// the turbofish for collect is ::<Vec<String>>
if let Ref(_, ref_type, _) = collect_output_adjusted_type.kind();
if let Slice(slice) = ref_type.kind();
- if is_type_diagnostic_item(cx, *slice, sym::String);
+ if is_type_lang_item(cx, *slice, LangItem::String);
// the argument for join is ""
if let ExprKind::Lit(spanned) = &join_arg.kind;
if let LitKind::Str(symbol, _) = spanned.node;
use clippy_utils::diagnostics::{multispan_sugg, span_lint_and_then};
use clippy_utils::ptr::get_spans;
use clippy_utils::source::{snippet, snippet_opt};
-use clippy_utils::ty::{implements_trait, is_copy, is_type_diagnostic_item};
+use clippy_utils::ty::{implements_trait, is_copy, is_type_diagnostic_item, is_type_lang_item};
use clippy_utils::{get_trait_def_id, is_self, paths};
use if_chain::if_chain;
use rustc_ast::ast::Attribute;
use rustc_hir::{
BindingAnnotation, Body, FnDecl, GenericArg, HirId, Impl, ItemKind, Mutability, Node, PatKind, QPath, TyKind,
};
-use rustc_hir::{HirIdMap, HirIdSet};
+use rustc_hir::{HirIdMap, HirIdSet, LangItem};
use rustc_hir_typeck::expr_use_visitor as euv;
use rustc_infer::infer::TyCtxtInferExt;
use rustc_lint::{LateContext, LateLintPass};
}
}
- if is_type_diagnostic_item(cx, ty, sym::String) {
+ if is_type_lang_item(cx, ty, LangItem::String) {
if let Some(clone_spans) =
get_spans(cx, Some(body.id()), idx, &[("clone", ".to_string()"), ("as_str", "")]) {
diag.span_suggestion(
use clippy_utils::diagnostics::span_lint_and_help;
use clippy_utils::is_direct_expn_of;
use if_chain::if_chain;
-use rustc_ast::ast::{Expr, ExprKind};
+use rustc_ast::ast::{Expr, ExprKind, MethodCall};
use rustc_lint::{EarlyContext, EarlyLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::sym;
impl EarlyLintPass for OptionEnvUnwrap {
fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
if_chain! {
- if let ExprKind::MethodCall(path_segment, receiver, _, _) = &expr.kind;
- if matches!(path_segment.ident.name, sym::expect | sym::unwrap);
+ if let ExprKind::MethodCall(box MethodCall { seg, receiver, .. }) = &expr.kind;
+ if matches!(seg.ident.name, sym::expect | sym::unwrap);
if let ExprKind::Call(caller, _) = &receiver.kind;
if is_direct_expn_of(caller.span, "option_env").is_some();
then {
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::snippet_with_applicability;
use if_chain::if_chain;
-use rustc_ast::ast::{BinOpKind, Expr, ExprKind, UnOp};
+use rustc_ast::ast::{BinOpKind, Expr, ExprKind, MethodCall, UnOp};
use rustc_ast::token;
use rustc_errors::Applicability;
use rustc_lint::{EarlyContext, EarlyLintPass};
let mut arg = operand;
let mut all_odd = true;
- while let ExprKind::MethodCall(path_segment, receiver, _, _) = &arg.kind {
- let path_segment_str = path_segment.ident.name.as_str();
+ while let ExprKind::MethodCall(box MethodCall { seg, receiver, .. }) = &arg.kind {
+ let seg_str = seg.ident.name.as_str();
all_odd &= ALLOWED_ODD_FUNCTIONS
.iter()
- .any(|odd_function| **odd_function == *path_segment_str);
+ .any(|odd_function| **odd_function == *seg_str);
arg = receiver;
}
substs.type_at(0),
),
),
- Some(sym::String) => (
+ _ if Some(adt.did()) == cx.tcx.lang_items().string() => (
[("clone", ".to_owned()"), ("as_str", "")].as_slice(),
DerefTy::Str,
),
use clippy_utils::diagnostics::{span_lint_hir, span_lint_hir_and_then};
use clippy_utils::mir::{visit_local_usage, LocalUsage, PossibleBorrowerMap};
use clippy_utils::source::snippet_opt;
-use clippy_utils::ty::{has_drop, is_copy, is_type_diagnostic_item, walk_ptrs_ty_depth};
+use clippy_utils::ty::{has_drop, is_copy, is_type_diagnostic_item, is_type_lang_item, walk_ptrs_ty_depth};
use clippy_utils::{fn_has_unsatisfiable_preds, match_def_path, paths};
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir::intravisit::FnKind;
-use rustc_hir::{def_id, Body, FnDecl, HirId};
+use rustc_hir::{def_id, Body, FnDecl, HirId, LangItem};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::mir;
use rustc_middle::ty::{self, Ty};
let from_borrow = match_def_path(cx, fn_def_id, &paths::CLONE_TRAIT_METHOD)
|| match_def_path(cx, fn_def_id, &paths::TO_OWNED_METHOD)
|| (match_def_path(cx, fn_def_id, &paths::TO_STRING_METHOD)
- && is_type_diagnostic_item(cx, arg_ty, sym::String));
+ && is_type_lang_item(cx, arg_ty, LangItem::String));
let from_deref = !from_borrow
&& (match_def_path(cx, fn_def_id, &paths::PATH_TO_PATH_BUF)
if_chain! {
if let ast::ExprKind::Call(ref paren, _) = expr.kind;
if let ast::ExprKind::Paren(ref closure) = paren.kind;
- if let ast::ExprKind::Closure(_, _, ref r#async, _, ref decl, ref block, _) = closure.kind;
+ if let ast::ExprKind::Closure(box ast::Closure { ref asyncness, ref fn_decl, ref body, .. }) = closure.kind;
then {
let mut visitor = ReturnVisitor::new();
- visitor.visit_expr(block);
+ visitor.visit_expr(body);
if !visitor.found_return {
span_lint_and_then(
cx,
expr.span,
"try not to call a closure in the expression where it is declared",
|diag| {
- if decl.inputs.is_empty() {
+ if fn_decl.inputs.is_empty() {
let app = Applicability::MachineApplicable;
- let mut hint = Sugg::ast(cx, block, "..");
+ let mut hint = Sugg::ast(cx, body, "..");
- if r#async.is_async() {
+ if asyncness.is_async() {
// `async x` is a syntax error, so it becomes `async { x }`
- if !matches!(block.kind, ast::ExprKind::Block(_, _)) {
+ if !matches!(body.kind, ast::ExprKind::Block(_, _)) {
hint = hint.blockify();
}
use clippy_utils::diagnostics::{span_lint, span_lint_and_help, span_lint_and_sugg};
use clippy_utils::source::{snippet, snippet_with_applicability};
-use clippy_utils::ty::is_type_diagnostic_item;
+use clippy_utils::ty::is_type_lang_item;
use clippy_utils::{get_parent_expr, is_lint_allowed, match_function_call, method_calls, paths};
use clippy_utils::{peel_blocks, SpanlessEq};
use if_chain::if_chain;
},
ExprKind::Index(target, _idx) => {
let e_ty = cx.typeck_results().expr_ty(target).peel_refs();
- if matches!(e_ty.kind(), ty::Str) || is_type_diagnostic_item(cx, e_ty, sym::String) {
+ if matches!(e_ty.kind(), ty::Str) || is_type_lang_item(cx, e_ty, LangItem::String) {
span_lint(
cx,
STRING_SLICE,
}
fn is_string(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
- is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(e).peel_refs(), sym::String)
+ is_type_lang_item(cx, cx.typeck_results().expr_ty(e).peel_refs(), LangItem::String)
}
fn is_add(cx: &LateContext<'_>, src: &Expr<'_>, target: &Expr<'_>) -> bool {
if let ExprKind::MethodCall(path, self_arg, ..) = &expr.kind;
if path.ident.name == sym::to_string;
let ty = cx.typeck_results().expr_ty(self_arg);
- if is_type_diagnostic_item(cx, ty, sym::String);
+ if is_type_lang_item(cx, ty, LangItem::String);
then {
span_lint_and_help(
cx,
| (Await(_), Await(_))
| (Async(_, _, _), Async(_, _, _))
| (Block(_, _), Block(_, _))
- | (Closure(_, _, _, _, _, _, _), Closure(_, _, _, _, _, _, _))
+ | (Closure(_), Closure(_))
| (Match(_, _), Match(_, _))
| (Loop(_, _), Loop(_, _))
| (ForLoop(_, _, _, _), ForLoop(_, _, _, _))
| (Unary(_, _), Unary(_, _))
| (Binary(_, _, _), Binary(_, _, _))
| (Tup(_), Tup(_))
- | (MethodCall(_, _, _, _), MethodCall(_, _, _, _))
+ | (MethodCall(_), MethodCall(_))
| (Call(_, _), Call(_, _))
| (ConstBlock(_), ConstBlock(_))
| (Array(_), Array(_))
fn get_std_collection(cx: &LateContext<'_>, qpath: &QPath<'_>) -> Option<Symbol> {
let param = qpath_generic_tys(qpath).next()?;
let id = path_def_id(cx, param)?;
- cx.tcx.get_diagnostic_name(id).filter(|&name| {
- matches!(
- name,
- sym::HashMap
- | sym::String
- | sym::Vec
- | sym::HashSet
- | sym::VecDeque
- | sym::LinkedList
- | sym::BTreeMap
- | sym::BTreeSet
- | sym::BinaryHeap
- )
- })
+ cx.tcx
+ .get_diagnostic_name(id)
+ .filter(|&name| matches!(name, sym::HashMap | sym::Vec | sym::HashSet
+ | sym::VecDeque
+ | sym::LinkedList
+ | sym::BTreeMap
+ | sym::BTreeSet
+ | sym::BinaryHeap))
+ .or_else(|| {
+ cx.tcx
+ .lang_items()
+ .string()
+ .filter(|did| id == *did)
+ .map(|_| sym::String)
+ })
}
fn match_buffer_type(cx: &LateContext<'_>, qpath: &QPath<'_>) -> Option<&'static str> {
let ty = qpath_generic_tys(qpath).next()?;
let id = path_def_id(cx, ty)?;
- let path = match cx.tcx.get_diagnostic_name(id)? {
- sym::String => "str",
- sym::OsString => "std::ffi::OsStr",
- sym::PathBuf => "std::path::Path",
+ let path = match cx.tcx.get_diagnostic_name(id) {
+ Some(sym::OsString) => "std::ffi::OsStr",
+ Some(sym::PathBuf) => "std::path::Path",
+ _ if Some(id) == cx.tcx.lang_items().string() => "str",
_ => return None,
};
Some(path)
-use clippy_utils::{diagnostics::span_lint_and_sugg, ty::is_type_diagnostic_item};
+use clippy_utils::{diagnostics::span_lint_and_sugg, ty::is_type_lang_item};
use clippy_utils::{match_def_path, paths};
use if_chain::if_chain;
use rustc_ast::ast::LitKind;
use rustc_errors::Applicability;
-use rustc_hir::{BorrowKind, Expr, ExprKind, Mutability};
+use rustc_hir::{BorrowKind, Expr, ExprKind, LangItem, Mutability};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty;
use rustc_session::{declare_lint_pass, declare_tool_lint};
-use rustc_span::sym;
declare_clippy_lint! {
/// ### What it does
if let LitKind::Str(symbol, _) = spanned.node;
if symbol.is_empty();
let inner_expr_type = cx.typeck_results().expr_ty(inner_expr);
- if is_type_diagnostic_item(cx, inner_expr_type, sym::String);
+ if is_type_lang_item(cx, inner_expr_type, LangItem::String);
then {
span_lint_and_sugg(
cx,
/// So when we fixate on some `ident_k: pat_k`, we try to find `ident_k` in the other pattern
/// and check that all `fp_i` where `i ∈ ((0...n) \ k)` between two patterns are equal.
fn extend_with_struct_pat(
- qself1: &Option<ast::QSelf>,
+ qself1: &Option<P<ast::QSelf>>,
path1: &ast::Path,
fps1: &mut [ast::PatField],
rest1: bool,
use clippy_utils::diagnostics::span_lint_and_help;
use rustc_hir::intravisit::{walk_expr, walk_fn, FnKind, Visitor};
-use rustc_hir::{Body, Expr, ExprKind, FnDecl, HirId, IsAsync, YieldSource};
+use rustc_hir::{Body, Expr, ExprKind, FnDecl, HirId, YieldSource};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::hir::nested_filter;
use rustc_session::{declare_lint_pass, declare_tool_lint};
span: Span,
hir_id: HirId,
) {
- if !span.from_expansion() && fn_kind.asyncness() == IsAsync::Async {
+ if !span.from_expansion() && fn_kind.asyncness().is_async() {
let mut visitor = AsyncFnVisitor { cx, found_await: false };
walk_fn(&mut visitor, fn_kind, fn_decl, body.id(), hir_id);
if !visitor.found_await {
use clippy_utils::diagnostics::span_lint_and_sugg;
-use rustc_ast::ast::{Expr, ExprKind};
+use rustc_ast::ast::{Expr, ExprKind, MethodCall};
use rustc_errors::Applicability;
use rustc_lint::{EarlyContext, EarlyLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};
declare_lint_pass!(UnusedRounding => [UNUSED_ROUNDING]);
fn is_useless_rounding(expr: &Expr) -> Option<(&str, String)> {
- if let ExprKind::MethodCall(name_ident, receiver, _, _) = &expr.kind
- && let method_name = name_ident.ident.name.as_str()
+ if let ExprKind::MethodCall(box MethodCall { seg, receiver, .. }) = &expr.kind
+ && let method_name = seg.ident.name.as_str()
&& (method_name == "ceil" || method_name == "round" || method_name == "floor")
&& let ExprKind::Lit(token_lit) = &receiver.kind
&& token_lit.is_semantic_float() {
SimplifiedTypeGen::StrSimplifiedType,
]
.iter()
- .flat_map(|&ty| cx.tcx.incoherent_impls(ty));
- for item_def_id in lang_items.items().iter().flatten().chain(incoherent_impls) {
- let lang_item_path = cx.get_def_path(*item_def_id);
+ .flat_map(|&ty| cx.tcx.incoherent_impls(ty).iter().copied());
+ for item_def_id in lang_items.iter().map(|(_, def_id)| def_id).chain(incoherent_impls) {
+ let lang_item_path = cx.get_def_path(item_def_id);
if path_syms.starts_with(&lang_item_path) {
if let [item] = &path_syms[lang_item_path.len()..] {
if matches!(
- cx.tcx.def_kind(*item_def_id),
+ cx.tcx.def_kind(item_def_id),
DefKind::Mod | DefKind::Enum | DefKind::Trait
) {
- for child in cx.tcx.module_children(*item_def_id) {
+ for child in cx.tcx.module_children(item_def_id) {
if child.ident.name == *item {
return true;
}
}
} else {
- for child in cx.tcx.associated_item_def_ids(*item_def_id) {
+ for child in cx.tcx.associated_item_def_ids(item_def_id) {
if cx.tcx.item_name(*child) == *item {
return true;
}
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::Applicability;
use rustc_hir as hir;
-use rustc_hir::def::{DefKind, Namespace, Res};
+use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::DefId;
use rustc_hir::{Expr, ExprKind, Local, Mutability, Node};
use rustc_lint::{LateContext, LateLintPass};
#[allow(clippy::too_many_lines)]
fn check_call(&mut self, cx: &LateContext<'_>, func: &Expr<'_>, args: &[Expr<'_>], span: Span) {
enum Item {
- LangItem(Symbol),
+ LangItem(&'static str),
DiagnosticItem(Symbol),
}
static PATHS: &[&[&str]] = &[
})
}
-fn get_lang_item_name(cx: &LateContext<'_>, def_id: DefId) -> Option<Symbol> {
- if let Some(lang_item) = cx.tcx.lang_items().items().iter().position(|id| *id == Some(def_id)) {
- let lang_items = def_path_res(cx, &["rustc_hir", "lang_items", "LangItem"], Some(Namespace::TypeNS)).def_id();
- let item_name = cx
- .tcx
- .adt_def(lang_items)
- .variants()
- .iter()
- .nth(lang_item)
- .unwrap()
- .name;
- Some(item_name)
+fn get_lang_item_name(cx: &LateContext<'_>, def_id: DefId) -> Option<&'static str> {
+ if let Some((lang_item, _)) = cx.tcx.lang_items().iter().find(|(_, id)| *id == def_id) {
+ Some(lang_item.variant_name())
} else {
None
}
&& over(&l.attrs, &r.attrs, eq_attr)
}
-pub fn eq_qself(l: &QSelf, r: &QSelf) -> bool {
+pub fn eq_qself(l: &P<QSelf>, r: &P<QSelf>) -> bool {
l.position == r.position && eq_ty(&l.ty, &r.ty)
}
-pub fn eq_maybe_qself(l: &Option<QSelf>, r: &Option<QSelf>) -> bool {
+pub fn eq_maybe_qself(l: &Option<P<QSelf>>, r: &Option<P<QSelf>>) -> bool {
match (l, r) {
(Some(l), Some(r)) => eq_qself(l, r),
(None, None) => true,
(Array(l), Array(r)) | (Tup(l), Tup(r)) => over(l, r, |l, r| eq_expr(l, r)),
(Repeat(le, ls), Repeat(re, rs)) => eq_expr(le, re) && eq_expr(&ls.value, &rs.value),
(Call(lc, la), Call(rc, ra)) => eq_expr(lc, rc) && over(la, ra, |l, r| eq_expr(l, r)),
- (MethodCall(lc, ls, la, _), MethodCall(rc, rs, ra, _)) => {
- eq_path_seg(lc, rc) && eq_expr(ls, rs) && over(la, ra, |l, r| eq_expr(l, r))
+ (
+ MethodCall(box ast::MethodCall { seg: ls, receiver: lr, args: la, .. }),
+ MethodCall(box ast::MethodCall { seg: rs, receiver: rr, args: ra, .. })
+ ) => {
+ eq_path_seg(ls, rs) && eq_expr(lr, rr) && over(la, ra, |l, r| eq_expr(l, r))
},
(Binary(lo, ll, lr), Binary(ro, rl, rr)) => lo.node == ro.node && eq_expr(ll, rl) && eq_expr(lr, rr),
(Unary(lo, l), Unary(ro, r)) => mem::discriminant(lo) == mem::discriminant(ro) && eq_expr(l, r),
(AssignOp(lo, lp, lv), AssignOp(ro, rp, rv)) => lo.node == ro.node && eq_expr(lp, rp) && eq_expr(lv, rv),
(Field(lp, lf), Field(rp, rf)) => eq_id(*lf, *rf) && eq_expr(lp, rp),
(Match(ls, la), Match(rs, ra)) => eq_expr(ls, rs) && over(la, ra, eq_arm),
- (Closure(lb, lc, la, lm, lf, le, _), Closure(rb, rc, ra, rm, rf, re, _)) => {
+ (
+ Closure(box ast::Closure {
+ binder: lb,
+ capture_clause: lc,
+ asyncness: la,
+ movability: lm,
+ fn_decl: lf,
+ body: le,
+ ..
+ }),
+ Closure(box ast::Closure {
+ binder: rb,
+ capture_clause: rc,
+ asyncness: ra,
+ movability: rm,
+ fn_decl: rf,
+ body: re,
+ ..
+ })
+ ) => {
eq_closure_binder(lb, rb)
&& lc == rc
&& la.is_async() == ra.is_async()
use rustc_hir::intravisit::{walk_expr, FnKind, Visitor};
use rustc_hir::LangItem::{OptionNone, ResultErr, ResultOk};
use rustc_hir::{
- def, Arm, ArrayLen, BindingAnnotation, Block, BlockCheckMode, Body, Closure, Constness, Destination, Expr,
- ExprKind, FnDecl, HirId, Impl, ImplItem, ImplItemKind, IsAsync, Item, ItemKind, LangItem, Local, MatchSource,
- Mutability, Node, Param, Pat, PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, TraitItem, TraitItemKind,
- TraitRef, TyKind, UnOp,
+ def, Arm, ArrayLen, BindingAnnotation, Block, BlockCheckMode, Body, Closure, Constness,
+ Destination, Expr, ExprKind, FnDecl, HirId, Impl, ImplItem, ImplItemKind, Item, ItemKind,
+ LangItem, Local, MatchSource, Mutability, Node, Param, Pat, PatKind, Path, PathSegment, PrimTy,
+ QPath, Stmt, StmtKind, TraitItem, TraitItemKind, TraitRef, TyKind, UnOp,
};
use rustc_lexer::{tokenize, TokenKind};
use rustc_lint::{LateContext, Level, Lint, LintContext};
path_def_id(cx, expr).map_or(false, |id| match_def_path(cx, id, segments))
}
+/// If `maybe_path` is a path node which resolves to an item, resolves it to a `DefId` and checks if
+/// it matches the given lang item.
+pub fn is_path_lang_item<'tcx>(
+ cx: &LateContext<'_>,
+ maybe_path: &impl MaybePath<'tcx>,
+ lang_item: LangItem,
+) -> bool {
+ path_def_id(cx, maybe_path).map_or(false, |id| cx.tcx.lang_items().get(lang_item) == Some(id))
+}
+
/// If `maybe_path` is a path node which resolves to an item, resolves it to a `DefId` and checks if
/// it matches the given diagnostic item.
pub fn is_path_diagnostic_item<'tcx>(
/// constructor from the std library
fn is_default_equivalent_ctor(cx: &LateContext<'_>, def_id: DefId, path: &QPath<'_>) -> bool {
let std_types_symbols = &[
- sym::String,
sym::Vec,
sym::VecDeque,
sym::LinkedList,
if let Some(adt) = cx.tcx.type_of(impl_did).ty_adt_def() {
return std_types_symbols
.iter()
- .any(|&symbol| cx.tcx.is_diagnostic_item(symbol, adt.did()));
+ .any(|&symbol| cx.tcx.is_diagnostic_item(symbol, adt.did()) || Some(adt.did()) == cx.tcx.lang_items().string());
}
}
}
ExprKind::Lit(hir::Lit {
node: LitKind::Str(ref sym, _),
..
- }) => return sym.is_empty() && is_path_diagnostic_item(cx, ty, sym::String),
+ }) => return sym.is_empty() && is_path_lang_item(cx, ty, LangItem::String),
ExprKind::Array([]) => return is_path_diagnostic_item(cx, ty, sym::Vec),
ExprKind::Repeat(_, ArrayLen::Body(len)) => {
if let ExprKind::Lit(ref const_lit) = cx.tcx.hir().body(len.body).value.kind &&
/// Checks if the given function kind is an async function.
pub fn is_async_fn(kind: FnKind<'_>) -> bool {
- matches!(kind, FnKind::ItemFn(_, _, header) if header.asyncness == IsAsync::Async)
+ matches!(kind, FnKind::ItemFn(_, _, header) if header.asyncness.is_async())
}
/// Peels away all the compiler generated code surrounding the body of an async function,
let _ = is_type_lang_item(cx, ty, LangItem::OwnedBox);
let _ = is_type_diagnostic_item(cx, ty, sym::maybe_uninit_uninit);
- let _ = cx.tcx.lang_items().require(LangItem::OwnedBox).ok() == Some(did);
+ let _ = cx.tcx.lang_items().get(LangItem::OwnedBox) == Some(did);
let _ = cx.tcx.is_diagnostic_item(sym::Option, did);
- let _ = cx.tcx.lang_items().require(LangItem::OptionSome).ok() == Some(did);
+ let _ = cx.tcx.lang_items().get(LangItem::OptionSome) == Some(did);
let _ = is_trait_method(cx, expr, sym::AsRef);
let _ = is_path_diagnostic_item(cx, expr, sym::Option);
- let _ = path_res(cx, expr).opt_def_id().map_or(false, |id| cx.tcx.lang_items().require(LangItem::IteratorNext).ok() == Some(id));
+ let _ = path_res(cx, expr).opt_def_id().map_or(false, |id| cx.tcx.lang_items().get(LangItem::IteratorNext) == Some(id));
let _ = is_res_lang_ctor(cx, path_res(cx, expr), LangItem::OptionSome);
}
--> $DIR/unnecessary_def_path.rs:51:13
|
LL | let _ = match_def_path(cx, did, &["alloc", "boxed", "Box"]);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cx.tcx.lang_items().require(LangItem::OwnedBox).ok() == Some(did)`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cx.tcx.lang_items().get(LangItem::OwnedBox) == Some(did)`
error: use of a def path to a diagnostic item
--> $DIR/unnecessary_def_path.rs:52:13
--> $DIR/unnecessary_def_path.rs:53:13
|
LL | let _ = match_def_path(cx, did, &["core", "option", "Option", "Some"]);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cx.tcx.lang_items().require(LangItem::OptionSome).ok() == Some(did)`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cx.tcx.lang_items().get(LangItem::OptionSome) == Some(did)`
|
= help: if this `DefId` came from a constructor expression or pattern then the parent `DefId` should be used instead
--> $DIR/unnecessary_def_path.rs:58:13
|
LL | let _ = is_expr_path_def_path(cx, expr, &["core", "iter", "traits", "Iterator", "next"]);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `path_res(cx, expr).opt_def_id().map_or(false, |id| cx.tcx.lang_items().require(LangItem::IteratorNext).ok() == Some(id))`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `path_res(cx, expr).opt_def_id().map_or(false, |id| cx.tcx.lang_items().get(LangItem::IteratorNext) == Some(id))`
error: use of a def path to a `LangItem`
--> $DIR/unnecessary_def_path.rs:59:13
-error: hardcoded path to a language item
- --> $DIR/unnecessary_def_path_hardcoded_path.rs:11:40
+error: hardcoded path to a diagnostic item
+ --> $DIR/unnecessary_def_path_hardcoded_path.rs:10:36
|
-LL | const DEREF_MUT_TRAIT: [&str; 4] = ["core", "ops", "deref", "DerefMut"];
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | const DEREF_TRAIT: [&str; 4] = ["core", "ops", "deref", "Deref"];
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
- = help: convert all references to use `LangItem::DerefMut`
+ = help: convert all references to use `sym::Deref`
= note: `-D clippy::unnecessary-def-path` implied by `-D warnings`
error: hardcoded path to a diagnostic item
|
= help: convert all references to use `sym::deref_method`
-error: hardcoded path to a diagnostic item
- --> $DIR/unnecessary_def_path_hardcoded_path.rs:10:36
+error: hardcoded path to a language item
+ --> $DIR/unnecessary_def_path_hardcoded_path.rs:11:40
|
-LL | const DEREF_TRAIT: [&str; 4] = ["core", "ops", "deref", "Deref"];
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | const DEREF_MUT_TRAIT: [&str; 4] = ["core", "ops", "deref", "DerefMut"];
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
- = help: convert all references to use `sym::Deref`
+ = help: convert all references to use `LangItem::DerefMut`
error: aborting due to 3 previous errors
/// The directory where programs should be built
pub build_base: PathBuf,
+ /// The directory containing the compiler sysroot
+ pub sysroot_base: PathBuf,
+
/// The name of the stage being built (stage1, etc)
pub stage_id: String,
"--jsondocck-path=",
"--src-base=",
"--build-base=",
+ "--sysroot-base=",
"--stage-id=stage2",
"--cc=c",
"--cxx=c++",
.optopt("", "llvm-filecheck", "path to LLVM's FileCheck binary", "DIR")
.reqopt("", "src-base", "directory to scan for test files", "PATH")
.reqopt("", "build-base", "directory to deposit test outputs", "PATH")
+ .reqopt("", "sysroot-base", "directory containing the compiler sysroot", "PATH")
.reqopt("", "stage-id", "the target-stage identifier", "stageN-TARGET")
.reqopt(
"",
llvm_bin_dir: matches.opt_str("llvm-bin-dir").map(PathBuf::from),
src_base,
build_base: opt_path(matches, "build-base"),
+ sysroot_base: opt_path(matches, "sysroot-base"),
stage_id: matches.opt_str("stage-id").unwrap(),
mode,
suite: matches.opt_str("suite").unwrap(),
script_str.push_str("\n");
}
- script_str.push_str("\nqq\n"); // Quit the debugger (including remote debugger, if any)
+ script_str.push_str("qq\n"); // Quit the debugger (including remote debugger, if any)
// Write the script into a file
debug!("script_str = {}", script_str);
let parent_dir = self.testpaths.file.parent().unwrap();
normalize_path(parent_dir, "$DIR");
- // Paths into the libstd/libcore
- let base_dir = self.config.src_base.parent().unwrap().parent().unwrap().parent().unwrap();
- let src_dir = base_dir.join("library");
- normalize_path(&src_dir, "$SRC_DIR");
-
- // `ui-fulldeps` tests can show paths to the compiler source when testing macros from
- // `rustc_macros`
- // eg. /home/user/rust/compiler
- let compiler_src_dir = base_dir.join("compiler");
- normalize_path(&compiler_src_dir, "$COMPILER_DIR");
-
- if let Some(virtual_rust_source_base_dir) =
- option_env!("CFG_VIRTUAL_RUST_SOURCE_BASE_DIR").map(PathBuf::from)
- {
- normalize_path(&virtual_rust_source_base_dir.join("library"), "$SRC_DIR");
- normalize_path(&virtual_rust_source_base_dir.join("compiler"), "$COMPILER_DIR");
+ let source_bases = &[
+ // Source base on the current filesystem (calculated as parent of `src/test/$suite`):
+ Some(self.config.src_base.parent().unwrap().parent().unwrap().parent().unwrap().into()),
+ // Source base on the sysroot (from the src components downloaded by `download-rustc`):
+ Some(self.config.sysroot_base.join("lib").join("rustlib").join("src").join("rust")),
+ // Virtual `/rustc/$sha` remapped paths (if `remap-debuginfo` is enabled):
+ option_env!("CFG_VIRTUAL_RUST_SOURCE_BASE_DIR").map(PathBuf::from),
+ // Virtual `/rustc/$sha` coming from download-rustc:
+ std::env::var_os("FAKE_DOWNLOAD_RUSTC_PREFIX").map(PathBuf::from),
+ ];
+ for base_dir in source_bases {
+ if let Some(base_dir) = base_dir {
+ // Paths into the libstd/libcore
+ normalize_path(&base_dir.join("library"), "$SRC_DIR");
+ // `ui-fulldeps` tests can show paths to the compiler source when testing macros from
+ // `rustc_macros`
+ // eg. /home/user/rust/compiler
+ normalize_path(&base_dir.join("compiler"), "$COMPILER_DIR");
+ }
}
// Paths into the build directory
"regex",
"rustc-workspace-hack",
"rustc_version",
- "shell-escape",
"smallvec",
"ui_test",
]
"lazy_static",
]
-[[package]]
-name = "shell-escape"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "45bb67a18fa91266cc7807181f62f9178a6873bfad7dc788c42e6430db40184f"
-
[[package]]
name = "smallvec"
version = "1.9.0"
getrandom = { version = "0.2", features = ["std"] }
env_logger = "0.9"
log = "0.4"
-shell-escape = "0.1.4"
rand = "0.8"
smallvec = "1.7"
# Miri
-[![Actions build status][actions-badge]][actions-url]
-
-[actions-badge]: https://github.com/rust-lang/miri/workflows/CI/badge.svg?branch=master
-[actions-url]: https://github.com/rust-lang/miri/actions
-
An experimental interpreter for [Rust][rust]'s
[mid-level intermediate representation][mir] (MIR). It can run binaries and
test suites of cargo projects and detect certain classes of
snippet calls Miri in a loop with different values for the seed:
```
-for SEED in $({ echo obase=16; seq 0 255; } | bc); do
+for SEED in $(seq 0 255); do
echo "Trying seed: $SEED"
MIRIFLAGS=-Zmiri-seed=$SEED cargo miri test || { echo "Failing seed: $SEED"; break; };
done
tell what it is doing when a program just keeps running. You can customize how frequently the
report is printed via `-Zmiri-report-progress=<blocks>`, which prints the report every N basic
blocks.
-* `-Zmiri-seed=<hex>` configures the seed of the RNG that Miri uses to resolve non-determinism. This
+* `-Zmiri-seed=<num>` configures the seed of the RNG that Miri uses to resolve non-determinism. This
RNG is used to pick base addresses for allocations, to determine preemption and failure of
`compare_exchange_weak`, and to control store buffering for weak memory emulation. When isolation
is enabled (the default), this is also used to emulate system entropy. The default seed is 0. You
`rustup-toolchain-install-master` must be installed for this to work. Any extra
flags are passed to `rustup-toolchain-install-master`.
-./miri rustc-pull:
-Pull and merge Miri changes from the rustc repo. The fetched commit is stored in
-the `rust-version` file, so the next `./miri toolchain` will install the rustc
-we just pulled.
+./miri rustc-pull <commit>:
+Pull and merge Miri changes from the rustc repo. Defaults to fetching the latest
+rustc commit. The fetched commit is stored in the `rust-version` file, so the
+next `./miri toolchain` will install the rustc that just got pulled.
./miri rustc-push <github user> <branch>:
Push Miri changes back to the rustc repo. This will pull a copy of the rustc
;;
rustc-pull)
cd "$MIRIDIR"
- FETCH_COMMIT=$(git ls-remote https://github.com/rust-lang/rust/ HEAD | cut -f 1)
- # We can't pull from a commit with josh
- # (https://github.com/josh-project/josh/issues/1034), so we just hope that
- # nothing gets merged into rustc *during* this pull.
- git fetch http://localhost:8000/rust-lang/rust.git$JOSH_FILTER.git master
- # Just verify that `master` didn't move.
- if [[ $FETCH_COMMIT != $(git ls-remote https://github.com/rust-lang/rust/ HEAD | cut -f 1) ]]; then
- echo "Looks like something got merged into Rust *while we were pulling*. Aborting. Please try again."
+ FETCH_COMMIT="$1"
+ if [ -z "$FETCH_COMMIT" ]; then
+ FETCH_COMMIT=$(git ls-remote https://github.com/rust-lang/rust/ HEAD | cut -f 1)
fi
- echo "$FETCH_COMMIT" > rust-version # do this *before* merging as merging will fail in case of conflicts
+ # Update rust-version file. As a separate commit, since making it part of
+ # the merge has confused the heck out of josh in the past.
+ echo "$FETCH_COMMIT" > rust-version
+ git commit rust-version -m "Preparing for merge from rustc"
+ # Fetch given rustc commit and note down which one that was
+ git fetch http://localhost:8000/rust-lang/rust.git@$FETCH_COMMIT$JOSH_FILTER.git
git merge FETCH_HEAD --no-ff -m "Merge from rustc"
- git commit rust-version --amend -m "Merge from rustc"
exit 0
;;
rustc-push)
fi
git fetch https://github.com/rust-lang/rust $BASE
git push https://github.com/$USER/rust $BASE:refs/heads/$BRANCH -f
+ echo
# Do the actual push.
cd "$MIRIDIR"
echo "Pushing Miri changes..."
git push http://localhost:8000/$USER/rust.git$JOSH_FILTER.git HEAD:$BRANCH
- exit 0
+ # Do a round-trip check to make sure the push worked as expected.
+ echo
+ git fetch http://localhost:8000/$USER/rust.git@$JOSH_FILTER.git $BRANCH &>/dev/null
+ if [[ $(git rev-parse HEAD) != $(git rev-parse FETCH_HEAD) ]]; then
+ echo "ERROR: Josh created a non-roundtrip push! Do NOT merge this into rustc!"
+ exit 1
+ else
+ echo "Confirmed that the push round-trips back to Miri properly. Please create a rustc PR:"
+ echo " https://github.com/$USER/rust/pull/new/$BRANCH"
+ exit 0
+ fi
;;
many-seeds)
- for SEED in $({ echo obase=16; seq 0 255; } | bc); do
+ for SEED in $(seq 0 255); do
echo "Trying seed: $SEED"
- MIRIFLAGS="$MIRIFLAGS -Zmiri-seed=$SEED" $@ || { echo "Failing seed: $SEED"; break; }
+ MIRIFLAGS="$MIRIFLAGS -Zlayout-seed=$SEED -Zmiri-seed=$SEED" $@ || { echo "Failing seed: $SEED"; break; }
done
exit 0
;;
-101e1822c3e54e63996c8aaa014d55716f3937eb
+7477c1f4f7d6bef037d523099b240d22aa1b63a0
if miri_config.seed.is_some() {
show_error!("Cannot specify -Zmiri-seed multiple times!");
}
- let seed = u64::from_str_radix(param, 16)
- .unwrap_or_else(|_| show_error!(
- "-Zmiri-seed should only contain valid hex digits [0-9a-fA-F] and must fit into a u64 (max 16 characters)"
- ));
+ let seed = param.parse::<u64>().unwrap_or_else(|_| {
+ show_error!("-Zmiri-seed must be an integer that fits into u64")
+ });
miri_config.seed = Some(seed);
} else if let Some(_param) = arg.strip_prefix("-Zmiri-env-exclude=") {
show_error!(
}
// Other
- "exact_div" => {
- let [num, denom] = check_arg_count(args)?;
- this.exact_div(&this.read_immediate(num)?, &this.read_immediate(denom)?, dest)?;
- }
-
"breakpoint" => {
let [] = check_arg_count(args)?;
// normally this would raise a SIGTRAP, which aborts if no debugger is connected
}
let ptr = this.read_pointer(ptr_op)?;
+ // If this carries no provenance, treat it like an integer.
+ if ptr.provenance.is_none() {
+ // Use actual implementation.
+ return Ok(false);
+ }
+
if let Ok((alloc_id, _offset, _)) = this.ptr_try_get_alloc_id(ptr) {
// Only do anything if we can identify the allocation this goes to.
let (_size, cur_align, _kind) = this.get_alloc_info(alloc_id);
let this = self.eval_context_mut();
- this.assert_target_os("linux", "clock_gettime");
+ this.assert_target_os_is_unix("clock_gettime");
let clk_id = this.read_scalar(clk_id_op)?.to_i32()?;
- // Linux has two main kinds of clocks. REALTIME clocks return the actual time since the
- // Unix epoch, including effects which may cause time to move backwards such as NTP.
- // Linux further distinguishes regular and "coarse" clocks, but the "coarse" version
- // is just specified to be "faster and less precise", so we implement both the same way.
- let absolute_clocks =
- [this.eval_libc_i32("CLOCK_REALTIME")?, this.eval_libc_i32("CLOCK_REALTIME_COARSE")?];
- // The second kind is MONOTONIC clocks for which 0 is an arbitrary time point, but they are
- // never allowed to go backwards. We don't need to do any additonal monotonicity
- // enforcement because std::time::Instant already guarantees that it is monotonic.
- let relative_clocks =
- [this.eval_libc_i32("CLOCK_MONOTONIC")?, this.eval_libc_i32("CLOCK_MONOTONIC_COARSE")?];
+ let absolute_clocks;
+ let mut relative_clocks;
+
+ match this.tcx.sess.target.os.as_ref() {
+ "linux" => {
+ // Linux has two main kinds of clocks. REALTIME clocks return the actual time since the
+ // Unix epoch, including effects which may cause time to move backwards such as NTP.
+ // Linux further distinguishes regular and "coarse" clocks, but the "coarse" version
+ // is just specified to be "faster and less precise", so we implement both the same way.
+ absolute_clocks = vec![
+ this.eval_libc_i32("CLOCK_REALTIME")?,
+ this.eval_libc_i32("CLOCK_REALTIME_COARSE")?,
+ ];
+ // The second kind is MONOTONIC clocks for which 0 is an arbitrary time point, but they are
+ // never allowed to go backwards. We don't need to do any additonal monotonicity
+ // enforcement because std::time::Instant already guarantees that it is monotonic.
+ relative_clocks = vec![
+ this.eval_libc_i32("CLOCK_MONOTONIC")?,
+ this.eval_libc_i32("CLOCK_MONOTONIC_COARSE")?,
+ ];
+ }
+ "macos" => {
+ absolute_clocks = vec![this.eval_libc_i32("CLOCK_REALTIME")?];
+ relative_clocks = vec![this.eval_libc_i32("CLOCK_MONOTONIC")?];
+ // Some clocks only seem to exist in the aarch64 version of the target.
+ if this.tcx.sess.target.arch == "aarch64" {
+ // `CLOCK_UPTIME_RAW` supposed to not increment while the system is asleep... but
+ // that's not really something a program running inside Miri can tell, anyway.
+ // We need to support it because std uses it.
+ relative_clocks.push(this.eval_libc_i32("CLOCK_UPTIME_RAW")?);
+ }
+ }
+ target => throw_unsup_format!("`clock_gettime` is not supported on target OS {target}"),
+ }
let duration = if absolute_clocks.contains(&clk_id) {
this.check_no_isolation("`clock_gettime` with `REALTIME` clocks")?;
} else if relative_clocks.contains(&clk_id) {
this.machine.clock.now().duration_since(this.machine.clock.anchor())
} else {
+ // Unsupported clock.
let einval = this.eval_libc("EINVAL")?;
this.set_last_error(einval)?;
return Ok(Scalar::from_i32(-1));
let result = this.gettimeofday(tv, tz)?;
this.write_scalar(Scalar::from_i32(result), dest)?;
}
+ "clock_gettime" => {
+ let [clk_id, tp] =
+ this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+ let result = this.clock_gettime(clk_id, tp)?;
+ this.write_scalar(result, dest)?;
+ }
// Allocation
"posix_memalign" => {
this.write_scalar(result, dest)?;
}
- // Time related shims
- "clock_gettime" => {
- // This is a POSIX function but it has only been tested on linux.
- let [clk_id, tp] =
- this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
- let result = this.clock_gettime(clk_id, tp)?;
- this.write_scalar(result, dest)?;
- }
-
// Threading
"pthread_condattr_setclock" => {
let [attr, clock_id] =
use rustc_middle::ty::{
self,
layout::{HasParamEnv, LayoutOf},
- Ty,
};
use rustc_target::abi::Abi;
use rustc_target::abi::Size;
let mut visitor = RetagVisitor { ecx: this, kind, retag_cause, retag_fields };
return visitor.visit_value(place);
- // Determine mutability and whether to add a protector.
- // Cannot use `builtin_deref` because that reports *immutable* for `Box`,
- // making it useless.
- fn qualify(ty: Ty<'_>, kind: RetagKind) -> Option<(RefKind, bool)> {
- match ty.kind() {
- // References are simple.
- ty::Ref(_, _, Mutability::Mut) =>
- Some((
- RefKind::Unique { two_phase: kind == RetagKind::TwoPhase },
- kind == RetagKind::FnEntry,
- )),
- ty::Ref(_, _, Mutability::Not) =>
- Some((RefKind::Shared, kind == RetagKind::FnEntry)),
- // Raw pointers need to be enabled.
- ty::RawPtr(tym) if kind == RetagKind::Raw =>
- Some((RefKind::Raw { mutable: tym.mutbl == Mutability::Mut }, false)),
- // Boxes are handled separately due to that allocator situation,
- // see the visitor below.
- _ => None,
- }
- }
-
// The actual visitor.
struct RetagVisitor<'ecx, 'mir, 'tcx> {
ecx: &'ecx mut MiriInterpCx<'mir, 'tcx>,
return Ok(());
}
- let recurse_for_fields = || {
- match self.retag_fields {
- RetagFields::No => false,
- RetagFields::Yes => true,
- RetagFields::OnlyScalar => {
- // Matching `ArgAbi::new` at the time of writing, only fields of
- // `Scalar` and `ScalarPair` ABI are considered.
- matches!(place.layout.abi, Abi::Scalar(..) | Abi::ScalarPair(..))
+ // Check the type of this value to see what to do with it (retag, or recurse).
+ match place.layout.ty.kind() {
+ ty::Ref(_, _, mutbl) => {
+ let ref_kind = match mutbl {
+ Mutability::Mut =>
+ RefKind::Unique { two_phase: self.kind == RetagKind::TwoPhase },
+ Mutability::Not => RefKind::Shared,
+ };
+ self.retag_place(
+ place,
+ ref_kind,
+ self.retag_cause,
+ /*protector*/ self.kind == RetagKind::FnEntry,
+ )?;
+ }
+ ty::RawPtr(tym) => {
+ // We definitely do *not* want to recurse into raw pointers -- wide raw
+ // pointers have fields, and for dyn Trait pointees those can have reference
+ // type!
+ if self.kind == RetagKind::Raw {
+ // Raw pointers need to be enabled.
+ self.retag_place(
+ place,
+ RefKind::Raw { mutable: tym.mutbl == Mutability::Mut },
+ self.retag_cause,
+ /*protector*/ false,
+ )?;
+ }
+ }
+ _ if place.layout.ty.ty_adt_def().is_some_and(|adt| adt.is_box()) => {
+ // Recurse for boxes, they require some tricky handling and will end up in `visit_box` above.
+ // (Yes this means we technically also recursively retag the allocator itself
+ // even if field retagging is not enabled. *shrug*)
+ self.walk_value(place)?;
+ }
+ _ => {
+ // Not a reference/pointer/box. Only recurse if configured appropriately.
+ let recurse = match self.retag_fields {
+ RetagFields::No => false,
+ RetagFields::Yes => true,
+ RetagFields::OnlyScalar => {
+ // Matching `ArgAbi::new` at the time of writing, only fields of
+ // `Scalar` and `ScalarPair` ABI are considered.
+ matches!(place.layout.abi, Abi::Scalar(..) | Abi::ScalarPair(..))
+ }
+ };
+ if recurse {
+ self.walk_value(place)?;
}
}
- };
-
- if let Some((ref_kind, protector)) = qualify(place.layout.ty, self.kind) {
- self.retag_place(place, ref_kind, self.retag_cause, protector)?;
- } else if matches!(place.layout.ty.kind(), ty::RawPtr(..)) {
- // Wide raw pointers *do* have fields and their types are strange.
- // vtables have a type like `&[*const (); 3]` or so!
- // Do *not* recurse into them.
- // (No need to worry about wide references, those always "qualify". And Boxes
- // are handles specially by the visitor anyway.)
- } else if recurse_for_fields()
- || place.layout.ty.ty_adt_def().is_some_and(|adt| adt.is_box())
- {
- // Recurse deeper. Need to always recurse for `Box` to even hit `visit_box`.
- // (Yes this means we technically also recursively retag the allocator itself
- // even if field retagging is not enabled. *shrug*)
- self.walk_value(place)?;
}
+
Ok(())
}
}
test("`cargo miri test`",
cargo_miri("test"),
default_ref, "test.stderr-empty.ref",
- env={'MIRIFLAGS': "-Zmiri-permissive-provenance -Zmiri-seed=feed"},
+ env={'MIRIFLAGS': "-Zmiri-permissive-provenance -Zmiri-seed=4242"},
)
test("`cargo miri test` (no isolation, no doctests)",
cargo_miri("test") + ["--bins", "--tests"], # no `--lib`, we disabled that in `Cargo.toml`
}
/// Tests whether clock support exists at all
-#[cfg(target_os = "linux")]
fn test_clocks() {
let mut tp = std::mem::MaybeUninit::<libc::timespec>::uninit();
let is_error = unsafe { libc::clock_gettime(libc::CLOCK_REALTIME, tp.as_mut_ptr()) };
assert_eq!(is_error, 0);
- let is_error = unsafe { libc::clock_gettime(libc::CLOCK_REALTIME_COARSE, tp.as_mut_ptr()) };
- assert_eq!(is_error, 0);
let is_error = unsafe { libc::clock_gettime(libc::CLOCK_MONOTONIC, tp.as_mut_ptr()) };
assert_eq!(is_error, 0);
- let is_error = unsafe { libc::clock_gettime(libc::CLOCK_MONOTONIC_COARSE, tp.as_mut_ptr()) };
- assert_eq!(is_error, 0);
+ #[cfg(target_os = "linux")]
+ {
+ let is_error = unsafe { libc::clock_gettime(libc::CLOCK_REALTIME_COARSE, tp.as_mut_ptr()) };
+ assert_eq!(is_error, 0);
+ let is_error =
+ unsafe { libc::clock_gettime(libc::CLOCK_MONOTONIC_COARSE, tp.as_mut_ptr()) };
+ assert_eq!(is_error, 0);
+ }
+ #[cfg(all(target_os = "macos", target_arch = "aarch64"))]
+ {
+ let is_error = unsafe { libc::clock_gettime(libc::CLOCK_UPTIME_RAW, tp.as_mut_ptr()) };
+ assert_eq!(is_error, 0);
+ }
}
fn test_posix_gettimeofday() {
test_thread_local_errno();
test_isatty();
+ test_clocks();
#[cfg(target_os = "linux")]
{
test_posix_fadvise();
test_sync_file_range();
- test_clocks();
}
}
//@compile-flags: -Zmiri-symbolic-alignment-check
+#![feature(strict_provenance)]
+
+use std::ptr;
fn test_align_offset() {
let d = Box::new([0u32; 4]);
assert_eq!(raw.wrapping_offset(2).align_offset(2), 0);
assert_eq!(raw.wrapping_offset(2).align_offset(4), 2);
assert_eq!(raw.wrapping_offset(2).align_offset(8), usize::MAX); // requested alignment higher than allocation alignment
+
+ let p = ptr::invalid::<()>(1);
+ assert_eq!(p.align_offset(1), 0);
}
fn test_align_to() {
+++ /dev/null
-#![feature(type_alias_impl_trait)]
-
-trait T {
- type Item;
-}
-
-type Alias<'a> = impl T<Item = &'a ()>;
-
-struct S;
-impl<'a> T for &'a S {
- type Item = &'a ();
-}
-
-fn filter_positive<'a>() -> Alias<'a> {
- &S
-}
-
-fn with_positive(fun: impl Fn(Alias<'_>)) {
- fun(filter_positive());
-}
-
-fn main() {
- with_positive(|_| ());
-}
});
test(Some("align_offset: align is not a power-of-two"), |_old_val| {
- (0usize as *const u8).align_offset(3);
+ let _ = (0usize as *const u8).align_offset(3);
loop {}
});
let test_file_contents = fs::read_to_string(&testfile).unwrap();
let test_dir = testfile.parent().unwrap();
- let test_crate = testfile.file_stem().unwrap().to_str().unwrap().replace("-", "_");
+ let test_crate = testfile.file_stem().unwrap().to_str().unwrap().replace('-', "_");
let bit_width = if test_file_contents.lines().any(|l| l == "// EMIT_MIR_FOR_EACH_BIT_WIDTH") {
format!(".{}bit", bit_width)
fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
Some(match self.kind {
ast::MetaItemKind::Word => {
- rewrite_path(context, PathContext::Type, None, &self.path, shape)?
+ rewrite_path(context, PathContext::Type, &None, &self.path, shape)?
}
ast::MetaItemKind::List(ref list) => {
- let path = rewrite_path(context, PathContext::Type, None, &self.path, shape)?;
+ let path = rewrite_path(context, PathContext::Type, &None, &self.path, shape)?;
let has_trailing_comma = crate::expr::span_ends_with_comma(context, self.span);
overflow::rewrite_with_parens(
context,
)?
}
ast::MetaItemKind::NameValue(ref literal) => {
- let path = rewrite_path(context, PathContext::Type, None, &self.path, shape)?;
+ let path = rewrite_path(context, PathContext::Type, &None, &self.path, shape)?;
// 3 = ` = `
let lit_shape = shape.shrink_left(path.len() + 3)?;
// `rewrite_literal` returns `None` when `literal` exceeds max
fn from_ast(context: &RewriteContext<'_>, expr: &ast::Expr) -> (ChainItemKind, Span) {
let (kind, span) = match expr.kind {
- ast::ExprKind::MethodCall(ref segment, ref receiver, ref expressions, _) => {
- let types = if let Some(ref generic_args) = segment.args {
+ ast::ExprKind::MethodCall(ref call) => {
+ let types = if let Some(ref generic_args) = call.seg.args {
if let ast::GenericArgs::AngleBracketed(ref data) = **generic_args {
data.args
.iter()
} else {
vec![]
};
- let span = mk_sp(receiver.span.hi(), expr.span.hi());
- let kind = ChainItemKind::MethodCall(segment.clone(), types, expressions.clone());
+ let span = mk_sp(call.receiver.span.hi(), expr.span.hi());
+ let kind = ChainItemKind::MethodCall(call.seg.clone(), types, call.args.clone());
(kind, span)
}
ast::ExprKind::Field(ref nested, field) => {
// is a try! macro, we'll convert it to shorthand when the option is set.
fn pop_expr_chain(expr: &ast::Expr, context: &RewriteContext<'_>) -> Option<ast::Expr> {
match expr.kind {
- ast::ExprKind::MethodCall(_, ref receiver, _, _) => {
- Some(Self::convert_try(&receiver, context))
- }
+ ast::ExprKind::MethodCall(ref call) => Some(Self::convert_try(&call.receiver, context)),
ast::ExprKind::Field(ref subexpr, _)
| ast::ExprKind::Try(ref subexpr)
| ast::ExprKind::Await(ref subexpr) => Some(Self::convert_try(subexpr, context)),
expr: &ast::Expr,
shape: Shape,
) -> Option<String> {
- if let ast::ExprKind::Closure(
- ref binder,
- capture,
- ref is_async,
- movability,
- ref fn_decl,
- ref body,
- _,
- ) = expr.kind
- {
+ if let ast::ExprKind::Closure(ref closure) = expr.kind {
+ let ast::Closure {
+ ref binder,
+ capture_clause,
+ ref asyncness,
+ movability,
+ ref fn_decl,
+ ref body,
+ fn_decl_span: _,
+ } = **closure;
let body = match body.kind {
ast::ExprKind::Block(ref block, _)
if !is_unsafe_block(block)
_ => body,
};
let (prefix, extra_offset) = rewrite_closure_fn_decl(
- binder, capture, is_async, movability, fn_decl, body, expr.span, context, shape,
+ binder,
+ capture_clause,
+ asyncness,
+ movability,
+ fn_decl,
+ body,
+ expr.span,
+ context,
+ shape,
)?;
// If the closure goes multi line before its body, do not overflow the closure.
if prefix.contains('\n') {
rewrite_struct_lit(
context,
path,
- qself.as_ref(),
+ qself,
fields,
rest,
&expr.attrs,
rewrite_match(context, cond, arms, shape, expr.span, &expr.attrs)
}
ast::ExprKind::Path(ref qself, ref path) => {
- rewrite_path(context, PathContext::Expr, qself.as_ref(), path, shape)
+ rewrite_path(context, PathContext::Expr, qself, path, shape)
}
ast::ExprKind::Assign(ref lhs, ref rhs, _) => {
rewrite_assignment(context, lhs, rhs, None, shape)
Some("yield".to_string())
}
}
- ast::ExprKind::Closure(
- ref binder,
- capture,
- ref is_async,
- movability,
- ref fn_decl,
- ref body,
- _,
- ) => closures::rewrite_closure(
- binder, capture, is_async, movability, fn_decl, body, expr.span, context, shape,
+ ast::ExprKind::Closure(ref cl) => closures::rewrite_closure(
+ &cl.binder,
+ cl.capture_clause,
+ &cl.asyncness,
+ cl.movability,
+ &cl.fn_decl,
+ &cl.body,
+ expr.span,
+ context,
+ shape,
),
ast::ExprKind::Try(..)
| ast::ExprKind::Field(..)
fn rewrite_struct_lit<'a>(
context: &RewriteContext<'_>,
path: &ast::Path,
- qself: Option<&ast::QSelf>,
+ qself: &Option<ptr::P<ast::QSelf>>,
fields: &'a [ast::ExprField],
struct_rest: &ast::StructRest,
attrs: &[ast::Attribute],
}
PatKind::Tuple(ref items) => rewrite_tuple_pat(items, None, self.span, context, shape),
PatKind::Path(ref q_self, ref path) => {
- rewrite_path(context, PathContext::Expr, q_self.as_ref(), path, shape)
+ rewrite_path(context, PathContext::Expr, q_self, path, shape)
}
PatKind::TupleStruct(ref q_self, ref path, ref pat_vec) => {
- let path_str =
- rewrite_path(context, PathContext::Expr, q_self.as_ref(), path, shape)?;
+ let path_str = rewrite_path(context, PathContext::Expr, q_self, path, shape)?;
rewrite_tuple_pat(pat_vec, Some(path_str), self.span, context, shape)
}
PatKind::Lit(ref expr) => expr.rewrite(context, shape),
}
fn rewrite_struct_pat(
- qself: &Option<ast::QSelf>,
+ qself: &Option<ptr::P<ast::QSelf>>,
path: &ast::Path,
fields: &[ast::PatField],
ellipsis: bool,
) -> Option<String> {
// 2 = ` {`
let path_shape = shape.sub_width(2)?;
- let path_str = rewrite_path(context, PathContext::Expr, qself.as_ref(), path, path_shape)?;
+ let path_str = rewrite_path(context, PathContext::Expr, qself, path, path_shape)?;
if fields.is_empty() && !ellipsis {
return Some(format!("{} {{}}", path_str));
pub(crate) fn rewrite_path(
context: &RewriteContext<'_>,
path_context: PathContext,
- qself: Option<&ast::QSelf>,
+ qself: &Option<ptr::P<ast::QSelf>>,
path: &ast::Path,
shape: Shape,
) -> Option<String> {
- let skip_count = qself.map_or(0, |x| x.position);
+ let skip_count = qself.as_ref().map_or(0, |x| x.position);
let mut result = if path.is_global() && qself.is_none() && path_context != PathContext::Import {
"::".to_owned()
impl Rewrite for ast::TraitRef {
fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
- rewrite_path(context, PathContext::Type, None, &self.path, shape)
+ rewrite_path(context, PathContext::Type, &None, &self.path, shape)
}
}
rewrite_tuple(context, items.iter(), self.span, shape, items.len() == 1)
}
ast::TyKind::Path(ref q_self, ref path) => {
- rewrite_path(context, PathContext::Type, q_self.as_ref(), path, shape)
+ rewrite_path(context, PathContext::Type, q_self, path, shape)
}
ast::TyKind::Array(ref ty, ref repeats) => rewrite_pair(
&**ty,
| ast::ExprKind::Binary(_, _, ref expr)
| ast::ExprKind::Index(_, ref expr)
| ast::ExprKind::Unary(_, ref expr)
- | ast::ExprKind::Closure(_, _, _, _, _, ref expr, _)
| ast::ExprKind::Try(ref expr)
| ast::ExprKind::Yield(Some(ref expr)) => is_block_expr(context, expr, repr),
+ ast::ExprKind::Closure(ref closure) => is_block_expr(context, &closure.body, repr),
// This can only be a string lit
ast::ExprKind::Lit(_) => {
repr.contains('\n') && trimmed_last_line_width(repr) <= context.config.tab_spaces()
"hashbrown",
"hermit-abi",
"humantime",
+ "icu_list",
+ "icu_locid",
+ "icu_provider",
+ "icu_provider_adapters",
+ "icu_provider_macros",
"if_chain",
"indexmap",
"instant",
"libc",
"libloading",
"libz-sys",
+ "litemap",
"lock_api",
"log",
"matchers",
"winapi-i686-pc-windows-gnu",
"winapi-util",
"winapi-x86_64-pc-windows-gnu",
+ "writeable",
// this is a false-positive: it's only used by rustfmt, but because it's enabled through a
// feature, tidy thinks it's used by rustc as well.
"yansi-term",
+ "yoke",
+ "yoke-derive",
+ "zerofrom",
+ "zerofrom-derive",
+ "zerovec",
+ "zerovec-derive",
];
const PERMITTED_CRANELIFT_DEPENDENCIES: &[&str] = &[