Skip to content

Commit 61c2b7a

Browse files
committed
Mention where implicit Sized obligations come from on E0277
WIP: ordering of `Sized` obligations can affect the presence of the note. Some tweaks needed to make this the best it can be.
1 parent c85ccdb commit 61c2b7a

File tree

66 files changed

+277
-69
lines changed

Some content is hidden

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

66 files changed

+277
-69
lines changed

compiler/rustc_infer/src/traits/util.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ impl Elaborator<'tcx> {
124124

125125
let bound_predicate = obligation.predicate.kind();
126126
match bound_predicate.skip_binder() {
127-
ty::PredicateKind::Trait(data, _) => {
127+
ty::PredicateKind::Trait(data, ..) => {
128128
// Get predicates declared on the trait.
129129
let predicates = tcx.super_predicates_of(data.def_id());
130130

compiler/rustc_lint/src/traits.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ impl<'tcx> LateLintPass<'tcx> for DropTraitConstraints {
5050
let predicates = cx.tcx.explicit_predicates_of(item.def_id);
5151
for &(predicate, span) in predicates.predicates {
5252
let trait_predicate = match predicate.kind().skip_binder() {
53-
Trait(trait_predicate, _constness) => trait_predicate,
53+
Trait(trait_predicate, _constness, _) => trait_predicate,
5454
_ => continue,
5555
};
5656
let def_id = trait_predicate.trait_ref.def_id;

compiler/rustc_lint/src/unused.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
202202
let mut has_emitted = false;
203203
for &(predicate, _) in cx.tcx.explicit_item_bounds(def) {
204204
// We only look at the `DefId`, so it is safe to skip the binder here.
205-
if let ty::PredicateKind::Trait(ref poly_trait_predicate, _) =
205+
if let ty::PredicateKind::Trait(ref poly_trait_predicate, _, _) =
206206
predicate.kind().skip_binder()
207207
{
208208
let def_id = poly_trait_predicate.trait_ref.def_id;

compiler/rustc_middle/src/ty/assoc.rs

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,44 @@ impl AssocItem {
5858
// regions just fine, showing `fn(&MyType)`.
5959
tcx.fn_sig(self.def_id).skip_binder().to_string()
6060
}
61-
ty::AssocKind::Type => format!("type {};", self.ident),
61+
ty::AssocKind::Type => {
62+
let default = match tcx.hir().get_if_local(self.def_id) {
63+
Some(
64+
hir::Node::TraitItem(hir::TraitItem {
65+
kind: hir::TraitItemKind::Type(_, Some(ty)),
66+
..
67+
})
68+
| hir::Node::ImplItem(hir::ImplItem {
69+
kind: hir::ImplItemKind::TyAlias(ty),
70+
..
71+
}),
72+
) => {
73+
format!(" = {:?}", ty)
74+
}
75+
_ => String::new(),
76+
};
77+
format!("type {}{};", self.ident, default)
78+
}
6279
ty::AssocKind::Const => {
63-
format!("const {}: {:?};", self.ident, tcx.type_of(self.def_id))
80+
let default = match tcx.hir().get_if_local(self.def_id) {
81+
Some(
82+
hir::Node::TraitItem(hir::TraitItem {
83+
kind: hir::TraitItemKind::Const(_, Some(body_id)),
84+
..
85+
})
86+
| hir::Node::ImplItem(hir::ImplItem {
87+
kind: hir::ImplItemKind::Const(_, body_id),
88+
..
89+
}),
90+
) => match tcx.hir().find(body_id.hir_id) {
91+
Some(value) => {
92+
format!(" = {:?}", value)
93+
}
94+
None => String::new(),
95+
},
96+
_ => String::new(),
97+
};
98+
format!("const {}: {:?}{};", self.ident, tcx.type_of(self.def_id), default)
6499
}
65100
}
66101
}

compiler/rustc_middle/src/ty/context.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2110,7 +2110,7 @@ impl<'tcx> TyCtxt<'tcx> {
21102110
let generic_predicates = self.super_predicates_of(trait_did);
21112111

21122112
for (predicate, _) in generic_predicates.predicates {
2113-
if let ty::PredicateKind::Trait(data, _) = predicate.kind().skip_binder() {
2113+
if let ty::PredicateKind::Trait(data, ..) = predicate.kind().skip_binder() {
21142114
if set.insert(data.def_id()) {
21152115
stack.push(data.def_id());
21162116
}

compiler/rustc_middle/src/ty/flags.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ impl FlagComputation {
216216

217217
fn add_predicate_atom(&mut self, atom: ty::PredicateKind<'_>) {
218218
match atom {
219-
ty::PredicateKind::Trait(trait_pred, _constness) => {
219+
ty::PredicateKind::Trait(trait_pred, _constness, _) => {
220220
self.add_substs(trait_pred.trait_ref.substs);
221221
}
222222
ty::PredicateKind::RegionOutlives(ty::OutlivesPredicate(a, b)) => {

compiler/rustc_middle/src/ty/mod.rs

Lines changed: 71 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,38 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for Predicate<'tcx> {
425425
}
426426
}
427427

428+
#[derive(Clone, Copy, Debug, Eq, TyEncodable, TyDecodable, TypeFoldable)]
429+
pub enum ImplicitTraitPredicate {
430+
Yes,
431+
No,
432+
}
433+
434+
impl Hash for ImplicitTraitPredicate {
435+
fn hash<H>(&self, _: &mut H)
436+
where
437+
H: Hasher,
438+
{
439+
// This type is used purely for improving diagnostics involving default `Sized` bounds on
440+
// type parameters and associated types, it has no incidence whatsoever on anything else.
441+
}
442+
}
443+
444+
impl<CTX> ::rustc_data_structures::stable_hasher::HashStable<CTX> for ImplicitTraitPredicate {
445+
#[inline]
446+
fn hash_stable(&self, _hcx: &mut CTX, _hasher: &mut StableHasher) {
447+
// This type is used purely for improving diagnostics involving default `Sized` bounds on
448+
// type parameters and associated types, it has no incidence whatsoever on anything else.
449+
}
450+
}
451+
452+
impl PartialEq for ImplicitTraitPredicate {
453+
fn eq(&self, _: &ImplicitTraitPredicate) -> bool {
454+
// This type is used purely for improving diagnostics involving default `Sized` bounds on
455+
// type parameters and associated types, it has no incidence whatsoever on anything else.
456+
true
457+
}
458+
}
459+
428460
#[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
429461
#[derive(HashStable, TypeFoldable)]
430462
pub enum PredicateKind<'tcx> {
@@ -435,7 +467,7 @@ pub enum PredicateKind<'tcx> {
435467
/// A trait predicate will have `Constness::Const` if it originates
436468
/// from a bound on a `const fn` without the `?const` opt-out (e.g.,
437469
/// `const fn foobar<Foo: Bar>() {}`).
438-
Trait(TraitPredicate<'tcx>, Constness),
470+
Trait(TraitPredicate<'tcx>, Constness, ImplicitTraitPredicate),
439471

440472
/// `where 'a: 'b`
441473
RegionOutlives(RegionOutlivesPredicate<'tcx>),
@@ -724,24 +756,47 @@ impl ToPredicate<'tcx> for PredicateKind<'tcx> {
724756

725757
impl<'tcx> ToPredicate<'tcx> for ConstnessAnd<TraitRef<'tcx>> {
726758
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
727-
PredicateKind::Trait(ty::TraitPredicate { trait_ref: self.value }, self.constness)
728-
.to_predicate(tcx)
759+
PredicateKind::Trait(
760+
ty::TraitPredicate { trait_ref: self.value },
761+
self.constness,
762+
ImplicitTraitPredicate::No,
763+
)
764+
.to_predicate(tcx)
765+
}
766+
}
767+
768+
impl<'tcx> ToPredicate<'tcx> for ImplicitSized<ConstnessAnd<Binder<'tcx, TraitRef<'tcx>>>> {
769+
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
770+
PredicateKind::Trait(
771+
ty::TraitPredicate { trait_ref: self.0.value.skip_binder() },
772+
self.0.constness,
773+
ImplicitTraitPredicate::Yes,
774+
)
775+
.to_predicate(tcx)
729776
}
730777
}
731778

732779
impl<'tcx> ToPredicate<'tcx> for ConstnessAnd<PolyTraitRef<'tcx>> {
733780
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
734781
self.value
735782
.map_bound(|trait_ref| {
736-
PredicateKind::Trait(ty::TraitPredicate { trait_ref }, self.constness)
783+
PredicateKind::Trait(
784+
ty::TraitPredicate { trait_ref },
785+
self.constness,
786+
ImplicitTraitPredicate::No,
787+
)
737788
})
738789
.to_predicate(tcx)
739790
}
740791
}
741792

742793
impl<'tcx> ToPredicate<'tcx> for ConstnessAnd<PolyTraitPredicate<'tcx>> {
743794
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
744-
self.value.map_bound(|value| PredicateKind::Trait(value, self.constness)).to_predicate(tcx)
795+
self.value
796+
.map_bound(|value| {
797+
PredicateKind::Trait(value, self.constness, ImplicitTraitPredicate::No)
798+
})
799+
.to_predicate(tcx)
745800
}
746801
}
747802

@@ -767,7 +822,7 @@ impl<'tcx> Predicate<'tcx> {
767822
pub fn to_opt_poly_trait_ref(self) -> Option<ConstnessAnd<PolyTraitRef<'tcx>>> {
768823
let predicate = self.kind();
769824
match predicate.skip_binder() {
770-
PredicateKind::Trait(t, constness) => {
825+
PredicateKind::Trait(t, constness, _) => {
771826
Some(ConstnessAnd { constness, value: predicate.rebind(t.trait_ref) })
772827
}
773828
PredicateKind::Projection(..)
@@ -1259,7 +1314,17 @@ pub trait WithConstness: Sized {
12591314
}
12601315
}
12611316

1317+
pub struct ImplicitSized<T>(T);
1318+
1319+
pub trait WithImplicitSized: Sized {
1320+
#[inline]
1321+
fn with_implicit(self) -> ImplicitSized<Self> {
1322+
ImplicitSized(self)
1323+
}
1324+
}
1325+
12621326
impl<T> WithConstness for T {}
1327+
impl<T> WithImplicitSized for T {}
12631328

12641329
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TypeFoldable)]
12651330
pub struct ParamEnvAnd<'tcx, T> {

compiler/rustc_middle/src/ty/print/pretty.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -630,8 +630,11 @@ pub trait PrettyPrinter<'tcx>:
630630
for (predicate, _) in bounds {
631631
let predicate = predicate.subst(self.tcx(), substs);
632632
let bound_predicate = predicate.kind();
633-
if let ty::PredicateKind::Trait(pred, _) = bound_predicate.skip_binder() {
633+
if let ty::PredicateKind::Trait(pred, _, _default) =
634+
bound_predicate.skip_binder()
635+
{
634636
let trait_ref = bound_predicate.rebind(pred.trait_ref);
637+
// Maybe use `_default` to determine whether to show `Sized` if `Yes`.
635638
// Don't print +Sized, but rather +?Sized if absent.
636639
if Some(trait_ref.def_id()) == self.tcx().lang_items().sized_trait() {
637640
is_sized = true;
@@ -2191,7 +2194,7 @@ define_print_and_forward_display! {
21912194

21922195
ty::PredicateKind<'tcx> {
21932196
match *self {
2194-
ty::PredicateKind::Trait(ref data, constness) => {
2197+
ty::PredicateKind::Trait(ref data, constness, _) => {
21952198
if let hir::Constness::Const = constness {
21962199
p!("const ");
21972200
}

compiler/rustc_middle/src/ty/structural_impls.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ impl fmt::Debug for ty::Predicate<'tcx> {
174174
impl fmt::Debug for ty::PredicateKind<'tcx> {
175175
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
176176
match *self {
177-
ty::PredicateKind::Trait(ref a, constness) => {
177+
ty::PredicateKind::Trait(ref a, constness, _) => {
178178
if let hir::Constness::Const = constness {
179179
write!(f, "const ")?;
180180
}
@@ -419,8 +419,8 @@ impl<'a, 'tcx> Lift<'tcx> for ty::PredicateKind<'a> {
419419
type Lifted = ty::PredicateKind<'tcx>;
420420
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
421421
match self {
422-
ty::PredicateKind::Trait(data, constness) => {
423-
tcx.lift(data).map(|data| ty::PredicateKind::Trait(data, constness))
422+
ty::PredicateKind::Trait(data, constness, d) => {
423+
tcx.lift(data).map(|data| ty::PredicateKind::Trait(data, constness, d))
424424
}
425425
ty::PredicateKind::Subtype(data) => tcx.lift(data).map(ty::PredicateKind::Subtype),
426426
ty::PredicateKind::RegionOutlives(data) => {

compiler/rustc_mir/src/borrow_check/type_check/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2720,6 +2720,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
27202720
Some(ty::PredicateKind::Trait(
27212721
ty::TraitPredicate { trait_ref },
27222722
hir::Constness::NotConst,
2723+
ty::ImplicitTraitPredicate::No,
27232724
)),
27242725
locations,
27252726
category,

compiler/rustc_mir/src/transform/check_consts/validation.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,7 @@ impl Validator<'mir, 'tcx> {
424424
ty::PredicateKind::Subtype(_) => {
425425
bug!("subtype predicate on function: {:#?}", predicate)
426426
}
427-
ty::PredicateKind::Trait(pred, _constness) => {
427+
ty::PredicateKind::Trait(pred, _constness, _) => {
428428
if Some(pred.def_id()) == tcx.lang_items().sized_trait() {
429429
continue;
430430
}

compiler/rustc_mir/src/transform/function_item_references.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ impl<'a, 'tcx> FunctionItemRefChecker<'a, 'tcx> {
132132

133133
/// If the given predicate is the trait `fmt::Pointer`, returns the bound parameter type.
134134
fn is_pointer_trait(&self, bound: &PredicateKind<'tcx>) -> Option<Ty<'tcx>> {
135-
if let ty::PredicateKind::Trait(predicate, _) = bound {
135+
if let ty::PredicateKind::Trait(predicate, _, _) = bound {
136136
if self.tcx.is_diagnostic_item(sym::pointer_trait, predicate.def_id()) {
137137
Some(predicate.trait_ref.self_ty())
138138
} else {

compiler/rustc_privacy/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ where
122122

123123
fn visit_predicate(&mut self, predicate: ty::Predicate<'tcx>) -> ControlFlow<V::BreakTy> {
124124
match predicate.kind().skip_binder() {
125-
ty::PredicateKind::Trait(ty::TraitPredicate { trait_ref }, _) => {
125+
ty::PredicateKind::Trait(ty::TraitPredicate { trait_ref }, _, _) => {
126126
self.visit_trait(trait_ref)
127127
}
128128
ty::PredicateKind::Projection(ty::ProjectionPredicate { projection_ty, ty }) => {

compiler/rustc_resolve/src/late/lifetimes.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2666,7 +2666,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
26662666
let obligations = predicates.predicates.iter().filter_map(|&(pred, _)| {
26672667
let bound_predicate = pred.kind();
26682668
match bound_predicate.skip_binder() {
2669-
ty::PredicateKind::Trait(data, _) => {
2669+
ty::PredicateKind::Trait(data, _, _) => {
26702670
// The order here needs to match what we would get from `subst_supertrait`
26712671
let pred_bound_vars = bound_predicate.bound_vars();
26722672
let mut all_bound_vars = bound_vars.clone();

compiler/rustc_trait_selection/src/traits/auto_trait.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -415,8 +415,8 @@ impl AutoTraitFinder<'tcx> {
415415
let mut should_add_new = true;
416416
user_computed_preds.retain(|&old_pred| {
417417
if let (
418-
ty::PredicateKind::Trait(new_trait, _),
419-
ty::PredicateKind::Trait(old_trait, _),
418+
ty::PredicateKind::Trait(new_trait, _, _),
419+
ty::PredicateKind::Trait(old_trait, _, _),
420420
) = (new_pred.kind().skip_binder(), old_pred.kind().skip_binder())
421421
{
422422
if new_trait.def_id() == old_trait.def_id() {
@@ -638,7 +638,7 @@ impl AutoTraitFinder<'tcx> {
638638

639639
let bound_predicate = predicate.kind();
640640
match bound_predicate.skip_binder() {
641-
ty::PredicateKind::Trait(p, _) => {
641+
ty::PredicateKind::Trait(p, _, _) => {
642642
// Add this to `predicates` so that we end up calling `select`
643643
// with it. If this predicate ends up being unimplemented,
644644
// then `evaluate_predicates` will handle adding it the `ParamEnv`

0 commit comments

Comments
 (0)