Skip to content

Commit b64c7b8

Browse files
committed
Refactor QPath to take an ast::TraitRef
1 parent cf7df1e commit b64c7b8

16 files changed

+122
-190
lines changed

src/librustc/middle/resolve.rs

+4-59
Original file line numberDiff line numberDiff line change
@@ -633,6 +633,7 @@ enum TraitReferenceType {
633633
TraitDerivation, // trait T : SomeTrait { ... }
634634
TraitBoundingTypeParameter, // fn f<T:SomeTrait>() { ... }
635635
TraitObject, // Box<for<'a> SomeTrait>
636+
TraitQPath, // <T as SomeTrait>::
636637
}
637638

638639
impl NameBindings {
@@ -4532,6 +4533,7 @@ impl<'a> Resolver<'a> {
45324533
TraitImplementation => "implement",
45334534
TraitDerivation => "derive",
45344535
TraitObject => "reference",
4536+
TraitQPath => "extract an associated type from",
45354537
};
45364538

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

49714973
TyQPath(ref qpath) => {
4972-
self.resolve_type(&*qpath.for_type);
4973-
4974-
let current_module = self.current_module.clone();
4975-
let module_path: Vec<_> =
4976-
qpath.trait_name
4977-
.segments
4978-
.iter()
4979-
.map(|ps| ps.identifier.name)
4980-
.collect();
4981-
match self.resolve_module_path(
4982-
current_module,
4983-
module_path.as_slice(),
4984-
UseLexicalScope,
4985-
qpath.trait_name.span,
4986-
PathSearch) {
4987-
Success((ref module, _)) if module.kind.get() ==
4988-
TraitModuleKind => {
4989-
match self.resolve_definition_of_name_in_module(
4990-
(*module).clone(),
4991-
qpath.item_name.name,
4992-
TypeNS) {
4993-
ChildNameDefinition(def, lp) |
4994-
ImportNameDefinition(def, lp) => {
4995-
match def {
4996-
DefAssociatedTy(trait_type_id) => {
4997-
let def = DefAssociatedTy(
4998-
trait_type_id);
4999-
self.record_def(ty.id, (def, lp));
5000-
}
5001-
_ => {
5002-
self.resolve_error(
5003-
ty.span,
5004-
"not an associated type");
5005-
}
5006-
}
5007-
}
5008-
NoNameDefinition => {
5009-
self.resolve_error(ty.span,
5010-
"unresolved associated \
5011-
type");
5012-
}
5013-
}
5014-
}
5015-
Success(..) => self.resolve_error(ty.span, "not a trait"),
5016-
Indeterminate => {
5017-
self.session.span_bug(ty.span,
5018-
"indeterminate result when \
5019-
resolving associated type")
5020-
}
5021-
Failed(error) => {
5022-
let (span, help) = match error {
5023-
Some((span, msg)) => (span, format!("; {}", msg)),
5024-
None => (ty.span, String::new()),
5025-
};
5026-
self.resolve_error(span,
5027-
format!("unresolved trait: {}",
5028-
help).as_slice())
5029-
}
5030-
}
4974+
self.resolve_type(&*qpath.self_type);
4975+
self.resolve_trait_reference(ty.id, &*qpath.trait_ref, TraitQPath);
50314976
}
50324977

50334978
TyClosure(ref c) | TyProc(ref c) => {

src/librustc/middle/subst.rs

+4
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,10 @@ impl<'tcx> Substs<'tcx> {
100100
regions_is_noop && self.types.is_empty()
101101
}
102102

103+
pub fn type_for_def(&self, ty_param_def: &ty::TypeParameterDef) -> Ty<'tcx> {
104+
*self.types.get(ty_param_def.space, ty_param_def.index)
105+
}
106+
103107
pub fn has_regions_escaping_depth(&self, depth: uint) -> bool {
104108
self.types.iter().any(|&t| ty::type_escapes_depth(t, depth)) || {
105109
match self.regions {

src/librustc/middle/traits/mod.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ use std::rc::Rc;
2525
use std::slice::Items;
2626
use syntax::ast;
2727
use syntax::codemap::{Span, DUMMY_SP};
28+
use util::common::ErrorReported;
2829

2930
pub use self::fulfill::FulfillmentContext;
3031
pub use self::select::SelectionContext;
@@ -95,10 +96,6 @@ pub enum ObligationCauseCode<'tcx> {
9596
FieldSized,
9697
}
9798

98-
// An error has already been reported to the user, so no need to continue checking.
99-
#[deriving(Clone,Show)]
100-
pub struct ErrorReported;
101-
10299
pub type Obligations<'tcx> = subst::VecPerParamSpace<Obligation<'tcx>>;
103100

104101
pub type Selection<'tcx> = Vtable<'tcx, Obligation<'tcx>>;

src/librustc/middle/traits/select.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ use self::Candidate::*;
1717
use self::BuiltinBoundConditions::*;
1818
use self::EvaluationResult::*;
1919

20-
use super::{ErrorReported};
2120
use super::{Obligation, ObligationCause};
2221
use super::{SelectionError, Unimplemented, Overflow,
2322
OutputTypeParameterMismatch};
@@ -38,6 +37,7 @@ use std::cell::RefCell;
3837
use std::collections::hash_map::HashMap;
3938
use std::rc::Rc;
4039
use syntax::ast;
40+
use util::common::ErrorReported;
4141
use util::ppaux::Repr;
4242

4343
pub struct SelectionContext<'cx, 'tcx:'cx> {

src/librustc/middle/traits/util.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,10 @@ use std::fmt;
1818
use std::rc::Rc;
1919
use syntax::ast;
2020
use syntax::codemap::Span;
21+
use util::common::ErrorReported;
2122
use util::ppaux::Repr;
2223

23-
use super::{ErrorReported, Obligation, ObligationCause, VtableImpl,
24+
use super::{Obligation, ObligationCause, VtableImpl,
2425
VtableParam, VtableParamData, VtableImplData};
2526

2627
///////////////////////////////////////////////////////////////////////////

src/librustc/middle/typeck/astconv.rs

+38-90
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,6 @@ fn ast_path_substs_for_ty<'tcx,AC,RS>(
207207
decl_def_id: ast::DefId,
208208
decl_generics: &ty::Generics<'tcx>,
209209
self_ty: Option<Ty<'tcx>>,
210-
associated_ty: Option<Ty<'tcx>>,
211210
path: &ast::Path)
212211
-> Substs<'tcx>
213212
where AC: AstConv<'tcx>, RS: RegionScope
@@ -243,7 +242,7 @@ fn ast_path_substs_for_ty<'tcx,AC,RS>(
243242
};
244243

245244
create_substs_for_ast_path(this, rscope, path.span, decl_def_id,
246-
decl_generics, self_ty, types, regions, associated_ty)
245+
decl_generics, self_ty, types, regions)
247246
}
248247

249248
fn create_substs_for_ast_path<'tcx,AC,RS>(
@@ -254,8 +253,7 @@ fn create_substs_for_ast_path<'tcx,AC,RS>(
254253
decl_generics: &ty::Generics<'tcx>,
255254
self_ty: Option<Ty<'tcx>>,
256255
types: Vec<Ty<'tcx>>,
257-
regions: Vec<ty::Region>,
258-
associated_ty: Option<Ty<'tcx>>)
256+
regions: Vec<ty::Region>)
259257
-> Substs<'tcx>
260258
where AC: AstConv<'tcx>, RS: RegionScope
261259
{
@@ -366,9 +364,9 @@ fn create_substs_for_ast_path<'tcx,AC,RS>(
366364
substs.types.push(
367365
AssocSpace,
368366
this.associated_type_binding(span,
369-
associated_ty,
367+
self_ty,
370368
decl_def_id,
371-
param.def_id))
369+
param.def_id));
372370
}
373371

