Skip to content

Commit 4c30f64

Browse files
committed
Move the hack with fake partial resolution for <A>::B from typeck to resolve
1 parent 91b9dab commit 4c30f64

File tree

5 files changed

+40
-105
lines changed

5 files changed

+40
-105
lines changed

src/librustc/hir/lowering.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1238,7 +1238,7 @@ impl<'a> LoweringContext<'a> {
12381238
position: position,
12391239
}
12401240
});
1241-
let rename = if path.segments.len() == 1 {
1241+
let rename = if qself.is_none() && path.segments.len() == 1 {
12421242
// Only local variables are renamed
12431243
match self.resolver.get_resolution(e.id).map(|d| d.full_def()) {
12441244
Some(Def::Local(..)) | Some(Def::Upvar(..)) => true,

src/librustc_resolve/lib.rs

Lines changed: 37 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ use self::TypeParameters::*;
3838
use self::RibKind::*;
3939
use self::UseLexicalScopeFlag::*;
4040
use self::ModulePrefixResult::*;
41-
use self::AssocItemResolveResult::*;
4241
use self::ParentLink::*;
4342

4443
use rustc::hir::map::Definitions;
@@ -671,15 +670,6 @@ enum ModulePrefixResult<'a> {
671670
PrefixFound(Module<'a>, usize),
672671
}
673672

674-
#[derive(Copy, Clone)]
675-
enum AssocItemResolveResult {
676-
/// Syntax such as `<T>::item`, which can't be resolved until type
677-
/// checking.
678-
TypecheckRequired,
679-
/// We should have been able to resolve the associated item.
680-
ResolveAttempt(Option<PathResolution>),
681-
}
682-
683673
/// One local scope.
684674
#[derive(Debug)]
685675
struct Rib<'a> {
@@ -2131,24 +2121,12 @@ impl<'a> Resolver<'a> {
21312121
fn resolve_type(&mut self, ty: &Ty) {
21322122
match ty.node {
21332123
TyKind::Path(ref maybe_qself, ref path) => {
2134-
let resolution = match self.resolve_possibly_assoc_item(ty.id,
2135-
maybe_qself.as_ref(),
2136-
path,
2137-
TypeNS) {
2138-
// `<T>::a::b::c` is resolved by typeck alone.
2139-
TypecheckRequired => {
2140-
// Resolve embedded types.
2141-
visit::walk_ty(self, ty);
2142-
return;
2143-
}
2144-
ResolveAttempt(resolution) => resolution,
2145-
};
2146-
21472124
// This is a path in the type namespace. Walk through scopes
21482125
// looking for it.
2149-
if let Some(def) = resolution {
2126+
if let Some(def) = self.resolve_possibly_assoc_item(ty.id, maybe_qself.as_ref(),
2127+
path, TypeNS) {
21502128
match def.base_def {
2151-
Def::Mod(..) => {
2129+
Def::Mod(..) if def.depth == 0 => {
21522130
self.session.span_err(path.span, "expected type, found module");
21532131
self.record_def(ty.id, err_path_resolution());
21542132
}
@@ -2281,54 +2259,40 @@ impl<'a> Resolver<'a> {
22812259
expected_what: &'static str)
22822260
where ExpectedFn: FnOnce(Def) -> bool
22832261
{
2284-
let resolution = match self.resolve_possibly_assoc_item(pat_id, qself, path, namespace) {
2285-
ResolveAttempt(resolution) => {
2286-
if let Some(resolution) = resolution {
2287-
if resolution.depth == 0 {
2288-
if expected_fn(resolution.base_def) {
2289-
resolution
2290-
} else {
2291-
resolve_error(
2292-
self,
2293-
path.span,
2294-
ResolutionError::PatPathUnexpected(expected_what,
2295-
resolution.kind_name(), path)
2296-
);
2297-
err_path_resolution()
2298-
}
2299-
} else {
2300-
// Not fully resolved associated item `T::A::B::C` or
2301-
// `<T as Tr>::A::B::C`. If `C` should be resolved in value
2302-
// namespace then it needs to be added to the trait map.
2303-
if namespace == ValueNS {
2304-
let item_name = path.segments.last().unwrap().identifier.name;
2305-
let traits = self.get_traits_containing_item(item_name);
2306-
self.trait_map.insert(pat_id, traits);
2307-
}
2308-
resolution
2309-
}
2262+
let resolution = if let Some(resolution) = self.resolve_possibly_assoc_item(pat_id,
2263+
qself, path, namespace) {
2264+
if resolution.depth == 0 {
2265+
if expected_fn(resolution.base_def) {
2266+
resolution
23102267
} else {
2311-
if let Err(false) = self.resolve_path(pat_id, path, 0, namespace) {
2312-
resolve_error(
2313-
self,
2314-
path.span,
2315-
ResolutionError::PatPathUnresolved(expected_what, path)
2316-
);
2317-
}
2268+
resolve_error(
2269+
self,
2270+
path.span,
2271+
ResolutionError::PatPathUnexpected(expected_what,
2272+
resolution.kind_name(), path)
2273+
);
23182274
err_path_resolution()
23192275
}
2320-
}
2321-
TypecheckRequired => {
2322-
// `<T>::A::B::C`, resolves exclusively during typechecking.
2323-
// If `C` should be resolved in value namespace then it needs
2324-
// to be added to the trait map.
2276+
} else {
2277+
// Not fully resolved associated item `T::A::B` or `<T as Tr>::A::B`
2278+
// or `<T>::A::B`. If `B` should be resolved in value namespace then
2279+
// it needs to be added to the trait map.
23252280
if namespace == ValueNS {
23262281
let item_name = path.segments.last().unwrap().identifier.name;
23272282
let traits = self.get_traits_containing_item(item_name);
23282283
self.trait_map.insert(pat_id, traits);
23292284
}
2330-
return;
2285+
resolution
2286+
}
2287+
} else {
2288+
if let Err(false) = self.resolve_path(pat_id, path, 0, namespace) {
2289+
resolve_error(
2290+
self,
2291+
path.span,
2292+
ResolutionError::PatPathUnresolved(expected_what, path)
2293+
);
23312294
}
2295+
err_path_resolution()
23322296
};
23332297

23342298
self.record_def(pat_id, resolution);
@@ -2444,13 +2408,17 @@ impl<'a> Resolver<'a> {
24442408
maybe_qself: Option<&QSelf>,
24452409
path: &Path,
24462410
namespace: Namespace)
2447-
-> AssocItemResolveResult {
2411+
-> Option<PathResolution> {
24482412
let max_assoc_types;
24492413

24502414
match maybe_qself {
24512415
Some(qself) => {
24522416
if qself.position == 0 {
2453-
return TypecheckRequired;
2417+
// FIXME: Create some fake resolution that can't possibly be a type.
2418+
return Some(PathResolution {
2419+
base_def: Def::Mod(self.definitions.local_def_id(ast::CRATE_NODE_ID)),
2420+
depth: path.segments.len()
2421+
});
24542422
}
24552423
max_assoc_types = path.segments.len() - qself.position;
24562424
// Make sure the trait is valid.
@@ -2477,7 +2445,7 @@ impl<'a> Resolver<'a> {
24772445
}
24782446
});
24792447
}
2480-
ResolveAttempt(resolution)
2448+
resolution
24812449
}
24822450

24832451
/// Skips `path_depth` trailing segments, which is also reflected in the
@@ -2826,24 +2794,10 @@ impl<'a> Resolver<'a> {
28262794
// Next, resolve the node.
28272795
match expr.node {
28282796
ExprKind::Path(ref maybe_qself, ref path) => {
2829-
let resolution = match self.resolve_possibly_assoc_item(expr.id,
2830-
maybe_qself.as_ref(),
2831-
path,
2832-
ValueNS) {
2833-
// `<T>::a::b::c` is resolved by typeck alone.
2834-
TypecheckRequired => {
2835-
let method_name = path.segments.last().unwrap().identifier.name;
2836-
let traits = self.get_traits_containing_item(method_name);
2837-
self.trait_map.insert(expr.id, traits);
2838-
visit::walk_expr(self, expr);
2839-
return;
2840-
}
2841-
ResolveAttempt(resolution) => resolution,
2842-
};
2843-
28442797
// This is a local path in the value namespace. Walk through
28452798
// scopes looking for it.
2846-
if let Some(path_res) = resolution {
2799+
if let Some(path_res) = self.resolve_possibly_assoc_item(expr.id,
2800+
maybe_qself.as_ref(), path, ValueNS) {
28472801
// Check if struct variant
28482802
let is_struct_variant = if let Def::Variant(_, variant_id) = path_res.base_def {
28492803
self.structs.contains_key(&variant_id)

src/librustc_typeck/astconv.rs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1723,12 +1723,6 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
17231723
debug!("ast_ty_to_ty: maybe_qself={:?} path={:?}", maybe_qself, path);
17241724
let path_res = if let Some(&d) = tcx.def_map.borrow().get(&ast_ty.id) {
17251725
d
1726-
} else if let Some(hir::QSelf { position: 0, .. }) = *maybe_qself {
1727-
// Create some fake resolution that can't possibly be a type.
1728-
def::PathResolution {
1729-
base_def: Def::Mod(tcx.map.local_def_id(ast::CRATE_NODE_ID)),
1730-
depth: path.segments.len()
1731-
}
17321726
} else {
17331727
span_bug!(ast_ty.span, "unbound path {:?}", ast_ty)
17341728
};

src/librustc_typeck/check/_match.rs

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
use hir::def::{self, Def};
11+
use hir::def::Def;
1212
use rustc::infer::{self, InferOk, TypeOrigin};
1313
use hir::pat_util::{PatIdMap, pat_id_map};
1414
use hir::pat_util::{EnumerateAndAdjustIterator, pat_is_resolved_const};
@@ -224,13 +224,6 @@ impl<'a, 'gcx, 'tcx> PatCtxt<'a, 'gcx, 'tcx> {
224224
return;
225225
}
226226
d
227-
} else if qself.position == 0 {
228-
// This is just a sentinel for finish_resolving_def_to_ty.
229-
let sentinel = self.tcx.map.local_def_id(ast::CRATE_NODE_ID);
230-
def::PathResolution {
231-
base_def: Def::Mod(sentinel),
232-
depth: path.segments.len()
233-
}
234227
} else {
235228
debug!("unbound path {:?}", pat);
236229
self.write_error(pat.id);

src/librustc_typeck/check/mod.rs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3352,13 +3352,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
33523352

33533353
let path_res = if let Some(&d) = tcx.def_map.borrow().get(&id) {
33543354
d
3355-
} else if let Some(hir::QSelf { position: 0, .. }) = *maybe_qself {
3356-
// Create some fake resolution that can't possibly be a type.
3357-
def::PathResolution {
3358-
base_def: Def::Mod(tcx.map.local_def_id(ast::CRATE_NODE_ID)),
3359-
depth: path.segments.len()
3360-
}
3361-
} else {
3355+
} else {
33623356
span_bug!(expr.span, "unbound path {:?}", expr)
33633357
};
33643358

0 commit comments

Comments
 (0)