Skip to content

Commit f958e6c

Browse files
committed
Separate bounds and predicates for associated/opaque types
1 parent d297147 commit f958e6c

File tree

107 files changed

+934
-1128
lines changed

Some content is hidden

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

107 files changed

+934
-1128
lines changed

compiler/rustc_ast_lowering/src/expr.rs

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -432,17 +432,25 @@ impl<'hir> LoweringContext<'_, 'hir> {
432432
self.with_catch_scope(body.id, |this| {
433433
let mut block = this.lower_block_noalloc(body, true);
434434

435-
let try_span = this.mark_span_with_reason(
436-
DesugaringKind::TryBlock,
437-
body.span,
438-
this.allow_try_trait.clone(),
439-
);
440-
441435
// Final expression of the block (if present) or `()` with span at the end of block
442-
let tail_expr = block
443-
.expr
444-
.take()
445-
.unwrap_or_else(|| this.expr_unit(this.sess.source_map().end_point(try_span)));
436+
let (try_span, tail_expr) = if let Some(expr) = block.expr.take() {
437+
(
438+
this.mark_span_with_reason(
439+
DesugaringKind::TryBlock,
440+
expr.span,
441+
this.allow_try_trait.clone(),
442+
),
443+
expr,
444+
)
445+
} else {
446+
let try_span = this.mark_span_with_reason(
447+
DesugaringKind::TryBlock,
448+
this.sess.source_map().end_point(body.span),
449+
this.allow_try_trait.clone(),
450+
);
451+
452+
(try_span, this.expr_unit(try_span))
453+
};
446454

447455
let ok_wrapped_span =
448456
this.mark_span_with_reason(DesugaringKind::TryBlock, tail_expr.span, None);
@@ -1553,7 +1561,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
15531561
hir::LangItem::TryFromError,
15541562
unstable_span,
15551563
from_expr,
1556-
try_span,
1564+
unstable_span,
15571565
);
15581566
let thin_attrs = ThinVec::from(attrs);
15591567
let catch_scope = self.catch_scopes.last().copied();

compiler/rustc_infer/src/traits/util.rs

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ use crate::traits::{Obligation, ObligationCause, PredicateObligation};
44
use rustc_data_structures::fx::FxHashSet;
55
use rustc_middle::ty::outlives::Component;
66
use rustc_middle::ty::{self, ToPredicate, TyCtxt, WithConstness};
7-
use rustc_span::Span;
87

98
pub fn anonymize_predicate<'tcx>(
109
tcx: TyCtxt<'tcx>,
@@ -94,7 +93,11 @@ pub fn elaborate_predicates<'tcx>(
9493
tcx: TyCtxt<'tcx>,
9594
predicates: impl Iterator<Item = ty::Predicate<'tcx>>,
9695
) -> Elaborator<'tcx> {
97-
let obligations = predicates.map(|predicate| predicate_obligation(predicate, None)).collect();
96+
let obligations = predicates
97+
.map(|predicate| {
98+
predicate_obligation(predicate, ty::ParamEnv::empty(), ObligationCause::dummy())
99+
})
100+
.collect();
98101
elaborate_obligations(tcx, obligations)
99102
}
100103

@@ -109,15 +112,10 @@ pub fn elaborate_obligations<'tcx>(
109112

110113
fn predicate_obligation<'tcx>(
111114
predicate: ty::Predicate<'tcx>,
112-
span: Option<Span>,
115+
param_env: ty::ParamEnv<'tcx>,
116+
cause: ObligationCause<'tcx>,
113117
) -> PredicateObligation<'tcx> {
114-
let cause = if let Some(span) = span {
115-
ObligationCause::dummy_with_span(span)
116-
} else {
117-
ObligationCause::dummy()
118-
};
119-
120-
Obligation { cause, param_env: ty::ParamEnv::empty(), recursion_depth: 0, predicate }
118+
Obligation { cause, param_env, recursion_depth: 0, predicate }
121119
}
122120

