syntax: don't use TraitRef in QPath.
This commit is contained in:
parent
a817c69297
commit
004df413aa
23 changed files with 143 additions and 146 deletions
|
@ -717,6 +717,11 @@ impl<'a, 'tcx, 'v> Visitor<'v> for Context<'a, 'tcx> {
|
||||||
visit::walk_path(self, p);
|
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) {
|
fn visit_attribute(&mut self, attr: &ast::Attribute) {
|
||||||
run_lints!(self, check_attribute, attr);
|
run_lints!(self, check_attribute, attr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -157,6 +157,7 @@ pub trait LintPass {
|
||||||
fn check_explicit_self(&mut self, _: &Context, _: &ast::ExplicitSelf) { }
|
fn check_explicit_self(&mut self, _: &Context, _: &ast::ExplicitSelf) { }
|
||||||
fn check_mac(&mut self, _: &Context, _: &ast::Mac) { }
|
fn check_mac(&mut self, _: &Context, _: &ast::Mac) { }
|
||||||
fn check_path(&mut self, _: &Context, _: &ast::Path, _: ast::NodeId) { }
|
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) { }
|
fn check_attribute(&mut self, _: &Context, _: &ast::Attribute) { }
|
||||||
|
|
||||||
/// Called when entering a syntax node that can have lint attributes such
|
/// Called when entering a syntax node that can have lint attributes such
|
||||||
|
|
|
@ -1241,9 +1241,8 @@ fn encode_info_for_item(ecx: &EncodeContext,
|
||||||
}
|
}
|
||||||
rbml_w.end_tag();
|
rbml_w.end_tag();
|
||||||
}
|
}
|
||||||
if let Some(ref ast_trait_ref) = *opt_trait {
|
if opt_trait.is_some() {
|
||||||
let trait_ref = ty::node_id_to_trait_ref(
|
let trait_ref = ty::impl_id_to_trait_ref(tcx, item.id);
|
||||||
tcx, ast_trait_ref.ref_id);
|
|
||||||
encode_trait_ref(rbml_w, ecx, &*trait_ref, tag_item_trait_ref);
|
encode_trait_ref(rbml_w, ecx, &*trait_ref, tag_item_trait_ref);
|
||||||
}
|
}
|
||||||
encode_path(rbml_w, path.clone());
|
encode_path(rbml_w, path.clone());
|
||||||
|
|
|
@ -306,6 +306,11 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MarkSymbolVisitor<'a, 'tcx> {
|
||||||
visit::walk_path(self, path);
|
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) {
|
fn visit_item(&mut self, _: &ast::Item) {
|
||||||
// Do not recurse into items. These items will be added to the
|
// Do not recurse into items. These items will be added to the
|
||||||
// worklist and recursed into manually if necessary.
|
// 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 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>>>>,
|
pub trait_defs: RefCell<DefIdMap<Rc<TraitDef<'tcx>>>>,
|
||||||
|
|
||||||
/// Maps from the def-id of an item (trait/struct/enum/fn) to its
|
/// 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,
|
region_maps: region_maps,
|
||||||
node_types: RefCell::new(FnvHashMap()),
|
node_types: RefCell::new(FnvHashMap()),
|
||||||
item_substs: RefCell::new(NodeMap()),
|
item_substs: RefCell::new(NodeMap()),
|
||||||
trait_refs: RefCell::new(NodeMap()),
|
impl_trait_refs: RefCell::new(NodeMap()),
|
||||||
trait_defs: RefCell::new(DefIdMap()),
|
trait_defs: RefCell::new(DefIdMap()),
|
||||||
predicates: RefCell::new(DefIdMap()),
|
predicates: RefCell::new(DefIdMap()),
|
||||||
object_cast_map: RefCell::new(NodeMap()),
|
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>> {
|
-> Rc<ty::TraitRef<'tcx>> {
|
||||||
match cx.trait_refs.borrow().get(&id) {
|
match cx.impl_trait_refs.borrow().get(&id) {
|
||||||
Some(ty) => ty.clone(),
|
Some(ty) => ty.clone(),
|
||||||
None => cx.sess.bug(
|
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)))
|
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| {
|
memoized(&cx.impl_trait_cache, id, |id: ast::DefId| {
|
||||||
if id.krate == ast::LOCAL_CRATE {
|
if id.krate == ast::LOCAL_CRATE {
|
||||||
debug!("(impl_trait_ref) searching for trait impl {:?}", id);
|
debug!("(impl_trait_ref) searching for trait impl {:?}", id);
|
||||||
match cx.map.find(id.node) {
|
if let Some(ast_map::NodeItem(item)) = cx.map.find(id.node) {
|
||||||
Some(ast_map::NodeItem(item)) => {
|
if let ast::ItemImpl(_, _, _, ref opt_trait, _, _) = item.node {
|
||||||
match item.node {
|
opt_trait.as_ref().map(|_| {
|
||||||
ast::ItemImpl(_, _, _, ref opt_trait, _, _) => {
|
ty::impl_id_to_trait_ref(cx, id.node)
|
||||||
match opt_trait {
|
})
|
||||||
&Some(ref t) => {
|
} else {
|
||||||
let trait_ref = ty::node_id_to_trait_ref(cx, t.ref_id);
|
None
|
||||||
Some(trait_ref)
|
|
||||||
}
|
|
||||||
&None => None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ast::ItemDefaultImpl(_, ref ast_trait_ref) => {
|
ast::ItemDefaultImpl(_, ref ast_trait_ref) => {
|
||||||
Some(ty::node_id_to_trait_ref(cx, ast_trait_ref.ref_id))
|
Some(ty::node_id_to_trait_ref(cx, ast_trait_ref.ref_id))
|
||||||
}
|
}
|
||||||
_ => None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_ => None
|
} else {
|
||||||
|
None
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
csearch::get_impl_trait(cx, id)
|
csearch::get_impl_trait(cx, id)
|
||||||
|
|
|
@ -194,6 +194,7 @@ mod svh_visitor {
|
||||||
SawVariant,
|
SawVariant,
|
||||||
SawExplicitSelf,
|
SawExplicitSelf,
|
||||||
SawPath,
|
SawPath,
|
||||||
|
SawQPath,
|
||||||
SawOptLifetimeRef,
|
SawOptLifetimeRef,
|
||||||
SawBlock,
|
SawBlock,
|
||||||
SawPat,
|
SawPat,
|
||||||
|
@ -485,6 +486,10 @@ mod svh_visitor {
|
||||||
SawPath.hash(self.st); visit::walk_path(self, path)
|
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) {
|
fn visit_block(&mut self, b: &Block) {
|
||||||
SawBlock.hash(self.st); visit::walk_block(self, b)
|
SawBlock.hash(self.st); visit::walk_block(self, b)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1021,6 +1021,11 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
|
||||||
self.check_path(path.span, id, path.segments.last().unwrap().identifier);
|
self.check_path(path.span, id, path.segments.last().unwrap().identifier);
|
||||||
visit::walk_path(self, path);
|
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 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||||
this.resolve_type_parameters(&generics.ty_params);
|
this.resolve_type_parameters(&generics.ty_params);
|
||||||
this.resolve_where_clause(&generics.where_clause);
|
this.resolve_where_clause(&generics.where_clause);
|
||||||
|
|
||||||
this.resolve_type_parameter_bounds(item.id, bounds,
|
this.resolve_type_parameter_bounds(bounds, TraitDerivation);
|
||||||
TraitDerivation);
|
|
||||||
|
|
||||||
for trait_item in &(*trait_items) {
|
for trait_item in &(*trait_items) {
|
||||||
// Create a new rib for the trait_item-specific type
|
// Create a new rib for the trait_item-specific type
|
||||||
|
@ -3141,8 +3140,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||||
type_parameter: &TyParam) {
|
type_parameter: &TyParam) {
|
||||||
self.check_if_primitive_type_name(type_parameter.ident.name, type_parameter.span);
|
self.check_if_primitive_type_name(type_parameter.ident.name, type_parameter.span);
|
||||||
for bound in &*type_parameter.bounds {
|
for bound in &*type_parameter.bounds {
|
||||||
self.resolve_type_parameter_bound(type_parameter.id, bound,
|
self.resolve_type_parameter_bound(bound, TraitBoundingTypeParameter);
|
||||||
TraitBoundingTypeParameter);
|
|
||||||
}
|
}
|
||||||
match type_parameter.default {
|
match type_parameter.default {
|
||||||
Some(ref ty) => self.resolve_type(&**ty),
|
Some(ref ty) => self.resolve_type(&**ty),
|
||||||
|
@ -3151,41 +3149,33 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_type_parameter_bounds(&mut self,
|
fn resolve_type_parameter_bounds(&mut self,
|
||||||
id: NodeId,
|
|
||||||
type_parameter_bounds: &OwnedSlice<TyParamBound>,
|
type_parameter_bounds: &OwnedSlice<TyParamBound>,
|
||||||
reference_type: TraitReferenceType) {
|
reference_type: TraitReferenceType) {
|
||||||
for type_parameter_bound in &**type_parameter_bounds {
|
for type_parameter_bound in &**type_parameter_bounds {
|
||||||
self.resolve_type_parameter_bound(id, type_parameter_bound,
|
self.resolve_type_parameter_bound(type_parameter_bound, reference_type);
|
||||||
reference_type);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_type_parameter_bound(&mut self,
|
fn resolve_type_parameter_bound(&mut self,
|
||||||
id: NodeId,
|
|
||||||
type_parameter_bound: &TyParamBound,
|
type_parameter_bound: &TyParamBound,
|
||||||
reference_type: TraitReferenceType) {
|
reference_type: TraitReferenceType) {
|
||||||
match *type_parameter_bound {
|
match *type_parameter_bound {
|
||||||
TraitTyParamBound(ref tref, _) => {
|
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(..) => {}
|
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,
|
fn resolve_trait_reference(&mut self,
|
||||||
id: NodeId,
|
id: NodeId,
|
||||||
trait_reference: &TraitRef,
|
trait_path: &Path,
|
||||||
reference_type: TraitReferenceType) {
|
reference_type: TraitReferenceType) {
|
||||||
match self.resolve_path(id, &trait_reference.path, TypeNS, true) {
|
match self.resolve_path(id, trait_path, TypeNS, true) {
|
||||||
None => {
|
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 {
|
let usage_str = match reference_type {
|
||||||
TraitBoundingTypeParameter => "bound type parameter with",
|
TraitBoundingTypeParameter => "bound type parameter with",
|
||||||
TraitImplementation => "implement",
|
TraitImplementation => "implement",
|
||||||
|
@ -3195,26 +3185,23 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||||
};
|
};
|
||||||
|
|
||||||
let msg = format!("attempt to {} a nonexistent trait `{}`", usage_str, path_str);
|
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) => {
|
Some(def) => {
|
||||||
match def {
|
match def {
|
||||||
(DefTrait(_), _) => {
|
(DefTrait(_), _) => {
|
||||||
debug!("(resolving trait) found trait def: {:?}", def);
|
debug!("(resolving trait) found trait def: {:?}", def);
|
||||||
self.record_def(trait_reference.ref_id, def);
|
self.record_def(id, def);
|
||||||
}
|
}
|
||||||
(def, _) => {
|
(def, _) => {
|
||||||
self.resolve_error(trait_reference.path.span,
|
self.resolve_error(trait_path.span,
|
||||||
&format!("`{}` is not a trait",
|
&format!("`{}` is not a trait",
|
||||||
self.path_names_to_string(
|
self.path_names_to_string(trait_path)));
|
||||||
&trait_reference.path)));
|
|
||||||
|
|
||||||
// If it's a typedef, give a note
|
// If it's a typedef, give a note
|
||||||
if let DefTy(..) = def {
|
if let DefTy(..) = def {
|
||||||
self.session.span_note(
|
self.session.span_note(trait_path.span,
|
||||||
trait_reference.path.span,
|
&format!("`type` aliases cannot be used for traits"));
|
||||||
&format!("`type` aliases cannot be used for traits")
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3229,8 +3216,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||||
self.resolve_type(&*bound_pred.bounded_ty);
|
self.resolve_type(&*bound_pred.bounded_ty);
|
||||||
|
|
||||||
for bound in &*bound_pred.bounds {
|
for bound in &*bound_pred.bounds {
|
||||||
self.resolve_type_parameter_bound(bound_pred.bounded_ty.id, bound,
|
self.resolve_type_parameter_bound(bound, TraitBoundingTypeParameter);
|
||||||
TraitBoundingTypeParameter);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&ast::WherePredicate::RegionPredicate(_) => {}
|
&ast::WherePredicate::RegionPredicate(_) => {}
|
||||||
|
@ -3303,14 +3289,16 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||||
result
|
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>,
|
opt_trait_ref: &Option<TraitRef>,
|
||||||
f: F) -> T where
|
f: F) -> T where
|
||||||
F: FnOnce(&mut Resolver) -> T,
|
F: FnOnce(&mut Resolver) -> T,
|
||||||
{
|
{
|
||||||
let new_val = match *opt_trait_ref {
|
let new_val = match *opt_trait_ref {
|
||||||
Some(ref 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) {
|
match self.def_map.borrow().get(&trait_ref.ref_id) {
|
||||||
Some(def) => {
|
Some(def) => {
|
||||||
|
@ -3345,7 +3333,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||||
this.resolve_where_clause(&generics.where_clause);
|
this.resolve_where_clause(&generics.where_clause);
|
||||||
|
|
||||||
// Resolve the trait reference, if necessary.
|
// 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.
|
// Resolve the self type.
|
||||||
this.resolve_type(self_type);
|
this.resolve_type(self_type);
|
||||||
|
|
||||||
|
@ -3630,13 +3618,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||||
|
|
||||||
TyObjectSum(ref ty, ref bound_vec) => {
|
TyObjectSum(ref ty, ref bound_vec) => {
|
||||||
self.resolve_type(&**ty);
|
self.resolve_type(&**ty);
|
||||||
self.resolve_type_parameter_bounds(ty.id, bound_vec,
|
self.resolve_type_parameter_bounds(bound_vec, TraitBoundingTypeParameter);
|
||||||
TraitBoundingTypeParameter);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TyQPath(ref qpath) => {
|
TyQPath(ref qpath) => {
|
||||||
self.resolve_type(&*qpath.self_type);
|
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() {
|
for ty in qpath.item_path.parameters.types() {
|
||||||
self.resolve_type(&**ty);
|
self.resolve_type(&**ty);
|
||||||
}
|
}
|
||||||
|
@ -3646,10 +3633,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
TyPolyTraitRef(ref bounds) => {
|
TyPolyTraitRef(ref bounds) => {
|
||||||
self.resolve_type_parameter_bounds(
|
self.resolve_type_parameter_bounds(bounds, TraitObject);
|
||||||
ty.id,
|
|
||||||
bounds,
|
|
||||||
TraitObject);
|
|
||||||
visit::walk_ty(self, ty);
|
visit::walk_ty(self, ty);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
@ -4439,8 +4423,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||||
ExprPath(ref path) => path,
|
ExprPath(ref path) => path,
|
||||||
ExprQPath(ref qpath) => {
|
ExprQPath(ref qpath) => {
|
||||||
self.resolve_type(&*qpath.self_type);
|
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.segments.push(qpath.item_path.clone());
|
||||||
&path_from_qpath
|
&path_from_qpath
|
||||||
}
|
}
|
||||||
|
|
|
@ -1340,10 +1340,10 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
|
||||||
visit::walk_path(self, path);
|
visit::walk_path(self, path);
|
||||||
}
|
}
|
||||||
ast::ExprQPath(ref qpath) => {
|
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());
|
path.segments.push(qpath.item_path.clone());
|
||||||
self.process_path(ex.id, ex.span, &path, None);
|
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) =>
|
ast::ExprStruct(ref path, ref fields, ref base) =>
|
||||||
self.process_struct_lit(ex, path, fields, 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.
|
// lifetimes. Oh well, not there yet.
|
||||||
let shifted_rscope = ShiftedRscope::new(rscope);
|
let shifted_rscope = ShiftedRscope::new(rscope);
|
||||||
|
|
||||||
let trait_ref =
|
let trait_ref = instantiate_trait_ref(this, &shifted_rscope,
|
||||||
instantiate_trait_ref(this, &shifted_rscope, &ast_trait_ref.trait_ref,
|
&ast_trait_ref.trait_ref.path,
|
||||||
self_ty, Some(&mut projections));
|
ast_trait_ref.trait_ref.ref_id,
|
||||||
|
None, self_ty, Some(&mut projections));
|
||||||
|
|
||||||
for projection in projections {
|
for projection in projections {
|
||||||
poly_projections.push(ty::Binder(projection));
|
poly_projections.push(ty::Binder(projection));
|
||||||
|
@ -594,26 +595,29 @@ pub fn instantiate_poly_trait_ref<'tcx>(
|
||||||
pub fn instantiate_trait_ref<'tcx>(
|
pub fn instantiate_trait_ref<'tcx>(
|
||||||
this: &AstConv<'tcx>,
|
this: &AstConv<'tcx>,
|
||||||
rscope: &RegionScope,
|
rscope: &RegionScope,
|
||||||
ast_trait_ref: &ast::TraitRef,
|
path: &ast::Path,
|
||||||
|
path_id: ast::NodeId,
|
||||||
|
impl_id: Option<ast::NodeId>,
|
||||||
self_ty: Option<Ty<'tcx>>,
|
self_ty: Option<Ty<'tcx>>,
|
||||||
projections: Option<&mut Vec<ty::ProjectionPredicate<'tcx>>>)
|
projections: Option<&mut Vec<ty::ProjectionPredicate<'tcx>>>)
|
||||||
-> Rc<ty::TraitRef<'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) => {
|
def::DefTrait(trait_def_id) => {
|
||||||
let trait_ref = ast_path_to_trait_ref(this,
|
let trait_ref = ast_path_to_trait_ref(this,
|
||||||
rscope,
|
rscope,
|
||||||
trait_def_id,
|
trait_def_id,
|
||||||
self_ty,
|
self_ty,
|
||||||
&ast_trait_ref.path,
|
path,
|
||||||
projections);
|
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
|
trait_ref
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
span_fatal!(this.tcx().sess, ast_trait_ref.path.span, E0245,
|
span_fatal!(this.tcx().sess, path.span, E0245, "`{}` is not a trait",
|
||||||
"`{}` is not a trait",
|
path.user_string(this.tcx()));
|
||||||
ast_trait_ref.path.user_string(this.tcx()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1056,7 +1060,9 @@ fn qpath_to_ty<'tcx>(this: &AstConv<'tcx>,
|
||||||
|
|
||||||
let trait_ref = instantiate_trait_ref(this,
|
let trait_ref = instantiate_trait_ref(this,
|
||||||
rscope,
|
rscope,
|
||||||
&*qpath.trait_ref,
|
&qpath.trait_path,
|
||||||
|
ast_ty.id,
|
||||||
|
None,
|
||||||
Some(self_type),
|
Some(self_type),
|
||||||
None);
|
None);
|
||||||
|
|
||||||
|
|
|
@ -3611,13 +3611,10 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
|
||||||
constrain_path_type_parameters(fcx, expr);
|
constrain_path_type_parameters(fcx, expr);
|
||||||
}
|
}
|
||||||
ast::ExprQPath(ref qpath) => {
|
ast::ExprQPath(ref qpath) => {
|
||||||
// Require explicit type params for the trait.
|
|
||||||
let self_ty = fcx.to_ty(&*qpath.self_type);
|
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 defn = lookup_def(fcx, expr.span, id);
|
||||||
let (scheme, predicates) = type_scheme_and_predicates_for_def(fcx, expr.span, defn);
|
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());
|
path.segments.push(qpath.item_path.clone());
|
||||||
instantiate_path(fcx, &path, scheme, &predicates, Some(self_ty),
|
instantiate_path(fcx, &path, scheme, &predicates, Some(self_ty),
|
||||||
defn, expr.span, expr.id);
|
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
|
// to add defaults. If the user provided *too many* types, that's
|
||||||
// a problem.
|
// a problem.
|
||||||
for &space in &ParamSpace::all() {
|
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));
|
assert_eq!(substs.types.len(space), type_defs.len(space));
|
||||||
|
|
||||||
adjust_region_parameters(fcx, span, space, region_defs, &mut substs);
|
adjust_region_parameters(fcx, span, space, region_defs, &mut substs);
|
||||||
|
@ -5007,6 +5005,7 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
||||||
span: Span,
|
span: Span,
|
||||||
space: ParamSpace,
|
space: ParamSpace,
|
||||||
defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
|
defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
|
||||||
|
require_type_space: bool,
|
||||||
substs: &mut Substs<'tcx>)
|
substs: &mut Substs<'tcx>)
|
||||||
{
|
{
|
||||||
let provided_len = substs.types.len(space);
|
let provided_len = substs.types.len(space);
|
||||||
|
@ -5029,9 +5028,8 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
||||||
|
|
||||||
// Nothing specified at all: supply inference variables for
|
// Nothing specified at all: supply inference variables for
|
||||||
// everything.
|
// everything.
|
||||||
if provided_len == 0 {
|
if provided_len == 0 && !(require_type_space && space == subst::TypeSpace) {
|
||||||
substs.types.replace(space,
|
substs.types.replace(space, fcx.infcx().next_ty_vars(desired.len()));
|
||||||
fcx.infcx().next_ty_vars(desired.len()));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -81,8 +81,8 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
|
||||||
ast::ItemImpl(_, ast::ImplPolarity::Positive, _, _, _, _) => {
|
ast::ItemImpl(_, ast::ImplPolarity::Positive, _, _, _, _) => {
|
||||||
self.check_impl(item);
|
self.check_impl(item);
|
||||||
}
|
}
|
||||||
ast::ItemImpl(_, ast::ImplPolarity::Negative, _, Some(ref tref), _, _) => {
|
ast::ItemImpl(_, ast::ImplPolarity::Negative, _, Some(_), _, _) => {
|
||||||
let trait_ref = ty::node_id_to_trait_ref(ccx.tcx, tref.ref_id);
|
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);
|
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) {
|
match ccx.tcx.lang_items.to_builtin_kind(trait_ref.def_id) {
|
||||||
Some(ty::BoundSend) | Some(ty::BoundSync) => {}
|
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> {
|
impl<'cx, 'tcx,'v> visit::Visitor<'v> for ImplsChecker<'cx, 'tcx> {
|
||||||
fn visit_item(&mut self, item: &'v ast::Item) {
|
fn visit_item(&mut self, item: &'v ast::Item) {
|
||||||
match item.node {
|
match item.node {
|
||||||
ast::ItemImpl(_, _, _, Some(ref opt_trait), _, _) => {
|
ast::ItemImpl(_, _, _, Some(_), _, _) => {
|
||||||
let trait_ref = ty::node_id_to_trait_ref(self.tcx, opt_trait.ref_id);
|
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) {
|
if let Some(_) = self.tcx.lang_items.to_builtin_kind(trait_ref.def_id) {
|
||||||
match trait_ref.self_ty().sty {
|
match trait_ref.self_ty().sty {
|
||||||
ty::ty_struct(..) | ty::ty_enum(..) => {}
|
ty::ty_struct(..) | ty::ty_enum(..) => {}
|
||||||
|
|
|
@ -106,19 +106,9 @@ impl<'a, 'tcx, 'v> visit::Visitor<'v> for CoherenceCheckVisitor<'a, 'tcx> {
|
||||||
|
|
||||||
//debug!("(checking coherence) item '{}'", token::get_ident(item.ident));
|
//debug!("(checking coherence) item '{}'", token::get_ident(item.ident));
|
||||||
|
|
||||||
match item.node {
|
if let ItemImpl(_, _, _, ref opt_trait, _, _) = item.node {
|
||||||
ItemImpl(_, _, _, ref opt_trait, _, _) => {
|
self.cc.check_implementation(item, opt_trait.as_ref())
|
||||||
match opt_trait.clone() {
|
}
|
||||||
Some(opt_trait) => {
|
|
||||||
self.cc.check_implementation(item, &[opt_trait]);
|
|
||||||
}
|
|
||||||
None => self.cc.check_implementation(item, &[])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
// Nothing to do.
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
visit::walk_item(self, item);
|
visit::walk_item(self, item);
|
||||||
}
|
}
|
||||||
|
@ -155,9 +145,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
|
||||||
self.check_implementations_of_copy();
|
self.check_implementations_of_copy();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_implementation(&self,
|
fn check_implementation(&self, item: &Item, opt_trait: Option<&TraitRef>) {
|
||||||
item: &Item,
|
|
||||||
associated_traits: &[TraitRef]) {
|
|
||||||
let tcx = self.crate_context.tcx;
|
let tcx = self.crate_context.tcx;
|
||||||
let impl_did = local_def(item.id);
|
let impl_did = local_def(item.id);
|
||||||
let self_type = ty::lookup_item_type(tcx, impl_did);
|
let self_type = ty::lookup_item_type(tcx, impl_did);
|
||||||
|
@ -167,9 +155,8 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
|
||||||
|
|
||||||
let impl_items = self.create_impl_from_item(item);
|
let impl_items = self.create_impl_from_item(item);
|
||||||
|
|
||||||
for associated_trait in associated_traits {
|
if opt_trait.is_some() {
|
||||||
let trait_ref = ty::node_id_to_trait_ref(self.crate_context.tcx,
|
let trait_ref = ty::impl_id_to_trait_ref(self.crate_context.tcx, item.id);
|
||||||
associated_trait.ref_id);
|
|
||||||
debug!("(checking implementation) adding impl for trait '{}', item '{}'",
|
debug!("(checking implementation) adding impl for trait '{}', item '{}'",
|
||||||
trait_ref.repr(self.crate_context.tcx),
|
trait_ref.repr(self.crate_context.tcx),
|
||||||
token::get_ident(item.ident));
|
token::get_ident(item.ident));
|
||||||
|
@ -191,7 +178,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
Some(base_type_def_id) => {
|
Some(base_type_def_id) => {
|
||||||
// FIXME: Gather up default methods?
|
// 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);
|
self.add_inherent_impl(base_type_def_id, impl_did);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -289,7 +276,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
|
||||||
// Converts an implementation in the AST to a vector of items.
|
// Converts an implementation in the AST to a vector of items.
|
||||||
fn create_impl_from_item(&self, item: &Item) -> Vec<ImplOrTraitItemId> {
|
fn create_impl_from_item(&self, item: &Item) -> Vec<ImplOrTraitItemId> {
|
||||||
match item.node {
|
match item.node {
|
||||||
ItemImpl(_, _, _, ref trait_refs, _, ref ast_items) => {
|
ItemImpl(_, _, _, ref opt_trait, _, ref ast_items) => {
|
||||||
let mut items: Vec<ImplOrTraitItemId> =
|
let mut items: Vec<ImplOrTraitItemId> =
|
||||||
ast_items.iter()
|
ast_items.iter()
|
||||||
.map(|ast_item| {
|
.map(|ast_item| {
|
||||||
|
@ -304,13 +291,12 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}).collect();
|
}).collect();
|
||||||
|
|
||||||
if let Some(ref trait_ref) = *trait_refs {
|
if opt_trait.is_some() {
|
||||||
let ty_trait_ref = ty::node_id_to_trait_ref(
|
let trait_ref = ty::impl_id_to_trait_ref(self.crate_context.tcx,
|
||||||
self.crate_context.tcx,
|
item.id);
|
||||||
trait_ref.ref_id);
|
|
||||||
|
|
||||||
self.instantiate_default_methods(local_def(item.id),
|
self.instantiate_default_methods(local_def(item.id),
|
||||||
&*ty_trait_ref,
|
&*trait_ref,
|
||||||
&mut items);
|
&mut items);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -740,7 +740,9 @@ fn convert_item(ccx: &CollectCtxt, it: &ast::Item) {
|
||||||
if let Some(ref trait_ref) = *opt_trait_ref {
|
if let Some(ref trait_ref) = *opt_trait_ref {
|
||||||
astconv::instantiate_trait_ref(ccx,
|
astconv::instantiate_trait_ref(ccx,
|
||||||
&ExplicitRscope,
|
&ExplicitRscope,
|
||||||
trait_ref,
|
&trait_ref.path,
|
||||||
|
trait_ref.ref_id,
|
||||||
|
Some(it.id),
|
||||||
Some(selfty),
|
Some(selfty),
|
||||||
None);
|
None);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1629,7 +1629,7 @@ impl Clean<Type> for ast::QPath {
|
||||||
Type::QPath {
|
Type::QPath {
|
||||||
name: self.item_path.identifier.clean(cx),
|
name: self.item_path.identifier.clean(cx),
|
||||||
self_type: box self.self_type.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
|
/// <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)]
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
||||||
pub struct QPath {
|
pub struct QPath {
|
||||||
pub self_type: P<Ty>,
|
pub self_type: P<Ty>,
|
||||||
pub trait_ref: P<TraitRef>,
|
pub trait_path: Path,
|
||||||
pub item_path: PathSegment,
|
pub item_path: PathSegment,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1258,12 +1258,12 @@ pub enum Ty_ {
|
||||||
///
|
///
|
||||||
/// Type parameters are stored in the Path itself
|
/// Type parameters are stored in the Path itself
|
||||||
TyPath(Path),
|
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.
|
/// Something like `A+B`. Note that `B` must always be a path.
|
||||||
TyObjectSum(P<Ty>, TyParamBounds),
|
TyObjectSum(P<Ty>, TyParamBounds),
|
||||||
/// A type like `for<'a> Foo<&'a Bar>`
|
/// A type like `for<'a> Foo<&'a Bar>`
|
||||||
TyPolyTraitRef(TyParamBounds),
|
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
|
/// No-op; kept solely so that we can pretty-print faithfully
|
||||||
TyParen(P<Ty>),
|
TyParen(P<Ty>),
|
||||||
/// Unused for now
|
/// Unused for now
|
||||||
|
|
|
@ -561,13 +561,18 @@ impl<'a, 'v, O: IdVisitingOperation> Visitor<'v> for IdVisitor<'a, O> {
|
||||||
visit::walk_trait_item(self, tm);
|
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);
|
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);
|
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,
|
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))),
|
TyTup(tys) => TyTup(tys.move_map(|ty| fld.fold_ty(ty))),
|
||||||
TyParen(ty) => TyParen(fld.fold_ty(ty)),
|
TyParen(ty) => TyParen(fld.fold_ty(ty)),
|
||||||
TyPath(path) => TyPath(fld.fold_path(path)),
|
TyPath(path) => TyPath(fld.fold_path(path)),
|
||||||
|
TyQPath(qpath) => {
|
||||||
|
TyQPath(fld.fold_qpath(qpath))
|
||||||
|
}
|
||||||
TyObjectSum(ty, bounds) => {
|
TyObjectSum(ty, bounds) => {
|
||||||
TyObjectSum(fld.fold_ty(ty),
|
TyObjectSum(fld.fold_ty(ty),
|
||||||
fld.fold_bounds(bounds))
|
fld.fold_bounds(bounds))
|
||||||
}
|
}
|
||||||
TyQPath(qpath) => {
|
|
||||||
TyQPath(fld.fold_qpath(qpath))
|
|
||||||
}
|
|
||||||
TyFixedLengthVec(ty, e) => {
|
TyFixedLengthVec(ty, e) => {
|
||||||
TyFixedLengthVec(fld.fold_ty(ty), fld.fold_expr(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.map(|qpath| {
|
||||||
QPath {
|
QPath {
|
||||||
self_type: fld.fold_ty(qpath.self_type),
|
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 {
|
item_path: PathSegment {
|
||||||
identifier: fld.fold_ident(qpath.item_path.identifier),
|
identifier: fld.fold_ident(qpath.item_path.identifier),
|
||||||
parameters: fld.fold_path_parameters(qpath.item_path.parameters),
|
parameters: fld.fold_path_parameters(qpath.item_path.parameters),
|
||||||
|
|
|
@ -1525,13 +1525,13 @@ impl<'a> Parser<'a> {
|
||||||
// QUALIFIED PATH `<TYPE as TRAIT_REF>::item`
|
// QUALIFIED PATH `<TYPE as TRAIT_REF>::item`
|
||||||
let self_type = self.parse_ty_sum();
|
let self_type = self.parse_ty_sum();
|
||||||
self.expect_keyword(keywords::As);
|
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::Gt);
|
||||||
self.expect(&token::ModSep);
|
self.expect(&token::ModSep);
|
||||||
let item_name = self.parse_ident();
|
let item_name = self.parse_ident();
|
||||||
TyQPath(P(QPath {
|
TyQPath(P(QPath {
|
||||||
self_type: self_type,
|
self_type: self_type,
|
||||||
trait_ref: P(trait_ref),
|
trait_path: trait_path,
|
||||||
item_path: ast::PathSegment {
|
item_path: ast::PathSegment {
|
||||||
identifier: item_name,
|
identifier: item_name,
|
||||||
parameters: ast::PathParameters::none()
|
parameters: ast::PathParameters::none()
|
||||||
|
@ -2220,7 +2220,7 @@ impl<'a> Parser<'a> {
|
||||||
// QUALIFIED PATH `<TYPE as TRAIT_REF>::item::<'a, T>`
|
// QUALIFIED PATH `<TYPE as TRAIT_REF>::item::<'a, T>`
|
||||||
let self_type = self.parse_ty_sum();
|
let self_type = self.parse_ty_sum();
|
||||||
self.expect_keyword(keywords::As);
|
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::Gt);
|
||||||
self.expect(&token::ModSep);
|
self.expect(&token::ModSep);
|
||||||
let item_name = self.parse_ident();
|
let item_name = self.parse_ident();
|
||||||
|
@ -2240,7 +2240,7 @@ impl<'a> Parser<'a> {
|
||||||
let hi = self.span.hi;
|
let hi = self.span.hi;
|
||||||
return self.mk_expr(lo, hi, ExprQPath(P(QPath {
|
return self.mk_expr(lo, hi, ExprQPath(P(QPath {
|
||||||
self_type: self_type,
|
self_type: self_type,
|
||||||
trait_ref: P(trait_ref),
|
trait_path: trait_path,
|
||||||
item_path: ast::PathSegment {
|
item_path: ast::PathSegment {
|
||||||
identifier: item_name,
|
identifier: item_name,
|
||||||
parameters: parameters
|
parameters: parameters
|
||||||
|
|
|
@ -2047,7 +2047,7 @@ impl<'a> State<'a> {
|
||||||
try!(self.print_type(&*qpath.self_type));
|
try!(self.print_type(&*qpath.self_type));
|
||||||
try!(space(&mut self.s));
|
try!(space(&mut self.s));
|
||||||
try!(self.word_space("as"));
|
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!(word(&mut self.s, "::"));
|
try!(word(&mut self.s, "::"));
|
||||||
try!(self.print_ident(qpath.item_path.identifier));
|
try!(self.print_ident(qpath.item_path.identifier));
|
||||||
|
|
|
@ -125,8 +125,8 @@ pub trait Visitor<'v> : Sized {
|
||||||
fn visit_path(&mut self, path: &'v Path, _id: ast::NodeId) {
|
fn visit_path(&mut self, path: &'v Path, _id: ast::NodeId) {
|
||||||
walk_path(self, path)
|
walk_path(self, path)
|
||||||
}
|
}
|
||||||
fn visit_qpath(&mut self, qpath_span: Span, qpath: &'v QPath) {
|
fn visit_qpath(&mut self, qpath: &'v QPath, _id: ast::NodeId) {
|
||||||
walk_qpath(self, qpath_span, qpath)
|
walk_qpath(self, qpath)
|
||||||
}
|
}
|
||||||
fn visit_path_segment(&mut self, path_span: Span, path_segment: &'v PathSegment) {
|
fn visit_path_segment(&mut self, path_span: Span, path_segment: &'v PathSegment) {
|
||||||
walk_path_segment(self, path_span, path_segment)
|
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) => {
|
TyPath(ref path) => {
|
||||||
visitor.visit_path(path, typ.id);
|
visitor.visit_path(path, typ.id);
|
||||||
}
|
}
|
||||||
|
TyQPath(ref qpath) => {
|
||||||
|
visitor.visit_qpath(&**qpath, typ.id);
|
||||||
|
}
|
||||||
TyObjectSum(ref ty, ref bounds) => {
|
TyObjectSum(ref ty, ref bounds) => {
|
||||||
visitor.visit_ty(&**ty);
|
visitor.visit_ty(&**ty);
|
||||||
walk_ty_param_bounds_helper(visitor, bounds);
|
walk_ty_param_bounds_helper(visitor, bounds);
|
||||||
}
|
}
|
||||||
TyQPath(ref qpath) => {
|
|
||||||
visitor.visit_qpath(typ.span, &**qpath);
|
|
||||||
}
|
|
||||||
TyFixedLengthVec(ref ty, ref expression) => {
|
TyFixedLengthVec(ref ty, ref expression) => {
|
||||||
visitor.visit_ty(&**ty);
|
visitor.visit_ty(&**ty);
|
||||||
visitor.visit_expr(&**expression)
|
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,
|
pub fn walk_qpath<'v, V: Visitor<'v>>(visitor: &mut V, qpath: &'v QPath) {
|
||||||
qpath_span: Span,
|
|
||||||
qpath: &'v QPath) {
|
|
||||||
visitor.visit_ty(&*qpath.self_type);
|
visitor.visit_ty(&*qpath.self_type);
|
||||||
visitor.visit_trait_ref(&*qpath.trait_ref);
|
walk_path(visitor, &qpath.trait_path);
|
||||||
visitor.visit_path_segment(qpath_span, &qpath.item_path);
|
visitor.visit_path_segment(qpath.trait_path.span, &qpath.item_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn walk_path_segment<'v, V: Visitor<'v>>(visitor: &mut V,
|
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)
|
visitor.visit_path(path, expression.id)
|
||||||
}
|
}
|
||||||
ExprQPath(ref qpath) => {
|
ExprQPath(ref qpath) => {
|
||||||
visitor.visit_qpath(expression.span, &**qpath)
|
visitor.visit_qpath(&**qpath, expression.id)
|
||||||
}
|
}
|
||||||
ExprBreak(_) | ExprAgain(_) => {}
|
ExprBreak(_) | ExprAgain(_) => {}
|
||||||
ExprRet(ref optional_expression) => {
|
ExprRet(ref optional_expression) => {
|
||||||
|
|
|
@ -12,5 +12,5 @@ use std::borrow::IntoCow;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
<String as IntoCow>::into_cow("foo".to_string());
|
<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)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue