Auto merge of #103903 - matthiaskrgr:rollup-r5xcvrp, r=matthiaskrgr

Rollup of 6 pull requests

Successful merges:

 - #99801 (fix(generic_const_exprs): Fix predicate inheritance for children of opaque types)
 - #103610 (Allow use of `-Clto=thin` with `-Ccodegen-units=1` in general)
 - #103870 (Fix `inferred_kind` ICE)
 - #103875 (Simplify astconv item def id handling)
 - #103886 (rustdoc: Fix merge of attributes for reexports of local items)
 - #103890 (rustdoc: remove unused mobile CSS `.rustdoc { padding-top: 0 }`)

Failed merges:

 - #103884 (Add visit_fn_ret_ty to hir intravisit)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2022-11-03 00:20:08 +00:00
commit 96787c45ac
15 changed files with 213 additions and 50 deletions

View File

@ -177,11 +177,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
.all_traits()
.filter(|trait_def_id| {
let viz = self.tcx().visibility(*trait_def_id);
if let Some(def_id) = self.item_def_id() {
viz.is_accessible_from(def_id, self.tcx())
} else {
viz.is_visible_locally()
}
let def_id = self.item_def_id();
viz.is_accessible_from(def_id, self.tcx())
})
.collect();

View File

@ -54,7 +54,7 @@ pub struct PathSeg(pub DefId, pub usize);
pub trait AstConv<'tcx> {
fn tcx<'a>(&'a self) -> TyCtxt<'tcx>;
fn item_def_id(&self) -> Option<DefId>;
fn item_def_id(&self) -> DefId;
/// Returns predicates in scope of the form `X: Foo<T>`, where `X`
/// is a type parameter `X` with the given id `def_id` and T
@ -500,6 +500,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
}
GenericParamDefKind::Const { has_default } => {
let ty = tcx.at(self.span).type_of(param.def_id);
if ty.references_error() {
return tcx.const_error(ty).into();
}
if !infer_args && has_default {
tcx.bound_const_param_default(param.def_id)
.subst(tcx, substs.unwrap())
@ -2079,17 +2082,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
debug!("qpath_to_ty: self.item_def_id()={:?}", def_id);
let parent_def_id = def_id
.and_then(|def_id| {
def_id.as_local().map(|def_id| tcx.hir().local_def_id_to_hir_id(def_id))
})
let parent_def_id = def_id.as_local().map(|def_id| tcx.hir().local_def_id_to_hir_id(def_id))
.map(|hir_id| tcx.hir().get_parent_item(hir_id).to_def_id());
debug!("qpath_to_ty: parent_def_id={:?}", parent_def_id);
// If the trait in segment is the same as the trait defining the item,
// use the `<Self as ..>` syntax in the error.
let is_part_of_self_trait_constraints = def_id == Some(trait_def_id);
let is_part_of_self_trait_constraints = def_id == trait_def_id;
let is_part_of_fn_in_self_trait = parent_def_id == Some(trait_def_id);
let type_name = if is_part_of_self_trait_constraints || is_part_of_fn_in_self_trait {

View File

@ -379,8 +379,8 @@ impl<'tcx> AstConv<'tcx> for ItemCtxt<'tcx> {
self.tcx
}
fn item_def_id(&self) -> Option<DefId> {
Some(self.item_def_id)
fn item_def_id(&self) -> DefId {
self.item_def_id
}
fn get_type_parameter_bounds(

View File

@ -427,6 +427,8 @@ pub(super) fn explicit_predicates_of<'tcx>(
} else {
if matches!(def_kind, DefKind::AnonConst) && tcx.lazy_normalization() {
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
let parent_def_id = tcx.hir().get_parent_item(hir_id);
if tcx.hir().opt_const_param_default_param_hir_id(hir_id).is_some() {
// In `generics_of` we set the generics' parent to be our parent's parent which means that
// we lose out on the predicates of our actual parent if we dont return those predicates here.
@ -439,8 +441,33 @@ pub(super) fn explicit_predicates_of<'tcx>(
// parent of generics returned by `generics_of`
//
// In the above code we want the anon const to have predicates in its param env for `T: Trait`
let item_def_id = tcx.hir().get_parent_item(hir_id);
// In the above code example we would be calling `explicit_predicates_of(Foo)` here
// and we would be calling `explicit_predicates_of(Foo)` here
return tcx.explicit_predicates_of(parent_def_id);
}
let parent_def_kind = tcx.def_kind(parent_def_id);
if matches!(parent_def_kind, DefKind::OpaqueTy) {
// In `instantiate_identity` we inherit the predicates of our parent.
// However, opaque types do not have a parent (see `gather_explicit_predicates_of`), which means
// that we lose out on the predicates of our actual parent if we dont return those predicates here.
//
//
// fn foo<T: Trait>() -> impl Iterator<Output = Another<{ <T as Trait>::ASSOC }> > { todo!() }
// ^^^^^^^^^^^^^^^^^^^ the def id we are calling
// explicit_predicates_of on
//
// In the above code we want the anon const to have predicates in its param env for `T: Trait`.
// However, the anon const cannot inherit predicates from its parent since it's opaque.
//
// To fix this, we call `explicit_predicates_of` directly on `foo`, the parent's parent.
// In the above example this is `foo::{opaque#0}` or `impl Iterator`
let parent_hir_id = tcx.hir().local_def_id_to_hir_id(parent_def_id.def_id);
// In the above example this is the function `foo`
let item_def_id = tcx.hir().get_parent_item(parent_hir_id);
// In the above code example we would be calling `explicit_predicates_of(foo)` here
return tcx.explicit_predicates_of(item_def_id);
}
}

View File

@ -194,8 +194,8 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
self.tcx
}
fn item_def_id(&self) -> Option<DefId> {
None
fn item_def_id(&self) -> DefId {
self.body_id.owner.to_def_id()
}
fn get_type_parameter_bounds(

View File

@ -738,7 +738,7 @@ impl Default for Options {
actually_rustdoc: false,
trimmed_def_paths: TrimmedDefPaths::default(),
cli_forced_codegen_units: None,
cli_forced_thinlto_off: false,
cli_forced_local_thinlto_off: false,
remap_path_prefix: Vec::new(),
real_rust_source_base_dir: None,
edition: DEFAULT_EDITION,
@ -1721,7 +1721,7 @@ fn should_override_cgus_and_disable_thinlto(
error_format: ErrorOutputType,
mut codegen_units: Option<usize>,
) -> (bool, Option<usize>) {
let mut disable_thinlto = false;
let mut disable_local_thinlto = false;
// Issue #30063: if user requests LLVM-related output to one
// particular path, disable codegen-units.
let incompatible: Vec<_> = output_types
@ -1746,12 +1746,12 @@ fn should_override_cgus_and_disable_thinlto(
}
early_warn(error_format, "resetting to default -C codegen-units=1");
codegen_units = Some(1);
disable_thinlto = true;
disable_local_thinlto = true;
}
}
_ => {
codegen_units = Some(1);
disable_thinlto = true;
disable_local_thinlto = true;
}
}
}
@ -1760,7 +1760,7 @@ fn should_override_cgus_and_disable_thinlto(
early_error(error_format, "value for codegen units must be a positive non-zero integer");
}
(disable_thinlto, codegen_units)
(disable_local_thinlto, codegen_units)
}
fn check_thread_count(unstable_opts: &UnstableOptions, error_format: ErrorOutputType) {
@ -2265,7 +2265,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
let output_types = parse_output_types(&unstable_opts, matches, error_format);
let mut cg = CodegenOptions::build(matches, error_format);
let (disable_thinlto, mut codegen_units) = should_override_cgus_and_disable_thinlto(
let (disable_local_thinlto, mut codegen_units) = should_override_cgus_and_disable_thinlto(
&output_types,
matches,
error_format,
@ -2508,7 +2508,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
actually_rustdoc: false,
trimmed_def_paths: TrimmedDefPaths::default(),
cli_forced_codegen_units: codegen_units,
cli_forced_thinlto_off: disable_thinlto,
cli_forced_local_thinlto_off: disable_local_thinlto,
remap_path_prefix,
real_rust_source_base_dir,
edition,

View File

@ -181,7 +181,7 @@ top_level_options!(
#[rustc_lint_opt_deny_field_access("use `Session::codegen_units` instead of this field")]
cli_forced_codegen_units: Option<usize> [UNTRACKED],
#[rustc_lint_opt_deny_field_access("use `Session::lto` instead of this field")]
cli_forced_thinlto_off: bool [UNTRACKED],
cli_forced_local_thinlto_off: bool [UNTRACKED],
/// Remap source path prefixes in all output (messages, object files, debug, etc.).
remap_path_prefix: Vec<(PathBuf, PathBuf)> [TRACKED_NO_CRATE_HASH],

View File

@ -1018,11 +1018,8 @@ impl Session {
return config::Lto::Fat;
}
config::LtoCli::Thin => {
return if self.opts.cli_forced_thinlto_off {
config::Lto::Fat
} else {
config::Lto::Thin
};
// The user explicitly asked for ThinLTO
return config::Lto::Thin;
}
}
@ -1034,7 +1031,7 @@ impl Session {
// If processing command line options determined that we're incompatible
// with ThinLTO (e.g., `-C lto --emit llvm-ir`) then return that option.
if self.opts.cli_forced_thinlto_off {
if self.opts.cli_forced_local_thinlto_off {
return config::Lto::No;
}

View File

@ -74,12 +74,12 @@ pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext<
// This covers the case where somebody does an import which should pull in an item,
// but there's already an item with the same namespace and same name. Rust gives
// priority to the not-imported one, so we should, too.
items.extend(doc.items.iter().flat_map(|(item, renamed)| {
items.extend(doc.items.iter().flat_map(|(item, renamed, import_id)| {
// First, lower everything other than imports.
if matches!(item.kind, hir::ItemKind::Use(_, hir::UseKind::Glob)) {
return Vec::new();
}
let v = clean_maybe_renamed_item(cx, item, *renamed);
let v = clean_maybe_renamed_item(cx, item, *renamed, *import_id);
for item in &v {
if let Some(name) = item.name && !item.attrs.lists(sym::doc).has_word(sym::hidden) {
inserted.insert((item.type_(), name));
@ -87,7 +87,7 @@ pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext<
}
v
}));
items.extend(doc.items.iter().flat_map(|(item, renamed)| {
items.extend(doc.items.iter().flat_map(|(item, renamed, _)| {
// Now we actually lower the imports, skipping everything else.
if let hir::ItemKind::Use(path, hir::UseKind::Glob) = item.kind {
let name = renamed.unwrap_or_else(|| cx.tcx.hir().name(item.hir_id()));
@ -1911,6 +1911,7 @@ fn clean_maybe_renamed_item<'tcx>(
cx: &mut DocContext<'tcx>,
item: &hir::Item<'tcx>,
renamed: Option<Symbol>,
import_id: Option<hir::HirId>,
) -> Vec<Item> {
use hir::ItemKind;
@ -1987,8 +1988,23 @@ fn clean_maybe_renamed_item<'tcx>(
}
_ => unreachable!("not yet converted"),
};
vec![Item::from_def_id_and_parts(def_id, Some(name), kind, cx)]
if let Some(import_id) = import_id {
let (attrs, cfg) = inline::merge_attrs(
cx,
Some(cx.tcx.parent_module(import_id).to_def_id()),
inline::load_attrs(cx, def_id),
Some(inline::load_attrs(cx, cx.tcx.hir().local_def_id(import_id).to_def_id())),
);
vec![Item::from_def_id_and_attrs_and_parts(
def_id,
Some(name),
kind,
Box::new(attrs),
cfg,
)]
} else {
vec![Item::from_def_id_and_parts(def_id, Some(name), kind, cx)]
}
})
}

View File

@ -1677,7 +1677,6 @@ in storage.js
}
.rustdoc {
padding-top: 0px;
/* Sidebar should overlay main content, rather than pushing main content to the right.
Turn off `display: flex` on the body element. */
display: block;

View File

@ -25,8 +25,8 @@ pub(crate) struct Module<'hir> {
pub(crate) where_inner: Span,
pub(crate) mods: Vec<Module<'hir>>,
pub(crate) id: hir::HirId,
// (item, renamed)
pub(crate) items: Vec<(&'hir hir::Item<'hir>, Option<Symbol>)>,
// (item, renamed, import_id)
pub(crate) items: Vec<(&'hir hir::Item<'hir>, Option<Symbol>, Option<hir::HirId>)>,
pub(crate) foreigns: Vec<(&'hir hir::ForeignItem<'hir>, Option<Symbol>)>,
}
@ -93,6 +93,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
hir::CRATE_HIR_ID,
self.cx.tcx.hir().root_module(),
self.cx.tcx.crate_name(LOCAL_CRATE),
None,
);
// `#[macro_export] macro_rules!` items are reexported at the top level of the
@ -113,7 +114,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
if self.cx.tcx.has_attr(def_id, sym::macro_export) {
if inserted.insert(def_id) {
let item = self.cx.tcx.hir().expect_item(local_def_id);
top_level_module.items.push((item, None));
top_level_module.items.push((item, None, None));
}
}
}
@ -155,6 +156,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
id: hir::HirId,
m: &'tcx hir::Mod<'tcx>,
name: Symbol,
parent_id: Option<hir::HirId>,
) -> Module<'tcx> {
let mut om = Module::new(name, id, m.spans.inner_span);
let def_id = self.cx.tcx.hir().local_def_id(id).to_def_id();
@ -166,7 +168,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
if matches!(item.kind, hir::ItemKind::Use(_, hir::UseKind::Glob)) {
continue;
}
self.visit_item(item, None, &mut om);
self.visit_item(item, None, &mut om, parent_id);
}
for &i in m.item_ids {
let item = self.cx.tcx.hir().item(i);
@ -174,7 +176,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
// Later passes in rustdoc will de-duplicate by name and kind, so if glob-
// imported items appear last, then they'll be the ones that get discarded.
if matches!(item.kind, hir::ItemKind::Use(_, hir::UseKind::Glob)) {
self.visit_item(item, None, &mut om);
self.visit_item(item, None, &mut om, parent_id);
}
}
self.inside_public_path = orig_inside_public_path;
@ -247,14 +249,14 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
let prev = mem::replace(&mut self.inlining, true);
for &i in m.item_ids {
let i = self.cx.tcx.hir().item(i);
self.visit_item(i, None, om);
self.visit_item(i, None, om, Some(id));
}
self.inlining = prev;
true
}
Node::Item(it) if !glob => {
let prev = mem::replace(&mut self.inlining, true);
self.visit_item(it, renamed, om);
self.visit_item(it, renamed, om, Some(id));
self.inlining = prev;
true
}
@ -275,6 +277,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
item: &'tcx hir::Item<'_>,
renamed: Option<Symbol>,
om: &mut Module<'tcx>,
parent_id: Option<hir::HirId>,
) {
debug!("visiting item {:?}", item);
let name = renamed.unwrap_or(item.ident.name);
@ -330,7 +333,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
}
}
om.items.push((item, renamed))
om.items.push((item, renamed, parent_id))
}
hir::ItemKind::Macro(ref macro_def, _) => {
// `#[macro_export] macro_rules!` items are handled separately in `visit()`,
@ -349,11 +352,11 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
let nonexported = !self.cx.tcx.has_attr(def_id, sym::macro_export);
if is_macro_2_0 || nonexported || self.inlining {
om.items.push((item, renamed));
om.items.push((item, renamed, None));
}
}
hir::ItemKind::Mod(ref m) => {
om.mods.push(self.visit_mod_contents(item.hir_id(), m, name));
om.mods.push(self.visit_mod_contents(item.hir_id(), m, name, parent_id));
}
hir::ItemKind::Fn(..)
| hir::ItemKind::ExternCrate(..)
@ -364,19 +367,19 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
| hir::ItemKind::OpaqueTy(..)
| hir::ItemKind::Static(..)
| hir::ItemKind::Trait(..)
| hir::ItemKind::TraitAlias(..) => om.items.push((item, renamed)),
| hir::ItemKind::TraitAlias(..) => om.items.push((item, renamed, parent_id)),
hir::ItemKind::Const(..) => {
// Underscore constants do not correspond to a nameable item and
// so are never useful in documentation.
if name != kw::Underscore {
om.items.push((item, renamed));
om.items.push((item, renamed, parent_id));
}
}
hir::ItemKind::Impl(impl_) => {
// Don't duplicate impls when inlining or if it's implementing a trait, we'll pick
// them up regardless of where they're located.
if !self.inlining && impl_.of_trait.is_none() {
om.items.push((item, None));
om.items.push((item, None, None));
}
}
}

View File

@ -0,0 +1,16 @@
// This test ensures that the reexports of local items also get the doc from
// the reexport.
#![crate_name = "foo"]
// @has 'foo/fn.g.html'
// @has - '//*[@class="rustdoc-toggle top-doc"]/*[@class="docblock"]' \
// 'outer module inner module'
mod inner_mod {
/// inner module
pub fn g() {}
}
/// outer module
pub use inner_mod::g;

View File

@ -0,0 +1,33 @@
// check-pass
#![crate_type = "lib"]
#![feature(generic_const_exprs)]
#![allow(incomplete_features)]
pub trait MyIterator {
type Output;
}
pub trait Foo {
const ABC: usize;
}
pub struct IteratorStruct<const N: usize>{
}
pub struct Bar<const N: usize> {
pub data: [usize; N]
}
impl<const N: usize> MyIterator for IteratorStruct<N> {
type Output = Bar<N>;
}
pub fn test1<T: Foo>() -> impl MyIterator<Output = Bar<{T::ABC}>> where [(); T::ABC]: Sized {
IteratorStruct::<{T::ABC}>{}
}
pub trait Baz<const N: usize>{}
impl<const N: usize> Baz<N> for Bar<N> {}
pub fn test2<T: Foo>() -> impl MyIterator<Output = impl Baz<{ T::ABC }>> where [(); T::ABC]: Sized {
IteratorStruct::<{T::ABC}>{}
}

View File

@ -0,0 +1,10 @@
#![feature(generic_const_exprs)]
#![allow(incomplete_features)]
struct S<const S: (), const S: S = { S }>;
//~^ ERROR the name `S` is already used for a generic parameter in this item's generic parameters
//~| ERROR missing generics for struct `S`
//~| ERROR cycle detected when computing type of `S::S`
//~| ERROR cycle detected when computing type of `S`
fn main() {}

View File

@ -0,0 +1,65 @@
error[E0403]: the name `S` is already used for a generic parameter in this item's generic parameters
--> $DIR/issue-103790.rs:4:29
|
LL | struct S<const S: (), const S: S = { S }>;
| - ^ already used
| |
| first use of `S`
error[E0107]: missing generics for struct `S`
--> $DIR/issue-103790.rs:4:32
|
LL | struct S<const S: (), const S: S = { S }>;
| ^ expected at least 1 generic argument
|
note: struct defined here, with at least 1 generic parameter: `S`
--> $DIR/issue-103790.rs:4:8
|
LL | struct S<const S: (), const S: S = { S }>;
| ^ -----------
help: add missing generic argument
|
LL | struct S<const S: (), const S: S<S> = { S }>;
| ~~~~
error[E0391]: cycle detected when computing type of `S::S`
--> $DIR/issue-103790.rs:4:32
|
LL | struct S<const S: (), const S: S = { S }>;
| ^
|
= note: ...which immediately requires computing type of `S::S` again
note: cycle used when computing type of `S`
--> $DIR/issue-103790.rs:4:1
|
LL | struct S<const S: (), const S: S = { S }>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0391]: cycle detected when computing type of `S`
--> $DIR/issue-103790.rs:4:1
|
LL | struct S<const S: (), const S: S = { S }>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: ...which requires computing type of `S::S`...
--> $DIR/issue-103790.rs:4:32
|
LL | struct S<const S: (), const S: S = { S }>;
| ^
= note: ...which again requires computing type of `S`, completing the cycle
note: cycle used when collecting item types in top-level module
--> $DIR/issue-103790.rs:1:1
|
LL | / #![feature(generic_const_exprs)]
LL | | #![allow(incomplete_features)]
LL | |
LL | | struct S<const S: (), const S: S = { S }>;
... |
LL | |
LL | | fn main() {}
| |____________^
error: aborting due to 4 previous errors
Some errors have detailed explanations: E0107, E0391, E0403.
For more information about an error, try `rustc --explain E0107`.