Auto merge of #131958 - Zalathar:rollup-gkuk3n1, r=Zalathar
Rollup of 4 pull requests Successful merges: - #131876 (compiler: Use LLVM's Comdat support) - #131941 (compiletest: disambiguate html-tidy from rust tidy tool) - #131942 (compiler: Adopt rust-analyzer impls for `LayoutCalculatorError`) - #131945 (rustdoc: Clean up footnote handling) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
d68c327796
@ -39,7 +39,7 @@ enum NicheBias {
|
||||
End,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
pub enum LayoutCalculatorError<F> {
|
||||
/// An unsized type was found in a location where a sized type was expected.
|
||||
///
|
||||
@ -56,6 +56,31 @@ pub enum LayoutCalculatorError<F> {
|
||||
EmptyUnion,
|
||||
}
|
||||
|
||||
impl<F> LayoutCalculatorError<F> {
|
||||
pub fn without_payload(&self) -> LayoutCalculatorError<()> {
|
||||
match self {
|
||||
LayoutCalculatorError::UnexpectedUnsized(_) => {
|
||||
LayoutCalculatorError::UnexpectedUnsized(())
|
||||
}
|
||||
LayoutCalculatorError::SizeOverflow => LayoutCalculatorError::SizeOverflow,
|
||||
LayoutCalculatorError::EmptyUnion => LayoutCalculatorError::EmptyUnion,
|
||||
}
|
||||
}
|
||||
|
||||
/// Format an untranslated diagnostic for this type
|
||||
///
|
||||
/// Intended for use by rust-analyzer, as neither it nor `rustc_abi` depend on fluent infra.
|
||||
pub fn fallback_fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.write_str(match self {
|
||||
LayoutCalculatorError::UnexpectedUnsized(_) => {
|
||||
"an unsized type was found where a sized type was expected"
|
||||
}
|
||||
LayoutCalculatorError::SizeOverflow => "size overflow",
|
||||
LayoutCalculatorError::EmptyUnion => "type is a union with no fields",
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
type LayoutCalculatorResult<FieldIdx, VariantIdx, F> =
|
||||
Result<LayoutS<FieldIdx, VariantIdx>, LayoutCalculatorError<F>>;
|
||||
|
||||
|
@ -132,7 +132,7 @@ pub(crate) fn finalize(cx: &CodegenCx<'_, '_>) {
|
||||
.collect::<Vec<_>>();
|
||||
let initializer = cx.const_array(cx.type_ptr(), &name_globals);
|
||||
|
||||
let array = llvm::add_global(cx.llmod, cx.val_ty(initializer), "__llvm_coverage_names");
|
||||
let array = llvm::add_global(cx.llmod, cx.val_ty(initializer), c"__llvm_coverage_names");
|
||||
llvm::set_global_constant(array, true);
|
||||
llvm::set_linkage(array, llvm::Linkage::InternalLinkage);
|
||||
llvm::set_initializer(array, initializer);
|
||||
|
@ -1,4 +1,5 @@
|
||||
use std::cell::RefCell;
|
||||
use std::ffi::CString;
|
||||
|
||||
use libc::c_uint;
|
||||
use rustc_codegen_ssa::traits::{
|
||||
@ -12,6 +13,7 @@
|
||||
use rustc_middle::ty::Instance;
|
||||
use rustc_middle::ty::layout::HasTyCtxt;
|
||||
use rustc_target::abi::{Align, Size};
|
||||
use rustc_target::spec::HasTargetSpec;
|
||||
use tracing::{debug, instrument};
|
||||
|
||||
use crate::builder::Builder;
|
||||
@ -284,10 +286,10 @@ pub(crate) fn save_cov_data_to_mod<'ll, 'tcx>(
|
||||
cx: &CodegenCx<'ll, 'tcx>,
|
||||
cov_data_val: &'ll llvm::Value,
|
||||
) {
|
||||
let covmap_var_name = llvm::build_string(|s| unsafe {
|
||||
let covmap_var_name = CString::new(llvm::build_byte_buffer(|s| unsafe {
|
||||
llvm::LLVMRustCoverageWriteMappingVarNameToString(s);
|
||||
})
|
||||
.expect("Rust Coverage Mapping var name failed UTF-8 conversion");
|
||||
}))
|
||||
.unwrap();
|
||||
debug!("covmap var name: {:?}", covmap_var_name);
|
||||
|
||||
let covmap_section_name = llvm::build_string(|s| unsafe {
|
||||
@ -322,7 +324,8 @@ pub(crate) fn save_func_record_to_mod<'ll, 'tcx>(
|
||||
// of descriptions play distinct roles in LLVM IR; therefore, assign them different names (by
|
||||
// appending "u" to the end of the function record var name, to prevent `linkonce_odr` merging.
|
||||
let func_record_var_name =
|
||||
format!("__covrec_{:X}{}", func_name_hash, if is_used { "u" } else { "" });
|
||||
CString::new(format!("__covrec_{:X}{}", func_name_hash, if is_used { "u" } else { "" }))
|
||||
.unwrap();
|
||||
debug!("function record var name: {:?}", func_record_var_name);
|
||||
debug!("function record section name: {:?}", covfun_section_name);
|
||||
|
||||
@ -334,7 +337,9 @@ pub(crate) fn save_func_record_to_mod<'ll, 'tcx>(
|
||||
llvm::set_section(llglobal, covfun_section_name);
|
||||
// LLVM's coverage mapping format specifies 8-byte alignment for items in this section.
|
||||
llvm::set_alignment(llglobal, Align::EIGHT);
|
||||
llvm::set_comdat(cx.llmod, llglobal, &func_record_var_name);
|
||||
if cx.target_spec().supports_comdat() {
|
||||
llvm::set_comdat(cx.llmod, llglobal, &func_record_var_name);
|
||||
}
|
||||
cx.add_used_global(llglobal);
|
||||
}
|
||||
|
||||
|
@ -787,7 +787,9 @@ fn codegen_msvc_try<'ll>(
|
||||
let tydesc = bx.declare_global("__rust_panic_type_info", bx.val_ty(type_info));
|
||||
unsafe {
|
||||
llvm::LLVMRustSetLinkage(tydesc, llvm::Linkage::LinkOnceODRLinkage);
|
||||
llvm::SetUniqueComdat(bx.llmod, tydesc);
|
||||
if bx.cx.tcx.sess.target.supports_comdat() {
|
||||
llvm::SetUniqueComdat(bx.llmod, tydesc);
|
||||
}
|
||||
llvm::LLVMSetInitializer(tydesc, type_info);
|
||||
}
|
||||
|
||||
|
@ -646,6 +646,7 @@ struct InvariantOpaque<'a> {
|
||||
pub type Attribute;
|
||||
pub type Metadata;
|
||||
pub type BasicBlock;
|
||||
pub type Comdat;
|
||||
}
|
||||
#[repr(C)]
|
||||
pub struct Builder<'a>(InvariantOpaque<'a>);
|
||||
@ -1490,6 +1491,9 @@ pub fn LLVMStructSetBody<'a>(
|
||||
pub fn LLVMSetUnnamedAddress(Global: &Value, UnnamedAddr: UnnamedAddr);
|
||||
|
||||
pub fn LLVMIsAConstantInt(value_ref: &Value) -> Option<&ConstantInt>;
|
||||
|
||||
pub fn LLVMGetOrInsertComdat(M: &Module, Name: *const c_char) -> &Comdat;
|
||||
pub fn LLVMSetComdat(V: &Value, C: &Comdat);
|
||||
}
|
||||
|
||||
#[link(name = "llvm-wrapper", kind = "static")]
|
||||
@ -2320,7 +2324,6 @@ pub fn LLVMRustBuildOperandBundleDef(
|
||||
|
||||
pub fn LLVMRustPositionBuilderAtStart<'a>(B: &Builder<'a>, BB: &'a BasicBlock);
|
||||
|
||||
pub fn LLVMRustSetComdat<'a>(M: &'a Module, V: &'a Value, Name: *const c_char, NameLen: size_t);
|
||||
pub fn LLVMRustSetModulePICLevel(M: &Module);
|
||||
pub fn LLVMRustSetModulePIELevel(M: &Module);
|
||||
pub fn LLVMRustSetModuleCodeModel(M: &Module, Model: CodeModel);
|
||||
|
@ -178,10 +178,10 @@ pub fn SetFunctionCallConv(fn_: &Value, cc: CallConv) {
|
||||
// function.
|
||||
// For more details on COMDAT sections see e.g., https://www.airs.com/blog/archives/52
|
||||
pub fn SetUniqueComdat(llmod: &Module, val: &Value) {
|
||||
unsafe {
|
||||
let name = get_value_name(val);
|
||||
LLVMRustSetComdat(llmod, val, name.as_ptr().cast(), name.len());
|
||||
}
|
||||
let name_buf = get_value_name(val).to_vec();
|
||||
let name =
|
||||
CString::from_vec_with_nul(name_buf).or_else(|buf| CString::new(buf.into_bytes())).unwrap();
|
||||
set_comdat(llmod, val, &name);
|
||||
}
|
||||
|
||||
pub fn SetUnnamedAddress(global: &Value, unnamed: UnnamedAddr) {
|
||||
@ -217,8 +217,7 @@ pub fn set_section(llglobal: &Value, section_name: &str) {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_global<'a>(llmod: &'a Module, ty: &'a Type, name: &str) -> &'a Value {
|
||||
let name_cstr = CString::new(name).expect("unexpected CString error");
|
||||
pub fn add_global<'a>(llmod: &'a Module, ty: &'a Type, name_cstr: &CStr) -> &'a Value {
|
||||
unsafe { LLVMAddGlobal(llmod, ty, name_cstr.as_ptr()) }
|
||||
}
|
||||
|
||||
@ -252,9 +251,14 @@ pub fn set_alignment(llglobal: &Value, align: Align) {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_comdat(llmod: &Module, llglobal: &Value, name: &str) {
|
||||
/// Get the `name`d comdat from `llmod` and assign it to `llglobal`.
|
||||
///
|
||||
/// Inserts the comdat into `llmod` if it does not exist.
|
||||
/// It is an error to call this if the target does not support comdat.
|
||||
pub fn set_comdat(llmod: &Module, llglobal: &Value, name: &CStr) {
|
||||
unsafe {
|
||||
LLVMRustSetComdat(llmod, llglobal, name.as_ptr().cast(), name.len());
|
||||
let comdat = LLVMGetOrInsertComdat(llmod, name.as_ptr());
|
||||
LLVMSetComdat(llglobal, comdat);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -64,7 +64,9 @@ fn predefine_fn(
|
||||
unsafe { llvm::LLVMRustSetLinkage(lldecl, base::linkage_to_llvm(linkage)) };
|
||||
let attrs = self.tcx.codegen_fn_attrs(instance.def_id());
|
||||
base::set_link_section(lldecl, attrs);
|
||||
if linkage == Linkage::LinkOnceODR || linkage == Linkage::WeakODR {
|
||||
if (linkage == Linkage::LinkOnceODR || linkage == Linkage::WeakODR)
|
||||
&& self.tcx.sess.target.supports_comdat()
|
||||
{
|
||||
llvm::SetUniqueComdat(self.llmod, lldecl);
|
||||
}
|
||||
|
||||
|
@ -1658,16 +1658,6 @@ extern "C" void LLVMRustPositionBuilderAtStart(LLVMBuilderRef B,
|
||||
unwrap(B)->SetInsertPoint(unwrap(BB), Point);
|
||||
}
|
||||
|
||||
extern "C" void LLVMRustSetComdat(LLVMModuleRef M, LLVMValueRef V,
|
||||
const char *Name, size_t NameLen) {
|
||||
Triple TargetTriple = Triple(unwrap(M)->getTargetTriple());
|
||||
GlobalObject *GV = unwrap<GlobalObject>(V);
|
||||
if (TargetTriple.supportsCOMDAT()) {
|
||||
StringRef NameRef(Name, NameLen);
|
||||
GV->setComdat(unwrap(M)->getOrInsertComdat(NameRef));
|
||||
}
|
||||
}
|
||||
|
||||
enum class LLVMRustLinkage {
|
||||
ExternalLinkage = 0,
|
||||
AvailableExternallyLinkage = 1,
|
||||
|
@ -2514,6 +2514,13 @@ fn add_link_args(link_args: &mut LinkArgs, flavor: LinkerFlavor, args: &[&'stati
|
||||
add_link_args_iter(link_args, flavor, args.iter().copied().map(Cow::Borrowed))
|
||||
}
|
||||
|
||||
impl TargetOptions {
|
||||
pub fn supports_comdat(&self) -> bool {
|
||||
// XCOFF and MachO don't support COMDAT.
|
||||
!self.is_like_aix && !self.is_like_osx
|
||||
}
|
||||
}
|
||||
|
||||
impl TargetOptions {
|
||||
fn link_args(flavor: LinkerFlavor, args: &[&'static str]) -> LinkArgs {
|
||||
let mut link_args = LinkArgs::new();
|
||||
|
@ -37,7 +37,7 @@
|
||||
use pulldown_cmark::{
|
||||
BrokenLink, CodeBlockKind, CowStr, Event, LinkType, Options, Parser, Tag, TagEnd, html,
|
||||
};
|
||||
use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_errors::{Diag, DiagMessage};
|
||||
use rustc_hir::def_id::LocalDefId;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
@ -57,6 +57,7 @@
|
||||
use crate::html::render::small_url_encode;
|
||||
use crate::html::toc::{Toc, TocBuilder};
|
||||
|
||||
mod footnotes;
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
@ -646,81 +647,6 @@ fn next(&mut self) -> Option<Self::Item> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Moves all footnote definitions to the end and add back links to the
|
||||
/// references.
|
||||
struct Footnotes<'a, I> {
|
||||
inner: I,
|
||||
footnotes: FxIndexMap<String, (Vec<Event<'a>>, u16)>,
|
||||
}
|
||||
|
||||
impl<'a, I> Footnotes<'a, I> {
|
||||
fn new(iter: I) -> Self {
|
||||
Footnotes { inner: iter, footnotes: FxIndexMap::default() }
|
||||
}
|
||||
|
||||
fn get_entry(&mut self, key: &str) -> &mut (Vec<Event<'a>>, u16) {
|
||||
let new_id = self.footnotes.len() + 1;
|
||||
let key = key.to_owned();
|
||||
self.footnotes.entry(key).or_insert((Vec::new(), new_id as u16))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, I: Iterator<Item = SpannedEvent<'a>>> Iterator for Footnotes<'a, I> {
|
||||
type Item = SpannedEvent<'a>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
loop {
|
||||
match self.inner.next() {
|
||||
Some((Event::FootnoteReference(ref reference), range)) => {
|
||||
let entry = self.get_entry(reference);
|
||||
let reference = format!(
|
||||
"<sup id=\"fnref{0}\"><a href=\"#fn{0}\">{0}</a></sup>",
|
||||
(*entry).1
|
||||
);
|
||||
return Some((Event::Html(reference.into()), range));
|
||||
}
|
||||
Some((Event::Start(Tag::FootnoteDefinition(def)), _)) => {
|
||||
let mut content = Vec::new();
|
||||
for (event, _) in &mut self.inner {
|
||||
if let Event::End(TagEnd::FootnoteDefinition) = event {
|
||||
break;
|
||||
}
|
||||
content.push(event);
|
||||
}
|
||||
let entry = self.get_entry(&def);
|
||||
(*entry).0 = content;
|
||||
}
|
||||
Some(e) => return Some(e),
|
||||
None => {
|
||||
if !self.footnotes.is_empty() {
|
||||
let mut v: Vec<_> = self.footnotes.drain(..).map(|(_, x)| x).collect();
|
||||
v.sort_by(|a, b| a.1.cmp(&b.1));
|
||||
let mut ret = String::from("<div class=\"footnotes\"><hr><ol>");
|
||||
for (mut content, id) in v {
|
||||
write!(ret, "<li id=\"fn{id}\">").unwrap();
|
||||
let mut is_paragraph = false;
|
||||
if let Some(&Event::End(TagEnd::Paragraph)) = content.last() {
|
||||
content.pop();
|
||||
is_paragraph = true;
|
||||
}
|
||||
html::push_html(&mut ret, content.into_iter());
|
||||
write!(ret, " <a href=\"#fnref{id}\">↩</a>").unwrap();
|
||||
if is_paragraph {
|
||||
ret.push_str("</p>");
|
||||
}
|
||||
ret.push_str("</li>");
|
||||
}
|
||||
ret.push_str("</ol></div>");
|
||||
return Some((Event::Html(ret.into()), 0..0));
|
||||
} else {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A newtype that represents a relative line number in Markdown.
|
||||
///
|
||||
/// In other words, this represents an offset from the first line of Markdown
|
||||
@ -1408,7 +1334,7 @@ pub fn into_string(self) -> String {
|
||||
let mut s = String::with_capacity(md.len() * 3 / 2);
|
||||
|
||||
let p = HeadingLinks::new(p, None, ids, heading_offset);
|
||||
let p = Footnotes::new(p);
|
||||
let p = footnotes::Footnotes::new(p);
|
||||
let p = LinkReplacer::new(p.map(|(ev, _)| ev), links);
|
||||
let p = TableWrapper::new(p);
|
||||
let p = CodeBlocks::new(p, codes, edition, playground);
|
||||
@ -1443,7 +1369,7 @@ pub(crate) fn into_parts(self) -> (Toc, String) {
|
||||
|
||||
{
|
||||
let p = HeadingLinks::new(p, Some(&mut toc), ids, HeadingOffset::H1);
|
||||
let p = Footnotes::new(p);
|
||||
let p = footnotes::Footnotes::new(p);
|
||||
let p = TableWrapper::new(p.map(|(ev, _)| ev));
|
||||
let p = CodeBlocks::new(p, codes, edition, playground);
|
||||
html::push_html(&mut s, p);
|
||||
@ -1476,7 +1402,7 @@ pub(crate) fn into_string(self) -> String {
|
||||
let mut s = String::with_capacity(md.len() * 3 / 2);
|
||||
|
||||
let p = HeadingLinks::new(p, None, ids, HeadingOffset::H1);
|
||||
let p = Footnotes::new(p);
|
||||
let p = footnotes::Footnotes::new(p);
|
||||
let p = TableWrapper::new(p.map(|(ev, _)| ev));
|
||||
let p = p.filter(|event| {
|
||||
!matches!(event, Event::Start(Tag::Paragraph) | Event::End(TagEnd::Paragraph))
|
||||
|
113
src/librustdoc/html/markdown/footnotes.rs
Normal file
113
src/librustdoc/html/markdown/footnotes.rs
Normal file
@ -0,0 +1,113 @@
|
||||
//! Markdown footnote handling.
|
||||
use std::fmt::Write as _;
|
||||
|
||||
use pulldown_cmark::{Event, Tag, TagEnd, html};
|
||||
use rustc_data_structures::fx::FxIndexMap;
|
||||
|
||||
use super::SpannedEvent;
|
||||
|
||||
/// Moves all footnote definitions to the end and add back links to the
|
||||
/// references.
|
||||
pub(super) struct Footnotes<'a, I> {
|
||||
inner: I,
|
||||
footnotes: FxIndexMap<String, FootnoteDef<'a>>,
|
||||
}
|
||||
|
||||
/// The definition of a single footnote.
|
||||
struct FootnoteDef<'a> {
|
||||
content: Vec<Event<'a>>,
|
||||
/// The number that appears in the footnote reference and list.
|
||||
id: u16,
|
||||
}
|
||||
|
||||
impl<'a, I> Footnotes<'a, I> {
|
||||
pub(super) fn new(iter: I) -> Self {
|
||||
Footnotes { inner: iter, footnotes: FxIndexMap::default() }
|
||||
}
|
||||
|
||||
fn get_entry(&mut self, key: &str) -> (&mut Vec<Event<'a>>, u16) {
|
||||
let new_id = self.footnotes.len() + 1;
|
||||
let key = key.to_owned();
|
||||
let FootnoteDef { content, id } = self
|
||||
.footnotes
|
||||
.entry(key)
|
||||
.or_insert(FootnoteDef { content: Vec::new(), id: new_id as u16 });
|
||||
// Don't allow changing the ID of existing entrys, but allow changing the contents.
|
||||
(content, *id)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, I: Iterator<Item = SpannedEvent<'a>>> Iterator for Footnotes<'a, I> {
|
||||
type Item = SpannedEvent<'a>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
loop {
|
||||
match self.inner.next() {
|
||||
Some((Event::FootnoteReference(ref reference), range)) => {
|
||||
// When we see a reference (to a footnote we may not know) the definition of,
|
||||
// reserve a number for it, and emit a link to that number.
|
||||
let (_, id) = self.get_entry(reference);
|
||||
let reference =
|
||||
format!("<sup id=\"fnref{0}\"><a href=\"#fn{0}\">{0}</a></sup>", id);
|
||||
return Some((Event::Html(reference.into()), range));
|
||||
}
|
||||
Some((Event::Start(Tag::FootnoteDefinition(def)), _)) => {
|
||||
// When we see a footnote definition, collect the assocated content, and store
|
||||
// that for rendering later.
|
||||
let content = collect_footnote_def(&mut self.inner);
|
||||
let (entry_content, _) = self.get_entry(&def);
|
||||
*entry_content = content;
|
||||
}
|
||||
Some(e) => return Some(e),
|
||||
None => {
|
||||
if !self.footnotes.is_empty() {
|
||||
// After all the markdown is emmited, emit an <hr> then all the footnotes
|
||||
// in a list.
|
||||
let defs: Vec<_> = self.footnotes.drain(..).map(|(_, x)| x).collect();
|
||||
let defs_html = render_footnotes_defs(defs);
|
||||
return Some((Event::Html(defs_html.into()), 0..0));
|
||||
} else {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn collect_footnote_def<'a>(events: impl Iterator<Item = SpannedEvent<'a>>) -> Vec<Event<'a>> {
|
||||
let mut content = Vec::new();
|
||||
for (event, _) in events {
|
||||
if let Event::End(TagEnd::FootnoteDefinition) = event {
|
||||
break;
|
||||
}
|
||||
content.push(event);
|
||||
}
|
||||
content
|
||||
}
|
||||
|
||||
fn render_footnotes_defs(mut footnotes: Vec<FootnoteDef<'_>>) -> String {
|
||||
let mut ret = String::from("<div class=\"footnotes\"><hr><ol>");
|
||||
|
||||
// Footnotes must listed in order of id, so the numbers the
|
||||
// browser generated for <li> are right.
|
||||
footnotes.sort_by_key(|x| x.id);
|
||||
|
||||
for FootnoteDef { mut content, id } in footnotes {
|
||||
write!(ret, "<li id=\"fn{id}\">").unwrap();
|
||||
let mut is_paragraph = false;
|
||||
if let Some(&Event::End(TagEnd::Paragraph)) = content.last() {
|
||||
content.pop();
|
||||
is_paragraph = true;
|
||||
}
|
||||
html::push_html(&mut ret, content.into_iter());
|
||||
write!(ret, " <a href=\"#fnref{id}\">↩</a>").unwrap();
|
||||
if is_paragraph {
|
||||
ret.push_str("</p>");
|
||||
}
|
||||
ret.push_str("</li>");
|
||||
}
|
||||
ret.push_str("</ol></div>");
|
||||
|
||||
ret
|
||||
}
|
@ -19,7 +19,7 @@ fn main() {
|
||||
let config = Arc::new(parse_config(env::args().collect()));
|
||||
|
||||
if !config.has_tidy && config.mode == Mode::Rustdoc {
|
||||
eprintln!("warning: `tidy` is not installed; diffs will not be generated");
|
||||
eprintln!("warning: `tidy` (html-tidy.org) is not installed; diffs will not be generated");
|
||||
}
|
||||
|
||||
if !config.profiler_runtime && config.mode == Mode::CoverageRun {
|
||||
|
@ -72,6 +72,8 @@ fn index(self) -> usize {
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
pub enum LayoutError {
|
||||
// FIXME: Remove variants that duplicate LayoutCalculatorError's variants after sync
|
||||
BadCalc(LayoutCalculatorError<()>),
|
||||
EmptyUnion,
|
||||
HasErrorConst,
|
||||
HasErrorType,
|
||||
@ -90,6 +92,7 @@ impl std::error::Error for LayoutError {}
|
||||
impl fmt::Display for LayoutError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
LayoutError::BadCalc(err) => err.fallback_fmt(f),
|
||||
LayoutError::EmptyUnion => write!(f, "type is an union with no fields"),
|
||||
LayoutError::HasErrorConst => write!(f, "type contains an unevaluatable const"),
|
||||
LayoutError::HasErrorType => write!(f, "type contains an error"),
|
||||
@ -114,11 +117,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
|
||||
impl<F> From<LayoutCalculatorError<F>> for LayoutError {
|
||||
fn from(err: LayoutCalculatorError<F>) -> Self {
|
||||
match err {
|
||||
LayoutCalculatorError::EmptyUnion => LayoutError::EmptyUnion,
|
||||
LayoutCalculatorError::UnexpectedUnsized(_) => LayoutError::UnexpectedUnsized,
|
||||
LayoutCalculatorError::SizeOverflow => LayoutError::SizeOverflow,
|
||||
}
|
||||
LayoutError::BadCalc(err.without_payload())
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user