Skip to content

Commit b6c0a62

Browse files
committed
Auto merge of #22172 - eddyb:almost-there, r=nikomatsakis
Adds `<module::Type>::method` support and makes `module::Type::method` a shorthand for it. This is most of #16293, except that chaining multiple associated types is not yet supported. Unfortunately, this is still a *[breaking-change]*: * If you used a global path to a primitive type, i.e. `::bool`, `::i32` etc. - that was a bug I had to fix. Solution: remove the leading `::`. * If you passed explicit `impl`-side type parameters to an inherent method, e.g.: ```rust struct Foo<T>(T); impl<A, B> Foo<(A, B)> { fn pair(a: A, b: B) -> Foo<(A, B)> { Foo((a, b)) } } Foo::<A, B>::pair(a, b) // Now that is sugar for: <Foo<A, B>>::pair(a, b) // Which isn't valid because `Foo` has only one type parameter. // Solution: replace with: Foo::<(A, B)>::pair(a, b) // And, if possible, remove the explicit type param entirely: Foo::pair(a, b) ``` * If you used the `QPath`-related `AstBuilder` methods @hugwijst added in #21943. The methods still exist, but `QPath` was replaced by `QSelf`, with the actual path stored separately. Solution: unpack the pair returned by `cx.qpath` to get the two arguments for `cx.expr_qpath`.
2 parents 522d09d + 4abb93c commit b6c0a62

File tree

110 files changed

+2290
-2612
lines changed

Some content is hidden

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

110 files changed

+2290
-2612
lines changed

src/libcollections/slice.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -790,7 +790,7 @@ pub trait SliceExt {
790790
fn ends_with(&self, needle: &[Self::Item]) -> bool where Self::Item: PartialEq;
791791

792792
/// Convert `self` into a vector without clones or allocation.
793-
#[unstable(feature = "collections")]
793+
#[stable(feature = "rust1", since = "1.0.0")]
794794
fn into_vec(self: Box<Self>) -> Vec<Self::Item>;
795795
}
796796

src/libcore/iter.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -978,7 +978,7 @@ pub trait IteratorExt: Iterator + Sized {
978978
#[unstable(feature = "core", reason = "recent addition")]
979979
fn cloned(self) -> Cloned<Self> where
980980
Self::Item: Deref,
981-
<Self::Item as Deref>::Output: Clone,
981+
<Self::Item as Deref>::Target: Clone,
982982
{
983983
Cloned { it: self }
984984
}

src/librustc/lint/builtin.rs

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -405,8 +405,8 @@ struct ImproperCTypesVisitor<'a, 'tcx: 'a> {
405405
}
406406

