1 // Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 #![crate_name = "rustc_resolve"]
12 #![unstable(feature = "rustc_private", issue = "27812")]
13 #![crate_type = "dylib"]
14 #![crate_type = "rlib"]
15 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
16 html_favicon_url
= "https://doc.rust-lang.org/favicon.ico",
17 html_root_url
= "https://doc.rust-lang.org/nightly/")]
18 #![cfg_attr(not(stage0), deny(warnings))]
20 #![feature(associated_consts)]
21 #![feature(borrow_state)]
22 #![feature(rustc_diagnostic_macros)]
23 #![feature(rustc_private)]
24 #![feature(staged_api)]
33 extern crate rustc_bitflags
;
37 use self::PatternBindingMode
::*;
38 use self::Namespace
::*;
39 use self::ResolveResult
::*;
40 use self::FallbackSuggestion
::*;
41 use self::TypeParameters
::*;
43 use self::UseLexicalScopeFlag
::*;
44 use self::ModulePrefixResult
::*;
45 use self::AssocItemResolveResult
::*;
46 use self::BareIdentifierPatternResolution
::*;
47 use self::ParentLink
::*;
48 use self::FallbackChecks
::*;
50 use rustc
::dep_graph
::DepNode
;
51 use rustc
::hir
::map
as hir_map
;
52 use rustc
::session
::Session
;
54 use rustc
::middle
::cstore
::CrateStore
;
55 use rustc
::hir
::def
::*;
56 use rustc
::hir
::def_id
::DefId
;
57 use rustc
::hir
::pat_util
::pat_bindings
;
58 use rustc
::ty
::subst
::{ParamSpace, FnSpace, TypeSpace}
;
59 use rustc
::hir
::{Freevar, FreevarMap, TraitMap, GlobMap}
;
60 use rustc
::util
::nodemap
::{NodeMap, FnvHashMap, FnvHashSet}
;
62 use syntax
::ast
::{self, FloatTy}
;
63 use syntax
::ast
::{CRATE_NODE_ID, Name, NodeId, CrateNum, IntTy, UintTy}
;
64 use syntax
::attr
::AttrMetaMethods
;
65 use syntax
::codemap
::{self, Span, Pos}
;
66 use syntax
::errors
::DiagnosticBuilder
;
67 use syntax
::parse
::token
::{self, special_names, special_idents}
;
68 use syntax
::util
::lev_distance
::find_best_match_for_name
;
70 use rustc
::hir
::intravisit
::{self, FnKind, Visitor}
;
72 use rustc
::hir
::{Arm, BindByRef, BindByValue, BindingMode, Block}
;
73 use rustc
::hir
::Crate
;
74 use rustc
::hir
::{Expr, ExprAgain, ExprBreak, ExprCall, ExprField}
;
75 use rustc
::hir
::{ExprLoop, ExprWhile, ExprMethodCall}
;
76 use rustc
::hir
::{ExprPath, ExprStruct, FnDecl}
;
77 use rustc
::hir
::{ForeignItemFn, ForeignItemStatic, Generics}
;
78 use rustc
::hir
::{ImplItem, Item, ItemConst, ItemEnum, ItemExternCrate}
;
79 use rustc
::hir
::{ItemFn, ItemForeignMod, ItemImpl, ItemMod, ItemStatic, ItemDefaultImpl}
;
80 use rustc
::hir
::{ItemStruct, ItemTrait, ItemTy, ItemUse}
;
81 use rustc
::hir
::Local
;
82 use rustc
::hir
::{Pat, PatKind, Path, PrimTy}
;
83 use rustc
::hir
::{PathSegment, PathParameters}
;
84 use rustc
::hir
::HirVec
;
85 use rustc
::hir
::{TraitRef, Ty, TyBool, TyChar, TyFloat, TyInt}
;
86 use rustc
::hir
::{TyRptr, TyStr, TyUint, TyPath, TyPtr}
;
88 use std
::collections
::{HashMap, HashSet}
;
89 use std
::cell
::{Cell, RefCell}
;
91 use std
::mem
::replace
;
93 use resolve_imports
::{ImportDirective, NameResolution}
;
95 // NB: This module needs to be declared first so diagnostics are
96 // registered before they are used.
100 mod build_reduced_graph
;
103 // Perform the callback, not walking deeper if the return is true
104 macro_rules
! execute_callback
{
105 ($node
: expr
, $walker
: expr
) => (
106 if let Some(ref callback
) = $walker
.callback
{
107 if callback($node
, &mut $walker
.resolved
) {
114 enum SuggestionType
{
116 Function(token
::InternedString
),
120 /// Candidates for a name resolution failure
121 struct SuggestedCandidates
{
123 candidates
: Vec
<Path
>,
126 enum ResolutionError
<'a
> {
127 /// error E0401: can't use type parameters from outer function
128 TypeParametersFromOuterFunction
,
129 /// error E0402: cannot use an outer type parameter in this context
130 OuterTypeParameterContext
,
131 /// error E0403: the name is already used for a type parameter in this type parameter list
132 NameAlreadyUsedInTypeParameterList(Name
),
133 /// error E0404: is not a trait
134 IsNotATrait(&'a
str),
135 /// error E0405: use of undeclared trait name
136 UndeclaredTraitName(&'a
str, SuggestedCandidates
),
137 /// error E0406: undeclared associated type
138 UndeclaredAssociatedType
,
139 /// error E0407: method is not a member of trait
140 MethodNotMemberOfTrait(Name
, &'a
str),
141 /// error E0437: type is not a member of trait
142 TypeNotMemberOfTrait(Name
, &'a
str),
143 /// error E0438: const is not a member of trait
144 ConstNotMemberOfTrait(Name
, &'a
str),
145 /// error E0408: variable `{}` from pattern #1 is not bound in pattern
146 VariableNotBoundInPattern(Name
, usize),
147 /// error E0409: variable is bound with different mode in pattern #{} than in pattern #1
148 VariableBoundWithDifferentMode(Name
, usize),
149 /// error E0410: variable from pattern is not bound in pattern #1
150 VariableNotBoundInParentPattern(Name
, usize),
151 /// error E0411: use of `Self` outside of an impl or trait
152 SelfUsedOutsideImplOrTrait
,
153 /// error E0412: use of undeclared
154 UseOfUndeclared(&'a
str, &'a
str, SuggestedCandidates
),
155 /// error E0413: declaration shadows an enum variant or unit-like struct in scope
156 DeclarationShadowsEnumVariantOrUnitLikeStruct(Name
),
157 /// error E0414: only irrefutable patterns allowed here
158 OnlyIrrefutablePatternsAllowedHere(DefId
, Name
),
159 /// error E0415: identifier is bound more than once in this parameter list
160 IdentifierBoundMoreThanOnceInParameterList(&'a
str),
161 /// error E0416: identifier is bound more than once in the same pattern
162 IdentifierBoundMoreThanOnceInSamePattern(&'a
str),
163 /// error E0417: static variables cannot be referenced in a pattern
164 StaticVariableReference
,
165 /// error E0418: is not an enum variant, struct or const
166 NotAnEnumVariantStructOrConst(&'a
str),
167 /// error E0419: unresolved enum variant, struct or const
168 UnresolvedEnumVariantStructOrConst(&'a
str),
169 /// error E0420: is not an associated const
170 NotAnAssociatedConst(&'a
str),
171 /// error E0421: unresolved associated const
172 UnresolvedAssociatedConst(&'a
str),
173 /// error E0422: does not name a struct
174 DoesNotNameAStruct(&'a
str),
175 /// error E0423: is a struct variant name, but this expression uses it like a function name
176 StructVariantUsedAsFunction(&'a
str),
177 /// error E0424: `self` is not available in a static method
178 SelfNotAvailableInStaticMethod
,
179 /// error E0425: unresolved name
180 UnresolvedName(&'a
str, &'a
str, UnresolvedNameContext
),
181 /// error E0426: use of undeclared label
182 UndeclaredLabel(&'a
str),
183 /// error E0427: cannot use `ref` binding mode with ...
184 CannotUseRefBindingModeWith(&'a
str),
185 /// error E0429: `self` imports are only allowed within a { } list
186 SelfImportsOnlyAllowedWithin
,
187 /// error E0430: `self` import can only appear once in the list
188 SelfImportCanOnlyAppearOnceInTheList
,
189 /// error E0431: `self` import can only appear in an import list with a non-empty prefix
190 SelfImportOnlyInImportListWithNonEmptyPrefix
,
191 /// error E0432: unresolved import
192 UnresolvedImport(Option
<(&'a
str, &'a
str)>),
193 /// error E0433: failed to resolve
194 FailedToResolve(&'a
str),
195 /// error E0434: can't capture dynamic environment in a fn item
196 CannotCaptureDynamicEnvironmentInFnItem
,
197 /// error E0435: attempt to use a non-constant value in a constant
198 AttemptToUseNonConstantValueInConstant
,
201 /// Context of where `ResolutionError::UnresolvedName` arose.
202 #[derive(Clone, PartialEq, Eq, Debug)]
203 enum UnresolvedNameContext
{
204 /// `PathIsMod(id)` indicates that a given path, used in
205 /// expression context, actually resolved to a module rather than
206 /// a value. The `id` attached to the variant is the node id of
207 /// the erroneous path expression.
208 PathIsMod(ast
::NodeId
),
210 /// `Other` means we have no extra information about the context
211 /// of the unresolved name error. (Maybe we could eliminate all
212 /// such cases; but for now, this is an information-free default.)
216 fn resolve_error
<'b
, 'a
: 'b
, 'tcx
: 'a
>(resolver
: &'b Resolver
<'a
, 'tcx
>,
217 span
: syntax
::codemap
::Span
,
218 resolution_error
: ResolutionError
<'b
>) {
219 resolve_struct_error(resolver
, span
, resolution_error
).emit();
222 fn resolve_struct_error
<'b
, 'a
: 'b
, 'tcx
: 'a
>(resolver
: &'b Resolver
<'a
, 'tcx
>,
223 span
: syntax
::codemap
::Span
,
224 resolution_error
: ResolutionError
<'b
>)
225 -> DiagnosticBuilder
<'a
> {
226 if !resolver
.emit_errors
{
227 return resolver
.session
.diagnostic().struct_dummy();
230 match resolution_error
{
231 ResolutionError
::TypeParametersFromOuterFunction
=> {
232 struct_span_err
!(resolver
.session
,
235 "can't use type parameters from outer function; try using a local \
236 type parameter instead")
238 ResolutionError
::OuterTypeParameterContext
=> {
239 struct_span_err
!(resolver
.session
,
242 "cannot use an outer type parameter in this context")
244 ResolutionError
::NameAlreadyUsedInTypeParameterList(name
) => {
245 struct_span_err
!(resolver
.session
,
248 "the name `{}` is already used for a type parameter in this type \
252 ResolutionError
::IsNotATrait(name
) => {
253 struct_span_err
!(resolver
.session
, span
, E0404
, "`{}` is not a trait", name
)
255 ResolutionError
::UndeclaredTraitName(name
, candidates
) => {
256 let mut err
= struct_span_err
!(resolver
.session
,
259 "trait `{}` is not in scope",
261 show_candidates(&mut err
, span
, &candidates
);
264 ResolutionError
::UndeclaredAssociatedType
=> {
265 struct_span_err
!(resolver
.session
, span
, E0406
, "undeclared associated type")
267 ResolutionError
::MethodNotMemberOfTrait(method
, trait_
) => {
268 struct_span_err
!(resolver
.session
,
271 "method `{}` is not a member of trait `{}`",
275 ResolutionError
::TypeNotMemberOfTrait(type_
, trait_
) => {
276 struct_span_err
!(resolver
.session
,
279 "type `{}` is not a member of trait `{}`",
283 ResolutionError
::ConstNotMemberOfTrait(const_
, trait_
) => {
284 struct_span_err
!(resolver
.session
,
287 "const `{}` is not a member of trait `{}`",
291 ResolutionError
::VariableNotBoundInPattern(variable_name
, pattern_number
) => {
292 struct_span_err
!(resolver
.session
,
295 "variable `{}` from pattern #1 is not bound in pattern #{}",
299 ResolutionError
::VariableBoundWithDifferentMode(variable_name
, pattern_number
) => {
300 struct_span_err
!(resolver
.session
,
303 "variable `{}` is bound with different mode in pattern #{} than in \
308 ResolutionError
::VariableNotBoundInParentPattern(variable_name
, pattern_number
) => {
309 struct_span_err
!(resolver
.session
,
312 "variable `{}` from pattern #{} is not bound in pattern #1",
316 ResolutionError
::SelfUsedOutsideImplOrTrait
=> {
317 struct_span_err
!(resolver
.session
,
320 "use of `Self` outside of an impl or trait")
322 ResolutionError
::UseOfUndeclared(kind
, name
, candidates
) => {
323 let mut err
= struct_span_err
!(resolver
.session
,
326 "{} `{}` is undefined or not in scope",
329 show_candidates(&mut err
, span
, &candidates
);
332 ResolutionError
::DeclarationShadowsEnumVariantOrUnitLikeStruct(name
) => {
333 struct_span_err
!(resolver
.session
,
336 "declaration of `{}` shadows an enum variant \
337 or unit-like struct in scope",
340 ResolutionError
::OnlyIrrefutablePatternsAllowedHere(did
, name
) => {
341 let mut err
= struct_span_err
!(resolver
.session
,
344 "only irrefutable patterns allowed here");
346 "there already is a constant in scope sharing the same \
347 name as this pattern");
348 if let Some(sp
) = resolver
.ast_map
.span_if_local(did
) {
349 err
.span_note(sp
, "constant defined here");
351 if let Some(binding
) = resolver
.current_module
352 .resolve_name_in_lexical_scope(name
, ValueNS
) {
353 if binding
.is_import() {
354 err
.span_note(binding
.span
.unwrap(), "constant imported here");
359 ResolutionError
::IdentifierBoundMoreThanOnceInParameterList(identifier
) => {
360 struct_span_err
!(resolver
.session
,
363 "identifier `{}` is bound more than once in this parameter list",
366 ResolutionError
::IdentifierBoundMoreThanOnceInSamePattern(identifier
) => {
367 struct_span_err
!(resolver
.session
,
370 "identifier `{}` is bound more than once in the same pattern",
373 ResolutionError
::StaticVariableReference
=> {
374 struct_span_err
!(resolver
.session
,
377 "static variables cannot be referenced in a pattern, use a \
380 ResolutionError
::NotAnEnumVariantStructOrConst(name
) => {
381 struct_span_err
!(resolver
.session
,
384 "`{}` is not an enum variant, struct or const",
387 ResolutionError
::UnresolvedEnumVariantStructOrConst(name
) => {
388 struct_span_err
!(resolver
.session
,
391 "unresolved enum variant, struct or const `{}`",
394 ResolutionError
::NotAnAssociatedConst(name
) => {
395 struct_span_err
!(resolver
.session
,
398 "`{}` is not an associated const",
401 ResolutionError
::UnresolvedAssociatedConst(name
) => {
402 struct_span_err
!(resolver
.session
,
405 "unresolved associated const `{}`",
408 ResolutionError
::DoesNotNameAStruct(name
) => {
409 struct_span_err
!(resolver
.session
,
412 "`{}` does not name a structure",
415 ResolutionError
::StructVariantUsedAsFunction(path_name
) => {
416 struct_span_err
!(resolver
.session
,
419 "`{}` is the name of a struct or struct variant, but this expression \
420 uses it like a function name",
423 ResolutionError
::SelfNotAvailableInStaticMethod
=> {
424 struct_span_err
!(resolver
.session
,
427 "`self` is not available in a static method. Maybe a `self` \
428 argument is missing?")
430 ResolutionError
::UnresolvedName(path
, msg
, context
) => {
431 let mut err
= struct_span_err
!(resolver
.session
,
434 "unresolved name `{}`{}",
439 UnresolvedNameContext
::Other
=> { }
// no help available
440 UnresolvedNameContext
::PathIsMod(id
) => {
441 let mut help_msg
= String
::new();
442 let parent_id
= resolver
.ast_map
.get_parent_node(id
);
443 if let Some(hir_map
::Node
::NodeExpr(e
)) = resolver
.ast_map
.find(parent_id
) {
445 ExprField(_
, ident
) => {
446 help_msg
= format
!("To reference an item from the \
447 `{module}` module, use \
448 `{module}::{ident}`",
452 ExprMethodCall(ident
, _
, _
) => {
453 help_msg
= format
!("To call a function from the \
454 `{module}` module, use \
455 `{module}::{ident}(..)`",
460 help_msg
= format
!("No function corresponds to `{module}(..)`",
463 _
=> { }
// no help available
466 help_msg
= format
!("Module `{module}` cannot be the value of an expression",
470 if !help_msg
.is_empty() {
471 err
.fileline_help(span
, &help_msg
);
477 ResolutionError
::UndeclaredLabel(name
) => {
478 struct_span_err
!(resolver
.session
,
481 "use of undeclared label `{}`",
484 ResolutionError
::CannotUseRefBindingModeWith(descr
) => {
485 struct_span_err
!(resolver
.session
,
488 "cannot use `ref` binding mode with {}",
491 ResolutionError
::SelfImportsOnlyAllowedWithin
=> {
492 struct_span_err
!(resolver
.session
,
496 "`self` imports are only allowed within a { } list")
498 ResolutionError
::SelfImportCanOnlyAppearOnceInTheList
=> {
499 struct_span_err
!(resolver
.session
,
502 "`self` import can only appear once in the list")
504 ResolutionError
::SelfImportOnlyInImportListWithNonEmptyPrefix
=> {
505 struct_span_err
!(resolver
.session
,
508 "`self` import can only appear in an import list with a \
511 ResolutionError
::UnresolvedImport(name
) => {
512 let msg
= match name
{
513 Some((n
, p
)) => format
!("unresolved import `{}`{}", n
, p
),
514 None
=> "unresolved import".to_owned(),
516 struct_span_err
!(resolver
.session
, span
, E0432
, "{}", msg
)
518 ResolutionError
::FailedToResolve(msg
) => {
519 struct_span_err
!(resolver
.session
, span
, E0433
, "failed to resolve. {}", msg
)
521 ResolutionError
::CannotCaptureDynamicEnvironmentInFnItem
=> {
522 struct_span_err
!(resolver
.session
,
526 "can't capture dynamic environment in a fn item; use the || { ... } \
527 closure form instead")
529 ResolutionError
::AttemptToUseNonConstantValueInConstant
=> {
530 struct_span_err
!(resolver
.session
,
533 "attempt to use a non-constant value in a constant")
538 #[derive(Copy, Clone)]
541 binding_mode
: BindingMode
,
544 // Map from the name in a pattern to its binding mode.
545 type BindingMap
= HashMap
<Name
, BindingInfo
>;
547 #[derive(Copy, Clone, PartialEq)]
548 enum PatternBindingMode
{
550 LocalIrrefutableMode
,
551 ArgumentIrrefutableMode
,
554 #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
560 impl<'a
, 'v
, 'tcx
> Visitor
<'v
> for Resolver
<'a
, 'tcx
> {
561 fn visit_nested_item(&mut self, item
: hir
::ItemId
) {
562 self.visit_item(self.ast_map
.expect_item(item
.id
))
564 fn visit_item(&mut self, item
: &Item
) {
565 execute_callback
!(hir_map
::Node
::NodeItem(item
), self);
566 self.resolve_item(item
);
568 fn visit_arm(&mut self, arm
: &Arm
) {
569 self.resolve_arm(arm
);
571 fn visit_block(&mut self, block
: &Block
) {
572 execute_callback
!(hir_map
::Node
::NodeBlock(block
), self);
573 self.resolve_block(block
);
575 fn visit_expr(&mut self, expr
: &Expr
) {
576 execute_callback
!(hir_map
::Node
::NodeExpr(expr
), self);
577 self.resolve_expr(expr
);
579 fn visit_local(&mut self, local
: &Local
) {
580 execute_callback
!(hir_map
::Node
::NodeLocal(&local
.pat
), self);
581 self.resolve_local(local
);
583 fn visit_ty(&mut self, ty
: &Ty
) {
584 self.resolve_type(ty
);
586 fn visit_generics(&mut self, generics
: &Generics
) {
587 self.resolve_generics(generics
);
589 fn visit_poly_trait_ref(&mut self, tref
: &hir
::PolyTraitRef
, m
: &hir
::TraitBoundModifier
) {
590 match self.resolve_trait_reference(tref
.trait_ref
.ref_id
, &tref
.trait_ref
.path
, 0) {
591 Ok(def
) => self.record_def(tref
.trait_ref
.ref_id
, def
),
593 // error already reported
594 self.record_def(tref
.trait_ref
.ref_id
, err_path_resolution())
597 intravisit
::walk_poly_trait_ref(self, tref
, m
);
599 fn visit_variant(&mut self,
600 variant
: &hir
::Variant
,
602 item_id
: ast
::NodeId
) {
603 execute_callback
!(hir_map
::Node
::NodeVariant(variant
), self);
604 if let Some(ref dis_expr
) = variant
.node
.disr_expr
{
605 // resolve the discriminator expr as a constant
606 self.with_constant_rib(|this
| {
607 this
.visit_expr(dis_expr
);
611 // `intravisit::walk_variant` without the discriminant expression.
612 self.visit_variant_data(&variant
.node
.data
,
618 fn visit_foreign_item(&mut self, foreign_item
: &hir
::ForeignItem
) {
619 execute_callback
!(hir_map
::Node
::NodeForeignItem(foreign_item
), self);
620 let type_parameters
= match foreign_item
.node
{
621 ForeignItemFn(_
, ref generics
) => {
622 HasTypeParameters(generics
, FnSpace
, ItemRibKind
)
624 ForeignItemStatic(..) => NoTypeParameters
,
626 self.with_type_parameter_rib(type_parameters
, |this
| {
627 intravisit
::walk_foreign_item(this
, foreign_item
);
630 fn visit_fn(&mut self,
631 function_kind
: FnKind
<'v
>,
632 declaration
: &'v FnDecl
,
636 let rib_kind
= match function_kind
{
637 FnKind
::ItemFn(_
, generics
, _
, _
, _
, _
, _
) => {
638 self.visit_generics(generics
);
641 FnKind
::Method(_
, sig
, _
, _
) => {
642 self.visit_generics(&sig
.generics
);
643 self.visit_explicit_self(&sig
.explicit_self
);
646 FnKind
::Closure(_
) => ClosureRibKind(node_id
),
648 self.resolve_function(rib_kind
, declaration
, block
);
652 pub type ErrorMessage
= Option
<(Span
, String
)>;
654 #[derive(Clone, PartialEq, Eq)]
655 pub enum ResolveResult
<T
> {
656 Failed(ErrorMessage
), // Failed to resolve the name, optional helpful error message.
657 Indeterminate
, // Couldn't determine due to unresolved globs.
658 Success(T
), // Successfully resolved the import.
661 impl<T
> ResolveResult
<T
> {
662 fn and_then
<U
, F
: FnOnce(T
) -> ResolveResult
<U
>>(self, f
: F
) -> ResolveResult
<U
> {
664 Failed(msg
) => Failed(msg
),
665 Indeterminate
=> Indeterminate
,
670 fn success(self) -> Option
<T
> {
672 Success(t
) => Some(t
),
678 enum FallbackSuggestion
{
683 StaticMethod(String
),
687 #[derive(Copy, Clone)]
688 enum TypeParameters
<'tcx
, 'a
> {
690 HasTypeParameters(// Type parameters.
693 // Identifies the things that these parameters
694 // were declared on (type, fn, etc)
697 // The kind of the rib used for type parameters.
701 // The rib kind controls the translation of local
702 // definitions (`Def::Local`) to upvars (`Def::Upvar`).
703 #[derive(Copy, Clone, Debug)]
705 // No translation needs to be applied.
708 // We passed through a closure scope at the given node ID.
709 // Translate upvars as appropriate.
710 ClosureRibKind(NodeId
/* func id */),
712 // We passed through an impl or trait and are now in one of its
713 // methods. Allow references to ty params that impl or trait
714 // binds. Disallow any other upvars (including other ty params that are
718 // We passed through an item scope. Disallow upvars.
721 // We're in a constant item. Can't refer to dynamic stuff.
724 // We passed through a module.
725 ModuleRibKind(Module
<'a
>),
728 #[derive(Copy, Clone)]
729 enum UseLexicalScopeFlag
{
734 enum ModulePrefixResult
<'a
> {
736 PrefixFound(Module
<'a
>, usize),
739 #[derive(Copy, Clone)]
740 enum AssocItemResolveResult
{
741 /// Syntax such as `<T>::item`, which can't be resolved until type
744 /// We should have been able to resolve the associated item.
745 ResolveAttempt(Option
<PathResolution
>),
748 #[derive(Copy, Clone)]
749 enum BareIdentifierPatternResolution
{
750 FoundStructOrEnumVariant(Def
),
751 FoundConst(Def
, Name
),
752 BareIdentifierPatternUnresolved
,
758 bindings
: HashMap
<Name
, Def
>,
763 fn new(kind
: RibKind
<'a
>) -> Rib
<'a
> {
765 bindings
: HashMap
::new(),
771 /// A definition along with the index of the rib it was found on
773 ribs
: Option
<(Namespace
, usize)>,
778 fn from_def(def
: Def
) -> Self {
786 enum LexicalScopeBinding
<'a
> {
787 Item(&'a NameBinding
<'a
>),
791 impl<'a
> LexicalScopeBinding
<'a
> {
792 fn local_def(self) -> LocalDef
{
794 LexicalScopeBinding
::LocalDef(local_def
) => local_def
,
795 LexicalScopeBinding
::Item(binding
) => LocalDef
::from_def(binding
.def().unwrap()),
799 fn def(self) -> Def
{
803 fn module(self) -> Option
<Module
<'a
>> {
805 LexicalScopeBinding
::Item(binding
) => binding
.module(),
811 /// The link from a module up to its nearest parent node.
812 #[derive(Clone,Debug)]
813 enum ParentLink
<'a
> {
815 ModuleParentLink(Module
<'a
>, Name
),
816 BlockParentLink(Module
<'a
>, NodeId
),
819 /// One node in the tree of modules.
820 pub struct ModuleS
<'a
> {
821 parent_link
: ParentLink
<'a
>,
825 // If the module is an extern crate, `def` is root of the external crate and `extern_crate_id`
826 // is the NodeId of the local `extern crate` item (otherwise, `extern_crate_id` is None).
827 extern_crate_id
: Option
<NodeId
>,
829 resolutions
: RefCell
<HashMap
<(Name
, Namespace
), &'a RefCell
<NameResolution
<'a
>>>>,
830 unresolved_imports
: RefCell
<Vec
<&'a ImportDirective
<'a
>>>,
832 // The module children of this node, including normal modules and anonymous modules.
833 // Anonymous children are pseudo-modules that are implicitly created around items
834 // contained within blocks.
836 // For example, if we have this:
844 // There will be an anonymous module created around `g` with the ID of the
845 // entry block for `f`.
846 module_children
: RefCell
<NodeMap
<Module
<'a
>>>,
848 prelude
: RefCell
<Option
<Module
<'a
>>>,
850 glob_importers
: RefCell
<Vec
<(Module
<'a
>, &'a ImportDirective
<'a
>)>>,
851 globs
: RefCell
<Vec
<&'a ImportDirective
<'a
>>>,
853 // Used to memoize the traits in this module for faster searches through all traits in scope.
854 traits
: RefCell
<Option
<Box
<[&'a NameBinding
<'a
>]>>>,
856 // Whether this module is populated. If not populated, any attempt to
857 // access the children must be preceded with a
858 // `populate_module_if_necessary` call.
859 populated
: Cell
<bool
>,
861 arenas
: &'a ResolverArenas
<'a
>,
864 pub type Module
<'a
> = &'a ModuleS
<'a
>;
866 impl<'a
> ModuleS
<'a
> {
867 fn new(parent_link
: ParentLink
<'a
>,
871 arenas
: &'a ResolverArenas
<'a
>) -> Self {
873 parent_link
: parent_link
,
875 is_public
: is_public
,
876 extern_crate_id
: None
,
877 resolutions
: RefCell
::new(HashMap
::new()),
878 unresolved_imports
: RefCell
::new(Vec
::new()),
879 module_children
: RefCell
::new(NodeMap()),
880 prelude
: RefCell
::new(None
),
881 glob_importers
: RefCell
::new(Vec
::new()),
882 globs
: RefCell
::new((Vec
::new())),
883 traits
: RefCell
::new(None
),
884 populated
: Cell
::new(!external
),
889 fn for_each_child
<F
: FnMut(Name
, Namespace
, &'a NameBinding
<'a
>)>(&self, mut f
: F
) {
890 for (&(name
, ns
), name_resolution
) in self.resolutions
.borrow().iter() {
891 name_resolution
.borrow().binding
.map(|binding
| f(name
, ns
, binding
));
895 fn def_id(&self) -> Option
<DefId
> {
896 self.def
.as_ref().map(Def
::def_id
)
899 fn is_normal(&self) -> bool
{
901 Some(Def
::Mod(_
)) | Some(Def
::ForeignMod(_
)) => true,
906 fn is_trait(&self) -> bool
{
908 Some(Def
::Trait(_
)) => true,
913 fn is_ancestor_of(&self, module
: Module
<'a
>) -> bool
{
914 if self.def_id() == module
.def_id() { return true }
915 match module
.parent_link
{
916 ParentLink
::BlockParentLink(parent
, _
) |
917 ParentLink
::ModuleParentLink(parent
, _
) => self.is_ancestor_of(parent
),
923 impl<'a
> fmt
::Debug
for ModuleS
<'a
> {
924 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
938 flags DefModifiers
: u8 {
939 // Enum variants are always considered `PUBLIC`, this is needed for `use Enum::Variant`
940 // or `use Enum::*` to work on private enums.
941 const PUBLIC
= 1 << 0,
942 const IMPORTABLE
= 1 << 1,
943 // Variants are considered `PUBLIC`, but some of them live in private enums.
944 // We need to track them to prohibit reexports like `pub use PrivEnum::Variant`.
945 const PRIVATE_VARIANT
= 1 << 2,
946 const GLOB_IMPORTED
= 1 << 3,
950 // Records a possibly-private value, type, or module definition.
951 #[derive(Clone, Debug)]
952 pub struct NameBinding
<'a
> {
953 modifiers
: DefModifiers
,
954 kind
: NameBindingKind
<'a
>,
958 #[derive(Clone, Debug)]
959 enum NameBindingKind
<'a
> {
963 binding
: &'a NameBinding
<'a
>,
965 // Some(error) if using this imported name causes the import to be a privacy error
966 privacy_error
: Option
<Box
<PrivacyError
<'a
>>>,
970 #[derive(Clone, Debug)]
971 struct PrivacyError
<'a
>(Span
, Name
, &'a NameBinding
<'a
>);
973 impl<'a
> NameBinding
<'a
> {
974 fn create_from_module(module
: Module
<'a
>, span
: Option
<Span
>) -> Self {
975 let modifiers
= if module
.is_public
{
978 DefModifiers
::empty()
979 } | DefModifiers
::IMPORTABLE
;
981 NameBinding { modifiers: modifiers, kind: NameBindingKind::Module(module), span: span }
984 fn module(&self) -> Option
<Module
<'a
>> {
986 NameBindingKind
::Module(module
) => Some(module
),
987 NameBindingKind
::Def(_
) => None
,
988 NameBindingKind
::Import { binding, .. }
=> binding
.module(),
992 fn def(&self) -> Option
<Def
> {
994 NameBindingKind
::Def(def
) => Some(def
),
995 NameBindingKind
::Module(module
) => module
.def
,
996 NameBindingKind
::Import { binding, .. }
=> binding
.def(),
1000 fn defined_with(&self, modifiers
: DefModifiers
) -> bool
{
1001 self.modifiers
.contains(modifiers
)
1004 fn is_public(&self) -> bool
{
1005 self.defined_with(DefModifiers
::PUBLIC
)
1008 fn is_extern_crate(&self) -> bool
{
1009 self.module().and_then(|module
| module
.extern_crate_id
).is_some()
1012 fn is_import(&self) -> bool
{
1014 NameBindingKind
::Import { .. }
=> true,
1020 /// Interns the names of the primitive types.
1021 struct PrimitiveTypeTable
{
1022 primitive_types
: HashMap
<Name
, PrimTy
>,
1025 impl PrimitiveTypeTable
{
1026 fn new() -> PrimitiveTypeTable
{
1027 let mut table
= PrimitiveTypeTable { primitive_types: HashMap::new() }
;
1029 table
.intern("bool", TyBool
);
1030 table
.intern("char", TyChar
);
1031 table
.intern("f32", TyFloat(FloatTy
::F32
));
1032 table
.intern("f64", TyFloat(FloatTy
::F64
));
1033 table
.intern("isize", TyInt(IntTy
::Is
));
1034 table
.intern("i8", TyInt(IntTy
::I8
));
1035 table
.intern("i16", TyInt(IntTy
::I16
));
1036 table
.intern("i32", TyInt(IntTy
::I32
));
1037 table
.intern("i64", TyInt(IntTy
::I64
));
1038 table
.intern("str", TyStr
);
1039 table
.intern("usize", TyUint(UintTy
::Us
));
1040 table
.intern("u8", TyUint(UintTy
::U8
));
1041 table
.intern("u16", TyUint(UintTy
::U16
));
1042 table
.intern("u32", TyUint(UintTy
::U32
));
1043 table
.intern("u64", TyUint(UintTy
::U64
));
1048 fn intern(&mut self, string
: &str, primitive_type
: PrimTy
) {
1049 self.primitive_types
.insert(token
::intern(string
), primitive_type
);
1053 /// The main resolver class.
1054 pub struct Resolver
<'a
, 'tcx
: 'a
> {
1055 session
: &'a Session
,
1057 ast_map
: &'a hir_map
::Map
<'tcx
>,
1059 graph_root
: Module
<'a
>,
1061 trait_item_map
: FnvHashMap
<(Name
, DefId
), DefId
>,
1063 structs
: FnvHashMap
<DefId
, Vec
<Name
>>,
1065 // The number of imports that are currently unresolved.
1066 unresolved_imports
: usize,
1068 // The module that represents the current item scope.
1069 current_module
: Module
<'a
>,
1071 // The current set of local scopes, for values.
1072 // FIXME #4948: Reuse ribs to avoid allocation.
1073 value_ribs
: Vec
<Rib
<'a
>>,
1075 // The current set of local scopes, for types.
1076 type_ribs
: Vec
<Rib
<'a
>>,
1078 // The current set of local scopes, for labels.
1079 label_ribs
: Vec
<Rib
<'a
>>,
1081 // The trait that the current context can refer to.
1082 current_trait_ref
: Option
<(DefId
, TraitRef
)>,
1084 // The current self type if inside an impl (used for better errors).
1085 current_self_type
: Option
<Ty
>,
1087 // The idents for the primitive types.
1088 primitive_type_table
: PrimitiveTypeTable
,
1090 def_map
: RefCell
<DefMap
>,
1091 freevars
: FreevarMap
,
1092 freevars_seen
: NodeMap
<NodeMap
<usize>>,
1093 export_map
: ExportMap
,
1094 trait_map
: TraitMap
,
1096 // Whether or not to print error messages. Can be set to true
1097 // when getting additional info for error message suggestions,
1098 // so as to avoid printing duplicate errors
1101 make_glob_map
: bool
,
1102 // Maps imports to the names of items actually imported (this actually maps
1103 // all imports, but only glob imports are actually interesting).
1106 used_imports
: HashSet
<(NodeId
, Namespace
)>,
1107 used_crates
: HashSet
<CrateNum
>,
1109 // Callback function for intercepting walks
1110 callback
: Option
<Box
<Fn(hir_map
::Node
, &mut bool
) -> bool
>>,
1111 // The intention is that the callback modifies this flag.
1112 // Once set, the resolver falls out of the walk, preserving the ribs.
1114 privacy_errors
: Vec
<PrivacyError
<'a
>>,
1116 arenas
: &'a ResolverArenas
<'a
>,
1119 struct ResolverArenas
<'a
> {
1120 modules
: arena
::TypedArena
<ModuleS
<'a
>>,
1121 name_bindings
: arena
::TypedArena
<NameBinding
<'a
>>,
1122 import_directives
: arena
::TypedArena
<ImportDirective
<'a
>>,
1123 name_resolutions
: arena
::TypedArena
<RefCell
<NameResolution
<'a
>>>,
1126 impl<'a
> ResolverArenas
<'a
> {
1127 fn alloc_module(&'a
self, module
: ModuleS
<'a
>) -> Module
<'a
> {
1128 self.modules
.alloc(module
)
1130 fn alloc_name_binding(&'a
self, name_binding
: NameBinding
<'a
>) -> &'a NameBinding
<'a
> {
1131 self.name_bindings
.alloc(name_binding
)
1133 fn alloc_import_directive(&'a
self, import_directive
: ImportDirective
<'a
>)
1134 -> &'a ImportDirective
{
1135 self.import_directives
.alloc(import_directive
)
1137 fn alloc_name_resolution(&'a
self) -> &'a RefCell
<NameResolution
<'a
>> {
1138 self.name_resolutions
.alloc(Default
::default())
1142 #[derive(PartialEq)]
1143 enum FallbackChecks
{
1145 OnlyTraitAndStatics
,
1148 impl<'a
, 'tcx
> Resolver
<'a
, 'tcx
> {
1149 fn new(session
: &'a Session
,
1150 ast_map
: &'a hir_map
::Map
<'tcx
>,
1151 make_glob_map
: MakeGlobMap
,
1152 arenas
: &'a ResolverArenas
<'a
>)
1153 -> Resolver
<'a
, 'tcx
> {
1154 let root_def_id
= ast_map
.local_def_id(CRATE_NODE_ID
);
1156 ModuleS
::new(NoParentLink
, Some(Def
::Mod(root_def_id
)), false, true, arenas
);
1157 let graph_root
= arenas
.alloc_module(graph_root
);
1164 // The outermost module has def ID 0; this is not reflected in the
1166 graph_root
: graph_root
,
1168 trait_item_map
: FnvHashMap(),
1169 structs
: FnvHashMap(),
1171 unresolved_imports
: 0,
1173 current_module
: graph_root
,
1174 value_ribs
: vec
![Rib
::new(ModuleRibKind(graph_root
))],
1175 type_ribs
: vec
![Rib
::new(ModuleRibKind(graph_root
))],
1176 label_ribs
: Vec
::new(),
1178 current_trait_ref
: None
,
1179 current_self_type
: None
,
1181 primitive_type_table
: PrimitiveTypeTable
::new(),
1183 def_map
: RefCell
::new(NodeMap()),
1184 freevars
: NodeMap(),
1185 freevars_seen
: NodeMap(),
1186 export_map
: NodeMap(),
1187 trait_map
: NodeMap(),
1188 used_imports
: HashSet
::new(),
1189 used_crates
: HashSet
::new(),
1192 make_glob_map
: make_glob_map
== MakeGlobMap
::Yes
,
1193 glob_map
: NodeMap(),
1197 privacy_errors
: Vec
::new(),
1203 fn arenas() -> ResolverArenas
<'a
> {
1205 modules
: arena
::TypedArena
::new(),
1206 name_bindings
: arena
::TypedArena
::new(),
1207 import_directives
: arena
::TypedArena
::new(),
1208 name_resolutions
: arena
::TypedArena
::new(),
1212 fn new_module(&self,
1213 parent_link
: ParentLink
<'a
>,
1216 is_public
: bool
) -> Module
<'a
> {
1217 self.arenas
.alloc_module(ModuleS
::new(parent_link
, def
, external
, is_public
, self.arenas
))
1220 fn new_extern_crate_module(&self,
1221 parent_link
: ParentLink
<'a
>,
1224 local_node_id
: NodeId
)
1226 let mut module
= ModuleS
::new(parent_link
, Some(def
), false, is_public
, self.arenas
);
1227 module
.extern_crate_id
= Some(local_node_id
);
1228 self.arenas
.modules
.alloc(module
)
1231 fn get_ribs
<'b
>(&'b
mut self, ns
: Namespace
) -> &'b
mut Vec
<Rib
<'a
>> {
1232 match ns { ValueNS => &mut self.value_ribs, TypeNS => &mut self.type_ribs }
1236 fn record_use(&mut self, name
: Name
, ns
: Namespace
, binding
: &'a NameBinding
<'a
>) {
1237 // track extern crates for unused_extern_crate lint
1238 if let Some(DefId { krate, .. }
) = binding
.module().and_then(ModuleS
::def_id
) {
1239 self.used_crates
.insert(krate
);
1242 let (import_id
, privacy_error
) = match binding
.kind
{
1243 NameBindingKind
::Import { id, ref privacy_error, .. }
=> (id
, privacy_error
),
1247 self.used_imports
.insert((import_id
, ns
));
1248 if let Some(error
) = privacy_error
.as_ref() {
1249 self.privacy_errors
.push((**error
).clone());
1252 if !self.make_glob_map
{
1255 if self.glob_map
.contains_key(&import_id
) {
1256 self.glob_map
.get_mut(&import_id
).unwrap().insert(name
);
1260 let mut new_set
= FnvHashSet();
1261 new_set
.insert(name
);
1262 self.glob_map
.insert(import_id
, new_set
);
1265 fn get_trait_name(&self, did
: DefId
) -> Name
{
1266 if let Some(node_id
) = self.ast_map
.as_local_node_id(did
) {
1267 self.ast_map
.expect_item(node_id
).name
1269 self.session
.cstore
.item_name(did
)
1273 /// Resolves the given module path from the given root `module_`.
1274 fn resolve_module_path_from_root(&mut self,
1275 module_
: Module
<'a
>,
1276 module_path
: &[Name
],
1279 -> ResolveResult
<Module
<'a
>> {
1280 fn search_parent_externals(needle
: Name
, module
: Module
) -> Option
<Module
> {
1281 match module
.resolve_name(needle
, TypeNS
, false) {
1282 Success(binding
) if binding
.is_extern_crate() => Some(module
),
1283 _
=> match module
.parent_link
{
1284 ModuleParentLink(ref parent
, _
) => {
1285 search_parent_externals(needle
, parent
)
1292 let mut search_module
= module_
;
1293 let mut index
= index
;
1294 let module_path_len
= module_path
.len();
1296 // Resolve the module part of the path. This does not involve looking
1297 // upward though scope chains; we simply resolve names directly in
1298 // modules as we go.
1299 while index
< module_path_len
{
1300 let name
= module_path
[index
];
1301 match self.resolve_name_in_module(search_module
, name
, TypeNS
, false, true) {
1303 let segment_name
= name
.as_str();
1304 let module_name
= module_to_string(search_module
);
1305 let mut span
= span
;
1306 let msg
= if "???" == &module_name
{
1307 span
.hi
= span
.lo
+ Pos
::from_usize(segment_name
.len());
1309 match search_parent_externals(name
, &self.current_module
) {
1311 let path_str
= names_to_string(module_path
);
1312 let target_mod_str
= module_to_string(&module
);
1313 let current_mod_str
= module_to_string(&self.current_module
);
1315 let prefix
= if target_mod_str
== current_mod_str
{
1316 "self::".to_string()
1318 format
!("{}::", target_mod_str
)
1321 format
!("Did you mean `{}{}`?", prefix
, path_str
)
1323 None
=> format
!("Maybe a missing `extern crate {}`?", segment_name
),
1326 format
!("Could not find `{}` in `{}`", segment_name
, module_name
)
1329 return Failed(Some((span
, msg
)));
1331 Failed(err
) => return Failed(err
),
1333 debug
!("(resolving module path for import) module resolution is \
1336 return Indeterminate
;
1338 Success(binding
) => {
1339 // Check to see whether there are type bindings, and, if
1340 // so, whether there is a module within.
1341 if let Some(module_def
) = binding
.module() {
1342 self.check_privacy(search_module
, name
, binding
, span
);
1343 search_module
= module_def
;
1345 let msg
= format
!("Not a module `{}`", name
);
1346 return Failed(Some((span
, msg
)));
1354 return Success(search_module
);
1357 /// Attempts to resolve the module part of an import directive or path
1358 /// rooted at the given module.
1359 fn resolve_module_path(&mut self,
1360 module_path
: &[Name
],
1361 use_lexical_scope
: UseLexicalScopeFlag
,
1363 -> ResolveResult
<Module
<'a
>> {
1364 if module_path
.len() == 0 {
1365 return Success(self.graph_root
) // Use the crate root
1368 debug
!("(resolving module path for import) processing `{}` rooted at `{}`",
1369 names_to_string(module_path
),
1370 module_to_string(self.current_module
));
1372 // Resolve the module prefix, if any.
1373 let module_prefix_result
= self.resolve_module_prefix(module_path
, span
);
1377 match module_prefix_result
{
1378 Failed(err
) => return Failed(err
),
1380 debug
!("(resolving module path for import) indeterminate; bailing");
1381 return Indeterminate
;
1383 Success(NoPrefixFound
) => {
1384 // There was no prefix, so we're considering the first element
1385 // of the path. How we handle this depends on whether we were
1386 // instructed to use lexical scope or not.
1387 match use_lexical_scope
{
1388 DontUseLexicalScope
=> {
1389 // This is a crate-relative path. We will start the
1390 // resolution process at index zero.
1391 search_module
= self.graph_root
;
1394 UseLexicalScope
=> {
1395 // This is not a crate-relative path. We resolve the
1396 // first component of the path in the current lexical
1397 // scope and then proceed to resolve below that.
1398 let ident
= hir
::Ident
::from_name(module_path
[0]);
1399 match self.resolve_ident_in_lexical_scope(ident
, TypeNS
, true)
1400 .and_then(LexicalScopeBinding
::module
) {
1401 None
=> return Failed(None
),
1402 Some(containing_module
) => {
1403 search_module
= containing_module
;
1410 Success(PrefixFound(ref containing_module
, index
)) => {
1411 search_module
= containing_module
;
1412 start_index
= index
;
1416 self.resolve_module_path_from_root(search_module
,
1422 /// This resolves the identifier `ident` in the namespace `ns` in the current lexical scope.
1423 /// More specifically, we proceed up the hierarchy of scopes and return the binding for
1424 /// `ident` in the first scope that defines it (or None if no scopes define it).
1426 /// A block's items are above its local variables in the scope hierarchy, regardless of where
1427 /// the items are defined in the block. For example,
1430 /// g(); // Since there are no local variables in scope yet, this resolves to the item.
1433 /// g(); // This resolves to the local variable `g` since it shadows the item.
1437 /// Invariant: This must only be called during main resolution, not during
1438 /// import resolution.
1439 fn resolve_ident_in_lexical_scope(&mut self,
1443 -> Option
<LexicalScopeBinding
<'a
>> {
1444 let name
= match ns { ValueNS => ident.name, TypeNS => ident.unhygienic_name }
;
1446 // Walk backwards up the ribs in scope.
1447 for i
in (0 .. self.get_ribs(ns
).len()).rev() {
1448 if let Some(def
) = self.get_ribs(ns
)[i
].bindings
.get(&name
).cloned() {
1449 // The ident resolves to a type parameter or local variable.
1450 return Some(LexicalScopeBinding
::LocalDef(LocalDef
{
1451 ribs
: Some((ns
, i
)),
1456 if let ModuleRibKind(module
) = self.get_ribs(ns
)[i
].kind
{
1457 let name
= ident
.unhygienic_name
;
1458 let item
= self.resolve_name_in_module(module
, name
, ns
, true, record_used
);
1459 if let Success(binding
) = item
{
1460 // The ident resolves to an item.
1461 return Some(LexicalScopeBinding
::Item(binding
));
1464 // We can only see through anonymous modules
1465 if module
.def
.is_some() { return None; }
1472 /// Returns the nearest normal module parent of the given module.
1473 fn get_nearest_normal_module_parent(&mut self, module_
: Module
<'a
>) -> Option
<Module
<'a
>> {
1474 let mut module_
= module_
;
1476 match module_
.parent_link
{
1477 NoParentLink
=> return None
,
1478 ModuleParentLink(new_module
, _
) |
1479 BlockParentLink(new_module
, _
) => {
1480 let new_module
= new_module
;
1481 if new_module
.is_normal() {
1482 return Some(new_module
);
1484 module_
= new_module
;
1490 /// Returns the nearest normal module parent of the given module, or the
1491 /// module itself if it is a normal module.
1492 fn get_nearest_normal_module_parent_or_self(&mut self, module_
: Module
<'a
>) -> Module
<'a
> {
1493 if module_
.is_normal() {
1496 match self.get_nearest_normal_module_parent(module_
) {
1498 Some(new_module
) => new_module
,
1502 /// Resolves a "module prefix". A module prefix is one or both of (a) `self::`;
1503 /// (b) some chain of `super::`.
1504 /// grammar: (SELF MOD_SEP ) ? (SUPER MOD_SEP) *
1505 fn resolve_module_prefix(&mut self, module_path
: &[Name
], span
: Span
)
1506 -> ResolveResult
<ModulePrefixResult
<'a
>> {
1507 // Start at the current module if we see `self` or `super`, or at the
1508 // top of the crate otherwise.
1509 let mut i
= match &*module_path
[0].as_str() {
1512 _
=> return Success(NoPrefixFound
),
1514 let module_
= self.current_module
;
1515 let mut containing_module
= self.get_nearest_normal_module_parent_or_self(module_
);
1517 // Now loop through all the `super`s we find.
1518 while i
< module_path
.len() && "super" == module_path
[i
].as_str() {
1519 debug
!("(resolving module prefix) resolving `super` at {}",
1520 module_to_string(&containing_module
));
1521 match self.get_nearest_normal_module_parent(containing_module
) {
1523 let msg
= "There are too many initial `super`s.".into();
1524 return Failed(Some((span
, msg
)));
1526 Some(new_module
) => {
1527 containing_module
= new_module
;
1533 debug
!("(resolving module prefix) finished resolving prefix at {}",
1534 module_to_string(&containing_module
));
1536 return Success(PrefixFound(containing_module
, i
));
1539 /// Attempts to resolve the supplied name in the given module for the
1540 /// given namespace. If successful, returns the binding corresponding to
1542 fn resolve_name_in_module(&mut self,
1545 namespace
: Namespace
,
1546 use_lexical_scope
: bool
,
1548 -> ResolveResult
<&'a NameBinding
<'a
>> {
1549 debug
!("(resolving name in module) resolving `{}` in `{}`", name
, module_to_string(module
));
1551 self.populate_module_if_necessary(module
);
1552 match use_lexical_scope
{
1553 true => module
.resolve_name_in_lexical_scope(name
, namespace
)
1554 .map(Success
).unwrap_or(Failed(None
)),
1555 false => module
.resolve_name(name
, namespace
, false),
1556 }.and_then(|binding
| {
1558 self.record_use(name
, namespace
, binding
);
1566 // We maintain a list of value ribs and type ribs.
1568 // Simultaneously, we keep track of the current position in the module
1569 // graph in the `current_module` pointer. When we go to resolve a name in
1570 // the value or type namespaces, we first look through all the ribs and
1571 // then query the module graph. When we resolve a name in the module
1572 // namespace, we can skip all the ribs (since nested modules are not
1573 // allowed within blocks in Rust) and jump straight to the current module
1576 // Named implementations are handled separately. When we find a method
1577 // call, we consult the module node to find all of the implementations in
1578 // scope. This information is lazily cached in the module node. We then
1579 // generate a fake "implementation scope" containing all the
1580 // implementations thus found, for compatibility with old resolve pass.
1582 fn with_scope
<F
>(&mut self, id
: NodeId
, f
: F
)
1583 where F
: FnOnce(&mut Resolver
)
1585 if let Some(module
) = self.current_module
.module_children
.borrow().get(&id
) {
1586 // Move down in the graph.
1587 let orig_module
= ::std
::mem
::replace(&mut self.current_module
, module
);
1588 self.value_ribs
.push(Rib
::new(ModuleRibKind(module
)));
1589 self.type_ribs
.push(Rib
::new(ModuleRibKind(module
)));
1593 self.current_module
= orig_module
;
1594 self.value_ribs
.pop();
1595 self.type_ribs
.pop();
1601 /// Searches the current set of local scopes for labels.
1602 /// Stops after meeting a closure.
1603 fn search_label(&self, name
: Name
) -> Option
<Def
> {
1604 for rib
in self.label_ribs
.iter().rev() {
1610 // Do not resolve labels across function boundary
1614 let result
= rib
.bindings
.get(&name
).cloned();
1615 if result
.is_some() {
1622 fn resolve_crate(&mut self, krate
: &hir
::Crate
) {
1623 debug
!("(resolving crate) starting");
1625 intravisit
::walk_crate(self, krate
);
1628 fn resolve_item(&mut self, item
: &Item
) {
1629 let name
= item
.name
;
1631 debug
!("(resolving item) resolving {}", name
);
1634 ItemEnum(_
, ref generics
) |
1635 ItemTy(_
, ref generics
) |
1636 ItemStruct(_
, ref generics
) => {
1637 self.with_type_parameter_rib(HasTypeParameters(generics
, TypeSpace
, ItemRibKind
),
1638 |this
| intravisit
::walk_item(this
, item
));
1640 ItemFn(_
, _
, _
, _
, ref generics
, _
) => {
1641 self.with_type_parameter_rib(HasTypeParameters(generics
, FnSpace
, ItemRibKind
),
1642 |this
| intravisit
::walk_item(this
, item
));
1645 ItemDefaultImpl(_
, ref trait_ref
) => {
1646 self.with_optional_trait_ref(Some(trait_ref
), |_
, _
| {}
);
1648 ItemImpl(_
, _
, ref generics
, ref opt_trait_ref
, ref self_type
, ref impl_items
) => {
1649 self.resolve_implementation(generics
,
1656 ItemTrait(_
, ref generics
, ref bounds
, ref trait_items
) => {
1657 // Create a new rib for the trait-wide type parameters.
1658 self.with_type_parameter_rib(HasTypeParameters(generics
,
1662 let local_def_id
= this
.ast_map
.local_def_id(item
.id
);
1663 this
.with_self_rib(Def
::SelfTy(Some(local_def_id
), None
), |this
| {
1664 this
.visit_generics(generics
);
1665 walk_list
!(this
, visit_ty_param_bound
, bounds
);
1667 for trait_item
in trait_items
{
1668 match trait_item
.node
{
1669 hir
::ConstTraitItem(_
, ref default) => {
1670 // Only impose the restrictions of
1671 // ConstRibKind if there's an actual constant
1672 // expression in a provided default.
1673 if default.is_some() {
1674 this
.with_constant_rib(|this
| {
1675 intravisit
::walk_trait_item(this
, trait_item
)
1678 intravisit
::walk_trait_item(this
, trait_item
)
1681 hir
::MethodTraitItem(ref sig
, _
) => {
1682 let type_parameters
=
1683 HasTypeParameters(&sig
.generics
,
1686 this
.with_type_parameter_rib(type_parameters
, |this
| {
1687 intravisit
::walk_trait_item(this
, trait_item
)
1690 hir
::TypeTraitItem(..) => {
1691 this
.with_type_parameter_rib(NoTypeParameters
, |this
| {
1692 intravisit
::walk_trait_item(this
, trait_item
)
1701 ItemMod(_
) | ItemForeignMod(_
) => {
1702 self.with_scope(item
.id
, |this
| {
1703 intravisit
::walk_item(this
, item
);
1707 ItemConst(..) | ItemStatic(..) => {
1708 self.with_constant_rib(|this
| {
1709 intravisit
::walk_item(this
, item
);
1713 ItemUse(ref view_path
) => {
1714 match view_path
.node
{
1715 hir
::ViewPathList(ref prefix
, ref items
) => {
1716 // Resolve prefix of an import with empty braces (issue #28388)
1717 if items
.is_empty() && !prefix
.segments
.is_empty() {
1718 match self.resolve_crate_relative_path(prefix
.span
,
1722 self.record_def(item
.id
, PathResolution
::new(def
, 0)),
1723 Err(true) => self.record_def(item
.id
, err_path_resolution()),
1727 ResolutionError
::FailedToResolve(
1728 &path_names_to_string(prefix
, 0)));
1729 self.record_def(item
.id
, err_path_resolution());
1738 ItemExternCrate(_
) => {
1739 // do nothing, these are just around to be encoded
1744 fn with_type_parameter_rib
<'b
, F
>(&'b
mut self, type_parameters
: TypeParameters
<'a
, 'b
>, f
: F
)
1745 where F
: FnOnce(&mut Resolver
)
1747 match type_parameters
{
1748 HasTypeParameters(generics
, space
, rib_kind
) => {
1749 let mut function_type_rib
= Rib
::new(rib_kind
);
1750 let mut seen_bindings
= HashSet
::new();
1751 for (index
, type_parameter
) in generics
.ty_params
.iter().enumerate() {
1752 let name
= type_parameter
.name
;
1753 debug
!("with_type_parameter_rib: {}", type_parameter
.id
);
1755 if seen_bindings
.contains(&name
) {
1757 type_parameter
.span
,
1758 ResolutionError
::NameAlreadyUsedInTypeParameterList(name
));
1760 seen_bindings
.insert(name
);
1762 // plain insert (no renaming)
1763 let def_id
= self.ast_map
.local_def_id(type_parameter
.id
);
1764 let def
= Def
::TyParam(space
, index
as u32, def_id
, name
);
1765 function_type_rib
.bindings
.insert(name
, def
);
1767 self.type_ribs
.push(function_type_rib
);
1770 NoTypeParameters
=> {
1777 match type_parameters
{
1778 HasTypeParameters(..) => {
1780 self.type_ribs
.pop();
1783 NoTypeParameters
=> {}
1787 fn with_label_rib
<F
>(&mut self, f
: F
)
1788 where F
: FnOnce(&mut Resolver
)
1790 self.label_ribs
.push(Rib
::new(NormalRibKind
));
1793 self.label_ribs
.pop();
1797 fn with_constant_rib
<F
>(&mut self, f
: F
)
1798 where F
: FnOnce(&mut Resolver
)
1800 self.value_ribs
.push(Rib
::new(ConstantItemRibKind
));
1801 self.type_ribs
.push(Rib
::new(ConstantItemRibKind
));
1804 self.type_ribs
.pop();
1805 self.value_ribs
.pop();
1809 fn resolve_function(&mut self, rib_kind
: RibKind
<'a
>, declaration
: &FnDecl
, block
: &Block
) {
1810 // Create a value rib for the function.
1811 self.value_ribs
.push(Rib
::new(rib_kind
));
1813 // Create a label rib for the function.
1814 self.label_ribs
.push(Rib
::new(rib_kind
));
1816 // Add each argument to the rib.
1817 let mut bindings_list
= HashMap
::new();
1818 for argument
in &declaration
.inputs
{
1819 self.resolve_pattern(&argument
.pat
, ArgumentIrrefutableMode
, &mut bindings_list
);
1821 self.visit_ty(&argument
.ty
);
1823 debug
!("(resolving function) recorded argument");
1825 intravisit
::walk_fn_ret_ty(self, &declaration
.output
);
1827 // Resolve the function body.
1828 self.visit_block(block
);
1830 debug
!("(resolving function) leaving function");
1833 self.label_ribs
.pop();
1834 self.value_ribs
.pop();
1838 fn resolve_trait_reference(&mut self,
1842 -> Result
<PathResolution
, ()> {
1843 self.resolve_path(id
, trait_path
, path_depth
, TypeNS
).and_then(|path_res
| {
1844 if let Def
::Trait(_
) = path_res
.base_def
{
1845 debug
!("(resolving trait) found trait def: {:?}", path_res
);
1849 resolve_struct_error(self,
1851 ResolutionError
::IsNotATrait(&path_names_to_string(trait_path
,
1854 // If it's a typedef, give a note
1855 if let Def
::TyAlias(did
) = path_res
.base_def
{
1856 err
.fileline_note(trait_path
.span
,
1857 "`type` aliases cannot be used for traits");
1858 if let Some(sp
) = self.ast_map
.span_if_local(did
) {
1859 err
.span_note(sp
, "type defined here");
1865 }).map_err(|error_reported
| {
1866 if error_reported { return }
1868 // find possible candidates
1869 let trait_name
= trait_path
.segments
.last().unwrap().identifier
.name
;
1871 self.lookup_candidates(
1875 Def
::Trait(_
) => true,
1880 // create error object
1881 let name
= &path_names_to_string(trait_path
, path_depth
);
1883 ResolutionError
::UndeclaredTraitName(
1888 resolve_error(self, trait_path
.span
, error
);
1892 fn resolve_generics(&mut self, generics
: &Generics
) {
1893 for predicate
in &generics
.where_clause
.predicates
{
1895 &hir
::WherePredicate
::BoundPredicate(_
) |
1896 &hir
::WherePredicate
::RegionPredicate(_
) => {}
1897 &hir
::WherePredicate
::EqPredicate(ref eq_pred
) => {
1898 self.resolve_path(eq_pred
.id
, &eq_pred
.path
, 0, TypeNS
).and_then(|path_res
| {
1899 if let PathResolution { base_def: Def::TyParam(..), .. }
= path_res
{
1900 Ok(self.record_def(eq_pred
.id
, path_res
))
1904 }).map_err(|error_reported
| {
1905 self.record_def(eq_pred
.id
, err_path_resolution());
1906 if error_reported { return }
1907 let error_variant
= ResolutionError
::UndeclaredAssociatedType
;
1908 resolve_error(self, eq_pred
.span
, error_variant
);
1913 intravisit
::walk_generics(self, generics
);
1916 fn with_current_self_type
<T
, F
>(&mut self, self_type
: &Ty
, f
: F
) -> T
1917 where F
: FnOnce(&mut Resolver
) -> T
1919 // Handle nested impls (inside fn bodies)
1920 let previous_value
= replace(&mut self.current_self_type
, Some(self_type
.clone()));
1921 let result
= f(self);
1922 self.current_self_type
= previous_value
;
1926 fn with_optional_trait_ref
<T
, F
>(&mut self, opt_trait_ref
: Option
<&TraitRef
>, f
: F
) -> T
1927 where F
: FnOnce(&mut Resolver
, Option
<DefId
>) -> T
1929 let mut new_val
= None
;
1930 let mut new_id
= None
;
1931 if let Some(trait_ref
) = opt_trait_ref
{
1932 if let Ok(path_res
) = self.resolve_trait_reference(trait_ref
.ref_id
,
1935 assert
!(path_res
.depth
== 0);
1936 self.record_def(trait_ref
.ref_id
, path_res
);
1937 new_val
= Some((path_res
.base_def
.def_id(), trait_ref
.clone()));
1938 new_id
= Some(path_res
.base_def
.def_id());
1940 self.record_def(trait_ref
.ref_id
, err_path_resolution());
1942 intravisit
::walk_trait_ref(self, trait_ref
);
1944 let original_trait_ref
= replace(&mut self.current_trait_ref
, new_val
);
1945 let result
= f(self, new_id
);
1946 self.current_trait_ref
= original_trait_ref
;
1950 fn with_self_rib
<F
>(&mut self, self_def
: Def
, f
: F
)
1951 where F
: FnOnce(&mut Resolver
)
1953 let mut self_type_rib
= Rib
::new(NormalRibKind
);
1955 // plain insert (no renaming, types are not currently hygienic....)
1956 let name
= special_names
::type_self
;
1957 self_type_rib
.bindings
.insert(name
, self_def
);
1958 self.type_ribs
.push(self_type_rib
);
1961 self.type_ribs
.pop();
1965 fn resolve_implementation(&mut self,
1966 generics
: &Generics
,
1967 opt_trait_reference
: &Option
<TraitRef
>,
1970 impl_items
: &[ImplItem
]) {
1971 // If applicable, create a rib for the type parameters.
1972 self.with_type_parameter_rib(HasTypeParameters(generics
,
1976 // Resolve the type parameters.
1977 this
.visit_generics(generics
);
1979 // Resolve the trait reference, if necessary.
1980 this
.with_optional_trait_ref(opt_trait_reference
.as_ref(), |this
, trait_id
| {
1981 // Resolve the self type.
1982 this
.visit_ty(self_type
);
1984 this
.with_self_rib(Def
::SelfTy(trait_id
, Some((item_id
, self_type
.id
))), |this
| {
1985 this
.with_current_self_type(self_type
, |this
| {
1986 for impl_item
in impl_items
{
1987 match impl_item
.node
{
1988 hir
::ImplItemKind
::Const(..) => {
1989 // If this is a trait impl, ensure the const
1991 this
.check_trait_item(impl_item
.name
,
1993 |n
, s
| ResolutionError
::ConstNotMemberOfTrait(n
, s
));
1994 this
.with_constant_rib(|this
| {
1995 intravisit
::walk_impl_item(this
, impl_item
);
1998 hir
::ImplItemKind
::Method(ref sig
, _
) => {
1999 // If this is a trait impl, ensure the method
2001 this
.check_trait_item(impl_item
.name
,
2003 |n
, s
| ResolutionError
::MethodNotMemberOfTrait(n
, s
));
2005 // We also need a new scope for the method-
2006 // specific type parameters.
2007 let type_parameters
=
2008 HasTypeParameters(&sig
.generics
,
2011 this
.with_type_parameter_rib(type_parameters
, |this
| {
2012 intravisit
::walk_impl_item(this
, impl_item
);
2015 hir
::ImplItemKind
::Type(ref ty
) => {
2016 // If this is a trait impl, ensure the type
2018 this
.check_trait_item(impl_item
.name
,
2020 |n
, s
| ResolutionError
::TypeNotMemberOfTrait(n
, s
));
2032 fn check_trait_item
<F
>(&self, name
: Name
, span
: Span
, err
: F
)
2033 where F
: FnOnce(Name
, &str) -> ResolutionError
2035 // If there is a TraitRef in scope for an impl, then the method must be in the
2037 if let Some((did
, ref trait_ref
)) = self.current_trait_ref
{
2038 if !self.trait_item_map
.contains_key(&(name
, did
)) {
2039 let path_str
= path_names_to_string(&trait_ref
.path
, 0);
2040 resolve_error(self, span
, err(name
, &path_str
));
2045 fn resolve_local(&mut self, local
: &Local
) {
2046 // Resolve the type.
2047 walk_list
!(self, visit_ty
, &local
.ty
);
2049 // Resolve the initializer.
2050 walk_list
!(self, visit_expr
, &local
.init
);
2052 // Resolve the pattern.
2053 self.resolve_pattern(&local
.pat
, LocalIrrefutableMode
, &mut HashMap
::new());
2056 // build a map from pattern identifiers to binding-info's.
2057 // this is done hygienically. This could arise for a macro
2058 // that expands into an or-pattern where one 'x' was from the
2059 // user and one 'x' came from the macro.
2060 fn binding_mode_map(&mut self, pat
: &Pat
) -> BindingMap
{
2061 let mut result
= HashMap
::new();
2062 pat_bindings(&self.def_map
, pat
, |binding_mode
, _id
, sp
, path1
| {
2063 let name
= path1
.node
;
2067 binding_mode
: binding_mode
,
2073 // check that all of the arms in an or-pattern have exactly the
2074 // same set of bindings, with the same binding modes for each.
2075 fn check_consistent_bindings(&mut self, arm
: &Arm
) {
2076 if arm
.pats
.is_empty() {
2079 let map_0
= self.binding_mode_map(&arm
.pats
[0]);
2080 for (i
, p
) in arm
.pats
.iter().enumerate() {
2081 let map_i
= self.binding_mode_map(&p
);
2083 for (&key
, &binding_0
) in &map_0
{
2084 match map_i
.get(&key
) {
2088 ResolutionError
::VariableNotBoundInPattern(key
, i
+ 1));
2090 Some(binding_i
) => {
2091 if binding_0
.binding_mode
!= binding_i
.binding_mode
{
2094 ResolutionError
::VariableBoundWithDifferentMode(key
,
2101 for (&key
, &binding
) in &map_i
{
2102 if !map_0
.contains_key(&key
) {
2105 ResolutionError
::VariableNotBoundInParentPattern(key
, i
+ 1));
2111 fn resolve_arm(&mut self, arm
: &Arm
) {
2112 self.value_ribs
.push(Rib
::new(NormalRibKind
));
2114 let mut bindings_list
= HashMap
::new();
2115 for pattern
in &arm
.pats
{
2116 self.resolve_pattern(&pattern
, RefutableMode
, &mut bindings_list
);
2119 // This has to happen *after* we determine which
2120 // pat_idents are variants
2121 self.check_consistent_bindings(arm
);
2123 walk_list
!(self, visit_expr
, &arm
.guard
);
2124 self.visit_expr(&arm
.body
);
2127 self.value_ribs
.pop();
2131 fn resolve_block(&mut self, block
: &Block
) {
2132 debug
!("(resolving block) entering block");
2133 // Move down in the graph, if there's an anonymous module rooted here.
2134 let orig_module
= self.current_module
;
2135 let anonymous_module
=
2136 orig_module
.module_children
.borrow().get(&block
.id
).map(|module
| *module
);
2138 if let Some(anonymous_module
) = anonymous_module
{
2139 debug
!("(resolving block) found anonymous module, moving down");
2140 self.value_ribs
.push(Rib
::new(ModuleRibKind(anonymous_module
)));
2141 self.type_ribs
.push(Rib
::new(ModuleRibKind(anonymous_module
)));
2142 self.current_module
= anonymous_module
;
2144 self.value_ribs
.push(Rib
::new(NormalRibKind
));
2147 // Descend into the block.
2148 intravisit
::walk_block(self, block
);
2152 self.current_module
= orig_module
;
2153 self.value_ribs
.pop();
2154 if let Some(_
) = anonymous_module
{
2155 self.type_ribs
.pop();
2158 debug
!("(resolving block) leaving block");
2161 fn resolve_type(&mut self, ty
: &Ty
) {
2163 TyPath(ref maybe_qself
, ref path
) => {
2164 let resolution
= match self.resolve_possibly_assoc_item(ty
.id
,
2165 maybe_qself
.as_ref(),
2168 // `<T>::a::b::c` is resolved by typeck alone.
2169 TypecheckRequired
=> {
2170 // Resolve embedded types.
2171 intravisit
::walk_ty(self, ty
);
2174 ResolveAttempt(resolution
) => resolution
,
2177 // This is a path in the type namespace. Walk through scopes
2179 if let Some(def
) = resolution
{
2180 // Write the result into the def map.
2181 debug
!("(resolving type) writing resolution for `{}` (id {}) = {:?}",
2182 path_names_to_string(path
, 0), ty
.id
, def
);
2183 self.record_def(ty
.id
, def
);
2185 self.record_def(ty
.id
, err_path_resolution());
2187 // Keep reporting some errors even if they're ignored above.
2188 if let Err(true) = self.resolve_path(ty
.id
, path
, 0, TypeNS
) {
2189 // `resolve_path` already reported the error
2191 let kind
= if maybe_qself
.is_some() {
2197 let self_type_name
= special_idents
::type_self
.name
;
2198 let is_invalid_self_type_name
= path
.segments
.len() > 0 &&
2199 maybe_qself
.is_none() &&
2200 path
.segments
[0].identifier
.name
==
2202 if is_invalid_self_type_name
{
2205 ResolutionError
::SelfUsedOutsideImplOrTrait
);
2207 let segment
= path
.segments
.last();
2208 let segment
= segment
.expect("missing name in path");
2209 let type_name
= segment
.identifier
.name
;
2212 self.lookup_candidates(
2219 Def
::TyAlias(_
) => true,
2224 // create error object
2225 let name
= &path_names_to_string(path
, 0);
2227 ResolutionError
::UseOfUndeclared(
2233 resolve_error(self, ty
.span
, error
);
2240 // Resolve embedded types.
2241 intravisit
::walk_ty(self, ty
);
2244 fn resolve_pattern(&mut self,
2246 mode
: PatternBindingMode
,
2247 // Maps idents to the node ID for the (outermost)
2248 // pattern that binds them
2249 bindings_list
: &mut HashMap
<Name
, NodeId
>) {
2250 let pat_id
= pattern
.id
;
2251 pattern
.walk(|pattern
| {
2252 match pattern
.node
{
2253 PatKind
::Ident(binding_mode
, ref path1
, ref at_rhs
) => {
2254 // The meaning of PatKind::Ident with no type parameters
2255 // depends on whether an enum variant or unit-like struct
2256 // with that name is in scope. The probing lookup has to
2257 // be careful not to emit spurious errors. Only matching
2258 // patterns (match) can match nullary variants or
2259 // unit-like structs. For binding patterns (let
2260 // and the LHS of @-patterns), matching such a value is
2261 // simply disallowed (since it's rarely what you want).
2262 let const_ok
= mode
== RefutableMode
&& at_rhs
.is_none();
2264 let ident
= path1
.node
;
2265 let renamed
= ident
.name
;
2267 match self.resolve_bare_identifier_pattern(ident
, pattern
.span
) {
2268 FoundStructOrEnumVariant(def
) if const_ok
=> {
2269 debug
!("(resolving pattern) resolving `{}` to struct or enum variant",
2272 self.enforce_default_binding_mode(pattern
,
2275 self.record_def(pattern
.id
,
2281 FoundStructOrEnumVariant(..) => {
2285 ResolutionError
::DeclarationShadowsEnumVariantOrUnitLikeStruct(
2288 self.record_def(pattern
.id
, err_path_resolution());
2290 FoundConst(def
, _
) if const_ok
=> {
2291 debug
!("(resolving pattern) resolving `{}` to constant", renamed
);
2293 self.enforce_default_binding_mode(pattern
, binding_mode
, "a constant");
2294 self.record_def(pattern
.id
,
2300 FoundConst(def
, name
) => {
2304 ResolutionError
::OnlyIrrefutablePatternsAllowedHere(def
.def_id(),
2307 self.record_def(pattern
.id
, err_path_resolution());
2309 BareIdentifierPatternUnresolved
=> {
2310 debug
!("(resolving pattern) binding `{}`", renamed
);
2312 let def_id
= self.ast_map
.local_def_id(pattern
.id
);
2313 let def
= Def
::Local(def_id
, pattern
.id
);
2315 // Record the definition so that later passes
2316 // will be able to distinguish variants from
2317 // locals in patterns.
2319 self.record_def(pattern
.id
,
2325 // Add the binding to the local ribs, if it
2326 // doesn't already exist in the bindings list. (We
2327 // must not add it if it's in the bindings list
2328 // because that breaks the assumptions later
2329 // passes make about or-patterns.)
2330 if !bindings_list
.contains_key(&renamed
) {
2331 let this
= &mut *self;
2332 let last_rib
= this
.value_ribs
.last_mut().unwrap();
2333 last_rib
.bindings
.insert(renamed
, def
);
2334 bindings_list
.insert(renamed
, pat_id
);
2335 } else if mode
== ArgumentIrrefutableMode
&&
2336 bindings_list
.contains_key(&renamed
) {
2337 // Forbid duplicate bindings in the same
2342 ResolutionError
::IdentifierBoundMoreThanOnceInParameterList(
2343 &ident
.name
.as_str())
2345 } else if bindings_list
.get(&renamed
) == Some(&pat_id
) {
2346 // Then this is a duplicate variable in the
2347 // same disjunction, which is an error.
2351 ResolutionError
::IdentifierBoundMoreThanOnceInSamePattern(
2352 &ident
.name
.as_str())
2355 // Else, not bound in the same pattern: do
2361 PatKind
::TupleStruct(ref path
, _
) | PatKind
::Path(ref path
) => {
2362 // This must be an enum variant, struct or const.
2363 let resolution
= match self.resolve_possibly_assoc_item(pat_id
,
2367 // The below shouldn't happen because all
2368 // qualified paths should be in PatKind::QPath.
2369 TypecheckRequired
=>
2370 span_bug
!(path
.span
,
2371 "resolve_possibly_assoc_item claimed that a path \
2372 in PatKind::Path or PatKind::TupleStruct \
2373 requires typecheck to resolve, but qualified \
2374 paths should be PatKind::QPath"),
2375 ResolveAttempt(resolution
) => resolution
,
2377 if let Some(path_res
) = resolution
{
2378 match path_res
.base_def
{
2379 Def
::Struct(..) if path_res
.depth
== 0 => {
2380 self.record_def(pattern
.id
, path_res
);
2382 Def
::Variant(..) | Def
::Const(..) => {
2383 self.record_def(pattern
.id
, path_res
);
2385 Def
::Static(..) => {
2386 resolve_error(&self,
2388 ResolutionError
::StaticVariableReference
);
2389 self.record_def(pattern
.id
, err_path_resolution());
2392 // If anything ends up here entirely resolved,
2393 // it's an error. If anything ends up here
2394 // partially resolved, that's OK, because it may
2395 // be a `T::CONST` that typeck will resolve.
2396 if path_res
.depth
== 0 {
2400 ResolutionError
::NotAnEnumVariantStructOrConst(
2408 self.record_def(pattern
.id
, err_path_resolution());
2410 let const_name
= path
.segments
2415 let traits
= self.get_traits_containing_item(const_name
);
2416 self.trait_map
.insert(pattern
.id
, traits
);
2417 self.record_def(pattern
.id
, path_res
);
2425 ResolutionError
::UnresolvedEnumVariantStructOrConst(
2426 &path
.segments
.last().unwrap().identifier
.name
.as_str())
2428 self.record_def(pattern
.id
, err_path_resolution());
2430 intravisit
::walk_path(self, path
);
2433 PatKind
::QPath(ref qself
, ref path
) => {
2434 // Associated constants only.
2435 let resolution
= match self.resolve_possibly_assoc_item(pat_id
,
2439 TypecheckRequired
=> {
2440 // All `<T>::CONST` should end up here, and will
2441 // require use of the trait map to resolve
2442 // during typechecking.
2443 let const_name
= path
.segments
2448 let traits
= self.get_traits_containing_item(const_name
);
2449 self.trait_map
.insert(pattern
.id
, traits
);
2450 intravisit
::walk_pat(self, pattern
);
2453 ResolveAttempt(resolution
) => resolution
,
2455 if let Some(path_res
) = resolution
{
2456 match path_res
.base_def
{
2457 // All `<T as Trait>::CONST` should end up here, and
2458 // have the trait already selected.
2459 Def
::AssociatedConst(..) => {
2460 self.record_def(pattern
.id
, path_res
);
2466 ResolutionError
::NotAnAssociatedConst(
2467 &path
.segments
.last().unwrap().identifier
.name
.as_str()
2470 self.record_def(pattern
.id
, err_path_resolution());
2476 ResolutionError
::UnresolvedAssociatedConst(&path
.segments
2482 self.record_def(pattern
.id
, err_path_resolution());
2484 intravisit
::walk_pat(self, pattern
);
2487 PatKind
::Struct(ref path
, _
, _
) => {
2488 match self.resolve_path(pat_id
, path
, 0, TypeNS
) {
2490 self.record_def(pattern
.id
, definition
);
2492 Err(true) => self.record_def(pattern
.id
, err_path_resolution()),
2497 ResolutionError
::DoesNotNameAStruct(
2498 &path_names_to_string(path
, 0))
2500 self.record_def(pattern
.id
, err_path_resolution());
2503 intravisit
::walk_path(self, path
);
2506 PatKind
::Lit(_
) | PatKind
::Range(..) => {
2507 intravisit
::walk_pat(self, pattern
);
2518 fn resolve_bare_identifier_pattern(&mut self, ident
: hir
::Ident
, span
: Span
)
2519 -> BareIdentifierPatternResolution
{
2520 match self.resolve_ident_in_lexical_scope(ident
, ValueNS
, true)
2521 .map(LexicalScopeBinding
::def
) {
2522 Some(def @ Def
::Variant(..)) | Some(def @ Def
::Struct(..)) => {
2523 FoundStructOrEnumVariant(def
)
2525 Some(def @ Def
::Const(..)) | Some(def @ Def
::AssociatedConst(..)) => {
2526 FoundConst(def
, ident
.unhygienic_name
)
2528 Some(Def
::Static(..)) => {
2529 resolve_error(self, span
, ResolutionError
::StaticVariableReference
);
2530 BareIdentifierPatternUnresolved
2532 _
=> BareIdentifierPatternUnresolved
,
2536 /// Handles paths that may refer to associated items
2537 fn resolve_possibly_assoc_item(&mut self,
2539 maybe_qself
: Option
<&hir
::QSelf
>,
2541 namespace
: Namespace
)
2542 -> AssocItemResolveResult
{
2543 let max_assoc_types
;
2547 if qself
.position
== 0 {
2548 return TypecheckRequired
;
2550 max_assoc_types
= path
.segments
.len() - qself
.position
;
2551 // Make sure the trait is valid.
2552 let _
= self.resolve_trait_reference(id
, path
, max_assoc_types
);
2555 max_assoc_types
= path
.segments
.len();
2559 let mut resolution
= self.with_no_errors(|this
| {
2560 this
.resolve_path(id
, path
, 0, namespace
).ok()
2562 for depth
in 1..max_assoc_types
{
2563 if resolution
.is_some() {
2566 self.with_no_errors(|this
| {
2567 resolution
= this
.resolve_path(id
, path
, depth
, TypeNS
).ok();
2570 if let Some(Def
::Mod(_
)) = resolution
.map(|r
| r
.base_def
) {
2571 // A module is not a valid type or value.
2574 ResolveAttempt(resolution
)
2577 /// Skips `path_depth` trailing segments, which is also reflected in the
2578 /// returned value. See `hir::def::PathResolution` for more info.
2579 fn resolve_path(&mut self, id
: NodeId
, path
: &Path
, path_depth
: usize, namespace
: Namespace
)
2580 -> Result
<PathResolution
, bool
/* true if an error was reported */ > {
2581 let span
= path
.span
;
2582 let segments
= &path
.segments
[..path
.segments
.len() - path_depth
];
2584 let mk_res
= |def
| PathResolution
::new(def
, path_depth
);
2587 let def
= self.resolve_crate_relative_path(span
, segments
, namespace
);
2588 return def
.map(mk_res
);
2591 // Try to find a path to an item in a module.
2592 let last_ident
= segments
.last().unwrap().identifier
;
2593 // Resolve a single identifier with fallback to primitive types
2594 let resolve_identifier_with_fallback
= |this
: &mut Self, record_used
| {
2595 let def
= this
.resolve_identifier(last_ident
, namespace
, record_used
);
2597 None
| Some(LocalDef{def: Def::Mod(..), ..}
) if namespace
== TypeNS
=>
2598 this
.primitive_type_table
2600 .get(&last_ident
.unhygienic_name
)
2601 .map_or(def
, |prim_ty
| Some(LocalDef
::from_def(Def
::PrimTy(*prim_ty
)))),
2606 if segments
.len() == 1 {
2607 // In `a(::assoc_item)*` `a` cannot be a module. If `a` does resolve to a module we
2608 // don't report an error right away, but try to fallback to a primitive type.
2609 // So, we are still able to successfully resolve something like
2611 // use std::u8; // bring module u8 in scope
2612 // fn f() -> u8 { // OK, resolves to primitive u8, not to std::u8
2613 // u8::max_value() // OK, resolves to associated function <u8>::max_value,
2614 // // not to non-existent std::u8::max_value
2617 // Such behavior is required for backward compatibility.
2618 // The same fallback is used when `a` resolves to nothing.
2619 let def
= resolve_identifier_with_fallback(self, true).ok_or(false);
2620 return def
.and_then(|def
| self.adjust_local_def(def
, span
).ok_or(true)).map(mk_res
);
2623 let unqualified_def
= resolve_identifier_with_fallback(self, false);
2624 let def
= self.resolve_module_relative_path(span
, segments
, namespace
);
2625 match (def
, unqualified_def
) {
2626 (Ok(d
), Some(ref ud
)) if d
== ud
.def
=> {
2628 .add_lint(lint
::builtin
::UNUSED_QUALIFICATIONS
,
2631 "unnecessary qualification".to_string());
2639 // Resolve a single identifier
2640 fn resolve_identifier(&mut self,
2641 identifier
: hir
::Ident
,
2642 namespace
: Namespace
,
2644 -> Option
<LocalDef
> {
2645 if identifier
.name
== special_idents
::invalid
.name
{
2646 return Some(LocalDef
::from_def(Def
::Err
));
2649 self.resolve_ident_in_lexical_scope(identifier
, namespace
, record_used
)
2650 .map(LexicalScopeBinding
::local_def
)
2653 // Resolve a local definition, potentially adjusting for closures.
2654 fn adjust_local_def(&mut self, local_def
: LocalDef
, span
: Span
) -> Option
<Def
> {
2655 let ribs
= match local_def
.ribs
{
2656 Some((TypeNS
, i
)) => &self.type_ribs
[i
+ 1..],
2657 Some((ValueNS
, i
)) => &self.value_ribs
[i
+ 1..],
2660 let mut def
= local_def
.def
;
2663 span_bug
!(span
, "unexpected {:?} in bindings", def
)
2665 Def
::Local(_
, node_id
) => {
2668 NormalRibKind
| ModuleRibKind(..) => {
2669 // Nothing to do. Continue.
2671 ClosureRibKind(function_id
) => {
2673 let node_def_id
= self.ast_map
.local_def_id(node_id
);
2675 let seen
= self.freevars_seen
2677 .or_insert_with(|| NodeMap());
2678 if let Some(&index
) = seen
.get(&node_id
) {
2679 def
= Def
::Upvar(node_def_id
, node_id
, index
, function_id
);
2682 let vec
= self.freevars
2684 .or_insert_with(|| vec
![]);
2685 let depth
= vec
.len();
2691 def
= Def
::Upvar(node_def_id
, node_id
, depth
, function_id
);
2692 seen
.insert(node_id
, depth
);
2694 ItemRibKind
| MethodRibKind
=> {
2695 // This was an attempt to access an upvar inside a
2696 // named function item. This is not allowed, so we
2700 ResolutionError
::CannotCaptureDynamicEnvironmentInFnItem
);
2703 ConstantItemRibKind
=> {
2704 // Still doesn't deal with upvars
2707 ResolutionError
::AttemptToUseNonConstantValueInConstant
);
2713 Def
::TyParam(..) | Def
::SelfTy(..) => {
2716 NormalRibKind
| MethodRibKind
| ClosureRibKind(..) |
2717 ModuleRibKind(..) => {
2718 // Nothing to do. Continue.
2721 // This was an attempt to use a type parameter outside
2726 ResolutionError
::TypeParametersFromOuterFunction
);
2729 ConstantItemRibKind
=> {
2731 resolve_error(self, span
, ResolutionError
::OuterTypeParameterContext
);
2742 // resolve a "module-relative" path, e.g. a::b::c
2743 fn resolve_module_relative_path(&mut self,
2745 segments
: &[hir
::PathSegment
],
2746 namespace
: Namespace
)
2747 -> Result
<Def
, bool
/* true if an error was reported */> {
2748 let module_path
= segments
.split_last()
2752 .map(|ps
| ps
.identifier
.name
)
2753 .collect
::<Vec
<_
>>();
2755 let containing_module
;
2756 match self.resolve_module_path(&module_path
, UseLexicalScope
, span
) {
2758 let (span
, msg
) = match err
{
2759 Some((span
, msg
)) => (span
, msg
),
2761 let msg
= format
!("Use of undeclared type or module `{}`",
2762 names_to_string(&module_path
));
2767 resolve_error(self, span
, ResolutionError
::FailedToResolve(&msg
));
2770 Indeterminate
=> return Err(false),
2771 Success(resulting_module
) => {
2772 containing_module
= resulting_module
;
2776 let name
= segments
.last().unwrap().identifier
.name
;
2777 let result
= self.resolve_name_in_module(containing_module
, name
, namespace
, false, true);
2778 result
.success().map(|binding
| {
2779 self.check_privacy(containing_module
, name
, binding
, span
);
2780 binding
.def().unwrap()
2784 /// Invariant: This must be called only during main resolution, not during
2785 /// import resolution.
2786 fn resolve_crate_relative_path(&mut self,
2788 segments
: &[hir
::PathSegment
],
2789 namespace
: Namespace
)
2790 -> Result
<Def
, bool
/* true if an error was reported */> {
2791 let module_path
= segments
.split_last()
2795 .map(|ps
| ps
.identifier
.name
)
2796 .collect
::<Vec
<_
>>();
2798 let root_module
= self.graph_root
;
2800 let containing_module
;
2801 match self.resolve_module_path_from_root(root_module
,
2806 let (span
, msg
) = match err
{
2807 Some((span
, msg
)) => (span
, msg
),
2809 let msg
= format
!("Use of undeclared module `::{}`",
2810 names_to_string(&module_path
));
2815 resolve_error(self, span
, ResolutionError
::FailedToResolve(&msg
));
2819 Indeterminate
=> return Err(false),
2821 Success(resulting_module
) => {
2822 containing_module
= resulting_module
;
2826 let name
= segments
.last().unwrap().identifier
.name
;
2827 let result
= self.resolve_name_in_module(containing_module
, name
, namespace
, false, true);
2828 result
.success().map(|binding
| {
2829 self.check_privacy(containing_module
, name
, binding
, span
);
2830 binding
.def().unwrap()
2834 fn with_no_errors
<T
, F
>(&mut self, f
: F
) -> T
2835 where F
: FnOnce(&mut Resolver
) -> T
2837 self.emit_errors
= false;
2839 self.emit_errors
= true;
2843 fn find_fallback_in_self_type(&mut self, name
: Name
) -> FallbackSuggestion
{
2844 fn extract_path_and_node_id(t
: &Ty
,
2845 allow
: FallbackChecks
)
2846 -> Option
<(Path
, NodeId
, FallbackChecks
)> {
2848 TyPath(None
, ref path
) => Some((path
.clone(), t
.id
, allow
)),
2849 TyPtr(ref mut_ty
) => extract_path_and_node_id(&mut_ty
.ty
, OnlyTraitAndStatics
),
2850 TyRptr(_
, ref mut_ty
) => extract_path_and_node_id(&mut_ty
.ty
, allow
),
2851 // This doesn't handle the remaining `Ty` variants as they are not
2852 // that commonly the self_type, it might be interesting to provide
2853 // support for those in future.
2858 fn get_module
<'a
, 'tcx
>(this
: &mut Resolver
<'a
, 'tcx
>,
2860 name_path
: &[ast
::Name
])
2861 -> Option
<Module
<'a
>> {
2862 let last_name
= name_path
.last().unwrap();
2864 if name_path
.len() == 1 {
2865 match this
.primitive_type_table
.primitive_types
.get(last_name
) {
2867 None
=> this
.current_module
.resolve_name_in_lexical_scope(*last_name
, TypeNS
)
2868 .and_then(NameBinding
::module
)
2871 this
.resolve_module_path(&name_path
, UseLexicalScope
, span
).success()
2875 fn is_static_method(this
: &Resolver
, did
: DefId
) -> bool
{
2876 if let Some(node_id
) = this
.ast_map
.as_local_node_id(did
) {
2877 let sig
= match this
.ast_map
.get(node_id
) {
2878 hir_map
::NodeTraitItem(trait_item
) => match trait_item
.node
{
2879 hir
::MethodTraitItem(ref sig
, _
) => sig
,
2882 hir_map
::NodeImplItem(impl_item
) => match impl_item
.node
{
2883 hir
::ImplItemKind
::Method(ref sig
, _
) => sig
,
2888 sig
.explicit_self
.node
== hir
::SelfStatic
2890 this
.session
.cstore
.is_static_method(did
)
2894 let (path
, node_id
, allowed
) = match self.current_self_type
{
2895 Some(ref ty
) => match extract_path_and_node_id(ty
, Everything
) {
2897 None
=> return NoSuggestion
,
2899 None
=> return NoSuggestion
,
2902 if allowed
== Everything
{
2903 // Look for a field with the same name in the current self_type.
2904 match self.def_map
.borrow().get(&node_id
).map(|d
| d
.full_def()) {
2905 Some(Def
::Enum(did
)) |
2906 Some(Def
::TyAlias(did
)) |
2907 Some(Def
::Struct(did
)) |
2908 Some(Def
::Variant(_
, did
)) => match self.structs
.get(&did
) {
2911 if fields
.iter().any(|&field_name
| name
== field_name
) {
2916 _
=> {}
// Self type didn't resolve properly
2920 let name_path
= path
.segments
.iter().map(|seg
| seg
.identifier
.name
).collect
::<Vec
<_
>>();
2922 // Look for a method in the current self type's impl module.
2923 if let Some(module
) = get_module(self, path
.span
, &name_path
) {
2924 if let Some(binding
) = module
.resolve_name_in_lexical_scope(name
, ValueNS
) {
2925 if let Some(Def
::Method(did
)) = binding
.def() {
2926 if is_static_method(self, did
) {
2927 return StaticMethod(path_names_to_string(&path
, 0));
2929 if self.current_trait_ref
.is_some() {
2931 } else if allowed
== Everything
{
2938 // Look for a method in the current trait.
2939 if let Some((trait_did
, ref trait_ref
)) = self.current_trait_ref
{
2940 if let Some(&did
) = self.trait_item_map
.get(&(name
, trait_did
)) {
2941 if is_static_method(self, did
) {
2942 return TraitMethod(path_names_to_string(&trait_ref
.path
, 0));
2952 fn find_best_match(&mut self, name
: &str) -> SuggestionType
{
2953 if let Some(macro_name
) = self.session
.available_macros
2954 .borrow().iter().find(|n
| n
.as_str() == name
) {
2955 return SuggestionType
::Macro(format
!("{}!", macro_name
));
2958 let names
= self.value_ribs
2961 .flat_map(|rib
| rib
.bindings
.keys());
2963 if let Some(found
) = find_best_match_for_name(names
, name
, None
) {
2965 return SuggestionType
::Function(found
);
2967 } SuggestionType
::NotFound
2970 fn resolve_expr(&mut self, expr
: &Expr
) {
2971 // First, record candidate traits for this expression if it could
2972 // result in the invocation of a method call.
2974 self.record_candidate_traits_for_expr_if_necessary(expr
);
2976 // Next, resolve the node.
2978 ExprPath(ref maybe_qself
, ref path
) => {
2979 let resolution
= match self.resolve_possibly_assoc_item(expr
.id
,
2980 maybe_qself
.as_ref(),
2983 // `<T>::a::b::c` is resolved by typeck alone.
2984 TypecheckRequired
=> {
2985 let method_name
= path
.segments
.last().unwrap().identifier
.name
;
2986 let traits
= self.get_traits_containing_item(method_name
);
2987 self.trait_map
.insert(expr
.id
, traits
);
2988 intravisit
::walk_expr(self, expr
);
2991 ResolveAttempt(resolution
) => resolution
,
2994 // This is a local path in the value namespace. Walk through
2995 // scopes looking for it.
2996 if let Some(path_res
) = resolution
{
2997 // Check if struct variant
2998 let is_struct_variant
= if let Def
::Variant(_
, variant_id
) = path_res
.base_def
{
2999 self.structs
.contains_key(&variant_id
)
3003 if is_struct_variant
{
3004 let _
= self.structs
.contains_key(&path_res
.base_def
.def_id());
3005 let path_name
= path_names_to_string(path
, 0);
3007 let mut err
= resolve_struct_error(self,
3009 ResolutionError
::StructVariantUsedAsFunction(&path_name
));
3011 let msg
= format
!("did you mean to write: `{} {{ /* fields */ }}`?",
3013 if self.emit_errors
{
3014 err
.fileline_help(expr
.span
, &msg
);
3016 err
.span_help(expr
.span
, &msg
);
3019 self.record_def(expr
.id
, err_path_resolution());
3021 // Write the result into the def map.
3022 debug
!("(resolving expr) resolved `{}`",
3023 path_names_to_string(path
, 0));
3025 // Partial resolutions will need the set of traits in scope,
3026 // so they can be completed during typeck.
3027 if path_res
.depth
!= 0 {
3028 let method_name
= path
.segments
.last().unwrap().identifier
.name
;
3029 let traits
= self.get_traits_containing_item(method_name
);
3030 self.trait_map
.insert(expr
.id
, traits
);
3033 self.record_def(expr
.id
, path_res
);
3036 // Be helpful if the name refers to a struct
3037 // (The pattern matching def_tys where the id is in self.structs
3038 // matches on regular structs while excluding tuple- and enum-like
3039 // structs, which wouldn't result in this error.)
3040 let path_name
= path_names_to_string(path
, 0);
3041 let type_res
= self.with_no_errors(|this
| {
3042 this
.resolve_path(expr
.id
, path
, 0, TypeNS
)
3045 self.record_def(expr
.id
, err_path_resolution());
3047 if let Ok(Def
::Struct(..)) = type_res
.map(|r
| r
.base_def
) {
3049 ResolutionError
::StructVariantUsedAsFunction(&path_name
);
3050 let mut err
= resolve_struct_error(self, expr
.span
, error_variant
);
3052 let msg
= format
!("did you mean to write: `{} {{ /* fields */ }}`?",
3055 if self.emit_errors
{
3056 err
.fileline_help(expr
.span
, &msg
);
3058 err
.span_help(expr
.span
, &msg
);
3062 // Keep reporting some errors even if they're ignored above.
3063 if let Err(true) = self.resolve_path(expr
.id
, path
, 0, ValueNS
) {
3064 // `resolve_path` already reported the error
3066 let mut method_scope
= false;
3067 self.value_ribs
.iter().rev().all(|rib
| {
3068 method_scope
= match rib
.kind
{
3069 MethodRibKind
=> true,
3070 ItemRibKind
| ConstantItemRibKind
=> false,
3071 _
=> return true, // Keep advancing
3073 false // Stop advancing
3076 if method_scope
&& special_names
::self_
.as_str() == &path_name
[..] {
3079 ResolutionError
::SelfNotAvailableInStaticMethod
);
3081 let last_name
= path
.segments
.last().unwrap().identifier
.name
;
3082 let mut msg
= match self.find_fallback_in_self_type(last_name
) {
3084 // limit search to 5 to reduce the number
3085 // of stupid suggestions
3086 match self.find_best_match(&path_name
) {
3087 SuggestionType
::Macro(s
) => {
3088 format
!("the macro `{}`", s
)
3090 SuggestionType
::Function(s
) => format
!("`{}`", s
),
3091 SuggestionType
::NotFound
=> "".to_string(),
3094 Field
=> format
!("`self.{}`", path_name
),
3096 TraitItem
=> format
!("to call `self.{}`", path_name
),
3097 TraitMethod(path_str
) |
3098 StaticMethod(path_str
) =>
3099 format
!("to call `{}::{}`", path_str
, path_name
),
3102 let mut context
= UnresolvedNameContext
::Other
;
3103 if !msg
.is_empty() {
3104 msg
= format
!(". Did you mean {}?", msg
);
3106 // we check if this a module and if so, we display a help
3108 let name_path
= path
.segments
.iter()
3109 .map(|seg
| seg
.identifier
.name
)
3110 .collect
::<Vec
<_
>>();
3112 match self.resolve_module_path(&name_path
[..],
3116 context
= UnresolvedNameContext
::PathIsMod(expr
.id
);
3124 ResolutionError
::UnresolvedName(
3125 &path_name
, &msg
, context
));
3131 intravisit
::walk_expr(self, expr
);
3134 ExprStruct(ref path
, _
, _
) => {
3135 // Resolve the path to the structure it goes to. We don't
3136 // check to ensure that the path is actually a structure; that
3137 // is checked later during typeck.
3138 match self.resolve_path(expr
.id
, path
, 0, TypeNS
) {
3139 Ok(definition
) => self.record_def(expr
.id
, definition
),
3140 Err(true) => self.record_def(expr
.id
, err_path_resolution()),
3142 debug
!("(resolving expression) didn't find struct def",);
3146 ResolutionError
::DoesNotNameAStruct(
3147 &path_names_to_string(path
, 0))
3149 self.record_def(expr
.id
, err_path_resolution());
3153 intravisit
::walk_expr(self, expr
);
3156 ExprLoop(_
, Some(label
)) | ExprWhile(_
, _
, Some(label
)) => {
3157 self.with_label_rib(|this
| {
3158 let def
= Def
::Label(expr
.id
);
3161 let rib
= this
.label_ribs
.last_mut().unwrap();
3162 rib
.bindings
.insert(label
.name
, def
);
3165 intravisit
::walk_expr(this
, expr
);
3169 ExprBreak(Some(label
)) | ExprAgain(Some(label
)) => {
3170 match self.search_label(label
.node
.name
) {
3172 self.record_def(expr
.id
, err_path_resolution());
3175 ResolutionError
::UndeclaredLabel(&label
.node
.name
.as_str()))
3177 Some(def @ Def
::Label(_
)) => {
3178 // Since this def is a label, it is never read.
3179 self.record_def(expr
.id
,
3186 span_bug
!(expr
.span
, "label wasn't mapped to a label def!")
3192 intravisit
::walk_expr(self, expr
);
3197 fn record_candidate_traits_for_expr_if_necessary(&mut self, expr
: &Expr
) {
3199 ExprField(_
, name
) => {
3200 // FIXME(#6890): Even though you can't treat a method like a
3201 // field, we need to add any trait methods we find that match
3202 // the field name so that we can do some nice error reporting
3203 // later on in typeck.
3204 let traits
= self.get_traits_containing_item(name
.node
);
3205 self.trait_map
.insert(expr
.id
, traits
);
3207 ExprMethodCall(name
, _
, _
) => {
3208 debug
!("(recording candidate traits for expr) recording traits for {}",
3210 let traits
= self.get_traits_containing_item(name
.node
);
3211 self.trait_map
.insert(expr
.id
, traits
);
3219 fn get_traits_containing_item(&mut self, name
: Name
) -> Vec
<DefId
> {
3220 debug
!("(getting traits containing item) looking for '{}'", name
);
3222 fn add_trait_info(found_traits
: &mut Vec
<DefId
>, trait_def_id
: DefId
, name
: Name
) {
3223 debug
!("(adding trait info) found trait {:?} for method '{}'",
3226 found_traits
.push(trait_def_id
);
3229 let mut found_traits
= Vec
::new();
3230 // Look for the current trait.
3231 if let Some((trait_def_id
, _
)) = self.current_trait_ref
{
3232 if self.trait_item_map
.contains_key(&(name
, trait_def_id
)) {
3233 add_trait_info(&mut found_traits
, trait_def_id
, name
);
3237 let mut search_module
= self.current_module
;
3239 // Look for trait children.
3240 let mut search_in_module
= |module
: Module
<'a
>| {
3241 let mut traits
= module
.traits
.borrow_mut();
3242 if traits
.is_none() {
3243 let mut collected_traits
= Vec
::new();
3244 module
.for_each_child(|_
, ns
, binding
| {
3245 if ns
!= TypeNS { return }
3246 if let Some(Def
::Trait(_
)) = binding
.def() {
3247 collected_traits
.push(binding
);
3250 *traits
= Some(collected_traits
.into_boxed_slice());
3253 for binding
in traits
.as_ref().unwrap().iter() {
3254 let trait_def_id
= binding
.def().unwrap().def_id();
3255 if self.trait_item_map
.contains_key(&(name
, trait_def_id
)) {
3256 add_trait_info(&mut found_traits
, trait_def_id
, name
);
3257 let trait_name
= self.get_trait_name(trait_def_id
);
3258 self.record_use(trait_name
, TypeNS
, binding
);
3262 search_in_module(search_module
);
3264 match search_module
.parent_link
{
3265 NoParentLink
| ModuleParentLink(..) => {
3266 search_module
.prelude
.borrow().map(search_in_module
);
3269 BlockParentLink(parent_module
, _
) => {
3270 search_module
= parent_module
;
3278 /// When name resolution fails, this method can be used to look up candidate
3279 /// entities with the expected name. It allows filtering them using the
3280 /// supplied predicate (which should be used to only accept the types of
3281 /// definitions expected e.g. traits). The lookup spans across all crates.
3283 /// NOTE: The method does not look into imports, but this is not a problem,
3284 /// since we report the definitions (thus, the de-aliased imports).
3285 fn lookup_candidates
<FilterFn
>(&mut self,
3287 namespace
: Namespace
,
3288 filter_fn
: FilterFn
) -> SuggestedCandidates
3289 where FilterFn
: Fn(Def
) -> bool
{
3291 let mut lookup_results
= Vec
::new();
3292 let mut worklist
= Vec
::new();
3293 worklist
.push((self.graph_root
, Vec
::new(), false));
3295 while let Some((in_module
,
3297 in_module_is_extern
)) = worklist
.pop() {
3298 self.populate_module_if_necessary(in_module
);
3300 in_module
.for_each_child(|name
, ns
, name_binding
| {
3302 // avoid imports entirely
3303 if name_binding
.is_import() { return; }
3305 // collect results based on the filter function
3306 if let Some(def
) = name_binding
.def() {
3307 if name
== lookup_name
&& ns
== namespace
&& filter_fn(def
) {
3309 let ident
= hir
::Ident
::from_name(name
);
3310 let params
= PathParameters
::none();
3311 let segment
= PathSegment
{
3315 let span
= name_binding
.span
.unwrap_or(syntax
::codemap
::DUMMY_SP
);
3316 let mut segms
= path_segments
.clone();
3317 segms
.push(segment
);
3318 let segms
= HirVec
::from_vec(segms
);
3324 // the entity is accessible in the following cases:
3325 // 1. if it's defined in the same crate, it's always
3326 // accessible (since private entities can be made public)
3327 // 2. if it's defined in another crate, it's accessible
3328 // only if both the module is public and the entity is
3329 // declared as public (due to pruning, we don't explore
3330 // outside crate private modules => no need to check this)
3331 if !in_module_is_extern
|| name_binding
.is_public() {
3332 lookup_results
.push(path
);
3337 // collect submodules to explore
3338 if let Some(module
) = name_binding
.module() {
3340 let path_segments
= match module
.parent_link
{
3341 NoParentLink
=> path_segments
.clone(),
3342 ModuleParentLink(_
, name
) => {
3343 let mut paths
= path_segments
.clone();
3344 let ident
= hir
::Ident
::from_name(name
);
3345 let params
= PathParameters
::none();
3346 let segm
= PathSegment
{
3356 if !in_module_is_extern
|| name_binding
.is_public() {
3357 // add the module to the lookup
3358 let is_extern
= in_module_is_extern
|| name_binding
.is_extern_crate();
3359 worklist
.push((module
, path_segments
, is_extern
));
3365 SuggestedCandidates
{
3366 name
: lookup_name
.as_str().to_string(),
3367 candidates
: lookup_results
,
3371 fn record_def(&mut self, node_id
: NodeId
, resolution
: PathResolution
) {
3372 debug
!("(recording def) recording {:?} for {}", resolution
, node_id
);
3373 if let Some(prev_res
) = self.def_map
.borrow_mut().insert(node_id
, resolution
) {
3374 let span
= self.ast_map
.opt_span(node_id
).unwrap_or(codemap
::DUMMY_SP
);
3376 "path resolved multiple times ({:?} before, {:?} now)",
3382 fn enforce_default_binding_mode(&mut self,
3384 pat_binding_mode
: BindingMode
,
3386 match pat_binding_mode
{
3387 BindByValue(_
) => {}
3391 ResolutionError
::CannotUseRefBindingModeWith(descr
));
3396 fn is_visible(&self, binding
: &'a NameBinding
<'a
>, parent
: Module
<'a
>) -> bool
{
3397 binding
.is_public() || parent
.is_ancestor_of(self.current_module
)
3400 fn check_privacy(&mut self,
3403 binding
: &'a NameBinding
<'a
>,
3405 if !self.is_visible(binding
, module
) {
3406 self.privacy_errors
.push(PrivacyError(span
, name
, binding
));
3410 fn report_privacy_errors(&self) {
3411 if self.privacy_errors
.len() == 0 { return }
3412 let mut reported_spans
= HashSet
::new();
3413 for &PrivacyError(span
, name
, binding
) in &self.privacy_errors
{
3414 if !reported_spans
.insert(span
) { continue }
3415 if binding
.is_extern_crate() {
3416 // Warn when using an inaccessible extern crate.
3417 let node_id
= binding
.module().unwrap().extern_crate_id
.unwrap();
3418 let msg
= format
!("extern crate `{}` is private", name
);
3419 self.session
.add_lint(lint
::builtin
::INACCESSIBLE_EXTERN_CRATE
, node_id
, span
, msg
);
3421 let def
= binding
.def().unwrap();
3422 self.session
.span_err(span
, &format
!("{} `{}` is private", def
.kind_name(), name
));
3427 fn report_conflict(&self,
3431 binding
: &NameBinding
,
3432 old_binding
: &NameBinding
) {
3433 // Error on the second of two conflicting names
3434 if old_binding
.span
.unwrap().lo
> binding
.span
.unwrap().lo
{
3435 return self.report_conflict(parent
, name
, ns
, old_binding
, binding
);
3438 let container
= match parent
.def
{
3439 Some(Def
::Mod(_
)) => "module",
3440 Some(Def
::Trait(_
)) => "trait",
3445 let (participle
, noun
) = match old_binding
.is_import() || old_binding
.is_extern_crate() {
3446 true => ("imported", "import"),
3447 false => ("defined", "definition"),
3450 let span
= binding
.span
.unwrap();
3452 let kind
= match (ns
, old_binding
.module()) {
3453 (ValueNS
, _
) => "a value",
3454 (TypeNS
, Some(module
)) if module
.extern_crate_id
.is_some() => "an extern crate",
3455 (TypeNS
, Some(module
)) if module
.is_normal() => "a module",
3456 (TypeNS
, Some(module
)) if module
.is_trait() => "a trait",
3457 (TypeNS
, _
) => "a type",
3459 format
!("{} named `{}` has already been {} in this {}",
3460 kind
, name
, participle
, container
)
3463 let mut err
= match (old_binding
.is_extern_crate(), binding
.is_extern_crate()) {
3464 (true, true) => struct_span_err
!(self.session
, span
, E0259
, "{}", msg
),
3465 (true, _
) | (_
, true) if binding
.is_import() || old_binding
.is_import() =>
3466 struct_span_err
!(self.session
, span
, E0254
, "{}", msg
),
3467 (true, _
) | (_
, true) => struct_span_err
!(self.session
, span
, E0260
, "{}", msg
),
3468 _
=> match (old_binding
.is_import(), binding
.is_import()) {
3469 (false, false) => struct_span_err
!(self.session
, span
, E0428
, "{}", msg
),
3470 (true, true) => struct_span_err
!(self.session
, span
, E0252
, "{}", msg
),
3471 _
=> struct_span_err
!(self.session
, span
, E0255
, "{}", msg
),
3475 let span
= old_binding
.span
.unwrap();
3476 if span
!= codemap
::DUMMY_SP
{
3477 err
.span_note(span
, &format
!("previous {} of `{}` here", noun
, name
));
3483 fn names_to_string(names
: &[Name
]) -> String
{
3484 let mut first
= true;
3485 let mut result
= String
::new();
3490 result
.push_str("::")
3492 result
.push_str(&name
.as_str());
3497 fn path_names_to_string(path
: &Path
, depth
: usize) -> String
{
3498 let names
: Vec
<ast
::Name
> = path
.segments
[..path
.segments
.len() - depth
]
3500 .map(|seg
| seg
.identifier
.name
)
3502 names_to_string(&names
[..])
3505 /// When an entity with a given name is not available in scope, we search for
3506 /// entities with that name in all crates. This method allows outputting the
3507 /// results of this search in a programmer-friendly way
3508 fn show_candidates(session
: &mut DiagnosticBuilder
,
3509 span
: syntax
::codemap
::Span
,
3510 candidates
: &SuggestedCandidates
) {
3512 let paths
= &candidates
.candidates
;
3514 if paths
.len() > 0 {
3515 // don't show more than MAX_CANDIDATES results, so
3516 // we're consistent with the trait suggestions
3517 const MAX_CANDIDATES
: usize = 5;
3519 // we want consistent results across executions, but candidates are produced
3520 // by iterating through a hash map, so make sure they are ordered:
3521 let mut path_strings
: Vec
<_
> = paths
.into_iter()
3522 .map(|p
| path_names_to_string(&p
, 0))
3524 path_strings
.sort();
3526 // behave differently based on how many candidates we have:
3527 if !paths
.is_empty() {
3528 if paths
.len() == 1 {
3529 session
.fileline_help(
3531 &format
!("you can import it into scope: `use {};`.",
3535 session
.fileline_help(span
, "you can import several candidates \
3536 into scope (`use ...;`):");
3537 let count
= path_strings
.len() as isize - MAX_CANDIDATES
as isize + 1;
3539 for (idx
, path_string
) in path_strings
.iter().enumerate() {
3540 if idx
== MAX_CANDIDATES
- 1 && count
> 1 {
3541 session
.fileline_help(
3543 &format
!(" and {} other candidates", count
).to_string(),
3547 session
.fileline_help(
3549 &format
!(" `{}`", path_string
).to_string(),
3557 session
.fileline_help(
3559 &format
!("no candidates by the name of `{}` found in your \
3560 project; maybe you misspelled the name or forgot to import \
3561 an external crate?", candidates
.name
.to_string()),
3566 /// A somewhat inefficient routine to obtain the name of a module.
3567 fn module_to_string(module
: Module
) -> String
{
3568 let mut names
= Vec
::new();
3570 fn collect_mod(names
: &mut Vec
<ast
::Name
>, module
: Module
) {
3571 match module
.parent_link
{
3573 ModuleParentLink(ref module
, name
) => {
3575 collect_mod(names
, module
);
3577 BlockParentLink(ref module
, _
) => {
3578 // danger, shouldn't be ident?
3579 names
.push(special_idents
::opaque
.name
);
3580 collect_mod(names
, module
);
3584 collect_mod(&mut names
, module
);
3586 if names
.is_empty() {
3587 return "???".to_string();
3589 names_to_string(&names
.into_iter().rev().collect
::<Vec
<ast
::Name
>>())
3592 fn err_path_resolution() -> PathResolution
{
3600 pub struct CrateMap
{
3601 pub def_map
: RefCell
<DefMap
>,
3602 pub freevars
: FreevarMap
,
3603 pub export_map
: ExportMap
,
3604 pub trait_map
: TraitMap
,
3605 pub glob_map
: Option
<GlobMap
>,
3608 #[derive(PartialEq,Copy, Clone)]
3609 pub enum MakeGlobMap
{
3614 /// Entry point to crate resolution.
3615 pub fn resolve_crate
<'a
, 'tcx
>(session
: &'a Session
,
3616 ast_map
: &'a hir_map
::Map
<'tcx
>,
3617 make_glob_map
: MakeGlobMap
)
3619 // Currently, we ignore the name resolution data structures for
3620 // the purposes of dependency tracking. Instead we will run name
3621 // resolution and include its output in the hash of each item,
3622 // much like we do for macro expansion. In other words, the hash
3623 // reflects not just its contents but the results of name
3624 // resolution on those contents. Hopefully we'll push this back at
3626 let _task
= ast_map
.dep_graph
.in_task(DepNode
::Resolve
);
3628 let krate
= ast_map
.krate();
3629 let arenas
= Resolver
::arenas();
3630 let mut resolver
= create_resolver(session
, ast_map
, krate
, make_glob_map
, &arenas
, None
);
3632 resolver
.resolve_crate(krate
);
3634 check_unused
::check_crate(&mut resolver
, krate
);
3635 resolver
.report_privacy_errors();
3638 def_map
: resolver
.def_map
,
3639 freevars
: resolver
.freevars
,
3640 export_map
: resolver
.export_map
,
3641 trait_map
: resolver
.trait_map
,
3642 glob_map
: if resolver
.make_glob_map
{
3643 Some(resolver
.glob_map
)
3650 /// Builds a name resolution walker to be used within this module,
3651 /// or used externally, with an optional callback function.
3653 /// The callback takes a &mut bool which allows callbacks to end a
3654 /// walk when set to true, passing through the rest of the walk, while
3655 /// preserving the ribs + current module. This allows resolve_path
3656 /// calls to be made with the correct scope info. The node in the
3657 /// callback corresponds to the current node in the walk.
3658 fn create_resolver
<'a
, 'tcx
>(session
: &'a Session
,
3659 ast_map
: &'a hir_map
::Map
<'tcx
>,
3661 make_glob_map
: MakeGlobMap
,
3662 arenas
: &'a ResolverArenas
<'a
>,
3663 callback
: Option
<Box
<Fn(hir_map
::Node
, &mut bool
) -> bool
>>)
3664 -> Resolver
<'a
, 'tcx
> {
3665 let mut resolver
= Resolver
::new(session
, ast_map
, make_glob_map
, arenas
);
3667 resolver
.callback
= callback
;
3669 resolver
.build_reduced_graph(krate
);
3671 resolve_imports
::resolve_imports(&mut resolver
);
3676 __build_diagnostic_array
! { librustc_resolve, DIAGNOSTICS }