mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
set the default edition when pre-parsing a doctest
This commit is contained in:
parent
a19cf18c7d
commit
20a5aa302e
@ -386,18 +386,6 @@ impl Options {
|
||||
}
|
||||
}
|
||||
|
||||
let mut id_map = html::markdown::IdMap::new();
|
||||
id_map.populate(html::render::initial_ids());
|
||||
let external_html = match ExternalHtml::load(
|
||||
&matches.opt_strs("html-in-header"),
|
||||
&matches.opt_strs("html-before-content"),
|
||||
&matches.opt_strs("html-after-content"),
|
||||
&matches.opt_strs("markdown-before-content"),
|
||||
&matches.opt_strs("markdown-after-content"), &diag, &mut id_map) {
|
||||
Some(eh) => eh,
|
||||
None => return Err(3),
|
||||
};
|
||||
|
||||
let edition = matches.opt_str("edition").unwrap_or("2015".to_string());
|
||||
let edition = match edition.parse() {
|
||||
Ok(e) => e,
|
||||
@ -407,6 +395,19 @@ impl Options {
|
||||
}
|
||||
};
|
||||
|
||||
let mut id_map = html::markdown::IdMap::new();
|
||||
id_map.populate(html::render::initial_ids());
|
||||
let external_html = match ExternalHtml::load(
|
||||
&matches.opt_strs("html-in-header"),
|
||||
&matches.opt_strs("html-before-content"),
|
||||
&matches.opt_strs("html-after-content"),
|
||||
&matches.opt_strs("markdown-before-content"),
|
||||
&matches.opt_strs("markdown-after-content"),
|
||||
&diag, &mut id_map, edition) {
|
||||
Some(eh) => eh,
|
||||
None => return Err(3),
|
||||
};
|
||||
|
||||
match matches.opt_str("r").as_ref().map(|s| &**s) {
|
||||
Some("rust") | None => {}
|
||||
Some(s) => {
|
||||
|
@ -3,6 +3,7 @@ use std::path::Path;
|
||||
use std::str;
|
||||
use errors;
|
||||
use crate::syntax::feature_gate::UnstableFeatures;
|
||||
use crate::syntax::edition::Edition;
|
||||
use crate::html::markdown::{IdMap, ErrorCodes, Markdown};
|
||||
|
||||
use std::cell::RefCell;
|
||||
@ -23,7 +24,7 @@ pub struct ExternalHtml {
|
||||
impl ExternalHtml {
|
||||
pub fn load(in_header: &[String], before_content: &[String], after_content: &[String],
|
||||
md_before_content: &[String], md_after_content: &[String], diag: &errors::Handler,
|
||||
id_map: &mut IdMap)
|
||||
id_map: &mut IdMap, edition: Edition)
|
||||
-> Option<ExternalHtml> {
|
||||
let codes = ErrorCodes::from(UnstableFeatures::from_environment().is_nightly_build());
|
||||
load_external_files(in_header, diag)
|
||||
@ -34,7 +35,8 @@ impl ExternalHtml {
|
||||
.and_then(|(ih, bc)|
|
||||
load_external_files(md_before_content, diag)
|
||||
.map(|m_bc| (ih,
|
||||
format!("{}{}", bc, Markdown(&m_bc, &[], RefCell::new(id_map), codes))))
|
||||
format!("{}{}", bc, Markdown(&m_bc, &[], RefCell::new(id_map),
|
||||
codes, edition))))
|
||||
)
|
||||
.and_then(|(ih, bc)|
|
||||
load_external_files(after_content, diag)
|
||||
@ -43,7 +45,8 @@ impl ExternalHtml {
|
||||
.and_then(|(ih, bc, ac)|
|
||||
load_external_files(md_after_content, diag)
|
||||
.map(|m_ac| (ih, bc,
|
||||
format!("{}{}", ac, Markdown(&m_ac, &[], RefCell::new(id_map), codes))))
|
||||
format!("{}{}", ac, Markdown(&m_ac, &[], RefCell::new(id_map),
|
||||
codes, edition))))
|
||||
)
|
||||
.map(|(ih, bc, ac)|
|
||||
ExternalHtml {
|
||||
|
@ -42,14 +42,21 @@ fn opts() -> Options {
|
||||
/// A unit struct which has the `fmt::Display` trait implemented. When
|
||||
/// formatted, this struct will emit the HTML corresponding to the rendered
|
||||
/// version of the contained markdown string.
|
||||
/// The second parameter is a list of link replacements
|
||||
///
|
||||
/// The second parameter is a list of link replacements.
|
||||
///
|
||||
/// The third is the current list of used header IDs.
|
||||
///
|
||||
/// The fourth is whether to allow the use of explicit error codes in doctest lang strings.
|
||||
///
|
||||
/// The fifth is what default edition to use when parsing doctests (to add a `fn main`).
|
||||
pub struct Markdown<'a>(
|
||||
pub &'a str, pub &'a [(String, String)], pub RefCell<&'a mut IdMap>, pub ErrorCodes);
|
||||
pub &'a str, pub &'a [(String, String)], pub RefCell<&'a mut IdMap>, pub ErrorCodes, pub Edition);
|
||||
/// A unit struct like `Markdown`, that renders the markdown with a
|
||||
/// table of contents.
|
||||
pub struct MarkdownWithToc<'a>(pub &'a str, pub RefCell<&'a mut IdMap>, pub ErrorCodes);
|
||||
pub struct MarkdownWithToc<'a>(pub &'a str, pub RefCell<&'a mut IdMap>, pub ErrorCodes, pub Edition);
|
||||
/// A unit struct like `Markdown`, that renders the markdown escaping HTML tags.
|
||||
pub struct MarkdownHtml<'a>(pub &'a str, pub RefCell<&'a mut IdMap>, pub ErrorCodes);
|
||||
pub struct MarkdownHtml<'a>(pub &'a str, pub RefCell<&'a mut IdMap>, pub ErrorCodes, pub Edition);
|
||||
/// A unit struct like `Markdown`, that renders only the first paragraph.
|
||||
pub struct MarkdownSummaryLine<'a>(pub &'a str, pub &'a [(String, String)]);
|
||||
|
||||
@ -146,13 +153,15 @@ thread_local!(pub static PLAYGROUND: RefCell<Option<(Option<String>, String)>> =
|
||||
struct CodeBlocks<'a, I: Iterator<Item = Event<'a>>> {
|
||||
inner: I,
|
||||
check_error_codes: ErrorCodes,
|
||||
edition: Edition,
|
||||
}
|
||||
|
||||
impl<'a, I: Iterator<Item = Event<'a>>> CodeBlocks<'a, I> {
|
||||
fn new(iter: I, error_codes: ErrorCodes) -> Self {
|
||||
fn new(iter: I, error_codes: ErrorCodes, edition: Edition) -> Self {
|
||||
CodeBlocks {
|
||||
inner: iter,
|
||||
check_error_codes: error_codes,
|
||||
edition,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -177,6 +186,9 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'a, I> {
|
||||
return event;
|
||||
}
|
||||
|
||||
let explicit_edition = edition.is_some();
|
||||
let edition = edition.unwrap_or(self.edition);
|
||||
|
||||
let mut origtext = String::new();
|
||||
for event in &mut self.inner {
|
||||
match event {
|
||||
@ -202,22 +214,14 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'a, I> {
|
||||
.collect::<Vec<Cow<'_, str>>>().join("\n");
|
||||
let krate = krate.as_ref().map(|s| &**s);
|
||||
let (test, _) = test::make_test(&test, krate, false,
|
||||
&Default::default());
|
||||
&Default::default(), edition);
|
||||
let channel = if test.contains("#![feature(") {
|
||||
"&version=nightly"
|
||||
} else {
|
||||
""
|
||||
};
|
||||
|
||||
let edition_string = if let Some(e @ Edition::Edition2018) = edition {
|
||||
format!("&edition={}{}", e,
|
||||
if channel == "&version=nightly" { "" }
|
||||
else { "&version=nightly" })
|
||||
} else if let Some(e) = edition {
|
||||
format!("&edition={}", e)
|
||||
} else {
|
||||
"".to_owned()
|
||||
};
|
||||
let edition_string = format!("&edition={}", edition);
|
||||
|
||||
// These characters don't need to be escaped in a URI.
|
||||
// FIXME: use a library function for percent encoding.
|
||||
@ -247,8 +251,8 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'a, I> {
|
||||
Some(("This example is not tested".to_owned(), "ignore"))
|
||||
} else if compile_fail {
|
||||
Some(("This example deliberately fails to compile".to_owned(), "compile_fail"))
|
||||
} else if let Some(e) = edition {
|
||||
Some((format!("This code runs with edition {}", e), "edition"))
|
||||
} else if explicit_edition {
|
||||
Some((format!("This code runs with edition {}", edition), "edition"))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
@ -259,7 +263,7 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'a, I> {
|
||||
Some(&format!("rust-example-rendered{}",
|
||||
if ignore { " ignore" }
|
||||
else if compile_fail { " compile_fail" }
|
||||
else if edition.is_some() { " edition " }
|
||||
else if explicit_edition { " edition " }
|
||||
else { "" })),
|
||||
playground_button.as_ref().map(String::as_str),
|
||||
Some((s1.as_str(), s2))));
|
||||
@ -270,7 +274,7 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'a, I> {
|
||||
Some(&format!("rust-example-rendered{}",
|
||||
if ignore { " ignore" }
|
||||
else if compile_fail { " compile_fail" }
|
||||
else if edition.is_some() { " edition " }
|
||||
else if explicit_edition { " edition " }
|
||||
else { "" })),
|
||||
playground_button.as_ref().map(String::as_str),
|
||||
None));
|
||||
@ -659,7 +663,7 @@ impl LangString {
|
||||
|
||||
impl<'a> fmt::Display for Markdown<'a> {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let Markdown(md, links, ref ids, codes) = *self;
|
||||
let Markdown(md, links, ref ids, codes, edition) = *self;
|
||||
let mut ids = ids.borrow_mut();
|
||||
|
||||
// This is actually common enough to special-case
|
||||
@ -678,7 +682,7 @@ impl<'a> fmt::Display for Markdown<'a> {
|
||||
|
||||
let p = HeadingLinks::new(p, None, &mut ids);
|
||||
let p = LinkReplacer::new(p, links);
|
||||
let p = CodeBlocks::new(p, codes);
|
||||
let p = CodeBlocks::new(p, codes, edition);
|
||||
let p = Footnotes::new(p);
|
||||
html::push_html(&mut s, p);
|
||||
|
||||
@ -688,7 +692,7 @@ impl<'a> fmt::Display for Markdown<'a> {
|
||||
|
||||
impl<'a> fmt::Display for MarkdownWithToc<'a> {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let MarkdownWithToc(md, ref ids, codes) = *self;
|
||||
let MarkdownWithToc(md, ref ids, codes, edition) = *self;
|
||||
let mut ids = ids.borrow_mut();
|
||||
|
||||
let p = Parser::new_ext(md, opts());
|
||||
@ -699,7 +703,7 @@ impl<'a> fmt::Display for MarkdownWithToc<'a> {
|
||||
|
||||
{
|
||||
let p = HeadingLinks::new(p, Some(&mut toc), &mut ids);
|
||||
let p = CodeBlocks::new(p, codes);
|
||||
let p = CodeBlocks::new(p, codes, edition);
|
||||
let p = Footnotes::new(p);
|
||||
html::push_html(&mut s, p);
|
||||
}
|
||||
@ -712,7 +716,7 @@ impl<'a> fmt::Display for MarkdownWithToc<'a> {
|
||||
|
||||
impl<'a> fmt::Display for MarkdownHtml<'a> {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let MarkdownHtml(md, ref ids, codes) = *self;
|
||||
let MarkdownHtml(md, ref ids, codes, edition) = *self;
|
||||
let mut ids = ids.borrow_mut();
|
||||
|
||||
// This is actually common enough to special-case
|
||||
@ -728,7 +732,7 @@ impl<'a> fmt::Display for MarkdownHtml<'a> {
|
||||
let mut s = String::with_capacity(md.len() * 3 / 2);
|
||||
|
||||
let p = HeadingLinks::new(p, None, &mut ids);
|
||||
let p = CodeBlocks::new(p, codes);
|
||||
let p = CodeBlocks::new(p, codes, edition);
|
||||
let p = Footnotes::new(p);
|
||||
html::push_html(&mut s, p);
|
||||
|
||||
|
@ -47,6 +47,7 @@ use std::rc::Rc;
|
||||
use errors;
|
||||
use serialize::json::{ToJson, Json, as_json};
|
||||
use syntax::ast;
|
||||
use syntax::edition::Edition;
|
||||
use syntax::ext::base::MacroKind;
|
||||
use syntax::source_map::FileName;
|
||||
use syntax::feature_gate::UnstableFeatures;
|
||||
@ -107,6 +108,8 @@ struct Context {
|
||||
/// publicly reused items to redirect to the right location.
|
||||
pub render_redirect_pages: bool,
|
||||
pub codes: ErrorCodes,
|
||||
/// The default edition used to parse doctests.
|
||||
pub edition: Edition,
|
||||
/// The map used to ensure all generated 'id=' attributes are unique.
|
||||
id_map: Rc<RefCell<IdMap>>,
|
||||
pub shared: Arc<SharedContext>,
|
||||
@ -513,7 +516,8 @@ pub fn run(mut krate: clean::Crate,
|
||||
options: RenderOptions,
|
||||
passes: FxHashSet<String>,
|
||||
renderinfo: RenderInfo,
|
||||
diag: &errors::Handler) -> Result<(), Error> {
|
||||
diag: &errors::Handler,
|
||||
edition: Edition) -> Result<(), Error> {
|
||||
// need to save a copy of the options for rendering the index page
|
||||
let md_opts = options.clone();
|
||||
let RenderOptions {
|
||||
@ -603,6 +607,7 @@ pub fn run(mut krate: clean::Crate,
|
||||
dst,
|
||||
render_redirect_pages: false,
|
||||
codes: ErrorCodes::from(UnstableFeatures::from_environment().is_nightly_build()),
|
||||
edition,
|
||||
id_map: Rc::new(RefCell::new(id_map)),
|
||||
shared: Arc::new(scx),
|
||||
};
|
||||
@ -1127,7 +1132,7 @@ themePicker.onblur = handleThemeButtonsBlur;
|
||||
md_opts.output = cx.dst.clone();
|
||||
md_opts.external_html = (*cx.shared).layout.external_html.clone();
|
||||
|
||||
crate::markdown::render(index_page, md_opts, diag);
|
||||
crate::markdown::render(index_page, md_opts, diag, cx.edition);
|
||||
} else {
|
||||
let dst = cx.dst.join("index.html");
|
||||
let mut w = BufWriter::new(try_err!(File::create(&dst), &dst));
|
||||
@ -2552,7 +2557,7 @@ fn render_markdown(w: &mut fmt::Formatter<'_>,
|
||||
if is_hidden { " hidden" } else { "" },
|
||||
prefix,
|
||||
Markdown(md_text, &links, RefCell::new(&mut ids),
|
||||
cx.codes))
|
||||
cx.codes, cx.edition))
|
||||
}
|
||||
|
||||
fn document_short(
|
||||
@ -2917,7 +2922,7 @@ fn short_stability(item: &clean::Item, cx: &Context) -> Vec<String> {
|
||||
|
||||
if let Some(note) = note {
|
||||
let mut ids = cx.id_map.borrow_mut();
|
||||
let html = MarkdownHtml(¬e, RefCell::new(&mut ids), error_codes);
|
||||
let html = MarkdownHtml(¬e, RefCell::new(&mut ids), error_codes, cx.edition);
|
||||
message.push_str(&format!(": {}", html));
|
||||
}
|
||||
stability.push(format!("<div class='stab deprecated'>{}</div>", message));
|
||||
@ -2966,7 +2971,7 @@ fn short_stability(item: &clean::Item, cx: &Context) -> Vec<String> {
|
||||
message = format!(
|
||||
"<details><summary>{}</summary>{}</details>",
|
||||
message,
|
||||
MarkdownHtml(&unstable_reason, RefCell::new(&mut ids), error_codes)
|
||||
MarkdownHtml(&unstable_reason, RefCell::new(&mut ids), error_codes, cx.edition)
|
||||
);
|
||||
}
|
||||
|
||||
@ -4179,7 +4184,8 @@ fn render_impl(w: &mut fmt::Formatter<'_>, cx: &Context, i: &Impl, link: AssocIt
|
||||
if let Some(ref dox) = cx.shared.maybe_collapsed_doc_value(&i.impl_item) {
|
||||
let mut ids = cx.id_map.borrow_mut();
|
||||
write!(w, "<div class='docblock'>{}</div>",
|
||||
Markdown(&*dox, &i.impl_item.links(), RefCell::new(&mut ids), cx.codes))?;
|
||||
Markdown(&*dox, &i.impl_item.links(), RefCell::new(&mut ids),
|
||||
cx.codes, cx.edition))?;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -391,7 +391,10 @@ fn main_args(args: &[String]) -> i32 {
|
||||
match (options.should_test, options.markdown_input()) {
|
||||
(true, true) => return markdown::test(options, &diag),
|
||||
(true, false) => return test::run(options),
|
||||
(false, true) => return markdown::render(options.input, options.render_options, &diag),
|
||||
(false, true) => return markdown::render(options.input,
|
||||
options.render_options,
|
||||
&diag,
|
||||
options.edition),
|
||||
(false, false) => {}
|
||||
}
|
||||
|
||||
@ -399,7 +402,8 @@ fn main_args(args: &[String]) -> i32 {
|
||||
// but we can't crates the Handler ahead of time because it's not Send
|
||||
let diag_opts = (options.error_format,
|
||||
options.debugging_options.treat_err_as_bug,
|
||||
options.debugging_options.ui_testing);
|
||||
options.debugging_options.ui_testing,
|
||||
options.edition);
|
||||
let show_coverage = options.show_coverage;
|
||||
rust_input(options, move |out| {
|
||||
if show_coverage {
|
||||
@ -410,7 +414,7 @@ fn main_args(args: &[String]) -> i32 {
|
||||
|
||||
let Output { krate, passes, renderinfo, renderopts } = out;
|
||||
info!("going to format");
|
||||
let (error_format, treat_err_as_bug, ui_testing) = diag_opts;
|
||||
let (error_format, treat_err_as_bug, ui_testing, edition) = diag_opts;
|
||||
let diag = core::new_handler(error_format, None, treat_err_as_bug, ui_testing);
|
||||
match html::render::run(
|
||||
krate,
|
||||
@ -418,6 +422,7 @@ fn main_args(args: &[String]) -> i32 {
|
||||
passes.into_iter().collect(),
|
||||
renderinfo,
|
||||
&diag,
|
||||
edition,
|
||||
) {
|
||||
Ok(_) => rustc_driver::EXIT_SUCCESS,
|
||||
Err(e) => {
|
||||
|
@ -5,6 +5,7 @@ use std::cell::RefCell;
|
||||
|
||||
use errors;
|
||||
use testing;
|
||||
use syntax::edition::Edition;
|
||||
use syntax::source_map::DUMMY_SP;
|
||||
use syntax::feature_gate::UnstableFeatures;
|
||||
|
||||
@ -36,7 +37,12 @@ fn extract_leading_metadata<'a>(s: &'a str) -> (Vec<&'a str>, &'a str) {
|
||||
|
||||
/// Render `input` (e.g., "foo.md") into an HTML file in `output`
|
||||
/// (e.g., output = "bar" => "bar/foo.html").
|
||||
pub fn render(input: PathBuf, options: RenderOptions, diag: &errors::Handler) -> i32 {
|
||||
pub fn render(
|
||||
input: PathBuf,
|
||||
options: RenderOptions,
|
||||
diag: &errors::Handler,
|
||||
edition: Edition
|
||||
) -> i32 {
|
||||
let mut output = options.output;
|
||||
output.push(input.file_stem().unwrap());
|
||||
output.set_extension("html");
|
||||
@ -76,9 +82,9 @@ pub fn render(input: PathBuf, options: RenderOptions, diag: &errors::Handler) ->
|
||||
let mut ids = IdMap::new();
|
||||
let error_codes = ErrorCodes::from(UnstableFeatures::from_environment().is_nightly_build());
|
||||
let text = if !options.markdown_no_toc {
|
||||
MarkdownWithToc(text, RefCell::new(&mut ids), error_codes).to_string()
|
||||
MarkdownWithToc(text, RefCell::new(&mut ids), error_codes, edition).to_string()
|
||||
} else {
|
||||
Markdown(text, &[], RefCell::new(&mut ids), error_codes).to_string()
|
||||
Markdown(text, &[], RefCell::new(&mut ids), error_codes, edition).to_string()
|
||||
};
|
||||
|
||||
let err = write!(
|
||||
|
@ -167,7 +167,7 @@ fn run_test(test: &str, cratename: &str, filename: &FileName, line: usize,
|
||||
maybe_sysroot: Option<PathBuf>, linker: Option<PathBuf>, edition: Edition,
|
||||
persist_doctests: Option<PathBuf>) {
|
||||
let (test, line_offset) = match panic::catch_unwind(|| {
|
||||
make_test(test, Some(cratename), as_test_harness, opts)
|
||||
make_test(test, Some(cratename), as_test_harness, opts, edition)
|
||||
}) {
|
||||
Ok((test, line_offset)) => (test, line_offset),
|
||||
Err(cause) if cause.is::<errors::FatalErrorMarker>() => {
|
||||
@ -356,7 +356,8 @@ fn run_test(test: &str, cratename: &str, filename: &FileName, line: usize,
|
||||
pub fn make_test(s: &str,
|
||||
cratename: Option<&str>,
|
||||
dont_insert_main: bool,
|
||||
opts: &TestOptions)
|
||||
opts: &TestOptions,
|
||||
edition: Edition)
|
||||
-> (String, usize) {
|
||||
let (crate_attrs, everything_else, crates) = partition_source(s);
|
||||
let everything_else = everything_else.trim();
|
||||
@ -390,6 +391,8 @@ pub fn make_test(s: &str,
|
||||
use errors::emitter::EmitterWriter;
|
||||
use errors::Handler;
|
||||
|
||||
syntax::ext::hygiene::set_default_edition(edition);
|
||||
|
||||
let filename = FileName::anon_source_code(s);
|
||||
let source = crates + &everything_else;
|
||||
|
||||
@ -397,6 +400,7 @@ pub fn make_test(s: &str,
|
||||
// send all the errors that libsyntax emits directly into a `Sink` instead of stderr.
|
||||
let cm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
|
||||
let emitter = EmitterWriter::new(box io::sink(), None, false, false, false);
|
||||
// FIXME(misdreavus): pass `-Z treat-err-as-bug` to the doctest parser
|
||||
let handler = Handler::with_emitter(false, None, box emitter);
|
||||
let sess = ParseSess::with_span_handler(handler, cm);
|
||||
|
||||
|
@ -15,6 +15,7 @@ use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
use std::cell::RefCell;
|
||||
|
||||
use syntax::edition::DEFAULT_EDITION;
|
||||
use syntax::diagnostics::metadata::{get_metadata_dir, ErrorMetadataMap, ErrorMetadata};
|
||||
|
||||
use rustdoc::html::markdown::{Markdown, IdMap, ErrorCodes, PLAYGROUND};
|
||||
@ -97,7 +98,8 @@ impl Formatter for HTMLFormatter {
|
||||
Some(ref desc) => {
|
||||
let mut id_map = self.0.borrow_mut();
|
||||
write!(output, "{}",
|
||||
Markdown(desc, &[], RefCell::new(&mut id_map), ErrorCodes::Yes))?
|
||||
Markdown(desc, &[], RefCell::new(&mut id_map),
|
||||
ErrorCodes::Yes, DEFAULT_EDITION))?
|
||||
},
|
||||
None => write!(output, "<p>No description.</p>\n")?,
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user