Skip to content

Commit

Permalink
Migrate more
Browse files Browse the repository at this point in the history
  • Loading branch information
cassaundra committed Jan 25, 2023
1 parent b177323 commit 0dcccb7
Show file tree
Hide file tree
Showing 7 changed files with 136 additions and 181 deletions.
19 changes: 19 additions & 0 deletions compiler/rustc_error_messages/locales/en-US/rustdoc.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -109,3 +109,22 @@ rustdoc_error_reading_file_not_utf8 =
rustdoc_error_loading_examples =
failed to load examples: {$error} (for path {$path})
rustdoc_anonymous_imports_cannot_be_inlined =
anonymous imports cannot be inlined
.import_span = anonymous import
rustdoc_invalid_codeblock_attribute =
unknown attribute `{$attr_name}`. Did you mean `{$suggested_attr_name}`?
.compile_fail = the code block will either not be tested if not marked as a rust one or won't fail if it compiles successfully
.should_panic = the code block will either not be tested if not marked as a rust one or won't fail if it doesn't panic when running
.no_run = the code block will either not be tested if not marked as a rust one or will be run (which you might not want)
.test_harness = the code block will either not be tested if not marked as a rust one or the code will be wrapped inside a main function
rustdoc_failed_to_read_file =
failed to read file {$path}: {$error}
rustdoc_bare_url_not_hyperlink =
this URL is not a hyperlink
.note = bare URLs are not automatically turned into clickable links
.suggestion = use an automatic link instead
13 changes: 5 additions & 8 deletions src/librustdoc/clean/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ use std::mem;
use thin_vec::ThinVec;

use crate::core::{self, DocContext, ImplTraitParam};
use crate::errors::AnonymousImportsCannotBeInlined;
use crate::formats::item_type::ItemType;
use crate::visit_ast::Module as DocModule;

Expand Down Expand Up @@ -2405,14 +2406,10 @@ fn clean_use_statement_inner<'tcx>(

if pub_underscore {
if let Some(ref inline) = inline_attr {
rustc_errors::struct_span_err!(
cx.tcx.sess,
inline.span(),
E0780,
"anonymous imports cannot be inlined"
)
.span_label(import.span, "anonymous import")
.emit();
cx.tcx.sess.emit_err(AnonymousImportsCannotBeInlined {
inline_span: inline.span(),
import_span: import.span,
});
}
}

Expand Down
69 changes: 69 additions & 0 deletions src/librustdoc/errors.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use rustc_errors::{DecorateLint, DiagnosticMessage};
use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
use rustc_span::Span;

Expand Down Expand Up @@ -179,3 +180,71 @@ pub struct ErrorLoadingExamples {
pub error: io::Error,
pub path: String,
}

#[derive(Diagnostic)]
#[diag(rustdoc_anonymous_imports_cannot_be_inlined, code = "E0780")]
pub struct AnonymousImportsCannotBeInlined {
#[primary_span]
pub inline_span: Span,
#[label(import_span)]
pub import_span: Span,
}

pub struct InvalidCodeblockAttribute<'a> {
pub attr_name: &'a str,
pub suggested_attr_kind: CodeblockAttributeKind,
}

impl<'a> DecorateLint<'a, ()> for InvalidCodeblockAttribute<'_> {
fn decorate_lint<'b>(
self,
diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>,
) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
use CodeblockAttributeKind::*;

diag.set_arg("attr_name", self.attr_name);
let suggested_attr_name = match self.suggested_attr_kind {
CompileFail => "compile_fail",
ShouldPanic => "should_panic",
NoRun => "no_run",
TestHarness => "test_harness",
};
diag.set_arg("suggested_attr_name", suggested_attr_name);
diag.subdiagnostic(self.suggested_attr_kind);
diag
}

fn msg(&self) -> DiagnosticMessage {
rustc_errors::fluent::rustdoc_invalid_codeblock_attribute
}
}

#[derive(Subdiagnostic)]
pub enum CodeblockAttributeKind {
#[help(compile_fail)]
CompileFail,
#[help(should_panic)]
ShouldPanic,
#[help(no_run)]
NoRun,
#[help(test_harness)]
TestHarness,
}