407407
impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
408-
fn check_def(&mut self, sp: Span, ty_id: ast::NodeId, path_id: ast::NodeId) {
409-
match self.cx.tcx.def_map.borrow()[path_id].clone() {
408+
fn check_def(&mut self, sp: Span, id: ast::NodeId) {
409+
match self.cx.tcx.def_map.borrow()[id].full_def() {
410410
def::DefPrimTy(ast::TyInt(ast::TyIs(_))) => {
411411
self.cx.span_lint(IMPROPER_CTYPES, sp,
412412
"found rust type `isize` in foreign module, while \
@@ -418,7 +418,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
418418
libc::c_uint or libc::c_ulong should be used");
419419
}
420420
def::DefTy(..) => {
421-
let tty = match self.cx.tcx.ast_ty_to_ty_cache.borrow().get(&ty_id) {
421+
let tty = match self.cx.tcx.ast_ty_to_ty_cache.borrow().get(&id) {
422422
Some(&ty::atttce_resolved(t)) => t,
423423
_ => panic!("ast_ty_to_ty_cache was incomplete after typeck!")
424424
};
@@ -437,9 +437,8 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
437437

438438
impl<'a, 'tcx, 'v> Visitor<'v> for ImproperCTypesVisitor<'a, 'tcx> {
439439
fn visit_ty(&mut self, ty: &ast::Ty) {
440-
match ty.node {
441-
ast::TyPath(_, id) => self.check_def(ty.span, ty.id, id),
442-
_ => (),
440+
if let ast::TyPath(..) = ty.node {
441+
self.check_def(ty.span, ty.id);
443442
}
444443
visit::walk_ty(self, ty);
445444
}
@@ -683,8 +682,8 @@ impl LintPass for PathStatements {
683682
match s.node {
684683
ast::StmtSemi(ref expr, _) => {
685684
match expr.node {
686-
ast::ExprPath(_) => cx.span_lint(PATH_STATEMENTS, s.span,
687-
"path statement with no effect"),
685+
ast::ExprPath(..) => cx.span_lint(PATH_STATEMENTS, s.span,
686+
"path statement with no effect"),
688687
_ => ()
689688
}
690689
}
@@ -1001,7 +1000,8 @@ impl LintPass for NonSnakeCase {
10011000

10021001
fn check_pat(&mut self, cx: &Context, p: &ast::Pat) {
10031002
if let &ast::PatIdent(_, ref path1, _) = &p.node {
1004-
if let Some(&def::DefLocal(_)) = cx.tcx.def_map.borrow().get(&p.id) {
1003+
let def = cx.tcx.def_map.borrow().get(&p.id).map(|d| d.full_def());
1004+
if let Some(def::DefLocal(_)) = def {
10051005
self.check_snake_case(cx, "variable", path1.node, p.span);
10061006
}
10071007
}
@@ -1066,8 +1066,8 @@ impl LintPass for NonUpperCaseGlobals {
10661066

10671067
fn check_pat(&mut self, cx: &Context, p: &ast::Pat) {
10681068
// Lint for constants that look like binding identifiers (#7526)
1069-
match (&p.node, cx.tcx.def_map.borrow().get(&p.id)) {
1070-
(&ast::PatIdent(_, ref path1, _), Some(&def::DefConst(..))) => {
1069+
match (&p.node, cx.tcx.def_map.borrow().get(&p.id).map(|d| d.full_def())) {
1070+
(&ast::PatIdent(_, ref path1, _), Some(def::DefConst(..))) => {
10711071
NonUpperCaseGlobals::check_upper_case(cx, "constant in pattern",
10721072
path1.node, p.span);
10731073
}
@@ -1227,10 +1227,13 @@ impl LintPass for NonShorthandFieldPatterns {
12271227
fn check_pat(&mut self, cx: &Context, pat: &ast::Pat) {
12281228
let def_map = cx.tcx.def_map.borrow();
12291229
if let ast::PatStruct(_, ref v, _) = pat.node {
1230-
for fieldpat in v.iter()
1231-
.filter(|fieldpat| !fieldpat.node.is_shorthand)
1232-
.filter(|fieldpat| def_map.get(&fieldpat.node.pat.id)
1233-
== Some(&def::DefLocal(fieldpat.node.pat.id))) {
1230+
let field_pats = v.iter()
1231+
.filter(|fieldpat| !fieldpat.node.is_shorthand)
1232+
.filter(|fieldpat| {
1233+
let def = def_map.get(&fieldpat.node.pat.id).map(|d| d.full_def());
1234+
def == Some(def::DefLocal(fieldpat.node.pat.id))
1235+
});
1236+
for fieldpat in field_pats {
12341237
if let ast::PatIdent(_, ident, None) = fieldpat.node.pat.node {
12351238
if ident.node.as_str() == fieldpat.node.ident.as_str() {
12361239
cx.span_lint(NON_SHORTHAND_FIELD_PATTERNS, fieldpat.span,
@@ -1857,10 +1860,7 @@ impl LintPass for UnconditionalRecursion {
18571860
_: ast::Ident,
18581861
id: ast::NodeId) -> bool {
18591862
tcx.def_map.borrow().get(&id)
1860-
.map_or(false, |def| {
1861-
let did = def.def_id();
1862-
ast_util::is_local(did) && did.node == fn_id
1863-
})
1863+
.map_or(false, |def| def.def_id() == ast_util::local_def(fn_id))
18641864
}
18651865

18661866
// check if the method call `id` refers to method `method_id`

src/librustc/metadata/csearch.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -150,12 +150,9 @@ pub fn get_trait_name(cstore: &cstore::CStore, def: ast::DefId) -> ast::Name {
150150
def.node)
151151
}
152152

153-
pub fn get_trait_item_name_and_kind(cstore: &cstore::CStore, def: ast::DefId)
154-
-> (ast::Name, def::TraitItemKind) {
153+
pub fn is_static_method(cstore: &cstore::CStore, def: ast::DefId) -> bool {
155154
let cdata = cstore.get_crate_data(def.krate);
156-
decoder::get_trait_item_name_and_kind(cstore.intr.clone(),
157-
&*cdata,
158-
def.node)
155+
decoder::is_static_method(&*cdata, def.node)
159156
}
160157

161158
pub fn get_trait_item_def_ids(cstore: &cstore::CStore, def: ast::DefId)

src/librustc/metadata/decoder.rs

Lines changed: 26 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,6 @@ enum Family {
119119
StaticMethod, // F
120120
Method, // h
121121
Type, // y
122-
ForeignType, // T
123122
Mod, // m
124123
ForeignMod, // n
125124
Enum, // t
@@ -144,7 +143,6 @@ fn item_family(item: rbml::Doc) -> Family {
144143
'F' => StaticMethod,
145144
'h' => Method,
146145
'y' => Type,
147-
'T' => ForeignType,
148146
'm' => Mod,
149147
'n' => ForeignMod,
150148
't' => Enum,
@@ -172,16 +170,13 @@ fn item_visibility(item: rbml::Doc) -> ast::Visibility {
172170
}
173171
}
174172

175-
fn item_sort(item: rbml::Doc) -> char {
173+
fn item_sort(item: rbml::Doc) -> Option<char> {
176174
let mut ret = None;
177175
reader::tagged_docs(item, tag_item_trait_item_sort, |doc| {
178176
ret = Some(doc.as_str_slice().as_bytes()[0] as char);
179177
false
180178
});
181-
match ret {
182-
Some(r) => r,
183-
None => panic!("No item_sort found")
184-
}
179+
ret
185180
}
186181

187182
fn item_symbol(item: rbml::Doc) -> String {
@@ -337,14 +332,16 @@ fn item_to_def_like(item: rbml::Doc, did: ast::DefId, cnum: ast::CrateNum)
337332
def::FromImpl(item_reqd_and_translated_parent_item(cnum,
338333
item))
339334
};
340-
match fam {
341-
// We don't bother to get encode/decode the trait id, we don't need it.
342-
Method => DlDef(def::DefMethod(did, None, provenance)),
343-
StaticMethod => DlDef(def::DefStaticMethod(did, provenance)),
344-
_ => panic!()
335+
DlDef(def::DefMethod(did, provenance))
336+
}
337+
Type => {
338+
if item_sort(item) == Some('t') {
339+
let trait_did = item_reqd_and_translated_parent_item(cnum, item);
340+
DlDef(def::DefAssociatedTy(trait_did, did))
341+
} else {
342+
DlDef(def::DefTy(did, false))
345343
}
346344
}
347-
Type | ForeignType => DlDef(def::DefTy(did, false)),
348345
Mod => DlDef(def::DefMod(did)),
349346
ForeignMod => DlDef(def::DefForeignMod(did)),
350347
StructVariant => {
@@ -829,8 +826,10 @@ pub fn get_impl_items(cdata: Cmd, impl_id: ast::NodeId)
829826
tag_item_impl_item, |doc| {
830827
let def_id = item_def_id(doc, cdata);
831828
match item_sort(doc) {
832-
'r' | 'p' => impl_items.push(ty::MethodTraitItemId(def_id)),
833-
't' => impl_items.push(ty::TypeTraitItemId(def_id)),
829+
Some('r') | Some('p') => {
830+
impl_items.push(ty::MethodTraitItemId(def_id))
831+
}
832+
Some('t') => impl_items.push(ty::TypeTraitItemId(def_id)),
834833
_ => panic!("unknown impl item sort"),
835834
}
836835
true
@@ -847,22 +846,13 @@ pub fn get_trait_name(intr: Rc<IdentInterner>,
847846
item_name(&*intr, doc)
848847
}
849848

850-
pub fn get_trait_item_name_and_kind(intr: Rc<IdentInterner>,
851-
cdata: Cmd,
852-
id: ast::NodeId)
853-
-> (ast::Name, def::TraitItemKind) {
849+
pub fn is_static_method(cdata: Cmd, id: ast::NodeId) -> bool {
854850
let doc = lookup_item(id, cdata.data());
855-
let name = item_name(&*intr, doc);
856851
match item_sort(doc) {
857-
'r' | 'p' => {
858-
let explicit_self = get_explicit_self(doc);
859-
(name, def::TraitItemKind::from_explicit_self_category(explicit_self))
860-
}
861-
't' => (name, def::TypeTraitItemKind),
862-
c => {
863-
panic!("get_trait_item_name_and_kind(): unknown trait item kind \
864-
in metadata: `{}`", c)
852+
Some('r') | Some('p') => {
853+
get_explicit_self(doc) == ty::StaticExplicitSelfCategory
865854
}
855+
_ => false
866856
}
867857
}
868858

@@ -887,7 +877,7 @@ pub fn get_impl_or_trait_item<'tcx>(intr: Rc<IdentInterner>,
887877
let vis = item_visibility(method_doc);
888878

889879
match item_sort(method_doc) {
890-
'r' | 'p' => {
880+
Some('r') | Some('p') => {
891881
let generics = doc_generics(method_doc, tcx, cdata, tag_method_ty_generics);
892882
let predicates = doc_predicates(method_doc, tcx, cdata, tag_method_ty_generics);
893883
let fty = doc_method_fty(method_doc, tcx, cdata);
@@ -904,7 +894,7 @@ pub fn get_impl_or_trait_item<'tcx>(intr: Rc<IdentInterner>,
904894
container,
905895
provided_source)))
906896
}
907-
't' => {
897+
Some('t') => {
908898
ty::TypeTraitItem(Rc::new(ty::AssociatedType {
909899
name: name,
910900
vis: vis,
@@ -924,8 +914,10 @@ pub fn get_trait_item_def_ids(cdata: Cmd, id: ast::NodeId)
924914
reader::tagged_docs(item, tag_item_trait_item, |mth| {
925915
let def_id = item_def_id(mth, cdata);
926916
match item_sort(mth) {
927-
'r' | 'p' => result.push(ty::MethodTraitItemId(def_id)),
928-
't' => result.push(ty::TypeTraitItemId(def_id)),
917+
Some('r') | Some('p') => {
918+
result.push(ty::MethodTraitItemId(def_id));
919+
}
920+
Some('t') => result.push(ty::TypeTraitItemId(def_id)),
929921
_ => panic!("unknown trait item sort"),
930922
}
931923
true
@@ -954,7 +946,7 @@ pub fn get_provided_trait_methods<'tcx>(intr: Rc<IdentInterner>,
954946
let did = item_def_id(mth_id, cdata);
955947
let mth = lookup_item(did.node, data);
956948

957-
if item_sort(mth) == 'p' {
949+
if item_sort(mth) == Some('p') {
958950
let trait_item = get_impl_or_trait_item(intr.clone(),
959951
cdata,
960952
did.node,
@@ -1558,6 +1550,6 @@ pub fn is_associated_type(cdata: Cmd, id: ast::NodeId) -> bool {
15581550
let items = reader::get_doc(rbml::Doc::new(cdata.data()), tag_items);
15591551
match maybe_find_item(id, items) {
15601552
None => false,
1561-
Some(item) => item_sort(item) == 't',
1553+
Some(item) => item_sort(item) == Some('t'),
15621554
}
15631555
}

src/librustc/metadata/encoder.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1217,7 +1217,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
12171217
encode_unsafety(rbml_w, unsafety);
12181218
encode_polarity(rbml_w, polarity);
12191219
match ty.node {
1220-
ast::TyPath(ref path, _) if path.segments.len() == 1 => {
1220+
ast::TyPath(None, ref path) if path.segments.len() == 1 => {
12211221
let ident = path.segments.last().unwrap().identifier;
12221222
encode_impl_type_basename(rbml_w, ident);
12231223
}
@@ -1237,9 +1237,8 @@ fn encode_info_for_item(ecx: &EncodeContext,
12371237
}
12381238
rbml_w.end_tag();
12391239
}
1240-
if let Some(ref ast_trait_ref) = *opt_trait {
1241-
let trait_ref = ty::node_id_to_trait_ref(
1242-
tcx, ast_trait_ref.ref_id);
1240+
if opt_trait.is_some() {
1241+
let trait_ref = ty::impl_id_to_trait_ref(tcx, item.id);
12431242
encode_trait_ref(rbml_w, ecx, &*trait_ref, tag_item_trait_ref);
12441243
}
12451244
encode_path(rbml_w, path.clone());
@@ -1909,9 +1908,7 @@ struct ImplVisitor<'a, 'b:'a, 'c:'a, 'tcx:'b> {
19091908
impl<'a, 'b, 'c, 'tcx, 'v> Visitor<'v> for ImplVisitor<'a, 'b, 'c, 'tcx> {
19101909
fn visit_item(&mut self, item: &ast::Item) {
19111910
if let ast::ItemImpl(_, _, _, Some(ref trait_ref), _, _) = item.node {
1912-
let def_map = &self.ecx.tcx.def_map;
1913-
let trait_def = def_map.borrow()[trait_ref.ref_id].clone();
1914-
let def_id = trait_def.def_id();
1911+
let def_id = self.ecx.tcx.def_map.borrow()[trait_ref.ref_id].def_id();
19151912

19161913
// Load eagerly if this is an implementation of the Drop trait
19171914
// or if the trait is not defined in this crate.

0 commit comments

Comments
 (0)