Skip to content

Commit

Permalink
Auto merge of #110522 - matthiaskrgr:rollup-9m7rw3u, r=matthiaskrgr
Browse files Browse the repository at this point in the history
Rollup of 7 pull requests

Successful merges:

 - #110432 (Report more detailed reason why `Index` impl is not satisfied)
 - #110451 (Minor changes to `IndexVec::ensure_contains_elem` & related methods)
 - #110476 (Delay a good path bug on drop for `TypeErrCtxt` (instead of a regular delayed bug))
 - #110498 (Switch to `EarlyBinder` for `collect_return_position_impl_trait_in_trait_tys`)
 - #110507 (boostrap: print output during building tools)
 - #110510 (Fix ICE for transmutability in candidate assembly)
 - #110513 (make `non_upper_case_globals` lint not report trait impls)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Apr 19, 2023
2 parents 9e7f72c + 78490ad commit c781584
Show file tree
Hide file tree
Showing 28 changed files with 303 additions and 57 deletions.
10 changes: 5 additions & 5 deletions compiler/rustc_ast_lowering/src/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,18 +89,18 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
lctx.with_hir_id_owner(owner, |lctx| f(lctx));

for (def_id, info) in lctx.children {
self.owners.ensure_contains_elem(def_id, || hir::MaybeOwner::Phantom);
debug_assert!(matches!(self.owners[def_id], hir::MaybeOwner::Phantom));
self.owners[def_id] = info;
let owner = self.owners.ensure_contains_elem(def_id, || hir::MaybeOwner::Phantom);
debug_assert!(matches!(owner, hir::MaybeOwner::Phantom));
*owner = info;
}
}

pub(super) fn lower_node(
&mut self,
def_id: LocalDefId,
) -> hir::MaybeOwner<&'hir hir::OwnerInfo<'hir>> {
self.owners.ensure_contains_elem(def_id, || hir::MaybeOwner::Phantom);
if let hir::MaybeOwner::Phantom = self.owners[def_id] {
let owner = self.owners.ensure_contains_elem(def_id, || hir::MaybeOwner::Phantom);
if let hir::MaybeOwner::Phantom = owner {
let node = self.ast_index[def_id];
match node {
AstOwner::NonOwner => {}
Expand Down
15 changes: 7 additions & 8 deletions compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -368,8 +368,8 @@ fn index_crate<'a>(
krate: &'a Crate,
) -> IndexVec<LocalDefId, AstOwner<'a>> {
let mut indexer = Indexer { node_id_to_def_id, index: IndexVec::new() };
indexer.index.ensure_contains_elem(CRATE_DEF_ID, || AstOwner::NonOwner);
indexer.index[CRATE_DEF_ID] = AstOwner::Crate(krate);
*indexer.index.ensure_contains_elem(CRATE_DEF_ID, || AstOwner::NonOwner) =
AstOwner::Crate(krate);
visit::walk_crate(&mut indexer, krate);
return indexer.index;

Expand All @@ -386,22 +386,21 @@ fn index_crate<'a>(

fn visit_item(&mut self, item: &'a ast::Item) {
let def_id = self.node_id_to_def_id[&item.id];
self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner);
self.index[def_id] = AstOwner::Item(item);
*self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner) = AstOwner::Item(item);
visit::walk_item(self, item)
}

fn visit_assoc_item(&mut self, item: &'a ast::AssocItem, ctxt: visit::AssocCtxt) {
let def_id = self.node_id_to_def_id[&item.id];
self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner);
self.index[def_id] = AstOwner::AssocItem(item, ctxt);
*self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner) =
AstOwner::AssocItem(item, ctxt);
visit::walk_assoc_item(self, item, ctxt);
}