#[derive(Diagnostic)]
#[diag(rustdoc_failed_to_read_file)]
pub struct FailedToReadFile<'a> {
#[primary_span]
pub span: Span,
pub path: &'a Path,
pub error: io::Error,
}

#[derive(LintDiagnostic)]
#[note]
#[diag(rustdoc_bare_url_not_hyperlink)]
pub struct BareUrlNotHyperlink<'a> {
#[suggestion(code = "<{url}>", applicability = "machine-applicable")]
pub span: Span,
pub url: &'a str,
}
54 changes: 17 additions & 37 deletions src/librustdoc/html/markdown.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ use std::str;

use crate::clean::RenderedLink;
use crate::doctest;
use crate::errors::{CodeblockAttributeKind, InvalidCodeblockAttribute};
use crate::html::escape::Escape;
use crate::html::format::Buffer;
use crate::html::highlight;
Expand Down Expand Up @@ -803,7 +804,7 @@ impl<'tcx> ExtraInfo<'tcx> {
ExtraInfo { id: ExtraInfoId::Def(did), sp, tcx }
}

fn error_invalid_codeblock_attr(&self, msg: &str, help: &str) {
fn error_invalid_codeblock_attr(&self, name: &str, suggested_kind: CodeblockAttributeKind) {
let hir_id = match self.id {
ExtraInfoId::Hir(hir_id) => hir_id,
ExtraInfoId::Def(item_did) => {
Expand All @@ -816,12 +817,11 @@ impl<'tcx> ExtraInfo<'tcx> {
}
}
};
self.tcx.struct_span_lint_hir(
self.tcx.emit_spanned_lint(
crate::lint::INVALID_CODEBLOCK_ATTRIBUTES,
hir_id,
self.sp,
msg,
|lint| lint.help(help),
InvalidCodeblockAttribute { attr_name: name, suggested_attr_kind: suggested_kind },
);
}
}
Expand Down Expand Up @@ -956,41 +956,21 @@ impl LangString {
}
x if extra.is_some() => {
let s = x.to_lowercase();
if let Some((flag, help)) = if s == "compile-fail"
|| s == "compile_fail"
|| s == "compilefail"
if let Some(kind) =
if s == "compile-fail" || s == "compile_fail" || s == "compilefail" {
Some(CodeblockAttributeKind::CompileFail)
} else if s == "should-panic" || s == "should_panic" || s == "shouldpanic" {
Some(CodeblockAttributeKind::ShouldPanic)
} else if s == "no-run" || s == "no_run" || s == "norun" {
Some(CodeblockAttributeKind::NoRun)
} else if s == "test-harness" || s == "test_harness" || s == "testharness" {
Some(CodeblockAttributeKind::TestHarness)
} else {
None
}
{
Some((
"compile_fail",
"the code block will either not be tested if not marked as a rust one \
or won't fail if it compiles successfully",
))
} else if s == "should-panic" || s == "should_panic" || s == "shouldpanic" {
Some((
"should_panic",
"the code block will either not be tested if not marked as a rust one \
or won't fail if it doesn't panic when running",
))
} else if s == "no-run" || s == "no_run" || s == "norun" {
Some((
"no_run",
"the code block will either not be tested if not marked as a rust one \
or will be run (which you might not want)",
))
} else if s == "test-harness" || s == "test_harness" || s == "testharness" {
Some((
"test_harness",
"the code block will either not be tested if not marked as a rust one \
or the code will be wrapped inside a main function",
))
} else {
None
} {
if let Some(extra) = extra {
extra.error_invalid_codeblock_attr(
&format!("unknown attribute `{}`. Did you mean `{}`?", x, flag),
help,
);
extra.error_invalid_codeblock_attr(x, kind);
}
}
seen_other_tags = true;
Expand Down
6 changes: 3 additions & 3 deletions src/librustdoc/html/render/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ use serde::{Serialize, Serializer};

use crate::clean::{self, ItemId, RenderedLink, SelfTy};
use crate::error::Error;
use crate::errors::FailedToReadFile;
use crate::formats::cache::Cache;
use crate::formats::item_type::ItemType;
use crate::formats::{AssocItemRender, Impl, RenderMode};
Expand Down Expand Up @@ -2854,10 +2855,9 @@ fn render_call_locations(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Ite
let write_example = |w: &mut Buffer, (path, call_data): (&PathBuf, &CallData)| -> bool {
let contents = match fs::read_to_string(&path) {
Ok(contents) => contents,
Err(err) => {
Err(error) => {
let span = item.span(tcx).map_or(rustc_span::DUMMY_SP, |span| span.inner());
tcx.sess
.span_err(span, &format!("failed to read file {}: {}", path.display(), err));
tcx.sess.emit_err(FailedToReadFile { span, path, error });
return false;
}
};
Expand Down
58 changes: 22 additions & 36 deletions src/librustdoc/passes/lint/bare_urls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
use crate::clean::*;
use crate::core::DocContext;
use crate::errors::BareUrlNotHyperlink;
use crate::html::markdown::main_body_opts;
use crate::passes::source_span_for_markdown_range;
use core::ops::Range;
use pulldown_cmark::{Event, Parser, Tag};
use regex::Regex;
use rustc_errors::Applicability;
use std::mem;
use std::sync::LazyLock;

Expand All @@ -20,25 +20,31 @@ pub(super) fn visit_item(cx: &DocContext<'_>, item: &Item) {
};
let dox = item.attrs.collapsed_doc_value().unwrap_or_default();
if !dox.is_empty() {
let report_diag = |cx: &DocContext<'_>, msg: &str, url: &str, range: Range<usize>| {
let sp = source_span_for_markdown_range(cx.tcx, &dox, &range, &item.attrs)
.unwrap_or_else(|| item.attr_span(cx.tcx));
cx.tcx.struct_span_lint_hir(crate::lint::BARE_URLS, hir_id, sp, msg, |lint| {
lint.note("bare URLs are not automatically turned into clickable links")
.span_suggestion(
sp,
"use an automatic link instead",
format!("<{}>", url),
Applicability::MachineApplicable,
)
});
};

let mut p = Parser::new_ext(&dox, main_body_opts()).into_offset_iter();

while let Some((event, range)) = p.next() {
match event {
Event::Text(s) => find_raw_urls(cx, &s, range, &report_diag),
Event::Text(text) => {
trace!("looking for raw urls in {}", text);
// For now, we only check "full" URLs (meaning, starting with "http://" or "https://").
for match_ in URL_REGEX.find_iter(&text) {
let url = match_.as_str();
let url_range = match_.range();
let range = Range {
start: range.start + url_range.start,
end: range.start + url_range.end,
};
let span =
source_span_for_markdown_range(cx.tcx, &dox, &range, &item.attrs)
.unwrap_or_else(|| item.attr_span(cx.tcx));
cx.tcx.emit_spanned_lint(
crate::lint::BARE_URLS,
hir_id,
span,
BareUrlNotHyperlink { span, url },
);
}
}
// We don't want to check the text inside code blocks or links.
Event::Start(tag @ (Tag::CodeBlock(_) | Tag::Link(..))) => {
while let Some((event, _)) = p.next() {
Expand Down Expand Up @@ -67,23 +73,3 @@ static URL_REGEX: LazyLock<Regex> = LazyLock::new(|| {
))
.expect("failed to build regex")
});

fn find_raw_urls(
cx: &DocContext<'_>,
text: &str,
range: Range<usize>,
f: &impl Fn(&DocContext<'_>, &str, &str, Range<usize>),
) {
trace!("looking for raw urls in {}", text);
// For now, we only check "full" URLs (meaning, starting with "http://" or "https://").
for match_ in URL_REGEX.find_iter(text) {
let url = match_.as_str();
let url_range = match_.range();
f(
cx,
"this URL is not a hyperlink",
url,
Range { start: range.start + url_range.start, end: range.start + url_range.end },
);
}
}
Loading

0 comments on commit 0dcccb7

Please sign in to comment.