Skip to content

Commit 6ebb6fd

Browse files
committed
hir: lower ImplicitSelf to resolved Self TyQPath's.
1 parent 0807104 commit 6ebb6fd

File tree

10 files changed

+106
-183
lines changed

10 files changed

+106
-183
lines changed

src/librustc/hir/lowering.rs

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ impl<'a> LoweringContext<'a> {
259259
P(hir::Ty {
260260
id: t.id,
261261
node: match t.node {
262-
TyKind::Infer | TyKind::ImplicitSelf => hir::TyInfer,
262+
TyKind::Infer => hir::TyInfer,
263263
TyKind::Slice(ref ty) => hir::TySlice(self.lower_ty(ty)),
264264
TyKind::Ptr(ref mt) => hir::TyPtr(self.lower_mt(mt)),
265265
TyKind::Rptr(ref region, ref mt) => {
@@ -283,6 +283,16 @@ impl<'a> LoweringContext<'a> {
283283
TyKind::Path(ref qself, ref path) => {
284284
hir::TyPath(self.lower_qpath(t.id, qself, path, ParamMode::Explicit))
285285
}
286+
TyKind::ImplicitSelf => {
287+
hir::TyPath(hir::QPath::Resolved(None, P(hir::Path {
288+
def: self.expect_full_def(t.id),
289+
segments: hir_vec![hir::PathSegment {
290+
name: keywords::SelfType.name(),
291+
parameters: hir::PathParameters::none()
292+
}],
293+
span: t.span,
294+
})))
295+
}
286296
TyKind::ObjectSum(ref ty, ref bounds) => {
287297
hir::TyObjectSum(self.lower_ty(ty), self.lower_bounds(bounds))
288298
}
@@ -976,7 +986,7 @@ impl<'a> LoweringContext<'a> {
976986
ImplItemKind::Const(..) => hir::AssociatedItemKind::Const,
977987
ImplItemKind::Type(..) => hir::AssociatedItemKind::Type,
978988
ImplItemKind::Method(ref sig, _) => hir::AssociatedItemKind::Method {
979-
has_self: sig.decl.get_self().is_some(),
989+
has_self: sig.decl.has_self(),
980990
},
981991
ImplItemKind::Macro(..) => unimplemented!(),
982992
},
@@ -1051,24 +1061,13 @@ impl<'a> LoweringContext<'a> {
10511061
}
10521062

10531063
fn lower_method_sig(&mut self, sig: &MethodSig) -> hir::MethodSig {
1054-
let hir_sig = hir::MethodSig {
1064+
hir::MethodSig {
10551065
generics: self.lower_generics(&sig.generics),
10561066
abi: sig.abi,
10571067
unsafety: self.lower_unsafety(sig.unsafety),
10581068
constness: self.lower_constness(sig.constness),
10591069
decl: self.lower_fn_decl(&sig.decl),
1060-
};
1061-
// Check for `self: _` and `self: &_`
1062-
if let Some(SelfKind::Explicit(..)) = sig.decl.get_self().map(|eself| eself.node) {
1063-
match hir_sig.decl.get_self().map(|eself| eself.node) {
1064-
Some(hir::SelfKind::Value(..)) | Some(hir::SelfKind::Region(..)) => {
1065-
self.diagnostic().span_err(sig.decl.inputs[0].ty.span,
1066-
"the type placeholder `_` is not allowed within types on item signatures");
1067-
}
1068-
_ => {}
1069-
}
10701070
}
1071-
hir_sig
10721071
}
10731072

10741073
fn lower_unsafety(&mut self, u: Unsafety) -> hir::Unsafety {

src/librustc/hir/mod.rs

Lines changed: 3 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ use hir::def_id::DefId;
3535
use util::nodemap::{NodeMap, FxHashSet};
3636
use rustc_data_structures::fnv::FnvHashMap;
3737

38-
use syntax_pos::{mk_sp, Span, ExpnId, DUMMY_SP};
39-
use syntax::codemap::{self, respan, Spanned};
38+
use syntax_pos::{Span, ExpnId, DUMMY_SP};
39+
use syntax::codemap::{self, Spanned};
4040
use syntax::abi::Abi;
4141
use syntax::ast::{Name, NodeId, DUMMY_NODE_ID, AsmDialect};
4242
use syntax::ast::{Attribute, Lit, StrStyle, FloatTy, IntTy, UintTy, MetaItem};
@@ -1234,37 +1234,8 @@ pub struct Arg {
12341234
pub id: NodeId,
12351235
}
12361236

1237-
/// Alternative representation for `Arg`s describing `self` parameter of methods.
1238-
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1239-
pub enum SelfKind {
1240-
/// `self`, `mut self`
1241-
Value(Mutability),
1242-
/// `&'lt self`, `&'lt mut self`
1243-
Region(Option<Lifetime>, Mutability),
1244-
/// `self: TYPE`, `mut self: TYPE`
1245-
Explicit(P<Ty>, Mutability),
1246-
}
1247-
1248-
pub type ExplicitSelf = Spanned<SelfKind>;
1249-
12501237
impl Arg {
1251-
pub fn to_self(&self) -> Option<ExplicitSelf> {
1252-
if let PatKind::Binding(BindByValue(mutbl), _, name, _) = self.pat.node {
1253-
if name.node == keywords::SelfValue.name() {
1254-
return match self.ty.node {
1255-
TyInfer => Some(respan(self.pat.span, SelfKind::Value(mutbl))),
1256-
TyRptr(lt, MutTy{ref ty, mutbl}) if ty.node == TyInfer => {
1257-
Some(respan(self.pat.span, SelfKind::Region(lt, mutbl)))
1258-
}
1259-
_ => Some(respan(mk_sp(self.pat.span.lo, self.ty.span.hi),
1260-
SelfKind::Explicit(self.ty.clone(), mutbl)))
1261-
}
1262-
}
1263-
}
1264-
None
1265-
}
1266-
1267-
pub fn is_self(&self) -> bool {
1238+
fn is_self(&self) -> bool {
12681239
if let PatKind::Binding(_, _, name, _) = self.pat.node {
12691240
name.node == keywords::SelfValue.name()
12701241
} else {
@@ -1282,9 +1253,6 @@ pub struct FnDecl {
12821253
}
12831254

12841255
impl FnDecl {
1285-
pub fn get_self(&self) -> Option<ExplicitSelf> {
1286-
self.inputs.get(0).and_then(Arg::to_self)
1287-
}
12881256
pub fn has_self(&self) -> bool {
12891257
self.inputs.get(0).map(Arg::is_self).unwrap_or(false)
12901258
}

src/librustc/hir/print.rs

Lines changed: 10 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use syntax_pos::{self, BytePos};
2525
use errors;
2626

2727
use hir;
28-
use hir::{Crate, PatKind, RegionTyParamBound, SelfKind, TraitTyParamBound, TraitBoundModifier};
28+
use hir::{Crate, PatKind, RegionTyParamBound, TraitTyParamBound, TraitBoundModifier};
2929

3030
use std::io::{self, Write, Read};
3131

@@ -1954,27 +1954,6 @@ impl<'a> State<'a> {
19541954
self.end() // close enclosing cbox
19551955
}
19561956

1957-
fn print_explicit_self(&mut self, explicit_self: &hir::ExplicitSelf) -> io::Result<()> {
1958-
match explicit_self.node {
1959-
SelfKind::Value(m) => {
1960-
self.print_mutability(m)?;
1961-
word(&mut self.s, "self")
1962-
}
1963-
SelfKind::Region(ref lt, m) => {
1964-
word(&mut self.s, "&")?;
1965-
self.print_opt_lifetime(lt)?;
1966-
self.print_mutability(m)?;
1967-
word(&mut self.s, "self")
1968-
}
1969-
SelfKind::Explicit(ref typ, m) => {
1970-
self.print_mutability(m)?;
1971-
word(&mut self.s, "self")?;
1972-
self.word_space(":")?;
1973-
self.print_type(&typ)
1974-
}
1975-
}
1976-
}
1977-
19781957
pub fn print_fn(&mut self,
19791958
decl: &hir::FnDecl,
19801959
unsafety: hir::Unsafety,
@@ -2185,21 +2164,17 @@ impl<'a> State<'a> {
21852164
match input.ty.node {
21862165
hir::TyInfer if is_closure => self.print_pat(&input.pat)?,
21872166
_ => {
2188-
if let Some(eself) = input.to_self() {
2189-
self.print_explicit_self(&eself)?;
2167+
let invalid = if let PatKind::Binding(_, _, name, _) = input.pat.node {
2168+
name.node == keywords::Invalid.name()
21902169
} else {
2191-
let invalid = if let PatKind::Binding(_, _, name, _) = input.pat.node {
2192-
name.node == keywords::Invalid.name()
2193-
} else {
2194-
false
2195-
};
2196-
if !invalid {
2197-
self.print_pat(&input.pat)?;
2198-
word(&mut self.s, ":")?;
2199-
space(&mut self.s)?;
2200-
}
2201-
self.print_type(&input.ty)?;
2170+
false
2171+
};
2172+
if !invalid {
2173+
self.print_pat(&input.pat)?;
2174+
word(&mut self.s, ":")?;
2175+
space(&mut self.s)?;
22022176
}
2177+
self.print_type(&input.ty)?;
22032178
}
22042179
}
22052180
self.end()

src/librustc/ty/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2127,7 +2127,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
21272127

21282128
let (kind, has_self, has_value) = match trait_item.node {
21292129
hir::MethodTraitItem(ref sig, ref body) => {
2130-
(AssociatedKind::Method, sig.decl.get_self().is_some(),
2130+
(AssociatedKind::Method, sig.decl.has_self(),
21312131
body.is_some())
21322132
}
21332133
hir::ConstTraitItem(_, ref value) => {

src/librustc_resolve/lib.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,11 @@ impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> {
571571
fn visit_ty(&mut self, ty: &'tcx Ty) {
572572
if let TyKind::Path(ref qself, ref path) = ty.node {
573573
self.smart_resolve_path(ty.id, qself.as_ref(), path, PathSource::Type);
574+
} else if let TyKind::ImplicitSelf = ty.node {
575+
let self_ty = keywords::SelfType.ident();
576+
let def = self.resolve_ident_in_lexical_scope(self_ty, TypeNS, Some(ty.span))
577+
.map_or(Def::Err, |d| d.def());
578+
self.record_def(ty.id, PathResolution::new(def));
574579
}
575580
visit::walk_ty(self, ty);
576581
}
@@ -741,6 +746,13 @@ impl<'a> LexicalScopeBinding<'a> {
741746
_ => None,
742747
}
743748
}
749+
750+
fn def(self) -> Def {
751+
match self {
752+
LexicalScopeBinding::Item(binding) => binding.def(),
753+
LexicalScopeBinding::Def(def) => def,
754+
}
755+
}
744756
}
745757

746758
#[derive(Clone)]

src/librustc_typeck/astconv.rs

Lines changed: 23 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050
5151
use rustc_const_eval::eval_length;
5252
use rustc_data_structures::accumulate_vec::AccumulateVec;
53-
use hir::{self, SelfKind};
53+
use hir;
5454
use hir::def::Def;
5555
use hir::def_id::DefId;
5656
use hir::print as pprust;
@@ -1743,36 +1743,33 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
17431743
// declaration are bound to that function type.
17441744
let rb = MaybeWithAnonTypes::new(BindingRscope::new(), arg_anon_scope);
17451745

1746-
// `implied_output_region` is the region that will be assumed for any
1747-
// region parameters in the return type. In accordance with the rules for
1748-
// lifetime elision, we can determine it in two ways. First (determined
1749-
// here), if self is by-reference, then the implied output region is the
1750-
// region of the self parameter.
1751-
let (self_ty, explicit_self) = match (opt_untransformed_self_ty, decl.get_self()) {
1752-
(Some(untransformed_self_ty), Some(explicit_self)) => {
1753-
let self_type = self.determine_self_type(&rb, untransformed_self_ty,
1754-
&explicit_self);
1755-
(Some(self_type), Some(ExplicitSelf::determine(untransformed_self_ty, self_type)))
1756-
}
1757-
_ => (None, None),
1758-
};
1746+
let input_tys: Vec<Ty> =
1747+
decl.inputs.iter().map(|a| self.ty_of_arg(&rb, a, None)).collect();
17591748

1760-
// HACK(eddyb) replace the fake self type in the AST with the actual type.
1761-
let arg_params = if self_ty.is_some() {
1762-
&decl.inputs[1..]
1763-
} else {
1764-
&decl.inputs[..]
1749+
let has_self = decl.has_self();
1750+
let explicit_self = match (opt_untransformed_self_ty, has_self) {
1751+
(Some(untransformed_self_ty), true) => {
1752+
Some(ExplicitSelf::determine(untransformed_self_ty, input_tys[0]))
1753+
}
1754+
_ => None
17651755
};
1766-
let arg_tys: Vec<Ty> =
1767-
arg_params.iter().map(|a| self.ty_of_arg(&rb, a, None)).collect();
17681756

1769-
// Second, if there was exactly one lifetime (either a substitution or a
1770-
// reference) in the arguments, then any anonymous regions in the output
1771-
// have that lifetime.
17721757
let implied_output_region = match explicit_self {
1758+
// `implied_output_region` is the region that will be assumed for any
1759+
// region parameters in the return type. In accordance with the rules for
1760+
// lifetime elision, we can determine it in two ways. First (determined
1761+
// here), if self is by-reference, then the implied output region is the
1762+
// region of the self parameter.
17731763
Some(ExplicitSelf::ByReference(region, _)) => Ok(*region),
1764+
1765+
// Second, if there was exactly one lifetime (either a substitution or a
1766+
// reference) in the arguments, then any anonymous regions in the output
1767+
// have that lifetime.
17741768
_ => {
1775-
self.find_implied_output_region(&arg_tys,
1769+
let arg_params = &decl.inputs[has_self as usize..];
1770+
let arg_tys = &input_tys[has_self as usize..];
1771+
1772+
self.find_implied_output_region(arg_tys,
17761773
arg_params.iter()
17771774
.map(|a| pprust::pat_to_string(&a.pat)))
17781775

@@ -1793,37 +1790,13 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
17931790
unsafety: unsafety,
17941791
abi: abi,
17951792
sig: ty::Binder(self.tcx().mk_fn_sig(
1796-
self_ty.into_iter().chain(arg_tys),
1793+
input_tys.into_iter(),
17971794
output_ty,
17981795
decl.variadic
17991796
)),
18001797
})
18011798
}
18021799

1803-
fn determine_self_type<'a>(&self,
1804-
rscope: &RegionScope,
1805-
untransformed_self_ty: Ty<'tcx>,
1806-
explicit_self: &hir::ExplicitSelf)
1807-
-> Ty<'tcx>
1808-
{
1809-
match explicit_self.node {
1810-
SelfKind::Value(..) => untransformed_self_ty,
1811-
SelfKind::Region(ref lifetime, mutability) => {
1812-
let region =
1813-
self.opt_ast_region_to_region(
1814-
rscope,
1815-
explicit_self.span,
1816-
lifetime);
1817-
self.tcx().mk_ref(region,
1818-
ty::TypeAndMut {
1819-
ty: untransformed_self_ty,
1820-
mutbl: mutability
1821-
})
1822-
}
1823-
SelfKind::Explicit(ref ast_type, _) => self.ast_ty_to_ty(rscope, &ast_type)
1824-
}
1825-
}
1826-
18271800
pub fn ty_of_closure(&self,
18281801
unsafety: hir::Unsafety,
18291802
decl: &hir::FnDecl,

src/librustc_typeck/check/compare_method.rs

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

11-
use rustc::hir;
11+
use rustc::hir::{self, ImplItemKind, TraitItem_};
1212
use rustc::infer::{self, InferOk};
1313
use rustc::middle::free_region::FreeRegionMap;
1414
use rustc::ty;
1515
use rustc::traits::{self, ObligationCause, ObligationCauseCode, Reveal};
1616
use rustc::ty::error::{ExpectedFound, TypeError};
1717
use rustc::ty::subst::{Subst, Substs};
18-
use rustc::hir::{ImplItemKind, TraitItem_, Ty_};
1918
use rustc::util::common::ErrorReported;
2019

2120
use syntax::ast;
@@ -456,31 +455,18 @@ fn extract_spans_for_error_reporting<'a, 'gcx, 'tcx>(infcx: &infer::InferCtxt<'a
456455
_ => bug!("{:?} is not a MethodTraitItem", trait_m),
457456
};
458457

459-
impl_m_iter.zip(trait_m_iter)
460-
.find(|&(ref impl_arg, ref trait_arg)| {
461-
match (&impl_arg.ty.node, &trait_arg.ty.node) {
462-
(&Ty_::TyRptr(_, ref impl_mt), &Ty_::TyRptr(_, ref trait_mt)) |
463-
(&Ty_::TyPtr(ref impl_mt), &Ty_::TyPtr(ref trait_mt)) => {
464-
impl_mt.mutbl != trait_mt.mutbl
465-
}
466-
_ => false,
467-
}
468-
})
469-
.map(|(ref impl_arg, ref trait_arg)| {
470-
match (impl_arg.to_self(), trait_arg.to_self()) {
471-
(Some(impl_self), Some(trait_self)) => {
472-
(impl_self.span, Some(trait_self.span))
473-
}
474-
(None, None) => (impl_arg.ty.span, Some(trait_arg.ty.span)),
475-
_ => {
476-
bug!("impl and trait fns have different first args, impl: \
477-
{:?}, trait: {:?}",
478-
impl_arg,
479-
trait_arg)
480-
}
481-
}
482-
})
483-
.unwrap_or((cause.span, tcx.map.span_if_local(trait_m.def_id)))
458+
impl_m_iter.zip(trait_m_iter).find(|&(ref impl_arg, ref trait_arg)| {
459+
match (&impl_arg.ty.node, &trait_arg.ty.node) {
460+
(&hir::TyRptr(_, ref impl_mt), &hir::TyRptr(_, ref trait_mt)) |
461+
(&hir::TyPtr(ref impl_mt), &hir::TyPtr(ref trait_mt)) => {
462+
impl_mt.mutbl != trait_mt.mutbl
463+
}
464+
_ => false,
465+
}
466+
}).map(|(ref impl_arg, ref trait_arg)| {
467+
(impl_arg.ty.span, Some(trait_arg.ty.span))
468+
})
469+
.unwrap_or_else(|| (cause.span, tcx.map.span_if_local(trait_m.def_id)))
484470
} else {
485471
(cause.span, tcx.map.span_if_local(trait_m.def_id))
486472
}

0 commit comments

Comments
 (0)