1
Fork 0

Auto merge of #107451 - matthiaskrgr:rollup-m4ucfu8, r=matthiaskrgr

Rollup of 11 pull requests

Successful merges:

 - #96763 (Fix maintainer validation message)
 - #106540 (Insert whitespace to avoid ident concatenation in suggestion)
 - #106763 (print why a test was ignored if its the only test specified)
 - #106769 (libtest: Print why a test was ignored if it's the only test specified.)
 - #106798 (Implement `signum` with `Ord`)
 - #107006 (Output tree representation on thir-tree)
 - #107078 (Update wording of invalid_doc_attributes docs.)
 - #107169 (Pass `--locked` to the x test tidy call)
 - #107431 (docs: remove colon from time header)
 - #107432 (rustdoc: remove unused class `has-srclink`)
 - #107448 (When stamp doesn't exist, should say Error, and print path to stamp file)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2023-01-29 19:29:49 +00:00
commit e972bc8083
79 changed files with 1553 additions and 233 deletions

View file

@ -498,6 +498,21 @@ fn print_with_analysis(tcx: TyCtxt<'_>, ppm: PpMode) -> Result<(), ErrorGuarante
out out
} }
ThirFlat => {
let mut out = String::new();
abort_on_err(rustc_hir_analysis::check_crate(tcx), tcx.sess);
debug!("pretty printing THIR flat");
for did in tcx.hir().body_owners() {
let _ = writeln!(
out,
"{:?}:\n{}\n",
did,
tcx.thir_flat(ty::WithOptConstParam::unknown(did))
);
}
out
}
_ => unreachable!(), _ => unreachable!(),
}; };

View file

@ -3531,9 +3531,15 @@ declare_lint! {
/// ///
/// ### Explanation /// ### Explanation
/// ///
/// Previously, there were very like checks being performed on `#[doc(..)]` /// Previously, incorrect usage of the `#[doc(..)]` attribute was not
/// unlike the other attributes. It'll now catch all the issues that it /// being validated. Usually these should be rejected as a hard error,
/// silently ignored previously. /// but this lint was introduced to avoid breaking any existing
/// crates which included them.
///
/// This is a [future-incompatible] lint to transition this to a hard
/// error in the future. See [issue #82730] for more details.
///
/// [issue #82730]: https://github.com/rust-lang/rust/issues/82730
pub INVALID_DOC_ATTRIBUTES, pub INVALID_DOC_ATTRIBUTES,
Warn, Warn,
"detects invalid `#[doc(...)]` attributes", "detects invalid `#[doc(...)]` attributes",

View file

@ -361,6 +361,13 @@ rustc_queries! {
desc { |tcx| "constructing THIR tree for `{}`", tcx.def_path_str(key.did.to_def_id()) } desc { |tcx| "constructing THIR tree for `{}`", tcx.def_path_str(key.did.to_def_id()) }
} }
/// Create a list-like THIR representation for debugging.
query thir_flat(key: ty::WithOptConstParam<LocalDefId>) -> String {
no_hash
arena_cache
desc { |tcx| "constructing flat THIR representation for `{}`", tcx.def_path_str(key.did.to_def_id()) }
}
/// Set of all the `DefId`s in this crate that have MIR associated with /// Set of all the `DefId`s in this crate that have MIR associated with
/// them. This includes all the body owners, but also things like struct /// them. This includes all the body owners, but also things like struct
/// constructors. /// constructors.

View file

