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 0eb9aef

Browse files
committedJan 12, 2024
WIP
1 parent 4d66bb7 commit 0eb9aef

File tree

24 files changed

+529
-193
lines changed

24 files changed

+529
-193
lines changed
 

‎compiler/rustc_hir_analysis/src/coherence/builtin.rs

+91-65
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,21 @@ use rustc_trait_selection::traits::ObligationCtxt;
2525
use rustc_trait_selection::traits::{self, ObligationCause};
2626
use std::collections::BTreeMap;
2727

28-
pub fn check_trait(tcx: TyCtxt<'_>, trait_def_id: DefId) {
28+
pub fn check_trait(tcx: TyCtxt<'_>, trait_def_id: DefId) -> Result<(), ErrorGuaranteed> {
2929
let lang_items = tcx.lang_items();
30-
Checker { tcx, trait_def_id }
31-
.check(lang_items.drop_trait(), visit_implementation_of_drop)
32-
.check(lang_items.copy_trait(), visit_implementation_of_copy)
33-
.check(lang_items.const_param_ty_trait(), visit_implementation_of_const_param_ty)
34-
.check(lang_items.coerce_unsized_trait(), visit_implementation_of_coerce_unsized)
35-
.check(lang_items.dispatch_from_dyn_trait(), visit_implementation_of_dispatch_from_dyn);
30+
let checker = Checker { tcx, trait_def_id };
31+
let mut res = checker.check(lang_items.drop_trait(), visit_implementation_of_drop);
32+
res = res.and(checker.check(lang_items.copy_trait(), visit_implementation_of_copy));
33+
res = res.and(
34+
checker.check(lang_items.const_param_ty_trait(), visit_implementation_of_const_param_ty),
35+
);
36+
res = res.and(
37+
checker.check(lang_items.coerce_unsized_trait(), visit_implementation_of_coerce_unsized),
38+
);
39+
res.and(
40+
checker
41+
.check(lang_items.dispatch_from_dyn_trait(), visit_implementation_of_dispatch_from_dyn),
42+
)
3643
}
3744

3845
struct Checker<'tcx> {
@@ -41,33 +48,40 @@ struct Checker<'tcx> {
4148
}
4249

4350
impl<'tcx> Checker<'tcx> {
44-
fn check<F>(&self, trait_def_id: Option<DefId>, mut f: F) -> &Self
51+
fn check<F>(&self, trait_def_id: Option<DefId>, mut f: F) -> Result<(), ErrorGuaranteed>
4552
where
46-
F: FnMut(TyCtxt<'tcx>, LocalDefId),
53+
F: FnMut(TyCtxt<'tcx>, LocalDefId) -> Result<(), ErrorGuaranteed>,
4754
{
55+
let mut res = Ok(());
4856
if Some(self.trait_def_id) == trait_def_id {
4957
for &impl_def_id in self.tcx.hir().trait_impls(self.trait_def_id) {
50-
f(self.tcx, impl_def_id);
58+
res = res.and(f(self.tcx, impl_def_id));
5159
}
5260
}
53-
self
61+
res
5462
}
5563
}
5664

57-
fn visit_implementation_of_drop(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
65+
fn visit_implementation_of_drop(
66+
tcx: TyCtxt<'_>,
67+
impl_did: LocalDefId,
68+
) -> Result<(), ErrorGuaranteed> {
5869
// Destructors only work on local ADT types.
5970
match tcx.type_of(impl_did).instantiate_identity().kind() {
60-
ty::Adt(def, _) if def.did().is_local() => return,
61-
ty::Error(_) => return,
71+
ty::Adt(def, _) if def.did().is_local() => return Ok(()),
72+
ty::Error(_) => return Ok(()),
6273
_ => {}
6374
}
6475

6576
let impl_ = tcx.hir().expect_item(impl_did).expect_impl();
6677

67-
tcx.dcx().emit_err(errors::DropImplOnWrongItem { span: impl_.self_ty.span });
78+
Err(tcx.dcx().emit_err(errors::DropImplOnWrongItem { span: impl_.self_ty.span }))
6879
}
6980

70-
fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
81+
fn visit_implementation_of_copy(
82+
tcx: TyCtxt<'_>,
83+
impl_did: LocalDefId,
84+
) -> Result<(), ErrorGuaranteed> {
7185
debug!("visit_implementation_of_copy: impl_did={:?}", impl_did);
7286

7387
let self_type = tcx.type_of(impl_did).instantiate_identity();
@@ -79,59 +93,68 @@ fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
7993
debug!("visit_implementation_of_copy: self_type={:?} (free)", self_type);
8094

8195
let span = match tcx.hir().expect_item(impl_did).expect_impl() {
82-
hir::Impl { polarity: hir::ImplPolarity::Negative(_), .. } => return,
96+
hir::Impl { polarity: hir::ImplPolarity::Negative(_), .. } => return Ok(()),
8397
hir::Impl { self_ty, .. } => self_ty.span,
8498
};
8599

86100
let cause = traits::ObligationCause::misc(span, impl_did);
87101
match type_allowed_to_implement_copy(tcx, param_env, self_type, cause) {
88-
Ok(()) => {}
102+
Ok(()) => Ok(()),
89103
Err(CopyImplementationError::InfringingFields(fields)) => {
90-
infringing_fields_error(tcx, fields, LangItem::Copy, impl_did, span);
104+
Err(infringing_fields_error(tcx, fields, LangItem::Copy, impl_did, span))
91105
}
92106
Err(CopyImplementationError::NotAnAdt) => {
93-
tcx.dcx().emit_err(errors::CopyImplOnNonAdt { span });
107+
Err(tcx.dcx().emit_err(errors::CopyImplOnNonAdt { span }))
94108
}
95109
Err(CopyImplementationError::HasDestructor) => {
96-
tcx.dcx().emit_err(errors::CopyImplOnTypeWithDtor { span });
110+
Err(tcx.dcx().emit_err(errors::CopyImplOnTypeWithDtor { span }))
97111
}
98112
}
99113
}
100114

101-
fn visit_implementation_of_const_param_ty(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
115+
fn visit_implementation_of_const_param_ty(
116+
tcx: TyCtxt<'_>,
117+
impl_did: LocalDefId,
118+
) -> Result<(), ErrorGuaranteed> {
102119
let self_type = tcx.type_of(impl_did).instantiate_identity();
103120
assert!(!self_type.has_escaping_bound_vars());
104121

105122
let param_env = tcx.param_env(impl_did);
106123

107124
let span = match tcx.hir().expect_item(impl_did).expect_impl() {
108-
hir::Impl { polarity: hir::ImplPolarity::Negative(_), .. } => return,
125+
hir::Impl { polarity: hir::ImplPolarity::Negative(_), .. } => return Ok(()),
109126
impl_ => impl_.self_ty.span,
110127
};
111128

112129
let cause = traits::ObligationCause::misc(span, impl_did);
113130
match type_allowed_to_implement_const_param_ty(tcx, param_env, self_type, cause) {
114-
Ok(()) => {}
131+
Ok(()) => Ok(()),
115132
Err(ConstParamTyImplementationError::InfrigingFields(fields)) => {
116-
infringing_fields_error(tcx, fields, LangItem::ConstParamTy, impl_did, span);
133+
Err(infringing_fields_error(tcx, fields, LangItem::ConstParamTy, impl_did, span))
117134
}
118135
Err(ConstParamTyImplementationError::NotAnAdtOrBuiltinAllowed) => {
119-
tcx.dcx().emit_err(errors::ConstParamTyImplOnNonAdt { span });
136+
Err(tcx.dcx().emit_err(errors::ConstParamTyImplOnNonAdt { span }))
120137
}
121138
}
122139
}
123140

124-
fn visit_implementation_of_coerce_unsized(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
141+
fn visit_implementation_of_coerce_unsized(
142+
tcx: TyCtxt<'_>,
143+
impl_did: LocalDefId,
144+
) -> Result<(), ErrorGuaranteed> {
125145
debug!("visit_implementation_of_coerce_unsized: impl_did={:?}", impl_did);
126146

127147
// Just compute this for the side-effects, in particular reporting
128148
// errors; other parts of the code may demand it for the info of
129149
// course.
130150
let span = tcx.def_span(impl_did);
131-
tcx.at(span).coerce_unsized_info(impl_did);
151+
tcx.at(span).ensure().coerce_unsized_info(impl_did)
132152
}
133153

134-
fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
154+
fn visit_implementation_of_dispatch_from_dyn(
155+
tcx: TyCtxt<'_>,
156+
impl_did: LocalDefId,
157+
) -> Result<(), ErrorGuaranteed> {
135158
debug!("visit_implementation_of_dispatch_from_dyn: impl_did={:?}", impl_did);
136159

137160
let span = tcx.def_span(impl_did);
@@ -166,26 +189,28 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDef
166189
match (source.kind(), target.kind()) {
167190
(&Ref(r_a, _, mutbl_a), Ref(r_b, _, mutbl_b))
168191
if infcx.at(&cause, param_env).eq(DefineOpaqueTypes::No, r_a, *r_b).is_ok()
169-
&& mutbl_a == *mutbl_b => {}
170-
(&RawPtr(tm_a), &RawPtr(tm_b)) if tm_a.mutbl == tm_b.mutbl => (),
192+
&& mutbl_a == *mutbl_b =>
193+
{
194+
Ok(())
195+
}
196+
(&RawPtr(tm_a), &RawPtr(tm_b)) if tm_a.mutbl == tm_b.mutbl => Ok(()),
171197
(&Adt(def_a, args_a), &Adt(def_b, args_b)) if def_a.is_struct() && def_b.is_struct() => {
172198
if def_a != def_b {
173199
let source_path = tcx.def_path_str(def_a.did());
174200
let target_path = tcx.def_path_str(def_b.did());
175201

176-
tcx.dcx().emit_err(errors::DispatchFromDynCoercion {
202+
return Err(tcx.dcx().emit_err(errors::DispatchFromDynCoercion {
177203
span,
178204
trait_name: "DispatchFromDyn",
179205
note: true,
180206
source_path,
181207
target_path,
182-
});
183-
184-
return;
208+
}));
185209
}
186210

211+
let mut res = Ok(());
187212
if def_a.repr().c() || def_a.repr().packed() {
188-
tcx.dcx().emit_err(errors::DispatchFromDynRepr { span });
213+
res = Err(tcx.dcx().emit_err(errors::DispatchFromDynRepr { span }));
189214
}
190215

191216
let fields = &def_a.non_enum_variant().fields;
@@ -207,11 +232,11 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDef
207232
infcx.at(&cause, param_env).eq(DefineOpaqueTypes::No, ty_a, ty_b)
208233
{
209234
if ok.obligations.is_empty() {
210-
tcx.dcx().emit_err(errors::DispatchFromDynZST {
235+
res = Err(tcx.dcx().emit_err(errors::DispatchFromDynZST {
211236
span,
212237
name: field.name,
213238
ty: ty_a,
214-
});
239+
}));
215240

216241
return false;
217242
}
@@ -222,13 +247,13 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDef
222247
.collect::<Vec<_>>();
223248

224249
if coerced_fields.is_empty() {
225-
tcx.dcx().emit_err(errors::DispatchFromDynSingle {
250+
res = Err(tcx.dcx().emit_err(errors::DispatchFromDynSingle {
226251
span,
227252
trait_name: "DispatchFromDyn",
228253
note: true,
229-
});
254+
}));
230255
} else if coerced_fields.len() > 1 {
231-
tcx.dcx().emit_err(errors::DispatchFromDynMulti {
256+
res = Err(tcx.dcx().emit_err(errors::DispatchFromDynMulti {
232257
span,
233258
coercions_note: true,
234259
number: coerced_fields.len(),
@@ -244,7 +269,7 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDef
244269
})
245270
.collect::<Vec<_>>()
246271
.join(", "),
247-
});
272+
}));
248273
} else {
249274
let ocx = ObligationCtxt::new(&infcx);
250275
for field in coerced_fields {
@@ -261,21 +286,25 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDef
261286
}
262287
let errors = ocx.select_all_or_error();
263288
if !errors.is_empty() {
264-
infcx.err_ctxt().report_fulfillment_errors(errors);
289+
res = Err(infcx.err_ctxt().report_fulfillment_errors(errors));
265290
}
266291

267292
// Finally, resolve all regions.
268293
let outlives_env = OutlivesEnvironment::new(param_env);
269-
let _ = ocx.resolve_regions_and_report_errors(impl_did, &outlives_env);
294+
res = res.and(ocx.resolve_regions_and_report_errors(impl_did, &outlives_env));
270295
}
296+
res
271297
}
272-
_ => {
273-
tcx.dcx().emit_err(errors::CoerceUnsizedMay { span, trait_name: "DispatchFromDyn" });
274-
}
298+
_ => Err(tcx
299+
.dcx()
300+
.emit_err(errors::CoerceUnsizedMay { span, trait_name: "DispatchFromDyn" })),
275301
}
276302
}
277303

278-
pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: LocalDefId) -> CoerceUnsizedInfo {
304+
pub fn coerce_unsized_info<'tcx>(
305+
tcx: TyCtxt<'tcx>,
306+
impl_did: LocalDefId,
307+
) -> Result<CoerceUnsizedInfo, ErrorGuaranteed> {
279308
debug!("compute_coerce_unsized_info(impl_did={:?})", impl_did);
280309
let span = tcx.def_span(impl_did);
281310

@@ -292,8 +321,6 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: LocalDefId) -> Coe
292321
let param_env = tcx.param_env(impl_did);
293322
assert!(!source.has_escaping_bound_vars());
294323

295-
let err_info = CoerceUnsizedInfo { custom_kind: None };
296-
297324
debug!("visit_implementation_of_coerce_unsized: {:?} -> {:?} (free)", source, target);
298325

299326
let infcx = tcx.infer_ctxt().build();
@@ -337,14 +364,13 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: LocalDefId) -> Coe
337364
if def_a != def_b {
338365
let source_path = tcx.def_path_str(def_a.did());
339366
let target_path = tcx.def_path_str(def_b.did());
340-
tcx.dcx().emit_err(errors::DispatchFromDynSame {
367+
return Err(tcx.dcx().emit_err(errors::DispatchFromDynSame {
341368
span,
342369
trait_name: "CoerceUnsized",
343370
note: true,
344371
source_path,
345372
target_path,
346-
});
347-
return err_info;
373+
}));
348374
}
349375

350376
// Here we are considering a case of converting
@@ -419,12 +445,11 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: LocalDefId) -> Coe
419445
.collect::<Vec<_>>();
420446

421447
if diff_fields.is_empty() {
422-
tcx.dcx().emit_err(errors::CoerceUnsizedOneField {
448+
return Err(tcx.dcx().emit_err(errors::CoerceUnsizedOneField {
423449
span,
424450
trait_name: "CoerceUnsized",
425451
note: true,
426-
});
427-
return err_info;
452+
}));
428453
} else if diff_fields.len() > 1 {
429454
let item = tcx.hir().expect_item(impl_did);
430455
let span = if let ItemKind::Impl(hir::Impl { of_trait: Some(t), .. }) = &item.kind {
@@ -433,7 +458,7 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: LocalDefId) -> Coe
433458
tcx.def_span(impl_did)
434459
};
435460

436-
tcx.dcx().emit_err(errors::CoerceUnsizedMulti {
461+
return Err(tcx.dcx().emit_err(errors::CoerceUnsizedMulti {
437462
span,
438463
coercions_note: true,
439464
number: diff_fields.len(),
@@ -442,9 +467,7 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: LocalDefId) -> Coe
442467
.map(|&(i, a, b)| format!("`{}` (`{}` to `{}`)", fields[i].name, a, b))
443468
.collect::<Vec<_>>()
444469
.join(", "),
445-
});
446-
447-
return err_info;
470+
}));
448471
}
449472

