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

Refactor QPath to take an ast::TraitRef #18868

Merged
Merged
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
63 changes: 4 additions & 59 deletions src/librustc/middle/resolve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -633,6 +633,7 @@ enum TraitReferenceType {
TraitDerivation, // trait T : SomeTrait { ... }
TraitBoundingTypeParameter, // fn f<T:SomeTrait>() { ... }
TraitObject, // Box<for<'a> SomeTrait>
TraitQPath, // <T as SomeTrait>::
}

impl NameBindings {
Expand Down Expand Up @@ -4532,6 +4533,7 @@ impl<'a> Resolver<'a> {
TraitImplementation => "implement",
TraitDerivation => "derive",
TraitObject => "reference",
TraitQPath => "extract an associated type from",
};

let msg = format!("attempt to {} a nonexistent trait `{}`", usage_str, path_str);
Expand Down Expand Up @@ -4969,65 +4971,8 @@ impl<'a> Resolver<'a> {
}

TyQPath(ref qpath) => {
self.resolve_type(&*qpath.for_type);

let current_module = self.current_module.clone();
let module_path: Vec<_> =
qpath.trait_name
.segments
.iter()
.map(|ps| ps.identifier.name)
.collect();
match self.resolve_module_path(
current_module,
module_path.as_slice(),
UseLexicalScope,
qpath.trait_name.span,
PathSearch) {
Success((ref module, _)) if module.kind.get() ==
TraitModuleKind => {
match self.resolve_definition_of_name_in_module(
(*module).clone(),
qpath.item_name.name,
TypeNS) {
ChildNameDefinition(def, lp) |
ImportNameDefinition(def, lp) => {
match def {
DefAssociatedTy(trait_type_id) => {
let def = DefAssociatedTy(
trait_type_id);
self.record_def(ty.id, (def, lp));
}
_ => {
self.resolve_error(
ty.span,
"not an associated type");
}
}
}
NoNameDefinition => {
self.resolve_error(ty.span,
"unresolved associated \
type");
}
}
}
Success(..) => self.resolve_error(ty.span, "not a trait"),
Indeterminate => {
self.session.span_bug(ty.span,
"indeterminate result when \
resolving associated type")
}
Failed(error) => {
let (span, help) = match error {
Some((span, msg)) => (span, format!("; {}", msg)),
None => (ty.span, String::new()),
};
self.resolve_error(span,
format!("unresolved trait: {}",
help).as_slice())
}
}
self.resolve_type(&*qpath.self_type);
self.resolve_trait_reference(ty.id, &*qpath.trait_ref, TraitQPath);
}

TyClosure(ref c) | TyProc(ref c) => {
Expand Down
4 changes: 4 additions & 0 deletions src/librustc/middle/subst.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,10 @@ impl<'tcx> Substs<'tcx> {
regions_is_noop && self.types.is_empty()
}

pub fn type_for_def(&self, ty_param_def: &ty::TypeParameterDef) -> Ty<'tcx> {
*self.types.get(ty_param_def.space, ty_param_def.index)
}

pub fn has_regions_escaping_depth(&self, depth: uint) -> bool {
self.types.iter().any(|&t| ty::type_escapes_depth(t, depth)) || {
match self.regions {
Expand Down
5 changes: 1 addition & 4 deletions src/librustc/middle/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ use std::rc::Rc;
use std::slice::Items;
use syntax::ast;
use syntax::codemap::{Span, DUMMY_SP};
use util::common::ErrorReported;

pub use self::fulfill::FulfillmentContext;
pub use self::select::SelectionContext;
Expand Down Expand Up @@ -95,10 +96,6 @@ pub enum ObligationCauseCode<'tcx> {
FieldSized,
}

// An error has already been reported to the user, so no need to continue checking.
#[deriving(Clone,Show)]
pub struct ErrorReported;

pub type Obligations<'tcx> = subst::VecPerParamSpace<Obligation<'tcx>>;

pub type Selection<'tcx> = Vtable<'tcx, Obligation<'tcx>>;
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/traits/select.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ use self::Candidate::*;
use self::BuiltinBoundConditions::*;
use self::EvaluationResult::*;

use super::{ErrorReported};
use super::{Obligation, ObligationCause};
use super::{SelectionError, Unimplemented, Overflow,
OutputTypeParameterMismatch};
Expand All @@ -38,6 +37,7 @@ use std::cell::RefCell;
use std::collections::hash_map::HashMap;
use std::rc::Rc;
use syntax::ast;
use util::common::ErrorReported;
use util::ppaux::Repr;

pub struct SelectionContext<'cx, 'tcx:'cx> {
Expand Down
3 changes: 2 additions & 1 deletion src/librustc/middle/traits/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@ use std::fmt;
use std::rc::Rc;
use syntax::ast;
use syntax::codemap::Span;
use util::common::ErrorReported;
use util::ppaux::Repr;

use super::{ErrorReported, Obligation, ObligationCause, VtableImpl,
use super::{Obligation, ObligationCause, VtableImpl,
VtableParam, VtableParamData, VtableImplData};

///////////////////////////////////////////////////////////////////////////
Expand Down
128 changes: 38 additions & 90 deletions src/librustc/middle/typeck/astconv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,6 @@ fn ast_path_substs_for_ty<'tcx,AC,RS>(
decl_def_id: ast::DefId,
decl_generics: &ty::Generics<'tcx>,
self_ty: Option<Ty<'tcx>>,
associated_ty: Option<Ty<'tcx>>,
path: &ast::Path)
-> Substs<'tcx>
where AC: AstConv<'tcx>, RS: RegionScope
Expand Down Expand Up @@ -243,7 +242,7 @@ fn ast_path_substs_for_ty<'tcx,AC,RS>(
};

create_substs_for_ast_path(this, rscope, path.span, decl_def_id,
decl_generics, self_ty, types, regions, associated_ty)
decl_generics, self_ty, types, regions)
}

