Skip to content

Commit 0bd1565

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. It also fixes #22563 as `impl`s are no longer treated as modules in resolve. 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 c9ace05 + 0c6d1f3 commit 0bd1565

File tree

111 files changed

+2363
-2648
lines changed

Some content is hidden

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

111 files changed

+2363
-2648
lines changed

src/libcollections/slice.rs

+1-1
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

+1-1
Original file line numberDiff line numberDiff line change
@@ -981,7 +981,7 @@ pub trait IteratorExt: Iterator + Sized {
981981
#[unstable(feature = "core", reason = "recent addition")]
982982
fn cloned(self) -> Cloned<Self> where
983983
Self::Item: Deref,
984-
<Self::Item as Deref>::Output: Clone,
984+
<Self::Item as Deref>::Target: Clone,
985985
{
986986
Cloned { it: self }
987987
}

src/librustc/lint/builtin.rs

+19-19
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,
@@ -1909,10 +1912,7 @@ impl LintPass for UnconditionalRecursion {
19091912
_: ast::Ident,
19101913
id: ast::NodeId) -> bool {
19111914
tcx.def_map.borrow().get(&id)
1912-
.map_or(false, |def| {
1913-
let did = def.def_id();
1914-
ast_util::is_local(did) && did.node == fn_id
1915-
})
1915+
.map_or(false, |def| def.def_id() == ast_util::local_def(fn_id))
19161916
}
19171917

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

src/librustc/metadata/csearch.rs

+2-5
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

+27-35
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
@@ -145,7 +144,6 @@ fn item_family(item: rbml::Doc) -> Family {
145144
'F' => StaticMethod,
146145
'h' => Method,
147146
'y' => Type,
148-
'T' => ForeignType,
149147
'm' => Mod,
150148
'n' => ForeignMod,
151149
't' => Enum,
@@ -174,16 +172,13 @@ fn item_visibility(item: rbml::Doc) -> ast::Visibility {
174172
}
175173
}
176174

177-
fn item_sort(item: rbml::Doc) -> char {
175+
fn item_sort(item: rbml::Doc) -> Option<char> {
178176
let mut ret = None;
179177
reader::tagged_docs(item, tag_item_trait_item_sort, |doc| {
180178
ret = Some(doc.as_str_slice().as_bytes()[0] as char);
181179
false
182180
});
183-
match ret {
184-
Some(r) => r,
185-
None => panic!("No item_sort found")
186-
}
181+
ret
187182
}
188183

189184
fn item_symbol(item: rbml::Doc) -> String {
@@ -339,14 +334,16 @@ fn item_to_def_like(item: rbml::Doc, did: ast::DefId, cnum: ast::CrateNum)
339334
def::FromImpl(item_reqd_and_translated_parent_item(cnum,
340335
item))
341336
};
342-
match fam {
343-
// We don't bother to get encode/decode the trait id, we don't need it.
344-
Method => DlDef(def::DefMethod(did, None, provenance)),
345-
StaticMethod => DlDef(def::DefStaticMethod(did, provenance)),
346-
_ => panic!()
337+
DlDef(def::DefMethod(did, provenance))
338+
}
339+
Type => {
340+
if item_sort(item) == Some('t') {
341+
let trait_did = item_reqd_and_translated_parent_item(cnum, item);
342+
DlDef(def::DefAssociatedTy(trait_did, did))
343+
} else {
344+
DlDef(def::DefTy(did, false))
347345
}
348346
}
349-
Type | ForeignType => DlDef(def::DefTy(did, false)),
350347
Mod => DlDef(def::DefMod(did)),
351348
ForeignMod => DlDef(def::DefForeignMod(did)),
352349
StructVariant => {
@@ -357,7 +354,7 @@ fn item_to_def_like(item: rbml::Doc, did: ast::DefId, cnum: ast::CrateNum)
357354
let enum_did = item_reqd_and_translated_parent_item(cnum, item);
358355
DlDef(def::DefVariant(enum_did, did, false))
359356
}
360-
Trait => DlDef(def::DefaultImpl(did)),
357+
Trait => DlDef(def::DefTrait(did)),
361358
Enum => DlDef(def::DefTy(did, true)),
362359
Impl | DefaultImpl => DlImpl(did),
363360
PublicField | InheritedField => DlField,
@@ -831,8 +828,10 @@ pub fn get_impl_items(cdata: Cmd, impl_id: ast::NodeId)
831828
tag_item_impl_item, |doc| {
832829
let def_id = item_def_id(doc, cdata);
833830
match item_sort(doc) {
834-
'r' | 'p' => impl_items.push(ty::MethodTraitItemId(def_id)),
835-
't' => impl_items.push(ty::TypeTraitItemId(def_id)),
831+
Some('r') | Some('p') => {
832+
impl_items.push(ty::MethodTraitItemId(def_id))
833+
}
834+
Some('t') => impl_items.push(ty::TypeTraitItemId(def_id)),
836835
_ => panic!("unknown impl item sort"),
837836
}
838837
true
@@ -849,22 +848,13 @@ pub fn get_trait_name(intr: Rc<IdentInterner>,
849848
item_name(&*intr, doc)
850849
}
851850

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

@@ -889,7 +879,7 @@ pub fn get_impl_or_trait_item<'tcx>(intr: Rc<IdentInterner>,
889879
let vis = item_visibility(method_doc);
890880

891881
match item_sort(method_doc) {
892-
'r' | 'p' => {
882+
Some('r') | Some('p') => {
893883
let generics = doc_generics(method_doc, tcx, cdata, tag_method_ty_generics);
894884
let predicates = doc_predicates(method_doc, tcx, cdata, tag_method_ty_generics);
895885
let fty = doc_method_fty(method_doc, tcx, cdata);
@@ -906,7 +896,7 @@ pub fn get_impl_or_trait_item<'tcx>(intr: Rc<IdentInterner>,
906896
container,
907897
provided_source)))
908898
}
909-
't' => {
899+
Some('t') => {
910900
ty::TypeTraitItem(Rc::new(ty::AssociatedType {
911901
name: name,
912902
vis: vis,
@@ -926,8 +916,10 @@ pub fn get_trait_item_def_ids(cdata: Cmd, id: ast::NodeId)
926916
reader::tagged_docs(item, tag_item_trait_item, |mth| {
927917
let def_id = item_def_id(mth, cdata);
928918
match item_sort(mth) {
929-
'r' | 'p' => result.push(ty::MethodTraitItemId(def_id)),
930-
't' => result.push(ty::TypeTraitItemId(def_id)),
919+
Some('r') | Some('p') => {
920+
result.push(ty::MethodTraitItemId(def_id));
921+
}
922+
Some('t') => result.push(ty::TypeTraitItemId(def_id)),
931923
_ => panic!("unknown trait item sort"),
932924
}
933925
true
@@ -956,7 +948,7 @@ pub fn get_provided_trait_methods<'tcx>(intr: Rc<IdentInterner>,
956948
let did = item_def_id(mth_id, cdata);
957949
let mth = lookup_item(did.node, data);
958950

959-
if item_sort(mth) == 'p' {
951+
if item_sort(mth) == Some('p') {
960952
let trait_item = get_impl_or_trait_item(intr.clone(),
961953
cdata,
962954
did.node,
@@ -1560,7 +1552,7 @@ pub fn is_associated_type(cdata: Cmd, id: ast::NodeId) -> bool {
15601552
let items = reader::get_doc(rbml::Doc::new(cdata.data()), tag_items);
15611553
match maybe_find_item(id, items) {
15621554
None => false,
1563-
Some(item) => item_sort(item) == 't',
1555+
Some(item) => item_sort(item) == Some('t'),
15641556
}
15651557
}
15661558

src/librustc/metadata/encoder.rs

+6-9
Original file line numberDiff line numberDiff line change
@@ -1193,15 +1193,15 @@ fn encode_info_for_item(ecx: &EncodeContext,
11931193
None => {}
11941194
}
11951195
}
1196-
ast::ItemDefaultImpl(unsafety, ref ast_trait_ref) => {
1196+
ast::ItemDefaultImpl(unsafety, _) => {
11971197
add_to_index(item, rbml_w, index);
11981198
rbml_w.start_tag(tag_items_data_item);
11991199
encode_def_id(rbml_w, def_id);
12001200
encode_family(rbml_w, 'd');
12011201
encode_name(rbml_w, item.ident.name);
12021202
encode_unsafety(rbml_w, unsafety);
12031203

1204-
let trait_ref = ty::node_id_to_trait_ref(tcx, ast_trait_ref.ref_id);
1204+
let trait_ref = ty::impl_id_to_trait_ref(tcx, item.id);
12051205
encode_trait_ref(rbml_w, ecx, &*trait_ref, tag_item_trait_ref);
12061206
rbml_w.end_tag();
12071207
}
@@ -1221,7 +1221,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
12211221
encode_unsafety(rbml_w, unsafety);
12221222
encode_polarity(rbml_w, polarity);
12231223
match ty.node {
1224-
ast::TyPath(ref path, _) if path.segments.len() == 1 => {
1224+
ast::TyPath(None, ref path) if path.segments.len() == 1 => {
12251225
let ident = path.segments.last().unwrap().identifier;
12261226
encode_impl_type_basename(rbml_w, ident);
12271227
}
@@ -1241,9 +1241,8 @@ fn encode_info_for_item(ecx: &EncodeContext,
12411241
}
12421242
rbml_w.end_tag();
12431243
}
1244-
if let Some(ref ast_trait_ref) = *opt_trait {
1245-
let trait_ref = ty::node_id_to_trait_ref(
1246-
tcx, ast_trait_ref.ref_id);
1244+
if opt_trait.is_some() {
1245+
let trait_ref = ty::impl_id_to_trait_ref(tcx, item.id);
12471246
encode_trait_ref(rbml_w, ecx, &*trait_ref, tag_item_trait_ref);
12481247
}
12491248
encode_path(rbml_w, path.clone());
@@ -1871,9 +1870,7 @@ struct ImplVisitor<'a, 'b:'a, 'c:'a, 'tcx:'b> {
18711870
impl<'a, 'b, 'c, 'tcx, 'v> Visitor<'v> for ImplVisitor<'a, 'b, 'c, 'tcx> {
18721871
fn visit_item(&mut self, item: &ast::Item) {
18731872
if let ast::ItemImpl(_, _, _, Some(ref trait_ref), _, _) = item.node {
1874-
let def_map = &self.ecx.tcx.def_map;
1875-
let trait_def = def_map.borrow()[trait_ref.ref_id].clone();
1876-
let def_id = trait_def.def_id();
1873+
let def_id = self.ecx.tcx.def_map.borrow()[trait_ref.ref_id].def_id();
18771874

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

0 commit comments

Comments
 (0)