mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-12 18:07:40 +00:00
Auto merge of #112025 - matthiaskrgr:rollup-j693v67, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - #108630 (Fix docs for `alloc::realloc`) - #109084 (rustc driver: Remove argument 0 before at-expansion to prevent ICE) - #111181 (fix(parse): return unpected when current token is EOF) - #111656 (Use an unbounded lifetime in `String::leak`.) - #111946 (rustdoc: Add `ItemTemplate` trait and related functions to avoid repetitively wrapping existing functions) - #112018 (Clean up usage of `cx.tcx` when `tcx` is already set into a variable) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
cca7ee5811
@ -18,6 +18,9 @@ fn arg_expand(arg: String) -> Result<Vec<String>, Error> {
|
||||
}
|
||||
}
|
||||
|
||||
/// **Note:** This function doesn't interpret argument 0 in any special way.
|
||||
/// If this function is intended to be used with command line arguments,
|
||||
/// `argv[0]` must be removed prior to calling it manually.
|
||||
pub fn arg_expand_all(at_args: &[String]) -> Vec<String> {
|
||||
let mut args = Vec::new();
|
||||
for arg in at_args {
|
||||
|
@ -250,6 +250,16 @@ fn run_compiler(
|
||||
Box<dyn FnOnce(&config::Options) -> Box<dyn CodegenBackend> + Send>,
|
||||
>,
|
||||
) -> interface::Result<()> {
|
||||
// Throw away the first argument, the name of the binary.
|
||||
// In case of at_args being empty, as might be the case by
|
||||
// passing empty argument array to execve under some platforms,
|
||||
// just use an empty slice.
|
||||
//
|
||||
// This situation was possible before due to arg_expand_all being
|
||||
// called before removing the argument, enabling a crash by calling
|
||||
// the compiler with @empty_file as argv[0] and no more arguments.
|
||||
let at_args = at_args.get(1..).unwrap_or_default();
|
||||
|
||||
let args = args::arg_expand_all(at_args);
|
||||
|
||||
let Some(matches) = handle_options(&args) else { return Ok(()) };
|
||||
@ -1074,9 +1084,6 @@ fn print_flag_list<T>(
|
||||
/// So with all that in mind, the comments below have some more detail about the
|
||||
/// contortions done here to get things to work out correctly.
|
||||
pub fn handle_options(args: &[String]) -> Option<getopts::Matches> {
|
||||
// Throw away the first argument, the name of the binary
|
||||
let args = &args[1..];
|
||||
|
||||
if args.is_empty() {
|
||||
// user did not write `-v` nor `-Z unstable-options`, so do not
|
||||
// include that extra information.
|
||||
|
@ -536,7 +536,9 @@ impl<'a> Parser<'a> {
|
||||
} else if inedible.contains(&self.token.kind) {
|
||||
// leave it in the input
|
||||
Ok(false)
|
||||
} else if self.last_unexpected_token_span == Some(self.token.span) {
|
||||
} else if self.token.kind != token::Eof
|
||||
&& self.last_unexpected_token_span == Some(self.token.span)
|
||||
{
|
||||
FatalError.raise();
|
||||
} else {
|
||||
self.expected_one_of_not_found(edible, inedible)
|
||||
|
@ -1851,7 +1851,7 @@ impl String {
|
||||
}
|
||||
|
||||
/// Consumes and leaks the `String`, returning a mutable reference to the contents,
|
||||
/// `&'static mut str`.
|
||||
/// `&'a mut str`.
|
||||
///
|
||||
/// This is mainly useful for data that lives for the remainder of
|
||||
/// the program's life. Dropping the returned reference will cause a memory
|
||||
@ -1874,7 +1874,7 @@ impl String {
|
||||
/// ```
|
||||
#[unstable(feature = "string_leak", issue = "102929")]
|
||||
#[inline]
|
||||
pub fn leak(self) -> &'static mut str {
|
||||
pub fn leak<'a>(self) -> &'a mut str {
|
||||
let slice = self.vec.leak();
|
||||
unsafe { from_utf8_unchecked_mut(slice) }
|
||||
}
|
||||
|
@ -235,7 +235,8 @@ pub unsafe trait GlobalAlloc {
|
||||
/// * `new_size` must be greater than zero.
|
||||
///
|
||||
/// * `new_size`, when rounded up to the nearest multiple of `layout.align()`,
|
||||
/// must not overflow (i.e., the rounded value must be less than `usize::MAX`).
|
||||
/// must not overflow isize (i.e., the rounded value must be less than or
|
||||
/// equal to `isize::MAX`).
|
||||
///
|
||||
/// (Extension subtraits might provide more specific bounds on
|
||||
/// behavior, e.g., guarantee a sentinel address or a null pointer
|
||||
|
@ -355,9 +355,9 @@ pub(crate) fn build_impl(
|
||||
return;
|
||||
}
|
||||
|
||||
let _prof_timer = cx.tcx.sess.prof.generic_activity("build_impl");
|
||||
|
||||
let tcx = cx.tcx;
|
||||
let _prof_timer = tcx.sess.prof.generic_activity("build_impl");
|
||||
|
||||
let associated_trait = tcx.impl_trait_ref(did).map(ty::EarlyBinder::skip_binder);
|
||||
|
||||
// Only inline impl if the implemented trait is
|
||||
|
@ -193,7 +193,7 @@ pub(crate) fn build_deref_target_impls(
|
||||
};
|
||||
|
||||
if let Some(prim) = target.primitive_type() {
|
||||
let _prof_timer = cx.tcx.sess.prof.generic_activity("build_primitive_inherent_impls");
|
||||
let _prof_timer = tcx.sess.prof.generic_activity("build_primitive_inherent_impls");
|
||||
for did in prim.impls(tcx).filter(|did| !did.is_local()) {
|
||||
inline::build_impl(cx, did, None, ret);
|
||||
}
|
||||
|
@ -314,7 +314,6 @@ impl Options {
|
||||
matches: &getopts::Matches,
|
||||
args: Vec<String>,
|
||||
) -> Result<(Options, RenderOptions), i32> {
|
||||
let args = &args[1..];
|
||||
// Check for unstable options.
|
||||
nightly_options::check_nightly_options(matches, &opts());
|
||||
|
||||
|
@ -147,7 +147,7 @@ impl Cache {
|
||||
|
||||
// Cache where all our extern crates are located
|
||||
// FIXME: this part is specific to HTML so it'd be nice to remove it from the common code
|
||||
for &crate_num in cx.tcx.crates(()) {
|
||||
for &crate_num in tcx.crates(()) {
|
||||
let e = ExternalCrate { crate_num };
|
||||
|
||||
let name = e.name(tcx);
|
||||
|
@ -9,6 +9,8 @@ use rustc_middle::middle::stability;
|
||||
use rustc_middle::ty::{self, TyCtxt};
|
||||
use rustc_span::hygiene::MacroKind;
|
||||
use rustc_span::symbol::{kw, sym, Symbol};
|
||||
use std::borrow::Borrow;
|
||||
use std::cell::{RefCell, RefMut};
|
||||
use std::cmp::Ordering;
|
||||
use std::fmt;
|
||||
use std::rc::Rc;
|
||||
@ -216,6 +218,53 @@ fn toggle_close(mut w: impl fmt::Write) {
|
||||
w.write_str("</details>").unwrap();
|
||||
}
|
||||
|
||||
trait ItemTemplate<'a, 'cx: 'a>: askama::Template + fmt::Display {
|
||||
fn item_and_mut_cx(&self) -> (&'a clean::Item, RefMut<'_, &'a mut Context<'cx>>);
|
||||
}
|
||||
|
||||
fn item_template_document<'a: 'b, 'b, 'cx: 'a>(
|
||||
templ: &'b impl ItemTemplate<'a, 'cx>,
|
||||
) -> impl fmt::Display + Captures<'a> + 'b + Captures<'cx> {
|
||||
display_fn(move |f| {
|
||||
let (item, mut cx) = templ.item_and_mut_cx();
|
||||
let v = document(*cx, item, None, HeadingOffset::H2);
|
||||
write!(f, "{v}")
|
||||
})
|
||||
}
|
||||
|
||||
fn item_template_document_type_layout<'a: 'b, 'b, 'cx: 'a>(
|
||||
templ: &'b impl ItemTemplate<'a, 'cx>,
|
||||
) -> impl fmt::Display + Captures<'a> + 'b + Captures<'cx> {
|
||||
display_fn(move |f| {
|
||||
let (item, cx) = templ.item_and_mut_cx();
|
||||
let def_id = item.item_id.expect_def_id();
|
||||
let v = document_type_layout(*cx, def_id);
|
||||
write!(f, "{v}")
|
||||
})
|
||||
}
|
||||
|
||||
fn item_template_render_attributes_in_pre<'a: 'b, 'b, 'cx: 'a>(
|
||||
templ: &'b impl ItemTemplate<'a, 'cx>,
|
||||
) -> impl fmt::Display + Captures<'a> + 'b + Captures<'cx> {
|
||||
display_fn(move |f| {
|
||||
let (item, cx) = templ.item_and_mut_cx();
|
||||
let tcx = cx.tcx();
|
||||
let v = render_attributes_in_pre(item, "", tcx);
|
||||
write!(f, "{v}")
|
||||
})
|
||||
}
|
||||
|
||||
fn item_template_render_assoc_items<'a: 'b, 'b, 'cx: 'a>(
|
||||
templ: &'b impl ItemTemplate<'a, 'cx>,
|
||||
) -> impl fmt::Display + Captures<'a> + 'b + Captures<'cx> {
|
||||
display_fn(move |f| {
|
||||
let (item, mut cx) = templ.item_and_mut_cx();
|
||||
let def_id = item.item_id.expect_def_id();
|
||||
let v = render_assoc_items(*cx, item, def_id, AssocItemRender::All);
|
||||
write!(f, "{v}")
|
||||
})
|
||||
}
|
||||
|
||||
fn item_module(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Item, items: &[clean::Item]) {
|
||||
write!(w, "{}", document(cx, item, None, HeadingOffset::H2));
|
||||
|
||||
@ -356,18 +405,18 @@ fn item_module(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Item, items:
|
||||
|
||||
clean::ImportItem(ref import) => {
|
||||
let stab_tags = if let Some(import_def_id) = import.source.did {
|
||||
let ast_attrs = cx.tcx().get_attrs_unchecked(import_def_id);
|
||||
let ast_attrs = tcx.get_attrs_unchecked(import_def_id);
|
||||
let import_attrs = Box::new(clean::Attributes::from_ast(ast_attrs));
|
||||
|
||||
// Just need an item with the correct def_id and attrs
|
||||
let import_item = clean::Item {
|
||||
item_id: import_def_id.into(),
|
||||
attrs: import_attrs,
|
||||
cfg: ast_attrs.cfg(cx.tcx(), &cx.cache().hidden_cfg),
|
||||
cfg: ast_attrs.cfg(tcx, &cx.cache().hidden_cfg),
|
||||
..myitem.clone()
|
||||
};
|
||||
|
||||
let stab_tags = Some(extra_info_tags(&import_item, item, cx.tcx()).to_string());
|
||||
let stab_tags = Some(extra_info_tags(&import_item, item, tcx).to_string());
|
||||
stab_tags
|
||||
} else {
|
||||
None
|
||||
@ -405,8 +454,7 @@ fn item_module(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Item, items:
|
||||
|
||||
let unsafety_flag = match *myitem.kind {
|
||||
clean::FunctionItem(_) | clean::ForeignFunctionItem(_)
|
||||
if myitem.fn_header(cx.tcx()).unwrap().unsafety
|
||||
== hir::Unsafety::Unsafe =>
|
||||
if myitem.fn_header(tcx).unwrap().unsafety == hir::Unsafety::Unsafe =>
|
||||
{
|
||||
"<sup title=\"unsafe function\">⚠</sup>"
|
||||
}
|
||||
@ -439,7 +487,7 @@ fn item_module(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Item, items:
|
||||
{docs_before}{docs}{docs_after}",
|
||||
name = myitem.name.unwrap(),
|
||||
visibility_emoji = visibility_emoji,
|
||||
stab_tags = extra_info_tags(myitem, item, cx.tcx()),
|
||||
stab_tags = extra_info_tags(myitem, item, tcx),
|
||||
class = myitem.type_(),
|
||||
unsafety_flag = unsafety_flag,
|
||||
href = item_path(myitem.type_(), myitem.name.unwrap().as_str()),
|
||||
@ -886,7 +934,7 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean:
|
||||
write_small_section_header(w, "foreign-impls", "Implementations on Foreign Types", "");
|
||||
|
||||
for implementor in foreign {
|
||||
let provided_methods = implementor.inner_impl().provided_trait_methods(cx.tcx());
|
||||
let provided_methods = implementor.inner_impl().provided_trait_methods(tcx);
|
||||
let assoc_link =
|
||||
AssocItemLink::GotoSource(implementor.impl_item.item_id, &provided_methods);
|
||||
render_impl(
|
||||
@ -919,7 +967,7 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean:
|
||||
}
|
||||
w.write_str("</div>");
|
||||
|
||||
if t.is_auto(cx.tcx()) {
|
||||
if t.is_auto(tcx) {
|
||||
write_small_section_header(
|
||||
w,
|
||||
"synthetic-implementors",
|
||||
@ -948,7 +996,7 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean:
|
||||
"<div id=\"implementors-list\"></div>",
|
||||
);
|
||||
|
||||
if t.is_auto(cx.tcx()) {
|
||||
if t.is_auto(tcx) {
|
||||
write_small_section_header(
|
||||
w,
|
||||
"synthetic-implementors",
|
||||
@ -1131,32 +1179,18 @@ fn item_union(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, s: &clean:
|
||||
#[derive(Template)]
|
||||
#[template(path = "item_union.html")]
|
||||
struct ItemUnion<'a, 'cx> {
|
||||
cx: std::cell::RefCell<&'a mut Context<'cx>>,
|
||||
cx: RefCell<&'a mut Context<'cx>>,
|
||||
it: &'a clean::Item,
|
||||
s: &'a clean::Union,
|
||||
}
|
||||
|
||||
impl<'a, 'cx: 'a> ItemTemplate<'a, 'cx> for ItemUnion<'a, 'cx> {
|
||||
fn item_and_mut_cx(&self) -> (&'a clean::Item, RefMut<'_, &'a mut Context<'cx>>) {
|
||||
(self.it, self.cx.borrow_mut())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'cx: 'a> ItemUnion<'a, 'cx> {
|
||||
fn render_assoc_items<'b>(
|
||||
&'b self,
|
||||
) -> impl fmt::Display + Captures<'a> + 'b + Captures<'cx> {
|
||||
display_fn(move |f| {
|
||||
let def_id = self.it.item_id.expect_def_id();
|
||||
let mut cx = self.cx.borrow_mut();
|
||||
let v = render_assoc_items(*cx, self.it, def_id, AssocItemRender::All);
|
||||
write!(f, "{v}")
|
||||
})
|
||||
}
|
||||
fn document_type_layout<'b>(
|
||||
&'b self,
|
||||
) -> impl fmt::Display + Captures<'a> + 'b + Captures<'cx> {
|
||||
display_fn(move |f| {
|
||||
let def_id = self.it.item_id.expect_def_id();
|
||||
let cx = self.cx.borrow_mut();
|
||||
let v = document_type_layout(*cx, def_id);
|
||||
write!(f, "{v}")
|
||||
})
|
||||
}
|
||||
fn render_union<'b>(&'b self) -> impl fmt::Display + Captures<'a> + 'b + Captures<'cx> {
|
||||
display_fn(move |f| {
|
||||
let cx = self.cx.borrow_mut();
|
||||
@ -1164,22 +1198,6 @@ fn item_union(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, s: &clean:
|
||||
write!(f, "{v}")
|
||||
})
|
||||
}
|
||||
fn render_attributes_in_pre<'b>(
|
||||
&'b self,
|
||||
) -> impl fmt::Display + Captures<'a> + 'b + Captures<'cx> {
|
||||
display_fn(move |f| {
|
||||
let tcx = self.cx.borrow().tcx();
|
||||
let v = render_attributes_in_pre(self.it, "", tcx);
|
||||
write!(f, "{v}")
|
||||
})
|
||||
}
|
||||
fn document<'b>(&'b self) -> impl fmt::Display + Captures<'a> + 'b + Captures<'cx> {
|
||||
display_fn(move |f| {
|
||||
let mut cx = self.cx.borrow_mut();
|
||||
let v = document(*cx, self.it, None, HeadingOffset::H2);
|
||||
write!(f, "{v}")
|
||||
})
|
||||
}
|
||||
fn document_field<'b>(
|
||||
&'b self,
|
||||
field: &'a clean::Item,
|
||||
@ -1219,7 +1237,7 @@ fn item_union(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, s: &clean:
|
||||
}
|
||||
}
|
||||
|
||||
ItemUnion { cx: std::cell::RefCell::new(cx), it, s }.render_into(w).unwrap();
|
||||
ItemUnion { cx: RefCell::new(cx), it, s }.render_into(w).unwrap();
|
||||
}
|
||||
|
||||
fn print_tuple_struct_fields<'a, 'cx: 'a>(
|
||||
|
@ -54,13 +54,13 @@ pub(crate) fn document_type_layout<'a, 'cx: 'a>(
|
||||
} else if let Primitive::Int(i, _) = tag.primitive() {
|
||||
i.size().bytes()
|
||||
} else {
|
||||
span_bug!(cx.tcx().def_span(ty_def_id), "tag is neither niche nor int")
|
||||
span_bug!(tcx.def_span(ty_def_id), "tag is neither niche nor int")
|
||||
};
|
||||
variants
|
||||
.iter_enumerated()
|
||||
.map(|(variant_idx, variant_layout)| {
|
||||
let Adt(adt, _) = type_layout.ty.kind() else {
|
||||
span_bug!(cx.tcx().def_span(ty_def_id), "not an adt")
|
||||
span_bug!(tcx.def_span(ty_def_id), "not an adt")
|
||||
};
|
||||
let name = adt.variant(variant_idx).name;
|
||||
let is_unsized = variant_layout.abi.is_unsized();
|
||||
|
@ -1,8 +1,8 @@
|
||||
<pre class="rust item-decl"><code>
|
||||
{{ self.render_attributes_in_pre() | safe }}
|
||||
{{ self::item_template_render_attributes_in_pre(self.borrow()) | safe }}
|
||||
{{ self.render_union() | safe }}
|
||||
</code></pre>
|
||||
{{ self.document() | safe }}
|
||||
{{ self::item_template_document(self.borrow()) | safe }}
|
||||
{% if self.fields_iter().peek().is_some() %}
|
||||
<h2 id="fields" class="fields small-section-header">
|
||||
Fields<a href="#fields" class="anchor">§</a>
|
||||
@ -19,5 +19,5 @@
|
||||
{{ self.document_field(field) | safe }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{{ self.render_assoc_items() | safe }}
|
||||
{{ self.document_type_layout() | safe }}
|
||||
{{ self::item_template_render_assoc_items(self.borrow()) | safe }}
|
||||
{{ self::item_template_document_type_layout(self.borrow()) | safe }}
|
||||
|
@ -712,13 +712,23 @@ fn run_renderer<'tcx, T: formats::FormatRenderer<'tcx>>(
|
||||
}
|
||||
|
||||
fn main_args(at_args: &[String]) -> MainResult {
|
||||
// Throw away the first argument, the name of the binary.
|
||||
// In case of at_args being empty, as might be the case by
|
||||
// passing empty argument array to execve under some platforms,
|
||||
// just use an empty slice.
|
||||
//
|
||||
// This situation was possible before due to arg_expand_all being
|
||||
// called before removing the argument, enabling a crash by calling
|
||||
// the compiler with @empty_file as argv[0] and no more arguments.
|
||||
let at_args = at_args.get(1..).unwrap_or_default();
|
||||
|
||||
let args = rustc_driver::args::arg_expand_all(at_args);
|
||||
|
||||
let mut options = getopts::Options::new();
|
||||
for option in opts() {
|
||||
(option.apply)(&mut options);
|
||||
}
|
||||
let matches = match options.parse(&args[1..]) {
|
||||
let matches = match options.parse(&args) {
|
||||
Ok(m) => m,
|
||||
Err(err) => {
|
||||
early_error(ErrorOutputType::default(), err.to_string());
|
||||
|
@ -723,7 +723,7 @@ fn resolve_associated_trait_item<'a>(
|
||||
.iter()
|
||||
.flat_map(|&(impl_, trait_)| {
|
||||
filter_assoc_items_by_name_and_namespace(
|
||||
cx.tcx,
|
||||
tcx,
|
||||
trait_,
|
||||
Ident::with_dummy_span(item_name),
|
||||
ns,
|
||||
@ -1743,7 +1743,7 @@ fn resolution_failure(
|
||||
if let Ok(v_res) = collector.resolve(start, ns, item_id, module_id) {
|
||||
debug!("found partial_res={:?}", v_res);
|
||||
if !v_res.is_empty() {
|
||||
*partial_res = Some(full_res(collector.cx.tcx, v_res[0]));
|
||||
*partial_res = Some(full_res(tcx, v_res[0]));
|
||||
*unresolved = end.into();
|
||||
break 'outer;
|
||||
}
|
||||
|
@ -19,9 +19,10 @@ pub(crate) const COLLECT_TRAIT_IMPLS: Pass = Pass {
|
||||
};
|
||||
|
||||
pub(crate) fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) -> Crate {
|
||||
let tcx = cx.tcx;
|
||||
// We need to check if there are errors before running this pass because it would crash when
|
||||
// we try to get auto and blanket implementations.
|
||||
if cx.tcx.sess.diagnostic().has_errors_or_lint_errors().is_some() {
|
||||
if tcx.sess.diagnostic().has_errors_or_lint_errors().is_some() {
|
||||
return krate;
|
||||
}
|
||||
|
||||
@ -32,8 +33,7 @@ pub(crate) fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) ->
|
||||
});
|
||||
|
||||
let local_crate = ExternalCrate { crate_num: LOCAL_CRATE };
|
||||
let prims: FxHashSet<PrimitiveType> =
|
||||
local_crate.primitives(cx.tcx).iter().map(|p| p.1).collect();
|
||||
let prims: FxHashSet<PrimitiveType> = local_crate.primitives(tcx).iter().map(|p| p.1).collect();
|
||||
|
||||
let crate_items = {
|
||||
let mut coll = ItemCollector::new();
|
||||
@ -46,9 +46,9 @@ pub(crate) fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) ->
|
||||
|
||||
// External trait impls.
|
||||
{
|
||||
let _prof_timer = cx.tcx.sess.prof.generic_activity("build_extern_trait_impls");
|
||||
for &cnum in cx.tcx.crates(()) {
|
||||
for &impl_def_id in cx.tcx.trait_impls_in_crate(cnum) {
|
||||
let _prof_timer = tcx.sess.prof.generic_activity("build_extern_trait_impls");
|
||||
for &cnum in tcx.crates(()) {
|
||||
for &impl_def_id in tcx.trait_impls_in_crate(cnum) {
|
||||
inline::build_impl(cx, impl_def_id, None, &mut new_items_external);
|
||||
}
|
||||
}
|
||||
@ -56,14 +56,13 @@ pub(crate) fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) ->
|
||||
|
||||
// Local trait impls.
|
||||
{
|
||||
let _prof_timer = cx.tcx.sess.prof.generic_activity("build_local_trait_impls");
|
||||
let _prof_timer = tcx.sess.prof.generic_activity("build_local_trait_impls");
|
||||
let mut attr_buf = Vec::new();
|
||||
for &impl_def_id in cx.tcx.trait_impls_in_crate(LOCAL_CRATE) {
|
||||
let mut parent = Some(cx.tcx.parent(impl_def_id));
|
||||
for &impl_def_id in tcx.trait_impls_in_crate(LOCAL_CRATE) {
|
||||
let mut parent = Some(tcx.parent(impl_def_id));
|
||||
while let Some(did) = parent {
|
||||
attr_buf.extend(
|
||||
cx.tcx
|
||||
.get_attrs(did, sym::doc)
|
||||
tcx.get_attrs(did, sym::doc)
|
||||
.filter(|attr| {
|
||||
if let Some([attr]) = attr.meta_item_list().as_deref() {
|
||||
attr.has_name(sym::cfg)
|
||||
@ -73,25 +72,24 @@ pub(crate) fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) ->
|
||||
})
|
||||
.cloned(),
|
||||
);
|
||||
parent = cx.tcx.opt_parent(did);
|
||||
parent = tcx.opt_parent(did);
|
||||
}
|
||||
inline::build_impl(cx, impl_def_id, Some((&attr_buf, None)), &mut new_items_local);
|
||||
attr_buf.clear();
|
||||
}
|
||||
}
|
||||
|
||||
cx.tcx.sess.prof.generic_activity("build_primitive_trait_impls").run(|| {
|
||||
for def_id in PrimitiveType::all_impls(cx.tcx) {
|
||||
tcx.sess.prof.generic_activity("build_primitive_trait_impls").run(|| {
|
||||
for def_id in PrimitiveType::all_impls(tcx) {
|
||||
// Try to inline primitive impls from other crates.
|
||||
if !def_id.is_local() {
|
||||
inline::build_impl(cx, def_id, None, &mut new_items_external);
|
||||
}
|
||||
}
|
||||
for (prim, did) in PrimitiveType::primitive_locations(cx.tcx) {
|
||||
for (prim, did) in PrimitiveType::primitive_locations(tcx) {
|
||||
// Do not calculate blanket impl list for docs that are not going to be rendered.
|
||||
// While the `impl` blocks themselves are only in `libcore`, the module with `doc`
|
||||
// attached is directly included in `libstd` as well.
|
||||
let tcx = cx.tcx;
|
||||
if did.is_local() {
|
||||
for def_id in prim.impls(tcx).filter(|def_id| {
|
||||
// Avoid including impl blocks with filled-in generics.
|
||||
@ -157,7 +155,7 @@ pub(crate) fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) ->
|
||||
// scan through included items ahead of time to splice in Deref targets to the "valid" sets
|
||||
for it in new_items_external.iter().chain(new_items_local.iter()) {
|
||||
if let ImplItem(box Impl { ref for_, ref trait_, ref items, .. }) = *it.kind &&
|
||||
trait_.as_ref().map(|t| t.def_id()) == cx.tcx.lang_items().deref_trait() &&
|
||||
trait_.as_ref().map(|t| t.def_id()) == tcx.lang_items().deref_trait() &&
|
||||
cleaner.keep_impl(for_, true)
|
||||
{
|
||||
let target = items
|
||||
@ -199,7 +197,7 @@ pub(crate) fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) ->
|
||||
if let ImplItem(box Impl { ref for_, ref trait_, ref kind, .. }) = *it.kind {
|
||||
cleaner.keep_impl(
|
||||
for_,
|
||||
trait_.as_ref().map(|t| t.def_id()) == cx.tcx.lang_items().deref_trait(),
|
||||
trait_.as_ref().map(|t| t.def_id()) == tcx.lang_items().deref_trait(),
|
||||
) || trait_.as_ref().map_or(false, |t| cleaner.keep_impl_with_def_id(t.def_id().into()))
|
||||
|| kind.is_blanket()
|
||||
} else {
|
||||
|
@ -56,7 +56,7 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item) {
|
||||
)
|
||||
.unwrap_or_else(|| item.attr_span(tcx));
|
||||
|
||||
cx.tcx.struct_span_lint_hir(crate::lint::UNESCAPED_BACKTICKS, hir_id, span, "unescaped backtick", |lint| {
|
||||
tcx.struct_span_lint_hir(crate::lint::UNESCAPED_BACKTICKS, hir_id, span, "unescaped backtick", |lint| {
|
||||
let mut help_emitted = false;
|
||||
|
||||
match element.prev_code_guess {
|
||||
|
@ -280,9 +280,8 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
||||
return false;
|
||||
};
|
||||
|
||||
let is_private =
|
||||
!self.cx.cache.effective_visibilities.is_directly_public(self.cx.tcx, ori_res_did);
|
||||
let is_hidden = inherits_doc_hidden(self.cx.tcx, res_did, None);
|
||||
let is_private = !self.cx.cache.effective_visibilities.is_directly_public(tcx, ori_res_did);
|
||||
let is_hidden = inherits_doc_hidden(tcx, res_did, None);
|
||||
|
||||
// Only inline if requested or if the item would otherwise be stripped.
|
||||
if (!please_inline && !is_private && !is_hidden) || is_no_inline {
|
||||
@ -290,7 +289,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
||||
}
|
||||
|
||||
if !please_inline &&
|
||||
let Some(item_def_id) = reexport_chain(self.cx.tcx, def_id, res_did).iter()
|
||||
let Some(item_def_id) = reexport_chain(tcx, def_id, res_did).iter()
|
||||
.flat_map(|reexport| reexport.id()).map(|id| id.expect_local())
|
||||
.chain(iter::once(res_did)).nth(1) &&
|
||||
item_def_id != def_id &&
|
||||
@ -298,8 +297,8 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
||||
.cx
|
||||
.cache
|
||||
.effective_visibilities
|
||||
.is_directly_public(self.cx.tcx, item_def_id.to_def_id()) &&
|
||||
!inherits_doc_hidden(self.cx.tcx, item_def_id, None)
|
||||
.is_directly_public(tcx, item_def_id.to_def_id()) &&
|
||||
!inherits_doc_hidden(tcx, item_def_id, None)
|
||||
{
|
||||
// The imported item is public and not `doc(hidden)` so no need to inline it.
|
||||
return false;
|
||||
@ -329,7 +328,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
||||
Node::Item(&hir::Item { kind: hir::ItemKind::Mod(ref m), .. }) if glob => {
|
||||
let prev = mem::replace(&mut self.inlining, true);
|
||||
for &i in m.item_ids {
|
||||
let i = self.cx.tcx.hir().item(i);
|
||||
let i = tcx.hir().item(i);
|
||||
self.visit_item_inner(i, None, Some(def_id));
|
||||
}
|
||||
self.inlining = prev;
|
||||
|
2
tests/ui/parser/issues/issue-111148.rs
Normal file
2
tests/ui/parser/issues/issue-111148.rs
Normal file
@ -0,0 +1,2 @@
|
||||
fn a<<i<Y<w<>#
|
||||
//~^ ERROR expected one of `#`, `>`, `const`, identifier, or lifetime, found `<`
|
8
tests/ui/parser/issues/issue-111148.stderr
Normal file
8
tests/ui/parser/issues/issue-111148.stderr
Normal file
@ -0,0 +1,8 @@
|
||||
error: expected one of `#`, `>`, `const`, identifier, or lifetime, found `<`
|
||||
--> $DIR/issue-111148.rs:1:6
|
||||
|
|
||||
LL | fn a<<i<Y<w<>#
|
||||
| ^ expected one of `#`, `>`, `const`, identifier, or lifetime
|
||||
|
||||
error: aborting due to previous error
|
||||
|
Loading…
Reference in New Issue
Block a user