Skip to content

Commit f7e3a77

Browse files
committed
Auto merge of rust-lang#121500 - oli-obk:track_errors12, r=<try>
Merge `collect_mod_item_types` query into `check_well_formed` follow-up to rust-lang#121154 r? `@ghost`
2 parents 6dadb6e + 62bc4bd commit f7e3a77

File tree

121 files changed

+1737
-1283
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

121 files changed

+1737
-1283
lines changed

compiler/rustc_hir_analysis/src/check/wfcheck.rs

+22-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
use crate::autoderef::Autoderef;
2+
use crate::collect::CollectItemTypesVisitor;
23
use crate::constrained_generic_params::{identify_constrained_generic_params, Parameter};
34
use crate::errors;
45

6+
use hir::intravisit::Visitor;
57
use rustc_ast as ast;
68
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
79
use rustc_errors::{codes::*, pluralize, struct_span_code_err, Applicability, ErrorGuaranteed};
@@ -225,6 +227,7 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<()
225227
?item.owner_id,
226228
item.name = ? tcx.def_path_str(def_id)
227229
);
230+
CollectItemTypesVisitor { tcx }.visit_item(item);
228231

229232
let res = match item.kind {
230233
// Right now we check that every default trait implementation
@@ -248,6 +251,8 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<()
248251
let header = tcx.impl_trait_header(def_id);
249252
let is_auto = header
250253
.is_some_and(|header| tcx.trait_is_auto(header.skip_binder().trait_ref.def_id));
254+
255+
crate::impl_wf_check::check_impl_wf(tcx, def_id)?;
251256
let mut res = Ok(());
252257
if let (hir::Defaultness::Default { .. }, true) = (impl_.defaultness, is_auto) {
253258
let sp = impl_.of_trait.as_ref().map_or(item.span, |t| t.path.span);
@@ -334,9 +339,14 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<()
334339
res
335340
}
336341

337-
fn check_foreign_item(tcx: TyCtxt<'_>, item: &hir::ForeignItem<'_>) -> Result<(), ErrorGuaranteed> {
342+
fn check_foreign_item<'tcx>(
343+
tcx: TyCtxt<'tcx>,
344+
item: &'tcx hir::ForeignItem<'tcx>,
345+
) -> Result<(), ErrorGuaranteed> {
338346
let def_id = item.owner_id.def_id;
339347

348+
CollectItemTypesVisitor { tcx }.visit_foreign_item(item);
349+
340350
debug!(
341351
?item.owner_id,
342352
item.name = ? tcx.def_path_str(def_id)
@@ -353,12 +363,14 @@ fn check_foreign_item(tcx: TyCtxt<'_>, item: &hir::ForeignItem<'_>) -> Result<()
353363
}
354364
}
355365

356-
fn check_trait_item(
357-
tcx: TyCtxt<'_>,
358-
trait_item: &hir::TraitItem<'_>,
366+
fn check_trait_item<'tcx>(
367+
tcx: TyCtxt<'tcx>,
368+
trait_item: &'tcx hir::TraitItem<'tcx>,
359369
) -> Result<(), ErrorGuaranteed> {
360370
let def_id = trait_item.owner_id.def_id;
361371

372+
CollectItemTypesVisitor { tcx }.visit_trait_item(trait_item);
373+
362374
let (method_sig, span) = match trait_item.kind {
363375
hir::TraitItemKind::Fn(ref sig, _) => (Some(sig), trait_item.span),
364376
hir::TraitItemKind::Type(_bounds, Some(ty)) => (None, ty.span),
@@ -895,7 +907,12 @@ fn check_object_unsafe_self_trait_by_name(tcx: TyCtxt<'_>, item: &hir::TraitItem
895907
}
896908
}
897909

898-
fn check_impl_item(tcx: TyCtxt<'_>, impl_item: &hir::ImplItem<'_>) -> Result<(), ErrorGuaranteed> {
910+
fn check_impl_item<'tcx>(
911+
tcx: TyCtxt<'tcx>,
912+
impl_item: &'tcx hir::ImplItem<'tcx>,
913+
) -> Result<(), ErrorGuaranteed> {
914+
CollectItemTypesVisitor { tcx }.visit_impl_item(impl_item);
915+
899916
let (method_sig, span) = match impl_item.kind {
900917
hir::ImplItemKind::Fn(ref sig, _) => (Some(sig), impl_item.span),
901918
// Constrain binding and overflow error spans to `<Ty>` in `type foo = <Ty>`.

compiler/rustc_hir_analysis/src/collect.rs

+16-10
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use rustc_data_structures::unord::UnordMap;
2020
use rustc_errors::{Applicability, DiagnosticBuilder, ErrorGuaranteed, StashKey};
2121
use rustc_hir as hir;
2222
use rustc_hir::def::DefKind;
23-
use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId};
23+
use rustc_hir::def_id::{DefId, LocalDefId};
2424
use rustc_hir::intravisit::{self, Visitor};
2525
use rustc_hir::{GenericParamKind, Node};
2626
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
@@ -52,11 +52,6 @@ mod resolve_bound_vars;
5252
mod type_of;
5353

5454
///////////////////////////////////////////////////////////////////////////
55-
// Main entry point
56-
57-
fn collect_mod_item_types(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) {
58-
tcx.hir().visit_item_likes_in_module(module_def_id, &mut CollectItemTypesVisitor { tcx });
59-
}
6055

6156
pub fn provide(providers: &mut Providers) {
6257
resolve_bound_vars::provide(providers);
@@ -82,7 +77,6 @@ pub fn provide(providers: &mut Providers) {
8277
impl_trait_header,
8378
coroutine_kind,
8479
coroutine_for_closure,
85-
collect_mod_item_types,
8680
is_type_alias_impl_trait,
8781
find_field,
8882
..*providers
@@ -155,8 +149,8 @@ impl<'v> Visitor<'v> for HirPlaceholderCollector {
155149
}
156150
}
157151

158-
struct CollectItemTypesVisitor<'tcx> {
159-
tcx: TyCtxt<'tcx>,
152+
pub struct CollectItemTypesVisitor<'tcx> {
153+
pub tcx: TyCtxt<'tcx>,
160154
}
161155

162156
/// If there are any placeholder types (`_`), emit an error explaining that this is not allowed
@@ -1025,7 +1019,19 @@ fn adt_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::AdtDef<'_> {
10251019

10261020
let is_anonymous = item.ident.name == kw::Empty;
10271021
let repr = if is_anonymous {
1028-
tcx.adt_def(tcx.local_parent(def_id)).repr()
1022+
let mut def_id = def_id;
1023+
loop {
1024+
def_id = tcx.local_parent(def_id);
1025+
if let Node::Item(_) = tcx.hir_node_by_def_id(def_id) {
1026+
break;
1027+
} else {
1028+
tcx.dcx().span_delayed_bug(
1029+
tcx.def_span(def_id),
1030+
"invalid anonymous adt position, already got rejected in ast validation",
1031+
);
1032+
}
1033+
}
1034+
tcx.adt_def(def_id).repr()
10291035
} else {
10301036
tcx.repr_options_of_def(def_id)
10311037
};

compiler/rustc_hir_analysis/src/impl_wf_check.rs

+7-15
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@ use min_specialization::check_min_specialization;
1414
use rustc_data_structures::fx::FxHashSet;
1515
use rustc_errors::{codes::*, struct_span_code_err};
1616
use rustc_hir::def::DefKind;
17-
use rustc_hir::def_id::{LocalDefId, LocalModDefId};
18-
use rustc_middle::query::Providers;
17+
use rustc_hir::def_id::LocalDefId;
1918
use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
2019
use rustc_span::{ErrorGuaranteed, Span, Symbol};
2120

@@ -51,23 +50,16 @@ mod min_specialization;
5150
/// impl<'a> Trait<Foo> for Bar { type X = &'a i32; }
5251
/// // ^ 'a is unused and appears in assoc type, error
5352
/// ```
54-
fn check_mod_impl_wf(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) -> Result<(), ErrorGuaranteed> {
53+
pub fn check_impl_wf(tcx: TyCtxt<'_>, impl_def_id: LocalDefId) -> Result<(), ErrorGuaranteed> {
5554
let min_specialization = tcx.features().min_specialization;
56-
let module = tcx.hir_module_items(module_def_id);
5755
let mut res = Ok(());
58-
for id in module.items() {
59-
if matches!(tcx.def_kind(id.owner_id), DefKind::Impl { .. }) {
60-
res = res.and(enforce_impl_params_are_constrained(tcx, id.owner_id.def_id));
61-
if min_specialization {
62-
res = res.and(check_min_specialization(tcx, id.owner_id.def_id));
63-
}
64-
}
56+
debug_assert!(matches!(tcx.def_kind(impl_def_id), DefKind::Impl { .. }));
57+
res = res.and(enforce_impl_params_are_constrained(tcx, impl_def_id));
58+
if min_specialization {
59+
res = res.and(check_min_specialization(tcx, impl_def_id));
6560
}
66-
res
67-
}
6861

69-
pub fn provide(providers: &mut Providers) {
70-
*providers = Providers { check_mod_impl_wf, ..*providers };
62+
res
7163
}
7264

7365
fn enforce_impl_params_are_constrained(

compiler/rustc_hir_analysis/src/lib.rs

+4-18
Original file line numberDiff line numberDiff line change
@@ -153,47 +153,33 @@ pub fn provide(providers: &mut Providers) {
153153
check_unused::provide(providers);
154154
variance::provide(providers);
155155
outlives::provide(providers);
156-
impl_wf_check::provide(providers);
157156
hir_wf_check::provide(providers);
158157
}
159158

160159
pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> {
161160
let _prof_timer = tcx.sess.timer("type_check_crate");
162161

163-
// this ensures that later parts of type checking can assume that items
164-
// have valid types and not error
165-
tcx.sess.time("type_collecting", || {
166-
tcx.hir().for_each_module(|module| tcx.ensure().collect_mod_item_types(module))
167-
});
168-
169162
if tcx.features().rustc_attrs {
170163
tcx.sess.time("outlives_testing", || outlives::test::test_inferred_outlives(tcx))?;
171164
}
172165

173166
tcx.sess.time("coherence_checking", || {
174-
// Check impls constrain their parameters
175-
let res =
176-
tcx.hir().try_par_for_each_module(|module| tcx.ensure().check_mod_impl_wf(module));
167+
tcx.hir().par_for_each_module(|module| {
168+
let _ = tcx.ensure().check_mod_type_wf(module);
169+
});
177170

178171
for &trait_def_id in tcx.all_local_trait_impls(()).keys() {
179172
let _ = tcx.ensure().coherent_trait(trait_def_id);
180173
}
181174
// these queries are executed for side-effects (error reporting):
182175
let _ = tcx.ensure().crate_inherent_impls(());
183176
let _ = tcx.ensure().crate_inherent_impls_overlap_check(());
184-
res
185-
})?;
177+
});
186178

187179
if tcx.features().rustc_attrs {
188180
tcx.sess.time("variance_testing", || variance::test::test_variance(tcx))?;
189181
}
190182

191-
tcx.sess.time("wf_checking", || {
192-
tcx.hir().par_for_each_module(|module| {
193-
let _ = tcx.ensure().check_mod_type_wf(module);
194-
})
195-
});
196-
197183
if tcx.features().rustc_attrs {
198184
collect::test_opaque_hidden_types(tcx)?;
199185
}

compiler/rustc_middle/src/query/mod.rs

+1-9
Original file line numberDiff line numberDiff line change
@@ -772,6 +772,7 @@ rustc_queries! {
772772
desc { |tcx| "computing the variances of `{}`", tcx.def_path_str(def_id) }
773773
cache_on_disk_if { def_id.is_local() }
774774
separate_provide_extern
775+
cycle_delay_bug
775776
}
776777

777778
/// Maps from thee `DefId` of a type to its (inferred) outlives.
@@ -964,20 +965,11 @@ rustc_queries! {
964965
desc { |tcx| "checking deathness of variables in {}", describe_as_module(key, tcx) }
965966
}
966967

967-
query check_mod_impl_wf(key: LocalModDefId) -> Result<(), ErrorGuaranteed> {
968-
desc { |tcx| "checking that impls are well-formed in {}", describe_as_module(key, tcx) }
969-
ensure_forwards_result_if_red
970-
}
971-
972968
query check_mod_type_wf(key: LocalModDefId) -> Result<(), ErrorGuaranteed> {
973969
desc { |tcx| "checking that types are well-formed in {}", describe_as_module(key, tcx) }
974970
ensure_forwards_result_if_red
975971
}
976972

977-
query collect_mod_item_types(key: LocalModDefId) {
978-
desc { |tcx| "collecting item types in {}", describe_as_module(key, tcx) }
979-
}
980-
981973
/// Caches `CoerceUnsized` kinds for impls on custom types.
982974
query coerce_unsized_info(key: DefId) -> Result<ty::adjustment::CoerceUnsizedInfo, ErrorGuaranteed> {
983975
desc { |tcx| "computing CoerceUnsized info for `{}`", tcx.def_path_str(key) }

compiler/rustc_middle/src/values.rs

+21
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,27 @@ impl<'tcx> Value<TyCtxt<'tcx>> for ty::EarlyBinder<ty::Binder<'_, ty::FnSig<'_>>
131131
}
132132
}
133133

134+
impl<'tcx> Value<TyCtxt<'tcx>> for &[ty::Variance] {
135+
fn from_cycle_error(
136+
tcx: TyCtxt<'tcx>,
137+
cycle_error: &CycleError,
138+
_guar: ErrorGuaranteed,
139+
) -> Self {
140+
if let Some(frame) = cycle_error.cycle.get(0)
141+
&& frame.query.dep_kind == dep_kinds::variances_of
142+
&& let Some(def_id) = frame.query.def_id
143+
{
144+
let n = tcx.generics_of(def_id).params.len();
145+
vec![ty::Variance::Bivariant; n].leak()
146+
} else {
147+
span_bug!(
148+
cycle_error.usage.as_ref().unwrap().0,
149+
"only `variances_of` returns `&[ty::Variance]`"
150+
);
151+
}
152+
}
153+
}
154+
134155
// Take a cycle of `Q` and try `try_cycle` on every permutation, falling back to `otherwise`.
135156
fn search_for_cycle_permutation<Q, T>(
136157
cycle: &[Q],

compiler/rustc_resolve/src/late.rs

+12-4
Original file line numberDiff line numberDiff line change
@@ -2597,10 +2597,18 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
25972597
let span = *entry.get();
25982598
let err = ResolutionError::NameAlreadyUsedInParameterList(ident.name, span);
25992599
self.report_error(param.ident.span, err);
2600-
if let GenericParamKind::Lifetime = param.kind {
2601-
// Record lifetime res, so lowering knows there is something fishy.
2602-
self.record_lifetime_param(param.id, LifetimeRes::Error);
2603-
}
2600+
let rib = match param.kind {
2601+
GenericParamKind::Lifetime => {
2602+
// Record lifetime res, so lowering knows there is something fishy.
2603+
self.record_lifetime_param(param.id, LifetimeRes::Error);
2604+
continue;
2605+
}
2606+
GenericParamKind::Type { .. } => &mut function_type_rib,
2607+
GenericParamKind::Const { .. } => &mut function_value_rib,
2608+
};
2609+
2610+
self.r.record_partial_res(param.id, PartialRes::new(Res::Err));
2611+
rib.bindings.insert(ident, Res::Err);
26042612
continue;
26052613
}
26062614
Entry::Vacant(entry) => {

compiler/rustc_traits/src/codegen.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
use rustc_infer::infer::TyCtxtInferExt;
77
use rustc_infer::traits::{FulfillmentErrorCode, TraitEngineExt as _};
88
use rustc_middle::traits::CodegenObligationError;
9-
use rustc_middle::ty::{self, TyCtxt};
9+
use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
1010
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
1111
use rustc_trait_selection::traits::{
1212
ImplSource, Obligation, ObligationCause, SelectionContext, TraitEngine, TraitEngineExt,
@@ -72,6 +72,10 @@ pub fn codegen_select_candidate<'tcx>(
7272

7373
let impl_source = infcx.resolve_vars_if_possible(impl_source);
7474
let impl_source = infcx.tcx.erase_regions(impl_source);
75+
if impl_source.has_infer() {
76+
infcx.tcx.dcx().has_errors().unwrap();
77+
return Err(CodegenObligationError::FulfillmentError);
78+
}
7579

7680
Ok(&*tcx.arena.alloc(impl_source))
7781
}

src/librustdoc/core.rs

-11
Original file line numberDiff line numberDiff line change
@@ -315,21 +315,10 @@ pub(crate) fn run_global_ctxt(
315315
// typeck function bodies or run the default rustc lints.
316316
// (see `override_queries` in the `config`)
317317

318-
// HACK(jynelson) this calls an _extremely_ limited subset of `typeck`
319-
// and might break if queries change their assumptions in the future.
320-
tcx.sess.time("type_collecting", || {
321-
tcx.hir().for_each_module(|module| tcx.ensure().collect_mod_item_types(module))
322-
});
323-
324318
// NOTE: These are copy/pasted from typeck/lib.rs and should be kept in sync with those changes.
325319
let _ = tcx.sess.time("wf_checking", || {
326320
tcx.hir().try_par_for_each_module(|module| tcx.ensure().check_mod_type_wf(module))
327321
});
328-
tcx.sess.time("item_types_checking", || {
329-
tcx.hir().for_each_module(|module| {
330-
let _ = tcx.ensure().check_mod_type_wf(module);
331-
});
332-
});
333322

334323
if let Some(guar) = tcx.dcx().has_errors() {
335324
return Err(guar);

tests/rustdoc-ui/not-wf-ambiguous-normalization.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ struct DefaultAllocator;
1212
// `<DefaultAllocator as Allocator>::Buffer` to be ambiguous,
1313
// which caused an ICE with `-Znormalize-docs`.
1414
impl<T> Allocator for DefaultAllocator {
15-
//~^ ERROR: type annotations needed
15+
//~^ ERROR: the type parameter `T` is not constrained
1616
type Buffer = ();
1717
}
1818

Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
error[E0282]: type annotations needed
2-
--> $DIR/not-wf-ambiguous-normalization.rs:14:23
1+
error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates
2+
--> $DIR/not-wf-ambiguous-normalization.rs:14:6
33
|
44
LL | impl<T> Allocator for DefaultAllocator {
5-
| ^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T`
5+
| ^ unconstrained type parameter
66

77
error: aborting due to 1 previous error
88

9-
For more information about this error, try `rustc --explain E0282`.
9+
For more information about this error, try `rustc --explain E0207`.

tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-adt.stderr

+4-10
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,11 @@ note: ...which requires computing normalized predicates of `Foo`...
2626
LL | struct Foo {
2727
| ^^^^^^^^^^
2828
= note: ...which again requires computing predicates of `Foo`, completing the cycle
29-
note: cycle used when collecting item types in top-level module
30-
--> $DIR/cycle-iat-inside-of-adt.rs:3:1
29+
note: cycle used when checking that `Foo` is well-formed
30+
--> $DIR/cycle-iat-inside-of-adt.rs:7:1
3131
|
32-
LL | / #![feature(inherent_associated_types)]
33-
LL | | #![allow(incomplete_features)]
34-
LL | | // FIXME(inherent_associated_types): This should pass.
35-
LL | |
36-
... |
37-
LL | |
38-
LL | | fn main() {}
39-
| |____________^
32+
LL | struct Foo {
33+
| ^^^^^^^^^^
4034
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
4135

4236
error: aborting due to 1 previous error

0 commit comments

Comments
 (0)