374372
return substs;
@@ -417,19 +415,17 @@ pub fn instantiate_poly_trait_ref<'tcx,AC,RS>(
417415
this: &AC,
418416
rscope: &RS,
419417
ast_trait_ref: &ast::PolyTraitRef,
420-
self_ty: Option<Ty<'tcx>>,
421-
associated_type: Option<Ty<'tcx>>)
418+
self_ty: Option<Ty<'tcx>>)
422419
-> Rc<ty::TraitRef<'tcx>>
423420
where AC: AstConv<'tcx>, RS: RegionScope
424421
{
425-
instantiate_trait_ref(this, rscope, &ast_trait_ref.trait_ref, self_ty, associated_type)
422+
instantiate_trait_ref(this, rscope, &ast_trait_ref.trait_ref, self_ty)
426423
}
427424

428425
pub fn instantiate_trait_ref<'tcx,AC,RS>(this: &AC,
429426
rscope: &RS,
430427
ast_trait_ref: &ast::TraitRef,
431-
self_ty: Option<Ty<'tcx>>,
432-
associated_type: Option<Ty<'tcx>>)
428+
self_ty: Option<Ty<'tcx>>)
433429
-> Rc<ty::TraitRef<'tcx>>
434430
where AC: AstConv<'tcx>,
435431
RS: RegionScope
@@ -444,8 +440,8 @@ pub fn instantiate_trait_ref<'tcx,AC,RS>(this: &AC,
444440
ast_trait_ref.path.span,
445441
ast_trait_ref.ref_id) {
446442
def::DefTrait(trait_def_id) => {
447-
let trait_ref = Rc::new(ast_path_to_trait_ref(this, rscope, trait_def_id, self_ty,
448-
associated_type, &ast_trait_ref.path));
443+
let trait_ref = Rc::new(ast_path_to_trait_ref(this, rscope, trait_def_id,
444+
self_ty, &ast_trait_ref.path));
449445
this.tcx().trait_refs.borrow_mut().insert(ast_trait_ref.ref_id,
450446
trait_ref.clone());
451447
trait_ref
@@ -463,7 +459,6 @@ fn ast_path_to_trait_ref<'tcx,AC,RS>(
463459
rscope: &RS,
464460
trait_def_id: ast::DefId,
465461
self_ty: Option<Ty<'tcx>>,
466-
associated_type: Option<Ty<'tcx>>,
467462
path: &ast::Path)
468463
-> ty::TraitRef<'tcx>
469464
where AC: AstConv<'tcx>, RS: RegionScope
@@ -493,8 +488,7 @@ fn ast_path_to_trait_ref<'tcx,AC,RS>(
493488
&trait_def.generics,
494489
self_ty,
495490
types,
496-
regions,
497-
associated_type);
491+
regions);
498492

