Skip to content

Rollup of 7 pull requests #104974

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 19 commits into from
Closed
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
c256bd2
Remove redundant `all` in cfg
ChrisDenton Nov 26, 2022
2ab3f76
Remove more redundant `all`s
ChrisDenton Nov 26, 2022
e06b61c
explain how to get the discriminant out of a `#[repr(T)] enum`
Nov 25, 2022
4b2a1eb
Support unit tests for jsondoclint
aDotInTheVoid Nov 26, 2022
946d51e
fix broken link fragment
Nov 26, 2022
09818a8
Add a test that makes sense
aDotInTheVoid Nov 26, 2022
74de78a
rustdoc: improve popover focus handling JS
notriddle Nov 26, 2022
c96d888
Pretty-print generators with their `generator_kind`
Swatinem Nov 25, 2022
c26074a
rustdoc: pass "true" to reset focus for notable traits
notriddle Nov 26, 2022
2343353
Avoid ICE if the Clone trait is not found while building error sugges…
mucinoab Nov 26, 2022
353cef9
Use target exe_suffix for doctests
workingjubilee Apr 9, 2022
47ddca6
Attempt to solve problem with globs
workingjubilee Nov 27, 2022
c3bbceb
Rollup merge of #95836 - workingjubilee:doctest-exe, r=notriddle
matthiaskrgr Nov 27, 2022
ed55eab
Rollup merge of #104892 - lukas-code:discriminant, r=scottmcm
matthiaskrgr Nov 27, 2022
8c87202
Rollup merge of #104931 - Swatinem:async-pretty, r=eholk
matthiaskrgr Nov 27, 2022
a5eeb3b
Rollup merge of #104934 - ChrisDenton:all-anybody-wants, r=thomcc
matthiaskrgr Nov 27, 2022
2466992
Rollup merge of #104944 - aDotInTheVoid:jsondoclint-unit-tests, r=jyn514
matthiaskrgr Nov 27, 2022
34d73ea
Rollup merge of #104946 - notriddle:notriddle/popover-menu-focus, r=G…
matthiaskrgr Nov 27, 2022
4990ab8
Rollup merge of #104956 - mucinoab:issue-104870, r=compiler-errors
matthiaskrgr Nov 27, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 9 additions & 7 deletions compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
Original file line number Diff line number Diff line change
@@ -732,13 +732,15 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
let tcx = self.infcx.tcx;
// Try to find predicates on *generic params* that would allow copying `ty`
let infcx = tcx.infer_ctxt().build();
if infcx
.type_implements_trait(
tcx.lang_items().clone_trait().unwrap(),
[tcx.erase_regions(ty)],
self.param_env,
)
.must_apply_modulo_regions()

if let Some(clone_trait_def) = tcx.lang_items().clone_trait()
&& infcx
.type_implements_trait(
clone_trait_def,
[tcx.erase_regions(ty)],
self.param_env,
)
.must_apply_modulo_regions()
{
err.span_suggestion_verbose(
span.shrink_to_hi(),
8 changes: 4 additions & 4 deletions compiler/rustc_codegen_gcc/example/alloc_system.rs
Original file line number Diff line number Diff line change
@@ -13,17 +13,17 @@

// The minimum alignment guaranteed by the architecture. This value is used to
// add fast paths for low alignment values.
#[cfg(all(any(target_arch = "x86",
#[cfg(any(target_arch = "x86",
target_arch = "arm",
target_arch = "mips",
target_arch = "powerpc",
target_arch = "powerpc64")))]
target_arch = "powerpc64"))]
const MIN_ALIGN: usize = 8;
#[cfg(all(any(target_arch = "x86_64",
#[cfg(any(target_arch = "x86_64",
target_arch = "aarch64",
target_arch = "mips64",
target_arch = "s390x",
target_arch = "sparc64")))]
target_arch = "sparc64"))]
const MIN_ALIGN: usize = 16;

