diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 90dd2dad7203..7d98aab8d27d 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -1238,7 +1238,7 @@ impl<'a> LoweringContext<'a> { position: position, } }); - let rename = if path.segments.len() == 1 { + let rename = if qself.is_none() && path.segments.len() == 1 { // Only local variables are renamed match self.resolver.get_resolution(e.id).map(|d| d.full_def()) { Some(Def::Local(..)) | Some(Def::Upvar(..)) => true, diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 86868fc085bf..921a6683069e 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -38,7 +38,6 @@ use self::TypeParameters::*; use self::RibKind::*; use self::UseLexicalScopeFlag::*; use self::ModulePrefixResult::*; -use self::AssocItemResolveResult::*; use self::ParentLink::*; use rustc::hir::map::Definitions; @@ -671,15 +670,6 @@ enum ModulePrefixResult<'a> { PrefixFound(Module<'a>, usize), } -#[derive(Copy, Clone)] -enum AssocItemResolveResult { - /// Syntax such as `::item`, which can't be resolved until type - /// checking. - TypecheckRequired, - /// We should have been able to resolve the associated item. - ResolveAttempt(Option), -} - /// One local scope. #[derive(Debug)] struct Rib<'a> { @@ -2131,24 +2121,12 @@ impl<'a> Resolver<'a> { fn resolve_type(&mut self, ty: &Ty) { match ty.node { TyKind::Path(ref maybe_qself, ref path) => { - let resolution = match self.resolve_possibly_assoc_item(ty.id, - maybe_qself.as_ref(), - path, - TypeNS) { - // `::a::b::c` is resolved by typeck alone. - TypecheckRequired => { - // Resolve embedded types. - visit::walk_ty(self, ty); - return; - } - ResolveAttempt(resolution) => resolution, - }; - // This is a path in the type namespace. Walk through scopes // looking for it. - if let Some(def) = resolution { + if let Some(def) = self.resolve_possibly_assoc_item(ty.id, maybe_qself.as_ref(), + path, TypeNS) { match def.base_def { - Def::Mod(..) => { + Def::Mod(..) if def.depth == 0 => { self.session.span_err(path.span, "expected type, found module"); self.record_def(ty.id, err_path_resolution()); } @@ -2281,54 +2259,40 @@ impl<'a> Resolver<'a> { expected_what: &'static str) where ExpectedFn: FnOnce(Def) -> bool { - let resolution = match self.resolve_possibly_assoc_item(pat_id, qself, path, namespace) { - ResolveAttempt(resolution) => { - if let Some(resolution) = resolution { - if resolution.depth == 0 { - if expected_fn(resolution.base_def) { - resolution - } else { - resolve_error( - self, - path.span, - ResolutionError::PatPathUnexpected(expected_what, - resolution.kind_name(), path) - ); - err_path_resolution() - } - } else { - // Not fully resolved associated item `T::A::B::C` or - // `::A::B::C`. If `C` should be resolved in value - // namespace then it needs to be added to the trait map. - if namespace == ValueNS { - let item_name = path.segments.last().unwrap().identifier.name; - let traits = self.get_traits_containing_item(item_name); - self.trait_map.insert(pat_id, traits); - } - resolution - } + let resolution = if let Some(resolution) = self.resolve_possibly_assoc_item(pat_id, + qself, path, namespace) { + if resolution.depth == 0 { + if expected_fn(resolution.base_def) { + resolution } else { - if let Err(false) = self.resolve_path(pat_id, path, 0, namespace) { - resolve_error( - self, - path.span, - ResolutionError::PatPathUnresolved(expected_what, path) - ); - } + resolve_error( + self, + path.span, + ResolutionError::PatPathUnexpected(expected_what, + resolution.kind_name(), path) + ); err_path_resolution() } - } - TypecheckRequired => { - // `::A::B::C`, resolves exclusively during typechecking. - // If `C` should be resolved in value namespace then it needs - // to be added to the trait map. + } else { + // Not fully resolved associated item `T::A::B` or `::A::B` + // or `::A::B`. If `B` should be resolved in value namespace then + // it needs to be added to the trait map. if namespace == ValueNS { let item_name = path.segments.last().unwrap().identifier.name; let traits = self.get_traits_containing_item(item_name); self.trait_map.insert(pat_id, traits); } - return; + resolution } + } else { + if let Err(false) = self.resolve_path(pat_id, path, 0, namespace) { + resolve_error( + self, + path.span, + ResolutionError::PatPathUnresolved(expected_what, path) + ); + } + err_path_resolution() }; self.record_def(pat_id, resolution); @@ -2444,13 +2408,17 @@ impl<'a> Resolver<'a> { maybe_qself: Option<&QSelf>, path: &Path, namespace: Namespace) - -> AssocItemResolveResult { + -> Option { let max_assoc_types; match maybe_qself { Some(qself) => { if qself.position == 0 { - return TypecheckRequired; + // FIXME: Create some fake resolution that can't possibly be a type. + return Some(PathResolution { + base_def: Def::Mod(self.definitions.local_def_id(ast::CRATE_NODE_ID)), + depth: path.segments.len() + }); } max_assoc_types = path.segments.len() - qself.position; // Make sure the trait is valid. @@ -2477,7 +2445,7 @@ impl<'a> Resolver<'a> { } }); } - ResolveAttempt(resolution) + resolution } /// Skips `path_depth` trailing segments, which is also reflected in the @@ -2826,24 +2794,10 @@ impl<'a> Resolver<'a> { // Next, resolve the node. match expr.node { ExprKind::Path(ref maybe_qself, ref path) => { - let resolution = match self.resolve_possibly_assoc_item(expr.id, - maybe_qself.as_ref(), - path, - ValueNS) { - // `::a::b::c` is resolved by typeck alone. - TypecheckRequired => { - let method_name = path.segments.last().unwrap().identifier.name; - let traits = self.get_traits_containing_item(method_name); - self.trait_map.insert(expr.id, traits); - visit::walk_expr(self, expr); - return; - } - ResolveAttempt(resolution) => resolution, - }; - // This is a local path in the value namespace. Walk through // scopes looking for it. - if let Some(path_res) = resolution { + if let Some(path_res) = self.resolve_possibly_assoc_item(expr.id, + maybe_qself.as_ref(), path, ValueNS) { // Check if struct variant let is_struct_variant = if let Def::Variant(_, variant_id) = path_res.base_def { self.structs.contains_key(&variant_id) diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 472d6ac67f4f..d492c34a55db 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1723,12 +1723,6 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { debug!("ast_ty_to_ty: maybe_qself={:?} path={:?}", maybe_qself, path); let path_res = if let Some(&d) = tcx.def_map.borrow().get(&ast_ty.id) { d - } else if let Some(hir::QSelf { position: 0, .. }) = *maybe_qself { - // Create some fake resolution that can't possibly be a type. - def::PathResolution { - base_def: Def::Mod(tcx.map.local_def_id(ast::CRATE_NODE_ID)), - depth: path.segments.len() - } } else { span_bug!(ast_ty.span, "unbound path {:?}", ast_ty) }; diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index 0430585fe6d0..c06aa9f14df1 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use hir::def::{self, Def}; +use hir::def::Def; use rustc::infer::{self, InferOk, TypeOrigin}; use hir::pat_util::{PatIdMap, pat_id_map}; use hir::pat_util::{EnumerateAndAdjustIterator, pat_is_resolved_const}; @@ -224,13 +224,6 @@ impl<'a, 'gcx, 'tcx> PatCtxt<'a, 'gcx, 'tcx> { return; } d - } else if qself.position == 0 { - // This is just a sentinel for finish_resolving_def_to_ty. - let sentinel = self.tcx.map.local_def_id(ast::CRATE_NODE_ID); - def::PathResolution { - base_def: Def::Mod(sentinel), - depth: path.segments.len() - } } else { debug!("unbound path {:?}", pat); self.write_error(pat.id); diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index de45883c872a..c59401764210 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -3352,13 +3352,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let path_res = if let Some(&d) = tcx.def_map.borrow().get(&id) { d - } else if let Some(hir::QSelf { position: 0, .. }) = *maybe_qself { - // Create some fake resolution that can't possibly be a type. - def::PathResolution { - base_def: Def::Mod(tcx.map.local_def_id(ast::CRATE_NODE_ID)), - depth: path.segments.len() - } - } else { + } else { span_bug!(expr.span, "unbound path {:?}", expr) };