Skip to content

Commit 9783947

Browse files
committed
rustc_typeck: move impl Trait checks out of RegionScope.
1 parent ba1849d commit 9783947

File tree

5 files changed

+65
-143
lines changed

5 files changed

+65
-143
lines changed

src/librustc_typeck/astconv.rs

Lines changed: 53 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ use rustc::ty::wf::object_region_bounds;
6262
use rustc_back::slice;
6363
use require_c_abi_if_variadic;
6464
use rscope::{RegionScope, ObjectLifetimeDefaultRscope, ShiftedRscope};
65-
use rscope::{AnonTypeScope, MaybeWithAnonTypes, ExplicitRscope};
65+
use rscope::ExplicitRscope;
6666
use util::common::{ErrorReported, FN_OUTPUT_NAME};
6767
use util::nodemap::{NodeMap, FxHashSet};
6868

@@ -361,8 +361,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
361361
}
362362
hir::ParenthesizedParameters(ref data) => {
363363
assert_eq!(i, 0);
364-
let (ty, assoc) =
365-
self.convert_parenthesized_parameters(rscope, substs, data);
364+
let (ty, assoc) = self.convert_parenthesized_parameters(substs, data);
366365
output_assoc_binding = Some(assoc);
367366
ty
368367
}
@@ -416,7 +415,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
416415
vec![output_assoc_binding.unwrap_or_else(|| {
417416
// This is an error condition, but we should
418417
// get the associated type binding anyway.
419-
self.convert_parenthesized_parameters(rscope, substs, data).1
418+
self.convert_parenthesized_parameters(substs, data).1
420419
})]
421420
}
422421
};
@@ -428,20 +427,17 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
428427
}
429428