@ -29,6 +29,7 @@ use rustc_target::asm::InlineAsmRegOrRegClass;
use std::fmt; use std::fmt;
use std::ops::Index; use std::ops::Index;
pub mod print;
pub mod visit; pub mod visit;
macro_rules! thir_with_elements { macro_rules! thir_with_elements {

View file

@ -0,0 +1,881 @@
use crate::thir::*;
use crate::ty::{self, TyCtxt};
use std::fmt::{self, Write};
impl<'tcx> TyCtxt<'tcx> {
pub fn thir_tree_representation<'a>(self, thir: &'a Thir<'tcx>) -> String {
let mut printer = ThirPrinter::new(thir);
printer.print();
printer.into_buffer()
}
}
struct ThirPrinter<'a, 'tcx> {
thir: &'a Thir<'tcx>,
fmt: String,
}
const INDENT: &str = " ";
macro_rules! print_indented {
($writer:ident, $s:expr, $indent_lvl:expr) => {
let indent = (0..$indent_lvl).map(|_| INDENT).collect::<Vec<_>>().concat();
writeln!($writer, "{}{}", indent, $s).expect("unable to write to ThirPrinter");
};
}
impl<'a, 'tcx> Write for ThirPrinter<'a, 'tcx> {
fn write_str(&mut self, s: &str) -> fmt::Result {
self.fmt.push_str(s);
Ok(())
}
}
impl<'a, 'tcx> ThirPrinter<'a, 'tcx> {
fn new(thir: &'a Thir<'tcx>) -> Self {
Self { thir, fmt: String::new() }
}
fn print(&mut self) {
print_indented!(self, "params: [", 0);
for param in self.thir.params.iter() {
self.print_param(param, 1);
}
print_indented!(self, "]", 0);
print_indented!(self, "body:", 0);
let expr = ExprId::from_usize(self.thir.exprs.len() - 1);
self.print_expr(expr, 1);
}
fn into_buffer(self) -> String {
self.fmt
}
fn print_param(&mut self, param: &Param<'tcx>, depth_lvl: usize) {
let Param { pat, ty, ty_span, self_kind, hir_id } = param;
print_indented!(self, "Param {", depth_lvl);
print_indented!(self, format!("ty: {:?}", ty), depth_lvl + 1);
print_indented!(self, format!("ty_span: {:?}", ty_span), depth_lvl + 1);
print_indented!(self, format!("self_kind: {:?}", self_kind), depth_lvl + 1);
print_indented!(self, format!("hir_id: {:?}", hir_id), depth_lvl + 1);
if let Some(pat) = pat {
print_indented!(self, "param: Some( ", depth_lvl + 1);
self.print_pat(pat, depth_lvl + 2);
print_indented!(self, ")", depth_lvl + 1);
} else {
print_indented!(self, "param: None", depth_lvl + 1);
}
print_indented!(self, "}", depth_lvl);
}
fn print_block(&mut self, block_id: BlockId, depth_lvl: usize) {
let Block {
targeted_by_break,
opt_destruction_scope,
span,
region_scope,
stmts,
expr,
safety_mode,
} = &self.thir.blocks[block_id];
print_indented!(self, "Block {", depth_lvl);
print_indented!(self, format!("targeted_by_break: {}", targeted_by_break), depth_lvl + 1);
print_indented!(
self,
format!("opt_destruction_scope: {:?}", opt_destruction_scope),
depth_lvl + 1
);
print_indented!(self, format!("span: {:?}", span), depth_lvl + 1);
print_indented!(self, format!("region_scope: {:?}", region_scope), depth_lvl + 1);
print_indented!(self, format!("safety_mode: {:?}", safety_mode), depth_lvl + 1);
if stmts.len() > 0 {
print_indented!(self, "stmts: [", depth_lvl + 1);
for stmt in stmts.iter() {
self.print_stmt(*stmt, depth_lvl + 2);
}
print_indented!(self, "]", depth_lvl + 1);
} else {
print_indented!(self, "stmts: []", depth_lvl + 1);
}
if let Some(expr_id) = expr {
print_indented!(self, "expr:", depth_lvl + 1);
self.print_expr(*expr_id, depth_lvl + 2);
} else {
print_indented!(self, "expr: []", depth_lvl + 1);
}
print_indented!(self, "}", depth_lvl);
}
fn print_stmt(&mut self, stmt_id: StmtId, depth_lvl: usize) {
let Stmt { kind, opt_destruction_scope } = &self.thir.stmts[stmt_id];
print_indented!(self, "Stmt {", depth_lvl);
print_indented!(
self,
format!("opt_destruction_scope: {:?}", opt_destruction_scope),
depth_lvl + 1
);
match kind {
StmtKind::Expr { scope, expr } => {
print_indented!(self, "kind: Expr {", depth_lvl + 1);
print_indented!(self, format!("scope: {:?}", scope), depth_lvl + 2);
print_indented!(self, "expr:", depth_lvl + 2);
self.print_expr(*expr, depth_lvl + 3);
print_indented!(self, "}", depth_lvl + 1);
}
StmtKind::Let {
remainder_scope,
init_scope,
pattern,
initializer,
else_block,
lint_level,
} => {
print_indented!(self, "kind: Let {", depth_lvl + 1);
print_indented!(
self,
format!("remainder_scope: {:?}", remainder_scope),
depth_lvl + 2
);
print_indented!(self, format!("init_scope: {:?}", init_scope), depth_lvl + 2);
print_indented!(self, "pattern: ", depth_lvl + 2);
self.print_pat(pattern, depth_lvl + 3);
print_indented!(self, ",", depth_lvl + 2);
if let Some(init) = initializer {
print_indented!(self, "initializer: Some(", depth_lvl + 2);
self.print_expr(*init, depth_lvl + 3);
print_indented!(self, ")", depth_lvl + 2);
} else {
print_indented!(self, "initializer: None", depth_lvl + 2);
}
if let Some(else_block) = else_block {
print_indented!(self, "else_block: Some(", depth_lvl + 2);
self.print_block(*else_block, depth_lvl + 3);
print_indented!(self, ")", depth_lvl + 2);
} else {
print_indented!(self, "else_block: None", depth_lvl + 2);
}
print_indented!(self, format!("lint_level: {:?}", lint_level), depth_lvl + 2);
print_indented!(self, "}", depth_lvl + 1);
}
}
print_indented!(self, "}", depth_lvl);
}
fn print_expr(&mut self, expr: ExprId, depth_lvl: usize) {
let Expr { ty, temp_lifetime, span, kind } = &self.thir[expr];
print_indented!(self, "Expr {", depth_lvl);
print_indented!(self, format!("ty: {:?}", ty), depth_lvl + 1);
print_indented!(self, format!("temp_lifetime: {:?}", temp_lifetime), depth_lvl + 1);
print_indented!(self, format!("span: {:?}", span), depth_lvl + 1);
print_indented!(self, "kind: ", depth_lvl + 1);
self.print_expr_kind(kind, depth_lvl + 2);
print_indented!(self, "}", depth_lvl);
}
fn print_expr_kind(&mut self, expr_kind: &ExprKind<'tcx>, depth_lvl: usize) {
use rustc_middle::thir::ExprKind::*;
match expr_kind {
Scope { region_scope, value, lint_level } => {
print_indented!(self, "Scope {", depth_lvl);
print_indented!(self, format!("region_scope: {:?}", region_scope), depth_lvl + 1);
print_indented!(self, format!("lint_level: {:?}", lint_level), depth_lvl + 1);
print_indented!(self, "value:", depth_lvl + 1);
self.print_expr(*value, depth_lvl + 2);
print_indented!(self, "}", depth_lvl);
}
Box { value } => {
print_indented!(self, "Box {", depth_lvl);
self.print_expr(*value, depth_lvl + 1);
print_indented!(self, "}", depth_lvl);
}
If { if_then_scope, cond, then, else_opt } => {
print_indented!(self, "If {", depth_lvl);
print_indented!(self, format!("if_then_scope: {:?}", if_then_scope), depth_lvl + 1);
print_indented!(self, "cond:", depth_lvl + 1);
self.print_expr(*cond, depth_lvl + 2);
print_indented!(self, "then:", depth_lvl + 1);
self.print_expr(*then, depth_lvl + 2);
if let Some(else_expr) = else_opt {
print_indented!(self, "else:", depth_lvl + 1);
self.print_expr(*else_expr, depth_lvl + 2);
}
print_indented!(self, "}", depth_lvl);
}
Call { fun, args, ty, from_hir_call, fn_span } => {
print_indented!(self, "Call {", depth_lvl);
print_indented!(self, format!("ty: {:?}", ty), depth_lvl + 1);
print_indented!(self, format!("from_hir_call: {}", from_hir_call), depth_lvl + 1);
print_indented!(self, format!("fn_span: {:?}", fn_span), depth_lvl + 1);
print_indented!(self, "fun:", depth_lvl + 1);
self.print_expr(*fun, depth_lvl + 2);
if args.len() > 0 {
print_indented!(self, "args: [", depth_lvl + 1);
for arg in args.iter() {
self.print_expr(*arg, depth_lvl + 2);
}
print_indented!(self, "]", depth_lvl + 1);
} else {
print_indented!(self, "args: []", depth_lvl + 1);
}
print_indented!(self, "}", depth_lvl);
}
Deref { arg } => {
print_indented!(self, "Deref {", depth_lvl);
self.print_expr(*arg, depth_lvl + 1);
print_indented!(self, "}", depth_lvl);
}
Binary { op, lhs, rhs } => {
print_indented!(self, "Binary {", depth_lvl);
print_indented!(self, format!("op: {:?}", op), depth_lvl + 1);
print_indented!(self, "lhs:", depth_lvl + 1);
self.print_expr(*lhs, depth_lvl + 2);
print_indented!(self, "rhs:", depth_lvl + 1);
self.print_expr(*rhs, depth_lvl + 2);
print_indented!(self, "}", depth_lvl);
}
LogicalOp { op, lhs, rhs } => {
print_indented!(self, "LogicalOp {", depth_lvl);
print_indented!(self, format!("op: {:?}", op), depth_lvl + 1);
print_indented!(self, "lhs:", depth_lvl + 1);
self.print_expr(*lhs, depth_lvl + 2);
print_indented!(self, "rhs:", depth_lvl + 1);
self.print_expr(*rhs, depth_lvl + 2);
print_indented!(self, "}", depth_lvl);
}
Unary { op, arg } => {
print_indented!(self, "Unary {", depth_lvl);
print_indented!(self, format!("op: {:?}", op), depth_lvl + 1);
print_indented!(self, "arg:", depth_lvl + 1);
self.print_expr(*arg, depth_lvl + 2);
print_indented!(self, "}", depth_lvl);
}
Cast { source } => {
print_indented!(self, "Cast {", depth_lvl);
print_indented!(self, "source:", depth_lvl + 1);
self.print_expr(*source, depth_lvl + 2);
print_indented!(self, "}", depth_lvl);
}
Use { source } => {
print_indented!(self, "Use {", depth_lvl);
print_indented!(self, "source:", depth_lvl + 1);
self.print_expr(*source, depth_lvl + 2);
print_indented!(self, "}", depth_lvl);
}
NeverToAny { source } => {
print_indented!(self, "NeverToAny {", depth_lvl);
print_indented!(self, "source:", depth_lvl + 1);
self.print_expr(*source, depth_lvl + 2);
print_indented!(self, "}", depth_lvl);
}
Pointer { cast, source } => {
print_indented!(self, "Pointer {", depth_lvl);
print_indented!(self, format!("cast: {:?}", cast), depth_lvl + 1);
print_indented!(self, "source:", depth_lvl + 1);
self.print_expr(*source, depth_lvl + 2);
print_indented!(self, "}", depth_lvl);
}
Loop { body } => {
print_indented!(self, "Loop (", depth_lvl);
print_indented!(self, "body:", depth_lvl + 1);
self.print_expr(*body, depth_lvl + 2);
print_indented!(self, ")", depth_lvl);
}
Let { expr, pat } => {
print_indented!(self, "Let {", depth_lvl);
print_indented!(self, "expr:", depth_lvl + 1);
self.print_expr(*expr, depth_lvl + 2);
print_indented!(self, format!("pat: {:?}", pat), depth_lvl + 1);
print_indented!(self, "}", depth_lvl);
}
Match { scrutinee, arms } => {
print_indented!(self, "Match {", depth_lvl);
print_indented!(self, "scrutinee:", depth_lvl + 1);
self.print_expr(*scrutinee, depth_lvl + 2);
print_indented!(self, "arms: [", depth_lvl + 1);
for arm_id in arms.iter() {
self.print_arm(*arm_id, depth_lvl + 2);
}
print_indented!(self, "]", depth_lvl + 1);
print_indented!(self, "}", depth_lvl);
}
Block { block } => self.print_block(*block, depth_lvl),
Assign { lhs, rhs } => {
print_indented!(self, "Assign {", depth_lvl);
print_indented!(self, "lhs:", depth_lvl + 1);
self.print_expr(*lhs, depth_lvl + 2);
print_indented!(self, "rhs:", depth_lvl + 1);
self.print_expr(*rhs, depth_lvl + 2);
print_indented!(self, "}", depth_lvl);
}
AssignOp { op, lhs, rhs } => {
print_indented!(self, "AssignOp {", depth_lvl);
print_indented!(self, format!("op: {:?}", op), depth_lvl + 1);
print_indented!(self, "lhs:", depth_lvl + 1);
self.print_expr(*lhs, depth_lvl + 2);
print_indented!(self, "rhs:", depth_lvl + 1);
self.print_expr(*rhs, depth_lvl + 2);
print_indented!(self, "}", depth_lvl);
}
Field { lhs, variant_index, name } => {
print_indented!(self, "Field {", depth_lvl);
print_indented!(self, format!("variant_index: {:?}", variant_index), depth_lvl + 1);
print_indented!(self, format!("name: {:?}", name), depth_lvl + 1);
print_indented!(self, "lhs:", depth_lvl + 1);
self.print_expr(*lhs, depth_lvl + 2);
print_indented!(self, "}", depth_lvl);
}
Index { lhs, index } => {
print_indented!(self, "Index {", depth_lvl);
print_indented!(self, format!("index: {:?}", index), depth_lvl + 1);
print_indented!(self, "lhs:", depth_lvl + 1);
self.print_expr(*lhs, depth_lvl + 2);
print_indented!(self, "}", depth_lvl);
}
VarRef { id } => {
print_indented!(self, "VarRef {", depth_lvl);
print_indented!(self, format!("id: {:?}", id), depth_lvl + 1);
print_indented!(self, "}", depth_lvl);
}
UpvarRef { closure_def_id, var_hir_id } => {
print_indented!(self, "UpvarRef {", depth_lvl);
print_indented!(
self,
format!("closure_def_id: {:?}", closure_def_id),
depth_lvl + 1
);
print_indented!(self, format!("var_hir_id: {:?}", var_hir_id), depth_lvl + 1);
print_indented!(self, "}", depth_lvl);
}
Borrow { borrow_kind, arg } => {
print_indented!(self, "Borrow (", depth_lvl);
print_indented!(self, format!("borrow_kind: {:?}", borrow_kind), depth_lvl + 1);
print_indented!(self, "arg:", depth_lvl + 1);
self.print_expr(*arg, depth_lvl + 2);
print_indented!(self, ")", depth_lvl);
}
AddressOf { mutability, arg } => {
print_indented!(self, "AddressOf {", depth_lvl);
print_indented!(self, format!("mutability: {:?}", mutability), depth_lvl + 1);
print_indented!(self, "arg:", depth_lvl + 1);
self.print_expr(*arg, depth_lvl + 2);
print_indented!(self, "}", depth_lvl);
}
Break { label, value } => {
print_indented!(self, "Break (", depth_lvl);
print_indented!(self, format!("label: {:?}", label), depth_lvl + 1);
if let Some(value) = value {
print_indented!(self, "value:", depth_lvl + 1);
self.print_expr(*value, depth_lvl + 2);
}
print_indented!(self, ")", depth_lvl);
}
Continue { label } => {
print_indented!(self, "Continue {", depth_lvl);
print_indented!(self, format!("label: {:?}", label), depth_lvl + 1);
print_indented!(self, "}", depth_lvl);
}
Return { value } => {
print_indented!(self, "Return {", depth_lvl);
print_indented!(self, "value:", depth_lvl + 1);
if let Some(value) = value {
self.print_expr(*value, depth_lvl + 2);
}
print_indented!(self, "}", depth_lvl);
}
ConstBlock { did, substs } => {
print_indented!(self, "ConstBlock {", depth_lvl);
print_indented!(self, format!("did: {:?}", did), depth_lvl + 1);
print_indented!(self, format!("substs: {:?}", substs), depth_lvl + 1);
print_indented!(self, "}", depth_lvl);
}
Repeat { value, count } => {
print_indented!(self, "Repeat {", depth_lvl);
print_indented!(self, format!("count: {:?}", count), depth_lvl + 1);
print_indented!(self, "value:", depth_lvl + 1);
self.print_expr(*value, depth_lvl + 2);
print_indented!(self, "}", depth_lvl);
}
Array { fields } => {
print_indented!(self, "Array {", depth_lvl);
print_indented!(self, "fields: [", depth_lvl + 1);
for field_id in fields.iter() {
self.print_expr(*field_id, depth_lvl + 2);
}
print_indented!(self, "]", depth_lvl + 1);
print_indented!(self, "}", depth_lvl);
}
Tuple { fields } => {
print_indented!(self, "Tuple {", depth_lvl);
print_indented!(self, "fields: [", depth_lvl + 1);
for field_id in fields.iter() {
self.print_expr(*field_id, depth_lvl + 2);
}
print_indented!(self, "]", depth_lvl + 1);
print_indented!(self, "}", depth_lvl);
}
Adt(adt_expr) => {
print_indented!(self, "Adt {", depth_lvl);
self.print_adt_expr(&**adt_expr, depth_lvl + 1);
print_indented!(self, "}", depth_lvl);
}
PlaceTypeAscription { source, user_ty } => {
print_indented!(self, "PlaceTypeAscription {", depth_lvl);
print_indented!(self, format!("user_ty: {:?}", user_ty), depth_lvl + 1);
print_indented!(self, "source:", depth_lvl + 1);
self.print_expr(*source, depth_lvl + 2);
print_indented!(self, "}", depth_lvl);
}
ValueTypeAscription { source, user_ty } => {
print_indented!(self, "ValueTypeAscription {", depth_lvl);
print_indented!(self, format!("user_ty: {:?}", user_ty), depth_lvl + 1);
print_indented!(self, "source:", depth_lvl + 1);
self.print_expr(*source, depth_lvl + 2);
print_indented!(self, "}", depth_lvl);
}
Closure(closure_expr) => {
print_indented!(self, "Closure {", depth_lvl);
print_indented!(self, "closure_expr:", depth_lvl + 1);
self.print_closure_expr(&**closure_expr, depth_lvl + 2);
print_indented!(self, "}", depth_lvl);
}
Literal { lit, neg } => {
print_indented!(
self,
format!("Literal( lit: {:?}, neg: {:?})\n", lit, neg),
depth_lvl
);
}
NonHirLiteral { lit, user_ty } => {
print_indented!(self, "NonHirLiteral {", depth_lvl);
print_indented!(self, format!("lit: {:?}", lit), depth_lvl + 1);
print_indented!(self, format!("user_ty: {:?}", user_ty), depth_lvl + 1);
print_indented!(self, "}", depth_lvl);
}
ZstLiteral { user_ty } => {
print_indented!(self, format!("ZstLiteral(user_ty: {:?})", user_ty), depth_lvl);
}
NamedConst { def_id, substs, user_ty } => {
print_indented!(self, "NamedConst {", depth_lvl);
print_indented!(self, format!("def_id: {:?}", def_id), depth_lvl + 1);
print_indented!(self, format!("user_ty: {:?}", user_ty), depth_lvl + 1);
print_indented!(self, format!("substs: {:?}", substs), depth_lvl + 1);
print_indented!(self, "}", depth_lvl);
}
ConstParam { param, def_id } => {
print_indented!(self, "ConstParam {", depth_lvl);
print_indented!(self, format!("def_id: {:?}", def_id), depth_lvl + 1);
print_indented!(self, format!("param: {:?}", param), depth_lvl + 1);
print_indented!(self, "}", depth_lvl);
}
StaticRef { alloc_id, ty, def_id } => {
print_indented!(self, "StaticRef {", depth_lvl);
print_indented!(self, format!("def_id: {:?}", def_id), depth_lvl + 1);
print_indented!(self, format!("ty: {:?}", ty), depth_lvl + 1);
print_indented!(self, format!("alloc_id: {:?}", alloc_id), depth_lvl + 1);
print_indented!(self, "}", depth_lvl);
}
InlineAsm(expr) => {
print_indented!(self, "InlineAsm {", depth_lvl);
print_indented!(self, "expr:", depth_lvl + 1);
self.print_inline_asm_expr(&**expr, depth_lvl + 2);
print_indented!(self, "}", depth_lvl);
}
ThreadLocalRef(def_id) => {
print_indented!(self, "ThreadLocalRef {", depth_lvl);
print_indented!(self, format!("def_id: {:?}", def_id), depth_lvl + 1);
print_indented!(self, "}", depth_lvl);
}
Yield { value } => {
print_indented!(self, "Yield {", depth_lvl);
print_indented!(self, "value:", depth_lvl + 1);
self.print_expr(*value, depth_lvl + 2);
print_indented!(self, "}", depth_lvl);
}
}
}
fn print_adt_expr(&mut self, adt_expr: &AdtExpr<'tcx>, depth_lvl: usize) {
print_indented!(self, "adt_def:", depth_lvl);
self.print_adt_def(adt_expr.adt_def, depth_lvl + 1);
print_indented!(
self,
format!("variant_index: {:?}", adt_expr.variant_index),
depth_lvl + 1
);
print_indented!(self, format!("substs: {:?}", adt_expr.substs), depth_lvl + 1);
print_indented!(self, format!("user_ty: {:?}", adt_expr.user_ty), depth_lvl + 1);
for (i, field_expr) in adt_expr.fields.iter().enumerate() {
print_indented!(self, format!("field {}:", i), depth_lvl + 1);
self.print_expr(field_expr.expr, depth_lvl + 2);
}
if let Some(ref base) = adt_expr.base {
print_indented!(self, "base:", depth_lvl + 1);
self.print_fru_info(base, depth_lvl + 2);
} else {
print_indented!(self, "base: None", depth_lvl + 1);
}
}
fn print_adt_def(&mut self, adt_def: ty::AdtDef<'tcx>, depth_lvl: usize) {
print_indented!(self, "AdtDef {", depth_lvl);
print_indented!(self, format!("did: {:?}", adt_def.did()), depth_lvl + 1);
print_indented!(self, format!("variants: {:?}", adt_def.variants()), depth_lvl + 1);
print_indented!(self, format!("flags: {:?}", adt_def.flags()), depth_lvl + 1);
print_indented!(self, format!("repr: {:?}", adt_def.repr()), depth_lvl + 1);
}
fn print_fru_info(&mut self, fru_info: &FruInfo<'tcx>, depth_lvl: usize) {
print_indented!(self, "FruInfo {", depth_lvl);
print_indented!(self, "base: ", depth_lvl + 1);
self.print_expr(fru_info.base, depth_lvl + 2);
print_indented!(self, "field_types: [", depth_lvl + 1);
for ty in fru_info.field_types.iter() {
print_indented!(self, format!("ty: {:?}", ty), depth_lvl + 2);
}
print_indented!(self, "}", depth_lvl);
}
fn print_arm(&mut self, arm_id: ArmId, depth_lvl: usize) {
print_indented!(self, "Arm {", depth_lvl);
let arm = &self.thir.arms[arm_id];
let Arm { pattern, guard, body, lint_level, scope, span } = arm;
print_indented!(self, "pattern: ", depth_lvl + 1);
self.print_pat(pattern, depth_lvl + 2);
if let Some(guard) = guard {
print_indented!(self, "guard: ", depth_lvl + 1);
self.print_guard(guard, depth_lvl + 2);
} else {
print_indented!(self, "guard: None", depth_lvl + 1);
}
print_indented!(self, "body: ", depth_lvl + 1);
self.print_expr(*body, depth_lvl + 2);
print_indented!(self, format!("lint_level: {:?}", lint_level), depth_lvl + 1);
print_indented!(self, format!("scope: {:?}", scope), depth_lvl + 1);
print_indented!(self, format!("span: {:?}", span), depth_lvl + 1);
print_indented!(self, "}", depth_lvl);
}
fn print_pat(&mut self, pat: &Box<Pat<'tcx>>, depth_lvl: usize) {
let Pat { ty, span, kind } = &**pat;
print_indented!(self, "Pat: {", depth_lvl);
print_indented!(self, format!("ty: {:?}", ty), depth_lvl + 1);
print_indented!(self, format!("span: {:?}", span), depth_lvl + 1);
self.print_pat_kind(kind, depth_lvl + 1);
print_indented!(self, "}", depth_lvl);
}
fn print_pat_kind(&mut self, pat_kind: &PatKind<'tcx>, depth_lvl: usize) {
print_indented!(self, "kind: PatKind {", depth_lvl);
match pat_kind {
PatKind::Wild => {
print_indented!(self, "Wild", depth_lvl + 1);
}
PatKind::AscribeUserType { ascription, subpattern } => {
print_indented!(self, "AscribeUserType: {", depth_lvl + 1);
print_indented!(self, format!("ascription: {:?}", ascription), depth_lvl + 2);
print_indented!(self, "subpattern: ", depth_lvl + 2);
self.print_pat(subpattern, depth_lvl + 3);
print_indented!(self, "}", depth_lvl + 1);
}
PatKind::Binding { mutability, name, mode, var, ty, subpattern, is_primary } => {
print_indented!(self, "Binding {", depth_lvl + 1);
print_indented!(self, format!("mutability: {:?}", mutability), depth_lvl + 2);
print_indented!(self, format!("name: {:?}", name), depth_lvl + 2);
print_indented!(self, format!("mode: {:?}", mode), depth_lvl + 2);
print_indented!(self, format!("var: {:?}", var), depth_lvl + 2);
print_indented!(self, format!("ty: {:?}", ty), depth_lvl + 2);
print_indented!(self, format!("is_primary: {:?}", is_primary), depth_lvl + 2);
if let Some(subpattern) = subpattern {
print_indented!(self, "subpattern: Some( ", depth_lvl + 2);
self.print_pat(subpattern, depth_lvl + 3);
print_indented!(self, ")", depth_lvl + 2);
} else {
print_indented!(self, "subpattern: None", depth_lvl + 2);
}
print_indented!(self, "}", depth_lvl + 1);
}
PatKind::Variant { adt_def, substs, variant_index, subpatterns } => {
print_indented!(self, "Variant {", depth_lvl + 1);
print_indented!(self, "adt_def: ", depth_lvl + 2);
self.print_adt_def(*adt_def, depth_lvl + 3);
print_indented!(self, format!("substs: {:?}", substs), depth_lvl + 2);
print_indented!(self, format!("variant_index: {:?}", variant_index), depth_lvl + 2);
if subpatterns.len() > 0 {
print_indented!(self, "subpatterns: [", depth_lvl + 2);
for field_pat in subpatterns.iter() {
self.print_pat(&field_pat.pattern, depth_lvl + 3);
}
print_indented!(self, "]", depth_lvl + 2);
} else {
print_indented!(self, "subpatterns: []", depth_lvl + 2);
}
print_indented!(self, "}", depth_lvl + 1);
}
PatKind::Leaf { subpatterns } => {
print_indented!(self, "Leaf { ", depth_lvl + 1);
print_indented!(self, "subpatterns: [", depth_lvl + 2);
for field_pat in subpatterns.iter() {
self.print_pat(&field_pat.pattern, depth_lvl + 3);
}
print_indented!(self, "]", depth_lvl + 2);
print_indented!(self, "}", depth_lvl + 1);
}
PatKind::Deref { subpattern } => {
print_indented!(self, "Deref { ", depth_lvl + 1);
print_indented!(self, "subpattern: ", depth_lvl + 2);
self.print_pat(subpattern, depth_lvl + 2);
print_indented!(self, "}", depth_lvl + 1);
}
PatKind::Constant { value } => {
print_indented!(self, "Constant {", depth_lvl + 1);
print_indented!(self, format!("value: {:?}", value), depth_lvl + 2);
print_indented!(self, "}", depth_lvl + 1);
}
PatKind::Range(pat_range) => {
print_indented!(self, format!("Range ( {:?} )", pat_range), depth_lvl + 1);
}
PatKind::Slice { prefix, slice, suffix } => {
print_indented!(self, "Slice {", depth_lvl + 1);
print_indented!(self, "prefix: [", depth_lvl + 2);
for prefix_pat in prefix.iter() {
self.print_pat(prefix_pat, depth_lvl + 3);
}
print_indented!(self, "]", depth_lvl + 2);
if let Some(slice) = slice {
print_indented!(self, "slice: ", depth_lvl + 2);
self.print_pat(slice, depth_lvl + 3);
}
print_indented!(self, "suffix: [", depth_lvl + 2);
for suffix_pat in suffix.iter() {
self.print_pat(suffix_pat, depth_lvl + 3);
}
print_indented!(self, "]", depth_lvl + 2);
print_indented!(self, "}", depth_lvl + 1);
}
PatKind::Array { prefix, slice, suffix } => {
print_indented!(self, "Array {", depth_lvl + 1);
print_indented!(self, "prefix: [", depth_lvl + 2);
for prefix_pat in prefix.iter() {
self.print_pat(prefix_pat, depth_lvl + 3);
}
print_indented!(self, "]", depth_lvl + 2);
if let Some(slice) = slice {
print_indented!(self, "slice: ", depth_lvl + 2);
self.print_pat(slice, depth_lvl + 3);
}
print_indented!(self, "suffix: [", depth_lvl + 2);
for suffix_pat in suffix.iter() {
self.print_pat(suffix_pat, depth_lvl + 3);
}
print_indented!(self, "]", depth_lvl + 2);
print_indented!(self, "}", depth_lvl + 1);
}
PatKind::Or { pats } => {
print_indented!(self, "Or {", depth_lvl + 1);
print_indented!(self, "pats: [", depth_lvl + 2);
for pat in pats.iter() {
self.print_pat(pat, depth_lvl + 3);
}
print_indented!(self, "]", depth_lvl + 2);
print_indented!(self, "}", depth_lvl + 1);
}
}
print_indented!(self, "}", depth_lvl);
}
fn print_guard(&mut self, guard: &Guard<'tcx>, depth_lvl: usize) {
print_indented!(self, "Guard {", depth_lvl);
match guard {
Guard::If(expr_id) => {
print_indented!(self, "If (", depth_lvl + 1);
self.print_expr(*expr_id, depth_lvl + 2);
print_indented!(self, ")", depth_lvl + 1);
}
Guard::IfLet(pat, expr_id) => {
print_indented!(self, "IfLet (", depth_lvl + 1);
self.print_pat(pat, depth_lvl + 2);
print_indented!(self, ",", depth_lvl + 1);
self.print_expr(*expr_id, depth_lvl + 2);
print_indented!(self, ")", depth_lvl + 1);
}
}
print_indented!(self, "}", depth_lvl);
}
fn print_closure_expr(&mut self, expr: &ClosureExpr<'tcx>, depth_lvl: usize) {
let ClosureExpr { closure_id, substs, upvars, movability, fake_reads } = expr;
print_indented!(self, "ClosureExpr {", depth_lvl);
print_indented!(self, format!("closure_id: {:?}", closure_id), depth_lvl + 1);
print_indented!(self, format!("substs: {:?}", substs), depth_lvl + 1);
if upvars.len() > 0 {
print_indented!(self, "upvars: [", depth_lvl + 1);
for upvar in upvars.iter() {
self.print_expr(*upvar, depth_lvl + 2);
print_indented!(self, ",", depth_lvl + 1);
}
print_indented!(self, "]", depth_lvl + 1);
} else {
print_indented!(self, "upvars: []", depth_lvl + 1);
}
print_indented!(self, format!("movability: {:?}", movability), depth_lvl + 1);
if fake_reads.len() > 0 {
print_indented!(self, "fake_reads: [", depth_lvl + 1);
for (fake_read_expr, cause, hir_id) in fake_reads.iter() {
print_indented!(self, "(", depth_lvl + 2);
self.print_expr(*fake_read_expr, depth_lvl + 3);
print_indented!(self, ",", depth_lvl + 2);
print_indented!(self, format!("cause: {:?}", cause), depth_lvl + 3);
print_indented!(self, ",", depth_lvl + 2);
print_indented!(self, format!("hir_id: {:?}", hir_id), depth_lvl + 3);
print_indented!(self, "),", depth_lvl + 2);
}
print_indented!(self, "]", depth_lvl + 1);
} else {
print_indented!(self, "fake_reads: []", depth_lvl + 1);
}
print_indented!(self, "}", depth_lvl);
}
fn print_inline_asm_expr(&mut self, expr: &InlineAsmExpr<'tcx>, depth_lvl: usize) {
let InlineAsmExpr { template, operands, options, line_spans } = expr;
print_indented!(self, "InlineAsmExpr {", depth_lvl);
print_indented!(self, "template: [", depth_lvl + 1);
for template_piece in template.iter() {
print_indented!(self, format!("{:?}", template_piece), depth_lvl + 2);
}
print_indented!(self, "]", depth_lvl + 1);
print_indented!(self, "operands: [", depth_lvl + 1);
for operand in operands.iter() {
self.print_inline_operand(operand, depth_lvl + 2);
}
print_indented!(self, "]", depth_lvl + 1);
print_indented!(self, format!("options: {:?}", options), depth_lvl + 1);
print_indented!(self, format!("line_spans: {:?}", line_spans), depth_lvl + 1);
}
fn print_inline_operand(&mut self, operand: &InlineAsmOperand<'tcx>, depth_lvl: usize) {
match operand {
InlineAsmOperand::In { reg, expr } => {
print_indented!(self, "InlineAsmOperand::In {", depth_lvl);
print_indented!(self, format!("reg: {:?}", reg), depth_lvl + 1);
print_indented!(self, "expr: ", depth_lvl + 1);
self.print_expr(*expr, depth_lvl + 2);
print_indented!(self, "}", depth_lvl + 1);
}
InlineAsmOperand::Out { reg, late, expr } => {
print_indented!(self, "InlineAsmOperand::Out {", depth_lvl);
print_indented!(self, format!("reg: {:?}", reg), depth_lvl + 1);
print_indented!(self, format!("late: {:?}", late), depth_lvl + 1);
if let Some(out) = expr {
print_indented!(self, "place: Some( ", depth_lvl + 1);
self.print_expr(*out, depth_lvl + 2);
print_indented!(self, ")", depth_lvl + 1);
} else {
print_indented!(self, "place: None", depth_lvl + 1);
}
print_indented!(self, "}", depth_lvl + 1);
}
InlineAsmOperand::InOut { reg, late, expr } => {
print_indented!(self, "InlineAsmOperand::InOut {", depth_lvl);
print_indented!(self, format!("reg: {:?}", reg), depth_lvl + 1);
print_indented!(self, format!("late: {:?}", late), depth_lvl + 1);
print_indented!(self, "expr: ", depth_lvl + 1);
self.print_expr(*expr, depth_lvl + 2);
print_indented!(self, "}", depth_lvl + 1);
}
InlineAsmOperand::SplitInOut { reg, late, in_expr, out_expr } => {
print_indented!(self, "InlineAsmOperand::SplitInOut {", depth_lvl);
print_indented!(self, format!("reg: {:?}", reg), depth_lvl + 1);
print_indented!(self, format!("late: {:?}", late), depth_lvl + 1);
print_indented!(self, "in_expr: ", depth_lvl + 1);
self.print_expr(*in_expr, depth_lvl + 2);
if let Some(out_expr) = out_expr {
print_indented!(self, "out_expr: Some( ", depth_lvl + 1);
self.print_expr(*out_expr, depth_lvl + 2);
print_indented!(self, ")", depth_lvl + 1);
} else {
print_indented!(self, "out_expr: None", depth_lvl + 1);
}
print_indented!(self, "}", depth_lvl + 1);
}
InlineAsmOperand::Const { value, span } => {
print_indented!(self, "InlineAsmOperand::Const {", depth_lvl);
print_indented!(self, format!("value: {:?}", value), depth_lvl + 1);
print_indented!(self, format!("span: {:?}", span), depth_lvl + 1);
print_indented!(self, "}", depth_lvl + 1);
}
InlineAsmOperand::SymFn { value, span } => {
print_indented!(self, "InlineAsmOperand::SymFn {", depth_lvl);
print_indented!(self, format!("value: {:?}", *value), depth_lvl + 1);
print_indented!(self, format!("span: {:?}", span), depth_lvl + 1);
print_indented!(self, "}", depth_lvl + 1);
}
InlineAsmOperand::SymStatic { def_id } => {
print_indented!(self, "InlineAsmOperand::SymStatic {", depth_lvl);
print_indented!(self, format!("def_id: {:?}", def_id), depth_lvl + 1);
print_indented!(self, "}", depth_lvl + 1);
}
}
}
}

View file

@ -439,6 +439,10 @@ fn construct_fn<'tcx>(
let fn_id = tcx.hir().local_def_id_to_hir_id(fn_def.did); let fn_id = tcx.hir().local_def_id_to_hir_id(fn_def.did);
let generator_kind = tcx.generator_kind(fn_def.did); let generator_kind = tcx.generator_kind(fn_def.did);
// The representation of thir for `-Zunpretty=thir-tree` relies on
// the entry expression being the last element of `thir.exprs`.
assert_eq!(expr.as_usize(), thir.exprs.len() - 1);
// Figure out what primary body this item has. // Figure out what primary body this item has.
let body_id = tcx.hir().body_owned_by(fn_def.did); let body_id = tcx.hir().body_owned_by(fn_def.did);
let span_with_body = tcx.hir().span_with_body(fn_id); let span_with_body = tcx.hir().span_with_body(fn_id);

View file

@ -34,4 +34,5 @@ pub fn provide(providers: &mut Providers) {
providers.thir_check_unsafety_for_const_arg = check_unsafety::thir_check_unsafety_for_const_arg; providers.thir_check_unsafety_for_const_arg = check_unsafety::thir_check_unsafety_for_const_arg;
providers.thir_body = thir::cx::thir_body; providers.thir_body = thir::cx::thir_body;
providers.thir_tree = thir::cx::thir_tree; providers.thir_tree = thir::cx::thir_tree;
providers.thir_flat = thir::cx::thir_flat;
} }

