Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit c7377f6

Browse files
committedNov 23, 2024
Auto merge of rust-lang#133392 - compiler-errors:object-sup, r=<try>
Fix ICE when multiple supertrait substitutions need assoc but only one is provided I'll write more here when the crate run is done. Fixes rust-lang#133388 r? lcnr `@rustbot` author
2 parents 826b673 + 8a10f68 commit c7377f6

30 files changed

+249
-648
lines changed
 

‎compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs

+44-31
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
1-
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
1+
use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
22
use rustc_errors::codes::*;
33
use rustc_errors::struct_span_code_err;
44
use rustc_hir as hir;
55
use rustc_hir::def::{DefKind, Res};
6-
use rustc_hir::def_id::DefId;
76
use rustc_lint_defs::builtin::UNUSED_ASSOCIATED_TYPE_BOUNDS;
87
use rustc_middle::span_bug;
98
use rustc_middle::ty::fold::BottomUpFolder;
109
use rustc_middle::ty::{
11-
self, DynKind, ExistentialPredicateStableCmpExt as _, Ty, TyCtxt, TypeFoldable, Upcast,
10+
self, DynKind, ExistentialPredicateStableCmpExt as _, Ty, TyCtxt, TypeFoldable,
11+
TypeVisitableExt, Upcast,
1212
};
13-
use rustc_span::{ErrorGuaranteed, Span};
13+
use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span};
1414
use rustc_trait_selection::error_reporting::traits::report_dyn_incompatibility;
1515
use rustc_trait_selection::traits::{self, hir_ty_lowering_dyn_compatibility_violations};
1616
use rustc_type_ir::elaborate::ClauseWithSupertraitSpan;
@@ -92,11 +92,20 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
9292

9393
let (mut auto_traits, regular_traits): (Vec<_>, Vec<_>) =
9494
expanded_traits.partition(|i| tcx.trait_is_auto(i.trait_ref().def_id()));
95+
96+
// We don't support >1 principal
9597
if regular_traits.len() > 1 {
96-
let _ = self.report_trait_object_addition_traits_error(&regular_traits);
97-
} else if regular_traits.is_empty() && auto_traits.is_empty() {
98-
let reported = self.report_trait_object_with_no_traits_error(span, &trait_bounds);
99-
return Ty::new_error(tcx, reported);
98+
let guar = self.report_trait_object_addition_traits_error(&regular_traits);
99+
return Ty::new_error(tcx, guar);
100+
}
101+
// We don't support empty trait objects.
102+
if regular_traits.is_empty() && auto_traits.is_empty() {
103+
let guar = self.report_trait_object_with_no_traits_error(span, &trait_bounds);
104+
return Ty::new_error(tcx, guar);
105+
}
106+
// Don't create a dyn trait if we have errors in the principal.
107+
if let Err(guar) = trait_bounds.error_reported() {
108+
return Ty::new_error(tcx, guar);
100109
}
101110

102111
// Check that there are no gross dyn-compatibility violations;
@@ -118,15 +127,16 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
118127
}
119128
}
120129

121-
let mut associated_types: FxIndexMap<Span, FxIndexSet<DefId>> = FxIndexMap::default();
130+
let mut needed_associated_types = FxIndexSet::default();
122131

132+
let principal_span = regular_traits.first().map_or(DUMMY_SP, |info| info.bottom().1);
123133
let regular_traits_refs_spans = trait_bounds
124134
.into_iter()
125135
.filter(|(trait_ref, _)| !tcx.trait_is_auto(trait_ref.def_id()));
126136

127137
for (base_trait_ref, original_span) in regular_traits_refs_spans {
128138
let base_pred: ty::Predicate<'tcx> = base_trait_ref.upcast(tcx);
129-
for ClauseWithSupertraitSpan { pred, original_span, supertrait_span } in
139+
for ClauseWithSupertraitSpan { pred, supertrait_span } in
130140
traits::elaborate(tcx, [ClauseWithSupertraitSpan::new(base_pred, original_span)])
131141
.filter_only_self()
132142
{
@@ -135,13 +145,18 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
135145
let bound_predicate = pred.kind();
136146
match bound_predicate.skip_binder() {
137147
ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred)) => {
138-
let pred = bound_predicate.rebind(pred);
139-
associated_types.entry(original_span).or_default().extend(
140-
tcx.associated_items(pred.def_id())
148+
// FIXME(negative_bounds): Handle this correctly...
149+
let trait_ref =
150+
tcx.anonymize_bound_vars(bound_predicate.rebind(pred.trait_ref));
151+
needed_associated_types.extend(
152+
tcx.associated_items(trait_ref.def_id())
141153
.in_definition_order()
142154
.filter(|item| item.kind == ty::AssocKind::Type)
143155
.filter(|item| !item.is_impl_trait_in_trait())
144-
.map(|item| item.def_id),
156+
// If the associated type has a `where Self: Sized` bound,
157+
// we do not need to constrain the associated type.
158+
.filter(|item| !tcx.generics_require_sized_self(item.def_id))
159+
.map(|item| (item.def_id, trait_ref)),
145160
);
146161
}
147162
ty::PredicateKind::Clause(ty::ClauseKind::Projection(pred)) => {
@@ -191,27 +206,25 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
191206
// So every `Projection` clause is an `Assoc = Foo` bound. `associated_types` contains all associated
192207
// types's `DefId`, so the following loop removes all the `DefIds` of the associated types that have a
193208
// corresponding `Projection` clause
194-
for def_ids in associated_types.values_mut() {
195-
for (projection_bound, span) in &projection_bounds {
196-
let def_id = projection_bound.projection_def_id();
197-
// FIXME(#120456) - is `swap_remove` correct?
198-
def_ids.swap_remove(&def_id);
199-
if tcx.generics_require_sized_self(def_id) {
200-
tcx.emit_node_span_lint(
201-
UNUSED_ASSOCIATED_TYPE_BOUNDS,
202-
hir_id,
203-
*span,
204-
crate::errors::UnusedAssociatedTypeBounds { span: *span },
205-
);
206-
}
209+
for (projection_bound, span) in &projection_bounds {
210+
let def_id = projection_bound.projection_def_id();
211+
let trait_ref = tcx.anonymize_bound_vars(
212+
projection_bound.map_bound(|p| p.projection_term.trait_ref(tcx)),
213+
);
214+
needed_associated_types.swap_remove(&(def_id, trait_ref));
215+
if tcx.generics_require_sized_self(def_id) {
216+
tcx.emit_node_span_lint(
217+
UNUSED_ASSOCIATED_TYPE_BOUNDS,
218+
hir_id,
219+
*span,
220+
crate::errors::UnusedAssociatedTypeBounds { span: *span },
221+
);
207222
}
208-
// If the associated type has a `where Self: Sized` bound, we do not need to constrain the associated
209-
// type in the `dyn Trait`.
210-
def_ids.retain(|def_id| !tcx.generics_require_sized_self(def_id));
211223
}
212224

213225
self.complain_about_missing_assoc_tys(
214-
associated_types,
226+
principal_span,
227+
needed_associated_types,
215228
potential_assoc_types,
216229
hir_trait_bounds,
217230
);
There was a problem loading the remainder of the diff.

0 commit comments

Comments
 (0)
Failed to load comments.