Skip to content

Fix a handful of minor default method bugs #8659

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

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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/librustc/middle/liveness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1617,7 +1617,7 @@ impl Liveness {

pub fn should_warn(&self, var: Variable) -> Option<@str> {
let name = self.ir.variable_name(var);
if name[0] == ('_' as u8) { None } else { Some(name) }
if name.len() == 0 || name[0] == ('_' as u8) { None } else { Some(name) }
}

pub fn warn_about_unused_args(&self, decl: &fn_decl, entry_ln: LiveNode) {
Expand Down
19 changes: 11 additions & 8 deletions src/librustc/middle/trans/meth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -577,20 +577,23 @@ fn emit_vtable_methods(bcx: @mut Block,

let trait_method_def_ids = ty::trait_method_def_ids(tcx, trt_id);
do trait_method_def_ids.map |method_def_id| {
let im = ty::method(tcx, *method_def_id);
let ident = ty::method(tcx, *method_def_id).ident;
// The substitutions we have are on the impl, so we grab
// the method type from the impl to substitute into.
let m_id = method_with_name(ccx, impl_id, ident);
let m = ty::method(tcx, m_id);
debug!("(making impl vtable) emitting method %s at subst %s",
m.repr(tcx),
substs.repr(tcx));
let fty = ty::subst_tps(tcx,
substs,
None,
ty::mk_bare_fn(tcx, im.fty.clone()));
if im.generics.has_type_params() || ty::type_has_self(fty) {
ty::mk_bare_fn(tcx, m.fty.clone()));
if m.generics.has_type_params() || ty::type_has_self(fty) {
debug!("(making impl vtable) method has self or type params: %s",
tcx.sess.str_of(im.ident));
tcx.sess.str_of(ident));
C_null(Type::nil().ptr_to())
} else {
debug!("(making impl vtable) adding method to vtable: %s",
tcx.sess.str_of(im.ident));
let m_id = method_with_name(ccx, impl_id, im.ident);

trans_fn_ref_with_vtables(bcx, m_id, 0,
substs, Some(vtables)).llfn
}
Expand Down
15 changes: 12 additions & 3 deletions src/librustc/middle/typeck/check/method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -938,9 +938,18 @@ impl<'self> LookupContext<'self> {

// static methods should never have gotten this far:
assert!(candidate.method_ty.explicit_self != sty_static);
let transformed_self_ty =
ty::subst(tcx, &candidate.rcvr_substs,
candidate.method_ty.transformed_self_ty.unwrap());

let transformed_self_ty = match candidate.origin {
method_object(*) => {
// For annoying reasons, we've already handled the
// substitution for object calls.
candidate.method_ty.transformed_self_ty.unwrap()
}
_ => {
ty::subst(tcx, &candidate.rcvr_substs,
candidate.method_ty.transformed_self_ty.unwrap())
}
};

// Determine the values for the type parameters of the method.
// If they were not explicitly supplied, just construct fresh
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/middle/typeck/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3092,7 +3092,6 @@ pub fn ty_param_bounds_and_ty_for_def(fcx: @mut FnCtxt,
sp: span,
defn: ast::def)
-> ty_param_bounds_and_ty {

match defn {
ast::def_arg(nid, _) | ast::def_local(nid, _) | ast::def_self(nid, _) |
ast::def_binding(nid, _) => {
Expand Down Expand Up @@ -3149,7 +3148,8 @@ pub fn instantiate_path(fcx: @mut FnCtxt,
let ty_param_count = tpt.generics.type_param_defs.len();
let ty_substs_len = pth.types.len();

debug!("ty_param_count=%? ty_substs_len=%?",
debug!("tpt=%s ty_param_count=%? ty_substs_len=%?",
tpt.repr(fcx.tcx()),
ty_param_count,
ty_substs_len);

Expand Down
10 changes: 8 additions & 2 deletions src/librustc/middle/typeck/collect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -346,9 +346,10 @@ pub fn ensure_trait_methods(ccx: &CrateCtxt,
let substd_type_param_defs = m.generics.type_param_defs.subst(tcx, &substs);
new_type_param_defs.push_all(*substd_type_param_defs);

debug!("static method %s type_param_defs=%s substs=%s",
debug!("static method %s type_param_defs=%s ty=%s, substs=%s",
m.def_id.repr(tcx),
new_type_param_defs.repr(tcx),
ty.repr(tcx),
substs.repr(tcx));

tcx.tcache.insert(m.def_id,
Expand Down Expand Up @@ -893,8 +894,8 @@ pub fn convert(ccx: &CrateCtxt, it: &ast::item) {
}
ast::item_trait(ref generics, _, ref trait_methods) => {
let _trait_def = trait_def_of_item(ccx, it);
ensure_trait_methods(ccx, it.id);

// Run convert_methods on the provided methods.
let (_, provided_methods) =
split_trait_methods(*trait_methods);
let untransformed_rcvr_ty = ty::mk_self(tcx, local_def(it.id));
Expand All @@ -904,6 +905,11 @@ pub fn convert(ccx: &CrateCtxt, it: &ast::item) {
untransformed_rcvr_ty,
&ty_generics, generics,
it.vis);

// We need to do this *after* converting methods, since
// convert_methods produces a tcache entry that is wrong for
// static trait methods. This is somewhat unfortunate.
ensure_trait_methods(ccx, it.id);
}
ast::item_struct(struct_def, ref generics) => {
ensure_no_ty_param_bounds(ccx, it.span, generics, "structure");
Expand Down
1 change: 1 addition & 0 deletions src/librustpkg/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -678,6 +678,7 @@ fn rustpkg_local_pkg() {
}
#[test]
#[ignore (reason = "test makes bogus assumptions about build directory layout: issue #8690")]
fn package_script_with_default_build() {
let dir = create_local_package(&PkgId::new("fancy-lib"));
debug!("dir = %s", dir.to_str());
Expand Down
16 changes: 11 additions & 5 deletions src/libsyntax/ast_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,12 +238,18 @@ impl Visitor<()> for Ctx {
self.map.insert(p.ref_id, node_item(i, item_path));
}
for tm in methods.iter() {
let id = ast_util::trait_method_to_ty_method(tm).id;
let ext = { self.extend(i.ident) };
let d_id = ast_util::local_def(i.id);
self.map.insert(id,
node_trait_method(@(*tm).clone(),
d_id,
item_path));
match *tm {
required(ref m) => {
let entry =
node_trait_method(@(*tm).clone(), d_id, ext);
self.map.insert(m.id, entry);
}
provided(m) => {
self.map_method(d_id, ext, m, true);
}
}
}
}
_ => {}
Expand Down
46 changes: 46 additions & 0 deletions src/test/run-pass/trait-object-generics.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// test for #8664

pub trait Trait2<A> {
fn doit(&self);
}

pub struct Impl<A1, A2, A3> {
/*
* With A2 we get the ICE:
* task <unnamed> failed at 'index out of bounds: the len is 1 but the index is 1', /home/tortue/rust_compiler_newest/src/librustc/middle/subst.rs:58
*/
t: ~Trait2<A2>
}

impl<A1, A2, A3> Impl<A1, A2, A3> {
pub fn step(&self) {
self.t.doit()
}
}

// test for #8601

enum Type<T> { Constant }

trait Trait<K,V> {
fn method(&self,Type<(K,V)>) -> int;
}

impl<V> Trait<u8,V> for () {
fn method(&self, _x: Type<(u8,V)>) -> int { 0 }
}

fn main () {
let a = @() as @Trait<u8, u8>;
assert_eq!(a.method(Constant), 0);
}