Skip to content

Rollup of 6 pull requests #101652

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 17 commits into from
Sep 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion compiler/rustc_data_structures/src/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ cfg_if! {
/// the native atomic types.
/// You should use this type through the `AtomicU64`, `AtomicUsize`, etc, type aliases
/// as it's not intended to be used separately.
#[derive(Debug)]
#[derive(Debug, Default)]
pub struct Atomic<T: Copy>(Cell<T>);

impl<T: Copy> Atomic<T> {
Expand Down
7 changes: 2 additions & 5 deletions compiler/rustc_middle/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1202,14 +1202,11 @@ rustc_queries! {
}
}

query codegen_fulfill_obligation(
query codegen_select_candidate(
key: (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>)
) -> Result<&'tcx ImplSource<'tcx, ()>, traits::CodegenObligationError> {
cache_on_disk_if { true }
desc { |tcx|
"checking if `{}` fulfills its obligations",
tcx.def_path_str(key.1.def_id())
}
desc { |tcx| "computing candidate for `{}`", key.1 }
}

/// Return all `impl` blocks in the current crate.
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1024,7 +1024,7 @@ pub enum MethodViolationCode {
UndispatchableReceiver(Option<Span>),
}

/// These are the error cases for `codegen_fulfill_obligation`.
/// These are the error cases for `codegen_select_candidate`.
#[derive(Copy, Clone, Debug, Hash, HashStable, Encodable, Decodable)]
pub enum CodegenObligationError {
/// Ambiguity can happen when monomorphizing during trans
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_monomorphize/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ fn custom_coerce_unsize_info<'tcx>(
substs: tcx.mk_substs_trait(source_ty, &[target_ty.into()]),
});

match tcx.codegen_fulfill_obligation((ty::ParamEnv::reveal_all(), trait_ref)) {
match tcx.codegen_select_candidate((ty::ParamEnv::reveal_all(), trait_ref)) {
Ok(traits::ImplSource::UserDefined(traits::ImplSourceUserDefinedData {
impl_def_id,
..
Expand Down
35 changes: 20 additions & 15 deletions compiler/rustc_query_impl/src/plumbing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use crate::keys::Key;
use crate::{on_disk_cache, Queries};
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::sync::Lock;
use rustc_data_structures::sync::{AtomicU64, Lock};
use rustc_errors::{Diagnostic, Handler};
use rustc_middle::dep_graph::{
self, DepKind, DepKindStruct, DepNode, DepNodeIndex, SerializedDepNodeIndex,
Expand Down Expand Up @@ -499,9 +499,28 @@ macro_rules! define_queries {
}
}

use crate::{ExternProviders, OnDiskCache, Providers};

impl<'tcx> Queries<'tcx> {
pub fn new(
local_providers: Providers,
extern_providers: ExternProviders,
on_disk_cache: Option<OnDiskCache<'tcx>>,
) -> Self {
Queries {
local_providers: Box::new(local_providers),
extern_providers: Box::new(extern_providers),
on_disk_cache,
jobs: AtomicU64::new(1),
..Queries::default()
}
}
}

macro_rules! define_queries_struct {
(
input: ($(([$($modifiers:tt)*] [$($attr:tt)*] [$name:ident]))*)) => {
#[derive(Default)]
pub struct Queries<'tcx> {
local_providers: Box<Providers>,
extern_providers: Box<ExternProviders>,
Expand All @@ -514,20 +533,6 @@ macro_rules! define_queries_struct {
}

impl<'tcx> Queries<'tcx> {
pub fn new(
local_providers: Providers,
extern_providers: ExternProviders,
on_disk_cache: Option<OnDiskCache<'tcx>>,
) -> Self {
Queries {
local_providers: Box::new(local_providers),
extern_providers: Box::new(extern_providers),
on_disk_cache,
jobs: AtomicU64::new(1),
$($name: Default::default()),*
}
}

pub(crate) fn try_collect_active_jobs(
&'tcx self,
tcx: TyCtxt<'tcx>,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_trait_selection/src/traits/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use rustc_middle::ty::{self, TyCtxt};
/// obligations *could be* resolved if we wanted to.
///
/// This also expects that `trait_ref` is fully normalized.
pub fn codegen_fulfill_obligation<'tcx>(
pub fn codegen_select_candidate<'tcx>(
tcx: TyCtxt<'tcx>,
(param_env, trait_ref): (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>),
) -> Result<&'tcx ImplSource<'tcx, ()>, CodegenObligationError> {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_trait_selection/src/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -971,7 +971,7 @@ pub fn provide(providers: &mut ty::query::Providers) {
*providers = ty::query::Providers {
specialization_graph_of: specialize::specialization_graph_provider,
specializes: specialize::specializes,
codegen_fulfill_obligation: codegen::codegen_fulfill_obligation,
codegen_select_candidate: codegen::codegen_select_candidate,
own_existential_vtable_entries,
vtable_entries,
vtable_trait_upcasting_coercion_new_vptr_slot,
Expand Down
113 changes: 3 additions & 110 deletions compiler/rustc_ty_utils/src/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,113 +3,11 @@ use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_infer::infer::TyCtxtInferExt;
use rustc_middle::traits::CodegenObligationError;
use rustc_middle::ty::subst::SubstsRef;
use rustc_middle::ty::{
self, Binder, Instance, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor,
};
use rustc_middle::ty::{self, Instance, TyCtxt, TypeVisitable};
use rustc_span::{sym, DUMMY_SP};
use rustc_trait_selection::traits;
use traits::{translate_substs, Reveal};

use rustc_data_structures::sso::SsoHashSet;
use std::collections::btree_map::Entry;
use std::collections::BTreeMap;
use std::ops::ControlFlow;

// FIXME(#86795): `BoundVarsCollector` here should **NOT** be used
// outside of `resolve_associated_item`. It's just to address #64494,
// #83765, and #85848 which are creating bound types/regions that lose
// their `Binder` *unintentionally*.
// It's ideal to remove `BoundVarsCollector` and just use
// `ty::Binder::*` methods but we use this stopgap until we figure out
// the "real" fix.
struct BoundVarsCollector<'tcx> {
binder_index: ty::DebruijnIndex,
vars: BTreeMap<u32, ty::BoundVariableKind>,
// We may encounter the same variable at different levels of binding, so
// this can't just be `Ty`
visited: SsoHashSet<(ty::DebruijnIndex, Ty<'tcx>)>,
}

impl<'tcx> BoundVarsCollector<'tcx> {
fn new() -> Self {
BoundVarsCollector {
binder_index: ty::INNERMOST,
vars: BTreeMap::new(),
visited: SsoHashSet::default(),
}
}

fn into_vars(self, tcx: TyCtxt<'tcx>) -> &'tcx ty::List<ty::BoundVariableKind> {
let max = self.vars.iter().map(|(k, _)| *k).max().unwrap_or(0);
for i in 0..max {
if let None = self.vars.get(&i) {
panic!("Unknown variable: {:?}", i);
}
}

tcx.mk_bound_variable_kinds(self.vars.into_iter().map(|(_, v)| v))
}
}

impl<'tcx> TypeVisitor<'tcx> for BoundVarsCollector<'tcx> {
type BreakTy = ();

fn visit_binder<T: TypeVisitable<'tcx>>(
&mut self,
t: &Binder<'tcx, T>,
) -> ControlFlow<Self::BreakTy> {
self.binder_index.shift_in(1);
let result = t.super_visit_with(self);
self.binder_index.shift_out(1);
result
}

fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
if t.outer_exclusive_binder() < self.binder_index
|| !self.visited.insert((self.binder_index, t))
{
return ControlFlow::CONTINUE;
}
match *t.kind() {
ty::Bound(debruijn, bound_ty) if debruijn == self.binder_index => {
match self.vars.entry(bound_ty.var.as_u32()) {
Entry::Vacant(entry) => {
entry.insert(ty::BoundVariableKind::Ty(bound_ty.kind));
}
Entry::Occupied(entry) => match entry.get() {
ty::BoundVariableKind::Ty(_) => {}
_ => bug!("Conflicting bound vars"),
},
}
}

_ => (),
};

t.super_visit_with(self)
}

fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
match *r {
ty::ReLateBound(index, br) if index == self.binder_index => {
match self.vars.entry(br.var.as_u32()) {
Entry::Vacant(entry) => {
entry.insert(ty::BoundVariableKind::Region(br.kind));
}
Entry::Occupied(entry) => match entry.get() {
ty::BoundVariableKind::Region(_) => {}
_ => bug!("Conflicting bound vars"),
},
}
}

_ => (),
};

r.super_visit_with(self)
}
}

fn resolve_instance<'tcx>(
tcx: TyCtxt<'tcx>,
key: ty::ParamEnvAnd<'tcx, (DefId, SubstsRef<'tcx>)>,
Expand Down Expand Up @@ -201,19 +99,14 @@ fn resolve_associated_item<'tcx>(

let trait_ref = ty::TraitRef::from_method(tcx, trait_id, rcvr_substs);

// See FIXME on `BoundVarsCollector`.
let mut bound_vars_collector = BoundVarsCollector::new();
trait_ref.visit_with(&mut bound_vars_collector);
let trait_binder = ty::Binder::bind_with_vars(trait_ref, bound_vars_collector.into_vars(tcx));
let vtbl = match tcx.codegen_fulfill_obligation((param_env, trait_binder)) {
let vtbl = match tcx.codegen_select_candidate((param_env, ty::Binder::dummy(trait_ref))) {
Ok(vtbl) => vtbl,
Err(CodegenObligationError::Ambiguity) => {
let reported = tcx.sess.delay_span_bug(
tcx.def_span(trait_item_id),
&format!(
"encountered ambiguity selecting `{:?}` during codegen, presuming due to \
"encountered ambiguity selecting `{trait_ref:?}` during codegen, presuming due to \
overflow or prior type error",
trait_binder
),
);
return Err(reported);
Expand Down
19 changes: 17 additions & 2 deletions compiler/rustc_typeck/src/check/compare_method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -295,12 +295,26 @@ pub(super) fn compare_predicates_and_trait_impl_trait_tys<'tcx>(
// type would be more appropriate. In other places we have a `Vec<Span>`
// corresponding to their `Vec<Predicate>`, but we don't have that here.
// Fixing this would improve the output of test `issue-83765.rs`.
let sub_result = infcx
let mut result = infcx
.at(&cause, param_env)
.sup(trait_fty, impl_fty)
.map(|infer_ok| ocx.register_infer_ok_obligations(infer_ok));

if let Err(terr) = sub_result {
// HACK(RPITIT): #101614. When we are trying to infer the hidden types for
// RPITITs, we need to equate the output tys instead of just subtyping. If
// we just use `sup` above, we'll end up `&'static str <: _#1t`, which causes
// us to infer `_#1t = #'_#2r str`, where `'_#2r` is unconstrained, which gets
// fixed up to `ReEmpty`, and which is certainly not what we want.
if trait_fty.has_infer_types() {
result = result.and_then(|()| {
infcx
.at(&cause, param_env)
.eq(trait_sig.output(), impl_sig.output())
.map(|infer_ok| ocx.register_infer_ok_obligations(infer_ok))
});
}

if let Err(terr) = result {
debug!("sub_types failed: impl ty {:?}, trait ty {:?}", impl_fty, trait_fty);

let (impl_err_span, trait_err_span) =
Expand Down Expand Up @@ -445,6 +459,7 @@ pub(super) fn compare_predicates_and_trait_impl_trait_tys<'tcx>(
region
}
});
debug!(%ty);
collected_tys.insert(def_id, ty);
}
Err(err) => {
Expand Down
2 changes: 1 addition & 1 deletion library/std/src/thread/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@
//! Threads are able to have associated names for identification purposes. By default, spawned
//! threads are unnamed. To specify a name for a thread, build the thread with [`Builder`] and pass
//! the desired thread name to [`Builder::name`]. To retrieve the thread name from within the
//! thread, use [`Thread::name`]. A couple examples of where the name of a thread gets used:
//! thread, use [`Thread::name`]. A couple of examples where the name of a thread gets used:
//!
//! * If a panic occurs in a named thread, the thread name will be printed in the panic message.
//! * The thread name is provided to the OS where applicable (e.g., `pthread_setname_np` in
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.9.7
0.9.8
19 changes: 14 additions & 5 deletions src/librustdoc/clean/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,23 @@ pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext<
let mut inserted = FxHashSet::default();
items.extend(doc.foreigns.iter().map(|(item, renamed)| {
let item = clean_maybe_renamed_foreign_item(cx, item, *renamed);
if let Some(name) = item.name {
if let Some(name) = item.name && !item.attrs.lists(sym::doc).has_word(sym::hidden) {
inserted.insert((item.type_(), name));
}
item
}));
items.extend(doc.mods.iter().map(|x| {
inserted.insert((ItemType::Module, x.name));
clean_doc_module(x, cx)
items.extend(doc.mods.iter().filter_map(|x| {
if !inserted.insert((ItemType::Module, x.name)) {
return None;
}
let item = clean_doc_module(x, cx);
if item.attrs.lists(sym::doc).has_word(sym::hidden) {
// Hidden modules are stripped at a later stage.
// If a hidden module has the same name as a visible one, we want
// to keep both of them around.
inserted.remove(&(ItemType::Module, x.name));
}
Some(item)
}));

// Split up imports from all other items.
Expand All @@ -72,7 +81,7 @@ pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext<
}
let v = clean_maybe_renamed_item(cx, item, *renamed);
for item in &v {
if let Some(name) = item.name {
if let Some(name) = item.name && !item.attrs.lists(sym::doc).has_word(sym::hidden) {
inserted.insert((item.type_(), name));
}
}
Expand Down
12 changes: 12 additions & 0 deletions src/librustdoc/visit_ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,20 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
self.inside_public_path &= self.cx.tcx.visibility(def_id).is_public();
for &i in m.item_ids {
let item = self.cx.tcx.hir().item(i);
if matches!(item.kind, hir::ItemKind::Use(_, hir::UseKind::Glob)) {
continue;
}
self.visit_item(item, None, &mut om);
}
for &i in m.item_ids {
let item = self.cx.tcx.hir().item(i);
// To match the way import precedence works, visit glob imports last.
// 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.inside_public_path = orig_inside_public_path;
om
}
Expand Down
20 changes: 20 additions & 0 deletions src/test/rustdoc/glob-shadowing-const.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// https://github.com/rust-lang/rust/pull/83872#issuecomment-820101008
#![crate_name="foo"]

mod sub4 {
/// 0
pub const X: usize = 0;
pub mod inner {
pub use super::*;
/// 1
pub const X: usize = 1;
}
}

#[doc(inline)]
pub use sub4::inner::*;

// @has 'foo/index.html'
// @has - '//div[@class="item-right docblock-short"]' '1'
// @!has - '//div[@class="item-right docblock-short"]' '0'
fn main() { assert_eq!(X, 1); }
Loading