pub struct System;
Original file line number Diff line number Diff line change
@@ -376,7 +376,7 @@ impl<'tcx> NonConstOp<'tcx> for Generator {
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
let msg = format!("{}s are not allowed in {}s", self.0, ccx.const_kind());
let msg = format!("{}s are not allowed in {}s", self.0.descr(), ccx.const_kind());
if let hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Block) = self.0 {
ccx.tcx.sess.create_feature_err(
UnallowedOpInConstContext { span, msg },
6 changes: 3 additions & 3 deletions compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
@@ -1514,9 +1514,9 @@ pub enum AsyncGeneratorKind {
impl fmt::Display for AsyncGeneratorKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(match self {
AsyncGeneratorKind::Block => "`async` block",
AsyncGeneratorKind::Closure => "`async` closure body",
AsyncGeneratorKind::Fn => "`async fn` body",
AsyncGeneratorKind::Block => "async block",
AsyncGeneratorKind::Closure => "async closure body",
AsyncGeneratorKind::Fn => "async fn body",
})
}
}
3 changes: 2 additions & 1 deletion compiler/rustc_hir_typeck/src/generator_interior/mod.rs
Original file line number Diff line number Diff line change
@@ -118,7 +118,8 @@ impl<'a, 'tcx> InteriorVisitor<'a, 'tcx> {
} else {
let note = format!(
"the type is part of the {} because of this {}",
self.kind, yield_data.source
self.kind.descr(),
yield_data.source
);

self.fcx
25 changes: 10 additions & 15 deletions compiler/rustc_middle/src/ty/print/pretty.rs
Original file line number Diff line number Diff line change
@@ -681,25 +681,20 @@ pub trait PrettyPrinter<'tcx>:
}
ty::Str => p!("str"),
ty::Generator(did, substs, movability) => {
// FIXME(swatinem): async constructs used to be pretty printed
// as `impl Future` previously due to the `from_generator` wrapping.
// lets special case this here for now to avoid churn in diagnostics.
let generator_kind = self.tcx().generator_kind(did);
if matches!(generator_kind, Some(hir::GeneratorKind::Async(..))) {
let return_ty = substs.as_generator().return_ty();
p!(write("impl Future<Output = {}>", return_ty));

return Ok(self);
}

p!(write("["));
match movability {
hir::Movability::Movable => {}
hir::Movability::Static => p!("static "),
let generator_kind = self.tcx().generator_kind(did).unwrap();
let should_print_movability =
self.should_print_verbose() || generator_kind == hir::GeneratorKind::Gen;

if should_print_movability {
match movability {
hir::Movability::Movable => {}
hir::Movability::Static => p!("static "),
}
}

if !self.should_print_verbose() {
p!("generator");
p!(write("{}", generator_kind));
// FIXME(eddyb) should use `def_span`.
if let Some(did) = did.as_local() {
let span = self.tcx().def_span(did);
2 changes: 1 addition & 1 deletion compiler/rustc_span/src/analyze_source_file.rs
Original file line number Diff line number Diff line change
@@ -41,7 +41,7 @@ pub fn analyze_source_file(
}

cfg_if::cfg_if! {
if #[cfg(all(any(target_arch = "x86", target_arch = "x86_64")))] {
if #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] {
fn analyze_source_file_dispatch(src: &str,
source_file_start_pos: BytePos,
lines: &mut Vec<BytePos>,
Original file line number Diff line number Diff line change
@@ -2673,7 +2673,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
let sp = self.tcx.def_span(def_id);

// Special-case this to say "async block" instead of `[static generator]`.
let kind = tcx.generator_kind(def_id).unwrap();
let kind = tcx.generator_kind(def_id).unwrap().descr();
err.span_note(
sp,
&format!("required because it's used within this {}", kind),
61 changes: 60 additions & 1 deletion library/core/src/mem/mod.rs
Original file line number Diff line number Diff line change
@@ -1113,7 +1113,10 @@ impl<T> fmt::Debug for Discriminant<T> {
/// # Stability
///
/// The discriminant of an enum variant may change if the enum definition changes. A discriminant
/// of some variant will not change between compilations with the same compiler.
/// of some variant will not change between compilations with the same compiler. See the [Reference]
/// for more information.
///
/// [Reference]: ../../reference/items/enumerations.html#custom-discriminant-values-for-fieldless-enumerations
///
/// # Examples
///
@@ -1129,6 +1132,62 @@ impl<T> fmt::Debug for Discriminant<T> {
/// assert_eq!(mem::discriminant(&Foo::B(1)), mem::discriminant(&Foo::B(2)));
/// assert_ne!(mem::discriminant(&Foo::B(3)), mem::discriminant(&Foo::C(3)));
/// ```
///
/// ## Accessing the numeric value of the discriminant
///
/// Note that it is *undefined behavior* to [`transmute`] from [`Discriminant`] to a primitive!
///
/// If an enum has only unit variants, then the numeric value of the discriminant can be accessed
/// with an [`as`] cast:
///
/// ```
/// enum Enum {
/// Foo,
/// Bar,
/// Baz,
/// }
///
/// assert_eq!(0, Enum::Foo as isize);
/// assert_eq!(1, Enum::Bar as isize);
/// assert_eq!(2, Enum::Baz as isize);
/// ```
///
/// If an enum has opted-in to having a [primitive representation] for its discriminant,
/// then it's possible to use pointers to read the memory location storing the discriminant.
/// That **cannot** be done for enums using the [default representation], however, as it's
/// undefined what layout the discriminant has and where it's stored — it might not even be
/// stored at all!
///
/// [`as`]: ../../std/keyword.as.html
/// [primitive representation]: ../../reference/type-layout.html#primitive-representations
/// [default representation]: ../../reference/type-layout.html#the-default-representation
/// ```
/// #[repr(u8)]
/// enum Enum {
/// Unit,
/// Tuple(bool),
/// Struct { a: bool },
/// }
///
/// impl Enum {
/// fn discriminant(&self) -> u8 {
/// // SAFETY: Because `Self` is marked `repr(u8)`, its layout is a `repr(C)` `union`
/// // between `repr(C)` structs, each of which has the `u8` discriminant as its first
/// // field, so we can read the discriminant without offsetting the pointer.
/// unsafe { *<*const _>::from(self).cast::<u8>() }
/// }
/// }
///
/// let unit_like = Enum::Unit;
/// let tuple_like = Enum::Tuple(true);
/// let struct_like = Enum::Struct { a: false };
/// assert_eq!(0, unit_like.discriminant());
/// assert_eq!(1, tuple_like.discriminant());
/// assert_eq!(2, struct_like.discriminant());
///
/// // ⚠️ This is undefined behavior. Don't do this. ⚠️
/// // assert_eq!(0, unsafe { std::mem::transmute::<_, u8>(std::mem::discriminant(&unit_like)) });
/// ```
#[stable(feature = "discriminant_value", since = "1.21.0")]
#[rustc_const_unstable(feature = "const_discriminant", issue = "69821")]
#[cfg_attr(not(test), rustc_diagnostic_item = "mem_discriminant")]
12 changes: 6 additions & 6 deletions library/std/src/sys/common/alloc.rs
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@ use crate::ptr;

// The minimum alignment guaranteed by the architecture. This value is used to
// add fast paths for low alignment values.
#[cfg(all(any(
#[cfg(any(
target_arch = "x86",
target_arch = "arm",
target_arch = "mips",
@@ -16,23 +16,23 @@ use crate::ptr;
target_arch = "hexagon",
all(target_arch = "riscv32", not(target_os = "espidf")),
all(target_arch = "xtensa", not(target_os = "espidf")),
)))]
))]
pub const MIN_ALIGN: usize = 8;
#[cfg(all(any(
#[cfg(any(
target_arch = "x86_64",
target_arch = "aarch64",
target_arch = "mips64",
target_arch = "s390x",
target_arch = "sparc64",
target_arch = "riscv64",
target_arch = "wasm64",
)))]
))]
pub const MIN_ALIGN: usize = 16;
// The allocator on the esp-idf platform guarantees 4 byte alignment.
#[cfg(all(any(
#[cfg(any(
all(target_arch = "riscv32", target_os = "espidf"),
all(target_arch = "xtensa", target_os = "espidf"),
)))]
))]
pub const MIN_ALIGN: usize = 4;

pub unsafe fn realloc_fallback(
1 change: 1 addition & 0 deletions src/bootstrap/builder.rs
Original file line number Diff line number Diff line change
@@ -644,6 +644,7 @@ impl<'a> Builder<'a> {
test::CrateLibrustc,
test::CrateRustdoc,
test::CrateRustdocJsonTypes,
test::CrateJsonDocLint,
test::Linkcheck,
test::TierCheck,
test::ReplacePlaceholderTest,
36 changes: 36 additions & 0 deletions src/bootstrap/test.rs
Original file line number Diff line number Diff line change
@@ -90,6 +90,42 @@ fn try_run_quiet(builder: &Builder<'_>, cmd: &mut Command) -> bool {
true
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct CrateJsonDocLint {
host: TargetSelection,
}

impl Step for CrateJsonDocLint {
type Output = ();
const ONLY_HOSTS: bool = true;
const DEFAULT: bool = true;

fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
run.path("src/tools/jsondoclint")
}

fn make_run(run: RunConfig<'_>) {
run.builder.ensure(CrateJsonDocLint { host: run.target });
}

fn run(self, builder: &Builder<'_>) {
let bootstrap_host = builder.config.build;
let compiler = builder.compiler(0, bootstrap_host);

let cargo = tool::prepare_tool_cargo(
builder,
compiler,
Mode::ToolBootstrap,
bootstrap_host,
"test",
"src/tools/jsondoclint",
SourceType::InTree,
&[],
);
try_run(builder, &mut cargo.into());
}
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct Linkcheck {
host: TargetSelection,
16 changes: 14 additions & 2 deletions src/librustdoc/doctest.rs
Original file line number Diff line number Diff line change
@@ -19,7 +19,7 @@ use rustc_span::edition::Edition;
use rustc_span::source_map::SourceMap;
use rustc_span::symbol::sym;
use rustc_span::{BytePos, FileName, Pos, Span, DUMMY_SP};
use rustc_target::spec::TargetTriple;
use rustc_target::spec::{Target, TargetTriple};
use tempfile::Builder as TempFileBuilder;

use std::env;
@@ -293,6 +293,16 @@ struct UnusedExterns {
unused_extern_names: Vec<String>,
}

fn add_exe_suffix(input: String, target: &TargetTriple) -> String {
let exe_suffix = match target {
TargetTriple::TargetTriple(_) => Target::expect_builtin(target).options.exe_suffix,
TargetTriple::TargetJson { contents, .. } => {
Target::from_json(contents.parse().unwrap()).unwrap().0.options.exe_suffix
}
};
input + &exe_suffix
}

fn run_test(
test: &str,
crate_name: &str,
@@ -313,7 +323,9 @@ fn run_test(
let (test, line_offset, supports_color) =
make_test(test, Some(crate_name), lang_string.test_harness, opts, edition, Some(test_id));

let output_file = outdir.path().join("rust_out");
// Make sure we emit well-formed executable names for our target.
let rust_out = add_exe_suffix("rust_out".to_owned(), &target);
let output_file = outdir.path().join(rust_out);

let rustc_binary = rustdoc_options
.test_builder
20 changes: 16 additions & 4 deletions src/librustdoc/html/static/js/main.js
Original file line number Diff line number Diff line change
@@ -202,6 +202,7 @@ function loadCss(cssUrl) {
if (event.ctrlKey || event.altKey || event.metaKey) {
return;
}
window.hideAllModals(false);
addClass(getSettingsButton(), "rotate");
event.preventDefault();
// Sending request for the CSS and the JS files at the same time so it will
@@ -377,7 +378,7 @@ function loadCss(cssUrl) {
}
ev.preventDefault();
searchState.defocus();
window.hidePopoverMenus();
window.hideAllModals(true); // true = reset focus for notable traits
}

function handleShortcut(ev) {
@@ -767,6 +768,7 @@ function loadCss(cssUrl) {
};

function showSidebar() {
window.hideAllModals(false);
window.rustdocMobileScrollLock();
const sidebar = document.getElementsByClassName("sidebar")[0];
addClass(sidebar, "shown");
@@ -843,7 +845,7 @@ function loadCss(cssUrl) {
// Make this function idempotent.
return;
}
hideNotable(false);
window.hideAllModals(false);
const ty = e.getAttribute("data-ty");
const wrapper = document.createElement("div");
wrapper.innerHTML = "<div class=\"docblock\">" + window.NOTABLE_TRAITS[ty] + "</div>";
@@ -1049,14 +1051,24 @@ function loadCss(cssUrl) {
return container;
}

/**
* Hide popover menus, notable trait tooltips, and the sidebar (if applicable).
*
* Pass "true" to reset focus for notable traits.
*/
window.hideAllModals = function(switchFocus) {
hideSidebar();
window.hidePopoverMenus();
hideNotable(switchFocus);
};

/**
* Hide all the popover menus.
*/
window.hidePopoverMenus = function() {
onEachLazy(document.querySelectorAll(".search-form .popover"), elem => {
elem.style.display = "none";
});
hideNotable(false);
};

/**
@@ -1081,7 +1093,7 @@ function loadCss(cssUrl) {
function showHelp() {
const menu = getHelpMenu(true);
if (menu.style.display === "none") {
window.hidePopoverMenus();
window.hideAllModals();
menu.style.display = "";
}
}
2 changes: 1 addition & 1 deletion src/librustdoc/html/static/js/settings.js
Original file line number Diff line number Diff line change
@@ -268,7 +268,7 @@
event.preventDefault();
const shouldDisplaySettings = settingsMenu.style.display === "none";

window.hidePopoverMenus();
window.hideAllModals();
if (shouldDisplaySettings) {
displaySettings();
}
2 changes: 1 addition & 1 deletion src/test/run-make/coverage-reports/Makefile
Original file line number Diff line number Diff line change
@@ -132,7 +132,7 @@ include clear_expected_if_blessed
--instr-profile="$(TMPDIR)"/$@.profdata \
$(call BIN,"$(TMPDIR)"/$@) \
$$( \
for file in $(TMPDIR)/rustdoc-$@/*/rust_out; do \
for file in $(TMPDIR)/rustdoc-$@/*/rust_out*; do \
[ -x "$$file" ] && printf "%s %s " -object $$file; \
done \
) \
25 changes: 25 additions & 0 deletions src/test/rustdoc-gui/notable-trait.goml
Original file line number Diff line number Diff line change
@@ -200,12 +200,14 @@ move-cursor-to: "//*[@class='notable popover']"
assert-count: ("//*[@class='notable popover']", 1)
press-key: "Escape"
assert-count: ("//*[@class='notable popover']", 0)
assert: "#method\.create_an_iterator_from_read .notable-traits:focus"

// Check that clicking outside works.
click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']"
assert-count: ("//*[@class='notable popover']", 1)
click: ".search-input"
assert-count: ("//*[@class='notable popover']", 0)
assert-false: "#method\.create_an_iterator_from_read .notable-traits:focus"

// Check that pressing tab over and over works.
click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']"
@@ -249,3 +251,26 @@ click: "#settings-menu a"
press-key: "Escape"
// We ensure we didn't come back to the previous focused item.
assert-window-property-false: {"scrollY": |scroll|}

// Opening the mobile sidebar should close the popover.
size: (650, 600)
click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']"
assert-count: ("//*[@class='notable popover']", 1)
click: ".sidebar-menu-toggle"
assert: "//*[@class='sidebar shown']"
assert-count: ("//*[@class='notable popover']", 0)
assert-false: "#method\.create_an_iterator_from_read .notable-traits:focus"
// Clicking a notable popover should close the sidebar.
click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']"
assert-count: ("//*[@class='notable popover']", 1)
assert-false: "//*[@class='sidebar shown']"

// Also check the focus handling for the help button.
size: (1100, 600)
reload:
assert-count: ("//*[@class='notable popover']", 0)
click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']"
assert-count: ("//*[@class='notable popover']", 1)
click: "#help-button a"
assert-count: ("//*[@class='notable popover']", 0)
assert-false: "#method\.create_an_iterator_from_read .notable-traits:focus"
21 changes: 21 additions & 0 deletions src/test/rustdoc-gui/pocket-menu.goml
Original file line number Diff line number Diff line change
@@ -75,3 +75,24 @@ assert-css: (
)
compare-elements-css: ("#help-button .popover", "#help-button .top", ["border-color"])
compare-elements-css: ("#help-button .popover", "#help-button .bottom", ["border-color"])

// Opening the mobile sidebar should close the settings popover.
size: (650, 600)
click: "#settings-menu a"
assert-css: ("#settings-menu .popover", {"display": "block"})
click: ".sidebar-menu-toggle"
assert: "//*[@class='sidebar shown']"
assert-css: ("#settings-menu .popover", {"display": "none"})
// Opening the settings popover should close the sidebar.
click: "#settings-menu a"
assert-css: ("#settings-menu .popover", {"display": "block"})
assert-false: "//*[@class='sidebar shown']"

// Opening the settings popover at start (which async loads stuff) should also close.
reload:
click: ".sidebar-menu-toggle"
assert: "//*[@class='sidebar shown']"
assert-false: "#settings-menu .popover"
click: "#settings-menu a"
assert-false: "//*[@class='sidebar shown']"
wait-for: "#settings-menu .popover"
6 changes: 6 additions & 0 deletions src/test/rustdoc-gui/sidebar-mobile.goml
Original file line number Diff line number Diff line change
@@ -32,6 +32,12 @@ assert-css: ("//nav[contains(@class, 'sidebar')]//h2/a[text()='In test_docs']/pa
click: "body"
assert-css: (".sidebar", {"display": "block", "left": "-1000px"})

// Open the sidebar menu, and make sure pressing Escape closes it.
click: ".sidebar-menu-toggle"
assert-css: (".sidebar", {"left": "0px"})
press-key: "Escape"
assert-css: (".sidebar", {"display": "block", "left": "-1000px"})

// Check that the topbar is visible
assert-property: (".mobile-topbar", {"clientHeight": "45"})

Original file line number Diff line number Diff line change
@@ -15,7 +15,7 @@ fn return_targets_async_block_not_fn() -> u8 {
return 0u8;
};
let _: &dyn Future<Output = ()> = &block;
//~^ ERROR expected `impl Future<Output = u8>` to be a future that resolves to `()`, but it resolves to `u8`
//~^ ERROR to be a future that resolves to `()`, but it resolves to `u8`
}

async fn return_targets_async_block_not_async_fn() -> u8 {
@@ -24,7 +24,7 @@ async fn return_targets_async_block_not_async_fn() -> u8 {
return 0u8;
};
let _: &dyn Future<Output = ()> = &block;
//~^ ERROR expected `impl Future<Output = u8>` to be a future that resolves to `()`, but it resolves to `u8`
//~^ ERROR to be a future that resolves to `()`, but it resolves to `u8`
}

fn no_break_in_async_block() {
Original file line number Diff line number Diff line change
@@ -29,13 +29,13 @@ LL | |
LL | | }
| |_^ expected `u8`, found `()`

error[E0271]: expected `impl Future<Output = u8>` to be a future that resolves to `()`, but it resolves to `u8`
error[E0271]: expected `[async block@$DIR/async-block-control-flow-static-semantics.rs:23:17: 25:6]` to be a future that resolves to `()`, but it resolves to `u8`
--> $DIR/async-block-control-flow-static-semantics.rs:26:39
|
LL | let _: &dyn Future<Output = ()> = &block;
| ^^^^^^ expected `()`, found `u8`
|
= note: required for the cast from `impl Future<Output = u8>` to the object type `dyn Future<Output = ()>`
= note: required for the cast from `[async block@$DIR/async-block-control-flow-static-semantics.rs:23:17: 25:6]` to the object type `dyn Future<Output = ()>`

error[E0308]: mismatched types
--> $DIR/async-block-control-flow-static-semantics.rs:12:43
@@ -45,13 +45,13 @@ LL | fn return_targets_async_block_not_fn() -> u8 {
| |
| implicitly returns `()` as its body has no tail or `return` expression

error[E0271]: expected `impl Future<Output = u8>` to be a future that resolves to `()`, but it resolves to `u8`
error[E0271]: expected `[async block@$DIR/async-block-control-flow-static-semantics.rs:14:17: 16:6]` to be a future that resolves to `()`, but it resolves to `u8`
--> $DIR/async-block-control-flow-static-semantics.rs:17:39
|
LL | let _: &dyn Future<Output = ()> = &block;
| ^^^^^^ expected `()`, found `u8`
|
= note: required for the cast from `impl Future<Output = u8>` to the object type `dyn Future<Output = ()>`
= note: required for the cast from `[async block@$DIR/async-block-control-flow-static-semantics.rs:14:17: 16:6]` to the object type `dyn Future<Output = ()>`

error[E0308]: mismatched types
--> $DIR/async-block-control-flow-static-semantics.rs:49:44
8 changes: 4 additions & 4 deletions src/test/ui/async-await/generator-desc.stderr
Original file line number Diff line number Diff line change
@@ -8,8 +8,8 @@ LL | fun(async {}, async {});
| | arguments to this function are incorrect
| the expected `async` block
|
= note: expected `async` block `impl Future<Output = ()>` (`async` block)
found `async` block `impl Future<Output = ()>` (`async` block)
= note: expected `async` block `[async block@$DIR/generator-desc.rs:10:9: 10:17]`
found `async` block `[async block@$DIR/generator-desc.rs:10:19: 10:27]`
note: function defined here
--> $SRC_DIR/core/src/future/mod.rs:LL:COL
|
@@ -53,8 +53,8 @@ LL | fun((async || {})(), (async || {})());
| | the expected `async` closure body
| arguments to this function are incorrect
|
= note: expected `async` closure body `impl Future<Output = ()>` (`async` closure body)
found `async` closure body `impl Future<Output = ()>` (`async` closure body)
= note: expected `async` closure body `[async closure body@$DIR/generator-desc.rs:14:19: 14:21]`
found `async` closure body `[async closure body@$DIR/generator-desc.rs:14:36: 14:38]`
note: function defined here
--> $DIR/generator-desc.rs:8:4
|
2 changes: 1 addition & 1 deletion src/test/ui/async-await/issue-67252-unnamed-future.stderr
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@ LL | | AFuture.await;
LL | | });
| |_____^ future created by async block is not `Send`
|
= help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `*mut ()`
= help: within `[async block@$DIR/issue-67252-unnamed-future.rs:18:11: 21:6]`, the trait `Send` is not implemented for `*mut ()`
note: future is not `Send` as this value is used across an await
--> $DIR/issue-67252-unnamed-future.rs:20:16
|
2 changes: 1 addition & 1 deletion src/test/ui/async-await/issue-86507.stderr
Original file line number Diff line number Diff line change
@@ -13,7 +13,7 @@ note: captured value is not `Send` because `&` references cannot be sent unless
|
LL | let x = x;
| ^ has type `&T` which is not `Send`, because `T` is not `Sync`
= note: required for the cast from `impl Future<Output = ()>` to the object type `dyn Future<Output = ()> + Send`
= note: required for the cast from `[async block@$DIR/issue-86507.rs:18:17: 20:18]` to the object type `dyn Future<Output = ()> + Send`
help: consider further restricting this bound
|
LL | fn bar<'me, 'async_trait, T: Send + std::marker::Sync>(x: &'me T)
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@ LL | | bar(Foo(std::ptr::null())).await;
LL | | })
| |_____^ future created by async block is not `Send`
|
= help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `*const u8`
= help: within `[async block@$DIR/issue-65436-raw-ptr-not-send.rs:16:17: 19:6]`, the trait `Send` is not implemented for `*const u8`
note: future is not `Send` as this value is used across an await
--> $DIR/issue-65436-raw-ptr-not-send.rs:18:35
|
22 changes: 11 additions & 11 deletions src/test/ui/chalkify/bugs/async.stderr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error[E0277]: `impl Future<Output = u32>` is not a future
error[E0277]: `[async fn body@$DIR/async.rs:7:29: 9:2]` is not a future
--> $DIR/async.rs:7:29
|
LL | async fn foo(x: u32) -> u32 {
@@ -7,18 +7,18 @@ LL | | x
LL | | }
| | ^
| | |
| |_`impl Future<Output = u32>` is not a future
| |_`[async fn body@$DIR/async.rs:7:29: 9:2]` is not a future
| required by a bound introduced by this call
|
= help: the trait `Future` is not implemented for `impl Future<Output = u32>`
= note: impl Future<Output = u32> must be a future or must implement `IntoFuture` to be awaited
= help: the trait `Future` is not implemented for `[async fn body@$DIR/async.rs:7:29: 9:2]`
= note: [async fn body@$DIR/async.rs:7:29: 9:2] must be a future or must implement `IntoFuture` to be awaited
note: required by a bound in `identity_future`
--> $SRC_DIR/core/src/future/mod.rs:LL:COL
|
LL | pub const fn identity_future<O, Fut: Future<Output = O>>(f: Fut) -> Fut {
| ^^^^^^^^^^^^^^^^^^ required by this bound in `identity_future`

error[E0277]: the size for values of type `<impl Future<Output = u32> as Future>::Output` cannot be known at compilation time
error[E0277]: the size for values of type `<[async fn body@$DIR/async.rs:7:29: 9:2] as Future>::Output` cannot be known at compilation time
--> $DIR/async.rs:7:29
|
LL | async fn foo(x: u32) -> u32 {
@@ -27,23 +27,23 @@ LL | | x
LL | | }
| |_^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `<impl Future<Output = u32> as Future>::Output`
= help: the trait `Sized` is not implemented for `<[async fn body@$DIR/async.rs:7:29: 9:2] as Future>::Output`
note: required by a bound in `identity_future`
--> $SRC_DIR/core/src/future/mod.rs:LL:COL
|
LL | pub const fn identity_future<O, Fut: Future<Output = O>>(f: Fut) -> Fut {
| ^ required by this bound in `identity_future`

error[E0277]: `impl Future<Output = u32>` is not a future
error[E0277]: `[async fn body@$DIR/async.rs:7:29: 9:2]` is not a future
--> $DIR/async.rs:7:25
|
LL | async fn foo(x: u32) -> u32 {
| ^^^ `impl Future<Output = u32>` is not a future
| ^^^ `[async fn body@$DIR/async.rs:7:29: 9:2]` is not a future
|
= help: the trait `Future` is not implemented for `impl Future<Output = u32>`
= note: impl Future<Output = u32> must be a future or must implement `IntoFuture` to be awaited
= help: the trait `Future` is not implemented for `[async fn body@$DIR/async.rs:7:29: 9:2]`
= note: [async fn body@$DIR/async.rs:7:29: 9:2] must be a future or must implement `IntoFuture` to be awaited

error[E0280]: the requirement `<impl Future<Output = u32> as Future>::Output == u32` is not satisfied
error[E0280]: the requirement `<[async fn body@$DIR/async.rs:7:29: 9:2] as Future>::Output == u32` is not satisfied
--> $DIR/async.rs:7:25
|
LL | async fn foo(x: u32) -> u32 {
27 changes: 13 additions & 14 deletions src/test/ui/generator/clone-impl-async.rs
Original file line number Diff line number Diff line change
@@ -15,42 +15,42 @@ fn main() {
drop(non_clone);
};
check_copy(&inner_non_clone);
//~^ ERROR the trait bound `impl Future<Output = ()>: Copy` is not satisfied
//~^ ERROR : Copy` is not satisfied
check_clone(&inner_non_clone);
//~^ ERROR the trait bound `impl Future<Output = ()>: Clone` is not satisfied
//~^ ERROR : Clone` is not satisfied

let non_clone = NonClone;
let outer_non_clone = async move {
drop(non_clone);
};
check_copy(&outer_non_clone);
//~^ ERROR the trait bound `impl Future<Output = ()>: Copy` is not satisfied
//~^ ERROR : Copy` is not satisfied
check_clone(&outer_non_clone);
//~^ ERROR the trait bound `impl Future<Output = ()>: Clone` is not satisfied
//~^ ERROR : Clone` is not satisfied

let maybe_copy_clone = async move {};
check_copy(&maybe_copy_clone);
//~^ ERROR the trait bound `impl Future<Output = ()>: Copy` is not satisfied
//~^ ERROR : Copy` is not satisfied
check_clone(&maybe_copy_clone);
//~^ ERROR the trait bound `impl Future<Output = ()>: Clone` is not satisfied
//~^ ERROR : Clone` is not satisfied

let inner_non_clone_fn = the_inner_non_clone_fn();
check_copy(&inner_non_clone_fn);
//~^ ERROR the trait bound `impl Future<Output = ()>: Copy` is not satisfied
//~^ ERROR : Copy` is not satisfied
check_clone(&inner_non_clone_fn);
//~^ ERROR the trait bound `impl Future<Output = ()>: Clone` is not satisfied
//~^ ERROR : Clone` is not satisfied

let outer_non_clone_fn = the_outer_non_clone_fn(NonClone);
check_copy(&outer_non_clone_fn);
//~^ ERROR the trait bound `impl Future<Output = ()>: Copy` is not satisfied
//~^ ERROR : Copy` is not satisfied
check_clone(&outer_non_clone_fn);
//~^ ERROR the trait bound `impl Future<Output = ()>: Clone` is not satisfied
//~^ ERROR : Clone` is not satisfied

let maybe_copy_clone_fn = the_maybe_copy_clone_fn();
check_copy(&maybe_copy_clone_fn);
//~^ ERROR the trait bound `impl Future<Output = ()>: Copy` is not satisfied
//~^ ERROR : Copy` is not satisfied
check_clone(&maybe_copy_clone_fn);
//~^ ERROR the trait bound `impl Future<Output = ()>: Clone` is not satisfied
//~^ ERROR : Clone` is not satisfied
}

async fn the_inner_non_clone_fn() {
@@ -64,8 +64,7 @@ async fn the_outer_non_clone_fn(non_clone: NonClone) {
drop(non_clone);
}

async fn the_maybe_copy_clone_fn() {
}
async fn the_maybe_copy_clone_fn() {}

fn check_copy<T: Copy>(_x: &T) {}
fn check_clone<T: Clone>(_x: &T) {}
48 changes: 24 additions & 24 deletions src/test/ui/generator/clone-impl-async.stderr
Original file line number Diff line number Diff line change
@@ -1,83 +1,83 @@
error[E0277]: the trait bound `impl Future<Output = ()>: Copy` is not satisfied
error[E0277]: the trait bound `[async block@$DIR/clone-impl-async.rs:12:27: 16:6]: Copy` is not satisfied
--> $DIR/clone-impl-async.rs:17:16
|
LL | check_copy(&inner_non_clone);
| ---------- ^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `impl Future<Output = ()>`
| ---------- ^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `[async block@$DIR/clone-impl-async.rs:12:27: 16:6]`
| |
| required by a bound introduced by this call
|
note: required by a bound in `check_copy`
--> $DIR/clone-impl-async.rs:70:18
--> $DIR/clone-impl-async.rs:69:18
|
LL | fn check_copy<T: Copy>(_x: &T) {}
| ^^^^ required by this bound in `check_copy`

error[E0277]: the trait bound `impl Future<Output = ()>: Clone` is not satisfied
error[E0277]: the trait bound `[async block@$DIR/clone-impl-async.rs:12:27: 16:6]: Clone` is not satisfied
--> $DIR/clone-impl-async.rs:19:17
|
LL | check_clone(&inner_non_clone);
| ----------- ^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `impl Future<Output = ()>`
| ----------- ^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `[async block@$DIR/clone-impl-async.rs:12:27: 16:6]`
| |
| required by a bound introduced by this call
|
note: required by a bound in `check_clone`
--> $DIR/clone-impl-async.rs:71:19
--> $DIR/clone-impl-async.rs:70:19
|
LL | fn check_clone<T: Clone>(_x: &T) {}
| ^^^^^ required by this bound in `check_clone`

error[E0277]: the trait bound `impl Future<Output = ()>: Copy` is not satisfied
error[E0277]: the trait bound `[async block@$DIR/clone-impl-async.rs:23:27: 25:6]: Copy` is not satisfied
--> $DIR/clone-impl-async.rs:26:16
|
LL | check_copy(&outer_non_clone);
| ---------- ^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `impl Future<Output = ()>`
| ---------- ^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `[async block@$DIR/clone-impl-async.rs:23:27: 25:6]`
| |
| required by a bound introduced by this call
|
note: required by a bound in `check_copy`
--> $DIR/clone-impl-async.rs:70:18
--> $DIR/clone-impl-async.rs:69:18
|
LL | fn check_copy<T: Copy>(_x: &T) {}
| ^^^^ required by this bound in `check_copy`

error[E0277]: the trait bound `impl Future<Output = ()>: Clone` is not satisfied
error[E0277]: the trait bound `[async block@$DIR/clone-impl-async.rs:23:27: 25:6]: Clone` is not satisfied
--> $DIR/clone-impl-async.rs:28:17
|
LL | check_clone(&outer_non_clone);
| ----------- ^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `impl Future<Output = ()>`
| ----------- ^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `[async block@$DIR/clone-impl-async.rs:23:27: 25:6]`
| |
| required by a bound introduced by this call
|
note: required by a bound in `check_clone`
--> $DIR/clone-impl-async.rs:71:19
--> $DIR/clone-impl-async.rs:70:19
|
LL | fn check_clone<T: Clone>(_x: &T) {}
| ^^^^^ required by this bound in `check_clone`

error[E0277]: the trait bound `impl Future<Output = ()>: Copy` is not satisfied
error[E0277]: the trait bound `[async block@$DIR/clone-impl-async.rs:31:28: 31:41]: Copy` is not satisfied
--> $DIR/clone-impl-async.rs:32:16
|
LL | check_copy(&maybe_copy_clone);
| ---------- ^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `impl Future<Output = ()>`
| ---------- ^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `[async block@$DIR/clone-impl-async.rs:31:28: 31:41]`
| |
| required by a bound introduced by this call
|
note: required by a bound in `check_copy`
--> $DIR/clone-impl-async.rs:70:18
--> $DIR/clone-impl-async.rs:69:18
|
LL | fn check_copy<T: Copy>(_x: &T) {}
| ^^^^ required by this bound in `check_copy`

error[E0277]: the trait bound `impl Future<Output = ()>: Clone` is not satisfied
error[E0277]: the trait bound `[async block@$DIR/clone-impl-async.rs:31:28: 31:41]: Clone` is not satisfied
--> $DIR/clone-impl-async.rs:34:17
|
LL | check_clone(&maybe_copy_clone);
| ----------- ^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `impl Future<Output = ()>`
| ----------- ^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `[async block@$DIR/clone-impl-async.rs:31:28: 31:41]`
| |
| required by a bound introduced by this call
|
note: required by a bound in `check_clone`
--> $DIR/clone-impl-async.rs:71:19
--> $DIR/clone-impl-async.rs:70:19
|
LL | fn check_clone<T: Clone>(_x: &T) {}
| ^^^^^ required by this bound in `check_clone`
@@ -91,7 +91,7 @@ LL | check_copy(&inner_non_clone_fn);
| required by a bound introduced by this call
|
note: required by a bound in `check_copy`
--> $DIR/clone-impl-async.rs:70:18
--> $DIR/clone-impl-async.rs:69:18
|
LL | fn check_copy<T: Copy>(_x: &T) {}
| ^^^^ required by this bound in `check_copy`
@@ -105,7 +105,7 @@ LL | check_clone(&inner_non_clone_fn);
| required by a bound introduced by this call
|
note: required by a bound in `check_clone`
--> $DIR/clone-impl-async.rs:71:19
--> $DIR/clone-impl-async.rs:70:19
|
LL | fn check_clone<T: Clone>(_x: &T) {}
| ^^^^^ required by this bound in `check_clone`
@@ -119,7 +119,7 @@ LL | check_copy(&outer_non_clone_fn);
| required by a bound introduced by this call
|
note: required by a bound in `check_copy`
--> $DIR/clone-impl-async.rs:70:18
--> $DIR/clone-impl-async.rs:69:18
|
LL | fn check_copy<T: Copy>(_x: &T) {}
| ^^^^ required by this bound in `check_copy`
@@ -133,7 +133,7 @@ LL | check_clone(&outer_non_clone_fn);
| required by a bound introduced by this call
|
note: required by a bound in `check_clone`
--> $DIR/clone-impl-async.rs:71:19
--> $DIR/clone-impl-async.rs:70:19
|
LL | fn check_clone<T: Clone>(_x: &T) {}
| ^^^^^ required by this bound in `check_clone`
@@ -147,7 +147,7 @@ LL | check_copy(&maybe_copy_clone_fn);
| required by a bound introduced by this call
|
note: required by a bound in `check_copy`
--> $DIR/clone-impl-async.rs:70:18
--> $DIR/clone-impl-async.rs:69:18
|
LL | fn check_copy<T: Copy>(_x: &T) {}
| ^^^^ required by this bound in `check_copy`
@@ -161,7 +161,7 @@ LL | check_clone(&maybe_copy_clone_fn);
| required by a bound introduced by this call
|
note: required by a bound in `check_clone`
--> $DIR/clone-impl-async.rs:71:19
--> $DIR/clone-impl-async.rs:70:19
|
LL | fn check_clone<T: Clone>(_x: &T) {}
| ^^^^^ required by this bound in `check_clone`
2 changes: 1 addition & 1 deletion src/test/ui/impl-trait/issue-55872-3.rs
Original file line number Diff line number Diff line change
@@ -12,7 +12,7 @@ pub trait Bar {
impl<S> Bar for S {
type E = impl std::marker::Copy;
fn foo<T>() -> Self::E {
//~^ ERROR the trait bound `impl Future<Output = ()>: Copy` is not satisfied [E0277]
//~^ ERROR : Copy` is not satisfied [E0277]
async {}
}
}
4 changes: 2 additions & 2 deletions src/test/ui/impl-trait/issue-55872-3.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0277]: the trait bound `impl Future<Output = ()>: Copy` is not satisfied
error[E0277]: the trait bound `[async block@$DIR/issue-55872-3.rs:16:9: 16:17]: Copy` is not satisfied
--> $DIR/issue-55872-3.rs:14:20
|
LL | fn foo<T>() -> Self::E {
| ^^^^^^^ the trait `Copy` is not implemented for `impl Future<Output = ()>`
| ^^^^^^^ the trait `Copy` is not implemented for `[async block@$DIR/issue-55872-3.rs:16:9: 16:17]`

error: aborting due to previous error

2 changes: 1 addition & 1 deletion src/test/ui/impl-trait/issues/issue-78722.rs
Original file line number Diff line number Diff line change
@@ -7,7 +7,7 @@ type F = impl core::future::Future<Output = u8>;
struct Bug {
V1: [(); {
fn concrete_use() -> F {
//~^ ERROR expected `impl Future<Output = ()>` to be a future that resolves to `u8`, but it resolves to `()`
//~^ ERROR to be a future that resolves to `u8`, but it resolves to `()`
async {}
}
let f: F = async { 1 };
2 changes: 1 addition & 1 deletion src/test/ui/impl-trait/issues/issue-78722.stderr
Original file line number Diff line number Diff line change
@@ -16,7 +16,7 @@ LL | let f: F = async { 1 };
LL | }],
| - value is dropped here

error[E0271]: expected `impl Future<Output = ()>` to be a future that resolves to `u8`, but it resolves to `()`
error[E0271]: expected `[async block@$DIR/issue-78722.rs:11:13: 11:21]` to be a future that resolves to `u8`, but it resolves to `()`
--> $DIR/issue-78722.rs:9:30
|
LL | fn concrete_use() -> F {
19 changes: 19 additions & 0 deletions src/test/ui/issues/issue-104870.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Avoid panicking if the Clone trait is not found while building error suggestions

#![feature(no_core, lang_items)]
#![no_core]

#[lang = "sized"]
trait Sized {}

#[lang = "copy"]
trait Copy {}

fn g<T>(x: T) {}

fn f(x: *mut u8) {
g(x);
g(x); //~ ERROR use of moved value: `x`
}

fn main() {}
21 changes: 21 additions & 0 deletions src/test/ui/issues/issue-104870.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
error[E0382]: use of moved value: `x`
--> $DIR/issue-104870.rs:16:7
|
LL | fn f(x: *mut u8) {
| - move occurs because `x` has type `*mut u8`, which does not implement the `Copy` trait
LL | g(x);
| - value moved here
LL | g(x);
| ^ value used here after move
|
note: consider changing this parameter type in function `g` to borrow instead if owning the value isn't necessary
--> $DIR/issue-104870.rs:12:12
|
LL | fn g<T>(x: T) {}
| - ^ this parameter takes ownership of the value
| |
| in this function

error: aborting due to previous error

For more information about this error, try `rustc --explain E0382`.
2 changes: 1 addition & 1 deletion src/test/ui/pattern/non-structural-match-types.stderr
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@ error: `[closure@$DIR/non-structural-match-types.rs:9:17: 9:19]` cannot be used
LL | const { || {} } => {},
| ^^^^^^^^^^^^^^^

error: `impl Future<Output = ()>` cannot be used in patterns
error: `[async block@$DIR/non-structural-match-types.rs:12:17: 12:25]` cannot be used in patterns
--> $DIR/non-structural-match-types.rs:12:9
|
LL | const { async {} } => {},
Original file line number Diff line number Diff line change
@@ -87,7 +87,7 @@ LL | | }
| arguments to this function are incorrect
|
= note: expected struct `Pin<Box<dyn Future<Output = i32> + Send>>`
found `async` block `impl Future<Output = {integer}>`
found `async` block `[async block@$DIR/expected-boxed-future-isnt-pinned.rs:28:5: 30:6]`
note: function defined here
--> $SRC_DIR/core/src/future/mod.rs:LL:COL
|
5 changes: 4 additions & 1 deletion src/tools/jsondoclint/src/json_find.rs
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@ use std::fmt::Write;

use serde_json::Value;

#[derive(Debug, Clone)]
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum SelectorPart {
Field(String),
Index(usize),
@@ -72,3 +72,6 @@ fn find_selector_recursive(
}
}
}

#[cfg(test)]
mod tests;
27 changes: 27 additions & 0 deletions src/tools/jsondoclint/src/json_find/tests.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
use super::*;

#[test]
fn basic_find() {
use SelectorPart::*;

let j = serde_json::json!({
"index": {
"4": {
"inner": {
"items": ["1", "2", "3"]
}
}
}
});

let sel = find_selector(&j, &serde_json::json!("1"));
let exp: Vec<Vec<SelectorPart>> = vec![vec![
Field("index".to_owned()),
Field("4".to_owned()),
Field("inner".to_owned()),
Field("items".to_owned()),
Index(0),
]];

assert_eq!(exp, sel);
}
4 changes: 2 additions & 2 deletions src/tools/jsondoclint/src/main.rs
Original file line number Diff line number Diff line change
@@ -9,13 +9,13 @@ pub(crate) mod item_kind;
mod json_find;
mod validator;

#[derive(Debug)]
#[derive(Debug, PartialEq, Eq)]
struct Error {
kind: ErrorKind,
id: Id,
}

#[derive(Debug)]
#[derive(Debug, PartialEq, Eq)]
enum ErrorKind {
NotFound,
Custom(String),