Skip to content

Commit c781584

Browse files
committed
Auto merge of rust-lang#110522 - matthiaskrgr:rollup-9m7rw3u, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - rust-lang#110432 (Report more detailed reason why `Index` impl is not satisfied) - rust-lang#110451 (Minor changes to `IndexVec::ensure_contains_elem` & related methods) - rust-lang#110476 (Delay a good path bug on drop for `TypeErrCtxt` (instead of a regular delayed bug)) - rust-lang#110498 (Switch to `EarlyBinder` for `collect_return_position_impl_trait_in_trait_tys`) - rust-lang#110507 (boostrap: print output during building tools) - rust-lang#110510 (Fix ICE for transmutability in candidate assembly) - rust-lang#110513 (make `non_upper_case_globals` lint not report trait impls) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 9e7f72c + 78490ad commit c781584

File tree

28 files changed

+303
-57
lines changed

28 files changed

+303
-57
lines changed

compiler/rustc_ast_lowering/src/item.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -89,18 +89,18 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
8989
lctx.with_hir_id_owner(owner, |lctx| f(lctx));
9090

9191
for (def_id, info) in lctx.children {
92-
self.owners.ensure_contains_elem(def_id, || hir::MaybeOwner::Phantom);
93-
debug_assert!(matches!(self.owners[def_id], hir::MaybeOwner::Phantom));
94-
self.owners[def_id] = info;
92+
let owner = self.owners.ensure_contains_elem(def_id, || hir::MaybeOwner::Phantom);
93+
debug_assert!(matches!(owner, hir::MaybeOwner::Phantom));
94+
*owner = info;
9595
}
9696
}
9797

9898
pub(super) fn lower_node(
9999
&mut self,
100100
def_id: LocalDefId,
101101
) -> hir::MaybeOwner<&'hir hir::OwnerInfo<'hir>> {
102-
self.owners.ensure_contains_elem(def_id, || hir::MaybeOwner::Phantom);
103-
if let hir::MaybeOwner::Phantom = self.owners[def_id] {
102+
let owner = self.owners.ensure_contains_elem(def_id, || hir::MaybeOwner::Phantom);
103+
if let hir::MaybeOwner::Phantom = owner {
104104
let node = self.ast_index[def_id];
105105
match node {
106106
AstOwner::NonOwner => {}

compiler/rustc_ast_lowering/src/lib.rs

+7-8
Original file line numberDiff line numberDiff line change
@@ -368,8 +368,8 @@ fn index_crate<'a>(
368368
krate: &'a Crate,
369369
) -> IndexVec<LocalDefId, AstOwner<'a>> {
370370
let mut indexer = Indexer { node_id_to_def_id, index: IndexVec::new() };
371-
indexer.index.ensure_contains_elem(CRATE_DEF_ID, || AstOwner::NonOwner);
372-
indexer.index[CRATE_DEF_ID] = AstOwner::Crate(krate);
371+
*indexer.index.ensure_contains_elem(CRATE_DEF_ID, || AstOwner::NonOwner) =
372+
AstOwner::Crate(krate);
373373
visit::walk_crate(&mut indexer, krate);
374374
return indexer.index;
375375

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

387387
fn visit_item(&mut self, item: &'a ast::Item) {
388388
let def_id = self.node_id_to_def_id[&item.id];
389-
self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner);
390-
self.index[def_id] = AstOwner::Item(item);
389+
*self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner) = AstOwner::Item(item);
391390
visit::walk_item(self, item)
392391
}
393392

394393
fn visit_assoc_item(&mut self, item: &'a ast::AssocItem, ctxt: visit::AssocCtxt) {
395394
let def_id = self.node_id_to_def_id[&item.id];
396-
self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner);
397-
self.index[def_id] = AstOwner::AssocItem(item, ctxt);
395+
*self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner) =
396+
AstOwner::AssocItem(item, ctxt);
398397
visit::walk_assoc_item(self, item, ctxt);
399398
}
400399

401400
fn visit_foreign_item(&mut self, item: &'a ast::ForeignItem) {
402401
let def_id = self.node_id_to_def_id[&item.id];
403-
self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner);
404-
self.index[def_id] = AstOwner::ForeignItem(item);
402+
*self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner) =
403+
AstOwner::ForeignItem(item);
405404
visit::walk_foreign_item(self, item);
406405
}
407406
}

