"cargo-util",
"clap",
"crates-io",
- "crossbeam-utils",
"curl",
"curl-sys",
"env_logger 0.9.0",
"libgit2-sys",
"log",
"memchr",
- "num_cpus",
"opener",
"openssl",
"os_info",
[[package]]
name = "compiler_builtins"
-version = "0.1.78"
+version = "0.1.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "413b6b13f725a46cdec40364e0c1d564a22cf0aaac5f1e267a129d956478a6b4"
+checksum = "4f873ce2bd3550b0b565f878b3d04ea8253f4259dc3d20223af2e1ba86f5ecca"
dependencies = [
"cc",
"rustc-std-workspace-core",
- [Extend `ptr::null` and `null_mut` to all thin (including extern) types.][94954]
- [`impl Read and Write for VecDeque<u8>`.][95632]
- [STD support for the Nintendo 3DS.][95897]
+- [Use rounding in float to Duration conversion methods.][96051]
- [Make write/print macros eagerly drop temporaries.][96455]
- [Implement internal traits that enable `[OsStr]::join`.][96881]
- [Implement `Hash` for `core::alloc::Layout`.][97034]
- [`#[link]` attributes are now checked more strictly,][96885] which may introduce
errors for invalid attribute arguments that were previously ignored.
+- [Rounding is now used when converting a float to a `Duration`.][96051] The converted
+ duration can differ slightly from what it was.
Internal Changes
----------------
[95818]: https://github.com/rust-lang/rust/pull/95818/
[95897]: https://github.com/rust-lang/rust/pull/95897/
[95953]: https://github.com/rust-lang/rust/pull/95953/
+[96051]: https://github.com/rust-lang/rust/pull/96051/
[96296]: https://github.com/rust-lang/rust/pull/96296/
[96455]: https://github.com/rust-lang/rust/pull/96455/
[96737]: https://github.com/rust-lang/rust/pull/96737/
#![feature(const_trait_impl)]
#![feature(if_let_guard)]
#![feature(label_break_value)]
-#![cfg_attr(bootstrap, feature(let_chains))]
#![feature(min_specialization)]
#![feature(negative_impls)]
#![feature(slice_internals)]
}
fn lower_expr_field(&mut self, f: &ExprField) -> hir::ExprField<'hir> {
+ let hir_id = self.lower_node_id(f.id);
+ self.lower_attrs(hir_id, &f.attrs);
hir::ExprField {
- hir_id: self.next_id(),
+ hir_id,
ident: self.lower_ident(f.ident),
expr: self.lower_expr(&f.expr),
span: self.lower_span(f.span),
});
}
+ fn visit_pat_field(&mut self, field: &'hir PatField<'hir>) {
+ self.insert(field.span, field.hir_id, Node::PatField(field));
+ self.with_parent(field.hir_id, |this| {
+ intravisit::walk_pat_field(this, field);
+ });
+ }
+
fn visit_arm(&mut self, arm: &'hir Arm<'hir>) {
let node = Node::Arm(arm);
});
}
+ fn visit_expr_field(&mut self, field: &'hir ExprField<'hir>) {
+ self.insert(field.span, field.hir_id, Node::ExprField(field));
+ self.with_parent(field.hir_id, |this| {
+ intravisit::walk_expr_field(this, field);
+ });
+ }
+
fn visit_stmt(&mut self, stmt: &'hir Stmt<'hir>) {
self.insert(stmt.span, stmt.hir_id, Node::Stmt(stmt));
//! in the HIR, especially for multiple identifiers.
#![feature(box_patterns)]
-#![cfg_attr(bootstrap, feature(let_chains))]
#![feature(let_else)]
#![feature(never_type)]
#![recursion_limit = "256"]
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
);
- let fs = self.arena.alloc_from_iter(fields.iter().map(|f| hir::PatField {
- hir_id: self.next_id(),
- ident: self.lower_ident(f.ident),
- pat: self.lower_pat(&f.pat),
- is_shorthand: f.is_shorthand,
- span: self.lower_span(f.span),
+ let fs = self.arena.alloc_from_iter(fields.iter().map(|f| {
+ let hir_id = self.lower_node_id(f.id);
+ self.lower_attrs(hir_id, &f.attrs);
+
+ hir::PatField {
+ hir_id,
+ ident: self.lower_ident(f.ident),
+ pat: self.lower_pat(&f.pat),
+ is_shorthand: f.is_shorthand,
+ span: self.lower_span(f.span),
+ }
}));
break hir::PatKind::Struct(qpath, fs, etc);
}
#![feature(box_patterns)]
#![feature(if_let_guard)]
#![feature(iter_is_partitioned)]
-#![cfg_attr(bootstrap, feature(let_chains))]
#![feature(let_else)]
#![recursion_limit = "256"]
//! The goal is to move the definition of `MetaItem` and things that don't need to be in `syntax`
//! to this crate.
-#![cfg_attr(bootstrap, feature(let_chains))]
#![feature(let_else)]
#[macro_use]
};
nice_error.try_report_from_nll().or_else(|| {
if let SubregionOrigin::Subtype(trace) = cause {
- Some(
- infcx.report_and_explain_type_error(*trace, &TypeError::RegionsPlaceholderMismatch),
- )
+ Some(infcx.report_and_explain_type_error(*trace, TypeError::RegionsPlaceholderMismatch))
} else {
None
}
#![allow(rustc::potential_query_instability)]
#![feature(box_patterns)]
-#![cfg_attr(bootstrap, feature(let_chains))]
#![feature(let_else)]
#![feature(min_specialization)]
#![feature(never_type)]
/// CountIsParam, which contains an index into the arguments.
fn maybe_add_positional_named_arg(
&mut self,
- current_positional_arg: usize,
- total_args_length: usize,
- format_argument_index: usize,
+ arg: Option<&FormatArg>,
ty: PositionalNamedArgType,
cur_piece: usize,
inner_span_to_replace: Option<rustc_parse_format::InnerSpan>,
- names: &FxHashMap<Symbol, (usize, Span)>,
has_formatting: bool,
) {
- let start_of_named_args = total_args_length - names.len();
- if current_positional_arg >= start_of_named_args {
- self.maybe_push(
- format_argument_index,
- ty,
- cur_piece,
- inner_span_to_replace,
- names,
- has_formatting,
- )
+ if let Some(arg) = arg {
+ if let Some(name) = arg.name {
+ self.push(name, ty, cur_piece, inner_span_to_replace, has_formatting)
+ }
}
}
- /// Try constructing a PositionalNamedArg struct and pushing it into the vec of positional
- /// named arguments. If a named arg associated with `format_argument_index` cannot be found,
- /// a new item will not be added as the lint cannot be emitted in this case.
- fn maybe_push(
+ /// Construct a PositionalNamedArg struct and push it into the vec of positional
+ /// named arguments.
+ fn push(
&mut self,
- format_argument_index: usize,
+ arg_name: Ident,
ty: PositionalNamedArgType,
cur_piece: usize,
inner_span_to_replace: Option<rustc_parse_format::InnerSpan>,
- names: &FxHashMap<Symbol, (usize, Span)>,
has_formatting: bool,
) {
- let named_arg = names
- .iter()
- .find(|&(_, &(index, _))| index == format_argument_index)
- .map(|found| found.clone());
-
- if let Some((&replacement, &(_, positional_named_arg_span))) = named_arg {
- // In FormatSpec, `precision_span` starts at the leading `.`, which we want to keep in
- // the lint suggestion, so increment `start` by 1 when `PositionalArgumentType` is
- // `Precision`.
- let inner_span_to_replace = if ty == PositionalNamedArgType::Precision {
- inner_span_to_replace
- .map(|is| rustc_parse_format::InnerSpan { start: is.start + 1, end: is.end })
- } else {
- inner_span_to_replace
- };
- self.positional_named_args.push(PositionalNamedArg {
- ty,
- cur_piece,
- inner_span_to_replace,
- replacement,
- positional_named_arg_span,
- has_formatting,
- });
- }
+ // In FormatSpec, `precision_span` starts at the leading `.`, which we want to keep in
+ // the lint suggestion, so increment `start` by 1 when `PositionalArgumentType` is
+ // `Precision`.
+ let inner_span_to_replace = if ty == PositionalNamedArgType::Precision {
+ inner_span_to_replace
+ .map(|is| rustc_parse_format::InnerSpan { start: is.start + 1, end: is.end })
+ } else {
+ inner_span_to_replace
+ };
+ self.positional_named_args.push(PositionalNamedArg {
+ ty,
+ cur_piece,
+ inner_span_to_replace,
+ replacement: arg_name.name,
+ positional_named_arg_span: arg_name.span,
+ has_formatting,
+ });
}
}
/// * `arg_types` (in JSON): `[[0, 1, 0], [0, 1, 1], [0, 1]]`
/// * `arg_unique_types` (in simplified JSON): `[["o", "x"], ["o", "x"], ["o", "x"]]`
/// * `names` (in JSON): `{"foo": 2}`
- args: Vec<P<ast::Expr>>,
+ args: Vec<FormatArg>,
/// The number of arguments that were added by implicit capturing.
num_captured_args: usize,
/// Placeholder slot numbers indexed by argument.
/// Unique format specs seen for each argument.
arg_unique_types: Vec<Vec<ArgumentType>>,
/// Map from named arguments to their resolved indices.
- names: FxHashMap<Symbol, (usize, Span)>,
+ names: FxHashMap<Symbol, usize>,
/// The latest consecutive literal strings, or empty if there weren't any.
literal: String,
pub struct FormatArg {
expr: P<ast::Expr>,
- named: bool,
+ name: Option<Ident>,
}
/// Parses the arguments from the given list of tokens, returning the diagnostic
ecx: &mut ExtCtxt<'a>,
sp: Span,
tts: TokenStream,
-) -> PResult<'a, (P<ast::Expr>, Vec<FormatArg>, FxHashMap<Symbol, (usize, Span)>)> {
+) -> PResult<'a, (P<ast::Expr>, Vec<FormatArg>, FxHashMap<Symbol, usize>)> {
let mut args = Vec::<FormatArg>::new();
- let mut names = FxHashMap::<Symbol, (usize, Span)>::default();
+ let mut names = FxHashMap::<Symbol, usize>::default();
let mut p = ecx.new_parser_from_tts(tts);
p.bump();
p.expect(&token::Eq)?;
let e = p.parse_expr()?;
- if let Some((prev, _)) = names.get(&ident.name) {
+ if let Some(&prev) = names.get(&ident.name) {
ecx.struct_span_err(e.span, &format!("duplicate argument named `{}`", ident))
- .span_label(args[*prev].expr.span, "previously here")
+ .span_label(args[prev].expr.span, "previously here")
.span_label(e.span, "duplicate argument")
.emit();
continue;
// if the input is valid, we can simply append to the positional
// args. And remember the names.
let slot = args.len();
- names.insert(ident.name, (slot, ident.span));
- args.push(FormatArg { expr: e, named: true });
+ names.insert(ident.name, slot);
+ args.push(FormatArg { expr: e, name: Some(ident) });
}
_ => {
let e = p.parse_expr()?;
"positional arguments cannot follow named arguments",
);
err.span_label(e.span, "positional arguments must be before named arguments");
- for pos in names.values() {
- err.span_label(args[pos.0].expr.span, "named argument");
+ for &pos in names.values() {
+ err.span_label(args[pos].expr.span, "named argument");
}
err.emit();
}
- args.push(FormatArg { expr: e, named: false });
+ args.push(FormatArg { expr: e, name: None });
}
}
}
fn resolve_name_inplace(&mut self, p: &mut parse::Piece<'_>) {
// NOTE: the `unwrap_or` branch is needed in case of invalid format
// arguments, e.g., `format_args!("{foo}")`.
- let lookup =
- |s: &str| self.names.get(&Symbol::intern(s)).unwrap_or(&(0, Span::default())).0;
+ let lookup = |s: &str| self.names.get(&Symbol::intern(s)).copied().unwrap_or(0);
match *p {
parse::String(_) => {}
let pos = match arg.position {
parse::ArgumentIs(i) => {
self.unused_names_lint.maybe_add_positional_named_arg(
- i,
- self.args.len(),
- i,
+ self.args.get(i),
PositionalNamedArgType::Arg,
self.curpiece,
Some(arg.position_span),
- &self.names,
has_precision || has_width,
);
}
parse::ArgumentImplicitlyIs(i) => {
self.unused_names_lint.maybe_add_positional_named_arg(
- i,
- self.args.len(),
- i,
+ self.args.get(i),
PositionalNamedArgType::Arg,
self.curpiece,
None,
- &self.names,
has_precision || has_width,
);
Exact(i)
parse::CountImplied | parse::CountIs(..) => {}
parse::CountIsParam(i) => {
self.unused_names_lint.maybe_add_positional_named_arg(
- i,
- self.args.len(),
- i,
+ self.args.get(i),
named_arg_type,
self.curpiece,
*inner_span,
- &self.names,
true,
);
self.verify_arg_type(Exact(i), Count);
);
for arg in &self.args {
// Point at the arguments that will be formatted.
- e.span_label(arg.span, "");
+ e.span_label(arg.expr.span, "");
}
} else {
let (mut refs, spans): (Vec<_>, Vec<_>) = refs.unzip();
);
if let Some(arg) = self.args.get(pos) {
e.span_label(
- arg.span,
+ arg.expr.span,
"this parameter corresponds to the precision flag",
);
}
match self.names.get(&name) {
Some(&idx) => {
// Treat as positional arg.
- self.verify_arg_type(Capture(idx.0), ty)
+ self.verify_arg_type(Capture(idx), ty)
}
None => {
// For the moment capturing variables from format strings expanded from macros is
self.fmtsp
};
self.num_captured_args += 1;
- self.args.push(self.ecx.expr_ident(span, Ident::new(name, span)));
- self.names.insert(name, (idx, span));
+ self.args.push(FormatArg {
+ expr: self.ecx.expr_ident(span, Ident::new(name, span)),
+ name: Some(Ident::new(name, span)),
+ });
+ self.names.insert(name, idx);
self.verify_arg_type(Capture(idx), ty)
} else {
let msg = format!("there is no argument named `{}`", name);
// evaluated a single time each, in the order written by the programmer,
// and that the surrounding future/generator (if any) is Send whenever
// possible.
- let no_need_for_match =
- nicely_ordered && !original_args.iter().skip(1).any(|e| may_contain_yield_point(e));
+ let no_need_for_match = nicely_ordered
+ && !original_args.iter().skip(1).any(|arg| may_contain_yield_point(&arg.expr));
for (arg_index, arg_ty) in fmt_arg_index_and_ty {
- let e = &mut original_args[arg_index];
+ let e = &mut original_args[arg_index].expr;
let span = e.span;
let arg = if no_need_for_match {
let expansion_span = e.span.with_ctxt(self.macsp.ctxt());
// span is otherwise unavailable in the MIR used by borrowck).
let heads = original_args
.into_iter()
- .map(|e| self.ecx.expr_addr_of(e.span.with_ctxt(self.macsp.ctxt()), e))
+ .map(|arg| {
+ self.ecx.expr_addr_of(arg.expr.span.with_ctxt(self.macsp.ctxt()), arg.expr)
+ })
.collect();
let pat = self.ecx.pat_ident(self.macsp, Ident::new(sym::args, self.macsp));
sp: Span,
efmt: P<ast::Expr>,
args: Vec<FormatArg>,
- names: FxHashMap<Symbol, (usize, Span)>,
+ names: FxHashMap<Symbol, usize>,
append_newline: bool,
) -> P<ast::Expr> {
// NOTE: this verbose way of initializing `Vec<Vec<ArgumentType>>` is because
if err.should_be_replaced_with_positional_argument {
let captured_arg_span =
fmt_span.from_inner(InnerSpan::new(err.span.start, err.span.end));
- let positional_args = args.iter().filter(|arg| !arg.named).collect::<Vec<_>>();
+ let n_positional_args =
+ args.iter().rposition(|arg| arg.name.is_none()).map_or(0, |i| i + 1);
if let Ok(arg) = ecx.source_map().span_to_snippet(captured_arg_span) {
- let span = match positional_args.last() {
+ let span = match args[..n_positional_args].last() {
Some(arg) => arg.expr.span,
None => fmt_sp,
};
e.multipart_suggestion_verbose(
"consider using a positional formatting argument instead",
vec![
- (captured_arg_span, positional_args.len().to_string()),
+ (captured_arg_span, n_positional_args.to_string()),
(span.shrink_to_hi(), format!(", {}", arg)),
],
Applicability::MachineApplicable,
.map(|span| fmt_span.from_inner(InnerSpan::new(span.start, span.end)))
.collect();
- let named_pos: FxHashSet<usize> = names.values().cloned().map(|(i, _)| i).collect();
-
let mut cx = Context {
ecx,
- args: args.into_iter().map(|arg| arg.expr).collect(),
+ args,
num_captured_args: 0,
arg_types,
arg_unique_types,
.enumerate()
.filter(|(i, ty)| ty.is_empty() && !cx.count_positions.contains_key(&i))
.map(|(i, _)| {
- let msg = if named_pos.contains(&i) {
- // named argument
+ let msg = if cx.args[i].name.is_some() {
"named argument never used"
} else {
- // positional argument
"argument never used"
};
- (cx.args[i].span, msg)
+ (cx.args[i].expr.span, msg)
})
.collect::<Vec<_>>();
#![feature(decl_macro)]
#![feature(if_let_guard)]
#![feature(is_sorted)]
-#![cfg_attr(bootstrap, feature(let_chains))]
#![feature(let_else)]
#![feature(proc_macro_internals)]
#![feature(proc_macro_quote)]
}
/// Extract size and alignment from a TyAndLayout.
+#[inline]
fn size_and_align_of<'tcx>(ty_and_layout: TyAndLayout<'tcx>) -> (Size, Align) {
(ty_and_layout.size, ty_and_layout.align.abi)
}
use std::borrow::Cow;
use libc::c_uint;
-use rustc_codegen_ssa::debuginfo::{
- type_names::compute_debuginfo_type_name, wants_c_like_enum_debuginfo,
+use rustc_codegen_ssa::{
+ debuginfo::{type_names::compute_debuginfo_type_name, wants_c_like_enum_debuginfo},
+ traits::ConstMethods,
};
+
+use rustc_index::vec::IndexVec;
use rustc_middle::{
bug,
ty::{
self,
layout::{LayoutOf, TyAndLayout},
- util::Discr,
- AdtDef, GeneratorSubsts,
+ AdtDef, GeneratorSubsts, Ty,
},
};
-use rustc_target::abi::{Size, TagEncoding, VariantIdx, Variants};
+use rustc_target::abi::{Align, Endian, Size, TagEncoding, VariantIdx, Variants};
use smallvec::smallvec;
use crate::{
debuginfo::{
metadata::{
build_field_di_node, closure_saved_names_of_captured_variables,
- enums::tag_base_type,
- file_metadata, generator_layout_and_saved_local_names, size_and_align_of,
- type_map::{self, UniqueTypeId},
+ enums::{tag_base_type, DiscrResult},
+ file_metadata, generator_layout_and_saved_local_names, size_and_align_of, type_di_node,
+ type_map::{self, Stub, UniqueTypeId},
unknown_file_metadata, DINodeCreationResult, SmallVec, NO_GENERICS, NO_SCOPE_METADATA,
UNKNOWN_LINE_NUMBER,
},
},
};
-/// In CPP-like mode, we generate a union of structs for each variant and an
-/// explicit discriminant field roughly equivalent to the following C/C++ code:
+// The names of the associated constants in each variant wrapper struct.
+// These have to match up with the names being used in `intrinsic.natvis`.
+const ASSOC_CONST_DISCR_NAME: &str = "NAME";
+const ASSOC_CONST_DISCR_EXACT: &str = "DISCR_EXACT";
+const ASSOC_CONST_DISCR_BEGIN: &str = "DISCR_BEGIN";
+const ASSOC_CONST_DISCR_END: &str = "DISCR_END";
+
+const ASSOC_CONST_DISCR128_EXACT_LO: &str = "DISCR128_EXACT_LO";
+const ASSOC_CONST_DISCR128_EXACT_HI: &str = "DISCR128_EXACT_HI";
+const ASSOC_CONST_DISCR128_BEGIN_LO: &str = "DISCR128_BEGIN_LO";
+const ASSOC_CONST_DISCR128_BEGIN_HI: &str = "DISCR128_BEGIN_HI";
+const ASSOC_CONST_DISCR128_END_LO: &str = "DISCR128_END_LO";
+const ASSOC_CONST_DISCR128_END_HI: &str = "DISCR128_END_HI";
+
+// The name of the tag field in the top-level union
+const TAG_FIELD_NAME: &str = "tag";
+const TAG_FIELD_NAME_128_LO: &str = "tag128_lo";
+const TAG_FIELD_NAME_128_HI: &str = "tag128_hi";
+
+// We assign a "virtual" discriminant value to the sole variant of
+// a single-variant enum.
+const SINGLE_VARIANT_VIRTUAL_DISR: u64 = 0;
+
+/// In CPP-like mode, we generate a union with a field for each variant and an
+/// explicit tag field. The field of each variant has a struct type
+/// that encodes the discrimiant of the variant and it's data layout.
+/// The union also has a nested enumeration type that is only used for encoding
+/// variant names in an efficient way. Its enumerator values do _not_ correspond
+/// to the enum's discriminant values.
+/// It's roughly equivalent to the following C/C++ code:
///
/// ```c
-/// union enum$<{fully-qualified-name}> {
-/// struct {variant 0 name} {
-/// <variant 0 fields>
+/// union enum2$<{fully-qualified-name}> {
+/// struct Variant0 {
+/// struct {name-of-variant-0} {
+/// <variant 0 fields>
+/// } value;
+///
+/// static VariantNames NAME = {name-of-variant-0};
+/// static int_type DISCR_EXACT = {discriminant-of-variant-0};
/// } variant0;
+///
/// <other variant structs>
-/// {name} discriminant;
+///
+/// int_type tag;
+///
+/// enum VariantNames {
+/// <name-of-variant-0> = 0, // The numeric values are variant index,
+/// <name-of-variant-1> = 1, // not discriminant values.
+/// <name-of-variant-2> = 2,
+/// ...
+/// }
/// }
/// ```
///
-/// As you can see, the type name is wrapped `enum$`. This way we can have a
-/// single NatVis rule for handling all enums.
+/// As you can see, the type name is wrapped in `enum2$<_>`. This way we can
+/// have a single NatVis rule for handling all enums. The `2` in `enum2$<_>`
+/// is an encoding version tag, so that debuggers can decide to decode this
+/// differently than the previous `enum$<_>` encoding emitted by earlier
+/// compiler versions.
///
-/// At the LLVM IR level this looks like
+/// Niche-tag enums have one special variant, usually called the
+/// "dataful variant". This variant has a field that
+/// doubles as the tag of the enum. The variant is active when the value of
+/// that field is within a pre-defined range. Therefore the variant struct
+/// has a `DISCR_BEGIN` and `DISCR_END` field instead of `DISCR_EXACT` in
+/// that case. Both `DISCR_BEGIN` and `DISCR_END` are inclusive bounds.
+/// Note that these ranges can wrap around, so that `DISCR_END < DISCR_BEGIN`.
///
-/// ```txt
-/// DW_TAG_union_type (top-level type for enum)
-/// DW_TAG_member (member for variant 1)
-/// DW_TAG_member (member for variant 2)
-/// DW_TAG_member (member for variant 3)
-/// DW_TAG_structure_type (type of variant 1)
-/// DW_TAG_structure_type (type of variant 2)
-/// DW_TAG_structure_type (type of variant 3)
-/// DW_TAG_enumeration_type (type of tag)
-/// ```
+/// Single-variant enums don't actually have a tag field. In this case we
+/// emit a static tag field (that always has the value 0) so we can use the
+/// same representation (and NatVis).
///
-/// The above encoding applies for enums with a direct tag. For niche-tag we have to do things
-/// differently in order to allow a NatVis visualizer to extract all the information needed:
-/// We generate a union of two fields, one for the dataful variant
-/// and one that just points to the discriminant (which is some field within the dataful variant).
-/// We also create a DW_TAG_enumeration_type DIE that contains tag values for the non-dataful
-/// variants and make the discriminant field that type. We then use NatVis to render the enum type
-/// correctly in Windbg/VS. This will generate debuginfo roughly equivalent to the following C:
+/// For niche-layout enums it's possible to have a 128-bit tag. NatVis, VS, and
+/// WinDbg (the main targets for CPP-like debuginfo at the moment) don't support
+/// 128-bit integers, so all values involved get split into two 64-bit fields.
+/// Instead of the `tag` field, we generate two fields `tag128_lo` and `tag128_hi`,
+/// Instead of `DISCR_EXACT`, we generate `DISCR128_EXACT_LO` and `DISCR128_EXACT_HI`,
+/// and so on.
///
-/// ```c
-/// union enum$<{name}, {min niche}, {max niche}, {dataful variant name}> {
-/// struct <dataful variant name> {
-/// <fields in dataful variant>
-/// } dataful_variant;
-/// enum Discriminant$ {
-/// <non-dataful variants>
-/// } discriminant;
+///
+/// The following pseudocode shows how to decode an enum value in a debugger:
+///
+/// ```text
+///
+/// fn find_active_variant(enum_value) -> (VariantName, VariantValue) {
+/// let is_128_bit = enum_value.has_field("tag128_lo");
+///
+/// if !is_128_bit {
+/// // Note: `tag` can be a static field for enums with only one
+/// // inhabited variant.
+/// let tag = enum_value.field("tag").value;
+///
+/// // For each variant, check if it is a match. Only one of them will match,
+/// // so if we find it we can return it immediately.
+/// for variant_field in enum_value.fields().filter(|f| f.name.starts_with("variant")) {
+/// if variant_field.has_field("DISCR_EXACT") {
+/// // This variant corresponds to a single tag value
+/// if variant_field.field("DISCR_EXACT").value == tag {
+/// return (variant_field.field("NAME"), variant_field.value);
+/// }
+/// } else {
+/// // This is a range variant
+/// let begin = variant_field.field("DISCR_BEGIN");
+/// let end = variant_field.field("DISCR_END");
+///
+/// if is_in_range(tag, begin, end) {
+/// return (variant_field.field("NAME"), variant_field.value);
+/// }
+/// }
+/// }
+/// } else {
+/// // Basically the same as with smaller tags, we just have to
+/// // stitch the values together.
+/// let tag: u128 = (enum_value.field("tag128_lo").value as u128) |
+/// (enum_value.field("tag128_hi").value as u128 << 64);
+///
+/// for variant_field in enum_value.fields().filter(|f| f.name.starts_with("variant")) {
+/// if variant_field.has_field("DISCR128_EXACT_LO") {
+/// let discr_exact = (variant_field.field("DISCR128_EXACT_LO" as u128) |
+/// (variant_field.field("DISCR128_EXACT_HI") as u128 << 64);
+///
+/// // This variant corresponds to a single tag value
+/// if discr_exact.value == tag {
+/// return (variant_field.field("NAME"), variant_field.value);
+/// }
+/// } else {
+/// // This is a range variant
+/// let begin = (variant_field.field("DISCR128_BEGIN_LO").value as u128) |
+/// (variant_field.field("DISCR128_BEGIN_HI").value as u128 << 64);
+/// let end = (variant_field.field("DISCR128_END_LO").value as u128) |
+/// (variant_field.field("DISCR128_END_HI").value as u128 << 64);
+///
+/// if is_in_range(tag, begin, end) {
+/// return (variant_field.field("NAME"), variant_field.value);
+/// }
+/// }
+/// }
+/// }
+///
+/// // We should have found an active variant at this point.
+/// unreachable!();
/// }
-/// ```
///
-/// The NatVis in `intrinsic.natvis` matches on the type name `enum$<*, *, *, *>`
-/// and evaluates `this.discriminant`. If the value is between the min niche and max
-/// niche, then the enum is in the dataful variant and `this.dataful_variant` is
-/// rendered. Otherwise, the enum is in one of the non-dataful variants. In that
-/// case, we just need to render the name of the `this.discriminant` enum.
+/// // Check if a value is within the given range
+/// // (where the range might wrap around the value space)
+/// fn is_in_range(value, start, end) -> bool {
+/// if start < end {
+/// value >= start && value <= end
+/// } else {
+/// value >= start || value <= end
+/// }
+/// }
+///
+/// ```
pub(super) fn build_enum_type_di_node<'ll, 'tcx>(
cx: &CodegenCx<'ll, 'tcx>,
unique_type_id: UniqueTypeId<'tcx>,
ref variants,
tag_field,
..
- } => build_union_fields_for_direct_tag_enum(
+ } => build_union_fields_for_enum(
cx,
enum_adt_def,
enum_type_and_layout,
enum_type_di_node,
- &mut variants.indices(),
+ variants.indices(),
tag_field,
+ None,
),
Variants::Multiple {
tag_encoding: TagEncoding::Niche { dataful_variant, .. },
ref variants,
tag_field,
..
- } => build_union_fields_for_niche_tag_enum(
+ } => build_union_fields_for_enum(
cx,
enum_adt_def,
enum_type_and_layout,
enum_type_di_node,
- dataful_variant,
- &mut variants.indices(),
+ variants.indices(),
tag_field,
+ Some(dataful_variant),
),
}
},
let variant_layout = enum_type_and_layout.for_variant(cx, variant_index);
let variant_struct_type_di_node = super::build_enum_variant_struct_type_di_node(
cx,
- enum_type_and_layout.ty,
+ enum_type_and_layout,
enum_type_di_node,
variant_index,
enum_adt_def.variant(variant_index),
variant_layout,
);
- // NOTE: The field name of the union is the same as the variant name, not "variant0".
- let variant_name = enum_adt_def.variant(variant_index).name.as_str();
+ let tag_base_type = cx.tcx.types.u32;
+ let tag_base_type_di_node = type_di_node(cx, tag_base_type);
+ let tag_base_type_align = cx.align_of(tag_base_type);
- smallvec![build_field_di_node(
+ let variant_names_type_di_node = build_variant_names_type_di_node(
cx,
enum_type_di_node,
- variant_name,
- // NOTE: We use the size and align of the entire type, not from variant_layout
- // since the later is sometimes smaller (if it has fewer fields).
- size_and_align_of(enum_type_and_layout),
- Size::ZERO,
- DIFlags::FlagZero,
+ std::iter::once((
+ variant_index,
+ Cow::from(enum_adt_def.variant(variant_index).name.as_str()),
+ )),
+ );
+
+ let variant_struct_type_wrapper_di_node = build_variant_struct_wrapper_type_di_node(
+ cx,
+ enum_type_and_layout,
+ enum_type_di_node,
+ variant_index,
+ None,
variant_struct_type_di_node,
- )]
+ variant_names_type_di_node,
+ tag_base_type_di_node,
+ tag_base_type,
+ DiscrResult::NoDiscriminant,
+ );
+
+ smallvec![
+ build_field_di_node(
+ cx,
+ enum_type_di_node,
+ &variant_union_field_name(variant_index),
+ // NOTE: We use the size and align of the entire type, not from variant_layout
+ // since the later is sometimes smaller (if it has fewer fields).
+ size_and_align_of(enum_type_and_layout),
+ Size::ZERO,
+ DIFlags::FlagZero,
+ variant_struct_type_wrapper_di_node,
+ ),
+ unsafe {
+ llvm::LLVMRustDIBuilderCreateStaticMemberType(
+ DIB(cx),
+ enum_type_di_node,
+ TAG_FIELD_NAME.as_ptr().cast(),
+ TAG_FIELD_NAME.len(),
+ unknown_file_metadata(cx),
+ UNKNOWN_LINE_NUMBER,
+ variant_names_type_di_node,
+ DIFlags::FlagZero,
+ Some(cx.const_u64(SINGLE_VARIANT_VIRTUAL_DISR)),
+ tag_base_type_align.bits() as u32,
+ )
+ }
+ ]
}
-fn build_union_fields_for_direct_tag_enum<'ll, 'tcx>(
+fn build_union_fields_for_enum<'ll, 'tcx>(
cx: &CodegenCx<'ll, 'tcx>,
enum_adt_def: AdtDef<'tcx>,
enum_type_and_layout: TyAndLayout<'tcx>,
enum_type_di_node: &'ll DIType,
- variant_indices: &mut dyn Iterator<Item = VariantIdx>,
+ variant_indices: impl Iterator<Item = VariantIdx> + Clone,
tag_field: usize,
+ dataful_variant_index: Option<VariantIdx>,
) -> SmallVec<&'ll DIType> {
+ let tag_base_type = super::tag_base_type(cx, enum_type_and_layout);
+
+ let variant_names_type_di_node = build_variant_names_type_di_node(
+ cx,
+ enum_type_di_node,
+ variant_indices.clone().map(|variant_index| {
+ let variant_name = Cow::from(enum_adt_def.variant(variant_index).name.as_str());
+ (variant_index, variant_name)
+ }),
+ );
+
let variant_field_infos: SmallVec<VariantFieldInfo<'ll>> = variant_indices
.map(|variant_index| {
let variant_layout = enum_type_and_layout.for_variant(cx, variant_index);
+ let variant_def = enum_adt_def.variant(variant_index);
+
+ let variant_struct_type_di_node = super::build_enum_variant_struct_type_di_node(
+ cx,
+ enum_type_and_layout,
+ enum_type_di_node,
+ variant_index,
+ variant_def,
+ variant_layout,
+ );
+
VariantFieldInfo {
variant_index,
- variant_struct_type_di_node: super::build_enum_variant_struct_type_di_node(
- cx,
- enum_type_and_layout.ty,
- enum_type_di_node,
- variant_index,
- enum_adt_def.variant(variant_index),
- variant_layout,
- ),
+ variant_struct_type_di_node,
source_info: None,
+ discr: super::compute_discriminant_value(cx, enum_type_and_layout, variant_index),
}
})
.collect();
- let discr_type_name = cx.tcx.item_name(enum_adt_def.did());
- let tag_base_type = super::tag_base_type(cx, enum_type_and_layout);
- let discr_type_di_node = super::build_enumeration_type_di_node(
- cx,
- discr_type_name.as_str(),
- tag_base_type,
- &mut enum_adt_def.discriminants(cx.tcx).map(|(variant_index, discr)| {
- (discr, Cow::from(enum_adt_def.variant(variant_index).name.as_str()))
- }),
- enum_type_di_node,
- );
-
build_union_fields_for_direct_tag_enum_or_generator(
cx,
enum_type_and_layout,
enum_type_di_node,
&variant_field_infos,
- discr_type_di_node,
+ variant_names_type_di_node,
+ tag_base_type,
tag_field,
+ dataful_variant_index,
)
}
-fn build_union_fields_for_niche_tag_enum<'ll, 'tcx>(
+// The base type of the VariantNames DW_AT_enumeration_type is always the same.
+// It has nothing to do with the tag of the enum and just has to be big enough
+// to hold all variant names.
+fn variant_names_enum_base_type<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>) -> Ty<'tcx> {
+ cx.tcx.types.u32
+}
+
+/// This function builds a DW_AT_enumeration_type that contains an entry for
+/// each variant. Note that this has nothing to do with the discriminant. The
+/// numeric value of each enumerator corresponds to the variant index. The
+/// type is only used for efficiently encoding the name of each variant in
+/// debuginfo.
+fn build_variant_names_type_di_node<'ll, 'tcx>(
cx: &CodegenCx<'ll, 'tcx>,
- enum_adt_def: AdtDef<'tcx>,
- enum_type_and_layout: TyAndLayout<'tcx>,
- enum_type_di_node: &'ll DIType,
- dataful_variant_index: VariantIdx,
- variant_indices: &mut dyn Iterator<Item = VariantIdx>,
- tag_field: usize,
-) -> SmallVec<&'ll DIType> {
- let dataful_variant_struct_type_di_node = super::build_enum_variant_struct_type_di_node(
+ containing_scope: &'ll DIType,
+ variants: impl Iterator<Item = (VariantIdx, Cow<'tcx, str>)>,
+) -> &'ll DIType {
+ // Create an enumerator for each variant.
+ super::build_enumeration_type_di_node(
cx,
- enum_type_and_layout.ty,
- enum_type_di_node,
- dataful_variant_index,
- &enum_adt_def.variant(dataful_variant_index),
- enum_type_and_layout.for_variant(cx, dataful_variant_index),
- );
+ "VariantNames",
+ variant_names_enum_base_type(cx),
+ variants.map(|(variant_index, variant_name)| (variant_name, variant_index.as_u32() as u64)),
+ containing_scope,
+ )
+}
- let tag_base_type = super::tag_base_type(cx, enum_type_and_layout);
- // Create an DW_TAG_enumerator for each variant except the dataful one.
- let discr_type_di_node = super::build_enumeration_type_di_node(
+fn build_variant_struct_wrapper_type_di_node<'ll, 'tcx>(
+ cx: &CodegenCx<'ll, 'tcx>,
+ enum_or_generator_type_and_layout: TyAndLayout<'tcx>,
+ enum_or_generator_type_di_node: &'ll DIType,
+ variant_index: VariantIdx,
+ dataful_variant_index: Option<VariantIdx>,
+ variant_struct_type_di_node: &'ll DIType,
+ variant_names_type_di_node: &'ll DIType,
+ tag_base_type_di_node: &'ll DIType,
+ tag_base_type: Ty<'tcx>,
+ discr: DiscrResult,
+) -> &'ll DIType {
+ type_map::build_type_with_children(
cx,
- "Discriminant$",
- tag_base_type,
- &mut variant_indices.filter_map(|variant_index| {
- if let Some(discr_val) =
- super::compute_discriminant_value(cx, enum_type_and_layout, variant_index)
- {
- let discr = Discr { val: discr_val as u128, ty: tag_base_type };
- let variant_name = Cow::from(enum_adt_def.variant(variant_index).name.as_str());
- Some((discr, variant_name))
- } else {
- debug_assert_eq!(variant_index, dataful_variant_index);
- None
- }
- }),
- enum_type_di_node,
- );
-
- smallvec![
- build_field_di_node(
- cx,
- enum_type_di_node,
- "dataful_variant",
- size_and_align_of(enum_type_and_layout),
- Size::ZERO,
- DIFlags::FlagZero,
- dataful_variant_struct_type_di_node,
- ),
- build_field_di_node(
+ type_map::stub(
cx,
- enum_type_di_node,
- "discriminant",
- cx.size_and_align_of(tag_base_type),
- enum_type_and_layout.fields.offset(tag_field),
+ Stub::Struct,
+ UniqueTypeId::for_enum_variant_struct_type_wrapper(
+ cx.tcx,
+ enum_or_generator_type_and_layout.ty,
+ variant_index,
+ ),
+ &variant_struct_wrapper_type_name(variant_index),
+ // NOTE: We use size and align of enum_type, not from variant_layout:
+ size_and_align_of(enum_or_generator_type_and_layout),
+ Some(enum_or_generator_type_di_node),
DIFlags::FlagZero,
- discr_type_di_node,
),
- ]
+ |cx, wrapper_struct_type_di_node| {
+ enum DiscrKind {
+ Exact(u64),
+ Exact128(u128),
+ Range(u64, u64),
+ Range128(u128, u128),
+ }
+
+ let (tag_base_type_size, tag_base_type_align) = cx.size_and_align_of(tag_base_type);
+ let is_128_bits = tag_base_type_size.bits() > 64;
+
+ let discr = match discr {
+ DiscrResult::NoDiscriminant => DiscrKind::Exact(SINGLE_VARIANT_VIRTUAL_DISR),
+ DiscrResult::Value(discr_val) => {
+ if is_128_bits {
+ DiscrKind::Exact128(discr_val)
+ } else {
+ debug_assert_eq!(discr_val, discr_val as u64 as u128);
+ DiscrKind::Exact(discr_val as u64)
+ }
+ }
+ DiscrResult::Range(min, max) => {
+ assert_eq!(Some(variant_index), dataful_variant_index);
+ if is_128_bits {
+ DiscrKind::Range128(min, max)
+ } else {
+ debug_assert_eq!(min, min as u64 as u128);
+ debug_assert_eq!(max, max as u64 as u128);
+ DiscrKind::Range(min as u64, max as u64)
+ }
+ }
+ };
+
+ let mut fields = SmallVec::new();
+
+ // We always have a field for the value
+ fields.push(build_field_di_node(
+ cx,
+ wrapper_struct_type_di_node,
+ "value",
+ size_and_align_of(enum_or_generator_type_and_layout),
+ Size::ZERO,
+ DIFlags::FlagZero,
+ variant_struct_type_di_node,
+ ));
+
+ let build_assoc_const =
+ |name: &str, type_di_node: &'ll DIType, value: u64, align: Align| unsafe {
+ llvm::LLVMRustDIBuilderCreateStaticMemberType(
+ DIB(cx),
+ wrapper_struct_type_di_node,
+ name.as_ptr().cast(),
+ name.len(),
+ unknown_file_metadata(cx),
+ UNKNOWN_LINE_NUMBER,
+ type_di_node,
+ DIFlags::FlagZero,
+ Some(cx.const_u64(value)),
+ align.bits() as u32,
+ )
+ };
+
+ // We also always have an associated constant for the discriminant value
+ // of the variant.
+ fields.push(build_assoc_const(
+ ASSOC_CONST_DISCR_NAME,
+ variant_names_type_di_node,
+ variant_index.as_u32() as u64,
+ cx.align_of(variant_names_enum_base_type(cx)),
+ ));
+
+ // Emit the discriminant value (or range) corresponding to the variant.
+ match discr {
+ DiscrKind::Exact(discr_val) => {
+ fields.push(build_assoc_const(
+ ASSOC_CONST_DISCR_EXACT,
+ tag_base_type_di_node,
+ discr_val,
+ tag_base_type_align,
+ ));
+ }
+ DiscrKind::Exact128(discr_val) => {
+ let align = cx.align_of(cx.tcx.types.u64);
+ let type_di_node = type_di_node(cx, cx.tcx.types.u64);
+ let Split128 { hi, lo } = split_128(discr_val);
+
+ fields.push(build_assoc_const(
+ ASSOC_CONST_DISCR128_EXACT_LO,
+ type_di_node,
+ lo,
+ align,
+ ));
+
+ fields.push(build_assoc_const(
+ ASSOC_CONST_DISCR128_EXACT_HI,
+ type_di_node,
+ hi,
+ align,
+ ));
+ }
+ DiscrKind::Range(begin, end) => {
+ fields.push(build_assoc_const(
+ ASSOC_CONST_DISCR_BEGIN,
+ tag_base_type_di_node,
+ begin,
+ tag_base_type_align,
+ ));
+
+ fields.push(build_assoc_const(
+ ASSOC_CONST_DISCR_END,
+ tag_base_type_di_node,
+ end,
+ tag_base_type_align,
+ ));
+ }
+ DiscrKind::Range128(begin, end) => {
+ let align = cx.align_of(cx.tcx.types.u64);
+ let type_di_node = type_di_node(cx, cx.tcx.types.u64);
+ let Split128 { hi: begin_hi, lo: begin_lo } = split_128(begin);
+ let Split128 { hi: end_hi, lo: end_lo } = split_128(end);
+
+ fields.push(build_assoc_const(
+ ASSOC_CONST_DISCR128_BEGIN_HI,
+ type_di_node,
+ begin_hi,
+ align,
+ ));
+
+ fields.push(build_assoc_const(
+ ASSOC_CONST_DISCR128_BEGIN_LO,
+ type_di_node,
+ begin_lo,
+ align,
+ ));
+
+ fields.push(build_assoc_const(
+ ASSOC_CONST_DISCR128_END_HI,
+ type_di_node,
+ end_hi,
+ align,
+ ));
+
+ fields.push(build_assoc_const(
+ ASSOC_CONST_DISCR128_END_LO,
+ type_di_node,
+ end_lo,
+ align,
+ ));
+ }
+ }
+
+ fields
+ },
+ NO_GENERICS,
+ )
+ .di_node
+}
+
+struct Split128 {
+ hi: u64,
+ lo: u64,
+}
+
+fn split_128(value: u128) -> Split128 {
+ Split128 { hi: (value >> 64) as u64, lo: value as u64 }
}
fn build_union_fields_for_direct_tag_generator<'ll, 'tcx>(
let common_upvar_names = closure_saved_names_of_captured_variables(cx.tcx, generator_def_id);
let variant_range = generator_substs.variant_range(generator_def_id, cx.tcx);
+ let variant_count = (variant_range.start.as_u32()..variant_range.end.as_u32()).len();
+
+ let tag_base_type = tag_base_type(cx, generator_type_and_layout);
+
+ let variant_names_type_di_node = build_variant_names_type_di_node(
+ cx,
+ generator_type_di_node,
+ variant_range
+ .clone()
+ .map(|variant_index| (variant_index, GeneratorSubsts::variant_name(variant_index))),
+ );
+
+ let discriminants: IndexVec<VariantIdx, DiscrResult> = {
+ let discriminants_iter = generator_substs.discriminants(generator_def_id, cx.tcx);
+ let mut discriminants: IndexVec<VariantIdx, DiscrResult> =
+ IndexVec::with_capacity(variant_count);
+ for (variant_index, discr) in discriminants_iter {
+ // Assert that the index in the IndexMap matches up with the given VariantIdx.
+ assert_eq!(variant_index, discriminants.next_index());
+ discriminants.push(DiscrResult::Value(discr.val));
+ }
+ discriminants
+ };
// Build the type node for each field.
let variant_field_infos: SmallVec<VariantFieldInfo<'ll>> = variant_range
None
};
- VariantFieldInfo { variant_index, variant_struct_type_di_node, source_info }
+ VariantFieldInfo {
+ variant_index,
+ variant_struct_type_di_node,
+ source_info,
+ discr: discriminants[variant_index],
+ }
})
.collect();
- let tag_base_type = tag_base_type(cx, generator_type_and_layout);
- let discr_type_name = "Discriminant$";
- let discr_type_di_node = super::build_enumeration_type_di_node(
- cx,
- discr_type_name,
- tag_base_type,
- &mut generator_substs
- .discriminants(generator_def_id, cx.tcx)
- .map(|(variant_index, discr)| (discr, GeneratorSubsts::variant_name(variant_index))),
- generator_type_di_node,
- );
-
build_union_fields_for_direct_tag_enum_or_generator(
cx,
generator_type_and_layout,
generator_type_di_node,
&variant_field_infos[..],
- discr_type_di_node,
+ variant_names_type_di_node,
+ tag_base_type,
tag_field,
+ None,
)
}
enum_type_di_node: &'ll DIType,
variant_field_infos: &[VariantFieldInfo<'ll>],
discr_type_di_node: &'ll DIType,
+ tag_base_type: Ty<'tcx>,
tag_field: usize,
+ dataful_variant_index: Option<VariantIdx>,
) -> SmallVec<&'ll DIType> {
+ let tag_base_type_di_node = type_di_node(cx, tag_base_type);
let mut unions_fields = SmallVec::with_capacity(variant_field_infos.len() + 1);
// We create a field in the union for each variant ...
let field_name = variant_union_field_name(variant_member_info.variant_index);
let (size, align) = size_and_align_of(enum_type_and_layout);
+ let variant_struct_type_wrapper = build_variant_struct_wrapper_type_di_node(
+ cx,
+ enum_type_and_layout,
+ enum_type_di_node,
+ variant_member_info.variant_index,
+ dataful_variant_index,
+ variant_member_info.variant_struct_type_di_node,
+ discr_type_di_node,
+ tag_base_type_di_node,
+ tag_base_type,
+ variant_member_info.discr,
+ );
+
// We use LLVMRustDIBuilderCreateMemberType() member type directly because
// the build_field_di_node() function does not support specifying a source location,
// which is something that we don't do anywhere else.
// Union fields are always at offset zero
Size::ZERO.bits(),
DIFlags::FlagZero,
- variant_member_info.variant_struct_type_di_node,
+ variant_struct_type_wrapper,
)
}
}));
cx.size_and_align_of(super::tag_base_type(cx, enum_type_and_layout))
);
- // ... and a field for the discriminant.
- unions_fields.push(build_field_di_node(
- cx,
- enum_type_di_node,
- "discriminant",
- cx.size_and_align_of(enum_type_and_layout.field(cx, tag_field).ty),
- enum_type_and_layout.fields.offset(tag_field),
- DIFlags::FlagZero,
- discr_type_di_node,
- ));
+ // ... and a field for the tag. If the tag is 128 bits wide, this will actually
+ // be two 64-bit fields.
+ let is_128_bits = cx.size_of(tag_base_type).bits() > 64;
+
+ if is_128_bits {
+ let type_di_node = type_di_node(cx, cx.tcx.types.u64);
+ let size_and_align = cx.size_and_align_of(cx.tcx.types.u64);
+
+ let (lo_offset, hi_offset) = match cx.tcx.data_layout.endian {
+ Endian::Little => (0, 8),
+ Endian::Big => (8, 0),
+ };
+
+ let tag_field_offset = enum_type_and_layout.fields.offset(tag_field).bytes();
+ let lo_offset = Size::from_bytes(tag_field_offset + lo_offset);
+ let hi_offset = Size::from_bytes(tag_field_offset + hi_offset);
+
+ unions_fields.push(build_field_di_node(
+ cx,
+ enum_type_di_node,
+ TAG_FIELD_NAME_128_LO,
+ size_and_align,
+ lo_offset,
+ DIFlags::FlagZero,
+ type_di_node,
+ ));
+
+ unions_fields.push(build_field_di_node(
+ cx,
+ enum_type_di_node,
+ TAG_FIELD_NAME_128_HI,
+ size_and_align,
+ hi_offset,
+ DIFlags::FlagZero,
+ type_di_node,
+ ));
+ } else {
+ unions_fields.push(build_field_di_node(
+ cx,
+ enum_type_di_node,
+ TAG_FIELD_NAME,
+ cx.size_and_align_of(enum_type_and_layout.field(cx, tag_field).ty),
+ enum_type_and_layout.fields.offset(tag_field),
+ DIFlags::FlagZero,
+ tag_base_type_di_node,
+ ));
+ }
unions_fields
}
variant_index: VariantIdx,
variant_struct_type_di_node: &'ll DIType,
source_info: Option<(&'ll DIFile, c_uint)>,
+ discr: DiscrResult,
}
fn variant_union_field_name(variant_index: VariantIdx) -> Cow<'static, str> {
.map(|&s| Cow::from(s))
.unwrap_or_else(|| format!("variant{}", variant_index.as_usize()).into())
}
+
+fn variant_struct_wrapper_type_name(variant_index: VariantIdx) -> Cow<'static, str> {
+ const PRE_ALLOCATED: [&str; 16] = [
+ "Variant0",
+ "Variant1",
+ "Variant2",
+ "Variant3",
+ "Variant4",
+ "Variant5",
+ "Variant6",
+ "Variant7",
+ "Variant8",
+ "Variant9",
+ "Variant10",
+ "Variant11",
+ "Variant12",
+ "Variant13",
+ "Variant14",
+ "Variant15",
+ ];
+
+ PRE_ALLOCATED
+ .get(variant_index.as_usize())
+ .map(|&s| Cow::from(s))
+ .unwrap_or_else(|| format!("Variant{}", variant_index.as_usize()).into())
+}
ty::{
self,
layout::{IntegerExt, LayoutOf, PrimitiveExt, TyAndLayout},
- util::Discr,
AdtDef, GeneratorSubsts, Ty, VariantDef,
},
};
cx,
&compute_debuginfo_type_name(cx.tcx, enum_type_and_layout.ty, false),
tag_base_type(cx, enum_type_and_layout),
- &mut enum_adt_def.discriminants(cx.tcx).map(|(variant_index, discr)| {
- (discr, Cow::from(enum_adt_def.variant(variant_index).name.as_str()))
+ enum_adt_def.discriminants(cx.tcx).map(|(variant_index, discr)| {
+ let name = Cow::from(enum_adt_def.variant(variant_index).name.as_str());
+ // Is there anything we can do to support 128-bit C-Style enums?
+ let value = discr.val as u64;
+ (name, value)
}),
containing_scope,
),
cx: &CodegenCx<'ll, 'tcx>,
type_name: &str,
base_type: Ty<'tcx>,
- variants: &mut dyn Iterator<Item = (Discr<'tcx>, Cow<'tcx, str>)>,
+ enumerators: impl Iterator<Item = (Cow<'tcx, str>, u64)>,
containing_scope: &'ll DIType,
) -> &'ll DIType {
let is_unsigned = match base_type.kind() {
_ => bug!("build_enumeration_type_di_node() called with non-integer tag type."),
};
- let enumerator_di_nodes: SmallVec<Option<&'ll DIType>> = variants
- .map(|(discr, variant_name)| {
- unsafe {
- Some(llvm::LLVMRustDIBuilderCreateEnumerator(
- DIB(cx),
- variant_name.as_ptr().cast(),
- variant_name.len(),
- // FIXME: what if enumeration has i128 discriminant?
- discr.val as i64,
- is_unsigned,
- ))
- }
+ let enumerator_di_nodes: SmallVec<Option<&'ll DIType>> = enumerators
+ .map(|(name, value)| unsafe {
+ Some(llvm::LLVMRustDIBuilderCreateEnumerator(
+ DIB(cx),
+ name.as_ptr().cast(),
+ name.len(),
+ value as i64,
+ is_unsigned,
+ ))
})
.collect();
/// and a DW_TAG_member for each field (but not the discriminant).
fn build_enum_variant_struct_type_di_node<'ll, 'tcx>(
cx: &CodegenCx<'ll, 'tcx>,
- enum_type: Ty<'tcx>,
+ enum_type_and_layout: TyAndLayout<'tcx>,
enum_type_di_node: &'ll DIType,
variant_index: VariantIdx,
variant_def: &VariantDef,
variant_layout: TyAndLayout<'tcx>,
) -> &'ll DIType {
- debug_assert_eq!(variant_layout.ty, enum_type);
+ debug_assert_eq!(variant_layout.ty, enum_type_and_layout.ty);
type_map::build_type_with_children(
cx,
type_map::stub(
cx,
Stub::Struct,
- UniqueTypeId::for_enum_variant_struct_type(cx.tcx, enum_type, variant_index),
+ UniqueTypeId::for_enum_variant_struct_type(
+ cx.tcx,
+ enum_type_and_layout.ty,
+ variant_index,
+ ),
variant_def.name.as_str(),
// NOTE: We use size and align of enum_type, not from variant_layout:
- cx.size_and_align_of(enum_type),
+ size_and_align_of(enum_type_and_layout),
Some(enum_type_di_node),
DIFlags::FlagZero,
),
type_di_node(cx, field_layout.ty),
)
})
- .collect()
+ .collect::<SmallVec<_>>()
},
- |cx| build_generic_type_param_di_nodes(cx, enum_type),
+ |cx| build_generic_type_param_di_nodes(cx, enum_type_and_layout.ty),
)
.di_node
}
.di_node
}
+#[derive(Copy, Clone)]
+enum DiscrResult {
+ NoDiscriminant,
+ Value(u128),
+ Range(u128, u128),
+}
+
+impl DiscrResult {
+ fn opt_single_val(&self) -> Option<u128> {
+ if let Self::Value(d) = *self { Some(d) } else { None }
+ }
+}
+
/// Returns the discriminant value corresponding to the variant index.
///
/// Will return `None` if there is less than two variants (because then the enum won't have)
cx: &CodegenCx<'ll, 'tcx>,
enum_type_and_layout: TyAndLayout<'tcx>,
variant_index: VariantIdx,
-) -> Option<u64> {
+) -> DiscrResult {
match enum_type_and_layout.layout.variants() {
- &Variants::Single { .. } => None,
- &Variants::Multiple { tag_encoding: TagEncoding::Direct, .. } => Some(
- enum_type_and_layout.ty.discriminant_for_variant(cx.tcx, variant_index).unwrap().val
- as u64,
+ &Variants::Single { .. } => DiscrResult::NoDiscriminant,
+ &Variants::Multiple { tag_encoding: TagEncoding::Direct, .. } => DiscrResult::Value(
+ enum_type_and_layout.ty.discriminant_for_variant(cx.tcx, variant_index).unwrap().val,
),
&Variants::Multiple {
tag_encoding: TagEncoding::Niche { ref niche_variants, niche_start, dataful_variant },
..
} => {
if variant_index == dataful_variant {
- None
+ let valid_range = enum_type_and_layout
+ .for_variant(cx, variant_index)
+ .largest_niche
+ .as_ref()
+ .unwrap()
+ .valid_range;
+
+ let min = valid_range.start.min(valid_range.end);
+ let min = tag.size(cx).truncate(min);
+
+ let max = valid_range.start.max(valid_range.end);
+ let max = tag.size(cx).truncate(max);
+
+ DiscrResult::Range(min, max)
} else {
let value = (variant_index.as_u32() as u128)
.wrapping_sub(niche_variants.start().as_u32() as u128)
.wrapping_add(niche_start);
let value = tag.size(cx).truncate(value);
- // NOTE(eddyb) do *NOT* remove this assert, until
- // we pass the full 128-bit value to LLVM, otherwise
- // truncation will be silent and remain undetected.
- assert_eq!(value as u64 as u128, value);
- Some(value as u64)
+ DiscrResult::Value(value)
}
}
}
variant_name: Cow::from(enum_adt_def.variant(variant_index).name.as_str()),
variant_struct_type_di_node: super::build_enum_variant_struct_type_di_node(
cx,
- enum_type,
+ enum_type_and_layout,
enum_type_di_node,
variant_index,
enum_adt_def.variant(variant_index),
enum_type_and_layout.size.bits(),
enum_type_and_layout.align.abi.bits() as u32,
Size::ZERO.bits(),
- discr_value.map(|v| cx.const_u64(v)),
+ discr_value.opt_single_val().map(|value| {
+ // NOTE(eddyb) do *NOT* remove this assert, until
+ // we pass the full 128-bit value to LLVM, otherwise
+ // truncation will be silent and remain undetected.
+ assert_eq!(value as u64 as u128, value);
+ cx.const_u64(value as u64)
+ }),
DIFlags::FlagZero,
variant_member_info.variant_struct_type_di_node,
)
VariantPart(Ty<'tcx>, private::HiddenZst),
/// The ID for the artificial struct type describing a single enum variant.
VariantStructType(Ty<'tcx>, VariantIdx, private::HiddenZst),
+ /// The ID for the additional wrapper struct type describing an enum variant in CPP-like mode.
+ VariantStructTypeCppLikeWrapper(Ty<'tcx>, VariantIdx, private::HiddenZst),
/// The ID of the artificial type we create for VTables.
VTableTy(Ty<'tcx>, Option<PolyExistentialTraitRef<'tcx>>, private::HiddenZst),
}
UniqueTypeId::VariantStructType(enum_ty, variant_idx, private::HiddenZst)
}
+ pub fn for_enum_variant_struct_type_wrapper(
+ tcx: TyCtxt<'tcx>,
+ enum_ty: Ty<'tcx>,
+ variant_idx: VariantIdx,
+ ) -> Self {
+ debug_assert_eq!(enum_ty, tcx.normalize_erasing_regions(ParamEnv::reveal_all(), enum_ty));
+ UniqueTypeId::VariantStructTypeCppLikeWrapper(enum_ty, variant_idx, private::HiddenZst)
+ }
+
pub fn for_vtable_ty(
tcx: TyCtxt<'tcx>,
self_type: Ty<'tcx>,
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![feature(hash_raw_entry)]
-#![cfg_attr(bootstrap, feature(let_chains))]
#![feature(let_else)]
#![feature(extern_types)]
#![feature(once_cell)]
Ty: &'a DIType,
) -> &'a DIType;
+ pub fn LLVMRustDIBuilderCreateStaticMemberType<'a>(
+ Builder: &DIBuilder<'a>,
+ Scope: &'a DIDescriptor,
+ Name: *const c_char,
+ NameLen: size_t,
+ File: &'a DIFile,
+ LineNo: c_uint,
+ Ty: &'a DIType,
+ Flags: DIFlags,
+ val: Option<&'a Value>,
+ AlignInBits: u32,
+ ) -> &'a DIDerivedType;
+
pub fn LLVMRustDIBuilderCreateLexicalBlock<'a>(
Builder: &DIBuilder<'a>,
Scope: &'a DIScope,
use rustc_session::{filesearch, Session};
use rustc_span::symbol::Symbol;
use rustc_span::DebuggerVisualizerFile;
-use rustc_target::spec::crt_objects::{CrtObjects, CrtObjectsFallback};
+use rustc_target::spec::crt_objects::{CrtObjects, LinkSelfContainedDefault};
use rustc_target::spec::{LinkOutputKind, LinkerFlavor, LldFlavor, SplitDebuginfo};
use rustc_target::spec::{PanicStrategy, RelocModel, RelroLevel, SanitizerSet, Target};
"Linker does not support -static-pie command line option. Retrying with -static instead."
);
// Mirror `add_(pre,post)_link_objects` to replace CRT objects.
- let self_contained = crt_objects_fallback(sess, crate_type);
+ let self_contained = self_contained(sess, crate_type);
let opts = &sess.target;
let pre_objects = if self_contained {
- &opts.pre_link_objects_fallback
+ &opts.pre_link_objects_self_contained
} else {
&opts.pre_link_objects
};
let post_objects = if self_contained {
- &opts.post_link_objects_fallback
+ &opts.post_link_objects_self_contained
} else {
&opts.post_link_objects
};
true
}
-/// Whether we link to our own CRT objects instead of relying on gcc to pull them.
+/// Various toolchain components used during linking are used from rustc distribution
+/// instead of being found somewhere on the host system.
/// We only provide such support for a very limited number of targets.
-fn crt_objects_fallback(sess: &Session, crate_type: CrateType) -> bool {
+fn self_contained(sess: &Session, crate_type: CrateType) -> bool {
if let Some(self_contained) = sess.opts.cg.link_self_contained {
return self_contained;
}
- match sess.target.crt_objects_fallback {
+ match sess.target.link_self_contained {
+ LinkSelfContainedDefault::False => false,
+ LinkSelfContainedDefault::True => true,
// FIXME: Find a better heuristic for "native musl toolchain is available",
// based on host and linker path, for example.
// (https://github.com/rust-lang/rust/pull/71769#issuecomment-626330237).
- Some(CrtObjectsFallback::Musl) => sess.crt_static(Some(crate_type)),
- Some(CrtObjectsFallback::Mingw) => {
+ LinkSelfContainedDefault::Musl => sess.crt_static(Some(crate_type)),
+ LinkSelfContainedDefault::Mingw => {
sess.host == sess.target
&& sess.target.vendor != "uwp"
&& detect_self_contained_mingw(&sess)
}
- // FIXME: Figure out cases in which WASM needs to link with a native toolchain.
- Some(CrtObjectsFallback::Wasm) => true,
- None => false,
}
}
let opts = &sess.target;
let empty = Default::default();
let objects = if self_contained {
- &opts.pre_link_objects_fallback
+ &opts.pre_link_objects_self_contained
} else if !(sess.target.os == "fuchsia" && flavor == LinkerFlavor::Gcc) {
&opts.pre_link_objects
} else {
link_output_kind: LinkOutputKind,
self_contained: bool,
) {
- let opts = &sess.target;
- let objects =
- if self_contained { &opts.post_link_objects_fallback } else { &opts.post_link_objects };
+ let objects = if self_contained {
+ &sess.target.post_link_objects_self_contained
+ } else {
+ &sess.target.post_link_objects
+ };
for obj in objects.get(&link_output_kind).iter().copied().flatten() {
cmd.add_object(&get_object_file_path(sess, obj, self_contained));
}
out_filename: &Path,
codegen_results: &CodegenResults,
) -> Result<Command, ErrorGuaranteed> {
- let crt_objects_fallback = crt_objects_fallback(sess, crate_type);
+ let self_contained = self_contained(sess, crate_type);
let cmd = &mut *super::linker::get_linker(
sess,
path,
flavor,
- crt_objects_fallback,
+ self_contained,
&codegen_results.crate_info.target_cpu,
);
let link_output_kind = link_output_kind(sess, crate_type);
// ------------ Object code and libraries, order-dependent ------------
// Pre-link CRT objects.
- add_pre_link_objects(cmd, sess, flavor, link_output_kind, crt_objects_fallback);
+ add_pre_link_objects(cmd, sess, flavor, link_output_kind, self_contained);
add_linked_symbol_object(
cmd,
cmd,
sess,
link_output_kind,
- crt_objects_fallback,
+ self_contained,
flavor,
crate_type,
codegen_results,
// ------------ Object code and libraries, order-dependent ------------
// Post-link CRT objects.
- add_post_link_objects(cmd, sess, link_output_kind, crt_objects_fallback);
+ add_post_link_objects(cmd, sess, link_output_kind, self_contained);
// ------------ Late order-dependent options ------------
cmd: &mut dyn Linker,
sess: &Session,
link_output_kind: LinkOutputKind,
- crt_objects_fallback: bool,
+ self_contained: bool,
flavor: LinkerFlavor,
crate_type: CrateType,
codegen_results: &CodegenResults,
// Make the binary compatible with data execution prevention schemes.
cmd.add_no_exec();
- if crt_objects_fallback {
+ if self_contained {
cmd.no_crt_objects();
}
cmd.linker_plugin_lto();
- add_library_search_dirs(cmd, sess, crt_objects_fallback);
+ add_library_search_dirs(cmd, sess, self_contained);
cmd.output_filename(out_filename);
use rustc_hir::{AsyncGeneratorKind, GeneratorKind, Mutability};
use rustc_middle::ty::layout::{IntegerExt, TyAndLayout};
use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
-use rustc_middle::ty::{self, ExistentialProjection, GeneratorSubsts, ParamEnv, Ty, TyCtxt};
-use rustc_target::abi::{Integer, TagEncoding, Variants};
+use rustc_middle::ty::{self, ExistentialProjection, ParamEnv, Ty, TyCtxt};
+use rustc_target::abi::Integer;
use smallvec::SmallVec;
-use std::borrow::Cow;
use std::fmt::Write;
use crate::debuginfo::wants_c_like_enum_debuginfo;
if let Some(ty_and_layout) = layout_for_cpp_like_fallback {
msvc_enum_fallback(
- tcx,
ty_and_layout,
&|output, visited| {
push_item_name(tcx, def.did(), true, output);
// Name will be "{closure_env#0}<T1, T2, ...>", "{generator_env#0}<T1, T2, ...>", or
// "{async_fn_env#0}<T1, T2, ...>", etc.
// In the case of cpp-like debuginfo, the name additionally gets wrapped inside of
- // an artificial `enum$<>` type, as defined in msvc_enum_fallback().
+ // an artificial `enum2$<>` type, as defined in msvc_enum_fallback().
if cpp_like_debuginfo && t.is_generator() {
let ty_and_layout = tcx.layout_of(ParamEnv::reveal_all().and(t)).unwrap();
msvc_enum_fallback(
- tcx,
ty_and_layout,
&|output, visited| {
push_closure_or_generator_name(tcx, def_id, substs, true, output, visited);
/// MSVC names enums differently than other platforms so that the debugging visualization
// format (natvis) is able to understand enums and render the active variant correctly in the
- // debugger. For more information, look in `src/etc/natvis/intrinsic.natvis` and
- // `EnumMemberDescriptionFactor::create_member_descriptions`.
+ // debugger. For more information, look in
+ // rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs.
fn msvc_enum_fallback<'tcx>(
- tcx: TyCtxt<'tcx>,
ty_and_layout: TyAndLayout<'tcx>,
push_inner: &dyn Fn(/*output*/ &mut String, /*visited*/ &mut FxHashSet<Ty<'tcx>>),
output: &mut String,
visited: &mut FxHashSet<Ty<'tcx>>,
) {
debug_assert!(!wants_c_like_enum_debuginfo(ty_and_layout));
- let ty = ty_and_layout.ty;
-
- output.push_str("enum$<");
+ output.push_str("enum2$<");
push_inner(output, visited);
-
- let variant_name = |variant_index| match ty.kind() {
- ty::Adt(adt_def, _) => {
- debug_assert!(adt_def.is_enum());
- Cow::from(adt_def.variant(variant_index).name.as_str())
- }
- ty::Generator(..) => GeneratorSubsts::variant_name(variant_index),
- _ => unreachable!(),
- };
-
- if let Variants::Multiple {
- tag_encoding: TagEncoding::Niche { dataful_variant, .. },
- tag,
- variants,
- ..
- } = &ty_and_layout.variants
- {
- let dataful_variant_layout = &variants[*dataful_variant];
-
- // calculate the range of values for the dataful variant
- let dataful_discriminant_range =
- dataful_variant_layout.largest_niche().unwrap().valid_range;
-
- let min = dataful_discriminant_range.start;
- let min = tag.size(&tcx).truncate(min);
-
- let max = dataful_discriminant_range.end;
- let max = tag.size(&tcx).truncate(max);
-
- let dataful_variant_name = variant_name(*dataful_variant);
- write!(output, ", {}, {}, {}", min, max, dataful_variant_name).unwrap();
- } else if let Variants::Single { index: variant_idx } = &ty_and_layout.variants {
- // Uninhabited enums can't be constructed and should never need to be visualized so
- // skip this step for them.
- if !ty_and_layout.abi.is_uninhabited() {
- write!(output, ", {}", variant_name(*variant_idx)).unwrap();
- }
- }
push_close_angle_bracket(true, output);
}
("zhinxmin", Some(sym::riscv_target_feature)),
("zfh", Some(sym::riscv_target_feature)),
("zfhmin", Some(sym::riscv_target_feature)),
+ ("zba", Some(sym::riscv_target_feature)),
+ ("zbb", Some(sym::riscv_target_feature)),
+ ("zbc", Some(sym::riscv_target_feature)),
+ ("zbs", Some(sym::riscv_target_feature)),
("zbkb", Some(sym::riscv_target_feature)),
("zbkc", Some(sym::riscv_target_feature)),
("zbkx", Some(sym::riscv_target_feature)),
const PANIC_ON_ALLOC_FAIL: bool = false; // will be raised as a proper error
+ #[inline(always)]
+ fn enforce_alignment(ecx: &InterpCx<'mir, 'tcx, Self>) -> bool {
+ ecx.tcx.sess.opts.unstable_opts.extra_const_ub_checks
+ }
+
+ #[inline(always)]
+ fn enforce_validity(ecx: &InterpCx<'mir, 'tcx, Self>) -> bool {
+ ecx.tcx.sess.opts.unstable_opts.extra_const_ub_checks
+ }
+
fn load_mir(
ecx: &InterpCx<'mir, 'tcx, Self>,
instance: ty::InstanceDef<'tcx>,
type AllocExtra = ();
type FrameExtra = ();
- #[inline(always)]
- fn enforce_alignment(_ecx: &InterpCx<$mir, $tcx, Self>) -> bool {
- // We do not check for alignment to avoid having to carry an `Align`
- // in `ConstValue::ByRef`.
- false
- }
-
#[inline(always)]
fn force_int_for_alignment_check(_ecx: &InterpCx<$mir, $tcx, Self>) -> bool {
// We do not support `force_int`.
false
}
- #[inline(always)]
- fn enforce_validity(_ecx: &InterpCx<$mir, $tcx, Self>) -> bool {
- false // for now, we don't enforce validity
- }
-
#[inline(always)]
fn enforce_number_init(_ecx: &InterpCx<$mir, $tcx, Self>) -> bool {
true
/// It will error if the bits at the destination do not match the ones described by the layout.
#[inline(always)]
pub fn validate_operand(&self, op: &OpTy<'tcx, M::Provenance>) -> InterpResult<'tcx> {
+ // Note that we *could* actually be in CTFE here with `-Zextra-const-ub-checks`, but it's
+ // still correct to not use `ctfe_mode`: that mode is for validation of the final constant
+ // value, it rules out things like `UnsafeCell` in awkward places. It also can make checking
+ // recurse through references which, for now, we don't want here, either.
self.validate_operand_internal(op, vec![], None, None)
}
}
#![feature(control_flow_enum)]
#![feature(decl_macro)]
#![feature(exact_size_is_empty)]
-#![cfg_attr(bootstrap, feature(let_chains))]
#![feature(let_else)]
#![feature(map_try_insert)]
#![feature(min_specialization)]
let mut promoted_operand = |ty, span| {
promoted.span = span;
promoted.local_decls[RETURN_PLACE] = LocalDecl::new(ty, span);
+ let substs = tcx.erase_regions(InternalSubsts::identity_for_item(tcx, def.did));
let _const = tcx.mk_const(ty::ConstS {
ty,
kind: ty::ConstKind::Unevaluated(ty::Unevaluated {
def,
- substs: InternalSubsts::for_item(tcx, def.did, |param, _| {
- if let ty::GenericParamDefKind::Lifetime = param.kind {
- tcx.lifetimes.re_erased.into()
- } else {
- tcx.mk_param_from_def(param)
- }
- }),
+ substs,
promoted: Some(promoted_id),
}),
});
-borrowck-move-unsized =
+borrowck_move_unsized =
cannot move a value of type `{$ty}`
.label = the size of `{$ty}` cannot be statically determined
-borrowck-higher-ranked-lifetime-error =
+borrowck_higher_ranked_lifetime_error =
higher-ranked lifetime error
-borrowck-could-not-prove =
+borrowck_could_not_prove =
could not prove `{$predicate}`
-borrowck-could-not-normalize =
+borrowck_could_not_normalize =
could not normalize `{$value}`
-borrowck-higher-ranked-subtype-error =
+borrowck_higher_ranked_subtype_error =
higher-ranked subtype error
-generic-does-not-live-long-enough =
+generic_does_not_live_long_enough =
`{$kind}` does not live long enough
\ No newline at end of file
-builtin-macros-requires-cfg-pattern =
+builtin_macros_requires_cfg_pattern =
macro requires a cfg-pattern as an argument
.label = cfg-pattern required
-builtin-macros-expected-one-cfg-pattern = expected 1 cfg-pattern
+builtin_macros_expected_one_cfg_pattern = expected 1 cfg-pattern
-const-eval-unstable-in-stable =
+const_eval_unstable_in_stable =
const-stable function cannot use `#[feature({$gate})]`
- .unstable-sugg = if it is not part of the public API, make this function unstably const
- .bypass-sugg = otherwise `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks
+ .unstable_sugg = if it is not part of the public API, make this function unstably const
+ .bypass_sugg = otherwise `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks
-const-eval-thread-local-access =
+const_eval_thread_local_access =
thread-local statics cannot be accessed at compile-time
-const-eval-static-access =
+const_eval_static_access =
{$kind}s cannot refer to statics
.help = consider extracting the value of the `static` to a `const`, and referring to that
- .teach-note = `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable.
- .teach-help = To fix this, the value can be extracted to a `const` and then used.
+ .teach_note = `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable.
+ .teach_help = To fix this, the value can be extracted to a `const` and then used.
-const-eval-raw-ptr-to-int =
+const_eval_raw_ptr_to_int =
pointers cannot be cast to integers during const eval
.note = at compile-time, pointers do not have an integer value
.note2 = avoiding this restriction via `transmute`, `union`, or raw pointers leads to compile-time undefined behavior
-const-eval-raw-ptr-comparison =
+const_eval_raw_ptr_comparison =
pointers cannot be reliably compared during const eval
.note = see issue #53020 <https://github.com/rust-lang/rust/issues/53020> for more information
-const-eval-panic-non-str = argument to `panic!()` in a const context must have type `&str`
+const_eval_panic_non_str = argument to `panic!()` in a const context must have type `&str`
-const-eval-mut-deref =
+const_eval_mut_deref =
mutation through a reference is not allowed in {$kind}s
-const-eval-transient-mut-borrow = mutable references are not allowed in {$kind}s
+const_eval_transient_mut_borrow = mutable references are not allowed in {$kind}s
-const-eval-transient-mut-borrow-raw = raw mutable references are not allowed in {$kind}s
+const_eval_transient_mut_borrow_raw = raw mutable references are not allowed in {$kind}s
-expand-explain-doc-comment-outer =
+expand_explain_doc_comment_outer =
outer doc comments expand to `#[doc = "..."]`, which is what this macro attempted to match
-expand-explain-doc-comment-inner =
+expand_explain_doc_comment_inner =
inner doc comments expand to `#![doc = "..."]`, which is what this macro attempted to match
-lint-array-into-iter =
+lint_array_into_iter =
this method call resolves to `<&{$target} as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to <{$target} as IntoIterator>::into_iter in Rust 2021
- .use-iter-suggestion = use `.iter()` instead of `.into_iter()` to avoid ambiguity
- .remove-into-iter-suggestion = or remove `.into_iter()` to iterate by value
- .use-explicit-into-iter-suggestion =
+ .use_iter_suggestion = use `.iter()` instead of `.into_iter()` to avoid ambiguity
+ .remove_into_iter_suggestion = or remove `.into_iter()` to iterate by value
+ .use_explicit_into_iter_suggestion =
or use `IntoIterator::into_iter(..)` instead of `.into_iter()` to explicitly iterate by value
-lint-enum-intrinsics-mem-discriminant =
+lint_enum_intrinsics_mem_discriminant =
the return value of `mem::discriminant` is unspecified when called with a non-enum type
.note = the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `{$ty_param}`, which is not an enum.
-lint-enum-intrinsics-mem-variant =
+lint_enum_intrinsics_mem_variant =
the return value of `mem::variant_count` is unspecified when called with a non-enum type
.note = the type parameter of `variant_count` should be an enum, but it was instantiated with the type `{$ty_param}`, which is not an enum.
-lint-expectation = this lint expectation is unfulfilled
+lint_expectation = this lint expectation is unfulfilled
.note = the `unfulfilled_lint_expectations` lint can't be expected and will always produce this message
-lint-hidden-unicode-codepoints = unicode codepoint changing visible direction of text present in {$label}
+lint_hidden_unicode_codepoints = unicode codepoint changing visible direction of text present in {$label}
.label = this {$label} contains {$count ->
[one] an invisible
*[other] invisible
*[other] codepoints
}
.note = these kind of unicode codepoints change the way text flows on applications that support them, but can cause confusion because they change the order of characters on the screen
- .suggestion-remove = if their presence wasn't intentional, you can remove them
- .suggestion-escape = if you want to keep them but make them visible in your source code, you can escape them
- .no-suggestion-note-escape = if you want to keep them but make them visible in your source code, you can escape them: {$escaped}
+ .suggestion_remove = if their presence wasn't intentional, you can remove them
+ .suggestion_escape = if you want to keep them but make them visible in your source code, you can escape them
+ .no_suggestion_note_escape = if you want to keep them but make them visible in your source code, you can escape them: {$escaped}
-lint-default-hash-types = prefer `{$preferred}` over `{$used}`, it has better performance
+lint_default_hash_types = prefer `{$preferred}` over `{$used}`, it has better performance
.note = a `use rustc_data_structures::fx::{$preferred}` may be necessary
-lint-query-instability = using `{$query}` can result in unstable query results
+lint_query_instability = using `{$query}` can result in unstable query results
.note = if you believe this case to be fine, allow this lint and add a comment explaining your rationale
-lint-tykind-kind = usage of `ty::TyKind::<kind>`
+lint_tykind_kind = usage of `ty::TyKind::<kind>`
.suggestion = try using `ty::<kind>` directly
-lint-tykind = usage of `ty::TyKind`
+lint_tykind = usage of `ty::TyKind`
.help = try using `Ty` instead
-lint-ty-qualified = usage of qualified `ty::{$ty}`
+lint_ty_qualified = usage of qualified `ty::{$ty}`
.suggestion = try importing it and using it unqualified
-lint-lintpass-by-hand = implementing `LintPass` by hand
+lint_lintpass_by_hand = implementing `LintPass` by hand
.help = try using `declare_lint_pass!` or `impl_lint_pass!` instead
-lint-non-existant-doc-keyword = found non-existing keyword `{$keyword}` used in `#[doc(keyword = \"...\")]`
+lint_non_existant_doc_keyword = found non-existing keyword `{$keyword}` used in `#[doc(keyword = \"...\")]`
.help = only existing keywords are allowed in core/std
-lint-diag-out-of-impl =
+lint_diag_out_of_impl =
diagnostics should only be created in `SessionDiagnostic`/`AddSubdiagnostic` impls
-lint-untranslatable-diag = diagnostics should be created using translatable messages
+lint_untranslatable_diag = diagnostics should be created using translatable messages
-lint-cstring-ptr = getting the inner pointer of a temporary `CString`
- .as-ptr-label = this pointer will be invalid
- .unwrap-label = this `CString` is deallocated at the end of the statement, bind it to a variable to extend its lifetime
+lint_cstring_ptr = getting the inner pointer of a temporary `CString`
+ .as_ptr_label = this pointer will be invalid
+ .unwrap_label = this `CString` is deallocated at the end of the statement, bind it to a variable to extend its lifetime
.note = pointers do not have a lifetime; when calling `as_ptr` the `CString` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned
.help = for more information, see https://doc.rust-lang.org/reference/destructors.html
-lint-identifier-non-ascii-char = identifier contains non-ASCII characters
+lint_identifier_non_ascii_char = identifier contains non-ASCII characters
-lint-identifier-uncommon-codepoints = identifier contains uncommon Unicode codepoints
+lint_identifier_uncommon_codepoints = identifier contains uncommon Unicode codepoints
-lint-confusable-identifier-pair = identifier pair considered confusable between `{$existing_sym}` and `{$sym}`
+lint_confusable_identifier_pair = identifier pair considered confusable between `{$existing_sym}` and `{$sym}`
.label = this is where the previous identifier occurred
-lint-mixed-script-confusables =
+lint_mixed_script_confusables =
the usage of Script Group `{$set}` in this crate consists solely of mixed script confusables
- .includes-note = the usage includes {$includes}
+ .includes_note = the usage includes {$includes}
.note = please recheck to make sure their usages are indeed what you want
-lint-non-fmt-panic = panic message is not a string literal
+lint_non_fmt_panic = panic message is not a string literal
.note = this usage of `{$name}!()` is deprecated; it will be a hard error in Rust 2021
- .more-info-note = for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
- .supports-fmt-note = the `{$name}!()` macro supports formatting, so there's no need for the `format!()` macro here
- .supports-fmt-suggestion = remove the `format!(..)` macro call
- .display-suggestion = add a "{"{"}{"}"}" format string to `Display` the message
- .debug-suggestion =
+ .more_info_note = for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
+ .supports_fmt_note = the `{$name}!()` macro supports formatting, so there's no need for the `format!()` macro here
+ .supports_fmt_suggestion = remove the `format!(..)` macro call
+ .display_suggestion = add a "{"{"}{"}"}" format string to `Display` the message
+ .debug_suggestion =
add a "{"{"}:?{"}"}" format string to use the `Debug` implementation of `{$ty}`
- .panic-suggestion = {$already_suggested ->
+ .panic_suggestion = {$already_suggested ->
[true] or use
*[false] use
} std::panic::panic_any instead
-lint-non-fmt-panic-unused =
+lint_non_fmt_panic_unused =
panic message contains {$count ->
[one] an unused
*[other] unused
*[other] placeholders
}
.note = this message is not used as a format string when given without arguments, but will be in Rust 2021
- .add-args-suggestion = add the missing {$count ->
+ .add_args_suggestion = add the missing {$count ->
[one] argument
*[other] arguments
}
- .add-fmt-suggestion = or add a "{"{"}{"}"}" format string to use the message literally
+ .add_fmt_suggestion = or add a "{"{"}{"}"}" format string to use the message literally
-lint-non-fmt-panic-braces =
+lint_non_fmt_panic_braces =
panic message contains {$count ->
[one] a brace
*[other] braces
.note = this message is not used as a format string, but will be in Rust 2021
.suggestion = add a "{"{"}{"}"}" format string to use the message literally
-lint-non-camel-case-type = {$sort} `{$name}` should have an upper camel case name
+lint_non_camel_case_type = {$sort} `{$name}` should have an upper camel case name
.suggestion = convert the identifier to upper camel case
.label = should have an UpperCamelCase name
-lint-non-snake-case = {$sort} `{$name}` should have a snake case name
- .rename-or-convert-suggestion = rename the identifier or convert it to a snake case raw identifier
- .cannot-convert-note = `{$sc}` cannot be used as a raw identifier
- .rename-suggestion = rename the identifier
- .convert-suggestion = convert the identifier to snake case
+lint_non_snake_case = {$sort} `{$name}` should have a snake case name
+ .rename_or_convert_suggestion = rename the identifier or convert it to a snake case raw identifier
+ .cannot_convert_note = `{$sc}` cannot be used as a raw identifier
+ .rename_suggestion = rename the identifier
+ .convert_suggestion = convert the identifier to snake case
.help = convert the identifier to snake case: `{$sc}`
.label = should have a snake_case name
-lint-non-upper_case-global = {$sort} `{$name}` should have an upper case name
+lint_non_upper_case_global = {$sort} `{$name}` should have an upper case name
.suggestion = convert the identifier to upper case
.label = should have an UPPER_CASE name
-lint-noop-method-call = call to `.{$method}()` on a reference in this situation does nothing
+lint_noop_method_call = call to `.{$method}()` on a reference in this situation does nothing
.label = unnecessary method call
.note = the type `{$receiver_ty}` which `{$method}` is being called on is the same as the type returned from `{$method}`, so the method call does not do anything and can be removed
-lint-pass-by-value = passing `{$ty}` by reference
+lint_pass_by_value = passing `{$ty}` by reference
.suggestion = try passing by value
-lint-redundant-semicolons =
+lint_redundant_semicolons =
unnecessary trailing {$multiple ->
[true] semicolons
*[false] semicolon
*[false] this semicolon
}
-lint-drop-trait-constraints =
+lint_drop_trait_constraints =
bounds on `{$predicate}` are most likely incorrect, consider instead using `{$needs_drop}` to detect whether a type can be trivially dropped
-lint-drop-glue =
+lint_drop_glue =
types that do not implement `Drop` can still have drop glue, consider instead using `{$needs_drop}` to detect whether a type is trivially dropped
-lint-range-endpoint-out-of-range = range endpoint is out of range for `{$ty}`
+lint_range_endpoint_out_of_range = range endpoint is out of range for `{$ty}`
.suggestion = use an inclusive range instead
-lint-overflowing-bin-hex = literal out of range for `{$ty}`
- .negative-note = the literal `{$lit}` (decimal `{$dec}`) does not fit into the type `{$ty}`
- .negative-becomes-note = and the value `-{$lit}` will become `{$actually}{$ty}`
- .positive-note = the literal `{$lit}` (decimal `{$dec}`) does not fit into the type `{$ty}` and will become `{$actually}{$ty}`
+lint_overflowing_bin_hex = literal out of range for `{$ty}`
+ .negative_note = the literal `{$lit}` (decimal `{$dec}`) does not fit into the type `{$ty}`
+ .negative_becomes_note = and the value `-{$lit}` will become `{$actually}{$ty}`
+ .positive_note = the literal `{$lit}` (decimal `{$dec}`) does not fit into the type `{$ty}` and will become `{$actually}{$ty}`
.suggestion = consider using the type `{$suggestion_ty}` instead
.help = consider using the type `{$suggestion_ty}` instead
-lint-overflowing-int = literal out of range for `{$ty}`
+lint_overflowing_int = literal out of range for `{$ty}`
.note = the literal `{$lit}` does not fit into the type `{$ty}` whose range is `{$min}..={$max}`
.help = consider using the type `{$suggestion_ty}` instead
-lint-only-cast-u8-to-char = only `u8` can be cast into `char`
+lint_only_cast_u8_to_char = only `u8` can be cast into `char`
.suggestion = use a `char` literal instead
-lint-overflowing-uint = literal out of range for `{$ty}`
+lint_overflowing_uint = literal out of range for `{$ty}`
.note = the literal `{$lit}` does not fit into the type `{$ty}` whose range is `{$min}..={$max}`
-lint-overflowing-literal = literal out of range for `{$ty}`
+lint_overflowing_literal = literal out of range for `{$ty}`
.note = the literal `{$lit}` does not fit into the type `{$ty}` and will be converted to `{$ty}::INFINITY`
-lint-unused-comparisons = comparison is useless due to type limits
+lint_unused_comparisons = comparison is useless due to type limits
-lint-improper-ctypes = `extern` {$desc} uses type `{$ty}`, which is not FFI-safe
+lint_improper_ctypes = `extern` {$desc} uses type `{$ty}`, which is not FFI-safe
.label = not FFI-safe
.note = the type is defined here
-lint-improper-ctypes-opaque = opaque types have no C equivalent
+lint_improper_ctypes_opaque = opaque types have no C equivalent
-lint-improper-ctypes-fnptr-reason = this function pointer has Rust-specific calling convention
-lint-improper-ctypes-fnptr-help = consider using an `extern fn(...) -> ...` function pointer instead
+lint_improper_ctypes_fnptr_reason = this function pointer has Rust-specific calling convention
+lint_improper_ctypes_fnptr_help = consider using an `extern fn(...) -> ...` function pointer instead
-lint-improper-ctypes-tuple-reason = tuples have unspecified layout
-lint-improper-ctypes-tuple-help = consider using a struct instead
+lint_improper_ctypes_tuple_reason = tuples have unspecified layout
+lint_improper_ctypes_tuple_help = consider using a struct instead
-lint-improper-ctypes-str-reason = string slices have no C equivalent
-lint-improper-ctypes-str-help = consider using `*const u8` and a length instead
+lint_improper_ctypes_str_reason = string slices have no C equivalent
+lint_improper_ctypes_str_help = consider using `*const u8` and a length instead
-lint-improper-ctypes-dyn = trait objects have no C equivalent
+lint_improper_ctypes_dyn = trait objects have no C equivalent
-lint-improper-ctypes-slice-reason = slices have no C equivalent
-lint-improper-ctypes-slice-help = consider using a raw pointer instead
+lint_improper_ctypes_slice_reason = slices have no C equivalent
+lint_improper_ctypes_slice_help = consider using a raw pointer instead
-lint-improper-ctypes-128bit = 128-bit integers don't currently have a known stable ABI
+lint_improper_ctypes_128bit = 128-bit integers don't currently have a known stable ABI
-lint-improper-ctypes-char-reason = the `char` type has no C equivalent
-lint-improper-ctypes-char-help = consider using `u32` or `libc::wchar_t` instead
+lint_improper_ctypes_char_reason = the `char` type has no C equivalent
+lint_improper_ctypes_char_help = consider using `u32` or `libc::wchar_t` instead
-lint-improper-ctypes-non-exhaustive = this enum is non-exhaustive
-lint-improper-ctypes-non-exhaustive-variant = this enum has non-exhaustive variants
+lint_improper_ctypes_non_exhaustive = this enum is non-exhaustive
+lint_improper_ctypes_non_exhaustive_variant = this enum has non-exhaustive variants
-lint-improper-ctypes-enum-repr-reason = enum has no representation hint
-lint-improper-ctypes-enum-repr-help =
+lint_improper_ctypes_enum_repr_reason = enum has no representation hint
+lint_improper_ctypes_enum_repr_help =
consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
-lint-improper-ctypes-struct-fieldless-reason = this struct has no fields
-lint-improper-ctypes-struct-fieldless-help = consider adding a member to this struct
+lint_improper_ctypes_struct_fieldless_reason = this struct has no fields
+lint_improper_ctypes_struct_fieldless_help = consider adding a member to this struct
-lint-improper-ctypes-union-fieldless-reason = this union has no fields
-lint-improper-ctypes-union-fieldless-help = consider adding a member to this union
+lint_improper_ctypes_union_fieldless_reason = this union has no fields
+lint_improper_ctypes_union_fieldless_help = consider adding a member to this union
-lint-improper-ctypes-struct-non-exhaustive = this struct is non-exhaustive
-lint-improper-ctypes-union-non-exhaustive = this union is non-exhaustive
+lint_improper_ctypes_struct_non_exhaustive = this struct is non-exhaustive
+lint_improper_ctypes_union_non_exhaustive = this union is non-exhaustive
-lint-improper-ctypes-struct-layout-reason = this struct has unspecified layout
-lint-improper-ctypes-struct-layout-help = consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
+lint_improper_ctypes_struct_layout_reason = this struct has unspecified layout
+lint_improper_ctypes_struct_layout_help = consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
-lint-improper-ctypes-union-layout-reason = this union has unspecified layout
-lint-improper-ctypes-union-layout-help = consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this union
+lint_improper_ctypes_union_layout_reason = this union has unspecified layout
+lint_improper_ctypes_union_layout_help = consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this union
-lint-improper-ctypes-box = box cannot be represented as a single pointer
+lint_improper_ctypes_box = box cannot be represented as a single pointer
-lint-improper-ctypes-enum-phantomdata = this enum contains a PhantomData field
+lint_improper_ctypes_enum_phantomdata = this enum contains a PhantomData field
-lint-improper-ctypes-struct-zst = this struct contains only zero-sized fields
+lint_improper_ctypes_struct_zst = this struct contains only zero-sized fields
-lint-improper-ctypes-array-reason = passing raw arrays by value is not FFI-safe
-lint-improper-ctypes-array-help = consider passing a pointer to the array
+lint_improper_ctypes_array_reason = passing raw arrays by value is not FFI-safe
+lint_improper_ctypes_array_help = consider passing a pointer to the array
-lint-improper-ctypes-only-phantomdata = composed only of `PhantomData`
+lint_improper_ctypes_only_phantomdata = composed only of `PhantomData`
-lint-variant-size-differences =
+lint_variant_size_differences =
enum variant is more than three times larger ({$largest} bytes) than the next largest
-lint-atomic-ordering-load = atomic loads cannot have `Release` or `AcqRel` ordering
+lint_atomic_ordering_load = atomic loads cannot have `Release` or `AcqRel` ordering
.help = consider using ordering modes `Acquire`, `SeqCst` or `Relaxed`
-lint-atomic-ordering-store = atomic stores cannot have `Acquire` or `AcqRel` ordering
+lint_atomic_ordering_store = atomic stores cannot have `Acquire` or `AcqRel` ordering
.help = consider using ordering modes `Release`, `SeqCst` or `Relaxed`
-lint-atomic-ordering-fence = memory fences cannot have `Relaxed` ordering
+lint_atomic_ordering_fence = memory fences cannot have `Relaxed` ordering
.help = consider using ordering modes `Acquire`, `Release`, `AcqRel` or `SeqCst`
-lint-atomic-ordering-invalid = `{$method}`'s failure ordering may not be `Release` or `AcqRel`, since a failed `{$method}` does not result in a write
+lint_atomic_ordering_invalid = `{$method}`'s failure ordering may not be `Release` or `AcqRel`, since a failed `{$method}` does not result in a write
.label = invalid failure ordering
.help = consider using `Acquire` or `Relaxed` failure ordering instead
-lint-unused-op = unused {$op} that must be used
+lint_unused_op = unused {$op} that must be used
.label = the {$op} produces a value
.suggestion = use `let _ = ...` to ignore the resulting value
-lint-unused-result = unused result of type `{$ty}`
+lint_unused_result = unused result of type `{$ty}`
-lint-unused-closure =
+lint_unused_closure =
unused {$pre}{$count ->
[one] closure
*[other] closures
}{$post} that must be used
.note = closures are lazy and do nothing unless called
-lint-unused-generator =
+lint_unused_generator =
unused {$pre}{$count ->
[one] generator
*[other] generator
}{$post} that must be used
.note = generators are lazy and do nothing unless resumed
-lint-unused-def = unused {$pre}`{$def}`{$post} that must be used
+lint_unused_def = unused {$pre}`{$def}`{$post} that must be used
-lint-path-statement-drop = path statement drops value
+lint_path_statement_drop = path statement drops value
.suggestion = use `drop` to clarify the intent
-lint-path-statement-no-effect = path statement with no effect
+lint_path_statement_no_effect = path statement with no effect
-lint-unused-delim = unnecessary {$delim} around {$item}
+lint_unused_delim = unnecessary {$delim} around {$item}
.suggestion = remove these {$delim}
-lint-unused-import-braces = braces around {$node} is unnecessary
+lint_unused_import_braces = braces around {$node} is unnecessary
-lint-unused-allocation = unnecessary allocation, use `&` instead
-lint-unused-allocation-mut = unnecessary allocation, use `&mut` instead
+lint_unused_allocation = unnecessary allocation, use `&` instead
+lint_unused_allocation_mut = unnecessary allocation, use `&mut` instead
-lint-builtin-while-true = denote infinite loops with `loop {"{"} ... {"}"}`
+lint_builtin_while_true = denote infinite loops with `loop {"{"} ... {"}"}`
.suggestion = use `loop`
-lint-builtin-box-pointers = type uses owned (Box type) pointers: {$ty}
+lint_builtin_box_pointers = type uses owned (Box type) pointers: {$ty}
-lint-builtin-non-shorthand-field-patterns = the `{$ident}:` in this pattern is redundant
+lint_builtin_non_shorthand_field_patterns = the `{$ident}:` in this pattern is redundant
.suggestion = use shorthand field pattern
-lint-builtin-overridden-symbol-name =
+lint_builtin_overridden_symbol_name =
the linker's behavior with multiple libraries exporting duplicate symbol names is undefined and Rust cannot provide guarantees when you manually override them
-lint-builtin-overridden-symbol-section =
+lint_builtin_overridden_symbol_section =
the program's behavior with overridden link sections on items is unpredictable and Rust cannot provide guarantees when you manually override them
-lint-builtin-allow-internal-unsafe =
+lint_builtin_allow_internal_unsafe =
`allow_internal_unsafe` allows defining macros using unsafe without triggering the `unsafe_code` lint at their call site
-lint-builtin-unsafe-block = usage of an `unsafe` block
+lint_builtin_unsafe_block = usage of an `unsafe` block
-lint-builtin-unsafe-trait = declaration of an `unsafe` trait
+lint_builtin_unsafe_trait = declaration of an `unsafe` trait
-lint-builtin-unsafe-impl = implementation of an `unsafe` trait
+lint_builtin_unsafe_impl = implementation of an `unsafe` trait
-lint-builtin-no-mangle-fn = declaration of a `no_mangle` function
-lint-builtin-export-name-fn = declaration of a function with `export_name`
-lint-builtin-link-section-fn = declaration of a function with `link_section`
+lint_builtin_no_mangle_fn = declaration of a `no_mangle` function
+lint_builtin_export_name_fn = declaration of a function with `export_name`
+lint_builtin_link_section_fn = declaration of a function with `link_section`
-lint-builtin-no-mangle-static = declaration of a `no_mangle` static
-lint-builtin-export-name-static = declaration of a static with `export_name`
-lint-builtin-link-section-static = declaration of a static with `link_section`
+lint_builtin_no_mangle_static = declaration of a `no_mangle` static
+lint_builtin_export_name_static = declaration of a static with `export_name`
+lint_builtin_link_section_static = declaration of a static with `link_section`
-lint-builtin-no-mangle-method = declaration of a `no_mangle` method
-lint-builtin-export-name-method = declaration of a method with `export_name`
+lint_builtin_no_mangle_method = declaration of a `no_mangle` method
+lint_builtin_export_name_method = declaration of a method with `export_name`
-lint-builtin-decl-unsafe-fn = declaration of an `unsafe` function
-lint-builtin-decl-unsafe-method = declaration of an `unsafe` method
-lint-builtin-impl-unsafe-method = implementation of an `unsafe` method
+lint_builtin_decl_unsafe_fn = declaration of an `unsafe` function
+lint_builtin_decl_unsafe_method = declaration of an `unsafe` method
+lint_builtin_impl_unsafe_method = implementation of an `unsafe` method
-lint-builtin-missing-doc = missing documentation for {$article} {$desc}
+lint_builtin_missing_doc = missing documentation for {$article} {$desc}
-lint-builtin-missing-copy-impl = type could implement `Copy`; consider adding `impl Copy`
+lint_builtin_missing_copy_impl = type could implement `Copy`; consider adding `impl Copy`
-lint-builtin-missing-debug-impl =
+lint_builtin_missing_debug_impl =
type does not implement `{$debug}`; consider adding `#[derive(Debug)]` or a manual implementation
-lint-builtin-anonymous-params = anonymous parameters are deprecated and will be removed in the next edition
+lint_builtin_anonymous_params = anonymous parameters are deprecated and will be removed in the next edition
.suggestion = try naming the parameter or explicitly ignoring it
-lint-builtin-deprecated-attr-link = use of deprecated attribute `{$name}`: {$reason}. See {$link}
-lint-builtin-deprecated-attr-used = use of deprecated attribute `{$name}`: no longer used.
-lint-builtin-deprecated-attr-default-suggestion = remove this attribute
+lint_builtin_deprecated_attr_link = use of deprecated attribute `{$name}`: {$reason}. See {$link}
+lint_builtin_deprecated_attr_used = use of deprecated attribute `{$name}`: no longer used.
+lint_builtin_deprecated_attr_default_suggestion = remove this attribute
-lint-builtin-unused-doc-comment = unused doc comment
+lint_builtin_unused_doc_comment = unused doc comment
.label = rustdoc does not generate documentation for {$kind}
- .plain-help = use `//` for a plain comment
- .block-help = use `/* */` for a plain comment
+ .plain_help = use `//` for a plain comment
+ .block_help = use `/* */` for a plain comment
-lint-builtin-no-mangle-generic = functions generic over types or consts must be mangled
+lint_builtin_no_mangle_generic = functions generic over types or consts must be mangled
.suggestion = remove this attribute
-lint-builtin-const-no-mangle = const items should never be `#[no_mangle]`
+lint_builtin_const_no_mangle = const items should never be `#[no_mangle]`
.suggestion = try a static value
-lint-builtin-mutable-transmutes =
+lint_builtin_mutable_transmutes =
transmuting &T to &mut T is undefined behavior, even if the reference is unused, consider instead using an UnsafeCell
-lint-builtin-unstable-features = unstable feature
+lint_builtin_unstable_features = unstable feature
-lint-builtin-unreachable-pub = unreachable `pub` {$what}
+lint_builtin_unreachable_pub = unreachable `pub` {$what}
.suggestion = consider restricting its visibility
.help = or consider exporting it for use by other crates
-lint-builtin-type-alias-bounds-help = use fully disambiguated paths (i.e., `<T as Trait>::Assoc`) to refer to associated types in type aliases
+lint_builtin_type_alias_bounds_help = use fully disambiguated paths (i.e., `<T as Trait>::Assoc`) to refer to associated types in type aliases
-lint-builtin-type-alias-where-clause = where clauses are not enforced in type aliases
+lint_builtin_type_alias_where_clause = where clauses are not enforced in type aliases
.suggestion = the clause will not be checked when the type alias is used, and should be removed
-lint-builtin-type-alias-generic-bounds = bounds on generic parameters are not enforced in type aliases
+lint_builtin_type_alias_generic_bounds = bounds on generic parameters are not enforced in type aliases
.suggestion = the bound will not be checked when the type alias is used, and should be removed
-lint-builtin-trivial-bounds = {$predicate_kind_name} bound {$predicate} does not depend on any type or lifetime parameters
+lint_builtin_trivial_bounds = {$predicate_kind_name} bound {$predicate} does not depend on any type or lifetime parameters
-lint-builtin-ellipsis-inclusive-range-patterns = `...` range patterns are deprecated
+lint_builtin_ellipsis_inclusive_range_patterns = `...` range patterns are deprecated
.suggestion = use `..=` for an inclusive range
-lint-builtin-unnameable-test-items = cannot test inner items
+lint_builtin_unnameable_test_items = cannot test inner items
-lint-builtin-keyword-idents = `{$kw}` is a keyword in the {$next} edition
+lint_builtin_keyword_idents = `{$kw}` is a keyword in the {$next} edition
.suggestion = you can use a raw identifier to stay compatible
-lint-builtin-explicit-outlives = outlives requirements can be inferred
+lint_builtin_explicit_outlives = outlives requirements can be inferred
.suggestion = remove {$count ->
[one] this bound
*[other] these bounds
}
-lint-builtin-incomplete-features = the feature `{$name}` is incomplete and may not be safe to use and/or cause compiler crashes
+lint_builtin_incomplete_features = the feature `{$name}` is incomplete and may not be safe to use and/or cause compiler crashes
.note = see issue #{$n} <https://github.com/rust-lang/rust/issues/{$n}> for more information
.help = consider using `min_{$name}` instead, which is more stable and complete
-lint-builtin-clashing-extern-same-name = `{$this_fi}` redeclared with a different signature
- .previous-decl-label = `{$orig}` previously declared here
- .mismatch-label = this signature doesn't match the previous declaration
-lint-builtin-clashing-extern-diff-name = `{$this_fi}` redeclares `{$orig}` with a different signature
- .previous-decl-label = `{$orig}` previously declared here
- .mismatch-label = this signature doesn't match the previous declaration
+lint_builtin_clashing_extern_same_name = `{$this_fi}` redeclared with a different signature
+ .previous_decl_label = `{$orig}` previously declared here
+ .mismatch_label = this signature doesn't match the previous declaration
+lint_builtin_clashing_extern_diff_name = `{$this_fi}` redeclares `{$orig}` with a different signature
+ .previous_decl_label = `{$orig}` previously declared here
+ .mismatch_label = this signature doesn't match the previous declaration
-lint-builtin-deref-nullptr = dereferencing a null pointer
+lint_builtin_deref_nullptr = dereferencing a null pointer
.label = this code causes undefined behavior when executed
-lint-builtin-asm-labels = avoid using named labels in inline assembly
+lint_builtin_asm_labels = avoid using named labels in inline assembly
-parser-struct-literal-body-without-path =
+parser_struct_literal_body_without_path =
struct literal body without path
.suggestion = you might have forgotten to add the struct literal inside the block
-parser-maybe-report-ambiguous-plus =
+parser_maybe_report_ambiguous_plus =
ambiguous `+` in a type
.suggestion = use parentheses to disambiguate
-parser-maybe-recover-from-bad-type-plus =
+parser_maybe_recover_from_bad_type_plus =
expected a path on the left-hand side of `+`, not `{$ty}`
-parser-add-paren = try adding parentheses
+parser_add_paren = try adding parentheses
-parser-forgot-paren = perhaps you forgot parentheses?
+parser_forgot_paren = perhaps you forgot parentheses?
-parser-expect-path = expected a path
+parser_expect_path = expected a path
-parser-maybe-recover-from-bad-qpath-stage-2 =
+parser_maybe_recover_from_bad_qpath_stage_2 =
missing angle brackets in associated item path
.suggestion = try: `{$ty}`
-parser-incorrect-semicolon =
+parser_incorrect_semicolon =
expected item, found `;`
.suggestion = remove this semicolon
.help = {$name} declarations are not followed by a semicolon
-parser-incorrect-use-of-await =
+parser_incorrect_use_of_await =
incorrect use of `await`
- .parentheses-suggestion = `await` is not a method call, remove the parentheses
- .postfix-suggestion = `await` is a postfix operation
+ .parentheses_suggestion = `await` is not a method call, remove the parentheses
+ .postfix_suggestion = `await` is a postfix operation
-parser-in-in-typo =
+parser_in_in_typo =
expected iterable, found keyword `in`
.suggestion = remove the duplicated `in`
--passes-previously-accepted =
+-passes_previously_accepted =
this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
--passes-see-issue =
+-passes_see_issue =
see issue #{$issue} <https://github.com/rust-lang/rust/issues/{$issue}> for more information
-passes-outer-crate-level-attr =
+passes_outer_crate_level_attr =
crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-passes-inner-crate-level-attr =
+passes_inner_crate_level_attr =
crate-level attribute should be in the root module
-passes-ignored-attr-with-macro = `#[{$sym}]` is ignored on struct fields, match arms and macro defs
- .warn = {-passes-previously-accepted}
- .note = {-passes-see-issue(issue: "80564")}
+passes_ignored_attr_with_macro = `#[{$sym}]` is ignored on struct fields, match arms and macro defs
+ .warn = {-passes_previously_accepted}
+ .note = {-passes_see_issue(issue: "80564")}
-passes-ignored-attr = `#[{$sym}]` is ignored on struct fields and match arms
- .warn = {-passes-previously-accepted}
- .note = {-passes-see-issue(issue: "80564")}
+passes_ignored_attr = `#[{$sym}]` is ignored on struct fields and match arms
+ .warn = {-passes_previously_accepted}
+ .note = {-passes_see_issue(issue: "80564")}
-passes-inline-ignored-function-prototype = `#[inline]` is ignored on function prototypes
+passes_inline_ignored_function_prototype = `#[inline]` is ignored on function prototypes
-passes-inline-ignored-constants = `#[inline]` is ignored on constants
- .warn = {-passes-previously-accepted}
- .note = {-passes-see-issue(issue: "65833")}
+passes_inline_ignored_constants = `#[inline]` is ignored on constants
+ .warn = {-passes_previously_accepted}
+ .note = {-passes_see_issue(issue: "65833")}
-passes-inline-not-fn-or-closure = attribute should be applied to function or closure
+passes_inline_not_fn_or_closure = attribute should be applied to function or closure
.label = not a function or closure
-passes-no-coverage-ignored-function-prototype = `#[no_coverage]` is ignored on function prototypes
+passes_no_coverage_ignored_function_prototype = `#[no_coverage]` is ignored on function prototypes
-passes-no-coverage-propagate =
+passes_no_coverage_propagate =
`#[no_coverage]` does not propagate into items and must be applied to the contained functions directly
-passes-no-coverage-fn-defn = `#[no_coverage]` may only be applied to function definitions
+passes_no_coverage_fn_defn = `#[no_coverage]` may only be applied to function definitions
-passes-no-coverage-not-coverable = `#[no_coverage]` must be applied to coverable code
+passes_no_coverage_not_coverable = `#[no_coverage]` must be applied to coverable code
.label = not coverable code
-passes-should-be-applied-to-fn = attribute should be applied to a function definition
+passes_should_be_applied_to_fn = attribute should be applied to a function definition
.label = not a function definition
-passes-naked-tracked-caller = cannot use `#[track_caller]` with `#[naked]`
+passes_naked_tracked_caller = cannot use `#[track_caller]` with `#[naked]`
-passes-should-be-applied-to-struct-enum = attribute should be applied to a struct or enum
+passes_should_be_applied_to_struct_enum = attribute should be applied to a struct or enum
.label = not a struct or enum
-passes-should-be-applied-to-trait = attribute should be applied to a trait
+passes_should_be_applied_to_trait = attribute should be applied to a trait
.label = not a trait
-passes-target-feature-on-statement = {passes-should-be-applied-to-fn}
- .warn = {-passes-previously-accepted}
- .label = {passes-should-be-applied-to-fn.label}
+passes_target_feature_on_statement = {passes_should_be_applied_to_fn}
+ .warn = {-passes_previously_accepted}
+ .label = {passes_should_be_applied_to_fn.label}
-passes-should-be-applied-to-static = attribute should be applied to a static
+passes_should_be_applied_to_static = attribute should be applied to a static
.label = not a static
-passes-doc-expect-str = doc {$attr_name} attribute expects a string: #[doc({$attr_name} = "a")]
+passes_doc_expect_str = doc {$attr_name} attribute expects a string: #[doc({$attr_name} = "a")]
-passes-doc-alias-empty = {$attr_str} attribute cannot have empty value
+passes_doc_alias_empty = {$attr_str} attribute cannot have empty value
-passes-doc-alias-bad-char = {$char_} character isn't allowed in {$attr_str}
+passes_doc_alias_bad_char = {$char_} character isn't allowed in {$attr_str}
-passes-doc-alias-start-end = {$attr_str} cannot start or end with ' '
+passes_doc_alias_start_end = {$attr_str} cannot start or end with ' '
-passes-doc-alias-bad-location = {$attr_str} isn't allowed on {$location}
+passes_doc_alias_bad_location = {$attr_str} isn't allowed on {$location}
-passes-doc-alias-not-an-alias = {$attr_str} is the same as the item's name
+passes_doc_alias_not_an_alias = {$attr_str} is the same as the item's name
-passes-doc-alias-duplicated = doc alias is duplicated
+passes_doc_alias_duplicated = doc alias is duplicated
.label = first defined here
-passes-doc-alias-not-string-literal = `#[doc(alias("a"))]` expects string literals
+passes_doc_alias_not_string_literal = `#[doc(alias("a"))]` expects string literals
-passes-doc-alias-malformed =
+passes_doc_alias_malformed =
doc alias attribute expects a string `#[doc(alias = "a")]` or a list of strings `#[doc(alias("a", "b"))]`
-passes-doc-keyword-empty-mod = `#[doc(keyword = "...")]` should be used on empty modules
+passes_doc_keyword_empty_mod = `#[doc(keyword = "...")]` should be used on empty modules
-passes-doc-keyword-not-mod = `#[doc(keyword = "...")]` should be used on modules
+passes_doc_keyword_not_mod = `#[doc(keyword = "...")]` should be used on modules
-passes-doc-keyword-invalid-ident = `{$doc_keyword}` is not a valid identifier
+passes_doc_keyword_invalid_ident = `{$doc_keyword}` is not a valid identifier
-passes-doc-fake-variadic-not-valid =
+passes_doc_fake_variadic_not_valid =
`#[doc(fake_variadic)]` must be used on the first of a set of tuple or fn pointer trait impls with varying arity
-passes-doc-keyword-only-impl = `#[doc(keyword = "...")]` should be used on impl blocks
+passes_doc_keyword_only_impl = `#[doc(keyword = "...")]` should be used on impl blocks
-passes-doc-inline-conflict-first = this attribute...
-passes-doc-inline-conflict-second = ...conflicts with this attribute
-passes-doc-inline-conflict = conflicting doc inlining attributes
+passes_doc_inline_conflict_first = this attribute...
+passes_doc_inline_conflict_second = ...conflicts with this attribute
+passes_doc_inline_conflict = conflicting doc inlining attributes
.help = remove one of the conflicting attributes
-passes-doc-inline-only-use = this attribute can only be applied to a `use` item
+passes_doc_inline_only_use = this attribute can only be applied to a `use` item
.label = only applicable on `use` items
- .not-a-use-item-label = not a `use` item
+ .not_a_use_item_label = not a `use` item
.note = read <https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#inline-and-no_inline> for more information
-passes-doc-attr-not-crate-level =
+passes_doc_attr_not_crate_level =
`#![doc({$attr_name} = "...")]` isn't allowed as a crate-level attribute
-passes-attr-crate-level = this attribute can only be applied at the crate level
+passes_attr_crate_level = this attribute can only be applied at the crate level
.suggestion = to apply to the crate, use an inner attribute
.help = to apply to the crate, use an inner attribute
.note = read <https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level> for more information
-passes-doc-test-unknown = unknown `doc(test)` attribute `{$path}`
+passes_doc_test_unknown = unknown `doc(test)` attribute `{$path}`
-passes-doc-test-takes-list = `#[doc(test(...)]` takes a list of attributes
+passes_doc_test_takes_list = `#[doc(test(...)]` takes a list of attributes
-passes-doc-primitive = `doc(primitive)` should never have been stable
+passes_doc_primitive = `doc(primitive)` should never have been stable
-passes-doc-test-unknown-any = unknown `doc` attribute `{$path}`
+passes_doc_test_unknown_any = unknown `doc` attribute `{$path}`
-passes-doc-test-unknown-spotlight = unknown `doc` attribute `{$path}`
+passes_doc_test_unknown_spotlight = unknown `doc` attribute `{$path}`
.note = `doc(spotlight)` was renamed to `doc(notable_trait)`
.suggestion = use `notable_trait` instead
- .no-op-note = `doc(spotlight)` is now a no-op
+ .no_op_note = `doc(spotlight)` is now a no-op
-passes-doc-test-unknown-include = unknown `doc` attribute `{$path}`
+passes_doc_test_unknown_include = unknown `doc` attribute `{$path}`
.suggestion = use `doc = include_str!` instead
-passes-doc-invalid = invalid `doc` attribute
+passes_doc_invalid = invalid `doc` attribute
-passes-pass-by-value = `pass_by_value` attribute should be applied to a struct, enum or type alias
+passes_pass_by_value = `pass_by_value` attribute should be applied to a struct, enum or type alias
.label = is not a struct, enum or type alias
-passes-allow-incoherent-impl =
+passes_allow_incoherent_impl =
`rustc_allow_incoherent_impl` attribute should be applied to impl items.
.label = the only currently supported targets are inherent methods
-passes-has-incoherent-inherent-impl =
+passes_has_incoherent_inherent_impl =
`rustc_has_incoherent_inherent_impls` attribute should be applied to types or traits.
.label = only adts, extern types and traits are supported
-passes-must-use-async =
+passes_must_use_async =
`must_use` attribute on `async` functions applies to the anonymous `Future` returned by the function, not the value within
.label = this attribute does nothing, the `Future`s returned by async functions are already `must_use`
-passes-must-use-no-effect = `#[must_use]` has no effect when applied to {$article} {$target}
+passes_must_use_no_effect = `#[must_use]` has no effect when applied to {$article} {$target}
-passes-must-not-suspend = `must_not_suspend` attribute should be applied to a struct, enum, or trait
+passes_must_not_suspend = `must_not_suspend` attribute should be applied to a struct, enum, or trait
.label = is not a struct, enum, or trait
-passes-cold = {passes-should-be-applied-to-fn}
- .warn = {-passes-previously-accepted}
- .label = {passes-should-be-applied-to-fn.label}
+passes_cold = {passes_should_be_applied_to_fn}
+ .warn = {-passes_previously_accepted}
+ .label = {passes_should_be_applied_to_fn.label}
-passes-link = attribute should be applied to an `extern` block with non-Rust ABI
- .warn = {-passes-previously-accepted}
+passes_link = attribute should be applied to an `extern` block with non-Rust ABI
+ .warn = {-passes_previously_accepted}
.label = not an `extern` block
-passes-link-name = attribute should be applied to a foreign function or static
- .warn = {-passes-previously-accepted}
+passes_link_name = attribute should be applied to a foreign function or static
+ .warn = {-passes_previously_accepted}
.label = not a foreign function or static
.help = try `#[link(name = "{$value}")]` instead
-passes-no-link = attribute should be applied to an `extern crate` item
+passes_no_link = attribute should be applied to an `extern crate` item
.label = not an `extern crate` item
-passes-export-name = attribute should be applied to a free function, impl method or static
+passes_export_name = attribute should be applied to a free function, impl method or static
.label = not a free function, impl method or static
-passes-rustc-layout-scalar-valid-range-not-struct = attribute should be applied to a struct
+passes_rustc_layout_scalar_valid_range_not_struct = attribute should be applied to a struct
.label = not a struct
-passes-rustc-layout-scalar-valid-range-arg = expected exactly one integer literal argument
+passes_rustc_layout_scalar_valid_range_arg = expected exactly one integer literal argument
-passes-rustc-legacy-const-generics-only = #[rustc_legacy_const_generics] functions must only have const generics
+passes_rustc_legacy_const_generics_only = #[rustc_legacy_const_generics] functions must only have const generics
.label = non-const generic parameter
-passes-rustc-legacy-const-generics-index = #[rustc_legacy_const_generics] must have one index for each generic parameter
+passes_rustc_legacy_const_generics_index = #[rustc_legacy_const_generics] must have one index for each generic parameter
.label = generic parameters
-passes-rustc-legacy-const-generics-index-exceed = index exceeds number of arguments
+passes_rustc_legacy_const_generics_index_exceed = index exceeds number of arguments
.label = there {$arg_count ->
[one] is
*[other] are
*[other] arguments
}
-passes-rustc-legacy-const-generics-index-negative = arguments should be non-negative integers
+passes_rustc_legacy_const_generics_index_negative = arguments should be non-negative integers
-passes-rustc-dirty-clean = attribute requires -Z query-dep-graph to be enabled
+passes_rustc_dirty_clean = attribute requires -Z query-dep-graph to be enabled
-passes-link-section = attribute should be applied to a function or static
- .warn = {-passes-previously-accepted}
+passes_link_section = attribute should be applied to a function or static
+ .warn = {-passes_previously_accepted}
.label = not a function or static
-passes-no-mangle-foreign = `#[no_mangle]` has no effect on a foreign {$foreign_item_kind}
- .warn = {-passes-previously-accepted}
+passes_no_mangle_foreign = `#[no_mangle]` has no effect on a foreign {$foreign_item_kind}
+ .warn = {-passes_previously_accepted}
.label = foreign {$foreign_item_kind}
.note = symbol names in extern blocks are not mangled
.suggestion = remove this attribute
-passes-no-mangle = attribute should be applied to a free function, impl method or static
- .warn = {-passes-previously-accepted}
+passes_no_mangle = attribute should be applied to a free function, impl method or static
+ .warn = {-passes_previously_accepted}
.label = not a free function, impl method or static
-passes-repr-ident = meta item in `repr` must be an identifier
+passes_repr_ident = meta item in `repr` must be an identifier
-passes-repr-conflicting = conflicting representation hints
+passes_repr_conflicting = conflicting representation hints
-passes-used-static = attribute must be applied to a `static` variable
+passes_used_static = attribute must be applied to a `static` variable
-passes-used-compiler-linker = `used(compiler)` and `used(linker)` can't be used together
+passes_used_compiler_linker = `used(compiler)` and `used(linker)` can't be used together
-passes-allow-internal-unstable = attribute should be applied to a macro
+passes_allow_internal_unstable = attribute should be applied to a macro
.label = not a macro
-passes-debug-visualizer-placement = attribute should be applied to a module
+passes_debug_visualizer_placement = attribute should be applied to a module
-passes-debug-visualizer-invalid = invalid argument
- .note-1 = expected: `natvis_file = "..."`
- .note-2 = OR
- .note-3 = expected: `gdb_script_file = "..."`
+passes_debug_visualizer_invalid = invalid argument
+ .note_1 = expected: `natvis_file = "..."`
+ .note_2 = OR
+ .note_3 = expected: `gdb_script_file = "..."`
-passes-rustc-allow-const-fn-unstable = attribute should be applied to `const fn`
+passes_rustc_allow_const_fn_unstable = attribute should be applied to `const fn`
.label = not a `const fn`
-passes-rustc-std-internal-symbol = attribute should be applied to functions or statics
+passes_rustc_std_internal_symbol = attribute should be applied to functions or statics
.label = not a function or static
-passes-const-trait = attribute should be applied to a trait
+passes_const_trait = attribute should be applied to a trait
-passes-stability-promotable = attribute cannot be applied to an expression
+passes_stability_promotable = attribute cannot be applied to an expression
-passes-deprecated = attribute is ignored here
+passes_deprecated = attribute is ignored here
-passes-macro-use = `#[{$name}]` only has an effect on `extern crate` and modules
+passes_macro_use = `#[{$name}]` only has an effect on `extern crate` and modules
-passes-macro-export = `#[macro_export]` only has an effect on macro definitions
+passes_macro_export = `#[macro_export]` only has an effect on macro definitions
-passes-plugin-registrar = `#[plugin_registrar]` only has an effect on functions
+passes_plugin_registrar = `#[plugin_registrar]` only has an effect on functions
-passes-unused-empty-lints-note = attribute `{$name}` with an empty list has no effect
+passes_unused_empty_lints_note = attribute `{$name}` with an empty list has no effect
-passes-unused-no-lints-note = attribute `{$name}` without any lints has no effect
+passes_unused_no_lints_note = attribute `{$name}` without any lints has no effect
-passes-unused-default-method-body-const-note =
+passes_unused_default_method_body_const_note =
`default_method_body_is_const` has been replaced with `#[const_trait]` on traits
-passes-unused = unused attribute
+passes_unused = unused attribute
.suggestion = remove this attribute
-passes-non-exported-macro-invalid-attrs = attribute should be applied to function or closure
+passes_non_exported_macro_invalid_attrs = attribute should be applied to function or closure
.label = not a function or closure
-passes-unused-duplicate = unused attribute
+passes_unused_duplicate = unused attribute
.suggestion = remove this attribute
.note = attribute also specified here
- .warn = {-passes-previously-accepted}
+ .warn = {-passes_previously_accepted}
-passes-unused-multiple = multiple `{$name}` attributes
+passes_unused_multiple = multiple `{$name}` attributes
.suggestion = remove this attribute
.note = attribute also specified here
-passes-rustc-lint-opt-ty = `#[rustc_lint_opt_ty]` should be applied to a struct
+passes_rustc_lint_opt_ty = `#[rustc_lint_opt_ty]` should be applied to a struct
.label = not a struct
-passes-rustc-lint-opt-deny-field-access = `#[rustc_lint_opt_deny_field_access]` should be applied to a field
+passes_rustc_lint_opt_deny_field_access = `#[rustc_lint_opt_deny_field_access]` should be applied to a field
.label = not a field
-passes-link-ordinal = attribute should be applied to a foreign function or static
- .label = not a foreign function or static
\ No newline at end of file
+passes_link_ordinal = attribute should be applied to a foreign function or static
+ .label = not a foreign function or static
-privacy-field-is-private = field `{$field_name}` of {$variant_descr} `{$def_path_str}` is private
-privacy-field-is-private-is-update-syntax-label = field `{$field_name}` is private
-privacy-field-is-private-label = private field
+privacy_field_is_private = field `{$field_name}` of {$variant_descr} `{$def_path_str}` is private
+privacy_field_is_private_is_update_syntax_label = field `{$field_name}` is private
+privacy_field_is_private_label = private field
-privacy-item-is-private = {$kind} `{$descr}` is private
+privacy_item_is_private = {$kind} `{$descr}` is private
.label = private {$kind}
-privacy-unnamed-item-is-private = {$kind} is private
+privacy_unnamed_item_is_private = {$kind} is private
.label = private {$kind}
-privacy-in-public-interface = {$vis_descr} {$kind} `{$descr}` in public interface
+privacy_in_public_interface = {$vis_descr} {$kind} `{$descr}` in public interface
.label = can't leak {$vis_descr} {$kind}
- .visibility-label = `{$descr}` declared as {$vis_descr}
+ .visibility_label = `{$descr}` declared as {$vis_descr}
-privacy-from-private-dep-in-public-interface =
+privacy_from_private_dep_in_public_interface =
{$kind} `{$descr}` from private dependency '{$krate}' in public interface
-private-in-public-lint =
+private_in_public_lint =
{$vis_descr} {$kind} `{$descr}` in public interface (error {$kind ->
[trait] E0445
*[other] E0446
-typeck-field-multiply-specified-in-initializer =
+typeck_field_multiply_specified_in_initializer =
field `{$ident}` specified more than once
.label = used more than once
- .previous-use-label = first use of `{$ident}`
+ .previous_use_label = first use of `{$ident}`
-typeck-unrecognized-atomic-operation =
+typeck_unrecognized_atomic_operation =
unrecognized atomic operation function: `{$op}`
.label = unrecognized atomic operation
-typeck-wrong-number-of-generic-arguments-to-intrinsic =
+typeck_wrong_number_of_generic_arguments_to_intrinsic =
intrinsic has wrong number of {$descr} parameters: found {$found}, expected {$expected}
.label = expected {$expected} {$descr} {$expected ->
[one] parameter
*[other] parameters
}
-typeck-unrecognized-intrinsic-function =
+typeck_unrecognized_intrinsic_function =
unrecognized intrinsic function: `{$name}`
.label = unrecognized intrinsic
-typeck-lifetimes-or-bounds-mismatch-on-trait =
+typeck_lifetimes_or_bounds_mismatch_on_trait =
lifetime parameters or bounds on {$item_kind} `{$ident}` do not match the trait declaration
.label = lifetimes do not match {$item_kind} in trait
- .generics-label = lifetimes in impl do not match this {$item_kind} in trait
+ .generics_label = lifetimes in impl do not match this {$item_kind} in trait
-typeck-drop-impl-on-wrong-item =
+typeck_drop_impl_on_wrong_item =
the `Drop` trait may only be implemented for structs, enums, and unions
.label = must be a struct, enum, or union
-typeck-field-already-declared =
+typeck_field_already_declared =
field `{$field_name}` is already declared
.label = field already declared
- .previous-decl-label = `{$field_name}` first declared here
+ .previous_decl_label = `{$field_name}` first declared here
-typeck-copy-impl-on-type-with-dtor =
+typeck_copy_impl_on_type_with_dtor =
the trait `Copy` may not be implemented for this type; the type has a destructor
.label = `Copy` not allowed on types with destructors
-typeck-multiple-relaxed-default-bounds =
+typeck_multiple_relaxed_default_bounds =
type parameter has more than one relaxed default bound, only one is supported
-typeck-copy-impl-on-non-adt =
+typeck_copy_impl_on_non_adt =
the trait `Copy` may not be implemented for this type
.label = type is not a structure or enumeration
-typeck-trait-object-declared-with-no-traits =
+typeck_trait_object_declared_with_no_traits =
at least one trait is required for an object type
- .alias-span = this alias does not contain a trait
+ .alias_span = this alias does not contain a trait
-typeck-ambiguous-lifetime-bound =
+typeck_ambiguous_lifetime_bound =
ambiguous lifetime bound, explicit lifetime bound required
-typeck-assoc-type-binding-not-allowed =
+typeck_assoc_type_binding_not_allowed =
associated type bindings are not allowed here
.label = associated type not allowed here
-typeck-functional-record-update-on-non-struct =
+typeck_functional_record_update_on_non_struct =
functional record update syntax requires a struct
-typeck-typeof-reserved-keyword-used =
+typeck_typeof_reserved_keyword_used =
`typeof` is a reserved keyword but unimplemented
.suggestion = consider replacing `typeof(...)` with an actual type
.label = reserved keyword
-typeck-return-stmt-outside-of-fn-body =
+typeck_return_stmt_outside_of_fn_body =
return statement outside of function body
- .encl-body-label = the return is part of this body...
- .encl-fn-label = ...not the enclosing function body
+ .encl_body_label = the return is part of this body...
+ .encl_fn_label = ...not the enclosing function body
-typeck-yield-expr-outside-of-generator =
+typeck_yield_expr_outside_of_generator =
yield expression outside of generator literal
-typeck-struct-expr-non-exhaustive =
+typeck_struct_expr_non_exhaustive =
cannot create non-exhaustive {$what} using struct expression
-typeck-method-call-on-unknown-type =
+typeck_method_call_on_unknown_type =
the type of this value must be known to call a method on a raw pointer on it
-typeck-value-of-associated-struct-already-specified =
+typeck_value_of_associated_struct_already_specified =
the value of the associated type `{$item_name}` (from trait `{$def_path}`) is already specified
.label = re-bound here
- .previous-bound-label = `{$item_name}` bound here first
+ .previous_bound_label = `{$item_name}` bound here first
-typeck-address-of-temporary-taken = cannot take address of a temporary
+typeck_address_of_temporary_taken = cannot take address of a temporary
.label = temporary value
-typeck-add-return-type-add = try adding a return type
+typeck_add_return_type_add = try adding a return type
-typeck-add-return-type-missing-here = a return type might be missing here
+typeck_add_return_type_missing_here = a return type might be missing here
-typeck-expected-default-return-type = expected `()` because of default return type
+typeck_expected_default_return_type = expected `()` because of default return type
-typeck-expected-return-type = expected `{$expected}` because of return type
+typeck_expected_return_type = expected `{$expected}` because of return type
-typeck-unconstrained-opaque-type = unconstrained opaque type
+typeck_unconstrained_opaque_type = unconstrained opaque type
.note = `{$name}` must be used in combination with a concrete type within the same module
-typeck-missing-type-params =
+typeck_missing_type_params =
the type {$parameterCount ->
[one] parameter
*[other] parameters
[one] type
*[other] types
}
- .no-suggestion-label = missing {$parameterCount ->
+ .no_suggestion_label = missing {$parameterCount ->
[one] reference
*[other] references
} to {$parameters}
.note = because of the default `Self` reference, type parameters must be specified on object types
-typeck-manual-implementation =
+typeck_manual_implementation =
manual implementations of `{$trait_name}` are experimental
.label = manual implementations of `{$trait_name}` are experimental
.help = add `#![feature(unboxed_closures)]` to the crate attributes to enable
-typeck-substs-on-overridden-impl = could not resolve substs on overridden impl
+typeck_substs_on_overridden_impl = could not resolve substs on overridden impl
-#![cfg_attr(bootstrap, feature(let_chains))]
#![feature(once_cell)]
#![feature(rustc_attrs)]
#![feature(type_alias_impl_trait)]
DiagnosticMessage::FluentIdentifier(identifier, attr) => (identifier, attr),
};
- let bundle = match self.fluent_bundle() {
- Some(bundle) if bundle.has_message(&identifier) => bundle,
- _ => self.fallback_fluent_bundle(),
- };
+ let translate_with_bundle = |bundle: &'a FluentBundle| -> Option<(Cow<'_, str>, Vec<_>)> {
+ let message = bundle.get_message(&identifier)?;
+ let value = match attr {
+ Some(attr) => message.get_attribute(attr)?.value(),
+ None => message.value()?,
+ };
+ debug!(?message, ?value);
- let message = bundle.get_message(&identifier).expect("missing diagnostic in fluent bundle");
- let value = match attr {
- Some(attr) => {
- if let Some(attr) = message.get_attribute(attr) {
- attr.value()
- } else {
- panic!("missing attribute `{attr}` in fluent message `{identifier}`")
- }
- }
- None => {
- if let Some(value) = message.value() {
- value
- } else {
- panic!("missing value in fluent message `{identifier}`")
- }
- }
+ let mut errs = vec![];
+ let translated = bundle.format_pattern(value, Some(&args), &mut errs);
+ debug!(?translated, ?errs);
+ Some((translated, errs))
};
- let mut err = vec![];
- let translated = bundle.format_pattern(value, Some(&args), &mut err);
- trace!(?translated, ?err);
- debug_assert!(
- err.is_empty(),
- "identifier: {:?}, args: {:?}, errors: {:?}",
- identifier,
- args,
- err
- );
- translated
+ self.fluent_bundle()
+ .and_then(|bundle| translate_with_bundle(bundle))
+ // If `translate_with_bundle` returns `None` with the primary bundle, this is likely
+ // just that the primary bundle doesn't contain the message being translated, so
+ // proceed to the fallback bundle.
+ //
+ // However, when errors are produced from translation, then that means the translation
+ // is broken (e.g. `{$foo}` exists in a translation but `foo` isn't provided).
+ //
+ // In debug builds, assert so that compiler devs can spot the broken translation and
+ // fix it..
+ .inspect(|(_, errs)| {
+ debug_assert!(
+ errs.is_empty(),
+ "identifier: {:?}, attr: {:?}, args: {:?}, errors: {:?}",
+ identifier,
+ attr,
+ args,
+ errs
+ );
+ })
+ // ..otherwise, for end users, an error about this wouldn't be useful or actionable, so
+ // just hide it and try with the fallback bundle.
+ .filter(|(_, errs)| errs.is_empty())
+ .or_else(|| translate_with_bundle(self.fallback_fluent_bundle()))
+ .map(|(translated, errs)| {
+ // Always bail out for errors with the fallback bundle.
+ assert!(
+ errs.is_empty(),
+ "identifier: {:?}, attr: {:?}, args: {:?}, errors: {:?}",
+ identifier,
+ attr,
+ args,
+ errs
+ );
+ translated
+ })
+ .expect("failed to find message in primary or fallback fluent bundles")
}
/// Formats the substitutions of the primary_span
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![feature(drain_filter)]
#![feature(if_let_guard)]
-#![cfg_attr(bootstrap, feature(let_chains))]
+#![feature(adt_const_params)]
#![feature(let_else)]
#![feature(never_type)]
-#![feature(adt_const_params)]
+#![feature(result_option_inspect)]
#![feature(rustc_attrs)]
#![allow(incomplete_features)]
#![allow(rustc::potential_query_instability)]
#![feature(associated_type_bounds)]
#![feature(associated_type_defaults)]
#![feature(if_let_guard)]
-#![cfg_attr(bootstrap, feature(let_chains))]
#![feature(let_else)]
#![feature(macro_metavar_expr)]
#![feature(proc_macro_diagnostic)]
Field(&'hir FieldDef<'hir>),
AnonConst(&'hir AnonConst),
Expr(&'hir Expr<'hir>),
+ ExprField(&'hir ExprField<'hir>),
Stmt(&'hir Stmt<'hir>),
PathSegment(&'hir PathSegment<'hir>),
Ty(&'hir Ty<'hir>),
TypeBinding(&'hir TypeBinding<'hir>),
TraitRef(&'hir TraitRef<'hir>),
Pat(&'hir Pat<'hir>),
+ PatField(&'hir PatField<'hir>),
Arm(&'hir Arm<'hir>),
Block(&'hir Block<'hir>),
Local(&'hir Local<'hir>),
| Node::Block(..)
| Node::Ctor(..)
| Node::Pat(..)
+ | Node::PatField(..)
+ | Node::ExprField(..)
| Node::Arm(..)
| Node::Local(..)
| Node::Crate(..)
fn visit_pat(&mut self, p: &'v Pat<'v>) {
walk_pat(self, p)
}
+ fn visit_pat_field(&mut self, f: &'v PatField<'v>) {
+ walk_pat_field(self, f)
+ }
fn visit_array_length(&mut self, len: &'v ArrayLen) {
walk_array_len(self, len)
}
fn visit_let_expr(&mut self, lex: &'v Let<'v>) {
walk_let_expr(self, lex)
}
+ fn visit_expr_field(&mut self, field: &'v ExprField<'v>) {
+ walk_expr_field(self, field)
+ }
fn visit_ty(&mut self, t: &'v Ty<'v>) {
walk_ty(self, t)
}
}
PatKind::Struct(ref qpath, fields, _) => {
visitor.visit_qpath(qpath, pattern.hir_id, pattern.span);
- for field in fields {
- visitor.visit_id(field.hir_id);
- visitor.visit_ident(field.ident);
- visitor.visit_pat(&field.pat)
- }
+ walk_list!(visitor, visit_pat_field, fields);
}
PatKind::Or(pats) => walk_list!(visitor, visit_pat, pats),
PatKind::Tuple(tuple_elements, _) => {
}
}
+pub fn walk_pat_field<'v, V: Visitor<'v>>(visitor: &mut V, field: &'v PatField<'v>) {
+ visitor.visit_id(field.hir_id);
+ visitor.visit_ident(field.ident);
+ visitor.visit_pat(&field.pat)
+}
+
pub fn walk_foreign_item<'v, V: Visitor<'v>>(visitor: &mut V, foreign_item: &'v ForeignItem<'v>) {
visitor.visit_id(foreign_item.hir_id());
visitor.visit_ident(foreign_item.ident);
walk_list!(visitor, visit_ty, let_expr.ty);
}
+pub fn walk_expr_field<'v, V: Visitor<'v>>(visitor: &mut V, field: &'v ExprField<'v>) {
+ visitor.visit_id(field.hir_id);
+ visitor.visit_ident(field.ident);
+ visitor.visit_expr(&field.expr)
+}
+
pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>) {
visitor.visit_id(expression.hir_id);
match expression.kind {
}
ExprKind::Struct(ref qpath, fields, ref optional_base) => {
visitor.visit_qpath(qpath, expression.hir_id, expression.span);
- for field in fields {
- visitor.visit_id(field.hir_id);
- visitor.visit_ident(field.ident);
- visitor.visit_expr(&field.expr)
- }
+ walk_list!(visitor, visit_expr_field, fields);
walk_list!(visitor, visit_expr, optional_base);
}
ExprKind::Tup(subexpressions) => {
GenericParam(GenericParamKind),
MacroDef,
Param,
+ PatField,
+ ExprField,
}
impl Display for Target {
},
Target::MacroDef => "macro def",
Target::Param => "function param",
+ Target::PatField => "pattern field",
+ Target::ExprField => "struct field",
}
}
}
Node::Variant(a) => self.print_variant(a),
Node::AnonConst(a) => self.print_anon_const(a),
Node::Expr(a) => self.print_expr(a),
+ Node::ExprField(a) => self.print_expr_field(&a),
Node::Stmt(a) => self.print_stmt(a),
Node::PathSegment(a) => self.print_path_segment(a),
Node::Ty(a) => self.print_type(a),
Node::TypeBinding(a) => self.print_type_binding(a),
Node::TraitRef(a) => self.print_trait_ref(a),
Node::Pat(a) => self.print_pat(a),
+ Node::PatField(a) => self.print_patfield(&a),
Node::Arm(a) => self.print_arm(a),
Node::Infer(_) => self.word("_"),
Node::Block(a) => {
if let Some(els) = els {
self.nbsp();
self.word_space("else");
+ // containing cbox, will be closed by print-block at `}`
+ self.cbox(0);
+ // head-box, will be closed by print-block after `{`
+ self.ibox(0);
self.print_block(els);
}
) {
self.print_qpath(qpath, true);
self.word("{");
- self.commasep_cmnt(
- Consistent,
- fields,
- |s, field| {
- s.ibox(INDENT_UNIT);
- if !field.is_shorthand {
- s.print_ident(field.ident);
- s.word_space(":");
- }
- s.print_expr(field.expr);
- s.end()
- },
- |f| f.span,
- );
+ self.commasep_cmnt(Consistent, fields, |s, field| s.print_expr_field(field), |f| f.span);
if let Some(expr) = wth {
self.ibox(INDENT_UNIT);
if !fields.is_empty() {
self.word("}");
}
+ fn print_expr_field(&mut self, field: &hir::ExprField<'_>) {
+ if self.attrs(field.hir_id).is_empty() {
+ self.space();
+ }
+ self.cbox(INDENT_UNIT);
+ self.print_outer_attributes(&self.attrs(field.hir_id));
+ if !field.is_shorthand {
+ self.print_ident(field.ident);
+ self.word_space(":");
+ }
+ self.print_expr(&field.expr);
+ self.end()
+ }
+
fn print_expr_tup(&mut self, exprs: &[hir::Expr<'_>]) {
self.popen();
self.commasep_exprs(Inconsistent, exprs);
if !empty {
self.space();
}
- self.commasep_cmnt(
- Consistent,
- fields,
- |s, f| {
- s.cbox(INDENT_UNIT);
- if !f.is_shorthand {
- s.print_ident(f.ident);
- s.word_nbsp(":");
- }
- s.print_pat(f.pat);
- s.end()
- },
- |f| f.pat.span,
- );
+ self.commasep_cmnt(Consistent, &fields, |s, f| s.print_patfield(f), |f| f.pat.span);
if etc {
if !fields.is_empty() {
self.word_space(",");
self.ann.post(self, AnnNode::Pat(pat))
}
+ pub fn print_patfield(&mut self, field: &hir::PatField<'_>) {
+ if self.attrs(field.hir_id).is_empty() {
+ self.space();
+ }
+ self.cbox(INDENT_UNIT);
+ self.print_outer_attributes(&self.attrs(field.hir_id));
+ if !field.is_shorthand {
+ self.print_ident(field.ident);
+ self.word_nbsp(":");
+ }
+ self.print_pat(field.pat);
+ self.end();
+ }
+
pub fn print_param(&mut self, arg: &hir::Param<'_>) {
self.print_outer_attributes(self.attrs(arg.hir_id));
self.print_pat(arg.pat);
}
#[inline]
- pub fn indices(&self) -> impl DoubleEndedIterator<Item = I> + ExactSizeIterator + 'static {
+ pub fn indices(
+ &self,
+ ) -> impl DoubleEndedIterator<Item = I> + ExactSizeIterator + Clone + 'static {
(0..self.len()).map(|n| I::new(n))
}
}
/// Adds a note if the types come from similarly named crates
- fn check_and_note_conflicting_crates(&self, err: &mut Diagnostic, terr: &TypeError<'tcx>) {
+ fn check_and_note_conflicting_crates(&self, err: &mut Diagnostic, terr: TypeError<'tcx>) {
use hir::def_id::CrateNum;
use rustc_hir::definitions::DisambiguatedDefPathData;
use ty::print::Printer;
}
}
};
- match *terr {
+ match terr {
TypeError::Sorts(ref exp_found) => {
// if they are both "path types", there's a chance of ambiguity
// due to different versions of the same crate
err: &mut Diagnostic,
cause: &ObligationCause<'tcx>,
exp_found: Option<ty::error::ExpectedFound<Ty<'tcx>>>,
- terr: &TypeError<'tcx>,
+ terr: TypeError<'tcx>,
) {
match *cause.code() {
ObligationCauseCode::Pattern { origin_expr: true, span: Some(span), root_ty } => {
/// E0271, like `src/test/ui/issues/issue-39970.stderr`.
#[tracing::instrument(
level = "debug",
- skip(self, diag, secondary_span, swap_secondary_and_primary, force_label)
+ skip(self, diag, secondary_span, swap_secondary_and_primary, prefer_label)
)]
pub fn note_type_err(
&self,
cause: &ObligationCause<'tcx>,
secondary_span: Option<(Span, String)>,
mut values: Option<ValuePairs<'tcx>>,
- terr: &TypeError<'tcx>,
+ terr: TypeError<'tcx>,
swap_secondary_and_primary: bool,
- force_label: bool,
+ prefer_label: bool,
) {
let span = cause.span();
TypeError::ObjectUnsafeCoercion(_) => {}
_ => {
let mut label_or_note = |span: Span, msg: &str| {
- if force_label || &[span] == diag.span.primary_spans() {
+ if (prefer_label && is_simple_error) || &[span] == diag.span.primary_spans() {
diag.span_label(span, msg);
} else {
diag.span_note(span, msg);
ty::error::TypeError::Sorts(terr)
if exp_found.map_or(false, |ef| terr.found == ef.found) =>
{
- Some(*terr)
+ Some(terr)
}
_ => exp_found,
};
pub fn report_and_explain_type_error(
&self,
trace: TypeTrace<'tcx>,
- terr: &TypeError<'tcx>,
+ terr: TypeError<'tcx>,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
use crate::traits::ObligationCauseCode::MatchExpressionArm;
}
pub trait ObligationCauseExt<'tcx> {
- fn as_failure_code(&self, terr: &TypeError<'tcx>) -> FailureCode;
+ fn as_failure_code(&self, terr: TypeError<'tcx>) -> FailureCode;
fn as_requirement_str(&self) -> &'static str;
}
impl<'tcx> ObligationCauseExt<'tcx> for ObligationCause<'tcx> {
- fn as_failure_code(&self, terr: &TypeError<'tcx>) -> FailureCode {
+ fn as_failure_code(&self, terr: TypeError<'tcx>) -> FailureCode {
use self::FailureCode::*;
use crate::traits::ObligationCauseCode::*;
match self.code() {
TypeError::IntrinsicCast => {
Error0308("cannot coerce intrinsics to function pointers")
}
- TypeError::ObjectUnsafeCoercion(did) => Error0038(*did),
+ TypeError::ObjectUnsafeCoercion(did) => Error0038(did),
_ => Error0308("mismatched types"),
},
}
match origin {
infer::Subtype(box trace) => {
let terr = TypeError::RegionsDoesNotOutlive(sup, sub);
- let mut err = self.report_and_explain_type_error(trace, &terr);
+ let mut err = self.report_and_explain_type_error(trace, terr);
match (*sub, *sup) {
(ty::RePlaceholder(_), ty::RePlaceholder(_)) => {}
(ty::RePlaceholder(_), _) => {
}
infer::Subtype(box trace) => {
let terr = TypeError::RegionsPlaceholderMismatch;
- return self.report_and_explain_type_error(trace, &terr);
+ return self.report_and_explain_type_error(trace, terr);
}
_ => return self.report_concrete_failure(placeholder_origin, sub, sup),
}
actual: Ty<'tcx>,
err: TypeError<'tcx>,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
- let trace = TypeTrace::types(cause, true, expected, actual);
- self.report_and_explain_type_error(trace, &err)
+ self.report_and_explain_type_error(TypeTrace::types(cause, true, expected, actual), err)
}
pub fn report_mismatched_consts(
actual: ty::Const<'tcx>,
err: TypeError<'tcx>,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
- let trace = TypeTrace::consts(cause, true, expected, actual);
- self.report_and_explain_type_error(trace, &err)
+ self.report_and_explain_type_error(TypeTrace::consts(cause, true, expected, actual), err)
}
pub fn replace_bound_vars_with_fresh_vars<T>(
#![feature(control_flow_enum)]
#![feature(extend_one)]
#![feature(label_break_value)]
-#![cfg_attr(bootstrap, feature(let_chains))]
#![feature(let_else)]
#![feature(min_specialization)]
#![feature(never_type)]
}
// JUSTIFICATION: before session exists, only config
-#[cfg_attr(not(bootstrap), allow(rustc::bad_opt_access))]
+#[allow(rustc::bad_opt_access)]
pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Send) -> R {
tracing::trace!("run_compiler");
util::run_in_thread_pool_with_globals(
-#![cfg_attr(not(bootstrap), allow(rustc::bad_opt_access))]
+#![allow(rustc::bad_opt_access)]
use crate::interface::parse_cfgspecs;
use rustc_data_structures::fx::FxHashSet;
// command line, then reuse the empty `base` Vec to hold the types that
// will be found in crate attributes.
// JUSTIFICATION: before wrapper fn is available
- #[cfg_attr(not(bootstrap), allow(rustc::bad_opt_access))]
+ #[allow(rustc::bad_opt_access)]
let mut base = session.opts.crate_types.clone();
if base.is_empty() {
base.extend(attr_types);
run_early_pass!(self, check_pat_post, p);
}
+ fn visit_pat_field(&mut self, field: &'a ast::PatField) {
+ self.with_lint_attrs(field.id, &field.attrs, |cx| {
+ ast_visit::walk_pat_field(cx, field);
+ });
+ }
+
fn visit_anon_const(&mut self, c: &'a ast::AnonConst) {
self.check_id(c.id);
ast_visit::walk_anon_const(self, c);
}
fn visit_generic_param(&mut self, param: &'a ast::GenericParam) {
- run_early_pass!(self, check_generic_param, param);
- self.check_id(param.id);
- ast_visit::walk_generic_param(self, param);
+ self.with_lint_attrs(param.id, ¶m.attrs, |cx| {
+ run_early_pass!(cx, check_generic_param, param);
+ ast_visit::walk_generic_param(cx, param);
+ });
}
fn visit_generics(&mut self, g: &'a ast::Generics) {
})
}
+ fn visit_expr_field(&mut self, field: &'tcx hir::ExprField<'tcx>) {
+ self.with_lint_attrs(field.hir_id, |builder| {
+ intravisit::walk_expr_field(builder, field);
+ })
+ }
+
fn visit_field_def(&mut self, s: &'tcx hir::FieldDef<'tcx>) {
self.with_lint_attrs(s.hir_id, |builder| {
intravisit::walk_field_def(builder, s);
intravisit::walk_impl_item(builder, impl_item);
});
}
+
+ fn visit_pat_field(&mut self, field: &'tcx hir::PatField<'tcx>) {
+ self.with_lint_attrs(field.hir_id, |builder| {
+ intravisit::walk_pat_field(builder, field);
+ })
+ }
+
+ fn visit_generic_param(&mut self, p: &'tcx hir::GenericParam<'tcx>) {
+ self.with_lint_attrs(p.hir_id, |builder| {
+ intravisit::walk_generic_param(builder, p);
+ });
+ }
}
pub fn provide(providers: &mut Providers) {
#![feature(if_let_guard)]
#![feature(iter_intersperse)]
#![feature(iter_order_by)]
-#![cfg_attr(bootstrap, feature(let_chains))]
#![feature(let_else)]
#![feature(never_type)]
#![recursion_limit = "256"]
fn check_pat(&mut self, cx: &LateContext<'_>, p: &hir::Pat<'_>) {
if let PatKind::Binding(_, hid, ident, _) = p.kind {
- if let hir::Node::Pat(parent_pat) = cx.tcx.hir().get(cx.tcx.hir().get_parent_node(hid))
+ if let hir::Node::PatField(field) = cx.tcx.hir().get(cx.tcx.hir().get_parent_node(hid))
{
- if let PatKind::Struct(_, field_pats, _) = &parent_pat.kind {
- if field_pats
- .iter()
- .any(|field| !field.is_shorthand && field.pat.hir_id == p.hir_id)
- {
- // Only check if a new name has been introduced, to avoid warning
- // on both the struct definition and this pattern.
- self.check_snake_case(cx, "variable", &ident);
- }
- return;
+ if !field.is_shorthand {
+ // Only check if a new name has been introduced, to avoid warning
+ // on both the struct definition and this pattern.
+ self.check_snake_case(cx, "variable", &ident);
}
+ return;
}
self.check_snake_case(cx, "variable", &ident);
}
lit_val: u128,
max: u128,
expr: &'tcx hir::Expr<'tcx>,
- parent_expr: &'tcx hir::Expr<'tcx>,
ty: &str,
) -> bool {
// We only want to handle exclusive (`..`) ranges,
// which are represented as `ExprKind::Struct`.
+ let par_id = cx.tcx.hir().get_parent_node(expr.hir_id);
+ let Node::ExprField(field) = cx.tcx.hir().get(par_id) else { return false };
+ let field_par_id = cx.tcx.hir().get_parent_node(field.hir_id);
+ let Node::Expr(struct_expr) = cx.tcx.hir().get(field_par_id) else { return false };
+ if !is_range_literal(struct_expr) {
+ return false;
+ };
+ let ExprKind::Struct(_, eps, _) = &struct_expr.kind else { return false };
+ if eps.len() != 2 {
+ return false;
+ }
+
let mut overwritten = false;
- if let ExprKind::Struct(_, eps, _) = &parent_expr.kind {
- if eps.len() != 2 {
- return false;
- }
- // We can suggest using an inclusive range
- // (`..=`) instead only if it is the `end` that is
- // overflowing and only by 1.
- if eps[1].expr.hir_id == expr.hir_id && lit_val - 1 == max {
- cx.struct_span_lint(OVERFLOWING_LITERALS, parent_expr.span, |lint| {
- let mut err = lint.build(fluent::lint::range_endpoint_out_of_range);
- err.set_arg("ty", ty);
- if let Ok(start) = cx.sess().source_map().span_to_snippet(eps[0].span) {
- use ast::{LitIntType, LitKind};
- // We need to preserve the literal's suffix,
- // as it may determine typing information.
- let suffix = match lit.node {
- LitKind::Int(_, LitIntType::Signed(s)) => s.name_str(),
- LitKind::Int(_, LitIntType::Unsigned(s)) => s.name_str(),
- LitKind::Int(_, LitIntType::Unsuffixed) => "",
- _ => bug!(),
- };
- let suggestion = format!("{}..={}{}", start, lit_val - 1, suffix);
- err.span_suggestion(
- parent_expr.span,
- fluent::lint::suggestion,
- suggestion,
- Applicability::MachineApplicable,
- );
- err.emit();
- overwritten = true;
- }
- });
- }
+ // We can suggest using an inclusive range
+ // (`..=`) instead only if it is the `end` that is
+ // overflowing and only by 1.
+ if eps[1].expr.hir_id == expr.hir_id && lit_val - 1 == max {
+ cx.struct_span_lint(OVERFLOWING_LITERALS, struct_expr.span, |lint| {
+ let mut err = lint.build(fluent::lint::range_endpoint_out_of_range);
+ err.set_arg("ty", ty);
+ if let Ok(start) = cx.sess().source_map().span_to_snippet(eps[0].span) {
+ use ast::{LitIntType, LitKind};
+ // We need to preserve the literal's suffix,
+ // as it may determine typing information.
+ let suffix = match lit.node {
+ LitKind::Int(_, LitIntType::Signed(s)) => s.name_str(),
+ LitKind::Int(_, LitIntType::Unsigned(s)) => s.name_str(),
+ LitKind::Int(_, LitIntType::Unsuffixed) => "",
+ _ => bug!(),
+ };
+ let suggestion = format!("{}..={}{}", start, lit_val - 1, suffix);
+ err.span_suggestion(
+ struct_expr.span,
+ fluent::lint::suggestion,
+ suggestion,
+ Applicability::MachineApplicable,
+ );
+ err.emit();
+ overwritten = true;
+ }
+ });
}
overwritten
}
return;
}
- let par_id = cx.tcx.hir().get_parent_node(e.hir_id);
- if let Node::Expr(par_e) = cx.tcx.hir().get(par_id) {
- if let hir::ExprKind::Struct(..) = par_e.kind {
- if is_range_literal(par_e)
- && lint_overflowing_range_endpoint(cx, lit, v, max, e, par_e, t.name_str())
- {
- // The overflowing literal lint was overridden.
- return;
- }
- }
+ if lint_overflowing_range_endpoint(cx, lit, v, max, e, t.name_str()) {
+ // The overflowing literal lint was overridden.
+ return;
}
cx.struct_span_lint(OVERFLOWING_LITERALS, e.span, |lint| {
return;
}
}
- hir::ExprKind::Struct(..) if is_range_literal(par_e) => {
- let t = t.name_str();
- if lint_overflowing_range_endpoint(cx, lit, lit_val, max, e, par_e, t) {
- // The overflowing literal lint was overridden.
- return;
- }
- }
_ => {}
}
}
+ if lint_overflowing_range_endpoint(cx, lit, lit_val, max, e, t.name_str()) {
+ // The overflowing literal lint was overridden.
+ return;
+ }
if let Some(repr_str) = get_bin_hex_repr(cx, lit) {
report_bin_hex_error(
cx,
fromRust(Flags), unwrapDI<DIType>(Ty)));
}
+extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStaticMemberType(
+ LLVMRustDIBuilderRef Builder,
+ LLVMMetadataRef Scope,
+ const char *Name,
+ size_t NameLen,
+ LLVMMetadataRef File,
+ unsigned LineNo,
+ LLVMMetadataRef Ty,
+ LLVMRustDIFlags Flags,
+ LLVMValueRef val,
+ uint32_t AlignInBits
+) {
+ return wrap(Builder->createStaticMemberType(
+ unwrapDI<DIDescriptor>(Scope),
+ StringRef(Name, NameLen),
+ unwrapDI<DIFile>(File),
+ LineNo,
+ unwrapDI<DIType>(Ty),
+ fromRust(Flags),
+ unwrap<llvm::ConstantInt>(val),
+ AlignInBits
+ ));
+}
+
extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateLexicalBlock(
LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
LLVMMetadataRef File, unsigned Line, unsigned Col) {
if let Entry::Message(Message { id: Identifier { name }, attributes, .. }) = entry {
let _ = previous_defns.entry(name.to_string()).or_insert(ident_span);
- // `typeck-foo-bar` => `foo_bar` (in `typeck.ftl`)
- // `const-eval-baz` => `baz` (in `const_eval.ftl`)
+ if name.contains('-') {
+ Diagnostic::spanned(
+ ident_span,
+ Level::Error,
+ format!("name `{name}` contains a '-' character"),
+ )
+ .help("replace any '-'s with '_'s")
+ .emit();
+ }
+
+ // `typeck_foo_bar` => `foo_bar` (in `typeck.ftl`)
+ // `const_eval_baz` => `baz` (in `const_eval.ftl`)
+ // `const-eval-hyphen-having` => `hyphen_having` (in `const_eval.ftl`)
+ // The last case we error about above, but we want to fall back gracefully
+ // so that only the error is being emitted and not also one about the macro
+ // failing.
let snake_name = Ident::new(
// FIXME: should probably trim prefix, not replace all occurrences
- &name
- .replace(&format!("{}-", res.ident).replace('_', "-"), "")
- .replace('-', "_"),
+ &name.replace('-', "_").replace(&format!("{}_", res.ident), ""),
span,
);
constants.extend(quote! {
continue;
}
+ if attr_name.contains('-') {
+ Diagnostic::spanned(
+ ident_span,
+ Level::Error,
+ format!("attribute `{attr_name}` contains a '-' character"),
+ )
+ .help("replace any '-'s with '_'s")
+ .emit();
+ }
+
constants.extend(quote! {
pub const #snake_name: crate::SubdiagnosticMessage =
crate::SubdiagnosticMessage::FluentAttr(
/// ```
///
/// ```fluent
-/// move-out-of-borrow = cannot move out of {$name} because it is borrowed
+/// move_out_of_borrow = cannot move out of {$name} because it is borrowed
/// .label = cannot move out of borrow
-/// .first-borrow-label = `{$ty}` first borrowed here
+/// .first_borrow_label = `{$ty}` first borrowed here
/// .suggestion = consider cloning here
/// ```
///
/// ```
///
/// ```fluent
-/// lint-atomic-ordering-invalid-fail-success = `{$method}`'s success ordering must be at least as strong as its failure ordering
-/// .fail-label = `{$fail_ordering}` failure ordering
-/// .success-label = `{$success_ordering}` success ordering
+/// lint_atomic_ordering_invalid_fail_success = `{$method}`'s success ordering must be at least as strong as its failure ordering
+/// .fail_label = `{$fail_ordering}` failure ordering
+/// .success_label = `{$success_ordering}` success ordering
/// .suggestion = consider using `{$success_suggestion}` success ordering instead
/// ```
///
/// ```
///
/// ```fluent
-/// parser-expected-identifier = expected identifier
+/// parser_expected_identifier = expected identifier
///
-/// parser-expected-identifier-found = expected identifier, found {$found}
+/// parser_expected_identifier-found = expected identifier, found {$found}
///
-/// parser-raw-identifier = escape `{$ident}` to use it as an identifier
+/// parser_raw_identifier = escape `{$ident}` to use it as an identifier
/// ```
///
/// Then, later, to add the subdiagnostic:
/// ..where `typeck.ftl` has the following contents..
///
/// ```fluent
-/// typeck-field-multiply-specified-in-initializer =
+/// typeck_field_multiply_specified_in_initializer =
/// field `{$ident}` specified more than once
/// .label = used more than once
-/// .label-previous-use = first use of `{$ident}`
+/// .label_previous_use = first use of `{$ident}`
/// ```
/// ...then the macro parse the Fluent resource, emitting a diagnostic if it fails to do so, and
/// will generate the following code:
/// mod fluent_generated {
/// mod typeck {
/// pub const field_multiply_specified_in_initializer: DiagnosticMessage =
-/// DiagnosticMessage::fluent("typeck-field-multiply-specified-in-initializer");
+/// DiagnosticMessage::fluent("typeck_field_multiply_specified_in_initializer");
/// pub const field_multiply_specified_in_initializer_label_previous_use: DiagnosticMessage =
/// DiagnosticMessage::fluent_attr(
-/// "typeck-field-multiply-specified-in-initializer",
-/// "previous-use-label"
+/// "typeck_field_multiply_specified_in_initializer",
+/// "previous_use_label"
/// );
/// }
/// }
#![feature(generators)]
#![feature(generic_associated_types)]
#![feature(iter_from_generator)]
-#![cfg_attr(bootstrap, feature(let_chains))]
#![feature(let_else)]
#![feature(once_cell)]
#![feature(proc_macro_internals)]
| Node::Infer(_)
| Node::TraitRef(_)
| Node::Pat(_)
+ | Node::PatField(_)
+ | Node::ExprField(_)
| Node::Local(_)
| Node::Param(_)
| Node::Arm(_)
Node::Field(field) => field.span,
Node::AnonConst(constant) => self.body(constant.body).value.span,
Node::Expr(expr) => expr.span,
+ Node::ExprField(field) => field.span,
Node::Stmt(stmt) => stmt.span,
Node::PathSegment(seg) => {
let ident_span = seg.ident.span;
Node::TypeBinding(tb) => tb.span,
Node::TraitRef(tr) => tr.path.span,
Node::Pat(pat) => pat.span,
+ Node::PatField(field) => field.span,
Node::Arm(arm) => arm.span,
Node::Block(block) => block.span,
Node::Ctor(..) => self.span_with_body(self.get_parent_node(hir_id)),
}
Some(Node::AnonConst(_)) => node_str("const"),
Some(Node::Expr(_)) => node_str("expr"),
+ Some(Node::ExprField(_)) => node_str("expr field"),
Some(Node::Stmt(_)) => node_str("stmt"),
Some(Node::PathSegment(_)) => node_str("path segment"),
Some(Node::Ty(_)) => node_str("type"),
Some(Node::TypeBinding(_)) => node_str("type binding"),
Some(Node::TraitRef(_)) => node_str("trait ref"),
Some(Node::Pat(_)) => node_str("pat"),
+ Some(Node::PatField(_)) => node_str("pattern field"),
Some(Node::Param(_)) => node_str("param"),
Some(Node::Arm(_)) => node_str("arm"),
Some(Node::Block(_)) => node_str("block"),
#![feature(extern_types)]
#![feature(new_uninit)]
#![feature(once_cell)]
-#![cfg_attr(bootstrap, feature(let_chains))]
#![feature(let_else)]
#![feature(min_specialization)]
#![feature(trusted_len)]
}
// Data structures used in type unification
-#[derive(Clone, Debug, TypeFoldable, TypeVisitable)]
+#[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable)]
+#[rustc_pass_by_value]
pub enum TypeError<'tcx> {
Mismatch,
ConstnessMismatch(ExpectedFound<ty::BoundConstness>),
}
impl<'tcx> TypeError<'tcx> {
- pub fn must_include_note(&self) -> bool {
+ pub fn must_include_note(self) -> bool {
use self::TypeError::*;
match self {
CyclicTy(_) | CyclicConst(_) | UnsafetyMismatch(_) | ConstnessMismatch(_)
pub fn note_and_explain_type_err(
self,
diag: &mut Diagnostic,
- err: &TypeError<'tcx>,
+ err: TypeError<'tcx>,
cause: &ObligationCause<'tcx>,
sp: Span,
body_owner_def_id: DefId,
}
TargetFeatureCast(def_id) => {
let target_spans =
- self.get_attrs(*def_id, sym::target_feature).map(|attr| attr.span);
+ self.get_attrs(def_id, sym::target_feature).map(|attr| attr.span);
diag.note(
"functions with `#[target_feature]` can only be coerced to `unsafe` function pointers"
);
self,
diag: &mut Diagnostic,
proj_ty: &ty::ProjectionTy<'tcx>,
- values: &ExpectedFound<Ty<'tcx>>,
+ values: ExpectedFound<Ty<'tcx>>,
body_owner_def_id: DefId,
cause_code: &ObligationCauseCode<'_>,
) {
#![feature(box_patterns)]
#![feature(control_flow_enum)]
#![feature(if_let_guard)]
-#![cfg_attr(bootstrap, feature(let_chains))]
#![feature(let_else)]
#![feature(min_specialization)]
#![feature(once_cell)]
type MemoryKind = !;
+ #[inline(always)]
+ fn enforce_alignment(_ecx: &InterpCx<'mir, 'tcx, Self>) -> bool {
+ // We do not check for alignment to avoid having to carry an `Align`
+ // in `ConstValue::ByRef`.
+ false
+ }
+
+ #[inline(always)]
+ fn enforce_validity(_ecx: &InterpCx<'mir, 'tcx, Self>) -> bool {
+ false // for now, we don't enforce validity
+ }
+
fn load_mir(
_ecx: &InterpCx<'mir, 'tcx, Self>,
_instance: ty::InstanceDef<'tcx>,
#![allow(rustc::potential_query_instability)]
#![feature(box_patterns)]
-#![cfg_attr(bootstrap, feature(let_chains))]
#![feature(let_else)]
#![feature(map_try_insert)]
#![feature(min_specialization)]
return false;
}
+ if let DefKind::Static(_) = tcx.def_kind(def_id) {
+ // We cannot monomorphize statics from upstream crates.
+ return false;
+ }
+
if !tcx.is_mir_available(def_id) {
bug!("no MIR available for {:?}", def_id);
}
#![feature(array_windows)]
#![feature(box_patterns)]
#![feature(if_let_guard)]
-#![cfg_attr(bootstrap, feature(let_chains))]
#![feature(let_else)]
#![feature(never_type)]
#![feature(rustc_attrs)]
)
} else if expected.is_empty() {
(
- format!("unexpected token: {}", actual),
+ format!("unexpected token: {actual}"),
(self.prev_token.span, "unexpected token after this".to_string()),
)
} else {
MultiSugg {
msg: format!("use `{}= 1` instead", kind.op.chr()),
patches: vec![
- (pre_span, format!("{{ let {} = ", tmp_var)),
+ (pre_span, format!("{{ let {tmp_var} = ")),
(post_span, format!("; {} {}= 1; {} }}", base_src, kind.op.chr(), tmp_var)),
],
applicability: Applicability::HasPlaceholders,
attrs: attrs.into(),
ty,
pat,
- span: lo.to(this.token.span),
+ span: lo.to(this.prev_token.span),
id: DUMMY_NODE_ID,
is_placeholder: false,
},
if !self.maybe_consume_incorrect_semicolon(&items) {
let msg = &format!("expected item, found {token_str}");
let mut err = self.struct_span_err(self.token.span, msg);
- err.span_label(self.token.span, "expected item");
+ let label = if self.is_kw_followed_by_ident(kw::Let) {
+ "consider using `const` or `static` instead of `let` for global variables"
+ } else {
+ "expected item"
+ };
+ err.span_label(self.token.span, label);
return Err(err);
}
}
}
match parse_item(self) {
Ok(None) => {
+ let is_unnecessary_semicolon = !items.is_empty()
+ // When the close delim is `)` in a case like the following, `token.kind` is expected to be `token::CloseDelim(Delimiter::Parenthesis)`,
+ // but the actual `token.kind` is `token::CloseDelim(Delimiter::Bracket)`.
+ // This is because the `token.kind` of the close delim is treated as the same as
+ // that of the open delim in `TokenTreesReader::parse_token_tree`, even if the delimiters of them are different.
+ // Therefore, `token.kind` should not be compared here.
+ //
+ // issue-60075.rs
+ // ```
+ // trait T {
+ // fn qux() -> Option<usize> {
+ // let _ = if true {
+ // });
+ // ^ this close delim
+ // Some(4)
+ // }
+ // ```
+ && self
+ .span_to_snippet(self.prev_token.span)
+ .map_or(false, |snippet| snippet == "}")
+ && self.token.kind == token::Semi;
+ let semicolon_span = self.token.span;
// We have to bail or we'll potentially never make progress.
let non_item_span = self.token.span;
self.consume_block(Delimiter::Brace, ConsumeClosingDelim::Yes);
- self.struct_span_err(non_item_span, "non-item in item list")
- .span_label(open_brace_span, "item list starts here")
+ let mut err = self.struct_span_err(non_item_span, "non-item in item list");
+ err.span_label(open_brace_span, "item list starts here")
.span_label(non_item_span, "non-item starts here")
- .span_label(self.prev_token.span, "item list ends here")
- .emit();
+ .span_label(self.prev_token.span, "item list ends here");
+ if is_unnecessary_semicolon {
+ err.span_suggestion(
+ semicolon_span,
+ "consider removing this semicolon",
+ "",
+ Applicability::MaybeIncorrect,
+ );
+ }
+ err.emit();
break;
}
Ok(Some(item)) => items.extend(item),
Applicability::MaybeIncorrect,
)
.emit();
+ } else if self.eat_keyword(kw::Let) {
+ let span = self.prev_token.span;
+ self.struct_span_err(const_span.to(span), "`const` and `let` are mutually exclusive")
+ .span_suggestion(
+ const_span.to(span),
+ "remove `let`",
+ "const",
+ Applicability::MaybeIncorrect,
+ )
+ .emit();
}
}
}
}
- if self.token.is_ident() {
- // This is likely another field; emit the diagnostic and keep going
+ if self.token.is_ident()
+ || (self.token.kind == TokenKind::Pound
+ && (self.look_ahead(1, |t| t == &token::OpenDelim(Delimiter::Bracket))))
+ {
+ // This is likely another field, TokenKind::Pound is used for `#[..]` attribute for next field,
+ // emit the diagnostic and keep going
err.span_suggestion(
sp,
"try adding a comma",
(pat, this.parse_ty_for_param()?)
} else {
debug!("parse_param_general ident_to_pat");
- let parser_snapshot_before_ty = this.clone();
+ let parser_snapshot_before_ty = this.create_snapshot_for_diagnostic();
this.eat_incorrect_doc_comment_for_param_type();
let mut ty = this.parse_ty_for_param();
if ty.is_ok()
// Recover from attempting to parse the argument as a type without pattern.
Err(err) => {
err.cancel();
- *this = parser_snapshot_before_ty;
+ this.restore_snapshot(parser_snapshot_before_ty);
this.recover_arg_parse()?
}
}
};
- let span = lo.until(this.token.span);
+ let span = lo.to(this.prev_token.span);
Ok((
Param {
return Ok(Some(stmt.into_inner()));
}
+ if self.token.is_keyword(kw::Mut) && self.is_keyword_ahead(1, &[kw::Let]) {
+ self.bump();
+ let mut_let_span = lo.to(self.token.span);
+ self.struct_span_err(mut_let_span, "invalid variable declaration")
+ .span_suggestion(
+ mut_let_span,
+ "switch the order of `mut` and `let`",
+ "let mut",
+ Applicability::MaybeIncorrect,
+ )
+ .emit();
+ }
+
Ok(Some(if self.token.is_keyword(kw::Let) {
self.parse_local_mk(lo, attrs, capture_semi, force_collect)?
} else if self.is_kw_followed_by_ident(kw::Mut) {
/// Parses a local variable declaration.
fn parse_local(&mut self, attrs: AttrVec) -> PResult<'a, P<Local>> {
let lo = self.prev_token.span;
+
+ if self.token.is_keyword(kw::Const) && self.look_ahead(1, |t| t.is_ident()) {
+ self.struct_span_err(
+ lo.to(self.token.span),
+ "`const` and `let` are mutually exclusive",
+ )
+ .span_suggestion(
+ lo.to(self.token.span),
+ "remove `let`",
+ "const",
+ Applicability::MaybeIncorrect,
+ )
+ .emit();
+ self.bump();
+ }
+
let (pat, colon) = self.parse_pat_before_ty(None, RecoverComma::Yes, "`let` bindings")?;
let (err, ty) = if colon {
| Target::ForeignStatic
| Target::ForeignTy
| Target::GenericParam(..)
- | Target::MacroDef => None,
+ | Target::MacroDef
+ | Target::PatField
+ | Target::ExprField => None,
} {
tcx.sess.emit_err(errors::DocAliasBadLocation { span, attr_str, location });
return false;
intravisit::walk_expr(self, expr)
}
+ fn visit_expr_field(&mut self, field: &'tcx hir::ExprField<'tcx>) {
+ self.check_attributes(field.hir_id, field.span, Target::ExprField, None);
+ intravisit::walk_expr_field(self, field)
+ }
+
fn visit_variant(&mut self, variant: &'tcx hir::Variant<'tcx>) {
self.check_attributes(variant.id, variant.span, Target::Variant, None);
intravisit::walk_variant(self, variant)
intravisit::walk_param(self, param);
}
+
+ fn visit_pat_field(&mut self, field: &'tcx hir::PatField<'tcx>) {
+ self.check_attributes(field.hir_id, field.span, Target::PatField, None);
+ intravisit::walk_pat_field(self, field);
+ }
}
fn is_c_like_enum(item: &Item<'_>) -> bool {
#![allow(rustc::potential_query_instability)]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![feature(iter_intersperse)]
-#![cfg_attr(bootstrap, feature(let_chains))]
#![feature(let_else)]
#![feature(map_try_insert)]
#![feature(min_specialization)]
use rustc_middle::ty::{self, DefIdTree, RootVariableMinCaptureList, Ty, TyCtxt};
use rustc_session::lint;
use rustc_span::symbol::{kw, sym, Symbol};
-use rustc_span::Span;
+use rustc_span::{BytePos, Span};
use std::collections::VecDeque;
use std::io;
.or_insert_with(|| (ln, var, vec![id_and_sp]));
});
+ let can_remove = matches!(&pat.kind, hir::PatKind::Struct(_, _, true));
+
for (_, (ln, var, hir_ids_and_spans)) in vars {
if self.used_on_entry(ln, var) {
let id = hir_ids_and_spans[0].0;
hir_ids_and_spans.into_iter().map(|(_, _, ident_span)| ident_span).collect();
on_used_on_entry(spans, id, ln, var);
} else {
- self.report_unused(hir_ids_and_spans, ln, var);
+ self.report_unused(hir_ids_and_spans, ln, var, can_remove);
}
}
}
+ #[tracing::instrument(skip(self), level = "INFO")]
fn report_unused(
&self,
hir_ids_and_spans: Vec<(HirId, Span, Span)>,
ln: LiveNode,
var: Variable,
+ can_remove: bool,
) {
let first_hir_id = hir_ids_and_spans[0].0;
.emit();
},
)
+ } else if can_remove {
+ self.ir.tcx.struct_span_lint_hir(
+ lint::builtin::UNUSED_VARIABLES,
+ first_hir_id,
+ hir_ids_and_spans.iter().map(|(_, pat_span, _)| *pat_span).collect::<Vec<_>>(),
+ |lint| {
+ let mut err = lint.build(&format!("unused variable: `{}`", name));
+ err.multipart_suggestion(
+ "try removing the field",
+ hir_ids_and_spans
+ .iter()
+ .map(|(_, pat_span, _)| {
+ let span = self
+ .ir
+ .tcx
+ .sess
+ .source_map()
+ .span_extend_to_next_char(*pat_span, ',', true);
+ (span.with_hi(BytePos(span.hi().0 + 1)), String::new())
+ })
+ .collect(),
+ Applicability::MachineApplicable,
+ );
+ err.emit();
+ },
+ );
} else {
let (shorthands, non_shorthands): (Vec<_>, Vec<_>) =
hir_ids_and_spans.iter().copied().partition(|(hir_id, _, ident_span)| {
AnnotationKind::Required,
InheritDeprecation::Yes,
InheritConstStability::No,
- InheritStability::No,
+ InheritStability::Yes,
|_| {},
);
}
fn visit_variant(&mut self, var: &'tcx Variant<'tcx>) {
self.check_missing_stability(self.tcx.hir().local_def_id(var.id), var.span);
+ if let Some(ctor_hir_id) = var.data.ctor_hir_id() {
+ self.check_missing_stability(self.tcx.hir().local_def_id(ctor_hir_id), var.span);
+ }
intravisit::walk_variant(self, var);
}
remaining_lib_features.remove(&sym::libc);
remaining_lib_features.remove(&sym::test);
- // We always collect the lib features declared in the current crate, even if there are
- // no unknown features, because the collection also does feature attribute validation.
- let local_defined_features = tcx.lib_features(());
- let mut all_lib_features: FxHashMap<_, _> =
- local_defined_features.to_vec().iter().map(|el| *el).collect();
- let mut implications = tcx.stability_implications(rustc_hir::def_id::LOCAL_CRATE).clone();
- for &cnum in tcx.crates(()) {
- implications.extend(tcx.stability_implications(cnum));
- all_lib_features.extend(tcx.defined_lib_features(cnum).iter().map(|el| *el));
- }
-
- // Check that every feature referenced by an `implied_by` exists (for features defined in the
- // local crate).
- for (implied_by, feature) in tcx.stability_implications(rustc_hir::def_id::LOCAL_CRATE) {
- // Only `implied_by` needs to be checked, `feature` is guaranteed to exist.
- if !all_lib_features.contains_key(implied_by) {
- let span = local_defined_features
- .stable
- .get(feature)
- .map(|(_, span)| span)
- .or_else(|| local_defined_features.unstable.get(feature))
- .expect("feature that implied another does not exist");
- tcx.sess
- .struct_span_err(
- *span,
- format!("feature `{implied_by}` implying `{feature}` does not exist"),
- )
- .emit();
- }
- }
-
- if !remaining_lib_features.is_empty() {
- for (feature, since) in all_lib_features.iter() {
+ /// For each feature in `defined_features`..
+ ///
+ /// - If it is in `remaining_lib_features` (those features with `#![feature(..)]` attributes in
+ /// the current crate), check if it is stable (or partially stable) and thus an unnecessary
+ /// attribute.
+ /// - If it is in `remaining_implications` (a feature that is referenced by an `implied_by`
+ /// from the current crate), then remove it from the remaining implications.
+ ///
+ /// Once this function has been invoked for every feature (local crate and all extern crates),
+ /// then..
+ ///
+ /// - If features remain in `remaining_lib_features`, then the user has enabled a feature that
+ /// does not exist.
+ /// - If features remain in `remaining_implications`, the `implied_by` refers to a feature that
+ /// does not exist.
+ ///
+ /// By structuring the code in this way: checking the features defined from each crate one at a
+ /// time, less loading from metadata is performed and thus compiler performance is improved.
+ fn check_features<'tcx>(
+ tcx: TyCtxt<'tcx>,
+ remaining_lib_features: &mut FxIndexMap<&Symbol, Span>,
+ remaining_implications: &mut FxHashMap<Symbol, Symbol>,
+ defined_features: &[(Symbol, Option<Symbol>)],
+ all_implications: &FxHashMap<Symbol, Symbol>,
+ ) {
+ for (feature, since) in defined_features {
if let Some(since) = since && let Some(span) = remaining_lib_features.get(&feature) {
// Warn if the user has enabled an already-stable lib feature.
- if let Some(implies) = implications.get(&feature) {
+ if let Some(implies) = all_implications.get(&feature) {
unnecessary_partially_stable_feature_lint(tcx, *span, *feature, *implies, *since);
} else {
unnecessary_stable_feature_lint(tcx, *span, *feature, *since);
}
+
}
- remaining_lib_features.remove(&feature);
- if remaining_lib_features.is_empty() {
+ remaining_lib_features.remove(feature);
+
+ // `feature` is the feature doing the implying, but `implied_by` is the feature with
+ // the attribute that establishes this relationship. `implied_by` is guaranteed to be a
+ // feature defined in the local crate because `remaining_implications` is only the
+ // implications from this crate.
+ remaining_implications.remove(feature);
+
+ if remaining_lib_features.is_empty() && remaining_implications.is_empty() {
break;
}
}
}
+ // All local crate implications need to have the feature that implies it confirmed to exist.
+ let mut remaining_implications =
+ tcx.stability_implications(rustc_hir::def_id::LOCAL_CRATE).clone();
+
+ // We always collect the lib features declared in the current crate, even if there are
+ // no unknown features, because the collection also does feature attribute validation.
+ let local_defined_features = tcx.lib_features(()).to_vec();
+ if !remaining_lib_features.is_empty() || !remaining_implications.is_empty() {
+ // Loading the implications of all crates is unavoidable to be able to emit the partial
+ // stabilization diagnostic, but it can be avoided when there are no
+ // `remaining_lib_features`.
+ let mut all_implications = remaining_implications.clone();
+ for &cnum in tcx.crates(()) {
+ all_implications.extend(tcx.stability_implications(cnum));
+ }
+
+ check_features(
+ tcx,
+ &mut remaining_lib_features,
+ &mut remaining_implications,
+ local_defined_features.as_slice(),
+ &all_implications,
+ );
+
+ for &cnum in tcx.crates(()) {
+ if remaining_lib_features.is_empty() && remaining_implications.is_empty() {
+ break;
+ }
+ check_features(
+ tcx,
+ &mut remaining_lib_features,
+ &mut remaining_implications,
+ tcx.defined_lib_features(cnum).to_vec().as_slice(),
+ &all_implications,
+ );
+ }
+ }
+
for (feature, span) in remaining_lib_features {
struct_span_err!(tcx.sess, span, E0635, "unknown feature `{}`", feature).emit();
}
+ for (implied_by, feature) in remaining_implications {
+ let local_defined_features = tcx.lib_features(());
+ let span = local_defined_features
+ .stable
+ .get(&feature)
+ .map(|(_, span)| span)
+ .or_else(|| local_defined_features.unstable.get(&feature))
+ .expect("feature that implied another does not exist");
+ tcx.sess
+ .struct_span_err(
+ *span,
+ format!("feature `{implied_by}` implying `{feature}` does not exist"),
+ )
+ .emit();
+ }
+
// FIXME(#44232): the `used_features` table no longer exists, so we
// don't lint about unused features. We should re-enable this one day!
}
#![feature(try_blocks)]
#![recursion_limit = "256"]
#![allow(rustc::potential_query_instability)]
-#![cfg_attr(not(bootstrap), deny(rustc::untranslatable_diagnostic))]
-#![cfg_attr(not(bootstrap), deny(rustc::diagnostic_outside_of_impl))]
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
mod errors;
let ns = source.namespace();
let is_expected = &|res| source.is_expected(res);
- let path_sep = |err: &mut Diagnostic, expr: &Expr| match expr.kind {
- ExprKind::Field(_, ident) => {
+ let path_sep = |err: &mut Diagnostic, expr: &Expr, kind: DefKind| {
+ const MESSAGE: &str = "use the path separator to refer to an item";
+
+ let (lhs_span, rhs_span) = match &expr.kind {
+ ExprKind::Field(base, ident) => (base.span, ident.span),
+ ExprKind::MethodCall(_, receiver, _, span) => (receiver.span, *span),
+ _ => return false,
+ };
+
+ if lhs_span.eq_ctxt(rhs_span) {
err.span_suggestion(
- expr.span,
- "use the path separator to refer to an item",
- format!("{}::{}", path_str, ident),
+ lhs_span.between(rhs_span),
+ MESSAGE,
+ "::",
Applicability::MaybeIncorrect,
);
true
- }
- ExprKind::MethodCall(ref segment, ..) => {
- let span = expr.span.with_hi(segment.ident.span.hi());
- err.span_suggestion(
- span,
- "use the path separator to refer to an item",
- format!("{}::{}", path_str, segment.ident),
+ } else if kind == DefKind::Struct
+ && let Some(lhs_source_span) = lhs_span.find_ancestor_inside(expr.span)
+ && let Ok(snippet) = self.r.session.source_map().span_to_snippet(lhs_source_span)
+ {
+ // The LHS is a type that originates from a macro call.
+ // We have to add angle brackets around it.
+
+ err.span_suggestion_verbose(
+ lhs_source_span.until(rhs_span),
+ MESSAGE,
+ format!("<{snippet}>::"),
Applicability::MaybeIncorrect,
);
true
+ } else {
+ // Either we were unable to obtain the source span / the snippet or
+ // the LHS originates from a macro call and it is not a type and thus
+ // there is no way to replace `.` with `::` and still somehow suggest
+ // valid Rust code.
+
+ false
}
- _ => false,
};
let find_span = |source: &PathSource<'_>, err: &mut Diagnostic| {
match source {
PathSource::Expr(Some(
parent @ Expr { kind: ExprKind::Field(..) | ExprKind::MethodCall(..), .. },
- )) if path_sep(err, &parent) => {}
+ )) if path_sep(err, &parent, DefKind::Struct) => {}
PathSource::Expr(
None
| Some(Expr {
}
}
}
- (Res::Def(DefKind::Mod, _), PathSource::Expr(Some(parent))) => {
- if !path_sep(err, &parent) {
+ (
+ Res::Def(kind @ (DefKind::Mod | DefKind::Trait), _),
+ PathSource::Expr(Some(parent)),
+ ) => {
+ if !path_sep(err, &parent, kind) {
return false;
}
}
#![feature(box_patterns)]
#![feature(drain_filter)]
#![feature(if_let_guard)]
-#![cfg_attr(bootstrap, feature(let_chains))]
#![feature(iter_intersperse)]
#![feature(let_else)]
#![feature(never_type)]
ret.insert((sym::debug_assertions, None));
}
// JUSTIFICATION: before wrapper fn is available
- #[cfg_attr(not(bootstrap), allow(rustc::bad_opt_access))]
+ #[allow(rustc::bad_opt_access)]
if sess.opts.crate_types.contains(&CrateType::ProcMacro) {
ret.insert((sym::proc_macro, None));
}
}
// JUSTIFICATION: before wrapper fn is available
-#[cfg_attr(not(bootstrap), allow(rustc::bad_opt_access))]
+#[allow(rustc::bad_opt_access)]
pub fn build_session_options(matches: &getopts::Matches) -> Options {
let color = parse_color(matches);
#![feature(if_let_guard)]
-#![cfg_attr(bootstrap, feature(let_chains))]
#![feature(let_else)]
#![feature(min_specialization)]
#![feature(never_type)]
/// `CodegenOptions`, think about how it influences incremental compilation. If in
/// doubt, specify `[TRACKED]`, which is always "correct" but might lead to
/// unnecessary re-compilation.
- #[cfg_attr(not(bootstrap), rustc_lint_opt_ty)]
+ #[rustc_lint_opt_ty]
pub struct Options {
/// The crate config requested for the session, which may be combined
/// with additional crate configurations during the compile process.
- #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::crate_types` instead of this field"))]
+ #[rustc_lint_opt_deny_field_access("use `Session::crate_types` instead of this field")]
crate_types: Vec<CrateType> [TRACKED],
optimize: OptLevel [TRACKED],
/// Include the `debug_assertions` flag in dependency tracking, since it
/// what rustc was invoked with, but massaged a bit to agree with
/// commands like `--emit llvm-ir` which they're often incompatible with
/// if we otherwise use the defaults of rustc.
- #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::codegen_units` instead of this field"))]
+ #[rustc_lint_opt_deny_field_access("use `Session::codegen_units` instead of this field")]
cli_forced_codegen_units: Option<usize> [UNTRACKED],
- #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::lto` instead of this field"))]
+ #[rustc_lint_opt_deny_field_access("use `Session::lto` instead of this field")]
cli_forced_thinlto_off: bool [UNTRACKED],
/// Remap source path prefixes in all output (messages, object files, debug, etc.).
),* ,) =>
(
#[derive(Clone)]
- #[cfg_attr(not(bootstrap), rustc_lint_opt_ty)]
+ #[rustc_lint_opt_ty]
pub struct $struct_name { $( $( #[$attr] )* pub $opt: $t),* }
impl Default for $struct_name {
impl Options {
// JUSTIFICATION: defn of the suggested wrapper fn
- #[cfg_attr(not(bootstrap), allow(rustc::bad_opt_access))]
+ #[allow(rustc::bad_opt_access)]
pub fn time_passes(&self) -> bool {
self.unstable_opts.time_passes || self.unstable_opts.time
}
impl CodegenOptions {
// JUSTIFICATION: defn of the suggested wrapper fn
- #[cfg_attr(not(bootstrap), allow(rustc::bad_opt_access))]
+ #[allow(rustc::bad_opt_access)]
pub fn instrument_coverage(&self) -> InstrumentCoverage {
self.instrument_coverage.unwrap_or(InstrumentCoverage::Off)
}
ar: String = (String::new(), parse_string, [UNTRACKED],
"this option is deprecated and does nothing"),
- #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::code_model` instead of this field"))]
+ #[rustc_lint_opt_deny_field_access("use `Session::code_model` instead of this field")]
code_model: Option<CodeModel> = (None, parse_code_model, [TRACKED],
"choose the code model to use (`rustc --print code-models` for details)"),
codegen_units: Option<usize> = (None, parse_opt_number, [UNTRACKED],
"extra data to put in each output filename"),
force_frame_pointers: Option<bool> = (None, parse_opt_bool, [TRACKED],
"force use of the frame pointers"),
- #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::must_emit_unwind_tables` instead of this field"))]
+ #[rustc_lint_opt_deny_field_access("use `Session::must_emit_unwind_tables` instead of this field")]
force_unwind_tables: Option<bool> = (None, parse_opt_bool, [TRACKED],
"force use of unwind tables"),
incremental: Option<String> = (None, parse_opt_string, [UNTRACKED],
"enable incremental compilation"),
inline_threshold: Option<u32> = (None, parse_opt_number, [TRACKED],
"set the threshold for inlining a function"),
- #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::instrument_coverage` instead of this field"))]
+ #[rustc_lint_opt_deny_field_access("use `Session::instrument_coverage` instead of this field")]
instrument_coverage: Option<InstrumentCoverage> = (None, parse_instrument_coverage, [TRACKED],
"instrument the generated code to support LLVM source-based code coverage \
reports (note, the compiler build config must include `profiler = true`); \
"a single extra argument to append to the linker invocation (can be used several times)"),
link_args: Vec<String> = (Vec::new(), parse_list, [UNTRACKED],
"extra arguments to append to the linker invocation (space separated)"),
- #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::link_dead_code` instead of this field"))]
+ #[rustc_lint_opt_deny_field_access("use `Session::link_dead_code` instead of this field")]
link_dead_code: Option<bool> = (None, parse_opt_bool, [TRACKED],
"keep dead code at link time (useful for code coverage) (default: no)"),
link_self_contained: Option<bool> = (None, parse_opt_bool, [UNTRACKED],
"generate build artifacts that are compatible with linker-based LTO"),
llvm_args: Vec<String> = (Vec::new(), parse_list, [TRACKED],
"a list of arguments to pass to LLVM (space separated)"),
- #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::lto` instead of this field"))]
+ #[rustc_lint_opt_deny_field_access("use `Session::lto` instead of this field")]
lto: LtoCli = (LtoCli::Unspecified, parse_lto, [TRACKED],
"perform LLVM link-time optimizations"),
metadata: Vec<String> = (Vec::new(), parse_list, [TRACKED],
"disable LLVM's SLP vectorization pass"),
opt_level: String = ("0".to_string(), parse_string, [TRACKED],
"optimization level (0-3, s, or z; default: 0)"),
- #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::overflow_checks` instead of this field"))]
+ #[rustc_lint_opt_deny_field_access("use `Session::overflow_checks` instead of this field")]
overflow_checks: Option<bool> = (None, parse_opt_bool, [TRACKED],
"use overflow checks for integer arithmetic"),
- #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::panic_strategy` instead of this field"))]
+ #[rustc_lint_opt_deny_field_access("use `Session::panic_strategy` instead of this field")]
panic: Option<PanicStrategy> = (None, parse_opt_panic_strategy, [TRACKED],
"panic strategy to compile crate with"),
passes: Vec<String> = (Vec::new(), parse_list, [TRACKED],
"compile the program with profiling instrumentation"),
profile_use: Option<PathBuf> = (None, parse_opt_pathbuf, [TRACKED],
"use the given `.profdata` file for profile-guided optimization"),
- #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::relocation_model` instead of this field"))]
+ #[rustc_lint_opt_deny_field_access("use `Session::relocation_model` instead of this field")]
relocation_model: Option<RelocModel> = (None, parse_relocation_model, [TRACKED],
"control generation of position-independent code (PIC) \
(`rustc --print relocation-models` for details)"),
"save all temporary output files during compilation (default: no)"),
soft_float: bool = (false, parse_bool, [TRACKED],
"use soft float ABI (*eabihf targets only) (default: no)"),
- #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::split_debuginfo` instead of this field"))]
+ #[rustc_lint_opt_deny_field_access("use `Session::split_debuginfo` instead of this field")]
split_debuginfo: Option<SplitDebuginfo> = (None, parse_split_debuginfo, [TRACKED],
"how to handle split-debuginfo, a platform-specific option"),
strip: Strip = (Strip::None, parse_strip, [UNTRACKED],
"encode MIR of all functions into the crate metadata (default: no)"),
assume_incomplete_release: bool = (false, parse_bool, [TRACKED],
"make cfg(version) treat the current version as incomplete (default: no)"),
- #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::asm_comments` instead of this field"))]
+ #[rustc_lint_opt_deny_field_access("use `Session::asm_comments` instead of this field")]
asm_comments: bool = (false, parse_bool, [TRACKED],
"generate comments into the assembly (may change behavior) (default: no)"),
assert_incr_state: Option<String> = (None, parse_opt_string, [UNTRACKED],
"assert that the incremental cache is in given state: \
either `loaded` or `not-loaded`."),
- #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::binary_dep_depinfo` instead of this field"))]
+ #[rustc_lint_opt_deny_field_access("use `Session::binary_dep_depinfo` instead of this field")]
binary_dep_depinfo: bool = (false, parse_bool, [TRACKED],
"include artifacts (sysroot, crate dependencies) used during compilation in dep-info \
(default: no)"),
"emit the bc module with thin LTO info (default: yes)"),
export_executable_symbols: bool = (false, parse_bool, [TRACKED],
"export symbols from executables, as if they were dynamic libraries"),
- #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::fewer_names` instead of this field"))]
+ extra_const_ub_checks: bool = (false, parse_bool, [TRACKED],
+ "turns on more checks to detect const UB, which can be slow (default: no)"),
+ #[rustc_lint_opt_deny_field_access("use `Session::fewer_names` instead of this field")]
fewer_names: Option<bool> = (None, parse_opt_bool, [TRACKED],
"reduce memory use by retaining fewer names within compilation artifacts (LLVM-IR) \
(default: no)"),
"control whether `#[inline]` functions are in all CGUs"),
input_stats: bool = (false, parse_bool, [UNTRACKED],
"gather statistics about the input (default: no)"),
- #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::instrument_coverage` instead of this field"))]
+ #[rustc_lint_opt_deny_field_access("use `Session::instrument_coverage` instead of this field")]
instrument_coverage: Option<InstrumentCoverage> = (None, parse_instrument_coverage, [TRACKED],
"instrument the generated code to support LLVM source-based code coverage \
reports (note, the compiler build config must include `profiler = true`); \
`=except-unused-generics`
`=except-unused-functions`
`=off` (default)"),
- #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::instrument_mcount` instead of this field"))]
+ #[rustc_lint_opt_deny_field_access("use `Session::instrument_mcount` instead of this field")]
instrument_mcount: bool = (false, parse_bool, [TRACKED],
"insert function instrument code for mcount-based tracing (default: no)"),
keep_hygiene_data: bool = (false, parse_bool, [UNTRACKED],
merge_functions: Option<MergeFunctions> = (None, parse_merge_functions, [TRACKED],
"control the operation of the MergeFunctions LLVM pass, taking \
the same values as the target option of the same name"),
- #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::meta_stats` instead of this field"))]
+ #[rustc_lint_opt_deny_field_access("use `Session::meta_stats` instead of this field")]
meta_stats: bool = (false, parse_bool, [UNTRACKED],
"gather metadata statistics (default: no)"),
mir_emit_retag: bool = (false, parse_bool, [TRACKED],
disabled by other flags as usual."),
mir_pretty_relative_line_numbers: bool = (false, parse_bool, [UNTRACKED],
"use line numbers relative to the function in mir pretty printing"),
- #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::mir_opt_level` instead of this field"))]
+ #[rustc_lint_opt_deny_field_access("use `Session::mir_opt_level` instead of this field")]
mir_opt_level: Option<usize> = (None, parse_opt_number, [TRACKED],
"MIR optimization level (0-4; default: 1 in non optimized builds and 2 in optimized builds)"),
move_size_limit: Option<usize> = (None, parse_opt_number, [TRACKED],
See #77382 and #74551."),
print_fuel: Option<String> = (None, parse_opt_string, [TRACKED],
"make rustc print the total optimization fuel used by a crate"),
- #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::print_llvm_passes` instead of this field"))]
+ #[rustc_lint_opt_deny_field_access("use `Session::print_llvm_passes` instead of this field")]
print_llvm_passes: bool = (false, parse_bool, [UNTRACKED],
"print the LLVM optimization passes being run (default: no)"),
print_mono_items: Option<String> = (None, parse_opt_string, [UNTRACKED],
"exclude spans when debug-printing compiler state (default: no)"),
src_hash_algorithm: Option<SourceFileHashAlgorithm> = (None, parse_src_file_hash, [TRACKED],
"hash algorithm of source files in debug info (`md5`, `sha1`, or `sha256`)"),
- #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::stack_protector` instead of this field"))]
+ #[rustc_lint_opt_deny_field_access("use `Session::stack_protector` instead of this field")]
stack_protector: StackProtector = (StackProtector::None, parse_stack_protector, [TRACKED],
"control stack smash protection strategy (`rustc --print stack-protector-strategies` for details)"),
strict_init_checks: bool = (false, parse_bool, [TRACKED],
symbol_mangling_version: Option<SymbolManglingVersion> = (None,
parse_symbol_mangling_version, [TRACKED],
"which mangling version to use for symbol names ('legacy' (default) or 'v0')"),
- #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::teach` instead of this field"))]
+ #[rustc_lint_opt_deny_field_access("use `Session::teach` instead of this field")]
teach: bool = (false, parse_bool, [TRACKED],
"show extended diagnostic help (default: no)"),
temps_dir: Option<String> = (None, parse_opt_string, [UNTRACKED],
"emit directionality isolation markers in translated diagnostics"),
tune_cpu: Option<String> = (None, parse_opt_string, [TRACKED],
"select processor to schedule for (`rustc --print target-cpus` for details)"),
- #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::lto` instead of this field"))]
+ #[rustc_lint_opt_deny_field_access("use `Session::lto` instead of this field")]
thinlto: Option<bool> = (None, parse_opt_bool, [TRACKED],
"enable ThinLTO when possible"),
thir_unsafeck: bool = (false, parse_bool, [TRACKED],
/// a sequential compiler for now. This'll likely be adjusted
/// in the future. Note that -Zthreads=0 is the way to get
/// the num_cpus behavior.
- #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::threads` instead of this field"))]
+ #[rustc_lint_opt_deny_field_access("use `Session::threads` instead of this field")]
threads: usize = (1, parse_threads, [UNTRACKED],
"use a thread pool with N threads"),
- #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::time_passes` instead of this field"))]
+ #[rustc_lint_opt_deny_field_access("use `Session::time_passes` instead of this field")]
time: bool = (false, parse_bool, [UNTRACKED],
"measure time of rustc processes (default: no)"),
- #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::time_llvm_passes` instead of this field"))]
+ #[rustc_lint_opt_deny_field_access("use `Session::time_llvm_passes` instead of this field")]
time_llvm_passes: bool = (false, parse_bool, [UNTRACKED],
"measure time of each LLVM pass (default: no)"),
- #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::time_passes` instead of this field"))]
+ #[rustc_lint_opt_deny_field_access("use `Session::time_passes` instead of this field")]
time_passes: bool = (false, parse_bool, [UNTRACKED],
"measure time of each rustc pass (default: no)"),
- #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::tls_model` instead of this field"))]
+ #[rustc_lint_opt_deny_field_access("use `Session::tls_model` instead of this field")]
tls_model: Option<TlsModel> = (None, parse_tls_model, [TRACKED],
"choose the TLS model to use (`rustc --print tls-models` for details)"),
trace_macros: bool = (false, parse_bool, [UNTRACKED],
"enable unsound and buggy MIR optimizations (default: no)"),
/// This name is kind of confusing: Most unstable options enable something themselves, while
/// this just allows "normal" options to be feature-gated.
- #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::unstable_options` instead of this field"))]
+ #[rustc_lint_opt_deny_field_access("use `Session::unstable_options` instead of this field")]
unstable_options: bool = (false, parse_bool, [UNTRACKED],
"adds unstable command line options to rustc interface (default: no)"),
use_ctors_section: Option<bool> = (None, parse_opt_bool, [TRACKED],
"use legacy .ctors section for initializers rather than .init_array"),
validate_mir: bool = (false, parse_bool, [UNTRACKED],
"validate MIR after each transformation"),
- #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::verbose` instead of this field"))]
+ #[rustc_lint_opt_deny_field_access("use `Session::verbose` instead of this field")]
verbose: bool = (false, parse_bool, [UNTRACKED],
"in general, enable more debug printouts (default: no)"),
- #[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::verify_llvm_ir` instead of this field"))]
+ #[rustc_lint_opt_deny_field_access("use `Session::verify_llvm_ir` instead of this field")]
verify_llvm_ir: bool = (false, parse_bool, [TRACKED],
"verify LLVM IR (default: no)"),
virtual_function_elimination: bool = (false, parse_bool, [TRACKED],
let found_positive = requested_features.clone().any(|r| r == "+crt-static");
// JUSTIFICATION: necessary use of crate_types directly (see FIXME below)
- #[cfg_attr(not(bootstrap), allow(rustc::bad_opt_access))]
+ #[allow(rustc::bad_opt_access)]
if found_positive || found_negative {
found_positive
} else if crate_type == Some(CrateType::ProcMacro)
}
// JUSTIFICATION: defn of the suggested wrapper fns
-#[cfg_attr(not(bootstrap), allow(rustc::bad_opt_access))]
+#[allow(rustc::bad_opt_access)]
impl Session {
pub fn verbose(&self) -> bool {
self.opts.unstable_opts.verbose
}
// JUSTIFICATION: part of session construction
-#[cfg_attr(not(bootstrap), allow(rustc::bad_opt_access))]
+#[allow(rustc::bad_opt_access)]
fn default_emitter(
sopts: &config::Options,
registry: rustc_errors::registry::Registry,
}
// JUSTIFICATION: literally session construction
-#[cfg_attr(not(bootstrap), allow(rustc::bad_opt_access))]
+#[allow(rustc::bad_opt_access)]
pub fn build_session(
sopts: config::Options,
local_crate_source_file: Option<PathBuf>,
/// If it is useful to have a Session available already for validating a commandline argument, you
/// can do so here.
// JUSTIFICATION: needs to access args to validate them
-#[cfg_attr(not(bootstrap), allow(rustc::bad_opt_access))]
+#[allow(rustc::bad_opt_access)]
fn validate_commandline_args_with_session_available(sess: &Session) {
// Since we don't know if code in an rlib will be linked to statically or
// dynamically downstream, rustc generates `__imp_` symbols that help linkers
})
}
- /// Extends the given `Span` to just after the next occurrence of `c`.
+ /// Extends the given `Span` to just before the next occurrence of `c`.
pub fn span_extend_to_next_char(&self, sp: Span, c: char, accept_newlines: bool) -> Span {
if let Ok(next_source) = self.span_to_next_source(sp) {
let next_source = next_source.split(c).next().unwrap_or("");
])
}
-pub(super) fn pre_musl_fallback() -> CrtObjects {
+pub(super) fn pre_musl_self_contained() -> CrtObjects {
new(&[
(LinkOutputKind::DynamicNoPicExe, &["crt1.o", "crti.o", "crtbegin.o"]),
(LinkOutputKind::DynamicPicExe, &["Scrt1.o", "crti.o", "crtbeginS.o"]),
])
}
-pub(super) fn post_musl_fallback() -> CrtObjects {
+pub(super) fn post_musl_self_contained() -> CrtObjects {
new(&[
(LinkOutputKind::DynamicNoPicExe, &["crtend.o", "crtn.o"]),
(LinkOutputKind::DynamicPicExe, &["crtendS.o", "crtn.o"]),
])
}
-pub(super) fn pre_mingw_fallback() -> CrtObjects {
+pub(super) fn pre_mingw_self_contained() -> CrtObjects {
new(&[
(LinkOutputKind::DynamicNoPicExe, &["crt2.o", "rsbegin.o"]),
(LinkOutputKind::DynamicPicExe, &["crt2.o", "rsbegin.o"]),
])
}
-pub(super) fn post_mingw_fallback() -> CrtObjects {
+pub(super) fn post_mingw_self_contained() -> CrtObjects {
all("rsend.o")
}
all("rsend.o")
}
-pub(super) fn pre_wasi_fallback() -> CrtObjects {
+pub(super) fn pre_wasi_self_contained() -> CrtObjects {
// Use crt1-command.o instead of crt1.o to enable support for new-style
// commands. See https://reviews.llvm.org/D81689 for more info.
new(&[
])
}
-pub(super) fn post_wasi_fallback() -> CrtObjects {
+pub(super) fn post_wasi_self_contained() -> CrtObjects {
new(&[])
}
-/// Which logic to use to determine whether to fall back to the "self-contained" mode or not.
+/// Which logic to use to determine whether to use self-contained linking mode
+/// if `-Clink-self-contained` is not specified explicitly.
#[derive(Clone, Copy, PartialEq, Hash, Debug)]
-pub enum CrtObjectsFallback {
+pub enum LinkSelfContainedDefault {
+ False,
+ True,
Musl,
Mingw,
- Wasm,
}
-impl FromStr for CrtObjectsFallback {
+impl FromStr for LinkSelfContainedDefault {
type Err = ();
- fn from_str(s: &str) -> Result<CrtObjectsFallback, ()> {
+ fn from_str(s: &str) -> Result<LinkSelfContainedDefault, ()> {
Ok(match s {
- "musl" => CrtObjectsFallback::Musl,
- "mingw" => CrtObjectsFallback::Mingw,
- "wasm" => CrtObjectsFallback::Wasm,
+ "false" => LinkSelfContainedDefault::False,
+ "true" | "wasm" => LinkSelfContainedDefault::True,
+ "musl" => LinkSelfContainedDefault::Musl,
+ "mingw" => LinkSelfContainedDefault::Mingw,
_ => return Err(()),
})
}
}
-impl ToJson for CrtObjectsFallback {
+impl ToJson for LinkSelfContainedDefault {
fn to_json(&self) -> Json {
match *self {
- CrtObjectsFallback::Musl => "musl",
- CrtObjectsFallback::Mingw => "mingw",
- CrtObjectsFallback::Wasm => "wasm",
+ LinkSelfContainedDefault::False => "false",
+ LinkSelfContainedDefault::True => "true",
+ LinkSelfContainedDefault::Musl => "musl",
+ LinkSelfContainedDefault::Mingw => "mingw",
}
.to_json()
}
-use crate::spec::crt_objects::{self, CrtObjectsFallback};
+use crate::spec::crt_objects::{self, LinkSelfContainedDefault};
use crate::spec::TargetOptions;
pub fn opts() -> TargetOptions {
let mut base = super::linux_base::opts();
base.env = "musl".into();
- base.pre_link_objects_fallback = crt_objects::pre_musl_fallback();
- base.post_link_objects_fallback = crt_objects::post_musl_fallback();
- base.crt_objects_fallback = Some(CrtObjectsFallback::Musl);
+ base.pre_link_objects_self_contained = crt_objects::pre_musl_self_contained();
+ base.post_link_objects_self_contained = crt_objects::post_musl_self_contained();
+ base.link_self_contained = LinkSelfContainedDefault::Musl;
// These targets statically link libc by default
base.crt_static_default = true;
use crate::abi::Endian;
use crate::json::{Json, ToJson};
use crate::spec::abi::{lookup as lookup_abi, Abi};
-use crate::spec::crt_objects::{CrtObjects, CrtObjectsFallback};
+use crate::spec::crt_objects::{CrtObjects, LinkSelfContainedDefault};
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
use rustc_span::symbol::{sym, Symbol};
/// Objects to link before and after all other object code.
pub pre_link_objects: CrtObjects,
pub post_link_objects: CrtObjects,
- /// Same as `(pre|post)_link_objects`, but when we fail to pull the objects with help of the
- /// target's native gcc and fall back to the "self-contained" mode and pull them manually.
- /// See `crt_objects.rs` for some more detailed documentation.
- pub pre_link_objects_fallback: CrtObjects,
- pub post_link_objects_fallback: CrtObjects,
- /// Which logic to use to determine whether to fall back to the "self-contained" mode or not.
- pub crt_objects_fallback: Option<CrtObjectsFallback>,
+ /// Same as `(pre|post)_link_objects`, but when self-contained linking mode is enabled.
+ pub pre_link_objects_self_contained: CrtObjects,
+ pub post_link_objects_self_contained: CrtObjects,
+ pub link_self_contained: LinkSelfContainedDefault,
/// Linker arguments that are unconditionally passed after any
/// user-defined but before post-link objects. Standard platform
relro_level: RelroLevel::None,
pre_link_objects: Default::default(),
post_link_objects: Default::default(),
- pre_link_objects_fallback: Default::default(),
- post_link_objects_fallback: Default::default(),
- crt_objects_fallback: None,
+ pre_link_objects_self_contained: Default::default(),
+ post_link_objects_self_contained: Default::default(),
+ link_self_contained: LinkSelfContainedDefault::False,
late_link_args: LinkArgs::new(),
late_link_args_dynamic: LinkArgs::new(),
late_link_args_static: LinkArgs::new(),
Ok::<(), String>(())
} );
- ($key_name:ident, crt_objects_fallback) => ( {
- let name = (stringify!($key_name)).replace("_", "-");
- obj.remove(&name).and_then(|o| o.as_str().and_then(|s| {
- match s.parse::<CrtObjectsFallback>() {
- Ok(fallback) => base.$key_name = Some(fallback),
- _ => return Some(Err(format!("'{}' is not a valid CRT objects fallback. \
- Use 'musl', 'mingw' or 'wasm'", s))),
+ ($key_name:ident = $json_name:expr, link_self_contained) => ( {
+ let name = $json_name;
+ obj.remove(name).and_then(|o| o.as_str().and_then(|s| {
+ match s.parse::<LinkSelfContainedDefault>() {
+ Ok(lsc_default) => base.$key_name = lsc_default,
+ _ => return Some(Err(format!("'{}' is not a valid `-Clink-self-contained` default. \
+ Use 'false', 'true', 'musl' or 'mingw'", s))),
}
Some(Ok(()))
})).unwrap_or(Ok(()))
} );
- ($key_name:ident, link_objects) => ( {
- let name = (stringify!($key_name)).replace("_", "-");
- if let Some(val) = obj.remove(&name) {
+ ($key_name:ident = $json_name:expr, link_objects) => ( {
+ let name = $json_name;
+ if let Some(val) = obj.remove(name) {
let obj = val.as_object().ok_or_else(|| format!("{}: expected a \
JSON object with fields per CRT object kind.", name))?;
let mut args = CrtObjects::new();
key!(linker_flavor, LinkerFlavor)?;
key!(linker, optional);
key!(lld_flavor, LldFlavor)?;
- key!(pre_link_objects, link_objects);
- key!(post_link_objects, link_objects);
- key!(pre_link_objects_fallback, link_objects);
- key!(post_link_objects_fallback, link_objects);
- key!(crt_objects_fallback, crt_objects_fallback)?;
+ key!(pre_link_objects = "pre-link-objects", link_objects);
+ key!(post_link_objects = "post-link-objects", link_objects);
+ key!(pre_link_objects_self_contained = "pre-link-objects-fallback", link_objects);
+ key!(post_link_objects_self_contained = "post-link-objects-fallback", link_objects);
+ key!(link_self_contained = "crt-objects-fallback", link_self_contained)?;
key!(pre_link_args, link_args);
key!(late_link_args, link_args);
key!(late_link_args_dynamic, link_args);
target_option_val!(lld_flavor);
target_option_val!(pre_link_objects);
target_option_val!(post_link_objects);
- target_option_val!(pre_link_objects_fallback);
- target_option_val!(post_link_objects_fallback);
- target_option_val!(crt_objects_fallback);
+ target_option_val!(pre_link_objects_self_contained, "pre-link-objects-fallback");
+ target_option_val!(post_link_objects_self_contained, "post-link-objects-fallback");
+ target_option_val!(link_self_contained, "crt-objects-fallback");
target_option_val!(link_args - pre_link_args);
target_option_val!(link_args - late_link_args);
target_option_val!(link_args - late_link_args_dynamic);
}
assert!(
- (self.pre_link_objects_fallback.is_empty()
- && self.post_link_objects_fallback.is_empty())
- || self.crt_objects_fallback.is_some()
+ (self.pre_link_objects_self_contained.is_empty()
+ && self.post_link_objects_self_contained.is_empty())
+ || self.link_self_contained != LinkSelfContainedDefault::False
);
// If your target really needs to deviate from the rules below,
options.linker_flavor = LinkerFlavor::Lld(LldFlavor::Wasm);
options.add_pre_link_args(LinkerFlavor::Gcc, &["--target=wasm32-wasi"]);
- options.pre_link_objects_fallback = crt_objects::pre_wasi_fallback();
- options.post_link_objects_fallback = crt_objects::post_wasi_fallback();
+ options.pre_link_objects_self_contained = crt_objects::pre_wasi_self_contained();
+ options.post_link_objects_self_contained = crt_objects::post_wasi_self_contained();
// Right now this is a bit of a workaround but we're currently saying that
// the target by default has a static crt which we're taking as a signal
-use super::crt_objects::CrtObjectsFallback;
+use super::crt_objects::LinkSelfContainedDefault;
use super::{cvs, LinkerFlavor, LldFlavor, PanicStrategy, RelocModel, TargetOptions, TlsModel};
pub fn options() -> TargetOptions {
pre_link_args,
- crt_objects_fallback: Some(CrtObjectsFallback::Wasm),
+ // FIXME: Figure out cases in which WASM needs to link with a native toolchain.
+ link_self_contained: LinkSelfContainedDefault::True,
// This has no effect in LLVM 8 or prior, but in LLVM 9 and later when
// PIC code is implemented this has quite a drastic effect if it stays
-use crate::spec::crt_objects::{self, CrtObjectsFallback};
+use crate::spec::crt_objects::{self, LinkSelfContainedDefault};
use crate::spec::{cvs, LinkerFlavor, TargetOptions};
pub fn opts() -> TargetOptions {
pre_link_args,
pre_link_objects: crt_objects::pre_mingw(),
post_link_objects: crt_objects::post_mingw(),
- pre_link_objects_fallback: crt_objects::pre_mingw_fallback(),
- post_link_objects_fallback: crt_objects::post_mingw_fallback(),
- crt_objects_fallback: Some(CrtObjectsFallback::Mingw),
+ pre_link_objects_self_contained: crt_objects::pre_mingw_self_contained(),
+ post_link_objects_self_contained: crt_objects::post_mingw_self_contained(),
+ link_self_contained: LinkSelfContainedDefault::Mingw,
late_link_args,
late_link_args_dynamic,
late_link_args_static,
#![feature(drain_filter)]
#![feature(hash_drain_filter)]
#![feature(label_break_value)]
-#![cfg_attr(bootstrap, feature(let_chains))]
#![feature(let_else)]
#![feature(if_let_guard)]
#![feature(never_type)]
tcx.impl_subject(impl1_def_id),
) {
Ok(s) => s,
- Err(err) => bug!("failed to fully normalize {:?}: {:?}", impl1_def_id, err),
+ Err(err) => {
+ tcx.sess.delay_span_bug(
+ tcx.def_span(impl1_def_id),
+ format!("failed to fully normalize {:?}: {:?}", impl1_def_id, err),
+ );
+ return false;
+ }
};
// Attempt to prove that impl2 applies, given all of the above.
result
}
- // FIXME: Constants should participate in orphan checking.
+ /// All possible values for a constant parameter already exist
+ /// in the crate defining the trait, so they are always non-local[^1].
+ ///
+ /// Because there's no way to have an impl where the first local
+ /// generic argument is a constant, we also don't have to fail
+ /// the orphan check when encountering a parameter or a generic constant.
+ ///
+ /// This means that we can completely ignore constants during the orphan check.
+ ///
+ /// See `src/test/ui/coherence/const-generics-orphan-check-ok.rs` for examples.
+ ///
+ /// [^1]: This might not hold for function pointers or trait objects in the future.
+ /// As these should be quite rare as const arguments and especially rare as impl
+ /// parameters, allowing uncovered const parameters in impls seems more useful
+ /// than allowing `impl<T> Trait<local_fn_ptr, T> for i32` to compile.
fn visit_const(&mut self, _c: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
ControlFlow::CONTINUE
}
}
self.probe(|_| {
- let err_buf;
- let mut err = &error.err;
+ let mut err = error.err;
let mut values = None;
// try to find the mismatched types to report the error with.
| ObligationCauseCode::ObjectCastObligation(..)
| ObligationCauseCode::OpaqueType
);
- if let Err(error) = self.at(&obligation.cause, obligation.param_env).eq_exp(
+ if let Err(new_err) = self.at(&obligation.cause, obligation.param_env).eq_exp(
is_normalized_ty_expected,
normalized_ty,
data.term,
) {
values = Some((data, is_normalized_ty_expected, normalized_ty, data.term));
- err_buf = error;
- err = &err_buf;
+ err = new_err;
}
}
if resolved_ty == ty {
// No progress, bail out to prevent "livelock".
return None;
+ } else {
+ resolved_ty
}
-
- resolved_ty
}
_ => ty,
}
}
GenericArgKind::Const(ct) => {
match ct.kind() {
- ty::ConstKind::Infer(infer) => {
- let resolved = infcx.shallow_resolve(infer);
- if resolved == infer {
+ ty::ConstKind::Infer(_) => {
+ let resolved = infcx.shallow_resolve(ct);
+ if resolved == ct {
// No progress.
return None;
+ } else {
+ resolved
}
-
- infcx
- .tcx
- .mk_const(ty::ConstS { kind: ty::ConstKind::Infer(resolved), ty: ct.ty() })
}
_ => ct,
}
};
use rustc_trait_selection::traits::wf::object_region_bounds;
-use smallvec::SmallVec;
+use smallvec::{smallvec, SmallVec};
use std::collections::BTreeSet;
use std::slice;
return (tcx.intern_substs(&[]), arg_count);
}
- let is_object = self_ty.map_or(false, |ty| ty == self.tcx().types.trait_object_dummy_self);
-
struct SubstsForAstPathCtxt<'a, 'tcx> {
astconv: &'a (dyn AstConv<'tcx> + 'a),
def_id: DefId,
generic_args: &'a GenericArgs<'a>,
span: Span,
- missing_type_params: Vec<Symbol>,
inferred_params: Vec<Span>,
infer_args: bool,
- is_object: bool,
- }
-
- impl<'tcx, 'a> SubstsForAstPathCtxt<'tcx, 'a> {
- fn default_needs_object_self(&mut self, param: &ty::GenericParamDef) -> bool {
- let tcx = self.astconv.tcx();
- if let GenericParamDefKind::Type { has_default, .. } = param.kind {
- if self.is_object && has_default {
- let default_ty = tcx.at(self.span).type_of(param.def_id);
- let self_param = tcx.types.self_param;
- if default_ty.walk().any(|arg| arg == self_param.into()) {
- // There is no suitable inference default for a type parameter
- // that references self, in an object type.
- return true;
- }
- }
- }
-
- false
- }
}
impl<'a, 'tcx> CreateSubstsForGenericArgsCtxt<'a, 'tcx> for SubstsForAstPathCtxt<'a, 'tcx> {
GenericParamDefKind::Type { has_default, .. } => {
if !infer_args && has_default {
// No type parameter provided, but a default exists.
-
- // If we are converting an object type, then the
- // `Self` parameter is unknown. However, some of the
- // other type parameters may reference `Self` in their
- // defaults. This will lead to an ICE if we are not
- // careful!
- if self.default_needs_object_self(param) {
- self.missing_type_params.push(param.name);
- tcx.ty_error().into()
- } else {
- // This is a default type parameter.
- let substs = substs.unwrap();
- if substs.iter().any(|arg| match arg.unpack() {
- GenericArgKind::Type(ty) => ty.references_error(),
- _ => false,
- }) {
- // Avoid ICE #86756 when type error recovery goes awry.
- return tcx.ty_error().into();
- }
- self.astconv
- .normalize_ty(
- self.span,
- EarlyBinder(tcx.at(self.span).type_of(param.def_id))
- .subst(tcx, substs),
- )
- .into()
+ let substs = substs.unwrap();
+ if substs.iter().any(|arg| match arg.unpack() {
+ GenericArgKind::Type(ty) => ty.references_error(),
+ _ => false,
+ }) {
+ // Avoid ICE #86756 when type error recovery goes awry.
+ return tcx.ty_error().into();
}
+ self.astconv
+ .normalize_ty(
+ self.span,
+ EarlyBinder(tcx.at(self.span).type_of(param.def_id))
+ .subst(tcx, substs),
+ )
+ .into()
} else if infer_args {
- // No type parameters were provided, we can infer all.
- let param = if !self.default_needs_object_self(param) {
- Some(param)
- } else {
- None
- };
- self.astconv.ty_infer(param, self.span).into()
+ self.astconv.ty_infer(Some(param), self.span).into()
} else {
// We've already errored above about the mismatch.
tcx.ty_error().into()
def_id,
span,
generic_args,
- missing_type_params: vec![],
inferred_params: vec![],
infer_args,
- is_object,
};
let substs = Self::create_substs_for_generic_args(
tcx,
&mut substs_ctx,
);
- self.complain_about_missing_type_params(
- substs_ctx.missing_type_params,
- def_id,
- span,
- generic_args.args.is_empty(),
- );
-
debug!(
"create_substs_for_ast_path(generic_params={:?}, self_ty={:?}) -> {:?}",
generics, self_ty, substs
// Erase the `dummy_self` (`trait_object_dummy_self`) used above.
let existential_trait_refs = regular_traits.iter().map(|i| {
i.trait_ref().map_bound(|trait_ref: ty::TraitRef<'tcx>| {
- if trait_ref.self_ty() != dummy_self {
- // FIXME: There appears to be a missing filter on top of `expand_trait_aliases`,
- // which picks up non-supertraits where clauses - but also, the object safety
- // completely ignores trait aliases, which could be object safety hazards. We
- // `delay_span_bug` here to avoid an ICE in stable even when the feature is
- // disabled. (#66420)
- tcx.sess.delay_span_bug(
- DUMMY_SP,
- &format!(
- "trait_ref_to_existential called on {:?} with non-dummy Self",
- trait_ref,
- ),
+ assert_eq!(trait_ref.self_ty(), dummy_self);
+
+ // Verify that `dummy_self` did not leak inside default type parameters. This
+ // could not be done at path creation, since we need to see through trait aliases.
+ let mut missing_type_params = vec![];
+ let mut references_self = false;
+ let generics = tcx.generics_of(trait_ref.def_id);
+ let substs: Vec<_> = trait_ref
+ .substs
+ .iter()
+ .enumerate()
+ .skip(1) // Remove `Self` for `ExistentialPredicate`.
+ .map(|(index, arg)| {
+ if let ty::GenericArgKind::Type(ty) = arg.unpack() {
+ debug!(?ty);
+ if ty == dummy_self {
+ let param = &generics.params[index];
+ missing_type_params.push(param.name);
+ tcx.ty_error().into()
+ } else if ty.walk().any(|arg| arg == dummy_self.into()) {
+ references_self = true;
+ tcx.ty_error().into()
+ } else {
+ arg
+ }
+ } else {
+ arg
+ }
+ })
+ .collect();
+ let substs = tcx.intern_substs(&substs[..]);
+
+ let span = i.bottom().1;
+ let empty_generic_args = trait_bounds.iter().any(|hir_bound| {
+ hir_bound.trait_ref.path.res == Res::Def(DefKind::Trait, trait_ref.def_id)
+ && hir_bound.span.contains(span)
+ });
+ self.complain_about_missing_type_params(
+ missing_type_params,
+ trait_ref.def_id,
+ span,
+ empty_generic_args,
+ );
+
+ if references_self {
+ let def_id = i.bottom().0.def_id();
+ let mut err = struct_span_err!(
+ tcx.sess,
+ i.bottom().1,
+ E0038,
+ "the {} `{}` cannot be made into an object",
+ tcx.def_kind(def_id).descr(def_id),
+ tcx.item_name(def_id),
+ );
+ err.note(
+ rustc_middle::traits::ObjectSafetyViolation::SupertraitSelf(smallvec![])
+ .error_msg(),
);
+ err.emit();
}
- ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref)
+
+ ty::ExistentialTraitRef { def_id: trait_ref.def_id, substs }
})
});
+
let existential_projections = bounds.projection_bounds.iter().map(|(bound, _)| {
bound.map_bound(|b| {
if b.projection_ty.self_ty() != dummy_self {
debug!("sub_types failed: impl ty {:?}, trait ty {:?}", impl_fty, trait_fty);
let (impl_err_span, trait_err_span) =
- extract_spans_for_error_reporting(&infcx, &terr, &cause, impl_m, trait_m);
+ extract_spans_for_error_reporting(&infcx, terr, &cause, impl_m, trait_m);
cause.span = impl_err_span;
expected: trait_fty.into(),
found: impl_fty.into(),
})),
- &terr,
+ terr,
false,
false,
);
#[instrument(level = "debug", skip(infcx))]
fn extract_spans_for_error_reporting<'a, 'tcx>(
infcx: &infer::InferCtxt<'a, 'tcx>,
- terr: &TypeError<'_>,
+ terr: TypeError<'_>,
cause: &ObligationCause<'tcx>,
impl_m: &ty::AssocItem,
trait_m: &ty::AssocItem,
_ => bug!("{:?} is not a TraitItemKind::Fn", trait_m),
});
- match *terr {
+ match terr {
TypeError::ArgumentMutability(i) => {
(impl_args.nth(i).unwrap(), trait_args.and_then(|mut args| args.nth(i)))
}
expected: trait_ty.into(),
found: impl_ty.into(),
})),
- &terr,
+ terr,
false,
false,
);
}?;
match hir.find(hir.get_parent_node(expr.hir_id))? {
- Node::Expr(hir::Expr { kind: hir::ExprKind::Struct(_, fields, ..), .. }) => {
- for field in *fields {
- if field.ident.name == local.name && field.is_shorthand {
- return Some(local.name);
- }
+ Node::ExprField(field) => {
+ if field.ident.name == local.name && field.is_shorthand {
+ return Some(local.name);
}
}
_ => {}
let mut sugg = vec![];
- if let Some(hir::Node::Expr(hir::Expr {
- kind: hir::ExprKind::Struct(_, fields, _), ..
- })) = self.tcx.hir().find(self.tcx.hir().get_parent_node(expr.hir_id))
+ if let Some(hir::Node::ExprField(field)) =
+ self.tcx.hir().find(self.tcx.hir().get_parent_node(expr.hir_id))
{
// `expr` is a literal field for a struct, only suggest if appropriate
- match (*fields)
- .iter()
- .find(|field| field.expr.hir_id == expr.hir_id && field.is_shorthand)
- {
+ if field.is_shorthand {
// This is a field literal
- Some(field) => {
- sugg.push((field.ident.span.shrink_to_lo(), format!("{}: ", field.ident)));
- }
+ sugg.push((field.ident.span.shrink_to_lo(), format!("{}: ", field.ident)));
+ } else {
// Likely a field was meant, but this field wasn't found. Do not suggest anything.
- None => return false,
+ return false;
}
};
debug!("FnCtxt::check_asm: {} deferred checks", deferred_asm_checks.len());
for (asm, hir_id) in deferred_asm_checks.drain(..) {
let enclosing_id = self.tcx.hir().enclosing_body_owner(hir_id);
- InlineAsmCtxt::new_in_fn(self)
+ let get_operand_ty = |expr| {
+ let ty = self.typeck_results.borrow().expr_ty_adjusted(expr);
+ let ty = self.resolve_vars_if_possible(ty);
+ if ty.has_infer_types_or_consts() {
+ assert!(self.is_tainted_by_errors());
+ self.tcx.ty_error()
+ } else {
+ self.tcx.erase_regions(ty)
+ }
+ };
+ InlineAsmCtxt::new_in_fn(self.tcx, self.param_env, get_operand_ty)
.check_asm(asm, self.tcx.hir().local_def_id_to_hir_id(enclosing_id));
}
}
call_expr: &hir::Expr<'tcx>,
) {
// Next, let's construct the error
- let (error_span, full_call_span, ctor_of) = match &call_expr.kind {
+ let (error_span, full_call_span, ctor_of, is_method) = match &call_expr.kind {
hir::ExprKind::Call(
hir::Expr { hir_id, span, kind: hir::ExprKind::Path(qpath), .. },
_,
if let Res::Def(DefKind::Ctor(of, _), _) =
self.typeck_results.borrow().qpath_res(qpath, *hir_id)
{
- (call_span, *span, Some(of))
+ (call_span, *span, Some(of), false)
} else {
- (call_span, *span, None)
+ (call_span, *span, None, false)
}
}
- hir::ExprKind::Call(hir::Expr { span, .. }, _) => (call_span, *span, None),
+ hir::ExprKind::Call(hir::Expr { span, .. }, _) => (call_span, *span, None, false),
hir::ExprKind::MethodCall(path_segment, _, span) => {
let ident_span = path_segment.ident.span;
let ident_span = if let Some(args) = path_segment.args {
} else {
ident_span
};
- (
- *span, ident_span, None, // methods are never ctors
- )
+ // methods are never ctors
+ (*span, ident_span, None, true)
}
k => span_bug!(call_span, "checking argument types on a non-call: `{:?}`", k),
};
let coerced_ty = expectation.only_has_type(self).unwrap_or(formal_input_ty);
let can_coerce = self.can_coerce(arg_ty, coerced_ty);
if !can_coerce {
- return Compatibility::Incompatible(None);
+ return Compatibility::Incompatible(Some(ty::error::TypeError::Sorts(
+ ty::error::ExpectedFound::new(true, coerced_ty, arg_ty),
+ )));
}
// Using probe here, since we don't want this subtyping to affect inference.
// First, check if we just need to wrap some arguments in a tuple.
if let Some((mismatch_idx, terr)) =
compatibility_diagonal.iter().enumerate().find_map(|(i, c)| {
- if let Compatibility::Incompatible(Some(terr)) = c { Some((i, terr)) } else { None }
+ if let Compatibility::Incompatible(Some(terr)) = c {
+ Some((i, *terr))
+ } else {
+ None
+ }
})
{
// Is the first bad expected argument a tuple?
Applicability::MachineApplicable,
);
};
- self.label_fn_like(&mut err, fn_def_id, callee_ty);
+ self.label_fn_like(&mut err, fn_def_id, callee_ty, Some(mismatch_idx), is_method);
err.emit();
return;
}
}
errors.drain_filter(|error| {
- let Error::Invalid(provided_idx, expected_idx, Compatibility::Incompatible(error)) = error else { return false };
+ let Error::Invalid(provided_idx, expected_idx, Compatibility::Incompatible(Some(e))) = error else { return false };
let (provided_ty, provided_span) = provided_arg_tys[*provided_idx];
let (expected_ty, _) = formal_and_expected_inputs[*expected_idx];
let cause = &self.misc(provided_span);
let trace = TypeTrace::types(cause, true, expected_ty, provided_ty);
- if let Some(e) = error {
- if !matches!(trace.cause.as_failure_code(e), FailureCode::Error0308(_)) {
- self.report_and_explain_type_error(trace, e).emit();
- return true;
- }
+ if !matches!(trace.cause.as_failure_code(*e), FailureCode::Error0308(_)) {
+ self.report_and_explain_type_error(trace, *e).emit();
+ return true;
}
false
});
let (provided_ty, provided_arg_span) = provided_arg_tys[*provided_idx];
let cause = &self.misc(provided_arg_span);
let trace = TypeTrace::types(cause, true, expected_ty, provided_ty);
- let mut err = self.report_and_explain_type_error(trace, err);
+ let mut err = self.report_and_explain_type_error(trace, *err);
self.emit_coerce_suggestions(
&mut err,
&provided_args[*provided_idx],
format!("arguments to this {} are incorrect", call_name),
);
// Call out where the function is defined
- self.label_fn_like(&mut err, fn_def_id, callee_ty);
+ self.label_fn_like(
+ &mut err,
+ fn_def_id,
+ callee_ty,
+ Some(expected_idx.as_usize()),
+ is_method,
+ );
err.emit();
return;
}
Error::Invalid(provided_idx, expected_idx, compatibility) => {
let (formal_ty, expected_ty) = formal_and_expected_inputs[expected_idx];
let (provided_ty, provided_span) = provided_arg_tys[provided_idx];
- if let Compatibility::Incompatible(error) = &compatibility {
+ if let Compatibility::Incompatible(error) = compatibility {
let cause = &self.misc(provided_span);
let trace = TypeTrace::types(cause, true, expected_ty, provided_ty);
if let Some(e) = error {
}
// Call out where the function is defined
- self.label_fn_like(&mut err, fn_def_id, callee_ty);
+ self.label_fn_like(&mut err, fn_def_id, callee_ty, None, is_method);
// And add a suggestion block for all of the parameters
let suggestion_text = match suggestion_text {
ObligationCauseCode::ImplDerivedObligation(code) => {
code.derived.parent_trait_pred.self_ty().skip_binder().into()
}
- _ if let ty::PredicateKind::Trait(predicate) =
- error.obligation.predicate.kind().skip_binder() =>
- {
- predicate.self_ty().into()
- }
- _ => continue,
+ _ => match error.obligation.predicate.kind().skip_binder() {
+ ty::PredicateKind::Trait(predicate) => predicate.self_ty().into(),
+ ty::PredicateKind::Projection(predicate) => {
+ predicate.projection_ty.self_ty().into()
+ }
+ _ => continue,
+ },
};
let self_ = self.resolve_vars_if_possible(self_);
let ty_matches_self = |ty: Ty<'tcx>| ty.walk().any(|arg| arg == self_);
if let hir::ExprKind::Call(path, _) = &call_expr.kind {
if let hir::ExprKind::Path(hir::QPath::Resolved(_, path)) = &path.kind {
for error in errors {
- if let ty::PredicateKind::Trait(predicate) =
- error.obligation.predicate.kind().skip_binder()
+ let self_ty = match error.obligation.predicate.kind().skip_binder() {
+ ty::PredicateKind::Trait(predicate) => predicate.self_ty(),
+ ty::PredicateKind::Projection(predicate) => {
+ predicate.projection_ty.self_ty()
+ }
+ _ => continue,
+ };
+ // If any of the type arguments in this path segment caused the
+ // `FulfillmentError`, point at its span (#61860).
+ for arg in path
+ .segments
+ .iter()
+ .filter_map(|seg| seg.args.as_ref())
+ .flat_map(|a| a.args.iter())
{
- // If any of the type arguments in this path segment caused the
- // `FulfillmentError`, point at its span (#61860).
- for arg in path
- .segments
- .iter()
- .filter_map(|seg| seg.args.as_ref())
- .flat_map(|a| a.args.iter())
+ if let hir::GenericArg::Type(hir_ty) = &arg
+ && let Some(ty) =
+ self.typeck_results.borrow().node_type_opt(hir_ty.hir_id)
+ && self.resolve_vars_if_possible(ty) == self_ty
{
- if let hir::GenericArg::Type(hir_ty) = &arg
- && let Some(ty) =
- self.typeck_results.borrow().node_type_opt(hir_ty.hir_id)
- && self.resolve_vars_if_possible(ty) == predicate.self_ty()
- {
- error.obligation.cause.span = hir_ty.span;
- break;
- }
+ error.obligation.cause.span = hir_ty.span;
+ break;
}
}
}
err: &mut Diagnostic,
callable_def_id: Option<DefId>,
callee_ty: Option<Ty<'tcx>>,
+ // A specific argument should be labeled, instead of all of them
+ expected_idx: Option<usize>,
+ is_method: bool,
) {
let Some(mut def_id) = callable_def_id else {
return;
.get_if_local(def_id)
.and_then(|node| node.body_id())
.into_iter()
- .flat_map(|id| self.tcx.hir().body(id).params);
+ .flat_map(|id| self.tcx.hir().body(id).params)
+ .skip(if is_method { 1 } else { 0 });
- for param in params {
+ for (_, param) in params
+ .into_iter()
+ .enumerate()
+ .filter(|(idx, _)| expected_idx.map_or(true, |expected_idx| expected_idx == *idx))
+ {
spans.push_span_label(param.span, "");
}
let def_kind = self.tcx.def_kind(def_id);
err.span_note(spans, &format!("{} defined here", def_kind.descr(def_id)));
+ } else if let Some(hir::Node::Expr(e)) = self.tcx.hir().get_if_local(def_id)
+ && let hir::ExprKind::Closure(hir::Closure { body, .. }) = &e.kind
+ {
+ let param = expected_idx
+ .and_then(|expected_idx| self.tcx.hir().body(*body).params.get(expected_idx));
+ let (kind, span) = if let Some(param) = param {
+ ("closure parameter", param.span)
+ } else {
+ ("closure", self.tcx.def_span(def_id))
+ };
+ err.span_note(span, &format!("{} defined here", kind));
} else {
let def_kind = self.tcx.def_kind(def_id);
err.span_note(
| hir::Node::TypeBinding(..)
| hir::Node::TraitRef(..)
| hir::Node::Pat(..)
+ | hir::Node::PatField(..)
+ | hir::Node::ExprField(..)
| hir::Node::Arm(..)
| hir::Node::Local(..)
| hir::Node::Ctor(..)
// to note that it's safe to call, since
// safe extern fns are otherwise unprecedented.
sym::abort
+ | sym::assert_inhabited
+ | sym::assert_zero_valid
+ | sym::assert_uninit_valid
| sym::size_of
| sym::min_align_of
| sym::needs_drop
use rustc_span::{Span, Symbol, DUMMY_SP};
use rustc_target::abi::{Pointer, VariantIdx};
use rustc_target::asm::{InlineAsmReg, InlineAsmRegClass, InlineAsmRegOrRegClass, InlineAsmType};
-use rustc_trait_selection::infer::InferCtxtExt;
use super::FnCtxt;
}
err.emit();
}
+}
+
+pub struct InlineAsmCtxt<'a, 'tcx> {
+ tcx: TyCtxt<'tcx>,
+ param_env: ty::ParamEnv<'tcx>,
+ get_operand_ty: Box<dyn Fn(&'tcx hir::Expr<'tcx>) -> Ty<'tcx> + 'a>,
+}
+
+impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
+ pub fn new_global_asm(tcx: TyCtxt<'tcx>) -> Self {
+ InlineAsmCtxt {
+ tcx,
+ param_env: ty::ParamEnv::empty(),
+ get_operand_ty: Box::new(|e| bug!("asm operand in global asm: {e:?}")),
+ }
+ }
+
+ pub fn new_in_fn(
+ tcx: TyCtxt<'tcx>,
+ param_env: ty::ParamEnv<'tcx>,
+ get_operand_ty: impl Fn(&'tcx hir::Expr<'tcx>) -> Ty<'tcx> + 'a,
+ ) -> Self {
+ InlineAsmCtxt { tcx, param_env, get_operand_ty: Box::new(get_operand_ty) }
+ }
// FIXME(compiler-errors): This could use `<$ty as Pointee>::Metadata == ()`
fn is_thin_ptr_ty(&self, ty: Ty<'tcx>) -> bool {
// Type still may have region variables, but `Sized` does not depend
// on those, so just erase them before querying.
- if self.tcx.erase_regions(ty).is_sized(self.tcx.at(DUMMY_SP), self.param_env) {
+ if ty.is_sized(self.tcx.at(DUMMY_SP), self.param_env) {
return true;
}
if let ty::Foreign(..) = ty.kind() {
}
false
}
-}
-
-pub struct InlineAsmCtxt<'a, 'tcx> {
- tcx: TyCtxt<'tcx>,
- fcx: Option<&'a FnCtxt<'a, 'tcx>>,
-}
-
-impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
- pub fn new_global_asm(tcx: TyCtxt<'tcx>) -> Self {
- InlineAsmCtxt { tcx, fcx: None }
- }
-
- pub fn new_in_fn(fcx: &'a FnCtxt<'a, 'tcx>) -> Self {
- InlineAsmCtxt { tcx: fcx.tcx, fcx: Some(fcx) }
- }
fn check_asm_operand_type(
&self,
idx: usize,
reg: InlineAsmRegOrRegClass,
- expr: &hir::Expr<'tcx>,
+ expr: &'tcx hir::Expr<'tcx>,
template: &[InlineAsmTemplatePiece],
is_input: bool,
- tied_input: Option<(&hir::Expr<'tcx>, Option<InlineAsmType>)>,
+ tied_input: Option<(&'tcx hir::Expr<'tcx>, Option<InlineAsmType>)>,
target_features: &FxHashSet<Symbol>,
) -> Option<InlineAsmType> {
- let fcx = self.fcx.unwrap_or_else(|| span_bug!(expr.span, "asm operand for global asm"));
- // Check the type against the allowed types for inline asm.
- let ty = fcx.typeck_results.borrow().expr_ty_adjusted(expr);
- let ty = fcx.resolve_vars_if_possible(ty);
+ let ty = (self.get_operand_ty)(expr);
+ if ty.has_infer_types_or_consts() {
+ bug!("inference variable in asm operand ty: {:?} {:?}", expr, ty);
+ }
let asm_ty_isize = match self.tcx.sess.target.pointer_width {
16 => InlineAsmType::I16,
32 => InlineAsmType::I32,
_ => unreachable!(),
};
- // Expect types to be fully resolved, no const or type variables.
- if ty.has_infer_types_or_consts() {
- assert!(fcx.is_tainted_by_errors());
- return None;
- }
-
let asm_ty = match *ty.kind() {
// `!` is allowed for input but not for output (issue #87802)
ty::Never if is_input => return None,
ty::Float(FloatTy::F32) => Some(InlineAsmType::F32),
ty::Float(FloatTy::F64) => Some(InlineAsmType::F64),
ty::FnPtr(_) => Some(asm_ty_isize),
- ty::RawPtr(ty::TypeAndMut { ty, mutbl: _ }) if fcx.is_thin_ptr_ty(ty) => {
+ ty::RawPtr(ty::TypeAndMut { ty, mutbl: _ }) if self.is_thin_ptr_ty(ty) => {
Some(asm_ty_isize)
}
ty::Adt(adt, substs) if adt.repr().simd() => {
// Check that the type implements Copy. The only case where this can
// possibly fail is for SIMD types which don't #[derive(Copy)].
- if !fcx.infcx.type_is_copy_modulo_regions(fcx.param_env, ty, DUMMY_SP) {
+ if !ty.is_copy_modulo_regions(self.tcx.at(expr.span), self.param_env) {
let msg = "arguments for inline assembly must be copyable";
let mut err = self.tcx.sess.struct_span_err(expr.span, msg);
err.note(&format!("`{ty}` does not implement the Copy trait"));
let msg = "incompatible types for asm inout argument";
let mut err = self.tcx.sess.struct_span_err(vec![in_expr.span, expr.span], msg);
- let in_expr_ty = fcx.typeck_results.borrow().expr_ty_adjusted(in_expr);
- let in_expr_ty = fcx.resolve_vars_if_possible(in_expr_ty);
+ let in_expr_ty = (self.get_operand_ty)(in_expr);
err.span_label(in_expr.span, &format!("type `{in_expr_ty}`"));
err.span_label(expr.span, &format!("type `{ty}`"));
err.note(
),
);
match self.tcx.hir().get(self.tcx.hir().get_parent_node(pat.hir_id)) {
- hir::Node::Pat(Pat { kind: hir::PatKind::Struct(..), .. }) => {
+ hir::Node::PatField(..) => {
e.span_suggestion_verbose(
ident.span.shrink_to_hi(),
"bind the struct field to a different name instead",
intravisit::walk_expr(self, e);
}
+ fn visit_generic_param(&mut self, p: &'tcx hir::GenericParam<'tcx>) {
+ match &p.kind {
+ hir::GenericParamKind::Lifetime { .. } => {
+ // Nothing to write back here
+ }
+ hir::GenericParamKind::Type { .. } | hir::GenericParamKind::Const { .. } => {
+ self.tcx().sess.delay_span_bug(p.span, format!("unexpected generic param: {p:?}"));
+ }
+ }
+ }
+
fn visit_block(&mut self, b: &'tcx hir::Block<'tcx>) {
self.visit_node_id(b.span, b.hir_id);
intravisit::walk_block(self, b);
#![feature(is_sorted)]
#![feature(iter_intersperse)]
#![feature(label_break_value)]
-#![cfg_attr(bootstrap, feature(let_chains))]
#![feature(let_else)]
#![feature(min_specialization)]
#![feature(never_type)]
#[rustc_allocator]
#[rustc_allocator_nounwind]
fn __rust_alloc(size: usize, align: usize) -> *mut u8;
- #[cfg_attr(not(bootstrap), rustc_deallocator)]
+ #[rustc_deallocator]
#[rustc_allocator_nounwind]
fn __rust_dealloc(ptr: *mut u8, size: usize, align: usize);
- #[cfg_attr(not(bootstrap), rustc_reallocator)]
+ #[rustc_reallocator]
#[rustc_allocator_nounwind]
fn __rust_realloc(ptr: *mut u8, old_size: usize, align: usize, new_size: usize) -> *mut u8;
- #[cfg_attr(not(bootstrap), rustc_allocator_zeroed)]
+ #[rustc_allocator_zeroed]
#[rustc_allocator_nounwind]
fn __rust_alloc_zeroed(size: usize, align: usize) -> *mut u8;
}
/// {
/// return null_mut();
/// };
-/// (self.arena.get() as *mut u8).add(allocated)
+/// self.arena.get().cast::<u8>().add(allocated)
/// }
/// unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout) {}
/// }
///
/// This function will return an instance of [`Error`] on error.
///
+ /// The purpose of std::fmt::Error is to abort the formatting operation when the underlying
+ /// destination encounters some error preventing it from accepting more text; it should
+ /// generally be propagated rather than handled, at least when implementing formatting traits.
+ ///
/// # Examples
///
/// ```
macro_rules! maybe_tuple_doc {
($a:ident @ #[$meta:meta] $item:item) => {
- #[cfg_attr(not(bootstrap), doc(fake_variadic))]
+ #[doc(fake_variadic)]
#[doc = "This trait is implemented for tuples up to twelve items long."]
#[$meta]
$item
macro_rules! maybe_tuple_doc {
($a:ident @ #[$meta:meta] $item:item) => {
- #[cfg_attr(not(bootstrap), doc(fake_variadic))]
+ #[doc(fake_variadic)]
#[doc = "This trait is implemented for tuples up to twelve items long."]
#[$meta]
$item
use crate::sync::atomic::{self, AtomicBool, AtomicI32, AtomicIsize, AtomicU32, Ordering};
#[stable(feature = "drop_in_place", since = "1.8.0")]
-#[cfg_attr(not(bootstrap), rustc_allowed_through_unstable_modules)]
+#[rustc_allowed_through_unstable_modules]
#[deprecated(note = "no longer an intrinsic - use `ptr::drop_in_place` directly", since = "1.52.0")]
#[inline]
pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
unsafe { crate::ptr::drop_in_place(to_drop) }
}
-// These have been renamed.
-#[cfg(bootstrap)]
-extern "rust-intrinsic" {
- pub fn atomic_cxchg<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
- pub fn atomic_cxchg_acq<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
- pub fn atomic_cxchg_rel<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
- pub fn atomic_cxchg_acqrel<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
- pub fn atomic_cxchg_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
- pub fn atomic_cxchg_failrelaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
- pub fn atomic_cxchg_failacq<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
- pub fn atomic_cxchg_acq_failrelaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
- pub fn atomic_cxchg_acqrel_failrelaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
- pub fn atomic_cxchgweak<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
- pub fn atomic_cxchgweak_acq<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
- pub fn atomic_cxchgweak_rel<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
- pub fn atomic_cxchgweak_acqrel<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
- pub fn atomic_cxchgweak_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
- pub fn atomic_cxchgweak_failrelaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
- pub fn atomic_cxchgweak_failacq<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
- pub fn atomic_cxchgweak_acq_failrelaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
- pub fn atomic_cxchgweak_acqrel_failrelaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
- pub fn atomic_load<T: Copy>(src: *const T) -> T;
- pub fn atomic_load_acq<T: Copy>(src: *const T) -> T;
- pub fn atomic_load_relaxed<T: Copy>(src: *const T) -> T;
- pub fn atomic_load_unordered<T: Copy>(src: *const T) -> T;
- pub fn atomic_store<T: Copy>(dst: *mut T, val: T);
- pub fn atomic_store_rel<T: Copy>(dst: *mut T, val: T);
- pub fn atomic_store_relaxed<T: Copy>(dst: *mut T, val: T);
- pub fn atomic_store_unordered<T: Copy>(dst: *mut T, val: T);
- pub fn atomic_xchg<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_xchg_acq<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_xchg_rel<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_xchg_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_xchg_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_xadd<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_xadd_acq<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_xadd_rel<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_xadd_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_xadd_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_xsub<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_xsub_acq<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_xsub_rel<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_xsub_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_xsub_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_and<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_and_acq<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_and_rel<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_and_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_and_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_nand<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_nand_acq<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_nand_rel<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_nand_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_nand_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_or<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_or_acq<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_or_rel<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_or_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_or_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_xor<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_xor_acq<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_xor_rel<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_xor_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_xor_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_max<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_max_acq<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_max_rel<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_max_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_max_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_min<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_min_acq<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_min_rel<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_min_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_min_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_umin<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_umin_acq<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_umin_rel<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_umin_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_umin_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_umax<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_umax_acq<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_umax_rel<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_umax_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_umax_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
- pub fn atomic_fence();
- pub fn atomic_fence_acq();
- pub fn atomic_fence_rel();
- pub fn atomic_fence_acqrel();
- pub fn atomic_singlethreadfence();
- pub fn atomic_singlethreadfence_acq();
- pub fn atomic_singlethreadfence_rel();
- pub fn atomic_singlethreadfence_acqrel();
-}
-
-// These have been renamed.
-#[cfg(bootstrap)]
-mod atomics {
- pub use super::atomic_cxchg as atomic_cxchg_seqcst_seqcst;
- pub use super::atomic_cxchg_acq as atomic_cxchg_acquire_acquire;
- pub use super::atomic_cxchg_acq_failrelaxed as atomic_cxchg_acquire_relaxed;
- pub use super::atomic_cxchg_acqrel as atomic_cxchg_acqrel_acquire;
- pub use super::atomic_cxchg_acqrel_failrelaxed as atomic_cxchg_acqrel_relaxed;
- pub use super::atomic_cxchg_failacq as atomic_cxchg_seqcst_acquire;
- pub use super::atomic_cxchg_failrelaxed as atomic_cxchg_seqcst_relaxed;
- pub use super::atomic_cxchg_rel as atomic_cxchg_release_relaxed;
- pub use super::atomic_cxchg_relaxed as atomic_cxchg_relaxed_relaxed;
-
- pub use super::atomic_cxchgweak as atomic_cxchgweak_seqcst_seqcst;
- pub use super::atomic_cxchgweak_acq as atomic_cxchgweak_acquire_acquire;
- pub use super::atomic_cxchgweak_acq_failrelaxed as atomic_cxchgweak_acquire_relaxed;
- pub use super::atomic_cxchgweak_acqrel as atomic_cxchgweak_acqrel_acquire;
- pub use super::atomic_cxchgweak_acqrel_failrelaxed as atomic_cxchgweak_acqrel_relaxed;
- pub use super::atomic_cxchgweak_failacq as atomic_cxchgweak_seqcst_acquire;
- pub use super::atomic_cxchgweak_failrelaxed as atomic_cxchgweak_seqcst_relaxed;
- pub use super::atomic_cxchgweak_rel as atomic_cxchgweak_release_relaxed;
- pub use super::atomic_cxchgweak_relaxed as atomic_cxchgweak_relaxed_relaxed;
-
- pub use super::atomic_load as atomic_load_seqcst;
- pub use super::atomic_load_acq as atomic_load_acquire;
- pub use super::atomic_load_relaxed;
- pub use super::atomic_load_unordered;
-
- pub use super::atomic_store as atomic_store_seqcst;
- pub use super::atomic_store_rel as atomic_store_release;
- pub use super::atomic_store_relaxed;
- pub use super::atomic_store_unordered;
-
- pub use super::atomic_xchg as atomic_xchg_seqcst;
- pub use super::atomic_xchg_acq as atomic_xchg_acquire;
- pub use super::atomic_xchg_acqrel;
- pub use super::atomic_xchg_rel as atomic_xchg_release;
- pub use super::atomic_xchg_relaxed;
-
- pub use super::atomic_xadd as atomic_xadd_seqcst;
- pub use super::atomic_xadd_acq as atomic_xadd_acquire;
- pub use super::atomic_xadd_acqrel;
- pub use super::atomic_xadd_rel as atomic_xadd_release;
- pub use super::atomic_xadd_relaxed;
-
- pub use super::atomic_xsub as atomic_xsub_seqcst;
- pub use super::atomic_xsub_acq as atomic_xsub_acquire;
- pub use super::atomic_xsub_acqrel;
- pub use super::atomic_xsub_rel as atomic_xsub_release;
- pub use super::atomic_xsub_relaxed;
-
- pub use super::atomic_and as atomic_and_seqcst;
- pub use super::atomic_and_acq as atomic_and_acquire;
- pub use super::atomic_and_acqrel;
- pub use super::atomic_and_rel as atomic_and_release;
- pub use super::atomic_and_relaxed;
-
- pub use super::atomic_nand as atomic_nand_seqcst;
- pub use super::atomic_nand_acq as atomic_nand_acquire;
- pub use super::atomic_nand_acqrel;
- pub use super::atomic_nand_rel as atomic_nand_release;
- pub use super::atomic_nand_relaxed;
-
- pub use super::atomic_or as atomic_or_seqcst;
- pub use super::atomic_or_acq as atomic_or_acquire;
- pub use super::atomic_or_acqrel;
- pub use super::atomic_or_rel as atomic_or_release;
- pub use super::atomic_or_relaxed;
-
- pub use super::atomic_xor as atomic_xor_seqcst;
- pub use super::atomic_xor_acq as atomic_xor_acquire;
- pub use super::atomic_xor_acqrel;
- pub use super::atomic_xor_rel as atomic_xor_release;
- pub use super::atomic_xor_relaxed;
-
- pub use super::atomic_max as atomic_max_seqcst;
- pub use super::atomic_max_acq as atomic_max_acquire;
- pub use super::atomic_max_acqrel;
- pub use super::atomic_max_rel as atomic_max_release;
- pub use super::atomic_max_relaxed;
-
- pub use super::atomic_min as atomic_min_seqcst;
- pub use super::atomic_min_acq as atomic_min_acquire;
- pub use super::atomic_min_acqrel;
- pub use super::atomic_min_rel as atomic_min_release;
- pub use super::atomic_min_relaxed;
-
- pub use super::atomic_umin as atomic_umin_seqcst;
- pub use super::atomic_umin_acq as atomic_umin_acquire;
- pub use super::atomic_umin_acqrel;
- pub use super::atomic_umin_rel as atomic_umin_release;
- pub use super::atomic_umin_relaxed;
-
- pub use super::atomic_umax as atomic_umax_seqcst;
- pub use super::atomic_umax_acq as atomic_umax_acquire;
- pub use super::atomic_umax_acqrel;
- pub use super::atomic_umax_rel as atomic_umax_release;
- pub use super::atomic_umax_relaxed;
-
- pub use super::atomic_fence as atomic_fence_seqcst;
- pub use super::atomic_fence_acq as atomic_fence_acquire;
- pub use super::atomic_fence_acqrel;
- pub use super::atomic_fence_rel as atomic_fence_release;
-
- pub use super::atomic_singlethreadfence as atomic_singlethreadfence_seqcst;
- pub use super::atomic_singlethreadfence_acq as atomic_singlethreadfence_acquire;
- pub use super::atomic_singlethreadfence_acqrel;
- pub use super::atomic_singlethreadfence_rel as atomic_singlethreadfence_release;
-}
-
-#[cfg(bootstrap)]
-pub use atomics::*;
-
-#[cfg(not(bootstrap))]
extern "rust-intrinsic" {
// N.B., these intrinsics take raw pointers because they mutate aliased
// memory, which is not valid for either `&` or `&mut`.
//
// These are the aliases for the old names.
// To be removed when stdarch and panic_unwind have been updated.
-#[cfg(not(bootstrap))]
mod atomics {
pub use super::atomic_cxchg_acqrel_acquire as atomic_cxchg_acqrel;
pub use super::atomic_cxchg_acqrel_relaxed as atomic_cxchg_acqrel_failrelaxed;
pub use super::atomic_store_seqcst as atomic_store;
}
-#[cfg(not(bootstrap))]
pub use atomics::*;
extern "rust-intrinsic" {
/// }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
- #[cfg_attr(not(bootstrap), rustc_allowed_through_unstable_modules)]
+ #[rustc_allowed_through_unstable_modules]
#[rustc_const_stable(feature = "const_transmute", since = "1.56.0")]
#[rustc_diagnostic_item = "transmute"]
pub fn transmute<T, U>(e: T) -> U;
/// `ptr` must point to a vtable.
/// The intrinsic will return the size stored in that vtable.
- #[cfg(not(bootstrap))]
pub fn vtable_size(ptr: *const ()) -> usize;
/// `ptr` must point to a vtable.
/// The intrinsic will return the alignment stored in that vtable.
- #[cfg(not(bootstrap))]
pub fn vtable_align(ptr: *const ()) -> usize;
}
/// [`Vec::append`]: ../../std/vec/struct.Vec.html#method.append
#[doc(alias = "memcpy")]
#[stable(feature = "rust1", since = "1.0.0")]
-#[cfg_attr(not(bootstrap), rustc_allowed_through_unstable_modules)]
+#[rustc_allowed_through_unstable_modules]
#[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.63.0")]
#[inline]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
/// ```
#[doc(alias = "memmove")]
#[stable(feature = "rust1", since = "1.0.0")]
-#[cfg_attr(not(bootstrap), rustc_allowed_through_unstable_modules)]
+#[rustc_allowed_through_unstable_modules]
#[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.63.0")]
#[inline]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
/// ```
#[doc(alias = "memset")]
#[stable(feature = "rust1", since = "1.0.0")]
-#[cfg_attr(not(bootstrap), rustc_allowed_through_unstable_modules)]
+#[rustc_allowed_through_unstable_modules]
#[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")]
#[inline]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
--- /dev/null
+use crate::array;
+use crate::iter::{ByRefSized, FusedIterator, Iterator};
+use crate::ops::{ControlFlow, NeverShortCircuit, Try};
+
+/// An iterator over `N` elements of the iterator at a time.
+///
+/// The chunks do not overlap. If `N` does not divide the length of the
+/// iterator, then the last up to `N-1` elements will be omitted.
+///
+/// This `struct` is created by the [`array_chunks`][Iterator::array_chunks]
+/// method on [`Iterator`]. See its documentation for more.
+#[derive(Debug, Clone)]
+#[must_use = "iterators are lazy and do nothing unless consumed"]
+#[unstable(feature = "iter_array_chunks", reason = "recently added", issue = "100450")]
+pub struct ArrayChunks<I: Iterator, const N: usize> {
+ iter: I,
+ remainder: Option<array::IntoIter<I::Item, N>>,
+}
+
+impl<I, const N: usize> ArrayChunks<I, N>
+where
+ I: Iterator,
+{
+ #[track_caller]
+ pub(in crate::iter) fn new(iter: I) -> Self {
+ assert!(N != 0, "chunk size must be non-zero");
+ Self { iter, remainder: None }
+ }
+
+ /// Returns an iterator over the remaining elements of the original iterator
+ /// that are not going to be returned by this iterator. The returned
+ /// iterator will yield at most `N-1` elements.
+ #[unstable(feature = "iter_array_chunks", reason = "recently added", issue = "100450")]
+ #[inline]
+ pub fn into_remainder(self) -> Option<array::IntoIter<I::Item, N>> {
+ self.remainder
+ }
+}
+
+#[unstable(feature = "iter_array_chunks", reason = "recently added", issue = "100450")]
+impl<I, const N: usize> Iterator for ArrayChunks<I, N>
+where
+ I: Iterator,
+{
+ type Item = [I::Item; N];
+
+ #[inline]
+ fn next(&mut self) -> Option<Self::Item> {
+ self.try_for_each(ControlFlow::Break).break_value()
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ let (lower, upper) = self.iter.size_hint();
+
+ (lower / N, upper.map(|n| n / N))
+ }
+
+ #[inline]
+ fn count(self) -> usize {
+ self.iter.count() / N
+ }
+
+ fn try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R
+ where
+ Self: Sized,
+ F: FnMut(B, Self::Item) -> R,
+ R: Try<Output = B>,
+ {
+ let mut acc = init;
+ loop {
+ match self.iter.next_chunk() {
+ Ok(chunk) => acc = f(acc, chunk)?,
+ Err(remainder) => {
+ // Make sure to not override `self.remainder` with an empty array
+ // when `next` is called after `ArrayChunks` exhaustion.
+ self.remainder.get_or_insert(remainder);
+
+ break try { acc };
+ }
+ }
+ }
+ }
+
+ fn fold<B, F>(mut self, init: B, f: F) -> B
+ where
+ Self: Sized,
+ F: FnMut(B, Self::Item) -> B,
+ {
+ self.try_fold(init, NeverShortCircuit::wrap_mut_2(f)).0
+ }
+}
+
+#[unstable(feature = "iter_array_chunks", reason = "recently added", issue = "100450")]
+impl<I, const N: usize> DoubleEndedIterator for ArrayChunks<I, N>
+where
+ I: DoubleEndedIterator + ExactSizeIterator,
+{
+ #[inline]
+ fn next_back(&mut self) -> Option<Self::Item> {
+ self.try_rfold((), |(), x| ControlFlow::Break(x)).break_value()
+ }
+
+ fn try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R
+ where
+ Self: Sized,
+ F: FnMut(B, Self::Item) -> R,
+ R: Try<Output = B>,
+ {
+ // We are iterating from the back we need to first handle the remainder.
+ self.next_back_remainder();
+
+ let mut acc = init;
+ let mut iter = ByRefSized(&mut self.iter).rev();
+
+ // NB remainder is handled by `next_back_remainder`, so
+ // `next_chunk` can't return `Err` with non-empty remainder
+ // (assuming correct `I as ExactSizeIterator` impl).
+ while let Ok(mut chunk) = iter.next_chunk() {
+ // FIXME: do not do double reverse
+ // (we could instead add `next_chunk_back` for example)
+ chunk.reverse();
+ acc = f(acc, chunk)?
+ }
+
+ try { acc }
+ }
+
+ fn rfold<B, F>(mut self, init: B, f: F) -> B
+ where
+ Self: Sized,
+ F: FnMut(B, Self::Item) -> B,
+ {
+ self.try_rfold(init, NeverShortCircuit::wrap_mut_2(f)).0
+ }
+}
+
+impl<I, const N: usize> ArrayChunks<I, N>
+where
+ I: DoubleEndedIterator + ExactSizeIterator,
+{
+ /// Updates `self.remainder` such that `self.iter.len` is divisible by `N`.
+ fn next_back_remainder(&mut self) {
+ // Make sure to not override `self.remainder` with an empty array
+ // when `next_back` is called after `ArrayChunks` exhaustion.
+ if self.remainder.is_some() {
+ return;
+ }
+
+ // We use the `ExactSizeIterator` implementation of the underlying
+ // iterator to know how many remaining elements there are.
+ let rem = self.iter.len() % N;
+
+ // Take the last `rem` elements out of `self.iter`.
+ let mut remainder =
+ // SAFETY: `unwrap_err` always succeeds because x % N < N for all x.
+ unsafe { self.iter.by_ref().rev().take(rem).next_chunk().unwrap_err_unchecked() };
+
+ // We used `.rev()` above, so we need to re-reverse the reminder
+ remainder.as_mut_slice().reverse();
+ self.remainder = Some(remainder);
+ }
+}
+
+#[unstable(feature = "iter_array_chunks", reason = "recently added", issue = "100450")]
+impl<I, const N: usize> FusedIterator for ArrayChunks<I, N> where I: FusedIterator {}
+
+#[unstable(feature = "iter_array_chunks", reason = "recently added", issue = "100450")]
+impl<I, const N: usize> ExactSizeIterator for ArrayChunks<I, N>
+where
+ I: ExactSizeIterator,
+{
+ #[inline]
+ fn len(&self) -> usize {
+ self.iter.len() / N
+ }
+
+ #[inline]
+ fn is_empty(&self) -> bool {
+ self.iter.len() < N
+ }
+}
use crate::iter::{InPlaceIterable, Iterator};
use crate::ops::{ChangeOutputType, ControlFlow, FromResidual, NeverShortCircuit, Residual, Try};
+mod array_chunks;
mod by_ref_sized;
mod chain;
mod cloned;
scan::Scan, skip::Skip, skip_while::SkipWhile, take::Take, take_while::TakeWhile, zip::Zip,
};
+#[unstable(feature = "iter_array_chunks", reason = "recently added", issue = "100450")]
+pub use self::array_chunks::ArrayChunks;
+
#[unstable(feature = "std_internals", issue = "none")]
pub use self::by_ref_sized::ByRefSized;
#[inline]
fn next(&mut self) -> Option<I::Item> {
if unlikely(self.n > 0) {
- self.iter.nth(crate::mem::take(&mut self.n) - 1)?;
+ self.iter.nth(crate::mem::take(&mut self.n))
+ } else {
+ self.iter.next()
}
- self.iter.next()
}
#[inline]
fn nth(&mut self, n: usize) -> Option<I::Item> {
- // Can't just add n + self.n due to overflow.
if self.n > 0 {
- let to_skip = self.n;
- self.n = 0;
- // nth(n) skips n+1
- self.iter.nth(to_skip - 1)?;
+ let skip: usize = crate::mem::take(&mut self.n);
+ // Checked add to handle overflow case.
+ let n = match skip.checked_add(n) {
+ Some(nth) => nth,
+ None => {
+ // In case of overflow, load skip value, before loading `n`.
+ // Because the amount of elements to iterate is beyond `usize::MAX`, this
+ // is split into two `nth` calls where the `skip` `nth` call is discarded.
+ self.iter.nth(skip - 1)?;
+ n
+ }
+ };
+ // Load nth element including skip.
+ self.iter.nth(n)
+ } else {
+ self.iter.nth(n)
}
- self.iter.nth(n)
}
#[inline]
#[stable(feature = "iter_zip", since = "1.59.0")]
pub use self::adapters::zip;
+#[unstable(feature = "iter_array_chunks", reason = "recently added", issue = "100450")]
+pub use self::adapters::ArrayChunks;
#[unstable(feature = "std_internals", issue = "none")]
pub use self::adapters::ByRefSized;
#[stable(feature = "iter_cloned", since = "1.1.0")]
use super::super::try_process;
use super::super::ByRefSized;
use super::super::TrustedRandomAccessNoCoerce;
-use super::super::{Chain, Cloned, Copied, Cycle, Enumerate, Filter, FilterMap, Fuse};
+use super::super::{ArrayChunks, Chain, Cloned, Copied, Cycle, Enumerate, Filter, FilterMap, Fuse};
use super::super::{FlatMap, Flatten};
use super::super::{FromIterator, Intersperse, IntersperseWith, Product, Sum, Zip};
use super::super::{
Cycle::new(self)
}
+ /// Returns an iterator over `N` elements of the iterator at a time.
+ ///
+ /// The chunks do not overlap. If `N` does not divide the length of the
+ /// iterator, then the last up to `N-1` elements will be omitted and can be
+ /// retrieved from the [`.into_remainder()`][ArrayChunks::into_remainder]
+ /// function of the iterator.
+ ///
+ /// # Panics
+ ///
+ /// Panics if `N` is 0.
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// ```
+ /// #![feature(iter_array_chunks)]
+ ///
+ /// let mut iter = "lorem".chars().array_chunks();
+ /// assert_eq!(iter.next(), Some(['l', 'o']));
+ /// assert_eq!(iter.next(), Some(['r', 'e']));
+ /// assert_eq!(iter.next(), None);
+ /// assert_eq!(iter.into_remainder().unwrap().as_slice(), &['m']);
+ /// ```
+ ///
+ /// ```
+ /// #![feature(iter_array_chunks)]
+ ///
+ /// let data = [1, 1, 2, -2, 6, 0, 3, 1];
+ /// // ^-----^ ^------^
+ /// for [x, y, z] in data.iter().array_chunks() {
+ /// assert_eq!(x + y + z, 4);
+ /// }
+ /// ```
+ #[track_caller]
+ #[unstable(feature = "iter_array_chunks", reason = "recently added", issue = "100450")]
+ fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N>
+ where
+ Self: Sized,
+ {
+ ArrayChunks::new(self)
+ }
+
/// Sums the elements of an iterator.
///
/// Takes each element, adds them together, and returns the result.
/// any value of type `Self` are safely transmutable into a value of type `Dst`, in a given `Context`,
/// notwithstanding whatever safety checks you have asked the compiler to [`Assume`] are satisfied.
#[unstable(feature = "transmutability", issue = "99571")]
-#[cfg_attr(not(bootstrap), lang = "transmute_trait")]
+#[lang = "transmute_trait"]
#[rustc_on_unimplemented(
message = "`{Src}` cannot be safely transmuted into `{Self}` in the defining scope of `{Context}`.",
label = "`{Src}` cannot be safely transmuted into `{Self}` in the defining scope of `{Context}`."
// Fake impl that's only really used for docs.
#[cfg(doc)]
#[stable(feature = "rust1", since = "1.0.0")]
-#[cfg_attr(not(bootstrap), doc(fake_variadic))]
+#[doc(fake_variadic)]
/// This trait is implemented on arbitrary-length tuples.
impl<T: Clone> Clone for (T,) {
fn clone(&self) -> Self {
// Fake impl that's only really used for docs.
#[cfg(doc)]
#[stable(feature = "rust1", since = "1.0.0")]
-#[cfg_attr(not(bootstrap), doc(fake_variadic))]
+#[doc(fake_variadic)]
/// This trait is implemented on arbitrary-length tuples.
impl<T: Copy> Copy for (T,) {
// empty
// Required to make auto trait impls render.
// See src/librustdoc/passes/collect_trait_impls.rs:collect_trait_impls
#[doc(hidden)]
-#[cfg(not(bootstrap))]
impl<Ret, T> fn(T) -> Ret {}
// Fake impl that's only really used for docs.
#[cfg(doc)]
#[stable(feature = "rust1", since = "1.0.0")]
-#[cfg_attr(not(bootstrap), doc(fake_variadic))]
+#[doc(fake_variadic)]
/// This trait is implemented on function pointers with any number of arguments.
impl<Ret, T> Clone for fn(T) -> Ret {
fn clone(&self) -> Self {
// Fake impl that's only really used for docs.
#[cfg(doc)]
#[stable(feature = "rust1", since = "1.0.0")]
-#[cfg_attr(not(bootstrap), doc(fake_variadic))]
+#[doc(fake_variadic)]
/// This trait is implemented on function pointers with any number of arguments.
impl<Ret, T> Copy for fn(T) -> Ret {
// empty
/// Accessing adjacent `u8` as `u16`
///
/// ```
- /// # fn foo(n: usize) {
- /// # use std::mem::align_of;
+ /// use std::mem::align_of;
+ ///
/// # unsafe {
- /// let x = [5u8, 6u8, 7u8, 8u8, 9u8];
- /// let ptr = x.as_ptr().add(n) as *const u8;
+ /// let x = [5_u8, 6, 7, 8, 9];
+ /// let ptr = x.as_ptr();
/// let offset = ptr.align_offset(align_of::<u16>());
- /// if offset < x.len() - n - 1 {
- /// let u16_ptr = ptr.add(offset) as *const u16;
- /// assert_ne!(*u16_ptr, 500);
+ ///
+ /// if offset < x.len() - 1 {
+ /// let u16_ptr = ptr.add(offset).cast::<u16>();
+ /// assert!(*u16_ptr == u16::from_ne_bytes([5, 6]) || *u16_ptr == u16::from_ne_bytes([6, 7]));
/// } else {
/// // while the pointer can be aligned via `offset`, it would point
/// // outside the allocation
/// }
- /// # } }
+ /// # }
/// ```
#[stable(feature = "align_offset", since = "1.36.0")]
#[rustc_const_unstable(feature = "const_align_offset", issue = "90962")]
phantom: crate::marker::PhantomData<Dyn>,
}
-#[cfg(not(bootstrap))]
extern "C" {
/// Opaque type for accessing vtables.
///
type VTable;
}
-/// The common prefix of all vtables. It is followed by function pointers for trait methods.
-///
-/// Private implementation detail of `DynMetadata::size_of` etc.
-#[repr(C)]
-#[cfg(bootstrap)]
-struct VTable {
- drop_in_place: fn(*mut ()),
- size_of: usize,
- align_of: usize,
-}
-
impl<Dyn: ?Sized> DynMetadata<Dyn> {
/// Returns the size of the type associated with this vtable.
#[inline]
// Note that "size stored in vtable" is *not* the same as "result of size_of_val_raw".
// Consider a reference like `&(i32, dyn Send)`: the vtable will only store the size of the
// `Send` part!
- #[cfg(bootstrap)]
- return self.vtable_ptr.size_of;
- #[cfg(not(bootstrap))]
// SAFETY: DynMetadata always contains a valid vtable pointer
return unsafe {
crate::intrinsics::vtable_size(self.vtable_ptr as *const VTable as *const ())
/// Returns the alignment of the type associated with this vtable.
#[inline]
pub fn align_of(self) -> usize {
- #[cfg(bootstrap)]
- return self.vtable_ptr.align_of;
- #[cfg(not(bootstrap))]
// SAFETY: DynMetadata always contains a valid vtable pointer
return unsafe {
crate::intrinsics::vtable_align(self.vtable_ptr as *const VTable as *const ())
#[must_use]
#[inline]
#[unstable(feature = "strict_provenance", issue = "95228")]
+#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
pub fn from_exposed_addr<T>(addr: usize) -> *const T
where
T: Sized,
#[must_use]
#[inline]
#[unstable(feature = "strict_provenance", issue = "95228")]
+#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
pub fn from_exposed_addr_mut<T>(addr: usize) -> *mut T
where
T: Sized,
$item
};
($a:ident @ #[$meta:meta] $item:item) => {
- #[cfg_attr(not(bootstrap), doc(fake_variadic))]
+ #[doc(fake_variadic)]
#[doc = "This trait is implemented for function pointers with up to twelve arguments."]
#[$meta]
$item
/// Accessing adjacent `u8` as `u16`
///
/// ```
- /// # fn foo(n: usize) {
- /// # use std::mem::align_of;
+ /// use std::mem::align_of;
+ ///
/// # unsafe {
- /// let x = [5u8, 6u8, 7u8, 8u8, 9u8];
- /// let ptr = x.as_ptr().add(n) as *const u8;
+ /// let mut x = [5_u8, 6, 7, 8, 9];
+ /// let ptr = x.as_mut_ptr();
/// let offset = ptr.align_offset(align_of::<u16>());
- /// if offset < x.len() - n - 1 {
- /// let u16_ptr = ptr.add(offset) as *const u16;
- /// assert_ne!(*u16_ptr, 500);
+ ///
+ /// if offset < x.len() - 1 {
+ /// let u16_ptr = ptr.add(offset).cast::<u16>();
+ /// *u16_ptr = 0;
+ ///
+ /// assert!(x == [0, 0, 7, 8, 9] || x == [5, 0, 0, 8, 9]);
/// } else {
/// // while the pointer can be aligned via `offset`, it would point
/// // outside the allocation
/// }
- /// # } }
+ /// # }
/// ```
#[stable(feature = "align_offset", since = "1.36.0")]
#[rustc_const_unstable(feature = "const_align_offset", issue = "90962")]
assume(!ptr.is_null());
let end = if mem::size_of::<T>() == 0 {
- (ptr as *const u8).wrapping_add(slice.len()) as *const T
+ ptr.wrapping_byte_add(slice.len())
} else {
ptr.add(slice.len())
};
assume(!ptr.is_null());
let end = if mem::size_of::<T>() == 0 {
- (ptr as *mut u8).wrapping_add(slice.len()) as *mut T
+ ptr.wrapping_byte_add(slice.len())
} else {
ptr.add(slice.len())
};
}
}
-#[cfg(not(bootstrap))]
#[cfg(not(test))]
impl [f32] {
/// Sorts the slice of floats.
}
}
-#[cfg(not(bootstrap))]
#[cfg(not(test))]
impl [f64] {
/// Sorts the slice of floats.
#[unstable(feature = "strict_provenance_atomic_ptr", issue = "99108")]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
pub fn fetch_byte_add(&self, val: usize, order: Ordering) -> *mut T {
- #[cfg(not(bootstrap))]
// SAFETY: data races are prevented by atomic intrinsics.
- unsafe {
- atomic_add(self.p.get(), core::ptr::invalid_mut(val), order).cast()
- }
- #[cfg(bootstrap)]
- // SAFETY: data races are prevented by atomic intrinsics.
- unsafe {
- atomic_add(self.p.get().cast::<usize>(), val, order) as *mut T
- }
+ unsafe { atomic_add(self.p.get(), core::ptr::invalid_mut(val), order).cast() }
}
/// Offsets the pointer's address by subtracting `val` *bytes*, returning the
#[unstable(feature = "strict_provenance_atomic_ptr", issue = "99108")]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
pub fn fetch_byte_sub(&self, val: usize, order: Ordering) -> *mut T {
- #[cfg(not(bootstrap))]
// SAFETY: data races are prevented by atomic intrinsics.
- unsafe {
- atomic_sub(self.p.get(), core::ptr::invalid_mut(val), order).cast()
- }
- #[cfg(bootstrap)]
- // SAFETY: data races are prevented by atomic intrinsics.
- unsafe {
- atomic_sub(self.p.get().cast::<usize>(), val, order) as *mut T
- }
+ unsafe { atomic_sub(self.p.get(), core::ptr::invalid_mut(val), order).cast() }
}
/// Performs a bitwise "or" operation on the address of the current pointer,
#[unstable(feature = "strict_provenance_atomic_ptr", issue = "99108")]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
pub fn fetch_or(&self, val: usize, order: Ordering) -> *mut T {
- #[cfg(not(bootstrap))]
- // SAFETY: data races are prevented by atomic intrinsics.
- unsafe {
- atomic_or(self.p.get(), core::ptr::invalid_mut(val), order).cast()
- }
- #[cfg(bootstrap)]
// SAFETY: data races are prevented by atomic intrinsics.
- unsafe {
- atomic_or(self.p.get().cast::<usize>(), val, order) as *mut T
- }
+ unsafe { atomic_or(self.p.get(), core::ptr::invalid_mut(val), order).cast() }
}
/// Performs a bitwise "and" operation on the address of the current
#[unstable(feature = "strict_provenance_atomic_ptr", issue = "99108")]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
pub fn fetch_and(&self, val: usize, order: Ordering) -> *mut T {
- #[cfg(not(bootstrap))]
- // SAFETY: data races are prevented by atomic intrinsics.
- unsafe {
- atomic_and(self.p.get(), core::ptr::invalid_mut(val), order).cast()
- }
- #[cfg(bootstrap)]
// SAFETY: data races are prevented by atomic intrinsics.
- unsafe {
- atomic_and(self.p.get().cast::<usize>(), val, order) as *mut T
- }
+ unsafe { atomic_and(self.p.get(), core::ptr::invalid_mut(val), order).cast() }
}
/// Performs a bitwise "xor" operation on the address of the current
#[unstable(feature = "strict_provenance_atomic_ptr", issue = "99108")]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
pub fn fetch_xor(&self, val: usize, order: Ordering) -> *mut T {
- #[cfg(not(bootstrap))]
- // SAFETY: data races are prevented by atomic intrinsics.
- unsafe {
- atomic_xor(self.p.get(), core::ptr::invalid_mut(val), order).cast()
- }
- #[cfg(bootstrap)]
// SAFETY: data races are prevented by atomic intrinsics.
- unsafe {
- atomic_xor(self.p.get().cast::<usize>(), val, order) as *mut T
- }
+ unsafe { atomic_xor(self.p.get(), core::ptr::invalid_mut(val), order).cast() }
}
}
let (val, ok) = unsafe {
match (success, failure) {
(Relaxed, Relaxed) => intrinsics::atomic_cxchg_relaxed_relaxed(dst, old, new),
- #[cfg(not(bootstrap))]
(Relaxed, Acquire) => intrinsics::atomic_cxchg_relaxed_acquire(dst, old, new),
- #[cfg(not(bootstrap))]
(Relaxed, SeqCst) => intrinsics::atomic_cxchg_relaxed_seqcst(dst, old, new),
(Acquire, Relaxed) => intrinsics::atomic_cxchg_acquire_relaxed(dst, old, new),
(Acquire, Acquire) => intrinsics::atomic_cxchg_acquire_acquire(dst, old, new),
- #[cfg(not(bootstrap))]
(Acquire, SeqCst) => intrinsics::atomic_cxchg_acquire_seqcst(dst, old, new),
(Release, Relaxed) => intrinsics::atomic_cxchg_release_relaxed(dst, old, new),
- #[cfg(not(bootstrap))]
(Release, Acquire) => intrinsics::atomic_cxchg_release_acquire(dst, old, new),
- #[cfg(not(bootstrap))]
(Release, SeqCst) => intrinsics::atomic_cxchg_release_seqcst(dst, old, new),
(AcqRel, Relaxed) => intrinsics::atomic_cxchg_acqrel_relaxed(dst, old, new),
(AcqRel, Acquire) => intrinsics::atomic_cxchg_acqrel_acquire(dst, old, new),
- #[cfg(not(bootstrap))]
(AcqRel, SeqCst) => intrinsics::atomic_cxchg_acqrel_seqcst(dst, old, new),
(SeqCst, Relaxed) => intrinsics::atomic_cxchg_seqcst_relaxed(dst, old, new),
(SeqCst, Acquire) => intrinsics::atomic_cxchg_seqcst_acquire(dst, old, new),
(SeqCst, SeqCst) => intrinsics::atomic_cxchg_seqcst_seqcst(dst, old, new),
(_, AcqRel) => panic!("there is no such thing as an acquire-release failure ordering"),
(_, Release) => panic!("there is no such thing as a release failure ordering"),
- #[cfg(bootstrap)]
- _ => panic!("a failure ordering can't be stronger than a success ordering"),
}
};
if ok { Ok(val) } else { Err(val) }
let (val, ok) = unsafe {
match (success, failure) {
(Relaxed, Relaxed) => intrinsics::atomic_cxchgweak_relaxed_relaxed(dst, old, new),
- #[cfg(not(bootstrap))]
(Relaxed, Acquire) => intrinsics::atomic_cxchgweak_relaxed_acquire(dst, old, new),
- #[cfg(not(bootstrap))]
(Relaxed, SeqCst) => intrinsics::atomic_cxchgweak_relaxed_seqcst(dst, old, new),
(Acquire, Relaxed) => intrinsics::atomic_cxchgweak_acquire_relaxed(dst, old, new),
(Acquire, Acquire) => intrinsics::atomic_cxchgweak_acquire_acquire(dst, old, new),
- #[cfg(not(bootstrap))]
(Acquire, SeqCst) => intrinsics::atomic_cxchgweak_acquire_seqcst(dst, old, new),
(Release, Relaxed) => intrinsics::atomic_cxchgweak_release_relaxed(dst, old, new),
- #[cfg(not(bootstrap))]
(Release, Acquire) => intrinsics::atomic_cxchgweak_release_acquire(dst, old, new),
- #[cfg(not(bootstrap))]
(Release, SeqCst) => intrinsics::atomic_cxchgweak_release_seqcst(dst, old, new),
(AcqRel, Relaxed) => intrinsics::atomic_cxchgweak_acqrel_relaxed(dst, old, new),
(AcqRel, Acquire) => intrinsics::atomic_cxchgweak_acqrel_acquire(dst, old, new),
- #[cfg(not(bootstrap))]
(AcqRel, SeqCst) => intrinsics::atomic_cxchgweak_acqrel_seqcst(dst, old, new),
(SeqCst, Relaxed) => intrinsics::atomic_cxchgweak_seqcst_relaxed(dst, old, new),
(SeqCst, Acquire) => intrinsics::atomic_cxchgweak_seqcst_acquire(dst, old, new),
(SeqCst, SeqCst) => intrinsics::atomic_cxchgweak_seqcst_seqcst(dst, old, new),
(_, AcqRel) => panic!("there is no such thing as an acquire-release failure ordering"),
(_, Release) => panic!("there is no such thing as a release failure ordering"),
- #[cfg(bootstrap)]
- _ => panic!("a failure ordering can't be stronger than a success ordering"),
}
};
if ok { Ok(val) } else { Err(val) }
// Otherwise, it hides the docs entirely.
macro_rules! maybe_tuple_doc {
($a:ident @ #[$meta:meta] $item:item) => {
- #[cfg_attr(not(bootstrap), doc(fake_variadic))]
+ #[doc(fake_variadic)]
#[doc = "This trait is implemented for tuples up to twelve items long."]
#[$meta]
$item
const fn unaligned_ptr() -> *const u16 {
// Since DATA.as_ptr() is aligned to two bytes, adding 1 byte to that produces an unaligned *const u16
- unsafe { (DATA.as_ptr() as *const u8).add(1) as *const u16 }
+ unsafe { DATA.as_ptr().byte_add(1) }
}
#[test]
const fn write_unaligned() -> [u16; 2] {
let mut two_aligned = [0u16; 2];
unsafe {
- let unaligned_ptr = (two_aligned.as_mut_ptr() as *mut u8).add(1) as *mut u16;
+ let unaligned_ptr = two_aligned.as_mut_ptr().byte_add(1);
ptr::write_unaligned(unaligned_ptr, u16::from_ne_bytes([0x23, 0x45]));
}
two_aligned
const fn write_unaligned() -> [u16; 2] {
let mut two_aligned = [0u16; 2];
unsafe {
- let unaligned_ptr = (two_aligned.as_mut_ptr() as *mut u8).add(1) as *mut u16;
+ let unaligned_ptr = two_aligned.as_mut_ptr().byte_add(1);
unaligned_ptr.write_unaligned(u16::from_ne_bytes([0x23, 0x45]));
}
two_aligned
--- /dev/null
+use core::cell::Cell;
+use core::iter::{self, Iterator};
+
+use super::*;
+
+#[test]
+fn test_iterator_array_chunks_infer() {
+ let xs = [1, 1, 2, -2, 6, 0, 3, 1];
+ for [a, b, c] in xs.iter().copied().array_chunks() {
+ assert_eq!(a + b + c, 4);
+ }
+}
+
+#[test]
+fn test_iterator_array_chunks_clone_and_drop() {
+ let count = Cell::new(0);
+ let mut it = (0..5).map(|_| CountDrop::new(&count)).array_chunks::<3>();
+ assert_eq!(it.by_ref().count(), 1);
+ assert_eq!(count.get(), 3);
+ let mut it2 = it.clone();
+ assert_eq!(count.get(), 3);
+ assert_eq!(it.into_remainder().unwrap().len(), 2);
+ assert_eq!(count.get(), 5);
+ assert!(it2.next().is_none());
+ assert_eq!(it2.into_remainder().unwrap().len(), 2);
+ assert_eq!(count.get(), 7);
+}
+
+#[test]
+fn test_iterator_array_chunks_remainder() {
+ let mut it = (0..11).array_chunks::<4>();
+ assert_eq!(it.next(), Some([0, 1, 2, 3]));
+ assert_eq!(it.next(), Some([4, 5, 6, 7]));
+ assert_eq!(it.next(), None);
+ assert_eq!(it.into_remainder().unwrap().as_slice(), &[8, 9, 10]);
+}
+
+#[test]
+fn test_iterator_array_chunks_size_hint() {
+ let it = (0..6).array_chunks::<1>();
+ assert_eq!(it.size_hint(), (6, Some(6)));
+
+ let it = (0..6).array_chunks::<3>();
+ assert_eq!(it.size_hint(), (2, Some(2)));
+
+ let it = (0..6).array_chunks::<5>();
+ assert_eq!(it.size_hint(), (1, Some(1)));
+
+ let it = (0..6).array_chunks::<7>();
+ assert_eq!(it.size_hint(), (0, Some(0)));
+
+ let it = (1..).array_chunks::<2>();
+ assert_eq!(it.size_hint(), (usize::MAX / 2, None));
+
+ let it = (1..).filter(|x| x % 2 != 0).array_chunks::<2>();
+ assert_eq!(it.size_hint(), (0, None));
+}
+
+#[test]
+fn test_iterator_array_chunks_count() {
+ let it = (0..6).array_chunks::<1>();
+ assert_eq!(it.count(), 6);
+
+ let it = (0..6).array_chunks::<3>();
+ assert_eq!(it.count(), 2);
+
+ let it = (0..6).array_chunks::<5>();
+ assert_eq!(it.count(), 1);
+
+ let it = (0..6).array_chunks::<7>();
+ assert_eq!(it.count(), 0);
+
+ let it = (0..6).filter(|x| x % 2 == 0).array_chunks::<2>();
+ assert_eq!(it.count(), 1);
+
+ let it = iter::empty::<i32>().array_chunks::<2>();
+ assert_eq!(it.count(), 0);
+
+ let it = [(); usize::MAX].iter().array_chunks::<2>();
+ assert_eq!(it.count(), usize::MAX / 2);
+}
+
+#[test]
+fn test_iterator_array_chunks_next_and_next_back() {
+ let mut it = (0..11).array_chunks::<3>();
+ assert_eq!(it.next(), Some([0, 1, 2]));
+ assert_eq!(it.next_back(), Some([6, 7, 8]));
+ assert_eq!(it.next(), Some([3, 4, 5]));
+ assert_eq!(it.next_back(), None);
+ assert_eq!(it.next(), None);
+ assert_eq!(it.next_back(), None);
+ assert_eq!(it.next(), None);
+ assert_eq!(it.into_remainder().unwrap().as_slice(), &[9, 10]);
+}
+
+#[test]
+fn test_iterator_array_chunks_rev_remainder() {
+ let mut it = (0..11).array_chunks::<4>();
+ {
+ let mut it = it.by_ref().rev();
+ assert_eq!(it.next(), Some([4, 5, 6, 7]));
+ assert_eq!(it.next(), Some([0, 1, 2, 3]));
+ assert_eq!(it.next(), None);
+ assert_eq!(it.next(), None);
+ }
+ assert_eq!(it.into_remainder().unwrap().as_slice(), &[8, 9, 10]);
+}
+
+#[test]
+fn test_iterator_array_chunks_try_fold() {
+ let count = Cell::new(0);
+ let mut it = (0..10).map(|_| CountDrop::new(&count)).array_chunks::<3>();
+ let result: Result<_, ()> = it.by_ref().try_fold(0, |acc, _item| Ok(acc + 1));
+ assert_eq!(result, Ok(3));
+ assert_eq!(count.get(), 9);
+ drop(it);
+ assert_eq!(count.get(), 10);
+
+ let count = Cell::new(0);
+ let mut it = (0..10).map(|_| CountDrop::new(&count)).array_chunks::<3>();
+ let result = it.by_ref().try_fold(0, |acc, _item| if acc < 2 { Ok(acc + 1) } else { Err(acc) });
+ assert_eq!(result, Err(2));
+ assert_eq!(count.get(), 9);
+ drop(it);
+ assert_eq!(count.get(), 9);
+}
+
+#[test]
+fn test_iterator_array_chunks_fold() {
+ let result = (1..11).array_chunks::<3>().fold(0, |acc, [a, b, c]| {
+ assert_eq!(acc + 1, a);
+ assert_eq!(acc + 2, b);
+ assert_eq!(acc + 3, c);
+ acc + 3
+ });
+ assert_eq!(result, 9);
+
+ let count = Cell::new(0);
+ let result =
+ (0..10).map(|_| CountDrop::new(&count)).array_chunks::<3>().fold(0, |acc, _item| acc + 1);
+ assert_eq!(result, 3);
+ assert_eq!(count.get(), 10);
+}
+
+#[test]
+fn test_iterator_array_chunks_try_rfold() {
+ let count = Cell::new(0);
+ let mut it = (0..10).map(|_| CountDrop::new(&count)).array_chunks::<3>();
+ let result: Result<_, ()> = it.try_rfold(0, |acc, _item| Ok(acc + 1));
+ assert_eq!(result, Ok(3));
+ assert_eq!(count.get(), 9);
+ drop(it);
+ assert_eq!(count.get(), 10);
+
+ let count = Cell::new(0);
+ let mut it = (0..10).map(|_| CountDrop::new(&count)).array_chunks::<3>();
+ let result = it.try_rfold(0, |acc, _item| if acc < 2 { Ok(acc + 1) } else { Err(acc) });
+ assert_eq!(result, Err(2));
+ assert_eq!(count.get(), 9);
+ drop(it);
+ assert_eq!(count.get(), 10);
+}
+
+#[test]
+fn test_iterator_array_chunks_rfold() {
+ let result = (1..11).array_chunks::<3>().rfold(0, |acc, [a, b, c]| {
+ assert_eq!(10 - (acc + 1), c);
+ assert_eq!(10 - (acc + 2), b);
+ assert_eq!(10 - (acc + 3), a);
+ acc + 3
+ });
+ assert_eq!(result, 9);
+
+ let count = Cell::new(0);
+ let result =
+ (0..10).map(|_| CountDrop::new(&count)).array_chunks::<3>().rfold(0, |acc, _item| acc + 1);
+ assert_eq!(result, 3);
+ assert_eq!(count.get(), 10);
+}
+mod array_chunks;
mod chain;
mod cloned;
mod copied;
ret
}
}
+
+#[derive(Debug, Clone)]
+struct CountDrop<'a> {
+ dropped: bool,
+ count: &'a Cell<usize>,
+}
+
+impl<'a> CountDrop<'a> {
+ pub fn new(count: &'a Cell<usize>) -> Self {
+ Self { dropped: false, count }
+ }
+}
+
+impl Drop for CountDrop<'_> {
+ fn drop(&mut self) {
+ if self.dropped {
+ panic!("double drop");
+ }
+ self.dropped = true;
+ self.count.set(self.count.get() + 1);
+ }
+}
// advance it further. `Unfuse` tests that this doesn't happen by panicking in that scenario.
let _ = non_fused.skip(20).next();
}
+
+#[test]
+fn test_skip_non_fused_nth_overflow() {
+ let non_fused = Unfuse::new(0..10);
+
+ // Ensures that calling skip and `nth` where the sum would overflow does not fail for non-fused
+ // iterators.
+ let _ = non_fused.skip(20).nth(usize::MAX);
+}
+
+#[test]
+fn test_skip_overflow_wrapping() {
+ // Test to ensure even on overflowing on `skip+nth` the correct amount of elements are yielded.
+ struct WrappingIterator(usize);
+
+ impl Iterator for WrappingIterator {
+ type Item = usize;
+
+ fn next(&mut self) -> core::option::Option<Self::Item> {
+ <Self as Iterator>::nth(self, 0)
+ }
+
+ fn nth(&mut self, nth: usize) -> core::option::Option<Self::Item> {
+ self.0 = self.0.wrapping_add(nth.wrapping_add(1));
+ Some(self.0)
+ }
+ }
+
+ let wrap = WrappingIterator(0);
+ assert_eq!(wrap.skip(20).nth(usize::MAX), Some(20));
+}
#![feature(const_maybe_uninit_assume_init_read)]
#![feature(const_nonnull_new)]
#![feature(const_num_from_num)]
+#![feature(const_pointer_byte_offsets)]
#![feature(const_ptr_as_ref)]
#![feature(const_ptr_read)]
#![feature(const_ptr_write)]
#![feature(slice_partition_dedup)]
#![feature(int_log)]
#![feature(iter_advance_by)]
+#![feature(iter_array_chunks)]
#![feature(iter_collect_into)]
#![feature(iter_partition_in_place)]
#![feature(iter_intersperse)]
#![feature(never_type)]
#![feature(unwrap_infallible)]
#![feature(result_into_ok_or_err)]
+#![feature(pointer_byte_offsets)]
#![feature(portable_simd)]
#![feature(ptr_metadata)]
#![feature(once_cell)]
// Tell the compiler to link to either panic_abort or panic_unwind
#![needs_panic_runtime]
// Ensure that std can be linked against panic_abort despite compiled with `-C panic=unwind`
-#![cfg_attr(not(bootstrap), deny(ffi_unwind_calls))]
+#![deny(ffi_unwind_calls)]
// std may use features in a platform-specific way
#![allow(unused_features)]
#![cfg_attr(test, feature(internal_output_capture, print_internals, update_panic_count, rt))]
#![feature(intra_doc_pointers)]
#![feature(label_break_value)]
#![feature(lang_items)]
-#![cfg_attr(bootstrap, feature(let_chains))]
#![feature(let_else)]
#![feature(linkage)]
#![feature(link_cfg)]
use crate::sys_common::{AsInner, IntoInner};
/// Raw file descriptors.
-#[cfg_attr(not(bootstrap), rustc_allowed_through_unstable_modules)]
+#[rustc_allowed_through_unstable_modules]
#[stable(feature = "rust1", since = "1.0.0")]
pub type RawFd = raw::c_int;
/// This is only available on unix and WASI platforms and must be imported in
/// order to call the method. Windows platforms have a corresponding
/// `AsRawHandle` and `AsRawSocket` set of traits.
-#[cfg_attr(not(bootstrap), rustc_allowed_through_unstable_modules)]
+#[rustc_allowed_through_unstable_modules]
#[stable(feature = "rust1", since = "1.0.0")]
pub trait AsRawFd {
/// Extracts the raw file descriptor.
/// A trait to express the ability to construct an object from a raw file
/// descriptor.
-#[cfg_attr(not(bootstrap), rustc_allowed_through_unstable_modules)]
+#[rustc_allowed_through_unstable_modules]
#[stable(feature = "from_raw_os", since = "1.1.0")]
pub trait FromRawFd {
/// Constructs a new instance of `Self` from the given raw file
/// A trait to express the ability to consume an object and acquire ownership of
/// its raw file descriptor.
-#[cfg_attr(not(bootstrap), rustc_allowed_through_unstable_modules)]
+#[rustc_allowed_through_unstable_modules]
#[stable(feature = "into_raw_os", since = "1.4.0")]
pub trait IntoRawFd {
/// Consumes this object, returning the raw underlying file descriptor.
// Fake impl that's only really used for docs.
#[cfg(doc)]
#[stable(feature = "rust1", since = "1.0.0")]
-#[cfg_attr(not(bootstrap), doc(fake_variadic))]
+#[doc(fake_variadic)]
/// This trait is implemented on arbitrary-length tuples.
impl<T: Clone> Clone for (T,) {
fn clone(&self) -> Self {
// Fake impl that's only really used for docs.
#[cfg(doc)]
#[stable(feature = "rust1", since = "1.0.0")]
-#[cfg_attr(not(bootstrap), doc(fake_variadic))]
+#[doc(fake_variadic)]
/// This trait is implemented on arbitrary-length tuples.
impl<T: Copy> Copy for (T,) {
// empty
// Required to make auto trait impls render.
// See src/librustdoc/passes/collect_trait_impls.rs:collect_trait_impls
#[doc(hidden)]
-#[cfg(not(bootstrap))]
impl<Ret, T> fn(T) -> Ret {}
// Fake impl that's only really used for docs.
#[cfg(doc)]
#[stable(feature = "rust1", since = "1.0.0")]
-#[cfg_attr(not(bootstrap), doc(fake_variadic))]
+#[doc(fake_variadic)]
/// This trait is implemented on function pointers with any number of arguments.
impl<Ret, T> Clone for fn(T) -> Ret {
fn clone(&self) -> Self {
// Fake impl that's only really used for docs.
#[cfg(doc)]
#[stable(feature = "rust1", since = "1.0.0")]
-#[cfg_attr(not(bootstrap), doc(fake_variadic))]
+#[doc(fake_variadic)]
/// This trait is implemented on function pointers with any number of arguments.
impl<Ret, T> Copy for fn(T) -> Ret {
// empty
/// * the pointer is null.
/// * the pointed-to range is not in user memory.
unsafe fn check_ptr(ptr: *const Self) {
- let is_aligned = |p| -> bool { 0 == (p as usize) & (Self::align_of() - 1) };
+ let is_aligned = |p: *const u8| -> bool { 0 == p.addr() & (Self::align_of() - 1) };
assert!(is_aligned(ptr as *const u8));
assert!(is_user_range(ptr as _, mem::size_of_val(unsafe { &*ptr })));
fn default() -> Self {
// Redox doesn't appear to support `UTIME_OMIT`, so we stub it out here, and always return
// an error in `set_times`.
- // ESP-IDF does not support `futimens` at all and the behavior for that OS is therefore
+ // ESP-IDF and HorizonOS do not support `futimens` at all and the behavior for those OS is therefore
// the same as for Redox.
- #[cfg(any(target_os = "redox", target_os = "espidf"))]
+ #[cfg(any(target_os = "redox", target_os = "espidf", target_os = "horizon"))]
let omit = libc::timespec { tv_sec: 0, tv_nsec: 0 };
- #[cfg(not(any(target_os = "redox", target_os = "espidf")))]
+ #[cfg(not(any(target_os = "redox", target_os = "espidf", target_os = "horizon")))]
let omit = libc::timespec { tv_sec: 0, tv_nsec: libc::UTIME_OMIT as _ };
Self([omit; 2])
}
impl Drop for Dir {
fn drop(&mut self) {
let r = unsafe { libc::closedir(self.0) };
- debug_assert_eq!(r, 0);
+ assert!(
+ r == 0 || crate::io::Error::last_os_error().kind() == crate::io::ErrorKind::Interrupted,
+ "unexpected error during closedir: {:?}",
+ crate::io::Error::last_os_error()
+ );
}
}
pub fn set_times(&self, times: FileTimes) -> io::Result<()> {
cfg_if::cfg_if! {
- if #[cfg(any(target_os = "redox", target_os = "espidf"))] {
+ if #[cfg(any(target_os = "redox", target_os = "espidf", target_os = "horizon"))] {
// Redox doesn't appear to support `UTIME_OMIT`.
- // ESP-IDF does not support `futimens` at all and the behavior for that OS is therefore
+ // ESP-IDF and HorizonOS do not support `futimens` at all and the behavior for those OS is therefore
// the same as for Redox.
drop(times);
Err(io::const_io_error!(
let mut sys_now = libc::timeval { tv_sec: 0, tv_usec: 0 };
let stable_now = Instant::now();
let r = libc::gettimeofday(&mut sys_now, ptr::null_mut());
- debug_assert_eq!(r, 0);
+ assert_eq!(r, 0, "unexpected error: {:?}", crate::io::Error::last_os_error());
let nsec = dur.subsec_nanos() as libc::c_long + (sys_now.tv_usec * 1000) as libc::c_long;
let extra = (nsec / 1_000_000_000) as libc::time_t;
use crate::alloc::{GlobalAlloc, Layout, System};
+use crate::ptr::null_mut;
#[stable(feature = "alloc_system_type", since = "1.28.0")]
unsafe impl GlobalAlloc for System {
#[inline]
unsafe fn alloc(&self, _layout: Layout) -> *mut u8 {
- 0 as *mut u8
+ null_mut()
}
#[inline]
unsafe fn alloc_zeroed(&self, _layout: Layout) -> *mut u8 {
- 0 as *mut u8
+ null_mut()
}
#[inline]
#[inline]
unsafe fn realloc(&self, _ptr: *mut u8, _layout: Layout, _new_size: usize) -> *mut u8 {
- 0 as *mut u8
+ null_mut()
}
}
use super::{Key, StaticKey};
+use core::ptr;
fn assert_sync<T: Sync>() {}
fn assert_send<T: Send>() {}
let k2 = Key::new(None);
assert!(k1.get().is_null());
assert!(k2.get().is_null());
- k1.set(1 as *mut _);
- k2.set(2 as *mut _);
+ k1.set(ptr::invalid_mut(1));
+ k2.set(ptr::invalid_mut(2));
assert_eq!(k1.get() as usize, 1);
assert_eq!(k2.get() as usize, 2);
}
unsafe {
assert!(K1.get().is_null());
assert!(K2.get().is_null());
- K1.set(1 as *mut _);
- K2.set(2 as *mut _);
+ K1.set(ptr::invalid_mut(1));
+ K2.set(ptr::invalid_mut(2));
assert_eq!(K1.get() as usize, 1);
assert_eq!(K2.get() as usize, 2);
}
use crate::str;
use crate::sync::Arc;
use crate::sys::thread as imp;
-use crate::sys_common::mutex;
use crate::sys_common::thread;
use crate::sys_common::thread_info;
use crate::sys_common::thread_parker::Parker;
impl ThreadId {
// Generate a new unique thread ID.
fn new() -> ThreadId {
- // It is UB to attempt to acquire this mutex reentrantly!
- static GUARD: mutex::StaticMutex = mutex::StaticMutex::new();
- static mut COUNTER: u64 = 1;
-
- unsafe {
- let guard = GUARD.lock();
-
- // If we somehow use up all our bits, panic so that we're not
- // covering up subtle bugs of IDs being reused.
- if COUNTER == u64::MAX {
- drop(guard); // in case the panic handler ends up calling `ThreadId::new()`, avoid reentrant lock acquire.
- panic!("failed to generate unique thread ID: bitspace exhausted");
- }
-
- let id = COUNTER;
- COUNTER += 1;
+ #[cold]
+ fn exhausted() -> ! {
+ panic!("failed to generate unique thread ID: bitspace exhausted")
+ }
- ThreadId(NonZeroU64::new(id).unwrap())
+ cfg_if::cfg_if! {
+ if #[cfg(target_has_atomic = "64")] {
+ use crate::sync::atomic::{AtomicU64, Ordering::Relaxed};
+
+ static COUNTER: AtomicU64 = AtomicU64::new(0);
+
+ let mut last = COUNTER.load(Relaxed);
+ loop {
+ let Some(id) = last.checked_add(1) else {
+ exhausted();
+ };
+
+ match COUNTER.compare_exchange_weak(last, id, Relaxed, Relaxed) {
+ Ok(_) => return ThreadId(NonZeroU64::new(id).unwrap()),
+ Err(id) => last = id,
+ }
+ }
+ } else {
+ use crate::sys_common::mutex::StaticMutex;
+
+ // It is UB to attempt to acquire this mutex reentrantly!
+ static GUARD: StaticMutex = StaticMutex::new();
+ static mut COUNTER: u64 = 0;
+
+ unsafe {
+ let guard = GUARD.lock();
+
+ let Some(id) = COUNTER.checked_add(1) else {
+ drop(guard); // in case the panic handler ends up calling `ThreadId::new()`, avoid reentrant lock acquire.
+ exhausted();
+ };
+
+ COUNTER = id;
+ drop(guard);
+ ThreadId(NonZeroU64::new(id).unwrap())
+ }
+ }
}
}
// With LLD, we can use ICF (identical code folding) to reduce the executable size
// of librustc_driver/rustc and to improve i-cache utilization.
- if builder.config.use_lld {
+ //
+ // -Wl,[link options] doesn't work on MSVC. However, /OPT:ICF (technically /OPT:REF,ICF)
+ // is already on by default in MSVC optimized builds, which is interpreted as --icf=all:
+ // https://github.com/llvm/llvm-project/blob/3329cec2f79185bafd678f310fafadba2a8c76d2/lld/COFF/Driver.cpp#L1746
+ // https://github.com/rust-lang/rust/blob/f22819bcce4abaff7d1246a56eec493418f9f4ee/compiler/rustc_codegen_ssa/src/back/linker.rs#L827
+ if builder.config.use_lld && !compiler.host.contains("msvc") {
cargo.rustflag("-Clink-args=-Wl,--icf=all");
}
.get(&target)
.and_then(|t| t.llvm_libunwind)
.or(self.llvm_libunwind_default)
- .unwrap_or(LlvmLibunwind::No)
+ .unwrap_or(if target.contains("fuchsia") {
+ LlvmLibunwind::InTree
+ } else {
+ LlvmLibunwind::No
+ })
}
pub fn submodules(&self, rust_info: &GitInfo) -> bool {
pub llvm_profile_generate: bool,
}
+#[derive(Debug)]
#[cfg_attr(test, derive(Clone))]
pub enum Subcommand {
Build {
src/test/ui
ci-mingw-subset-1:
- $(Q)$(CFG_SRC_DIR)/x.sh test --stage 2 $(TESTS_IN_MINGW_2:%=--exclude %)
+ $(Q)$(CFG_SRC_DIR)/x test --stage 2 $(TESTS_IN_MINGW_2:%=--exclude %)
ci-mingw-subset-2:
$(Q)$(BOOTSTRAP) test --stage 2 $(TESTS_IN_MINGW_2)
io::{self, Write},
};
-#[derive(Clone, Copy, Eq, PartialEq)]
+#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum Profile {
Compiler,
Codegen,
--enable-llvm-link-shared \
--set rust.thin-lto-import-instr-limit=10
-# NOTE: intentionally uses all of `x.py`, `x.sh`, and `x.ps1` to make sure they all work on Linux.
+# NOTE: intentionally uses all of `x.py`, `x`, and `x.ps1` to make sure they all work on Linux.
ENV SCRIPT ../x.py --stage 2 test --exclude src/tools/tidy && \
# Run the `mir-opt` tests again but this time for a 32-bit target.
# This enforces that tests using `// EMIT_MIR_FOR_EACH_BIT_WIDTH` have
# the PR is approved and tested for merging.
# It will also detect tests lacking `// EMIT_MIR_FOR_EACH_BIT_WIDTH`,
# despite having different output on 32-bit vs 64-bit targets.
- ../x.sh --stage 2 test src/test/mir-opt \
+ ../x --stage 2 test src/test/mir-opt \
--host='' --target=i686-unknown-linux-gnu && \
# Run the UI test suite again, but in `--pass=check` mode
#
```toml
[build]
target = ["<host_platform>", "aarch64-fuchsia", "x86_64-fuchsia"]
-
-[target.x86_64-fuchsia]
-llvm-libunwind = "in-tree"
-
-[target.aarch64-fuchsia]
-llvm-libunwind = "in-tree"
```
Additionally, the following environment variables must be configured (for
if "trait_bound" in bound:
for param in bound["trait_bound"]["generic_params"]:
check_generic_param(param)
- check_type(bound["trait_bound"]["trait"])
+ check_path(bound["trait_bound"]["trait"])
def check_decl(decl):
if decl["output"]:
check_type(decl["output"])
+def check_path(path):
+ args = path["args"]
+ if args:
+ if "angle_bracketed" in args:
+ for arg in args["angle_bracketed"]["args"]:
+ if "type" in arg:
+ check_type(arg["type"])
+ elif "const" in arg:
+ check_type(arg["const"]["type"])
+ for binding in args["angle_bracketed"]["bindings"]:
+ if "equality" in binding["binding"]:
+ term = binding["binding"]["equality"]
+ if "type" in term: check_type(term["type"])
+ elif "const" in term: check_type(term["const"])
+ elif "constraint" in binding["binding"]:
+ for bound in binding["binding"]["constraint"]:
+ check_generic_bound(bound)
+ elif "parenthesized" in args:
+ for input_ty in args["parenthesized"]["inputs"]:
+ check_type(input_ty)
+ if args["parenthesized"]["output"]:
+ check_type(args["parenthesized"]["output"])
+ if not valid_id(path["id"]):
+ print("Type contained an invalid ID:", path["id"])
+ sys.exit(1)
def check_type(ty):
if ty["kind"] == "resolved_path":
- for bound in ty["inner"]["param_names"]:
- check_generic_bound(bound)
- args = ty["inner"]["args"]
- if args:
- if "angle_bracketed" in args:
- for arg in args["angle_bracketed"]["args"]:
- if "type" in arg:
- check_type(arg["type"])
- elif "const" in arg:
- check_type(arg["const"]["type"])
- for binding in args["angle_bracketed"]["bindings"]:
- if "equality" in binding["binding"]:
- term = binding["binding"]["equality"]
- if "type" in term: check_type(term["type"])
- elif "const" in term: check_type(term["const"])
- elif "constraint" in binding["binding"]:
- for bound in binding["binding"]["constraint"]:
- check_generic_bound(bound)
- elif "parenthesized" in args:
- for input_ty in args["parenthesized"]["inputs"]:
- check_type(input_ty)
- if args["parenthesized"]["output"]:
- check_type(args["parenthesized"]["output"])
- if not valid_id(ty["inner"]["id"]):
- print("Type contained an invalid ID:", ty["inner"]["id"])
- sys.exit(1)
+ check_path(ty["inner"])
elif ty["kind"] == "tuple":
for ty in ty["inner"]:
check_type(ty)
check_decl(ty["inner"]["decl"])
elif ty["kind"] == "qualified_path":
check_type(ty["inner"]["self_type"])
- check_type(ty["inner"]["trait"])
+ check_path(ty["inner"]["trait"])
work_list = set([crate["root"]])
elif item["kind"] == "impl":
check_generics(item["inner"]["generics"])
if item["inner"]["trait"]:
- check_type(item["inner"]["trait"])
+ check_path(item["inner"]["trait"])
if item["inner"]["blanket_impl"]:
check_type(item["inner"]["blanket_impl"])
check_type(item["inner"]["for"])
`PATH` is relative to the output directory. It can be given as `-`
which repeats the most recently used `PATH`.
-* `@has PATH PATTERN` and `@matches PATH PATTERN` checks for
- the occurrence of the given pattern `PATTERN` in the specified file.
+* `@hasraw PATH PATTERN` and `@matchesraw PATH PATTERN` checks
+ for the occurrence of the given pattern `PATTERN` in the specified file.
Only one occurrence of the pattern is enough.
- For `@has`, `PATTERN` is a whitespace-normalized (every consecutive
+ For `@hasraw`, `PATTERN` is a whitespace-normalized (every consecutive
whitespace being replaced by one single space character) string.
The entire file is also whitespace-normalized including newlines.
- For `@matches`, `PATTERN` is a Python-supported regular expression.
+ For `@matchesraw`, `PATTERN` is a Python-supported regular expression.
The file remains intact but the regexp is matched without the `MULTILINE`
and `IGNORECASE` options. You can still use a prefix `(?m)` or `(?i)`
to override them, and `\A` and `\Z` for definitely matching
def check_command(c, cache):
try:
cerr = ""
- if c.cmd == 'has' or c.cmd == 'matches': # string test
- regexp = (c.cmd == 'matches')
- if len(c.args) == 1 and not regexp: # @has <path> = file existence
+ if c.cmd in ['has', 'hasraw', 'matches', 'matchesraw']: # string test
+ regexp = c.cmd.startswith('matches')
+
+ # @has <path> = file existence
+ if len(c.args) == 1 and not regexp and 'raw' not in c.cmd:
try:
cache.get_file(c.args[0])
ret = True
except FailedCheck as err:
cerr = str(err)
ret = False
- elif len(c.args) == 2: # @has/matches <path> <pat> = string test
+ # @hasraw/matchesraw <path> <pat> = string test
+ elif len(c.args) == 2 and 'raw' in c.cmd:
cerr = "`PATTERN` did not match"
ret = check_string(cache.get_file(c.args[0]), c.args[1], regexp)
- elif len(c.args) == 3: # @has/matches <path> <pat> <match> = XML tree test
+ # @has/matches <path> <pat> <match> = XML tree test
+ elif len(c.args) == 3 and 'raw' not in c.cmd:
cerr = "`XPATH PATTERN` did not match"
ret = get_nb_matching_elements(cache, c, regexp, True) != 0
else:
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
<Type Name="str">
<DisplayString>{(char*)data_ptr,[length]s8}</DisplayString>
</Expand>
</Type>
- <!-- Directly tagged enums. $T1 is the type name -->
- <Type Name="enum$<*>">
- <Intrinsic Name="tag" Expression="discriminant" />
- <DisplayString Condition="tag() == 0">{tag(),en}</DisplayString>
- <DisplayString Condition="tag() == 1" Optional="true">{tag(),en}</DisplayString>
- <DisplayString Condition="tag() == 2" Optional="true">{tag(),en}</DisplayString>
- <DisplayString Condition="tag() == 3" Optional="true">{tag(),en}</DisplayString>
- <DisplayString Condition="tag() == 4" Optional="true">{tag(),en}</DisplayString>
- <DisplayString Condition="tag() == 5" Optional="true">{tag(),en}</DisplayString>
- <DisplayString Condition="tag() == 6" Optional="true">{tag(),en}</DisplayString>
- <DisplayString Condition="tag() == 7" Optional="true">{tag(),en}</DisplayString>
- <DisplayString Condition="tag() == 8" Optional="true">{tag(),en}</DisplayString>
- <DisplayString Condition="tag() == 9" Optional="true">{tag(),en}</DisplayString>
- <DisplayString Condition="tag() == 10" Optional="true">{tag(),en}</DisplayString>
- <DisplayString Condition="tag() == 11" Optional="true">{tag(),en}</DisplayString>
- <DisplayString Condition="tag() == 12" Optional="true">{tag(),en}</DisplayString>
- <DisplayString Condition="tag() == 13" Optional="true">{tag(),en}</DisplayString>
- <DisplayString Condition="tag() == 14" Optional="true">{tag(),en}</DisplayString>
- <DisplayString Condition="tag() == 15" Optional="true">{tag(),en}</DisplayString>
+ <!--
+ This is the visualizer for all enums. It takes care of selecting the active variant.
+ See `compiler\rustc_codegen_llvm\src\debuginfo\metadata\enums\cpp_like.rs` for more information.
+ -->
+ <Type Name="enum2$<*>">
+ <!-- NOTE: That tag ranges can wrap around, in which case `end` is less than `begin` and we
+ have to do a different check -->
+ <Intrinsic Name="in_range" Expression="(begin <= end) ? ((x >= begin) && (x <= end)) : ((x >= begin) || (x <= end))">
+ <Parameter Name="x" Type="unsigned __int64" />
+ <Parameter Name="begin" Type="unsigned __int64" />
+ <Parameter Name="end" Type="unsigned __int64" />
+ </Intrinsic>
- <Expand>
- <Synthetic Name="[variant]">
- <DisplayString>{tag(),en}</DisplayString>
- </Synthetic>
- <ExpandedItem Condition="tag() == 0">variant0</ExpandedItem>
- <ExpandedItem Condition="tag() == 1" Optional="true">variant1</ExpandedItem>
- <ExpandedItem Condition="tag() == 2" Optional="true">variant2</ExpandedItem>
- <ExpandedItem Condition="tag() == 3" Optional="true">variant3</ExpandedItem>
- <ExpandedItem Condition="tag() == 4" Optional="true">variant4</ExpandedItem>
- <ExpandedItem Condition="tag() == 5" Optional="true">variant5</ExpandedItem>
- <ExpandedItem Condition="tag() == 6" Optional="true">variant6</ExpandedItem>
- <ExpandedItem Condition="tag() == 7" Optional="true">variant7</ExpandedItem>
- <ExpandedItem Condition="tag() == 8" Optional="true">variant8</ExpandedItem>
- <ExpandedItem Condition="tag() == 9" Optional="true">variant9</ExpandedItem>
- <ExpandedItem Condition="tag() == 10" Optional="true">variant10</ExpandedItem>
- <ExpandedItem Condition="tag() == 11" Optional="true">variant11</ExpandedItem>
- <ExpandedItem Condition="tag() == 12" Optional="true">variant12</ExpandedItem>
- <ExpandedItem Condition="tag() == 13" Optional="true">variant13</ExpandedItem>
- <ExpandedItem Condition="tag() == 14" Optional="true">variant14</ExpandedItem>
- <ExpandedItem Condition="tag() == 15" Optional="true">variant15</ExpandedItem>
- </Expand>
- </Type>
+ <Intrinsic Name="eq128" Expression="(x_hi == y_hi) && (x_lo == y_lo)">
+ <Parameter Name="x_hi" Type="unsigned __int64" />
+ <Parameter Name="x_lo" Type="unsigned __int64" />
+ <Parameter Name="y_hi" Type="unsigned __int64" />
+ <Parameter Name="y_lo" Type="unsigned __int64" />
+ </Intrinsic>
- <!-- Single variant enums. $T1 is the name of the enum, $T2 is the name of the variant -->
- <Type Name="enum$<*, *>">
- <DisplayString>{"$T2",sb}</DisplayString>
- <Expand>
- <Synthetic Name="[variant]">
- <DisplayString>{"$T2",sb}</DisplayString>
- </Synthetic>
- <ExpandedItem>$T2</ExpandedItem>
- </Expand>
- </Type>
+ <Intrinsic Name="lt128" Expression="(x_hi < y_hi) || ((x_hi == y_hi) && (x_lo < y_lo))">
+ <Parameter Name="x_hi" Type="unsigned __int64" />
+ <Parameter Name="x_lo" Type="unsigned __int64" />
+ <Parameter Name="y_hi" Type="unsigned __int64" />
+ <Parameter Name="y_lo" Type="unsigned __int64" />
+ </Intrinsic>
- <!-- Niche-layout enums. $T1 is the name of the enum, $T2 is the low value of the dataful
- variant tag, $T3 is the high value of the dataful variant tag, $T4 is the name of
- the dataful variant -->
- <Type Name="enum$<*, *, *, *>">
- <Intrinsic Name="tag" Expression="discriminant" />
- <Intrinsic Name="is_dataful" Expression="tag() >= $T2 && tag() <= $T3" />
- <DisplayString Condition="is_dataful()">{"$T4",sb}({dataful_variant})</DisplayString>
- <DisplayString Condition="!is_dataful()">{discriminant,en}</DisplayString>
- <Expand>
- <ExpandedItem Condition="is_dataful()">dataful_variant</ExpandedItem>
- <Synthetic Condition="is_dataful()" Name="[variant]">
- <DisplayString>{"$T4",sb}</DisplayString>
- </Synthetic>
- <Synthetic Condition="!is_dataful()" Name="[variant]">
- <DisplayString>{discriminant,en}</DisplayString>
- </Synthetic>
+ <Intrinsic Name="lt_or_eq128" Expression="((x_hi == y_hi) && (x_lo == y_lo)) || lt128(x_hi, x_lo, y_hi, y_lo)">
+ <Parameter Name="x_hi" Type="unsigned __int64" />
+ <Parameter Name="x_lo" Type="unsigned __int64" />
+ <Parameter Name="y_hi" Type="unsigned __int64" />
+ <Parameter Name="y_lo" Type="unsigned __int64" />
+ </Intrinsic>
+
+ <!-- NOTE: That tag ranges can wrap around, in which case `end` is less than `begin` and we
+ have to do a different check -->
+ <Intrinsic Name="in_range128" Expression="(lt_or_eq128(begin_hi, begin_lo, end_hi, end_lo)) ?
+ (lt_or_eq128(begin_hi, begin_lo, x_hi, x_lo) && lt_or_eq128(x_hi, x_lo, end_hi, end_lo)) :
+ (lt_or_eq128(begin_hi, begin_lo, x_hi, x_lo) || lt_or_eq128(x_hi, x_lo, end_hi, end_lo))">
+ <Parameter Name="x_hi" Type="unsigned __int64" />
+ <Parameter Name="x_lo" Type="unsigned __int64" />
+ <Parameter Name="begin_hi" Type="unsigned __int64" />
+ <Parameter Name="begin_lo" Type="unsigned __int64" />
+ <Parameter Name="end_hi" Type="unsigned __int64" />
+ <Parameter Name="end_lo" Type="unsigned __int64" />
+ </Intrinsic>
+
+ <DisplayString Condition="tag == variant0.DISCR_EXACT" Optional="true">{variant0.NAME,en}</DisplayString>
+ <DisplayString Condition="tag == variant1.DISCR_EXACT" Optional="true">{variant1.NAME,en}</DisplayString>
+ <DisplayString Condition="tag == variant2.DISCR_EXACT" Optional="true">{variant2.NAME,en}</DisplayString>
+ <DisplayString Condition="tag == variant3.DISCR_EXACT" Optional="true">{variant3.NAME,en}</DisplayString>
+ <DisplayString Condition="tag == variant4.DISCR_EXACT" Optional="true">{variant4.NAME,en}</DisplayString>
+ <DisplayString Condition="tag == variant5.DISCR_EXACT" Optional="true">{variant5.NAME,en}</DisplayString>
+ <DisplayString Condition="tag == variant6.DISCR_EXACT" Optional="true">{variant6.NAME,en}</DisplayString>
+ <DisplayString Condition="tag == variant7.DISCR_EXACT" Optional="true">{variant7.NAME,en}</DisplayString>
+ <DisplayString Condition="tag == variant8.DISCR_EXACT" Optional="true">{variant8.NAME,en}</DisplayString>
+ <DisplayString Condition="tag == variant9.DISCR_EXACT" Optional="true">{variant9.NAME,en}</DisplayString>
+ <DisplayString Condition="tag == variant10.DISCR_EXACT" Optional="true">{variant10.NAME,en}</DisplayString>
+ <DisplayString Condition="tag == variant11.DISCR_EXACT" Optional="true">{variant11.NAME,en}</DisplayString>
+ <DisplayString Condition="tag == variant12.DISCR_EXACT" Optional="true">{variant12.NAME,en}</DisplayString>
+ <DisplayString Condition="tag == variant13.DISCR_EXACT" Optional="true">{variant13.NAME,en}</DisplayString>
+ <DisplayString Condition="tag == variant14.DISCR_EXACT" Optional="true">{variant14.NAME,en}</DisplayString>
+ <DisplayString Condition="tag == variant15.DISCR_EXACT" Optional="true">{variant15.NAME,en}</DisplayString>
+
+ <DisplayString Condition="in_range(tag, variant0.DISCR_BEGIN, variant0.DISCR_END)" Optional="true">{variant0.NAME,en}</DisplayString>
+ <DisplayString Condition="in_range(tag, variant1.DISCR_BEGIN, variant1.DISCR_END)" Optional="true">{variant1.NAME,en}</DisplayString>
+ <DisplayString Condition="in_range(tag, variant2.DISCR_BEGIN, variant2.DISCR_END)" Optional="true">{variant2.NAME,en}</DisplayString>
+ <DisplayString Condition="in_range(tag, variant3.DISCR_BEGIN, variant3.DISCR_END)" Optional="true">{variant3.NAME,en}</DisplayString>
+ <DisplayString Condition="in_range(tag, variant4.DISCR_BEGIN, variant4.DISCR_END)" Optional="true">{variant4.NAME,en}</DisplayString>
+ <DisplayString Condition="in_range(tag, variant5.DISCR_BEGIN, variant5.DISCR_END)" Optional="true">{variant5.NAME,en}</DisplayString>
+ <DisplayString Condition="in_range(tag, variant6.DISCR_BEGIN, variant6.DISCR_END)" Optional="true">{variant6.NAME,en}</DisplayString>
+ <DisplayString Condition="in_range(tag, variant7.DISCR_BEGIN, variant7.DISCR_END)" Optional="true">{variant7.NAME,en}</DisplayString>
+ <DisplayString Condition="in_range(tag, variant8.DISCR_BEGIN, variant8.DISCR_END)" Optional="true">{variant8.NAME,en}</DisplayString>
+ <DisplayString Condition="in_range(tag, variant9.DISCR_BEGIN, variant9.DISCR_END)" Optional="true">{variant9.NAME,en}</DisplayString>
+ <DisplayString Condition="in_range(tag, variant10.DISCR_BEGIN, variant10.DISCR_END)" Optional="true">{variant10.NAME,en}</DisplayString>
+ <DisplayString Condition="in_range(tag, variant11.DISCR_BEGIN, variant11.DISCR_END)" Optional="true">{variant11.NAME,en}</DisplayString>
+ <DisplayString Condition="in_range(tag, variant12.DISCR_BEGIN, variant12.DISCR_END)" Optional="true">{variant12.NAME,en}</DisplayString>
+ <DisplayString Condition="in_range(tag, variant13.DISCR_BEGIN, variant13.DISCR_END)" Optional="true">{variant13.NAME,en}</DisplayString>
+ <DisplayString Condition="in_range(tag, variant14.DISCR_BEGIN, variant14.DISCR_END)" Optional="true">{variant14.NAME,en}</DisplayString>
+ <DisplayString Condition="in_range(tag, variant15.DISCR_BEGIN, variant15.DISCR_END)" Optional="true">{variant15.NAME,en}</DisplayString>
+
+ <DisplayString Condition="eq128(tag128_hi, tag128_lo, variant0.DISCR128_EXACT_HI, variant0.DISCR128_EXACT_LO)" Optional="true">{variant0.NAME,en}</DisplayString>
+ <DisplayString Condition="eq128(tag128_hi, tag128_lo, variant1.DISCR128_EXACT_HI, variant1.DISCR128_EXACT_LO)" Optional="true">{variant1.NAME,en}</DisplayString>
+ <DisplayString Condition="eq128(tag128_hi, tag128_lo, variant2.DISCR128_EXACT_HI, variant2.DISCR128_EXACT_LO)" Optional="true">{variant2.NAME,en}</DisplayString>
+ <DisplayString Condition="eq128(tag128_hi, tag128_lo, variant3.DISCR128_EXACT_HI, variant3.DISCR128_EXACT_LO)" Optional="true">{variant3.NAME,en}</DisplayString>
+ <DisplayString Condition="eq128(tag128_hi, tag128_lo, variant4.DISCR128_EXACT_HI, variant4.DISCR128_EXACT_LO)" Optional="true">{variant4.NAME,en}</DisplayString>
+ <DisplayString Condition="eq128(tag128_hi, tag128_lo, variant5.DISCR128_EXACT_HI, variant5.DISCR128_EXACT_LO)" Optional="true">{variant5.NAME,en}</DisplayString>
+ <DisplayString Condition="eq128(tag128_hi, tag128_lo, variant6.DISCR128_EXACT_HI, variant6.DISCR128_EXACT_LO)" Optional="true">{variant6.NAME,en}</DisplayString>
+ <DisplayString Condition="eq128(tag128_hi, tag128_lo, variant7.DISCR128_EXACT_HI, variant7.DISCR128_EXACT_LO)" Optional="true">{variant7.NAME,en}</DisplayString>
+ <DisplayString Condition="eq128(tag128_hi, tag128_lo, variant8.DISCR128_EXACT_HI, variant8.DISCR128_EXACT_LO)" Optional="true">{variant8.NAME,en}</DisplayString>
+ <DisplayString Condition="eq128(tag128_hi, tag128_lo, variant9.DISCR128_EXACT_HI, variant9.DISCR128_EXACT_LO)" Optional="true">{variant9.NAME,en}</DisplayString>
+ <DisplayString Condition="eq128(tag128_hi, tag128_lo, variant10.DISCR128_EXACT_HI, variant10.DISCR128_EXACT_LO)" Optional="true">{variant10.NAME,en}</DisplayString>
+ <DisplayString Condition="eq128(tag128_hi, tag128_lo, variant11.DISCR128_EXACT_HI, variant11.DISCR128_EXACT_LO)" Optional="true">{variant11.NAME,en}</DisplayString>
+ <DisplayString Condition="eq128(tag128_hi, tag128_lo, variant12.DISCR128_EXACT_HI, variant12.DISCR128_EXACT_LO)" Optional="true">{variant12.NAME,en}</DisplayString>
+ <DisplayString Condition="eq128(tag128_hi, tag128_lo, variant13.DISCR128_EXACT_HI, variant13.DISCR128_EXACT_LO)" Optional="true">{variant13.NAME,en}</DisplayString>
+ <DisplayString Condition="eq128(tag128_hi, tag128_lo, variant14.DISCR128_EXACT_HI, variant14.DISCR128_EXACT_LO)" Optional="true">{variant14.NAME,en}</DisplayString>
+ <DisplayString Condition="eq128(tag128_hi, tag128_lo, variant15.DISCR128_EXACT_HI, variant15.DISCR128_EXACT_LO)" Optional="true">{variant15.NAME,en}</DisplayString>
+
+ <DisplayString Condition="in_range128(tag128_hi, tag128_lo, variant0.DISCR128_BEGIN_HI, variant0.DISCR128_BEGIN_LO, variant0.DISCR128_END_HI, variant0.DISCR128_END_LO)" Optional="true">{variant0.NAME,en}</DisplayString>
+ <DisplayString Condition="in_range128(tag128_hi, tag128_lo, variant1.DISCR128_BEGIN_HI, variant1.DISCR128_BEGIN_LO, variant1.DISCR128_END_HI, variant1.DISCR128_END_LO)" Optional="true">{variant1.NAME,en}</DisplayString>
+ <DisplayString Condition="in_range128(tag128_hi, tag128_lo, variant2.DISCR128_BEGIN_HI, variant2.DISCR128_BEGIN_LO, variant2.DISCR128_END_HI, variant2.DISCR128_END_LO)" Optional="true">{variant2.NAME,en}</DisplayString>
+ <DisplayString Condition="in_range128(tag128_hi, tag128_lo, variant3.DISCR128_BEGIN_HI, variant3.DISCR128_BEGIN_LO, variant3.DISCR128_END_HI, variant3.DISCR128_END_LO)" Optional="true">{variant3.NAME,en}</DisplayString>
+ <DisplayString Condition="in_range128(tag128_hi, tag128_lo, variant4.DISCR128_BEGIN_HI, variant4.DISCR128_BEGIN_LO, variant4.DISCR128_END_HI, variant4.DISCR128_END_LO)" Optional="true">{variant4.NAME,en}</DisplayString>
+ <DisplayString Condition="in_range128(tag128_hi, tag128_lo, variant5.DISCR128_BEGIN_HI, variant5.DISCR128_BEGIN_LO, variant5.DISCR128_END_HI, variant5.DISCR128_END_LO)" Optional="true">{variant5.NAME,en}</DisplayString>
+ <DisplayString Condition="in_range128(tag128_hi, tag128_lo, variant6.DISCR128_BEGIN_HI, variant6.DISCR128_BEGIN_LO, variant6.DISCR128_END_HI, variant6.DISCR128_END_LO)" Optional="true">{variant6.NAME,en}</DisplayString>
+ <DisplayString Condition="in_range128(tag128_hi, tag128_lo, variant7.DISCR128_BEGIN_HI, variant7.DISCR128_BEGIN_LO, variant7.DISCR128_END_HI, variant7.DISCR128_END_LO)" Optional="true">{variant7.NAME,en}</DisplayString>
+ <DisplayString Condition="in_range128(tag128_hi, tag128_lo, variant8.DISCR128_BEGIN_HI, variant8.DISCR128_BEGIN_LO, variant8.DISCR128_END_HI, variant8.DISCR128_END_LO)" Optional="true">{variant8.NAME,en}</DisplayString>
+ <DisplayString Condition="in_range128(tag128_hi, tag128_lo, variant9.DISCR128_BEGIN_HI, variant9.DISCR128_BEGIN_LO, variant9.DISCR128_END_HI, variant9.DISCR128_END_LO)" Optional="true">{variant9.NAME,en}</DisplayString>
+ <DisplayString Condition="in_range128(tag128_hi, tag128_lo, variant10.DISCR128_BEGIN_HI, variant10.DISCR128_BEGIN_LO, variant10.DISCR128_END_HI, variant10.DISCR128_END_LO)" Optional="true">{variant10.NAME,en}</DisplayString>
+ <DisplayString Condition="in_range128(tag128_hi, tag128_lo, variant11.DISCR128_BEGIN_HI, variant11.DISCR128_BEGIN_LO, variant11.DISCR128_END_HI, variant11.DISCR128_END_LO)" Optional="true">{variant11.NAME,en}</DisplayString>
+ <DisplayString Condition="in_range128(tag128_hi, tag128_lo, variant12.DISCR128_BEGIN_HI, variant12.DISCR128_BEGIN_LO, variant12.DISCR128_END_HI, variant12.DISCR128_END_LO)" Optional="true">{variant12.NAME,en}</DisplayString>
+ <DisplayString Condition="in_range128(tag128_hi, tag128_lo, variant13.DISCR128_BEGIN_HI, variant13.DISCR128_BEGIN_LO, variant13.DISCR128_END_HI, variant13.DISCR128_END_LO)" Optional="true">{variant13.NAME,en}</DisplayString>
+ <DisplayString Condition="in_range128(tag128_hi, tag128_lo, variant14.DISCR128_BEGIN_HI, variant14.DISCR128_BEGIN_LO, variant14.DISCR128_END_HI, variant14.DISCR128_END_LO)" Optional="true">{variant14.NAME,en}</DisplayString>
+ <DisplayString Condition="in_range128(tag128_hi, tag128_lo, variant15.DISCR128_BEGIN_HI, variant15.DISCR128_BEGIN_LO, variant15.DISCR128_END_HI, variant15.DISCR128_END_LO)" Optional="true">{variant15.NAME,en}</DisplayString>
+
+ <Expand HideRawView="true">
+ <ExpandedItem Condition="tag == variant0.DISCR_EXACT" Optional="true">variant0.value</ExpandedItem>
+ <ExpandedItem Condition="tag == variant1.DISCR_EXACT" Optional="true">variant1.value</ExpandedItem>
+ <ExpandedItem Condition="tag == variant2.DISCR_EXACT" Optional="true">variant2.value</ExpandedItem>
+ <ExpandedItem Condition="tag == variant3.DISCR_EXACT" Optional="true">variant3.value</ExpandedItem>
+ <ExpandedItem Condition="tag == variant4.DISCR_EXACT" Optional="true">variant4.value</ExpandedItem>
+ <ExpandedItem Condition="tag == variant5.DISCR_EXACT" Optional="true">variant5.value</ExpandedItem>
+ <ExpandedItem Condition="tag == variant6.DISCR_EXACT" Optional="true">variant6.value</ExpandedItem>
+ <ExpandedItem Condition="tag == variant7.DISCR_EXACT" Optional="true">variant7.value</ExpandedItem>
+ <ExpandedItem Condition="tag == variant8.DISCR_EXACT" Optional="true">variant8.value</ExpandedItem>
+ <ExpandedItem Condition="tag == variant9.DISCR_EXACT" Optional="true">variant9.value</ExpandedItem>
+ <ExpandedItem Condition="tag == variant10.DISCR_EXACT" Optional="true">variant10.value</ExpandedItem>
+ <ExpandedItem Condition="tag == variant11.DISCR_EXACT" Optional="true">variant11.value</ExpandedItem>
+ <ExpandedItem Condition="tag == variant12.DISCR_EXACT" Optional="true">variant12.value</ExpandedItem>
+ <ExpandedItem Condition="tag == variant13.DISCR_EXACT" Optional="true">variant13.value</ExpandedItem>
+ <ExpandedItem Condition="tag == variant14.DISCR_EXACT" Optional="true">variant14.value</ExpandedItem>
+ <ExpandedItem Condition="tag == variant15.DISCR_EXACT" Optional="true">variant15.value</ExpandedItem>
+
+ <ExpandedItem Condition="in_range(tag, variant0.DISCR_BEGIN, variant0.DISCR_END)" Optional="true">variant0.value</ExpandedItem>
+ <ExpandedItem Condition="in_range(tag, variant1.DISCR_BEGIN, variant1.DISCR_END)" Optional="true">variant1.value</ExpandedItem>
+ <ExpandedItem Condition="in_range(tag, variant2.DISCR_BEGIN, variant2.DISCR_END)" Optional="true">variant2.value</ExpandedItem>
+ <ExpandedItem Condition="in_range(tag, variant3.DISCR_BEGIN, variant3.DISCR_END)" Optional="true">variant3.value</ExpandedItem>
+ <ExpandedItem Condition="in_range(tag, variant4.DISCR_BEGIN, variant4.DISCR_END)" Optional="true">variant4.value</ExpandedItem>
+ <ExpandedItem Condition="in_range(tag, variant5.DISCR_BEGIN, variant5.DISCR_END)" Optional="true">variant5.value</ExpandedItem>
+ <ExpandedItem Condition="in_range(tag, variant6.DISCR_BEGIN, variant6.DISCR_END)" Optional="true">variant6.value</ExpandedItem>
+ <ExpandedItem Condition="in_range(tag, variant7.DISCR_BEGIN, variant7.DISCR_END)" Optional="true">variant7.value</ExpandedItem>
+ <ExpandedItem Condition="in_range(tag, variant8.DISCR_BEGIN, variant8.DISCR_END)" Optional="true">variant8.value</ExpandedItem>
+ <ExpandedItem Condition="in_range(tag, variant9.DISCR_BEGIN, variant9.DISCR_END)" Optional="true">variant9.value</ExpandedItem>
+ <ExpandedItem Condition="in_range(tag, variant10.DISCR_BEGIN, variant10.DISCR_END)" Optional="true">variant10.value</ExpandedItem>
+ <ExpandedItem Condition="in_range(tag, variant11.DISCR_BEGIN, variant11.DISCR_END)" Optional="true">variant11.value</ExpandedItem>
+ <ExpandedItem Condition="in_range(tag, variant12.DISCR_BEGIN, variant12.DISCR_END)" Optional="true">variant12.value</ExpandedItem>
+ <ExpandedItem Condition="in_range(tag, variant13.DISCR_BEGIN, variant13.DISCR_END)" Optional="true">variant13.value</ExpandedItem>
+ <ExpandedItem Condition="in_range(tag, variant14.DISCR_BEGIN, variant14.DISCR_END)" Optional="true">variant14.value</ExpandedItem>
+ <ExpandedItem Condition="in_range(tag, variant15.DISCR_BEGIN, variant15.DISCR_END)" Optional="true">variant15.value</ExpandedItem>
+
+ <ExpandedItem Condition="eq128(tag128_hi, tag128_lo, variant0.DISCR128_EXACT_HI, variant0.DISCR128_EXACT_LO)" Optional="true">variant0.value</ExpandedItem>
+ <ExpandedItem Condition="eq128(tag128_hi, tag128_lo, variant1.DISCR128_EXACT_HI, variant1.DISCR128_EXACT_LO)" Optional="true">variant1.value</ExpandedItem>
+ <ExpandedItem Condition="eq128(tag128_hi, tag128_lo, variant2.DISCR128_EXACT_HI, variant2.DISCR128_EXACT_LO)" Optional="true">variant2.value</ExpandedItem>
+ <ExpandedItem Condition="eq128(tag128_hi, tag128_lo, variant3.DISCR128_EXACT_HI, variant3.DISCR128_EXACT_LO)" Optional="true">variant3.value</ExpandedItem>
+ <ExpandedItem Condition="eq128(tag128_hi, tag128_lo, variant4.DISCR128_EXACT_HI, variant4.DISCR128_EXACT_LO)" Optional="true">variant4.value</ExpandedItem>
+ <ExpandedItem Condition="eq128(tag128_hi, tag128_lo, variant5.DISCR128_EXACT_HI, variant5.DISCR128_EXACT_LO)" Optional="true">variant5.value</ExpandedItem>
+ <ExpandedItem Condition="eq128(tag128_hi, tag128_lo, variant6.DISCR128_EXACT_HI, variant6.DISCR128_EXACT_LO)" Optional="true">variant6.value</ExpandedItem>
+ <ExpandedItem Condition="eq128(tag128_hi, tag128_lo, variant7.DISCR128_EXACT_HI, variant7.DISCR128_EXACT_LO)" Optional="true">variant7.value</ExpandedItem>
+ <ExpandedItem Condition="eq128(tag128_hi, tag128_lo, variant8.DISCR128_EXACT_HI, variant8.DISCR128_EXACT_LO)" Optional="true">variant8.value</ExpandedItem>
+ <ExpandedItem Condition="eq128(tag128_hi, tag128_lo, variant9.DISCR128_EXACT_HI, variant9.DISCR128_EXACT_LO)" Optional="true">variant9.value</ExpandedItem>
+ <ExpandedItem Condition="eq128(tag128_hi, tag128_lo, variant10.DISCR128_EXACT_HI, variant10.DISCR128_EXACT_LO)" Optional="true">variant10.value</ExpandedItem>
+ <ExpandedItem Condition="eq128(tag128_hi, tag128_lo, variant11.DISCR128_EXACT_HI, variant11.DISCR128_EXACT_LO)" Optional="true">variant11.value</ExpandedItem>
+ <ExpandedItem Condition="eq128(tag128_hi, tag128_lo, variant12.DISCR128_EXACT_HI, variant12.DISCR128_EXACT_LO)" Optional="true">variant12.value</ExpandedItem>
+ <ExpandedItem Condition="eq128(tag128_hi, tag128_lo, variant13.DISCR128_EXACT_HI, variant13.DISCR128_EXACT_LO)" Optional="true">variant13.value</ExpandedItem>
+ <ExpandedItem Condition="eq128(tag128_hi, tag128_lo, variant14.DISCR128_EXACT_HI, variant14.DISCR128_EXACT_LO)" Optional="true">variant14.value</ExpandedItem>
+ <ExpandedItem Condition="eq128(tag128_hi, tag128_lo, variant15.DISCR128_EXACT_HI, variant15.DISCR128_EXACT_LO)" Optional="true">variant15.value</ExpandedItem>
+
+ <ExpandedItem Condition="in_range128(tag128_hi, tag128_lo, variant0.DISCR128_BEGIN_HI, variant0.DISCR128_BEGIN_LO, variant0.DISCR128_END_HI, variant0.DISCR128_END_LO)" Optional="true">variant0.value</ExpandedItem>
+ <ExpandedItem Condition="in_range128(tag128_hi, tag128_lo, variant1.DISCR128_BEGIN_HI, variant1.DISCR128_BEGIN_LO, variant1.DISCR128_END_HI, variant1.DISCR128_END_LO)" Optional="true">variant1.value</ExpandedItem>
+ <ExpandedItem Condition="in_range128(tag128_hi, tag128_lo, variant2.DISCR128_BEGIN_HI, variant2.DISCR128_BEGIN_LO, variant2.DISCR128_END_HI, variant2.DISCR128_END_LO)" Optional="true">variant2.value</ExpandedItem>
+ <ExpandedItem Condition="in_range128(tag128_hi, tag128_lo, variant3.DISCR128_BEGIN_HI, variant3.DISCR128_BEGIN_LO, variant3.DISCR128_END_HI, variant3.DISCR128_END_LO)" Optional="true">variant3.value</ExpandedItem>
+ <ExpandedItem Condition="in_range128(tag128_hi, tag128_lo, variant4.DISCR128_BEGIN_HI, variant4.DISCR128_BEGIN_LO, variant4.DISCR128_END_HI, variant4.DISCR128_END_LO)" Optional="true">variant4.value</ExpandedItem>
+ <ExpandedItem Condition="in_range128(tag128_hi, tag128_lo, variant5.DISCR128_BEGIN_HI, variant5.DISCR128_BEGIN_LO, variant5.DISCR128_END_HI, variant5.DISCR128_END_LO)" Optional="true">variant5.value</ExpandedItem>
+ <ExpandedItem Condition="in_range128(tag128_hi, tag128_lo, variant6.DISCR128_BEGIN_HI, variant6.DISCR128_BEGIN_LO, variant6.DISCR128_END_HI, variant6.DISCR128_END_LO)" Optional="true">variant6.value</ExpandedItem>
+ <ExpandedItem Condition="in_range128(tag128_hi, tag128_lo, variant7.DISCR128_BEGIN_HI, variant7.DISCR128_BEGIN_LO, variant7.DISCR128_END_HI, variant7.DISCR128_END_LO)" Optional="true">variant7.value</ExpandedItem>
+ <ExpandedItem Condition="in_range128(tag128_hi, tag128_lo, variant8.DISCR128_BEGIN_HI, variant8.DISCR128_BEGIN_LO, variant8.DISCR128_END_HI, variant8.DISCR128_END_LO)" Optional="true">variant8.value</ExpandedItem>
+ <ExpandedItem Condition="in_range128(tag128_hi, tag128_lo, variant9.DISCR128_BEGIN_HI, variant9.DISCR128_BEGIN_LO, variant9.DISCR128_END_HI, variant9.DISCR128_END_LO)" Optional="true">variant9.value</ExpandedItem>
+ <ExpandedItem Condition="in_range128(tag128_hi, tag128_lo, variant10.DISCR128_BEGIN_HI, variant10.DISCR128_BEGIN_LO, variant10.DISCR128_END_HI, variant10.DISCR128_END_LO)" Optional="true">variant10.value</ExpandedItem>
+ <ExpandedItem Condition="in_range128(tag128_hi, tag128_lo, variant11.DISCR128_BEGIN_HI, variant11.DISCR128_BEGIN_LO, variant11.DISCR128_END_HI, variant11.DISCR128_END_LO)" Optional="true">variant11.value</ExpandedItem>
+ <ExpandedItem Condition="in_range128(tag128_hi, tag128_lo, variant12.DISCR128_BEGIN_HI, variant12.DISCR128_BEGIN_LO, variant12.DISCR128_END_HI, variant12.DISCR128_END_LO)" Optional="true">variant12.value</ExpandedItem>
+ <ExpandedItem Condition="in_range128(tag128_hi, tag128_lo, variant13.DISCR128_BEGIN_HI, variant13.DISCR128_BEGIN_LO, variant13.DISCR128_END_HI, variant13.DISCR128_END_LO)" Optional="true">variant13.value</ExpandedItem>
+ <ExpandedItem Condition="in_range128(tag128_hi, tag128_lo, variant14.DISCR128_BEGIN_HI, variant14.DISCR128_BEGIN_LO, variant14.DISCR128_END_HI, variant14.DISCR128_END_LO)" Optional="true">variant14.value</ExpandedItem>
+ <ExpandedItem Condition="in_range128(tag128_hi, tag128_lo, variant15.DISCR128_BEGIN_HI, variant15.DISCR128_BEGIN_LO, variant15.DISCR128_END_HI, variant15.DISCR128_END_LO)" Optional="true">variant15.value</ExpandedItem>
</Expand>
</Type>
</AutoVisualizer>
</ArrayItems>
</Expand>
</Type>
-
- <Type Name="alloc::borrow::Cow<*>">
- <DisplayString Condition="RUST$ENUM$DISR == 0x0">Borrowed({__0})</DisplayString>
- <DisplayString Condition="RUST$ENUM$DISR == 0x1">Owned({__0})</DisplayString>
- <Expand>
- <Item Name="[value]" ExcludeView="simple">__0</Item>
- </Expand>
- </Type>
</AutoVisualizer>
pub(crate) use self::types::*;
pub(crate) use self::utils::{get_auto_trait_and_blanket_impls, krate, register_res};
-pub(crate) trait Clean<'tcx, T> {
- fn clean(&self, cx: &mut DocContext<'tcx>) -> T;
-}
-
pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext<'tcx>) -> Item {
let mut items: Vec<Item> = vec![];
let mut inserted = FxHashSet::default();
let trait_def = cx.tcx.associated_item(p.res.def_id()).container_id(cx.tcx);
let trait_ = self::Path {
res: Res::Def(DefKind::Trait, trait_def),
- segments: trait_segments.iter().map(|x| x.clean(cx)).collect(),
+ segments: trait_segments.iter().map(|x| clean_path_segment(x, cx)).collect(),
};
register_res(cx, trait_.res);
let self_def_id = DefId::local(qself.hir_id.owner.local_def_index);
let self_type = clean_ty(qself, cx);
let should_show_cast = compute_should_show_cast(Some(self_def_id), &trait_, &self_type);
Type::QPath {
- assoc: Box::new(p.segments.last().expect("segments were empty").clean(cx)),
+ assoc: Box::new(clean_path_segment(
+ p.segments.last().expect("segments were empty"),
+ cx,
+ )),
should_show_cast,
self_type: Box::new(self_type),
trait_,
let self_type = clean_ty(qself, cx);
let should_show_cast = compute_should_show_cast(self_def_id, &trait_, &self_type);
Type::QPath {
- assoc: Box::new(segment.clean(cx)),
+ assoc: Box::new(clean_path_segment(segment, cx)),
should_show_cast,
self_type: Box::new(self_type),
trait_,
if !lifetime.is_elided() { Some(clean_lifetime(*lifetime, cx)) } else { None };
DynTrait(bounds, lifetime)
}
- TyKind::BareFn(barefn) => BareFunction(Box::new(barefn.clean(cx))),
+ TyKind::BareFn(barefn) => BareFunction(Box::new(clean_bare_fn_ty(barefn, cx))),
// Rustdoc handles `TyKind::Err`s by turning them into `Type::Infer`s.
TyKind::Infer | TyKind::Err => Infer,
TyKind::Typeof(..) => panic!("unimplemented type {:?}", ty.kind),
}
fn clean_path<'tcx>(path: &hir::Path<'tcx>, cx: &mut DocContext<'tcx>) -> Path {
- Path { res: path.res, segments: path.segments.iter().map(|x| x.clean(cx)).collect() }
+ Path {
+ res: path.res,
+ segments: path.segments.iter().map(|x| clean_path_segment(x, cx)).collect(),
+ }
}
fn clean_generic_args<'tcx>(
}
}
-impl<'tcx> Clean<'tcx, PathSegment> for hir::PathSegment<'tcx> {
- fn clean(&self, cx: &mut DocContext<'tcx>) -> PathSegment {
- PathSegment { name: self.ident.name, args: clean_generic_args(self.args(), cx) }
- }
+fn clean_path_segment<'tcx>(
+ path: &hir::PathSegment<'tcx>,
+ cx: &mut DocContext<'tcx>,
+) -> PathSegment {
+ PathSegment { name: path.ident.name, args: clean_generic_args(path.args(), cx) }
}
-impl<'tcx> Clean<'tcx, BareFunctionDecl> for hir::BareFnTy<'tcx> {
- fn clean(&self, cx: &mut DocContext<'tcx>) -> BareFunctionDecl {
- let (generic_params, decl) = enter_impl_trait(cx, |cx| {
- // NOTE: generics must be cleaned before args
- let generic_params = self
- .generic_params
- .iter()
- .filter(|p| !is_elided_lifetime(p))
- .map(|x| clean_generic_param(cx, None, x))
- .collect();
- let args = clean_args_from_types_and_names(cx, self.decl.inputs, self.param_names);
- let decl = clean_fn_decl_with_args(cx, self.decl, args);
- (generic_params, decl)
- });
- BareFunctionDecl { unsafety: self.unsafety, abi: self.abi, decl, generic_params }
- }
+fn clean_bare_fn_ty<'tcx>(
+ bare_fn: &hir::BareFnTy<'tcx>,
+ cx: &mut DocContext<'tcx>,
+) -> BareFunctionDecl {
+ let (generic_params, decl) = enter_impl_trait(cx, |cx| {
+ // NOTE: generics must be cleaned before args
+ let generic_params = bare_fn
+ .generic_params
+ .iter()
+ .filter(|p| !is_elided_lifetime(p))
+ .map(|x| clean_generic_param(cx, None, x))
+ .collect();
+ let args = clean_args_from_types_and_names(cx, bare_fn.decl.inputs, bare_fn.param_names);
+ let decl = clean_fn_decl_with_args(cx, bare_fn.decl, args);
+ (generic_params, decl)
+ });
+ BareFunctionDecl { unsafety: bare_fn.unsafety, abi: bare_fn.abi, decl, generic_params }
}
fn clean_maybe_renamed_item<'tcx>(
}))
}
ItemKind::Enum(ref def, generics) => EnumItem(Enum {
- variants: def.variants.iter().map(|v| v.clean(cx)).collect(),
+ variants: def.variants.iter().map(|v| clean_variant(v, cx)).collect(),
generics: clean_generics(generics, cx),
}),
ItemKind::TraitAlias(generics, bounds) => TraitAliasItem(TraitAlias {
})
}
-impl<'tcx> Clean<'tcx, Item> for hir::Variant<'tcx> {
- fn clean(&self, cx: &mut DocContext<'tcx>) -> Item {
- let kind = VariantItem(clean_variant_data(&self.data, cx));
- let what_rustc_thinks =
- Item::from_hir_id_and_parts(self.id, Some(self.ident.name), kind, cx);
- // don't show `pub` for variants, which are always public
- Item { visibility: Inherited, ..what_rustc_thinks }
- }
+fn clean_variant<'tcx>(variant: &hir::Variant<'tcx>, cx: &mut DocContext<'tcx>) -> Item {
+ let kind = VariantItem(clean_variant_data(&variant.data, cx));
+ let what_rustc_thinks =
+ Item::from_hir_id_and_parts(variant.id, Some(variant.ident.name), kind, cx);
+ // don't show `pub` for variants, which are always public
+ Item { visibility: Inherited, ..what_rustc_thinks }
}
fn clean_impl<'tcx>(
.unwrap_or(false)
}
- pub(crate) fn span(&self, tcx: TyCtxt<'_>) -> Span {
+ pub(crate) fn span(&self, tcx: TyCtxt<'_>) -> Option<Span> {
let kind = match &*self.kind {
ItemKind::StrippedItem(k) => k,
_ => &*self.kind,
};
match kind {
- ItemKind::ModuleItem(Module { span, .. }) => *span,
- ItemKind::ImplItem(box Impl { kind: ImplKind::Auto, .. }) => Span::dummy(),
+ ItemKind::ModuleItem(Module { span, .. }) => Some(*span),
+ ItemKind::ImplItem(box Impl { kind: ImplKind::Auto, .. }) => None,
ItemKind::ImplItem(box Impl { kind: ImplKind::Blanket(_), .. }) => {
if let ItemId::Blanket { impl_id, .. } = self.item_id {
- rustc_span(impl_id, tcx)
+ Some(rustc_span(impl_id, tcx))
} else {
panic!("blanket impl item has non-blanket ID")
}
}
- _ => {
- self.item_id.as_def_id().map(|did| rustc_span(did, tcx)).unwrap_or_else(Span::dummy)
- }
+ _ => self.item_id.as_def_id().map(|did| rustc_span(did, tcx)),
}
}
pub(crate) fn attr_span(&self, tcx: TyCtxt<'_>) -> rustc_span::Span {
- crate::passes::span_of_attrs(&self.attrs).unwrap_or_else(|| self.span(tcx).inner())
+ crate::passes::span_of_attrs(&self.attrs)
+ .unwrap_or_else(|| self.span(tcx).map_or(rustc_span::DUMMY_SP, |span| span.inner()))
}
/// Finds the `doc` attribute as a NameValue and returns the corresponding
self.0
}
- pub(crate) fn dummy() -> Self {
- Self(rustc_span::DUMMY_SP)
- }
-
- pub(crate) fn is_dummy(&self) -> bool {
- self.0.is_dummy()
- }
-
pub(crate) fn filename(&self, sess: &Session) -> FileName {
sess.source_map().span_to_filename(self.0)
}
write!(out, "<code>");
}
+/// Write all the pending elements sharing a same (or at mergeable) `Class`.
+///
+/// If there is a "parent" (if a `EnterSpan` event was encountered) and the parent can be merged
+/// with the elements' class, then we simply write the elements since the `ExitSpan` event will
+/// close the tag.
+///
+/// Otherwise, if there is only one pending element, we let the `string` function handle both
+/// opening and closing the tag, otherwise we do it into this function.
+fn write_pending_elems(
+ out: &mut Buffer,
+ href_context: &Option<HrefContext<'_, '_, '_>>,
+ pending_elems: &mut Vec<(&str, Option<Class>)>,
+ current_class: &mut Option<Class>,
+ closing_tags: &[(&str, Class)],
+) {
+ if pending_elems.is_empty() {
+ return;
+ }
+ let mut done = false;
+ if let Some((_, parent_class)) = closing_tags.last() {
+ if can_merge(*current_class, Some(*parent_class), "") {
+ for (text, class) in pending_elems.iter() {
+ string(out, Escape(text), *class, &href_context, false);
+ }
+ done = true;
+ }
+ }
+ if !done {
+ // We only want to "open" the tag ourselves if we have more than one pending and if the current
+ // parent tag is not the same as our pending content.
+ let open_tag_ourselves = pending_elems.len() > 1;
+ let close_tag = if open_tag_ourselves {
+ enter_span(out, current_class.unwrap(), &href_context)
+ } else {
+ ""
+ };
+ for (text, class) in pending_elems.iter() {
+ string(out, Escape(text), *class, &href_context, !open_tag_ourselves);
+ }
+ if open_tag_ourselves {
+ exit_span(out, close_tag);
+ }
+ }
+ pending_elems.clear();
+ *current_class = None;
+}
+
+/// Check if two `Class` can be merged together. In the following rules, "unclassified" means `None`
+/// basically (since it's `Option<Class>`). The following rules apply:
+///
+/// * If two `Class` have the same variant, then they can be merged.
+/// * If the other `Class` is unclassified and only contains white characters (backline,
+/// whitespace, etc), it can be merged.
+/// * `Class::Ident` is considered the same as unclassified (because it doesn't have an associated
+/// CSS class).
+fn can_merge(class1: Option<Class>, class2: Option<Class>, text: &str) -> bool {
+ match (class1, class2) {
+ (Some(c1), Some(c2)) => c1.is_equal_to(c2),
+ (Some(Class::Ident(_)), None) | (None, Some(Class::Ident(_))) => true,
+ (Some(_), None) | (None, Some(_)) => text.trim().is_empty(),
+ _ => false,
+ }
+}
+
/// Convert the given `src` source code into HTML by adding classes for highlighting.
///
/// This code is used to render code blocks (in the documentation) as well as the source code pages.
) {
// This replace allows to fix how the code source with DOS backline characters is displayed.
let src = src.replace("\r\n", "\n");
- let mut closing_tags: Vec<&'static str> = Vec::new();
+ // It contains the closing tag and the associated `Class`.
+ let mut closing_tags: Vec<(&'static str, Class)> = Vec::new();
+ // The following two variables are used to group HTML elements with same `class` attributes
+ // to reduce the DOM size.
+ let mut current_class: Option<Class> = None;
+ // We need to keep the `Class` for each element because it could contain a `Span` which is
+ // used to generate links.
+ let mut pending_elems: Vec<(&str, Option<Class>)> = Vec::new();
+
Classifier::new(
&src,
href_context.as_ref().map(|c| c.file_span).unwrap_or(DUMMY_SP),
)
.highlight(&mut |highlight| {
match highlight {
- Highlight::Token { text, class } => string(out, Escape(text), class, &href_context),
+ Highlight::Token { text, class } => {
+ // If the two `Class` are different, time to flush the current content and start
+ // a new one.
+ if !can_merge(current_class, class, text) {
+ write_pending_elems(
+ out,
+ &href_context,
+ &mut pending_elems,
+ &mut current_class,
+ &closing_tags,
+ );
+ current_class = class.map(Class::dummy);
+ } else if current_class.is_none() {
+ current_class = class.map(Class::dummy);
+ }
+ pending_elems.push((text, class));
+ }
Highlight::EnterSpan { class } => {
- closing_tags.push(enter_span(out, class, &href_context))
+ // We flush everything just in case...
+ write_pending_elems(
+ out,
+ &href_context,
+ &mut pending_elems,
+ &mut current_class,
+ &closing_tags,
+ );
+ closing_tags.push((enter_span(out, class, &href_context), class))
}
Highlight::ExitSpan => {
- exit_span(out, closing_tags.pop().expect("ExitSpan without EnterSpan"))
+ // We flush everything just in case...
+ write_pending_elems(
+ out,
+ &href_context,
+ &mut pending_elems,
+ &mut current_class,
+ &closing_tags,
+ );
+ exit_span(out, closing_tags.pop().expect("ExitSpan without EnterSpan").0)
}
};
});
+ write_pending_elems(out, &href_context, &mut pending_elems, &mut current_class, &closing_tags);
}
fn write_footer(out: &mut Buffer, playground_button: Option<&str>) {
DocComment,
Attribute,
KeyWord,
- // Keywords that do pointer/reference stuff.
+ /// Keywords that do pointer/reference stuff.
RefKeyWord,
Self_(Span),
- Op,
Macro(Span),
MacroNonTerminal,
String,
Number,
Bool,
+ /// `Ident` isn't rendered in the HTML but we still need it for the `Span` it contains.
Ident(Span),
Lifetime,
PreludeTy,
}
impl Class {
+ /// It is only looking at the variant, not the variant content.
+ ///
+ /// It is used mostly to group multiple similar HTML elements into one `<span>` instead of
+ /// multiple ones.
+ fn is_equal_to(self, other: Self) -> bool {
+ match (self, other) {
+ (Self::Self_(_), Self::Self_(_))
+ | (Self::Macro(_), Self::Macro(_))
+ | (Self::Ident(_), Self::Ident(_))
+ | (Self::Decoration(_), Self::Decoration(_)) => true,
+ (x, y) => x == y,
+ }
+ }
+
+ /// If `self` contains a `Span`, it'll be replaced with `DUMMY_SP` to prevent creating links
+ /// on "empty content" (because of the attributes merge).
+ fn dummy(self) -> Self {
+ match self {
+ Self::Self_(_) => Self::Self_(DUMMY_SP),
+ Self::Macro(_) => Self::Macro(DUMMY_SP),
+ Self::Ident(_) => Self::Ident(DUMMY_SP),
+ s => s,
+ }
+ }
+
/// Returns the css class expected by rustdoc for each `Class`.
fn as_html(self) -> &'static str {
match self {
Class::KeyWord => "kw",
Class::RefKeyWord => "kw-2",
Class::Self_(_) => "self",
- Class::Op => "op",
Class::Macro(_) => "macro",
Class::MacroNonTerminal => "macro-nonterminal",
Class::String => "string",
Class::Number => "number",
Class::Bool => "bool-val",
- Class::Ident(_) => "ident",
+ Class::Ident(_) => "",
Class::Lifetime => "lifetime",
Class::PreludeTy => "prelude-ty",
Class::PreludeVal => "prelude-val",
| Self::Attribute
| Self::KeyWord
| Self::RefKeyWord
- | Self::Op
| Self::MacroNonTerminal
| Self::String
| Self::Number
// or a reference or pointer type. Unless, of course, it looks like
// a logical and or a multiplication operator: `&&` or `* `.
TokenKind::Star => match self.tokens.peek() {
- Some((TokenKind::Whitespace, _)) => Class::Op,
+ Some((TokenKind::Whitespace, _)) => return no_highlight(sink),
Some((TokenKind::Ident, "mut")) => {
self.next();
sink(Highlight::Token { text: "*mut", class: Some(Class::RefKeyWord) });
TokenKind::And => match self.tokens.peek() {
Some((TokenKind::And, _)) => {
self.next();
- sink(Highlight::Token { text: "&&", class: Some(Class::Op) });
+ sink(Highlight::Token { text: "&&", class: None });
return;
}
Some((TokenKind::Eq, _)) => {
self.next();
- sink(Highlight::Token { text: "&=", class: Some(Class::Op) });
+ sink(Highlight::Token { text: "&=", class: None });
return;
}
- Some((TokenKind::Whitespace, _)) => Class::Op,
+ Some((TokenKind::Whitespace, _)) => return no_highlight(sink),
Some((TokenKind::Ident, "mut")) => {
self.next();
sink(Highlight::Token { text: "&mut", class: Some(Class::RefKeyWord) });
TokenKind::Eq => match lookahead {
Some(TokenKind::Eq) => {
self.next();
- sink(Highlight::Token { text: "==", class: Some(Class::Op) });
+ sink(Highlight::Token { text: "==", class: None });
return;
}
Some(TokenKind::Gt) => {
sink(Highlight::Token { text: "=>", class: None });
return;
}
- _ => Class::Op,
+ _ => return no_highlight(sink),
},
TokenKind::Minus if lookahead == Some(TokenKind::Gt) => {
self.next();
| TokenKind::Percent
| TokenKind::Bang
| TokenKind::Lt
- | TokenKind::Gt => Class::Op,
+ | TokenKind::Gt => return no_highlight(sink),
// Miscellaneous, no highlighting.
TokenKind::Dot
TokenKind::CloseBracket => {
if self.in_attribute {
self.in_attribute = false;
- sink(Highlight::Token { text: "]", class: None });
+ sink(Highlight::Token { text: "]", class: Some(Class::Attribute) });
sink(Highlight::ExitSpan);
return;
}
klass: Class,
href_context: &Option<HrefContext<'_, '_, '_>>,
) -> &'static str {
- string_without_closing_tag(out, "", Some(klass), href_context).expect(
+ string_without_closing_tag(out, "", Some(klass), href_context, true).expect(
"internal error: enter_span was called with Some(klass) but did not return a \
closing HTML tag",
)
text: T,
klass: Option<Class>,
href_context: &Option<HrefContext<'_, '_, '_>>,
+ open_tag: bool,
) {
- if let Some(closing_tag) = string_without_closing_tag(out, text, klass, href_context) {
+ if let Some(closing_tag) = string_without_closing_tag(out, text, klass, href_context, open_tag)
+ {
out.write_str(closing_tag);
}
}
text: T,
klass: Option<Class>,
href_context: &Option<HrefContext<'_, '_, '_>>,
+ open_tag: bool,
) -> Option<&'static str> {
let Some(klass) = klass
else {
};
let Some(def_span) = klass.get_span()
else {
+ if !open_tag {
+ write!(out, "{}", text);
+ return None;
+ }
write!(out, "<span class=\"{}\">{}", klass.as_html(), text);
return Some("</span>");
};
path
});
}
+
if let Some(href_context) = href_context {
if let Some(href) =
href_context.context.shared.span_correspondance_map.get(&def_span).and_then(|href| {
}
})
{
- write!(out, "<a class=\"{}\" href=\"{}\">{}", klass.as_html(), href, text_s);
+ if !open_tag {
+ // We're already inside an element which has the same klass, no need to give it
+ // again.
+ write!(out, "<a href=\"{}\">{}", href, text_s);
+ } else {
+ let klass_s = klass.as_html();
+ if klass_s.is_empty() {
+ write!(out, "<a href=\"{}\">{}", href, text_s);
+ } else {
+ write!(out, "<a class=\"{}\" href=\"{}\">{}", klass_s, href, text_s);
+ }
+ }
return Some("</a>");
}
}
- write!(out, "<span class=\"{}\">{}", klass.as_html(), text_s);
- Some("</span>")
+ if !open_tag {
+ write!(out, "{}", text_s);
+ return None;
+ }
+ let klass_s = klass.as_html();
+ if klass_s.is_empty() {
+ write!(out, "{}", text_s);
+ Some("")
+ } else {
+ write!(out, "<span class=\"{}\">{}", klass_s, text_s);
+ Some("</span>")
+ }
}
#[cfg(test)]
-<span class="example"><span class="kw">let</span> <span class="ident">x</span> <span class="op">=</span> <span class="number">1</span>;</span>
-<span class="kw">let</span> <span class="ident">y</span> <span class="op">=</span> <span class="number">2</span>;
\ No newline at end of file
+<span class="example"><span class="kw">let </span>x = <span class="number">1</span>;</span>
+<span class="kw">let </span>y = <span class="number">2</span>;
\ No newline at end of file
-<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">foo</span>() {
+<span class="kw">pub fn </span>foo() {
<span class="macro">println!</span>(<span class="string">"foo"</span>);
}
-<span class="kw">use</span> <span class="ident"><span class="kw">crate</span>::a::foo</span>;
-<span class="kw">use</span> <span class="ident"><span class="self">self</span>::whatever</span>;
-<span class="kw">let</span> <span class="ident">x</span> <span class="op">=</span> <span class="ident"><span class="kw">super</span>::b::foo</span>;
-<span class="kw">let</span> <span class="ident">y</span> <span class="op">=</span> <span class="ident"><span class="self">Self</span>::whatever</span>;
\ No newline at end of file
+<span class="kw">use </span><span class="kw">crate</span>::a::foo;
+<span class="kw">use </span><span class="self">self</span>::whatever;
+<span class="kw">let </span>x = <span class="kw">super</span>::b::foo;
+<span class="kw">let </span>y = <span class="self">Self</span>::whatever;
\ No newline at end of file
.lifetime { color: #B76514; }
.question-mark { color: #ff9011; }
</style>
-<pre><code><span class="attribute">#![<span class="ident">crate_type</span> <span class="op">=</span> <span class="string">"lib"</span>]</span>
+<pre><code><span class="attribute">#![crate_type = <span class="string">"lib"</span>]</span>
-<span class="kw">use</span> <span class="ident">std::path</span>::{<span class="ident">Path</span>, <span class="ident">PathBuf</span>};
+<span class="kw">use </span>std::path::{Path, PathBuf};
-<span class="attribute">#[<span class="ident">cfg</span>(<span class="ident">target_os</span> <span class="op">=</span> <span class="string">"linux"</span>)]</span>
-<span class="kw">fn</span> <span class="ident">main</span>() -> () {
- <span class="kw">let</span> <span class="ident">foo</span> <span class="op">=</span> <span class="bool-val">true</span> <span class="op">&&</span> <span class="bool-val">false</span> <span class="op">|</span><span class="op">|</span> <span class="bool-val">true</span>;
- <span class="kw">let</span> <span class="kw">_</span>: <span class="kw-2">*const</span> () <span class="op">=</span> <span class="number">0</span>;
- <span class="kw">let</span> <span class="kw">_</span> <span class="op">=</span> <span class="kw-2">&</span><span class="ident">foo</span>;
- <span class="kw">let</span> <span class="kw">_</span> <span class="op">=</span> <span class="op">&&</span><span class="ident">foo</span>;
- <span class="kw">let</span> <span class="kw">_</span> <span class="op">=</span> <span class="kw-2">*</span><span class="ident">foo</span>;
- <span class="macro">mac!</span>(<span class="ident">foo</span>, <span class="kw-2">&mut</span> <span class="ident">bar</span>);
- <span class="macro">assert!</span>(<span class="self">self</span>.<span class="ident">length</span> <span class="op"><</span> <span class="ident">N</span> <span class="op">&&</span> <span class="ident">index</span> <span class="op"><</span><span class="op">=</span> <span class="self">self</span>.<span class="ident">length</span>);
- <span class="ident">::std::env::var</span>(<span class="string">"gateau"</span>).<span class="ident">is_ok</span>();
- <span class="attribute">#[<span class="ident">rustfmt::skip</span>]</span>
- <span class="kw">let</span> <span class="ident">s</span>:<span class="ident">std::path::PathBuf</span> <span class="op">=</span> <span class="ident">std::path::PathBuf::new</span>();
- <span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">s</span> <span class="op">=</span> <span class="ident">String::new</span>();
+<span class="attribute">#[cfg(target_os = <span class="string">"linux"</span>)]</span>
+<span class="kw">fn </span>main() -> () {
+ <span class="kw">let </span>foo = <span class="bool-val">true </span>&& <span class="bool-val">false </span>|| <span class="bool-val">true</span>;
+ <span class="kw">let _</span>: <span class="kw-2">*const </span>() = <span class="number">0</span>;
+ <span class="kw">let _ </span>= <span class="kw-2">&</span>foo;
+ <span class="kw">let _ </span>= &&foo;
+ <span class="kw">let _ </span>= <span class="kw-2">*</span>foo;
+ <span class="macro">mac!</span>(foo, <span class="kw-2">&mut </span>bar);
+ <span class="macro">assert!</span>(<span class="self">self</span>.length < N && index <= <span class="self">self</span>.length);
+ ::std::env::var(<span class="string">"gateau"</span>).is_ok();
+ <span class="attribute">#[rustfmt::skip]</span>
+ <span class="kw">let </span>s:std::path::PathBuf = std::path::PathBuf::new();
+ <span class="kw">let </span><span class="kw-2">mut </span>s = String::new();
- <span class="kw">match</span> <span class="kw-2">&</span><span class="ident">s</span> {
- <span class="kw-2">ref</span> <span class="kw-2">mut</span> <span class="ident">x</span> => {}
+ <span class="kw">match </span><span class="kw-2">&</span>s {
+ <span class="kw-2">ref mut </span>x => {}
}
}
-<span class="macro">macro_rules!</span> <span class="ident">bar</span> {
- (<span class="macro-nonterminal">$</span><span class="macro-nonterminal">foo</span>:<span class="ident">tt</span>) => {};
+<span class="macro">macro_rules!</span> bar {
+ (<span class="macro-nonterminal">$foo</span>:tt) => {};
}
</code></pre>
-<span class="kw">union</span> <span class="ident">Foo</span> {
- <span class="ident">i</span>: <span class="ident">i8</span>,
- <span class="ident">u</span>: <span class="ident">i8</span>,
+<span class="kw">union </span>Foo {
+ i: i8,
+ u: i8,
}
-<span class="kw">fn</span> <span class="ident">main</span>() {
- <span class="kw">let</span> <span class="ident">union</span> <span class="op">=</span> <span class="number">0</span>;
+<span class="kw">fn </span>main() {
+ <span class="kw">let </span>union = <span class="number">0</span>;
}
/// may happen, for example, with externally inlined items where the source
/// of their crate documentation isn't known.
pub(super) fn src_href(&self, item: &clean::Item) -> Option<String> {
- self.href_from_span(item.span(self.tcx()), true)
+ self.href_from_span(item.span(self.tcx())?, true)
}
pub(crate) fn href_from_span(&self, span: clean::Span, with_lines: bool) -> Option<String> {
- if span.is_dummy() {
- return None;
- }
let mut root = self.root_path();
let mut path = String::new();
let cnum = span.cnum(self.sess());
let contents = match fs::read_to_string(&path) {
Ok(contents) => contents,
Err(err) => {
- let span = item.span(tcx).inner();
+ let span = item.span(tcx).map_or(rustc_span::DUMMY_SP, |span| span.inner());
tcx.sess
.span_err(span, &format!("failed to read file {}: {}", path.display(), err));
return false;
fn add_local_source(&mut self, item: &clean::Item) {
let sess = self.tcx.sess;
let span = item.span(self.tcx);
+ let Some(span) = span else { return };
// skip all synthetic "files"
if !is_real_and_local(span, sess) {
return;
let tcx = self.cx.tcx();
let span = item.span(tcx);
+ let Some(span) = span else { return };
let sess = tcx.sess;
// If we're not rendering sources, there's nothing to do.
pre.rust .number, pre.rust .string { color: #b8cc52; }
pre.rust .kw, pre.rust .kw-2, pre.rust .prelude-ty,
pre.rust .bool-val, pre.rust .prelude-val,
-pre.rust .op, pre.rust .lifetime { color: #ff7733; }
+pre.rust .lifetime { color: #ff7733; }
pre.rust .macro, pre.rust .macro-nonterminal { color: #a37acc; }
pre.rust .question-mark {
color: #ff9011;
pre.rust .attribute {
color: #e6e1cf;
}
-pre.rust .attribute .ident, pre.rust .attribute .op {
- color: #e6e1cf;
-}
.example-wrap > pre.line-number {
color: #5c67736e;
.block a.current.method,.content span.tymethod,.content a.tymethod,.block a.current.tymethod,
.content .fnname {}
pre.rust .kw {}
-pre.rust .self,pre.rust .bool-val,pre.rust .prelude-val,pre.rust .attribute,
-pre.rust .attribute .ident {}
+pre.rust .self,pre.rust .bool-val,pre.rust .prelude-val,pre.rust .attribute {}
.content span.foreigntype,.content a.foreigntype,.block a.current.foreigntype {}
pre.rust .doccomment {}
.stab.deprecated {}
pre.rust .kw-2, pre.rust .prelude-ty { color: #769acb; }
pre.rust .number, pre.rust .string { color: #83a300; }
pre.rust .self, pre.rust .bool-val, pre.rust .prelude-val,
-pre.rust .attribute, pre.rust .attribute .ident { color: #ee6868; }
+pre.rust .attribute { color: #ee6868; }
pre.rust .macro, pre.rust .macro-nonterminal { color: #3E999F; }
pre.rust .lifetime { color: #d97f26; }
pre.rust .question-mark {
pre.rust .kw-2, pre.rust .prelude-ty { color: #4271AE; }
pre.rust .number, pre.rust .string { color: #718C00; }
pre.rust .self, pre.rust .bool-val, pre.rust .prelude-val,
-pre.rust .attribute, pre.rust .attribute .ident { color: #C82829; }
+pre.rust .attribute { color: #C82829; }
pre.rust .comment { color: #8E908C; }
pre.rust .doccomment { color: #4D4D4C; }
pre.rust .macro, pre.rust .macro-nonterminal { color: #3E999F; }
id: from_item_id_with_name(item_id, self.tcx, name),
crate_id: item_id.krate().as_u32(),
name: name.map(|sym| sym.to_string()),
- span: self.convert_span(span),
+ span: span.and_then(|span| self.convert_span(span)),
visibility: self.convert_visibility(visibility),
docs,
attrs,
use clean::GenericBound::*;
match bound {
TraitBound(clean::PolyTrait { trait_, generic_params }, modifier) => {
- // FIXME: should `trait_` be a clean::Path equivalent in JSON?
- let trait_ = clean::Type::Path { path: trait_ }.into_tcx(tcx);
GenericBound::TraitBound {
- trait_,
+ trait_: trait_.into_tcx(tcx),
generic_params: generic_params.into_tcx(tcx),
modifier: from_trait_bound_modifier(modifier),
}
};
match ty {
- clean::Type::Path { path } => Type::ResolvedPath {
- name: path.whole_name(),
- id: from_item_id(path.def_id().into(), tcx),
- args: path.segments.last().map(|args| Box::new(args.clone().args.into_tcx(tcx))),
- param_names: Vec::new(),
- },
+ clean::Type::Path { path } => Type::ResolvedPath(path.into_tcx(tcx)),
clean::Type::DynTrait(bounds, lt) => Type::DynTrait(DynTrait {
lifetime: lt.map(convert_lifetime),
traits: bounds.into_tcx(tcx),
mutable: mutability == ast::Mutability::Mut,
type_: Box::new((*type_).into_tcx(tcx)),
},
- QPath { assoc, self_type, trait_, .. } => {
- // FIXME: should `trait_` be a clean::Path equivalent in JSON?
- let trait_ = clean::Type::Path { path: trait_ }.into_tcx(tcx);
- Type::QualifiedPath {
- name: assoc.name.to_string(),
- args: Box::new(assoc.args.clone().into_tcx(tcx)),
- self_type: Box::new((*self_type).into_tcx(tcx)),
- trait_: Box::new(trait_),
- }
- }
+ QPath { assoc, self_type, trait_, .. } => Type::QualifiedPath {
+ name: assoc.name.to_string(),
+ args: Box::new(assoc.args.clone().into_tcx(tcx)),
+ self_type: Box::new((*self_type).into_tcx(tcx)),
+ trait_: trait_.into_tcx(tcx),
+ },
+ }
+ }
+}
+
+impl FromWithTcx<clean::Path> for Path {
+ fn from_tcx(path: clean::Path, tcx: TyCtxt<'_>) -> Path {
+ Path {
+ name: path.whole_name(),
+ id: from_item_id(path.def_id().into(), tcx),
+ args: path.segments.last().map(|args| Box::new(args.clone().args.into_tcx(tcx))),
}
}
}
clean::PolyTrait { trait_, generic_params }: clean::PolyTrait,
tcx: TyCtxt<'_>,
) -> Self {
- PolyTrait {
- trait_: clean::Type::Path { path: trait_ }.into_tcx(tcx),
- generic_params: generic_params.into_tcx(tcx),
- }
+ PolyTrait { trait_: trait_.into_tcx(tcx), generic_params: generic_params.into_tcx(tcx) }
}
}
fn from_tcx(impl_: clean::Impl, tcx: TyCtxt<'_>) -> Self {
let provided_trait_methods = impl_.provided_trait_methods(tcx);
let clean::Impl { unsafety, generics, trait_, for_, items, polarity, kind } = impl_;
- // FIXME: should `trait_` be a clean::Path equivalent in JSON?
- let trait_ = trait_.map(|path| clean::Type::Path { path }.into_tcx(tcx));
// FIXME: use something like ImplKind in JSON?
let (synthetic, blanket_impl) = match kind {
clean::ImplKind::Normal | clean::ImplKind::FakeVaradic => (false, None),
.into_iter()
.map(|x| x.to_string())
.collect(),
- trait_,
+ trait_: trait_.map(|path| path.into_tcx(tcx)),
for_: for_.into_tcx(tcx),
items: ids(items, tcx),
negative: negative_polarity,
#![feature(box_patterns)]
#![feature(control_flow_enum)]
#![feature(drain_filter)]
-#![cfg_attr(bootstrap, feature(let_chains))]
#![feature(let_else)]
#![feature(test)]
#![feature(never_type)]
None,
);
- let filename = i.span(self.ctx.tcx).filename(self.ctx.sess());
let has_doc_example = tests.found_tests != 0;
// The `expect_def_id()` should be okay because `local_def_id_to_hir_id`
// would presumably panic if a fake `DefIndex` were passed.
let should_have_docs = !should_be_ignored
&& (level != lint::Level::Allow || matches!(source, LintLevelSource::Default));
- debug!("counting {:?} {:?} in {:?}", i.type_(), i.name, filename);
- self.items.entry(filename).or_default().count_item(
- has_docs,
- has_doc_example,
- should_have_doc_example(self.ctx, i),
- should_have_docs,
- );
+ if let Some(span) = i.span(self.ctx.tcx) {
+ let filename = span.filename(self.ctx.sess());
+ debug!("counting {:?} {:?} in {:?}", i.type_(), i.name, filename);
+ self.items.entry(filename).or_default().count_item(
+ has_docs,
+ has_doc_example,
+ should_have_doc_example(self.ctx, i),
+ should_have_docs,
+ );
+ }
}
}
}
// handled in the `strip-priv-imports` pass
- clean::ExternCrateItem { .. } | clean::ImportItem(..) => {}
+ clean::ExternCrateItem { .. } => {}
+ clean::ImportItem(ref imp) => {
+ // Because json doesn't inline imports from private modules, we need to mark
+ // the imported item as retained so it's impls won't be stripped.i
+ //
+ // FIXME: Is it necessary to check for json output here: See
+ // https://github.com/rust-lang/rust/pull/100325#discussion_r941495215
+ if let Some(did) = imp.source.did && self.is_json_output {
+ self.retained.insert(did.into());
+ }
+ }
clean::ImplItem(..) => {}
use serde::{Deserialize, Serialize};
/// rustdoc format-version.
-pub const FORMAT_VERSION: u32 = 17;
+pub const FORMAT_VERSION: u32 = 18;
/// A `Crate` is the root of the emitted JSON blob. It contains all type/documentation information
/// about the language items in the local crate, as well as info about external items to allow
/// A trait and potential HRTBs
pub struct PolyTrait {
#[serde(rename = "trait")]
- pub trait_: Type,
+ pub trait_: Path,
/// Used for Higher-Rank Trait Bounds (HRTBs)
/// ```text
/// dyn for<'a> Fn() -> &'a i32"
pub enum GenericBound {
TraitBound {
#[serde(rename = "trait")]
- trait_: Type,
+ trait_: Path,
/// Used for Higher-Rank Trait Bounds (HRTBs)
/// ```text
/// where F: for<'a, 'b> Fn(&'a u8, &'b u8)
#[serde(tag = "kind", content = "inner")]
pub enum Type {
/// Structs, enums, and traits
- ResolvedPath {
- name: String,
- id: Id,
- args: Option<Box<GenericArgs>>,
- param_names: Vec<GenericBound>,
- },
+ ResolvedPath(Path),
DynTrait(DynTrait),
/// Parameterized types
Generic(String),
args: Box<GenericArgs>,
self_type: Box<Type>,
#[serde(rename = "trait")]
- trait_: Box<Type>,
+ trait_: Path,
},
}
+#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
+pub struct Path {
+ pub name: String,
+ pub id: Id,
+ /// Generic arguments to the type
+ /// ```test
+ /// std::borrow::Cow<'static, str>
+ /// ^^^^^^^^^^^^^^
+ /// |
+ /// this part
+ /// ```
+ pub args: Option<Box<GenericArgs>>,
+}
+
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct FunctionPointer {
pub decl: FnDecl,
pub generics: Generics,
pub provided_trait_methods: Vec<String>,
#[serde(rename = "trait")]
- pub trait_: Option<Type>,
+ pub trait_: Option<Path>,
#[serde(rename = "for")]
pub for_: Type,
pub items: Vec<Id>,
"tool is executed."
],
"compiler": {
- "date": "2022-07-16",
+ "date": "2022-08-09",
"version": "beta"
},
"rustfmt": {
- "date": "2022-07-21",
+ "date": "2022-08-09",
"version": "nightly"
},
"checksums_sha256": {
- "dist/2022-07-16/cargo-beta-aarch64-apple-darwin.tar.gz": "d114c9c7d39fa092e291d39eeed2cac5ec67a9d7f1e392014f83629dffd500f6",
- "dist/2022-07-16/cargo-beta-aarch64-apple-darwin.tar.xz": "d3d0090e4afb944da8ae9b6b5441486e03066e83de69a2a9606a51444e601196",
- "dist/2022-07-16/cargo-beta-aarch64-pc-windows-msvc.tar.gz": "99d64f68bdbeff55552efe0860a2170db6c0cda155a7a955322d4ccfced2a2e7",
- "dist/2022-07-16/cargo-beta-aarch64-pc-windows-msvc.tar.xz": "209b0514a99341bdcaf62ad4785b807383aff2572105f143e89fc89f67bea0d4",
- "dist/2022-07-16/cargo-beta-aarch64-unknown-linux-gnu.tar.gz": "6dc3c9f6739418e14d5d505b1f215c12768d9db2cc26912cae09ec75d6a5b336",
- "dist/2022-07-16/cargo-beta-aarch64-unknown-linux-gnu.tar.xz": "741f7d7a55fcab360d6e0d91e0f83bf8ee6aaf19b0e880a7c3e91af22a4d7ca9",
- "dist/2022-07-16/cargo-beta-aarch64-unknown-linux-musl.tar.gz": "15185b7f4b806cf8dd5e785625df73efa27a5653e8c38476040372f372a11b1f",
- "dist/2022-07-16/cargo-beta-aarch64-unknown-linux-musl.tar.xz": "0122b5d493383d97d39d6593bd9cc709a1809f29f1713d3553ae242b78047e34",
- "dist/2022-07-16/cargo-beta-arm-unknown-linux-gnueabi.tar.gz": "e3e2b281ff1233f6596b27db8b593252867d7f26c1ce91b779a164234d2cfd86",
- "dist/2022-07-16/cargo-beta-arm-unknown-linux-gnueabi.tar.xz": "0c71da4b8daeab00da01bca07eef363c5a17a03c1eaf48014d3508c7f228e24b",
- "dist/2022-07-16/cargo-beta-arm-unknown-linux-gnueabihf.tar.gz": "6bce124d863189178f06cf430466c18d9ba0cd0e42851e18bb38254d00bdad64",
- "dist/2022-07-16/cargo-beta-arm-unknown-linux-gnueabihf.tar.xz": "0ae2a35e0e4f2946dd78420b11f17a54a370e15e12367ba29b63e3f087fb0c71",
- "dist/2022-07-16/cargo-beta-armv7-unknown-linux-gnueabihf.tar.gz": "eee82cd57578eade5cbc07cf3d48be243a4789e6fba6d7db5772038f87e243f9",
- "dist/2022-07-16/cargo-beta-armv7-unknown-linux-gnueabihf.tar.xz": "e27b8fe73df64a2733002007503995d9f914d16f852d5e643ac539408086435d",
- "dist/2022-07-16/cargo-beta-i686-pc-windows-gnu.tar.gz": "0aa99ee73efa4940ffd6789f98d3774bf33a3a54c579759b1f9f0e92cb403134",
- "dist/2022-07-16/cargo-beta-i686-pc-windows-gnu.tar.xz": "244a98bc858d800a1a36018d7b9fbb77471842b9a130301f9dc19e427c336fb2",
- "dist/2022-07-16/cargo-beta-i686-pc-windows-msvc.tar.gz": "6b19412e037eb918b05e993ab1c62d96da8cbf92b0a9fc1480a76ad2dc331f0f",
- "dist/2022-07-16/cargo-beta-i686-pc-windows-msvc.tar.xz": "0420980cc9381249bb187c274f42472997e6283acf95bebf1f93b50d5c138942",
- "dist/2022-07-16/cargo-beta-i686-unknown-linux-gnu.tar.gz": "95d0e17823ee02ebc3d73982e54b96a110afbf97656ed581da0e71e2635cfb51",
- "dist/2022-07-16/cargo-beta-i686-unknown-linux-gnu.tar.xz": "75a65a917ad25c1927c9c8306e76d13989f1ea42c6ca063269685e33811e1fb1",
- "dist/2022-07-16/cargo-beta-mips-unknown-linux-gnu.tar.gz": "ac12e969fc6a892621ce9ffa2108a21381033800526d3b0dc6c1dd343b10af09",
- "dist/2022-07-16/cargo-beta-mips-unknown-linux-gnu.tar.xz": "3be48fe74c14e48c084fe395b9eef153d97fca57dfc12b5a07f2de143c5df4fc",
- "dist/2022-07-16/cargo-beta-mips64-unknown-linux-gnuabi64.tar.gz": "1727662c7307c3fec52663d356ccc147dd0c2608cd5607f83057a3f2f315e578",
- "dist/2022-07-16/cargo-beta-mips64-unknown-linux-gnuabi64.tar.xz": "47b32153e287a972d6b7278a7d9b2339d16e8d9a938a42221536d12762d0df92",
- "dist/2022-07-16/cargo-beta-mips64el-unknown-linux-gnuabi64.tar.gz": "14d56231996a7c20e91c204658412142b8288668109d46f3ed9771186937fff5",
- "dist/2022-07-16/cargo-beta-mips64el-unknown-linux-gnuabi64.tar.xz": "83410621415f07b345d6989fd146303594c811449fd5e3c7609158a9404ba236",
- "dist/2022-07-16/cargo-beta-mipsel-unknown-linux-gnu.tar.gz": "5362caf0bd6af50fc4bd89864beddcc909d1d53d0ce2b4049eca4b9019b9d922",
- "dist/2022-07-16/cargo-beta-mipsel-unknown-linux-gnu.tar.xz": "6b5007890a41aead77f919ad7ff0fc29c32e460ab3402837ea0e6ded21f2e4c0",
- "dist/2022-07-16/cargo-beta-powerpc-unknown-linux-gnu.tar.gz": "e4c914ef7b6e97aeb437d0fb2100f0fe621519ef8f6bdee98a4b3e731d5626d6",
- "dist/2022-07-16/cargo-beta-powerpc-unknown-linux-gnu.tar.xz": "33a77edf6f85fc2ea790a10c3108811c0ccb22a0c4c0d1e3a6c3ba27c43ab6d9",
- "dist/2022-07-16/cargo-beta-powerpc64-unknown-linux-gnu.tar.gz": "85969807dc0d2999fe4dffdb0f8290bfeaf65646cf333924a933adaa4b045d05",
- "dist/2022-07-16/cargo-beta-powerpc64-unknown-linux-gnu.tar.xz": "b36b74e1032d6f83da8b18847df80d52fdf3375b2d45140020452e35c2b9af00",
- "dist/2022-07-16/cargo-beta-powerpc64le-unknown-linux-gnu.tar.gz": "203402c33bb81ed9c176ee7579fde97671b2f32ad5e7fb3200cd1b77f434d52b",
- "dist/2022-07-16/cargo-beta-powerpc64le-unknown-linux-gnu.tar.xz": "1bf1daa9660d4fe96e7b9d35fde4995e0e12efcdcb0247cb574495d20de080a1",
- "dist/2022-07-16/cargo-beta-riscv64gc-unknown-linux-gnu.tar.gz": "a5aec71139c49fb950c03bb4b6af19bac0eec2d6ba2520e49c2d1a08eeae36ee",
- "dist/2022-07-16/cargo-beta-riscv64gc-unknown-linux-gnu.tar.xz": "f0c5b7813073502316e25b71ab41eb600baffd8e51d6ad8134bf14aee53820ac",
- "dist/2022-07-16/cargo-beta-s390x-unknown-linux-gnu.tar.gz": "b64be7c8c471c9b4a2d9380ecf7d23431b1ea255bd080635ba58380a820cbe23",
- "dist/2022-07-16/cargo-beta-s390x-unknown-linux-gnu.tar.xz": "a0a6f204ce1f38482939caeb2efe645b60760e8b4c7a68ee4edcf51fc93409d7",
- "dist/2022-07-16/cargo-beta-x86_64-apple-darwin.tar.gz": "9ab770b4d43ca4020c40b2c234867b67d99794945bb274382f69f9d1e4b0d042",
- "dist/2022-07-16/cargo-beta-x86_64-apple-darwin.tar.xz": "66201509e2d1eb5b447f85b019467a2193fb9d3eaa12df025aff6746a47f49a7",
- "dist/2022-07-16/cargo-beta-x86_64-pc-windows-gnu.tar.gz": "295bfb182c85aad35fa5c25691acb03c037a28a8178b9b049df88d40176e418b",
- "dist/2022-07-16/cargo-beta-x86_64-pc-windows-gnu.tar.xz": "c1d4578521feb07b04c38b5431eb93830d518bbee47bb458e8f745a7bbd4b312",
- "dist/2022-07-16/cargo-beta-x86_64-pc-windows-msvc.tar.gz": "7eda4ebd7d8ade6e62772604bd6fe1a64f7123da1002c22810a752906893429d",
- "dist/2022-07-16/cargo-beta-x86_64-pc-windows-msvc.tar.xz": "7eb53b58d63c3f11faf58c819da9bf828f47b579904f9cc801a97b044bb7814c",
- "dist/2022-07-16/cargo-beta-x86_64-unknown-freebsd.tar.gz": "cce8a7f5d0e561ab9ede68e535b601396a7a46c2737d01b9c9f008b6cf4b510f",
- "dist/2022-07-16/cargo-beta-x86_64-unknown-freebsd.tar.xz": "c1989f0a6bb75c8ae4fb56fac60c880a62e92dbb225fa86b5383242573e62e9a",
- "dist/2022-07-16/cargo-beta-x86_64-unknown-illumos.tar.gz": "eb5a4e9bd6a2216e4b72afb5bc542d49583a23a3bb3146ef2c02aa9f15887d24",
- "dist/2022-07-16/cargo-beta-x86_64-unknown-illumos.tar.xz": "42c5330ba2ce1b8e4045e7b8671ad1254bc2d6119bc34996467c5956108897f9",
- "dist/2022-07-16/cargo-beta-x86_64-unknown-linux-gnu.tar.gz": "35fcf80d8cb8bcc5ab413128575bc6a843c145b4b748df2de9cc9697d535fb6b",
- "dist/2022-07-16/cargo-beta-x86_64-unknown-linux-gnu.tar.xz": "4070423142b86fac1ad312ea74880456343fbfe2f5f73e465993b21f4f019b93",
- "dist/2022-07-16/cargo-beta-x86_64-unknown-linux-musl.tar.gz": "4d3adc8d1cc15d45a4e7498965b92b9313cce8fa9a8f1391000d4dbe0258603a",
- "dist/2022-07-16/cargo-beta-x86_64-unknown-linux-musl.tar.xz": "2a39a68b74b7a62fb89f4ccbd202679fed65b425c1678451ac268b94c8294228",
- "dist/2022-07-16/cargo-beta-x86_64-unknown-netbsd.tar.gz": "8508973b3595a0b0a65050d761c108119251a57ba3013d4942f65d0f4f634a7a",
- "dist/2022-07-16/cargo-beta-x86_64-unknown-netbsd.tar.xz": "4309d7b2c2c26e454fee473e0345947b7447b6e107f795ce9d4cedfca3baa199",
- "dist/2022-07-16/rust-std-beta-aarch64-apple-darwin.tar.gz": "2168776e63da0bb2b6d09e90510f0d481c68d4aaaa1e1cfc79317add45a01d5a",
- "dist/2022-07-16/rust-std-beta-aarch64-apple-darwin.tar.xz": "bb9a83c1b5468e740a9b444052afe91a3d8d3223acdf1626e4302475f864acdd",
- "dist/2022-07-16/rust-std-beta-aarch64-apple-ios-sim.tar.gz": "44f00f44ee97a5f05b156a0be66151fefb79452b94b5d764564702194fb84ba1",
- "dist/2022-07-16/rust-std-beta-aarch64-apple-ios-sim.tar.xz": "b06f7599e3024cea98f90ea4a9dc0fac9d458dcce63aecc2497e2ec15a00eda8",
- "dist/2022-07-16/rust-std-beta-aarch64-apple-ios.tar.gz": "35d7c8d11aac14f2e4ce3a1e236a8e59642a6be1e474be7d741c0e38ffcb9d5d",
- "dist/2022-07-16/rust-std-beta-aarch64-apple-ios.tar.xz": "7fef57b2788303b10b267c228b80f6347c437a10dd2b77bea71e7280a11db008",
- "dist/2022-07-16/rust-std-beta-aarch64-fuchsia.tar.gz": "d83d4186e499853f337513b5603c4cdf287012bc121a33537eb514b2d47e8963",
- "dist/2022-07-16/rust-std-beta-aarch64-fuchsia.tar.xz": "92d3caab76907cea85fe78c10f902661ea0887c6689888f6eb9fffa2f443339f",
- "dist/2022-07-16/rust-std-beta-aarch64-linux-android.tar.gz": "82ca00fd9913e2d55bc0ecf06313a2f9004f71c40c44f01b3d7d9cd8d1799fb0",
- "dist/2022-07-16/rust-std-beta-aarch64-linux-android.tar.xz": "dc7c287887bba704fe988e7f5f7d080aff576de7a214f1dc63ded4fc784eba0b",
- "dist/2022-07-16/rust-std-beta-aarch64-pc-windows-msvc.tar.gz": "fe47ed76b388f7b01d5e3d1d51918beb0f04ca7e015353479f7eff78e49b9794",
- "dist/2022-07-16/rust-std-beta-aarch64-pc-windows-msvc.tar.xz": "0bcece81cf9b81c5ace02459f945b97be181f81704cade21687460f1db00343a",
- "dist/2022-07-16/rust-std-beta-aarch64-unknown-linux-gnu.tar.gz": "9f28057d4828f7a07eeefd8eb03c9e807babd86e67443099491421f7c5afa67f",
- "dist/2022-07-16/rust-std-beta-aarch64-unknown-linux-gnu.tar.xz": "b21f0deee74041385b7018979e7db1dfd071530f064b1bc500f9281cfafc38cc",
- "dist/2022-07-16/rust-std-beta-aarch64-unknown-linux-musl.tar.gz": "588d6952722ec461de5d0c10c5f01c6d6735740a74b8162e2e2ebb848f9175d4",
- "dist/2022-07-16/rust-std-beta-aarch64-unknown-linux-musl.tar.xz": "c6731bcd0e4e15d79dcdc6f974b5a4f7a379692ad2183c0bfd56e6619d9f0fe1",
- "dist/2022-07-16/rust-std-beta-aarch64-unknown-none-softfloat.tar.gz": "588585fd26813de3ae2a8a49c6e6fea5f0f7311911a54c015372010883cf5938",
- "dist/2022-07-16/rust-std-beta-aarch64-unknown-none-softfloat.tar.xz": "a5e820bbbf113250c4f814dd0f4aaa9b20b1a7d61613b7157993d25fb0ff3518",
- "dist/2022-07-16/rust-std-beta-aarch64-unknown-none.tar.gz": "69ec1ef2f456a8cd294ec3f7c485f45401e6f200df9f525419726cf9da60dc60",
- "dist/2022-07-16/rust-std-beta-aarch64-unknown-none.tar.xz": "b13d0099a55a928dfbfe07d80426e9bd53b6e35cfc6b634ad2ee02174ce42f7a",
- "dist/2022-07-16/rust-std-beta-arm-linux-androideabi.tar.gz": "a90a4cc72263b96ada453dd3c8443d076ec150ed910ad30f26f825cd668516e9",
- "dist/2022-07-16/rust-std-beta-arm-linux-androideabi.tar.xz": "0d7c8c13a18888cd7e9613c7d88ef227d9b2034739d0d16507aca28403328b42",
- "dist/2022-07-16/rust-std-beta-arm-unknown-linux-gnueabi.tar.gz": "9fcd72dfd5568a3e7023c416720ba4d5e42aa6d425c7ce6feb2ebf1b650d7591",
- "dist/2022-07-16/rust-std-beta-arm-unknown-linux-gnueabi.tar.xz": "43efd4e1ca95f54fef097f14483a4f4d96d499c38c5ad3d3a290e02f7c4c4637",
- "dist/2022-07-16/rust-std-beta-arm-unknown-linux-gnueabihf.tar.gz": "7d2c708aaeb01014856ee7d2c6c4c85883f17fd00fca912aabb93d84170e3e61",
- "dist/2022-07-16/rust-std-beta-arm-unknown-linux-gnueabihf.tar.xz": "97d3c092fd702dc7df0df83722046371b4d418aabc60fbbf0807ddddf3e7dcda",
- "dist/2022-07-16/rust-std-beta-arm-unknown-linux-musleabi.tar.gz": "74e8fe4152eb12ee8b9d4fd4e3cfe5d506329c94ab515319fb2aaf013bacea5f",
- "dist/2022-07-16/rust-std-beta-arm-unknown-linux-musleabi.tar.xz": "a207d79cf57f3e13b6f85761373a00fa8afde8f513e14a3e0c0a70f40d89e890",
- "dist/2022-07-16/rust-std-beta-arm-unknown-linux-musleabihf.tar.gz": "4660ec4d1fe1960e70b54bce58cae6775b8df86c3ecbc96f4df0067dcd90a3cf",
- "dist/2022-07-16/rust-std-beta-arm-unknown-linux-musleabihf.tar.xz": "c86a999f7affd8f4d2e0d509cf3e2229a3cd40768ef86b1ac36b5dccbbe56bdf",
- "dist/2022-07-16/rust-std-beta-armebv7r-none-eabi.tar.gz": "5ecc032c10a8f8d3e1e40256ca7c7e03cc98ae35d56105f70df94a4519412dbb",
- "dist/2022-07-16/rust-std-beta-armebv7r-none-eabi.tar.xz": "8e2c1c97083aa141d3b31476903a6325fd11f0ae5350909eb0295b8be19eb1f8",
- "dist/2022-07-16/rust-std-beta-armebv7r-none-eabihf.tar.gz": "e111491ee2412c8d770b0a93fe402566e46c2faa855c71f24da77a989f36ea2a",
- "dist/2022-07-16/rust-std-beta-armebv7r-none-eabihf.tar.xz": "7c814fece60ece924f5dffff6ee6f1605965841f4b864cd271c5c4f3b3c18042",
- "dist/2022-07-16/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.gz": "0d4e93aa2f04f1d255d319653b3f4c02bd3557cc8227e6be4e0f1769aeadd2a8",
- "dist/2022-07-16/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.xz": "d60246292f63abeb9eb35ddf93901ea9f75cba358a67589595aa1cfc9d35e6aa",
- "dist/2022-07-16/rust-std-beta-armv5te-unknown-linux-musleabi.tar.gz": "085e236212a908e0e363d78dd3ce8c676cd2dbc8e817601486502389ba8d0734",
- "dist/2022-07-16/rust-std-beta-armv5te-unknown-linux-musleabi.tar.xz": "654e655cb257dbed0490ec0c75e0cc0b7e35512d4f6f9f5dddc10bab0cd02098",
- "dist/2022-07-16/rust-std-beta-armv7-linux-androideabi.tar.gz": "10fb120b0269a65f554a592e05ec26703b0888dbeaf06c15b43522b730c943cd",
- "dist/2022-07-16/rust-std-beta-armv7-linux-androideabi.tar.xz": "470eec8bd47f66409e28eac2b86b5c6c0644531c91135637f667f54edb7fd6a9",
- "dist/2022-07-16/rust-std-beta-armv7-unknown-linux-gnueabi.tar.gz": "520e83ebeb2dd29fea43087399af6227fe90b5a571572322301cc6d9b76f5027",
- "dist/2022-07-16/rust-std-beta-armv7-unknown-linux-gnueabi.tar.xz": "a7527bcd5ee6017de7fde1a6f1d98db831e7bddf5a64b54ce12cadafaa3d560b",
- "dist/2022-07-16/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.gz": "bb0ac318b0a5dd972356f4e94789b68caae1a14e5996493a3bed1a579bb1145d",
- "dist/2022-07-16/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.xz": "cc1e65bf50246be9d9578487580038a7015f3a61444dc53afb7c4f2afc8181f8",
- "dist/2022-07-16/rust-std-beta-armv7-unknown-linux-musleabi.tar.gz": "7ff2051b2324f51bf0b3fe7581e1b5e02c4e2fb4075950c36716e8ba783b1b42",
- "dist/2022-07-16/rust-std-beta-armv7-unknown-linux-musleabi.tar.xz": "d4e32fcf2da983adc8db7043175cded76e56894f136766c5d9afe08ef6f0e766",
- "dist/2022-07-16/rust-std-beta-armv7-unknown-linux-musleabihf.tar.gz": "6f7b86e7b51ba9d8187c61ff0d7a6d28fe65201bc94b94bd5a845490fbcff3e4",
- "dist/2022-07-16/rust-std-beta-armv7-unknown-linux-musleabihf.tar.xz": "3ac410ea3f641b578ec1183856306b1eb4e0d02ba58534df114ab45a91fafd1d",
- "dist/2022-07-16/rust-std-beta-armv7a-none-eabi.tar.gz": "abe93aa78a72eda2735d2f78cc98ea9b7a50752320d83b70464bac86a4a765ee",
- "dist/2022-07-16/rust-std-beta-armv7a-none-eabi.tar.xz": "059560de23b47a43800319fc968a5dd34d44ab61f486a8f33a075798c66f0528",
- "dist/2022-07-16/rust-std-beta-armv7r-none-eabi.tar.gz": "b08a4b0b56d86182e735d5dc6f47083a4f8a0101b4a712e02f14c9f3d1720001",
- "dist/2022-07-16/rust-std-beta-armv7r-none-eabi.tar.xz": "d65cb28ea5f5cb7e5649a85a591609b5f49c0e3b0d02c1ff8d2b1dc10ea3b4a3",
- "dist/2022-07-16/rust-std-beta-armv7r-none-eabihf.tar.gz": "cb13a879797483d7a7fd2073be2af0c83f98c4226e81ea0333670eddffc4f77e",
- "dist/2022-07-16/rust-std-beta-armv7r-none-eabihf.tar.xz": "4965ee9c27d6104f572bcfd19944e19a3f70d58a5d0d215059f2cc52f7bc9c1e",
- "dist/2022-07-16/rust-std-beta-asmjs-unknown-emscripten.tar.gz": "e8437c9df42118b8607723c1e4f04a7b7a302e9894dc52ab8c212f07964ac994",
- "dist/2022-07-16/rust-std-beta-asmjs-unknown-emscripten.tar.xz": "b05f10cee7b5c8aeea44689c11ddfe6f266a8779dfb0fa9df51c7c784f9f31a6",
- "dist/2022-07-16/rust-std-beta-i586-pc-windows-msvc.tar.gz": "65f66e8690c742b13c3371c1af4219d701b66f61e4fd984b1d67bb89d6468566",
- "dist/2022-07-16/rust-std-beta-i586-pc-windows-msvc.tar.xz": "cabea5fef3004aee4c3108a47fba945f434bd29b4c55250236ec009405e41b36",
- "dist/2022-07-16/rust-std-beta-i586-unknown-linux-gnu.tar.gz": "8349e67b9760f9c257c745c4d87015bd623e1cf073703429f64400f7dc9c1210",
- "dist/2022-07-16/rust-std-beta-i586-unknown-linux-gnu.tar.xz": "ee6473059771a8f49ce5ca8f36913a9ef31be3def32c63c5a31f50a896aa565e",
- "dist/2022-07-16/rust-std-beta-i586-unknown-linux-musl.tar.gz": "7edb1155a5fab3c123e0a847c0397b6c347cd7b4a6a15996d93f45281c2d8eb1",
- "dist/2022-07-16/rust-std-beta-i586-unknown-linux-musl.tar.xz": "49360ce15d751ef01403459fe3eaa30061160a79e4454eee7f5c63fc65a3666d",
- "dist/2022-07-16/rust-std-beta-i686-linux-android.tar.gz": "5d62f8e1b15b44998f7b039b7e6ab7deff85ba13130a11309b2541c70834538a",
- "dist/2022-07-16/rust-std-beta-i686-linux-android.tar.xz": "4b2e1b2835919299113d28eca09b1e12471054786156da0cb63bc0620d6afe00",
- "dist/2022-07-16/rust-std-beta-i686-pc-windows-gnu.tar.gz": "39a9c3f2392240b29f52ed525f57d548537e7cc7a57438bd84f7efbd85b49811",
- "dist/2022-07-16/rust-std-beta-i686-pc-windows-gnu.tar.xz": "d8ae971791693c23260b73c8faf94570a1bddbcecfa9c339fbd23682c8cd2bb5",
- "dist/2022-07-16/rust-std-beta-i686-pc-windows-msvc.tar.gz": "e57020d959cbe2e7331808f425e8d95e5204f4e9c33cdd301c6809aa06ba6d90",
- "dist/2022-07-16/rust-std-beta-i686-pc-windows-msvc.tar.xz": "35b4504603903e7c753487585fcc75237f4f8a0ee933c52941abaf2c6913e0f0",
- "dist/2022-07-16/rust-std-beta-i686-unknown-freebsd.tar.gz": "dd5c6dd4fe4bfb1acdda726ac9f6fa0944f745be946ed175a8e3c62c0d4c46f7",
- "dist/2022-07-16/rust-std-beta-i686-unknown-freebsd.tar.xz": "95a9f3bcce8780522d678822cac8b06ba662112df51afa312f4c7ed76a3987ed",
- "dist/2022-07-16/rust-std-beta-i686-unknown-linux-gnu.tar.gz": "52b49a92f66cbc2b250a7272f58acfb9732fdb7073baa430b47ff9ebfe0c98a2",
- "dist/2022-07-16/rust-std-beta-i686-unknown-linux-gnu.tar.xz": "2f6b5de99c83cdd01c44b388ea059d10ee7f0f62ca17547b7a6d8d66fdf349f4",
- "dist/2022-07-16/rust-std-beta-i686-unknown-linux-musl.tar.gz": "24d81d4d181c86dc02fe5b3fb54c50f78f72f73c2d9c319710d275fb08a53980",
- "dist/2022-07-16/rust-std-beta-i686-unknown-linux-musl.tar.xz": "32c99f24396601c8a4afb250cda4718d6d5fae57f9534d5c3c3962e4c076d261",
- "dist/2022-07-16/rust-std-beta-mips-unknown-linux-gnu.tar.gz": "d476561d571d62d31c03b57fd380591acbb809fd4f26873e2ef2e4b3f583da46",
- "dist/2022-07-16/rust-std-beta-mips-unknown-linux-gnu.tar.xz": "93d3d0511508351f5e3322a3e4360586c2c2bdb60ca0c4aaea4fe5e7da081e92",
- "dist/2022-07-16/rust-std-beta-mips-unknown-linux-musl.tar.gz": "d8c354f83a5481508a88fa6ced6fb458458678ddfa7814e47415b5daa66b0470",
- "dist/2022-07-16/rust-std-beta-mips-unknown-linux-musl.tar.xz": "19f272db8772fa7b77cb9d5e1c56a1a2062a6e087b2980131128ab01b025f571",
- "dist/2022-07-16/rust-std-beta-mips64-unknown-linux-gnuabi64.tar.gz": "775aaac7be36438ce4e8f1cda3926c3540f90fc9b74e387d5e4497227ceaad97",
- "dist/2022-07-16/rust-std-beta-mips64-unknown-linux-gnuabi64.tar.xz": "bc460e80f4fd82492cc8e66f11320ef22c71fe26a4255606c73c325bbd2f8516",
- "dist/2022-07-16/rust-std-beta-mips64-unknown-linux-muslabi64.tar.gz": "7ebb73739bafa8f412756575f4033b45629b62a92a35460bb37f3f691640bcc9",
- "dist/2022-07-16/rust-std-beta-mips64-unknown-linux-muslabi64.tar.xz": "1483cde530d3d50116f4dbcb42a3b22cf7bb04559cc9bebd762f82e8b3ebea40",
- "dist/2022-07-16/rust-std-beta-mips64el-unknown-linux-gnuabi64.tar.gz": "a7f813851b5a9c67ba16c80da5b80397db1f4c9b5a10f4877f52b6861b856b1d",
- "dist/2022-07-16/rust-std-beta-mips64el-unknown-linux-gnuabi64.tar.xz": "3fd132910d46fb9d769d8697e81b89aff7f739d9b197e4a54b00797e217a0a66",
- "dist/2022-07-16/rust-std-beta-mips64el-unknown-linux-muslabi64.tar.gz": "8ddc74476e1023ee58ee5564d7357082cbba2a7d930abd7c704dbdf49439e2cf",
- "dist/2022-07-16/rust-std-beta-mips64el-unknown-linux-muslabi64.tar.xz": "f773cbcfb9010491f92cbeeccff0dfc8109d4407af4c10269766674a51e84b68",
- "dist/2022-07-16/rust-std-beta-mipsel-unknown-linux-gnu.tar.gz": "85bebea249c436f016fddef2865850adcb16585cccd6fd4fbd9baf0be971160c",
- "dist/2022-07-16/rust-std-beta-mipsel-unknown-linux-gnu.tar.xz": "74a519aa2b595b093510b81b0c65b9a864dc2cb3cb4ff5af8619531afd436b8a",
- "dist/2022-07-16/rust-std-beta-mipsel-unknown-linux-musl.tar.gz": "f8dcb0e03629d23715e7cba213b91753d99a9e0ce8b0111e360a8c6e062b9f41",
- "dist/2022-07-16/rust-std-beta-mipsel-unknown-linux-musl.tar.xz": "e2ad66f17aca663689d80e59b6ab854fe27aabda318c0ae41febf9fff700ac7f",
- "dist/2022-07-16/rust-std-beta-nvptx64-nvidia-cuda.tar.gz": "6351ee40b19c7981f9b4aa2900bda8cf6fec04f5953bca78c0f480f885b78425",
- "dist/2022-07-16/rust-std-beta-nvptx64-nvidia-cuda.tar.xz": "8c8f6ca9717ef1f4168d9ac4c4eb0f771149dcbc77ee4ec179031b10f9de13a2",
- "dist/2022-07-16/rust-std-beta-powerpc-unknown-linux-gnu.tar.gz": "706d3e633e8fdbc8f672153f16638ed2ade39321beefde054f63864bfac4e9af",
- "dist/2022-07-16/rust-std-beta-powerpc-unknown-linux-gnu.tar.xz": "0b7b37b4eee8fcccad684d606aa5b326f60473ed9f567cd2d17def4cbd8c3b63",
- "dist/2022-07-16/rust-std-beta-powerpc64-unknown-linux-gnu.tar.gz": "40a2572f1a4297bef43708d1dafd1709373a0258f2bbe7914a9f954ca4dbe2f0",
- "dist/2022-07-16/rust-std-beta-powerpc64-unknown-linux-gnu.tar.xz": "78ebece93dd1b8e6825d6026444484f0beca982d802651149da32b13d8de69c3",
- "dist/2022-07-16/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.gz": "4a362a752fb6270c75fc24dc7cae00a70d4272972b1f0409a0a32582d1293acd",
- "dist/2022-07-16/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.xz": "f1b8eb010818955e3ed21b2b4e3c42180fa817dcc0aa6b75520149fccd2b9d1c",
- "dist/2022-07-16/rust-std-beta-riscv32i-unknown-none-elf.tar.gz": "0eb83977d0fb83eb498ff7858edd3fdfc0a2e40efa859a23b9a03972fd0f0c10",
- "dist/2022-07-16/rust-std-beta-riscv32i-unknown-none-elf.tar.xz": "b39894ecc6fd00b8398b1430285d7876f8955eeae43949e54a45a0e374ad8c37",
- "dist/2022-07-16/rust-std-beta-riscv32imac-unknown-none-elf.tar.gz": "402e022a2a7f1eb06e91ba883532b6354e94dbd1314a7ab406f37e56026e6097",
- "dist/2022-07-16/rust-std-beta-riscv32imac-unknown-none-elf.tar.xz": "97762f1261461a996626dc922f7d2b9791d38d216e871065d1c9f3fe21dd10e2",
- "dist/2022-07-16/rust-std-beta-riscv32imc-unknown-none-elf.tar.gz": "0999c8f23113ed6cdb98f0751779d90fe368d6b322a49506dd5df96e9c00ce0b",
- "dist/2022-07-16/rust-std-beta-riscv32imc-unknown-none-elf.tar.xz": "7b289c284b7b53f7f12b05f841be6d6024dc581bbe59abf07402d87f87b78231",
- "dist/2022-07-16/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.gz": "f6a71af82c15e20aa20881fdf0daa5815c2c9589c6fab1a69fade2380c9c740c",
- "dist/2022-07-16/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.xz": "3adc7fd340e08b482259eece4c1abc210ec32f97fe6d5fdf6847ddeebe7e8e10",
- "dist/2022-07-16/rust-std-beta-riscv64gc-unknown-none-elf.tar.gz": "2136b39139393e6b9454b0c84a0c25256a444a940b9a6c207fddc7ef2b25a22d",
- "dist/2022-07-16/rust-std-beta-riscv64gc-unknown-none-elf.tar.xz": "ec9f3f7c62dd6fcc5339579d5becd5e5542c0eb45b415b91a9a2b6ebde18bd7c",
- "dist/2022-07-16/rust-std-beta-riscv64imac-unknown-none-elf.tar.gz": "79e21a41c5400e646f4ff76d8c4c0bea12501338742ce800093ee1e06d0d6932",
- "dist/2022-07-16/rust-std-beta-riscv64imac-unknown-none-elf.tar.xz": "f686a014f19efed6d8357d0ff88702779a0132bc412cd1e6eb93b535ebf26686",
- "dist/2022-07-16/rust-std-beta-s390x-unknown-linux-gnu.tar.gz": "45a9dbab6143f10131f702c446768e542180572033811060947d4a1d79a7c2a0",
- "dist/2022-07-16/rust-std-beta-s390x-unknown-linux-gnu.tar.xz": "eefcfb4558b26145aebfafb193420972be8d8e6ca1b8d83a648ab9718cdbf97b",
- "dist/2022-07-16/rust-std-beta-sparc64-unknown-linux-gnu.tar.gz": "96e69f7db947588df72b49975b53387a02d102eb1295ecc8712f5cdcf0191ba7",
- "dist/2022-07-16/rust-std-beta-sparc64-unknown-linux-gnu.tar.xz": "10c2dfa886225fdcd991db70c0ae077432a9ace7f69c5464222555f1cbe9b51c",
- "dist/2022-07-16/rust-std-beta-sparcv9-sun-solaris.tar.gz": "254a8a83f480947878a377feb64803e6b396a967e07957513741aa7aa3ef6a07",
- "dist/2022-07-16/rust-std-beta-sparcv9-sun-solaris.tar.xz": "a18a04dfdcb6fecea8376908114690e0ca5ca54b2aced5e922f463799483d882",
- "dist/2022-07-16/rust-std-beta-thumbv6m-none-eabi.tar.gz": "643b8d6e5b17aa5ed0696550439039651e178695348dfb11567520e0439091a3",
- "dist/2022-07-16/rust-std-beta-thumbv6m-none-eabi.tar.xz": "9cb7f0543dfd4f13b6126a6de336a6b11eea9a241cdbbf00290ed0c7a1d331ea",
- "dist/2022-07-16/rust-std-beta-thumbv7em-none-eabi.tar.gz": "58d094491df31e051e9fc85d4376df165ef103651b676e494beba2b689382254",
- "dist/2022-07-16/rust-std-beta-thumbv7em-none-eabi.tar.xz": "5e44398411718fb4cd22bc13a5fd091adb23938c2010d45ce63ac0a547435406",
- "dist/2022-07-16/rust-std-beta-thumbv7em-none-eabihf.tar.gz": "186ac77a1844786df52e5325e9aacd519db8f61ab72cd08376e8af869ce71e22",
- "dist/2022-07-16/rust-std-beta-thumbv7em-none-eabihf.tar.xz": "737d50c6ad0f0918580b29bdf3cf811f43a49fc5fcfd3b4e5f0cfdfde4acbf15",
- "dist/2022-07-16/rust-std-beta-thumbv7m-none-eabi.tar.gz": "7e6bb04375764e3c80f2d477b2a982baa170339029a8c3f99caeefb280acd95e",
- "dist/2022-07-16/rust-std-beta-thumbv7m-none-eabi.tar.xz": "e15af6e720e2b19884a1bfa3b6c2d394082786bf95483b0962ed134d7787161c",
- "dist/2022-07-16/rust-std-beta-thumbv7neon-linux-androideabi.tar.gz": "80a32a6988b945861eb834f3bfc0cbbf594a0b2b7cb1594f150e7ac8f2919065",
- "dist/2022-07-16/rust-std-beta-thumbv7neon-linux-androideabi.tar.xz": "75f986807dbeb40418b049264334580cf0d324db80e3e86d047d65e6ebb50a2b",
- "dist/2022-07-16/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.gz": "d86a80418c9cc9b883faf2b5e681b530ea09c550fb39b9e558a381ab67d3f43f",
- "dist/2022-07-16/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.xz": "30af6048b67ee64c378250b23227383b799c598aa24e3a09cf50baa4e15a9833",
- "dist/2022-07-16/rust-std-beta-thumbv8m.base-none-eabi.tar.gz": "ed57999629478f3d1efd164249bb471eaf866a95da7c0916572bd0537f40c964",
- "dist/2022-07-16/rust-std-beta-thumbv8m.base-none-eabi.tar.xz": "232f3099d833785dc6e50dadb205ade5440e850ec24821cdd24a534a19b93cb1",
- "dist/2022-07-16/rust-std-beta-thumbv8m.main-none-eabi.tar.gz": "56ea2a0a2ff89efaeb791df36751cd6493161878e281d3dce507f9637044e304",
- "dist/2022-07-16/rust-std-beta-thumbv8m.main-none-eabi.tar.xz": "820b1c2fa96e952a09b32ba0a5a94239bf69ecde2bdcb769d073f35e5ee13383",
- "dist/2022-07-16/rust-std-beta-thumbv8m.main-none-eabihf.tar.gz": "a1b9d35ed7346f43025a354c38e5836340c1be3a9b2173845c91afe7bbfadfc4",
- "dist/2022-07-16/rust-std-beta-thumbv8m.main-none-eabihf.tar.xz": "e3da59132bdef040b4618037f9d7f0c38511701420a676c9d451544cbfda0ce4",
- "dist/2022-07-16/rust-std-beta-wasm32-unknown-emscripten.tar.gz": "e92dce094d5c503c3a66c7419f4b2b341a0647678596f6c5ec5ddebaa4107905",
- "dist/2022-07-16/rust-std-beta-wasm32-unknown-emscripten.tar.xz": "b7a2e4db89f9dde15b51dea0044b57204326898e351fcb45df1da31c5edbe929",
- "dist/2022-07-16/rust-std-beta-wasm32-unknown-unknown.tar.gz": "608834a5a7d60024e2f7275ac5615d7dc1c1723b2195695eb889dbd633a45e2c",
- "dist/2022-07-16/rust-std-beta-wasm32-unknown-unknown.tar.xz": "646cbf64202df1f11d829d371810867e12120e12266895125b53600e4d678d26",
- "dist/2022-07-16/rust-std-beta-wasm32-wasi.tar.gz": "b1802f8dd97e213466bdaaa769ef4b03ea1baf5cd14475edba8b70dd6736b855",
- "dist/2022-07-16/rust-std-beta-wasm32-wasi.tar.xz": "f47bf0b5aaea9d52deea681b85daab38920db504168fb9a0eeea161996eaf494",
- "dist/2022-07-16/rust-std-beta-x86_64-apple-darwin.tar.gz": "cd5be7559517ea844335c88e3cd5846990cad18bbb4dd96c1c1add6d873b5ef3",
- "dist/2022-07-16/rust-std-beta-x86_64-apple-darwin.tar.xz": "3e028523c2a23a5681b6a9f4ed4f4313bbc0295f3f0e986e0c6bffad69454368",
- "dist/2022-07-16/rust-std-beta-x86_64-apple-ios.tar.gz": "7c18b0d86b4cb7da00139112966e86de05da9286fea72458056dbf1607eab774",
- "dist/2022-07-16/rust-std-beta-x86_64-apple-ios.tar.xz": "4aeaf6925f7a591a7ff0449d98b1ee5b1fd2fbca93e8bfb7fd2b279ecd2ec2ed",
- "dist/2022-07-16/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.gz": "62ac06824cb70a0b02292ccdca9ae4e2660644fa9a0abb186c73d64e9632c733",
- "dist/2022-07-16/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.xz": "8642bd83f1bf709d38260ee54fbb4de679bbec802d5c72f09e1146e82195577a",
- "dist/2022-07-16/rust-std-beta-x86_64-fuchsia.tar.gz": "caf561a7b5efb474c9db48dd5ac3ceb32505f60813324b2665fadc639e6103e1",
- "dist/2022-07-16/rust-std-beta-x86_64-fuchsia.tar.xz": "c6481548b0ef6b9c4a82b1f697842cb7c38176acb06699d559c825243fbbaf4a",
- "dist/2022-07-16/rust-std-beta-x86_64-linux-android.tar.gz": "be110f47348bc63d27b541af4093167cd48d5f011897482ca7a940abcfeeb1a7",
- "dist/2022-07-16/rust-std-beta-x86_64-linux-android.tar.xz": "11ccae4e0bfc76df7bd33d858fe47ead9294cd0707aee3f42ac3683a140d583f",
- "dist/2022-07-16/rust-std-beta-x86_64-pc-solaris.tar.gz": "78d6662fbfb469c7cb0b2f381523ebab1b566edf2dfa676c8a509a6d584e17f2",
- "dist/2022-07-16/rust-std-beta-x86_64-pc-solaris.tar.xz": "034be03c974835fa0d2747364c8b26f50d83762316d4a266473972622e2627d6",
- "dist/2022-07-16/rust-std-beta-x86_64-pc-windows-gnu.tar.gz": "759eed3f19e2c8203a7b03ab90eedf4b09e0edfff9fea49bcb2fc795aef66a4f",
- "dist/2022-07-16/rust-std-beta-x86_64-pc-windows-gnu.tar.xz": "119c6fbaa021130baa881738164810d7829ee54234e8adb6e82f1f6cba9da876",
- "dist/2022-07-16/rust-std-beta-x86_64-pc-windows-msvc.tar.gz": "b0369c5804ab496b5ae9a2643f5da959e62cf574d394d3a74a06524816bd2fc6",
- "dist/2022-07-16/rust-std-beta-x86_64-pc-windows-msvc.tar.xz": "130b922369beb56a30666dfb6f36881105e5446284f196eef6817939f94f1b02",
- "dist/2022-07-16/rust-std-beta-x86_64-sun-solaris.tar.gz": "5405406252ab897de56c46023de48c08d03fce7791e7db06c009d10e4c9c03f3",
- "dist/2022-07-16/rust-std-beta-x86_64-sun-solaris.tar.xz": "b91c6f6dfbe142102a8d72b5c91f8efd1873c20e73e34d9240898a08f63d6be3",
- "dist/2022-07-16/rust-std-beta-x86_64-unknown-freebsd.tar.gz": "17526319a486038ef77e7a0f8c1ffbc6e43b4ac3eef4d14c4b70307cbd937c5e",
- "dist/2022-07-16/rust-std-beta-x86_64-unknown-freebsd.tar.xz": "8cccb4640373abd1f17418c5b7d5198e8da3af3886206dff559fa2e23c4994e2",
- "dist/2022-07-16/rust-std-beta-x86_64-unknown-illumos.tar.gz": "ff3f98720355eede902bc3c12d5ecdfc6e7f53b70133492e26b4cd464ff585f2",
- "dist/2022-07-16/rust-std-beta-x86_64-unknown-illumos.tar.xz": "73531fe83d87304fe54adee9ede87e82220afd4dcb5c1a27878a1d9dd7dce9d9",
- "dist/2022-07-16/rust-std-beta-x86_64-unknown-linux-gnu.tar.gz": "936855bb97c47c0978caa65748515e3e7550916beb5d06aa569dab6192738886",
- "dist/2022-07-16/rust-std-beta-x86_64-unknown-linux-gnu.tar.xz": "e8b95205019e5f73e86247da9f5dab22f8ceaa98f6afa8f0eb7c6d92a258b97e",
- "dist/2022-07-16/rust-std-beta-x86_64-unknown-linux-gnux32.tar.gz": "2f016727a0d761960923f4a83cce489d2f4d87b354352d109be1e89ad45f99e4",
- "dist/2022-07-16/rust-std-beta-x86_64-unknown-linux-gnux32.tar.xz": "16f0829deae2df1fee609dfae7ec51bbcb7da5a9dcfe48f4d517d07934463b42",
- "dist/2022-07-16/rust-std-beta-x86_64-unknown-linux-musl.tar.gz": "8bb4f4c9bb114cdee7c3d95c78e66f9c574ae47116b3aa0401712eb29c41461f",
- "dist/2022-07-16/rust-std-beta-x86_64-unknown-linux-musl.tar.xz": "8a4977f3bb54c0f260c4b41f2fc7bf0fb06fd69e6eb9a9c88c438274f7ea993d",
- "dist/2022-07-16/rust-std-beta-x86_64-unknown-netbsd.tar.gz": "2b361b36d6a6f917b17a92b68dc9fb80c05e0b90a1987f4761b05ecb970ef4c6",
- "dist/2022-07-16/rust-std-beta-x86_64-unknown-netbsd.tar.xz": "5a4069a5ee239d289e13f8071c3fab252dab944706c2e223f763107509730fda",
- "dist/2022-07-16/rust-std-beta-x86_64-unknown-none.tar.gz": "d4b0d375705732ac44da55e5272bde7c0756231bed205fabfa5b8b265e0d8e79",
- "dist/2022-07-16/rust-std-beta-x86_64-unknown-none.tar.xz": "5d4f05830dc0530d60e0d570e692b0c4d7ee48e68d4bb3838878fead474bc063",
- "dist/2022-07-16/rust-std-beta-x86_64-unknown-redox.tar.gz": "c43fb78286169bcdede9e092d84a9f2e7762ad67bdd2ed7a14d6d3234af52b9e",
- "dist/2022-07-16/rust-std-beta-x86_64-unknown-redox.tar.xz": "905d5a8f6f642a978e55afc45329f6b7b6083a34ec6f51de0bb854685c5e3add",
- "dist/2022-07-16/rustc-beta-aarch64-apple-darwin.tar.gz": "86afdc287964673c25d3c625b5bf03231d897d46fe8565e1078747e7b85bc627",
- "dist/2022-07-16/rustc-beta-aarch64-apple-darwin.tar.xz": "8cd87fd24927617793bb06edc581184edfc12de7c961f03a530aee7eb793166f",
- "dist/2022-07-16/rustc-beta-aarch64-pc-windows-msvc.tar.gz": "6c2858cc584d845ebcb8cc4dbadc5b0bf4e875dd0920b2d9106791b8bb7567e7",
- "dist/2022-07-16/rustc-beta-aarch64-pc-windows-msvc.tar.xz": "dde2c77b23b8ecedbec8427c3b8f6a889d96b053de74787a73faef366cdb30c1",
- "dist/2022-07-16/rustc-beta-aarch64-unknown-linux-gnu.tar.gz": "5ff5ae57cc7eacf26a3410c499d23e520ed9ef20f7aa50e77a3354a7bbed541f",
- "dist/2022-07-16/rustc-beta-aarch64-unknown-linux-gnu.tar.xz": "850f4456625e7ae545c3036338b5bdcb1982a2fca4d1664efc835630a7e42468",
- "dist/2022-07-16/rustc-beta-aarch64-unknown-linux-musl.tar.gz": "5409263cbb71867780c8a2bcce126665217632d8eb7e4dab95c199ebfee8755e",
- "dist/2022-07-16/rustc-beta-aarch64-unknown-linux-musl.tar.xz": "deeeff68790e4857d625fdc1e0ed430e4d31b4e5e87b5534d899cdf7fec2adf5",
- "dist/2022-07-16/rustc-beta-arm-unknown-linux-gnueabi.tar.gz": "0701e5f5d04db2cc677366ec769fa3f6c39351a9527f8493fd54d29086294a00",
- "dist/2022-07-16/rustc-beta-arm-unknown-linux-gnueabi.tar.xz": "a133838e0eb1d9177fe0c052667ba9820a6ba5cbba604a80ad732ca5c1e23846",
- "dist/2022-07-16/rustc-beta-arm-unknown-linux-gnueabihf.tar.gz": "9ad3ad6c0c27d50238f83821b526a1d6f598ff293a36381d0a8a28cbd0a7ab4e",
- "dist/2022-07-16/rustc-beta-arm-unknown-linux-gnueabihf.tar.xz": "3313866d0d78c82b0b571e889d6ed85fce80dc2ea3dcc495f4738672e8d3b972",
- "dist/2022-07-16/rustc-beta-armv7-unknown-linux-gnueabihf.tar.gz": "0459cf4a11cc6d41aa95d837b73a339fbf1c50ecfc078a95705c110d03a9c941",
- "dist/2022-07-16/rustc-beta-armv7-unknown-linux-gnueabihf.tar.xz": "16b092bd7fccc84d6776f8cf3794c302b258fe9b3bf2adcc2ba1551197d3ab92",
- "dist/2022-07-16/rustc-beta-i686-pc-windows-gnu.tar.gz": "c3c49711e23a87fb78d2a85d4838893963f151918464708f61cbd0a0ef8d6841",
- "dist/2022-07-16/rustc-beta-i686-pc-windows-gnu.tar.xz": "eac7e88ef96b4eb99d5f15e168c7b782f0c9bfced92e5852559414e4c95a18c4",
- "dist/2022-07-16/rustc-beta-i686-pc-windows-msvc.tar.gz": "fe6f0c952dccbe7262678615c8a850ce76f510295202427a16755005f3505744",
- "dist/2022-07-16/rustc-beta-i686-pc-windows-msvc.tar.xz": "bd596d7e1fac9b4e02a036aa1e59819317d210044b3298bf4ec3633817f2ec2b",
- "dist/2022-07-16/rustc-beta-i686-unknown-linux-gnu.tar.gz": "5dbbdd77e606ad28421a39d9ec95d2254e2658033247d94a733dec05a2368cb5",
- "dist/2022-07-16/rustc-beta-i686-unknown-linux-gnu.tar.xz": "f9471eb60265b18f755c76dc4786895804fdc2b0ed8c8c8e58a454dbd1eca3b3",
- "dist/2022-07-16/rustc-beta-mips-unknown-linux-gnu.tar.gz": "e4e8e67a0c4240ccb478631ee3b7a0fcc22d68b2adce26228f5fc9fff34dc03c",
- "dist/2022-07-16/rustc-beta-mips-unknown-linux-gnu.tar.xz": "c7879912b5b6bfbaea4b424562ac1174bab8e30a4d20b3a82291b606a5a5f09e",
- "dist/2022-07-16/rustc-beta-mips64-unknown-linux-gnuabi64.tar.gz": "3b437ea0fe1c9f52505cc7e5cfe2b3b103973e3ba3c132ba304d828c210e7eb1",
- "dist/2022-07-16/rustc-beta-mips64-unknown-linux-gnuabi64.tar.xz": "d1c144f58626f3b0df9a24ffe5db9b2df45a410071df551fec48e0a7097bb17a",
- "dist/2022-07-16/rustc-beta-mips64el-unknown-linux-gnuabi64.tar.gz": "364647a234f7d40095d38cf01fcbdf554128436829d2972cb22f91fde18b346a",
- "dist/2022-07-16/rustc-beta-mips64el-unknown-linux-gnuabi64.tar.xz": "fc2c9200111139a051c8e3bb41f936b2126d24ca91ba175d88de95d59b6e00da",
- "dist/2022-07-16/rustc-beta-mipsel-unknown-linux-gnu.tar.gz": "884a0da049f646196964f6cf93f03d9211e3864b39190432ee2e369c34051717",
- "dist/2022-07-16/rustc-beta-mipsel-unknown-linux-gnu.tar.xz": "d82cd504ff34e741c9cf246fd6d8829f8af74d36670de46daea858a2c282f286",
- "dist/2022-07-16/rustc-beta-powerpc-unknown-linux-gnu.tar.gz": "0fdd190eec39c72972d8d4df7fb59c77ffd9e9fad4d219264b6ceaa301c0250f",
- "dist/2022-07-16/rustc-beta-powerpc-unknown-linux-gnu.tar.xz": "e74704b5c21a77c3d1dd7f265a7f24e9f904405afc3170d5f3836c8d28105ee0",
- "dist/2022-07-16/rustc-beta-powerpc64-unknown-linux-gnu.tar.gz": "90c1480f585ad1d9e0c3b564f5eb87667eedf5992ce46f73d6462dbb9a136182",
- "dist/2022-07-16/rustc-beta-powerpc64-unknown-linux-gnu.tar.xz": "e5b3e75d5d85e84fbf8c0d4b8e1f4c20421e1d20c18805f413f785d594c14a4c",
- "dist/2022-07-16/rustc-beta-powerpc64le-unknown-linux-gnu.tar.gz": "5163f545aca9e56edb0510c30eb9343dbdd95ce3704677cdbebcb70947437838",
- "dist/2022-07-16/rustc-beta-powerpc64le-unknown-linux-gnu.tar.xz": "f6c61e0c2bb404f248986287dcf7f4bcf8458fd17e678bbb53c43ce5ef19d5eb",
- "dist/2022-07-16/rustc-beta-riscv64gc-unknown-linux-gnu.tar.gz": "fce64768b803f67470e093422926f44cf621eca5052eff4d9c6b89b94556b411",
- "dist/2022-07-16/rustc-beta-riscv64gc-unknown-linux-gnu.tar.xz": "e99f1ae947b812047c4367d87f0f4dde6581c0af02240625500b1ddc9133025e",
- "dist/2022-07-16/rustc-beta-s390x-unknown-linux-gnu.tar.gz": "c6bb4bd5eaea57d15dd995de614471aeaddd103158e609ecdf43177f1843c25b",
- "dist/2022-07-16/rustc-beta-s390x-unknown-linux-gnu.tar.xz": "8e54cc288f3bb2a268fe37f2815ce94c3810438aefdfab9dd679ef572dbc127b",
- "dist/2022-07-16/rustc-beta-x86_64-apple-darwin.tar.gz": "dc06d6cc19934b091cb3894c42debf6189f7b2d54162cc93418cb8851c967154",
- "dist/2022-07-16/rustc-beta-x86_64-apple-darwin.tar.xz": "2f177aa386c389ce18ec47495d5c48d5512bee00aed0e3dad53809fbdb81f55a",
- "dist/2022-07-16/rustc-beta-x86_64-pc-windows-gnu.tar.gz": "e6af40fc7d92ddfd3bdab6ed92b8bb614df2ef7158a8f59291593034191d483a",
- "dist/2022-07-16/rustc-beta-x86_64-pc-windows-gnu.tar.xz": "5c51250a55d9e424ced7f91a90a801d53bfcf489be033a06c15adfcd587f5e47",
- "dist/2022-07-16/rustc-beta-x86_64-pc-windows-msvc.tar.gz": "f4bc463f82baa6681ad7292c512836bde962743b32b28ba118c38622dc3478f4",
- "dist/2022-07-16/rustc-beta-x86_64-pc-windows-msvc.tar.xz": "a25e397cd228f44c0280f61621bdbab028fb07a20551a3c1b25606d0eefc4745",
- "dist/2022-07-16/rustc-beta-x86_64-unknown-freebsd.tar.gz": "27e0d39b8bdde40899a1486fc39b6bc612068dc4d4db65d52a4b3c85f03675e4",
- "dist/2022-07-16/rustc-beta-x86_64-unknown-freebsd.tar.xz": "74f59446e6e6b031fedd12d10380bd33c119b09d0d1435488008f104a4297a97",
- "dist/2022-07-16/rustc-beta-x86_64-unknown-illumos.tar.gz": "9b49259f9446ffdc510b80b3cb67084f006cbf86bc6c14e6a6a42128657773eb",
- "dist/2022-07-16/rustc-beta-x86_64-unknown-illumos.tar.xz": "2a5b5c0f33dcdf79afce7445d6dd0183ba95f898becfca6eace5858e6836706f",
- "dist/2022-07-16/rustc-beta-x86_64-unknown-linux-gnu.tar.gz": "b891c82a6acbb2ee5e3b46c4e5ebfc4a215e70415879425125934b7fa8c33329",
- "dist/2022-07-16/rustc-beta-x86_64-unknown-linux-gnu.tar.xz": "e33bf0cd9e7e50469c9cd98c9404aa7495268192e4be70117c75607a9a18bb95",
- "dist/2022-07-16/rustc-beta-x86_64-unknown-linux-musl.tar.gz": "f5ed5f80204fa0608e888750866b880575d9eba63bbcd69b71708713a27fe27c",
- "dist/2022-07-16/rustc-beta-x86_64-unknown-linux-musl.tar.xz": "3f69e388b687cbdafaf59ca3486eed4dda510652a8ee37fde9efeff096258801",
- "dist/2022-07-16/rustc-beta-x86_64-unknown-netbsd.tar.gz": "57eb4ebf820c11e5d4700f6c3ec414e6d2b70475f71579f854aec66650ab9eb3",
- "dist/2022-07-16/rustc-beta-x86_64-unknown-netbsd.tar.xz": "979c3d20834c4bdee5b47598fddc26c3e02edd7678ee34faf97ac5f11aa8314b",
- "dist/2022-07-21/rustfmt-nightly-aarch64-apple-darwin.tar.gz": "9099fe96569cf008c9bb92f86efe1773a1e6f8542e71af037727d411ca3e4c92",
- "dist/2022-07-21/rustfmt-nightly-aarch64-apple-darwin.tar.xz": "085c6086a977725738ee44c4e0b748be255847c740fbce4aec62519afa91c088",
- "dist/2022-07-21/rustfmt-nightly-aarch64-pc-windows-msvc.tar.gz": "c829b598f2a7d815ddb1772153aa847e5f1fe844710acc01e18f626d5af1daaf",
- "dist/2022-07-21/rustfmt-nightly-aarch64-pc-windows-msvc.tar.xz": "50d3336081798cf6dffa615e1217845b51f82017375b4b0cf18167a939de0a5c",
- "dist/2022-07-21/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.gz": "40a86effd1d5b60735d15c33090e31a0ed1cccdcca7cece013176071a90f3c93",
- "dist/2022-07-21/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.xz": "ee29ab772f2f24f7f4f8655cbab2a64ad7fd2253ce04a4a72c497cdd18fd71cc",
- "dist/2022-07-21/rustfmt-nightly-aarch64-unknown-linux-musl.tar.gz": "d739d788caf9190fccbab1a00e42f75bb7e10d94263b556578175bdd11826468",
- "dist/2022-07-21/rustfmt-nightly-aarch64-unknown-linux-musl.tar.xz": "9775c98de87876ade2a7896e0df6519334ffb21cca12f60afa1874105b7dc75b",
- "dist/2022-07-21/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.gz": "241d9983b1314829b9311bb7e1743e422b81d22342eed7216ba534788df77016",
- "dist/2022-07-21/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.xz": "df50d81cf63dfea4a17f32318d4b4111944323395641ad9f7c989f9f74dbd383",
- "dist/2022-07-21/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.gz": "1953f4f8c244c81e60a97c9480f78c0a3e0373c44ef7c188306ea26a6ff087e1",
- "dist/2022-07-21/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.xz": "296273dfe9ad0ebf0ef47bb0a566050f90ec235bdb3d7776371b0b249466764e",
- "dist/2022-07-21/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.gz": "da67ad4667d2b39862e21d43b9e0a99ad0bbd36ccc936779ed6dacb9b2fd17c2",
- "dist/2022-07-21/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.xz": "efc5eb6d3c6fabdb03b83c9e9215b13955f82ceec62255aafd78db0e28ba8421",
- "dist/2022-07-21/rustfmt-nightly-i686-pc-windows-gnu.tar.gz": "e603216f64f6fcf3ca21581dcdd283b41a1b6a59779c7760b8aa79b4c593e7e8",
- "dist/2022-07-21/rustfmt-nightly-i686-pc-windows-gnu.tar.xz": "7c5c47faf6f014b63e1193cbf27de51bec82e9811537a17cb9b4922b709618c8",
- "dist/2022-07-21/rustfmt-nightly-i686-pc-windows-msvc.tar.gz": "ac605732e74a1c344ea7c6ef84a6ca1823d3ed51024ef895ec9a181a6f91f8c3",
- "dist/2022-07-21/rustfmt-nightly-i686-pc-windows-msvc.tar.xz": "7044d68341f8ea2fef122600f3995fff681599dc1a545ab2b45d1b2302fd6436",
- "dist/2022-07-21/rustfmt-nightly-i686-unknown-linux-gnu.tar.gz": "b7d57d01a9985826333ecac8447e0a1a5a753cf0ed11770de70d47b59050215b",
- "dist/2022-07-21/rustfmt-nightly-i686-unknown-linux-gnu.tar.xz": "13076a20f555c18db2d38deaaf33aeaed0f27b8cb5a2962b26661b6989dc3a5f",
- "dist/2022-07-21/rustfmt-nightly-mips-unknown-linux-gnu.tar.gz": "c64ab15040368af0c595102a7232b405b1a52164fe39e06ba189b2a26c70fe9d",
- "dist/2022-07-21/rustfmt-nightly-mips-unknown-linux-gnu.tar.xz": "a05b3aa95231a7e6631f0da01869d8cb8b6e3a5c184eb411591583cc78cd3aaf",
- "dist/2022-07-21/rustfmt-nightly-mips64-unknown-linux-gnuabi64.tar.gz": "242650636f9b33adc71a8c1bba1dc3a2928ba7723c976ae5645428b47862c658",
- "dist/2022-07-21/rustfmt-nightly-mips64-unknown-linux-gnuabi64.tar.xz": "7a2a54f05cac08aa65645e099d2597504477bba269b6f74e99f2df397a660eaf",
- "dist/2022-07-21/rustfmt-nightly-mips64el-unknown-linux-gnuabi64.tar.gz": "2c3f944a0b8a5b06c4a341882934b737a451baf38f7a902f0794b0f41e1102e3",
- "dist/2022-07-21/rustfmt-nightly-mips64el-unknown-linux-gnuabi64.tar.xz": "506e4f89b5243b8c2f6709d69a8b8facad5d7a555b108bed4f689dbd3fe1e46e",
- "dist/2022-07-21/rustfmt-nightly-mipsel-unknown-linux-gnu.tar.gz": "fe3a12786f8eecf26213286045a69bc1046d7138a401511618b86b74a70eb66a",
- "dist/2022-07-21/rustfmt-nightly-mipsel-unknown-linux-gnu.tar.xz": "37409a8573c5d0c9ea1fd0a745990a4e85f325a87a25c9916dd25617b6059783",
- "dist/2022-07-21/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.gz": "e74050fa0288e7368a9e65f2739498f38ca9c91d36c519674e4590c17d86fcd7",
- "dist/2022-07-21/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.xz": "10da2c6d12e14f4a2c6c9a7f1d2c161a62e4f9956ed7ee100ba31fce9446ea78",
- "dist/2022-07-21/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.gz": "a0cf070555fed25a8aa9f20d704149936dca1ccb7c3aa55aabad2be84a7860f7",
- "dist/2022-07-21/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.xz": "f388ba16822251f2dff0d9fd837dc19c5ca181ebabc93ed81759530d07dce72f",
- "dist/2022-07-21/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.gz": "6056b5c1f46807fce83c4c3e2a443beb66b433e678fb090ca253aef5a87d2927",
- "dist/2022-07-21/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.xz": "642046b17142d6e9ecd207243ed82108088c941b04ee5d8f6b1371b07da60601",
- "dist/2022-07-21/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.gz": "600b5e7a11e3cb583fae2ef9f9dc784c2bef08e355da9e3a37204e0c81a63451",
- "dist/2022-07-21/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.xz": "a9019c838270635f2fe383da5b11fdef2c7b23f838bc5edee7ba5882e7102c63",
- "dist/2022-07-21/rustfmt-nightly-s390x-unknown-linux-gnu.tar.gz": "613539dc9a67c78216d8d11b0d9baf068d48c4067d628c8144bccec2d899afd1",
- "dist/2022-07-21/rustfmt-nightly-s390x-unknown-linux-gnu.tar.xz": "55d992631c567da8ea082ca6dfcfdbf4774374ec430050a16001def2221adafe",
- "dist/2022-07-21/rustfmt-nightly-x86_64-apple-darwin.tar.gz": "9bade75f59be530972a26618f4e283c89bda864cfd162f47c8d1782d31163148",
- "dist/2022-07-21/rustfmt-nightly-x86_64-apple-darwin.tar.xz": "39f21c72c31dc0cf945db142cead8aa8f9208769d8f4336905794ec52848e90e",
- "dist/2022-07-21/rustfmt-nightly-x86_64-pc-windows-gnu.tar.gz": "3b5cdcc58acad278a1b4eb84dc5aacd8eafe0bd2ac0ab62c5056c918661a9364",
- "dist/2022-07-21/rustfmt-nightly-x86_64-pc-windows-gnu.tar.xz": "159dd0daacf54993386b2d1cefab13354d9c7614983745d43c28a1a873fbe498",
- "dist/2022-07-21/rustfmt-nightly-x86_64-pc-windows-msvc.tar.gz": "cfef1baac5ef48912a3d30b3ba6513da50e6a35d1ad8687452dfe64e671effc7",
- "dist/2022-07-21/rustfmt-nightly-x86_64-pc-windows-msvc.tar.xz": "8c72ca088ae104dd3cd1ce711e083a1816d16876ddd1a07af983d9c22cec1a33",
- "dist/2022-07-21/rustfmt-nightly-x86_64-unknown-freebsd.tar.gz": "fdecac3b5e42523e9f5200080f682e3b557b6820ae0f67a02620e1d1fba6f571",
- "dist/2022-07-21/rustfmt-nightly-x86_64-unknown-freebsd.tar.xz": "cbf56b942479ee95c89e14b060765ab8e21b2152b2c3e02ffb47957e37cec4cf",
- "dist/2022-07-21/rustfmt-nightly-x86_64-unknown-illumos.tar.gz": "309be4a29a875ba17ed14e351a6aff7a649e0e6897f3d2c3394f2f2ae966a275",
- "dist/2022-07-21/rustfmt-nightly-x86_64-unknown-illumos.tar.xz": "72e6bfd09cb22f8400dbef4017cd09deb2881cdf67df61d4e4d2d2ed5221a683",
- "dist/2022-07-21/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.gz": "d40edc2217657dedee45336aad31289190a7da43bc5620b5d36b7dc0fce1f211",
- "dist/2022-07-21/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.xz": "1df1787f682e9a8bd97a054f76094281fccd4d321c3067e2600860327dd088e3",
- "dist/2022-07-21/rustfmt-nightly-x86_64-unknown-linux-musl.tar.gz": "91ed27676b13193eecb93839c0c748e667e869f091de88cea4183c51870efbe8",
- "dist/2022-07-21/rustfmt-nightly-x86_64-unknown-linux-musl.tar.xz": "ccb0245ac982c34c9db9f6ffc3c30769e2b62637a18d88dc30a4ed3c1922fa7e",
- "dist/2022-07-21/rustfmt-nightly-x86_64-unknown-netbsd.tar.gz": "54344a42f2fca291c0c10f84386135e2797c9b81519eab0c6db633a95c109f20",
- "dist/2022-07-21/rustfmt-nightly-x86_64-unknown-netbsd.tar.xz": "4a276eac1bdace68484b49104b8bb2c48f93a775404f2bd29e9c3d4c6ce7367f"
+ "dist/2022-08-09/cargo-beta-aarch64-apple-darwin.tar.gz": "5d9f0ee2de50a18124fd506f493cbdf6cb6385944d32aca1aca9dcdf15bdef4d",
+ "dist/2022-08-09/cargo-beta-aarch64-apple-darwin.tar.xz": "683e8546ab86d98ec84204cdcdd2192d19a98c42c13bf0c69697865641238001",
+ "dist/2022-08-09/cargo-beta-aarch64-pc-windows-msvc.tar.gz": "fb2a95793d79e04201dcb38fb5ccdb86f1c74503b181a0b3fce0f332e3380bec",
+ "dist/2022-08-09/cargo-beta-aarch64-pc-windows-msvc.tar.xz": "5b1b826315990487dc0afe561fecd7f937d82bc8d2898742592349c9993cb3c8",
+ "dist/2022-08-09/cargo-beta-aarch64-unknown-linux-gnu.tar.gz": "23d20d9078154f6f03b3b056607b804ce3e049dfe4d949ccf430556c2f8e79b1",
+ "dist/2022-08-09/cargo-beta-aarch64-unknown-linux-gnu.tar.xz": "d7a9283bf838c1182e6cc8904b6b464cd9c1dd342078b2447309797868aec7ff",
+ "dist/2022-08-09/cargo-beta-aarch64-unknown-linux-musl.tar.gz": "fb82a87e759d5ab3536a8edba682793653f51c15d8f27a874ecbff11c991b1fc",
+ "dist/2022-08-09/cargo-beta-aarch64-unknown-linux-musl.tar.xz": "21de23c600646a3d5a9421761c0411d7e173876278548c42d6a8794abfc5d3d2",
+ "dist/2022-08-09/cargo-beta-arm-unknown-linux-gnueabi.tar.gz": "d931162577c04807b093d6cedcca989315b15b48f153c790f8ee2ce3edf479dd",
+ "dist/2022-08-09/cargo-beta-arm-unknown-linux-gnueabi.tar.xz": "797752acf6d0b5814ff1c6e7dd5e54fec0716677c4a11f03143c6e769ed34b1f",
+ "dist/2022-08-09/cargo-beta-arm-unknown-linux-gnueabihf.tar.gz": "f080f5f486cbfbd09206cca7b70cb051da5e5a68914227a58ee81ecb5ed19c48",
+ "dist/2022-08-09/cargo-beta-arm-unknown-linux-gnueabihf.tar.xz": "79964e35d780df520ace77ec8035652571709620ba49f14ac7bc59008fd712f8",
+ "dist/2022-08-09/cargo-beta-armv7-unknown-linux-gnueabihf.tar.gz": "339b969dcf283d0cedd0ffea09d534994c5bf588977ecfde61ce87e64090f70d",
+ "dist/2022-08-09/cargo-beta-armv7-unknown-linux-gnueabihf.tar.xz": "601b6b0f58652434d888320851867b9188cb5a99b5f18358b0d7376dd98d4a0a",
+ "dist/2022-08-09/cargo-beta-i686-pc-windows-gnu.tar.gz": "1c9944d71ff7ed9cd40be1df8fc828e7faa4f5496d917dc6ccc94a1b31839a12",
+ "dist/2022-08-09/cargo-beta-i686-pc-windows-gnu.tar.xz": "4e3fc72b845b821e3aa1193250a10d494592f3e0917c7716b5bd963d0ad08b73",
+ "dist/2022-08-09/cargo-beta-i686-pc-windows-msvc.tar.gz": "80559b267ab936cb08a7ef51087e63b61a215df64fa9f5254809705fa31ea3a6",
+ "dist/2022-08-09/cargo-beta-i686-pc-windows-msvc.tar.xz": "aee6122d25a0bf7e083b45e622858acf34be3e17a1f9964a2f0d9fc7dfdbe164",
+ "dist/2022-08-09/cargo-beta-i686-unknown-linux-gnu.tar.gz": "5e1f2c32adbdde68b7135d1e4c358076f5dd872c935ac1bbdcbfda0ff43e061f",
+ "dist/2022-08-09/cargo-beta-i686-unknown-linux-gnu.tar.xz": "f0e6acd5158430866ad0bed435a7e0dbd9f35130b4805b990050b3d9751b4416",
+ "dist/2022-08-09/cargo-beta-mips-unknown-linux-gnu.tar.gz": "99b71c9001b65408f42e65cf481a905bc30f77edc96401691fb9b122a20009fb",
+ "dist/2022-08-09/cargo-beta-mips-unknown-linux-gnu.tar.xz": "08d1f3824354af35fb90d6563a7a51775ff9574a9ffe0c87e897e377be778598",
+ "dist/2022-08-09/cargo-beta-mips64-unknown-linux-gnuabi64.tar.gz": "7dd3dc44fd37af40e587dba68d973b9d2cf40a939a97605a6adee5ba0f589215",
+ "dist/2022-08-09/cargo-beta-mips64-unknown-linux-gnuabi64.tar.xz": "2f638fc21bb6e11fd59ff07d66a1012d3336d6dbd5b73b2c42461f84415e333d",
+ "dist/2022-08-09/cargo-beta-mips64el-unknown-linux-gnuabi64.tar.gz": "ade7f1ba6f19382980b0a6cbe3e8035932a60c898f7141782921d22398b1cf03",
+ "dist/2022-08-09/cargo-beta-mips64el-unknown-linux-gnuabi64.tar.xz": "2fe5d3b4102320fb1e36198e8d6e43d201986a2c58e4ad45fc2acb23865cf09f",
+ "dist/2022-08-09/cargo-beta-mipsel-unknown-linux-gnu.tar.gz": "c99aa42005094a65bbeb41deb3499a2fd46032296f6509fd1bf108f7d4cbdd04",
+ "dist/2022-08-09/cargo-beta-mipsel-unknown-linux-gnu.tar.xz": "7c65e8e6d76cab786f628e4ca02b6af47f6c2c4a36123ee7b8fc059309ce6039",
+ "dist/2022-08-09/cargo-beta-powerpc-unknown-linux-gnu.tar.gz": "b7b98621ef835f6108c0d1ec60c88d66b462a3daf62ddfc796d31f4e09f7baca",
+ "dist/2022-08-09/cargo-beta-powerpc-unknown-linux-gnu.tar.xz": "f85473a1d6b33d9b865a6532ea444415c7cfaa3f76af39d637619ffdddd0c00b",
+ "dist/2022-08-09/cargo-beta-powerpc64-unknown-linux-gnu.tar.gz": "e783ea66457a0aff31489cd42f549a2c9c33cbb2ca0aa253575a59c9de7f73f4",
+ "dist/2022-08-09/cargo-beta-powerpc64-unknown-linux-gnu.tar.xz": "d90a02cb425320fb5a5b163d87ec03726159994af31b32954c91b1cb9eb3ebf4",
+ "dist/2022-08-09/cargo-beta-powerpc64le-unknown-linux-gnu.tar.gz": "ff1fda58f7bdb9df563172388f66f787a60f75bdd169ef8d2c791b27bbd8c6ce",
+ "dist/2022-08-09/cargo-beta-powerpc64le-unknown-linux-gnu.tar.xz": "df740d61415bf15c62f9656932370e08fea5a289ac25bec78a626e771d24ab7f",
+ "dist/2022-08-09/cargo-beta-riscv64gc-unknown-linux-gnu.tar.gz": "019dfff6fef8c7714dd19c64a5bb408b2b5063367ec1aa8a72960316aa880834",
+ "dist/2022-08-09/cargo-beta-riscv64gc-unknown-linux-gnu.tar.xz": "f8d025d2943b76d665500c9c72aab18a63ecd137e07c10d1463f1905b4274573",
+ "dist/2022-08-09/cargo-beta-s390x-unknown-linux-gnu.tar.gz": "c379f3c122a9df41b66f13ca3dcb79feb9ae68798c9704dac3018d85ec96d895",
+ "dist/2022-08-09/cargo-beta-s390x-unknown-linux-gnu.tar.xz": "69bd9bd12f4386c831aaa8e1fac8edf1a0e618d1f6e0e4bcb7be16f1eeb08d81",
+ "dist/2022-08-09/cargo-beta-x86_64-apple-darwin.tar.gz": "d74acf4f57681527af3a2c469e916bd9dc1ecdb591e16657757db493984de07a",
+ "dist/2022-08-09/cargo-beta-x86_64-apple-darwin.tar.xz": "00201568ce4b95c6618389ec86e00677a27435276dd1bec16fea44b87a2dce4b",
+ "dist/2022-08-09/cargo-beta-x86_64-pc-windows-gnu.tar.gz": "3d049963cdda9755e524443a04b0b9c5566cb0e58dc61e13779484d92c3e0f69",
+ "dist/2022-08-09/cargo-beta-x86_64-pc-windows-gnu.tar.xz": "c8f0c13771e010ed85002ee10e44ad7c0b21ce2ddd105c9b90fbe1896d0687f0",
+ "dist/2022-08-09/cargo-beta-x86_64-pc-windows-msvc.tar.gz": "796d9da5a59c984a5a78afcfce762134e3a72e52525d0150ebe4bb29d207bd00",
+ "dist/2022-08-09/cargo-beta-x86_64-pc-windows-msvc.tar.xz": "1ec2764428d4df9355380444158aaa2947c4fe00708e7a30bc6978433621d120",
+ "dist/2022-08-09/cargo-beta-x86_64-unknown-freebsd.tar.gz": "14643490b1259120b14a7be84942bfd324fdf03dcf473f33f7ae2466fb99f60b",
+ "dist/2022-08-09/cargo-beta-x86_64-unknown-freebsd.tar.xz": "3af267ab65b3c61b0184f8fb5b5cc5fb61688f9b668654986f30d3a794d9a1a6",
+ "dist/2022-08-09/cargo-beta-x86_64-unknown-illumos.tar.gz": "5b84826e0e68b6f9769ef7d00b4b1225cb1a4dde1b41f5b6021feb34e7376c63",
+ "dist/2022-08-09/cargo-beta-x86_64-unknown-illumos.tar.xz": "a1dde17fd13bfb626acd0ae65d88c440a3172e1fdb20aeefda3a205bad71d703",
+ "dist/2022-08-09/cargo-beta-x86_64-unknown-linux-gnu.tar.gz": "fedfd6a7b8156de19ed2d6b8f354affc4120fe311874e6563b9620634a5d962b",
+ "dist/2022-08-09/cargo-beta-x86_64-unknown-linux-gnu.tar.xz": "8701ba8c8fcf21623a690d3b7c00d50fc9949035af5aee092ff1239bed4a9784",
+ "dist/2022-08-09/cargo-beta-x86_64-unknown-linux-musl.tar.gz": "beac64aa92687f975b3a0d5265d7c79ef3962c1d0f0e196296f67bf8e2b803d0",
+ "dist/2022-08-09/cargo-beta-x86_64-unknown-linux-musl.tar.xz": "8b50c03102cfdf5ffff5fa7b51b0a4d159e24671be5430c77c07256e54a4fd12",
+ "dist/2022-08-09/cargo-beta-x86_64-unknown-netbsd.tar.gz": "dde29de6d56f02f5cdf35b96287e404ceed85372c3c671ee54972255369470fe",
+ "dist/2022-08-09/cargo-beta-x86_64-unknown-netbsd.tar.xz": "7e4d07676c4b33af0303436442dc763623784ed20293ed262780267b01843949",
+ "dist/2022-08-09/rust-std-beta-aarch64-apple-darwin.tar.gz": "63526962ddd66cd6b60f5bb348861caab7a78c7d80515baf4397cab857258d71",
+ "dist/2022-08-09/rust-std-beta-aarch64-apple-darwin.tar.xz": "64ba52408086b6c7e3578e2ded98528fd63466ec8d7f86045b55a575e0ca780b",
+ "dist/2022-08-09/rust-std-beta-aarch64-apple-ios-sim.tar.gz": "261109cb02193cfa113697c9d769fcd4d4e265b01dbb4ca0bfa0e0d62f64c71e",
+ "dist/2022-08-09/rust-std-beta-aarch64-apple-ios-sim.tar.xz": "7f2182b749a8980c2e7b4f31e5a8c72b8a9df8dd2552cda29d061e2236acc589",
+ "dist/2022-08-09/rust-std-beta-aarch64-apple-ios.tar.gz": "5abe9df533e7bfd62586483f20a1911be5eede5da6114b53b2a000c110e35768",
+ "dist/2022-08-09/rust-std-beta-aarch64-apple-ios.tar.xz": "2898b8ad95c6a67c2c296c4698acd043cadcb3a2b0449fb7515bfeb48db69a70",
+ "dist/2022-08-09/rust-std-beta-aarch64-fuchsia.tar.gz": "9f86fcd871ddef0fb86cdfb0084d1bf6fa150bb7cb4dfe3fcade13b75beea5a6",
+ "dist/2022-08-09/rust-std-beta-aarch64-fuchsia.tar.xz": "4aa91e4f7f3589085c2da45de78a16c48cfe9dd47541928db87ee964c3406b53",
+ "dist/2022-08-09/rust-std-beta-aarch64-linux-android.tar.gz": "910f4c1ad41d74306e7fdae43c8d04e7fc47724ae84b9276f2d264fbdf2b70f1",
+ "dist/2022-08-09/rust-std-beta-aarch64-linux-android.tar.xz": "cd60ac333fd684cb730c134cf5a037718254afb9aa65528b2463d76a138f07f7",
+ "dist/2022-08-09/rust-std-beta-aarch64-pc-windows-msvc.tar.gz": "39740739479c12203c9b6ae7c72f0e542c92750e08b2ca66c5e96355f1eea61f",
+ "dist/2022-08-09/rust-std-beta-aarch64-pc-windows-msvc.tar.xz": "1c7fb416b404c401f34d4461c61c95ffbaa5b50d8c95d090485aabe12cc78a0c",
+ "dist/2022-08-09/rust-std-beta-aarch64-unknown-linux-gnu.tar.gz": "8cd2b395607ba16cac4a4fb85f1c5ccf9626849a8e11dc66e911053a6cd1df1b",
+ "dist/2022-08-09/rust-std-beta-aarch64-unknown-linux-gnu.tar.xz": "c7ef35d4bb2ab6b8ad762349821b6e076851bd5b51dddb7a3b1678b78e21cb42",
+ "dist/2022-08-09/rust-std-beta-aarch64-unknown-linux-musl.tar.gz": "6410dc79e6e00eca4e483b438ef8a314a55ea6857c618efd50a32a2f95195df8",
+ "dist/2022-08-09/rust-std-beta-aarch64-unknown-linux-musl.tar.xz": "4d674cbb7d417944a1aaaa23e8c654ac9276529fed3639c75421e1de1e7bfcc2",
+ "dist/2022-08-09/rust-std-beta-aarch64-unknown-none-softfloat.tar.gz": "1719104655a62e8300df06fb4636543532821c0ac43dcf90435d5fbbf39c12c1",
+ "dist/2022-08-09/rust-std-beta-aarch64-unknown-none-softfloat.tar.xz": "bf3c12dae8fee831402f9700295d9a6718d6a6046a7e5a0d0748c3f2e3d82224",
+ "dist/2022-08-09/rust-std-beta-aarch64-unknown-none.tar.gz": "727621bd08ad0e879a79635fb00c187de6d23e0291143b494d3965cacb35d358",
+ "dist/2022-08-09/rust-std-beta-aarch64-unknown-none.tar.xz": "6b152098c76b2a3367dad676e4c3d328e5d5c89c95504b041e1997e5d141404a",
+ "dist/2022-08-09/rust-std-beta-arm-linux-androideabi.tar.gz": "c78d9c97e742ef1777679743765de5d475dffe62ea9b60efe2025eb91ba7ba5c",
+ "dist/2022-08-09/rust-std-beta-arm-linux-androideabi.tar.xz": "1029382048bce0b8e556b87008821f8b4c5c92e30b340c9a8086e32a8ca7f105",
+ "dist/2022-08-09/rust-std-beta-arm-unknown-linux-gnueabi.tar.gz": "d4b8bb607968ca49d840c1835fc56e92006dd186c7ed71663a23b7495fa392e9",
+ "dist/2022-08-09/rust-std-beta-arm-unknown-linux-gnueabi.tar.xz": "562dcbfb8ddd31e64939844055c3dbd87a4c04065ad34dbe3a2d87136c0bb4b4",
+ "dist/2022-08-09/rust-std-beta-arm-unknown-linux-gnueabihf.tar.gz": "1d8e8d87ce8f1ee5e8cb946c8b7a92e6f4a56ddd6b3afd1c646e4d5cdb703608",
+ "dist/2022-08-09/rust-std-beta-arm-unknown-linux-gnueabihf.tar.xz": "ce8edce3a2976694a8ca0cff0b296b331f64e0afa6b5cb107bf03e2aff5949c1",
+ "dist/2022-08-09/rust-std-beta-arm-unknown-linux-musleabi.tar.gz": "d57aff420435c76ff8bfaaaa8d94bce62d96299a2a0158b67b9fe914695cc188",
+ "dist/2022-08-09/rust-std-beta-arm-unknown-linux-musleabi.tar.xz": "7eecf0facd3f2dd236e5f731eaf3fbc51b46d1a039f762f5bb42aabd0ab21c00",
+ "dist/2022-08-09/rust-std-beta-arm-unknown-linux-musleabihf.tar.gz": "6b6341eeca9a48e1c15b03501428ebdd2f591f4196c50d988408a1c591152fb0",
+ "dist/2022-08-09/rust-std-beta-arm-unknown-linux-musleabihf.tar.xz": "019e36e7c8855ef9d1277d4f5388862412c6d49e7f16d6808d3a6f69c60e5030",
+ "dist/2022-08-09/rust-std-beta-armebv7r-none-eabi.tar.gz": "41b1cfbcfd16061d52413e0bf2503756ffbe819b4ef2d81f8570e477e0b5893b",
+ "dist/2022-08-09/rust-std-beta-armebv7r-none-eabi.tar.xz": "209828e95d236ee218a10f468b12d64e4f4bb773a0cbfc247e6f54c2aacdc8a5",
+ "dist/2022-08-09/rust-std-beta-armebv7r-none-eabihf.tar.gz": "762a5764e926cb081062040cc4f43f8653eab007ac9cb8600751c0f364f17639",
+ "dist/2022-08-09/rust-std-beta-armebv7r-none-eabihf.tar.xz": "eb9b66ad16ff5c7427112ed5cf73498a02694b7b3af37220e3160bb6a16eca1c",
+ "dist/2022-08-09/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.gz": "369b3afe600692f552f7d0bdd310c7b254f8745948e5a4ffff7c5fccf0873ce4",
+ "dist/2022-08-09/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.xz": "2cdeb7b58e979bec71aa0a67a95ede5b55ab6ac295b24b08c67e651c4a76b13a",
+ "dist/2022-08-09/rust-std-beta-armv5te-unknown-linux-musleabi.tar.gz": "1a31c291792ba44053c9701d8e665c62155cb319b371359c7f0f9b5b81269f6b",
+ "dist/2022-08-09/rust-std-beta-armv5te-unknown-linux-musleabi.tar.xz": "54b17f4959cff54daf926f33dad8141663366856f691f4ca1015fedf36720022",
+ "dist/2022-08-09/rust-std-beta-armv7-linux-androideabi.tar.gz": "77ca2251056b76db72b9e8795dfc1b9583544f35dd067435128b2336b33aa892",
+ "dist/2022-08-09/rust-std-beta-armv7-linux-androideabi.tar.xz": "888b80410a8f9f1f85ec379c4e5490fc18bfb3f7e4954fa66f9b9c27ea92d121",
+ "dist/2022-08-09/rust-std-beta-armv7-unknown-linux-gnueabi.tar.gz": "3b8132040574da39cafbf48cc1e2535ab1c52c51ac2968aaf167911bb4bab648",
+ "dist/2022-08-09/rust-std-beta-armv7-unknown-linux-gnueabi.tar.xz": "915acd9a715cb25db4e899315afbb2b97ad34aee52a7f4536b4e684295e93e8b",
+ "dist/2022-08-09/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.gz": "9a1e59513f6812f631fa4926ea794b05524e58cd4d36a55b7a4e286b2e7bd506",
+ "dist/2022-08-09/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.xz": "017892f81ce10323b76dd32347d5ba921003177fd95e5d4b4972ad4e84e699c8",
+ "dist/2022-08-09/rust-std-beta-armv7-unknown-linux-musleabi.tar.gz": "3a7b2f2c4d06135a9ff3931a1a9c0f4431bb3a31763501bbad1dbfb85849e681",
+ "dist/2022-08-09/rust-std-beta-armv7-unknown-linux-musleabi.tar.xz": "6226c7228337739435cd7194fe3c233250fb2eb8df4dd16c9ef637b2d91c1807",
+ "dist/2022-08-09/rust-std-beta-armv7-unknown-linux-musleabihf.tar.gz": "48b626650f72a7e3885ea2aabbb8c520b079ebda0f798f685392501f1ef7fd79",
+ "dist/2022-08-09/rust-std-beta-armv7-unknown-linux-musleabihf.tar.xz": "627a0be5e0059cc07a4bfd99a0f70e009367c7be6ea45eb4ac0f8554680309e4",
+ "dist/2022-08-09/rust-std-beta-armv7a-none-eabi.tar.gz": "2489ef3102a8b0ba9885c092309a2e7deaf65721c934a83259fa7f7698440638",
+ "dist/2022-08-09/rust-std-beta-armv7a-none-eabi.tar.xz": "0e43df943f9550e374ba9334a0bd68f3bd107dc68ee8012f92357aaa0bf3851e",
+ "dist/2022-08-09/rust-std-beta-armv7r-none-eabi.tar.gz": "edb09fe24634386fe335685bbced045cd7448d1aad520f1cbaa4f0d38f3d38a1",
+ "dist/2022-08-09/rust-std-beta-armv7r-none-eabi.tar.xz": "2b170a322d07da39e949047871dd28444feaf49d09c901fbdd4015f00e456415",
+ "dist/2022-08-09/rust-std-beta-armv7r-none-eabihf.tar.gz": "82a69f097820c70c0fdc9b5f22b5378ab1d70d3d35bfec0ebab8b30ad7903178",
+ "dist/2022-08-09/rust-std-beta-armv7r-none-eabihf.tar.xz": "0301f9984effc3b186531aacb182e65fb57519c5ebd80f445c7346db27dfcc39",
+ "dist/2022-08-09/rust-std-beta-asmjs-unknown-emscripten.tar.gz": "47bc8975498b6f6afdce3ef7d2d8d4b239b6219f5e4bae9841a82587e1279415",
+ "dist/2022-08-09/rust-std-beta-asmjs-unknown-emscripten.tar.xz": "0806ef9782068d292106f3fce8b7bf879931fb89efc5e832d85f82bbffa99489",
+ "dist/2022-08-09/rust-std-beta-i586-pc-windows-msvc.tar.gz": "fb11022f5410c508936617b337d8940d82431544f77366ba6dbc3da81172bd21",
+ "dist/2022-08-09/rust-std-beta-i586-pc-windows-msvc.tar.xz": "326bc6a7dfe216b03222b187ed424ca6b83325f9a91e0b873d9294c713040a37",
+ "dist/2022-08-09/rust-std-beta-i586-unknown-linux-gnu.tar.gz": "0a608449de9eca7fbb421263fee19d22a3950f68dee80ca343c8704b2a9fcefb",
+ "dist/2022-08-09/rust-std-beta-i586-unknown-linux-gnu.tar.xz": "ca980e9d255d4444a329983565eb15807a26c0cdb48bfe763f9fdee061d8a9e4",
+ "dist/2022-08-09/rust-std-beta-i586-unknown-linux-musl.tar.gz": "db8c6517bb71bf49470b87cc1c9bd180c0421475bad04917be988c0933620db6",
+ "dist/2022-08-09/rust-std-beta-i586-unknown-linux-musl.tar.xz": "2feccd2d2ec54e25ac36ec2b9ff823887d353c9ca1106a29f8ca0f33f2e5d08a",
+ "dist/2022-08-09/rust-std-beta-i686-linux-android.tar.gz": "0ce00226f5aa2165d043108650e7444e165ae80c985c62f953b46fd680946b5a",
+ "dist/2022-08-09/rust-std-beta-i686-linux-android.tar.xz": "e591b8ae11fa7b6b8907d598e159c8795e4c3ff9c2c55e65773c29e488f64550",
+ "dist/2022-08-09/rust-std-beta-i686-pc-windows-gnu.tar.gz": "51fa05e5fb2d0d310b97c9e255ea3bc5ecb185093013406588cc96fddba18788",
+ "dist/2022-08-09/rust-std-beta-i686-pc-windows-gnu.tar.xz": "64d87c682eb1a2e0b8abd393358e1880016803bb7da699f2d239ad2d59e0eb0c",
+ "dist/2022-08-09/rust-std-beta-i686-pc-windows-msvc.tar.gz": "e3c2df5572996ade55a9af5b5b54a84fc0ff2edfcad164f57852ab0d3695d938",
+ "dist/2022-08-09/rust-std-beta-i686-pc-windows-msvc.tar.xz": "2991215756373d253ffd27a8f650613a5f2bb636adf263b664741772c594241a",
+ "dist/2022-08-09/rust-std-beta-i686-unknown-freebsd.tar.gz": "bf82e2e7734304f12d3ed5db591ece38a1078b575d92aab8f45328d087cf56ba",
+ "dist/2022-08-09/rust-std-beta-i686-unknown-freebsd.tar.xz": "73a3b79fe72e835a8b7dfdaba6a1b9c5ee8dde25534fcc520b0ee80a7853b31a",
+ "dist/2022-08-09/rust-std-beta-i686-unknown-linux-gnu.tar.gz": "74e23ff14e240e935f630e19467bbc9e1b02e9962313dc74f8c444c96bcbfb2e",
+ "dist/2022-08-09/rust-std-beta-i686-unknown-linux-gnu.tar.xz": "987003e5b23308f31f613a5a133466cd045c05a5998ab29e4d3d8ef15a8342d9",
+ "dist/2022-08-09/rust-std-beta-i686-unknown-linux-musl.tar.gz": "1c76bac0701c3f9352f4439d2daecb219c08964c6a48ceb212520b4a8e532e02",
+ "dist/2022-08-09/rust-std-beta-i686-unknown-linux-musl.tar.xz": "7007e60d8ba5e9e40f6aefa248b4881057a9b9a73aa9e7ff0c67a36de7748be3",
+ "dist/2022-08-09/rust-std-beta-mips-unknown-linux-gnu.tar.gz": "0f6ca4637da137235a3e9315691f1b5c0afc2f853a855458ad6d10ea59ef8579",
+ "dist/2022-08-09/rust-std-beta-mips-unknown-linux-gnu.tar.xz": "778557cf1c57ada5c1a64ecd58db3a49e8f874217664d53a8be0cfb89b031980",
+ "dist/2022-08-09/rust-std-beta-mips-unknown-linux-musl.tar.gz": "cbe799d70ca9a24645187d61198c40d495aeed8ef037570ed3cad95b898f6c82",
+ "dist/2022-08-09/rust-std-beta-mips-unknown-linux-musl.tar.xz": "ab37bff0f1c90a6adb9d603041d5fbe7c94dccfa05a6171145c41335350d02a9",
+ "dist/2022-08-09/rust-std-beta-mips64-unknown-linux-gnuabi64.tar.gz": "3e5aa74f970a70614751d258b7958696457b03c3f8c6eb2b8e61f3395d9f9169",
+ "dist/2022-08-09/rust-std-beta-mips64-unknown-linux-gnuabi64.tar.xz": "e32f82fa27968b9f9cc0bad083daae95cc21bc7f56b6fed8e57de39200398248",
+ "dist/2022-08-09/rust-std-beta-mips64-unknown-linux-muslabi64.tar.gz": "29247f72e5d5563dbfaff65876cd1181943c57121e27a979c11005734825de4f",
+ "dist/2022-08-09/rust-std-beta-mips64-unknown-linux-muslabi64.tar.xz": "1835664e58cd35261f7387be0746bfd821a8d8108ef8f26dc68db1b4886cc6b6",
+ "dist/2022-08-09/rust-std-beta-mips64el-unknown-linux-gnuabi64.tar.gz": "eb6826841be8177bead8edf3d06892219fe7e898e541d2a76539e49c7cf2caa7",
+ "dist/2022-08-09/rust-std-beta-mips64el-unknown-linux-gnuabi64.tar.xz": "25c2801f324985094cf3aa9aa56d88e2c73bcd1f7849fdbfd11032fb9d853bc9",
+ "dist/2022-08-09/rust-std-beta-mips64el-unknown-linux-muslabi64.tar.gz": "573f981b5e197ef337812fb3bcc4ee513121067968d3d33e369426ec51cfdb8e",
+ "dist/2022-08-09/rust-std-beta-mips64el-unknown-linux-muslabi64.tar.xz": "da6d57cff4999bec0e4249c0b1f1048eae925e793149c60f044b257f306d26bf",
+ "dist/2022-08-09/rust-std-beta-mipsel-unknown-linux-gnu.tar.gz": "8637387cb7f722457e7cdbb6c75eb70fdb913a5543adb1e4dd81d7316f0d2520",
+ "dist/2022-08-09/rust-std-beta-mipsel-unknown-linux-gnu.tar.xz": "539a0a66e06fe7b49e40b2615c3d04611236746419bf03f5439b14cc37f3344e",
+ "dist/2022-08-09/rust-std-beta-mipsel-unknown-linux-musl.tar.gz": "458734ed82bb7e3feb1d831ea6224cd4eeabfbcb06599181d025660298ef7bbe",
+ "dist/2022-08-09/rust-std-beta-mipsel-unknown-linux-musl.tar.xz": "64f0ce96ae9a99daa300d49d087837c7c619e4bdb38f41664d79844c84254c32",
+ "dist/2022-08-09/rust-std-beta-nvptx64-nvidia-cuda.tar.gz": "937c3b1481aeab47b45dcb8dc45c12f856a771615c3b6e56b04e10b4f8075d1d",
+ "dist/2022-08-09/rust-std-beta-nvptx64-nvidia-cuda.tar.xz": "05094bfba7b7fe1fe66f0643ed60079c675d739613e27cb64ca8a61b5faadcd0",
+ "dist/2022-08-09/rust-std-beta-powerpc-unknown-linux-gnu.tar.gz": "d15c897c52bc02a241e9756c62b48c126d651d498a72a3cc70521e6a395bce7c",
+ "dist/2022-08-09/rust-std-beta-powerpc-unknown-linux-gnu.tar.xz": "2182c3300e6cf5f7fba5a687235c34fa9e799beef2edbb07206205ede50964ad",
+ "dist/2022-08-09/rust-std-beta-powerpc64-unknown-linux-gnu.tar.gz": "cba214c9827f639f6c88de0bb28f81c58e81f1263b10ccb4fda5c84ad23ea036",
+ "dist/2022-08-09/rust-std-beta-powerpc64-unknown-linux-gnu.tar.xz": "f7f9bb0d56ebd4b80db0560d6f71b25028c97b99f79eb7ef89255d46ca4df22e",
+ "dist/2022-08-09/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.gz": "b190a078b408d184766831664df1a2d472a134909ad00f195fb84d522d360a56",
+ "dist/2022-08-09/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.xz": "31bcf275272e3a46618110219f61eefd5fdd2c11a75f7ff612fea012dbc3c4b5",
+ "dist/2022-08-09/rust-std-beta-riscv32i-unknown-none-elf.tar.gz": "eadde81672eda5af55c8f2eff6729ad134dd484ac16aef4fa0e402e0164f30df",
+ "dist/2022-08-09/rust-std-beta-riscv32i-unknown-none-elf.tar.xz": "2a5d69f4ec463377e2f9eca3a70647680d1ed09bef4f9a7b839d1d08eed989ca",
+ "dist/2022-08-09/rust-std-beta-riscv32imac-unknown-none-elf.tar.gz": "89b9b9149461362d54b64b2cbdec317674266a9061fc0d46b438f664e003ac83",
+ "dist/2022-08-09/rust-std-beta-riscv32imac-unknown-none-elf.tar.xz": "3c56a23f2fda148e442318bb5a21d895a5b61cc698db5ea9a1ff3c2740887fc4",
+ "dist/2022-08-09/rust-std-beta-riscv32imc-unknown-none-elf.tar.gz": "94f9f155ce07f09ca12814b745cce5d6dfc731cc59c95fcd5b1831f60d9c04fb",
+ "dist/2022-08-09/rust-std-beta-riscv32imc-unknown-none-elf.tar.xz": "b9f76d28c4e057d9b7eada2076c4358d6876aed1c32f65dfa50dc3e3c1970d79",
+ "dist/2022-08-09/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.gz": "e664018f445157229a0c07406d3fc4e7a19cb53722fc3838fcee1bbd3a3a00cf",
+ "dist/2022-08-09/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.xz": "8d48a304ba7ca9470ed5f88076f6c50477f6b3a1afe303aab772638df8978c32",
+ "dist/2022-08-09/rust-std-beta-riscv64gc-unknown-none-elf.tar.gz": "347072268911f3a03223bd494cd2d14cfe4c553fc35e9d36571b54995e04d9aa",
+ "dist/2022-08-09/rust-std-beta-riscv64gc-unknown-none-elf.tar.xz": "100d5a1e75b7c302f03eba8eb26c5c023e1b396cd44d7798f2902bf8f40ec48b",
+ "dist/2022-08-09/rust-std-beta-riscv64imac-unknown-none-elf.tar.gz": "f5d91e04ac7980aa5253e0c90e7e312e42b5fa7de03f35f61fe11ab207894f50",
+ "dist/2022-08-09/rust-std-beta-riscv64imac-unknown-none-elf.tar.xz": "0d83e81a8c48f9cc3e62442e51aee769cef4cc618a2661506a5fb9120163be25",
+ "dist/2022-08-09/rust-std-beta-s390x-unknown-linux-gnu.tar.gz": "96d983517839cbd1d64adfff4b3b0241ceed99573579f041d136be39aa2b7995",
+ "dist/2022-08-09/rust-std-beta-s390x-unknown-linux-gnu.tar.xz": "0eb2c70b7eeb3f754ffea3716e41dc3efae49e98d77ca1843541587dddd6b880",
+ "dist/2022-08-09/rust-std-beta-sparc64-unknown-linux-gnu.tar.gz": "91fa2a025c04e41a7b9a7eb6b4cda351b93fc53801f97042ae0e76bd871d92e9",
+ "dist/2022-08-09/rust-std-beta-sparc64-unknown-linux-gnu.tar.xz": "8ad9da4410688824d5adc6cb8ed42f76bb8a35d41bee62b5f7b44e0d6bd346bb",
+ "dist/2022-08-09/rust-std-beta-sparcv9-sun-solaris.tar.gz": "cb3a28d68f432a3357b6a971f046b5ea37fdad5d4aaa4aea7cc997356d487b75",
+ "dist/2022-08-09/rust-std-beta-sparcv9-sun-solaris.tar.xz": "746fb859655ed6b4379fce8937fff998952cb81297412091844b0e277ec65a23",
+ "dist/2022-08-09/rust-std-beta-thumbv6m-none-eabi.tar.gz": "8bab8c46c7e873d0fa0a7078675fa7a54a90e5342f8b58419e0dd434e9942b67",
+ "dist/2022-08-09/rust-std-beta-thumbv6m-none-eabi.tar.xz": "954b5c32e5515e09b77bcaa3a7c4e139905a4f3d1801b492069c027a8311bc6b",
+ "dist/2022-08-09/rust-std-beta-thumbv7em-none-eabi.tar.gz": "9eb56471c38528c2b80dea81d94e5368f68a977745a1e02449f3eae353ca405f",
+ "dist/2022-08-09/rust-std-beta-thumbv7em-none-eabi.tar.xz": "0334379d0e8c3ef9680837b1dfc96788da4836a91e42d71446461ece7217ab78",
+ "dist/2022-08-09/rust-std-beta-thumbv7em-none-eabihf.tar.gz": "0c65cc553ca2730d020fd8a97b90ebfe2b3c0fc2755b137df55955a3d1c7908f",
+ "dist/2022-08-09/rust-std-beta-thumbv7em-none-eabihf.tar.xz": "625a109a589fae6e2fb64376e3fec4bb39ca19217ad6d312df524129868f343b",
+ "dist/2022-08-09/rust-std-beta-thumbv7m-none-eabi.tar.gz": "e0002c917055c85b613297da21427fc3b6c5f55ee120921ee8bae9b99afec2b6",
+ "dist/2022-08-09/rust-std-beta-thumbv7m-none-eabi.tar.xz": "74cc0f5b245b483b62c9a9e8bd642069af5205ecc59fd0b7464ab1fd6f4f3f7e",
+ "dist/2022-08-09/rust-std-beta-thumbv7neon-linux-androideabi.tar.gz": "98c09985ea2d56fcc8c219c46d355310b65fd4f7c6920df2e7ec5355848ba83d",
+ "dist/2022-08-09/rust-std-beta-thumbv7neon-linux-androideabi.tar.xz": "5122e60b031458c4606905a3df5d64b7bac54bcf883c18ba53443aa76fc5c1cf",
+ "dist/2022-08-09/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.gz": "6ab96971e69a073a5789c3eaaa460a7f5d6a3a5df8ac5125344744dde8476706",
+ "dist/2022-08-09/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.xz": "be874a256076dd2869d6d5780c5b4e8c850e52a62b5d10087d7c1aca32b0b831",
+ "dist/2022-08-09/rust-std-beta-thumbv8m.base-none-eabi.tar.gz": "c37ab11b56d3ac41b8eeadbed09ae5e78467c8945cecb49c218fe91a284e43c0",
+ "dist/2022-08-09/rust-std-beta-thumbv8m.base-none-eabi.tar.xz": "dfa4d1dcfb32d4001b2b9f00a829afd699065dcc6538598eaa27d684a01facac",
+ "dist/2022-08-09/rust-std-beta-thumbv8m.main-none-eabi.tar.gz": "31931cdb16a9a81bf7fc779c8aef6890c1f35130ba1c323d8b548a5dd5494346",
+ "dist/2022-08-09/rust-std-beta-thumbv8m.main-none-eabi.tar.xz": "0aeb4ff0e9b139e3b5550103c6429cb3cb4b455335514b07491e22fa63719169",
+ "dist/2022-08-09/rust-std-beta-thumbv8m.main-none-eabihf.tar.gz": "ba7077816ba6f1b6b386b0245249e10a1482b82eaec711561f912a1975482817",
+ "dist/2022-08-09/rust-std-beta-thumbv8m.main-none-eabihf.tar.xz": "6a49c1907e0ce91a3650aeeb61f6674c39936b67366fa4bb197fc612e9ae5a49",
+ "dist/2022-08-09/rust-std-beta-wasm32-unknown-emscripten.tar.gz": "0e268083c1935be97e3a96ca94b824c84877970a65c2e581f3e71d7364264dff",
+ "dist/2022-08-09/rust-std-beta-wasm32-unknown-emscripten.tar.xz": "27510dbb922d9cc0ee669f3854ffeb1ca28c105b3284e3ba523abcb9cfc10055",
+ "dist/2022-08-09/rust-std-beta-wasm32-unknown-unknown.tar.gz": "6d2f49e7e75ca2e3873dd1530d4bc3eedcebf3b2db6b1e193c0d57d7daa681a3",
+ "dist/2022-08-09/rust-std-beta-wasm32-unknown-unknown.tar.xz": "5508d36c7ae20176af2c10a0c974d5162202e3914e79468b9541c3e1b585612a",
+ "dist/2022-08-09/rust-std-beta-wasm32-wasi.tar.gz": "721726c4b073b27df9abc9e47a2b82eb48ca12a44c87363ae57a632d26619fc9",
+ "dist/2022-08-09/rust-std-beta-wasm32-wasi.tar.xz": "320ae842da96d4ba3147ca338e91306ed602250320df5163a01748491599ade3",
+ "dist/2022-08-09/rust-std-beta-x86_64-apple-darwin.tar.gz": "2dd9b9defe95357d7af5ae81428be814efe9923c308a4c2f3a370b16d912707f",
+ "dist/2022-08-09/rust-std-beta-x86_64-apple-darwin.tar.xz": "17ea6b22feb7fef1211c319a3d9d0f7bcdd8cd215d3ddffc523a83cfeb8331a6",
+ "dist/2022-08-09/rust-std-beta-x86_64-apple-ios.tar.gz": "df3618fb0b30d89d567d238d4e744d8cff81ca07cef701876b4471a98768c810",
+ "dist/2022-08-09/rust-std-beta-x86_64-apple-ios.tar.xz": "60932e2848af4a25699e7d300833f0b8e10bc8dc201d4ac9dcda417f86413cb8",
+ "dist/2022-08-09/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.gz": "57db93d53efad36639645baf0cdfa47b4b70664e22a1eac3f08a5abedc0834ac",
+ "dist/2022-08-09/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.xz": "cea91317cf86ec301730a2ef8a1c68213b6a4921c105bab228e9bd8620641f2b",
+ "dist/2022-08-09/rust-std-beta-x86_64-fuchsia.tar.gz": "7b961a55c6616b02aa91a25eb9e2521bd50ac881120975ea3af92543adfdd8b5",
+ "dist/2022-08-09/rust-std-beta-x86_64-fuchsia.tar.xz": "3ce7314f2c8f3a00430a6686fa267a5b4a8ef20b28023b765aa326f0151d2521",
+ "dist/2022-08-09/rust-std-beta-x86_64-linux-android.tar.gz": "37d538db9ab3cad73c4cdfb0b3836f124a6a2e47dbd1f6aa54167451057ced2f",
+ "dist/2022-08-09/rust-std-beta-x86_64-linux-android.tar.xz": "600ea7bc318580195d3b4e681c5f374075ec40272641050f0fd6296da4a9d383",
+ "dist/2022-08-09/rust-std-beta-x86_64-pc-solaris.tar.gz": "7d389f2d2632068cde7e8f72e685a888462897f4d5aa98034060472443cb89ff",
+ "dist/2022-08-09/rust-std-beta-x86_64-pc-solaris.tar.xz": "60a6532403d902d71883169c2001d6b279f882bee4444bb8107e742e4cfa3ecc",
+ "dist/2022-08-09/rust-std-beta-x86_64-pc-windows-gnu.tar.gz": "76c93994bc6eaa7596ee91dd24f51685ab659533835d441352f88b89a0991236",
+ "dist/2022-08-09/rust-std-beta-x86_64-pc-windows-gnu.tar.xz": "fdba628daf4b04afc1ec1d8ac4b9460ffe0a230feaf61dd7b621e2ec02b09a2b",
+ "dist/2022-08-09/rust-std-beta-x86_64-pc-windows-msvc.tar.gz": "4ee478c238ec38ec4977fa8a1689aa28b7a2b0173549da92f1b2e1a2f6772aee",
+ "dist/2022-08-09/rust-std-beta-x86_64-pc-windows-msvc.tar.xz": "c732f3054a4a67f25242ba9acb5bfbc945e3ac62a2b0de5b7ede0990313984b5",
+ "dist/2022-08-09/rust-std-beta-x86_64-sun-solaris.tar.gz": "47a4e8d8cc03e402e480ce5f24326de7094622fe339e4441df7f6a6271a8775c",
+ "dist/2022-08-09/rust-std-beta-x86_64-sun-solaris.tar.xz": "260c93c4dafb20d476a965e2681751e38be15bfb96d32b10730e44a1d4da6079",
+ "dist/2022-08-09/rust-std-beta-x86_64-unknown-freebsd.tar.gz": "9d7c63a2ced8041b21459192a0176665ad93324c3774f3028b411eacafd9bfe8",
+ "dist/2022-08-09/rust-std-beta-x86_64-unknown-freebsd.tar.xz": "276235e7efd773273ffe281cfe5119a9fd361f04ddb1f3ed060d0abb983ff55d",
+ "dist/2022-08-09/rust-std-beta-x86_64-unknown-illumos.tar.gz": "00ee12a1d47b1d00403e8f2d083a0dbfc8bbbf86ba973b08fbf4c59333f70052",
+ "dist/2022-08-09/rust-std-beta-x86_64-unknown-illumos.tar.xz": "e11ffdd664228acb94e8e92ae919f7c3bf354083a1ca586be4fa65b7abac17eb",
+ "dist/2022-08-09/rust-std-beta-x86_64-unknown-linux-gnu.tar.gz": "d58aedd100cf952c52b8364731b1ecc05567c4d6be4899d36f210ff619b934dd",
+ "dist/2022-08-09/rust-std-beta-x86_64-unknown-linux-gnu.tar.xz": "28021e5a4ff36813f76f6aeb063fefaf58310d65993557df2128ff5b9eeb4f75",
+ "dist/2022-08-09/rust-std-beta-x86_64-unknown-linux-gnux32.tar.gz": "ef5ed09b2bd6b9c1772aeb66444dd821176b4aefb27e657db5bbd24f09d9c104",
+ "dist/2022-08-09/rust-std-beta-x86_64-unknown-linux-gnux32.tar.xz": "c41edbd8ec4266555b7824594eef470ca6d7695675cf13303dcca6b248d0b692",
+ "dist/2022-08-09/rust-std-beta-x86_64-unknown-linux-musl.tar.gz": "575e5b74248f2503de16294d10e6fec2f6bacac9082ffd73e0395ac2669aefda",
+ "dist/2022-08-09/rust-std-beta-x86_64-unknown-linux-musl.tar.xz": "4b0f56d6a004c6ebdf325ece1d8006795ffb404ea4f1e958a1425ba9edb28b18",
+ "dist/2022-08-09/rust-std-beta-x86_64-unknown-netbsd.tar.gz": "9e39545494934be7f91675de58907b7b71fe383c535b55799add8c5706371dcb",
+ "dist/2022-08-09/rust-std-beta-x86_64-unknown-netbsd.tar.xz": "3807db4641082a329edbd08654f40f769e44d139edc99be0b559c8c00c27adbf",
+ "dist/2022-08-09/rust-std-beta-x86_64-unknown-none.tar.gz": "4eeddd2654e6a84ef5ad5a6f90d88dab043ca087f884e640c945a4565c6b20e2",
+ "dist/2022-08-09/rust-std-beta-x86_64-unknown-none.tar.xz": "656e1ff5941fe4699ac16d6c1cdd715fca3a7980b4159644b856af08d8b47918",
+ "dist/2022-08-09/rust-std-beta-x86_64-unknown-redox.tar.gz": "0e0d5de37c86d6a0684b627f16dd6adebbd2ab4776f4a3fb6a386b3ebe9cdbb2",
+ "dist/2022-08-09/rust-std-beta-x86_64-unknown-redox.tar.xz": "dc79147efac5730201980035d1ae377cda5a18bb446647e1bc8375c5d645b1c9",
+ "dist/2022-08-09/rustc-beta-aarch64-apple-darwin.tar.gz": "a3916d7a71d422a0118363228bfcca4a72abd08a6fe6c6d3b4888b87846a1bbf",
+ "dist/2022-08-09/rustc-beta-aarch64-apple-darwin.tar.xz": "f18d8918c9c1ff55cc513fffa309d72b9aeb853f92dfa66e34fb151a2c374269",
+ "dist/2022-08-09/rustc-beta-aarch64-pc-windows-msvc.tar.gz": "ba008d21693e01291e3016773f728c98040903eaa6a71abda23f8043eb9348b6",
+ "dist/2022-08-09/rustc-beta-aarch64-pc-windows-msvc.tar.xz": "1333977a0a147bd5f05eef63ca859b8e78ddc51bed2202616ce5fda5a9203080",
+ "dist/2022-08-09/rustc-beta-aarch64-unknown-linux-gnu.tar.gz": "78e40c65e40a287e9ee2d9178f84c8ff7277c2a5beff67555185d79fee1af44b",
+ "dist/2022-08-09/rustc-beta-aarch64-unknown-linux-gnu.tar.xz": "ce24270b141952b3fb67c0f43896416dd77be66ed3b311857bff8b07121e1de9",
+ "dist/2022-08-09/rustc-beta-aarch64-unknown-linux-musl.tar.gz": "6557c13f5014acda10349a99e24749224b4f86e55b6499e35f05b5e583a1fed3",
+ "dist/2022-08-09/rustc-beta-aarch64-unknown-linux-musl.tar.xz": "d4b1b814bfa277f895ef4a6c8963ce482965fbdf83ba0661b11db8df39ef301c",
+ "dist/2022-08-09/rustc-beta-arm-unknown-linux-gnueabi.tar.gz": "3fd9fdfe30333a0a99cf8e9fe754cb1b8f8734b5d1ab47aaf9490d8eaf3b29b8",
+ "dist/2022-08-09/rustc-beta-arm-unknown-linux-gnueabi.tar.xz": "a736efa35fab54ebf36aebf5c7f5b6d4f0ec1f7b0e5b8b3acf2720d97b0c7d93",
+ "dist/2022-08-09/rustc-beta-arm-unknown-linux-gnueabihf.tar.gz": "5b824f9aa8a77f8a21d8cf68751924739e65d599c0fe561ea9383b8de4132315",
+ "dist/2022-08-09/rustc-beta-arm-unknown-linux-gnueabihf.tar.xz": "9996ad84db143044b454483cc24c6ad5c333edd7988ab4ef221237d37891e26d",
+ "dist/2022-08-09/rustc-beta-armv7-unknown-linux-gnueabihf.tar.gz": "6fcbf77721d4d5c51fe5c580f0ff8ac7347d6c49895da33a3eca19e505cc752d",
+ "dist/2022-08-09/rustc-beta-armv7-unknown-linux-gnueabihf.tar.xz": "3b4e566667ee1b2e9fdb5ac6cde4aa3ddf9c9739e7e64e519f2204db2048bd20",
+ "dist/2022-08-09/rustc-beta-i686-pc-windows-gnu.tar.gz": "cc4f775b79c3ad51bf6ff558267100e05c6fa12ac378d69cc0b0affc37b541a9",
+ "dist/2022-08-09/rustc-beta-i686-pc-windows-gnu.tar.xz": "b646befe7d3ad1b0a30c9eb4e14a6e401f1346e11f88145ee17043de2b6f4df0",
+ "dist/2022-08-09/rustc-beta-i686-pc-windows-msvc.tar.gz": "9b4847beb5faf417bc24b4b963f40c8c8dce55b73658eacb10d2d1c968c676b5",
+ "dist/2022-08-09/rustc-beta-i686-pc-windows-msvc.tar.xz": "6b57826d56686f481d2a20e90994a2af6cb9886c063b1dc08c3bb181ce248a69",
+ "dist/2022-08-09/rustc-beta-i686-unknown-linux-gnu.tar.gz": "ea34b82db9cc6d079a67df542036c83e8661d435d15802976676671cb2b27c24",
+ "dist/2022-08-09/rustc-beta-i686-unknown-linux-gnu.tar.xz": "d679a401e807b12fa8fd3686d3ac09374d3c8d660c6f0a571efc7c9217a05f09",
+ "dist/2022-08-09/rustc-beta-mips-unknown-linux-gnu.tar.gz": "cb3c3638460f3d71c94ca10ab9684ebdbb25f886b8604e62e8412361be56e579",
+ "dist/2022-08-09/rustc-beta-mips-unknown-linux-gnu.tar.xz": "0665c0e3b2ac28648c2a0ac49670181a737ae30fc74add44a2ee612b1d74dd24",
+ "dist/2022-08-09/rustc-beta-mips64-unknown-linux-gnuabi64.tar.gz": "0acc722d22b787adbe16549edbf28debdd4d84633701f8bb7514d5911d6ff124",
+ "dist/2022-08-09/rustc-beta-mips64-unknown-linux-gnuabi64.tar.xz": "441d5ca203afbd5bc4af16431c31d3c76e05edbe45ad37aea4d1f90ca4afecee",
+ "dist/2022-08-09/rustc-beta-mips64el-unknown-linux-gnuabi64.tar.gz": "437c52c97b0a8edd1165b957b768e7c9f7c3d79023626fdcb97538899f424592",
+ "dist/2022-08-09/rustc-beta-mips64el-unknown-linux-gnuabi64.tar.xz": "9812034d2fe8bb583dfe57a792639a6ac7ab912682ad7383db975efd5f0cd281",
+ "dist/2022-08-09/rustc-beta-mipsel-unknown-linux-gnu.tar.gz": "5d39fe2005a50e40505b18210af700ed8fd439d018fe8723c13221c7683defad",
+ "dist/2022-08-09/rustc-beta-mipsel-unknown-linux-gnu.tar.xz": "da77cb500618d57682ef4d601e1c8492d9d5412a1833757ffa95d00b0aab790f",
+ "dist/2022-08-09/rustc-beta-powerpc-unknown-linux-gnu.tar.gz": "5e4559e41c12f1248cec5f4cb40c196e5d6520bffcc043a40759e7a7668ee0b7",
+ "dist/2022-08-09/rustc-beta-powerpc-unknown-linux-gnu.tar.xz": "41c527f4dbf76275f26f7486b48613fba57171b82275ae29ad90bbe684497ce8",
+ "dist/2022-08-09/rustc-beta-powerpc64-unknown-linux-gnu.tar.gz": "410f2768e5b69f03ebed37923e0c0bb54d4b297bcbef98d82529216a1dfa4c6f",
+ "dist/2022-08-09/rustc-beta-powerpc64-unknown-linux-gnu.tar.xz": "7f0d0ff4a797120c1a31d33cecd4abd4bd69ec6ff97351291267423f27f7f3f1",
+ "dist/2022-08-09/rustc-beta-powerpc64le-unknown-linux-gnu.tar.gz": "2fa446a7f79d254350b7e9828a36fd415f6931494bdec8bf8f26e0c13636849f",
+ "dist/2022-08-09/rustc-beta-powerpc64le-unknown-linux-gnu.tar.xz": "8572718b7ca5aef0de8227550816dbbd7b41fcc2ab6b0624a50096fa387503ce",
+ "dist/2022-08-09/rustc-beta-riscv64gc-unknown-linux-gnu.tar.gz": "7d82792f2526c6e6522c5255dd350e09f838551f743f760634b875eb22b48b0e",
+ "dist/2022-08-09/rustc-beta-riscv64gc-unknown-linux-gnu.tar.xz": "99f4ff1b50ce3b644b12bc0da84910f376c9187adede0222dc8a1e242e347263",
+ "dist/2022-08-09/rustc-beta-s390x-unknown-linux-gnu.tar.gz": "81f32e172bc635028fe048d2194f1d49c4f31b4daadf8690931cd3a15a9e06d1",
+ "dist/2022-08-09/rustc-beta-s390x-unknown-linux-gnu.tar.xz": "c50258bda8d09646bef493463d66be02d8e7155122e2b7eafe9bc5bd11cbe6b9",
+ "dist/2022-08-09/rustc-beta-x86_64-apple-darwin.tar.gz": "fa2d6a74109c087f13fbbf00171252fcd9079b9978028ee6df4fb2d18c27a39e",
+ "dist/2022-08-09/rustc-beta-x86_64-apple-darwin.tar.xz": "630b218549ee04a8bc5a8a29616d5d8c1d866804cedb2fc3861cc2e354382c5e",
+ "dist/2022-08-09/rustc-beta-x86_64-pc-windows-gnu.tar.gz": "633b22f9c9a93f6cbed7a53fb466ea0bf5895f6fa9c3a22a5883951cedbd606b",
+ "dist/2022-08-09/rustc-beta-x86_64-pc-windows-gnu.tar.xz": "d109d67480ab01ab1e176b5c904df5053fbb54baaf422d4f5019a28dd122e149",
+ "dist/2022-08-09/rustc-beta-x86_64-pc-windows-msvc.tar.gz": "627635dcd8515ed029515e1621b8411e1a3a6ede4058d2cf581c8d669b96dd5f",
+ "dist/2022-08-09/rustc-beta-x86_64-pc-windows-msvc.tar.xz": "6f98febabe7229c566c86728dcf773849c97f29bc0f43ea4f5ffb4e81f163b18",
+ "dist/2022-08-09/rustc-beta-x86_64-unknown-freebsd.tar.gz": "a4b4dcd9dd1128df37d761efaa669ebb35841af0847b5bb5bcf38295ca47db6d",
+ "dist/2022-08-09/rustc-beta-x86_64-unknown-freebsd.tar.xz": "cd28418166eaa754102b469414d0fcfe6785096855e50a2b895c5903e528d8c2",
+ "dist/2022-08-09/rustc-beta-x86_64-unknown-illumos.tar.gz": "168cf42f579132b44ac35a214328f518ab201d6fb9d88d645899fdd88e1d5e34",
+ "dist/2022-08-09/rustc-beta-x86_64-unknown-illumos.tar.xz": "7792763eda89f90a878b09dd99ea9af94d6db0c36bb9570e9b1a05d8dc2f1e47",
+ "dist/2022-08-09/rustc-beta-x86_64-unknown-linux-gnu.tar.gz": "ec79355625df63a29487253925f5213442f8606f2fd6fca7a94f8db57220f802",
+ "dist/2022-08-09/rustc-beta-x86_64-unknown-linux-gnu.tar.xz": "b7df0b00cfc3bee9a1a906441726ae009aa7dfbfe22e16bc9127ec4df11cd1a7",
+ "dist/2022-08-09/rustc-beta-x86_64-unknown-linux-musl.tar.gz": "372a7c389366e543f3477f2854271c7a74042abf51c37f2d5ce1450f4cd3bfd3",
+ "dist/2022-08-09/rustc-beta-x86_64-unknown-linux-musl.tar.xz": "11243da1c7642ee7ece1b43de1e59b4c45fa8ecf0c9d632d6f1db4772e4479a6",
+ "dist/2022-08-09/rustc-beta-x86_64-unknown-netbsd.tar.gz": "808a451394f4a023ef28420d7dc29e2de92618e5a563055798ec2307e0ca062f",
+ "dist/2022-08-09/rustc-beta-x86_64-unknown-netbsd.tar.xz": "55b447374eb361b2ea1de87080bac3a0cc4fbd233e916e53e5424d6b9ed0dc48",
+ "dist/2022-08-09/rustfmt-nightly-aarch64-apple-darwin.tar.gz": "bbbfd82986d5fafa76f06b87b08cfda800dbc87a1adaed3587f570336a648c3f",
+ "dist/2022-08-09/rustfmt-nightly-aarch64-apple-darwin.tar.xz": "69a99ec973a3603c3d84361d407fbe9c79af0a284a48f5578fb6f46affe751b1",
+ "dist/2022-08-09/rustfmt-nightly-aarch64-pc-windows-msvc.tar.gz": "4a886c744cd6b5f4fe0ec2a3b87730e9a4f7a66c9d4fb0c6411be32014e9e5f0",
+ "dist/2022-08-09/rustfmt-nightly-aarch64-pc-windows-msvc.tar.xz": "095ff2687c8dd48decf47c2b65ce84579bc753de0732877cb092b4ccb9df4f92",
+ "dist/2022-08-09/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.gz": "3533a40f72ee318f04448f005e0a811add2e97285e158f63758f76b4424ebe46",
+ "dist/2022-08-09/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.xz": "85a4f34d889bf52b65b93066bd1bd6a91092ed49cf6443f476bd60fb36b1cb6d",
+ "dist/2022-08-09/rustfmt-nightly-aarch64-unknown-linux-musl.tar.gz": "11c4bb5a071d555cda8b685e340727eb588f7a830cd4fc22937e44e68b3d7ee4",
+ "dist/2022-08-09/rustfmt-nightly-aarch64-unknown-linux-musl.tar.xz": "b7c9628299f155530d5a2831a4ffe8d398d2cd222952815006eb19d6ff92a846",
+ "dist/2022-08-09/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.gz": "04ce1aec5cd9c7ba644954d8ec6ba4c851de1c964b64b0d63965cd2043e7d590",
+ "dist/2022-08-09/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.xz": "08635b48b6a7585dbeb7e53f5aac172404e8dfbdf8c165e281064737f073a013",
+ "dist/2022-08-09/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.gz": "852ea71bee89cbf9c9fd1d9abb02a88695732d51b106d3de78c36f371663341e",
+ "dist/2022-08-09/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.xz": "499ded5cd2689626186c3a51af671991ec67ea0eb16bfa30097a764c6718405a",
+ "dist/2022-08-09/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.gz": "eff28bbdd1d3dc44fb4504b24856dc8c550f1311ce56a1614acf2b7409a1c5e2",
+ "dist/2022-08-09/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.xz": "b621a87a5257c280b0610fa90abd288264ee01238669d61030ae057e87eb8e47",
+ "dist/2022-08-09/rustfmt-nightly-i686-pc-windows-gnu.tar.gz": "9307f1feb9c06f57930cd0009aa7b740f1c9e1515212bd7e2ae81149ea0f571d",
+ "dist/2022-08-09/rustfmt-nightly-i686-pc-windows-gnu.tar.xz": "fea653c9e14d305ed217f9c984742c066ea7f7d2fb6d316a13586afc820fca8a",
+ "dist/2022-08-09/rustfmt-nightly-i686-pc-windows-msvc.tar.gz": "8e600a6ad04dff36fe9b1846592faa693b1a036f58d136a522d6ca86f9d76be1",
+ "dist/2022-08-09/rustfmt-nightly-i686-pc-windows-msvc.tar.xz": "52b45791540bc754a82a7349ca4c5ce194afd28e6c857b61f0ff7e87f10f1253",
+ "dist/2022-08-09/rustfmt-nightly-i686-unknown-linux-gnu.tar.gz": "964847cfa824c66db554ec20a7e623f4ea50e4cef2439b6813592bcdc31a94ce",
+ "dist/2022-08-09/rustfmt-nightly-i686-unknown-linux-gnu.tar.xz": "71b89b63be5a44e12d0303e71e3e14b0b770aaac5bcf2879e17526b27e568c6d",
+ "dist/2022-08-09/rustfmt-nightly-mips-unknown-linux-gnu.tar.gz": "aac0b10cfcb07c64de04fea33d9cf8d691f307e3aefaa9582a8ba3e1fd54aa35",
+ "dist/2022-08-09/rustfmt-nightly-mips-unknown-linux-gnu.tar.xz": "e3688bc8ef82fff7685cc95fc1ec708a5d76d288cccbd42c37e5c83184f6a52e",
+ "dist/2022-08-09/rustfmt-nightly-mips64-unknown-linux-gnuabi64.tar.gz": "aa89a2dbfe0c6020139d8be52be126a01af9691eaf73fa94c94f9ae75d09d619",
+ "dist/2022-08-09/rustfmt-nightly-mips64-unknown-linux-gnuabi64.tar.xz": "1e7e5f11f829b06f4d8ae5b6d38f13e055ff1fda5b1481e33e40e2a336c7852a",
+ "dist/2022-08-09/rustfmt-nightly-mips64el-unknown-linux-gnuabi64.tar.gz": "e43b8009179139c1bd15f3e947a8bc7357e57833959f9fd18fde1d75a742bede",
+ "dist/2022-08-09/rustfmt-nightly-mips64el-unknown-linux-gnuabi64.tar.xz": "5bf84aa3ad0badbf0c60d31f686498801d9a23dc0324062128cd7690f9c69234",
+ "dist/2022-08-09/rustfmt-nightly-mipsel-unknown-linux-gnu.tar.gz": "b3816072c441ee9e2b8da5cc6a8ed022795b7176d4ac604d97b0d213f89522ac",
+ "dist/2022-08-09/rustfmt-nightly-mipsel-unknown-linux-gnu.tar.xz": "d7c6b668f4a2c128ab845e010deb7c9c3e374aaf167244395cdad6c746f73420",
+ "dist/2022-08-09/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.gz": "91c36676f8b9093976d7e30ac39f2c477f8442771a3e9c49f41610a0b8688cbe",
+ "dist/2022-08-09/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.xz": "86bc5289beee0abf87bfc57a09d6504bfe58675871f4e7559b7f9e1b748e8dc6",
+ "dist/2022-08-09/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.gz": "12a1716934b48c2cf716a56c66f95852a70bc74b65c2e44a542b9c2ebf1be5ec",
+ "dist/2022-08-09/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.xz": "591ac7d4acd0036d532c91fa3f64a7789881224dd5496b1fe3564c79fd5f0254",
+ "dist/2022-08-09/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.gz": "b558c9463e5b8380e133a7a64bc95994d8625fa0097f8b41fb39c93367704698",
+ "dist/2022-08-09/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.xz": "d28bbc411779d19279fec251e9378b3923c4b3a8c651d375e139732dd6daaaad",
+ "dist/2022-08-09/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.gz": "af9644ab1e369495a4e35fbd111946c679e597c8c1f8342d3a92bad0cad30ffc",
+ "dist/2022-08-09/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.xz": "c2acdb98f2c2565cbaf57557cbd99038fb066a09b5602ff3d3bbcb58388b4501",
+ "dist/2022-08-09/rustfmt-nightly-s390x-unknown-linux-gnu.tar.gz": "eddd4a32740ba700c095568bff791e959d6b8ab0a47b5e98a317ea56cc754751",
+ "dist/2022-08-09/rustfmt-nightly-s390x-unknown-linux-gnu.tar.xz": "021bba582076650b577d78fda0b6d9374b17e623d2f3ddb0322f9960874ac269",
+ "dist/2022-08-09/rustfmt-nightly-x86_64-apple-darwin.tar.gz": "355c877020b386f0297765f8ae1b1e3fa126c9e9b537f8923d275bd31cbdba33",
+ "dist/2022-08-09/rustfmt-nightly-x86_64-apple-darwin.tar.xz": "809d3314e1b69efb5544fa6daa6719907e09edfd7e0c2cf483ad89a3d508b98d",
+ "dist/2022-08-09/rustfmt-nightly-x86_64-pc-windows-gnu.tar.gz": "def326ede8106aa440b57698a027fffe024158351879d17f9bba0e58c3788662",
+ "dist/2022-08-09/rustfmt-nightly-x86_64-pc-windows-gnu.tar.xz": "86684f3c6ba66216c5c9cb203eb9fce96e0239a345df912a2071bc9aa83cc9da",
+ "dist/2022-08-09/rustfmt-nightly-x86_64-pc-windows-msvc.tar.gz": "2d658db4849089e86af76eb4d7986d605da644af6f6ad43429931f775b5bb094",
+ "dist/2022-08-09/rustfmt-nightly-x86_64-pc-windows-msvc.tar.xz": "ec14c63680836e5303450d3bfda7b6ca5b163ec01cdaf1e3f2d7b6c584c4c6a1",
+ "dist/2022-08-09/rustfmt-nightly-x86_64-unknown-freebsd.tar.gz": "39542f4fd6261b864c59494958071dacd32703fd870286ec5fceaf3664d3e5a4",
+ "dist/2022-08-09/rustfmt-nightly-x86_64-unknown-freebsd.tar.xz": "a02061c8bcdd23a8b3f21c4f776e900536fcd44019a495fdec159fd9b4282700",
+ "dist/2022-08-09/rustfmt-nightly-x86_64-unknown-illumos.tar.gz": "15fe16aca96080380c6ebf109522f60134dbaad610d3841e07ac5059ee920edc",
+ "dist/2022-08-09/rustfmt-nightly-x86_64-unknown-illumos.tar.xz": "43d562bce508ccc40afdc3f1ec85b6f0e29b1bad1661a758d07e57cb97d63407",
+ "dist/2022-08-09/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.gz": "80659ef19b274724eb3becb90ca03ea6cb6eb1ff9ff6989073df6e1e52c0d406",
+ "dist/2022-08-09/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.xz": "392e98288ea2ef6602dff922c9bef4fcb17acdcefbb4bca050ede73aeee669e8",
+ "dist/2022-08-09/rustfmt-nightly-x86_64-unknown-linux-musl.tar.gz": "1eccdcb7cdb96ffb5a5261d4190e4bd1f92e5cf61e92e556ed6baf42e9c316ab",
+ "dist/2022-08-09/rustfmt-nightly-x86_64-unknown-linux-musl.tar.xz": "9526d26c9fef619cf429437d45c5a79e89a894b22f88635d7995639f1f9696b6",
+ "dist/2022-08-09/rustfmt-nightly-x86_64-unknown-netbsd.tar.gz": "486b79d19fff869275f973b274b3cddf02693ba444a79a2e100c6ba79be5d493",
+ "dist/2022-08-09/rustfmt-nightly-x86_64-unknown-netbsd.tar.xz": "1378376c8b16aa269034cd99b2efb8d8a0fe77e9526338d652b6d6e9aff2ac0c"
}
}
}
// NONMSVC: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "{async_fn_env#0}",
-// MSVC: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_union_type, name: "enum$<async_fn_debug_awaitee_field::async_fn_test::async_fn_env$0>",
+// MSVC: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_union_type, name: "enum2$<async_fn_debug_awaitee_field::async_fn_test::async_fn_env$0>",
// CHECK: [[SUSPEND_STRUCT:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Suspend0", scope: [[GEN]],
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "__awaitee", scope: [[SUSPEND_STRUCT]], {{.*}}, baseType: [[AWAITEE_TYPE:![0-9]*]],
// NONMSVC: [[AWAITEE_TYPE]] = !DICompositeType(tag: DW_TAG_structure_type, name: "GenFuture<async_fn_debug_awaitee_field::foo::{async_fn_env#0}>",
-// MSVC: [[AWAITEE_TYPE]] = !DICompositeType(tag: DW_TAG_structure_type, name: "GenFuture<enum$<async_fn_debug_awaitee_field::foo::async_fn_env$0> >",
+// MSVC: [[AWAITEE_TYPE]] = !DICompositeType(tag: DW_TAG_structure_type, name: "GenFuture<enum2$<async_fn_debug_awaitee_field::foo::async_fn_env$0> >",
fn main() {
let _fn = async_fn_test();
// FIXME: No way to reliably check the filename.
-// CHECK-DAG: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_union_type, name: "enum$<async_fn_debug_msvc::async_fn_test::async_fn_env$0>",
+// CHECK-DAG: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_union_type, name: "enum2$<async_fn_debug_msvc::async_fn_test::async_fn_env$0>",
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "variant0", scope: [[GEN]],
// For brevity, we only check the struct name and members of the last variant.
// CHECK-SAME: file: [[FILE:![0-9]*]], line: 11,
// CHECK-SAME: )
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "variant4", scope: [[GEN]],
// CHECK-SAME: file: [[FILE]], line: 14,
-// CHECK-SAME: baseType: [[VARIANT:![0-9]*]]
+// CHECK-SAME: baseType: [[VARIANT_WRAPPER:![0-9]*]]
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
+// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "value", scope: [[VARIANT_WRAPPER]], file: !2, baseType: [[VARIANT:![0-9]*]],
// CHECK: [[VARIANT]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Suspend1", scope: [[GEN]],
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "s", scope: [[VARIANT]]
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
-// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "discriminant", scope: [[GEN]],
+// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "tag", scope: [[GEN]],
// CHECK-NOT: flags: DIFlagArtificial
fn main() {
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "align", scope: ![[VTABLE_TY2]], {{.*}}, baseType: ![[USIZE]], size: {{64|32}}, align: {{64|32}}, offset: {{128|64}})
// NONMSVC: !DIGlobalVariable(name: "<debug_vtable::bar::{closure_env#0} as core::ops::function::FnOnce<(core::option::Option<&dyn core::ops::function::Fn<(), Output=()>>)>>::{vtable}"
-// MSVC: !DIGlobalVariable(name: "impl$<debug_vtable::bar::closure_env$0, core::ops::function::FnOnce<tuple$<enum$<core::option::Option<ref$<dyn$<core::ops::function::Fn<tuple$<>,assoc$<Output,tuple$<> > > > > >, {{.*}}, {{.*}}, Some> > > >::vtable$"
+// MSVC: !DIGlobalVariable(name: "impl$<debug_vtable::bar::closure_env$0, core::ops::function::FnOnce<tuple$<enum2$<core::option::Option<ref$<dyn$<core::ops::function::Fn<tuple$<>,assoc$<Output,tuple$<> > > > > > > > > >::vtable$"
// NONMSVC: !DIGlobalVariable(name: "<debug_vtable::generic_closure::{closure_env#0}<bool> as core::ops::function::FnOnce<()>>::{vtable}"
// MSVC: !DIGlobalVariable(name: "impl$<debug_vtable::generic_closure::closure_env$0<bool>, core::ops::function::FnOnce<tuple$<> > >::vtable$
// FIXME: No way to reliably check the filename.
-// CHECK-DAG: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_union_type, name: "enum$<generator_debug_msvc::generator_test::generator_env$0>"
+// CHECK-DAG: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_union_type, name: "enum2$<generator_debug_msvc::generator_test::generator_env$0>"
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "variant0", scope: [[GEN]],
// For brevity, we only check the struct name and members of the last variant.
// CHECK-SAME: file: [[FILE:![0-9]*]], line: 14,
// CHECK-SAME: )
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "variant4", scope: [[GEN]],
// CHECK-SAME: file: [[FILE]], line: 17,
-// CHECK-SAME: baseType: [[VARIANT:![0-9]*]]
+// CHECK-SAME: baseType: [[VARIANT_WRAPPER:![0-9]*]]
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
+// CHECK: [[VARIANT_WRAPPER]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Variant4", scope: [[GEN]],
+// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "value", scope: [[VARIANT_WRAPPER]], {{.*}}, baseType: [[VARIANT:![0-9]*]],
// CHECK: [[VARIANT]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Suspend1", scope: [[GEN]],
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "s", scope: [[VARIANT]]
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
-// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "discriminant", scope: [[GEN]],
+// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "tag", scope: [[GEN]],
// CHECK-NOT: flags: DIFlagArtificial
fn main() {
// cdb-command: g
// cdb-command: dx b
-// cdb-check: b : Unresumed [Type: enum$<generator_objects::main::generator_env$0>]
-// cdb-check: [variant] : Unresumed
+// cdb-check: b : Unresumed [Type: enum2$<generator_objects::main::generator_env$0>]
// cdb-check: [+0x[...]] _ref__a : 0x[...] : 5 [Type: int *]
// cdb-command: g
// cdb-command: dx b
-// cdb-check: b : Suspend0 [Type: enum$<generator_objects::main::generator_env$0>]
-// cdb-check: [variant] : Suspend0
+// cdb-check: b : Suspend0 [Type: enum2$<generator_objects::main::generator_env$0>]
// cdb-check: [+0x[...]] c : 6 [Type: int]
// cdb-check: [+0x[...]] d : 7 [Type: int]
// cdb-check: [+0x[...]] _ref__a : 0x[...] : 5 [Type: int *]
// cdb-command: g
// cdb-command: dx b
-// cdb-check: b : Suspend1 [Type: enum$<generator_objects::main::generator_env$0>]
-// cdb-check: [variant] : Suspend1
+// cdb-check: b : Suspend1 [Type: enum2$<generator_objects::main::generator_env$0>]
// cdb-check: [+0x[...]] c : 7 [Type: int]
// cdb-check: [+0x[...]] d : 8 [Type: int]
// cdb-check: [+0x[...]] _ref__a : 0x[...] : 6 [Type: int *]
// cdb-command: g
// cdb-command: dx b
-// cdb-check: b : Returned [Type: enum$<generator_objects::main::generator_env$0>]
-// cdb-check: [<Raw View>] [Type: enum$<generator_objects::main::generator_env$0>]
-// cdb-check: [variant] : Returned
+// cdb-check: b : Returned [Type: enum2$<generator_objects::main::generator_env$0>]
// cdb-check: [+0x[...]] _ref__a : 0x[...] : 6 [Type: int *]
#![feature(omit_gdb_pretty_printer_section, generators, generator_trait)]
// cdb-command: g
// cdb-command: dx a
-// cdb-check:a : Some({...}) [Type: enum$<core::option::Option<msvc_pretty_enums::CStyleEnum>, 2, 16, Some>]
-// cdb-check: [<Raw View>] [Type: enum$<core::option::Option<msvc_pretty_enums::CStyleEnum>, 2, 16, Some>]
-// cdb-check: [variant] : Some
+// cdb-check:a : Some [Type: enum2$<core::option::Option<msvc_pretty_enums::CStyleEnum> >]
// cdb-check: [+0x000] __0 : Low (0x2) [Type: msvc_pretty_enums::CStyleEnum]
// cdb-command: dx b
-// cdb-check:b : None [Type: enum$<core::option::Option<msvc_pretty_enums::CStyleEnum>, 2, 16, Some>]
-// cdb-check: [<Raw View>] [Type: enum$<core::option::Option<msvc_pretty_enums::CStyleEnum>, 2, 16, Some>]
-// cdb-check: [variant] : None
+// cdb-check:b : None [Type: enum2$<core::option::Option<msvc_pretty_enums::CStyleEnum> >]
// cdb-command: dx c
-// cdb-check:c : Tag1 [Type: enum$<msvc_pretty_enums::NicheLayoutEnum, 2, 16, Data>]
-// cdb-check: [<Raw View>] [Type: enum$<msvc_pretty_enums::NicheLayoutEnum, 2, 16, Data>]
-// cdb-check: [variant] : Tag1
+// cdb-check:c : Tag1 [Type: enum2$<msvc_pretty_enums::NicheLayoutEnum>]
// cdb-command: dx d
-// cdb-check:d : Data({...}) [Type: enum$<msvc_pretty_enums::NicheLayoutEnum, 2, 16, Data>]
-// cdb-check: [<Raw View>] [Type: enum$<msvc_pretty_enums::NicheLayoutEnum, 2, 16, Data>]
-// cdb-check: [variant] : Data
+// cdb-check:d : Data [Type: enum2$<msvc_pretty_enums::NicheLayoutEnum>]
// cdb-check: [+0x000] my_data : High (0x10) [Type: msvc_pretty_enums::CStyleEnum]
// cdb-command: dx e
-// cdb-check:e : Tag2 [Type: enum$<msvc_pretty_enums::NicheLayoutEnum, 2, 16, Data>]
-// cdb-check: [<Raw View>] [Type: enum$<msvc_pretty_enums::NicheLayoutEnum, 2, 16, Data>]
-// cdb-check: [variant] : Tag2
+// cdb-check:e : Tag2 [Type: enum2$<msvc_pretty_enums::NicheLayoutEnum>]
// cdb-command: dx f
-// cdb-check:f : Some({...}) [Type: enum$<core::option::Option<ref$<u32> >, 1, [...], Some>]
-// cdb-check: [<Raw View>] [Type: enum$<core::option::Option<ref$<u32> >, 1, [...], Some>]
-// cdb-check: [variant] : Some
+// cdb-check:f : Some [Type: enum2$<core::option::Option<ref$<u32> > >]
// cdb-check: [+0x000] __0 : 0x[...] : 0x1 [Type: unsigned int *]
// cdb-command: dx g
-// cdb-check:g : None [Type: enum$<core::option::Option<ref$<u32> >, 1, [...], Some>]
-// cdb-check: [<Raw View>] [Type: enum$<core::option::Option<ref$<u32> >, 1, [...], Some>]
-// cdb-check: [variant] : None
+// cdb-check:g : None [Type: enum2$<core::option::Option<ref$<u32> > >]
// cdb-command: dx h
-// cdb-check:h : Some [Type: enum$<core::option::Option<u32> >]
-// cdb-check: [<Raw View>] [Type: enum$<core::option::Option<u32> >]
-// cdb-check: [variant] : Some
+// cdb-check:h : Some [Type: enum2$<core::option::Option<u32> >]
// cdb-check: [+0x004] __0 : 0xc [Type: unsigned int]
// cdb-command: dx i
-// cdb-check:i : None [Type: enum$<core::option::Option<u32> >]
-// cdb-check: [<Raw View>] [Type: enum$<core::option::Option<u32> >]
-// cdb-check: [variant] : None
+// cdb-check:i : None [Type: enum2$<core::option::Option<u32> >]
// cdb-command: dx j
// cdb-check:j : High (0x10) [Type: msvc_pretty_enums::CStyleEnum]
// cdb-command: dx k
-// cdb-check:k : Some({...}) [Type: enum$<core::option::Option<alloc::string::String>, 1, [...], Some>]
-// cdb-check: [<Raw View>] [Type: enum$<core::option::Option<alloc::string::String>, 1, [...], Some>]
-// cdb-check: [variant] : Some
+// cdb-check:k : Some [Type: enum2$<core::option::Option<alloc::string::String> >]
// cdb-check: [+0x000] __0 : "IAMA optional string!" [Type: alloc::string::String]
// cdb-command: dx l
-// cdb-check:l : Ok [Type: enum$<core::result::Result<u32,enum$<msvc_pretty_enums::Empty> >, Ok>]
-// cdb-check: [<Raw View>] [Type: enum$<core::result::Result<u32,enum$<msvc_pretty_enums::Empty> >, Ok>]
-// cdb-check: [variant] : Ok
+// cdb-check:l : Ok [Type: enum2$<core::result::Result<u32,enum2$<msvc_pretty_enums::Empty> > >]
// cdb-check: [+0x000] __0 : 0x2a [Type: unsigned int]
+// cdb-command: dx niche128_some
+// cdb-check: niche128_some : Some [Type: enum2$<core::option::Option<core::num::nonzero::NonZeroI128> >]
+// Note: we can't actually read the value of the field because CDB cannot handle 128 bit integers.
+// cdb-check: [+0x000] __0 [...] [Type: core::num::nonzero::NonZeroI128]
+
+// cdb-command: dx niche128_none
+// cdb-check: niche128_none : None [Type: enum2$<core::option::Option<core::num::nonzero::NonZeroI128> >]
+
+// cdb-command: dx wrapping_niche128_dataful
+// cdb-check: wrapping_niche128_dataful : X [Type: enum2$<msvc_pretty_enums::Wrapping128Niche>]
+// cdb-check: [+0x[...]] __0 [Type: msvc_pretty_enums::Wrapping128]
+
+// cdb-command: dx wrapping_niche128_none1
+// cdb-check: wrapping_niche128_none1 : Y [Type: enum2$<msvc_pretty_enums::Wrapping128Niche>]
+// cdb-check: [+0x[...]] __0 [Type: msvc_pretty_enums::Wrapping128]
+
+// cdb-command: dx wrapping_niche128_none2
+// cdb-check: wrapping_niche128_none2 : Z [Type: enum2$<msvc_pretty_enums::Wrapping128Niche>]
+// cdb-check: [+0x[...]] __0 [Type: msvc_pretty_enums::Wrapping128]
+
+// cdb-command: dx direct_tag_128_a,d
+// cdb-check: direct_tag_128_a,d : A [Type: enum2$<msvc_pretty_enums::DirectTag128>]
+// cdb-check: [+0x[...]] __0 : 42 [Type: unsigned int]
+
+// cdb-command: dx direct_tag_128_b,d
+// cdb-check: direct_tag_128_b,d : B [Type: enum2$<msvc_pretty_enums::DirectTag128>]
+// cdb-check: [+0x[...]] __0 : 137 [Type: unsigned int]
+
+// cdb-command: dx niche_w_fields_1_some,d
+// cdb-check: niche_w_fields_1_some,d : A [Type: enum2$<msvc_pretty_enums::NicheLayoutWithFields1>]
+// cdb-check: [+0x[...]] __0 : 0x[...] : 77 [Type: unsigned char *]
+// cdb-check: [+0x[...]] __1 : 7 [Type: unsigned int]
+
+// cdb-command: dx niche_w_fields_1_none,d
+// cdb-check: niche_w_fields_1_none,d : B [Type: enum2$<msvc_pretty_enums::NicheLayoutWithFields1>]
+// cdb-check: [+0x[...]] __0 : 99 [Type: unsigned int]
+
+// cdb-command: dx niche_w_fields_2_some,d
+// cdb-check: niche_w_fields_2_some,d : A [Type: enum2$<msvc_pretty_enums::NicheLayoutWithFields2>]
+// cdb-check: [+0x[...]] __0 : 800 [Type: core::num::nonzero::NonZeroU32]
+// cdb-check: [+0x[...]] __1 : 900 [Type: unsigned __int64]
+
+// cdb-command: dx niche_w_fields_2_none,d
+// cdb-check: niche_w_fields_2_none,d : B [Type: enum2$<msvc_pretty_enums::NicheLayoutWithFields2>]
+// cdb-check: [+0x[...]] __0 : 1000 [Type: unsigned __int64]
+
+// cdb-command: dx niche_w_fields_3_some,d
+// cdb-check: niche_w_fields_3_some,d : A [Type: enum2$<msvc_pretty_enums::NicheLayoutWithFields3>]
+// cdb-check: [+0x[...]] __0 : 137 [Type: unsigned char]
+// cdb-check: [+0x[...]] __1 : true [Type: bool]
+
+// cdb-command: dx niche_w_fields_3_niche1,d
+// cdb-check: niche_w_fields_3_niche1,d : B [Type: enum2$<msvc_pretty_enums::NicheLayoutWithFields3>]
+// cdb-check: [+0x[...]] __0 : 12 [Type: unsigned char]
+
+// cdb-command: dx niche_w_fields_3_niche2,d
+// cdb-check: niche_w_fields_3_niche2,d : C [Type: enum2$<msvc_pretty_enums::NicheLayoutWithFields3>]
+// cdb-check: [+0x[...]] __0 : false [Type: bool]
+
+// cdb-command: dx niche_w_fields_3_niche3,d
+// cdb-check: niche_w_fields_3_niche3,d : D [Type: enum2$<msvc_pretty_enums::NicheLayoutWithFields3>]
+// cdb-check: [+0x[...]] __0 : 34 [Type: unsigned char]
+
+// cdb-command: dx niche_w_fields_3_niche4,d
+// cdb-check: niche_w_fields_3_niche4,d : E [Type: enum2$<msvc_pretty_enums::NicheLayoutWithFields3>]
+// cdb-check: [+0x[...]] __0 : 56 [Type: unsigned char]
+
+// cdb-command: dx niche_w_fields_3_niche5,d
+// cdb-check: niche_w_fields_3_niche5,d : F [Type: enum2$<msvc_pretty_enums::NicheLayoutWithFields3>]
+
+// cdb-command: dx -r3 niche_w_fields_std_result_ok,d
+// cdb-check: niche_w_fields_std_result_ok,d : Ok [Type: enum2$<core::result::Result<alloc::boxed::Box<slice$<u8>,alloc::alloc::Global>,u64> >]
+// cdb-check: [+0x[...]] __0 [Type: alloc::boxed::Box<slice$<u8>,alloc::alloc::Global>]
+// cdb-check: [+0x[...]] data_ptr : [...]
+// cdb-check: [+0x[...]] length : 3 [...]
+
+// cdb-command: dx -r3 niche_w_fields_std_result_err,d
+// cdb-check: niche_w_fields_std_result_err,d : Err [Type: enum2$<core::result::Result<alloc::boxed::Box<slice$<u8>,alloc::alloc::Global>,u64> >]
+// cdb-check: [+0x[...]] __0 : 789 [Type: unsigned __int64]
+
+// cdb-command: dx -r2 arbitrary_discr1,d
+// cdb-check: arbitrary_discr1,d : Abc [Type: enum2$<msvc_pretty_enums::ArbitraryDiscr>]
+// cdb-check: [+0x[...]] __0 : 1234 [Type: unsigned int]
+
+// cdb-command: dx -r2 arbitrary_discr2,d
+// cdb-check: arbitrary_discr2,d : Def [Type: enum2$<msvc_pretty_enums::ArbitraryDiscr>]
+// cdb-check: [+0x[...]] __0 : 5678 [Type: unsigned int]
+
+#![feature(rustc_attrs)]
+#![feature(repr128)]
+#![feature(arbitrary_enum_discriminant)]
+
+use std::num::{NonZeroI128, NonZeroU32};
+
pub enum CStyleEnum {
Low = 2,
High = 16,
pub enum Empty {}
+// The following three types will use a niche layout once
+// https://github.com/rust-lang/rust/pull/94075 is merged:
+enum NicheLayoutWithFields1<'a> {
+ A(&'a u8, u32),
+ B(u32),
+}
+
+enum NicheLayoutWithFields2 {
+ A(NonZeroU32, u64),
+ B(u64),
+}
+
+enum NicheLayoutWithFields3 {
+ A(u8, bool),
+ B(u8),
+ C(bool),
+ D(u8),
+ E(u8),
+ F,
+}
+
+#[rustc_layout_scalar_valid_range_start(340282366920938463463374607431768211454)]
+#[rustc_layout_scalar_valid_range_end(1)]
+#[repr(transparent)]
+struct Wrapping128(u128);
+
+// #[rustc_layout(debug)]
+enum Wrapping128Niche {
+ X(Wrapping128),
+ Y,
+ Z,
+}
+
+#[repr(i128)]
+enum DirectTag128 {
+ A(u32),
+ B(u32),
+}
+
+#[repr(u32)]
+enum ArbitraryDiscr {
+ Abc(u32) = 1000,
+ Def(u32) = 5000_000,
+}
+
fn main() {
let a = Some(CStyleEnum::Low);
let b = Option::<CStyleEnum>::None;
let j = CStyleEnum::High;
let k = Some("IAMA optional string!".to_string());
let l = Result::<u32, Empty>::Ok(42);
+ let niche128_some = Some(NonZeroI128::new(123456).unwrap());
+ let niche128_none: Option<NonZeroI128> = None;
+
+ let wrapping_niche128_dataful =
+ unsafe { Wrapping128Niche::X(Wrapping128(340282366920938463463374607431768211454)) };
+ let wrapping_niche128_none1 = Wrapping128Niche::Y;
+ let wrapping_niche128_none2 = Wrapping128Niche::Z;
+
+ let direct_tag_128_a = DirectTag128::A(42);
+ let direct_tag_128_b = DirectTag128::B(137);
+
+ let niche_w_fields_1_some = NicheLayoutWithFields1::A(&77, 7);
+ let niche_w_fields_1_none = NicheLayoutWithFields1::B(99);
+
+ let niche_w_fields_2_some = NicheLayoutWithFields2::A(NonZeroU32::new(800).unwrap(), 900);
+ let niche_w_fields_2_none = NicheLayoutWithFields2::B(1000);
+
+ let niche_w_fields_3_some = NicheLayoutWithFields3::A(137, true);
+ let niche_w_fields_3_niche1 = NicheLayoutWithFields3::B(12);
+ let niche_w_fields_3_niche2 = NicheLayoutWithFields3::C(false);
+ let niche_w_fields_3_niche3 = NicheLayoutWithFields3::D(34);
+ let niche_w_fields_3_niche4 = NicheLayoutWithFields3::E(56);
+ let niche_w_fields_3_niche5 = NicheLayoutWithFields3::F;
+
+ let niche_w_fields_std_result_ok: Result<Box<[u8]>, u64> = Ok(vec![1, 2, 3].into());
+ let niche_w_fields_std_result_err: Result<Box<[u8]>, u64> = Err(789);
+
+ let arbitrary_discr1 = ArbitraryDiscr::Abc(1234);
+ let arbitrary_discr2 = ArbitraryDiscr::Def(5678);
zzz(); // #break
}
// cdb-command: g
// cdb-command: dx o1
-// cdb-check:o1 : Some [Type: enum$<core::option::Option<u32> >]
-// cdb-check: [variant] : Some
+// cdb-check:o1 : Some [Type: enum2$<core::option::Option<u32> >]
// cdb-check: [+0x004] __0 : 0x4d2 [Type: [...]]
// cdb-command: dx o2
-// cdb-check:o2 : Some [Type: enum$<core::option::Option<u64> >]
-// cdb-check: [variant] : Some
+// cdb-check:o2 : Some [Type: enum2$<core::option::Option<u64> >]
// cdb-check: [+0x008] __0 : 0x162e [Type: unsigned __int64]
// cdb-command: g
zzz(); // #break
}
-fn zzz() { }
+fn zzz() {}
fn main() {
range(10..12, 20..30);
// cdb-check: [<Raw View>] [Type: core::cell::UnsafeCell<i32>]
//
-// cdb-command:dx lock,d
-// cdb-check:lock,d : Ok [Type: enum$<core::result::Result<std::sync::mutex::MutexGuard<i32>,enum$<std::sync::poison::TryLockError<std::sync::mutex::MutexGuard<i32> >, 0, 1, Poisoned> > >]
-// cdb-check: [variant] : Ok
+// cdb-command:dx _lock,d
+// cdb-check:_lock,d : Ok [Type: enum2$<core::result::Result<std::sync::mutex::MutexGuard<i32>,enum2$<std::sync::poison::TryLockError<std::sync::mutex::MutexGuard<i32> > > > >]
// cdb-check: [...] __0 [Type: std::sync::mutex::MutexGuard<i32>]
use std::sync::Mutex;
-#[allow(unused_variables)]
-fn main()
-{
+fn main() {
let m = Mutex::new(0);
- let lock = m.try_lock();
+ let _lock = m.try_lock();
+
+ println!("this line avoids an `Ambiguous symbol error` while setting the breakpoint");
+
zzz(); // #break
}
+#[inline(never)]
fn zzz() {}
// gdb-command: print some_string
// gdb-check:$8 = Some = {"IAMA "...}
-
// === LLDB TESTS ==================================================================================
// lldb-command: run
// lldb-command: print os_string
// lldb-check:[...]$6 = "IAMA OS string 😃"[...]
-
// === CDB TESTS ==================================================================================
// cdb-command: g
// cdb-check: [chars] : "IAMA OS string [...]"
// cdb-command: dx some
-// cdb-check:some : Some [Type: enum$<core::option::Option<i16> >]
-// cdb-check: [<Raw View>] [Type: enum$<core::option::Option<i16> >]
-// cdb-check: [variant] : Some
+// cdb-check:some : Some [Type: enum2$<core::option::Option<i16> >]
+// cdb-check: [<Raw View>] [Type: enum2$<core::option::Option<i16> >]
// cdb-check: [+0x002] __0 : 8 [Type: short]
// cdb-command: dx none
-// cdb-check:none : None [Type: enum$<core::option::Option<i64> >]
-// cdb-check: [<Raw View>] [Type: enum$<core::option::Option<i64> >]
-// cdb-check: [variant] : None
+// cdb-check:none : None [Type: enum2$<core::option::Option<i64> >]
+// cdb-check: [<Raw View>] [Type: enum2$<core::option::Option<i64> >]
// cdb-command: dx some_string
-// cdb-check:some_string : Some({...}) [Type: enum$<core::option::Option<alloc::string::String>, 1, [...], Some>]
-// cdb-check: [<Raw View>] [Type: enum$<core::option::Option<alloc::string::String>, 1, [...], Some>]
-// cdb-check: [variant] : Some
+// cdb-check:some_string : Some [Type: enum2$<core::option::Option<alloc::string::String> >]
+// cdb-check: [<Raw View>] [Type: enum2$<core::option::Option<alloc::string::String> >]
// cdb-check: [+0x000] __0 : "IAMA optional string!" [Type: alloc::string::String]
// cdb-command: dx linkedlist
use std::ffi::OsString;
fn main() {
-
// &[]
let slice: &[i32] = &[0, 1, 2, 3];
zzz(); // #break
}
-fn zzz() { () }
+fn zzz() {
+ ()
+}
// cdb-command: g
// cdb-command: dx x,d
-// cdb-check:x,d : Ok [Type: enum$<core::result::Result<i32,str> >]
+// cdb-check:x,d : Ok [Type: enum2$<core::result::Result<i32,str> >]
// cdb-check: [...] __0 : -3 [Type: int]
// cdb-command: dx y
-// cdb-check:y : Err [Type: enum$<core::result::Result<i32,str> >]
+// cdb-check:y : Err [Type: enum2$<core::result::Result<i32,str> >]
// cdb-check: [...] __0 : "Some error message" [Type: str]
-fn main()
-{
+fn main() {
let x: Result<i32, &str> = Ok(-3);
assert_eq!(x.is_ok(), true);
zzz(); // #break.
}
-fn zzz() { () }
+fn zzz() {
+ ()
+}
// 0-sized structs appear to be optimized away in some cases, so only check the structs that do
// actually appear.
// cdb-command:dv /t *_struct
-// cdb-check:struct type_names::GenericStruct<enum$<type_names::mod1::Enum2>,f64> mut_generic_struct = [...]
+// cdb-check:struct type_names::GenericStruct<enum2$<type_names::mod1::Enum2>,f64> mut_generic_struct = [...]
// ENUMS
// cdb-command:dv /t *_enum_*
-// cdb-check:union enum$<type_names::Enum1> simple_enum_1 = [...]
-// cdb-check:union enum$<type_names::Enum1> simple_enum_2 = [...]
-// cdb-check:union enum$<type_names::mod1::Enum2> simple_enum_3 = [...]
-// cdb-check:union enum$<type_names::mod1::mod2::Enum3<type_names::mod1::Struct2> > generic_enum_1 = [...]
-// cdb-check:union enum$<type_names::mod1::mod2::Enum3<type_names::Struct1> > generic_enum_2 = [...]
+// cdb-check:union enum2$<type_names::Enum1> simple_enum_1 = [...]
+// cdb-check:union enum2$<type_names::Enum1> simple_enum_2 = [...]
+// cdb-check:union enum2$<type_names::mod1::Enum2> simple_enum_3 = [...]
+// cdb-check:union enum2$<type_names::mod1::mod2::Enum3<type_names::mod1::Struct2> > generic_enum_1 = [...]
+// cdb-check:union enum2$<type_names::mod1::mod2::Enum3<type_names::Struct1> > generic_enum_2 = [...]
// TUPLES
// cdb-command:dv /t tuple*
-// cdb-check:struct tuple$<u32,type_names::Struct1,enum$<type_names::mod1::mod2::Enum3<type_names::mod1::Struct2> > > tuple1 = [...]
-// cdb-check:struct tuple$<tuple$<type_names::Struct1,type_names::mod1::mod2::Struct3>,enum$<type_names::mod1::Enum2>,char> tuple2 = [...]
+// cdb-check:struct tuple$<u32,type_names::Struct1,enum2$<type_names::mod1::mod2::Enum3<type_names::mod1::Struct2> > > tuple1 = [...]
+// cdb-check:struct tuple$<tuple$<type_names::Struct1,type_names::mod1::mod2::Struct3>,enum2$<type_names::mod1::Enum2>,char> tuple2 = [...]
// BOX
// cdb-command:dv /t box*
// cdb-check:struct tuple$<alloc::boxed::Box<f32,alloc::alloc::Global>,i32> box1 = [...]
-// cdb-check:struct tuple$<alloc::boxed::Box<enum$<type_names::mod1::mod2::Enum3<f32> >,alloc::alloc::Global>,i32> box2 = [...]
+// cdb-check:struct tuple$<alloc::boxed::Box<enum2$<type_names::mod1::mod2::Enum3<f32> >,alloc::alloc::Global>,i32> box2 = [...]
// REFERENCES
// cdb-command:dv /t *ref*
// cdb-check:struct tuple$<ref$<type_names::Struct1>,i32> ref1 = [...]
// cdb-check:struct tuple$<ref$<type_names::GenericStruct<char,type_names::Struct1> >,i32> ref2 = [...]
// cdb-check:struct tuple$<ref_mut$<type_names::Struct1>,i32> mut_ref1 = [...]
-// cdb-check:struct tuple$<ref_mut$<type_names::GenericStruct<enum$<type_names::mod1::Enum2>,f64> >,i32> mut_ref2 = [...]
+// cdb-check:struct tuple$<ref_mut$<type_names::GenericStruct<enum2$<type_names::mod1::Enum2>,f64> >,i32> mut_ref2 = [...]
// RAW POINTERS
// cdb-command:dv /t *_ptr*
// cdb-check:struct tuple$<ptr_mut$<type_names::Struct1>,isize> mut_ptr1 = [...]
// cdb-check:struct tuple$<ptr_mut$<isize>,isize> mut_ptr2 = [...]
-// cdb-check:struct tuple$<ptr_mut$<enum$<type_names::mod1::mod2::Enum3<type_names::Struct1> > >,isize> mut_ptr3 = [...]
+// cdb-check:struct tuple$<ptr_mut$<enum2$<type_names::mod1::mod2::Enum3<type_names::Struct1> > >,isize> mut_ptr3 = [...]
// cdb-check:struct tuple$<ptr_const$<type_names::Struct1>,isize> const_ptr1 = [...]
// cdb-check:struct tuple$<ptr_const$<isize>,isize> const_ptr2 = [...]
-// cdb-check:struct tuple$<ptr_const$<enum$<type_names::mod1::mod2::Enum3<type_names::Struct1> > >,isize> const_ptr3 = [...]
+// cdb-check:struct tuple$<ptr_const$<enum2$<type_names::mod1::mod2::Enum3<type_names::Struct1> > >,isize> const_ptr3 = [...]
// VECTORS
// cdb-command:dv /t *vec*
// cdb-check:struct tuple$<array$<type_names::Struct1,3>,i16> fixed_size_vec1 = [...]
// cdb-check:struct tuple$<array$<usize,3>,i16> fixed_size_vec2 = [...]
// cdb-check:struct alloc::vec::Vec<usize,alloc::alloc::Global> vec1 = [...]
-// cdb-check:struct alloc::vec::Vec<enum$<type_names::mod1::Enum2>,alloc::alloc::Global> vec2 = [...]
+// cdb-check:struct alloc::vec::Vec<enum2$<type_names::mod1::Enum2>,alloc::alloc::Global> vec2 = [...]
// cdb-command:dv /t slice*
// cdb-check:struct slice$<usize> slice1 = [...]
-// cdb-check:struct slice$<enum$<type_names::mod1::Enum2> > slice2 = [...]
+// cdb-check:struct slice$<enum2$<type_names::mod1::Enum2> > slice2 = [...]
// TRAITS
// cdb-command:dv /t *_trait
// cdb-check:struct tuple$<type_names::mod1::Struct2 (*)(type_names::GenericStruct<u16,u8>),usize> unsafe_fn_with_return_value = [...]
// cdb-check:struct tuple$<type_names::Struct1 (*)(),usize> extern_c_fn_with_return_value = [...]
// cdb-check:struct tuple$<usize (*)(f64),usize> rust_fn_with_return_value = [...]
-// cdb-check:struct tuple$<void (*)(enum$<core::result::Result<char,f64> >),usize> unsafe_fn = [...]
+// cdb-check:struct tuple$<void (*)(enum2$<core::result::Result<char,f64> >),usize> unsafe_fn = [...]
// cdb-check:struct tuple$<void (*)(isize),usize> extern_c_fn = [...]
-// cdb-check:struct tuple$<void (*)(enum$<core::option::Option<isize> >,enum$<core::option::Option<ref$<type_names::mod1::Struct2> >, 1, [...], Some>),usize> rust_fn = [...]
+// cdb-check:struct tuple$<void (*)(enum2$<core::option::Option<isize> >,enum2$<core::option::Option<ref$<type_names::mod1::Struct2> > >),usize> rust_fn = [...]
// cdb-command:dv /t *_function*
// cdb-check:struct tuple$<isize (*)(ptr_const$<u8>, ...),usize> variadic_function = [...]
// cdb-check:struct tuple$<type_names::mod1::mod2::Struct3 (*)(type_names::mod1::mod2::Struct3),usize> generic_function_struct3 = [...]
// cdb-check:struct tuple$<isize (*)(isize),usize> generic_function_int = [...]
// cdb-command:dx Debugger.State.Scripts.@"type-names.cdb".Contents.getFunctionDetails("rust_fn")
// cdb-check:Return Type: void
-// cdb-check:Parameter Types: enum$<core::option::Option<isize> >,enum$<core::option::Option<ref$<type_names::mod1::Struct2> >, 1, [...], Some>
+// cdb-check:Parameter Types: enum2$<core::option::Option<isize> >,enum2$<core::option::Option<ref$<type_names::mod1::Struct2> > >
// cdb-command:dx Debugger.State.Scripts.@"type-names.cdb".Contents.getFunctionDetails("rust_fn_with_return_value")
// cdb-check:Return Type: usize
// cdb-check:Parameter Types: f64
--- /dev/null
+-include ../../run-make-fulldeps/tools.mk
+
+# Regression test for issue #85401
+# Verify that we do not ICE when trying to access MIR for statics,
+# but emit an error when linking.
+
+OUTPUT_FILE := $(TMPDIR)/build-output
+
+all:
+ $(RUSTC) --crate-type rlib --crate-name foo -Crelocation-model=pic --edition=2018 foo.rs -Zalways-encode-mir=yes --emit metadata -o $(TMPDIR)/libfoo.rmeta
+ $(RUSTC) --crate-type rlib --crate-name bar -Crelocation-model=pic --edition=2018 bar.rs -o $(TMPDIR)/libbar.rlib --extern=foo=$(TMPDIR)/libfoo.rmeta
+ $(RUSTC) --crate-type bin --crate-name baz -Crelocation-model=pic --edition=2018 baz.rs -o $(TMPDIR)/baz -L $(TMPDIR) --extern=bar=$(TMPDIR)/libbar.rlib > $(OUTPUT_FILE) 2>&1; [ $$? -eq 1 ]
+ cat $(OUTPUT_FILE)
+ $(CGREP) 'crate `foo` required to be available in rlib format, but was not found in this form' < $(OUTPUT_FILE)
+ # -v tests are fragile, hopefully this text won't change
+ $(CGREP) -v "internal compiler error" < $(OUTPUT_FILE)
--- /dev/null
+pub fn bar() {
+ println!("bar {}", foo::FOO);
+ foo::foo();
+}
--- /dev/null
+fn main() {
+ bar::bar()
+}
--- /dev/null
+pub static FOO: &str = "foo";
+
+pub fn foo() {
+ println!("foo");
+}
all: normal custom sysroot
-normal: basic-translation.rs
+# Check that the test works normally, using the built-in fallback bundle.
+normal: test.rs
$(RUSTC) $< 2>&1 | grep "struct literal body without path"
-custom: basic-translation.rs basic-translation.ftl
- $(RUSTC) $< -Ztranslate-additional-ftl=$(CURDIR)/basic-translation.ftl 2>&1 | grep "this is a test message"
+# Check that a primary bundle can be loaded and will be preferentially used
+# where possible.
+custom: test.rs working.ftl
+ $(RUSTC) $< -Ztranslate-additional-ftl=$(CURDIR)/working.ftl 2>&1 | grep "this is a test message"
+
+# Check that a primary bundle with a broken message (e.g. a interpolated
+# variable is missing) will use the fallback bundle.
+missing: test.rs missing.ftl
+ $(RUSTC) $< -Ztranslate-additional-ftl=$(CURDIR)/missing.ftl 2>&1 | grep "struct literal body without path"
+
+# Check that a primary bundle without the desired message will use the fallback
+# bundle.
+broken: test.rs broken.ftl
+ $(RUSTC) $< -Ztranslate-additional-ftl=$(CURDIR)/broken.ftl 2>&1 | grep "struct literal body without path"
# Check that a locale can be loaded from the sysroot given a language
# identifier by making a local copy of the sysroot and adding the custom locale
# to it.
-sysroot: basic-translation.rs basic-translation.ftl
+sysroot: test.rs working.ftl
mkdir $(FAKEROOT)
ln -s $(SYSROOT)/* $(FAKEROOT)
rm -f $(FAKEROOT)/lib
mkdir $(FAKEROOT)/lib/rustlib/src
ln -s $(SYSROOT)/lib/rustlib/src/* $(FAKEROOT)/lib/rustlib/src
mkdir -p $(FAKEROOT)/share/locale/zh-CN/
- ln -s $(CURDIR)/basic-translation.ftl $(FAKEROOT)/share/locale/zh-CN/basic-translation.ftl
+ ln -s $(CURDIR)/working.ftl $(FAKEROOT)/share/locale/zh-CN/basic-translation.ftl
$(RUSTC) $< --sysroot $(FAKEROOT) -Ztranslate-lang=zh-CN 2>&1 | grep "this is a test message"
# Check that the compiler errors out when the sysroot requested cannot be
# Check that the compiler errors out when the sysroot requested cannot be
# found. This test might start failing if there actually exists a Klingon
# translation of rustc's error messages.
-sysroot-invalid: basic-translation.rs basic-translation.ftl
+sysroot-invalid: test.rs working.ftl
mkdir $(FAKEROOT)
ln -s $(SYSROOT)/* $(FAKEROOT)
rm -f $(FAKEROOT)/lib
+++ /dev/null
-parser-struct-literal-body-without-path = this is a test message
- .suggestion = this is a test suggestion
+++ /dev/null
-// Exact error being tested isn't relevant, it just needs to be known that it uses Fluent-backed
-// diagnostics.
-
-struct Foo {
- val: (),
-}
-
-fn foo() -> Foo {
- val: (),
-}
-
-fn main() {
- let x = foo();
- x.val == 42;
- let x = {
- val: (),
- };
-}
--- /dev/null
+# `foo` isn't provided by this diagnostic so it is expected that the fallback message is used.
+parser_struct_literal_body_without_path = this is a {$foo} message
+ .suggestion = this is a test suggestion
--- /dev/null
+# `parser_struct_literal_body_without_path` isn't provided by this resource at all, so the
+# fallback should be used.
+foo = bar
--- /dev/null
+// Exact error being tested isn't relevant, it just needs to be known that it uses Fluent-backed
+// diagnostics.
+
+struct Foo {
+ val: (),
+}
+
+fn foo() -> Foo {
+ val: (),
+}
+
+fn main() {
+ let x = foo();
+ x.val == 42;
+ let x = {
+ val: (),
+ };
+}
--- /dev/null
+parser_struct_literal_body_without_path = this is a test message
+ .suggestion = this is a test suggestion
// @is - "$.index[*][?(@.name=='generics')].inner.generics.params[0].name" '"F"'
// @is - "$.index[*][?(@.name=='generics')].inner.generics.params[0].kind.type.default" 'null'
// @count - "$.index[*][?(@.name=='generics')].inner.generics.params[0].kind.type.bounds[*]" 1
-// @is - "$.index[*][?(@.name=='generics')].inner.generics.params[0].kind.type.bounds[0].trait_bound.trait.inner.id" '$foo'
+// @is - "$.index[*][?(@.name=='generics')].inner.generics.params[0].kind.type.bounds[0].trait_bound.trait.id" '$foo'
// @count - "$.index[*][?(@.name=='generics')].inner.decl.inputs[*]" 1
// @is - "$.index[*][?(@.name=='generics')].inner.decl.inputs[0][0]" '"f"'
// @is - "$.index[*][?(@.name=='generics')].inner.decl.inputs[0][1].kind" '"generic"'
// @is - "$.index[*][?(@.name=='impl_trait')].inner.generics.where_predicates" "[]"
// @count - "$.index[*][?(@.name=='impl_trait')].inner.generics.params[*]" 1
// @is - "$.index[*][?(@.name=='impl_trait')].inner.generics.params[0].name" '"impl Foo"'
-// @is - "$.index[*][?(@.name=='impl_trait')].inner.generics.params[0].kind.type.bounds[0].trait_bound.trait.inner.id" $foo
+// @is - "$.index[*][?(@.name=='impl_trait')].inner.generics.params[0].kind.type.bounds[0].trait_bound.trait.id" $foo
// @count - "$.index[*][?(@.name=='impl_trait')].inner.decl.inputs[*]" 1
// @is - "$.index[*][?(@.name=='impl_trait')].inner.decl.inputs[0][0]" '"f"'
// @is - "$.index[*][?(@.name=='impl_trait')].inner.decl.inputs[0][1].kind" '"impl_trait"'
// @count - "$.index[*][?(@.name=='impl_trait')].inner.decl.inputs[0][1].inner[*]" 1
-// @is - "$.index[*][?(@.name=='impl_trait')].inner.decl.inputs[0][1].inner[0].trait_bound.trait.inner.id" $foo
+// @is - "$.index[*][?(@.name=='impl_trait')].inner.decl.inputs[0][1].inner[0].trait_bound.trait.id" $foo
pub fn impl_trait(f: impl Foo) {}
// @count - "$.index[*][?(@.name=='where_clase')].inner.generics.params[*]" 3
// @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[0].bound_predicate.type" '{"inner": "F", "kind": "generic"}'
// @count - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[0].bound_predicate.bounds[*]" 1
-// @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[0].bound_predicate.bounds[0].trait_bound.trait.inner.id" $foo
+// @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[0].bound_predicate.bounds[0].trait_bound.trait.id" $foo
// @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[1].bound_predicate.type" '{"inner": "G", "kind": "generic"}'
// @count - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[1].bound_predicate.bounds[*]" 1
-// @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[1].bound_predicate.bounds[0].trait_bound.trait.inner.id" $generic_foo
+// @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[1].bound_predicate.bounds[0].trait_bound.trait.id" $generic_foo
// @count - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[1].bound_predicate.bounds[0].trait_bound.generic_params[*]" 1
// @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[1].bound_predicate.bounds[0].trait_bound.generic_params[0].name" \"\'a\"
// @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[1].bound_predicate.bounds[0].trait_bound.generic_params[0].kind" '{ "lifetime": { "outlives": [] } }'
// @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[2].bound_predicate.type.inner.lifetime" \"\'b\"
// @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[2].bound_predicate.type.inner.type" '{"inner": "H", "kind": "generic"}'
// @count - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[2].bound_predicate.bounds[*]" 1
-// @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[2].bound_predicate.bounds[0].trait_bound.trait.inner.id" $foo
+// @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[2].bound_predicate.bounds[0].trait_bound.trait.id" $foo
// @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[2].bound_predicate.bounds[0].trait_bound.generic_params" "[]"
// @count - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[2].bound_predicate.generic_params[*]" 1
// @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[2].bound_predicate.generic_params[0].name" \"\'b\"
// @is - "$.index[*][?(@.name=='get_foo')].inner.decl.inputs" []
// @is - "$.index[*][?(@.name=='get_foo')].inner.decl.output.kind" '"impl_trait"'
// @count - "$.index[*][?(@.name=='get_foo')].inner.decl.output.inner[*]" 1
-// @is - "$.index[*][?(@.name=='get_foo')].inner.decl.output.inner[0].trait_bound.trait.inner.id" $foo
+// @is - "$.index[*][?(@.name=='get_foo')].inner.decl.output.inner[0].trait_bound.trait.id" $foo
pub fn get_foo() -> impl Foo {
Fooer {}
}
// @count - "$.index[*][?(@.name=='one_generic_param_fn')].inner.generics.params[*]" 1
// @is - "$.index[*][?(@.name=='one_generic_param_fn')].inner.generics.params[0].name" '"T"'
// @has - "$.index[*][?(@.name=='one_generic_param_fn')].inner.generics.params[0].kind.type.synthetic" false
-// @has - "$.index[*][?(@.name=='one_generic_param_fn')].inner.generics.params[0].kind.type.bounds[0].trait_bound.trait.inner.id" $wham_id
+// @has - "$.index[*][?(@.name=='one_generic_param_fn')].inner.generics.params[0].kind.type.bounds[0].trait_bound.trait.id" $wham_id
// @is - "$.index[*][?(@.name=='one_generic_param_fn')].inner.decl.inputs" '[["w", {"inner": "T", "kind": "generic"}]]'
pub fn one_generic_param_fn<T: Wham>(w: T) {}
// @count - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.generics.params[*]" 1
// @is - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.generics.params[0].name" '"impl Wham"'
// @has - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.generics.params[0].kind.type.synthetic" true
-// @has - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.generics.params[0].kind.type.bounds[0].trait_bound.trait.inner.id" $wham_id
+// @has - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.generics.params[0].kind.type.bounds[0].trait_bound.trait.id" $wham_id
// @count - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.decl.inputs[*]" 1
// @is - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.decl.inputs[0][0]" '"w"'
// @is - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.decl.inputs[0][1].kind" '"impl_trait"'
-// @is - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.decl.inputs[0][1].inner[0].trait_bound.trait.inner.id" $wham_id
+// @is - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.decl.inputs[0][1].inner[0].trait_bound.trait.id" $wham_id
pub fn one_synthetic_generic_param_fn(w: impl Wham) {}
--- /dev/null
+#![feature(no_core, auto_traits, lang_items)]
+#![no_core]
+
+#[lang = "sized"]
+trait Sized {}
+
+pub auto trait Bar {}
+
+/// has span
+impl Foo {
+ pub fn baz(&self) {}
+}
+
+// Testing spans, so all tests below code
+// @is auto.json "$.index[*][?(@.kind=='impl' && @.inner.synthetic==true)].span" null
+// @is - "$.index[*][?(@.docs=='has span')].span.begin" "[10, 0]"
+// @is - "$.index[*][?(@.docs=='has span')].span.end" "[12, 1]"
+pub struct Foo;
--- /dev/null
+// https://github.com/rust-lang/rust/issues/100252
+
+#![feature(no_core)]
+#![no_core]
+
+mod bar {
+ // @set baz = import_from_private.json "$.index[*][?(@.kind=='struct')].id"
+ pub struct Baz;
+ // @set impl = - "$.index[*][?(@.kind=='impl')].id"
+ impl Baz {
+ // @set doit = - "$.index[*][?(@.kind=='method')].id"
+ pub fn doit() {}
+ }
+}
+
+// @set import = - "$.index[*][?(@.kind=='import')].id"
+pub use bar::Baz;
+
+// FIXME(adotinthevoid): Use hasexact once #99474 lands
+
+// @has - "$.index[*][?(@.kind=='module')].inner.items[*]" $import
+// @is - "$.index[*][?(@.kind=='import')].inner.id" $baz
+// @has - "$.index[*][?(@.kind=='struct')].inner.impls[*]" $impl
+// @has - "$.index[*][?(@.kind=='impl')].inner.items[*]" $doit
// @set very_loud_id = - "$.index[*][?(@.name=='VeryLoud')].id"
// @count - "$.index[*][?(@.name=='VeryLoud')].inner.bounds[*]" 1
-// @is - "$.index[*][?(@.name=='VeryLoud')].inner.bounds[0].trait_bound.trait.inner.id" $loud_id
+// @is - "$.index[*][?(@.name=='VeryLoud')].inner.bounds[0].trait_bound.trait.id" $loud_id
pub trait VeryLoud: Loud {}
// @set sounds_good_id = - "$.index[*][?(@.name=='SoundsGood')].id"
pub trait SoundsGood {}
// @count - "$.index[*][?(@.name=='MetalBand')].inner.bounds[*]" 2
-// @is - "$.index[*][?(@.name=='MetalBand')].inner.bounds[0].trait_bound.trait.inner.id" $very_loud_id
-// @is - "$.index[*][?(@.name=='MetalBand')].inner.bounds[1].trait_bound.trait.inner.id" $sounds_good_id
+// @is - "$.index[*][?(@.name=='MetalBand')].inner.bounds[0].trait_bound.trait.id" $very_loud_id
+// @is - "$.index[*][?(@.name=='MetalBand')].inner.bounds[1].trait_bound.trait.id" $sounds_good_id
pub trait MetalBand: VeryLoud + SoundsGood {}
// @count - "$.index[*][?(@.name=='DnabLatem')].inner.bounds[*]" 2
-// @is - "$.index[*][?(@.name=='DnabLatem')].inner.bounds[1].trait_bound.trait.inner.id" $very_loud_id
-// @is - "$.index[*][?(@.name=='DnabLatem')].inner.bounds[0].trait_bound.trait.inner.id" $sounds_good_id
+// @is - "$.index[*][?(@.name=='DnabLatem')].inner.bounds[1].trait_bound.trait.id" $very_loud_id
+// @is - "$.index[*][?(@.name=='DnabLatem')].inner.bounds[0].trait_bound.trait.id" $sounds_good_id
pub trait DnabLatem: SoundsGood + VeryLoud {}
// @is - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.traits[0].generic_params" []
// @is - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.traits[1].generic_params" []
// @is - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.traits[2].generic_params" []
-// @is - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.traits[0].trait.inner.name" '"Fn"'
-// @is - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.traits[1].trait.inner.name" '"Send"'
-// @is - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.traits[2].trait.inner.name" '"Sync"'
-// @is - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.traits[0].trait.inner.args" '{"parenthesized": {"inputs": [],"output": {"inner": "i32","kind": "primitive"}}}'
+// @is - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.traits[0].trait.name" '"Fn"'
+// @is - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.traits[1].trait.name" '"Send"'
+// @is - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.traits[2].trait.name" '"Sync"'
+// @is - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.traits[0].trait.args" '{"parenthesized": {"inputs": [],"output": {"inner": "i32","kind": "primitive"}}}'
pub type SyncIntGen = Box<dyn Fn() -> i32 + Send + Sync + 'static>;
// @is - "$.index[*][?(@.name=='RefFn')].kind" \"typedef\"
// @is - "$.index[*][?(@.name=='RefFn')].inner.type.inner.type.inner.lifetime" null
// @count - "$.index[*][?(@.name=='RefFn')].inner.type.inner.type.inner.traits[*]" 1
// @is - "$.index[*][?(@.name=='RefFn')].inner.type.inner.type.inner.traits[0].generic_params" '[{"kind": {"lifetime": {"outlives": []}},"name": "'\''b"}]'
-// @is - "$.index[*][?(@.name=='RefFn')].inner.type.inner.type.inner.traits[0].trait.kind" '"resolved_path"'
-// @is - "$.index[*][?(@.name=='RefFn')].inner.type.inner.type.inner.traits[0].trait.inner.name" '"Fn"'
-// @is - "$.index[*][?(@.name=='RefFn')].inner.type.inner.type.inner.traits[0].trait.inner.args.parenthesized.inputs[0].kind" '"borrowed_ref"'
-// @is - "$.index[*][?(@.name=='RefFn')].inner.type.inner.type.inner.traits[0].trait.inner.args.parenthesized.inputs[0].inner.lifetime" "\"'b\""
-// @is - "$.index[*][?(@.name=='RefFn')].inner.type.inner.type.inner.traits[0].trait.inner.args.parenthesized.output.kind" '"borrowed_ref"'
-// @is - "$.index[*][?(@.name=='RefFn')].inner.type.inner.type.inner.traits[0].trait.inner.args.parenthesized.output.inner.lifetime" "\"'b\""
+// @is - "$.index[*][?(@.name=='RefFn')].inner.type.inner.type.inner.traits[0].trait.name" '"Fn"'
+// @is - "$.index[*][?(@.name=='RefFn')].inner.type.inner.type.inner.traits[0].trait.args.parenthesized.inputs[0].kind" '"borrowed_ref"'
+// @is - "$.index[*][?(@.name=='RefFn')].inner.type.inner.type.inner.traits[0].trait.args.parenthesized.inputs[0].inner.lifetime" "\"'b\""
+// @is - "$.index[*][?(@.name=='RefFn')].inner.type.inner.type.inner.traits[0].trait.args.parenthesized.output.kind" '"borrowed_ref"'
+// @is - "$.index[*][?(@.name=='RefFn')].inner.type.inner.type.inner.traits[0].trait.args.parenthesized.output.inner.lifetime" "\"'b\""
pub type RefFn<'a> = &'a dyn for<'b> Fn(&'b i32) -> &'b i32;
-// @is - "$.index[*][?(@.name=='WeirdOrder')].inner.type.inner.args.angle_bracketed.args[0].type.inner.traits[0].trait.inner.name" '"Send"'
-// @is - "$.index[*][?(@.name=='WeirdOrder')].inner.type.inner.args.angle_bracketed.args[0].type.inner.traits[1].trait.inner.name" '"Debug"'
+// @is - "$.index[*][?(@.name=='WeirdOrder')].inner.type.inner.args.angle_bracketed.args[0].type.inner.traits[0].trait.name" '"Send"'
+// @is - "$.index[*][?(@.name=='WeirdOrder')].inner.type.inner.args.angle_bracketed.args[0].type.inner.traits[1].trait.name" '"Debug"'
pub type WeirdOrder = Box<dyn Send + Debug>;
// @is - "$.index[*][?(@.name=='dynfn')].inner.decl.inputs[0][1].inner.type.inner.lifetime" null
// @count - "$.index[*][?(@.name=='dynfn')].inner.decl.inputs[0][1].inner.type.inner.traits[*]" 1
// @is - "$.index[*][?(@.name=='dynfn')].inner.decl.inputs[0][1].inner.type.inner.traits[0].generic_params" '[{"kind": {"lifetime": {"outlives": []}},"name": "'\''a"},{"kind": {"lifetime": {"outlives": []}},"name": "'\''b"}]'
-// @is - "$.index[*][?(@.name=='dynfn')].inner.decl.inputs[0][1].inner.type.inner.traits[0].trait.inner.name" '"Fn"'
+// @is - "$.index[*][?(@.name=='dynfn')].inner.decl.inputs[0][1].inner.type.inner.traits[0].trait.name" '"Fn"'
pub fn dynfn(f: &dyn for<'a, 'b> Fn(&'a i32, &'b i32)) {
let zero = 0;
f(&zero, &zero);
-Z emit-stack-sizes=val -- emit a section containing stack size metadata (default: no)
-Z emit-thin-lto=val -- emit the bc module with thin LTO info (default: yes)
-Z export-executable-symbols=val -- export symbols from executables, as if they were dynamic libraries
+ -Z extra-const-ub-checks=val -- turns on more checks to detect const UB, which can be slow (default: no)
-Z fewer-names=val -- reduce memory use by retaining fewer names within compilation artifacts (LLVM-IR) (default: no)
-Z force-unstable-if-unmarked=val -- force all crates to be `rustc_private` unstable (default: no)
-Z fuel=val -- set the optimization fuel quota for a crate
}
// @has foo/all.html '//a[@href="struct.ReexportedStruct.html"]' 'ReexportedStruct'
-// @!has foo/all.html 'private_module'
+// @!hasraw foo/all.html 'private_module'
pub use private_module::ReexportedStruct;
const FOO: usize = 12 + 1;
// @has - '//*[@id="associatedconstant.FOO_NO_DEFAULT"]' 'const FOO_NO_DEFAULT: bool'
const FOO_NO_DEFAULT: bool;
- // @!has - FOO_HIDDEN
+ // @!hasraw - FOO_HIDDEN
#[doc(hidden)]
const FOO_HIDDEN: u8 = 0;
}
const FOO: usize = 12;
// @has - '//*[@id="associatedconstant.FOO_NO_DEFAULT"]' 'const FOO_NO_DEFAULT: bool'
const FOO_NO_DEFAULT: bool = false;
- // @!has - FOO_HIDDEN
+ // @!hasraw - FOO_HIDDEN
#[doc(hidden)]
const FOO_HIDDEN: u8 = 0;
}
}
impl Bar {
- // @!has assoc_consts/struct.Bar.html 'BAR_PRIVATE'
+ // @!hasraw assoc_consts/struct.Bar.html 'BAR_PRIVATE'
const BAR_PRIVATE: char = 'a';
- // @!has assoc_consts/struct.Bar.html 'BAR_HIDDEN'
+ // @!hasraw assoc_consts/struct.Bar.html 'BAR_HIDDEN'
#[doc(hidden)]
pub const BAR_HIDDEN: &'static str = "a";
}
pub const unsafe fn foo_unsafe() -> u32 { 42 }
// @has 'foo/fn.foo2.html' '//pre' 'pub const fn foo2() -> u32'
-// @!has - '//span[@class="since"]'
+// @!hasraw - '//span[@class="since"]'
#[unstable(feature = "humans", issue = "none")]
pub const fn foo2() -> u32 { 42 }
// @has 'foo/fn.foo2_gated.html' '//pre' 'pub const unsafe fn foo2_gated() -> u32'
-// @!has - '//span[@class="since"]'
+// @!hasraw - '//span[@class="since"]'
#[unstable(feature = "foo2", issue = "none")]
pub const unsafe fn foo2_gated() -> u32 { 42 }
pub const unsafe fn bar2_gated() -> u32 { 42 }
// @has 'foo/fn.bar_not_gated.html' '//pre' 'pub const unsafe fn bar_not_gated() -> u32'
-// @!has - '//span[@class="since"]'
+// @!hasraw - '//span[@class="since"]'
pub const unsafe fn bar_not_gated() -> u32 { 42 }
pub struct Foo;
impl Foo0 {
// @has - '//*[@class="stab deprecated"]' 'Deprecated since 1.0.1: fn_with_doc'
- // @has - 'fn_with_doc short'
- // @has - 'fn_with_doc full'
+ // @hasraw - 'fn_with_doc short'
+ // @hasraw - 'fn_with_doc full'
/// fn_with_doc short
///
/// fn_with_doc full
impl Bar for Foo1 {
// @has - '//*[@class="stab deprecated"]' 'Deprecated since 1.0.3: fn_empty_with_doc'
- // @has - 'fn_empty_with_doc_impl short'
- // @has - 'fn_empty_with_doc_impl full'
+ // @hasraw - 'fn_empty_with_doc_impl short'
+ // @hasraw - 'fn_empty_with_doc_impl full'
/// fn_empty_with_doc_impl short
///
/// fn_empty_with_doc_impl full
fn fn_empty_without_doc() {}
// @has - '//*[@class="stab deprecated"]' 'Deprecated since 1.0.5: fn_def_with_doc'
- // @has - 'fn_def_with_doc_impl short'
- // @has - 'fn_def_with_doc_impl full'
+ // @hasraw - 'fn_def_with_doc_impl short'
+ // @hasraw - 'fn_def_with_doc_impl full'
/// fn_def_with_doc_impl short
///
/// fn_def_with_doc_impl full
fn fn_def_without_doc() {}
// @has - '//*[@class="stab deprecated"]' 'Deprecated since 1.0.7: fn_def_def_with_doc'
- // @has - 'fn_def_def_with_doc short'
- // @!has - 'fn_def_def_with_doc full'
+ // @hasraw - 'fn_def_def_with_doc short'
+ // @!hasraw - 'fn_def_def_with_doc full'
// @has - '//*[@class="stab deprecated"]' 'Deprecated since 1.0.8: fn_def_def_without_doc'
}
impl Bar for Foo2 {
// @has - '//*[@class="stab deprecated"]' 'Deprecated since 1.0.3: fn_empty_with_doc'
- // @has - 'fn_empty_with_doc short'
- // @!has - 'fn_empty_with_doc full'
+ // @hasraw - 'fn_empty_with_doc short'
+ // @!hasraw - 'fn_empty_with_doc full'
fn fn_empty_with_doc() {}
// @has - '//*[@class="stab deprecated"]' 'Deprecated since 1.0.4: fn_empty_without_doc'
- // @has - 'fn_empty_without_doc_impl short'
- // @has - 'fn_empty_without_doc_impl full'
+ // @hasraw - 'fn_empty_without_doc_impl short'
+ // @hasraw - 'fn_empty_without_doc_impl full'
/// fn_empty_without_doc_impl short
///
/// fn_empty_without_doc_impl full
fn fn_empty_without_doc() {}
// @has - '//*[@class="stab deprecated"]' 'Deprecated since 1.0.5: fn_def_with_doc'
- // @has - 'fn_def_with_doc short'
- // @!has - 'fn_def_with_doc full'
+ // @hasraw - 'fn_def_with_doc short'
+ // @!hasraw - 'fn_def_with_doc full'
fn fn_def_with_doc() {}
// @has - '//*[@class="stab deprecated"]' 'Deprecated since 1.0.6: fn_def_without_doc'
- // @has - 'fn_def_without_doc_impl short'
- // @has - 'fn_def_without_doc_impl full'
+ // @hasraw - 'fn_def_without_doc_impl short'
+ // @hasraw - 'fn_def_without_doc_impl full'
/// fn_def_without_doc_impl short
///
/// fn_def_without_doc_impl full
fn fn_def_without_doc() {}
// @has - '//*[@class="stab deprecated"]' 'Deprecated since 1.0.7: fn_def_def_with_doc'
- // @has - 'fn_def_def_with_doc short'
- // @!has - 'fn_def_def_with_doc full'
+ // @hasraw - 'fn_def_def_with_doc short'
+ // @!hasraw - 'fn_def_def_with_doc full'
// @has - '//*[@class="stab deprecated"]' 'Deprecated since 1.0.8: fn_def_def_without_doc'
}
type ARef<'a> = Ref<'a>;
// @has foo/fn.test1.html
-// @matches - "Ref</a><'_>"
+// @matchesraw - "Ref</a><'_>"
pub fn test1(a: &u32) -> Ref {
Ref(a)
}
// @has foo/fn.test2.html
-// @matches - "Ref</a><'_>"
+// @matchesraw - "Ref</a><'_>"
pub fn test2(a: &u32) -> Ref<'_> {
Ref(a)
}
// @has foo/fn.test3.html
-// @matches - "Ref</a><'_>"
+// @matchesraw - "Ref</a><'_>"
pub fn test3(a: &u32) -> ARef {
Ref(a)
}
// @has foo/fn.test4.html
-// @matches - "Ref</a><'_>"
+// @matchesraw - "Ref</a><'_>"
pub fn test4(a: &u32) -> ARef<'_> {
Ref(a)
}
// Ensure external paths in inlined docs also display elided lifetime
// @has foo/bar/fn.test5.html
-// @matches - "Ref</a><'_>"
+// @matchesraw - "Ref</a><'_>"
// @has foo/bar/fn.test6.html
-// @matches - "Ref</a><'_>"
+// @matchesraw - "Ref</a><'_>"
#[doc(inline)]
pub extern crate bar;
// compile-flags: --document-private-items
// @has 'empty_mod_private/index.html' '//a[@href="foo/index.html"]' 'foo'
-// @has 'empty_mod_private/sidebar-items.js' 'foo'
+// @hasraw 'empty_mod_private/sidebar-items.js' 'foo'
// @matches 'empty_mod_private/foo/index.html' '//h1' 'Module empty_mod_private::foo'
mod foo {}
// @has 'empty_mod_private/index.html' '//a[@href="bar/index.html"]' 'bar'
-// @has 'empty_mod_private/sidebar-items.js' 'bar'
+// @hasraw 'empty_mod_private/sidebar-items.js' 'bar'
// @matches 'empty_mod_private/bar/index.html' '//h1' 'Module empty_mod_private::bar'
mod bar {
// @has 'empty_mod_private/bar/index.html' '//a[@href="baz/index.html"]' 'baz'
- // @has 'empty_mod_private/bar/sidebar-items.js' 'baz'
+ // @hasraw 'empty_mod_private/bar/sidebar-items.js' 'baz'
// @matches 'empty_mod_private/bar/baz/index.html' '//h1' 'Module empty_mod_private::bar::baz'
mod baz {}
}
// @has 'empty_mod_public/index.html' '//a[@href="foo/index.html"]' 'foo'
-// @has 'empty_mod_public/sidebar-items.js' 'foo'
+// @hasraw 'empty_mod_public/sidebar-items.js' 'foo'
// @matches 'empty_mod_public/foo/index.html' '//h1' 'Module empty_mod_public::foo'
pub mod foo {}
// @has 'empty_mod_public/index.html' '//a[@href="bar/index.html"]' 'bar'
-// @has 'empty_mod_public/sidebar-items.js' 'bar'
+// @hasraw 'empty_mod_public/sidebar-items.js' 'bar'
// @matches 'empty_mod_public/bar/index.html' '//h1' 'Module empty_mod_public::bar'
pub mod bar {
// @has 'empty_mod_public/bar/index.html' '//a[@href="baz/index.html"]' 'baz'
- // @has 'empty_mod_public/bar/sidebar-items.js' 'baz'
+ // @hasraw 'empty_mod_public/bar/sidebar-items.js' 'baz'
// @matches 'empty_mod_public/bar/baz/index.html' '//h1' 'Module empty_mod_public::bar::baz'
pub mod baz {}
}
pub struct Foo;
// @has foo/struct.Foo.html
-// @!has - 'Auto Trait Implementations'
+// @!hasraw - 'Auto Trait Implementations'
impl !Send for Foo {}
impl !Sync for Foo {}
impl !std::marker::Unpin for Foo {}
// Make sure that the elided lifetime shows up
// @has foo/type.T.html
-// @has - "pub type T = "
-// @has - "<'_>"
+// @hasraw - "pub type T = "
+// @hasraw - "<'_>"
pub type T = fn(&<() as Trait>::Gat<'_>);
}
// @has foo/trait.Clone.html
-// @!has - 'Foo'
+// @!hasraw - 'Foo'
// @has implementors/core/clone/trait.Clone.js
-// @!has - 'Foo'
+// @!hasraw - 'Foo'
pub use std::clone::Clone;
/// ```
pub fn foo() {}
-// @!has hidden_line/fn.foo.html invisible
+// @!hasraw hidden_line/fn.foo.html invisible
// @matches - //pre "#\[derive\(PartialEq\)\] // Bar"
}
// @has foo/struct.Foo.html
-// @!has - 'Methods'
+// @!hasraw - 'Methods'
// @!has - '//code' 'impl Foo'
-// @!has - 'this_should_be_hidden'
+// @!hasraw - 'this_should_be_hidden'
pub use hidden::Foo;
// @has foo/struct.Bar.html
-// @!has - 'Methods'
+// @!hasraw - 'Methods'
// @!has - '//code' 'impl Bar'
-// @!has - 'this_should_be_hidden'
+// @!hasraw - 'this_should_be_hidden'
pub use hidden::Bar;
extern crate unstable_trait;
-// @has foo/struct.Foo.html 'bar'
-// @has foo/struct.Foo.html 'bar2'
+// @hasraw foo/struct.Foo.html 'bar'
+// @hasraw foo/struct.Foo.html 'bar2'
#[doc(inline)]
pub use unstable_trait::Foo;
// full impl string. Instead, just make sure something from each part
// is mentioned.
-// @has implementors/rustdoc_impl_parts_crosscrate/trait.AnAutoTrait.js Bar
-// @has - Send
-// @has - !AnAutoTrait
-// @has - Copy
+// @hasraw implementors/rustdoc_impl_parts_crosscrate/trait.AnAutoTrait.js Bar
+// @hasraw - Send
+// @hasraw - !AnAutoTrait
+// @hasraw - Copy
impl<T: Send> !rustdoc_impl_parts_crosscrate::AnAutoTrait for Bar<T>
where T: Copy {}
trait MyTrait {}
impl MyTrait for i32 {}
-// @has impl_trait_alias/type.Foo.html 'Foo'
+// @hasraw impl_trait_alias/type.Foo.html 'Foo'
/// debug type
pub type Foo = impl MyTrait;
-// @has impl_trait_alias/fn.foo.html 'foo'
+// @hasraw impl_trait_alias/fn.foo.html 'foo'
/// debug function
pub fn foo() -> Foo {
1
// @has add_docs/struct.MyStruct.html
-// @has add_docs/struct.MyStruct.html "Doc comment from ‘pub use’, Doc comment from definition"
+// @hasraw add_docs/struct.MyStruct.html "Doc comment from ‘pub use’, Doc comment from definition"
/// Doc comment from 'pub use',
pub use inner::MyStruct;
extern crate assoc_items;
// @has foo/struct.MyStruct.html
-// @!has - 'PrivateConst'
+// @!hasraw - 'PrivateConst'
// @has - '//*[@id="associatedconstant.PublicConst"]' 'pub const PublicConst: u8'
// @has - '//*[@class="docblock"]' 'docs for PublicConst'
-// @!has - 'private_method'
+// @!hasraw - 'private_method'
// @has - '//*[@id="method.public_method"]' 'pub fn public_method()'
// @has - '//*[@class="docblock"]' 'docs for public_method'
// @has - '//*[@id="associatedconstant.ConstNoDefault"]' 'const ConstNoDefault: i16'
extern crate rustdoc_hidden;
// @has hidden_use/index.html
-// @!has - 'rustdoc_hidden'
-// @!has - 'Bar'
+// @!hasraw - 'rustdoc_hidden'
+// @!hasraw - 'Bar'
// @!has hidden_use/struct.Bar.html
#[doc(hidden)]
pub use rustdoc_hidden::Bar;
// @has proc_macro/derive.SomeDerive.html
// @has proc_macro/macro.some_proc_macro.html
-// @has - 'a proc-macro that swallows its input and does nothing.'
+// @hasraw - 'a proc-macro that swallows its input and does nothing.'
pub use some_macros::some_proc_macro;
// @has proc_macro/macro.reexported_macro.html
-// @has - 'Doc comment from the original crate'
+// @hasraw - 'Doc comment from the original crate'
pub use some_macros::reexported_macro;
// @has proc_macro/attr.some_proc_attr.html
-// @has - 'a proc-macro attribute that passes its item through verbatim.'
+// @hasraw - 'a proc-macro attribute that passes its item through verbatim.'
pub use some_macros::some_proc_attr;
// @has proc_macro/derive.SomeDerive.html
-// @has - 'a derive attribute that adds nothing to its input.'
+// @hasraw - 'a derive attribute that adds nothing to its input.'
pub use some_macros::SomeDerive;
// @has proc_macro/attr.first_attr.html
-// @has - 'Generated doc comment'
+// @hasraw - 'Generated doc comment'
pub use some_macros::first_attr;
// @has proc_macro/attr.second_attr.html
-// @has - 'Generated doc comment'
+// @hasraw - 'Generated doc comment'
pub use some_macros::second_attr;
pub use mod1::*;
// @has foo/index.html
-// @has - "mod1"
-// @has - "public_fn"
-// @!has - "private_fn"
+// @hasraw - "mod1"
+// @hasraw - "public_fn"
+// @!hasraw - "private_fn"
// @has foo/fn.public_fn.html
// @!has foo/fn.private_fn.html
// @has foo/mod1/index.html
-// @has - "public_fn"
-// @has - "private_fn"
+// @hasraw - "public_fn"
+// @hasraw - "private_fn"
// @has foo/mod1/fn.public_fn.html
// @has foo/mod1/fn.private_fn.html
pub use mod1::*;
// @has foo/index.html
-// @!has - "mod1"
-// @has - "public_fn"
-// @!has - "private_fn"
+// @!hasraw - "mod1"
+// @hasraw - "public_fn"
+// @!hasraw - "private_fn"
// @has foo/fn.public_fn.html
// @!has foo/fn.private_fn.html
pub use mod1::*;
// @has foo/index.html
-// @has - "mod1"
-// @has - "Mod1Public"
-// @!has - "Mod1Private"
-// @!has - "mod2"
-// @has - "Mod2Public"
-// @!has - "Mod2Private"
+// @hasraw - "mod1"
+// @hasraw - "Mod1Public"
+// @!hasraw - "Mod1Private"
+// @!hasraw - "mod2"
+// @hasraw - "Mod2Public"
+// @!hasraw - "Mod2Private"
// @has foo/struct.Mod1Public.html
// @!has foo/struct.Mod1Private.html
// @has foo/struct.Mod2Public.html
// @!has foo/struct.Mod2Private.html
// @has foo/mod1/index.html
-// @has - "mod2"
-// @has - "Mod1Public"
-// @has - "Mod1Private"
-// @!has - "Mod2Public"
-// @!has - "Mod2Private"
+// @hasraw - "mod2"
+// @hasraw - "Mod1Public"
+// @hasraw - "Mod1Private"
+// @!hasraw - "Mod2Public"
+// @!hasraw - "Mod2Private"
// @has foo/mod1/struct.Mod1Public.html
// @has foo/mod1/struct.Mod1Private.html
// @!has foo/mod1/struct.Mod2Public.html
// @!has foo/mod1/struct.Mod2Private.html
// @has foo/mod1/mod2/index.html
-// @has - "Mod2Public"
-// @has - "Mod2Private"
+// @hasraw - "Mod2Public"
+// @hasraw - "Mod2Private"
// @has foo/mod1/mod2/struct.Mod2Public.html
// @has foo/mod1/mod2/struct.Mod2Private.html
pub use mod1::*;
// @has foo/index.html
-// @!has - "mod1"
-// @has - "Mod1Public"
-// @!has - "Mod1Private"
-// @!has - "mod2"
-// @has - "Mod2Public"
-// @!has - "Mod2Private"
+// @!hasraw - "mod1"
+// @hasraw - "Mod1Public"
+// @!hasraw - "Mod1Private"
+// @!hasraw - "mod2"
+// @hasraw - "Mod2Public"
+// @!hasraw - "Mod2Private"
// @has foo/struct.Mod1Public.html
// @!has foo/struct.Mod1Private.html
// @has foo/struct.Mod2Public.html
}
// @has hidden_use/index.html
-// @!has - 'private'
-// @!has - 'Foo'
+// @!hasraw - 'private'
+// @!hasraw - 'Foo'
// @!has hidden_use/struct.Foo.html
#[doc(hidden)]
pub use private::Foo;
// @has macro_by_example/macros/index.html
pub mod macros {
- // @!has - 'pub use foo as bar;'
+ // @!hasraw - 'pub use foo as bar;'
// @has macro_by_example/macros/macro.bar.html
// @has - '//*[@class="docblock"]' 'docs for foo'
// @has - '//*[@class="stab deprecated"]' 'Deprecated since 1.2.3: text'
// @has please_inline/a/index.html
pub mod a {
- // @!has - 'pub use foo::'
+ // @!hasraw - 'pub use foo::'
// @has please_inline/a/struct.Foo.html
#[doc(inline)]
pub use foo::Foo;
// @has please_inline/b/index.html
pub mod b {
- // @has - 'pub use foo::'
+ // @hasraw - 'pub use foo::'
// @!has please_inline/b/struct.Foo.html
#[feature(inline)]
pub use foo::Foo;
// Check that the unstable marker is not added for "rustc_private".
// @!matches internal/index.html \
-// '//*[@class="item-right docblock-short"]/span[@class="stab unstable"]'
+// '//*[@class="item-right docblock-short"]/span[@class="stab unstable"]' \
+// ''
// @!matches internal/index.html \
-// '//*[@class="item-right docblock-short"]/span[@class="stab internal"]'
+// '//*[@class="item-right docblock-short"]/span[@class="stab internal"]' \
+// ''
// @matches - '//*[@class="item-right docblock-short"]' 'Docs'
-// @!has internal/struct.S.html '//*[@class="stab unstable"]'
-// @!has internal/struct.S.html '//*[@class="stab internal"]'
+// @!has internal/struct.S.html '//*[@class="stab unstable"]' ''
+// @!has internal/struct.S.html '//*[@class="stab internal"]' ''
/// Docs
pub struct S;
}
// @has 'extern_type/foreigntype.ExternType.html'
-// @has 'extern_type/fn.links_to_extern_type.html' \
+// @hasraw 'extern_type/fn.links_to_extern_type.html' \
// 'href="foreigntype.ExternType.html#method.f"'
-// @has 'extern_type/fn.links_to_extern_type.html' \
+// @hasraw 'extern_type/fn.links_to_extern_type.html' \
// 'href="foreigntype.ExternType.html#method.test"'
-// @has 'extern_type/fn.links_to_extern_type.html' \
+// @hasraw 'extern_type/fn.links_to_extern_type.html' \
// 'href="foreigntype.ExternType.html#method.g"'
/// See also [ExternType::f]
/// See also [ExternType::test]
pub struct Foo;
-// @has issue_16265_1/traits/index.html 'source'
+// @hasraw issue_16265_1/traits/index.html 'source'
pub mod traits {
impl PartialEq for super::Foo {
fn eq(&self, _: &super::Foo) -> bool {
-// @has issue_16265_2/index.html 'source'
+// @hasraw issue_16265_2/index.html 'source'
trait Y {}
impl Y for Option<u32> {}
#![doc(primitive = "str")]
impl str {
- // @has search-index.js foo
+ // @hasraw search-index.js foo
#[rustc_allow_incoherent_impl]
pub fn foo(&self) {}
}
}
// @has issue_23812/Foo/index.html
-// @has - 'Outer comment'
-// @!has - '/// Outer comment'
-// @has - 'Inner comment'
-// @!has - '//! Inner comment'
+// @hasraw - 'Outer comment'
+// @!hasraw - '/// Outer comment'
+// @hasraw - 'Inner comment'
+// @!hasraw - '//! Inner comment'
doc! {
}
// @has issue_23812/Bar/index.html
-// @has - 'Outer block comment'
-// @!has - '/** Outer block comment */'
-// @has - 'Inner block comment'
-// @!has - '/*! Inner block comment */'
+// @hasraw - 'Outer block comment'
+// @!hasraw - '/** Outer block comment */'
+// @hasraw - 'Inner block comment'
+// @!hasraw - '/*! Inner block comment */'
// ignore-cross-compile
// @has issue_27104/index.html
-// @!has - 'extern crate std'
-// @!has - 'use std::prelude::'
+// @!hasraw - 'extern crate std'
+// @!hasraw - 'use std::prelude::'
-// @has - 'pub extern crate empty'
+// @hasraw - 'pub extern crate empty'
pub extern crate empty;
#![unstable(feature="test", issue="27759")]
// @has issue_27759/unstable/index.html
-// @has - '<code>test</code> <a href="http://issue_url/27759">#27759</a>'
+// @hasraw - '<code>test</code> <a href="http://issue_url/27759">#27759</a>'
#[unstable(feature="test", issue="27759")]
pub mod unstable {
// @has issue_27759/unstable/fn.issue.html
- // @has - '<code>test_function</code> <a href="http://issue_url/12345">#12345</a>'
+ // @hasraw - '<code>test_function</code> <a href="http://issue_url/12345">#12345</a>'
#[unstable(feature="test_function", issue="12345")]
pub fn issue() {}
}
extern crate issue_29584;
// @has issue_29584/struct.Foo.html
-// @!has - 'impl Bar for'
+// @!hasraw - 'impl Bar for'
pub use issue_29584::Foo;
// @has issue_31899/index.html
-// @has - 'Make this line a bit longer.'
-// @!has - 'rust rust-example-rendered'
-// @!has - 'use ndarray::arr2'
-// @!has - 'prohibited'
+// @hasraw - 'Make this line a bit longer.'
+// @!hasraw - 'rust rust-example-rendered'
+// @!hasraw - 'use ndarray::arr2'
+// @!hasraw - 'prohibited'
/// A tuple or fixed size array that can be used to index an array.
/// Make this line a bit longer.
// @has issue_32374/struct.T.html '//*[@class="stab deprecated"]' \
// '👎 Deprecated since 1.0.0: text'
-// @has - '<code>test</code> <a href="https://issue_url/32374">#32374</a>'
+// @hasraw - '<code>test</code> <a href="https://issue_url/32374">#32374</a>'
// @matches issue_32374/struct.T.html '//*[@class="stab unstable"]' \
// '🔬 This is a nightly-only experimental API. \(test\s#32374\)$'
/// Docs
// ignore-cross-compile
// @has variant_struct/enum.Foo.html
-// @!has - 'pub qux'
-// @!has - 'pub(crate) qux'
-// @!has - 'pub Bar'
+// @!hasraw - 'pub qux'
+// @!hasraw - 'pub(crate) qux'
+// @!hasraw - 'pub Bar'
extern crate variant_struct;
// @has issue_32395/enum.Foo.html
-// @!has - 'pub qux'
-// @!has - 'pub(crate) qux'
-// @!has - 'pub Bar'
+// @!hasraw - 'pub qux'
+// @!hasraw - 'pub(crate) qux'
+// @!hasraw - 'pub Bar'
pub use variant_struct::Foo;
}
// @has foo/index.html
-// @!has - SomeTypeWithLongName
+// @!hasraw - SomeTypeWithLongName
// @has foo/struct.SomeType.html
// @!has foo/struct.SomeTypeWithLongName.html
pub use second::{SomeTypeWithLongName as SomeType};
--- /dev/null
+<code># single
+## double
+### triple
+<span class="attribute">#[outer]</span>
+<span class="attribute">#![inner]</span></code>
\ No newline at end of file
// @has issue_41783/struct.Foo.html
-// @!has - 'space'
-// @!has - 'comment'
-// @has - '# <span class="ident">single'
-// @has - '## <span class="ident">double</span>'
-// @has - '### <span class="ident">triple</span>'
-// @has - '<span class="attribute">#[<span class="ident">outer</span>]</span>'
-// @has - '<span class="attribute">#![<span class="ident">inner</span>]</span>'
+// @!hasraw - 'space'
+// @!hasraw - 'comment'
+// @hasraw - '<span class="attribute">#[outer]</span>'
+// @hasraw - '<span class="attribute">#![inner]</span>'
+// @snapshot 'codeblock' - '//*[@class="rustdoc-toggle top-doc"]/*[@class="docblock"]//pre/code'
/// ```no_run
/// # # space
extern crate issue_53689;
// @has foo/trait.MyTrait.html
-// @!has - 'MyStruct'
+// @!hasraw - 'MyStruct'
// @count - '//*[h3="impl<T> MyTrait for T"]' 1
pub trait MyTrait {}
// @has issue_61592/index.html
// @has - '//a[@href="#reexports"]' 'Re-exports'
// @has - '//code' 'pub use foo::FooTrait as _;'
-// @!has - '//a[@href="trait._.html"]'
+// @!has - '//a[@href="trait._.html"]' ''
pub use foo::FooTrait as _;
// @has issue_61592/index.html
// @has - '//a[@href="#reexports"]' 'Re-exports'
// @has - '//code' 'pub use foo::FooStruct as _;'
-// @!has - '//a[@href="struct._.html"]'
+// @!has - '//a[@href="struct._.html"]' ''
pub use foo::FooStruct as _;
#![no_core]
#![feature(no_core)]
-// @matches 'issue_89852/sidebar-items.js' '"repro"'
-// @!matches 'issue_89852/sidebar-items.js' '"repro".*"repro"'
+// @matchesraw 'issue_89852/sidebar-items.js' '"repro"'
+// @!matchesraw 'issue_89852/sidebar-items.js' '"repro".*"repro"'
#[macro_export]
macro_rules! repro {
//!
//! [foo]: url 'title & <stuff> & "things"'
-// @has 'foo/index.html' 'title & <stuff> & "things"'
+// @hasraw 'foo/index.html' 'title & <stuff> & "things"'
//
// compile-flags: --document-private-items
-// @has macro_document_private_duplicate/index.html 'Doc 1.'
-// @has macro_document_private_duplicate/macro.a_macro.html 'Doc 1.'
+// @hasraw macro_document_private_duplicate/index.html 'Doc 1.'
+// @hasraw macro_document_private_duplicate/macro.a_macro.html 'Doc 1.'
/// Doc 1.
macro_rules! a_macro {
() => ()
}
-// @has macro_document_private_duplicate/index.html 'Doc 2.'
-// @!has macro_document_private_duplicate/macro.a_macro.html 'Doc 2.'
+// @hasraw macro_document_private_duplicate/index.html 'Doc 2.'
+// @!hasraw macro_document_private_duplicate/macro.a_macro.html 'Doc 2.'
/// Doc 2.
macro_rules! a_macro {
() => ()
// This is a regression text for issue #88453.
#![feature(decl_macro)]
-// @!has macro_private_not_documented/index.html 'a_macro'
+// @!hasraw macro_private_not_documented/index.html 'a_macro'
// @!has macro_private_not_documented/macro.a_macro.html
macro_rules! a_macro {
() => ()
}
-// @!has macro_private_not_documented/index.html 'another_macro'
+// @!hasraw macro_private_not_documented/index.html 'another_macro'
// @!has macro_private_not_documented/macro.another_macro.html
macro another_macro {
() => ()
// @has 'foo/macro.todo.html'
// @has - '//span[@class="macro"]' 'macro_rules!'
-// @has - '//span[@class="ident"]' 'todo'
-// Note: the only op is the `+`
-// @count - '//pre[@class="rust macro"]//span[@class="op"]' 1
+// @hasraw - ' todo {'
-// @has - '{ () => { ... }; ($('
+// @hasraw - '{ () => { ... }; ($('
// @has - '//span[@class="macro-nonterminal"]' '$'
// @has - '//span[@class="macro-nonterminal"]' 'arg'
-// @has - ':'
-// @has - '//span[@class="ident"]' 'tt'
-// @has - '),'
-// @has - '//span[@class="op"]' '+'
-// @has - ') => { ... }; }'
+// @hasraw - ':tt)+'
+// @hasraw - ') => { ... }; }'
pub use std::todo;
mod mod1 {
// @has 'foo/macro.macro1.html'
- // @has - 'macro_rules!'
- // @has - 'macro1'
- // @has - '{ () => { ... }; ($('
+ // @hasraw - 'macro_rules!'
+ // @hasraw - 'macro1'
+ // @hasraw - '{ () => { ... }; ($('
// @has - '//span[@class="macro-nonterminal"]' '$'
// @has - '//span[@class="macro-nonterminal"]' 'arg'
- // @has - ':'
- // @has - 'expr'
- // @has - '),'
- // @has - '+'
- // @has - ') => { ... }; }'
+ // @hasraw - ':'
+ // @hasraw - 'expr'
+ // @hasraw - '),'
+ // @hasraw - '+'
+ // @hasraw - ') => { ... }; }'
#[macro_export]
macro_rules! macro1 {
() => {};
//!
//! [link]: https://example.com
-// @has search-index.js 'This <em>summary</em> has a link and <code>code</code>.'
-// @!has - 'second paragraph'
+// @hasraw search-index.js 'This <em>summary</em> has a link and <code>code</code>.'
+// @!hasraw - 'second paragraph'
/// This `code` will be rendered in a code tag.
///
/// This text should not be rendered.
pub struct Sidebar;
-// @has search-index.js 'This <code>code</code> will be rendered in a code tag.'
-// @has summaries/sidebar-items.js 'This `code` will be rendered in a code tag.'
-// @!has - 'text should not be rendered'
+// @hasraw search-index.js 'This <code>code</code> will be rendered in a code tag.'
+// @hasraw summaries/sidebar-items.js 'This `code` will be rendered in a code tag.'
+// @!hasraw - 'text should not be rendered'
/// ```text
/// this block should not be rendered
/// ```
pub struct Sidebar2;
-// @!has summaries/sidebar-items.js 'block should not be rendered'
+// @!hasraw summaries/sidebar-items.js 'block should not be rendered'
#[doc(masked)]
extern crate masked;
-// @!has 'search-index.js' 'masked_method'
+// @!hasraw 'search-index.js' 'masked_method'
-// @!has 'foo/struct.String.html' 'MaskedTrait'
-// @!has 'foo/struct.String.html' 'masked_method'
+// @!hasraw 'foo/struct.String.html' 'MaskedTrait'
+// @!hasraw 'foo/struct.String.html' 'masked_method'
pub use std::string::String;
-// @!has 'foo/trait.Clone.html' 'MaskedStruct'
+// @!hasraw 'foo/trait.Clone.html' 'MaskedStruct'
pub use std::clone::Clone;
-// @!has 'foo/struct.MyStruct.html' 'MaskedTrait'
-// @!has 'foo/struct.MyStruct.html' 'masked_method'
+// @!hasraw 'foo/struct.MyStruct.html' 'MaskedTrait'
+// @!hasraw 'foo/struct.MyStruct.html' 'masked_method'
pub struct MyStruct;
impl masked::MaskedTrait for MyStruct {
fn masked_method() {}
}
-// @!has 'foo/trait.MyTrait.html' 'MaskedStruct'
+// @!hasraw 'foo/trait.MyTrait.html' 'MaskedStruct'
pub trait MyTrait {}
impl MyTrait for masked::MaskedStruct {}
pub use std::marker::Send;
-// @!has foo/index.html 'Implementations'
+// @!hasraw foo/index.html 'Implementations'
pub mod a_nested_module {
// @has aCrate/a_nested_module/index.html '//a[@href="fn.a_nested_public_function.html"]' 'a_nested_public_function'
- // @has aCrate/a_nested_module/fn.a_nested_public_function.html 'pub fn a_nested_public_function()'
+ // @hasraw aCrate/a_nested_module/fn.a_nested_public_function.html 'pub fn a_nested_public_function()'
pub fn a_nested_public_function() {}
// @has aCrate/a_nested_module/index.html '//a[@href="fn.another_nested_public_function.html"]' 'another_nested_public_function'
- // @has aCrate/a_nested_module/fn.another_nested_public_function.html 'pub fn another_nested_public_function()'
+ // @hasraw aCrate/a_nested_module/fn.another_nested_public_function.html 'pub fn another_nested_public_function()'
pub use a_nested_module::a_nested_public_function as another_nested_public_function;
}
- // @!has aCrate/a_nested_module/index.html 'yet_another_nested_public_function'
+ // @!hasraw aCrate/a_nested_module/index.html 'yet_another_nested_public_function'
pub use a_nested_module::a_nested_public_function as yet_another_nested_public_function;
- // @!has aCrate/a_nested_module/index.html 'one_last_nested_public_function'
+ // @!hasraw aCrate/a_nested_module/index.html 'one_last_nested_public_function'
pub use a_nested_module::another_nested_public_function as one_last_nested_public_function;
}
-// @!has aCrate/index.html 'a_module'
+// @!hasraw aCrate/index.html 'a_module'
// @has aCrate/index.html '//a[@href="a_nested_module/index.html"]' 'a_nested_module'
pub use a_module::a_nested_module;
};
// @has aCrate/index.html '//a[@href="fn.private_function.html"]' 'private_function'
-// @!has aCrate/fn.private_function.html 'a_module'
+// @!hasraw aCrate/fn.private_function.html 'a_module'
// @has aCrate/index.html '//a[@href="fn.other_private_function.html"]' 'other_private_function'
-// @!has aCrate/fn.other_private_function.html 'a_module'
+// @!hasraw aCrate/fn.other_private_function.html 'a_module'
pub use a_module::{other_private_function, private_function};
// compile-flags: -Z unstable-options --disable-per-crate-search
-// @!has 'foo/struct.Foo.html' '//*[id="crate-search"]'
+// @!has 'foo/struct.Foo.html' '//*[id="crate-search"]' ''
pub struct Foo;
// @has recursive_deref/struct.D.html '//h3[@class="code-header in-band"]' 'impl Deref for D'
// We also check that `G::g` method isn't rendered because there is no `self` argument.
-// @!has '-' '//*[@id="deref-methods-G"]'
+// @!has '-' '//*[@id="deref-methods-G"]' ''
impl Deref for D {
type Target = E;
// @has recursive_deref/struct.E.html '//h3[@class="code-header in-band"]' 'impl Deref for E'
// We also check that `G::g` method isn't rendered because there is no `self` argument.
-// @!has '-' '//*[@id="deref-methods-G"]'
+// @!has '-' '//*[@id="deref-methods-G"]' ''
impl Deref for E {
type Target = F;
// @has recursive_deref/struct.F.html '//h3[@class="code-header in-band"]' 'impl Deref for F'
// We also check that `G::g` method isn't rendered because there is no `self` argument.
-// @!has '-' '//*[@id="deref-methods-G"]'
+// @!has '-' '//*[@id="deref-methods-G"]' ''
impl Deref for F {
type Target = G;
}
// @has recursive_deref/struct.H.html '//h3[@class="code-header in-band"]' 'impl Deref for H'
-// @!has '-' '//*[@id="deref-methods-I"]'
+// @!has '-' '//*[@id="deref-methods-I"]' ''
impl Deref for H {
type Target = I;
#![crate_name = "foo"]
// @has foo/fn.foo.html
-// @!has - '//a[@href="http://a.a"]'
+// @!has - '//a[@href="http://a.a"]' ''
// @has - '//a[@href="#implementing-stuff-somewhere"]' 'Implementing stuff somewhere'
// @has - '//a[@href="#another-one-urg"]' 'Another one urg'
#![crate_name = "foo"]
-// @has 'search-index.js' 'Foo short link.'
-// @!has - 'www.example.com'
-// @!has - 'More Foo.'
+// @hasraw 'search-index.js' 'Foo short link.'
+// @!hasraw - 'www.example.com'
+// @!hasraw - 'More Foo.'
/// Foo short [link](https://www.example.com/).
///
use std::ops::Deref;
-// @has search-index.js Foo
+// @hasraw search-index.js Foo
pub use private::Foo;
mod private {
pub struct Foo;
impl Foo {
- pub fn test_method() {} // @has - test_method
- fn priv_method() {} // @!has - priv_method
+ pub fn test_method() {} // @hasraw - test_method
+ fn priv_method() {} // @!hasraw - priv_method
}
pub trait PrivateTrait {
- fn trait_method(&self) {} // @!has - priv_method
+ fn trait_method(&self) {} // @!hasraw - priv_method
}
}
pub struct Bar;
impl Deref for Bar {
- // @!has search-index.js Target
+ // @!hasraw search-index.js Target
type Target = Bar;
fn deref(&self) -> &Bar { self }
}
// Test that the contents of constants are displayed as part of the
// documentation.
-// @has show_const_contents/constant.CONST_S.html 'show this'
-// @!has show_const_contents/constant.CONST_S.html '; //'
+// @hasraw show_const_contents/constant.CONST_S.html 'show this'
+// @!hasraw show_const_contents/constant.CONST_S.html '; //'
pub const CONST_S: &'static str = "show this";
-// @has show_const_contents/constant.CONST_I32.html '= 42;'
-// @!has show_const_contents/constant.CONST_I32.html '; //'
+// @hasraw show_const_contents/constant.CONST_I32.html '= 42;'
+// @!hasraw show_const_contents/constant.CONST_I32.html '; //'
pub const CONST_I32: i32 = 42;
-// @has show_const_contents/constant.CONST_I32_HEX.html '= 0x42;'
-// @!has show_const_contents/constant.CONST_I32_HEX.html '; //'
+// @hasraw show_const_contents/constant.CONST_I32_HEX.html '= 0x42;'
+// @!hasraw show_const_contents/constant.CONST_I32_HEX.html '; //'
pub const CONST_I32_HEX: i32 = 0x42;
-// @has show_const_contents/constant.CONST_NEG_I32.html '= -42;'
-// @!has show_const_contents/constant.CONST_NEG_I32.html '; //'
+// @hasraw show_const_contents/constant.CONST_NEG_I32.html '= -42;'
+// @!hasraw show_const_contents/constant.CONST_NEG_I32.html '; //'
pub const CONST_NEG_I32: i32 = -42;
-// @has show_const_contents/constant.CONST_EQ_TO_VALUE_I32.html '= 42i32;'
-// @!has show_const_contents/constant.CONST_EQ_TO_VALUE_I32.html '// 42i32'
+// @hasraw show_const_contents/constant.CONST_EQ_TO_VALUE_I32.html '= 42i32;'
+// @!hasraw show_const_contents/constant.CONST_EQ_TO_VALUE_I32.html '// 42i32'
pub const CONST_EQ_TO_VALUE_I32: i32 = 42i32;
-// @has show_const_contents/constant.CONST_CALC_I32.html '= _; // 43i32'
+// @hasraw show_const_contents/constant.CONST_CALC_I32.html '= _; // 43i32'
pub const CONST_CALC_I32: i32 = 42 + 1;
-// @!has show_const_contents/constant.CONST_REF_I32.html '= &42;'
-// @!has show_const_contents/constant.CONST_REF_I32.html '; //'
+// @!hasraw show_const_contents/constant.CONST_REF_I32.html '= &42;'
+// @!hasraw show_const_contents/constant.CONST_REF_I32.html '; //'
pub const CONST_REF_I32: &'static i32 = &42;
-// @has show_const_contents/constant.CONST_I32_MAX.html '= i32::MAX; // 2_147_483_647i32'
+// @hasraw show_const_contents/constant.CONST_I32_MAX.html '= i32::MAX; // 2_147_483_647i32'
pub const CONST_I32_MAX: i32 = i32::MAX;
-// @!has show_const_contents/constant.UNIT.html '= ();'
-// @!has show_const_contents/constant.UNIT.html '; //'
+// @!hasraw show_const_contents/constant.UNIT.html '= ();'
+// @!hasraw show_const_contents/constant.UNIT.html '; //'
pub const UNIT: () = ();
pub struct MyType(i32);
-// @!has show_const_contents/constant.MY_TYPE.html '= MyType(42);'
-// @!has show_const_contents/constant.MY_TYPE.html '; //'
+// @!hasraw show_const_contents/constant.MY_TYPE.html '= MyType(42);'
+// @!hasraw show_const_contents/constant.MY_TYPE.html '; //'
pub const MY_TYPE: MyType = MyType(42);
pub struct MyTypeWithStr(&'static str);
-// @!has show_const_contents/constant.MY_TYPE_WITH_STR.html '= MyTypeWithStr("show this");'
-// @!has show_const_contents/constant.MY_TYPE_WITH_STR.html '; //'
+// @!hasraw show_const_contents/constant.MY_TYPE_WITH_STR.html '= MyTypeWithStr("show this");'
+// @!hasraw show_const_contents/constant.MY_TYPE_WITH_STR.html '; //'
pub const MY_TYPE_WITH_STR: MyTypeWithStr = MyTypeWithStr("show this");
-// @has show_const_contents/constant.PI.html '= 3.14159265358979323846264338327950288f32;'
-// @has show_const_contents/constant.PI.html '; // 3.14159274f32'
+// @hasraw show_const_contents/constant.PI.html '= 3.14159265358979323846264338327950288f32;'
+// @hasraw show_const_contents/constant.PI.html '; // 3.14159274f32'
pub use std::f32::consts::PI;
-// @has show_const_contents/constant.MAX.html '= i32::MAX; // 2_147_483_647i32'
+// @hasraw show_const_contents/constant.MAX.html '= i32::MAX; // 2_147_483_647i32'
#[allow(deprecated, deprecated_in_future)]
pub use std::i32::MAX;
)
}
-// @has show_const_contents/constant.MIN.html '= i16::MIN; // -32_768i16'
+// @hasraw show_const_contents/constant.MIN.html '= i16::MIN; // -32_768i16'
int_module!(i16);
// @has show_const_contents/constant.ESCAPE.html //pre '= r#"<script>alert("ESCAPE");</script>"#;'
#![crate_name = "foo"]
// @has foo/struct.Bar.html
-// @!has - '//*[@id="impl-Sized"]'
+// @!has - '//*[@id="impl-Sized"]' ''
pub struct Bar {
a: u16,
}
// @has foo/struct.Foo.html
-// @!has - '//*[@id="impl-Sized"]'
+// @!has - '//*[@id="impl-Sized"]' ''
pub struct Foo<T: ?Sized>(T);
// @has foo/struct.Unsized.html
pub mod module_a {}
-// @matches 'sort_modules_by_appearance/index.html' '(?s)module_b.*module_c.*module_a'
-// @matches 'sort_modules_by_appearance/sidebar-items.js' '"module_b".*"module_c".*"module_a"'
+// @matchesraw 'sort_modules_by_appearance/index.html' '(?s)module_b.*module_c.*module_a'
+// @matchesraw 'sort_modules_by_appearance/sidebar-items.js' '"module_b".*"module_c".*"module_a"'
#![crate_name = "foo"]
-// @has source-files.js source-file.rs
+// @hasraw source-files.js source-file.rs
pub struct Foo;
// compile-flags:-Z unstable-options --static-root-path /cache/
// @has static_root_path/struct.SomeStruct.html
-// @matches - '"/cache/main\.js"'
-// @!matches - '"\.\./main\.js"'
-// @matches - 'data-root-path="\.\./"'
-// @!matches - '"/cache/search-index\.js"'
+// @matchesraw - '"/cache/main\.js"'
+// @!matchesraw - '"\.\./main\.js"'
+// @matchesraw - 'data-root-path="\.\./"'
+// @!matchesraw - '"/cache/search-index\.js"'
pub struct SomeStruct;
// @has src/static_root_path/static-root-path.rs.html
-// @matches - '"/cache/source-script\.js"'
-// @!matches - '"\.\./\.\./source-script\.js"'
-// @matches - '"\.\./\.\./source-files.js"'
-// @!matches - '"/cache/source-files\.js"'
+// @matchesraw - '"/cache/source-script\.js"'
+// @!matchesraw - '"\.\./\.\./source-script\.js"'
+// @matchesraw - '"\.\./\.\./source-files.js"'
+// @!matchesraw - '"/cache/source-files\.js"'
// @has settings.html
-// @matches - '/cache/settings\.js'
-// @!matches - '\./settings\.js'
+// @matchesraw - '/cache/settings\.js'
+// @!matchesraw - '\./settings\.js'
// @has foo/struct.Foo.html
// @count - '//*[@class="docblock"]/div/table' 2
-// @!has - '//*[@class="docblock"]/table'
+// @!has - '//*[@class="docblock"]/table' ''
/// | hello | hello2 |
/// | ----- | ------ |
/// | data | data2 |
}
// @has 'toggle_item_contents/enum.Enum.html'
-// @!has - '//details[@class="rustdoc-toggle type-contents-toggle"]'
+// @!has - '//details[@class="rustdoc-toggle type-contents-toggle"]' ''
pub enum Enum {
A, B, C,
D {
}
// @has 'toggle_item_contents/enum.EnumStructVariant.html'
-// @!has - '//details[@class="rustdoc-toggle type-contents-toggle"]'
+// @!has - '//details[@class="rustdoc-toggle type-contents-toggle"]' ''
pub enum EnumStructVariant {
A, B, C,
D {
// We check that associated items with default values aren't generated in the implementors list.
impl MyTrait for (u8, u8) {
- // @!has trait_impl_items_links_and_anchors/trait.MyTrait.html '//div[@id="associatedconstant.VALUE-4"]'
+ // @!has trait_impl_items_links_and_anchors/trait.MyTrait.html '//div[@id="associatedconstant.VALUE-4"]' ''
type Assoc = bool;
fn trait_function(&self) {}
}
fn c() {}
// @has - '//*[@id="method.d"]/../../div[@class="docblock"]/p' 'Escaped formatting a*b*c* works'
- // @!has - '//*[@id="method.d"]/../../div[@class="docblock"]/p/em'
+ // @!has - '//*[@id="method.d"]/../../div[@class="docblock"]/p/em' ''
fn d() {}
// @has - '//*[@id="impl-Trait-for-Struct"]/h3//a/@href' 'trait.Trait.html'
// @has - '//h3[@class="sidebar-title"]/a[@href="#fields"]' 'Tuple Fields'
// @has - '//*[@id="structfield.0"]' '0: u32'
// @has - '//*[@id="main-content"]/div[@class="docblock"]' 'hello'
-// @!has - '//*[@id="structfield.1"]'
+// @!has - '//*[@id="structfield.1"]' ''
// @has - '//*[@id="structfield.2"]' '2: char'
// @has - '//*[@id="structfield.3"]' '3: i8'
// @has - '//*[@id="main-content"]/div[@class="docblock"]' 'not hello'
// Tests that `--show-type-layout` is required in order to show layout info.
-// @!has type_layout_flag_required/struct.Foo.html 'Size: '
+// @!hasraw type_layout_flag_required/struct.Foo.html 'Size: '
pub struct Foo(usize);
// compile-flags: --show-type-layout -Z unstable-options
-// @has type_layout/struct.Foo.html 'Size: '
-// @has - ' bytes'
+// @hasraw type_layout/struct.Foo.html 'Size: '
+// @hasraw - ' bytes'
// @has - '//*[@id="layout"]/a[@href="#layout"]' ''
pub struct Foo {
pub a: usize,
b: Vec<String>,
}
-// @has type_layout/enum.Bar.html 'Size: '
-// @has - ' bytes'
+// @hasraw type_layout/enum.Bar.html 'Size: '
+// @hasraw - ' bytes'
pub enum Bar<'a> {
A(String),
B(&'a str, (std::collections::HashMap<String, usize>, Foo)),
}
-// @has type_layout/union.Baz.html 'Size: '
-// @has - ' bytes'
+// @hasraw type_layout/union.Baz.html 'Size: '
+// @hasraw - ' bytes'
pub union Baz {
a: &'static str,
b: usize,
c: &'static [u8],
}
-// @has type_layout/struct.X.html 'Size: '
-// @has - ' bytes'
+// @hasraw type_layout/struct.X.html 'Size: '
+// @hasraw - ' bytes'
pub struct X(usize);
-// @has type_layout/struct.Y.html 'Size: '
-// @has - '1 byte'
-// @!has - ' bytes'
+// @hasraw type_layout/struct.Y.html 'Size: '
+// @hasraw - '1 byte'
+// @!hasraw - ' bytes'
pub struct Y(u8);
-// @has type_layout/struct.Z.html 'Size: '
-// @has - '0 bytes'
+// @hasraw type_layout/struct.Z.html 'Size: '
+// @hasraw - '0 bytes'
pub struct Z;
// We can't compute layout for generic types.
-// @has type_layout/struct.Generic.html 'Unable to compute type layout, possibly due to this type having generic parameters'
-// @!has - 'Size: '
+// @hasraw type_layout/struct.Generic.html 'Unable to compute type layout, possibly due to this type having generic parameters'
+// @!hasraw - 'Size: '
pub struct Generic<T>(T);
// We *can*, however, compute layout for types that are only generic over lifetimes,
// because lifetimes are a type-system construct.
-// @has type_layout/struct.GenericLifetimes.html 'Size: '
-// @has - ' bytes'
+// @hasraw type_layout/struct.GenericLifetimes.html 'Size: '
+// @hasraw - ' bytes'
pub struct GenericLifetimes<'a>(&'a str);
-// @has type_layout/struct.Unsized.html 'Size: '
-// @has - '(unsized)'
+// @hasraw type_layout/struct.Unsized.html 'Size: '
+// @hasraw - '(unsized)'
pub struct Unsized([u8]);
-// @has type_layout/type.TypeAlias.html 'Size: '
-// @has - ' bytes'
+// @hasraw type_layout/type.TypeAlias.html 'Size: '
+// @hasraw - ' bytes'
pub type TypeAlias = X;
-// @has type_layout/type.GenericTypeAlias.html 'Size: '
-// @has - '8 bytes'
+// @hasraw type_layout/type.GenericTypeAlias.html 'Size: '
+// @hasraw - '8 bytes'
pub type GenericTypeAlias = (Generic<(u32, ())>, Generic<u32>);
// Regression test for the rustdoc equivalent of #85103.
-// @has type_layout/type.Edges.html 'Encountered an error during type layout; the type failed to be normalized.'
+// @hasraw type_layout/type.Edges.html 'Encountered an error during type layout; the type failed to be normalized.'
pub type Edges<'a, E> = std::borrow::Cow<'a, [E]>;
-// @!has type_layout/trait.MyTrait.html 'Size: '
+// @!hasraw type_layout/trait.MyTrait.html 'Size: '
pub trait MyTrait {}
-// @has type_layout/enum.Variants.html 'Size: '
-// @has - '2 bytes'
-// @has - '<code>A</code>: 0 bytes'
-// @has - '<code>B</code>: 1 byte'
+// @hasraw type_layout/enum.Variants.html 'Size: '
+// @hasraw - '2 bytes'
+// @hasraw - '<code>A</code>: 0 bytes'
+// @hasraw - '<code>B</code>: 1 byte'
pub enum Variants {
A,
B(u8),
}
-// @has type_layout/enum.WithNiche.html 'Size: '
+// @hasraw type_layout/enum.WithNiche.html 'Size: '
// @has - //p '4 bytes'
-// @has - '<code>None</code>: 0 bytes'
-// @has - '<code>Some</code>: 4 bytes'
+// @hasraw - '<code>None</code>: 0 bytes'
+// @hasraw - '<code>Some</code>: 4 bytes'
pub enum WithNiche {
None,
Some(std::num::NonZeroU32),
// @has typedef/type.MyAlias.html
// @has - '//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' 'impl MyAlias'
// @has - '//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' 'impl MyTrait for MyAlias'
-// @has - 'Alias docstring'
+// @hasraw - 'Alias docstring'
// @has - '//*[@class="sidebar"]//*[@class="location"]' 'MyAlias'
// @has - '//*[@class="sidebar"]//a[@href="#implementations"]' 'Methods'
// @has - '//*[@class="sidebar"]//a[@href="#trait-implementations"]' 'Trait Implementations'
// @has foo/fn.foo.html
// @has - //pre 'foo('
-// @matches - '_x: impl <a class="trait" href="[^"]+/trait\.Clone\.html"'
-// @matches - '_z: .+impl.+trait\.Copy\.html.+, impl.+trait\.Clone\.html'
+// @matchesraw - '_x: impl <a class="trait" href="[^"]+/trait\.Clone\.html"'
+// @matchesraw - '_z: .+impl.+trait\.Copy\.html.+, impl.+trait\.Clone\.html'
pub fn foo(_x: impl Clone, _y: i32, _z: (impl Copy, impl Clone)) {
}
pub trait Trait {
// @has foo/trait.Trait.html
- // @has - 'method</a>('
- // @matches - '_x: impl <a class="trait" href="[^"]+/trait\.Debug\.html"'
+ // @hasraw - 'method</a>('
+ // @matchesraw - '_x: impl <a class="trait" href="[^"]+/trait\.Debug\.html"'
fn method(&self, _x: impl std::fmt::Debug) {
}
}
impl<T> S<T> {
// @has foo/struct.S.html
- // @has - 'bar</a>('
- // @matches - '_bar: impl <a class="trait" href="[^"]+/trait\.Copy\.html"'
+ // @hasraw - 'bar</a>('
+ // @matchesraw - '_bar: impl <a class="trait" href="[^"]+/trait\.Copy\.html"'
pub fn bar(_bar: impl Copy) {
}
- // @has - 'baz</a>('
- // @matches - '_baz:.+struct\.S\.html.+impl .+trait\.Clone\.html'
+ // @hasraw - 'baz</a>('
+ // @matchesraw - '_baz:.+struct\.S\.html.+impl .+trait\.Clone\.html'
pub fn baz(_baz: S<impl Clone>) {
}
- // @has - 'qux</a>('
- // @matches - 'trait\.Read\.html'
+ // @hasraw - 'qux</a>('
+ // @matchesraw - 'trait\.Read\.html'
pub fn qux(_qux: impl IntoIterator<Item = S<impl Read>>) {
}
}
-// @has - 'method</a>('
-// @matches - '_x: impl <a class="trait" href="[^"]+/trait\.Debug\.html"'
+// @hasraw - 'method</a>('
+// @matchesraw - '_x: impl <a class="trait" href="[^"]+/trait\.Debug\.html"'
impl<T> Trait for S<T> {}
// @has foo/fn.much_universe.html
-// @matches - 'T:.+Borrow.+impl .+trait\.Trait\.html'
-// @matches - 'U:.+IntoIterator.+= impl.+Iterator\.html.+= impl.+Clone\.html'
-// @matches - '_: impl .+trait\.Read\.html.+ \+ .+trait\.Clone\.html'
+// @matchesraw - 'T:.+Borrow.+impl .+trait\.Trait\.html'
+// @matchesraw - 'U:.+IntoIterator.+= impl.+Iterator\.html.+= impl.+Clone\.html'
+// @matchesraw - '_: impl .+trait\.Read\.html.+ \+ .+trait\.Clone\.html'
pub fn much_universe<
T: Borrow<impl Trait>,
U: IntoIterator<Item = impl Iterator<Item = impl Clone>>,
--- /dev/null
+some_slug = hi
+ .label-has-hyphens = test
-missing-message =
+missing_message =
--- /dev/null
+this-slug-has-hyphens = hi
}
}
+mod slug_with_hyphens {
+ use super::fluent_messages;
+
+ fluent_messages! {
+ slug_with_hyphens => "./slug-with-hyphens.ftl",
+//~^ ERROR name `this-slug-has-hyphens` contains a '-' character
+ }
+}
+
+mod label_with_hyphens {
+ use super::fluent_messages;
+
+ fluent_messages! {
+ label_with_hyphens => "./label-with-hyphens.ftl",
+//~^ ERROR attribute `label-has-hyphens` contains a '-' character
+ }
+}
+
mod valid {
use super::fluent_messages;
|
= help: see additional errors emitted
-error: expected a message field for "missing-message"
+error: expected a message field for "missing_message"
--> ./missing-message.ftl:1:1
|
-1 | missing-message =
- | ^^^^^^^^^^^^^^^^^^
+1 | missing_message =
+ | ^^^^^^^^^^^^^^^^^
|
error: overrides existing message: `key`
LL | a => "./duplicate-a.ftl",
| ^
-error: aborting due to 4 previous errors
+error: name `this-slug-has-hyphens` contains a '-' character
+ --> $DIR/test.rs:62:9
+ |
+LL | slug_with_hyphens => "./slug-with-hyphens.ftl",
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = help: replace any '-'s with '_'s
+
+error: attribute `label-has-hyphens` contains a '-' character
+ --> $DIR/test.rs:71:9
+ |
+LL | label_with_hyphens => "./label-with-hyphens.ftl",
+ | ^^^^^^^^^^^^^^^^^^
+ |
+ = help: replace any '-'s with '_'s
+
+error: aborting due to 6 previous errors
--> $DIR/complex.rs:11:4
|
LL | fn complex(_i: u32, _s: &str, _e: E, _f: F, _g: G, _x: X, _y: Y, _z: Z ) {}
- | ^^^^^^^ ------- -------- ----- ----- ----- ----- ----- ------
+ | ^^^^^^^ ------- -------- ----- ----- ----- ----- ----- -----
help: did you mean
|
LL | complex(/* u32 */, &"", /* E */, F::X2, G{}, X {}, Y {}, Z {});
--> $DIR/invalid_arguments.rs:6:4
|
LL | fn two_arg_same(_a: i32, _b: i32) {}
- | ^^^^^^^^^^^^ ------- -------
+ | ^^^^^^^^^^^^ -------
error[E0308]: mismatched types
--> $DIR/invalid_arguments.rs:17:16
--> $DIR/invalid_arguments.rs:6:4
|
LL | fn two_arg_same(_a: i32, _b: i32) {}
- | ^^^^^^^^^^^^ ------- -------
+ | ^^^^^^^^^^^^ -------
error[E0308]: arguments to this function are incorrect
--> $DIR/invalid_arguments.rs:18:3
--> $DIR/invalid_arguments.rs:7:4
|
LL | fn two_arg_diff(_a: i32, _b: f32) {}
- | ^^^^^^^^^^^^ ------- -------
+ | ^^^^^^^^^^^^ -------
error[E0308]: mismatched types
--> $DIR/invalid_arguments.rs:20:16
--> $DIR/invalid_arguments.rs:7:4
|
LL | fn two_arg_diff(_a: i32, _b: f32) {}
- | ^^^^^^^^^^^^ ------- -------
+ | ^^^^^^^^^^^^ -------
error[E0308]: arguments to this function are incorrect
--> $DIR/invalid_arguments.rs:21:3
--> $DIR/invalid_arguments.rs:8:4
|
LL | fn three_arg_diff(_a: i32, _b: f32, _c: &str) {}
- | ^^^^^^^^^^^^^^ ------- ------- --------
+ | ^^^^^^^^^^^^^^ -------
error[E0308]: mismatched types
--> $DIR/invalid_arguments.rs:25:21
--> $DIR/invalid_arguments.rs:8:4
|
LL | fn three_arg_diff(_a: i32, _b: f32, _c: &str) {}
- | ^^^^^^^^^^^^^^ ------- ------- --------
+ | ^^^^^^^^^^^^^^ -------
error[E0308]: mismatched types
--> $DIR/invalid_arguments.rs:26:26
--> $DIR/invalid_arguments.rs:8:4
|
LL | fn three_arg_diff(_a: i32, _b: f32, _c: &str) {}
- | ^^^^^^^^^^^^^^ ------- ------- --------
+ | ^^^^^^^^^^^^^^ --------
error[E0308]: arguments to this function are incorrect
--> $DIR/invalid_arguments.rs:28:3
--> $DIR/invalid_arguments.rs:9:4
|
LL | fn three_arg_repeat(_a: i32, _b: i32, _c: &str) {}
- | ^^^^^^^^^^^^^^^^ ------- ------- --------
+ | ^^^^^^^^^^^^^^^^ -------
error[E0308]: mismatched types
--> $DIR/invalid_arguments.rs:35:23
--> $DIR/invalid_arguments.rs:9:4
|
LL | fn three_arg_repeat(_a: i32, _b: i32, _c: &str) {}
- | ^^^^^^^^^^^^^^^^ ------- ------- --------
+ | ^^^^^^^^^^^^^^^^ -------
error[E0308]: mismatched types
--> $DIR/invalid_arguments.rs:36:26
--> $DIR/invalid_arguments.rs:9:4
|
LL | fn three_arg_repeat(_a: i32, _b: i32, _c: &str) {}
- | ^^^^^^^^^^^^^^^^ ------- ------- --------
+ | ^^^^^^^^^^^^^^^^ --------
error[E0308]: arguments to this function are incorrect
--> $DIR/invalid_arguments.rs:38:3
--> $DIR/issue-96638.rs:8:5
|
LL | f(&x, "");
- | ^ -- an argument of type `usize` is missing
+ | ^ -- -- expected `usize`, found `&str`
+ | |
+ | an argument of type `usize` is missing
|
note: function defined here
--> $DIR/issue-96638.rs:1:4
--> $DIR/issue-97484.rs:12:5
|
LL | foo(&&A, B, C, D, E, F, G);
- | ^^^ - - - argument of type `F` unexpected
- | | |
+ | ^^^ - - - - argument of type `F` unexpected
+ | | | |
+ | | | expected `&E`, found struct `E`
| | argument of type `C` unexpected
| argument of type `B` unexpected
|
--- /dev/null
+struct Qux;
+
+impl Qux {
+ fn foo(
+ &self,
+ a: i32,
+ b: i32,
+ c: i32,
+ d: i32,
+ e: i32,
+ f: i32,
+ g: i32,
+ h: i32,
+ i: i32,
+ j: i32,
+ k: i32,
+ l: i32,
+ ) {
+ }
+}
+
+fn what(
+ qux: &Qux,
+ a: i32,
+ b: i32,
+ c: i32,
+ d: i32,
+ e: i32,
+ f: &i32,
+ g: i32,
+ h: i32,
+ i: i32,
+ j: i32,
+ k: i32,
+ l: i32,
+) {
+ qux.foo(a, b, c, d, e, f, g, h, i, j, k, l);
+ //~^ ERROR mismatched types
+}
+
+fn main() {}
--- /dev/null
+error[E0308]: mismatched types
+ --> $DIR/too-long.rs:37:28
+ |
+LL | qux.foo(a, b, c, d, e, f, g, h, i, j, k, l);
+ | --- ^ expected `i32`, found `&i32`
+ | |
+ | arguments to this function are incorrect
+ |
+note: associated function defined here
+ --> $DIR/too-long.rs:4:8
+ |
+LL | fn foo(
+ | ^^^
+...
+LL | f: i32,
+ | ------
+help: consider dereferencing the borrow
+ |
+LL | qux.foo(a, b, c, d, e, *f, g, h, i, j, k, l);
+ | +
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
--- /dev/null
+#[derive(Copy, Clone)]
+struct Wrapper<T>(T);
+
+fn foo(_: fn(i32), _: Wrapper<i32>) {}
+
+fn f(_: u32) {}
+
+fn main() {
+ let w = Wrapper::<isize>(1isize);
+ foo(f, w); //~ ERROR arguments to this function are incorrect
+}
--- /dev/null
+error[E0308]: arguments to this function are incorrect
+ --> $DIR/two-mismatch-notes.rs:10:5
+ |
+LL | foo(f, w);
+ | ^^^
+ |
+note: expected `i32`, found `u32`
+ --> $DIR/two-mismatch-notes.rs:10:9
+ |
+LL | foo(f, w);
+ | ^
+ = note: expected fn pointer `fn(i32)`
+ found fn item `fn(u32) {f}`
+note: expected `i32`, found `isize`
+ --> $DIR/two-mismatch-notes.rs:10:12
+ |
+LL | foo(f, w);
+ | ^
+ = note: expected struct `Wrapper<i32>`
+ found struct `Wrapper<isize>`
+note: function defined here
+ --> $DIR/two-mismatch-notes.rs:4:4
+ |
+LL | fn foo(_: fn(i32), _: Wrapper<i32>) {}
+ | ^^^ ---------- ---------------
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
--> $DIR/associated-type-projection-from-supertrait.rs:25:4
|
LL | fn dent<C:Car>(c: C, color: C::Color) { c.chip_paint(color) }
- | ^^^^ ---- ---------------
+ | ^^^^ ---------------
error[E0308]: mismatched types
--> $DIR/associated-type-projection-from-supertrait.rs:28:23
--> $DIR/associated-type-projection-from-supertrait.rs:25:4
|
LL | fn dent<C:Car>(c: C, color: C::Color) { c.chip_paint(color) }
- | ^^^^ ---- ---------------
+ | ^^^^ ---------------
error[E0308]: mismatched types
--> $DIR/associated-type-projection-from-supertrait.rs:32:28
--> $DIR/associated-type-projection-from-supertrait.rs:12:8
|
LL | fn chip_paint(&self, c: Self::Color) { }
- | ^^^^^^^^^^ ----- --------------
+ | ^^^^^^^^^^ --------------
error[E0308]: mismatched types
--> $DIR/associated-type-projection-from-supertrait.rs:33:28
--> $DIR/associated-type-projection-from-supertrait.rs:12:8
|
LL | fn chip_paint(&self, c: Self::Color) { }
- | ^^^^^^^^^^ ----- --------------
+ | ^^^^^^^^^^ --------------
error: aborting due to 4 previous errors
error[E0271]: type mismatch resolving `<ModelT as Vehicle>::Color == Blue`
- --> $DIR/associated-types-binding-to-type-defined-in-supertrait.rs:31:10
+ --> $DIR/associated-types-binding-to-type-defined-in-supertrait.rs:31:19
|
LL | fn b() { blue_car(ModelT); }
- | ^^^^^^^^ type mismatch resolving `<ModelT as Vehicle>::Color == Blue`
+ | -------- ^^^^^^ type mismatch resolving `<ModelT as Vehicle>::Color == Blue`
+ | |
+ | required by a bound introduced by this call
|
note: expected this to be `Blue`
--> $DIR/associated-types-binding-to-type-defined-in-supertrait.rs:16:40
| ^^^^^^^^^^ required by this bound in `blue_car`
error[E0271]: type mismatch resolving `<ModelU as Vehicle>::Color == Black`
- --> $DIR/associated-types-binding-to-type-defined-in-supertrait.rs:32:10
+ --> $DIR/associated-types-binding-to-type-defined-in-supertrait.rs:32:20
|
LL | fn c() { black_car(ModelU); }
- | ^^^^^^^^^ type mismatch resolving `<ModelU as Vehicle>::Color == Black`
+ | --------- ^^^^^^ type mismatch resolving `<ModelU as Vehicle>::Color == Black`
+ | |
+ | required by a bound introduced by this call
|
note: expected this to be `Black`
--> $DIR/associated-types-binding-to-type-defined-in-supertrait.rs:21:40
| +++++++++
error[E0271]: type mismatch resolving `<isize as Foo>::A == Bar`
- --> $DIR/associated-types-eq-3.rs:38:5
+ --> $DIR/associated-types-eq-3.rs:38:10
|
LL | foo1(a);
- | ^^^^ type mismatch resolving `<isize as Foo>::A == Bar`
+ | ---- ^ type mismatch resolving `<isize as Foo>::A == Bar`
+ | |
+ | required by a bound introduced by this call
|
note: expected this to be `Bar`
--> $DIR/associated-types-eq-3.rs:12:14
--> $DIR/associated-types-eq-3.rs:40:9
|
LL | baz(&a);
- | ^^ type mismatch resolving `<isize as Foo>::A == Bar`
+ | --- ^^ type mismatch resolving `<isize as Foo>::A == Bar`
+ | |
+ | required by a bound introduced by this call
|
note: expected this to be `Bar`
--> $DIR/associated-types-eq-3.rs:12:14
error[E0271]: type mismatch resolving `for<'x> <UintStruct as TheTrait<&'x isize>>::A == &'x isize`
- --> $DIR/associated-types-eq-hr.rs:87:5
+ --> $DIR/associated-types-eq-hr.rs:87:11
|
LL | foo::<UintStruct>();
- | ^^^^^^^^^^^^^^^^^ type mismatch resolving `for<'x> <UintStruct as TheTrait<&'x isize>>::A == &'x isize`
+ | ^^^^^^^^^^ type mismatch resolving `for<'x> <UintStruct as TheTrait<&'x isize>>::A == &'x isize`
|
note: expected this to be `&isize`
--> $DIR/associated-types-eq-hr.rs:26:14
| ^^^^^^^^^^^^^ required by this bound in `foo`
error[E0271]: type mismatch resolving `for<'x> <IntStruct as TheTrait<&'x isize>>::A == &'x usize`
- --> $DIR/associated-types-eq-hr.rs:91:5
+ --> $DIR/associated-types-eq-hr.rs:91:11
|
LL | bar::<IntStruct>();
- | ^^^^^^^^^^^^^^^^ type mismatch resolving `for<'x> <IntStruct as TheTrait<&'x isize>>::A == &'x usize`
+ | ^^^^^^^^^ type mismatch resolving `for<'x> <IntStruct as TheTrait<&'x isize>>::A == &'x usize`
|
note: expected this to be `&usize`
--> $DIR/associated-types-eq-hr.rs:14:14
error[E0271]: type mismatch resolving `<Adapter<I> as Iterator>::Item == Option<T>`
- --> $DIR/associated-types-issue-20346.rs:34:5
+ --> $DIR/associated-types-issue-20346.rs:34:36
|
LL | fn test_adapter<T, I: Iterator<Item=Option<T>>>(it: I) {
| - this type parameter
...
LL | is_iterator_of::<Option<T>, _>(&adapter);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type mismatch resolving `<Adapter<I> as Iterator>::Item == Option<T>`
+ | ------------------------------ ^^^^^^^^ type mismatch resolving `<Adapter<I> as Iterator>::Item == Option<T>`
+ | |
+ | required by a bound introduced by this call
|
note: expected this to be `Option<T>`
--> $DIR/associated-types-issue-20346.rs:23:17
error[E0271]: type mismatch resolving `<T as Foo>::Y == i32`
- --> $DIR/associated-types-multiple-types-one-trait.rs:13:5
+ --> $DIR/associated-types-multiple-types-one-trait.rs:13:12
|
LL | want_y(t);
- | ^^^^^^ expected `i32`, found associated type
+ | ------ ^ expected `i32`, found associated type
+ | |
+ | required by a bound introduced by this call
|
= note: expected type `i32`
found associated type `<T as Foo>::Y`
| +++++++++
error[E0271]: type mismatch resolving `<T as Foo>::X == u32`
- --> $DIR/associated-types-multiple-types-one-trait.rs:18:5
+ --> $DIR/associated-types-multiple-types-one-trait.rs:18:12
|
LL | want_x(t);
- | ^^^^^^ expected `u32`, found associated type
+ | ------ ^ expected `u32`, found associated type
+ | |
+ | required by a bound introduced by this call
|
= note: expected type `u32`
found associated type `<T as Foo>::X`
--> $DIR/associated-types-path-2.rs:13:8
|
LL | pub fn f1<T: Foo>(a: T, x: T::A) {}
- | ^^ ---- -------
+ | ^^ -------
help: change the type of the numeric literal from `i32` to `u32`
|
LL | f1(2i32, 4u32);
-error[E0393]: the type parameter `Rhs` must be explicitly specified
- --> $DIR/issue-22560.rs:9:23
- |
-LL | trait Sub<Rhs=Self> {
- | ------------------- type parameter `Rhs` must be specified for this
-...
-LL | type Test = dyn Add + Sub;
- | ^^^ help: set the type parameter to the desired type: `Sub<Rhs>`
- |
- = note: because of the default `Self` reference, type parameters must be specified on object types
-
-error[E0393]: the type parameter `Rhs` must be explicitly specified
- --> $DIR/issue-22560.rs:9:17
- |
-LL | trait Add<Rhs=Self> {
- | ------------------- type parameter `Rhs` must be specified for this
-...
-LL | type Test = dyn Add + Sub;
- | ^^^ help: set the type parameter to the desired type: `Add<Rhs>`
- |
- = note: because of the default `Self` reference, type parameters must be specified on object types
-
error[E0225]: only auto traits can be used as additional traits in a trait object
--> $DIR/issue-22560.rs:9:23
|
| |
| first non-auto trait
|
- = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Add<[type error]> + Sub<[type error]> {}`
+ = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Add + Sub {}`
= note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
error[E0191]: the value of the associated types `Output` (from trait `Add`), `Output` (from trait `Sub`) must be specified
LL | type Test = dyn Add<Output = Type> + Sub<Output = Type>;
| ~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~
+error[E0393]: the type parameter `Rhs` must be explicitly specified
+ --> $DIR/issue-22560.rs:9:17
+ |
+LL | trait Add<Rhs=Self> {
+ | ------------------- type parameter `Rhs` must be specified for this
+...
+LL | type Test = dyn Add + Sub;
+ | ^^^ help: set the type parameter to the desired type: `Add<Rhs>`
+ |
+ = note: because of the default `Self` reference, type parameters must be specified on object types
+
+error[E0393]: the type parameter `Rhs` must be explicitly specified
+ --> $DIR/issue-22560.rs:9:23
+ |
+LL | trait Sub<Rhs=Self> {
+ | ------------------- type parameter `Rhs` must be specified for this
+...
+LL | type Test = dyn Add + Sub;
+ | ^^^ help: set the type parameter to the desired type: `Sub<Rhs>`
+ |
+ = note: because of the default `Self` reference, type parameters must be specified on object types
+
error: aborting due to 4 previous errors
Some errors have detailed explanations: E0191, E0225, E0393.
error[E0271]: type mismatch resolving `<A as Trait>::Associated == ()`
- --> $DIR/issue-87261.rs:56:5
+ --> $DIR/issue-87261.rs:56:19
|
LL | accepts_trait(a);
- | ^^^^^^^^^^^^^ expected `()`, found associated type
+ | ------------- ^ expected `()`, found associated type
+ | |
+ | required by a bound introduced by this call
|
= note: expected unit type `()`
found associated type `<A as Trait>::Associated`
| +++++++++++++++++
error[E0271]: type mismatch resolving `<B as Trait>::Associated == ()`
- --> $DIR/issue-87261.rs:59:5
+ --> $DIR/issue-87261.rs:59:19
|
LL | accepts_trait(b);
- | ^^^^^^^^^^^^^ expected `()`, found associated type
+ | ------------- ^ expected `()`, found associated type
+ | |
+ | required by a bound introduced by this call
|
= note: expected unit type `()`
found associated type `<B as Trait>::Associated`
| ^^^^^^^^^^^^^^^ required by this bound in `accepts_trait`
error[E0271]: type mismatch resolving `<C as Trait>::Associated == ()`
- --> $DIR/issue-87261.rs:62:5
+ --> $DIR/issue-87261.rs:62:19
|
LL | accepts_trait(c);
- | ^^^^^^^^^^^^^ expected `()`, found associated type
+ | ------------- ^ expected `()`, found associated type
+ | |
+ | required by a bound introduced by this call
|
= note: expected unit type `()`
found associated type `<C as Trait>::Associated`
| +++++++++++++++++
error[E0271]: type mismatch resolving `<D as Trait>::Associated == ()`
- --> $DIR/issue-87261.rs:65:5
+ --> $DIR/issue-87261.rs:65:19
|
LL | accepts_trait(d);
- | ^^^^^^^^^^^^^ expected `()`, found associated type
+ | ------------- ^ expected `()`, found associated type
+ | |
+ | required by a bound introduced by this call
|
= note: expected unit type `()`
found associated type `<D as Trait>::Associated`
| ^^^^^^^^^^^^^^^ required by this bound in `accepts_trait`
error[E0271]: type mismatch resolving `<E as GenericTrait<()>>::Associated == ()`
- --> $DIR/issue-87261.rs:68:5
+ --> $DIR/issue-87261.rs:68:27
|
LL | accepts_generic_trait(e);
- | ^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type
+ | --------------------- ^ expected `()`, found associated type
+ | |
+ | required by a bound introduced by this call
|
= note: expected unit type `()`
found associated type `<E as GenericTrait<()>>::Associated`
| +++++++++++++++++
error[E0271]: type mismatch resolving `<F as GenericTrait<()>>::Associated == ()`
- --> $DIR/issue-87261.rs:71:5
+ --> $DIR/issue-87261.rs:71:27
|
LL | accepts_generic_trait(f);
- | ^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type
+ | --------------------- ^ expected `()`, found associated type
+ | |
+ | required by a bound introduced by this call
|
= note: expected unit type `()`
found associated type `<F as GenericTrait<()>>::Associated`
| +++++++++++++++++
error[E0271]: type mismatch resolving `<G as GenericTrait<()>>::Associated == ()`
- --> $DIR/issue-87261.rs:74:5
+ --> $DIR/issue-87261.rs:74:27
|
LL | accepts_generic_trait(g);
- | ^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type
+ | --------------------- ^ expected `()`, found associated type
+ | |
+ | required by a bound introduced by this call
|
= note: expected unit type `()`
found associated type `<G as GenericTrait<()>>::Associated`
| ^^^^^^^^^^^^^^^ required by this bound in `accepts_generic_trait`
error[E0271]: type mismatch resolving `<impl Trait as Trait>::Associated == ()`
- --> $DIR/issue-87261.rs:79:5
+ --> $DIR/issue-87261.rs:79:19
|
LL | fn returns_opaque() -> impl Trait + 'static {
| -------------------- the found opaque type
...
LL | accepts_trait(returns_opaque());
- | ^^^^^^^^^^^^^ expected `()`, found associated type
+ | ------------- ^^^^^^^^^^^^^^^^ expected `()`, found associated type
+ | |
+ | required by a bound introduced by this call
|
= note: expected unit type `()`
found associated type `<impl Trait as Trait>::Associated`
| +++++++++++++++++
error[E0271]: type mismatch resolving `<impl DerivedTrait as Trait>::Associated == ()`
- --> $DIR/issue-87261.rs:82:5
+ --> $DIR/issue-87261.rs:82:19
|
LL | fn returns_opaque_derived() -> impl DerivedTrait + 'static {
| --------------------------- the found opaque type
...
LL | accepts_trait(returns_opaque_derived());
- | ^^^^^^^^^^^^^ expected `()`, found associated type
+ | ------------- ^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type
+ | |
+ | required by a bound introduced by this call
|
= note: expected unit type `()`
found associated type `<impl DerivedTrait as Trait>::Associated`
| +++++++++++++++++
error[E0271]: type mismatch resolving `<impl Trait + Foo as Trait>::Associated == ()`
- --> $DIR/issue-87261.rs:85:5
+ --> $DIR/issue-87261.rs:85:19
|
LL | fn returns_opaque_foo() -> impl Trait + Foo {
| ---------------- the found opaque type
...
LL | accepts_trait(returns_opaque_foo());
- | ^^^^^^^^^^^^^ expected `()`, found associated type
+ | ------------- ^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type
+ | |
+ | required by a bound introduced by this call
|
= note: expected unit type `()`
found associated type `<impl Trait + Foo as Trait>::Associated`
| +++++++++++++++++
error[E0271]: type mismatch resolving `<impl DerivedTrait + Foo as Trait>::Associated == ()`
- --> $DIR/issue-87261.rs:88:5
+ --> $DIR/issue-87261.rs:88:19
|
LL | fn returns_opaque_derived_foo() -> impl DerivedTrait + Foo {
| ----------------------- the found opaque type
...
LL | accepts_trait(returns_opaque_derived_foo());
- | ^^^^^^^^^^^^^ expected `()`, found associated type
+ | ------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type
+ | |
+ | required by a bound introduced by this call
|
= note: expected unit type `()`
found associated type `<impl DerivedTrait + Foo as Trait>::Associated`
| ^^^^^^^^^^^^^^^ required by this bound in `accepts_trait`
error[E0271]: type mismatch resolving `<impl GenericTrait<()> as GenericTrait<()>>::Associated == ()`
- --> $DIR/issue-87261.rs:91:5
+ --> $DIR/issue-87261.rs:91:27
|
LL | fn returns_opaque_generic() -> impl GenericTrait<()> + 'static {
| ------------------------------- the found opaque type
...
LL | accepts_generic_trait(returns_opaque_generic());
- | ^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type
+ | --------------------- ^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type
+ | |
+ | required by a bound introduced by this call
|
= note: expected unit type `()`
found associated type `<impl GenericTrait<()> as GenericTrait<()>>::Associated`
| +++++++++++++++++
error[E0271]: type mismatch resolving `<impl GenericTrait<()> + Foo as GenericTrait<()>>::Associated == ()`
- --> $DIR/issue-87261.rs:94:5
+ --> $DIR/issue-87261.rs:94:27
|
LL | fn returns_opaque_generic_foo() -> impl GenericTrait<()> + Foo {
| --------------------------- the found opaque type
...
LL | accepts_generic_trait(returns_opaque_generic_foo());
- | ^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type
+ | --------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type
+ | |
+ | required by a bound introduced by this call
|
= note: expected unit type `()`
found associated type `<impl GenericTrait<()> + Foo as GenericTrait<()>>::Associated`
| +++++++++++++++++
error[E0271]: type mismatch resolving `<impl GenericTrait<()> + GenericTrait<u8> as GenericTrait<()>>::Associated == ()`
- --> $DIR/issue-87261.rs:97:5
+ --> $DIR/issue-87261.rs:97:27
|
LL | fn returns_opaque_generic_duplicate() -> impl GenericTrait<()> + GenericTrait<u8> {
| ---------------------------------------- the found opaque type
...
LL | accepts_generic_trait(returns_opaque_generic_duplicate());
- | ^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type
+ | --------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type
+ | |
+ | required by a bound introduced by this call
|
= note: expected unit type `()`
found associated type `<impl GenericTrait<()> + GenericTrait<u8> as GenericTrait<()>>::Associated`
--> $DIR/generator-desc.rs:8:4
|
LL | fn fun<F: Future<Output = ()>>(f1: F, f2: F) {}
- | ^^^ ----- -----
+ | ^^^ -----
error[E0308]: mismatched types
--> $DIR/generator-desc.rs:14:26
--> $DIR/generator-desc.rs:8:4
|
LL | fn fun<F: Future<Output = ()>>(f1: F, f2: F) {}
- | ^^^ ----- -----
+ | ^^^ -----
error: aborting due to 3 previous errors
--> $DIR/issue-86053-1.rs:11:12
|
LL | self , ... , self , self , ... ) where F : FnOnce ( & 'a & 'b usize ) {
- | ^^^^
+ | ^^^
error: only foreign or `unsafe extern "C"` functions may be C-variadic
--> $DIR/issue-86053-1.rs:11:12
|
LL | self , ... , self , self , ... ) where F : FnOnce ( & 'a & 'b usize ) {
- | ^^^^
+ | ^^^
error: only foreign or `unsafe extern "C"` functions may be C-variadic
--> $DIR/issue-86053-1.rs:11:36
|
LL | self , ... , self , self , ... ) where F : FnOnce ( & 'a & 'b usize ) {
- | ^^^^
+ | ^^^
error[E0412]: cannot find type `F` in this scope
--> $DIR/issue-86053-1.rs:11:48
--- /dev/null
+#![feature(closure_lifetime_binder)]
+
+fn main() {
+ for<const N: i32> || -> () {};
+ //~^ ERROR only lifetime parameters can be used in this context
+}
--- /dev/null
+error: only lifetime parameters can be used in this context
+ --> $DIR/disallow-const.rs:4:15
+ |
+LL | for<const N: i32> || -> () {};
+ | ^
+
+error: aborting due to previous error
+
--- /dev/null
+#![feature(closure_lifetime_binder)]
+
+fn main() {
+ for<T> || -> () {};
+ //~^ ERROR only lifetime parameters can be used in this context
+}
--- /dev/null
+error: only lifetime parameters can be used in this context
+ --> $DIR/disallow-ty.rs:4:9
+ |
+LL | for<T> || -> () {};
+ | ^
+
+error: aborting due to previous error
+
--> $DIR/coerce-reborrow-multi-arg-fail.rs:1:4
|
LL | fn test<T>(_a: T, _b: T) {}
- | ^^^^ ----- -----
+ | ^^^^ -----
error: aborting due to previous error
--> $DIR/coerce-to-bang.rs:3:4
|
LL | fn foo(x: usize, y: !, z: usize) { }
- | ^^^ -------- ---- --------
+ | ^^^ ----
error[E0308]: mismatched types
--> $DIR/coerce-to-bang.rs:18:13
--> $DIR/coerce-to-bang.rs:3:4
|
LL | fn foo(x: usize, y: !, z: usize) { }
- | ^^^ -------- ---- --------
+ | ^^^ ----
error[E0308]: mismatched types
--> $DIR/coerce-to-bang.rs:26:12
--> $DIR/coerce-to-bang.rs:3:4
|
LL | fn foo(x: usize, y: !, z: usize) { }
- | ^^^ -------- ---- --------
+ | ^^^ ----
error[E0308]: mismatched types
--> $DIR/coerce-to-bang.rs:36:12
--> $DIR/coerce-to-bang.rs:3:4
|
LL | fn foo(x: usize, y: !, z: usize) { }
- | ^^^ -------- ---- --------
+ | ^^^ ----
error[E0308]: mismatched types
--> $DIR/coerce-to-bang.rs:45:12
--> $DIR/coerce-to-bang.rs:3:4
|
LL | fn foo(x: usize, y: !, z: usize) { }
- | ^^^ -------- ---- --------
+ | ^^^ ----
error[E0308]: mismatched types
--> $DIR/coerce-to-bang.rs:50:21
--- /dev/null
+pub trait Trait<const N: usize, T> {}
--- /dev/null
+// check-pass
+// aux-build:trait-with-const-param.rs
+extern crate trait_with_const_param;
+use trait_with_const_param::*;
+
+// Trivial case, const param after local type.
+struct Local1;
+impl<const N: usize, T> Trait<N, T> for Local1 {}
+
+// Concrete consts behave the same as foreign types,
+// so this also trivially works.
+impl Trait<3, Local1> for i32 {}
+
+// This case isn't as trivial as we would forbid type
+// parameters here, we do allow const parameters though.
+//
+// The reason that type parameters are forbidden for
+// `impl<T> Trait<T, LocalInA> for i32 {}` is that another
+// downstream crate can add `impl<T> Trait<LocalInB, T> for i32`.
+// As these two impls would overlap we forbid any impls which
+// have a type parameter in front of a local type.
+//
+// With const parameters this issue does not exist as there are no
+// constants local to another downstream crate.
+struct Local2;
+impl<const N: usize> Trait<N, Local2> for i32 {}
+
+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 because of the requirements on the impl of `Trait<_>` for `T`
+ --> $DIR/issue-100191-2.rs:8:20
+ |
+LL | default impl<T, U> Trait<T> for U {}
+ | ^^^^^^^^ ^
+ = note: 128 redundant requirements hidden
+ = note: required because of the requirements on the impl of `Trait<_>` for `T`
+
+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
+// check-pass
+// (this requires debug assertions)
+
+#![feature(adt_const_params)]
+#![allow(incomplete_features)]
+
+fn foo<const B: &'static bool>(arg: &'static bool) -> bool {
+ B == arg
+}
+
+fn main() {
+ foo::<{ &true }>(&false);
+}
--- /dev/null
+// check-pass
+// (this requires debug assertions)
+
+#![feature(adt_const_params)]
+#![allow(incomplete_features)]
+
+pub const BAR: () = ice::<"">();
+pub const fn ice<const N: &'static str>() {
+ &10;
+}
+
+fn main() {}
const _BAD1: () = unsafe {
MaybeUninit::<!>::uninit().assume_init();
};
- const _BAD2: () = unsafe {
+ const _BAD2: () = {
intrinsics::assert_uninit_valid::<bool>();
};
- const _BAD3: () = unsafe {
+ const _BAD3: () = {
intrinsics::assert_zero_valid::<&'static i32>();
};
}
error: any use of this value will cause an error
--> $DIR/assert-type-intrinsics.rs:17:9
|
-LL | const _BAD2: () = unsafe {
+LL | const _BAD2: () = {
| ---------------
LL | intrinsics::assert_uninit_valid::<bool>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ aborted execution: attempted to leave type `bool` uninitialized, which is invalid
error: any use of this value will cause an error
--> $DIR/assert-type-intrinsics.rs:20:9
|
-LL | const _BAD3: () = unsafe {
+LL | const _BAD3: () = {
| ---------------
LL | intrinsics::assert_zero_valid::<&'static i32>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ aborted execution: attempted to zero-initialize type `&i32`, which is invalid
error: any use of this value will cause an error
--> $DIR/assert-type-intrinsics.rs:17:9
|
-LL | const _BAD2: () = unsafe {
+LL | const _BAD2: () = {
| ---------------
LL | intrinsics::assert_uninit_valid::<bool>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ aborted execution: attempted to leave type `bool` uninitialized, which is invalid
error: any use of this value will cause an error
--> $DIR/assert-type-intrinsics.rs:20:9
|
-LL | const _BAD3: () = unsafe {
+LL | const _BAD3: () = {
| ---------------
LL | intrinsics::assert_zero_valid::<&'static i32>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ aborted execution: attempted to zero-initialize type `&i32`, which is invalid
--- /dev/null
+// revisions: no_flag with_flag
+// [no_flag] check-pass
+// [with_flag] compile-flags: -Zextra-const-ub-checks
+#![feature(const_ptr_read)]
+
+use std::mem::transmute;
+
+const INVALID_BOOL: () = unsafe {
+ let _x: bool = transmute(3u8);
+ //[with_flag]~^ ERROR: evaluation of constant value failed
+ //[with_flag]~| invalid value
+};
+
+const INVALID_PTR_IN_INT: () = unsafe {
+ let _x: usize = transmute(&3u8);
+ //[with_flag]~^ ERROR: evaluation of constant value failed
+ //[with_flag]~| invalid value
+};
+
+const INVALID_SLICE_TO_USIZE_TRANSMUTE: () = unsafe {
+ let x: &[u8] = &[0; 32];
+ let _x: (usize, usize) = transmute(x);
+ //[with_flag]~^ ERROR: evaluation of constant value failed
+ //[with_flag]~| invalid value
+};
+
+const UNALIGNED_PTR: () = unsafe {
+ let _x: &u32 = transmute(&[0u8; 4]);
+ //[with_flag]~^ ERROR: evaluation of constant value failed
+ //[with_flag]~| invalid value
+};
+
+const UNALIGNED_READ: () = {
+ INNER; //[with_flag]~ERROR any use of this value will cause an error
+ //[with_flag]~| previously accepted
+ // There is an error here but its span is in the standard library so we cannot match it...
+ // so we have this in a *nested* const, such that the *outer* const fails to use it.
+ const INNER: () = unsafe {
+ let x = &[0u8; 4];
+ let ptr = x.as_ptr().cast::<u32>();
+ ptr.read();
+ };
+};
+
+fn main() {}
--- /dev/null
+error[E0080]: evaluation of constant value failed
+ --> $DIR/detect-extra-ub.rs:9:20
+ |
+LL | let _x: bool = transmute(3u8);
+ | ^^^^^^^^^^^^^^ constructing invalid value: encountered 0x03, but expected a boolean
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/detect-extra-ub.rs:15:21
+ |
+LL | let _x: usize = transmute(&3u8);
+ | ^^^^^^^^^^^^^^^ constructing invalid value: encountered (potentially part of) a pointer, but expected plain (non-pointer) bytes
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/detect-extra-ub.rs:22:30
+ |
+LL | let _x: (usize, usize) = transmute(x);
+ | ^^^^^^^^^^^^ constructing invalid value at .0: encountered (potentially part of) a pointer, but expected plain (non-pointer) bytes
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/detect-extra-ub.rs:28:20
+ |
+LL | let _x: &u32 = transmute(&[0u8; 4]);
+ | ^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered an unaligned reference (required 4 byte alignment but found 1)
+
+error[E0080]: evaluation of constant value failed
+ --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+ |
+LL | copy_nonoverlapping(src, tmp.as_mut_ptr(), 1);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | accessing memory with alignment 1, but alignment 4 is required
+ | inside `std::ptr::read::<u32>` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+ |
+ ::: $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+ |
+LL | unsafe { read(self) }
+ | ---------- inside `ptr::const_ptr::<impl *const u32>::read` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+ |
+ ::: $DIR/detect-extra-ub.rs:41:9
+ |
+LL | ptr.read();
+ | ---------- inside `INNER` at $DIR/detect-extra-ub.rs:41:9
+
+error: any use of this value will cause an error
+ --> $DIR/detect-extra-ub.rs:34:5
+ |
+LL | const UNALIGNED_READ: () = {
+ | ------------------------
+LL | INNER;
+ | ^^^^^ referenced constant has errors
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0080`.
+Future incompatibility report: Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/detect-extra-ub.rs:34:5
+ |
+LL | const UNALIGNED_READ: () = {
+ | ------------------------
+LL | INNER;
+ | ^^^^^ referenced constant has errors
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
trait Foo<X = Box<dyn Foo>> {
//~^ ERROR cycle detected
- //~| ERROR cycle detected
}
fn main() { }
|
LL | / trait Foo<X = Box<dyn Foo>> {
LL | |
-LL | |
-LL | | }
-LL | |
-LL | | fn main() { }
- | |_____________^
-
-error[E0391]: cycle detected when computing type of `Foo::X`
- --> $DIR/cycle-trait-default-type-trait.rs:4:23
- |
-LL | trait Foo<X = Box<dyn Foo>> {
- | ^^^
- |
- = note: ...which immediately requires computing type of `Foo::X` again
-note: cycle used when collecting item types in top-level module
- --> $DIR/cycle-trait-default-type-trait.rs:4:1
- |
-LL | / trait Foo<X = Box<dyn Foo>> {
-LL | |
-LL | |
LL | | }
LL | |
LL | | fn main() { }
| |_____________^
-error: aborting due to 2 previous errors
+error: aborting due to previous error
For more information about this error, try `rustc --explain E0391`.
--- /dev/null
+// run-pass
+
+use std::cell::RefCell;
+use std::convert::TryInto;
+
+#[derive(Default)]
+struct DropOrderCollector(RefCell<Vec<u32>>);
+
+struct LoudDrop<'a>(&'a DropOrderCollector, u32);
+
+impl Drop for LoudDrop<'_> {
+ fn drop(&mut self) {
+ println!("{}", self.1);
+ self.0.0.borrow_mut().push(self.1);
+ }
+}
+
+impl DropOrderCollector {
+ fn option_loud_drop(&self, n: u32) -> Option<LoudDrop> {
+ Some(LoudDrop(self, n))
+ }
+
+ fn loud_drop(&self, n: u32) -> LoudDrop {
+ LoudDrop(self, n)
+ }
+
+ fn print(&self, n: u32) {
+ println!("{}", n);
+ self.0.borrow_mut().push(n)
+ }
+
+ fn if_(&self) {
+ if self.option_loud_drop(1).is_some() {
+ self.print(2);
+ }
+
+ if self.option_loud_drop(3).is_none() {
+ unreachable!();
+ } else if self.option_loud_drop(4).is_some() {
+ self.print(5);
+ }
+
+ if {
+ if self.option_loud_drop(7).is_some() && self.option_loud_drop(6).is_some() {
+ self.loud_drop(8);
+ true
+ } else {
+ false
+ }
+ } {
+ self.print(9);
+ }
+ }
+
+ fn if_let(&self) {
+ if let None = self.option_loud_drop(2) {
+ unreachable!();
+ } else {
+ self.print(1);
+ }
+
+ if let Some(_) = self.option_loud_drop(4) {
+ self.print(3);
+ }
+
+ if let Some(_d) = self.option_loud_drop(6) {
+ self.print(5);
+ }
+ }
+
+ fn match_(&self) {
+ match self.option_loud_drop(2) {
+ _any => self.print(1),
+ }
+
+ match self.option_loud_drop(4) {
+ _ => self.print(3),
+ }
+
+ match self.option_loud_drop(6) {
+ Some(_) => self.print(5),
+ _ => unreachable!(),
+ }
+
+ match {
+ let _ = self.loud_drop(7);
+ let _d = self.loud_drop(9);
+ self.print(8);
+ ()
+ } {
+ () => self.print(10),
+ }
+
+ match {
+ match self.option_loud_drop(14) {
+ _ => {
+ self.print(11);
+ self.option_loud_drop(13)
+ }
+ }
+ } {
+ _ => self.print(12),
+ }
+
+ match {
+ loop {
+ break match self.option_loud_drop(16) {
+ _ => {
+ self.print(15);
+ self.option_loud_drop(18)
+ }
+ };
+ }
+ } {
+ _ => self.print(17),
+ }
+ }
+
+ fn assert_sorted(self) {
+ assert!(
+ self.0
+ .into_inner()
+ .into_iter()
+ .enumerate()
+ .all(|(idx, item)| idx + 1 == item.try_into().unwrap())
+ );
+ }
+}
+
+fn main() {
+ println!("-- if --");
+ let collector = DropOrderCollector::default();
+ collector.if_();
+ collector.assert_sorted();
+
+ println!("-- if let --");
+ let collector = DropOrderCollector::default();
+ collector.if_let();
+ collector.assert_sorted();
+
+ println!("-- match --");
+ let collector = DropOrderCollector::default();
+ collector.match_();
+ collector.assert_sorted();
+}
error[E0271]: type mismatch resolving `<i8 as Trait>::AssociatedType == u32`
- --> $DIR/E0271.rs:10:5
+ --> $DIR/E0271.rs:10:9
|
LL | foo(3_i8);
- | ^^^ type mismatch resolving `<i8 as Trait>::AssociatedType == u32`
+ | --- ^^^^ type mismatch resolving `<i8 as Trait>::AssociatedType == u32`
+ | |
+ | required by a bound introduced by this call
|
note: expected this to be `u32`
--> $DIR/E0271.rs:7:43
--> $DIR/fn-item-type.rs:7:4
|
LL | fn eq<T>(x: T, y: T) { }
- | ^^ ---- ----
+ | ^^ ----
error[E0308]: mismatched types
--> $DIR/fn-item-type.rs:22:19
--> $DIR/fn-item-type.rs:7:4
|
LL | fn eq<T>(x: T, y: T) { }
- | ^^ ---- ----
+ | ^^ ----
error[E0308]: mismatched types
--> $DIR/fn-item-type.rs:29:23
--> $DIR/fn-item-type.rs:7:4
|
LL | fn eq<T>(x: T, y: T) { }
- | ^^ ---- ----
+ | ^^ ----
error[E0308]: mismatched types
--> $DIR/fn-item-type.rs:38:26
--> $DIR/fn-item-type.rs:7:4
|
LL | fn eq<T>(x: T, y: T) { }
- | ^^ ---- ----
+ | ^^ ----
error[E0308]: mismatched types
--> $DIR/fn-item-type.rs:45:19
--> $DIR/fn-item-type.rs:7:4
|
LL | fn eq<T>(x: T, y: T) { }
- | ^^ ---- ----
+ | ^^ ----
error: aborting due to 5 previous errors
error[E0271]: type mismatch resolving `<{integer} as Fun>::F<'_> == [u8]`
- --> $DIR/issue-74684-2.rs:23:5
+ --> $DIR/issue-74684-2.rs:23:9
|
LL | bug(Box::new(x));
- | ^^^ type mismatch resolving `<{integer} as Fun>::F<'_> == [u8]`
+ | --- ^^^^^^^^^^^ type mismatch resolving `<{integer} as Fun>::F<'_> == [u8]`
+ | |
+ | required by a bound introduced by this call
|
note: expected this to be `[u8]`
--> $DIR/issue-74684-2.rs:10:18
--- /dev/null
+// check-pass
+
+trait A<'a> {}
+trait B<'b> {}
+fn foo<T>() where for<'a> T: A<'a> + 'a {}
+trait C<'c>: for<'a> A<'a> + for<'b> B<'b> {
+ type As;
+}
+struct D<T> where T: for<'c> C<'c, As=&'c ()> {
+ t: std::marker::PhantomData<T>,
+}
+trait E<'e, 'g> {
+ type As;
+}
+trait F<'f>: for<'a> A<'a> + for<'e> E<'e, 'f> {}
+struct G<T> where T: for<'f> F<'f, As=&'f ()> {
+ t: std::marker::PhantomData<T>,
+}
+trait H<'a, 'b> {
+ type As;
+}
+trait I<'a>: for<'b> H<'a, 'b> {}
+
+struct J<T> where T: for<'i> I<'i, As=&'i ()> {
+ t: std::marker::PhantomData<T>,
+}
+
+fn main() {}
--- /dev/null
+fn main() {
+ test::<FooS>(&mut 42); //~ ERROR implementation of `Foo` is not general enough
+}
+
+trait Foo<'a> {}
+
+struct FooS<'a> {
+ data: &'a mut u32,
+}
+
+impl<'a, 'b: 'a> Foo<'b> for FooS<'a> {}
+
+fn test<'a, F>(data: &'a mut u32) where F: for<'b> Foo<'b> {}
--- /dev/null
+error: implementation of `Foo` is not general enough
+ --> $DIR/due-to-where-clause.rs:2:5
+ |
+LL | test::<FooS>(&mut 42);
+ | ^^^^^^^^^^^^ implementation of `Foo` is not general enough
+ |
+ = note: `FooS<'_>` must implement `Foo<'0>`, for any lifetime `'0`...
+ = note: ...but `FooS<'_>` actually implements `Foo<'1>`, for some specific lifetime `'1`
+
+error: aborting due to previous error
+
--- /dev/null
+// Regression test for #54302.
+//
+// We were incorrectly using the "evaluation cache" (which ignored
+// region results) to conclude that `&'static str: Deserialize`, even
+// though it would require that `for<'de> 'de: 'static`, which is
+// clearly false.
+
+trait Deserialize<'de> {}
+
+trait DeserializeOwned: for<'de> Deserialize<'de> {}
+impl<T> DeserializeOwned for T where T: for<'de> Deserialize<'de> {}
+
+// Based on this impl, `&'static str` only implements Deserialize<'static>.
+// It does not implement for<'de> Deserialize<'de>.
+impl<'de: 'a, 'a> Deserialize<'de> for &'a str {}
+
+fn main() {
+ fn assert_deserialize_owned<T: DeserializeOwned>() {}
+ assert_deserialize_owned::<&'static str>(); //~ ERROR
+
+ // It correctly does not implement for<'de> Deserialize<'de>.
+ // fn assert_hrtb<T: for<'de> Deserialize<'de>>() {}
+ // assert_hrtb::<&'static str>();
+}
--- /dev/null
+error: implementation of `Deserialize` is not general enough
+ --> $DIR/hrtb-cache-issue-54302.rs:19:5
+ |
+LL | assert_deserialize_owned::<&'static str>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Deserialize` is not general enough
+ |
+ = note: `&'static str` must implement `Deserialize<'0>`, for any lifetime `'0`...
+ = note: ...but `&str` actually implements `Deserialize<'1>`, for some specific lifetime `'1`
+
+error: aborting due to previous error
+
--- /dev/null
+// Test that an impl with only one bound region `'a` cannot be used to
+// satisfy a constraint where there are two bound regions.
+
+trait Foo<X> {
+ fn foo(&self, x: X) { }
+}
+
+fn want_foo2<T>()
+ where T : for<'a,'b> Foo<(&'a isize, &'b isize)>
+{
+}
+
+fn want_foo1<T>()
+ where T : for<'z> Foo<(&'z isize, &'z isize)>
+{
+}
+
+// Expressed as a where clause
+
+struct SomeStruct;
+
+impl<'a> Foo<(&'a isize, &'a isize)> for SomeStruct
+{
+}
+
+fn a() { want_foo1::<SomeStruct>(); } // OK -- foo wants just one region
+fn b() { want_foo2::<SomeStruct>(); }
+//~^ ERROR implementation of
+//~| ERROR implementation of
+
+fn main() { }
--- /dev/null
+error: implementation of `Foo` is not general enough
+ --> $DIR/hrtb-conflate-regions.rs:27:10
+ |
+LL | fn b() { want_foo2::<SomeStruct>(); }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
+ |
+ = note: `SomeStruct` must implement `Foo<(&'0 isize, &'1 isize)>`, for any two lifetimes `'0` and `'1`...
+ = note: ...but it actually implements `Foo<(&'2 isize, &'2 isize)>`, for some specific lifetime `'2`
+
+error: implementation of `Foo` is not general enough
+ --> $DIR/hrtb-conflate-regions.rs:27:10
+ |
+LL | fn b() { want_foo2::<SomeStruct>(); }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
+ |
+ = note: `SomeStruct` must implement `Foo<(&'0 isize, &'1 isize)>`, for any two lifetimes `'0` and `'1`...
+ = note: ...but it actually implements `Foo<(&'2 isize, &'2 isize)>`, for some specific lifetime `'2`
+
+error: aborting due to 2 previous errors
+
--- /dev/null
+// Test the case where the `Self` type has a bound lifetime that must
+// be adjusted in the fn signature. Issue #19537.
+
+use std::collections::HashMap;
+
+struct Foo<'a> {
+ map: HashMap<usize, &'a str>
+}
+
+impl<'a> Foo<'a> {
+ fn new() -> Foo<'a> { panic!() }
+ fn insert(&'a mut self) { }
+}
+fn main() {
+ let mut foo = Foo::new();
+ foo.insert();
+ foo.insert(); //~ ERROR cannot borrow
+}
--- /dev/null
+error[E0499]: cannot borrow `foo` as mutable more than once at a time
+ --> $DIR/hrtb-debruijn-in-receiver.rs:17:5
+ |
+LL | foo.insert();
+ | ------------ first mutable borrow occurs here
+LL | foo.insert();
+ | ^^^^^^^^^^^^
+ | |
+ | second mutable borrow occurs here
+ | first borrow later used here
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0499`.
--- /dev/null
+// Test an `exists<'a> { forall<'b> { 'a = 'b } }` pattern -- which should not compile!
+//
+// In particular, we test this pattern in trait solving, where it is not connected
+// to any part of the source code.
+
+fn foo<'a>() -> fn(&'a u32) {
+ panic!()
+}
+
+fn main() {
+ // Here, proving that `fn(&'a u32) <: for<'b> fn(&'b u32)`:
+ //
+ // - instantiates `'b` with a placeholder `!b`,
+ // - requires that `&!b u32 <: &'a u32` and hence that `!b: 'a`,
+ // - but we can never know this.
+
+ let _: for<'b> fn(&'b u32) = foo(); //~ ERROR mismatched types
+}
--- /dev/null
+error[E0308]: mismatched types
+ --> $DIR/hrtb-exists-forall-fn.rs:17:34
+ |
+LL | let _: for<'b> fn(&'b u32) = foo();
+ | ^^^^^ one type is more general than the other
+ |
+ = note: expected fn pointer `for<'b> fn(&'b u32)`
+ found fn pointer `fn(&u32)`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
--- /dev/null
+// Test a case where variance and higher-ranked types interact in surprising ways.
+//
+// In particular, we test this pattern in trait solving, where it is not connected
+// to any part of the source code.
+
+trait Trait<T> {}
+
+fn foo<T>()
+where
+ T: Trait<for<'b> fn(&'b u32)>,
+{
+}
+
+impl<'a> Trait<fn(&'a u32)> for () {}
+
+fn main() {
+ // Here, proving that `(): Trait<for<'b> fn(&'b u32)>` uses the impl:
+ //
+ // - The impl provides the clause `forall<'a> { (): Trait<fn(&'a u32)> }`
+ // - We instantiate `'a` existentially to get `(): Trait<fn(&?a u32)>`
+ // - We unify `fn(&?a u32)` with `for<'b> fn(&'b u32)` -- this does a
+ // "bidirectional" subtyping check, so we wind up with:
+ // - `fn(&?a u32) <: for<'b> fn(&'b u32)` :-
+ // - `&'!b u32 <: &?a u32`
+ // - `!'b: ?a` -- solveable if `?a` is inferred to `'empty`
+ // - `for<'b> fn(&'b u32) <: fn(&?a u32)` :-
+ // - `&?a u32 u32 <: &?b u32`
+ // - `?a: ?b` -- solveable if `?b` is also inferred to `'empty`
+ // - So the subtyping check succeeds, somewhat surprisingly.
+ // This is because we can use `'empty`.
+ //
+ // NB. *However*, the reinstated leak-check gives an error here.
+
+ foo::<()>();
+ //~^ ERROR implementation of `Trait` is not general enough
+}
--- /dev/null
+error: implementation of `Trait` is not general enough
+ --> $DIR/hrtb-exists-forall-trait-contravariant.rs:34:5
+ |
+LL | foo::<()>();
+ | ^^^^^^^^^^^ implementation of `Trait` is not general enough
+ |
+ = note: `()` must implement `Trait<for<'b> fn(&'b u32)>`
+ = note: ...but it actually implements `Trait<fn(&'0 u32)>`, for some specific lifetime `'0`
+
+error: aborting due to previous error
+
--- /dev/null
+// Test a case where variance and higher-ranked types interact in surprising ways.
+//
+// In particular, we test this pattern in trait solving, where it is not connected
+// to any part of the source code.
+//
+// check-pass
+
+trait Trait<T> {}
+
+fn foo<T>()
+where
+ T: Trait<for<'b> fn(fn(&'b u32))>,
+{
+}
+
+impl<'a> Trait<fn(fn(&'a u32))> for () {}
+
+fn main() {
+ // Here, proving that `(): Trait<for<'b> fn(&'b u32)>` uses the impl:
+ //
+ // - The impl provides the clause `forall<'a> { (): Trait<fn(fn(&'a u32))> }`
+ // - We instantiate `'a` existentially to get `(): Trait<fn(fn(&?a u32))>`
+ // - We unify `fn(fn(&?a u32))` with `for<'b> fn(fn(&'b u32))` -- this does a
+ // "bidirectional" subtyping check, so we wind up with:
+ // - `fn(fn(&?a u32)) <: for<'b> fn(fn(&'b u32))` :-
+ // - `fn(&!b u32) <: fn(&?a u32)`
+ // - `&?a u32 <: &!b u32`
+ // - `?a: !'b` -- solveable if `?a` is inferred to `'static`
+ // - `for<'b> fn(fn(&'b u32)) <: fn(fn(&?a u32))` :-
+ // - `fn(&?a u32) <: fn(&?b u32)`
+ // - `&?b u32 <: &?a u32`
+ // - `?b: ?a` -- solveable if `?b` is inferred to `'static`
+ // - So the subtyping check succeeds, somewhat surprisingly.
+ // This is because we can use `'static`.
+
+ foo::<()>();
+}
--- /dev/null
+// Test an `exists<'a> { forall<'b> { 'a = 'b } }` pattern -- which should not compile!
+//
+// In particular, we test this pattern in trait solving, where it is not connected
+// to any part of the source code.
+
+use std::cell::Cell;
+
+trait Trait<T> {}
+
+fn foo<T>()
+where
+ T: Trait<for<'b> fn(Cell<&'b u32>)>,
+{
+}
+
+impl<'a> Trait<fn(Cell<&'a u32>)> for () {}
+
+fn main() {
+ // Here, proving that `(): Trait<for<'b> fn(&'b u32)>` uses the impl:
+ //
+ // - The impl provides the clause `forall<'a> { (): Trait<fn(&'a u32)> }`
+ // - We instantiate `'a` existentially to get `(): Trait<fn(&?a u32)>`
+ // - We unify `fn(&?a u32)` with `for<'b> fn(&'b u32)`
+ // - This requires (among other things) instantiating `'b` universally,
+ // yielding `fn(&!b u32)`, in a fresh universe U1
+ // - So we get `?a = !b` but the universe U0 assigned to `?a` cannot name `!b`.
+
+ foo::<()>(); //~ ERROR implementation of `Trait` is not general enough
+}
--- /dev/null
+error: implementation of `Trait` is not general enough
+ --> $DIR/hrtb-exists-forall-trait-invariant.rs:28:5
+ |
+LL | foo::<()>();
+ | ^^^^^^^^^^^ implementation of `Trait` is not general enough
+ |
+ = note: `()` must implement `Trait<for<'b> fn(Cell<&'b u32>)>`
+ = note: ...but it actually implements `Trait<fn(Cell<&'0 u32>)>`, for some specific lifetime `'0`
+
+error: aborting due to previous error
+
--- /dev/null
+// Test HRTB supertraits with several levels of expansion required.
+
+trait Foo<'tcx>
+{
+ fn foo(&'tcx self) -> &'tcx isize;
+}
+
+trait Bar<'ccx>
+ : for<'tcx> Foo<'tcx>
+{
+ fn bar(&'ccx self) -> &'ccx isize;
+}
+
+trait Baz
+ : for<'ccx> Bar<'ccx>
+{
+ fn dummy(&self);
+}
+
+trait Qux
+ : Bar<'static>
+{
+ fn dummy(&self);
+}
+
+fn want_foo_for_any_tcx<F>(f: &F)
+ where F : for<'tcx> Foo<'tcx>
+{
+}
+
+fn want_bar_for_any_ccx<B>(b: &B)
+ where B : for<'ccx> Bar<'ccx>
+{
+}
+
+fn want_baz<B>(b: &B)
+ where B : Baz
+{
+ want_foo_for_any_tcx(b);
+ want_bar_for_any_ccx(b);
+}
+
+fn want_qux<B>(b: &B)
+ where B : Qux
+{
+ want_foo_for_any_tcx(b);
+ want_bar_for_any_ccx(b); //~ ERROR
+}
+
+fn main() {}
--- /dev/null
+error[E0277]: the trait bound `for<'ccx> B: Bar<'ccx>` is not satisfied
+ --> $DIR/hrtb-higher-ranker-supertraits-transitive.rs:47:26
+ |
+LL | want_bar_for_any_ccx(b);
+ | -------------------- ^ the trait `for<'ccx> Bar<'ccx>` is not implemented for `B`
+ | |
+ | required by a bound introduced by this call
+ |
+note: required by a bound in `want_bar_for_any_ccx`
+ --> $DIR/hrtb-higher-ranker-supertraits-transitive.rs:32:15
+ |
+LL | fn want_bar_for_any_ccx<B>(b: &B)
+ | -------------------- required by a bound in this
+LL | where B : for<'ccx> Bar<'ccx>
+ | ^^^^^^^^^^^^^^^^^^^ required by this bound in `want_bar_for_any_ccx`
+help: consider further restricting this bound
+ |
+LL | where B : Qux + for<'ccx> Bar<'ccx>
+ | +++++++++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
--- /dev/null
+// Test a trait (`Bar`) with a higher-ranked supertrait.
+
+trait Foo<'tcx>
+{
+ fn foo(&'tcx self) -> &'tcx isize;
+}
+
+trait Bar<'ccx>
+ : for<'tcx> Foo<'tcx>
+{
+ fn bar(&'ccx self) -> &'ccx isize;
+}
+
+fn want_foo_for_some_tcx<'x,F>(f: &'x F)
+ where F : Foo<'x>
+{
+ want_foo_for_some_tcx(f);
+ want_foo_for_any_tcx(f); //~ ERROR not satisfied
+}
+
+fn want_foo_for_any_tcx<F>(f: &F)
+ where F : for<'tcx> Foo<'tcx>
+{
+ want_foo_for_some_tcx(f);
+ want_foo_for_any_tcx(f);
+}
+
+fn want_bar_for_some_ccx<'x,B>(b: &B)
+ where B : Bar<'x>
+{
+ want_foo_for_some_tcx(b);
+ want_foo_for_any_tcx(b);
+
+ want_bar_for_some_ccx(b);
+ want_bar_for_any_ccx(b); //~ ERROR not satisfied
+}
+
+fn want_bar_for_any_ccx<B>(b: &B)
+ where B : for<'ccx> Bar<'ccx>
+{
+ want_foo_for_some_tcx(b);
+ want_foo_for_any_tcx(b);
+
+ want_bar_for_some_ccx(b);
+ want_bar_for_any_ccx(b);
+}
+
+fn main() {}
--- /dev/null
+error[E0277]: the trait bound `for<'tcx> F: Foo<'tcx>` is not satisfied
+ --> $DIR/hrtb-higher-ranker-supertraits.rs:18:26
+ |
+LL | want_foo_for_any_tcx(f);
+ | -------------------- ^ the trait `for<'tcx> Foo<'tcx>` is not implemented for `F`
+ | |
+ | required by a bound introduced by this call
+ |
+note: required by a bound in `want_foo_for_any_tcx`
+ --> $DIR/hrtb-higher-ranker-supertraits.rs:22:15
+ |
+LL | fn want_foo_for_any_tcx<F>(f: &F)
+ | -------------------- required by a bound in this
+LL | where F : for<'tcx> Foo<'tcx>
+ | ^^^^^^^^^^^^^^^^^^^ required by this bound in `want_foo_for_any_tcx`
+help: consider further restricting this bound
+ |
+LL | where F : Foo<'x> + for<'tcx> Foo<'tcx>
+ | +++++++++++++++++++++
+
+error[E0277]: the trait bound `for<'ccx> B: Bar<'ccx>` is not satisfied
+ --> $DIR/hrtb-higher-ranker-supertraits.rs:35:26
+ |
+LL | want_bar_for_any_ccx(b);
+ | -------------------- ^ the trait `for<'ccx> Bar<'ccx>` is not implemented for `B`
+ | |
+ | required by a bound introduced by this call
+ |
+note: required by a bound in `want_bar_for_any_ccx`
+ --> $DIR/hrtb-higher-ranker-supertraits.rs:39:15
+ |
+LL | fn want_bar_for_any_ccx<B>(b: &B)
+ | -------------------- required by a bound in this
+LL | where B : for<'ccx> Bar<'ccx>
+ | ^^^^^^^^^^^^^^^^^^^ required by this bound in `want_bar_for_any_ccx`
+help: consider further restricting this bound
+ |
+LL | where B : Bar<'x> + for<'ccx> Bar<'ccx>
+ | +++++++++++++++++++++
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
--- /dev/null
+// Test that the `'a` in the where clause correctly links the region
+// of the output to the region of the input.
+
+trait FnLike<A,R> {
+ fn call(&self, arg: A) -> R;
+}
+
+fn call_repeatedly<F>(f: F)
+ where F : for<'a> FnLike<&'a isize, &'a isize>
+{
+ // Result is stored: cannot re-assign `x`
+ let mut x = 3;
+ let y = f.call(&x);
+ x = 5; //~ ERROR cannot assign to `x` because it is borrowed
+
+ // Result is not stored: can re-assign `x`
+ let mut x = 3;
+ f.call(&x);
+ f.call(&x);
+ f.call(&x);
+ x = 5;
+ drop(y);
+}
+
+fn main() {
+}
--- /dev/null
+error[E0506]: cannot assign to `x` because it is borrowed
+ --> $DIR/hrtb-identity-fn-borrows.rs:14:5
+ |
+LL | let y = f.call(&x);
+ | -- borrow of `x` occurs here
+LL | x = 5;
+ | ^^^^^ assignment to borrowed `x` occurs here
+...
+LL | drop(y);
+ | - borrow later used here
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0506`.
--- /dev/null
+// Test a case where you have an impl of `Foo<X>` for all `X` that
+// is being applied to `for<'a> Foo<&'a mut X>`. Issue #19730.
+
+trait Foo<X> {
+ fn foo(&self, x: X) { }
+}
+
+fn want_hrtb<T>()
+ where T : for<'a> Foo<&'a isize>
+{
+}
+
+// AnyInt implements Foo<&'a isize> for any 'a, so it is a match.
+struct AnyInt;
+impl<'a> Foo<&'a isize> for AnyInt { }
+fn give_any() {
+ want_hrtb::<AnyInt>()
+}
+
+// StaticInt only implements Foo<&'static isize>, so it is an error.
+struct StaticInt;
+impl Foo<&'static isize> for StaticInt { }
+fn give_static() {
+ want_hrtb::<StaticInt>() //~ ERROR
+}
+
+// &'a u32 only implements Foo<&'a isize> for specific 'a, so it is an error.
+impl<'a> Foo<&'a isize> for &'a u32 { }
+fn give_some<'a>() {
+ want_hrtb::<&'a u32>()
+ //~^ ERROR lifetime may not live long enough
+ //~| ERROR implementation of `Foo` is not general enough
+}
+
+fn main() { }
--- /dev/null
+error: implementation of `Foo` is not general enough
+ --> $DIR/hrtb-just-for-static.rs:24:5
+ |
+LL | want_hrtb::<StaticInt>()
+ | ^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
+ |
+ = note: `StaticInt` must implement `Foo<&'0 isize>`, for any lifetime `'0`...
+ = note: ...but it actually implements `Foo<&'static isize>`
+
+error: lifetime may not live long enough
+ --> $DIR/hrtb-just-for-static.rs:30:5
+ |
+LL | fn give_some<'a>() {
+ | -- lifetime `'a` defined here
+LL | want_hrtb::<&'a u32>()
+ | ^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
+
+error: implementation of `Foo` is not general enough
+ --> $DIR/hrtb-just-for-static.rs:30:5
+ |
+LL | want_hrtb::<&'a u32>()
+ | ^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
+ |
+ = note: `Foo<&'0 isize>` would have to be implemented for the type `&u32`, for any lifetime `'0`...
+ = note: ...but `Foo<&'1 isize>` is actually implemented for the type `&'1 u32`, for some specific lifetime `'1`
+
+error: aborting due to 3 previous errors
+
--- /dev/null
+warning: function cannot return without recursing
+ --> $DIR/hrtb-perfect-forwarding.rs:16:1
+ |
+LL | / fn no_hrtb<'b, T>(mut t: T)
+LL | | where
+LL | | T: Bar<&'b isize>,
+LL | | {
+... |
+LL | | no_hrtb(&mut t);
+ | | --------------- recursive call site
+LL | | }
+ | |_^ cannot return without recursing
+ |
+ = note: `#[warn(unconditional_recursion)]` on by default
+ = help: a `loop` may express intention better if this is on purpose
+
+warning: function cannot return without recursing
+ --> $DIR/hrtb-perfect-forwarding.rs:25:1
+ |
+LL | / fn bar_hrtb<T>(mut t: T)
+LL | | where
+LL | | T: for<'b> Bar<&'b isize>,
+LL | | {
+... |
+LL | | bar_hrtb(&mut t);
+ | | ---------------- recursive call site
+LL | | }
+ | |_^ cannot return without recursing
+ |
+ = help: a `loop` may express intention better if this is on purpose
+
+warning: function cannot return without recursing
+ --> $DIR/hrtb-perfect-forwarding.rs:35:1
+ |
+LL | / fn foo_hrtb_bar_not<'b, T>(mut t: T)
+LL | | where
+LL | | T: for<'a> Foo<&'a isize> + Bar<&'b isize>,
+LL | | {
+... |
+LL | | foo_hrtb_bar_not(&mut t);
+ | | ------------------------ recursive call site
+LL | |
+LL | |
+LL | | }
+ | |_^ cannot return without recursing
+ |
+ = help: a `loop` may express intention better if this is on purpose
+
+error: higher-ranked subtype error
+ --> $DIR/hrtb-perfect-forwarding.rs:43:5
+ |
+LL | foo_hrtb_bar_not(&mut t);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: function cannot return without recursing
+ --> $DIR/hrtb-perfect-forwarding.rs:48:1
+ |
+LL | / fn foo_hrtb_bar_hrtb<T>(mut t: T)
+LL | | where
+LL | | T: for<'a> Foo<&'a isize> + for<'b> Bar<&'b isize>,
+LL | | {
+LL | | // OK -- now we have `T : for<'b> Bar<&'b isize>`.
+LL | | foo_hrtb_bar_hrtb(&mut t);
+ | | ------------------------- recursive call site
+LL | | }
+ | |_^ cannot return without recursing
+ |
+ = help: a `loop` may express intention better if this is on purpose
+
+error: aborting due to previous error; 4 warnings emitted
+
--- /dev/null
+// Test a case where you have an impl of `Foo<X>` for all `X` that
+// is being applied to `for<'a> Foo<&'a mut X>`. Issue #19730.
+
+trait Foo<X> {
+ fn foo(&mut self, x: X) {}
+}
+
+trait Bar<X> {
+ fn bar(&mut self, x: X) {}
+}
+
+impl<'a, X, F> Foo<X> for &'a mut F where F: Foo<X> + Bar<X> {}
+
+impl<'a, X, F> Bar<X> for &'a mut F where F: Bar<X> {}
+
+fn no_hrtb<'b, T>(mut t: T) //~ WARN function cannot return
+where
+ T: Bar<&'b isize>,
+{
+ // OK -- `T : Bar<&'b isize>`, and thus the impl above ensures that
+ // `&mut T : Bar<&'b isize>`.
+ no_hrtb(&mut t);
+}
+
+fn bar_hrtb<T>(mut t: T) //~ WARN function cannot return
+where
+ T: for<'b> Bar<&'b isize>,
+{
+ // OK -- `T : for<'b> Bar<&'b isize>`, and thus the impl above
+ // ensures that `&mut T : for<'b> Bar<&'b isize>`. This is an
+ // example of a "perfect forwarding" impl.
+ bar_hrtb(&mut t);
+}
+
+fn foo_hrtb_bar_not<'b, T>(mut t: T) //~ WARN function cannot return
+where
+ T: for<'a> Foo<&'a isize> + Bar<&'b isize>,
+{
+ // Not OK -- The forwarding impl for `Foo` requires that `Bar` also
+ // be implemented. Thus to satisfy `&mut T : for<'a> Foo<&'a
+ // isize>`, we require `T : for<'a> Bar<&'a isize>`, but the where
+ // clause only specifies `T : Bar<&'b isize>`.
+ foo_hrtb_bar_not(&mut t);
+ //~^ ERROR implementation of `Bar` is not general enough
+ //~^^ ERROR lifetime may not live long enough
+}
+
+fn foo_hrtb_bar_hrtb<T>(mut t: T) //~ WARN function cannot return
+where
+ T: for<'a> Foo<&'a isize> + for<'b> Bar<&'b isize>,
+{
+ // OK -- now we have `T : for<'b> Bar<&'b isize>`.
+ foo_hrtb_bar_hrtb(&mut t);
+}
+
+fn main() {}
--- /dev/null
+warning: function cannot return without recursing
+ --> $DIR/hrtb-perfect-forwarding.rs:16:1
+ |
+LL | / fn no_hrtb<'b, T>(mut t: T)
+LL | | where
+LL | | T: Bar<&'b isize>,
+ | |______________________^ cannot return without recursing
+...
+LL | no_hrtb(&mut t);
+ | --------------- recursive call site
+ |
+ = note: `#[warn(unconditional_recursion)]` on by default
+ = help: a `loop` may express intention better if this is on purpose
+
+warning: function cannot return without recursing
+ --> $DIR/hrtb-perfect-forwarding.rs:25:1
+ |
+LL | / fn bar_hrtb<T>(mut t: T)
+LL | | where
+LL | | T: for<'b> Bar<&'b isize>,
+ | |______________________________^ cannot return without recursing
+...
+LL | bar_hrtb(&mut t);
+ | ---------------- recursive call site
+ |
+ = help: a `loop` may express intention better if this is on purpose
+
+warning: function cannot return without recursing
+ --> $DIR/hrtb-perfect-forwarding.rs:35:1
+ |
+LL | / fn foo_hrtb_bar_not<'b, T>(mut t: T)
+LL | | where
+LL | | T: for<'a> Foo<&'a isize> + Bar<&'b isize>,
+ | |_______________________________________________^ cannot return without recursing
+...
+LL | foo_hrtb_bar_not(&mut t);
+ | ------------------------ recursive call site
+ |
+ = help: a `loop` may express intention better if this is on purpose
+
+error: lifetime may not live long enough
+ --> $DIR/hrtb-perfect-forwarding.rs:43:5
+ |
+LL | fn foo_hrtb_bar_not<'b, T>(mut t: T)
+ | -- lifetime `'b` defined here
+...
+LL | foo_hrtb_bar_not(&mut t);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'b` must outlive `'static`
+
+error: implementation of `Bar` is not general enough
+ --> $DIR/hrtb-perfect-forwarding.rs:43:5
+ |
+LL | foo_hrtb_bar_not(&mut t);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Bar` is not general enough
+ |
+ = note: `T` must implement `Bar<&'0 isize>`, for any lifetime `'0`...
+ = note: ...but it actually implements `Bar<&'1 isize>`, for some specific lifetime `'1`
+
+warning: function cannot return without recursing
+ --> $DIR/hrtb-perfect-forwarding.rs:48:1
+ |
+LL | / fn foo_hrtb_bar_hrtb<T>(mut t: T)
+LL | | where
+LL | | T: for<'a> Foo<&'a isize> + for<'b> Bar<&'b isize>,
+ | |_______________________________________________________^ cannot return without recursing
+...
+LL | foo_hrtb_bar_hrtb(&mut t);
+ | ------------------------- recursive call site
+ |
+ = help: a `loop` may express intention better if this is on purpose
+
+error: aborting due to 2 previous errors; 4 warnings emitted
+
--- /dev/null
+// rust-lang/rust#30786: the use of `for<'b> &'b mut A: Stream<Item=T`
+// should act as assertion that item does not borrow from its stream;
+// but an earlier buggy rustc allowed `.map(|x: &_| x)` which does
+// have such an item.
+//
+// This tests double-checks that we do not allow such behavior to leak
+// through again.
+
+pub trait Stream {
+ type Item;
+ fn next(self) -> Option<Self::Item>;
+}
+
+// Example stream
+pub struct Repeat(u64);
+
+impl<'a> Stream for &'a mut Repeat {
+ type Item = &'a u64;
+ fn next(self) -> Option<Self::Item> {
+ Some(&self.0)
+ }
+}
+
+pub struct Map<S, F> {
+ stream: S,
+ func: F,
+}
+
+impl<'a, A, F, T> Stream for &'a mut Map<A, F>
+where
+ &'a mut A: Stream,
+ F: FnMut(<&'a mut A as Stream>::Item) -> T,
+{
+ type Item = T;
+ fn next(self) -> Option<T> {
+ match self.stream.next() {
+ Some(item) => Some((self.func)(item)),
+ None => None,
+ }
+ }
+}
+
+pub struct Filter<S, F> {
+ stream: S,
+ func: F,
+}
+
+impl<'a, A, F, T> Stream for &'a mut Filter<A, F>
+where
+ for<'b> &'b mut A: Stream<Item = T>, // <---- BAD
+ F: FnMut(&T) -> bool,
+{
+ type Item = <&'a mut A as Stream>::Item;
+ fn next(self) -> Option<Self::Item> {
+ while let Some(item) = self.stream.next() {
+ if (self.func)(&item) {
+ return Some(item);
+ }
+ }
+ None
+ }
+}
+
+pub trait StreamExt
+where
+ for<'b> &'b mut Self: Stream,
+{
+ fn mapx<F>(self, func: F) -> Map<Self, F>
+ where
+ Self: Sized,
+ for<'a> &'a mut Map<Self, F>: Stream,
+ {
+ Map { func: func, stream: self }
+ }
+
+ fn filterx<F>(self, func: F) -> Filter<Self, F>
+ where
+ Self: Sized,
+ for<'a> &'a mut Filter<Self, F>: Stream,
+ {
+ Filter { func: func, stream: self }
+ }
+
+ fn countx(mut self) -> usize
+ where
+ Self: Sized,
+ {
+ let mut count = 0;
+ while let Some(_) = self.next() {
+ count += 1;
+ }
+ count
+ }
+}
+
+impl<T> StreamExt for T where for<'a> &'a mut T: Stream {}
+
+fn identity<T>(x: &T) -> &T {
+ x
+}
+
+fn variant1() {
+ let source = Repeat(10);
+
+ // Here, the call to `mapx` returns a type `T` to which `StreamExt`
+ // is not applicable, because `for<'b> &'b mut T: Stream`) doesn't hold.
+ //
+ // More concretely, the type `T` is `Map<Repeat, Closure>`, and
+ // the where clause doesn't hold because the signature of the
+ // closure gets inferred to a signature like `|&'_ Stream| -> &'_`
+ // for some specific `'_`, rather than a more generic
+ // signature.
+ //
+ // Why *exactly* we opt for this signature is a bit unclear to me,
+ // we deduce it somehow from a reuqirement that `Map: Stream` I
+ // guess.
+ let map = source.mapx(|x: &_| x);
+ let filter = map.filterx(|x: &_| true);
+ //~^ ERROR the method
+}
+
+fn variant2() {
+ let source = Repeat(10);
+
+ // Here, we use a function, which is not subject to the vagaries
+ // of closure signature inference. In this case, we get the error
+ // on `countx` as, I think, the test originally expected.
+ let map = source.mapx(identity);
+ let filter = map.filterx(|x: &_| true);
+ let count = filter.countx();
+ //~^ ERROR the method
+}
+
+fn main() {}
--- /dev/null
+error[E0599]: the method `filterx` exists for struct `Map<Repeat, [closure@$DIR/issue-30786.rs:117:27: 117:34]>`, but its trait bounds were not satisfied
+ --> $DIR/issue-30786.rs:118:22
+ |
+LL | pub struct Map<S, F> {
+ | --------------------
+ | |
+ | method `filterx` not found for this struct
+ | doesn't satisfy `_: StreamExt`
+...
+LL | let filter = map.filterx(|x: &_| true);
+ | ^^^^^^^ method cannot be called on `Map<Repeat, [closure@$DIR/issue-30786.rs:117:27: 117:34]>` due to unsatisfied trait bounds
+ |
+note: the following trait bounds were not satisfied:
+ `&'a mut &Map<Repeat, [closure@$DIR/issue-30786.rs:117:27: 117:34]>: Stream`
+ `&'a mut &mut Map<Repeat, [closure@$DIR/issue-30786.rs:117:27: 117:34]>: Stream`
+ `&'a mut Map<Repeat, [closure@$DIR/issue-30786.rs:117:27: 117:34]>: Stream`
+ --> $DIR/issue-30786.rs:96:50
+ |
+LL | impl<T> StreamExt for T where for<'a> &'a mut T: Stream {}
+ | --------- - ^^^^^^ unsatisfied trait bound introduced here
+
+error[E0599]: the method `countx` exists for struct `Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:129:30: 129:37]>`, but its trait bounds were not satisfied
+ --> $DIR/issue-30786.rs:130:24
+ |
+LL | pub struct Filter<S, F> {
+ | -----------------------
+ | |
+ | method `countx` not found for this struct
+ | doesn't satisfy `_: StreamExt`
+...
+LL | let count = filter.countx();
+ | ^^^^^^ method cannot be called on `Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:129:30: 129:37]>` due to unsatisfied trait bounds
+ |
+note: the following trait bounds were not satisfied:
+ `&'a mut &Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:129:30: 129:37]>: Stream`
+ `&'a mut &mut Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:129:30: 129:37]>: Stream`
+ `&'a mut Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:129:30: 129:37]>: Stream`
+ --> $DIR/issue-30786.rs:96:50
+ |
+LL | impl<T> StreamExt for T where for<'a> &'a mut T: Stream {}
+ | --------- - ^^^^^^ unsatisfied trait bound introduced here
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0599`.
--- /dev/null
+// Regression test for #46989:
+//
+// In the move to universes, this test started passing.
+// It is not necessarily WRONG to do so, but it was a bit
+// surprising. The reason that it passed is that when we were
+// asked to prove that
+//
+// for<'a> fn(&'a i32): Foo
+//
+// we were able to use the impl below to prove
+//
+// fn(&'empty i32): Foo
+//
+// and then we were able to prove that
+//
+// fn(&'empty i32) = for<'a> fn(&'a i32)
+//
+// This last fact is somewhat surprising, but essentially "falls out"
+// from handling variance correctly. In particular, consider the subtyping
+// relations. First:
+//
+// fn(&'empty i32) <: for<'a> fn(&'a i32)
+//
+// This holds because -- intuitively -- a fn that takes a reference but doesn't use
+// it can be given a reference with any lifetime. Similarly, the opposite direction:
+//
+// for<'a> fn(&'a i32) <: fn(&'empty i32)
+//
+// holds because 'a can be instantiated to 'empty.
+
+trait Foo {}
+
+impl<A> Foo for fn(A) {}
+
+fn assert_foo<T: Foo>() {}
+
+fn main() {
+ assert_foo::<fn(&i32)>();
+ //~^ ERROR implementation of `Foo` is not general enough
+}
--- /dev/null
+error: implementation of `Foo` is not general enough
+ --> $DIR/issue-46989.rs:38:5
+ |
+LL | assert_foo::<fn(&i32)>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
+ |
+ = note: `Foo` would have to be implemented for the type `for<'r> fn(&'r i32)`
+ = note: ...but `Foo` is actually implemented for the type `fn(&'0 i32)`, for some specific lifetime `'0`
+
+error: aborting due to previous error
+
--- /dev/null
+// Regression test for #57639:
+//
+// In the move to universes, this test stopped working. The problem
+// was that when the trait solver was asked to prove `for<'a> T::Item:
+// Foo<'a>` as part of WF checking, it wound up "eagerly committing"
+// to the where clause, which says that `T::Item: Foo<'a>`, but it
+// should instead have been using the bound found in the trait
+// declaration. Pre-universe, this used to work out ok because we got
+// "eager errors" due to the leak check.
+//
+// See [this comment on GitHub][c] for more details.
+//
+// check-pass
+//
+// [c]: https://github.com/rust-lang/rust/issues/57639#issuecomment-455685861
+
+trait Foo<'a> {}
+
+trait Bar {
+ type Item: for<'a> Foo<'a>;
+}
+
+fn foo<'a, T>(_: T)
+where
+ T: Bar,
+ T::Item: Foo<'a>,
+{}
+
+fn main() { }
--- /dev/null
+// Regression test for #58451:
+//
+// Error reporting here encountered an ICE in the shift to universes.
+
+fn f<I>(i: I)
+where
+ I: IntoIterator,
+ I::Item: for<'a> Into<&'a ()>,
+{}
+
+fn main() {
+ f(&[f()]); //~ ERROR this function takes 1 argument
+}
--- /dev/null
+error[E0061]: this function takes 1 argument but 0 arguments were supplied
+ --> $DIR/issue-58451.rs:12:9
+ |
+LL | f(&[f()]);
+ | ^-- an argument is missing
+ |
+note: function defined here
+ --> $DIR/issue-58451.rs:5:4
+ |
+LL | fn f<I>(i: I)
+ | ^ ----
+help: provide the argument
+ |
+LL | f(&[f(/* value */)]);
+ | ~~~~~~~~~~~~~~
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0061`.
--- /dev/null
+trait T0<'a, A> {
+ type O;
+}
+
+struct L<T> {
+ f: T,
+}
+
+// explicitly named variants of what one would normally denote by the
+// unit type `()`. Why do this? So that we can differentiate them in
+// the diagnostic output.
+struct Unit1;
+struct Unit2;
+struct Unit3;
+struct Unit4;
+
+impl<'a, A, T> T0<'a, A> for L<T>
+where
+ T: FnMut(A) -> Unit3,
+{
+ type O = T::Output;
+}
+
+trait T1: for<'r> Ty<'r> {
+ fn m<'a, B: Ty<'a>, F>(&self, f: F) -> Unit1
+ where
+ F: for<'r> T0<'r, (<Self as Ty<'r>>::V,), O = <B as Ty<'r>>::V>,
+ {
+ unimplemented!();
+ }
+}
+
+trait Ty<'a> {
+ type V;
+}
+
+fn main() {
+ let v = Unit2.m(
+ L {
+ //~^ ERROR to be a closure that returns `Unit3`, but it returns `Unit4`
+ //~| ERROR type mismatch
+ f: |x| {
+ drop(x);
+ Unit4
+ },
+ },
+ );
+}
+
+impl<'a> Ty<'a> for Unit2 {
+ type V = &'a u8;
+}
+
+impl T1 for Unit2 {}
--- /dev/null
+error[E0271]: type mismatch resolving `for<'r> <L<[closure@$DIR/issue-62203-hrtb-ice.rs:42:16: 42:19]> as T0<'r, (&'r u8,)>>::O == <_ as Ty<'r>>::V`
+ --> $DIR/issue-62203-hrtb-ice.rs:39:9
+ |
+LL | let v = Unit2.m(
+ | - required by a bound introduced by this call
+LL | / L {
+LL | |
+LL | |
+LL | | f: |x| {
+... |
+LL | | },
+LL | | },
+ | |_________^ type mismatch resolving `for<'r> <L<[closure@$DIR/issue-62203-hrtb-ice.rs:42:16: 42:19]> as T0<'r, (&'r u8,)>>::O == <_ as Ty<'r>>::V`
+ |
+note: expected this to be `<_ as Ty<'_>>::V`
+ --> $DIR/issue-62203-hrtb-ice.rs:21:14
+ |
+LL | type O = T::Output;
+ | ^^^^^^^^^
+ = note: expected associated type `<_ as Ty<'_>>::V`
+ found struct `Unit4`
+ = help: consider constraining the associated type `<_ as Ty<'_>>::V` to `Unit4` or calling a method that returns `<_ as Ty<'_>>::V`
+ = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
+note: required by a bound in `T1::m`
+ --> $DIR/issue-62203-hrtb-ice.rs:27:51
+ |
+LL | fn m<'a, B: Ty<'a>, F>(&self, f: F) -> Unit1
+ | - required by a bound in this
+LL | where
+LL | F: for<'r> T0<'r, (<Self as Ty<'r>>::V,), O = <B as Ty<'r>>::V>,
+ | ^^^^^^^^^^^^^^^^^^^^ required by this bound in `T1::m`
+
+error[E0271]: expected `[closure@$DIR/issue-62203-hrtb-ice.rs:42:16: 42:19]` to be a closure that returns `Unit3`, but it returns `Unit4`
+ --> $DIR/issue-62203-hrtb-ice.rs:39:9
+ |
+LL | let v = Unit2.m(
+ | - required by a bound introduced by this call
+LL | / L {
+LL | |
+LL | |
+LL | | f: |x| {
+... |
+LL | | },
+LL | | },
+ | |_________^ expected struct `Unit3`, found struct `Unit4`
+ |
+note: required because of the requirements on the impl of `for<'r> T0<'r, (&'r u8,)>` for `L<[closure@$DIR/issue-62203-hrtb-ice.rs:42:16: 42:19]>`
+ --> $DIR/issue-62203-hrtb-ice.rs:17:16
+ |
+LL | impl<'a, A, T> T0<'a, A> for L<T>
+ | ^^^^^^^^^ ^^^^
+note: required by a bound in `T1::m`
+ --> $DIR/issue-62203-hrtb-ice.rs:27:12
+ |
+LL | fn m<'a, B: Ty<'a>, F>(&self, f: F) -> Unit1
+ | - required by a bound in this
+LL | where
+LL | F: for<'r> T0<'r, (<Self as Ty<'r>>::V,), O = <B as Ty<'r>>::V>,
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `T1::m`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0271`.
--- /dev/null
+// check-pass
+
+trait Yokeable<'a> {
+ type Output: 'a;
+}
+impl<'a> Yokeable<'a> for () {
+ type Output = ();
+}
+
+trait DataMarker<'data> {
+ type Yokeable: for<'a> Yokeable<'a>;
+}
+impl<'data> DataMarker<'data> for () {
+ type Yokeable = ();
+}
+
+struct DataPayload<'data, M>(&'data M);
+
+impl DataPayload<'static, ()> {
+ pub fn map_project_with_capture<M2, T>(
+ _: for<'a> fn(
+ capture: T,
+ std::marker::PhantomData<&'a ()>,
+ ) -> <M2::Yokeable as Yokeable<'a>>::Output,
+ ) -> DataPayload<'static, M2>
+ where
+ M2: DataMarker<'static>,
+ {
+ todo!()
+ }
+}
+
+fn main() {
+ let _: DataPayload<()> = DataPayload::<()>::map_project_with_capture::<_, &()>(|_, _| todo!());
+}
--- /dev/null
+// check-pass
+
+trait Base<'f> {
+ type Assoc;
+
+ fn do_something(&self);
+}
+
+trait ForAnyLifetime: for<'f> Base<'f> {}
+
+impl<T> ForAnyLifetime for T where T: for<'f> Base<'f> {}
+
+trait CanBeDynamic: ForAnyLifetime + for<'f> Base<'f, Assoc = ()> {}
+
+fn foo(a: &dyn CanBeDynamic) {
+ a.do_something();
+}
+
+struct S;
+
+impl<'a> Base<'a> for S {
+ type Assoc = ();
+
+ fn do_something(&self) {}
+}
+
+impl CanBeDynamic for S {}
+
+fn main() {
+ let s = S;
+ foo(&s);
+}
--- /dev/null
+// known-bug: #95034
+// failure-status: 101
+// compile-flags: --edition=2021 --crate-type=lib
+// rustc-env:RUST_BACKTRACE=0
+
+// normalize-stderr-test "thread 'rustc' panicked.*" -> "thread 'rustc' panicked"
+// normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> ""
+// normalize-stderr-test "\nerror: internal compiler error.*\n\n" -> ""
+// normalize-stderr-test "note:.*unexpectedly panicked.*\n\n" -> ""
+// normalize-stderr-test "note: we would appreciate a bug report.*\n\n" -> ""
+// normalize-stderr-test "note: compiler flags.*\n\n" -> ""
+// normalize-stderr-test "note: rustc.*running on.*\n\n" -> ""
+// normalize-stderr-test "query stack during panic:\n" -> ""
+// normalize-stderr-test "we're just showing a limited slice of the query stack\n" -> ""
+// normalize-stderr-test "end of query stack\n" -> ""
+// normalize-stderr-test "#.*\n" -> ""
+
+// This should not ICE.
+
+// Refer to the issue for more minimized versions.
+
+use std::{
+ future::Future,
+ marker::PhantomData,
+ pin::Pin,
+ task::{Context, Poll},
+};
+
+mod object {
+ use super::*;
+
+ pub trait Object<'a> {
+ type Error;
+ type Future: Future<Output = Self>;
+ fn create() -> Self::Future;
+ }
+
+ impl<'a> Object<'a> for u8 {
+ type Error = ();
+ type Future = Pin<Box<dyn Future<Output = Self>>>;
+ fn create() -> Self::Future {
+ unimplemented!()
+ }
+ }
+
+ impl<'a, E, A: Object<'a, Error = E>> Object<'a> for (A,) {
+ type Error = ();
+ type Future = CustomFut<'a, E, A>;
+ fn create() -> Self::Future {
+ unimplemented!()
+ }
+ }
+
+ pub struct CustomFut<'f, E, A: Object<'f, Error = E>> {
+ ph: PhantomData<(A::Future,)>,
+ }
+
+ impl<'f, E, A: Object<'f, Error = E>> Future for CustomFut<'f, E, A> {
+ type Output = (A,);
+ fn poll(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Self::Output> {
+ unimplemented!()
+ }
+ }
+}
+
+mod async_fn {
+ use super::*;
+
+ pub trait AsyncFn {
+ type Future: Future<Output = ()>;
+ fn call(&self) -> Self::Future;
+ }
+
+ impl<F, Fut> AsyncFn for F
+ where
+ F: Fn() -> Fut,
+ Fut: Future<Output = ()>,
+ {
+ type Future = Fut;
+ fn call(&self) -> Self::Future {
+ (self)()
+ }
+ }
+}
+
+pub async fn test() {
+ use self::{async_fn::AsyncFn, object::Object};
+
+ async fn create<T: Object<'static>>() {
+ T::create().await;
+ }
+
+ async fn call_async_fn(inner: impl AsyncFn) {
+ inner.call().await;
+ }
+
+ call_async_fn(create::<(u8,)>).await;
+}
--- /dev/null
+thread 'rustc' panicked
--- /dev/null
+// check-pass
+
+pub struct Bar
+where
+ for<'a> &'a mut Self:;
+
+fn main() {}
+++ /dev/null
-// check-pass
-
-trait A<'a> {}
-trait B<'b> {}
-fn foo<T>() where for<'a> T: A<'a> + 'a {}
-trait C<'c>: for<'a> A<'a> + for<'b> B<'b> {
- type As;
-}
-struct D<T> where T: for<'c> C<'c, As=&'c ()> {
- t: std::marker::PhantomData<T>,
-}
-trait E<'e, 'g> {
- type As;
-}
-trait F<'f>: for<'a> A<'a> + for<'e> E<'e, 'f> {}
-struct G<T> where T: for<'f> F<'f, As=&'f ()> {
- t: std::marker::PhantomData<T>,
-}
-trait H<'a, 'b> {
- type As;
-}
-trait I<'a>: for<'b> H<'a, 'b> {}
-
-struct J<T> where T: for<'i> I<'i, As=&'i ()> {
- t: std::marker::PhantomData<T>,
-}
-
-fn main() {}
+++ /dev/null
-fn main() {
- test::<FooS>(&mut 42); //~ ERROR implementation of `Foo` is not general enough
-}
-
-trait Foo<'a> {}
-
-struct FooS<'a> {
- data: &'a mut u32,
-}
-
-impl<'a, 'b: 'a> Foo<'b> for FooS<'a> {}
-
-fn test<'a, F>(data: &'a mut u32) where F: for<'b> Foo<'b> {}
+++ /dev/null
-error: implementation of `Foo` is not general enough
- --> $DIR/due-to-where-clause.rs:2:5
- |
-LL | test::<FooS>(&mut 42);
- | ^^^^^^^^^^^^ implementation of `Foo` is not general enough
- |
- = note: `FooS<'_>` must implement `Foo<'0>`, for any lifetime `'0`...
- = note: ...but `FooS<'_>` actually implements `Foo<'1>`, for some specific lifetime `'1`
-
-error: aborting due to previous error
-
+++ /dev/null
-// Regression test for #54302.
-//
-// We were incorrectly using the "evaluation cache" (which ignored
-// region results) to conclude that `&'static str: Deserialize`, even
-// though it would require that `for<'de> 'de: 'static`, which is
-// clearly false.
-
-trait Deserialize<'de> {}
-
-trait DeserializeOwned: for<'de> Deserialize<'de> {}
-impl<T> DeserializeOwned for T where T: for<'de> Deserialize<'de> {}
-
-// Based on this impl, `&'static str` only implements Deserialize<'static>.
-// It does not implement for<'de> Deserialize<'de>.
-impl<'de: 'a, 'a> Deserialize<'de> for &'a str {}
-
-fn main() {
- fn assert_deserialize_owned<T: DeserializeOwned>() {}
- assert_deserialize_owned::<&'static str>(); //~ ERROR
-
- // It correctly does not implement for<'de> Deserialize<'de>.
- // fn assert_hrtb<T: for<'de> Deserialize<'de>>() {}
- // assert_hrtb::<&'static str>();
-}
+++ /dev/null
-error: implementation of `Deserialize` is not general enough
- --> $DIR/hrtb-cache-issue-54302.rs:19:5
- |
-LL | assert_deserialize_owned::<&'static str>();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Deserialize` is not general enough
- |
- = note: `&'static str` must implement `Deserialize<'0>`, for any lifetime `'0`...
- = note: ...but `&str` actually implements `Deserialize<'1>`, for some specific lifetime `'1`
-
-error: aborting due to previous error
-
+++ /dev/null
-// Test that an impl with only one bound region `'a` cannot be used to
-// satisfy a constraint where there are two bound regions.
-
-trait Foo<X> {
- fn foo(&self, x: X) { }
-}
-
-fn want_foo2<T>()
- where T : for<'a,'b> Foo<(&'a isize, &'b isize)>
-{
-}
-
-fn want_foo1<T>()
- where T : for<'z> Foo<(&'z isize, &'z isize)>
-{
-}
-
-// Expressed as a where clause
-
-struct SomeStruct;
-
-impl<'a> Foo<(&'a isize, &'a isize)> for SomeStruct
-{
-}
-
-fn a() { want_foo1::<SomeStruct>(); } // OK -- foo wants just one region
-fn b() { want_foo2::<SomeStruct>(); }
-//~^ ERROR implementation of
-//~| ERROR implementation of
-
-fn main() { }
+++ /dev/null
-error: implementation of `Foo` is not general enough
- --> $DIR/hrtb-conflate-regions.rs:27:10
- |
-LL | fn b() { want_foo2::<SomeStruct>(); }
- | ^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
- |
- = note: `SomeStruct` must implement `Foo<(&'0 isize, &'1 isize)>`, for any two lifetimes `'0` and `'1`...
- = note: ...but it actually implements `Foo<(&'2 isize, &'2 isize)>`, for some specific lifetime `'2`
-
-error: implementation of `Foo` is not general enough
- --> $DIR/hrtb-conflate-regions.rs:27:10
- |
-LL | fn b() { want_foo2::<SomeStruct>(); }
- | ^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
- |
- = note: `SomeStruct` must implement `Foo<(&'0 isize, &'1 isize)>`, for any two lifetimes `'0` and `'1`...
- = note: ...but it actually implements `Foo<(&'2 isize, &'2 isize)>`, for some specific lifetime `'2`
-
-error: aborting due to 2 previous errors
-
+++ /dev/null
-// Test the case where the `Self` type has a bound lifetime that must
-// be adjusted in the fn signature. Issue #19537.
-
-use std::collections::HashMap;
-
-struct Foo<'a> {
- map: HashMap<usize, &'a str>
-}
-
-impl<'a> Foo<'a> {
- fn new() -> Foo<'a> { panic!() }
- fn insert(&'a mut self) { }
-}
-fn main() {
- let mut foo = Foo::new();
- foo.insert();
- foo.insert(); //~ ERROR cannot borrow
-}
+++ /dev/null
-error[E0499]: cannot borrow `foo` as mutable more than once at a time
- --> $DIR/hrtb-debruijn-in-receiver.rs:17:5
- |
-LL | foo.insert();
- | ------------ first mutable borrow occurs here
-LL | foo.insert();
- | ^^^^^^^^^^^^
- | |
- | second mutable borrow occurs here
- | first borrow later used here
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0499`.
+++ /dev/null
-// Test an `exists<'a> { forall<'b> { 'a = 'b } }` pattern -- which should not compile!
-//
-// In particular, we test this pattern in trait solving, where it is not connected
-// to any part of the source code.
-
-fn foo<'a>() -> fn(&'a u32) {
- panic!()
-}
-
-fn main() {
- // Here, proving that `fn(&'a u32) <: for<'b> fn(&'b u32)`:
- //
- // - instantiates `'b` with a placeholder `!b`,
- // - requires that `&!b u32 <: &'a u32` and hence that `!b: 'a`,
- // - but we can never know this.
-
- let _: for<'b> fn(&'b u32) = foo(); //~ ERROR mismatched types
-}
+++ /dev/null
-error[E0308]: mismatched types
- --> $DIR/hrtb-exists-forall-fn.rs:17:34
- |
-LL | let _: for<'b> fn(&'b u32) = foo();
- | ^^^^^ one type is more general than the other
- |
- = note: expected fn pointer `for<'b> fn(&'b u32)`
- found fn pointer `fn(&u32)`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0308`.
+++ /dev/null
-// Test a case where variance and higher-ranked types interact in surprising ways.
-//
-// In particular, we test this pattern in trait solving, where it is not connected
-// to any part of the source code.
-
-trait Trait<T> {}
-
-fn foo<T>()
-where
- T: Trait<for<'b> fn(&'b u32)>,
-{
-}
-
-impl<'a> Trait<fn(&'a u32)> for () {}
-
-fn main() {
- // Here, proving that `(): Trait<for<'b> fn(&'b u32)>` uses the impl:
- //
- // - The impl provides the clause `forall<'a> { (): Trait<fn(&'a u32)> }`
- // - We instantiate `'a` existentially to get `(): Trait<fn(&?a u32)>`
- // - We unify `fn(&?a u32)` with `for<'b> fn(&'b u32)` -- this does a
- // "bidirectional" subtyping check, so we wind up with:
- // - `fn(&?a u32) <: for<'b> fn(&'b u32)` :-
- // - `&'!b u32 <: &?a u32`
- // - `!'b: ?a` -- solveable if `?a` is inferred to `'empty`
- // - `for<'b> fn(&'b u32) <: fn(&?a u32)` :-
- // - `&?a u32 u32 <: &?b u32`
- // - `?a: ?b` -- solveable if `?b` is also inferred to `'empty`
- // - So the subtyping check succeeds, somewhat surprisingly.
- // This is because we can use `'empty`.
- //
- // NB. *However*, the reinstated leak-check gives an error here.
-
- foo::<()>();
- //~^ ERROR implementation of `Trait` is not general enough
-}
+++ /dev/null
-error: implementation of `Trait` is not general enough
- --> $DIR/hrtb-exists-forall-trait-contravariant.rs:34:5
- |
-LL | foo::<()>();
- | ^^^^^^^^^^^ implementation of `Trait` is not general enough
- |
- = note: `()` must implement `Trait<for<'b> fn(&'b u32)>`
- = note: ...but it actually implements `Trait<fn(&'0 u32)>`, for some specific lifetime `'0`
-
-error: aborting due to previous error
-
+++ /dev/null
-// Test a case where variance and higher-ranked types interact in surprising ways.
-//
-// In particular, we test this pattern in trait solving, where it is not connected
-// to any part of the source code.
-//
-// check-pass
-
-trait Trait<T> {}
-
-fn foo<T>()
-where
- T: Trait<for<'b> fn(fn(&'b u32))>,
-{
-}
-
-impl<'a> Trait<fn(fn(&'a u32))> for () {}
-
-fn main() {
- // Here, proving that `(): Trait<for<'b> fn(&'b u32)>` uses the impl:
- //
- // - The impl provides the clause `forall<'a> { (): Trait<fn(fn(&'a u32))> }`
- // - We instantiate `'a` existentially to get `(): Trait<fn(fn(&?a u32))>`
- // - We unify `fn(fn(&?a u32))` with `for<'b> fn(fn(&'b u32))` -- this does a
- // "bidirectional" subtyping check, so we wind up with:
- // - `fn(fn(&?a u32)) <: for<'b> fn(fn(&'b u32))` :-
- // - `fn(&!b u32) <: fn(&?a u32)`
- // - `&?a u32 <: &!b u32`
- // - `?a: !'b` -- solveable if `?a` is inferred to `'static`
- // - `for<'b> fn(fn(&'b u32)) <: fn(fn(&?a u32))` :-
- // - `fn(&?a u32) <: fn(&?b u32)`
- // - `&?b u32 <: &?a u32`
- // - `?b: ?a` -- solveable if `?b` is inferred to `'static`
- // - So the subtyping check succeeds, somewhat surprisingly.
- // This is because we can use `'static`.
-
- foo::<()>();
-}
+++ /dev/null
-// Test an `exists<'a> { forall<'b> { 'a = 'b } }` pattern -- which should not compile!
-//
-// In particular, we test this pattern in trait solving, where it is not connected
-// to any part of the source code.
-
-use std::cell::Cell;
-
-trait Trait<T> {}
-
-fn foo<T>()
-where
- T: Trait<for<'b> fn(Cell<&'b u32>)>,
-{
-}
-
-impl<'a> Trait<fn(Cell<&'a u32>)> for () {}
-
-fn main() {
- // Here, proving that `(): Trait<for<'b> fn(&'b u32)>` uses the impl:
- //
- // - The impl provides the clause `forall<'a> { (): Trait<fn(&'a u32)> }`
- // - We instantiate `'a` existentially to get `(): Trait<fn(&?a u32)>`
- // - We unify `fn(&?a u32)` with `for<'b> fn(&'b u32)`
- // - This requires (among other things) instantiating `'b` universally,
- // yielding `fn(&!b u32)`, in a fresh universe U1
- // - So we get `?a = !b` but the universe U0 assigned to `?a` cannot name `!b`.
-
- foo::<()>(); //~ ERROR implementation of `Trait` is not general enough
-}
+++ /dev/null
-error: implementation of `Trait` is not general enough
- --> $DIR/hrtb-exists-forall-trait-invariant.rs:28:5
- |
-LL | foo::<()>();
- | ^^^^^^^^^^^ implementation of `Trait` is not general enough
- |
- = note: `()` must implement `Trait<for<'b> fn(Cell<&'b u32>)>`
- = note: ...but it actually implements `Trait<fn(Cell<&'0 u32>)>`, for some specific lifetime `'0`
-
-error: aborting due to previous error
-
+++ /dev/null
-// Test HRTB supertraits with several levels of expansion required.
-
-trait Foo<'tcx>
-{
- fn foo(&'tcx self) -> &'tcx isize;
-}
-
-trait Bar<'ccx>
- : for<'tcx> Foo<'tcx>
-{
- fn bar(&'ccx self) -> &'ccx isize;
-}
-
-trait Baz
- : for<'ccx> Bar<'ccx>
-{
- fn dummy(&self);
-}
-
-trait Qux
- : Bar<'static>
-{
- fn dummy(&self);
-}
-
-fn want_foo_for_any_tcx<F>(f: &F)
- where F : for<'tcx> Foo<'tcx>
-{
-}
-
-fn want_bar_for_any_ccx<B>(b: &B)
- where B : for<'ccx> Bar<'ccx>
-{
-}
-
-fn want_baz<B>(b: &B)
- where B : Baz
-{
- want_foo_for_any_tcx(b);
- want_bar_for_any_ccx(b);
-}
-
-fn want_qux<B>(b: &B)
- where B : Qux
-{
- want_foo_for_any_tcx(b);
- want_bar_for_any_ccx(b); //~ ERROR
-}
-
-fn main() {}
+++ /dev/null
-error[E0277]: the trait bound `for<'ccx> B: Bar<'ccx>` is not satisfied
- --> $DIR/hrtb-higher-ranker-supertraits-transitive.rs:47:26
- |
-LL | want_bar_for_any_ccx(b);
- | -------------------- ^ the trait `for<'ccx> Bar<'ccx>` is not implemented for `B`
- | |
- | required by a bound introduced by this call
- |
-note: required by a bound in `want_bar_for_any_ccx`
- --> $DIR/hrtb-higher-ranker-supertraits-transitive.rs:32:15
- |
-LL | fn want_bar_for_any_ccx<B>(b: &B)
- | -------------------- required by a bound in this
-LL | where B : for<'ccx> Bar<'ccx>
- | ^^^^^^^^^^^^^^^^^^^ required by this bound in `want_bar_for_any_ccx`
-help: consider further restricting this bound
- |
-LL | where B : Qux + for<'ccx> Bar<'ccx>
- | +++++++++++++++++++++
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0277`.
+++ /dev/null
-// Test a trait (`Bar`) with a higher-ranked supertrait.
-
-trait Foo<'tcx>
-{
- fn foo(&'tcx self) -> &'tcx isize;
-}
-
-trait Bar<'ccx>
- : for<'tcx> Foo<'tcx>
-{
- fn bar(&'ccx self) -> &'ccx isize;
-}
-
-fn want_foo_for_some_tcx<'x,F>(f: &'x F)
- where F : Foo<'x>
-{
- want_foo_for_some_tcx(f);
- want_foo_for_any_tcx(f); //~ ERROR not satisfied
-}
-
-fn want_foo_for_any_tcx<F>(f: &F)
- where F : for<'tcx> Foo<'tcx>
-{
- want_foo_for_some_tcx(f);
- want_foo_for_any_tcx(f);
-}
-
-fn want_bar_for_some_ccx<'x,B>(b: &B)
- where B : Bar<'x>
-{
- want_foo_for_some_tcx(b);
- want_foo_for_any_tcx(b);
-
- want_bar_for_some_ccx(b);
- want_bar_for_any_ccx(b); //~ ERROR not satisfied
-}
-
-fn want_bar_for_any_ccx<B>(b: &B)
- where B : for<'ccx> Bar<'ccx>
-{
- want_foo_for_some_tcx(b);
- want_foo_for_any_tcx(b);
-
- want_bar_for_some_ccx(b);
- want_bar_for_any_ccx(b);
-}
-
-fn main() {}
+++ /dev/null
-error[E0277]: the trait bound `for<'tcx> F: Foo<'tcx>` is not satisfied
- --> $DIR/hrtb-higher-ranker-supertraits.rs:18:26
- |
-LL | want_foo_for_any_tcx(f);
- | -------------------- ^ the trait `for<'tcx> Foo<'tcx>` is not implemented for `F`
- | |
- | required by a bound introduced by this call
- |
-note: required by a bound in `want_foo_for_any_tcx`
- --> $DIR/hrtb-higher-ranker-supertraits.rs:22:15
- |
-LL | fn want_foo_for_any_tcx<F>(f: &F)
- | -------------------- required by a bound in this
-LL | where F : for<'tcx> Foo<'tcx>
- | ^^^^^^^^^^^^^^^^^^^ required by this bound in `want_foo_for_any_tcx`
-help: consider further restricting this bound
- |
-LL | where F : Foo<'x> + for<'tcx> Foo<'tcx>
- | +++++++++++++++++++++
-
-error[E0277]: the trait bound `for<'ccx> B: Bar<'ccx>` is not satisfied
- --> $DIR/hrtb-higher-ranker-supertraits.rs:35:26
- |
-LL | want_bar_for_any_ccx(b);
- | -------------------- ^ the trait `for<'ccx> Bar<'ccx>` is not implemented for `B`
- | |
- | required by a bound introduced by this call
- |
-note: required by a bound in `want_bar_for_any_ccx`
- --> $DIR/hrtb-higher-ranker-supertraits.rs:39:15
- |
-LL | fn want_bar_for_any_ccx<B>(b: &B)
- | -------------------- required by a bound in this
-LL | where B : for<'ccx> Bar<'ccx>
- | ^^^^^^^^^^^^^^^^^^^ required by this bound in `want_bar_for_any_ccx`
-help: consider further restricting this bound
- |
-LL | where B : Bar<'x> + for<'ccx> Bar<'ccx>
- | +++++++++++++++++++++
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0277`.
+++ /dev/null
-// Test that the `'a` in the where clause correctly links the region
-// of the output to the region of the input.
-
-trait FnLike<A,R> {
- fn call(&self, arg: A) -> R;
-}
-
-fn call_repeatedly<F>(f: F)
- where F : for<'a> FnLike<&'a isize, &'a isize>
-{
- // Result is stored: cannot re-assign `x`
- let mut x = 3;
- let y = f.call(&x);
- x = 5; //~ ERROR cannot assign to `x` because it is borrowed
-
- // Result is not stored: can re-assign `x`
- let mut x = 3;
- f.call(&x);
- f.call(&x);
- f.call(&x);
- x = 5;
- drop(y);
-}
-
-fn main() {
-}
+++ /dev/null
-error[E0506]: cannot assign to `x` because it is borrowed
- --> $DIR/hrtb-identity-fn-borrows.rs:14:5
- |
-LL | let y = f.call(&x);
- | -- borrow of `x` occurs here
-LL | x = 5;
- | ^^^^^ assignment to borrowed `x` occurs here
-...
-LL | drop(y);
- | - borrow later used here
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0506`.
+++ /dev/null
-// Test a case where you have an impl of `Foo<X>` for all `X` that
-// is being applied to `for<'a> Foo<&'a mut X>`. Issue #19730.
-
-trait Foo<X> {
- fn foo(&self, x: X) { }
-}
-
-fn want_hrtb<T>()
- where T : for<'a> Foo<&'a isize>
-{
-}
-
-// AnyInt implements Foo<&'a isize> for any 'a, so it is a match.
-struct AnyInt;
-impl<'a> Foo<&'a isize> for AnyInt { }
-fn give_any() {
- want_hrtb::<AnyInt>()
-}
-
-// StaticInt only implements Foo<&'static isize>, so it is an error.
-struct StaticInt;
-impl Foo<&'static isize> for StaticInt { }
-fn give_static() {
- want_hrtb::<StaticInt>() //~ ERROR
-}
-
-// &'a u32 only implements Foo<&'a isize> for specific 'a, so it is an error.
-impl<'a> Foo<&'a isize> for &'a u32 { }
-fn give_some<'a>() {
- want_hrtb::<&'a u32>()
- //~^ ERROR lifetime may not live long enough
- //~| ERROR implementation of `Foo` is not general enough
-}
-
-fn main() { }
+++ /dev/null
-error: implementation of `Foo` is not general enough
- --> $DIR/hrtb-just-for-static.rs:24:5
- |
-LL | want_hrtb::<StaticInt>()
- | ^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
- |
- = note: `StaticInt` must implement `Foo<&'0 isize>`, for any lifetime `'0`...
- = note: ...but it actually implements `Foo<&'static isize>`
-
-error: lifetime may not live long enough
- --> $DIR/hrtb-just-for-static.rs:30:5
- |
-LL | fn give_some<'a>() {
- | -- lifetime `'a` defined here
-LL | want_hrtb::<&'a u32>()
- | ^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
-
-error: implementation of `Foo` is not general enough
- --> $DIR/hrtb-just-for-static.rs:30:5
- |
-LL | want_hrtb::<&'a u32>()
- | ^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
- |
- = note: `Foo<&'0 isize>` would have to be implemented for the type `&u32`, for any lifetime `'0`...
- = note: ...but `Foo<&'1 isize>` is actually implemented for the type `&'1 u32`, for some specific lifetime `'1`
-
-error: aborting due to 3 previous errors
-
+++ /dev/null
-warning: function cannot return without recursing
- --> $DIR/hrtb-perfect-forwarding.rs:16:1
- |
-LL | / fn no_hrtb<'b, T>(mut t: T)
-LL | | where
-LL | | T: Bar<&'b isize>,
-LL | | {
-... |
-LL | | no_hrtb(&mut t);
- | | --------------- recursive call site
-LL | | }
- | |_^ cannot return without recursing
- |
- = note: `#[warn(unconditional_recursion)]` on by default
- = help: a `loop` may express intention better if this is on purpose
-
-warning: function cannot return without recursing
- --> $DIR/hrtb-perfect-forwarding.rs:25:1
- |
-LL | / fn bar_hrtb<T>(mut t: T)
-LL | | where
-LL | | T: for<'b> Bar<&'b isize>,
-LL | | {
-... |
-LL | | bar_hrtb(&mut t);
- | | ---------------- recursive call site
-LL | | }
- | |_^ cannot return without recursing
- |
- = help: a `loop` may express intention better if this is on purpose
-
-warning: function cannot return without recursing
- --> $DIR/hrtb-perfect-forwarding.rs:35:1
- |
-LL | / fn foo_hrtb_bar_not<'b, T>(mut t: T)
-LL | | where
-LL | | T: for<'a> Foo<&'a isize> + Bar<&'b isize>,
-LL | | {
-... |
-LL | | foo_hrtb_bar_not(&mut t);
- | | ------------------------ recursive call site
-LL | |
-LL | |
-LL | | }
- | |_^ cannot return without recursing
- |
- = help: a `loop` may express intention better if this is on purpose
-
-error: higher-ranked subtype error
- --> $DIR/hrtb-perfect-forwarding.rs:43:5
- |
-LL | foo_hrtb_bar_not(&mut t);
- | ^^^^^^^^^^^^^^^^^^^^^^^^
-
-warning: function cannot return without recursing
- --> $DIR/hrtb-perfect-forwarding.rs:48:1
- |
-LL | / fn foo_hrtb_bar_hrtb<T>(mut t: T)
-LL | | where
-LL | | T: for<'a> Foo<&'a isize> + for<'b> Bar<&'b isize>,
-LL | | {
-LL | | // OK -- now we have `T : for<'b> Bar<&'b isize>`.
-LL | | foo_hrtb_bar_hrtb(&mut t);
- | | ------------------------- recursive call site
-LL | | }
- | |_^ cannot return without recursing
- |
- = help: a `loop` may express intention better if this is on purpose
-
-error: aborting due to previous error; 4 warnings emitted
-
+++ /dev/null
-// Test a case where you have an impl of `Foo<X>` for all `X` that
-// is being applied to `for<'a> Foo<&'a mut X>`. Issue #19730.
-
-trait Foo<X> {
- fn foo(&mut self, x: X) {}
-}
-
-trait Bar<X> {
- fn bar(&mut self, x: X) {}
-}
-
-impl<'a, X, F> Foo<X> for &'a mut F where F: Foo<X> + Bar<X> {}
-
-impl<'a, X, F> Bar<X> for &'a mut F where F: Bar<X> {}
-
-fn no_hrtb<'b, T>(mut t: T) //~ WARN function cannot return
-where
- T: Bar<&'b isize>,
-{
- // OK -- `T : Bar<&'b isize>`, and thus the impl above ensures that
- // `&mut T : Bar<&'b isize>`.
- no_hrtb(&mut t);
-}
-
-fn bar_hrtb<T>(mut t: T) //~ WARN function cannot return
-where
- T: for<'b> Bar<&'b isize>,
-{
- // OK -- `T : for<'b> Bar<&'b isize>`, and thus the impl above
- // ensures that `&mut T : for<'b> Bar<&'b isize>`. This is an
- // example of a "perfect forwarding" impl.
- bar_hrtb(&mut t);
-}
-
-fn foo_hrtb_bar_not<'b, T>(mut t: T) //~ WARN function cannot return
-where
- T: for<'a> Foo<&'a isize> + Bar<&'b isize>,
-{
- // Not OK -- The forwarding impl for `Foo` requires that `Bar` also
- // be implemented. Thus to satisfy `&mut T : for<'a> Foo<&'a
- // isize>`, we require `T : for<'a> Bar<&'a isize>`, but the where
- // clause only specifies `T : Bar<&'b isize>`.
- foo_hrtb_bar_not(&mut t);
- //~^ ERROR implementation of `Bar` is not general enough
- //~^^ ERROR lifetime may not live long enough
-}
-
-fn foo_hrtb_bar_hrtb<T>(mut t: T) //~ WARN function cannot return
-where
- T: for<'a> Foo<&'a isize> + for<'b> Bar<&'b isize>,
-{
- // OK -- now we have `T : for<'b> Bar<&'b isize>`.
- foo_hrtb_bar_hrtb(&mut t);
-}
-
-fn main() {}
+++ /dev/null
-warning: function cannot return without recursing
- --> $DIR/hrtb-perfect-forwarding.rs:16:1
- |
-LL | / fn no_hrtb<'b, T>(mut t: T)
-LL | | where
-LL | | T: Bar<&'b isize>,
- | |______________________^ cannot return without recursing
-...
-LL | no_hrtb(&mut t);
- | --------------- recursive call site
- |
- = note: `#[warn(unconditional_recursion)]` on by default
- = help: a `loop` may express intention better if this is on purpose
-
-warning: function cannot return without recursing
- --> $DIR/hrtb-perfect-forwarding.rs:25:1
- |
-LL | / fn bar_hrtb<T>(mut t: T)
-LL | | where
-LL | | T: for<'b> Bar<&'b isize>,
- | |______________________________^ cannot return without recursing
-...
-LL | bar_hrtb(&mut t);
- | ---------------- recursive call site
- |
- = help: a `loop` may express intention better if this is on purpose
-
-warning: function cannot return without recursing
- --> $DIR/hrtb-perfect-forwarding.rs:35:1
- |
-LL | / fn foo_hrtb_bar_not<'b, T>(mut t: T)
-LL | | where
-LL | | T: for<'a> Foo<&'a isize> + Bar<&'b isize>,
- | |_______________________________________________^ cannot return without recursing
-...
-LL | foo_hrtb_bar_not(&mut t);
- | ------------------------ recursive call site
- |
- = help: a `loop` may express intention better if this is on purpose
-
-error: lifetime may not live long enough
- --> $DIR/hrtb-perfect-forwarding.rs:43:5
- |
-LL | fn foo_hrtb_bar_not<'b, T>(mut t: T)
- | -- lifetime `'b` defined here
-...
-LL | foo_hrtb_bar_not(&mut t);
- | ^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'b` must outlive `'static`
-
-error: implementation of `Bar` is not general enough
- --> $DIR/hrtb-perfect-forwarding.rs:43:5
- |
-LL | foo_hrtb_bar_not(&mut t);
- | ^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Bar` is not general enough
- |
- = note: `T` must implement `Bar<&'0 isize>`, for any lifetime `'0`...
- = note: ...but it actually implements `Bar<&'1 isize>`, for some specific lifetime `'1`
-
-warning: function cannot return without recursing
- --> $DIR/hrtb-perfect-forwarding.rs:48:1
- |
-LL | / fn foo_hrtb_bar_hrtb<T>(mut t: T)
-LL | | where
-LL | | T: for<'a> Foo<&'a isize> + for<'b> Bar<&'b isize>,
- | |_______________________________________________________^ cannot return without recursing
-...
-LL | foo_hrtb_bar_hrtb(&mut t);
- | ------------------------- recursive call site
- |
- = help: a `loop` may express intention better if this is on purpose
-
-error: aborting due to 2 previous errors; 4 warnings emitted
-
+++ /dev/null
-// rust-lang/rust#30786: the use of `for<'b> &'b mut A: Stream<Item=T`
-// should act as assertion that item does not borrow from its stream;
-// but an earlier buggy rustc allowed `.map(|x: &_| x)` which does
-// have such an item.
-//
-// This tests double-checks that we do not allow such behavior to leak
-// through again.
-
-pub trait Stream {
- type Item;
- fn next(self) -> Option<Self::Item>;
-}
-
-// Example stream
-pub struct Repeat(u64);
-
-impl<'a> Stream for &'a mut Repeat {
- type Item = &'a u64;
- fn next(self) -> Option<Self::Item> {
- Some(&self.0)
- }
-}
-
-pub struct Map<S, F> {
- stream: S,
- func: F,
-}
-
-impl<'a, A, F, T> Stream for &'a mut Map<A, F>
-where
- &'a mut A: Stream,
- F: FnMut(<&'a mut A as Stream>::Item) -> T,
-{
- type Item = T;
- fn next(self) -> Option<T> {
- match self.stream.next() {
- Some(item) => Some((self.func)(item)),
- None => None,
- }
- }
-}
-
-pub struct Filter<S, F> {
- stream: S,
- func: F,
-}
-
-impl<'a, A, F, T> Stream for &'a mut Filter<A, F>
-where
- for<'b> &'b mut A: Stream<Item = T>, // <---- BAD
- F: FnMut(&T) -> bool,
-{
- type Item = <&'a mut A as Stream>::Item;
- fn next(self) -> Option<Self::Item> {
- while let Some(item) = self.stream.next() {
- if (self.func)(&item) {
- return Some(item);
- }
- }
- None
- }
-}
-
-pub trait StreamExt
-where
- for<'b> &'b mut Self: Stream,
-{
- fn mapx<F>(self, func: F) -> Map<Self, F>
- where
- Self: Sized,
- for<'a> &'a mut Map<Self, F>: Stream,
- {
- Map { func: func, stream: self }
- }
-
- fn filterx<F>(self, func: F) -> Filter<Self, F>
- where
- Self: Sized,
- for<'a> &'a mut Filter<Self, F>: Stream,
- {
- Filter { func: func, stream: self }
- }
-
- fn countx(mut self) -> usize
- where
- Self: Sized,
- {
- let mut count = 0;
- while let Some(_) = self.next() {
- count += 1;
- }
- count
- }
-}
-
-impl<T> StreamExt for T where for<'a> &'a mut T: Stream {}
-
-fn identity<T>(x: &T) -> &T {
- x
-}
-
-fn variant1() {
- let source = Repeat(10);
-
- // Here, the call to `mapx` returns a type `T` to which `StreamExt`
- // is not applicable, because `for<'b> &'b mut T: Stream`) doesn't hold.
- //
- // More concretely, the type `T` is `Map<Repeat, Closure>`, and
- // the where clause doesn't hold because the signature of the
- // closure gets inferred to a signature like `|&'_ Stream| -> &'_`
- // for some specific `'_`, rather than a more generic
- // signature.
- //
- // Why *exactly* we opt for this signature is a bit unclear to me,
- // we deduce it somehow from a reuqirement that `Map: Stream` I
- // guess.
- let map = source.mapx(|x: &_| x);
- let filter = map.filterx(|x: &_| true);
- //~^ ERROR the method
-}
-
-fn variant2() {
- let source = Repeat(10);
-
- // Here, we use a function, which is not subject to the vagaries
- // of closure signature inference. In this case, we get the error
- // on `countx` as, I think, the test originally expected.
- let map = source.mapx(identity);
- let filter = map.filterx(|x: &_| true);
- let count = filter.countx();
- //~^ ERROR the method
-}
-
-fn main() {}
+++ /dev/null
-error[E0599]: the method `filterx` exists for struct `Map<Repeat, [closure@$DIR/issue-30786.rs:117:27: 117:34]>`, but its trait bounds were not satisfied
- --> $DIR/issue-30786.rs:118:22
- |
-LL | pub struct Map<S, F> {
- | --------------------
- | |
- | method `filterx` not found for this struct
- | doesn't satisfy `_: StreamExt`
-...
-LL | let filter = map.filterx(|x: &_| true);
- | ^^^^^^^ method cannot be called on `Map<Repeat, [closure@$DIR/issue-30786.rs:117:27: 117:34]>` due to unsatisfied trait bounds
- |
-note: the following trait bounds were not satisfied:
- `&'a mut &Map<Repeat, [closure@$DIR/issue-30786.rs:117:27: 117:34]>: Stream`
- `&'a mut &mut Map<Repeat, [closure@$DIR/issue-30786.rs:117:27: 117:34]>: Stream`
- `&'a mut Map<Repeat, [closure@$DIR/issue-30786.rs:117:27: 117:34]>: Stream`
- --> $DIR/issue-30786.rs:96:50
- |
-LL | impl<T> StreamExt for T where for<'a> &'a mut T: Stream {}
- | --------- - ^^^^^^ unsatisfied trait bound introduced here
-
-error[E0599]: the method `countx` exists for struct `Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:129:30: 129:37]>`, but its trait bounds were not satisfied
- --> $DIR/issue-30786.rs:130:24
- |
-LL | pub struct Filter<S, F> {
- | -----------------------
- | |
- | method `countx` not found for this struct
- | doesn't satisfy `_: StreamExt`
-...
-LL | let count = filter.countx();
- | ^^^^^^ method cannot be called on `Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:129:30: 129:37]>` due to unsatisfied trait bounds
- |
-note: the following trait bounds were not satisfied:
- `&'a mut &Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:129:30: 129:37]>: Stream`
- `&'a mut &mut Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:129:30: 129:37]>: Stream`
- `&'a mut Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:129:30: 129:37]>: Stream`
- --> $DIR/issue-30786.rs:96:50
- |
-LL | impl<T> StreamExt for T where for<'a> &'a mut T: Stream {}
- | --------- - ^^^^^^ unsatisfied trait bound introduced here
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0599`.
+++ /dev/null
-// Regression test for #46989:
-//
-// In the move to universes, this test started passing.
-// It is not necessarily WRONG to do so, but it was a bit
-// surprising. The reason that it passed is that when we were
-// asked to prove that
-//
-// for<'a> fn(&'a i32): Foo
-//
-// we were able to use the impl below to prove
-//
-// fn(&'empty i32): Foo
-//
-// and then we were able to prove that
-//
-// fn(&'empty i32) = for<'a> fn(&'a i32)
-//
-// This last fact is somewhat surprising, but essentially "falls out"
-// from handling variance correctly. In particular, consider the subtyping
-// relations. First:
-//
-// fn(&'empty i32) <: for<'a> fn(&'a i32)
-//
-// This holds because -- intuitively -- a fn that takes a reference but doesn't use
-// it can be given a reference with any lifetime. Similarly, the opposite direction:
-//
-// for<'a> fn(&'a i32) <: fn(&'empty i32)
-//
-// holds because 'a can be instantiated to 'empty.
-
-trait Foo {}
-
-impl<A> Foo for fn(A) {}
-
-fn assert_foo<T: Foo>() {}
-
-fn main() {
- assert_foo::<fn(&i32)>();
- //~^ ERROR implementation of `Foo` is not general enough
-}
+++ /dev/null
-error: implementation of `Foo` is not general enough
- --> $DIR/issue-46989.rs:38:5
- |
-LL | assert_foo::<fn(&i32)>();
- | ^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
- |
- = note: `Foo` would have to be implemented for the type `for<'r> fn(&'r i32)`
- = note: ...but `Foo` is actually implemented for the type `fn(&'0 i32)`, for some specific lifetime `'0`
-
-error: aborting due to previous error
-
+++ /dev/null
-// Regression test for #57639:
-//
-// In the move to universes, this test stopped working. The problem
-// was that when the trait solver was asked to prove `for<'a> T::Item:
-// Foo<'a>` as part of WF checking, it wound up "eagerly committing"
-// to the where clause, which says that `T::Item: Foo<'a>`, but it
-// should instead have been using the bound found in the trait
-// declaration. Pre-universe, this used to work out ok because we got
-// "eager errors" due to the leak check.
-//
-// See [this comment on GitHub][c] for more details.
-//
-// check-pass
-//
-// [c]: https://github.com/rust-lang/rust/issues/57639#issuecomment-455685861
-
-trait Foo<'a> {}
-
-trait Bar {
- type Item: for<'a> Foo<'a>;
-}
-
-fn foo<'a, T>(_: T)
-where
- T: Bar,
- T::Item: Foo<'a>,
-{}
-
-fn main() { }
+++ /dev/null
-// Regression test for #58451:
-//
-// Error reporting here encountered an ICE in the shift to universes.
-
-fn f<I>(i: I)
-where
- I: IntoIterator,
- I::Item: for<'a> Into<&'a ()>,
-{}
-
-fn main() {
- f(&[f()]); //~ ERROR this function takes 1 argument
-}
+++ /dev/null
-error[E0061]: this function takes 1 argument but 0 arguments were supplied
- --> $DIR/issue-58451.rs:12:9
- |
-LL | f(&[f()]);
- | ^-- an argument is missing
- |
-note: function defined here
- --> $DIR/issue-58451.rs:5:4
- |
-LL | fn f<I>(i: I)
- | ^ ----
-help: provide the argument
- |
-LL | f(&[f(/* value */)]);
- | ~~~~~~~~~~~~~~
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0061`.
+++ /dev/null
-trait T0<'a, A> {
- type O;
-}
-
-struct L<T> {
- f: T,
-}
-
-// explicitly named variants of what one would normally denote by the
-// unit type `()`. Why do this? So that we can differentiate them in
-// the diagnostic output.
-struct Unit1;
-struct Unit2;
-struct Unit3;
-struct Unit4;
-
-impl<'a, A, T> T0<'a, A> for L<T>
-where
- T: FnMut(A) -> Unit3,
-{
- type O = T::Output;
-}
-
-trait T1: for<'r> Ty<'r> {
- fn m<'a, B: Ty<'a>, F>(&self, f: F) -> Unit1
- where
- F: for<'r> T0<'r, (<Self as Ty<'r>>::V,), O = <B as Ty<'r>>::V>,
- {
- unimplemented!();
- }
-}
-
-trait Ty<'a> {
- type V;
-}
-
-fn main() {
- let v = Unit2.m(
- //~^ ERROR type mismatch
- L {
- //~^ ERROR to be a closure that returns `Unit3`, but it returns `Unit4`
- f: |x| {
- drop(x);
- Unit4
- },
- },
- );
-}
-
-impl<'a> Ty<'a> for Unit2 {
- type V = &'a u8;
-}
-
-impl T1 for Unit2 {}
+++ /dev/null
-error[E0271]: type mismatch resolving `for<'r> <L<[closure@$DIR/issue-62203-hrtb-ice.rs:42:16: 42:19]> as T0<'r, (&'r u8,)>>::O == <_ as Ty<'r>>::V`
- --> $DIR/issue-62203-hrtb-ice.rs:38:19
- |
-LL | let v = Unit2.m(
- | ^ type mismatch resolving `for<'r> <L<[closure@$DIR/issue-62203-hrtb-ice.rs:42:16: 42:19]> as T0<'r, (&'r u8,)>>::O == <_ as Ty<'r>>::V`
- |
-note: expected this to be `<_ as Ty<'_>>::V`
- --> $DIR/issue-62203-hrtb-ice.rs:21:14
- |
-LL | type O = T::Output;
- | ^^^^^^^^^
- = note: expected associated type `<_ as Ty<'_>>::V`
- found struct `Unit4`
- = help: consider constraining the associated type `<_ as Ty<'_>>::V` to `Unit4` or calling a method that returns `<_ as Ty<'_>>::V`
- = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
-note: required by a bound in `T1::m`
- --> $DIR/issue-62203-hrtb-ice.rs:27:51
- |
-LL | fn m<'a, B: Ty<'a>, F>(&self, f: F) -> Unit1
- | - required by a bound in this
-LL | where
-LL | F: for<'r> T0<'r, (<Self as Ty<'r>>::V,), O = <B as Ty<'r>>::V>,
- | ^^^^^^^^^^^^^^^^^^^^ required by this bound in `T1::m`
-
-error[E0271]: expected `[closure@$DIR/issue-62203-hrtb-ice.rs:42:16: 42:19]` to be a closure that returns `Unit3`, but it returns `Unit4`
- --> $DIR/issue-62203-hrtb-ice.rs:40:9
- |
-LL | let v = Unit2.m(
- | - required by a bound introduced by this call
-LL |
-LL | / L {
-LL | |
-LL | | f: |x| {
-LL | | drop(x);
-LL | | Unit4
-LL | | },
-LL | | },
- | |_________^ expected struct `Unit3`, found struct `Unit4`
- |
-note: required because of the requirements on the impl of `for<'r> T0<'r, (&'r u8,)>` for `L<[closure@$DIR/issue-62203-hrtb-ice.rs:42:16: 42:19]>`
- --> $DIR/issue-62203-hrtb-ice.rs:17:16
- |
-LL | impl<'a, A, T> T0<'a, A> for L<T>
- | ^^^^^^^^^ ^^^^
-note: required by a bound in `T1::m`
- --> $DIR/issue-62203-hrtb-ice.rs:27:12
- |
-LL | fn m<'a, B: Ty<'a>, F>(&self, f: F) -> Unit1
- | - required by a bound in this
-LL | where
-LL | F: for<'r> T0<'r, (<Self as Ty<'r>>::V,), O = <B as Ty<'r>>::V>,
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `T1::m`
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0271`.
+++ /dev/null
-// check-pass
-
-trait Yokeable<'a> {
- type Output: 'a;
-}
-impl<'a> Yokeable<'a> for () {
- type Output = ();
-}
-
-trait DataMarker<'data> {
- type Yokeable: for<'a> Yokeable<'a>;
-}
-impl<'data> DataMarker<'data> for () {
- type Yokeable = ();
-}
-
-struct DataPayload<'data, M>(&'data M);
-
-impl DataPayload<'static, ()> {
- pub fn map_project_with_capture<M2, T>(
- _: for<'a> fn(
- capture: T,
- std::marker::PhantomData<&'a ()>,
- ) -> <M2::Yokeable as Yokeable<'a>>::Output,
- ) -> DataPayload<'static, M2>
- where
- M2: DataMarker<'static>,
- {
- todo!()
- }
-}
-
-fn main() {
- let _: DataPayload<()> = DataPayload::<()>::map_project_with_capture::<_, &()>(|_, _| todo!());
-}
+++ /dev/null
-// check-pass
-
-trait Base<'f> {
- type Assoc;
-
- fn do_something(&self);
-}
-
-trait ForAnyLifetime: for<'f> Base<'f> {}
-
-impl<T> ForAnyLifetime for T where T: for<'f> Base<'f> {}
-
-trait CanBeDynamic: ForAnyLifetime + for<'f> Base<'f, Assoc = ()> {}
-
-fn foo(a: &dyn CanBeDynamic) {
- a.do_something();
-}
-
-struct S;
-
-impl<'a> Base<'a> for S {
- type Assoc = ();
-
- fn do_something(&self) {}
-}
-
-impl CanBeDynamic for S {}
-
-fn main() {
- let s = S;
- foo(&s);
-}
+++ /dev/null
-// known-bug: #95034
-// failure-status: 101
-// compile-flags: --edition=2021 --crate-type=lib
-// rustc-env:RUST_BACKTRACE=0
-
-// normalize-stderr-test "thread 'rustc' panicked.*" -> "thread 'rustc' panicked"
-// normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> ""
-// normalize-stderr-test "\nerror: internal compiler error.*\n\n" -> ""
-// normalize-stderr-test "note:.*unexpectedly panicked.*\n\n" -> ""
-// normalize-stderr-test "note: we would appreciate a bug report.*\n\n" -> ""
-// normalize-stderr-test "note: compiler flags.*\n\n" -> ""
-// normalize-stderr-test "note: rustc.*running on.*\n\n" -> ""
-// normalize-stderr-test "query stack during panic:\n" -> ""
-// normalize-stderr-test "we're just showing a limited slice of the query stack\n" -> ""
-// normalize-stderr-test "end of query stack\n" -> ""
-// normalize-stderr-test "#.*\n" -> ""
-
-// This should not ICE.
-
-// Refer to the issue for more minimized versions.
-
-use std::{
- future::Future,
- marker::PhantomData,
- pin::Pin,
- task::{Context, Poll},
-};
-
-mod object {
- use super::*;
-
- pub trait Object<'a> {
- type Error;
- type Future: Future<Output = Self>;
- fn create() -> Self::Future;
- }
-
- impl<'a> Object<'a> for u8 {
- type Error = ();
- type Future = Pin<Box<dyn Future<Output = Self>>>;
- fn create() -> Self::Future {
- unimplemented!()
- }
- }
-
- impl<'a, E, A: Object<'a, Error = E>> Object<'a> for (A,) {
- type Error = ();
- type Future = CustomFut<'a, E, A>;
- fn create() -> Self::Future {
- unimplemented!()
- }
- }
-
- pub struct CustomFut<'f, E, A: Object<'f, Error = E>> {
- ph: PhantomData<(A::Future,)>,
- }
-
- impl<'f, E, A: Object<'f, Error = E>> Future for CustomFut<'f, E, A> {
- type Output = (A,);
- fn poll(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Self::Output> {
- unimplemented!()
- }
- }
-}
-
-mod async_fn {
- use super::*;
-
- pub trait AsyncFn {
- type Future: Future<Output = ()>;
- fn call(&self) -> Self::Future;
- }
-
- impl<F, Fut> AsyncFn for F
- where
- F: Fn() -> Fut,
- Fut: Future<Output = ()>,
- {
- type Future = Fut;
- fn call(&self) -> Self::Future {
- (self)()
- }
- }
-}
-
-pub async fn test() {
- use self::{async_fn::AsyncFn, object::Object};
-
- async fn create<T: Object<'static>>() {
- T::create().await;
- }
-
- async fn call_async_fn(inner: impl AsyncFn) {
- inner.call().await;
- }
-
- call_async_fn(create::<(u8,)>).await;
-}
+++ /dev/null
-thread 'rustc' panicked
+++ /dev/null
-// check-pass
-
-pub struct Bar
-where
- for<'a> &'a mut Self:;
-
-fn main() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `const_eval_select`
error[E0271]: expected `fn(i32) -> bool {bar}` to be a fn item that returns `i32`, but it returns `bool`
- --> $DIR/const-eval-select-bad.rs:29:5
+ --> $DIR/const-eval-select-bad.rs:29:34
|
LL | const_eval_select((1,), foo, bar);
- | ^^^^^^^^^^^^^^^^^ expected `i32`, found `bool`
+ | ----------------- ^^^ expected `i32`, found `bool`
+ | |
+ | required by a bound introduced by this call
|
note: required by a bound in `const_eval_select`
--> $SRC_DIR/core/src/intrinsics.rs:LL:COL
--> $DIR/issue-11374.rs:13:12
|
LL | pub fn read_to(&mut self, vec: &mut [u8]) {
- | ^^^^^^^ --------- --------------
+ | ^^^^^^^ --------------
error: aborting due to previous error
--> $DIR/issue-18819.rs:16:5
|
LL | print_x(X);
- | ^^^^^^^---
- | ||
- | |expected reference, found struct `X`
- | an argument of type `&str` is missing
+ | ^^^^^^^--- an argument of type `&str` is missing
|
+note: expected reference, found struct `X`
+ --> $DIR/issue-18819.rs:16:13
+ |
+LL | print_x(X);
+ | ^
= note: expected reference `&dyn Foo<Item = bool>`
found struct `X`
note: function defined here
+error[E0191]: the value of the associated type `Output` (from trait `Add`) must be specified
+ --> $DIR/issue-21950.rs:10:25
+ |
+LL | type Output;
+ | ----------- `Output` defined here
+...
+LL | let x = &10 as &dyn Add;
+ | ^^^ help: specify the associated type: `Add<Output = Type>`
+
error[E0393]: the type parameter `Rhs` must be explicitly specified
--> $DIR/issue-21950.rs:10:25
|
|
= note: because of the default `Self` reference, type parameters must be specified on object types
-error[E0191]: the value of the associated type `Output` (from trait `Add`) must be specified
- --> $DIR/issue-21950.rs:10:25
- |
-LL | type Output;
- | ----------- `Output` defined here
-...
-LL | let x = &10 as &dyn Add;
- | ^^^ help: specify the associated type: `Add<Output = Type>`
-
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0191, E0393.
--- /dev/null
+// Issue #94176: wrong span for the error message of a mismatched type error,
+// if the function uses a `let else` construct.
+#![feature(let_else)]
+
+pub fn test(a: Option<u32>) -> Option<u32> { //~ ERROR mismatched types
+ let Some(_) = a else { return None; };
+ println!("Foo");
+}
+
+fn main() {}
--- /dev/null
+error[E0308]: mismatched types
+ --> $DIR/issue-94176.rs:5:32
+ |
+LL | pub fn test(a: Option<u32>) -> Option<u32> {
+ | ---- ^^^^^^^^^^^ expected enum `Option`, found `()`
+ | |
+ | implicitly returns `()` as its body has no tail or `return` expression
+ |
+ = note: expected enum `Option<u32>`
+ found unit type `()`
+help: consider returning the local binding `a`
+ |
+LL ~ println!("Foo");
+LL + a
+ |
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
--- /dev/null
+//
+// popped up in in #94012, where an alternative desugaring was
+// causing unreachable code errors
+
+#![feature(let_else)]
+#![deny(unused_variables)]
+#![deny(unreachable_code)]
+
+fn let_else_diverge() -> bool {
+ let Some(_) = Some("test") else {
+ let x = 5; //~ ERROR unused variable: `x`
+ return false;
+ };
+ return true;
+}
+
+fn main() {
+ let_else_diverge();
+}
--- /dev/null
+error: unused variable: `x`
+ --> $DIR/let-else-then-diverge.rs:11:13
+ |
+LL | let x = 5;
+ | ^ help: if this is intentional, prefix it with an underscore: `_x`
+ |
+note: the lint level is defined here
+ --> $DIR/let-else-then-diverge.rs:6:9
+ |
+LL | #![deny(unused_variables)]
+ | ^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
--- /dev/null
+// Tests that lint levels can be set for early lints.
+#![allow(non_camel_case_types, unsafe_code, while_true, unused_parens)]
+
+// The following is a check of the lints used here to verify they do not warn
+// when allowed.
+fn verify_no_warnings() {
+ type non_camel_type = i32; // non_camel_case_types
+ struct NON_CAMEL_IS_ALLOWED; // non_camel_case_types
+ unsafe {} // unsafe_code
+ enum Enum {
+ VARIANT_CAMEL // non_camel_case_types
+ }
+ fn generics<foo>() {} // non_camel_case_types
+ while true {} // while_true
+ type T = (i32); // unused_parens
+}
+
+
+// ################## Types
+
+#[deny(non_camel_case_types)]
+type type_outer = i32; //~ ERROR type `type_outer` should have an upper camel case name
+
+type BareFnPtr = fn(#[deny(unused_parens)](i32)); //~ ERROR unnecessary parentheses around type
+// There aren't any early lints that currently apply to the variadic spot.
+// type BareFnPtrVariadic = extern "C" fn(i32, #[deny()]...);
+
+// ################## Items
+#[deny(non_camel_case_types)]
+struct ITEM_OUTER; //~ ERROR type `ITEM_OUTER` should have an upper camel case name
+
+mod module_inner {
+ #![deny(unsafe_code)]
+ fn f() {
+ unsafe {} //~ ERROR usage of an `unsafe` block
+ }
+}
+
+struct Associated;
+impl Associated {
+ #![deny(unsafe_code)]
+
+ fn inherent_denied_from_inner() { unsafe {} } //~ usage of an `unsafe` block
+
+ #[deny(while_true)]
+ fn inherent_fn() { while true {} } //~ ERROR denote infinite loops with
+
+ #[deny(while_true)]
+ const INHERENT_CONST: i32 = {while true {} 1}; //~ ERROR denote infinite loops with
+}
+
+trait trait_inner { //~ ERROR trait `trait_inner` should have an upper camel case name
+ #![deny(non_camel_case_types)]
+}
+
+trait AssociatedTrait {
+ #![deny(unsafe_code)]
+
+ fn denied_from_inner() { unsafe {} } //~ ERROR usage of an `unsafe` block
+
+ #[deny(while_true)]
+ fn assoc_fn() { while true {} } //~ ERROR denote infinite loops with
+
+ #[deny(while_true)]
+ const ASSOC_CONST: i32 = {while true {} 1}; //~ ERROR denote infinite loops with
+
+ #[deny(non_camel_case_types)]
+ type assoc_type; //~ ERROR associated type `assoc_type` should have an upper camel case name
+}
+
+impl AssociatedTrait for Associated {
+ #![deny(unsafe_code)]
+
+ fn denied_from_inner() { unsafe {} } //~ ERROR usage of an `unsafe` block
+
+ #[deny(while_true)]
+ fn assoc_fn() { while true {} } //~ ERROR denote infinite loops with
+
+ #[deny(while_true)]
+ const ASSOC_CONST: i32 = {while true {} 1}; //~ ERROR denote infinite loops with
+
+ #[deny(unused_parens)]
+ type assoc_type = (i32); //~ ERROR unnecessary parentheses around type
+}
+
+struct StructFields {
+ #[deny(unused_parens)]f1: (i32), //~ ERROR unnecessary parentheses around type
+}
+struct StructTuple(#[deny(unused_parens)](i32)); //~ ERROR unnecessary parentheses around type
+
+enum Enum {
+ #[deny(non_camel_case_types)]
+ VARIANT_CAMEL, //~ ERROR variant `VARIANT_CAMEL` should have an upper camel case name
+}
+
+extern "C" {
+ #![deny(unused_parens)]
+
+ fn foreign_denied_from_inner(x: (i32)); //~ ERROR unnecessary parentheses around type
+}
+
+extern "C" {
+ #[deny(unused_parens)]
+ fn foreign_denied_from_outer(x: (i32)); //~ ERROR unnecessary parentheses around type
+}
+
+fn function(#[deny(unused_parens)] param: (i32)) {} //~ ERROR unnecessary parentheses around type
+
+fn generics<#[deny(non_camel_case_types)]foo>() {} //~ ERROR type parameter `foo` should have an upper camel case name
+
+
+// ################## Statements
+fn statements() {
+ #[deny(unused_parens)]
+ let x = (1); //~ ERROR unnecessary parentheses around assigned value
+}
+
+
+// ################## Expressions
+fn expressions() {
+ let closure = |#[deny(unused_parens)] param: (i32)| {}; //~ ERROR unnecessary parentheses around type
+
+ struct Match{f1: i32}
+ // Strangely unused_parens doesn't fire with {f1: (123)}
+ let f = Match{#[deny(unused_parens)]f1: {(123)}}; //~ ERROR unnecessary parentheses around block return value
+
+ match f {
+ #![deny(unsafe_code)]
+
+ #[deny(while_true)]
+ Match{f1} => {
+ unsafe {} //~ ERROR usage of an `unsafe` block
+ while true {} //~ ERROR denote infinite loops with
+ }
+ }
+
+ // Statement Block
+ {
+ #![deny(unsafe_code)]
+ unsafe {} //~ ERROR usage of an `unsafe` block
+ }
+ let block_tail = {
+ #[deny(unsafe_code)]
+ unsafe {} //~ ERROR usage of an `unsafe` block
+ };
+
+ // Before expression as a statement.
+ #[deny(unsafe_code)]
+ unsafe {}; //~ ERROR usage of an `unsafe` block
+
+ [#[deny(unsafe_code)] unsafe {123}]; //~ ERROR usage of an `unsafe` block
+ (#[deny(unsafe_code)] unsafe {123},); //~ ERROR usage of an `unsafe` block
+ fn call(p: i32) {}
+ call(#[deny(unsafe_code)] unsafe {123}); //~ ERROR usage of an `unsafe` block
+ struct TupleStruct(i32);
+ TupleStruct(#[deny(unsafe_code)] unsafe {123}); //~ ERROR usage of an `unsafe` block
+}
+
+
+// ################## Patterns
+fn patterns() {
+ struct PatField{f1: i32, f2: i32};
+ let f = PatField{f1: 1, f2: 2};
+ match f {
+ PatField {
+ #[deny(ellipsis_inclusive_range_patterns)]
+ f1: 0...100,
+ //~^ ERROR range patterns are deprecated
+ //~| WARNING this is accepted in the current edition
+ ..
+ } => {}
+ _ => {}
+ }
+}
+
+fn main() {}
--- /dev/null
+error: type `type_outer` should have an upper camel case name
+ --> $DIR/lint-attr-everywhere-early.rs:22:6
+ |
+LL | type type_outer = i32;
+ | ^^^^^^^^^^ help: convert the identifier to upper camel case: `TypeOuter`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:21:8
+ |
+LL | #[deny(non_camel_case_types)]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: unnecessary parentheses around type
+ --> $DIR/lint-attr-everywhere-early.rs:24:43
+ |
+LL | type BareFnPtr = fn(#[deny(unused_parens)](i32));
+ | ^ ^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:24:28
+ |
+LL | type BareFnPtr = fn(#[deny(unused_parens)](i32));
+ | ^^^^^^^^^^^^^
+help: remove these parentheses
+ |
+LL - type BareFnPtr = fn(#[deny(unused_parens)](i32));
+LL + type BareFnPtr = fn(#[deny(unused_parens)]i32);
+ |
+
+error: type `ITEM_OUTER` should have an upper camel case name
+ --> $DIR/lint-attr-everywhere-early.rs:30:8
+ |
+LL | struct ITEM_OUTER;
+ | ^^^^^^^^^^ help: convert the identifier to upper camel case: `ItemOuter`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:29:8
+ |
+LL | #[deny(non_camel_case_types)]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: usage of an `unsafe` block
+ --> $DIR/lint-attr-everywhere-early.rs:35:9
+ |
+LL | unsafe {}
+ | ^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:33:13
+ |
+LL | #![deny(unsafe_code)]
+ | ^^^^^^^^^^^
+
+error: usage of an `unsafe` block
+ --> $DIR/lint-attr-everywhere-early.rs:43:39
+ |
+LL | fn inherent_denied_from_inner() { unsafe {} }
+ | ^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:41:13
+ |
+LL | #![deny(unsafe_code)]
+ | ^^^^^^^^^^^
+
+error: denote infinite loops with `loop { ... }`
+ --> $DIR/lint-attr-everywhere-early.rs:46:24
+ |
+LL | fn inherent_fn() { while true {} }
+ | ^^^^^^^^^^ help: use `loop`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:45:12
+ |
+LL | #[deny(while_true)]
+ | ^^^^^^^^^^
+
+error: denote infinite loops with `loop { ... }`
+ --> $DIR/lint-attr-everywhere-early.rs:49:34
+ |
+LL | const INHERENT_CONST: i32 = {while true {} 1};
+ | ^^^^^^^^^^ help: use `loop`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:48:12
+ |
+LL | #[deny(while_true)]
+ | ^^^^^^^^^^
+
+error: trait `trait_inner` should have an upper camel case name
+ --> $DIR/lint-attr-everywhere-early.rs:52:7
+ |
+LL | trait trait_inner {
+ | ^^^^^^^^^^^ help: convert the identifier to upper camel case: `TraitInner`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:53:13
+ |
+LL | #![deny(non_camel_case_types)]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: usage of an `unsafe` block
+ --> $DIR/lint-attr-everywhere-early.rs:59:30
+ |
+LL | fn denied_from_inner() { unsafe {} }
+ | ^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:57:13
+ |
+LL | #![deny(unsafe_code)]
+ | ^^^^^^^^^^^
+
+error: denote infinite loops with `loop { ... }`
+ --> $DIR/lint-attr-everywhere-early.rs:62:21
+ |
+LL | fn assoc_fn() { while true {} }
+ | ^^^^^^^^^^ help: use `loop`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:61:12
+ |
+LL | #[deny(while_true)]
+ | ^^^^^^^^^^
+
+error: denote infinite loops with `loop { ... }`
+ --> $DIR/lint-attr-everywhere-early.rs:65:31
+ |
+LL | const ASSOC_CONST: i32 = {while true {} 1};
+ | ^^^^^^^^^^ help: use `loop`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:64:12
+ |
+LL | #[deny(while_true)]
+ | ^^^^^^^^^^
+
+error: associated type `assoc_type` should have an upper camel case name
+ --> $DIR/lint-attr-everywhere-early.rs:68:10
+ |
+LL | type assoc_type;
+ | ^^^^^^^^^^ help: convert the identifier to upper camel case: `AssocType`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:67:12
+ |
+LL | #[deny(non_camel_case_types)]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: usage of an `unsafe` block
+ --> $DIR/lint-attr-everywhere-early.rs:74:30
+ |
+LL | fn denied_from_inner() { unsafe {} }
+ | ^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:72:13
+ |
+LL | #![deny(unsafe_code)]
+ | ^^^^^^^^^^^
+
+error: denote infinite loops with `loop { ... }`
+ --> $DIR/lint-attr-everywhere-early.rs:77:21
+ |
+LL | fn assoc_fn() { while true {} }
+ | ^^^^^^^^^^ help: use `loop`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:76:12
+ |
+LL | #[deny(while_true)]
+ | ^^^^^^^^^^
+
+error: denote infinite loops with `loop { ... }`
+ --> $DIR/lint-attr-everywhere-early.rs:80:31
+ |
+LL | const ASSOC_CONST: i32 = {while true {} 1};
+ | ^^^^^^^^^^ help: use `loop`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:79:12
+ |
+LL | #[deny(while_true)]
+ | ^^^^^^^^^^
+
+error: unnecessary parentheses around type
+ --> $DIR/lint-attr-everywhere-early.rs:83:23
+ |
+LL | type assoc_type = (i32);
+ | ^ ^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:82:12
+ |
+LL | #[deny(unused_parens)]
+ | ^^^^^^^^^^^^^
+help: remove these parentheses
+ |
+LL - type assoc_type = (i32);
+LL + type assoc_type = i32;
+ |
+
+error: unnecessary parentheses around type
+ --> $DIR/lint-attr-everywhere-early.rs:87:31
+ |
+LL | #[deny(unused_parens)]f1: (i32),
+ | ^ ^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:87:12
+ |
+LL | #[deny(unused_parens)]f1: (i32),
+ | ^^^^^^^^^^^^^
+help: remove these parentheses
+ |
+LL - #[deny(unused_parens)]f1: (i32),
+LL + #[deny(unused_parens)]f1: i32,
+ |
+
+error: unnecessary parentheses around type
+ --> $DIR/lint-attr-everywhere-early.rs:89:42
+ |
+LL | struct StructTuple(#[deny(unused_parens)](i32));
+ | ^ ^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:89:27
+ |
+LL | struct StructTuple(#[deny(unused_parens)](i32));
+ | ^^^^^^^^^^^^^
+help: remove these parentheses
+ |
+LL - struct StructTuple(#[deny(unused_parens)](i32));
+LL + struct StructTuple(#[deny(unused_parens)]i32);
+ |
+
+error: variant `VARIANT_CAMEL` should have an upper camel case name
+ --> $DIR/lint-attr-everywhere-early.rs:93:5
+ |
+LL | VARIANT_CAMEL,
+ | ^^^^^^^^^^^^^ help: convert the identifier to upper camel case: `VariantCamel`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:92:12
+ |
+LL | #[deny(non_camel_case_types)]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: unnecessary parentheses around type
+ --> $DIR/lint-attr-everywhere-early.rs:99:37
+ |
+LL | fn foreign_denied_from_inner(x: (i32));
+ | ^ ^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:97:13
+ |
+LL | #![deny(unused_parens)]
+ | ^^^^^^^^^^^^^
+help: remove these parentheses
+ |
+LL - fn foreign_denied_from_inner(x: (i32));
+LL + fn foreign_denied_from_inner(x: i32);
+ |
+
+error: unnecessary parentheses around type
+ --> $DIR/lint-attr-everywhere-early.rs:104:37
+ |
+LL | fn foreign_denied_from_outer(x: (i32));
+ | ^ ^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:103:12
+ |
+LL | #[deny(unused_parens)]
+ | ^^^^^^^^^^^^^
+help: remove these parentheses
+ |
+LL - fn foreign_denied_from_outer(x: (i32));
+LL + fn foreign_denied_from_outer(x: i32);
+ |
+
+error: unnecessary parentheses around type
+ --> $DIR/lint-attr-everywhere-early.rs:107:43
+ |
+LL | fn function(#[deny(unused_parens)] param: (i32)) {}
+ | ^ ^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:107:20
+ |
+LL | fn function(#[deny(unused_parens)] param: (i32)) {}
+ | ^^^^^^^^^^^^^
+help: remove these parentheses
+ |
+LL - fn function(#[deny(unused_parens)] param: (i32)) {}
+LL + fn function(#[deny(unused_parens)] param: i32) {}
+ |
+
+error: type parameter `foo` should have an upper camel case name
+ --> $DIR/lint-attr-everywhere-early.rs:109:42
+ |
+LL | fn generics<#[deny(non_camel_case_types)]foo>() {}
+ | ^^^ help: convert the identifier to upper camel case (notice the capitalization): `Foo`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:109:20
+ |
+LL | fn generics<#[deny(non_camel_case_types)]foo>() {}
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: unnecessary parentheses around assigned value
+ --> $DIR/lint-attr-everywhere-early.rs:115:13
+ |
+LL | let x = (1);
+ | ^ ^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:114:12
+ |
+LL | #[deny(unused_parens)]
+ | ^^^^^^^^^^^^^
+help: remove these parentheses
+ |
+LL - let x = (1);
+LL + let x = 1;
+ |
+
+error: unnecessary parentheses around type
+ --> $DIR/lint-attr-everywhere-early.rs:121:50
+ |
+LL | let closure = |#[deny(unused_parens)] param: (i32)| {};
+ | ^ ^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:121:27
+ |
+LL | let closure = |#[deny(unused_parens)] param: (i32)| {};
+ | ^^^^^^^^^^^^^
+help: remove these parentheses
+ |
+LL - let closure = |#[deny(unused_parens)] param: (i32)| {};
+LL + let closure = |#[deny(unused_parens)] param: i32| {};
+ |
+
+error: unnecessary parentheses around block return value
+ --> $DIR/lint-attr-everywhere-early.rs:125:46
+ |
+LL | let f = Match{#[deny(unused_parens)]f1: {(123)}};
+ | ^ ^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:125:26
+ |
+LL | let f = Match{#[deny(unused_parens)]f1: {(123)}};
+ | ^^^^^^^^^^^^^
+help: remove these parentheses
+ |
+LL - let f = Match{#[deny(unused_parens)]f1: {(123)}};
+LL + let f = Match{#[deny(unused_parens)]f1: {123}};
+ |
+
+error: usage of an `unsafe` block
+ --> $DIR/lint-attr-everywhere-early.rs:132:13
+ |
+LL | unsafe {}
+ | ^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:128:17
+ |
+LL | #![deny(unsafe_code)]
+ | ^^^^^^^^^^^
+
+error: denote infinite loops with `loop { ... }`
+ --> $DIR/lint-attr-everywhere-early.rs:133:13
+ |
+LL | while true {}
+ | ^^^^^^^^^^ help: use `loop`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:130:16
+ |
+LL | #[deny(while_true)]
+ | ^^^^^^^^^^
+
+error: usage of an `unsafe` block
+ --> $DIR/lint-attr-everywhere-early.rs:140:9
+ |
+LL | unsafe {}
+ | ^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:139:17
+ |
+LL | #![deny(unsafe_code)]
+ | ^^^^^^^^^^^
+
+error: usage of an `unsafe` block
+ --> $DIR/lint-attr-everywhere-early.rs:144:9
+ |
+LL | unsafe {}
+ | ^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:143:16
+ |
+LL | #[deny(unsafe_code)]
+ | ^^^^^^^^^^^
+
+error: usage of an `unsafe` block
+ --> $DIR/lint-attr-everywhere-early.rs:149:5
+ |
+LL | unsafe {};
+ | ^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:148:12
+ |
+LL | #[deny(unsafe_code)]
+ | ^^^^^^^^^^^
+
+error: usage of an `unsafe` block
+ --> $DIR/lint-attr-everywhere-early.rs:151:27
+ |
+LL | [#[deny(unsafe_code)] unsafe {123}];
+ | ^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:151:13
+ |
+LL | [#[deny(unsafe_code)] unsafe {123}];
+ | ^^^^^^^^^^^
+
+error: usage of an `unsafe` block
+ --> $DIR/lint-attr-everywhere-early.rs:152:27
+ |
+LL | (#[deny(unsafe_code)] unsafe {123},);
+ | ^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:152:13
+ |
+LL | (#[deny(unsafe_code)] unsafe {123},);
+ | ^^^^^^^^^^^
+
+error: usage of an `unsafe` block
+ --> $DIR/lint-attr-everywhere-early.rs:154:31
+ |
+LL | call(#[deny(unsafe_code)] unsafe {123});
+ | ^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:154:17
+ |
+LL | call(#[deny(unsafe_code)] unsafe {123});
+ | ^^^^^^^^^^^
+
+error: usage of an `unsafe` block
+ --> $DIR/lint-attr-everywhere-early.rs:156:38
+ |
+LL | TupleStruct(#[deny(unsafe_code)] unsafe {123});
+ | ^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:156:24
+ |
+LL | TupleStruct(#[deny(unsafe_code)] unsafe {123});
+ | ^^^^^^^^^^^
+
+error: `...` range patterns are deprecated
+ --> $DIR/lint-attr-everywhere-early.rs:167:18
+ |
+LL | f1: 0...100,
+ | ^^^ help: use `..=` for an inclusive range
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-early.rs:166:20
+ |
+LL | #[deny(ellipsis_inclusive_range_patterns)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+
+error: aborting due to 36 previous errors
+
--- /dev/null
+// Tests that lint levels can be set for late lints.
+#![allow(
+ non_snake_case,
+ overflowing_literals,
+ missing_docs,
+ dyn_drop,
+ enum_intrinsics_non_enums,
+ clashing_extern_declarations
+)]
+
+extern crate core;
+use core::mem::{Discriminant, discriminant};
+
+// The following is a check of the lints used here to verify they do not warn
+// when allowed.
+pub fn missing_docs_allowed() {} // missing_docs
+fn dyn_drop_allowed(_x: Box<dyn Drop>) {} // dyn_drop
+fn verify_no_warnings() {
+ discriminant::<i32>(&123); // enum_intrinsics_non_enums
+ let x: u8 = 1000; // overflowing_literals
+ let NON_SNAKE_CASE = 1; // non_snake_case
+}
+mod clashing_extern_allowed {
+ extern "C" {
+ fn extern_allowed();
+ }
+}
+extern "C" {
+ fn extern_allowed(_: i32); // clashing_extern_declarations
+}
+
+// ################## Types
+
+#[deny(missing_docs)]
+pub type MissingDocType = i32; //~ ERROR missing documentation for a type alias
+
+// There aren't any late lints that I can find that can be easily used with types.
+// type BareFnPtr = fn(#[deny()]i32);
+// type BareFnPtrVariadic = extern "C" fn(i32, #[deny()]...);
+
+// ################## Items
+#[deny(missing_docs)]
+pub struct ItemOuter; //~ ERROR missing documentation for a struct
+
+pub mod module_inner { //~ ERROR missing documentation for a module
+ #![deny(missing_docs)]
+ pub fn missing_inner() {} //~ ERROR missing documentation for a function
+}
+
+pub struct Associated;
+impl Associated {
+ #![deny(missing_docs)]
+
+ pub fn inherent_denied_from_inner() {} //~ ERROR missing documentation for an associated function
+}
+
+impl Associated {
+ #[deny(missing_docs)]
+ pub fn inherent_fn() {} //~ ERROR missing documentation for an associated function
+
+ #[deny(missing_docs)]
+ pub const INHERENT_CONST: i32 = 1; //~ ERROR missing documentation for an associated constant
+}
+
+pub trait TraitInner { //~ ERROR missing documentation for a trait
+ #![deny(missing_docs)]
+}
+
+pub trait AssociatedTraitInner { //~ ERROR missing documentation for a trait
+ #![deny(missing_docs)]
+
+ fn denied_from_inner() {} //~ ERROR missing documentation for an associated function
+}
+
+pub trait AssociatedTrait {
+ fn denied_from_inner(_x: Box<dyn Drop>) {} // Used below
+
+ #[deny(missing_docs)]
+ fn assoc_fn() {} //~ ERROR missing documentation for an associated function
+
+ #[deny(missing_docs)]
+ const ASSOC_CONST: u8 = 1; //~ ERROR missing documentation for an associated constant
+
+ #[deny(missing_docs)]
+ type AssocType; //~ ERROR missing documentation for an associated type
+}
+
+struct Foo;
+
+impl AssociatedTrait for Associated {
+ #![deny(dyn_drop)]
+
+ fn denied_from_inner(_x: Box<dyn Drop>) {} //~ ERROR types that do not implement `Drop`
+
+ #[deny(enum_intrinsics_non_enums)]
+ fn assoc_fn() { discriminant::<i32>(&123); } //~ ERROR the return value of
+
+ #[deny(overflowing_literals)] const ASSOC_CONST: u8 = 1000; //~ ERROR literal out of range
+ type AssocType = i32;
+}
+
+
+// There aren't any late lints that can apply to a field that I can find.
+// non_snake_case doesn't work on fields
+// struct StructFields {
+// #[deny()]f1: i32,
+// }
+// struct StructTuple(#[deny()]i32);
+
+pub enum Enum {
+ #[deny(missing_docs)]
+ Variant1, //~ ERROR missing documentation for a variant
+}
+
+mod clashing_extern {
+ extern "C" {
+ fn clashing1();
+ fn clashing2();
+ }
+}
+extern "C" {
+ #![deny(clashing_extern_declarations)]
+ fn clashing1(_: i32); //~ ERROR `clashing1` redeclared with a different signature
+}
+
+extern "C" {
+ #[deny(clashing_extern_declarations)]
+ fn clashing2(_: i32); //~ ERROR `clashing2` redeclared with a different signature
+}
+
+fn function(#[deny(non_snake_case)] PARAM: i32) {} //~ ERROR variable `PARAM` should have a snake case name
+// There aren't any late lints that can apply to generics that I can find.
+// fn generics<#[deny()]T>() {}
+
+
+// ################## Statements
+fn statements() {
+ #[deny(enum_intrinsics_non_enums)]
+ let _ = discriminant::<i32>(&123); //~ ERROR the return value of
+}
+
+
+// ################## Expressions
+fn expressions() {
+ let closure = |#[deny(non_snake_case)] PARAM: i32| {}; //~ ERROR variable `PARAM` should have a snake case name
+
+ struct Match{f1: i32}
+ // I can't find any late lints for patterns.
+ // let f = Match{#[deny()]f1: 123};
+
+ let f = Match{f1: 123};
+ match f {
+ #![deny(enum_intrinsics_non_enums)]
+ Match{f1} => {
+ discriminant::<i32>(&123); //~ ERROR the return value of
+ }
+ }
+ match f {
+ #[deny(enum_intrinsics_non_enums)]
+ Match{f1} => {
+ discriminant::<i32>(&123); //~ ERROR the return value of
+ }
+ }
+
+ // Statement Block
+ {
+ #![deny(enum_intrinsics_non_enums)]
+ discriminant::<i32>(&123); //~ ERROR the return value of
+ }
+ let block_tail = {
+ #[deny(enum_intrinsics_non_enums)]
+ discriminant::<i32>(&123); //~ ERROR the return value of
+ };
+
+ // Before expression as a statement.
+ #[deny(enum_intrinsics_non_enums)]
+ discriminant::<i32>(&123); //~ ERROR the return value of
+
+ [#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123)]; //~ ERROR the return value of
+ (#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123),); //~ ERROR the return value of
+ fn call(p: Discriminant<i32>) {}
+ call(#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123)); //~ ERROR the return value of
+ struct TupleStruct(Discriminant<i32>);
+ TupleStruct(#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123)); //~ ERROR the return value of
+}
+
+
+// ################## Patterns
+fn patterns() {
+ // There aren't any late lints that I can find that apply to pattern fields.
+ //
+ // struct PatField{f1: i32, f2: i32};
+ // let f = PatField{f1: 1, f2: 2};
+ // let PatField{#[deny()]f1, #[deny()]..} = f;
+}
+
+fn main() {}
--- /dev/null
+error: missing documentation for a type alias
+ --> $DIR/lint-attr-everywhere-late.rs:35:1
+ |
+LL | pub type MissingDocType = i32;
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:34:8
+ |
+LL | #[deny(missing_docs)]
+ | ^^^^^^^^^^^^
+
+error: missing documentation for a struct
+ --> $DIR/lint-attr-everywhere-late.rs:43:1
+ |
+LL | pub struct ItemOuter;
+ | ^^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:42:8
+ |
+LL | #[deny(missing_docs)]
+ | ^^^^^^^^^^^^
+
+error: missing documentation for a module
+ --> $DIR/lint-attr-everywhere-late.rs:45:1
+ |
+LL | pub mod module_inner {
+ | ^^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:46:13
+ |
+LL | #![deny(missing_docs)]
+ | ^^^^^^^^^^^^
+
+error: missing documentation for a function
+ --> $DIR/lint-attr-everywhere-late.rs:47:5
+ |
+LL | pub fn missing_inner() {}
+ | ^^^^^^^^^^^^^^^^^^^^^^
+
+error: missing documentation for an associated function
+ --> $DIR/lint-attr-everywhere-late.rs:54:5
+ |
+LL | pub fn inherent_denied_from_inner() {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:52:13
+ |
+LL | #![deny(missing_docs)]
+ | ^^^^^^^^^^^^
+
+error: missing documentation for an associated function
+ --> $DIR/lint-attr-everywhere-late.rs:59:5
+ |
+LL | pub fn inherent_fn() {}
+ | ^^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:58:12
+ |
+LL | #[deny(missing_docs)]
+ | ^^^^^^^^^^^^
+
+error: missing documentation for an associated constant
+ --> $DIR/lint-attr-everywhere-late.rs:62:5
+ |
+LL | pub const INHERENT_CONST: i32 = 1;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:61:12
+ |
+LL | #[deny(missing_docs)]
+ | ^^^^^^^^^^^^
+
+error: missing documentation for a trait
+ --> $DIR/lint-attr-everywhere-late.rs:65:1
+ |
+LL | pub trait TraitInner {
+ | ^^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:66:13
+ |
+LL | #![deny(missing_docs)]
+ | ^^^^^^^^^^^^
+
+error: missing documentation for a trait
+ --> $DIR/lint-attr-everywhere-late.rs:69:1
+ |
+LL | pub trait AssociatedTraitInner {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:70:13
+ |
+LL | #![deny(missing_docs)]
+ | ^^^^^^^^^^^^
+
+error: missing documentation for an associated function
+ --> $DIR/lint-attr-everywhere-late.rs:72:5
+ |
+LL | fn denied_from_inner() {}
+ | ^^^^^^^^^^^^^^^^^^^^^^
+
+error: missing documentation for an associated function
+ --> $DIR/lint-attr-everywhere-late.rs:79:5
+ |
+LL | fn assoc_fn() {}
+ | ^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:78:12
+ |
+LL | #[deny(missing_docs)]
+ | ^^^^^^^^^^^^
+
+error: missing documentation for an associated constant
+ --> $DIR/lint-attr-everywhere-late.rs:82:5
+ |
+LL | const ASSOC_CONST: u8 = 1;
+ | ^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:81:12
+ |
+LL | #[deny(missing_docs)]
+ | ^^^^^^^^^^^^
+
+error: missing documentation for an associated type
+ --> $DIR/lint-attr-everywhere-late.rs:85:5
+ |
+LL | type AssocType;
+ | ^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:84:12
+ |
+LL | #[deny(missing_docs)]
+ | ^^^^^^^^^^^^
+
+error: missing documentation for a variant
+ --> $DIR/lint-attr-everywhere-late.rs:112:5
+ |
+LL | Variant1,
+ | ^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:111:12
+ |
+LL | #[deny(missing_docs)]
+ | ^^^^^^^^^^^^
+
+error: `clashing1` redeclared with a different signature
+ --> $DIR/lint-attr-everywhere-late.rs:123:5
+ |
+LL | fn clashing1();
+ | --------------- `clashing1` previously declared here
+...
+LL | fn clashing1(_: i32);
+ | ^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:122:13
+ |
+LL | #![deny(clashing_extern_declarations)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = note: expected `unsafe extern "C" fn()`
+ found `unsafe extern "C" fn(i32)`
+
+error: `clashing2` redeclared with a different signature
+ --> $DIR/lint-attr-everywhere-late.rs:128:5
+ |
+LL | fn clashing2();
+ | --------------- `clashing2` previously declared here
+...
+LL | fn clashing2(_: i32);
+ | ^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:127:12
+ |
+LL | #[deny(clashing_extern_declarations)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = note: expected `unsafe extern "C" fn()`
+ found `unsafe extern "C" fn(i32)`
+
+error: types that do not implement `Drop` can still have drop glue, consider instead using `std::mem::needs_drop` to detect whether a type is trivially dropped
+ --> $DIR/lint-attr-everywhere-late.rs:93:38
+ |
+LL | fn denied_from_inner(_x: Box<dyn Drop>) {}
+ | ^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:91:13
+ |
+LL | #![deny(dyn_drop)]
+ | ^^^^^^^^
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+ --> $DIR/lint-attr-everywhere-late.rs:96:21
+ |
+LL | fn assoc_fn() { discriminant::<i32>(&123); }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:95:12
+ |
+LL | #[deny(enum_intrinsics_non_enums)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
+ --> $DIR/lint-attr-everywhere-late.rs:96:41
+ |
+LL | fn assoc_fn() { discriminant::<i32>(&123); }
+ | ^^^^
+
+error: literal out of range for `u8`
+ --> $DIR/lint-attr-everywhere-late.rs:98:59
+ |
+LL | #[deny(overflowing_literals)] const ASSOC_CONST: u8 = 1000;
+ | ^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:98:12
+ |
+LL | #[deny(overflowing_literals)] const ASSOC_CONST: u8 = 1000;
+ | ^^^^^^^^^^^^^^^^^^^^
+ = note: the literal `1000` does not fit into the type `u8` whose range is `0..=255`
+
+error: variable `PARAM` should have a snake case name
+ --> $DIR/lint-attr-everywhere-late.rs:131:37
+ |
+LL | fn function(#[deny(non_snake_case)] PARAM: i32) {}
+ | ^^^^^ help: convert the identifier to snake case: `param`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:131:20
+ |
+LL | fn function(#[deny(non_snake_case)] PARAM: i32) {}
+ | ^^^^^^^^^^^^^^
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+ --> $DIR/lint-attr-everywhere-late.rs:139:13
+ |
+LL | let _ = discriminant::<i32>(&123);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:138:12
+ |
+LL | #[deny(enum_intrinsics_non_enums)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
+ --> $DIR/lint-attr-everywhere-late.rs:139:33
+ |
+LL | let _ = discriminant::<i32>(&123);
+ | ^^^^
+
+error: variable `PARAM` should have a snake case name
+ --> $DIR/lint-attr-everywhere-late.rs:145:44
+ |
+LL | let closure = |#[deny(non_snake_case)] PARAM: i32| {};
+ | ^^^^^ help: convert the identifier to snake case: `param`
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:145:27
+ |
+LL | let closure = |#[deny(non_snake_case)] PARAM: i32| {};
+ | ^^^^^^^^^^^^^^
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+ --> $DIR/lint-attr-everywhere-late.rs:155:13
+ |
+LL | discriminant::<i32>(&123);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:153:17
+ |
+LL | #![deny(enum_intrinsics_non_enums)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
+ --> $DIR/lint-attr-everywhere-late.rs:155:33
+ |
+LL | discriminant::<i32>(&123);
+ | ^^^^
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+ --> $DIR/lint-attr-everywhere-late.rs:161:13
+ |
+LL | discriminant::<i32>(&123);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:159:16
+ |
+LL | #[deny(enum_intrinsics_non_enums)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
+ --> $DIR/lint-attr-everywhere-late.rs:161:33
+ |
+LL | discriminant::<i32>(&123);
+ | ^^^^
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+ --> $DIR/lint-attr-everywhere-late.rs:168:9
+ |
+LL | discriminant::<i32>(&123);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:167:17
+ |
+LL | #![deny(enum_intrinsics_non_enums)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
+ --> $DIR/lint-attr-everywhere-late.rs:168:29
+ |
+LL | discriminant::<i32>(&123);
+ | ^^^^
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+ --> $DIR/lint-attr-everywhere-late.rs:172:9
+ |
+LL | discriminant::<i32>(&123);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:171:16
+ |
+LL | #[deny(enum_intrinsics_non_enums)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
+ --> $DIR/lint-attr-everywhere-late.rs:172:29
+ |
+LL | discriminant::<i32>(&123);
+ | ^^^^
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+ --> $DIR/lint-attr-everywhere-late.rs:177:5
+ |
+LL | discriminant::<i32>(&123);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:176:12
+ |
+LL | #[deny(enum_intrinsics_non_enums)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
+ --> $DIR/lint-attr-everywhere-late.rs:177:25
+ |
+LL | discriminant::<i32>(&123);
+ | ^^^^
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+ --> $DIR/lint-attr-everywhere-late.rs:179:41
+ |
+LL | [#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123)];
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:179:13
+ |
+LL | [#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123)];
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
+ --> $DIR/lint-attr-everywhere-late.rs:179:61
+ |
+LL | [#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123)];
+ | ^^^^
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+ --> $DIR/lint-attr-everywhere-late.rs:180:41
+ |
+LL | (#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123),);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:180:13
+ |
+LL | (#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123),);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
+ --> $DIR/lint-attr-everywhere-late.rs:180:61
+ |
+LL | (#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123),);
+ | ^^^^
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+ --> $DIR/lint-attr-everywhere-late.rs:182:45
+ |
+LL | call(#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123));
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:182:17
+ |
+LL | call(#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123));
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
+ --> $DIR/lint-attr-everywhere-late.rs:182:65
+ |
+LL | call(#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123));
+ | ^^^^
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+ --> $DIR/lint-attr-everywhere-late.rs:184:52
+ |
+LL | TupleStruct(#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123));
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-attr-everywhere-late.rs:184:24
+ |
+LL | TupleStruct(#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123));
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
+ --> $DIR/lint-attr-everywhere-late.rs:184:72
+ |
+LL | TupleStruct(#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123));
+ | ^^^^
+
+error: aborting due to 31 previous errors
+
Some(res) => res,
None => 0,
};
+
+ struct PatternField {
+ foo: i32,
+ }
+ let s = PatternField { #[must_use] foo: 123 }; //~ ERROR `#[must_use]` has no effect
+ let PatternField { #[must_use] foo } = s; //~ ERROR `#[must_use]` has no effect
}
LL | #[must_use]
| ^^^^^^^^^^^
+error: `#[must_use]` has no effect when applied to a struct field
+ --> $DIR/unused_attributes-must_use.rs:129:28
+ |
+LL | let s = PatternField { #[must_use] foo: 123 };
+ | ^^^^^^^^^^^
+
+error: `#[must_use]` has no effect when applied to a pattern field
+ --> $DIR/unused_attributes-must_use.rs:130:24
+ |
+LL | let PatternField { #[must_use] foo } = s;
+ | ^^^^^^^^^^^
+
error: `#[must_use]` has no effect when applied to an associated const
--> $DIR/unused_attributes-must_use.rs:68:5
|
LL | ().get_four();
| ^^^^^^^^^^^^^^
-error: aborting due to 26 previous errors
+error: aborting due to 28 previous errors
--> $DIR/method-call-err-msg.rs:5:8
|
LL | fn zero(self) -> Foo { self }
- | ^^^^ ----
+ | ^^^^
help: remove the extra argument
|
LL | x.zero()
--> $DIR/method-call-err-msg.rs:6:8
|
LL | fn one(self, _: isize) -> Foo { self }
- | ^^^ ---- --------
+ | ^^^ --------
help: provide the argument
|
LL | .one(/* isize */)
--> $DIR/method-call-err-msg.rs:7:8
|
LL | fn two(self, _: isize, _: isize) -> Foo { self }
- | ^^^ ---- -------- --------
+ | ^^^ -------- --------
help: provide the argument
|
LL | .two(0, /* isize */);
--> $DIR/method-call-err-msg.rs:8:8
|
LL | fn three<T>(self, _: T, _: T, _: T) -> Foo { self }
- | ^^^^^ ---- ---- ---- ----
+ | ^^^^^ ---- ---- ----
help: provide the arguments
|
LL | y.three::<usize>(/* usize */, /* usize */, /* usize */);
--- /dev/null
+// run-rustfix
+
+fn main() {
+ let mut _x = 123;
+ //~^ ERROR invalid variable declaration
+}
--- /dev/null
+// run-rustfix
+
+fn main() {
+ mut let _x = 123;
+ //~^ ERROR invalid variable declaration
+}
--- /dev/null
+error: invalid variable declaration
+ --> $DIR/issue-100197-mut-let.rs:4:5
+ |
+LL | mut let _x = 123;
+ | ^^^^^^^ help: switch the order of `mut` and `let`: `let mut`
+
+error: aborting due to previous error
+
--- /dev/null
+// run-rustfix
+
+fn main() {
+ const _FOO: i32 = 123;
+ //~^ ERROR const` and `let` are mutually exclusive
+ const _BAR: i32 = 123;
+ //~^ ERROR `const` and `let` are mutually exclusive
+}
--- /dev/null
+// run-rustfix
+
+fn main() {
+ const let _FOO: i32 = 123;
+ //~^ ERROR const` and `let` are mutually exclusive
+ let const _BAR: i32 = 123;
+ //~^ ERROR `const` and `let` are mutually exclusive
+}
--- /dev/null
+error: `const` and `let` are mutually exclusive
+ --> $DIR/issue-99910-const-let-mutually-exclusive.rs:4:5
+ |
+LL | const let _FOO: i32 = 123;
+ | ^^^^^^^^^ help: remove `let`: `const`
+
+error: `const` and `let` are mutually exclusive
+ --> $DIR/issue-99910-const-let-mutually-exclusive.rs:6:5
+ |
+LL | let const _BAR: i32 = 123;
+ | ^^^^^^^^^ help: remove `let`: `const`
+
+error: aborting due to 2 previous errors
+
--- /dev/null
+// Issue: 100461, Try to give a helpful diagnostic even when the next struct field has an attribute.
+// run-rustfix
+
+struct Feelings {
+ owo: bool,
+ //~^ ERROR expected `,`, or `}`, found `#`
+ #[allow(unused)]
+ uwu: bool,
+}
+
+impl Feelings {
+ #[allow(unused)]
+ fn hmm(&self) -> bool {
+ self.owo
+ }
+}
+
+fn main() { }
--- /dev/null
+// Issue: 100461, Try to give a helpful diagnostic even when the next struct field has an attribute.
+// run-rustfix
+
+struct Feelings {
+ owo: bool
+ //~^ ERROR expected `,`, or `}`, found `#`
+ #[allow(unused)]
+ uwu: bool,
+}
+
+impl Feelings {
+ #[allow(unused)]
+ fn hmm(&self) -> bool {
+ self.owo
+ }
+}
+
+fn main() { }
--- /dev/null
+error: expected `,`, or `}`, found `#`
+ --> $DIR/struct-filed-with-attr.rs:5:14
+ |
+LL | owo: bool
+ | ^ help: try adding a comma: `,`
+
+error: aborting due to previous error
+
--- /dev/null
+let X: i32 = 12;
+//~^ ERROR expected item, found keyword `let`
+
+fn main() {
+ println!("{}", X);
+}
--- /dev/null
+error: expected item, found keyword `let`
+ --> $DIR/suggest-const-for-global-var.rs:1:1
+ |
+LL | let X: i32 = 12;
+ | ^^^ consider using `const` or `static` instead of `let` for global variables
+
+error: aborting due to previous error
+
--- /dev/null
+// run-rustfix
+
+trait Foo {
+ fn bar() {} //~ ERROR non-item in item list
+}
+
+fn main() {}
--- /dev/null
+// run-rustfix
+
+trait Foo {
+ fn bar() {}; //~ ERROR non-item in item list
+}
+
+fn main() {}
--- /dev/null
+error: non-item in item list
+ --> $DIR/suggest-removing-semicolon-after-impl-trait-items.rs:4:16
+ |
+LL | trait Foo {
+ | - item list starts here
+LL | fn bar() {};
+ | ^
+ | |
+ | non-item starts here
+ | help: consider removing this semicolon
+LL | }
+ | - item list ends here
+
+error: aborting due to previous error
+
--- /dev/null
+fn main() {
+ let addr = Into::<std::net::IpAddr>.into([127, 0, 0, 1]);
+ //~^ ERROR expected value, found trait `Into`
+ //~| HELP use the path separator
+
+ let _ = Into.into(());
+ //~^ ERROR expected value, found trait `Into`
+ //~| HELP use the path separator
+
+ let _ = Into::<()>.into;
+ //~^ ERROR expected value, found trait `Into`
+ //~| HELP use the path separator
+}
+
+macro_rules! Trait {
+ () => {
+ ::std::iter::Iterator
+ //~^ ERROR expected value, found trait `std::iter::Iterator`
+ //~| ERROR expected value, found trait `std::iter::Iterator`
+ };
+}
+
+macro_rules! create {
+ () => {
+ Into::<String>.into("")
+ //~^ ERROR expected value, found trait `Into`
+ //~| HELP use the path separator
+ };
+}
+
+fn interaction_with_macros() {
+ //
+ // Note that if the receiver is a macro call, we do not want to suggest to replace
+ // `.` with `::` as that would be a syntax error.
+ // Since the receiver is a trait and not a type, we cannot suggest to surround
+ // it with angle brackets. It would be interpreted as a trait object type void of
+ // `dyn` which is most likely not what the user intended to write.
+ // `<_ as Trait!()>::` is also not an option as it's equally syntactically invalid.
+ //
+
+ Trait!().map(std::convert::identity); // no `help` here!
+
+ Trait!().map; // no `help` here!
+
+ //
+ // Ensure that the suggestion is shown for expressions inside of macro definitions.
+ //
+
+ let _ = create!();
+}
--- /dev/null
+error[E0423]: expected value, found trait `Into`
+ --> $DIR/issue-100365.rs:2:16
+ |
+LL | let addr = Into::<std::net::IpAddr>.into([127, 0, 0, 1]);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^- help: use the path separator to refer to an item: `::`
+
+error[E0423]: expected value, found trait `Into`
+ --> $DIR/issue-100365.rs:6:13
+ |
+LL | let _ = Into.into(());
+ | ^^^^- help: use the path separator to refer to an item: `::`
+
+error[E0423]: expected value, found trait `Into`
+ --> $DIR/issue-100365.rs:10:13
+ |
+LL | let _ = Into::<()>.into;
+ | ^^^^^^^^^^- help: use the path separator to refer to an item: `::`
+
+error[E0423]: expected value, found trait `std::iter::Iterator`
+ --> $DIR/issue-100365.rs:17:9
+ |
+LL | ::std::iter::Iterator
+ | ^^^^^^^^^^^^^^^^^^^^^ not a value
+...
+LL | Trait!().map(std::convert::identity); // no `help` here!
+ | -------- in this macro invocation
+ |
+ = note: this error originates in the macro `Trait` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0423]: expected value, found trait `std::iter::Iterator`
+ --> $DIR/issue-100365.rs:17:9
+ |
+LL | ::std::iter::Iterator
+ | ^^^^^^^^^^^^^^^^^^^^^ not a value
+...
+LL | Trait!().map; // no `help` here!
+ | -------- in this macro invocation
+ |
+ = note: this error originates in the macro `Trait` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0423]: expected value, found trait `Into`
+ --> $DIR/issue-100365.rs:25:9
+ |
+LL | Into::<String>.into("")
+ | ^^^^^^^^^^^^^^- help: use the path separator to refer to an item: `::`
+...
+LL | let _ = create!();
+ | --------- in this macro invocation
+ |
+ = note: this error originates in the macro `create` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0423`.
fn main() {
- let _ = String.new(); //~ ERROR expected value, found struct `String`
+ let _ = String.new();
+ //~^ ERROR expected value, found struct `String`
+ //~| HELP use the path separator
+
+ let _ = String.default;
+ //~^ ERROR expected value, found struct `String`
+ //~| HELP use the path separator
+
+ let _ = Vec::<()>.with_capacity(1);
+ //~^ ERROR expected value, found struct `Vec`
+ //~| HELP use the path separator
+}
+
+macro_rules! Type {
+ () => {
+ ::std::cell::Cell
+ //~^ ERROR expected value, found struct `std::cell::Cell`
+ //~| ERROR expected value, found struct `std::cell::Cell`
+ //~| ERROR expected value, found struct `std::cell::Cell`
+ };
+}
+
+macro_rules! create {
+ (type method) => {
+ Vec.new()
+ //~^ ERROR expected value, found struct `Vec`
+ //~| HELP use the path separator
+ };
+ (type field) => {
+ Vec.new
+ //~^ ERROR expected value, found struct `Vec`
+ //~| HELP use the path separator
+ };
+ (macro method) => {
+ Type!().new(0)
+ //~^ HELP use the path separator
+ };
+}
+
+fn interaction_with_macros() {
+ //
+ // Verify that we do not only suggest to replace `.` with `::` if the receiver is a
+ // macro call but that we also correctly suggest to surround it with angle brackets.
+ //
+
+ Type!().get();
+ //~^ HELP use the path separator
+
+ Type! {}.get;
+ //~^ HELP use the path separator
+
+ //
+ // Ensure that the suggestion is shown for expressions inside of macro definitions.
+ //
+
+ let _ = create!(type method);
+ let _ = create!(type field);
+ let _ = create!(macro method);
}
--> $DIR/issue-22692.rs:2:13
|
LL | let _ = String.new();
- | ^^^^^^----
- | |
- | help: use the path separator to refer to an item: `String::new`
+ | ^^^^^^- help: use the path separator to refer to an item: `::`
-error: aborting due to previous error
+error[E0423]: expected value, found struct `String`
+ --> $DIR/issue-22692.rs:6:13
+ |
+LL | let _ = String.default;
+ | ^^^^^^- help: use the path separator to refer to an item: `::`
+
+error[E0423]: expected value, found struct `Vec`
+ --> $DIR/issue-22692.rs:10:13
+ |
+LL | let _ = Vec::<()>.with_capacity(1);
+ | ^^^^^^^^^- help: use the path separator to refer to an item: `::`
+
+error[E0423]: expected value, found struct `std::cell::Cell`
+ --> $DIR/issue-22692.rs:17:9
+ |
+LL | ::std::cell::Cell
+ | ^^^^^^^^^^^^^^^^^
+...
+LL | Type!().get();
+ | ------- in this macro invocation
+ |
+ = note: this error originates in the macro `Type` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: use the path separator to refer to an item
+ |
+LL | <Type!()>::get();
+ | ~~~~~~~~~~~
+
+error[E0423]: expected value, found struct `std::cell::Cell`
+ --> $DIR/issue-22692.rs:17:9
+ |
+LL | ::std::cell::Cell
+ | ^^^^^^^^^^^^^^^^^
+...
+LL | Type! {}.get;
+ | -------- in this macro invocation
+ |
+ = note: this error originates in the macro `Type` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: use the path separator to refer to an item
+ |
+LL | <Type! {}>::get;
+ | ~~~~~~~~~~~~
+
+error[E0423]: expected value, found struct `Vec`
+ --> $DIR/issue-22692.rs:26:9
+ |
+LL | Vec.new()
+ | ^^^- help: use the path separator to refer to an item: `::`
+...
+LL | let _ = create!(type method);
+ | -------------------- in this macro invocation
+ |
+ = note: this error originates in the macro `create` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0423]: expected value, found struct `Vec`
+ --> $DIR/issue-22692.rs:31:9
+ |
+LL | Vec.new
+ | ^^^- help: use the path separator to refer to an item: `::`
+...
+LL | let _ = create!(type field);
+ | ------------------- in this macro invocation
+ |
+ = note: this error originates in the macro `create` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0423]: expected value, found struct `std::cell::Cell`
+ --> $DIR/issue-22692.rs:17:9
+ |
+LL | ::std::cell::Cell
+ | ^^^^^^^^^^^^^^^^^
+...
+LL | let _ = create!(macro method);
+ | --------------------- in this macro invocation
+ |
+ = note: this error originates in the macro `Type` which comes from the expansion of the macro `create` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: use the path separator to refer to an item
+ |
+LL | <Type!()>::new(0)
+ | ~~~~~~~~~~~
+
+error: aborting due to 8 previous errors
For more information about this error, try `rustc --explain E0423`.
--> $DIR/suggest-path-for-tuple-struct.rs:22:13
|
LL | let _ = SomeTupleStruct.new();
- | ^^^^^^^^^^^^^^^----
- | |
- | help: use the path separator to refer to an item: `SomeTupleStruct::new`
+ | ^^^^^^^^^^^^^^^- help: use the path separator to refer to an item: `::`
error[E0423]: expected value, found struct `SomeRegularStruct`
--> $DIR/suggest-path-for-tuple-struct.rs:24:13
|
LL | let _ = SomeRegularStruct.new();
- | ^^^^^^^^^^^^^^^^^----
- | |
- | help: use the path separator to refer to an item: `SomeRegularStruct::new`
+ | ^^^^^^^^^^^^^^^^^- help: use the path separator to refer to an item: `::`
error: aborting due to 2 previous errors
fn h1() -> i32 {
a.I
//~^ ERROR expected value, found module `a`
+ //~| HELP use the path separator
}
fn h2() -> i32 {
a.g()
//~^ ERROR expected value, found module `a`
+ //~| HELP use the path separator
}
fn h3() -> i32 {
a.b.J
//~^ ERROR expected value, found module `a`
+ //~| HELP use the path separator
}
fn h4() -> i32 {
a::b.J
//~^ ERROR expected value, found module `a::b`
+ //~| HELP a constant with a similar name exists
+ //~| HELP use the path separator
}
fn h5() {
a.b.f();
//~^ ERROR expected value, found module `a`
+ //~| HELP use the path separator
let v = Vec::new();
v.push(a::b);
//~^ ERROR expected value, found module `a::b`
+ //~| HELP a constant with a similar name exists
}
fn h6() -> i32 {
a::b.f()
//~^ ERROR expected value, found module `a::b`
+ //~| HELP a constant with a similar name exists
+ //~| HELP use the path separator
}
fn h7() {
a::b
//~^ ERROR expected value, found module `a::b`
+ //~| HELP a constant with a similar name exists
}
fn h8() -> i32 {
a::b()
//~^ ERROR expected function, found module `a::b`
+ //~| HELP a constant with a similar name exists
+}
+
+macro_rules! module {
+ () => {
+ a
+ //~^ ERROR expected value, found module `a`
+ //~| ERROR expected value, found module `a`
+ };
+}
+
+macro_rules! create {
+ (method) => {
+ a.f()
+ //~^ ERROR expected value, found module `a`
+ //~| HELP use the path separator
+ };
+ (field) => {
+ a.f
+ //~^ ERROR expected value, found module `a`
+ //~| HELP use the path separator
+ };
+}
+
+fn h9() {
+ //
+ // Note that if the receiver is a macro call, we do not want to suggest to replace
+ // `.` with `::` as that would be a syntax error.
+ // Since the receiver is a module and not a type, we cannot suggest to surround
+ // it with angle brackets.
+ //
+
+ module!().g::<()>(); // no `help` here!
+
+ module!().g; // no `help` here!
+
+ //
+ // Ensure that the suggestion is shown for expressions inside of macro definitions.
+ //
+
+ let _ = create!(method);
+ let _ = create!(field);
}
fn main() {}
--> $DIR/suggest-path-instead-of-mod-dot-item.rs:17:5
|
LL | a.I
- | ^--
- | |
- | help: use the path separator to refer to an item: `a::I`
+ | ^- help: use the path separator to refer to an item: `::`
error[E0423]: expected value, found module `a`
- --> $DIR/suggest-path-instead-of-mod-dot-item.rs:22:5
+ --> $DIR/suggest-path-instead-of-mod-dot-item.rs:23:5
|
LL | a.g()
- | ^--
- | |
- | help: use the path separator to refer to an item: `a::g`
+ | ^- help: use the path separator to refer to an item: `::`
error[E0423]: expected value, found module `a`
- --> $DIR/suggest-path-instead-of-mod-dot-item.rs:27:5
+ --> $DIR/suggest-path-instead-of-mod-dot-item.rs:29:5
|
LL | a.b.J
- | ^--
- | |
- | help: use the path separator to refer to an item: `a::b`
+ | ^- help: use the path separator to refer to an item: `::`
error[E0423]: expected value, found module `a::b`
- --> $DIR/suggest-path-instead-of-mod-dot-item.rs:32:5
+ --> $DIR/suggest-path-instead-of-mod-dot-item.rs:35:5
|
LL | pub const I: i32 = 1;
| --------------------- similarly named constant `I` defined here
help: use the path separator to refer to an item
|
LL | a::b::J
- |
+ | ~~
help: a constant with a similar name exists
|
LL | a::I.J
| ~
error[E0423]: expected value, found module `a`
- --> $DIR/suggest-path-instead-of-mod-dot-item.rs:37:5
+ --> $DIR/suggest-path-instead-of-mod-dot-item.rs:42:5
|
LL | a.b.f();
- | ^--
- | |
- | help: use the path separator to refer to an item: `a::b`
+ | ^- help: use the path separator to refer to an item: `::`
error[E0423]: expected value, found module `a::b`
- --> $DIR/suggest-path-instead-of-mod-dot-item.rs:40:12
+ --> $DIR/suggest-path-instead-of-mod-dot-item.rs:46:12
|
LL | pub const I: i32 = 1;
| --------------------- similarly named constant `I` defined here
| help: a constant with a similar name exists: `I`
error[E0423]: expected value, found module `a::b`
- --> $DIR/suggest-path-instead-of-mod-dot-item.rs:45:5
+ --> $DIR/suggest-path-instead-of-mod-dot-item.rs:52:5
|
LL | pub const I: i32 = 1;
| --------------------- similarly named constant `I` defined here
help: use the path separator to refer to an item
|
LL | a::b::f()
- | ~~~~~~~
+ | ~~
help: a constant with a similar name exists
|
LL | a::I.f()
| ~
error[E0423]: expected value, found module `a::b`
- --> $DIR/suggest-path-instead-of-mod-dot-item.rs:50:5
+ --> $DIR/suggest-path-instead-of-mod-dot-item.rs:59:5
|
LL | pub const I: i32 = 1;
| --------------------- similarly named constant `I` defined here
| help: a constant with a similar name exists: `I`
error[E0423]: expected function, found module `a::b`
- --> $DIR/suggest-path-instead-of-mod-dot-item.rs:55:5
+ --> $DIR/suggest-path-instead-of-mod-dot-item.rs:65:5
|
LL | pub const I: i32 = 1;
| --------------------- similarly named constant `I` defined here
| |
| help: a constant with a similar name exists: `I`
-error: aborting due to 9 previous errors
+error[E0423]: expected value, found module `a`
+ --> $DIR/suggest-path-instead-of-mod-dot-item.rs:72:9
+ |
+LL | a
+ | ^ not a value
+...
+LL | module!().g::<()>(); // no `help` here!
+ | --------- in this macro invocation
+ |
+ = note: this error originates in the macro `module` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0423]: expected value, found module `a`
+ --> $DIR/suggest-path-instead-of-mod-dot-item.rs:72:9
+ |
+LL | a
+ | ^ not a value
+...
+LL | module!().g; // no `help` here!
+ | --------- in this macro invocation
+ |
+ = note: this error originates in the macro `module` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0423]: expected value, found module `a`
+ --> $DIR/suggest-path-instead-of-mod-dot-item.rs:80:9
+ |
+LL | a.f()
+ | ^- help: use the path separator to refer to an item: `::`
+...
+LL | let _ = create!(method);
+ | --------------- in this macro invocation
+ |
+ = note: this error originates in the macro `create` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0423]: expected value, found module `a`
+ --> $DIR/suggest-path-instead-of-mod-dot-item.rs:85:9
+ |
+LL | a.f
+ | ^- help: use the path separator to refer to an item: `::`
+...
+LL | let _ = create!(field);
+ | -------------- in this macro invocation
+ |
+ = note: this error originates in the macro `create` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 13 previous errors
For more information about this error, try `rustc --explain E0423`.
// run-fail
// error-pattern: MemorySanitizer: use-of-uninitialized-value
// error-pattern: Uninitialized value was created by an allocation
-// error-pattern: in the stack frame of function 'main'
+// error-pattern: in the stack frame
//
// This test case intentionally limits the usage of the std,
// since it will be linked with an uninstrumented version of it.
--> $DIR/issue-34264.rs:3:4
|
LL | fn bar(x, y: usize) {}
- | ^^^ - --------
+ | ^^^ --------
error[E0061]: this function takes 2 arguments but 3 arguments were supplied
--> $DIR/issue-34264.rs:10:5
--> $DIR/missing-unit-argument.rs:6:8
|
LL | fn baz(self, (): ()) { }
- | ^^^ ---- ------
+ | ^^^ ------
help: provide the argument
|
LL | S.baz(());
--> $DIR/missing-unit-argument.rs:7:8
|
LL | fn generic<T>(self, _: T) { }
- | ^^^^^^^ ---- ----
+ | ^^^^^^^ ----
help: provide the argument
|
LL | S.generic::<()>(());
--- /dev/null
+#![crate_type = "lib"]
+#![feature(staged_api)]
+#![stable(feature = "none", since = "1.0")]
+
+#[stable(feature = "none", since = "1.0")]
+pub enum Foo {
+ A,
+}
--- /dev/null
+// aux-build:ctor-stability.rs
+// check-pass
+
+extern crate ctor_stability;
+
+fn main() {
+ let _ = ctor_stability::Foo::A;
+}
--> $DIR/args-instead-of-tuple-errors.rs:6:34
|
LL | let _: Option<(i32, bool)> = Some(1, 2);
- | ^^^^ - - argument of type `{integer}` unexpected
- | |
- | expected tuple, found integer
+ | ^^^^ - argument of type `{integer}` unexpected
|
+note: expected tuple, found integer
+ --> $DIR/args-instead-of-tuple-errors.rs:6:39
+ |
+LL | let _: Option<(i32, bool)> = Some(1, 2);
+ | ^
= note: expected tuple `(i32, bool)`
found type `{integer}`
note: tuple variant defined here
--> $DIR/args-instead-of-tuple-errors.rs:8:5
|
LL | int_bool(1, 2);
- | ^^^^^^^^ - - argument of type `{integer}` unexpected
- | |
- | expected tuple, found integer
+ | ^^^^^^^^ - argument of type `{integer}` unexpected
|
+note: expected tuple, found integer
+ --> $DIR/args-instead-of-tuple-errors.rs:8:14
+ |
+LL | int_bool(1, 2);
+ | ^
= note: expected tuple `(i32, bool)`
found type `{integer}`
note: function defined here
--> $DIR/assoc-const-as-field.rs:11:9
|
LL | foo(Mod::Foo.Bar);
- | ^^^^^^^^----
- | |
- | help: use the path separator to refer to an item: `Mod::Foo::Bar`
+ | ^^^^^^^^- help: use the path separator to refer to an item: `::`
error: aborting due to previous error
--- /dev/null
+// run-pass
+
+#![allow(dead_code)]
+
+struct Foo {
+ foo: i32,
+ bar: i32,
+ baz: (),
+}
+
+fn use_foo(x: Foo) -> (i32, i32) {
+ let Foo { foo, bar, baz } = x; //~ WARNING unused variable: `baz`
+ //~| help: try ignoring the field
+ return (foo, bar);
+}
+
+fn main() {}
--- /dev/null
+warning: unused variable: `baz`
+ --> $DIR/dont-try-removing-the-field.rs:12:25
+ |
+LL | let Foo { foo, bar, baz } = x;
+ | ^^^ help: try ignoring the field: `baz: _`
+ |
+ = note: `#[warn(unused_variables)]` on by default
+
+warning: 1 warning emitted
+
note: function defined here
--> $DIR/suggest-ref-macro.rs:8:1
|
-LL | #[hello]
- | _-^^^^^^^
-LL | | fn abc() {}
-LL | |
-LL | | fn x(_: &mut i32) {}
-LL | |
-LL | | macro_rules! bla {
- | |_____________-
+LL | #[hello]
+ | ^^^^^^^^
= note: this error originates in the attribute macro `hello` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0308]: mismatched types
--- /dev/null
+// run-pass
+
+#![allow(dead_code)]
+
+struct Foo {
+ foo: i32,
+ bar: (),
+ baz: (),
+}
+
+fn use_foo(x: Foo) -> i32 {
+ let Foo { foo, bar, .. } = x; //~ WARNING unused variable: `bar`
+ //~| help: try removing the field
+ return foo;
+}
+
+fn main() {}
--- /dev/null
+warning: unused variable: `bar`
+ --> $DIR/try-removing-the-field.rs:12:20
+ |
+LL | let Foo { foo, bar, .. } = x;
+ | ^^^-
+ | |
+ | help: try removing the field
+ |
+ = note: `#[warn(unused_variables)]` on by default
+
+warning: 1 warning emitted
+
--- /dev/null
+trait SendEqAlias<T> = PartialEq;
+//~^ ERROR trait aliases are experimental
+
+struct Foo<T>(dyn SendEqAlias<T>);
+//~^ ERROR the type parameter `Rhs` must be explicitly specified [E0393]
+
+struct Bar<T>(dyn SendEqAlias<T>, T);
+//~^ ERROR the type parameter `Rhs` must be explicitly specified [E0393]
+
+fn main() {}
--- /dev/null
+error[E0658]: trait aliases are experimental
+ --> $DIR/generic-default-in-dyn.rs:1:1
+ |
+LL | trait SendEqAlias<T> = PartialEq;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: see issue #41517 <https://github.com/rust-lang/rust/issues/41517> for more information
+ = help: add `#![feature(trait_alias)]` to the crate attributes to enable
+
+error[E0393]: the type parameter `Rhs` must be explicitly specified
+ --> $DIR/generic-default-in-dyn.rs:4:19
+ |
+LL | struct Foo<T>(dyn SendEqAlias<T>);
+ | ^^^^^^^^^^^^^^ missing reference to `Rhs`
+ |
+ ::: $SRC_DIR/core/src/cmp.rs:LL:COL
+ |
+LL | pub trait PartialEq<Rhs: ?Sized = Self> {
+ | --------------------------------------- type parameter `Rhs` must be specified for this
+ |
+ = note: because of the default `Self` reference, type parameters must be specified on object types
+
+error[E0393]: the type parameter `Rhs` must be explicitly specified
+ --> $DIR/generic-default-in-dyn.rs:7:19
+ |
+LL | struct Bar<T>(dyn SendEqAlias<T>, T);
+ | ^^^^^^^^^^^^^^ missing reference to `Rhs`
+ |
+ ::: $SRC_DIR/core/src/cmp.rs:LL:COL
+ |
+LL | pub trait PartialEq<Rhs: ?Sized = Self> {
+ | --------------------------------------- type parameter `Rhs` must be specified for this
+ |
+ = note: because of the default `Self` reference, type parameters must be specified on object types
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0393, E0658.
+For more information about an error, try `rustc --explain E0393`.
--- /dev/null
+#![feature(trait_alias)]
+
+pub trait SelfInput = Fn(&mut Self);
+
+pub fn f(_f: &dyn SelfInput) {}
+//~^ ERROR the trait alias `SelfInput` cannot be made into an object [E0038]
+
+fn main() {}
--- /dev/null
+error[E0038]: the trait alias `SelfInput` cannot be made into an object
+ --> $DIR/self-in-generics.rs:5:19
+ |
+LL | pub fn f(_f: &dyn SelfInput) {}
+ | ^^^^^^^^^
+ |
+ = note: it cannot use `Self` as a type parameter in a supertrait or `where`-clause
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0038`.
error[E0271]: type mismatch resolving `<i32 as Is>::T == i64`
- --> $DIR/check-trait-object-bounds-5.rs:23:5
+ --> $DIR/check-trait-object-bounds-5.rs:23:12
|
LL | is_obj(x)
- | ^^^^^^ type mismatch resolving `<i32 as Is>::T == i64`
+ | ------ ^ type mismatch resolving `<i32 as Is>::T == i64`
+ | |
+ | required by a bound introduced by this call
|
note: expected this to be `i64`
--> $DIR/check-trait-object-bounds-5.rs:9:14
error[E0271]: type mismatch resolving `<i32 as Is>::T == i64`
- --> $DIR/check-trait-object-bounds-6.rs:20:5
+ --> $DIR/check-trait-object-bounds-6.rs:20:12
|
LL | is_obj(x)
- | ^^^^^^ type mismatch resolving `<i32 as Is>::T == i64`
+ | ------ ^ type mismatch resolving `<i32 as Is>::T == i64`
+ | |
+ | required by a bound introduced by this call
|
note: expected this to be `i64`
--> $DIR/check-trait-object-bounds-6.rs:9:14
--> $DIR/multidispatch-bad.rs:13:4
|
LL | fn test<T,U>(_: T, _: U)
- | ^^^^ ---- ----
+ | ^^^^ ----
help: change the type of the numeric literal from `i32` to `u32`
|
LL | test(22i32, 44u32);
error[E0271]: type mismatch resolving `<dyn Trait<B = B, A = A> as SuperTrait>::A == B`
- --> $DIR/enforce-supertrait-projection.rs:9:5
+ --> $DIR/enforce-supertrait-projection.rs:9:17
|
LL | fn transmute<A, B>(x: A) -> B {
| - - expected type parameter
| |
| found type parameter
LL | foo::<A, B, dyn Trait<A = A, B = B>>(x)
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter `B`, found type parameter `A`
+ | ^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter `B`, found type parameter `A`
|
= note: expected type parameter `B`
found type parameter `A`
error[E0271]: type mismatch resolving `<T as Pointee>::Metadata == ()`
- --> $DIR/pointee-tail-is-generic-errors.rs:13:5
+ --> $DIR/pointee-tail-is-generic-errors.rs:13:15
|
LL | is_thin::<T>();
- | ^^^^^^^^^^^^ expected `()`, found associated type
+ | ^ expected `()`, found associated type
|
= note: expected unit type `()`
found associated type `<T as Pointee>::Metadata`
| ^^^^^^^^^^^^^ required by this bound in `is_thin`
error[E0271]: type mismatch resolving `<Opaque as Pointee>::Metadata == ()`
- --> $DIR/pointee-tail-is-generic-errors.rs:16:5
+ --> $DIR/pointee-tail-is-generic-errors.rs:16:15
|
LL | type Opaque = impl std::fmt::Debug + ?Sized;
| ----------------------------- the found opaque type
...
LL | is_thin::<Opaque>();
- | ^^^^^^^^^^^^^^^^^ expected `()`, found associated type
+ | ^^^^^^ expected `()`, found associated type
|
= note: expected unit type `()`
found associated type `<Opaque as Pointee>::Metadata`
--- /dev/null
+pub trait Foo<A=Self> {
+ fn foo(&self);
+}
+
+pub trait Bar<X=usize, A=Self> {
+ fn foo(&self);
+}
+
+fn main() {
+ let a = Foo::lol();
+ //~^ ERROR no function or associated item named
+ //~| WARN trait objects without an explicit `dyn` are deprecated
+ //~| WARN this is accepted in the current edition
+ let b = Foo::<_>::lol();
+ //~^ ERROR no function or associated item named
+ //~| WARN trait objects without an explicit `dyn` are deprecated
+ //~| WARN this is accepted in the current edition
+ let c = Bar::lol();
+ //~^ ERROR no function or associated item named
+ //~| WARN trait objects without an explicit `dyn` are deprecated
+ //~| WARN this is accepted in the current edition
+ let d = Bar::<usize, _>::lol();
+ //~^ ERROR no function or associated item named
+ //~| WARN trait objects without an explicit `dyn` are deprecated
+ //~| WARN this is accepted in the current edition
+ let e = Bar::<usize>::lol();
+ //~^ ERROR must be explicitly specified
+ //~| WARN trait objects without an explicit `dyn` are deprecated
+ //~| WARN this is accepted in the current edition
+}
--- /dev/null
+warning: trait objects without an explicit `dyn` are deprecated
+ --> $DIR/unspecified-self-in-trait-ref.rs:10:13
+ |
+LL | let a = Foo::lol();
+ | ^^^
+ |
+ = note: `#[warn(bare_trait_objects)]` on by default
+ = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+help: use `dyn`
+ |
+LL | let a = <dyn Foo>::lol();
+ | ++++ +
+
+error[E0599]: no function or associated item named `lol` found for trait object `dyn Foo<_>` in the current scope
+ --> $DIR/unspecified-self-in-trait-ref.rs:10:18
+ |
+LL | let a = Foo::lol();
+ | ^^^ function or associated item not found in `dyn Foo<_>`
+
+warning: trait objects without an explicit `dyn` are deprecated
+ --> $DIR/unspecified-self-in-trait-ref.rs:14:13
+ |
+LL | let b = Foo::<_>::lol();
+ | ^^^^^^^^
+ |
+ = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+help: use `dyn`
+ |
+LL | let b = <dyn Foo::<_>>::lol();
+ | ++++ +
+
+error[E0599]: no function or associated item named `lol` found for trait object `dyn Foo<_>` in the current scope
+ --> $DIR/unspecified-self-in-trait-ref.rs:14:23
+ |
+LL | let b = Foo::<_>::lol();
+ | ^^^ function or associated item not found in `dyn Foo<_>`
+
+warning: trait objects without an explicit `dyn` are deprecated
+ --> $DIR/unspecified-self-in-trait-ref.rs:18:13
+ |
+LL | let c = Bar::lol();
+ | ^^^
+ |
+ = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+help: use `dyn`
+ |
+LL | let c = <dyn Bar>::lol();
+ | ++++ +
+
+error[E0599]: no function or associated item named `lol` found for trait object `dyn Bar<_, _>` in the current scope
+ --> $DIR/unspecified-self-in-trait-ref.rs:18:18
+ |
+LL | let c = Bar::lol();
+ | ^^^ function or associated item not found in `dyn Bar<_, _>`
+
+warning: trait objects without an explicit `dyn` are deprecated
+ --> $DIR/unspecified-self-in-trait-ref.rs:22:13
+ |
+LL | let d = Bar::<usize, _>::lol();
+ | ^^^^^^^^^^^^^^^
+ |
+ = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+help: use `dyn`
+ |
+LL | let d = <dyn Bar::<usize, _>>::lol();
+ | ++++ +
+
+error[E0599]: no function or associated item named `lol` found for trait object `dyn Bar<usize, _>` in the current scope
+ --> $DIR/unspecified-self-in-trait-ref.rs:22:30
+ |
+LL | let d = Bar::<usize, _>::lol();
+ | ^^^ function or associated item not found in `dyn Bar<usize, _>`
+
+warning: trait objects without an explicit `dyn` are deprecated
+ --> $DIR/unspecified-self-in-trait-ref.rs:26:13
+ |
+LL | let e = Bar::<usize>::lol();
+ | ^^^^^^^^^^^^
+ |
+ = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+help: use `dyn`
+ |
+LL | let e = <dyn Bar::<usize>>::lol();
+ | ++++ +
+
+error[E0393]: the type parameter `A` must be explicitly specified
+ --> $DIR/unspecified-self-in-trait-ref.rs:26:13
+ |
+LL | pub trait Bar<X=usize, A=Self> {
+ | ------------------------------ type parameter `A` must be specified for this
+...
+LL | let e = Bar::<usize>::lol();
+ | ^^^^^^^^^^^^ missing reference to `A`
+ |
+ = note: because of the default `Self` reference, type parameters must be specified on object types
+
+error: aborting due to 5 previous errors; 5 warnings emitted
+
+Some errors have detailed explanations: E0393, E0599.
+For more information about an error, try `rustc --explain E0393`.
--> $DIR/add-tuple-within-arguments.rs:1:4
|
LL | fn foo(s: &str, a: (i32, i32), s2: &str) {}
- | ^^^ ------- ------------- --------
+ | ^^^ -------------
help: wrap these arguments in parentheses to construct a tuple
|
LL | foo("hi", (1, 2), "hi");
--> $DIR/add-tuple-within-arguments.rs:3:4
|
LL | fn bar(s: &str, a: (&str,), s2: &str) {}
- | ^^^ ------- ---------- --------
+ | ^^^ ----------
help: use a trailing comma to create a tuple with one element
|
LL | bar("hi", ("hi",), "hi");
--> $DIR/wrong_argument_ice-3.rs:9:16
|
LL | groups.push(new_group, vec![process]);
- | ^^^^ --------- ------------- argument of type `Vec<&Process>` unexpected
- | |
- | expected tuple, found struct `Vec`
+ | ^^^^ ------------- argument of type `Vec<&Process>` unexpected
|
+note: expected tuple, found struct `Vec`
+ --> $DIR/wrong_argument_ice-3.rs:9:21
+ |
+LL | groups.push(new_group, vec![process]);
+ | ^^^^^^^^^
= note: expected tuple `(Vec<String>, Vec<Process>)`
found struct `Vec<String>`
note: associated function defined here
error: function can not have more than 65535 arguments
- --> $DIR/issue-88577-check-fn-with-more-than-65535-arguments.rs:6:24
+ --> $DIR/issue-88577-check-fn-with-more-than-65535-arguments.rs:6:22
|
-LL | fn _f($($t: ()),*) {}
- | ________________________^
-LL | | }
-LL | | }
-LL | |
-LL | | many_args!{[_]########## ######}
- | |____________^
+LL | fn _f($($t: ()),*) {}
+ | ^
+...
+LL | many_args!{[_]########## ######}
+ | -------------------------------- in this macro invocation
+ |
+ = note: this error originates in the macro `many_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to previous error
| |
| arguments to this function are incorrect
|
-note: closure defined here
- --> $DIR/unboxed-closures-type-mismatch.rs:4:17
+note: closure parameter defined here
+ --> $DIR/unboxed-closures-type-mismatch.rs:4:18
|
LL | let mut f = |x: isize, y: isize| -> isize { x + y };
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^
help: change the type of the numeric literal from `usize` to `isize`
|
LL | let z = f(1_isize, 2);
--- /dev/null
+// compile-flags: -Zunpretty=hir
+// check-pass
+
+#![feature(let_else)]
+
+fn foo(x: Option<u32>) {
+ let Some(_) = x else { panic!() };
+}
+
+fn main() {}
--- /dev/null
+// compile-flags: -Zunpretty=hir
+// check-pass
+
+#![feature(let_else)]
+#[prelude_import]
+use ::std::prelude::rust_2015::*;
+#[macro_use]
+extern crate std;
+
+fn foo(x:
+ Option<u32>) {
+ let Some(_) = x else
+ {
+
+ { ::std::rt::begin_panic("explicit panic") }
+ };
+ }
+fn main() { }
+++ /dev/null
-pub trait Foo<A=Self> {
- fn foo(&self);
-}
-
-pub trait Bar<X=usize, A=Self> {
- fn foo(&self);
-}
-
-fn main() {
- let a = Foo::lol();
- //~^ ERROR no function or associated item named
- //~| WARN trait objects without an explicit `dyn` are deprecated
- //~| WARN this is accepted in the current edition
- let b = Foo::<_>::lol();
- //~^ ERROR no function or associated item named
- //~| WARN trait objects without an explicit `dyn` are deprecated
- //~| WARN this is accepted in the current edition
- let c = Bar::lol();
- //~^ ERROR no function or associated item named
- //~| WARN trait objects without an explicit `dyn` are deprecated
- //~| WARN this is accepted in the current edition
- let d = Bar::<usize, _>::lol();
- //~^ ERROR no function or associated item named
- //~| WARN trait objects without an explicit `dyn` are deprecated
- //~| WARN this is accepted in the current edition
- let e = Bar::<usize>::lol();
- //~^ ERROR must be explicitly specified
- //~| WARN trait objects without an explicit `dyn` are deprecated
- //~| WARN this is accepted in the current edition
-}
+++ /dev/null
-warning: trait objects without an explicit `dyn` are deprecated
- --> $DIR/unspecified-self-in-trait-ref.rs:10:13
- |
-LL | let a = Foo::lol();
- | ^^^
- |
- = note: `#[warn(bare_trait_objects)]` on by default
- = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
-help: use `dyn`
- |
-LL | let a = <dyn Foo>::lol();
- | ++++ +
-
-error[E0599]: no function or associated item named `lol` found for trait object `dyn Foo<_>` in the current scope
- --> $DIR/unspecified-self-in-trait-ref.rs:10:18
- |
-LL | let a = Foo::lol();
- | ^^^ function or associated item not found in `dyn Foo<_>`
-
-warning: trait objects without an explicit `dyn` are deprecated
- --> $DIR/unspecified-self-in-trait-ref.rs:14:13
- |
-LL | let b = Foo::<_>::lol();
- | ^^^^^^^^
- |
- = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
-help: use `dyn`
- |
-LL | let b = <dyn Foo::<_>>::lol();
- | ++++ +
-
-error[E0599]: no function or associated item named `lol` found for trait object `dyn Foo<_>` in the current scope
- --> $DIR/unspecified-self-in-trait-ref.rs:14:23
- |
-LL | let b = Foo::<_>::lol();
- | ^^^ function or associated item not found in `dyn Foo<_>`
-
-warning: trait objects without an explicit `dyn` are deprecated
- --> $DIR/unspecified-self-in-trait-ref.rs:18:13
- |
-LL | let c = Bar::lol();
- | ^^^
- |
- = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
-help: use `dyn`
- |
-LL | let c = <dyn Bar>::lol();
- | ++++ +
-
-error[E0599]: no function or associated item named `lol` found for trait object `dyn Bar<_, _>` in the current scope
- --> $DIR/unspecified-self-in-trait-ref.rs:18:18
- |
-LL | let c = Bar::lol();
- | ^^^ function or associated item not found in `dyn Bar<_, _>`
-
-warning: trait objects without an explicit `dyn` are deprecated
- --> $DIR/unspecified-self-in-trait-ref.rs:22:13
- |
-LL | let d = Bar::<usize, _>::lol();
- | ^^^^^^^^^^^^^^^
- |
- = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
-help: use `dyn`
- |
-LL | let d = <dyn Bar::<usize, _>>::lol();
- | ++++ +
-
-error[E0599]: no function or associated item named `lol` found for trait object `dyn Bar<usize, _>` in the current scope
- --> $DIR/unspecified-self-in-trait-ref.rs:22:30
- |
-LL | let d = Bar::<usize, _>::lol();
- | ^^^ function or associated item not found in `dyn Bar<usize, _>`
-
-warning: trait objects without an explicit `dyn` are deprecated
- --> $DIR/unspecified-self-in-trait-ref.rs:26:13
- |
-LL | let e = Bar::<usize>::lol();
- | ^^^^^^^^^^^^
- |
- = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
-help: use `dyn`
- |
-LL | let e = <dyn Bar::<usize>>::lol();
- | ++++ +
-
-error[E0393]: the type parameter `A` must be explicitly specified
- --> $DIR/unspecified-self-in-trait-ref.rs:26:13
- |
-LL | pub trait Bar<X=usize, A=Self> {
- | ------------------------------ type parameter `A` must be specified for this
-...
-LL | let e = Bar::<usize>::lol();
- | ^^^^^^^^^^^^ missing reference to `A`
- |
- = note: because of the default `Self` reference, type parameters must be specified on object types
-
-error: aborting due to 5 previous errors; 5 warnings emitted
-
-Some errors have detailed explanations: E0393, E0599.
-For more information about an error, try `rustc --explain E0393`.
-Subproject commit ce40690a5e4e315d3dab0aae1eae69d0252c52ac
+Subproject commit efd4ca3dc0b89929dc8c5f5c023d25978d76cb61
-#![cfg_attr(bootstrap, feature(let_chains))]
#![feature(let_else)]
#![feature(once_cell)]
#![feature(rustc_private)]
use clippy_utils::source::{snippet_with_applicability, snippet_with_context};
use clippy_utils::sugg::has_enclosing_paren;
use clippy_utils::ty::{expr_sig, peel_mid_ty_refs, ty_sig, variant_of_res};
-use clippy_utils::{get_parent_expr, is_lint_allowed, path_to_local, walk_to_expr_usage};
+use clippy_utils::{get_parent_expr, get_parent_expr_for_hir, is_lint_allowed, path_to_local, walk_to_expr_usage};
use rustc_ast::util::parser::{PREC_POSTFIX, PREC_PREFIX};
use rustc_data_structures::fx::FxIndexMap;
use rustc_errors::Applicability;
Some(ty_auto_deref_stability(cx, output, precedence).position_for_result(cx))
},
+ Node::ExprField(field) if field.span.ctxt() == ctxt => match get_parent_expr_for_hir(cx, field.hir_id) {
+ Some(Expr {
+ hir_id,
+ kind: ExprKind::Struct(path, ..),
+ ..
+ }) => variant_of_res(cx, cx.qpath_res(path, *hir_id))
+ .and_then(|variant| variant.fields.iter().find(|f| f.name == field.ident.name))
+ .map(|field_def| {
+ ty_auto_deref_stability(cx, cx.tcx.type_of(field_def.did), precedence).position_for_arg()
+ }),
+ _ => None,
+ },
+
Node::Expr(parent) if parent.span.ctxt() == ctxt => match parent.kind {
ExprKind::Ret(_) => {
let owner_id = cx.tcx.hir().body_owner(cx.enclosing_body.unwrap());
}
})
},
- ExprKind::Struct(path, fields, _) => {
- let variant = variant_of_res(cx, cx.qpath_res(path, parent.hir_id));
- fields
- .iter()
- .find(|f| f.expr.hir_id == child_id)
- .zip(variant)
- .and_then(|(field, variant)| variant.fields.iter().find(|f| f.name == field.ident.name))
- .map(|field| {
- ty_auto_deref_stability(cx, cx.tcx.type_of(field.did), precedence).position_for_arg()
- })
- },
ExprKind::Field(child, name) if child.hir_id == e.hir_id => Some(Position::FieldAccess(name.name)),
ExprKind::Unary(UnOp::Deref, child) if child.hir_id == e.hir_id => Some(Position::Deref),
ExprKind::Match(child, _, MatchSource::TryDesugar | MatchSource::AwaitDesugar)
#![feature(control_flow_enum)]
#![feature(drain_filter)]
#![feature(iter_intersperse)]
-#![cfg_attr(bootstrap, feature(let_chains))]
#![feature(let_else)]
#![feature(lint_reasons)]
#![feature(never_type)]
#![feature(box_patterns)]
#![feature(control_flow_enum)]
#![feature(let_else)]
-#![cfg_attr(bootstrap, feature(let_chains))]
#![feature(lint_reasons)]
#![feature(once_cell)]
#![feature(rustc_private)]
impl rustc_driver::Callbacks for ClippyCallbacks {
// JUSTIFICATION: necessary in clippy driver to set `mir_opt_level`
- #[cfg_attr(not(bootstrap), allow(rustc::bad_opt_access))]
+ #[allow(rustc::bad_opt_access)]
fn config(&mut self, config: &mut interface::Config) {
let previous = config.register_lints.take();
let clippy_args_var = self.clippy_args_var.take();
stamp.add_path(&path);
}
+ stamp.add_dir(&rust_src_dir.join("src/etc/natvis"));
+
stamp.add_dir(&config.run_lib_path);
if let Some(ref rustdoc_path) = config.rustdoc_path {
-Subproject commit 39ee5747153bf13324870c4a912acbf1f9bfde3f
+Subproject commit 50ef22af522f2545295090cc1ad3e4bd4aa8632c
pub fn check(path: &Path, bad: &mut bool) {
use std::ffi::OsStr;
- const ALLOWED: &[&str] = &["configure"];
+ const ALLOWED: &[&str] = &["configure", "x"];
crate::walk_no_read(
path,
--- /dev/null
+#!/bin/sh
+
+# Modern Linux and macOS systems commonly only have a thing called `python3` and
+# not `python`, while Windows commonly does not have `python3`, so we cannot
+# directly use python in the x.py shebang and have it consistently work. Instead we
+# have a shell script to look for a python to run x.py.
+
+set -eu
+
+realpath() {
+ if [ -d "$1" ]; then
+ CDPATH='' command cd "$1" && pwd -P
+ else
+ echo "$(realpath "$(dirname "$1")")/$(basename "$1")"
+ fi
+}
+
+xpy=$(dirname "$(realpath "$0")")/x.py
+
+# On Windows, `py -3` sometimes works. We need to try it first because `python3`
+# sometimes tries to launch the app store on Windows.
+for SEARCH_PYTHON in py python3 python python2; do
+ if python=$(command -v $SEARCH_PYTHON) && [ -x "$python" ]; then
+ if [ $SEARCH_PYTHON = py ]; then
+ extra_arg="-3"
+ else
+ extra_arg=""
+ fi
+ exec "$python" $extra_arg "$xpy" "$@"
+ fi
+done
+echo "$0: error: did not find python installed" >&2
+exit 1
#!/usr/bin/env pwsh
-# See x.sh for why these scripts exist.
+# See ./x for why these scripts exist.
$xpy = Join-Path $PSScriptRoot x.py
# Start-Process for some reason splits arguments on spaces. (Isn't powershell supposed to be simpler than bash?)
#!/usr/bin/env python3
# Some systems don't have `python3` in their PATH. This isn't supported by x.py directly;
-# they should use `x.sh` or `x.ps1` instead.
+# they should use `x` or `x.ps1` instead.
# This file is only a "symlink" to bootstrap.py, all logic should go there.
+++ /dev/null
-#!/bin/sh
-
-# Modern Linux and macOS systems commonly only have a thing called `python3` and
-# not `python`, while Windows commonly does not have `python3`, so we cannot
-# directly use python in the x.py shebang and have it consistently work. Instead we
-# have a shell script to look for a python to run x.py.
-
-set -eu
-
-realpath() {
- if [ -d "$1" ]; then
- CDPATH='' command cd "$1" && pwd -P
- else
- echo "$(realpath "$(dirname "$1")")/$(basename "$1")"
- fi
-}
-
-xpy=$(dirname "$(realpath "$0")")/x.py
-
-# On Windows, `py -3` sometimes works. We need to try it first because `python3`
-# sometimes tries to launch the app store on Windows.
-for SEARCH_PYTHON in py python3 python python2; do
- if python=$(command -v $SEARCH_PYTHON) && [ -x "$python" ]; then
- if [ $SEARCH_PYTHON = py ]; then
- extra_arg="-3"
- else
- extra_arg=""
- fi
- exec "$python" $extra_arg "$xpy" "$@"
- fi
-done
-echo "$0: error: did not find python installed" >&2
-exit 1