450473
let (i, a, b) = diff_fields[0];
@@ -453,8 +476,9 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: LocalDefId) -> Coe
453476
}
454477

455478
_ => {
456-
tcx.dcx().emit_err(errors::DispatchFromDynStruct { span, trait_name: "CoerceUnsized" });
457-
return err_info;
479+
return Err(tcx
480+
.dcx()
481+
.emit_err(errors::DispatchFromDynStruct { span, trait_name: "CoerceUnsized" }));
458482
}
459483
};
460484

@@ -469,15 +493,17 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: LocalDefId) -> Coe
469493
);
470494
ocx.register_obligation(obligation);
471495
let errors = ocx.select_all_or_error();
496+
let mut res = Ok(());
472497
if !errors.is_empty() {
473-
infcx.err_ctxt().report_fulfillment_errors(errors);
498+
res = Err(infcx.err_ctxt().report_fulfillment_errors(errors));
474499
}
475500

476501
// Finally, resolve all regions.
477502
let outlives_env = OutlivesEnvironment::new(param_env);
478-
let _ = ocx.resolve_regions_and_report_errors(impl_did, &outlives_env);
503+
ocx.resolve_regions_and_report_errors(impl_did, &outlives_env)?;
504+
res?;
479505

480-
CoerceUnsizedInfo { custom_kind: kind }
506+
Ok(CoerceUnsizedInfo { custom_kind: kind })
481507
}
482508