499493
ty::TraitRef::new(trait_def_id, substs)
500494
}
@@ -517,7 +511,6 @@ pub fn ast_path_to_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
517511
did,
518512
&generics,
519513
None,
520-
None,
521514
path);
522515
let ty = decl_ty.subst(tcx, &substs);
523516
TypeAndSubsts { substs: substs, ty: ty }
@@ -558,7 +551,7 @@ pub fn ast_path_to_ty_relaxed<'tcx,AC,RS>(
558551
Substs::new(VecPerParamSpace::params_from_type(type_params),
559552
VecPerParamSpace::params_from_type(region_params))
560553
} else {
561-
ast_path_substs_for_ty(this, rscope, did, &generics, None, None, path)
554+
ast_path_substs_for_ty(this, rscope, did, &generics, None, path)
562555
};
563556

564557
let ty = decl_ty.subst(tcx, &substs);
@@ -726,7 +719,6 @@ fn mk_pointer<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
726719
rscope,
727720
trait_def_id,
728721
None,
729-
None,
730722
path);
731723
let empty_vec = [];
732724
let bounds = match *opt_bounds { None => empty_vec.as_slice(),
@@ -750,61 +742,37 @@ fn mk_pointer<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
750742
constr(ast_ty_to_ty(this, rscope, a_seq_ty))
751743
}
752744

