Auto merge of #100063 - matthiaskrgr:rollup-lznouys, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - #99987 (Always include a position span in `rustc_parse_format::Argument`) - #100005 (Remove Clean trait for ast::Attribute and improve Attributes::from_ast) - #100025 (Remove redundant `TransferWrapper` struct) - #100045 (Properly reject the `may_unwind` option in `global_asm!`) - #100052 (RISC-V ASM test: relax label name constraint.) - #100053 (move [`assertions_on_result_states`] to restriction) - #100057 (Remove more Clean trait implementations) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
4493a0f472
23 changed files with 185 additions and 150 deletions
|
@ -410,12 +410,12 @@ fn parse_options<'a>(
|
||||||
try_set_option(p, args, sym::noreturn, ast::InlineAsmOptions::NORETURN);
|
try_set_option(p, args, sym::noreturn, ast::InlineAsmOptions::NORETURN);
|
||||||
} else if !is_global_asm && p.eat_keyword(sym::nostack) {
|
} else if !is_global_asm && p.eat_keyword(sym::nostack) {
|
||||||
try_set_option(p, args, sym::nostack, ast::InlineAsmOptions::NOSTACK);
|
try_set_option(p, args, sym::nostack, ast::InlineAsmOptions::NOSTACK);
|
||||||
|
} else if !is_global_asm && p.eat_keyword(sym::may_unwind) {
|
||||||
|
try_set_option(p, args, kw::Raw, ast::InlineAsmOptions::MAY_UNWIND);
|
||||||
} else if p.eat_keyword(sym::att_syntax) {
|
} else if p.eat_keyword(sym::att_syntax) {
|
||||||
try_set_option(p, args, sym::att_syntax, ast::InlineAsmOptions::ATT_SYNTAX);
|
try_set_option(p, args, sym::att_syntax, ast::InlineAsmOptions::ATT_SYNTAX);
|
||||||
} else if p.eat_keyword(kw::Raw) {
|
} else if p.eat_keyword(kw::Raw) {
|
||||||
try_set_option(p, args, kw::Raw, ast::InlineAsmOptions::RAW);
|
try_set_option(p, args, kw::Raw, ast::InlineAsmOptions::RAW);
|
||||||
} else if p.eat_keyword(sym::may_unwind) {
|
|
||||||
try_set_option(p, args, kw::Raw, ast::InlineAsmOptions::MAY_UNWIND);
|
|
||||||
} else {
|
} else {
|
||||||
return p.unexpected();
|
return p.unexpected();
|
||||||
}
|
}
|
||||||
|
@ -656,7 +656,7 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, args: AsmArgs) -> Option<ast::Inl
|
||||||
let span = arg_spans.next().unwrap_or(template_sp);
|
let span = arg_spans.next().unwrap_or(template_sp);
|
||||||
|
|
||||||
let operand_idx = match arg.position {
|
let operand_idx = match arg.position {
|
||||||
parse::ArgumentIs(idx, _) | parse::ArgumentImplicitlyIs(idx) => {
|
parse::ArgumentIs(idx) | parse::ArgumentImplicitlyIs(idx) => {
|
||||||
if idx >= args.operands.len()
|
if idx >= args.operands.len()
|
||||||
|| named_pos.contains_key(&idx)
|
|| named_pos.contains_key(&idx)
|
||||||
|| args.reg_args.contains(&idx)
|
|| args.reg_args.contains(&idx)
|
||||||
|
@ -702,11 +702,12 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, args: AsmArgs) -> Option<ast::Inl
|
||||||
Some(idx)
|
Some(idx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
parse::ArgumentNamed(name, span) => {
|
parse::ArgumentNamed(name) => {
|
||||||
match args.named_args.get(&Symbol::intern(name)) {
|
match args.named_args.get(&Symbol::intern(name)) {
|
||||||
Some(&idx) => Some(idx),
|
Some(&idx) => Some(idx),
|
||||||
None => {
|
None => {
|
||||||
let msg = format!("there is no argument named `{}`", name);
|
let msg = format!("there is no argument named `{}`", name);
|
||||||
|
let span = arg.position_span;
|
||||||
ecx.struct_span_err(
|
ecx.struct_span_err(
|
||||||
template_span
|
template_span
|
||||||
.from_inner(InnerSpan::new(span.start, span.end)),
|
.from_inner(InnerSpan::new(span.start, span.end)),
|
||||||
|
|
|
@ -381,8 +381,8 @@ impl<'a, 'b> Context<'a, 'b> {
|
||||||
match *p {
|
match *p {
|
||||||
parse::String(_) => {}
|
parse::String(_) => {}
|
||||||
parse::NextArgument(ref mut arg) => {
|
parse::NextArgument(ref mut arg) => {
|
||||||
if let parse::ArgumentNamed(s, _) = arg.position {
|
if let parse::ArgumentNamed(s) = arg.position {
|
||||||
arg.position = parse::ArgumentIs(lookup(s), None);
|
arg.position = parse::ArgumentIs(lookup(s));
|
||||||
}
|
}
|
||||||
if let parse::CountIsName(s, _) = arg.format.width {
|
if let parse::CountIsName(s, _) = arg.format.width {
|
||||||
arg.format.width = parse::CountIsParam(lookup(s));
|
arg.format.width = parse::CountIsParam(lookup(s));
|
||||||
|
@ -417,14 +417,14 @@ impl<'a, 'b> Context<'a, 'b> {
|
||||||
// argument second, if it's an implicit positional parameter
|
// argument second, if it's an implicit positional parameter
|
||||||
// it's written second, so it should come after width/precision.
|
// it's written second, so it should come after width/precision.
|
||||||
let pos = match arg.position {
|
let pos = match arg.position {
|
||||||
parse::ArgumentIs(i, arg_end) => {
|
parse::ArgumentIs(i) => {
|
||||||
self.unused_names_lint.maybe_add_positional_named_arg(
|
self.unused_names_lint.maybe_add_positional_named_arg(
|
||||||
i,
|
i,
|
||||||
self.args.len(),
|
self.args.len(),
|
||||||
i,
|
i,
|
||||||
PositionalNamedArgType::Arg,
|
PositionalNamedArgType::Arg,
|
||||||
self.curpiece,
|
self.curpiece,
|
||||||
arg_end,
|
Some(arg.position_span),
|
||||||
&self.names,
|
&self.names,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -442,8 +442,9 @@ impl<'a, 'b> Context<'a, 'b> {
|
||||||
);
|
);
|
||||||
Exact(i)
|
Exact(i)
|
||||||
}
|
}
|
||||||
parse::ArgumentNamed(s, span) => {
|
parse::ArgumentNamed(s) => {
|
||||||
let symbol = Symbol::intern(s);
|
let symbol = Symbol::intern(s);
|
||||||
|
let span = arg.position_span;
|
||||||
Named(symbol, InnerSpan::new(span.start, span.end))
|
Named(symbol, InnerSpan::new(span.start, span.end))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -878,8 +879,9 @@ impl<'a, 'b> Context<'a, 'b> {
|
||||||
// track the current argument ourselves.
|
// track the current argument ourselves.
|
||||||
let i = self.curarg;
|
let i = self.curarg;
|
||||||
self.curarg += 1;
|
self.curarg += 1;
|
||||||
parse::ArgumentIs(i, None)
|
parse::ArgumentIs(i)
|
||||||
},
|
},
|
||||||
|
position_span: arg.position_span,
|
||||||
format: parse::FormatSpec {
|
format: parse::FormatSpec {
|
||||||
fill: arg.format.fill,
|
fill: arg.format.fill,
|
||||||
align: parse::AlignUnknown,
|
align: parse::AlignUnknown,
|
||||||
|
|
|
@ -222,18 +222,6 @@ impl<'a, 'tcx> AnalysisDomain<'tcx> for MaybeTransitiveLiveLocals<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct TransferWrapper<'a>(&'a mut ChunkedBitSet<Local>);
|
|
||||||
|
|
||||||
impl<'a> GenKill<Local> for TransferWrapper<'a> {
|
|
||||||
fn gen(&mut self, l: Local) {
|
|
||||||
self.0.insert(l);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn kill(&mut self, l: Local) {
|
|
||||||
self.0.remove(l);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, 'tcx> Analysis<'tcx> for MaybeTransitiveLiveLocals<'a> {
|
impl<'a, 'tcx> Analysis<'tcx> for MaybeTransitiveLiveLocals<'a> {
|
||||||
fn apply_statement_effect(
|
fn apply_statement_effect(
|
||||||
&self,
|
&self,
|
||||||
|
@ -271,7 +259,7 @@ impl<'a, 'tcx> Analysis<'tcx> for MaybeTransitiveLiveLocals<'a> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TransferFunction(&mut TransferWrapper(trans)).visit_statement(statement, location);
|
TransferFunction(trans).visit_statement(statement, location);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn apply_terminator_effect(
|
fn apply_terminator_effect(
|
||||||
|
@ -280,7 +268,7 @@ impl<'a, 'tcx> Analysis<'tcx> for MaybeTransitiveLiveLocals<'a> {
|
||||||
terminator: &mir::Terminator<'tcx>,
|
terminator: &mir::Terminator<'tcx>,
|
||||||
location: Location,
|
location: Location,
|
||||||
) {
|
) {
|
||||||
TransferFunction(&mut TransferWrapper(trans)).visit_terminator(terminator, location);
|
TransferFunction(trans).visit_terminator(terminator, location);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn apply_call_return_effect(
|
fn apply_call_return_effect(
|
||||||
|
|
|
@ -70,6 +70,9 @@ pub enum Piece<'a> {
|
||||||
pub struct Argument<'a> {
|
pub struct Argument<'a> {
|
||||||
/// Where to find this argument
|
/// Where to find this argument
|
||||||
pub position: Position<'a>,
|
pub position: Position<'a>,
|
||||||
|
/// The span of the position indicator. Includes any whitespace in implicit
|
||||||
|
/// positions (`{ }`).
|
||||||
|
pub position_span: InnerSpan,
|
||||||
/// How to format the argument
|
/// How to format the argument
|
||||||
pub format: FormatSpec<'a>,
|
pub format: FormatSpec<'a>,
|
||||||
}
|
}
|
||||||
|
@ -105,9 +108,9 @@ pub enum Position<'a> {
|
||||||
/// The argument is implied to be located at an index
|
/// The argument is implied to be located at an index
|
||||||
ArgumentImplicitlyIs(usize),
|
ArgumentImplicitlyIs(usize),
|
||||||
/// The argument is located at a specific index given in the format,
|
/// The argument is located at a specific index given in the format,
|
||||||
ArgumentIs(usize, Option<InnerSpan>),
|
ArgumentIs(usize),
|
||||||
/// The argument has a name.
|
/// The argument has a name.
|
||||||
ArgumentNamed(&'a str, InnerSpan),
|
ArgumentNamed(&'a str),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Position<'_> {
|
impl Position<'_> {
|
||||||
|
@ -216,14 +219,15 @@ impl<'a> Iterator for Parser<'a> {
|
||||||
'{' => {
|
'{' => {
|
||||||
let curr_last_brace = self.last_opening_brace;
|
let curr_last_brace = self.last_opening_brace;
|
||||||
let byte_pos = self.to_span_index(pos);
|
let byte_pos = self.to_span_index(pos);
|
||||||
self.last_opening_brace = Some(byte_pos.to(InnerOffset(byte_pos.0 + 1)));
|
let lbrace_end = InnerOffset(byte_pos.0 + 1);
|
||||||
|
self.last_opening_brace = Some(byte_pos.to(lbrace_end));
|
||||||
self.cur.next();
|
self.cur.next();
|
||||||
if self.consume('{') {
|
if self.consume('{') {
|
||||||
self.last_opening_brace = curr_last_brace;
|
self.last_opening_brace = curr_last_brace;
|
||||||
|
|
||||||
Some(String(self.string(pos + 1)))
|
Some(String(self.string(pos + 1)))
|
||||||
} else {
|
} else {
|
||||||
let arg = self.argument();
|
let arg = self.argument(lbrace_end);
|
||||||
if let Some(rbrace_byte_idx) = self.must_consume('}') {
|
if let Some(rbrace_byte_idx) = self.must_consume('}') {
|
||||||
let lbrace_inner_offset = self.to_span_index(pos);
|
let lbrace_inner_offset = self.to_span_index(pos);
|
||||||
let rbrace_inner_offset = self.to_span_index(rbrace_byte_idx);
|
let rbrace_inner_offset = self.to_span_index(rbrace_byte_idx);
|
||||||
|
@ -477,8 +481,16 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parses an `Argument` structure, or what's contained within braces inside the format string.
|
/// Parses an `Argument` structure, or what's contained within braces inside the format string.
|
||||||
fn argument(&mut self) -> Argument<'a> {
|
fn argument(&mut self, start: InnerOffset) -> Argument<'a> {
|
||||||
let pos = self.position();
|
let pos = self.position();
|
||||||
|
|
||||||
|
let end = self
|
||||||
|
.cur
|
||||||
|
.clone()
|
||||||
|
.find(|(_, ch)| !ch.is_whitespace())
|
||||||
|
.map_or(start, |(end, _)| self.to_span_index(end));
|
||||||
|
let position_span = start.to(end);
|
||||||
|
|
||||||
let format = match self.mode {
|
let format = match self.mode {
|
||||||
ParseMode::Format => self.format(),
|
ParseMode::Format => self.format(),
|
||||||
ParseMode::InlineAsm => self.inline_asm(),
|
ParseMode::InlineAsm => self.inline_asm(),
|
||||||
|
@ -494,7 +506,7 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Argument { position: pos, format }
|
Argument { position: pos, position_span, format }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parses a positional argument for a format. This could either be an
|
/// Parses a positional argument for a format. This could either be an
|
||||||
|
@ -502,23 +514,11 @@ impl<'a> Parser<'a> {
|
||||||
/// Returns `Some(parsed_position)` if the position is not implicitly
|
/// Returns `Some(parsed_position)` if the position is not implicitly
|
||||||
/// consuming a macro argument, `None` if it's the case.
|
/// consuming a macro argument, `None` if it's the case.
|
||||||
fn position(&mut self) -> Option<Position<'a>> {
|
fn position(&mut self) -> Option<Position<'a>> {
|
||||||
let start_position = self.cur.peek().map(|item| item.0);
|
|
||||||
if let Some(i) = self.integer() {
|
if let Some(i) = self.integer() {
|
||||||
let inner_span = start_position.and_then(|start| {
|
Some(ArgumentIs(i))
|
||||||
self.cur
|
|
||||||
.peek()
|
|
||||||
.cloned()
|
|
||||||
.and_then(|item| Some(self.to_span_index(start).to(self.to_span_index(item.0))))
|
|
||||||
});
|
|
||||||
Some(ArgumentIs(i, inner_span))
|
|
||||||
} else {
|
} else {
|
||||||
match self.cur.peek() {
|
match self.cur.peek() {
|
||||||
Some(&(start, c)) if rustc_lexer::is_id_start(c) => {
|
Some(&(_, c)) if rustc_lexer::is_id_start(c) => Some(ArgumentNamed(self.word())),
|
||||||
let word = self.word();
|
|
||||||
let end = start + word.len();
|
|
||||||
let span = self.to_span_index(start).to(self.to_span_index(end));
|
|
||||||
Some(ArgumentNamed(word, span))
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is an `ArgumentNext`.
|
// This is an `ArgumentNext`.
|
||||||
// Record the fact and do the resolution after parsing the
|
// Record the fact and do the resolution after parsing the
|
||||||
|
|
|
@ -58,14 +58,22 @@ fn invalid06() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn format_nothing() {
|
fn format_nothing() {
|
||||||
same("{}", &[NextArgument(Argument { position: ArgumentImplicitlyIs(0), format: fmtdflt() })]);
|
same(
|
||||||
|
"{}",
|
||||||
|
&[NextArgument(Argument {
|
||||||
|
position: ArgumentImplicitlyIs(0),
|
||||||
|
position_span: InnerSpan { start: 2, end: 2 },
|
||||||
|
format: fmtdflt(),
|
||||||
|
})],
|
||||||
|
);
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn format_position() {
|
fn format_position() {
|
||||||
same(
|
same(
|
||||||
"{3}",
|
"{3}",
|
||||||
&[NextArgument(Argument {
|
&[NextArgument(Argument {
|
||||||
position: ArgumentIs(3, Some(InnerSpan { start: 2, end: 3 })),
|
position: ArgumentIs(3),
|
||||||
|
position_span: InnerSpan { start: 2, end: 3 },
|
||||||
format: fmtdflt(),
|
format: fmtdflt(),
|
||||||
})],
|
})],
|
||||||
);
|
);
|
||||||
|
@ -75,17 +83,30 @@ fn format_position_nothing_else() {
|
||||||
same(
|
same(
|
||||||
"{3:}",
|
"{3:}",
|
||||||
&[NextArgument(Argument {
|
&[NextArgument(Argument {
|
||||||
position: ArgumentIs(3, Some(InnerSpan { start: 2, end: 3 })),
|
position: ArgumentIs(3),
|
||||||
|
position_span: InnerSpan { start: 2, end: 3 },
|
||||||
format: fmtdflt(),
|
format: fmtdflt(),
|
||||||
})],
|
})],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
|
fn format_named() {
|
||||||
|
same(
|
||||||
|
"{name}",
|
||||||
|
&[NextArgument(Argument {
|
||||||
|
position: ArgumentNamed("name"),
|
||||||
|
position_span: InnerSpan { start: 2, end: 6 },
|
||||||
|
format: fmtdflt(),
|
||||||
|
})],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
fn format_type() {
|
fn format_type() {
|
||||||
same(
|
same(
|
||||||
"{3:x}",
|
"{3:x}",
|
||||||
&[NextArgument(Argument {
|
&[NextArgument(Argument {
|
||||||
position: ArgumentIs(3, Some(InnerSpan { start: 2, end: 3 })),
|
position: ArgumentIs(3),
|
||||||
|
position_span: InnerSpan { start: 2, end: 3 },
|
||||||
format: FormatSpec {
|
format: FormatSpec {
|
||||||
fill: None,
|
fill: None,
|
||||||
align: AlignUnknown,
|
align: AlignUnknown,
|
||||||
|
@ -105,7 +126,8 @@ fn format_align_fill() {
|
||||||
same(
|
same(
|
||||||
"{3:>}",
|
"{3:>}",
|
||||||
&[NextArgument(Argument {
|
&[NextArgument(Argument {
|
||||||
position: ArgumentIs(3, Some(InnerSpan { start: 2, end: 3 })),
|
position: ArgumentIs(3),
|
||||||
|
position_span: InnerSpan { start: 2, end: 3 },
|
||||||
format: FormatSpec {
|
format: FormatSpec {
|
||||||
fill: None,
|
fill: None,
|
||||||
align: AlignRight,
|
align: AlignRight,
|
||||||
|
@ -122,7 +144,8 @@ fn format_align_fill() {
|
||||||
same(
|
same(
|
||||||
"{3:0<}",
|
"{3:0<}",
|
||||||
&[NextArgument(Argument {
|
&[NextArgument(Argument {
|
||||||
position: ArgumentIs(3, Some(InnerSpan { start: 2, end: 3 })),
|
position: ArgumentIs(3),
|
||||||
|
position_span: InnerSpan { start: 2, end: 3 },
|
||||||
format: FormatSpec {
|
format: FormatSpec {
|
||||||
fill: Some('0'),
|
fill: Some('0'),
|
||||||
align: AlignLeft,
|
align: AlignLeft,
|
||||||
|
@ -139,7 +162,8 @@ fn format_align_fill() {
|
||||||
same(
|
same(
|
||||||
"{3:*<abcd}",
|
"{3:*<abcd}",
|
||||||
&[NextArgument(Argument {
|
&[NextArgument(Argument {
|
||||||
position: ArgumentIs(3, Some(InnerSpan { start: 2, end: 3 })),
|
position: ArgumentIs(3),
|
||||||
|
position_span: InnerSpan { start: 2, end: 3 },
|
||||||
format: FormatSpec {
|
format: FormatSpec {
|
||||||
fill: Some('*'),
|
fill: Some('*'),
|
||||||
align: AlignLeft,
|
align: AlignLeft,
|
||||||
|
@ -160,6 +184,7 @@ fn format_counts() {
|
||||||
"{:10x}",
|
"{:10x}",
|
||||||
&[NextArgument(Argument {
|
&[NextArgument(Argument {
|
||||||
position: ArgumentImplicitlyIs(0),
|
position: ArgumentImplicitlyIs(0),
|
||||||
|
position_span: InnerSpan { start: 2, end: 2 },
|
||||||
format: FormatSpec {
|
format: FormatSpec {
|
||||||
fill: None,
|
fill: None,
|
||||||
align: AlignUnknown,
|
align: AlignUnknown,
|
||||||
|
@ -177,6 +202,7 @@ fn format_counts() {
|
||||||
"{:10$.10x}",
|
"{:10$.10x}",
|
||||||
&[NextArgument(Argument {
|
&[NextArgument(Argument {
|
||||||
position: ArgumentImplicitlyIs(0),
|
position: ArgumentImplicitlyIs(0),
|
||||||
|
position_span: InnerSpan { start: 2, end: 2 },
|
||||||
format: FormatSpec {
|
format: FormatSpec {
|
||||||
fill: None,
|
fill: None,
|
||||||
align: AlignUnknown,
|
align: AlignUnknown,
|
||||||
|
@ -193,7 +219,8 @@ fn format_counts() {
|
||||||
same(
|
same(
|
||||||
"{1:0$.10x}",
|
"{1:0$.10x}",
|
||||||
&[NextArgument(Argument {
|
&[NextArgument(Argument {
|
||||||
position: ArgumentIs(1, Some(InnerSpan { start: 2, end: 3 })),
|
position: ArgumentIs(1),
|
||||||
|
position_span: InnerSpan { start: 2, end: 3 },
|
||||||
format: FormatSpec {
|
format: FormatSpec {
|
||||||
fill: None,
|
fill: None,
|
||||||
align: AlignUnknown,
|
align: AlignUnknown,
|
||||||
|
@ -211,6 +238,7 @@ fn format_counts() {
|
||||||
"{:.*x}",
|
"{:.*x}",
|
||||||
&[NextArgument(Argument {
|
&[NextArgument(Argument {
|
||||||
position: ArgumentImplicitlyIs(1),
|
position: ArgumentImplicitlyIs(1),
|
||||||
|
position_span: InnerSpan { start: 2, end: 2 },
|
||||||
format: FormatSpec {
|
format: FormatSpec {
|
||||||
fill: None,
|
fill: None,
|
||||||
align: AlignUnknown,
|
align: AlignUnknown,
|
||||||
|
@ -228,6 +256,7 @@ fn format_counts() {
|
||||||
"{:.10$x}",
|
"{:.10$x}",
|
||||||
&[NextArgument(Argument {
|
&[NextArgument(Argument {
|
||||||
position: ArgumentImplicitlyIs(0),
|
position: ArgumentImplicitlyIs(0),
|
||||||
|
position_span: InnerSpan { start: 2, end: 2 },
|
||||||
format: FormatSpec {
|
format: FormatSpec {
|
||||||
fill: None,
|
fill: None,
|
||||||
align: AlignUnknown,
|
align: AlignUnknown,
|
||||||
|
@ -245,6 +274,7 @@ fn format_counts() {
|
||||||
"{:a$.b$?}",
|
"{:a$.b$?}",
|
||||||
&[NextArgument(Argument {
|
&[NextArgument(Argument {
|
||||||
position: ArgumentImplicitlyIs(0),
|
position: ArgumentImplicitlyIs(0),
|
||||||
|
position_span: InnerSpan { start: 2, end: 2 },
|
||||||
format: FormatSpec {
|
format: FormatSpec {
|
||||||
fill: None,
|
fill: None,
|
||||||
align: AlignUnknown,
|
align: AlignUnknown,
|
||||||
|
@ -265,6 +295,7 @@ fn format_flags() {
|
||||||
"{:-}",
|
"{:-}",
|
||||||
&[NextArgument(Argument {
|
&[NextArgument(Argument {
|
||||||
position: ArgumentImplicitlyIs(0),
|
position: ArgumentImplicitlyIs(0),
|
||||||
|
position_span: InnerSpan { start: 2, end: 2 },
|
||||||
format: FormatSpec {
|
format: FormatSpec {
|
||||||
fill: None,
|
fill: None,
|
||||||
align: AlignUnknown,
|
align: AlignUnknown,
|
||||||
|
@ -282,6 +313,7 @@ fn format_flags() {
|
||||||
"{:+#}",
|
"{:+#}",
|
||||||
&[NextArgument(Argument {
|
&[NextArgument(Argument {
|
||||||
position: ArgumentImplicitlyIs(0),
|
position: ArgumentImplicitlyIs(0),
|
||||||
|
position_span: InnerSpan { start: 2, end: 2 },
|
||||||
format: FormatSpec {
|
format: FormatSpec {
|
||||||
fill: None,
|
fill: None,
|
||||||
align: AlignUnknown,
|
align: AlignUnknown,
|
||||||
|
@ -303,7 +335,8 @@ fn format_mixture() {
|
||||||
&[
|
&[
|
||||||
String("abcd "),
|
String("abcd "),
|
||||||
NextArgument(Argument {
|
NextArgument(Argument {
|
||||||
position: ArgumentIs(3, Some(InnerSpan { start: 7, end: 8 })),
|
position: ArgumentIs(3),
|
||||||
|
position_span: InnerSpan { start: 7, end: 8 },
|
||||||
format: FormatSpec {
|
format: FormatSpec {
|
||||||
fill: None,
|
fill: None,
|
||||||
align: AlignUnknown,
|
align: AlignUnknown,
|
||||||
|
@ -320,3 +353,22 @@ fn format_mixture() {
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
#[test]
|
||||||
|
fn format_whitespace() {
|
||||||
|
same(
|
||||||
|
"{ }",
|
||||||
|
&[NextArgument(Argument {
|
||||||
|
position: ArgumentImplicitlyIs(0),
|
||||||
|
position_span: InnerSpan { start: 2, end: 3 },
|
||||||
|
format: fmtdflt(),
|
||||||
|
})],
|
||||||
|
);
|
||||||
|
same(
|
||||||
|
"{ }",
|
||||||
|
&[NextArgument(Argument {
|
||||||
|
position: ArgumentImplicitlyIs(0),
|
||||||
|
position_span: InnerSpan { start: 2, end: 4 },
|
||||||
|
format: fmtdflt(),
|
||||||
|
})],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
|
@ -300,7 +300,7 @@ impl<'tcx> OnUnimplementedFormatString {
|
||||||
match token {
|
match token {
|
||||||
Piece::String(_) => (), // Normal string, no need to check it
|
Piece::String(_) => (), // Normal string, no need to check it
|
||||||
Piece::NextArgument(a) => match a.position {
|
Piece::NextArgument(a) => match a.position {
|
||||||
Position::ArgumentNamed(s, _) => {
|
Position::ArgumentNamed(s) => {
|
||||||
match Symbol::intern(s) {
|
match Symbol::intern(s) {
|
||||||
// `{Self}` is allowed
|
// `{Self}` is allowed
|
||||||
kw::SelfUpper => (),
|
kw::SelfUpper => (),
|
||||||
|
@ -386,7 +386,7 @@ impl<'tcx> OnUnimplementedFormatString {
|
||||||
.map(|p| match p {
|
.map(|p| match p {
|
||||||
Piece::String(s) => s,
|
Piece::String(s) => s,
|
||||||
Piece::NextArgument(a) => match a.position {
|
Piece::NextArgument(a) => match a.position {
|
||||||
Position::ArgumentNamed(s, _) => {
|
Position::ArgumentNamed(s) => {
|
||||||
let s = Symbol::intern(s);
|
let s = Symbol::intern(s);
|
||||||
match generic_map.get(&s) {
|
match generic_map.get(&s) {
|
||||||
Some(val) => val,
|
Some(val) => val,
|
||||||
|
|
|
@ -120,7 +120,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
|
||||||
kind: Box::new(ImplItem(Box::new(Impl {
|
kind: Box::new(ImplItem(Box::new(Impl {
|
||||||
unsafety: hir::Unsafety::Normal,
|
unsafety: hir::Unsafety::Normal,
|
||||||
generics: new_generics,
|
generics: new_generics,
|
||||||
trait_: Some(trait_ref.clean(self.cx)),
|
trait_: Some(clean_trait_ref_with_bindings(self.cx, trait_ref, &[])),
|
||||||
for_: clean_middle_ty(ty, self.cx, None),
|
for_: clean_middle_ty(ty, self.cx, None),
|
||||||
items: Vec::new(),
|
items: Vec::new(),
|
||||||
polarity,
|
polarity,
|
||||||
|
|
|
@ -115,7 +115,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
|
||||||
),
|
),
|
||||||
// FIXME(eddyb) compute both `trait_` and `for_` from
|
// FIXME(eddyb) compute both `trait_` and `for_` from
|
||||||
// the post-inference `trait_ref`, as it's more accurate.
|
// the post-inference `trait_ref`, as it's more accurate.
|
||||||
trait_: Some(trait_ref.0.clean(cx)),
|
trait_: Some(clean_trait_ref_with_bindings(cx, trait_ref.0, &[])),
|
||||||
for_: clean_middle_ty(ty.0, cx, None),
|
for_: clean_middle_ty(ty.0, cx, None),
|
||||||
items: cx.tcx
|
items: cx.tcx
|
||||||
.associated_items(impl_def_id)
|
.associated_items(impl_def_id)
|
||||||
|
|
|
@ -16,9 +16,9 @@ use rustc_span::hygiene::MacroKind;
|
||||||
use rustc_span::symbol::{kw, sym, Symbol};
|
use rustc_span::symbol::{kw, sym, Symbol};
|
||||||
|
|
||||||
use crate::clean::{
|
use crate::clean::{
|
||||||
self, clean_fn_decl_from_did_and_sig, clean_middle_field, clean_middle_ty, clean_ty,
|
self, clean_fn_decl_from_did_and_sig, clean_middle_field, clean_middle_ty,
|
||||||
clean_ty_generics, clean_variant_def, clean_visibility, utils, Attributes, AttributesExt,
|
clean_trait_ref_with_bindings, clean_ty, clean_ty_generics, clean_variant_def,
|
||||||
Clean, ImplKind, ItemId, Type, Visibility,
|
clean_visibility, utils, Attributes, AttributesExt, Clean, ImplKind, ItemId, Type, Visibility,
|
||||||
};
|
};
|
||||||
use crate::core::DocContext;
|
use crate::core::DocContext;
|
||||||
use crate::formats::item_type::ItemType;
|
use crate::formats::item_type::ItemType;
|
||||||
|
@ -304,14 +304,14 @@ fn merge_attrs(
|
||||||
both.extend_from_slice(old_attrs);
|
both.extend_from_slice(old_attrs);
|
||||||
(
|
(
|
||||||
if let Some(new_id) = parent_module {
|
if let Some(new_id) = parent_module {
|
||||||
Attributes::from_ast(old_attrs, Some((inner, new_id)))
|
Attributes::from_ast_with_additional(old_attrs, (inner, new_id))
|
||||||
} else {
|
} else {
|
||||||
Attributes::from_ast(&both, None)
|
Attributes::from_ast(&both)
|
||||||
},
|
},
|
||||||
both.cfg(cx.tcx, &cx.cache.hidden_cfg),
|
both.cfg(cx.tcx, &cx.cache.hidden_cfg),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
(old_attrs.clean(cx), old_attrs.cfg(cx.tcx, &cx.cache.hidden_cfg))
|
(Attributes::from_ast(&old_attrs), old_attrs.cfg(cx.tcx, &cx.cache.hidden_cfg))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -450,7 +450,7 @@ pub(crate) fn build_impl(
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
let polarity = tcx.impl_polarity(did);
|
let polarity = tcx.impl_polarity(did);
|
||||||
let trait_ = associated_trait.map(|t| t.clean(cx));
|
let trait_ = associated_trait.map(|t| clean_trait_ref_with_bindings(cx, t, &[]));
|
||||||
if trait_.as_ref().map(|t| t.def_id()) == tcx.lang_items().deref_trait() {
|
if trait_.as_ref().map(|t| t.def_id()) == tcx.lang_items().deref_trait() {
|
||||||
super::build_deref_target_impls(cx, &trait_items, ret);
|
super::build_deref_target_impls(cx, &trait_items, ret);
|
||||||
}
|
}
|
||||||
|
|
|
@ -121,16 +121,10 @@ impl<'tcx> Clean<'tcx, Item> for DocModule<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> Clean<'tcx, Attributes> for [ast::Attribute] {
|
|
||||||
fn clean(&self, _cx: &mut DocContext<'_>) -> Attributes {
|
|
||||||
Attributes::from_ast(self, None)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tcx> Clean<'tcx, Option<GenericBound>> for hir::GenericBound<'tcx> {
|
impl<'tcx> Clean<'tcx, Option<GenericBound>> for hir::GenericBound<'tcx> {
|
||||||
fn clean(&self, cx: &mut DocContext<'tcx>) -> Option<GenericBound> {
|
fn clean(&self, cx: &mut DocContext<'tcx>) -> Option<GenericBound> {
|
||||||
Some(match *self {
|
Some(match *self {
|
||||||
hir::GenericBound::Outlives(lt) => GenericBound::Outlives(lt.clean(cx)),
|
hir::GenericBound::Outlives(lt) => GenericBound::Outlives(clean_lifetime(lt, cx)),
|
||||||
hir::GenericBound::LangItemTrait(lang_item, span, _, generic_args) => {
|
hir::GenericBound::LangItemTrait(lang_item, span, _, generic_args) => {
|
||||||
let def_id = cx.tcx.require_lang_item(lang_item, Some(span));
|
let def_id = cx.tcx.require_lang_item(lang_item, Some(span));
|
||||||
|
|
||||||
|
@ -163,7 +157,7 @@ impl<'tcx> Clean<'tcx, Option<GenericBound>> for hir::GenericBound<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clean_trait_ref_with_bindings<'tcx>(
|
pub(crate) fn clean_trait_ref_with_bindings<'tcx>(
|
||||||
cx: &mut DocContext<'tcx>,
|
cx: &mut DocContext<'tcx>,
|
||||||
trait_ref: ty::TraitRef<'tcx>,
|
trait_ref: ty::TraitRef<'tcx>,
|
||||||
bindings: &[TypeBinding],
|
bindings: &[TypeBinding],
|
||||||
|
@ -180,12 +174,6 @@ fn clean_trait_ref_with_bindings<'tcx>(
|
||||||
path
|
path
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> Clean<'tcx, Path> for ty::TraitRef<'tcx> {
|
|
||||||
fn clean(&self, cx: &mut DocContext<'tcx>) -> Path {
|
|
||||||
clean_trait_ref_with_bindings(cx, *self, &[])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn clean_poly_trait_ref_with_bindings<'tcx>(
|
fn clean_poly_trait_ref_with_bindings<'tcx>(
|
||||||
cx: &mut DocContext<'tcx>,
|
cx: &mut DocContext<'tcx>,
|
||||||
poly_trait_ref: ty::PolyTraitRef<'tcx>,
|
poly_trait_ref: ty::PolyTraitRef<'tcx>,
|
||||||
|
@ -220,21 +208,19 @@ impl<'tcx> Clean<'tcx, GenericBound> for ty::PolyTraitRef<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> Clean<'tcx, Lifetime> for hir::Lifetime {
|
fn clean_lifetime<'tcx>(lifetime: hir::Lifetime, cx: &mut DocContext<'tcx>) -> Lifetime {
|
||||||
fn clean(&self, cx: &mut DocContext<'tcx>) -> Lifetime {
|
let def = cx.tcx.named_region(lifetime.hir_id);
|
||||||
let def = cx.tcx.named_region(self.hir_id);
|
if let Some(
|
||||||
if let Some(
|
rl::Region::EarlyBound(_, node_id)
|
||||||
rl::Region::EarlyBound(_, node_id)
|
| rl::Region::LateBound(_, _, node_id)
|
||||||
| rl::Region::LateBound(_, _, node_id)
|
| rl::Region::Free(_, node_id),
|
||||||
| rl::Region::Free(_, node_id),
|
) = def
|
||||||
) = def
|
{
|
||||||
{
|
if let Some(lt) = cx.substs.get(&node_id).and_then(|p| p.as_lt()).cloned() {
|
||||||
if let Some(lt) = cx.substs.get(&node_id).and_then(|p| p.as_lt()).cloned() {
|
return lt;
|
||||||
return lt;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Lifetime(self.name.ident().name)
|
|
||||||
}
|
}
|
||||||
|
Lifetime(lifetime.name.ident().name)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn clean_const<'tcx>(constant: &hir::ConstArg, cx: &mut DocContext<'tcx>) -> Constant {
|
pub(crate) fn clean_const<'tcx>(constant: &hir::ConstArg, cx: &mut DocContext<'tcx>) -> Constant {
|
||||||
|
@ -311,7 +297,7 @@ impl<'tcx> Clean<'tcx, Option<WherePredicate>> for hir::WherePredicate<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
hir::WherePredicate::RegionPredicate(ref wrp) => WherePredicate::RegionPredicate {
|
hir::WherePredicate::RegionPredicate(ref wrp) => WherePredicate::RegionPredicate {
|
||||||
lifetime: wrp.lifetime.clean(cx),
|
lifetime: clean_lifetime(wrp.lifetime, cx),
|
||||||
bounds: wrp.bounds.iter().filter_map(|x| x.clean(cx)).collect(),
|
bounds: wrp.bounds.iter().filter_map(|x| x.clean(cx)).collect(),
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -432,7 +418,7 @@ fn clean_projection<'tcx>(
|
||||||
def_id: Option<DefId>,
|
def_id: Option<DefId>,
|
||||||
) -> Type {
|
) -> Type {
|
||||||
let lifted = ty.lift_to_tcx(cx.tcx).unwrap();
|
let lifted = ty.lift_to_tcx(cx.tcx).unwrap();
|
||||||
let trait_ = lifted.trait_ref(cx.tcx).clean(cx);
|
let trait_ = clean_trait_ref_with_bindings(cx, lifted.trait_ref(cx.tcx), &[]);
|
||||||
let self_type = clean_middle_ty(ty.self_ty(), cx, None);
|
let self_type = clean_middle_ty(ty.self_ty(), cx, None);
|
||||||
let self_def_id = if let Some(def_id) = def_id {
|
let self_def_id = if let Some(def_id) = def_id {
|
||||||
cx.tcx.opt_parent(def_id).or(Some(def_id))
|
cx.tcx.opt_parent(def_id).or(Some(def_id))
|
||||||
|
@ -524,7 +510,7 @@ fn clean_generic_param<'tcx>(
|
||||||
.filter(|bp| !bp.in_where_clause)
|
.filter(|bp| !bp.in_where_clause)
|
||||||
.flat_map(|bp| bp.bounds)
|
.flat_map(|bp| bp.bounds)
|
||||||
.map(|bound| match bound {
|
.map(|bound| match bound {
|
||||||
hir::GenericBound::Outlives(lt) => lt.clean(cx),
|
hir::GenericBound::Outlives(lt) => clean_lifetime(*lt, cx),
|
||||||
_ => panic!(),
|
_ => panic!(),
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
|
@ -1431,7 +1417,8 @@ fn maybe_expand_private_type_alias<'tcx>(
|
||||||
});
|
});
|
||||||
if let Some(lt) = lifetime.cloned() {
|
if let Some(lt) = lifetime.cloned() {
|
||||||
let lt_def_id = cx.tcx.hir().local_def_id(param.hir_id);
|
let lt_def_id = cx.tcx.hir().local_def_id(param.hir_id);
|
||||||
let cleaned = if !lt.is_elided() { lt.clean(cx) } else { Lifetime::elided() };
|
let cleaned =
|
||||||
|
if !lt.is_elided() { clean_lifetime(lt, cx) } else { Lifetime::elided() };
|
||||||
substs.insert(lt_def_id.to_def_id(), SubstParam::Lifetime(cleaned));
|
substs.insert(lt_def_id.to_def_id(), SubstParam::Lifetime(cleaned));
|
||||||
}
|
}
|
||||||
indices.lifetimes += 1;
|
indices.lifetimes += 1;
|
||||||
|
@ -1503,7 +1490,7 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T
|
||||||
// there's no case where it could cause the function to fail to compile.
|
// there's no case where it could cause the function to fail to compile.
|
||||||
let elided =
|
let elided =
|
||||||
l.is_elided() || matches!(l.name, LifetimeName::Param(_, ParamName::Fresh));
|
l.is_elided() || matches!(l.name, LifetimeName::Param(_, ParamName::Fresh));
|
||||||
let lifetime = if elided { None } else { Some(l.clean(cx)) };
|
let lifetime = if elided { None } else { Some(clean_lifetime(*l, cx)) };
|
||||||
BorrowedRef { lifetime, mutability: m.mutbl, type_: Box::new(clean_ty(m.ty, cx)) }
|
BorrowedRef { lifetime, mutability: m.mutbl, type_: Box::new(clean_ty(m.ty, cx)) }
|
||||||
}
|
}
|
||||||
TyKind::Slice(ty) => Slice(Box::new(clean_ty(ty, cx))),
|
TyKind::Slice(ty) => Slice(Box::new(clean_ty(ty, cx))),
|
||||||
|
@ -1539,7 +1526,8 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T
|
||||||
TyKind::Path(_) => clean_qpath(ty, cx),
|
TyKind::Path(_) => clean_qpath(ty, cx),
|
||||||
TyKind::TraitObject(bounds, ref lifetime, _) => {
|
TyKind::TraitObject(bounds, ref lifetime, _) => {
|
||||||
let bounds = bounds.iter().map(|bound| bound.clean(cx)).collect();
|
let bounds = bounds.iter().map(|bound| bound.clean(cx)).collect();
|
||||||
let lifetime = if !lifetime.is_elided() { Some(lifetime.clean(cx)) } else { None };
|
let lifetime =
|
||||||
|
if !lifetime.is_elided() { Some(clean_lifetime(*lifetime, cx)) } else { None };
|
||||||
DynTrait(bounds, lifetime)
|
DynTrait(bounds, lifetime)
|
||||||
}
|
}
|
||||||
TyKind::BareFn(barefn) => BareFunction(Box::new(barefn.clean(cx))),
|
TyKind::BareFn(barefn) => BareFunction(Box::new(barefn.clean(cx))),
|
||||||
|
@ -1875,7 +1863,7 @@ impl<'tcx> Clean<'tcx, GenericArgs> for hir::GenericArgs<'tcx> {
|
||||||
.iter()
|
.iter()
|
||||||
.map(|arg| match arg {
|
.map(|arg| match arg {
|
||||||
hir::GenericArg::Lifetime(lt) if !lt.is_elided() => {
|
hir::GenericArg::Lifetime(lt) if !lt.is_elided() => {
|
||||||
GenericArg::Lifetime(lt.clean(cx))
|
GenericArg::Lifetime(clean_lifetime(*lt, cx))
|
||||||
}
|
}
|
||||||
hir::GenericArg::Lifetime(_) => GenericArg::Lifetime(Lifetime::elided()),
|
hir::GenericArg::Lifetime(_) => GenericArg::Lifetime(Lifetime::elided()),
|
||||||
hir::GenericArg::Type(ty) => GenericArg::Type(clean_ty(ty, cx)),
|
hir::GenericArg::Type(ty) => GenericArg::Type(clean_ty(ty, cx)),
|
||||||
|
@ -2096,7 +2084,7 @@ fn clean_extern_crate<'tcx>(
|
||||||
// FIXME: using `from_def_id_and_kind` breaks `rustdoc/masked` for some reason
|
// FIXME: using `from_def_id_and_kind` breaks `rustdoc/masked` for some reason
|
||||||
vec![Item {
|
vec![Item {
|
||||||
name: Some(name),
|
name: Some(name),
|
||||||
attrs: Box::new(attrs.clean(cx)),
|
attrs: Box::new(Attributes::from_ast(attrs)),
|
||||||
item_id: crate_def_id.into(),
|
item_id: crate_def_id.into(),
|
||||||
visibility: clean_visibility(ty_vis),
|
visibility: clean_visibility(ty_vis),
|
||||||
kind: Box::new(ExternCrateItem { src: orig_name }),
|
kind: Box::new(ExternCrateItem { src: orig_name }),
|
||||||
|
|
|
@ -34,10 +34,10 @@ use rustc_target::spec::abi::Abi;
|
||||||
use rustc_typeck::check::intrinsic::intrinsic_operation_unsafety;
|
use rustc_typeck::check::intrinsic::intrinsic_operation_unsafety;
|
||||||
|
|
||||||
use crate::clean::cfg::Cfg;
|
use crate::clean::cfg::Cfg;
|
||||||
|
use crate::clean::clean_visibility;
|
||||||
use crate::clean::external_path;
|
use crate::clean::external_path;
|
||||||
use crate::clean::inline::{self, print_inlined_const};
|
use crate::clean::inline::{self, print_inlined_const};
|
||||||
use crate::clean::utils::{is_literal_expr, print_const_expr, print_evaluated_const};
|
use crate::clean::utils::{is_literal_expr, print_const_expr, print_evaluated_const};
|
||||||
use crate::clean::{clean_visibility, Clean};
|
|
||||||
use crate::core::DocContext;
|
use crate::core::DocContext;
|
||||||
use crate::formats::cache::Cache;
|
use crate::formats::cache::Cache;
|
||||||
use crate::formats::item_type::ItemType;
|
use crate::formats::item_type::ItemType;
|
||||||
|
@ -469,7 +469,7 @@ impl Item {
|
||||||
def_id,
|
def_id,
|
||||||
name,
|
name,
|
||||||
kind,
|
kind,
|
||||||
Box::new(ast_attrs.clean(cx)),
|
Box::new(Attributes::from_ast(ast_attrs)),
|
||||||
cx,
|
cx,
|
||||||
ast_attrs.cfg(cx.tcx, &cx.cache.hidden_cfg),
|
ast_attrs.cfg(cx.tcx, &cx.cache.hidden_cfg),
|
||||||
)
|
)
|
||||||
|
@ -1161,14 +1161,16 @@ impl Attributes {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn from_ast(
|
pub(crate) fn from_ast(attrs: &[ast::Attribute]) -> Attributes {
|
||||||
|
Attributes::from_ast_iter(attrs.iter().map(|attr| (attr, None)), false)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn from_ast_with_additional(
|
||||||
attrs: &[ast::Attribute],
|
attrs: &[ast::Attribute],
|
||||||
additional_attrs: Option<(&[ast::Attribute], DefId)>,
|
(additional_attrs, def_id): (&[ast::Attribute], DefId),
|
||||||
) -> Attributes {
|
) -> Attributes {
|
||||||
// Additional documentation should be shown before the original documentation.
|
// Additional documentation should be shown before the original documentation.
|
||||||
let attrs1 = additional_attrs
|
let attrs1 = additional_attrs.iter().map(|attr| (attr, Some(def_id)));
|
||||||
.into_iter()
|
|
||||||
.flat_map(|(attrs, def_id)| attrs.iter().map(move |attr| (attr, Some(def_id))));
|
|
||||||
let attrs2 = attrs.iter().map(|attr| (attr, None));
|
let attrs2 = attrs.iter().map(|attr| (attr, None));
|
||||||
Attributes::from_ast_iter(attrs1.chain(attrs2), false)
|
Attributes::from_ast_iter(attrs1.chain(attrs2), false)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1222,7 +1222,7 @@ impl<'a, 'hir, 'tcx> HirCollector<'a, 'hir, 'tcx> {
|
||||||
|
|
||||||
// The collapse-docs pass won't combine sugared/raw doc attributes, or included files with
|
// The collapse-docs pass won't combine sugared/raw doc attributes, or included files with
|
||||||
// anything else, this will combine them for us.
|
// anything else, this will combine them for us.
|
||||||
let attrs = Attributes::from_ast(ast_attrs, None);
|
let attrs = Attributes::from_ast(ast_attrs);
|
||||||
if let Some(doc) = attrs.collapsed_doc_value() {
|
if let Some(doc) = attrs.collapsed_doc_value() {
|
||||||
// Use the outermost invocation, so that doctest names come from where the docs were written.
|
// Use the outermost invocation, so that doctest names come from where the docs were written.
|
||||||
let span = ast_attrs
|
let span = ast_attrs
|
||||||
|
|
|
@ -345,7 +345,7 @@ fn item_module(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Item, items:
|
||||||
clean::ImportItem(ref import) => {
|
clean::ImportItem(ref import) => {
|
||||||
let (stab, stab_tags) = if let Some(import_def_id) = import.source.did {
|
let (stab, stab_tags) = if let Some(import_def_id) = import.source.did {
|
||||||
let ast_attrs = cx.tcx().get_attrs_unchecked(import_def_id);
|
let ast_attrs = cx.tcx().get_attrs_unchecked(import_def_id);
|
||||||
let import_attrs = Box::new(clean::Attributes::from_ast(ast_attrs, None));
|
let import_attrs = Box::new(clean::Attributes::from_ast(ast_attrs));
|
||||||
|
|
||||||
// Just need an item with the correct def_id and attrs
|
// Just need an item with the correct def_id and attrs
|
||||||
let import_item = clean::Item {
|
let import_item = clean::Item {
|
||||||
|
|
|
@ -56,7 +56,7 @@ pub unsafe fn sym_fn() {
|
||||||
// CHECK-LABEL: sym_static:
|
// CHECK-LABEL: sym_static:
|
||||||
// CHECK: #APP
|
// CHECK: #APP
|
||||||
// CHECK: auipc t0, %pcrel_hi(extern_static)
|
// CHECK: auipc t0, %pcrel_hi(extern_static)
|
||||||
// CHECK: lb t0, %pcrel_lo(.Lpcrel_hi0)(t0)
|
// CHECK: lb t0, %pcrel_lo(.Lpcrel_hi{{[0-9]+}})(t0)
|
||||||
// CHECK: #NO_APP
|
// CHECK: #NO_APP
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe fn sym_static() {
|
pub unsafe fn sym_static() {
|
||||||
|
|
|
@ -36,41 +36,41 @@ LL | asm!("{}", out(reg) foo, clobber_abi("C"));
|
||||||
| |
|
| |
|
||||||
| generic outputs
|
| generic outputs
|
||||||
|
|
||||||
error: expected one of `)`, `att_syntax`, `may_unwind`, or `raw`, found `nomem`
|
error: expected one of `)`, `att_syntax`, or `raw`, found `nomem`
|
||||||
--> $DIR/bad-options.rs:28:25
|
--> $DIR/bad-options.rs:28:25
|
||||||
|
|
|
|
||||||
LL | global_asm!("", options(nomem));
|
LL | global_asm!("", options(nomem));
|
||||||
| ^^^^^ expected one of `)`, `att_syntax`, `may_unwind`, or `raw`
|
| ^^^^^ expected one of `)`, `att_syntax`, or `raw`
|
||||||
|
|
||||||
error: expected one of `)`, `att_syntax`, `may_unwind`, or `raw`, found `readonly`
|
error: expected one of `)`, `att_syntax`, or `raw`, found `readonly`
|
||||||
--> $DIR/bad-options.rs:30:25
|
--> $DIR/bad-options.rs:30:25
|
||||||
|
|
|
|
||||||
LL | global_asm!("", options(readonly));
|
LL | global_asm!("", options(readonly));
|
||||||
| ^^^^^^^^ expected one of `)`, `att_syntax`, `may_unwind`, or `raw`
|
| ^^^^^^^^ expected one of `)`, `att_syntax`, or `raw`
|
||||||
|
|
||||||
error: expected one of `)`, `att_syntax`, `may_unwind`, or `raw`, found `noreturn`
|
error: expected one of `)`, `att_syntax`, or `raw`, found `noreturn`
|
||||||
--> $DIR/bad-options.rs:32:25
|
--> $DIR/bad-options.rs:32:25
|
||||||
|
|
|
|
||||||
LL | global_asm!("", options(noreturn));
|
LL | global_asm!("", options(noreturn));
|
||||||
| ^^^^^^^^ expected one of `)`, `att_syntax`, `may_unwind`, or `raw`
|
| ^^^^^^^^ expected one of `)`, `att_syntax`, or `raw`
|
||||||
|
|
||||||
error: expected one of `)`, `att_syntax`, `may_unwind`, or `raw`, found `pure`
|
error: expected one of `)`, `att_syntax`, or `raw`, found `pure`
|
||||||
--> $DIR/bad-options.rs:34:25
|
--> $DIR/bad-options.rs:34:25
|
||||||
|
|
|
|
||||||
LL | global_asm!("", options(pure));
|
LL | global_asm!("", options(pure));
|
||||||
| ^^^^ expected one of `)`, `att_syntax`, `may_unwind`, or `raw`
|
| ^^^^ expected one of `)`, `att_syntax`, or `raw`
|
||||||
|
|
||||||
error: expected one of `)`, `att_syntax`, `may_unwind`, or `raw`, found `nostack`
|
error: expected one of `)`, `att_syntax`, or `raw`, found `nostack`
|
||||||
--> $DIR/bad-options.rs:36:25
|
--> $DIR/bad-options.rs:36:25
|
||||||
|
|
|
|
||||||
LL | global_asm!("", options(nostack));
|
LL | global_asm!("", options(nostack));
|
||||||
| ^^^^^^^ expected one of `)`, `att_syntax`, `may_unwind`, or `raw`
|
| ^^^^^^^ expected one of `)`, `att_syntax`, or `raw`
|
||||||
|
|
||||||
error: expected one of `)`, `att_syntax`, `may_unwind`, or `raw`, found `preserves_flags`
|
error: expected one of `)`, `att_syntax`, or `raw`, found `preserves_flags`
|
||||||
--> $DIR/bad-options.rs:38:25
|
--> $DIR/bad-options.rs:38:25
|
||||||
|
|
|
|
||||||
LL | global_asm!("", options(preserves_flags));
|
LL | global_asm!("", options(preserves_flags));
|
||||||
| ^^^^^^^^^^^^^^^ expected one of `)`, `att_syntax`, `may_unwind`, or `raw`
|
| ^^^^^^^^^^^^^^^ expected one of `)`, `att_syntax`, or `raw`
|
||||||
|
|
||||||
error: invalid ABI for `clobber_abi`
|
error: invalid ABI for `clobber_abi`
|
||||||
--> $DIR/bad-options.rs:20:18
|
--> $DIR/bad-options.rs:20:18
|
||||||
|
|
|
@ -260,23 +260,23 @@ error: expected one of `,`, `.`, `?`, or an operator, found `FOO`
|
||||||
LL | global_asm!("{}", const(reg) FOO);
|
LL | global_asm!("{}", const(reg) FOO);
|
||||||
| ^^^ expected one of `,`, `.`, `?`, or an operator
|
| ^^^ expected one of `,`, `.`, `?`, or an operator
|
||||||
|
|
||||||
error: expected one of `)`, `att_syntax`, `may_unwind`, or `raw`, found `FOO`
|
error: expected one of `)`, `att_syntax`, or `raw`, found `FOO`
|
||||||
--> $DIR/parse-error.rs:102:25
|
--> $DIR/parse-error.rs:102:25
|
||||||
|
|
|
|
||||||
LL | global_asm!("", options(FOO));
|
LL | global_asm!("", options(FOO));
|
||||||
| ^^^ expected one of `)`, `att_syntax`, `may_unwind`, or `raw`
|
| ^^^ expected one of `)`, `att_syntax`, or `raw`
|
||||||
|
|
||||||
error: expected one of `)`, `att_syntax`, `may_unwind`, or `raw`, found `nomem`
|
error: expected one of `)`, `att_syntax`, or `raw`, found `nomem`
|
||||||
--> $DIR/parse-error.rs:104:25
|
--> $DIR/parse-error.rs:104:25
|
||||||
|
|
|
|
||||||
LL | global_asm!("", options(nomem FOO));
|
LL | global_asm!("", options(nomem FOO));
|
||||||
| ^^^^^ expected one of `)`, `att_syntax`, `may_unwind`, or `raw`
|
| ^^^^^ expected one of `)`, `att_syntax`, or `raw`
|
||||||
|
|
||||||
error: expected one of `)`, `att_syntax`, `may_unwind`, or `raw`, found `nomem`
|
error: expected one of `)`, `att_syntax`, or `raw`, found `nomem`
|
||||||
--> $DIR/parse-error.rs:106:25
|
--> $DIR/parse-error.rs:106:25
|
||||||
|
|
|
|
||||||
LL | global_asm!("", options(nomem, FOO));
|
LL | global_asm!("", options(nomem, FOO));
|
||||||
| ^^^^^ expected one of `)`, `att_syntax`, `may_unwind`, or `raw`
|
| ^^^^^ expected one of `)`, `att_syntax`, or `raw`
|
||||||
|
|
||||||
error: arguments are not allowed after options
|
error: arguments are not allowed after options
|
||||||
--> $DIR/parse-error.rs:108:30
|
--> $DIR/parse-error.rs:108:30
|
||||||
|
|
|
@ -45,41 +45,41 @@ LL | asm!("{}", out(reg) foo, clobber_abi("C"), clobber_abi("C"));
|
||||||
| | clobber_abi
|
| | clobber_abi
|
||||||
| generic outputs
|
| generic outputs
|
||||||
|
|
||||||
error: expected one of `)`, `att_syntax`, `may_unwind`, or `raw`, found `nomem`
|
error: expected one of `)`, `att_syntax`, or `raw`, found `nomem`
|
||||||
--> $DIR/bad-options.rs:31:25
|
--> $DIR/bad-options.rs:31:25
|
||||||
|
|
|
|
||||||
LL | global_asm!("", options(nomem));
|
LL | global_asm!("", options(nomem));
|
||||||
| ^^^^^ expected one of `)`, `att_syntax`, `may_unwind`, or `raw`
|
| ^^^^^ expected one of `)`, `att_syntax`, or `raw`
|
||||||
|
|
||||||
error: expected one of `)`, `att_syntax`, `may_unwind`, or `raw`, found `readonly`
|
error: expected one of `)`, `att_syntax`, or `raw`, found `readonly`
|
||||||
--> $DIR/bad-options.rs:33:25
|
--> $DIR/bad-options.rs:33:25
|
||||||
|
|
|
|
||||||
LL | global_asm!("", options(readonly));
|
LL | global_asm!("", options(readonly));
|
||||||
| ^^^^^^^^ expected one of `)`, `att_syntax`, `may_unwind`, or `raw`
|
| ^^^^^^^^ expected one of `)`, `att_syntax`, or `raw`
|
||||||
|
|
||||||
error: expected one of `)`, `att_syntax`, `may_unwind`, or `raw`, found `noreturn`
|
error: expected one of `)`, `att_syntax`, or `raw`, found `noreturn`
|
||||||
--> $DIR/bad-options.rs:35:25
|
--> $DIR/bad-options.rs:35:25
|
||||||
|
|
|
|
||||||
LL | global_asm!("", options(noreturn));
|
LL | global_asm!("", options(noreturn));
|
||||||
| ^^^^^^^^ expected one of `)`, `att_syntax`, `may_unwind`, or `raw`
|
| ^^^^^^^^ expected one of `)`, `att_syntax`, or `raw`
|
||||||
|
|
||||||
error: expected one of `)`, `att_syntax`, `may_unwind`, or `raw`, found `pure`
|
error: expected one of `)`, `att_syntax`, or `raw`, found `pure`
|
||||||
--> $DIR/bad-options.rs:37:25
|
--> $DIR/bad-options.rs:37:25
|
||||||
|
|
|
|
||||||
LL | global_asm!("", options(pure));
|
LL | global_asm!("", options(pure));
|
||||||
| ^^^^ expected one of `)`, `att_syntax`, `may_unwind`, or `raw`
|
| ^^^^ expected one of `)`, `att_syntax`, or `raw`
|
||||||
|
|
||||||
error: expected one of `)`, `att_syntax`, `may_unwind`, or `raw`, found `nostack`
|
error: expected one of `)`, `att_syntax`, or `raw`, found `nostack`
|
||||||
--> $DIR/bad-options.rs:39:25
|
--> $DIR/bad-options.rs:39:25
|
||||||
|
|
|
|
||||||
LL | global_asm!("", options(nostack));
|
LL | global_asm!("", options(nostack));
|
||||||
| ^^^^^^^ expected one of `)`, `att_syntax`, `may_unwind`, or `raw`
|
| ^^^^^^^ expected one of `)`, `att_syntax`, or `raw`
|
||||||
|
|
||||||
error: expected one of `)`, `att_syntax`, `may_unwind`, or `raw`, found `preserves_flags`
|
error: expected one of `)`, `att_syntax`, or `raw`, found `preserves_flags`
|
||||||
--> $DIR/bad-options.rs:41:25
|
--> $DIR/bad-options.rs:41:25
|
||||||
|
|
|
|
||||||
LL | global_asm!("", options(preserves_flags));
|
LL | global_asm!("", options(preserves_flags));
|
||||||
| ^^^^^^^^^^^^^^^ expected one of `)`, `att_syntax`, `may_unwind`, or `raw`
|
| ^^^^^^^^^^^^^^^ expected one of `)`, `att_syntax`, or `raw`
|
||||||
|
|
||||||
error: invalid ABI for `clobber_abi`
|
error: invalid ABI for `clobber_abi`
|
||||||
--> $DIR/bad-options.rs:20:18
|
--> $DIR/bad-options.rs:20:18
|
||||||
|
|
|
@ -266,23 +266,23 @@ error: expected one of `,`, `.`, `?`, or an operator, found `FOO`
|
||||||
LL | global_asm!("{}", const(reg) FOO);
|
LL | global_asm!("{}", const(reg) FOO);
|
||||||
| ^^^ expected one of `,`, `.`, `?`, or an operator
|
| ^^^ expected one of `,`, `.`, `?`, or an operator
|
||||||
|
|
||||||
error: expected one of `)`, `att_syntax`, `may_unwind`, or `raw`, found `FOO`
|
error: expected one of `)`, `att_syntax`, or `raw`, found `FOO`
|
||||||
--> $DIR/parse-error.rs:104:25
|
--> $DIR/parse-error.rs:104:25
|
||||||
|
|
|
|
||||||
LL | global_asm!("", options(FOO));
|
LL | global_asm!("", options(FOO));
|
||||||
| ^^^ expected one of `)`, `att_syntax`, `may_unwind`, or `raw`
|
| ^^^ expected one of `)`, `att_syntax`, or `raw`
|
||||||
|
|
||||||
error: expected one of `)`, `att_syntax`, `may_unwind`, or `raw`, found `nomem`
|
error: expected one of `)`, `att_syntax`, or `raw`, found `nomem`
|
||||||
--> $DIR/parse-error.rs:106:25
|
--> $DIR/parse-error.rs:106:25
|
||||||
|
|
|
|
||||||
LL | global_asm!("", options(nomem FOO));
|
LL | global_asm!("", options(nomem FOO));
|
||||||
| ^^^^^ expected one of `)`, `att_syntax`, `may_unwind`, or `raw`
|
| ^^^^^ expected one of `)`, `att_syntax`, or `raw`
|
||||||
|
|
||||||
error: expected one of `)`, `att_syntax`, `may_unwind`, or `raw`, found `nomem`
|
error: expected one of `)`, `att_syntax`, or `raw`, found `nomem`
|
||||||
--> $DIR/parse-error.rs:108:25
|
--> $DIR/parse-error.rs:108:25
|
||||||
|
|
|
|
||||||
LL | global_asm!("", options(nomem, FOO));
|
LL | global_asm!("", options(nomem, FOO));
|
||||||
| ^^^^^ expected one of `)`, `att_syntax`, `may_unwind`, or `raw`
|
| ^^^^^ expected one of `)`, `att_syntax`, or `raw`
|
||||||
|
|
||||||
error: arguments are not allowed after options
|
error: arguments are not allowed after options
|
||||||
--> $DIR/parse-error.rs:110:30
|
--> $DIR/parse-error.rs:110:30
|
||||||
|
|
|
@ -19,6 +19,9 @@ declare_clippy_lint! {
|
||||||
/// ### Why is this bad?
|
/// ### Why is this bad?
|
||||||
/// An assertion failure cannot output an useful message of the error.
|
/// An assertion failure cannot output an useful message of the error.
|
||||||
///
|
///
|
||||||
|
/// ### Known problems
|
||||||
|
/// The suggested replacement decreases the readability of code and log output.
|
||||||
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```rust,ignore
|
/// ```rust,ignore
|
||||||
/// # let r = Ok::<_, ()>(());
|
/// # let r = Ok::<_, ()>(());
|
||||||
|
@ -28,7 +31,7 @@ declare_clippy_lint! {
|
||||||
/// ```
|
/// ```
|
||||||
#[clippy::version = "1.64.0"]
|
#[clippy::version = "1.64.0"]
|
||||||
pub ASSERTIONS_ON_RESULT_STATES,
|
pub ASSERTIONS_ON_RESULT_STATES,
|
||||||
style,
|
restriction,
|
||||||
"`assert!(r.is_ok())`/`assert!(r.is_err())` gives worse error message than directly calling `r.unwrap()`/`r.unwrap_err()`"
|
"`assert!(r.is_ok())`/`assert!(r.is_err())` gives worse error message than directly calling `r.unwrap()`/`r.unwrap_err()`"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@ store.register_group(true, "clippy::all", Some("clippy_all"), vec![
|
||||||
LintId::of(almost_complete_letter_range::ALMOST_COMPLETE_LETTER_RANGE),
|
LintId::of(almost_complete_letter_range::ALMOST_COMPLETE_LETTER_RANGE),
|
||||||
LintId::of(approx_const::APPROX_CONSTANT),
|
LintId::of(approx_const::APPROX_CONSTANT),
|
||||||
LintId::of(assertions_on_constants::ASSERTIONS_ON_CONSTANTS),
|
LintId::of(assertions_on_constants::ASSERTIONS_ON_CONSTANTS),
|
||||||
LintId::of(assertions_on_result_states::ASSERTIONS_ON_RESULT_STATES),
|
|
||||||
LintId::of(async_yields_async::ASYNC_YIELDS_ASYNC),
|
LintId::of(async_yields_async::ASYNC_YIELDS_ASYNC),
|
||||||
LintId::of(attrs::BLANKET_CLIPPY_RESTRICTION_LINTS),
|
LintId::of(attrs::BLANKET_CLIPPY_RESTRICTION_LINTS),
|
||||||
LintId::of(attrs::DEPRECATED_CFG_ATTR),
|
LintId::of(attrs::DEPRECATED_CFG_ATTR),
|
||||||
|
|
|
@ -7,6 +7,7 @@ store.register_group(true, "clippy::restriction", Some("clippy_restriction"), ve
|
||||||
LintId::of(as_underscore::AS_UNDERSCORE),
|
LintId::of(as_underscore::AS_UNDERSCORE),
|
||||||
LintId::of(asm_syntax::INLINE_ASM_X86_ATT_SYNTAX),
|
LintId::of(asm_syntax::INLINE_ASM_X86_ATT_SYNTAX),
|
||||||
LintId::of(asm_syntax::INLINE_ASM_X86_INTEL_SYNTAX),
|
LintId::of(asm_syntax::INLINE_ASM_X86_INTEL_SYNTAX),
|
||||||
|
LintId::of(assertions_on_result_states::ASSERTIONS_ON_RESULT_STATES),
|
||||||
LintId::of(attrs::ALLOW_ATTRIBUTES_WITHOUT_REASON),
|
LintId::of(attrs::ALLOW_ATTRIBUTES_WITHOUT_REASON),
|
||||||
LintId::of(casts::FN_TO_NUMERIC_CAST_ANY),
|
LintId::of(casts::FN_TO_NUMERIC_CAST_ANY),
|
||||||
LintId::of(create_dir::CREATE_DIR),
|
LintId::of(create_dir::CREATE_DIR),
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
|
|
||||||
store.register_group(true, "clippy::style", Some("clippy_style"), vec![
|
store.register_group(true, "clippy::style", Some("clippy_style"), vec![
|
||||||
LintId::of(assertions_on_constants::ASSERTIONS_ON_CONSTANTS),
|
LintId::of(assertions_on_constants::ASSERTIONS_ON_CONSTANTS),
|
||||||
LintId::of(assertions_on_result_states::ASSERTIONS_ON_RESULT_STATES),
|
|
||||||
LintId::of(blacklisted_name::BLACKLISTED_NAME),
|
LintId::of(blacklisted_name::BLACKLISTED_NAME),
|
||||||
LintId::of(blocks_in_if_conditions::BLOCKS_IN_IF_CONDITIONS),
|
LintId::of(blocks_in_if_conditions::BLOCKS_IN_IF_CONDITIONS),
|
||||||
LintId::of(bool_assert_comparison::BOOL_ASSERT_COMPARISON),
|
LintId::of(bool_assert_comparison::BOOL_ASSERT_COMPARISON),
|
||||||
|
|
|
@ -441,7 +441,7 @@ impl SimpleFormatArgs {
|
||||||
};
|
};
|
||||||
|
|
||||||
match arg.position {
|
match arg.position {
|
||||||
ArgumentIs(n, _) | ArgumentImplicitlyIs(n) => {
|
ArgumentIs(n) | ArgumentImplicitlyIs(n) => {
|
||||||
if self.unnamed.len() <= n {
|
if self.unnamed.len() <= n {
|
||||||
// Use a dummy span to mark all unseen arguments.
|
// Use a dummy span to mark all unseen arguments.
|
||||||
self.unnamed.resize_with(n, || vec![DUMMY_SP]);
|
self.unnamed.resize_with(n, || vec![DUMMY_SP]);
|
||||||
|
@ -462,7 +462,7 @@ impl SimpleFormatArgs {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ArgumentNamed(n, _) => {
|
ArgumentNamed(n) => {
|
||||||
let n = Symbol::intern(n);
|
let n = Symbol::intern(n);
|
||||||
if let Some(x) = self.named.iter_mut().find(|x| x.0 == n) {
|
if let Some(x) = self.named.iter_mut().find(|x| x.0 == n) {
|
||||||
match x.1.as_slice() {
|
match x.1.as_slice() {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue