Auto merge of #70734 - Dylan-DPC:rollup-xmncatq, r=Dylan-DPC
Rollup of 6 pull requests Successful merges: - #70696 (Extend #69020 test to include reversed operand order.) - #70706 (Minor cleanup in rustdoc --check-theme) - #70725 (Avoid `.unwrap()`s on `.span_to_snippet(...)`s) - #70728 (Minor doc improvements on `AllocRef`) - #70730 (Fix link in task::Wake docs) - #70731 (Minor follow-up after renaming librustc(_middle)) Failed merges: r? @ghost
This commit is contained in:
commit
f6fe99c798
|
@ -12,10 +12,12 @@ use crate::sync::Arc;
|
|||
/// to the tasks that are executed on that executor.
|
||||
///
|
||||
/// This trait is a memory-safe and ergonomic alternative to constructing a
|
||||
/// [`RawWaker`]. It supports the common executor design in which the data
|
||||
/// used to wake up a task is stored in an [`Arc`]. Some executors (especially
|
||||
/// [`RawWaker`]. It supports the common executor design in which the data used
|
||||
/// to wake up a task is stored in an [`Arc`][arc]. Some executors (especially
|
||||
/// those for embedded systems) cannot use this API, which is why [`RawWaker`]
|
||||
/// exists as an alternative for those systems.
|
||||
///
|
||||
/// [arc]: ../../std/sync/struct.Arc.html
|
||||
#[unstable(feature = "wake_trait", issue = "69912")]
|
||||
pub trait Wake {
|
||||
/// Wake this task.
|
||||
|
|
|
@ -119,7 +119,7 @@ pub enum ReallocPlacement {
|
|||
///
|
||||
/// Unlike [`GlobalAlloc`][], zero-sized allocations are allowed in `AllocRef`. If an underlying
|
||||
/// allocator does not support this (like jemalloc) or return a null pointer (such as
|
||||
/// `libc::malloc`), this case must be caught.
|
||||
/// `libc::malloc`), this must be caught by the implementation.
|
||||
///
|
||||
/// ### Currently allocated memory
|
||||
///
|
||||
|
@ -157,10 +157,10 @@ pub enum ReallocPlacement {
|
|||
/// # Safety
|
||||
///
|
||||
/// * Memory blocks returned from an allocator must point to valid memory and retain their validity
|
||||
/// until the instance and all of its clones are dropped, and
|
||||
/// until the instance and all of its clones are dropped,
|
||||
///
|
||||
/// * cloning or moving the allocator must not invalidate memory blocks returned from this
|
||||
/// allocator. A cloned allocator must behave like the same allocator.
|
||||
/// allocator. A cloned allocator must behave like the same allocator, and
|
||||
///
|
||||
/// * any pointer to a memory block which is [*currently allocated*] may be passed to any other
|
||||
/// method of the allocator.
|
||||
|
@ -168,7 +168,9 @@ pub enum ReallocPlacement {
|
|||
/// [*currently allocated*]: #currently-allocated-memory
|
||||
#[unstable(feature = "allocator_api", issue = "32838")]
|
||||
pub unsafe trait AllocRef {
|
||||
/// On success, returns a memory block meeting the size and alignment guarantees of `layout`.
|
||||
/// Attempts to allocate a block of memory.
|
||||
///
|
||||
/// On success, returns a [`MemoryBlock`][] meeting the size and alignment guarantees of `layout`.
|
||||
///
|
||||
/// The returned block may have a larger size than specified by `layout.size()` and is
|
||||
/// initialized as specified by [`init`], all the way up to the returned size of the block.
|
||||
|
@ -190,12 +192,12 @@ pub unsafe trait AllocRef {
|
|||
/// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html
|
||||
fn alloc(&mut self, layout: Layout, init: AllocInit) -> Result<MemoryBlock, AllocErr>;
|
||||
|
||||
/// Deallocates the memory denoted by `memory`.
|
||||
/// Deallocates the memory referenced by `ptr`.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// * `ptr` must be [*currently allocated*] via this allocator, and
|
||||
/// * `layout` must [*fit*] the `ptr`.
|
||||
/// * `ptr` must denote a block of memory [*currently allocated*] via this allocator, and
|
||||
/// * `layout` must [*fit*] that block of memory.
|
||||
///
|
||||
/// [*currently allocated*]: #currently-allocated-memory
|
||||
/// [*fit*]: #memory-fitting
|
||||
|
@ -203,13 +205,13 @@ pub unsafe trait AllocRef {
|
|||
|
||||
/// Attempts to extend the memory block.
|
||||
///
|
||||
/// Returns a new memory block containing a pointer and the actual size of the allocated
|
||||
/// block. The pointer is suitable for holding data described by a new layout with `layout`’s
|
||||
/// Returns a new [`MemoryBlock`][] containing a pointer and the actual size of the allocated
|
||||
/// memory. The pointer is suitable for holding data described by a new layout with `layout`’s
|
||||
/// alignment and a size given by `new_size`. To accomplish this, the allocator may extend the
|
||||
/// allocation referenced by `ptr` to fit the new layout. If the [`placement`] is
|
||||
/// [`InPlace`], the returned pointer is guaranteed to be the same as the passed `ptr`.
|
||||
///
|
||||
/// If `ReallocPlacement::MayMove` is used then ownership of the memory block referenced by `ptr`
|
||||
/// If [`MayMove`] is used then ownership of the memory block referenced by `ptr`
|
||||
/// is transferred to this allocator. The memory may or may not be freed, and should be
|
||||
/// considered unusable (unless of course it is transferred back to the caller again via the
|
||||
/// return value of this method).
|
||||
|
@ -227,17 +229,18 @@ pub unsafe trait AllocRef {
|
|||
/// the size of the `MemoryBlock` returned by the `grow` call.
|
||||
///
|
||||
/// [`InPlace`]: ReallocPlacement::InPlace
|
||||
/// [`MayMove`]: ReallocPlacement::MayMove
|
||||
/// [`placement`]: ReallocPlacement
|
||||
/// [`init`]: AllocInit
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// * `ptr` must be [*currently allocated*] via this allocator,
|
||||
/// * `layout` must [*fit*] the `ptr`. (The `new_size` argument need not fit it.)
|
||||
/// * `ptr` must denote a block of memory [*currently allocated*] via this allocator,
|
||||
/// * `layout` must [*fit*] that block of memory (The `new_size` argument need not fit it.),
|
||||
// We can't require that `new_size` is strictly greater than `memory.size` because of ZSTs.
|
||||
// An alternative would be
|
||||
// * `new_size must be strictly greater than `memory.size` or both are zero
|
||||
/// * `new_size` must be greater than or equal to `layout.size()`
|
||||
/// * `new_size` must be greater than or equal to `layout.size()`, and
|
||||
/// * `new_size`, when rounded up to the nearest multiple of `layout.align()`, must not overflow
|
||||
/// (i.e., the rounded value must be less than or equal to `usize::MAX`).
|
||||
///
|
||||
|
@ -289,8 +292,8 @@ pub unsafe trait AllocRef {
|
|||
|
||||
/// Attempts to shrink the memory block.
|
||||
///
|
||||
/// Returns a new memory block containing a pointer and the actual size of the allocated
|
||||
/// block. The pointer is suitable for holding data described by a new layout with `layout`’s
|
||||
/// Returns a new [`MemoryBlock`][] containing a pointer and the actual size of the allocated
|
||||
/// memory. The pointer is suitable for holding data described by a new layout with `layout`’s
|
||||
/// alignment and a size given by `new_size`. To accomplish this, the allocator may shrink the
|
||||
/// allocation referenced by `ptr` to fit the new layout. If the [`placement`] is
|
||||
/// [`InPlace`], the returned pointer is guaranteed to be the same as the passed `ptr`.
|
||||
|
@ -310,12 +313,12 @@ pub unsafe trait AllocRef {
|
|||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// * `ptr` must be [*currently allocated*] via this allocator,
|
||||
/// * `layout` must [*fit*] the `ptr`. (The `new_size` argument need not fit it.)
|
||||
/// * `ptr` must denote a block of memory [*currently allocated*] via this allocator,
|
||||
/// * `layout` must [*fit*] that block of memory (The `new_size` argument need not fit it.), and
|
||||
// We can't require that `new_size` is strictly smaller than `memory.size` because of ZSTs.
|
||||
// An alternative would be
|
||||
// * `new_size must be strictly smaller than `memory.size` or both are zero
|
||||
/// * `new_size` must be smaller than or equal to `layout.size()`
|
||||
/// * `new_size` must be smaller than or equal to `layout.size()`.
|
||||
///
|
||||
/// [*currently allocated*]: #currently-allocated-memory
|
||||
/// [*fit*]: #memory-fitting
|
||||
|
@ -323,7 +326,7 @@ pub unsafe trait AllocRef {
|
|||
/// # Errors
|
||||
///
|
||||
/// Returns `Err` if the new layout does not meet the allocator's size and alignment
|
||||
/// constraints of the allocator, or if growing otherwise fails.
|
||||
/// constraints of the allocator, or if shrinking otherwise fails.
|
||||
///
|
||||
/// Implementations are encouraged to return `Err` on memory exhaustion rather than panicking or
|
||||
/// aborting, but this is not a strict requirement. (Specifically: it is *legal* to implement
|
||||
|
|
|
@ -169,7 +169,8 @@ pub struct AssertParamIsCopy<T: Copy + ?Sized> {
|
|||
/// Implementations of `Clone` for primitive types.
|
||||
///
|
||||
/// Implementations that cannot be described in Rust
|
||||
/// are implemented in `SelectionContext::copy_clone_conditions()` in librustc_middle.
|
||||
/// are implemented in `traits::SelectionContext::copy_clone_conditions()`
|
||||
/// in `rustc_trait_selection`.
|
||||
mod impls {
|
||||
|
||||
use super::Clone;
|
||||
|
|
|
@ -759,7 +759,8 @@ impl<T: ?Sized> Unpin for *mut T {}
|
|||
/// Implementations of `Copy` for primitive types.
|
||||
///
|
||||
/// Implementations that cannot be described in Rust
|
||||
/// are implemented in `SelectionContext::copy_clone_conditions()` in librustc_middle.
|
||||
/// are implemented in `traits::SelectionContext::copy_clone_conditions()`
|
||||
/// in `rustc_trait_selection`.
|
||||
mod copy_impls {
|
||||
|
||||
use super::Copy;
|
||||
|
|
|
@ -6,7 +6,8 @@
|
|||
//! They can be used as targets of transmutes in unsafe code for manipulating
|
||||
//! the raw representations directly.
|
||||
//!
|
||||
//! Their definition should always match the ABI defined in `rustc_target::abi`.
|
||||
//! Their definition should always match the ABI defined in
|
||||
//! `rustc_middle::ty::layout`.
|
||||
|
||||
/// The representation of a trait object like `&SomeTrait`.
|
||||
///
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//! This module provides linkage between libgraphviz traits and
|
||||
//! `rustc_middle::middle::typeck::infer::region_constraints`, generating a
|
||||
//! `rustc_trait_selection::infer::region_constraints`, generating a
|
||||
//! rendering of the graph represented by the list of `Constraint`
|
||||
//! instances (which make up the edges of the graph), as well as the
|
||||
//! origin for each constraint (which are attached to the labels on
|
||||
|
|
|
@ -202,7 +202,7 @@ pub(crate) enum Cause {
|
|||
///
|
||||
/// For more information about this translation, see
|
||||
/// `InferCtxt::process_registered_region_obligations` and
|
||||
/// `InferCtxt::type_must_outlive` in `rustc_middle::infer::outlives`.
|
||||
/// `InferCtxt::type_must_outlive` in `rustc_infer::infer::InferCtxt`.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct TypeTest<'tcx> {
|
||||
/// The type `T` that must outlive the region.
|
||||
|
|
|
@ -1053,7 +1053,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||
/// regions which are extracted and stored as having occurred at
|
||||
/// `locations`.
|
||||
///
|
||||
/// **Any `rustc_middle::infer` operations that might generate region
|
||||
/// **Any `rustc_infer::infer` operations that might generate region
|
||||
/// constraints should occur within this method so that those
|
||||
/// constraints can be properly localized!**
|
||||
fn fully_perform_op<R>(
|
||||
|
|
|
@ -165,9 +165,9 @@ impl<'a> Parser<'a> {
|
|||
// Rewind to before attempting to parse the type and continue parsing.
|
||||
let parser_snapshot_after_type = self.clone();
|
||||
mem::replace(self, parser_snapshot_before_type);
|
||||
|
||||
let snippet = self.span_to_snippet(pat.span).unwrap();
|
||||
err.span_label(pat.span, format!("while parsing the type for `{}`", snippet));
|
||||
if let Ok(snip) = self.span_to_snippet(pat.span) {
|
||||
err.span_label(pat.span, format!("while parsing the type for `{}`", snip));
|
||||
}
|
||||
(Some((parser_snapshot_after_type, colon_sp, err)), None)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,8 +27,8 @@ pub struct Context {
|
|||
/// of the innermost fn body. Each fn forms its own disjoint tree
|
||||
/// in the region hierarchy. These fn bodies are themselves
|
||||
/// arranged into a tree. See the "Modeling closures" section of
|
||||
/// the README in `infer::region_constraints` for more
|
||||
/// details.
|
||||
/// the README in `rustc_trait_selection::infer::region_constraints`
|
||||
/// for more details.
|
||||
root_id: Option<hir::ItemLocalId>,
|
||||
|
||||
/// The scope that contains any new variables declared, plus its depth in
|
||||
|
|
|
@ -438,7 +438,7 @@ fn new_index(tcx: TyCtxt<'tcx>) -> Index<'tcx> {
|
|||
// If the `-Z force-unstable-if-unmarked` flag is passed then we provide
|
||||
// a parent stability annotation which indicates that this is private
|
||||
// with the `rustc_private` feature. This is intended for use when
|
||||
// compiling librustc_middle crates themselves so we can leverage crates.io
|
||||
// compiling `librustc_*` crates themselves so we can leverage crates.io
|
||||
// while maintaining the invariant that all sysroot crates are unstable
|
||||
// by default and are unable to be used.
|
||||
if tcx.sess.opts.debugging_opts.force_unstable_if_unmarked {
|
||||
|
|
|
@ -143,8 +143,8 @@ fn find_libdir(sysroot: &Path) -> Cow<'static, str> {
|
|||
// FIXME: This is a quick hack to make the rustc binary able to locate
|
||||
// Rust libraries in Linux environments where libraries might be installed
|
||||
// to lib64/lib32. This would be more foolproof by basing the sysroot off
|
||||
// of the directory where librustc_middle is located, rather than where the rustc
|
||||
// binary is.
|
||||
// of the directory where `librustc_driver` is located, rather than
|
||||
// where the rustc binary is.
|
||||
// If --libdir is set during configuration to the value other than
|
||||
// "lib" (i.e., non-default), this value is used (see issue #16552).
|
||||
|
||||
|
|
|
@ -195,7 +195,7 @@ pub enum BuiltinLintDiagnostics {
|
|||
}
|
||||
|
||||
/// Lints that are buffered up early on in the `Session` before the
|
||||
/// `LintLevels` is calculated. These are later passed to `librustc_middle`.
|
||||
/// `LintLevels` is calculated.
|
||||
#[derive(PartialEq)]
|
||||
pub struct BufferedEarlyLint {
|
||||
/// The span of code that we are linting on.
|
||||
|
@ -207,7 +207,8 @@ pub struct BufferedEarlyLint {
|
|||
/// The `NodeId` of the AST node that generated the lint.
|
||||
pub node_id: NodeId,
|
||||
|
||||
/// A lint Id that can be passed to `rustc_session::lint::Lint::from_parser_lint_id`.
|
||||
/// A lint Id that can be passed to
|
||||
/// `rustc_lint::early::EarlyContextAndPass::check_id`.
|
||||
pub lint_id: LintId,
|
||||
|
||||
/// Customization of the `DiagnosticBuilder<'_>` for the lint.
|
||||
|
|
|
@ -65,7 +65,7 @@ pub trait InferCtxtExt<'tcx> {
|
|||
/// returns a span and `ArgKind` information that describes the
|
||||
/// arguments it expects. This can be supplied to
|
||||
/// `report_arg_count_mismatch`.
|
||||
fn get_fn_like_arguments(&self, node: Node<'_>) -> (Span, Vec<ArgKind>);
|
||||
fn get_fn_like_arguments(&self, node: Node<'_>) -> Option<(Span, Vec<ArgKind>)>;
|
||||
|
||||
/// Reports an error when the number of arguments needed by a
|
||||
/// trait match doesn't match the number that the expression
|
||||
|
@ -611,10 +611,10 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
)
|
||||
} else {
|
||||
let (closure_span, found) = found_did
|
||||
.and_then(|did| self.tcx.hir().get_if_local(did))
|
||||
.map(|node| {
|
||||
let (found_span, found) = self.get_fn_like_arguments(node);
|
||||
(Some(found_span), found)
|
||||
.and_then(|did| {
|
||||
let node = self.tcx.hir().get_if_local(did)?;
|
||||
let (found_span, found) = self.get_fn_like_arguments(node)?;
|
||||
Some((Some(found_span), found))
|
||||
})
|
||||
.unwrap_or((found_span, found));
|
||||
|
||||
|
@ -672,43 +672,38 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
/// returns a span and `ArgKind` information that describes the
|
||||
/// arguments it expects. This can be supplied to
|
||||
/// `report_arg_count_mismatch`.
|
||||
fn get_fn_like_arguments(&self, node: Node<'_>) -> (Span, Vec<ArgKind>) {
|
||||
match node {
|
||||
fn get_fn_like_arguments(&self, node: Node<'_>) -> Option<(Span, Vec<ArgKind>)> {
|
||||
let sm = self.tcx.sess.source_map();
|
||||
let hir = self.tcx.hir();
|
||||
Some(match node {
|
||||
Node::Expr(&hir::Expr {
|
||||
kind: hir::ExprKind::Closure(_, ref _decl, id, span, _),
|
||||
..
|
||||
}) => (
|
||||
self.tcx.sess.source_map().guess_head_span(span),
|
||||
self.tcx
|
||||
.hir()
|
||||
.body(id)
|
||||
sm.guess_head_span(span),
|
||||
hir.body(id)
|
||||
.params
|
||||
.iter()
|
||||
.map(|arg| {
|
||||
if let hir::Pat { kind: hir::PatKind::Tuple(ref args, _), span, .. } =
|
||||
*arg.pat
|
||||
{
|
||||
ArgKind::Tuple(
|
||||
Some(ArgKind::Tuple(
|
||||
Some(span),
|
||||
args.iter()
|
||||
.map(|pat| {
|
||||
let snippet = self
|
||||
.tcx
|
||||
.sess
|
||||
.source_map()
|
||||
.span_to_snippet(pat.span)
|
||||
.unwrap();
|
||||
(snippet, "_".to_owned())
|
||||
sm.span_to_snippet(pat.span)
|
||||
.ok()
|
||||
.map(|snippet| (snippet, "_".to_owned()))
|
||||
})
|
||||
.collect::<Vec<_>>(),
|
||||
)
|
||||
.collect::<Option<Vec<_>>>()?,
|
||||
))
|
||||
} else {
|
||||
let name =
|
||||
self.tcx.sess.source_map().span_to_snippet(arg.pat.span).unwrap();
|
||||
ArgKind::Arg(name, "_".to_owned())
|
||||
let name = sm.span_to_snippet(arg.pat.span).ok()?;
|
||||
Some(ArgKind::Arg(name, "_".to_owned()))
|
||||
}
|
||||
})
|
||||
.collect::<Vec<ArgKind>>(),
|
||||
.collect::<Option<Vec<ArgKind>>>()?,
|
||||
),
|
||||
Node::Item(&hir::Item { span, kind: hir::ItemKind::Fn(ref sig, ..), .. })
|
||||
| Node::ImplItem(&hir::ImplItem {
|
||||
|
@ -721,7 +716,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
kind: hir::TraitItemKind::Fn(ref sig, _),
|
||||
..
|
||||
}) => (
|
||||
self.tcx.sess.source_map().guess_head_span(span),
|
||||
sm.guess_head_span(span),
|
||||
sig.decl
|
||||
.inputs
|
||||
.iter()
|
||||
|
@ -735,16 +730,12 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
.collect::<Vec<ArgKind>>(),
|
||||
),
|
||||
Node::Ctor(ref variant_data) => {
|
||||
let span = variant_data
|
||||
.ctor_hir_id()
|
||||
.map(|hir_id| self.tcx.hir().span(hir_id))
|
||||
.unwrap_or(DUMMY_SP);
|
||||
let span = self.tcx.sess.source_map().guess_head_span(span);
|
||||
|
||||
let span = variant_data.ctor_hir_id().map(|id| hir.span(id)).unwrap_or(DUMMY_SP);
|
||||
let span = sm.guess_head_span(span);
|
||||
(span, vec![ArgKind::empty(); variant_data.fields().len()])
|
||||
}
|
||||
_ => panic!("non-FnLike node found: {:?}", node),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Reports an error when the number of arguments needed by a
|
||||
|
|
|
@ -732,12 +732,13 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
true
|
||||
};
|
||||
|
||||
let sm = self.tcx.sess.source_map();
|
||||
let (snippet, last_ty) =
|
||||
if let (true, hir::TyKind::TraitObject(..), Ok(snippet), true, Some(last_ty)) = (
|
||||
// Verify that we're dealing with a return `dyn Trait`
|
||||
ret_ty.span.overlaps(span),
|
||||
&ret_ty.kind,
|
||||
self.tcx.sess.source_map().span_to_snippet(ret_ty.span),
|
||||
sm.span_to_snippet(ret_ty.span),
|
||||
// If any of the return types does not conform to the trait, then we can't
|
||||
// suggest `impl Trait` nor trait objects, it is a type mismatch error.
|
||||
all_returns_conform_to_trait,
|
||||
|
@ -775,26 +776,23 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
if is_object_safe {
|
||||
// Suggest `-> Box<dyn Trait>` and `Box::new(returned_value)`.
|
||||
// Get all the return values and collect their span and suggestion.
|
||||
let mut suggestions = visitor
|
||||
if let Some(mut suggestions) = visitor
|
||||
.returns
|
||||
.iter()
|
||||
.map(|expr| {
|
||||
(
|
||||
expr.span,
|
||||
format!(
|
||||
"Box::new({})",
|
||||
self.tcx.sess.source_map().span_to_snippet(expr.span).unwrap()
|
||||
),
|
||||
)
|
||||
let snip = sm.span_to_snippet(expr.span).ok()?;
|
||||
Some((expr.span, format!("Box::new({})", snip)))
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
// Add the suggestion for the return type.
|
||||
suggestions.push((ret_ty.span, format!("Box<dyn {}>", trait_obj)));
|
||||
err.multipart_suggestion(
|
||||
"return a boxed trait object instead",
|
||||
suggestions,
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
.collect::<Option<Vec<_>>>()
|
||||
{
|
||||
// Add the suggestion for the return type.
|
||||
suggestions.push((ret_ty.span, format!("Box<dyn {}>", trait_obj)));
|
||||
err.multipart_suggestion(
|
||||
"return a boxed trait object instead",
|
||||
suggestions,
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
// This is currently not possible to trigger because E0038 takes precedence, but
|
||||
// leave it in for completeness in case anything changes in an earlier stage.
|
||||
|
|
|
@ -1010,7 +1010,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
|
|||
// type.
|
||||
//
|
||||
// NOTE: This should be kept in sync with the similar code in
|
||||
// `rustc_middle::ty::instance::resolve_associated_item()`.
|
||||
// `rustc_ty::instance::resolve_associated_item()`.
|
||||
let node_item =
|
||||
assoc_ty_def(selcx, impl_data.impl_def_id, obligation.predicate.item_def_id)
|
||||
.map_err(|ErrorReported| ())?;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
//! Provider for the `implied_outlives_bounds` query.
|
||||
//! Do not call this query directory. See [`rustc_middle::traits::query::implied_outlives_bounds`].
|
||||
//! Do not call this query directory. See
|
||||
//! [`rustc_trait_selection::traits::query::type_op::implied_outlives_bounds`].
|
||||
|
||||
use rustc_hir as hir;
|
||||
use rustc_infer::infer::canonical::{self, Canonical};
|
||||
|
|
|
@ -118,7 +118,7 @@ fn resolve_associated_item<'tcx>(
|
|||
// Since this is a trait item, we need to see if the item is either a trait default item
|
||||
// or a specialization because we can't resolve those unless we can `Reveal::All`.
|
||||
// NOTE: This should be kept in sync with the similar code in
|
||||
// `rustc_middle::traits::project::assemble_candidates_from_impls()`.
|
||||
// `rustc_trait_selection::traits::project::assemble_candidates_from_impls()`.
|
||||
let eligible = if leaf_def.is_final() {
|
||||
// Non-specializable items are always projectable.
|
||||
true
|
||||
|
|
|
@ -432,18 +432,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
body: &hir::Body<'_>,
|
||||
expected_sig: ExpectedSig<'tcx>,
|
||||
) -> ClosureSignatures<'tcx> {
|
||||
let expr_map_node = self.tcx.hir().get_if_local(expr_def_id).unwrap();
|
||||
let hir = self.tcx.hir();
|
||||
let expr_map_node = hir.get_if_local(expr_def_id).unwrap();
|
||||
let expected_args: Vec<_> = expected_sig
|
||||
.sig
|
||||
.inputs()
|
||||
.iter()
|
||||
.map(|ty| ArgKind::from_expected_ty(ty, None))
|
||||
.collect();
|
||||
let (closure_span, found_args) = self.get_fn_like_arguments(expr_map_node);
|
||||
let expected_span = expected_sig.cause_span.unwrap_or(closure_span);
|
||||
let (closure_span, found_args) = match self.get_fn_like_arguments(expr_map_node) {
|
||||
Some((sp, args)) => (Some(sp), args),
|
||||
None => (None, Vec::new()),
|
||||
};
|
||||
let expected_span =
|
||||
expected_sig.cause_span.unwrap_or_else(|| hir.span_if_local(expr_def_id).unwrap());
|
||||
self.report_arg_count_mismatch(
|
||||
expected_span,
|
||||
Some(closure_span),
|
||||
closure_span,
|
||||
expected_args,
|
||||
found_args,
|
||||
true,
|
||||
|
|
|
@ -481,7 +481,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
}
|
||||
|
||||
/// If one of the types is an uncalled function and calling it would yield the other type,
|
||||
/// suggest calling the function. Returns whether a suggestion was given.
|
||||
/// suggest calling the function. Returns `true` if suggestion would apply (even if not given).
|
||||
fn add_type_neq_err_label(
|
||||
&self,
|
||||
err: &mut rustc_errors::DiagnosticBuilder<'_>,
|
||||
|
@ -514,24 +514,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
.lookup_op_method(fn_sig.output(), &[other_ty], Op::Binary(op, is_assign))
|
||||
.is_ok()
|
||||
{
|
||||
let (variable_snippet, applicability) = if !fn_sig.inputs().is_empty() {
|
||||
(
|
||||
format!("{}( /* arguments */ )", source_map.span_to_snippet(span).unwrap()),
|
||||
Applicability::HasPlaceholders,
|
||||
)
|
||||
} else {
|
||||
(
|
||||
format!("{}()", source_map.span_to_snippet(span).unwrap()),
|
||||
Applicability::MaybeIncorrect,
|
||||
)
|
||||
};
|
||||
if let Ok(snippet) = source_map.span_to_snippet(span) {
|
||||
let (variable_snippet, applicability) = if !fn_sig.inputs().is_empty() {
|
||||
(format!("{}( /* arguments */ )", snippet), Applicability::HasPlaceholders)
|
||||
} else {
|
||||
(format!("{}()", snippet), Applicability::MaybeIncorrect)
|
||||
};
|
||||
|
||||
err.span_suggestion(
|
||||
span,
|
||||
"you might have forgotten to call this function",
|
||||
variable_snippet,
|
||||
applicability,
|
||||
);
|
||||
err.span_suggestion(
|
||||
span,
|
||||
"you might have forgotten to call this function",
|
||||
variable_snippet,
|
||||
applicability,
|
||||
);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,18 +8,6 @@ use rustc_errors::Handler;
|
|||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
macro_rules! try_something {
|
||||
($e:expr, $diag:expr, $out:expr) => {{
|
||||
match $e {
|
||||
Ok(c) => c,
|
||||
Err(e) => {
|
||||
$diag.struct_err(&e.to_string()).emit();
|
||||
return $out;
|
||||
}
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Eq)]
|
||||
pub struct CssPath {
|
||||
pub name: String,
|
||||
|
@ -265,7 +253,13 @@ pub fn test_theme_against<P: AsRef<Path>>(
|
|||
against: &CssPath,
|
||||
diag: &Handler,
|
||||
) -> (bool, Vec<String>) {
|
||||
let data = try_something!(fs::read(f), diag, (false, vec![]));
|
||||
let data = match fs::read(f) {
|
||||
Ok(c) => c,
|
||||
Err(e) => {
|
||||
diag.struct_err(&e.to_string()).emit();
|
||||
return (false, vec![]);
|
||||
}
|
||||
};
|
||||
|
||||
let paths = load_css_paths(&data);
|
||||
let mut ret = vec![];
|
||||
|
|
|
@ -289,10 +289,10 @@ pub fn rust_oom(layout: Layout) -> ! {
|
|||
pub mod __default_lib_allocator {
|
||||
use super::{GlobalAlloc, Layout, System};
|
||||
// These magic symbol names are used as a fallback for implementing the
|
||||
// `__rust_alloc` etc symbols (see `src/liballoc/alloc.rs) when there is
|
||||
// `__rust_alloc` etc symbols (see `src/liballoc/alloc.rs`) when there is
|
||||
// no `#[global_allocator]` attribute.
|
||||
|
||||
// for symbol names src/librustc_middle/middle/allocator.rs
|
||||
// for symbol names src/librustc_ast/expand/allocator.rs
|
||||
// for signatures src/librustc_allocator/lib.rs
|
||||
|
||||
// linkage directives are provided as part of the current compiler allocator
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
error: this arithmetic operation will overflow
|
||||
--> $DIR/issue-69020-assoc-const-arith-overflow.rs:29:22
|
||||
|
|
||||
LL | const NEG: i32 = -i32::MIN + T::NEG;
|
||||
| ^^^^^^^^^ attempt to negate with overflow
|
||||
|
|
||||
= note: `#[deny(arithmetic_overflow)]` on by default
|
||||
|
||||
error: this arithmetic operation will overflow
|
||||
--> $DIR/issue-69020-assoc-const-arith-overflow.rs:31:35
|
||||
|
|
||||
LL | const NEG_REV: i32 = T::NEG + (-i32::MIN);
|
||||
| ^^^^^^^^^^^ attempt to negate with overflow
|
||||
|
||||
error: this arithmetic operation will overflow
|
||||
--> $DIR/issue-69020-assoc-const-arith-overflow.rs:34:22
|
||||
|
|
||||
LL | const ADD: i32 = (i32::MAX+1) + T::ADD;
|
||||
| ^^^^^^^^^^^^ attempt to add with overflow
|
||||
|
||||
error: this arithmetic operation will overflow
|
||||
--> $DIR/issue-69020-assoc-const-arith-overflow.rs:36:36
|
||||
|
|
||||
LL | const ADD_REV: i32 = T::ADD + (i32::MAX+1);
|
||||
| ^^^^^^^^^^^^ attempt to add with overflow
|
||||
|
||||
error: this operation will panic at runtime
|
||||
--> $DIR/issue-69020-assoc-const-arith-overflow.rs:39:22
|
||||
|
|
||||
LL | const DIV: i32 = (1/0) + T::DIV;
|
||||
| ^^^^^ attempt to divide by zero
|
||||
|
|
||||
= note: `#[deny(unconditional_panic)]` on by default
|
||||
|
||||
error: this operation will panic at runtime
|
||||
--> $DIR/issue-69020-assoc-const-arith-overflow.rs:41:35
|
||||
|
|
||||
LL | const DIV_REV: i32 = T::DIV + (1/0);
|
||||
| ^^^^^ attempt to divide by zero
|
||||
|
||||
error: this operation will panic at runtime
|
||||
--> $DIR/issue-69020-assoc-const-arith-overflow.rs:44:22
|
||||
|
|
||||
LL | const OOB: i32 = [1][1] + T::OOB;
|
||||
| ^^^^^^ index out of bounds: the len is 1 but the index is 1
|
||||
|
||||
error: this operation will panic at runtime
|
||||
--> $DIR/issue-69020-assoc-const-arith-overflow.rs:46:35
|
||||
|
|
||||
LL | const OOB_REV: i32 = T::OOB + [1][1];
|
||||
| ^^^^^^ index out of bounds: the len is 1 but the index is 1
|
||||
|
||||
error: aborting due to 8 previous errors
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
error: this arithmetic operation will overflow
|
||||
--> $DIR/issue-69020-assoc-const-arith-overflow.rs:29:22
|
||||
|
|
||||
LL | const NEG: i32 = -i32::MIN + T::NEG;
|
||||
| ^^^^^^^^^ attempt to negate with overflow
|
||||
|
|
||||
= note: `#[deny(arithmetic_overflow)]` on by default
|
||||
|
||||
error: this arithmetic operation will overflow
|
||||
--> $DIR/issue-69020-assoc-const-arith-overflow.rs:31:35
|
||||
|
|
||||
LL | const NEG_REV: i32 = T::NEG + (-i32::MIN);
|
||||
| ^^^^^^^^^^^ attempt to negate with overflow
|
||||
|
||||
error: this arithmetic operation will overflow
|
||||
--> $DIR/issue-69020-assoc-const-arith-overflow.rs:34:22
|
||||
|
|
||||
LL | const ADD: i32 = (i32::MAX+1) + T::ADD;
|
||||
| ^^^^^^^^^^^^ attempt to add with overflow
|
||||
|
||||
error: this arithmetic operation will overflow
|
||||
--> $DIR/issue-69020-assoc-const-arith-overflow.rs:36:36
|
||||
|
|
||||
LL | const ADD_REV: i32 = T::ADD + (i32::MAX+1);
|
||||
| ^^^^^^^^^^^^ attempt to add with overflow
|
||||
|
||||
error: this operation will panic at runtime
|
||||
--> $DIR/issue-69020-assoc-const-arith-overflow.rs:39:22
|
||||
|
|
||||
LL | const DIV: i32 = (1/0) + T::DIV;
|
||||
| ^^^^^ attempt to divide by zero
|
||||
|
|
||||
= note: `#[deny(unconditional_panic)]` on by default
|
||||
|
||||
error: this operation will panic at runtime
|
||||
--> $DIR/issue-69020-assoc-const-arith-overflow.rs:41:35
|
||||
|
|
||||
LL | const DIV_REV: i32 = T::DIV + (1/0);
|
||||
| ^^^^^ attempt to divide by zero
|
||||
|
||||
error: this operation will panic at runtime
|
||||
--> $DIR/issue-69020-assoc-const-arith-overflow.rs:44:22
|
||||
|
|
||||
LL | const OOB: i32 = [1][1] + T::OOB;
|
||||
| ^^^^^^ index out of bounds: the len is 1 but the index is 1
|
||||
|
||||
error: this operation will panic at runtime
|
||||
--> $DIR/issue-69020-assoc-const-arith-overflow.rs:46:35
|
||||
|
|
||||
LL | const OOB_REV: i32 = T::OOB + [1][1];
|
||||
| ^^^^^^ index out of bounds: the len is 1 but the index is 1
|
||||
|
||||
error: aborting due to 8 previous errors
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
error: this arithmetic operation will overflow
|
||||
--> $DIR/issue-69020-assoc-const-arith-overflow.rs:29:22
|
||||
|
|
||||
LL | const NEG: i32 = -i32::MIN + T::NEG;
|
||||
| ^^^^^^^^^ attempt to negate with overflow
|
||||
|
|
||||
= note: `#[deny(arithmetic_overflow)]` on by default
|
||||
|
||||
error: this arithmetic operation will overflow
|
||||
--> $DIR/issue-69020-assoc-const-arith-overflow.rs:31:35
|
||||
|
|
||||
LL | const NEG_REV: i32 = T::NEG + (-i32::MIN);
|
||||
| ^^^^^^^^^^^ attempt to negate with overflow
|
||||
|
||||
error: this arithmetic operation will overflow
|
||||
--> $DIR/issue-69020-assoc-const-arith-overflow.rs:34:22
|
||||
|
|
||||
LL | const ADD: i32 = (i32::MAX+1) + T::ADD;
|
||||
| ^^^^^^^^^^^^ attempt to add with overflow
|
||||
|
||||
error: this arithmetic operation will overflow
|
||||
--> $DIR/issue-69020-assoc-const-arith-overflow.rs:36:36
|
||||
|
|
||||
LL | const ADD_REV: i32 = T::ADD + (i32::MAX+1);
|
||||
| ^^^^^^^^^^^^ attempt to add with overflow
|
||||
|
||||
error: this operation will panic at runtime
|
||||
--> $DIR/issue-69020-assoc-const-arith-overflow.rs:39:22
|
||||
|
|
||||
LL | const DIV: i32 = (1/0) + T::DIV;
|
||||
| ^^^^^ attempt to divide by zero
|
||||
|
|
||||
= note: `#[deny(unconditional_panic)]` on by default
|
||||
|
||||
error: this operation will panic at runtime
|
||||
--> $DIR/issue-69020-assoc-const-arith-overflow.rs:41:35
|
||||
|
|
||||
LL | const DIV_REV: i32 = T::DIV + (1/0);
|
||||
| ^^^^^ attempt to divide by zero
|
||||
|
||||
error: this operation will panic at runtime
|
||||
--> $DIR/issue-69020-assoc-const-arith-overflow.rs:44:22
|
||||
|
|
||||
LL | const OOB: i32 = [1][1] + T::OOB;
|
||||
| ^^^^^^ index out of bounds: the len is 1 but the index is 1
|
||||
|
||||
error: this operation will panic at runtime
|
||||
--> $DIR/issue-69020-assoc-const-arith-overflow.rs:46:35
|
||||
|
|
||||
LL | const OOB_REV: i32 = T::OOB + [1][1];
|
||||
| ^^^^^^ index out of bounds: the len is 1 but the index is 1
|
||||
|
||||
error: aborting due to 8 previous errors
|
||||
|
|
@ -9,21 +9,40 @@ use std::i32;
|
|||
|
||||
pub trait Foo {
|
||||
const NEG: i32;
|
||||
const NEG_REV: i32;
|
||||
|
||||
const ADD: i32;
|
||||
const ADD_REV: i32;
|
||||
|
||||
const DIV: i32;
|
||||
const DIV_REV: i32;
|
||||
|
||||
const OOB: i32;
|
||||
const OOB_REV: i32;
|
||||
}
|
||||
|
||||
// These constants cannot be evaluated already (they depend on `T::N`), so
|
||||
// they can just be linted like normal run-time code. But codegen works
|
||||
// a bit different in const context, so this test makes sure that we still catch overflow.
|
||||
// These constants cannot be evaluated already (they depend on `T::N`), so they can just be linted
|
||||
// like normal run-time code. But codegen works a bit different in const context, so this test
|
||||
// makes sure that we still catch overflow. Also make sure we emit the same lints if we reverse the
|
||||
// operands (so that the generic operand comes first).
|
||||
impl<T: Foo> Foo for Vec<T> {
|
||||
const NEG: i32 = -i32::MIN + T::NEG;
|
||||
//~^ ERROR arithmetic operation will overflow
|
||||
const NEG_REV: i32 = T::NEG + (-i32::MIN);
|
||||
//~^ ERROR arithmetic operation will overflow
|
||||
|
||||
const ADD: i32 = (i32::MAX+1) + T::ADD;
|
||||
//~^ ERROR arithmetic operation will overflow
|
||||
const ADD_REV: i32 = T::ADD + (i32::MAX+1);
|
||||
//~^ ERROR arithmetic operation will overflow
|
||||
|
||||
const DIV: i32 = (1/0) + T::DIV;
|
||||
//~^ ERROR operation will panic
|
||||
const DIV_REV: i32 = T::DIV + (1/0);
|
||||
//~^ ERROR operation will panic
|
||||
|
||||
const OOB: i32 = [1][1] + T::OOB;
|
||||
//~^ ERROR operation will panic
|
||||
const OOB_REV: i32 = T::OOB + [1][1];
|
||||
//~^ ERROR operation will panic
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
error: this arithmetic operation will overflow
|
||||
--> $DIR/issue-69020.rs:21:22
|
||||
|
|
||||
LL | const NEG: i32 = -i32::MIN + T::NEG;
|
||||
| ^^^^^^^^^ attempt to negate with overflow
|
||||
|
|
||||
= note: `#[deny(arithmetic_overflow)]` on by default
|
||||
|
||||
error: this arithmetic operation will overflow
|
||||
--> $DIR/issue-69020.rs:23:22
|
||||
|
|
||||
LL | const ADD: i32 = (i32::MAX+1) + T::ADD;
|
||||
| ^^^^^^^^^^^^ attempt to add with overflow
|
||||
|
||||
error: this operation will panic at runtime
|
||||
--> $DIR/issue-69020.rs:25:22
|
||||
|
|
||||
LL | const DIV: i32 = (1/0) + T::DIV;
|
||||
| ^^^^^ attempt to divide by zero
|
||||
|
|
||||
= note: `#[deny(unconditional_panic)]` on by default
|
||||
|
||||
error: this operation will panic at runtime
|
||||
--> $DIR/issue-69020.rs:27:22
|
||||
|
|
||||
LL | const OOB: i32 = [1][1] + T::OOB;
|
||||
| ^^^^^^ index out of bounds: the len is 1 but the index is 1
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
error: this arithmetic operation will overflow
|
||||
--> $DIR/issue-69020.rs:21:22
|
||||
|
|
||||
LL | const NEG: i32 = -i32::MIN + T::NEG;
|
||||
| ^^^^^^^^^ attempt to negate with overflow
|
||||
|
|
||||
= note: `#[deny(arithmetic_overflow)]` on by default
|
||||
|
||||
error: this arithmetic operation will overflow
|
||||
--> $DIR/issue-69020.rs:23:22
|
||||
|
|
||||
LL | const ADD: i32 = (i32::MAX+1) + T::ADD;
|
||||
| ^^^^^^^^^^^^ attempt to add with overflow
|
||||
|
||||
error: this operation will panic at runtime
|
||||
--> $DIR/issue-69020.rs:25:22
|
||||
|
|
||||
LL | const DIV: i32 = (1/0) + T::DIV;
|
||||
| ^^^^^ attempt to divide by zero
|
||||
|
|
||||
= note: `#[deny(unconditional_panic)]` on by default
|
||||
|
||||
error: this operation will panic at runtime
|
||||
--> $DIR/issue-69020.rs:27:22
|
||||
|
|
||||
LL | const OOB: i32 = [1][1] + T::OOB;
|
||||
| ^^^^^^ index out of bounds: the len is 1 but the index is 1
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
error: this arithmetic operation will overflow
|
||||
--> $DIR/issue-69020.rs:21:22
|
||||
|
|
||||
LL | const NEG: i32 = -i32::MIN + T::NEG;
|
||||
| ^^^^^^^^^ attempt to negate with overflow
|
||||
|
|
||||
= note: `#[deny(arithmetic_overflow)]` on by default
|
||||
|
||||
error: this arithmetic operation will overflow
|
||||
--> $DIR/issue-69020.rs:23:22
|
||||
|
|
||||
LL | const ADD: i32 = (i32::MAX+1) + T::ADD;
|
||||
| ^^^^^^^^^^^^ attempt to add with overflow
|
||||
|
||||
error: this operation will panic at runtime
|
||||
--> $DIR/issue-69020.rs:25:22
|
||||
|
|
||||
LL | const DIV: i32 = (1/0) + T::DIV;
|
||||
| ^^^^^ attempt to divide by zero
|
||||
|
|
||||
= note: `#[deny(unconditional_panic)]` on by default
|
||||
|
||||
error: this operation will panic at runtime
|
||||
--> $DIR/issue-69020.rs:27:22
|
||||
|
|
||||
LL | const OOB: i32 = [1][1] + T::OOB;
|
||||
| ^^^^^^ index out of bounds: the len is 1 but the index is 1
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
fn a() -> i32 {
|
||||
3
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
assert_eq!(a, 0);
|
||||
//~^ ERROR binary operation `==` cannot
|
||||
//~| ERROR mismatched types
|
||||
//~| ERROR doesn't implement
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
error[E0369]: binary operation `==` cannot be applied to type `fn() -> i32 {a}`
|
||||
--> $DIR/issue-70724-add_type_neq_err_label-unwrap.rs:6:5
|
||||
|
|
||||
LL | assert_eq!(a, 0);
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
| |
|
||||
| fn() -> i32 {a}
|
||||
| {integer}
|
||||
| help: you might have forgotten to call this function: `*left_val()`
|
||||
|
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-70724-add_type_neq_err_label-unwrap.rs:6:5
|
||||
|
|
||||
LL | assert_eq!(a, 0);
|
||||
| ^^^^^^^^^^^^^^^^^ expected fn item, found integer
|
||||
|
|
||||
= note: expected fn item `fn() -> i32 {a}`
|
||||
found type `i32`
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0277]: `fn() -> i32 {a}` doesn't implement `std::fmt::Debug`
|
||||
--> $DIR/issue-70724-add_type_neq_err_label-unwrap.rs:6:5
|
||||
|
|
||||
LL | fn a() -> i32 {
|
||||
| - consider calling this function
|
||||
...
|
||||
LL | assert_eq!(a, 0);
|
||||
| ^^^^^^^^^^^^^^^^^ `fn() -> i32 {a}` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug`
|
||||
|
|
||||
= help: the trait `std::fmt::Debug` is not implemented for `fn() -> i32 {a}`
|
||||
= help: use parentheses to call the function: `a()`
|
||||
= note: required because of the requirements on the impl of `std::fmt::Debug` for `&fn() -> i32 {a}`
|
||||
= note: required by `std::fmt::Debug::fmt`
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0277, E0308, E0369.
|
||||
For more information about an error, try `rustc --explain E0277`.
|
Loading…
Reference in New Issue