fn create_substs_for_ast_path<'tcx,AC,RS>(
Expand All @@ -254,8 +253,7 @@ fn create_substs_for_ast_path<'tcx,AC,RS>(
decl_generics: &ty::Generics<'tcx>,
self_ty: Option<Ty<'tcx>>,
types: Vec<Ty<'tcx>>,
regions: Vec<ty::Region>,
associated_ty: Option<Ty<'tcx>>)
regions: Vec<ty::Region>)
-> Substs<'tcx>
where AC: AstConv<'tcx>, RS: RegionScope
{
Expand Down Expand Up @@ -366,9 +364,9 @@ fn create_substs_for_ast_path<'tcx,AC,RS>(
substs.types.push(
AssocSpace,
this.associated_type_binding(span,
associated_ty,
self_ty,
decl_def_id,
param.def_id))
param.def_id));
}

return substs;
Expand Down Expand Up @@ -417,19 +415,17 @@ pub fn instantiate_poly_trait_ref<'tcx,AC,RS>(
this: &AC,
rscope: &RS,
ast_trait_ref: &ast::PolyTraitRef,
self_ty: Option<Ty<'tcx>>,
associated_type: Option<Ty<'tcx>>)
self_ty: Option<Ty<'tcx>>)
-> Rc<ty::TraitRef<'tcx>>
where AC: AstConv<'tcx>, RS: RegionScope
{
instantiate_trait_ref(this, rscope, &ast_trait_ref.trait_ref, self_ty, associated_type)
instantiate_trait_ref(this, rscope, &ast_trait_ref.trait_ref, self_ty)
}

pub fn instantiate_trait_ref<'tcx,AC,RS>(this: &AC,
rscope: &RS,
ast_trait_ref: &ast::TraitRef,
self_ty: Option<Ty<'tcx>>,
associated_type: Option<Ty<'tcx>>)
self_ty: Option<Ty<'tcx>>)
-> Rc<ty::TraitRef<'tcx>>
where AC: AstConv<'tcx>,
RS: RegionScope
Expand All @@ -444,8 +440,8 @@ pub fn instantiate_trait_ref<'tcx,AC,RS>(this: &AC,
ast_trait_ref.path.span,
ast_trait_ref.ref_id) {
def::DefTrait(trait_def_id) => {
let trait_ref = Rc::new(ast_path_to_trait_ref(this, rscope, trait_def_id, self_ty,
associated_type, &ast_trait_ref.path));
let trait_ref = Rc::new(ast_path_to_trait_ref(this, rscope, trait_def_id,
self_ty, &ast_trait_ref.path));
this.tcx().trait_refs.borrow_mut().insert(ast_trait_ref.ref_id,
trait_ref.clone());
trait_ref
Expand All @@ -463,7 +459,6 @@ fn ast_path_to_trait_ref<'tcx,AC,RS>(
rscope: &RS,
trait_def_id: ast::DefId,
self_ty: Option<Ty<'tcx>>,
associated_type: Option<Ty<'tcx>>,
path: &ast::Path)
-> ty::TraitRef<'tcx>
where AC: AstConv<'tcx>, RS: RegionScope
Expand Down Expand Up @@ -493,8 +488,7 @@ fn ast_path_to_trait_ref<'tcx,AC,RS>(
&trait_def.generics,
self_ty,
types,
regions,
associated_type);
regions);

ty::TraitRef::new(trait_def_id, substs)
}
Expand All @@ -517,7 +511,6 @@ pub fn ast_path_to_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
did,
&generics,
None,
None,
path);
let ty = decl_ty.subst(tcx, &substs);
TypeAndSubsts { substs: substs, ty: ty }
Expand Down Expand Up @@ -558,7 +551,7 @@ pub fn ast_path_to_ty_relaxed<'tcx,AC,RS>(
Substs::new(VecPerParamSpace::params_from_type(type_params),
VecPerParamSpace::params_from_type(region_params))
} else {
ast_path_substs_for_ty(this, rscope, did, &generics, None, None, path)
ast_path_substs_for_ty(this, rscope, did, &generics, None, path)
};

let ty = decl_ty.subst(tcx, &substs);
Expand Down Expand Up @@ -726,7 +719,6 @@ fn mk_pointer<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
rscope,
trait_def_id,
None,
None,
path);
let empty_vec = [];
let bounds = match *opt_bounds { None => empty_vec.as_slice(),
Expand All @@ -750,61 +742,37 @@ fn mk_pointer<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
constr(ast_ty_to_ty(this, rscope, a_seq_ty))
}

fn associated_ty_to_ty<'tcx,AC,RS>(this: &AC,
rscope: &RS,
trait_path: &ast::Path,
for_ast_type: &ast::Ty,
trait_type_id: ast::DefId,
span: Span)
-> Ty<'tcx>
where AC: AstConv<'tcx>, RS: RegionScope
fn qpath_to_ty<'tcx,AC,RS>(this: &AC,
rscope: &RS,
ast_ty: &ast::Ty, // the TyQPath
qpath: &ast::QPath)
-> Ty<'tcx>
where AC: AstConv<'tcx>, RS: RegionScope
{
debug!("associated_ty_to_ty(trait_path={}, for_ast_type={}, trait_type_id={})",
trait_path.repr(this.tcx()),
for_ast_type.repr(this.tcx()),
trait_type_id.repr(this.tcx()));

// Find the trait that this associated type belongs to.
let trait_did = match ty::impl_or_trait_item(this.tcx(),
trait_type_id).container() {
ty::ImplContainer(_) => {
this.tcx().sess.span_bug(span,
"associated_ty_to_ty(): impl associated \
types shouldn't go through this \
function")
}
ty::TraitContainer(trait_id) => trait_id,
};
debug!("qpath_to_ty(ast_ty={})",
ast_ty.repr(this.tcx()));

let for_type = ast_ty_to_ty(this, rscope, for_ast_type);
if !this.associated_types_of_trait_are_valid(for_type, trait_did) {
this.tcx().sess.span_err(span,
"this associated type is not \
allowed in this context");
return ty::mk_err()
}
let self_type = ast_ty_to_ty(this, rscope, &*qpath.self_type);

debug!("qpath_to_ty: self_type={}", self_type.repr(this.tcx()));

let trait_ref = ast_path_to_trait_ref(this,
let trait_ref = instantiate_trait_ref(this,
rscope,
trait_did,
None,
Some(for_type),
trait_path);

debug!("associated_ty_to_ty(trait_ref={})",
trait_ref.repr(this.tcx()));

let trait_def = this.get_trait_def(trait_did);
for type_parameter in trait_def.generics.types.iter() {
if type_parameter.def_id == trait_type_id {
debug!("associated_ty_to_ty(type_parameter={} substs={})",
type_parameter.repr(this.tcx()),
trait_ref.substs.repr(this.tcx()));
return *trait_ref.substs.types.get(type_parameter.space,
type_parameter.index)
&*qpath.trait_ref,
Some(self_type));

debug!("qpath_to_ty: trait_ref={}", trait_ref.repr(this.tcx()));

let trait_def = this.get_trait_def(trait_ref.def_id);

for ty_param_def in trait_def.generics.types.get_slice(AssocSpace).iter() {
if ty_param_def.name == qpath.item_name.name {
debug!("qpath_to_ty: corresponding ty_param_def={}", ty_param_def);
return trait_ref.substs.type_for_def(ty_param_def);
}
}
this.tcx().sess.span_bug(span,

this.tcx().sess.span_bug(ast_ty.span,
"this associated type didn't get added \
as a parameter for some reason")
}
Expand Down Expand Up @@ -931,7 +899,6 @@ pub fn ast_ty_to_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
rscope,
trait_def_id,
None,
None,
path);
let empty_bounds: &[ast::TyParamBound] = &[];
let ast_bounds = match *bounds {
Expand Down Expand Up @@ -996,26 +963,7 @@ pub fn ast_ty_to_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
}
}
ast::TyQPath(ref qpath) => {
match tcx.def_map.borrow().get(&ast_ty.id) {
None => {
tcx.sess.span_bug(ast_ty.span,
"unbound qualified path")
}
Some(&def::DefAssociatedTy(trait_type_id)) => {
associated_ty_to_ty(this,
rscope,
&qpath.trait_name,
&*qpath.for_type,
trait_type_id,
ast_ty.span)
}
Some(_) => {
tcx.sess.span_err(ast_ty.span,
"this qualified path does not name \
an associated type");
ty::mk_err()
}
}
qpath_to_ty(this, rscope, ast_ty, &**qpath)
}
ast::TyFixedLengthVec(ref ty, ref e) => {
match const_eval::eval_const_expr_partial(tcx, &**e) {
Expand Down Expand Up @@ -1411,7 +1359,7 @@ fn conv_ty_poly_trait_ref<'tcx, AC, RS>(

let main_trait_bound = match partitioned_bounds.trait_bounds.remove(0) {
Some(trait_bound) => {
Some(instantiate_poly_trait_ref(this, rscope, trait_bound, None, None))
Some(instantiate_poly_trait_ref(this, rscope, trait_bound, None))
}
None => {
this.tcx().sess.span_err(
Expand Down
Loading