Skip to content

Commit 0e05fc0

Browse files
committed
strip param-env from infcx
1 parent 830f7c5 commit 0e05fc0

Some content is hidden

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

51 files changed

+684
-377
lines changed

src/librustc/infer/combine.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ pub struct CombineFields<'infcx, 'gcx: 'infcx+'tcx, 'tcx: 'infcx> {
5555
pub infcx: &'infcx InferCtxt<'infcx, 'gcx, 'tcx>,
5656
pub trace: TypeTrace<'tcx>,
5757
pub cause: Option<ty::relate::Cause>,
58+
pub param_env: ty::ParamEnv<'tcx>,
5859
pub obligations: PredicateObligations<'tcx>,
5960
}
6061

@@ -215,6 +216,7 @@ impl<'infcx, 'gcx, 'tcx> CombineFields<'infcx, 'gcx, 'tcx> {
215216

216217
if needs_wf {
217218
self.obligations.push(Obligation::new(self.trace.cause.clone(),
219+
self.param_env,
218220
ty::Predicate::WellFormed(b_ty)));
219221
}
220222

src/librustc/infer/mod.rs

Lines changed: 103 additions & 83 deletions
Large diffs are not rendered by default.

src/librustc/infer/sub.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
9696
self.fields.obligations.push(
9797
Obligation::new(
9898
self.fields.trace.cause.clone(),
99+
self.fields.param_env,
99100
ty::Predicate::Subtype(
100101
ty::Binder(ty::SubtypePredicate {
101102
a_is_expected: self.a_is_expected,

src/librustc/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
#![cfg_attr(stage0, feature(staged_api))]
4848
#![cfg_attr(stage0, feature(loop_break_value))]
4949

50-
#![recursion_limit="192"]
50+
#![recursion_limit="256"]
5151

5252
extern crate arena;
5353
extern crate core;

src/librustc/middle/expr_use_visitor.rs

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,7 @@ impl OverloadedCallType {
242242
pub struct ExprUseVisitor<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
243243
mc: mc::MemCategorizationContext<'a, 'gcx, 'tcx>,
244244
delegate: &'a mut Delegate<'tcx>,
245+
param_env: ty::ParamEnv<'tcx>,
245246
}
246247

247248
// If the TYPER results in an error, it's because the type check
@@ -272,24 +273,28 @@ enum PassArgs {
272273
impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
273274
pub fn new(delegate: &'a mut (Delegate<'tcx>+'a),
274275
region_maps: &'a RegionMaps,
275-
infcx: &'a InferCtxt<'a, 'gcx, 'tcx>)
276+
infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
277+
param_env: ty::ParamEnv<'tcx>)
276278
-> Self
277279
{
278280
ExprUseVisitor::with_options(delegate,
279281
infcx,
282+
param_env,
280283
region_maps,
281284
mc::MemCategorizationOptions::default())
282285
}
283286

284287
pub fn with_options(delegate: &'a mut (Delegate<'tcx>+'a),
285288
infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
289+
param_env: ty::ParamEnv<'tcx>,
286290
region_maps: &'a RegionMaps,
287291
options: mc::MemCategorizationOptions)
288292
-> Self
289293
{
290294
ExprUseVisitor {
291295
mc: mc::MemCategorizationContext::with_options(infcx, region_maps, options),
292-
delegate: delegate
296+
delegate,
297+
param_env,
293298
}
294299
}
295300

@@ -324,7 +329,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
324329
debug!("delegate_consume(consume_id={}, cmt={:?})",
325330
consume_id, cmt);
326331

327-
let mode = copy_or_move(self.mc.infcx, &cmt, DirectRefMove);
332+
let mode = copy_or_move(self.mc.infcx, self.param_env, &cmt, DirectRefMove);
328333
self.delegate.consume(consume_id, consume_span, cmt, mode);
329334
}
330335

@@ -937,7 +942,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
937942
PatKind::Binding(hir::BindByRef(..), ..) =>
938943
mode.lub(BorrowingMatch),
939944
PatKind::Binding(hir::BindByValue(..), ..) => {
940-
match copy_or_move(self.mc.infcx, &cmt_pat, PatBindingMove) {
945+
match copy_or_move(self.mc.infcx, self.param_env, &cmt_pat, PatBindingMove) {
941946
Copy => mode.lub(CopyingMatch),
942947
Move(..) => mode.lub(MovingMatch),
943948
}
@@ -953,10 +958,9 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
953958
fn walk_pat(&mut self, cmt_discr: mc::cmt<'tcx>, pat: &hir::Pat, match_mode: MatchMode) {
954959
debug!("walk_pat cmt_discr={:?} pat={:?}", cmt_discr, pat);
955960

956-
let tcx = &self.tcx();
957-
let mc = &self.mc;
961+
let tcx = self.tcx();
958962
let infcx = self.mc.infcx;
959-
let delegate = &mut self.delegate;
963+
let ExprUseVisitor { ref mc, ref mut delegate, param_env } = *self;
960964
return_if_err!(mc.cat_pattern(cmt_discr.clone(), pat, |mc, cmt_pat, pat| {
961965
if let PatKind::Binding(bmode, def_id, ..) = pat.node {
962966
debug!("binding cmt_pat={:?} pat={:?} match_mode={:?}", cmt_pat, pat, match_mode);
@@ -980,7 +984,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
980984
}
981985
}
982986
hir::BindByValue(..) => {
983-
let mode = copy_or_move(infcx, &cmt_pat, PatBindingMove);
987+
let mode = copy_or_move(infcx, param_env, &cmt_pat, PatBindingMove);
984988
debug!("walk_pat binding consuming pat");
985989
delegate.consume_pat(pat, cmt_pat, mode);
986990
}
@@ -1039,7 +1043,10 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
10391043
freevar.def));
10401044
match upvar_capture {
10411045
ty::UpvarCapture::ByValue => {
1042-
let mode = copy_or_move(self.mc.infcx, &cmt_var, CaptureMove);
1046+
let mode = copy_or_move(self.mc.infcx,
1047+
self.param_env,
1048+
&cmt_var,
1049+
CaptureMove);
10431050
self.delegate.consume(closure_expr.id, freevar.span, cmt_var, mode);
10441051
}
10451052
ty::UpvarCapture::ByRef(upvar_borrow) => {
@@ -1069,11 +1076,12 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
10691076
}
10701077

10711078
fn copy_or_move<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
1079+
param_env: ty::ParamEnv<'tcx>,
10721080
cmt: &mc::cmt<'tcx>,
10731081
move_reason: MoveReason)
10741082
-> ConsumeMode
10751083
{
1076-
if infcx.type_moves_by_default(cmt.ty, cmt.span) {
1084+
if infcx.type_moves_by_default(param_env, cmt.ty, cmt.span) {
10771085
Move(move_reason)
10781086
} else {
10791087
Copy

src/librustc/traits/coherence.rs

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,11 @@
1010

1111
//! See `README.md` for high-level documentation
1212
13-
use super::{SelectionContext, Obligation, ObligationCause};
14-
1513
use hir::def_id::{DefId, LOCAL_CRATE};
14+
use syntax_pos::DUMMY_SP;
15+
use traits::{self, Normalized, SelectionContext, Obligation, ObligationCause, Reveal};
1616
use ty::{self, Ty, TyCtxt};
17+
use ty::subst::Subst;
1718

1819
use infer::{InferCtxt, InferOk};
1920

@@ -37,6 +38,28 @@ pub fn overlapping_impls<'cx, 'gcx, 'tcx>(infcx: &InferCtxt<'cx, 'gcx, 'tcx>,
3738
overlap(selcx, impl1_def_id, impl2_def_id)
3839
}
3940

41+
fn with_fresh_ty_vars<'cx, 'gcx, 'tcx>(selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>,
42+
param_env: ty::ParamEnv<'tcx>,
43+
impl_def_id: DefId)
44+
-> ty::ImplHeader<'tcx>
45+
{
46+
let tcx = selcx.tcx();
47+
let impl_substs = selcx.infcx().fresh_substs_for_item(DUMMY_SP, impl_def_id);
48+
49+
let header = ty::ImplHeader {
50+
impl_def_id: impl_def_id,
51+
self_ty: tcx.type_of(impl_def_id),
52+
trait_ref: tcx.impl_trait_ref(impl_def_id),
53+
predicates: tcx.predicates_of(impl_def_id).predicates
54+
}.subst(tcx, impl_substs);
55+
56+
let Normalized { value: mut header, obligations } =
57+
traits::normalize(selcx, param_env, ObligationCause::dummy(), &header);
58+
59+
header.predicates.extend(obligations.into_iter().map(|o| o.predicate));
60+
header
61+
}
62+
4063
/// Can both impl `a` and impl `b` be satisfied by a common type (including
4164
/// `where` clauses)? If so, returns an `ImplHeader` that unifies the two impls.
4265
fn overlap<'cx, 'gcx, 'tcx>(selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>,
@@ -48,17 +71,24 @@ fn overlap<'cx, 'gcx, 'tcx>(selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>,
4871
a_def_id,
4972
b_def_id);
5073

51-
let a_impl_header = ty::ImplHeader::with_fresh_ty_vars(selcx, a_def_id);
52-
let b_impl_header = ty::ImplHeader::with_fresh_ty_vars(selcx, b_def_id);
74+
// For the purposes of this check, we don't bring any skolemized
75+
// types into scope; instead, we replace the generic types with
76+
// fresh type variables, and hence we do our evaluations in an
77+
// empty environment.
78+
let param_env = ty::ParamEnv::empty(Reveal::UserFacing);
79+
80+
let a_impl_header = with_fresh_ty_vars(selcx, param_env, a_def_id);
81+
let b_impl_header = with_fresh_ty_vars(selcx, param_env, b_def_id);
5382

5483
debug!("overlap: a_impl_header={:?}", a_impl_header);
5584
debug!("overlap: b_impl_header={:?}", b_impl_header);
5685

5786
// Do `a` and `b` unify? If not, no overlap.
5887
let obligations = match selcx.infcx().eq_impl_headers(true,
59-
&ObligationCause::dummy(),
60-
&a_impl_header,
61-
&b_impl_header) {
88+
&ObligationCause::dummy(),
89+
param_env,
90+
&a_impl_header,
91+
&b_impl_header) {
6292
Ok(InferOk { obligations, .. }) => {
6393
obligations
6494
}
@@ -75,6 +105,7 @@ fn overlap<'cx, 'gcx, 'tcx>(selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>,
75105
.chain(&b_impl_header.predicates)
76106
.map(|p| infcx.resolve_type_vars_if_possible(p))
77107
.map(|p| Obligation { cause: ObligationCause::dummy(),
108+
param_env: param_env,
78109
recursion_depth: 0,
79110
predicate: p })
80111
.chain(obligations)

src/librustc/traits/error_reporting.rs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -179,12 +179,13 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
179179
data);
180180
let normalized = super::normalize_projection_type(
181181
&mut selcx,
182+
obligation.param_env,
182183
data.projection_ty,
183184
obligation.cause.clone(),
184185
0
185186
);
186187
if let Err(error) = self.eq_types(
187-
false, &obligation.cause,
188+
false, &obligation.cause, obligation.param_env,
188189
data.ty, normalized.value
189190
) {
190191
values = Some(infer::ValuePairs::Types(ExpectedFound {
@@ -251,7 +252,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
251252
-> Option<DefId>
252253
{
253254
let tcx = self.tcx;
254-
255+
let param_env = obligation.param_env;
255256
let trait_ref = tcx.erase_late_bound_regions(&trait_ref);
256257
let trait_self_ty = trait_ref.self_ty();
257258

@@ -268,7 +269,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
268269

269270
let impl_self_ty = impl_trait_ref.self_ty();
270271

271-
if let Ok(..) = self.can_equate(&trait_self_ty, &impl_self_ty) {
272+
if let Ok(..) = self.can_equate(param_env, &trait_self_ty, &impl_self_ty) {
272273
self_match_impls.push(def_id);
273274

274275
if trait_ref.substs.types().skip(1)
@@ -578,7 +579,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
578579

579580
// Try to report a help message
580581
if !trait_ref.has_infer_types() &&
581-
self.predicate_can_apply(trait_ref) {
582+
self.predicate_can_apply(obligation.param_env, trait_ref) {
582583
// If a where-clause may be useful, remind the
583584
// user that they can add it.
584585
//
@@ -607,7 +608,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
607608
ty::Predicate::Equate(ref predicate) => {
608609
let predicate = self.resolve_type_vars_if_possible(predicate);
609610
let err = self.equality_predicate(&obligation.cause,
610-
&predicate).err().unwrap();
611+
obligation.param_env,
612+
&predicate).err().unwrap();
611613
struct_span_err!(self.tcx.sess, span, E0278,
612614
"the requirement `{}` is not satisfied (`{}`)",
613615
predicate, err)
@@ -936,7 +938,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
936938

937939
/// Returns whether the trait predicate may apply for *some* assignment
938940
/// to the type parameters.
939-
fn predicate_can_apply(&self, pred: ty::PolyTraitRef<'tcx>) -> bool {
941+
fn predicate_can_apply(&self,
942+
param_env: ty::ParamEnv<'tcx>,
943+
pred: ty::PolyTraitRef<'tcx>)
944+
-> bool {
940945
struct ParamToVarFolder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
941946
infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
942947
var_map: FxHashMap<Ty<'tcx>, Ty<'tcx>>
@@ -967,12 +972,14 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
967972

968973
let cleaned_pred = super::project::normalize(
969974
&mut selcx,
975+
param_env,
970976
ObligationCause::dummy(),
971977
&cleaned_pred
972978
).value;
973979

974980
let obligation = Obligation::new(
975981
ObligationCause::dummy(),
982+
param_env,
976983
cleaned_pred.to_predicate()
977984
);
978985

src/librustc/traits/fulfill.rs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ impl<'a, 'gcx, 'tcx> FulfillmentContext<'tcx> {
113113
/// `projection_ty` again.
114114
pub fn normalize_projection_type(&mut self,
115115
infcx: &InferCtxt<'a, 'gcx, 'tcx>,
116+
param_env: ty::ParamEnv<'tcx>,
116117
projection_ty: ty::ProjectionTy<'tcx>,
117118
cause: ObligationCause<'tcx>)
118119
-> Ty<'tcx>
@@ -125,7 +126,11 @@ impl<'a, 'gcx, 'tcx> FulfillmentContext<'tcx> {
125126
// FIXME(#20304) -- cache
126127

127128
let mut selcx = SelectionContext::new(infcx);
128-
let normalized = project::normalize_projection_type(&mut selcx, projection_ty, cause, 0);
129+
let normalized = project::normalize_projection_type(&mut selcx,
130+
param_env,
131+
projection_ty,
132+
cause,
133+
0);
129134

130135
for obligation in normalized.obligations {
131136
self.register_predicate_obligation(infcx, obligation);
@@ -136,8 +141,12 @@ impl<'a, 'gcx, 'tcx> FulfillmentContext<'tcx> {
136141
normalized.value
137142
}
138143

144+
/// Requires that `ty` must implement the trait with `def_id` in
145+
/// the given environment. This trait must not have any type
146+
/// parameters (except for `Self`).
139147
pub fn register_bound(&mut self,
140148
infcx: &InferCtxt<'a, 'gcx, 'tcx>,
149+
param_env: ty::ParamEnv<'tcx>,
141150
ty: Ty<'tcx>,
142151
def_id: DefId,
143152
cause: ObligationCause<'tcx>)
@@ -149,6 +158,7 @@ impl<'a, 'gcx, 'tcx> FulfillmentContext<'tcx> {
149158
self.register_predicate_obligation(infcx, Obligation {
150159
cause: cause,
151160
recursion_depth: 0,
161+
param_env,
152162
predicate: trait_ref.to_predicate()
153163
});
154164
}
@@ -410,7 +420,7 @@ fn process_predicate<'a, 'gcx, 'tcx>(
410420
}
411421

412422
ty::Predicate::Equate(ref binder) => {
413-
match selcx.infcx().equality_predicate(&obligation.cause, binder) {
423+
match selcx.infcx().equality_predicate(&obligation.cause, obligation.param_env, binder) {
414424
Ok(InferOk { obligations, value: () }) => {
415425
Ok(Some(obligations))
416426
},
@@ -498,7 +508,7 @@ fn process_predicate<'a, 'gcx, 'tcx>(
498508
}
499509

500510
ty::Predicate::WellFormed(ty) => {
501-
match ty::wf::obligations(selcx.infcx(), obligation.cause.body_id,
511+
match ty::wf::obligations(selcx.infcx(), obligation.param_env, obligation.cause.body_id,
502512
ty, obligation.cause.span) {
503513
None => {
504514
pending_obligation.stalled_on = vec![ty];
@@ -509,7 +519,7 @@ fn process_predicate<'a, 'gcx, 'tcx>(
509519
}
510520

511521
ty::Predicate::Subtype(ref subtype) => {
512-
match selcx.infcx().subtype_predicate(&obligation.cause, subtype) {
522+
match selcx.infcx().subtype_predicate(&obligation.cause, obligation.param_env, subtype) {
513523
None => {
514524
// none means that both are unresolved
515525
pending_obligation.stalled_on = vec![subtype.skip_binder().a,

0 commit comments

Comments
 (0)