Skip to content

Commit

Permalink
auto merge of #15585 : bgamari/rust/subst-bug, r=pnkfelix
Browse files Browse the repository at this point in the history
This branch has a fix for #15557 (a2bcef9) as well as a variety of patches I found useful while debugging this issue. These include adding `Show` impls to a variety of types, including the majority of `syntax::ast` and some of `middle::ty`.
  • Loading branch information
bors committed Jul 16, 2014
2 parents afbcbbc + 446f937 commit c523d86
Show file tree
Hide file tree
Showing 11 changed files with 181 additions and 108 deletions.
4 changes: 2 additions & 2 deletions src/librustc/middle/def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use syntax::ast_util::local_def;

use std::gc::Gc;

#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
pub enum Def {
DefFn(ast::DefId, ast::FnStyle),
DefStaticMethod(/* method */ ast::DefId, MethodProvenance, ast::FnStyle),
Expand Down Expand Up @@ -51,7 +51,7 @@ pub enum Def {
DefMethod(ast::DefId /* method */, Option<ast::DefId> /* trait */),
}

#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
pub enum MethodProvenance {
FromTrait(ast::DefId),
FromImpl(ast::DefId),
Expand Down
5 changes: 3 additions & 2 deletions src/librustc/middle/kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@ fn check_struct_safe_for_destructor(cx: &mut Context,
span: Span,
struct_did: DefId) {
let struct_tpt = ty::lookup_item_type(cx.tcx, struct_did);
if !struct_tpt.generics.has_type_params(subst::TypeSpace) {
if !struct_tpt.generics.has_type_params(subst::TypeSpace)
&& !struct_tpt.generics.has_region_params(subst::TypeSpace) {
let struct_ty = ty::mk_struct(cx.tcx, struct_did,
subst::Substs::empty());
if !ty::type_is_sendable(cx.tcx, struct_ty) {
Expand Down Expand Up @@ -121,7 +122,7 @@ fn check_impl_of_trait(cx: &mut Context, it: &Item, trait_ref: &TraitRef, self_t

// If this trait has builtin-kind supertraits, meet them.
let self_ty: ty::t = ty::node_id_to_type(cx.tcx, it.id);
debug!("checking impl with self type {:?}", ty::get(self_ty).sty);
debug!("checking impl with self type {}", ty::get(self_ty).sty);
check_builtin_bounds(cx, self_ty, trait_def.bounds, |missing| {
cx.tcx.sess.span_err(self_type.span,
format!("the type `{}', which does not fulfill `{}`, cannot implement this \
Expand Down
32 changes: 28 additions & 4 deletions src/librustc/middle/subst.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use middle::ty_fold;
use middle::ty_fold::{TypeFoldable, TypeFolder};
use util::ppaux::Repr;

use std::fmt;
use std::mem;
use std::raw;
use std::slice::{Items, MutItems};
Expand Down Expand Up @@ -83,7 +84,7 @@ impl<T> HomogeneousTuple3<T> for (T, T, T) {
* space* (which indices where the parameter is defined; see
* `ParamSpace`).
*/
#[deriving(Clone, PartialEq, Eq, Hash)]
#[deriving(Clone, PartialEq, Eq, Hash, Show)]
pub struct Substs {
pub types: VecPerParamSpace<ty::t>,
pub regions: RegionSubsts,
Expand All @@ -93,7 +94,7 @@ pub struct Substs {
* Represents the values to use when substituting lifetime parameters.
* If the value is `ErasedRegions`, then this subst is occurring during
* trans, and all region parameters will be replaced with `ty::ReStatic`. */
#[deriving(Clone, PartialEq, Eq, Hash)]
#[deriving(Clone, PartialEq, Eq, Hash, Show)]
pub enum RegionSubsts {
ErasedRegions,
NonerasedRegions(VecPerParamSpace<ty::Region>)
Expand Down Expand Up @@ -275,6 +276,17 @@ pub struct VecPerParamSpace<T> {
content: Vec<T>,
}

impl<T:fmt::Show> fmt::Show for VecPerParamSpace<T> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
try!(write!(fmt, "VecPerParamSpace {{"));
for space in ParamSpace::all().iter() {
try!(write!(fmt, "{}: {}, ", *space, self.get_slice(*space)));
}
try!(write!(fmt, "}}"));
Ok(())
}
}

impl<T:Clone> VecPerParamSpace<T> {
pub fn push_all(&mut self, space: ParamSpace, values: &[T]) {
// FIXME (#15435): slow; O(n^2); could enhance vec to make it O(n).
Expand Down Expand Up @@ -558,10 +570,22 @@ impl<'a> TypeFolder for SubstFolder<'a> {
// the specialized routine
// `middle::typeck::check::regionmanip::replace_late_regions_in_fn_sig()`.
match r {
ty::ReEarlyBound(_, space, i, _) => {
ty::ReEarlyBound(_, space, i, region_name) => {
match self.substs.regions {
ErasedRegions => ty::ReStatic,
NonerasedRegions(ref regions) => *regions.get(space, i),
NonerasedRegions(ref regions) =>
match regions.opt_get(space, i) {
Some(t) => *t,
None => {
let span = self.span.unwrap_or(DUMMY_SP);
self.tcx().sess.span_bug(
span,
format!("Type parameter out of range \
when substituting in region {} (root type={})",
region_name.as_str(),
self.root_ty.repr(self.tcx())).as_slice());
}
}
}
}
_ => r
Expand Down
31 changes: 18 additions & 13 deletions src/librustc/middle/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ impl Method {
}
}

#[deriving(Clone, PartialEq, Eq, Hash)]
#[deriving(Clone, PartialEq, Eq, Hash, Show)]
pub struct mt {
pub ty: t,
pub mutbl: ast::Mutability,
Expand All @@ -138,7 +138,7 @@ pub enum TraitStore {
RegionTraitStore(Region, ast::Mutability),
}

#[deriving(Clone)]
#[deriving(Clone, Show)]
pub struct field_ty {
pub name: Name,
pub id: DefId,
Expand Down Expand Up @@ -394,6 +394,7 @@ pub enum tbox_flag {

pub type t_box = &'static t_box_;

#[deriving(Show)]
pub struct t_box_ {
pub sty: sty,
pub id: uint,
Expand Down Expand Up @@ -436,14 +437,14 @@ pub fn type_needs_infer(t: t) -> bool {
}
pub fn type_id(t: t) -> uint { get(t).id }

#[deriving(Clone, PartialEq, Eq, Hash)]
#[deriving(Clone, PartialEq, Eq, Hash, Show)]
pub struct BareFnTy {
pub fn_style: ast::FnStyle,
pub abi: abi::Abi,
pub sig: FnSig,
}

#[deriving(Clone, PartialEq, Eq, Hash)]
#[deriving(Clone, PartialEq, Eq, Hash, Show)]
pub struct ClosureTy {
pub fn_style: ast::FnStyle,
pub onceness: ast::Onceness,
Expand Down Expand Up @@ -472,7 +473,7 @@ pub struct FnSig {
pub variadic: bool
}

#[deriving(Clone, PartialEq, Eq, Hash)]
#[deriving(Clone, PartialEq, Eq, Hash, Show)]
pub struct ParamTy {
pub space: subst::ParamSpace,
pub idx: uint,
Expand Down Expand Up @@ -712,7 +713,7 @@ mod primitives {

// NB: If you change this, you'll probably want to change the corresponding
// AST structure in libsyntax/ast.rs as well.
#[deriving(Clone, PartialEq, Eq, Hash)]
#[deriving(Clone, PartialEq, Eq, Hash, Show)]
pub enum sty {
ty_nil,
ty_bot,
Expand Down Expand Up @@ -741,14 +742,14 @@ pub enum sty {
// on non-useful type error messages)
}

#[deriving(Clone, PartialEq, Eq, Hash)]
#[deriving(Clone, PartialEq, Eq, Hash, Show)]
pub struct TyTrait {
pub def_id: DefId,
pub substs: Substs,
pub bounds: BuiltinBounds
}

#[deriving(PartialEq, Eq, Hash)]
#[deriving(PartialEq, Eq, Hash, Show)]
pub struct TraitRef {
pub def_id: DefId,
pub substs: Substs,
Expand Down Expand Up @@ -808,7 +809,7 @@ pub enum type_err {
terr_variadic_mismatch(expected_found<bool>)
}

#[deriving(PartialEq, Eq, Hash)]
#[deriving(PartialEq, Eq, Hash, Show)]
pub struct ParamBounds {
pub builtin_bounds: BuiltinBounds,
pub trait_bounds: Vec<Rc<TraitRef>>
Expand Down Expand Up @@ -948,7 +949,7 @@ impl fmt::Show for IntVarValue {
}
}

#[deriving(Clone)]
#[deriving(Clone, Show)]
pub struct TypeParameterDef {
pub ident: ast::Ident,
pub def_id: ast::DefId,
Expand All @@ -958,7 +959,7 @@ pub struct TypeParameterDef {
pub default: Option<ty::t>
}

#[deriving(Encodable, Decodable, Clone)]
#[deriving(Encodable, Decodable, Clone, Show)]
pub struct RegionParameterDef {
pub name: ast::Name,
pub def_id: ast::DefId,
Expand All @@ -968,7 +969,7 @@ pub struct RegionParameterDef {

/// Information about the type/lifetime parameters associated with an
/// item or method. Analogous to ast::Generics.
#[deriving(Clone)]
#[deriving(Clone, Show)]
pub struct Generics {
pub types: VecPerParamSpace<TypeParameterDef>,
pub regions: VecPerParamSpace<RegionParameterDef>,
Expand All @@ -983,6 +984,10 @@ impl Generics {
pub fn has_type_params(&self, space: subst::ParamSpace) -> bool {
!self.types.is_empty_in(space)
}

pub fn has_region_params(&self, space: subst::ParamSpace) -> bool {
!self.regions.is_empty_in(space)
}
}

/// When type checking, we use the `ParameterEnvironment` to track
Expand Down Expand Up @@ -1014,7 +1019,7 @@ pub struct ParameterEnvironment {
/// - `generics`: the set of type parameters and their bounds
/// - `ty`: the base types, which may reference the parameters defined
/// in `generics`
#[deriving(Clone)]
#[deriving(Clone, Show)]
pub struct Polytype {
pub generics: Generics,
pub ty: t
Expand Down
5 changes: 3 additions & 2 deletions src/librustc/middle/typeck/astconv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ pub fn opt_ast_region_to_region<AC:AstConv,RS:RegionScope>(
}
};

debug!("opt_ast_region_to_region(opt_lifetime={:?}) yields {}",
debug!("opt_ast_region_to_region(opt_lifetime={}) yields {}",
opt_lifetime.as_ref().map(|e| lifetime_to_string(e)),
r.repr(this.tcx()));

Expand Down Expand Up @@ -504,6 +504,7 @@ pub fn ast_ty_to_builtin_ty<AC:AstConv,
}
}

#[deriving(Show)]
enum PointerTy {
Box,
RPtr(ty::Region),
Expand Down Expand Up @@ -565,7 +566,7 @@ fn mk_pointer<AC:AstConv,
constr: |ty::t| -> ty::t)
-> ty::t {
let tcx = this.tcx();
debug!("mk_pointer(ptr_ty={:?})", ptr_ty);
debug!("mk_pointer(ptr_ty={})", ptr_ty);

match a_seq_ty.ty.node {
ast::TyVec(ref ty) => {
Expand Down
22 changes: 14 additions & 8 deletions src/librustc/middle/typeck/check/_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -507,14 +507,20 @@ pub fn check_pat(pcx: &pat_ctxt, pat: &ast::Pat, expected: ty::t) {
ty::ty_struct(cid, ref substs) => {
// Verify that the pattern named the right structure.
let item_did = tcx.def_map.borrow().get(&pat.id).def_id();
let struct_did =
ty::ty_to_def_id(
ty::lookup_item_type(tcx, item_did).ty).unwrap();
if struct_did != cid {
span_err!(tcx.sess, pat.span, E0032,
"`{}` does not name the structure `{}`",
pprust::path_to_string(path),
fcx.infcx().ty_to_string(expected));
match ty::ty_to_def_id(ty::lookup_item_type(tcx, item_did).ty) {
Some(struct_did) if struct_did != cid => {
span_err!(tcx.sess, path.span, E0032,
"`{}` does not name the structure `{}`",
pprust::path_to_string(path),
fcx.infcx().ty_to_string(expected));
},
Some(_) => {},
None => {
tcx.sess.span_bug(
path.span,
format!("This shouldn't happen: failed to lookup structure. \
item_did = {}", item_did).as_slice())
},
}

check_struct_pat(pcx, pat.id, pat.span, expected, path,
Expand Down
13 changes: 7 additions & 6 deletions src/librustc/middle/typeck/collect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1018,16 +1018,17 @@ fn ty_generics(ccx: &CrateCtxt,
let mut result = base_generics;

for (i, l) in lifetimes.iter().enumerate() {
result.regions.push(space,
ty::RegionParameterDef { name: l.name,
space: space,
index: i,
def_id: local_def(l.id) });
let def = ty::RegionParameterDef { name: l.name,
space: space,
index: i,
def_id: local_def(l.id) };
debug!("ty_generics: def for region param: {}", def);
result.regions.push(space, def);
}

for (i, param) in types.iter().enumerate() {
let def = get_or_create_type_parameter_def(ccx, space, param, i);
debug!("def for param: {}", def.repr(ccx.tcx));
debug!("ty_generics: def for type param: {}", def.repr(ccx.tcx));
result.types.push(space, def);
}

Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/typeck/infer/region_inference/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ impl<'a> RegionVarBindings<'a> {
if self.in_snapshot() {
self.undo_log.borrow_mut().push(AddVar(vid));
}
debug!("created new region variable {:?} with origin {:?}",
debug!("created new region variable {} with origin {}",
vid, origin.repr(self.tcx));
return vid;
}
Expand Down
Loading

0 comments on commit c523d86

Please sign in to comment.