Auto merge of #84501 - JohnTitor:rollup-wxu1thu, r=JohnTitor
Rollup of 10 pull requests Successful merges: - #83990 (implement `TrustedRandomAccess` for `Take` iterator adapter) - #84250 (bootstrap: use bash on illumos to run install scripts) - #84320 (Use details tag for trait implementors.) - #84436 (Make a few functions private) - #84453 (Document From implementations for Waker and RawWaker) - #84458 (Remove unnecessary fields and parameters in rustdoc) - #84485 (Add some associated type bounds tests) - #84489 (Mention FusedIterator case in Iterator::fuse doc) - #84492 (rustdoc: Remove unnecessary dummy span) - #84496 (Add some specialization tests) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
e11a9fa52a
44 changed files with 324 additions and 152 deletions
|
@ -797,7 +797,7 @@ pub const fn default_lib_output() -> CrateType {
|
|||
CrateType::Rlib
|
||||
}
|
||||
|
||||
pub fn default_configuration(sess: &Session) -> CrateConfig {
|
||||
fn default_configuration(sess: &Session) -> CrateConfig {
|
||||
let end = &sess.target.endian;
|
||||
let arch = &sess.target.arch;
|
||||
let wordsz = sess.target.pointer_width.to_string();
|
||||
|
@ -892,7 +892,7 @@ pub fn build_configuration(sess: &Session, mut user_cfg: CrateConfig) -> CrateCo
|
|||
user_cfg
|
||||
}
|
||||
|
||||
pub fn build_target_config(opts: &Options, target_override: Option<Target>) -> Target {
|
||||
pub(super) fn build_target_config(opts: &Options, target_override: Option<Target>) -> Target {
|
||||
let target_result = target_override.map_or_else(|| Target::search(&opts.target_triple), Ok);
|
||||
let target = target_result.unwrap_or_else(|e| {
|
||||
early_error(
|
||||
|
|
|
@ -87,6 +87,9 @@ pub trait Wake {
|
|||
|
||||
#[stable(feature = "wake_trait", since = "1.51.0")]
|
||||
impl<W: Wake + Send + Sync + 'static> From<Arc<W>> for Waker {
|
||||
/// Use a `Wake`-able type as a `Waker`.
|
||||
///
|
||||
/// No heap allocations or atomic operations are used for this conversion.
|
||||
fn from(waker: Arc<W>) -> Waker {
|
||||
// SAFETY: This is safe because raw_waker safely constructs
|
||||
// a RawWaker from Arc<W>.
|
||||
|
@ -96,6 +99,9 @@ impl<W: Wake + Send + Sync + 'static> From<Arc<W>> for Waker {
|
|||
|
||||
#[stable(feature = "wake_trait", since = "1.51.0")]
|
||||
impl<W: Wake + Send + Sync + 'static> From<Arc<W>> for RawWaker {
|
||||
/// Use a `Wake`-able type as a `RawWaker`.
|
||||
///
|
||||
/// No heap allocations or atomic operations are used for this conversion.
|
||||
fn from(waker: Arc<W>) -> RawWaker {
|
||||
raw_waker(waker)
|
||||
}
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
use crate::cmp;
|
||||
use crate::iter::{adapters::SourceIter, FusedIterator, InPlaceIterable, TrustedLen};
|
||||
use crate::iter::{
|
||||
adapters::zip::try_get_unchecked, adapters::SourceIter, FusedIterator, InPlaceIterable,
|
||||
TrustedLen, TrustedRandomAccess,
|
||||
};
|
||||
use crate::ops::{ControlFlow, Try};
|
||||
|
||||
/// An iterator that only iterates over the first `n` iterations of `iter`.
|
||||
|
@ -111,6 +114,15 @@ where
|
|||
|
||||
self.try_fold(init, ok(fold)).unwrap()
|
||||
}
|
||||
|
||||
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> <I as Iterator>::Item
|
||||
where
|
||||
Self: TrustedRandomAccess,
|
||||
{
|
||||
// SAFETY: the caller must uphold the contract for
|
||||
// `Iterator::__iterator_get_unchecked`.
|
||||
unsafe { try_get_unchecked(&mut self.iter, idx) }
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(issue = "none", feature = "inplace_iteration")]
|
||||
|
@ -207,3 +219,12 @@ impl<I> FusedIterator for Take<I> where I: FusedIterator {}
|
|||
|
||||
#[unstable(feature = "trusted_len", issue = "37572")]
|
||||
unsafe impl<I: TrustedLen> TrustedLen for Take<I> {}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[unstable(feature = "trusted_random_access", issue = "none")]
|
||||
unsafe impl<I> TrustedRandomAccess for Take<I>
|
||||
where
|
||||
I: TrustedRandomAccess,
|
||||
{
|
||||
const MAY_HAVE_SIDE_EFFECT: bool = I::MAY_HAVE_SIDE_EFFECT;
|
||||
}
|
||||
|
|
|
@ -1495,7 +1495,12 @@ pub trait Iterator {
|
|||
/// [`Some(T)`] again. `fuse()` adapts an iterator, ensuring that after a
|
||||
/// [`None`] is given, it will always return [`None`] forever.
|
||||
///
|
||||
/// Note that the [`Fuse`] wrapper is a no-op on iterators that implement
|
||||
/// the [`FusedIterator`] trait. `fuse()` may therefore behave incorrectly
|
||||
/// if the [`FusedIterator`] trait is improperly implemented.
|
||||
///
|
||||
/// [`Some(T)`]: Some
|
||||
/// [`FusedIterator`]: crate::iter::FusedIterator
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
|
|
@ -17,6 +17,11 @@ use crate::Compiler;
|
|||
use crate::builder::{Builder, RunConfig, ShouldRun, Step};
|
||||
use crate::config::{Config, TargetSelection};
|
||||
|
||||
#[cfg(target_os = "illumos")]
|
||||
const SHELL: &str = "bash";
|
||||
#[cfg(not(target_os = "illumos"))]
|
||||
const SHELL: &str = "sh";
|
||||
|
||||
fn install_sh(
|
||||
builder: &Builder<'_>,
|
||||
package: &str,
|
||||
|
@ -37,7 +42,7 @@ fn install_sh(
|
|||
let empty_dir = builder.out.join("tmp/empty_dir");
|
||||
t!(fs::create_dir_all(&empty_dir));
|
||||
|
||||
let mut cmd = Command::new("sh");
|
||||
let mut cmd = Command::new(SHELL);
|
||||
cmd.current_dir(&empty_dir)
|
||||
.arg(sanitize_sh(&tarball.decompressed_output().join("install.sh")))
|
||||
.arg(format!("--prefix={}", prepare_dir(prefix)))
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_span::{edition::Edition, Symbol};
|
||||
use rustc_span::Symbol;
|
||||
|
||||
use crate::clean;
|
||||
use crate::config::RenderOptions;
|
||||
|
@ -23,7 +23,6 @@ crate trait FormatRenderer<'tcx>: Sized {
|
|||
fn init(
|
||||
krate: clean::Crate,
|
||||
options: RenderOptions,
|
||||
edition: Edition,
|
||||
cache: Cache,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
) -> Result<(Self, clean::Crate), Error>;
|
||||
|
@ -35,19 +34,15 @@ crate trait FormatRenderer<'tcx>: Sized {
|
|||
fn item(&mut self, item: clean::Item) -> Result<(), Error>;
|
||||
|
||||
/// Renders a module (should not handle recursing into children).
|
||||
fn mod_item_in(&mut self, item: &clean::Item, item_name: &str) -> Result<(), Error>;
|
||||
fn mod_item_in(&mut self, item: &clean::Item) -> Result<(), Error>;
|
||||
|
||||
/// Runs after recursively rendering all sub-items of a module.
|
||||
fn mod_item_out(&mut self, item_name: &str) -> Result<(), Error>;
|
||||
fn mod_item_out(&mut self) -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Post processing hook for cleanup and dumping output to files.
|
||||
///
|
||||
/// A handler is available if the renderer wants to report errors.
|
||||
fn after_krate(
|
||||
&mut self,
|
||||
crate_name: Symbol,
|
||||
diag: &rustc_errors::Handler,
|
||||
) -> Result<(), Error>;
|
||||
fn after_krate(&mut self) -> Result<(), Error>;
|
||||
|
||||
fn cache(&self) -> &Cache;
|
||||
}
|
||||
|
@ -57,8 +52,6 @@ crate fn run_format<'tcx, T: FormatRenderer<'tcx>>(
|
|||
krate: clean::Crate,
|
||||
options: RenderOptions,
|
||||
cache: Cache,
|
||||
diag: &rustc_errors::Handler,
|
||||
edition: Edition,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
) -> Result<(), Error> {
|
||||
let prof = &tcx.sess.prof;
|
||||
|
@ -66,14 +59,13 @@ crate fn run_format<'tcx, T: FormatRenderer<'tcx>>(
|
|||
let emit_crate = options.should_emit_crate();
|
||||
let (mut format_renderer, krate) = prof
|
||||
.extra_verbose_generic_activity("create_renderer", T::descr())
|
||||
.run(|| T::init(krate, options, edition, cache, tcx))?;
|
||||
.run(|| T::init(krate, options, cache, tcx))?;
|
||||
|
||||
if !emit_crate {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// Render the crate documentation
|
||||
let crate_name = krate.name;
|
||||
let mut work = vec![(format_renderer.make_child_renderer(), krate.module)];
|
||||
|
||||
let unknown = Symbol::intern("<unknown item>");
|
||||
|
@ -81,13 +73,10 @@ crate fn run_format<'tcx, T: FormatRenderer<'tcx>>(
|
|||
if item.is_mod() && T::RUN_ON_MODULE {
|
||||
// modules are special because they add a namespace. We also need to
|
||||
// recurse into the items of the module as well.
|
||||
let name = item.name.as_ref().unwrap().to_string();
|
||||
if name.is_empty() {
|
||||
panic!("Unexpected module with empty name");
|
||||
}
|
||||
let _timer = prof.generic_activity_with_arg("render_mod_item", name.as_str());
|
||||
let _timer =
|
||||
prof.generic_activity_with_arg("render_mod_item", item.name.unwrap().to_string());
|
||||
|
||||
cx.mod_item_in(&item, &name)?;
|
||||
cx.mod_item_in(&item)?;
|
||||
let module = match *item.kind {
|
||||
clean::StrippedItem(box clean::ModuleItem(m)) | clean::ModuleItem(m) => m,
|
||||
_ => unreachable!(),
|
||||
|
@ -97,7 +86,7 @@ crate fn run_format<'tcx, T: FormatRenderer<'tcx>>(
|
|||
work.push((cx.make_child_renderer(), it));
|
||||
}
|
||||
|
||||
cx.mod_item_out(&name)?;
|
||||
cx.mod_item_out()?;
|
||||
// FIXME: checking `item.name.is_some()` is very implicit and leads to lots of special
|
||||
// cases. Use an explicit match instead.
|
||||
} else if item.name.is_some() && !item.is_extern_crate() {
|
||||
|
@ -106,5 +95,5 @@ crate fn run_format<'tcx, T: FormatRenderer<'tcx>>(
|
|||
}
|
||||
}
|
||||
prof.extra_verbose_generic_activity("renderer_after_krate", T::descr())
|
||||
.run(|| format_renderer.after_krate(crate_name, diag))
|
||||
.run(|| format_renderer.after_krate())
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ use rustc_middle::ty::TyCtxt;
|
|||
use rustc_session::Session;
|
||||
use rustc_span::edition::Edition;
|
||||
use rustc_span::source_map::FileName;
|
||||
use rustc_span::{symbol::sym, Symbol};
|
||||
use rustc_span::symbol::sym;
|
||||
|
||||
use super::cache::{build_index, ExternalLocation};
|
||||
use super::print_item::{full_path, item_path, print_item};
|
||||
|
@ -111,8 +111,6 @@ crate struct SharedContext<'tcx> {
|
|||
crate static_root_path: Option<String>,
|
||||
/// The fs handle we are working with.
|
||||
crate fs: DocFS,
|
||||
/// The default edition used to parse doctests.
|
||||
crate edition: Edition,
|
||||
pub(super) codes: ErrorCodes,
|
||||
pub(super) playground: Option<markdown::Playground>,
|
||||
all: RefCell<AllTypes>,
|
||||
|
@ -141,6 +139,10 @@ impl SharedContext<'_> {
|
|||
crate fn maybe_collapsed_doc_value<'a>(&self, item: &'a clean::Item) -> Option<String> {
|
||||
if self.collapsed { item.collapsed_doc_value() } else { item.doc_value() }
|
||||
}
|
||||
|
||||
crate fn edition(&self) -> Edition {
|
||||
self.tcx.sess.edition()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Context<'tcx> {
|
||||
|
@ -346,7 +348,6 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
|
|||
fn init(
|
||||
mut krate: clean::Crate,
|
||||
options: RenderOptions,
|
||||
edition: Edition,
|
||||
mut cache: Cache,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
) -> Result<(Self, clean::Crate), Error> {
|
||||
|
@ -435,7 +436,6 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
|
|||
resource_suffix,
|
||||
static_root_path,
|
||||
fs: DocFS::new(sender),
|
||||
edition,
|
||||
codes: ErrorCodes::from(unstable_features.is_nightly_build()),
|
||||
playground,
|
||||
all: RefCell::new(AllTypes::new()),
|
||||
|
@ -494,11 +494,8 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn after_krate(
|
||||
&mut self,
|
||||
crate_name: Symbol,
|
||||
diag: &rustc_errors::Handler,
|
||||
) -> Result<(), Error> {
|
||||
fn after_krate(&mut self) -> Result<(), Error> {
|
||||
let crate_name = self.tcx().crate_name(LOCAL_CRATE);
|
||||
let final_file = self.dst.join(&*crate_name.as_str()).join("all.html");
|
||||
let settings_file = self.dst.join("settings.html");
|
||||
|
||||
|
@ -572,7 +569,8 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
|
|||
|
||||
// Flush pending errors.
|
||||
Rc::get_mut(&mut self.shared).unwrap().fs.close();
|
||||
let nb_errors = self.shared.errors.iter().map(|err| diag.struct_err(&err).emit()).count();
|
||||
let nb_errors =
|
||||
self.shared.errors.iter().map(|err| self.tcx().sess.struct_err(&err).emit()).count();
|
||||
if nb_errors > 0 {
|
||||
Err(Error::new(io::Error::new(io::ErrorKind::Other, "I/O error"), ""))
|
||||
} else {
|
||||
|
@ -580,7 +578,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn mod_item_in(&mut self, item: &clean::Item, item_name: &str) -> Result<(), Error> {
|
||||
fn mod_item_in(&mut self, item: &clean::Item) -> Result<(), Error> {
|
||||
// Stripped modules survive the rustdoc passes (i.e., `strip-private`)
|
||||
// if they contain impls for public types. These modules can also
|
||||
// contain items such as publicly re-exported structures.
|
||||
|
@ -592,8 +590,9 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
|
|||
self.render_redirect_pages = item.is_stripped();
|
||||
}
|
||||
let scx = &self.shared;
|
||||
self.dst.push(item_name);
|
||||
self.current.push(item_name.to_owned());
|
||||
let item_name = item.name.as_ref().unwrap().to_string();
|
||||
self.dst.push(&item_name);
|
||||
self.current.push(item_name);
|
||||
|
||||
info!("Recursing into {}", self.dst.display());
|
||||
|
||||
|
@ -619,7 +618,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn mod_item_out(&mut self, _item_name: &str) -> Result<(), Error> {
|
||||
fn mod_item_out(&mut self) -> Result<(), Error> {
|
||||
info!("Recursed; leaving {}", self.dst.display());
|
||||
|
||||
// Go back to where we were at
|
||||
|
|
|
@ -530,7 +530,7 @@ fn render_markdown(
|
|||
&links,
|
||||
&mut ids,
|
||||
cx.shared.codes,
|
||||
cx.shared.edition,
|
||||
cx.shared.edition(),
|
||||
&cx.shared.playground
|
||||
)
|
||||
.into_string()
|
||||
|
@ -660,7 +660,7 @@ fn short_item_info(
|
|||
¬e,
|
||||
&mut ids,
|
||||
error_codes,
|
||||
cx.shared.edition,
|
||||
cx.shared.edition(),
|
||||
&cx.shared.playground,
|
||||
);
|
||||
message.push_str(&format!(": {}", html.into_string()));
|
||||
|
@ -702,7 +702,7 @@ fn short_item_info(
|
|||
&unstable_reason.as_str(),
|
||||
&mut ids,
|
||||
error_codes,
|
||||
cx.shared.edition,
|
||||
cx.shared.edition(),
|
||||
&cx.shared.playground,
|
||||
)
|
||||
.into_string()
|
||||
|
@ -1284,6 +1284,7 @@ fn render_impl(
|
|||
let cache = cx.cache();
|
||||
let traits = &cache.traits;
|
||||
let trait_ = i.trait_did_full(cache).map(|did| &traits[&did]);
|
||||
let mut close_tags = String::new();
|
||||
|
||||
if render_mode == RenderMode::Normal {
|
||||
let id = cx.derive_id(match i.inner_impl().trait_ {
|
||||
|
@ -1302,7 +1303,12 @@ fn render_impl(
|
|||
format!(" aliases=\"{}\"", aliases.join(","))
|
||||
};
|
||||
if let Some(use_absolute) = use_absolute {
|
||||
write!(w, "<h3 id=\"{}\" class=\"impl\"{}><code class=\"in-band\">", id, aliases);
|
||||
write!(
|
||||
w,
|
||||
"<details class=\"rustdoc-toggle implementors-toggle\"><summary><h3 id=\"{}\" class=\"impl\"{}><code class=\"in-band\">",
|
||||
id, aliases
|
||||
);
|
||||
close_tags.insert_str(0, "</details>");
|
||||
write!(w, "{}", i.inner_impl().print(use_absolute, cx));
|
||||
if show_def_docs {
|
||||
for it in &i.inner_impl().items {
|
||||
|
@ -1325,11 +1331,12 @@ fn render_impl(
|
|||
} else {
|
||||
write!(
|
||||
w,
|
||||
"<h3 id=\"{}\" class=\"impl\"{}><code class=\"in-band\">{}</code>",
|
||||
"<details class=\"rustdoc-toggle implementors-toggle\"><summary><h3 id=\"{}\" class=\"impl\"{}><code class=\"in-band\">{}</code>",
|
||||
id,
|
||||
aliases,
|
||||
i.inner_impl().print(false, cx)
|
||||
);
|
||||
close_tags.insert_str(0, "</details>");
|
||||
}
|
||||
write!(w, "<a href=\"#{}\" class=\"anchor\"></a>", id);
|
||||
render_stability_since_raw(
|
||||
|
@ -1341,6 +1348,7 @@ fn render_impl(
|
|||
);
|
||||
write_srclink(cx, &i.impl_item, w);
|
||||
w.write_str("</h3>");
|
||||
w.write_str("</summary>");
|
||||
|
||||
if trait_.is_some() {
|
||||
if let Some(portability) = portability(&i.impl_item, Some(parent)) {
|
||||
|
@ -1358,7 +1366,7 @@ fn render_impl(
|
|||
&i.impl_item.links(cx),
|
||||
&mut ids,
|
||||
cx.shared.codes,
|
||||
cx.shared.edition,
|
||||
cx.shared.edition(),
|
||||
&cx.shared.playground
|
||||
)
|
||||
.into_string()
|
||||
|
@ -1542,6 +1550,7 @@ fn render_impl(
|
|||
}
|
||||
|
||||
w.write_str("<div class=\"impl-items\">");
|
||||
close_tags.insert_str(0, "</div>");
|
||||
for trait_item in &i.inner_impl().items {
|
||||
doc_impl_item(
|
||||
w,
|
||||
|
@ -1612,7 +1621,7 @@ fn render_impl(
|
|||
);
|
||||
}
|
||||
}
|
||||
w.write_str("</div>");
|
||||
w.write_str(&close_tags);
|
||||
}
|
||||
|
||||
fn print_sidebar(cx: &Context<'_>, it: &clean::Item, buffer: &mut Buffer) {
|
||||
|
|
|
@ -425,7 +425,7 @@ pub(super) fn write_shared(
|
|||
md_opts.output = cx.dst.clone();
|
||||
md_opts.external_html = (*cx.shared).layout.external_html.clone();
|
||||
|
||||
crate::markdown::render(&index_page, md_opts, cx.shared.edition)
|
||||
crate::markdown::render(&index_page, md_opts, cx.shared.edition())
|
||||
.map_err(|e| Error::new(e, &index_page))?;
|
||||
} else {
|
||||
let dst = cx.dst.join("index.html");
|
||||
|
|
|
@ -129,7 +129,7 @@ impl SourceCollector<'_, 'tcx> {
|
|||
&self.scx.layout,
|
||||
&page,
|
||||
"",
|
||||
|buf: &mut _| print_src(buf, contents, self.scx.edition),
|
||||
|buf: &mut _| print_src(buf, contents, self.scx.edition()),
|
||||
&self.scx.style_files,
|
||||
);
|
||||
self.scx.fs.write(&cur, v.as_bytes())?;
|
||||
|
|
|
@ -1207,31 +1207,18 @@ function hideThemeButtonState() {
|
|||
if (!next) {
|
||||
return;
|
||||
}
|
||||
if (hasClass(e, "impl") &&
|
||||
(next.getElementsByClassName("method").length > 0 ||
|
||||
next.getElementsByClassName("associatedconstant").length > 0)) {
|
||||
var newToggle = toggle.cloneNode(true);
|
||||
insertAfter(newToggle, e.childNodes[e.childNodes.length - 1]);
|
||||
// In case the option "auto-collapse implementors" is not set to false, we collapse
|
||||
// all implementors.
|
||||
if (hideImplementors === true && e.parentNode.id === "implementors-list") {
|
||||
collapseDocs(newToggle, "hide");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
onEachLazy(document.getElementsByClassName("method"), func);
|
||||
onEachLazy(document.getElementsByClassName("associatedconstant"), func);
|
||||
onEachLazy(document.getElementsByClassName("impl"), funcImpl);
|
||||
var impl_call = function() {};
|
||||
// Large items are hidden by default in the HTML. If the setting overrides that, show 'em.
|
||||
if (!hideLargeItemContents) {
|
||||
onEachLazy(document.getElementsByTagName("details"), function (e) {
|
||||
if (hasClass(e, "type-contents-toggle")) {
|
||||
e.open = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
onEachLazy(document.getElementsByTagName("details"), function (e) {
|
||||
var showLargeItem = !hideLargeItemContents && hasClass(e, "type-contents-toggle");
|
||||
var showImplementor = !hideImplementors && hasClass(e, "implementors-toggle");
|
||||
if (showLargeItem || showImplementor) {
|
||||
e.open = true;
|
||||
}
|
||||
});
|
||||
if (hideMethodDocs === true) {
|
||||
impl_call = function(e, newToggle) {
|
||||
if (e.id.match(/^impl(?:-\d+)?$/) === null) {
|
||||
|
|
|
@ -1573,6 +1573,10 @@ h4 > .notable-traits {
|
|||
left: -10px;
|
||||
}
|
||||
|
||||
.item-list > details.rustdoc-toggle > summary:not(.hideme)::before {
|
||||
left: -10px;
|
||||
}
|
||||
|
||||
#all-types {
|
||||
margin: 10px;
|
||||
}
|
||||
|
@ -1787,6 +1791,7 @@ details.rustdoc-toggle > summary::before {
|
|||
font-weight: 300;
|
||||
font-size: 0.8em;
|
||||
letter-spacing: 1px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
details.rustdoc-toggle > summary.hideme::before {
|
||||
|
@ -1794,7 +1799,8 @@ details.rustdoc-toggle > summary.hideme::before {
|
|||
}
|
||||
|
||||
details.rustdoc-toggle > summary:not(.hideme)::before {
|
||||
float: left;
|
||||
position: absolute;
|
||||
left: -23px;
|
||||
}
|
||||
|
||||
/* When a "hideme" summary is open and the "Expand description" or "Show
|
||||
|
|
|
@ -14,7 +14,6 @@ use std::rc::Rc;
|
|||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_session::Session;
|
||||
use rustc_span::{edition::Edition, Symbol};
|
||||
|
||||
use rustdoc_json_types as types;
|
||||
|
||||
|
@ -134,7 +133,6 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
|
|||
fn init(
|
||||
krate: clean::Crate,
|
||||
options: RenderOptions,
|
||||
_edition: Edition,
|
||||
cache: Cache,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
) -> Result<(Self, clean::Crate), Error> {
|
||||
|
@ -183,7 +181,7 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn mod_item_in(&mut self, item: &clean::Item, _module_name: &str) -> Result<(), Error> {
|
||||
fn mod_item_in(&mut self, item: &clean::Item) -> Result<(), Error> {
|
||||
use clean::types::ItemKind::*;
|
||||
if let ModuleItem(m) = &*item.kind {
|
||||
for item in &m.items {
|
||||
|
@ -200,15 +198,7 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn mod_item_out(&mut self, _item_name: &str) -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn after_krate(
|
||||
&mut self,
|
||||
_crate_name: Symbol,
|
||||
_diag: &rustc_errors::Handler,
|
||||
) -> Result<(), Error> {
|
||||
fn after_krate(&mut self) -> Result<(), Error> {
|
||||
debug!("Done with crate");
|
||||
let mut index = (*self.index).clone().into_inner();
|
||||
index.extend(self.get_trait_items());
|
||||
|
|
|
@ -656,14 +656,13 @@ fn run_renderer<'tcx, T: formats::FormatRenderer<'tcx>>(
|
|||
krate: clean::Crate,
|
||||
renderopts: config::RenderOptions,
|
||||
cache: formats::cache::Cache,
|
||||
diag: &rustc_errors::Handler,
|
||||
edition: rustc_span::edition::Edition,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
) -> MainResult {
|
||||
match formats::run_format::<T>(krate, renderopts, cache, &diag, edition, tcx) {
|
||||
match formats::run_format::<T>(krate, renderopts, cache, tcx) {
|
||||
Ok(_) => Ok(()),
|
||||
Err(e) => {
|
||||
let mut msg = diag.struct_err(&format!("couldn't generate documentation: {}", e.error));
|
||||
let mut msg =
|
||||
tcx.sess.struct_err(&format!("couldn't generate documentation: {}", e.error));
|
||||
let file = e.file.display().to_string();
|
||||
if file.is_empty() {
|
||||
msg.emit()
|
||||
|
@ -692,7 +691,6 @@ fn main_options(options: config::Options) -> MainResult {
|
|||
|
||||
// need to move these items separately because we lose them by the time the closure is called,
|
||||
// but we can't create the Handler ahead of time because it's not Send
|
||||
let diag_opts = (options.error_format, options.edition, options.debugging_opts.clone());
|
||||
let show_coverage = options.show_coverage;
|
||||
let run_check = options.run_check;
|
||||
|
||||
|
@ -758,28 +756,12 @@ fn main_options(options: config::Options) -> MainResult {
|
|||
}
|
||||
|
||||
info!("going to format");
|
||||
let (error_format, edition, debugging_options) = diag_opts;
|
||||
let diag = core::new_handler(error_format, None, &debugging_options);
|
||||
match output_format {
|
||||
config::OutputFormat::Html => sess.time("render_html", || {
|
||||
run_renderer::<html::render::Context<'_>>(
|
||||
krate,
|
||||
render_opts,
|
||||
cache,
|
||||
&diag,
|
||||
edition,
|
||||
tcx,
|
||||
)
|
||||
run_renderer::<html::render::Context<'_>>(krate, render_opts, cache, tcx)
|
||||
}),
|
||||
config::OutputFormat::Json => sess.time("render_json", || {
|
||||
run_renderer::<json::JsonRenderer<'_>>(
|
||||
krate,
|
||||
render_opts,
|
||||
cache,
|
||||
&diag,
|
||||
edition,
|
||||
tcx,
|
||||
)
|
||||
run_renderer::<json::JsonRenderer<'_>>(krate, render_opts, cache, tcx)
|
||||
}),
|
||||
}
|
||||
})
|
||||
|
|
|
@ -71,9 +71,10 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
|||
}
|
||||
|
||||
crate fn visit(mut self, krate: &'tcx hir::Crate<'_>) -> Module<'tcx> {
|
||||
let span = krate.item.inner;
|
||||
let mut top_level_module = self.visit_mod_contents(
|
||||
krate.item.inner,
|
||||
&Spanned { span: rustc_span::DUMMY_SP, node: hir::VisibilityKind::Public },
|
||||
span,
|
||||
&Spanned { span, node: hir::VisibilityKind::Public },
|
||||
hir::CRATE_HIR_ID,
|
||||
&krate.item,
|
||||
self.cx.tcx.crate_name,
|
||||
|
@ -130,7 +131,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
|||
fn visit_mod_contents(
|
||||
&mut self,
|
||||
span: Span,
|
||||
vis: &'tcx hir::Visibility<'_>,
|
||||
vis: &hir::Visibility<'_>,
|
||||
id: hir::HirId,
|
||||
m: &'tcx hir::Mod<'tcx>,
|
||||
name: Symbol,
|
||||
|
|
|
@ -8,7 +8,7 @@ pub struct Simd<T, const WIDTH: usize> {
|
|||
inner: T,
|
||||
}
|
||||
|
||||
// @has foo/struct.Simd.html '//div[@id="trait-implementations-list"]/h3/code' 'impl Add<Simd<u8, 16_usize>> for Simd<u8, 16>'
|
||||
// @has foo/struct.Simd.html '//div[@id="trait-implementations-list"]//h3/code' 'impl Add<Simd<u8, 16_usize>> for Simd<u8, 16>'
|
||||
impl Add for Simd<u8, 16> {
|
||||
type Output = Self;
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
// @has issue_33054/impls/struct.Foo.html
|
||||
// @has - '//code' 'impl Foo'
|
||||
// @has - '//code' 'impl Bar for Foo'
|
||||
// @count - '//*[@id="trait-implementations-list"]/*[@class="impl"]' 1
|
||||
// @count - '//*[@id="main"]/*[@class="impl"]' 1
|
||||
// @count - '//*[@id="trait-implementations-list"]//*[@class="impl"]' 1
|
||||
// @count - '//*[@id="main"]/details/summary/*[@class="impl"]' 1
|
||||
// @has issue_33054/impls/bar/trait.Bar.html
|
||||
// @has - '//code' 'impl Bar for Foo'
|
||||
// @count - '//*[@class="struct"]' 1
|
||||
|
|
|
@ -7,5 +7,5 @@ mod inner {
|
|||
pub trait Blah { }
|
||||
|
||||
// @count issue_21474/struct.What.html \
|
||||
// '//*[@id="trait-implementations-list"]/*[@class="impl"]' 1
|
||||
// '//*[@id="trait-implementations-list"]//*[@class="impl"]' 1
|
||||
pub struct What;
|
||||
|
|
|
@ -5,7 +5,7 @@ pub trait MyTrait {
|
|||
fn my_string(&self) -> String;
|
||||
}
|
||||
|
||||
// @has - "//div[@id='implementors-list']/h3[@id='impl-MyTrait']//code" "impl<T> MyTrait for T where T: Debug"
|
||||
// @has - "//div[@id='implementors-list']//h3[@id='impl-MyTrait']//code" "impl<T> MyTrait for T where T: Debug"
|
||||
impl<T> MyTrait for T where T: fmt::Debug {
|
||||
fn my_string(&self) -> String {
|
||||
format!("{:?}", self)
|
||||
|
|
|
@ -4,12 +4,12 @@ pub trait Bar<T, U> {}
|
|||
|
||||
// @has 'foo/struct.Foo1.html'
|
||||
pub struct Foo1;
|
||||
// @count - '//*[@id="trait-implementations-list"]/*[@class="impl"]' 1
|
||||
// @count - '//*[@id="trait-implementations-list"]//*[@class="impl"]' 1
|
||||
// @has - '//*[@class="impl"]' "impl Bar<Foo1, &'static Foo1> for Foo1"
|
||||
impl Bar<Foo1, &'static Foo1> for Foo1 {}
|
||||
|
||||
// @has 'foo/struct.Foo2.html'
|
||||
pub struct Foo2;
|
||||
// @count - '//*[@id="trait-implementations-list"]/*[@class="impl"]' 1
|
||||
// @count - '//*[@id="trait-implementations-list"]//*[@class="impl"]' 1
|
||||
// @has - '//*[@class="impl"]' "impl Bar<&'static Foo2, Foo2> for u8"
|
||||
impl Bar<&'static Foo2, Foo2> for u8 {}
|
||||
|
|
|
@ -13,8 +13,8 @@ impl<B, C> Signal2 for B where B: Signal<Item = C> {
|
|||
// @has issue_50159/struct.Switch.html
|
||||
// @has - '//code' 'impl<B> Send for Switch<B> where <B as Signal>::Item: Send'
|
||||
// @has - '//code' 'impl<B> Sync for Switch<B> where <B as Signal>::Item: Sync'
|
||||
// @count - '//*[@id="implementations-list"]/*[@class="impl"]' 0
|
||||
// @count - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]' 5
|
||||
// @count - '//*[@id="implementations-list"]//*[@class="impl"]' 0
|
||||
// @count - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]' 5
|
||||
pub struct Switch<B: Signal> {
|
||||
pub inner: <B as Signal2>::Item2,
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ pub mod traits {
|
|||
}
|
||||
|
||||
// @has issue_51236/struct.Owned.html
|
||||
// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//code' "impl<T> Send for \
|
||||
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//code' "impl<T> Send for \
|
||||
// Owned<T> where <T as Owned<'static>>::Reader: Send"
|
||||
pub struct Owned<T> where T: for<'a> ::traits::Owned<'a> {
|
||||
marker: PhantomData<<T as ::traits::Owned<'static>>::Reader>,
|
||||
|
|
|
@ -12,9 +12,9 @@ macro_rules! array_impls {
|
|||
}
|
||||
}
|
||||
|
||||
// @has issue_53812/trait.MyIterator.html '//*[@id="implementors-list"]//h3[1]' 'MyStruct<[T; 0]>'
|
||||
// @has - '//*[@id="implementors-list"]//h3[2]' 'MyStruct<[T; 1]>'
|
||||
// @has - '//*[@id="implementors-list"]//h3[3]' 'MyStruct<[T; 2]>'
|
||||
// @has - '//*[@id="implementors-list"]//h3[4]' 'MyStruct<[T; 3]>'
|
||||
// @has - '//*[@id="implementors-list"]//h3[5]' 'MyStruct<[T; 10]>'
|
||||
// @has issue_53812/trait.MyIterator.html '//*[@id="implementors-list"]/details[1]/summary/h3' 'MyStruct<[T; 0]>'
|
||||
// @has - '//*[@id="implementors-list"]/details[2]/summary/h3' 'MyStruct<[T; 1]>'
|
||||
// @has - '//*[@id="implementors-list"]/details[3]/summary/h3' 'MyStruct<[T; 2]>'
|
||||
// @has - '//*[@id="implementors-list"]/details[4]/summary/h3' 'MyStruct<[T; 3]>'
|
||||
// @has - '//*[@id="implementors-list"]/details[5]/summary/h3' 'MyStruct<[T; 10]>'
|
||||
array_impls! { 10 3 2 1 0 }
|
||||
|
|
|
@ -3,10 +3,10 @@ pub trait ScopeHandle<'scope> {}
|
|||
|
||||
|
||||
// @has issue_54705/struct.ScopeFutureContents.html
|
||||
// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//code' "impl<'scope, S> \
|
||||
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//code' "impl<'scope, S> \
|
||||
// Send for ScopeFutureContents<'scope, S> where S: Sync"
|
||||
//
|
||||
// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//code' "impl<'scope, S> \
|
||||
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//code' "impl<'scope, S> \
|
||||
// Sync for ScopeFutureContents<'scope, S> where S: Sync"
|
||||
pub struct ScopeFutureContents<'scope, S>
|
||||
where S: ScopeHandle<'scope>,
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
#![feature(negative_impls)]
|
||||
|
||||
// @has issue_55321/struct.A.html
|
||||
// @has - '//*[@id="trait-implementations-list"]/*[@class="impl"]//code' "impl !Send for A"
|
||||
// @has - '//*[@id="trait-implementations-list"]/*[@class="impl"]//code' "impl !Sync for A"
|
||||
// @has - '//*[@id="trait-implementations-list"]//*[@class="impl"]//code' "impl !Send for A"
|
||||
// @has - '//*[@id="trait-implementations-list"]//*[@class="impl"]//code' "impl !Sync for A"
|
||||
pub struct A();
|
||||
|
||||
impl !Send for A {}
|
||||
impl !Sync for A {}
|
||||
|
||||
// @has issue_55321/struct.B.html
|
||||
// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//code' "impl<T> !Send for \
|
||||
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//code' "impl<T> !Send for \
|
||||
// B<T>"
|
||||
// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//code' "impl<T> !Sync for \
|
||||
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//code' "impl<T> !Sync for \
|
||||
// B<T>"
|
||||
pub struct B<T: ?Sized>(A, Box<T>);
|
||||
|
|
|
@ -17,7 +17,7 @@ impl<'a, T> MyTrait for Inner<'a, T> {
|
|||
}
|
||||
|
||||
// @has issue_56822/struct.Parser.html
|
||||
// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//code' "impl<'a> Send for \
|
||||
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//code' "impl<'a> Send for \
|
||||
// Parser<'a>"
|
||||
pub struct Parser<'a> {
|
||||
field: <Wrapper<Inner<'a, u8>> as MyTrait>::Output
|
||||
|
|
|
@ -26,9 +26,9 @@ where
|
|||
{}
|
||||
|
||||
// @has issue_60726/struct.IntoIter.html
|
||||
// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//code' "impl<T> !Send for \
|
||||
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//code' "impl<T> !Send for \
|
||||
// IntoIter<T>"
|
||||
// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//code' "impl<T> !Sync for \
|
||||
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//code' "impl<T> !Sync for \
|
||||
// IntoIter<T>"
|
||||
pub struct IntoIter<T>{
|
||||
hello:DynTrait<FooInterface<T>>,
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
// @has basic/struct.Foo.html
|
||||
// @has - '//code' 'impl<T> Send for Foo<T> where T: Send'
|
||||
// @has - '//code' 'impl<T> Sync for Foo<T> where T: Sync'
|
||||
// @count - '//*[@id="implementations-list"]/*[@class="impl"]' 0
|
||||
// @count - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]' 5
|
||||
// @count - '//*[@id="implementations-list"]//*[@class="impl"]' 0
|
||||
// @count - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]' 5
|
||||
pub struct Foo<T> {
|
||||
field: T,
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ mod foo {
|
|||
}
|
||||
|
||||
// @has complex/struct.NotOuter.html
|
||||
// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//code' "impl<'a, T, K: \
|
||||
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//code' "impl<'a, T, K: \
|
||||
// ?Sized> Send for Outer<'a, T, K> where K: for<'b> Fn((&'b bool, &'a u8)) \
|
||||
// -> &'b i8, T: MyTrait<'a>, <T as MyTrait<'a>>::MyItem: Copy, 'a: 'static"
|
||||
|
||||
|
|
|
@ -9,10 +9,10 @@ where
|
|||
{}
|
||||
|
||||
// @has lifetimes/struct.Foo.html
|
||||
// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//code' "impl<'c, K> Send \
|
||||
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//code' "impl<'c, K> Send \
|
||||
// for Foo<'c, K> where K: for<'b> Fn(&'b bool) -> &'c u8, 'c: 'static"
|
||||
//
|
||||
// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//code' "impl<'c, K> Sync \
|
||||
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//code' "impl<'c, K> Sync \
|
||||
// for Foo<'c, K> where K: Sync"
|
||||
pub struct Foo<'c, K: 'c> {
|
||||
inner_field: Inner<'c, K>,
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
// @has manual/struct.Foo.html
|
||||
// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//code' 'impl<T> Sync for \
|
||||
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//code' 'impl<T> Sync for \
|
||||
// Foo<T> where T: Sync'
|
||||
//
|
||||
// @has - '//*[@id="trait-implementations-list"]/*[@class="impl"]//code' \
|
||||
// @has - '//*[@id="trait-implementations-list"]//*[@class="impl"]//code' \
|
||||
// 'impl<T> Send for Foo<T>'
|
||||
//
|
||||
// @count - '//*[@id="trait-implementations-list"]/*[@class="impl"]' 1
|
||||
// @count - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]' 4
|
||||
// @count - '//*[@id="trait-implementations-list"]//*[@class="impl"]' 1
|
||||
// @count - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]' 4
|
||||
pub struct Foo<T> {
|
||||
field: T,
|
||||
}
|
||||
|
|
|
@ -3,10 +3,10 @@ pub struct Inner<T: Copy> {
|
|||
}
|
||||
|
||||
// @has negative/struct.Outer.html
|
||||
// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//code' "impl<T> !Send for \
|
||||
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//code' "impl<T> !Send for \
|
||||
// Outer<T>"
|
||||
//
|
||||
// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//code' "impl<T> \
|
||||
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//code' "impl<T> \
|
||||
// !Sync for Outer<T>"
|
||||
pub struct Outer<T: Copy> {
|
||||
inner_field: Inner<T>,
|
||||
|
|
|
@ -9,10 +9,10 @@ where
|
|||
}
|
||||
|
||||
// @has nested/struct.Foo.html
|
||||
// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//code' 'impl<T> Send for \
|
||||
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//code' 'impl<T> Send for \
|
||||
// Foo<T> where T: Copy'
|
||||
//
|
||||
// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//code' \
|
||||
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//code' \
|
||||
// 'impl<T> Sync for Foo<T> where T: Sync'
|
||||
pub struct Foo<T> {
|
||||
inner_field: Inner<T>,
|
||||
|
|
|
@ -9,7 +9,7 @@ where
|
|||
}
|
||||
|
||||
// @has no_redundancy/struct.Outer.html
|
||||
// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//code' "impl<T> Send for \
|
||||
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//code' "impl<T> Send for \
|
||||
// Outer<T> where T: Copy + Send"
|
||||
pub struct Outer<T> {
|
||||
inner_field: Inner<T>,
|
||||
|
|
|
@ -23,10 +23,10 @@ where
|
|||
}
|
||||
|
||||
// @has project/struct.Foo.html
|
||||
// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//code' "impl<'c, K> Send \
|
||||
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//code' "impl<'c, K> Send \
|
||||
// for Foo<'c, K> where K: MyTrait<MyItem = bool>, 'c: 'static"
|
||||
//
|
||||
// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//code' "impl<'c, K> Sync \
|
||||
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//code' "impl<'c, K> Sync \
|
||||
// for Foo<'c, K> where K: MyTrait, <K as MyTrait>::MyItem: OtherTrait, 'c: 'static,"
|
||||
pub struct Foo<'c, K: 'c> {
|
||||
inner_field: Inner<'c, K>,
|
||||
|
|
|
@ -23,7 +23,7 @@ impl<T> Pattern for Wrapper<T> {
|
|||
|
||||
|
||||
// @has self_referential/struct.WriteAndThen.html
|
||||
// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//code' "impl<P1> Send for \
|
||||
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//code' "impl<P1> Send for \
|
||||
// WriteAndThen<P1> where <P1 as Pattern>::Value: Send"
|
||||
pub struct WriteAndThen<P1>(pub P1::Value,pub <Constrain<P1, Wrapper<P1::Value>> as Pattern>::Value)
|
||||
where P1: Pattern;
|
||||
|
|
|
@ -3,7 +3,7 @@ pub trait OwnedTrait<'a> {
|
|||
}
|
||||
|
||||
// @has static_region/struct.Owned.html
|
||||
// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//code' "impl<T> Send for \
|
||||
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//code' "impl<T> Send for \
|
||||
// Owned<T> where <T as OwnedTrait<'static>>::Reader: Send"
|
||||
pub struct Owned<T> where T: OwnedTrait<'static> {
|
||||
marker: <T as OwnedTrait<'static>>::Reader,
|
||||
|
|
15
src/test/ui/associated-type-bounds/issue-81193.rs
Normal file
15
src/test/ui/associated-type-bounds/issue-81193.rs
Normal file
|
@ -0,0 +1,15 @@
|
|||
// check-pass
|
||||
|
||||
#![feature(associated_type_bounds)]
|
||||
|
||||
trait A<'a, 'b> {}
|
||||
|
||||
trait B<'a, 'b, 'c> {}
|
||||
|
||||
fn err<'u, 'a, F>()
|
||||
where
|
||||
for<'b> F: Iterator<Item: for<'c> B<'a, 'b, 'c> + for<'c> A<'a, 'c>>,
|
||||
{
|
||||
}
|
||||
|
||||
fn main() {}
|
39
src/test/ui/associated-type-bounds/issue-83017.rs
Normal file
39
src/test/ui/associated-type-bounds/issue-83017.rs
Normal file
|
@ -0,0 +1,39 @@
|
|||
#![feature(associated_type_bounds)]
|
||||
|
||||
trait TraitA<'a> {
|
||||
type AsA;
|
||||
}
|
||||
|
||||
trait TraitB<'a, 'b> {
|
||||
type AsB;
|
||||
}
|
||||
|
||||
trait TraitC<'a, 'b, 'c> {}
|
||||
|
||||
struct X;
|
||||
|
||||
impl<'a, 'b, 'c> TraitC<'a, 'b, 'c> for X {}
|
||||
|
||||
struct Y;
|
||||
|
||||
impl<'a, 'b> TraitB<'a, 'b> for Y {
|
||||
type AsB = X;
|
||||
}
|
||||
|
||||
struct Z;
|
||||
|
||||
impl<'a> TraitA<'a> for Z {
|
||||
type AsA = Y;
|
||||
}
|
||||
|
||||
fn foo<T>()
|
||||
where
|
||||
for<'a> T: TraitA<'a, AsA: for<'b> TraitB<'a, 'b, AsB: for<'c> TraitC<'a, 'b, 'c>>>,
|
||||
{
|
||||
}
|
||||
|
||||
fn main() {
|
||||
foo::<Z>();
|
||||
//~^ ERROR: the trait bound `for<'a, 'b> <Z as TraitA<'a>>::AsA: TraitB<'a, 'b>` is not satisfied
|
||||
//~| ERROR: the trait bound `for<'a, 'b, 'c> <<Z as TraitA<'a>>::AsA as TraitB<'a, 'b>>::AsB: TraitC<'a, 'b, 'c>` is not satisfied
|
||||
}
|
27
src/test/ui/associated-type-bounds/issue-83017.stderr
Normal file
27
src/test/ui/associated-type-bounds/issue-83017.stderr
Normal file
|
@ -0,0 +1,27 @@
|
|||
error[E0277]: the trait bound `for<'a, 'b> <Z as TraitA<'a>>::AsA: TraitB<'a, 'b>` is not satisfied
|
||||
--> $DIR/issue-83017.rs:36:5
|
||||
|
|
||||
LL | fn foo<T>()
|
||||
| --- required by a bound in this
|
||||
LL | where
|
||||
LL | for<'a> T: TraitA<'a, AsA: for<'b> TraitB<'a, 'b, AsB: for<'c> TraitC<'a, 'b, 'c>>>,
|
||||
| ------------------------------------------------------- required by this bound in `foo`
|
||||
...
|
||||
LL | foo::<Z>();
|
||||
| ^^^^^^^^ the trait `for<'a, 'b> TraitB<'a, 'b>` is not implemented for `<Z as TraitA<'a>>::AsA`
|
||||
|
||||
error[E0277]: the trait bound `for<'a, 'b, 'c> <<Z as TraitA<'a>>::AsA as TraitB<'a, 'b>>::AsB: TraitC<'a, 'b, 'c>` is not satisfied
|
||||
--> $DIR/issue-83017.rs:36:5
|
||||
|
|
||||
LL | fn foo<T>()
|
||||
| --- required by a bound in this
|
||||
LL | where
|
||||
LL | for<'a> T: TraitA<'a, AsA: for<'b> TraitB<'a, 'b, AsB: for<'c> TraitC<'a, 'b, 'c>>>,
|
||||
| -------------------------- required by this bound in `foo`
|
||||
...
|
||||
LL | foo::<Z>();
|
||||
| ^^^^^^^^ the trait `for<'a, 'b, 'c> TraitC<'a, 'b, 'c>` is not implemented for `<<Z as TraitA<'a>>::AsA as TraitB<'a, 'b>>::AsB`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
45
src/test/ui/specialization/issue-33017.rs
Normal file
45
src/test/ui/specialization/issue-33017.rs
Normal file
|
@ -0,0 +1,45 @@
|
|||
// Test to ensure that trait bounds are propertly
|
||||
// checked on specializable associated types
|
||||
|
||||
#![allow(incomplete_features)]
|
||||
#![feature(specialization)]
|
||||
|
||||
trait UncheckedCopy: Sized {
|
||||
type Output: From<Self> + Copy + Into<Self>;
|
||||
}
|
||||
|
||||
impl<T> UncheckedCopy for T {
|
||||
default type Output = Self;
|
||||
//~^ ERROR: the trait bound `T: Copy` is not satisfied
|
||||
}
|
||||
|
||||
fn unchecked_copy<T: UncheckedCopy>(other: &T::Output) -> T {
|
||||
(*other).into()
|
||||
}
|
||||
|
||||
fn bug(origin: String) {
|
||||
// Turn the String into it's Output type...
|
||||
// Which we can just do by `.into()`, the assoc type states `From<Self>`.
|
||||
let origin_output = origin.into();
|
||||
|
||||
// Make a copy of String::Output, which is a String...
|
||||
let mut copy: String = unchecked_copy::<String>(&origin_output);
|
||||
|
||||
// Turn the Output type into a String again,
|
||||
// Which we can just do by `.into()`, the assoc type states `Into<Self>`.
|
||||
let mut origin: String = origin_output.into();
|
||||
|
||||
// assert both Strings use the same buffer.
|
||||
assert_eq!(copy.as_ptr(), origin.as_ptr());
|
||||
|
||||
// Any use of the copy we made becomes invalid,
|
||||
drop(origin);
|
||||
|
||||
// OH NO! UB UB UB UB!
|
||||
copy.push_str(" world!");
|
||||
println!("{}", copy);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
bug(String::from("hello"));
|
||||
}
|
17
src/test/ui/specialization/issue-33017.stderr
Normal file
17
src/test/ui/specialization/issue-33017.stderr
Normal file
|
@ -0,0 +1,17 @@
|
|||
error[E0277]: the trait bound `T: Copy` is not satisfied
|
||||
--> $DIR/issue-33017.rs:12:5
|
||||
|
|
||||
LL | type Output: From<Self> + Copy + Into<Self>;
|
||||
| ---- required by this bound in `UncheckedCopy::Output`
|
||||
...
|
||||
LL | default type Output = Self;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `T`
|
||||
|
|
||||
help: consider restricting type parameter `T`
|
||||
|
|
||||
LL | impl<T: std::marker::Copy> UncheckedCopy for T {
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
19
src/test/ui/specialization/issue-51892.rs
Normal file
19
src/test/ui/specialization/issue-51892.rs
Normal file
|
@ -0,0 +1,19 @@
|
|||
#![allow(incomplete_features)]
|
||||
#![feature(const_generics)]
|
||||
#![feature(const_evaluatable_checked)]
|
||||
#![feature(specialization)]
|
||||
|
||||
pub trait Trait {
|
||||
type Type;
|
||||
}
|
||||
|
||||
impl<T: ?Sized> Trait for T {
|
||||
default type Type = [u8; 1];
|
||||
}
|
||||
|
||||
impl<T: Trait> Trait for *const T {
|
||||
type Type = [u8; std::mem::size_of::<<T as Trait>::Type>()];
|
||||
//~^ ERROR: unconstrained generic constant
|
||||
}
|
||||
|
||||
fn main() {}
|
10
src/test/ui/specialization/issue-51892.stderr
Normal file
10
src/test/ui/specialization/issue-51892.stderr
Normal file
|
@ -0,0 +1,10 @@
|
|||
error: unconstrained generic constant
|
||||
--> $DIR/issue-51892.rs:15:5
|
||||
|
|
||||
LL | type Type = [u8; std::mem::size_of::<<T as Trait>::Type>()];
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: try adding a `where` bound using this expression: `where [(); std::mem::size_of::<<T as Trait>::Type>()]:`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
Loading…
Reference in a new issue