123121
impl Elaborator<'tcx> {
@@ -133,10 +131,11 @@ impl Elaborator<'tcx> {
133131
// Get predicates declared on the trait.
134132
let predicates = tcx.super_predicates_of(data.def_id());
135133

136-
let obligations = predicates.predicates.iter().map(|&(pred, span)| {
134+
let obligations = predicates.predicates.iter().map(|&(pred, _)| {
137135
predicate_obligation(
138136
pred.subst_supertrait(tcx, &ty::Binder::bind(data.trait_ref)),
139-
Some(span),
137+
obligation.param_env,
138+
obligation.cause.clone(),
140139
)
141140
});
142141
debug!("super_predicates: data={:?}", data);
@@ -233,7 +232,13 @@ impl Elaborator<'tcx> {
233232
})
234233
.map(|predicate_kind| predicate_kind.to_predicate(tcx))
235234
.filter(|&predicate| visited.insert(predicate))
236-
.map(|predicate| predicate_obligation(predicate, None)),
235+
.map(|predicate| {
236+
predicate_obligation(
237+
predicate,
238+
obligation.param_env,
239+
obligation.cause.clone(),
240+
)
241+
}),
237242
);
238243
}
239244
ty::PredicateAtom::TypeWellFormedFromEnv(..) => {

compiler/rustc_lint/src/unused.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
200200
ty::Adt(def, _) => check_must_use_def(cx, def.did, span, descr_pre, descr_post),
201201
ty::Opaque(def, _) => {
202202
let mut has_emitted = false;
203-
for (predicate, _) in cx.tcx.predicates_of(def).predicates {
203+
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.
205205
if let ty::PredicateAtom::Trait(ref poly_trait_predicate, _) =
206206
predicate.skip_binders()

compiler/rustc_metadata/src/rmeta/encoder.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1266,7 +1266,10 @@ impl EncodeContext<'a, 'tcx> {
12661266
hir::ItemKind::ForeignMod(_) => EntryKind::ForeignMod,
12671267
hir::ItemKind::GlobalAsm(..) => EntryKind::GlobalAsm,
12681268
hir::ItemKind::TyAlias(..) => EntryKind::Type,
1269-
hir::ItemKind::OpaqueTy(..) => EntryKind::OpaqueTy,
1269+
hir::ItemKind::OpaqueTy(..) => {
1270+
self.encode_explicit_item_bounds(def_id);
1271+
EntryKind::OpaqueTy
1272+
}
12701273
hir::ItemKind::Enum(..) => EntryKind::Enum(self.tcx.adt_def(def_id).repr),
12711274
hir::ItemKind::Struct(ref struct_def, _) => {
12721275
let adt_def = self.tcx.adt_def(def_id);

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -607,12 +607,13 @@ pub trait PrettyPrinter<'tcx>:
607607
}
608608
// Grab the "TraitA + TraitB" from `impl TraitA + TraitB`,
609609
// by looking up the projections associated with the def_id.
610-
let bounds = self.tcx().item_bounds(def_id).subst(self.tcx(), substs);
610+
let bounds = self.tcx().explicit_item_bounds(def_id);
611611

612612
let mut first = true;
613613
let mut is_sized = false;
614614
p!("impl");
615-
for predicate in bounds {
615+
for (predicate, _) in bounds {
616+
let predicate = predicate.subst(self.tcx(), substs);
616617
// Note: We can't use `to_opt_poly_trait_ref` here as `predicate`
617618
// may contain unbound variables. We therefore do this manually.
618619
//

compiler/rustc_privacy/src/lib.rs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -194,11 +194,14 @@ where
194194
// The intent is to treat `impl Trait1 + Trait2` identically to
195195
// `dyn Trait1 + Trait2`. Therefore we ignore def-id of the opaque type itself
196196
// (it either has no visibility, or its visibility is insignificant, like
197-
// visibilities of type aliases) and recurse into predicates instead to go
197+
// visibilities of type aliases) and recurse into bounds instead to go
198198
// through the trait list (default type visitor doesn't visit those traits).
199199
// All traits in the list are considered the "primary" part of the type
200200
// and are visited by shallow visitors.
201-
if self.visit_predicates(tcx.predicates_of(def_id)) {
201+
if self.visit_predicates(ty::GenericPredicates {
202+
parent: None,
203+
predicates: tcx.explicit_item_bounds(def_id),
204+
}) {
202205
return true;
203206
}
204207
}
@@ -1800,6 +1803,14 @@ impl SearchInterfaceForPrivateItemsVisitor<'tcx> {
18001803
self
18011804
}
18021805

1806+
fn bounds(&mut self) -> &mut Self {
1807+
self.visit_predicates(ty::GenericPredicates {
1808+
parent: None,
1809+
predicates: self.tcx.explicit_item_bounds(self.item_def_id),
1810+
});
1811+
self
1812+
}
1813+
18031814
fn ty(&mut self) -> &mut Self {
18041815
self.visit(self.tcx.type_of(self.item_def_id));
18051816
self
@@ -1975,7 +1986,7 @@ impl<'a, 'tcx> Visitor<'tcx> for PrivateItemsInPublicInterfacesVisitor<'a, 'tcx>
19751986
hir::ItemKind::OpaqueTy(..) => {
19761987
// `ty()` for opaque types is the underlying type,
19771988
// it's not a part of interface, so we skip it.
1978-
self.check(item.hir_id, item_visibility).generics().predicates();
1989+
self.check(item.hir_id, item_visibility).generics().bounds();
19791990
}
19801991
hir::ItemKind::Trait(.., trait_item_refs) => {
19811992
self.check(item.hir_id, item_visibility).generics().predicates();
@@ -1987,6 +1998,10 @@ impl<'a, 'tcx> Visitor<'tcx> for PrivateItemsInPublicInterfacesVisitor<'a, 'tcx>
19871998
trait_item_ref.defaultness,
19881999
item_visibility,
19892000
);
2001+
2002+
if let AssocItemKind::Type = trait_item_ref.kind {
2003+
self.check(trait_item_ref.id.hir_id, item_visibility).bounds();
2004+
}
19902005
}
19912006
}
19922007
hir::ItemKind::TraitAlias(..) => {

compiler/rustc_traits/src/chalk/db.rs

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,18 +73,28 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
7373
}
7474
let bound_vars = bound_vars_for_item(self.interner.tcx, def_id);
7575
let binders = binders_for(&self.interner, bound_vars);
76-
// FIXME(chalk): this really isn't right I don't think. The functions
77-
// for GATs are a bit hard to figure out. Are these supposed to be where
78-
// clauses or bounds?
76+
7977
let where_clauses = self.where_clauses_for(def_id, bound_vars);
8078

79+
let bounds = self
80+
.tcx
81+
.explicit_item_bounds(def_id)
82+
.iter()
83+
.map(|(bound, _)| bound.subst(self.tcx, &bound_vars))
84+
.filter_map(|bound| {
85+
LowerInto::<
86+
Option<chalk_solve::rust_ir::QuantifiedInlineBound<RustInterner<'tcx>>>,
87+
>::lower_into(bound, &self.interner)
88+
})
89+
.collect();
90+
8191
Arc::new(chalk_solve::rust_ir::AssociatedTyDatum {
8292
trait_id: chalk_ir::TraitId(trait_def_id),
8393
id: assoc_type_id,
8494
name: (),
8595
binders: chalk_ir::Binders::new(
8696
binders,
87-
chalk_solve::rust_ir::AssociatedTyDatumBound { bounds: vec![], where_clauses },
97+
chalk_solve::rust_ir::AssociatedTyDatumBound { bounds, where_clauses },
8898
),
8999
})
90100
}
@@ -443,10 +453,17 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
443453
let binders = binders_for(&self.interner, bound_vars);
444454
let where_clauses = self.where_clauses_for(opaque_ty_id.0, bound_vars);
445455

456+
let bounds: Vec<_> = predicates
457+
.iter()
458+
.map(|(bound, _)| bound.subst(self.tcx, &bound_vars))
459+
.filter_map(|bound| LowerInto::<Option<chalk_ir::QuantifiedWhereClause<RustInterner<'tcx>>>>::lower_into(bound, &self.interner))
460+
.collect();
461+
446462
let value = chalk_solve::rust_ir::OpaqueTyDatumBound {
447-
bounds: chalk_ir::Binders::new(binders.clone(), vec![]),
463+
bounds: chalk_ir::Binders::new(binders, bounds),
448464
where_clauses: chalk_ir::Binders::new(binders, where_clauses),
449465
};
466+
450467
Arc::new(chalk_solve::rust_ir::OpaqueTyDatum {
451468
opaque_ty_id,
452469
bound: chalk_ir::Binders::empty(&self.interner, value),

compiler/rustc_traits/src/chalk/lowering.rs

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -728,6 +728,84 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::FnSig<RustInterner<'tcx>>> for ty::Binder<t
728728
}
729729
}
730730

731+
// We lower into an Option here since there are some predicates which Chalk
732+
// doesn't have a representation for yet (as an `InlineBound`). The `Option` will
733+
// eventually be removed.
734+
impl<'tcx> LowerInto<'tcx, Option<chalk_solve::rust_ir::QuantifiedInlineBound<RustInterner<'tcx>>>>
735+
for ty::Predicate<'tcx>
736+
{
737+
fn lower_into(
738+
self,
739+
interner: &RustInterner<'tcx>,
740+
) -> Option<chalk_solve::rust_ir::QuantifiedInlineBound<RustInterner<'tcx>>> {
741+
match &self.kind() {
742+
ty::PredicateKind::Trait(predicate, _) => {
743+
let (predicate, binders, _named_regions) =
744+
collect_bound_vars(interner, interner.tcx, predicate);
745+
746+
Some(chalk_ir::Binders::new(
747+
binders,
748+
chalk_solve::rust_ir::InlineBound::TraitBound(
749+
predicate.trait_ref.lower_into(interner),
750+
),
751+
))
752+
}
753+
ty::PredicateKind::Projection(predicate) => {
754+
let (predicate, binders, _named_regions) =
755+
collect_bound_vars(interner, interner.tcx, predicate);
756+
757+
Some(chalk_ir::Binders::new(
758+
binders,
759+
chalk_solve::rust_ir::InlineBound::AliasEqBound(predicate.lower_into(interner)),
760+
))
761+
}
762+
ty::PredicateKind::TypeOutlives(_predicate) => None,
763+
ty::PredicateKind::WellFormed(_ty) => None,
764+
765+
ty::PredicateKind::RegionOutlives(..)
766+
| ty::PredicateKind::ObjectSafe(..)
767+
| ty::PredicateKind::ClosureKind(..)
768+
| ty::PredicateKind::Subtype(..)
769+
| ty::PredicateKind::ConstEvaluatable(..)
770+
| ty::PredicateKind::ConstEquate(..) => bug!("unexpected predicate {}", &self),
771+
}
772+
}
773+
}
774+
775+
impl<'tcx> LowerInto<'tcx, chalk_solve::rust_ir::TraitBound<RustInterner<'tcx>>>
776+
for ty::TraitRef<'tcx>
777+
{
778+
fn lower_into(
779+
self,
780+
interner: &RustInterner<'tcx>,
781+
) -> chalk_solve::rust_ir::TraitBound<RustInterner<'tcx>> {
782+
chalk_solve::rust_ir::TraitBound {
783+
trait_id: chalk_ir::TraitId(self.def_id),
784+
args_no_self: self.substs[1..].iter().map(|arg| arg.lower_into(interner)).collect(),
785+
}
786+
}
787+
}
788+
789+
impl<'tcx> LowerInto<'tcx, chalk_solve::rust_ir::AliasEqBound<RustInterner<'tcx>>>
790+
for ty::ProjectionPredicate<'tcx>
791+
{
792+
fn lower_into(
793+
self,
794+
interner: &RustInterner<'tcx>,
795+
) -> chalk_solve::rust_ir::AliasEqBound<RustInterner<'tcx>> {
796+
let trait_ref = self.projection_ty.trait_ref(interner.tcx);
797+
chalk_solve::rust_ir::AliasEqBound {
798+
trait_bound: trait_ref.lower_into(interner),
799+
associated_ty_id: chalk_ir::AssocTypeId(self.projection_ty.item_def_id),
800+
parameters: self.projection_ty.substs[trait_ref.substs.len()..]
801+
.iter()
802+
.map(|arg| arg.lower_into(interner))
803+
.collect(),
804+
value: self.ty.lower_into(interner),
805+
}
806+
}
807+
}
808+
731809
/// To collect bound vars, we have to do two passes. In the first pass, we
732810
/// collect all `BoundRegion`s and `ty::Bound`s. In the second pass, we then
733811
/// replace `BrNamed` into `BrAnon`. The two separate passes are important,

compiler/rustc_typeck/src/check/check.rs

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use super::coercion::CoerceMany;
2+
use super::compare_method::check_type_bounds;
23
use super::compare_method::{compare_const_impl, compare_impl_method, compare_ty_impl};
34
use super::*;
45

@@ -453,8 +454,7 @@ pub(super) fn check_opaque_for_inheriting_lifetimes(
453454
ty: None,
454455
};
455456
let prohibit_opaque = tcx
456-
.predicates_of(def_id)
457-
.predicates
457+
.explicit_item_bounds(def_id)
458458
.iter()
459459
.any(|(predicate, _)| predicate.visit_with(&mut visitor));
460460
debug!(
@@ -476,7 +476,7 @@ pub(super) fn check_opaque_for_inheriting_lifetimes(
476476
span,
477477
E0760,
478478
"`{}` return type cannot contain a projection or `Self` that references lifetimes from \
479-
a parent scope",
479+
a parent scope",
480480
if is_async { "async fn" } else { "impl Trait" },
481481
);
482482

@@ -553,9 +553,25 @@ pub fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, it: &'tcx hir::Item<'tcx>) {
553553

554554
for item in items.iter() {
555555
let item = tcx.hir().trait_item(item.id);
556-
if let hir::TraitItemKind::Fn(sig, _) = &item.kind {
557-
let abi = sig.header.abi;
558-
fn_maybe_err(tcx, item.ident.span, abi);
556+
match item.kind {
557+
hir::TraitItemKind::Fn(ref sig, _) => {
558+
let abi = sig.header.abi;
559+
fn_maybe_err(tcx, item.ident.span, abi);
560+
}
561+
hir::TraitItemKind::Type(.., Some(_default)) => {
562+
let item_def_id = tcx.hir().local_def_id(item.hir_id).to_def_id();
563+
let assoc_item = tcx.associated_item(item_def_id);
564+
let trait_substs =
565+
InternalSubsts::identity_for_item(tcx, def_id.to_def_id());
566+
let _: Result<_, rustc_errors::ErrorReported> = check_type_bounds(
567+
tcx,
568+
assoc_item,
569+
assoc_item,
570+
item.span,
571+
ty::TraitRef { def_id: def_id.to_def_id(), substs: trait_substs },
572+
);
573+
}
574+
_ => {}
559575
}
560576
}
561577
}

0 commit comments

Comments
 (0)