diff options
| author | Eduard Burtescu <edy.burt@gmail.com> | 2015-02-05 09:19:07 +0200 |
|---|---|---|
| committer | Eduard Burtescu <edy.burt@gmail.com> | 2015-02-24 14:14:16 +0200 |
| commit | 5809f8ae746dbde96e0924b8e422b9e0d092375b (patch) | |
| tree | c9d4cc7863019b1f9955afad67d75345df2dc3bc | |
| parent | ffb8092ccf8dd186a9a03e6808d04a7276206793 (diff) | |
| download | rust-5809f8ae746dbde96e0924b8e422b9e0d092375b.tar.gz rust-5809f8ae746dbde96e0924b8e422b9e0d092375b.zip | |
rustc_resolve: use the visitor model more, remove redundant repeated lookups.
26 files changed, 335 insertions, 722 deletions
diff --git a/src/librustc/middle/astconv_util.rs b/src/librustc/middle/astconv_util.rs index d4680844838..d45c18efee7 100644 --- a/src/librustc/middle/astconv_util.rs +++ b/src/librustc/middle/astconv_util.rs @@ -35,55 +35,36 @@ pub fn check_path_args(tcx: &ty::ctxt, if (flags & NO_REGIONS) != 0 { if path.segments.iter().any(|s| s.parameters.has_lifetimes()) { span_err!(tcx.sess, path.span, E0110, - "region parameters are not allowed on this type"); + "lifetime parameters are not allowed on this type"); } } } pub fn ast_ty_to_prim_ty<'tcx>(tcx: &ty::ctxt<'tcx>, ast_ty: &ast::Ty) -> Option<Ty<'tcx>> { - match ast_ty.node { - ast::TyPath(ref path) => { - let a_def = match tcx.def_map.borrow().get(&ast_ty.id) { - None => { - tcx.sess.span_bug(ast_ty.span, - &format!("unbound path {}", - path.repr(tcx))) - } - Some(&d) => d - }; - match a_def { - def::DefPrimTy(nty) => { - match nty { - ast::TyBool => { - check_path_args(tcx, path, NO_TPS | NO_REGIONS); - Some(tcx.types.bool) - } - ast::TyChar => { - check_path_args(tcx, path, NO_TPS | NO_REGIONS); - Some(tcx.types.char) - } - ast::TyInt(it) => { - check_path_args(tcx, path, NO_TPS | NO_REGIONS); - Some(ty::mk_mach_int(tcx, it)) - } - ast::TyUint(uit) => { - check_path_args(tcx, path, NO_TPS | NO_REGIONS); - Some(ty::mk_mach_uint(tcx, uit)) - } - ast::TyFloat(ft) => { - check_path_args(tcx, path, NO_TPS | NO_REGIONS); - Some(ty::mk_mach_float(tcx, ft)) - } - ast::TyStr => { - Some(ty::mk_str(tcx)) - } - } - } - _ => None + if let ast::TyPath(ref path) = ast_ty.node { + let def = match tcx.def_map.borrow().get(&ast_ty.id) { + None => { + tcx.sess.span_bug(ast_ty.span, + &format!("unbound path {}", path.repr(tcx))) } + Some(&d) => d + }; + if let def::DefPrimTy(nty) = def { + check_path_args(tcx, path, NO_TPS | NO_REGIONS); + Some(match nty { + ast::TyBool => tcx.types.bool, + ast::TyChar => tcx.types.char, + ast::TyInt(it) => ty::mk_mach_int(tcx, it), + ast::TyUint(uit) => ty::mk_mach_uint(tcx, uit), + ast::TyFloat(ft) => ty::mk_mach_float(tcx, ft), + ast::TyStr => ty::mk_str(tcx) + }) + } else { + None } - _ => None + } else { + None } } diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index c4b874f7930..37586b08b36 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -456,9 +456,6 @@ impl tr for def::Def { } def::DefStruct(did) => def::DefStruct(did.tr(dcx)), def::DefRegion(nid) => def::DefRegion(dcx.tr_id(nid)), - def::DefTyParamBinder(nid) => { - def::DefTyParamBinder(dcx.tr_id(nid)) - } def::DefLabel(nid) => def::DefLabel(dcx.tr_id(nid)) } } diff --git a/src/librustc/middle/def.rs b/src/librustc/middle/def.rs index a341b55333f..191672775f2 100644 --- a/src/librustc/middle/def.rs +++ b/src/librustc/middle/def.rs @@ -54,7 +54,6 @@ pub enum Def { /// - If it's an ExprPath referring to some tuple struct, then DefMap maps /// it to a def whose id is the StructDef.ctor_id. DefStruct(ast::DefId), - DefTyParamBinder(ast::NodeId), /* struct, impl or trait with ty params */ DefRegion(ast::NodeId), DefLabel(ast::NodeId), DefMethod(ast::DefId /* method */, Option<ast::DefId> /* trait */, MethodProvenance), @@ -145,7 +144,6 @@ impl Def { DefSelfTy(id) | DefUpvar(id, _) | DefRegion(id) | - DefTyParamBinder(id) | DefLabel(id) => { local_def(id) } diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index d1fba421bbe..59e090a6037 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -580,7 +580,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> { } def::DefMod(_) | def::DefForeignMod(_) | def::DefUse(_) | def::DefTrait(_) | def::DefTy(..) | def::DefPrimTy(_) | - def::DefTyParam(..) | def::DefTyParamBinder(..) | def::DefRegion(_) | + def::DefTyParam(..) | def::DefRegion(_) | def::DefLabel(_) | def::DefSelfTy(..) | def::DefAssociatedTy(..) | def::DefAssociatedPath(..)=> { Ok(Rc::new(cmt_ { diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 7c6e537f0be..cc47090198b 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -23,10 +23,8 @@ use Namespace::{TypeNS, ValueNS}; use NameBindings; use ParentLink::{self, ModuleParentLink, BlockParentLink}; use Resolver; -use RibKind::*; use Shadowable; use TypeNsDef; -use TypeParameters::HasTypeParameters; use self::DuplicateCheckingMode::*; use self::NamespaceError::*; @@ -34,7 +32,6 @@ use self::NamespaceError::*; use rustc::metadata::csearch; use rustc::metadata::decoder::{DefLike, DlDef, DlField, DlImpl}; use rustc::middle::def::*; -use rustc::middle::subst::FnSpace; use syntax::ast::{Block, Crate}; use syntax::ast::{DeclItem, DefId}; @@ -773,12 +770,9 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> { } /// Constructs the reduced graph for one foreign item. - fn build_reduced_graph_for_foreign_item<F>(&mut self, - foreign_item: &ForeignItem, - parent: &Rc<Module>, - f: F) where - F: FnOnce(&mut Resolver), - { + fn build_reduced_graph_for_foreign_item(&mut self, + foreign_item: &ForeignItem, + parent: &Rc<Module>) { let name = foreign_item.ident.name; let is_public = foreign_item.vis == ast::Public; let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE; @@ -786,25 +780,15 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> { self.add_child(name, parent, ForbidDuplicateValues, foreign_item.span); - match foreign_item.node { - ForeignItemFn(_, ref generics) => { - let def = DefFn(local_def(foreign_item.id), false); - name_bindings.define_value(def, foreign_item.span, modifiers); - - self.with_type_parameter_rib( - HasTypeParameters(generics, - FnSpace, - foreign_item.id, - NormalRibKind), - f); + let def = match foreign_item.node { + ForeignItemFn(..) => { + DefFn(local_def(foreign_item.id), false) } ForeignItemStatic(_, m) => { - let def = DefStatic(local_def(foreign_item.id), m); - name_bindings.define_value(def, foreign_item.span, modifiers); - - f(self.resolver) + DefStatic(local_def(foreign_item.id), m) } - } + }; + name_bindings.define_value(def, foreign_item.span, modifiers); } fn build_reduced_graph_for_block(&mut self, block: &Block, parent: &Rc<Module>) -> Rc<Module> { @@ -980,7 +964,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> { } DefLocal(..) | DefPrimTy(..) | DefTyParam(..) | DefUse(..) | DefUpvar(..) | DefRegion(..) | - DefTyParamBinder(..) | DefLabel(..) | DefSelfTy(..) => { + DefLabel(..) | DefSelfTy(..) => { panic!("didn't expect `{:?}`", def); } } @@ -1241,16 +1225,7 @@ impl<'a, 'b, 'v, 'tcx> Visitor<'v> for BuildReducedGraphVisitor<'a, 'b, 'tcx> { } fn visit_foreign_item(&mut self, foreign_item: &ForeignItem) { - let parent = &self.parent; - self.builder.build_reduced_graph_for_foreign_item(foreign_item, - parent, - |r| { - let mut v = BuildReducedGraphVisitor { - builder: GraphBuilder { resolver: r }, - parent: parent.clone() - }; - visit::walk_foreign_item(&mut v, foreign_item); - }) + self.builder.build_reduced_graph_for_foreign_item(foreign_item, &self.parent); } fn visit_block(&mut self, block: &Block) { diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 6584e3cc19d..b211681992b 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -41,14 +41,12 @@ use self::ResolveResult::*; use self::FallbackSuggestion::*; use self::TypeParameters::*; use self::RibKind::*; -use self::MethodSort::*; use self::UseLexicalScopeFlag::*; use self::ModulePrefixResult::*; use self::NameSearchType::*; use self::BareIdentifierPatternResolution::*; use self::ParentLink::*; use self::ModuleKind::*; -use self::TraitReferenceType::*; use self::FallbackChecks::*; use rustc::session::Session; @@ -66,21 +64,18 @@ use rustc::util::lev_distance::lev_distance; use syntax::ast::{Arm, BindByRef, BindByValue, BindingMode, Block, Crate, CrateNum}; use syntax::ast::{DefId, Expr, ExprAgain, ExprBreak, ExprField}; -use syntax::ast::{ExprClosure, ExprLoop, ExprWhile, ExprMethodCall}; +use syntax::ast::{ExprLoop, ExprWhile, ExprMethodCall}; use syntax::ast::{ExprPath, ExprQPath, ExprStruct, FnDecl}; use syntax::ast::{ForeignItemFn, ForeignItemStatic, Generics}; use syntax::ast::{Ident, ImplItem, Item, ItemConst, ItemEnum, ItemExternCrate}; use syntax::ast::{ItemFn, ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic, ItemDefaultImpl}; use syntax::ast::{ItemStruct, ItemTrait, ItemTy, ItemUse}; -use syntax::ast::{Local, MethodImplItem, Mod, Name, NodeId}; +use syntax::ast::{Local, MethodImplItem, Name, NodeId}; use syntax::ast::{Pat, PatEnum, PatIdent, PatLit}; -use syntax::ast::{PatRange, PatStruct, Path}; -use syntax::ast::{PolyTraitRef, PrimTy, SelfExplicit}; -use syntax::ast::{RegionTyParamBound, StructField}; -use syntax::ast::{TraitRef, TraitTyParamBound}; -use syntax::ast::{Ty, TyBool, TyChar, TyF32}; -use syntax::ast::{TyF64, TyFloat, TyIs, TyI8, TyI16, TyI32, TyI64, TyInt, TyObjectSum}; -use syntax::ast::{TyParam, TyParamBound, TyPath, TyPtr, TyPolyTraitRef, TyQPath}; +use syntax::ast::{PatRange, PatStruct, Path, PrimTy}; +use syntax::ast::{TraitRef, Ty, TyBool, TyChar, TyF32}; +use syntax::ast::{TyF64, TyFloat, TyIs, TyI8, TyI16, TyI32, TyI64, TyInt}; +use syntax::ast::{TyPath, TyPtr, TyQPath}; use syntax::ast::{TyRptr, TyStr, TyUs, TyU8, TyU16, TyU32, TyU64, TyUint}; use syntax::ast::{TypeImplItem}; use syntax::ast; @@ -89,8 +84,7 @@ use syntax::ast_util::{PostExpansionMethod, local_def, walk_pat}; use syntax::attr::AttrMetaMethods; use syntax::ext::mtwt; use syntax::parse::token::{self, special_names, special_idents}; -use syntax::codemap::{Span, Pos}; -use syntax::owned_slice::OwnedSlice; +use syntax::codemap::{self, Span, Pos}; use syntax::visit::{self, Visitor}; use std::collections::{HashMap, HashSet}; @@ -188,6 +182,72 @@ impl<'a, 'v, 'tcx> Visitor<'v> for Resolver<'a, 'tcx> { fn visit_ty(&mut self, ty: &Ty) { self.resolve_type(ty); } + fn visit_generics(&mut self, generics: &Generics) { + self.resolve_generics(generics); + } + fn visit_poly_trait_ref(&mut self, + tref: &ast::PolyTraitRef, + m: &ast::TraitBoundModifier) { + match self.resolve_trait_reference(tref.trait_ref.ref_id, &tref.trait_ref.path, 0) { + Ok(def) => self.record_def(tref.trait_ref.ref_id, def), + Err(_) => { /* error already reported */ } + } + visit::walk_poly_trait_ref(self, tref, m); + } + fn visit_variant(&mut self, variant: &ast::Variant, generics: &Generics) { + if let Some(ref dis_expr) = variant.node.disr_expr { + // resolve the discriminator expr as a constant + self.with_constant_rib(|this| { + this.visit_expr(&**dis_expr); + }); + } + + // `visit::walk_variant` without the discriminant expression. + match variant.node.kind { + ast::TupleVariantKind(ref variant_arguments) => { + for variant_argument in variant_arguments.iter() { + self.visit_ty(&*variant_argument.ty); + } + } + ast::StructVariantKind(ref struct_definition) => { + self.visit_struct_def(&**struct_definition, + variant.node.name, + generics, + variant.node.id); + } + } + } + fn visit_foreign_item(&mut self, foreign_item: &ast::ForeignItem) { + let type_parameters = match foreign_item.node { + ForeignItemFn(_, ref generics) => { + HasTypeParameters(generics, FnSpace, ItemRibKind) + } + ForeignItemStatic(..) => NoTypeParameters + }; + self.with_type_parameter_rib(type_parameters, |this| { + visit::walk_foreign_item(this, foreign_item); + }); + } + fn visit_fn(&mut self, + function_kind: visit::FnKind<'v>, + declaration: &'v FnDecl, + block: &'v Block, + _: Span, + node_id: NodeId) { + let rib_kind = match function_kind { + visit::FkItemFn(_, generics, _, _) => { + self.visit_generics(generics); + ItemRibKind + } + visit::FkMethod(_, generics, method) => { + self.visit_generics(generics); + self.visit_explicit_self(method.pe_explicit_self()); + MethodRibKind + } + visit::FkFnBlock(..) => ClosureRibKind(node_id) + }; + self.resolve_function(rib_kind, declaration, block); + } } /// Contains data for specific types of import directives. @@ -231,9 +291,6 @@ enum TypeParameters<'a> { // were declared on (type, fn, etc) ParamSpace, - // ID of the enclosing item. - NodeId, - // The kind of the rib used for type parameters. RibKind) } @@ -253,8 +310,7 @@ enum RibKind { // methods. Allow references to ty params that impl or trait // binds. Disallow any other upvars (including other ty params that are // upvars). - // parent; method itself - MethodRibKind(NodeId, MethodSort), + MethodRibKind, // We passed through an item scope. Disallow upvars. ItemRibKind, @@ -263,13 +319,6 @@ enum RibKind { ConstantItemRibKind } -// Methods can be required or provided. RequiredMethod methods only occur in traits. -#[derive(Copy, Debug)] -enum MethodSort { - RequiredMethod, - ProvidedMethod(NodeId) -} - #[derive(Copy)] enum UseLexicalScopeFlag { DontUseLexicalScope, @@ -586,16 +635,6 @@ struct NameBindings { value_def: RefCell<Option<ValueNsDef>>, //< Meaning in value namespace. } -/// Ways in which a trait can be referenced -#[derive(Copy)] -enum TraitReferenceType { - TraitImplementation, // impl SomeTrait for T { ... } - TraitDerivation, // trait T : SomeTrait { ... } - TraitBoundingTypeParameter, // fn f<T:SomeTrait>() { ... } - TraitObject, // Box<for<'a> SomeTrait> - TraitQPath, // <T as SomeTrait>:: -} - impl NameBindings { fn new() -> NameBindings { NameBindings { @@ -2600,14 +2639,16 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { def_like: DefLike, span: Span) -> Option<DefLike> { - match def_like { - DlDef(d @ DefUpvar(..)) => { + let mut def = match def_like { + DlDef(def) => def, + _ => return Some(def_like) + }; + match def { + DefUpvar(..) => { self.session.span_bug(span, - &format!("unexpected {:?} in bindings", d)) + &format!("unexpected {:?} in bindings", def)) } - DlDef(d @ DefLocal(_)) => { - let node_id = d.def_id().node; - let mut def = d; + DefLocal(node_id) => { for rib in ribs { match rib.kind { NormalRibKind => { @@ -2631,39 +2672,14 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { }.push(Freevar { def: prev_def, span: span }); seen.insert(node_id); } - MethodRibKind(item_id, _) => { - // If the def is a ty param, and came from the parent - // item, it's ok - match def { - DefTyParam(_, _, did, _) if { - self.def_map.borrow().get(&did.node).cloned() - == Some(DefTyParamBinder(item_id)) - } => {} // ok - DefSelfTy(did) if did == item_id => {} // ok - _ => { - // This was an attempt to access an upvar inside a - // named function item. This is not allowed, so we - // report an error. - - self.resolve_error( - span, - "can't capture dynamic environment in a fn item; \ - use the || { ... } closure form instead"); - - return None; - } - } - } - ItemRibKind => { + ItemRibKind | MethodRibKind => { // This was an attempt to access an upvar inside a // named function item. This is not allowed, so we // report an error. - self.resolve_error( - span, + self.resolve_error(span, "can't capture dynamic environment in a fn item; \ - use the || { ... } closure form instead"); - + use the || { ... } closure form instead"); return None; } ConstantItemRibKind => { @@ -2671,42 +2687,17 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { self.resolve_error(span, "attempt to use a non-constant \ value in a constant"); - + return None; } } } - Some(DlDef(def)) } - DlDef(def @ DefTyParam(..)) | - DlDef(def @ DefSelfTy(..)) => { + DefTyParam(..) | DefSelfTy(_) => { for rib in ribs { match rib.kind { - NormalRibKind | ClosureRibKind(..) => { + NormalRibKind | MethodRibKind | ClosureRibKind(..) => { // Nothing to do. Continue. } - MethodRibKind(item_id, _) => { - // If the def is a ty param, and came from the parent - // item, it's ok - match def { - DefTyParam(_, _, did, _) if { - self.def_map.borrow().get(&did.node).cloned() - == Some(DefTyParamBinder(item_id)) - } => {} // ok - DefSelfTy(did) if did == item_id => {} // ok - - _ => { - // This was an attempt to use a type parameter outside - // its scope. - - self.resolve_error(span, - "can't use type parameters from \ - outer function; try using a local \ - type parameter instead"); - - return None; - } - } - } ItemRibKind => { // This was an attempt to use a type parameter outside // its scope. @@ -2715,7 +2706,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { "can't use type parameters from \ outer function; try using a local \ type parameter instead"); - return None; } ConstantItemRibKind => { @@ -2723,14 +2713,14 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { self.resolve_error(span, "cannot use an outer type \ parameter in this context"); - + return None; } } } - Some(DlDef(def)) } - _ => Some(def_like) + _ => {} } + Some(DlDef(def)) } /// Searches the current set of local scopes and @@ -2743,13 +2733,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // FIXME #4950: Try caching? for (i, rib) in ribs.iter().enumerate().rev() { - match rib.bindings.get(&name).cloned() { - Some(def_like) => { - return self.upvarify(&ribs[i + 1..], def_like, span); - } - None => { - // Continue. - } + if let Some(def_like) = rib.bindings.get(&name).cloned() { + return self.upvarify(&ribs[i + 1..], def_like, span); } } @@ -2797,47 +2782,21 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { token::get_name(name)); match item.node { - - // enum item: resolve all the variants' discrs, - // then resolve the ty params - ItemEnum(ref enum_def, ref generics) => { + ItemEnum(_, ref generics) | + ItemTy(_, ref generics) | + ItemStruct(_, ref generics) => { self.check_if_primitive_type_name(name, item.span); - for variant in &(*enum_def).variants { - if let Some(ref dis_expr) = variant.node.disr_expr { - // resolve the discriminator expr - // as a constant - self.with_constant_rib(|this| { - this.resolve_expr(&**dis_expr); - }); - } - } - - // n.b. the discr expr gets visited twice. - // but maybe it's okay since the first time will signal an - // error if there is one? -- tjc self.with_type_parameter_rib(HasTypeParameters(generics, TypeSpace, - item.id, ItemRibKind), - |this| { - this.resolve_type_parameters(&generics.ty_params); - this.resolve_where_clause(&generics.where_clause); - visit::walk_item(this, item); - }); + |this| visit::walk_item(this, item)); } - - ItemTy(_, ref generics) => { - self.check_if_primitive_type_name(name, item.span); - + ItemFn(_, _, _, ref generics, _) => { self.with_type_parameter_rib(HasTypeParameters(generics, - TypeSpace, - item.id, + FnSpace, ItemRibKind), - |this| { - this.resolve_type_parameters(&generics.ty_params); - visit::walk_item(this, item); - }); + |this| visit::walk_item(this, item)); } ItemDefaultImpl(_, ref trait_ref) => { @@ -2848,8 +2807,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { ref implemented_traits, ref self_type, ref impl_items) => { - self.resolve_implementation(item.id, - generics, + self.resolve_implementation(generics, implemented_traits, &**self_type, &impl_items[..]); @@ -2869,13 +2827,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // Create a new rib for the trait-wide type parameters. self.with_type_parameter_rib(HasTypeParameters(generics, TypeSpace, - item.id, NormalRibKind), |this| { - this.resolve_type_parameters(&generics.ty_params); - this.resolve_where_clause(&generics.where_clause); - - this.resolve_type_parameter_bounds(bounds, TraitDerivation); + this.visit_generics(generics); + visit::walk_ty_param_bounds_helper(this, bounds); for trait_item in &(*trait_items) { // Create a new rib for the trait_item-specific type @@ -2883,101 +2838,34 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // // FIXME #4951: Do we need a node ID here? - match *trait_item { - ast::RequiredMethod(ref ty_m) => { - this.with_type_parameter_rib - (HasTypeParameters(&ty_m.generics, - FnSpace, - item.id, - MethodRibKind(item.id, RequiredMethod)), - |this| { - - // Resolve the method-specific type - // parameters. - this.resolve_type_parameters( - &ty_m.generics.ty_params); - this.resolve_where_clause(&ty_m.generics - .where_clause); - - for argument in &ty_m.decl.inputs { - this.resolve_type(&*argument.ty); - } - - if let SelfExplicit(ref typ, _) = ty_m.explicit_self.node { - this.resolve_type(&**typ) - } - - if let ast::Return(ref ret_ty) = ty_m.decl.output { - this.resolve_type(&**ret_ty); - } - }); - } - ast::ProvidedMethod(ref m) => { - this.resolve_method(MethodRibKind(item.id, - ProvidedMethod(m.id)), - &**m) - } - ast::TypeTraitItem(ref data) => { - this.resolve_type_parameter(&data.ty_param); - visit::walk_trait_item(this, trait_item); - } - } + let type_parameters = match *trait_item { + ast::RequiredMethod(ref ty_m) => { + HasTypeParameters(&ty_m.generics, + FnSpace, + MethodRibKind) + } + ast::ProvidedMethod(ref m) => { + HasTypeParameters(m.pe_generics(), + FnSpace, + MethodRibKind) + } + ast::TypeTraitItem(_) => NoTypeParameters, + }; + this.with_type_parameter_rib(type_parameters, |this| { + visit::walk_trait_item(this, trait_item) + }); } }); self.type_ribs.pop(); } - ItemStruct(ref struct_def, ref generics) => { - self.check_if_primitive_type_name(name, item.span); - - self.resolve_struct(item.id, - generics, - &struct_def.fields); - } - - ItemMod(ref module_) => { + ItemMod(_) | ItemForeignMod(_) => { self.with_scope(Some(name), |this| { - this.resolve_module(module_, item.span, name, - item.id); - }); - } - - ItemForeignMod(ref foreign_module) => { - self.with_scope(Some(name), |this| { - for foreign_item in &foreign_module.items { - match foreign_item.node { - ForeignItemFn(_, ref generics) => { - this.with_type_parameter_rib( - HasTypeParameters( - generics, FnSpace, foreign_item.id, - ItemRibKind), - |this| { - this.resolve_type_parameters(&generics.ty_params); - this.resolve_where_clause(&generics.where_clause); - visit::walk_foreign_item(this, &**foreign_item) - }); - } - ForeignItemStatic(..) => { - visit::walk_foreign_item(this, - &**foreign_item); - } - } - } + visit::walk_item(this, item); }); } - ItemFn(ref fn_decl, _, _, ref generics, ref block) => { - self.resolve_function(ItemRibKind, - Some(&**fn_decl), - HasTypeParameters - (generics, - FnSpace, - item.id, - ItemRibKind), - &**block); - } - ItemConst(..) | ItemStatic(..) => { self.with_constant_rib(|this| { visit::walk_item(this, item); @@ -3006,35 +2894,29 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { F: FnOnce(&mut Resolver), { match type_parameters { - HasTypeParameters(generics, space, node_id, rib_kind) => { + HasTypeParameters(generics, space, rib_kind) => { let mut function_type_rib = Rib::new(rib_kind); let mut seen_bindings = HashSet::new(); for (index, type_parameter) in generics.ty_params.iter().enumerate() { let name = type_parameter.ident.name; - debug!("with_type_parameter_rib: {} {}", node_id, - type_parameter.id); + debug!("with_type_parameter_rib: {}", type_parameter.id); if seen_bindings.contains(&name) { self.resolve_error(type_parameter.span, &format!("the name `{}` is already \ - used for a type \ - parameter in this type \ - parameter list", - token::get_name( - name))) + used for a type \ + parameter in this type \ + parameter list", + token::get_name(name))) } seen_bindings.insert(name); - let def_like = DlDef(DefTyParam(space, - index as u32, - local_def(type_parameter.id), - name)); - // Associate this type parameter with - // the item that bound it - self.record_def(type_parameter.id, - (DefTyParamBinder(node_id), LastMod(AllPublic))); // plain insert (no renaming) - function_type_rib.bindings.insert(name, def_like); + function_type_rib.bindings.insert(name, + DlDef(DefTyParam(space, + index as u32, + local_def(type_parameter.id), + name))); } self.type_ribs.push(function_type_rib); } @@ -3072,154 +2954,74 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { fn resolve_function(&mut self, rib_kind: RibKind, - optional_declaration: Option<&FnDecl>, - type_parameters: TypeParameters, + declaration: &FnDecl, block: &Block) { // Create a value rib for the function. - let function_value_rib = Rib::new(rib_kind); - self.value_ribs.push(function_value_rib); + self.value_ribs.push(Rib::new(rib_kind)); // Create a label rib for the function. - let function_label_rib = Rib::new(rib_kind); - self.label_ribs.push(function_label_rib); - - // If this function has type parameters, add them now. - self.with_type_parameter_rib(type_parameters, |this| { - // Resolve the type parameters. - match type_parameters { - NoTypeParameters => { - // Continue. - } - HasTypeParameters(ref generics, _, _, _) => { - this.resolve_type_parameters(&generics.ty_params); - this.resolve_where_clause(&generics.where_clause); - } - } + self.label_ribs.push(Rib::new(rib_kind)); - // Add each argument to the rib. - match optional_declaration { - None => { - // Nothing to do. - } - Some(declaration) => { - let mut bindings_list = HashMap::new(); - for argument in &declaration.inputs { - this.resolve_pattern(&*argument.pat, - ArgumentIrrefutableMode, - &mut bindings_list); - - this.resolve_type(&*argument.ty); + // Add each argument to the rib. + let mut bindings_list = HashMap::new(); + for argument in &declaration.inputs { + self.resolve_pattern(&*argument.pat, + ArgumentIrrefutableMode, + &mut bindings_list); - debug!("(resolving function) recorded argument"); - } + self.visit_ty(&*argument.ty); - if let ast::Return(ref ret_ty) = declaration.output { - this.resolve_type(&**ret_ty); - } - } - } + debug!("(resolving function) recorded argument"); + } + visit::walk_fn_ret_ty(self, &declaration.output); - // Resolve the function body. - this.resolve_block(&*block); + // Resolve the function body. + self.visit_block(&*block); - debug!("(resolving function) leaving function"); - }); + debug!("(resolving function) leaving function"); self.label_ribs.pop(); self.value_ribs.pop(); } - fn resolve_type_parameters(&mut self, - type_parameters: &OwnedSlice<TyParam>) { - for type_parameter in &**type_parameters { - self.resolve_type_parameter(type_parameter); - } - } - - 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(bound, TraitBoundingTypeParameter); - } - match type_parameter.default { - Some(ref ty) => self.resolve_type(&**ty), - None => {} - } - } - - fn resolve_type_parameter_bounds(&mut self, - type_parameter_bounds: &OwnedSlice<TyParamBound>, - reference_type: TraitReferenceType) { - for type_parameter_bound in &**type_parameter_bounds { - self.resolve_type_parameter_bound(type_parameter_bound, reference_type); - } - } - - fn resolve_type_parameter_bound(&mut self, - type_parameter_bound: &TyParamBound, - reference_type: TraitReferenceType) { - match *type_parameter_bound { - TraitTyParamBound(ref tref, _) => { - self.resolve_trait_reference(tref.trait_ref.ref_id, - &tref.trait_ref.path, 0, - reference_type) - } - RegionTyParamBound(..) => {} - } - } - fn resolve_trait_reference(&mut self, id: NodeId, trait_path: &Path, - path_depth: usize, - reference_type: TraitReferenceType) { + path_depth: usize) + -> Result<(Def, LastPrivate), ()> { match self.resolve_path(id, trait_path, path_depth, TypeNS, true) { - None => { - let path_str = self.path_names_to_string(trait_path, path_depth); - let usage_str = match reference_type { - TraitBoundingTypeParameter => "bound type parameter with", - TraitImplementation => "implement", - TraitDerivation => "derive", - TraitObject => "reference", - TraitQPath => "extract an associated item from", - }; - - let msg = format!("attempt to {} a nonexistent trait `{}`", usage_str, path_str); - self.resolve_error(trait_path.span, &msg[..]); - } - Some(def) => { - match def { - (DefTrait(_), _) => { - debug!("(resolving trait) found trait def: {:?}", def); - self.record_def(id, def); - } - (def, _) => { - self.resolve_error(trait_path.span, - &format!("`{}` is not a trait", - self.path_names_to_string(trait_path, path_depth))); - - // If it's a typedef, give a note - if let DefTy(..) = def { - self.session.span_note(trait_path.span, - &format!("`type` aliases cannot be used for traits")); - } - } + Some(def @ (DefTrait(_), _)) => { + debug!("(resolving trait) found trait def: {:?}", def); + Ok(def) + } + Some((def, _)) => { + self.resolve_error(trait_path.span, + &format!("`{}` is not a trait", + self.path_names_to_string(trait_path, path_depth))); + + // If it's a typedef, give a note + if let DefTy(..) = def { + self.session.span_note(trait_path.span, + "`type` aliases cannot be used for traits"); } + Err(()) + } + None => { + let msg = format!("use of undeclared trait name `{}`", + self.path_names_to_string(trait_path, path_depth)); + self.resolve_error(trait_path.span, &msg[]); + Err(()) } } } - fn resolve_where_clause(&mut self, where_clause: &ast::WhereClause) { - for predicate in &where_clause.predicates { + fn resolve_generics(&mut self, generics: &Generics) { + for type_parameter in &generics.ty_params { + self.check_if_primitive_type_name(type_parameter.ident.name, type_parameter.span); + } + for predicate in &generics.where_clause.predicates { match predicate { - &ast::WherePredicate::BoundPredicate(ref bound_pred) => { - self.resolve_type(&*bound_pred.bounded_ty); - - for bound in &*bound_pred.bounds { - self.resolve_type_parameter_bound(bound, TraitBoundingTypeParameter); - } - } + &ast::WherePredicate::BoundPredicate(_) | &ast::WherePredicate::RegionPredicate(_) => {} &ast::WherePredicate::EqPredicate(ref eq_pred) => { match self.resolve_path(eq_pred.id, &eq_pred.path, 0, TypeNS, true) { @@ -3231,53 +3033,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { "undeclared associated type"); } } - - self.resolve_type(&*eq_pred.ty); } } } - } - - fn resolve_struct(&mut self, - id: NodeId, - generics: &Generics, - fields: &[StructField]) { - // If applicable, create a rib for the type parameters. - self.with_type_parameter_rib(HasTypeParameters(generics, - TypeSpace, - id, - ItemRibKind), - |this| { - // Resolve the type parameters. - this.resolve_type_parameters(&generics.ty_params); - this.resolve_where_clause(&generics.where_clause); - - // Resolve fields. - for field in fields { - this.resolve_type(&*field.node.ty); - } - }); - } - - // Does this really need to take a RibKind or is it always going - // to be NormalRibKind? - fn resolve_method(&mut self, - rib_kind: RibKind, - method: &ast::Method) { - let method_generics = method.pe_generics(); - let type_parameters = HasTypeParameters(method_generics, - FnSpace, - method.id, - rib_kind); - - if let SelfExplicit(ref typ, _) = method.pe_explicit_self().node { - self.resolve_type(&**typ); - } - - self.resolve_function(rib_kind, - Some(method.pe_fn_decl()), - type_parameters, - method.pe_body()); + visit::walk_generics(self, generics); } fn with_current_self_type<T, F>(&mut self, self_type: &Ty, f: F) -> T where @@ -3295,22 +3054,17 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { f: F) -> T where F: FnOnce(&mut Resolver) -> T, { - let new_val = match *opt_trait_ref { - Some(ref trait_ref) => { - self.resolve_trait_reference(trait_ref.ref_id, - &trait_ref.path, 0, - TraitImplementation); - - match self.def_map.borrow().get(&trait_ref.ref_id) { - Some(def) => { - let did = def.def_id(); - Some((did, trait_ref.clone())) - } - None => None + let mut new_val = None; + if let Some(ref trait_ref) = *opt_trait_ref { + match self.resolve_trait_reference(trait_ref.ref_id, &trait_ref.path, 0) { + Ok(def) => { + self.record_def(trait_ref.ref_id, def); + new_val = Some((def.0.def_id(), trait_ref.clone())); } + Err(_) => { /* error was already reported */ } } - None => None - }; + visit::walk_trait_ref(self, trait_ref); + } let original_trait_ref = replace(&mut self.current_trait_ref, new_val); let result = f(self); self.current_trait_ref = original_trait_ref; @@ -3318,7 +3072,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } fn resolve_implementation(&mut self, - id: NodeId, generics: &Generics, opt_trait_reference: &Option<TraitRef>, self_type: &Ty, @@ -3326,17 +3079,15 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // If applicable, create a rib for the type parameters. self.with_type_parameter_rib(HasTypeParameters(generics, TypeSpace, - id, - NormalRibKind), + ItemRibKind), |this| { // Resolve the type parameters. - this.resolve_type_parameters(&generics.ty_params); - this.resolve_where_clause(&generics.where_clause); + this.visit_generics(generics); // Resolve the trait reference, if necessary. this.with_optional_trait_ref(opt_trait_reference, |this| { // Resolve the self type. - this.resolve_type(self_type); + this.visit_ty(self_type); this.with_current_self_type(self_type, |this| { for impl_item in impl_items { @@ -3349,9 +3100,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // We also need a new scope for the method- // specific type parameters. - this.resolve_method( - MethodRibKind(id, ProvidedMethod(method.id)), - &**method); + let type_parameters = + HasTypeParameters(method.pe_generics(), + FnSpace, + MethodRibKind); + this.with_type_parameter_rib(type_parameters, |this| { + visit::walk_method_helper(this, &**method); + }); } TypeImplItem(ref typedef) => { // If this is a trait impl, ensure the method @@ -3359,7 +3114,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { this.check_trait_item(typedef.ident.name, typedef.span); - this.resolve_type(&*typedef.typ); + this.visit_ty(&*typedef.typ); } } } @@ -3405,34 +3160,17 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } } - fn resolve_module(&mut self, module: &Mod, _span: Span, - _name: Name, id: NodeId) { - // Write the implementations in scope into the module metadata. - debug!("(resolving module) resolving module ID {}", id); - visit::walk_mod(self, module); - } - fn resolve_local(&mut self, local: &Local) { // Resolve the type. - if let Some(ref ty) = local.ty { - self.resolve_type(&**ty); - } + visit::walk_ty_opt(self, &local.ty); - // Resolve the initializer, if necessary. - match local.init { - None => { - // Nothing to do. - } - Some(ref initializer) => { - self.resolve_expr(&**initializer); - } - } + // Resolve the initializer. + visit::walk_expr_opt(self, &local.init); // Resolve the pattern. - let mut bindings_list = HashMap::new(); self.resolve_pattern(&*local.pat, LocalIrrefutableMode, - &mut bindings_list); + &mut HashMap::new()); } // build a map from pattern identifiers to binding-info's. @@ -3510,7 +3248,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { self.check_consistent_bindings(arm); visit::walk_expr_opt(self, &arm.guard); - self.resolve_expr(&*arm.body); + self.visit_expr(&*arm.body); self.value_ribs.pop(); } @@ -3566,49 +3304,14 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // on whether the path has multiple elements in it or not. TyPath(ref path) | TyQPath(ast::QPath { ref path, .. }) => { - if let TyQPath(ref qpath) = ty.node { - self.resolve_type(&*qpath.self_type); - - // Just make sure the trait is valid, don't record a def. - self.resolve_trait_reference(ty.id, path, 1, TraitQPath); - self.def_map.borrow_mut().remove(&ty.id); + if let TyQPath(_) = ty.node { + // Make sure the trait is valid. + self.resolve_trait_reference(ty.id, path, 1); } // This is a path in the type namespace. Walk through scopes // looking for it. - let mut result_def = None; - - // First, check to see whether the name is a primitive type. - if path.segments.len() == 1 { - let id = path.segments.last().unwrap().identifier; - - match self.primitive_type_table - .primitive_types - .get(&id.name) { - - Some(&primitive_type) => { - result_def = - Some((DefPrimTy(primitive_type), LastMod(AllPublic))); - - if path.segments[0].parameters.has_lifetimes() { - span_err!(self.session, path.span, E0157, - "lifetime parameters are not allowed on this type"); - } else if !path.segments[0].parameters.is_empty() { - span_err!(self.session, path.span, E0153, - "type parameters are not allowed on this type"); - } - } - None => { - // Continue. - } - } - } - - if let None = result_def { - result_def = self.resolve_path(ty.id, path, 0, TypeNS, true); - } - - match result_def { + match self.resolve_path(ty.id, path, 0, TypeNS, true) { Some(def) => { // Write the result into the def map. debug!("(resolving type) writing resolution for `{}` \ @@ -3628,21 +3331,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } } } - - TyObjectSum(ref ty, ref bound_vec) => { - self.resolve_type(&**ty); - self.resolve_type_parameter_bounds(bound_vec, TraitBoundingTypeParameter); - } - - TyPolyTraitRef(ref bounds) => { - self.resolve_type_parameter_bounds(bounds, TraitObject); - visit::walk_ty(self, ty); - } - _ => { - // Just resolve embedded types. - visit::walk_ty(self, ty); - } + _ => {} } + // Resolve embedded types. + visit::walk_ty(self, ty); } fn resolve_pattern(&mut self, @@ -3669,7 +3361,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let renamed = mtwt::resolve(ident); match self.resolve_bare_identifier_pattern(ident.name, pattern.span) { - FoundStructOrEnumVariant(ref def, lp) + FoundStructOrEnumVariant(def, lp) if mode == RefutableMode => { debug!("(resolving pattern) resolving `{}` to \ struct or enum variant", @@ -3679,7 +3371,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { pattern, binding_mode, "an enum variant"); - self.record_def(pattern.id, (def.clone(), lp)); + self.record_def(pattern.id, (def, lp)); } FoundStructOrEnumVariant(..) => { self.resolve_error( @@ -3689,7 +3381,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { scope", token::get_name(renamed))); } - FoundConst(ref def, lp) if mode == RefutableMode => { + FoundConst(def, lp) if mode == RefutableMode => { debug!("(resolving pattern) resolving `{}` to \ constant", token::get_name(renamed)); @@ -3698,7 +3390,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { pattern, binding_mode, "a constant"); - self.record_def(pattern.id, (def.clone(), lp)); + self.record_def(pattern.id, (def, lp)); } FoundConst(..) => { self.resolve_error(pattern.span, @@ -3782,22 +3474,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { token::get_ident(path.segments.last().unwrap().identifier))); } } - - // Check the types in the path pattern. - for ty in path.segments - .iter() - .flat_map(|s| s.parameters.types().into_iter()) { - self.resolve_type(&**ty); - } - } - - PatLit(ref expr) => { - self.resolve_expr(&**expr); - } - - PatRange(ref first_expr, ref last_expr) => { - self.resolve_expr(&**first_expr); - self.resolve_expr(&**last_expr); + visit::walk_path(self, path); } PatStruct(ref path, _, _) => { @@ -3813,6 +3490,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { self.resolve_error(path.span, &msg[..]); } } + visit::walk_path(self, path); + } + + PatLit(_) | PatRange(..) => { + visit::walk_pat(self, pattern); } _ => { @@ -3895,14 +3577,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let span = path.span; let segments = &path.segments[..path.segments.len()-path_depth]; - // First, resolve the types and associated type bindings. - for ty in segments.iter().flat_map(|s| s.parameters.types().into_iter()) { - self.resolve_type(&**ty); - } - for binding in segments.iter().flat_map(|s| s.parameters.bindings().into_iter()) { - self.resolve_type(&*binding.ty); - } - // A special case for sugared associated type paths `T::A` where `T` is // a type parameter and `A` is an associated type on some bound of `T`. if namespace == TypeNS && segments.len() == 2 { @@ -3957,7 +3631,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { return def; } - return unqualified_def; + unqualified_def } // resolve a single identifier (used as a varref) @@ -3967,20 +3641,24 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { check_ribs: bool, span: Span) -> Option<(Def, LastPrivate)> { + // First, check to see whether the name is a primitive type. + if namespace == TypeNS { + if let Some(&prim_ty) = self.primitive_type_table + .primitive_types + .get(&identifier.name) { + return Some((DefPrimTy(prim_ty), LastMod(AllPublic))); + } + } + if check_ribs { - match self.resolve_identifier_in_local_ribs(identifier, - namespace, - span) { - Some(def) => { - return Some((def, LastMod(AllPublic))); - } - None => { - // Continue. - } + if let Some(def) = self.resolve_identifier_in_local_ribs(identifier, + namespace, + span) { + return Some((def, LastMod(AllPublic))); } } - return self.resolve_item_by_name_in_lexical_scope(identifier.name, namespace); + self.resolve_item_by_name_in_lexical_scope(identifier.name, namespace) } // FIXME #4952: Merge me with resolve_name_in_module? @@ -4197,10 +3875,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { local: {:?}", token::get_ident(ident), def); - return Some(def); + Some(def) } Some(DlField) | Some(DlImpl(_)) | None => { - return None; + None } } } @@ -4425,12 +4103,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // multiple elements in it or not. ExprPath(ref path) | ExprQPath(ast::QPath { ref path, .. }) => { - if let ExprQPath(ref qpath) = expr.node { - self.resolve_type(&*qpath.self_type); - - // Just make sure the trait is valid, don't record a def. - self.resolve_trait_reference(expr.id, path, 1, TraitQPath); - self.def_map.borrow_mut().remove(&expr.id); + if let ExprQPath(_) = expr.node { + // Make sure the trait is valid. + self.resolve_trait_reference(expr.id, path, 1); } // This is a local path in the value namespace. Walk through @@ -4482,13 +4157,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { _ => { let mut method_scope = false; self.value_ribs.iter().rev().all(|rib| { - let res = match *rib { - Rib { bindings: _, kind: MethodRibKind(_, _) } => true, - Rib { bindings: _, kind: ItemRibKind } => false, + method_scope = match rib.kind { + MethodRibKind => true, + ItemRibKind | ConstantItemRibKind => false, _ => return true, // Keep advancing }; - - method_scope = res; false // Stop advancing }); @@ -4537,21 +4210,14 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { visit::walk_expr(self, expr); } - ExprClosure(_, ref fn_decl, ref block) => { - self.resolve_function(ClosureRibKind(expr.id), - Some(&**fn_decl), NoTypeParameters, - &**block); - } - ExprStruct(ref path, _, _) => { // Resolve the path to the structure it goes to. We don't // check to ensure that the path is actually a structure; that // is checked later during typeck. match self.resolve_path(expr.id, path, 0, TypeNS, false) { Some(definition) => self.record_def(expr.id, definition), - result => { - debug!("(resolving expression) didn't find struct \ - def: {:?}", result); + None => { + debug!("(resolving expression) didn't find struct def",); let msg = format!("`{}` does not name a structure", self.path_names_to_string(path, 0)); self.resolve_error(path.span, &msg[..]); @@ -4704,26 +4370,20 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { found_traits } - fn record_def(&mut self, node_id: NodeId, (def, lp): (Def, LastPrivate)) { + fn record_def(&mut self, + node_id: NodeId, + (def, lp): (Def, LastPrivate)) { debug!("(recording def) recording {:?} for {}, last private {:?}", def, node_id, lp); assert!(match lp {LastImport{..} => false, _ => true}, "Import should only be used for `use` directives"); self.last_private.insert(node_id, lp); - match self.def_map.borrow_mut().entry(node_id) { - // Resolve appears to "resolve" the same ID multiple - // times, so here is a sanity check it at least comes to - // the same conclusion! - nmatsakis - Occupied(entry) => if def != *entry.get() { - self.session - .bug(&format!("node_id {} resolved first to {:?} and \ - then {:?}", - node_id, - *entry.get(), - def)); - }, - Vacant(entry) => { entry.insert(def); }, + if let Some(prev_def) = self.def_map.borrow_mut().insert(node_id, def) { + let span = self.ast_map.opt_span(node_id).unwrap_or(codemap::DUMMY_SP); + self.session.span_bug(span, &format!("path resolved multiple times \ + ({:?} before, {:?} now)", + prev_def, def)); } } diff --git a/src/librustc_trans/save/mod.rs b/src/librustc_trans/save/mod.rs index 6a20938da2e..531700b9563 100644 --- a/src/librustc_trans/save/mod.rs +++ b/src/librustc_trans/save/mod.rs @@ -250,7 +250,6 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { def::DefSelfTy(_) | def::DefRegion(_) | - def::DefTyParamBinder(_) | def::DefLabel(_) | def::DefStaticMethod(..) | def::DefTyParam(..) | diff --git a/src/librustc_trans/trans/callee.rs b/src/librustc_trans/trans/callee.rs index 25568db8148..9dbcbc8b1a2 100644 --- a/src/librustc_trans/trans/callee.rs +++ b/src/librustc_trans/trans/callee.rs @@ -209,9 +209,8 @@ fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &ast::Expr) } def::DefMod(..) | def::DefForeignMod(..) | def::DefTrait(..) | def::DefTy(..) | def::DefPrimTy(..) | def::DefAssociatedTy(..) | - def::DefUse(..) | def::DefTyParamBinder(..) | - def::DefRegion(..) | def::DefLabel(..) | def::DefTyParam(..) | - def::DefSelfTy(..) | def::DefAssociatedPath(..) => { + def::DefUse(..) | def::DefRegion(..) | def::DefLabel(..) | + def::DefTyParam(..) | def::DefSelfTy(..) | def::DefAssociatedPath(..) => { bcx.tcx().sess.span_bug( ref_expr.span, &format!("cannot translate def {:?} \ diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 5b3090be593..9d303f492eb 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -4729,7 +4729,6 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, def::DefSelfTy(..) | def::DefStruct(..) | def::DefVariant(..) | - def::DefTyParamBinder(..) | def::DefTy(..) | def::DefAssociatedTy(..) | def::DefAssociatedPath(..) | diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 2af81076223..7a27159bc47 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1344,8 +1344,6 @@ pub enum Type { typarams: Option<Vec<TyParamBound>>, did: ast::DefId, }, - // I have no idea how to usefully use this. - TyParamBinder(ast::NodeId), /// For parameterized types, so the consumer of the JSON don't go /// looking for types which don't exist anywhere. Generic(String), @@ -2416,7 +2414,6 @@ fn resolve_type(cx: &DocContext, ast::TyFloat(ast::TyF64) => return Primitive(F64), }, def::DefTyParam(_, _, _, n) => return Generic(token::get_name(n).to_string()), - def::DefTyParamBinder(i) => return TyParamBinder(i), _ => {} }; let did = register_def(&*cx, def); diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 11d9ecac14d..03a2d708ee4 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -454,9 +454,6 @@ fn tybounds(w: &mut fmt::Formatter, impl fmt::Display for clean::Type { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { - clean::TyParamBinder(id) => { - f.write_str(&cache().typarams[ast_util::local_def(id)]) - } clean::Generic(ref name) => { f.write_str(name) } diff --git a/src/libsyntax/ext/deriving/cmp/eq.rs b/src/libsyntax/ext/deriving/cmp/eq.rs index 91212a86958..80ef882745f 100644 --- a/src/libsyntax/ext/deriving/cmp/eq.rs +++ b/src/libsyntax/ext/deriving/cmp/eq.rs @@ -70,7 +70,7 @@ pub fn expand_deriving_eq<F>(cx: &mut ExtCtxt, generics: LifetimeBounds::empty(), explicit_self: borrowed_explicit_self(), args: vec!(borrowed_self()), - ret_ty: Literal(path!(bool)), + ret_ty: Literal(path_local!(bool)), attributes: attrs, combine_substructure: combine_substructure(box |a, b, c| { $f(a, b, c) diff --git a/src/libsyntax/ext/deriving/cmp/ord.rs b/src/libsyntax/ext/deriving/cmp/ord.rs index b109850a6bd..be4a33002aa 100644 --- a/src/libsyntax/ext/deriving/cmp/ord.rs +++ b/src/libsyntax/ext/deriving/cmp/ord.rs @@ -36,7 +36,7 @@ pub fn expand_deriving_ord<F>(cx: &mut ExtCtxt, generics: LifetimeBounds::empty(), explicit_self: borrowed_explicit_self(), args: vec!(borrowed_self()), - ret_ty: Literal(path!(bool)), + ret_ty: Literal(path_local!(bool)), attributes: attrs, combine_substructure: combine_substructure(box |cx, span, substr| { cs_op($op, $equal, cx, span, substr) diff --git a/src/libsyntax/ext/deriving/mod.rs b/src/libsyntax/ext/deriving/mod.rs index eee780f457c..973c8f5fa1e 100644 --- a/src/libsyntax/ext/deriving/mod.rs +++ b/src/libsyntax/ext/deriving/mod.rs @@ -30,6 +30,12 @@ macro_rules! path { ) } +macro_rules! path_local { + ($x:ident) => ( + ::ext::deriving::generic::ty::Path::new_local(stringify!($x)) + ) +} + macro_rules! pathvec_std { ($cx:expr, $first:ident :: $($rest:ident)::+) => ( if $cx.use_std { diff --git a/src/libsyntax/ext/deriving/primitive.rs b/src/libsyntax/ext/deriving/primitive.rs index 22c87d978c9..3b96292323a 100644 --- a/src/libsyntax/ext/deriving/primitive.rs +++ b/src/libsyntax/ext/deriving/primitive.rs @@ -38,7 +38,7 @@ pub fn expand_deriving_from_primitive<F>(cx: &mut ExtCtxt, name: "from_i64", generics: LifetimeBounds::empty(), explicit_self: None, - args: vec!(Literal(path!(i64))), + args: vec!(Literal(path_local!(i64))), ret_ty: Literal(Path::new_(pathvec_std!(cx, core::option::Option), None, vec!(box Self_), @@ -53,7 +53,7 @@ pub fn expand_deriving_from_primitive<F>(cx: &mut ExtCtxt, name: "from_u64", generics: LifetimeBounds::empty(), explicit_self: None, - args: vec!(Literal(path!(u64))), + args: vec!(Literal(path_local!(u64))), ret_ty: Literal(Path::new_(pathvec_std!(cx, core::option::Option), None, vec!(box Self_), diff --git a/src/test/compile-fail/extern-with-type-bounds.rs b/src/test/compile-fail/extern-with-type-bounds.rs index ade8b397e00..21334e1d513 100644 --- a/src/test/compile-fail/extern-with-type-bounds.rs +++ b/src/test/compile-fail/extern-with-type-bounds.rs @@ -24,7 +24,7 @@ extern "rust-intrinsic" { // Unresolved bounds should still error. fn align_of<T: NoSuchTrait>() -> usize; - //~^ ERROR attempt to bound type parameter with a nonexistent trait `NoSuchTrait` + //~^ ERROR use of undeclared trait name `NoSuchTrait` } fn main() {} diff --git a/src/test/compile-fail/glob-resolve1.rs b/src/test/compile-fail/glob-resolve1.rs index fce8a07d727..181503db818 100644 --- a/src/test/compile-fail/glob-resolve1.rs +++ b/src/test/compile-fail/glob-resolve1.rs @@ -36,9 +36,6 @@ fn main() { import(); //~ ERROR: unresolved foo::<A>(); //~ ERROR: undeclared - //~^ ERROR: undeclared foo::<C>(); //~ ERROR: undeclared - //~^ ERROR: undeclared foo::<D>(); //~ ERROR: undeclared - //~^ ERROR: undeclared } diff --git a/src/test/compile-fail/inner-static-type-parameter.rs b/src/test/compile-fail/inner-static-type-parameter.rs index abd7efe0e8e..cf2a70deee5 100644 --- a/src/test/compile-fail/inner-static-type-parameter.rs +++ b/src/test/compile-fail/inner-static-type-parameter.rs @@ -14,7 +14,8 @@ enum Bar<T> { What } fn foo<T>() { static a: Bar<T> = Bar::What; - //~^ ERROR: cannot use an outer type parameter in this context + //~^ ERROR cannot use an outer type parameter in this context + //~| ERROR use of undeclared type name `T` } fn main() { diff --git a/src/test/compile-fail/issue-3521-2.rs b/src/test/compile-fail/issue-3521-2.rs index 678618d7216..ad5bc4e445c 100644 --- a/src/test/compile-fail/issue-3521-2.rs +++ b/src/test/compile-fail/issue-3521-2.rs @@ -11,7 +11,9 @@ fn main() { let foo = 100; - static y: isize = foo + 1; //~ ERROR: attempt to use a non-constant value in a constant + static y: isize = foo + 1; + //~^ ERROR attempt to use a non-constant value in a constant + //~| ERROR unresolved name `foo` println!("{}", y); } diff --git a/src/test/compile-fail/issue-3521.rs b/src/test/compile-fail/issue-3521.rs index c49959c16a6..f06aa45ac38 100644 --- a/src/test/compile-fail/issue-3521.rs +++ b/src/test/compile-fail/issue-3521.rs @@ -13,7 +13,9 @@ fn main() { #[derive(Debug)] enum Stuff { - Bar = foo //~ ERROR attempt to use a non-constant value in a constant + Bar = foo + //~^ ERROR attempt to use a non-constant value in a constant + //~| ERROR unresolved name `foo` } println!("{}", Stuff::Bar); diff --git a/src/test/compile-fail/issue-3668-2.rs b/src/test/compile-fail/issue-3668-2.rs index 0577b152723..a09c8090de0 100644 --- a/src/test/compile-fail/issue-3668-2.rs +++ b/src/test/compile-fail/issue-3668-2.rs @@ -9,7 +9,9 @@ // except according to those terms. fn f(x:isize) { - static child: isize = x + 1; //~ ERROR attempt to use a non-constant value in a constant + static child: isize = x + 1; + //~^ ERROR attempt to use a non-constant value in a constant + //~| ERROR unresolved name `x` } fn main() {} diff --git a/src/test/compile-fail/issue-3668.rs b/src/test/compile-fail/issue-3668.rs index 9c31dc1e38e..9b7476244f0 100644 --- a/src/test/compile-fail/issue-3668.rs +++ b/src/test/compile-fail/issue-3668.rs @@ -17,6 +17,7 @@ impl PTrait for P { fn getChildOption(&self) -> Option<Box<P>> { static childVal: Box<P> = self.child.get(); //~^ ERROR attempt to use a non-constant value in a constant + //~| ERROR unresolved name `self` panic!(); } } diff --git a/src/test/compile-fail/no-implicit-prelude-nested.rs b/src/test/compile-fail/no-implicit-prelude-nested.rs index 2fb097f111d..526750257d2 100644 --- a/src/test/compile-fail/no-implicit-prelude-nested.rs +++ b/src/test/compile-fail/no-implicit-prelude-nested.rs @@ -18,11 +18,11 @@ mod foo { mod baz { struct Test; - impl Add for Test {} //~ ERROR: attempt to implement a nonexistent trait - impl Clone for Test {} //~ ERROR: attempt to implement a nonexistent trait - impl Iterator for Test {} //~ ERROR: attempt to implement a nonexistent trait - impl ToString for Test {} //~ ERROR: attempt to implement a nonexistent trait - impl Writer for Test {} //~ ERROR: attempt to implement a nonexistent trait + impl Add for Test {} //~ ERROR: use of undeclared trait + impl Clone for Test {} //~ ERROR: use of undeclared trait + impl Iterator for Test {} //~ ERROR: use of undeclared trait + impl ToString for Test {} //~ ERROR: use of undeclared trait + impl Writer for Test {} //~ ERROR: use of undeclared trait fn foo() { drop(2) //~ ERROR: unresolved name @@ -30,11 +30,11 @@ mod foo { } struct Test; - impl Add for Test {} //~ ERROR: attempt to implement a nonexistent trait - impl Clone for Test {} //~ ERROR: attempt to implement a nonexistent trait - impl Iterator for Test {} //~ ERROR: attempt to implement a nonexistent trait - impl ToString for Test {} //~ ERROR: attempt to implement a nonexistent trait - impl Writer for Test {} //~ ERROR: attempt to implement a nonexistent trait + impl Add for Test {} //~ ERROR: use of undeclared trait + impl Clone for Test {} //~ ERROR: use of undeclared trait + impl Iterator for Test {} //~ ERROR: use of undeclared trait + impl ToString for Test {} //~ ERROR: use of undeclared trait + impl Writer for Test {} //~ ERROR: use of undeclared trait fn foo() { drop(2) //~ ERROR: unresolved name @@ -45,11 +45,11 @@ fn qux() { #[no_implicit_prelude] mod qux_inner { struct Test; - impl Add for Test {} //~ ERROR: attempt to implement a nonexistent trait - impl Clone for Test {} //~ ERROR: attempt to implement a nonexistent trait - impl Iterator for Test {} //~ ERROR: attempt to implement a nonexistent trait - impl ToString for Test {} //~ ERROR: attempt to implement a nonexistent trait - impl Writer for Test {} //~ ERROR: attempt to implement a nonexistent trait + impl Add for Test {} //~ ERROR: use of undeclared trait + impl Clone for Test {} //~ ERROR: use of undeclared trait + impl Iterator for Test {} //~ ERROR: use of undeclared trait + impl ToString for Test {} //~ ERROR: use of undeclared trait + impl Writer for Test {} //~ ERROR: use of undeclared trait fn foo() { drop(2) //~ ERROR: unresolved name diff --git a/src/test/compile-fail/no-implicit-prelude.rs b/src/test/compile-fail/no-implicit-prelude.rs index c0f7bea25b5..c4bcd33b93b 100644 --- a/src/test/compile-fail/no-implicit-prelude.rs +++ b/src/test/compile-fail/no-implicit-prelude.rs @@ -17,11 +17,11 @@ // fail with the same error message). struct Test; -impl Add for Test {} //~ ERROR: attempt to implement a nonexistent trait -impl Clone for Test {} //~ ERROR: attempt to implement a nonexistent trait -impl Iterator for Test {} //~ ERROR: attempt to implement a nonexistent trait -impl ToString for Test {} //~ ERROR: attempt to implement a nonexistent trait -impl Writer for Test {} //~ ERROR: attempt to implement a nonexistent trait +impl Add for Test {} //~ ERROR: use of undeclared trait +impl Clone for Test {} //~ ERROR: use of undeclared trait +impl Iterator for Test {} //~ ERROR: use of undeclared trait +impl ToString for Test {} //~ ERROR: use of undeclared trait +impl Writer for Test {} //~ ERROR: use of undeclared trait fn main() { drop(2) //~ ERROR: unresolved name diff --git a/src/test/compile-fail/resolve-unknown-trait.rs b/src/test/compile-fail/resolve-unknown-trait.rs index 0d0dc0a05d1..3983a84f6ad 100644 --- a/src/test/compile-fail/resolve-unknown-trait.rs +++ b/src/test/compile-fail/resolve-unknown-trait.rs @@ -10,11 +10,11 @@ trait NewTrait : SomeNonExistentTrait {} -//~^ ERROR attempt to derive a nonexistent trait `SomeNonExistentTrait` +//~^ ERROR use of undeclared trait name `SomeNonExistentTrait` impl SomeNonExistentTrait for isize {} -//~^ ERROR attempt to implement a nonexistent trait `SomeNonExistentTrait` +//~^ ERROR use of undeclared trait name `SomeNonExistentTrait` fn f<T:SomeNonExistentTrait>() {} -//~^ ERROR attempt to bound type parameter with a nonexistent trait `SomeNonExistentTrait` +//~^ ERROR use of undeclared trait name `SomeNonExistentTrait` diff --git a/src/test/compile-fail/unboxed-closure-sugar-nonexistent-trait.rs b/src/test/compile-fail/unboxed-closure-sugar-nonexistent-trait.rs index 12f62d805e1..f28bf7acadd 100644 --- a/src/test/compile-fail/unboxed-closure-sugar-nonexistent-trait.rs +++ b/src/test/compile-fail/unboxed-closure-sugar-nonexistent-trait.rs @@ -10,7 +10,7 @@ #![feature(unboxed_closures)] -fn f<F:Nonexist(isize) -> isize>(x: F) {} //~ ERROR nonexistent trait `Nonexist` +fn f<F:Nonexist(isize) -> isize>(x: F) {} //~ ERROR undeclared trait name `Nonexist` type Typedef = isize; |