View file

@ -53,6 +53,16 @@ pub(crate) fn thir_body(
} }
pub(crate) fn thir_tree(tcx: TyCtxt<'_>, owner_def: ty::WithOptConstParam<LocalDefId>) -> String { pub(crate) fn thir_tree(tcx: TyCtxt<'_>, owner_def: ty::WithOptConstParam<LocalDefId>) -> String {
match thir_body(tcx, owner_def) {
Ok((thir, _)) => {
let thir = thir.steal();
tcx.thir_tree_representation(&thir)
}
Err(_) => "error".into(),
}
}
pub(crate) fn thir_flat(tcx: TyCtxt<'_>, owner_def: ty::WithOptConstParam<LocalDefId>) -> String {
match thir_body(tcx, owner_def) { match thir_body(tcx, owner_def) {
Ok((thir, _)) => format!("{:#?}", thir.steal()), Ok((thir, _)) => format!("{:#?}", thir.steal()),
Err(_) => "error".into(), Err(_) => "error".into(),

View file

@ -1048,7 +1048,7 @@ impl<'a> Parser<'a> {
self.parse_remaining_bounds(bounds, true)?; self.parse_remaining_bounds(bounds, true)?;
self.expect(&token::CloseDelim(Delimiter::Parenthesis))?; self.expect(&token::CloseDelim(Delimiter::Parenthesis))?;
let sp = vec![lo, self.prev_token.span]; let sp = vec![lo, self.prev_token.span];
let sugg: Vec<_> = sp.iter().map(|sp| (*sp, String::new())).collect(); let sugg = vec![(lo, String::from(" ")), (self.prev_token.span, String::new())];
self.struct_span_err(sp, "incorrect braces around trait bounds") self.struct_span_err(sp, "incorrect braces around trait bounds")
.multipart_suggestion( .multipart_suggestion(
"remove the parentheses", "remove the parentheses",

View file

@ -2573,6 +2573,7 @@ fn parse_pretty(unstable_opts: &UnstableOptions, efmt: ErrorOutputType) -> Optio
"hir,typed" => Hir(PpHirMode::Typed), "hir,typed" => Hir(PpHirMode::Typed),
"hir-tree" => HirTree, "hir-tree" => HirTree,
"thir-tree" => ThirTree, "thir-tree" => ThirTree,
"thir-flat" => ThirFlat,
"mir" => Mir, "mir" => Mir,
"mir-cfg" => MirCFG, "mir-cfg" => MirCFG,
name => early_error( name => early_error(
@ -2581,7 +2582,8 @@ fn parse_pretty(unstable_opts: &UnstableOptions, efmt: ErrorOutputType) -> Optio
"argument to `unpretty` must be one of `normal`, `identified`, \ "argument to `unpretty` must be one of `normal`, `identified`, \
`expanded`, `expanded,identified`, `expanded,hygiene`, \ `expanded`, `expanded,identified`, `expanded,hygiene`, \
`ast-tree`, `ast-tree,expanded`, `hir`, `hir,identified`, \ `ast-tree`, `ast-tree,expanded`, `hir`, `hir,identified`, \
`hir,typed`, `hir-tree`, `thir-tree`, `mir` or `mir-cfg`; got {name}" `hir,typed`, `hir-tree`, `thir-tree`, `thir-flat`, `mir` or \
`mir-cfg`; got {name}"
), ),
), ),
}; };
@ -2736,6 +2738,8 @@ pub enum PpMode {
HirTree, HirTree,
/// `-Zunpretty=thir-tree` /// `-Zunpretty=thir-tree`
ThirTree, ThirTree,
/// `-Zunpretty=`thir-flat`
ThirFlat,
/// `-Zunpretty=mir` /// `-Zunpretty=mir`
Mir, Mir,
/// `-Zunpretty=mir-cfg` /// `-Zunpretty=mir-cfg`
@ -2754,6 +2758,7 @@ impl PpMode {
| Hir(_) | Hir(_)
| HirTree | HirTree
| ThirTree | ThirTree
| ThirFlat
| Mir | Mir
| MirCFG => true, | MirCFG => true,
} }
@ -2763,13 +2768,13 @@ impl PpMode {
match *self { match *self {
Source(_) | AstTree(_) => false, Source(_) | AstTree(_) => false,
Hir(_) | HirTree | ThirTree | Mir | MirCFG => true, Hir(_) | HirTree | ThirTree | ThirFlat | Mir | MirCFG => true,
} }
} }
pub fn needs_analysis(&self) -> bool { pub fn needs_analysis(&self) -> bool {
use PpMode::*; use PpMode::*;
matches!(*self, Mir | MirCFG | ThirTree) matches!(*self, Mir | MirCFG | ThirTree | ThirFlat)
} }
} }

View file

@ -2574,12 +2574,13 @@ macro_rules! int_impl {
#[must_use = "this returns the result of the operation, \ #[must_use = "this returns the result of the operation, \
without modifying the original"] without modifying the original"]
#[inline(always)] #[inline(always)]
#[rustc_allow_const_fn_unstable(const_cmp)]
pub const fn signum(self) -> Self { pub const fn signum(self) -> Self {
match self { // Picking the right way to phrase this is complicated
n if n > 0 => 1, // (<https://graphics.stanford.edu/~seander/bithacks.html#CopyIntegerSign>)
0 => 0, // so delegate it to `Ord` which is already producing -1/0/+1
_ => -1, // exactly like we need and can be the place to deal with the complexity.
} self.cmp(&0) as _
} }
/// Returns `true` if `self` is positive and `false` if the number is zero or /// Returns `true` if `self` is positive and `false` if the number is zero or

View file

@ -1,6 +1,6 @@
//! Temporal quantification. //! Temporal quantification.
//! //!
//! # Examples: //! # Examples
//! //!
//! There are multiple ways to create a new [`Duration`]: //! There are multiple ways to create a new [`Duration`]:
//! //!

View file

