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

Issue 7331 #9841

Closed
wants to merge 3 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
30 changes: 21 additions & 9 deletions src/librustc/middle/typeck/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ use std::result;
use std::util::replace;
use std::vec;
use extra::list::Nil;
use extra::list;
use syntax::abi::AbiSet;
use syntax::ast::{provided, required};
use syntax::ast;
Expand Down Expand Up @@ -3342,19 +3343,30 @@ pub fn instantiate_path(fcx: @mut FnCtxt,
}
};

// Special case: If there is a self parameter, omit it from the list of
// type parameters.
//
// Here we calculate the "user type parameter count", which is the number
// of type parameters actually manifest in the AST. This will differ from
// the internal type parameter count when there are self types involved.
let (user_type_parameter_count, self_parameter_index) = match def {
// Special case for static trait methods: omit the self parameter
// from the list of type parameters and constrain the 'self
// lifetime to be equal to the enclosing 'self lifetime.
let (user_type_parameter_count, self_parameter_index, regions) = match def {
ast::DefStaticMethod(_, provenance @ ast::FromTrait(_), _) => {
let generics = generics_of_static_method_container(fcx.ccx.tcx,
provenance);
(ty_param_count - 1, Some(generics.type_param_defs.len()))

// If 'self is in scope, then use the free region it is already
// associated with. If 'self is not in scope then
// `regions` won't be used anyway.
let constrained_regions =
match list::find(fcx.in_scope_regions,
|&(br, _)| br == ty::br_self) {
Some((_, r)) => opt_vec::with(r),
None => regions
};

(ty_param_count - 1,
Some(generics.type_param_defs.len()),
constrained_regions)
}
_ => (ty_param_count, None),
_ => {
(ty_param_count, None, regions)}
};

// determine values for type parameters, using the values given by
Expand Down
28 changes: 28 additions & 0 deletions src/librustc/middle/typeck/check/vtable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ use std::result;
use syntax::ast;
use syntax::ast_util;
use syntax::codemap::Span;
use syntax::opt_vec;
use syntax::print::pprust::expr_to_str;
use syntax::visit;
use syntax::visit::Visitor;
Expand Down Expand Up @@ -295,6 +296,33 @@ fn lookup_vtable_from_bounds(vcx: &VtableContext,
bound_trait_ref.repr(vcx.tcx()));

if bound_trait_ref.def_id == trait_ref.def_id {

// Replace any instances of br_self with a new region
// variable in order to avoid asking region inference to
// relate a bound region to a free region. Strictly
// speaking, instead of a new region variable, we should
// use the free region associated with br_self, if it
// exists. However, bound_trait_ref does not play an
// important role in the main phase of region checking, so
// precisely what we choose here shouldn't matter.
let substs = ty::substs {
self_ty : None,
tps : ~[],
regions: ty::NonerasedRegions(opt_vec::with(
vcx.infcx.next_region_var(
infer::BoundRegionInTypeOrImpl(
location_info.span))))
};

let bound_trait_ref = @ty::TraitRef {
def_id : bound_trait_ref.def_id,
substs : ty::substs {
self_ty : bound_trait_ref.substs.self_ty.clone(),
tps : bound_trait_ref.substs.tps.clone(),
regions : bound_trait_ref.substs.regions.subst(vcx.ccx.tcx,
&substs)
}};

relate_trait_refs(vcx,
location_info,
bound_trait_ref,
Expand Down
6 changes: 3 additions & 3 deletions src/librustc/middle/typeck/collect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ pub fn ensure_trait_methods(ccx: &CrateCtxt,
// fn foo<D,E,F>(...) -> Self;
// }
//
// and we will create a function like
// then we will create a function like
//
// fn foo<A',B',C',D',E',F',G'>(...) -> D' {}
//
Expand Down Expand Up @@ -312,7 +312,7 @@ pub fn ensure_trait_methods(ccx: &CrateCtxt,
// Self => D'
// D,E,F => E',F',G'
let substs = substs {
regions: ty::NonerasedRegions(opt_vec::Empty),
regions: ty::NonerasedRegions(opt_vec::with(ty::re_bound(ty::br_self))),
self_ty: Some(self_param),
tps: non_shifted_trait_tps + shifted_method_tps
};
Expand Down Expand Up @@ -357,7 +357,7 @@ pub fn ensure_trait_methods(ccx: &CrateCtxt,
ty_param_bounds_and_ty {
generics: ty::Generics {
type_param_defs: @new_type_param_defs,
region_param: trait_ty_generics.region_param
region_param: None
},
ty: ty
});
Expand Down
31 changes: 31 additions & 0 deletions src/test/run-pass/issue-7331.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// 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.

pub trait Interner<'self, T> {
fn new() -> Self;
fn get(&'self self, tag: uint) -> Option<&'self T>;
}

pub trait FromVec<'self> {
fn fromVec(&'self [u8]) -> Self;
}

struct Reader<'self> {
v : &'self [u8]
}

impl <'self, T : FromVec<'self>> Reader<'self> {
fn get(&self) -> T {
FromVec::fromVec(self.v)
}
}


fn main() {}