Tidying up and reformatting
This commit is contained in:
parent
a5479622ea
commit
0dd0925f57
@ -65,7 +65,7 @@ pub enum Def {
|
||||
/// <T as Trait>::AssocX::AssocY::MethodOrAssocType
|
||||
/// ^~~~~~~~~~~~~~ ^~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
/// base_def depth = 2
|
||||
#[derive(Copy, Debug)]
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct PathResolution {
|
||||
pub base_def: Def,
|
||||
pub last_private: LastPrivate,
|
||||
@ -85,6 +85,17 @@ impl PathResolution {
|
||||
pub fn def_id(&self) -> ast::DefId {
|
||||
self.full_def().def_id()
|
||||
}
|
||||
|
||||
pub fn new(base_def: Def,
|
||||
last_private: LastPrivate,
|
||||
depth: usize)
|
||||
-> PathResolution {
|
||||
PathResolution {
|
||||
base_def: base_def,
|
||||
last_private: last_private,
|
||||
depth: depth,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Definition mapping
|
||||
|
@ -32,7 +32,7 @@ pub type ExternalExports = DefIdSet;
|
||||
/// reexporting a public struct doesn't inline the doc).
|
||||
pub type PublicItems = NodeSet;
|
||||
|
||||
#[derive(Copy, Debug)]
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub enum LastPrivate {
|
||||
LastMod(PrivateDep),
|
||||
// `use` directives (imports) can refer to two separate definitions in the
|
||||
@ -46,14 +46,14 @@ pub enum LastPrivate {
|
||||
type_used: ImportUse},
|
||||
}
|
||||
|
||||
#[derive(Copy, Debug)]
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub enum PrivateDep {
|
||||
AllPublic,
|
||||
DependsOn(ast::DefId),
|
||||
}
|
||||
|
||||
// How an import is used.
|
||||
#[derive(Copy, PartialEq, Debug)]
|
||||
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||
pub enum ImportUse {
|
||||
Unused, // The import is not used.
|
||||
Used, // The import is used.
|
||||
|
@ -162,9 +162,12 @@ impl NamespaceResult {
|
||||
}
|
||||
|
||||
enum NameDefinition {
|
||||
NoNameDefinition, //< The name was unbound.
|
||||
ChildNameDefinition(Def, LastPrivate), //< The name identifies an immediate child.
|
||||
ImportNameDefinition(Def, LastPrivate) //< The name identifies an import.
|
||||
// The name was unbound.
|
||||
NoNameDefinition,
|
||||
// The name identifies an immediate child.
|
||||
ChildNameDefinition(Def, LastPrivate),
|
||||
// The name identifies an import.
|
||||
ImportNameDefinition(Def, LastPrivate),
|
||||
}
|
||||
|
||||
impl<'a, 'v, 'tcx> Visitor<'v> for Resolver<'a, 'tcx> {
|
||||
@ -795,11 +798,6 @@ pub struct Resolver<'a, 'tcx:'a> {
|
||||
// The current self type if inside an impl (used for better errors).
|
||||
current_self_type: Option<Ty>,
|
||||
|
||||
// The ident for the keyword "self".
|
||||
self_name: Name,
|
||||
// The ident for the non-keyword "Self".
|
||||
type_self_name: Name,
|
||||
|
||||
// The idents for the primitive types.
|
||||
primitive_type_table: PrimitiveTypeTable,
|
||||
|
||||
@ -869,9 +867,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
current_trait_ref: None,
|
||||
current_self_type: None,
|
||||
|
||||
self_name: special_names::self_,
|
||||
type_self_name: special_names::type_self,
|
||||
|
||||
primitive_type_table: PrimitiveTypeTable::new(),
|
||||
|
||||
def_map: RefCell::new(NodeMap()),
|
||||
@ -1822,7 +1817,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
let mut self_type_rib = Rib::new(ItemRibKind);
|
||||
|
||||
// plain insert (no renaming, types are not currently hygienic....)
|
||||
let name = self.type_self_name;
|
||||
let name = special_names::type_self;
|
||||
self_type_rib.bindings.insert(name, DlDef(DefSelfTy(item.id)));
|
||||
self.type_ribs.push(self_type_rib);
|
||||
|
||||
@ -2047,8 +2042,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
|
||||
fn with_optional_trait_ref<T, F>(&mut self,
|
||||
opt_trait_ref: Option<&TraitRef>,
|
||||
f: F) -> T where
|
||||
F: FnOnce(&mut Resolver) -> T,
|
||||
f: F)
|
||||
-> T
|
||||
where F: FnOnce(&mut Resolver) -> T,
|
||||
{
|
||||
let mut new_val = None;
|
||||
if let Some(trait_ref) = opt_trait_ref {
|
||||
@ -2585,11 +2581,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
let span = path.span;
|
||||
let segments = &path.segments[..path.segments.len()-path_depth];
|
||||
|
||||
let mk_res = |(def, lp)| PathResolution {
|
||||
base_def: def,
|
||||
last_private: lp,
|
||||
depth: path_depth
|
||||
};
|
||||
let mk_res = |(def, lp)| PathResolution::new(def, lp, path_depth);
|
||||
|
||||
if path.global {
|
||||
let def = self.resolve_crate_relative_path(span, segments, namespace);
|
||||
@ -2603,25 +2595,25 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
check_ribs,
|
||||
span);
|
||||
|
||||
if segments.len() > 1 {
|
||||
let def = self.resolve_module_relative_path(span, segments, namespace);
|
||||
match (def, unqualified_def) {
|
||||
(Some((ref d, _)), Some((ref ud, _))) if *d == *ud => {
|
||||
self.session
|
||||
.add_lint(lint::builtin::UNUSED_QUALIFICATIONS,
|
||||
id, span,
|
||||
"unnecessary qualification".to_string());
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
|
||||
def.map(mk_res)
|
||||
} else {
|
||||
unqualified_def.map(mk_res)
|
||||
if segments.len() <= 1 {
|
||||
return unqualified_def.map(mk_res);
|
||||
}
|
||||
|
||||
let def = self.resolve_module_relative_path(span, segments, namespace);
|
||||
match (def, unqualified_def) {
|
||||
(Some((ref d, _)), Some((ref ud, _))) if *d == *ud => {
|
||||
self.session
|
||||
.add_lint(lint::builtin::UNUSED_QUALIFICATIONS,
|
||||
id, span,
|
||||
"unnecessary qualification".to_string());
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
def.map(mk_res)
|
||||
}
|
||||
|
||||
// resolve a single identifier (used as a varref)
|
||||
// Resolve a single identifier.
|
||||
fn resolve_identifier(&mut self,
|
||||
identifier: Ident,
|
||||
namespace: Namespace,
|
||||
@ -2662,8 +2654,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
match child_name_bindings.def_for_namespace(namespace) {
|
||||
Some(def) => {
|
||||
// Found it. Stop the search here.
|
||||
let p = child_name_bindings.defined_in_public_namespace(
|
||||
namespace);
|
||||
let p = child_name_bindings.defined_in_public_namespace(namespace);
|
||||
let lp = if p {LastMod(AllPublic)} else {
|
||||
LastMod(DependsOn(def.def_id()))
|
||||
};
|
||||
@ -2734,8 +2725,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
|
||||
let containing_module;
|
||||
let last_private;
|
||||
let module = self.current_module.clone();
|
||||
match self.resolve_module_path(module,
|
||||
let current_module = self.current_module.clone();
|
||||
match self.resolve_module_path(current_module,
|
||||
&module_path[..],
|
||||
UseLexicalScope,
|
||||
span,
|
||||
@ -2858,8 +2849,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
|
||||
match search_result {
|
||||
Some(DlDef(def)) => {
|
||||
debug!("(resolving path in local ribs) resolved `{}` to \
|
||||
local: {:?}",
|
||||
debug!("(resolving path in local ribs) resolved `{}` to local: {:?}",
|
||||
token::get_ident(ident),
|
||||
def);
|
||||
Some(def)
|
||||
@ -2904,15 +2894,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
panic!("unexpected indeterminate result");
|
||||
}
|
||||
Failed(err) => {
|
||||
match err {
|
||||
Some((span, msg)) =>
|
||||
self.resolve_error(span, &format!("failed to resolve. {}",
|
||||
msg)),
|
||||
None => ()
|
||||
}
|
||||
|
||||
debug!("(resolving item path by identifier in lexical scope) \
|
||||
failed to resolve {}", token::get_name(name));
|
||||
|
||||
if let Some((span, msg)) = err {
|
||||
self.resolve_error(span, &format!("failed to resolve. {}", msg))
|
||||
}
|
||||
|
||||
return None;
|
||||
}
|
||||
}
|
||||
@ -2964,10 +2952,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
}
|
||||
} else {
|
||||
match this.resolve_module_path(root,
|
||||
&name_path[..],
|
||||
UseLexicalScope,
|
||||
span,
|
||||
PathSearch) {
|
||||
&name_path[..],
|
||||
UseLexicalScope,
|
||||
span,
|
||||
PathSearch) {
|
||||
Success((module, _)) => Some(module),
|
||||
_ => None
|
||||
}
|
||||
@ -3203,8 +3191,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
false // Stop advancing
|
||||
});
|
||||
|
||||
if method_scope && &token::get_name(self.self_name)[..]
|
||||
== path_name {
|
||||
if method_scope &&
|
||||
&token::get_name(special_names::self_)[..] == path_name {
|
||||
self.resolve_error(
|
||||
expr.span,
|
||||
"`self` is not available \
|
||||
|
@ -140,13 +140,7 @@ pub trait AstConv<'tcx> {
|
||||
span: Span,
|
||||
_trait_ref: Rc<ty::TraitRef<'tcx>>,
|
||||
_item_name: ast::Name)
|
||||
-> Ty<'tcx>
|
||||
{
|
||||
span_err!(self.tcx().sess, span, E0213,
|
||||
"associated types are not accepted in this context");
|
||||
|
||||
self.tcx().types.err
|
||||
}
|
||||
-> Ty<'tcx>;
|
||||
}
|
||||
|
||||
pub fn ast_region_to_region(tcx: &ty::ctxt, lifetime: &ast::Lifetime)
|
||||
@ -924,9 +918,12 @@ fn ast_path_to_ty<'tcx>(
|
||||
}
|
||||
};
|
||||
|
||||
let substs = ast_path_substs_for_ty(this, rscope,
|
||||
span, param_mode,
|
||||
&generics, item_segment);
|
||||
let substs = ast_path_substs_for_ty(this,
|
||||
rscope,
|
||||
span,
|
||||
param_mode,
|
||||
&generics,
|
||||
item_segment);
|
||||
|
||||
// FIXME(#12938): This is a hack until we have full support for DST.
|
||||
if Some(did) == this.tcx().lang_items.owned_box() {
|
||||
@ -1044,6 +1041,12 @@ fn report_ambiguous_associated_type(tcx: &ty::ctxt,
|
||||
type_str, trait_str, name);
|
||||
}
|
||||
|
||||
// Create a type from a a path to an associated type.
|
||||
// For a path A::B::C::D, ty and ty_path_def are the type and def for A::B::C
|
||||
// and item_segment is the path segment for D. We return a type and a def for
|
||||
// the whole path.
|
||||
// Will fail except for T::A and Self::A; i.e., if ty/ty_path_def are not a type
|
||||
// parameter or Self.
|
||||
fn associated_path_def_to_ty<'tcx>(this: &AstConv<'tcx>,
|
||||
span: Span,
|
||||
ty: Ty<'tcx>,
|
||||
@ -1052,35 +1055,43 @@ fn associated_path_def_to_ty<'tcx>(this: &AstConv<'tcx>,
|
||||
-> (Ty<'tcx>, def::Def)
|
||||
{
|
||||
let tcx = this.tcx();
|
||||
check_path_args(tcx, slice::ref_slice(item_segment), NO_TPS | NO_REGIONS);
|
||||
let assoc_name = item_segment.identifier.name;
|
||||
|
||||
let is_param = match (&ty.sty, ty_path_def) {
|
||||
debug!("associated_path_def_to_ty: {}::{}", ty.repr(tcx), token::get_name(assoc_name));
|
||||
|
||||
check_path_args(tcx, slice::ref_slice(item_segment), NO_TPS | NO_REGIONS);
|
||||
|
||||
// Check that the path prefix given by ty/ty_path_def is a type parameter/Self.
|
||||
match (&ty.sty, ty_path_def) {
|
||||
(&ty::ty_param(_), def::DefTyParam(..)) |
|
||||
(&ty::ty_param(_), def::DefSelfTy(_)) => true,
|
||||
_ => false
|
||||
};
|
||||
|
||||
let ty_param_node_id = if is_param {
|
||||
ty_path_def.local_node_id()
|
||||
} else {
|
||||
report_ambiguous_associated_type(
|
||||
tcx, span, &ty.user_string(tcx), "Trait", &token::get_name(assoc_name));
|
||||
return (tcx.types.err, ty_path_def);
|
||||
};
|
||||
(&ty::ty_param(_), def::DefSelfTy(_)) => {}
|
||||
_ => {
|
||||
report_ambiguous_associated_type(tcx,
|
||||
span,
|
||||
&ty.user_string(tcx),
|
||||
"Trait",
|
||||
&token::get_name(assoc_name));
|
||||
return (tcx.types.err, ty_path_def);
|
||||
}
|
||||
}
|
||||
|
||||
let ty_param_node_id = ty_path_def.local_node_id();
|
||||
let ty_param_name = tcx.ty_param_defs.borrow().get(&ty_param_node_id).unwrap().name;
|
||||
|
||||
let bounds = match this.get_type_parameter_bounds(span, ty_param_node_id) {
|
||||
Ok(v) => v,
|
||||
Err(ErrorReported) => { return (tcx.types.err, ty_path_def); }
|
||||
Err(ErrorReported) => {
|
||||
return (tcx.types.err, ty_path_def);
|
||||
}
|
||||
};
|
||||
|
||||
// ensure the super predicates and stop if we encountered an error
|
||||
// Ensure the super predicates and stop if we encountered an error.
|
||||
if bounds.iter().any(|b| this.ensure_super_predicates(span, b.def_id()).is_err()) {
|
||||
return (this.tcx().types.err, ty_path_def);
|
||||
}
|
||||
|
||||
// Check that there is exactly one way to find an associated type with the
|
||||
// correct name.
|
||||
let mut suitable_bounds: Vec<_> =
|
||||
traits::transitive_bounds(tcx, &bounds)
|
||||
.filter(|b| this.trait_defines_associated_type_named(b.def_id(), assoc_name))
|
||||
@ -1118,7 +1129,8 @@ fn associated_path_def_to_ty<'tcx>(this: &AstConv<'tcx>,
|
||||
// by type collection, which may be in progress at this point.
|
||||
match this.tcx().map.expect_item(trait_did.node).node {
|
||||
ast::ItemTrait(_, _, _, ref trait_items) => {
|
||||
let item = trait_items.iter().find(|i| i.ident.name == assoc_name)
|
||||
let item = trait_items.iter()
|
||||
.find(|i| i.ident.name == assoc_name)
|
||||
.expect("missing associated type");
|
||||
ast_util::local_def(item.id)
|
||||
}
|
||||
@ -1129,6 +1141,7 @@ fn associated_path_def_to_ty<'tcx>(this: &AstConv<'tcx>,
|
||||
let item = trait_items.iter().find(|i| i.name() == assoc_name);
|
||||
item.expect("missing associated type").def_id()
|
||||
};
|
||||
|
||||
(ty, def::DefAssociatedTy(trait_did, item_did))
|
||||
}
|
||||
|
||||
@ -1150,8 +1163,11 @@ fn qpath_to_ty<'tcx>(this: &AstConv<'tcx>,
|
||||
ty
|
||||
} else {
|
||||
let path_str = ty::item_path_str(tcx, trait_def_id);
|
||||
report_ambiguous_associated_type(
|
||||
tcx, span, "Type", &path_str, &token::get_ident(item_segment.identifier));
|
||||
report_ambiguous_associated_type(tcx,
|
||||
span,
|
||||
"Type",
|
||||
&path_str,
|
||||
&token::get_ident(item_segment.identifier));
|
||||
return tcx.types.err;
|
||||
};
|
||||
|
||||
@ -1204,13 +1220,15 @@ pub fn ast_ty_arg_to_ty<'tcx>(this: &AstConv<'tcx>,
|
||||
}
|
||||
}
|
||||
|
||||
// Note that both base_segments and assoc_segments may be empty, although not at
|
||||
// the same time.
|
||||
pub fn finish_resolving_def_to_ty<'tcx>(this: &AstConv<'tcx>,
|
||||
rscope: &RegionScope,
|
||||
span: Span,
|
||||
param_mode: PathParamMode,
|
||||
def: &mut def::Def,
|
||||
def: &def::Def,
|
||||
opt_self_ty: Option<Ty<'tcx>>,
|
||||
segments: &[ast::PathSegment],
|
||||
base_segments: &[ast::PathSegment],
|
||||
assoc_segments: &[ast::PathSegment])
|
||||
-> Ty<'tcx> {
|
||||
let tcx = this.tcx();
|
||||
@ -1226,52 +1244,64 @@ pub fn finish_resolving_def_to_ty<'tcx>(this: &AstConv<'tcx>,
|
||||
span,
|
||||
param_mode,
|
||||
trait_def_id,
|
||||
segments.last().unwrap(),
|
||||
base_segments.last().unwrap(),
|
||||
&mut projection_bounds);
|
||||
|
||||
check_path_args(tcx, segments.init(), NO_TPS | NO_REGIONS);
|
||||
trait_ref_to_object_type(this, rscope, span, trait_ref,
|
||||
projection_bounds, &[])
|
||||
check_path_args(tcx, base_segments.init(), NO_TPS | NO_REGIONS);
|
||||
trait_ref_to_object_type(this,
|
||||
rscope,
|
||||
span,
|
||||
trait_ref,
|
||||
projection_bounds,
|
||||
&[])
|
||||
}
|
||||
def::DefTy(did, _) | def::DefStruct(did) => {
|
||||
check_path_args(tcx, segments.init(), NO_TPS | NO_REGIONS);
|
||||
check_path_args(tcx, base_segments.init(), NO_TPS | NO_REGIONS);
|
||||
ast_path_to_ty(this, rscope, span,
|
||||
param_mode, did,
|
||||
segments.last().unwrap())
|
||||
base_segments.last().unwrap())
|
||||
}
|
||||
def::DefTyParam(space, index, _, name) => {
|
||||
check_path_args(tcx, segments, NO_TPS | NO_REGIONS);
|
||||
check_path_args(tcx, base_segments, NO_TPS | NO_REGIONS);
|
||||
ty::mk_param(tcx, space, index, name)
|
||||
}
|
||||
def::DefSelfTy(_) => {
|
||||
// n.b.: resolve guarantees that the this type only appears in a
|
||||
// N.b.: resolve guarantees that the this type only appears in a
|
||||
// trait, which we rely upon in various places when creating
|
||||
// substs
|
||||
check_path_args(tcx, segments, NO_TPS | NO_REGIONS);
|
||||
// substs.
|
||||
check_path_args(tcx, base_segments, NO_TPS | NO_REGIONS);
|
||||
ty::mk_self_type(tcx)
|
||||
}
|
||||
def::DefAssociatedTy(trait_did, _) => {
|
||||
check_path_args(tcx, &segments[..segments.len()-2], NO_TPS | NO_REGIONS);
|
||||
qpath_to_ty(this, rscope, span, param_mode,
|
||||
opt_self_ty, trait_did,
|
||||
&segments[segments.len()-2],
|
||||
segments.last().unwrap())
|
||||
check_path_args(tcx, &base_segments[..base_segments.len()-2], NO_TPS | NO_REGIONS);
|
||||
qpath_to_ty(this,
|
||||
rscope,
|
||||
span,
|
||||
param_mode,
|
||||
opt_self_ty,
|
||||
trait_did,
|
||||
&base_segments[base_segments.len()-2],
|
||||
base_segments.last().unwrap())
|
||||
}
|
||||
def::DefMod(id) => {
|
||||
// Used as sentinel by callers to indicate the `<T>::A::B::C` form.
|
||||
// FIXME(#22519) This part of the resolution logic should be
|
||||
// avoided entirely for that form, once we stop needed a Def
|
||||
// for `associated_path_def_to_ty`.
|
||||
if segments.is_empty() {
|
||||
opt_self_ty.expect("missing T in <T>::a::b::c")
|
||||
} else {
|
||||
span_err!(tcx.sess, span, E0247, "found module name used as a type: {}",
|
||||
|
||||
if !base_segments.is_empty() {
|
||||
span_err!(tcx.sess,
|
||||
span,
|
||||
E0247,
|
||||
"found module name used as a type: {}",
|
||||
tcx.map.node_to_string(id.node));
|
||||
return this.tcx().types.err;
|
||||
}
|
||||
|
||||
opt_self_ty.expect("missing T in <T>::a::b::c")
|
||||
}
|
||||
def::DefPrimTy(prim_ty) => {
|
||||
prim_ty_to_ty(tcx, segments, prim_ty)
|
||||
prim_ty_to_ty(tcx, base_segments, prim_ty)
|
||||
}
|
||||
_ => {
|
||||
span_err!(tcx.sess, span, E0248,
|
||||
@ -1282,15 +1312,19 @@ pub fn finish_resolving_def_to_ty<'tcx>(this: &AstConv<'tcx>,
|
||||
|
||||
// If any associated type segments remain, attempt to resolve them.
|
||||
let mut ty = base_ty;
|
||||
let mut def = *def;
|
||||
for segment in assoc_segments {
|
||||
if ty.sty == ty::ty_err {
|
||||
break;
|
||||
}
|
||||
// This is pretty bad (it will fail except for T::A and Self::A).
|
||||
let (a_ty, a_def) = associated_path_def_to_ty(this, span,
|
||||
ty, *def, segment);
|
||||
let (a_ty, a_def) = associated_path_def_to_ty(this,
|
||||
span,
|
||||
ty,
|
||||
def,
|
||||
segment);
|
||||
ty = a_ty;
|
||||
*def = a_def;
|
||||
def = a_def;
|
||||
}
|
||||
ty
|
||||
}
|
||||
@ -1378,13 +1412,16 @@ pub fn ast_ty_to_ty<'tcx>(this: &AstConv<'tcx>,
|
||||
tcx.sess.span_bug(ast_ty.span,
|
||||
&format!("unbound path {}", ast_ty.repr(tcx)))
|
||||
};
|
||||
let mut def = path_res.base_def;
|
||||
let def = path_res.base_def;
|
||||
let base_ty_end = path.segments.len() - path_res.depth;
|
||||
let opt_self_ty = maybe_qself.as_ref().map(|qself| {
|
||||
ast_ty_to_ty(this, rscope, &qself.ty)
|
||||
});
|
||||
let ty = finish_resolving_def_to_ty(this, rscope, ast_ty.span,
|
||||
PathParamMode::Explicit, &mut def,
|
||||
let ty = finish_resolving_def_to_ty(this,
|
||||
rscope,
|
||||
ast_ty.span,
|
||||
PathParamMode::Explicit,
|
||||
&def,
|
||||
opt_self_ty,
|
||||
&path.segments[..base_ty_end],
|
||||
&path.segments[base_ty_end..]);
|
||||
|
@ -3329,7 +3329,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
|
||||
&format!("unbound path {}", expr.repr(tcx)))
|
||||
};
|
||||
|
||||
let mut def = path_res.base_def;
|
||||
let def = path_res.base_def;
|
||||
if path_res.depth == 0 {
|
||||
let (scheme, predicates) =
|
||||
type_scheme_and_predicates_for_def(fcx, expr.span, def);
|
||||
@ -3339,9 +3339,11 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
|
||||
} else {
|
||||
let ty_segments = path.segments.init();
|
||||
let base_ty_end = path.segments.len() - path_res.depth;
|
||||
let ty = astconv::finish_resolving_def_to_ty(fcx, fcx, expr.span,
|
||||
let ty = astconv::finish_resolving_def_to_ty(fcx,
|
||||
fcx,
|
||||
expr.span,
|
||||
PathParamMode::Optional,
|
||||
&mut def,
|
||||
&def,
|
||||
opt_self_ty,
|
||||
&ty_segments[..base_ty_end],
|
||||
&ty_segments[base_ty_end..]);
|
||||
|
Loading…
x
Reference in New Issue
Block a user