Skip to content

Commit ba11640

Browse files
committed
rustc_typeck: hook up collect and item/body check to on-demand.
1 parent 9c3c306 commit ba11640

File tree

36 files changed

+773
-1088
lines changed

36 files changed

+773
-1088
lines changed

src/librustc/middle/dead.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -159,10 +159,9 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
159159
hir_map::NodeItem(item) => {
160160
match item.node {
161161
hir::ItemStruct(..) | hir::ItemUnion(..) => {
162-
self.struct_has_extern_repr = item.attrs.iter().any(|attr| {
163-
attr::find_repr_attrs(self.tcx.sess.diagnostic(), attr)
164-
.contains(&attr::ReprExtern)
165-
});
162+
let def_id = self.tcx.hir.local_def_id(item.id);
163+
let def = self.tcx.lookup_adt_def(def_id);
164+
self.struct_has_extern_repr = def.repr.c;
166165

167166
intravisit::walk_item(self, &item);
168167
}

src/librustc/mir/tcx.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -173,9 +173,7 @@ impl<'tcx> Rvalue<'tcx> {
173173
Rvalue::Discriminant(ref lval) => {
174174
let ty = lval.ty(mir, tcx).to_ty(tcx);
175175
if let ty::TyAdt(adt_def, _) = ty.sty {
176-
let repr_hints = tcx.lookup_repr_hints(adt_def.did);
177-
let repr_type = tcx.enum_repr_type(repr_hints.get(0));
178-
Some(repr_type.to_ty(tcx))
176+
Some(adt_def.repr.discr_type().to_ty(tcx))
179177
} else {
180178
// Undefined behaviour, bug for now; may want to return something for
181179
// the `discriminant` intrinsic later.

src/librustc/traits/fulfill.rs

+5-134
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,18 @@
1111
use dep_graph::DepGraph;
1212
use infer::{InferCtxt, InferOk};
1313
use ty::{self, Ty, TypeFoldable, ToPolyTraitRef, TyCtxt, ToPredicate};
14-
use ty::subst::Subst;
1514
use rustc_data_structures::obligation_forest::{ObligationForest, Error};
1615
use rustc_data_structures::obligation_forest::{ForestObligation, ObligationProcessor};
1716
use std::marker::PhantomData;
18-
use std::mem;
1917
use syntax::ast;
2018
use util::nodemap::{FxHashSet, NodeMap};
2119
use hir::def_id::DefId;
2220

2321
use super::CodeAmbiguity;
2422
use super::CodeProjectionError;
2523
use super::CodeSelectionError;
26-
use super::{FulfillmentError, FulfillmentErrorCode, SelectionError};
27-
use super::{ObligationCause, BuiltinDerivedObligation};
28-
use super::{PredicateObligation, TraitObligation, Obligation};
24+
use super::{FulfillmentError, FulfillmentErrorCode};
25+
use super::{ObligationCause, PredicateObligation, Obligation};
2926
use super::project;
3027
use super::select::SelectionContext;
3128
use super::Unimplemented;
@@ -82,10 +79,6 @@ pub struct FulfillmentContext<'tcx> {
8279
// obligations (otherwise, it's easy to fail to walk to a
8380
// particular node-id).
8481
region_obligations: NodeMap<Vec<RegionObligation<'tcx>>>,
85-
86-
// A list of obligations that need to be deferred to
87-
// a later time for them to be properly fulfilled.
88-
deferred_obligations: Vec<DeferredObligation<'tcx>>,
8982
}
9083

9184
#[derive(Clone)]
@@ -101,100 +94,12 @@ pub struct PendingPredicateObligation<'tcx> {
10194
pub stalled_on: Vec<Ty<'tcx>>,
10295
}
10396

104-
/// An obligation which cannot be fulfilled in the context
105-
/// it was registered in, such as auto trait obligations on
106-
/// `impl Trait`, which require the concrete type to be
107-
/// available, only guaranteed after finishing type-checking.
108-
#[derive(Clone, Debug)]
109-
pub struct DeferredObligation<'tcx> {
110-
pub predicate: ty::PolyTraitPredicate<'tcx>,
111-
pub cause: ObligationCause<'tcx>
112-
}
113-
114-
impl<'a, 'gcx, 'tcx> DeferredObligation<'tcx> {
115-
/// If possible, create a `DeferredObligation` from
116-
/// a trait predicate which had failed selection,
117-
/// but could succeed later.
118-
pub fn from_select_error(tcx: TyCtxt<'a, 'gcx, 'tcx>,
119-
obligation: &TraitObligation<'tcx>,
120-
selection_err: &SelectionError<'tcx>)
121-
-> Option<DeferredObligation<'tcx>> {
122-
if let Unimplemented = *selection_err {
123-
if DeferredObligation::must_defer(tcx, &obligation.predicate) {
124-
return Some(DeferredObligation {
125-
predicate: obligation.predicate.clone(),
126-
cause: obligation.cause.clone()
127-
});
128-
}
129-
}
130-
131-
None
132-
}
133-
134-
/// Returns true if the given trait predicate can be
135-
/// fulfilled at a later time.
136-
pub fn must_defer(tcx: TyCtxt<'a, 'gcx, 'tcx>,
137-
predicate: &ty::PolyTraitPredicate<'tcx>)
138-
-> bool {
139-
// Auto trait obligations on `impl Trait`.
140-
if tcx.trait_has_default_impl(predicate.def_id()) {
141-
let substs = predicate.skip_binder().trait_ref.substs;
142-
if substs.types().count() == 1 && substs.regions().next().is_none() {
143-
if let ty::TyAnon(..) = predicate.skip_binder().self_ty().sty {
144-
return true;
145-
}
146-
}
147-
}
148-
149-
false
150-
}
151-
152-
/// If possible, return the nested obligations required
153-
/// to fulfill this obligation.
154-
pub fn try_select(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>)
155-
-> Option<Vec<PredicateObligation<'tcx>>> {
156-
if let ty::TyAnon(def_id, substs) = self.predicate.skip_binder().self_ty().sty {
157-
let ty = if def_id.is_local() {
158-
tcx.maps.ty.borrow().get(&def_id).cloned()
159-
} else {
160-
Some(tcx.item_type(def_id))
161-
};
162-
// We can resolve the `impl Trait` to its concrete type.
163-
if let Some(concrete_ty) = ty.subst(tcx, substs) {
164-
let predicate = ty::TraitRef {
165-
def_id: self.predicate.def_id(),
166-
substs: tcx.mk_substs_trait(concrete_ty, &[])
167-
}.to_predicate();
168-
169-
let original_obligation = Obligation::new(self.cause.clone(),
170-
self.predicate.clone());
171-
let cause = original_obligation.derived_cause(BuiltinDerivedObligation);
172-
return Some(vec![Obligation::new(cause, predicate)]);
173-
}
174-
}
175-
176-
None
177-
}
178-
179-
/// Return the `PredicateObligation` this was created from.
180-
pub fn to_obligation(&self) -> PredicateObligation<'tcx> {
181-
let predicate = ty::Predicate::Trait(self.predicate.clone());
182-
Obligation::new(self.cause.clone(), predicate)
183-
}
184-
185-
/// Return an error as if this obligation had failed.
186-
pub fn to_error(&self) -> FulfillmentError<'tcx> {
187-
FulfillmentError::new(self.to_obligation(), CodeSelectionError(Unimplemented))
188-
}
189-
}
190-
19197
impl<'a, 'gcx, 'tcx> FulfillmentContext<'tcx> {
19298
/// Creates a new fulfillment context.
19399
pub fn new() -> FulfillmentContext<'tcx> {
194100
FulfillmentContext {
195101
predicates: ObligationForest::new(),
196102
region_obligations: NodeMap(),
197-
deferred_obligations: vec![],
198103
}
199104
}
200105