@ -53,6 +53,7 @@ pub struct ConsoleTestState {
pub metrics: MetricMap, pub metrics: MetricMap,
pub failures: Vec<(TestDesc, Vec<u8>)>, pub failures: Vec<(TestDesc, Vec<u8>)>,
pub not_failures: Vec<(TestDesc, Vec<u8>)>, pub not_failures: Vec<(TestDesc, Vec<u8>)>,
pub ignores: Vec<(TestDesc, Vec<u8>)>,
pub time_failures: Vec<(TestDesc, Vec<u8>)>, pub time_failures: Vec<(TestDesc, Vec<u8>)>,
pub options: Options, pub options: Options,
} }
@ -76,6 +77,7 @@ impl ConsoleTestState {
metrics: MetricMap::new(), metrics: MetricMap::new(),
failures: Vec::new(), failures: Vec::new(),
not_failures: Vec::new(), not_failures: Vec::new(),
ignores: Vec::new(),
time_failures: Vec::new(), time_failures: Vec::new(),
options: opts.options, options: opts.options,
}) })
@ -194,7 +196,10 @@ fn handle_test_result(st: &mut ConsoleTestState, completed_test: CompletedTest)
st.passed += 1; st.passed += 1;
st.not_failures.push((test, stdout)); st.not_failures.push((test, stdout));
} }
TestResult::TrIgnored => st.ignored += 1, TestResult::TrIgnored => {
st.ignored += 1;
st.ignores.push((test, stdout));
}
TestResult::TrBench(bs) => { TestResult::TrBench(bs) => {
st.metrics.insert_metric( st.metrics.insert_metric(
test.name.as_slice(), test.name.as_slice(),

View file

@ -254,6 +254,15 @@ impl<T: Write> OutputFormatter for TerseFormatter<T> {
self.write_plain("\n\n")?; self.write_plain("\n\n")?;
// Custom handling of cases where there is only 1 test to execute and that test was ignored.
// We want to show more detailed information(why was the test ignored) for investigation purposes.
if self.total_test_count == 1 && state.ignores.len() == 1 {
let test_desc = &state.ignores[0].0;
if let Some(im) = test_desc.ignore_message {
self.write_plain(format!("test: {}, ignore_message: {}\n\n", test_desc.name, im))?;
}
}
Ok(success) Ok(success)
} }
} }

View file

@ -790,6 +790,7 @@ fn should_sort_failures_before_printing_them() {
failures: vec![(test_b, Vec::new()), (test_a, Vec::new())], failures: vec![(test_b, Vec::new()), (test_a, Vec::new())],
options: Options::new(), options: Options::new(),
not_failures: Vec::new(), not_failures: Vec::new(),
ignores: Vec::new(),
time_failures: Vec::new(), time_failures: Vec::new(),
}; };

View file

