Skip to content
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

Rollup of 6 pull requests #91288

Merged
merged 15 commits into from
Nov 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
49 changes: 48 additions & 1 deletion compiler/rustc_ast_passes/src/ast_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -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 &param.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",
);
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_ast_passes/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#![feature(iter_is_partitioned)]
#![feature(box_patterns)]
#![feature(let_else)]
#![recursion_limit = "256"]

pub mod ast_validation;
Expand Down
42 changes: 24 additions & 18 deletions library/core/src/fmt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

// 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);
/// 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);

if f.width.is_none() {
f.width = Some((usize::BITS / 4) as usize + 2);
}
}
}
f.flags |= 1 << (FlagV1::Alternate as u32);
f.flags |= 1 << (FlagV1::Alternate as u32);

let ret = LowerHex::fmt(&(ptr as usize), f);

let ret = LowerHex::fmt(&(*self as *const () as usize), f);
f.width = old_width;
f.flags = old_flags;

f.width = old_width;
f.flags = old_flags;
ret
}

ret
inner(*self as *const (), f)
}
}

Expand Down
13 changes: 13 additions & 0 deletions library/core/src/hash/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 4 additions & 2 deletions library/core/src/iter/traits/iterator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -461,8 +461,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
///
Expand Down
9 changes: 6 additions & 3 deletions library/std/src/thread/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/librustdoc/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -552,7 +552,7 @@ impl Options {
))
.emit();
}
themes.push(StylePath { path: theme_file, disabled: true });
themes.push(StylePath { path: theme_file });
}
}

Expand Down
5 changes: 4 additions & 1 deletion src/librustdoc/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
));
}
}
}};
Expand Down
26 changes: 11 additions & 15 deletions src/librustdoc/html/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};

Expand Down Expand Up @@ -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>(
Expand All @@ -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()
Expand Down
18 changes: 11 additions & 7 deletions src/librustdoc/html/render/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)?;
Expand Down Expand Up @@ -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,
Expand All @@ -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 {
Expand Down
38 changes: 15 additions & 23 deletions src/librustdoc/html/render/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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>,
},
}

Expand Down Expand Up @@ -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,
Expand All @@ -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] = &[
(
Expand Down Expand Up @@ -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
))
}

Expand Down
Loading