@@ -294,16 +199,10 @@ impl<'a, 'gcx, 'tcx> FulfillmentContext<'tcx> {
294199
{
295200
self.select_where_possible(infcx)?;
296201

297-
// Fail all of the deferred obligations that haven't
298-
// been otherwise removed from the context.
299-
let deferred_errors = self.deferred_obligations.iter()
300-
.map(|d| d.to_error());
301-
302202
let errors: Vec<_> =
303203
self.predicates.to_errors(CodeAmbiguity)
304204
.into_iter()
305205
.map(|e| to_fulfillment_error(e))
306-
.chain(deferred_errors)
307206
.collect();
308207
if errors.is_empty() {
309208
Ok(())
@@ -324,10 +223,6 @@ impl<'a, 'gcx, 'tcx> FulfillmentContext<'tcx> {
324223
self.predicates.pending_obligations()
325224
}
326225

327-
pub fn take_deferred_obligations(&mut self) -> Vec<DeferredObligation<'tcx>> {
328-
mem::replace(&mut self.deferred_obligations, vec![])
329-
}
330-
331226
/// Attempts to select obligations using `selcx`. If `only_new_obligations` is true, then it
332227
/// only attempts to select obligations that haven't been seen before.
333228
fn select(&mut self, selcx: &mut SelectionContext<'a, 'gcx, 'tcx>)
@@ -343,7 +238,6 @@ impl<'a, 'gcx, 'tcx> FulfillmentContext<'tcx> {
343238
let outcome = self.predicates.process_obligations(&mut FulfillProcessor {
344239
selcx: selcx,
345240
region_obligations: &mut self.region_obligations,
346-
deferred_obligations: &mut self.deferred_obligations
347241
});
348242
debug!("select: outcome={:?}", outcome);
349243

@@ -378,7 +272,6 @@ impl<'a, 'gcx, 'tcx> FulfillmentContext<'tcx> {
378272
struct FulfillProcessor<'a, 'b: 'a, 'gcx: 'tcx, 'tcx: 'b> {
379273
selcx: &'a mut SelectionContext<'b, 'gcx, 'tcx>,
380274
region_obligations: &'a mut NodeMap<Vec<RegionObligation<'tcx>>>,
381-
deferred_obligations: &'a mut Vec<DeferredObligation<'tcx>>
382275
}
383276

384277
impl<'a, 'b, 'gcx, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'gcx, 'tcx> {
@@ -391,8 +284,7 @@ impl<'a, 'b, 'gcx, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'gcx,
391284
{
392285
process_predicate(self.selcx,
393286
obligation,
394-
self.region_obligations,
395-
self.deferred_obligations)
287+
self.region_obligations)
396288
.map(|os| os.map(|os| os.into_iter().map(|o| PendingPredicateObligation {
397289
obligation: o,
398290
stalled_on: vec![]
@@ -432,8 +324,7 @@ fn trait_ref_type_vars<'a, 'gcx, 'tcx>(selcx: &mut SelectionContext<'a, 'gcx, 't
432324
fn process_predicate<'a, 'gcx, 'tcx>(
433325
selcx: &mut SelectionContext<'a, 'gcx, 'tcx>,
434326
pending_obligation: &mut PendingPredicateObligation<'tcx>,
435-
region_obligations: &mut NodeMap<Vec<RegionObligation<'tcx>>>,
436-
deferred_obligations: &mut Vec<DeferredObligation<'tcx>>)
327+
region_obligations: &mut NodeMap<Vec<RegionObligation<'tcx>>>)
437328
-> Result<Option<Vec<PredicateObligation<'tcx>>>,
438329
FulfillmentErrorCode<'tcx>>
439330
{
@@ -502,21 +393,7 @@ fn process_predicate<'a, 'gcx, 'tcx>(
502393
info!("selecting trait `{:?}` at depth {} yielded Err",
503394
data, obligation.recursion_depth);
504395

505-
let defer = DeferredObligation::from_select_error(selcx.tcx(),
506-
&trait_obligation,
507-
&selection_err);
508-
if let Some(deferred_obligation) = defer {
509-
if let Some(nested) = deferred_obligation.try_select(selcx.tcx()) {
510-
Ok(Some(nested))
511-
} else {
512-
// Pretend that the obligation succeeded,
513-
// but record it for later.
514-
deferred_obligations.push(deferred_obligation);
515-
Ok(Some(vec![]))
516-
}
517-
} else {
518-
Err(CodeSelectionError(selection_err))
519-
}
396+
Err(CodeSelectionError(selection_err))
520397
}
521398
}
522399
}
@@ -714,12 +591,6 @@ impl<'a, 'gcx, 'tcx> GlobalFulfilledPredicates<'gcx> {
714591
// already has the required read edges, so we don't need
715592
// to add any more edges here.
716593
if data.is_global() {
717-
// Don't cache predicates which were fulfilled
718-
// by deferring them for later fulfillment.
719-
if DeferredObligation::must_defer(tcx, data) {
720-
return;
721-
}
722-
723594
if let Some(data) = tcx.lift_to_global(data) {
724595
if self.set.insert(data.clone()) {
725596
debug!("add_if_global: global predicate `{:?}` added", data);

src/librustc/traits/mod.rs

-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ pub use self::coherence::orphan_check;
3131
pub use self::coherence::overlapping_impls;
3232
pub use self::coherence::OrphanCheckErr;
3333
pub use self::fulfill::{FulfillmentContext, GlobalFulfilledPredicates, RegionObligation};
34-
pub use self::fulfill::DeferredObligation;
3534
pub use self::project::MismatchedProjectionTypes;
3635
pub use self::project::{normalize, normalize_projection_type, Normalized};
3736
pub use self::project::{ProjectionCache, ProjectionCacheSnapshot, Reveal};

src/librustc/traits/select.rs

+8-3
Original file line numberDiff line numberDiff line change
@@ -1478,8 +1478,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
14781478
// `assemble_candidates_from_object_ty`.
14791479
}
14801480
ty::TyParam(..) |
1481-
ty::TyProjection(..) |
1482-
ty::TyAnon(..) => {
1481+
ty::TyProjection(..) => {
14831482
// In these cases, we don't know what the actual
14841483
// type is. Therefore, we cannot break it down
14851484
// into its constituent types. So we don't
@@ -1902,7 +1901,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
19021901
ty::TyDynamic(..) |
19031902
ty::TyParam(..) |
19041903
ty::TyProjection(..) |
1905-
ty::TyAnon(..) |
19061904
ty::TyInfer(ty::TyVar(_)) |
19071905
ty::TyInfer(ty::FreshTy(_)) |
19081906
ty::TyInfer(ty::FreshIntTy(_)) |
@@ -1947,6 +1945,13 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
19471945
.map(|f| f.ty(self.tcx(), substs))
19481946
.collect()
19491947
}
1948+
1949+
ty::TyAnon(def_id, substs) => {
1950+
// We can resolve the `impl Trait` to its concrete type,
1951+
// which enforces a DAG between the functions requiring
1952+
// the auto trait bounds in question.
1953+
vec![self.tcx().item_type(def_id).subst(self.tcx(), substs)]
1954+
}
19501955
}
19511956
}
19521957

src/librustc/traits/structural_impls.rs

-27
Original file line numberDiff line numberDiff line change
@@ -269,20 +269,6 @@ impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCause<'a> {
269269
}
270270
}
271271

272-
impl<'a, 'tcx> Lift<'tcx> for traits::DeferredObligation<'a> {
273-
type Lifted = traits::DeferredObligation<'tcx>;
274-
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
275-
tcx.lift(&self.predicate).and_then(|predicate| {
276-
tcx.lift(&self.cause).map(|cause| {
277-
traits::DeferredObligation {
278-
predicate: predicate,
279-
cause: cause
280-
}
281-
})
282-
})
283-
}
284-
}
285-
286272
// For trans only.
287273
impl<'a, 'tcx> Lift<'tcx> for traits::Vtable<'a, ()> {
288274
type Lifted = traits::Vtable<'tcx, ()>;
@@ -589,16 +575,3 @@ impl<'tcx> TypeFoldable<'tcx> for traits::ObligationCause<'tcx> {
589575
self.code.visit_with(visitor)
590576
}
591577
}
592-
593-
impl<'tcx> TypeFoldable<'tcx> for traits::DeferredObligation<'tcx> {
594-
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
595-
traits::DeferredObligation {
596-
predicate: self.predicate.fold_with(folder),
597-
cause: self.cause.fold_with(folder)
598-
}
599-
}
600-
601-
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
602-
self.predicate.visit_with(visitor) || self.cause.visit_with(visitor)
603-
}
604-
}

0 commit comments

Comments
 (0)