Auto merge of #92996 - matthiaskrgr:rollup-50wpzva, r=matthiaskrgr
Rollup of 10 pull requests Successful merges: - #92795 (Link sidebar "location" heading to top of page) - #92799 (Remove some unnecessary uses of `FieldDef::ident`) - #92808 (Fix `try wrapping expression in variant` suggestion with struct field shorthand) - #92819 (rustdoc: remove hand-rolled isatty) - #92876 (Fix suggesting turbofish with lifetime arguments) - #92921 (Rename Printer constructor from mk_printer() to Printer::new()) - #92937 (rustdoc: Add missing dot separator) - #92953 (Copy an example to PartialOrd as well) - #92977 (Docs: recommend VecDeque instead of Vec::remove(0)) - #92981 (fix const_ptr_offset_from tracking issue) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
128417f40f
@ -4443,6 +4443,7 @@ version = "0.0.0"
|
||||
dependencies = [
|
||||
"arrayvec",
|
||||
"askama",
|
||||
"atty",
|
||||
"expect-test",
|
||||
"itertools 0.9.0",
|
||||
"minifier",
|
||||
|
@ -222,29 +222,6 @@ struct PrintStackElem {
|
||||
|
||||
const SIZE_INFINITY: isize = 0xffff;
|
||||
|
||||
pub fn mk_printer() -> Printer {
|
||||
let linewidth = 78;
|
||||
// Yes 55, it makes the ring buffers big enough to never fall behind.
|
||||
let n: usize = 55 * linewidth;
|
||||
debug!("mk_printer {}", linewidth);
|
||||
Printer {
|
||||
out: String::new(),
|
||||
buf_max_len: n,
|
||||
margin: linewidth as isize,
|
||||
space: linewidth as isize,
|
||||
left: 0,
|
||||
right: 0,
|
||||
// Initialize a single entry; advance_right() will extend it on demand
|
||||
// up to `buf_max_len` elements.
|
||||
buf: vec![BufEntry::default()],
|
||||
left_total: 0,
|
||||
right_total: 0,
|
||||
scan_stack: VecDeque::new(),
|
||||
print_stack: Vec::new(),
|
||||
pending_indentation: 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Printer {
|
||||
out: String,
|
||||
buf_max_len: usize,
|
||||
@ -288,6 +265,29 @@ fn default() -> Self {
|
||||
}
|
||||
|
||||
impl Printer {
|
||||
pub fn new() -> Self {
|
||||
let linewidth = 78;
|
||||
// Yes 55, it makes the ring buffers big enough to never fall behind.
|
||||
let n: usize = 55 * linewidth;
|
||||
debug!("Printer::new {}", linewidth);
|
||||
Printer {
|
||||
out: String::new(),
|
||||
buf_max_len: n,
|
||||
margin: linewidth as isize,
|
||||
space: linewidth as isize,
|
||||
left: 0,
|
||||
right: 0,
|
||||
// Initialize a single entry; advance_right() will extend it on demand
|
||||
// up to `buf_max_len` elements.
|
||||
buf: vec![BufEntry::default()],
|
||||
left_total: 0,
|
||||
right_total: 0,
|
||||
scan_stack: VecDeque::new(),
|
||||
print_stack: Vec::new(),
|
||||
pending_indentation: 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn last_token(&self) -> Token {
|
||||
self.buf[self.right].token.clone()
|
||||
}
|
||||
|
@ -103,7 +103,7 @@ pub fn print_crate<'a>(
|
||||
edition: Edition,
|
||||
) -> String {
|
||||
let mut s =
|
||||
State { s: pp::mk_printer(), comments: Some(Comments::new(sm, filename, input)), ann };
|
||||
State { s: pp::Printer::new(), comments: Some(Comments::new(sm, filename, input)), ann };
|
||||
|
||||
if is_expanded && !krate.attrs.iter().any(|attr| attr.has_name(sym::no_core)) {
|
||||
// We need to print `#![no_std]` (and its feature gate) so that
|
||||
@ -910,7 +910,7 @@ fn print_generic_args(&mut self, args: &ast::GenericArgs, colons_before_params:
|
||||
|
||||
impl<'a> State<'a> {
|
||||
pub fn new() -> State<'a> {
|
||||
State { s: pp::mk_printer(), comments: None, ann: &NoAnn }
|
||||
State { s: pp::Printer::new(), comments: None, ann: &NoAnn }
|
||||
}
|
||||
|
||||
crate fn commasep_cmnt<T, F, G>(&mut self, b: Breaks, elts: &[T], mut op: F, mut get_span: G)
|
||||
|
@ -170,7 +170,7 @@ pub fn new_from_input(
|
||||
ann: &'a dyn PpAnn,
|
||||
) -> State<'a> {
|
||||
State {
|
||||
s: pp::mk_printer(),
|
||||
s: pp::Printer::new(),
|
||||
comments: Some(Comments::new(sm, filename, input)),
|
||||
attrs,
|
||||
ann,
|
||||
@ -186,7 +186,7 @@ pub fn to_string<F>(ann: &dyn PpAnn, f: F) -> String
|
||||
where
|
||||
F: FnOnce(&mut State<'_>),
|
||||
{
|
||||
let mut printer = State { s: pp::mk_printer(), comments: None, attrs: &|_| &[], ann };
|
||||
let mut printer = State { s: pp::Printer::new(), comments: None, attrs: &|_| &[], ann };
|
||||
f(&mut printer);
|
||||
printer.s.eof()
|
||||
}
|
||||
|
@ -27,7 +27,7 @@
|
||||
use tracing::{debug, trace};
|
||||
|
||||
const TURBOFISH_SUGGESTION_STR: &str =
|
||||
"use `::<...>` instead of `<...>` to specify type or const arguments";
|
||||
"use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments";
|
||||
|
||||
/// Creates a placeholder argument.
|
||||
pub(super) fn dummy_arg(ident: Ident) -> Param {
|
||||
@ -731,21 +731,28 @@ pub(super) fn check_mistyped_turbofish_with_multiple_type_params(
|
||||
match x {
|
||||
Ok((_, _, false)) => {
|
||||
if self.eat(&token::Gt) {
|
||||
match self.parse_expr() {
|
||||
Ok(_) => {
|
||||
e.span_suggestion_verbose(
|
||||
binop.span.shrink_to_lo(),
|
||||
TURBOFISH_SUGGESTION_STR,
|
||||
"::".to_string(),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
e.emit();
|
||||
*expr =
|
||||
self.mk_expr_err(expr.span.to(self.prev_token.span));
|
||||
return Ok(());
|
||||
}
|
||||
Err(mut err) => {
|
||||
err.cancel();
|
||||
let turbo_err = e.span_suggestion_verbose(
|
||||
binop.span.shrink_to_lo(),
|
||||
TURBOFISH_SUGGESTION_STR,
|
||||
"::".to_string(),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
if self.check(&TokenKind::Semi) {
|
||||
turbo_err.emit();
|
||||
*expr = self.mk_expr_err(expr.span);
|
||||
return Ok(());
|
||||
} else {
|
||||
match self.parse_expr() {
|
||||
Ok(_) => {
|
||||
turbo_err.emit();
|
||||
*expr = self
|
||||
.mk_expr_err(expr.span.to(self.prev_token.span));
|
||||
return Ok(());
|
||||
}
|
||||
Err(mut err) => {
|
||||
turbo_err.cancel();
|
||||
err.cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1443,7 +1443,7 @@ fn parse_labeled_expr(
|
||||
&mut self,
|
||||
label: Label,
|
||||
attrs: AttrVec,
|
||||
consume_colon: bool,
|
||||
mut consume_colon: bool,
|
||||
) -> PResult<'a, P<Expr>> {
|
||||
let lo = label.ident.span;
|
||||
let label = Some(label);
|
||||
@ -1456,6 +1456,12 @@ fn parse_labeled_expr(
|
||||
self.parse_loop_expr(label, lo, attrs)
|
||||
} else if self.check(&token::OpenDelim(token::Brace)) || self.token.is_whole_block() {
|
||||
self.parse_block_expr(label, lo, BlockCheckMode::Default, attrs)
|
||||
} else if !ate_colon && (self.check(&TokenKind::Comma) || self.check(&TokenKind::Gt)) {
|
||||
// We're probably inside of a `Path<'a>` that needs a turbofish, so suppress the
|
||||
// "must be followed by a colon" error.
|
||||
self.diagnostic().delay_span_bug(lo, "this label wasn't parsed correctly");
|
||||
consume_colon = false;
|
||||
Ok(self.mk_expr_err(lo))
|
||||
} else {
|
||||
let msg = "expected `while`, `for`, `loop` or `{` after a label";
|
||||
self.struct_span_err(self.token.span, msg).span_label(self.token.span, msg).emit();
|
||||
|
@ -13,7 +13,7 @@
|
||||
use rustc_middle::ty::error::{ExpectedFound, TypeError};
|
||||
use rustc_middle::ty::print::with_no_trimmed_paths;
|
||||
use rustc_middle::ty::{self, AssocItem, Ty, TypeAndMut};
|
||||
use rustc_span::symbol::sym;
|
||||
use rustc_span::symbol::{sym, Symbol};
|
||||
use rustc_span::{BytePos, Span};
|
||||
|
||||
use super::method::probe;
|
||||
@ -24,7 +24,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
pub fn emit_coerce_suggestions(
|
||||
&self,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
expr: &hir::Expr<'_>,
|
||||
expr: &hir::Expr<'tcx>,
|
||||
expr_ty: Ty<'tcx>,
|
||||
expected: Ty<'tcx>,
|
||||
expected_ty_expr: Option<&'tcx hir::Expr<'tcx>>,
|
||||
@ -109,7 +109,7 @@ pub fn demand_eqtype_with_origin(
|
||||
|
||||
pub fn demand_coerce(
|
||||
&self,
|
||||
expr: &hir::Expr<'_>,
|
||||
expr: &hir::Expr<'tcx>,
|
||||
checked_ty: Ty<'tcx>,
|
||||
expected: Ty<'tcx>,
|
||||
expected_ty_expr: Option<&'tcx hir::Expr<'tcx>>,
|
||||
@ -129,7 +129,7 @@ pub fn demand_coerce(
|
||||
/// will be permitted if the diverges flag is currently "always".
|
||||
pub fn demand_coerce_diag(
|
||||
&self,
|
||||
expr: &hir::Expr<'_>,
|
||||
expr: &hir::Expr<'tcx>,
|
||||
checked_ty: Ty<'tcx>,
|
||||
expected: Ty<'tcx>,
|
||||
expected_ty_expr: Option<&'tcx hir::Expr<'tcx>>,
|
||||
@ -338,31 +338,40 @@ fn suggest_compatible_variants(
|
||||
})
|
||||
.collect();
|
||||
|
||||
if let [variant] = &compatible_variants[..] {
|
||||
// Just a single matching variant.
|
||||
err.multipart_suggestion(
|
||||
&format!("try wrapping the expression in `{}`", variant),
|
||||
vec![
|
||||
(expr.span.shrink_to_lo(), format!("{}(", variant)),
|
||||
(expr.span.shrink_to_hi(), ")".to_string()),
|
||||
],
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
} else if compatible_variants.len() > 1 {
|
||||
// More than one matching variant.
|
||||
err.multipart_suggestions(
|
||||
&format!(
|
||||
"try wrapping the expression in a variant of `{}`",
|
||||
self.tcx.def_path_str(expected_adt.did)
|
||||
),
|
||||
compatible_variants.into_iter().map(|variant| {
|
||||
let prefix = match self.maybe_get_struct_pattern_shorthand_field(expr) {
|
||||
Some(ident) => format!("{}: ", ident),
|
||||
None => format!(""),
|
||||
};
|
||||
|
||||
match &compatible_variants[..] {
|
||||
[] => { /* No variants to format */ }
|
||||
[variant] => {
|
||||
// Just a single matching variant.
|
||||
err.multipart_suggestion_verbose(
|
||||
&format!("try wrapping the expression in `{}`", variant),
|
||||
vec![
|
||||
(expr.span.shrink_to_lo(), format!("{}(", variant)),
|
||||
(expr.span.shrink_to_lo(), format!("{}{}(", prefix, variant)),
|
||||
(expr.span.shrink_to_hi(), ")".to_string()),
|
||||
]
|
||||
}),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
],
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
_ => {
|
||||
// More than one matching variant.
|
||||
err.multipart_suggestions(
|
||||
&format!(
|
||||
"try wrapping the expression in a variant of `{}`",
|
||||
self.tcx.def_path_str(expected_adt.did)
|
||||
),
|
||||
compatible_variants.into_iter().map(|variant| {
|
||||
vec![
|
||||
(expr.span.shrink_to_lo(), format!("{}{}(", prefix, variant)),
|
||||
(expr.span.shrink_to_hi(), ")".to_string()),
|
||||
]
|
||||
}),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -483,33 +492,45 @@ fn can_use_as_ref(&self, expr: &hir::Expr<'_>) -> Option<(Span, &'static str, St
|
||||
}
|
||||
}
|
||||
|
||||
crate fn is_hir_id_from_struct_pattern_shorthand_field(
|
||||
crate fn maybe_get_struct_pattern_shorthand_field(
|
||||
&self,
|
||||
hir_id: hir::HirId,
|
||||
sp: Span,
|
||||
) -> bool {
|
||||
let sm = self.sess().source_map();
|
||||
let parent_id = self.tcx.hir().get_parent_node(hir_id);
|
||||
if let Some(parent) = self.tcx.hir().find(parent_id) {
|
||||
// Account for fields
|
||||
if let Node::Expr(hir::Expr { kind: hir::ExprKind::Struct(_, fields, ..), .. }) = parent
|
||||
{
|
||||
if let Ok(src) = sm.span_to_snippet(sp) {
|
||||
for field in *fields {
|
||||
if field.ident.as_str() == src && field.is_shorthand {
|
||||
return true;
|
||||
}
|
||||
expr: &hir::Expr<'_>,
|
||||
) -> Option<Symbol> {
|
||||
let hir = self.tcx.hir();
|
||||
let local = match expr {
|
||||
hir::Expr {
|
||||
kind:
|
||||
hir::ExprKind::Path(hir::QPath::Resolved(
|
||||
None,
|
||||
hir::Path {
|
||||
res: hir::def::Res::Local(_),
|
||||
segments: [hir::PathSegment { ident, .. }],
|
||||
..
|
||||
},
|
||||
)),
|
||||
..
|
||||
} => Some(ident),
|
||||
_ => None,
|
||||
}?;
|
||||
|
||||
match hir.find(hir.get_parent_node(expr.hir_id))? {
|
||||
Node::Expr(hir::Expr { kind: hir::ExprKind::Struct(_, fields, ..), .. }) => {
|
||||
for field in *fields {
|
||||
if field.ident.name == local.name && field.is_shorthand {
|
||||
return Some(local.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
false
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
/// If the given `HirId` corresponds to a block with a trailing expression, return that expression
|
||||
crate fn maybe_get_block_expr(&self, hir_id: hir::HirId) -> Option<&'tcx hir::Expr<'tcx>> {
|
||||
match self.tcx.hir().find(hir_id)? {
|
||||
Node::Expr(hir::Expr { kind: hir::ExprKind::Block(block, ..), .. }) => block.expr,
|
||||
crate fn maybe_get_block_expr(&self, expr: &hir::Expr<'tcx>) -> Option<&'tcx hir::Expr<'tcx>> {
|
||||
match expr {
|
||||
hir::Expr { kind: hir::ExprKind::Block(block, ..), .. } => block.expr,
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
@ -547,7 +568,7 @@ fn can_use_as_ref(&self, expr: &hir::Expr<'_>) -> Option<(Span, &'static str, St
|
||||
/// `&mut`!".
|
||||
pub fn check_ref(
|
||||
&self,
|
||||
expr: &hir::Expr<'_>,
|
||||
expr: &hir::Expr<'tcx>,
|
||||
checked_ty: Ty<'tcx>,
|
||||
expected: Ty<'tcx>,
|
||||
) -> Option<(Span, &'static str, String, Applicability, bool /* verbose */)> {
|
||||
@ -565,9 +586,6 @@ pub fn check_ref(
|
||||
s.strip_prefix(old).map(|stripped| new.to_string() + stripped)
|
||||
};
|
||||
|
||||
let is_struct_pat_shorthand_field =
|
||||
self.is_hir_id_from_struct_pattern_shorthand_field(expr.hir_id, sp);
|
||||
|
||||
// `ExprKind::DropTemps` is semantically irrelevant for these suggestions.
|
||||
let expr = expr.peel_drop_temps();
|
||||
|
||||
@ -661,11 +679,12 @@ pub fn check_ref(
|
||||
false,
|
||||
));
|
||||
}
|
||||
let field_name = if is_struct_pat_shorthand_field {
|
||||
format!("{}: ", sugg_expr)
|
||||
} else {
|
||||
String::new()
|
||||
|
||||
let prefix = match self.maybe_get_struct_pattern_shorthand_field(expr) {
|
||||
Some(ident) => format!("{}: ", ident),
|
||||
None => format!(""),
|
||||
};
|
||||
|
||||
if let Some(hir::Node::Expr(hir::Expr {
|
||||
kind: hir::ExprKind::Assign(left_expr, ..),
|
||||
..
|
||||
@ -695,14 +714,14 @@ pub fn check_ref(
|
||||
hir::Mutability::Mut => (
|
||||
sp,
|
||||
"consider mutably borrowing here",
|
||||
format!("{}&mut {}", field_name, sugg_expr),
|
||||
format!("{}&mut {}", prefix, sugg_expr),
|
||||
Applicability::MachineApplicable,
|
||||
false,
|
||||
),
|
||||
hir::Mutability::Not => (
|
||||
sp,
|
||||
"consider borrowing here",
|
||||
format!("{}&{}", field_name, sugg_expr),
|
||||
format!("{}&{}", prefix, sugg_expr),
|
||||
Applicability::MachineApplicable,
|
||||
false,
|
||||
),
|
||||
@ -846,32 +865,33 @@ pub fn check_ref(
|
||||
if self.infcx.type_is_copy_modulo_regions(self.param_env, expected, sp)
|
||||
|| checked_ty.is_box()
|
||||
{
|
||||
if let Ok(code) = sm.span_to_snippet(expr.span) {
|
||||
let message = if checked_ty.is_box() {
|
||||
"consider unboxing the value"
|
||||
} else if checked_ty.is_region_ptr() {
|
||||
"consider dereferencing the borrow"
|
||||
} else {
|
||||
"consider dereferencing the type"
|
||||
};
|
||||
let (span, suggestion) = if is_struct_pat_shorthand_field {
|
||||
(expr.span, format!("{}: *{}", code, code))
|
||||
} else if self.is_else_if_block(expr) {
|
||||
// Don't suggest nonsense like `else *if`
|
||||
return None;
|
||||
} else if let Some(expr) = self.maybe_get_block_expr(expr.hir_id) {
|
||||
(expr.span.shrink_to_lo(), "*".to_string())
|
||||
} else {
|
||||
(expr.span.shrink_to_lo(), "*".to_string())
|
||||
};
|
||||
return Some((
|
||||
span,
|
||||
message,
|
||||
suggestion,
|
||||
Applicability::MachineApplicable,
|
||||
true,
|
||||
));
|
||||
}
|
||||
let message = if checked_ty.is_box() {
|
||||
"consider unboxing the value"
|
||||
} else if checked_ty.is_region_ptr() {
|
||||
"consider dereferencing the borrow"
|
||||
} else {
|
||||
"consider dereferencing the type"
|
||||
};
|
||||
let prefix = match self.maybe_get_struct_pattern_shorthand_field(expr) {
|
||||
Some(ident) => format!("{}: ", ident),
|
||||
None => format!(""),
|
||||
};
|
||||
let (span, suggestion) = if self.is_else_if_block(expr) {
|
||||
// Don't suggest nonsense like `else *if`
|
||||
return None;
|
||||
} else if let Some(expr) = self.maybe_get_block_expr(expr) {
|
||||
// prefix should be empty here..
|
||||
(expr.span.shrink_to_lo(), "*".to_string())
|
||||
} else {
|
||||
(expr.span.shrink_to_lo(), format!("{}*", prefix))
|
||||
};
|
||||
return Some((
|
||||
span,
|
||||
message,
|
||||
suggestion,
|
||||
Applicability::MachineApplicable,
|
||||
true,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -208,7 +208,7 @@ fn suggest_fn_call(
|
||||
pub fn suggest_deref_ref_or_into(
|
||||
&self,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
expr: &hir::Expr<'_>,
|
||||
expr: &hir::Expr<'tcx>,
|
||||
expected: Ty<'tcx>,
|
||||
found: Ty<'tcx>,
|
||||
expected_ty_expr: Option<&'tcx hir::Expr<'tcx>>,
|
||||
@ -231,7 +231,7 @@ pub fn suggest_deref_ref_or_into(
|
||||
}
|
||||
} else if !self.check_for_cast(err, expr, found, expected, expected_ty_expr) {
|
||||
let is_struct_pat_shorthand_field =
|
||||
self.is_hir_id_from_struct_pattern_shorthand_field(expr.hir_id, expr.span);
|
||||
self.maybe_get_struct_pattern_shorthand_field(expr).is_some();
|
||||
let methods = self.get_conversion_methods(expr.span, expected, found, expr.hir_id);
|
||||
if !methods.is_empty() {
|
||||
if let Ok(expr_text) = self.sess().source_map().span_to_snippet(expr.span) {
|
||||
|
@ -1372,9 +1372,12 @@ fn assert_failed(index: usize, len: usize) -> ! {
|
||||
///
|
||||
/// Note: Because this shifts over the remaining elements, it has a
|
||||
/// worst-case performance of *O*(*n*). If you don't need the order of elements
|
||||
/// to be preserved, use [`swap_remove`] instead.
|
||||
/// to be preserved, use [`swap_remove`] instead. If you'd like to remove
|
||||
/// elements from the beginning of the `Vec`, consider using
|
||||
/// [`VecDeque::pop_front`] instead.
|
||||
///
|
||||
/// [`swap_remove`]: Vec::swap_remove
|
||||
/// [`VecDeque::pop_front`]: crate::collections::VecDeque::pop_front
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
@ -1735,6 +1738,11 @@ pub fn push(&mut self, value: T) {
|
||||
/// Removes the last element from a vector and returns it, or [`None`] if it
|
||||
/// is empty.
|
||||
///
|
||||
/// If you'd like to pop the first element, consider using
|
||||
/// [`VecDeque::pop_front`] instead.
|
||||
///
|
||||
/// [`VecDeque::pop_front`]: crate::collections::VecDeque::pop_front
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
|
@ -661,20 +661,37 @@ fn clone_from(&mut self, other: &Self) {
|
||||
///
|
||||
/// ## Derivable
|
||||
///
|
||||
/// This trait can be used with `#[derive]`. When `derive`d on structs, it will produce a
|
||||
/// [lexicographic](https://en.wikipedia.org/wiki/Lexicographic_order) ordering based on the top-to-bottom declaration order of the struct's members.
|
||||
/// When `derive`d on enums, variants are ordered by their top-to-bottom discriminant order.
|
||||
/// This means variants at the top are less than variants at the bottom.
|
||||
/// Here's an example:
|
||||
/// This trait can be used with `#[derive]`.
|
||||
///
|
||||
/// When `derive`d on structs, it will produce a
|
||||
/// [lexicographic](https://en.wikipedia.org/wiki/Lexicographic_order) ordering
|
||||
/// based on the top-to-bottom declaration order of the struct's members.
|
||||
///
|
||||
/// When `derive`d on enums, variants are ordered by their discriminants.
|
||||
/// By default, the discriminant is smallest for variants at the top, and
|
||||
/// largest for variants at the bottom. Here's an example:
|
||||
///
|
||||
/// ```
|
||||
/// #[derive(PartialEq, PartialOrd)]
|
||||
/// enum Size {
|
||||
/// Small,
|
||||
/// Large,
|
||||
/// #[derive(PartialEq, Eq, PartialOrd, Ord)]
|
||||
/// enum E {
|
||||
/// Top,
|
||||
/// Bottom,
|
||||
/// }
|
||||
///
|
||||
/// assert!(Size::Small < Size::Large);
|
||||
/// assert!(E::Top < E::Bottom);
|
||||
/// ```
|
||||
///
|
||||
/// However, manually setting the discriminants can override this default
|
||||
/// behavior:
|
||||
///
|
||||
/// ```
|
||||
/// #[derive(PartialEq, Eq, PartialOrd, Ord)]
|
||||
/// enum E {
|
||||
/// Top = 2,
|
||||
/// Bottom = 1,
|
||||
/// }
|
||||
///
|
||||
/// assert!(E::Bottom < E::Top);
|
||||
/// ```
|
||||
///
|
||||
/// ## Lexicographical comparison
|
||||
@ -895,9 +912,38 @@ fn partial_cmp(&self, other: &Ordering) -> Option<Ordering> {
|
||||
///
|
||||
/// ## Derivable
|
||||
///
|
||||
/// This trait can be used with `#[derive]`. When `derive`d on structs, it will produce a
|
||||
/// lexicographic ordering based on the top-to-bottom declaration order of the struct's members.
|
||||
/// When `derive`d on enums, variants are ordered by their top-to-bottom discriminant order.
|
||||
/// This trait can be used with `#[derive]`.
|
||||
///
|
||||
/// When `derive`d on structs, it will produce a
|
||||
/// [lexicographic](https://en.wikipedia.org/wiki/Lexicographic_order) ordering
|
||||
/// based on the top-to-bottom declaration order of the struct's members.
|
||||
///
|
||||
/// When `derive`d on enums, variants are ordered by their discriminants.
|
||||
/// By default, the discriminant is smallest for variants at the top, and
|
||||
/// largest for variants at the bottom. Here's an example:
|
||||
///
|
||||
/// ```
|
||||
/// #[derive(PartialEq, PartialOrd)]
|
||||
/// enum E {
|
||||
/// Top,
|
||||
/// Bottom,
|
||||
/// }
|
||||
///
|
||||
/// assert!(E::Top < E::Bottom);
|
||||
/// ```
|
||||
///
|
||||
/// However, manually setting the discriminants can override this default
|
||||
/// behavior:
|
||||
///
|
||||
/// ```
|
||||
/// #[derive(PartialEq, PartialOrd)]
|
||||
/// enum E {
|
||||
/// Top = 2,
|
||||
/// Bottom = 1,
|
||||
/// }
|
||||
///
|
||||
/// assert!(E::Bottom < E::Top);
|
||||
/// ```
|
||||
///
|
||||
/// ## How can I implement `PartialOrd`?
|
||||
///
|
||||
@ -970,8 +1016,8 @@ fn partial_cmp(&self, other: &Ordering) -> Option<Ordering> {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// let x : u32 = 0;
|
||||
/// let y : u32 = 1;
|
||||
/// let x: u32 = 0;
|
||||
/// let y: u32 = 1;
|
||||
///
|
||||
/// assert_eq!(x < y, true);
|
||||
/// assert_eq!(x.lt(&y), true);
|
||||
|
@ -1893,7 +1893,7 @@ pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
|
||||
pub fn nontemporal_store<T>(ptr: *mut T, val: T);
|
||||
|
||||
/// See documentation of `<*const T>::offset_from` for details.
|
||||
#[rustc_const_unstable(feature = "const_ptr_offset_from", issue = "41079")]
|
||||
#[rustc_const_unstable(feature = "const_ptr_offset_from", issue = "92980")]
|
||||
pub fn ptr_offset_from<T>(ptr: *const T, base: *const T) -> isize;
|
||||
|
||||
/// See documentation of `<*const T>::guaranteed_eq` for details.
|
||||
|
@ -439,7 +439,7 @@ pub const fn wrapping_offset(self, count: isize) -> *const T
|
||||
/// }
|
||||
/// ```
|
||||
#[stable(feature = "ptr_offset_from", since = "1.47.0")]
|
||||
#[rustc_const_unstable(feature = "const_ptr_offset_from", issue = "41079")]
|
||||
#[rustc_const_unstable(feature = "const_ptr_offset_from", issue = "92980")]
|
||||
#[inline]
|
||||
pub const unsafe fn offset_from(self, origin: *const T) -> isize
|
||||
where
|
||||
|
@ -617,7 +617,7 @@ pub const fn guaranteed_eq(self, other: *mut T) -> bool
|
||||
/// }
|
||||
/// ```
|
||||
#[stable(feature = "ptr_offset_from", since = "1.47.0")]
|
||||
#[rustc_const_unstable(feature = "const_ptr_offset_from", issue = "41079")]
|
||||
#[rustc_const_unstable(feature = "const_ptr_offset_from", issue = "92980")]
|
||||
#[inline(always)]
|
||||
pub const unsafe fn offset_from(self, origin: *const T) -> isize
|
||||
where
|
||||
|
@ -9,6 +9,7 @@ path = "lib.rs"
|
||||
[dependencies]
|
||||
arrayvec = { version = "0.7", default-features = false }
|
||||
askama = { version = "0.11", default-features = false }
|
||||
atty = "0.2"
|
||||
pulldown-cmark = { version = "0.9", default-features = false }
|
||||
minifier = "0.0.41"
|
||||
rayon = "1.5.1"
|
||||
|
@ -1736,7 +1736,7 @@ fn print_sidebar(cx: &Context<'_>, it: &clean::Item, buffer: &mut Buffer) {
|
||||
{
|
||||
write!(
|
||||
buffer,
|
||||
"<h2 class=\"location\">{}{}</h2>",
|
||||
"<h2 class=\"location\"><a href=\"#\">{}{}</a></h2>",
|
||||
match *it.kind {
|
||||
clean::StructItem(..) => "Struct ",
|
||||
clean::TraitItem(..) => "Trait ",
|
||||
|
@ -670,7 +670,11 @@ fn trait_item(w: &mut Buffer, cx: &Context<'_>, m: &clean::Item, t: &clean::Item
|
||||
}
|
||||
write!(w, "<div id=\"{}\" class=\"method has-srclink\">", id);
|
||||
write!(w, "<div class=\"rightside\">");
|
||||
render_stability_since(w, m, t, cx.tcx());
|
||||
|
||||
let has_stability = render_stability_since(w, m, t, cx.tcx());
|
||||
if has_stability {
|
||||
w.write_str(" · ");
|
||||
}
|
||||
write_srclink(cx, m, w);
|
||||
write!(w, "</div>");
|
||||
write!(w, "<h4 class=\"code-header\">");
|
||||
@ -1457,14 +1461,14 @@ fn render_stability_since(
|
||||
item: &clean::Item,
|
||||
containing_item: &clean::Item,
|
||||
tcx: TyCtxt<'_>,
|
||||
) {
|
||||
) -> bool {
|
||||
render_stability_since_raw(
|
||||
w,
|
||||
item.stable_since(tcx),
|
||||
item.const_stability(tcx),
|
||||
containing_item.stable_since(tcx),
|
||||
containing_item.const_stable_since(tcx),
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
fn compare_impl<'a, 'b>(lhs: &'a &&Impl, rhs: &'b &&Impl, cx: &Context<'_>) -> Ordering {
|
||||
|
@ -71,7 +71,8 @@
|
||||
use tikv_jemalloc_sys as jemalloc_sys;
|
||||
|
||||
use std::default::Default;
|
||||
use std::env;
|
||||
use std::env::{self, VarError};
|
||||
use std::io;
|
||||
use std::process;
|
||||
|
||||
use rustc_driver::{abort_on_err, describe_lints};
|
||||
@ -179,47 +180,20 @@ pub fn main() {
|
||||
}
|
||||
|
||||
fn init_logging() {
|
||||
use std::io;
|
||||
|
||||
// FIXME remove these and use winapi 0.3 instead
|
||||
// Duplicates: bootstrap/compile.rs, librustc_errors/emitter.rs, rustc_driver/lib.rs
|
||||
#[cfg(unix)]
|
||||
fn stdout_isatty() -> bool {
|
||||
extern crate libc;
|
||||
unsafe { libc::isatty(libc::STDOUT_FILENO) != 0 }
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn stdout_isatty() -> bool {
|
||||
extern crate winapi;
|
||||
use winapi::um::consoleapi::GetConsoleMode;
|
||||
use winapi::um::processenv::GetStdHandle;
|
||||
use winapi::um::winbase::STD_OUTPUT_HANDLE;
|
||||
|
||||
unsafe {
|
||||
let handle = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
let mut out = 0;
|
||||
GetConsoleMode(handle, &mut out) != 0
|
||||
}
|
||||
}
|
||||
|
||||
let color_logs = match std::env::var("RUSTDOC_LOG_COLOR") {
|
||||
Ok(value) => match value.as_ref() {
|
||||
"always" => true,
|
||||
"never" => false,
|
||||
"auto" => stdout_isatty(),
|
||||
_ => early_error(
|
||||
ErrorOutputType::default(),
|
||||
&format!(
|
||||
"invalid log color value '{}': expected one of always, never, or auto",
|
||||
value
|
||||
),
|
||||
),
|
||||
},
|
||||
Err(std::env::VarError::NotPresent) => stdout_isatty(),
|
||||
Err(std::env::VarError::NotUnicode(_value)) => early_error(
|
||||
let color_logs = match std::env::var("RUSTDOC_LOG_COLOR").as_deref() {
|
||||
Ok("always") => true,
|
||||
Ok("never") => false,
|
||||
Ok("auto") | Err(VarError::NotPresent) => atty::is(atty::Stream::Stdout),
|
||||
Ok(value) => early_error(
|
||||
ErrorOutputType::default(),
|
||||
"non-Unicode log color value: expected one of always, never, or auto",
|
||||
&format!("invalid log color value '{}': expected one of always, never, or auto", value),
|
||||
),
|
||||
Err(VarError::NotUnicode(value)) => early_error(
|
||||
ErrorOutputType::default(),
|
||||
&format!(
|
||||
"invalid log color value '{}': expected one of always, never, or auto",
|
||||
value.to_string_lossy()
|
||||
),
|
||||
),
|
||||
};
|
||||
let filter = tracing_subscriber::EnvFilter::from_env("RUSTDOC_LOG");
|
||||
|
@ -436,8 +436,7 @@ fn variant_field<'path>(
|
||||
}
|
||||
match tcx.type_of(did).kind() {
|
||||
ty::Adt(def, _) if def.is_enum() => {
|
||||
if let Some(field) =
|
||||
def.all_fields().find(|f| f.ident(tcx).name == variant_field_name)
|
||||
if let Some(field) = def.all_fields().find(|f| f.name == variant_field_name)
|
||||
{
|
||||
Ok((ty_res, Some(ItemFragment(FragmentKind::VariantField, field.did))))
|
||||
} else {
|
||||
@ -806,11 +805,8 @@ fn resolve_associated_item(
|
||||
ty::Adt(def, _) if !def.is_enum() => def,
|
||||
_ => return None,
|
||||
};
|
||||
let field = def
|
||||
.non_enum_variant()
|
||||
.fields
|
||||
.iter()
|
||||
.find(|item| item.ident(tcx).name == item_name)?;
|
||||
let field =
|
||||
def.non_enum_variant().fields.iter().find(|item| item.name == item_name)?;
|
||||
Some((root_res, ItemFragment(FragmentKind::StructField, field.did)))
|
||||
}
|
||||
Res::Def(DefKind::Trait, did) => tcx
|
||||
|
@ -22,6 +22,13 @@ click: "#structs + .item-table .item-left > a"
|
||||
assert-count: (".sidebar .location", 2)
|
||||
// We check that there is no crate listed outside of the top level.
|
||||
assert-false: ".sidebar-elems > .crate"
|
||||
|
||||
click: ".sidebar-links a"
|
||||
assert-property: ("html", {"scrollTop": "389"})
|
||||
|
||||
click: ".sidebar h2.location"
|
||||
assert-property: ("html", {"scrollTop": "0"})
|
||||
|
||||
// We now go back to the crate page to click on the "lib2" crate link.
|
||||
goto: file://|DOC_PATH|/test_docs/index.html
|
||||
click: ".sidebar-elems .crate > ul > li:first-child > a"
|
||||
|
31
src/test/rustdoc/source-version-separator.rs
Normal file
31
src/test/rustdoc/source-version-separator.rs
Normal file
@ -0,0 +1,31 @@
|
||||
#![stable(feature = "bar", since = "1.0")]
|
||||
#![crate_name = "foo"]
|
||||
|
||||
#![feature(staged_api)]
|
||||
|
||||
// @has foo/trait.Bar.html
|
||||
// @has - '//div[@class="main-heading"]/*[@class="out-of-band"]' '1.0· source · '
|
||||
#[stable(feature = "bar", since = "1.0")]
|
||||
pub trait Bar {
|
||||
// @has - '//div[@id="tymethod.foo"]/*[@class="rightside"]' '3.0 · source'
|
||||
#[stable(feature = "foobar", since = "3.0")]
|
||||
fn foo();
|
||||
}
|
||||
|
||||
// @has - '//div[@id="implementors-list"]//*[@class="rightside"]' '4.0 · source'
|
||||
|
||||
// @has foo/struct.Foo.html
|
||||
// @has - '//div[@class="main-heading"]/*[@class="out-of-band"]' '1.0· source · '
|
||||
#[stable(feature = "baz", since = "1.0")]
|
||||
pub struct Foo;
|
||||
|
||||
impl Foo {
|
||||
// @has - '//div[@id="method.foofoo"]/*[@class="rightside"]' '3.0 · source'
|
||||
#[stable(feature = "foobar", since = "3.0")]
|
||||
pub fn foofoo() {}
|
||||
}
|
||||
|
||||
#[stable(feature = "yolo", since = "4.0")]
|
||||
impl Bar for Foo {
|
||||
fn foo() {}
|
||||
}
|
@ -4,7 +4,7 @@ error: comparison operators cannot be chained
|
||||
LL | foo<BAR + 3>();
|
||||
| ^ ^
|
||||
|
|
||||
help: use `::<...>` instead of `<...>` to specify type or const arguments
|
||||
help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
|
||||
|
|
||||
LL | foo::<BAR + 3>();
|
||||
| ++
|
||||
@ -15,7 +15,7 @@ error: comparison operators cannot be chained
|
||||
LL | foo<BAR + BAR>();
|
||||
| ^ ^
|
||||
|
|
||||
help: use `::<...>` instead of `<...>` to specify type or const arguments
|
||||
help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
|
||||
|
|
||||
LL | foo::<BAR + BAR>();
|
||||
| ++
|
||||
@ -26,7 +26,7 @@ error: comparison operators cannot be chained
|
||||
LL | foo<3 + 3>();
|
||||
| ^ ^
|
||||
|
|
||||
help: use `::<...>` instead of `<...>` to specify type or const arguments
|
||||
help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
|
||||
|
|
||||
LL | foo::<3 + 3>();
|
||||
| ++
|
||||
@ -37,7 +37,7 @@ error: comparison operators cannot be chained
|
||||
LL | foo<BAR - 3>();
|
||||
| ^ ^
|
||||
|
|
||||
help: use `::<...>` instead of `<...>` to specify type or const arguments
|
||||
help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
|
||||
|
|
||||
LL | foo::<BAR - 3>();
|
||||
| ++
|
||||
@ -48,7 +48,7 @@ error: comparison operators cannot be chained
|
||||
LL | foo<BAR - BAR>();
|
||||
| ^ ^
|
||||
|
|
||||
help: use `::<...>` instead of `<...>` to specify type or const arguments
|
||||
help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
|
||||
|
|
||||
LL | foo::<BAR - BAR>();
|
||||
| ++
|
||||
@ -59,7 +59,7 @@ error: comparison operators cannot be chained
|
||||
LL | foo<100 - BAR>();
|
||||
| ^ ^
|
||||
|
|
||||
help: use `::<...>` instead of `<...>` to specify type or const arguments
|
||||
help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
|
||||
|
|
||||
LL | foo::<100 - BAR>();
|
||||
| ++
|
||||
@ -70,7 +70,7 @@ error: comparison operators cannot be chained
|
||||
LL | foo<bar<i32>()>();
|
||||
| ^ ^
|
||||
|
|
||||
help: use `::<...>` instead of `<...>` to specify type or const arguments
|
||||
help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
|
||||
|
|
||||
LL | foo::<bar<i32>()>();
|
||||
| ++
|
||||
@ -87,7 +87,7 @@ error: comparison operators cannot be chained
|
||||
LL | foo<bar::<i32>()>();
|
||||
| ^ ^
|
||||
|
|
||||
help: use `::<...>` instead of `<...>` to specify type or const arguments
|
||||
help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
|
||||
|
|
||||
LL | foo::<bar::<i32>()>();
|
||||
| ++
|
||||
@ -98,7 +98,7 @@ error: comparison operators cannot be chained
|
||||
LL | foo<bar::<i32>() + BAR>();
|
||||
| ^ ^
|
||||
|
|
||||
help: use `::<...>` instead of `<...>` to specify type or const arguments
|
||||
help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
|
||||
|
|
||||
LL | foo::<bar::<i32>() + BAR>();
|
||||
| ++
|
||||
@ -109,7 +109,7 @@ error: comparison operators cannot be chained
|
||||
LL | foo<bar::<i32>() - BAR>();
|
||||
| ^ ^
|
||||
|
|
||||
help: use `::<...>` instead of `<...>` to specify type or const arguments
|
||||
help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
|
||||
|
|
||||
LL | foo::<bar::<i32>() - BAR>();
|
||||
| ++
|
||||
@ -120,7 +120,7 @@ error: comparison operators cannot be chained
|
||||
LL | foo<BAR - bar::<i32>()>();
|
||||
| ^ ^
|
||||
|
|
||||
help: use `::<...>` instead of `<...>` to specify type or const arguments
|
||||
help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
|
||||
|
|
||||
LL | foo::<BAR - bar::<i32>()>();
|
||||
| ++
|
||||
@ -131,7 +131,7 @@ error: comparison operators cannot be chained
|
||||
LL | foo<BAR - bar::<i32>()>();
|
||||
| ^ ^
|
||||
|
|
||||
help: use `::<...>` instead of `<...>` to specify type or const arguments
|
||||
help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
|
||||
|
|
||||
LL | foo::<BAR - bar::<i32>()>();
|
||||
| ++
|
||||
|
@ -3,6 +3,10 @@ enum Hey<A, B> {
|
||||
B(B),
|
||||
}
|
||||
|
||||
struct Foo {
|
||||
bar: Option<i32>,
|
||||
}
|
||||
|
||||
fn f() {}
|
||||
|
||||
fn a() -> Option<()> {
|
||||
@ -40,4 +44,8 @@ fn main() {
|
||||
let _: Hey<i32, bool> = false;
|
||||
//~^ ERROR mismatched types
|
||||
//~| HELP try wrapping
|
||||
let bar = 1i32;
|
||||
let _ = Foo { bar };
|
||||
//~^ ERROR mismatched types
|
||||
//~| HELP try wrapping
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/compatible-variants.rs:9:5
|
||||
--> $DIR/compatible-variants.rs:13:5
|
||||
|
|
||||
LL | fn a() -> Option<()> {
|
||||
| ---------- expected `Option<()>` because of return type
|
||||
@ -21,7 +21,7 @@ LL + Some(())
|
||||
|
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/compatible-variants.rs:17:5
|
||||
--> $DIR/compatible-variants.rs:21:5
|
||||
|
|
||||
LL | fn b() -> Result<(), ()> {
|
||||
| -------------- expected `Result<(), ()>` because of return type
|
||||
@ -37,7 +37,7 @@ LL + Ok(())
|
||||
|
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/compatible-variants.rs:23:25
|
||||
--> $DIR/compatible-variants.rs:27:25
|
||||
|
|
||||
LL | let _: Option<()> = while false {};
|
||||
| ---------- ^^^^^^^^^^^^^^ expected enum `Option`, found `()`
|
||||
@ -52,7 +52,7 @@ LL | let _: Option<()> = Some(while false {});
|
||||
| +++++ +
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/compatible-variants.rs:27:9
|
||||
--> $DIR/compatible-variants.rs:31:9
|
||||
|
|
||||
LL | while false {}
|
||||
| ^^^^^^^^^^^^^^ expected enum `Option`, found `()`
|
||||
@ -69,7 +69,7 @@ LL + Some(())
|
||||
|
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/compatible-variants.rs:31:31
|
||||
--> $DIR/compatible-variants.rs:35:31
|
||||
|
|
||||
LL | let _: Result<i32, i32> = 1;
|
||||
| ---------------- ^ expected enum `Result`, found integer
|
||||
@ -86,7 +86,7 @@ LL | let _: Result<i32, i32> = Err(1);
|
||||
| ++++ +
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/compatible-variants.rs:34:26
|
||||
--> $DIR/compatible-variants.rs:38:26
|
||||
|
|
||||
LL | let _: Option<i32> = 1;
|
||||
| ----------- ^ expected enum `Option`, found integer
|
||||
@ -101,7 +101,7 @@ LL | let _: Option<i32> = Some(1);
|
||||
| +++++ +
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/compatible-variants.rs:37:28
|
||||
--> $DIR/compatible-variants.rs:41:28
|
||||
|
|
||||
LL | let _: Hey<i32, i32> = 1;
|
||||
| ------------- ^ expected enum `Hey`, found integer
|
||||
@ -118,7 +118,7 @@ LL | let _: Hey<i32, i32> = Hey::B(1);
|
||||
| +++++++ +
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/compatible-variants.rs:40:29
|
||||
--> $DIR/compatible-variants.rs:44:29
|
||||
|
|
||||
LL | let _: Hey<i32, bool> = false;
|
||||
| -------------- ^^^^^ expected enum `Hey`, found `bool`
|
||||
@ -132,6 +132,19 @@ help: try wrapping the expression in `Hey::B`
|
||||
LL | let _: Hey<i32, bool> = Hey::B(false);
|
||||
| +++++++ +
|
||||
|
||||
error: aborting due to 8 previous errors
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/compatible-variants.rs:48:19
|
||||
|
|
||||
LL | let _ = Foo { bar };
|
||||
| ^^^ expected enum `Option`, found `i32`
|
||||
|
|
||||
= note: expected enum `Option<i32>`
|
||||
found type `i32`
|
||||
help: try wrapping the expression in `Some`
|
||||
|
|
||||
LL | let _ = Foo { bar: Some(bar) };
|
||||
| ++++++++++ +
|
||||
|
||||
error: aborting due to 9 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
||||
|
@ -4,7 +4,7 @@ error: comparison operators cannot be chained
|
||||
LL | (0..13).collect<Vec<i32>>();
|
||||
| ^ ^
|
||||
|
|
||||
help: use `::<...>` instead of `<...>` to specify type or const arguments
|
||||
help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
|
||||
|
|
||||
LL | (0..13).collect::<Vec<i32>>();
|
||||
| ++
|
||||
@ -15,7 +15,7 @@ error: comparison operators cannot be chained
|
||||
LL | Vec<i32>::new();
|
||||
| ^ ^
|
||||
|
|
||||
help: use `::<...>` instead of `<...>` to specify type or const arguments
|
||||
help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
|
||||
|
|
||||
LL | Vec::<i32>::new();
|
||||
| ++
|
||||
@ -26,7 +26,7 @@ error: comparison operators cannot be chained
|
||||
LL | (0..13).collect<Vec<i32>();
|
||||
| ^ ^
|
||||
|
|
||||
help: use `::<...>` instead of `<...>` to specify type or const arguments
|
||||
help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
|
||||
|
|
||||
LL | (0..13).collect::<Vec<i32>();
|
||||
| ++
|
||||
@ -37,7 +37,7 @@ error: expected one of `!`, `.`, `::`, `;`, `?`, `else`, `{`, or an operator, fo
|
||||
LL | let x = std::collections::HashMap<i128, i128>::new();
|
||||
| ^ expected one of 8 possible tokens
|
||||
|
|
||||
help: use `::<...>` instead of `<...>` to specify type or const arguments
|
||||
help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
|
||||
|
|
||||
LL | let x = std::collections::HashMap::<i128, i128>::new();
|
||||
| ++
|
||||
@ -48,7 +48,7 @@ error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found
|
||||
LL | std::collections::HashMap<i128, i128>::new()
|
||||
| ^ expected one of 8 possible tokens
|
||||
|
|
||||
help: use `::<...>` instead of `<...>` to specify type or const arguments
|
||||
help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
|
||||
|
|
||||
LL | std::collections::HashMap::<i128, i128>::new()
|
||||
| ++
|
||||
@ -59,7 +59,7 @@ error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found
|
||||
LL | std::collections::HashMap<i128, i128>::new();
|
||||
| ^ expected one of 8 possible tokens
|
||||
|
|
||||
help: use `::<...>` instead of `<...>` to specify type or const arguments
|
||||
help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
|
||||
|
|
||||
LL | std::collections::HashMap::<i128, i128>::new();
|
||||
| ++
|
||||
@ -70,7 +70,7 @@ error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found
|
||||
LL | std::collections::HashMap<i128, i128>::new(1, 2);
|
||||
| ^ expected one of 8 possible tokens
|
||||
|
|
||||
help: use `::<...>` instead of `<...>` to specify type or const arguments
|
||||
help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
|
||||
|
|
||||
LL | std::collections::HashMap::<i128, i128>::new(1, 2);
|
||||
| ++
|
||||
|
@ -87,7 +87,7 @@ LL | let r = R { i };
|
||||
help: consider dereferencing the borrow
|
||||
|
|
||||
LL | let r = R { i: *i };
|
||||
| ~~~~~
|
||||
| ++++
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/deref-suggestion.rs:46:20
|
||||
|
@ -1,6 +1,3 @@
|
||||
fn f<T>() {}
|
||||
struct X;
|
||||
|
||||
fn main() {
|
||||
false == false == false;
|
||||
//~^ ERROR comparison operators cannot be chained
|
||||
@ -12,15 +9,26 @@ fn main() {
|
||||
|
||||
f<X>();
|
||||
//~^ ERROR comparison operators cannot be chained
|
||||
//~| HELP use `::<...>` instead of `<...>` to specify type or const arguments
|
||||
//~| HELP use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
|
||||
|
||||
f<Result<Option<X>, Option<Option<X>>>(1, 2);
|
||||
//~^ ERROR comparison operators cannot be chained
|
||||
//~| HELP use `::<...>` instead of `<...>` to specify type or const arguments
|
||||
//~| HELP use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
|
||||
|
||||
use std::convert::identity;
|
||||
let _ = identity<u8>;
|
||||
let _ = f<u8, i8>();
|
||||
//~^ ERROR expected one of
|
||||
//~| HELP use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
|
||||
|
||||
let _ = f<'_, i8>();
|
||||
//~^ ERROR expected one of
|
||||
//~| HELP use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
|
||||
|
||||
f<'_>();
|
||||
//~^ comparison operators cannot be chained
|
||||
//~| HELP use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
|
||||
|
||||
let _ = f<u8>;
|
||||
//~^ ERROR comparison operators cannot be chained
|
||||
//~| HELP use `::<...>` instead of `<...>` to specify type or const arguments
|
||||
//~| HELP use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
|
||||
//~| HELP or use `(...)` if you meant to specify fn arguments
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
error: comparison operators cannot be chained
|
||||
--> $DIR/require-parens-for-chained-comparison.rs:5:11
|
||||
--> $DIR/require-parens-for-chained-comparison.rs:2:11
|
||||
|
|
||||
LL | false == false == false;
|
||||
| ^^ ^^
|
||||
@ -10,7 +10,7 @@ LL | false == false && false == false;
|
||||
| ++++++++
|
||||
|
||||
error: comparison operators cannot be chained
|
||||
--> $DIR/require-parens-for-chained-comparison.rs:9:11
|
||||
--> $DIR/require-parens-for-chained-comparison.rs:6:11
|
||||
|
|
||||
LL | false == 0 < 2;
|
||||
| ^^ ^
|
||||
@ -21,35 +21,68 @@ LL | false == (0 < 2);
|
||||
| + +
|
||||
|
||||
error: comparison operators cannot be chained
|
||||
--> $DIR/require-parens-for-chained-comparison.rs:13:6
|
||||
--> $DIR/require-parens-for-chained-comparison.rs:10:6
|
||||
|
|
||||
LL | f<X>();
|
||||
| ^ ^
|
||||
|
|
||||
help: use `::<...>` instead of `<...>` to specify type or const arguments
|
||||
help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
|
||||
|
|
||||
LL | f::<X>();
|
||||
| ++
|
||||
|
||||
error: comparison operators cannot be chained
|
||||
--> $DIR/require-parens-for-chained-comparison.rs:17:6
|
||||
--> $DIR/require-parens-for-chained-comparison.rs:14:6
|
||||
|
|
||||
LL | f<Result<Option<X>, Option<Option<X>>>(1, 2);
|
||||
| ^ ^
|
||||
|
|
||||
help: use `::<...>` instead of `<...>` to specify type or const arguments
|
||||
help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
|
||||
|
|
||||
LL | f::<Result<Option<X>, Option<Option<X>>>(1, 2);
|
||||
| ++
|
||||
|
||||
error: expected one of `!`, `.`, `::`, `;`, `?`, `else`, `{`, or an operator, found `,`
|
||||
--> $DIR/require-parens-for-chained-comparison.rs:18:17
|
||||
|
|
||||
LL | let _ = f<u8, i8>();
|
||||
| ^ expected one of 8 possible tokens
|
||||
|
|
||||
help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
|
||||
|
|
||||
LL | let _ = f::<u8, i8>();
|
||||
| ++
|
||||
|
||||
error: expected one of `.`, `:`, `;`, `?`, `else`, `for`, `loop`, `while`, `{`, or an operator, found `,`
|
||||
--> $DIR/require-parens-for-chained-comparison.rs:22:17
|
||||
|
|
||||
LL | let _ = f<'_, i8>();
|
||||
| ^ expected one of 10 possible tokens
|
||||
|
|
||||
help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
|
||||
|
|
||||
LL | let _ = f::<'_, i8>();
|
||||
| ++
|
||||
|
||||
error: comparison operators cannot be chained
|
||||
--> $DIR/require-parens-for-chained-comparison.rs:22:21
|
||||
--> $DIR/require-parens-for-chained-comparison.rs:26:6
|
||||
|
|
||||
LL | let _ = identity<u8>;
|
||||
| ^ ^
|
||||
LL | f<'_>();
|
||||
| ^ ^
|
||||
|
|
||||
= help: use `::<...>` instead of `<...>` to specify type or const arguments
|
||||
help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
|
||||
|
|
||||
LL | f::<'_>();
|
||||
| ++
|
||||
|
||||
error: comparison operators cannot be chained
|
||||
--> $DIR/require-parens-for-chained-comparison.rs:30:14
|
||||
|
|
||||
LL | let _ = f<u8>;
|
||||
| ^ ^
|
||||
|
|
||||
= help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
|
||||
= help: or use `(...)` if you meant to specify fn arguments
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
error: aborting due to 8 previous errors
|
||||
|
||||
|
@ -4,7 +4,7 @@ error: comparison operators cannot be chained
|
||||
LL | T1<1>::C;
|
||||
| ^ ^
|
||||
|
|
||||
help: use `::<...>` instead of `<...>` to specify type or const arguments
|
||||
help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
|
||||
|
|
||||
LL | T1::<1>::C;
|
||||
| ++
|
||||
@ -15,7 +15,7 @@ error: expected one of `.`, `;`, `?`, `}`, or an operator, found `,`
|
||||
LL | T2<1, 2>::C;
|
||||
| ^ expected one of `.`, `;`, `?`, `}`, or an operator
|
||||
|
|
||||
help: use `::<...>` instead of `<...>` to specify type or const arguments
|
||||
help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
|
||||
|
|
||||
LL | T2::<1, 2>::C;
|
||||
| ++
|
||||
@ -26,7 +26,7 @@ error: expected one of `.`, `;`, `?`, `}`, or an operator, found `,`
|
||||
LL | T3<1, 2, 3>::C;
|
||||
| ^ expected one of `.`, `;`, `?`, `}`, or an operator
|
||||
|
|
||||
help: use `::<...>` instead of `<...>` to specify type or const arguments
|
||||
help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
|
||||
|
|
||||
LL | T3::<1, 2, 3>::C;
|
||||
| ++
|
||||
|
@ -4,7 +4,7 @@ error: comparison operators cannot be chained
|
||||
LL | fn foo1() -> [(); Foo1<10>::SUM] {
|
||||
| ^ ^
|
||||
|
|
||||
help: use `::<...>` instead of `<...>` to specify type or const arguments
|
||||
help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
|
||||
|
|
||||
LL | fn foo1() -> [(); Foo1::<10>::SUM] {
|
||||
| ++
|
||||
@ -15,7 +15,7 @@ error: expected one of `.`, `?`, `]`, or an operator, found `,`
|
||||
LL | fn foo2() -> [(); Foo2<10, 20>::SUM] {
|
||||
| ^ expected one of `.`, `?`, `]`, or an operator
|
||||
|
|
||||
help: use `::<...>` instead of `<...>` to specify type or const arguments
|
||||
help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
|
||||
|
|
||||
LL | fn foo2() -> [(); Foo2::<10, 20>::SUM] {
|
||||
| ++
|
||||
@ -26,7 +26,7 @@ error: expected one of `.`, `?`, `]`, or an operator, found `,`
|
||||
LL | fn foo3() -> [(); Foo3<10, 20, 30>::SUM] {
|
||||
| ^ expected one of `.`, `?`, `]`, or an operator
|
||||
|
|
||||
help: use `::<...>` instead of `<...>` to specify type or const arguments
|
||||
help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
|
||||
|
|
||||
LL | fn foo3() -> [(); Foo3::<10, 20, 30>::SUM] {
|
||||
| ++
|
||||
|
Loading…
Reference in New Issue
Block a user