Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Partial implementation for UFCS trait-less associated paths. #22172

Merged
merged 27 commits into from
Feb 24, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
949d1ff
Add cfgs to `liblibc` for NaCl targets.
DiamondLovesYou Feb 17, 2015
0ef56da
Auto merge of #21581 - DiamondLovesYou:nacl-libc, r=alexcrichton
bors Feb 24, 2015
dccdde4
Auto merge of #22755 - Manishearth:rollup, r=Manishearth
bors Feb 24, 2015
27747ac
Revert bogus rename from DefTrait to DefaultImpl.
eddyb Feb 24, 2015
a817c69
syntax: don't store a secondary NodeId for TyPath.
eddyb Jan 29, 2015
004df41
syntax: don't use TraitRef in QPath.
eddyb Jan 30, 2015
9739ae4
rustc: remove unused ForeignType item family.
eddyb Jan 30, 2015
9a69378
rustc: load DefAssociatedTy from cross-crate metadata. Fixes #20542.
eddyb Jan 30, 2015
326711e
rustc_resolve: use DefAssociatedTy for TyQPath.
eddyb Jan 31, 2015
ffb8092
syntax: use a single Path for Trait::Item in QPath.
eddyb Jan 31, 2015
5809f8a
rustc_resolve: use the visitor model more, remove redundant repeated …
eddyb Feb 5, 2015
0f49254
rustc: use partially resolved definitions to replace the `T::A` hack.
eddyb Feb 5, 2015
7a3054f
rustc_resolve: remove the distinction between DefStaticMethod and Def…
eddyb Feb 11, 2015
fe4f9b8
Use partial path resolutions in expressions for UFCS desugaring.
eddyb Feb 11, 2015
6700166
core: fix typo that wasn't caught by the hacky previous implementation.
eddyb Feb 11, 2015
06f362a
rustc_resolve: don't handle impl items as if they were modules.
eddyb Feb 20, 2015
5a6a9ed
rustc: combine partial_def_map and last_private_map into def_map.
eddyb Feb 17, 2015
fdfb532
tests: remove warnings from and rename const-polymorphic-paths to ufc…
eddyb Feb 17, 2015
d31b9eb
Implement `<T>::method` UFCS expression syntax.
eddyb Feb 17, 2015
09ad993
tests: add two new run-pass tests for method behavior after UFCS.
eddyb Feb 19, 2015
923616e
Fix @nikomatsakis' nits in typeck.
eddyb Feb 20, 2015
866a5ee
Fix fallout from correct stability handling in UFCS.
eddyb Feb 19, 2015
9ac0736
Fix fallout from allowing impls outside of the type's definition module.
eddyb Feb 20, 2015
f0efa2d
Update trans/save's span hacks for fully qualified UFCS paths.
eddyb Feb 20, 2015
8501c9d
rustc_typeck: unify the impl type with the UFCS path prefix type.
eddyb Feb 23, 2015
72d5f39
Fix fallout from rebasing.
eddyb Feb 24, 2015
0c6d1f3
syntax: update pretty-printer for the `<T>::method` shorthand.
eddyb Feb 24, 2015
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/libcollections/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -790,7 +790,7 @@ pub trait SliceExt {
fn ends_with(&self, needle: &[Self::Item]) -> bool where Self::Item: PartialEq;

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

Expand Down
2 changes: 1 addition & 1 deletion src/libcore/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -981,7 +981,7 @@ pub trait IteratorExt: Iterator + Sized {
#[unstable(feature = "core", reason = "recent addition")]
fn cloned(self) -> Cloned<Self> where
Self::Item: Deref,
<Self::Item as Deref>::Output: Clone,
<Self::Item as Deref>::Target: Clone,
{
Cloned { it: self }
}
Expand Down
479 changes: 241 additions & 238 deletions src/liblibc/lib.rs

Large diffs are not rendered by default.

38 changes: 19 additions & 19 deletions src/librustc/lint/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -405,8 +405,8 @@ struct ImproperCTypesVisitor<'a, 'tcx: 'a> {
}

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

impl<'a, 'tcx, 'v> Visitor<'v> for ImproperCTypesVisitor<'a, 'tcx> {
fn visit_ty(&mut self, ty: &ast::Ty) {
match ty.node {
ast::TyPath(_, id) => self.check_def(ty.span, ty.id, id),
_ => (),
if let ast::TyPath(..) = ty.node {
self.check_def(ty.span, ty.id);
}
visit::walk_ty(self, ty);
}
Expand Down Expand Up @@ -683,8 +682,8 @@ impl LintPass for PathStatements {
match s.node {
ast::StmtSemi(ref expr, _) => {
match expr.node {
ast::ExprPath(_) => cx.span_lint(PATH_STATEMENTS, s.span,
"path statement with no effect"),
ast::ExprPath(..) => cx.span_lint(PATH_STATEMENTS, s.span,
"path statement with no effect"),
_ => ()
}
}
Expand Down Expand Up @@ -1001,7 +1000,8 @@ impl LintPass for NonSnakeCase {

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

fn check_pat(&mut self, cx: &Context, p: &ast::Pat) {
// Lint for constants that look like binding identifiers (#7526)
match (&p.node, cx.tcx.def_map.borrow().get(&p.id)) {
(&ast::PatIdent(_, ref path1, _), Some(&def::DefConst(..))) => {
match (&p.node, cx.tcx.def_map.borrow().get(&p.id).map(|d| d.full_def())) {
(&ast::PatIdent(_, ref path1, _), Some(def::DefConst(..))) => {
NonUpperCaseGlobals::check_upper_case(cx, "constant in pattern",
path1.node, p.span);
}
Expand Down Expand Up @@ -1227,10 +1227,13 @@ impl LintPass for NonShorthandFieldPatterns {
fn check_pat(&mut self, cx: &Context, pat: &ast::Pat) {
let def_map = cx.tcx.def_map.borrow();
if let ast::PatStruct(_, ref v, _) = pat.node {
for fieldpat in v.iter()
.filter(|fieldpat| !fieldpat.node.is_shorthand)
.filter(|fieldpat| def_map.get(&fieldpat.node.pat.id)
== Some(&def::DefLocal(fieldpat.node.pat.id))) {
let field_pats = v.iter()
.filter(|fieldpat| !fieldpat.node.is_shorthand)
.filter(|fieldpat| {
let def = def_map.get(&fieldpat.node.pat.id).map(|d| d.full_def());
def == Some(def::DefLocal(fieldpat.node.pat.id))
});
for fieldpat in field_pats {
if let ast::PatIdent(_, ident, None) = fieldpat.node.pat.node {
if ident.node.as_str() == fieldpat.node.ident.as_str() {
cx.span_lint(NON_SHORTHAND_FIELD_PATTERNS, fieldpat.span,
Expand Down Expand Up @@ -1909,10 +1912,7 @@ impl LintPass for UnconditionalRecursion {
_: ast::Ident,
id: ast::NodeId) -> bool {
tcx.def_map.borrow().get(&id)
.map_or(false, |def| {
let did = def.def_id();
ast_util::is_local(did) && did.node == fn_id
})
.map_or(false, |def| def.def_id() == ast_util::local_def(fn_id))
}

// check if the method call `id` refers to method `method_id`
Expand Down
7 changes: 2 additions & 5 deletions src/librustc/metadata/csearch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,12 +150,9 @@ pub fn get_trait_name(cstore: &cstore::CStore, def: ast::DefId) -> ast::Name {
def.node)
}

pub fn get_trait_item_name_and_kind(cstore: &cstore::CStore, def: ast::DefId)
-> (ast::Name, def::TraitItemKind) {
pub fn is_static_method(cstore: &cstore::CStore, def: ast::DefId) -> bool {
let cdata = cstore.get_crate_data(def.krate);
decoder::get_trait_item_name_and_kind(cstore.intr.clone(),
&*cdata,
def.node)
decoder::is_static_method(&*cdata, def.node)
}

pub fn get_trait_item_def_ids(cstore: &cstore::CStore, def: ast::DefId)
Expand Down
62 changes: 27 additions & 35 deletions src/librustc/metadata/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,6 @@ enum Family {
StaticMethod, // F
Method, // h
Type, // y
ForeignType, // T
Mod, // m
ForeignMod, // n
Enum, // t
Expand All @@ -145,7 +144,6 @@ fn item_family(item: rbml::Doc) -> Family {
'F' => StaticMethod,
'h' => Method,
'y' => Type,
'T' => ForeignType,
'm' => Mod,
'n' => ForeignMod,
't' => Enum,
Expand Down Expand Up @@ -174,16 +172,13 @@ fn item_visibility(item: rbml::Doc) -> ast::Visibility {
}
}

fn item_sort(item: rbml::Doc) -> char {
fn item_sort(item: rbml::Doc) -> Option<char> {
let mut ret = None;
reader::tagged_docs(item, tag_item_trait_item_sort, |doc| {
ret = Some(doc.as_str_slice().as_bytes()[0] as char);
false
});
match ret {
Some(r) => r,
None => panic!("No item_sort found")
}
ret
}

fn item_symbol(item: rbml::Doc) -> String {
Expand Down Expand Up @@ -339,14 +334,16 @@ fn item_to_def_like(item: rbml::Doc, did: ast::DefId, cnum: ast::CrateNum)
def::FromImpl(item_reqd_and_translated_parent_item(cnum,
item))
};
match fam {
// We don't bother to get encode/decode the trait id, we don't need it.
Method => DlDef(def::DefMethod(did, None, provenance)),
StaticMethod => DlDef(def::DefStaticMethod(did, provenance)),
_ => panic!()
DlDef(def::DefMethod(did, provenance))
}
Type => {
if item_sort(item) == Some('t') {
let trait_did = item_reqd_and_translated_parent_item(cnum, item);
DlDef(def::DefAssociatedTy(trait_did, did))
} else {
DlDef(def::DefTy(did, false))
}
}
Type | ForeignType => DlDef(def::DefTy(did, false)),
Mod => DlDef(def::DefMod(did)),
ForeignMod => DlDef(def::DefForeignMod(did)),
StructVariant => {
Expand All @@ -357,7 +354,7 @@ fn item_to_def_like(item: rbml::Doc, did: ast::DefId, cnum: ast::CrateNum)
let enum_did = item_reqd_and_translated_parent_item(cnum, item);
DlDef(def::DefVariant(enum_did, did, false))
}
Trait => DlDef(def::DefaultImpl(did)),
Trait => DlDef(def::DefTrait(did)),
Enum => DlDef(def::DefTy(did, true)),
Impl | DefaultImpl => DlImpl(did),
PublicField | InheritedField => DlField,
Expand Down Expand Up @@ -831,8 +828,10 @@ pub fn get_impl_items(cdata: Cmd, impl_id: ast::NodeId)
tag_item_impl_item, |doc| {
let def_id = item_def_id(doc, cdata);
match item_sort(doc) {
'r' | 'p' => impl_items.push(ty::MethodTraitItemId(def_id)),
't' => impl_items.push(ty::TypeTraitItemId(def_id)),
Some('r') | Some('p') => {
impl_items.push(ty::MethodTraitItemId(def_id))
}
Some('t') => impl_items.push(ty::TypeTraitItemId(def_id)),
_ => panic!("unknown impl item sort"),
}
true
Expand All @@ -849,22 +848,13 @@ pub fn get_trait_name(intr: Rc<IdentInterner>,
item_name(&*intr, doc)
}

pub fn get_trait_item_name_and_kind(intr: Rc<IdentInterner>,
cdata: Cmd,
id: ast::NodeId)
-> (ast::Name, def::TraitItemKind) {
pub fn is_static_method(cdata: Cmd, id: ast::NodeId) -> bool {
let doc = lookup_item(id, cdata.data());
let name = item_name(&*intr, doc);
match item_sort(doc) {
'r' | 'p' => {
let explicit_self = get_explicit_self(doc);
(name, def::TraitItemKind::from_explicit_self_category(explicit_self))
}
't' => (name, def::TypeTraitItemKind),
c => {
panic!("get_trait_item_name_and_kind(): unknown trait item kind \
in metadata: `{}`", c)
Some('r') | Some('p') => {
get_explicit_self(doc) == ty::StaticExplicitSelfCategory
}
_ => false
}
}

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

match item_sort(method_doc) {
'r' | 'p' => {
Some('r') | Some('p') => {
let generics = doc_generics(method_doc, tcx, cdata, tag_method_ty_generics);
let predicates = doc_predicates(method_doc, tcx, cdata, tag_method_ty_generics);
let fty = doc_method_fty(method_doc, tcx, cdata);
Expand All @@ -906,7 +896,7 @@ pub fn get_impl_or_trait_item<'tcx>(intr: Rc<IdentInterner>,
container,
provided_source)))
}
't' => {
Some('t') => {
ty::TypeTraitItem(Rc::new(ty::AssociatedType {
name: name,
vis: vis,
Expand All @@ -926,8 +916,10 @@ pub fn get_trait_item_def_ids(cdata: Cmd, id: ast::NodeId)
reader::tagged_docs(item, tag_item_trait_item, |mth| {
let def_id = item_def_id(mth, cdata);
match item_sort(mth) {
'r' | 'p' => result.push(ty::MethodTraitItemId(def_id)),
't' => result.push(ty::TypeTraitItemId(def_id)),
Some('r') | Some('p') => {
result.push(ty::MethodTraitItemId(def_id));
}
Some('t') => result.push(ty::TypeTraitItemId(def_id)),
_ => panic!("unknown trait item sort"),
}
true
Expand Down Expand Up @@ -956,7 +948,7 @@ pub fn get_provided_trait_methods<'tcx>(intr: Rc<IdentInterner>,
let did = item_def_id(mth_id, cdata);
let mth = lookup_item(did.node, data);

if item_sort(mth) == 'p' {
if item_sort(mth) == Some('p') {
let trait_item = get_impl_or_trait_item(intr.clone(),
cdata,
did.node,
Expand Down Expand Up @@ -1560,7 +1552,7 @@ pub fn is_associated_type(cdata: Cmd, id: ast::NodeId) -> bool {
let items = reader::get_doc(rbml::Doc::new(cdata.data()), tag_items);
match maybe_find_item(id, items) {
None => false,
Some(item) => item_sort(item) == 't',
Some(item) => item_sort(item) == Some('t'),
}
}

Expand Down
15 changes: 6 additions & 9 deletions src/librustc/metadata/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1193,15 +1193,15 @@ fn encode_info_for_item(ecx: &EncodeContext,
None => {}
}
}
ast::ItemDefaultImpl(unsafety, ref ast_trait_ref) => {
ast::ItemDefaultImpl(unsafety, _) => {
add_to_index(item, rbml_w, index);
rbml_w.start_tag(tag_items_data_item);
encode_def_id(rbml_w, def_id);
encode_family(rbml_w, 'd');
encode_name(rbml_w, item.ident.name);
encode_unsafety(rbml_w, unsafety);

let trait_ref = ty::node_id_to_trait_ref(tcx, ast_trait_ref.ref_id);
let trait_ref = ty::impl_id_to_trait_ref(tcx, item.id);
encode_trait_ref(rbml_w, ecx, &*trait_ref, tag_item_trait_ref);
rbml_w.end_tag();
}
Expand All @@ -1221,7 +1221,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
encode_unsafety(rbml_w, unsafety);
encode_polarity(rbml_w, polarity);
match ty.node {
ast::TyPath(ref path, _) if path.segments.len() == 1 => {
ast::TyPath(None, ref path) if path.segments.len() == 1 => {
let ident = path.segments.last().unwrap().identifier;
encode_impl_type_basename(rbml_w, ident);
}
Expand All @@ -1241,9 +1241,8 @@ fn encode_info_for_item(ecx: &EncodeContext,
}
rbml_w.end_tag();
}
if let Some(ref ast_trait_ref) = *opt_trait {
let trait_ref = ty::node_id_to_trait_ref(
tcx, ast_trait_ref.ref_id);
if opt_trait.is_some() {
let trait_ref = ty::impl_id_to_trait_ref(tcx, item.id);
encode_trait_ref(rbml_w, ecx, &*trait_ref, tag_item_trait_ref);
}
encode_path(rbml_w, path.clone());
Expand Down Expand Up @@ -1871,9 +1870,7 @@ struct ImplVisitor<'a, 'b:'a, 'c:'a, 'tcx:'b> {
impl<'a, 'b, 'c, 'tcx, 'v> Visitor<'v> for ImplVisitor<'a, 'b, 'c, 'tcx> {
fn visit_item(&mut self, item: &ast::Item) {
if let ast::ItemImpl(_, _, _, Some(ref trait_ref), _, _) = item.node {
let def_map = &self.ecx.tcx.def_map;
let trait_def = def_map.borrow()[trait_ref.ref_id].clone();
let def_id = trait_def.def_id();
let def_id = self.ecx.tcx.def_map.borrow()[trait_ref.ref_id].def_id();

// Load eagerly if this is an implementation of the Drop trait
// or if the trait is not defined in this crate.
Expand Down
Loading