Skip to content

Commit 2944454

Browse files
authored
Rollup merge of #99353 - compiler-errors:gat-where-clause-mismatch, r=cjgillot
Slightly improve mismatched GAT where clause error This makes the error reporting a bit more standardized between `where` on GATs and functions. cc #99206 (`@BoxyUwU),` don't want to mark this as as "fixed" because they're still not perfect, but this is still an improvement IMO so I want to land it incrementally. regarding "consider adding where clause to trait definition", we don't actually do that for methods as far as i can tell? i could file an issue to look into that maybe.
2 parents d3acd00 + 3bbe95c commit 2944454

22 files changed

+126
-208
lines changed

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

+20-6
Original file line numberDiff line numberDiff line change
@@ -1883,7 +1883,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
18831883
exp_span, exp_found.expected, exp_found.found,
18841884
);
18851885

1886-
if let ObligationCauseCode::CompareImplMethodObligation { .. } = cause.code() {
1886+
if let ObligationCauseCode::CompareImplItemObligation { .. } = cause.code() {
18871887
return;
18881888
}
18891889

@@ -2351,7 +2351,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
23512351
GenericKind::Projection(ref p) => format!("the associated type `{}`", p),
23522352
};
23532353

2354-
if let Some(SubregionOrigin::CompareImplMethodObligation {
2354+
if let Some(SubregionOrigin::CompareImplItemObligation {
23552355
span,
23562356
impl_item_def_id,
23572357
trait_item_def_id,
@@ -2788,8 +2788,15 @@ impl<'tcx> ObligationCauseExt<'tcx> for ObligationCause<'tcx> {
27882788
use self::FailureCode::*;
27892789
use crate::traits::ObligationCauseCode::*;
27902790
match self.code() {
2791-
CompareImplMethodObligation { .. } => Error0308("method not compatible with trait"),
2792-
CompareImplTypeObligation { .. } => Error0308("type not compatible with trait"),
2791+
CompareImplItemObligation { kind: ty::AssocKind::Fn, .. } => {
2792+
Error0308("method not compatible with trait")
2793+
}
2794+
CompareImplItemObligation { kind: ty::AssocKind::Type, .. } => {
2795+
Error0308("type not compatible with trait")
2796+
}
2797+
CompareImplItemObligation { kind: ty::AssocKind::Const, .. } => {
2798+
Error0308("const not compatible with trait")
2799+
}
27932800
MatchExpressionArm(box MatchExpressionArmCause { source, .. }) => {
27942801
Error0308(match source {
27952802
hir::MatchSource::TryDesugar => "`?` operator has incompatible types",
@@ -2823,8 +2830,15 @@ impl<'tcx> ObligationCauseExt<'tcx> for ObligationCause<'tcx> {
28232830
fn as_requirement_str(&self) -> &'static str {
28242831
use crate::traits::ObligationCauseCode::*;
28252832
match self.code() {
2826-
CompareImplMethodObligation { .. } => "method type is compatible with trait",
2827-
CompareImplTypeObligation { .. } => "associated type is compatible with trait",
2833+
CompareImplItemObligation { kind: ty::AssocKind::Fn, .. } => {
2834+
"method type is compatible with trait"
2835+
}
2836+
CompareImplItemObligation { kind: ty::AssocKind::Type, .. } => {
2837+
"associated type is compatible with trait"
2838+
}
2839+
CompareImplItemObligation { kind: ty::AssocKind::Const, .. } => {
2840+
"const is compatible with trait"
2841+
}
28282842
ExprAssignable => "expression is assignable",
28292843
IfExpression { .. } => "`if` and `else` have incompatible types",
28302844
IfExpressionWithNoElse => "`if` missing an `else` returns `()`",

compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs

+17-52
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,17 @@
22
33
use crate::infer::error_reporting::nice_region_error::NiceRegionError;
44
use crate::infer::lexical_region_resolve::RegionResolutionError;
5-
use crate::infer::{SubregionOrigin, Subtype};
6-
use crate::traits::ObligationCauseCode::CompareImplMethodObligation;
5+
use crate::infer::Subtype;
6+
use crate::traits::ObligationCauseCode::CompareImplItemObligation;
77
use rustc_errors::{ErrorGuaranteed, MultiSpan};
88
use rustc_hir as hir;
99
use rustc_hir::def::Res;
10-
use rustc_hir::def_id::{DefId, LocalDefId};
10+
use rustc_hir::def_id::DefId;
1111
use rustc_hir::intravisit::Visitor;
1212
use rustc_middle::hir::nested_filter;
1313
use rustc_middle::ty::print::RegionHighlightMode;
1414
use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitor};
15-
use rustc_span::{Span, Symbol};
15+
use rustc_span::Span;
1616

1717
use std::ops::ControlFlow;
1818

@@ -22,38 +22,22 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
2222
let error = self.error.as_ref()?;
2323
debug!("try_report_impl_not_conforming_to_trait {:?}", error);
2424
if let RegionResolutionError::SubSupConflict(
25-
_, var_origin, sub_origin, _sub, sup_origin, _sup, _,
25+
_,
26+
var_origin,
27+
sub_origin,
28+
_sub,
29+
sup_origin,
30+
_sup,
31+
_,
2632
) = error.clone()
27-
&& let (&Subtype(ref sup_trace), &Subtype(ref sub_trace)) = (&sup_origin, &sub_origin)
28-
&& let (
29-
sub_expected_found @ Some((sub_expected, sub_found)),
30-
sup_expected_found @ Some(_),
31-
CompareImplMethodObligation { trait_item_def_id, .. },
32-
) = (sub_trace.values.ty(), sup_trace.values.ty(), sub_trace.cause.code())
33+
&& let (Subtype(sup_trace), Subtype(sub_trace)) = (&sup_origin, &sub_origin)
34+
&& let sub_expected_found @ Some((sub_expected, sub_found)) = sub_trace.values.ty()
35+
&& let sup_expected_found @ Some(_) = sup_trace.values.ty()
36+
&& let CompareImplItemObligation { trait_item_def_id, .. } = sub_trace.cause.code()
3337
&& sup_expected_found == sub_expected_found
3438
{
35-
let guar = self.emit_err(
36-
var_origin.span(),
37-
sub_expected,
38-
sub_found,
39-
*trait_item_def_id,
40-
);
41-
return Some(guar);
42-
}
43-
if let RegionResolutionError::ConcreteFailure(origin, _, _)
44-
| RegionResolutionError::GenericBoundFailure(origin, _, _) = error.clone()
45-
&& let SubregionOrigin::CompareImplTypeObligation {
46-
span,
47-
impl_item_def_id,
48-
trait_item_def_id,
49-
} = origin
50-
{
51-
let guar = self.emit_associated_type_err(
52-
span,
53-
self.infcx.tcx.item_name(impl_item_def_id.to_def_id()),
54-
impl_item_def_id,
55-
trait_item_def_id,
56-
);
39+
let guar =
40+
self.emit_err(var_origin.span(), sub_expected, sub_found, *trait_item_def_id);
5741
return Some(guar);
5842
}
5943
None
@@ -147,25 +131,6 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
147131
}
148132
err.emit()
149133
}
150-
151-
fn emit_associated_type_err(
152-
&self,
153-
span: Span,
154-
item_name: Symbol,
155-
impl_item_def_id: LocalDefId,
156-
trait_item_def_id: DefId,
157-
) -> ErrorGuaranteed {
158-
let impl_sp = self.tcx().def_span(impl_item_def_id);
159-
let trait_sp = self.tcx().def_span(trait_item_def_id);
160-
let mut err = self
161-
.tcx()
162-
.sess
163-
.struct_span_err(span, &format!("`impl` associated type signature for `{}` doesn't match `trait` associated type signature", item_name));
164-
err.span_label(impl_sp, "found");
165-
err.span_label(trait_sp, "expected");
166-
167-
err.emit()
168-
}
169134
}
170135

171136
struct TypeParamSpanVisitor<'tcx> {

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

+2-16
Original file line numberDiff line numberDiff line change
@@ -86,13 +86,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
8686
"...so that the declared lifetime parameter bounds are satisfied",
8787
);
8888
}
89-
infer::CompareImplMethodObligation { span, .. } => {
90-
label_or_note(
91-
span,
92-
"...so that the definition in impl matches the definition from the trait",
93-
);
94-
}
95-
infer::CompareImplTypeObligation { span, .. } => {
89+
infer::CompareImplItemObligation { span, .. } => {
9690
label_or_note(
9791
span,
9892
"...so that the definition in impl matches the definition from the trait",
@@ -329,15 +323,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
329323
);
330324
err
331325
}
332-
infer::CompareImplMethodObligation { span, impl_item_def_id, trait_item_def_id } => {
333-
self.report_extra_impl_obligation(
334-
span,
335-
impl_item_def_id,
336-
trait_item_def_id,
337-
&format!("`{}: {}`", sup, sub),
338-
)
339-
}
340-
infer::CompareImplTypeObligation { span, impl_item_def_id, trait_item_def_id } => self
326+
infer::CompareImplItemObligation { span, impl_item_def_id, trait_item_def_id } => self
341327
.report_extra_impl_obligation(
342328
span,
343329
impl_item_def_id,

compiler/rustc_infer/src/infer/mod.rs

+5-22
Original file line numberDiff line numberDiff line change
@@ -405,15 +405,7 @@ pub enum SubregionOrigin<'tcx> {
405405

406406
/// Comparing the signature and requirements of an impl method against
407407
/// the containing trait.
408-
CompareImplMethodObligation {
409-
span: Span,
410-
impl_item_def_id: LocalDefId,
411-
trait_item_def_id: DefId,
412-
},
413-
414-
/// Comparing the signature and requirements of an impl associated type
415-
/// against the containing trait
416-
CompareImplTypeObligation { span: Span, impl_item_def_id: LocalDefId, trait_item_def_id: DefId },
408+
CompareImplItemObligation { span: Span, impl_item_def_id: LocalDefId, trait_item_def_id: DefId },
417409

418410
/// Checking that the bounds of a trait's associated type hold for a given impl
419411
CheckAssociatedTypeBounds {
@@ -1945,8 +1937,7 @@ impl<'tcx> SubregionOrigin<'tcx> {
19451937
ReborrowUpvar(a, _) => a,
19461938
DataBorrowed(_, a) => a,
19471939
ReferenceOutlivesReferent(_, a) => a,
1948-
CompareImplMethodObligation { span, .. } => span,
1949-
CompareImplTypeObligation { span, .. } => span,
1940+
CompareImplItemObligation { span, .. } => span,
19501941
CheckAssociatedTypeBounds { ref parent, .. } => parent.span(),
19511942
}
19521943
}
@@ -1960,19 +1951,11 @@ impl<'tcx> SubregionOrigin<'tcx> {
19601951
SubregionOrigin::ReferenceOutlivesReferent(ref_type, cause.span)
19611952
}
19621953

1963-
traits::ObligationCauseCode::CompareImplMethodObligation {
1964-
impl_item_def_id,
1965-
trait_item_def_id,
1966-
} => SubregionOrigin::CompareImplMethodObligation {
1967-
span: cause.span,
1968-
impl_item_def_id,
1969-
trait_item_def_id,
1970-
},
1971-
1972-
traits::ObligationCauseCode::CompareImplTypeObligation {
1954+
traits::ObligationCauseCode::CompareImplItemObligation {
19731955
impl_item_def_id,
19741956
trait_item_def_id,
1975-
} => SubregionOrigin::CompareImplTypeObligation {
1957+
kind: _,
1958+
} => SubregionOrigin::CompareImplItemObligation {
19761959
span: cause.span,
19771960
impl_item_def_id,
19781961
trait_item_def_id,

compiler/rustc_middle/src/traits/mod.rs

+2-10
Original file line numberDiff line numberDiff line change
@@ -311,18 +311,10 @@ pub enum ObligationCauseCode<'tcx> {
311311
},
312312

313313
/// Error derived when matching traits/impls; see ObligationCause for more details
314-
CompareImplConstObligation,
315-
316-
/// Error derived when matching traits/impls; see ObligationCause for more details
317-
CompareImplMethodObligation {
318-
impl_item_def_id: LocalDefId,
319-
trait_item_def_id: DefId,
320-
},
321-
322-
/// Error derived when matching traits/impls; see ObligationCause for more details
323-
CompareImplTypeObligation {
314+
CompareImplItemObligation {
324315
impl_item_def_id: LocalDefId,
325316
trait_item_def_id: DefId,
317+
kind: ty::AssocKind,
326318
},
327319

328320
/// Checking that the bounds of a trait's associated type hold for a given impl

compiler/rustc_middle/src/ty/assoc.rs

+10
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,16 @@ impl AssocKind {
105105
}
106106
}
107107

108+
impl std::fmt::Display for AssocKind {
109+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
110+
match self {
111+
AssocKind::Fn => write!(f, "method"),
112+
AssocKind::Const => write!(f, "associated const"),
113+
AssocKind::Type => write!(f, "associated type"),
114+
}
115+
}
116+
}
117+
108118
/// A list of `ty::AssocItem`s in definition order that allows for efficient lookup by name.
109119
///
110120
/// When doing lookup by name, we try to postpone hygienic comparison for as long as possible since

compiler/rustc_middle/src/ty/error.rs

+2-6
Original file line numberDiff line numberDiff line change
@@ -660,12 +660,8 @@ impl<T> Trait<T> for X {
660660
| hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Fn(..), .. }),
661661
)
662662
);
663-
let impl_comparison = matches!(
664-
cause_code,
665-
ObligationCauseCode::CompareImplMethodObligation { .. }
666-
| ObligationCauseCode::CompareImplTypeObligation { .. }
667-
| ObligationCauseCode::CompareImplConstObligation
668-
);
663+
let impl_comparison =
664+
matches!(cause_code, ObligationCauseCode::CompareImplItemObligation { .. });
669665
let assoc = self.associated_item(proj_ty.item_def_id);
670666
if !callable_scope || impl_comparison {
671667
// We do not want to suggest calling functions when the reason of the

compiler/rustc_middle/src/ty/structural_impls.rs

+1
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ TrivialTypeTraversalAndLiftImpls! {
224224
// general `Region`.
225225
crate::ty::BoundRegionKind,
226226
crate::ty::AssocItem,
227+
crate::ty::AssocKind,
227228
crate::ty::Placeholder<crate::ty::BoundRegionKind>,
228229
crate::ty::ClosureKind,
229230
crate::ty::FreeRegion,

compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -301,13 +301,10 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
301301
span = obligation.cause.span;
302302
}
303303
}
304-
if let ObligationCauseCode::CompareImplMethodObligation {
305-
impl_item_def_id,
306-
trait_item_def_id,
307-
}
308-
| ObligationCauseCode::CompareImplTypeObligation {
304+
if let ObligationCauseCode::CompareImplItemObligation {
309305
impl_item_def_id,
310306
trait_item_def_id,
307+
kind: _,
311308
} = *obligation.cause.code()
312309
{
313310
self.report_extra_impl_obligation(

compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs

+4-36
Original file line numberDiff line numberDiff line change
@@ -2682,11 +2682,11 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
26822682
)
26832683
});
26842684
}
2685-
ObligationCauseCode::CompareImplMethodObligation { trait_item_def_id, .. } => {
2685+
ObligationCauseCode::CompareImplItemObligation { trait_item_def_id, kind, .. } => {
26862686
let item_name = self.tcx.item_name(trait_item_def_id);
26872687
let msg = format!(
2688-
"the requirement `{}` appears on the impl method `{}` but not on the \
2689-
corresponding trait method",
2688+
"the requirement `{}` appears on the `impl`'s {kind} `{}` but not on the \
2689+
corresponding trait's {kind}",
26902690
predicate, item_name,
26912691
);
26922692
let sp = self
@@ -2697,7 +2697,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
26972697
let mut assoc_span: MultiSpan = sp.into();
26982698
assoc_span.push_span_label(
26992699
sp,
2700-
format!("this trait method doesn't have the requirement `{}`", predicate),
2700+
format!("this trait's {kind} doesn't have the requirement `{}`", predicate),
27012701
);
27022702
if let Some(ident) = self
27032703
.tcx
@@ -2708,38 +2708,6 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
27082708
}
27092709
err.span_note(assoc_span, &msg);
27102710
}
2711-
ObligationCauseCode::CompareImplTypeObligation { trait_item_def_id, .. } => {
2712-
let item_name = self.tcx.item_name(trait_item_def_id);
2713-
let msg = format!(
2714-
"the requirement `{}` appears on the associated impl type `{}` but not on the \
2715-
corresponding associated trait type",
2716-
predicate, item_name,
2717-
);
2718-
let sp = self.tcx.def_span(trait_item_def_id);
2719-
let mut assoc_span: MultiSpan = sp.into();
2720-
assoc_span.push_span_label(
2721-
sp,
2722-
format!(
2723-
"this trait associated type doesn't have the requirement `{}`",
2724-
predicate,
2725-
),
2726-
);
2727-
if let Some(ident) = self
2728-
.tcx
2729-
.opt_associated_item(trait_item_def_id)
2730-
.and_then(|i| self.tcx.opt_item_ident(i.container.id()))
2731-
{
2732-
assoc_span.push_span_label(ident.span, "in this trait");
2733-
}
2734-
err.span_note(assoc_span, &msg);
2735-
}
2736-
ObligationCauseCode::CompareImplConstObligation => {
2737-
err.note(&format!(
2738-
"the requirement `{}` appears on the associated impl constant \
2739-
but not on the corresponding associated trait constant",
2740-
predicate
2741-
));
2742-
}
27432711
ObligationCauseCode::TrivialBound => {
27442712
err.help("see issue #48214");
27452713
if tcx.sess.opts.unstable_features.is_nightly_build() {

compiler/rustc_typeck/src/astconv/mod.rs

+2-7
Original file line numberDiff line numberDiff line change
@@ -1150,17 +1150,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
11501150
.expect("missing associated type");
11511151

11521152
if !assoc_item.vis.is_accessible_from(def_scope, tcx) {
1153-
let kind = match assoc_item.kind {
1154-
ty::AssocKind::Type => "type",
1155-
ty::AssocKind::Const => "const",
1156-
_ => unreachable!(),
1157-
};
11581153
tcx.sess
11591154
.struct_span_err(
11601155
binding.span,
1161-
&format!("associated {kind} `{}` is private", binding.item_name),
1156+
&format!("{} `{}` is private", assoc_item.kind, binding.item_name),
11621157
)
1163-
.span_label(binding.span, &format!("private associated {kind}"))
1158+
.span_label(binding.span, &format!("private {}", assoc_item.kind))
11641159
.emit();
11651160
}
11661161
tcx.check_stability(assoc_item.def_id, Some(hir_ref_id), binding.span, None);

0 commit comments

Comments
 (0)