Skip to content

Commit 0f533e5

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 1c02dbb commit 0f533e5

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
@@ -2097,7 +2097,7 @@ impl<'tcx> TyCtxt<'tcx> {
20972097
let generic_predicates = self.super_predicates_of(trait_did);
20982098

20992099
for (predicate, _) in generic_predicates.predicates {
2100-
if let ty::PredicateKind::Trait(data, _) = predicate.kind().skip_binder() {
2100+
if let ty::PredicateKind::Trait(data, ..) = predicate.kind().skip_binder() {
21012101
if set.insert(data.def_id()) {
21022102
stack.push(data.def_id());
21032103
}

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
@@ -424,6 +424,38 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for Predicate<'tcx> {
424424
}
425425
}
426426

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

439471
/// `where 'a: 'b`
440472
RegionOutlives(RegionOutlivesPredicate<'tcx>),
@@ -723,24 +755,47 @@ impl ToPredicate<'tcx> for PredicateKind<'tcx> {
723755

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

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

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

@@ -766,7 +821,7 @@ impl<'tcx> Predicate<'tcx> {
766821
pub fn to_opt_poly_trait_ref(self) -> Option<ConstnessAnd<PolyTraitRef<'tcx>>> {
767822
let predicate = self.kind();
768823
match predicate.skip_binder() {
769-
PredicateKind::Trait(t, constness) => {
824+
PredicateKind::Trait(t, constness, _) => {
770825
Some(ConstnessAnd { constness, value: predicate.rebind(t.trait_ref) })
771826
}
772827
PredicateKind::Projection(..)
@@ -1264,7 +1319,17 @@ pub trait WithConstness: Sized {
12641319
}
12651320
}
12661321

1322+
pub struct ImplicitSized<T>(T);
1323+
1324+
pub trait WithImplicitSized: Sized {
1325+
#[inline]
1326+
fn with_implicit(self) -> ImplicitSized<Self> {
1327+
ImplicitSized(self)
1328+
}
1329+
}
1330+
12671331
impl<T> WithConstness for T {}
1332+
impl<T> WithImplicitSized for T {}
12681333

12691334
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TypeFoldable)]
12701335
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
@@ -2718,6 +2718,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
27182718
Some(ty::PredicateKind::Trait(
27192719
ty::TraitPredicate { trait_ref },
27202720
hir::Constness::NotConst,
2721+
ty::ImplicitTraitPredicate::No,
27212722
)),
27222723
locations,
27232724
category,

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

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

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
@@ -2658,7 +2658,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
26582658
let obligations = predicates.predicates.iter().filter_map(|&(pred, _)| {
26592659
let bound_predicate = pred.kind();
26602660
match bound_predicate.skip_binder() {
2661-
ty::PredicateKind::Trait(data, _) => {
2661+
ty::PredicateKind::Trait(data, _, _) => {
26622662
// The order here needs to match what we would get from `subst_supertrait`
26632663
let pred_bound_vars = bound_predicate.bound_vars();
26642664
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)