753-
fn associated_ty_to_ty<'tcx,AC,RS>(this: &AC,
754-
rscope: &RS,
755-
trait_path: &ast::Path,
756-
for_ast_type: &ast::Ty,
757-
trait_type_id: ast::DefId,
758-
span: Span)
759-
-> Ty<'tcx>
760-
where AC: AstConv<'tcx>, RS: RegionScope
745+
fn qpath_to_ty<'tcx,AC,RS>(this: &AC,
746+
rscope: &RS,
747+
ast_ty: &ast::Ty, // the TyQPath
748+
qpath: &ast::QPath)
749+
-> Ty<'tcx>
750+
where AC: AstConv<'tcx>, RS: RegionScope
761751
{
762-
debug!("associated_ty_to_ty(trait_path={}, for_ast_type={}, trait_type_id={})",
763-
trait_path.repr(this.tcx()),
764-
for_ast_type.repr(this.tcx()),
765-
trait_type_id.repr(this.tcx()));
766-
767-
// Find the trait that this associated type belongs to.
768-
let trait_did = match ty::impl_or_trait_item(this.tcx(),
769-
trait_type_id).container() {
770-
ty::ImplContainer(_) => {
771-
this.tcx().sess.span_bug(span,
772-
"associated_ty_to_ty(): impl associated \
773-
types shouldn't go through this \
774-
function")
775-
}
776-
ty::TraitContainer(trait_id) => trait_id,
777-
};
752+
debug!("qpath_to_ty(ast_ty={})",
753+
ast_ty.repr(this.tcx()));
778754

779-
let for_type = ast_ty_to_ty(this, rscope, for_ast_type);
780-
if !this.associated_types_of_trait_are_valid(for_type, trait_did) {
781-
this.tcx().sess.span_err(span,
782-
"this associated type is not \
783-
allowed in this context");
784-
return ty::mk_err()
785-
}
755+
let self_type = ast_ty_to_ty(this, rscope, &*qpath.self_type);
756+
757+
debug!("qpath_to_ty: self_type={}", self_type.repr(this.tcx()));
786758

787-
let trait_ref = ast_path_to_trait_ref(this,
759+
let trait_ref = instantiate_trait_ref(this,
788760
rscope,
789-
trait_did,
790-
None,
791-
Some(for_type),
792-
trait_path);
793-
794-
debug!("associated_ty_to_ty(trait_ref={})",
795-
trait_ref.repr(this.tcx()));
796-
797-
let trait_def = this.get_trait_def(trait_did);
798-
for type_parameter in trait_def.generics.types.iter() {
799-
if type_parameter.def_id == trait_type_id {
800-
debug!("associated_ty_to_ty(type_parameter={} substs={})",
801-
type_parameter.repr(this.tcx()),
802-
trait_ref.substs.repr(this.tcx()));
803-
return *trait_ref.substs.types.get(type_parameter.space,
804-
type_parameter.index)
761+
&*qpath.trait_ref,
762+
Some(self_type));
763+
764+
debug!("qpath_to_ty: trait_ref={}", trait_ref.repr(this.tcx()));
765+
766+
let trait_def = this.get_trait_def(trait_ref.def_id);
767+
768+
for ty_param_def in trait_def.generics.types.get_slice(AssocSpace).iter() {
769+
if ty_param_def.name == qpath.item_name.name {
770+
debug!("qpath_to_ty: corresponding ty_param_def={}", ty_param_def);
771+
return trait_ref.substs.type_for_def(ty_param_def);
805772
}
806773
}
807-
this.tcx().sess.span_bug(span,
774+
775+
this.tcx().sess.span_bug(ast_ty.span,
808776
"this associated type didn't get added \
809777
as a parameter for some reason")
810778
}
@@ -931,7 +899,6 @@ pub fn ast_ty_to_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
931899
rscope,
932900
trait_def_id,
933901
None,
934-
None,
935902
path);
936903
let empty_bounds: &[ast::TyParamBound] = &[];
937904
let ast_bounds = match *bounds {
@@ -996,26 +963,7 @@ pub fn ast_ty_to_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
996963
}
997964
}
998965
ast::TyQPath(ref qpath) => {
999-
match tcx.def_map.borrow().get(&ast_ty.id) {
1000-
None => {
1001-
tcx.sess.span_bug(ast_ty.span,
1002-
"unbound qualified path")
1003-
}
1004-
Some(&def::DefAssociatedTy(trait_type_id)) => {
1005-
associated_ty_to_ty(this,
1006-
rscope,
1007-
&qpath.trait_name,
1008-
&*qpath.for_type,
1009-
trait_type_id,
1010-
ast_ty.span)
1011-
}
1012-
Some(_) => {
1013-
tcx.sess.span_err(ast_ty.span,
1014-
"this qualified path does not name \
1015-
an associated type");
1016-
ty::mk_err()
1017-
}
1018-
}
966+
qpath_to_ty(this, rscope, ast_ty, &**qpath)
1019967
}
1020968
ast::TyFixedLengthVec(ref ty, ref e) => {
1021969
match const_eval::eval_const_expr_partial(tcx, &**e) {
@@ -1411,7 +1359,7 @@ fn conv_ty_poly_trait_ref<'tcx, AC, RS>(
14111359

14121360
let main_trait_bound = match partitioned_bounds.trait_bounds.remove(0) {
14131361
Some(trait_bound) => {
1414-
Some(instantiate_poly_trait_ref(this, rscope, trait_bound, None, None))
1362+
Some(instantiate_poly_trait_ref(this, rscope, trait_bound, None))
14151363
}
14161364
None => {
14171365
this.tcx().sess.span_err(

0 commit comments

Comments
 (0)