483509
fn infringing_fields_error(

‎compiler/rustc_hir_analysis/src/coherence/mod.rs

+30-25
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use rustc_errors::{error_code, struct_span_code_err};
1010
use rustc_hir::def_id::{DefId, LocalDefId};
1111
use rustc_middle::query::Providers;
1212
use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
13+
use rustc_span::ErrorGuaranteed;
1314
use rustc_trait_selection::traits;
1415

1516
mod builtin;
@@ -18,7 +19,11 @@ mod inherent_impls_overlap;
1819
mod orphan;
1920
mod unsafety;
2021

21-
fn check_impl(tcx: TyCtxt<'_>, impl_def_id: LocalDefId, trait_ref: ty::TraitRef<'_>) {
22+
fn check_impl(
23+
tcx: TyCtxt<'_>,
24+
impl_def_id: LocalDefId,
25+
trait_ref: ty::TraitRef<'_>,
26+
) -> Result<(), ErrorGuaranteed> {
2227
debug!(
2328
"(checking implementation) adding impl for trait '{:?}', item '{}'",
2429
trait_ref,
@@ -28,18 +33,18 @@ fn check_impl(tcx: TyCtxt<'_>, impl_def_id: LocalDefId, trait_ref: ty::TraitRef<
2833
// Skip impls where one of the self type is an error type.
2934
// This occurs with e.g., resolve failures (#30589).
3035
if trait_ref.references_error() {
31-
return;
36+
return Ok(());
3237
}
3338

34-
enforce_trait_manually_implementable(tcx, impl_def_id, trait_ref.def_id);
35-
enforce_empty_impls_for_marker_traits(tcx, impl_def_id, trait_ref.def_id);
39+
enforce_trait_manually_implementable(tcx, impl_def_id, trait_ref.def_id)
40+
.and(enforce_empty_impls_for_marker_traits(tcx, impl_def_id, trait_ref.def_id))
3641
}
3742

3843
fn enforce_trait_manually_implementable(
3944
tcx: TyCtxt<'_>,
4045
impl_def_id: LocalDefId,
4146
trait_def_id: DefId,
42-
) {
47+
) -> Result<(), ErrorGuaranteed> {
4348
let impl_header_span = tcx.def_span(impl_def_id);
4449

4550
// Disallow *all* explicit impls of traits marked `#[rustc_deny_explicit_impl]`
@@ -59,18 +64,17 @@ fn enforce_trait_manually_implementable(
5964
err.code(error_code!(E0328));
6065
}
6166

62-
err.emit();
63-
return;
67+
return Err(err.emit());
6468
}
6569

6670
if let ty::trait_def::TraitSpecializationKind::AlwaysApplicable =
6771
tcx.trait_def(trait_def_id).specialization_kind
6872
{
6973
if !tcx.features().specialization && !tcx.features().min_specialization {
70-
tcx.dcx().emit_err(errors::SpecializationTrait { span: impl_header_span });
71-
return;
74+
return Err(tcx.dcx().emit_err(errors::SpecializationTrait { span: impl_header_span }));
7275
}
7376
}
77+
Ok(())
7478
}
7579

7680
/// We allow impls of marker traits to overlap, so they can't override impls
@@ -79,22 +83,22 @@ fn enforce_empty_impls_for_marker_traits(
7983
tcx: TyCtxt<'_>,
8084
impl_def_id: LocalDefId,
8185
trait_def_id: DefId,
82-
) {
86+
) -> Result<(), ErrorGuaranteed> {
8387
if !tcx.trait_def(trait_def_id).is_marker {
84-
return;
88+
return Ok(());
8589
}
8690

8791
if tcx.associated_item_def_ids(trait_def_id).is_empty() {
88-
return;
92+
return Ok(());
8993
}
9094

91-
struct_span_code_err!(
95+
Err(struct_span_code_err!(
9296
tcx.dcx(),
9397
tcx.def_span(impl_def_id),
9498
E0715,
9599
"impls for marker traits cannot contain items"
96100
)
97-
.emit();
101+
.emit())
98102
}
99103

100104
pub fn provide(providers: &mut Providers) {
@@ -115,36 +119,36 @@ pub fn provide(providers: &mut Providers) {
115119
};
116120
}
117121

118-
fn coherent_trait(tcx: TyCtxt<'_>, def_id: DefId) {
122+
fn coherent_trait(tcx: TyCtxt<'_>, def_id: DefId) -> Result<(), ErrorGuaranteed> {
119123
// Trigger building the specialization graph for the trait. This will detect and report any
120124
// overlap errors.
121-
tcx.ensure().specialization_graph_of(def_id);
125+
let mut res = tcx.ensure().specialization_graph_of(def_id);
122126

123127
let impls = tcx.hir().trait_impls(def_id);
124128
for &impl_def_id in impls {
125129
let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap().instantiate_identity();
126130

127-
check_impl(tcx, impl_def_id, trait_ref);
128-
check_object_overlap(tcx, impl_def_id, trait_ref);
131+
res = res.and(check_impl(tcx, impl_def_id, trait_ref));
132+
res = res.and(check_object_overlap(tcx, impl_def_id, trait_ref));
129133

130-
unsafety::check_item(tcx, impl_def_id);
131-
tcx.ensure().orphan_check_impl(impl_def_id);
134+
res = res.and(unsafety::check_item(tcx, impl_def_id));
135+
res = res.and(tcx.ensure().orphan_check_impl(impl_def_id));
132136
}
133137

134-
builtin::check_trait(tcx, def_id);
138+
res.and(builtin::check_trait(tcx, def_id))
135139
}
136140

137141
/// Checks whether an impl overlaps with the automatic `impl Trait for dyn Trait`.
138142
fn check_object_overlap<'tcx>(
139143
tcx: TyCtxt<'tcx>,
140144
impl_def_id: LocalDefId,
141145
trait_ref: ty::TraitRef<'tcx>,
142-
) {
146+
) -> Result<(), ErrorGuaranteed> {
143147
let trait_def_id = trait_ref.def_id;
144148

145149
if trait_ref.references_error() {
146150
debug!("coherence: skipping impl {:?} with error {:?}", impl_def_id, trait_ref);
147-
return;
151+
return Ok(());
148152
}
149153

150154
// check for overlap with the automatic `impl Trait for dyn Trait`
@@ -173,7 +177,7 @@ fn check_object_overlap<'tcx>(
173177
let mut supertrait_def_ids = traits::supertrait_def_ids(tcx, component_def_id);
174178
if supertrait_def_ids.any(|d| d == trait_def_id) {
175179
let span = tcx.def_span(impl_def_id);
176-
struct_span_code_err!(
180+
return Err(struct_span_code_err!(
177181
tcx.dcx(),
178182
span,
179183
E0371,
@@ -189,9 +193,10 @@ fn check_object_overlap<'tcx>(
189193
tcx.def_path_str(trait_def_id)
190194
),
191195
)
192-
.emit();
196+
.emit());
193197
}
194198
}
195199
}
196200
}
201+
Ok(())
197202
}

‎compiler/rustc_hir_analysis/src/coherence/unsafety.rs

+9-7
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@ use rustc_hir as hir;
66
use rustc_hir::Unsafety;
77
use rustc_middle::ty::TyCtxt;
88
use rustc_span::def_id::LocalDefId;
9+
use rustc_span::ErrorGuaranteed;
910

10-
pub(super) fn check_item(tcx: TyCtxt<'_>, def_id: LocalDefId) {
11+
pub(super) fn check_item(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), ErrorGuaranteed> {
1112
let item = tcx.hir().expect_item(def_id);
1213
let impl_ = item.expect_impl();
1314

@@ -18,7 +19,7 @@ pub(super) fn check_item(tcx: TyCtxt<'_>, def_id: LocalDefId) {
1819
impl_.generics.params.iter().find(|p| p.pure_wrt_drop).map(|_| "may_dangle");
1920
match (trait_def.unsafety, unsafe_attr, impl_.unsafety, impl_.polarity) {
2021
(Unsafety::Normal, None, Unsafety::Unsafe, hir::ImplPolarity::Positive) => {
21-
struct_span_code_err!(
22+
return Err(struct_span_code_err!(
2223
tcx.dcx(),
2324
tcx.def_span(def_id),
2425
E0199,
@@ -31,11 +32,11 @@ pub(super) fn check_item(tcx: TyCtxt<'_>, def_id: LocalDefId) {
3132
"",
3233
rustc_errors::Applicability::MachineApplicable,
3334
)
34-
.emit();
35+
.emit());
3536
}
3637

3738
(Unsafety::Unsafe, _, Unsafety::Normal, hir::ImplPolarity::Positive) => {
38-
struct_span_code_err!(
39+
return Err(struct_span_code_err!(
3940
tcx.dcx(),
4041
tcx.def_span(def_id),
4142
E0200,
@@ -54,11 +55,11 @@ pub(super) fn check_item(tcx: TyCtxt<'_>, def_id: LocalDefId) {
5455
"unsafe ",
5556
rustc_errors::Applicability::MaybeIncorrect,
5657
)
57-
.emit();
58+
.emit());
5859
}
5960

6061
(Unsafety::Normal, Some(attr_name), Unsafety::Normal, hir::ImplPolarity::Positive) => {
61-
struct_span_code_err!(
62+
return Err(struct_span_code_err!(
6263
tcx.dcx(),
6364
tcx.def_span(def_id),
6465
E0569,
@@ -77,7 +78,7 @@ pub(super) fn check_item(tcx: TyCtxt<'_>, def_id: LocalDefId) {
7778
"unsafe ",
7879
rustc_errors::Applicability::MaybeIncorrect,
7980
)
80-
.emit();
81+
.emit());
8182
}
8283

8384
(_, _, Unsafety::Unsafe, hir::ImplPolarity::Negative(_)) => {
@@ -92,4 +93,5 @@ pub(super) fn check_item(tcx: TyCtxt<'_>, def_id: LocalDefId) {
9293
}
9394
}
9495
}
96+
Ok(())
9597
}

‎compiler/rustc_hir_analysis/src/lib.rs

+6-10
Original file line numberDiff line numberDiff line change
@@ -176,19 +176,15 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> {
176176

177177
tcx.sess.time("coherence_checking", || {
178178
// Check impls constrain their parameters
179-
let res =
179+
let mut res =
180180
tcx.hir().try_par_for_each_module(|module| tcx.ensure().check_mod_impl_wf(module));
181181

182-
// FIXME(matthewjasper) We shouldn't need to use `track_errors` anywhere in this function
183-
// or the compiler in general.
184-
res.and(tcx.sess.track_errors(|| {
185-
for &trait_def_id in tcx.all_local_trait_impls(()).keys() {
186-
tcx.ensure().coherent_trait(trait_def_id);
187-
}
188-
}))
182+
for &trait_def_id in tcx.all_local_trait_impls(()).keys() {
183+
res = res.and(tcx.ensure().coherent_trait(trait_def_id));
184+
}
189185
// these queries are executed for side-effects (error reporting):
190-
.and(tcx.ensure().crate_inherent_impls(()))
191-
.and(tcx.ensure().crate_inherent_impls_overlap_check(()))
186+
res.and(tcx.ensure().crate_inherent_impls(()))
187+
.and(tcx.ensure().crate_inherent_impls_overlap_check(()))
192188
})?;
193189

194190
if tcx.features().rustc_attrs {

‎compiler/rustc_infer/src/infer/relate/combine.rs

+6-22
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ impl<'tcx> InferCtxt<'tcx> {
167167
//
168168
// This probe is probably not strictly necessary but it seems better to be safe and not accidentally find
169169
// ourselves with a check to find bugs being required for code to compile because it made inference progress.
170-
let compatible_types = self.probe(|_| {
170+
self.probe(|_| {
171171
if a.ty() == b.ty() {
172172
return Ok(());
173173
}
@@ -180,30 +180,14 @@ impl<'tcx> InferCtxt<'tcx> {
180180
&mut OriginalQueryValues::default(),
181181
);
182182
self.tcx.check_tys_might_be_eq(canonical).map_err(|_| {
183+
// The error will only be reported later. If we emit an ErrorGuaranteed
184+
// here, then we will never get to the code that actually emits the error.
183185
self.tcx.dcx().delayed_bug(format!(
184186
"cannot relate consts of different types (a={a:?}, b={b:?})",
185-
))
187+
));
188+
TypeError::Mismatch
186189
})
187-
});
188-
189-
// If the consts have differing types, just bail with a const error with
190-
// the expected const's type. Specifically, we don't want const infer vars
191-
// to do any type shapeshifting before and after resolution.
192-
if let Err(guar) = compatible_types {
193-
// HACK: equating both sides with `[const error]` eagerly prevents us
194-
// from leaving unconstrained inference vars during things like impl
195-
// matching in the solver.
196-
let a_error = ty::Const::new_error(self.tcx, guar, a.ty());
197-
if let ty::ConstKind::Infer(InferConst::Var(vid)) = a.kind() {
198-
return self.unify_const_variable(vid, a_error, relation.param_env());
199-
}
200-
let b_error = ty::Const::new_error(self.tcx, guar, b.ty());
201-
if let ty::ConstKind::Infer(InferConst::Var(vid)) = b.kind() {
202-
return self.unify_const_variable(vid, b_error, relation.param_env());
203-
}
204-
205-
return Ok(if relation.a_is_expected() { a_error } else { b_error });
206-
}
190+
})?;
207191

208192
match (a.kind(), b.kind()) {
209193
(

‎compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,14 @@ provide! { tcx, def_id, other, cdata,
236236
impl_polarity => { table_direct }
237237
defaultness => { table_direct }
238238
constness => { table_direct }
239-
coerce_unsized_info => { table }
239+
coerce_unsized_info => {
240+
Ok(cdata
241+
.root
242+
.tables
243+
.coerce_unsized_info
244+
.get(cdata, def_id.index)
245+
.map(|lazy| lazy.decode((cdata, tcx)))
246+
.process_decoded(tcx, || panic!("{def_id:?} does not have coerce_unsized_info"))) }
240247
mir_const_qualif => { table }
241248
rendered_const => { table }
242249
asyncness => { table_direct }

‎compiler/rustc_metadata/src/rmeta/encoder.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1994,7 +1994,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
19941994
// if this is an impl of `CoerceUnsized`, create its
19951995
// "unsized info", else just store None
19961996
if Some(trait_ref.def_id) == tcx.lang_items().coerce_unsized_trait() {
1997-
let coerce_unsized_info = tcx.coerce_unsized_info(def_id);
1997+
let coerce_unsized_info = tcx.coerce_unsized_info(def_id).unwrap();
19981998
record!(self.tables.coerce_unsized_info[def_id] <- coerce_unsized_info);
19991999
}
20002000
}

‎compiler/rustc_middle/src/query/erase.rs

+5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use crate::mir;
22
use crate::query::CyclePlaceholder;
33
use crate::traits;
4+
use crate::ty::adjustment::CoerceUnsizedInfo;
45
use crate::ty::{self, Ty};
56
use std::intrinsics::transmute_unchecked;
67
use std::mem::{size_of, MaybeUninit};
@@ -101,6 +102,10 @@ impl EraseType for Result<Option<ty::Instance<'_>>, rustc_errors::ErrorGuarantee
101102
[u8; size_of::<Result<Option<ty::Instance<'static>>, rustc_errors::ErrorGuaranteed>>()];
102103
}
103104

105+
impl EraseType for Result<CoerceUnsizedInfo, rustc_errors::ErrorGuaranteed> {
106+
type Result = [u8; size_of::<Result<CoerceUnsizedInfo, rustc_errors::ErrorGuaranteed>>()];
107+
}
108+
104109
impl EraseType for Result<Option<ty::EarlyBinder<ty::Const<'_>>>, rustc_errors::ErrorGuaranteed> {
105110
type Result = [u8; size_of::<
106111
Result<Option<ty::EarlyBinder<ty::Const<'static>>>, rustc_errors::ErrorGuaranteed>,

‎compiler/rustc_middle/src/query/mod.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -976,10 +976,11 @@ rustc_queries! {
976976
}
977977

978978
/// Caches `CoerceUnsized` kinds for impls on custom types.
979-
query coerce_unsized_info(key: DefId) -> ty::adjustment::CoerceUnsizedInfo {
979+
query coerce_unsized_info(key: DefId) -> Result<ty::adjustment::CoerceUnsizedInfo, ErrorGuaranteed> {
980980
desc { |tcx| "computing CoerceUnsized info for `{}`", tcx.def_path_str(key) }
981981
cache_on_disk_if { key.is_local() }
982982
separate_provide_extern
983+
ensure_forwards_result_if_red
983984
}
984985

985986
query typeck(key: LocalDefId) -> &'tcx ty::TypeckResults<'tcx> {
@@ -999,8 +1000,9 @@ rustc_queries! {
9991000
desc { |tcx| "checking whether `{}` has a body", tcx.def_path_str(def_id) }
10001001
}
10011002

1002-
query coherent_trait(def_id: DefId) -> () {
1003+
query coherent_trait(def_id: DefId) -> Result<(), ErrorGuaranteed> {
10031004
desc { |tcx| "coherence checking all impls of trait `{}`", tcx.def_path_str(def_id) }
1005+
ensure_forwards_result_if_red
10041006
}
10051007

10061008
/// Borrow-checks the function body. If this is a closure, returns
@@ -1031,6 +1033,7 @@ rustc_queries! {
10311033
"checking whether impl `{}` follows the orphan rules",
10321034
tcx.def_path_str(key),
10331035
}
1036+
ensure_forwards_result_if_red
10341037
}
10351038

10361039
/// Check whether the function has any recursion that could cause the inliner to trigger
@@ -1299,6 +1302,7 @@ rustc_queries! {
12991302
query specialization_graph_of(trait_id: DefId) -> Result<&'tcx specialization_graph::Graph, ErrorGuaranteed> {
13001303
desc { |tcx| "building specialization graph of trait `{}`", tcx.def_path_str(trait_id) }
13011304
cache_on_disk_if { true }
1305+
ensure_forwards_result_if_red
13021306
}
13031307
query object_safety_violations(trait_id: DefId) -> &'tcx [ObjectSafetyViolation] {
13041308
desc { |tcx| "determining object safety of trait `{}`", tcx.def_path_str(trait_id) }

‎compiler/rustc_middle/src/ty/util.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ impl<'tcx> TyCtxt<'tcx> {
350350
validate: impl Fn(Self, DefId) -> Result<(), ErrorGuaranteed>,
351351
) -> Option<ty::Destructor> {
352352
let drop_trait = self.lang_items().drop_trait()?;
353-
self.ensure().coherent_trait(drop_trait);
353+
self.ensure().coherent_trait(drop_trait).ok()?;
354354

355355
let ty = self.type_of(adt_did).instantiate_identity();
356356
let mut dtor_candidate = None;

‎compiler/rustc_monomorphize/src/collector.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -1088,7 +1088,13 @@ fn find_vtable_types_for_unsizing<'tcx>(
10881088
assert_eq!(source_adt_def, target_adt_def);
10891089

10901090
let CustomCoerceUnsized::Struct(coerce_index) =
1091-
crate::custom_coerce_unsize_info(tcx, source_ty, target_ty);
1091+
match crate::custom_coerce_unsize_info(tcx, source_ty, target_ty) {
1092+
Ok(ccu) => ccu,
1093+
Err(e) => {
1094+
let e = Ty::new_error(tcx.tcx, e);
1095+
return (e, e);
1096+
}
1097+
};
10921098

10931099
let source_fields = &source_adt_def.non_enum_variant().fields;
10941100
let target_fields = &target_adt_def.non_enum_variant().fields;

‎compiler/rustc_monomorphize/src/lib.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use rustc_middle::query::{Providers, TyCtxtAt};
1515
use rustc_middle::traits;
1616
use rustc_middle::ty::adjustment::CustomCoerceUnsized;
1717
use rustc_middle::ty::{self, Ty};
18+
use rustc_span::ErrorGuaranteed;
1819

1920
mod collector;
2021
mod errors;
@@ -28,7 +29,7 @@ fn custom_coerce_unsize_info<'tcx>(
2829
tcx: TyCtxtAt<'tcx>,
2930
source_ty: Ty<'tcx>,
3031
target_ty: Ty<'tcx>,
31-
) -> CustomCoerceUnsized {
32+
) -> Result<CustomCoerceUnsized, ErrorGuaranteed> {
3233
let trait_ref = ty::TraitRef::from_lang_item(
3334
tcx.tcx,
3435
LangItem::CoerceUnsized,
@@ -40,7 +41,7 @@ fn custom_coerce_unsize_info<'tcx>(
4041
Ok(traits::ImplSource::UserDefined(traits::ImplSourceUserDefinedData {
4142
impl_def_id,
4243
..
43-
})) => tcx.coerce_unsized_info(impl_def_id).custom_kind.unwrap(),
44+
})) => Ok(tcx.coerce_unsized_info(impl_def_id)?.custom_kind.unwrap()),
4445
impl_source => {
4546
bug!("invalid `CoerceUnsized` impl_source: {:?}", impl_source);
4647
}

‎compiler/rustc_session/src/session.rs

-14
Original file line numberDiff line numberDiff line change
@@ -331,20 +331,6 @@ impl Session {
331331
}
332332
}
333333

334-
// FIXME(matthewjasper) Remove this method, it should never be needed.
335-
pub fn track_errors<F, T>(&self, f: F) -> Result<T, ErrorGuaranteed>
336-
where
337-
F: FnOnce() -> T,
338-
{
339-
let old_count = self.dcx().err_count();
340-
let result = f();
341-
if self.dcx().err_count() == old_count {
342-
Ok(result)
343-
} else {
344-
Err(self.dcx().delayed_bug("`self.err_count()` changed but an error was not emitted"))
345-
}
346-
}
347-
348334
/// Used for code paths of expensive computations that should only take place when
349335
/// warnings or errors are emitted. If no messages are emitted ("good path"), then
350336
/// it's likely a bug.

‎tests/ui/associated-consts/issue-105330.stderr

+3-9
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,7 @@ LL | impl TraitWAssocConst for impl Demo {
4141
|
4242
= note: `impl Trait` is only allowed in arguments and return types of functions and methods
4343

44-
error[E0131]: `main` function is not allowed to have generic parameters
45-
--> $DIR/issue-105330.rs:15:8
46-
|
47-
LL | fn main<A: TraitWAssocConst<A=32>>() {
48-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `main` cannot have generic parameters
49-
50-
error: aborting due to 6 previous errors
44+
error: aborting due to 5 previous errors
5145

52-
Some errors have detailed explanations: E0131, E0404, E0562, E0658.
53-
For more information about an error, try `rustc --explain E0131`.
46+
Some errors have detailed explanations: E0404, E0562, E0658.
47+
For more information about an error, try `rustc --explain E0404`.

‎tests/ui/associated-types/issue-38821.stderr

+267-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,272 @@ help: consider further restricting the associated type
1717
LL | Expr: Expression<SqlType=<Col::SqlType as IntoNullable>::Nullable>, <Col as Expression>::SqlType: NotNull,
1818
| +++++++++++++++++++++++++++++++++++++++
1919

20-
error: aborting due to 1 previous error
20+
error[E0277]: the trait bound `<Col as Expression>::SqlType: NotNull` is not satisfied
21+
--> $DIR/issue-38821.rs:25:1
22+
|
23+
LL | pub enum ColumnInsertValue<Col, Expr> where
24+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NotNull` is not implemented for `<Col as Expression>::SqlType`
25+
|
26+
note: required for `<Col as Expression>::SqlType` to implement `IntoNullable`
27+
--> $DIR/issue-38821.rs:9:18
28+
|
29+
LL | impl<T: NotNull> IntoNullable for T {
30+
| ------- ^^^^^^^^^^^^ ^
31+
| |
32+
| unsatisfied trait bound introduced here
33+
help: consider extending the `where` clause, but there might be an alternative better way to express this requirement
34+
|
35+
LL | Expr: Expression<SqlType=<Col::SqlType as IntoNullable>::Nullable>, <Col as Expression>::SqlType: NotNull
36+
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
37+
38+
error[E0277]: the trait bound `<Col as Expression>::SqlType: NotNull` is not satisfied
39+
--> $DIR/issue-38821.rs:25:1
40+
|
41+
LL | / pub enum ColumnInsertValue<Col, Expr> where
42+
LL | | Col: Column,
43+
LL | | Expr: Expression<SqlType=<Col::SqlType as IntoNullable>::Nullable>,
44+
LL | | {
45+
LL | | Expression(Col, Expr),
46+
LL | | Default(Col),
47+
LL | | }
48+
| |_^ the trait `NotNull` is not implemented for `<Col as Expression>::SqlType`
49+
|
50+
note: required for `<Col as Expression>::SqlType` to implement `IntoNullable`
51+
--> $DIR/issue-38821.rs:9:18
52+
|
53+
LL | impl<T: NotNull> IntoNullable for T {
54+
| ------- ^^^^^^^^^^^^ ^
55+
| |
56+
| unsatisfied trait bound introduced here
57+
help: consider extending the `where` clause, but there might be an alternative better way to express this requirement
58+
|
59+
LL | Expr: Expression<SqlType=<Col::SqlType as IntoNullable>::Nullable>, <Col as Expression>::SqlType: NotNull
60+
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
61+
62+
error[E0277]: the trait bound `<Col as Expression>::SqlType: NotNull` is not satisfied
63+
--> $DIR/issue-38821.rs:23:10
64+
|
65+
LL | #[derive(Debug, Copy, Clone)]
66+
| ^^^^^ the trait `NotNull` is not implemented for `<Col as Expression>::SqlType`
67+
|
68+
note: required for `<Col as Expression>::SqlType` to implement `IntoNullable`
69+
--> $DIR/issue-38821.rs:9:18
70+
|
71+
LL | impl<T: NotNull> IntoNullable for T {
72+
| ------- ^^^^^^^^^^^^ ^
73+
| |
74+
| unsatisfied trait bound introduced here
75+
= note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
76+
help: consider further restricting the associated type
77+
|
78+
LL | Expr: Expression<SqlType=<Col::SqlType as IntoNullable>::Nullable>, <Col as Expression>::SqlType: NotNull,
79+
| +++++++++++++++++++++++++++++++++++++++
80+
81+
error[E0277]: the trait bound `<Col as Expression>::SqlType: NotNull` is not satisfied
82+
--> $DIR/issue-38821.rs:23:10
83+
|
84+
LL | #[derive(Debug, Copy, Clone)]
85+
| ^^^^^ the trait `NotNull` is not implemented for `<Col as Expression>::SqlType`
86+
|
87+
note: required for `<Col as Expression>::SqlType` to implement `IntoNullable`
88+
--> $DIR/issue-38821.rs:9:18
89+
|
90+
LL | impl<T: NotNull> IntoNullable for T {
91+
| ------- ^^^^^^^^^^^^ ^
92+
| |
93+
| unsatisfied trait bound introduced here
94+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
95+
= note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
96+
help: consider further restricting the associated type
97+
|
98+
LL | Expr: Expression<SqlType=<Col::SqlType as IntoNullable>::Nullable>, <Col as Expression>::SqlType: NotNull,
99+
| +++++++++++++++++++++++++++++++++++++++
100+
101+
error[E0277]: the trait bound `<Col as Expression>::SqlType: NotNull` is not satisfied
102+
--> $DIR/issue-38821.rs:23:10
103+
|
104+
LL | #[derive(Debug, Copy, Clone)]
105+
| ^^^^^ the trait `NotNull` is not implemented for `<Col as Expression>::SqlType`
106+
|
107+
note: required for `<Col as Expression>::SqlType` to implement `IntoNullable`
108+
--> $DIR/issue-38821.rs:9:18
109+
|
110+
LL | impl<T: NotNull> IntoNullable for T {
111+
| ------- ^^^^^^^^^^^^ ^
112+
| |
113+
| unsatisfied trait bound introduced here
114+
= note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
115+
116+
error[E0277]: the trait bound `<Col as Expression>::SqlType: NotNull` is not satisfied
117+
--> $DIR/issue-38821.rs:23:10
118+
|
119+
LL | #[derive(Debug, Copy, Clone)]
120+
| ^^^^^ the trait `NotNull` is not implemented for `<Col as Expression>::SqlType`
121+
|
122+
note: required for `<Col as Expression>::SqlType` to implement `IntoNullable`
123+
--> $DIR/issue-38821.rs:9:18
124+
|
125+
LL | impl<T: NotNull> IntoNullable for T {
126+
| ------- ^^^^^^^^^^^^ ^
127+
| |
128+
| unsatisfied trait bound introduced here
129+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
130+
= note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
131+
132+
error[E0277]: the trait bound `<Col as Expression>::SqlType: NotNull` is not satisfied
133+
--> $DIR/issue-38821.rs:23:17
134+
|
135+
LL | #[derive(Debug, Copy, Clone)]
136+
| ^^^^ the trait `NotNull` is not implemented for `<Col as Expression>::SqlType`
137+
|
138+
note: required for `<Col as Expression>::SqlType` to implement `IntoNullable`
139+
--> $DIR/issue-38821.rs:9:18
140+
|
141+
LL | impl<T: NotNull> IntoNullable for T {
142+
| ------- ^^^^^^^^^^^^ ^
143+
| |
144+
| unsatisfied trait bound introduced here
145+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
146+
= note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info)
147+
help: consider further restricting the associated type
148+
|
149+
LL | Expr: Expression<SqlType=<Col::SqlType as IntoNullable>::Nullable>, <Col as Expression>::SqlType: NotNull,
150+
| +++++++++++++++++++++++++++++++++++++++
151+
152+
error[E0277]: the trait bound `<Col as Expression>::SqlType: NotNull` is not satisfied
153+
--> $DIR/issue-38821.rs:23:23
154+
|
155+
LL | #[derive(Debug, Copy, Clone)]
156+
| ^^^^^ the trait `NotNull` is not implemented for `<Col as Expression>::SqlType`
157+
|
158+
note: required for `<Col as Expression>::SqlType` to implement `IntoNullable`
159+
--> $DIR/issue-38821.rs:9:18
160+
|
161+
LL | impl<T: NotNull> IntoNullable for T {
162+
| ------- ^^^^^^^^^^^^ ^
163+
| |
164+
| unsatisfied trait bound introduced here
165+
= note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
166+
help: consider further restricting the associated type
167+
|
168+
LL | Expr: Expression<SqlType=<Col::SqlType as IntoNullable>::Nullable>, <Col as Expression>::SqlType: NotNull,
169+
| +++++++++++++++++++++++++++++++++++++++
170+
171+
error[E0277]: the trait bound `<Col as Expression>::SqlType: NotNull` is not satisfied
172+
--> $DIR/issue-38821.rs:23:23
173+
|
174+
LL | #[derive(Debug, Copy, Clone)]
175+
| ^^^^^ the trait `NotNull` is not implemented for `<Col as Expression>::SqlType`
176+
|
177+
note: required for `<Col as Expression>::SqlType` to implement `IntoNullable`
178+
--> $DIR/issue-38821.rs:9:18
179+
|
180+
LL | impl<T: NotNull> IntoNullable for T {
181+
| ------- ^^^^^^^^^^^^ ^
182+
| |
183+
| unsatisfied trait bound introduced here
184+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
185+
= note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
186+
help: consider further restricting the associated type
187+
|
188+
LL | Expr: Expression<SqlType=<Col::SqlType as IntoNullable>::Nullable>, <Col as Expression>::SqlType: NotNull,
189+
| +++++++++++++++++++++++++++++++++++++++
190+
191+
error[E0277]: the trait bound `<Col as Expression>::SqlType: NotNull` is not satisfied
192+
--> $DIR/issue-38821.rs:23:23
193+
|
194+
LL | #[derive(Debug, Copy, Clone)]
195+
| ^^^^^ the trait `NotNull` is not implemented for `<Col as Expression>::SqlType`
196+
|
197+
note: required for `<Col as Expression>::SqlType` to implement `IntoNullable`
198+
--> $DIR/issue-38821.rs:9:18
199+
|
200+
LL | impl<T: NotNull> IntoNullable for T {
201+
| ------- ^^^^^^^^^^^^ ^
202+
| |
203+
| unsatisfied trait bound introduced here
204+
= note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
205+
206+
error[E0277]: the trait bound `<Col as Expression>::SqlType: NotNull` is not satisfied
207+
--> $DIR/issue-38821.rs:23:23
208+
|
209+
LL | #[derive(Debug, Copy, Clone)]
210+
| ^^^^^ the trait `NotNull` is not implemented for `<Col as Expression>::SqlType`
211+
|
212+
note: required for `<Col as Expression>::SqlType` to implement `IntoNullable`
213+
--> $DIR/issue-38821.rs:9:18
214+
|
215+
LL | impl<T: NotNull> IntoNullable for T {
216+
| ------- ^^^^^^^^^^^^ ^
217+
| |
218+
| unsatisfied trait bound introduced here
219+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
220+
= note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
221+
222+
error[E0277]: the trait bound `<Col as Expression>::SqlType: NotNull` is not satisfied
223+
--> $DIR/issue-38821.rs:23:10
224+
|
225+
LL | #[derive(Debug, Copy, Clone)]
226+
| ^^^^^ the trait `NotNull` is not implemented for `<Col as Expression>::SqlType`
227+
|
228+
note: required for `<Col as Expression>::SqlType` to implement `IntoNullable`
229+
--> $DIR/issue-38821.rs:9:18
230+
|
231+
LL | impl<T: NotNull> IntoNullable for T {
232+
| ------- ^^^^^^^^^^^^ ^
233+
| |
234+
| unsatisfied trait bound introduced here
235+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
236+
= note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
237+
238+
error[E0277]: the trait bound `<Col as Expression>::SqlType: NotNull` is not satisfied
239+
--> $DIR/issue-38821.rs:23:10
240+
|
241+
LL | #[derive(Debug, Copy, Clone)]
242+
| ^^^^^ the trait `NotNull` is not implemented for `<Col as Expression>::SqlType`
243+
|
244+
note: required for `<Col as Expression>::SqlType` to implement `IntoNullable`
245+
--> $DIR/issue-38821.rs:9:18
246+
|
247+
LL | impl<T: NotNull> IntoNullable for T {
248+
| ------- ^^^^^^^^^^^^ ^
249+
| |
250+
| unsatisfied trait bound introduced here
251+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
252+
= note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
253+
254+
error[E0277]: the trait bound `<Col as Expression>::SqlType: NotNull` is not satisfied
255+
--> $DIR/issue-38821.rs:23:23
256+
|
257+
LL | #[derive(Debug, Copy, Clone)]
258+
| ^^^^^ the trait `NotNull` is not implemented for `<Col as Expression>::SqlType`
259+
|
260+
note: required for `<Col as Expression>::SqlType` to implement `IntoNullable`
261+
--> $DIR/issue-38821.rs:9:18
262+
|
263+
LL | impl<T: NotNull> IntoNullable for T {
264+
| ------- ^^^^^^^^^^^^ ^
265+
| |
266+
| unsatisfied trait bound introduced here
267+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
268+
= note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
269+
270+
error[E0277]: the trait bound `<Col as Expression>::SqlType: NotNull` is not satisfied
271+
--> $DIR/issue-38821.rs:23:23
272+
|
273+
LL | #[derive(Debug, Copy, Clone)]
274+
| ^^^^^ the trait `NotNull` is not implemented for `<Col as Expression>::SqlType`
275+
|
276+
note: required for `<Col as Expression>::SqlType` to implement `IntoNullable`
277+
--> $DIR/issue-38821.rs:9:18
278+
|
279+
LL | impl<T: NotNull> IntoNullable for T {
280+
| ------- ^^^^^^^^^^^^ ^
281+
| |
282+
| unsatisfied trait bound introduced here
283+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
284+
= note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
285+
286+
error: aborting due to 16 previous errors
21287

22288
For more information about this error, try `rustc --explain E0277`.

‎tests/ui/const-generics/bad-generic-in-copy-impl.rs

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
pub struct Foo {
33
x: [u8; SIZE],
44
//~^ ERROR mismatched types
5+
//~| ERROR mismatched types
56
}
67

78
const SIZE: u32 = 1;

‎tests/ui/const-generics/bad-generic-in-copy-impl.stderr

+9-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@ error[E0308]: mismatched types
44
LL | x: [u8; SIZE],
55
| ^^^^ expected `usize`, found `u32`
66

7-
error: aborting due to 1 previous error
7+
error[E0308]: mismatched types
8+
--> $DIR/bad-generic-in-copy-impl.rs:3:13
9+
|
10+
LL | x: [u8; SIZE],
11+
| ^^^^ expected `usize`, found `u32`
12+
|
13+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
14+
15+
error: aborting due to 2 previous errors
816

917
For more information about this error, try `rustc --explain E0308`.
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,18 @@
1+
error[E0277]: the trait bound `[u8; 13]: Q` is not satisfied
2+
--> $DIR/bad-subst-const-kind.rs:13:24
3+
|
4+
LL | pub fn test() -> [u8; <[u8; 13] as Q>::ASSOC] { todo!() }
5+
| ^^^^^^^^ the trait `Q` is not implemented for `[u8; 13]`
6+
|
7+
= help: the trait `Q` is implemented for `[u8; N]`
8+
19
error[E0308]: mismatched types
210
--> $DIR/bad-subst-const-kind.rs:8:31
311
|
412
LL | impl<const N: u64> Q for [u8; N] {
513
| ^ expected `usize`, found `u64`
614

7-
error: aborting due to 1 previous error
15+
error: aborting due to 2 previous errors
816

9-
For more information about this error, try `rustc --explain E0308`.
17+
Some errors have detailed explanations: E0277, E0308.
18+
For more information about an error, try `rustc --explain E0277`.

‎tests/ui/const-generics/generic_const_exprs/type_mismatch.stderr

+25-2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,29 @@ LL | const ASSOC: usize;
77
LL | impl<const N: u64> Q for [u8; N] {}
88
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `ASSOC` in implementation
99

10-
error: aborting due to 1 previous error
10+
error[E0277]: the trait bound `[u8; 13]: Q` is not satisfied
11+
--> $DIR/type_mismatch.rs:11:26
12+
|
13+
LL | pub fn q_user() -> [u8; <[u8; 13] as Q>::ASSOC] {}
14+
| ^^^^^^^^ the trait `Q` is not implemented for `[u8; 13]`
15+
|
16+
= help: the trait `Q` is implemented for `[u8; N]`
17+
18+
error[E0308]: mismatched types
19+
--> $DIR/type_mismatch.rs:11:20
20+
|
21+
LL | pub fn q_user() -> [u8; <[u8; 13] as Q>::ASSOC] {}
22+
| ------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `[u8; <[u8; 13] as Q>::ASSOC]`, found `()`
23+
| |
24+
| implicitly returns `()` as its body has no tail or `return` expression
25+
26+
error[E0308]: mismatched types
27+
--> $DIR/type_mismatch.rs:8:31
28+
|
29+
LL | impl<const N: u64> Q for [u8; N] {}
30+
| ^ expected `usize`, found `u64`
31+
32+
error: aborting due to 4 previous errors
1133

12-
For more information about this error, try `rustc --explain E0046`.
34+
Some errors have detailed explanations: E0046, E0277, E0308.
35+
For more information about an error, try `rustc --explain E0046`.

‎tests/ui/enum-discriminant/issue-72554.stderr

+17-2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,21 @@ help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle
1212
LL | A(Box<ElemDerived>)
1313
| ++++ +
1414

15-
error: aborting due to 1 previous error
15+
error[E0391]: cycle detected when computing drop-check constraints for `ElemDerived`
16+
--> $DIR/issue-72554.rs:4:1
17+
|
18+
LL | pub enum ElemDerived {
19+
| ^^^^^^^^^^^^^^^^^^^^
20+
|
21+
= note: ...which immediately requires computing drop-check constraints for `ElemDerived` again
22+
note: cycle used when computing drop-check constraints for `Elem`
23+
--> $DIR/issue-72554.rs:10:1
24+
|
25+
LL | pub enum Elem {
26+
| ^^^^^^^^^^^^^
27+
= 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
28+
29+
error: aborting due to 2 previous errors
1630

17-
For more information about this error, try `rustc --explain E0072`.
31+
Some errors have detailed explanations: E0072, E0391.
32+
For more information about an error, try `rustc --explain E0072`.

‎tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness-2.stderr

+2-12
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,6 @@ LL | impl<T: Default> A for T {
77
LL | impl<T: Default + ~const Sup> const A for T {
88
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation
99

10-
error[E0308]: mismatched types
11-
--> $DIR/specializing-constness-2.rs:27:5
12-
|
13-
LL | <T as A>::a();
14-
| ^^^^^^^^^^^^^ expected `host`, found `true`
15-
|
16-
= note: expected constant `host`
17-
found constant `true`
18-
19-
error: aborting due to 2 previous errors
10+
error: aborting due to 1 previous error
2011

21-
Some errors have detailed explanations: E0119, E0308.
22-
For more information about an error, try `rustc --explain E0119`.
12+
For more information about this error, try `rustc --explain E0119`.

‎tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.rs

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ struct S<const L: usize>;
77

88
impl<const N: i32> Copy for S<N> {}
99
//~^ ERROR the constant `N` is not of type `usize`
10+
//~| ERROR the trait bound `S<N>: Clone` is not satisfied
1011
impl<const M: usize> Copy for S<M> {}
1112

1213
fn main() {}

‎tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.stderr

+17-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,18 @@
1+
error[E0277]: the trait bound `S<N>: Clone` is not satisfied
2+
--> $DIR/bad-const-wf-doesnt-specialize.rs:8:29
3+
|
4+
LL | impl<const N: i32> Copy for S<N> {}
5+
| ^^^^ the trait `Clone` is not implemented for `S<N>`
6+
|
7+
= help: the trait `Clone` is implemented for `S<L>`
8+
note: required by a bound in `Copy`
9+
--> $SRC_DIR/core/src/marker.rs:LL:COL
10+
help: consider annotating `S<N>` with `#[derive(Clone)]`
11+
|
12+
LL + #[derive(Clone)]
13+
LL | struct S<const L: usize>;
14+
|
15+
116
error: the constant `N` is not of type `usize`
217
--> $DIR/bad-const-wf-doesnt-specialize.rs:8:29
318
|
@@ -10,5 +25,6 @@ note: required by a bound in `S`
1025
LL | struct S<const L: usize>;
1126
| ^^^^^^^^^^^^^^ required by this bound in `S`
1227

13-
error: aborting due to 1 previous error
28+
error: aborting due to 2 previous errors
1429

30+
For more information about this error, try `rustc --explain E0277`.

‎tests/ui/typeck/typeck_type_placeholder_item.stderr

+3-12
Original file line numberDiff line numberDiff line change
@@ -657,16 +657,7 @@ LL | const D: _ = 42;
657657
| not allowed in type signatures
658658
| help: replace with the correct type: `i32`
659659

660-
error[E0046]: not all trait items implemented, missing: `F`
661-
--> $DIR/typeck_type_placeholder_item.rs:200:1
662-
|
663-
LL | type F: std::ops::Fn(_);
664-
| ----------------------- `F` from trait
665-
...
666-
LL | impl Qux for Struct {
667-
| ^^^^^^^^^^^^^^^^^^^ missing `F` in implementation
668-
669-
error: aborting due to 72 previous errors
660+
error: aborting due to 71 previous errors
670661

671-
Some errors have detailed explanations: E0046, E0121, E0282, E0403.
672-
For more information about an error, try `rustc --explain E0046`.
662+
Some errors have detailed explanations: E0121, E0282, E0403.
663+
For more information about an error, try `rustc --explain E0121`.

0 commit comments

Comments
 (0)
Please sign in to comment.