compiler/rustc_hir_analysis/src/check/compare_impl_item.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -579,7 +579,7 @@ fn compare_asyncness<'tcx>(
579579
pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
580580
tcx: TyCtxt<'tcx>,
581581
impl_m_def_id: LocalDefId,
582-
) -> Result<&'tcx FxHashMap<DefId, Ty<'tcx>>, ErrorGuaranteed> {
582+
) -> Result<&'tcx FxHashMap<DefId, ty::EarlyBinder<Ty<'tcx>>>, ErrorGuaranteed> {
583583
let impl_m = tcx.opt_associated_item(impl_m_def_id.to_def_id()).unwrap();
584584
let trait_m = tcx.opt_associated_item(impl_m.trait_item_def_id.unwrap()).unwrap();
585585
let impl_trait_ref =
@@ -782,14 +782,14 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
782782
})
783783
});
784784
debug!(%ty);
785-
collected_tys.insert(def_id, ty);
785+
collected_tys.insert(def_id, ty::EarlyBinder(ty));
786786
}
787787
Err(err) => {
788788
let reported = tcx.sess.delay_span_bug(
789789
return_span,
790790
format!("could not fully resolve: {ty} => {err:?}"),
791791
);
792-
collected_tys.insert(def_id, tcx.ty_error(reported));
792+
collected_tys.insert(def_id, ty::EarlyBinder(tcx.ty_error(reported)));
793793
}
794794
}
795795
}

compiler/rustc_hir_analysis/src/collect/type_of.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
251251
match tcx.collect_return_position_impl_trait_in_trait_tys(fn_def_id) {
252252
Ok(map) => {
253253
let assoc_item = tcx.associated_item(def_id);
254-
return ty::EarlyBinder(map[&assoc_item.trait_item_def_id.unwrap()]);
254+
return map[&assoc_item.trait_item_def_id.unwrap()];
255255
}
256256
Err(_) => {
257257
return ty::EarlyBinder(tcx.ty_error_with_message(

compiler/rustc_hir_typeck/src/expr.rs

+90
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ use rustc_infer::infer;
3838
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
3939
use rustc_infer::infer::DefineOpaqueTypes;
4040
use rustc_infer::infer::InferOk;
41+
use rustc_infer::traits::query::NoSolution;
4142
use rustc_infer::traits::ObligationCause;
4243
use rustc_middle::middle::stability;
4344
use rustc_middle::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase};
@@ -53,6 +54,8 @@ use rustc_span::symbol::{kw, sym, Ident, Symbol};
5354
use rustc_target::abi::FieldIdx;
5455
use rustc_target::spec::abi::Abi::RustIntrinsic;
5556
use rustc_trait_selection::infer::InferCtxtExt;
57+
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
58+
use rustc_trait_selection::traits::ObligationCtxt;
5659
use rustc_trait_selection::traits::{self, ObligationCauseCode};
5760

5861
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
@@ -2800,6 +2803,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
28002803
element_ty
28012804
}
28022805
None => {
2806+
// Attempt to *shallowly* search for an impl which matches,
2807+
// but has nested obligations which are unsatisfied.
2808+
for (base_t, _) in self.autoderef(base.span, base_t).silence_errors() {
2809+
if let Some((_, index_ty, element_ty)) =
2810+
self.find_and_report_unsatisfied_index_impl(expr.hir_id, base, base_t)
2811+
{
2812+
self.demand_coerce(idx, idx_t, index_ty, None, AllowTwoPhase::No);
2813+
return element_ty;
2814+
}
2815+
}
2816+
28032817
let mut err = type_error_struct!(
28042818
self.tcx.sess,
28052819
expr.span,
@@ -2843,6 +2857,82 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
28432857
}
28442858
}
28452859

2860+
/// Try to match an implementation of `Index` against a self type, and report
2861+
/// the unsatisfied predicates that result from confirming this impl.
2862+
///
2863+
/// Given an index expression, sometimes the `Self` type shallowly but does not
2864+
/// deeply satisfy an impl predicate. Instead of simply saying that the type
2865+
/// does not support being indexed, we want to point out exactly what nested
2866+
/// predicates cause this to be, so that the user can add them to fix their code.
2867+
fn find_and_report_unsatisfied_index_impl(
2868+
&self,
2869+
index_expr_hir_id: HirId,
2870+
base_expr: &hir::Expr<'_>,
2871+
base_ty: Ty<'tcx>,
2872+
) -> Option<(ErrorGuaranteed, Ty<'tcx>, Ty<'tcx>)> {
2873+
let index_trait_def_id = self.tcx.lang_items().index_trait()?;
2874+
let index_trait_output_def_id = self.tcx.get_diagnostic_item(sym::IndexOutput)?;
2875+
2876+
let mut relevant_impls = vec![];
2877+
self.tcx.for_each_relevant_impl(index_trait_def_id, base_ty, |impl_def_id| {
2878+
relevant_impls.push(impl_def_id);
2879+
});
2880+
let [impl_def_id] = relevant_impls[..] else {
2881+
// Only report unsatisfied impl predicates if there's one impl
2882+
return None;
2883+
};
2884+
2885+
self.commit_if_ok(|_| {
2886+
let ocx = ObligationCtxt::new_in_snapshot(self);
2887+
let impl_substs = self.fresh_substs_for_item(base_expr.span, impl_def_id);
2888+
let impl_trait_ref =
2889+
self.tcx.impl_trait_ref(impl_def_id).unwrap().subst(self.tcx, impl_substs);
2890+
let cause = self.misc(base_expr.span);
2891+
2892+
// Match the impl self type against the base ty. If this fails,
2893+
// we just skip this impl, since it's not particularly useful.
2894+
let impl_trait_ref = ocx.normalize(&cause, self.param_env, impl_trait_ref);
2895+
ocx.eq(&cause, self.param_env, impl_trait_ref.self_ty(), base_ty)?;
2896+
2897+
// Register the impl's predicates. One of these predicates
2898+
// must be unsatisfied, or else we wouldn't have gotten here
2899+
// in the first place.
2900+
ocx.register_obligations(traits::predicates_for_generics(
2901+
|idx, span| {
2902+
traits::ObligationCause::new(
2903+
base_expr.span,
2904+
self.body_id,
2905+
if span.is_dummy() {
2906+
traits::ExprItemObligation(impl_def_id, index_expr_hir_id, idx)
2907+
} else {
2908+
traits::ExprBindingObligation(impl_def_id, span, index_expr_hir_id, idx)
2909+
},
2910+
)
2911+
},
2912+
self.param_env,
2913+
self.tcx.predicates_of(impl_def_id).instantiate(self.tcx, impl_substs),
2914+
));
2915+
2916+
// Normalize the output type, which we can use later on as the
2917+
// return type of the index expression...
2918+
let element_ty = ocx.normalize(
2919+
&cause,
2920+
self.param_env,
2921+
self.tcx.mk_projection(index_trait_output_def_id, impl_trait_ref.substs),
2922+
);
2923+
2924+
let errors = ocx.select_where_possible();
2925+
// There should be at least one error reported. If not, we
2926+
// will still delay a span bug in `report_fulfillment_errors`.
2927+
Ok::<_, NoSolution>((
2928+
self.err_ctxt().report_fulfillment_errors(&errors),
2929+
impl_trait_ref.substs.type_at(1),
2930+
element_ty,
2931+
))
2932+
})
2933+
.ok()
2934+
}
2935+
28462936
fn point_at_index_if_possible(
28472937
&self,
28482938
errors: &mut Vec<traits::FulfillmentError<'tcx>>,

compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/mod.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -268,8 +268,7 @@ impl DropRangesBuilder {
268268

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

275274
fn add_control_edge(&mut self, from: PostOrderId, to: PostOrderId) {

compiler/rustc_index/src/interval.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -261,8 +261,7 @@ impl<R: Idx, C: Step + Idx> SparseIntervalMatrix<R, C> {
261261
}
262262

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

268267
pub fn union_row(&mut self, row: R, from: &IntervalSet<C>) -> bool

compiler/rustc_index/src/vec.rs

+8-7
Original file line numberDiff line numberDiff line change
@@ -236,12 +236,16 @@ impl<I: Idx, T> IndexVec<I, T> {
236236
/// `elem`; if that is already true, then has no
237237
/// effect. Otherwise, inserts new values as needed by invoking
238238
/// `fill_value`.
239+
///
240+
/// Returns a reference to the `elem` entry.
239241
#[inline]
240-
pub fn ensure_contains_elem(&mut self, elem: I, fill_value: impl FnMut() -> T) {
242+
pub fn ensure_contains_elem(&mut self, elem: I, fill_value: impl FnMut() -> T) -> &mut T {
241243
let min_new_len = elem.index() + 1;
242244
if self.len() < min_new_len {
243245
self.raw.resize_with(min_new_len, fill_value);
244246
}
247+
248+
&mut self[elem]
245249
}
246250

247251
#[inline]
@@ -446,20 +450,17 @@ impl<I: Idx, J: Idx> IndexSlice<I, J> {
446450
impl<I: Idx, T> IndexVec<I, Option<T>> {
447451
#[inline]
448452
pub fn insert(&mut self, index: I, value: T) -> Option<T> {
449-
self.ensure_contains_elem(index, || None);
450-
self[index].replace(value)
453+
self.ensure_contains_elem(index, || None).replace(value)
451454
}
452455

453456
#[inline]
454457
pub fn get_or_insert_with(&mut self, index: I, value: impl FnOnce() -> T) -> &mut T {
455-
self.ensure_contains_elem(index, || None);
456-
self[index].get_or_insert_with(value)
458+
self.ensure_contains_elem(index, || None).get_or_insert_with(value)
457459
}
458460

459461
#[inline]
460462
pub fn remove(&mut self, index: I) -> Option<T> {
461-
self.ensure_contains_elem(index, || None);
462-
self[index].take()
463+
self.get_mut(index)?.take()
463464
}
464465
}
465466

compiler/rustc_infer/src/infer/error_reporting/mod.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@ use rustc_middle::ty::{
7474
self, error::TypeError, List, Region, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable,
7575
TypeVisitable, TypeVisitableExt,
7676
};
77-
use rustc_span::DUMMY_SP;
7877
use rustc_span::{sym, symbol::kw, BytePos, DesugaringKind, Pos, Span};
7978
use rustc_target::spec::abi;
8079
use std::ops::{ControlFlow, Deref};
@@ -138,7 +137,7 @@ impl Drop for TypeErrCtxt<'_, '_> {
138137
self.infcx
139138
.tcx
140139
.sess
141-
.delay_span_bug(DUMMY_SP, "used a `TypeErrCtxt` without failing compilation");
140+
.delay_good_path_bug("used a `TypeErrCtxt` without raising an error or lint");
142141
}
143142
}
144143
}

compiler/rustc_lint/src/nonstandard_style.rs

+9-6
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,15 @@ impl<'tcx> LateLintPass<'tcx> for NonUpperCaseGlobals {
494494
hir::ItemKind::Const(..) => {
495495
NonUpperCaseGlobals::check_upper_case(cx, "constant", &it.ident);
496496
}
497+
// we only want to check inherent associated consts, trait consts
498+
// are linted at def-site.
499+
hir::ItemKind::Impl(hir::Impl { of_trait: None, items, .. }) => {
500+
for it in *items {
501+
if let hir::AssocItemKind::Const = it.kind {
502+
NonUpperCaseGlobals::check_upper_case(cx, "associated constant", &it.ident);
503+
}
504+
}
505+
}
497506
_ => {}
498507
}
499508
}
@@ -504,12 +513,6 @@ impl<'tcx> LateLintPass<'tcx> for NonUpperCaseGlobals {
504513
}
505514
}
506515

507-
fn check_impl_item(&mut self, cx: &LateContext<'_>, ii: &hir::ImplItem<'_>) {
508-
if let hir::ImplItemKind::Const(..) = ii.kind {
509-
NonUpperCaseGlobals::check_upper_case(cx, "associated constant", &ii.ident);
510-
}
511-
}
512-
513516
fn check_pat(&mut self, cx: &LateContext<'_>, p: &hir::Pat<'_>) {
514517
// Lint for constants that look like binding identifiers (#7526)
515518
if let PatKind::Path(hir::QPath::Resolved(None, ref path)) = p.kind {

compiler/rustc_metadata/src/rmeta/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -416,7 +416,7 @@ define_tables! {
416416
macro_definition: Table<DefIndex, LazyValue<ast::DelimArgs>>,
417417
proc_macro: Table<DefIndex, MacroKind>,
418418
deduced_param_attrs: Table<DefIndex, LazyArray<DeducedParamAttrs>>,
419-
trait_impl_trait_tys: Table<DefIndex, LazyValue<FxHashMap<DefId, Ty<'static>>>>,
419+
trait_impl_trait_tys: Table<DefIndex, LazyValue<FxHashMap<DefId, ty::EarlyBinder<Ty<'static>>>>>,
420420
doc_link_resolutions: Table<DefIndex, LazyValue<DocLinkResMap>>,
421421
doc_link_traits_in_scope: Table<DefIndex, LazyArray<DefId>>,
422422
}

compiler/rustc_metadata/src/rmeta/table.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -413,8 +413,8 @@ impl<I: Idx, const N: usize, T: FixedSizeEncoding<ByteArray = [u8; N]>> TableBui
413413
// > Space requirements could perhaps be optimized by using the HAMT `popcnt`
414414
// > trick (i.e. divide things into buckets of 32 or 64 items and then
415415
// > store bit-masks of which item in each bucket is actually serialized).
416-
self.blocks.ensure_contains_elem(i, || [0; N]);
417-
value.write_to_bytes(&mut self.blocks[i]);
416+
let block = self.blocks.ensure_contains_elem(i, || [0; N]);
417+
value.write_to_bytes(block);
418418
}
419419
}
420420

compiler/rustc_middle/src/arena.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,11 @@ macro_rules! arena_types {
114114

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

117-
[decode] trait_impl_trait_tys: rustc_data_structures::fx::FxHashMap<rustc_hir::def_id::DefId, rustc_middle::ty::Ty<'tcx>>,
117+
[decode] trait_impl_trait_tys:
118+
rustc_data_structures::fx::FxHashMap<
119+
rustc_hir::def_id::DefId,
120+
rustc_middle::ty::EarlyBinder<rustc_middle::ty::Ty<'tcx>>
121+
>,
118122
[] bit_set_u32: rustc_index::bit_set::BitSet<u32>,
119123
[] external_constraints: rustc_middle::traits::solve::ExternalConstraintsData<'tcx>,
120124
[decode] doc_link_resolutions: rustc_hir::def::DocLinkResMap,

compiler/rustc_middle/src/query/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ rustc_queries! {
181181
}
182182

183183
query collect_return_position_impl_trait_in_trait_tys(key: DefId)
184-
-> Result<&'tcx FxHashMap<DefId, Ty<'tcx>>, ErrorGuaranteed>
184+
-> Result<&'tcx FxHashMap<DefId, ty::EarlyBinder<Ty<'tcx>>>, ErrorGuaranteed>
185185
{
186186
desc { "comparing an impl and trait method signature, inferring any hidden `impl Trait` types in the process" }
187187
cache_on_disk_if { key.is_local() }

compiler/rustc_middle/src/ty/util.rs

-7
Original file line numberDiff line numberDiff line change
@@ -694,13 +694,6 @@ impl<'tcx> TyCtxt<'tcx> {
694694
if visitor.found_recursion { Err(expanded_type) } else { Ok(expanded_type) }
695695
}
696696

697-
pub fn bound_return_position_impl_trait_in_trait_tys(
698-
self,
699-
def_id: DefId,
700-
) -> ty::EarlyBinder<Result<&'tcx FxHashMap<DefId, Ty<'tcx>>, ErrorGuaranteed>> {
701-
ty::EarlyBinder(self.collect_return_position_impl_trait_in_trait_tys(def_id))
702-
}
703-
704697
pub fn bound_explicit_item_bounds(
705698
self,
706699
def_id: DefId,

compiler/rustc_query_impl/src/on_disk_cache.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -807,7 +807,9 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for &'tcx UnordSet<LocalDefId>
807807
}
808808
}
809809

810-
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for &'tcx FxHashMap<DefId, Ty<'tcx>> {
810+
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>>
811+
for &'tcx FxHashMap<DefId, ty::EarlyBinder<Ty<'tcx>>>
812+
{
811813
fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self {
812814
RefDecodable::decode(d)
813815
}

compiler/rustc_span/src/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ symbols! {
204204
HashSet,
205205
Hasher,
206206
Implied,
207+
IndexOutput,
207208
Input,
208209
Into,
209210
IntoDiagnostic,

0 commit comments

Comments
 (0)