@ -1433,7 +1433,8 @@ impl Build {
if !stamp.exists() { if !stamp.exists() {
eprintln!( eprintln!(
"Warning: Unable to find the stamp file, did you try to keep a nonexistent build stage?" "Error: Unable to find the stamp file {}, did you try to keep a nonexistent build stage?",
stamp.display()
); );
crate::detail_exit(1); crate::detail_exit(1);
} }

View file

@ -9,11 +9,5 @@ git clone --depth=1 https://github.com/rust-lang-nursery/rust-toolstate.git
cd rust-toolstate cd rust-toolstate
python3 "../../src/tools/publish_toolstate.py" "$(git rev-parse HEAD)" \ python3 "../../src/tools/publish_toolstate.py" "$(git rev-parse HEAD)" \
"$(git log --format=%s -n1 HEAD)" "" "" "$(git log --format=%s -n1 HEAD)" "" ""
# Only check maintainers if this build is supposed to publish toolstate.
# Builds that are not supposed to publish don't have the access token.
if [ -n "${TOOLSTATE_PUBLISH+is_set}" ]; then
TOOLSTATE_VALIDATE_MAINTAINERS_REPO=rust-lang/rust python3 \
"../../src/tools/publish_toolstate.py"
fi
cd .. cd ..
rm -rf rust-toolstate rm -rf rust-toolstate

View file

@ -14,4 +14,4 @@ ROOT_DIR="$(git rev-parse --show-toplevel)"
echo "Running pre-push script $ROOT_DIR/x test tidy" echo "Running pre-push script $ROOT_DIR/x test tidy"
cd "$ROOT_DIR" cd "$ROOT_DIR"
./x test tidy CARGOFLAGS="--locked" ./x test tidy

View file

@ -1528,11 +1528,7 @@ fn render_impl(
}) })
}) })
.map(|item| format!("{}.{}", item.type_(), name)); .map(|item| format!("{}.{}", item.type_(), name));
write!( write!(w, "<section id=\"{}\" class=\"{}{}\">", id, item_type, in_trait_class,);
w,
"<section id=\"{}\" class=\"{}{} has-srclink\">",
id, item_type, in_trait_class,
);
render_rightside(w, cx, item, containing_item, render_mode); render_rightside(w, cx, item, containing_item, render_mode);
if trait_.is_some() { if trait_.is_some() {
// Anchors are only used on trait impls. // Anchors are only used on trait impls.
@ -1554,11 +1550,7 @@ fn render_impl(
kind @ (clean::TyAssocConstItem(ty) | clean::AssocConstItem(ty, _)) => { kind @ (clean::TyAssocConstItem(ty) | clean::AssocConstItem(ty, _)) => {
let source_id = format!("{}.{}", item_type, name); let source_id = format!("{}.{}", item_type, name);
let id = cx.derive_id(source_id.clone()); let id = cx.derive_id(source_id.clone());
write!( write!(w, "<section id=\"{}\" class=\"{}{}\">", id, item_type, in_trait_class);
w,
"<section id=\"{}\" class=\"{}{} has-srclink\">",
id, item_type, in_trait_class
);
render_rightside(w, cx, item, containing_item, render_mode); render_rightside(w, cx, item, containing_item, render_mode);
if trait_.is_some() { if trait_.is_some() {
// Anchors are only used on trait impls. // Anchors are only used on trait impls.
@ -1606,11 +1598,7 @@ fn render_impl(
clean::AssocTypeItem(tydef, _bounds) => { clean::AssocTypeItem(tydef, _bounds) => {
let source_id = format!("{}.{}", item_type, name); let source_id = format!("{}.{}", item_type, name);
let id = cx.derive_id(source_id.clone()); let id = cx.derive_id(source_id.clone());
write!( write!(w, "<section id=\"{}\" class=\"{}{}\">", id, item_type, in_trait_class);
w,
"<section id=\"{}\" class=\"{}{} has-srclink\">",
id, item_type, in_trait_class
);
if trait_.is_some() { if trait_.is_some() {
// Anchors are only used on trait impls. // Anchors are only used on trait impls.
write!(w, "<a href=\"#{}\" class=\"anchor\">§</a>", id); write!(w, "<a href=\"#{}\" class=\"anchor\">§</a>", id);
@ -1844,7 +1832,7 @@ pub(crate) fn render_impl_summary(
} else { } else {
format!(" data-aliases=\"{}\"", aliases.join(",")) format!(" data-aliases=\"{}\"", aliases.join(","))
}; };
write!(w, "<section id=\"{}\" class=\"impl has-srclink\"{}>", id, aliases); write!(w, "<section id=\"{}\" class=\"impl\"{}>", id, aliases);
render_rightside(w, cx, &i.impl_item, containing_item, RenderMode::Normal); render_rightside(w, cx, &i.impl_item, containing_item, RenderMode::Normal);
write!(w, "<a href=\"#{}\" class=\"anchor\">§</a>", id); write!(w, "<a href=\"#{}\" class=\"anchor\">§</a>", id);
write!(w, "<h3 class=\"code-header\">"); write!(w, "<h3 class=\"code-header\">");

View file

@ -735,7 +735,7 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean:
let method_toggle_class = if item_type.is_method() { " method-toggle" } else { "" }; let method_toggle_class = if item_type.is_method() { " method-toggle" } else { "" };
write!(w, "<details class=\"toggle{method_toggle_class}\" open><summary>"); write!(w, "<details class=\"toggle{method_toggle_class}\" open><summary>");
} }
write!(w, "<section id=\"{}\" class=\"method has-srclink\">", id); write!(w, "<section id=\"{}\" class=\"method\">", id);
render_rightside(w, cx, m, t, RenderMode::Normal); render_rightside(w, cx, m, t, RenderMode::Normal);
write!(w, "<h4 class=\"code-header\">"); write!(w, "<h4 class=\"code-header\">");
render_assoc_item( render_assoc_item(

View file

@ -926,7 +926,7 @@ pub fn make_test_description<R: Read>(
cfg: Option<&str>, cfg: Option<&str>,
) -> test::TestDesc { ) -> test::TestDesc {
let mut ignore = false; let mut ignore = false;
let ignore_message = None; let mut ignore_message = None;
let mut should_fail = false; let mut should_fail = false;
let rustc_has_profiler_support = env::var_os("RUSTC_PROFILER_SUPPORT").is_some(); let rustc_has_profiler_support = env::var_os("RUSTC_PROFILER_SUPPORT").is_some();
@ -966,41 +966,67 @@ pub fn make_test_description<R: Read>(
if revision.is_some() && revision != cfg { if revision.is_some() && revision != cfg {
return; return;
} }
macro_rules! reason {
($e:expr) => {
ignore |= match $e {
true => {
ignore_message = Some(stringify!($e));
true
}
false => ignore,
}
};
}
ignore = match config.parse_cfg_name_directive(ln, "ignore") { ignore = match config.parse_cfg_name_directive(ln, "ignore") {
ParsedNameDirective::Match => true, ParsedNameDirective::Match => {
ignore_message = Some("cfg -> ignore => Match");
true
}
ParsedNameDirective::NoMatch => ignore, ParsedNameDirective::NoMatch => ignore,
}; };
if config.has_cfg_prefix(ln, "only") { if config.has_cfg_prefix(ln, "only") {
ignore = match config.parse_cfg_name_directive(ln, "only") { ignore = match config.parse_cfg_name_directive(ln, "only") {
ParsedNameDirective::Match => ignore, ParsedNameDirective::Match => ignore,
ParsedNameDirective::NoMatch => true, ParsedNameDirective::NoMatch => {
ignore_message = Some("cfg -> only => NoMatch");
true
}
}; };
} }
ignore |= ignore_llvm(config, ln);
ignore |= reason!(ignore_llvm(config, ln));
config.run_clang_based_tests_with.is_none() && config.parse_needs_matching_clang(ln); reason!(
ignore |= !has_asm_support && config.parse_name_directive(ln, "needs-asm-support"); config.run_clang_based_tests_with.is_none() && config.parse_needs_matching_clang(ln)
ignore |= !rustc_has_profiler_support && config.parse_needs_profiler_support(ln); );
ignore |= !config.run_enabled() && config.parse_name_directive(ln, "needs-run-enabled"); reason!(!has_asm_support && config.parse_name_directive(ln, "needs-asm-support"));
ignore |= !rustc_has_sanitizer_support reason!(!rustc_has_profiler_support && config.parse_needs_profiler_support(ln));
&& config.parse_name_directive(ln, "needs-sanitizer-support"); reason!(!config.run_enabled() && config.parse_name_directive(ln, "needs-run-enabled"));
ignore |= !has_asan && config.parse_name_directive(ln, "needs-sanitizer-address"); reason!(
ignore |= !has_cfi && config.parse_name_directive(ln, "needs-sanitizer-cfi"); !rustc_has_sanitizer_support
ignore |= !has_kcfi && config.parse_name_directive(ln, "needs-sanitizer-kcfi"); && config.parse_name_directive(ln, "needs-sanitizer-support")
ignore |= !has_lsan && config.parse_name_directive(ln, "needs-sanitizer-leak"); );
ignore |= !has_msan && config.parse_name_directive(ln, "needs-sanitizer-memory"); reason!(!has_asan && config.parse_name_directive(ln, "needs-sanitizer-address"));
ignore |= !has_tsan && config.parse_name_directive(ln, "needs-sanitizer-thread"); reason!(!has_cfi && config.parse_name_directive(ln, "needs-sanitizer-cfi"));
ignore |= !has_hwasan && config.parse_name_directive(ln, "needs-sanitizer-hwaddress"); reason!(!has_kcfi && config.parse_name_directive(ln, "needs-sanitizer-kcfi"));
ignore |= !has_memtag && config.parse_name_directive(ln, "needs-sanitizer-memtag"); reason!(!has_lsan && config.parse_name_directive(ln, "needs-sanitizer-leak"));
ignore |= !has_shadow_call_stack reason!(!has_msan && config.parse_name_directive(ln, "needs-sanitizer-memory"));
&& config.parse_name_directive(ln, "needs-sanitizer-shadow-call-stack"); reason!(!has_tsan && config.parse_name_directive(ln, "needs-sanitizer-thread"));
ignore |= !config.can_unwind() && config.parse_name_directive(ln, "needs-unwind"); reason!(!has_hwasan && config.parse_name_directive(ln, "needs-sanitizer-hwaddress"));
ignore |= config.target == "wasm32-unknown-unknown" reason!(!has_memtag && config.parse_name_directive(ln, "needs-sanitizer-memtag"));
&& config.parse_name_directive(ln, directives::CHECK_RUN_RESULTS); reason!(
ignore |= config.debugger == Some(Debugger::Cdb) && ignore_cdb(config, ln); !has_shadow_call_stack
ignore |= config.debugger == Some(Debugger::Gdb) && ignore_gdb(config, ln); && config.parse_name_directive(ln, "needs-sanitizer-shadow-call-stack")
ignore |= config.debugger == Some(Debugger::Lldb) && ignore_lldb(config, ln); );
ignore |= !has_rust_lld && config.parse_name_directive(ln, "needs-rust-lld"); reason!(!config.can_unwind() && config.parse_name_directive(ln, "needs-unwind"));
reason!(
config.target == "wasm32-unknown-unknown"
&& config.parse_name_directive(ln, directives::CHECK_RUN_RESULTS)
);
reason!(config.debugger == Some(Debugger::Cdb) && ignore_cdb(config, ln));
reason!(config.debugger == Some(Debugger::Gdb) && ignore_gdb(config, ln));
reason!(config.debugger == Some(Debugger::Lldb) && ignore_lldb(config, ln));
reason!(!has_rust_lld && config.parse_name_directive(ln, "needs-rust-lld"));
should_fail |= config.parse_name_directive(ln, "should-fail"); should_fail |= config.parse_name_directive(ln, "should-fail");
}); });

View file

@ -68,52 +68,6 @@ def load_json_from_response(resp):
print("Refusing to decode " + str(type(content)) + " to str") print("Refusing to decode " + str(type(content)) + " to str")
return json.loads(content_str) return json.loads(content_str)
def validate_maintainers(repo, github_token):
# type: (str, str) -> None
'''Ensure all maintainers are assignable on a GitHub repo'''
next_link_re = re.compile(r'<([^>]+)>; rel="next"')
# Load the list of assignable people in the GitHub repo
assignable = [] # type: typing.List[str]
url = 'https://api.github.com/repos/' \
+ '%s/collaborators?per_page=100' % repo # type: typing.Optional[str]
while url is not None:
response = urllib2.urlopen(urllib2.Request(url, headers={
'Authorization': 'token ' + github_token,
# Properly load nested teams.
'Accept': 'application/vnd.github.hellcat-preview+json',
}))
assignable.extend(user['login'] for user in load_json_from_response(response))
# Load the next page if available
url = None
link_header = response.headers.get('Link')
if link_header:
matches = next_link_re.match(link_header)
if matches is not None:
url = matches.group(1)
errors = False
for tool, maintainers in MAINTAINERS.items():
for maintainer in maintainers:
if maintainer not in assignable:
errors = True
print(
"error: %s maintainer @%s is not assignable in the %s repo"
% (tool, maintainer, repo),
)
if errors:
print()
print(" To be assignable, a person needs to be explicitly listed as a")
print(" collaborator in the repository settings. The simple way to")
print(" fix this is to ask someone with 'admin' privileges on the repo")
print(" to add the person or whole team as a collaborator with 'read'")
print(" privileges. Those privileges don't grant any extra permissions")
print(" so it's safe to apply them.")
print()
print("The build will fail due to this.")
exit(1)
def read_current_status(current_commit, path): def read_current_status(current_commit, path):
# type: (str, str) -> typing.Mapping[str, typing.Any] # type: (str, str) -> typing.Mapping[str, typing.Any]
@ -280,21 +234,6 @@ def update_latest(
try: try:
if __name__ != '__main__': if __name__ != '__main__':
exit(0) exit(0)
repo = os.environ.get('TOOLSTATE_VALIDATE_MAINTAINERS_REPO')
if repo:
github_token = os.environ.get('TOOLSTATE_REPO_ACCESS_TOKEN')
if github_token:
# FIXME: This is currently broken. Starting on 2021-09-15, GitHub
# seems to have changed it so that to list the collaborators
# requires admin permissions. I think this will probably just need
# to be removed since we are probably not going to use an admin
# token, and I don't see another way to do this.
print('maintainer validation disabled')
# validate_maintainers(repo, github_token)
else:
print('skipping toolstate maintainers validation since no GitHub token is present')
# When validating maintainers don't run the full script.
exit(0)
cur_commit = sys.argv[1] cur_commit = sys.argv[1]
cur_datetime = datetime.datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%SZ') cur_datetime = datetime.datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%SZ')

View file

@ -4,13 +4,13 @@
goto: "file://" + |DOC_PATH| + "/test_docs/struct.Foo.html" goto: "file://" + |DOC_PATH| + "/test_docs/struct.Foo.html"
show-text: true show-text: true
// Check the impl headers. // Check the impl headers.
assert-css: (".impl.has-srclink .srclink", {"font-size": "16px", "font-weight": 400}, ALL) assert-css: (".impl .srclink", {"font-size": "16px", "font-weight": 400}, ALL)
assert-css: (".impl.has-srclink .code-header", {"font-size": "18px", "font-weight": 600}, ALL) assert-css: (".impl .code-header", {"font-size": "18px", "font-weight": 600}, ALL)
// Check the impl items. // Check the impl items.
assert-css: (".impl-items .has-srclink .srclink", {"font-size": "16px", "font-weight": 400}, ALL) assert-css: (".impl-items .srclink", {"font-size": "16px", "font-weight": 400}, ALL)
assert-css: (".impl-items .has-srclink .code-header", {"font-size": "16px", "font-weight": 600}, ALL) assert-css: (".impl-items .code-header", {"font-size": "16px", "font-weight": 600}, ALL)
// Check that we can click on source link // Check that we can click on source link
store-document-property: (url, "URL") store-document-property: (url, "URL")
click: ".impl-items .has-srclink .srclink" click: ".impl-items .srclink"
assert-document-property-false: {"URL": |url|} assert-document-property-false: {"URL": |url|}

View file

@ -1 +1 @@
<section id="associatedconstant.YOLO" class="method has-srclink"><a class="srclink rightside" href="../src/foo/anchors.rs.html#16">source</a><h4 class="code-header">const <a href="#associatedconstant.YOLO" class="constant">YOLO</a>: <a class="primitive" href="{{channel}}/std/primitive.u32.html">u32</a></h4></section> <section id="associatedconstant.YOLO" class="method"><a class="srclink rightside" href="../src/foo/anchors.rs.html#16">source</a><h4 class="code-header">const <a href="#associatedconstant.YOLO" class="constant">YOLO</a>: <a class="primitive" href="{{channel}}/std/primitive.u32.html">u32</a></h4></section>

View file

@ -1 +1 @@
<section id="associatedconstant.X" class="associatedconstant has-srclink"><a class="srclink rightside" href="../src/foo/anchors.rs.html#42">source</a><h4 class="code-header">pub const <a href="#associatedconstant.X" class="constant">X</a>: <a class="primitive" href="{{channel}}/std/primitive.i32.html">i32</a> = 0i32</h4></section> <section id="associatedconstant.X" class="associatedconstant"><a class="srclink rightside" href="../src/foo/anchors.rs.html#42">source</a><h4 class="code-header">pub const <a href="#associatedconstant.X" class="constant">X</a>: <a class="primitive" href="{{channel}}/std/primitive.i32.html">i32</a> = 0i32</h4></section>

View file

@ -1 +1 @@
<section id="method.new" class="method has-srclink"><a class="srclink rightside" href="../src/foo/anchors.rs.html#48">source</a><h4 class="code-header">pub fn <a href="#method.new" class="fn">new</a>() -&gt; Self</h4></section> <section id="method.new" class="method"><a class="srclink rightside" href="../src/foo/anchors.rs.html#48">source</a><h4 class="code-header">pub fn <a href="#method.new" class="fn">new</a>() -&gt; Self</h4></section>

View file

@ -1 +1 @@
<section id="method.bar" class="method has-srclink"><a class="srclink rightside" href="../src/foo/anchors.rs.html#23">source</a><h4 class="code-header">fn <a href="#method.bar" class="fn">bar</a>()</h4></section> <section id="method.bar" class="method"><a class="srclink rightside" href="../src/foo/anchors.rs.html#23">source</a><h4 class="code-header">fn <a href="#method.bar" class="fn">bar</a>()</h4></section>

View file

@ -1 +1 @@
<section id="tymethod.foo" class="method has-srclink"><a class="srclink rightside" href="../src/foo/anchors.rs.html#20">source</a><h4 class="code-header">fn <a href="#tymethod.foo" class="fn">foo</a>()</h4></section> <section id="tymethod.foo" class="method"><a class="srclink rightside" href="../src/foo/anchors.rs.html#20">source</a><h4 class="code-header">fn <a href="#tymethod.foo" class="fn">foo</a>()</h4></section>

View file

@ -1 +1 @@
<section id="associatedtype.T" class="method has-srclink"><a class="srclink rightside" href="../src/foo/anchors.rs.html#13">source</a><h4 class="code-header">type <a href="#associatedtype.T" class="associatedtype">T</a></h4></section> <section id="associatedtype.T" class="method"><a class="srclink rightside" href="../src/foo/anchors.rs.html#13">source</a><h4 class="code-header">type <a href="#associatedtype.T" class="associatedtype">T</a></h4></section>

View file

@ -1 +1 @@
<section id="associatedtype.Y" class="associatedtype has-srclink"><h4 class="code-header">type <a href="#associatedtype.Y" class="associatedtype">Y</a> = <a class="primitive" href="{{channel}}/std/primitive.u32.html">u32</a></h4></section> <section id="associatedtype.Y" class="associatedtype"><h4 class="code-header">type <a href="#associatedtype.Y" class="associatedtype">Y</a> = <a class="primitive" href="{{channel}}/std/primitive.u32.html">u32</a></h4></section>

View file

@ -77,12 +77,12 @@ struct AsyncFdReadyGuard<'a, T> { x: &'a T }
impl Foo { impl Foo {
// @has async_fn/struct.Foo.html // @has async_fn/struct.Foo.html
// @has - '//*[@class="method has-srclink"]' 'pub async fn complicated_lifetimes( &self, context: &impl Bar) -> impl Iterator<Item = &usize>' // @has - '//*[@class="method"]' 'pub async fn complicated_lifetimes( &self, context: &impl Bar) -> impl Iterator<Item = &usize>'
pub async fn complicated_lifetimes(&self, context: &impl Bar) -> impl Iterator<Item = &usize> {} pub async fn complicated_lifetimes(&self, context: &impl Bar) -> impl Iterator<Item = &usize> {}
// taken from `tokio` as an example of a method that was particularly bad before // taken from `tokio` as an example of a method that was particularly bad before
// @has - '//*[@class="method has-srclink"]' "pub async fn readable<T>(&self) -> Result<AsyncFdReadyGuard<'_, T>, ()>" // @has - '//*[@class="method"]' "pub async fn readable<T>(&self) -> Result<AsyncFdReadyGuard<'_, T>, ()>"
pub async fn readable<T>(&self) -> Result<AsyncFdReadyGuard<'_, T>, ()> {} pub async fn readable<T>(&self) -> Result<AsyncFdReadyGuard<'_, T>, ()> {}
// @has - '//*[@class="method has-srclink"]' "pub async fn mut_self(&mut self)" // @has - '//*[@class="method"]' "pub async fn mut_self(&mut self)"
pub async fn mut_self(&mut self) {} pub async fn mut_self(&mut self) {}
} }

View file

@ -8,7 +8,7 @@ pub const fn bar() -> usize {
} }
// @has foo/struct.Foo.html // @has foo/struct.Foo.html
// @has - '//*[@class="method has-srclink"]' 'const fn new()' // @has - '//*[@class="method"]' 'const fn new()'
pub struct Foo(usize); pub struct Foo(usize);
impl Foo { impl Foo {

View file

@ -5,7 +5,7 @@ pub trait Array {
} }
// @has foo/trait.Array.html // @has foo/trait.Array.html
// @has - '//*[@class="impl has-srclink"]' 'impl<T, const N: usize> Array for [T; N]' // @has - '//*[@class="impl"]' 'impl<T, const N: usize> Array for [T; N]'
impl<T, const N: usize> Array for [T; N] { impl<T, const N: usize> Array for [T; N] {
type Item = T; type Item = T;
} }

View file

@ -8,7 +8,7 @@ pub trait Bar {
fn foo(foo: Self::Fuu); fn foo(foo: Self::Fuu);
} }
// @has doc_assoc_item/struct.Foo.html '//*[@class="impl has-srclink"]' 'impl<T: Bar<Fuu = u32>> Foo<T>' // @has doc_assoc_item/struct.Foo.html '//*[@class="impl"]' 'impl<T: Bar<Fuu = u32>> Foo<T>'
impl<T: Bar<Fuu = u32>> Foo<T> { impl<T: Bar<Fuu = u32>> Foo<T> {
pub fn new(t: T) -> Foo<T> { pub fn new(t: T) -> Foo<T> {
Foo { Foo {

View file

@ -3,8 +3,8 @@
// @has issue_33054/impls/struct.Foo.html // @has issue_33054/impls/struct.Foo.html
// @has - '//h3[@class="code-header"]' 'impl Foo' // @has - '//h3[@class="code-header"]' 'impl Foo'
// @has - '//h3[@class="code-header"]' 'impl Bar for Foo' // @has - '//h3[@class="code-header"]' 'impl Bar for Foo'
// @count - '//*[@id="trait-implementations-list"]//*[@class="impl has-srclink"]' 1 // @count - '//*[@id="trait-implementations-list"]//*[@class="impl"]' 1
// @count - '//*[@id="main-content"]/div[@id="implementations-list"]/details/summary/*[@class="impl has-srclink"]' 1 // @count - '//*[@id="main-content"]/div[@id="implementations-list"]/details/summary/*[@class="impl"]' 1
// @has issue_33054/impls/bar/trait.Bar.html // @has issue_33054/impls/bar/trait.Bar.html
// @has - '//h3[@class="code-header"]' 'impl Bar for Foo' // @has - '//h3[@class="code-header"]' 'impl Bar for Foo'
// @count - '//*[@class="struct"]' 1 // @count - '//*[@class="struct"]' 1

View file

@ -7,7 +7,7 @@
// blanket implementations. // blanket implementations.
// @has 'foo/struct.Whatever.html' // @has 'foo/struct.Whatever.html'
// @count - '//*[@id="blanket-implementations-list"]/section[@class="impl has-srclink"]' 1 // @count - '//*[@id="blanket-implementations-list"]/section[@class="impl"]' 1
pub trait Something<T> { } pub trait Something<T> { }
pub struct Whatever; pub struct Whatever;

View file

@ -10,7 +10,7 @@ pub struct Foo;
// There are 3 impl blocks with public item and one that should not be displayed // There are 3 impl blocks with public item and one that should not be displayed
// by default because it only contains private items (but not in this case because // by default because it only contains private items (but not in this case because
// we used `--document-private-items`). // we used `--document-private-items`).
// @count - '//*[@class="impl has-srclink"]' 'impl Foo' 4 // @count - '//*[@class="impl"]' 'impl Foo' 4
// Impl block only containing private items should not be displayed unless the // Impl block only containing private items should not be displayed unless the
// `--document-private-items` flag is used. // `--document-private-items` flag is used.

View file

@ -7,7 +7,7 @@ pub struct Foo;
// There are 3 impl blocks with public item and one that should not be displayed // There are 3 impl blocks with public item and one that should not be displayed
// because it only contains private items. // because it only contains private items.
// @count - '//*[@class="impl has-srclink"]' 'impl Foo' 3 // @count - '//*[@class="impl"]' 'impl Foo' 3
// Impl block only containing private items should not be displayed. // Impl block only containing private items should not be displayed.
/// Private /// Private

View file

@ -8,7 +8,7 @@ pub struct Foo;
/// Hello empty impl block! /// Hello empty impl block!
impl Foo {} impl Foo {}
// We ensure that this empty impl block without doc isn't rendered. // We ensure that this empty impl block without doc isn't rendered.
// @count - '//*[@class="impl has-srclink"]' 'impl Foo' 1 // @count - '//*[@class="impl"]' 'impl Foo' 1
impl Foo {} impl Foo {}
// Just to ensure that empty trait impl blocks are rendered. // Just to ensure that empty trait impl blocks are rendered.

View file

@ -5,7 +5,7 @@ pub auto trait AnAutoTrait {}
pub struct Foo<T> { field: T } pub struct Foo<T> { field: T }
// @has impl_parts/struct.Foo.html '//*[@class="impl has-srclink"]//h3[@class="code-header"]' \ // @has impl_parts/struct.Foo.html '//*[@class="impl"]//h3[@class="code-header"]' \
// "impl<T> !AnAutoTrait for Foo<T>where T: Sync + Clone," // "impl<T> !AnAutoTrait for Foo<T>where T: Sync + Clone,"
// @has impl_parts/trait.AnAutoTrait.html '//*[@id="implementors-list"]//h3[@class="code-header"]' \ // @has impl_parts/trait.AnAutoTrait.html '//*[@id="implementors-list"]//h3[@class="code-header"]' \
// "impl<T> !AnAutoTrait for Foo<T>where T: Sync + Clone," // "impl<T> !AnAutoTrait for Foo<T>where T: Sync + Clone,"

View file

@ -5,8 +5,8 @@
extern crate rustdoc_nonreachable_impls; extern crate rustdoc_nonreachable_impls;
// @has issue_31948_1/struct.Wobble.html // @has issue_31948_1/struct.Wobble.html
// @has - '//*[@class="impl has-srclink"]//h3[@class="code-header"]' 'Bark for' // @has - '//*[@class="impl"]//h3[@class="code-header"]' 'Bark for'
// @has - '//*[@class="impl has-srclink"]//h3[@class="code-header"]' 'Woof for' // @has - '//*[@class="impl"]//h3[@class="code-header"]' 'Woof for'
// @!has - '//*[@class="impl"]//h3[@class="code-header"]' 'Bar for' // @!has - '//*[@class="impl"]//h3[@class="code-header"]' 'Bar for'
// @!has - '//*[@class="impl"]//h3[@class="code-header"]' 'Qux for' // @!has - '//*[@class="impl"]//h3[@class="code-header"]' 'Qux for'
pub use rustdoc_nonreachable_impls::hidden::Wobble; pub use rustdoc_nonreachable_impls::hidden::Wobble;

View file

@ -5,9 +5,9 @@
extern crate rustdoc_nonreachable_impls; extern crate rustdoc_nonreachable_impls;
// @has issue_31948_2/struct.Wobble.html // @has issue_31948_2/struct.Wobble.html
// @has - '//*[@class="impl has-srclink"]//h3[@class="code-header"]' 'Qux for' // @has - '//*[@class="impl"]//h3[@class="code-header"]' 'Qux for'
// @has - '//*[@class="impl has-srclink"]//h3[@class="code-header"]' 'Bark for' // @has - '//*[@class="impl"]//h3[@class="code-header"]' 'Bark for'
// @has - '//*[@class="impl has-srclink"]//h3[@class="code-header"]' 'Woof for' // @has - '//*[@class="impl"]//h3[@class="code-header"]' 'Woof for'
// @!has - '//*[@class="impl"]//h3[@class="code-header"]' 'Bar for' // @!has - '//*[@class="impl"]//h3[@class="code-header"]' 'Bar for'
pub use rustdoc_nonreachable_impls::hidden::Wobble; pub use rustdoc_nonreachable_impls::hidden::Wobble;

View file

@ -5,9 +5,9 @@
extern crate rustdoc_nonreachable_impls; extern crate rustdoc_nonreachable_impls;
// @has issue_31948/struct.Foo.html // @has issue_31948/struct.Foo.html
// @has - '//*[@class="impl has-srclink"]//h3[@class="code-header"]' 'Bark for' // @has - '//*[@class="impl"]//h3[@class="code-header"]' 'Bark for'
// @has - '//*[@class="impl has-srclink"]//h3[@class="code-header"]' 'Woof for' // @has - '//*[@class="impl"]//h3[@class="code-header"]' 'Woof for'
// @!has - '//*[@class="impl has-srclink"]//h3[@class="code-header"]' 'Bar for' // @!has - '//*[@class="impl"]//h3[@class="code-header"]' 'Bar for'
// @!has - '//*[@class="impl"]//h3[@class="code-header"]' 'Qux for' // @!has - '//*[@class="impl"]//h3[@class="code-header"]' 'Qux for'
pub use rustdoc_nonreachable_impls::Foo; pub use rustdoc_nonreachable_impls::Foo;

View file

@ -7,5 +7,5 @@ mod inner {
pub trait Blah { } pub trait Blah { }
// @count issue_21474/struct.What.html \ // @count issue_21474/struct.What.html \
// '//*[@id="trait-implementations-list"]//*[@class="impl has-srclink"]' 1 // '//*[@id="trait-implementations-list"]//*[@class="impl"]' 1
pub struct What; pub struct What;

View file

@ -22,7 +22,7 @@ macro_rules! make {
} }
// @has issue_33302/struct.S.html \ // @has issue_33302/struct.S.html \
// '//*[@class="impl has-srclink"]' 'impl T<[i32; 16]> for S' // '//*[@class="impl"]' 'impl T<[i32; 16]> for S'
// @has - '//*[@id="associatedconstant.C"]' 'const C: [i32; 16]' // @has - '//*[@id="associatedconstant.C"]' 'const C: [i32; 16]'
// @has - '//*[@id="associatedconstant.D"]' 'const D: i32' // @has - '//*[@id="associatedconstant.D"]' 'const D: i32'
impl T<[i32; ($n * $n)]> for S { impl T<[i32; ($n * $n)]> for S {
@ -30,7 +30,7 @@ macro_rules! make {
} }
// @has issue_33302/struct.S.html \ // @has issue_33302/struct.S.html \
// '//*[@class="impl has-srclink"]' 'impl T<[i32; 16]> for S' // '//*[@class="impl"]' 'impl T<[i32; 16]> for S'
// @has - '//*[@id="associatedconstant.C-1"]' 'const C: (i32,)' // @has - '//*[@id="associatedconstant.C-1"]' 'const C: (i32,)'
// @has - '//*[@id="associatedconstant.D-1"]' 'const D: i32' // @has - '//*[@id="associatedconstant.D-1"]' 'const D: i32'
impl T<(i32,)> for S { impl T<(i32,)> for S {
@ -38,7 +38,7 @@ macro_rules! make {
} }
// @has issue_33302/struct.S.html \ // @has issue_33302/struct.S.html \
// '//*[@class="impl has-srclink"]' 'impl T<(i32, i32)> for S' // '//*[@class="impl"]' 'impl T<(i32, i32)> for S'
// @has - '//*[@id="associatedconstant.C-2"]' 'const C: (i32, i32)' // @has - '//*[@id="associatedconstant.C-2"]' 'const C: (i32, i32)'
// @has - '//*[@id="associatedconstant.D-2"]' 'const D: i32' // @has - '//*[@id="associatedconstant.D-2"]' 'const D: i32'
impl T<(i32, i32)> for S { impl T<(i32, i32)> for S {

View file

@ -4,12 +4,12 @@ pub trait Bar<T, U> {}
// @has 'foo/struct.Foo1.html' // @has 'foo/struct.Foo1.html'
pub struct Foo1; pub struct Foo1;
// @count - '//*[@id="trait-implementations-list"]//*[@class="impl has-srclink"]' 1 // @count - '//*[@id="trait-implementations-list"]//*[@class="impl"]' 1
// @has - '//*[@class="impl has-srclink"]' "impl Bar<Foo1, &'static Foo1> for Foo1" // @has - '//*[@class="impl"]' "impl Bar<Foo1, &'static Foo1> for Foo1"
impl Bar<Foo1, &'static Foo1> for Foo1 {} impl Bar<Foo1, &'static Foo1> for Foo1 {}
// @has 'foo/struct.Foo2.html' // @has 'foo/struct.Foo2.html'
pub struct Foo2; pub struct Foo2;
// @count - '//*[@id="trait-implementations-list"]//*[@class="impl has-srclink"]' 1 // @count - '//*[@id="trait-implementations-list"]//*[@class="impl"]' 1
// @has - '//*[@class="impl has-srclink"]' "impl Bar<&'static Foo2, Foo2> for u8" // @has - '//*[@class="impl"]' "impl Bar<&'static Foo2, Foo2> for u8"
impl Bar<&'static Foo2, Foo2> for u8 {} impl Bar<&'static Foo2, Foo2> for u8 {}

View file

@ -14,7 +14,7 @@ impl<B, C> Signal2 for B where B: Signal<Item = C> {
// @has - '//h3[@class="code-header"]' 'impl<B> Send for Switch<B>where <B as Signal>::Item: Send' // @has - '//h3[@class="code-header"]' 'impl<B> Send for Switch<B>where <B as Signal>::Item: Send'
// @has - '//h3[@class="code-header"]' 'impl<B> Sync for Switch<B>where <B as Signal>::Item: Sync' // @has - '//h3[@class="code-header"]' 'impl<B> Sync for Switch<B>where <B as Signal>::Item: Sync'
// @count - '//*[@id="implementations-list"]//*[@class="impl"]' 0 // @count - '//*[@id="implementations-list"]//*[@class="impl"]' 0
// @count - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]' 5 // @count - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]' 5
pub struct Switch<B: Signal> { pub struct Switch<B: Signal> {
pub inner: <B as Signal2>::Item2, pub inner: <B as Signal2>::Item2,
} }

View file

@ -7,7 +7,7 @@ pub mod traits {
} }
// @has issue_51236/struct.Owned.html // @has issue_51236/struct.Owned.html
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header"]' \ // @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//h3[@class="code-header"]' \
// "impl<T> Send for Owned<T>where <T as Owned<'static>>::Reader: Send" // "impl<T> Send for Owned<T>where <T as Owned<'static>>::Reader: Send"
pub struct Owned<T> where T: for<'a> ::traits::Owned<'a> { pub struct Owned<T> where T: for<'a> ::traits::Owned<'a> {
marker: PhantomData<<T as ::traits::Owned<'static>>::Reader>, marker: PhantomData<<T as ::traits::Owned<'static>>::Reader>,

View file

@ -12,9 +12,9 @@ macro_rules! array_impls {
} }
// @has issue_53812/trait.MyIterator.html // @has issue_53812/trait.MyIterator.html
// @has - '//*[@id="implementors-list"]/*[@class="impl has-srclink"][1]' 'MyStruct<[T; 0]>' // @has - '//*[@id="implementors-list"]/*[@class="impl"][1]' 'MyStruct<[T; 0]>'
// @has - '//*[@id="implementors-list"]/*[@class="impl has-srclink"][2]' 'MyStruct<[T; 1]>' // @has - '//*[@id="implementors-list"]/*[@class="impl"][2]' 'MyStruct<[T; 1]>'
// @has - '//*[@id="implementors-list"]/*[@class="impl has-srclink"][3]' 'MyStruct<[T; 2]>' // @has - '//*[@id="implementors-list"]/*[@class="impl"][3]' 'MyStruct<[T; 2]>'
// @has - '//*[@id="implementors-list"]/*[@class="impl has-srclink"][4]' 'MyStruct<[T; 3]>' // @has - '//*[@id="implementors-list"]/*[@class="impl"][4]' 'MyStruct<[T; 3]>'
// @has - '//*[@id="implementors-list"]/*[@class="impl has-srclink"][5]' 'MyStruct<[T; 10]>' // @has - '//*[@id="implementors-list"]/*[@class="impl"][5]' 'MyStruct<[T; 10]>'
array_impls! { 10 3 2 1 0 } array_impls! { 10 3 2 1 0 }

View file

@ -1,10 +1,10 @@
pub trait ScopeHandle<'scope> {} pub trait ScopeHandle<'scope> {}
// @has issue_54705/struct.ScopeFutureContents.html // @has issue_54705/struct.ScopeFutureContents.html
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header"]' \ // @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//h3[@class="code-header"]' \
// "impl<'scope, S> Send for ScopeFutureContents<'scope, S>where S: Sync" // "impl<'scope, S> Send for ScopeFutureContents<'scope, S>where S: Sync"
// //
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header"]' \ // @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//h3[@class="code-header"]' \
// "impl<'scope, S> Sync for ScopeFutureContents<'scope, S>where S: Sync" // "impl<'scope, S> Sync for ScopeFutureContents<'scope, S>where S: Sync"
pub struct ScopeFutureContents<'scope, S> pub struct ScopeFutureContents<'scope, S>
where S: ScopeHandle<'scope>, where S: ScopeHandle<'scope>,

View file

@ -1,9 +1,9 @@
#![feature(negative_impls)] #![feature(negative_impls)]
// @has issue_55321/struct.A.html // @has issue_55321/struct.A.html
// @has - '//*[@id="trait-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header"]' \ // @has - '//*[@id="trait-implementations-list"]//*[@class="impl"]//h3[@class="code-header"]' \
// "impl !Send for A" // "impl !Send for A"
// @has - '//*[@id="trait-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header"]' \ // @has - '//*[@id="trait-implementations-list"]//*[@class="impl"]//h3[@class="code-header"]' \
// "impl !Sync for A" // "impl !Sync for A"
pub struct A(); pub struct A();
@ -11,8 +11,8 @@ impl !Send for A {}
impl !Sync for A {} impl !Sync for A {}
// @has issue_55321/struct.B.html // @has issue_55321/struct.B.html
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header"]' \ // @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//h3[@class="code-header"]' \
// "impl<T> !Send for B<T>" // "impl<T> !Send for B<T>"
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header"]' \ // @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//h3[@class="code-header"]' \
// "impl<T> !Sync for B<T>" // "impl<T> !Sync for B<T>"
pub struct B<T: ?Sized>(A, Box<T>); pub struct B<T: ?Sized>(A, Box<T>);

View file

@ -17,7 +17,7 @@ impl<'a, T> MyTrait for Inner<'a, T> {
} }
// @has issue_56822/struct.Parser.html // @has issue_56822/struct.Parser.html
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header"]' \ // @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//h3[@class="code-header"]' \
// "impl<'a> Send for Parser<'a>" // "impl<'a> Send for Parser<'a>"
pub struct Parser<'a> { pub struct Parser<'a> {
field: <Wrapper<Inner<'a, u8>> as MyTrait>::Output field: <Wrapper<Inner<'a, u8>> as MyTrait>::Output

View file

@ -26,9 +26,9 @@ where
{} {}
// @has issue_60726/struct.IntoIter.html // @has issue_60726/struct.IntoIter.html
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header"]' \ // @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//h3[@class="code-header"]' \
// "impl<T> !Send for IntoIter<T>" // "impl<T> !Send for IntoIter<T>"
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header"]' \ // @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//h3[@class="code-header"]' \
// "impl<T> !Sync for IntoIter<T>" // "impl<T> !Sync for IntoIter<T>"
pub struct IntoIter<T>{ pub struct IntoIter<T>{
hello:DynTrait<FooInterface<T>>, hello:DynTrait<FooInterface<T>>,

View file

@ -8,7 +8,7 @@ pub const fn bloop() -> i32 {
pub struct Struct {} pub struct Struct {}
impl Struct { impl Struct {
// @has 'issue_76501/struct.Struct.html' '//*[@class="method has-srclink"]' \ // @has 'issue_76501/struct.Struct.html' '//*[@class="method"]' \
// 'pub const fn blurp() -> i32' // 'pub const fn blurp() -> i32'
/// A useless function that always returns 1. /// A useless function that always returns 1.
pub const fn blurp() -> i32 { pub const fn blurp() -> i32 {

View file

@ -7,8 +7,8 @@ pub trait AnAmazingTrait {}
impl<T: Something> AnAmazingTrait for T {} impl<T: Something> AnAmazingTrait for T {}
// @has 'issue_78673/struct.MyStruct.html' // @has 'issue_78673/struct.MyStruct.html'
// @has - '//*[@class="impl has-srclink"]' 'AnAmazingTrait for MyStruct' // @has - '//*[@class="impl"]' 'AnAmazingTrait for MyStruct'
// @!has - '//*[@class="impl has-srclink"]' 'AnAmazingTrait for T' // @!has - '//*[@class="impl"]' 'AnAmazingTrait for T'
pub struct MyStruct; pub struct MyStruct;
impl AnAmazingTrait for MyStruct {} impl AnAmazingTrait for MyStruct {}
@ -16,8 +16,8 @@ impl AnAmazingTrait for MyStruct {}
// generic structs may have _both_ specific and blanket impls that apply // generic structs may have _both_ specific and blanket impls that apply
// @has 'issue_78673/struct.AnotherStruct.html' // @has 'issue_78673/struct.AnotherStruct.html'
// @has - '//*[@class="impl has-srclink"]' 'AnAmazingTrait for AnotherStruct<()>' // @has - '//*[@class="impl"]' 'AnAmazingTrait for AnotherStruct<()>'
// @has - '//*[@class="impl has-srclink"]' 'AnAmazingTrait for T' // @has - '//*[@class="impl"]' 'AnAmazingTrait for T'
pub struct AnotherStruct<T>(T); pub struct AnotherStruct<T>(T);
impl<T: Something> Something for AnotherStruct<T> {} impl<T: Something> Something for AnotherStruct<T> {}

View file

@ -5,7 +5,7 @@
pub struct Foo; pub struct Foo;
// @count foo/struct.Foo.html '//*[@class="impl-items"]//*[@class="method has-srclink"]' 2 // @count foo/struct.Foo.html '//*[@class="impl-items"]//*[@class="method"]' 2
// @!has - '//*[@class="impl-items"]//*[@class="method"]' 'mut' // @!has - '//*[@class="impl-items"]//*[@class="method"]' 'mut'
impl Foo { impl Foo {
pub fn foo(mut self) {} pub fn foo(mut self) {}

View file

@ -5,10 +5,10 @@ pub struct Alpha;
// @matches negative_impl/struct.Bravo.html '//pre' "pub struct Bravo<B>" // @matches negative_impl/struct.Bravo.html '//pre' "pub struct Bravo<B>"
pub struct Bravo<B>(B); pub struct Bravo<B>(B);
// @matches negative_impl/struct.Alpha.html '//*[@class="impl has-srclink"]//h3[@class="code-header"]' \ // @matches negative_impl/struct.Alpha.html '//*[@class="impl"]//h3[@class="code-header"]' \
// "impl !Send for Alpha" // "impl !Send for Alpha"
impl !Send for Alpha {} impl !Send for Alpha {}
// @matches negative_impl/struct.Bravo.html '//*[@class="impl has-srclink"]//h3[@class="code-header"]' "\ // @matches negative_impl/struct.Bravo.html '//*[@class="impl"]//h3[@class="code-header"]' "\
// impl<B> !Send for Bravo<B>" // impl<B> !Send for Bravo<B>"
impl<B> !Send for Bravo<B> {} impl<B> !Send for Bravo<B> {}

View file

@ -13,7 +13,7 @@
// @has - '//section[@id="main-content"]//div[@class="docblock"]//p' 'this is a test!' // @has - '//section[@id="main-content"]//div[@class="docblock"]//p' 'this is a test!'
// There should be only one implementation listed. // There should be only one implementation listed.
// @count - '//*[@class="impl has-srclink"]' 1 // @count - '//*[@class="impl"]' 1
// @has - '//*[@id="impl-Foo%3C%26A%3E-for-%26B"]/*[@class="code-header"]' \ // @has - '//*[@id="impl-Foo%3C%26A%3E-for-%26B"]/*[@class="code-header"]' \
// 'impl<A, B> Foo<&A> for &B' // 'impl<A, B> Foo<&A> for &B'
#[doc(primitive = "reference")] #[doc(primitive = "reference")]

View file

@ -10,8 +10,8 @@ pub fn bar() -> usize {
} }
// @has foo/struct.Foo.html // @has foo/struct.Foo.html
// @has - '//*[@class="method has-srclink"]' 'pub fn new()' // @has - '//*[@class="method"]' 'pub fn new()'
// @has - '//*[@class="method has-srclink"]' 'fn not_pub()' // @has - '//*[@class="method"]' 'fn not_pub()'
pub struct Foo(usize); pub struct Foo(usize);
impl Foo { impl Foo {

View file

@ -1,8 +1,8 @@
// @has basic/struct.Foo.html // @has basic/struct.Foo.html
// @has - '//h3[@class="code-header"]' 'impl<T> Send for Foo<T>where T: Send' // @has - '//h3[@class="code-header"]' 'impl<T> Send for Foo<T>where T: Send'
// @has - '//h3[@class="code-header"]' 'impl<T> Sync for Foo<T>where T: Sync' // @has - '//h3[@class="code-header"]' 'impl<T> Sync for Foo<T>where T: Sync'
// @count - '//*[@id="implementations-list"]//*[@class="impl has-srclink"]' 0 // @count - '//*[@id="implementations-list"]//*[@class="impl"]' 0
// @count - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]' 5 // @count - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]' 5
pub struct Foo<T> { pub struct Foo<T> {
field: T, field: T,
} }

View file

@ -20,7 +20,7 @@ mod foo {
} }
// @has complex/struct.NotOuter.html // @has complex/struct.NotOuter.html
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header"]' \ // @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//h3[@class="code-header"]' \
// "impl<'a, T, K: ?Sized> Send for Outer<'a, T, K>where K: for<'b> Fn((&'b bool, &'a u8)) \ // "impl<'a, T, K: ?Sized> Send for Outer<'a, T, K>where K: for<'b> Fn((&'b bool, &'a u8)) \
// -> &'b i8, T: MyTrait<'a>, <T as MyTrait<'a>>::MyItem: Copy, 'a: 'static" // -> &'b i8, T: MyTrait<'a>, <T as MyTrait<'a>>::MyItem: Copy, 'a: 'static"

View file

@ -9,10 +9,10 @@ where
{} {}
// @has lifetimes/struct.Foo.html // @has lifetimes/struct.Foo.html
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header"]' \ // @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//h3[@class="code-header"]' \
// "impl<'c, K> Send for Foo<'c, K>where K: for<'b> Fn(&'b bool) -> &'c u8, 'c: 'static" // "impl<'c, K> Send for Foo<'c, K>where K: for<'b> Fn(&'b bool) -> &'c u8, 'c: 'static"
// //
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header"]' \ // @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//h3[@class="code-header"]' \
// "impl<'c, K> Sync for Foo<'c, K>where K: Sync" // "impl<'c, K> Sync for Foo<'c, K>where K: Sync"
pub struct Foo<'c, K: 'c> { pub struct Foo<'c, K: 'c> {
inner_field: Inner<'c, K>, inner_field: Inner<'c, K>,

View file

@ -1,12 +1,12 @@
// @has manual/struct.Foo.html // @has manual/struct.Foo.html
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header"]' \ // @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//h3[@class="code-header"]' \
// 'impl<T> Sync for Foo<T>where T: Sync' // 'impl<T> Sync for Foo<T>where T: Sync'
// //
// @has - '//*[@id="trait-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header"]' \ // @has - '//*[@id="trait-implementations-list"]//*[@class="impl"]//h3[@class="code-header"]' \
// 'impl<T> Send for Foo<T>' // 'impl<T> Send for Foo<T>'
// //
// @count - '//*[@id="trait-implementations-list"]//*[@class="impl has-srclink"]' 1 // @count - '//*[@id="trait-implementations-list"]//*[@class="impl"]' 1
// @count - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]' 4 // @count - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]' 4
pub struct Foo<T> { pub struct Foo<T> {
field: T, field: T,
} }

View file

@ -3,10 +3,10 @@ pub struct Inner<T: Copy> {
} }
// @has negative/struct.Outer.html // @has negative/struct.Outer.html
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header"]' \ // @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//h3[@class="code-header"]' \
// "impl<T> !Send for Outer<T>" // "impl<T> !Send for Outer<T>"
// //
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header"]' \ // @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//h3[@class="code-header"]' \
// "impl<T> !Sync for Outer<T>" // "impl<T> !Sync for Outer<T>"
pub struct Outer<T: Copy> { pub struct Outer<T: Copy> {
inner_field: Inner<T>, inner_field: Inner<T>,

View file

@ -9,10 +9,10 @@ where
} }
// @has nested/struct.Foo.html // @has nested/struct.Foo.html
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header"]' \ // @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//h3[@class="code-header"]' \
// 'impl<T> Send for Foo<T>where T: Copy' // 'impl<T> Send for Foo<T>where T: Copy'
// //
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header"]' \ // @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//h3[@class="code-header"]' \
// 'impl<T> Sync for Foo<T>where T: Sync' // 'impl<T> Sync for Foo<T>where T: Sync'
pub struct Foo<T> { pub struct Foo<T> {
inner_field: Inner<T>, inner_field: Inner<T>,

View file

@ -9,7 +9,7 @@ where
} }
// @has no_redundancy/struct.Outer.html // @has no_redundancy/struct.Outer.html
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header"]' \ // @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//h3[@class="code-header"]' \
// "impl<T> Send for Outer<T>where T: Send + Copy" // "impl<T> Send for Outer<T>where T: Send + Copy"
pub struct Outer<T> { pub struct Outer<T> {
inner_field: Inner<T>, inner_field: Inner<T>,

View file

@ -23,10 +23,10 @@ where
} }
// @has project/struct.Foo.html // @has project/struct.Foo.html
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header"]' \ // @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//h3[@class="code-header"]' \
// "impl<'c, K> Send for Foo<'c, K>where K: MyTrait<MyItem = bool>, 'c: 'static" // "impl<'c, K> Send for Foo<'c, K>where K: MyTrait<MyItem = bool>, 'c: 'static"
// //
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header"]' \ // @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//h3[@class="code-header"]' \
// "impl<'c, K> Sync for Foo<'c, K>where K: MyTrait, <K as MyTrait>::MyItem: OtherTrait, \ // "impl<'c, K> Sync for Foo<'c, K>where K: MyTrait, <K as MyTrait>::MyItem: OtherTrait, \
// 'c: 'static," // 'c: 'static,"
pub struct Foo<'c, K: 'c> { pub struct Foo<'c, K: 'c> {

View file

@ -23,7 +23,7 @@ impl<T> Pattern for Wrapper<T> {
// @has self_referential/struct.WriteAndThen.html // @has self_referential/struct.WriteAndThen.html
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header"]' \ // @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//h3[@class="code-header"]' \
// "impl<P1> Send for WriteAndThen<P1>where <P1 as Pattern>::Value: Send" // "impl<P1> Send for WriteAndThen<P1>where <P1 as Pattern>::Value: Send"
pub struct WriteAndThen<P1>(pub P1::Value,pub <Constrain<P1, Wrapper<P1::Value>> as Pattern>::Value) pub struct WriteAndThen<P1>(pub P1::Value,pub <Constrain<P1, Wrapper<P1::Value>> as Pattern>::Value)
where P1: Pattern; where P1: Pattern;

View file

@ -3,7 +3,7 @@ pub trait OwnedTrait<'a> {
} }
// @has static_region/struct.Owned.html // @has static_region/struct.Owned.html
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header"]' \ // @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//h3[@class="code-header"]' \
// "impl<T> Send for Owned<T>where <T as OwnedTrait<'static>>::Reader: Send" // "impl<T> Send for Owned<T>where <T as OwnedTrait<'static>>::Reader: Send"
pub struct Owned<T> where T: OwnedTrait<'static> { pub struct Owned<T> where T: OwnedTrait<'static> {
marker: <T as OwnedTrait<'static>>::Reader, marker: <T as OwnedTrait<'static>>::Reader,

View file

@ -9,8 +9,8 @@ impl MyStruct {
} }
// @has typedef/type.MyAlias.html // @has typedef/type.MyAlias.html
// @has - '//*[@class="impl has-srclink"]//h3[@class="code-header"]' 'impl MyAlias' // @has - '//*[@class="impl"]//h3[@class="code-header"]' 'impl MyAlias'
// @has - '//*[@class="impl has-srclink"]//h3[@class="code-header"]' 'impl MyTrait for MyAlias' // @has - '//*[@class="impl"]//h3[@class="code-header"]' 'impl MyTrait for MyAlias'
// @hasraw - 'Alias docstring' // @hasraw - 'Alias docstring'
// @has - '//*[@class="sidebar"]//*[@class="location"]' 'MyAlias' // @has - '//*[@class="sidebar"]//*[@class="location"]' 'MyAlias'
// @has - '//*[@class="sidebar"]//a[@href="#implementations"]' 'Methods' // @has - '//*[@class="sidebar"]//a[@href="#implementations"]' 'Methods'

View file

@ -13,7 +13,7 @@ pub fn charlie<C>() where C: MyTrait {}
pub struct Delta<D>(D); pub struct Delta<D>(D);
// @has foo/struct.Delta.html '//*[@class="impl has-srclink"]//h3[@class="code-header"]' \ // @has foo/struct.Delta.html '//*[@class="impl"]//h3[@class="code-header"]' \
// "impl<D> Delta<D>where D: MyTrait" // "impl<D> Delta<D>where D: MyTrait"
impl<D> Delta<D> where D: MyTrait { impl<D> Delta<D> where D: MyTrait {
pub fn delta() {} pub fn delta() {}
@ -43,7 +43,7 @@ pub trait TraitWhere {
{ todo!() } { todo!() }
} }
// @has foo/struct.Echo.html '//*[@class="impl has-srclink"]//h3[@class="code-header"]' \ // @has foo/struct.Echo.html '//*[@class="impl"]//h3[@class="code-header"]' \
// "impl<E> MyTrait for Echo<E>where E: MyTrait" // "impl<E> MyTrait for Echo<E>where E: MyTrait"
// @has foo/trait.MyTrait.html '//*[@id="implementors-list"]//h3[@class="code-header"]' \ // @has foo/trait.MyTrait.html '//*[@id="implementors-list"]//h3[@class="code-header"]' \
// "impl<E> MyTrait for Echo<E>where E: MyTrait" // "impl<E> MyTrait for Echo<E>where E: MyTrait"
@ -51,7 +51,7 @@ impl<E> MyTrait for Echo<E>where E: MyTrait {}
pub enum Foxtrot<F> { Foxtrot1(F) } pub enum Foxtrot<F> { Foxtrot1(F) }
// @has foo/enum.Foxtrot.html '//*[@class="impl has-srclink"]//h3[@class="code-header"]' \ // @has foo/enum.Foxtrot.html '//*[@class="impl"]//h3[@class="code-header"]' \
// "impl<F> MyTrait for Foxtrot<F>where F: MyTrait" // "impl<F> MyTrait for Foxtrot<F>where F: MyTrait"
// @has foo/trait.MyTrait.html '//*[@id="implementors-list"]//h3[@class="code-header"]' \ // @has foo/trait.MyTrait.html '//*[@id="implementors-list"]//h3[@class="code-header"]' \
// "impl<F> MyTrait for Foxtrot<F>where F: MyTrait" // "impl<F> MyTrait for Foxtrot<F>where F: MyTrait"

View file

@ -5,6 +5,8 @@ fn foo1(_: &dyn Drop + AsRef<str>) {} //~ ERROR ambiguous `+` in a type
fn foo2(_: &dyn (Drop + AsRef<str>)) {} //~ ERROR incorrect braces around trait bounds fn foo2(_: &dyn (Drop + AsRef<str>)) {} //~ ERROR incorrect braces around trait bounds
fn foo2_no_space(_: &dyn(Drop + AsRef<str>)) {} //~ ERROR incorrect braces around trait bounds
fn foo3(_: &dyn {Drop + AsRef<str>}) {} //~ ERROR expected parameter name, found `{` fn foo3(_: &dyn {Drop + AsRef<str>}) {} //~ ERROR expected parameter name, found `{`
//~^ ERROR expected one of `!`, `(`, `)`, `*`, `,`, `?`, `for`, `~`, lifetime, or path, found `{` //~^ ERROR expected one of `!`, `(`, `)`, `*`, `,`, `?`, `for`, `~`, lifetime, or path, found `{`
//~| ERROR at least one trait is required for an object type //~| ERROR at least one trait is required for an object type

View file

@ -16,14 +16,26 @@ LL - fn foo2(_: &dyn (Drop + AsRef<str>)) {}
LL + fn foo2(_: &dyn Drop + AsRef<str>) {} LL + fn foo2(_: &dyn Drop + AsRef<str>) {}
| |
error: incorrect braces around trait bounds
--> $DIR/trait-object-delimiters.rs:8:25
|
LL | fn foo2_no_space(_: &dyn(Drop + AsRef<str>)) {}
| ^ ^
|
help: remove the parentheses
|
LL - fn foo2_no_space(_: &dyn(Drop + AsRef<str>)) {}
LL + fn foo2_no_space(_: &dyn Drop + AsRef<str>) {}
|
error: expected parameter name, found `{` error: expected parameter name, found `{`
--> $DIR/trait-object-delimiters.rs:8:17 --> $DIR/trait-object-delimiters.rs:10:17
| |
LL | fn foo3(_: &dyn {Drop + AsRef<str>}) {} LL | fn foo3(_: &dyn {Drop + AsRef<str>}) {}
| ^ expected parameter name | ^ expected parameter name
error: expected one of `!`, `(`, `)`, `*`, `,`, `?`, `for`, `~`, lifetime, or path, found `{` error: expected one of `!`, `(`, `)`, `*`, `,`, `?`, `for`, `~`, lifetime, or path, found `{`
--> $DIR/trait-object-delimiters.rs:8:17 --> $DIR/trait-object-delimiters.rs:10:17
| |
LL | fn foo3(_: &dyn {Drop + AsRef<str>}) {} LL | fn foo3(_: &dyn {Drop + AsRef<str>}) {}
| -^ expected one of 10 possible tokens | -^ expected one of 10 possible tokens
@ -31,13 +43,13 @@ LL | fn foo3(_: &dyn {Drop + AsRef<str>}) {}
| help: missing `,` | help: missing `,`
error: expected identifier, found `<` error: expected identifier, found `<`
--> $DIR/trait-object-delimiters.rs:12:17 --> $DIR/trait-object-delimiters.rs:14:17
| |
LL | fn foo4(_: &dyn <Drop + AsRef<str>>) {} LL | fn foo4(_: &dyn <Drop + AsRef<str>>) {}
| ^ expected identifier | ^ expected identifier
error: invalid `dyn` keyword error: invalid `dyn` keyword
--> $DIR/trait-object-delimiters.rs:14:25 --> $DIR/trait-object-delimiters.rs:16:25
| |
LL | fn foo5(_: &(dyn Drop + dyn AsRef<str>)) {} LL | fn foo5(_: &(dyn Drop + dyn AsRef<str>)) {}
| ^^^ help: remove this keyword | ^^^ help: remove this keyword
@ -56,13 +68,13 @@ LL | fn foo1(_: &dyn Drop + AsRef<str>) {}
= 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> = 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[E0224]: at least one trait is required for an object type error[E0224]: at least one trait is required for an object type
--> $DIR/trait-object-delimiters.rs:8:13 --> $DIR/trait-object-delimiters.rs:10:13
| |
LL | fn foo3(_: &dyn {Drop + AsRef<str>}) {} LL | fn foo3(_: &dyn {Drop + AsRef<str>}) {}
| ^^^ | ^^^
error[E0225]: only auto traits can be used as additional traits in a trait object error[E0225]: only auto traits can be used as additional traits in a trait object
--> $DIR/trait-object-delimiters.rs:14:29 --> $DIR/trait-object-delimiters.rs:16:29
| |
LL | fn foo5(_: &(dyn Drop + dyn AsRef<str>)) {} LL | fn foo5(_: &(dyn Drop + dyn AsRef<str>)) {}
| ---- ^^^^^^^^^^ additional non-auto trait | ---- ^^^^^^^^^^ additional non-auto trait
@ -72,7 +84,7 @@ LL | fn foo5(_: &(dyn Drop + dyn AsRef<str>)) {}
= help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Drop + AsRef<str> {}` = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Drop + AsRef<str> {}`
= 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> = 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: aborting due to 9 previous errors error: aborting due to 10 previous errors
Some errors have detailed explanations: E0224, E0225. Some errors have detailed explanations: E0224, E0225.
For more information about an error, try `rustc --explain E0224`. For more information about an error, try `rustc --explain E0224`.

View file

@ -0,0 +1,4 @@
// compile-flags: -Z unpretty=thir-flat
// check-pass
pub fn main() {}

View file

@ -1,4 +1,4 @@
DefId(0:3 ~ thir_tree[8f1d]::main): DefId(0:3 ~ thir_flat[45a6]::main):
Thir { Thir {
arms: [], arms: [],
blocks: [ blocks: [
@ -6,7 +6,7 @@ Thir {
targeted_by_break: false, targeted_by_break: false,
region_scope: Node(1), region_scope: Node(1),
opt_destruction_scope: None, opt_destruction_scope: None,
span: $DIR/thir-tree.rs:4:15: 4:17 (#0), span: $DIR/thir-flat.rs:4:15: 4:17 (#0),
stmts: [], stmts: [],
expr: None, expr: None,
safety_mode: Safe, safety_mode: Safe,
@ -18,7 +18,7 @@ Thir {
temp_lifetime: Some( temp_lifetime: Some(
Node(2), Node(2),
), ),
span: $DIR/thir-tree.rs:4:15: 4:17 (#0), span: $DIR/thir-flat.rs:4:15: 4:17 (#0),
kind: Block { kind: Block {
block: b0, block: b0,
}, },
@ -28,11 +28,11 @@ Thir {
temp_lifetime: Some( temp_lifetime: Some(
Node(2), Node(2),
), ),
span: $DIR/thir-tree.rs:4:15: 4:17 (#0), span: $DIR/thir-flat.rs:4:15: 4:17 (#0),
kind: Scope { kind: Scope {
region_scope: Node(2), region_scope: Node(2),
lint_level: Explicit( lint_level: Explicit(
HirId(DefId(0:3 ~ thir_tree[8f1d]::main).2), HirId(DefId(0:3 ~ thir_flat[45a6]::main).2),
), ),
value: e0, value: e0,
}, },
@ -42,7 +42,7 @@ Thir {
temp_lifetime: Some( temp_lifetime: Some(
Node(2), Node(2),
), ),
span: $DIR/thir-tree.rs:4:15: 4:17 (#0), span: $DIR/thir-flat.rs:4:15: 4:17 (#0),
kind: Scope { kind: Scope {
region_scope: Destruction(2), region_scope: Destruction(2),
lint_level: Inherited, lint_level: Inherited,

View file

@ -0,0 +1,23 @@
// check-pass
// compile-flags: -Zunpretty=thir-tree
enum Bar {
First,
Second,
Third,
}
enum Foo {
FooOne(Bar),
FooTwo,
}
fn has_match(foo: Foo) -> bool {
match foo {
Foo::FooOne(Bar::First) => true,
Foo::FooOne(_) => false,
Foo::FooTwo => true,
}
}
fn main() {}

View file

@ -0,0 +1,342 @@
DefId(0:16 ~ thir_tree_match[3c9a]::has_match):
params: [
Param {
ty: Foo
ty_span: Some($DIR/thir-tree-match.rs:15:19: 15:22 (#0))
self_kind: None
hir_id: Some(HirId(DefId(0:16 ~ thir_tree_match[3c9a]::has_match).1))
param: Some(
Pat: {
ty: Foo
span: $DIR/thir-tree-match.rs:15:14: 15:17 (#0)
kind: PatKind {
Binding {
mutability: Not
name: "foo"
mode: ByValue
var: LocalVarId(HirId(DefId(0:16 ~ thir_tree_match[3c9a]::has_match).2))
ty: Foo
is_primary: true
subpattern: None
}
}
}
)
}
]
body:
Expr {
ty: bool
temp_lifetime: Some(Node(26))
span: $DIR/thir-tree-match.rs:15:32: 21:2 (#0)
kind:
Scope {
region_scope: Destruction(26)
lint_level: Inherited
value:
Expr {
ty: bool
temp_lifetime: Some(Node(26))
span: $DIR/thir-tree-match.rs:15:32: 21:2 (#0)
kind:
Scope {
region_scope: Node(26)
lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[3c9a]::has_match).26))
value:
Expr {
ty: bool
temp_lifetime: Some(Node(26))
span: $DIR/thir-tree-match.rs:15:32: 21:2 (#0)
kind:
Block {
targeted_by_break: false
opt_destruction_scope: None
span: $DIR/thir-tree-match.rs:15:32: 21:2 (#0)
region_scope: Node(25)
safety_mode: Safe
stmts: []
expr:
Expr {
ty: bool
temp_lifetime: Some(Node(26))
span: $DIR/thir-tree-match.rs:16:5: 20:6 (#0)
kind:
Scope {
region_scope: Node(3)
lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[3c9a]::has_match).3))
value:
Expr {
ty: bool
temp_lifetime: Some(Node(26))
span: $DIR/thir-tree-match.rs:16:5: 20:6 (#0)
kind:
Match {
scrutinee:
Expr {
ty: Foo
temp_lifetime: Some(Node(26))
span: $DIR/thir-tree-match.rs:16:11: 16:14 (#0)
kind:
Scope {
region_scope: Node(4)
lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[3c9a]::has_match).4))
value:
Expr {
ty: Foo
temp_lifetime: Some(Node(26))
span: $DIR/thir-tree-match.rs:16:11: 16:14 (#0)
kind:
VarRef {
id: LocalVarId(HirId(DefId(0:16 ~ thir_tree_match[3c9a]::has_match).2))
}
}
}
}
arms: [
Arm {
pattern:
Pat: {
ty: Foo
span: $DIR/thir-tree-match.rs:17:9: 17:32 (#0)
kind: PatKind {
Variant {
adt_def:
AdtDef {
did: DefId(0:10 ~ thir_tree_match[3c9a]::Foo)
variants: [VariantDef { def_id: DefId(0:11 ~ thir_tree_match[3c9a]::Foo::FooOne), ctor: Some((Fn, DefId(0:12 ~ thir_tree_match[3c9a]::Foo::FooOne::{constructor#0}))), name: "FooOne", discr: Relative(0), fields: [FieldDef { did: DefId(0:13 ~ thir_tree_match[3c9a]::Foo::FooOne::0), name: "0", vis: Restricted(DefId(0:0 ~ thir_tree_match[3c9a])) }], flags: NO_VARIANT_FLAGS }, VariantDef { def_id: DefId(0:14 ~ thir_tree_match[3c9a]::Foo::FooTwo), ctor: Some((Const, DefId(0:15 ~ thir_tree_match[3c9a]::Foo::FooTwo::{constructor#0}))), name: "FooTwo", discr: Relative(1), fields: [], flags: NO_VARIANT_FLAGS }]
flags: IS_ENUM
repr: ReprOptions { int: None, align: None, pack: None, flags: (empty), field_shuffle_seed: 11573694388057581 }
substs: []
variant_index: 0
subpatterns: [
Pat: {
ty: Bar
span: $DIR/thir-tree-match.rs:17:21: 17:31 (#0)
kind: PatKind {
Variant {
adt_def:
AdtDef {
did: DefId(0:3 ~ thir_tree_match[3c9a]::Bar)
variants: [VariantDef { def_id: DefId(0:4 ~ thir_tree_match[3c9a]::Bar::First), ctor: Some((Const, DefId(0:5 ~ thir_tree_match[3c9a]::Bar::First::{constructor#0}))), name: "First", discr: Relative(0), fields: [], flags: NO_VARIANT_FLAGS }, VariantDef { def_id: DefId(0:6 ~ thir_tree_match[3c9a]::Bar::Second), ctor: Some((Const, DefId(0:7 ~ thir_tree_match[3c9a]::Bar::Second::{constructor#0}))), name: "Second", discr: Relative(1), fields: [], flags: NO_VARIANT_FLAGS }, VariantDef { def_id: DefId(0:8 ~ thir_tree_match[3c9a]::Bar::Third), ctor: Some((Const, DefId(0:9 ~ thir_tree_match[3c9a]::Bar::Third::{constructor#0}))), name: "Third", discr: Relative(2), fields: [], flags: NO_VARIANT_FLAGS }]
flags: IS_ENUM
repr: ReprOptions { int: None, align: None, pack: None, flags: (empty), field_shuffle_seed: 3125160937860410723 }
substs: []
variant_index: 0
subpatterns: []
}
}
}
]
}
}
}
guard: None
body:
Expr {
ty: bool
temp_lifetime: Some(Node(13))
span: $DIR/thir-tree-match.rs:17:36: 17:40 (#0)
kind:
Scope {
region_scope: Destruction(13)
lint_level: Inherited
value:
Expr {
ty: bool
temp_lifetime: Some(Node(13))
span: $DIR/thir-tree-match.rs:17:36: 17:40 (#0)
kind:
Scope {
region_scope: Node(13)
lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[3c9a]::has_match).13))
value:
Expr {
ty: bool
temp_lifetime: Some(Node(13))
span: $DIR/thir-tree-match.rs:17:36: 17:40 (#0)
kind:
Literal( lit: Spanned { node: Bool(true), span: $DIR/thir-tree-match.rs:17:36: 17:40 (#0) }, neg: false)
}
}
}
}
}
lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[3c9a]::has_match).12))
scope: Node(12)
span: $DIR/thir-tree-match.rs:17:9: 17:40 (#0)
}
Arm {
pattern:
Pat: {
ty: Foo
span: $DIR/thir-tree-match.rs:18:9: 18:23 (#0)
kind: PatKind {
Variant {
adt_def:
AdtDef {
did: DefId(0:10 ~ thir_tree_match[3c9a]::Foo)
variants: [VariantDef { def_id: DefId(0:11 ~ thir_tree_match[3c9a]::Foo::FooOne), ctor: Some((Fn, DefId(0:12 ~ thir_tree_match[3c9a]::Foo::FooOne::{constructor#0}))), name: "FooOne", discr: Relative(0), fields: [FieldDef { did: DefId(0:13 ~ thir_tree_match[3c9a]::Foo::FooOne::0), name: "0", vis: Restricted(DefId(0:0 ~ thir_tree_match[3c9a])) }], flags: NO_VARIANT_FLAGS }, VariantDef { def_id: DefId(0:14 ~ thir_tree_match[3c9a]::Foo::FooTwo), ctor: Some((Const, DefId(0:15 ~ thir_tree_match[3c9a]::Foo::FooTwo::{constructor#0}))), name: "FooTwo", discr: Relative(1), fields: [], flags: NO_VARIANT_FLAGS }]
flags: IS_ENUM
repr: ReprOptions { int: None, align: None, pack: None, flags: (empty), field_shuffle_seed: 11573694388057581 }
substs: []
variant_index: 0
subpatterns: [
Pat: {
ty: Bar
span: $DIR/thir-tree-match.rs:18:21: 18:22 (#0)
kind: PatKind {
Wild
}
}
]
}
}
}
guard: None
body:
Expr {
ty: bool
temp_lifetime: Some(Node(19))
span: $DIR/thir-tree-match.rs:18:27: 18:32 (#0)
kind:
Scope {
region_scope: Destruction(19)
lint_level: Inherited
value:
Expr {
ty: bool
temp_lifetime: Some(Node(19))
span: $DIR/thir-tree-match.rs:18:27: 18:32 (#0)
kind:
Scope {
region_scope: Node(19)
lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[3c9a]::has_match).19))
value:
Expr {
ty: bool
temp_lifetime: Some(Node(19))
span: $DIR/thir-tree-match.rs:18:27: 18:32 (#0)
kind:
Literal( lit: Spanned { node: Bool(false), span: $DIR/thir-tree-match.rs:18:27: 18:32 (#0) }, neg: false)
}
}
}
}
}
lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[3c9a]::has_match).18))
scope: Node(18)
span: $DIR/thir-tree-match.rs:18:9: 18:32 (#0)
}
Arm {
pattern:
Pat: {
ty: Foo
span: $DIR/thir-tree-match.rs:19:9: 19:20 (#0)
kind: PatKind {
Variant {
adt_def:
AdtDef {
did: DefId(0:10 ~ thir_tree_match[3c9a]::Foo)
variants: [VariantDef { def_id: DefId(0:11 ~ thir_tree_match[3c9a]::Foo::FooOne), ctor: Some((Fn, DefId(0:12 ~ thir_tree_match[3c9a]::Foo::FooOne::{constructor#0}))), name: "FooOne", discr: Relative(0), fields: [FieldDef { did: DefId(0:13 ~ thir_tree_match[3c9a]::Foo::FooOne::0), name: "0", vis: Restricted(DefId(0:0 ~ thir_tree_match[3c9a])) }], flags: NO_VARIANT_FLAGS }, VariantDef { def_id: DefId(0:14 ~ thir_tree_match[3c9a]::Foo::FooTwo), ctor: Some((Const, DefId(0:15 ~ thir_tree_match[3c9a]::Foo::FooTwo::{constructor#0}))), name: "FooTwo", discr: Relative(1), fields: [], flags: NO_VARIANT_FLAGS }]
flags: IS_ENUM
repr: ReprOptions { int: None, align: None, pack: None, flags: (empty), field_shuffle_seed: 11573694388057581 }
substs: []
variant_index: 1
subpatterns: []
}
}
}
guard: None
body:
Expr {
ty: bool
temp_lifetime: Some(Node(24))
span: $DIR/thir-tree-match.rs:19:24: 19:28 (#0)
kind:
Scope {
region_scope: Destruction(24)
lint_level: Inherited
value:
Expr {
ty: bool
temp_lifetime: Some(Node(24))
span: $DIR/thir-tree-match.rs:19:24: 19:28 (#0)
kind:
Scope {
region_scope: Node(24)
lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[3c9a]::has_match).24))
value:
Expr {
ty: bool
temp_lifetime: Some(Node(24))
span: $DIR/thir-tree-match.rs:19:24: 19:28 (#0)
kind:
Literal( lit: Spanned { node: Bool(true), span: $DIR/thir-tree-match.rs:19:24: 19:28 (#0) }, neg: false)
}
}
}
}
}
lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[3c9a]::has_match).23))
scope: Node(23)
span: $DIR/thir-tree-match.rs:19:9: 19:28 (#0)
}
]
}
}
}
}
}
}
}
}
}
}
DefId(0:17 ~ thir_tree_match[3c9a]::main):
params: [
]
body:
Expr {
ty: ()
temp_lifetime: Some(Node(2))
span: $DIR/thir-tree-match.rs:23:11: 23:13 (#0)
kind:
Scope {
region_scope: Destruction(2)
lint_level: Inherited
value:
Expr {
ty: ()
temp_lifetime: Some(Node(2))
span: $DIR/thir-tree-match.rs:23:11: 23:13 (#0)
kind:
Scope {
region_scope: Node(2)
lint_level: Explicit(HirId(DefId(0:17 ~ thir_tree_match[3c9a]::main).2))
value:
Expr {
ty: ()
temp_lifetime: Some(Node(2))
span: $DIR/thir-tree-match.rs:23:11: 23:13 (#0)
kind:
Block {
targeted_by_break: false
opt_destruction_scope: None
span: $DIR/thir-tree-match.rs:23:11: 23:13 (#0)
region_scope: Node(1)
safety_mode: Safe
stmts: []
expr: []
}
}
}
}
}
}

View file

@ -0,0 +1,43 @@
DefId(0:3 ~ thir_tree[8f1d]::main):
params: [
]
body:
Expr {
ty: ()
temp_lifetime: Some(Node(2))
span: $DIR/thir-tree.rs:4:15: 4:17 (#0)
kind:
Scope {
region_scope: Destruction(2)
lint_level: Inherited
value:
Expr {
ty: ()
temp_lifetime: Some(Node(2))
span: $DIR/thir-tree.rs:4:15: 4:17 (#0)
kind:
Scope {
region_scope: Node(2)
lint_level: Explicit(HirId(DefId(0:3 ~ thir_tree[8f1d]::main).2))
value:
Expr {
ty: ()
temp_lifetime: Some(Node(2))
span: $DIR/thir-tree.rs:4:15: 4:17 (#0)
kind:
Block {
targeted_by_break: false
opt_destruction_scope: None
span: $DIR/thir-tree.rs:4:15: 4:17 (#0)
region_scope: Node(1)
safety_mode: Safe
stmts: []
expr: []
}
}
}
}
}
}