430429
fn convert_parenthesized_parameters(&self,
431-
rscope: &RegionScope,
432430
region_substs: &[Kind<'tcx>],
433431
data: &hir::ParenthesizedParameterData)
434432
-> (Ty<'tcx>, ConvertedBinding<'tcx>)
435433
{
436-
let anon_scope = rscope.anon_type_scope();
437-
let rscope = MaybeWithAnonTypes::new(ExplicitRscope, anon_scope);
438434
let inputs = self.tcx().mk_type_list(data.inputs.iter().map(|a_t| {
439-
self.ast_ty_arg_to_ty(&rscope, None, region_substs, a_t)
435+
self.ast_ty_arg_to_ty(&ExplicitRscope, None, region_substs, a_t)
440436
}));
441437

442438
let (output, output_span) = match data.output {
443439
Some(ref output_ty) => {
444-
(self.ast_ty_to_ty(&rscope, output_ty), output_ty.span)
440+
(self.ast_ty_to_ty(&ExplicitRscope, output_ty), output_ty.span)
445441
}
446442
None => {
447443
(self.tcx().mk_nil(), data.span)
@@ -1309,12 +1305,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
13091305
}
13101306
hir::TyBareFn(ref bf) => {
13111307
require_c_abi_if_variadic(tcx, &bf.decl, bf.abi, ast_ty.span);
1312-
let anon_scope = rscope.anon_type_scope();
1313-
let bare_fn_ty = self.ty_of_method_or_bare_fn(bf.unsafety,
1314-
bf.abi,
1315-
&bf.decl,
1316-
anon_scope,
1317-
anon_scope);
1308+
let bare_fn_ty = self.ty_of_fn(bf.unsafety, bf.abi, &bf.decl);
13181309

13191310
// Find any late-bound regions declared in return type that do
13201311
// not appear in the arguments. These are not wellformed.
@@ -1361,16 +1352,54 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
13611352
hir::TyImplTrait(ref bounds) => {
13621353
use collect::{compute_bounds, SizedByDefault};
13631354

1355+
// Figure out if we can allow an `impl Trait` here, by walking up
1356+
// to a `fn` or inherent `impl` method, going only through `Ty`
1357+
// or `TraitRef` nodes (as nothing else should be in types) and
1358+
// ensuring that we reach the `fn`/method signature's return type.
1359+
let mut node_id = ast_ty.id;
1360+
let fn_decl = loop {
1361+
let parent = tcx.hir.get_parent_node(node_id);
1362+
match tcx.hir.get(parent) {
1363+
hir::map::NodeItem(&hir::Item {
1364+
node: hir::ItemFn(ref fn_decl, ..), ..
1365+
}) => break Some(fn_decl),
1366+
1367+
hir::map::NodeImplItem(&hir::ImplItem {
1368+
node: hir::ImplItemKind::Method(ref sig, _), ..
1369+
}) => {
1370+
match tcx.hir.expect_item(tcx.hir.get_parent(parent)).node {
1371+
hir::ItemImpl(.., None, _, _) => {
1372+
break Some(&sig.decl)
1373+
}
1374+
_ => break None
1375+
}
1376+
}
1377+
1378+
hir::map::NodeTy(_) | hir::map::NodeTraitRef(_) => {}
1379+
1380+
_ => break None
1381+
}
1382+
node_id = parent;
1383+
};
1384+
let allow = fn_decl.map_or(false, |fd| {
1385+
match fd.output {
1386+
hir::DefaultReturn(_) => false,
1387+
hir::Return(ref ty) => ty.id == node_id
1388+
}
1389+
});
1390+
13641391
// Create the anonymized type.
1365-
let def_id = tcx.hir.local_def_id(ast_ty.id);
1366-
if let Some(anon_scope) = rscope.anon_type_scope() {
1367-
let substs = anon_scope.fresh_substs(self, ast_ty.span);
1392+
if allow {
1393+
let def_id = tcx.hir.local_def_id(ast_ty.id);
1394+
if let Err(ErrorReported) = self.get_generics(ast_ty.span, def_id) {
1395+
return tcx.types.err;
1396+
}
1397+
let substs = Substs::identity_for_item(tcx, def_id);
13681398
let ty = tcx.mk_anon(tcx.hir.local_def_id(ast_ty.id), substs);
13691399

13701400
// Collect the bounds, i.e. the `A+B+'c` in `impl A+B+'c`.
13711401
let bounds = compute_bounds(self, ty, bounds,
13721402
SizedByDefault::Yes,
1373-
Some(anon_scope),
13741403
ast_ty.span);
13751404
let predicates = bounds.predicates(tcx, ty);
13761405
let predicates = tcx.lift_to_global(&predicates).unwrap();
@@ -1450,36 +1479,19 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
14501479
pub fn ty_of_fn(&self,
14511480
unsafety: hir::Unsafety,
14521481
abi: abi::Abi,
1453-
decl: &hir::FnDecl,
1454-
anon_scope: Option<AnonTypeScope>)
1482+
decl: &hir::FnDecl)
14551483
-> &'tcx ty::BareFnTy<'tcx> {
1456-
self.ty_of_method_or_bare_fn(unsafety, abi, decl, None, anon_scope)
1457-
}
1458-
1459-
fn ty_of_method_or_bare_fn(&self,
1460-
unsafety: hir::Unsafety,
1461-
abi: abi::Abi,
1462-
decl: &hir::FnDecl,
1463-
arg_anon_scope: Option<AnonTypeScope>,
1464-
ret_anon_scope: Option<AnonTypeScope>)
1465-
-> &'tcx ty::BareFnTy<'tcx>
1466-
{
1467-
debug!("ty_of_method_or_bare_fn");
1468-
1469-
// New region names that appear inside of the arguments of the function
1470-
// declaration are bound to that function type.
1471-
let rb = MaybeWithAnonTypes::new(ExplicitRscope, arg_anon_scope);
1484+
debug!("ty_of_fn");
14721485

14731486
let input_tys: Vec<Ty> =
1474-
decl.inputs.iter().map(|a| self.ty_of_arg(&rb, a, None)).collect();
1487+
decl.inputs.iter().map(|a| self.ty_of_arg(&ExplicitRscope, a, None)).collect();
14751488

14761489
let output_ty = match decl.output {
1477-
hir::Return(ref output) =>
1478-
self.ast_ty_to_ty(&MaybeWithAnonTypes::new(ExplicitRscope, ret_anon_scope), output),
1490+
hir::Return(ref output) => self.ast_ty_to_ty(&ExplicitRscope, output),
14791491
hir::DefaultReturn(..) => self.tcx().mk_nil(),
14801492
};
14811493

1482-
debug!("ty_of_method_or_bare_fn: output_ty={:?}", output_ty);
1494+
debug!("ty_of_fn: output_ty={:?}", output_ty);
14831495

14841496
self.tcx().mk_bare_fn(ty::BareFnTy {
14851497
unsafety: unsafety,

src/librustc_typeck/collect.rs

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -641,7 +641,6 @@ fn convert_field<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
641641
}
642642

643643
fn convert_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
644-
container: AssociatedItemContainer,
645644
id: ast::NodeId,
646645
sig: &hir::MethodSig,
647646
rcvr_ty_predicates: &ty::GenericPredicates<'tcx>,) {
@@ -651,12 +650,8 @@ fn convert_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
651650
let ty_generic_predicates =
652651
ty_generic_predicates(ccx, &sig.generics, ty_generics.parent, vec![], false);
653652

654-
let anon_scope = match container {
655-
ImplContainer(_) => Some(AnonTypeScope::new(def_id)),
656-
TraitContainer(_) => None
657-
};
658653
let fty = AstConv::ty_of_fn(&ccx.icx(&(rcvr_ty_predicates, &sig.generics)),
659-
sig.unsafety, sig.abi, &sig.decl, anon_scope);
654+
sig.unsafety, sig.abi, &sig.decl);
660655

661656
let substs = mk_item_substs(&ccx.icx(&(rcvr_ty_predicates, &sig.generics)),
662657
ccx.tcx.hir.span(id), def_id);
@@ -874,8 +869,7 @@ fn convert_trait_item(ccx: &CrateCtxt, trait_item: &hir::TraitItem) {
874869
}
875870

876871
hir::TraitItemKind::Method(ref sig, _) => {
877-
convert_method(ccx, TraitContainer(trait_def_id),
878-
trait_item.id, sig, &trait_predicates);
872+
convert_method(ccx, trait_item.id, sig, &trait_predicates);
879873
}
880874
}
881875
}
@@ -915,7 +909,7 @@ fn convert_impl_item(ccx: &CrateCtxt, impl_item: &hir::ImplItem) {
915909
}
916910

917911
hir::ImplItemKind::Method(ref sig, _) => {
918-
convert_method(ccx, ImplContainer(impl_def_id), impl_item.id, sig, &impl_predicates);
912+
convert_method(ccx, impl_item.id, sig, &impl_predicates);
919913
}
920914
}
921915
}
@@ -1186,7 +1180,6 @@ fn ensure_super_predicates_step(ccx: &CrateCtxt,
11861180
self_param_ty,
11871181
bounds,
11881182
SizedByDefault::No,
1189-
None,
11901183
item.span);
11911184

11921185
let superbounds1 = superbounds1.predicates(tcx, self_param_ty);
@@ -1323,7 +1316,6 @@ fn convert_trait_predicates<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &hir::Item)
13231316
assoc_ty,
13241317
bounds,
13251318
SizedByDefault::Yes,
1326-
None,
13271319
trait_item.span);
13281320

13291321
bounds.predicates(ccx.tcx, assoc_ty).into_iter()
@@ -1537,8 +1529,7 @@ fn type_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
15371529
ccx.icx(&()).to_ty(&ExplicitRscope, &t)
15381530
}
15391531
ItemFn(ref decl, unsafety, _, abi, ref generics, _) => {
1540-
let tofd = AstConv::ty_of_fn(&ccx.icx(generics), unsafety, abi, &decl,
1541-
Some(AnonTypeScope::new(def_id)));
1532+
let tofd = AstConv::ty_of_fn(&ccx.icx(generics), unsafety, abi, &decl);
15421533
let substs = mk_item_substs(&ccx.icx(generics), item.span, def_id);
15431534
ccx.tcx.mk_fn_def(def_id, substs, tofd)
15441535
}
@@ -1770,7 +1761,6 @@ fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
17701761
param_ty,
17711762
&param.bounds,
17721763
SizedByDefault::Yes,
1773-
None,
17741764
param.span);
17751765
predicates.extend(bounds.predicates(ccx.tcx, param_ty));
17761766
}
@@ -1968,7 +1958,6 @@ pub fn compute_bounds<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>,
19681958
param_ty: ty::Ty<'tcx>,
19691959
ast_bounds: &[hir::TyParamBound],
19701960
sized_by_default: SizedByDefault,
1971-
anon_scope: Option<AnonTypeScope>,
19721961
span: Span)
19731962
-> Bounds<'tcx>
19741963
{
@@ -1979,9 +1968,8 @@ pub fn compute_bounds<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>,
19791968

19801969
let mut projection_bounds = vec![];
19811970

1982-
let rscope = MaybeWithAnonTypes::new(ExplicitRscope, anon_scope);
19831971
let mut trait_bounds: Vec<_> = trait_bounds.iter().map(|&bound| {
1984-
astconv.instantiate_poly_trait_ref(&rscope,
1972+
astconv.instantiate_poly_trait_ref(&ExplicitRscope,
19851973
bound,
19861974
param_ty,
19871975
&mut projection_bounds)
@@ -2048,7 +2036,7 @@ fn compute_type_of_foreign_fn_decl<'a, 'tcx>(
20482036
abi: abi::Abi)
20492037
-> Ty<'tcx>
20502038
{
2051-
let fty = AstConv::ty_of_fn(&ccx.icx(ast_generics), hir::Unsafety::Unsafe, abi, decl, None);
2039+
let fty = AstConv::ty_of_fn(&ccx.icx(ast_generics), hir::Unsafety::Unsafe, abi, decl);
20522040

20532041
// feature gate SIMD types in FFI, since I (huonw) am not sure the
20542042
// ABIs are handled at all correctly.
@@ -2077,10 +2065,10 @@ fn compute_type_of_foreign_fn_decl<'a, 'tcx>(
20772065
ccx.tcx.mk_fn_def(def_id, substs, fty)
20782066
}
20792067

2080-
pub fn mk_item_substs<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>,
2081-
span: Span,
2082-
def_id: DefId)
2083-
-> &'tcx Substs<'tcx> {
2068+
fn mk_item_substs<'tcx>(astconv: &AstConv<'tcx, 'tcx>,
2069+
span: Span,
2070+
def_id: DefId)
2071+
-> &'tcx Substs<'tcx> {
20842072
let tcx = astconv.tcx();
20852073
// FIXME(eddyb) Do this request from Substs::for_item in librustc.
20862074
if let Err(ErrorReported) = astconv.get_generics(span, def_id) {

src/librustc_typeck/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ This API is completely unstable and subject to change.
7777
#![feature(box_patterns)]
7878
#![feature(box_syntax)]
7979
#![feature(conservative_impl_trait)]
80+
#![feature(loop_break_value)]
8081
#![feature(quote)]
8182
#![feature(rustc_diagnostic_macros)]
8283
#![feature(rustc_private)]

src/librustc_typeck/rscope.rs

Lines changed: 0 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
use rustc::hir::def_id::DefId;
1211
use rustc::ty;
13-
use rustc::ty::subst::Substs;
14-
15-
use astconv::AstConv;
1612

1713
use syntax_pos::Span;
1814

@@ -38,73 +34,6 @@ pub trait RegionScope {
3834
/// computing `object_lifetime_default` (in particular, in legacy
3935
/// modes, it may not be relevant).
4036
fn base_object_lifetime_default(&self, span: Span) -> ty::Region;
41-
42-
/// If this scope allows anonymized types, return the generics in
43-
/// scope, that anonymized types will close over. For example,
44-
/// if you have a function like:
45-
///
46-
/// fn foo<'a, T>() -> impl Trait { ... }
47-
///
48-
/// then, for the rscope that is used when handling the return type,
49-
/// `anon_type_scope()` would return a `Some(AnonTypeScope {...})`,
50-
/// on which `.fresh_substs(...)` can be used to obtain identity
51-
/// Substs for `'a` and `T`, to track them in `TyAnon`. This property
52-
/// is controlled by the region scope because it's fine-grained enough
53-
/// to allow restriction of anonymized types to the syntactical extent
54-
/// of a function's return type.
55-
fn anon_type_scope(&self) -> Option<AnonTypeScope> {
56-
None
57-
}
58-
}
59-
60-
#[derive(Copy, Clone)]
61-
pub struct AnonTypeScope {
62-
enclosing_item: DefId
63-
}
64-
65-
impl<'gcx: 'tcx, 'tcx> AnonTypeScope {
66-
pub fn new(enclosing_item: DefId) -> AnonTypeScope {
67-
AnonTypeScope {
68-
enclosing_item: enclosing_item
69-
}
70-
}
71-
72-
pub fn fresh_substs(&self, astconv: &AstConv<'gcx, 'tcx>, span: Span)
73-
-> &'tcx Substs<'tcx> {
74-
use collect::mk_item_substs;
75-
76-
mk_item_substs(astconv, span, self.enclosing_item)
77-
}
78-
}
79-
80-
/// A scope wrapper which optionally allows anonymized types.
81-
#[derive(Copy, Clone)]
82-
pub struct MaybeWithAnonTypes<R> {
83-
base_scope: R,
84-
anon_scope: Option<AnonTypeScope>
85-
}
86-
87-
impl<R: RegionScope> MaybeWithAnonTypes<R> {
88-
pub fn new(base_scope: R, anon_scope: Option<AnonTypeScope>) -> Self {
89-
MaybeWithAnonTypes {
90-
base_scope: base_scope,
91-
anon_scope: anon_scope
92-
}
93-
}
94-
}
95-
96-
impl<R: RegionScope> RegionScope for MaybeWithAnonTypes<R> {
97-
fn object_lifetime_default(&self, span: Span) -> Option<ty::Region> {
98-
self.base_scope.object_lifetime_default(span)
99-
}
100-
101-
fn base_object_lifetime_default(&self, span: Span) -> ty::Region {
102-
self.base_scope.base_object_lifetime_default(span)
103-
}
104-
105-
fn anon_type_scope(&self) -> Option<AnonTypeScope> {
106-
self.anon_scope
107-
}
10837
}
10938

11039
// A scope in which all regions must be explicitly named. This is used
@@ -158,10 +87,6 @@ impl<'r> RegionScope for ObjectLifetimeDefaultRscope<'r> {
15887
fn base_object_lifetime_default(&self, span: Span) -> ty::Region {
15988
self.base_scope.base_object_lifetime_default(span)
16089
}
161-
162-
fn anon_type_scope(&self) -> Option<AnonTypeScope> {
163-
self.base_scope.anon_type_scope()
164-
}
16590
}
16691

16792
/// A scope which simply shifts the Debruijn index of other scopes
@@ -185,8 +110,4 @@ impl<'r> RegionScope for ShiftedRscope<'r> {
185110
fn base_object_lifetime_default(&self, span: Span) -> ty::Region {
186111
ty::fold::shift_region(self.base_scope.base_object_lifetime_default(span), 1)
187112
}
188-
189-
fn anon_type_scope(&self) -> Option<AnonTypeScope> {
190-
self.base_scope.anon_type_scope()
191-
}
192113
}

0 commit comments

Comments
 (0)