mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-01 06:51:58 +00:00
Auto merge of #91288 - matthiaskrgr:rollup-yp5h41r, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - #83791 (Weaken guarantee around advancing underlying iterators in zip) - #90995 (Document non-guarantees for Hash) - #91057 (Expand `available_parallelism` docs in anticipation of cgroup quota support) - #91062 (rustdoc: Consolidate static-file replacement mechanism) - #91208 (Account for incorrect `where T::Assoc = Ty` bound) - #91266 (Use non-generic inner function for pointer formatting) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
686e313a9a
@ -23,7 +23,7 @@ use rustc_span::symbol::{kw, sym, Ident};
|
||||
use rustc_span::Span;
|
||||
use rustc_target::spec::abi;
|
||||
use std::mem;
|
||||
use std::ops::DerefMut;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
|
||||
const MORE_EXTERN: &str =
|
||||
"for more information, visit https://doc.rust-lang.org/std/keyword.extern.html";
|
||||
@ -1714,6 +1714,53 @@ fn deny_equality_constraints(
|
||||
}
|
||||
}
|
||||
}
|
||||
// Given `A: Foo, A::Bar = RhsTy`, suggest `A: Foo<Bar = RhsTy>`.
|
||||
if let TyKind::Path(None, full_path) = &predicate.lhs_ty.kind {
|
||||
if let [potential_param, potential_assoc] = &full_path.segments[..] {
|
||||
for param in &generics.params {
|
||||
if param.ident == potential_param.ident {
|
||||
for bound in ¶m.bounds {
|
||||
if let ast::GenericBound::Trait(trait_ref, TraitBoundModifier::None) = bound
|
||||
{
|
||||
if let [trait_segment] = &trait_ref.trait_ref.path.segments[..] {
|
||||
let assoc = pprust::path_to_string(&ast::Path::from_ident(
|
||||
potential_assoc.ident,
|
||||
));
|
||||
let ty = pprust::ty_to_string(&predicate.rhs_ty);
|
||||
let (args, span) = match &trait_segment.args {
|
||||
Some(args) => match args.deref() {
|
||||
ast::GenericArgs::AngleBracketed(args) => {
|
||||
let Some(arg) = args.args.last() else {
|
||||
continue;
|
||||
};
|
||||
(
|
||||
format!(", {} = {}", assoc, ty),
|
||||
arg.span().shrink_to_hi(),
|
||||
)
|
||||
}
|
||||
_ => continue,
|
||||
},
|
||||
None => (
|
||||
format!("<{} = {}>", assoc, ty),
|
||||
trait_segment.span().shrink_to_hi(),
|
||||
),
|
||||
};
|
||||
err.multipart_suggestion(
|
||||
&format!(
|
||||
"if `{}::{}` is an associated type you're trying to set, \
|
||||
use the associated type binding syntax",
|
||||
trait_segment.ident, potential_assoc.ident,
|
||||
),
|
||||
vec![(span, args), (predicate.span, String::new())],
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
err.note(
|
||||
"see issue #20041 <https://github.com/rust-lang/rust/issues/20041> for more information",
|
||||
);
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#![feature(iter_is_partitioned)]
|
||||
#![feature(box_patterns)]
|
||||
#![feature(let_else)]
|
||||
#![recursion_limit = "256"]
|
||||
|
||||
pub mod ast_validation;
|
||||
|
@ -2186,28 +2186,34 @@ impl Display for char {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized> Pointer for *const T {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
|
||||
let old_width = f.width;
|
||||
let old_flags = f.flags;
|
||||
/// Since the formatting will be identical for all pointer types, use a non-monomorphized
|
||||
/// implementation for the actual formatting to reduce the amount of codegen work needed
|
||||
fn inner(ptr: *const (), f: &mut Formatter<'_>) -> Result {
|
||||
let old_width = f.width;
|
||||
let old_flags = f.flags;
|
||||
|
||||
// The alternate flag is already treated by LowerHex as being special-
|
||||
// it denotes whether to prefix with 0x. We use it to work out whether
|
||||
// or not to zero extend, and then unconditionally set it to get the
|
||||
// prefix.
|
||||
if f.alternate() {
|
||||
f.flags |= 1 << (FlagV1::SignAwareZeroPad as u32);
|
||||
// The alternate flag is already treated by LowerHex as being special-
|
||||
// it denotes whether to prefix with 0x. We use it to work out whether
|
||||
// or not to zero extend, and then unconditionally set it to get the
|
||||
// prefix.
|
||||
if f.alternate() {
|
||||
f.flags |= 1 << (FlagV1::SignAwareZeroPad as u32);
|
||||
|
||||
if f.width.is_none() {
|
||||
f.width = Some((usize::BITS / 4) as usize + 2);
|
||||
if f.width.is_none() {
|
||||
f.width = Some((usize::BITS / 4) as usize + 2);
|
||||
}
|
||||
}
|
||||
f.flags |= 1 << (FlagV1::Alternate as u32);
|
||||
|
||||
let ret = LowerHex::fmt(&(ptr as usize), f);
|
||||
|
||||
f.width = old_width;
|
||||
f.flags = old_flags;
|
||||
|
||||
ret
|
||||
}
|
||||
f.flags |= 1 << (FlagV1::Alternate as u32);
|
||||
|
||||
let ret = LowerHex::fmt(&(*self as *const () as usize), f);
|
||||
|
||||
f.width = old_width;
|
||||
f.flags = old_flags;
|
||||
|
||||
ret
|
||||
inner(*self as *const (), f)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -164,6 +164,19 @@ mod sip;
|
||||
/// `0xFF` byte to the `Hasher` so that the values `("ab", "c")` and `("a",
|
||||
/// "bc")` hash differently.
|
||||
///
|
||||
/// ## Portability
|
||||
///
|
||||
/// Due to differences in endianness and type sizes, data fed by `Hash` to a `Hasher`
|
||||
/// should not be considered portable across platforms. Additionally the data passed by most
|
||||
/// standard library types should not be considered stable between compiler versions.
|
||||
///
|
||||
/// This means tests shouldn't probe hard-coded hash values or data fed to a `Hasher` and
|
||||
/// instead should check consistency with `Eq`.
|
||||
///
|
||||
/// Serialization formats intended to be portable between platforms or compiler versions should
|
||||
/// either avoid encoding hashes or only rely on `Hash` and `Hasher` implementations that
|
||||
/// provide additional guarantees.
|
||||
///
|
||||
/// [`HashMap`]: ../../std/collections/struct.HashMap.html
|
||||
/// [`HashSet`]: ../../std/collections/struct.HashSet.html
|
||||
/// [`hash`]: Hash::hash
|
||||
|
@ -458,8 +458,10 @@ pub trait Iterator {
|
||||
/// In other words, it zips two iterators together, into a single one.
|
||||
///
|
||||
/// If either iterator returns [`None`], [`next`] from the zipped iterator
|
||||
/// will return [`None`]. If the first iterator returns [`None`], `zip` will
|
||||
/// short-circuit and `next` will not be called on the second iterator.
|
||||
/// will return [`None`].
|
||||
/// If the zipped iterator has no more elements to return then each further attempt to advance
|
||||
/// it will first try to advance the first iterator at most one time and if it still yielded an item
|
||||
/// try to advance the second iterator at most one time.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -1460,9 +1460,12 @@ fn _assert_sync_and_send() {
|
||||
/// The purpose of this API is to provide an easy and portable way to query
|
||||
/// the default amount of parallelism the program should use. Among other things it
|
||||
/// does not expose information on NUMA regions, does not account for
|
||||
/// differences in (co)processor capabilities, and will not modify the program's
|
||||
/// global state in order to more accurately query the amount of available
|
||||
/// parallelism.
|
||||
/// differences in (co)processor capabilities or current system load,
|
||||
/// and will not modify the program's global state in order to more accurately
|
||||
/// query the amount of available parallelism.
|
||||
///
|
||||
/// Where both fixed steady-state and burst limits are available the steady-state
|
||||
/// capacity will be used to ensure more predictable latencies.
|
||||
///
|
||||
/// Resource limits can be changed during the runtime of a program, therefore the value is
|
||||
/// not cached and instead recomputed every time this function is called. It should not be
|
||||
|
@ -552,7 +552,7 @@ impl Options {
|
||||
))
|
||||
.emit();
|
||||
}
|
||||
themes.push(StylePath { path: theme_file, disabled: true });
|
||||
themes.push(StylePath { path: theme_file });
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -39,7 +39,10 @@ macro_rules! try_none {
|
||||
match $e {
|
||||
Some(e) => e,
|
||||
None => {
|
||||
return Err(Error::new(io::Error::new(io::ErrorKind::Other, "not found"), $file));
|
||||
return Err(<crate::error::Error as crate::docfs::PathError>::new(
|
||||
io::Error::new(io::ErrorKind::Other, "not found"),
|
||||
$file,
|
||||
));
|
||||
}
|
||||
}
|
||||
}};
|
||||
|
@ -2,8 +2,8 @@ use std::path::PathBuf;
|
||||
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
|
||||
use crate::error::Error;
|
||||
use crate::externalfiles::ExternalHtml;
|
||||
use crate::html::escape::Escape;
|
||||
use crate::html::format::{Buffer, Print};
|
||||
use crate::html::render::{ensure_trailing_slash, StylePath};
|
||||
|
||||
@ -50,10 +50,11 @@ struct PageLayout<'a> {
|
||||
static_root_path: &'a str,
|
||||
page: &'a Page<'a>,
|
||||
layout: &'a Layout,
|
||||
style_files: String,
|
||||
themes: Vec<String>,
|
||||
sidebar: String,
|
||||
content: String,
|
||||
krate_with_trailing_slash: String,
|
||||
crate rustdoc_version: &'a str,
|
||||
}
|
||||
|
||||
crate fn render<T: Print, S: Print>(
|
||||
@ -66,29 +67,24 @@ crate fn render<T: Print, S: Print>(
|
||||
) -> String {
|
||||
let static_root_path = page.get_static_root_path();
|
||||
let krate_with_trailing_slash = ensure_trailing_slash(&layout.krate).to_string();
|
||||
let style_files = style_files
|
||||
let mut themes: Vec<String> = style_files
|
||||
.iter()
|
||||
.filter_map(|t| t.path.file_stem().map(|stem| (stem, t.disabled)))
|
||||
.filter_map(|t| t.0.to_str().map(|path| (path, t.1)))
|
||||
.map(|t| {
|
||||
format!(
|
||||
r#"<link rel="stylesheet" type="text/css" href="{}.css" {} {}>"#,
|
||||
Escape(&format!("{}{}{}", static_root_path, t.0, page.resource_suffix)),
|
||||
if t.1 { "disabled" } else { "" },
|
||||
if t.0 == "light" { "id=\"themeStyle\"" } else { "" }
|
||||
)
|
||||
})
|
||||
.collect::<String>();
|
||||
.map(StylePath::basename)
|
||||
.collect::<Result<_, Error>>()
|
||||
.unwrap_or_default();
|
||||
themes.sort();
|
||||
let rustdoc_version = rustc_interface::util::version_str().unwrap_or("unknown version");
|
||||
let content = Buffer::html().to_display(t); // Note: This must happen before making the sidebar.
|
||||
let sidebar = Buffer::html().to_display(sidebar);
|
||||
let teractx = tera::Context::from_serialize(PageLayout {
|
||||
static_root_path,
|
||||
page,
|
||||
layout,
|
||||
style_files,
|
||||
themes,
|
||||
sidebar,
|
||||
content,
|
||||
krate_with_trailing_slash,
|
||||
rustdoc_version,
|
||||
})
|
||||
.unwrap();
|
||||
templates.render("page.html", &teractx).unwrap()
|
||||
|
@ -504,9 +504,9 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
|
||||
// by the browser as the theme stylesheet. The theme system (hackily) works by
|
||||
// changing the href to this stylesheet. All other themes are disabled to
|
||||
// prevent rule conflicts
|
||||
scx.style_files.push(StylePath { path: PathBuf::from("light.css"), disabled: false });
|
||||
scx.style_files.push(StylePath { path: PathBuf::from("dark.css"), disabled: true });
|
||||
scx.style_files.push(StylePath { path: PathBuf::from("ayu.css"), disabled: true });
|
||||
scx.style_files.push(StylePath { path: PathBuf::from("light.css") });
|
||||
scx.style_files.push(StylePath { path: PathBuf::from("dark.css") });
|
||||
scx.style_files.push(StylePath { path: PathBuf::from("ayu.css") });
|
||||
|
||||
let dst = output;
|
||||
scx.ensure_dir(&dst)?;
|
||||
@ -596,9 +596,13 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
|
||||
page.description = "Settings of Rustdoc";
|
||||
page.root_path = "./";
|
||||
|
||||
let mut style_files = self.shared.style_files.clone();
|
||||
let sidebar = "<h2 class=\"location\">Settings</h2><div class=\"sidebar-elems\"></div>";
|
||||
style_files.push(StylePath { path: PathBuf::from("settings.css"), disabled: false });
|
||||
let theme_names: Vec<String> = self
|
||||
.shared
|
||||
.style_files
|
||||
.iter()
|
||||
.map(StylePath::basename)
|
||||
.collect::<Result<_, Error>>()?;
|
||||
let v = layout::render(
|
||||
&self.shared.templates,
|
||||
&self.shared.layout,
|
||||
@ -607,9 +611,9 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
|
||||
settings(
|
||||
self.shared.static_root_path.as_deref().unwrap_or("./"),
|
||||
&self.shared.resource_suffix,
|
||||
&self.shared.style_files,
|
||||
theme_names,
|
||||
)?,
|
||||
&style_files,
|
||||
&self.shared.style_files,
|
||||
);
|
||||
self.shared.fs.write(settings_file, v)?;
|
||||
if let Some(ref redirections) = self.shared.redirections {
|
||||
|
@ -64,7 +64,6 @@ use serde::ser::SerializeSeq;
|
||||
use serde::{Serialize, Serializer};
|
||||
|
||||
use crate::clean::{self, ItemId, RenderedLink, SelfTy};
|
||||
use crate::docfs::PathError;
|
||||
use crate::error::Error;
|
||||
use crate::formats::cache::Cache;
|
||||
use crate::formats::item_type::ItemType;
|
||||
@ -173,8 +172,12 @@ impl Serialize for TypeWithKind {
|
||||
crate struct StylePath {
|
||||
/// The path to the theme
|
||||
crate path: PathBuf,
|
||||
/// What the `disabled` attribute should be set to in the HTML tag
|
||||
crate disabled: bool,
|
||||
}
|
||||
|
||||
impl StylePath {
|
||||
pub fn basename(&self) -> Result<String, Error> {
|
||||
Ok(try_none!(try_none!(self.path.file_stem(), &self.path).to_str(), &self.path).to_string())
|
||||
}
|
||||
}
|
||||
|
||||
fn write_srclink(cx: &Context<'_>, item: &clean::Item, buf: &mut Buffer) {
|
||||
@ -353,7 +356,7 @@ enum Setting {
|
||||
js_data_name: &'static str,
|
||||
description: &'static str,
|
||||
default_value: &'static str,
|
||||
options: Vec<(String, String)>,
|
||||
options: Vec<String>,
|
||||
},
|
||||
}
|
||||
|
||||
@ -393,10 +396,9 @@ impl Setting {
|
||||
options
|
||||
.iter()
|
||||
.map(|opt| format!(
|
||||
"<option value=\"{}\" {}>{}</option>",
|
||||
opt.0,
|
||||
if opt.0 == default_value { "selected" } else { "" },
|
||||
opt.1,
|
||||
"<option value=\"{name}\" {}>{name}</option>",
|
||||
if opt == default_value { "selected" } else { "" },
|
||||
name = opt,
|
||||
))
|
||||
.collect::<String>(),
|
||||
root_path,
|
||||
@ -421,18 +423,7 @@ impl<T: Into<Setting>> From<(&'static str, Vec<T>)> for Setting {
|
||||
}
|
||||
}
|
||||
|
||||
fn settings(root_path: &str, suffix: &str, themes: &[StylePath]) -> Result<String, Error> {
|
||||
let theme_names: Vec<(String, String)> = themes
|
||||
.iter()
|
||||
.map(|entry| {
|
||||
let theme =
|
||||
try_none!(try_none!(entry.path.file_stem(), &entry.path).to_str(), &entry.path)
|
||||
.to_string();
|
||||
|
||||
Ok((theme.clone(), theme))
|
||||
})
|
||||
.collect::<Result<_, Error>>()?;
|
||||
|
||||
fn settings(root_path: &str, suffix: &str, theme_names: Vec<String>) -> Result<String, Error> {
|
||||
// (id, explanation, default value)
|
||||
let settings: &[Setting] = &[
|
||||
(
|
||||
@ -469,10 +460,11 @@ fn settings(root_path: &str, suffix: &str, themes: &[StylePath]) -> Result<Strin
|
||||
<span class=\"in-band\">Rustdoc settings</span>\
|
||||
</h1>\
|
||||
<div class=\"settings\">{}</div>\
|
||||
<script src=\"{}settings{}.js\"></script>",
|
||||
<link rel=\"stylesheet\" href=\"{root_path}settings{suffix}.css\">\
|
||||
<script src=\"{root_path}settings{suffix}.js\"></script>",
|
||||
settings.iter().map(|s| s.display(root_path, suffix)).collect::<String>(),
|
||||
root_path,
|
||||
suffix
|
||||
root_path = root_path,
|
||||
suffix = suffix
|
||||
))
|
||||
}
|
||||
|
||||
|
@ -181,42 +181,34 @@ pub(super) fn write_shared(
|
||||
cx.write_shared(SharedResource::InvocationSpecific { basename: p }, content, &options.emit)
|
||||
};
|
||||
|
||||
fn add_background_image_to_css(
|
||||
cx: &Context<'_>,
|
||||
css: &mut String,
|
||||
rule: &str,
|
||||
file: &'static str,
|
||||
) {
|
||||
css.push_str(&format!(
|
||||
"{} {{ background-image: url({}); }}",
|
||||
rule,
|
||||
SharedResource::ToolchainSpecific { basename: file }
|
||||
// Given "foo.svg", return e.g. "url(\"foo1.58.0.svg\")"
|
||||
fn ver_url(cx: &Context<'_>, basename: &'static str) -> String {
|
||||
format!(
|
||||
"url(\"{}\")",
|
||||
SharedResource::ToolchainSpecific { basename }
|
||||
.path(cx)
|
||||
.file_name()
|
||||
.unwrap()
|
||||
.to_str()
|
||||
.unwrap()
|
||||
))
|
||||
)
|
||||
}
|
||||
|
||||
// Add all the static files. These may already exist, but we just
|
||||
// overwrite them anyway to make sure that they're fresh and up-to-date.
|
||||
let mut rustdoc_css = static_files::RUSTDOC_CSS.to_owned();
|
||||
add_background_image_to_css(
|
||||
// We use the AUTOREPLACE mechanism to inject into our static JS and CSS certain
|
||||
// values that are only known at doc build time. Since this mechanism is somewhat
|
||||
// surprising when reading the code, please limit it to rustdoc.css.
|
||||
write_minify(
|
||||
"rustdoc.css",
|
||||
static_files::RUSTDOC_CSS
|
||||
.replace(
|
||||
"/* AUTOREPLACE: */url(\"toggle-minus.svg\")",
|
||||
&ver_url(cx, "toggle-minus.svg"),
|
||||
)
|
||||
.replace("/* AUTOREPLACE: */url(\"toggle-plus.svg\")", &ver_url(cx, "toggle-plus.svg"))
|
||||
.replace("/* AUTOREPLACE: */url(\"down-arrow.svg\")", &ver_url(cx, "down-arrow.svg")),
|
||||
cx,
|
||||
&mut rustdoc_css,
|
||||
"details.undocumented[open] > summary::before, \
|
||||
details.rustdoc-toggle[open] > summary::before, \
|
||||
details.rustdoc-toggle[open] > summary.hideme::before",
|
||||
"toggle-minus.svg",
|
||||
);
|
||||
add_background_image_to_css(
|
||||
cx,
|
||||
&mut rustdoc_css,
|
||||
"details.undocumented > summary::before, details.rustdoc-toggle > summary::before",
|
||||
"toggle-plus.svg",
|
||||
);
|
||||
write_minify("rustdoc.css", rustdoc_css, cx, options)?;
|
||||
options,
|
||||
)?;
|
||||
|
||||
// Add all the static files. These may already exist, but we just
|
||||
// overwrite them anyway to make sure that they're fresh and up-to-date.
|
||||
@ -228,12 +220,12 @@ pub(super) fn write_shared(
|
||||
let mut themes: FxHashSet<String> = FxHashSet::default();
|
||||
|
||||
for entry in &cx.shared.style_files {
|
||||
let theme = try_none!(try_none!(entry.path.file_stem(), &entry.path).to_str(), &entry.path);
|
||||
let theme = entry.basename()?;
|
||||
let extension =
|
||||
try_none!(try_none!(entry.path.extension(), &entry.path).to_str(), &entry.path);
|
||||
|
||||
// Handle the official themes
|
||||
match theme {
|
||||
match theme.as_str() {
|
||||
"light" => write_minify("light.css", static_files::themes::LIGHT, cx, options)?,
|
||||
"dark" => write_minify("dark.css", static_files::themes::DARK, cx, options)?,
|
||||
"ayu" => write_minify("ayu.css", static_files::themes::AYU, cx, options)?,
|
||||
@ -265,26 +257,7 @@ pub(super) fn write_shared(
|
||||
let mut themes: Vec<&String> = themes.iter().collect();
|
||||
themes.sort();
|
||||
|
||||
// FIXME: this should probably not be a toolchain file since it depends on `--theme`.
|
||||
// But it seems a shame to copy it over and over when it's almost always the same.
|
||||
// Maybe we can change the representation to move this out of main.js?
|
||||
write_minify(
|
||||
"main.js",
|
||||
static_files::MAIN_JS
|
||||
.replace(
|
||||
"/* INSERT THEMES HERE */",
|
||||
&format!(" = {}", serde_json::to_string(&themes).unwrap()),
|
||||
)
|
||||
.replace(
|
||||
"/* INSERT RUSTDOC_VERSION HERE */",
|
||||
&format!(
|
||||
"rustdoc {}",
|
||||
rustc_interface::util::version_str().unwrap_or("unknown version")
|
||||
),
|
||||
),
|
||||
cx,
|
||||
options,
|
||||
)?;
|
||||
write_minify("main.js", static_files::MAIN_JS, cx, options)?;
|
||||
write_minify("search.js", static_files::SEARCH_JS, cx, options)?;
|
||||
write_minify("settings.js", static_files::SETTINGS_JS, cx, options)?;
|
||||
|
||||
@ -292,18 +265,7 @@ pub(super) fn write_shared(
|
||||
write_minify("source-script.js", static_files::sidebar::SOURCE_SCRIPT, cx, options)?;
|
||||
}
|
||||
|
||||
{
|
||||
write_minify(
|
||||
"storage.js",
|
||||
format!(
|
||||
"var resourcesSuffix = \"{}\";{}",
|
||||
cx.shared.resource_suffix,
|
||||
static_files::STORAGE_JS
|
||||
),
|
||||
cx,
|
||||
options,
|
||||
)?;
|
||||
}
|
||||
write_minify("storage.js", static_files::STORAGE_JS, cx, options)?;
|
||||
|
||||
if cx.shared.layout.scrape_examples_extension {
|
||||
cx.write_minify(
|
||||
|
@ -828,6 +828,7 @@ h2.small-section-header > .anchor {
|
||||
background-color: transparent;
|
||||
background-size: 20px;
|
||||
background-position: calc(100% - 1px) 56%;
|
||||
background-image: /* AUTOREPLACE: */url("down-arrow.svg");
|
||||
}
|
||||
.search-container > .top-button {
|
||||
position: absolute;
|
||||
@ -1610,6 +1611,16 @@ details.rustdoc-toggle[open] > summary.hideme > span {
|
||||
display: none;
|
||||
}
|
||||
|
||||
details.undocumented[open] > summary::before,
|
||||
details.rustdoc-toggle[open] > summary::before,
|
||||
details.rustdoc-toggle[open] > summary.hideme::before {
|
||||
background-image: /* AUTOREPLACE: */url("toggle-minus.svg");
|
||||
}
|
||||
|
||||
details.undocumented > summary::before, details.rustdoc-toggle > summary::before {
|
||||
background-image: /* AUTOREPLACE: */url("toggle-plus.svg");
|
||||
}
|
||||
|
||||
details.rustdoc-toggle[open] > summary::before,
|
||||
details.rustdoc-toggle[open] > summary.hideme::before {
|
||||
width: 17px;
|
||||
|
@ -37,14 +37,29 @@ if (!DOMTokenList.prototype.remove) {
|
||||
};
|
||||
}
|
||||
|
||||
(function () {
|
||||
var rustdocVars = document.getElementById("rustdoc-vars");
|
||||
if (rustdocVars) {
|
||||
window.rootPath = rustdocVars.attributes["data-root-path"].value;
|
||||
window.currentCrate = rustdocVars.attributes["data-current-crate"].value;
|
||||
window.searchJS = rustdocVars.attributes["data-search-js"].value;
|
||||
window.searchIndexJS = rustdocVars.attributes["data-search-index-js"].value;
|
||||
// Get a value from the rustdoc-vars div, which is used to convey data from
|
||||
// Rust to the JS. If there is no such element, return null.
|
||||
function getVar(name) {
|
||||
var el = document.getElementById("rustdoc-vars");
|
||||
if (el) {
|
||||
return el.attributes["data-" + name].value;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Given a basename (e.g. "storage") and an extension (e.g. ".js"), return a URL
|
||||
// for a resource under the root-path, with the resource-suffix.
|
||||
function resourcePath(basename, extension) {
|
||||
return getVar("root-path") + basename + getVar("resource-suffix") + extension;
|
||||
}
|
||||
|
||||
|
||||
(function () {
|
||||
window.rootPath = getVar("root-path");
|
||||
window.currentCrate = getVar("current-crate");
|
||||
window.searchJS = resourcePath("search", ".js");
|
||||
window.searchIndexJS = resourcePath("search-index", ".js");
|
||||
var sidebarVars = document.getElementById("sidebar-vars");
|
||||
if (sidebarVars) {
|
||||
window.sidebarCurrent = {
|
||||
@ -115,7 +130,7 @@ function hideThemeButtonState() {
|
||||
(function () {
|
||||
var themeChoices = getThemesElement();
|
||||
var themePicker = getThemePickerElement();
|
||||
var availableThemes/* INSERT THEMES HERE */;
|
||||
var availableThemes = getVar("themes").split(",");
|
||||
|
||||
function switchThemeButtonState() {
|
||||
if (themeChoices.style.display === "block") {
|
||||
@ -980,7 +995,7 @@ function hideThemeButtonState() {
|
||||
var rustdoc_version = document.createElement("span");
|
||||
rustdoc_version.className = "bottom";
|
||||
var rustdoc_version_code = document.createElement("code");
|
||||
rustdoc_version_code.innerText = "/* INSERT RUSTDOC_VERSION HERE */";
|
||||
rustdoc_version_code.innerText = "rustdoc " + getVar("rustdoc-version");
|
||||
rustdoc_version.appendChild(rustdoc_version_code);
|
||||
|
||||
container.appendChild(rustdoc_version);
|
||||
|
@ -1,5 +1,3 @@
|
||||
// From rust:
|
||||
/* global resourcesSuffix */
|
||||
var darkThemes = ["dark", "ayu"];
|
||||
window.currentTheme = document.getElementById("themeStyle");
|
||||
window.mainTheme = document.getElementById("mainThemeStyle");
|
||||
@ -107,9 +105,8 @@ function getCurrentValue(name) {
|
||||
}
|
||||
|
||||
function switchTheme(styleElem, mainStyleElem, newTheme, saveTheme) {
|
||||
var fullBasicCss = "rustdoc" + resourcesSuffix + ".css";
|
||||
var fullNewTheme = newTheme + resourcesSuffix + ".css";
|
||||
var newHref = mainStyleElem.href.replace(fullBasicCss, fullNewTheme);
|
||||
var newHref = mainStyleElem.href.replace(
|
||||
/\/rustdoc([^/]*)\.css/, "/" + newTheme + "$1" + ".css");
|
||||
|
||||
// If this new value comes from a system setting or from the previously
|
||||
// saved theme, no need to save it.
|
||||
|
@ -12,7 +12,16 @@
|
||||
<link rel="stylesheet" type="text/css" {# -#}
|
||||
href="{{static_root_path | safe}}rustdoc{{page.resource_suffix}}.css" {# -#}
|
||||
id="mainThemeStyle"> {#- -#}
|
||||
{{- style_files | safe -}}
|
||||
{%- for theme in themes -%}
|
||||
<link rel="stylesheet" type="text/css" {# -#}
|
||||
href="{{static_root_path | safe}}{{theme}}{{page.resource_suffix}}.css" {#- -#}
|
||||
{%- if theme == "light" -%}
|
||||
id="themeStyle"
|
||||
{%- else -%}
|
||||
disabled
|
||||
{%- endif -%}
|
||||
>
|
||||
{%- endfor -%}
|
||||
<script id="default-settings" {# -#}
|
||||
{% for k, v in layout.default_settings %}
|
||||
data-{{k}}="{{v}}"
|
||||
@ -49,11 +58,6 @@
|
||||
href="{{static_root_path | safe}}favicon{{page.resource_suffix}}.svg"> {#- -#}
|
||||
{%- endif -%}
|
||||
{{- layout.external_html.in_header | safe -}}
|
||||
<style type="text/css"> {#- -#}
|
||||
#crate-search{ {#- -#}
|
||||
background-image:url("{{static_root_path | safe}}down-arrow{{page.resource_suffix}}.svg"); {#- -#}
|
||||
} {#- -#}
|
||||
</style> {#- -#}
|
||||
</head> {#- -#}
|
||||
<body class="rustdoc {{page.css_class}}"> {#- -#}
|
||||
<!--[if lte IE 11]> {#- -#}
|
||||
@ -114,8 +118,10 @@
|
||||
<div id="rustdoc-vars" {# -#}
|
||||
data-root-path="{{page.root_path | safe}}" {# -#}
|
||||
data-current-crate="{{layout.krate}}" {# -#}
|
||||
data-search-index-js="{{page.root_path | safe}}search-index{{page.resource_suffix}}.js" {# -#}
|
||||
data-search-js="{{static_root_path | safe}}search{{page.resource_suffix}}.js"> {#- -#}
|
||||
data-themes="{{themes | join(sep=",") }}" {# -#}
|
||||
data-resource-suffix="{{page.resource_suffix}}" {# -#}
|
||||
data-rustdoc-version="{{rustdoc_version}}" {# -#}
|
||||
> {#- -#}
|
||||
</div>
|
||||
</body> {#- -#}
|
||||
</html> {#- -#}
|
||||
|
@ -3,7 +3,7 @@
|
||||
// @has static_root_path/struct.SomeStruct.html
|
||||
// @matches - '"/cache/main\.js"'
|
||||
// @!matches - '"\.\./main\.js"'
|
||||
// @matches - '"\.\./search-index\.js"'
|
||||
// @matches - 'data-root-path="\.\./"'
|
||||
// @!matches - '"/cache/search-index\.js"'
|
||||
pub struct SomeStruct;
|
||||
|
||||
|
15
src/test/ui/generic-associated-types/equality-bound.rs
Normal file
15
src/test/ui/generic-associated-types/equality-bound.rs
Normal file
@ -0,0 +1,15 @@
|
||||
fn sum<I: Iterator<Item = ()>>(i: I) -> i32 where I::Item = i32 {
|
||||
//~^ ERROR equality constraints are not yet supported in `where` clauses
|
||||
panic!()
|
||||
}
|
||||
fn sum2<I: Iterator>(i: I) -> i32 where I::Item = i32 {
|
||||
//~^ ERROR equality constraints are not yet supported in `where` clauses
|
||||
panic!()
|
||||
}
|
||||
fn sum3<J: Iterator>(i: J) -> i32 where I::Item = i32 {
|
||||
//~^ ERROR equality constraints are not yet supported in `where` clauses
|
||||
//~| ERROR failed to resolve: use of undeclared type `I`
|
||||
panic!()
|
||||
}
|
||||
|
||||
fn main() {}
|
43
src/test/ui/generic-associated-types/equality-bound.stderr
Normal file
43
src/test/ui/generic-associated-types/equality-bound.stderr
Normal file
@ -0,0 +1,43 @@
|
||||
error: equality constraints are not yet supported in `where` clauses
|
||||
--> $DIR/equality-bound.rs:1:51
|
||||
|
|
||||
LL | fn sum<I: Iterator<Item = ()>>(i: I) -> i32 where I::Item = i32 {
|
||||
| ^^^^^^^^^^^^^ not supported
|
||||
|
|
||||
= note: see issue #20041 <https://github.com/rust-lang/rust/issues/20041> for more information
|
||||
help: if `Iterator::Item` is an associated type you're trying to set, use the associated type binding syntax
|
||||
|
|
||||
LL - fn sum<I: Iterator<Item = ()>>(i: I) -> i32 where I::Item = i32 {
|
||||
LL + fn sum<I: Iterator<Item = (), Item = i32>>(i: I) -> i32 where {
|
||||
|
|
||||
|
||||
error: equality constraints are not yet supported in `where` clauses
|
||||
--> $DIR/equality-bound.rs:5:41
|
||||
|
|
||||
LL | fn sum2<I: Iterator>(i: I) -> i32 where I::Item = i32 {
|
||||
| ^^^^^^^^^^^^^ not supported
|
||||
|
|
||||
= note: see issue #20041 <https://github.com/rust-lang/rust/issues/20041> for more information
|
||||
help: if `Iterator::Item` is an associated type you're trying to set, use the associated type binding syntax
|
||||
|
|
||||
LL - fn sum2<I: Iterator>(i: I) -> i32 where I::Item = i32 {
|
||||
LL + fn sum2<I: Iterator<Item = i32>>(i: I) -> i32 where {
|
||||
|
|
||||
|
||||
error: equality constraints are not yet supported in `where` clauses
|
||||
--> $DIR/equality-bound.rs:9:41
|
||||
|
|
||||
LL | fn sum3<J: Iterator>(i: J) -> i32 where I::Item = i32 {
|
||||
| ^^^^^^^^^^^^^ not supported
|
||||
|
|
||||
= note: see issue #20041 <https://github.com/rust-lang/rust/issues/20041> for more information
|
||||
|
||||
error[E0433]: failed to resolve: use of undeclared type `I`
|
||||
--> $DIR/equality-bound.rs:9:41
|
||||
|
|
||||
LL | fn sum3<J: Iterator>(i: J) -> i32 where I::Item = i32 {
|
||||
| ^ use of undeclared type `I`
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0433`.
|
@ -34,11 +34,12 @@ impl<B: std::ops::Add<Output = B>> Add for D<B> {
|
||||
|
||||
struct E<B>(B);
|
||||
|
||||
impl<B: Add> Add for E<B> where B: Add<Output = B> {
|
||||
impl<B: Add> Add for E<B> where B: Add<Output = B>, B: Add<Output = B> {
|
||||
//~^ ERROR equality constraints are not yet supported in `where` clauses
|
||||
type Output = Self;
|
||||
|
||||
fn add(self, rhs: Self) -> Self {
|
||||
Self(self.0 + rhs.0)
|
||||
Self(self.0 + rhs.0) //~ ERROR mismatched types
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -34,11 +34,12 @@ impl<B> Add for D<B> {
|
||||
|
||||
struct E<B>(B);
|
||||
|
||||
impl<B: Add> Add for E<B> where B: Add<Output = B> {
|
||||
impl<B: Add> Add for E<B> where <B as Add>::Output = B {
|
||||
//~^ ERROR equality constraints are not yet supported in `where` clauses
|
||||
type Output = Self;
|
||||
|
||||
fn add(self, rhs: Self) -> Self {
|
||||
Self(self.0 + rhs.0)
|
||||
Self(self.0 + rhs.0) //~ ERROR mismatched types
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,15 @@
|
||||
error: equality constraints are not yet supported in `where` clauses
|
||||
--> $DIR/missing-bounds.rs:37:33
|
||||
|
|
||||
LL | impl<B: Add> Add for E<B> where <B as Add>::Output = B {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ not supported
|
||||
|
|
||||
= note: see issue #20041 <https://github.com/rust-lang/rust/issues/20041> for more information
|
||||
help: if `Output` is an associated type you're trying to set, use the associated type binding syntax
|
||||
|
|
||||
LL | impl<B: Add> Add for E<B> where B: Add<Output = B> {
|
||||
| ~~~~~~~~~~~~~~~~~~
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/missing-bounds.rs:11:11
|
||||
|
|
||||
@ -43,7 +55,23 @@ help: consider restricting type parameter `B`
|
||||
LL | impl<B: std::ops::Add<Output = B>> Add for D<B> {
|
||||
| +++++++++++++++++++++++++++
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/missing-bounds.rs:42:14
|
||||
|
|
||||
LL | impl<B: Add> Add for E<B> where <B as Add>::Output = B {
|
||||
| - this type parameter
|
||||
...
|
||||
LL | Self(self.0 + rhs.0)
|
||||
| ^^^^^^^^^^^^^^ expected type parameter `B`, found associated type
|
||||
|
|
||||
= note: expected type parameter `B`
|
||||
found associated type `<B as Add>::Output`
|
||||
help: consider further restricting type parameter `B`
|
||||
|
|
||||
LL | impl<B: Add> Add for E<B> where <B as Add>::Output = B, B: Add<Output = B> {
|
||||
| ++++++++++++++++++++
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0308, E0369.
|
||||
For more information about an error, try `rustc --explain E0308`.
|
||||
|
Loading…
Reference in New Issue
Block a user