提交 004df413 编写于 作者: E Eduard Burtescu

syntax: don't use TraitRef in QPath.

上级 a817c692
......@@ -717,6 +717,11 @@ fn visit_path(&mut self, p: &ast::Path, id: ast::NodeId) {
visit::walk_path(self, p);
}
fn visit_qpath(&mut self, p: &ast::QPath, id: ast::NodeId) {
run_lints!(self, check_qpath, p, id);
visit::walk_qpath(self, p);
}
fn visit_attribute(&mut self, attr: &ast::Attribute) {
run_lints!(self, check_attribute, attr);
}
......
......@@ -157,6 +157,7 @@ fn check_lifetime_def(&mut self, _: &Context, _: &ast::LifetimeDef) { }
fn check_explicit_self(&mut self, _: &Context, _: &ast::ExplicitSelf) { }
fn check_mac(&mut self, _: &Context, _: &ast::Mac) { }
fn check_path(&mut self, _: &Context, _: &ast::Path, _: ast::NodeId) { }
fn check_qpath(&mut self, _: &Context, _: &ast::QPath, _: ast::NodeId) { }
fn check_attribute(&mut self, _: &Context, _: &ast::Attribute) { }
/// Called when entering a syntax node that can have lint attributes such
......
......@@ -1241,9 +1241,8 @@ fn add_to_index(item: &ast::Item, rbml_w: &Encoder,
}
rbml_w.end_tag();
}
if let Some(ref ast_trait_ref) = *opt_trait {
let trait_ref = ty::node_id_to_trait_ref(
tcx, ast_trait_ref.ref_id);
if opt_trait.is_some() {
let trait_ref = ty::impl_id_to_trait_ref(tcx, item.id);
encode_trait_ref(rbml_w, ecx, &*trait_ref, tag_item_trait_ref);
}
encode_path(rbml_w, path.clone());
......
......@@ -306,6 +306,11 @@ fn visit_path(&mut self, path: &ast::Path, id: ast::NodeId) {
visit::walk_path(self, path);
}
fn visit_qpath(&mut self, qpath: &ast::QPath, id: ast::NodeId) {
self.lookup_and_handle_definition(&id);
visit::walk_qpath(self, qpath);
}
fn visit_item(&mut self, _: &ast::Item) {
// Do not recurse into items. These items will be added to the
// worklist and recursed into manually if necessary.
......
......@@ -709,7 +709,7 @@ pub struct ctxt<'tcx> {
pub impl_trait_cache: RefCell<DefIdMap<Option<Rc<ty::TraitRef<'tcx>>>>>,
pub trait_refs: RefCell<NodeMap<Rc<TraitRef<'tcx>>>>,
pub impl_trait_refs: RefCell<NodeMap<Rc<TraitRef<'tcx>>>>,
pub trait_defs: RefCell<DefIdMap<Rc<TraitDef<'tcx>>>>,
/// Maps from the def-id of an item (trait/struct/enum/fn) to its
......@@ -2449,7 +2449,7 @@ pub fn mk_ctxt<'tcx>(s: Session,
region_maps: region_maps,
node_types: RefCell::new(FnvHashMap()),
item_substs: RefCell::new(NodeMap()),
trait_refs: RefCell::new(NodeMap()),
impl_trait_refs: RefCell::new(NodeMap()),
trait_defs: RefCell::new(DefIdMap()),
predicates: RefCell::new(DefIdMap()),
object_cast_map: RefCell::new(NodeMap()),
......@@ -4174,12 +4174,12 @@ pub fn named_element_ty<'tcx>(cx: &ctxt<'tcx>,
}
}
pub fn node_id_to_trait_ref<'tcx>(cx: &ctxt<'tcx>, id: ast::NodeId)
pub fn impl_id_to_trait_ref<'tcx>(cx: &ctxt<'tcx>, id: ast::NodeId)
-> Rc<ty::TraitRef<'tcx>> {
match cx.trait_refs.borrow().get(&id) {
match cx.impl_trait_refs.borrow().get(&id) {
Some(ty) => ty.clone(),
None => cx.sess.bug(
&format!("node_id_to_trait_ref: no trait ref for node `{}`",
&format!("impl_id_to_trait_ref: no trait ref for impl `{}`",
cx.map.node_to_string(id)))
}
}
......@@ -5116,25 +5116,19 @@ pub fn impl_trait_ref<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
memoized(&cx.impl_trait_cache, id, |id: ast::DefId| {
if id.krate == ast::LOCAL_CRATE {
debug!("(impl_trait_ref) searching for trait impl {:?}", id);
match cx.map.find(id.node) {
Some(ast_map::NodeItem(item)) => {
match item.node {
ast::ItemImpl(_, _, _, ref opt_trait, _, _) => {
match opt_trait {
&Some(ref t) => {
let trait_ref = ty::node_id_to_trait_ref(cx, t.ref_id);
Some(trait_ref)
}
&None => None
}
}
if let Some(ast_map::NodeItem(item)) = cx.map.find(id.node) {
if let ast::ItemImpl(_, _, _, ref opt_trait, _, _) = item.node {
opt_trait.as_ref().map(|_| {
ty::impl_id_to_trait_ref(cx, id.node)
})
} else {
None
ast::ItemDefaultImpl(_, ref ast_trait_ref) => {
Some(ty::node_id_to_trait_ref(cx, ast_trait_ref.ref_id))
}
_ => None
}
}
_ => None
} else {
None
}
} else {
csearch::get_impl_trait(cx, id)
......
......@@ -194,6 +194,7 @@ enum SawAbiComponent<'a> {
SawVariant,
SawExplicitSelf,
SawPath,
SawQPath,
SawOptLifetimeRef,
SawBlock,
SawPat,
......@@ -485,6 +486,10 @@ fn visit_path(&mut self, path: &Path, _: ast::NodeId) {
SawPath.hash(self.st); visit::walk_path(self, path)
}
fn visit_qpath(&mut self, qpath: &QPath, _: ast::NodeId) {
SawQPath.hash(self.st); visit::walk_qpath(self, qpath)
}
fn visit_block(&mut self, b: &Block) {
SawBlock.hash(self.st); visit::walk_block(self, b)
}
......
......@@ -1021,6 +1021,11 @@ fn visit_path(&mut self, path: &ast::Path, id: ast::NodeId) {
self.check_path(path.span, id, path.segments.last().unwrap().identifier);
visit::walk_path(self, path);
}
fn visit_qpath(&mut self, qpath: &ast::QPath, id: ast::NodeId) {
self.check_path(qpath.trait_path.span, id, qpath.item_path.identifier);
visit::walk_qpath(self, qpath);
}
}
////////////////////////////////////////////////////////////////////////////////
......
......@@ -2875,8 +2875,7 @@ fn resolve_item(&mut self, item: &Item) {
this.resolve_type_parameters(&generics.ty_params);
this.resolve_where_clause(&generics.where_clause);
this.resolve_type_parameter_bounds(item.id, bounds,
TraitDerivation);
this.resolve_type_parameter_bounds(bounds, TraitDerivation);
for trait_item in &(*trait_items) {
// Create a new rib for the trait_item-specific type
......@@ -3141,8 +3140,7 @@ fn resolve_type_parameter(&mut self,
type_parameter: &TyParam) {
self.check_if_primitive_type_name(type_parameter.ident.name, type_parameter.span);
for bound in &*type_parameter.bounds {
self.resolve_type_parameter_bound(type_parameter.id, bound,
TraitBoundingTypeParameter);
self.resolve_type_parameter_bound(bound, TraitBoundingTypeParameter);
}
match type_parameter.default {
Some(ref ty) => self.resolve_type(&**ty),
......@@ -3151,41 +3149,33 @@ fn resolve_type_parameter(&mut self,
}
fn resolve_type_parameter_bounds(&mut self,
id: NodeId,
type_parameter_bounds: &OwnedSlice<TyParamBound>,
reference_type: TraitReferenceType) {
for type_parameter_bound in &**type_parameter_bounds {
self.resolve_type_parameter_bound(id, type_parameter_bound,
reference_type);
self.resolve_type_parameter_bound(type_parameter_bound, reference_type);
}
}
fn resolve_type_parameter_bound(&mut self,
id: NodeId,
type_parameter_bound: &TyParamBound,
reference_type: TraitReferenceType) {
match *type_parameter_bound {
TraitTyParamBound(ref tref, _) => {
self.resolve_poly_trait_reference(id, tref, reference_type)
self.resolve_trait_reference(tref.trait_ref.ref_id,
&tref.trait_ref.path,
reference_type)
}
RegionTyParamBound(..) => {}
}
}
fn resolve_poly_trait_reference(&mut self,
id: NodeId,
poly_trait_reference: &PolyTraitRef,
reference_type: TraitReferenceType) {
self.resolve_trait_reference(id, &poly_trait_reference.trait_ref, reference_type)
}
fn resolve_trait_reference(&mut self,
id: NodeId,
trait_reference: &TraitRef,
trait_path: &Path,
reference_type: TraitReferenceType) {
match self.resolve_path(id, &trait_reference.path, TypeNS, true) {
match self.resolve_path(id, trait_path, TypeNS, true) {
None => {
let path_str = self.path_names_to_string(&trait_reference.path);
let path_str = self.path_names_to_string(trait_path);
let usage_str = match reference_type {
TraitBoundingTypeParameter => "bound type parameter with",
TraitImplementation => "implement",
......@@ -3195,26 +3185,23 @@ fn resolve_trait_reference(&mut self,
};
let msg = format!("attempt to {} a nonexistent trait `{}`", usage_str, path_str);
self.resolve_error(trait_reference.path.span, &msg[..]);
self.resolve_error(trait_path.span, &msg[..]);
}
Some(def) => {
match def {
(DefTrait(_), _) => {
debug!("(resolving trait) found trait def: {:?}", def);
self.record_def(trait_reference.ref_id, def);
self.record_def(id, def);
}
(def, _) => {
self.resolve_error(trait_reference.path.span,
&format!("`{}` is not a trait",
self.path_names_to_string(
&trait_reference.path)));
self.resolve_error(trait_path.span,
&format!("`{}` is not a trait",
self.path_names_to_string(trait_path)));
// If it's a typedef, give a note
if let DefTy(..) = def {
self.session.span_note(
trait_reference.path.span,
&format!("`type` aliases cannot be used for traits")
);
self.session.span_note(trait_path.span,
&format!("`type` aliases cannot be used for traits"));
}
}
}
......@@ -3229,8 +3216,7 @@ fn resolve_where_clause(&mut self, where_clause: &ast::WhereClause) {
self.resolve_type(&*bound_pred.bounded_ty);
for bound in &*bound_pred.bounds {
self.resolve_type_parameter_bound(bound_pred.bounded_ty.id, bound,
TraitBoundingTypeParameter);
self.resolve_type_parameter_bound(bound, TraitBoundingTypeParameter);
}
}
&ast::WherePredicate::RegionPredicate(_) => {}
......@@ -3303,14 +3289,16 @@ fn with_current_self_type<T, F>(&mut self, self_type: &Ty, f: F) -> T where
result
}
fn with_optional_trait_ref<T, F>(&mut self, id: NodeId,
fn with_optional_trait_ref<T, F>(&mut self,
opt_trait_ref: &Option<TraitRef>,
f: F) -> T where
F: FnOnce(&mut Resolver) -> T,
{
let new_val = match *opt_trait_ref {
Some(ref trait_ref) => {
self.resolve_trait_reference(id, trait_ref, TraitImplementation);
self.resolve_trait_reference(trait_ref.ref_id,
&trait_ref.path,
TraitImplementation);
match self.def_map.borrow().get(&trait_ref.ref_id) {
Some(def) => {
......@@ -3345,7 +3333,7 @@ fn resolve_implementation(&mut self,
this.resolve_where_clause(&generics.where_clause);
// Resolve the trait reference, if necessary.
this.with_optional_trait_ref(id, opt_trait_reference, |this| {
this.with_optional_trait_ref(opt_trait_reference, |this| {
// Resolve the self type.
this.resolve_type(self_type);
......@@ -3630,13 +3618,12 @@ fn resolve_type(&mut self, ty: &Ty) {
TyObjectSum(ref ty, ref bound_vec) => {
self.resolve_type(&**ty);
self.resolve_type_parameter_bounds(ty.id, bound_vec,
TraitBoundingTypeParameter);
self.resolve_type_parameter_bounds(bound_vec, TraitBoundingTypeParameter);
}
TyQPath(ref qpath) => {
self.resolve_type(&*qpath.self_type);
self.resolve_trait_reference(ty.id, &*qpath.trait_ref, TraitQPath);
self.resolve_trait_reference(ty.id, &qpath.trait_path, TraitQPath);
for ty in qpath.item_path.parameters.types() {
self.resolve_type(&**ty);
}
......@@ -3646,10 +3633,7 @@ fn resolve_type(&mut self, ty: &Ty) {
}
TyPolyTraitRef(ref bounds) => {
self.resolve_type_parameter_bounds(
ty.id,
bounds,
TraitObject);
self.resolve_type_parameter_bounds(bounds, TraitObject);
visit::walk_ty(self, ty);
}
_ => {
......@@ -4439,8 +4423,12 @@ fn resolve_expr(&mut self, expr: &Expr) {
ExprPath(ref path) => path,
ExprQPath(ref qpath) => {
self.resolve_type(&*qpath.self_type);
self.resolve_trait_reference(expr.id, &*qpath.trait_ref, TraitQPath);
path_from_qpath = qpath.trait_ref.path.clone();
// Just make sure the trait is valid, don't record a def.
self.resolve_trait_reference(expr.id, &qpath.trait_path, TraitQPath);
self.def_map.borrow_mut().remove(&expr.id);
path_from_qpath = qpath.trait_path.clone();
path_from_qpath.segments.push(qpath.item_path.clone());
&path_from_qpath
}
......
......@@ -1340,10 +1340,10 @@ fn visit_expr(&mut self, ex: &ast::Expr) {
visit::walk_path(self, path);
}
ast::ExprQPath(ref qpath) => {
let mut path = qpath.trait_ref.path.clone();
let mut path = qpath.trait_path.clone();
path.segments.push(qpath.item_path.clone());
self.process_path(ex.id, ex.span, &path, None);
visit::walk_qpath(self, ex.span, &**qpath);
visit::walk_qpath(self, &**qpath);
}
ast::ExprStruct(ref path, ref fields, ref base) =>
self.process_struct_lit(ex, path, fields, base),
......
......@@ -574,9 +574,10 @@ pub fn instantiate_poly_trait_ref<'tcx>(
// lifetimes. Oh well, not there yet.
let shifted_rscope = ShiftedRscope::new(rscope);
let trait_ref =
instantiate_trait_ref(this, &shifted_rscope, &ast_trait_ref.trait_ref,
self_ty, Some(&mut projections));
let trait_ref = instantiate_trait_ref(this, &shifted_rscope,
&ast_trait_ref.trait_ref.path,
ast_trait_ref.trait_ref.ref_id,
None, self_ty, Some(&mut projections));
for projection in projections {
poly_projections.push(ty::Binder(projection));
......@@ -594,26 +595,29 @@ pub fn instantiate_poly_trait_ref<'tcx>(
pub fn instantiate_trait_ref<'tcx>(
this: &AstConv<'tcx>,
rscope: &RegionScope,
ast_trait_ref: &ast::TraitRef,
path: &ast::Path,
path_id: ast::NodeId,
impl_id: Option<ast::NodeId>,
self_ty: Option<Ty<'tcx>>,
projections: Option<&mut Vec<ty::ProjectionPredicate<'tcx>>>)
-> Rc<ty::TraitRef<'tcx>>
{
match ::lookup_def_tcx(this.tcx(), ast_trait_ref.path.span, ast_trait_ref.ref_id) {
match ::lookup_def_tcx(this.tcx(), path.span, path_id) {
def::DefTrait(trait_def_id) => {
let trait_ref = ast_path_to_trait_ref(this,
rscope,
trait_def_id,
self_ty,
&ast_trait_ref.path,
path,
projections);
this.tcx().trait_refs.borrow_mut().insert(ast_trait_ref.ref_id, trait_ref.clone());
if let Some(id) = impl_id {
this.tcx().impl_trait_refs.borrow_mut().insert(id, trait_ref.clone());
}
trait_ref
}
_ => {
span_fatal!(this.tcx().sess, ast_trait_ref.path.span, E0245,
"`{}` is not a trait",
ast_trait_ref.path.user_string(this.tcx()));
span_fatal!(this.tcx().sess, path.span, E0245, "`{}` is not a trait",
path.user_string(this.tcx()));
}
}
}
......@@ -1056,7 +1060,9 @@ fn qpath_to_ty<'tcx>(this: &AstConv<'tcx>,
let trait_ref = instantiate_trait_ref(this,
rscope,
&*qpath.trait_ref,
&qpath.trait_path,
ast_ty.id,
None,
Some(self_type),
None);
......
......@@ -3611,13 +3611,10 @@ fn check_struct_fields_on_error<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
constrain_path_type_parameters(fcx, expr);
}
ast::ExprQPath(ref qpath) => {
// Require explicit type params for the trait.
let self_ty = fcx.to_ty(&*qpath.self_type);
astconv::instantiate_trait_ref(fcx, fcx, &*qpath.trait_ref, Some(self_ty), None);
let defn = lookup_def(fcx, expr.span, id);
let (scheme, predicates) = type_scheme_and_predicates_for_def(fcx, expr.span, defn);
let mut path = qpath.trait_ref.path.clone();
let mut path = qpath.trait_path.clone();
path.segments.push(qpath.item_path.clone());
instantiate_path(fcx, &path, scheme, &predicates, Some(self_ty),
defn, expr.span, expr.id);
......@@ -4829,7 +4826,8 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
// to add defaults. If the user provided *too many* types, that's
// a problem.
for &space in &ParamSpace::all() {
adjust_type_parameters(fcx, span, space, type_defs, &mut substs);
adjust_type_parameters(fcx, span, space, type_defs,
opt_self_ty.is_some(), &mut substs);
assert_eq!(substs.types.len(space), type_defs.len(space));
adjust_region_parameters(fcx, span, space, region_defs, &mut substs);
......@@ -5007,6 +5005,7 @@ fn adjust_type_parameters<'a, 'tcx>(
span: Span,
space: ParamSpace,
defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
require_type_space: bool,
substs: &mut Substs<'tcx>)
{
let provided_len = substs.types.len(space);
......@@ -5029,9 +5028,8 @@ fn adjust_type_parameters<'a, 'tcx>(
// Nothing specified at all: supply inference variables for
// everything.
if provided_len == 0 {
substs.types.replace(space,
fcx.infcx().next_ty_vars(desired.len()));
if provided_len == 0 && !(require_type_space && space == subst::TypeSpace) {
substs.types.replace(space, fcx.infcx().next_ty_vars(desired.len()));
return;
}
......
......@@ -81,8 +81,8 @@ fn check_item_well_formed(&mut self, item: &ast::Item) {
ast::ItemImpl(_, ast::ImplPolarity::Positive, _, _, _, _) => {
self.check_impl(item);
}
ast::ItemImpl(_, ast::ImplPolarity::Negative, _, Some(ref tref), _, _) => {
let trait_ref = ty::node_id_to_trait_ref(ccx.tcx, tref.ref_id);
ast::ItemImpl(_, ast::ImplPolarity::Negative, _, Some(_), _, _) => {
let trait_ref = ty::impl_id_to_trait_ref(ccx.tcx, item.id);
ty::populate_implementations_for_trait_if_necessary(ccx.tcx, trait_ref.def_id);
match ccx.tcx.lang_items.to_builtin_kind(trait_ref.def_id) {
Some(ty::BoundSend) | Some(ty::BoundSync) => {}
......
......@@ -28,8 +28,8 @@ struct ImplsChecker<'cx, 'tcx:'cx> {
impl<'cx, 'tcx,'v> visit::Visitor<'v> for ImplsChecker<'cx, 'tcx> {
fn visit_item(&mut self, item: &'v ast::Item) {
match item.node {
ast::ItemImpl(_, _, _, Some(ref opt_trait), _, _) => {
let trait_ref = ty::node_id_to_trait_ref(self.tcx, opt_trait.ref_id);
ast::ItemImpl(_, _, _, Some(_), _, _) => {
let trait_ref = ty::impl_id_to_trait_ref(self.tcx, item.id);
if let Some(_) = self.tcx.lang_items.to_builtin_kind(trait_ref.def_id) {
match trait_ref.self_ty().sty {
ty::ty_struct(..) | ty::ty_enum(..) => {}
......
......@@ -106,19 +106,9 @@ fn visit_item(&mut self, item: &Item) {
//debug!("(checking coherence) item '{}'", token::get_ident(item.ident));
match item.node {
ItemImpl(_, _, _, ref opt_trait, _, _) => {
match opt_trait.clone() {
Some(opt_trait) => {
self.cc.check_implementation(item, &[opt_trait]);
}
None => self.cc.check_implementation(item, &[])
}
}
_ => {
// Nothing to do.
}
};
if let ItemImpl(_, _, _, ref opt_trait, _, _) = item.node {
self.cc.check_implementation(item, opt_trait.as_ref())
}
visit::walk_item(self, item);
}
......@@ -155,9 +145,7 @@ fn check(&self, krate: &Crate) {
self.check_implementations_of_copy();
}
fn check_implementation(&self,
item: &Item,
associated_traits: &[TraitRef]) {
fn check_implementation(&self, item: &Item, opt_trait: Option<&TraitRef>) {
let tcx = self.crate_context.tcx;
let impl_did = local_def(item.id);
let self_type = ty::lookup_item_type(tcx, impl_did);
......@@ -167,9 +155,8 @@ fn check_implementation(&self,
let impl_items = self.create_impl_from_item(item);
for associated_trait in associated_traits {
let trait_ref = ty::node_id_to_trait_ref(self.crate_context.tcx,
associated_trait.ref_id);
if opt_trait.is_some() {
let trait_ref = ty::impl_id_to_trait_ref(self.crate_context.tcx, item.id);
debug!("(checking implementation) adding impl for trait '{}', item '{}'",
trait_ref.repr(self.crate_context.tcx),
token::get_ident(item.ident));
......@@ -191,7 +178,7 @@ fn check_implementation(&self,
}
Some(base_type_def_id) => {
// FIXME: Gather up default methods?
if associated_traits.len() == 0 {
if opt_trait.is_none() {
self.add_inherent_impl(base_type_def_id, impl_did);
}
}
......@@ -289,7 +276,7 @@ fn get_self_type_for_implementation(&self, impl_did: DefId)
// Converts an implementation in the AST to a vector of items.
fn create_impl_from_item(&self, item: &Item) -> Vec<ImplOrTraitItemId> {
match item.node {
ItemImpl(_, _, _, ref trait_refs, _, ref ast_items) => {
ItemImpl(_, _, _, ref opt_trait, _, ref ast_items) => {
let mut items: Vec<ImplOrTraitItemId> =
ast_items.iter()
.map(|ast_item| {
......@@ -304,13 +291,12 @@ fn create_impl_from_item(&self, item: &Item) -> Vec<ImplOrTraitItemId> {
}
}).collect();
if let Some(ref trait_ref) = *trait_refs {
let ty_trait_ref = ty::node_id_to_trait_ref(
self.crate_context.tcx,
trait_ref.ref_id);
if opt_trait.is_some() {
let trait_ref = ty::impl_id_to_trait_ref(self.crate_context.tcx,
item.id);
self.instantiate_default_methods(local_def(item.id),
&*ty_trait_ref,
&*trait_ref,
&mut items);
}
......
......@@ -740,7 +740,9 @@ fn convert_item(ccx: &CollectCtxt, it: &ast::Item) {
if let Some(ref trait_ref) = *opt_trait_ref {
astconv::instantiate_trait_ref(ccx,
&ExplicitRscope,
trait_ref,
&trait_ref.path,
trait_ref.ref_id,
Some(it.id),
Some(selfty),
None);
}
......
......@@ -1629,7 +1629,7 @@ fn clean(&self, cx: &DocContext) -> Type {
Type::QPath {
name: self.item_path.identifier.clean(cx),
self_type: box self.self_type.clean(cx),
trait_: box self.trait_ref.clean(cx)
trait_: box resolve_type(cx, self.trait_path.clean(cx), 0)
}
}
}
......
......@@ -782,11 +782,11 @@ pub enum Expr_ {
///
/// <Vec<T> as SomeTrait>::SomeAssociatedItem
/// ^~~~~ ^~~~~~~~~ ^~~~~~~~~~~~~~~~~~
/// self_type trait_name item_path
/// self_type trait_path item_path
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct QPath {
pub self_type: P<Ty>,
pub trait_ref: P<TraitRef>,
pub trait_path: Path,
pub item_path: PathSegment,
}
......@@ -1258,12 +1258,12 @@ pub enum Ty_ {
///
/// Type parameters are stored in the Path itself
TyPath(Path),
/// A "qualified path", e.g. `<Vec<T> as SomeTrait>::SomeType`
TyQPath(P<QPath>),
/// Something like `A+B`. Note that `B` must always be a path.
TyObjectSum(P<Ty>, TyParamBounds),
/// A type like `for<'a> Foo<&'a Bar>`
TyPolyTraitRef(TyParamBounds),
/// A "qualified path", e.g. `<Vec<T> as SomeTrait>::SomeType`
TyQPath(P<QPath>),
/// No-op; kept solely so that we can pretty-print faithfully
TyParen(P<Ty>),
/// Unused for now
......
......@@ -561,13 +561,18 @@ fn visit_trait_item(&mut self, tm: &ast::TraitItem) {
visit::walk_trait_item(self, tm);
}
fn visit_lifetime_ref(&mut self, lifetime: &'v Lifetime) {
fn visit_lifetime_ref(&mut self, lifetime: &Lifetime) {
self.operation.visit_id(lifetime.id);
}
fn visit_lifetime_def(&mut self, def: &'v LifetimeDef) {
fn visit_lifetime_def(&mut self, def: &LifetimeDef) {
self.visit_lifetime_ref(&def.lifetime);
}
fn visit_trait_ref(&mut self, trait_ref: &TraitRef) {
self.operation.visit_id(trait_ref.ref_id);
visit::walk_trait_ref(self, trait_ref);
}
}
pub fn visit_ids_for_inlined_item<O: IdVisitingOperation>(item: &InlinedItem,
......
......@@ -429,13 +429,13 @@ pub fn noop_fold_ty<T: Folder>(t: P<Ty>, fld: &mut T) -> P<Ty> {
TyTup(tys) => TyTup(tys.move_map(|ty| fld.fold_ty(ty))),
TyParen(ty) => TyParen(fld.fold_ty(ty)),
TyPath(path) => TyPath(fld.fold_path(path)),
TyQPath(qpath) => {
TyQPath(fld.fold_qpath(qpath))
}
TyObjectSum(ty, bounds) => {
TyObjectSum(fld.fold_ty(ty),
fld.fold_bounds(bounds))
}
TyQPath(qpath) => {
TyQPath(fld.fold_qpath(qpath))
}
TyFixedLengthVec(ty, e) => {
TyFixedLengthVec(fld.fold_ty(ty), fld.fold_expr(e))
}
......@@ -454,7 +454,7 @@ pub fn noop_fold_qpath<T: Folder>(qpath: P<QPath>, fld: &mut T) -> P<QPath> {
qpath.map(|qpath| {
QPath {
self_type: fld.fold_ty(qpath.self_type),
trait_ref: qpath.trait_ref.map(|tr| fld.fold_trait_ref(tr)),
trait_path: fld.fold_path(qpath.trait_path),
item_path: PathSegment {
identifier: fld.fold_ident(qpath.item_path.identifier),
parameters: fld.fold_path_parameters(qpath.item_path.parameters),
......
......@@ -1525,13 +1525,13 @@ pub fn parse_ty(&mut self) -> P<Ty> {
// QUALIFIED PATH `<TYPE as TRAIT_REF>::item`
let self_type = self.parse_ty_sum();
self.expect_keyword(keywords::As);
let trait_ref = self.parse_trait_ref();
let trait_path = self.parse_path(LifetimeAndTypesWithoutColons);
self.expect(&token::Gt);
self.expect(&token::ModSep);
let item_name = self.parse_ident();
TyQPath(P(QPath {
self_type: self_type,
trait_ref: P(trait_ref),
trait_path: trait_path,
item_path: ast::PathSegment {
identifier: item_name,
parameters: ast::PathParameters::none()
......@@ -2220,7 +2220,7 @@ pub fn parse_bottom_expr(&mut self) -> P<Expr> {
// QUALIFIED PATH `<TYPE as TRAIT_REF>::item::<'a, T>`
let self_type = self.parse_ty_sum();
self.expect_keyword(keywords::As);
let trait_ref = self.parse_trait_ref();
let trait_path = self.parse_path(LifetimeAndTypesWithoutColons);
self.expect(&token::Gt);
self.expect(&token::ModSep);
let item_name = self.parse_ident();
......@@ -2240,7 +2240,7 @@ pub fn parse_bottom_expr(&mut self) -> P<Expr> {
let hi = self.span.hi;
return self.mk_expr(lo, hi, ExprQPath(P(QPath {
self_type: self_type,
trait_ref: P(trait_ref),
trait_path: trait_path,
item_path: ast::PathSegment {
identifier: item_name,
parameters: parameters
......
......@@ -2047,7 +2047,7 @@ fn print_qpath(&mut self,
try!(self.print_type(&*qpath.self_type));
try!(space(&mut self.s));
try!(self.word_space("as"));
try!(self.print_trait_ref(&*qpath.trait_ref));
try!(self.print_path(&qpath.trait_path, false));
try!(word(&mut self.s, ">"));
try!(word(&mut self.s, "::"));
try!(self.print_ident(qpath.item_path.identifier));
......
......@@ -125,8 +125,8 @@ fn visit_mac(&mut self, _mac: &'v Mac) {
fn visit_path(&mut self, path: &'v Path, _id: ast::NodeId) {
walk_path(self, path)
}
fn visit_qpath(&mut self, qpath_span: Span, qpath: &'v QPath) {
walk_qpath(self, qpath_span, qpath)
fn visit_qpath(&mut self, qpath: &'v QPath, _id: ast::NodeId) {
walk_qpath(self, qpath)
}
fn visit_path_segment(&mut self, path_span: Span, path_segment: &'v PathSegment) {
walk_path_segment(self, path_span, path_segment)
......@@ -402,13 +402,13 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) {
TyPath(ref path) => {
visitor.visit_path(path, typ.id);
}
TyQPath(ref qpath) => {
visitor.visit_qpath(&**qpath, typ.id);
}
TyObjectSum(ref ty, ref bounds) => {
visitor.visit_ty(&**ty);
walk_ty_param_bounds_helper(visitor, bounds);
}
TyQPath(ref qpath) => {
visitor.visit_qpath(typ.span, &**qpath);
}
TyFixedLengthVec(ref ty, ref expression) => {
visitor.visit_ty(&**ty);
visitor.visit_expr(&**expression)
......@@ -436,12 +436,10 @@ pub fn walk_path<'v, V: Visitor<'v>>(visitor: &mut V, path: &'v Path) {
}
}
pub fn walk_qpath<'v, V: Visitor<'v>>(visitor: &mut V,
qpath_span: Span,
qpath: &'v QPath) {
pub fn walk_qpath<'v, V: Visitor<'v>>(visitor: &mut V, qpath: &'v QPath) {
visitor.visit_ty(&*qpath.self_type);
visitor.visit_trait_ref(&*qpath.trait_ref);
visitor.visit_path_segment(qpath_span, &qpath.item_path);
walk_path(visitor, &qpath.trait_path);
visitor.visit_path_segment(qpath.trait_path.span, &qpath.item_path);
}
pub fn walk_path_segment<'v, V: Visitor<'v>>(visitor: &mut V,
......@@ -873,7 +871,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
visitor.visit_path(path, expression.id)
}
ExprQPath(ref qpath) => {
visitor.visit_qpath(expression.span, &**qpath)
visitor.visit_qpath(&**qpath, expression.id)
}
ExprBreak(_) | ExprAgain(_) => {}
ExprRet(ref optional_expression) => {
......
......@@ -12,5 +12,5 @@
fn main() {
<String as IntoCow>::into_cow("foo".to_string());
//~^ ERROR wrong number of type arguments: expected 1, found 0
//~^ ERROR too few type parameters provided: expected 1 parameter(s)
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册