fn visit_foreign_item(&mut self, item: &'a ast::ForeignItem) {
let def_id = self.node_id_to_def_id[&item.id];
self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner);
self.index[def_id] = AstOwner::ForeignItem(item);
*self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner) =
AstOwner::ForeignItem(item);
visit::walk_foreign_item(self, item);
}
}
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -579,7 +579,7 @@ fn compare_asyncness<'tcx>(
pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
tcx: TyCtxt<'tcx>,
impl_m_def_id: LocalDefId,
) -> Result<&'tcx FxHashMap<DefId, Ty<'tcx>>, ErrorGuaranteed> {
) -> Result<&'tcx FxHashMap<DefId, ty::EarlyBinder<Ty<'tcx>>>, ErrorGuaranteed> {
let impl_m = tcx.opt_associated_item(impl_m_def_id.to_def_id()).unwrap();
let trait_m = tcx.opt_associated_item(impl_m.trait_item_def_id.unwrap()).unwrap();
let impl_trait_ref =
Expand Down Expand Up @@ -782,14 +782,14 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
})
});
debug!(%ty);
collected_tys.insert(def_id, ty);
collected_tys.insert(def_id, ty::EarlyBinder(ty));
}
Err(err) => {
let reported = tcx.sess.delay_span_bug(
return_span,
format!("could not fully resolve: {ty} => {err:?}"),
);
collected_tys.insert(def_id, tcx.ty_error(reported));
collected_tys.insert(def_id, ty::EarlyBinder(tcx.ty_error(reported)));
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/collect/type_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
match tcx.collect_return_position_impl_trait_in_trait_tys(fn_def_id) {
Ok(map) => {
let assoc_item = tcx.associated_item(def_id);
return ty::EarlyBinder(map[&assoc_item.trait_item_def_id.unwrap()]);
return map[&assoc_item.trait_item_def_id.unwrap()];
}
Err(_) => {
return ty::EarlyBinder(tcx.ty_error_with_message(
Expand Down
90 changes: 90 additions & 0 deletions compiler/rustc_hir_typeck/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ use rustc_infer::infer;
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_infer::infer::DefineOpaqueTypes;
use rustc_infer::infer::InferOk;
use rustc_infer::traits::query::NoSolution;
use rustc_infer::traits::ObligationCause;
use rustc_middle::middle::stability;
use rustc_middle::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase};
Expand All @@ -53,6 +54,8 @@ use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_target::abi::FieldIdx;
use rustc_target::spec::abi::Abi::RustIntrinsic;
use rustc_trait_selection::infer::InferCtxtExt;
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
use rustc_trait_selection::traits::ObligationCtxt;
use rustc_trait_selection::traits::{self, ObligationCauseCode};

impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
Expand Down Expand Up @@ -2800,6 +2803,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
element_ty
}
None => {
// Attempt to *shallowly* search for an impl which matches,
// but has nested obligations which are unsatisfied.
for (base_t, _) in self.autoderef(base.span, base_t).silence_errors() {
if let Some((_, index_ty, element_ty)) =
self.find_and_report_unsatisfied_index_impl(expr.hir_id, base, base_t)
{
self.demand_coerce(idx, idx_t, index_ty, None, AllowTwoPhase::No);
return element_ty;
}
}

let mut err = type_error_struct!(
self.tcx.sess,
expr.span,
Expand Down Expand Up @@ -2843,6 +2857,82 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}

/// Try to match an implementation of `Index` against a self type, and report
/// the unsatisfied predicates that result from confirming this impl.
///
/// Given an index expression, sometimes the `Self` type shallowly but does not
/// deeply satisfy an impl predicate. Instead of simply saying that the type
/// does not support being indexed, we want to point out exactly what nested
/// predicates cause this to be, so that the user can add them to fix their code.
fn find_and_report_unsatisfied_index_impl(
&self,
index_expr_hir_id: HirId,
base_expr: &hir::Expr<'_>,
base_ty: Ty<'tcx>,
) -> Option<(ErrorGuaranteed, Ty<'tcx>, Ty<'tcx>)> {
let index_trait_def_id = self.tcx.lang_items().index_trait()?;
let index_trait_output_def_id = self.tcx.get_diagnostic_item(sym::IndexOutput)?;

let mut relevant_impls = vec![];
self.tcx.for_each_relevant_impl(index_trait_def_id, base_ty, |impl_def_id| {
relevant_impls.push(impl_def_id);
});
let [impl_def_id] = relevant_impls[..] else {
// Only report unsatisfied impl predicates if there's one impl
return None;
};

self.commit_if_ok(|_| {
let ocx = ObligationCtxt::new_in_snapshot(self);
let impl_substs = self.fresh_substs_for_item(base_expr.span, impl_def_id);
let impl_trait_ref =
self.tcx.impl_trait_ref(impl_def_id).unwrap().subst(self.tcx, impl_substs);
let cause = self.misc(base_expr.span);

// Match the impl self type against the base ty. If this fails,
// we just skip this impl, since it's not particularly useful.
let impl_trait_ref = ocx.normalize(&cause, self.param_env, impl_trait_ref);
ocx.eq(&cause, self.param_env, impl_trait_ref.self_ty(), base_ty)?;

// Register the impl's predicates. One of these predicates
// must be unsatisfied, or else we wouldn't have gotten here
// in the first place.
ocx.register_obligations(traits::predicates_for_generics(
|idx, span| {
traits::ObligationCause::new(
base_expr.span,
self.body_id,
if span.is_dummy() {
traits::ExprItemObligation(impl_def_id, index_expr_hir_id, idx)
} else {
traits::ExprBindingObligation(impl_def_id, span, index_expr_hir_id, idx)
},
)
},
self.param_env,
self.tcx.predicates_of(impl_def_id).instantiate(self.tcx, impl_substs),
));

// Normalize the output type, which we can use later on as the
// return type of the index expression...
let element_ty = ocx.normalize(
&cause,
self.param_env,
self.tcx.mk_projection(index_trait_output_def_id, impl_trait_ref.substs),
);

let errors = ocx.select_where_possible();
// There should be at least one error reported. If not, we
// will still delay a span bug in `report_fulfillment_errors`.
Ok::<_, NoSolution>((
self.err_ctxt().report_fulfillment_errors(&errors),
impl_trait_ref.substs.type_at(1),
element_ty,
))
})
.ok()
}

fn point_at_index_if_possible(
&self,
errors: &mut Vec<traits::FulfillmentError<'tcx>>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -268,8 +268,7 @@ impl DropRangesBuilder {

fn node_mut(&mut self, id: PostOrderId) -> &mut NodeInfo {
let size = self.num_values();
self.nodes.ensure_contains_elem(id, || NodeInfo::new(size));
&mut self.nodes[id]
self.nodes.ensure_contains_elem(id, || NodeInfo::new(size))
}

fn add_control_edge(&mut self, from: PostOrderId, to: PostOrderId) {
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_index/src/interval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -261,8 +261,7 @@ impl<R: Idx, C: Step + Idx> SparseIntervalMatrix<R, C> {
}

fn ensure_row(&mut self, row: R) -> &mut IntervalSet<C> {
self.rows.ensure_contains_elem(row, || IntervalSet::new(self.column_size));
&mut self.rows[row]
self.rows.ensure_contains_elem(row, || IntervalSet::new(self.column_size))
}

pub fn union_row(&mut self, row: R, from: &IntervalSet<C>) -> bool
Expand Down
15 changes: 8 additions & 7 deletions compiler/rustc_index/src/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,12 +236,16 @@ impl<I: Idx, T> IndexVec<I, T> {
/// `elem`; if that is already true, then has no
/// effect. Otherwise, inserts new values as needed by invoking
/// `fill_value`.
///
/// Returns a reference to the `elem` entry.
#[inline]
pub fn ensure_contains_elem(&mut self, elem: I, fill_value: impl FnMut() -> T) {
pub fn ensure_contains_elem(&mut self, elem: I, fill_value: impl FnMut() -> T) -> &mut T {
let min_new_len = elem.index() + 1;
if self.len() < min_new_len {
self.raw.resize_with(min_new_len, fill_value);
}

&mut self[elem]
}

#[inline]
Expand Down Expand Up @@ -446,20 +450,17 @@ impl<I: Idx, J: Idx> IndexSlice<I, J> {
impl<I: Idx, T> IndexVec<I, Option<T>> {
#[inline]
pub fn insert(&mut self, index: I, value: T) -> Option<T> {
self.ensure_contains_elem(index, || None);
self[index].replace(value)
self.ensure_contains_elem(index, || None).replace(value)
}

#[inline]
pub fn get_or_insert_with(&mut self, index: I, value: impl FnOnce() -> T) -> &mut T {
self.ensure_contains_elem(index, || None);
self[index].get_or_insert_with(value)
self.ensure_contains_elem(index, || None).get_or_insert_with(value)
}

#[inline]
pub fn remove(&mut self, index: I) -> Option<T> {
self.ensure_contains_elem(index, || None);
self[index].take()
self.get_mut(index)?.take()
}
}

Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_infer/src/infer/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ use rustc_middle::ty::{
self, error::TypeError, List, Region, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable,
TypeVisitable, TypeVisitableExt,
};
use rustc_span::DUMMY_SP;
use rustc_span::{sym, symbol::kw, BytePos, DesugaringKind, Pos, Span};
use rustc_target::spec::abi;
use std::ops::{ControlFlow, Deref};
Expand Down Expand Up @@ -138,7 +137,7 @@ impl Drop for TypeErrCtxt<'_, '_> {
self.infcx
.tcx
.sess
.delay_span_bug(DUMMY_SP, "used a `TypeErrCtxt` without failing compilation");
.delay_good_path_bug("used a `TypeErrCtxt` without raising an error or lint");
}
}
}
Expand Down
15 changes: 9 additions & 6 deletions compiler/rustc_lint/src/nonstandard_style.rs
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,15 @@ impl<'tcx> LateLintPass<'tcx> for NonUpperCaseGlobals {
hir::ItemKind::Const(..) => {
NonUpperCaseGlobals::check_upper_case(cx, "constant", &it.ident);
}
// we only want to check inherent associated consts, trait consts
// are linted at def-site.
hir::ItemKind::Impl(hir::Impl { of_trait: None, items, .. }) => {
for it in *items {
if let hir::AssocItemKind::Const = it.kind {
NonUpperCaseGlobals::check_upper_case(cx, "associated constant", &it.ident);
}
}
}
_ => {}
}
}
Expand All @@ -504,12 +513,6 @@ impl<'tcx> LateLintPass<'tcx> for NonUpperCaseGlobals {
}
}

fn check_impl_item(&mut self, cx: &LateContext<'_>, ii: &hir::ImplItem<'_>) {
if let hir::ImplItemKind::Const(..) = ii.kind {
NonUpperCaseGlobals::check_upper_case(cx, "associated constant", &ii.ident);
}
}

fn check_pat(&mut self, cx: &LateContext<'_>, p: &hir::Pat<'_>) {
// Lint for constants that look like binding identifiers (#7526)
if let PatKind::Path(hir::QPath::Resolved(None, ref path)) = p.kind {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_metadata/src/rmeta/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,7 @@ define_tables! {
macro_definition: Table<DefIndex, LazyValue<ast::DelimArgs>>,
proc_macro: Table<DefIndex, MacroKind>,
deduced_param_attrs: Table<DefIndex, LazyArray<DeducedParamAttrs>>,
trait_impl_trait_tys: Table<DefIndex, LazyValue<FxHashMap<DefId, Ty<'static>>>>,
trait_impl_trait_tys: Table<DefIndex, LazyValue<FxHashMap<DefId, ty::EarlyBinder<Ty<'static>>>>>,
doc_link_resolutions: Table<DefIndex, LazyValue<DocLinkResMap>>,
doc_link_traits_in_scope: Table<DefIndex, LazyArray<DefId>>,
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_metadata/src/rmeta/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -413,8 +413,8 @@ impl<I: Idx, const N: usize, T: FixedSizeEncoding<ByteArray = [u8; N]>> TableBui
// > Space requirements could perhaps be optimized by using the HAMT `popcnt`
// > trick (i.e. divide things into buckets of 32 or 64 items and then
// > store bit-masks of which item in each bucket is actually serialized).
self.blocks.ensure_contains_elem(i, || [0; N]);
value.write_to_bytes(&mut self.blocks[i]);
let block = self.blocks.ensure_contains_elem(i, || [0; N]);
value.write_to_bytes(block);
}
}

Expand Down
6 changes: 5 additions & 1 deletion compiler/rustc_middle/src/arena.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,11 @@ macro_rules! arena_types {

[] dep_kind: rustc_middle::dep_graph::DepKindStruct<'tcx>,

[decode] trait_impl_trait_tys: rustc_data_structures::fx::FxHashMap<rustc_hir::def_id::DefId, rustc_middle::ty::Ty<'tcx>>,
[decode] trait_impl_trait_tys:
rustc_data_structures::fx::FxHashMap<
rustc_hir::def_id::DefId,
rustc_middle::ty::EarlyBinder<rustc_middle::ty::Ty<'tcx>>
>,
[] bit_set_u32: rustc_index::bit_set::BitSet<u32>,
[] external_constraints: rustc_middle::traits::solve::ExternalConstraintsData<'tcx>,
[decode] doc_link_resolutions: rustc_hir::def::DocLinkResMap,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ rustc_queries! {
}

query collect_return_position_impl_trait_in_trait_tys(key: DefId)
-> Result<&'tcx FxHashMap<DefId, Ty<'tcx>>, ErrorGuaranteed>
-> Result<&'tcx FxHashMap<DefId, ty::EarlyBinder<Ty<'tcx>>>, ErrorGuaranteed>
{
desc { "comparing an impl and trait method signature, inferring any hidden `impl Trait` types in the process" }
cache_on_disk_if { key.is_local() }
Expand Down
7 changes: 0 additions & 7 deletions compiler/rustc_middle/src/ty/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -694,13 +694,6 @@ impl<'tcx> TyCtxt<'tcx> {
if visitor.found_recursion { Err(expanded_type) } else { Ok(expanded_type) }
}

pub fn bound_return_position_impl_trait_in_trait_tys(
self,
def_id: DefId,
) -> ty::EarlyBinder<Result<&'tcx FxHashMap<DefId, Ty<'tcx>>, ErrorGuaranteed>> {
ty::EarlyBinder(self.collect_return_position_impl_trait_in_trait_tys(def_id))
}

pub fn bound_explicit_item_bounds(
self,
def_id: DefId,
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_query_impl/src/on_disk_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -807,7 +807,9 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for &'tcx UnordSet<LocalDefId>
}
}

impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for &'tcx FxHashMap<DefId, Ty<'tcx>> {
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>>
for &'tcx FxHashMap<DefId, ty::EarlyBinder<Ty<'tcx>>>
{
fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self {
RefDecodable::decode(d)
}
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ symbols! {
HashSet,
Hasher,
Implied,
IndexOutput,
Input,
Into,
IntoDiagnostic,
Expand Down
Loading

0 comments on commit c781584

Please sign in to comment.