Auto merge of #103962 - matthiaskrgr:rollup-9av8i6k, r=matthiaskrgr

Rollup of 7 pull requests

Successful merges:

 - #103680 (CStr: add some doc links)
 - #103780 (Fix late-bound lifetime closure ICEs in HIR typeck and MIR borrowck)
 - #103845 (Add track_caller to some Lock methods)
 - #103935 (Remove rustdoc clean::Visibility type)
 - #103941 (Fixed typos)
 - #103950 (Fix ICE when negative impl is collected during eager mono)
 - #103953 (Remove unused argument from `throw_unresolved_import_error`)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2022-11-04 13:47:37 +00:00
commit 6330c27ae2
22 changed files with 330 additions and 209 deletions

View File

@ -2314,7 +2314,7 @@ impl<'tcx> ClosureRegionRequirementsExt<'tcx> for ClosureRegionRequirements<'tcx
tcx,
closure_substs,
self.num_external_vids,
tcx.typeck_root_def_id(closure_def_id),
closure_def_id.expect_local(),
);
debug!("apply_requirements: closure_mapping={:?}", closure_mapping);

View File

@ -22,7 +22,9 @@ use rustc_hir::{BodyOwnerKind, HirId};
use rustc_index::vec::{Idx, IndexVec};
use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin};
use rustc_middle::ty::fold::TypeFoldable;
use rustc_middle::ty::{self, InlineConstSubsts, InlineConstSubstsParts, RegionVid, Ty, TyCtxt};
use rustc_middle::ty::{
self, DefIdTree, InlineConstSubsts, InlineConstSubstsParts, RegionVid, Ty, TyCtxt,
};
use rustc_middle::ty::{InternalSubsts, SubstsRef};
use std::iter;
@ -241,7 +243,7 @@ impl<'tcx> UniversalRegions<'tcx> {
tcx: TyCtxt<'tcx>,
closure_substs: SubstsRef<'tcx>,
expected_num_vars: usize,
typeck_root_def_id: DefId,
closure_def_id: LocalDefId,
) -> IndexVec<RegionVid, ty::Region<'tcx>> {
let mut region_mapping = IndexVec::with_capacity(expected_num_vars);
region_mapping.push(tcx.lifetimes.re_static);
@ -249,7 +251,7 @@ impl<'tcx> UniversalRegions<'tcx> {
region_mapping.push(fr);
});
for_each_late_bound_region_defined_on(tcx, typeck_root_def_id, |r| {
for_each_late_bound_region_in_recursive_scope(tcx, tcx.local_parent(closure_def_id), |r| {
region_mapping.push(r);
});
@ -339,9 +341,8 @@ impl<'tcx> UniversalRegions<'tcx> {
// tests, and the resulting print-outs include def-ids
// and other things that are not stable across tests!
// So we just include the region-vid. Annoying.
let typeck_root_def_id = tcx.typeck_root_def_id(def_id);
for_each_late_bound_region_defined_on(tcx, typeck_root_def_id, |r| {
err.note(&format!("late-bound region is {:?}", self.to_region_vid(r),));
for_each_late_bound_region_in_recursive_scope(tcx, def_id.expect_local(), |r| {
err.note(&format!("late-bound region is {:?}", self.to_region_vid(r)));
});
}
DefiningTy::Generator(def_id, substs, _) => {
@ -354,9 +355,8 @@ impl<'tcx> UniversalRegions<'tcx> {
// FIXME: As above, we'd like to print out the region
// `r` but doing so is not stable across architectures
// and so forth.
let typeck_root_def_id = tcx.typeck_root_def_id(def_id);
for_each_late_bound_region_defined_on(tcx, typeck_root_def_id, |r| {
err.note(&format!("late-bound region is {:?}", self.to_region_vid(r),));
for_each_late_bound_region_in_recursive_scope(tcx, def_id.expect_local(), |r| {
err.note(&format!("late-bound region is {:?}", self.to_region_vid(r)));
});
}
DefiningTy::FnDef(def_id, substs) => {
@ -421,13 +421,24 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
first_extern_index
} else {
// If this is a closure, generator, or inline-const, then the late-bound regions from the enclosing
// function are actually external regions to us. For example, here, 'a is not local
// function/closures are actually external regions to us. For example, here, 'a is not local
// to the closure c (although it is local to the fn foo):
// fn foo<'a>() {
// let c = || { let x: &'a u32 = ...; }
// }
self.infcx
.replace_late_bound_regions_with_nll_infer_vars(self.mir_def.did, &mut indices);
for_each_late_bound_region_in_recursive_scope(
self.infcx.tcx,
self.infcx.tcx.local_parent(self.mir_def.did),
|r| {
debug!(?r);
if !indices.indices.contains_key(&r) {
let region_vid = self.infcx.next_nll_region_var(FR);
debug!(?region_vid);
indices.insert_late_bound_region(r, region_vid.to_region_vid());
}
},
);
// Any regions created during the execution of `defining_ty` or during the above
// late-bound region replacement are all considered 'extern' regions
self.infcx.num_region_vars()
@ -444,12 +455,16 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
bound_inputs_and_output,
&mut indices,
);
// Converse of above, if this is a function then the late-bound regions declared on its
// signature are local to the fn.
if self.mir_def.did.to_def_id() == typeck_root_def_id {
self.infcx
.replace_late_bound_regions_with_nll_infer_vars(self.mir_def.did, &mut indices);
}
// Converse of above, if this is a function/closure then the late-bound regions declared on its
// signature are local.
for_each_late_bound_region_in_item(self.infcx.tcx, self.mir_def.did, |r| {
debug!(?r);
if !indices.indices.contains_key(&r) {
let region_vid = self.infcx.next_nll_region_var(FR);
debug!(?region_vid);
indices.insert_late_bound_region(r, region_vid.to_region_vid());
}
});
let (unnormalized_output_ty, mut unnormalized_input_tys) =
inputs_and_output.split_last().unwrap();
@ -692,7 +707,13 @@ trait InferCtxtExt<'tcx> {
where
T: TypeFoldable<'tcx>;
fn replace_late_bound_regions_with_nll_infer_vars(
fn replace_late_bound_regions_with_nll_infer_vars_in_recursive_scope(
&self,
mir_def_id: LocalDefId,
indices: &mut UniversalRegionIndices<'tcx>,
);
fn replace_late_bound_regions_with_nll_infer_vars_in_item(
&self,
mir_def_id: LocalDefId,
indices: &mut UniversalRegionIndices<'tcx>,
@ -746,13 +767,28 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
/// set of late-bound regions and checks for any that we have not yet seen, adding them to the
/// inputs vector.
#[instrument(skip(self, indices))]
fn replace_late_bound_regions_with_nll_infer_vars(
fn replace_late_bound_regions_with_nll_infer_vars_in_recursive_scope(
&self,
mir_def_id: LocalDefId,
indices: &mut UniversalRegionIndices<'tcx>,
) {
let typeck_root_def_id = self.tcx.typeck_root_def_id(mir_def_id.to_def_id());
for_each_late_bound_region_defined_on(self.tcx, typeck_root_def_id, |r| {
for_each_late_bound_region_in_recursive_scope(self.tcx, mir_def_id, |r| {
debug!(?r);
if !indices.indices.contains_key(&r) {
let region_vid = self.next_nll_region_var(FR);
debug!(?region_vid);
indices.insert_late_bound_region(r, region_vid.to_region_vid());
}
});
}
#[instrument(skip(self, indices))]
fn replace_late_bound_regions_with_nll_infer_vars_in_item(
&self,
mir_def_id: LocalDefId,
indices: &mut UniversalRegionIndices<'tcx>,
) {
for_each_late_bound_region_in_item(self.tcx, mir_def_id, |r| {
debug!(?r);
if !indices.indices.contains_key(&r) {
let region_vid = self.next_nll_region_var(FR);
@ -803,21 +839,44 @@ impl<'tcx> UniversalRegionIndices<'tcx> {
}
}
/// Iterates over the late-bound regions defined on fn_def_id and
/// invokes `f` with the liberated form of each one.
fn for_each_late_bound_region_defined_on<'tcx>(
/// Iterates over the late-bound regions defined on `mir_def_id` and all of its
/// parents, up to the typeck root, and invokes `f` with the liberated form
/// of each one.
fn for_each_late_bound_region_in_recursive_scope<'tcx>(
tcx: TyCtxt<'tcx>,
fn_def_id: DefId,
mut mir_def_id: LocalDefId,
mut f: impl FnMut(ty::Region<'tcx>),
) {
if let Some(late_bounds) = tcx.is_late_bound_map(fn_def_id.expect_local()) {
for &region_def_id in late_bounds.iter() {
let name = tcx.item_name(region_def_id.to_def_id());
let liberated_region = tcx.mk_region(ty::ReFree(ty::FreeRegion {
scope: fn_def_id,
bound_region: ty::BoundRegionKind::BrNamed(region_def_id.to_def_id(), name),
}));
f(liberated_region);
let typeck_root_def_id = tcx.typeck_root_def_id(mir_def_id.to_def_id());
// Walk up the tree, collecting late-bound regions until we hit the typeck root
loop {
for_each_late_bound_region_in_item(tcx, mir_def_id, &mut f);
if mir_def_id.to_def_id() == typeck_root_def_id {
break;
} else {
mir_def_id = tcx.local_parent(mir_def_id);
}
}
}
/// Iterates over the late-bound regions defined on `mir_def_id` and all of its
/// parents, up to the typeck root, and invokes `f` with the liberated form
/// of each one.
fn for_each_late_bound_region_in_item<'tcx>(
tcx: TyCtxt<'tcx>,
mir_def_id: LocalDefId,
mut f: impl FnMut(ty::Region<'tcx>),
) {
if !tcx.def_kind(mir_def_id).is_fn_like() {
return;
}
for bound_var in tcx.late_bound_vars(tcx.hir().local_def_id_to_hir_id(mir_def_id)) {
let ty::BoundVariableKind::Region(bound_region) = bound_var else { continue; };
let liberated_region = tcx
.mk_region(ty::ReFree(ty::FreeRegion { scope: mir_def_id.to_def_id(), bound_region }));
f(liberated_region);
}
}

View File

@ -410,6 +410,7 @@ impl<T> Lock<T> {
#[cfg(parallel_compiler)]
#[inline(always)]
#[track_caller]
pub fn lock(&self) -> LockGuard<'_, T> {
if ERROR_CHECKING {
self.0.try_lock().expect("lock was already held")
@ -420,21 +421,25 @@ impl<T> Lock<T> {
#[cfg(not(parallel_compiler))]
#[inline(always)]
#[track_caller]
pub fn lock(&self) -> LockGuard<'_, T> {
self.0.borrow_mut()
}
#[inline(always)]
#[track_caller]
pub fn with_lock<F: FnOnce(&mut T) -> R, R>(&self, f: F) -> R {
f(&mut *self.lock())
}
#[inline(always)]
#[track_caller]
pub fn borrow(&self) -> LockGuard<'_, T> {
self.lock()
}
#[inline(always)]
#[track_caller]
pub fn borrow_mut(&self) -> LockGuard<'_, T> {
self.lock()
}
@ -476,6 +481,7 @@ impl<T> RwLock<T> {
#[cfg(not(parallel_compiler))]
#[inline(always)]
#[track_caller]
pub fn read(&self) -> ReadGuard<'_, T> {
self.0.borrow()
}
@ -491,6 +497,7 @@ impl<T> RwLock<T> {
}
#[inline(always)]
#[track_caller]
pub fn with_read_lock<F: FnOnce(&T) -> R, R>(&self, f: F) -> R {
f(&*self.read())
}
@ -509,6 +516,7 @@ impl<T> RwLock<T> {
#[cfg(not(parallel_compiler))]
#[inline(always)]
#[track_caller]
pub fn write(&self) -> WriteGuard<'_, T> {
self.0.borrow_mut()
}
@ -524,16 +532,19 @@ impl<T> RwLock<T> {
}
#[inline(always)]
#[track_caller]
pub fn with_write_lock<F: FnOnce(&mut T) -> R, R>(&self, f: F) -> R {
f(&mut *self.write())
}
#[inline(always)]
#[track_caller]
pub fn borrow(&self) -> ReadGuard<'_, T> {
self.read()
}
#[inline(always)]
#[track_caller]
pub fn borrow_mut(&self) -> WriteGuard<'_, T> {
self.write()
}

View File

@ -1377,11 +1377,12 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
} else if let Some(body_id) = outermost_body {
let fn_id = self.tcx.hir().body_owner(body_id);
match self.tcx.hir().get(fn_id) {
Node::Item(&hir::Item { kind: hir::ItemKind::Fn(..), .. })
| Node::TraitItem(&hir::TraitItem {
Node::Item(hir::Item { kind: hir::ItemKind::Fn(..), .. })
| Node::TraitItem(hir::TraitItem {
kind: hir::TraitItemKind::Fn(..), ..
})
| Node::ImplItem(&hir::ImplItem { kind: hir::ImplItemKind::Fn(..), .. }) => {
| Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Fn(..), .. })
| Node::Expr(hir::Expr { kind: hir::ExprKind::Closure(..), .. }) => {
let scope = self.tcx.hir().local_def_id(fn_id);
def = Region::Free(scope.to_def_id(), def.id().unwrap());
}

View File

@ -1336,6 +1336,10 @@ fn create_mono_items_for_default_impls<'tcx>(
) {
match item.kind {
hir::ItemKind::Impl(ref impl_) => {
if matches!(impl_.polarity, hir::ImplPolarity::Negative(_)) {
return;
}
for param in impl_.generics.params {
match param.kind {
hir::GenericParamKind::Lifetime { .. } => {}

View File

@ -473,7 +473,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
{
// In the case of a new import line, throw a diagnostic message
// for the previous line.
self.throw_unresolved_import_error(errors, None);
self.throw_unresolved_import_error(errors);
errors = vec![];
}
if seen_spans.insert(err.span) {
@ -505,29 +505,21 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
}
if !errors.is_empty() {
self.throw_unresolved_import_error(errors, None);
self.throw_unresolved_import_error(errors);
}
}
fn throw_unresolved_import_error(
&self,
errors: Vec<(String, UnresolvedImportError)>,
span: Option<MultiSpan>,
) {
fn throw_unresolved_import_error(&self, errors: Vec<(String, UnresolvedImportError)>) {
if errors.is_empty() {
return;
}
/// Upper limit on the number of `span_label` messages.
const MAX_LABEL_COUNT: usize = 10;
let (span, msg) = if errors.is_empty() {
(span.unwrap(), "unresolved import".to_string())
} else {
let span = MultiSpan::from_spans(errors.iter().map(|(_, err)| err.span).collect());
let paths = errors.iter().map(|(path, _)| format!("`{}`", path)).collect::<Vec<_>>();
let msg = format!("unresolved import{} {}", pluralize!(paths.len()), paths.join(", "),);
(span, msg)
};
let span = MultiSpan::from_spans(errors.iter().map(|(_, err)| err.span).collect());
let paths = errors.iter().map(|(path, _)| format!("`{}`", path)).collect::<Vec<_>>();
let msg = format!("unresolved import{} {}", pluralize!(paths.len()), paths.join(", "),);
let mut diag = struct_span_err!(self.r.session, span, E0432, "{}", &msg);

View File

@ -2588,7 +2588,7 @@ impl<T: Clone, A: Allocator> ExtendFromWithinSpec for Vec<T, A> {
let (this, spare, len) = unsafe { self.split_at_spare_mut_with_len() };
// SAFETY:
// - caller guaratees that src is a valid index
// - caller guarantees that src is a valid index
let to_clone = unsafe { this.get_unchecked(src) };
iter::zip(to_clone, spare)
@ -2607,7 +2607,7 @@ impl<T: Copy, A: Allocator> ExtendFromWithinSpec for Vec<T, A> {
let (init, spare) = self.split_at_spare_mut();
// SAFETY:
// - caller guaratees that `src` is a valid index
// - caller guarantees that `src` is a valid index
let source = unsafe { init.get_unchecked(src) };
// SAFETY:

View File

@ -13,9 +13,9 @@ use crate::str;
/// array of bytes. It can be constructed safely from a <code>&[[u8]]</code>
/// slice, or unsafely from a raw `*const c_char`. It can then be
/// converted to a Rust <code>&[str]</code> by performing UTF-8 validation, or
/// into an owned `CString`.
/// into an owned [`CString`].
///
/// `&CStr` is to `CString` as <code>&[str]</code> is to `String`: the former
/// `&CStr` is to [`CString`] as <code>&[str]</code> is to [`String`]: the former
/// in each pair are borrowed references; the latter are owned
/// strings.
///
@ -24,6 +24,9 @@ use crate::str;
/// functions may leverage the unsafe [`CStr::from_ptr`] constructor to provide
/// a safe interface to other consumers.
///
/// [`CString`]: ../../std/ffi/struct.CString.html
/// [`String`]: ../../std/string/struct.String.html
///
/// # Examples
///
/// Inspecting a foreign C string:

View File

@ -19,8 +19,7 @@ use rustc_span::symbol::{kw, sym, Symbol};
use crate::clean::{
self, clean_fn_decl_from_did_and_sig, clean_generics, clean_impl_item, clean_middle_assoc_item,
clean_middle_field, clean_middle_ty, clean_trait_ref_with_bindings, clean_ty,
clean_ty_generics, clean_variant_def, clean_visibility, utils, Attributes, AttributesExt,
ImplKind, ItemId, Type,
clean_ty_generics, clean_variant_def, utils, Attributes, AttributesExt, ImplKind, ItemId, Type,
};
use crate::core::DocContext;
use crate::formats::item_type::ItemType;
@ -654,7 +653,7 @@ fn build_macro(
match CStore::from_tcx(cx.tcx).load_macro_untracked(def_id, cx.sess()) {
LoadedMacro::MacroDef(item_def, _) => {
if let ast::ItemKind::MacroDef(ref def) = item_def.kind {
let vis = clean_visibility(cx.tcx.visibility(import_def_id.unwrap_or(def_id)));
let vis = cx.tcx.visibility(import_def_id.unwrap_or(def_id));
clean::MacroItem(clean::Macro {
source: utils::display_macro_source(cx, name, def, def_id, vis),
})

View File

@ -1799,13 +1799,6 @@ pub(crate) fn clean_field_with_def_id(
Item::from_def_id_and_parts(def_id, Some(name), StructFieldItem(ty), cx)
}
pub(crate) fn clean_visibility(vis: ty::Visibility<DefId>) -> Visibility {
match vis {
ty::Visibility::Public => Visibility::Public,
ty::Visibility::Restricted(module) => Visibility::Restricted(module),
}
}
pub(crate) fn clean_variant_def<'tcx>(variant: &ty::VariantDef, cx: &mut DocContext<'tcx>) -> Item {
let kind = match variant.ctor_kind {
CtorKind::Const => Variant::CLike(match variant.discr {
@ -1962,7 +1955,7 @@ fn clean_maybe_renamed_item<'tcx>(
clean_fn_or_proc_macro(item, sig, generics, body_id, &mut name, cx)
}
ItemKind::Macro(ref macro_def, _) => {
let ty_vis = clean_visibility(cx.tcx.visibility(def_id));
let ty_vis = cx.tcx.visibility(def_id);
MacroItem(Macro {
source: display_macro_source(cx, name, macro_def, def_id, ty_vis),
})

View File

@ -24,7 +24,7 @@ use rustc_hir::{BodyId, Mutability};
use rustc_hir_analysis::check::intrinsic::intrinsic_operation_unsafety;
use rustc_index::vec::IndexVec;
use rustc_middle::ty::fast_reject::SimplifiedType;
use rustc_middle::ty::{self, DefIdTree, TyCtxt};
use rustc_middle::ty::{self, DefIdTree, TyCtxt, Visibility};
use rustc_session::Session;
use rustc_span::hygiene::MacroKind;
use rustc_span::source_map::DUMMY_SP;
@ -34,7 +34,6 @@ use rustc_target::abi::VariantIdx;
use rustc_target::spec::abi::Abi;
use crate::clean::cfg::Cfg;
use crate::clean::clean_visibility;
use crate::clean::external_path;
use crate::clean::inline::{self, print_inlined_const};
use crate::clean::utils::{is_literal_expr, print_const_expr, print_evaluated_const};
@ -51,7 +50,6 @@ pub(crate) use self::Type::{
Array, BareFunction, BorrowedRef, DynTrait, Generic, ImplTrait, Infer, Primitive, QPath,
RawPointer, Slice, Tuple,
};
pub(crate) use self::Visibility::{Inherited, Public};
#[cfg(test)]
mod tests;
@ -703,26 +701,28 @@ impl Item {
Some(header)
}
pub(crate) fn visibility(&self, tcx: TyCtxt<'_>) -> Visibility {
/// Returns the visibility of the current item. If the visibility is "inherited", then `None`
/// is returned.
pub(crate) fn visibility(&self, tcx: TyCtxt<'_>) -> Option<Visibility<DefId>> {
let def_id = match self.item_id {
// Anything but DefId *shouldn't* matter, but return a reasonable value anyway.
ItemId::Auto { .. } | ItemId::Blanket { .. } => return Visibility::Inherited,
ItemId::Auto { .. } | ItemId::Blanket { .. } => return None,
// Primitives and Keywords are written in the source code as private modules.
// The modules need to be private so that nobody actually uses them, but the
// keywords and primitives that they are documenting are public.
ItemId::Primitive(..) => return Visibility::Public,
ItemId::Primitive(..) => return Some(Visibility::Public),
ItemId::DefId(def_id) => def_id,
};
match *self.kind {
// Explication on `ItemId::Primitive` just above.
ItemKind::KeywordItem | ItemKind::PrimitiveItem(_) => return Visibility::Public,
ItemKind::KeywordItem | ItemKind::PrimitiveItem(_) => return Some(Visibility::Public),
// Variant fields inherit their enum's visibility.
StructFieldItem(..) if is_field_vis_inherited(tcx, def_id) => {
return Visibility::Inherited;
return None;
}
// Variants always inherit visibility
VariantItem(..) => return Visibility::Inherited,
VariantItem(..) => return None,
// Trait items inherit the trait's visibility
AssocConstItem(..) | TyAssocConstItem(..) | AssocTypeItem(..) | TyAssocTypeItem(..)
| TyMethodItem(..) | MethodItem(..) => {
@ -736,7 +736,7 @@ impl Item {
}
};
if is_trait_item {
return Visibility::Inherited;
return None;
}
}
_ => {}
@ -745,7 +745,7 @@ impl Item {
Some(inlined) => inlined,
None => def_id,
};
clean_visibility(tcx.visibility(def_id))
Some(tcx.visibility(def_id))
}
}
@ -2075,24 +2075,6 @@ impl From<hir::PrimTy> for PrimitiveType {
}
}
#[derive(Copy, Clone, Debug)]
pub(crate) enum Visibility {
/// `pub`
Public,
/// Visibility inherited from parent.
///
/// For example, this is the visibility of private items and of enum variants.
Inherited,
/// `pub(crate)`, `pub(super)`, or `pub(in path::to::somewhere)`
Restricted(DefId),
}
impl Visibility {
pub(crate) fn is_public(&self) -> bool {
matches!(self, Visibility::Public)
}
}
#[derive(Clone, Debug)]
pub(crate) struct Struct {
pub(crate) struct_type: CtorKind,

View File

@ -4,9 +4,10 @@ use crate::clean::render_macro_matchers::render_macro_matcher;
use crate::clean::{
clean_doc_module, clean_middle_const, clean_middle_region, clean_middle_ty, inline, Crate,
ExternalCrate, Generic, GenericArg, GenericArgs, ImportSource, Item, ItemKind, Lifetime, Path,
PathSegment, Primitive, PrimitiveType, Type, TypeBinding, Visibility,
PathSegment, Primitive, PrimitiveType, Type, TypeBinding,
};
use crate::core::DocContext;
use crate::html::format::visibility_to_src_with_space;
use rustc_ast as ast;
use rustc_ast::tokenstream::TokenTree;
@ -583,7 +584,7 @@ pub(super) fn display_macro_source(
name: Symbol,
def: &ast::MacroDef,
def_id: DefId,
vis: Visibility,
vis: ty::Visibility<DefId>,
) -> String {
let tts: Vec<_> = def.body.inner_tokens().into_trees().collect();
// Extract the spans of all matchers. They represent the "interface" of the macro.
@ -595,14 +596,14 @@ pub(super) fn display_macro_source(
if matchers.len() <= 1 {
format!(
"{}macro {}{} {{\n ...\n}}",
vis.to_src_with_space(cx.tcx, def_id),
visibility_to_src_with_space(Some(vis), cx.tcx, def_id),
name,
matchers.map(|matcher| render_macro_matcher(cx.tcx, matcher)).collect::<String>(),
)
} else {
format!(
"{}macro {} {{\n{}}}",
vis.to_src_with_space(cx.tcx, def_id),
visibility_to_src_with_space(Some(vis), cx.tcx, def_id),
name,
render_macro_arms(cx.tcx, matchers, ","),
)

View File

@ -1420,87 +1420,84 @@ impl clean::FnDecl {
}
}
impl clean::Visibility {
pub(crate) fn print_with_space<'a, 'tcx: 'a>(
self,
item_did: ItemId,
cx: &'a Context<'tcx>,
) -> impl fmt::Display + 'a + Captures<'tcx> {
use std::fmt::Write as _;
pub(crate) fn visibility_print_with_space<'a, 'tcx: 'a>(
visibility: Option<ty::Visibility<DefId>>,
item_did: ItemId,
cx: &'a Context<'tcx>,
) -> impl fmt::Display + 'a + Captures<'tcx> {
use std::fmt::Write as _;
let to_print: Cow<'static, str> = match self {
clean::Public => "pub ".into(),
clean::Inherited => "".into(),
clean::Visibility::Restricted(vis_did) => {
// FIXME(camelid): This may not work correctly if `item_did` is a module.
// However, rustdoc currently never displays a module's
// visibility, so it shouldn't matter.
let parent_module = find_nearest_parent_module(cx.tcx(), item_did.expect_def_id());
let to_print: Cow<'static, str> = match visibility {
None => "".into(),
Some(ty::Visibility::Public) => "pub ".into(),
Some(ty::Visibility::Restricted(vis_did)) => {
// FIXME(camelid): This may not work correctly if `item_did` is a module.
// However, rustdoc currently never displays a module's
// visibility, so it shouldn't matter.
let parent_module = find_nearest_parent_module(cx.tcx(), item_did.expect_def_id());
if vis_did.is_crate_root() {
"pub(crate) ".into()
} else if parent_module == Some(vis_did) {
// `pub(in foo)` where `foo` is the parent module
// is the same as no visibility modifier
"".into()
} else if parent_module
.and_then(|parent| find_nearest_parent_module(cx.tcx(), parent))
== Some(vis_did)
{
"pub(super) ".into()
} else {
let path = cx.tcx().def_path(vis_did);
debug!("path={:?}", path);
// modified from `resolved_path()` to work with `DefPathData`
let last_name = path.data.last().unwrap().data.get_opt_name().unwrap();
let anchor = anchor(vis_did, last_name, cx).to_string();
if vis_did.is_crate_root() {
"pub(crate) ".into()
} else if parent_module == Some(vis_did) {
// `pub(in foo)` where `foo` is the parent module
// is the same as no visibility modifier
"".into()
} else if parent_module.and_then(|parent| find_nearest_parent_module(cx.tcx(), parent))
== Some(vis_did)
{
"pub(super) ".into()
} else {
let path = cx.tcx().def_path(vis_did);
debug!("path={:?}", path);
// modified from `resolved_path()` to work with `DefPathData`
let last_name = path.data.last().unwrap().data.get_opt_name().unwrap();
let anchor = anchor(vis_did, last_name, cx).to_string();
let mut s = "pub(in ".to_owned();
for seg in &path.data[..path.data.len() - 1] {
let _ = write!(s, "{}::", seg.data.get_opt_name().unwrap());
}
let _ = write!(s, "{}) ", anchor);
s.into()
let mut s = "pub(in ".to_owned();
for seg in &path.data[..path.data.len() - 1] {
let _ = write!(s, "{}::", seg.data.get_opt_name().unwrap());
}
let _ = write!(s, "{}) ", anchor);
s.into()
}
};
display_fn(move |f| write!(f, "{}", to_print))
}
}
};
display_fn(move |f| write!(f, "{}", to_print))
}
/// This function is the same as print_with_space, except that it renders no links.
/// It's used for macros' rendered source view, which is syntax highlighted and cannot have
/// any HTML in it.
pub(crate) fn to_src_with_space<'a, 'tcx: 'a>(
self,
tcx: TyCtxt<'tcx>,
item_did: DefId,
) -> impl fmt::Display + 'a + Captures<'tcx> {
let to_print = match self {
clean::Public => "pub ".to_owned(),
clean::Inherited => String::new(),
clean::Visibility::Restricted(vis_did) => {
// FIXME(camelid): This may not work correctly if `item_did` is a module.
// However, rustdoc currently never displays a module's
// visibility, so it shouldn't matter.
let parent_module = find_nearest_parent_module(tcx, item_did);
/// This function is the same as print_with_space, except that it renders no links.
/// It's used for macros' rendered source view, which is syntax highlighted and cannot have
/// any HTML in it.
pub(crate) fn visibility_to_src_with_space<'a, 'tcx: 'a>(
visibility: Option<ty::Visibility<DefId>>,
tcx: TyCtxt<'tcx>,
item_did: DefId,
) -> impl fmt::Display + 'a + Captures<'tcx> {
let to_print = match visibility {
None => String::new(),
Some(ty::Visibility::Public) => "pub ".to_owned(),
Some(ty::Visibility::Restricted(vis_did)) => {
// FIXME(camelid): This may not work correctly if `item_did` is a module.
// However, rustdoc currently never displays a module's
// visibility, so it shouldn't matter.
let parent_module = find_nearest_parent_module(tcx, item_did);
if vis_did.is_crate_root() {
"pub(crate) ".to_owned()
} else if parent_module == Some(vis_did) {
// `pub(in foo)` where `foo` is the parent module
// is the same as no visibility modifier
String::new()
} else if parent_module.and_then(|parent| find_nearest_parent_module(tcx, parent))
== Some(vis_did)
{
"pub(super) ".to_owned()
} else {
format!("pub(in {}) ", tcx.def_path_str(vis_did))
}
if vis_did.is_crate_root() {
"pub(crate) ".to_owned()
} else if parent_module == Some(vis_did) {
// `pub(in foo)` where `foo` is the parent module
// is the same as no visibility modifier
String::new()
} else if parent_module.and_then(|parent| find_nearest_parent_module(tcx, parent))
== Some(vis_did)
{
"pub(super) ".to_owned()
} else {
format!("pub(in {}) ", tcx.def_path_str(vis_did))
}
};
display_fn(move |f| f.write_str(&to_print))
}
}
};
display_fn(move |f| f.write_str(&to_print))
}
pub(crate) trait PrintWithSpace {

View File

@ -70,8 +70,8 @@ use crate::formats::{AssocItemRender, Impl, RenderMode};
use crate::html::escape::Escape;
use crate::html::format::{
href, join_with_double_colon, print_abi_with_space, print_constness_with_space,
print_default_space, print_generic_bounds, print_where_clause, Buffer, Ending, HrefError,
PrintWithSpace,
print_default_space, print_generic_bounds, print_where_clause, visibility_print_with_space,
Buffer, Ending, HrefError, PrintWithSpace,
};
use crate::html::highlight;
use crate::html::markdown::{
@ -752,7 +752,7 @@ fn assoc_const(
w,
"{extra}{vis}const <a{href} class=\"constant\">{name}</a>: {ty}",
extra = extra,
vis = it.visibility(tcx).print_with_space(it.item_id, cx),
vis = visibility_print_with_space(it.visibility(tcx), it.item_id, cx),
href = assoc_href_attr(it, link, cx),
name = it.name.as_ref().unwrap(),
ty = ty.print(cx),
@ -809,7 +809,7 @@ fn assoc_method(
let tcx = cx.tcx();
let header = meth.fn_header(tcx).expect("Trying to get header from a non-function item");
let name = meth.name.as_ref().unwrap();
let vis = meth.visibility(tcx).print_with_space(meth.item_id, cx).to_string();
let vis = visibility_print_with_space(meth.visibility(tcx), meth.item_id, cx).to_string();
// FIXME: Once https://github.com/rust-lang/rust/issues/67792 is implemented, we can remove
// this condition.
let constness = match render_mode {

View File

@ -7,7 +7,7 @@ use rustc_hir::def_id::DefId;
use rustc_middle::middle::stability;
use rustc_middle::span_bug;
use rustc_middle::ty::layout::LayoutError;
use rustc_middle::ty::{Adt, TyCtxt};
use rustc_middle::ty::{self, Adt, TyCtxt};
use rustc_span::hygiene::MacroKind;
use rustc_span::symbol::{kw, sym, Symbol};
use rustc_target::abi::{Layout, Primitive, TagEncoding, Variants};
@ -28,7 +28,7 @@ use crate::formats::{AssocItemRender, Impl, RenderMode};
use crate::html::escape::Escape;
use crate::html::format::{
join_with_double_colon, print_abi_with_space, print_constness_with_space, print_where_clause,
Buffer, Ending, PrintWithSpace,
visibility_print_with_space, Buffer, Ending, PrintWithSpace,
};
use crate::html::highlight;
use crate::html::layout::Page;
@ -328,14 +328,14 @@ fn item_module(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Item, items:
Some(src) => write!(
w,
"<div class=\"item-left\"><code>{}extern crate {} as {};",
myitem.visibility(tcx).print_with_space(myitem.item_id, cx),
visibility_print_with_space(myitem.visibility(tcx), myitem.item_id, cx),
anchor(myitem.item_id.expect_def_id(), src, cx),
myitem.name.unwrap(),
),
None => write!(
w,
"<div class=\"item-left\"><code>{}extern crate {};",
myitem.visibility(tcx).print_with_space(myitem.item_id, cx),
visibility_print_with_space(myitem.visibility(tcx), myitem.item_id, cx),
anchor(myitem.item_id.expect_def_id(), myitem.name.unwrap(), cx),
),
}
@ -385,7 +385,7 @@ fn item_module(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Item, items:
</div>\
{stab_tags_before}{stab_tags}{stab_tags_after}",
stab = stab.unwrap_or_default(),
vis = myitem.visibility(tcx).print_with_space(myitem.item_id, cx),
vis = visibility_print_with_space(myitem.visibility(tcx), myitem.item_id, cx),
imp = import.print(cx),
);
w.write_str(ITEM_TABLE_ROW_CLOSE);
@ -410,7 +410,7 @@ fn item_module(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Item, items:
let add = if stab.is_some() { " " } else { "" };
let visibility_emoji = match myitem.visibility(tcx) {
clean::Visibility::Restricted(_) => {
Some(ty::Visibility::Restricted(_)) => {
"<span title=\"Restricted Visibility\">&nbsp;🔒</span> "
}
_ => "",
@ -503,7 +503,7 @@ fn item_function(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, f: &cle
let unsafety = header.unsafety.print_with_space();
let abi = print_abi_with_space(header.abi).to_string();
let asyncness = header.asyncness.print_with_space();
let visibility = it.visibility(tcx).print_with_space(it.item_id, cx).to_string();
let visibility = visibility_print_with_space(it.visibility(tcx), it.item_id, cx).to_string();
let name = it.name.unwrap();
let generics_len = format!("{:#}", f.generics.print(cx)).len();
@ -561,7 +561,7 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean:
write!(
w,
"{}{}{}trait {}{}{}",
it.visibility(tcx).print_with_space(it.item_id, cx),
visibility_print_with_space(it.visibility(tcx), it.item_id, cx),
t.unsafety(tcx).print_with_space(),
if t.is_auto(tcx) { "auto " } else { "" },
it.name.unwrap(),
@ -1086,7 +1086,7 @@ fn item_typedef(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clea
fn write_content(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Typedef) {
wrap_item(w, "typedef", |w| {
render_attributes_in_pre(w, it, "");
write!(w, "{}", it.visibility(cx.tcx()).print_with_space(it.item_id, cx));
write!(w, "{}", visibility_print_with_space(it.visibility(cx.tcx()), it.item_id, cx));
write!(
w,
"type {}{}{where_clause} = {type_};",
@ -1183,7 +1183,7 @@ fn item_enum(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, e: &clean::
write!(
w,
"{}enum {}{}",
it.visibility(tcx).print_with_space(it.item_id, cx),
visibility_print_with_space(it.visibility(tcx), it.item_id, cx),
it.name.unwrap(),
e.generics.print(cx),
);
@ -1398,7 +1398,7 @@ fn item_constant(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, c: &cle
write!(
w,
"{vis}const {name}: {typ}",
vis = it.visibility(tcx).print_with_space(it.item_id, cx),
vis = visibility_print_with_space(it.visibility(tcx), it.item_id, cx),
name = it.name.unwrap(),
typ = c.type_.print(cx),
);
@ -1499,7 +1499,7 @@ fn item_static(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, s: &clean
write!(
w,
"{vis}static {mutability}{name}: {typ}",
vis = it.visibility(cx.tcx()).print_with_space(it.item_id, cx),
vis = visibility_print_with_space(it.visibility(cx.tcx()), it.item_id, cx),
mutability = s.mutability.print_with_space(),
name = it.name.unwrap(),
typ = s.type_.print(cx)
@ -1517,7 +1517,7 @@ fn item_foreign_type(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item) {
write!(
w,
" {}type {};\n}}",
it.visibility(cx.tcx()).print_with_space(it.item_id, cx),
visibility_print_with_space(it.visibility(cx.tcx()), it.item_id, cx),
it.name.unwrap(),
);
});
@ -1671,7 +1671,12 @@ fn render_union(
cx: &Context<'_>,
) {
let tcx = cx.tcx();
write!(w, "{}union {}", it.visibility(tcx).print_with_space(it.item_id, cx), it.name.unwrap(),);
write!(
w,
"{}union {}",
visibility_print_with_space(it.visibility(tcx), it.item_id, cx),
it.name.unwrap(),
);
let where_displayed = g
.map(|g| {
@ -1698,7 +1703,7 @@ fn render_union(
write!(
w,
" {}{}: {},\n{}",
field.visibility(tcx).print_with_space(field.item_id, cx),
visibility_print_with_space(field.visibility(tcx), field.item_id, cx),
field.name.unwrap(),
ty.print(cx),
tab
@ -1729,7 +1734,7 @@ fn render_struct(
write!(
w,
"{}{}{}",
it.visibility(tcx).print_with_space(it.item_id, cx),
visibility_print_with_space(it.visibility(tcx), it.item_id, cx),
if structhead { "struct " } else { "" },
it.name.unwrap()
);
@ -1759,7 +1764,7 @@ fn render_struct(
w,
"\n{} {}{}: {},",
tab,
field.visibility(tcx).print_with_space(field.item_id, cx),
visibility_print_with_space(field.visibility(tcx), field.item_id, cx),
field.name.unwrap(),
ty.print(cx),
);
@ -1791,7 +1796,7 @@ fn render_struct(
write!(
w,
"{}{}",
field.visibility(tcx).print_with_space(field.item_id, cx),
visibility_print_with_space(field.visibility(tcx), field.item_id, cx),
ty.print(cx),
)
}

View File

@ -100,13 +100,12 @@ impl JsonRenderer<'_> {
}
}
fn convert_visibility(&self, v: clean::Visibility) -> Visibility {
use clean::Visibility::*;
fn convert_visibility(&self, v: Option<ty::Visibility<DefId>>) -> Visibility {
match v {
Public => Visibility::Public,
Inherited => Visibility::Default,
Restricted(did) if did.is_crate_root() => Visibility::Crate,
Restricted(did) => Visibility::Restricted {
None => Visibility::Default,
Some(ty::Visibility::Public) => Visibility::Public,
Some(ty::Visibility::Restricted(did)) if did.is_crate_root() => Visibility::Crate,
Some(ty::Visibility::Restricted(did)) => Visibility::Restricted {
parent: from_item_id(did.into(), self.tcx),
path: self.tcx.def_path(did).to_string_no_crate_verbose(),
},

View File

@ -1,6 +1,6 @@
//! A collection of utility functions for the `strip_*` passes.
use rustc_hir::def_id::DefId;
use rustc_middle::ty::TyCtxt;
use rustc_middle::ty::{TyCtxt, Visibility};
use rustc_span::symbol::sym;
use std::mem;
@ -81,13 +81,13 @@ impl<'a, 'tcx> DocFolder for Stripper<'a, 'tcx> {
}
clean::StructFieldItem(..) => {
if !i.visibility(self.tcx).is_public() {
if i.visibility(self.tcx) != Some(Visibility::Public) {
return Some(strip_item(i));
}
}
clean::ModuleItem(..) => {
if i.item_id.is_local() && !i.visibility(self.tcx).is_public() {
if i.item_id.is_local() && i.visibility(self.tcx) != Some(Visibility::Public) {
debug!("Stripper: stripping module {:?}", i.name);
let old = mem::replace(&mut self.update_retained, false);
let ret = strip_item(self.fold_item_recur(i));
@ -246,7 +246,7 @@ impl<'tcx> DocFolder for ImportStripper<'tcx> {
fn fold_item(&mut self, i: Item) -> Option<Item> {
match *i.kind {
clean::ExternCrateItem { .. } | clean::ImportItem(..)
if !i.visibility(self.tcx).is_public() =>
if i.visibility(self.tcx) != Some(Visibility::Public) =>
{
None
}

View File

@ -0,0 +1,9 @@
// check-pass
#![feature(closure_lifetime_binder)]
fn main() {
let _ = for<'a> || -> () {
let _: &'a bool = &true;
};
}

View File

@ -0,0 +1,9 @@
// check-pass
#![feature(closure_lifetime_binder)]
#![feature(rustc_attrs)]
#[rustc_regions]
fn main() {
for<'a> || -> () { for<'c> |_: &'a ()| -> () {}; };
}

View File

@ -0,0 +1,38 @@
note: external requirements
--> $DIR/nested-closures-regions.rs:8:24
|
LL | for<'a> || -> () { for<'c> |_: &'a ()| -> () {}; };
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: defining type: main::{closure#0}::{closure#0} with closure substs [
i8,
extern "rust-call" fn((&(),)),
(),
]
= note: late-bound region is '_#4r
= note: late-bound region is '_#2r
= note: number of external vids: 3
= note: where '_#1r: '_#2r
= note: where '_#2r: '_#1r
note: no external requirements
--> $DIR/nested-closures-regions.rs:8:5
|
LL | for<'a> || -> () { for<'c> |_: &'a ()| -> () {}; };
| ^^^^^^^^^^^^^^^^
|
= note: defining type: main::{closure#0} with closure substs [
i8,
extern "rust-call" fn(()),
(),
]
= note: late-bound region is '_#2r
note: no external requirements
--> $DIR/nested-closures-regions.rs:7:1
|
LL | fn main() {
| ^^^^^^^^^
|
= note: defining type: main

View File

@ -0,0 +1,7 @@
// check-pass
#![feature(closure_lifetime_binder)]
fn main() {
for<'a> || -> () { for<'c> |_: &'a ()| -> () {}; };
}

View File

@ -0,0 +1,12 @@
// build-pass
// compile-flags:-C link-dead-code=y
#![feature(negative_impls)]
trait Foo {
fn foo() {}
}
impl !Foo for () {}
fn main() {}