Auto merge of #109824 - GuillaumeGomez:rollup-i5r4uts, r=GuillaumeGomez
Rollup of 7 pull requests Successful merges: - #109104 (rustdoc: Fix invalid suggestions on ambiguous intra doc links v2) - #109443 (Move `doc(primitive)` future incompat warning to `invalid_doc_attributes`) - #109680 (Fix subslice capture in closure) - #109798 (fluent_messages macro: don't emit the OS error in a note) - #109805 (Source map cleanups) - #109818 (rustdoc: Add GUI test for jump to collapsed item) - #109820 (rustdoc-search: update docs for comma in `?` help popover) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
5e1d3299a2
83 changed files with 1025 additions and 411 deletions
|
@ -54,7 +54,7 @@ impl base::BangProcMacro for BangProcMacro {
|
||||||
) -> Result<TokenStream, ErrorGuaranteed> {
|
) -> Result<TokenStream, ErrorGuaranteed> {
|
||||||
let _timer =
|
let _timer =
|
||||||
ecx.sess.prof.generic_activity_with_arg_recorder("expand_proc_macro", |recorder| {
|
ecx.sess.prof.generic_activity_with_arg_recorder("expand_proc_macro", |recorder| {
|
||||||
recorder.record_arg_with_span(ecx.expansion_descr(), span);
|
recorder.record_arg_with_span(ecx.sess.source_map(), ecx.expansion_descr(), span);
|
||||||
});
|
});
|
||||||
|
|
||||||
let proc_macro_backtrace = ecx.ecfg.proc_macro_backtrace;
|
let proc_macro_backtrace = ecx.ecfg.proc_macro_backtrace;
|
||||||
|
@ -85,7 +85,7 @@ impl base::AttrProcMacro for AttrProcMacro {
|
||||||
) -> Result<TokenStream, ErrorGuaranteed> {
|
) -> Result<TokenStream, ErrorGuaranteed> {
|
||||||
let _timer =
|
let _timer =
|
||||||
ecx.sess.prof.generic_activity_with_arg_recorder("expand_proc_macro", |recorder| {
|
ecx.sess.prof.generic_activity_with_arg_recorder("expand_proc_macro", |recorder| {
|
||||||
recorder.record_arg_with_span(ecx.expansion_descr(), span);
|
recorder.record_arg_with_span(ecx.sess.source_map(), ecx.expansion_descr(), span);
|
||||||
});
|
});
|
||||||
|
|
||||||
let proc_macro_backtrace = ecx.ecfg.proc_macro_backtrace;
|
let proc_macro_backtrace = ecx.ecfg.proc_macro_backtrace;
|
||||||
|
@ -134,7 +134,11 @@ impl MultiItemModifier for DeriveProcMacro {
|
||||||
let stream = {
|
let stream = {
|
||||||
let _timer =
|
let _timer =
|
||||||
ecx.sess.prof.generic_activity_with_arg_recorder("expand_proc_macro", |recorder| {
|
ecx.sess.prof.generic_activity_with_arg_recorder("expand_proc_macro", |recorder| {
|
||||||
recorder.record_arg_with_span(ecx.expansion_descr(), span);
|
recorder.record_arg_with_span(
|
||||||
|
ecx.sess.source_map(),
|
||||||
|
ecx.expansion_descr(),
|
||||||
|
span,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
let proc_macro_backtrace = ecx.ecfg.proc_macro_backtrace;
|
let proc_macro_backtrace = ecx.ecfg.proc_macro_backtrace;
|
||||||
let strategy = exec_strategy(ecx);
|
let strategy = exec_strategy(ecx);
|
||||||
|
|
|
@ -225,7 +225,7 @@ declare_features! (
|
||||||
(active, rustc_allow_const_fn_unstable, "1.49.0", Some(69399), None),
|
(active, rustc_allow_const_fn_unstable, "1.49.0", Some(69399), None),
|
||||||
/// Allows using compiler's own crates.
|
/// Allows using compiler's own crates.
|
||||||
(active, rustc_private, "1.0.0", Some(27812), None),
|
(active, rustc_private, "1.0.0", Some(27812), None),
|
||||||
/// Allows using internal rustdoc features like `doc(primitive)` or `doc(keyword)`.
|
/// Allows using internal rustdoc features like `doc(keyword)`.
|
||||||
(active, rustdoc_internals, "1.58.0", Some(90418), None),
|
(active, rustdoc_internals, "1.58.0", Some(90418), None),
|
||||||
/// Allows using the `rustdoc::missing_doc_code_examples` lint
|
/// Allows using the `rustdoc::missing_doc_code_examples` lint
|
||||||
(active, rustdoc_missing_doc_code_examples, "1.31.0", Some(101730), None),
|
(active, rustdoc_missing_doc_code_examples, "1.31.0", Some(101730), None),
|
||||||
|
|
|
@ -778,6 +778,10 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
|
||||||
definition of a trait, it's currently in experimental form and should be changed before \
|
definition of a trait, it's currently in experimental form and should be changed before \
|
||||||
being exposed outside of the std"
|
being exposed outside of the std"
|
||||||
),
|
),
|
||||||
|
rustc_attr!(
|
||||||
|
rustc_doc_primitive, Normal, template!(NameValueStr: "primitive name"), ErrorFollowing,
|
||||||
|
r#"`rustc_doc_primitive` is a rustc internal attribute"#,
|
||||||
|
),
|
||||||
|
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
// Internal attributes, Testing:
|
// Internal attributes, Testing:
|
||||||
|
|
|
@ -1893,14 +1893,13 @@ fn restrict_capture_precision(
|
||||||
|
|
||||||
for (i, proj) in place.projections.iter().enumerate() {
|
for (i, proj) in place.projections.iter().enumerate() {
|
||||||
match proj.kind {
|
match proj.kind {
|
||||||
ProjectionKind::Index => {
|
ProjectionKind::Index | ProjectionKind::Subslice => {
|
||||||
// Arrays are completely captured, so we drop Index projections
|
// Arrays are completely captured, so we drop Index and Subslice projections
|
||||||
truncate_place_to_len_and_update_capture_kind(&mut place, &mut curr_mode, i);
|
truncate_place_to_len_and_update_capture_kind(&mut place, &mut curr_mode, i);
|
||||||
return (place, curr_mode);
|
return (place, curr_mode);
|
||||||
}
|
}
|
||||||
ProjectionKind::Deref => {}
|
ProjectionKind::Deref => {}
|
||||||
ProjectionKind::Field(..) => {} // ignore
|
ProjectionKind::Field(..) => {} // ignore
|
||||||
ProjectionKind::Subslice => {} // We never capture this
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -292,7 +292,7 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
|
||||||
override_queries: config.override_queries,
|
override_queries: config.override_queries,
|
||||||
};
|
};
|
||||||
|
|
||||||
rustc_span::with_source_map(compiler.sess.parse_sess.clone_source_map(), move || {
|
rustc_span::set_source_map(compiler.sess.parse_sess.clone_source_map(), move || {
|
||||||
let r = {
|
let r = {
|
||||||
let _sess_abort_error = OnDrop(|| {
|
let _sess_abort_error = OnDrop(|| {
|
||||||
compiler.sess.finish_diagnostics(registry);
|
compiler.sess.finish_diagnostics(registry);
|
||||||
|
|
|
@ -15,8 +15,7 @@ use proc_macro2::TokenStream;
|
||||||
use quote::quote;
|
use quote::quote;
|
||||||
use std::{
|
use std::{
|
||||||
collections::{HashMap, HashSet},
|
collections::{HashMap, HashSet},
|
||||||
fs::File,
|
fs::read_to_string,
|
||||||
io::Read,
|
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
};
|
};
|
||||||
use syn::{parse_macro_input, Ident, LitStr};
|
use syn::{parse_macro_input, Ident, LitStr};
|
||||||
|
@ -95,22 +94,18 @@ pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::Tok
|
||||||
|
|
||||||
// As this macro also outputs an `include_str!` for this file, the macro will always be
|
// As this macro also outputs an `include_str!` for this file, the macro will always be
|
||||||
// re-executed when the file changes.
|
// re-executed when the file changes.
|
||||||
let mut resource_file = match File::open(absolute_ftl_path) {
|
let resource_contents = match read_to_string(absolute_ftl_path) {
|
||||||
Ok(resource_file) => resource_file,
|
Ok(resource_contents) => resource_contents,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
Diagnostic::spanned(resource_span, Level::Error, "could not open Fluent resource")
|
Diagnostic::spanned(
|
||||||
.note(e.to_string())
|
resource_span,
|
||||||
|
Level::Error,
|
||||||
|
format!("could not open Fluent resource: {}", e.to_string()),
|
||||||
|
)
|
||||||
.emit();
|
.emit();
|
||||||
return failed(&crate_name);
|
return failed(&crate_name);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let mut resource_contents = String::new();
|
|
||||||
if let Err(e) = resource_file.read_to_string(&mut resource_contents) {
|
|
||||||
Diagnostic::spanned(resource_span, Level::Error, "could not read Fluent resource")
|
|
||||||
.note(e.to_string())
|
|
||||||
.emit();
|
|
||||||
return failed(&crate_name);
|
|
||||||
}
|
|
||||||
let mut bad = false;
|
let mut bad = false;
|
||||||
for esc in ["\\n", "\\\"", "\\'"] {
|
for esc in ["\\n", "\\\"", "\\'"] {
|
||||||
for _ in resource_contents.matches(esc) {
|
for _ in resource_contents.matches(esc) {
|
||||||
|
|
|
@ -148,9 +148,6 @@ passes_doc_test_unknown =
|
||||||
passes_doc_test_takes_list =
|
passes_doc_test_takes_list =
|
||||||
`#[doc(test(...)]` takes a list of attributes
|
`#[doc(test(...)]` takes a list of attributes
|
||||||
|
|
||||||
passes_doc_primitive =
|
|
||||||
`doc(primitive)` should never have been stable
|
|
||||||
|
|
||||||
passes_doc_cfg_hide_takes_list =
|
passes_doc_cfg_hide_takes_list =
|
||||||
`#[doc(cfg_hide(...)]` takes a list of attributes
|
`#[doc(cfg_hide(...)]` takes a list of attributes
|
||||||
|
|
||||||
|
|
|
@ -1109,17 +1109,6 @@ impl CheckAttrVisitor<'_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sym::primitive => {
|
|
||||||
if !self.tcx.features().rustdoc_internals {
|
|
||||||
self.tcx.emit_spanned_lint(
|
|
||||||
INVALID_DOC_ATTRIBUTES,
|
|
||||||
hir_id,
|
|
||||||
i_meta.span,
|
|
||||||
errors::DocPrimitive,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_ => {
|
_ => {
|
||||||
let path = rustc_ast_pretty::pprust::path_to_string(&i_meta.path);
|
let path = rustc_ast_pretty::pprust::path_to_string(&i_meta.path);
|
||||||
if i_meta.has_name(sym::spotlight) {
|
if i_meta.has_name(sym::spotlight) {
|
||||||
|
|
|
@ -288,10 +288,6 @@ pub struct DocTestTakesList;
|
||||||
#[diag(passes_doc_cfg_hide_takes_list)]
|
#[diag(passes_doc_cfg_hide_takes_list)]
|
||||||
pub struct DocCfgHideTakesList;
|
pub struct DocCfgHideTakesList;
|
||||||
|
|
||||||
#[derive(LintDiagnostic)]
|
|
||||||
#[diag(passes_doc_primitive)]
|
|
||||||
pub struct DocPrimitive;
|
|
||||||
|
|
||||||
#[derive(LintDiagnostic)]
|
#[derive(LintDiagnostic)]
|
||||||
#[diag(passes_doc_test_unknown_any)]
|
#[diag(passes_doc_test_unknown_any)]
|
||||||
pub struct DocTestUnknownAny {
|
pub struct DocTestUnknownAny {
|
||||||
|
|
|
@ -339,12 +339,14 @@ pub fn inner_docs(attrs: &[ast::Attribute]) -> bool {
|
||||||
attrs.iter().find(|a| a.doc_str().is_some()).map_or(true, |a| a.style == ast::AttrStyle::Inner)
|
attrs.iter().find(|a| a.doc_str().is_some()).map_or(true, |a| a.style == ast::AttrStyle::Inner)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Has `#[doc(primitive)]` or `#[doc(keyword)]`.
|
/// Has `#[rustc_doc_primitive]` or `#[doc(keyword)]`.
|
||||||
pub fn has_primitive_or_keyword_docs(attrs: &[ast::Attribute]) -> bool {
|
pub fn has_primitive_or_keyword_docs(attrs: &[ast::Attribute]) -> bool {
|
||||||
for attr in attrs {
|
for attr in attrs {
|
||||||
if attr.has_name(sym::doc) && let Some(items) = attr.meta_item_list() {
|
if attr.has_name(sym::rustc_doc_primitive) {
|
||||||
|
return true;
|
||||||
|
} else if attr.has_name(sym::doc) && let Some(items) = attr.meta_item_list() {
|
||||||
for item in items {
|
for item in items {
|
||||||
if item.has_name(sym::primitive) || item.has_name(sym::keyword) {
|
if item.has_name(sym::keyword) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,6 +87,14 @@ pub struct SessionGlobals {
|
||||||
symbol_interner: symbol::Interner,
|
symbol_interner: symbol::Interner,
|
||||||
span_interner: Lock<span_encoding::SpanInterner>,
|
span_interner: Lock<span_encoding::SpanInterner>,
|
||||||
hygiene_data: Lock<hygiene::HygieneData>,
|
hygiene_data: Lock<hygiene::HygieneData>,
|
||||||
|
|
||||||
|
/// A reference to the source map in the `Session`. It's an `Option`
|
||||||
|
/// because it can't be initialized until `Session` is created, which
|
||||||
|
/// happens after `SessionGlobals`. `set_source_map` does the
|
||||||
|
/// initialization.
|
||||||
|
///
|
||||||
|
/// This field should only be used in places where the `Session` is truly
|
||||||
|
/// not available, such as `<Span as Debug>::fmt`.
|
||||||
source_map: Lock<Option<Lrc<SourceMap>>>,
|
source_map: Lock<Option<Lrc<SourceMap>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1013,16 +1021,9 @@ impl<D: Decoder> Decodable<D> for Span {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Calls the provided closure, using the provided `SourceMap` to format
|
/// Insert `source_map` into the session globals for the duration of the
|
||||||
/// any spans that are debug-printed during the closure's execution.
|
/// closure's execution.
|
||||||
///
|
pub fn set_source_map<T, F: FnOnce() -> T>(source_map: Lrc<SourceMap>, f: F) -> T {
|
||||||
/// Normally, the global `TyCtxt` is used to retrieve the `SourceMap`
|
|
||||||
/// (see `rustc_interface::callbacks::span_debug1`). However, some parts
|
|
||||||
/// of the compiler (e.g. `rustc_parse`) may debug-print `Span`s before
|
|
||||||
/// a `TyCtxt` is available. In this case, we fall back to
|
|
||||||
/// the `SourceMap` provided to this function. If that is not available,
|
|
||||||
/// we fall back to printing the raw `Span` field values.
|
|
||||||
pub fn with_source_map<T, F: FnOnce() -> T>(source_map: Lrc<SourceMap>, f: F) -> T {
|
|
||||||
with_session_globals(|session_globals| {
|
with_session_globals(|session_globals| {
|
||||||
*session_globals.source_map.borrow_mut() = Some(source_map);
|
*session_globals.source_map.borrow_mut() = Some(source_map);
|
||||||
});
|
});
|
||||||
|
@ -1041,6 +1042,8 @@ pub fn with_source_map<T, F: FnOnce() -> T>(source_map: Lrc<SourceMap>, f: F) ->
|
||||||
|
|
||||||
impl fmt::Debug for Span {
|
impl fmt::Debug for Span {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
// Use the global `SourceMap` to print the span. If that's not
|
||||||
|
// available, fall back to printing the raw values.
|
||||||
with_session_globals(|session_globals| {
|
with_session_globals(|session_globals| {
|
||||||
if let Some(source_map) = &*session_globals.source_map.borrow() {
|
if let Some(source_map) = &*session_globals.source_map.borrow() {
|
||||||
write!(f, "{} ({:?})", source_map.span_to_diagnostic_string(*self), self.ctxt())
|
write!(f, "{} ({:?})", source_map.span_to_diagnostic_string(*self), self.ctxt())
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use crate::source_map::SourceMap;
|
||||||
|
|
||||||
use std::borrow::Borrow;
|
use std::borrow::Borrow;
|
||||||
|
|
||||||
use rustc_data_structures::profiling::EventArgRecorder;
|
use rustc_data_structures::profiling::EventArgRecorder;
|
||||||
|
@ -11,25 +13,17 @@ pub trait SpannedEventArgRecorder {
|
||||||
///
|
///
|
||||||
/// Note: when self-profiling with costly event arguments, at least one argument
|
/// Note: when self-profiling with costly event arguments, at least one argument
|
||||||
/// needs to be recorded. A panic will be triggered if that doesn't happen.
|
/// needs to be recorded. A panic will be triggered if that doesn't happen.
|
||||||
fn record_arg_with_span<A>(&mut self, event_arg: A, span: crate::Span)
|
fn record_arg_with_span<A>(&mut self, source_map: &SourceMap, event_arg: A, span: crate::Span)
|
||||||
where
|
where
|
||||||
A: Borrow<str> + Into<String>;
|
A: Borrow<str> + Into<String>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SpannedEventArgRecorder for EventArgRecorder<'_> {
|
impl SpannedEventArgRecorder for EventArgRecorder<'_> {
|
||||||
fn record_arg_with_span<A>(&mut self, event_arg: A, span: crate::Span)
|
fn record_arg_with_span<A>(&mut self, source_map: &SourceMap, event_arg: A, span: crate::Span)
|
||||||
where
|
where
|
||||||
A: Borrow<str> + Into<String>,
|
A: Borrow<str> + Into<String>,
|
||||||
{
|
{
|
||||||
self.record_arg(event_arg);
|
self.record_arg(event_arg);
|
||||||
|
self.record_arg(source_map.span_to_embeddable_string(span));
|
||||||
let span_arg = crate::with_session_globals(|session_globals| {
|
|
||||||
if let Some(source_map) = &*session_globals.source_map.borrow() {
|
|
||||||
source_map.span_to_embeddable_string(span)
|
|
||||||
} else {
|
|
||||||
format!("{span:?}")
|
|
||||||
}
|
|
||||||
});
|
|
||||||
self.record_arg(span_arg);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1247,6 +1247,7 @@ symbols! {
|
||||||
rustc_diagnostic_macros,
|
rustc_diagnostic_macros,
|
||||||
rustc_dirty,
|
rustc_dirty,
|
||||||
rustc_do_not_const_check,
|
rustc_do_not_const_check,
|
||||||
|
rustc_doc_primitive,
|
||||||
rustc_dummy,
|
rustc_dummy,
|
||||||
rustc_dump_env_program_clauses,
|
rustc_dump_env_program_clauses,
|
||||||
rustc_dump_program_clauses,
|
rustc_dump_program_clauses,
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
// `library/{std,core}/src/primitive_docs.rs` should have the same contents.
|
// `library/{std,core}/src/primitive_docs.rs` should have the same contents.
|
||||||
// These are different files so that relative links work properly without
|
// These are different files so that relative links work properly without
|
||||||
// having to have `CARGO_PKG_NAME` set, but conceptually they should always be the same.
|
// having to have `CARGO_PKG_NAME` set, but conceptually they should always be the same.
|
||||||
#[doc(primitive = "bool")]
|
#[cfg_attr(bootstrap, doc(primitive = "bool"))]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "bool")]
|
||||||
#[doc(alias = "true")]
|
#[doc(alias = "true")]
|
||||||
#[doc(alias = "false")]
|
#[doc(alias = "false")]
|
||||||
/// The boolean type.
|
/// The boolean type.
|
||||||
|
@ -63,7 +64,8 @@
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
mod prim_bool {}
|
mod prim_bool {}
|
||||||
|
|
||||||
#[doc(primitive = "never")]
|
#[cfg_attr(bootstrap, doc(primitive = "never"))]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "never")]
|
||||||
#[doc(alias = "!")]
|
#[doc(alias = "!")]
|
||||||
//
|
//
|
||||||
/// The `!` type, also called "never".
|
/// The `!` type, also called "never".
|
||||||
|
@ -274,7 +276,8 @@ mod prim_bool {}
|
||||||
#[unstable(feature = "never_type", issue = "35121")]
|
#[unstable(feature = "never_type", issue = "35121")]
|
||||||
mod prim_never {}
|
mod prim_never {}
|
||||||
|
|
||||||
#[doc(primitive = "char")]
|
#[cfg_attr(bootstrap, doc(primitive = "char"))]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "char")]
|
||||||
#[allow(rustdoc::invalid_rust_codeblocks)]
|
#[allow(rustdoc::invalid_rust_codeblocks)]
|
||||||
/// A character type.
|
/// A character type.
|
||||||
///
|
///
|
||||||
|
@ -398,7 +401,8 @@ mod prim_never {}
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
mod prim_char {}
|
mod prim_char {}
|
||||||
|
|
||||||
#[doc(primitive = "unit")]
|
#[cfg_attr(bootstrap, doc(primitive = "unit"))]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "unit")]
|
||||||
#[doc(alias = "(")]
|
#[doc(alias = "(")]
|
||||||
#[doc(alias = ")")]
|
#[doc(alias = ")")]
|
||||||
#[doc(alias = "()")]
|
#[doc(alias = "()")]
|
||||||
|
@ -460,7 +464,8 @@ impl Copy for () {
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(primitive = "pointer")]
|
#[cfg_attr(bootstrap, doc(primitive = "pointer"))]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "pointer")]
|
||||||
#[doc(alias = "ptr")]
|
#[doc(alias = "ptr")]
|
||||||
#[doc(alias = "*")]
|
#[doc(alias = "*")]
|
||||||
#[doc(alias = "*const")]
|
#[doc(alias = "*const")]
|
||||||
|
@ -577,7 +582,8 @@ impl Copy for () {
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
mod prim_pointer {}
|
mod prim_pointer {}
|
||||||
|
|
||||||
#[doc(primitive = "array")]
|
#[cfg_attr(bootstrap, doc(primitive = "array"))]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "array")]
|
||||||
#[doc(alias = "[]")]
|
#[doc(alias = "[]")]
|
||||||
#[doc(alias = "[T;N]")] // unfortunately, rustdoc doesn't have fuzzy search for aliases
|
#[doc(alias = "[T;N]")] // unfortunately, rustdoc doesn't have fuzzy search for aliases
|
||||||
#[doc(alias = "[T; N]")]
|
#[doc(alias = "[T; N]")]
|
||||||
|
@ -778,7 +784,8 @@ mod prim_pointer {}
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
mod prim_array {}
|
mod prim_array {}
|
||||||
|
|
||||||
#[doc(primitive = "slice")]
|
#[cfg_attr(bootstrap, doc(primitive = "slice"))]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "slice")]
|
||||||
#[doc(alias = "[")]
|
#[doc(alias = "[")]
|
||||||
#[doc(alias = "]")]
|
#[doc(alias = "]")]
|
||||||
#[doc(alias = "[]")]
|
#[doc(alias = "[]")]
|
||||||
|
@ -870,7 +877,8 @@ mod prim_array {}
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
mod prim_slice {}
|
mod prim_slice {}
|
||||||
|
|
||||||
#[doc(primitive = "str")]
|
#[cfg_attr(bootstrap, doc(primitive = "str"))]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "str")]
|
||||||
/// String slices.
|
/// String slices.
|
||||||
///
|
///
|
||||||
/// *[See also the `std::str` module](crate::str).*
|
/// *[See also the `std::str` module](crate::str).*
|
||||||
|
@ -937,7 +945,8 @@ mod prim_slice {}
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
mod prim_str {}
|
mod prim_str {}
|
||||||
|
|
||||||
#[doc(primitive = "tuple")]
|
#[cfg_attr(bootstrap, doc(primitive = "tuple"))]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "tuple")]
|
||||||
#[doc(alias = "(")]
|
#[doc(alias = "(")]
|
||||||
#[doc(alias = ")")]
|
#[doc(alias = ")")]
|
||||||
#[doc(alias = "()")]
|
#[doc(alias = "()")]
|
||||||
|
@ -1081,7 +1090,8 @@ impl<T: Copy> Copy for (T,) {
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(primitive = "f32")]
|
#[cfg_attr(bootstrap, doc(primitive = "f32"))]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "f32")]
|
||||||
/// A 32-bit floating point type (specifically, the "binary32" type defined in IEEE 754-2008).
|
/// A 32-bit floating point type (specifically, the "binary32" type defined in IEEE 754-2008).
|
||||||
///
|
///
|
||||||
/// This type can represent a wide range of decimal numbers, like `3.5`, `27`,
|
/// This type can represent a wide range of decimal numbers, like `3.5`, `27`,
|
||||||
|
@ -1147,7 +1157,8 @@ impl<T: Copy> Copy for (T,) {
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
mod prim_f32 {}
|
mod prim_f32 {}
|
||||||
|
|
||||||
#[doc(primitive = "f64")]
|
#[cfg_attr(bootstrap, doc(primitive = "f64"))]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "f64")]
|
||||||
/// A 64-bit floating point type (specifically, the "binary64" type defined in IEEE 754-2008).
|
/// A 64-bit floating point type (specifically, the "binary64" type defined in IEEE 754-2008).
|
||||||
///
|
///
|
||||||
/// This type is very similar to [`f32`], but has increased
|
/// This type is very similar to [`f32`], but has increased
|
||||||
|
@ -1162,67 +1173,78 @@ mod prim_f32 {}
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
mod prim_f64 {}
|
mod prim_f64 {}
|
||||||
|
|
||||||
#[doc(primitive = "i8")]
|
#[cfg_attr(bootstrap, doc(primitive = "i8"))]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "i8")]
|
||||||
//
|
//
|
||||||
/// The 8-bit signed integer type.
|
/// The 8-bit signed integer type.
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
mod prim_i8 {}
|
mod prim_i8 {}
|
||||||
|
|
||||||
#[doc(primitive = "i16")]
|
#[cfg_attr(bootstrap, doc(primitive = "i16"))]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "i16")]
|
||||||
//
|
//
|
||||||
/// The 16-bit signed integer type.
|
/// The 16-bit signed integer type.
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
mod prim_i16 {}
|
mod prim_i16 {}
|
||||||
|
|
||||||
#[doc(primitive = "i32")]
|
#[cfg_attr(bootstrap, doc(primitive = "i32"))]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "i32")]
|
||||||
//
|
//
|
||||||
/// The 32-bit signed integer type.
|
/// The 32-bit signed integer type.
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
mod prim_i32 {}
|
mod prim_i32 {}
|
||||||
|
|
||||||
#[doc(primitive = "i64")]
|
#[cfg_attr(bootstrap, doc(primitive = "i64"))]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "i64")]
|
||||||
//
|
//
|
||||||
/// The 64-bit signed integer type.
|
/// The 64-bit signed integer type.
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
mod prim_i64 {}
|
mod prim_i64 {}
|
||||||
|
|
||||||
#[doc(primitive = "i128")]
|
#[cfg_attr(bootstrap, doc(primitive = "i128"))]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "i128")]
|
||||||
//
|
//
|
||||||
/// The 128-bit signed integer type.
|
/// The 128-bit signed integer type.
|
||||||
#[stable(feature = "i128", since = "1.26.0")]
|
#[stable(feature = "i128", since = "1.26.0")]
|
||||||
mod prim_i128 {}
|
mod prim_i128 {}
|
||||||
|
|
||||||
#[doc(primitive = "u8")]
|
#[cfg_attr(bootstrap, doc(primitive = "u8"))]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "u8")]
|
||||||
//
|
//
|
||||||
/// The 8-bit unsigned integer type.
|
/// The 8-bit unsigned integer type.
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
mod prim_u8 {}
|
mod prim_u8 {}
|
||||||
|
|
||||||
#[doc(primitive = "u16")]
|
#[cfg_attr(bootstrap, doc(primitive = "u16"))]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "u16")]
|
||||||
//
|
//
|
||||||
/// The 16-bit unsigned integer type.
|
/// The 16-bit unsigned integer type.
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
mod prim_u16 {}
|
mod prim_u16 {}
|
||||||
|
|
||||||
#[doc(primitive = "u32")]
|
#[cfg_attr(bootstrap, doc(primitive = "u32"))]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "u32")]
|
||||||
//
|
//
|
||||||
/// The 32-bit unsigned integer type.
|
/// The 32-bit unsigned integer type.
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
mod prim_u32 {}
|
mod prim_u32 {}
|
||||||
|
|
||||||
#[doc(primitive = "u64")]
|
#[cfg_attr(bootstrap, doc(primitive = "u64"))]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "u64")]
|
||||||
//
|
//
|
||||||
/// The 64-bit unsigned integer type.
|
/// The 64-bit unsigned integer type.
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
mod prim_u64 {}
|
mod prim_u64 {}
|
||||||
|
|
||||||
#[doc(primitive = "u128")]
|
#[cfg_attr(bootstrap, doc(primitive = "u128"))]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "u128")]
|
||||||
//
|
//
|
||||||
/// The 128-bit unsigned integer type.
|
/// The 128-bit unsigned integer type.
|
||||||
#[stable(feature = "i128", since = "1.26.0")]
|
#[stable(feature = "i128", since = "1.26.0")]
|
||||||
mod prim_u128 {}
|
mod prim_u128 {}
|
||||||
|
|
||||||
#[doc(primitive = "isize")]
|
#[cfg_attr(bootstrap, doc(primitive = "isize"))]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "isize")]
|
||||||
//
|
//
|
||||||
/// The pointer-sized signed integer type.
|
/// The pointer-sized signed integer type.
|
||||||
///
|
///
|
||||||
|
@ -1232,7 +1254,8 @@ mod prim_u128 {}
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
mod prim_isize {}
|
mod prim_isize {}
|
||||||
|
|
||||||
#[doc(primitive = "usize")]
|
#[cfg_attr(bootstrap, doc(primitive = "usize"))]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "usize")]
|
||||||
//
|
//
|
||||||
/// The pointer-sized unsigned integer type.
|
/// The pointer-sized unsigned integer type.
|
||||||
///
|
///
|
||||||
|
@ -1242,7 +1265,8 @@ mod prim_isize {}
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
mod prim_usize {}
|
mod prim_usize {}
|
||||||
|
|
||||||
#[doc(primitive = "reference")]
|
#[cfg_attr(bootstrap, doc(primitive = "reference"))]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "reference")]
|
||||||
#[doc(alias = "&")]
|
#[doc(alias = "&")]
|
||||||
#[doc(alias = "&mut")]
|
#[doc(alias = "&mut")]
|
||||||
//
|
//
|
||||||
|
@ -1373,7 +1397,8 @@ mod prim_usize {}
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
mod prim_ref {}
|
mod prim_ref {}
|
||||||
|
|
||||||
#[doc(primitive = "fn")]
|
#[cfg_attr(bootstrap, doc(primitive = "fn"))]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "fn")]
|
||||||
//
|
//
|
||||||
/// Function pointers, like `fn(usize) -> bool`.
|
/// Function pointers, like `fn(usize) -> bool`.
|
||||||
///
|
///
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
// `library/{std,core}/src/primitive_docs.rs` should have the same contents.
|
// `library/{std,core}/src/primitive_docs.rs` should have the same contents.
|
||||||
// These are different files so that relative links work properly without
|
// These are different files so that relative links work properly without
|
||||||
// having to have `CARGO_PKG_NAME` set, but conceptually they should always be the same.
|
// having to have `CARGO_PKG_NAME` set, but conceptually they should always be the same.
|
||||||
#[doc(primitive = "bool")]
|
#[cfg_attr(bootstrap, doc(primitive = "bool"))]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "bool")]
|
||||||
#[doc(alias = "true")]
|
#[doc(alias = "true")]
|
||||||
#[doc(alias = "false")]
|
#[doc(alias = "false")]
|
||||||
/// The boolean type.
|
/// The boolean type.
|
||||||
|
@ -63,7 +64,8 @@
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
mod prim_bool {}
|
mod prim_bool {}
|
||||||
|
|
||||||
#[doc(primitive = "never")]
|
#[cfg_attr(bootstrap, doc(primitive = "never"))]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "never")]
|
||||||
#[doc(alias = "!")]
|
#[doc(alias = "!")]
|
||||||
//
|
//
|
||||||
/// The `!` type, also called "never".
|
/// The `!` type, also called "never".
|
||||||
|
@ -274,7 +276,8 @@ mod prim_bool {}
|
||||||
#[unstable(feature = "never_type", issue = "35121")]
|
#[unstable(feature = "never_type", issue = "35121")]
|
||||||
mod prim_never {}
|
mod prim_never {}
|
||||||
|
|
||||||
#[doc(primitive = "char")]
|
#[cfg_attr(bootstrap, doc(primitive = "char"))]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "char")]
|
||||||
#[allow(rustdoc::invalid_rust_codeblocks)]
|
#[allow(rustdoc::invalid_rust_codeblocks)]
|
||||||
/// A character type.
|
/// A character type.
|
||||||
///
|
///
|
||||||
|
@ -398,7 +401,8 @@ mod prim_never {}
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
mod prim_char {}
|
mod prim_char {}
|
||||||
|
|
||||||
#[doc(primitive = "unit")]
|
#[cfg_attr(bootstrap, doc(primitive = "unit"))]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "unit")]
|
||||||
#[doc(alias = "(")]
|
#[doc(alias = "(")]
|
||||||
#[doc(alias = ")")]
|
#[doc(alias = ")")]
|
||||||
#[doc(alias = "()")]
|
#[doc(alias = "()")]
|
||||||
|
@ -460,7 +464,8 @@ impl Copy for () {
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(primitive = "pointer")]
|
#[cfg_attr(bootstrap, doc(primitive = "pointer"))]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "pointer")]
|
||||||
#[doc(alias = "ptr")]
|
#[doc(alias = "ptr")]
|
||||||
#[doc(alias = "*")]
|
#[doc(alias = "*")]
|
||||||
#[doc(alias = "*const")]
|
#[doc(alias = "*const")]
|
||||||
|
@ -577,7 +582,8 @@ impl Copy for () {
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
mod prim_pointer {}
|
mod prim_pointer {}
|
||||||
|
|
||||||
#[doc(primitive = "array")]
|
#[cfg_attr(bootstrap, doc(primitive = "array"))]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "array")]
|
||||||
#[doc(alias = "[]")]
|
#[doc(alias = "[]")]
|
||||||
#[doc(alias = "[T;N]")] // unfortunately, rustdoc doesn't have fuzzy search for aliases
|
#[doc(alias = "[T;N]")] // unfortunately, rustdoc doesn't have fuzzy search for aliases
|
||||||
#[doc(alias = "[T; N]")]
|
#[doc(alias = "[T; N]")]
|
||||||
|
@ -778,7 +784,8 @@ mod prim_pointer {}
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
mod prim_array {}
|
mod prim_array {}
|
||||||
|
|
||||||
#[doc(primitive = "slice")]
|
#[cfg_attr(bootstrap, doc(primitive = "slice"))]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "slice")]
|
||||||
#[doc(alias = "[")]
|
#[doc(alias = "[")]
|
||||||
#[doc(alias = "]")]
|
#[doc(alias = "]")]
|
||||||
#[doc(alias = "[]")]
|
#[doc(alias = "[]")]
|
||||||
|
@ -870,7 +877,8 @@ mod prim_array {}
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
mod prim_slice {}
|
mod prim_slice {}
|
||||||
|
|
||||||
#[doc(primitive = "str")]
|
#[cfg_attr(bootstrap, doc(primitive = "str"))]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "str")]
|
||||||
/// String slices.
|
/// String slices.
|
||||||
///
|
///
|
||||||
/// *[See also the `std::str` module](crate::str).*
|
/// *[See also the `std::str` module](crate::str).*
|
||||||
|
@ -937,7 +945,8 @@ mod prim_slice {}
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
mod prim_str {}
|
mod prim_str {}
|
||||||
|
|
||||||
#[doc(primitive = "tuple")]
|
#[cfg_attr(bootstrap, doc(primitive = "tuple"))]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "tuple")]
|
||||||
#[doc(alias = "(")]
|
#[doc(alias = "(")]
|
||||||
#[doc(alias = ")")]
|
#[doc(alias = ")")]
|
||||||
#[doc(alias = "()")]
|
#[doc(alias = "()")]
|
||||||
|
@ -1081,7 +1090,8 @@ impl<T: Copy> Copy for (T,) {
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(primitive = "f32")]
|
#[cfg_attr(bootstrap, doc(primitive = "f32"))]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "f32")]
|
||||||
/// A 32-bit floating point type (specifically, the "binary32" type defined in IEEE 754-2008).
|
/// A 32-bit floating point type (specifically, the "binary32" type defined in IEEE 754-2008).
|
||||||
///
|
///
|
||||||
/// This type can represent a wide range of decimal numbers, like `3.5`, `27`,
|
/// This type can represent a wide range of decimal numbers, like `3.5`, `27`,
|
||||||
|
@ -1147,7 +1157,8 @@ impl<T: Copy> Copy for (T,) {
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
mod prim_f32 {}
|
mod prim_f32 {}
|
||||||
|
|
||||||
#[doc(primitive = "f64")]
|
#[cfg_attr(bootstrap, doc(primitive = "f64"))]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "f64")]
|
||||||
/// A 64-bit floating point type (specifically, the "binary64" type defined in IEEE 754-2008).
|
/// A 64-bit floating point type (specifically, the "binary64" type defined in IEEE 754-2008).
|
||||||
///
|
///
|
||||||
/// This type is very similar to [`f32`], but has increased
|
/// This type is very similar to [`f32`], but has increased
|
||||||
|
@ -1162,67 +1173,78 @@ mod prim_f32 {}
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
mod prim_f64 {}
|
mod prim_f64 {}
|
||||||
|
|
||||||
#[doc(primitive = "i8")]
|
#[cfg_attr(bootstrap, doc(primitive = "i8"))]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "i8")]
|
||||||
//
|
//
|
||||||
/// The 8-bit signed integer type.
|
/// The 8-bit signed integer type.
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
mod prim_i8 {}
|
mod prim_i8 {}
|
||||||
|
|
||||||
#[doc(primitive = "i16")]
|
#[cfg_attr(bootstrap, doc(primitive = "i16"))]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "i16")]
|
||||||
//
|
//
|
||||||
/// The 16-bit signed integer type.
|
/// The 16-bit signed integer type.
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
mod prim_i16 {}
|
mod prim_i16 {}
|
||||||
|
|
||||||
#[doc(primitive = "i32")]
|
#[cfg_attr(bootstrap, doc(primitive = "i32"))]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "i32")]
|
||||||
//
|
//
|
||||||
/// The 32-bit signed integer type.
|
/// The 32-bit signed integer type.
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
mod prim_i32 {}
|
mod prim_i32 {}
|
||||||
|
|
||||||
#[doc(primitive = "i64")]
|
#[cfg_attr(bootstrap, doc(primitive = "i64"))]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "i64")]
|
||||||
//
|
//
|
||||||
/// The 64-bit signed integer type.
|
/// The 64-bit signed integer type.
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
mod prim_i64 {}
|
mod prim_i64 {}
|
||||||
|
|
||||||
#[doc(primitive = "i128")]
|
#[cfg_attr(bootstrap, doc(primitive = "i128"))]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "i128")]
|
||||||
//
|
//
|
||||||
/// The 128-bit signed integer type.
|
/// The 128-bit signed integer type.
|
||||||
#[stable(feature = "i128", since = "1.26.0")]
|
#[stable(feature = "i128", since = "1.26.0")]
|
||||||
mod prim_i128 {}
|
mod prim_i128 {}
|
||||||
|
|
||||||
#[doc(primitive = "u8")]
|
#[cfg_attr(bootstrap, doc(primitive = "u8"))]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "u8")]
|
||||||
//
|
//
|
||||||
/// The 8-bit unsigned integer type.
|
/// The 8-bit unsigned integer type.
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
mod prim_u8 {}
|
mod prim_u8 {}
|
||||||
|
|
||||||
#[doc(primitive = "u16")]
|
#[cfg_attr(bootstrap, doc(primitive = "u16"))]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "u16")]
|
||||||
//
|
//
|
||||||
/// The 16-bit unsigned integer type.
|
/// The 16-bit unsigned integer type.
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
mod prim_u16 {}
|
mod prim_u16 {}
|
||||||
|
|
||||||
#[doc(primitive = "u32")]
|
#[cfg_attr(bootstrap, doc(primitive = "u32"))]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "u32")]
|
||||||
//
|
//
|
||||||
/// The 32-bit unsigned integer type.
|
/// The 32-bit unsigned integer type.
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
mod prim_u32 {}
|
mod prim_u32 {}
|
||||||
|
|
||||||
#[doc(primitive = "u64")]
|
#[cfg_attr(bootstrap, doc(primitive = "u64"))]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "u64")]
|
||||||
//
|
//
|
||||||
/// The 64-bit unsigned integer type.
|
/// The 64-bit unsigned integer type.
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
mod prim_u64 {}
|
mod prim_u64 {}
|
||||||
|
|
||||||
#[doc(primitive = "u128")]
|
#[cfg_attr(bootstrap, doc(primitive = "u128"))]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "u128")]
|
||||||
//
|
//
|
||||||
/// The 128-bit unsigned integer type.
|
/// The 128-bit unsigned integer type.
|
||||||
#[stable(feature = "i128", since = "1.26.0")]
|
#[stable(feature = "i128", since = "1.26.0")]
|
||||||
mod prim_u128 {}
|
mod prim_u128 {}
|
||||||
|
|
||||||
#[doc(primitive = "isize")]
|
#[cfg_attr(bootstrap, doc(primitive = "isize"))]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "isize")]
|
||||||
//
|
//
|
||||||
/// The pointer-sized signed integer type.
|
/// The pointer-sized signed integer type.
|
||||||
///
|
///
|
||||||
|
@ -1232,7 +1254,8 @@ mod prim_u128 {}
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
mod prim_isize {}
|
mod prim_isize {}
|
||||||
|
|
||||||
#[doc(primitive = "usize")]
|
#[cfg_attr(bootstrap, doc(primitive = "usize"))]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "usize")]
|
||||||
//
|
//
|
||||||
/// The pointer-sized unsigned integer type.
|
/// The pointer-sized unsigned integer type.
|
||||||
///
|
///
|
||||||
|
@ -1242,7 +1265,8 @@ mod prim_isize {}
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
mod prim_usize {}
|
mod prim_usize {}
|
||||||
|
|
||||||
#[doc(primitive = "reference")]
|
#[cfg_attr(bootstrap, doc(primitive = "reference"))]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "reference")]
|
||||||
#[doc(alias = "&")]
|
#[doc(alias = "&")]
|
||||||
#[doc(alias = "&mut")]
|
#[doc(alias = "&mut")]
|
||||||
//
|
//
|
||||||
|
@ -1373,7 +1397,8 @@ mod prim_usize {}
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
mod prim_ref {}
|
mod prim_ref {}
|
||||||
|
|
||||||
#[doc(primitive = "fn")]
|
#[cfg_attr(bootstrap, doc(primitive = "fn"))]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "fn")]
|
||||||
//
|
//
|
||||||
/// Function pointers, like `fn(usize) -> bool`.
|
/// Function pointers, like `fn(usize) -> bool`.
|
||||||
///
|
///
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
0.14.5
|
0.14.6
|
|
@ -177,9 +177,9 @@ Book][unstable-masked] and [its tracking issue][issue-masked].
|
||||||
This is for Rust compiler internal use only.
|
This is for Rust compiler internal use only.
|
||||||
|
|
||||||
Since primitive types are defined in the compiler, there's no place to attach documentation
|
Since primitive types are defined in the compiler, there's no place to attach documentation
|
||||||
attributes. The `#[doc(primitive)]` attribute is used by the standard library to provide a way
|
attributes. The `#[rustc_doc_primitive = "..."]` attribute is used by the standard library to
|
||||||
to generate documentation for primitive types, and requires `#![feature(rustdoc_internals)]` to
|
provide a way to generate documentation for primitive types, and requires `#![feature(rustc_attrs)]`
|
||||||
enable.
|
to enable.
|
||||||
|
|
||||||
### Document keywords
|
### Document keywords
|
||||||
|
|
||||||
|
|
|
@ -249,38 +249,24 @@ impl ExternalCrate {
|
||||||
//
|
//
|
||||||
// Note that this loop only searches the top-level items of the crate,
|
// Note that this loop only searches the top-level items of the crate,
|
||||||
// and this is intentional. If we were to search the entire crate for an
|
// and this is intentional. If we were to search the entire crate for an
|
||||||
// item tagged with `#[doc(primitive)]` then we would also have to
|
// item tagged with `#[rustc_doc_primitive]` then we would also have to
|
||||||
// search the entirety of external modules for items tagged
|
// search the entirety of external modules for items tagged
|
||||||
// `#[doc(primitive)]`, which is a pretty inefficient process (decoding
|
// `#[rustc_doc_primitive]`, which is a pretty inefficient process (decoding
|
||||||
// all that metadata unconditionally).
|
// all that metadata unconditionally).
|
||||||
//
|
//
|
||||||
// In order to keep the metadata load under control, the
|
// In order to keep the metadata load under control, the
|
||||||
// `#[doc(primitive)]` feature is explicitly designed to only allow the
|
// `#[rustc_doc_primitive]` feature is explicitly designed to only allow the
|
||||||
// primitive tags to show up as the top level items in a crate.
|
// primitive tags to show up as the top level items in a crate.
|
||||||
//
|
//
|
||||||
// Also note that this does not attempt to deal with modules tagged
|
// Also note that this does not attempt to deal with modules tagged
|
||||||
// duplicately for the same primitive. This is handled later on when
|
// duplicately for the same primitive. This is handled later on when
|
||||||
// rendering by delegating everything to a hash map.
|
// rendering by delegating everything to a hash map.
|
||||||
let as_primitive = |res: Res<!>| {
|
let as_primitive = |res: Res<!>| {
|
||||||
if let Res::Def(DefKind::Mod, def_id) = res {
|
let Res::Def(DefKind::Mod, def_id) = res else { return None };
|
||||||
let mut prim = None;
|
tcx.get_attrs(def_id, sym::rustc_doc_primitive).find_map(|attr| {
|
||||||
let meta_items = tcx
|
|
||||||
.get_attrs(def_id, sym::doc)
|
|
||||||
.flat_map(|attr| attr.meta_item_list().unwrap_or_default());
|
|
||||||
for meta in meta_items {
|
|
||||||
if let Some(v) = meta.value_str() {
|
|
||||||
if meta.has_name(sym::primitive) {
|
|
||||||
prim = PrimitiveType::from_symbol(v);
|
|
||||||
if prim.is_some() {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// FIXME: should warn on unknown primitives?
|
// FIXME: should warn on unknown primitives?
|
||||||
}
|
Some((def_id, PrimitiveType::from_symbol(attr.value_str()?)?))
|
||||||
}
|
})
|
||||||
}
|
|
||||||
return prim.map(|p| (def_id, p));
|
|
||||||
}
|
|
||||||
None
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if root.is_local() {
|
if root.is_local() {
|
||||||
|
@ -1829,13 +1815,17 @@ impl PrimitiveType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the DefId of the module with `doc(primitive)` for this primitive type.
|
/// Returns the DefId of the module with `rustc_doc_primitive` for this primitive type.
|
||||||
/// Panics if there is no such module.
|
/// Panics if there is no such module.
|
||||||
///
|
///
|
||||||
/// This gives precedence to primitives defined in the current crate, and deprioritizes primitives defined in `core`,
|
/// This gives precedence to primitives defined in the current crate, and deprioritizes
|
||||||
/// but otherwise, if multiple crates define the same primitive, there is no guarantee of which will be picked.
|
/// primitives defined in `core`,
|
||||||
/// In particular, if a crate depends on both `std` and another crate that also defines `doc(primitive)`, then
|
/// but otherwise, if multiple crates define the same primitive, there is no guarantee of which
|
||||||
/// it's entirely random whether `std` or the other crate is picked. (no_std crates are usually fine unless multiple dependencies define a primitive.)
|
/// will be picked.
|
||||||
|
///
|
||||||
|
/// In particular, if a crate depends on both `std` and another crate that also defines
|
||||||
|
/// `rustc_doc_primitive`, then it's entirely random whether `std` or the other crate is picked.
|
||||||
|
/// (no_std crates are usually fine unless multiple dependencies define a primitive.)
|
||||||
pub(crate) fn primitive_locations(tcx: TyCtxt<'_>) -> &FxHashMap<PrimitiveType, DefId> {
|
pub(crate) fn primitive_locations(tcx: TyCtxt<'_>) -> &FxHashMap<PrimitiveType, DefId> {
|
||||||
static PRIMITIVE_LOCATIONS: OnceCell<FxHashMap<PrimitiveType, DefId>> = OnceCell::new();
|
static PRIMITIVE_LOCATIONS: OnceCell<FxHashMap<PrimitiveType, DefId>> = OnceCell::new();
|
||||||
PRIMITIVE_LOCATIONS.get_or_init(|| {
|
PRIMITIVE_LOCATIONS.get_or_init(|| {
|
||||||
|
|
|
@ -1016,9 +1016,7 @@ function preLoadCss(cssUrl) {
|
||||||
<code>enum</code>, <code>trait</code>, <code>type</code>, <code>macro</code>, \
|
<code>enum</code>, <code>trait</code>, <code>type</code>, <code>macro</code>, \
|
||||||
and <code>const</code>.",
|
and <code>const</code>.",
|
||||||
"Search functions by type signature (e.g., <code>vec -> usize</code> or \
|
"Search functions by type signature (e.g., <code>vec -> usize</code> or \
|
||||||
<code>-> vec</code>)",
|
<code>-> vec</code> or <code>String, enum:Cow -> bool</code>)",
|
||||||
"Search multiple things at once by splitting your query with comma (e.g., \
|
|
||||||
<code>str,u8</code> or <code>String,struct:Vec,test</code>)",
|
|
||||||
"You can look for items with an exact name by putting double quotes around \
|
"You can look for items with an exact name by putting double quotes around \
|
||||||
your request: <code>\"string\"</code>",
|
your request: <code>\"string\"</code>",
|
||||||
"Look for items inside another one by searching for a path: <code>vec::Vec</code>",
|
"Look for items inside another one by searching for a path: <code>vec::Vec</code>",
|
||||||
|
|
|
@ -249,9 +249,7 @@ pub(crate) fn id_from_item_inner(
|
||||||
// instead, we directly get the primitive symbol and convert it to u32 to
|
// instead, we directly get the primitive symbol and convert it to u32 to
|
||||||
// generate the ID.
|
// generate the ID.
|
||||||
if matches!(tcx.def_kind(def_id), DefKind::Mod) &&
|
if matches!(tcx.def_kind(def_id), DefKind::Mod) &&
|
||||||
let Some(prim) = tcx.get_attrs(*def_id, sym::doc)
|
let Some(prim) = tcx.get_attrs(*def_id, sym::rustc_doc_primitive)
|
||||||
.flat_map(|attr| attr.meta_item_list().unwrap_or_default())
|
|
||||||
.filter(|attr| attr.has_name(sym::primitive))
|
|
||||||
.find_map(|attr| attr.value_str()) {
|
.find_map(|attr| attr.value_str()) {
|
||||||
format!(":{}", prim.as_u32())
|
format!(":{}", prim.as_u32())
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -78,7 +78,7 @@ impl<'tcx> JsonRenderer<'tcx> {
|
||||||
// HACK(hkmatsumoto): For impls of primitive types, we index them
|
// HACK(hkmatsumoto): For impls of primitive types, we index them
|
||||||
// regardless of whether they're local. This is because users can
|
// regardless of whether they're local. This is because users can
|
||||||
// document primitive items in an arbitrary crate by using
|
// document primitive items in an arbitrary crate by using
|
||||||
// `doc(primitive)`.
|
// `rustc_doc_primitive`.
|
||||||
let mut is_primitive_impl = false;
|
let mut is_primitive_impl = false;
|
||||||
if let clean::types::ItemKind::ImplItem(ref impl_) = *item.kind &&
|
if let clean::types::ItemKind::ImplItem(ref impl_) = *item.kind &&
|
||||||
impl_.trait_.is_none() &&
|
impl_.trait_.is_none() &&
|
||||||
|
|
|
@ -47,7 +47,18 @@ fn collect_intra_doc_links(krate: Crate, cx: &mut DocContext<'_>) -> Crate {
|
||||||
krate
|
krate
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Hash)]
|
fn filter_assoc_items_by_name_and_namespace<'a>(
|
||||||
|
tcx: TyCtxt<'a>,
|
||||||
|
assoc_items_of: DefId,
|
||||||
|
ident: Ident,
|
||||||
|
ns: Namespace,
|
||||||
|
) -> impl Iterator<Item = &ty::AssocItem> + 'a {
|
||||||
|
tcx.associated_items(assoc_items_of).filter_by_name_unhygienic(ident.name).filter(move |item| {
|
||||||
|
item.kind.namespace() == ns && tcx.hygienic_eq(ident, item.ident(tcx), assoc_items_of)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, Hash, PartialEq)]
|
||||||
enum Res {
|
enum Res {
|
||||||
Def(DefKind, DefId),
|
Def(DefKind, DefId),
|
||||||
Primitive(PrimitiveType),
|
Primitive(PrimitiveType),
|
||||||
|
@ -59,7 +70,7 @@ impl Res {
|
||||||
fn descr(self) -> &'static str {
|
fn descr(self) -> &'static str {
|
||||||
match self {
|
match self {
|
||||||
Res::Def(kind, id) => ResolveRes::Def(kind, id).descr(),
|
Res::Def(kind, id) => ResolveRes::Def(kind, id).descr(),
|
||||||
Res::Primitive(_) => "builtin type",
|
Res::Primitive(_) => "primitive type",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -317,14 +328,21 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
|
||||||
prim_ty: PrimitiveType,
|
prim_ty: PrimitiveType,
|
||||||
ns: Namespace,
|
ns: Namespace,
|
||||||
item_name: Symbol,
|
item_name: Symbol,
|
||||||
) -> Option<(Res, DefId)> {
|
) -> Vec<(Res, DefId)> {
|
||||||
let tcx = self.cx.tcx;
|
let tcx = self.cx.tcx;
|
||||||
|
|
||||||
prim_ty.impls(tcx).find_map(|impl_| {
|
prim_ty
|
||||||
tcx.associated_items(impl_)
|
.impls(tcx)
|
||||||
.find_by_name_and_namespace(tcx, Ident::with_dummy_span(item_name), ns, impl_)
|
.flat_map(|impl_| {
|
||||||
|
filter_assoc_items_by_name_and_namespace(
|
||||||
|
tcx,
|
||||||
|
impl_,
|
||||||
|
Ident::with_dummy_span(item_name),
|
||||||
|
ns,
|
||||||
|
)
|
||||||
.map(|item| (Res::Primitive(prim_ty), item.def_id))
|
.map(|item| (Res::Primitive(prim_ty), item.def_id))
|
||||||
})
|
})
|
||||||
|
.collect::<Vec<_>>()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_self_ty(&self, path_str: &str, ns: Namespace, item_id: DefId) -> Option<Res> {
|
fn resolve_self_ty(&self, path_str: &str, ns: Namespace, item_id: DefId) -> Option<Res> {
|
||||||
|
@ -394,14 +412,16 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
|
||||||
ns: Namespace,
|
ns: Namespace,
|
||||||
item_id: DefId,
|
item_id: DefId,
|
||||||
module_id: DefId,
|
module_id: DefId,
|
||||||
) -> Result<(Res, Option<DefId>), UnresolvedPath<'path>> {
|
) -> Result<Vec<(Res, Option<DefId>)>, UnresolvedPath<'path>> {
|
||||||
if let Some(res) = self.resolve_path(path_str, ns, item_id, module_id) {
|
if let Some(res) = self.resolve_path(path_str, ns, item_id, module_id) {
|
||||||
return Ok(match res {
|
return Ok(match res {
|
||||||
Res::Def(
|
Res::Def(
|
||||||
DefKind::AssocFn | DefKind::AssocConst | DefKind::AssocTy | DefKind::Variant,
|
DefKind::AssocFn | DefKind::AssocConst | DefKind::AssocTy | DefKind::Variant,
|
||||||
def_id,
|
def_id,
|
||||||
) => (Res::from_def_id(self.cx.tcx, self.cx.tcx.parent(def_id)), Some(def_id)),
|
) => {
|
||||||
_ => (res, None),
|
vec![(Res::from_def_id(self.cx.tcx, self.cx.tcx.parent(def_id)), Some(def_id))]
|
||||||
|
}
|
||||||
|
_ => vec![(res, None)],
|
||||||
});
|
});
|
||||||
} else if ns == MacroNS {
|
} else if ns == MacroNS {
|
||||||
return Err(UnresolvedPath {
|
return Err(UnresolvedPath {
|
||||||
|
@ -433,17 +453,24 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
// FIXME(#83862): this arbitrarily gives precedence to primitives over modules to support
|
// FIXME(#83862): this arbitrarily gives precedence to primitives over modules to support
|
||||||
// links to primitives when `#[doc(primitive)]` is present. It should give an ambiguity
|
// links to primitives when `#[rustc_doc_primitive]` is present. It should give an ambiguity
|
||||||
// error instead and special case *only* modules with `#[doc(primitive)]`, not all
|
// error instead and special case *only* modules with `#[rustc_doc_primitive]`, not all
|
||||||
// primitives.
|
// primitives.
|
||||||
resolve_primitive(&path_root, TypeNS)
|
match resolve_primitive(&path_root, TypeNS)
|
||||||
.or_else(|| self.resolve_path(&path_root, TypeNS, item_id, module_id))
|
.or_else(|| self.resolve_path(&path_root, TypeNS, item_id, module_id))
|
||||||
.and_then(|ty_res| {
|
.and_then(|ty_res| {
|
||||||
self.resolve_associated_item(ty_res, item_name, ns, module_id).map(Ok)
|
let candidates = self
|
||||||
})
|
.resolve_associated_item(ty_res, item_name, ns, module_id)
|
||||||
.unwrap_or_else(|| {
|
.into_iter()
|
||||||
|
.map(|(res, def_id)| (res, Some(def_id)))
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
if !candidates.is_empty() { Some(candidates) } else { None }
|
||||||
|
}) {
|
||||||
|
Some(r) => Ok(r),
|
||||||
|
None => {
|
||||||
if ns == Namespace::ValueNS {
|
if ns == Namespace::ValueNS {
|
||||||
self.variant_field(path_str, item_id, module_id)
|
self.variant_field(path_str, item_id, module_id)
|
||||||
|
.map(|(res, def_id)| vec![(res, Some(def_id))])
|
||||||
} else {
|
} else {
|
||||||
Err(UnresolvedPath {
|
Err(UnresolvedPath {
|
||||||
item_id,
|
item_id,
|
||||||
|
@ -452,8 +479,8 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
|
||||||
unresolved: path_root.into(),
|
unresolved: path_root.into(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
.map(|(res, def_id)| (res, Some(def_id)))
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert a DefId to a Res, where possible.
|
/// Convert a DefId to a Res, where possible.
|
||||||
|
@ -535,24 +562,31 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
|
||||||
item_name: Symbol,
|
item_name: Symbol,
|
||||||
ns: Namespace,
|
ns: Namespace,
|
||||||
module_id: DefId,
|
module_id: DefId,
|
||||||
) -> Option<(Res, DefId)> {
|
) -> Vec<(Res, DefId)> {
|
||||||
let tcx = self.cx.tcx;
|
let tcx = self.cx.tcx;
|
||||||
|
|
||||||
match root_res {
|
match root_res {
|
||||||
Res::Primitive(prim) => {
|
Res::Primitive(prim) => {
|
||||||
self.resolve_primitive_associated_item(prim, ns, item_name).or_else(|| {
|
let items = self.resolve_primitive_associated_item(prim, ns, item_name);
|
||||||
|
if !items.is_empty() {
|
||||||
|
items
|
||||||
|
// Inherent associated items take precedence over items that come from trait impls.
|
||||||
|
} else {
|
||||||
self.primitive_type_to_ty(prim)
|
self.primitive_type_to_ty(prim)
|
||||||
.and_then(|ty| {
|
.map(|ty| {
|
||||||
resolve_associated_trait_item(ty, module_id, item_name, ns, self.cx)
|
resolve_associated_trait_item(ty, module_id, item_name, ns, self.cx)
|
||||||
})
|
.iter()
|
||||||
.map(|item| (root_res, item.def_id))
|
.map(|item| (root_res, item.def_id))
|
||||||
|
.collect::<Vec<_>>()
|
||||||
})
|
})
|
||||||
|
.unwrap_or(Vec::new())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Res::Def(DefKind::TyAlias, did) => {
|
Res::Def(DefKind::TyAlias, did) => {
|
||||||
// Resolve the link on the type the alias points to.
|
// Resolve the link on the type the alias points to.
|
||||||
// FIXME: if the associated item is defined directly on the type alias,
|
// FIXME: if the associated item is defined directly on the type alias,
|
||||||
// it will show up on its documentation page, we should link there instead.
|
// it will show up on its documentation page, we should link there instead.
|
||||||
let res = self.def_id_to_res(did)?;
|
let Some(res) = self.def_id_to_res(did) else { return Vec::new() };
|
||||||
self.resolve_associated_item(res, item_name, ns, module_id)
|
self.resolve_associated_item(res, item_name, ns, module_id)
|
||||||
}
|
}
|
||||||
Res::Def(
|
Res::Def(
|
||||||
|
@ -566,7 +600,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
|
||||||
ty::Adt(adt_def, _) => {
|
ty::Adt(adt_def, _) => {
|
||||||
for variant in adt_def.variants() {
|
for variant in adt_def.variants() {
|
||||||
if variant.name == item_name {
|
if variant.name == item_name {
|
||||||
return Some((root_res, variant.def_id));
|
return vec![(root_res, variant.def_id)];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -575,43 +609,46 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checks if item_name belongs to `impl SomeItem`
|
// Checks if item_name belongs to `impl SomeItem`
|
||||||
let assoc_item = tcx
|
let mut assoc_items: Vec<_> = tcx
|
||||||
.inherent_impls(did)
|
.inherent_impls(did)
|
||||||
.iter()
|
.iter()
|
||||||
.flat_map(|&imp| {
|
.flat_map(|&imp| {
|
||||||
tcx.associated_items(imp).find_by_name_and_namespace(
|
filter_assoc_items_by_name_and_namespace(
|
||||||
tcx,
|
tcx,
|
||||||
|
imp,
|
||||||
Ident::with_dummy_span(item_name),
|
Ident::with_dummy_span(item_name),
|
||||||
ns,
|
ns,
|
||||||
imp,
|
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.copied()
|
.map(|item| (root_res, item.def_id))
|
||||||
// There should only ever be one associated item that matches from any inherent impl
|
.collect();
|
||||||
.next()
|
|
||||||
|
if assoc_items.is_empty() {
|
||||||
// Check if item_name belongs to `impl SomeTrait for SomeItem`
|
// Check if item_name belongs to `impl SomeTrait for SomeItem`
|
||||||
// FIXME(#74563): This gives precedence to `impl SomeItem`:
|
// FIXME(#74563): This gives precedence to `impl SomeItem`:
|
||||||
// Although having both would be ambiguous, use impl version for compatibility's sake.
|
// Although having both would be ambiguous, use impl version for compatibility's sake.
|
||||||
// To handle that properly resolve() would have to support
|
// To handle that properly resolve() would have to support
|
||||||
// something like [`ambi_fn`](<SomeStruct as SomeTrait>::ambi_fn)
|
// something like [`ambi_fn`](<SomeStruct as SomeTrait>::ambi_fn)
|
||||||
.or_else(|| {
|
assoc_items = resolve_associated_trait_item(
|
||||||
resolve_associated_trait_item(
|
|
||||||
tcx.type_of(did).subst_identity(),
|
tcx.type_of(did).subst_identity(),
|
||||||
module_id,
|
module_id,
|
||||||
item_name,
|
item_name,
|
||||||
ns,
|
ns,
|
||||||
self.cx,
|
self.cx,
|
||||||
)
|
)
|
||||||
});
|
.into_iter()
|
||||||
|
.map(|item| (root_res, item.def_id))
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
}
|
||||||
|
|
||||||
debug!("got associated item {:?}", assoc_item);
|
debug!("got associated item {:?}", assoc_items);
|
||||||
|
|
||||||
if let Some(item) = assoc_item {
|
if !assoc_items.is_empty() {
|
||||||
return Some((root_res, item.def_id));
|
return assoc_items;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ns != Namespace::ValueNS {
|
if ns != Namespace::ValueNS {
|
||||||
return None;
|
return Vec::new();
|
||||||
}
|
}
|
||||||
debug!("looking for fields named {} for {:?}", item_name, did);
|
debug!("looking for fields named {} for {:?}", item_name, did);
|
||||||
// FIXME: this doesn't really belong in `associated_item` (maybe `variant_field` is better?)
|
// FIXME: this doesn't really belong in `associated_item` (maybe `variant_field` is better?)
|
||||||
|
@ -631,20 +668,27 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
|
||||||
// field syntax) and are handled by the compiler's resolver.
|
// field syntax) and are handled by the compiler's resolver.
|
||||||
let def = match tcx.type_of(did).subst_identity().kind() {
|
let def = match tcx.type_of(did).subst_identity().kind() {
|
||||||
ty::Adt(def, _) if !def.is_enum() => def,
|
ty::Adt(def, _) if !def.is_enum() => def,
|
||||||
_ => return None,
|
_ => return Vec::new(),
|
||||||
};
|
};
|
||||||
let field =
|
def.non_enum_variant()
|
||||||
def.non_enum_variant().fields.iter().find(|item| item.name == item_name)?;
|
.fields
|
||||||
Some((root_res, field.did))
|
.iter()
|
||||||
|
.filter(|field| field.name == item_name)
|
||||||
|
.map(|field| (root_res, field.did))
|
||||||
|
.collect::<Vec<_>>()
|
||||||
}
|
}
|
||||||
Res::Def(DefKind::Trait, did) => tcx
|
Res::Def(DefKind::Trait, did) => filter_assoc_items_by_name_and_namespace(
|
||||||
.associated_items(did)
|
tcx,
|
||||||
.find_by_name_and_namespace(tcx, Ident::with_dummy_span(item_name), ns, did)
|
did,
|
||||||
|
Ident::with_dummy_span(item_name),
|
||||||
|
ns,
|
||||||
|
)
|
||||||
.map(|item| {
|
.map(|item| {
|
||||||
let res = Res::Def(item.kind.as_def_kind(), item.def_id);
|
let res = Res::Def(item.kind.as_def_kind(), item.def_id);
|
||||||
(res, item.def_id)
|
(res, item.def_id)
|
||||||
}),
|
})
|
||||||
_ => None,
|
.collect::<Vec<_>>(),
|
||||||
|
_ => Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -664,7 +708,7 @@ fn resolve_associated_trait_item<'a>(
|
||||||
item_name: Symbol,
|
item_name: Symbol,
|
||||||
ns: Namespace,
|
ns: Namespace,
|
||||||
cx: &mut DocContext<'a>,
|
cx: &mut DocContext<'a>,
|
||||||
) -> Option<ty::AssocItem> {
|
) -> Vec<ty::AssocItem> {
|
||||||
// FIXME: this should also consider blanket impls (`impl<T> X for T`). Unfortunately
|
// FIXME: this should also consider blanket impls (`impl<T> X for T`). Unfortunately
|
||||||
// `get_auto_trait_and_blanket_impls` is broken because the caching behavior is wrong. In the
|
// `get_auto_trait_and_blanket_impls` is broken because the caching behavior is wrong. In the
|
||||||
// meantime, just don't look for these blanket impls.
|
// meantime, just don't look for these blanket impls.
|
||||||
|
@ -672,19 +716,26 @@ fn resolve_associated_trait_item<'a>(
|
||||||
// Next consider explicit impls: `impl MyTrait for MyType`
|
// Next consider explicit impls: `impl MyTrait for MyType`
|
||||||
// Give precedence to inherent impls.
|
// Give precedence to inherent impls.
|
||||||
let traits = trait_impls_for(cx, ty, module);
|
let traits = trait_impls_for(cx, ty, module);
|
||||||
|
let tcx = cx.tcx;
|
||||||
debug!("considering traits {:?}", traits);
|
debug!("considering traits {:?}", traits);
|
||||||
let mut candidates = traits.iter().filter_map(|&(impl_, trait_)| {
|
let candidates = traits
|
||||||
cx.tcx
|
.iter()
|
||||||
.associated_items(trait_)
|
.flat_map(|&(impl_, trait_)| {
|
||||||
.find_by_name_and_namespace(cx.tcx, Ident::with_dummy_span(item_name), ns, trait_)
|
filter_assoc_items_by_name_and_namespace(
|
||||||
.map(|trait_assoc| {
|
cx.tcx,
|
||||||
trait_assoc_to_impl_assoc_item(cx.tcx, impl_, trait_assoc.def_id)
|
trait_,
|
||||||
|
Ident::with_dummy_span(item_name),
|
||||||
|
ns,
|
||||||
|
)
|
||||||
|
.map(move |trait_assoc| {
|
||||||
|
trait_assoc_to_impl_assoc_item(tcx, impl_, trait_assoc.def_id)
|
||||||
.unwrap_or(*trait_assoc)
|
.unwrap_or(*trait_assoc)
|
||||||
})
|
})
|
||||||
});
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
// FIXME(#74563): warn about ambiguity
|
// FIXME(#74563): warn about ambiguity
|
||||||
debug!("the candidates were {:?}", candidates.clone().collect::<Vec<_>>());
|
debug!("the candidates were {:?}", candidates);
|
||||||
candidates.next()
|
candidates
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Find the associated item in the impl `impl_id` that corresponds to the
|
/// Find the associated item in the impl `impl_id` that corresponds to the
|
||||||
|
@ -758,15 +809,15 @@ fn trait_impls_for<'a>(
|
||||||
/// Check for resolve collisions between a trait and its derive.
|
/// Check for resolve collisions between a trait and its derive.
|
||||||
///
|
///
|
||||||
/// These are common and we should just resolve to the trait in that case.
|
/// These are common and we should just resolve to the trait in that case.
|
||||||
fn is_derive_trait_collision<T>(ns: &PerNS<Result<(Res, T), ResolutionFailure<'_>>>) -> bool {
|
fn is_derive_trait_collision<T>(ns: &PerNS<Result<Vec<(Res, T)>, ResolutionFailure<'_>>>) -> bool {
|
||||||
matches!(
|
if let (&Ok(ref type_ns), &Ok(ref macro_ns)) = (&ns.type_ns, &ns.macro_ns) {
|
||||||
*ns,
|
type_ns.iter().any(|(res, _)| matches!(res, Res::Def(DefKind::Trait, _)))
|
||||||
PerNS {
|
&& macro_ns
|
||||||
type_ns: Ok((Res::Def(DefKind::Trait, _), _)),
|
.iter()
|
||||||
macro_ns: Ok((Res::Def(DefKind::Macro(MacroKind::Derive), _), _)),
|
.any(|(res, _)| matches!(res, Res::Def(DefKind::Macro(MacroKind::Derive), _)))
|
||||||
..
|
} else {
|
||||||
|
false
|
||||||
}
|
}
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> DocVisitor for LinkCollector<'a, 'tcx> {
|
impl<'a, 'tcx> DocVisitor for LinkCollector<'a, 'tcx> {
|
||||||
|
@ -987,15 +1038,15 @@ impl LinkCollector<'_, '_> {
|
||||||
res = prim;
|
res = prim;
|
||||||
} else {
|
} else {
|
||||||
// `[char]` when a `char` module is in scope
|
// `[char]` when a `char` module is in scope
|
||||||
let candidates = vec![res, prim];
|
let candidates = &[(res, res.def_id(self.cx.tcx)), (prim, None)];
|
||||||
ambiguity_error(self.cx, diag_info, path_str, candidates);
|
ambiguity_error(self.cx, &diag_info, path_str, candidates);
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
match res {
|
match res {
|
||||||
Res::Primitive(prim) => {
|
Res::Primitive(_) => {
|
||||||
if let Some(UrlFragment::Item(id)) = fragment {
|
if let Some(UrlFragment::Item(id)) = fragment {
|
||||||
// We're actually resolving an associated item of a primitive, so we need to
|
// We're actually resolving an associated item of a primitive, so we need to
|
||||||
// verify the disambiguator (if any) matches the type of the associated item.
|
// verify the disambiguator (if any) matches the type of the associated item.
|
||||||
|
@ -1015,15 +1066,6 @@ impl LinkCollector<'_, '_> {
|
||||||
item,
|
item,
|
||||||
&diag_info,
|
&diag_info,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
// FIXME: it would be nice to check that the feature gate was enabled in the original crate, not just ignore it altogether.
|
|
||||||
// However I'm not sure how to check that across crates.
|
|
||||||
if prim == PrimitiveType::RawPointer
|
|
||||||
&& item.item_id.is_local()
|
|
||||||
&& !self.cx.tcx.features().intra_doc_pointers
|
|
||||||
{
|
|
||||||
self.report_rawptr_assoc_feature_gate(dox, ori_link, item);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
match disambiguator {
|
match disambiguator {
|
||||||
Some(Disambiguator::Primitive | Disambiguator::Namespace(_)) | None => {}
|
Some(Disambiguator::Primitive | Disambiguator::Namespace(_)) | None => {}
|
||||||
|
@ -1102,7 +1144,7 @@ impl LinkCollector<'_, '_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// item can be non-local e.g. when using #[doc(primitive = "pointer")]
|
// item can be non-local e.g. when using `#[rustc_doc_primitive = "pointer"]`
|
||||||
if let Some((src_id, dst_id)) = id.as_local().and_then(|dst_id| {
|
if let Some((src_id, dst_id)) = id.as_local().and_then(|dst_id| {
|
||||||
item.item_id.expect_def_id().as_local().map(|src_id| (src_id, dst_id))
|
item.item_id.expect_def_id().as_local().map(|src_id| (src_id, dst_id))
|
||||||
}) {
|
}) {
|
||||||
|
@ -1144,9 +1186,8 @@ impl LinkCollector<'_, '_> {
|
||||||
report_diagnostic(self.cx.tcx, BROKEN_INTRA_DOC_LINKS, &msg, diag_info, callback);
|
report_diagnostic(self.cx.tcx, BROKEN_INTRA_DOC_LINKS, &msg, diag_info, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn report_rawptr_assoc_feature_gate(&self, dox: &str, ori_link: &MarkdownLink, item: &Item) {
|
fn report_rawptr_assoc_feature_gate(&self, dox: &str, ori_link: &Range<usize>, item: &Item) {
|
||||||
let span =
|
let span = super::source_span_for_markdown_range(self.cx.tcx, dox, ori_link, &item.attrs)
|
||||||
super::source_span_for_markdown_range(self.cx.tcx, dox, &ori_link.range, &item.attrs)
|
|
||||||
.unwrap_or_else(|| item.attr_span(self.cx.tcx));
|
.unwrap_or_else(|| item.attr_span(self.cx.tcx));
|
||||||
rustc_session::parse::feature_err(
|
rustc_session::parse::feature_err(
|
||||||
&self.cx.tcx.sess.parse_sess,
|
&self.cx.tcx.sess.parse_sess,
|
||||||
|
@ -1172,7 +1213,31 @@ impl LinkCollector<'_, '_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let res = self.resolve_with_disambiguator(&key, diag.clone()).and_then(|(res, def_id)| {
|
let mut candidates = self.resolve_with_disambiguator(&key, diag.clone());
|
||||||
|
|
||||||
|
// FIXME: it would be nice to check that the feature gate was enabled in the original crate, not just ignore it altogether.
|
||||||
|
// However I'm not sure how to check that across crates.
|
||||||
|
if let Some(candidate) = candidates.get(0) &&
|
||||||
|
candidate.0 == Res::Primitive(PrimitiveType::RawPointer) &&
|
||||||
|
key.path_str.contains("::") // We only want to check this if this is an associated item.
|
||||||
|
{
|
||||||
|
if key.item_id.is_local() && !self.cx.tcx.features().intra_doc_pointers {
|
||||||
|
self.report_rawptr_assoc_feature_gate(diag.dox, &diag.link_range, diag.item);
|
||||||
|
return None;
|
||||||
|
} else {
|
||||||
|
candidates = vec![candidates[0]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If there are multiple items with the same "kind" (for example, both "associated types")
|
||||||
|
// and after removing duplicated kinds, only one remains, the `ambiguity_error` function
|
||||||
|
// won't emit an error. So at this point, we can just take the first candidate as it was
|
||||||
|
// the first retrieved and use it to generate the link.
|
||||||
|
if candidates.len() > 1 && !ambiguity_error(self.cx, &diag, &key.path_str, &candidates) {
|
||||||
|
candidates = vec![candidates[0]];
|
||||||
|
}
|
||||||
|
|
||||||
|
if let &[(res, def_id)] = candidates.as_slice() {
|
||||||
let fragment = match (&key.extra_fragment, def_id) {
|
let fragment = match (&key.extra_fragment, def_id) {
|
||||||
(Some(_), Some(def_id)) => {
|
(Some(_), Some(def_id)) => {
|
||||||
report_anchor_conflict(self.cx, diag, def_id);
|
report_anchor_conflict(self.cx, diag, def_id);
|
||||||
|
@ -1182,13 +1247,15 @@ impl LinkCollector<'_, '_> {
|
||||||
(None, Some(def_id)) => Some(UrlFragment::Item(def_id)),
|
(None, Some(def_id)) => Some(UrlFragment::Item(def_id)),
|
||||||
(None, None) => None,
|
(None, None) => None,
|
||||||
};
|
};
|
||||||
Some((res, fragment))
|
let r = Some((res, fragment));
|
||||||
});
|
self.visited_links.insert(key, r.clone());
|
||||||
|
return r;
|
||||||
if res.is_some() || cache_errors {
|
|
||||||
self.visited_links.insert(key, res.clone());
|
|
||||||
}
|
}
|
||||||
res
|
|
||||||
|
if cache_errors {
|
||||||
|
self.visited_links.insert(key, None);
|
||||||
|
}
|
||||||
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
/// After parsing the disambiguator, resolve the main part of the link.
|
/// After parsing the disambiguator, resolve the main part of the link.
|
||||||
|
@ -1197,7 +1264,7 @@ impl LinkCollector<'_, '_> {
|
||||||
&mut self,
|
&mut self,
|
||||||
key: &ResolutionInfo,
|
key: &ResolutionInfo,
|
||||||
diag: DiagnosticInfo<'_>,
|
diag: DiagnosticInfo<'_>,
|
||||||
) -> Option<(Res, Option<DefId>)> {
|
) -> Vec<(Res, Option<DefId>)> {
|
||||||
let disambiguator = key.dis;
|
let disambiguator = key.dis;
|
||||||
let path_str = &key.path_str;
|
let path_str = &key.path_str;
|
||||||
let item_id = key.item_id;
|
let item_id = key.item_id;
|
||||||
|
@ -1206,7 +1273,7 @@ impl LinkCollector<'_, '_> {
|
||||||
match disambiguator.map(Disambiguator::ns) {
|
match disambiguator.map(Disambiguator::ns) {
|
||||||
Some(expected_ns) => {
|
Some(expected_ns) => {
|
||||||
match self.resolve(path_str, expected_ns, item_id, module_id) {
|
match self.resolve(path_str, expected_ns, item_id, module_id) {
|
||||||
Ok(res) => Some(res),
|
Ok(candidates) => candidates,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
// We only looked in one namespace. Try to give a better error if possible.
|
// We only looked in one namespace. Try to give a better error if possible.
|
||||||
// FIXME: really it should be `resolution_failure` that does this, not `resolve_with_disambiguator`.
|
// FIXME: really it should be `resolution_failure` that does this, not `resolve_with_disambiguator`.
|
||||||
|
@ -1215,10 +1282,11 @@ impl LinkCollector<'_, '_> {
|
||||||
for other_ns in [TypeNS, ValueNS, MacroNS] {
|
for other_ns in [TypeNS, ValueNS, MacroNS] {
|
||||||
if other_ns != expected_ns {
|
if other_ns != expected_ns {
|
||||||
if let Ok(res) =
|
if let Ok(res) =
|
||||||
self.resolve(path_str, other_ns, item_id, module_id)
|
self.resolve(path_str, other_ns, item_id, module_id) &&
|
||||||
|
!res.is_empty()
|
||||||
{
|
{
|
||||||
err = ResolutionFailure::WrongNamespace {
|
err = ResolutionFailure::WrongNamespace {
|
||||||
res: full_res(self.cx.tcx, res),
|
res: full_res(self.cx.tcx, res[0]),
|
||||||
expected_ns,
|
expected_ns,
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
|
@ -1239,18 +1307,26 @@ impl LinkCollector<'_, '_> {
|
||||||
let candidates = PerNS {
|
let candidates = PerNS {
|
||||||
macro_ns: candidate(MacroNS),
|
macro_ns: candidate(MacroNS),
|
||||||
type_ns: candidate(TypeNS),
|
type_ns: candidate(TypeNS),
|
||||||
value_ns: candidate(ValueNS).and_then(|(res, def_id)| {
|
value_ns: candidate(ValueNS).and_then(|v_res| {
|
||||||
|
for (res, _) in v_res.iter() {
|
||||||
match res {
|
match res {
|
||||||
// Constructors are picked up in the type namespace.
|
// Constructors are picked up in the type namespace.
|
||||||
Res::Def(DefKind::Ctor(..), _) => {
|
Res::Def(DefKind::Ctor(..), _) => {
|
||||||
Err(ResolutionFailure::WrongNamespace { res, expected_ns: TypeNS })
|
return Err(ResolutionFailure::WrongNamespace {
|
||||||
|
res: *res,
|
||||||
|
expected_ns: TypeNS,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
_ => Ok((res, def_id)),
|
_ => {}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
Ok(v_res)
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
|
||||||
let len = candidates.iter().filter(|res| res.is_ok()).count();
|
let len = candidates
|
||||||
|
.iter()
|
||||||
|
.fold(0, |acc, res| if let Ok(res) = res { acc + res.len() } else { acc });
|
||||||
|
|
||||||
if len == 0 {
|
if len == 0 {
|
||||||
return resolution_failure(
|
return resolution_failure(
|
||||||
|
@ -1260,22 +1336,21 @@ impl LinkCollector<'_, '_> {
|
||||||
disambiguator,
|
disambiguator,
|
||||||
candidates.into_iter().filter_map(|res| res.err()).collect(),
|
candidates.into_iter().filter_map(|res| res.err()).collect(),
|
||||||
);
|
);
|
||||||
}
|
} else if len == 1 {
|
||||||
|
candidates.into_iter().filter_map(|res| res.ok()).flatten().collect::<Vec<_>>()
|
||||||
if len == 1 {
|
} else {
|
||||||
Some(candidates.into_iter().find_map(|res| res.ok()).unwrap())
|
let has_derive_trait_collision = is_derive_trait_collision(&candidates);
|
||||||
} else if len == 2 && is_derive_trait_collision(&candidates) {
|
if len == 2 && has_derive_trait_collision {
|
||||||
Some(candidates.type_ns.unwrap())
|
candidates.type_ns.unwrap()
|
||||||
} else {
|
} else {
|
||||||
let ignore_macro = is_derive_trait_collision(&candidates);
|
|
||||||
// If we're reporting an ambiguity, don't mention the namespaces that failed
|
// If we're reporting an ambiguity, don't mention the namespaces that failed
|
||||||
let mut candidates =
|
let mut candidates = candidates.map(|candidate| candidate.ok());
|
||||||
candidates.map(|candidate| candidate.ok().map(|(res, _)| res));
|
// If there a collision between a trait and a derive, we ignore the derive.
|
||||||
if ignore_macro {
|
if has_derive_trait_collision {
|
||||||
candidates.macro_ns = None;
|
candidates.macro_ns = None;
|
||||||
}
|
}
|
||||||
ambiguity_error(self.cx, diag, path_str, candidates.present_items().collect());
|
candidates.into_iter().filter_map(|res| res).flatten().collect::<Vec<_>>()
|
||||||
None
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1563,7 +1638,7 @@ fn resolution_failure(
|
||||||
path_str: &str,
|
path_str: &str,
|
||||||
disambiguator: Option<Disambiguator>,
|
disambiguator: Option<Disambiguator>,
|
||||||
kinds: SmallVec<[ResolutionFailure<'_>; 3]>,
|
kinds: SmallVec<[ResolutionFailure<'_>; 3]>,
|
||||||
) -> Option<(Res, Option<DefId>)> {
|
) -> Vec<(Res, Option<DefId>)> {
|
||||||
let tcx = collector.cx.tcx;
|
let tcx = collector.cx.tcx;
|
||||||
let mut recovered_res = None;
|
let mut recovered_res = None;
|
||||||
report_diagnostic(
|
report_diagnostic(
|
||||||
|
@ -1622,13 +1697,15 @@ fn resolution_failure(
|
||||||
};
|
};
|
||||||
name = start;
|
name = start;
|
||||||
for ns in [TypeNS, ValueNS, MacroNS] {
|
for ns in [TypeNS, ValueNS, MacroNS] {
|
||||||
if let Ok(res) = collector.resolve(start, ns, item_id, module_id) {
|
if let Ok(v_res) = collector.resolve(start, ns, item_id, module_id) {
|
||||||
debug!("found partial_res={:?}", res);
|
debug!("found partial_res={:?}", v_res);
|
||||||
*partial_res = Some(full_res(collector.cx.tcx, res));
|
if !v_res.is_empty() {
|
||||||
|
*partial_res = Some(full_res(collector.cx.tcx, v_res[0]));
|
||||||
*unresolved = end.into();
|
*unresolved = end.into();
|
||||||
break 'outer;
|
break 'outer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
*unresolved = end.into();
|
*unresolved = end.into();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1774,7 +1851,10 @@ fn resolution_failure(
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
recovered_res
|
match recovered_res {
|
||||||
|
Some(r) => vec![r],
|
||||||
|
None => Vec::new(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn report_multiple_anchors(cx: &DocContext<'_>, diag_info: DiagnosticInfo<'_>) {
|
fn report_multiple_anchors(cx: &DocContext<'_>, diag_info: DiagnosticInfo<'_>) {
|
||||||
|
@ -1859,28 +1939,47 @@ fn report_malformed_generics(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Report an ambiguity error, where there were multiple possible resolutions.
|
/// Report an ambiguity error, where there were multiple possible resolutions.
|
||||||
|
///
|
||||||
|
/// If all `candidates` have the same kind, it's not possible to disambiguate so in this case,
|
||||||
|
/// the function won't emit an error and will return `false`. Otherwise, it'll emit the error and
|
||||||
|
/// return `true`.
|
||||||
fn ambiguity_error(
|
fn ambiguity_error(
|
||||||
cx: &DocContext<'_>,
|
cx: &DocContext<'_>,
|
||||||
diag_info: DiagnosticInfo<'_>,
|
diag_info: &DiagnosticInfo<'_>,
|
||||||
path_str: &str,
|
path_str: &str,
|
||||||
candidates: Vec<Res>,
|
candidates: &[(Res, Option<DefId>)],
|
||||||
) {
|
) -> bool {
|
||||||
let mut msg = format!("`{}` is ", path_str);
|
let mut descrs = FxHashSet::default();
|
||||||
|
let kinds = candidates
|
||||||
|
.iter()
|
||||||
|
.map(
|
||||||
|
|(res, def_id)| {
|
||||||
|
if let Some(def_id) = def_id { Res::from_def_id(cx.tcx, *def_id) } else { *res }
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.filter(|res| descrs.insert(res.descr()))
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
if descrs.len() == 1 {
|
||||||
|
// There is no way for users to disambiguate at this point, so better return the first
|
||||||
|
// candidate and not show a warning.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
match candidates.as_slice() {
|
let mut msg = format!("`{}` is ", path_str);
|
||||||
[first_def, second_def] => {
|
match kinds.as_slice() {
|
||||||
|
[res1, res2] => {
|
||||||
msg += &format!(
|
msg += &format!(
|
||||||
"both {} {} and {} {}",
|
"both {} {} and {} {}",
|
||||||
first_def.article(),
|
res1.article(),
|
||||||
first_def.descr(),
|
res1.descr(),
|
||||||
second_def.article(),
|
res2.article(),
|
||||||
second_def.descr(),
|
res2.descr()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
let mut candidates = candidates.iter().peekable();
|
let mut kinds = kinds.iter().peekable();
|
||||||
while let Some(res) = candidates.next() {
|
while let Some(res) = kinds.next() {
|
||||||
if candidates.peek().is_some() {
|
if kinds.peek().is_some() {
|
||||||
msg += &format!("{} {}, ", res.article(), res.descr());
|
msg += &format!("{} {}, ", res.article(), res.descr());
|
||||||
} else {
|
} else {
|
||||||
msg += &format!("and {} {}", res.article(), res.descr());
|
msg += &format!("and {} {}", res.article(), res.descr());
|
||||||
|
@ -1889,17 +1988,18 @@ fn ambiguity_error(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
report_diagnostic(cx.tcx, BROKEN_INTRA_DOC_LINKS, &msg, &diag_info, |diag, sp| {
|
report_diagnostic(cx.tcx, BROKEN_INTRA_DOC_LINKS, &msg, diag_info, |diag, sp| {
|
||||||
if let Some(sp) = sp {
|
if let Some(sp) = sp {
|
||||||
diag.span_label(sp, "ambiguous link");
|
diag.span_label(sp, "ambiguous link");
|
||||||
} else {
|
} else {
|
||||||
diag.note("ambiguous link");
|
diag.note("ambiguous link");
|
||||||
}
|
}
|
||||||
|
|
||||||
for res in candidates {
|
for res in kinds {
|
||||||
suggest_disambiguator(res, diag, path_str, diag_info.ori_link, sp);
|
suggest_disambiguator(res, diag, path_str, diag_info.ori_link, sp);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
/// In case of an ambiguity or mismatched disambiguator, suggest the correct
|
/// In case of an ambiguity or mismatched disambiguator, suggest the correct
|
||||||
|
|
21
tests/rustdoc-gui/go-to-collapsed-elem.goml
Normal file
21
tests/rustdoc-gui/go-to-collapsed-elem.goml
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
// This test ensures that when clicking on a link which leads to an item inside a collapsed element,
|
||||||
|
// the collapsed element will be expanded.
|
||||||
|
goto: "file://" + |DOC_PATH| + "/test_docs/struct.Foo.html"
|
||||||
|
// We check that the implementors block is expanded.
|
||||||
|
assert-property: ("#implementations-list .implementors-toggle", {"open": "true"})
|
||||||
|
// We now collapse the implementors block.
|
||||||
|
property: ("#implementations-list .implementors-toggle", {"open": "false"})
|
||||||
|
// And now we click on the link to the method to ensure it'll expand the implementors block.
|
||||||
|
click: "//*[@class='sidebar']//a[@href='#method.must_use']"
|
||||||
|
assert-property: ("#implementations-list .implementors-toggle", {"open": "true"})
|
||||||
|
|
||||||
|
// Now we do the same through search result.
|
||||||
|
// First we reload the page without the anchor in the URL.
|
||||||
|
goto: "file://" + |DOC_PATH| + "/test_docs/struct.Foo.html"
|
||||||
|
// Then we collapse the section again...
|
||||||
|
property: ("#implementations-list .implementors-toggle", {"open": "false"})
|
||||||
|
// Then we run the search.
|
||||||
|
write: (".search-input", "foo::must_use")
|
||||||
|
wait-for: "//*[@id='search']//a[@href='../test_docs/struct.Foo.html#method.must_use']"
|
||||||
|
click: "//*[@id='search']//a[@href='../test_docs/struct.Foo.html#method.must_use']"
|
||||||
|
assert-property: ("#implementations-list .implementors-toggle", {"open": "true"})
|
|
@ -1,5 +1,5 @@
|
||||||
#![feature(no_core)]
|
#![feature(no_core)]
|
||||||
#![feature(rustdoc_internals)]
|
#![feature(rustc_attrs)]
|
||||||
#![no_core]
|
#![no_core]
|
||||||
|
|
||||||
// @set Local = "$.index[*][?(@.name=='Local')].id"
|
// @set Local = "$.index[*][?(@.name=='Local')].id"
|
||||||
|
@ -16,6 +16,6 @@ impl Local for bool {}
|
||||||
|
|
||||||
// FIXME(#101695): Test bool's `impls` include "Local for bool"
|
// FIXME(#101695): Test bool's `impls` include "Local for bool"
|
||||||
// @has "$.index[*][?(@.name=='bool')]"
|
// @has "$.index[*][?(@.name=='bool')]"
|
||||||
#[doc(primitive = "bool")]
|
#[rustc_doc_primitive = "bool"]
|
||||||
/// Boolean docs
|
/// Boolean docs
|
||||||
mod prim_bool {}
|
mod prim_bool {}
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
//! Link to [i32][prim@i32] [i64][prim@i64]
|
//! Link to [i32][prim@i32] [i64][prim@i64]
|
||||||
|
|
||||||
#[doc(primitive = "i32")]
|
#[rustc_doc_primitive = "i32"]
|
||||||
mod prim_i32 {}
|
mod prim_i32 {}
|
||||||
|
|
||||||
// @set local_i32 = "$.index[*][?(@.name=='i32')].id"
|
// @set local_i32 = "$.index[*][?(@.name=='i32')].id"
|
||||||
|
|
|
@ -25,7 +25,7 @@ pub trait Trait {}
|
||||||
impl Trait for i32 {}
|
impl Trait for i32 {}
|
||||||
|
|
||||||
/// i32
|
/// i32
|
||||||
#[doc(primitive = "i32")]
|
#[rustc_doc_primitive = "i32"]
|
||||||
mod prim_i32 {}
|
mod prim_i32 {}
|
||||||
|
|
||||||
// @set i32 = "$.index[*][?(@.docs=='i32')].id"
|
// @set i32 = "$.index[*][?(@.docs=='i32')].id"
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
// Regression test for <https://github.com/rust-lang/rust/issues/98006>.
|
// Regression test for <https://github.com/rust-lang/rust/issues/98006>.
|
||||||
|
|
||||||
#![feature(rustdoc_internals)]
|
#![feature(rustc_attrs)]
|
||||||
#![feature(no_core)]
|
#![feature(no_core)]
|
||||||
|
|
||||||
#![no_core]
|
#![no_core]
|
||||||
|
@ -10,7 +10,7 @@
|
||||||
// @has "$.index[*][?(@.name=='usize')]"
|
// @has "$.index[*][?(@.name=='usize')]"
|
||||||
// @has "$.index[*][?(@.name=='prim')]"
|
// @has "$.index[*][?(@.name=='prim')]"
|
||||||
|
|
||||||
#[doc(primitive = "usize")]
|
#[rustc_doc_primitive = "usize"]
|
||||||
/// This is the built-in type `usize`.
|
/// This is the built-in type `usize`.
|
||||||
mod prim {
|
mod prim {
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
// edition:2018
|
// edition:2018
|
||||||
|
|
||||||
#![feature(rustdoc_internals)]
|
#![feature(rustc_attrs)]
|
||||||
|
|
||||||
#[doc(primitive = "usize")]
|
#[rustc_doc_primitive = "usize"]
|
||||||
mod usize {}
|
mod usize {}
|
||||||
|
|
||||||
// @set local_crate_id = "$.index[*][?(@.name=='use_primitive')].crate_id"
|
// @set local_crate_id = "$.index[*][?(@.name=='use_primitive')].crate_id"
|
||||||
|
|
|
@ -2,12 +2,13 @@
|
||||||
// check-pass
|
// check-pass
|
||||||
|
|
||||||
#![feature(rustdoc_internals)]
|
#![feature(rustdoc_internals)]
|
||||||
|
#![feature(rustc_attrs)]
|
||||||
|
|
||||||
//! the features only used in std also have entries in the table, so make sure those get pulled out
|
//! the features only used in std also have entries in the table, so make sure those get pulled out
|
||||||
//! properly as well
|
//! properly as well
|
||||||
|
|
||||||
/// woo, check it out, we can write our own primitive docs lol
|
/// woo, check it out, we can write our own primitive docs lol
|
||||||
#[doc(primitive="unit")]
|
#[rustc_doc_primitive = "unit"]
|
||||||
mod prim_unit {}
|
mod prim_unit {}
|
||||||
|
|
||||||
/// keywords? sure, pile them on
|
/// keywords? sure, pile them on
|
||||||
|
|
|
@ -35,6 +35,6 @@ pub mod foo {
|
||||||
/// Ambiguous non-implied shortcut link [`foo::bar`]. //~ERROR `foo::bar`
|
/// Ambiguous non-implied shortcut link [`foo::bar`]. //~ERROR `foo::bar`
|
||||||
pub struct Docs {}
|
pub struct Docs {}
|
||||||
|
|
||||||
/// [true] //~ ERROR `true` is both a module and a builtin type
|
/// [true] //~ ERROR `true` is both a module and a primitive type
|
||||||
/// [primitive@true]
|
/// [primitive@true]
|
||||||
pub mod r#true {}
|
pub mod r#true {}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
error: `true` is both a module and a builtin type
|
error: `true` is both a module and a primitive type
|
||||||
--> $DIR/ambiguity.rs:38:6
|
--> $DIR/ambiguity.rs:38:6
|
||||||
|
|
|
|
||||||
LL | /// [true]
|
LL | /// [true]
|
||||||
|
@ -13,89 +13,89 @@ help: to link to the module, prefix with `mod@`
|
||||||
|
|
|
|
||||||
LL | /// [mod@true]
|
LL | /// [mod@true]
|
||||||
| ++++
|
| ++++
|
||||||
help: to link to the builtin type, prefix with `prim@`
|
help: to link to the primitive type, prefix with `prim@`
|
||||||
|
|
|
|
||||||
LL | /// [prim@true]
|
LL | /// [prim@true]
|
||||||
| +++++
|
| +++++
|
||||||
|
|
||||||
error: `ambiguous` is both a struct and a function
|
error: `ambiguous` is both a function and a struct
|
||||||
--> $DIR/ambiguity.rs:27:7
|
--> $DIR/ambiguity.rs:27:7
|
||||||
|
|
|
|
||||||
LL | /// [`ambiguous`] is ambiguous.
|
LL | /// [`ambiguous`] is ambiguous.
|
||||||
| ^^^^^^^^^ ambiguous link
|
| ^^^^^^^^^ ambiguous link
|
||||||
|
|
|
|
||||||
help: to link to the struct, prefix with `struct@`
|
|
||||||
|
|
|
||||||
LL | /// [`struct@ambiguous`] is ambiguous.
|
|
||||||
| +++++++
|
|
||||||
help: to link to the function, add parentheses
|
help: to link to the function, add parentheses
|
||||||
|
|
|
|
||||||
LL | /// [`ambiguous()`] is ambiguous.
|
LL | /// [`ambiguous()`] is ambiguous.
|
||||||
| ++
|
| ++
|
||||||
|
help: to link to the struct, prefix with `struct@`
|
||||||
|
|
|
||||||
|
LL | /// [`struct@ambiguous`] is ambiguous.
|
||||||
|
| +++++++
|
||||||
|
|
||||||
error: `ambiguous` is both a struct and a function
|
error: `ambiguous` is both a function and a struct
|
||||||
--> $DIR/ambiguity.rs:29:6
|
--> $DIR/ambiguity.rs:29:6
|
||||||
|
|
|
|
||||||
LL | /// [ambiguous] is ambiguous.
|
LL | /// [ambiguous] is ambiguous.
|
||||||
| ^^^^^^^^^ ambiguous link
|
| ^^^^^^^^^ ambiguous link
|
||||||
|
|
|
|
||||||
help: to link to the struct, prefix with `struct@`
|
|
||||||
|
|
|
||||||
LL | /// [struct@ambiguous] is ambiguous.
|
|
||||||
| +++++++
|
|
||||||
help: to link to the function, add parentheses
|
help: to link to the function, add parentheses
|
||||||
|
|
|
|
||||||
LL | /// [ambiguous()] is ambiguous.
|
LL | /// [ambiguous()] is ambiguous.
|
||||||
| ++
|
| ++
|
||||||
|
help: to link to the struct, prefix with `struct@`
|
||||||
|
|
|
||||||
|
LL | /// [struct@ambiguous] is ambiguous.
|
||||||
|
| +++++++
|
||||||
|
|
||||||
error: `multi_conflict` is a struct, a function, and a macro
|
error: `multi_conflict` is a function, a struct, and a macro
|
||||||
--> $DIR/ambiguity.rs:31:7
|
--> $DIR/ambiguity.rs:31:7
|
||||||
|
|
|
|
||||||
LL | /// [`multi_conflict`] is a three-way conflict.
|
LL | /// [`multi_conflict`] is a three-way conflict.
|
||||||
| ^^^^^^^^^^^^^^ ambiguous link
|
| ^^^^^^^^^^^^^^ ambiguous link
|
||||||
|
|
|
|
||||||
help: to link to the struct, prefix with `struct@`
|
|
||||||
|
|
|
||||||
LL | /// [`struct@multi_conflict`] is a three-way conflict.
|
|
||||||
| +++++++
|
|
||||||
help: to link to the function, add parentheses
|
help: to link to the function, add parentheses
|
||||||
|
|
|
|
||||||
LL | /// [`multi_conflict()`] is a three-way conflict.
|
LL | /// [`multi_conflict()`] is a three-way conflict.
|
||||||
| ++
|
| ++
|
||||||
|
help: to link to the struct, prefix with `struct@`
|
||||||
|
|
|
||||||
|
LL | /// [`struct@multi_conflict`] is a three-way conflict.
|
||||||
|
| +++++++
|
||||||
help: to link to the macro, add an exclamation mark
|
help: to link to the macro, add an exclamation mark
|
||||||
|
|
|
|
||||||
LL | /// [`multi_conflict!`] is a three-way conflict.
|
LL | /// [`multi_conflict!`] is a three-way conflict.
|
||||||
| +
|
| +
|
||||||
|
|
||||||
error: `type_and_value` is both a module and a constant
|
error: `type_and_value` is both a constant and a module
|
||||||
--> $DIR/ambiguity.rs:33:16
|
--> $DIR/ambiguity.rs:33:16
|
||||||
|
|
|
|
||||||
LL | /// Ambiguous [type_and_value].
|
LL | /// Ambiguous [type_and_value].
|
||||||
| ^^^^^^^^^^^^^^ ambiguous link
|
| ^^^^^^^^^^^^^^ ambiguous link
|
||||||
|
|
|
|
||||||
help: to link to the module, prefix with `mod@`
|
|
||||||
|
|
|
||||||
LL | /// Ambiguous [mod@type_and_value].
|
|
||||||
| ++++
|
|
||||||
help: to link to the constant, prefix with `const@`
|
help: to link to the constant, prefix with `const@`
|
||||||
|
|
|
|
||||||
LL | /// Ambiguous [const@type_and_value].
|
LL | /// Ambiguous [const@type_and_value].
|
||||||
| ++++++
|
| ++++++
|
||||||
|
help: to link to the module, prefix with `mod@`
|
||||||
|
|
|
||||||
|
LL | /// Ambiguous [mod@type_and_value].
|
||||||
|
| ++++
|
||||||
|
|
||||||
error: `foo::bar` is both an enum and a function
|
error: `foo::bar` is both a function and an enum
|
||||||
--> $DIR/ambiguity.rs:35:43
|
--> $DIR/ambiguity.rs:35:43
|
||||||
|
|
|
|
||||||
LL | /// Ambiguous non-implied shortcut link [`foo::bar`].
|
LL | /// Ambiguous non-implied shortcut link [`foo::bar`].
|
||||||
| ^^^^^^^^ ambiguous link
|
| ^^^^^^^^ ambiguous link
|
||||||
|
|
|
|
||||||
help: to link to the enum, prefix with `enum@`
|
|
||||||
|
|
|
||||||
LL | /// Ambiguous non-implied shortcut link [`enum@foo::bar`].
|
|
||||||
| +++++
|
|
||||||
help: to link to the function, add parentheses
|
help: to link to the function, add parentheses
|
||||||
|
|
|
|
||||||
LL | /// Ambiguous non-implied shortcut link [`foo::bar()`].
|
LL | /// Ambiguous non-implied shortcut link [`foo::bar()`].
|
||||||
| ++
|
| ++
|
||||||
|
help: to link to the enum, prefix with `enum@`
|
||||||
|
|
|
||||||
|
LL | /// Ambiguous non-implied shortcut link [`enum@foo::bar`].
|
||||||
|
| +++++
|
||||||
|
|
||||||
error: aborting due to 6 previous errors
|
error: aborting due to 6 previous errors
|
||||||
|
|
||||||
|
|
|
@ -54,11 +54,11 @@
|
||||||
|
|
||||||
/// [u8::not_found]
|
/// [u8::not_found]
|
||||||
//~^ ERROR unresolved link
|
//~^ ERROR unresolved link
|
||||||
//~| NOTE the builtin type `u8` has no associated item named `not_found`
|
//~| NOTE the primitive type `u8` has no associated item named `not_found`
|
||||||
|
|
||||||
/// [std::primitive::u8::not_found]
|
/// [std::primitive::u8::not_found]
|
||||||
//~^ ERROR unresolved link
|
//~^ ERROR unresolved link
|
||||||
//~| NOTE the builtin type `u8` has no associated item named `not_found`
|
//~| NOTE the primitive type `u8` has no associated item named `not_found`
|
||||||
|
|
||||||
/// [type@Vec::into_iter]
|
/// [type@Vec::into_iter]
|
||||||
//~^ ERROR unresolved link
|
//~^ ERROR unresolved link
|
||||||
|
|
|
@ -80,13 +80,13 @@ error: unresolved link to `u8::not_found`
|
||||||
--> $DIR/errors.rs:55:6
|
--> $DIR/errors.rs:55:6
|
||||||
|
|
|
|
||||||
LL | /// [u8::not_found]
|
LL | /// [u8::not_found]
|
||||||
| ^^^^^^^^^^^^^ the builtin type `u8` has no associated item named `not_found`
|
| ^^^^^^^^^^^^^ the primitive type `u8` has no associated item named `not_found`
|
||||||
|
|
||||||
error: unresolved link to `std::primitive::u8::not_found`
|
error: unresolved link to `std::primitive::u8::not_found`
|
||||||
--> $DIR/errors.rs:59:6
|
--> $DIR/errors.rs:59:6
|
||||||
|
|
|
|
||||||
LL | /// [std::primitive::u8::not_found]
|
LL | /// [std::primitive::u8::not_found]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the builtin type `u8` has no associated item named `not_found`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the primitive type `u8` has no associated item named `not_found`
|
||||||
|
|
||||||
error: unresolved link to `Vec::into_iter`
|
error: unresolved link to `Vec::into_iter`
|
||||||
--> $DIR/errors.rs:63:6
|
--> $DIR/errors.rs:63:6
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
// This test ensures that this warning doesn't show up:
|
||||||
|
// warning: `PartialEq` is both a trait and a derive macro
|
||||||
|
// --> tests/rustdoc-ui/intra-doc/issue-108653-associated-items-10.rs:1:7
|
||||||
|
// |
|
||||||
|
// 1 | //! [`PartialEq`]
|
||||||
|
// | ^^^^^^^^^ ambiguous link
|
||||||
|
// |
|
||||||
|
// = note: `#[warn(rustdoc::broken_intra_doc_links)]` on by default
|
||||||
|
// help: to link to the trait, prefix with `trait@`
|
||||||
|
// |
|
||||||
|
// 1 | //! [`trait@PartialEq`]
|
||||||
|
// | ++++++
|
||||||
|
// help: to link to the derive macro, prefix with `derive@`
|
||||||
|
// |
|
||||||
|
// 1 | //! [`derive@PartialEq`]
|
||||||
|
// | +++++++
|
||||||
|
|
||||||
|
// check-pass
|
||||||
|
|
||||||
|
#![deny(rustdoc::broken_intra_doc_links)]
|
||||||
|
|
||||||
|
//! [`PartialEq`]
|
|
@ -0,0 +1,17 @@
|
||||||
|
// This is ensuring that the UI output for associated items is as expected.
|
||||||
|
|
||||||
|
#![deny(rustdoc::broken_intra_doc_links)]
|
||||||
|
|
||||||
|
/// [`Trait::IDENT`]
|
||||||
|
//~^ ERROR both an associated constant and an associated type
|
||||||
|
pub trait Trait {
|
||||||
|
type IDENT;
|
||||||
|
const IDENT: usize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [`Trait2::IDENT`]
|
||||||
|
//~^ ERROR both an associated function and an associated type
|
||||||
|
pub trait Trait2 {
|
||||||
|
type IDENT;
|
||||||
|
fn IDENT() {}
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
error: `Trait::IDENT` is both an associated constant and an associated type
|
||||||
|
--> $DIR/issue-108653-associated-items-2.rs:5:7
|
||||||
|
|
|
||||||
|
LL | /// [`Trait::IDENT`]
|
||||||
|
| ^^^^^^^^^^^^ ambiguous link
|
||||||
|
|
|
||||||
|
note: the lint level is defined here
|
||||||
|
--> $DIR/issue-108653-associated-items-2.rs:3:9
|
||||||
|
|
|
||||||
|
LL | #![deny(rustdoc::broken_intra_doc_links)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
help: to link to the associated constant, prefix with `const@`
|
||||||
|
|
|
||||||
|
LL | /// [`const@Trait::IDENT`]
|
||||||
|
| ++++++
|
||||||
|
help: to link to the associated type, prefix with `type@`
|
||||||
|
|
|
||||||
|
LL | /// [`type@Trait::IDENT`]
|
||||||
|
| +++++
|
||||||
|
|
||||||
|
error: `Trait2::IDENT` is both an associated function and an associated type
|
||||||
|
--> $DIR/issue-108653-associated-items-2.rs:12:7
|
||||||
|
|
|
||||||
|
LL | /// [`Trait2::IDENT`]
|
||||||
|
| ^^^^^^^^^^^^^ ambiguous link
|
||||||
|
|
|
||||||
|
help: to link to the associated function, add parentheses
|
||||||
|
|
|
||||||
|
LL | /// [`Trait2::IDENT()`]
|
||||||
|
| ++
|
||||||
|
help: to link to the associated type, prefix with `type@`
|
||||||
|
|
|
||||||
|
LL | /// [`type@Trait2::IDENT`]
|
||||||
|
| +++++
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
// This is ensuring that the UI output for associated items works when it's being documented
|
||||||
|
// from another item.
|
||||||
|
|
||||||
|
#![deny(rustdoc::broken_intra_doc_links)]
|
||||||
|
#![allow(nonstandard_style)]
|
||||||
|
|
||||||
|
pub trait Trait {
|
||||||
|
type Trait;
|
||||||
|
const Trait: usize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [`Trait`]
|
||||||
|
//~^ ERROR both a constant and a trait
|
||||||
|
/// [`Trait::Trait`]
|
||||||
|
//~^ ERROR both an associated constant and an associated type
|
||||||
|
pub const Trait: usize = 0;
|
|
@ -0,0 +1,37 @@
|
||||||
|
error: `Trait` is both a constant and a trait
|
||||||
|
--> $DIR/issue-108653-associated-items-3.rs:12:7
|
||||||
|
|
|
||||||
|
LL | /// [`Trait`]
|
||||||
|
| ^^^^^ ambiguous link
|
||||||
|
|
|
||||||
|
note: the lint level is defined here
|
||||||
|
--> $DIR/issue-108653-associated-items-3.rs:4:9
|
||||||
|
|
|
||||||
|
LL | #![deny(rustdoc::broken_intra_doc_links)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
help: to link to the constant, prefix with `const@`
|
||||||
|
|
|
||||||
|
LL | /// [`const@Trait`]
|
||||||
|
| ++++++
|
||||||
|
help: to link to the trait, prefix with `trait@`
|
||||||
|
|
|
||||||
|
LL | /// [`trait@Trait`]
|
||||||
|
| ++++++
|
||||||
|
|
||||||
|
error: `Trait::Trait` is both an associated constant and an associated type
|
||||||
|
--> $DIR/issue-108653-associated-items-3.rs:14:7
|
||||||
|
|
|
||||||
|
LL | /// [`Trait::Trait`]
|
||||||
|
| ^^^^^^^^^^^^ ambiguous link
|
||||||
|
|
|
||||||
|
help: to link to the associated constant, prefix with `const@`
|
||||||
|
|
|
||||||
|
LL | /// [`const@Trait::Trait`]
|
||||||
|
| ++++++
|
||||||
|
help: to link to the associated type, prefix with `type@`
|
||||||
|
|
|
||||||
|
LL | /// [`type@Trait::Trait`]
|
||||||
|
| +++++
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
// This is ensuring that the UI output for associated items works when it's being documented
|
||||||
|
// from another item.
|
||||||
|
|
||||||
|
#![deny(rustdoc::broken_intra_doc_links)]
|
||||||
|
#![allow(nonstandard_style)]
|
||||||
|
|
||||||
|
pub trait Trait {
|
||||||
|
type Trait;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [`Struct::Trait`]
|
||||||
|
//~^ ERROR both an associated constant and an associated type
|
||||||
|
pub struct Struct;
|
||||||
|
|
||||||
|
impl Trait for Struct {
|
||||||
|
type Trait = Struct;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Struct {
|
||||||
|
pub const Trait: usize = 0;
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
error: `Struct::Trait` is both an associated constant and an associated type
|
||||||
|
--> $DIR/issue-108653-associated-items-4.rs:11:7
|
||||||
|
|
|
||||||
|
LL | /// [`Struct::Trait`]
|
||||||
|
| ^^^^^^^^^^^^^ ambiguous link
|
||||||
|
|
|
||||||
|
note: the lint level is defined here
|
||||||
|
--> $DIR/issue-108653-associated-items-4.rs:4:9
|
||||||
|
|
|
||||||
|
LL | #![deny(rustdoc::broken_intra_doc_links)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
help: to link to the associated constant, prefix with `const@`
|
||||||
|
|
|
||||||
|
LL | /// [`const@Struct::Trait`]
|
||||||
|
| ++++++
|
||||||
|
help: to link to the associated type, prefix with `type@`
|
||||||
|
|
|
||||||
|
LL | /// [`type@Struct::Trait`]
|
||||||
|
| +++++
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
#![deny(rustdoc::broken_intra_doc_links)]
|
||||||
|
#![allow(nonstandard_style)]
|
||||||
|
|
||||||
|
/// [`u32::MAX`]
|
||||||
|
//~^ ERROR both an associated constant and a trait
|
||||||
|
pub mod u32 {
|
||||||
|
pub trait MAX {}
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
error: `u32::MAX` is both an associated constant and a trait
|
||||||
|
--> $DIR/issue-108653-associated-items-5.rs:4:7
|
||||||
|
|
|
||||||
|
LL | /// [`u32::MAX`]
|
||||||
|
| ^^^^^^^^ ambiguous link
|
||||||
|
|
|
||||||
|
note: the lint level is defined here
|
||||||
|
--> $DIR/issue-108653-associated-items-5.rs:1:9
|
||||||
|
|
|
||||||
|
LL | #![deny(rustdoc::broken_intra_doc_links)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
help: to link to the associated constant, prefix with `const@`
|
||||||
|
|
|
||||||
|
LL | /// [`const@u32::MAX`]
|
||||||
|
| ++++++
|
||||||
|
help: to link to the trait, prefix with `trait@`
|
||||||
|
|
|
||||||
|
LL | /// [`trait@u32::MAX`]
|
||||||
|
| ++++++
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
#![deny(rustdoc::broken_intra_doc_links)]
|
||||||
|
#![allow(nonstandard_style)]
|
||||||
|
|
||||||
|
/// [`u32::MAX`]
|
||||||
|
//~^ ERROR both an associated constant and a primitive type
|
||||||
|
pub mod u32 {
|
||||||
|
pub use std::primitive::u32 as MAX;
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
error: `u32::MAX` is both an associated constant and a primitive type
|
||||||
|
--> $DIR/issue-108653-associated-items-6.rs:4:7
|
||||||
|
|
|
||||||
|
LL | /// [`u32::MAX`]
|
||||||
|
| ^^^^^^^^ ambiguous link
|
||||||
|
|
|
||||||
|
note: the lint level is defined here
|
||||||
|
--> $DIR/issue-108653-associated-items-6.rs:1:9
|
||||||
|
|
|
||||||
|
LL | #![deny(rustdoc::broken_intra_doc_links)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
help: to link to the associated constant, prefix with `const@`
|
||||||
|
|
|
||||||
|
LL | /// [`const@u32::MAX`]
|
||||||
|
| ++++++
|
||||||
|
help: to link to the primitive type, prefix with `prim@`
|
||||||
|
|
|
||||||
|
LL | /// [`prim@u32::MAX`]
|
||||||
|
| +++++
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
#![deny(rustdoc::broken_intra_doc_links)]
|
||||||
|
#![allow(nonstandard_style)]
|
||||||
|
|
||||||
|
pub trait Trait {
|
||||||
|
type MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [`u32::MAX`]
|
||||||
|
//~^ ERROR both an associated constant and an associated type
|
||||||
|
impl Trait for u32 {
|
||||||
|
type MAX = u32;
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
error: `u32::MAX` is both an associated constant and an associated type
|
||||||
|
--> $DIR/issue-108653-associated-items-7.rs:8:7
|
||||||
|
|
|
||||||
|
LL | /// [`u32::MAX`]
|
||||||
|
| ^^^^^^^^ ambiguous link
|
||||||
|
|
|
||||||
|
note: the lint level is defined here
|
||||||
|
--> $DIR/issue-108653-associated-items-7.rs:1:9
|
||||||
|
|
|
||||||
|
LL | #![deny(rustdoc::broken_intra_doc_links)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
help: to link to the associated constant, prefix with `const@`
|
||||||
|
|
|
||||||
|
LL | /// [`const@u32::MAX`]
|
||||||
|
| ++++++
|
||||||
|
help: to link to the associated type, prefix with `type@`
|
||||||
|
|
|
||||||
|
LL | /// [`type@u32::MAX`]
|
||||||
|
| +++++
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
#![deny(rustdoc::broken_intra_doc_links)]
|
||||||
|
#![allow(nonstandard_style)]
|
||||||
|
|
||||||
|
/// [`u32::MAX`]
|
||||||
|
//~^ ERROR both an associated constant and an associated type
|
||||||
|
pub trait T {
|
||||||
|
type MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl T for u32 {
|
||||||
|
type MAX = ();
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
error: `u32::MAX` is both an associated constant and an associated type
|
||||||
|
--> $DIR/issue-108653-associated-items-8.rs:4:7
|
||||||
|
|
|
||||||
|
LL | /// [`u32::MAX`]
|
||||||
|
| ^^^^^^^^ ambiguous link
|
||||||
|
|
|
||||||
|
note: the lint level is defined here
|
||||||
|
--> $DIR/issue-108653-associated-items-8.rs:1:9
|
||||||
|
|
|
||||||
|
LL | #![deny(rustdoc::broken_intra_doc_links)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
help: to link to the associated constant, prefix with `const@`
|
||||||
|
|
|
||||||
|
LL | /// [`const@u32::MAX`]
|
||||||
|
| ++++++
|
||||||
|
help: to link to the associated type, prefix with `type@`
|
||||||
|
|
|
||||||
|
LL | /// [`type@u32::MAX`]
|
||||||
|
| +++++
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
// check-pass
|
||||||
|
|
||||||
|
#![deny(warnings)]
|
||||||
|
|
||||||
|
//! [usize::Item]
|
||||||
|
|
||||||
|
pub trait Foo { type Item; }
|
||||||
|
pub trait Bar { type Item; }
|
||||||
|
|
||||||
|
impl Foo for usize { type Item = u32; }
|
||||||
|
impl Bar for usize { type Item = i32; }
|
35
tests/rustdoc-ui/intra-doc/issue-108653-associated-items.rs
Normal file
35
tests/rustdoc-ui/intra-doc/issue-108653-associated-items.rs
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
// This is ensuring that the UI output for associated items is as expected.
|
||||||
|
|
||||||
|
#![deny(rustdoc::broken_intra_doc_links)]
|
||||||
|
|
||||||
|
pub enum Enum {
|
||||||
|
IDENT,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [`Self::IDENT`]
|
||||||
|
//~^ ERROR both an associated function and an associated type
|
||||||
|
pub trait Trait {
|
||||||
|
type IDENT;
|
||||||
|
fn IDENT();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [`Self::IDENT`]
|
||||||
|
//~^ ERROR both an associated function and a variant
|
||||||
|
impl Trait for Enum {
|
||||||
|
type IDENT = usize;
|
||||||
|
fn IDENT() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [`Self::IDENT2`]
|
||||||
|
//~^ ERROR both an associated constant and an associated type
|
||||||
|
pub trait Trait2 {
|
||||||
|
type IDENT2;
|
||||||
|
const IDENT2: usize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [`Self::IDENT2`]
|
||||||
|
//~^ ERROR both an associated constant and an associated type
|
||||||
|
impl Trait2 for Enum {
|
||||||
|
type IDENT2 = usize;
|
||||||
|
const IDENT2: usize = 0;
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
error: `Self::IDENT` is both an associated function and an associated type
|
||||||
|
--> $DIR/issue-108653-associated-items.rs:9:7
|
||||||
|
|
|
||||||
|
LL | /// [`Self::IDENT`]
|
||||||
|
| ^^^^^^^^^^^ ambiguous link
|
||||||
|
|
|
||||||
|
note: the lint level is defined here
|
||||||
|
--> $DIR/issue-108653-associated-items.rs:3:9
|
||||||
|
|
|
||||||
|
LL | #![deny(rustdoc::broken_intra_doc_links)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
help: to link to the associated function, add parentheses
|
||||||
|
|
|
||||||
|
LL | /// [`Self::IDENT()`]
|
||||||
|
| ++
|
||||||
|
help: to link to the associated type, prefix with `type@`
|
||||||
|
|
|
||||||
|
LL | /// [`type@Self::IDENT`]
|
||||||
|
| +++++
|
||||||
|
|
||||||
|
error: `Self::IDENT2` is both an associated constant and an associated type
|
||||||
|
--> $DIR/issue-108653-associated-items.rs:23:7
|
||||||
|
|
|
||||||
|
LL | /// [`Self::IDENT2`]
|
||||||
|
| ^^^^^^^^^^^^ ambiguous link
|
||||||
|
|
|
||||||
|
help: to link to the associated constant, prefix with `const@`
|
||||||
|
|
|
||||||
|
LL | /// [`const@Self::IDENT2`]
|
||||||
|
| ++++++
|
||||||
|
help: to link to the associated type, prefix with `type@`
|
||||||
|
|
|
||||||
|
LL | /// [`type@Self::IDENT2`]
|
||||||
|
| +++++
|
||||||
|
|
||||||
|
error: `Self::IDENT2` is both an associated constant and an associated type
|
||||||
|
--> $DIR/issue-108653-associated-items.rs:30:7
|
||||||
|
|
|
||||||
|
LL | /// [`Self::IDENT2`]
|
||||||
|
| ^^^^^^^^^^^^ ambiguous link
|
||||||
|
|
|
||||||
|
help: to link to the associated constant, prefix with `const@`
|
||||||
|
|
|
||||||
|
LL | /// [`const@Self::IDENT2`]
|
||||||
|
| ++++++
|
||||||
|
help: to link to the associated type, prefix with `type@`
|
||||||
|
|
|
||||||
|
LL | /// [`type@Self::IDENT2`]
|
||||||
|
| +++++
|
||||||
|
|
||||||
|
error: `Self::IDENT` is both an associated function and a variant
|
||||||
|
--> $DIR/issue-108653-associated-items.rs:16:7
|
||||||
|
|
|
||||||
|
LL | /// [`Self::IDENT`]
|
||||||
|
| ^^^^^^^^^^^ ambiguous link
|
||||||
|
|
|
||||||
|
help: to link to the associated function, add parentheses
|
||||||
|
|
|
||||||
|
LL | /// [`Self::IDENT()`]
|
||||||
|
| ++
|
||||||
|
help: to link to the variant, prefix with `type@`
|
||||||
|
|
|
||||||
|
LL | /// [`type@Self::IDENT`]
|
||||||
|
| +++++
|
||||||
|
|
||||||
|
error: aborting due to 4 previous errors
|
||||||
|
|
|
@ -39,25 +39,25 @@ error: unresolved link to `unit::eq`
|
||||||
--> $DIR/non-path-primitives.rs:28:6
|
--> $DIR/non-path-primitives.rs:28:6
|
||||||
|
|
|
|
||||||
LL | //! [unit::eq]
|
LL | //! [unit::eq]
|
||||||
| ^^^^^^^^ the builtin type `unit` has no associated item named `eq`
|
| ^^^^^^^^ the primitive type `unit` has no associated item named `eq`
|
||||||
|
|
||||||
error: unresolved link to `tuple::eq`
|
error: unresolved link to `tuple::eq`
|
||||||
--> $DIR/non-path-primitives.rs:29:6
|
--> $DIR/non-path-primitives.rs:29:6
|
||||||
|
|
|
|
||||||
LL | //! [tuple::eq]
|
LL | //! [tuple::eq]
|
||||||
| ^^^^^^^^^ the builtin type `tuple` has no associated item named `eq`
|
| ^^^^^^^^^ the primitive type `tuple` has no associated item named `eq`
|
||||||
|
|
||||||
error: unresolved link to `fn::eq`
|
error: unresolved link to `fn::eq`
|
||||||
--> $DIR/non-path-primitives.rs:30:6
|
--> $DIR/non-path-primitives.rs:30:6
|
||||||
|
|
|
|
||||||
LL | //! [fn::eq]
|
LL | //! [fn::eq]
|
||||||
| ^^^^^^ the builtin type `fn` has no associated item named `eq`
|
| ^^^^^^ the primitive type `fn` has no associated item named `eq`
|
||||||
|
|
||||||
error: unresolved link to `reference::deref`
|
error: unresolved link to `reference::deref`
|
||||||
--> $DIR/non-path-primitives.rs:34:6
|
--> $DIR/non-path-primitives.rs:34:6
|
||||||
|
|
|
|
||||||
LL | //! [reference::deref]
|
LL | //! [reference::deref]
|
||||||
| ^^^^^^^^^^^^^^^^ the builtin type `reference` has no associated item named `deref`
|
| ^^^^^^^^^^^^^^^^ the primitive type `reference` has no associated item named `deref`
|
||||||
|
|
||||||
error: aborting due to 8 previous errors
|
error: aborting due to 8 previous errors
|
||||||
|
|
||||||
|
|
|
@ -2,16 +2,16 @@
|
||||||
//~^ NOTE lint level is defined
|
//~^ NOTE lint level is defined
|
||||||
|
|
||||||
/// [char]
|
/// [char]
|
||||||
//~^ ERROR both a module and a builtin type
|
//~^ ERROR both a module and a primitive type
|
||||||
//~| NOTE ambiguous link
|
//~| NOTE ambiguous link
|
||||||
//~| HELP to link to the module
|
//~| HELP to link to the module
|
||||||
//~| HELP to link to the builtin type
|
//~| HELP to link to the primitive type
|
||||||
|
|
||||||
/// [type@char]
|
/// [type@char]
|
||||||
//~^ ERROR both a module and a builtin type
|
//~^ ERROR both a module and a primitive type
|
||||||
//~| NOTE ambiguous link
|
//~| NOTE ambiguous link
|
||||||
//~| HELP to link to the module
|
//~| HELP to link to the module
|
||||||
//~| HELP to link to the builtin type
|
//~| HELP to link to the primitive type
|
||||||
|
|
||||||
/// [mod@char] // ok
|
/// [mod@char] // ok
|
||||||
/// [prim@char] // ok
|
/// [prim@char] // ok
|
||||||
|
@ -26,5 +26,5 @@ pub mod inner {
|
||||||
//! [struct@char]
|
//! [struct@char]
|
||||||
//~^ ERROR incompatible link
|
//~^ ERROR incompatible link
|
||||||
//~| HELP prefix with `prim@`
|
//~| HELP prefix with `prim@`
|
||||||
//~| NOTE resolved to a builtin type
|
//~| NOTE resolved to a primitive type
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
error: `char` is both a module and a builtin type
|
error: `char` is both a module and a primitive type
|
||||||
--> $DIR/prim-conflict.rs:4:6
|
--> $DIR/prim-conflict.rs:4:6
|
||||||
|
|
|
|
||||||
LL | /// [char]
|
LL | /// [char]
|
||||||
|
@ -13,12 +13,12 @@ help: to link to the module, prefix with `mod@`
|
||||||
|
|
|
|
||||||
LL | /// [mod@char]
|
LL | /// [mod@char]
|
||||||
| ++++
|
| ++++
|
||||||
help: to link to the builtin type, prefix with `prim@`
|
help: to link to the primitive type, prefix with `prim@`
|
||||||
|
|
|
|
||||||
LL | /// [prim@char]
|
LL | /// [prim@char]
|
||||||
| +++++
|
| +++++
|
||||||
|
|
||||||
error: `char` is both a module and a builtin type
|
error: `char` is both a module and a primitive type
|
||||||
--> $DIR/prim-conflict.rs:10:6
|
--> $DIR/prim-conflict.rs:10:6
|
||||||
|
|
|
|
||||||
LL | /// [type@char]
|
LL | /// [type@char]
|
||||||
|
@ -28,7 +28,7 @@ help: to link to the module, prefix with `mod@`
|
||||||
|
|
|
|
||||||
LL | /// [mod@char]
|
LL | /// [mod@char]
|
||||||
| ~~~~
|
| ~~~~
|
||||||
help: to link to the builtin type, prefix with `prim@`
|
help: to link to the primitive type, prefix with `prim@`
|
||||||
|
|
|
|
||||||
LL | /// [prim@char]
|
LL | /// [prim@char]
|
||||||
| ~~~~~
|
| ~~~~~
|
||||||
|
@ -48,9 +48,9 @@ error: incompatible link kind for `char`
|
||||||
--> $DIR/prim-conflict.rs:26:10
|
--> $DIR/prim-conflict.rs:26:10
|
||||||
|
|
|
|
||||||
LL | //! [struct@char]
|
LL | //! [struct@char]
|
||||||
| ^^^^^^^^^^^ this link resolved to a builtin type, which is not a struct
|
| ^^^^^^^^^^^ this link resolved to a primitive type, which is not a struct
|
||||||
|
|
|
|
||||||
help: to link to the builtin type, prefix with `prim@`
|
help: to link to the primitive type, prefix with `prim@`
|
||||||
|
|
|
|
||||||
LL | //! [prim@char]
|
LL | //! [prim@char]
|
||||||
| ~~~~~
|
| ~~~~~
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
#![feature(rustdoc_internals)]
|
#![feature(rustc_attrs)]
|
||||||
|
|
||||||
#![crate_name = "foo"]
|
#![crate_name = "foo"]
|
||||||
|
|
||||||
pub use std::fs::File;
|
pub use std::fs::File;
|
||||||
|
|
||||||
// @has 'foo/primitive.i16.html' '//h2[@id="synthetic-implementations"]' 'Auto Trait Implementation'
|
// @has 'foo/primitive.i16.html' '//h2[@id="synthetic-implementations"]' 'Auto Trait Implementation'
|
||||||
#[doc(primitive = "i16")]
|
#[rustc_doc_primitive = "i16"]
|
||||||
/// I love poneys!
|
/// I love poneys!
|
||||||
mod prim {}
|
mod prim {}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
// compile-flags: -Cmetadata=aux
|
// compile-flags: -Cmetadata=aux
|
||||||
#![crate_type = "rlib"]
|
#![crate_type = "rlib"]
|
||||||
#![doc(html_root_url = "http://example.com/")]
|
#![doc(html_root_url = "http://example.com/")]
|
||||||
|
#![feature(rustc_attrs)]
|
||||||
#![feature(lang_items)]
|
#![feature(lang_items)]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
|
@ -12,5 +13,5 @@ fn foo() {}
|
||||||
fn bar(_: &core::panic::PanicInfo) -> ! { loop {} }
|
fn bar(_: &core::panic::PanicInfo) -> ! { loop {} }
|
||||||
|
|
||||||
/// dox
|
/// dox
|
||||||
#[doc(primitive = "pointer")]
|
#[rustc_doc_primitive = "pointer"]
|
||||||
pub mod ptr {}
|
pub mod ptr {}
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
// compile-flags: --crate-type lib --edition 2018
|
// compile-flags: --crate-type lib --edition 2018
|
||||||
|
|
||||||
|
#![feature(rustc_attrs)]
|
||||||
#![feature(no_core)]
|
#![feature(no_core)]
|
||||||
#![no_core]
|
#![no_core]
|
||||||
|
|
||||||
#[doc(primitive = "usize")]
|
#[rustc_doc_primitive = "usize"]
|
||||||
/// This is the built-in type `usize`.
|
/// This is the built-in type `usize`.
|
||||||
mod usize {
|
mod usize {
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
// aux-build:source_code.rs
|
// aux-build:source_code.rs
|
||||||
// build-aux-docs
|
// build-aux-docs
|
||||||
|
|
||||||
#![feature(rustdoc_internals)]
|
#![feature(rustc_attrs)]
|
||||||
|
|
||||||
#![crate_name = "foo"]
|
#![crate_name = "foo"]
|
||||||
|
|
||||||
|
@ -65,5 +65,5 @@ pub fn foo4() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// @has - '//pre[@class="rust"]//a[@href="../../foo/primitive.bool.html"]' 'bool'
|
// @has - '//pre[@class="rust"]//a[@href="../../foo/primitive.bool.html"]' 'bool'
|
||||||
#[doc(primitive = "bool")]
|
#[rustc_doc_primitive = "bool"]
|
||||||
mod whatever {}
|
mod whatever {}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
#![rustc_coherence_is_core]
|
#![rustc_coherence_is_core]
|
||||||
#![crate_type="rlib"]
|
#![crate_type="rlib"]
|
||||||
|
|
||||||
#[doc(primitive = "char")]
|
#[rustc_doc_primitive = "char"]
|
||||||
/// Some char docs
|
/// Some char docs
|
||||||
mod char {}
|
mod char {}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Crate tree without a `doc(primitive)` module for primitive type linked to by a doc link.
|
// Crate tree without a `rustc_doc_primitive` module for primitive type linked to by a doc link.
|
||||||
|
|
||||||
#![deny(rustdoc::broken_intra_doc_links)]
|
#![deny(rustdoc::broken_intra_doc_links)]
|
||||||
#![feature(no_core, lang_items, rustc_attrs)]
|
#![feature(no_core, lang_items, rustc_attrs)]
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
//! A [prim@`char`] and its [`char::len_utf8`].
|
//! A [prim@`char`] and its [`char::len_utf8`].
|
||||||
|
|
||||||
#[doc(primitive = "char")]
|
#[rustc_doc_primitive = "char"]
|
||||||
mod char {}
|
mod char {}
|
||||||
|
|
||||||
impl char {
|
impl char {
|
||||||
|
|
|
@ -25,7 +25,7 @@ impl usize {
|
||||||
pub type ME = usize;
|
pub type ME = usize;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(primitive = "usize")]
|
#[rustc_doc_primitive = "usize"]
|
||||||
/// This has some docs.
|
/// This has some docs.
|
||||||
mod usize {}
|
mod usize {}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#![feature(rustdoc_internals)]
|
#![feature(rustc_attrs)]
|
||||||
|
|
||||||
// @has issue_15318_3/primitive.pointer.html
|
// @has issue_15318_3/primitive.pointer.html
|
||||||
|
|
||||||
/// dox
|
/// dox
|
||||||
#[doc(primitive = "pointer")]
|
#[rustc_doc_primitive = "pointer"]
|
||||||
pub mod ptr {}
|
pub mod ptr {}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
pub mod str {
|
pub mod str {
|
||||||
#![doc(primitive = "str")]
|
#![rustc_doc_primitive = "str"]
|
||||||
|
|
||||||
impl str {
|
impl str {
|
||||||
// @hasraw search-index.js foo
|
// @hasraw search-index.js foo
|
||||||
|
|
|
@ -6,10 +6,10 @@
|
||||||
//!
|
//!
|
||||||
//! [#80737]: https://github.com/rust-lang/rust/issues/80737
|
//! [#80737]: https://github.com/rust-lang/rust/issues/80737
|
||||||
|
|
||||||
#![feature(rustdoc_internals)]
|
#![feature(rustc_attrs)]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
#[doc(primitive = "reference")]
|
#[rustc_doc_primitive = "reference"]
|
||||||
/// Some useless docs, wouhou!
|
/// Some useless docs, wouhou!
|
||||||
///
|
///
|
||||||
/// We need to put this in here, because notable traits
|
/// We need to put this in here, because notable traits
|
||||||
|
|
|
@ -5,9 +5,9 @@
|
||||||
//!
|
//!
|
||||||
//! [#78160]: https://github.com/rust-lang/rust/issues/78160
|
//! [#78160]: https://github.com/rust-lang/rust/issues/78160
|
||||||
|
|
||||||
#![feature(rustdoc_internals)]
|
#![feature(rustc_attrs)]
|
||||||
|
|
||||||
#[doc(primitive = "reference")]
|
#[rustc_doc_primitive = "reference"]
|
||||||
/// Some useless docs, wouhou!
|
/// Some useless docs, wouhou!
|
||||||
///
|
///
|
||||||
/// We need to put this in here, because notable traits
|
/// We need to put this in here, because notable traits
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#![crate_name = "foo"]
|
#![crate_name = "foo"]
|
||||||
|
|
||||||
#![feature(rustdoc_internals)]
|
#![feature(rustc_attrs)]
|
||||||
|
|
||||||
// @has foo/index.html
|
// @has foo/index.html
|
||||||
// @has - '//h2[@id="primitives"]' 'Primitive Types'
|
// @has - '//h2[@id="primitives"]' 'Primitive Types'
|
||||||
|
@ -16,7 +16,7 @@
|
||||||
// @count - '//*[@class="impl"]' 1
|
// @count - '//*[@class="impl"]' 1
|
||||||
// @has - '//*[@id="impl-Foo%3C%26A%3E-for-%26B"]/*[@class="code-header"]' \
|
// @has - '//*[@id="impl-Foo%3C%26A%3E-for-%26B"]/*[@class="code-header"]' \
|
||||||
// 'impl<A, B> Foo<&A> for &B'
|
// 'impl<A, B> Foo<&A> for &B'
|
||||||
#[doc(primitive = "reference")]
|
#[rustc_doc_primitive = "reference"]
|
||||||
/// this is a test!
|
/// this is a test!
|
||||||
mod reference {}
|
mod reference {}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// compile-flags: --crate-type lib --edition 2018
|
// compile-flags: --crate-type lib --edition 2018
|
||||||
|
|
||||||
#![crate_name = "foo"]
|
#![crate_name = "foo"]
|
||||||
#![feature(rustdoc_internals)]
|
#![feature(rustc_attrs)]
|
||||||
|
|
||||||
// @has foo/primitive.slice.html '//a[@class="primitive"]' 'slice'
|
// @has foo/primitive.slice.html '//a[@class="primitive"]' 'slice'
|
||||||
// @has - '//h1' 'Primitive Type slice'
|
// @has - '//h1' 'Primitive Type slice'
|
||||||
|
@ -9,6 +9,6 @@
|
||||||
// @has - '//h2[@id="synthetic-implementations"]' 'Auto Trait Implementations'
|
// @has - '//h2[@id="synthetic-implementations"]' 'Auto Trait Implementations'
|
||||||
// @has - '//div[@id="synthetic-implementations-list"]//h3' 'impl<T> Send for [T]where T: Send'
|
// @has - '//div[@id="synthetic-implementations-list"]//h3' 'impl<T> Send for [T]where T: Send'
|
||||||
// @has - '//div[@id="synthetic-implementations-list"]//h3' 'impl<T> Sync for [T]where T: Sync'
|
// @has - '//div[@id="synthetic-implementations-list"]//h3' 'impl<T> Sync for [T]where T: Sync'
|
||||||
#[doc(primitive = "slice")]
|
#[rustc_doc_primitive = "slice"]
|
||||||
/// this is a test!
|
/// this is a test!
|
||||||
mod slice_prim {}
|
mod slice_prim {}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// compile-flags: --crate-type lib --edition 2018
|
// compile-flags: --crate-type lib --edition 2018
|
||||||
|
|
||||||
#![crate_name = "foo"]
|
#![crate_name = "foo"]
|
||||||
#![feature(rustdoc_internals)]
|
#![feature(rustc_attrs)]
|
||||||
|
|
||||||
// @has foo/primitive.tuple.html '//a[@class="primitive"]' 'tuple'
|
// @has foo/primitive.tuple.html '//a[@class="primitive"]' 'tuple'
|
||||||
// @has - '//h1' 'Primitive Type tuple'
|
// @has - '//h1' 'Primitive Type tuple'
|
||||||
|
@ -9,7 +9,7 @@
|
||||||
// @has - '//h2[@id="synthetic-implementations"]' 'Auto Trait Implementations'
|
// @has - '//h2[@id="synthetic-implementations"]' 'Auto Trait Implementations'
|
||||||
// @has - '//div[@id="synthetic-implementations-list"]//h3' 'Send'
|
// @has - '//div[@id="synthetic-implementations-list"]//h3' 'Send'
|
||||||
// @has - '//div[@id="synthetic-implementations-list"]//h3' 'Sync'
|
// @has - '//div[@id="synthetic-implementations-list"]//h3' 'Sync'
|
||||||
#[doc(primitive = "tuple")]
|
#[rustc_doc_primitive = "tuple"]
|
||||||
/// this is a test!
|
/// this is a test!
|
||||||
///
|
///
|
||||||
// Hardcoded anchor to header written in library/core/src/primitive_docs.rs
|
// Hardcoded anchor to header written in library/core/src/primitive_docs.rs
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// compile-flags: --crate-type lib --edition 2018
|
// compile-flags: --crate-type lib --edition 2018
|
||||||
|
|
||||||
#![crate_name = "foo"]
|
#![crate_name = "foo"]
|
||||||
#![feature(rustdoc_internals)]
|
#![feature(rustc_attrs)]
|
||||||
|
|
||||||
// @has foo/primitive.unit.html '//a[@class="primitive"]' 'unit'
|
// @has foo/primitive.unit.html '//a[@class="primitive"]' 'unit'
|
||||||
// @has - '//h1' 'Primitive Type unit'
|
// @has - '//h1' 'Primitive Type unit'
|
||||||
|
@ -9,6 +9,6 @@
|
||||||
// @has - '//h2[@id="synthetic-implementations"]' 'Auto Trait Implementations'
|
// @has - '//h2[@id="synthetic-implementations"]' 'Auto Trait Implementations'
|
||||||
// @has - '//div[@id="synthetic-implementations-list"]//h3' 'impl Send for ()'
|
// @has - '//div[@id="synthetic-implementations-list"]//h3' 'impl Send for ()'
|
||||||
// @has - '//div[@id="synthetic-implementations-list"]//h3' 'impl Sync for ()'
|
// @has - '//div[@id="synthetic-implementations-list"]//h3' 'impl Sync for ()'
|
||||||
#[doc(primitive = "unit")]
|
#[rustc_doc_primitive = "unit"]
|
||||||
/// this is a test!
|
/// this is a test!
|
||||||
mod unit_prim {}
|
mod unit_prim {}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
#![feature(rustdoc_internals)]
|
#![feature(rustc_attrs)]
|
||||||
#![crate_name = "foo"]
|
#![crate_name = "foo"]
|
||||||
|
|
||||||
// @has foo/primitive.i32.html '//*[@id="impl-ToString-for-i32"]//h3[@class="code-header"]' 'impl<T> ToString for T'
|
// @has foo/primitive.i32.html '//*[@id="impl-ToString-for-i32"]//h3[@class="code-header"]' 'impl<T> ToString for T'
|
||||||
|
|
||||||
#[doc(primitive = "i32")]
|
#[rustc_doc_primitive = "i32"]
|
||||||
/// Some useless docs, wouhou!
|
/// Some useless docs, wouhou!
|
||||||
mod i32 {}
|
mod i32 {}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#![crate_name = "foo"]
|
#![crate_name = "foo"]
|
||||||
|
|
||||||
#![feature(rustdoc_internals)]
|
#![feature(rustc_attrs)]
|
||||||
|
|
||||||
// @has foo/index.html '//h2[@id="primitives"]' 'Primitive Types'
|
// @has foo/index.html '//h2[@id="primitives"]' 'Primitive Types'
|
||||||
// @has foo/index.html '//a[@href="primitive.i32.html"]' 'i32'
|
// @has foo/index.html '//a[@href="primitive.i32.html"]' 'i32'
|
||||||
|
@ -11,11 +11,11 @@
|
||||||
// @has foo/primitive.i32.html '//section[@id="main-content"]//div[@class="docblock"]//p' 'this is a test!'
|
// @has foo/primitive.i32.html '//section[@id="main-content"]//div[@class="docblock"]//p' 'this is a test!'
|
||||||
// @has foo/index.html '//a/@href' '../foo/index.html'
|
// @has foo/index.html '//a/@href' '../foo/index.html'
|
||||||
// @!has foo/index.html '//span' '🔒'
|
// @!has foo/index.html '//span' '🔒'
|
||||||
#[doc(primitive = "i32")]
|
#[rustc_doc_primitive = "i32"]
|
||||||
/// this is a test!
|
/// this is a test!
|
||||||
mod i32{}
|
mod i32{}
|
||||||
|
|
||||||
// @has foo/primitive.bool.html '//section[@id="main-content"]//div[@class="docblock"]//p' 'hello'
|
// @has foo/primitive.bool.html '//section[@id="main-content"]//div[@class="docblock"]//p' 'hello'
|
||||||
#[doc(primitive = "bool")]
|
#[rustc_doc_primitive = "bool"]
|
||||||
/// hello
|
/// hello
|
||||||
mod bool {}
|
mod bool {}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#![crate_name = "foo"]
|
#![crate_name = "foo"]
|
||||||
|
|
||||||
#![feature(rustdoc_internals)]
|
#![feature(rustc_attrs)]
|
||||||
|
|
||||||
// @has 'foo/all.html'
|
// @has 'foo/all.html'
|
||||||
// @has - '//*[@class="sidebar-elems"]//li' 'Structs'
|
// @has - '//*[@class="sidebar-elems"]//li' 'Structs'
|
||||||
|
@ -31,5 +31,5 @@ macro_rules! foo {
|
||||||
pub type Type = u8;
|
pub type Type = u8;
|
||||||
pub const FOO: u8 = 0;
|
pub const FOO: u8 = 0;
|
||||||
pub static BAR: u8 = 0;
|
pub static BAR: u8 = 0;
|
||||||
#[doc(primitive = "u8")]
|
#[rustc_doc_primitive = "u8"]
|
||||||
mod u8 {}
|
mod u8 {}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#![crate_name = "foo"]
|
#![crate_name = "foo"]
|
||||||
|
#![feature(rustc_attrs)]
|
||||||
#![feature(rustdoc_internals)]
|
#![feature(rustdoc_internals)]
|
||||||
|
|
||||||
// tests for the html <title> element
|
// tests for the html <title> element
|
||||||
|
@ -39,6 +40,6 @@ mod continue_keyword {}
|
||||||
|
|
||||||
// @has foo/primitive.u8.html '//head/title' 'u8 - Rust'
|
// @has foo/primitive.u8.html '//head/title' 'u8 - Rust'
|
||||||
// @!has - '//head/title' 'foo'
|
// @!has - '//head/title' 'foo'
|
||||||
#[doc(primitive = "u8")]
|
#[rustc_doc_primitive = "u8"]
|
||||||
/// `u8` docs
|
/// `u8` docs
|
||||||
mod u8 {}
|
mod u8 {}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#![crate_name = "foo"]
|
#![crate_name = "foo"]
|
||||||
#![feature(rustdoc_internals)]
|
#![feature(rustc_attrs)]
|
||||||
|
|
||||||
// @matches 'foo/index.html' '//h1' 'Crate foo'
|
// @matches 'foo/index.html' '//h1' 'Crate foo'
|
||||||
// @matches 'foo/index.html' '//h2[@class="location"]' 'Crate foo'
|
// @matches 'foo/index.html' '//h2[@class="location"]' 'Crate foo'
|
||||||
|
@ -41,7 +41,7 @@ macro_rules! foo_macro {
|
||||||
}
|
}
|
||||||
|
|
||||||
// @matches 'foo/primitive.bool.html' '//h1' 'Primitive Type bool'
|
// @matches 'foo/primitive.bool.html' '//h1' 'Primitive Type bool'
|
||||||
#[doc(primitive = "bool")]
|
#[rustc_doc_primitive = "bool"]
|
||||||
mod bool {}
|
mod bool {}
|
||||||
|
|
||||||
// @matches 'foo/static.FOO_STATIC.html' '//h1' 'Static foo::FOO_STATIC'
|
// @matches 'foo/static.FOO_STATIC.html' '//h1' 'Static foo::FOO_STATIC'
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// normalize-stderr-test "note.*" -> "note: os-specific message"
|
// normalize-stderr-test "could not open Fluent resource:.*" -> "could not open Fluent resource: os-specific message"
|
||||||
|
|
||||||
#![feature(rustc_private)]
|
#![feature(rustc_private)]
|
||||||
#![crate_type = "lib"]
|
#![crate_type = "lib"]
|
||||||
|
|
|
@ -1,18 +1,14 @@
|
||||||
error: could not open Fluent resource
|
error: could not open Fluent resource: os-specific message
|
||||||
--> $DIR/test.rs:24:24
|
--> $DIR/test.rs:24:24
|
||||||
|
|
|
|
||||||
LL | fluent_messages! { "/definitely_does_not_exist.ftl" }
|
LL | fluent_messages! { "/definitely_does_not_exist.ftl" }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
= note: os-specific message
|
|
||||||
|
|
||||||
error: could not open Fluent resource
|
error: could not open Fluent resource: os-specific message
|
||||||
--> $DIR/test.rs:31:24
|
--> $DIR/test.rs:31:24
|
||||||
|
|
|
|
||||||
LL | fluent_messages! { "../definitely_does_not_exist.ftl" }
|
LL | fluent_messages! { "../definitely_does_not_exist.ftl" }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
= note: os-specific message
|
|
||||||
|
|
||||||
error: could not parse Fluent resource
|
error: could not parse Fluent resource
|
||||||
--> $DIR/test.rs:38:24
|
--> $DIR/test.rs:38:24
|
||||||
|
@ -89,7 +85,7 @@ error: invalid escape `\n` in Fluent resource
|
||||||
LL | fluent_messages! { "./invalid-escape.ftl" }
|
LL | fluent_messages! { "./invalid-escape.ftl" }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: os-specific message
|
= note: Fluent does not interpret these escape sequences (<https://projectfluent.org/fluent/guide/special.html>)
|
||||||
|
|
||||||
error: invalid escape `\"` in Fluent resource
|
error: invalid escape `\"` in Fluent resource
|
||||||
--> $DIR/test.rs:99:24
|
--> $DIR/test.rs:99:24
|
||||||
|
@ -97,7 +93,7 @@ error: invalid escape `\"` in Fluent resource
|
||||||
LL | fluent_messages! { "./invalid-escape.ftl" }
|
LL | fluent_messages! { "./invalid-escape.ftl" }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: os-specific message
|
= note: Fluent does not interpret these escape sequences (<https://projectfluent.org/fluent/guide/special.html>)
|
||||||
|
|
||||||
error: invalid escape `\'` in Fluent resource
|
error: invalid escape `\'` in Fluent resource
|
||||||
--> $DIR/test.rs:99:24
|
--> $DIR/test.rs:99:24
|
||||||
|
@ -105,7 +101,7 @@ error: invalid escape `\'` in Fluent resource
|
||||||
LL | fluent_messages! { "./invalid-escape.ftl" }
|
LL | fluent_messages! { "./invalid-escape.ftl" }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: os-specific message
|
= note: Fluent does not interpret these escape sequences (<https://projectfluent.org/fluent/guide/special.html>)
|
||||||
|
|
||||||
error: aborting due to 13 previous errors
|
error: aborting due to 13 previous errors
|
||||||
|
|
||||||
|
|
13
tests/ui/closures/2229_closure_analysis/array_subslice.rs
Normal file
13
tests/ui/closures/2229_closure_analysis/array_subslice.rs
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
// regression test for #109298
|
||||||
|
// edition: 2021
|
||||||
|
|
||||||
|
pub fn subslice_array(x: [u8; 3]) {
|
||||||
|
let f = || {
|
||||||
|
let [_x @ ..] = x;
|
||||||
|
let [ref y, ref mut z @ ..] = x; //~ ERROR cannot borrow `x[..]` as mutable
|
||||||
|
};
|
||||||
|
|
||||||
|
f(); //~ ERROR cannot borrow `f` as mutable
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -0,0 +1,26 @@
|
||||||
|
error[E0596]: cannot borrow `x[..]` as mutable, as `x` is not declared as mutable
|
||||||
|
--> $DIR/array_subslice.rs:7:21
|
||||||
|
|
|
||||||
|
LL | pub fn subslice_array(x: [u8; 3]) {
|
||||||
|
| - help: consider changing this to be mutable: `mut x`
|
||||||
|
...
|
||||||
|
LL | let [ref y, ref mut z @ ..] = x;
|
||||||
|
| ^^^^^^^^^ cannot borrow as mutable
|
||||||
|
|
||||||
|
error[E0596]: cannot borrow `f` as mutable, as it is not declared as mutable
|
||||||
|
--> $DIR/array_subslice.rs:10:5
|
||||||
|
|
|
||||||
|
LL | let [ref y, ref mut z @ ..] = x;
|
||||||
|
| - calling `f` requires mutable binding due to mutable borrow of `x`
|
||||||
|
...
|
||||||
|
LL | f();
|
||||||
|
| ^ cannot borrow as mutable
|
||||||
|
|
|
||||||
|
help: consider changing this to be mutable
|
||||||
|
|
|
||||||
|
LL | let mut f = || {
|
||||||
|
| +++
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0596`.
|
8
tests/ui/rustdoc/doc-primitive.rs
Normal file
8
tests/ui/rustdoc/doc-primitive.rs
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
#![deny(invalid_doc_attributes)]
|
||||||
|
|
||||||
|
#[doc(primitive = "foo")]
|
||||||
|
//~^ ERROR unknown `doc` attribute `primitive`
|
||||||
|
//~| WARN
|
||||||
|
mod bar {}
|
||||||
|
|
||||||
|
fn main() {}
|
16
tests/ui/rustdoc/doc-primitive.stderr
Normal file
16
tests/ui/rustdoc/doc-primitive.stderr
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
error: unknown `doc` attribute `primitive`
|
||||||
|
--> $DIR/doc-primitive.rs:3:7
|
||||||
|
|
|
||||||
|
LL | #[doc(primitive = "foo")]
|
||||||
|
| ^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
|
= note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
|
||||||
|
note: the lint level is defined here
|
||||||
|
--> $DIR/doc-primitive.rs:1:9
|
||||||
|
|
|
||||||
|
LL | #![deny(invalid_doc_attributes)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
// check-pass
|
#[rustc_doc_primitive = "usize"]
|
||||||
#[doc(primitive = "usize")]
|
//~^ ERROR `rustc_doc_primitive` is a rustc internal attribute
|
||||||
//~^ WARNING `doc(primitive)` should never have been stable
|
|
||||||
//~| WARNING hard error in a future release
|
|
||||||
/// Some docs
|
/// Some docs
|
||||||
mod usize {}
|
mod usize {}
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
warning: `doc(primitive)` should never have been stable
|
error[E0658]: `rustc_doc_primitive` is a rustc internal attribute
|
||||||
--> $DIR/feature-gate-doc_primitive.rs:2:7
|
--> $DIR/feature-gate-doc_primitive.rs:1:1
|
||||||
|
|
|
|
||||||
LL | #[doc(primitive = "usize")]
|
LL | #[rustc_doc_primitive = "usize"]
|
||||||
| ^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
= help: add `#![feature(rustc_attrs)]` to the crate attributes to enable
|
||||||
= note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
|
|
||||||
= note: `#[warn(invalid_doc_attributes)]` on by default
|
|
||||||
|
|
||||||
warning: 1 warning emitted
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0658`.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue